OP_TAILCALL: Fall through to OP_CALL for native functions

Wed, 24 Nov 2010 02:50:02 +0000

author
Matthew Wild <mwild1@gmail.com>
date
Wed, 24 Nov 2010 02:50:02 +0000
changeset 134
2e2d08e3669c
parent 133
afce5a550d18
child 135
77022489338a

OP_TAILCALL: Fall through to OP_CALL for native functions

lvm.js file | annotate | diff | comparison | revisions
--- a/lvm.js	Wed Nov 24 02:49:40 2010 +0000
+++ b/lvm.js	Wed Nov 24 02:50:02 2010 +0000
@@ -503,19 +503,22 @@
 				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;
+				if(typeof(f) != "function") // Can't tail-call native functions
+				{
+					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;
+				}
+				// Fall through...
 			case OP_CALL:
 				var f = frame.reg[INS_A(instruction)].precall(); // return JS or LFunction
 				var A = INS_A(instruction), B = INS_B(instruction), C = INS_C(instruction);

mercurial