* libguile/vm-engine.c (vm_engine): Allow the caller to pass arguments
  on the stack.
---
 libguile/vm-engine.c |   17 +++++++++++++----
 1 file changed, 13 insertions(+), 4 deletions(-)

diff --git a/libguile/vm-engine.c b/libguile/vm-engine.c
index b7e355d..77c2e46 100644
--- a/libguile/vm-engine.c
+++ b/libguile/vm-engine.c
@@ -356,8 +356,19 @@ VM_NAME (SCM vm, SCM program, SCM *argv, int nargs)
       NEXT;
     }
 
-  /* Initial frame */
   CACHE_REGISTER ();
+
+  /* Since it's possible to receive the arguments on the stack itself,
+     and indeed the RTL VM invokes us that way, shuffle up the
+     arguments first.  */
+  VM_ASSERT (sp + 8 + nargs < stack_limit, vm_error_too_many_args (nargs));
+  {
+    int i;
+    for (i = nargs - 1; i >= 0; i--)
+      sp[9 + i] = argv[i];
+  }
+
+  /* Initial frame */
   PUSH (SCM_PACK (fp)); /* dynamic link */
   PUSH (SCM_PACK (0)); /* mvra */
   PUSH (SCM_PACK (ip)); /* ra */
@@ -371,9 +382,7 @@ VM_NAME (SCM vm, SCM program, SCM *argv, int nargs)
   PUSH (SCM_PACK (ip)); /* ra */
   PUSH (program);
   fp = sp + 1;
-  VM_ASSERT (sp + nargs < stack_limit, vm_error_too_many_args (nargs));
-  while (nargs--)
-    PUSH (*argv++);
+  sp += nargs;
 
   PUSH_CONTINUATION_HOOK ();
 
-- 
1.7.10.4


Reply via email to