2012-05-18 11:57:51 +02:00
|
|
|
|
/* Copyright (C) 2001, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
|
2000-08-22 15:54:19 +00:00
|
|
|
|
*
|
2009-05-26 22:23:44 +02:00
|
|
|
|
* This library is free software; you can redistribute it and/or
|
2009-06-17 00:22:09 +01:00
|
|
|
|
* modify it under the terms of the GNU Lesser General Public License
|
|
|
|
|
|
* as published by the Free Software Foundation; either version 3 of
|
|
|
|
|
|
* the License, or (at your option) any later version.
|
2000-08-22 15:54:19 +00:00
|
|
|
|
*
|
2009-06-17 00:22:09 +01:00
|
|
|
|
* This library is distributed in the hope that it will be useful, but
|
|
|
|
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
2009-05-26 22:23:44 +02:00
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
|
|
* Lesser General Public License for more details.
|
2000-08-22 15:54:19 +00:00
|
|
|
|
*
|
2009-05-26 22:23:44 +02:00
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
|
|
* License along with this library; if not, write to the Free Software
|
2009-06-17 00:22:09 +01:00
|
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
|
|
|
|
* 02110-1301 USA
|
2009-05-26 22:23:44 +02:00
|
|
|
|
*/
|
2000-08-22 15:54:19 +00:00
|
|
|
|
|
enable multiple vm engines (regular, debug, ...)
* libguile/vm-engine.c (VM_USE_HOOKS, VM_USE_CLOCK, VM_CHECK_EXTERNAL)
(VM_CHECK_OBJECT): Update to define these here, before including
vm-engine.h.
(vm_run): Change so that we can make different engines. Also, we take
an array of arguments, and the struct scm_vm directly, so as to avoid
any need to cons.
* libguile/vm-engine.h (CHECK_EXTERNAL, CHECK_OBJECT): Add some UNLIKELY
bits; don't seem to help.
* libguile/vm.c (vm_dispatch_hook): Change to not pass the VP. This needs
some love, and perhaps we revert to the old way.
(VM_ENGINE): Actually make two engines, vm_regular_engine and
vm_debug_engine. Probably there is room for improvement here. Actually
their speeds are the same at the moment.
(make_vm): Choose which engine to run; currently the debug engine by
default.
(scm_c_vm_run): A thin wrapper to invoke a VM without consing.
(scm_vm_apply): Use scm_c_vm_run.
(scm_load_compiled_with_vm): Use scm_c_vm_run.
2009-02-04 23:47:56 +01:00
|
|
|
|
/* This file is included in vm.c multiple times */
|
|
|
|
|
|
|
|
|
|
|
|
#if (VM_ENGINE == SCM_VM_REGULAR_ENGINE)
|
2012-05-18 12:21:08 +02:00
|
|
|
|
# define VM_USE_HOOKS 0 /* Various hooks */
|
enable multiple vm engines (regular, debug, ...)
* libguile/vm-engine.c (VM_USE_HOOKS, VM_USE_CLOCK, VM_CHECK_EXTERNAL)
(VM_CHECK_OBJECT): Update to define these here, before including
vm-engine.h.
(vm_run): Change so that we can make different engines. Also, we take
an array of arguments, and the struct scm_vm directly, so as to avoid
any need to cons.
* libguile/vm-engine.h (CHECK_EXTERNAL, CHECK_OBJECT): Add some UNLIKELY
bits; don't seem to help.
* libguile/vm.c (vm_dispatch_hook): Change to not pass the VP. This needs
some love, and perhaps we revert to the old way.
(VM_ENGINE): Actually make two engines, vm_regular_engine and
vm_debug_engine. Probably there is room for improvement here. Actually
their speeds are the same at the moment.
(make_vm): Choose which engine to run; currently the debug engine by
default.
(scm_c_vm_run): A thin wrapper to invoke a VM without consing.
(scm_vm_apply): Use scm_c_vm_run.
(scm_load_compiled_with_vm): Use scm_c_vm_run.
2009-02-04 23:47:56 +01:00
|
|
|
|
#elif (VM_ENGINE == SCM_VM_DEBUG_ENGINE)
|
2012-05-18 12:21:08 +02:00
|
|
|
|
# define VM_USE_HOOKS 1
|
enable multiple vm engines (regular, debug, ...)
* libguile/vm-engine.c (VM_USE_HOOKS, VM_USE_CLOCK, VM_CHECK_EXTERNAL)
(VM_CHECK_OBJECT): Update to define these here, before including
vm-engine.h.
(vm_run): Change so that we can make different engines. Also, we take
an array of arguments, and the struct scm_vm directly, so as to avoid
any need to cons.
* libguile/vm-engine.h (CHECK_EXTERNAL, CHECK_OBJECT): Add some UNLIKELY
bits; don't seem to help.
* libguile/vm.c (vm_dispatch_hook): Change to not pass the VP. This needs
some love, and perhaps we revert to the old way.
(VM_ENGINE): Actually make two engines, vm_regular_engine and
vm_debug_engine. Probably there is room for improvement here. Actually
their speeds are the same at the moment.
(make_vm): Choose which engine to run; currently the debug engine by
default.
(scm_c_vm_run): A thin wrapper to invoke a VM without consing.
(scm_vm_apply): Use scm_c_vm_run.
(scm_load_compiled_with_vm): Use scm_c_vm_run.
2009-02-04 23:47:56 +01:00
|
|
|
|
#else
|
2012-05-18 12:21:08 +02:00
|
|
|
|
# error unknown debug engine VM_ENGINE
|
enable multiple vm engines (regular, debug, ...)
* libguile/vm-engine.c (VM_USE_HOOKS, VM_USE_CLOCK, VM_CHECK_EXTERNAL)
(VM_CHECK_OBJECT): Update to define these here, before including
vm-engine.h.
(vm_run): Change so that we can make different engines. Also, we take
an array of arguments, and the struct scm_vm directly, so as to avoid
any need to cons.
* libguile/vm-engine.h (CHECK_EXTERNAL, CHECK_OBJECT): Add some UNLIKELY
bits; don't seem to help.
* libguile/vm.c (vm_dispatch_hook): Change to not pass the VP. This needs
some love, and perhaps we revert to the old way.
(VM_ENGINE): Actually make two engines, vm_regular_engine and
vm_debug_engine. Probably there is room for improvement here. Actually
their speeds are the same at the moment.
(make_vm): Choose which engine to run; currently the debug engine by
default.
(scm_c_vm_run): A thin wrapper to invoke a VM without consing.
(scm_vm_apply): Use scm_c_vm_run.
(scm_load_compiled_with_vm): Use scm_c_vm_run.
2009-02-04 23:47:56 +01:00
|
|
|
|
#endif
|
2000-08-22 15:54:19 +00:00
|
|
|
|
|
|
|
|
|
|
|
2012-05-18 11:52:12 +02:00
|
|
|
|
/* Register optimization. [ stolen from librep/src/lispmach.h,v 1.3 ]
|
|
|
|
|
|
|
|
|
|
|
|
Some compilers underestimate the use of the local variables representing
|
|
|
|
|
|
the abstract machine registers, and don't put them in hardware registers,
|
|
|
|
|
|
which slows down the interpreter considerably.
|
|
|
|
|
|
For GCC, I have hand-assigned hardware registers for several architectures.
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef __GNUC__
|
|
|
|
|
|
#ifdef __mips__
|
|
|
|
|
|
#define IP_REG asm("$16")
|
|
|
|
|
|
#define SP_REG asm("$17")
|
|
|
|
|
|
#define FP_REG asm("$18")
|
|
|
|
|
|
#endif
|
|
|
|
|
|
#ifdef __sparc__
|
|
|
|
|
|
#define IP_REG asm("%l0")
|
|
|
|
|
|
#define SP_REG asm("%l1")
|
|
|
|
|
|
#define FP_REG asm("%l2")
|
|
|
|
|
|
#endif
|
|
|
|
|
|
#ifdef __alpha__
|
|
|
|
|
|
#ifdef __CRAY__
|
|
|
|
|
|
#define IP_REG asm("r9")
|
|
|
|
|
|
#define SP_REG asm("r10")
|
|
|
|
|
|
#define FP_REG asm("r11")
|
|
|
|
|
|
#else
|
|
|
|
|
|
#define IP_REG asm("$9")
|
|
|
|
|
|
#define SP_REG asm("$10")
|
|
|
|
|
|
#define FP_REG asm("$11")
|
|
|
|
|
|
#endif
|
|
|
|
|
|
#endif
|
|
|
|
|
|
#ifdef __i386__
|
|
|
|
|
|
/* too few registers! because of register allocation errors with various gcs,
|
|
|
|
|
|
just punt on explicit assignments on i386, hoping that the "register"
|
|
|
|
|
|
declaration will be sufficient. */
|
|
|
|
|
|
#elif defined __x86_64__
|
|
|
|
|
|
/* GCC 4.6 chooses %rbp for IP_REG and %rbx for SP_REG, which works
|
|
|
|
|
|
well. Tell it to keep the jump table in a r12, which is
|
|
|
|
|
|
callee-saved. */
|
|
|
|
|
|
#define JT_REG asm ("r12")
|
|
|
|
|
|
#endif
|
|
|
|
|
|
#if defined(PPC) || defined(_POWER) || defined(_IBMR2)
|
|
|
|
|
|
#define IP_REG asm("26")
|
|
|
|
|
|
#define SP_REG asm("27")
|
|
|
|
|
|
#define FP_REG asm("28")
|
|
|
|
|
|
#endif
|
|
|
|
|
|
#ifdef __hppa__
|
|
|
|
|
|
#define IP_REG asm("%r18")
|
|
|
|
|
|
#define SP_REG asm("%r17")
|
|
|
|
|
|
#define FP_REG asm("%r16")
|
|
|
|
|
|
#endif
|
|
|
|
|
|
#ifdef __mc68000__
|
|
|
|
|
|
#define IP_REG asm("a5")
|
|
|
|
|
|
#define SP_REG asm("a4")
|
|
|
|
|
|
#define FP_REG
|
|
|
|
|
|
#endif
|
|
|
|
|
|
#ifdef __arm__
|
|
|
|
|
|
#define IP_REG asm("r9")
|
|
|
|
|
|
#define SP_REG asm("r8")
|
|
|
|
|
|
#define FP_REG asm("r7")
|
|
|
|
|
|
#endif
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
#ifndef IP_REG
|
|
|
|
|
|
#define IP_REG
|
|
|
|
|
|
#endif
|
|
|
|
|
|
#ifndef SP_REG
|
|
|
|
|
|
#define SP_REG
|
|
|
|
|
|
#endif
|
|
|
|
|
|
#ifndef FP_REG
|
|
|
|
|
|
#define FP_REG
|
|
|
|
|
|
#endif
|
|
|
|
|
|
#ifndef JT_REG
|
|
|
|
|
|
#define JT_REG
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
2012-05-18 11:57:51 +02:00
|
|
|
|
#define VM_ASSERT(condition, handler) \
|
|
|
|
|
|
do { \
|
|
|
|
|
|
if (SCM_UNLIKELY (!(condition))) \
|
|
|
|
|
|
{ \
|
|
|
|
|
|
SYNC_ALL(); \
|
|
|
|
|
|
handler; \
|
|
|
|
|
|
} \
|
|
|
|
|
|
} while (0)
|
2012-05-18 11:52:12 +02:00
|
|
|
|
|
|
|
|
|
|
#ifdef VM_ENABLE_ASSERTIONS
|
|
|
|
|
|
# define ASSERT(condition) VM_ASSERT (condition, abort())
|
|
|
|
|
|
#else
|
|
|
|
|
|
# define ASSERT(condition)
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Cache the VM's instruction, stack, and frame pointer in local variables. */
|
|
|
|
|
|
#define CACHE_REGISTER() \
|
|
|
|
|
|
{ \
|
|
|
|
|
|
ip = vp->ip; \
|
|
|
|
|
|
sp = vp->sp; \
|
|
|
|
|
|
fp = vp->fp; \
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Update the registers in VP, a pointer to the current VM. This must be done
|
|
|
|
|
|
at least before any GC invocation so that `vp->sp' is up-to-date and the
|
|
|
|
|
|
whole stack gets marked. */
|
|
|
|
|
|
#define SYNC_REGISTER() \
|
|
|
|
|
|
{ \
|
|
|
|
|
|
vp->ip = ip; \
|
|
|
|
|
|
vp->sp = sp; \
|
|
|
|
|
|
vp->fp = fp; \
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* FIXME */
|
|
|
|
|
|
#define ASSERT_VARIABLE(x) \
|
2012-05-18 11:57:51 +02:00
|
|
|
|
VM_ASSERT (SCM_VARIABLEP (x), abort())
|
2012-05-18 11:52:12 +02:00
|
|
|
|
#define ASSERT_BOUND_VARIABLE(x) \
|
2012-05-18 11:57:51 +02:00
|
|
|
|
VM_ASSERT (SCM_VARIABLEP (x) \
|
|
|
|
|
|
&& !scm_is_eq (SCM_VARIABLE_REF (x), SCM_UNDEFINED), \
|
|
|
|
|
|
abort())
|
2012-05-18 11:52:12 +02:00
|
|
|
|
|
|
|
|
|
|
#ifdef VM_ENABLE_PARANOID_ASSERTIONS
|
|
|
|
|
|
#define CHECK_IP() \
|
|
|
|
|
|
do { if (ip < bp->base || ip - bp->base > bp->len) abort (); } while (0)
|
|
|
|
|
|
#define ASSERT_ALIGNED_PROCEDURE() \
|
|
|
|
|
|
do { if ((scm_t_bits)bp % 8) abort (); } while (0)
|
|
|
|
|
|
#define ASSERT_BOUND(x) \
|
2012-05-18 11:57:51 +02:00
|
|
|
|
VM_ASSERT (!scm_is_eq ((x), SCM_UNDEFINED), abort())
|
2012-05-18 11:52:12 +02:00
|
|
|
|
#else
|
|
|
|
|
|
#define CHECK_IP()
|
|
|
|
|
|
#define ASSERT_ALIGNED_PROCEDURE()
|
|
|
|
|
|
#define ASSERT_BOUND(x)
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
/* Cache the object table and free variables. */
|
|
|
|
|
|
#define CACHE_PROGRAM() \
|
|
|
|
|
|
{ \
|
|
|
|
|
|
if (bp != SCM_PROGRAM_DATA (program)) { \
|
|
|
|
|
|
bp = SCM_PROGRAM_DATA (program); \
|
|
|
|
|
|
ASSERT_ALIGNED_PROCEDURE (); \
|
|
|
|
|
|
if (SCM_I_IS_VECTOR (SCM_PROGRAM_OBJTABLE (program))) { \
|
|
|
|
|
|
objects = SCM_I_VECTOR_WELTS (SCM_PROGRAM_OBJTABLE (program)); \
|
|
|
|
|
|
} else { \
|
|
|
|
|
|
objects = NULL; \
|
|
|
|
|
|
} \
|
|
|
|
|
|
} \
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#define SYNC_BEFORE_GC() \
|
|
|
|
|
|
{ \
|
|
|
|
|
|
SYNC_REGISTER (); \
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#define SYNC_ALL() \
|
|
|
|
|
|
{ \
|
|
|
|
|
|
SYNC_REGISTER (); \
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
* Error check
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
/* Accesses to a program's object table. */
|
|
|
|
|
|
#define CHECK_OBJECT(_num)
|
|
|
|
|
|
#define CHECK_FREE_VARIABLE(_num)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
* Hooks
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
#if VM_USE_HOOKS
|
|
|
|
|
|
#define RUN_HOOK(h) \
|
|
|
|
|
|
{ \
|
|
|
|
|
|
if (SCM_UNLIKELY (vp->trace_level > 0)) \
|
|
|
|
|
|
{ \
|
|
|
|
|
|
SYNC_REGISTER (); \
|
|
|
|
|
|
vm_dispatch_hook (vm, h); \
|
|
|
|
|
|
} \
|
|
|
|
|
|
}
|
|
|
|
|
|
#define RUN_HOOK1(h, x) \
|
|
|
|
|
|
{ \
|
|
|
|
|
|
if (SCM_UNLIKELY (vp->trace_level > 0)) \
|
|
|
|
|
|
{ \
|
|
|
|
|
|
PUSH (x); \
|
|
|
|
|
|
SYNC_REGISTER (); \
|
|
|
|
|
|
vm_dispatch_hook (vm, h); \
|
|
|
|
|
|
DROP(); \
|
|
|
|
|
|
} \
|
|
|
|
|
|
}
|
|
|
|
|
|
#else
|
|
|
|
|
|
#define RUN_HOOK(h)
|
|
|
|
|
|
#define RUN_HOOK1(h, x)
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
#define APPLY_HOOK() \
|
|
|
|
|
|
RUN_HOOK (SCM_VM_APPLY_HOOK)
|
|
|
|
|
|
#define PUSH_CONTINUATION_HOOK() \
|
|
|
|
|
|
RUN_HOOK (SCM_VM_PUSH_CONTINUATION_HOOK)
|
|
|
|
|
|
#define POP_CONTINUATION_HOOK(n) \
|
|
|
|
|
|
RUN_HOOK1 (SCM_VM_POP_CONTINUATION_HOOK, SCM_I_MAKINUM (n))
|
|
|
|
|
|
#define NEXT_HOOK() \
|
|
|
|
|
|
RUN_HOOK (SCM_VM_NEXT_HOOK)
|
|
|
|
|
|
#define ABORT_CONTINUATION_HOOK() \
|
|
|
|
|
|
RUN_HOOK (SCM_VM_ABORT_CONTINUATION_HOOK)
|
|
|
|
|
|
#define RESTORE_CONTINUATION_HOOK() \
|
|
|
|
|
|
RUN_HOOK (SCM_VM_RESTORE_CONTINUATION_HOOK)
|
|
|
|
|
|
|
|
|
|
|
|
#define VM_HANDLE_INTERRUPTS \
|
|
|
|
|
|
SCM_ASYNC_TICK_WITH_CODE (current_thread, SYNC_REGISTER ())
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
* Stack operation
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef VM_ENABLE_STACK_NULLING
|
|
|
|
|
|
# define CHECK_STACK_LEAKN(_n) ASSERT (!sp[_n]);
|
|
|
|
|
|
# define CHECK_STACK_LEAK() CHECK_STACK_LEAKN(1)
|
|
|
|
|
|
# define NULLSTACK(_n) { int __x = _n; CHECK_STACK_LEAKN (_n+1); while (__x > 0) sp[__x--] = NULL; }
|
|
|
|
|
|
/* If you have a nonlocal exit in a pre-wind proc while invoking a continuation
|
|
|
|
|
|
inside a dynwind (phew!), the stack is fully rewound but vm_reset_stack for
|
|
|
|
|
|
that continuation doesn't have a chance to run. It's not important on a
|
|
|
|
|
|
semantic level, but it does mess up our stack nulling -- so this macro is to
|
|
|
|
|
|
fix that. */
|
|
|
|
|
|
# define NULLSTACK_FOR_NONLOCAL_EXIT() if (vp->sp > sp) NULLSTACK (vp->sp - sp);
|
|
|
|
|
|
#else
|
|
|
|
|
|
# define CHECK_STACK_LEAKN(_n)
|
|
|
|
|
|
# define CHECK_STACK_LEAK()
|
|
|
|
|
|
# define NULLSTACK(_n)
|
|
|
|
|
|
# define NULLSTACK_FOR_NONLOCAL_EXIT()
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
/* For this check, we don't use VM_ASSERT, because that leads to a
|
|
|
|
|
|
per-site SYNC_ALL, which is too much code growth. The real problem
|
|
|
|
|
|
of course is having to check for overflow all the time... */
|
|
|
|
|
|
#define CHECK_OVERFLOW() \
|
|
|
|
|
|
do { if (SCM_UNLIKELY (sp >= stack_limit)) goto handle_overflow; } while (0)
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef VM_CHECK_UNDERFLOW
|
|
|
|
|
|
#define PRE_CHECK_UNDERFLOW(N) \
|
|
|
|
|
|
VM_ASSERT (sp - (N) > SCM_FRAME_UPPER_ADDRESS (fp), vm_error_stack_underflow ())
|
|
|
|
|
|
#define CHECK_UNDERFLOW() PRE_CHECK_UNDERFLOW (0)
|
|
|
|
|
|
#else
|
|
|
|
|
|
#define PRE_CHECK_UNDERFLOW(N) /* nop */
|
|
|
|
|
|
#define CHECK_UNDERFLOW() /* nop */
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define PUSH(x) do { sp++; CHECK_OVERFLOW (); *sp = x; } while (0)
|
|
|
|
|
|
#define DROP() do { sp--; CHECK_UNDERFLOW (); NULLSTACK (1); } while (0)
|
|
|
|
|
|
#define DROPN(_n) do { sp -= (_n); CHECK_UNDERFLOW (); NULLSTACK (_n); } while (0)
|
|
|
|
|
|
#define POP(x) do { PRE_CHECK_UNDERFLOW (1); x = *sp--; NULLSTACK (1); } while (0)
|
|
|
|
|
|
#define POP2(x,y) do { PRE_CHECK_UNDERFLOW (2); x = *sp--; y = *sp--; NULLSTACK (2); } while (0)
|
|
|
|
|
|
#define POP3(x,y,z) do { PRE_CHECK_UNDERFLOW (3); x = *sp--; y = *sp--; z = *sp--; NULLSTACK (3); } while (0)
|
|
|
|
|
|
|
|
|
|
|
|
/* Pop the N objects on top of the stack and push a list that contains
|
|
|
|
|
|
them. */
|
|
|
|
|
|
#define POP_LIST(n) \
|
|
|
|
|
|
do \
|
|
|
|
|
|
{ \
|
|
|
|
|
|
int i; \
|
|
|
|
|
|
SCM l = SCM_EOL, x; \
|
2012-05-17 11:39:35 +02:00
|
|
|
|
SYNC_BEFORE_GC (); \
|
2012-05-18 11:52:12 +02:00
|
|
|
|
for (i = n; i; i--) \
|
|
|
|
|
|
{ \
|
|
|
|
|
|
POP (x); \
|
2012-05-17 11:39:35 +02:00
|
|
|
|
l = scm_cons (x, l); \
|
2012-05-18 11:52:12 +02:00
|
|
|
|
} \
|
|
|
|
|
|
PUSH (l); \
|
|
|
|
|
|
} while (0)
|
|
|
|
|
|
|
|
|
|
|
|
/* The opposite: push all of the elements in L onto the list. */
|
|
|
|
|
|
#define PUSH_LIST(l, NILP) \
|
|
|
|
|
|
do \
|
|
|
|
|
|
{ \
|
|
|
|
|
|
for (; scm_is_pair (l); l = SCM_CDR (l)) \
|
|
|
|
|
|
PUSH (SCM_CAR (l)); \
|
|
|
|
|
|
VM_ASSERT (NILP (l), vm_error_improper_list (l)); \
|
|
|
|
|
|
} while (0)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
* Instruction operation
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
#define FETCH() (*ip++)
|
|
|
|
|
|
#define FETCH_LENGTH(len) do { len=*ip++; len<<=8; len+=*ip++; len<<=8; len+=*ip++; } while (0)
|
|
|
|
|
|
|
|
|
|
|
|
#undef NEXT_JUMP
|
|
|
|
|
|
#ifdef HAVE_LABELS_AS_VALUES
|
2012-05-18 11:57:51 +02:00
|
|
|
|
# define NEXT_JUMP() goto *jump_table[FETCH () & SCM_VM_INSTRUCTION_MASK]
|
2012-05-18 11:52:12 +02:00
|
|
|
|
#else
|
2012-05-18 11:57:51 +02:00
|
|
|
|
# define NEXT_JUMP() goto vm_start
|
2012-05-18 11:52:12 +02:00
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
#define NEXT \
|
|
|
|
|
|
{ \
|
|
|
|
|
|
NEXT_HOOK (); \
|
|
|
|
|
|
CHECK_STACK_LEAK (); \
|
|
|
|
|
|
NEXT_JUMP (); \
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* See frames.h for the layout of stack frames */
|
|
|
|
|
|
/* When this is called, bp points to the new program data,
|
|
|
|
|
|
and the arguments are already on the stack */
|
|
|
|
|
|
#define DROP_FRAME() \
|
|
|
|
|
|
{ \
|
|
|
|
|
|
sp -= 3; \
|
|
|
|
|
|
NULLSTACK (3); \
|
|
|
|
|
|
CHECK_UNDERFLOW (); \
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2005-04-28 15:45:59 +00:00
|
|
|
|
|
2000-08-22 15:54:19 +00:00
|
|
|
|
static SCM
|
rework vm tracing
* libguile/vm-engine.c (VM_NAME): Engines take the VM itself (not the
vp), so they can pass the VM to hooks. No more hook args, we dispatch
without them.
* libguile/vm-engine.h (RUN_HOOK): Dispatch the hook if the trace level
is positive (instead of if the hook is there). Don't cache registers
on return from the dispatch.
* libguile/vm.h:
* libguile/vm.c (vm_dispatch_hook): Don't bother with a dynwind; instead
decrement the trace level when going into a hook, and if we have a
nonlocal exit, the trace level never gets incremented again. Worse is
better.
(make_vm, scm_vm_trace_level, scm_set_vm_trace_level_x): New concept,
trace level. If positive, we run the hooks, otherwise we don't. Should
work. Removed scm_vm_trace_frame, I don't think that was the right way
to do it.
* module/system/vm/vm.scm: Replace vm-trace-frame with vm-trace-level
and set-vm-trace-level!; the hooks actually get the frame as an
argument now.
2009-12-21 21:57:20 +01:00
|
|
|
|
VM_NAME (SCM vm, SCM program, SCM *argv, int nargs)
|
2000-08-22 15:54:19 +00:00
|
|
|
|
{
|
2001-04-01 05:03:41 +00:00
|
|
|
|
/* VM registers */
|
programs have their own tc7 now
* libguile/tags.h (scm_tc7_program):
* libguile/programs.h: Programs now have their own tc7 code. Fix up the
macros appropriately.
* libguile/programs.c: Remove smobby bits, leaving marking, printing,
and application for other parts of Guile.
* libguile/debug.c (scm_procedure_source):
* libguile/eval.c (scm_trampoline_0, scm_trampoline_1)
(scm_trampoline_2): Add cases for tc7_program.
* libguile/eval.i.c (CEVAL, SCM_APPLY):
* libguile/evalext.c (scm_self_evaluating_p):
* libguile/gc-card.c (scm_i_sweep_card, scm_i_tag_name):
* libguile/gc-mark.c (1):
* libguile/print.c (iprin1):
* libguile/procs.c (scm_procedure_p, scm_thunk_p)
* libguile/vm-i-system.c (make-closure): Adapt to new procedure
representation.
* libguile/procprop.c (scm_i_procedure_arity): Do the right thing for
programs.
* test-suite/tests/procprop.test ("procedure-arity"): Arity test now
succeeds.
* libguile/goops.c (scm_class_of): Programs now belong to the class
<procedure>, not a smob class.
* libguile/vm.h (struct vm, struct vm_cont):
* libguile/vm-engine.c (vm_engine):
* libguile/frames.h (SCM_FRAME_BYTE_CAST, struct vm_frame):
* libguile/frames.c (scm_c_make_vm_frame): Fix usages of scm_byte_t,
changing them to scm_t_uint8.
2009-08-20 14:27:38 +02:00
|
|
|
|
register scm_t_uint8 *ip IP_REG; /* instruction pointer */
|
2001-04-01 05:03:41 +00:00
|
|
|
|
register SCM *sp SP_REG; /* stack pointer */
|
|
|
|
|
|
register SCM *fp FP_REG; /* frame pointer */
|
rework vm tracing
* libguile/vm-engine.c (VM_NAME): Engines take the VM itself (not the
vp), so they can pass the VM to hooks. No more hook args, we dispatch
without them.
* libguile/vm-engine.h (RUN_HOOK): Dispatch the hook if the trace level
is positive (instead of if the hook is there). Don't cache registers
on return from the dispatch.
* libguile/vm.h:
* libguile/vm.c (vm_dispatch_hook): Don't bother with a dynwind; instead
decrement the trace level when going into a hook, and if we have a
nonlocal exit, the trace level never gets incremented again. Worse is
better.
(make_vm, scm_vm_trace_level, scm_set_vm_trace_level_x): New concept,
trace level. If positive, we run the hooks, otherwise we don't. Should
work. Removed scm_vm_trace_frame, I don't think that was the right way
to do it.
* module/system/vm/vm.scm: Replace vm-trace-frame with vm-trace-level
and set-vm-trace-level!; the hooks actually get the frame as an
argument now.
2009-12-21 21:57:20 +01:00
|
|
|
|
struct scm_vm *vp = SCM_VM_DATA (vm);
|
2000-08-22 15:54:19 +00:00
|
|
|
|
|
2000-08-22 19:02:22 +00:00
|
|
|
|
/* Cache variables */
|
static opcodes; refactor program/objcode division; use new assembly pipeline
* gdbinit: Untested attempts to get the stack fondling macros to deal
with the new program representation.
* libguile/frames.c (scm_vm_frame_arguments, scm_vm_frame_source)
(scm_vm_frame_local_ref, scm_vm_frame_local_set_x): SCM_PROGRAM_DATA is
a struct scm_objcode*.
* libguile/instructions.h:
* libguile/instructions.c: Hide the instruction table and the struct
scm_instruction structure; all access to instructions now goes through
procedures. This is because instructions are no longer in a packed
array indexed by opcode. Also, declare a mask that all instructions
should fit in.
* libguile/objcodes.h:
* libguile/objcodes.c: Rewrite so that object code directly maps its
arity and length from its bytecode. This makes it unnecessary to keep
this information in programs, allowing programs to be simple conses
between the code (objcodes) and data (the object table and the closure
variables).
* libguile/programs.c (scm_make_program): Rework so that make-program
takes objcode, an object table, and externals as arguments. It's much
clearer this way, and we avoid malloc().
* libguile/stacks.c (is_vm_bootstrap_frame): Update for program/objcode
changes.
* libguile/vm-engine.c (vm_run): Initialize the jump table on the first
run, with the opcodes declared in the instruction sources, and with bad
instructions raising an error instead of wandering off into the
Unknown.
* libguile/vm-engine.h (FETCH_LENGTH): Always represent lengths as 3
bytes. The old code was too error-prone.
(NEXT_JUMP): Mask the instruction with SCM_VM_INSTRUCTION_MASK.
(NEW_FRAME): Update for program/objcode changes.
* libguile/vm-expand.h (VM_DEFINE_FUNCTION, VM_DEFINE_INSTRUCTION)
(VM_DEFINE_LOADER): Update so that we explicitly specify opcodes, so
that we have a stable bytecode API.
* libguile/vm-i-loader.c: Update license to LGPLv2+. Explicitly declare
opcodes.
(load-integer): Use an int instead of a long as the accumulator; still
need to revisit this code at some point, I think.
(load-program): Simplify, thankfully!! Just creates the objcode slice
and rolls with it.
* libguile/vm-i-scheme.c: Number the opcodes explicitly.
* libguile/vm-i-system.c: Update license to LGPLv2+. Explicitly declare
opcodes.
(make-closure): Update for new program API.
* libguile/vm.c (vm_make_boot_program): Update for new program/objcode
API. Still a bit ugly.
(scm_load_compiled_with_vm): Update for new program/objcode API.
* module/language/assembly.scm (byte-length): Fix byte-length calculation
for loaders, and load-program.
(code-pack, code-unpack): Start to move things from (system vm conv)
here.
(object->code, code->object): More things from conv.scm.
* module/language/glil.scm (<glil-program>): Add a new field,
closure-level.
(make-glil-program, compute-closure-level): Calculate the "closure
level" when making a glil program. This is the maximum depth of
external binding refs in this closure.
(unparse-glil): Fix label serialization.
* module/language/glil/compile-assembly.scm (make-meta): Prepend #f for
the meta's object table, though maybe in the future we can avoid
creating assembly in the first place.
(assoc-ref-or-acons, object-index-and-alist): GRRR! Caught again by the
different sets of arguments to assoc and assoc-ref!
(glil->assembly): Attempt to make the <glil-program> case more
readable, and fix the bugs. Sorry I don't know how to comment this
change any more than this.
(glil->assembly): For <glil-module> serialize the whole key, not just
the name.
(dump-object): subprogram-code is already a list. Serialize integers as
strings, not u8vectors. Fix the order of lists and vectors.
* module/language/glil/spec.scm (glil): Switch orders, so we prefer glil
-> assembly -> objcode. Actually glil->objcode doesn't work any more,
needs to be removed I think.
* module/language/objcode/spec.scm (objcode->value):
s/objcode->program/make-program/.
* module/language/scheme/inline.scm: Add acons inline.
* module/system/vm/conv.scm (make-byte-decoder): Skip the first 8 bytes,
they are header. Handle subprograms properly. Still needs help though.
(decode-length): Lengths are always 3 bytes now.
* module/system/vm/disasm.scm: Superficial changes to keep things
working. I'd like to fix this better in the future.
* module/system/vm/frame.scm (bootstrap-frame?): Fixes for
program-bytecode.
* module/system/vm/program.scm: Export make-program. It's program-objcode
now, no more program-bytecode.
* module/system/vm/vm.scm (vm-load): Use make-program.
* test-suite/tests/asm-to-bytecode.test: New test, very minimal.
* module/system/vm/objcode.scm: Export word-size, byte-order, and
write-objcode.
2009-01-29 21:09:04 +01:00
|
|
|
|
struct scm_objcode *bp = NULL; /* program base pointer */
|
2001-04-01 05:03:41 +00:00
|
|
|
|
SCM *objects = NULL; /* constant objects */
|
2001-04-06 00:17:39 +00:00
|
|
|
|
SCM *stack_limit = vp->stack_limit; /* stack limit address */
|
abort always dispatches to VM bytecode, to detect same-invocation aborts
* libguile/control.h:
* libguile/control.c (scm_c_make_prompt): Take an extra arg, a cookie.
Continuations will be rewindable only if the abort has the same cookie
as the prompt.
(scm_at_abort): Redefine from scm_abort, and instead of taking rest
args, take the abort values as a list directly. Also, don't allow
rewinding, because we won't support rewinding the C stack with
delimited continuations.
* libguile/eval.c (eval): Adapt to scm_c_make_prompt change.
* libguile/vm-engine.c (vm_engine): Use vp->cookie to get a unique value
corresponding to this VM invocation.
* libguile/vm-i-system.c (prompt): Pass the cookie to scm_c_make_prompt.
(abort): Take an additional tail arg.
* libguile/vm.c (vm_abort): Parse out the abort tail arg. This is for
the @abort case, or the (apply abort ...) case.
(make_vm): Initialize the cookie to 0.
* libguile/vm.h (struct scm_vm): Add cookie.
* module/ice-9/boot-9.scm (abort): Define here as a trampoline to
@abort. Needed to make sure that a call to abort dispatches to a VM
opcode, so the cookie will be the same.
* module/language/tree-il.scm (<tree-il>): Add a "tail" field to
<abort>, for the (apply abort ...) case, or (@abort tag args). Should
be #<const ()> in the normal case. Add support throughout.
* module/language/tree-il/analyze.scm (analyze-lexicals): Add abort-tail
support here too.
* module/language/tree-il/compile-glil.scm (flatten): Compile the tail
argument appropriately.
* module/language/tree-il/primitives.scm (*primitive-expand-table*): Fix
@abort and abort cases to pass the tail arg to make-abort.
2010-02-22 21:53:24 +01:00
|
|
|
|
|
2011-05-06 00:17:35 +02:00
|
|
|
|
scm_i_thread *current_thread = SCM_I_CURRENT_THREAD;
|
2000-08-22 15:54:19 +00:00
|
|
|
|
|
2000-08-22 19:02:22 +00:00
|
|
|
|
/* Internal variables */
|
2008-09-15 00:04:34 +02:00
|
|
|
|
int nvalues = 0;
|
dynstack: pushing a prompt no longer allocates memory
* libguile/control.h: Remove scm_t_prompt_registers and
scm_c_make_prompt_registers.
(scm_c_abort): Take a pointer to a jmpbuf instead of a cookie. It
will serve the same purpose.
* libguile/control.c (reify_partial_continuation, scm_at_abort): Adapt
to new prompt representation.
* libguile/dynstack.h:
* libguile/dynstack.c (scm_dynstack_push_prompt): Prompts now have 5
words instead of 2, as they now push the fp, sp, ip, and jmpbuf on the
stack separately. This avoids allocation.
(scm_dynstack_find_prompt): Likewise, add return values for fp, sp,
etc.
(scm_dynstack_wind_prompt): Replaces scm_dynstack_relocate_prompt.
* libguile/eval.c (eval):
* libguile/stacks.c (find_prompt):
* libguile/throw.c (pre_init_catch): Adapt to the new prompt mechanism.
* libguile/vm-engine.c (vm_engine): Setjmp an on-stack jmpbuf every time
the VM enters. We can then re-use that jmpbuf for all prompts in that
invocation.
* libguile/vm-i-system.c (partial_cont_call): Adapt to change in prompt
representation. We don't need to wind here any more, since we pass in
the prompt's jmpbuf.
(prompt): Adapt to scm_dynstack_push_prompt change.
(abort): Adapt to vm_abort change.
* libguile/vm.h (struct scm_vm): No more cookie.
* libguile/vm.c (vm_abort): Adapt to scm_c_abort change.
(vm_reinstate_partial_continuation): Rewind the dynamic stack here,
now that we do have a valid jmpbuf.
(make_vm): No need to initialize a cookie.
2012-03-07 10:27:16 +01:00
|
|
|
|
scm_i_jmp_buf registers; /* used for prompts */
|
|
|
|
|
|
|
static opcodes; refactor program/objcode division; use new assembly pipeline
* gdbinit: Untested attempts to get the stack fondling macros to deal
with the new program representation.
* libguile/frames.c (scm_vm_frame_arguments, scm_vm_frame_source)
(scm_vm_frame_local_ref, scm_vm_frame_local_set_x): SCM_PROGRAM_DATA is
a struct scm_objcode*.
* libguile/instructions.h:
* libguile/instructions.c: Hide the instruction table and the struct
scm_instruction structure; all access to instructions now goes through
procedures. This is because instructions are no longer in a packed
array indexed by opcode. Also, declare a mask that all instructions
should fit in.
* libguile/objcodes.h:
* libguile/objcodes.c: Rewrite so that object code directly maps its
arity and length from its bytecode. This makes it unnecessary to keep
this information in programs, allowing programs to be simple conses
between the code (objcodes) and data (the object table and the closure
variables).
* libguile/programs.c (scm_make_program): Rework so that make-program
takes objcode, an object table, and externals as arguments. It's much
clearer this way, and we avoid malloc().
* libguile/stacks.c (is_vm_bootstrap_frame): Update for program/objcode
changes.
* libguile/vm-engine.c (vm_run): Initialize the jump table on the first
run, with the opcodes declared in the instruction sources, and with bad
instructions raising an error instead of wandering off into the
Unknown.
* libguile/vm-engine.h (FETCH_LENGTH): Always represent lengths as 3
bytes. The old code was too error-prone.
(NEXT_JUMP): Mask the instruction with SCM_VM_INSTRUCTION_MASK.
(NEW_FRAME): Update for program/objcode changes.
* libguile/vm-expand.h (VM_DEFINE_FUNCTION, VM_DEFINE_INSTRUCTION)
(VM_DEFINE_LOADER): Update so that we explicitly specify opcodes, so
that we have a stable bytecode API.
* libguile/vm-i-loader.c: Update license to LGPLv2+. Explicitly declare
opcodes.
(load-integer): Use an int instead of a long as the accumulator; still
need to revisit this code at some point, I think.
(load-program): Simplify, thankfully!! Just creates the objcode slice
and rolls with it.
* libguile/vm-i-scheme.c: Number the opcodes explicitly.
* libguile/vm-i-system.c: Update license to LGPLv2+. Explicitly declare
opcodes.
(make-closure): Update for new program API.
* libguile/vm.c (vm_make_boot_program): Update for new program/objcode
API. Still a bit ugly.
(scm_load_compiled_with_vm): Update for new program/objcode API.
* module/language/assembly.scm (byte-length): Fix byte-length calculation
for loaders, and load-program.
(code-pack, code-unpack): Start to move things from (system vm conv)
here.
(object->code, code->object): More things from conv.scm.
* module/language/glil.scm (<glil-program>): Add a new field,
closure-level.
(make-glil-program, compute-closure-level): Calculate the "closure
level" when making a glil program. This is the maximum depth of
external binding refs in this closure.
(unparse-glil): Fix label serialization.
* module/language/glil/compile-assembly.scm (make-meta): Prepend #f for
the meta's object table, though maybe in the future we can avoid
creating assembly in the first place.
(assoc-ref-or-acons, object-index-and-alist): GRRR! Caught again by the
different sets of arguments to assoc and assoc-ref!
(glil->assembly): Attempt to make the <glil-program> case more
readable, and fix the bugs. Sorry I don't know how to comment this
change any more than this.
(glil->assembly): For <glil-module> serialize the whole key, not just
the name.
(dump-object): subprogram-code is already a list. Serialize integers as
strings, not u8vectors. Fix the order of lists and vectors.
* module/language/glil/spec.scm (glil): Switch orders, so we prefer glil
-> assembly -> objcode. Actually glil->objcode doesn't work any more,
needs to be removed I think.
* module/language/objcode/spec.scm (objcode->value):
s/objcode->program/make-program/.
* module/language/scheme/inline.scm: Add acons inline.
* module/system/vm/conv.scm (make-byte-decoder): Skip the first 8 bytes,
they are header. Handle subprograms properly. Still needs help though.
(decode-length): Lengths are always 3 bytes now.
* module/system/vm/disasm.scm: Superficial changes to keep things
working. I'd like to fix this better in the future.
* module/system/vm/frame.scm (bootstrap-frame?): Fixes for
program-bytecode.
* module/system/vm/program.scm: Export make-program. It's program-objcode
now, no more program-bytecode.
* module/system/vm/vm.scm (vm-load): Use make-program.
* test-suite/tests/asm-to-bytecode.test: New test, very minimal.
* module/system/vm/objcode.scm: Export word-size, byte-order, and
write-objcode.
2009-01-29 21:09:04 +01:00
|
|
|
|
#ifdef HAVE_LABELS_AS_VALUES
|
2011-07-04 23:56:16 +02:00
|
|
|
|
static const void **jump_table_pointer = NULL;
|
2009-02-05 12:28:19 +01:00
|
|
|
|
#endif
|
2011-07-04 23:56:16 +02:00
|
|
|
|
|
2009-02-05 12:28:19 +01:00
|
|
|
|
#ifdef HAVE_LABELS_AS_VALUES
|
2011-07-04 23:56:16 +02:00
|
|
|
|
register const void **jump_table JT_REG;
|
|
|
|
|
|
|
|
|
|
|
|
if (SCM_UNLIKELY (!jump_table_pointer))
|
static opcodes; refactor program/objcode division; use new assembly pipeline
* gdbinit: Untested attempts to get the stack fondling macros to deal
with the new program representation.
* libguile/frames.c (scm_vm_frame_arguments, scm_vm_frame_source)
(scm_vm_frame_local_ref, scm_vm_frame_local_set_x): SCM_PROGRAM_DATA is
a struct scm_objcode*.
* libguile/instructions.h:
* libguile/instructions.c: Hide the instruction table and the struct
scm_instruction structure; all access to instructions now goes through
procedures. This is because instructions are no longer in a packed
array indexed by opcode. Also, declare a mask that all instructions
should fit in.
* libguile/objcodes.h:
* libguile/objcodes.c: Rewrite so that object code directly maps its
arity and length from its bytecode. This makes it unnecessary to keep
this information in programs, allowing programs to be simple conses
between the code (objcodes) and data (the object table and the closure
variables).
* libguile/programs.c (scm_make_program): Rework so that make-program
takes objcode, an object table, and externals as arguments. It's much
clearer this way, and we avoid malloc().
* libguile/stacks.c (is_vm_bootstrap_frame): Update for program/objcode
changes.
* libguile/vm-engine.c (vm_run): Initialize the jump table on the first
run, with the opcodes declared in the instruction sources, and with bad
instructions raising an error instead of wandering off into the
Unknown.
* libguile/vm-engine.h (FETCH_LENGTH): Always represent lengths as 3
bytes. The old code was too error-prone.
(NEXT_JUMP): Mask the instruction with SCM_VM_INSTRUCTION_MASK.
(NEW_FRAME): Update for program/objcode changes.
* libguile/vm-expand.h (VM_DEFINE_FUNCTION, VM_DEFINE_INSTRUCTION)
(VM_DEFINE_LOADER): Update so that we explicitly specify opcodes, so
that we have a stable bytecode API.
* libguile/vm-i-loader.c: Update license to LGPLv2+. Explicitly declare
opcodes.
(load-integer): Use an int instead of a long as the accumulator; still
need to revisit this code at some point, I think.
(load-program): Simplify, thankfully!! Just creates the objcode slice
and rolls with it.
* libguile/vm-i-scheme.c: Number the opcodes explicitly.
* libguile/vm-i-system.c: Update license to LGPLv2+. Explicitly declare
opcodes.
(make-closure): Update for new program API.
* libguile/vm.c (vm_make_boot_program): Update for new program/objcode
API. Still a bit ugly.
(scm_load_compiled_with_vm): Update for new program/objcode API.
* module/language/assembly.scm (byte-length): Fix byte-length calculation
for loaders, and load-program.
(code-pack, code-unpack): Start to move things from (system vm conv)
here.
(object->code, code->object): More things from conv.scm.
* module/language/glil.scm (<glil-program>): Add a new field,
closure-level.
(make-glil-program, compute-closure-level): Calculate the "closure
level" when making a glil program. This is the maximum depth of
external binding refs in this closure.
(unparse-glil): Fix label serialization.
* module/language/glil/compile-assembly.scm (make-meta): Prepend #f for
the meta's object table, though maybe in the future we can avoid
creating assembly in the first place.
(assoc-ref-or-acons, object-index-and-alist): GRRR! Caught again by the
different sets of arguments to assoc and assoc-ref!
(glil->assembly): Attempt to make the <glil-program> case more
readable, and fix the bugs. Sorry I don't know how to comment this
change any more than this.
(glil->assembly): For <glil-module> serialize the whole key, not just
the name.
(dump-object): subprogram-code is already a list. Serialize integers as
strings, not u8vectors. Fix the order of lists and vectors.
* module/language/glil/spec.scm (glil): Switch orders, so we prefer glil
-> assembly -> objcode. Actually glil->objcode doesn't work any more,
needs to be removed I think.
* module/language/objcode/spec.scm (objcode->value):
s/objcode->program/make-program/.
* module/language/scheme/inline.scm: Add acons inline.
* module/system/vm/conv.scm (make-byte-decoder): Skip the first 8 bytes,
they are header. Handle subprograms properly. Still needs help though.
(decode-length): Lengths are always 3 bytes now.
* module/system/vm/disasm.scm: Superficial changes to keep things
working. I'd like to fix this better in the future.
* module/system/vm/frame.scm (bootstrap-frame?): Fixes for
program-bytecode.
* module/system/vm/program.scm: Export make-program. It's program-objcode
now, no more program-bytecode.
* module/system/vm/vm.scm (vm-load): Use make-program.
* test-suite/tests/asm-to-bytecode.test: New test, very minimal.
* module/system/vm/objcode.scm: Export word-size, byte-order, and
write-objcode.
2009-01-29 21:09:04 +01:00
|
|
|
|
{
|
|
|
|
|
|
int i;
|
2011-07-04 23:56:16 +02:00
|
|
|
|
jump_table_pointer = malloc (SCM_VM_NUM_INSTRUCTIONS * sizeof (void*));
|
static opcodes; refactor program/objcode division; use new assembly pipeline
* gdbinit: Untested attempts to get the stack fondling macros to deal
with the new program representation.
* libguile/frames.c (scm_vm_frame_arguments, scm_vm_frame_source)
(scm_vm_frame_local_ref, scm_vm_frame_local_set_x): SCM_PROGRAM_DATA is
a struct scm_objcode*.
* libguile/instructions.h:
* libguile/instructions.c: Hide the instruction table and the struct
scm_instruction structure; all access to instructions now goes through
procedures. This is because instructions are no longer in a packed
array indexed by opcode. Also, declare a mask that all instructions
should fit in.
* libguile/objcodes.h:
* libguile/objcodes.c: Rewrite so that object code directly maps its
arity and length from its bytecode. This makes it unnecessary to keep
this information in programs, allowing programs to be simple conses
between the code (objcodes) and data (the object table and the closure
variables).
* libguile/programs.c (scm_make_program): Rework so that make-program
takes objcode, an object table, and externals as arguments. It's much
clearer this way, and we avoid malloc().
* libguile/stacks.c (is_vm_bootstrap_frame): Update for program/objcode
changes.
* libguile/vm-engine.c (vm_run): Initialize the jump table on the first
run, with the opcodes declared in the instruction sources, and with bad
instructions raising an error instead of wandering off into the
Unknown.
* libguile/vm-engine.h (FETCH_LENGTH): Always represent lengths as 3
bytes. The old code was too error-prone.
(NEXT_JUMP): Mask the instruction with SCM_VM_INSTRUCTION_MASK.
(NEW_FRAME): Update for program/objcode changes.
* libguile/vm-expand.h (VM_DEFINE_FUNCTION, VM_DEFINE_INSTRUCTION)
(VM_DEFINE_LOADER): Update so that we explicitly specify opcodes, so
that we have a stable bytecode API.
* libguile/vm-i-loader.c: Update license to LGPLv2+. Explicitly declare
opcodes.
(load-integer): Use an int instead of a long as the accumulator; still
need to revisit this code at some point, I think.
(load-program): Simplify, thankfully!! Just creates the objcode slice
and rolls with it.
* libguile/vm-i-scheme.c: Number the opcodes explicitly.
* libguile/vm-i-system.c: Update license to LGPLv2+. Explicitly declare
opcodes.
(make-closure): Update for new program API.
* libguile/vm.c (vm_make_boot_program): Update for new program/objcode
API. Still a bit ugly.
(scm_load_compiled_with_vm): Update for new program/objcode API.
* module/language/assembly.scm (byte-length): Fix byte-length calculation
for loaders, and load-program.
(code-pack, code-unpack): Start to move things from (system vm conv)
here.
(object->code, code->object): More things from conv.scm.
* module/language/glil.scm (<glil-program>): Add a new field,
closure-level.
(make-glil-program, compute-closure-level): Calculate the "closure
level" when making a glil program. This is the maximum depth of
external binding refs in this closure.
(unparse-glil): Fix label serialization.
* module/language/glil/compile-assembly.scm (make-meta): Prepend #f for
the meta's object table, though maybe in the future we can avoid
creating assembly in the first place.
(assoc-ref-or-acons, object-index-and-alist): GRRR! Caught again by the
different sets of arguments to assoc and assoc-ref!
(glil->assembly): Attempt to make the <glil-program> case more
readable, and fix the bugs. Sorry I don't know how to comment this
change any more than this.
(glil->assembly): For <glil-module> serialize the whole key, not just
the name.
(dump-object): subprogram-code is already a list. Serialize integers as
strings, not u8vectors. Fix the order of lists and vectors.
* module/language/glil/spec.scm (glil): Switch orders, so we prefer glil
-> assembly -> objcode. Actually glil->objcode doesn't work any more,
needs to be removed I think.
* module/language/objcode/spec.scm (objcode->value):
s/objcode->program/make-program/.
* module/language/scheme/inline.scm: Add acons inline.
* module/system/vm/conv.scm (make-byte-decoder): Skip the first 8 bytes,
they are header. Handle subprograms properly. Still needs help though.
(decode-length): Lengths are always 3 bytes now.
* module/system/vm/disasm.scm: Superficial changes to keep things
working. I'd like to fix this better in the future.
* module/system/vm/frame.scm (bootstrap-frame?): Fixes for
program-bytecode.
* module/system/vm/program.scm: Export make-program. It's program-objcode
now, no more program-bytecode.
* module/system/vm/vm.scm (vm-load): Use make-program.
* test-suite/tests/asm-to-bytecode.test: New test, very minimal.
* module/system/vm/objcode.scm: Export word-size, byte-order, and
write-objcode.
2009-01-29 21:09:04 +01:00
|
|
|
|
for (i = 0; i < SCM_VM_NUM_INSTRUCTIONS; i++)
|
2011-07-04 23:56:16 +02:00
|
|
|
|
jump_table_pointer[i] = &&vm_error_bad_instruction;
|
static opcodes; refactor program/objcode division; use new assembly pipeline
* gdbinit: Untested attempts to get the stack fondling macros to deal
with the new program representation.
* libguile/frames.c (scm_vm_frame_arguments, scm_vm_frame_source)
(scm_vm_frame_local_ref, scm_vm_frame_local_set_x): SCM_PROGRAM_DATA is
a struct scm_objcode*.
* libguile/instructions.h:
* libguile/instructions.c: Hide the instruction table and the struct
scm_instruction structure; all access to instructions now goes through
procedures. This is because instructions are no longer in a packed
array indexed by opcode. Also, declare a mask that all instructions
should fit in.
* libguile/objcodes.h:
* libguile/objcodes.c: Rewrite so that object code directly maps its
arity and length from its bytecode. This makes it unnecessary to keep
this information in programs, allowing programs to be simple conses
between the code (objcodes) and data (the object table and the closure
variables).
* libguile/programs.c (scm_make_program): Rework so that make-program
takes objcode, an object table, and externals as arguments. It's much
clearer this way, and we avoid malloc().
* libguile/stacks.c (is_vm_bootstrap_frame): Update for program/objcode
changes.
* libguile/vm-engine.c (vm_run): Initialize the jump table on the first
run, with the opcodes declared in the instruction sources, and with bad
instructions raising an error instead of wandering off into the
Unknown.
* libguile/vm-engine.h (FETCH_LENGTH): Always represent lengths as 3
bytes. The old code was too error-prone.
(NEXT_JUMP): Mask the instruction with SCM_VM_INSTRUCTION_MASK.
(NEW_FRAME): Update for program/objcode changes.
* libguile/vm-expand.h (VM_DEFINE_FUNCTION, VM_DEFINE_INSTRUCTION)
(VM_DEFINE_LOADER): Update so that we explicitly specify opcodes, so
that we have a stable bytecode API.
* libguile/vm-i-loader.c: Update license to LGPLv2+. Explicitly declare
opcodes.
(load-integer): Use an int instead of a long as the accumulator; still
need to revisit this code at some point, I think.
(load-program): Simplify, thankfully!! Just creates the objcode slice
and rolls with it.
* libguile/vm-i-scheme.c: Number the opcodes explicitly.
* libguile/vm-i-system.c: Update license to LGPLv2+. Explicitly declare
opcodes.
(make-closure): Update for new program API.
* libguile/vm.c (vm_make_boot_program): Update for new program/objcode
API. Still a bit ugly.
(scm_load_compiled_with_vm): Update for new program/objcode API.
* module/language/assembly.scm (byte-length): Fix byte-length calculation
for loaders, and load-program.
(code-pack, code-unpack): Start to move things from (system vm conv)
here.
(object->code, code->object): More things from conv.scm.
* module/language/glil.scm (<glil-program>): Add a new field,
closure-level.
(make-glil-program, compute-closure-level): Calculate the "closure
level" when making a glil program. This is the maximum depth of
external binding refs in this closure.
(unparse-glil): Fix label serialization.
* module/language/glil/compile-assembly.scm (make-meta): Prepend #f for
the meta's object table, though maybe in the future we can avoid
creating assembly in the first place.
(assoc-ref-or-acons, object-index-and-alist): GRRR! Caught again by the
different sets of arguments to assoc and assoc-ref!
(glil->assembly): Attempt to make the <glil-program> case more
readable, and fix the bugs. Sorry I don't know how to comment this
change any more than this.
(glil->assembly): For <glil-module> serialize the whole key, not just
the name.
(dump-object): subprogram-code is already a list. Serialize integers as
strings, not u8vectors. Fix the order of lists and vectors.
* module/language/glil/spec.scm (glil): Switch orders, so we prefer glil
-> assembly -> objcode. Actually glil->objcode doesn't work any more,
needs to be removed I think.
* module/language/objcode/spec.scm (objcode->value):
s/objcode->program/make-program/.
* module/language/scheme/inline.scm: Add acons inline.
* module/system/vm/conv.scm (make-byte-decoder): Skip the first 8 bytes,
they are header. Handle subprograms properly. Still needs help though.
(decode-length): Lengths are always 3 bytes now.
* module/system/vm/disasm.scm: Superficial changes to keep things
working. I'd like to fix this better in the future.
* module/system/vm/frame.scm (bootstrap-frame?): Fixes for
program-bytecode.
* module/system/vm/program.scm: Export make-program. It's program-objcode
now, no more program-bytecode.
* module/system/vm/vm.scm (vm-load): Use make-program.
* test-suite/tests/asm-to-bytecode.test: New test, very minimal.
* module/system/vm/objcode.scm: Export word-size, byte-order, and
write-objcode.
2009-01-29 21:09:04 +01:00
|
|
|
|
#define VM_INSTRUCTION_TO_LABEL 1
|
2011-07-04 23:56:16 +02:00
|
|
|
|
#define jump_table jump_table_pointer
|
2009-03-16 23:39:29 +01:00
|
|
|
|
#include <libguile/vm-expand.h>
|
|
|
|
|
|
#include <libguile/vm-i-system.i>
|
|
|
|
|
|
#include <libguile/vm-i-scheme.i>
|
|
|
|
|
|
#include <libguile/vm-i-loader.i>
|
2011-07-04 23:56:16 +02:00
|
|
|
|
#undef jump_table
|
static opcodes; refactor program/objcode division; use new assembly pipeline
* gdbinit: Untested attempts to get the stack fondling macros to deal
with the new program representation.
* libguile/frames.c (scm_vm_frame_arguments, scm_vm_frame_source)
(scm_vm_frame_local_ref, scm_vm_frame_local_set_x): SCM_PROGRAM_DATA is
a struct scm_objcode*.
* libguile/instructions.h:
* libguile/instructions.c: Hide the instruction table and the struct
scm_instruction structure; all access to instructions now goes through
procedures. This is because instructions are no longer in a packed
array indexed by opcode. Also, declare a mask that all instructions
should fit in.
* libguile/objcodes.h:
* libguile/objcodes.c: Rewrite so that object code directly maps its
arity and length from its bytecode. This makes it unnecessary to keep
this information in programs, allowing programs to be simple conses
between the code (objcodes) and data (the object table and the closure
variables).
* libguile/programs.c (scm_make_program): Rework so that make-program
takes objcode, an object table, and externals as arguments. It's much
clearer this way, and we avoid malloc().
* libguile/stacks.c (is_vm_bootstrap_frame): Update for program/objcode
changes.
* libguile/vm-engine.c (vm_run): Initialize the jump table on the first
run, with the opcodes declared in the instruction sources, and with bad
instructions raising an error instead of wandering off into the
Unknown.
* libguile/vm-engine.h (FETCH_LENGTH): Always represent lengths as 3
bytes. The old code was too error-prone.
(NEXT_JUMP): Mask the instruction with SCM_VM_INSTRUCTION_MASK.
(NEW_FRAME): Update for program/objcode changes.
* libguile/vm-expand.h (VM_DEFINE_FUNCTION, VM_DEFINE_INSTRUCTION)
(VM_DEFINE_LOADER): Update so that we explicitly specify opcodes, so
that we have a stable bytecode API.
* libguile/vm-i-loader.c: Update license to LGPLv2+. Explicitly declare
opcodes.
(load-integer): Use an int instead of a long as the accumulator; still
need to revisit this code at some point, I think.
(load-program): Simplify, thankfully!! Just creates the objcode slice
and rolls with it.
* libguile/vm-i-scheme.c: Number the opcodes explicitly.
* libguile/vm-i-system.c: Update license to LGPLv2+. Explicitly declare
opcodes.
(make-closure): Update for new program API.
* libguile/vm.c (vm_make_boot_program): Update for new program/objcode
API. Still a bit ugly.
(scm_load_compiled_with_vm): Update for new program/objcode API.
* module/language/assembly.scm (byte-length): Fix byte-length calculation
for loaders, and load-program.
(code-pack, code-unpack): Start to move things from (system vm conv)
here.
(object->code, code->object): More things from conv.scm.
* module/language/glil.scm (<glil-program>): Add a new field,
closure-level.
(make-glil-program, compute-closure-level): Calculate the "closure
level" when making a glil program. This is the maximum depth of
external binding refs in this closure.
(unparse-glil): Fix label serialization.
* module/language/glil/compile-assembly.scm (make-meta): Prepend #f for
the meta's object table, though maybe in the future we can avoid
creating assembly in the first place.
(assoc-ref-or-acons, object-index-and-alist): GRRR! Caught again by the
different sets of arguments to assoc and assoc-ref!
(glil->assembly): Attempt to make the <glil-program> case more
readable, and fix the bugs. Sorry I don't know how to comment this
change any more than this.
(glil->assembly): For <glil-module> serialize the whole key, not just
the name.
(dump-object): subprogram-code is already a list. Serialize integers as
strings, not u8vectors. Fix the order of lists and vectors.
* module/language/glil/spec.scm (glil): Switch orders, so we prefer glil
-> assembly -> objcode. Actually glil->objcode doesn't work any more,
needs to be removed I think.
* module/language/objcode/spec.scm (objcode->value):
s/objcode->program/make-program/.
* module/language/scheme/inline.scm: Add acons inline.
* module/system/vm/conv.scm (make-byte-decoder): Skip the first 8 bytes,
they are header. Handle subprograms properly. Still needs help though.
(decode-length): Lengths are always 3 bytes now.
* module/system/vm/disasm.scm: Superficial changes to keep things
working. I'd like to fix this better in the future.
* module/system/vm/frame.scm (bootstrap-frame?): Fixes for
program-bytecode.
* module/system/vm/program.scm: Export make-program. It's program-objcode
now, no more program-bytecode.
* module/system/vm/vm.scm (vm-load): Use make-program.
* test-suite/tests/asm-to-bytecode.test: New test, very minimal.
* module/system/vm/objcode.scm: Export word-size, byte-order, and
write-objcode.
2009-01-29 21:09:04 +01:00
|
|
|
|
#undef VM_INSTRUCTION_TO_LABEL
|
|
|
|
|
|
}
|
2011-07-04 23:56:16 +02:00
|
|
|
|
|
|
|
|
|
|
/* Attempt to keep JUMP_TABLE_POINTER in a register. This saves one
|
|
|
|
|
|
load instruction at each instruction dispatch. */
|
|
|
|
|
|
jump_table = jump_table_pointer;
|
static opcodes; refactor program/objcode division; use new assembly pipeline
* gdbinit: Untested attempts to get the stack fondling macros to deal
with the new program representation.
* libguile/frames.c (scm_vm_frame_arguments, scm_vm_frame_source)
(scm_vm_frame_local_ref, scm_vm_frame_local_set_x): SCM_PROGRAM_DATA is
a struct scm_objcode*.
* libguile/instructions.h:
* libguile/instructions.c: Hide the instruction table and the struct
scm_instruction structure; all access to instructions now goes through
procedures. This is because instructions are no longer in a packed
array indexed by opcode. Also, declare a mask that all instructions
should fit in.
* libguile/objcodes.h:
* libguile/objcodes.c: Rewrite so that object code directly maps its
arity and length from its bytecode. This makes it unnecessary to keep
this information in programs, allowing programs to be simple conses
between the code (objcodes) and data (the object table and the closure
variables).
* libguile/programs.c (scm_make_program): Rework so that make-program
takes objcode, an object table, and externals as arguments. It's much
clearer this way, and we avoid malloc().
* libguile/stacks.c (is_vm_bootstrap_frame): Update for program/objcode
changes.
* libguile/vm-engine.c (vm_run): Initialize the jump table on the first
run, with the opcodes declared in the instruction sources, and with bad
instructions raising an error instead of wandering off into the
Unknown.
* libguile/vm-engine.h (FETCH_LENGTH): Always represent lengths as 3
bytes. The old code was too error-prone.
(NEXT_JUMP): Mask the instruction with SCM_VM_INSTRUCTION_MASK.
(NEW_FRAME): Update for program/objcode changes.
* libguile/vm-expand.h (VM_DEFINE_FUNCTION, VM_DEFINE_INSTRUCTION)
(VM_DEFINE_LOADER): Update so that we explicitly specify opcodes, so
that we have a stable bytecode API.
* libguile/vm-i-loader.c: Update license to LGPLv2+. Explicitly declare
opcodes.
(load-integer): Use an int instead of a long as the accumulator; still
need to revisit this code at some point, I think.
(load-program): Simplify, thankfully!! Just creates the objcode slice
and rolls with it.
* libguile/vm-i-scheme.c: Number the opcodes explicitly.
* libguile/vm-i-system.c: Update license to LGPLv2+. Explicitly declare
opcodes.
(make-closure): Update for new program API.
* libguile/vm.c (vm_make_boot_program): Update for new program/objcode
API. Still a bit ugly.
(scm_load_compiled_with_vm): Update for new program/objcode API.
* module/language/assembly.scm (byte-length): Fix byte-length calculation
for loaders, and load-program.
(code-pack, code-unpack): Start to move things from (system vm conv)
here.
(object->code, code->object): More things from conv.scm.
* module/language/glil.scm (<glil-program>): Add a new field,
closure-level.
(make-glil-program, compute-closure-level): Calculate the "closure
level" when making a glil program. This is the maximum depth of
external binding refs in this closure.
(unparse-glil): Fix label serialization.
* module/language/glil/compile-assembly.scm (make-meta): Prepend #f for
the meta's object table, though maybe in the future we can avoid
creating assembly in the first place.
(assoc-ref-or-acons, object-index-and-alist): GRRR! Caught again by the
different sets of arguments to assoc and assoc-ref!
(glil->assembly): Attempt to make the <glil-program> case more
readable, and fix the bugs. Sorry I don't know how to comment this
change any more than this.
(glil->assembly): For <glil-module> serialize the whole key, not just
the name.
(dump-object): subprogram-code is already a list. Serialize integers as
strings, not u8vectors. Fix the order of lists and vectors.
* module/language/glil/spec.scm (glil): Switch orders, so we prefer glil
-> assembly -> objcode. Actually glil->objcode doesn't work any more,
needs to be removed I think.
* module/language/objcode/spec.scm (objcode->value):
s/objcode->program/make-program/.
* module/language/scheme/inline.scm: Add acons inline.
* module/system/vm/conv.scm (make-byte-decoder): Skip the first 8 bytes,
they are header. Handle subprograms properly. Still needs help though.
(decode-length): Lengths are always 3 bytes now.
* module/system/vm/disasm.scm: Superficial changes to keep things
working. I'd like to fix this better in the future.
* module/system/vm/frame.scm (bootstrap-frame?): Fixes for
program-bytecode.
* module/system/vm/program.scm: Export make-program. It's program-objcode
now, no more program-bytecode.
* module/system/vm/vm.scm (vm-load): Use make-program.
* test-suite/tests/asm-to-bytecode.test: New test, very minimal.
* module/system/vm/objcode.scm: Export word-size, byte-order, and
write-objcode.
2009-01-29 21:09:04 +01:00
|
|
|
|
#endif
|
dynstack: pushing a prompt no longer allocates memory
* libguile/control.h: Remove scm_t_prompt_registers and
scm_c_make_prompt_registers.
(scm_c_abort): Take a pointer to a jmpbuf instead of a cookie. It
will serve the same purpose.
* libguile/control.c (reify_partial_continuation, scm_at_abort): Adapt
to new prompt representation.
* libguile/dynstack.h:
* libguile/dynstack.c (scm_dynstack_push_prompt): Prompts now have 5
words instead of 2, as they now push the fp, sp, ip, and jmpbuf on the
stack separately. This avoids allocation.
(scm_dynstack_find_prompt): Likewise, add return values for fp, sp,
etc.
(scm_dynstack_wind_prompt): Replaces scm_dynstack_relocate_prompt.
* libguile/eval.c (eval):
* libguile/stacks.c (find_prompt):
* libguile/throw.c (pre_init_catch): Adapt to the new prompt mechanism.
* libguile/vm-engine.c (vm_engine): Setjmp an on-stack jmpbuf every time
the VM enters. We can then re-use that jmpbuf for all prompts in that
invocation.
* libguile/vm-i-system.c (partial_cont_call): Adapt to change in prompt
representation. We don't need to wind here any more, since we pass in
the prompt's jmpbuf.
(prompt): Adapt to scm_dynstack_push_prompt change.
(abort): Adapt to vm_abort change.
* libguile/vm.h (struct scm_vm): No more cookie.
* libguile/vm.c (vm_abort): Adapt to scm_c_abort change.
(vm_reinstate_partial_continuation): Rewind the dynamic stack here,
now that we do have a valid jmpbuf.
(make_vm): No need to initialize a cookie.
2012-03-07 10:27:16 +01:00
|
|
|
|
|
|
|
|
|
|
if (SCM_I_SETJMP (registers))
|
|
|
|
|
|
{
|
|
|
|
|
|
/* Non-local return. Cache the VM registers back from the vp, and
|
|
|
|
|
|
go to the handler.
|
|
|
|
|
|
|
|
|
|
|
|
Note, at this point, we must assume that any variable local to
|
|
|
|
|
|
vm_engine that can be assigned *has* been assigned. So we need to pull
|
|
|
|
|
|
all our state back from the ip/fp/sp.
|
|
|
|
|
|
*/
|
|
|
|
|
|
CACHE_REGISTER ();
|
|
|
|
|
|
program = SCM_FRAME_PROGRAM (fp);
|
|
|
|
|
|
CACHE_PROGRAM ();
|
|
|
|
|
|
/* The stack contains the values returned to this continuation,
|
|
|
|
|
|
along with a number-of-values marker -- like an MV return. */
|
|
|
|
|
|
ABORT_CONTINUATION_HOOK ();
|
|
|
|
|
|
NEXT;
|
|
|
|
|
|
}
|
static opcodes; refactor program/objcode division; use new assembly pipeline
* gdbinit: Untested attempts to get the stack fondling macros to deal
with the new program representation.
* libguile/frames.c (scm_vm_frame_arguments, scm_vm_frame_source)
(scm_vm_frame_local_ref, scm_vm_frame_local_set_x): SCM_PROGRAM_DATA is
a struct scm_objcode*.
* libguile/instructions.h:
* libguile/instructions.c: Hide the instruction table and the struct
scm_instruction structure; all access to instructions now goes through
procedures. This is because instructions are no longer in a packed
array indexed by opcode. Also, declare a mask that all instructions
should fit in.
* libguile/objcodes.h:
* libguile/objcodes.c: Rewrite so that object code directly maps its
arity and length from its bytecode. This makes it unnecessary to keep
this information in programs, allowing programs to be simple conses
between the code (objcodes) and data (the object table and the closure
variables).
* libguile/programs.c (scm_make_program): Rework so that make-program
takes objcode, an object table, and externals as arguments. It's much
clearer this way, and we avoid malloc().
* libguile/stacks.c (is_vm_bootstrap_frame): Update for program/objcode
changes.
* libguile/vm-engine.c (vm_run): Initialize the jump table on the first
run, with the opcodes declared in the instruction sources, and with bad
instructions raising an error instead of wandering off into the
Unknown.
* libguile/vm-engine.h (FETCH_LENGTH): Always represent lengths as 3
bytes. The old code was too error-prone.
(NEXT_JUMP): Mask the instruction with SCM_VM_INSTRUCTION_MASK.
(NEW_FRAME): Update for program/objcode changes.
* libguile/vm-expand.h (VM_DEFINE_FUNCTION, VM_DEFINE_INSTRUCTION)
(VM_DEFINE_LOADER): Update so that we explicitly specify opcodes, so
that we have a stable bytecode API.
* libguile/vm-i-loader.c: Update license to LGPLv2+. Explicitly declare
opcodes.
(load-integer): Use an int instead of a long as the accumulator; still
need to revisit this code at some point, I think.
(load-program): Simplify, thankfully!! Just creates the objcode slice
and rolls with it.
* libguile/vm-i-scheme.c: Number the opcodes explicitly.
* libguile/vm-i-system.c: Update license to LGPLv2+. Explicitly declare
opcodes.
(make-closure): Update for new program API.
* libguile/vm.c (vm_make_boot_program): Update for new program/objcode
API. Still a bit ugly.
(scm_load_compiled_with_vm): Update for new program/objcode API.
* module/language/assembly.scm (byte-length): Fix byte-length calculation
for loaders, and load-program.
(code-pack, code-unpack): Start to move things from (system vm conv)
here.
(object->code, code->object): More things from conv.scm.
* module/language/glil.scm (<glil-program>): Add a new field,
closure-level.
(make-glil-program, compute-closure-level): Calculate the "closure
level" when making a glil program. This is the maximum depth of
external binding refs in this closure.
(unparse-glil): Fix label serialization.
* module/language/glil/compile-assembly.scm (make-meta): Prepend #f for
the meta's object table, though maybe in the future we can avoid
creating assembly in the first place.
(assoc-ref-or-acons, object-index-and-alist): GRRR! Caught again by the
different sets of arguments to assoc and assoc-ref!
(glil->assembly): Attempt to make the <glil-program> case more
readable, and fix the bugs. Sorry I don't know how to comment this
change any more than this.
(glil->assembly): For <glil-module> serialize the whole key, not just
the name.
(dump-object): subprogram-code is already a list. Serialize integers as
strings, not u8vectors. Fix the order of lists and vectors.
* module/language/glil/spec.scm (glil): Switch orders, so we prefer glil
-> assembly -> objcode. Actually glil->objcode doesn't work any more,
needs to be removed I think.
* module/language/objcode/spec.scm (objcode->value):
s/objcode->program/make-program/.
* module/language/scheme/inline.scm: Add acons inline.
* module/system/vm/conv.scm (make-byte-decoder): Skip the first 8 bytes,
they are header. Handle subprograms properly. Still needs help though.
(decode-length): Lengths are always 3 bytes now.
* module/system/vm/disasm.scm: Superficial changes to keep things
working. I'd like to fix this better in the future.
* module/system/vm/frame.scm (bootstrap-frame?): Fixes for
program-bytecode.
* module/system/vm/program.scm: Export make-program. It's program-objcode
now, no more program-bytecode.
* module/system/vm/vm.scm (vm-load): Use make-program.
* test-suite/tests/asm-to-bytecode.test: New test, very minimal.
* module/system/vm/objcode.scm: Export word-size, byte-order, and
write-objcode.
2009-01-29 21:09:04 +01:00
|
|
|
|
|
2012-05-10 12:43:33 +02:00
|
|
|
|
/* Initial frame */
|
|
|
|
|
|
CACHE_REGISTER ();
|
|
|
|
|
|
PUSH (SCM_PACK (fp)); /* dynamic link */
|
|
|
|
|
|
PUSH (SCM_PACK (0)); /* mvra */
|
|
|
|
|
|
PUSH (SCM_PACK (ip)); /* ra */
|
|
|
|
|
|
PUSH (boot_continuation);
|
|
|
|
|
|
fp = sp + 1;
|
|
|
|
|
|
ip = SCM_C_OBJCODE_BASE (SCM_PROGRAM_DATA (boot_continuation));
|
|
|
|
|
|
|
|
|
|
|
|
/* MV-call frame, function & arguments */
|
|
|
|
|
|
PUSH (SCM_PACK (fp)); /* dynamic link */
|
|
|
|
|
|
PUSH (SCM_PACK (ip + 1)); /* mvra */
|
|
|
|
|
|
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++);
|
|
|
|
|
|
|
|
|
|
|
|
PUSH_CONTINUATION_HOOK ();
|
|
|
|
|
|
|
|
|
|
|
|
apply:
|
|
|
|
|
|
program = fp[-1];
|
|
|
|
|
|
if (!SCM_PROGRAM_P (program))
|
|
|
|
|
|
{
|
|
|
|
|
|
if (SCM_STRUCTP (program) && SCM_STRUCT_APPLICABLE_P (program))
|
|
|
|
|
|
fp[-1] = SCM_STRUCT_PROCEDURE (program);
|
2012-05-10 13:02:11 +02:00
|
|
|
|
else if (SCM_HAS_TYP7 (program, scm_tc7_smob)
|
2012-05-10 12:43:33 +02:00
|
|
|
|
&& SCM_SMOB_APPLICABLE_P (program))
|
|
|
|
|
|
{
|
|
|
|
|
|
/* (smob arg0 ... argN) => (apply-smob smob arg0 ... argN) */
|
|
|
|
|
|
int i;
|
|
|
|
|
|
PUSH (SCM_BOOL_F);
|
|
|
|
|
|
for (i = sp - fp; i >= 0; i--)
|
|
|
|
|
|
fp[i] = fp[i - 1];
|
2012-05-10 13:02:11 +02:00
|
|
|
|
fp[-1] = SCM_SMOB_DESCRIPTOR (program).apply_trampoline;
|
2012-05-10 12:43:33 +02:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
SYNC_ALL();
|
|
|
|
|
|
vm_error_wrong_type_apply (program);
|
|
|
|
|
|
}
|
|
|
|
|
|
goto apply;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
CACHE_PROGRAM ();
|
|
|
|
|
|
ip = SCM_C_OBJCODE_BASE (bp);
|
|
|
|
|
|
|
|
|
|
|
|
APPLY_HOOK ();
|
2000-08-22 15:54:19 +00:00
|
|
|
|
|
|
|
|
|
|
/* Let's go! */
|
static opcodes; refactor program/objcode division; use new assembly pipeline
* gdbinit: Untested attempts to get the stack fondling macros to deal
with the new program representation.
* libguile/frames.c (scm_vm_frame_arguments, scm_vm_frame_source)
(scm_vm_frame_local_ref, scm_vm_frame_local_set_x): SCM_PROGRAM_DATA is
a struct scm_objcode*.
* libguile/instructions.h:
* libguile/instructions.c: Hide the instruction table and the struct
scm_instruction structure; all access to instructions now goes through
procedures. This is because instructions are no longer in a packed
array indexed by opcode. Also, declare a mask that all instructions
should fit in.
* libguile/objcodes.h:
* libguile/objcodes.c: Rewrite so that object code directly maps its
arity and length from its bytecode. This makes it unnecessary to keep
this information in programs, allowing programs to be simple conses
between the code (objcodes) and data (the object table and the closure
variables).
* libguile/programs.c (scm_make_program): Rework so that make-program
takes objcode, an object table, and externals as arguments. It's much
clearer this way, and we avoid malloc().
* libguile/stacks.c (is_vm_bootstrap_frame): Update for program/objcode
changes.
* libguile/vm-engine.c (vm_run): Initialize the jump table on the first
run, with the opcodes declared in the instruction sources, and with bad
instructions raising an error instead of wandering off into the
Unknown.
* libguile/vm-engine.h (FETCH_LENGTH): Always represent lengths as 3
bytes. The old code was too error-prone.
(NEXT_JUMP): Mask the instruction with SCM_VM_INSTRUCTION_MASK.
(NEW_FRAME): Update for program/objcode changes.
* libguile/vm-expand.h (VM_DEFINE_FUNCTION, VM_DEFINE_INSTRUCTION)
(VM_DEFINE_LOADER): Update so that we explicitly specify opcodes, so
that we have a stable bytecode API.
* libguile/vm-i-loader.c: Update license to LGPLv2+. Explicitly declare
opcodes.
(load-integer): Use an int instead of a long as the accumulator; still
need to revisit this code at some point, I think.
(load-program): Simplify, thankfully!! Just creates the objcode slice
and rolls with it.
* libguile/vm-i-scheme.c: Number the opcodes explicitly.
* libguile/vm-i-system.c: Update license to LGPLv2+. Explicitly declare
opcodes.
(make-closure): Update for new program API.
* libguile/vm.c (vm_make_boot_program): Update for new program/objcode
API. Still a bit ugly.
(scm_load_compiled_with_vm): Update for new program/objcode API.
* module/language/assembly.scm (byte-length): Fix byte-length calculation
for loaders, and load-program.
(code-pack, code-unpack): Start to move things from (system vm conv)
here.
(object->code, code->object): More things from conv.scm.
* module/language/glil.scm (<glil-program>): Add a new field,
closure-level.
(make-glil-program, compute-closure-level): Calculate the "closure
level" when making a glil program. This is the maximum depth of
external binding refs in this closure.
(unparse-glil): Fix label serialization.
* module/language/glil/compile-assembly.scm (make-meta): Prepend #f for
the meta's object table, though maybe in the future we can avoid
creating assembly in the first place.
(assoc-ref-or-acons, object-index-and-alist): GRRR! Caught again by the
different sets of arguments to assoc and assoc-ref!
(glil->assembly): Attempt to make the <glil-program> case more
readable, and fix the bugs. Sorry I don't know how to comment this
change any more than this.
(glil->assembly): For <glil-module> serialize the whole key, not just
the name.
(dump-object): subprogram-code is already a list. Serialize integers as
strings, not u8vectors. Fix the order of lists and vectors.
* module/language/glil/spec.scm (glil): Switch orders, so we prefer glil
-> assembly -> objcode. Actually glil->objcode doesn't work any more,
needs to be removed I think.
* module/language/objcode/spec.scm (objcode->value):
s/objcode->program/make-program/.
* module/language/scheme/inline.scm: Add acons inline.
* module/system/vm/conv.scm (make-byte-decoder): Skip the first 8 bytes,
they are header. Handle subprograms properly. Still needs help though.
(decode-length): Lengths are always 3 bytes now.
* module/system/vm/disasm.scm: Superficial changes to keep things
working. I'd like to fix this better in the future.
* module/system/vm/frame.scm (bootstrap-frame?): Fixes for
program-bytecode.
* module/system/vm/program.scm: Export make-program. It's program-objcode
now, no more program-bytecode.
* module/system/vm/vm.scm (vm-load): Use make-program.
* test-suite/tests/asm-to-bytecode.test: New test, very minimal.
* module/system/vm/objcode.scm: Export word-size, byte-order, and
write-objcode.
2009-01-29 21:09:04 +01:00
|
|
|
|
NEXT;
|
2000-08-22 15:54:19 +00:00
|
|
|
|
|
|
|
|
|
|
#ifndef HAVE_LABELS_AS_VALUES
|
2001-04-01 05:03:41 +00:00
|
|
|
|
vm_start:
|
static opcodes; refactor program/objcode division; use new assembly pipeline
* gdbinit: Untested attempts to get the stack fondling macros to deal
with the new program representation.
* libguile/frames.c (scm_vm_frame_arguments, scm_vm_frame_source)
(scm_vm_frame_local_ref, scm_vm_frame_local_set_x): SCM_PROGRAM_DATA is
a struct scm_objcode*.
* libguile/instructions.h:
* libguile/instructions.c: Hide the instruction table and the struct
scm_instruction structure; all access to instructions now goes through
procedures. This is because instructions are no longer in a packed
array indexed by opcode. Also, declare a mask that all instructions
should fit in.
* libguile/objcodes.h:
* libguile/objcodes.c: Rewrite so that object code directly maps its
arity and length from its bytecode. This makes it unnecessary to keep
this information in programs, allowing programs to be simple conses
between the code (objcodes) and data (the object table and the closure
variables).
* libguile/programs.c (scm_make_program): Rework so that make-program
takes objcode, an object table, and externals as arguments. It's much
clearer this way, and we avoid malloc().
* libguile/stacks.c (is_vm_bootstrap_frame): Update for program/objcode
changes.
* libguile/vm-engine.c (vm_run): Initialize the jump table on the first
run, with the opcodes declared in the instruction sources, and with bad
instructions raising an error instead of wandering off into the
Unknown.
* libguile/vm-engine.h (FETCH_LENGTH): Always represent lengths as 3
bytes. The old code was too error-prone.
(NEXT_JUMP): Mask the instruction with SCM_VM_INSTRUCTION_MASK.
(NEW_FRAME): Update for program/objcode changes.
* libguile/vm-expand.h (VM_DEFINE_FUNCTION, VM_DEFINE_INSTRUCTION)
(VM_DEFINE_LOADER): Update so that we explicitly specify opcodes, so
that we have a stable bytecode API.
* libguile/vm-i-loader.c: Update license to LGPLv2+. Explicitly declare
opcodes.
(load-integer): Use an int instead of a long as the accumulator; still
need to revisit this code at some point, I think.
(load-program): Simplify, thankfully!! Just creates the objcode slice
and rolls with it.
* libguile/vm-i-scheme.c: Number the opcodes explicitly.
* libguile/vm-i-system.c: Update license to LGPLv2+. Explicitly declare
opcodes.
(make-closure): Update for new program API.
* libguile/vm.c (vm_make_boot_program): Update for new program/objcode
API. Still a bit ugly.
(scm_load_compiled_with_vm): Update for new program/objcode API.
* module/language/assembly.scm (byte-length): Fix byte-length calculation
for loaders, and load-program.
(code-pack, code-unpack): Start to move things from (system vm conv)
here.
(object->code, code->object): More things from conv.scm.
* module/language/glil.scm (<glil-program>): Add a new field,
closure-level.
(make-glil-program, compute-closure-level): Calculate the "closure
level" when making a glil program. This is the maximum depth of
external binding refs in this closure.
(unparse-glil): Fix label serialization.
* module/language/glil/compile-assembly.scm (make-meta): Prepend #f for
the meta's object table, though maybe in the future we can avoid
creating assembly in the first place.
(assoc-ref-or-acons, object-index-and-alist): GRRR! Caught again by the
different sets of arguments to assoc and assoc-ref!
(glil->assembly): Attempt to make the <glil-program> case more
readable, and fix the bugs. Sorry I don't know how to comment this
change any more than this.
(glil->assembly): For <glil-module> serialize the whole key, not just
the name.
(dump-object): subprogram-code is already a list. Serialize integers as
strings, not u8vectors. Fix the order of lists and vectors.
* module/language/glil/spec.scm (glil): Switch orders, so we prefer glil
-> assembly -> objcode. Actually glil->objcode doesn't work any more,
needs to be removed I think.
* module/language/objcode/spec.scm (objcode->value):
s/objcode->program/make-program/.
* module/language/scheme/inline.scm: Add acons inline.
* module/system/vm/conv.scm (make-byte-decoder): Skip the first 8 bytes,
they are header. Handle subprograms properly. Still needs help though.
(decode-length): Lengths are always 3 bytes now.
* module/system/vm/disasm.scm: Superficial changes to keep things
working. I'd like to fix this better in the future.
* module/system/vm/frame.scm (bootstrap-frame?): Fixes for
program-bytecode.
* module/system/vm/program.scm: Export make-program. It's program-objcode
now, no more program-bytecode.
* module/system/vm/vm.scm (vm-load): Use make-program.
* test-suite/tests/asm-to-bytecode.test: New test, very minimal.
* module/system/vm/objcode.scm: Export word-size, byte-order, and
write-objcode.
2009-01-29 21:09:04 +01:00
|
|
|
|
switch ((*ip++) & SCM_VM_INSTRUCTION_MASK) {
|
2000-08-22 15:54:19 +00:00
|
|
|
|
#endif
|
|
|
|
|
|
|
2008-08-21 18:39:30 -07:00
|
|
|
|
#include "vm-expand.h"
|
|
|
|
|
|
#include "vm-i-system.c"
|
|
|
|
|
|
#include "vm-i-scheme.c"
|
|
|
|
|
|
#include "vm-i-loader.c"
|
2000-08-22 15:54:19 +00:00
|
|
|
|
|
|
|
|
|
|
#ifndef HAVE_LABELS_AS_VALUES
|
static opcodes; refactor program/objcode division; use new assembly pipeline
* gdbinit: Untested attempts to get the stack fondling macros to deal
with the new program representation.
* libguile/frames.c (scm_vm_frame_arguments, scm_vm_frame_source)
(scm_vm_frame_local_ref, scm_vm_frame_local_set_x): SCM_PROGRAM_DATA is
a struct scm_objcode*.
* libguile/instructions.h:
* libguile/instructions.c: Hide the instruction table and the struct
scm_instruction structure; all access to instructions now goes through
procedures. This is because instructions are no longer in a packed
array indexed by opcode. Also, declare a mask that all instructions
should fit in.
* libguile/objcodes.h:
* libguile/objcodes.c: Rewrite so that object code directly maps its
arity and length from its bytecode. This makes it unnecessary to keep
this information in programs, allowing programs to be simple conses
between the code (objcodes) and data (the object table and the closure
variables).
* libguile/programs.c (scm_make_program): Rework so that make-program
takes objcode, an object table, and externals as arguments. It's much
clearer this way, and we avoid malloc().
* libguile/stacks.c (is_vm_bootstrap_frame): Update for program/objcode
changes.
* libguile/vm-engine.c (vm_run): Initialize the jump table on the first
run, with the opcodes declared in the instruction sources, and with bad
instructions raising an error instead of wandering off into the
Unknown.
* libguile/vm-engine.h (FETCH_LENGTH): Always represent lengths as 3
bytes. The old code was too error-prone.
(NEXT_JUMP): Mask the instruction with SCM_VM_INSTRUCTION_MASK.
(NEW_FRAME): Update for program/objcode changes.
* libguile/vm-expand.h (VM_DEFINE_FUNCTION, VM_DEFINE_INSTRUCTION)
(VM_DEFINE_LOADER): Update so that we explicitly specify opcodes, so
that we have a stable bytecode API.
* libguile/vm-i-loader.c: Update license to LGPLv2+. Explicitly declare
opcodes.
(load-integer): Use an int instead of a long as the accumulator; still
need to revisit this code at some point, I think.
(load-program): Simplify, thankfully!! Just creates the objcode slice
and rolls with it.
* libguile/vm-i-scheme.c: Number the opcodes explicitly.
* libguile/vm-i-system.c: Update license to LGPLv2+. Explicitly declare
opcodes.
(make-closure): Update for new program API.
* libguile/vm.c (vm_make_boot_program): Update for new program/objcode
API. Still a bit ugly.
(scm_load_compiled_with_vm): Update for new program/objcode API.
* module/language/assembly.scm (byte-length): Fix byte-length calculation
for loaders, and load-program.
(code-pack, code-unpack): Start to move things from (system vm conv)
here.
(object->code, code->object): More things from conv.scm.
* module/language/glil.scm (<glil-program>): Add a new field,
closure-level.
(make-glil-program, compute-closure-level): Calculate the "closure
level" when making a glil program. This is the maximum depth of
external binding refs in this closure.
(unparse-glil): Fix label serialization.
* module/language/glil/compile-assembly.scm (make-meta): Prepend #f for
the meta's object table, though maybe in the future we can avoid
creating assembly in the first place.
(assoc-ref-or-acons, object-index-and-alist): GRRR! Caught again by the
different sets of arguments to assoc and assoc-ref!
(glil->assembly): Attempt to make the <glil-program> case more
readable, and fix the bugs. Sorry I don't know how to comment this
change any more than this.
(glil->assembly): For <glil-module> serialize the whole key, not just
the name.
(dump-object): subprogram-code is already a list. Serialize integers as
strings, not u8vectors. Fix the order of lists and vectors.
* module/language/glil/spec.scm (glil): Switch orders, so we prefer glil
-> assembly -> objcode. Actually glil->objcode doesn't work any more,
needs to be removed I think.
* module/language/objcode/spec.scm (objcode->value):
s/objcode->program/make-program/.
* module/language/scheme/inline.scm: Add acons inline.
* module/system/vm/conv.scm (make-byte-decoder): Skip the first 8 bytes,
they are header. Handle subprograms properly. Still needs help though.
(decode-length): Lengths are always 3 bytes now.
* module/system/vm/disasm.scm: Superficial changes to keep things
working. I'd like to fix this better in the future.
* module/system/vm/frame.scm (bootstrap-frame?): Fixes for
program-bytecode.
* module/system/vm/program.scm: Export make-program. It's program-objcode
now, no more program-bytecode.
* module/system/vm/vm.scm (vm-load): Use make-program.
* test-suite/tests/asm-to-bytecode.test: New test, very minimal.
* module/system/vm/objcode.scm: Export word-size, byte-order, and
write-objcode.
2009-01-29 21:09:04 +01:00
|
|
|
|
default:
|
|
|
|
|
|
goto vm_error_bad_instruction;
|
2000-08-22 15:54:19 +00:00
|
|
|
|
}
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
2012-04-30 20:25:53 +02:00
|
|
|
|
abort (); /* never reached */
|
2005-06-25 06:57:20 +00:00
|
|
|
|
|
2012-04-30 20:25:53 +02:00
|
|
|
|
vm_error_bad_instruction:
|
|
|
|
|
|
vm_error_bad_instruction (ip[-1]);
|
|
|
|
|
|
abort (); /* never reached */
|
2001-04-01 05:03:41 +00:00
|
|
|
|
|
2012-04-30 20:25:53 +02:00
|
|
|
|
handle_overflow:
|
|
|
|
|
|
SYNC_ALL ();
|
|
|
|
|
|
vm_error_stack_overflow (vp);
|
2000-08-22 15:54:19 +00:00
|
|
|
|
abort (); /* never reached */
|
|
|
|
|
|
}
|
enable multiple vm engines (regular, debug, ...)
* libguile/vm-engine.c (VM_USE_HOOKS, VM_USE_CLOCK, VM_CHECK_EXTERNAL)
(VM_CHECK_OBJECT): Update to define these here, before including
vm-engine.h.
(vm_run): Change so that we can make different engines. Also, we take
an array of arguments, and the struct scm_vm directly, so as to avoid
any need to cons.
* libguile/vm-engine.h (CHECK_EXTERNAL, CHECK_OBJECT): Add some UNLIKELY
bits; don't seem to help.
* libguile/vm.c (vm_dispatch_hook): Change to not pass the VP. This needs
some love, and perhaps we revert to the old way.
(VM_ENGINE): Actually make two engines, vm_regular_engine and
vm_debug_engine. Probably there is room for improvement here. Actually
their speeds are the same at the moment.
(make_vm): Choose which engine to run; currently the debug engine by
default.
(scm_c_vm_run): A thin wrapper to invoke a VM without consing.
(scm_vm_apply): Use scm_c_vm_run.
(scm_load_compiled_with_vm): Use scm_c_vm_run.
2009-02-04 23:47:56 +01:00
|
|
|
|
|
2012-05-18 11:57:51 +02:00
|
|
|
|
#undef RUN_HOOK
|
|
|
|
|
|
#undef RUN_HOOK1
|
enable multiple vm engines (regular, debug, ...)
* libguile/vm-engine.c (VM_USE_HOOKS, VM_USE_CLOCK, VM_CHECK_EXTERNAL)
(VM_CHECK_OBJECT): Update to define these here, before including
vm-engine.h.
(vm_run): Change so that we can make different engines. Also, we take
an array of arguments, and the struct scm_vm directly, so as to avoid
any need to cons.
* libguile/vm-engine.h (CHECK_EXTERNAL, CHECK_OBJECT): Add some UNLIKELY
bits; don't seem to help.
* libguile/vm.c (vm_dispatch_hook): Change to not pass the VP. This needs
some love, and perhaps we revert to the old way.
(VM_ENGINE): Actually make two engines, vm_regular_engine and
vm_debug_engine. Probably there is room for improvement here. Actually
their speeds are the same at the moment.
(make_vm): Choose which engine to run; currently the debug engine by
default.
(scm_c_vm_run): A thin wrapper to invoke a VM without consing.
(scm_vm_apply): Use scm_c_vm_run.
(scm_load_compiled_with_vm): Use scm_c_vm_run.
2009-02-04 23:47:56 +01:00
|
|
|
|
#undef VM_USE_HOOKS
|
2001-04-01 05:03:41 +00:00
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
Local Variables:
|
|
|
|
|
|
c-file-style: "gnu"
|
|
|
|
|
|
End:
|
|
|
|
|
|
*/
|