summaryrefslogtreecommitdiff
path: root/libguile/vm.c
diff options
context:
space:
mode:
authorLudovic Courtès <ludo@gnu.org>2010-04-21 01:05:42 +0200
committerLudovic Courtès <ludo@gnu.org>2010-05-07 13:47:52 +0200
commitb3567435e1ba8b4bdef78fc020a2032c02d73075 (patch)
treea394732a6d8ec116fe346a2ecba327a6116c630e /libguile/vm.c
parentf9a86f72a6ea7ab480f4bfd6ef61c835620df5eb (diff)
downloadguile-b3567435e1ba8b4bdef78fc020a2032c02d73075.tar.gz
Allocate frame objects on the stack when invoking VM hooks.
* libguile/vm.c (vm_dispatch_hook): Don't call `scm_c_make_frame ()'. Instead, allocate FRAME on the stack.
Diffstat (limited to 'libguile/vm.c')
-rw-r--r--libguile/vm.c28
1 files changed, 24 insertions, 4 deletions
diff --git a/libguile/vm.c b/libguile/vm.c
index ca074056a..4f766cbeb 100644
--- a/libguile/vm.c
+++ b/libguile/vm.c
@@ -185,7 +185,9 @@ vm_dispatch_hook (SCM vm, int hook_num)
{
struct scm_vm *vp;
SCM hook;
- SCM frame;
+ struct scm_frame c_frame;
+ scm_t_cell frame;
+ SCM args[1];
vp = SCM_VM_DATA (vm);
hook = vp->hooks[hook_num];
@@ -193,10 +195,28 @@ vm_dispatch_hook (SCM vm, int hook_num)
if (SCM_LIKELY (scm_is_false (hook))
|| scm_is_null (SCM_HOOK_PROCEDURES (hook)))
return;
-
+
vp->trace_level--;
- frame = scm_c_make_frame (vm, vp->fp, vp->sp, vp->ip, 0);
- scm_c_run_hookn (hook, &frame, 1);
+
+ /* Allocate a frame object on the stack. This is more efficient than calling
+ `scm_c_make_frame ()' to allocate on the heap, but it forces hooks to not
+ capture frame objects.
+
+ At the same time, procedures such as `frame-procedure' make sense only
+ while the stack frame represented by the frame object is visible, so it
+ seems reasonable to limit the lifetime of frame objects. */
+
+ c_frame.stack_holder = vm;
+ c_frame.fp = vp->fp;
+ c_frame.sp = vp->sp;
+ c_frame.ip = vp->ip;
+ c_frame.offset = 0;
+ frame.word_0 = SCM_PACK (scm_tc7_frame);
+ frame.word_1 = PTR2SCM (&c_frame);
+ args[0] = PTR2SCM (&frame);
+
+ scm_c_run_hookn (hook, args, 1);
+
vp->trace_level++;
}