2020-01-02 13:27:23 +01:00
|
|
|
|
/* Copyright 2001,2009-2015,2017-2020
|
2018-06-20 20:01:49 +02:00
|
|
|
|
Free Software Foundation, Inc.
|
|
|
|
|
|
|
|
|
|
|
|
This file is part of Guile.
|
|
|
|
|
|
|
|
|
|
|
|
Guile is free software: you can redistribute it and/or 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.
|
|
|
|
|
|
|
|
|
|
|
|
Guile is distributed in the hope that it will be useful, but WITHOUT
|
|
|
|
|
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
|
|
|
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
|
|
|
|
|
License for more details.
|
|
|
|
|
|
|
|
|
|
|
|
You should have received a copy of the GNU Lesser General Public
|
|
|
|
|
|
License along with Guile. If not, see
|
|
|
|
|
|
<https://www.gnu.org/licenses/>. */
|
2000-08-22 15:54:19 +00:00
|
|
|
|
|
2008-05-20 11:46:52 +02:00
|
|
|
|
#if HAVE_CONFIG_H
|
|
|
|
|
|
# include <config.h>
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
2010-06-01 00:40:00 +02:00
|
|
|
|
#include <alignof.h>
|
2018-06-17 19:46:33 +02:00
|
|
|
|
#include <alloca.h>
|
|
|
|
|
|
#include <errno.h>
|
Add new-style test and branch instructions
* libguile/vm-engine.c (UNPACK_16_16): New definition.
(u64=?, u64<?, s64=?, s64<?, f64=?, f64<?, =?, <?, arguments<?)
(positional-arguments<=?, immediate-tag=?, heap-tag=?, eq?): New
comparison instructions.
(j, jl, je, jnl, jne, jge, jnge): New branch instructions.
2017-10-24 21:12:19 +02:00
|
|
|
|
#include <math.h>
|
2010-10-13 01:31:19 +02:00
|
|
|
|
#include <stdint.h>
|
2018-06-19 11:51:57 +02:00
|
|
|
|
#include <stdio.h>
|
2018-06-17 19:46:33 +02:00
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
#include <string.h>
|
2014-01-31 21:41:36 +01:00
|
|
|
|
#include <unistd.h>
|
2009-08-20 01:56:47 +02:00
|
|
|
|
|
2013-11-22 14:41:19 +01:00
|
|
|
|
#ifdef HAVE_SYS_MMAN_H
|
|
|
|
|
|
#include <sys/mman.h>
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
2018-06-20 18:31:24 +02:00
|
|
|
|
#include "alist.h"
|
|
|
|
|
|
#include "async.h"
|
2018-06-20 17:19:31 +02:00
|
|
|
|
#include "atomic.h"
|
|
|
|
|
|
#include "atomics-internal.h"
|
2018-06-20 18:31:24 +02:00
|
|
|
|
#include "bdw-gc.h"
|
2018-06-20 17:19:31 +02:00
|
|
|
|
#include "cache-internal.h"
|
2018-06-26 10:46:11 +02:00
|
|
|
|
#include "continuations.h"
|
2018-06-20 17:19:31 +02:00
|
|
|
|
#include "control.h"
|
|
|
|
|
|
#include "dynwind.h"
|
2018-06-20 18:31:24 +02:00
|
|
|
|
#include "eval.h"
|
2018-06-20 17:19:31 +02:00
|
|
|
|
#include "extensions.h"
|
|
|
|
|
|
#include "foreign.h"
|
|
|
|
|
|
#include "frames.h"
|
|
|
|
|
|
#include "gc-inline.h"
|
2018-06-20 18:31:24 +02:00
|
|
|
|
#include "gsubr.h"
|
|
|
|
|
|
#include "hooks.h"
|
2018-06-20 17:19:31 +02:00
|
|
|
|
#include "instructions.h"
|
|
|
|
|
|
#include "intrinsics.h"
|
2018-07-23 12:43:30 +02:00
|
|
|
|
#include "jit.h"
|
2018-06-20 18:31:24 +02:00
|
|
|
|
#include "keywords.h"
|
|
|
|
|
|
#include "list.h"
|
2018-06-20 17:19:31 +02:00
|
|
|
|
#include "loader.h"
|
2018-06-20 18:31:24 +02:00
|
|
|
|
#include "modules.h"
|
|
|
|
|
|
#include "numbers.h"
|
|
|
|
|
|
#include "pairs.h"
|
2018-06-20 17:19:31 +02:00
|
|
|
|
#include "ports.h"
|
2018-06-20 18:31:24 +02:00
|
|
|
|
#include "procprop.h"
|
2018-06-20 17:19:31 +02:00
|
|
|
|
#include "programs.h"
|
|
|
|
|
|
#include "simpos.h"
|
2018-06-20 18:31:24 +02:00
|
|
|
|
#include "smob.h"
|
|
|
|
|
|
#include "stackchk.h"
|
2018-06-20 17:19:31 +02:00
|
|
|
|
#include "symbols.h"
|
2018-06-20 18:31:24 +02:00
|
|
|
|
#include "values.h"
|
2018-06-20 17:19:31 +02:00
|
|
|
|
#include "vectors.h"
|
2018-10-07 15:15:02 +02:00
|
|
|
|
#include "version.h"
|
2018-06-20 17:19:31 +02:00
|
|
|
|
#include "vm-builtins.h"
|
2000-08-22 15:54:19 +00:00
|
|
|
|
|
2018-06-20 18:31:24 +02:00
|
|
|
|
#include "vm.h"
|
|
|
|
|
|
|
|
|
|
|
|
#include <gc/gc_mark.h>
|
|
|
|
|
|
|
2018-06-17 19:10:52 +02:00
|
|
|
|
#if (defined __GNUC__)
|
|
|
|
|
|
# define SCM_NOINLINE __attribute__ ((__noinline__))
|
|
|
|
|
|
#else
|
|
|
|
|
|
# define SCM_NOINLINE /* noinline */
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
2010-09-28 09:22:38 +02:00
|
|
|
|
static int vm_default_engine = SCM_VM_REGULAR_ENGINE;
|
2010-09-27 21:06:24 +02:00
|
|
|
|
|
|
|
|
|
|
/* Unfortunately we can't snarf these: snarfed things are only loaded up from
|
|
|
|
|
|
(system vm vm), which might not be loaded before an error happens. */
|
|
|
|
|
|
static SCM sym_keyword_argument_error;
|
|
|
|
|
|
static SCM sym_regular;
|
|
|
|
|
|
static SCM sym_debug;
|
2000-08-22 15:54:19 +00:00
|
|
|
|
|
2014-03-12 17:18:13 +01:00
|
|
|
|
/* The page size. */
|
|
|
|
|
|
static size_t page_size;
|
|
|
|
|
|
|
precise stack marking, fix some missed references, still imperfect
* libguile/vm-engine.h (CHECK_STACK_LEAK, NULLSTACK): Add a new mode,
VM_ENABLE_STACK_NULLING, that tries to ensure that all stack data past
the top of the stack is NULL. This helps to verify the VM's
consistency. If VM_ENABLE_STACK_NULLING is not defined, there is no
overhead.
(DROP, DROPN): Hook into NULLSTACK.
(POP_LIST): Hoo, fix a good bug: if CONS triggered a GC, the elements
of the list that had not yet been consed would not be marked, because
the sp was already below them.
(NEXT): Hook into CHECK_STACK_LEAK.
(INIT_ARGS): Add a note that consing the rest arg can cause GC.
(NEW_FRAME): Cons up the external data after initializing the frame, so
that if GC is triggered, the precise marker sees a well-formed frame.
* libguile/vm-i-loader.c (load-program): In the four-integers case, use
the POP macro so that we can hook into NULLSTACK (if necessary).
* libguile/vm-i-scheme.c (ARGS2, ARGS3): Hook into NULLSTACK.
* libguile/vm-i-system.c (halt): Null the nvalues. Rework some asserts
into using ASSERT, and null the stack when we free the frame.
(variable-set): Use DROPN instead of sp -= 2.
(BR): Hook into NULLSTACK.
(goto/args): Hook into NULLSTACK. In the non-self case, delay updating
the frame until after INIT_ARGS so that GC sees a well-formed frame.
Delay consing the externals until after the frame is set up, as in
NEW_FRAME.
(call/cc): Add some asserts.
(return): Rework some asserts into ASSERT, and hook into NULLSTACK.
(return/values): Hook into NULLSTACK, and use ASSERT.
(return/values*) Use ASSERT.
* libguile/vm.c (VM_ENABLE_ASSERTIONS, VM_ENABLE_STACK_NULLING): These
are the variables that control assertions and nulling. Perhaps we can
do these per-engine when we start compiling the debug engine separate
from a speedy engine.
(vm_mark_stack): Add a precise stack marker. Yay!
(vm_cont_mark): Mark the continuation stack precisely.
(capture_vm_cont): Record the difference from the vp's stack_base too,
so that we can translate the dynamic links when marking the
continuation stack. Memset the stack to NULL if we are doing nulling.
(reinstate_vm_cont): If we are nulling, null out the relevant part
of the stack.
(vm_reset_stack): When resetting sp due to a nonlocal exit, null out
the stack too.
(vm_mark): If we are nulling, assert that there are no extra values on
the stack. Mark the stack precisely.
2008-10-03 16:00:30 +02:00
|
|
|
|
/* The VM has a number of internal assertions that shouldn't normally be
|
|
|
|
|
|
necessary, but might be if you think you found a bug in the VM. */
|
2014-02-20 19:57:47 +01:00
|
|
|
|
/* #define VM_ENABLE_ASSERTIONS */
|
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
|
|
|
|
|
VM stack grows downward
Adapt VM stack to grow downward. This will make native compilation look
more like the VM code, as we will be able to use native CALL
instructions, taking proper advantage of the return address buffer.
* libguile/continuations.c (scm_i_continuation_to_frame): Record offsets
from stack top.
* libguile/control.c (scm_i_prompt_pop_abort_args_x): Adapt for reversed
order of arguments, and instead of relying on the abort to push on the
number of arguments, make the caller save the stack depth, which
allows us to compute the number of arguments ourselves.
(reify_partial_continuation, scm_c_abort): Adapt to reversed stack
order.
* libguile/dynstack.c (scm_dynstack_wind_prompt): Since we wind the
stack in a downward direction, subtract the reloc instead of adding
it.
* libguile/dynstack.h (SCM_F_DYNSTACK_PROMPT_ESCAPE_ONLY): Remove flag;
instead rely on prompt-establishing code to save the stack depth.
* libguile/eval.c (eval): Remove extraneous "volatile" declarations for
variables that are not re-set between the setjmp and any longjmp.
Adapt to save stack depth before instating the prompt.
* libguile/foreign.c (scm_i_foreign_call): Adapt to receive arguments in
reverse order.
* libguile/frames.c (frame_stack_top, scm_i_frame_stack_top): Adapt to
compute stack top instead of stack bottom.
(scm_c_frame_closure): Adapt to stack growth change.
(scm_frame_num_locals, scm_frame_local_ref, scm_frame_set_x): Use
union data type to access stack.
(RELOC): Reformat.
(scm_c_frame_previous): Adapt to stack growth change.
* libguile/frames.h: Adapt stack diagram to indicate that the stack
grows up.
(union scm_vm_stack_element): New data type used to access items on
the stack.
(SCM_FRAME_PREVIOUS_SP)
(SCM_FRAME_RETURN_ADDRESS, SCM_FRAME_SET_RETURN_ADDRESS)
(SCM_FRAME_DYNAMIC_LINK, SCM_FRAME_SET_DYNAMIC_LINK)
(SCM_FRAME_LOCAL, SCM_FRAME_NUM_LOCALS): Adapt to stack representation
change.
(SCM_FRAME_SLOT): New helper.
(SCM_VM_FRAME_FP, SCM_VM_FRAME_SP): Adapt to stack growth change.
* libguile/stacks.c (scm_make_stack): Record offsets from top of stack.
* libguile/throw.c (catch): Adapt to scm_i_prompt_pop_abort_args_x
change.
* libguile/vm-engine.c (ALLOC_FRAME, RESET_FRAME):
(FRAME_LOCALS_COUNT_FROM): Adapt to stack growth change.
(LOCAL_ADDRESS): Use SCM_FRAME_SLOT to get the address as the proper
data type.
(RETURN_ONE_VALUE, RETURN_VALUE_LIST): Adapt to stack growth change.
(apply): Shuffling up the SMOB apply args can cause the stack to
expand, so use ALLOC_FRAME instead of RESET_FRAME.
(vm_engine): Adapt for stack growth change.
* libguile/vm.c (vm_increase_sp, vm_push_sp, vm_restore_sp): Adapt to
stack representation change.
(scm_i_vm_cont_to_frame): Adapt to take offsets from the top.
(scm_i_vm_capture_stack): Adapt to capture from the top.
(vm_return_to_continuation_inner): Adapt for data type changes.
(vm_return_to_continuation): Likewise, and instead of looping, just
splat the saved arguments on with memcpy.
(vm_dispatch_hook): Adapt to receive arguments in the reverse order.
Adapt callers.
(vm_abort): There is never a tail argument. Adapt to stack
representation change.
(vm_reinstate_partial_continuation)
(vm_reinstate_partial_continuation_inner): Adapt to stack growth
change.
(allocate_stack, free_stack): Adapt to data type change.
(expand_stack): Don't try to mremap(), as you can't grow a mapping
from the bottom. Without knowing that there's a free mapping space
right below the old stack, which there usually isn't on Linux, we have
to copy. We can't use MAP_GROWSDOWN because Linux is buggy.
(make_vm): Adapt to stack representation changes.
(return_unused_stack_to_os): Round down instead of up, as the stack
grows down.
(scm_i_vm_mark_stack): Adapt to walk up the stack.
(scm_i_vm_free_stack): Adapt to scm_vm changes.
(vm_expand_stack_inner, reset_stack_limit, vm_expand_stack): Adapt to
the stack growing down.
(scm_call_n): Adapt to the stack growing down. Don't allow argv to
point into the stack.
* libguile/vm.h (struct scm_vm, struct scm_vm_cont): Adapt to hold the
stack top and bottom.
2015-09-22 10:24:30 +00:00
|
|
|
|
static void vm_expand_stack (struct scm_vm *vp,
|
|
|
|
|
|
union scm_vm_stack_element *new_sp) SCM_NOINLINE;
|
2014-02-05 22:52:00 +01:00
|
|
|
|
|
|
|
|
|
|
/* RESTORE is for the case where we know we have done a PUSH of equal or
|
|
|
|
|
|
greater stack size in the past. Otherwise PUSH is the thing, which
|
|
|
|
|
|
may expand the stack. */
|
|
|
|
|
|
enum vm_increase_sp_kind { VM_SP_PUSH, VM_SP_RESTORE };
|
|
|
|
|
|
|
|
|
|
|
|
static inline void
|
VM stack grows downward
Adapt VM stack to grow downward. This will make native compilation look
more like the VM code, as we will be able to use native CALL
instructions, taking proper advantage of the return address buffer.
* libguile/continuations.c (scm_i_continuation_to_frame): Record offsets
from stack top.
* libguile/control.c (scm_i_prompt_pop_abort_args_x): Adapt for reversed
order of arguments, and instead of relying on the abort to push on the
number of arguments, make the caller save the stack depth, which
allows us to compute the number of arguments ourselves.
(reify_partial_continuation, scm_c_abort): Adapt to reversed stack
order.
* libguile/dynstack.c (scm_dynstack_wind_prompt): Since we wind the
stack in a downward direction, subtract the reloc instead of adding
it.
* libguile/dynstack.h (SCM_F_DYNSTACK_PROMPT_ESCAPE_ONLY): Remove flag;
instead rely on prompt-establishing code to save the stack depth.
* libguile/eval.c (eval): Remove extraneous "volatile" declarations for
variables that are not re-set between the setjmp and any longjmp.
Adapt to save stack depth before instating the prompt.
* libguile/foreign.c (scm_i_foreign_call): Adapt to receive arguments in
reverse order.
* libguile/frames.c (frame_stack_top, scm_i_frame_stack_top): Adapt to
compute stack top instead of stack bottom.
(scm_c_frame_closure): Adapt to stack growth change.
(scm_frame_num_locals, scm_frame_local_ref, scm_frame_set_x): Use
union data type to access stack.
(RELOC): Reformat.
(scm_c_frame_previous): Adapt to stack growth change.
* libguile/frames.h: Adapt stack diagram to indicate that the stack
grows up.
(union scm_vm_stack_element): New data type used to access items on
the stack.
(SCM_FRAME_PREVIOUS_SP)
(SCM_FRAME_RETURN_ADDRESS, SCM_FRAME_SET_RETURN_ADDRESS)
(SCM_FRAME_DYNAMIC_LINK, SCM_FRAME_SET_DYNAMIC_LINK)
(SCM_FRAME_LOCAL, SCM_FRAME_NUM_LOCALS): Adapt to stack representation
change.
(SCM_FRAME_SLOT): New helper.
(SCM_VM_FRAME_FP, SCM_VM_FRAME_SP): Adapt to stack growth change.
* libguile/stacks.c (scm_make_stack): Record offsets from top of stack.
* libguile/throw.c (catch): Adapt to scm_i_prompt_pop_abort_args_x
change.
* libguile/vm-engine.c (ALLOC_FRAME, RESET_FRAME):
(FRAME_LOCALS_COUNT_FROM): Adapt to stack growth change.
(LOCAL_ADDRESS): Use SCM_FRAME_SLOT to get the address as the proper
data type.
(RETURN_ONE_VALUE, RETURN_VALUE_LIST): Adapt to stack growth change.
(apply): Shuffling up the SMOB apply args can cause the stack to
expand, so use ALLOC_FRAME instead of RESET_FRAME.
(vm_engine): Adapt for stack growth change.
* libguile/vm.c (vm_increase_sp, vm_push_sp, vm_restore_sp): Adapt to
stack representation change.
(scm_i_vm_cont_to_frame): Adapt to take offsets from the top.
(scm_i_vm_capture_stack): Adapt to capture from the top.
(vm_return_to_continuation_inner): Adapt for data type changes.
(vm_return_to_continuation): Likewise, and instead of looping, just
splat the saved arguments on with memcpy.
(vm_dispatch_hook): Adapt to receive arguments in the reverse order.
Adapt callers.
(vm_abort): There is never a tail argument. Adapt to stack
representation change.
(vm_reinstate_partial_continuation)
(vm_reinstate_partial_continuation_inner): Adapt to stack growth
change.
(allocate_stack, free_stack): Adapt to data type change.
(expand_stack): Don't try to mremap(), as you can't grow a mapping
from the bottom. Without knowing that there's a free mapping space
right below the old stack, which there usually isn't on Linux, we have
to copy. We can't use MAP_GROWSDOWN because Linux is buggy.
(make_vm): Adapt to stack representation changes.
(return_unused_stack_to_os): Round down instead of up, as the stack
grows down.
(scm_i_vm_mark_stack): Adapt to walk up the stack.
(scm_i_vm_free_stack): Adapt to scm_vm changes.
(vm_expand_stack_inner, reset_stack_limit, vm_expand_stack): Adapt to
the stack growing down.
(scm_call_n): Adapt to the stack growing down. Don't allow argv to
point into the stack.
* libguile/vm.h (struct scm_vm, struct scm_vm_cont): Adapt to hold the
stack top and bottom.
2015-09-22 10:24:30 +00:00
|
|
|
|
vm_increase_sp (struct scm_vm *vp, union scm_vm_stack_element *new_sp,
|
|
|
|
|
|
enum vm_increase_sp_kind kind)
|
2014-02-05 22:52:00 +01:00
|
|
|
|
{
|
VM stack grows downward
Adapt VM stack to grow downward. This will make native compilation look
more like the VM code, as we will be able to use native CALL
instructions, taking proper advantage of the return address buffer.
* libguile/continuations.c (scm_i_continuation_to_frame): Record offsets
from stack top.
* libguile/control.c (scm_i_prompt_pop_abort_args_x): Adapt for reversed
order of arguments, and instead of relying on the abort to push on the
number of arguments, make the caller save the stack depth, which
allows us to compute the number of arguments ourselves.
(reify_partial_continuation, scm_c_abort): Adapt to reversed stack
order.
* libguile/dynstack.c (scm_dynstack_wind_prompt): Since we wind the
stack in a downward direction, subtract the reloc instead of adding
it.
* libguile/dynstack.h (SCM_F_DYNSTACK_PROMPT_ESCAPE_ONLY): Remove flag;
instead rely on prompt-establishing code to save the stack depth.
* libguile/eval.c (eval): Remove extraneous "volatile" declarations for
variables that are not re-set between the setjmp and any longjmp.
Adapt to save stack depth before instating the prompt.
* libguile/foreign.c (scm_i_foreign_call): Adapt to receive arguments in
reverse order.
* libguile/frames.c (frame_stack_top, scm_i_frame_stack_top): Adapt to
compute stack top instead of stack bottom.
(scm_c_frame_closure): Adapt to stack growth change.
(scm_frame_num_locals, scm_frame_local_ref, scm_frame_set_x): Use
union data type to access stack.
(RELOC): Reformat.
(scm_c_frame_previous): Adapt to stack growth change.
* libguile/frames.h: Adapt stack diagram to indicate that the stack
grows up.
(union scm_vm_stack_element): New data type used to access items on
the stack.
(SCM_FRAME_PREVIOUS_SP)
(SCM_FRAME_RETURN_ADDRESS, SCM_FRAME_SET_RETURN_ADDRESS)
(SCM_FRAME_DYNAMIC_LINK, SCM_FRAME_SET_DYNAMIC_LINK)
(SCM_FRAME_LOCAL, SCM_FRAME_NUM_LOCALS): Adapt to stack representation
change.
(SCM_FRAME_SLOT): New helper.
(SCM_VM_FRAME_FP, SCM_VM_FRAME_SP): Adapt to stack growth change.
* libguile/stacks.c (scm_make_stack): Record offsets from top of stack.
* libguile/throw.c (catch): Adapt to scm_i_prompt_pop_abort_args_x
change.
* libguile/vm-engine.c (ALLOC_FRAME, RESET_FRAME):
(FRAME_LOCALS_COUNT_FROM): Adapt to stack growth change.
(LOCAL_ADDRESS): Use SCM_FRAME_SLOT to get the address as the proper
data type.
(RETURN_ONE_VALUE, RETURN_VALUE_LIST): Adapt to stack growth change.
(apply): Shuffling up the SMOB apply args can cause the stack to
expand, so use ALLOC_FRAME instead of RESET_FRAME.
(vm_engine): Adapt for stack growth change.
* libguile/vm.c (vm_increase_sp, vm_push_sp, vm_restore_sp): Adapt to
stack representation change.
(scm_i_vm_cont_to_frame): Adapt to take offsets from the top.
(scm_i_vm_capture_stack): Adapt to capture from the top.
(vm_return_to_continuation_inner): Adapt for data type changes.
(vm_return_to_continuation): Likewise, and instead of looping, just
splat the saved arguments on with memcpy.
(vm_dispatch_hook): Adapt to receive arguments in the reverse order.
Adapt callers.
(vm_abort): There is never a tail argument. Adapt to stack
representation change.
(vm_reinstate_partial_continuation)
(vm_reinstate_partial_continuation_inner): Adapt to stack growth
change.
(allocate_stack, free_stack): Adapt to data type change.
(expand_stack): Don't try to mremap(), as you can't grow a mapping
from the bottom. Without knowing that there's a free mapping space
right below the old stack, which there usually isn't on Linux, we have
to copy. We can't use MAP_GROWSDOWN because Linux is buggy.
(make_vm): Adapt to stack representation changes.
(return_unused_stack_to_os): Round down instead of up, as the stack
grows down.
(scm_i_vm_mark_stack): Adapt to walk up the stack.
(scm_i_vm_free_stack): Adapt to scm_vm changes.
(vm_expand_stack_inner, reset_stack_limit, vm_expand_stack): Adapt to
the stack growing down.
(scm_call_n): Adapt to the stack growing down. Don't allow argv to
point into the stack.
* libguile/vm.h (struct scm_vm, struct scm_vm_cont): Adapt to hold the
stack top and bottom.
2015-09-22 10:24:30 +00:00
|
|
|
|
if (kind == VM_SP_PUSH && new_sp < vp->stack_limit)
|
2014-02-20 10:17:51 +01:00
|
|
|
|
vm_expand_stack (vp, new_sp);
|
|
|
|
|
|
else
|
2019-12-07 22:54:32 +01:00
|
|
|
|
vp->sp = new_sp;
|
2014-02-05 22:52:00 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static inline void
|
VM stack grows downward
Adapt VM stack to grow downward. This will make native compilation look
more like the VM code, as we will be able to use native CALL
instructions, taking proper advantage of the return address buffer.
* libguile/continuations.c (scm_i_continuation_to_frame): Record offsets
from stack top.
* libguile/control.c (scm_i_prompt_pop_abort_args_x): Adapt for reversed
order of arguments, and instead of relying on the abort to push on the
number of arguments, make the caller save the stack depth, which
allows us to compute the number of arguments ourselves.
(reify_partial_continuation, scm_c_abort): Adapt to reversed stack
order.
* libguile/dynstack.c (scm_dynstack_wind_prompt): Since we wind the
stack in a downward direction, subtract the reloc instead of adding
it.
* libguile/dynstack.h (SCM_F_DYNSTACK_PROMPT_ESCAPE_ONLY): Remove flag;
instead rely on prompt-establishing code to save the stack depth.
* libguile/eval.c (eval): Remove extraneous "volatile" declarations for
variables that are not re-set between the setjmp and any longjmp.
Adapt to save stack depth before instating the prompt.
* libguile/foreign.c (scm_i_foreign_call): Adapt to receive arguments in
reverse order.
* libguile/frames.c (frame_stack_top, scm_i_frame_stack_top): Adapt to
compute stack top instead of stack bottom.
(scm_c_frame_closure): Adapt to stack growth change.
(scm_frame_num_locals, scm_frame_local_ref, scm_frame_set_x): Use
union data type to access stack.
(RELOC): Reformat.
(scm_c_frame_previous): Adapt to stack growth change.
* libguile/frames.h: Adapt stack diagram to indicate that the stack
grows up.
(union scm_vm_stack_element): New data type used to access items on
the stack.
(SCM_FRAME_PREVIOUS_SP)
(SCM_FRAME_RETURN_ADDRESS, SCM_FRAME_SET_RETURN_ADDRESS)
(SCM_FRAME_DYNAMIC_LINK, SCM_FRAME_SET_DYNAMIC_LINK)
(SCM_FRAME_LOCAL, SCM_FRAME_NUM_LOCALS): Adapt to stack representation
change.
(SCM_FRAME_SLOT): New helper.
(SCM_VM_FRAME_FP, SCM_VM_FRAME_SP): Adapt to stack growth change.
* libguile/stacks.c (scm_make_stack): Record offsets from top of stack.
* libguile/throw.c (catch): Adapt to scm_i_prompt_pop_abort_args_x
change.
* libguile/vm-engine.c (ALLOC_FRAME, RESET_FRAME):
(FRAME_LOCALS_COUNT_FROM): Adapt to stack growth change.
(LOCAL_ADDRESS): Use SCM_FRAME_SLOT to get the address as the proper
data type.
(RETURN_ONE_VALUE, RETURN_VALUE_LIST): Adapt to stack growth change.
(apply): Shuffling up the SMOB apply args can cause the stack to
expand, so use ALLOC_FRAME instead of RESET_FRAME.
(vm_engine): Adapt for stack growth change.
* libguile/vm.c (vm_increase_sp, vm_push_sp, vm_restore_sp): Adapt to
stack representation change.
(scm_i_vm_cont_to_frame): Adapt to take offsets from the top.
(scm_i_vm_capture_stack): Adapt to capture from the top.
(vm_return_to_continuation_inner): Adapt for data type changes.
(vm_return_to_continuation): Likewise, and instead of looping, just
splat the saved arguments on with memcpy.
(vm_dispatch_hook): Adapt to receive arguments in the reverse order.
Adapt callers.
(vm_abort): There is never a tail argument. Adapt to stack
representation change.
(vm_reinstate_partial_continuation)
(vm_reinstate_partial_continuation_inner): Adapt to stack growth
change.
(allocate_stack, free_stack): Adapt to data type change.
(expand_stack): Don't try to mremap(), as you can't grow a mapping
from the bottom. Without knowing that there's a free mapping space
right below the old stack, which there usually isn't on Linux, we have
to copy. We can't use MAP_GROWSDOWN because Linux is buggy.
(make_vm): Adapt to stack representation changes.
(return_unused_stack_to_os): Round down instead of up, as the stack
grows down.
(scm_i_vm_mark_stack): Adapt to walk up the stack.
(scm_i_vm_free_stack): Adapt to scm_vm changes.
(vm_expand_stack_inner, reset_stack_limit, vm_expand_stack): Adapt to
the stack growing down.
(scm_call_n): Adapt to the stack growing down. Don't allow argv to
point into the stack.
* libguile/vm.h (struct scm_vm, struct scm_vm_cont): Adapt to hold the
stack top and bottom.
2015-09-22 10:24:30 +00:00
|
|
|
|
vm_push_sp (struct scm_vm *vp, union scm_vm_stack_element *new_sp)
|
2014-02-05 22:52:00 +01:00
|
|
|
|
{
|
|
|
|
|
|
vm_increase_sp (vp, new_sp, VM_SP_PUSH);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static inline void
|
VM stack grows downward
Adapt VM stack to grow downward. This will make native compilation look
more like the VM code, as we will be able to use native CALL
instructions, taking proper advantage of the return address buffer.
* libguile/continuations.c (scm_i_continuation_to_frame): Record offsets
from stack top.
* libguile/control.c (scm_i_prompt_pop_abort_args_x): Adapt for reversed
order of arguments, and instead of relying on the abort to push on the
number of arguments, make the caller save the stack depth, which
allows us to compute the number of arguments ourselves.
(reify_partial_continuation, scm_c_abort): Adapt to reversed stack
order.
* libguile/dynstack.c (scm_dynstack_wind_prompt): Since we wind the
stack in a downward direction, subtract the reloc instead of adding
it.
* libguile/dynstack.h (SCM_F_DYNSTACK_PROMPT_ESCAPE_ONLY): Remove flag;
instead rely on prompt-establishing code to save the stack depth.
* libguile/eval.c (eval): Remove extraneous "volatile" declarations for
variables that are not re-set between the setjmp and any longjmp.
Adapt to save stack depth before instating the prompt.
* libguile/foreign.c (scm_i_foreign_call): Adapt to receive arguments in
reverse order.
* libguile/frames.c (frame_stack_top, scm_i_frame_stack_top): Adapt to
compute stack top instead of stack bottom.
(scm_c_frame_closure): Adapt to stack growth change.
(scm_frame_num_locals, scm_frame_local_ref, scm_frame_set_x): Use
union data type to access stack.
(RELOC): Reformat.
(scm_c_frame_previous): Adapt to stack growth change.
* libguile/frames.h: Adapt stack diagram to indicate that the stack
grows up.
(union scm_vm_stack_element): New data type used to access items on
the stack.
(SCM_FRAME_PREVIOUS_SP)
(SCM_FRAME_RETURN_ADDRESS, SCM_FRAME_SET_RETURN_ADDRESS)
(SCM_FRAME_DYNAMIC_LINK, SCM_FRAME_SET_DYNAMIC_LINK)
(SCM_FRAME_LOCAL, SCM_FRAME_NUM_LOCALS): Adapt to stack representation
change.
(SCM_FRAME_SLOT): New helper.
(SCM_VM_FRAME_FP, SCM_VM_FRAME_SP): Adapt to stack growth change.
* libguile/stacks.c (scm_make_stack): Record offsets from top of stack.
* libguile/throw.c (catch): Adapt to scm_i_prompt_pop_abort_args_x
change.
* libguile/vm-engine.c (ALLOC_FRAME, RESET_FRAME):
(FRAME_LOCALS_COUNT_FROM): Adapt to stack growth change.
(LOCAL_ADDRESS): Use SCM_FRAME_SLOT to get the address as the proper
data type.
(RETURN_ONE_VALUE, RETURN_VALUE_LIST): Adapt to stack growth change.
(apply): Shuffling up the SMOB apply args can cause the stack to
expand, so use ALLOC_FRAME instead of RESET_FRAME.
(vm_engine): Adapt for stack growth change.
* libguile/vm.c (vm_increase_sp, vm_push_sp, vm_restore_sp): Adapt to
stack representation change.
(scm_i_vm_cont_to_frame): Adapt to take offsets from the top.
(scm_i_vm_capture_stack): Adapt to capture from the top.
(vm_return_to_continuation_inner): Adapt for data type changes.
(vm_return_to_continuation): Likewise, and instead of looping, just
splat the saved arguments on with memcpy.
(vm_dispatch_hook): Adapt to receive arguments in the reverse order.
Adapt callers.
(vm_abort): There is never a tail argument. Adapt to stack
representation change.
(vm_reinstate_partial_continuation)
(vm_reinstate_partial_continuation_inner): Adapt to stack growth
change.
(allocate_stack, free_stack): Adapt to data type change.
(expand_stack): Don't try to mremap(), as you can't grow a mapping
from the bottom. Without knowing that there's a free mapping space
right below the old stack, which there usually isn't on Linux, we have
to copy. We can't use MAP_GROWSDOWN because Linux is buggy.
(make_vm): Adapt to stack representation changes.
(return_unused_stack_to_os): Round down instead of up, as the stack
grows down.
(scm_i_vm_mark_stack): Adapt to walk up the stack.
(scm_i_vm_free_stack): Adapt to scm_vm changes.
(vm_expand_stack_inner, reset_stack_limit, vm_expand_stack): Adapt to
the stack growing down.
(scm_call_n): Adapt to the stack growing down. Don't allow argv to
point into the stack.
* libguile/vm.h (struct scm_vm, struct scm_vm_cont): Adapt to hold the
stack top and bottom.
2015-09-22 10:24:30 +00:00
|
|
|
|
vm_restore_sp (struct scm_vm *vp, union scm_vm_stack_element *new_sp)
|
2014-02-05 22:52:00 +01:00
|
|
|
|
{
|
|
|
|
|
|
vm_increase_sp (vp, new_sp, VM_SP_RESTORE);
|
|
|
|
|
|
}
|
2009-08-20 01:56:47 +02:00
|
|
|
|
|
2000-08-22 15:54:19 +00:00
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
* VM Continuation
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
2010-01-05 19:45:56 +01:00
|
|
|
|
void
|
|
|
|
|
|
scm_i_vm_cont_print (SCM x, SCM port, scm_print_state *pstate)
|
|
|
|
|
|
{
|
2016-04-26 23:07:28 +02:00
|
|
|
|
scm_puts ("#<vm-continuation ", port);
|
2010-01-05 19:45:56 +01:00
|
|
|
|
scm_uintprint (SCM_UNPACK (x), 16, port);
|
2016-04-26 23:07:28 +02:00
|
|
|
|
scm_puts (">", port);
|
2010-01-05 19:45:56 +01:00
|
|
|
|
}
|
2001-04-01 05:03:41 +00:00
|
|
|
|
|
2014-04-16 19:16:10 +02:00
|
|
|
|
int
|
|
|
|
|
|
scm_i_vm_cont_to_frame (SCM cont, struct scm_frame *frame)
|
|
|
|
|
|
{
|
|
|
|
|
|
struct scm_vm_cont *data = SCM_VM_CONT_DATA (cont);
|
|
|
|
|
|
|
|
|
|
|
|
frame->stack_holder = data;
|
2017-02-12 18:22:44 +01:00
|
|
|
|
frame->fp_offset = data->fp_offset;
|
2015-10-18 20:12:15 +02:00
|
|
|
|
frame->sp_offset = data->stack_size;
|
Continuations capture machine code address
* libguile/continuations.c (scm_i_continuation_to_frame): Adapt to vra
field renaming.
(scm_i_reinstate_continuation, grow_stack, copy_stack_and_call)
(scm_dynthrow): Take mra of continuation. Set on the vp before the
longjmp.
* libguile/continuations.h: Update scm_i_reinstate_continuation
prototype.
* libguile/dynstack.h:
* libguile/control.c (scm_suspendable_continuation_p):
* libguile/dynstack.c (PROMPT_WORDS, PROMPT_VRA, PROMPT_MRA):
(PROMPT_JMPBUF, scm_dynstack_push_prompt, scm_dynstack_find_prompt)
(scm_dynstack_wind_prompt): Store both virtual and machine return
addresses on the dynstack, for prompts.
* libguile/eval.c (eval): Pass NULL for mra.
* libguile/intrinsics.c (push_prompt): Add mra arg, and pass it to the
dynstack.
* libguile/intrinsics.h: Update prototypes so that continuation-related
intrinsics can save and restore the MRA.
* libguile/jit.h:
* libguile/jit.c: Return VRA when JIT code needs to tier down.
* libguile/stacks.c (find_prompt, scm_make_stack)
* libguile/throw.c (catch): Adapt find-prompt calls.
* libguile/vm-engine.c (instrument-entry, instrument-loop): Add logic to
continue with vcode after the mcode finishes.
(compose-continuation, capture-continuation, abort, prompt): Add logic
to pass NULL as captured MRA, but continue with mcode from new
continuations, if appropriate.
* libguile/vm.c (scm_i_vm_cont_to_frame, capture_stack)
(scm_i_capture_current_stack, reinstate_continuation_x)
(capture_continuation, compose_continuation_inner, compose_continuation)
(capture_delimited_continuation, abort_to_prompt): Adapt to plumb
around machine code continuations.
(scm_call_n): Check "mra_after_abort" field for machine code
continuation, if any.
* libguile/vm.h (struct scm_vm): Add "mra_after_abort" field.
(struct scm_vm_cont): Rename "ra" field to "vra" and add "mra" field.
2018-08-12 15:57:53 +02:00
|
|
|
|
frame->ip = data->vra;
|
2014-04-16 19:16:10 +02:00
|
|
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2014-02-19 11:19:10 +01:00
|
|
|
|
/* Ideally we could avoid copying the C stack if the continuation root
|
|
|
|
|
|
is inside VM code, and call/cc was invoked within that same call to
|
|
|
|
|
|
vm_run. That's currently not implemented. */
|
Continuations capture machine code address
* libguile/continuations.c (scm_i_continuation_to_frame): Adapt to vra
field renaming.
(scm_i_reinstate_continuation, grow_stack, copy_stack_and_call)
(scm_dynthrow): Take mra of continuation. Set on the vp before the
longjmp.
* libguile/continuations.h: Update scm_i_reinstate_continuation
prototype.
* libguile/dynstack.h:
* libguile/control.c (scm_suspendable_continuation_p):
* libguile/dynstack.c (PROMPT_WORDS, PROMPT_VRA, PROMPT_MRA):
(PROMPT_JMPBUF, scm_dynstack_push_prompt, scm_dynstack_find_prompt)
(scm_dynstack_wind_prompt): Store both virtual and machine return
addresses on the dynstack, for prompts.
* libguile/eval.c (eval): Pass NULL for mra.
* libguile/intrinsics.c (push_prompt): Add mra arg, and pass it to the
dynstack.
* libguile/intrinsics.h: Update prototypes so that continuation-related
intrinsics can save and restore the MRA.
* libguile/jit.h:
* libguile/jit.c: Return VRA when JIT code needs to tier down.
* libguile/stacks.c (find_prompt, scm_make_stack)
* libguile/throw.c (catch): Adapt find-prompt calls.
* libguile/vm-engine.c (instrument-entry, instrument-loop): Add logic to
continue with vcode after the mcode finishes.
(compose-continuation, capture-continuation, abort, prompt): Add logic
to pass NULL as captured MRA, but continue with mcode from new
continuations, if appropriate.
* libguile/vm.c (scm_i_vm_cont_to_frame, capture_stack)
(scm_i_capture_current_stack, reinstate_continuation_x)
(capture_continuation, compose_continuation_inner, compose_continuation)
(capture_delimited_continuation, abort_to_prompt): Adapt to plumb
around machine code continuations.
(scm_call_n): Check "mra_after_abort" field for machine code
continuation, if any.
* libguile/vm.h (struct scm_vm): Add "mra_after_abort" field.
(struct scm_vm_cont): Rename "ra" field to "vra" and add "mra" field.
2018-08-12 15:57:53 +02:00
|
|
|
|
static SCM
|
|
|
|
|
|
capture_stack (union scm_vm_stack_element *stack_top,
|
|
|
|
|
|
union scm_vm_stack_element *fp,
|
|
|
|
|
|
union scm_vm_stack_element *sp,
|
|
|
|
|
|
uint32_t *vra,
|
|
|
|
|
|
uint8_t *mra,
|
|
|
|
|
|
scm_t_dynstack *dynstack, uint32_t flags)
|
2000-08-22 15:54:19 +00:00
|
|
|
|
{
|
continuations return multiple values on the stack
* libguile/vm.h (struct scm_vm_cont): Instead of saving the "IP", save
"RA" and "MVRA". That is, save singly-valued and multiply-valued
return addresses, so that we can return multiple values on the stack.
(scm_i_vm_reinstate_continuation): Remove.
* libguile/vm.c (vm_capture_continuation): Rename from capture_vm_cont,
and change the prototype so we can capture the RA and MVRA, and so
that tail calls to call/cc can capture a continuation without the
call/cc application frame.
(vm_return_to_continuation): Rename from reinstate_vm_cont, and take
arguments to return to the continuation. Handles returning to single
or multiple-value RA.
(scm_i_vm_capture_continuation): Change to invoke
vm_capture_continuation. Kept around for the benefit of make-stack.
* libguile/vm-i-system.c (continuation-call): Handle reinstatement of
the VM stack, with arguments.
(call/cc, tail-call/cc): Adapt to new vm_capture_continuation
prototype. tail-call/cc captures tail continuations.
* libguile/stacks.c (scm_make_stack): Update for scm_vm_cont structure
change.
* libguile/continuations.h (struct scm_contregs): Remove throw_value
member, which was used to return a value to a continuation.
(scm_i_check_continuation): New internal function, checks that a
continuation may be reinstated.
(scm_i_reinstate_continuation): Replaces scm_i_continuation_call; just
reinstates the C stack.
(scm_i_contregs_vm, scm_i_contregs_vm_cont): New internal accessors.
* libguile/continuations.c (scm_i_make_continuation): Return
SCM_UNDEFINED if we are returning again.
(grow_stack, copy_stack_and_call, scm_dynthrow): Remove extra arg, as
vm opcodes handle value returns.
(copy_stack): No need to instate VM continuation.
(scm_i_reinstate_continuation): Adapt.
2010-02-08 22:59:25 +01:00
|
|
|
|
struct scm_vm_cont *p;
|
|
|
|
|
|
|
|
|
|
|
|
p = scm_gc_malloc (sizeof (*p), "capture_vm_cont");
|
VM stack grows downward
Adapt VM stack to grow downward. This will make native compilation look
more like the VM code, as we will be able to use native CALL
instructions, taking proper advantage of the return address buffer.
* libguile/continuations.c (scm_i_continuation_to_frame): Record offsets
from stack top.
* libguile/control.c (scm_i_prompt_pop_abort_args_x): Adapt for reversed
order of arguments, and instead of relying on the abort to push on the
number of arguments, make the caller save the stack depth, which
allows us to compute the number of arguments ourselves.
(reify_partial_continuation, scm_c_abort): Adapt to reversed stack
order.
* libguile/dynstack.c (scm_dynstack_wind_prompt): Since we wind the
stack in a downward direction, subtract the reloc instead of adding
it.
* libguile/dynstack.h (SCM_F_DYNSTACK_PROMPT_ESCAPE_ONLY): Remove flag;
instead rely on prompt-establishing code to save the stack depth.
* libguile/eval.c (eval): Remove extraneous "volatile" declarations for
variables that are not re-set between the setjmp and any longjmp.
Adapt to save stack depth before instating the prompt.
* libguile/foreign.c (scm_i_foreign_call): Adapt to receive arguments in
reverse order.
* libguile/frames.c (frame_stack_top, scm_i_frame_stack_top): Adapt to
compute stack top instead of stack bottom.
(scm_c_frame_closure): Adapt to stack growth change.
(scm_frame_num_locals, scm_frame_local_ref, scm_frame_set_x): Use
union data type to access stack.
(RELOC): Reformat.
(scm_c_frame_previous): Adapt to stack growth change.
* libguile/frames.h: Adapt stack diagram to indicate that the stack
grows up.
(union scm_vm_stack_element): New data type used to access items on
the stack.
(SCM_FRAME_PREVIOUS_SP)
(SCM_FRAME_RETURN_ADDRESS, SCM_FRAME_SET_RETURN_ADDRESS)
(SCM_FRAME_DYNAMIC_LINK, SCM_FRAME_SET_DYNAMIC_LINK)
(SCM_FRAME_LOCAL, SCM_FRAME_NUM_LOCALS): Adapt to stack representation
change.
(SCM_FRAME_SLOT): New helper.
(SCM_VM_FRAME_FP, SCM_VM_FRAME_SP): Adapt to stack growth change.
* libguile/stacks.c (scm_make_stack): Record offsets from top of stack.
* libguile/throw.c (catch): Adapt to scm_i_prompt_pop_abort_args_x
change.
* libguile/vm-engine.c (ALLOC_FRAME, RESET_FRAME):
(FRAME_LOCALS_COUNT_FROM): Adapt to stack growth change.
(LOCAL_ADDRESS): Use SCM_FRAME_SLOT to get the address as the proper
data type.
(RETURN_ONE_VALUE, RETURN_VALUE_LIST): Adapt to stack growth change.
(apply): Shuffling up the SMOB apply args can cause the stack to
expand, so use ALLOC_FRAME instead of RESET_FRAME.
(vm_engine): Adapt for stack growth change.
* libguile/vm.c (vm_increase_sp, vm_push_sp, vm_restore_sp): Adapt to
stack representation change.
(scm_i_vm_cont_to_frame): Adapt to take offsets from the top.
(scm_i_vm_capture_stack): Adapt to capture from the top.
(vm_return_to_continuation_inner): Adapt for data type changes.
(vm_return_to_continuation): Likewise, and instead of looping, just
splat the saved arguments on with memcpy.
(vm_dispatch_hook): Adapt to receive arguments in the reverse order.
Adapt callers.
(vm_abort): There is never a tail argument. Adapt to stack
representation change.
(vm_reinstate_partial_continuation)
(vm_reinstate_partial_continuation_inner): Adapt to stack growth
change.
(allocate_stack, free_stack): Adapt to data type change.
(expand_stack): Don't try to mremap(), as you can't grow a mapping
from the bottom. Without knowing that there's a free mapping space
right below the old stack, which there usually isn't on Linux, we have
to copy. We can't use MAP_GROWSDOWN because Linux is buggy.
(make_vm): Adapt to stack representation changes.
(return_unused_stack_to_os): Round down instead of up, as the stack
grows down.
(scm_i_vm_mark_stack): Adapt to walk up the stack.
(scm_i_vm_free_stack): Adapt to scm_vm changes.
(vm_expand_stack_inner, reset_stack_limit, vm_expand_stack): Adapt to
the stack growing down.
(scm_call_n): Adapt to the stack growing down. Don't allow argv to
point into the stack.
* libguile/vm.h (struct scm_vm, struct scm_vm_cont): Adapt to hold the
stack top and bottom.
2015-09-22 10:24:30 +00:00
|
|
|
|
p->stack_size = stack_top - sp;
|
|
|
|
|
|
p->stack_bottom = scm_gc_malloc (p->stack_size * sizeof (*p->stack_bottom),
|
|
|
|
|
|
"capture_vm_cont");
|
Continuations capture machine code address
* libguile/continuations.c (scm_i_continuation_to_frame): Adapt to vra
field renaming.
(scm_i_reinstate_continuation, grow_stack, copy_stack_and_call)
(scm_dynthrow): Take mra of continuation. Set on the vp before the
longjmp.
* libguile/continuations.h: Update scm_i_reinstate_continuation
prototype.
* libguile/dynstack.h:
* libguile/control.c (scm_suspendable_continuation_p):
* libguile/dynstack.c (PROMPT_WORDS, PROMPT_VRA, PROMPT_MRA):
(PROMPT_JMPBUF, scm_dynstack_push_prompt, scm_dynstack_find_prompt)
(scm_dynstack_wind_prompt): Store both virtual and machine return
addresses on the dynstack, for prompts.
* libguile/eval.c (eval): Pass NULL for mra.
* libguile/intrinsics.c (push_prompt): Add mra arg, and pass it to the
dynstack.
* libguile/intrinsics.h: Update prototypes so that continuation-related
intrinsics can save and restore the MRA.
* libguile/jit.h:
* libguile/jit.c: Return VRA when JIT code needs to tier down.
* libguile/stacks.c (find_prompt, scm_make_stack)
* libguile/throw.c (catch): Adapt find-prompt calls.
* libguile/vm-engine.c (instrument-entry, instrument-loop): Add logic to
continue with vcode after the mcode finishes.
(compose-continuation, capture-continuation, abort, prompt): Add logic
to pass NULL as captured MRA, but continue with mcode from new
continuations, if appropriate.
* libguile/vm.c (scm_i_vm_cont_to_frame, capture_stack)
(scm_i_capture_current_stack, reinstate_continuation_x)
(capture_continuation, compose_continuation_inner, compose_continuation)
(capture_delimited_continuation, abort_to_prompt): Adapt to plumb
around machine code continuations.
(scm_call_n): Check "mra_after_abort" field for machine code
continuation, if any.
* libguile/vm.h (struct scm_vm): Add "mra_after_abort" field.
(struct scm_vm_cont): Rename "ra" field to "vra" and add "mra" field.
2018-08-12 15:57:53 +02:00
|
|
|
|
p->vra = vra;
|
|
|
|
|
|
p->mra = mra;
|
2017-02-12 18:22:44 +01:00
|
|
|
|
p->fp_offset = stack_top - fp;
|
VM stack grows downward
Adapt VM stack to grow downward. This will make native compilation look
more like the VM code, as we will be able to use native CALL
instructions, taking proper advantage of the return address buffer.
* libguile/continuations.c (scm_i_continuation_to_frame): Record offsets
from stack top.
* libguile/control.c (scm_i_prompt_pop_abort_args_x): Adapt for reversed
order of arguments, and instead of relying on the abort to push on the
number of arguments, make the caller save the stack depth, which
allows us to compute the number of arguments ourselves.
(reify_partial_continuation, scm_c_abort): Adapt to reversed stack
order.
* libguile/dynstack.c (scm_dynstack_wind_prompt): Since we wind the
stack in a downward direction, subtract the reloc instead of adding
it.
* libguile/dynstack.h (SCM_F_DYNSTACK_PROMPT_ESCAPE_ONLY): Remove flag;
instead rely on prompt-establishing code to save the stack depth.
* libguile/eval.c (eval): Remove extraneous "volatile" declarations for
variables that are not re-set between the setjmp and any longjmp.
Adapt to save stack depth before instating the prompt.
* libguile/foreign.c (scm_i_foreign_call): Adapt to receive arguments in
reverse order.
* libguile/frames.c (frame_stack_top, scm_i_frame_stack_top): Adapt to
compute stack top instead of stack bottom.
(scm_c_frame_closure): Adapt to stack growth change.
(scm_frame_num_locals, scm_frame_local_ref, scm_frame_set_x): Use
union data type to access stack.
(RELOC): Reformat.
(scm_c_frame_previous): Adapt to stack growth change.
* libguile/frames.h: Adapt stack diagram to indicate that the stack
grows up.
(union scm_vm_stack_element): New data type used to access items on
the stack.
(SCM_FRAME_PREVIOUS_SP)
(SCM_FRAME_RETURN_ADDRESS, SCM_FRAME_SET_RETURN_ADDRESS)
(SCM_FRAME_DYNAMIC_LINK, SCM_FRAME_SET_DYNAMIC_LINK)
(SCM_FRAME_LOCAL, SCM_FRAME_NUM_LOCALS): Adapt to stack representation
change.
(SCM_FRAME_SLOT): New helper.
(SCM_VM_FRAME_FP, SCM_VM_FRAME_SP): Adapt to stack growth change.
* libguile/stacks.c (scm_make_stack): Record offsets from top of stack.
* libguile/throw.c (catch): Adapt to scm_i_prompt_pop_abort_args_x
change.
* libguile/vm-engine.c (ALLOC_FRAME, RESET_FRAME):
(FRAME_LOCALS_COUNT_FROM): Adapt to stack growth change.
(LOCAL_ADDRESS): Use SCM_FRAME_SLOT to get the address as the proper
data type.
(RETURN_ONE_VALUE, RETURN_VALUE_LIST): Adapt to stack growth change.
(apply): Shuffling up the SMOB apply args can cause the stack to
expand, so use ALLOC_FRAME instead of RESET_FRAME.
(vm_engine): Adapt for stack growth change.
* libguile/vm.c (vm_increase_sp, vm_push_sp, vm_restore_sp): Adapt to
stack representation change.
(scm_i_vm_cont_to_frame): Adapt to take offsets from the top.
(scm_i_vm_capture_stack): Adapt to capture from the top.
(vm_return_to_continuation_inner): Adapt for data type changes.
(vm_return_to_continuation): Likewise, and instead of looping, just
splat the saved arguments on with memcpy.
(vm_dispatch_hook): Adapt to receive arguments in the reverse order.
Adapt callers.
(vm_abort): There is never a tail argument. Adapt to stack
representation change.
(vm_reinstate_partial_continuation)
(vm_reinstate_partial_continuation_inner): Adapt to stack growth
change.
(allocate_stack, free_stack): Adapt to data type change.
(expand_stack): Don't try to mremap(), as you can't grow a mapping
from the bottom. Without knowing that there's a free mapping space
right below the old stack, which there usually isn't on Linux, we have
to copy. We can't use MAP_GROWSDOWN because Linux is buggy.
(make_vm): Adapt to stack representation changes.
(return_unused_stack_to_os): Round down instead of up, as the stack
grows down.
(scm_i_vm_mark_stack): Adapt to walk up the stack.
(scm_i_vm_free_stack): Adapt to scm_vm changes.
(vm_expand_stack_inner, reset_stack_limit, vm_expand_stack): Adapt to
the stack growing down.
(scm_call_n): Adapt to the stack growing down. Don't allow argv to
point into the stack.
* libguile/vm.h (struct scm_vm, struct scm_vm_cont): Adapt to hold the
stack top and bottom.
2015-09-22 10:24:30 +00:00
|
|
|
|
memcpy (p->stack_bottom, sp, p->stack_size * sizeof (*p->stack_bottom));
|
the dynamic stack is really a stack now, instead of a list
* libguile/dynstack.h:
* libguile/dynstack.c: New files, implementing the dynamic stack as a
true stack instead of a linked list. This lowers the cost of
dynwinds: frames, winders, prompts, with-fluids, and dynamic-wind.
For the most part, we allocate these items directly on the stack.
* libguile/dynwinds.h:
* libguile/dynwinds.c: Adapt all manipulators of the wind stack to use
interfaces from dynstack.c. Remove heap-allocated winder and frame
object types.
(scm_dowinds, scm_i_dowinds): Remove these. The first was exported,
but it was not a public interface.
* libguile/continuations.c:
* libguile/continuations.h (scm_t_contregs): Continuation objects
reference scm_t_dynstack* values now. Adapt to the new interfaces.
* libguile/control.c:
* libguile/control.h: There is no longer a scm_tc7_prompt kind of object
that can be allocated on the heap. Instead, the prompt flags, key,
and registers are pushed on the dynwind stack. (The registers are
still on the heap.) Also, since the vm_cont will reference the
dynwinds, make the partial continuation stub take just one extra arg,
instead of storing the intwinds separately in the object table.
* libguile/fluids.c:
* libguile/fluids.h: No more with-fluids objects; instead, the fluids go
on the dynstack. The values still have to be on the heap, though.
(scm_prepare_fluids, scm_swap_fluids): New internal functions,
replacing scm_i_make_with_fluids and scm_i_swap_with_fluids.
* libguile/print.c: Remove prompt and with-fluids printers.
* libguile/tags.h: Revert prompt and with-fluids tc7 values to what they
were before they were allocated.
* libguile/vm-i-system.c (partial_cont_call): Just pop the vmcont, the
intwinds will not be passed as a second arg. Rewind the dynamic stack
from within the VM, so that any rewinder sees valid prompt entries.
(call_cc, tail_call_cc): Adapt to pass the dynstack to
scm_i_vm_capture_stack.
(prompt, wind, unwind, wind_fluids, unwind_fluids): Adapt to the new
interfaces.
* libguile/vm.h (scm_i_capture_current_stack): Rename from
scm_i_vm_capture_continuation.
(scm_i_vm_capture_stack): Take a dynstack as an argument.
* libguile/vm.c (vm_reinstate_partial_continuation): Don't wind here, as
that could result in winders seeing invalid prompts.
* libguile/eval.c:
* libguile/root.c:
* libguile/stacks.c:
* libguile/threads.c:
* libguile/threads.h:
* libguile/throw.c: Adapt other users of dynwinds to use the dynstack.
2012-03-03 17:01:16 +01:00
|
|
|
|
p->dynstack = dynstack;
|
2010-02-22 23:00:19 +01:00
|
|
|
|
p->flags = flags;
|
VM stack grows downward
Adapt VM stack to grow downward. This will make native compilation look
more like the VM code, as we will be able to use native CALL
instructions, taking proper advantage of the return address buffer.
* libguile/continuations.c (scm_i_continuation_to_frame): Record offsets
from stack top.
* libguile/control.c (scm_i_prompt_pop_abort_args_x): Adapt for reversed
order of arguments, and instead of relying on the abort to push on the
number of arguments, make the caller save the stack depth, which
allows us to compute the number of arguments ourselves.
(reify_partial_continuation, scm_c_abort): Adapt to reversed stack
order.
* libguile/dynstack.c (scm_dynstack_wind_prompt): Since we wind the
stack in a downward direction, subtract the reloc instead of adding
it.
* libguile/dynstack.h (SCM_F_DYNSTACK_PROMPT_ESCAPE_ONLY): Remove flag;
instead rely on prompt-establishing code to save the stack depth.
* libguile/eval.c (eval): Remove extraneous "volatile" declarations for
variables that are not re-set between the setjmp and any longjmp.
Adapt to save stack depth before instating the prompt.
* libguile/foreign.c (scm_i_foreign_call): Adapt to receive arguments in
reverse order.
* libguile/frames.c (frame_stack_top, scm_i_frame_stack_top): Adapt to
compute stack top instead of stack bottom.
(scm_c_frame_closure): Adapt to stack growth change.
(scm_frame_num_locals, scm_frame_local_ref, scm_frame_set_x): Use
union data type to access stack.
(RELOC): Reformat.
(scm_c_frame_previous): Adapt to stack growth change.
* libguile/frames.h: Adapt stack diagram to indicate that the stack
grows up.
(union scm_vm_stack_element): New data type used to access items on
the stack.
(SCM_FRAME_PREVIOUS_SP)
(SCM_FRAME_RETURN_ADDRESS, SCM_FRAME_SET_RETURN_ADDRESS)
(SCM_FRAME_DYNAMIC_LINK, SCM_FRAME_SET_DYNAMIC_LINK)
(SCM_FRAME_LOCAL, SCM_FRAME_NUM_LOCALS): Adapt to stack representation
change.
(SCM_FRAME_SLOT): New helper.
(SCM_VM_FRAME_FP, SCM_VM_FRAME_SP): Adapt to stack growth change.
* libguile/stacks.c (scm_make_stack): Record offsets from top of stack.
* libguile/throw.c (catch): Adapt to scm_i_prompt_pop_abort_args_x
change.
* libguile/vm-engine.c (ALLOC_FRAME, RESET_FRAME):
(FRAME_LOCALS_COUNT_FROM): Adapt to stack growth change.
(LOCAL_ADDRESS): Use SCM_FRAME_SLOT to get the address as the proper
data type.
(RETURN_ONE_VALUE, RETURN_VALUE_LIST): Adapt to stack growth change.
(apply): Shuffling up the SMOB apply args can cause the stack to
expand, so use ALLOC_FRAME instead of RESET_FRAME.
(vm_engine): Adapt for stack growth change.
* libguile/vm.c (vm_increase_sp, vm_push_sp, vm_restore_sp): Adapt to
stack representation change.
(scm_i_vm_cont_to_frame): Adapt to take offsets from the top.
(scm_i_vm_capture_stack): Adapt to capture from the top.
(vm_return_to_continuation_inner): Adapt for data type changes.
(vm_return_to_continuation): Likewise, and instead of looping, just
splat the saved arguments on with memcpy.
(vm_dispatch_hook): Adapt to receive arguments in the reverse order.
Adapt callers.
(vm_abort): There is never a tail argument. Adapt to stack
representation change.
(vm_reinstate_partial_continuation)
(vm_reinstate_partial_continuation_inner): Adapt to stack growth
change.
(allocate_stack, free_stack): Adapt to data type change.
(expand_stack): Don't try to mremap(), as you can't grow a mapping
from the bottom. Without knowing that there's a free mapping space
right below the old stack, which there usually isn't on Linux, we have
to copy. We can't use MAP_GROWSDOWN because Linux is buggy.
(make_vm): Adapt to stack representation changes.
(return_unused_stack_to_os): Round down instead of up, as the stack
grows down.
(scm_i_vm_mark_stack): Adapt to walk up the stack.
(scm_i_vm_free_stack): Adapt to scm_vm changes.
(vm_expand_stack_inner, reset_stack_limit, vm_expand_stack): Adapt to
the stack growing down.
(scm_call_n): Adapt to the stack growing down. Don't allow argv to
point into the stack.
* libguile/vm.h (struct scm_vm, struct scm_vm_cont): Adapt to hold the
stack top and bottom.
2015-09-22 10:24:30 +00:00
|
|
|
|
return scm_cell (scm_tc7_vm_cont, (scm_t_bits) p);
|
2000-08-22 15:54:19 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2008-09-24 17:04:14 +02:00
|
|
|
|
SCM
|
the dynamic stack is really a stack now, instead of a list
* libguile/dynstack.h:
* libguile/dynstack.c: New files, implementing the dynamic stack as a
true stack instead of a linked list. This lowers the cost of
dynwinds: frames, winders, prompts, with-fluids, and dynamic-wind.
For the most part, we allocate these items directly on the stack.
* libguile/dynwinds.h:
* libguile/dynwinds.c: Adapt all manipulators of the wind stack to use
interfaces from dynstack.c. Remove heap-allocated winder and frame
object types.
(scm_dowinds, scm_i_dowinds): Remove these. The first was exported,
but it was not a public interface.
* libguile/continuations.c:
* libguile/continuations.h (scm_t_contregs): Continuation objects
reference scm_t_dynstack* values now. Adapt to the new interfaces.
* libguile/control.c:
* libguile/control.h: There is no longer a scm_tc7_prompt kind of object
that can be allocated on the heap. Instead, the prompt flags, key,
and registers are pushed on the dynwind stack. (The registers are
still on the heap.) Also, since the vm_cont will reference the
dynwinds, make the partial continuation stub take just one extra arg,
instead of storing the intwinds separately in the object table.
* libguile/fluids.c:
* libguile/fluids.h: No more with-fluids objects; instead, the fluids go
on the dynstack. The values still have to be on the heap, though.
(scm_prepare_fluids, scm_swap_fluids): New internal functions,
replacing scm_i_make_with_fluids and scm_i_swap_with_fluids.
* libguile/print.c: Remove prompt and with-fluids printers.
* libguile/tags.h: Revert prompt and with-fluids tc7 values to what they
were before they were allocated.
* libguile/vm-i-system.c (partial_cont_call): Just pop the vmcont, the
intwinds will not be passed as a second arg. Rewind the dynamic stack
from within the VM, so that any rewinder sees valid prompt entries.
(call_cc, tail_call_cc): Adapt to pass the dynstack to
scm_i_vm_capture_stack.
(prompt, wind, unwind, wind_fluids, unwind_fluids): Adapt to the new
interfaces.
* libguile/vm.h (scm_i_capture_current_stack): Rename from
scm_i_vm_capture_continuation.
(scm_i_vm_capture_stack): Take a dynstack as an argument.
* libguile/vm.c (vm_reinstate_partial_continuation): Don't wind here, as
that could result in winders seeing invalid prompts.
* libguile/eval.c:
* libguile/root.c:
* libguile/stacks.c:
* libguile/threads.c:
* libguile/threads.h:
* libguile/throw.c: Adapt other users of dynwinds to use the dynstack.
2012-03-03 17:01:16 +01:00
|
|
|
|
scm_i_capture_current_stack (void)
|
2008-09-24 17:04:14 +02:00
|
|
|
|
{
|
2018-06-26 11:40:22 +02:00
|
|
|
|
scm_thread *thread;
|
the dynamic stack is really a stack now, instead of a list
* libguile/dynstack.h:
* libguile/dynstack.c: New files, implementing the dynamic stack as a
true stack instead of a linked list. This lowers the cost of
dynwinds: frames, winders, prompts, with-fluids, and dynamic-wind.
For the most part, we allocate these items directly on the stack.
* libguile/dynwinds.h:
* libguile/dynwinds.c: Adapt all manipulators of the wind stack to use
interfaces from dynstack.c. Remove heap-allocated winder and frame
object types.
(scm_dowinds, scm_i_dowinds): Remove these. The first was exported,
but it was not a public interface.
* libguile/continuations.c:
* libguile/continuations.h (scm_t_contregs): Continuation objects
reference scm_t_dynstack* values now. Adapt to the new interfaces.
* libguile/control.c:
* libguile/control.h: There is no longer a scm_tc7_prompt kind of object
that can be allocated on the heap. Instead, the prompt flags, key,
and registers are pushed on the dynwind stack. (The registers are
still on the heap.) Also, since the vm_cont will reference the
dynwinds, make the partial continuation stub take just one extra arg,
instead of storing the intwinds separately in the object table.
* libguile/fluids.c:
* libguile/fluids.h: No more with-fluids objects; instead, the fluids go
on the dynstack. The values still have to be on the heap, though.
(scm_prepare_fluids, scm_swap_fluids): New internal functions,
replacing scm_i_make_with_fluids and scm_i_swap_with_fluids.
* libguile/print.c: Remove prompt and with-fluids printers.
* libguile/tags.h: Revert prompt and with-fluids tc7 values to what they
were before they were allocated.
* libguile/vm-i-system.c (partial_cont_call): Just pop the vmcont, the
intwinds will not be passed as a second arg. Rewind the dynamic stack
from within the VM, so that any rewinder sees valid prompt entries.
(call_cc, tail_call_cc): Adapt to pass the dynstack to
scm_i_vm_capture_stack.
(prompt, wind, unwind, wind_fluids, unwind_fluids): Adapt to the new
interfaces.
* libguile/vm.h (scm_i_capture_current_stack): Rename from
scm_i_vm_capture_continuation.
(scm_i_vm_capture_stack): Take a dynstack as an argument.
* libguile/vm.c (vm_reinstate_partial_continuation): Don't wind here, as
that could result in winders seeing invalid prompts.
* libguile/eval.c:
* libguile/root.c:
* libguile/stacks.c:
* libguile/threads.c:
* libguile/threads.h:
* libguile/throw.c: Adapt other users of dynwinds to use the dynstack.
2012-03-03 17:01:16 +01:00
|
|
|
|
struct scm_vm *vp;
|
|
|
|
|
|
|
|
|
|
|
|
thread = SCM_I_CURRENT_THREAD;
|
2018-06-24 09:32:11 +02:00
|
|
|
|
vp = &thread->vm;
|
the dynamic stack is really a stack now, instead of a list
* libguile/dynstack.h:
* libguile/dynstack.c: New files, implementing the dynamic stack as a
true stack instead of a linked list. This lowers the cost of
dynwinds: frames, winders, prompts, with-fluids, and dynamic-wind.
For the most part, we allocate these items directly on the stack.
* libguile/dynwinds.h:
* libguile/dynwinds.c: Adapt all manipulators of the wind stack to use
interfaces from dynstack.c. Remove heap-allocated winder and frame
object types.
(scm_dowinds, scm_i_dowinds): Remove these. The first was exported,
but it was not a public interface.
* libguile/continuations.c:
* libguile/continuations.h (scm_t_contregs): Continuation objects
reference scm_t_dynstack* values now. Adapt to the new interfaces.
* libguile/control.c:
* libguile/control.h: There is no longer a scm_tc7_prompt kind of object
that can be allocated on the heap. Instead, the prompt flags, key,
and registers are pushed on the dynwind stack. (The registers are
still on the heap.) Also, since the vm_cont will reference the
dynwinds, make the partial continuation stub take just one extra arg,
instead of storing the intwinds separately in the object table.
* libguile/fluids.c:
* libguile/fluids.h: No more with-fluids objects; instead, the fluids go
on the dynstack. The values still have to be on the heap, though.
(scm_prepare_fluids, scm_swap_fluids): New internal functions,
replacing scm_i_make_with_fluids and scm_i_swap_with_fluids.
* libguile/print.c: Remove prompt and with-fluids printers.
* libguile/tags.h: Revert prompt and with-fluids tc7 values to what they
were before they were allocated.
* libguile/vm-i-system.c (partial_cont_call): Just pop the vmcont, the
intwinds will not be passed as a second arg. Rewind the dynamic stack
from within the VM, so that any rewinder sees valid prompt entries.
(call_cc, tail_call_cc): Adapt to pass the dynstack to
scm_i_vm_capture_stack.
(prompt, wind, unwind, wind_fluids, unwind_fluids): Adapt to the new
interfaces.
* libguile/vm.h (scm_i_capture_current_stack): Rename from
scm_i_vm_capture_continuation.
(scm_i_vm_capture_stack): Take a dynstack as an argument.
* libguile/vm.c (vm_reinstate_partial_continuation): Don't wind here, as
that could result in winders seeing invalid prompts.
* libguile/eval.c:
* libguile/root.c:
* libguile/stacks.c:
* libguile/threads.c:
* libguile/threads.h:
* libguile/throw.c: Adapt other users of dynwinds to use the dynstack.
2012-03-03 17:01:16 +01:00
|
|
|
|
|
Continuations capture machine code address
* libguile/continuations.c (scm_i_continuation_to_frame): Adapt to vra
field renaming.
(scm_i_reinstate_continuation, grow_stack, copy_stack_and_call)
(scm_dynthrow): Take mra of continuation. Set on the vp before the
longjmp.
* libguile/continuations.h: Update scm_i_reinstate_continuation
prototype.
* libguile/dynstack.h:
* libguile/control.c (scm_suspendable_continuation_p):
* libguile/dynstack.c (PROMPT_WORDS, PROMPT_VRA, PROMPT_MRA):
(PROMPT_JMPBUF, scm_dynstack_push_prompt, scm_dynstack_find_prompt)
(scm_dynstack_wind_prompt): Store both virtual and machine return
addresses on the dynstack, for prompts.
* libguile/eval.c (eval): Pass NULL for mra.
* libguile/intrinsics.c (push_prompt): Add mra arg, and pass it to the
dynstack.
* libguile/intrinsics.h: Update prototypes so that continuation-related
intrinsics can save and restore the MRA.
* libguile/jit.h:
* libguile/jit.c: Return VRA when JIT code needs to tier down.
* libguile/stacks.c (find_prompt, scm_make_stack)
* libguile/throw.c (catch): Adapt find-prompt calls.
* libguile/vm-engine.c (instrument-entry, instrument-loop): Add logic to
continue with vcode after the mcode finishes.
(compose-continuation, capture-continuation, abort, prompt): Add logic
to pass NULL as captured MRA, but continue with mcode from new
continuations, if appropriate.
* libguile/vm.c (scm_i_vm_cont_to_frame, capture_stack)
(scm_i_capture_current_stack, reinstate_continuation_x)
(capture_continuation, compose_continuation_inner, compose_continuation)
(capture_delimited_continuation, abort_to_prompt): Adapt to plumb
around machine code continuations.
(scm_call_n): Check "mra_after_abort" field for machine code
continuation, if any.
* libguile/vm.h (struct scm_vm): Add "mra_after_abort" field.
(struct scm_vm_cont): Rename "ra" field to "vra" and add "mra" field.
2018-08-12 15:57:53 +02:00
|
|
|
|
return capture_stack (vp->stack_top, vp->fp, vp->sp, vp->ip, NULL,
|
|
|
|
|
|
scm_dynstack_capture_all (&thread->dynstack),
|
|
|
|
|
|
0);
|
2000-08-22 15:54:19 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2018-09-14 12:57:16 +02:00
|
|
|
|
#define FOR_EACH_HOOK(M) \
|
|
|
|
|
|
M(apply) \
|
|
|
|
|
|
M(return) \
|
|
|
|
|
|
M(next) \
|
|
|
|
|
|
M(abort)
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
|
vm_hook_compute_enabled (scm_thread *thread, SCM hook, uint8_t *enabled)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (thread->vm.trace_level <= 0
|
|
|
|
|
|
|| thread->vm.engine == SCM_VM_REGULAR_ENGINE
|
|
|
|
|
|
|| scm_is_false (hook)
|
|
|
|
|
|
|| scm_is_true (scm_hook_empty_p (hook)))
|
|
|
|
|
|
*enabled = 0;
|
|
|
|
|
|
else
|
|
|
|
|
|
*enabled = 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
|
vm_recompute_disable_mcode (scm_thread *thread)
|
|
|
|
|
|
{
|
2019-08-19 16:31:29 +02:00
|
|
|
|
#if ENABLE_JIT
|
|
|
|
|
|
/* FIXME: Some of this logic works for ahead-of-time compilation
|
|
|
|
|
|
too. */
|
|
|
|
|
|
|
2018-09-14 15:11:13 +02:00
|
|
|
|
uint8_t was_disabled = thread->vm.disable_mcode;
|
2018-09-14 12:57:16 +02:00
|
|
|
|
thread->vm.disable_mcode = 0;
|
2018-09-14 15:11:13 +02:00
|
|
|
|
|
2018-09-14 12:57:16 +02:00
|
|
|
|
#define DISABLE_MCODE_IF_HOOK_ENABLED(h) \
|
|
|
|
|
|
if (thread->vm.h##_hook_enabled) \
|
|
|
|
|
|
thread->vm.disable_mcode = 1;
|
2018-09-14 15:11:13 +02:00
|
|
|
|
FOR_EACH_HOOK (DISABLE_MCODE_IF_HOOK_ENABLED);
|
2018-09-14 12:57:16 +02:00
|
|
|
|
#undef DISABLE_MCODE_IF_HOOK_ENABLED
|
2018-09-14 15:11:13 +02:00
|
|
|
|
|
|
|
|
|
|
if (thread->vm.disable_mcode && !was_disabled)
|
2019-06-18 21:40:55 +02:00
|
|
|
|
scm_jit_clear_mcode_return_addresses (thread);
|
2019-08-19 16:31:29 +02:00
|
|
|
|
#endif
|
2018-09-14 12:57:16 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
|
set_vm_trace_level (scm_thread *thread, int level)
|
|
|
|
|
|
{
|
|
|
|
|
|
int old_level;
|
|
|
|
|
|
struct scm_vm *vp = &thread->vm;
|
|
|
|
|
|
|
|
|
|
|
|
old_level = vp->trace_level;
|
|
|
|
|
|
vp->trace_level = level;
|
|
|
|
|
|
vp->disable_mcode = 0;
|
|
|
|
|
|
#define RESET_LEVEL(h) \
|
|
|
|
|
|
vm_hook_compute_enabled (thread, vp->h##_hook, &vp->h##_hook_enabled);
|
|
|
|
|
|
FOR_EACH_HOOK (RESET_LEVEL);
|
|
|
|
|
|
#undef RESET_LEVEL
|
|
|
|
|
|
vm_recompute_disable_mcode (thread);
|
|
|
|
|
|
|
|
|
|
|
|
return old_level;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-06-17 19:10:52 +02:00
|
|
|
|
/* Return the first integer greater than or equal to LEN such that
|
|
|
|
|
|
LEN % ALIGN == 0. Return LEN if ALIGN is zero. */
|
|
|
|
|
|
#define ROUND_UP(len, align) \
|
|
|
|
|
|
((align) ? (((len) - 1UL) | ((align) - 1UL)) + 1UL : (len))
|
|
|
|
|
|
|
remove heap links in VM frames, incorporate vm frames into normal backtraces
* doc/ref/vm.texi (Stack Layout): Update to remove references to the
"heap link".
* gdbinit: Update for "heap link" removal.
* libguile/frames.c:
* libguile/frames.h: Update macros and diagram for removal of "heap
link". As part of this, we also remove "heap frames", replacing them
with "vm frames", which are much like the interpreter's debug objects,
but for VM stacks. That is to say, they don't actually hold the stack
themselves, just the pointers into stack that's held by a continuation
(either captured or current).
* libguile/stacks.c (stack_depth, read_frames): Since a "stack" object is
really a copy of information that comes from somewhere else, it makes
sense to copy over info from the VM, just as `make-stack' does from the
evaluator. The tricky bit is to figure out how to interleave VM and
interpreter frames. We do that by starting in the interpreter, and
whenever the current frame's procedure is actually a program, we switch
to the VM stack, switching back when we reach a "bootstrap frame". The
last bit is hacky, but it does work...
(is_vm_bootstrap_frame): Hacky predicate to see if a VM frame is a
bootstrap frame.
(scm_make_stack): Accept a VM frame in addition to debug frames.
Probably has some bugs in this case. But in the case that the arg is
#t (a common case), do the right thing, capturing the top VM frame as
well, and interleaving those frames appropriately on the stack.
As an accident, we lost the ability to limit the number of frames in
the backtrace. We could add that back, but personally I always want
*all* frames in the trace... Narrowing still works fine, though there
are some hiccups sometimes -- e.g. an outer cut to a procedure that
does a tail-call in VM code will never find the cut, as it no longer
exists in the continuation.
* libguile/vm.h (struct scm_vm): So! Now that we have switched to save
stacks in the normal make-stack, there's no more need for `this_frame'
or `last_frame'. On the other hand, we can take this opportunity to fix
tracing: when we're in a trace hook, we set `trace_frame' on the VM,
so we know not to fire hooks when we're already in a hook.
(struct scm_vm_cont): Expose this, as make-stack needs it to make VM
frames from VM continuations.
* libguile/vm.c (scm_vm_trace_frame): New function, gets the current
trace frame.
(vm_mark, make_vm): Hook up the trace frame.
(vm_dispatch_hook): New hook dispatcher, with a dynwind so it does the
right thing if the hook exits nonlocally.
* libguile/vm-engine.c (vm_run): No more this_frame in the wind data.
* libguile/vm-engine.h (RUN_HOOK): Run hooks through the dispatcher.
(ALIGN_AS_NON_IMMEDIATE, POP_LIST_ON_STACK): Remove unused code.
(NEW_FRAME): Adapt for no HL in the frame.
* libguile/vm-i-system.c (goto/args, mv-call, return, return/values):
Adapt for no HL in the frame.
* module/system/vm/frame.scm:
* module/system/vm/vm.scm: Beginnings of some reworkings, needs more
thought.
2008-12-26 17:59:46 +01:00
|
|
|
|
static void
|
2018-09-14 12:57:16 +02:00
|
|
|
|
invoke_hook (scm_thread *thread, SCM hook)
|
remove heap links in VM frames, incorporate vm frames into normal backtraces
* doc/ref/vm.texi (Stack Layout): Update to remove references to the
"heap link".
* gdbinit: Update for "heap link" removal.
* libguile/frames.c:
* libguile/frames.h: Update macros and diagram for removal of "heap
link". As part of this, we also remove "heap frames", replacing them
with "vm frames", which are much like the interpreter's debug objects,
but for VM stacks. That is to say, they don't actually hold the stack
themselves, just the pointers into stack that's held by a continuation
(either captured or current).
* libguile/stacks.c (stack_depth, read_frames): Since a "stack" object is
really a copy of information that comes from somewhere else, it makes
sense to copy over info from the VM, just as `make-stack' does from the
evaluator. The tricky bit is to figure out how to interleave VM and
interpreter frames. We do that by starting in the interpreter, and
whenever the current frame's procedure is actually a program, we switch
to the VM stack, switching back when we reach a "bootstrap frame". The
last bit is hacky, but it does work...
(is_vm_bootstrap_frame): Hacky predicate to see if a VM frame is a
bootstrap frame.
(scm_make_stack): Accept a VM frame in addition to debug frames.
Probably has some bugs in this case. But in the case that the arg is
#t (a common case), do the right thing, capturing the top VM frame as
well, and interleaving those frames appropriately on the stack.
As an accident, we lost the ability to limit the number of frames in
the backtrace. We could add that back, but personally I always want
*all* frames in the trace... Narrowing still works fine, though there
are some hiccups sometimes -- e.g. an outer cut to a procedure that
does a tail-call in VM code will never find the cut, as it no longer
exists in the continuation.
* libguile/vm.h (struct scm_vm): So! Now that we have switched to save
stacks in the normal make-stack, there's no more need for `this_frame'
or `last_frame'. On the other hand, we can take this opportunity to fix
tracing: when we're in a trace hook, we set `trace_frame' on the VM,
so we know not to fire hooks when we're already in a hook.
(struct scm_vm_cont): Expose this, as make-stack needs it to make VM
frames from VM continuations.
* libguile/vm.c (scm_vm_trace_frame): New function, gets the current
trace frame.
(vm_mark, make_vm): Hook up the trace frame.
(vm_dispatch_hook): New hook dispatcher, with a dynwind so it does the
right thing if the hook exits nonlocally.
* libguile/vm-engine.c (vm_run): No more this_frame in the wind data.
* libguile/vm-engine.h (RUN_HOOK): Run hooks through the dispatcher.
(ALIGN_AS_NON_IMMEDIATE, POP_LIST_ON_STACK): Remove unused code.
(NEW_FRAME): Adapt for no HL in the frame.
* libguile/vm-i-system.c (goto/args, mv-call, return, return/values):
Adapt for no HL in the frame.
* module/system/vm/frame.scm:
* module/system/vm/vm.scm: Beginnings of some reworkings, needs more
thought.
2008-12-26 17:59:46 +01:00
|
|
|
|
{
|
2018-06-27 19:16:38 +02:00
|
|
|
|
struct scm_vm *vp = &thread->vm;
|
2010-04-21 01:05:42 +02:00
|
|
|
|
struct scm_frame c_frame;
|
2010-09-26 16:24:35 +02:00
|
|
|
|
scm_t_cell *frame;
|
2018-08-06 17:55:28 +02:00
|
|
|
|
SCM scm_frame;
|
2010-09-17 10:59:36 +02:00
|
|
|
|
int saved_trace_level;
|
2018-06-21 08:39:03 +02:00
|
|
|
|
uint8_t saved_compare_result;
|
remove heap links in VM frames, incorporate vm frames into normal backtraces
* doc/ref/vm.texi (Stack Layout): Update to remove references to the
"heap link".
* gdbinit: Update for "heap link" removal.
* libguile/frames.c:
* libguile/frames.h: Update macros and diagram for removal of "heap
link". As part of this, we also remove "heap frames", replacing them
with "vm frames", which are much like the interpreter's debug objects,
but for VM stacks. That is to say, they don't actually hold the stack
themselves, just the pointers into stack that's held by a continuation
(either captured or current).
* libguile/stacks.c (stack_depth, read_frames): Since a "stack" object is
really a copy of information that comes from somewhere else, it makes
sense to copy over info from the VM, just as `make-stack' does from the
evaluator. The tricky bit is to figure out how to interleave VM and
interpreter frames. We do that by starting in the interpreter, and
whenever the current frame's procedure is actually a program, we switch
to the VM stack, switching back when we reach a "bootstrap frame". The
last bit is hacky, but it does work...
(is_vm_bootstrap_frame): Hacky predicate to see if a VM frame is a
bootstrap frame.
(scm_make_stack): Accept a VM frame in addition to debug frames.
Probably has some bugs in this case. But in the case that the arg is
#t (a common case), do the right thing, capturing the top VM frame as
well, and interleaving those frames appropriately on the stack.
As an accident, we lost the ability to limit the number of frames in
the backtrace. We could add that back, but personally I always want
*all* frames in the trace... Narrowing still works fine, though there
are some hiccups sometimes -- e.g. an outer cut to a procedure that
does a tail-call in VM code will never find the cut, as it no longer
exists in the continuation.
* libguile/vm.h (struct scm_vm): So! Now that we have switched to save
stacks in the normal make-stack, there's no more need for `this_frame'
or `last_frame'. On the other hand, we can take this opportunity to fix
tracing: when we're in a trace hook, we set `trace_frame' on the VM,
so we know not to fire hooks when we're already in a hook.
(struct scm_vm_cont): Expose this, as make-stack needs it to make VM
frames from VM continuations.
* libguile/vm.c (scm_vm_trace_frame): New function, gets the current
trace frame.
(vm_mark, make_vm): Hook up the trace frame.
(vm_dispatch_hook): New hook dispatcher, with a dynwind so it does the
right thing if the hook exits nonlocally.
* libguile/vm-engine.c (vm_run): No more this_frame in the wind data.
* libguile/vm-engine.h (RUN_HOOK): Run hooks through the dispatcher.
(ALIGN_AS_NON_IMMEDIATE, POP_LIST_ON_STACK): Remove unused code.
(NEW_FRAME): Adapt for no HL in the frame.
* libguile/vm-i-system.c (goto/args, mv-call, return, return/values):
Adapt for no HL in the frame.
* module/system/vm/frame.scm:
* module/system/vm/vm.scm: Beginnings of some reworkings, needs more
thought.
2008-12-26 17:59:46 +01:00
|
|
|
|
|
2018-09-14 12:57:16 +02:00
|
|
|
|
if (scm_is_false (hook) || scm_is_null (SCM_HOOK_PROCEDURES (hook)))
|
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
|
|
|
|
return;
|
2010-04-21 01:05:42 +02:00
|
|
|
|
|
2018-09-14 12:57:16 +02:00
|
|
|
|
saved_trace_level = set_vm_trace_level (thread, 0);
|
2018-01-08 15:19:55 +01:00
|
|
|
|
saved_compare_result = vp->compare_result;
|
|
|
|
|
|
|
2010-04-21 01:05:42 +02:00
|
|
|
|
/* 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. */
|
|
|
|
|
|
|
2013-11-21 17:21:37 +01:00
|
|
|
|
c_frame.stack_holder = vp;
|
VM stack grows downward
Adapt VM stack to grow downward. This will make native compilation look
more like the VM code, as we will be able to use native CALL
instructions, taking proper advantage of the return address buffer.
* libguile/continuations.c (scm_i_continuation_to_frame): Record offsets
from stack top.
* libguile/control.c (scm_i_prompt_pop_abort_args_x): Adapt for reversed
order of arguments, and instead of relying on the abort to push on the
number of arguments, make the caller save the stack depth, which
allows us to compute the number of arguments ourselves.
(reify_partial_continuation, scm_c_abort): Adapt to reversed stack
order.
* libguile/dynstack.c (scm_dynstack_wind_prompt): Since we wind the
stack in a downward direction, subtract the reloc instead of adding
it.
* libguile/dynstack.h (SCM_F_DYNSTACK_PROMPT_ESCAPE_ONLY): Remove flag;
instead rely on prompt-establishing code to save the stack depth.
* libguile/eval.c (eval): Remove extraneous "volatile" declarations for
variables that are not re-set between the setjmp and any longjmp.
Adapt to save stack depth before instating the prompt.
* libguile/foreign.c (scm_i_foreign_call): Adapt to receive arguments in
reverse order.
* libguile/frames.c (frame_stack_top, scm_i_frame_stack_top): Adapt to
compute stack top instead of stack bottom.
(scm_c_frame_closure): Adapt to stack growth change.
(scm_frame_num_locals, scm_frame_local_ref, scm_frame_set_x): Use
union data type to access stack.
(RELOC): Reformat.
(scm_c_frame_previous): Adapt to stack growth change.
* libguile/frames.h: Adapt stack diagram to indicate that the stack
grows up.
(union scm_vm_stack_element): New data type used to access items on
the stack.
(SCM_FRAME_PREVIOUS_SP)
(SCM_FRAME_RETURN_ADDRESS, SCM_FRAME_SET_RETURN_ADDRESS)
(SCM_FRAME_DYNAMIC_LINK, SCM_FRAME_SET_DYNAMIC_LINK)
(SCM_FRAME_LOCAL, SCM_FRAME_NUM_LOCALS): Adapt to stack representation
change.
(SCM_FRAME_SLOT): New helper.
(SCM_VM_FRAME_FP, SCM_VM_FRAME_SP): Adapt to stack growth change.
* libguile/stacks.c (scm_make_stack): Record offsets from top of stack.
* libguile/throw.c (catch): Adapt to scm_i_prompt_pop_abort_args_x
change.
* libguile/vm-engine.c (ALLOC_FRAME, RESET_FRAME):
(FRAME_LOCALS_COUNT_FROM): Adapt to stack growth change.
(LOCAL_ADDRESS): Use SCM_FRAME_SLOT to get the address as the proper
data type.
(RETURN_ONE_VALUE, RETURN_VALUE_LIST): Adapt to stack growth change.
(apply): Shuffling up the SMOB apply args can cause the stack to
expand, so use ALLOC_FRAME instead of RESET_FRAME.
(vm_engine): Adapt for stack growth change.
* libguile/vm.c (vm_increase_sp, vm_push_sp, vm_restore_sp): Adapt to
stack representation change.
(scm_i_vm_cont_to_frame): Adapt to take offsets from the top.
(scm_i_vm_capture_stack): Adapt to capture from the top.
(vm_return_to_continuation_inner): Adapt for data type changes.
(vm_return_to_continuation): Likewise, and instead of looping, just
splat the saved arguments on with memcpy.
(vm_dispatch_hook): Adapt to receive arguments in the reverse order.
Adapt callers.
(vm_abort): There is never a tail argument. Adapt to stack
representation change.
(vm_reinstate_partial_continuation)
(vm_reinstate_partial_continuation_inner): Adapt to stack growth
change.
(allocate_stack, free_stack): Adapt to data type change.
(expand_stack): Don't try to mremap(), as you can't grow a mapping
from the bottom. Without knowing that there's a free mapping space
right below the old stack, which there usually isn't on Linux, we have
to copy. We can't use MAP_GROWSDOWN because Linux is buggy.
(make_vm): Adapt to stack representation changes.
(return_unused_stack_to_os): Round down instead of up, as the stack
grows down.
(scm_i_vm_mark_stack): Adapt to walk up the stack.
(scm_i_vm_free_stack): Adapt to scm_vm changes.
(vm_expand_stack_inner, reset_stack_limit, vm_expand_stack): Adapt to
the stack growing down.
(scm_call_n): Adapt to the stack growing down. Don't allow argv to
point into the stack.
* libguile/vm.h (struct scm_vm, struct scm_vm_cont): Adapt to hold the
stack top and bottom.
2015-09-22 10:24:30 +00:00
|
|
|
|
c_frame.fp_offset = vp->stack_top - vp->fp;
|
|
|
|
|
|
c_frame.sp_offset = vp->stack_top - vp->sp;
|
2010-04-21 01:05:42 +02:00
|
|
|
|
c_frame.ip = vp->ip;
|
2010-09-26 16:24:35 +02:00
|
|
|
|
|
|
|
|
|
|
/* Arrange for FRAME to be 8-byte aligned, like any other cell. */
|
|
|
|
|
|
frame = alloca (sizeof (*frame) + 8);
|
2018-06-21 08:39:03 +02:00
|
|
|
|
frame = (scm_t_cell *) ROUND_UP ((uintptr_t) frame, 8UL);
|
2010-09-26 16:24:35 +02:00
|
|
|
|
|
2013-11-21 17:13:18 +01:00
|
|
|
|
frame->word_0 = SCM_PACK (scm_tc7_frame | (SCM_VM_FRAME_KIND_VM << 8));
|
2011-10-24 17:58:22 +02:00
|
|
|
|
frame->word_1 = SCM_PACK_POINTER (&c_frame);
|
2010-04-21 01:05:42 +02:00
|
|
|
|
|
2018-08-06 17:55:28 +02:00
|
|
|
|
scm_frame = SCM_PACK_POINTER (frame);
|
|
|
|
|
|
scm_c_run_hookn (hook, &scm_frame, 1);
|
2010-04-21 01:05:42 +02:00
|
|
|
|
|
2018-01-08 15:19:55 +01:00
|
|
|
|
vp->compare_result = saved_compare_result;
|
2018-09-14 12:57:16 +02:00
|
|
|
|
set_vm_trace_level (thread, saved_trace_level);
|
remove heap links in VM frames, incorporate vm frames into normal backtraces
* doc/ref/vm.texi (Stack Layout): Update to remove references to the
"heap link".
* gdbinit: Update for "heap link" removal.
* libguile/frames.c:
* libguile/frames.h: Update macros and diagram for removal of "heap
link". As part of this, we also remove "heap frames", replacing them
with "vm frames", which are much like the interpreter's debug objects,
but for VM stacks. That is to say, they don't actually hold the stack
themselves, just the pointers into stack that's held by a continuation
(either captured or current).
* libguile/stacks.c (stack_depth, read_frames): Since a "stack" object is
really a copy of information that comes from somewhere else, it makes
sense to copy over info from the VM, just as `make-stack' does from the
evaluator. The tricky bit is to figure out how to interleave VM and
interpreter frames. We do that by starting in the interpreter, and
whenever the current frame's procedure is actually a program, we switch
to the VM stack, switching back when we reach a "bootstrap frame". The
last bit is hacky, but it does work...
(is_vm_bootstrap_frame): Hacky predicate to see if a VM frame is a
bootstrap frame.
(scm_make_stack): Accept a VM frame in addition to debug frames.
Probably has some bugs in this case. But in the case that the arg is
#t (a common case), do the right thing, capturing the top VM frame as
well, and interleaving those frames appropriately on the stack.
As an accident, we lost the ability to limit the number of frames in
the backtrace. We could add that back, but personally I always want
*all* frames in the trace... Narrowing still works fine, though there
are some hiccups sometimes -- e.g. an outer cut to a procedure that
does a tail-call in VM code will never find the cut, as it no longer
exists in the continuation.
* libguile/vm.h (struct scm_vm): So! Now that we have switched to save
stacks in the normal make-stack, there's no more need for `this_frame'
or `last_frame'. On the other hand, we can take this opportunity to fix
tracing: when we're in a trace hook, we set `trace_frame' on the VM,
so we know not to fire hooks when we're already in a hook.
(struct scm_vm_cont): Expose this, as make-stack needs it to make VM
frames from VM continuations.
* libguile/vm.c (scm_vm_trace_frame): New function, gets the current
trace frame.
(vm_mark, make_vm): Hook up the trace frame.
(vm_dispatch_hook): New hook dispatcher, with a dynwind so it does the
right thing if the hook exits nonlocally.
* libguile/vm-engine.c (vm_run): No more this_frame in the wind data.
* libguile/vm-engine.h (RUN_HOOK): Run hooks through the dispatcher.
(ALIGN_AS_NON_IMMEDIATE, POP_LIST_ON_STACK): Remove unused code.
(NEW_FRAME): Adapt for no HL in the frame.
* libguile/vm-i-system.c (goto/args, mv-call, return, return/values):
Adapt for no HL in the frame.
* module/system/vm/frame.scm:
* module/system/vm/vm.scm: Beginnings of some reworkings, needs more
thought.
2008-12-26 17:59:46 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2018-09-14 12:57:16 +02:00
|
|
|
|
#define DEFINE_INVOKE_HOOK(h) \
|
2018-09-14 09:28:36 +02:00
|
|
|
|
static void \
|
|
|
|
|
|
invoke_##h##_hook (scm_thread *thread) SCM_NOINLINE; \
|
|
|
|
|
|
static void \
|
|
|
|
|
|
invoke_##h##_hook (scm_thread *thread) \
|
|
|
|
|
|
{ \
|
2018-09-14 12:57:16 +02:00
|
|
|
|
if (thread->vm.h##_hook_enabled) \
|
|
|
|
|
|
return invoke_hook (thread, thread->vm.h##_hook); \
|
2018-09-14 09:28:36 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2018-09-14 12:57:16 +02:00
|
|
|
|
FOR_EACH_HOOK (DEFINE_INVOKE_HOOK)
|
|
|
|
|
|
|
|
|
|
|
|
#undef DEFINE_INVOKE_HOOK
|
2013-11-19 22:14:20 +01:00
|
|
|
|
|
2012-04-30 20:25:53 +02:00
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
* VM Error Handling
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
2017-11-05 14:47:18 +01:00
|
|
|
|
|
2018-06-21 08:39:03 +02:00
|
|
|
|
static void vm_error_bad_instruction (uint32_t inst) SCM_NORETURN SCM_NOINLINE;
|
2017-11-05 14:47:18 +01:00
|
|
|
|
|
2012-04-30 20:25:53 +02:00
|
|
|
|
static void
|
2018-06-21 08:39:03 +02:00
|
|
|
|
vm_error_bad_instruction (uint32_t inst)
|
2012-04-30 20:25:53 +02:00
|
|
|
|
{
|
2018-06-27 09:19:36 +02:00
|
|
|
|
fprintf (stderr, "VM: Bad instruction: %x\n", inst);
|
|
|
|
|
|
abort ();
|
2012-04-30 20:25:53 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2009-07-26 12:56:11 +02:00
|
|
|
|
|
2013-11-19 20:05:45 +01:00
|
|
|
|
static SCM vm_boot_continuation;
|
2018-08-17 08:15:04 +02:00
|
|
|
|
|
|
|
|
|
|
#define DECLARE_BUILTIN(builtin, BUILTIN, req, opt, rest) \
|
|
|
|
|
|
static SCM vm_builtin_##builtin; \
|
|
|
|
|
|
static uint32_t *vm_builtin_##builtin##_code;
|
|
|
|
|
|
FOR_EACH_VM_BUILTIN (DECLARE_BUILTIN)
|
|
|
|
|
|
#undef DECLARE_BUILTIN
|
2013-05-23 14:52:29 +02:00
|
|
|
|
|
2018-06-21 08:39:03 +02:00
|
|
|
|
static const uint32_t vm_boot_continuation_code[] = {
|
2013-11-19 21:04:24 +01:00
|
|
|
|
SCM_PACK_OP_24 (halt, 0)
|
2013-05-23 14:52:29 +02:00
|
|
|
|
};
|
|
|
|
|
|
|
2015-11-26 16:36:22 +01:00
|
|
|
|
int
|
2018-06-21 08:39:03 +02:00
|
|
|
|
scm_i_vm_is_boot_continuation_code (uint32_t *ip)
|
2015-11-26 16:36:22 +01:00
|
|
|
|
{
|
|
|
|
|
|
return ip == vm_boot_continuation_code;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-08-19 17:38:59 +02:00
|
|
|
|
SCM
|
VM has "builtins": primitives addressable by emitted RTL code
* libguile/Makefile.am:
* libguile/vm-builtins.h: New header, declaring stubs needed by the
compiler like values, apply, and abort-to-prompt.
* libguile/vm.c: Adapt the apply and values stubs to conform to a
standard interface. Add an abort-to-prompt stub. Add call/cc and
call-with-values stubs.
(scm_vm_builtin_ref): New helper, for the builtin-ref opcode.
(scm_vm_builtin_name_to_index)
(scm_vm_builtin_index_to_name): New helpers, for the compiler and
disassembler, respectively.
(scm_init_vm_builtins, scm_bootstrap_vm): Allow the compiler helpers
to be loaded later into a module.
* module/language/rtl.scm: Export builtin-index->name and
builtin-name->index.
* libguile/vm-engine.c (RETURN_VALUE_LIST): Update to use new names of
"apply" and "values".
(tail-call/shuffle): New opcode.
(abort): Update to be a tail VM op, and reorder and renumber other
ops.
(builtin-ref): New opcode.
* libguile/continuations.h:
* libguile/continuations.c (scm_i_call_with_current_continuation):
Move this to vm.[ch], implemented as a builtin.
* module/language/tree-il/compile-cps.scm (convert): Convert to
'abort-to-prompt calls, possibly with 'apply, effectively undoing the
tree-il transformation.
* module/language/cps/reify-primitives.scm (builtin-ref): New helper.
(reify-primitives): Convert builtin primitives to builtin-ref.
* module/language/cps/dfg.scm (constant-needs-allocation?):
* module/language/cps/compile-rtl.scm (emit-rtl-sequence): Add support
for compiling builtin-ref.
* module/system/vm/disassembler.scm (code-annotation): Add annotation
for builtin-ref.
2013-10-20 15:49:22 +02:00
|
|
|
|
scm_vm_builtin_ref (unsigned idx)
|
|
|
|
|
|
{
|
|
|
|
|
|
switch (idx)
|
|
|
|
|
|
{
|
2013-11-08 14:08:42 +01:00
|
|
|
|
#define INDEX_TO_NAME(builtin, BUILTIN, req, opt, rest) \
|
VM has "builtins": primitives addressable by emitted RTL code
* libguile/Makefile.am:
* libguile/vm-builtins.h: New header, declaring stubs needed by the
compiler like values, apply, and abort-to-prompt.
* libguile/vm.c: Adapt the apply and values stubs to conform to a
standard interface. Add an abort-to-prompt stub. Add call/cc and
call-with-values stubs.
(scm_vm_builtin_ref): New helper, for the builtin-ref opcode.
(scm_vm_builtin_name_to_index)
(scm_vm_builtin_index_to_name): New helpers, for the compiler and
disassembler, respectively.
(scm_init_vm_builtins, scm_bootstrap_vm): Allow the compiler helpers
to be loaded later into a module.
* module/language/rtl.scm: Export builtin-index->name and
builtin-name->index.
* libguile/vm-engine.c (RETURN_VALUE_LIST): Update to use new names of
"apply" and "values".
(tail-call/shuffle): New opcode.
(abort): Update to be a tail VM op, and reorder and renumber other
ops.
(builtin-ref): New opcode.
* libguile/continuations.h:
* libguile/continuations.c (scm_i_call_with_current_continuation):
Move this to vm.[ch], implemented as a builtin.
* module/language/tree-il/compile-cps.scm (convert): Convert to
'abort-to-prompt calls, possibly with 'apply, effectively undoing the
tree-il transformation.
* module/language/cps/reify-primitives.scm (builtin-ref): New helper.
(reify-primitives): Convert builtin primitives to builtin-ref.
* module/language/cps/dfg.scm (constant-needs-allocation?):
* module/language/cps/compile-rtl.scm (emit-rtl-sequence): Add support
for compiling builtin-ref.
* module/system/vm/disassembler.scm (code-annotation): Add annotation
for builtin-ref.
2013-10-20 15:49:22 +02:00
|
|
|
|
case SCM_VM_BUILTIN_##BUILTIN: return vm_builtin_##builtin;
|
|
|
|
|
|
FOR_EACH_VM_BUILTIN(INDEX_TO_NAME)
|
|
|
|
|
|
#undef INDEX_TO_NAME
|
|
|
|
|
|
default: abort();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2013-11-08 14:08:42 +01:00
|
|
|
|
SCM scm_sym_apply;
|
VM has "builtins": primitives addressable by emitted RTL code
* libguile/Makefile.am:
* libguile/vm-builtins.h: New header, declaring stubs needed by the
compiler like values, apply, and abort-to-prompt.
* libguile/vm.c: Adapt the apply and values stubs to conform to a
standard interface. Add an abort-to-prompt stub. Add call/cc and
call-with-values stubs.
(scm_vm_builtin_ref): New helper, for the builtin-ref opcode.
(scm_vm_builtin_name_to_index)
(scm_vm_builtin_index_to_name): New helpers, for the compiler and
disassembler, respectively.
(scm_init_vm_builtins, scm_bootstrap_vm): Allow the compiler helpers
to be loaded later into a module.
* module/language/rtl.scm: Export builtin-index->name and
builtin-name->index.
* libguile/vm-engine.c (RETURN_VALUE_LIST): Update to use new names of
"apply" and "values".
(tail-call/shuffle): New opcode.
(abort): Update to be a tail VM op, and reorder and renumber other
ops.
(builtin-ref): New opcode.
* libguile/continuations.h:
* libguile/continuations.c (scm_i_call_with_current_continuation):
Move this to vm.[ch], implemented as a builtin.
* module/language/tree-il/compile-cps.scm (convert): Convert to
'abort-to-prompt calls, possibly with 'apply, effectively undoing the
tree-il transformation.
* module/language/cps/reify-primitives.scm (builtin-ref): New helper.
(reify-primitives): Convert builtin primitives to builtin-ref.
* module/language/cps/dfg.scm (constant-needs-allocation?):
* module/language/cps/compile-rtl.scm (emit-rtl-sequence): Add support
for compiling builtin-ref.
* module/system/vm/disassembler.scm (code-annotation): Add annotation
for builtin-ref.
2013-10-20 15:49:22 +02:00
|
|
|
|
static SCM scm_sym_values;
|
|
|
|
|
|
static SCM scm_sym_abort_to_prompt;
|
|
|
|
|
|
static SCM scm_sym_call_with_values;
|
|
|
|
|
|
static SCM scm_sym_call_with_current_continuation;
|
|
|
|
|
|
|
|
|
|
|
|
SCM
|
|
|
|
|
|
scm_vm_builtin_name_to_index (SCM name)
|
|
|
|
|
|
#define FUNC_NAME "builtin-name->index"
|
|
|
|
|
|
{
|
|
|
|
|
|
SCM_VALIDATE_SYMBOL (1, name);
|
|
|
|
|
|
|
2013-11-08 14:08:42 +01:00
|
|
|
|
#define NAME_TO_INDEX(builtin, BUILTIN, req, opt, rest) \
|
VM has "builtins": primitives addressable by emitted RTL code
* libguile/Makefile.am:
* libguile/vm-builtins.h: New header, declaring stubs needed by the
compiler like values, apply, and abort-to-prompt.
* libguile/vm.c: Adapt the apply and values stubs to conform to a
standard interface. Add an abort-to-prompt stub. Add call/cc and
call-with-values stubs.
(scm_vm_builtin_ref): New helper, for the builtin-ref opcode.
(scm_vm_builtin_name_to_index)
(scm_vm_builtin_index_to_name): New helpers, for the compiler and
disassembler, respectively.
(scm_init_vm_builtins, scm_bootstrap_vm): Allow the compiler helpers
to be loaded later into a module.
* module/language/rtl.scm: Export builtin-index->name and
builtin-name->index.
* libguile/vm-engine.c (RETURN_VALUE_LIST): Update to use new names of
"apply" and "values".
(tail-call/shuffle): New opcode.
(abort): Update to be a tail VM op, and reorder and renumber other
ops.
(builtin-ref): New opcode.
* libguile/continuations.h:
* libguile/continuations.c (scm_i_call_with_current_continuation):
Move this to vm.[ch], implemented as a builtin.
* module/language/tree-il/compile-cps.scm (convert): Convert to
'abort-to-prompt calls, possibly with 'apply, effectively undoing the
tree-il transformation.
* module/language/cps/reify-primitives.scm (builtin-ref): New helper.
(reify-primitives): Convert builtin primitives to builtin-ref.
* module/language/cps/dfg.scm (constant-needs-allocation?):
* module/language/cps/compile-rtl.scm (emit-rtl-sequence): Add support
for compiling builtin-ref.
* module/system/vm/disassembler.scm (code-annotation): Add annotation
for builtin-ref.
2013-10-20 15:49:22 +02:00
|
|
|
|
if (scm_is_eq (name, scm_sym_##builtin)) \
|
|
|
|
|
|
return scm_from_uint (SCM_VM_BUILTIN_##BUILTIN);
|
|
|
|
|
|
FOR_EACH_VM_BUILTIN(NAME_TO_INDEX)
|
|
|
|
|
|
#undef NAME_TO_INDEX
|
|
|
|
|
|
|
|
|
|
|
|
return SCM_BOOL_F;
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
SCM
|
|
|
|
|
|
scm_vm_builtin_index_to_name (SCM index)
|
|
|
|
|
|
#define FUNC_NAME "builtin-index->name"
|
|
|
|
|
|
{
|
|
|
|
|
|
unsigned idx;
|
|
|
|
|
|
|
|
|
|
|
|
SCM_VALIDATE_UINT_COPY (1, index, idx);
|
|
|
|
|
|
|
|
|
|
|
|
switch (idx)
|
|
|
|
|
|
{
|
2013-11-08 14:08:42 +01:00
|
|
|
|
#define INDEX_TO_NAME(builtin, BUILTIN, req, opt, rest) \
|
VM has "builtins": primitives addressable by emitted RTL code
* libguile/Makefile.am:
* libguile/vm-builtins.h: New header, declaring stubs needed by the
compiler like values, apply, and abort-to-prompt.
* libguile/vm.c: Adapt the apply and values stubs to conform to a
standard interface. Add an abort-to-prompt stub. Add call/cc and
call-with-values stubs.
(scm_vm_builtin_ref): New helper, for the builtin-ref opcode.
(scm_vm_builtin_name_to_index)
(scm_vm_builtin_index_to_name): New helpers, for the compiler and
disassembler, respectively.
(scm_init_vm_builtins, scm_bootstrap_vm): Allow the compiler helpers
to be loaded later into a module.
* module/language/rtl.scm: Export builtin-index->name and
builtin-name->index.
* libguile/vm-engine.c (RETURN_VALUE_LIST): Update to use new names of
"apply" and "values".
(tail-call/shuffle): New opcode.
(abort): Update to be a tail VM op, and reorder and renumber other
ops.
(builtin-ref): New opcode.
* libguile/continuations.h:
* libguile/continuations.c (scm_i_call_with_current_continuation):
Move this to vm.[ch], implemented as a builtin.
* module/language/tree-il/compile-cps.scm (convert): Convert to
'abort-to-prompt calls, possibly with 'apply, effectively undoing the
tree-il transformation.
* module/language/cps/reify-primitives.scm (builtin-ref): New helper.
(reify-primitives): Convert builtin primitives to builtin-ref.
* module/language/cps/dfg.scm (constant-needs-allocation?):
* module/language/cps/compile-rtl.scm (emit-rtl-sequence): Add support
for compiling builtin-ref.
* module/system/vm/disassembler.scm (code-annotation): Add annotation
for builtin-ref.
2013-10-20 15:49:22 +02:00
|
|
|
|
case SCM_VM_BUILTIN_##BUILTIN: return scm_sym_##builtin;
|
|
|
|
|
|
FOR_EACH_VM_BUILTIN(INDEX_TO_NAME)
|
|
|
|
|
|
#undef INDEX_TO_NAME
|
|
|
|
|
|
default: return SCM_BOOL_F;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
|
scm_init_vm_builtins (void)
|
|
|
|
|
|
{
|
|
|
|
|
|
scm_c_define_gsubr ("builtin-name->index", 1, 0, 0,
|
|
|
|
|
|
scm_vm_builtin_name_to_index);
|
|
|
|
|
|
scm_c_define_gsubr ("builtin-index->name", 1, 0, 0,
|
|
|
|
|
|
scm_vm_builtin_index_to_name);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-08-17 08:15:04 +02:00
|
|
|
|
static uint32_t*
|
|
|
|
|
|
instrumented_code (const uint32_t *code, size_t byte_size)
|
|
|
|
|
|
{
|
|
|
|
|
|
uint32_t *ret, *write;
|
|
|
|
|
|
ret = scm_i_alloc_primitive_code_with_instrumentation (byte_size / 4, &write);
|
|
|
|
|
|
memcpy (write, code, byte_size);
|
|
|
|
|
|
return ret;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
|
define_vm_builtins (void)
|
|
|
|
|
|
{
|
|
|
|
|
|
const uint32_t apply_code[] = {
|
|
|
|
|
|
SCM_PACK_OP_24 (assert_nargs_ge, 3),
|
|
|
|
|
|
SCM_PACK_OP_12_12 (shuffle_down, 1, 0),
|
|
|
|
|
|
SCM_PACK_OP_24 (expand_apply_argument, 0),
|
|
|
|
|
|
SCM_PACK_OP_24 (tail_call, 0),
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const uint32_t values_code[] = {
|
|
|
|
|
|
SCM_PACK_OP_12_12 (shuffle_down, 1, 0),
|
|
|
|
|
|
SCM_PACK_OP_24 (return_values, 0)
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const uint32_t abort_to_prompt_code[] = {
|
|
|
|
|
|
SCM_PACK_OP_24 (assert_nargs_ge, 2),
|
|
|
|
|
|
SCM_PACK_OP_24 (abort, 0), /* tag in r1, vals from r2 */
|
|
|
|
|
|
/* FIXME: Partial continuation should capture caller regs. */
|
|
|
|
|
|
SCM_PACK_OP_24 (return_values, 0) /* vals from r0 */
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const uint32_t call_with_values_code[] = {
|
|
|
|
|
|
SCM_PACK_OP_24 (assert_nargs_ee, 3),
|
|
|
|
|
|
SCM_PACK_OP_24 (alloc_frame, 8),
|
|
|
|
|
|
SCM_PACK_OP_12_12 (mov, 0, 6),
|
|
|
|
|
|
SCM_PACK_OP_24 (call, 7), SCM_PACK_OP_ARG_8_24 (0, 1),
|
|
|
|
|
|
SCM_PACK_OP_24 (long_fmov, 0), SCM_PACK_OP_ARG_8_24 (0, 2),
|
|
|
|
|
|
SCM_PACK_OP_12_12 (shuffle_down, 7, 1),
|
|
|
|
|
|
SCM_PACK_OP_24 (tail_call, 0)
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const uint32_t call_with_current_continuation_code[] = {
|
|
|
|
|
|
SCM_PACK_OP_24 (assert_nargs_ee, 2),
|
|
|
|
|
|
SCM_PACK_OP_12_12 (mov, 1, 0),
|
|
|
|
|
|
SCM_PACK_OP_24 (capture_continuation, 0),
|
|
|
|
|
|
SCM_PACK_OP_24 (tail_call, 0)
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/* This one isn't exactly a builtin but we still handle it here. */
|
|
|
|
|
|
const uint32_t handle_interrupt_code[] = {
|
|
|
|
|
|
SCM_PACK_OP_24 (alloc_frame, 4),
|
|
|
|
|
|
SCM_PACK_OP_12_12 (mov, 0, 3),
|
|
|
|
|
|
SCM_PACK_OP_24 (call, 3), SCM_PACK_OP_ARG_8_24 (0, 1),
|
|
|
|
|
|
SCM_PACK_OP_24 (return_from_interrupt, 0)
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
#define DEFINE_BUILTIN(builtin, BUILTIN, req, opt, rest) \
|
|
|
|
|
|
{ \
|
|
|
|
|
|
size_t sz = sizeof (builtin##_code); \
|
|
|
|
|
|
vm_builtin_##builtin##_code = instrumented_code (builtin##_code, sz); \
|
2019-04-24 18:14:54 +02:00
|
|
|
|
vm_builtin_##builtin = \
|
|
|
|
|
|
scm_cell (scm_tc7_program | SCM_F_PROGRAM_IS_PRIMITIVE, \
|
|
|
|
|
|
(scm_t_bits)vm_builtin_##builtin##_code); \
|
2018-08-17 08:15:04 +02:00
|
|
|
|
}
|
|
|
|
|
|
FOR_EACH_VM_BUILTIN (DEFINE_BUILTIN);
|
|
|
|
|
|
#undef INDEX_TO_NAME
|
|
|
|
|
|
|
|
|
|
|
|
scm_vm_intrinsics.handle_interrupt_code =
|
|
|
|
|
|
instrumented_code (handle_interrupt_code, sizeof (handle_interrupt_code));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
VM has "builtins": primitives addressable by emitted RTL code
* libguile/Makefile.am:
* libguile/vm-builtins.h: New header, declaring stubs needed by the
compiler like values, apply, and abort-to-prompt.
* libguile/vm.c: Adapt the apply and values stubs to conform to a
standard interface. Add an abort-to-prompt stub. Add call/cc and
call-with-values stubs.
(scm_vm_builtin_ref): New helper, for the builtin-ref opcode.
(scm_vm_builtin_name_to_index)
(scm_vm_builtin_index_to_name): New helpers, for the compiler and
disassembler, respectively.
(scm_init_vm_builtins, scm_bootstrap_vm): Allow the compiler helpers
to be loaded later into a module.
* module/language/rtl.scm: Export builtin-index->name and
builtin-name->index.
* libguile/vm-engine.c (RETURN_VALUE_LIST): Update to use new names of
"apply" and "values".
(tail-call/shuffle): New opcode.
(abort): Update to be a tail VM op, and reorder and renumber other
ops.
(builtin-ref): New opcode.
* libguile/continuations.h:
* libguile/continuations.c (scm_i_call_with_current_continuation):
Move this to vm.[ch], implemented as a builtin.
* module/language/tree-il/compile-cps.scm (convert): Convert to
'abort-to-prompt calls, possibly with 'apply, effectively undoing the
tree-il transformation.
* module/language/cps/reify-primitives.scm (builtin-ref): New helper.
(reify-primitives): Convert builtin primitives to builtin-ref.
* module/language/cps/dfg.scm (constant-needs-allocation?):
* module/language/cps/compile-rtl.scm (emit-rtl-sequence): Add support
for compiling builtin-ref.
* module/system/vm/disassembler.scm (code-annotation): Add annotation
for builtin-ref.
2013-10-20 15:49:22 +02:00
|
|
|
|
SCM
|
|
|
|
|
|
scm_i_call_with_current_continuation (SCM proc)
|
|
|
|
|
|
{
|
|
|
|
|
|
return scm_call_1 (vm_builtin_call_with_current_continuation, proc);
|
|
|
|
|
|
}
|
2013-05-23 14:52:29 +02:00
|
|
|
|
|
2000-08-22 15:54:19 +00:00
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
* VM
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
2013-11-19 21:26:26 +01:00
|
|
|
|
#define VM_NAME vm_regular_engine
|
|
|
|
|
|
#define VM_USE_HOOKS 0
|
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
|
|
|
|
#define FUNC_NAME "vm-regular-engine"
|
2008-08-21 18:39:30 -07:00
|
|
|
|
#include "vm-engine.c"
|
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 FUNC_NAME
|
2013-11-19 21:26:26 +01:00
|
|
|
|
#undef VM_USE_HOOKS
|
|
|
|
|
|
#undef VM_NAME
|
2001-04-01 05:03:41 +00:00
|
|
|
|
|
2013-11-19 21:26:26 +01:00
|
|
|
|
#define VM_NAME vm_debug_engine
|
|
|
|
|
|
#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
|
|
|
|
#define FUNC_NAME "vm-debug-engine"
|
2008-08-21 18:39:30 -07:00
|
|
|
|
#include "vm-engine.c"
|
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 FUNC_NAME
|
2013-11-19 21:26:26 +01:00
|
|
|
|
#undef VM_USE_HOOKS
|
|
|
|
|
|
#undef VM_NAME
|
2001-04-01 05:03:41 +00:00
|
|
|
|
|
2018-06-27 18:57:37 +02:00
|
|
|
|
typedef SCM (*scm_t_vm_engine) (scm_thread *current_thread);
|
2013-10-17 23:16:32 +02:00
|
|
|
|
|
2013-11-19 21:26:26 +01:00
|
|
|
|
static const scm_t_vm_engine vm_engines[SCM_VM_NUM_ENGINES] =
|
|
|
|
|
|
{ vm_regular_engine, vm_debug_engine };
|
2013-10-17 23:16:32 +02:00
|
|
|
|
|
VM stack grows downward
Adapt VM stack to grow downward. This will make native compilation look
more like the VM code, as we will be able to use native CALL
instructions, taking proper advantage of the return address buffer.
* libguile/continuations.c (scm_i_continuation_to_frame): Record offsets
from stack top.
* libguile/control.c (scm_i_prompt_pop_abort_args_x): Adapt for reversed
order of arguments, and instead of relying on the abort to push on the
number of arguments, make the caller save the stack depth, which
allows us to compute the number of arguments ourselves.
(reify_partial_continuation, scm_c_abort): Adapt to reversed stack
order.
* libguile/dynstack.c (scm_dynstack_wind_prompt): Since we wind the
stack in a downward direction, subtract the reloc instead of adding
it.
* libguile/dynstack.h (SCM_F_DYNSTACK_PROMPT_ESCAPE_ONLY): Remove flag;
instead rely on prompt-establishing code to save the stack depth.
* libguile/eval.c (eval): Remove extraneous "volatile" declarations for
variables that are not re-set between the setjmp and any longjmp.
Adapt to save stack depth before instating the prompt.
* libguile/foreign.c (scm_i_foreign_call): Adapt to receive arguments in
reverse order.
* libguile/frames.c (frame_stack_top, scm_i_frame_stack_top): Adapt to
compute stack top instead of stack bottom.
(scm_c_frame_closure): Adapt to stack growth change.
(scm_frame_num_locals, scm_frame_local_ref, scm_frame_set_x): Use
union data type to access stack.
(RELOC): Reformat.
(scm_c_frame_previous): Adapt to stack growth change.
* libguile/frames.h: Adapt stack diagram to indicate that the stack
grows up.
(union scm_vm_stack_element): New data type used to access items on
the stack.
(SCM_FRAME_PREVIOUS_SP)
(SCM_FRAME_RETURN_ADDRESS, SCM_FRAME_SET_RETURN_ADDRESS)
(SCM_FRAME_DYNAMIC_LINK, SCM_FRAME_SET_DYNAMIC_LINK)
(SCM_FRAME_LOCAL, SCM_FRAME_NUM_LOCALS): Adapt to stack representation
change.
(SCM_FRAME_SLOT): New helper.
(SCM_VM_FRAME_FP, SCM_VM_FRAME_SP): Adapt to stack growth change.
* libguile/stacks.c (scm_make_stack): Record offsets from top of stack.
* libguile/throw.c (catch): Adapt to scm_i_prompt_pop_abort_args_x
change.
* libguile/vm-engine.c (ALLOC_FRAME, RESET_FRAME):
(FRAME_LOCALS_COUNT_FROM): Adapt to stack growth change.
(LOCAL_ADDRESS): Use SCM_FRAME_SLOT to get the address as the proper
data type.
(RETURN_ONE_VALUE, RETURN_VALUE_LIST): Adapt to stack growth change.
(apply): Shuffling up the SMOB apply args can cause the stack to
expand, so use ALLOC_FRAME instead of RESET_FRAME.
(vm_engine): Adapt for stack growth change.
* libguile/vm.c (vm_increase_sp, vm_push_sp, vm_restore_sp): Adapt to
stack representation change.
(scm_i_vm_cont_to_frame): Adapt to take offsets from the top.
(scm_i_vm_capture_stack): Adapt to capture from the top.
(vm_return_to_continuation_inner): Adapt for data type changes.
(vm_return_to_continuation): Likewise, and instead of looping, just
splat the saved arguments on with memcpy.
(vm_dispatch_hook): Adapt to receive arguments in the reverse order.
Adapt callers.
(vm_abort): There is never a tail argument. Adapt to stack
representation change.
(vm_reinstate_partial_continuation)
(vm_reinstate_partial_continuation_inner): Adapt to stack growth
change.
(allocate_stack, free_stack): Adapt to data type change.
(expand_stack): Don't try to mremap(), as you can't grow a mapping
from the bottom. Without knowing that there's a free mapping space
right below the old stack, which there usually isn't on Linux, we have
to copy. We can't use MAP_GROWSDOWN because Linux is buggy.
(make_vm): Adapt to stack representation changes.
(return_unused_stack_to_os): Round down instead of up, as the stack
grows down.
(scm_i_vm_mark_stack): Adapt to walk up the stack.
(scm_i_vm_free_stack): Adapt to scm_vm changes.
(vm_expand_stack_inner, reset_stack_limit, vm_expand_stack): Adapt to
the stack growing down.
(scm_call_n): Adapt to the stack growing down. Don't allow argv to
point into the stack.
* libguile/vm.h (struct scm_vm, struct scm_vm_cont): Adapt to hold the
stack top and bottom.
2015-09-22 10:24:30 +00:00
|
|
|
|
static union scm_vm_stack_element*
|
2013-11-22 14:41:19 +01:00
|
|
|
|
allocate_stack (size_t size)
|
|
|
|
|
|
{
|
|
|
|
|
|
void *ret;
|
2009-08-20 01:56:47 +02:00
|
|
|
|
|
VM stack grows downward
Adapt VM stack to grow downward. This will make native compilation look
more like the VM code, as we will be able to use native CALL
instructions, taking proper advantage of the return address buffer.
* libguile/continuations.c (scm_i_continuation_to_frame): Record offsets
from stack top.
* libguile/control.c (scm_i_prompt_pop_abort_args_x): Adapt for reversed
order of arguments, and instead of relying on the abort to push on the
number of arguments, make the caller save the stack depth, which
allows us to compute the number of arguments ourselves.
(reify_partial_continuation, scm_c_abort): Adapt to reversed stack
order.
* libguile/dynstack.c (scm_dynstack_wind_prompt): Since we wind the
stack in a downward direction, subtract the reloc instead of adding
it.
* libguile/dynstack.h (SCM_F_DYNSTACK_PROMPT_ESCAPE_ONLY): Remove flag;
instead rely on prompt-establishing code to save the stack depth.
* libguile/eval.c (eval): Remove extraneous "volatile" declarations for
variables that are not re-set between the setjmp and any longjmp.
Adapt to save stack depth before instating the prompt.
* libguile/foreign.c (scm_i_foreign_call): Adapt to receive arguments in
reverse order.
* libguile/frames.c (frame_stack_top, scm_i_frame_stack_top): Adapt to
compute stack top instead of stack bottom.
(scm_c_frame_closure): Adapt to stack growth change.
(scm_frame_num_locals, scm_frame_local_ref, scm_frame_set_x): Use
union data type to access stack.
(RELOC): Reformat.
(scm_c_frame_previous): Adapt to stack growth change.
* libguile/frames.h: Adapt stack diagram to indicate that the stack
grows up.
(union scm_vm_stack_element): New data type used to access items on
the stack.
(SCM_FRAME_PREVIOUS_SP)
(SCM_FRAME_RETURN_ADDRESS, SCM_FRAME_SET_RETURN_ADDRESS)
(SCM_FRAME_DYNAMIC_LINK, SCM_FRAME_SET_DYNAMIC_LINK)
(SCM_FRAME_LOCAL, SCM_FRAME_NUM_LOCALS): Adapt to stack representation
change.
(SCM_FRAME_SLOT): New helper.
(SCM_VM_FRAME_FP, SCM_VM_FRAME_SP): Adapt to stack growth change.
* libguile/stacks.c (scm_make_stack): Record offsets from top of stack.
* libguile/throw.c (catch): Adapt to scm_i_prompt_pop_abort_args_x
change.
* libguile/vm-engine.c (ALLOC_FRAME, RESET_FRAME):
(FRAME_LOCALS_COUNT_FROM): Adapt to stack growth change.
(LOCAL_ADDRESS): Use SCM_FRAME_SLOT to get the address as the proper
data type.
(RETURN_ONE_VALUE, RETURN_VALUE_LIST): Adapt to stack growth change.
(apply): Shuffling up the SMOB apply args can cause the stack to
expand, so use ALLOC_FRAME instead of RESET_FRAME.
(vm_engine): Adapt for stack growth change.
* libguile/vm.c (vm_increase_sp, vm_push_sp, vm_restore_sp): Adapt to
stack representation change.
(scm_i_vm_cont_to_frame): Adapt to take offsets from the top.
(scm_i_vm_capture_stack): Adapt to capture from the top.
(vm_return_to_continuation_inner): Adapt for data type changes.
(vm_return_to_continuation): Likewise, and instead of looping, just
splat the saved arguments on with memcpy.
(vm_dispatch_hook): Adapt to receive arguments in the reverse order.
Adapt callers.
(vm_abort): There is never a tail argument. Adapt to stack
representation change.
(vm_reinstate_partial_continuation)
(vm_reinstate_partial_continuation_inner): Adapt to stack growth
change.
(allocate_stack, free_stack): Adapt to data type change.
(expand_stack): Don't try to mremap(), as you can't grow a mapping
from the bottom. Without knowing that there's a free mapping space
right below the old stack, which there usually isn't on Linux, we have
to copy. We can't use MAP_GROWSDOWN because Linux is buggy.
(make_vm): Adapt to stack representation changes.
(return_unused_stack_to_os): Round down instead of up, as the stack
grows down.
(scm_i_vm_mark_stack): Adapt to walk up the stack.
(scm_i_vm_free_stack): Adapt to scm_vm changes.
(vm_expand_stack_inner, reset_stack_limit, vm_expand_stack): Adapt to
the stack growing down.
(scm_call_n): Adapt to the stack growing down. Don't allow argv to
point into the stack.
* libguile/vm.h (struct scm_vm, struct scm_vm_cont): Adapt to hold the
stack top and bottom.
2015-09-22 10:24:30 +00:00
|
|
|
|
if (size >= ((size_t) -1) / sizeof (union scm_vm_stack_element))
|
2013-11-22 14:41:19 +01:00
|
|
|
|
abort ();
|
|
|
|
|
|
|
VM stack grows downward
Adapt VM stack to grow downward. This will make native compilation look
more like the VM code, as we will be able to use native CALL
instructions, taking proper advantage of the return address buffer.
* libguile/continuations.c (scm_i_continuation_to_frame): Record offsets
from stack top.
* libguile/control.c (scm_i_prompt_pop_abort_args_x): Adapt for reversed
order of arguments, and instead of relying on the abort to push on the
number of arguments, make the caller save the stack depth, which
allows us to compute the number of arguments ourselves.
(reify_partial_continuation, scm_c_abort): Adapt to reversed stack
order.
* libguile/dynstack.c (scm_dynstack_wind_prompt): Since we wind the
stack in a downward direction, subtract the reloc instead of adding
it.
* libguile/dynstack.h (SCM_F_DYNSTACK_PROMPT_ESCAPE_ONLY): Remove flag;
instead rely on prompt-establishing code to save the stack depth.
* libguile/eval.c (eval): Remove extraneous "volatile" declarations for
variables that are not re-set between the setjmp and any longjmp.
Adapt to save stack depth before instating the prompt.
* libguile/foreign.c (scm_i_foreign_call): Adapt to receive arguments in
reverse order.
* libguile/frames.c (frame_stack_top, scm_i_frame_stack_top): Adapt to
compute stack top instead of stack bottom.
(scm_c_frame_closure): Adapt to stack growth change.
(scm_frame_num_locals, scm_frame_local_ref, scm_frame_set_x): Use
union data type to access stack.
(RELOC): Reformat.
(scm_c_frame_previous): Adapt to stack growth change.
* libguile/frames.h: Adapt stack diagram to indicate that the stack
grows up.
(union scm_vm_stack_element): New data type used to access items on
the stack.
(SCM_FRAME_PREVIOUS_SP)
(SCM_FRAME_RETURN_ADDRESS, SCM_FRAME_SET_RETURN_ADDRESS)
(SCM_FRAME_DYNAMIC_LINK, SCM_FRAME_SET_DYNAMIC_LINK)
(SCM_FRAME_LOCAL, SCM_FRAME_NUM_LOCALS): Adapt to stack representation
change.
(SCM_FRAME_SLOT): New helper.
(SCM_VM_FRAME_FP, SCM_VM_FRAME_SP): Adapt to stack growth change.
* libguile/stacks.c (scm_make_stack): Record offsets from top of stack.
* libguile/throw.c (catch): Adapt to scm_i_prompt_pop_abort_args_x
change.
* libguile/vm-engine.c (ALLOC_FRAME, RESET_FRAME):
(FRAME_LOCALS_COUNT_FROM): Adapt to stack growth change.
(LOCAL_ADDRESS): Use SCM_FRAME_SLOT to get the address as the proper
data type.
(RETURN_ONE_VALUE, RETURN_VALUE_LIST): Adapt to stack growth change.
(apply): Shuffling up the SMOB apply args can cause the stack to
expand, so use ALLOC_FRAME instead of RESET_FRAME.
(vm_engine): Adapt for stack growth change.
* libguile/vm.c (vm_increase_sp, vm_push_sp, vm_restore_sp): Adapt to
stack representation change.
(scm_i_vm_cont_to_frame): Adapt to take offsets from the top.
(scm_i_vm_capture_stack): Adapt to capture from the top.
(vm_return_to_continuation_inner): Adapt for data type changes.
(vm_return_to_continuation): Likewise, and instead of looping, just
splat the saved arguments on with memcpy.
(vm_dispatch_hook): Adapt to receive arguments in the reverse order.
Adapt callers.
(vm_abort): There is never a tail argument. Adapt to stack
representation change.
(vm_reinstate_partial_continuation)
(vm_reinstate_partial_continuation_inner): Adapt to stack growth
change.
(allocate_stack, free_stack): Adapt to data type change.
(expand_stack): Don't try to mremap(), as you can't grow a mapping
from the bottom. Without knowing that there's a free mapping space
right below the old stack, which there usually isn't on Linux, we have
to copy. We can't use MAP_GROWSDOWN because Linux is buggy.
(make_vm): Adapt to stack representation changes.
(return_unused_stack_to_os): Round down instead of up, as the stack
grows down.
(scm_i_vm_mark_stack): Adapt to walk up the stack.
(scm_i_vm_free_stack): Adapt to scm_vm changes.
(vm_expand_stack_inner, reset_stack_limit, vm_expand_stack): Adapt to
the stack growing down.
(scm_call_n): Adapt to the stack growing down. Don't allow argv to
point into the stack.
* libguile/vm.h (struct scm_vm, struct scm_vm_cont): Adapt to hold the
stack top and bottom.
2015-09-22 10:24:30 +00:00
|
|
|
|
size *= sizeof (union scm_vm_stack_element);
|
2009-08-20 01:56:47 +02:00
|
|
|
|
|
2013-11-22 14:41:19 +01:00
|
|
|
|
#if HAVE_SYS_MMAN_H
|
|
|
|
|
|
ret = mmap (NULL, size, PROT_READ | PROT_WRITE,
|
|
|
|
|
|
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
VM stack grows downward
Adapt VM stack to grow downward. This will make native compilation look
more like the VM code, as we will be able to use native CALL
instructions, taking proper advantage of the return address buffer.
* libguile/continuations.c (scm_i_continuation_to_frame): Record offsets
from stack top.
* libguile/control.c (scm_i_prompt_pop_abort_args_x): Adapt for reversed
order of arguments, and instead of relying on the abort to push on the
number of arguments, make the caller save the stack depth, which
allows us to compute the number of arguments ourselves.
(reify_partial_continuation, scm_c_abort): Adapt to reversed stack
order.
* libguile/dynstack.c (scm_dynstack_wind_prompt): Since we wind the
stack in a downward direction, subtract the reloc instead of adding
it.
* libguile/dynstack.h (SCM_F_DYNSTACK_PROMPT_ESCAPE_ONLY): Remove flag;
instead rely on prompt-establishing code to save the stack depth.
* libguile/eval.c (eval): Remove extraneous "volatile" declarations for
variables that are not re-set between the setjmp and any longjmp.
Adapt to save stack depth before instating the prompt.
* libguile/foreign.c (scm_i_foreign_call): Adapt to receive arguments in
reverse order.
* libguile/frames.c (frame_stack_top, scm_i_frame_stack_top): Adapt to
compute stack top instead of stack bottom.
(scm_c_frame_closure): Adapt to stack growth change.
(scm_frame_num_locals, scm_frame_local_ref, scm_frame_set_x): Use
union data type to access stack.
(RELOC): Reformat.
(scm_c_frame_previous): Adapt to stack growth change.
* libguile/frames.h: Adapt stack diagram to indicate that the stack
grows up.
(union scm_vm_stack_element): New data type used to access items on
the stack.
(SCM_FRAME_PREVIOUS_SP)
(SCM_FRAME_RETURN_ADDRESS, SCM_FRAME_SET_RETURN_ADDRESS)
(SCM_FRAME_DYNAMIC_LINK, SCM_FRAME_SET_DYNAMIC_LINK)
(SCM_FRAME_LOCAL, SCM_FRAME_NUM_LOCALS): Adapt to stack representation
change.
(SCM_FRAME_SLOT): New helper.
(SCM_VM_FRAME_FP, SCM_VM_FRAME_SP): Adapt to stack growth change.
* libguile/stacks.c (scm_make_stack): Record offsets from top of stack.
* libguile/throw.c (catch): Adapt to scm_i_prompt_pop_abort_args_x
change.
* libguile/vm-engine.c (ALLOC_FRAME, RESET_FRAME):
(FRAME_LOCALS_COUNT_FROM): Adapt to stack growth change.
(LOCAL_ADDRESS): Use SCM_FRAME_SLOT to get the address as the proper
data type.
(RETURN_ONE_VALUE, RETURN_VALUE_LIST): Adapt to stack growth change.
(apply): Shuffling up the SMOB apply args can cause the stack to
expand, so use ALLOC_FRAME instead of RESET_FRAME.
(vm_engine): Adapt for stack growth change.
* libguile/vm.c (vm_increase_sp, vm_push_sp, vm_restore_sp): Adapt to
stack representation change.
(scm_i_vm_cont_to_frame): Adapt to take offsets from the top.
(scm_i_vm_capture_stack): Adapt to capture from the top.
(vm_return_to_continuation_inner): Adapt for data type changes.
(vm_return_to_continuation): Likewise, and instead of looping, just
splat the saved arguments on with memcpy.
(vm_dispatch_hook): Adapt to receive arguments in the reverse order.
Adapt callers.
(vm_abort): There is never a tail argument. Adapt to stack
representation change.
(vm_reinstate_partial_continuation)
(vm_reinstate_partial_continuation_inner): Adapt to stack growth
change.
(allocate_stack, free_stack): Adapt to data type change.
(expand_stack): Don't try to mremap(), as you can't grow a mapping
from the bottom. Without knowing that there's a free mapping space
right below the old stack, which there usually isn't on Linux, we have
to copy. We can't use MAP_GROWSDOWN because Linux is buggy.
(make_vm): Adapt to stack representation changes.
(return_unused_stack_to_os): Round down instead of up, as the stack
grows down.
(scm_i_vm_mark_stack): Adapt to walk up the stack.
(scm_i_vm_free_stack): Adapt to scm_vm changes.
(vm_expand_stack_inner, reset_stack_limit, vm_expand_stack): Adapt to
the stack growing down.
(scm_call_n): Adapt to the stack growing down. Don't allow argv to
point into the stack.
* libguile/vm.h (struct scm_vm, struct scm_vm_cont): Adapt to hold the
stack top and bottom.
2015-09-22 10:24:30 +00:00
|
|
|
|
if (ret == NULL)
|
|
|
|
|
|
/* Shouldn't happen. */
|
|
|
|
|
|
abort ();
|
2013-11-22 14:41:19 +01:00
|
|
|
|
if (ret == MAP_FAILED)
|
2014-02-19 11:01:39 +01:00
|
|
|
|
ret = NULL;
|
2013-11-22 14:41:19 +01:00
|
|
|
|
#else
|
|
|
|
|
|
ret = malloc (size);
|
2009-08-20 01:56:47 +02:00
|
|
|
|
#endif
|
|
|
|
|
|
|
2014-02-19 11:01:39 +01:00
|
|
|
|
if (!ret)
|
VM stack grows downward
Adapt VM stack to grow downward. This will make native compilation look
more like the VM code, as we will be able to use native CALL
instructions, taking proper advantage of the return address buffer.
* libguile/continuations.c (scm_i_continuation_to_frame): Record offsets
from stack top.
* libguile/control.c (scm_i_prompt_pop_abort_args_x): Adapt for reversed
order of arguments, and instead of relying on the abort to push on the
number of arguments, make the caller save the stack depth, which
allows us to compute the number of arguments ourselves.
(reify_partial_continuation, scm_c_abort): Adapt to reversed stack
order.
* libguile/dynstack.c (scm_dynstack_wind_prompt): Since we wind the
stack in a downward direction, subtract the reloc instead of adding
it.
* libguile/dynstack.h (SCM_F_DYNSTACK_PROMPT_ESCAPE_ONLY): Remove flag;
instead rely on prompt-establishing code to save the stack depth.
* libguile/eval.c (eval): Remove extraneous "volatile" declarations for
variables that are not re-set between the setjmp and any longjmp.
Adapt to save stack depth before instating the prompt.
* libguile/foreign.c (scm_i_foreign_call): Adapt to receive arguments in
reverse order.
* libguile/frames.c (frame_stack_top, scm_i_frame_stack_top): Adapt to
compute stack top instead of stack bottom.
(scm_c_frame_closure): Adapt to stack growth change.
(scm_frame_num_locals, scm_frame_local_ref, scm_frame_set_x): Use
union data type to access stack.
(RELOC): Reformat.
(scm_c_frame_previous): Adapt to stack growth change.
* libguile/frames.h: Adapt stack diagram to indicate that the stack
grows up.
(union scm_vm_stack_element): New data type used to access items on
the stack.
(SCM_FRAME_PREVIOUS_SP)
(SCM_FRAME_RETURN_ADDRESS, SCM_FRAME_SET_RETURN_ADDRESS)
(SCM_FRAME_DYNAMIC_LINK, SCM_FRAME_SET_DYNAMIC_LINK)
(SCM_FRAME_LOCAL, SCM_FRAME_NUM_LOCALS): Adapt to stack representation
change.
(SCM_FRAME_SLOT): New helper.
(SCM_VM_FRAME_FP, SCM_VM_FRAME_SP): Adapt to stack growth change.
* libguile/stacks.c (scm_make_stack): Record offsets from top of stack.
* libguile/throw.c (catch): Adapt to scm_i_prompt_pop_abort_args_x
change.
* libguile/vm-engine.c (ALLOC_FRAME, RESET_FRAME):
(FRAME_LOCALS_COUNT_FROM): Adapt to stack growth change.
(LOCAL_ADDRESS): Use SCM_FRAME_SLOT to get the address as the proper
data type.
(RETURN_ONE_VALUE, RETURN_VALUE_LIST): Adapt to stack growth change.
(apply): Shuffling up the SMOB apply args can cause the stack to
expand, so use ALLOC_FRAME instead of RESET_FRAME.
(vm_engine): Adapt for stack growth change.
* libguile/vm.c (vm_increase_sp, vm_push_sp, vm_restore_sp): Adapt to
stack representation change.
(scm_i_vm_cont_to_frame): Adapt to take offsets from the top.
(scm_i_vm_capture_stack): Adapt to capture from the top.
(vm_return_to_continuation_inner): Adapt for data type changes.
(vm_return_to_continuation): Likewise, and instead of looping, just
splat the saved arguments on with memcpy.
(vm_dispatch_hook): Adapt to receive arguments in the reverse order.
Adapt callers.
(vm_abort): There is never a tail argument. Adapt to stack
representation change.
(vm_reinstate_partial_continuation)
(vm_reinstate_partial_continuation_inner): Adapt to stack growth
change.
(allocate_stack, free_stack): Adapt to data type change.
(expand_stack): Don't try to mremap(), as you can't grow a mapping
from the bottom. Without knowing that there's a free mapping space
right below the old stack, which there usually isn't on Linux, we have
to copy. We can't use MAP_GROWSDOWN because Linux is buggy.
(make_vm): Adapt to stack representation changes.
(return_unused_stack_to_os): Round down instead of up, as the stack
grows down.
(scm_i_vm_mark_stack): Adapt to walk up the stack.
(scm_i_vm_free_stack): Adapt to scm_vm changes.
(vm_expand_stack_inner, reset_stack_limit, vm_expand_stack): Adapt to
the stack growing down.
(scm_call_n): Adapt to the stack growing down. Don't allow argv to
point into the stack.
* libguile/vm.h (struct scm_vm, struct scm_vm_cont): Adapt to hold the
stack top and bottom.
2015-09-22 10:24:30 +00:00
|
|
|
|
perror ("allocate_stack failed");
|
2014-02-19 11:01:39 +01:00
|
|
|
|
|
VM stack grows downward
Adapt VM stack to grow downward. This will make native compilation look
more like the VM code, as we will be able to use native CALL
instructions, taking proper advantage of the return address buffer.
* libguile/continuations.c (scm_i_continuation_to_frame): Record offsets
from stack top.
* libguile/control.c (scm_i_prompt_pop_abort_args_x): Adapt for reversed
order of arguments, and instead of relying on the abort to push on the
number of arguments, make the caller save the stack depth, which
allows us to compute the number of arguments ourselves.
(reify_partial_continuation, scm_c_abort): Adapt to reversed stack
order.
* libguile/dynstack.c (scm_dynstack_wind_prompt): Since we wind the
stack in a downward direction, subtract the reloc instead of adding
it.
* libguile/dynstack.h (SCM_F_DYNSTACK_PROMPT_ESCAPE_ONLY): Remove flag;
instead rely on prompt-establishing code to save the stack depth.
* libguile/eval.c (eval): Remove extraneous "volatile" declarations for
variables that are not re-set between the setjmp and any longjmp.
Adapt to save stack depth before instating the prompt.
* libguile/foreign.c (scm_i_foreign_call): Adapt to receive arguments in
reverse order.
* libguile/frames.c (frame_stack_top, scm_i_frame_stack_top): Adapt to
compute stack top instead of stack bottom.
(scm_c_frame_closure): Adapt to stack growth change.
(scm_frame_num_locals, scm_frame_local_ref, scm_frame_set_x): Use
union data type to access stack.
(RELOC): Reformat.
(scm_c_frame_previous): Adapt to stack growth change.
* libguile/frames.h: Adapt stack diagram to indicate that the stack
grows up.
(union scm_vm_stack_element): New data type used to access items on
the stack.
(SCM_FRAME_PREVIOUS_SP)
(SCM_FRAME_RETURN_ADDRESS, SCM_FRAME_SET_RETURN_ADDRESS)
(SCM_FRAME_DYNAMIC_LINK, SCM_FRAME_SET_DYNAMIC_LINK)
(SCM_FRAME_LOCAL, SCM_FRAME_NUM_LOCALS): Adapt to stack representation
change.
(SCM_FRAME_SLOT): New helper.
(SCM_VM_FRAME_FP, SCM_VM_FRAME_SP): Adapt to stack growth change.
* libguile/stacks.c (scm_make_stack): Record offsets from top of stack.
* libguile/throw.c (catch): Adapt to scm_i_prompt_pop_abort_args_x
change.
* libguile/vm-engine.c (ALLOC_FRAME, RESET_FRAME):
(FRAME_LOCALS_COUNT_FROM): Adapt to stack growth change.
(LOCAL_ADDRESS): Use SCM_FRAME_SLOT to get the address as the proper
data type.
(RETURN_ONE_VALUE, RETURN_VALUE_LIST): Adapt to stack growth change.
(apply): Shuffling up the SMOB apply args can cause the stack to
expand, so use ALLOC_FRAME instead of RESET_FRAME.
(vm_engine): Adapt for stack growth change.
* libguile/vm.c (vm_increase_sp, vm_push_sp, vm_restore_sp): Adapt to
stack representation change.
(scm_i_vm_cont_to_frame): Adapt to take offsets from the top.
(scm_i_vm_capture_stack): Adapt to capture from the top.
(vm_return_to_continuation_inner): Adapt for data type changes.
(vm_return_to_continuation): Likewise, and instead of looping, just
splat the saved arguments on with memcpy.
(vm_dispatch_hook): Adapt to receive arguments in the reverse order.
Adapt callers.
(vm_abort): There is never a tail argument. Adapt to stack
representation change.
(vm_reinstate_partial_continuation)
(vm_reinstate_partial_continuation_inner): Adapt to stack growth
change.
(allocate_stack, free_stack): Adapt to data type change.
(expand_stack): Don't try to mremap(), as you can't grow a mapping
from the bottom. Without knowing that there's a free mapping space
right below the old stack, which there usually isn't on Linux, we have
to copy. We can't use MAP_GROWSDOWN because Linux is buggy.
(make_vm): Adapt to stack representation changes.
(return_unused_stack_to_os): Round down instead of up, as the stack
grows down.
(scm_i_vm_mark_stack): Adapt to walk up the stack.
(scm_i_vm_free_stack): Adapt to scm_vm changes.
(vm_expand_stack_inner, reset_stack_limit, vm_expand_stack): Adapt to
the stack growing down.
(scm_call_n): Adapt to the stack growing down. Don't allow argv to
point into the stack.
* libguile/vm.h (struct scm_vm, struct scm_vm_cont): Adapt to hold the
stack top and bottom.
2015-09-22 10:24:30 +00:00
|
|
|
|
return (union scm_vm_stack_element *) ret;
|
2013-11-22 14:41:19 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
VM stack grows downward
Adapt VM stack to grow downward. This will make native compilation look
more like the VM code, as we will be able to use native CALL
instructions, taking proper advantage of the return address buffer.
* libguile/continuations.c (scm_i_continuation_to_frame): Record offsets
from stack top.
* libguile/control.c (scm_i_prompt_pop_abort_args_x): Adapt for reversed
order of arguments, and instead of relying on the abort to push on the
number of arguments, make the caller save the stack depth, which
allows us to compute the number of arguments ourselves.
(reify_partial_continuation, scm_c_abort): Adapt to reversed stack
order.
* libguile/dynstack.c (scm_dynstack_wind_prompt): Since we wind the
stack in a downward direction, subtract the reloc instead of adding
it.
* libguile/dynstack.h (SCM_F_DYNSTACK_PROMPT_ESCAPE_ONLY): Remove flag;
instead rely on prompt-establishing code to save the stack depth.
* libguile/eval.c (eval): Remove extraneous "volatile" declarations for
variables that are not re-set between the setjmp and any longjmp.
Adapt to save stack depth before instating the prompt.
* libguile/foreign.c (scm_i_foreign_call): Adapt to receive arguments in
reverse order.
* libguile/frames.c (frame_stack_top, scm_i_frame_stack_top): Adapt to
compute stack top instead of stack bottom.
(scm_c_frame_closure): Adapt to stack growth change.
(scm_frame_num_locals, scm_frame_local_ref, scm_frame_set_x): Use
union data type to access stack.
(RELOC): Reformat.
(scm_c_frame_previous): Adapt to stack growth change.
* libguile/frames.h: Adapt stack diagram to indicate that the stack
grows up.
(union scm_vm_stack_element): New data type used to access items on
the stack.
(SCM_FRAME_PREVIOUS_SP)
(SCM_FRAME_RETURN_ADDRESS, SCM_FRAME_SET_RETURN_ADDRESS)
(SCM_FRAME_DYNAMIC_LINK, SCM_FRAME_SET_DYNAMIC_LINK)
(SCM_FRAME_LOCAL, SCM_FRAME_NUM_LOCALS): Adapt to stack representation
change.
(SCM_FRAME_SLOT): New helper.
(SCM_VM_FRAME_FP, SCM_VM_FRAME_SP): Adapt to stack growth change.
* libguile/stacks.c (scm_make_stack): Record offsets from top of stack.
* libguile/throw.c (catch): Adapt to scm_i_prompt_pop_abort_args_x
change.
* libguile/vm-engine.c (ALLOC_FRAME, RESET_FRAME):
(FRAME_LOCALS_COUNT_FROM): Adapt to stack growth change.
(LOCAL_ADDRESS): Use SCM_FRAME_SLOT to get the address as the proper
data type.
(RETURN_ONE_VALUE, RETURN_VALUE_LIST): Adapt to stack growth change.
(apply): Shuffling up the SMOB apply args can cause the stack to
expand, so use ALLOC_FRAME instead of RESET_FRAME.
(vm_engine): Adapt for stack growth change.
* libguile/vm.c (vm_increase_sp, vm_push_sp, vm_restore_sp): Adapt to
stack representation change.
(scm_i_vm_cont_to_frame): Adapt to take offsets from the top.
(scm_i_vm_capture_stack): Adapt to capture from the top.
(vm_return_to_continuation_inner): Adapt for data type changes.
(vm_return_to_continuation): Likewise, and instead of looping, just
splat the saved arguments on with memcpy.
(vm_dispatch_hook): Adapt to receive arguments in the reverse order.
Adapt callers.
(vm_abort): There is never a tail argument. Adapt to stack
representation change.
(vm_reinstate_partial_continuation)
(vm_reinstate_partial_continuation_inner): Adapt to stack growth
change.
(allocate_stack, free_stack): Adapt to data type change.
(expand_stack): Don't try to mremap(), as you can't grow a mapping
from the bottom. Without knowing that there's a free mapping space
right below the old stack, which there usually isn't on Linux, we have
to copy. We can't use MAP_GROWSDOWN because Linux is buggy.
(make_vm): Adapt to stack representation changes.
(return_unused_stack_to_os): Round down instead of up, as the stack
grows down.
(scm_i_vm_mark_stack): Adapt to walk up the stack.
(scm_i_vm_free_stack): Adapt to scm_vm changes.
(vm_expand_stack_inner, reset_stack_limit, vm_expand_stack): Adapt to
the stack growing down.
(scm_call_n): Adapt to the stack growing down. Don't allow argv to
point into the stack.
* libguile/vm.h (struct scm_vm, struct scm_vm_cont): Adapt to hold the
stack top and bottom.
2015-09-22 10:24:30 +00:00
|
|
|
|
free_stack (union scm_vm_stack_element *stack, size_t size)
|
2013-11-22 14:41:19 +01:00
|
|
|
|
{
|
VM stack grows downward
Adapt VM stack to grow downward. This will make native compilation look
more like the VM code, as we will be able to use native CALL
instructions, taking proper advantage of the return address buffer.
* libguile/continuations.c (scm_i_continuation_to_frame): Record offsets
from stack top.
* libguile/control.c (scm_i_prompt_pop_abort_args_x): Adapt for reversed
order of arguments, and instead of relying on the abort to push on the
number of arguments, make the caller save the stack depth, which
allows us to compute the number of arguments ourselves.
(reify_partial_continuation, scm_c_abort): Adapt to reversed stack
order.
* libguile/dynstack.c (scm_dynstack_wind_prompt): Since we wind the
stack in a downward direction, subtract the reloc instead of adding
it.
* libguile/dynstack.h (SCM_F_DYNSTACK_PROMPT_ESCAPE_ONLY): Remove flag;
instead rely on prompt-establishing code to save the stack depth.
* libguile/eval.c (eval): Remove extraneous "volatile" declarations for
variables that are not re-set between the setjmp and any longjmp.
Adapt to save stack depth before instating the prompt.
* libguile/foreign.c (scm_i_foreign_call): Adapt to receive arguments in
reverse order.
* libguile/frames.c (frame_stack_top, scm_i_frame_stack_top): Adapt to
compute stack top instead of stack bottom.
(scm_c_frame_closure): Adapt to stack growth change.
(scm_frame_num_locals, scm_frame_local_ref, scm_frame_set_x): Use
union data type to access stack.
(RELOC): Reformat.
(scm_c_frame_previous): Adapt to stack growth change.
* libguile/frames.h: Adapt stack diagram to indicate that the stack
grows up.
(union scm_vm_stack_element): New data type used to access items on
the stack.
(SCM_FRAME_PREVIOUS_SP)
(SCM_FRAME_RETURN_ADDRESS, SCM_FRAME_SET_RETURN_ADDRESS)
(SCM_FRAME_DYNAMIC_LINK, SCM_FRAME_SET_DYNAMIC_LINK)
(SCM_FRAME_LOCAL, SCM_FRAME_NUM_LOCALS): Adapt to stack representation
change.
(SCM_FRAME_SLOT): New helper.
(SCM_VM_FRAME_FP, SCM_VM_FRAME_SP): Adapt to stack growth change.
* libguile/stacks.c (scm_make_stack): Record offsets from top of stack.
* libguile/throw.c (catch): Adapt to scm_i_prompt_pop_abort_args_x
change.
* libguile/vm-engine.c (ALLOC_FRAME, RESET_FRAME):
(FRAME_LOCALS_COUNT_FROM): Adapt to stack growth change.
(LOCAL_ADDRESS): Use SCM_FRAME_SLOT to get the address as the proper
data type.
(RETURN_ONE_VALUE, RETURN_VALUE_LIST): Adapt to stack growth change.
(apply): Shuffling up the SMOB apply args can cause the stack to
expand, so use ALLOC_FRAME instead of RESET_FRAME.
(vm_engine): Adapt for stack growth change.
* libguile/vm.c (vm_increase_sp, vm_push_sp, vm_restore_sp): Adapt to
stack representation change.
(scm_i_vm_cont_to_frame): Adapt to take offsets from the top.
(scm_i_vm_capture_stack): Adapt to capture from the top.
(vm_return_to_continuation_inner): Adapt for data type changes.
(vm_return_to_continuation): Likewise, and instead of looping, just
splat the saved arguments on with memcpy.
(vm_dispatch_hook): Adapt to receive arguments in the reverse order.
Adapt callers.
(vm_abort): There is never a tail argument. Adapt to stack
representation change.
(vm_reinstate_partial_continuation)
(vm_reinstate_partial_continuation_inner): Adapt to stack growth
change.
(allocate_stack, free_stack): Adapt to data type change.
(expand_stack): Don't try to mremap(), as you can't grow a mapping
from the bottom. Without knowing that there's a free mapping space
right below the old stack, which there usually isn't on Linux, we have
to copy. We can't use MAP_GROWSDOWN because Linux is buggy.
(make_vm): Adapt to stack representation changes.
(return_unused_stack_to_os): Round down instead of up, as the stack
grows down.
(scm_i_vm_mark_stack): Adapt to walk up the stack.
(scm_i_vm_free_stack): Adapt to scm_vm changes.
(vm_expand_stack_inner, reset_stack_limit, vm_expand_stack): Adapt to
the stack growing down.
(scm_call_n): Adapt to the stack growing down. Don't allow argv to
point into the stack.
* libguile/vm.h (struct scm_vm, struct scm_vm_cont): Adapt to hold the
stack top and bottom.
2015-09-22 10:24:30 +00:00
|
|
|
|
size *= sizeof (*stack);
|
2013-11-22 14:41:19 +01:00
|
|
|
|
|
|
|
|
|
|
#if HAVE_SYS_MMAN_H
|
|
|
|
|
|
munmap (stack, size);
|
|
|
|
|
|
#else
|
|
|
|
|
|
free (stack);
|
|
|
|
|
|
#endif
|
|
|
|
|
|
}
|
|
|
|
|
|
|
VM stack grows downward
Adapt VM stack to grow downward. This will make native compilation look
more like the VM code, as we will be able to use native CALL
instructions, taking proper advantage of the return address buffer.
* libguile/continuations.c (scm_i_continuation_to_frame): Record offsets
from stack top.
* libguile/control.c (scm_i_prompt_pop_abort_args_x): Adapt for reversed
order of arguments, and instead of relying on the abort to push on the
number of arguments, make the caller save the stack depth, which
allows us to compute the number of arguments ourselves.
(reify_partial_continuation, scm_c_abort): Adapt to reversed stack
order.
* libguile/dynstack.c (scm_dynstack_wind_prompt): Since we wind the
stack in a downward direction, subtract the reloc instead of adding
it.
* libguile/dynstack.h (SCM_F_DYNSTACK_PROMPT_ESCAPE_ONLY): Remove flag;
instead rely on prompt-establishing code to save the stack depth.
* libguile/eval.c (eval): Remove extraneous "volatile" declarations for
variables that are not re-set between the setjmp and any longjmp.
Adapt to save stack depth before instating the prompt.
* libguile/foreign.c (scm_i_foreign_call): Adapt to receive arguments in
reverse order.
* libguile/frames.c (frame_stack_top, scm_i_frame_stack_top): Adapt to
compute stack top instead of stack bottom.
(scm_c_frame_closure): Adapt to stack growth change.
(scm_frame_num_locals, scm_frame_local_ref, scm_frame_set_x): Use
union data type to access stack.
(RELOC): Reformat.
(scm_c_frame_previous): Adapt to stack growth change.
* libguile/frames.h: Adapt stack diagram to indicate that the stack
grows up.
(union scm_vm_stack_element): New data type used to access items on
the stack.
(SCM_FRAME_PREVIOUS_SP)
(SCM_FRAME_RETURN_ADDRESS, SCM_FRAME_SET_RETURN_ADDRESS)
(SCM_FRAME_DYNAMIC_LINK, SCM_FRAME_SET_DYNAMIC_LINK)
(SCM_FRAME_LOCAL, SCM_FRAME_NUM_LOCALS): Adapt to stack representation
change.
(SCM_FRAME_SLOT): New helper.
(SCM_VM_FRAME_FP, SCM_VM_FRAME_SP): Adapt to stack growth change.
* libguile/stacks.c (scm_make_stack): Record offsets from top of stack.
* libguile/throw.c (catch): Adapt to scm_i_prompt_pop_abort_args_x
change.
* libguile/vm-engine.c (ALLOC_FRAME, RESET_FRAME):
(FRAME_LOCALS_COUNT_FROM): Adapt to stack growth change.
(LOCAL_ADDRESS): Use SCM_FRAME_SLOT to get the address as the proper
data type.
(RETURN_ONE_VALUE, RETURN_VALUE_LIST): Adapt to stack growth change.
(apply): Shuffling up the SMOB apply args can cause the stack to
expand, so use ALLOC_FRAME instead of RESET_FRAME.
(vm_engine): Adapt for stack growth change.
* libguile/vm.c (vm_increase_sp, vm_push_sp, vm_restore_sp): Adapt to
stack representation change.
(scm_i_vm_cont_to_frame): Adapt to take offsets from the top.
(scm_i_vm_capture_stack): Adapt to capture from the top.
(vm_return_to_continuation_inner): Adapt for data type changes.
(vm_return_to_continuation): Likewise, and instead of looping, just
splat the saved arguments on with memcpy.
(vm_dispatch_hook): Adapt to receive arguments in the reverse order.
Adapt callers.
(vm_abort): There is never a tail argument. Adapt to stack
representation change.
(vm_reinstate_partial_continuation)
(vm_reinstate_partial_continuation_inner): Adapt to stack growth
change.
(allocate_stack, free_stack): Adapt to data type change.
(expand_stack): Don't try to mremap(), as you can't grow a mapping
from the bottom. Without knowing that there's a free mapping space
right below the old stack, which there usually isn't on Linux, we have
to copy. We can't use MAP_GROWSDOWN because Linux is buggy.
(make_vm): Adapt to stack representation changes.
(return_unused_stack_to_os): Round down instead of up, as the stack
grows down.
(scm_i_vm_mark_stack): Adapt to walk up the stack.
(scm_i_vm_free_stack): Adapt to scm_vm changes.
(vm_expand_stack_inner, reset_stack_limit, vm_expand_stack): Adapt to
the stack growing down.
(scm_call_n): Adapt to the stack growing down. Don't allow argv to
point into the stack.
* libguile/vm.h (struct scm_vm, struct scm_vm_cont): Adapt to hold the
stack top and bottom.
2015-09-22 10:24:30 +00:00
|
|
|
|
/* Ideally what we would like is an mremap or a realloc that grows at
|
|
|
|
|
|
the bottom, not the top. Oh well; mmap and memcpy are fast enough,
|
|
|
|
|
|
considering that they run very infrequently. */
|
|
|
|
|
|
static union scm_vm_stack_element*
|
|
|
|
|
|
expand_stack (union scm_vm_stack_element *old_bottom, size_t old_size,
|
|
|
|
|
|
size_t new_size)
|
2013-11-22 17:31:07 +01:00
|
|
|
|
#define FUNC_NAME "expand_stack"
|
|
|
|
|
|
{
|
VM stack grows downward
Adapt VM stack to grow downward. This will make native compilation look
more like the VM code, as we will be able to use native CALL
instructions, taking proper advantage of the return address buffer.
* libguile/continuations.c (scm_i_continuation_to_frame): Record offsets
from stack top.
* libguile/control.c (scm_i_prompt_pop_abort_args_x): Adapt for reversed
order of arguments, and instead of relying on the abort to push on the
number of arguments, make the caller save the stack depth, which
allows us to compute the number of arguments ourselves.
(reify_partial_continuation, scm_c_abort): Adapt to reversed stack
order.
* libguile/dynstack.c (scm_dynstack_wind_prompt): Since we wind the
stack in a downward direction, subtract the reloc instead of adding
it.
* libguile/dynstack.h (SCM_F_DYNSTACK_PROMPT_ESCAPE_ONLY): Remove flag;
instead rely on prompt-establishing code to save the stack depth.
* libguile/eval.c (eval): Remove extraneous "volatile" declarations for
variables that are not re-set between the setjmp and any longjmp.
Adapt to save stack depth before instating the prompt.
* libguile/foreign.c (scm_i_foreign_call): Adapt to receive arguments in
reverse order.
* libguile/frames.c (frame_stack_top, scm_i_frame_stack_top): Adapt to
compute stack top instead of stack bottom.
(scm_c_frame_closure): Adapt to stack growth change.
(scm_frame_num_locals, scm_frame_local_ref, scm_frame_set_x): Use
union data type to access stack.
(RELOC): Reformat.
(scm_c_frame_previous): Adapt to stack growth change.
* libguile/frames.h: Adapt stack diagram to indicate that the stack
grows up.
(union scm_vm_stack_element): New data type used to access items on
the stack.
(SCM_FRAME_PREVIOUS_SP)
(SCM_FRAME_RETURN_ADDRESS, SCM_FRAME_SET_RETURN_ADDRESS)
(SCM_FRAME_DYNAMIC_LINK, SCM_FRAME_SET_DYNAMIC_LINK)
(SCM_FRAME_LOCAL, SCM_FRAME_NUM_LOCALS): Adapt to stack representation
change.
(SCM_FRAME_SLOT): New helper.
(SCM_VM_FRAME_FP, SCM_VM_FRAME_SP): Adapt to stack growth change.
* libguile/stacks.c (scm_make_stack): Record offsets from top of stack.
* libguile/throw.c (catch): Adapt to scm_i_prompt_pop_abort_args_x
change.
* libguile/vm-engine.c (ALLOC_FRAME, RESET_FRAME):
(FRAME_LOCALS_COUNT_FROM): Adapt to stack growth change.
(LOCAL_ADDRESS): Use SCM_FRAME_SLOT to get the address as the proper
data type.
(RETURN_ONE_VALUE, RETURN_VALUE_LIST): Adapt to stack growth change.
(apply): Shuffling up the SMOB apply args can cause the stack to
expand, so use ALLOC_FRAME instead of RESET_FRAME.
(vm_engine): Adapt for stack growth change.
* libguile/vm.c (vm_increase_sp, vm_push_sp, vm_restore_sp): Adapt to
stack representation change.
(scm_i_vm_cont_to_frame): Adapt to take offsets from the top.
(scm_i_vm_capture_stack): Adapt to capture from the top.
(vm_return_to_continuation_inner): Adapt for data type changes.
(vm_return_to_continuation): Likewise, and instead of looping, just
splat the saved arguments on with memcpy.
(vm_dispatch_hook): Adapt to receive arguments in the reverse order.
Adapt callers.
(vm_abort): There is never a tail argument. Adapt to stack
representation change.
(vm_reinstate_partial_continuation)
(vm_reinstate_partial_continuation_inner): Adapt to stack growth
change.
(allocate_stack, free_stack): Adapt to data type change.
(expand_stack): Don't try to mremap(), as you can't grow a mapping
from the bottom. Without knowing that there's a free mapping space
right below the old stack, which there usually isn't on Linux, we have
to copy. We can't use MAP_GROWSDOWN because Linux is buggy.
(make_vm): Adapt to stack representation changes.
(return_unused_stack_to_os): Round down instead of up, as the stack
grows down.
(scm_i_vm_mark_stack): Adapt to walk up the stack.
(scm_i_vm_free_stack): Adapt to scm_vm changes.
(vm_expand_stack_inner, reset_stack_limit, vm_expand_stack): Adapt to
the stack growing down.
(scm_call_n): Adapt to the stack growing down. Don't allow argv to
point into the stack.
* libguile/vm.h (struct scm_vm, struct scm_vm_cont): Adapt to hold the
stack top and bottom.
2015-09-22 10:24:30 +00:00
|
|
|
|
union scm_vm_stack_element *new_bottom;
|
|
|
|
|
|
size_t extension_size;
|
2013-11-22 17:31:07 +01:00
|
|
|
|
|
VM stack grows downward
Adapt VM stack to grow downward. This will make native compilation look
more like the VM code, as we will be able to use native CALL
instructions, taking proper advantage of the return address buffer.
* libguile/continuations.c (scm_i_continuation_to_frame): Record offsets
from stack top.
* libguile/control.c (scm_i_prompt_pop_abort_args_x): Adapt for reversed
order of arguments, and instead of relying on the abort to push on the
number of arguments, make the caller save the stack depth, which
allows us to compute the number of arguments ourselves.
(reify_partial_continuation, scm_c_abort): Adapt to reversed stack
order.
* libguile/dynstack.c (scm_dynstack_wind_prompt): Since we wind the
stack in a downward direction, subtract the reloc instead of adding
it.
* libguile/dynstack.h (SCM_F_DYNSTACK_PROMPT_ESCAPE_ONLY): Remove flag;
instead rely on prompt-establishing code to save the stack depth.
* libguile/eval.c (eval): Remove extraneous "volatile" declarations for
variables that are not re-set between the setjmp and any longjmp.
Adapt to save stack depth before instating the prompt.
* libguile/foreign.c (scm_i_foreign_call): Adapt to receive arguments in
reverse order.
* libguile/frames.c (frame_stack_top, scm_i_frame_stack_top): Adapt to
compute stack top instead of stack bottom.
(scm_c_frame_closure): Adapt to stack growth change.
(scm_frame_num_locals, scm_frame_local_ref, scm_frame_set_x): Use
union data type to access stack.
(RELOC): Reformat.
(scm_c_frame_previous): Adapt to stack growth change.
* libguile/frames.h: Adapt stack diagram to indicate that the stack
grows up.
(union scm_vm_stack_element): New data type used to access items on
the stack.
(SCM_FRAME_PREVIOUS_SP)
(SCM_FRAME_RETURN_ADDRESS, SCM_FRAME_SET_RETURN_ADDRESS)
(SCM_FRAME_DYNAMIC_LINK, SCM_FRAME_SET_DYNAMIC_LINK)
(SCM_FRAME_LOCAL, SCM_FRAME_NUM_LOCALS): Adapt to stack representation
change.
(SCM_FRAME_SLOT): New helper.
(SCM_VM_FRAME_FP, SCM_VM_FRAME_SP): Adapt to stack growth change.
* libguile/stacks.c (scm_make_stack): Record offsets from top of stack.
* libguile/throw.c (catch): Adapt to scm_i_prompt_pop_abort_args_x
change.
* libguile/vm-engine.c (ALLOC_FRAME, RESET_FRAME):
(FRAME_LOCALS_COUNT_FROM): Adapt to stack growth change.
(LOCAL_ADDRESS): Use SCM_FRAME_SLOT to get the address as the proper
data type.
(RETURN_ONE_VALUE, RETURN_VALUE_LIST): Adapt to stack growth change.
(apply): Shuffling up the SMOB apply args can cause the stack to
expand, so use ALLOC_FRAME instead of RESET_FRAME.
(vm_engine): Adapt for stack growth change.
* libguile/vm.c (vm_increase_sp, vm_push_sp, vm_restore_sp): Adapt to
stack representation change.
(scm_i_vm_cont_to_frame): Adapt to take offsets from the top.
(scm_i_vm_capture_stack): Adapt to capture from the top.
(vm_return_to_continuation_inner): Adapt for data type changes.
(vm_return_to_continuation): Likewise, and instead of looping, just
splat the saved arguments on with memcpy.
(vm_dispatch_hook): Adapt to receive arguments in the reverse order.
Adapt callers.
(vm_abort): There is never a tail argument. Adapt to stack
representation change.
(vm_reinstate_partial_continuation)
(vm_reinstate_partial_continuation_inner): Adapt to stack growth
change.
(allocate_stack, free_stack): Adapt to data type change.
(expand_stack): Don't try to mremap(), as you can't grow a mapping
from the bottom. Without knowing that there's a free mapping space
right below the old stack, which there usually isn't on Linux, we have
to copy. We can't use MAP_GROWSDOWN because Linux is buggy.
(make_vm): Adapt to stack representation changes.
(return_unused_stack_to_os): Round down instead of up, as the stack
grows down.
(scm_i_vm_mark_stack): Adapt to walk up the stack.
(scm_i_vm_free_stack): Adapt to scm_vm changes.
(vm_expand_stack_inner, reset_stack_limit, vm_expand_stack): Adapt to
the stack growing down.
(scm_call_n): Adapt to the stack growing down. Don't allow argv to
point into the stack.
* libguile/vm.h (struct scm_vm, struct scm_vm_cont): Adapt to hold the
stack top and bottom.
2015-09-22 10:24:30 +00:00
|
|
|
|
if (new_size >= ((size_t) -1) / sizeof (union scm_vm_stack_element))
|
|
|
|
|
|
abort ();
|
|
|
|
|
|
if (new_size <= old_size)
|
2013-11-22 17:31:07 +01:00
|
|
|
|
abort ();
|
|
|
|
|
|
|
VM stack grows downward
Adapt VM stack to grow downward. This will make native compilation look
more like the VM code, as we will be able to use native CALL
instructions, taking proper advantage of the return address buffer.
* libguile/continuations.c (scm_i_continuation_to_frame): Record offsets
from stack top.
* libguile/control.c (scm_i_prompt_pop_abort_args_x): Adapt for reversed
order of arguments, and instead of relying on the abort to push on the
number of arguments, make the caller save the stack depth, which
allows us to compute the number of arguments ourselves.
(reify_partial_continuation, scm_c_abort): Adapt to reversed stack
order.
* libguile/dynstack.c (scm_dynstack_wind_prompt): Since we wind the
stack in a downward direction, subtract the reloc instead of adding
it.
* libguile/dynstack.h (SCM_F_DYNSTACK_PROMPT_ESCAPE_ONLY): Remove flag;
instead rely on prompt-establishing code to save the stack depth.
* libguile/eval.c (eval): Remove extraneous "volatile" declarations for
variables that are not re-set between the setjmp and any longjmp.
Adapt to save stack depth before instating the prompt.
* libguile/foreign.c (scm_i_foreign_call): Adapt to receive arguments in
reverse order.
* libguile/frames.c (frame_stack_top, scm_i_frame_stack_top): Adapt to
compute stack top instead of stack bottom.
(scm_c_frame_closure): Adapt to stack growth change.
(scm_frame_num_locals, scm_frame_local_ref, scm_frame_set_x): Use
union data type to access stack.
(RELOC): Reformat.
(scm_c_frame_previous): Adapt to stack growth change.
* libguile/frames.h: Adapt stack diagram to indicate that the stack
grows up.
(union scm_vm_stack_element): New data type used to access items on
the stack.
(SCM_FRAME_PREVIOUS_SP)
(SCM_FRAME_RETURN_ADDRESS, SCM_FRAME_SET_RETURN_ADDRESS)
(SCM_FRAME_DYNAMIC_LINK, SCM_FRAME_SET_DYNAMIC_LINK)
(SCM_FRAME_LOCAL, SCM_FRAME_NUM_LOCALS): Adapt to stack representation
change.
(SCM_FRAME_SLOT): New helper.
(SCM_VM_FRAME_FP, SCM_VM_FRAME_SP): Adapt to stack growth change.
* libguile/stacks.c (scm_make_stack): Record offsets from top of stack.
* libguile/throw.c (catch): Adapt to scm_i_prompt_pop_abort_args_x
change.
* libguile/vm-engine.c (ALLOC_FRAME, RESET_FRAME):
(FRAME_LOCALS_COUNT_FROM): Adapt to stack growth change.
(LOCAL_ADDRESS): Use SCM_FRAME_SLOT to get the address as the proper
data type.
(RETURN_ONE_VALUE, RETURN_VALUE_LIST): Adapt to stack growth change.
(apply): Shuffling up the SMOB apply args can cause the stack to
expand, so use ALLOC_FRAME instead of RESET_FRAME.
(vm_engine): Adapt for stack growth change.
* libguile/vm.c (vm_increase_sp, vm_push_sp, vm_restore_sp): Adapt to
stack representation change.
(scm_i_vm_cont_to_frame): Adapt to take offsets from the top.
(scm_i_vm_capture_stack): Adapt to capture from the top.
(vm_return_to_continuation_inner): Adapt for data type changes.
(vm_return_to_continuation): Likewise, and instead of looping, just
splat the saved arguments on with memcpy.
(vm_dispatch_hook): Adapt to receive arguments in the reverse order.
Adapt callers.
(vm_abort): There is never a tail argument. Adapt to stack
representation change.
(vm_reinstate_partial_continuation)
(vm_reinstate_partial_continuation_inner): Adapt to stack growth
change.
(allocate_stack, free_stack): Adapt to data type change.
(expand_stack): Don't try to mremap(), as you can't grow a mapping
from the bottom. Without knowing that there's a free mapping space
right below the old stack, which there usually isn't on Linux, we have
to copy. We can't use MAP_GROWSDOWN because Linux is buggy.
(make_vm): Adapt to stack representation changes.
(return_unused_stack_to_os): Round down instead of up, as the stack
grows down.
(scm_i_vm_mark_stack): Adapt to walk up the stack.
(scm_i_vm_free_stack): Adapt to scm_vm changes.
(vm_expand_stack_inner, reset_stack_limit, vm_expand_stack): Adapt to
the stack growing down.
(scm_call_n): Adapt to the stack growing down. Don't allow argv to
point into the stack.
* libguile/vm.h (struct scm_vm, struct scm_vm_cont): Adapt to hold the
stack top and bottom.
2015-09-22 10:24:30 +00:00
|
|
|
|
extension_size = new_size - old_size;
|
2013-11-22 17:31:07 +01:00
|
|
|
|
|
VM stack grows downward
Adapt VM stack to grow downward. This will make native compilation look
more like the VM code, as we will be able to use native CALL
instructions, taking proper advantage of the return address buffer.
* libguile/continuations.c (scm_i_continuation_to_frame): Record offsets
from stack top.
* libguile/control.c (scm_i_prompt_pop_abort_args_x): Adapt for reversed
order of arguments, and instead of relying on the abort to push on the
number of arguments, make the caller save the stack depth, which
allows us to compute the number of arguments ourselves.
(reify_partial_continuation, scm_c_abort): Adapt to reversed stack
order.
* libguile/dynstack.c (scm_dynstack_wind_prompt): Since we wind the
stack in a downward direction, subtract the reloc instead of adding
it.
* libguile/dynstack.h (SCM_F_DYNSTACK_PROMPT_ESCAPE_ONLY): Remove flag;
instead rely on prompt-establishing code to save the stack depth.
* libguile/eval.c (eval): Remove extraneous "volatile" declarations for
variables that are not re-set between the setjmp and any longjmp.
Adapt to save stack depth before instating the prompt.
* libguile/foreign.c (scm_i_foreign_call): Adapt to receive arguments in
reverse order.
* libguile/frames.c (frame_stack_top, scm_i_frame_stack_top): Adapt to
compute stack top instead of stack bottom.
(scm_c_frame_closure): Adapt to stack growth change.
(scm_frame_num_locals, scm_frame_local_ref, scm_frame_set_x): Use
union data type to access stack.
(RELOC): Reformat.
(scm_c_frame_previous): Adapt to stack growth change.
* libguile/frames.h: Adapt stack diagram to indicate that the stack
grows up.
(union scm_vm_stack_element): New data type used to access items on
the stack.
(SCM_FRAME_PREVIOUS_SP)
(SCM_FRAME_RETURN_ADDRESS, SCM_FRAME_SET_RETURN_ADDRESS)
(SCM_FRAME_DYNAMIC_LINK, SCM_FRAME_SET_DYNAMIC_LINK)
(SCM_FRAME_LOCAL, SCM_FRAME_NUM_LOCALS): Adapt to stack representation
change.
(SCM_FRAME_SLOT): New helper.
(SCM_VM_FRAME_FP, SCM_VM_FRAME_SP): Adapt to stack growth change.
* libguile/stacks.c (scm_make_stack): Record offsets from top of stack.
* libguile/throw.c (catch): Adapt to scm_i_prompt_pop_abort_args_x
change.
* libguile/vm-engine.c (ALLOC_FRAME, RESET_FRAME):
(FRAME_LOCALS_COUNT_FROM): Adapt to stack growth change.
(LOCAL_ADDRESS): Use SCM_FRAME_SLOT to get the address as the proper
data type.
(RETURN_ONE_VALUE, RETURN_VALUE_LIST): Adapt to stack growth change.
(apply): Shuffling up the SMOB apply args can cause the stack to
expand, so use ALLOC_FRAME instead of RESET_FRAME.
(vm_engine): Adapt for stack growth change.
* libguile/vm.c (vm_increase_sp, vm_push_sp, vm_restore_sp): Adapt to
stack representation change.
(scm_i_vm_cont_to_frame): Adapt to take offsets from the top.
(scm_i_vm_capture_stack): Adapt to capture from the top.
(vm_return_to_continuation_inner): Adapt for data type changes.
(vm_return_to_continuation): Likewise, and instead of looping, just
splat the saved arguments on with memcpy.
(vm_dispatch_hook): Adapt to receive arguments in the reverse order.
Adapt callers.
(vm_abort): There is never a tail argument. Adapt to stack
representation change.
(vm_reinstate_partial_continuation)
(vm_reinstate_partial_continuation_inner): Adapt to stack growth
change.
(allocate_stack, free_stack): Adapt to data type change.
(expand_stack): Don't try to mremap(), as you can't grow a mapping
from the bottom. Without knowing that there's a free mapping space
right below the old stack, which there usually isn't on Linux, we have
to copy. We can't use MAP_GROWSDOWN because Linux is buggy.
(make_vm): Adapt to stack representation changes.
(return_unused_stack_to_os): Round down instead of up, as the stack
grows down.
(scm_i_vm_mark_stack): Adapt to walk up the stack.
(scm_i_vm_free_stack): Adapt to scm_vm changes.
(vm_expand_stack_inner, reset_stack_limit, vm_expand_stack): Adapt to
the stack growing down.
(scm_call_n): Adapt to the stack growing down. Don't allow argv to
point into the stack.
* libguile/vm.h (struct scm_vm, struct scm_vm_cont): Adapt to hold the
stack top and bottom.
2015-09-22 10:24:30 +00:00
|
|
|
|
if ((size_t)old_bottom < extension_size * sizeof (union scm_vm_stack_element))
|
|
|
|
|
|
abort ();
|
2013-11-22 17:31:07 +01:00
|
|
|
|
|
VM stack grows downward
Adapt VM stack to grow downward. This will make native compilation look
more like the VM code, as we will be able to use native CALL
instructions, taking proper advantage of the return address buffer.
* libguile/continuations.c (scm_i_continuation_to_frame): Record offsets
from stack top.
* libguile/control.c (scm_i_prompt_pop_abort_args_x): Adapt for reversed
order of arguments, and instead of relying on the abort to push on the
number of arguments, make the caller save the stack depth, which
allows us to compute the number of arguments ourselves.
(reify_partial_continuation, scm_c_abort): Adapt to reversed stack
order.
* libguile/dynstack.c (scm_dynstack_wind_prompt): Since we wind the
stack in a downward direction, subtract the reloc instead of adding
it.
* libguile/dynstack.h (SCM_F_DYNSTACK_PROMPT_ESCAPE_ONLY): Remove flag;
instead rely on prompt-establishing code to save the stack depth.
* libguile/eval.c (eval): Remove extraneous "volatile" declarations for
variables that are not re-set between the setjmp and any longjmp.
Adapt to save stack depth before instating the prompt.
* libguile/foreign.c (scm_i_foreign_call): Adapt to receive arguments in
reverse order.
* libguile/frames.c (frame_stack_top, scm_i_frame_stack_top): Adapt to
compute stack top instead of stack bottom.
(scm_c_frame_closure): Adapt to stack growth change.
(scm_frame_num_locals, scm_frame_local_ref, scm_frame_set_x): Use
union data type to access stack.
(RELOC): Reformat.
(scm_c_frame_previous): Adapt to stack growth change.
* libguile/frames.h: Adapt stack diagram to indicate that the stack
grows up.
(union scm_vm_stack_element): New data type used to access items on
the stack.
(SCM_FRAME_PREVIOUS_SP)
(SCM_FRAME_RETURN_ADDRESS, SCM_FRAME_SET_RETURN_ADDRESS)
(SCM_FRAME_DYNAMIC_LINK, SCM_FRAME_SET_DYNAMIC_LINK)
(SCM_FRAME_LOCAL, SCM_FRAME_NUM_LOCALS): Adapt to stack representation
change.
(SCM_FRAME_SLOT): New helper.
(SCM_VM_FRAME_FP, SCM_VM_FRAME_SP): Adapt to stack growth change.
* libguile/stacks.c (scm_make_stack): Record offsets from top of stack.
* libguile/throw.c (catch): Adapt to scm_i_prompt_pop_abort_args_x
change.
* libguile/vm-engine.c (ALLOC_FRAME, RESET_FRAME):
(FRAME_LOCALS_COUNT_FROM): Adapt to stack growth change.
(LOCAL_ADDRESS): Use SCM_FRAME_SLOT to get the address as the proper
data type.
(RETURN_ONE_VALUE, RETURN_VALUE_LIST): Adapt to stack growth change.
(apply): Shuffling up the SMOB apply args can cause the stack to
expand, so use ALLOC_FRAME instead of RESET_FRAME.
(vm_engine): Adapt for stack growth change.
* libguile/vm.c (vm_increase_sp, vm_push_sp, vm_restore_sp): Adapt to
stack representation change.
(scm_i_vm_cont_to_frame): Adapt to take offsets from the top.
(scm_i_vm_capture_stack): Adapt to capture from the top.
(vm_return_to_continuation_inner): Adapt for data type changes.
(vm_return_to_continuation): Likewise, and instead of looping, just
splat the saved arguments on with memcpy.
(vm_dispatch_hook): Adapt to receive arguments in the reverse order.
Adapt callers.
(vm_abort): There is never a tail argument. Adapt to stack
representation change.
(vm_reinstate_partial_continuation)
(vm_reinstate_partial_continuation_inner): Adapt to stack growth
change.
(allocate_stack, free_stack): Adapt to data type change.
(expand_stack): Don't try to mremap(), as you can't grow a mapping
from the bottom. Without knowing that there's a free mapping space
right below the old stack, which there usually isn't on Linux, we have
to copy. We can't use MAP_GROWSDOWN because Linux is buggy.
(make_vm): Adapt to stack representation changes.
(return_unused_stack_to_os): Round down instead of up, as the stack
grows down.
(scm_i_vm_mark_stack): Adapt to walk up the stack.
(scm_i_vm_free_stack): Adapt to scm_vm changes.
(vm_expand_stack_inner, reset_stack_limit, vm_expand_stack): Adapt to
the stack growing down.
(scm_call_n): Adapt to the stack growing down. Don't allow argv to
point into the stack.
* libguile/vm.h (struct scm_vm, struct scm_vm_cont): Adapt to hold the
stack top and bottom.
2015-09-22 10:24:30 +00:00
|
|
|
|
new_bottom = allocate_stack (new_size);
|
2013-11-22 17:31:07 +01:00
|
|
|
|
|
VM stack grows downward
Adapt VM stack to grow downward. This will make native compilation look
more like the VM code, as we will be able to use native CALL
instructions, taking proper advantage of the return address buffer.
* libguile/continuations.c (scm_i_continuation_to_frame): Record offsets
from stack top.
* libguile/control.c (scm_i_prompt_pop_abort_args_x): Adapt for reversed
order of arguments, and instead of relying on the abort to push on the
number of arguments, make the caller save the stack depth, which
allows us to compute the number of arguments ourselves.
(reify_partial_continuation, scm_c_abort): Adapt to reversed stack
order.
* libguile/dynstack.c (scm_dynstack_wind_prompt): Since we wind the
stack in a downward direction, subtract the reloc instead of adding
it.
* libguile/dynstack.h (SCM_F_DYNSTACK_PROMPT_ESCAPE_ONLY): Remove flag;
instead rely on prompt-establishing code to save the stack depth.
* libguile/eval.c (eval): Remove extraneous "volatile" declarations for
variables that are not re-set between the setjmp and any longjmp.
Adapt to save stack depth before instating the prompt.
* libguile/foreign.c (scm_i_foreign_call): Adapt to receive arguments in
reverse order.
* libguile/frames.c (frame_stack_top, scm_i_frame_stack_top): Adapt to
compute stack top instead of stack bottom.
(scm_c_frame_closure): Adapt to stack growth change.
(scm_frame_num_locals, scm_frame_local_ref, scm_frame_set_x): Use
union data type to access stack.
(RELOC): Reformat.
(scm_c_frame_previous): Adapt to stack growth change.
* libguile/frames.h: Adapt stack diagram to indicate that the stack
grows up.
(union scm_vm_stack_element): New data type used to access items on
the stack.
(SCM_FRAME_PREVIOUS_SP)
(SCM_FRAME_RETURN_ADDRESS, SCM_FRAME_SET_RETURN_ADDRESS)
(SCM_FRAME_DYNAMIC_LINK, SCM_FRAME_SET_DYNAMIC_LINK)
(SCM_FRAME_LOCAL, SCM_FRAME_NUM_LOCALS): Adapt to stack representation
change.
(SCM_FRAME_SLOT): New helper.
(SCM_VM_FRAME_FP, SCM_VM_FRAME_SP): Adapt to stack growth change.
* libguile/stacks.c (scm_make_stack): Record offsets from top of stack.
* libguile/throw.c (catch): Adapt to scm_i_prompt_pop_abort_args_x
change.
* libguile/vm-engine.c (ALLOC_FRAME, RESET_FRAME):
(FRAME_LOCALS_COUNT_FROM): Adapt to stack growth change.
(LOCAL_ADDRESS): Use SCM_FRAME_SLOT to get the address as the proper
data type.
(RETURN_ONE_VALUE, RETURN_VALUE_LIST): Adapt to stack growth change.
(apply): Shuffling up the SMOB apply args can cause the stack to
expand, so use ALLOC_FRAME instead of RESET_FRAME.
(vm_engine): Adapt for stack growth change.
* libguile/vm.c (vm_increase_sp, vm_push_sp, vm_restore_sp): Adapt to
stack representation change.
(scm_i_vm_cont_to_frame): Adapt to take offsets from the top.
(scm_i_vm_capture_stack): Adapt to capture from the top.
(vm_return_to_continuation_inner): Adapt for data type changes.
(vm_return_to_continuation): Likewise, and instead of looping, just
splat the saved arguments on with memcpy.
(vm_dispatch_hook): Adapt to receive arguments in the reverse order.
Adapt callers.
(vm_abort): There is never a tail argument. Adapt to stack
representation change.
(vm_reinstate_partial_continuation)
(vm_reinstate_partial_continuation_inner): Adapt to stack growth
change.
(allocate_stack, free_stack): Adapt to data type change.
(expand_stack): Don't try to mremap(), as you can't grow a mapping
from the bottom. Without knowing that there's a free mapping space
right below the old stack, which there usually isn't on Linux, we have
to copy. We can't use MAP_GROWSDOWN because Linux is buggy.
(make_vm): Adapt to stack representation changes.
(return_unused_stack_to_os): Round down instead of up, as the stack
grows down.
(scm_i_vm_mark_stack): Adapt to walk up the stack.
(scm_i_vm_free_stack): Adapt to scm_vm changes.
(vm_expand_stack_inner, reset_stack_limit, vm_expand_stack): Adapt to
the stack growing down.
(scm_call_n): Adapt to the stack growing down. Don't allow argv to
point into the stack.
* libguile/vm.h (struct scm_vm, struct scm_vm_cont): Adapt to hold the
stack top and bottom.
2015-09-22 10:24:30 +00:00
|
|
|
|
if (!new_bottom)
|
2014-02-19 11:01:39 +01:00
|
|
|
|
return NULL;
|
|
|
|
|
|
|
VM stack grows downward
Adapt VM stack to grow downward. This will make native compilation look
more like the VM code, as we will be able to use native CALL
instructions, taking proper advantage of the return address buffer.
* libguile/continuations.c (scm_i_continuation_to_frame): Record offsets
from stack top.
* libguile/control.c (scm_i_prompt_pop_abort_args_x): Adapt for reversed
order of arguments, and instead of relying on the abort to push on the
number of arguments, make the caller save the stack depth, which
allows us to compute the number of arguments ourselves.
(reify_partial_continuation, scm_c_abort): Adapt to reversed stack
order.
* libguile/dynstack.c (scm_dynstack_wind_prompt): Since we wind the
stack in a downward direction, subtract the reloc instead of adding
it.
* libguile/dynstack.h (SCM_F_DYNSTACK_PROMPT_ESCAPE_ONLY): Remove flag;
instead rely on prompt-establishing code to save the stack depth.
* libguile/eval.c (eval): Remove extraneous "volatile" declarations for
variables that are not re-set between the setjmp and any longjmp.
Adapt to save stack depth before instating the prompt.
* libguile/foreign.c (scm_i_foreign_call): Adapt to receive arguments in
reverse order.
* libguile/frames.c (frame_stack_top, scm_i_frame_stack_top): Adapt to
compute stack top instead of stack bottom.
(scm_c_frame_closure): Adapt to stack growth change.
(scm_frame_num_locals, scm_frame_local_ref, scm_frame_set_x): Use
union data type to access stack.
(RELOC): Reformat.
(scm_c_frame_previous): Adapt to stack growth change.
* libguile/frames.h: Adapt stack diagram to indicate that the stack
grows up.
(union scm_vm_stack_element): New data type used to access items on
the stack.
(SCM_FRAME_PREVIOUS_SP)
(SCM_FRAME_RETURN_ADDRESS, SCM_FRAME_SET_RETURN_ADDRESS)
(SCM_FRAME_DYNAMIC_LINK, SCM_FRAME_SET_DYNAMIC_LINK)
(SCM_FRAME_LOCAL, SCM_FRAME_NUM_LOCALS): Adapt to stack representation
change.
(SCM_FRAME_SLOT): New helper.
(SCM_VM_FRAME_FP, SCM_VM_FRAME_SP): Adapt to stack growth change.
* libguile/stacks.c (scm_make_stack): Record offsets from top of stack.
* libguile/throw.c (catch): Adapt to scm_i_prompt_pop_abort_args_x
change.
* libguile/vm-engine.c (ALLOC_FRAME, RESET_FRAME):
(FRAME_LOCALS_COUNT_FROM): Adapt to stack growth change.
(LOCAL_ADDRESS): Use SCM_FRAME_SLOT to get the address as the proper
data type.
(RETURN_ONE_VALUE, RETURN_VALUE_LIST): Adapt to stack growth change.
(apply): Shuffling up the SMOB apply args can cause the stack to
expand, so use ALLOC_FRAME instead of RESET_FRAME.
(vm_engine): Adapt for stack growth change.
* libguile/vm.c (vm_increase_sp, vm_push_sp, vm_restore_sp): Adapt to
stack representation change.
(scm_i_vm_cont_to_frame): Adapt to take offsets from the top.
(scm_i_vm_capture_stack): Adapt to capture from the top.
(vm_return_to_continuation_inner): Adapt for data type changes.
(vm_return_to_continuation): Likewise, and instead of looping, just
splat the saved arguments on with memcpy.
(vm_dispatch_hook): Adapt to receive arguments in the reverse order.
Adapt callers.
(vm_abort): There is never a tail argument. Adapt to stack
representation change.
(vm_reinstate_partial_continuation)
(vm_reinstate_partial_continuation_inner): Adapt to stack growth
change.
(allocate_stack, free_stack): Adapt to data type change.
(expand_stack): Don't try to mremap(), as you can't grow a mapping
from the bottom. Without knowing that there's a free mapping space
right below the old stack, which there usually isn't on Linux, we have
to copy. We can't use MAP_GROWSDOWN because Linux is buggy.
(make_vm): Adapt to stack representation changes.
(return_unused_stack_to_os): Round down instead of up, as the stack
grows down.
(scm_i_vm_mark_stack): Adapt to walk up the stack.
(scm_i_vm_free_stack): Adapt to scm_vm changes.
(vm_expand_stack_inner, reset_stack_limit, vm_expand_stack): Adapt to
the stack growing down.
(scm_call_n): Adapt to the stack growing down. Don't allow argv to
point into the stack.
* libguile/vm.h (struct scm_vm, struct scm_vm_cont): Adapt to hold the
stack top and bottom.
2015-09-22 10:24:30 +00:00
|
|
|
|
memcpy (new_bottom + extension_size,
|
|
|
|
|
|
old_bottom,
|
|
|
|
|
|
old_size * sizeof (union scm_vm_stack_element));
|
|
|
|
|
|
free_stack (old_bottom, old_size);
|
2013-11-22 17:31:07 +01:00
|
|
|
|
|
VM stack grows downward
Adapt VM stack to grow downward. This will make native compilation look
more like the VM code, as we will be able to use native CALL
instructions, taking proper advantage of the return address buffer.
* libguile/continuations.c (scm_i_continuation_to_frame): Record offsets
from stack top.
* libguile/control.c (scm_i_prompt_pop_abort_args_x): Adapt for reversed
order of arguments, and instead of relying on the abort to push on the
number of arguments, make the caller save the stack depth, which
allows us to compute the number of arguments ourselves.
(reify_partial_continuation, scm_c_abort): Adapt to reversed stack
order.
* libguile/dynstack.c (scm_dynstack_wind_prompt): Since we wind the
stack in a downward direction, subtract the reloc instead of adding
it.
* libguile/dynstack.h (SCM_F_DYNSTACK_PROMPT_ESCAPE_ONLY): Remove flag;
instead rely on prompt-establishing code to save the stack depth.
* libguile/eval.c (eval): Remove extraneous "volatile" declarations for
variables that are not re-set between the setjmp and any longjmp.
Adapt to save stack depth before instating the prompt.
* libguile/foreign.c (scm_i_foreign_call): Adapt to receive arguments in
reverse order.
* libguile/frames.c (frame_stack_top, scm_i_frame_stack_top): Adapt to
compute stack top instead of stack bottom.
(scm_c_frame_closure): Adapt to stack growth change.
(scm_frame_num_locals, scm_frame_local_ref, scm_frame_set_x): Use
union data type to access stack.
(RELOC): Reformat.
(scm_c_frame_previous): Adapt to stack growth change.
* libguile/frames.h: Adapt stack diagram to indicate that the stack
grows up.
(union scm_vm_stack_element): New data type used to access items on
the stack.
(SCM_FRAME_PREVIOUS_SP)
(SCM_FRAME_RETURN_ADDRESS, SCM_FRAME_SET_RETURN_ADDRESS)
(SCM_FRAME_DYNAMIC_LINK, SCM_FRAME_SET_DYNAMIC_LINK)
(SCM_FRAME_LOCAL, SCM_FRAME_NUM_LOCALS): Adapt to stack representation
change.
(SCM_FRAME_SLOT): New helper.
(SCM_VM_FRAME_FP, SCM_VM_FRAME_SP): Adapt to stack growth change.
* libguile/stacks.c (scm_make_stack): Record offsets from top of stack.
* libguile/throw.c (catch): Adapt to scm_i_prompt_pop_abort_args_x
change.
* libguile/vm-engine.c (ALLOC_FRAME, RESET_FRAME):
(FRAME_LOCALS_COUNT_FROM): Adapt to stack growth change.
(LOCAL_ADDRESS): Use SCM_FRAME_SLOT to get the address as the proper
data type.
(RETURN_ONE_VALUE, RETURN_VALUE_LIST): Adapt to stack growth change.
(apply): Shuffling up the SMOB apply args can cause the stack to
expand, so use ALLOC_FRAME instead of RESET_FRAME.
(vm_engine): Adapt for stack growth change.
* libguile/vm.c (vm_increase_sp, vm_push_sp, vm_restore_sp): Adapt to
stack representation change.
(scm_i_vm_cont_to_frame): Adapt to take offsets from the top.
(scm_i_vm_capture_stack): Adapt to capture from the top.
(vm_return_to_continuation_inner): Adapt for data type changes.
(vm_return_to_continuation): Likewise, and instead of looping, just
splat the saved arguments on with memcpy.
(vm_dispatch_hook): Adapt to receive arguments in the reverse order.
Adapt callers.
(vm_abort): There is never a tail argument. Adapt to stack
representation change.
(vm_reinstate_partial_continuation)
(vm_reinstate_partial_continuation_inner): Adapt to stack growth
change.
(allocate_stack, free_stack): Adapt to data type change.
(expand_stack): Don't try to mremap(), as you can't grow a mapping
from the bottom. Without knowing that there's a free mapping space
right below the old stack, which there usually isn't on Linux, we have
to copy. We can't use MAP_GROWSDOWN because Linux is buggy.
(make_vm): Adapt to stack representation changes.
(return_unused_stack_to_os): Round down instead of up, as the stack
grows down.
(scm_i_vm_mark_stack): Adapt to walk up the stack.
(scm_i_vm_free_stack): Adapt to scm_vm changes.
(vm_expand_stack_inner, reset_stack_limit, vm_expand_stack): Adapt to
the stack growing down.
(scm_call_n): Adapt to the stack growing down. Don't allow argv to
point into the stack.
* libguile/vm.h (struct scm_vm, struct scm_vm_cont): Adapt to hold the
stack top and bottom.
2015-09-22 10:24:30 +00:00
|
|
|
|
return new_bottom;
|
2013-11-22 17:31:07 +01:00
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
2018-06-24 09:32:11 +02:00
|
|
|
|
void
|
|
|
|
|
|
scm_i_vm_prepare_stack (struct scm_vm *vp)
|
2000-08-22 15:54:19 +00:00
|
|
|
|
{
|
2018-06-24 09:32:11 +02:00
|
|
|
|
/* Not racey, as this will be run the first time a thread enters
|
|
|
|
|
|
Guile. */
|
|
|
|
|
|
if (page_size == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
page_size = getpagesize ();
|
|
|
|
|
|
/* page_size should be a power of two. */
|
|
|
|
|
|
if (page_size & (page_size - 1))
|
|
|
|
|
|
abort ();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
VM stack grows downward
Adapt VM stack to grow downward. This will make native compilation look
more like the VM code, as we will be able to use native CALL
instructions, taking proper advantage of the return address buffer.
* libguile/continuations.c (scm_i_continuation_to_frame): Record offsets
from stack top.
* libguile/control.c (scm_i_prompt_pop_abort_args_x): Adapt for reversed
order of arguments, and instead of relying on the abort to push on the
number of arguments, make the caller save the stack depth, which
allows us to compute the number of arguments ourselves.
(reify_partial_continuation, scm_c_abort): Adapt to reversed stack
order.
* libguile/dynstack.c (scm_dynstack_wind_prompt): Since we wind the
stack in a downward direction, subtract the reloc instead of adding
it.
* libguile/dynstack.h (SCM_F_DYNSTACK_PROMPT_ESCAPE_ONLY): Remove flag;
instead rely on prompt-establishing code to save the stack depth.
* libguile/eval.c (eval): Remove extraneous "volatile" declarations for
variables that are not re-set between the setjmp and any longjmp.
Adapt to save stack depth before instating the prompt.
* libguile/foreign.c (scm_i_foreign_call): Adapt to receive arguments in
reverse order.
* libguile/frames.c (frame_stack_top, scm_i_frame_stack_top): Adapt to
compute stack top instead of stack bottom.
(scm_c_frame_closure): Adapt to stack growth change.
(scm_frame_num_locals, scm_frame_local_ref, scm_frame_set_x): Use
union data type to access stack.
(RELOC): Reformat.
(scm_c_frame_previous): Adapt to stack growth change.
* libguile/frames.h: Adapt stack diagram to indicate that the stack
grows up.
(union scm_vm_stack_element): New data type used to access items on
the stack.
(SCM_FRAME_PREVIOUS_SP)
(SCM_FRAME_RETURN_ADDRESS, SCM_FRAME_SET_RETURN_ADDRESS)
(SCM_FRAME_DYNAMIC_LINK, SCM_FRAME_SET_DYNAMIC_LINK)
(SCM_FRAME_LOCAL, SCM_FRAME_NUM_LOCALS): Adapt to stack representation
change.
(SCM_FRAME_SLOT): New helper.
(SCM_VM_FRAME_FP, SCM_VM_FRAME_SP): Adapt to stack growth change.
* libguile/stacks.c (scm_make_stack): Record offsets from top of stack.
* libguile/throw.c (catch): Adapt to scm_i_prompt_pop_abort_args_x
change.
* libguile/vm-engine.c (ALLOC_FRAME, RESET_FRAME):
(FRAME_LOCALS_COUNT_FROM): Adapt to stack growth change.
(LOCAL_ADDRESS): Use SCM_FRAME_SLOT to get the address as the proper
data type.
(RETURN_ONE_VALUE, RETURN_VALUE_LIST): Adapt to stack growth change.
(apply): Shuffling up the SMOB apply args can cause the stack to
expand, so use ALLOC_FRAME instead of RESET_FRAME.
(vm_engine): Adapt for stack growth change.
* libguile/vm.c (vm_increase_sp, vm_push_sp, vm_restore_sp): Adapt to
stack representation change.
(scm_i_vm_cont_to_frame): Adapt to take offsets from the top.
(scm_i_vm_capture_stack): Adapt to capture from the top.
(vm_return_to_continuation_inner): Adapt for data type changes.
(vm_return_to_continuation): Likewise, and instead of looping, just
splat the saved arguments on with memcpy.
(vm_dispatch_hook): Adapt to receive arguments in the reverse order.
Adapt callers.
(vm_abort): There is never a tail argument. Adapt to stack
representation change.
(vm_reinstate_partial_continuation)
(vm_reinstate_partial_continuation_inner): Adapt to stack growth
change.
(allocate_stack, free_stack): Adapt to data type change.
(expand_stack): Don't try to mremap(), as you can't grow a mapping
from the bottom. Without knowing that there's a free mapping space
right below the old stack, which there usually isn't on Linux, we have
to copy. We can't use MAP_GROWSDOWN because Linux is buggy.
(make_vm): Adapt to stack representation changes.
(return_unused_stack_to_os): Round down instead of up, as the stack
grows down.
(scm_i_vm_mark_stack): Adapt to walk up the stack.
(scm_i_vm_free_stack): Adapt to scm_vm changes.
(vm_expand_stack_inner, reset_stack_limit, vm_expand_stack): Adapt to
the stack growing down.
(scm_call_n): Adapt to the stack growing down. Don't allow argv to
point into the stack.
* libguile/vm.h (struct scm_vm, struct scm_vm_cont): Adapt to hold the
stack top and bottom.
2015-09-22 10:24:30 +00:00
|
|
|
|
vp->stack_size = page_size / sizeof (union scm_vm_stack_element);
|
|
|
|
|
|
vp->stack_bottom = allocate_stack (vp->stack_size);
|
|
|
|
|
|
if (!vp->stack_bottom)
|
2014-02-19 11:01:39 +01:00
|
|
|
|
/* As in expand_stack, we don't have any way to throw an exception
|
|
|
|
|
|
if we can't allocate one measely page -- there's no stack to
|
|
|
|
|
|
handle it. For now, abort. */
|
|
|
|
|
|
abort ();
|
VM stack grows downward
Adapt VM stack to grow downward. This will make native compilation look
more like the VM code, as we will be able to use native CALL
instructions, taking proper advantage of the return address buffer.
* libguile/continuations.c (scm_i_continuation_to_frame): Record offsets
from stack top.
* libguile/control.c (scm_i_prompt_pop_abort_args_x): Adapt for reversed
order of arguments, and instead of relying on the abort to push on the
number of arguments, make the caller save the stack depth, which
allows us to compute the number of arguments ourselves.
(reify_partial_continuation, scm_c_abort): Adapt to reversed stack
order.
* libguile/dynstack.c (scm_dynstack_wind_prompt): Since we wind the
stack in a downward direction, subtract the reloc instead of adding
it.
* libguile/dynstack.h (SCM_F_DYNSTACK_PROMPT_ESCAPE_ONLY): Remove flag;
instead rely on prompt-establishing code to save the stack depth.
* libguile/eval.c (eval): Remove extraneous "volatile" declarations for
variables that are not re-set between the setjmp and any longjmp.
Adapt to save stack depth before instating the prompt.
* libguile/foreign.c (scm_i_foreign_call): Adapt to receive arguments in
reverse order.
* libguile/frames.c (frame_stack_top, scm_i_frame_stack_top): Adapt to
compute stack top instead of stack bottom.
(scm_c_frame_closure): Adapt to stack growth change.
(scm_frame_num_locals, scm_frame_local_ref, scm_frame_set_x): Use
union data type to access stack.
(RELOC): Reformat.
(scm_c_frame_previous): Adapt to stack growth change.
* libguile/frames.h: Adapt stack diagram to indicate that the stack
grows up.
(union scm_vm_stack_element): New data type used to access items on
the stack.
(SCM_FRAME_PREVIOUS_SP)
(SCM_FRAME_RETURN_ADDRESS, SCM_FRAME_SET_RETURN_ADDRESS)
(SCM_FRAME_DYNAMIC_LINK, SCM_FRAME_SET_DYNAMIC_LINK)
(SCM_FRAME_LOCAL, SCM_FRAME_NUM_LOCALS): Adapt to stack representation
change.
(SCM_FRAME_SLOT): New helper.
(SCM_VM_FRAME_FP, SCM_VM_FRAME_SP): Adapt to stack growth change.
* libguile/stacks.c (scm_make_stack): Record offsets from top of stack.
* libguile/throw.c (catch): Adapt to scm_i_prompt_pop_abort_args_x
change.
* libguile/vm-engine.c (ALLOC_FRAME, RESET_FRAME):
(FRAME_LOCALS_COUNT_FROM): Adapt to stack growth change.
(LOCAL_ADDRESS): Use SCM_FRAME_SLOT to get the address as the proper
data type.
(RETURN_ONE_VALUE, RETURN_VALUE_LIST): Adapt to stack growth change.
(apply): Shuffling up the SMOB apply args can cause the stack to
expand, so use ALLOC_FRAME instead of RESET_FRAME.
(vm_engine): Adapt for stack growth change.
* libguile/vm.c (vm_increase_sp, vm_push_sp, vm_restore_sp): Adapt to
stack representation change.
(scm_i_vm_cont_to_frame): Adapt to take offsets from the top.
(scm_i_vm_capture_stack): Adapt to capture from the top.
(vm_return_to_continuation_inner): Adapt for data type changes.
(vm_return_to_continuation): Likewise, and instead of looping, just
splat the saved arguments on with memcpy.
(vm_dispatch_hook): Adapt to receive arguments in the reverse order.
Adapt callers.
(vm_abort): There is never a tail argument. Adapt to stack
representation change.
(vm_reinstate_partial_continuation)
(vm_reinstate_partial_continuation_inner): Adapt to stack growth
change.
(allocate_stack, free_stack): Adapt to data type change.
(expand_stack): Don't try to mremap(), as you can't grow a mapping
from the bottom. Without knowing that there's a free mapping space
right below the old stack, which there usually isn't on Linux, we have
to copy. We can't use MAP_GROWSDOWN because Linux is buggy.
(make_vm): Adapt to stack representation changes.
(return_unused_stack_to_os): Round down instead of up, as the stack
grows down.
(scm_i_vm_mark_stack): Adapt to walk up the stack.
(scm_i_vm_free_stack): Adapt to scm_vm changes.
(vm_expand_stack_inner, reset_stack_limit, vm_expand_stack): Adapt to
the stack growing down.
(scm_call_n): Adapt to the stack growing down. Don't allow argv to
point into the stack.
* libguile/vm.h (struct scm_vm, struct scm_vm_cont): Adapt to hold the
stack top and bottom.
2015-09-22 10:24:30 +00:00
|
|
|
|
vp->stack_top = vp->stack_bottom + vp->stack_size;
|
|
|
|
|
|
vp->stack_limit = vp->stack_bottom;
|
2014-03-12 17:18:13 +01:00
|
|
|
|
vp->overflow_handler_stack = SCM_EOL;
|
VM stack grows downward
Adapt VM stack to grow downward. This will make native compilation look
more like the VM code, as we will be able to use native CALL
instructions, taking proper advantage of the return address buffer.
* libguile/continuations.c (scm_i_continuation_to_frame): Record offsets
from stack top.
* libguile/control.c (scm_i_prompt_pop_abort_args_x): Adapt for reversed
order of arguments, and instead of relying on the abort to push on the
number of arguments, make the caller save the stack depth, which
allows us to compute the number of arguments ourselves.
(reify_partial_continuation, scm_c_abort): Adapt to reversed stack
order.
* libguile/dynstack.c (scm_dynstack_wind_prompt): Since we wind the
stack in a downward direction, subtract the reloc instead of adding
it.
* libguile/dynstack.h (SCM_F_DYNSTACK_PROMPT_ESCAPE_ONLY): Remove flag;
instead rely on prompt-establishing code to save the stack depth.
* libguile/eval.c (eval): Remove extraneous "volatile" declarations for
variables that are not re-set between the setjmp and any longjmp.
Adapt to save stack depth before instating the prompt.
* libguile/foreign.c (scm_i_foreign_call): Adapt to receive arguments in
reverse order.
* libguile/frames.c (frame_stack_top, scm_i_frame_stack_top): Adapt to
compute stack top instead of stack bottom.
(scm_c_frame_closure): Adapt to stack growth change.
(scm_frame_num_locals, scm_frame_local_ref, scm_frame_set_x): Use
union data type to access stack.
(RELOC): Reformat.
(scm_c_frame_previous): Adapt to stack growth change.
* libguile/frames.h: Adapt stack diagram to indicate that the stack
grows up.
(union scm_vm_stack_element): New data type used to access items on
the stack.
(SCM_FRAME_PREVIOUS_SP)
(SCM_FRAME_RETURN_ADDRESS, SCM_FRAME_SET_RETURN_ADDRESS)
(SCM_FRAME_DYNAMIC_LINK, SCM_FRAME_SET_DYNAMIC_LINK)
(SCM_FRAME_LOCAL, SCM_FRAME_NUM_LOCALS): Adapt to stack representation
change.
(SCM_FRAME_SLOT): New helper.
(SCM_VM_FRAME_FP, SCM_VM_FRAME_SP): Adapt to stack growth change.
* libguile/stacks.c (scm_make_stack): Record offsets from top of stack.
* libguile/throw.c (catch): Adapt to scm_i_prompt_pop_abort_args_x
change.
* libguile/vm-engine.c (ALLOC_FRAME, RESET_FRAME):
(FRAME_LOCALS_COUNT_FROM): Adapt to stack growth change.
(LOCAL_ADDRESS): Use SCM_FRAME_SLOT to get the address as the proper
data type.
(RETURN_ONE_VALUE, RETURN_VALUE_LIST): Adapt to stack growth change.
(apply): Shuffling up the SMOB apply args can cause the stack to
expand, so use ALLOC_FRAME instead of RESET_FRAME.
(vm_engine): Adapt for stack growth change.
* libguile/vm.c (vm_increase_sp, vm_push_sp, vm_restore_sp): Adapt to
stack representation change.
(scm_i_vm_cont_to_frame): Adapt to take offsets from the top.
(scm_i_vm_capture_stack): Adapt to capture from the top.
(vm_return_to_continuation_inner): Adapt for data type changes.
(vm_return_to_continuation): Likewise, and instead of looping, just
splat the saved arguments on with memcpy.
(vm_dispatch_hook): Adapt to receive arguments in the reverse order.
Adapt callers.
(vm_abort): There is never a tail argument. Adapt to stack
representation change.
(vm_reinstate_partial_continuation)
(vm_reinstate_partial_continuation_inner): Adapt to stack growth
change.
(allocate_stack, free_stack): Adapt to data type change.
(expand_stack): Don't try to mremap(), as you can't grow a mapping
from the bottom. Without knowing that there's a free mapping space
right below the old stack, which there usually isn't on Linux, we have
to copy. We can't use MAP_GROWSDOWN because Linux is buggy.
(make_vm): Adapt to stack representation changes.
(return_unused_stack_to_os): Round down instead of up, as the stack
grows down.
(scm_i_vm_mark_stack): Adapt to walk up the stack.
(scm_i_vm_free_stack): Adapt to scm_vm changes.
(vm_expand_stack_inner, reset_stack_limit, vm_expand_stack): Adapt to
the stack growing down.
(scm_call_n): Adapt to the stack growing down. Don't allow argv to
point into the stack.
* libguile/vm.h (struct scm_vm, struct scm_vm_cont): Adapt to hold the
stack top and bottom.
2015-09-22 10:24:30 +00:00
|
|
|
|
vp->ip = NULL;
|
|
|
|
|
|
vp->sp = vp->stack_top;
|
2015-10-18 22:59:23 +02:00
|
|
|
|
vp->fp = vp->stack_top;
|
Add new-style test and branch instructions
* libguile/vm-engine.c (UNPACK_16_16): New definition.
(u64=?, u64<?, s64=?, s64<?, f64=?, f64<?, =?, <?, arguments<?)
(positional-arguments<=?, immediate-tag=?, heap-tag=?, eq?): New
comparison instructions.
(j, jl, je, jnl, jne, jge, jnge): New branch instructions.
2017-10-24 21:12:19 +02:00
|
|
|
|
vp->compare_result = SCM_F_COMPARE_NONE;
|
VM stack grows downward
Adapt VM stack to grow downward. This will make native compilation look
more like the VM code, as we will be able to use native CALL
instructions, taking proper advantage of the return address buffer.
* libguile/continuations.c (scm_i_continuation_to_frame): Record offsets
from stack top.
* libguile/control.c (scm_i_prompt_pop_abort_args_x): Adapt for reversed
order of arguments, and instead of relying on the abort to push on the
number of arguments, make the caller save the stack depth, which
allows us to compute the number of arguments ourselves.
(reify_partial_continuation, scm_c_abort): Adapt to reversed stack
order.
* libguile/dynstack.c (scm_dynstack_wind_prompt): Since we wind the
stack in a downward direction, subtract the reloc instead of adding
it.
* libguile/dynstack.h (SCM_F_DYNSTACK_PROMPT_ESCAPE_ONLY): Remove flag;
instead rely on prompt-establishing code to save the stack depth.
* libguile/eval.c (eval): Remove extraneous "volatile" declarations for
variables that are not re-set between the setjmp and any longjmp.
Adapt to save stack depth before instating the prompt.
* libguile/foreign.c (scm_i_foreign_call): Adapt to receive arguments in
reverse order.
* libguile/frames.c (frame_stack_top, scm_i_frame_stack_top): Adapt to
compute stack top instead of stack bottom.
(scm_c_frame_closure): Adapt to stack growth change.
(scm_frame_num_locals, scm_frame_local_ref, scm_frame_set_x): Use
union data type to access stack.
(RELOC): Reformat.
(scm_c_frame_previous): Adapt to stack growth change.
* libguile/frames.h: Adapt stack diagram to indicate that the stack
grows up.
(union scm_vm_stack_element): New data type used to access items on
the stack.
(SCM_FRAME_PREVIOUS_SP)
(SCM_FRAME_RETURN_ADDRESS, SCM_FRAME_SET_RETURN_ADDRESS)
(SCM_FRAME_DYNAMIC_LINK, SCM_FRAME_SET_DYNAMIC_LINK)
(SCM_FRAME_LOCAL, SCM_FRAME_NUM_LOCALS): Adapt to stack representation
change.
(SCM_FRAME_SLOT): New helper.
(SCM_VM_FRAME_FP, SCM_VM_FRAME_SP): Adapt to stack growth change.
* libguile/stacks.c (scm_make_stack): Record offsets from top of stack.
* libguile/throw.c (catch): Adapt to scm_i_prompt_pop_abort_args_x
change.
* libguile/vm-engine.c (ALLOC_FRAME, RESET_FRAME):
(FRAME_LOCALS_COUNT_FROM): Adapt to stack growth change.
(LOCAL_ADDRESS): Use SCM_FRAME_SLOT to get the address as the proper
data type.
(RETURN_ONE_VALUE, RETURN_VALUE_LIST): Adapt to stack growth change.
(apply): Shuffling up the SMOB apply args can cause the stack to
expand, so use ALLOC_FRAME instead of RESET_FRAME.
(vm_engine): Adapt for stack growth change.
* libguile/vm.c (vm_increase_sp, vm_push_sp, vm_restore_sp): Adapt to
stack representation change.
(scm_i_vm_cont_to_frame): Adapt to take offsets from the top.
(scm_i_vm_capture_stack): Adapt to capture from the top.
(vm_return_to_continuation_inner): Adapt for data type changes.
(vm_return_to_continuation): Likewise, and instead of looping, just
splat the saved arguments on with memcpy.
(vm_dispatch_hook): Adapt to receive arguments in the reverse order.
Adapt callers.
(vm_abort): There is never a tail argument. Adapt to stack
representation change.
(vm_reinstate_partial_continuation)
(vm_reinstate_partial_continuation_inner): Adapt to stack growth
change.
(allocate_stack, free_stack): Adapt to data type change.
(expand_stack): Don't try to mremap(), as you can't grow a mapping
from the bottom. Without knowing that there's a free mapping space
right below the old stack, which there usually isn't on Linux, we have
to copy. We can't use MAP_GROWSDOWN because Linux is buggy.
(make_vm): Adapt to stack representation changes.
(return_unused_stack_to_os): Round down instead of up, as the stack
grows down.
(scm_i_vm_mark_stack): Adapt to walk up the stack.
(scm_i_vm_free_stack): Adapt to scm_vm changes.
(vm_expand_stack_inner, reset_stack_limit, vm_expand_stack): Adapt to
the stack growing down.
(scm_call_n): Adapt to the stack growing down. Don't allow argv to
point into the stack.
* libguile/vm.h (struct scm_vm, struct scm_vm_cont): Adapt to hold the
stack top and bottom.
2015-09-22 10:24:30 +00:00
|
|
|
|
vp->engine = vm_default_engine;
|
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
|
|
|
|
vp->trace_level = 0;
|
2018-09-14 12:57:16 +02:00
|
|
|
|
#define INIT_HOOK(h) vp->h##_hook = SCM_BOOL_F;
|
|
|
|
|
|
FOR_EACH_HOOK (INIT_HOOK)
|
|
|
|
|
|
#undef INIT_HOOK
|
2000-08-22 15:54:19 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2014-01-31 21:41:36 +01:00
|
|
|
|
static void
|
|
|
|
|
|
return_unused_stack_to_os (struct scm_vm *vp)
|
|
|
|
|
|
{
|
|
|
|
|
|
#if HAVE_SYS_MMAN_H
|
2018-06-21 08:39:03 +02:00
|
|
|
|
uintptr_t lo = (uintptr_t) vp->stack_bottom;
|
|
|
|
|
|
uintptr_t hi = (uintptr_t) vp->sp;
|
2014-01-31 21:41:36 +01:00
|
|
|
|
|
VM stack grows downward
Adapt VM stack to grow downward. This will make native compilation look
more like the VM code, as we will be able to use native CALL
instructions, taking proper advantage of the return address buffer.
* libguile/continuations.c (scm_i_continuation_to_frame): Record offsets
from stack top.
* libguile/control.c (scm_i_prompt_pop_abort_args_x): Adapt for reversed
order of arguments, and instead of relying on the abort to push on the
number of arguments, make the caller save the stack depth, which
allows us to compute the number of arguments ourselves.
(reify_partial_continuation, scm_c_abort): Adapt to reversed stack
order.
* libguile/dynstack.c (scm_dynstack_wind_prompt): Since we wind the
stack in a downward direction, subtract the reloc instead of adding
it.
* libguile/dynstack.h (SCM_F_DYNSTACK_PROMPT_ESCAPE_ONLY): Remove flag;
instead rely on prompt-establishing code to save the stack depth.
* libguile/eval.c (eval): Remove extraneous "volatile" declarations for
variables that are not re-set between the setjmp and any longjmp.
Adapt to save stack depth before instating the prompt.
* libguile/foreign.c (scm_i_foreign_call): Adapt to receive arguments in
reverse order.
* libguile/frames.c (frame_stack_top, scm_i_frame_stack_top): Adapt to
compute stack top instead of stack bottom.
(scm_c_frame_closure): Adapt to stack growth change.
(scm_frame_num_locals, scm_frame_local_ref, scm_frame_set_x): Use
union data type to access stack.
(RELOC): Reformat.
(scm_c_frame_previous): Adapt to stack growth change.
* libguile/frames.h: Adapt stack diagram to indicate that the stack
grows up.
(union scm_vm_stack_element): New data type used to access items on
the stack.
(SCM_FRAME_PREVIOUS_SP)
(SCM_FRAME_RETURN_ADDRESS, SCM_FRAME_SET_RETURN_ADDRESS)
(SCM_FRAME_DYNAMIC_LINK, SCM_FRAME_SET_DYNAMIC_LINK)
(SCM_FRAME_LOCAL, SCM_FRAME_NUM_LOCALS): Adapt to stack representation
change.
(SCM_FRAME_SLOT): New helper.
(SCM_VM_FRAME_FP, SCM_VM_FRAME_SP): Adapt to stack growth change.
* libguile/stacks.c (scm_make_stack): Record offsets from top of stack.
* libguile/throw.c (catch): Adapt to scm_i_prompt_pop_abort_args_x
change.
* libguile/vm-engine.c (ALLOC_FRAME, RESET_FRAME):
(FRAME_LOCALS_COUNT_FROM): Adapt to stack growth change.
(LOCAL_ADDRESS): Use SCM_FRAME_SLOT to get the address as the proper
data type.
(RETURN_ONE_VALUE, RETURN_VALUE_LIST): Adapt to stack growth change.
(apply): Shuffling up the SMOB apply args can cause the stack to
expand, so use ALLOC_FRAME instead of RESET_FRAME.
(vm_engine): Adapt for stack growth change.
* libguile/vm.c (vm_increase_sp, vm_push_sp, vm_restore_sp): Adapt to
stack representation change.
(scm_i_vm_cont_to_frame): Adapt to take offsets from the top.
(scm_i_vm_capture_stack): Adapt to capture from the top.
(vm_return_to_continuation_inner): Adapt for data type changes.
(vm_return_to_continuation): Likewise, and instead of looping, just
splat the saved arguments on with memcpy.
(vm_dispatch_hook): Adapt to receive arguments in the reverse order.
Adapt callers.
(vm_abort): There is never a tail argument. Adapt to stack
representation change.
(vm_reinstate_partial_continuation)
(vm_reinstate_partial_continuation_inner): Adapt to stack growth
change.
(allocate_stack, free_stack): Adapt to data type change.
(expand_stack): Don't try to mremap(), as you can't grow a mapping
from the bottom. Without knowing that there's a free mapping space
right below the old stack, which there usually isn't on Linux, we have
to copy. We can't use MAP_GROWSDOWN because Linux is buggy.
(make_vm): Adapt to stack representation changes.
(return_unused_stack_to_os): Round down instead of up, as the stack
grows down.
(scm_i_vm_mark_stack): Adapt to walk up the stack.
(scm_i_vm_free_stack): Adapt to scm_vm changes.
(vm_expand_stack_inner, reset_stack_limit, vm_expand_stack): Adapt to
the stack growing down.
(scm_call_n): Adapt to the stack growing down. Don't allow argv to
point into the stack.
* libguile/vm.h (struct scm_vm, struct scm_vm_cont): Adapt to hold the
stack top and bottom.
2015-09-22 10:24:30 +00:00
|
|
|
|
lo &= ~(page_size - 1U); /* round down */
|
|
|
|
|
|
hi &= ~(page_size - 1U); /* round down */
|
2014-01-31 21:41:36 +01:00
|
|
|
|
|
|
|
|
|
|
/* Return these pages to the OS. The next time they are paged in,
|
|
|
|
|
|
they will be zeroed. */
|
VM stack grows downward
Adapt VM stack to grow downward. This will make native compilation look
more like the VM code, as we will be able to use native CALL
instructions, taking proper advantage of the return address buffer.
* libguile/continuations.c (scm_i_continuation_to_frame): Record offsets
from stack top.
* libguile/control.c (scm_i_prompt_pop_abort_args_x): Adapt for reversed
order of arguments, and instead of relying on the abort to push on the
number of arguments, make the caller save the stack depth, which
allows us to compute the number of arguments ourselves.
(reify_partial_continuation, scm_c_abort): Adapt to reversed stack
order.
* libguile/dynstack.c (scm_dynstack_wind_prompt): Since we wind the
stack in a downward direction, subtract the reloc instead of adding
it.
* libguile/dynstack.h (SCM_F_DYNSTACK_PROMPT_ESCAPE_ONLY): Remove flag;
instead rely on prompt-establishing code to save the stack depth.
* libguile/eval.c (eval): Remove extraneous "volatile" declarations for
variables that are not re-set between the setjmp and any longjmp.
Adapt to save stack depth before instating the prompt.
* libguile/foreign.c (scm_i_foreign_call): Adapt to receive arguments in
reverse order.
* libguile/frames.c (frame_stack_top, scm_i_frame_stack_top): Adapt to
compute stack top instead of stack bottom.
(scm_c_frame_closure): Adapt to stack growth change.
(scm_frame_num_locals, scm_frame_local_ref, scm_frame_set_x): Use
union data type to access stack.
(RELOC): Reformat.
(scm_c_frame_previous): Adapt to stack growth change.
* libguile/frames.h: Adapt stack diagram to indicate that the stack
grows up.
(union scm_vm_stack_element): New data type used to access items on
the stack.
(SCM_FRAME_PREVIOUS_SP)
(SCM_FRAME_RETURN_ADDRESS, SCM_FRAME_SET_RETURN_ADDRESS)
(SCM_FRAME_DYNAMIC_LINK, SCM_FRAME_SET_DYNAMIC_LINK)
(SCM_FRAME_LOCAL, SCM_FRAME_NUM_LOCALS): Adapt to stack representation
change.
(SCM_FRAME_SLOT): New helper.
(SCM_VM_FRAME_FP, SCM_VM_FRAME_SP): Adapt to stack growth change.
* libguile/stacks.c (scm_make_stack): Record offsets from top of stack.
* libguile/throw.c (catch): Adapt to scm_i_prompt_pop_abort_args_x
change.
* libguile/vm-engine.c (ALLOC_FRAME, RESET_FRAME):
(FRAME_LOCALS_COUNT_FROM): Adapt to stack growth change.
(LOCAL_ADDRESS): Use SCM_FRAME_SLOT to get the address as the proper
data type.
(RETURN_ONE_VALUE, RETURN_VALUE_LIST): Adapt to stack growth change.
(apply): Shuffling up the SMOB apply args can cause the stack to
expand, so use ALLOC_FRAME instead of RESET_FRAME.
(vm_engine): Adapt for stack growth change.
* libguile/vm.c (vm_increase_sp, vm_push_sp, vm_restore_sp): Adapt to
stack representation change.
(scm_i_vm_cont_to_frame): Adapt to take offsets from the top.
(scm_i_vm_capture_stack): Adapt to capture from the top.
(vm_return_to_continuation_inner): Adapt for data type changes.
(vm_return_to_continuation): Likewise, and instead of looping, just
splat the saved arguments on with memcpy.
(vm_dispatch_hook): Adapt to receive arguments in the reverse order.
Adapt callers.
(vm_abort): There is never a tail argument. Adapt to stack
representation change.
(vm_reinstate_partial_continuation)
(vm_reinstate_partial_continuation_inner): Adapt to stack growth
change.
(allocate_stack, free_stack): Adapt to data type change.
(expand_stack): Don't try to mremap(), as you can't grow a mapping
from the bottom. Without knowing that there's a free mapping space
right below the old stack, which there usually isn't on Linux, we have
to copy. We can't use MAP_GROWSDOWN because Linux is buggy.
(make_vm): Adapt to stack representation changes.
(return_unused_stack_to_os): Round down instead of up, as the stack
grows down.
(scm_i_vm_mark_stack): Adapt to walk up the stack.
(scm_i_vm_free_stack): Adapt to scm_vm changes.
(vm_expand_stack_inner, reset_stack_limit, vm_expand_stack): Adapt to
the stack growing down.
(scm_call_n): Adapt to the stack growing down. Don't allow argv to
point into the stack.
* libguile/vm.h (struct scm_vm, struct scm_vm_cont): Adapt to hold the
stack top and bottom.
2015-09-22 10:24:30 +00:00
|
|
|
|
if (lo < hi)
|
2014-02-19 11:01:39 +01:00
|
|
|
|
{
|
|
|
|
|
|
int ret = 0;
|
|
|
|
|
|
|
|
|
|
|
|
do
|
VM stack grows downward
Adapt VM stack to grow downward. This will make native compilation look
more like the VM code, as we will be able to use native CALL
instructions, taking proper advantage of the return address buffer.
* libguile/continuations.c (scm_i_continuation_to_frame): Record offsets
from stack top.
* libguile/control.c (scm_i_prompt_pop_abort_args_x): Adapt for reversed
order of arguments, and instead of relying on the abort to push on the
number of arguments, make the caller save the stack depth, which
allows us to compute the number of arguments ourselves.
(reify_partial_continuation, scm_c_abort): Adapt to reversed stack
order.
* libguile/dynstack.c (scm_dynstack_wind_prompt): Since we wind the
stack in a downward direction, subtract the reloc instead of adding
it.
* libguile/dynstack.h (SCM_F_DYNSTACK_PROMPT_ESCAPE_ONLY): Remove flag;
instead rely on prompt-establishing code to save the stack depth.
* libguile/eval.c (eval): Remove extraneous "volatile" declarations for
variables that are not re-set between the setjmp and any longjmp.
Adapt to save stack depth before instating the prompt.
* libguile/foreign.c (scm_i_foreign_call): Adapt to receive arguments in
reverse order.
* libguile/frames.c (frame_stack_top, scm_i_frame_stack_top): Adapt to
compute stack top instead of stack bottom.
(scm_c_frame_closure): Adapt to stack growth change.
(scm_frame_num_locals, scm_frame_local_ref, scm_frame_set_x): Use
union data type to access stack.
(RELOC): Reformat.
(scm_c_frame_previous): Adapt to stack growth change.
* libguile/frames.h: Adapt stack diagram to indicate that the stack
grows up.
(union scm_vm_stack_element): New data type used to access items on
the stack.
(SCM_FRAME_PREVIOUS_SP)
(SCM_FRAME_RETURN_ADDRESS, SCM_FRAME_SET_RETURN_ADDRESS)
(SCM_FRAME_DYNAMIC_LINK, SCM_FRAME_SET_DYNAMIC_LINK)
(SCM_FRAME_LOCAL, SCM_FRAME_NUM_LOCALS): Adapt to stack representation
change.
(SCM_FRAME_SLOT): New helper.
(SCM_VM_FRAME_FP, SCM_VM_FRAME_SP): Adapt to stack growth change.
* libguile/stacks.c (scm_make_stack): Record offsets from top of stack.
* libguile/throw.c (catch): Adapt to scm_i_prompt_pop_abort_args_x
change.
* libguile/vm-engine.c (ALLOC_FRAME, RESET_FRAME):
(FRAME_LOCALS_COUNT_FROM): Adapt to stack growth change.
(LOCAL_ADDRESS): Use SCM_FRAME_SLOT to get the address as the proper
data type.
(RETURN_ONE_VALUE, RETURN_VALUE_LIST): Adapt to stack growth change.
(apply): Shuffling up the SMOB apply args can cause the stack to
expand, so use ALLOC_FRAME instead of RESET_FRAME.
(vm_engine): Adapt for stack growth change.
* libguile/vm.c (vm_increase_sp, vm_push_sp, vm_restore_sp): Adapt to
stack representation change.
(scm_i_vm_cont_to_frame): Adapt to take offsets from the top.
(scm_i_vm_capture_stack): Adapt to capture from the top.
(vm_return_to_continuation_inner): Adapt for data type changes.
(vm_return_to_continuation): Likewise, and instead of looping, just
splat the saved arguments on with memcpy.
(vm_dispatch_hook): Adapt to receive arguments in the reverse order.
Adapt callers.
(vm_abort): There is never a tail argument. Adapt to stack
representation change.
(vm_reinstate_partial_continuation)
(vm_reinstate_partial_continuation_inner): Adapt to stack growth
change.
(allocate_stack, free_stack): Adapt to data type change.
(expand_stack): Don't try to mremap(), as you can't grow a mapping
from the bottom. Without knowing that there's a free mapping space
right below the old stack, which there usually isn't on Linux, we have
to copy. We can't use MAP_GROWSDOWN because Linux is buggy.
(make_vm): Adapt to stack representation changes.
(return_unused_stack_to_os): Round down instead of up, as the stack
grows down.
(scm_i_vm_mark_stack): Adapt to walk up the stack.
(scm_i_vm_free_stack): Adapt to scm_vm changes.
(vm_expand_stack_inner, reset_stack_limit, vm_expand_stack): Adapt to
the stack growing down.
(scm_call_n): Adapt to the stack growing down. Don't allow argv to
point into the stack.
* libguile/vm.h (struct scm_vm, struct scm_vm_cont): Adapt to hold the
stack top and bottom.
2015-09-22 10:24:30 +00:00
|
|
|
|
ret = madvise ((void *) lo, hi - lo, MADV_DONTNEED);
|
2018-06-18 13:46:10 +02:00
|
|
|
|
while (ret && errno == EAGAIN);
|
2014-02-19 11:01:39 +01:00
|
|
|
|
|
2018-12-15 18:04:27 +01:00
|
|
|
|
/* If the OS doesn't implement 'madvise' (as is currently the case
|
|
|
|
|
|
for GNU/Hurd), don't warn the user since there's nothing they
|
|
|
|
|
|
can do about it. */
|
|
|
|
|
|
if (ret && errno != ENOSYS)
|
2014-02-19 11:01:39 +01:00
|
|
|
|
perror ("madvise failed");
|
|
|
|
|
|
}
|
2014-01-31 21:41:36 +01:00
|
|
|
|
#endif
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2015-10-28 16:40:53 +00:00
|
|
|
|
#define SLOT_MAP_CACHE_SIZE 32U
|
|
|
|
|
|
struct slot_map_cache_entry
|
2014-02-02 11:43:03 +01:00
|
|
|
|
{
|
2018-06-21 08:39:03 +02:00
|
|
|
|
uint32_t *ip;
|
|
|
|
|
|
const uint8_t *map;
|
2014-02-02 11:43:03 +01:00
|
|
|
|
};
|
|
|
|
|
|
|
2015-10-28 16:40:53 +00:00
|
|
|
|
struct slot_map_cache
|
2014-02-02 11:43:03 +01:00
|
|
|
|
{
|
2015-10-28 16:40:53 +00:00
|
|
|
|
struct slot_map_cache_entry entries[SLOT_MAP_CACHE_SIZE];
|
2014-02-02 11:43:03 +01:00
|
|
|
|
};
|
|
|
|
|
|
|
2018-06-21 08:39:03 +02:00
|
|
|
|
static const uint8_t *
|
|
|
|
|
|
find_slot_map (uint32_t *ip, struct slot_map_cache *cache)
|
2014-02-02 11:43:03 +01:00
|
|
|
|
{
|
|
|
|
|
|
/* The lower two bits should be zero. FIXME: Use a better hash
|
|
|
|
|
|
function; we don't expose scm_raw_hashq currently. */
|
2018-06-21 08:39:03 +02:00
|
|
|
|
size_t slot = (((uintptr_t) ip) >> 2) % SLOT_MAP_CACHE_SIZE;
|
|
|
|
|
|
const uint8_t *map;
|
2014-02-02 11:43:03 +01:00
|
|
|
|
|
|
|
|
|
|
if (cache->entries[slot].ip == ip)
|
|
|
|
|
|
map = cache->entries[slot].map;
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
2015-10-28 16:40:53 +00:00
|
|
|
|
map = scm_find_slot_map_unlocked (ip);
|
2014-02-02 11:43:03 +01:00
|
|
|
|
cache->entries[slot].ip = ip;
|
|
|
|
|
|
cache->entries[slot].map = map;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return map;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2015-10-28 16:40:53 +00:00
|
|
|
|
enum slot_desc
|
|
|
|
|
|
{
|
|
|
|
|
|
SLOT_DESC_DEAD = 0,
|
|
|
|
|
|
SLOT_DESC_LIVE_RAW = 1,
|
2018-01-10 21:05:16 +01:00
|
|
|
|
SLOT_DESC_LIVE_GC = 2,
|
2015-10-28 16:40:53 +00:00
|
|
|
|
SLOT_DESC_UNUSED = 3
|
|
|
|
|
|
};
|
|
|
|
|
|
|
VM stack grows downward
Adapt VM stack to grow downward. This will make native compilation look
more like the VM code, as we will be able to use native CALL
instructions, taking proper advantage of the return address buffer.
* libguile/continuations.c (scm_i_continuation_to_frame): Record offsets
from stack top.
* libguile/control.c (scm_i_prompt_pop_abort_args_x): Adapt for reversed
order of arguments, and instead of relying on the abort to push on the
number of arguments, make the caller save the stack depth, which
allows us to compute the number of arguments ourselves.
(reify_partial_continuation, scm_c_abort): Adapt to reversed stack
order.
* libguile/dynstack.c (scm_dynstack_wind_prompt): Since we wind the
stack in a downward direction, subtract the reloc instead of adding
it.
* libguile/dynstack.h (SCM_F_DYNSTACK_PROMPT_ESCAPE_ONLY): Remove flag;
instead rely on prompt-establishing code to save the stack depth.
* libguile/eval.c (eval): Remove extraneous "volatile" declarations for
variables that are not re-set between the setjmp and any longjmp.
Adapt to save stack depth before instating the prompt.
* libguile/foreign.c (scm_i_foreign_call): Adapt to receive arguments in
reverse order.
* libguile/frames.c (frame_stack_top, scm_i_frame_stack_top): Adapt to
compute stack top instead of stack bottom.
(scm_c_frame_closure): Adapt to stack growth change.
(scm_frame_num_locals, scm_frame_local_ref, scm_frame_set_x): Use
union data type to access stack.
(RELOC): Reformat.
(scm_c_frame_previous): Adapt to stack growth change.
* libguile/frames.h: Adapt stack diagram to indicate that the stack
grows up.
(union scm_vm_stack_element): New data type used to access items on
the stack.
(SCM_FRAME_PREVIOUS_SP)
(SCM_FRAME_RETURN_ADDRESS, SCM_FRAME_SET_RETURN_ADDRESS)
(SCM_FRAME_DYNAMIC_LINK, SCM_FRAME_SET_DYNAMIC_LINK)
(SCM_FRAME_LOCAL, SCM_FRAME_NUM_LOCALS): Adapt to stack representation
change.
(SCM_FRAME_SLOT): New helper.
(SCM_VM_FRAME_FP, SCM_VM_FRAME_SP): Adapt to stack growth change.
* libguile/stacks.c (scm_make_stack): Record offsets from top of stack.
* libguile/throw.c (catch): Adapt to scm_i_prompt_pop_abort_args_x
change.
* libguile/vm-engine.c (ALLOC_FRAME, RESET_FRAME):
(FRAME_LOCALS_COUNT_FROM): Adapt to stack growth change.
(LOCAL_ADDRESS): Use SCM_FRAME_SLOT to get the address as the proper
data type.
(RETURN_ONE_VALUE, RETURN_VALUE_LIST): Adapt to stack growth change.
(apply): Shuffling up the SMOB apply args can cause the stack to
expand, so use ALLOC_FRAME instead of RESET_FRAME.
(vm_engine): Adapt for stack growth change.
* libguile/vm.c (vm_increase_sp, vm_push_sp, vm_restore_sp): Adapt to
stack representation change.
(scm_i_vm_cont_to_frame): Adapt to take offsets from the top.
(scm_i_vm_capture_stack): Adapt to capture from the top.
(vm_return_to_continuation_inner): Adapt for data type changes.
(vm_return_to_continuation): Likewise, and instead of looping, just
splat the saved arguments on with memcpy.
(vm_dispatch_hook): Adapt to receive arguments in the reverse order.
Adapt callers.
(vm_abort): There is never a tail argument. Adapt to stack
representation change.
(vm_reinstate_partial_continuation)
(vm_reinstate_partial_continuation_inner): Adapt to stack growth
change.
(allocate_stack, free_stack): Adapt to data type change.
(expand_stack): Don't try to mremap(), as you can't grow a mapping
from the bottom. Without knowing that there's a free mapping space
right below the old stack, which there usually isn't on Linux, we have
to copy. We can't use MAP_GROWSDOWN because Linux is buggy.
(make_vm): Adapt to stack representation changes.
(return_unused_stack_to_os): Round down instead of up, as the stack
grows down.
(scm_i_vm_mark_stack): Adapt to walk up the stack.
(scm_i_vm_free_stack): Adapt to scm_vm changes.
(vm_expand_stack_inner, reset_stack_limit, vm_expand_stack): Adapt to
the stack growing down.
(scm_call_n): Adapt to the stack growing down. Don't allow argv to
point into the stack.
* libguile/vm.h (struct scm_vm, struct scm_vm_cont): Adapt to hold the
stack top and bottom.
2015-09-22 10:24:30 +00:00
|
|
|
|
/* Mark the active VM stack region. */
|
2013-11-22 14:41:19 +01:00
|
|
|
|
struct GC_ms_entry *
|
|
|
|
|
|
scm_i_vm_mark_stack (struct scm_vm *vp, struct GC_ms_entry *mark_stack_ptr,
|
|
|
|
|
|
struct GC_ms_entry *mark_stack_limit)
|
2009-08-20 01:56:47 +02:00
|
|
|
|
{
|
VM stack grows downward
Adapt VM stack to grow downward. This will make native compilation look
more like the VM code, as we will be able to use native CALL
instructions, taking proper advantage of the return address buffer.
* libguile/continuations.c (scm_i_continuation_to_frame): Record offsets
from stack top.
* libguile/control.c (scm_i_prompt_pop_abort_args_x): Adapt for reversed
order of arguments, and instead of relying on the abort to push on the
number of arguments, make the caller save the stack depth, which
allows us to compute the number of arguments ourselves.
(reify_partial_continuation, scm_c_abort): Adapt to reversed stack
order.
* libguile/dynstack.c (scm_dynstack_wind_prompt): Since we wind the
stack in a downward direction, subtract the reloc instead of adding
it.
* libguile/dynstack.h (SCM_F_DYNSTACK_PROMPT_ESCAPE_ONLY): Remove flag;
instead rely on prompt-establishing code to save the stack depth.
* libguile/eval.c (eval): Remove extraneous "volatile" declarations for
variables that are not re-set between the setjmp and any longjmp.
Adapt to save stack depth before instating the prompt.
* libguile/foreign.c (scm_i_foreign_call): Adapt to receive arguments in
reverse order.
* libguile/frames.c (frame_stack_top, scm_i_frame_stack_top): Adapt to
compute stack top instead of stack bottom.
(scm_c_frame_closure): Adapt to stack growth change.
(scm_frame_num_locals, scm_frame_local_ref, scm_frame_set_x): Use
union data type to access stack.
(RELOC): Reformat.
(scm_c_frame_previous): Adapt to stack growth change.
* libguile/frames.h: Adapt stack diagram to indicate that the stack
grows up.
(union scm_vm_stack_element): New data type used to access items on
the stack.
(SCM_FRAME_PREVIOUS_SP)
(SCM_FRAME_RETURN_ADDRESS, SCM_FRAME_SET_RETURN_ADDRESS)
(SCM_FRAME_DYNAMIC_LINK, SCM_FRAME_SET_DYNAMIC_LINK)
(SCM_FRAME_LOCAL, SCM_FRAME_NUM_LOCALS): Adapt to stack representation
change.
(SCM_FRAME_SLOT): New helper.
(SCM_VM_FRAME_FP, SCM_VM_FRAME_SP): Adapt to stack growth change.
* libguile/stacks.c (scm_make_stack): Record offsets from top of stack.
* libguile/throw.c (catch): Adapt to scm_i_prompt_pop_abort_args_x
change.
* libguile/vm-engine.c (ALLOC_FRAME, RESET_FRAME):
(FRAME_LOCALS_COUNT_FROM): Adapt to stack growth change.
(LOCAL_ADDRESS): Use SCM_FRAME_SLOT to get the address as the proper
data type.
(RETURN_ONE_VALUE, RETURN_VALUE_LIST): Adapt to stack growth change.
(apply): Shuffling up the SMOB apply args can cause the stack to
expand, so use ALLOC_FRAME instead of RESET_FRAME.
(vm_engine): Adapt for stack growth change.
* libguile/vm.c (vm_increase_sp, vm_push_sp, vm_restore_sp): Adapt to
stack representation change.
(scm_i_vm_cont_to_frame): Adapt to take offsets from the top.
(scm_i_vm_capture_stack): Adapt to capture from the top.
(vm_return_to_continuation_inner): Adapt for data type changes.
(vm_return_to_continuation): Likewise, and instead of looping, just
splat the saved arguments on with memcpy.
(vm_dispatch_hook): Adapt to receive arguments in the reverse order.
Adapt callers.
(vm_abort): There is never a tail argument. Adapt to stack
representation change.
(vm_reinstate_partial_continuation)
(vm_reinstate_partial_continuation_inner): Adapt to stack growth
change.
(allocate_stack, free_stack): Adapt to data type change.
(expand_stack): Don't try to mremap(), as you can't grow a mapping
from the bottom. Without knowing that there's a free mapping space
right below the old stack, which there usually isn't on Linux, we have
to copy. We can't use MAP_GROWSDOWN because Linux is buggy.
(make_vm): Adapt to stack representation changes.
(return_unused_stack_to_os): Round down instead of up, as the stack
grows down.
(scm_i_vm_mark_stack): Adapt to walk up the stack.
(scm_i_vm_free_stack): Adapt to scm_vm changes.
(vm_expand_stack_inner, reset_stack_limit, vm_expand_stack): Adapt to
the stack growing down.
(scm_call_n): Adapt to the stack growing down. Don't allow argv to
point into the stack.
* libguile/vm.h (struct scm_vm, struct scm_vm_cont): Adapt to hold the
stack top and bottom.
2015-09-22 10:24:30 +00:00
|
|
|
|
union scm_vm_stack_element *sp, *fp;
|
2015-10-28 16:40:53 +00:00
|
|
|
|
/* The first frame will be marked conservatively (without a slot map).
|
|
|
|
|
|
This is because GC can happen at any point within the hottest
|
|
|
|
|
|
activation, due to multiple threads or per-instruction hooks, and
|
|
|
|
|
|
providing slot maps for all points in a program would take a
|
|
|
|
|
|
prohibitive amount of space. */
|
2018-06-21 08:39:03 +02:00
|
|
|
|
const uint8_t *slot_map = NULL;
|
VM stack grows downward
Adapt VM stack to grow downward. This will make native compilation look
more like the VM code, as we will be able to use native CALL
instructions, taking proper advantage of the return address buffer.
* libguile/continuations.c (scm_i_continuation_to_frame): Record offsets
from stack top.
* libguile/control.c (scm_i_prompt_pop_abort_args_x): Adapt for reversed
order of arguments, and instead of relying on the abort to push on the
number of arguments, make the caller save the stack depth, which
allows us to compute the number of arguments ourselves.
(reify_partial_continuation, scm_c_abort): Adapt to reversed stack
order.
* libguile/dynstack.c (scm_dynstack_wind_prompt): Since we wind the
stack in a downward direction, subtract the reloc instead of adding
it.
* libguile/dynstack.h (SCM_F_DYNSTACK_PROMPT_ESCAPE_ONLY): Remove flag;
instead rely on prompt-establishing code to save the stack depth.
* libguile/eval.c (eval): Remove extraneous "volatile" declarations for
variables that are not re-set between the setjmp and any longjmp.
Adapt to save stack depth before instating the prompt.
* libguile/foreign.c (scm_i_foreign_call): Adapt to receive arguments in
reverse order.
* libguile/frames.c (frame_stack_top, scm_i_frame_stack_top): Adapt to
compute stack top instead of stack bottom.
(scm_c_frame_closure): Adapt to stack growth change.
(scm_frame_num_locals, scm_frame_local_ref, scm_frame_set_x): Use
union data type to access stack.
(RELOC): Reformat.
(scm_c_frame_previous): Adapt to stack growth change.
* libguile/frames.h: Adapt stack diagram to indicate that the stack
grows up.
(union scm_vm_stack_element): New data type used to access items on
the stack.
(SCM_FRAME_PREVIOUS_SP)
(SCM_FRAME_RETURN_ADDRESS, SCM_FRAME_SET_RETURN_ADDRESS)
(SCM_FRAME_DYNAMIC_LINK, SCM_FRAME_SET_DYNAMIC_LINK)
(SCM_FRAME_LOCAL, SCM_FRAME_NUM_LOCALS): Adapt to stack representation
change.
(SCM_FRAME_SLOT): New helper.
(SCM_VM_FRAME_FP, SCM_VM_FRAME_SP): Adapt to stack growth change.
* libguile/stacks.c (scm_make_stack): Record offsets from top of stack.
* libguile/throw.c (catch): Adapt to scm_i_prompt_pop_abort_args_x
change.
* libguile/vm-engine.c (ALLOC_FRAME, RESET_FRAME):
(FRAME_LOCALS_COUNT_FROM): Adapt to stack growth change.
(LOCAL_ADDRESS): Use SCM_FRAME_SLOT to get the address as the proper
data type.
(RETURN_ONE_VALUE, RETURN_VALUE_LIST): Adapt to stack growth change.
(apply): Shuffling up the SMOB apply args can cause the stack to
expand, so use ALLOC_FRAME instead of RESET_FRAME.
(vm_engine): Adapt for stack growth change.
* libguile/vm.c (vm_increase_sp, vm_push_sp, vm_restore_sp): Adapt to
stack representation change.
(scm_i_vm_cont_to_frame): Adapt to take offsets from the top.
(scm_i_vm_capture_stack): Adapt to capture from the top.
(vm_return_to_continuation_inner): Adapt for data type changes.
(vm_return_to_continuation): Likewise, and instead of looping, just
splat the saved arguments on with memcpy.
(vm_dispatch_hook): Adapt to receive arguments in the reverse order.
Adapt callers.
(vm_abort): There is never a tail argument. Adapt to stack
representation change.
(vm_reinstate_partial_continuation)
(vm_reinstate_partial_continuation_inner): Adapt to stack growth
change.
(allocate_stack, free_stack): Adapt to data type change.
(expand_stack): Don't try to mremap(), as you can't grow a mapping
from the bottom. Without knowing that there's a free mapping space
right below the old stack, which there usually isn't on Linux, we have
to copy. We can't use MAP_GROWSDOWN because Linux is buggy.
(make_vm): Adapt to stack representation changes.
(return_unused_stack_to_os): Round down instead of up, as the stack
grows down.
(scm_i_vm_mark_stack): Adapt to walk up the stack.
(scm_i_vm_free_stack): Adapt to scm_vm changes.
(vm_expand_stack_inner, reset_stack_limit, vm_expand_stack): Adapt to
the stack growing down.
(scm_call_n): Adapt to the stack growing down. Don't allow argv to
point into the stack.
* libguile/vm.h (struct scm_vm, struct scm_vm_cont): Adapt to hold the
stack top and bottom.
2015-09-22 10:24:30 +00:00
|
|
|
|
void *upper = (void *) GC_greatest_plausible_heap_addr;
|
|
|
|
|
|
void *lower = (void *) GC_least_plausible_heap_addr;
|
2015-10-28 16:40:53 +00:00
|
|
|
|
struct slot_map_cache cache;
|
2014-02-02 11:43:03 +01:00
|
|
|
|
|
|
|
|
|
|
memset (&cache, 0, sizeof (cache));
|
2009-08-20 01:56:47 +02:00
|
|
|
|
|
2015-10-18 22:59:23 +02:00
|
|
|
|
for (fp = vp->fp, sp = vp->sp;
|
|
|
|
|
|
fp < vp->stack_top;
|
|
|
|
|
|
fp = SCM_FRAME_DYNAMIC_LINK (fp))
|
2013-11-22 15:02:17 +01:00
|
|
|
|
{
|
2018-06-21 08:43:47 +02:00
|
|
|
|
ptrdiff_t nlocals = SCM_FRAME_NUM_LOCALS (fp, sp);
|
VM stack grows downward
Adapt VM stack to grow downward. This will make native compilation look
more like the VM code, as we will be able to use native CALL
instructions, taking proper advantage of the return address buffer.
* libguile/continuations.c (scm_i_continuation_to_frame): Record offsets
from stack top.
* libguile/control.c (scm_i_prompt_pop_abort_args_x): Adapt for reversed
order of arguments, and instead of relying on the abort to push on the
number of arguments, make the caller save the stack depth, which
allows us to compute the number of arguments ourselves.
(reify_partial_continuation, scm_c_abort): Adapt to reversed stack
order.
* libguile/dynstack.c (scm_dynstack_wind_prompt): Since we wind the
stack in a downward direction, subtract the reloc instead of adding
it.
* libguile/dynstack.h (SCM_F_DYNSTACK_PROMPT_ESCAPE_ONLY): Remove flag;
instead rely on prompt-establishing code to save the stack depth.
* libguile/eval.c (eval): Remove extraneous "volatile" declarations for
variables that are not re-set between the setjmp and any longjmp.
Adapt to save stack depth before instating the prompt.
* libguile/foreign.c (scm_i_foreign_call): Adapt to receive arguments in
reverse order.
* libguile/frames.c (frame_stack_top, scm_i_frame_stack_top): Adapt to
compute stack top instead of stack bottom.
(scm_c_frame_closure): Adapt to stack growth change.
(scm_frame_num_locals, scm_frame_local_ref, scm_frame_set_x): Use
union data type to access stack.
(RELOC): Reformat.
(scm_c_frame_previous): Adapt to stack growth change.
* libguile/frames.h: Adapt stack diagram to indicate that the stack
grows up.
(union scm_vm_stack_element): New data type used to access items on
the stack.
(SCM_FRAME_PREVIOUS_SP)
(SCM_FRAME_RETURN_ADDRESS, SCM_FRAME_SET_RETURN_ADDRESS)
(SCM_FRAME_DYNAMIC_LINK, SCM_FRAME_SET_DYNAMIC_LINK)
(SCM_FRAME_LOCAL, SCM_FRAME_NUM_LOCALS): Adapt to stack representation
change.
(SCM_FRAME_SLOT): New helper.
(SCM_VM_FRAME_FP, SCM_VM_FRAME_SP): Adapt to stack growth change.
* libguile/stacks.c (scm_make_stack): Record offsets from top of stack.
* libguile/throw.c (catch): Adapt to scm_i_prompt_pop_abort_args_x
change.
* libguile/vm-engine.c (ALLOC_FRAME, RESET_FRAME):
(FRAME_LOCALS_COUNT_FROM): Adapt to stack growth change.
(LOCAL_ADDRESS): Use SCM_FRAME_SLOT to get the address as the proper
data type.
(RETURN_ONE_VALUE, RETURN_VALUE_LIST): Adapt to stack growth change.
(apply): Shuffling up the SMOB apply args can cause the stack to
expand, so use ALLOC_FRAME instead of RESET_FRAME.
(vm_engine): Adapt for stack growth change.
* libguile/vm.c (vm_increase_sp, vm_push_sp, vm_restore_sp): Adapt to
stack representation change.
(scm_i_vm_cont_to_frame): Adapt to take offsets from the top.
(scm_i_vm_capture_stack): Adapt to capture from the top.
(vm_return_to_continuation_inner): Adapt for data type changes.
(vm_return_to_continuation): Likewise, and instead of looping, just
splat the saved arguments on with memcpy.
(vm_dispatch_hook): Adapt to receive arguments in the reverse order.
Adapt callers.
(vm_abort): There is never a tail argument. Adapt to stack
representation change.
(vm_reinstate_partial_continuation)
(vm_reinstate_partial_continuation_inner): Adapt to stack growth
change.
(allocate_stack, free_stack): Adapt to data type change.
(expand_stack): Don't try to mremap(), as you can't grow a mapping
from the bottom. Without knowing that there's a free mapping space
right below the old stack, which there usually isn't on Linux, we have
to copy. We can't use MAP_GROWSDOWN because Linux is buggy.
(make_vm): Adapt to stack representation changes.
(return_unused_stack_to_os): Round down instead of up, as the stack
grows down.
(scm_i_vm_mark_stack): Adapt to walk up the stack.
(scm_i_vm_free_stack): Adapt to scm_vm changes.
(vm_expand_stack_inner, reset_stack_limit, vm_expand_stack): Adapt to
the stack growing down.
(scm_call_n): Adapt to the stack growing down. Don't allow argv to
point into the stack.
* libguile/vm.h (struct scm_vm, struct scm_vm_cont): Adapt to hold the
stack top and bottom.
2015-09-22 10:24:30 +00:00
|
|
|
|
size_t slot = nlocals - 1;
|
|
|
|
|
|
for (slot = nlocals - 1; sp < fp; sp++, slot--)
|
2013-11-22 15:02:17 +01:00
|
|
|
|
{
|
2018-01-10 21:05:16 +01:00
|
|
|
|
enum slot_desc desc = SLOT_DESC_LIVE_GC;
|
2015-10-28 16:40:53 +00:00
|
|
|
|
|
|
|
|
|
|
if (slot_map)
|
|
|
|
|
|
desc = (slot_map[slot / 4U] >> ((slot % 4U) * 2)) & 3U;
|
|
|
|
|
|
|
|
|
|
|
|
switch (desc)
|
2014-01-26 20:55:04 +01:00
|
|
|
|
{
|
2015-10-28 16:40:53 +00:00
|
|
|
|
case SLOT_DESC_LIVE_RAW:
|
|
|
|
|
|
break;
|
|
|
|
|
|
case SLOT_DESC_UNUSED:
|
2018-01-10 21:05:16 +01:00
|
|
|
|
case SLOT_DESC_LIVE_GC:
|
2015-10-28 16:40:53 +00:00
|
|
|
|
if (SCM_NIMP (sp->as_scm) &&
|
|
|
|
|
|
sp->as_ptr >= lower && sp->as_ptr <= upper)
|
|
|
|
|
|
mark_stack_ptr = GC_mark_and_push (sp->as_ptr,
|
|
|
|
|
|
mark_stack_ptr,
|
|
|
|
|
|
mark_stack_limit,
|
|
|
|
|
|
NULL);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case SLOT_DESC_DEAD:
|
|
|
|
|
|
/* This value may become dead as a result of GC,
|
|
|
|
|
|
so we can't just leave it on the stack. */
|
|
|
|
|
|
sp->as_scm = SCM_UNSPECIFIED;
|
|
|
|
|
|
break;
|
2014-01-26 20:55:04 +01:00
|
|
|
|
}
|
2013-11-22 15:02:17 +01:00
|
|
|
|
}
|
|
|
|
|
|
sp = SCM_FRAME_PREVIOUS_SP (fp);
|
2014-01-26 20:55:04 +01:00
|
|
|
|
/* Inner frames may have a dead slots map for precise marking.
|
|
|
|
|
|
Note that there may be other reasons to not have a dead slots
|
|
|
|
|
|
map, e.g. if all of the frame's slots below the callee frame
|
|
|
|
|
|
are live. */
|
2018-07-15 09:50:52 +02:00
|
|
|
|
slot_map = find_slot_map (SCM_FRAME_VIRTUAL_RETURN_ADDRESS (fp), &cache);
|
2013-11-22 15:02:17 +01:00
|
|
|
|
}
|
2009-08-20 01:56:47 +02:00
|
|
|
|
|
2014-01-31 21:41:36 +01:00
|
|
|
|
return_unused_stack_to_os (vp);
|
|
|
|
|
|
|
2009-08-20 01:56:47 +02:00
|
|
|
|
return mark_stack_ptr;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2013-11-22 14:41:19 +01:00
|
|
|
|
/* Free the VM stack, as this thread is exiting. */
|
|
|
|
|
|
void
|
|
|
|
|
|
scm_i_vm_free_stack (struct scm_vm *vp)
|
|
|
|
|
|
{
|
VM stack grows downward
Adapt VM stack to grow downward. This will make native compilation look
more like the VM code, as we will be able to use native CALL
instructions, taking proper advantage of the return address buffer.
* libguile/continuations.c (scm_i_continuation_to_frame): Record offsets
from stack top.
* libguile/control.c (scm_i_prompt_pop_abort_args_x): Adapt for reversed
order of arguments, and instead of relying on the abort to push on the
number of arguments, make the caller save the stack depth, which
allows us to compute the number of arguments ourselves.
(reify_partial_continuation, scm_c_abort): Adapt to reversed stack
order.
* libguile/dynstack.c (scm_dynstack_wind_prompt): Since we wind the
stack in a downward direction, subtract the reloc instead of adding
it.
* libguile/dynstack.h (SCM_F_DYNSTACK_PROMPT_ESCAPE_ONLY): Remove flag;
instead rely on prompt-establishing code to save the stack depth.
* libguile/eval.c (eval): Remove extraneous "volatile" declarations for
variables that are not re-set between the setjmp and any longjmp.
Adapt to save stack depth before instating the prompt.
* libguile/foreign.c (scm_i_foreign_call): Adapt to receive arguments in
reverse order.
* libguile/frames.c (frame_stack_top, scm_i_frame_stack_top): Adapt to
compute stack top instead of stack bottom.
(scm_c_frame_closure): Adapt to stack growth change.
(scm_frame_num_locals, scm_frame_local_ref, scm_frame_set_x): Use
union data type to access stack.
(RELOC): Reformat.
(scm_c_frame_previous): Adapt to stack growth change.
* libguile/frames.h: Adapt stack diagram to indicate that the stack
grows up.
(union scm_vm_stack_element): New data type used to access items on
the stack.
(SCM_FRAME_PREVIOUS_SP)
(SCM_FRAME_RETURN_ADDRESS, SCM_FRAME_SET_RETURN_ADDRESS)
(SCM_FRAME_DYNAMIC_LINK, SCM_FRAME_SET_DYNAMIC_LINK)
(SCM_FRAME_LOCAL, SCM_FRAME_NUM_LOCALS): Adapt to stack representation
change.
(SCM_FRAME_SLOT): New helper.
(SCM_VM_FRAME_FP, SCM_VM_FRAME_SP): Adapt to stack growth change.
* libguile/stacks.c (scm_make_stack): Record offsets from top of stack.
* libguile/throw.c (catch): Adapt to scm_i_prompt_pop_abort_args_x
change.
* libguile/vm-engine.c (ALLOC_FRAME, RESET_FRAME):
(FRAME_LOCALS_COUNT_FROM): Adapt to stack growth change.
(LOCAL_ADDRESS): Use SCM_FRAME_SLOT to get the address as the proper
data type.
(RETURN_ONE_VALUE, RETURN_VALUE_LIST): Adapt to stack growth change.
(apply): Shuffling up the SMOB apply args can cause the stack to
expand, so use ALLOC_FRAME instead of RESET_FRAME.
(vm_engine): Adapt for stack growth change.
* libguile/vm.c (vm_increase_sp, vm_push_sp, vm_restore_sp): Adapt to
stack representation change.
(scm_i_vm_cont_to_frame): Adapt to take offsets from the top.
(scm_i_vm_capture_stack): Adapt to capture from the top.
(vm_return_to_continuation_inner): Adapt for data type changes.
(vm_return_to_continuation): Likewise, and instead of looping, just
splat the saved arguments on with memcpy.
(vm_dispatch_hook): Adapt to receive arguments in the reverse order.
Adapt callers.
(vm_abort): There is never a tail argument. Adapt to stack
representation change.
(vm_reinstate_partial_continuation)
(vm_reinstate_partial_continuation_inner): Adapt to stack growth
change.
(allocate_stack, free_stack): Adapt to data type change.
(expand_stack): Don't try to mremap(), as you can't grow a mapping
from the bottom. Without knowing that there's a free mapping space
right below the old stack, which there usually isn't on Linux, we have
to copy. We can't use MAP_GROWSDOWN because Linux is buggy.
(make_vm): Adapt to stack representation changes.
(return_unused_stack_to_os): Round down instead of up, as the stack
grows down.
(scm_i_vm_mark_stack): Adapt to walk up the stack.
(scm_i_vm_free_stack): Adapt to scm_vm changes.
(vm_expand_stack_inner, reset_stack_limit, vm_expand_stack): Adapt to
the stack growing down.
(scm_call_n): Adapt to the stack growing down. Don't allow argv to
point into the stack.
* libguile/vm.h (struct scm_vm, struct scm_vm_cont): Adapt to hold the
stack top and bottom.
2015-09-22 10:24:30 +00:00
|
|
|
|
free_stack (vp->stack_bottom, vp->stack_size);
|
2018-06-24 09:32:11 +02:00
|
|
|
|
/* Not strictly necessary, but good to avoid confusion when debugging
|
|
|
|
|
|
thread-related GC issues. */
|
|
|
|
|
|
memset (vp, 0, sizeof (*vp));
|
2013-11-22 14:41:19 +01:00
|
|
|
|
}
|
2009-08-20 01:56:47 +02:00
|
|
|
|
|
2014-02-20 21:09:08 +01:00
|
|
|
|
struct vm_expand_stack_data
|
|
|
|
|
|
{
|
|
|
|
|
|
struct scm_vm *vp;
|
|
|
|
|
|
size_t stack_size;
|
VM stack grows downward
Adapt VM stack to grow downward. This will make native compilation look
more like the VM code, as we will be able to use native CALL
instructions, taking proper advantage of the return address buffer.
* libguile/continuations.c (scm_i_continuation_to_frame): Record offsets
from stack top.
* libguile/control.c (scm_i_prompt_pop_abort_args_x): Adapt for reversed
order of arguments, and instead of relying on the abort to push on the
number of arguments, make the caller save the stack depth, which
allows us to compute the number of arguments ourselves.
(reify_partial_continuation, scm_c_abort): Adapt to reversed stack
order.
* libguile/dynstack.c (scm_dynstack_wind_prompt): Since we wind the
stack in a downward direction, subtract the reloc instead of adding
it.
* libguile/dynstack.h (SCM_F_DYNSTACK_PROMPT_ESCAPE_ONLY): Remove flag;
instead rely on prompt-establishing code to save the stack depth.
* libguile/eval.c (eval): Remove extraneous "volatile" declarations for
variables that are not re-set between the setjmp and any longjmp.
Adapt to save stack depth before instating the prompt.
* libguile/foreign.c (scm_i_foreign_call): Adapt to receive arguments in
reverse order.
* libguile/frames.c (frame_stack_top, scm_i_frame_stack_top): Adapt to
compute stack top instead of stack bottom.
(scm_c_frame_closure): Adapt to stack growth change.
(scm_frame_num_locals, scm_frame_local_ref, scm_frame_set_x): Use
union data type to access stack.
(RELOC): Reformat.
(scm_c_frame_previous): Adapt to stack growth change.
* libguile/frames.h: Adapt stack diagram to indicate that the stack
grows up.
(union scm_vm_stack_element): New data type used to access items on
the stack.
(SCM_FRAME_PREVIOUS_SP)
(SCM_FRAME_RETURN_ADDRESS, SCM_FRAME_SET_RETURN_ADDRESS)
(SCM_FRAME_DYNAMIC_LINK, SCM_FRAME_SET_DYNAMIC_LINK)
(SCM_FRAME_LOCAL, SCM_FRAME_NUM_LOCALS): Adapt to stack representation
change.
(SCM_FRAME_SLOT): New helper.
(SCM_VM_FRAME_FP, SCM_VM_FRAME_SP): Adapt to stack growth change.
* libguile/stacks.c (scm_make_stack): Record offsets from top of stack.
* libguile/throw.c (catch): Adapt to scm_i_prompt_pop_abort_args_x
change.
* libguile/vm-engine.c (ALLOC_FRAME, RESET_FRAME):
(FRAME_LOCALS_COUNT_FROM): Adapt to stack growth change.
(LOCAL_ADDRESS): Use SCM_FRAME_SLOT to get the address as the proper
data type.
(RETURN_ONE_VALUE, RETURN_VALUE_LIST): Adapt to stack growth change.
(apply): Shuffling up the SMOB apply args can cause the stack to
expand, so use ALLOC_FRAME instead of RESET_FRAME.
(vm_engine): Adapt for stack growth change.
* libguile/vm.c (vm_increase_sp, vm_push_sp, vm_restore_sp): Adapt to
stack representation change.
(scm_i_vm_cont_to_frame): Adapt to take offsets from the top.
(scm_i_vm_capture_stack): Adapt to capture from the top.
(vm_return_to_continuation_inner): Adapt for data type changes.
(vm_return_to_continuation): Likewise, and instead of looping, just
splat the saved arguments on with memcpy.
(vm_dispatch_hook): Adapt to receive arguments in the reverse order.
Adapt callers.
(vm_abort): There is never a tail argument. Adapt to stack
representation change.
(vm_reinstate_partial_continuation)
(vm_reinstate_partial_continuation_inner): Adapt to stack growth
change.
(allocate_stack, free_stack): Adapt to data type change.
(expand_stack): Don't try to mremap(), as you can't grow a mapping
from the bottom. Without knowing that there's a free mapping space
right below the old stack, which there usually isn't on Linux, we have
to copy. We can't use MAP_GROWSDOWN because Linux is buggy.
(make_vm): Adapt to stack representation changes.
(return_unused_stack_to_os): Round down instead of up, as the stack
grows down.
(scm_i_vm_mark_stack): Adapt to walk up the stack.
(scm_i_vm_free_stack): Adapt to scm_vm changes.
(vm_expand_stack_inner, reset_stack_limit, vm_expand_stack): Adapt to
the stack growing down.
(scm_call_n): Adapt to the stack growing down. Don't allow argv to
point into the stack.
* libguile/vm.h (struct scm_vm, struct scm_vm_cont): Adapt to hold the
stack top and bottom.
2015-09-22 10:24:30 +00:00
|
|
|
|
union scm_vm_stack_element *new_sp;
|
2014-02-20 21:09:08 +01:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
static void *
|
|
|
|
|
|
vm_expand_stack_inner (void *data_ptr)
|
|
|
|
|
|
{
|
|
|
|
|
|
struct vm_expand_stack_data *data = data_ptr;
|
|
|
|
|
|
|
|
|
|
|
|
struct scm_vm *vp = data->vp;
|
VM stack grows downward
Adapt VM stack to grow downward. This will make native compilation look
more like the VM code, as we will be able to use native CALL
instructions, taking proper advantage of the return address buffer.
* libguile/continuations.c (scm_i_continuation_to_frame): Record offsets
from stack top.
* libguile/control.c (scm_i_prompt_pop_abort_args_x): Adapt for reversed
order of arguments, and instead of relying on the abort to push on the
number of arguments, make the caller save the stack depth, which
allows us to compute the number of arguments ourselves.
(reify_partial_continuation, scm_c_abort): Adapt to reversed stack
order.
* libguile/dynstack.c (scm_dynstack_wind_prompt): Since we wind the
stack in a downward direction, subtract the reloc instead of adding
it.
* libguile/dynstack.h (SCM_F_DYNSTACK_PROMPT_ESCAPE_ONLY): Remove flag;
instead rely on prompt-establishing code to save the stack depth.
* libguile/eval.c (eval): Remove extraneous "volatile" declarations for
variables that are not re-set between the setjmp and any longjmp.
Adapt to save stack depth before instating the prompt.
* libguile/foreign.c (scm_i_foreign_call): Adapt to receive arguments in
reverse order.
* libguile/frames.c (frame_stack_top, scm_i_frame_stack_top): Adapt to
compute stack top instead of stack bottom.
(scm_c_frame_closure): Adapt to stack growth change.
(scm_frame_num_locals, scm_frame_local_ref, scm_frame_set_x): Use
union data type to access stack.
(RELOC): Reformat.
(scm_c_frame_previous): Adapt to stack growth change.
* libguile/frames.h: Adapt stack diagram to indicate that the stack
grows up.
(union scm_vm_stack_element): New data type used to access items on
the stack.
(SCM_FRAME_PREVIOUS_SP)
(SCM_FRAME_RETURN_ADDRESS, SCM_FRAME_SET_RETURN_ADDRESS)
(SCM_FRAME_DYNAMIC_LINK, SCM_FRAME_SET_DYNAMIC_LINK)
(SCM_FRAME_LOCAL, SCM_FRAME_NUM_LOCALS): Adapt to stack representation
change.
(SCM_FRAME_SLOT): New helper.
(SCM_VM_FRAME_FP, SCM_VM_FRAME_SP): Adapt to stack growth change.
* libguile/stacks.c (scm_make_stack): Record offsets from top of stack.
* libguile/throw.c (catch): Adapt to scm_i_prompt_pop_abort_args_x
change.
* libguile/vm-engine.c (ALLOC_FRAME, RESET_FRAME):
(FRAME_LOCALS_COUNT_FROM): Adapt to stack growth change.
(LOCAL_ADDRESS): Use SCM_FRAME_SLOT to get the address as the proper
data type.
(RETURN_ONE_VALUE, RETURN_VALUE_LIST): Adapt to stack growth change.
(apply): Shuffling up the SMOB apply args can cause the stack to
expand, so use ALLOC_FRAME instead of RESET_FRAME.
(vm_engine): Adapt for stack growth change.
* libguile/vm.c (vm_increase_sp, vm_push_sp, vm_restore_sp): Adapt to
stack representation change.
(scm_i_vm_cont_to_frame): Adapt to take offsets from the top.
(scm_i_vm_capture_stack): Adapt to capture from the top.
(vm_return_to_continuation_inner): Adapt for data type changes.
(vm_return_to_continuation): Likewise, and instead of looping, just
splat the saved arguments on with memcpy.
(vm_dispatch_hook): Adapt to receive arguments in the reverse order.
Adapt callers.
(vm_abort): There is never a tail argument. Adapt to stack
representation change.
(vm_reinstate_partial_continuation)
(vm_reinstate_partial_continuation_inner): Adapt to stack growth
change.
(allocate_stack, free_stack): Adapt to data type change.
(expand_stack): Don't try to mremap(), as you can't grow a mapping
from the bottom. Without knowing that there's a free mapping space
right below the old stack, which there usually isn't on Linux, we have
to copy. We can't use MAP_GROWSDOWN because Linux is buggy.
(make_vm): Adapt to stack representation changes.
(return_unused_stack_to_os): Round down instead of up, as the stack
grows down.
(scm_i_vm_mark_stack): Adapt to walk up the stack.
(scm_i_vm_free_stack): Adapt to scm_vm changes.
(vm_expand_stack_inner, reset_stack_limit, vm_expand_stack): Adapt to
the stack growing down.
(scm_call_n): Adapt to the stack growing down. Don't allow argv to
point into the stack.
* libguile/vm.h (struct scm_vm, struct scm_vm_cont): Adapt to hold the
stack top and bottom.
2015-09-22 10:24:30 +00:00
|
|
|
|
union scm_vm_stack_element *old_top, *new_bottom;
|
2014-02-20 21:09:08 +01:00
|
|
|
|
size_t new_size;
|
2018-06-21 08:43:47 +02:00
|
|
|
|
ptrdiff_t reloc;
|
2014-02-20 21:09:08 +01:00
|
|
|
|
|
VM stack grows downward
Adapt VM stack to grow downward. This will make native compilation look
more like the VM code, as we will be able to use native CALL
instructions, taking proper advantage of the return address buffer.
* libguile/continuations.c (scm_i_continuation_to_frame): Record offsets
from stack top.
* libguile/control.c (scm_i_prompt_pop_abort_args_x): Adapt for reversed
order of arguments, and instead of relying on the abort to push on the
number of arguments, make the caller save the stack depth, which
allows us to compute the number of arguments ourselves.
(reify_partial_continuation, scm_c_abort): Adapt to reversed stack
order.
* libguile/dynstack.c (scm_dynstack_wind_prompt): Since we wind the
stack in a downward direction, subtract the reloc instead of adding
it.
* libguile/dynstack.h (SCM_F_DYNSTACK_PROMPT_ESCAPE_ONLY): Remove flag;
instead rely on prompt-establishing code to save the stack depth.
* libguile/eval.c (eval): Remove extraneous "volatile" declarations for
variables that are not re-set between the setjmp and any longjmp.
Adapt to save stack depth before instating the prompt.
* libguile/foreign.c (scm_i_foreign_call): Adapt to receive arguments in
reverse order.
* libguile/frames.c (frame_stack_top, scm_i_frame_stack_top): Adapt to
compute stack top instead of stack bottom.
(scm_c_frame_closure): Adapt to stack growth change.
(scm_frame_num_locals, scm_frame_local_ref, scm_frame_set_x): Use
union data type to access stack.
(RELOC): Reformat.
(scm_c_frame_previous): Adapt to stack growth change.
* libguile/frames.h: Adapt stack diagram to indicate that the stack
grows up.
(union scm_vm_stack_element): New data type used to access items on
the stack.
(SCM_FRAME_PREVIOUS_SP)
(SCM_FRAME_RETURN_ADDRESS, SCM_FRAME_SET_RETURN_ADDRESS)
(SCM_FRAME_DYNAMIC_LINK, SCM_FRAME_SET_DYNAMIC_LINK)
(SCM_FRAME_LOCAL, SCM_FRAME_NUM_LOCALS): Adapt to stack representation
change.
(SCM_FRAME_SLOT): New helper.
(SCM_VM_FRAME_FP, SCM_VM_FRAME_SP): Adapt to stack growth change.
* libguile/stacks.c (scm_make_stack): Record offsets from top of stack.
* libguile/throw.c (catch): Adapt to scm_i_prompt_pop_abort_args_x
change.
* libguile/vm-engine.c (ALLOC_FRAME, RESET_FRAME):
(FRAME_LOCALS_COUNT_FROM): Adapt to stack growth change.
(LOCAL_ADDRESS): Use SCM_FRAME_SLOT to get the address as the proper
data type.
(RETURN_ONE_VALUE, RETURN_VALUE_LIST): Adapt to stack growth change.
(apply): Shuffling up the SMOB apply args can cause the stack to
expand, so use ALLOC_FRAME instead of RESET_FRAME.
(vm_engine): Adapt for stack growth change.
* libguile/vm.c (vm_increase_sp, vm_push_sp, vm_restore_sp): Adapt to
stack representation change.
(scm_i_vm_cont_to_frame): Adapt to take offsets from the top.
(scm_i_vm_capture_stack): Adapt to capture from the top.
(vm_return_to_continuation_inner): Adapt for data type changes.
(vm_return_to_continuation): Likewise, and instead of looping, just
splat the saved arguments on with memcpy.
(vm_dispatch_hook): Adapt to receive arguments in the reverse order.
Adapt callers.
(vm_abort): There is never a tail argument. Adapt to stack
representation change.
(vm_reinstate_partial_continuation)
(vm_reinstate_partial_continuation_inner): Adapt to stack growth
change.
(allocate_stack, free_stack): Adapt to data type change.
(expand_stack): Don't try to mremap(), as you can't grow a mapping
from the bottom. Without knowing that there's a free mapping space
right below the old stack, which there usually isn't on Linux, we have
to copy. We can't use MAP_GROWSDOWN because Linux is buggy.
(make_vm): Adapt to stack representation changes.
(return_unused_stack_to_os): Round down instead of up, as the stack
grows down.
(scm_i_vm_mark_stack): Adapt to walk up the stack.
(scm_i_vm_free_stack): Adapt to scm_vm changes.
(vm_expand_stack_inner, reset_stack_limit, vm_expand_stack): Adapt to
the stack growing down.
(scm_call_n): Adapt to the stack growing down. Don't allow argv to
point into the stack.
* libguile/vm.h (struct scm_vm, struct scm_vm_cont): Adapt to hold the
stack top and bottom.
2015-09-22 10:24:30 +00:00
|
|
|
|
old_top = vp->stack_top;
|
2014-02-20 21:09:08 +01:00
|
|
|
|
new_size = vp->stack_size;
|
|
|
|
|
|
while (new_size < data->stack_size)
|
|
|
|
|
|
new_size *= 2;
|
|
|
|
|
|
|
VM stack grows downward
Adapt VM stack to grow downward. This will make native compilation look
more like the VM code, as we will be able to use native CALL
instructions, taking proper advantage of the return address buffer.
* libguile/continuations.c (scm_i_continuation_to_frame): Record offsets
from stack top.
* libguile/control.c (scm_i_prompt_pop_abort_args_x): Adapt for reversed
order of arguments, and instead of relying on the abort to push on the
number of arguments, make the caller save the stack depth, which
allows us to compute the number of arguments ourselves.
(reify_partial_continuation, scm_c_abort): Adapt to reversed stack
order.
* libguile/dynstack.c (scm_dynstack_wind_prompt): Since we wind the
stack in a downward direction, subtract the reloc instead of adding
it.
* libguile/dynstack.h (SCM_F_DYNSTACK_PROMPT_ESCAPE_ONLY): Remove flag;
instead rely on prompt-establishing code to save the stack depth.
* libguile/eval.c (eval): Remove extraneous "volatile" declarations for
variables that are not re-set between the setjmp and any longjmp.
Adapt to save stack depth before instating the prompt.
* libguile/foreign.c (scm_i_foreign_call): Adapt to receive arguments in
reverse order.
* libguile/frames.c (frame_stack_top, scm_i_frame_stack_top): Adapt to
compute stack top instead of stack bottom.
(scm_c_frame_closure): Adapt to stack growth change.
(scm_frame_num_locals, scm_frame_local_ref, scm_frame_set_x): Use
union data type to access stack.
(RELOC): Reformat.
(scm_c_frame_previous): Adapt to stack growth change.
* libguile/frames.h: Adapt stack diagram to indicate that the stack
grows up.
(union scm_vm_stack_element): New data type used to access items on
the stack.
(SCM_FRAME_PREVIOUS_SP)
(SCM_FRAME_RETURN_ADDRESS, SCM_FRAME_SET_RETURN_ADDRESS)
(SCM_FRAME_DYNAMIC_LINK, SCM_FRAME_SET_DYNAMIC_LINK)
(SCM_FRAME_LOCAL, SCM_FRAME_NUM_LOCALS): Adapt to stack representation
change.
(SCM_FRAME_SLOT): New helper.
(SCM_VM_FRAME_FP, SCM_VM_FRAME_SP): Adapt to stack growth change.
* libguile/stacks.c (scm_make_stack): Record offsets from top of stack.
* libguile/throw.c (catch): Adapt to scm_i_prompt_pop_abort_args_x
change.
* libguile/vm-engine.c (ALLOC_FRAME, RESET_FRAME):
(FRAME_LOCALS_COUNT_FROM): Adapt to stack growth change.
(LOCAL_ADDRESS): Use SCM_FRAME_SLOT to get the address as the proper
data type.
(RETURN_ONE_VALUE, RETURN_VALUE_LIST): Adapt to stack growth change.
(apply): Shuffling up the SMOB apply args can cause the stack to
expand, so use ALLOC_FRAME instead of RESET_FRAME.
(vm_engine): Adapt for stack growth change.
* libguile/vm.c (vm_increase_sp, vm_push_sp, vm_restore_sp): Adapt to
stack representation change.
(scm_i_vm_cont_to_frame): Adapt to take offsets from the top.
(scm_i_vm_capture_stack): Adapt to capture from the top.
(vm_return_to_continuation_inner): Adapt for data type changes.
(vm_return_to_continuation): Likewise, and instead of looping, just
splat the saved arguments on with memcpy.
(vm_dispatch_hook): Adapt to receive arguments in the reverse order.
Adapt callers.
(vm_abort): There is never a tail argument. Adapt to stack
representation change.
(vm_reinstate_partial_continuation)
(vm_reinstate_partial_continuation_inner): Adapt to stack growth
change.
(allocate_stack, free_stack): Adapt to data type change.
(expand_stack): Don't try to mremap(), as you can't grow a mapping
from the bottom. Without knowing that there's a free mapping space
right below the old stack, which there usually isn't on Linux, we have
to copy. We can't use MAP_GROWSDOWN because Linux is buggy.
(make_vm): Adapt to stack representation changes.
(return_unused_stack_to_os): Round down instead of up, as the stack
grows down.
(scm_i_vm_mark_stack): Adapt to walk up the stack.
(scm_i_vm_free_stack): Adapt to scm_vm changes.
(vm_expand_stack_inner, reset_stack_limit, vm_expand_stack): Adapt to
the stack growing down.
(scm_call_n): Adapt to the stack growing down. Don't allow argv to
point into the stack.
* libguile/vm.h (struct scm_vm, struct scm_vm_cont): Adapt to hold the
stack top and bottom.
2015-09-22 10:24:30 +00:00
|
|
|
|
new_bottom = expand_stack (vp->stack_bottom, vp->stack_size, new_size);
|
|
|
|
|
|
if (!new_bottom)
|
2014-02-20 21:09:08 +01:00
|
|
|
|
return NULL;
|
|
|
|
|
|
|
VM stack grows downward
Adapt VM stack to grow downward. This will make native compilation look
more like the VM code, as we will be able to use native CALL
instructions, taking proper advantage of the return address buffer.
* libguile/continuations.c (scm_i_continuation_to_frame): Record offsets
from stack top.
* libguile/control.c (scm_i_prompt_pop_abort_args_x): Adapt for reversed
order of arguments, and instead of relying on the abort to push on the
number of arguments, make the caller save the stack depth, which
allows us to compute the number of arguments ourselves.
(reify_partial_continuation, scm_c_abort): Adapt to reversed stack
order.
* libguile/dynstack.c (scm_dynstack_wind_prompt): Since we wind the
stack in a downward direction, subtract the reloc instead of adding
it.
* libguile/dynstack.h (SCM_F_DYNSTACK_PROMPT_ESCAPE_ONLY): Remove flag;
instead rely on prompt-establishing code to save the stack depth.
* libguile/eval.c (eval): Remove extraneous "volatile" declarations for
variables that are not re-set between the setjmp and any longjmp.
Adapt to save stack depth before instating the prompt.
* libguile/foreign.c (scm_i_foreign_call): Adapt to receive arguments in
reverse order.
* libguile/frames.c (frame_stack_top, scm_i_frame_stack_top): Adapt to
compute stack top instead of stack bottom.
(scm_c_frame_closure): Adapt to stack growth change.
(scm_frame_num_locals, scm_frame_local_ref, scm_frame_set_x): Use
union data type to access stack.
(RELOC): Reformat.
(scm_c_frame_previous): Adapt to stack growth change.
* libguile/frames.h: Adapt stack diagram to indicate that the stack
grows up.
(union scm_vm_stack_element): New data type used to access items on
the stack.
(SCM_FRAME_PREVIOUS_SP)
(SCM_FRAME_RETURN_ADDRESS, SCM_FRAME_SET_RETURN_ADDRESS)
(SCM_FRAME_DYNAMIC_LINK, SCM_FRAME_SET_DYNAMIC_LINK)
(SCM_FRAME_LOCAL, SCM_FRAME_NUM_LOCALS): Adapt to stack representation
change.
(SCM_FRAME_SLOT): New helper.
(SCM_VM_FRAME_FP, SCM_VM_FRAME_SP): Adapt to stack growth change.
* libguile/stacks.c (scm_make_stack): Record offsets from top of stack.
* libguile/throw.c (catch): Adapt to scm_i_prompt_pop_abort_args_x
change.
* libguile/vm-engine.c (ALLOC_FRAME, RESET_FRAME):
(FRAME_LOCALS_COUNT_FROM): Adapt to stack growth change.
(LOCAL_ADDRESS): Use SCM_FRAME_SLOT to get the address as the proper
data type.
(RETURN_ONE_VALUE, RETURN_VALUE_LIST): Adapt to stack growth change.
(apply): Shuffling up the SMOB apply args can cause the stack to
expand, so use ALLOC_FRAME instead of RESET_FRAME.
(vm_engine): Adapt for stack growth change.
* libguile/vm.c (vm_increase_sp, vm_push_sp, vm_restore_sp): Adapt to
stack representation change.
(scm_i_vm_cont_to_frame): Adapt to take offsets from the top.
(scm_i_vm_capture_stack): Adapt to capture from the top.
(vm_return_to_continuation_inner): Adapt for data type changes.
(vm_return_to_continuation): Likewise, and instead of looping, just
splat the saved arguments on with memcpy.
(vm_dispatch_hook): Adapt to receive arguments in the reverse order.
Adapt callers.
(vm_abort): There is never a tail argument. Adapt to stack
representation change.
(vm_reinstate_partial_continuation)
(vm_reinstate_partial_continuation_inner): Adapt to stack growth
change.
(allocate_stack, free_stack): Adapt to data type change.
(expand_stack): Don't try to mremap(), as you can't grow a mapping
from the bottom. Without knowing that there's a free mapping space
right below the old stack, which there usually isn't on Linux, we have
to copy. We can't use MAP_GROWSDOWN because Linux is buggy.
(make_vm): Adapt to stack representation changes.
(return_unused_stack_to_os): Round down instead of up, as the stack
grows down.
(scm_i_vm_mark_stack): Adapt to walk up the stack.
(scm_i_vm_free_stack): Adapt to scm_vm changes.
(vm_expand_stack_inner, reset_stack_limit, vm_expand_stack): Adapt to
the stack growing down.
(scm_call_n): Adapt to the stack growing down. Don't allow argv to
point into the stack.
* libguile/vm.h (struct scm_vm, struct scm_vm_cont): Adapt to hold the
stack top and bottom.
2015-09-22 10:24:30 +00:00
|
|
|
|
vp->stack_bottom = new_bottom;
|
2014-02-20 21:09:08 +01:00
|
|
|
|
vp->stack_size = new_size;
|
VM stack grows downward
Adapt VM stack to grow downward. This will make native compilation look
more like the VM code, as we will be able to use native CALL
instructions, taking proper advantage of the return address buffer.
* libguile/continuations.c (scm_i_continuation_to_frame): Record offsets
from stack top.
* libguile/control.c (scm_i_prompt_pop_abort_args_x): Adapt for reversed
order of arguments, and instead of relying on the abort to push on the
number of arguments, make the caller save the stack depth, which
allows us to compute the number of arguments ourselves.
(reify_partial_continuation, scm_c_abort): Adapt to reversed stack
order.
* libguile/dynstack.c (scm_dynstack_wind_prompt): Since we wind the
stack in a downward direction, subtract the reloc instead of adding
it.
* libguile/dynstack.h (SCM_F_DYNSTACK_PROMPT_ESCAPE_ONLY): Remove flag;
instead rely on prompt-establishing code to save the stack depth.
* libguile/eval.c (eval): Remove extraneous "volatile" declarations for
variables that are not re-set between the setjmp and any longjmp.
Adapt to save stack depth before instating the prompt.
* libguile/foreign.c (scm_i_foreign_call): Adapt to receive arguments in
reverse order.
* libguile/frames.c (frame_stack_top, scm_i_frame_stack_top): Adapt to
compute stack top instead of stack bottom.
(scm_c_frame_closure): Adapt to stack growth change.
(scm_frame_num_locals, scm_frame_local_ref, scm_frame_set_x): Use
union data type to access stack.
(RELOC): Reformat.
(scm_c_frame_previous): Adapt to stack growth change.
* libguile/frames.h: Adapt stack diagram to indicate that the stack
grows up.
(union scm_vm_stack_element): New data type used to access items on
the stack.
(SCM_FRAME_PREVIOUS_SP)
(SCM_FRAME_RETURN_ADDRESS, SCM_FRAME_SET_RETURN_ADDRESS)
(SCM_FRAME_DYNAMIC_LINK, SCM_FRAME_SET_DYNAMIC_LINK)
(SCM_FRAME_LOCAL, SCM_FRAME_NUM_LOCALS): Adapt to stack representation
change.
(SCM_FRAME_SLOT): New helper.
(SCM_VM_FRAME_FP, SCM_VM_FRAME_SP): Adapt to stack growth change.
* libguile/stacks.c (scm_make_stack): Record offsets from top of stack.
* libguile/throw.c (catch): Adapt to scm_i_prompt_pop_abort_args_x
change.
* libguile/vm-engine.c (ALLOC_FRAME, RESET_FRAME):
(FRAME_LOCALS_COUNT_FROM): Adapt to stack growth change.
(LOCAL_ADDRESS): Use SCM_FRAME_SLOT to get the address as the proper
data type.
(RETURN_ONE_VALUE, RETURN_VALUE_LIST): Adapt to stack growth change.
(apply): Shuffling up the SMOB apply args can cause the stack to
expand, so use ALLOC_FRAME instead of RESET_FRAME.
(vm_engine): Adapt for stack growth change.
* libguile/vm.c (vm_increase_sp, vm_push_sp, vm_restore_sp): Adapt to
stack representation change.
(scm_i_vm_cont_to_frame): Adapt to take offsets from the top.
(scm_i_vm_capture_stack): Adapt to capture from the top.
(vm_return_to_continuation_inner): Adapt for data type changes.
(vm_return_to_continuation): Likewise, and instead of looping, just
splat the saved arguments on with memcpy.
(vm_dispatch_hook): Adapt to receive arguments in the reverse order.
Adapt callers.
(vm_abort): There is never a tail argument. Adapt to stack
representation change.
(vm_reinstate_partial_continuation)
(vm_reinstate_partial_continuation_inner): Adapt to stack growth
change.
(allocate_stack, free_stack): Adapt to data type change.
(expand_stack): Don't try to mremap(), as you can't grow a mapping
from the bottom. Without knowing that there's a free mapping space
right below the old stack, which there usually isn't on Linux, we have
to copy. We can't use MAP_GROWSDOWN because Linux is buggy.
(make_vm): Adapt to stack representation changes.
(return_unused_stack_to_os): Round down instead of up, as the stack
grows down.
(scm_i_vm_mark_stack): Adapt to walk up the stack.
(scm_i_vm_free_stack): Adapt to scm_vm changes.
(vm_expand_stack_inner, reset_stack_limit, vm_expand_stack): Adapt to
the stack growing down.
(scm_call_n): Adapt to the stack growing down. Don't allow argv to
point into the stack.
* libguile/vm.h (struct scm_vm, struct scm_vm_cont): Adapt to hold the
stack top and bottom.
2015-09-22 10:24:30 +00:00
|
|
|
|
vp->stack_top = vp->stack_bottom + new_size;
|
|
|
|
|
|
vp->stack_limit = vp->stack_bottom;
|
|
|
|
|
|
reloc = vp->stack_top - old_top;
|
2014-02-20 21:09:08 +01:00
|
|
|
|
|
2015-10-18 22:59:23 +02:00
|
|
|
|
if (vp->fp)
|
|
|
|
|
|
vp->fp += reloc;
|
|
|
|
|
|
data->new_sp += reloc;
|
2014-02-20 21:09:08 +01:00
|
|
|
|
|
VM stack grows downward
Adapt VM stack to grow downward. This will make native compilation look
more like the VM code, as we will be able to use native CALL
instructions, taking proper advantage of the return address buffer.
* libguile/continuations.c (scm_i_continuation_to_frame): Record offsets
from stack top.
* libguile/control.c (scm_i_prompt_pop_abort_args_x): Adapt for reversed
order of arguments, and instead of relying on the abort to push on the
number of arguments, make the caller save the stack depth, which
allows us to compute the number of arguments ourselves.
(reify_partial_continuation, scm_c_abort): Adapt to reversed stack
order.
* libguile/dynstack.c (scm_dynstack_wind_prompt): Since we wind the
stack in a downward direction, subtract the reloc instead of adding
it.
* libguile/dynstack.h (SCM_F_DYNSTACK_PROMPT_ESCAPE_ONLY): Remove flag;
instead rely on prompt-establishing code to save the stack depth.
* libguile/eval.c (eval): Remove extraneous "volatile" declarations for
variables that are not re-set between the setjmp and any longjmp.
Adapt to save stack depth before instating the prompt.
* libguile/foreign.c (scm_i_foreign_call): Adapt to receive arguments in
reverse order.
* libguile/frames.c (frame_stack_top, scm_i_frame_stack_top): Adapt to
compute stack top instead of stack bottom.
(scm_c_frame_closure): Adapt to stack growth change.
(scm_frame_num_locals, scm_frame_local_ref, scm_frame_set_x): Use
union data type to access stack.
(RELOC): Reformat.
(scm_c_frame_previous): Adapt to stack growth change.
* libguile/frames.h: Adapt stack diagram to indicate that the stack
grows up.
(union scm_vm_stack_element): New data type used to access items on
the stack.
(SCM_FRAME_PREVIOUS_SP)
(SCM_FRAME_RETURN_ADDRESS, SCM_FRAME_SET_RETURN_ADDRESS)
(SCM_FRAME_DYNAMIC_LINK, SCM_FRAME_SET_DYNAMIC_LINK)
(SCM_FRAME_LOCAL, SCM_FRAME_NUM_LOCALS): Adapt to stack representation
change.
(SCM_FRAME_SLOT): New helper.
(SCM_VM_FRAME_FP, SCM_VM_FRAME_SP): Adapt to stack growth change.
* libguile/stacks.c (scm_make_stack): Record offsets from top of stack.
* libguile/throw.c (catch): Adapt to scm_i_prompt_pop_abort_args_x
change.
* libguile/vm-engine.c (ALLOC_FRAME, RESET_FRAME):
(FRAME_LOCALS_COUNT_FROM): Adapt to stack growth change.
(LOCAL_ADDRESS): Use SCM_FRAME_SLOT to get the address as the proper
data type.
(RETURN_ONE_VALUE, RETURN_VALUE_LIST): Adapt to stack growth change.
(apply): Shuffling up the SMOB apply args can cause the stack to
expand, so use ALLOC_FRAME instead of RESET_FRAME.
(vm_engine): Adapt for stack growth change.
* libguile/vm.c (vm_increase_sp, vm_push_sp, vm_restore_sp): Adapt to
stack representation change.
(scm_i_vm_cont_to_frame): Adapt to take offsets from the top.
(scm_i_vm_capture_stack): Adapt to capture from the top.
(vm_return_to_continuation_inner): Adapt for data type changes.
(vm_return_to_continuation): Likewise, and instead of looping, just
splat the saved arguments on with memcpy.
(vm_dispatch_hook): Adapt to receive arguments in the reverse order.
Adapt callers.
(vm_abort): There is never a tail argument. Adapt to stack
representation change.
(vm_reinstate_partial_continuation)
(vm_reinstate_partial_continuation_inner): Adapt to stack growth
change.
(allocate_stack, free_stack): Adapt to data type change.
(expand_stack): Don't try to mremap(), as you can't grow a mapping
from the bottom. Without knowing that there's a free mapping space
right below the old stack, which there usually isn't on Linux, we have
to copy. We can't use MAP_GROWSDOWN because Linux is buggy.
(make_vm): Adapt to stack representation changes.
(return_unused_stack_to_os): Round down instead of up, as the stack
grows down.
(scm_i_vm_mark_stack): Adapt to walk up the stack.
(scm_i_vm_free_stack): Adapt to scm_vm changes.
(vm_expand_stack_inner, reset_stack_limit, vm_expand_stack): Adapt to
the stack growing down.
(scm_call_n): Adapt to the stack growing down. Don't allow argv to
point into the stack.
* libguile/vm.h (struct scm_vm, struct scm_vm_cont): Adapt to hold the
stack top and bottom.
2015-09-22 10:24:30 +00:00
|
|
|
|
return new_bottom;
|
2014-02-20 21:09:08 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2018-06-21 08:43:47 +02:00
|
|
|
|
static ptrdiff_t
|
2014-03-12 17:18:13 +01:00
|
|
|
|
current_overflow_size (struct scm_vm *vp)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (scm_is_pair (vp->overflow_handler_stack))
|
|
|
|
|
|
return scm_to_ptrdiff_t (scm_caar (vp->overflow_handler_stack));
|
|
|
|
|
|
return -1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int
|
2018-06-21 08:43:47 +02:00
|
|
|
|
should_handle_stack_overflow (struct scm_vm *vp, ptrdiff_t stack_size)
|
2014-03-12 17:18:13 +01:00
|
|
|
|
{
|
2018-06-21 08:43:47 +02:00
|
|
|
|
ptrdiff_t overflow_size = current_overflow_size (vp);
|
2014-03-12 17:18:13 +01:00
|
|
|
|
return overflow_size >= 0 && stack_size >= overflow_size;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
|
reset_stack_limit (struct scm_vm *vp)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (should_handle_stack_overflow (vp, vp->stack_size))
|
VM stack grows downward
Adapt VM stack to grow downward. This will make native compilation look
more like the VM code, as we will be able to use native CALL
instructions, taking proper advantage of the return address buffer.
* libguile/continuations.c (scm_i_continuation_to_frame): Record offsets
from stack top.
* libguile/control.c (scm_i_prompt_pop_abort_args_x): Adapt for reversed
order of arguments, and instead of relying on the abort to push on the
number of arguments, make the caller save the stack depth, which
allows us to compute the number of arguments ourselves.
(reify_partial_continuation, scm_c_abort): Adapt to reversed stack
order.
* libguile/dynstack.c (scm_dynstack_wind_prompt): Since we wind the
stack in a downward direction, subtract the reloc instead of adding
it.
* libguile/dynstack.h (SCM_F_DYNSTACK_PROMPT_ESCAPE_ONLY): Remove flag;
instead rely on prompt-establishing code to save the stack depth.
* libguile/eval.c (eval): Remove extraneous "volatile" declarations for
variables that are not re-set between the setjmp and any longjmp.
Adapt to save stack depth before instating the prompt.
* libguile/foreign.c (scm_i_foreign_call): Adapt to receive arguments in
reverse order.
* libguile/frames.c (frame_stack_top, scm_i_frame_stack_top): Adapt to
compute stack top instead of stack bottom.
(scm_c_frame_closure): Adapt to stack growth change.
(scm_frame_num_locals, scm_frame_local_ref, scm_frame_set_x): Use
union data type to access stack.
(RELOC): Reformat.
(scm_c_frame_previous): Adapt to stack growth change.
* libguile/frames.h: Adapt stack diagram to indicate that the stack
grows up.
(union scm_vm_stack_element): New data type used to access items on
the stack.
(SCM_FRAME_PREVIOUS_SP)
(SCM_FRAME_RETURN_ADDRESS, SCM_FRAME_SET_RETURN_ADDRESS)
(SCM_FRAME_DYNAMIC_LINK, SCM_FRAME_SET_DYNAMIC_LINK)
(SCM_FRAME_LOCAL, SCM_FRAME_NUM_LOCALS): Adapt to stack representation
change.
(SCM_FRAME_SLOT): New helper.
(SCM_VM_FRAME_FP, SCM_VM_FRAME_SP): Adapt to stack growth change.
* libguile/stacks.c (scm_make_stack): Record offsets from top of stack.
* libguile/throw.c (catch): Adapt to scm_i_prompt_pop_abort_args_x
change.
* libguile/vm-engine.c (ALLOC_FRAME, RESET_FRAME):
(FRAME_LOCALS_COUNT_FROM): Adapt to stack growth change.
(LOCAL_ADDRESS): Use SCM_FRAME_SLOT to get the address as the proper
data type.
(RETURN_ONE_VALUE, RETURN_VALUE_LIST): Adapt to stack growth change.
(apply): Shuffling up the SMOB apply args can cause the stack to
expand, so use ALLOC_FRAME instead of RESET_FRAME.
(vm_engine): Adapt for stack growth change.
* libguile/vm.c (vm_increase_sp, vm_push_sp, vm_restore_sp): Adapt to
stack representation change.
(scm_i_vm_cont_to_frame): Adapt to take offsets from the top.
(scm_i_vm_capture_stack): Adapt to capture from the top.
(vm_return_to_continuation_inner): Adapt for data type changes.
(vm_return_to_continuation): Likewise, and instead of looping, just
splat the saved arguments on with memcpy.
(vm_dispatch_hook): Adapt to receive arguments in the reverse order.
Adapt callers.
(vm_abort): There is never a tail argument. Adapt to stack
representation change.
(vm_reinstate_partial_continuation)
(vm_reinstate_partial_continuation_inner): Adapt to stack growth
change.
(allocate_stack, free_stack): Adapt to data type change.
(expand_stack): Don't try to mremap(), as you can't grow a mapping
from the bottom. Without knowing that there's a free mapping space
right below the old stack, which there usually isn't on Linux, we have
to copy. We can't use MAP_GROWSDOWN because Linux is buggy.
(make_vm): Adapt to stack representation changes.
(return_unused_stack_to_os): Round down instead of up, as the stack
grows down.
(scm_i_vm_mark_stack): Adapt to walk up the stack.
(scm_i_vm_free_stack): Adapt to scm_vm changes.
(vm_expand_stack_inner, reset_stack_limit, vm_expand_stack): Adapt to
the stack growing down.
(scm_call_n): Adapt to the stack growing down. Don't allow argv to
point into the stack.
* libguile/vm.h (struct scm_vm, struct scm_vm_cont): Adapt to hold the
stack top and bottom.
2015-09-22 10:24:30 +00:00
|
|
|
|
vp->stack_limit = vp->stack_top - current_overflow_size (vp);
|
2014-03-12 17:18:13 +01:00
|
|
|
|
else
|
VM stack grows downward
Adapt VM stack to grow downward. This will make native compilation look
more like the VM code, as we will be able to use native CALL
instructions, taking proper advantage of the return address buffer.
* libguile/continuations.c (scm_i_continuation_to_frame): Record offsets
from stack top.
* libguile/control.c (scm_i_prompt_pop_abort_args_x): Adapt for reversed
order of arguments, and instead of relying on the abort to push on the
number of arguments, make the caller save the stack depth, which
allows us to compute the number of arguments ourselves.
(reify_partial_continuation, scm_c_abort): Adapt to reversed stack
order.
* libguile/dynstack.c (scm_dynstack_wind_prompt): Since we wind the
stack in a downward direction, subtract the reloc instead of adding
it.
* libguile/dynstack.h (SCM_F_DYNSTACK_PROMPT_ESCAPE_ONLY): Remove flag;
instead rely on prompt-establishing code to save the stack depth.
* libguile/eval.c (eval): Remove extraneous "volatile" declarations for
variables that are not re-set between the setjmp and any longjmp.
Adapt to save stack depth before instating the prompt.
* libguile/foreign.c (scm_i_foreign_call): Adapt to receive arguments in
reverse order.
* libguile/frames.c (frame_stack_top, scm_i_frame_stack_top): Adapt to
compute stack top instead of stack bottom.
(scm_c_frame_closure): Adapt to stack growth change.
(scm_frame_num_locals, scm_frame_local_ref, scm_frame_set_x): Use
union data type to access stack.
(RELOC): Reformat.
(scm_c_frame_previous): Adapt to stack growth change.
* libguile/frames.h: Adapt stack diagram to indicate that the stack
grows up.
(union scm_vm_stack_element): New data type used to access items on
the stack.
(SCM_FRAME_PREVIOUS_SP)
(SCM_FRAME_RETURN_ADDRESS, SCM_FRAME_SET_RETURN_ADDRESS)
(SCM_FRAME_DYNAMIC_LINK, SCM_FRAME_SET_DYNAMIC_LINK)
(SCM_FRAME_LOCAL, SCM_FRAME_NUM_LOCALS): Adapt to stack representation
change.
(SCM_FRAME_SLOT): New helper.
(SCM_VM_FRAME_FP, SCM_VM_FRAME_SP): Adapt to stack growth change.
* libguile/stacks.c (scm_make_stack): Record offsets from top of stack.
* libguile/throw.c (catch): Adapt to scm_i_prompt_pop_abort_args_x
change.
* libguile/vm-engine.c (ALLOC_FRAME, RESET_FRAME):
(FRAME_LOCALS_COUNT_FROM): Adapt to stack growth change.
(LOCAL_ADDRESS): Use SCM_FRAME_SLOT to get the address as the proper
data type.
(RETURN_ONE_VALUE, RETURN_VALUE_LIST): Adapt to stack growth change.
(apply): Shuffling up the SMOB apply args can cause the stack to
expand, so use ALLOC_FRAME instead of RESET_FRAME.
(vm_engine): Adapt for stack growth change.
* libguile/vm.c (vm_increase_sp, vm_push_sp, vm_restore_sp): Adapt to
stack representation change.
(scm_i_vm_cont_to_frame): Adapt to take offsets from the top.
(scm_i_vm_capture_stack): Adapt to capture from the top.
(vm_return_to_continuation_inner): Adapt for data type changes.
(vm_return_to_continuation): Likewise, and instead of looping, just
splat the saved arguments on with memcpy.
(vm_dispatch_hook): Adapt to receive arguments in the reverse order.
Adapt callers.
(vm_abort): There is never a tail argument. Adapt to stack
representation change.
(vm_reinstate_partial_continuation)
(vm_reinstate_partial_continuation_inner): Adapt to stack growth
change.
(allocate_stack, free_stack): Adapt to data type change.
(expand_stack): Don't try to mremap(), as you can't grow a mapping
from the bottom. Without knowing that there's a free mapping space
right below the old stack, which there usually isn't on Linux, we have
to copy. We can't use MAP_GROWSDOWN because Linux is buggy.
(make_vm): Adapt to stack representation changes.
(return_unused_stack_to_os): Round down instead of up, as the stack
grows down.
(scm_i_vm_mark_stack): Adapt to walk up the stack.
(scm_i_vm_free_stack): Adapt to scm_vm changes.
(vm_expand_stack_inner, reset_stack_limit, vm_expand_stack): Adapt to
the stack growing down.
(scm_call_n): Adapt to the stack growing down. Don't allow argv to
point into the stack.
* libguile/vm.h (struct scm_vm, struct scm_vm_cont): Adapt to hold the
stack top and bottom.
2015-09-22 10:24:30 +00:00
|
|
|
|
vp->stack_limit = vp->stack_bottom;
|
2014-03-12 17:18:13 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
struct overflow_handler_data
|
|
|
|
|
|
{
|
|
|
|
|
|
struct scm_vm *vp;
|
|
|
|
|
|
SCM overflow_handler_stack;
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
|
wind_overflow_handler (void *ptr)
|
|
|
|
|
|
{
|
|
|
|
|
|
struct overflow_handler_data *data = ptr;
|
|
|
|
|
|
|
|
|
|
|
|
data->vp->overflow_handler_stack = data->overflow_handler_stack;
|
|
|
|
|
|
|
|
|
|
|
|
reset_stack_limit (data->vp);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
|
unwind_overflow_handler (void *ptr)
|
|
|
|
|
|
{
|
|
|
|
|
|
struct overflow_handler_data *data = ptr;
|
|
|
|
|
|
|
|
|
|
|
|
data->vp->overflow_handler_stack = scm_cdr (data->overflow_handler_stack);
|
|
|
|
|
|
|
|
|
|
|
|
reset_stack_limit (data->vp);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2013-11-22 17:31:07 +01:00
|
|
|
|
static void
|
VM stack grows downward
Adapt VM stack to grow downward. This will make native compilation look
more like the VM code, as we will be able to use native CALL
instructions, taking proper advantage of the return address buffer.
* libguile/continuations.c (scm_i_continuation_to_frame): Record offsets
from stack top.
* libguile/control.c (scm_i_prompt_pop_abort_args_x): Adapt for reversed
order of arguments, and instead of relying on the abort to push on the
number of arguments, make the caller save the stack depth, which
allows us to compute the number of arguments ourselves.
(reify_partial_continuation, scm_c_abort): Adapt to reversed stack
order.
* libguile/dynstack.c (scm_dynstack_wind_prompt): Since we wind the
stack in a downward direction, subtract the reloc instead of adding
it.
* libguile/dynstack.h (SCM_F_DYNSTACK_PROMPT_ESCAPE_ONLY): Remove flag;
instead rely on prompt-establishing code to save the stack depth.
* libguile/eval.c (eval): Remove extraneous "volatile" declarations for
variables that are not re-set between the setjmp and any longjmp.
Adapt to save stack depth before instating the prompt.
* libguile/foreign.c (scm_i_foreign_call): Adapt to receive arguments in
reverse order.
* libguile/frames.c (frame_stack_top, scm_i_frame_stack_top): Adapt to
compute stack top instead of stack bottom.
(scm_c_frame_closure): Adapt to stack growth change.
(scm_frame_num_locals, scm_frame_local_ref, scm_frame_set_x): Use
union data type to access stack.
(RELOC): Reformat.
(scm_c_frame_previous): Adapt to stack growth change.
* libguile/frames.h: Adapt stack diagram to indicate that the stack
grows up.
(union scm_vm_stack_element): New data type used to access items on
the stack.
(SCM_FRAME_PREVIOUS_SP)
(SCM_FRAME_RETURN_ADDRESS, SCM_FRAME_SET_RETURN_ADDRESS)
(SCM_FRAME_DYNAMIC_LINK, SCM_FRAME_SET_DYNAMIC_LINK)
(SCM_FRAME_LOCAL, SCM_FRAME_NUM_LOCALS): Adapt to stack representation
change.
(SCM_FRAME_SLOT): New helper.
(SCM_VM_FRAME_FP, SCM_VM_FRAME_SP): Adapt to stack growth change.
* libguile/stacks.c (scm_make_stack): Record offsets from top of stack.
* libguile/throw.c (catch): Adapt to scm_i_prompt_pop_abort_args_x
change.
* libguile/vm-engine.c (ALLOC_FRAME, RESET_FRAME):
(FRAME_LOCALS_COUNT_FROM): Adapt to stack growth change.
(LOCAL_ADDRESS): Use SCM_FRAME_SLOT to get the address as the proper
data type.
(RETURN_ONE_VALUE, RETURN_VALUE_LIST): Adapt to stack growth change.
(apply): Shuffling up the SMOB apply args can cause the stack to
expand, so use ALLOC_FRAME instead of RESET_FRAME.
(vm_engine): Adapt for stack growth change.
* libguile/vm.c (vm_increase_sp, vm_push_sp, vm_restore_sp): Adapt to
stack representation change.
(scm_i_vm_cont_to_frame): Adapt to take offsets from the top.
(scm_i_vm_capture_stack): Adapt to capture from the top.
(vm_return_to_continuation_inner): Adapt for data type changes.
(vm_return_to_continuation): Likewise, and instead of looping, just
splat the saved arguments on with memcpy.
(vm_dispatch_hook): Adapt to receive arguments in the reverse order.
Adapt callers.
(vm_abort): There is never a tail argument. Adapt to stack
representation change.
(vm_reinstate_partial_continuation)
(vm_reinstate_partial_continuation_inner): Adapt to stack growth
change.
(allocate_stack, free_stack): Adapt to data type change.
(expand_stack): Don't try to mremap(), as you can't grow a mapping
from the bottom. Without knowing that there's a free mapping space
right below the old stack, which there usually isn't on Linux, we have
to copy. We can't use MAP_GROWSDOWN because Linux is buggy.
(make_vm): Adapt to stack representation changes.
(return_unused_stack_to_os): Round down instead of up, as the stack
grows down.
(scm_i_vm_mark_stack): Adapt to walk up the stack.
(scm_i_vm_free_stack): Adapt to scm_vm changes.
(vm_expand_stack_inner, reset_stack_limit, vm_expand_stack): Adapt to
the stack growing down.
(scm_call_n): Adapt to the stack growing down. Don't allow argv to
point into the stack.
* libguile/vm.h (struct scm_vm, struct scm_vm_cont): Adapt to hold the
stack top and bottom.
2015-09-22 10:24:30 +00:00
|
|
|
|
vm_expand_stack (struct scm_vm *vp, union scm_vm_stack_element *new_sp)
|
2013-11-22 17:31:07 +01:00
|
|
|
|
{
|
2018-06-21 08:43:47 +02:00
|
|
|
|
ptrdiff_t stack_size = vp->stack_top - new_sp;
|
2013-11-22 17:31:07 +01:00
|
|
|
|
|
|
|
|
|
|
if (stack_size > vp->stack_size)
|
|
|
|
|
|
{
|
2014-02-20 21:09:08 +01:00
|
|
|
|
struct vm_expand_stack_data data;
|
2014-02-19 11:01:39 +01:00
|
|
|
|
|
2014-02-20 21:09:08 +01:00
|
|
|
|
data.vp = vp;
|
|
|
|
|
|
data.stack_size = stack_size;
|
|
|
|
|
|
data.new_sp = new_sp;
|
|
|
|
|
|
|
|
|
|
|
|
if (!GC_call_with_alloc_lock (vm_expand_stack_inner, &data))
|
2014-03-12 17:18:13 +01:00
|
|
|
|
/* Throw an unwind-only exception. */
|
2014-02-20 21:09:08 +01:00
|
|
|
|
scm_report_stack_overflow ();
|
2013-11-22 17:31:07 +01:00
|
|
|
|
|
2014-02-20 21:09:08 +01:00
|
|
|
|
new_sp = data.new_sp;
|
2013-11-22 17:31:07 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2019-12-07 22:54:32 +01:00
|
|
|
|
vp->sp = new_sp;
|
2014-02-20 10:43:40 +01:00
|
|
|
|
|
2014-03-12 17:18:13 +01:00
|
|
|
|
if (should_handle_stack_overflow (vp, stack_size))
|
2013-11-22 17:31:07 +01:00
|
|
|
|
{
|
2014-03-12 17:18:13 +01:00
|
|
|
|
SCM more_stack, new_limit;
|
|
|
|
|
|
|
|
|
|
|
|
struct overflow_handler_data data;
|
|
|
|
|
|
data.vp = vp;
|
|
|
|
|
|
data.overflow_handler_stack = vp->overflow_handler_stack;
|
2013-11-22 17:31:07 +01:00
|
|
|
|
|
2014-03-12 17:18:13 +01:00
|
|
|
|
scm_dynwind_begin (SCM_F_DYNWIND_REWINDABLE);
|
2013-11-22 17:31:07 +01:00
|
|
|
|
|
2014-03-12 17:18:13 +01:00
|
|
|
|
scm_dynwind_rewind_handler (unwind_overflow_handler, &data,
|
|
|
|
|
|
SCM_F_WIND_EXPLICITLY);
|
|
|
|
|
|
scm_dynwind_unwind_handler (wind_overflow_handler, &data,
|
|
|
|
|
|
SCM_F_WIND_EXPLICITLY);
|
2013-11-22 17:31:07 +01:00
|
|
|
|
|
2014-03-12 17:18:13 +01:00
|
|
|
|
/* Call the overflow handler. */
|
|
|
|
|
|
more_stack = scm_call_0 (scm_cdar (data.overflow_handler_stack));
|
|
|
|
|
|
|
|
|
|
|
|
/* If the overflow handler returns, its return value should be an
|
|
|
|
|
|
integral number of words from the outer stack limit to transfer
|
|
|
|
|
|
to the inner limit. */
|
|
|
|
|
|
if (scm_to_ptrdiff_t (more_stack) <= 0)
|
|
|
|
|
|
scm_out_of_range (NULL, more_stack);
|
|
|
|
|
|
new_limit = scm_sum (scm_caar (data.overflow_handler_stack), more_stack);
|
|
|
|
|
|
if (scm_is_pair (scm_cdr (data.overflow_handler_stack)))
|
|
|
|
|
|
new_limit = scm_min (new_limit,
|
|
|
|
|
|
scm_caadr (data.overflow_handler_stack));
|
|
|
|
|
|
|
|
|
|
|
|
/* Ensure the new limit is in range. */
|
|
|
|
|
|
scm_to_ptrdiff_t (new_limit);
|
|
|
|
|
|
|
|
|
|
|
|
/* Increase the limit that we will restore. */
|
|
|
|
|
|
scm_set_car_x (scm_car (data.overflow_handler_stack), new_limit);
|
2013-11-22 17:31:07 +01:00
|
|
|
|
|
2014-03-12 17:18:13 +01:00
|
|
|
|
scm_dynwind_end ();
|
|
|
|
|
|
|
VM stack grows downward
Adapt VM stack to grow downward. This will make native compilation look
more like the VM code, as we will be able to use native CALL
instructions, taking proper advantage of the return address buffer.
* libguile/continuations.c (scm_i_continuation_to_frame): Record offsets
from stack top.
* libguile/control.c (scm_i_prompt_pop_abort_args_x): Adapt for reversed
order of arguments, and instead of relying on the abort to push on the
number of arguments, make the caller save the stack depth, which
allows us to compute the number of arguments ourselves.
(reify_partial_continuation, scm_c_abort): Adapt to reversed stack
order.
* libguile/dynstack.c (scm_dynstack_wind_prompt): Since we wind the
stack in a downward direction, subtract the reloc instead of adding
it.
* libguile/dynstack.h (SCM_F_DYNSTACK_PROMPT_ESCAPE_ONLY): Remove flag;
instead rely on prompt-establishing code to save the stack depth.
* libguile/eval.c (eval): Remove extraneous "volatile" declarations for
variables that are not re-set between the setjmp and any longjmp.
Adapt to save stack depth before instating the prompt.
* libguile/foreign.c (scm_i_foreign_call): Adapt to receive arguments in
reverse order.
* libguile/frames.c (frame_stack_top, scm_i_frame_stack_top): Adapt to
compute stack top instead of stack bottom.
(scm_c_frame_closure): Adapt to stack growth change.
(scm_frame_num_locals, scm_frame_local_ref, scm_frame_set_x): Use
union data type to access stack.
(RELOC): Reformat.
(scm_c_frame_previous): Adapt to stack growth change.
* libguile/frames.h: Adapt stack diagram to indicate that the stack
grows up.
(union scm_vm_stack_element): New data type used to access items on
the stack.
(SCM_FRAME_PREVIOUS_SP)
(SCM_FRAME_RETURN_ADDRESS, SCM_FRAME_SET_RETURN_ADDRESS)
(SCM_FRAME_DYNAMIC_LINK, SCM_FRAME_SET_DYNAMIC_LINK)
(SCM_FRAME_LOCAL, SCM_FRAME_NUM_LOCALS): Adapt to stack representation
change.
(SCM_FRAME_SLOT): New helper.
(SCM_VM_FRAME_FP, SCM_VM_FRAME_SP): Adapt to stack growth change.
* libguile/stacks.c (scm_make_stack): Record offsets from top of stack.
* libguile/throw.c (catch): Adapt to scm_i_prompt_pop_abort_args_x
change.
* libguile/vm-engine.c (ALLOC_FRAME, RESET_FRAME):
(FRAME_LOCALS_COUNT_FROM): Adapt to stack growth change.
(LOCAL_ADDRESS): Use SCM_FRAME_SLOT to get the address as the proper
data type.
(RETURN_ONE_VALUE, RETURN_VALUE_LIST): Adapt to stack growth change.
(apply): Shuffling up the SMOB apply args can cause the stack to
expand, so use ALLOC_FRAME instead of RESET_FRAME.
(vm_engine): Adapt for stack growth change.
* libguile/vm.c (vm_increase_sp, vm_push_sp, vm_restore_sp): Adapt to
stack representation change.
(scm_i_vm_cont_to_frame): Adapt to take offsets from the top.
(scm_i_vm_capture_stack): Adapt to capture from the top.
(vm_return_to_continuation_inner): Adapt for data type changes.
(vm_return_to_continuation): Likewise, and instead of looping, just
splat the saved arguments on with memcpy.
(vm_dispatch_hook): Adapt to receive arguments in the reverse order.
Adapt callers.
(vm_abort): There is never a tail argument. Adapt to stack
representation change.
(vm_reinstate_partial_continuation)
(vm_reinstate_partial_continuation_inner): Adapt to stack growth
change.
(allocate_stack, free_stack): Adapt to data type change.
(expand_stack): Don't try to mremap(), as you can't grow a mapping
from the bottom. Without knowing that there's a free mapping space
right below the old stack, which there usually isn't on Linux, we have
to copy. We can't use MAP_GROWSDOWN because Linux is buggy.
(make_vm): Adapt to stack representation changes.
(return_unused_stack_to_os): Round down instead of up, as the stack
grows down.
(scm_i_vm_mark_stack): Adapt to walk up the stack.
(scm_i_vm_free_stack): Adapt to scm_vm changes.
(vm_expand_stack_inner, reset_stack_limit, vm_expand_stack): Adapt to
the stack growing down.
(scm_call_n): Adapt to the stack growing down. Don't allow argv to
point into the stack.
* libguile/vm.h (struct scm_vm, struct scm_vm_cont): Adapt to hold the
stack top and bottom.
2015-09-22 10:24:30 +00:00
|
|
|
|
/* Recurse. */
|
2014-03-12 17:18:13 +01:00
|
|
|
|
return vm_expand_stack (vp, new_sp);
|
|
|
|
|
|
}
|
2013-11-22 17:31:07 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2018-06-24 11:49:42 +02:00
|
|
|
|
static uint32_t
|
2018-06-26 11:40:22 +02:00
|
|
|
|
frame_locals_count (scm_thread *thread)
|
2018-06-24 11:49:42 +02:00
|
|
|
|
{
|
|
|
|
|
|
return SCM_FRAME_NUM_LOCALS (thread->vm.fp, thread->vm.sp);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-06-24 10:07:52 +02:00
|
|
|
|
static void
|
2018-06-26 11:40:22 +02:00
|
|
|
|
thread_expand_stack (scm_thread *thread, union scm_vm_stack_element *new_sp)
|
2018-06-24 10:07:52 +02:00
|
|
|
|
{
|
|
|
|
|
|
vm_expand_stack (&thread->vm, new_sp);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-06-24 11:49:42 +02:00
|
|
|
|
/* This duplicates the inlined "ALLOC_FRAME" macro from vm-engine.c, but
|
|
|
|
|
|
it seems to be necessary for perf; the inlined version avoids the
|
|
|
|
|
|
needs to flush IP in the common case. */
|
|
|
|
|
|
static void
|
2018-06-26 11:40:22 +02:00
|
|
|
|
alloc_frame (scm_thread *thread, uint32_t nlocals)
|
2018-06-24 11:49:42 +02:00
|
|
|
|
{
|
|
|
|
|
|
union scm_vm_stack_element *sp = thread->vm.fp - nlocals;
|
|
|
|
|
|
|
2019-12-07 22:54:32 +01:00
|
|
|
|
if (SCM_UNLIKELY (sp < thread->vm.stack_limit))
|
|
|
|
|
|
thread_expand_stack (thread, sp);
|
2018-06-24 11:49:42 +02:00
|
|
|
|
else
|
|
|
|
|
|
thread->vm.sp = sp;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static uint32_t
|
2018-06-26 11:40:22 +02:00
|
|
|
|
compute_kwargs_npositional (scm_thread *thread, uint32_t nreq, uint32_t nopt)
|
2018-06-24 11:49:42 +02:00
|
|
|
|
{
|
|
|
|
|
|
uint32_t npositional, nargs;
|
|
|
|
|
|
|
|
|
|
|
|
nargs = frame_locals_count (thread);
|
|
|
|
|
|
|
|
|
|
|
|
/* look in optionals for first keyword or last positional */
|
|
|
|
|
|
/* starting after the last required positional arg */
|
|
|
|
|
|
npositional = nreq;
|
|
|
|
|
|
while (/* while we have args */
|
|
|
|
|
|
npositional < nargs
|
|
|
|
|
|
/* and we still have positionals to fill */
|
|
|
|
|
|
&& npositional < nreq + nopt
|
|
|
|
|
|
/* and we haven't reached a keyword yet */
|
|
|
|
|
|
&& !scm_is_keyword (SCM_FRAME_LOCAL (thread->vm.fp, npositional)))
|
|
|
|
|
|
/* bind this optional arg (by leaving it in place) */
|
|
|
|
|
|
npositional++;
|
|
|
|
|
|
|
|
|
|
|
|
return npositional;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
2018-06-26 11:40:22 +02:00
|
|
|
|
bind_kwargs (scm_thread *thread, uint32_t npositional, uint32_t nlocals,
|
2018-06-24 11:49:42 +02:00
|
|
|
|
SCM kwargs, uint8_t strict, uint8_t allow_other_keys)
|
|
|
|
|
|
{
|
|
|
|
|
|
uint32_t nargs, nkw, n;
|
|
|
|
|
|
union scm_vm_stack_element *fp;
|
|
|
|
|
|
|
|
|
|
|
|
nargs = frame_locals_count (thread);
|
|
|
|
|
|
nkw = nargs - npositional;
|
|
|
|
|
|
|
|
|
|
|
|
/* shuffle non-positional arguments above nlocals */
|
|
|
|
|
|
alloc_frame (thread, nlocals + nkw);
|
|
|
|
|
|
|
|
|
|
|
|
fp = thread->vm.fp;
|
|
|
|
|
|
n = nkw;
|
|
|
|
|
|
while (n--)
|
|
|
|
|
|
SCM_FRAME_LOCAL (fp, nlocals + n) = SCM_FRAME_LOCAL (fp, npositional + n);
|
|
|
|
|
|
|
|
|
|
|
|
/* Fill optionals & keyword args with SCM_UNDEFINED */
|
|
|
|
|
|
n = npositional;
|
|
|
|
|
|
while (n < nlocals)
|
|
|
|
|
|
SCM_FRAME_LOCAL (fp, n++) = SCM_UNDEFINED;
|
|
|
|
|
|
|
|
|
|
|
|
/* Now bind keywords, in the order given. */
|
|
|
|
|
|
for (n = 0; n < nkw; n++)
|
|
|
|
|
|
{
|
|
|
|
|
|
SCM kw = SCM_FRAME_LOCAL (fp, nlocals + n);
|
|
|
|
|
|
|
|
|
|
|
|
if (scm_is_keyword (kw))
|
|
|
|
|
|
{
|
|
|
|
|
|
SCM walk;
|
|
|
|
|
|
for (walk = kwargs; scm_is_pair (walk); walk = SCM_CDR (walk))
|
|
|
|
|
|
if (scm_is_eq (SCM_CAAR (walk), kw))
|
|
|
|
|
|
{
|
|
|
|
|
|
SCM si = SCM_CDAR (walk);
|
|
|
|
|
|
if (n + 1 < nkw)
|
|
|
|
|
|
SCM_FRAME_LOCAL (fp, scm_to_uint32 (si)) =
|
|
|
|
|
|
SCM_FRAME_LOCAL (fp, nlocals + n + 1);
|
|
|
|
|
|
else
|
|
|
|
|
|
scm_error_scm (sym_keyword_argument_error, SCM_BOOL_F,
|
|
|
|
|
|
scm_from_latin1_string
|
|
|
|
|
|
("Keyword argument has no value"),
|
|
|
|
|
|
SCM_EOL, scm_list_1 (kw));
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (!allow_other_keys && !scm_is_pair (walk))
|
|
|
|
|
|
scm_error_scm (sym_keyword_argument_error, SCM_BOOL_F,
|
|
|
|
|
|
scm_from_latin1_string ("Unrecognized keyword"),
|
|
|
|
|
|
SCM_EOL, scm_list_1 (kw));
|
|
|
|
|
|
n++;
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (strict)
|
|
|
|
|
|
{
|
|
|
|
|
|
scm_error_scm (sym_keyword_argument_error, SCM_BOOL_F,
|
|
|
|
|
|
scm_from_latin1_string ("Invalid keyword"),
|
|
|
|
|
|
SCM_EOL, scm_list_1 (kw));
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
/* Ignore this argument. It might get consed onto a rest list. */
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static SCM
|
2018-06-26 11:40:22 +02:00
|
|
|
|
cons_rest (scm_thread *thread, uint32_t base)
|
2018-06-24 11:49:42 +02:00
|
|
|
|
{
|
|
|
|
|
|
SCM rest = SCM_EOL;
|
|
|
|
|
|
uint32_t n = frame_locals_count (thread) - base;
|
|
|
|
|
|
|
|
|
|
|
|
while (n--)
|
|
|
|
|
|
rest = scm_inline_cons (thread, SCM_FRAME_LOCAL (thread->vm.fp, base + n),
|
|
|
|
|
|
rest);
|
|
|
|
|
|
|
|
|
|
|
|
return rest;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-06-25 10:52:16 +02:00
|
|
|
|
static void
|
2018-07-15 09:50:52 +02:00
|
|
|
|
push_interrupt_frame (scm_thread *thread, uint8_t *mra)
|
2018-06-25 10:52:16 +02:00
|
|
|
|
{
|
2018-06-29 22:28:48 +02:00
|
|
|
|
union scm_vm_stack_element *old_fp, *new_fp;
|
2018-07-16 15:42:05 +02:00
|
|
|
|
size_t frame_overhead = 3;
|
2018-06-25 10:52:16 +02:00
|
|
|
|
size_t old_frame_size = frame_locals_count (thread);
|
|
|
|
|
|
SCM proc = scm_i_async_pop (thread);
|
|
|
|
|
|
|
2020-02-19 16:53:44 +01:00
|
|
|
|
#if ENABLE_JIT
|
|
|
|
|
|
if (!mra)
|
|
|
|
|
|
mra = scm_jit_return_to_interpreter_trampoline;
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
2018-07-15 09:50:52 +02:00
|
|
|
|
/* Reserve space for frame and callee. */
|
|
|
|
|
|
alloc_frame (thread, old_frame_size + frame_overhead + 1);
|
2018-06-25 10:52:16 +02:00
|
|
|
|
|
|
|
|
|
|
old_fp = thread->vm.fp;
|
2018-08-07 12:43:25 +02:00
|
|
|
|
new_fp = SCM_FRAME_SLOT (old_fp, old_frame_size + frame_overhead - 1);
|
2018-06-29 22:28:48 +02:00
|
|
|
|
SCM_FRAME_SET_DYNAMIC_LINK (new_fp, old_fp);
|
2018-06-25 10:52:16 +02:00
|
|
|
|
/* Arrange to return to the same handle-interrupts opcode to handle
|
|
|
|
|
|
any additional interrupts. */
|
2018-08-07 12:43:25 +02:00
|
|
|
|
SCM_FRAME_SET_VIRTUAL_RETURN_ADDRESS (new_fp, thread->vm.ip);
|
|
|
|
|
|
SCM_FRAME_SET_MACHINE_RETURN_ADDRESS (new_fp, mra);
|
2018-06-29 22:28:48 +02:00
|
|
|
|
SCM_FRAME_LOCAL (new_fp, 0) = proc;
|
2018-06-25 10:52:16 +02:00
|
|
|
|
|
2018-06-29 22:28:48 +02:00
|
|
|
|
thread->vm.fp = new_fp;
|
2018-06-25 10:52:16 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2018-06-26 10:57:23 +02:00
|
|
|
|
struct return_to_continuation_data
|
|
|
|
|
|
{
|
|
|
|
|
|
struct scm_vm_cont *cp;
|
|
|
|
|
|
struct scm_vm *vp;
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/* Called with the GC lock to prevent the stack marker from traversing a
|
|
|
|
|
|
stack in an inconsistent state. */
|
|
|
|
|
|
static void *
|
|
|
|
|
|
vm_return_to_continuation_inner (void *data_ptr)
|
|
|
|
|
|
{
|
|
|
|
|
|
struct return_to_continuation_data *data = data_ptr;
|
|
|
|
|
|
struct scm_vm *vp = data->vp;
|
|
|
|
|
|
struct scm_vm_cont *cp = data->cp;
|
|
|
|
|
|
|
|
|
|
|
|
/* We know that there is enough space for the continuation, because we
|
|
|
|
|
|
captured it in the past. However there may have been an expansion
|
|
|
|
|
|
since the capture, so we may have to re-link the frame
|
|
|
|
|
|
pointers. */
|
|
|
|
|
|
memcpy (vp->stack_top - cp->stack_size,
|
|
|
|
|
|
cp->stack_bottom,
|
|
|
|
|
|
cp->stack_size * sizeof (*cp->stack_bottom));
|
|
|
|
|
|
vp->fp = vp->stack_top - cp->fp_offset;
|
|
|
|
|
|
vm_restore_sp (vp, vp->stack_top - cp->stack_size);
|
|
|
|
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-06-26 11:40:22 +02:00
|
|
|
|
static void reinstate_continuation_x (scm_thread *thread, SCM cont) SCM_NORETURN;
|
2018-06-26 10:57:23 +02:00
|
|
|
|
|
|
|
|
|
|
static void
|
2018-06-26 11:40:22 +02:00
|
|
|
|
reinstate_continuation_x (scm_thread *thread, SCM cont)
|
2018-06-26 10:57:23 +02:00
|
|
|
|
{
|
|
|
|
|
|
scm_t_contregs *continuation = scm_i_contregs (cont);
|
|
|
|
|
|
struct scm_vm *vp = &thread->vm;
|
|
|
|
|
|
struct scm_vm_cont *cp;
|
2018-07-16 15:42:05 +02:00
|
|
|
|
size_t n, i, frame_overhead = 3;
|
2018-06-26 10:57:23 +02:00
|
|
|
|
union scm_vm_stack_element *argv;
|
|
|
|
|
|
struct return_to_continuation_data data;
|
|
|
|
|
|
|
|
|
|
|
|
if (!scm_is_eq (continuation->root, thread->continuation_root))
|
|
|
|
|
|
scm_misc_error
|
|
|
|
|
|
("%continuation-call",
|
|
|
|
|
|
"invoking continuation would cross continuation barrier: ~A",
|
|
|
|
|
|
scm_list_1 (cont));
|
|
|
|
|
|
|
2018-06-26 15:10:58 +02:00
|
|
|
|
n = frame_locals_count (thread) - 1;
|
2018-06-26 10:57:23 +02:00
|
|
|
|
argv = alloca (n * sizeof (*argv));
|
|
|
|
|
|
memcpy (argv, vp->sp, n * sizeof (*argv));
|
|
|
|
|
|
|
|
|
|
|
|
cp = SCM_VM_CONT_DATA (continuation->vm_cont);
|
|
|
|
|
|
|
|
|
|
|
|
data.cp = cp;
|
|
|
|
|
|
data.vp = vp;
|
|
|
|
|
|
GC_call_with_alloc_lock (vm_return_to_continuation_inner, &data);
|
|
|
|
|
|
|
|
|
|
|
|
/* Now we have the continuation properly copied over. We just need to
|
|
|
|
|
|
copy on an empty frame and the return values, as the continuation
|
2018-07-19 13:56:13 +02:00
|
|
|
|
expects. */
|
|
|
|
|
|
vm_push_sp (vp, vp->sp - frame_overhead - n);
|
|
|
|
|
|
for (i = 0; i < frame_overhead; i++)
|
2018-07-15 09:50:52 +02:00
|
|
|
|
vp->sp[n+i].as_scm = SCM_BOOL_F;
|
2018-06-26 10:57:23 +02:00
|
|
|
|
memcpy(vp->sp, argv, n * sizeof (union scm_vm_stack_element));
|
|
|
|
|
|
|
Continuations capture machine code address
* libguile/continuations.c (scm_i_continuation_to_frame): Adapt to vra
field renaming.
(scm_i_reinstate_continuation, grow_stack, copy_stack_and_call)
(scm_dynthrow): Take mra of continuation. Set on the vp before the
longjmp.
* libguile/continuations.h: Update scm_i_reinstate_continuation
prototype.
* libguile/dynstack.h:
* libguile/control.c (scm_suspendable_continuation_p):
* libguile/dynstack.c (PROMPT_WORDS, PROMPT_VRA, PROMPT_MRA):
(PROMPT_JMPBUF, scm_dynstack_push_prompt, scm_dynstack_find_prompt)
(scm_dynstack_wind_prompt): Store both virtual and machine return
addresses on the dynstack, for prompts.
* libguile/eval.c (eval): Pass NULL for mra.
* libguile/intrinsics.c (push_prompt): Add mra arg, and pass it to the
dynstack.
* libguile/intrinsics.h: Update prototypes so that continuation-related
intrinsics can save and restore the MRA.
* libguile/jit.h:
* libguile/jit.c: Return VRA when JIT code needs to tier down.
* libguile/stacks.c (find_prompt, scm_make_stack)
* libguile/throw.c (catch): Adapt find-prompt calls.
* libguile/vm-engine.c (instrument-entry, instrument-loop): Add logic to
continue with vcode after the mcode finishes.
(compose-continuation, capture-continuation, abort, prompt): Add logic
to pass NULL as captured MRA, but continue with mcode from new
continuations, if appropriate.
* libguile/vm.c (scm_i_vm_cont_to_frame, capture_stack)
(scm_i_capture_current_stack, reinstate_continuation_x)
(capture_continuation, compose_continuation_inner, compose_continuation)
(capture_delimited_continuation, abort_to_prompt): Adapt to plumb
around machine code continuations.
(scm_call_n): Check "mra_after_abort" field for machine code
continuation, if any.
* libguile/vm.h (struct scm_vm): Add "mra_after_abort" field.
(struct scm_vm_cont): Rename "ra" field to "vra" and add "mra" field.
2018-08-12 15:57:53 +02:00
|
|
|
|
vp->ip = cp->vra;
|
2018-06-26 10:57:23 +02:00
|
|
|
|
|
Continuations capture machine code address
* libguile/continuations.c (scm_i_continuation_to_frame): Adapt to vra
field renaming.
(scm_i_reinstate_continuation, grow_stack, copy_stack_and_call)
(scm_dynthrow): Take mra of continuation. Set on the vp before the
longjmp.
* libguile/continuations.h: Update scm_i_reinstate_continuation
prototype.
* libguile/dynstack.h:
* libguile/control.c (scm_suspendable_continuation_p):
* libguile/dynstack.c (PROMPT_WORDS, PROMPT_VRA, PROMPT_MRA):
(PROMPT_JMPBUF, scm_dynstack_push_prompt, scm_dynstack_find_prompt)
(scm_dynstack_wind_prompt): Store both virtual and machine return
addresses on the dynstack, for prompts.
* libguile/eval.c (eval): Pass NULL for mra.
* libguile/intrinsics.c (push_prompt): Add mra arg, and pass it to the
dynstack.
* libguile/intrinsics.h: Update prototypes so that continuation-related
intrinsics can save and restore the MRA.
* libguile/jit.h:
* libguile/jit.c: Return VRA when JIT code needs to tier down.
* libguile/stacks.c (find_prompt, scm_make_stack)
* libguile/throw.c (catch): Adapt find-prompt calls.
* libguile/vm-engine.c (instrument-entry, instrument-loop): Add logic to
continue with vcode after the mcode finishes.
(compose-continuation, capture-continuation, abort, prompt): Add logic
to pass NULL as captured MRA, but continue with mcode from new
continuations, if appropriate.
* libguile/vm.c (scm_i_vm_cont_to_frame, capture_stack)
(scm_i_capture_current_stack, reinstate_continuation_x)
(capture_continuation, compose_continuation_inner, compose_continuation)
(capture_delimited_continuation, abort_to_prompt): Adapt to plumb
around machine code continuations.
(scm_call_n): Check "mra_after_abort" field for machine code
continuation, if any.
* libguile/vm.h (struct scm_vm): Add "mra_after_abort" field.
(struct scm_vm_cont): Rename "ra" field to "vra" and add "mra" field.
2018-08-12 15:57:53 +02:00
|
|
|
|
scm_i_reinstate_continuation (cont, cp->mra);
|
2018-06-26 10:57:23 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2018-06-26 12:01:01 +02:00
|
|
|
|
static SCM
|
2018-08-13 10:27:13 +02:00
|
|
|
|
capture_continuation (scm_thread *thread)
|
2018-06-26 12:01:01 +02:00
|
|
|
|
{
|
|
|
|
|
|
struct scm_vm *vp = &thread->vm;
|
2019-06-18 21:40:55 +02:00
|
|
|
|
void *mra = SCM_FRAME_MACHINE_RETURN_ADDRESS (vp->fp);
|
2019-08-19 16:43:43 +02:00
|
|
|
|
#if ENABLE_JIT
|
2019-06-18 21:40:55 +02:00
|
|
|
|
if (mra == scm_jit_return_to_interpreter_trampoline)
|
|
|
|
|
|
mra = NULL;
|
2019-08-19 16:31:29 +02:00
|
|
|
|
#endif
|
Continuations capture machine code address
* libguile/continuations.c (scm_i_continuation_to_frame): Adapt to vra
field renaming.
(scm_i_reinstate_continuation, grow_stack, copy_stack_and_call)
(scm_dynthrow): Take mra of continuation. Set on the vp before the
longjmp.
* libguile/continuations.h: Update scm_i_reinstate_continuation
prototype.
* libguile/dynstack.h:
* libguile/control.c (scm_suspendable_continuation_p):
* libguile/dynstack.c (PROMPT_WORDS, PROMPT_VRA, PROMPT_MRA):
(PROMPT_JMPBUF, scm_dynstack_push_prompt, scm_dynstack_find_prompt)
(scm_dynstack_wind_prompt): Store both virtual and machine return
addresses on the dynstack, for prompts.
* libguile/eval.c (eval): Pass NULL for mra.
* libguile/intrinsics.c (push_prompt): Add mra arg, and pass it to the
dynstack.
* libguile/intrinsics.h: Update prototypes so that continuation-related
intrinsics can save and restore the MRA.
* libguile/jit.h:
* libguile/jit.c: Return VRA when JIT code needs to tier down.
* libguile/stacks.c (find_prompt, scm_make_stack)
* libguile/throw.c (catch): Adapt find-prompt calls.
* libguile/vm-engine.c (instrument-entry, instrument-loop): Add logic to
continue with vcode after the mcode finishes.
(compose-continuation, capture-continuation, abort, prompt): Add logic
to pass NULL as captured MRA, but continue with mcode from new
continuations, if appropriate.
* libguile/vm.c (scm_i_vm_cont_to_frame, capture_stack)
(scm_i_capture_current_stack, reinstate_continuation_x)
(capture_continuation, compose_continuation_inner, compose_continuation)
(capture_delimited_continuation, abort_to_prompt): Adapt to plumb
around machine code continuations.
(scm_call_n): Check "mra_after_abort" field for machine code
continuation, if any.
* libguile/vm.h (struct scm_vm): Add "mra_after_abort" field.
(struct scm_vm_cont): Rename "ra" field to "vra" and add "mra" field.
2018-08-12 15:57:53 +02:00
|
|
|
|
SCM vm_cont = capture_stack (vp->stack_top,
|
|
|
|
|
|
SCM_FRAME_DYNAMIC_LINK (vp->fp),
|
|
|
|
|
|
SCM_FRAME_PREVIOUS_SP (vp->fp),
|
|
|
|
|
|
SCM_FRAME_VIRTUAL_RETURN_ADDRESS (vp->fp),
|
2019-06-18 21:40:55 +02:00
|
|
|
|
mra,
|
Continuations capture machine code address
* libguile/continuations.c (scm_i_continuation_to_frame): Adapt to vra
field renaming.
(scm_i_reinstate_continuation, grow_stack, copy_stack_and_call)
(scm_dynthrow): Take mra of continuation. Set on the vp before the
longjmp.
* libguile/continuations.h: Update scm_i_reinstate_continuation
prototype.
* libguile/dynstack.h:
* libguile/control.c (scm_suspendable_continuation_p):
* libguile/dynstack.c (PROMPT_WORDS, PROMPT_VRA, PROMPT_MRA):
(PROMPT_JMPBUF, scm_dynstack_push_prompt, scm_dynstack_find_prompt)
(scm_dynstack_wind_prompt): Store both virtual and machine return
addresses on the dynstack, for prompts.
* libguile/eval.c (eval): Pass NULL for mra.
* libguile/intrinsics.c (push_prompt): Add mra arg, and pass it to the
dynstack.
* libguile/intrinsics.h: Update prototypes so that continuation-related
intrinsics can save and restore the MRA.
* libguile/jit.h:
* libguile/jit.c: Return VRA when JIT code needs to tier down.
* libguile/stacks.c (find_prompt, scm_make_stack)
* libguile/throw.c (catch): Adapt find-prompt calls.
* libguile/vm-engine.c (instrument-entry, instrument-loop): Add logic to
continue with vcode after the mcode finishes.
(compose-continuation, capture-continuation, abort, prompt): Add logic
to pass NULL as captured MRA, but continue with mcode from new
continuations, if appropriate.
* libguile/vm.c (scm_i_vm_cont_to_frame, capture_stack)
(scm_i_capture_current_stack, reinstate_continuation_x)
(capture_continuation, compose_continuation_inner, compose_continuation)
(capture_delimited_continuation, abort_to_prompt): Adapt to plumb
around machine code continuations.
(scm_call_n): Check "mra_after_abort" field for machine code
continuation, if any.
* libguile/vm.h (struct scm_vm): Add "mra_after_abort" field.
(struct scm_vm_cont): Rename "ra" field to "vra" and add "mra" field.
2018-08-12 15:57:53 +02:00
|
|
|
|
scm_dynstack_capture_all (&thread->dynstack),
|
|
|
|
|
|
0);
|
2018-06-27 18:42:21 +02:00
|
|
|
|
return scm_i_make_continuation (thread, vm_cont);
|
2018-06-26 12:01:01 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2018-06-26 15:10:58 +02:00
|
|
|
|
struct compose_continuation_data
|
|
|
|
|
|
{
|
|
|
|
|
|
struct scm_vm *vp;
|
|
|
|
|
|
struct scm_vm_cont *cp;
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
static void *
|
|
|
|
|
|
compose_continuation_inner (void *data_ptr)
|
|
|
|
|
|
{
|
|
|
|
|
|
struct compose_continuation_data *data = data_ptr;
|
|
|
|
|
|
struct scm_vm *vp = data->vp;
|
|
|
|
|
|
struct scm_vm_cont *cp = data->cp;
|
|
|
|
|
|
|
|
|
|
|
|
memcpy (vp->fp - cp->stack_size,
|
|
|
|
|
|
cp->stack_bottom,
|
|
|
|
|
|
cp->stack_size * sizeof (*cp->stack_bottom));
|
|
|
|
|
|
|
|
|
|
|
|
vp->fp -= cp->fp_offset;
|
Continuations capture machine code address
* libguile/continuations.c (scm_i_continuation_to_frame): Adapt to vra
field renaming.
(scm_i_reinstate_continuation, grow_stack, copy_stack_and_call)
(scm_dynthrow): Take mra of continuation. Set on the vp before the
longjmp.
* libguile/continuations.h: Update scm_i_reinstate_continuation
prototype.
* libguile/dynstack.h:
* libguile/control.c (scm_suspendable_continuation_p):
* libguile/dynstack.c (PROMPT_WORDS, PROMPT_VRA, PROMPT_MRA):
(PROMPT_JMPBUF, scm_dynstack_push_prompt, scm_dynstack_find_prompt)
(scm_dynstack_wind_prompt): Store both virtual and machine return
addresses on the dynstack, for prompts.
* libguile/eval.c (eval): Pass NULL for mra.
* libguile/intrinsics.c (push_prompt): Add mra arg, and pass it to the
dynstack.
* libguile/intrinsics.h: Update prototypes so that continuation-related
intrinsics can save and restore the MRA.
* libguile/jit.h:
* libguile/jit.c: Return VRA when JIT code needs to tier down.
* libguile/stacks.c (find_prompt, scm_make_stack)
* libguile/throw.c (catch): Adapt find-prompt calls.
* libguile/vm-engine.c (instrument-entry, instrument-loop): Add logic to
continue with vcode after the mcode finishes.
(compose-continuation, capture-continuation, abort, prompt): Add logic
to pass NULL as captured MRA, but continue with mcode from new
continuations, if appropriate.
* libguile/vm.c (scm_i_vm_cont_to_frame, capture_stack)
(scm_i_capture_current_stack, reinstate_continuation_x)
(capture_continuation, compose_continuation_inner, compose_continuation)
(capture_delimited_continuation, abort_to_prompt): Adapt to plumb
around machine code continuations.
(scm_call_n): Check "mra_after_abort" field for machine code
continuation, if any.
* libguile/vm.h (struct scm_vm): Add "mra_after_abort" field.
(struct scm_vm_cont): Rename "ra" field to "vra" and add "mra" field.
2018-08-12 15:57:53 +02:00
|
|
|
|
vp->ip = cp->vra;
|
2018-06-26 15:10:58 +02:00
|
|
|
|
|
Continuations capture machine code address
* libguile/continuations.c (scm_i_continuation_to_frame): Adapt to vra
field renaming.
(scm_i_reinstate_continuation, grow_stack, copy_stack_and_call)
(scm_dynthrow): Take mra of continuation. Set on the vp before the
longjmp.
* libguile/continuations.h: Update scm_i_reinstate_continuation
prototype.
* libguile/dynstack.h:
* libguile/control.c (scm_suspendable_continuation_p):
* libguile/dynstack.c (PROMPT_WORDS, PROMPT_VRA, PROMPT_MRA):
(PROMPT_JMPBUF, scm_dynstack_push_prompt, scm_dynstack_find_prompt)
(scm_dynstack_wind_prompt): Store both virtual and machine return
addresses on the dynstack, for prompts.
* libguile/eval.c (eval): Pass NULL for mra.
* libguile/intrinsics.c (push_prompt): Add mra arg, and pass it to the
dynstack.
* libguile/intrinsics.h: Update prototypes so that continuation-related
intrinsics can save and restore the MRA.
* libguile/jit.h:
* libguile/jit.c: Return VRA when JIT code needs to tier down.
* libguile/stacks.c (find_prompt, scm_make_stack)
* libguile/throw.c (catch): Adapt find-prompt calls.
* libguile/vm-engine.c (instrument-entry, instrument-loop): Add logic to
continue with vcode after the mcode finishes.
(compose-continuation, capture-continuation, abort, prompt): Add logic
to pass NULL as captured MRA, but continue with mcode from new
continuations, if appropriate.
* libguile/vm.c (scm_i_vm_cont_to_frame, capture_stack)
(scm_i_capture_current_stack, reinstate_continuation_x)
(capture_continuation, compose_continuation_inner, compose_continuation)
(capture_delimited_continuation, abort_to_prompt): Adapt to plumb
around machine code continuations.
(scm_call_n): Check "mra_after_abort" field for machine code
continuation, if any.
* libguile/vm.h (struct scm_vm): Add "mra_after_abort" field.
(struct scm_vm_cont): Rename "ra" field to "vra" and add "mra" field.
2018-08-12 15:57:53 +02:00
|
|
|
|
return cp->mra;
|
2018-06-26 15:10:58 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
Continuations capture machine code address
* libguile/continuations.c (scm_i_continuation_to_frame): Adapt to vra
field renaming.
(scm_i_reinstate_continuation, grow_stack, copy_stack_and_call)
(scm_dynthrow): Take mra of continuation. Set on the vp before the
longjmp.
* libguile/continuations.h: Update scm_i_reinstate_continuation
prototype.
* libguile/dynstack.h:
* libguile/control.c (scm_suspendable_continuation_p):
* libguile/dynstack.c (PROMPT_WORDS, PROMPT_VRA, PROMPT_MRA):
(PROMPT_JMPBUF, scm_dynstack_push_prompt, scm_dynstack_find_prompt)
(scm_dynstack_wind_prompt): Store both virtual and machine return
addresses on the dynstack, for prompts.
* libguile/eval.c (eval): Pass NULL for mra.
* libguile/intrinsics.c (push_prompt): Add mra arg, and pass it to the
dynstack.
* libguile/intrinsics.h: Update prototypes so that continuation-related
intrinsics can save and restore the MRA.
* libguile/jit.h:
* libguile/jit.c: Return VRA when JIT code needs to tier down.
* libguile/stacks.c (find_prompt, scm_make_stack)
* libguile/throw.c (catch): Adapt find-prompt calls.
* libguile/vm-engine.c (instrument-entry, instrument-loop): Add logic to
continue with vcode after the mcode finishes.
(compose-continuation, capture-continuation, abort, prompt): Add logic
to pass NULL as captured MRA, but continue with mcode from new
continuations, if appropriate.
* libguile/vm.c (scm_i_vm_cont_to_frame, capture_stack)
(scm_i_capture_current_stack, reinstate_continuation_x)
(capture_continuation, compose_continuation_inner, compose_continuation)
(capture_delimited_continuation, abort_to_prompt): Adapt to plumb
around machine code continuations.
(scm_call_n): Check "mra_after_abort" field for machine code
continuation, if any.
* libguile/vm.h (struct scm_vm): Add "mra_after_abort" field.
(struct scm_vm_cont): Rename "ra" field to "vra" and add "mra" field.
2018-08-12 15:57:53 +02:00
|
|
|
|
static uint8_t*
|
2018-06-27 18:42:21 +02:00
|
|
|
|
compose_continuation (scm_thread *thread, SCM cont)
|
2018-06-26 15:10:58 +02:00
|
|
|
|
{
|
|
|
|
|
|
struct scm_vm *vp = &thread->vm;
|
|
|
|
|
|
size_t nargs;
|
|
|
|
|
|
struct compose_continuation_data data;
|
|
|
|
|
|
struct scm_vm_cont *cp;
|
|
|
|
|
|
union scm_vm_stack_element *args;
|
|
|
|
|
|
ptrdiff_t old_fp_offset;
|
Continuations capture machine code address
* libguile/continuations.c (scm_i_continuation_to_frame): Adapt to vra
field renaming.
(scm_i_reinstate_continuation, grow_stack, copy_stack_and_call)
(scm_dynthrow): Take mra of continuation. Set on the vp before the
longjmp.
* libguile/continuations.h: Update scm_i_reinstate_continuation
prototype.
* libguile/dynstack.h:
* libguile/control.c (scm_suspendable_continuation_p):
* libguile/dynstack.c (PROMPT_WORDS, PROMPT_VRA, PROMPT_MRA):
(PROMPT_JMPBUF, scm_dynstack_push_prompt, scm_dynstack_find_prompt)
(scm_dynstack_wind_prompt): Store both virtual and machine return
addresses on the dynstack, for prompts.
* libguile/eval.c (eval): Pass NULL for mra.
* libguile/intrinsics.c (push_prompt): Add mra arg, and pass it to the
dynstack.
* libguile/intrinsics.h: Update prototypes so that continuation-related
intrinsics can save and restore the MRA.
* libguile/jit.h:
* libguile/jit.c: Return VRA when JIT code needs to tier down.
* libguile/stacks.c (find_prompt, scm_make_stack)
* libguile/throw.c (catch): Adapt find-prompt calls.
* libguile/vm-engine.c (instrument-entry, instrument-loop): Add logic to
continue with vcode after the mcode finishes.
(compose-continuation, capture-continuation, abort, prompt): Add logic
to pass NULL as captured MRA, but continue with mcode from new
continuations, if appropriate.
* libguile/vm.c (scm_i_vm_cont_to_frame, capture_stack)
(scm_i_capture_current_stack, reinstate_continuation_x)
(capture_continuation, compose_continuation_inner, compose_continuation)
(capture_delimited_continuation, abort_to_prompt): Adapt to plumb
around machine code continuations.
(scm_call_n): Check "mra_after_abort" field for machine code
continuation, if any.
* libguile/vm.h (struct scm_vm): Add "mra_after_abort" field.
(struct scm_vm_cont): Rename "ra" field to "vra" and add "mra" field.
2018-08-12 15:57:53 +02:00
|
|
|
|
uint8_t *mra;
|
2018-06-26 15:10:58 +02:00
|
|
|
|
|
|
|
|
|
|
if (SCM_UNLIKELY (! SCM_VM_CONT_REWINDABLE_P (cont)))
|
2018-06-27 09:19:36 +02:00
|
|
|
|
scm_wrong_type_arg_msg (NULL, 0, cont, "resumable continuation");
|
2018-06-26 15:10:58 +02:00
|
|
|
|
|
2020-02-19 16:53:44 +01:00
|
|
|
|
#if ENABLE_JIT
|
|
|
|
|
|
if (!SCM_FRAME_MACHINE_RETURN_ADDRESS (vp->fp))
|
|
|
|
|
|
SCM_FRAME_SET_MACHINE_RETURN_ADDRESS
|
|
|
|
|
|
(vp->fp, scm_jit_return_to_interpreter_trampoline);
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
2018-06-26 15:10:58 +02:00
|
|
|
|
nargs = frame_locals_count (thread) - 1;
|
|
|
|
|
|
args = alloca (nargs * sizeof (*args));
|
|
|
|
|
|
memcpy (args, vp->sp, nargs * sizeof (*args));
|
|
|
|
|
|
|
|
|
|
|
|
cp = SCM_VM_CONT_DATA (cont);
|
|
|
|
|
|
|
|
|
|
|
|
old_fp_offset = vp->stack_top - vp->fp;
|
|
|
|
|
|
|
2018-07-19 13:56:13 +02:00
|
|
|
|
vm_push_sp (vp, vp->fp - (cp->stack_size + nargs));
|
2018-06-26 15:10:58 +02:00
|
|
|
|
|
|
|
|
|
|
data.vp = vp;
|
|
|
|
|
|
data.cp = cp;
|
Continuations capture machine code address
* libguile/continuations.c (scm_i_continuation_to_frame): Adapt to vra
field renaming.
(scm_i_reinstate_continuation, grow_stack, copy_stack_and_call)
(scm_dynthrow): Take mra of continuation. Set on the vp before the
longjmp.
* libguile/continuations.h: Update scm_i_reinstate_continuation
prototype.
* libguile/dynstack.h:
* libguile/control.c (scm_suspendable_continuation_p):
* libguile/dynstack.c (PROMPT_WORDS, PROMPT_VRA, PROMPT_MRA):
(PROMPT_JMPBUF, scm_dynstack_push_prompt, scm_dynstack_find_prompt)
(scm_dynstack_wind_prompt): Store both virtual and machine return
addresses on the dynstack, for prompts.
* libguile/eval.c (eval): Pass NULL for mra.
* libguile/intrinsics.c (push_prompt): Add mra arg, and pass it to the
dynstack.
* libguile/intrinsics.h: Update prototypes so that continuation-related
intrinsics can save and restore the MRA.
* libguile/jit.h:
* libguile/jit.c: Return VRA when JIT code needs to tier down.
* libguile/stacks.c (find_prompt, scm_make_stack)
* libguile/throw.c (catch): Adapt find-prompt calls.
* libguile/vm-engine.c (instrument-entry, instrument-loop): Add logic to
continue with vcode after the mcode finishes.
(compose-continuation, capture-continuation, abort, prompt): Add logic
to pass NULL as captured MRA, but continue with mcode from new
continuations, if appropriate.
* libguile/vm.c (scm_i_vm_cont_to_frame, capture_stack)
(scm_i_capture_current_stack, reinstate_continuation_x)
(capture_continuation, compose_continuation_inner, compose_continuation)
(capture_delimited_continuation, abort_to_prompt): Adapt to plumb
around machine code continuations.
(scm_call_n): Check "mra_after_abort" field for machine code
continuation, if any.
* libguile/vm.h (struct scm_vm): Add "mra_after_abort" field.
(struct scm_vm_cont): Rename "ra" field to "vra" and add "mra" field.
2018-08-12 15:57:53 +02:00
|
|
|
|
mra = GC_call_with_alloc_lock (compose_continuation_inner, &data);
|
2018-06-26 15:10:58 +02:00
|
|
|
|
|
|
|
|
|
|
/* The resumed continuation will expect ARGS on the stack as if from a
|
2018-07-19 13:56:13 +02:00
|
|
|
|
multiple-value return. */
|
2018-06-26 15:10:58 +02:00
|
|
|
|
memcpy (vp->sp, args, nargs * sizeof (*args));
|
|
|
|
|
|
|
|
|
|
|
|
/* The prompt captured a slice of the dynamic stack. Here we wind
|
|
|
|
|
|
those entries onto the current thread's stack. We also have to
|
|
|
|
|
|
relocate any prompts that we see along the way. */
|
|
|
|
|
|
{
|
|
|
|
|
|
scm_t_bits *walk;
|
|
|
|
|
|
|
|
|
|
|
|
for (walk = SCM_DYNSTACK_FIRST (cp->dynstack);
|
|
|
|
|
|
SCM_DYNSTACK_TAG (walk);
|
|
|
|
|
|
walk = SCM_DYNSTACK_NEXT (walk))
|
|
|
|
|
|
{
|
|
|
|
|
|
scm_t_bits tag = SCM_DYNSTACK_TAG (walk);
|
|
|
|
|
|
|
|
|
|
|
|
if (SCM_DYNSTACK_TAG_TYPE (tag) == SCM_DYNSTACK_TYPE_PROMPT)
|
|
|
|
|
|
scm_dynstack_wind_prompt (&thread->dynstack, walk, old_fp_offset,
|
2018-06-27 18:42:21 +02:00
|
|
|
|
thread->vm.registers);
|
2018-06-26 15:10:58 +02:00
|
|
|
|
else
|
|
|
|
|
|
scm_dynstack_wind_1 (&thread->dynstack, walk);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
Continuations capture machine code address
* libguile/continuations.c (scm_i_continuation_to_frame): Adapt to vra
field renaming.
(scm_i_reinstate_continuation, grow_stack, copy_stack_and_call)
(scm_dynthrow): Take mra of continuation. Set on the vp before the
longjmp.
* libguile/continuations.h: Update scm_i_reinstate_continuation
prototype.
* libguile/dynstack.h:
* libguile/control.c (scm_suspendable_continuation_p):
* libguile/dynstack.c (PROMPT_WORDS, PROMPT_VRA, PROMPT_MRA):
(PROMPT_JMPBUF, scm_dynstack_push_prompt, scm_dynstack_find_prompt)
(scm_dynstack_wind_prompt): Store both virtual and machine return
addresses on the dynstack, for prompts.
* libguile/eval.c (eval): Pass NULL for mra.
* libguile/intrinsics.c (push_prompt): Add mra arg, and pass it to the
dynstack.
* libguile/intrinsics.h: Update prototypes so that continuation-related
intrinsics can save and restore the MRA.
* libguile/jit.h:
* libguile/jit.c: Return VRA when JIT code needs to tier down.
* libguile/stacks.c (find_prompt, scm_make_stack)
* libguile/throw.c (catch): Adapt find-prompt calls.
* libguile/vm-engine.c (instrument-entry, instrument-loop): Add logic to
continue with vcode after the mcode finishes.
(compose-continuation, capture-continuation, abort, prompt): Add logic
to pass NULL as captured MRA, but continue with mcode from new
continuations, if appropriate.
* libguile/vm.c (scm_i_vm_cont_to_frame, capture_stack)
(scm_i_capture_current_stack, reinstate_continuation_x)
(capture_continuation, compose_continuation_inner, compose_continuation)
(capture_delimited_continuation, abort_to_prompt): Adapt to plumb
around machine code continuations.
(scm_call_n): Check "mra_after_abort" field for machine code
continuation, if any.
* libguile/vm.h (struct scm_vm): Add "mra_after_abort" field.
(struct scm_vm_cont): Rename "ra" field to "vra" and add "mra" field.
2018-08-12 15:57:53 +02:00
|
|
|
|
|
|
|
|
|
|
return mra;
|
2018-06-26 15:10:58 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2018-08-13 14:24:44 +02:00
|
|
|
|
static void
|
|
|
|
|
|
expand_apply_argument (scm_thread *thread)
|
2018-06-26 15:33:15 +02:00
|
|
|
|
{
|
2018-08-13 14:24:44 +02:00
|
|
|
|
SCM x = thread->vm.sp[0].as_scm;
|
2018-06-26 15:33:15 +02:00
|
|
|
|
int len = scm_ilength (x);
|
|
|
|
|
|
|
|
|
|
|
|
if (SCM_UNLIKELY (len < 0))
|
|
|
|
|
|
scm_error (scm_arg_type_key, "apply", "Apply to non-list: ~S",
|
|
|
|
|
|
scm_list_1 (x), scm_list_1 (x));
|
|
|
|
|
|
|
2018-08-13 14:24:44 +02:00
|
|
|
|
alloc_frame (thread, frame_locals_count (thread) - 1 + len);
|
|
|
|
|
|
|
|
|
|
|
|
while (len--)
|
|
|
|
|
|
{
|
|
|
|
|
|
thread->vm.sp[len].as_scm = SCM_CAR (x);
|
|
|
|
|
|
x = SCM_CDR (x);
|
|
|
|
|
|
}
|
2018-06-26 15:33:15 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2018-08-11 10:48:29 +02:00
|
|
|
|
/* This is here to avoid putting the code for "alloc-frame" in subr
|
|
|
|
|
|
calls. */
|
|
|
|
|
|
static void
|
|
|
|
|
|
unpack_values_object (scm_thread *thread, SCM obj)
|
|
|
|
|
|
{
|
|
|
|
|
|
size_t n, nvals = scm_i_nvalues (obj);
|
|
|
|
|
|
alloc_frame (thread, nvals);
|
|
|
|
|
|
for (n = 0; n < nvals; n++)
|
|
|
|
|
|
SCM_FRAME_LOCAL (thread->vm.fp, n) = scm_i_value_ref (obj, n);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-08-11 14:22:32 +02:00
|
|
|
|
static void
|
|
|
|
|
|
foreign_call (scm_thread *thread, SCM cif, SCM pointer)
|
|
|
|
|
|
{
|
|
|
|
|
|
SCM ret;
|
|
|
|
|
|
int err = 0;
|
|
|
|
|
|
|
|
|
|
|
|
ret = scm_i_foreign_call (cif, pointer, &err, thread->vm.sp);
|
|
|
|
|
|
|
|
|
|
|
|
alloc_frame (thread, 2);
|
|
|
|
|
|
SCM_FRAME_LOCAL (thread->vm.fp, 0) = ret;
|
|
|
|
|
|
SCM_FRAME_LOCAL (thread->vm.fp, 1) = scm_from_int (err);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-06-26 16:19:16 +02:00
|
|
|
|
static SCM
|
|
|
|
|
|
capture_delimited_continuation (struct scm_vm *vp,
|
|
|
|
|
|
union scm_vm_stack_element *saved_fp,
|
Continuations capture machine code address
* libguile/continuations.c (scm_i_continuation_to_frame): Adapt to vra
field renaming.
(scm_i_reinstate_continuation, grow_stack, copy_stack_and_call)
(scm_dynthrow): Take mra of continuation. Set on the vp before the
longjmp.
* libguile/continuations.h: Update scm_i_reinstate_continuation
prototype.
* libguile/dynstack.h:
* libguile/control.c (scm_suspendable_continuation_p):
* libguile/dynstack.c (PROMPT_WORDS, PROMPT_VRA, PROMPT_MRA):
(PROMPT_JMPBUF, scm_dynstack_push_prompt, scm_dynstack_find_prompt)
(scm_dynstack_wind_prompt): Store both virtual and machine return
addresses on the dynstack, for prompts.
* libguile/eval.c (eval): Pass NULL for mra.
* libguile/intrinsics.c (push_prompt): Add mra arg, and pass it to the
dynstack.
* libguile/intrinsics.h: Update prototypes so that continuation-related
intrinsics can save and restore the MRA.
* libguile/jit.h:
* libguile/jit.c: Return VRA when JIT code needs to tier down.
* libguile/stacks.c (find_prompt, scm_make_stack)
* libguile/throw.c (catch): Adapt find-prompt calls.
* libguile/vm-engine.c (instrument-entry, instrument-loop): Add logic to
continue with vcode after the mcode finishes.
(compose-continuation, capture-continuation, abort, prompt): Add logic
to pass NULL as captured MRA, but continue with mcode from new
continuations, if appropriate.
* libguile/vm.c (scm_i_vm_cont_to_frame, capture_stack)
(scm_i_capture_current_stack, reinstate_continuation_x)
(capture_continuation, compose_continuation_inner, compose_continuation)
(capture_delimited_continuation, abort_to_prompt): Adapt to plumb
around machine code continuations.
(scm_call_n): Check "mra_after_abort" field for machine code
continuation, if any.
* libguile/vm.h (struct scm_vm): Add "mra_after_abort" field.
(struct scm_vm_cont): Rename "ra" field to "vra" and add "mra" field.
2018-08-12 15:57:53 +02:00
|
|
|
|
uint8_t *saved_mra,
|
2018-06-26 16:19:16 +02:00
|
|
|
|
jmp_buf *saved_registers,
|
|
|
|
|
|
scm_t_dynstack *dynstack,
|
|
|
|
|
|
jmp_buf *current_registers)
|
|
|
|
|
|
{
|
|
|
|
|
|
SCM vm_cont;
|
|
|
|
|
|
uint32_t flags;
|
|
|
|
|
|
union scm_vm_stack_element *base_fp;
|
|
|
|
|
|
|
|
|
|
|
|
flags = SCM_F_VM_CONT_PARTIAL;
|
|
|
|
|
|
/* If we are aborting to a prompt that has the same registers as those
|
|
|
|
|
|
of the abort, it means there are no intervening C frames on the
|
|
|
|
|
|
stack, and so the continuation can be relocated elsewhere on the
|
|
|
|
|
|
stack: it is rewindable. */
|
|
|
|
|
|
if (saved_registers && saved_registers == current_registers)
|
|
|
|
|
|
flags |= SCM_F_VM_CONT_REWINDABLE;
|
|
|
|
|
|
|
|
|
|
|
|
/* Walk the stack until we find the first frame newer than saved_fp.
|
|
|
|
|
|
We will save the stack until that frame. It used to be that we
|
|
|
|
|
|
could determine the stack base in O(1) time, but that's no longer
|
|
|
|
|
|
the case, since the thunk application doesn't occur where the
|
|
|
|
|
|
prompt is saved. */
|
|
|
|
|
|
for (base_fp = vp->fp;
|
|
|
|
|
|
SCM_FRAME_DYNAMIC_LINK (base_fp) < saved_fp;
|
|
|
|
|
|
base_fp = SCM_FRAME_DYNAMIC_LINK (base_fp));
|
|
|
|
|
|
|
|
|
|
|
|
if (SCM_FRAME_DYNAMIC_LINK (base_fp) != saved_fp)
|
|
|
|
|
|
abort();
|
|
|
|
|
|
|
|
|
|
|
|
scm_dynstack_relocate_prompts (dynstack, vp->stack_top - base_fp);
|
|
|
|
|
|
|
2018-06-26 17:08:24 +02:00
|
|
|
|
/* Capture from the base_fp to the top thunk application frame. Don't
|
|
|
|
|
|
capture values from the most recent frame, as they are the abort
|
|
|
|
|
|
args. */
|
Continuations capture machine code address
* libguile/continuations.c (scm_i_continuation_to_frame): Adapt to vra
field renaming.
(scm_i_reinstate_continuation, grow_stack, copy_stack_and_call)
(scm_dynthrow): Take mra of continuation. Set on the vp before the
longjmp.
* libguile/continuations.h: Update scm_i_reinstate_continuation
prototype.
* libguile/dynstack.h:
* libguile/control.c (scm_suspendable_continuation_p):
* libguile/dynstack.c (PROMPT_WORDS, PROMPT_VRA, PROMPT_MRA):
(PROMPT_JMPBUF, scm_dynstack_push_prompt, scm_dynstack_find_prompt)
(scm_dynstack_wind_prompt): Store both virtual and machine return
addresses on the dynstack, for prompts.
* libguile/eval.c (eval): Pass NULL for mra.
* libguile/intrinsics.c (push_prompt): Add mra arg, and pass it to the
dynstack.
* libguile/intrinsics.h: Update prototypes so that continuation-related
intrinsics can save and restore the MRA.
* libguile/jit.h:
* libguile/jit.c: Return VRA when JIT code needs to tier down.
* libguile/stacks.c (find_prompt, scm_make_stack)
* libguile/throw.c (catch): Adapt find-prompt calls.
* libguile/vm-engine.c (instrument-entry, instrument-loop): Add logic to
continue with vcode after the mcode finishes.
(compose-continuation, capture-continuation, abort, prompt): Add logic
to pass NULL as captured MRA, but continue with mcode from new
continuations, if appropriate.
* libguile/vm.c (scm_i_vm_cont_to_frame, capture_stack)
(scm_i_capture_current_stack, reinstate_continuation_x)
(capture_continuation, compose_continuation_inner, compose_continuation)
(capture_delimited_continuation, abort_to_prompt): Adapt to plumb
around machine code continuations.
(scm_call_n): Check "mra_after_abort" field for machine code
continuation, if any.
* libguile/vm.h (struct scm_vm): Add "mra_after_abort" field.
(struct scm_vm_cont): Rename "ra" field to "vra" and add "mra" field.
2018-08-12 15:57:53 +02:00
|
|
|
|
vm_cont = capture_stack (base_fp, vp->fp, vp->fp, vp->ip,
|
|
|
|
|
|
saved_mra, dynstack, flags);
|
2018-06-26 16:19:16 +02:00
|
|
|
|
|
|
|
|
|
|
return scm_i_make_composable_continuation (vm_cont);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
2018-06-26 16:39:34 +02:00
|
|
|
|
scm_i_vm_abort (SCM *tag_and_argv, size_t n)
|
|
|
|
|
|
{
|
|
|
|
|
|
scm_call_n (vm_builtin_abort_to_prompt, tag_and_argv, n);
|
|
|
|
|
|
/* Unreachable. */
|
|
|
|
|
|
abort ();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-09-15 10:41:35 +02:00
|
|
|
|
/* The same as scm_i_vm_abort(), but possibly called in response to
|
|
|
|
|
|
resource allocation failures, so we might not be able to make a
|
|
|
|
|
|
call, as that might require stack expansion. Grrr. */
|
|
|
|
|
|
void
|
|
|
|
|
|
scm_i_vm_emergency_abort (SCM *tag_and_argv, size_t n)
|
|
|
|
|
|
{
|
|
|
|
|
|
scm_thread *thread = SCM_I_CURRENT_THREAD;
|
|
|
|
|
|
struct scm_vm *vp = &thread->vm;
|
|
|
|
|
|
scm_t_dynstack *dynstack = &thread->dynstack;
|
|
|
|
|
|
SCM tag, cont;
|
|
|
|
|
|
size_t nargs;
|
|
|
|
|
|
scm_t_bits *prompt;
|
|
|
|
|
|
scm_t_dynstack_prompt_flags flags;
|
|
|
|
|
|
ptrdiff_t fp_offset, sp_offset;
|
|
|
|
|
|
union scm_vm_stack_element *fp, *sp;
|
|
|
|
|
|
SCM *argv;
|
|
|
|
|
|
uint32_t *vra;
|
|
|
|
|
|
uint8_t *mra;
|
|
|
|
|
|
jmp_buf *registers;
|
|
|
|
|
|
|
|
|
|
|
|
tag = tag_and_argv[0];
|
|
|
|
|
|
argv = tag_and_argv + 1;
|
|
|
|
|
|
nargs = n - 1;
|
|
|
|
|
|
|
|
|
|
|
|
prompt = scm_dynstack_find_prompt (dynstack, tag,
|
|
|
|
|
|
&flags, &fp_offset, &sp_offset,
|
|
|
|
|
|
&vra, &mra, ®isters);
|
|
|
|
|
|
|
|
|
|
|
|
if (!prompt)
|
|
|
|
|
|
{
|
|
|
|
|
|
fprintf (stderr, "guile: fatal: emergency abort to unknown prompt\n");
|
|
|
|
|
|
abort ();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (!(flags & SCM_F_DYNSTACK_PROMPT_ESCAPE_ONLY))
|
|
|
|
|
|
{
|
|
|
|
|
|
fprintf (stderr, "guile: fatal: emergency abort to non-linear prompt\n");
|
|
|
|
|
|
abort ();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
cont = SCM_BOOL_F;
|
|
|
|
|
|
|
|
|
|
|
|
/* Unwind. */
|
|
|
|
|
|
scm_dynstack_unwind (dynstack, prompt);
|
|
|
|
|
|
|
2020-01-02 13:27:23 +01:00
|
|
|
|
fp = vp->stack_top - fp_offset;
|
|
|
|
|
|
sp = vp->stack_top - sp_offset;
|
|
|
|
|
|
|
2020-03-17 22:51:40 +01:00
|
|
|
|
/* Restore FP first so that a concurrent 'scm_i_vm_mark_stack' does
|
|
|
|
|
|
not overwrite the 'abort' arguments assigned below (see
|
|
|
|
|
|
<https://bugs.gnu.org/28211>). */
|
|
|
|
|
|
vp->fp = fp;
|
|
|
|
|
|
|
2018-09-15 10:41:35 +02:00
|
|
|
|
/* Continuation gets nargs+1 values: the one more is for the cont. */
|
|
|
|
|
|
sp = sp - nargs - 1;
|
|
|
|
|
|
|
|
|
|
|
|
/* Shuffle abort arguments down to the prompt continuation. We have
|
|
|
|
|
|
to be jumping to an older part of the stack. */
|
|
|
|
|
|
if (sp < vp->sp)
|
|
|
|
|
|
abort ();
|
|
|
|
|
|
sp[nargs].as_scm = cont;
|
|
|
|
|
|
|
|
|
|
|
|
while (nargs--)
|
|
|
|
|
|
sp[nargs].as_scm = *argv++;
|
|
|
|
|
|
|
|
|
|
|
|
/* Restore VM regs */
|
|
|
|
|
|
vp->sp = sp;
|
|
|
|
|
|
vp->ip = vra;
|
|
|
|
|
|
|
|
|
|
|
|
/* Jump! */
|
|
|
|
|
|
vp->mra_after_abort = mra;
|
|
|
|
|
|
longjmp (*registers, 1);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
Continuations capture machine code address
* libguile/continuations.c (scm_i_continuation_to_frame): Adapt to vra
field renaming.
(scm_i_reinstate_continuation, grow_stack, copy_stack_and_call)
(scm_dynthrow): Take mra of continuation. Set on the vp before the
longjmp.
* libguile/continuations.h: Update scm_i_reinstate_continuation
prototype.
* libguile/dynstack.h:
* libguile/control.c (scm_suspendable_continuation_p):
* libguile/dynstack.c (PROMPT_WORDS, PROMPT_VRA, PROMPT_MRA):
(PROMPT_JMPBUF, scm_dynstack_push_prompt, scm_dynstack_find_prompt)
(scm_dynstack_wind_prompt): Store both virtual and machine return
addresses on the dynstack, for prompts.
* libguile/eval.c (eval): Pass NULL for mra.
* libguile/intrinsics.c (push_prompt): Add mra arg, and pass it to the
dynstack.
* libguile/intrinsics.h: Update prototypes so that continuation-related
intrinsics can save and restore the MRA.
* libguile/jit.h:
* libguile/jit.c: Return VRA when JIT code needs to tier down.
* libguile/stacks.c (find_prompt, scm_make_stack)
* libguile/throw.c (catch): Adapt find-prompt calls.
* libguile/vm-engine.c (instrument-entry, instrument-loop): Add logic to
continue with vcode after the mcode finishes.
(compose-continuation, capture-continuation, abort, prompt): Add logic
to pass NULL as captured MRA, but continue with mcode from new
continuations, if appropriate.
* libguile/vm.c (scm_i_vm_cont_to_frame, capture_stack)
(scm_i_capture_current_stack, reinstate_continuation_x)
(capture_continuation, compose_continuation_inner, compose_continuation)
(capture_delimited_continuation, abort_to_prompt): Adapt to plumb
around machine code continuations.
(scm_call_n): Check "mra_after_abort" field for machine code
continuation, if any.
* libguile/vm.h (struct scm_vm): Add "mra_after_abort" field.
(struct scm_vm_cont): Rename "ra" field to "vra" and add "mra" field.
2018-08-12 15:57:53 +02:00
|
|
|
|
static uint8_t *
|
|
|
|
|
|
abort_to_prompt (scm_thread *thread, uint8_t *saved_mra)
|
2018-06-26 16:19:16 +02:00
|
|
|
|
{
|
2018-06-26 17:08:24 +02:00
|
|
|
|
struct scm_vm *vp = &thread->vm;
|
|
|
|
|
|
scm_t_dynstack *dynstack = &thread->dynstack;
|
|
|
|
|
|
SCM tag, cont;
|
|
|
|
|
|
size_t nargs;
|
2018-06-26 16:19:16 +02:00
|
|
|
|
scm_t_bits *prompt;
|
|
|
|
|
|
scm_t_dynstack_prompt_flags flags;
|
|
|
|
|
|
ptrdiff_t fp_offset, sp_offset;
|
|
|
|
|
|
union scm_vm_stack_element *fp, *sp;
|
Continuations capture machine code address
* libguile/continuations.c (scm_i_continuation_to_frame): Adapt to vra
field renaming.
(scm_i_reinstate_continuation, grow_stack, copy_stack_and_call)
(scm_dynthrow): Take mra of continuation. Set on the vp before the
longjmp.
* libguile/continuations.h: Update scm_i_reinstate_continuation
prototype.
* libguile/dynstack.h:
* libguile/control.c (scm_suspendable_continuation_p):
* libguile/dynstack.c (PROMPT_WORDS, PROMPT_VRA, PROMPT_MRA):
(PROMPT_JMPBUF, scm_dynstack_push_prompt, scm_dynstack_find_prompt)
(scm_dynstack_wind_prompt): Store both virtual and machine return
addresses on the dynstack, for prompts.
* libguile/eval.c (eval): Pass NULL for mra.
* libguile/intrinsics.c (push_prompt): Add mra arg, and pass it to the
dynstack.
* libguile/intrinsics.h: Update prototypes so that continuation-related
intrinsics can save and restore the MRA.
* libguile/jit.h:
* libguile/jit.c: Return VRA when JIT code needs to tier down.
* libguile/stacks.c (find_prompt, scm_make_stack)
* libguile/throw.c (catch): Adapt find-prompt calls.
* libguile/vm-engine.c (instrument-entry, instrument-loop): Add logic to
continue with vcode after the mcode finishes.
(compose-continuation, capture-continuation, abort, prompt): Add logic
to pass NULL as captured MRA, but continue with mcode from new
continuations, if appropriate.
* libguile/vm.c (scm_i_vm_cont_to_frame, capture_stack)
(scm_i_capture_current_stack, reinstate_continuation_x)
(capture_continuation, compose_continuation_inner, compose_continuation)
(capture_delimited_continuation, abort_to_prompt): Adapt to plumb
around machine code continuations.
(scm_call_n): Check "mra_after_abort" field for machine code
continuation, if any.
* libguile/vm.h (struct scm_vm): Add "mra_after_abort" field.
(struct scm_vm_cont): Rename "ra" field to "vra" and add "mra" field.
2018-08-12 15:57:53 +02:00
|
|
|
|
uint32_t *vra;
|
|
|
|
|
|
uint8_t *mra;
|
2018-06-26 16:19:16 +02:00
|
|
|
|
jmp_buf *registers;
|
2018-06-26 17:08:24 +02:00
|
|
|
|
|
|
|
|
|
|
tag = SCM_FRAME_LOCAL (vp->fp, 1);
|
|
|
|
|
|
nargs = frame_locals_count (thread) - 2;
|
2018-06-26 16:19:16 +02:00
|
|
|
|
|
|
|
|
|
|
prompt = scm_dynstack_find_prompt (dynstack, tag,
|
Continuations capture machine code address
* libguile/continuations.c (scm_i_continuation_to_frame): Adapt to vra
field renaming.
(scm_i_reinstate_continuation, grow_stack, copy_stack_and_call)
(scm_dynthrow): Take mra of continuation. Set on the vp before the
longjmp.
* libguile/continuations.h: Update scm_i_reinstate_continuation
prototype.
* libguile/dynstack.h:
* libguile/control.c (scm_suspendable_continuation_p):
* libguile/dynstack.c (PROMPT_WORDS, PROMPT_VRA, PROMPT_MRA):
(PROMPT_JMPBUF, scm_dynstack_push_prompt, scm_dynstack_find_prompt)
(scm_dynstack_wind_prompt): Store both virtual and machine return
addresses on the dynstack, for prompts.
* libguile/eval.c (eval): Pass NULL for mra.
* libguile/intrinsics.c (push_prompt): Add mra arg, and pass it to the
dynstack.
* libguile/intrinsics.h: Update prototypes so that continuation-related
intrinsics can save and restore the MRA.
* libguile/jit.h:
* libguile/jit.c: Return VRA when JIT code needs to tier down.
* libguile/stacks.c (find_prompt, scm_make_stack)
* libguile/throw.c (catch): Adapt find-prompt calls.
* libguile/vm-engine.c (instrument-entry, instrument-loop): Add logic to
continue with vcode after the mcode finishes.
(compose-continuation, capture-continuation, abort, prompt): Add logic
to pass NULL as captured MRA, but continue with mcode from new
continuations, if appropriate.
* libguile/vm.c (scm_i_vm_cont_to_frame, capture_stack)
(scm_i_capture_current_stack, reinstate_continuation_x)
(capture_continuation, compose_continuation_inner, compose_continuation)
(capture_delimited_continuation, abort_to_prompt): Adapt to plumb
around machine code continuations.
(scm_call_n): Check "mra_after_abort" field for machine code
continuation, if any.
* libguile/vm.h (struct scm_vm): Add "mra_after_abort" field.
(struct scm_vm_cont): Rename "ra" field to "vra" and add "mra" field.
2018-08-12 15:57:53 +02:00
|
|
|
|
&flags, &fp_offset, &sp_offset,
|
|
|
|
|
|
&vra, &mra, ®isters);
|
2018-06-26 16:19:16 +02:00
|
|
|
|
|
|
|
|
|
|
if (!prompt)
|
|
|
|
|
|
scm_misc_error ("abort", "Abort to unknown prompt", scm_list_1 (tag));
|
|
|
|
|
|
|
|
|
|
|
|
fp = vp->stack_top - fp_offset;
|
|
|
|
|
|
|
|
|
|
|
|
/* Only reify if the continuation referenced in the handler. */
|
|
|
|
|
|
if (flags & SCM_F_DYNSTACK_PROMPT_ESCAPE_ONLY)
|
|
|
|
|
|
cont = SCM_BOOL_F;
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
scm_t_dynstack *captured;
|
|
|
|
|
|
|
|
|
|
|
|
captured = scm_dynstack_capture (dynstack, SCM_DYNSTACK_NEXT (prompt));
|
Continuations capture machine code address
* libguile/continuations.c (scm_i_continuation_to_frame): Adapt to vra
field renaming.
(scm_i_reinstate_continuation, grow_stack, copy_stack_and_call)
(scm_dynthrow): Take mra of continuation. Set on the vp before the
longjmp.
* libguile/continuations.h: Update scm_i_reinstate_continuation
prototype.
* libguile/dynstack.h:
* libguile/control.c (scm_suspendable_continuation_p):
* libguile/dynstack.c (PROMPT_WORDS, PROMPT_VRA, PROMPT_MRA):
(PROMPT_JMPBUF, scm_dynstack_push_prompt, scm_dynstack_find_prompt)
(scm_dynstack_wind_prompt): Store both virtual and machine return
addresses on the dynstack, for prompts.
* libguile/eval.c (eval): Pass NULL for mra.
* libguile/intrinsics.c (push_prompt): Add mra arg, and pass it to the
dynstack.
* libguile/intrinsics.h: Update prototypes so that continuation-related
intrinsics can save and restore the MRA.
* libguile/jit.h:
* libguile/jit.c: Return VRA when JIT code needs to tier down.
* libguile/stacks.c (find_prompt, scm_make_stack)
* libguile/throw.c (catch): Adapt find-prompt calls.
* libguile/vm-engine.c (instrument-entry, instrument-loop): Add logic to
continue with vcode after the mcode finishes.
(compose-continuation, capture-continuation, abort, prompt): Add logic
to pass NULL as captured MRA, but continue with mcode from new
continuations, if appropriate.
* libguile/vm.c (scm_i_vm_cont_to_frame, capture_stack)
(scm_i_capture_current_stack, reinstate_continuation_x)
(capture_continuation, compose_continuation_inner, compose_continuation)
(capture_delimited_continuation, abort_to_prompt): Adapt to plumb
around machine code continuations.
(scm_call_n): Check "mra_after_abort" field for machine code
continuation, if any.
* libguile/vm.h (struct scm_vm): Add "mra_after_abort" field.
(struct scm_vm_cont): Rename "ra" field to "vra" and add "mra" field.
2018-08-12 15:57:53 +02:00
|
|
|
|
cont = capture_delimited_continuation (vp, fp, saved_mra, registers,
|
|
|
|
|
|
captured, thread->vm.registers);
|
2018-06-26 16:19:16 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Unwind. */
|
|
|
|
|
|
scm_dynstack_unwind (dynstack, prompt);
|
|
|
|
|
|
|
2020-01-02 13:27:23 +01:00
|
|
|
|
/* Recompute FP, as scm_dynstack_unwind may have expanded the stack. */
|
|
|
|
|
|
fp = vp->stack_top - fp_offset;
|
|
|
|
|
|
sp = vp->stack_top - sp_offset;
|
|
|
|
|
|
|
2018-07-19 13:56:13 +02:00
|
|
|
|
/* Continuation gets nargs+1 values: the one more is for the cont. */
|
2018-06-26 17:08:24 +02:00
|
|
|
|
sp = sp - nargs - 1;
|
2018-06-26 16:19:16 +02:00
|
|
|
|
|
2020-03-17 22:51:40 +01:00
|
|
|
|
/* Restore FP first so that a concurrent 'scm_i_vm_mark_stack' does
|
|
|
|
|
|
not overwrite the 'abort' arguments assigned below (see
|
|
|
|
|
|
<https://bugs.gnu.org/28211>). */
|
|
|
|
|
|
vp->fp = fp;
|
|
|
|
|
|
|
2018-06-26 17:08:24 +02:00
|
|
|
|
/* Shuffle abort arguments down to the prompt continuation. We have
|
|
|
|
|
|
to be jumping to an older part of the stack. */
|
|
|
|
|
|
if (sp < vp->sp)
|
2018-06-26 16:19:16 +02:00
|
|
|
|
abort ();
|
2018-06-26 17:08:24 +02:00
|
|
|
|
sp[nargs].as_scm = cont;
|
|
|
|
|
|
while (nargs--)
|
|
|
|
|
|
sp[nargs] = vp->sp[nargs];
|
2018-06-26 16:19:16 +02:00
|
|
|
|
|
2018-06-26 17:08:24 +02:00
|
|
|
|
/* Restore VM regs */
|
|
|
|
|
|
vp->sp = sp;
|
Continuations capture machine code address
* libguile/continuations.c (scm_i_continuation_to_frame): Adapt to vra
field renaming.
(scm_i_reinstate_continuation, grow_stack, copy_stack_and_call)
(scm_dynthrow): Take mra of continuation. Set on the vp before the
longjmp.
* libguile/continuations.h: Update scm_i_reinstate_continuation
prototype.
* libguile/dynstack.h:
* libguile/control.c (scm_suspendable_continuation_p):
* libguile/dynstack.c (PROMPT_WORDS, PROMPT_VRA, PROMPT_MRA):
(PROMPT_JMPBUF, scm_dynstack_push_prompt, scm_dynstack_find_prompt)
(scm_dynstack_wind_prompt): Store both virtual and machine return
addresses on the dynstack, for prompts.
* libguile/eval.c (eval): Pass NULL for mra.
* libguile/intrinsics.c (push_prompt): Add mra arg, and pass it to the
dynstack.
* libguile/intrinsics.h: Update prototypes so that continuation-related
intrinsics can save and restore the MRA.
* libguile/jit.h:
* libguile/jit.c: Return VRA when JIT code needs to tier down.
* libguile/stacks.c (find_prompt, scm_make_stack)
* libguile/throw.c (catch): Adapt find-prompt calls.
* libguile/vm-engine.c (instrument-entry, instrument-loop): Add logic to
continue with vcode after the mcode finishes.
(compose-continuation, capture-continuation, abort, prompt): Add logic
to pass NULL as captured MRA, but continue with mcode from new
continuations, if appropriate.
* libguile/vm.c (scm_i_vm_cont_to_frame, capture_stack)
(scm_i_capture_current_stack, reinstate_continuation_x)
(capture_continuation, compose_continuation_inner, compose_continuation)
(capture_delimited_continuation, abort_to_prompt): Adapt to plumb
around machine code continuations.
(scm_call_n): Check "mra_after_abort" field for machine code
continuation, if any.
* libguile/vm.h (struct scm_vm): Add "mra_after_abort" field.
(struct scm_vm_cont): Rename "ra" field to "vra" and add "mra" field.
2018-08-12 15:57:53 +02:00
|
|
|
|
vp->ip = vra;
|
2018-06-26 16:19:16 +02:00
|
|
|
|
|
2018-06-26 17:16:19 +02:00
|
|
|
|
/* If there are intervening C frames, then jump over them, making a
|
|
|
|
|
|
nonlocal exit. Otherwise fall through and let the VM pick up where
|
|
|
|
|
|
it left off. */
|
2018-06-27 18:42:21 +02:00
|
|
|
|
if (thread->vm.registers != registers)
|
Continuations capture machine code address
* libguile/continuations.c (scm_i_continuation_to_frame): Adapt to vra
field renaming.
(scm_i_reinstate_continuation, grow_stack, copy_stack_and_call)
(scm_dynthrow): Take mra of continuation. Set on the vp before the
longjmp.
* libguile/continuations.h: Update scm_i_reinstate_continuation
prototype.
* libguile/dynstack.h:
* libguile/control.c (scm_suspendable_continuation_p):
* libguile/dynstack.c (PROMPT_WORDS, PROMPT_VRA, PROMPT_MRA):
(PROMPT_JMPBUF, scm_dynstack_push_prompt, scm_dynstack_find_prompt)
(scm_dynstack_wind_prompt): Store both virtual and machine return
addresses on the dynstack, for prompts.
* libguile/eval.c (eval): Pass NULL for mra.
* libguile/intrinsics.c (push_prompt): Add mra arg, and pass it to the
dynstack.
* libguile/intrinsics.h: Update prototypes so that continuation-related
intrinsics can save and restore the MRA.
* libguile/jit.h:
* libguile/jit.c: Return VRA when JIT code needs to tier down.
* libguile/stacks.c (find_prompt, scm_make_stack)
* libguile/throw.c (catch): Adapt find-prompt calls.
* libguile/vm-engine.c (instrument-entry, instrument-loop): Add logic to
continue with vcode after the mcode finishes.
(compose-continuation, capture-continuation, abort, prompt): Add logic
to pass NULL as captured MRA, but continue with mcode from new
continuations, if appropriate.
* libguile/vm.c (scm_i_vm_cont_to_frame, capture_stack)
(scm_i_capture_current_stack, reinstate_continuation_x)
(capture_continuation, compose_continuation_inner, compose_continuation)
(capture_delimited_continuation, abort_to_prompt): Adapt to plumb
around machine code continuations.
(scm_call_n): Check "mra_after_abort" field for machine code
continuation, if any.
* libguile/vm.h (struct scm_vm): Add "mra_after_abort" field.
(struct scm_vm_cont): Rename "ra" field to "vra" and add "mra" field.
2018-08-12 15:57:53 +02:00
|
|
|
|
{
|
|
|
|
|
|
vp->mra_after_abort = mra;
|
|
|
|
|
|
longjmp (*registers, 1);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return mra;
|
2018-06-26 16:19:16 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2018-08-08 15:22:28 +02:00
|
|
|
|
static uint32_t *
|
|
|
|
|
|
get_callee_vcode (scm_thread *thread)
|
2018-06-27 13:38:30 +02:00
|
|
|
|
{
|
|
|
|
|
|
struct scm_vm *vp = &thread->vm;
|
|
|
|
|
|
|
|
|
|
|
|
SCM proc = SCM_FRAME_LOCAL (vp->fp, 0);
|
|
|
|
|
|
|
2018-08-08 15:22:28 +02:00
|
|
|
|
if (SCM_LIKELY (SCM_PROGRAM_P (proc)))
|
|
|
|
|
|
return SCM_PROGRAM_CODE (proc);
|
|
|
|
|
|
|
2018-06-27 13:38:30 +02:00
|
|
|
|
while (SCM_STRUCTP (proc) && SCM_STRUCT_APPLICABLE_P (proc))
|
|
|
|
|
|
{
|
|
|
|
|
|
proc = SCM_STRUCT_PROCEDURE (proc);
|
|
|
|
|
|
SCM_FRAME_LOCAL (vp->fp, 0) = proc;
|
|
|
|
|
|
|
|
|
|
|
|
if (SCM_PROGRAM_P (proc))
|
2018-08-08 15:22:28 +02:00
|
|
|
|
return SCM_PROGRAM_CODE (proc);
|
2018-06-27 13:38:30 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (SCM_HAS_TYP7 (proc, scm_tc7_smob) && SCM_SMOB_APPLICABLE_P (proc))
|
|
|
|
|
|
{
|
|
|
|
|
|
uint32_t n = frame_locals_count (thread);
|
|
|
|
|
|
|
|
|
|
|
|
alloc_frame (thread, n + 1);
|
|
|
|
|
|
|
|
|
|
|
|
/* Although we could make VM modifications to avoid this shuffle,
|
|
|
|
|
|
it's easier to piggy-back on the subr arg parsing machinery.
|
|
|
|
|
|
Hopefully applicable smobs will go away in the mid-term. */
|
|
|
|
|
|
while (n--)
|
|
|
|
|
|
SCM_FRAME_LOCAL (vp->fp, n + 1) = SCM_FRAME_LOCAL (vp->fp, n);
|
|
|
|
|
|
|
|
|
|
|
|
proc = SCM_SMOB_DESCRIPTOR (proc).apply_trampoline;
|
|
|
|
|
|
SCM_FRAME_LOCAL (vp->fp, 0) = proc;
|
2018-08-08 15:22:28 +02:00
|
|
|
|
return SCM_PROGRAM_CODE (proc);
|
2018-06-27 13:38:30 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2018-08-08 15:40:12 +02:00
|
|
|
|
vp->ip = SCM_FRAME_VIRTUAL_RETURN_ADDRESS (vp->fp);
|
|
|
|
|
|
|
2018-06-27 13:38:30 +02:00
|
|
|
|
scm_error (scm_arg_type_key, NULL, "Wrong type to apply: ~S",
|
|
|
|
|
|
scm_list_1 (proc), scm_list_1 (proc));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2013-11-21 18:50:12 +01:00
|
|
|
|
SCM
|
|
|
|
|
|
scm_call_n (SCM proc, SCM *argv, size_t nargs)
|
|
|
|
|
|
{
|
2018-06-26 11:40:22 +02:00
|
|
|
|
scm_thread *thread;
|
2013-11-21 18:50:12 +01:00
|
|
|
|
struct scm_vm *vp;
|
VM stack grows downward
Adapt VM stack to grow downward. This will make native compilation look
more like the VM code, as we will be able to use native CALL
instructions, taking proper advantage of the return address buffer.
* libguile/continuations.c (scm_i_continuation_to_frame): Record offsets
from stack top.
* libguile/control.c (scm_i_prompt_pop_abort_args_x): Adapt for reversed
order of arguments, and instead of relying on the abort to push on the
number of arguments, make the caller save the stack depth, which
allows us to compute the number of arguments ourselves.
(reify_partial_continuation, scm_c_abort): Adapt to reversed stack
order.
* libguile/dynstack.c (scm_dynstack_wind_prompt): Since we wind the
stack in a downward direction, subtract the reloc instead of adding
it.
* libguile/dynstack.h (SCM_F_DYNSTACK_PROMPT_ESCAPE_ONLY): Remove flag;
instead rely on prompt-establishing code to save the stack depth.
* libguile/eval.c (eval): Remove extraneous "volatile" declarations for
variables that are not re-set between the setjmp and any longjmp.
Adapt to save stack depth before instating the prompt.
* libguile/foreign.c (scm_i_foreign_call): Adapt to receive arguments in
reverse order.
* libguile/frames.c (frame_stack_top, scm_i_frame_stack_top): Adapt to
compute stack top instead of stack bottom.
(scm_c_frame_closure): Adapt to stack growth change.
(scm_frame_num_locals, scm_frame_local_ref, scm_frame_set_x): Use
union data type to access stack.
(RELOC): Reformat.
(scm_c_frame_previous): Adapt to stack growth change.
* libguile/frames.h: Adapt stack diagram to indicate that the stack
grows up.
(union scm_vm_stack_element): New data type used to access items on
the stack.
(SCM_FRAME_PREVIOUS_SP)
(SCM_FRAME_RETURN_ADDRESS, SCM_FRAME_SET_RETURN_ADDRESS)
(SCM_FRAME_DYNAMIC_LINK, SCM_FRAME_SET_DYNAMIC_LINK)
(SCM_FRAME_LOCAL, SCM_FRAME_NUM_LOCALS): Adapt to stack representation
change.
(SCM_FRAME_SLOT): New helper.
(SCM_VM_FRAME_FP, SCM_VM_FRAME_SP): Adapt to stack growth change.
* libguile/stacks.c (scm_make_stack): Record offsets from top of stack.
* libguile/throw.c (catch): Adapt to scm_i_prompt_pop_abort_args_x
change.
* libguile/vm-engine.c (ALLOC_FRAME, RESET_FRAME):
(FRAME_LOCALS_COUNT_FROM): Adapt to stack growth change.
(LOCAL_ADDRESS): Use SCM_FRAME_SLOT to get the address as the proper
data type.
(RETURN_ONE_VALUE, RETURN_VALUE_LIST): Adapt to stack growth change.
(apply): Shuffling up the SMOB apply args can cause the stack to
expand, so use ALLOC_FRAME instead of RESET_FRAME.
(vm_engine): Adapt for stack growth change.
* libguile/vm.c (vm_increase_sp, vm_push_sp, vm_restore_sp): Adapt to
stack representation change.
(scm_i_vm_cont_to_frame): Adapt to take offsets from the top.
(scm_i_vm_capture_stack): Adapt to capture from the top.
(vm_return_to_continuation_inner): Adapt for data type changes.
(vm_return_to_continuation): Likewise, and instead of looping, just
splat the saved arguments on with memcpy.
(vm_dispatch_hook): Adapt to receive arguments in the reverse order.
Adapt callers.
(vm_abort): There is never a tail argument. Adapt to stack
representation change.
(vm_reinstate_partial_continuation)
(vm_reinstate_partial_continuation_inner): Adapt to stack growth
change.
(allocate_stack, free_stack): Adapt to data type change.
(expand_stack): Don't try to mremap(), as you can't grow a mapping
from the bottom. Without knowing that there's a free mapping space
right below the old stack, which there usually isn't on Linux, we have
to copy. We can't use MAP_GROWSDOWN because Linux is buggy.
(make_vm): Adapt to stack representation changes.
(return_unused_stack_to_os): Round down instead of up, as the stack
grows down.
(scm_i_vm_mark_stack): Adapt to walk up the stack.
(scm_i_vm_free_stack): Adapt to scm_vm changes.
(vm_expand_stack_inner, reset_stack_limit, vm_expand_stack): Adapt to
the stack growing down.
(scm_call_n): Adapt to the stack growing down. Don't allow argv to
point into the stack.
* libguile/vm.h (struct scm_vm, struct scm_vm_cont): Adapt to hold the
stack top and bottom.
2015-09-22 10:24:30 +00:00
|
|
|
|
union scm_vm_stack_element *return_fp, *call_fp;
|
|
|
|
|
|
/* Since nargs can only describe the length of a valid argv array in
|
|
|
|
|
|
elements and each element is at least 4 bytes, nargs will not be
|
|
|
|
|
|
greater than INTMAX/2 and therefore we don't have to check for
|
|
|
|
|
|
overflow here or below. */
|
2018-07-19 13:56:13 +02:00
|
|
|
|
size_t return_nlocals = 0, call_nlocals = nargs + 1, frame_size = 3;
|
2018-06-21 08:43:47 +02:00
|
|
|
|
ptrdiff_t stack_reserve_words;
|
2013-11-21 19:05:43 +01:00
|
|
|
|
size_t i;
|
2010-09-27 21:06:24 +02:00
|
|
|
|
|
2013-11-21 18:50:12 +01:00
|
|
|
|
thread = SCM_I_CURRENT_THREAD;
|
2018-06-24 09:32:11 +02:00
|
|
|
|
vp = &thread->vm;
|
2013-11-21 18:50:12 +01:00
|
|
|
|
|
|
|
|
|
|
SCM_CHECK_STACK;
|
2013-11-21 19:05:43 +01:00
|
|
|
|
|
VM stack grows downward
Adapt VM stack to grow downward. This will make native compilation look
more like the VM code, as we will be able to use native CALL
instructions, taking proper advantage of the return address buffer.
* libguile/continuations.c (scm_i_continuation_to_frame): Record offsets
from stack top.
* libguile/control.c (scm_i_prompt_pop_abort_args_x): Adapt for reversed
order of arguments, and instead of relying on the abort to push on the
number of arguments, make the caller save the stack depth, which
allows us to compute the number of arguments ourselves.
(reify_partial_continuation, scm_c_abort): Adapt to reversed stack
order.
* libguile/dynstack.c (scm_dynstack_wind_prompt): Since we wind the
stack in a downward direction, subtract the reloc instead of adding
it.
* libguile/dynstack.h (SCM_F_DYNSTACK_PROMPT_ESCAPE_ONLY): Remove flag;
instead rely on prompt-establishing code to save the stack depth.
* libguile/eval.c (eval): Remove extraneous "volatile" declarations for
variables that are not re-set between the setjmp and any longjmp.
Adapt to save stack depth before instating the prompt.
* libguile/foreign.c (scm_i_foreign_call): Adapt to receive arguments in
reverse order.
* libguile/frames.c (frame_stack_top, scm_i_frame_stack_top): Adapt to
compute stack top instead of stack bottom.
(scm_c_frame_closure): Adapt to stack growth change.
(scm_frame_num_locals, scm_frame_local_ref, scm_frame_set_x): Use
union data type to access stack.
(RELOC): Reformat.
(scm_c_frame_previous): Adapt to stack growth change.
* libguile/frames.h: Adapt stack diagram to indicate that the stack
grows up.
(union scm_vm_stack_element): New data type used to access items on
the stack.
(SCM_FRAME_PREVIOUS_SP)
(SCM_FRAME_RETURN_ADDRESS, SCM_FRAME_SET_RETURN_ADDRESS)
(SCM_FRAME_DYNAMIC_LINK, SCM_FRAME_SET_DYNAMIC_LINK)
(SCM_FRAME_LOCAL, SCM_FRAME_NUM_LOCALS): Adapt to stack representation
change.
(SCM_FRAME_SLOT): New helper.
(SCM_VM_FRAME_FP, SCM_VM_FRAME_SP): Adapt to stack growth change.
* libguile/stacks.c (scm_make_stack): Record offsets from top of stack.
* libguile/throw.c (catch): Adapt to scm_i_prompt_pop_abort_args_x
change.
* libguile/vm-engine.c (ALLOC_FRAME, RESET_FRAME):
(FRAME_LOCALS_COUNT_FROM): Adapt to stack growth change.
(LOCAL_ADDRESS): Use SCM_FRAME_SLOT to get the address as the proper
data type.
(RETURN_ONE_VALUE, RETURN_VALUE_LIST): Adapt to stack growth change.
(apply): Shuffling up the SMOB apply args can cause the stack to
expand, so use ALLOC_FRAME instead of RESET_FRAME.
(vm_engine): Adapt for stack growth change.
* libguile/vm.c (vm_increase_sp, vm_push_sp, vm_restore_sp): Adapt to
stack representation change.
(scm_i_vm_cont_to_frame): Adapt to take offsets from the top.
(scm_i_vm_capture_stack): Adapt to capture from the top.
(vm_return_to_continuation_inner): Adapt for data type changes.
(vm_return_to_continuation): Likewise, and instead of looping, just
splat the saved arguments on with memcpy.
(vm_dispatch_hook): Adapt to receive arguments in the reverse order.
Adapt callers.
(vm_abort): There is never a tail argument. Adapt to stack
representation change.
(vm_reinstate_partial_continuation)
(vm_reinstate_partial_continuation_inner): Adapt to stack growth
change.
(allocate_stack, free_stack): Adapt to data type change.
(expand_stack): Don't try to mremap(), as you can't grow a mapping
from the bottom. Without knowing that there's a free mapping space
right below the old stack, which there usually isn't on Linux, we have
to copy. We can't use MAP_GROWSDOWN because Linux is buggy.
(make_vm): Adapt to stack representation changes.
(return_unused_stack_to_os): Round down instead of up, as the stack
grows down.
(scm_i_vm_mark_stack): Adapt to walk up the stack.
(scm_i_vm_free_stack): Adapt to scm_vm changes.
(vm_expand_stack_inner, reset_stack_limit, vm_expand_stack): Adapt to
the stack growing down.
(scm_call_n): Adapt to the stack growing down. Don't allow argv to
point into the stack.
* libguile/vm.h (struct scm_vm, struct scm_vm_cont): Adapt to hold the
stack top and bottom.
2015-09-22 10:24:30 +00:00
|
|
|
|
/* It's not valid for argv to point into the stack already. */
|
|
|
|
|
|
if ((void *) argv < (void *) vp->stack_top &&
|
|
|
|
|
|
(void *) argv >= (void *) vp->sp)
|
|
|
|
|
|
abort();
|
|
|
|
|
|
|
|
|
|
|
|
/* Check that we have enough space for the two stack frames: the
|
|
|
|
|
|
innermost one that makes the call, and its continuation which
|
|
|
|
|
|
receives the resulting value(s) and returns from the engine
|
|
|
|
|
|
call. */
|
|
|
|
|
|
stack_reserve_words = call_nlocals + frame_size + return_nlocals + frame_size;
|
|
|
|
|
|
vm_push_sp (vp, vp->sp - stack_reserve_words);
|
|
|
|
|
|
|
|
|
|
|
|
call_fp = vp->sp + call_nlocals;
|
|
|
|
|
|
return_fp = call_fp + frame_size + return_nlocals;
|
|
|
|
|
|
|
2018-07-15 09:50:52 +02:00
|
|
|
|
SCM_FRAME_SET_VIRTUAL_RETURN_ADDRESS (return_fp, vp->ip);
|
2018-07-16 15:42:05 +02:00
|
|
|
|
SCM_FRAME_SET_MACHINE_RETURN_ADDRESS (return_fp, 0);
|
VM stack grows downward
Adapt VM stack to grow downward. This will make native compilation look
more like the VM code, as we will be able to use native CALL
instructions, taking proper advantage of the return address buffer.
* libguile/continuations.c (scm_i_continuation_to_frame): Record offsets
from stack top.
* libguile/control.c (scm_i_prompt_pop_abort_args_x): Adapt for reversed
order of arguments, and instead of relying on the abort to push on the
number of arguments, make the caller save the stack depth, which
allows us to compute the number of arguments ourselves.
(reify_partial_continuation, scm_c_abort): Adapt to reversed stack
order.
* libguile/dynstack.c (scm_dynstack_wind_prompt): Since we wind the
stack in a downward direction, subtract the reloc instead of adding
it.
* libguile/dynstack.h (SCM_F_DYNSTACK_PROMPT_ESCAPE_ONLY): Remove flag;
instead rely on prompt-establishing code to save the stack depth.
* libguile/eval.c (eval): Remove extraneous "volatile" declarations for
variables that are not re-set between the setjmp and any longjmp.
Adapt to save stack depth before instating the prompt.
* libguile/foreign.c (scm_i_foreign_call): Adapt to receive arguments in
reverse order.
* libguile/frames.c (frame_stack_top, scm_i_frame_stack_top): Adapt to
compute stack top instead of stack bottom.
(scm_c_frame_closure): Adapt to stack growth change.
(scm_frame_num_locals, scm_frame_local_ref, scm_frame_set_x): Use
union data type to access stack.
(RELOC): Reformat.
(scm_c_frame_previous): Adapt to stack growth change.
* libguile/frames.h: Adapt stack diagram to indicate that the stack
grows up.
(union scm_vm_stack_element): New data type used to access items on
the stack.
(SCM_FRAME_PREVIOUS_SP)
(SCM_FRAME_RETURN_ADDRESS, SCM_FRAME_SET_RETURN_ADDRESS)
(SCM_FRAME_DYNAMIC_LINK, SCM_FRAME_SET_DYNAMIC_LINK)
(SCM_FRAME_LOCAL, SCM_FRAME_NUM_LOCALS): Adapt to stack representation
change.
(SCM_FRAME_SLOT): New helper.
(SCM_VM_FRAME_FP, SCM_VM_FRAME_SP): Adapt to stack growth change.
* libguile/stacks.c (scm_make_stack): Record offsets from top of stack.
* libguile/throw.c (catch): Adapt to scm_i_prompt_pop_abort_args_x
change.
* libguile/vm-engine.c (ALLOC_FRAME, RESET_FRAME):
(FRAME_LOCALS_COUNT_FROM): Adapt to stack growth change.
(LOCAL_ADDRESS): Use SCM_FRAME_SLOT to get the address as the proper
data type.
(RETURN_ONE_VALUE, RETURN_VALUE_LIST): Adapt to stack growth change.
(apply): Shuffling up the SMOB apply args can cause the stack to
expand, so use ALLOC_FRAME instead of RESET_FRAME.
(vm_engine): Adapt for stack growth change.
* libguile/vm.c (vm_increase_sp, vm_push_sp, vm_restore_sp): Adapt to
stack representation change.
(scm_i_vm_cont_to_frame): Adapt to take offsets from the top.
(scm_i_vm_capture_stack): Adapt to capture from the top.
(vm_return_to_continuation_inner): Adapt for data type changes.
(vm_return_to_continuation): Likewise, and instead of looping, just
splat the saved arguments on with memcpy.
(vm_dispatch_hook): Adapt to receive arguments in the reverse order.
Adapt callers.
(vm_abort): There is never a tail argument. Adapt to stack
representation change.
(vm_reinstate_partial_continuation)
(vm_reinstate_partial_continuation_inner): Adapt to stack growth
change.
(allocate_stack, free_stack): Adapt to data type change.
(expand_stack): Don't try to mremap(), as you can't grow a mapping
from the bottom. Without knowing that there's a free mapping space
right below the old stack, which there usually isn't on Linux, we have
to copy. We can't use MAP_GROWSDOWN because Linux is buggy.
(make_vm): Adapt to stack representation changes.
(return_unused_stack_to_os): Round down instead of up, as the stack
grows down.
(scm_i_vm_mark_stack): Adapt to walk up the stack.
(scm_i_vm_free_stack): Adapt to scm_vm changes.
(vm_expand_stack_inner, reset_stack_limit, vm_expand_stack): Adapt to
the stack growing down.
(scm_call_n): Adapt to the stack growing down. Don't allow argv to
point into the stack.
* libguile/vm.h (struct scm_vm, struct scm_vm_cont): Adapt to hold the
stack top and bottom.
2015-09-22 10:24:30 +00:00
|
|
|
|
SCM_FRAME_SET_DYNAMIC_LINK (return_fp, vp->fp);
|
|
|
|
|
|
|
2018-06-21 08:39:03 +02:00
|
|
|
|
vp->ip = (uint32_t *) vm_boot_continuation_code;
|
2013-11-21 19:05:43 +01:00
|
|
|
|
|
2018-07-15 09:50:52 +02:00
|
|
|
|
SCM_FRAME_SET_VIRTUAL_RETURN_ADDRESS (call_fp, vp->ip);
|
2018-07-16 15:42:05 +02:00
|
|
|
|
SCM_FRAME_SET_MACHINE_RETURN_ADDRESS (call_fp, 0);
|
VM stack grows downward
Adapt VM stack to grow downward. This will make native compilation look
more like the VM code, as we will be able to use native CALL
instructions, taking proper advantage of the return address buffer.
* libguile/continuations.c (scm_i_continuation_to_frame): Record offsets
from stack top.
* libguile/control.c (scm_i_prompt_pop_abort_args_x): Adapt for reversed
order of arguments, and instead of relying on the abort to push on the
number of arguments, make the caller save the stack depth, which
allows us to compute the number of arguments ourselves.
(reify_partial_continuation, scm_c_abort): Adapt to reversed stack
order.
* libguile/dynstack.c (scm_dynstack_wind_prompt): Since we wind the
stack in a downward direction, subtract the reloc instead of adding
it.
* libguile/dynstack.h (SCM_F_DYNSTACK_PROMPT_ESCAPE_ONLY): Remove flag;
instead rely on prompt-establishing code to save the stack depth.
* libguile/eval.c (eval): Remove extraneous "volatile" declarations for
variables that are not re-set between the setjmp and any longjmp.
Adapt to save stack depth before instating the prompt.
* libguile/foreign.c (scm_i_foreign_call): Adapt to receive arguments in
reverse order.
* libguile/frames.c (frame_stack_top, scm_i_frame_stack_top): Adapt to
compute stack top instead of stack bottom.
(scm_c_frame_closure): Adapt to stack growth change.
(scm_frame_num_locals, scm_frame_local_ref, scm_frame_set_x): Use
union data type to access stack.
(RELOC): Reformat.
(scm_c_frame_previous): Adapt to stack growth change.
* libguile/frames.h: Adapt stack diagram to indicate that the stack
grows up.
(union scm_vm_stack_element): New data type used to access items on
the stack.
(SCM_FRAME_PREVIOUS_SP)
(SCM_FRAME_RETURN_ADDRESS, SCM_FRAME_SET_RETURN_ADDRESS)
(SCM_FRAME_DYNAMIC_LINK, SCM_FRAME_SET_DYNAMIC_LINK)
(SCM_FRAME_LOCAL, SCM_FRAME_NUM_LOCALS): Adapt to stack representation
change.
(SCM_FRAME_SLOT): New helper.
(SCM_VM_FRAME_FP, SCM_VM_FRAME_SP): Adapt to stack growth change.
* libguile/stacks.c (scm_make_stack): Record offsets from top of stack.
* libguile/throw.c (catch): Adapt to scm_i_prompt_pop_abort_args_x
change.
* libguile/vm-engine.c (ALLOC_FRAME, RESET_FRAME):
(FRAME_LOCALS_COUNT_FROM): Adapt to stack growth change.
(LOCAL_ADDRESS): Use SCM_FRAME_SLOT to get the address as the proper
data type.
(RETURN_ONE_VALUE, RETURN_VALUE_LIST): Adapt to stack growth change.
(apply): Shuffling up the SMOB apply args can cause the stack to
expand, so use ALLOC_FRAME instead of RESET_FRAME.
(vm_engine): Adapt for stack growth change.
* libguile/vm.c (vm_increase_sp, vm_push_sp, vm_restore_sp): Adapt to
stack representation change.
(scm_i_vm_cont_to_frame): Adapt to take offsets from the top.
(scm_i_vm_capture_stack): Adapt to capture from the top.
(vm_return_to_continuation_inner): Adapt for data type changes.
(vm_return_to_continuation): Likewise, and instead of looping, just
splat the saved arguments on with memcpy.
(vm_dispatch_hook): Adapt to receive arguments in the reverse order.
Adapt callers.
(vm_abort): There is never a tail argument. Adapt to stack
representation change.
(vm_reinstate_partial_continuation)
(vm_reinstate_partial_continuation_inner): Adapt to stack growth
change.
(allocate_stack, free_stack): Adapt to data type change.
(expand_stack): Don't try to mremap(), as you can't grow a mapping
from the bottom. Without knowing that there's a free mapping space
right below the old stack, which there usually isn't on Linux, we have
to copy. We can't use MAP_GROWSDOWN because Linux is buggy.
(make_vm): Adapt to stack representation changes.
(return_unused_stack_to_os): Round down instead of up, as the stack
grows down.
(scm_i_vm_mark_stack): Adapt to walk up the stack.
(scm_i_vm_free_stack): Adapt to scm_vm changes.
(vm_expand_stack_inner, reset_stack_limit, vm_expand_stack): Adapt to
the stack growing down.
(scm_call_n): Adapt to the stack growing down. Don't allow argv to
point into the stack.
* libguile/vm.h (struct scm_vm, struct scm_vm_cont): Adapt to hold the
stack top and bottom.
2015-09-22 10:24:30 +00:00
|
|
|
|
SCM_FRAME_SET_DYNAMIC_LINK (call_fp, return_fp);
|
|
|
|
|
|
SCM_FRAME_LOCAL (call_fp, 0) = proc;
|
|
|
|
|
|
for (i = 0; i < nargs; i++)
|
|
|
|
|
|
SCM_FRAME_LOCAL (call_fp, i + 1) = argv[i];
|
2014-01-31 21:41:36 +01:00
|
|
|
|
|
2018-06-29 22:28:48 +02:00
|
|
|
|
vp->fp = call_fp;
|
|
|
|
|
|
|
2013-11-21 21:15:58 +01:00
|
|
|
|
{
|
2018-06-17 13:03:39 +02:00
|
|
|
|
jmp_buf registers;
|
2016-12-12 20:55:08 +01:00
|
|
|
|
int resume;
|
2018-06-27 18:21:04 +02:00
|
|
|
|
jmp_buf *prev_registers = thread->vm.registers;
|
2016-12-12 20:55:08 +01:00
|
|
|
|
SCM ret;
|
|
|
|
|
|
|
2018-06-17 13:03:39 +02:00
|
|
|
|
resume = setjmp (registers);
|
2018-09-03 18:30:45 +02:00
|
|
|
|
|
|
|
|
|
|
thread->vm.registers = ®isters;
|
|
|
|
|
|
|
2013-11-21 21:15:58 +01:00
|
|
|
|
if (SCM_UNLIKELY (resume))
|
2014-03-22 15:49:31 +01:00
|
|
|
|
{
|
Continuations capture machine code address
* libguile/continuations.c (scm_i_continuation_to_frame): Adapt to vra
field renaming.
(scm_i_reinstate_continuation, grow_stack, copy_stack_and_call)
(scm_dynthrow): Take mra of continuation. Set on the vp before the
longjmp.
* libguile/continuations.h: Update scm_i_reinstate_continuation
prototype.
* libguile/dynstack.h:
* libguile/control.c (scm_suspendable_continuation_p):
* libguile/dynstack.c (PROMPT_WORDS, PROMPT_VRA, PROMPT_MRA):
(PROMPT_JMPBUF, scm_dynstack_push_prompt, scm_dynstack_find_prompt)
(scm_dynstack_wind_prompt): Store both virtual and machine return
addresses on the dynstack, for prompts.
* libguile/eval.c (eval): Pass NULL for mra.
* libguile/intrinsics.c (push_prompt): Add mra arg, and pass it to the
dynstack.
* libguile/intrinsics.h: Update prototypes so that continuation-related
intrinsics can save and restore the MRA.
* libguile/jit.h:
* libguile/jit.c: Return VRA when JIT code needs to tier down.
* libguile/stacks.c (find_prompt, scm_make_stack)
* libguile/throw.c (catch): Adapt find-prompt calls.
* libguile/vm-engine.c (instrument-entry, instrument-loop): Add logic to
continue with vcode after the mcode finishes.
(compose-continuation, capture-continuation, abort, prompt): Add logic
to pass NULL as captured MRA, but continue with mcode from new
continuations, if appropriate.
* libguile/vm.c (scm_i_vm_cont_to_frame, capture_stack)
(scm_i_capture_current_stack, reinstate_continuation_x)
(capture_continuation, compose_continuation_inner, compose_continuation)
(capture_delimited_continuation, abort_to_prompt): Adapt to plumb
around machine code continuations.
(scm_call_n): Check "mra_after_abort" field for machine code
continuation, if any.
* libguile/vm.h (struct scm_vm): Add "mra_after_abort" field.
(struct scm_vm_cont): Rename "ra" field to "vra" and add "mra" field.
2018-08-12 15:57:53 +02:00
|
|
|
|
uint8_t *mcode = vp->mra_after_abort;
|
2014-03-22 15:49:31 +01:00
|
|
|
|
scm_gc_after_nonlocal_exit ();
|
|
|
|
|
|
/* Non-local return. */
|
2018-09-14 15:11:13 +02:00
|
|
|
|
if (vp->abort_hook_enabled)
|
2018-08-11 11:13:37 +02:00
|
|
|
|
invoke_abort_hook (thread);
|
2018-09-17 09:28:41 +02:00
|
|
|
|
#if ENABLE_JIT
|
2018-09-14 15:11:13 +02:00
|
|
|
|
if (mcode && !vp->disable_mcode)
|
2018-08-13 10:27:13 +02:00
|
|
|
|
scm_jit_enter_mcode (thread, mcode);
|
2018-09-17 09:28:41 +02:00
|
|
|
|
#endif
|
2014-03-22 15:49:31 +01:00
|
|
|
|
}
|
2018-06-27 18:57:37 +02:00
|
|
|
|
else
|
2018-08-08 15:22:28 +02:00
|
|
|
|
vp->ip = get_callee_vcode (thread);
|
2013-11-21 21:15:58 +01:00
|
|
|
|
|
2018-06-27 18:57:37 +02:00
|
|
|
|
ret = vm_engines[vp->engine](thread);
|
2018-06-27 18:21:04 +02:00
|
|
|
|
thread->vm.registers = prev_registers;
|
2016-12-12 20:55:08 +01:00
|
|
|
|
|
|
|
|
|
|
return ret;
|
2013-11-21 21:15:58 +01:00
|
|
|
|
}
|
2010-09-24 15:14:11 +02:00
|
|
|
|
}
|
2001-04-06 05:00:10 +00:00
|
|
|
|
|
2013-11-21 16:45:03 +01:00
|
|
|
|
/* Scheme interface */
|
2000-08-22 15:54:19 +00:00
|
|
|
|
|
2018-09-14 12:57:16 +02:00
|
|
|
|
#define VM_ADD_HOOK(h, f) \
|
|
|
|
|
|
{ \
|
|
|
|
|
|
scm_thread *t = SCM_I_CURRENT_THREAD; \
|
|
|
|
|
|
SCM hook = t->vm.h##_hook; \
|
|
|
|
|
|
if (scm_is_false (hook)) \
|
|
|
|
|
|
hook = t->vm.h##_hook = scm_make_hook (SCM_I_MAKINUM (1)); \
|
|
|
|
|
|
scm_add_hook_x (hook, f, SCM_UNDEFINED); \
|
|
|
|
|
|
vm_hook_compute_enabled (t, hook, &t->vm.h##_hook_enabled); \
|
|
|
|
|
|
vm_recompute_disable_mcode (t); \
|
|
|
|
|
|
return SCM_UNSPECIFIED; \
|
|
|
|
|
|
}
|
2001-04-01 05:03:41 +00:00
|
|
|
|
|
2018-09-14 12:57:16 +02:00
|
|
|
|
#define VM_REMOVE_HOOK(h, f) \
|
|
|
|
|
|
{ \
|
|
|
|
|
|
scm_thread *t = SCM_I_CURRENT_THREAD; \
|
|
|
|
|
|
SCM hook = t->vm.h##_hook; \
|
|
|
|
|
|
if (scm_is_true (hook)) \
|
|
|
|
|
|
scm_remove_hook_x (hook, f); \
|
|
|
|
|
|
vm_hook_compute_enabled (t, hook, &t->vm.h##_hook_enabled); \
|
|
|
|
|
|
vm_recompute_disable_mcode (t); \
|
|
|
|
|
|
return SCM_UNSPECIFIED; \
|
|
|
|
|
|
}
|
2018-09-14 08:42:41 +02:00
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_vm_add_apply_hook_x, "vm-add-apply-hook!", 1, 0, 0,
|
|
|
|
|
|
(SCM f),
|
2001-04-01 05:03:41 +00:00
|
|
|
|
"")
|
2018-09-14 08:42:41 +02:00
|
|
|
|
#define FUNC_NAME s_scm_vm_add_apply_hook_x
|
2000-08-22 15:54:19 +00:00
|
|
|
|
{
|
2018-09-14 12:57:16 +02:00
|
|
|
|
VM_ADD_HOOK (apply, f);
|
2000-08-22 15:54:19 +00:00
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
2018-09-14 08:42:41 +02:00
|
|
|
|
SCM_DEFINE (scm_vm_remove_apply_hook_x, "vm-remove-apply-hook!", 1, 0, 0,
|
|
|
|
|
|
(SCM f),
|
2001-04-01 05:03:41 +00:00
|
|
|
|
"")
|
2018-09-14 08:42:41 +02:00
|
|
|
|
#define FUNC_NAME s_scm_vm_remove_apply_hook_x
|
2000-08-22 15:54:19 +00:00
|
|
|
|
{
|
2018-09-14 12:57:16 +02:00
|
|
|
|
VM_REMOVE_HOOK (apply, f);
|
2000-08-22 15:54:19 +00:00
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
2018-09-14 08:42:41 +02:00
|
|
|
|
SCM_DEFINE (scm_vm_add_return_hook_x, "vm-add-return-hook!", 1, 0, 0,
|
|
|
|
|
|
(SCM f),
|
2001-04-01 05:03:41 +00:00
|
|
|
|
"")
|
2018-09-14 08:42:41 +02:00
|
|
|
|
#define FUNC_NAME s_scm_vm_add_return_hook_x
|
2000-08-22 15:54:19 +00:00
|
|
|
|
{
|
2018-09-14 12:57:16 +02:00
|
|
|
|
VM_ADD_HOOK (return, f);
|
2000-08-22 15:54:19 +00:00
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
2010-09-16 12:48:41 +02:00
|
|
|
|
|
2018-09-14 08:42:41 +02:00
|
|
|
|
SCM_DEFINE (scm_vm_remove_return_hook_x, "vm-remove-return-hook!", 1, 0, 0,
|
|
|
|
|
|
(SCM f),
|
|
|
|
|
|
"")
|
|
|
|
|
|
#define FUNC_NAME s_scm_vm_remove_return_hook_x
|
|
|
|
|
|
{
|
2018-09-14 12:57:16 +02:00
|
|
|
|
VM_REMOVE_HOOK (return, f);
|
2018-09-14 08:42:41 +02:00
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_vm_add_next_hook_x, "vm-add-next-hook!", 1, 0, 0,
|
|
|
|
|
|
(SCM f),
|
2010-09-16 12:48:41 +02:00
|
|
|
|
"")
|
2018-09-14 08:42:41 +02:00
|
|
|
|
#define FUNC_NAME s_scm_vm_add_next_hook_x
|
2010-09-16 12:48:41 +02:00
|
|
|
|
{
|
2018-09-14 12:57:16 +02:00
|
|
|
|
VM_ADD_HOOK (next, f);
|
2018-09-14 08:42:41 +02:00
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_vm_remove_next_hook_x, "vm-remove-next-hook!", 1, 0, 0,
|
|
|
|
|
|
(SCM f),
|
|
|
|
|
|
"")
|
|
|
|
|
|
#define FUNC_NAME s_scm_vm_remove_next_hook_x
|
|
|
|
|
|
{
|
2018-09-14 12:57:16 +02:00
|
|
|
|
VM_REMOVE_HOOK (next, f);
|
2018-09-14 08:42:41 +02:00
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_vm_add_abort_hook_x, "vm-add-abort-hook!", 1, 0, 0,
|
|
|
|
|
|
(SCM f),
|
|
|
|
|
|
"")
|
|
|
|
|
|
#define FUNC_NAME s_scm_vm_add_abort_hook_x
|
|
|
|
|
|
{
|
2018-09-14 12:57:16 +02:00
|
|
|
|
VM_ADD_HOOK (abort, f);
|
2018-09-14 08:42:41 +02:00
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_vm_remove_abort_hook_x, "vm-remove-abort-hook!", 1, 0, 0,
|
|
|
|
|
|
(SCM f),
|
|
|
|
|
|
"")
|
|
|
|
|
|
#define FUNC_NAME s_scm_vm_remove_abort_hook_x
|
|
|
|
|
|
{
|
2018-09-14 12:57:16 +02:00
|
|
|
|
VM_REMOVE_HOOK (abort, f);
|
2010-09-16 12:48:41 +02:00
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
VM accessors take VM as implicit argument, not explicit argument
* libguile/vm.h:
* libguile/vm.c:
(scm_vm_apply_hook, scm_vm_push_continuation_hook,
scm_vm_pop_continuation_hook, scm_vm_abort_continuation_hook,
scm_vm_restore_continuation_hook, scm_vm_next_hook,
scm_vm_trace_level, scm_set_vm_trace_level_x, scm_vm_engine,
scm_set_vm_engine_x, scm_c_set_vm_engine_x): The VM argument is now
implicit: the VM for the current thread.
* doc/ref/api-debug.texi (VM Hooks): Try to adapt.
* module/ice-9/command-line.scm:
* module/statprof.scm:
* module/system/vm/coverage.scm:
* module/system/vm/trace.scm:
* module/system/vm/trap-state.scm:
* module/system/vm/traps.scm:
* test-suite/tests/control.test:
* test-suite/tests/eval.test: Adapt users that set hooks or ensure that
we have a debug engine.
2013-11-21 16:10:41 +01:00
|
|
|
|
SCM_DEFINE (scm_vm_trace_level, "vm-trace-level", 0, 0, 0,
|
|
|
|
|
|
(void),
|
2001-04-01 05:03:41 +00:00
|
|
|
|
"")
|
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
|
|
|
|
#define FUNC_NAME s_scm_vm_trace_level
|
2000-08-22 15:54:19 +00:00
|
|
|
|
{
|
2018-06-24 09:32:11 +02:00
|
|
|
|
return scm_from_int (SCM_I_CURRENT_THREAD->vm.trace_level);
|
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
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
VM accessors take VM as implicit argument, not explicit argument
* libguile/vm.h:
* libguile/vm.c:
(scm_vm_apply_hook, scm_vm_push_continuation_hook,
scm_vm_pop_continuation_hook, scm_vm_abort_continuation_hook,
scm_vm_restore_continuation_hook, scm_vm_next_hook,
scm_vm_trace_level, scm_set_vm_trace_level_x, scm_vm_engine,
scm_set_vm_engine_x, scm_c_set_vm_engine_x): The VM argument is now
implicit: the VM for the current thread.
* doc/ref/api-debug.texi (VM Hooks): Try to adapt.
* module/ice-9/command-line.scm:
* module/statprof.scm:
* module/system/vm/coverage.scm:
* module/system/vm/trace.scm:
* module/system/vm/trap-state.scm:
* module/system/vm/traps.scm:
* test-suite/tests/control.test:
* test-suite/tests/eval.test: Adapt users that set hooks or ensure that
we have a debug engine.
2013-11-21 16:10:41 +01:00
|
|
|
|
SCM_DEFINE (scm_set_vm_trace_level_x, "set-vm-trace-level!", 1, 0, 0,
|
|
|
|
|
|
(SCM level),
|
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
|
|
|
|
"")
|
|
|
|
|
|
#define FUNC_NAME s_scm_set_vm_trace_level_x
|
|
|
|
|
|
{
|
2018-09-14 08:42:41 +02:00
|
|
|
|
scm_thread *thread = SCM_I_CURRENT_THREAD;
|
2018-09-14 12:57:16 +02:00
|
|
|
|
return scm_from_int (set_vm_trace_level (thread, scm_to_int (level)));
|
2000-08-22 15:54:19 +00:00
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
2010-09-27 21:06:24 +02:00
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
* VM engines
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
|
symbol_to_vm_engine (SCM engine, const char *FUNC_NAME)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (scm_is_eq (engine, sym_regular))
|
|
|
|
|
|
return SCM_VM_REGULAR_ENGINE;
|
|
|
|
|
|
else if (scm_is_eq (engine, sym_debug))
|
|
|
|
|
|
return SCM_VM_DEBUG_ENGINE;
|
|
|
|
|
|
else
|
|
|
|
|
|
SCM_MISC_ERROR ("Unknown VM engine: ~a", scm_list_1 (engine));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static SCM
|
|
|
|
|
|
vm_engine_to_symbol (int engine, const char *FUNC_NAME)
|
|
|
|
|
|
{
|
|
|
|
|
|
switch (engine)
|
|
|
|
|
|
{
|
|
|
|
|
|
case SCM_VM_REGULAR_ENGINE:
|
|
|
|
|
|
return sym_regular;
|
|
|
|
|
|
case SCM_VM_DEBUG_ENGINE:
|
|
|
|
|
|
return sym_debug;
|
|
|
|
|
|
default:
|
|
|
|
|
|
/* ? */
|
|
|
|
|
|
SCM_MISC_ERROR ("Unknown VM engine: ~a",
|
|
|
|
|
|
scm_list_1 (scm_from_int (engine)));
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
VM accessors take VM as implicit argument, not explicit argument
* libguile/vm.h:
* libguile/vm.c:
(scm_vm_apply_hook, scm_vm_push_continuation_hook,
scm_vm_pop_continuation_hook, scm_vm_abort_continuation_hook,
scm_vm_restore_continuation_hook, scm_vm_next_hook,
scm_vm_trace_level, scm_set_vm_trace_level_x, scm_vm_engine,
scm_set_vm_engine_x, scm_c_set_vm_engine_x): The VM argument is now
implicit: the VM for the current thread.
* doc/ref/api-debug.texi (VM Hooks): Try to adapt.
* module/ice-9/command-line.scm:
* module/statprof.scm:
* module/system/vm/coverage.scm:
* module/system/vm/trace.scm:
* module/system/vm/trap-state.scm:
* module/system/vm/traps.scm:
* test-suite/tests/control.test:
* test-suite/tests/eval.test: Adapt users that set hooks or ensure that
we have a debug engine.
2013-11-21 16:10:41 +01:00
|
|
|
|
SCM_DEFINE (scm_vm_engine, "vm-engine", 0, 0, 0,
|
|
|
|
|
|
(void),
|
2010-09-27 21:06:24 +02:00
|
|
|
|
"")
|
|
|
|
|
|
#define FUNC_NAME s_scm_vm_engine
|
|
|
|
|
|
{
|
2018-06-24 09:32:11 +02:00
|
|
|
|
return vm_engine_to_symbol (SCM_I_CURRENT_THREAD->vm.engine, FUNC_NAME);
|
2010-09-27 21:06:24 +02:00
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
void
|
VM accessors take VM as implicit argument, not explicit argument
* libguile/vm.h:
* libguile/vm.c:
(scm_vm_apply_hook, scm_vm_push_continuation_hook,
scm_vm_pop_continuation_hook, scm_vm_abort_continuation_hook,
scm_vm_restore_continuation_hook, scm_vm_next_hook,
scm_vm_trace_level, scm_set_vm_trace_level_x, scm_vm_engine,
scm_set_vm_engine_x, scm_c_set_vm_engine_x): The VM argument is now
implicit: the VM for the current thread.
* doc/ref/api-debug.texi (VM Hooks): Try to adapt.
* module/ice-9/command-line.scm:
* module/statprof.scm:
* module/system/vm/coverage.scm:
* module/system/vm/trace.scm:
* module/system/vm/trap-state.scm:
* module/system/vm/traps.scm:
* test-suite/tests/control.test:
* test-suite/tests/eval.test: Adapt users that set hooks or ensure that
we have a debug engine.
2013-11-21 16:10:41 +01:00
|
|
|
|
scm_c_set_vm_engine_x (int engine)
|
2010-09-27 21:06:24 +02:00
|
|
|
|
#define FUNC_NAME "set-vm-engine!"
|
|
|
|
|
|
{
|
2018-09-14 12:57:16 +02:00
|
|
|
|
scm_thread *thread = SCM_I_CURRENT_THREAD;
|
|
|
|
|
|
|
2010-09-27 21:06:24 +02:00
|
|
|
|
if (engine < 0 || engine >= SCM_VM_NUM_ENGINES)
|
|
|
|
|
|
SCM_MISC_ERROR ("Unknown VM engine: ~a",
|
|
|
|
|
|
scm_list_1 (scm_from_int (engine)));
|
|
|
|
|
|
|
2018-09-14 12:57:16 +02:00
|
|
|
|
thread->vm.engine = engine;
|
|
|
|
|
|
/* Trigger update of the various hook_enabled flags. */
|
|
|
|
|
|
set_vm_trace_level (thread, thread->vm.trace_level);
|
2010-09-27 21:06:24 +02:00
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
VM accessors take VM as implicit argument, not explicit argument
* libguile/vm.h:
* libguile/vm.c:
(scm_vm_apply_hook, scm_vm_push_continuation_hook,
scm_vm_pop_continuation_hook, scm_vm_abort_continuation_hook,
scm_vm_restore_continuation_hook, scm_vm_next_hook,
scm_vm_trace_level, scm_set_vm_trace_level_x, scm_vm_engine,
scm_set_vm_engine_x, scm_c_set_vm_engine_x): The VM argument is now
implicit: the VM for the current thread.
* doc/ref/api-debug.texi (VM Hooks): Try to adapt.
* module/ice-9/command-line.scm:
* module/statprof.scm:
* module/system/vm/coverage.scm:
* module/system/vm/trace.scm:
* module/system/vm/trap-state.scm:
* module/system/vm/traps.scm:
* test-suite/tests/control.test:
* test-suite/tests/eval.test: Adapt users that set hooks or ensure that
we have a debug engine.
2013-11-21 16:10:41 +01:00
|
|
|
|
SCM_DEFINE (scm_set_vm_engine_x, "set-vm-engine!", 1, 0, 0,
|
|
|
|
|
|
(SCM engine),
|
2010-09-27 21:06:24 +02:00
|
|
|
|
"")
|
|
|
|
|
|
#define FUNC_NAME s_scm_set_vm_engine_x
|
|
|
|
|
|
{
|
VM accessors take VM as implicit argument, not explicit argument
* libguile/vm.h:
* libguile/vm.c:
(scm_vm_apply_hook, scm_vm_push_continuation_hook,
scm_vm_pop_continuation_hook, scm_vm_abort_continuation_hook,
scm_vm_restore_continuation_hook, scm_vm_next_hook,
scm_vm_trace_level, scm_set_vm_trace_level_x, scm_vm_engine,
scm_set_vm_engine_x, scm_c_set_vm_engine_x): The VM argument is now
implicit: the VM for the current thread.
* doc/ref/api-debug.texi (VM Hooks): Try to adapt.
* module/ice-9/command-line.scm:
* module/statprof.scm:
* module/system/vm/coverage.scm:
* module/system/vm/trace.scm:
* module/system/vm/trap-state.scm:
* module/system/vm/traps.scm:
* test-suite/tests/control.test:
* test-suite/tests/eval.test: Adapt users that set hooks or ensure that
we have a debug engine.
2013-11-21 16:10:41 +01:00
|
|
|
|
scm_c_set_vm_engine_x (symbol_to_vm_engine (engine, FUNC_NAME));
|
2010-09-27 21:06:24 +02:00
|
|
|
|
return SCM_UNSPECIFIED;
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
|
scm_c_set_default_vm_engine_x (int engine)
|
|
|
|
|
|
#define FUNC_NAME "set-default-vm-engine!"
|
|
|
|
|
|
{
|
|
|
|
|
|
if (engine < 0 || engine >= SCM_VM_NUM_ENGINES)
|
|
|
|
|
|
SCM_MISC_ERROR ("Unknown VM engine: ~a",
|
|
|
|
|
|
scm_list_1 (scm_from_int (engine)));
|
|
|
|
|
|
|
|
|
|
|
|
vm_default_engine = engine;
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_set_default_vm_engine_x, "set-default-vm-engine!", 1, 0, 0,
|
|
|
|
|
|
(SCM engine),
|
|
|
|
|
|
"")
|
|
|
|
|
|
#define FUNC_NAME s_scm_set_default_vm_engine_x
|
|
|
|
|
|
{
|
|
|
|
|
|
scm_c_set_default_vm_engine_x (symbol_to_vm_engine (engine, FUNC_NAME));
|
|
|
|
|
|
return SCM_UNSPECIFIED;
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
VM accessors take VM as implicit argument, not explicit argument
* libguile/vm.h:
* libguile/vm.c:
(scm_vm_apply_hook, scm_vm_push_continuation_hook,
scm_vm_pop_continuation_hook, scm_vm_abort_continuation_hook,
scm_vm_restore_continuation_hook, scm_vm_next_hook,
scm_vm_trace_level, scm_set_vm_trace_level_x, scm_vm_engine,
scm_set_vm_engine_x, scm_c_set_vm_engine_x): The VM argument is now
implicit: the VM for the current thread.
* doc/ref/api-debug.texi (VM Hooks): Try to adapt.
* module/ice-9/command-line.scm:
* module/statprof.scm:
* module/system/vm/coverage.scm:
* module/system/vm/trace.scm:
* module/system/vm/trap-state.scm:
* module/system/vm/traps.scm:
* test-suite/tests/control.test:
* test-suite/tests/eval.test: Adapt users that set hooks or ensure that
we have a debug engine.
2013-11-21 16:10:41 +01:00
|
|
|
|
/* FIXME: This function makes no sense, but we keep it to make sure we
|
|
|
|
|
|
have a way of switching to the debug or regular VM. */
|
|
|
|
|
|
SCM_DEFINE (scm_call_with_vm, "call-with-vm", 1, 0, 1,
|
|
|
|
|
|
(SCM proc, SCM args),
|
2010-09-27 21:06:24 +02:00
|
|
|
|
"Apply @var{proc} to @var{args} in a dynamic extent in which\n"
|
VM accessors take VM as implicit argument, not explicit argument
* libguile/vm.h:
* libguile/vm.c:
(scm_vm_apply_hook, scm_vm_push_continuation_hook,
scm_vm_pop_continuation_hook, scm_vm_abort_continuation_hook,
scm_vm_restore_continuation_hook, scm_vm_next_hook,
scm_vm_trace_level, scm_set_vm_trace_level_x, scm_vm_engine,
scm_set_vm_engine_x, scm_c_set_vm_engine_x): The VM argument is now
implicit: the VM for the current thread.
* doc/ref/api-debug.texi (VM Hooks): Try to adapt.
* module/ice-9/command-line.scm:
* module/statprof.scm:
* module/system/vm/coverage.scm:
* module/system/vm/trace.scm:
* module/system/vm/trap-state.scm:
* module/system/vm/traps.scm:
* test-suite/tests/control.test:
* test-suite/tests/eval.test: Adapt users that set hooks or ensure that
we have a debug engine.
2013-11-21 16:10:41 +01:00
|
|
|
|
"@var{vm} is the current VM.")
|
2010-09-27 21:06:24 +02:00
|
|
|
|
#define FUNC_NAME s_scm_call_with_vm
|
|
|
|
|
|
{
|
VM accessors take VM as implicit argument, not explicit argument
* libguile/vm.h:
* libguile/vm.c:
(scm_vm_apply_hook, scm_vm_push_continuation_hook,
scm_vm_pop_continuation_hook, scm_vm_abort_continuation_hook,
scm_vm_restore_continuation_hook, scm_vm_next_hook,
scm_vm_trace_level, scm_set_vm_trace_level_x, scm_vm_engine,
scm_set_vm_engine_x, scm_c_set_vm_engine_x): The VM argument is now
implicit: the VM for the current thread.
* doc/ref/api-debug.texi (VM Hooks): Try to adapt.
* module/ice-9/command-line.scm:
* module/statprof.scm:
* module/system/vm/coverage.scm:
* module/system/vm/trace.scm:
* module/system/vm/trap-state.scm:
* module/system/vm/traps.scm:
* test-suite/tests/control.test:
* test-suite/tests/eval.test: Adapt users that set hooks or ensure that
we have a debug engine.
2013-11-21 16:10:41 +01:00
|
|
|
|
return scm_apply_0 (proc, args);
|
2010-09-27 21:06:24 +02:00
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
2014-03-12 17:18:13 +01:00
|
|
|
|
SCM_DEFINE (scm_call_with_stack_overflow_handler,
|
|
|
|
|
|
"call-with-stack-overflow-handler", 3, 0, 0,
|
|
|
|
|
|
(SCM limit, SCM thunk, SCM handler),
|
|
|
|
|
|
"Call @var{thunk} in an environment in which the stack limit has\n"
|
|
|
|
|
|
"been reduced to @var{limit} additional words. If the limit is\n"
|
|
|
|
|
|
"reached, @var{handler} (a thunk) will be invoked in the dynamic\n"
|
|
|
|
|
|
"environment of the error. For the extent of the call to\n"
|
|
|
|
|
|
"@var{handler}, the stack limit and handler are restored to the\n"
|
|
|
|
|
|
"values that were in place when\n"
|
|
|
|
|
|
"@code{call-with-stack-overflow-handler} was called.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_call_with_stack_overflow_handler
|
|
|
|
|
|
{
|
2018-06-26 11:40:22 +02:00
|
|
|
|
struct scm_thread *t = SCM_I_CURRENT_THREAD;
|
2018-06-21 08:43:47 +02:00
|
|
|
|
ptrdiff_t c_limit, stack_size;
|
2014-03-12 17:18:13 +01:00
|
|
|
|
struct overflow_handler_data data;
|
|
|
|
|
|
SCM new_limit, ret;
|
|
|
|
|
|
|
2018-06-24 09:32:11 +02:00
|
|
|
|
stack_size = t->vm.stack_top - t->vm.sp;
|
2014-03-12 17:18:13 +01:00
|
|
|
|
|
|
|
|
|
|
c_limit = scm_to_ptrdiff_t (limit);
|
|
|
|
|
|
if (c_limit <= 0)
|
|
|
|
|
|
scm_out_of_range (FUNC_NAME, limit);
|
|
|
|
|
|
|
|
|
|
|
|
new_limit = scm_sum (scm_from_ptrdiff_t (stack_size), limit);
|
2018-06-24 09:32:11 +02:00
|
|
|
|
if (scm_is_pair (t->vm.overflow_handler_stack))
|
|
|
|
|
|
new_limit = scm_min (new_limit, scm_caar (t->vm.overflow_handler_stack));
|
2014-03-12 17:18:13 +01:00
|
|
|
|
|
|
|
|
|
|
/* Hacky check that the current stack depth plus the limit is within
|
|
|
|
|
|
the range of a ptrdiff_t. */
|
|
|
|
|
|
scm_to_ptrdiff_t (new_limit);
|
|
|
|
|
|
|
2018-06-24 09:32:11 +02:00
|
|
|
|
data.vp = &t->vm;
|
2014-03-12 17:18:13 +01:00
|
|
|
|
data.overflow_handler_stack =
|
2018-06-24 09:32:11 +02:00
|
|
|
|
scm_acons (limit, handler, t->vm.overflow_handler_stack);
|
2014-03-12 17:18:13 +01:00
|
|
|
|
|
|
|
|
|
|
scm_dynwind_begin (SCM_F_DYNWIND_REWINDABLE);
|
|
|
|
|
|
|
|
|
|
|
|
scm_dynwind_rewind_handler (wind_overflow_handler, &data,
|
|
|
|
|
|
SCM_F_WIND_EXPLICITLY);
|
|
|
|
|
|
scm_dynwind_unwind_handler (unwind_overflow_handler, &data,
|
|
|
|
|
|
SCM_F_WIND_EXPLICITLY);
|
|
|
|
|
|
|
|
|
|
|
|
ret = scm_call_0 (thunk);
|
|
|
|
|
|
|
|
|
|
|
|
scm_dynwind_end ();
|
|
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
2000-08-22 15:54:19 +00:00
|
|
|
|
|
|
|
|
|
|
/*
|
2001-04-01 05:03:41 +00:00
|
|
|
|
* Initialize
|
2000-08-22 15:54:19 +00:00
|
|
|
|
*/
|
|
|
|
|
|
|
2013-11-21 18:23:08 +01:00
|
|
|
|
SCM
|
|
|
|
|
|
scm_load_compiled_with_vm (SCM file)
|
big reorg of scheme modules -- e.g. programs.c -> (system vm program)
This reorganization kills the ugly module-export-all hacks in
bootstrap.scm and core.scm. In fact, it gets rid of core.scm entirely,
breaking out its functionality into separate files.
* module/system/vm/trace.scm:
* module/system/vm/profile.scm:
* module/system/vm/disasm.scm:
* module/system/vm/debug.scm:
* module/system/vm/conv.scm:
* module/system/vm/assemble.scm:
* module/system/repl/repl.scm:
* module/system/repl/common.scm:
* module/system/base/compile.scm:
* module/system/repl/command.scm: Update for changes, and fix a bug in
procedure-documentation.
* module/system/vm/bootstrap.scm: Just call scm_bootstrap_vm, which
handles setting load-compiled for us.
* module/system/vm/core.scm: Removed, functionality folded into other
modules.
* module/system/vm/frame.scm: Export the C frame procedures here; also
move scheme functions from core.scm here.
* module/system/vm/instruction.scm: New file, exports procedures from
instructions.c.
* module/system/vm/objcode.scm: New file, exports procedures from
objcodes.c.
* module/system/vm/program.scm: New file, exports procedures from
programs.c, and some scheme functions originally from core.scm.
* module/system/vm/vm.scm: New file, from vm.c and core.scm.
* src/Makefile.am (libguile_vm_la_SOURCES): Add bootstrap.h.
* src/bootstrap.h: New file, prototypes scm_bootstrap_vm (), which the
scm_init_* functions call.
* src/frames.h:
* src/frames.c (scm_init_frames):
* src/frames.c (scm_bootstrap_frames):
* src/vm.h:
* src/instructions.h:
* src/instructions.c (scm_init_instructions):
* src/instructions.c (scm_bootstrap_instructions):
* src/objcodes.h:
* src/objcodes.c (scm_bootstrap_objcodes):
* src/objcodes.c (scm_init_objcodes):
* src/programs.h:
* src/programs.c (scm_bootstrap_programs):
* src/programs.c (scm_init_programs):
* src/vm.c (scm_bootstrap_vm):
* src/vm.c (scm_init_vm): Call scm_bootstrap_vm() before doing anything
in an init function. Bootstrap_vm will call bootstrap_instructions(),
etc to initialize types, then set load-compiled to point to
load-compiled/vm.
* src/vm.c (scm_load_compiled_with_vm): Code to load .go files, if
they're present.
2008-08-07 13:11:27 +02:00
|
|
|
|
{
|
2013-11-21 18:23:08 +01:00
|
|
|
|
return scm_call_0 (scm_load_thunk_from_file (file));
|
big reorg of scheme modules -- e.g. programs.c -> (system vm program)
This reorganization kills the ugly module-export-all hacks in
bootstrap.scm and core.scm. In fact, it gets rid of core.scm entirely,
breaking out its functionality into separate files.
* module/system/vm/trace.scm:
* module/system/vm/profile.scm:
* module/system/vm/disasm.scm:
* module/system/vm/debug.scm:
* module/system/vm/conv.scm:
* module/system/vm/assemble.scm:
* module/system/repl/repl.scm:
* module/system/repl/common.scm:
* module/system/base/compile.scm:
* module/system/repl/command.scm: Update for changes, and fix a bug in
procedure-documentation.
* module/system/vm/bootstrap.scm: Just call scm_bootstrap_vm, which
handles setting load-compiled for us.
* module/system/vm/core.scm: Removed, functionality folded into other
modules.
* module/system/vm/frame.scm: Export the C frame procedures here; also
move scheme functions from core.scm here.
* module/system/vm/instruction.scm: New file, exports procedures from
instructions.c.
* module/system/vm/objcode.scm: New file, exports procedures from
objcodes.c.
* module/system/vm/program.scm: New file, exports procedures from
programs.c, and some scheme functions originally from core.scm.
* module/system/vm/vm.scm: New file, from vm.c and core.scm.
* src/Makefile.am (libguile_vm_la_SOURCES): Add bootstrap.h.
* src/bootstrap.h: New file, prototypes scm_bootstrap_vm (), which the
scm_init_* functions call.
* src/frames.h:
* src/frames.c (scm_init_frames):
* src/frames.c (scm_bootstrap_frames):
* src/vm.h:
* src/instructions.h:
* src/instructions.c (scm_init_instructions):
* src/instructions.c (scm_bootstrap_instructions):
* src/objcodes.h:
* src/objcodes.c (scm_bootstrap_objcodes):
* src/objcodes.c (scm_init_objcodes):
* src/programs.h:
* src/programs.c (scm_bootstrap_programs):
* src/programs.c (scm_init_programs):
* src/vm.c (scm_bootstrap_vm):
* src/vm.c (scm_init_vm): Call scm_bootstrap_vm() before doing anything
in an init function. Bootstrap_vm will call bootstrap_instructions(),
etc to initialize types, then set load-compiled to point to
load-compiled/vm.
* src/vm.c (scm_load_compiled_with_vm): Code to load .go files, if
they're present.
2008-08-07 13:11:27 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2012-05-10 12:43:33 +02:00
|
|
|
|
|
2013-11-08 14:08:42 +01:00
|
|
|
|
void
|
|
|
|
|
|
scm_init_vm_builtin_properties (void)
|
|
|
|
|
|
{
|
|
|
|
|
|
/* FIXME: Seems hacky to do this here, but oh well :/ */
|
|
|
|
|
|
scm_sym_apply = scm_from_utf8_symbol ("apply");
|
|
|
|
|
|
scm_sym_values = scm_from_utf8_symbol ("values");
|
|
|
|
|
|
scm_sym_abort_to_prompt = scm_from_utf8_symbol ("abort-to-prompt");
|
|
|
|
|
|
scm_sym_call_with_values = scm_from_utf8_symbol ("call-with-values");
|
|
|
|
|
|
scm_sym_call_with_current_continuation =
|
|
|
|
|
|
scm_from_utf8_symbol ("call-with-current-continuation");
|
|
|
|
|
|
|
|
|
|
|
|
#define INIT_BUILTIN(builtin, BUILTIN, req, opt, rest) \
|
|
|
|
|
|
scm_set_procedure_property_x (vm_builtin_##builtin, scm_sym_name, \
|
2018-08-17 08:15:04 +02:00
|
|
|
|
scm_sym_##builtin);
|
2013-11-08 14:08:42 +01:00
|
|
|
|
FOR_EACH_VM_BUILTIN (INIT_BUILTIN);
|
|
|
|
|
|
#undef INIT_BUILTIN
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2001-04-01 05:03:41 +00:00
|
|
|
|
void
|
big reorg of scheme modules -- e.g. programs.c -> (system vm program)
This reorganization kills the ugly module-export-all hacks in
bootstrap.scm and core.scm. In fact, it gets rid of core.scm entirely,
breaking out its functionality into separate files.
* module/system/vm/trace.scm:
* module/system/vm/profile.scm:
* module/system/vm/disasm.scm:
* module/system/vm/debug.scm:
* module/system/vm/conv.scm:
* module/system/vm/assemble.scm:
* module/system/repl/repl.scm:
* module/system/repl/common.scm:
* module/system/base/compile.scm:
* module/system/repl/command.scm: Update for changes, and fix a bug in
procedure-documentation.
* module/system/vm/bootstrap.scm: Just call scm_bootstrap_vm, which
handles setting load-compiled for us.
* module/system/vm/core.scm: Removed, functionality folded into other
modules.
* module/system/vm/frame.scm: Export the C frame procedures here; also
move scheme functions from core.scm here.
* module/system/vm/instruction.scm: New file, exports procedures from
instructions.c.
* module/system/vm/objcode.scm: New file, exports procedures from
objcodes.c.
* module/system/vm/program.scm: New file, exports procedures from
programs.c, and some scheme functions originally from core.scm.
* module/system/vm/vm.scm: New file, from vm.c and core.scm.
* src/Makefile.am (libguile_vm_la_SOURCES): Add bootstrap.h.
* src/bootstrap.h: New file, prototypes scm_bootstrap_vm (), which the
scm_init_* functions call.
* src/frames.h:
* src/frames.c (scm_init_frames):
* src/frames.c (scm_bootstrap_frames):
* src/vm.h:
* src/instructions.h:
* src/instructions.c (scm_init_instructions):
* src/instructions.c (scm_bootstrap_instructions):
* src/objcodes.h:
* src/objcodes.c (scm_bootstrap_objcodes):
* src/objcodes.c (scm_init_objcodes):
* src/programs.h:
* src/programs.c (scm_bootstrap_programs):
* src/programs.c (scm_init_programs):
* src/vm.c (scm_bootstrap_vm):
* src/vm.c (scm_init_vm): Call scm_bootstrap_vm() before doing anything
in an init function. Bootstrap_vm will call bootstrap_instructions(),
etc to initialize types, then set load-compiled to point to
load-compiled/vm.
* src/vm.c (scm_load_compiled_with_vm): Code to load .go files, if
they're present.
2008-08-07 13:11:27 +02:00
|
|
|
|
scm_bootstrap_vm (void)
|
2001-04-01 05:03:41 +00:00
|
|
|
|
{
|
2010-03-16 21:18:12 +01:00
|
|
|
|
scm_c_register_extension ("libguile-" SCM_EFFECTIVE_VERSION,
|
|
|
|
|
|
"scm_init_vm",
|
2009-03-27 18:40:15 -07:00
|
|
|
|
(scm_t_extension_init_func)scm_init_vm, NULL);
|
VM has "builtins": primitives addressable by emitted RTL code
* libguile/Makefile.am:
* libguile/vm-builtins.h: New header, declaring stubs needed by the
compiler like values, apply, and abort-to-prompt.
* libguile/vm.c: Adapt the apply and values stubs to conform to a
standard interface. Add an abort-to-prompt stub. Add call/cc and
call-with-values stubs.
(scm_vm_builtin_ref): New helper, for the builtin-ref opcode.
(scm_vm_builtin_name_to_index)
(scm_vm_builtin_index_to_name): New helpers, for the compiler and
disassembler, respectively.
(scm_init_vm_builtins, scm_bootstrap_vm): Allow the compiler helpers
to be loaded later into a module.
* module/language/rtl.scm: Export builtin-index->name and
builtin-name->index.
* libguile/vm-engine.c (RETURN_VALUE_LIST): Update to use new names of
"apply" and "values".
(tail-call/shuffle): New opcode.
(abort): Update to be a tail VM op, and reorder and renumber other
ops.
(builtin-ref): New opcode.
* libguile/continuations.h:
* libguile/continuations.c (scm_i_call_with_current_continuation):
Move this to vm.[ch], implemented as a builtin.
* module/language/tree-il/compile-cps.scm (convert): Convert to
'abort-to-prompt calls, possibly with 'apply, effectively undoing the
tree-il transformation.
* module/language/cps/reify-primitives.scm (builtin-ref): New helper.
(reify-primitives): Convert builtin primitives to builtin-ref.
* module/language/cps/dfg.scm (constant-needs-allocation?):
* module/language/cps/compile-rtl.scm (emit-rtl-sequence): Add support
for compiling builtin-ref.
* module/system/vm/disassembler.scm (code-annotation): Add annotation
for builtin-ref.
2013-10-20 15:49:22 +02:00
|
|
|
|
scm_c_register_extension ("libguile-" SCM_EFFECTIVE_VERSION,
|
|
|
|
|
|
"scm_init_vm_builtins",
|
|
|
|
|
|
(scm_t_extension_init_func)scm_init_vm_builtins,
|
|
|
|
|
|
NULL);
|
2009-03-27 18:40:15 -07:00
|
|
|
|
|
2018-06-24 10:07:52 +02:00
|
|
|
|
scm_vm_intrinsics.expand_stack = thread_expand_stack;
|
2018-06-24 11:49:42 +02:00
|
|
|
|
scm_vm_intrinsics.cons_rest = cons_rest;
|
|
|
|
|
|
scm_vm_intrinsics.compute_kwargs_npositional = compute_kwargs_npositional;
|
|
|
|
|
|
scm_vm_intrinsics.bind_kwargs = bind_kwargs;
|
2018-06-25 10:52:16 +02:00
|
|
|
|
scm_vm_intrinsics.push_interrupt_frame = push_interrupt_frame;
|
2018-06-26 10:57:23 +02:00
|
|
|
|
scm_vm_intrinsics.reinstate_continuation_x = reinstate_continuation_x;
|
2018-06-26 12:01:01 +02:00
|
|
|
|
scm_vm_intrinsics.capture_continuation = capture_continuation;
|
2018-06-26 15:10:58 +02:00
|
|
|
|
scm_vm_intrinsics.compose_continuation = compose_continuation;
|
2018-08-13 14:24:44 +02:00
|
|
|
|
scm_vm_intrinsics.expand_apply_argument = expand_apply_argument;
|
2018-06-26 16:19:16 +02:00
|
|
|
|
scm_vm_intrinsics.abort_to_prompt = abort_to_prompt;
|
2018-08-08 15:22:28 +02:00
|
|
|
|
scm_vm_intrinsics.get_callee_vcode = get_callee_vcode;
|
2018-08-11 10:48:29 +02:00
|
|
|
|
scm_vm_intrinsics.unpack_values_object = unpack_values_object;
|
2018-08-11 14:22:32 +02:00
|
|
|
|
scm_vm_intrinsics.foreign_call = foreign_call;
|
2014-01-31 21:41:36 +01:00
|
|
|
|
|
2011-01-07 09:08:58 -08:00
|
|
|
|
sym_keyword_argument_error = scm_from_latin1_symbol ("keyword-argument-error");
|
|
|
|
|
|
sym_regular = scm_from_latin1_symbol ("regular");
|
|
|
|
|
|
sym_debug = scm_from_latin1_symbol ("debug");
|
2010-02-24 23:32:04 +01:00
|
|
|
|
|
2013-11-19 20:05:45 +01:00
|
|
|
|
vm_boot_continuation = scm_i_make_program (vm_boot_continuation_code);
|
|
|
|
|
|
SCM_SET_CELL_WORD_0 (vm_boot_continuation,
|
|
|
|
|
|
(SCM_CELL_WORD_0 (vm_boot_continuation)
|
2013-10-17 23:16:32 +02:00
|
|
|
|
| SCM_F_PROGRAM_IS_BOOT));
|
2013-11-08 14:08:42 +01:00
|
|
|
|
|
2018-08-17 08:15:04 +02:00
|
|
|
|
define_vm_builtins ();
|
big reorg of scheme modules -- e.g. programs.c -> (system vm program)
This reorganization kills the ugly module-export-all hacks in
bootstrap.scm and core.scm. In fact, it gets rid of core.scm entirely,
breaking out its functionality into separate files.
* module/system/vm/trace.scm:
* module/system/vm/profile.scm:
* module/system/vm/disasm.scm:
* module/system/vm/debug.scm:
* module/system/vm/conv.scm:
* module/system/vm/assemble.scm:
* module/system/repl/repl.scm:
* module/system/repl/common.scm:
* module/system/base/compile.scm:
* module/system/repl/command.scm: Update for changes, and fix a bug in
procedure-documentation.
* module/system/vm/bootstrap.scm: Just call scm_bootstrap_vm, which
handles setting load-compiled for us.
* module/system/vm/core.scm: Removed, functionality folded into other
modules.
* module/system/vm/frame.scm: Export the C frame procedures here; also
move scheme functions from core.scm here.
* module/system/vm/instruction.scm: New file, exports procedures from
instructions.c.
* module/system/vm/objcode.scm: New file, exports procedures from
objcodes.c.
* module/system/vm/program.scm: New file, exports procedures from
programs.c, and some scheme functions originally from core.scm.
* module/system/vm/vm.scm: New file, from vm.c and core.scm.
* src/Makefile.am (libguile_vm_la_SOURCES): Add bootstrap.h.
* src/bootstrap.h: New file, prototypes scm_bootstrap_vm (), which the
scm_init_* functions call.
* src/frames.h:
* src/frames.c (scm_init_frames):
* src/frames.c (scm_bootstrap_frames):
* src/vm.h:
* src/instructions.h:
* src/instructions.c (scm_init_instructions):
* src/instructions.c (scm_bootstrap_instructions):
* src/objcodes.h:
* src/objcodes.c (scm_bootstrap_objcodes):
* src/objcodes.c (scm_init_objcodes):
* src/programs.h:
* src/programs.c (scm_bootstrap_programs):
* src/programs.c (scm_init_programs):
* src/vm.c (scm_bootstrap_vm):
* src/vm.c (scm_init_vm): Call scm_bootstrap_vm() before doing anything
in an init function. Bootstrap_vm will call bootstrap_instructions(),
etc to initialize types, then set load-compiled to point to
load-compiled/vm.
* src/vm.c (scm_load_compiled_with_vm): Code to load .go files, if
they're present.
2008-08-07 13:11:27 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
|
scm_init_vm (void)
|
|
|
|
|
|
{
|
2001-04-01 05:03:41 +00:00
|
|
|
|
#ifndef SCM_MAGIC_SNARFER
|
2018-06-20 17:19:31 +02:00
|
|
|
|
#include "vm.x"
|
2001-04-01 05:03:41 +00:00
|
|
|
|
#endif
|
2000-08-22 15:54:19 +00:00
|
|
|
|
}
|