Implement OP_TAILCALL - the last opcode!

Mon, 22 Nov 2010 05:06:37 +0000

author
Matthew Wild <mwild1@gmail.com>
date
Mon, 22 Nov 2010 05:06:37 +0000
changeset 127
9a4c549c7828
parent 126
07ec490c7a6f
child 128
29c56996fa03

Implement OP_TAILCALL - the last opcode!

lvm.js file | annotate | diff | comparison | revisions
--- a/lvm.js	Mon Nov 22 04:56:38 2010 +0000
+++ b/lvm.js	Mon Nov 22 05:06:37 2010 +0000
@@ -28,7 +28,7 @@
 var OP_TEST = 26;
 var OP_TESTSET = 27;
 var OP_CALL = 28;
-//var OP_TAILCALL = 29;
+var OP_TAILCALL = 29;
 var OP_RETURN = 30;
 var OP_FORLOOP = 31;
 var OP_FORPREP = 32;
@@ -498,6 +498,21 @@
 						frame.reg[A+i] = new LValue(this, "nil", null);
 				}
 				break;
+			case OP_TAILCALL:
+				var f = frame.reg[INS_A(instruction)].precall();
+				var A = INS_A(instruction), B = INS_B(instruction);
+				var undefined, args;
+				if(B != 1)
+					args = frame.reg.slice(A+1, B==0?undefined:(A+B));
+				else
+					args = [];
+				if(args.length > f.numParameters)
+					args.length = f.numParameters;
+				for(var i=args.length;i<f.maxStackSize;i++)
+					args[i] = new LValue(this, "nil", null);
+				// Patch frame for new function
+				frame.f = f; frame.pc = 0; frame.reg = args;
+				break;
 			case OP_CALL:
 				var f = frame.reg[INS_A(instruction)].precall(); // return JS or LValue
 				var A = INS_A(instruction), B = INS_B(instruction), C = INS_C(instruction);

mercurial