Support for upvalues in functions \o/ implemented OP_GETUPVAL, and a stub for OP_SETUPVAL.

Sat, 22 May 2010 17:33:43 +0100

author
Matthew Wild <mwild1@gmail.com>
date
Sat, 22 May 2010 17:33:43 +0100
changeset 20
977ae93f612c
parent 19
8c9c1752272b
child 21
9b5cc503bc31

Support for upvalues in functions \o/ implemented OP_GETUPVAL, and a stub for OP_SETUPVAL.

lvm.js file | annotate | diff | comparison | revisions
--- a/lvm.js	Wed Apr 07 04:15:59 2010 +0100
+++ b/lvm.js	Sat May 22 17:33:43 2010 +0100
@@ -2,8 +2,10 @@
 var OP_MOVE = 0;
 var OP_LOADK = 1;
 var OP_LOADNIL = 3;
+var OP_GETUPVAL = 4;
 var OP_GETGLOBAL = 5;
 var OP_SETGLOBAL = 7;
+var OP_SETUPVAL = 8;
 var OP_CALL = 28;
 var OP_RETURN = 30;
 var OP_CLOSURE = 36;
@@ -237,6 +239,7 @@
 	var o = new F();
 	o.environment = env;
 	o.chunk = chunk;
+	o.upvalues = [];
 	return o;
 }
 
@@ -270,10 +273,16 @@
 				for(var i = INS_A(instruction);i<=INS_B(instruction);i++)
 					this.frame.reg[i] = new LValue("nil", null);
 				break;
+			case OP_GETUPVAL:
+				this.frame.reg[INS_A(instruction)] = this.frame.f.upvalues[INS_B(instruction)];
+				break;
 			case OP_GETGLOBAL:
 				var name = this.frame.f.constants[INS_Bx(instruction)];
 				this.frame.reg[INS_A(instruction)] = this.frame.f.environment.index(name);
 				break;
+			case OP_SETUPVAL:
+				throw "Setting upvalues not implemented yet, sorry :)";
+				break;
 			case OP_SETGLOBAL:
 				var name = this.frame.f.constants[INS_Bx(instruction)];
 				this.frame.f.environment.setIndex(name, this.frame.reg[instruction[1]]);
@@ -302,9 +311,25 @@
 			case OP_CLOSURE:
 				var prototype_id = INS_Bx(instruction);
 				var chunk = this.frame.f.chunk.prototypes[prototype_id];
-				if(chunk.numUpvalues>0)
-					throw "Upvalues not yet implemented, sorry :)";
 				var f = new LFunction(chunk, this.frame.f.environment);
+				f.me = "Yes, it's me!";
+				for(var i=0;i<chunk.numUpvalues;i++)
+				{
+					var upval_instruction = this.frame.f.instructions[this.frame.pc++];
+					switch(INS_OPCODE(upval_instruction))
+					{
+					case OP_MOVE:
+						sys.puts("CONSUMING OP_MOVE");
+						f.upvalues[i] = this.frame.reg[INS_B(upval_instruction)];
+						break;
+					case OP_GETUPVAL:
+						sys.puts("CONSUMING OP_GETUPVAL");
+						f.upvalues[i] = this.frame.f.upvalues[INS_B(upval_instruction)];
+						break;
+					default:
+						throw "Invalid upvalue opcode following OP_CLOSURE";
+					}
+				}
 				this.frame.reg[INS_A(instruction)] = new LValue("function", f);
 				break;
 			case OP_RETURN:

mercurial