Commit Diff


commit - 1433867a307e5fbd8399b90e210d4d9caf29ba00
commit + 9af2cde296684629983279f4e144d961be83fdf6
blob - d3adcb028212b28d8438a72bb0af388cec6883bd
blob + c2bac4ebb50b888bcbb3c8e804db287a6d44aa0e
--- script.c
+++ script.c
@@ -534,22 +534,34 @@ eval(struct op *op)
 
 	case OP_FUNCALL:
                 /* assume airity matches */
-
-		pushenv();
 
 		proc = op->v.funcall.proc;
-		for (i = 0; i < op->v.funcall.argc; ++i) {
-			t = &op->v.funcall.argv[i];
-			if ((ret = setvar(proc->args[i], t)) != EVAL_OK)
+		if (proc->nativefn != NULL) {
+			/* push arguments on the stack */
+			for (i = 0; i < op->v.funcall.argc; ++i) {
+				t = &op->v.funcall.argv[i];
+				if ((ret = eval(t)) != EVAL_OK)
+					return ret;
+			}
+			if ((ret = proc->nativefn(op->v.funcall.argc))
+			    != EVAL_OK)
 				return ret;
-		}
-
-		if (proc->nativefn != NULL)
-			proc->nativefn(i);
-		else if ((ret = eval(proc->body)) != EVAL_OK)
+		} else {
+			pushenv();
+
+			for (i = 0; i < op->v.funcall.argc; ++i) {
+				t = &op->v.funcall.argv[i];
+				if ((ret = setvar(proc->args[i], t))
+				    != EVAL_OK)
+					return ret;
+			}
+
+			if ((ret = eval(proc->body)) != EVAL_OK)
 				return ret;
 
-		popenv();
+			popenv();
+		}
+
 		break;
 
 	case OP_LITERAL: