2011-01-27 10:49:51 +01:00
|
|
|
|
/* Copyright (C) 2001,2008,2009,2010,2011 Free Software Foundation, Inc.
|
2000-08-22 15:54:19 +00:00
|
|
|
|
*
|
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
|
|
|
|
* This library is free software; you can redistribute it and/or
|
2009-06-17 00:22:09 +01:00
|
|
|
|
* modify it under the terms of the GNU Lesser General Public License
|
|
|
|
|
|
* as published by the Free Software Foundation; either version 3 of
|
|
|
|
|
|
* the License, or (at your option) any later version.
|
2000-08-22 15:54:19 +00:00
|
|
|
|
*
|
2009-06-17 00:22:09 +01:00
|
|
|
|
* This library is distributed in the hope that it will be useful, but
|
|
|
|
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
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
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
|
|
* Lesser General Public License for more details.
|
2000-08-22 15:54:19 +00:00
|
|
|
|
*
|
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
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
|
|
* License along with this library; if not, write to the Free Software
|
2009-06-17 00:22:09 +01:00
|
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
|
|
|
|
* 02110-1301 USA
|
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
|
|
|
|
*/
|
|
|
|
|
|
|
2000-08-22 15:54:19 +00:00
|
|
|
|
|
|
|
|
|
|
/* This file is included in vm_engine.c */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
* Basic operations
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
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_DEFINE_INSTRUCTION (0, nop, "nop", 0, 0, 0)
|
2000-08-22 15:54:19 +00:00
|
|
|
|
{
|
|
|
|
|
|
NEXT;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
static opcodes; refactor program/objcode division; use new assembly pipeline
* gdbinit: Untested attempts to get the stack fondling macros to deal
with the new program representation.
* libguile/frames.c (scm_vm_frame_arguments, scm_vm_frame_source)
(scm_vm_frame_local_ref, scm_vm_frame_local_set_x): SCM_PROGRAM_DATA is
a struct scm_objcode*.
* libguile/instructions.h:
* libguile/instructions.c: Hide the instruction table and the struct
scm_instruction structure; all access to instructions now goes through
procedures. This is because instructions are no longer in a packed
array indexed by opcode. Also, declare a mask that all instructions
should fit in.
* libguile/objcodes.h:
* libguile/objcodes.c: Rewrite so that object code directly maps its
arity and length from its bytecode. This makes it unnecessary to keep
this information in programs, allowing programs to be simple conses
between the code (objcodes) and data (the object table and the closure
variables).
* libguile/programs.c (scm_make_program): Rework so that make-program
takes objcode, an object table, and externals as arguments. It's much
clearer this way, and we avoid malloc().
* libguile/stacks.c (is_vm_bootstrap_frame): Update for program/objcode
changes.
* libguile/vm-engine.c (vm_run): Initialize the jump table on the first
run, with the opcodes declared in the instruction sources, and with bad
instructions raising an error instead of wandering off into the
Unknown.
* libguile/vm-engine.h (FETCH_LENGTH): Always represent lengths as 3
bytes. The old code was too error-prone.
(NEXT_JUMP): Mask the instruction with SCM_VM_INSTRUCTION_MASK.
(NEW_FRAME): Update for program/objcode changes.
* libguile/vm-expand.h (VM_DEFINE_FUNCTION, VM_DEFINE_INSTRUCTION)
(VM_DEFINE_LOADER): Update so that we explicitly specify opcodes, so
that we have a stable bytecode API.
* libguile/vm-i-loader.c: Update license to LGPLv2+. Explicitly declare
opcodes.
(load-integer): Use an int instead of a long as the accumulator; still
need to revisit this code at some point, I think.
(load-program): Simplify, thankfully!! Just creates the objcode slice
and rolls with it.
* libguile/vm-i-scheme.c: Number the opcodes explicitly.
* libguile/vm-i-system.c: Update license to LGPLv2+. Explicitly declare
opcodes.
(make-closure): Update for new program API.
* libguile/vm.c (vm_make_boot_program): Update for new program/objcode
API. Still a bit ugly.
(scm_load_compiled_with_vm): Update for new program/objcode API.
* module/language/assembly.scm (byte-length): Fix byte-length calculation
for loaders, and load-program.
(code-pack, code-unpack): Start to move things from (system vm conv)
here.
(object->code, code->object): More things from conv.scm.
* module/language/glil.scm (<glil-program>): Add a new field,
closure-level.
(make-glil-program, compute-closure-level): Calculate the "closure
level" when making a glil program. This is the maximum depth of
external binding refs in this closure.
(unparse-glil): Fix label serialization.
* module/language/glil/compile-assembly.scm (make-meta): Prepend #f for
the meta's object table, though maybe in the future we can avoid
creating assembly in the first place.
(assoc-ref-or-acons, object-index-and-alist): GRRR! Caught again by the
different sets of arguments to assoc and assoc-ref!
(glil->assembly): Attempt to make the <glil-program> case more
readable, and fix the bugs. Sorry I don't know how to comment this
change any more than this.
(glil->assembly): For <glil-module> serialize the whole key, not just
the name.
(dump-object): subprogram-code is already a list. Serialize integers as
strings, not u8vectors. Fix the order of lists and vectors.
* module/language/glil/spec.scm (glil): Switch orders, so we prefer glil
-> assembly -> objcode. Actually glil->objcode doesn't work any more,
needs to be removed I think.
* module/language/objcode/spec.scm (objcode->value):
s/objcode->program/make-program/.
* module/language/scheme/inline.scm: Add acons inline.
* module/system/vm/conv.scm (make-byte-decoder): Skip the first 8 bytes,
they are header. Handle subprograms properly. Still needs help though.
(decode-length): Lengths are always 3 bytes now.
* module/system/vm/disasm.scm: Superficial changes to keep things
working. I'd like to fix this better in the future.
* module/system/vm/frame.scm (bootstrap-frame?): Fixes for
program-bytecode.
* module/system/vm/program.scm: Export make-program. It's program-objcode
now, no more program-bytecode.
* module/system/vm/vm.scm (vm-load): Use make-program.
* test-suite/tests/asm-to-bytecode.test: New test, very minimal.
* module/system/vm/objcode.scm: Export word-size, byte-order, and
write-objcode.
2009-01-29 21:09:04 +01:00
|
|
|
|
VM_DEFINE_INSTRUCTION (1, halt, "halt", 0, 0, 0)
|
2000-08-22 15:54:19 +00:00
|
|
|
|
{
|
add multiple values support to the vm
* libguile/vm-engine.c (vm_run): The bootstrap program now uses mv_call,
so as to allow multiple values out of the VM. (It did before, because
multiple values were represented internally as single scm_values
objects, but now that values go on the stack, we need to note the boot
frame as accepting multiple values.)
(vm_error_no_values): New error, happens if you pass no values into a
single-value continuation. Passing more than one is OK though, it just
takes the first one.
* libguile/vm-i-system.c (halt): Assume that someone has pushed the
number of values onto the stack, and package up that number of values
as a scm_values() object, for communication with the interpreter.
(mv-call): New instruction, calls a procedure with a multiple-value
continuation, even handling calls out to the interpreter.
(return/values): New instruction, returns multiple values to the
continuation. If the continuation is single-valued, takes the first
value or errors if there are no values. Otherwise it returns to the
multiple-value return address, pushing the number of values on top of
the values.
* module/system/il/compile.scm (codegen): Compile <ghil-values> forms.
* module/system/il/ghil.scm (<ghil-values>) Add new GHIL data structure
and associated procedures.
* module/language/scheme/translate.scm (custom-transformer-table):
Compile (values .. ) forms into <ghil-values>.
2008-09-14 17:06:52 +02:00
|
|
|
|
nvalues = SCM_I_INUM (*sp--);
|
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
|
|
|
|
NULLSTACK (1);
|
add multiple values support to the vm
* libguile/vm-engine.c (vm_run): The bootstrap program now uses mv_call,
so as to allow multiple values out of the VM. (It did before, because
multiple values were represented internally as single scm_values
objects, but now that values go on the stack, we need to note the boot
frame as accepting multiple values.)
(vm_error_no_values): New error, happens if you pass no values into a
single-value continuation. Passing more than one is OK though, it just
takes the first one.
* libguile/vm-i-system.c (halt): Assume that someone has pushed the
number of values onto the stack, and package up that number of values
as a scm_values() object, for communication with the interpreter.
(mv-call): New instruction, calls a procedure with a multiple-value
continuation, even handling calls out to the interpreter.
(return/values): New instruction, returns multiple values to the
continuation. If the continuation is single-valued, takes the first
value or errors if there are no values. Otherwise it returns to the
multiple-value return address, pushing the number of values on top of
the values.
* module/system/il/compile.scm (codegen): Compile <ghil-values> forms.
* module/system/il/ghil.scm (<ghil-values>) Add new GHIL data structure
and associated procedures.
* module/language/scheme/translate.scm (custom-transformer-table):
Compile (values .. ) forms into <ghil-values>.
2008-09-14 17:06:52 +02:00
|
|
|
|
if (nvalues == 1)
|
2009-02-05 12:28:19 +01:00
|
|
|
|
POP (finish_args);
|
add multiple values support to the vm
* libguile/vm-engine.c (vm_run): The bootstrap program now uses mv_call,
so as to allow multiple values out of the VM. (It did before, because
multiple values were represented internally as single scm_values
objects, but now that values go on the stack, we need to note the boot
frame as accepting multiple values.)
(vm_error_no_values): New error, happens if you pass no values into a
single-value continuation. Passing more than one is OK though, it just
takes the first one.
* libguile/vm-i-system.c (halt): Assume that someone has pushed the
number of values onto the stack, and package up that number of values
as a scm_values() object, for communication with the interpreter.
(mv-call): New instruction, calls a procedure with a multiple-value
continuation, even handling calls out to the interpreter.
(return/values): New instruction, returns multiple values to the
continuation. If the continuation is single-valued, takes the first
value or errors if there are no values. Otherwise it returns to the
multiple-value return address, pushing the number of values on top of
the values.
* module/system/il/compile.scm (codegen): Compile <ghil-values> forms.
* module/system/il/ghil.scm (<ghil-values>) Add new GHIL data structure
and associated procedures.
* module/language/scheme/translate.scm (custom-transformer-table):
Compile (values .. ) forms into <ghil-values>.
2008-09-14 17:06:52 +02:00
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
POP_LIST (nvalues);
|
2009-02-05 12:28:19 +01:00
|
|
|
|
POP (finish_args);
|
2008-09-28 23:08:14 +02:00
|
|
|
|
SYNC_REGISTER ();
|
2009-02-05 12:28:19 +01:00
|
|
|
|
finish_args = scm_values (finish_args);
|
add multiple values support to the vm
* libguile/vm-engine.c (vm_run): The bootstrap program now uses mv_call,
so as to allow multiple values out of the VM. (It did before, because
multiple values were represented internally as single scm_values
objects, but now that values go on the stack, we need to note the boot
frame as accepting multiple values.)
(vm_error_no_values): New error, happens if you pass no values into a
single-value continuation. Passing more than one is OK though, it just
takes the first one.
* libguile/vm-i-system.c (halt): Assume that someone has pushed the
number of values onto the stack, and package up that number of values
as a scm_values() object, for communication with the interpreter.
(mv-call): New instruction, calls a procedure with a multiple-value
continuation, even handling calls out to the interpreter.
(return/values): New instruction, returns multiple values to the
continuation. If the continuation is single-valued, takes the first
value or errors if there are no values. Otherwise it returns to the
multiple-value return address, pushing the number of values on top of
the values.
* module/system/il/compile.scm (codegen): Compile <ghil-values> forms.
* module/system/il/ghil.scm (<ghil-values>) Add new GHIL data structure
and associated procedures.
* module/language/scheme/translate.scm (custom-transformer-table):
Compile (values .. ) forms into <ghil-values>.
2008-09-14 17:06:52 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2008-09-13 14:40:27 +02:00
|
|
|
|
{
|
runtime and debugging support for callee-parsed procedure args
* libguile/objcodes.h: Bump for metadata format change.
* libguile/frames.h: Rework so we don't frob the program's nargs, nlocs,
etc at runtime. Instead we don't really know what's a local var, an
argument, or an intermediate value. It's a little unfortunate, but
this will allow for case-lambda, and eventually for good polymorphic
generic dispatch; and the nlocs etc can be heuristically
reconstructed. Such a reconstruction would be better done at the
Scheme level, though.
(SCM_FRAME_STACK_ADDRESS): New macro, the pointer to the base of the
stack elements (not counting the program).
(SCM_FRAME_UPPER_ADDRESS): Repurpose to be the address of the last
element in the bookkeeping part of the stack -- i.e. to point to the
return address.
* libguile/vm-engine.h:
* libguile/vm-i-system.c: Adapt to removal of stack_base. Though we
still detect stack-smashing underflow, we don't do so as precisely as
we did before, because now we only detect overwriting of the frame
metadata.
* libguile/vm-engine.c (vm_engine): Remove the stack_base variable. It
is unnecessary, and difficult to keep track of in the face of
case-lambda. Also fix miscommented "ra" and "mvra" pushes. Push the
vp->ip as the first ra...
* libguile/vm-i-system.c (halt): ...because here we can restore the
vp->ip instead of setting ip to 0. Allows us to introspect ips all
down the stack, including in recursive VM invocations.
* libguile/frames.h:
* libguile/frames.c (scm_vm_frame_stack): Removed, because it's getting
more difficult to tell what's an argument and what's a temporary stack
element.
(scm_vm_frame_num_locals): New accessor.
(scm_vm_frame_instruction_pointer): New accessor.
(scm_vm_frame_arguments): Defer to an implementation in Scheme.
(scm_vm_frame_num_locals scm_vm_frame_local_ref)
(scm_vm_frame_local_set_x): Since we can get not-yet-active frames on
the stack now, with our current calling convention, we have to add a
heuristic here to jump over those frames -- because frames have
pointers in them, not Scheme values.
* libguile/programs.h:
* libguile/programs.c (scm_program_arity): Remove, in favor of..
(scm_program_arities): ...this, which a list of arities, in a new
format, occupying a slot in the metadata.
* module/language/assembly/decompile-bytecode.scm (decode-load-program):
Fix mv-call decompilation.
* module/system/vm/frame.scm (vm-frame-bindings, vm-frame-binding-ref)
(vm-frame-binding-set!): New functions, to access bindings by name in
a frame.
(vm-frame-arguments): Function now implemented in Scheme. Commented
fairly extensively.
* module/system/vm/program.scm (program-bindings-by-index)
(program-bindings-for-ip): New accessors, parsing the program bindings
metadata into something more useful.
(program-arities, program-arguments): In a case-lambda world, we have
to assume that programs can have multiple arities. But it's tough to
detect this algorithmically; instead we're going to require that the
program metadata include information about the arities, and the parts
of the program that that metadata applies to.
(program-lambda-list): New accessor.
(write-program): Show multiple arities.
* module/language/glil/compile-assembly.scm (glil->assembly): Add
"arities" to the state of the compiler, and add arities entries as
appropriate.
2009-09-27 19:25:58 -04:00
|
|
|
|
#ifdef VM_ENABLE_STACK_NULLING
|
|
|
|
|
|
SCM *old_sp = sp;
|
|
|
|
|
|
#endif
|
2008-09-13 14:40:27 +02:00
|
|
|
|
|
|
|
|
|
|
/* Restore registers */
|
|
|
|
|
|
sp = SCM_FRAME_LOWER_ADDRESS (fp) - 1;
|
runtime and debugging support for callee-parsed procedure args
* libguile/objcodes.h: Bump for metadata format change.
* libguile/frames.h: Rework so we don't frob the program's nargs, nlocs,
etc at runtime. Instead we don't really know what's a local var, an
argument, or an intermediate value. It's a little unfortunate, but
this will allow for case-lambda, and eventually for good polymorphic
generic dispatch; and the nlocs etc can be heuristically
reconstructed. Such a reconstruction would be better done at the
Scheme level, though.
(SCM_FRAME_STACK_ADDRESS): New macro, the pointer to the base of the
stack elements (not counting the program).
(SCM_FRAME_UPPER_ADDRESS): Repurpose to be the address of the last
element in the bookkeeping part of the stack -- i.e. to point to the
return address.
* libguile/vm-engine.h:
* libguile/vm-i-system.c: Adapt to removal of stack_base. Though we
still detect stack-smashing underflow, we don't do so as precisely as
we did before, because now we only detect overwriting of the frame
metadata.
* libguile/vm-engine.c (vm_engine): Remove the stack_base variable. It
is unnecessary, and difficult to keep track of in the face of
case-lambda. Also fix miscommented "ra" and "mvra" pushes. Push the
vp->ip as the first ra...
* libguile/vm-i-system.c (halt): ...because here we can restore the
vp->ip instead of setting ip to 0. Allows us to introspect ips all
down the stack, including in recursive VM invocations.
* libguile/frames.h:
* libguile/frames.c (scm_vm_frame_stack): Removed, because it's getting
more difficult to tell what's an argument and what's a temporary stack
element.
(scm_vm_frame_num_locals): New accessor.
(scm_vm_frame_instruction_pointer): New accessor.
(scm_vm_frame_arguments): Defer to an implementation in Scheme.
(scm_vm_frame_num_locals scm_vm_frame_local_ref)
(scm_vm_frame_local_set_x): Since we can get not-yet-active frames on
the stack now, with our current calling convention, we have to add a
heuristic here to jump over those frames -- because frames have
pointers in them, not Scheme values.
* libguile/programs.h:
* libguile/programs.c (scm_program_arity): Remove, in favor of..
(scm_program_arities): ...this, which a list of arities, in a new
format, occupying a slot in the metadata.
* module/language/assembly/decompile-bytecode.scm (decode-load-program):
Fix mv-call decompilation.
* module/system/vm/frame.scm (vm-frame-bindings, vm-frame-binding-ref)
(vm-frame-binding-set!): New functions, to access bindings by name in
a frame.
(vm-frame-arguments): Function now implemented in Scheme. Commented
fairly extensively.
* module/system/vm/program.scm (program-bindings-by-index)
(program-bindings-for-ip): New accessors, parsing the program bindings
metadata into something more useful.
(program-arities, program-arguments): In a case-lambda world, we have
to assume that programs can have multiple arities. But it's tough to
detect this algorithmically; instead we're going to require that the
program metadata include information about the arities, and the parts
of the program that that metadata applies to.
(program-lambda-list): New accessor.
(write-program): Show multiple arities.
* module/language/glil/compile-assembly.scm (glil->assembly): Add
"arities" to the state of the compiler, and add arities entries as
appropriate.
2009-09-27 19:25:58 -04:00
|
|
|
|
/* Setting the ip here doesn't actually affect control flow, as the calling
|
|
|
|
|
|
code will restore its own registers, but it does help when walking the
|
|
|
|
|
|
stack */
|
|
|
|
|
|
ip = SCM_FRAME_RETURN_ADDRESS (fp);
|
2008-09-13 14:40:27 +02:00
|
|
|
|
fp = SCM_FRAME_DYNAMIC_LINK (fp);
|
runtime and debugging support for callee-parsed procedure args
* libguile/objcodes.h: Bump for metadata format change.
* libguile/frames.h: Rework so we don't frob the program's nargs, nlocs,
etc at runtime. Instead we don't really know what's a local var, an
argument, or an intermediate value. It's a little unfortunate, but
this will allow for case-lambda, and eventually for good polymorphic
generic dispatch; and the nlocs etc can be heuristically
reconstructed. Such a reconstruction would be better done at the
Scheme level, though.
(SCM_FRAME_STACK_ADDRESS): New macro, the pointer to the base of the
stack elements (not counting the program).
(SCM_FRAME_UPPER_ADDRESS): Repurpose to be the address of the last
element in the bookkeeping part of the stack -- i.e. to point to the
return address.
* libguile/vm-engine.h:
* libguile/vm-i-system.c: Adapt to removal of stack_base. Though we
still detect stack-smashing underflow, we don't do so as precisely as
we did before, because now we only detect overwriting of the frame
metadata.
* libguile/vm-engine.c (vm_engine): Remove the stack_base variable. It
is unnecessary, and difficult to keep track of in the face of
case-lambda. Also fix miscommented "ra" and "mvra" pushes. Push the
vp->ip as the first ra...
* libguile/vm-i-system.c (halt): ...because here we can restore the
vp->ip instead of setting ip to 0. Allows us to introspect ips all
down the stack, including in recursive VM invocations.
* libguile/frames.h:
* libguile/frames.c (scm_vm_frame_stack): Removed, because it's getting
more difficult to tell what's an argument and what's a temporary stack
element.
(scm_vm_frame_num_locals): New accessor.
(scm_vm_frame_instruction_pointer): New accessor.
(scm_vm_frame_arguments): Defer to an implementation in Scheme.
(scm_vm_frame_num_locals scm_vm_frame_local_ref)
(scm_vm_frame_local_set_x): Since we can get not-yet-active frames on
the stack now, with our current calling convention, we have to add a
heuristic here to jump over those frames -- because frames have
pointers in them, not Scheme values.
* libguile/programs.h:
* libguile/programs.c (scm_program_arity): Remove, in favor of..
(scm_program_arities): ...this, which a list of arities, in a new
format, occupying a slot in the metadata.
* module/language/assembly/decompile-bytecode.scm (decode-load-program):
Fix mv-call decompilation.
* module/system/vm/frame.scm (vm-frame-bindings, vm-frame-binding-ref)
(vm-frame-binding-set!): New functions, to access bindings by name in
a frame.
(vm-frame-arguments): Function now implemented in Scheme. Commented
fairly extensively.
* module/system/vm/program.scm (program-bindings-by-index)
(program-bindings-for-ip): New accessors, parsing the program bindings
metadata into something more useful.
(program-arities, program-arguments): In a case-lambda world, we have
to assume that programs can have multiple arities. But it's tough to
detect this algorithmically; instead we're going to require that the
program metadata include information about the arities, and the parts
of the program that that metadata applies to.
(program-lambda-list): New accessor.
(write-program): Show multiple arities.
* module/language/glil/compile-assembly.scm (glil->assembly): Add
"arities" to the state of the compiler, and add arities entries as
appropriate.
2009-09-27 19:25:58 -04:00
|
|
|
|
NULLSTACK (old_sp - sp);
|
2008-09-13 14:40:27 +02:00
|
|
|
|
}
|
2009-02-05 12:28:19 +01:00
|
|
|
|
|
|
|
|
|
|
goto vm_done;
|
2000-08-22 15:54:19 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (2, drop, "drop", 0, 1, 0)
|
2000-08-22 15:54:19 +00:00
|
|
|
|
{
|
2001-04-01 05:03:41 +00:00
|
|
|
|
DROP ();
|
2000-08-22 15:54:19 +00:00
|
|
|
|
NEXT;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (3, dup, "dup", 0, 0, 1)
|
2000-09-10 22:36:28 +00:00
|
|
|
|
{
|
2001-04-09 04:08:46 +00:00
|
|
|
|
SCM x = *sp;
|
|
|
|
|
|
PUSH (x);
|
2000-09-10 22:36:28 +00:00
|
|
|
|
NEXT;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2001-04-01 05:03:41 +00:00
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
* Object creation
|
|
|
|
|
|
*/
|
2000-08-22 15:54:19 +00:00
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (4, void, "void", 0, 0, 1)
|
2000-08-22 15:54:19 +00:00
|
|
|
|
{
|
2001-04-01 05:03:41 +00:00
|
|
|
|
PUSH (SCM_UNSPECIFIED);
|
2000-08-22 15:54:19 +00:00
|
|
|
|
NEXT;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (5, make_true, "make-true", 0, 0, 1)
|
2000-08-22 15:54:19 +00:00
|
|
|
|
{
|
2001-04-01 05:03:41 +00:00
|
|
|
|
PUSH (SCM_BOOL_T);
|
2000-08-22 15:54:19 +00:00
|
|
|
|
NEXT;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (6, make_false, "make-false", 0, 0, 1)
|
2000-08-22 15:54:19 +00:00
|
|
|
|
{
|
2001-04-01 05:03:41 +00:00
|
|
|
|
PUSH (SCM_BOOL_F);
|
2000-08-22 15:54:19 +00:00
|
|
|
|
NEXT;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (7, make_nil, "make-nil", 0, 0, 1)
|
2009-06-29 13:16:27 +02:00
|
|
|
|
{
|
|
|
|
|
|
PUSH (SCM_ELISP_NIL);
|
|
|
|
|
|
NEXT;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (8, make_eol, "make-eol", 0, 0, 1)
|
2000-08-22 15:54:19 +00:00
|
|
|
|
{
|
2001-04-01 05:03:41 +00:00
|
|
|
|
PUSH (SCM_EOL);
|
2000-08-22 15:54:19 +00:00
|
|
|
|
NEXT;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (9, make_int8, "make-int8", 1, 0, 1)
|
2000-08-22 15:54:19 +00:00
|
|
|
|
{
|
2005-04-29 14:12:12 +00:00
|
|
|
|
PUSH (SCM_I_MAKINUM ((signed char) FETCH ()));
|
2000-08-22 15:54:19 +00:00
|
|
|
|
NEXT;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (10, make_int8_0, "make-int8:0", 0, 0, 1)
|
2000-08-22 15:54:19 +00:00
|
|
|
|
{
|
2005-04-28 15:45:59 +00:00
|
|
|
|
PUSH (SCM_INUM0);
|
2000-08-22 15:54:19 +00:00
|
|
|
|
NEXT;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (11, make_int8_1, "make-int8:1", 0, 0, 1)
|
2000-08-22 15:54:19 +00:00
|
|
|
|
{
|
2005-04-28 15:45:59 +00:00
|
|
|
|
PUSH (SCM_I_MAKINUM (1));
|
2000-08-22 15:54:19 +00:00
|
|
|
|
NEXT;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (12, make_int16, "make-int16", 2, 0, 1)
|
2000-08-22 15:54:19 +00:00
|
|
|
|
{
|
2001-04-05 01:38:38 +00:00
|
|
|
|
int h = FETCH ();
|
|
|
|
|
|
int l = FETCH ();
|
2005-04-29 14:12:12 +00:00
|
|
|
|
PUSH (SCM_I_MAKINUM ((signed short) (h << 8) + l));
|
2000-08-22 15:54:19 +00:00
|
|
|
|
NEXT;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (13, make_int64, "make-int64", 8, 0, 1)
|
2009-06-06 15:45:00 +02:00
|
|
|
|
{
|
|
|
|
|
|
scm_t_uint64 v = 0;
|
|
|
|
|
|
v += FETCH ();
|
|
|
|
|
|
v <<= 8; v += FETCH ();
|
|
|
|
|
|
v <<= 8; v += FETCH ();
|
|
|
|
|
|
v <<= 8; v += FETCH ();
|
|
|
|
|
|
v <<= 8; v += FETCH ();
|
|
|
|
|
|
v <<= 8; v += FETCH ();
|
|
|
|
|
|
v <<= 8; v += FETCH ();
|
|
|
|
|
|
v <<= 8; v += FETCH ();
|
|
|
|
|
|
PUSH (scm_from_int64 ((scm_t_int64) v));
|
|
|
|
|
|
NEXT;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (14, make_uint64, "make-uint64", 8, 0, 1)
|
2009-06-06 15:45:00 +02:00
|
|
|
|
{
|
|
|
|
|
|
scm_t_uint64 v = 0;
|
|
|
|
|
|
v += FETCH ();
|
|
|
|
|
|
v <<= 8; v += FETCH ();
|
|
|
|
|
|
v <<= 8; v += FETCH ();
|
|
|
|
|
|
v <<= 8; v += FETCH ();
|
|
|
|
|
|
v <<= 8; v += FETCH ();
|
|
|
|
|
|
v <<= 8; v += FETCH ();
|
|
|
|
|
|
v <<= 8; v += FETCH ();
|
|
|
|
|
|
v <<= 8; v += FETCH ();
|
|
|
|
|
|
PUSH (scm_from_uint64 (v));
|
|
|
|
|
|
NEXT;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (15, make_char8, "make-char8", 1, 0, 1)
|
2000-08-22 15:54:19 +00:00
|
|
|
|
{
|
2009-08-01 10:15:20 -07:00
|
|
|
|
scm_t_uint8 v = 0;
|
|
|
|
|
|
v = FETCH ();
|
|
|
|
|
|
|
|
|
|
|
|
PUSH (SCM_MAKE_CHAR (v));
|
|
|
|
|
|
/* Don't simplify this to PUSH (SCM_MAKE_CHAR (FETCH ())). The
|
|
|
|
|
|
contents of SCM_MAKE_CHAR may be evaluated more than once,
|
|
|
|
|
|
resulting in a double fetch. */
|
2000-08-22 15:54:19 +00:00
|
|
|
|
NEXT;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (16, make_char32, "make-char32", 4, 0, 1)
|
2009-07-29 06:38:32 -07:00
|
|
|
|
{
|
|
|
|
|
|
scm_t_wchar v = 0;
|
|
|
|
|
|
v += FETCH ();
|
|
|
|
|
|
v <<= 8; v += FETCH ();
|
|
|
|
|
|
v <<= 8; v += FETCH ();
|
|
|
|
|
|
v <<= 8; v += FETCH ();
|
|
|
|
|
|
PUSH (SCM_MAKE_CHAR (v));
|
|
|
|
|
|
NEXT;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (17, list, "list", 2, -1, 1)
|
2001-04-15 15:02:41 +00:00
|
|
|
|
{
|
2006-01-02 18:04:04 +00:00
|
|
|
|
unsigned h = FETCH ();
|
|
|
|
|
|
unsigned l = FETCH ();
|
|
|
|
|
|
unsigned len = ((h << 8) + l);
|
|
|
|
|
|
POP_LIST (len);
|
2001-04-15 15:02:41 +00:00
|
|
|
|
NEXT;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (18, vector, "vector", 2, -1, 1)
|
2001-04-15 15:02:41 +00:00
|
|
|
|
{
|
2006-01-02 18:04:04 +00:00
|
|
|
|
unsigned h = FETCH ();
|
|
|
|
|
|
unsigned l = FETCH ();
|
|
|
|
|
|
unsigned len = ((h << 8) + l);
|
2009-02-01 11:25:51 +01:00
|
|
|
|
SCM vect;
|
|
|
|
|
|
|
2008-09-28 23:08:14 +02:00
|
|
|
|
SYNC_REGISTER ();
|
2009-02-01 11:25:51 +01:00
|
|
|
|
sp++; sp -= len;
|
|
|
|
|
|
CHECK_UNDERFLOW ();
|
|
|
|
|
|
vect = scm_make_vector (scm_from_uint (len), SCM_BOOL_F);
|
|
|
|
|
|
memcpy (SCM_I_VECTOR_WELTS(vect), sp, sizeof(SCM) * len);
|
|
|
|
|
|
NULLSTACK (len);
|
|
|
|
|
|
*sp = vect;
|
|
|
|
|
|
|
2001-04-15 15:02:41 +00:00
|
|
|
|
NEXT;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2000-08-22 15:54:19 +00:00
|
|
|
|
|
|
|
|
|
|
/*
|
2001-04-01 05:03:41 +00:00
|
|
|
|
* Variable access
|
2000-08-22 15:54:19 +00:00
|
|
|
|
*/
|
|
|
|
|
|
|
2001-04-01 05:03:41 +00:00
|
|
|
|
#define OBJECT_REF(i) objects[i]
|
|
|
|
|
|
#define OBJECT_SET(i,o) objects[i] = o
|
2000-08-22 15:54:19 +00:00
|
|
|
|
|
2001-04-23 04:28:13 +00:00
|
|
|
|
#define LOCAL_REF(i) SCM_FRAME_VARIABLE (fp, i)
|
|
|
|
|
|
#define LOCAL_SET(i,o) SCM_FRAME_VARIABLE (fp, i) = o
|
2000-08-22 15:54:19 +00:00
|
|
|
|
|
2005-04-29 14:12:12 +00:00
|
|
|
|
/* For the variable operations, we _must_ obviously avoid function calls to
|
|
|
|
|
|
`scm_variable_ref ()', `scm_variable_bound_p ()' and friends which do
|
|
|
|
|
|
nothing more than the corresponding macros. */
|
|
|
|
|
|
#define VARIABLE_REF(v) SCM_VARIABLE_REF (v)
|
|
|
|
|
|
#define VARIABLE_SET(v,o) SCM_VARIABLE_SET (v, o)
|
scm_is_eq for SCM vals, not == or !=
* libguile/bytevectors.c (scm_make_bytevector, STRING_TO_UTF)
(UTF_TO_STRING):
* libguile/continuations.c (scm_i_check_continuation):
* libguile/expand.h (SCM_EXPANDED_P):
* libguile/fluids.c (scm_i_make_with_fluids):
* libguile/generalized-vectors.c (scm_make_generalized_vector):
* libguile/goops.c (SCM_GOOPS_UNBOUNDP, slot_definition_using_name):
(scm_c_extend_primitive_generic, more_specificp, scm_make)
* libguile/i18n.c (SCM_VALIDATE_OPTIONAL_LOCALE_COPY):
(scm_locale_string_to_integer)
* libguile/modules.c (resolve_duplicate_binding):
(scm_module_reverse_lookup)
* libguile/posix.c (scm_to_resource):
* libguile/r6rs-ports.c (scm_put_bytevector):
* libguile/socket.c (scm_connect, scm_bind, scm_sendto
* libguile/stacks.c (find_prompt):
* libguile/variable.c (scm_variable_ref, scm_variable_bound_p):
* libguile/vm-engine.h (ASSERT_BOUND_VARIABLE, ASSERT_BOUND)
* libguile/vm-i-system.c (VARIABLE_BOUNDP, local_bound)
(long_local_bound, fluid_ref): Use scm_is_eq to compare, not == / !=.
2011-05-13 12:42:01 +02:00
|
|
|
|
#define VARIABLE_BOUNDP(v) (!scm_is_eq (VARIABLE_REF (v), SCM_UNDEFINED))
|
2000-08-22 15:54:19 +00:00
|
|
|
|
|
allocate free variables inline to closures
* libguile/_scm.h (SCM_OBJCODE_MINOR_VERSION): Bump.
* libguile/programs.h (SCM_PROGRAM_FREE_VARIABLES)
(SCM_PROGRAM_FREE_VARIABLE_REF, SCM_PROGRAM_FREE_VARIABLE_SET)
(SCM_PROGRAM_NUM_FREE_VARIABLES):
* libguile/programs.c (scm_make_program, scm_program_num_free_variables)
(scm_program_free_variable_ref, scm_program_free_variable_set_x):
Allocate free variables inline with programs, instead of being in a
vect. Should improve locality, and require fewer local variables in
the VM.
* libguile/vm-engine.c (vm_engine): Remove free_vars and free_vars_count
variables.
* libguile/vm-engine.h (CACHE_PROGRAM): No need to muck with free_vars
and free_vars_count.
(CHECK_FREE_VARIABLE): Update for inline free vars.
* libguile/vm-i-system.c (FREE_VARIABLE_REF): Update for inline free
vars.
(make-closure, fix-closure): Take the closure vals as separate stack
args, and copy or fix them inline into the appropriate closure.
* module/language/objcode/spec.scm (program-free-variables): Define a
local version of this removed function.
* module/language/tree-il/compile-glil.scm (flatten): Adjust to not make
a vector when making closures.
* module/system/vm/program.scm: Export program-num-free-variables,
program-free-variable-ref, program-free-variable-set!, and remove
program-free-variables.
* test-suite/tests/tree-il.test ("lambda"): Update to not make vectors
when making closures.
2010-01-09 16:42:27 +01:00
|
|
|
|
#define FREE_VARIABLE_REF(i) SCM_PROGRAM_FREE_VARIABLE_REF (program, i)
|
2009-07-19 19:48:26 +02:00
|
|
|
|
|
2001-04-01 05:03:41 +00:00
|
|
|
|
/* ref */
|
2000-08-22 15:54:19 +00:00
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (19, object_ref, "object-ref", 1, 0, 1)
|
2000-08-22 15:54:19 +00:00
|
|
|
|
{
|
2005-06-25 06:57:20 +00:00
|
|
|
|
register unsigned objnum = FETCH ();
|
2005-06-25 03:13:56 +00:00
|
|
|
|
CHECK_OBJECT (objnum);
|
|
|
|
|
|
PUSH (OBJECT_REF (objnum));
|
2001-04-01 05:03:41 +00:00
|
|
|
|
NEXT;
|
2000-08-22 15:54:19 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2009-07-19 19:02:30 +02:00
|
|
|
|
/* FIXME: necessary? elt 255 of the vector could be a vector... */
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (20, long_object_ref, "long-object-ref", 2, 0, 1)
|
2009-07-19 19:02:30 +02:00
|
|
|
|
{
|
|
|
|
|
|
unsigned int objnum = FETCH ();
|
|
|
|
|
|
objnum <<= 8;
|
|
|
|
|
|
objnum += FETCH ();
|
|
|
|
|
|
CHECK_OBJECT (objnum);
|
|
|
|
|
|
PUSH (OBJECT_REF (objnum));
|
|
|
|
|
|
NEXT;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (21, local_ref, "local-ref", 1, 0, 1)
|
2000-08-22 15:54:19 +00:00
|
|
|
|
{
|
2001-04-01 05:03:41 +00:00
|
|
|
|
PUSH (LOCAL_REF (FETCH ()));
|
and, or, cond etc use syntax-rules, compile scheme through tree-il
* libguile/vm-i-system.c:
* libguile/vm-engine.h (ASSERT_BOUND): New assertion, that a value is
bound. Used by local-ref and external-ref in paranoid mode.
* module/ice-9/boot-9.scm (and, or, cond, case, do): Since we are
switching to use psyntax as the first pass of the compiler, and perhaps
soon of the interpreter too, we need to make sure it expands out all
forms to primitive expressions. So define expanders for these derived
syntax forms, as in the R5RS report.
* module/ice-9/psyntax-pp.scm: Regenerate, with core forms fully
expanded.
* module/ice-9/psyntax.scm (build-void): New constructor, for making
undefined values.
(build-primref): Add in a hack so that primitive refs in the boot
module expand out to toplevel refs, not module refs.
(chi-void): Use build-void.
(if): Define an expander for if that calls build-conditional.
* module/language/scheme/compile-tree-il.scm (compile-tree-il): Use let*
so as not to depend on binding order for the result of
(current-module).
* module/language/scheme/spec.scm (scheme): Switch over to tree-il as the
primary intermediate language. Not yet fully tested, but at least it
can compile psyntax-pp.scm.
* module/language/tree-il/analyze.scm (analyze-lexicals): Arguments don't
count towards a function's nlocs.
* module/language/tree-il/compile-glil.scm (*comp-module*, compile-glil):
Define a "compilation module" fluid.
(flatten-lambda): Fix a call to make-glil-argument. Fix bug in
heapifying arguments.
(flatten): Fix number of arguments passed to apply instruction. Add a
special case for `(values ...)'. If inlining primitive-refs fails,
try expanding into toplevel-refs if the comp-module's variable is the
same as the root variable.
* module/language/tree-il/optimize.scm (resolve-primitives!): Add missing
src variable for <module-ref>.
* test-suite/tests/tree-il.test ("lambda"): Fix nlocs counts. Add a
closure test case.
2009-05-20 11:15:22 +02:00
|
|
|
|
ASSERT_BOUND (*sp);
|
2001-04-01 05:03:41 +00:00
|
|
|
|
NEXT;
|
2000-08-22 15:54:19 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (22, long_local_ref, "long-local-ref", 2, 0, 1)
|
2000-08-22 15:54:19 +00:00
|
|
|
|
{
|
2009-07-24 11:00:32 +02:00
|
|
|
|
unsigned int i = FETCH ();
|
|
|
|
|
|
i <<= 8;
|
|
|
|
|
|
i += FETCH ();
|
2009-07-26 12:56:11 +02:00
|
|
|
|
PUSH (LOCAL_REF (i));
|
and, or, cond etc use syntax-rules, compile scheme through tree-il
* libguile/vm-i-system.c:
* libguile/vm-engine.h (ASSERT_BOUND): New assertion, that a value is
bound. Used by local-ref and external-ref in paranoid mode.
* module/ice-9/boot-9.scm (and, or, cond, case, do): Since we are
switching to use psyntax as the first pass of the compiler, and perhaps
soon of the interpreter too, we need to make sure it expands out all
forms to primitive expressions. So define expanders for these derived
syntax forms, as in the R5RS report.
* module/ice-9/psyntax-pp.scm: Regenerate, with core forms fully
expanded.
* module/ice-9/psyntax.scm (build-void): New constructor, for making
undefined values.
(build-primref): Add in a hack so that primitive refs in the boot
module expand out to toplevel refs, not module refs.
(chi-void): Use build-void.
(if): Define an expander for if that calls build-conditional.
* module/language/scheme/compile-tree-il.scm (compile-tree-il): Use let*
so as not to depend on binding order for the result of
(current-module).
* module/language/scheme/spec.scm (scheme): Switch over to tree-il as the
primary intermediate language. Not yet fully tested, but at least it
can compile psyntax-pp.scm.
* module/language/tree-il/analyze.scm (analyze-lexicals): Arguments don't
count towards a function's nlocs.
* module/language/tree-il/compile-glil.scm (*comp-module*, compile-glil):
Define a "compilation module" fluid.
(flatten-lambda): Fix a call to make-glil-argument. Fix bug in
heapifying arguments.
(flatten): Fix number of arguments passed to apply instruction. Add a
special case for `(values ...)'. If inlining primitive-refs fails,
try expanding into toplevel-refs if the comp-module's variable is the
same as the root variable.
* module/language/tree-il/optimize.scm (resolve-primitives!): Add missing
src variable for <module-ref>.
* test-suite/tests/tree-il.test ("lambda"): Fix nlocs counts. Add a
closure test case.
2009-05-20 11:15:22 +02:00
|
|
|
|
ASSERT_BOUND (*sp);
|
2000-08-22 15:54:19 +00:00
|
|
|
|
NEXT;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (23, local_bound, "local-bound?", 1, 0, 1)
|
2009-10-23 15:44:22 +02:00
|
|
|
|
{
|
scm_is_eq for SCM vals, not == or !=
* libguile/bytevectors.c (scm_make_bytevector, STRING_TO_UTF)
(UTF_TO_STRING):
* libguile/continuations.c (scm_i_check_continuation):
* libguile/expand.h (SCM_EXPANDED_P):
* libguile/fluids.c (scm_i_make_with_fluids):
* libguile/generalized-vectors.c (scm_make_generalized_vector):
* libguile/goops.c (SCM_GOOPS_UNBOUNDP, slot_definition_using_name):
(scm_c_extend_primitive_generic, more_specificp, scm_make)
* libguile/i18n.c (SCM_VALIDATE_OPTIONAL_LOCALE_COPY):
(scm_locale_string_to_integer)
* libguile/modules.c (resolve_duplicate_binding):
(scm_module_reverse_lookup)
* libguile/posix.c (scm_to_resource):
* libguile/r6rs-ports.c (scm_put_bytevector):
* libguile/socket.c (scm_connect, scm_bind, scm_sendto
* libguile/stacks.c (find_prompt):
* libguile/variable.c (scm_variable_ref, scm_variable_bound_p):
* libguile/vm-engine.h (ASSERT_BOUND_VARIABLE, ASSERT_BOUND)
* libguile/vm-i-system.c (VARIABLE_BOUNDP, local_bound)
(long_local_bound, fluid_ref): Use scm_is_eq to compare, not == / !=.
2011-05-13 12:42:01 +02:00
|
|
|
|
PUSH (scm_from_bool (!scm_is_eq (LOCAL_REF (FETCH ()), SCM_UNDEFINED)));
|
2009-10-23 15:44:22 +02:00
|
|
|
|
NEXT;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (24, long_local_bound, "long-local-bound?", 2, 0, 1)
|
2009-10-23 15:44:22 +02:00
|
|
|
|
{
|
|
|
|
|
|
unsigned int i = FETCH ();
|
|
|
|
|
|
i <<= 8;
|
|
|
|
|
|
i += FETCH ();
|
scm_is_eq for SCM vals, not == or !=
* libguile/bytevectors.c (scm_make_bytevector, STRING_TO_UTF)
(UTF_TO_STRING):
* libguile/continuations.c (scm_i_check_continuation):
* libguile/expand.h (SCM_EXPANDED_P):
* libguile/fluids.c (scm_i_make_with_fluids):
* libguile/generalized-vectors.c (scm_make_generalized_vector):
* libguile/goops.c (SCM_GOOPS_UNBOUNDP, slot_definition_using_name):
(scm_c_extend_primitive_generic, more_specificp, scm_make)
* libguile/i18n.c (SCM_VALIDATE_OPTIONAL_LOCALE_COPY):
(scm_locale_string_to_integer)
* libguile/modules.c (resolve_duplicate_binding):
(scm_module_reverse_lookup)
* libguile/posix.c (scm_to_resource):
* libguile/r6rs-ports.c (scm_put_bytevector):
* libguile/socket.c (scm_connect, scm_bind, scm_sendto
* libguile/stacks.c (find_prompt):
* libguile/variable.c (scm_variable_ref, scm_variable_bound_p):
* libguile/vm-engine.h (ASSERT_BOUND_VARIABLE, ASSERT_BOUND)
* libguile/vm-i-system.c (VARIABLE_BOUNDP, local_bound)
(long_local_bound, fluid_ref): Use scm_is_eq to compare, not == / !=.
2011-05-13 12:42:01 +02:00
|
|
|
|
PUSH (scm_from_bool (!scm_is_eq (LOCAL_REF (i), SCM_UNDEFINED)));
|
2009-10-23 15:44:22 +02:00
|
|
|
|
NEXT;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (25, variable_ref, "variable-ref", 0, 1, 1)
|
2000-08-22 15:54:19 +00:00
|
|
|
|
{
|
2001-04-01 05:03:41 +00:00
|
|
|
|
SCM x = *sp;
|
2005-04-28 15:45:59 +00:00
|
|
|
|
|
2011-01-27 10:49:51 +01:00
|
|
|
|
/* We don't use ASSERT_VARIABLE or ASSERT_BOUND_VARIABLE here because,
|
|
|
|
|
|
unlike in top-variable-ref, it really isn't an internal assertion
|
|
|
|
|
|
that can be optimized out -- the variable could be coming directly
|
|
|
|
|
|
from the user. */
|
|
|
|
|
|
if (SCM_UNLIKELY (!SCM_VARIABLEP (x)))
|
|
|
|
|
|
{
|
|
|
|
|
|
func_name = "variable-ref";
|
|
|
|
|
|
finish_args = x;
|
|
|
|
|
|
goto vm_error_not_a_variable;
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (SCM_UNLIKELY (!VARIABLE_BOUNDP (x)))
|
2001-04-01 05:03:41 +00:00
|
|
|
|
{
|
2010-07-26 16:36:24 +02:00
|
|
|
|
SCM var_name;
|
|
|
|
|
|
|
|
|
|
|
|
/* Attempt to provide the variable name in the error message. */
|
|
|
|
|
|
var_name = scm_module_reverse_lookup (scm_current_module (), x);
|
2010-12-07 12:26:07 +01:00
|
|
|
|
finish_args = scm_is_true (var_name) ? var_name : x;
|
2001-04-01 05:03:41 +00:00
|
|
|
|
goto vm_error_unbound;
|
|
|
|
|
|
}
|
2005-04-28 15:45:59 +00:00
|
|
|
|
else
|
|
|
|
|
|
{
|
2005-04-29 14:12:12 +00:00
|
|
|
|
SCM o = VARIABLE_REF (x);
|
2005-04-28 15:45:59 +00:00
|
|
|
|
*sp = o;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2000-08-22 15:54:19 +00:00
|
|
|
|
NEXT;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (26, variable_bound, "variable-bound?", 0, 1, 1)
|
2009-10-23 15:44:22 +02:00
|
|
|
|
{
|
2011-01-27 10:49:51 +01:00
|
|
|
|
SCM x = *sp;
|
|
|
|
|
|
|
|
|
|
|
|
if (SCM_UNLIKELY (!SCM_VARIABLEP (x)))
|
|
|
|
|
|
{
|
|
|
|
|
|
func_name = "variable-bound?";
|
|
|
|
|
|
finish_args = x;
|
|
|
|
|
|
goto vm_error_not_a_variable;
|
|
|
|
|
|
}
|
2009-10-23 15:44:22 +02:00
|
|
|
|
else
|
2011-01-27 10:49:51 +01:00
|
|
|
|
*sp = scm_from_bool (VARIABLE_BOUNDP (x));
|
2009-10-23 15:44:22 +02:00
|
|
|
|
NEXT;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (27, toplevel_ref, "toplevel-ref", 1, 0, 1)
|
Add instructions for doing very late binding
Fixes the mutually-recursive toplevel definitions case. This could be
fixed by rewriting bodies as letrecs, as r6 does, but that's not really
repl-compatible.
* module/system/il/ghil.scm (ghil-lookup): Ok, if we can't locate a
variable, mark it as unresolved.
* module/system/il/compile.scm (make-glil-var): Compile unresolved
variables as <glil-late-bound> objects.
* module/system/il/glil.scm: Add <glil-late-bound> definition.
* module/system/vm/assemble.scm (codegen): And, finally, when we see a
<vlate-bound> object, allocate a slot for it in the object vector,
setting it to a symbol. Add a new pair of instructions to resolve that
symbol to a variable at the last minute.
* src/vm_loader.c (load-number): Bugfix: the radix argument should be
SCM_UNDEFINED in order to default to 10.
(late-bind): Add an unresolved symbol to the object vector. Could be
replaced with load-symbol I guess.
* src/vm_system.c (late-variable-ref, late-variable-set): New
instructions to do late symbol binding.
* testsuite/Makefile.am (vm_test_files):
* testsuite/t-mutual-toplevel-defines.scm: New test, failing for some
reason involving the core even? and odd? definitions.
2008-05-19 17:46:05 +02:00
|
|
|
|
{
|
2008-05-19 19:37:39 +02:00
|
|
|
|
unsigned objnum = FETCH ();
|
2010-10-14 18:27:41 -07:00
|
|
|
|
SCM what, resolved;
|
Add instructions for doing very late binding
Fixes the mutually-recursive toplevel definitions case. This could be
fixed by rewriting bodies as letrecs, as r6 does, but that's not really
repl-compatible.
* module/system/il/ghil.scm (ghil-lookup): Ok, if we can't locate a
variable, mark it as unresolved.
* module/system/il/compile.scm (make-glil-var): Compile unresolved
variables as <glil-late-bound> objects.
* module/system/il/glil.scm: Add <glil-late-bound> definition.
* module/system/vm/assemble.scm (codegen): And, finally, when we see a
<vlate-bound> object, allocate a slot for it in the object vector,
setting it to a symbol. Add a new pair of instructions to resolve that
symbol to a variable at the last minute.
* src/vm_loader.c (load-number): Bugfix: the radix argument should be
SCM_UNDEFINED in order to default to 10.
(late-bind): Add an unresolved symbol to the object vector. Could be
replaced with load-symbol I guess.
* src/vm_system.c (late-variable-ref, late-variable-set): New
instructions to do late symbol binding.
* testsuite/Makefile.am (vm_test_files):
* testsuite/t-mutual-toplevel-defines.scm: New test, failing for some
reason involving the core even? and odd? definitions.
2008-05-19 17:46:05 +02:00
|
|
|
|
CHECK_OBJECT (objnum);
|
compile @ and @@
* libguile/vm-engine.c (vm_run): Add new error case for resolving @ or @@
references, but there is no such module. Possible if
module-public-interface returns #f.
* libguile/vm-i-loader.c (link-now): Allow the stack arg to be a sym, as
before, or a list, indicating an absolute reference. Could be two
separate instructions, but I'm lazy.
* libguile/vm-i-system.c (late-variable-ref, late-variable-set): As in
link-now, allow the lazy reference to be a list, for @ and @@.
* module/language/scheme/translate.scm (custom-transformer-table):
Compile @ and @@, and set! forms for both of them. This will ease the
non-hygienic pain for exported macros.
* module/system/il/compile.scm (make-glil-var): Translate public and
private module variable references into glil-module variables.
* module/system/il/ghil.scm (ghil-var-at-module!): New function, resolves
a variable for @ or @@.
* module/system/il/glil.scm (<glil-module>): Revival of <glil-module>,
this time with the semantics that it really links to a particular
module.
* module/system/vm/assemble.scm (<vlink-now>, <vlink-later>): Redefine as
taking a "key" as the argument, which may be a sym or a list; see the
notes on link-now for more details.
(codegen): Compile <glil-module> appropriately. Some duplication here,
probably could use some cleanup later.
2008-09-30 00:31:17 +02:00
|
|
|
|
what = OBJECT_REF (objnum);
|
Add instructions for doing very late binding
Fixes the mutually-recursive toplevel definitions case. This could be
fixed by rewriting bodies as letrecs, as r6 does, but that's not really
repl-compatible.
* module/system/il/ghil.scm (ghil-lookup): Ok, if we can't locate a
variable, mark it as unresolved.
* module/system/il/compile.scm (make-glil-var): Compile unresolved
variables as <glil-late-bound> objects.
* module/system/il/glil.scm: Add <glil-late-bound> definition.
* module/system/vm/assemble.scm (codegen): And, finally, when we see a
<vlate-bound> object, allocate a slot for it in the object vector,
setting it to a symbol. Add a new pair of instructions to resolve that
symbol to a variable at the last minute.
* src/vm_loader.c (load-number): Bugfix: the radix argument should be
SCM_UNDEFINED in order to default to 10.
(late-bind): Add an unresolved symbol to the object vector. Could be
replaced with load-symbol I guess.
* src/vm_system.c (late-variable-ref, late-variable-set): New
instructions to do late symbol binding.
* testsuite/Makefile.am (vm_test_files):
* testsuite/t-mutual-toplevel-defines.scm: New test, failing for some
reason involving the core even? and odd? definitions.
2008-05-19 17:46:05 +02:00
|
|
|
|
|
2010-10-14 18:27:41 -07:00
|
|
|
|
if (!SCM_VARIABLEP (what))
|
Add instructions for doing very late binding
Fixes the mutually-recursive toplevel definitions case. This could be
fixed by rewriting bodies as letrecs, as r6 does, but that's not really
repl-compatible.
* module/system/il/ghil.scm (ghil-lookup): Ok, if we can't locate a
variable, mark it as unresolved.
* module/system/il/compile.scm (make-glil-var): Compile unresolved
variables as <glil-late-bound> objects.
* module/system/il/glil.scm: Add <glil-late-bound> definition.
* module/system/vm/assemble.scm (codegen): And, finally, when we see a
<vlate-bound> object, allocate a slot for it in the object vector,
setting it to a symbol. Add a new pair of instructions to resolve that
symbol to a variable at the last minute.
* src/vm_loader.c (load-number): Bugfix: the radix argument should be
SCM_UNDEFINED in order to default to 10.
(late-bind): Add an unresolved symbol to the object vector. Could be
replaced with load-symbol I guess.
* src/vm_system.c (late-variable-ref, late-variable-set): New
instructions to do late symbol binding.
* testsuite/Makefile.am (vm_test_files):
* testsuite/t-mutual-toplevel-defines.scm: New test, failing for some
reason involving the core even? and odd? definitions.
2008-05-19 17:46:05 +02:00
|
|
|
|
{
|
improve source loc info in nonlocal exits and backtraces
* module/system/il/compile.scm (codegen): The currently-executing
instruction is actually the one right before the instruction pointer;
so for purposes of assv to find a source location for an ip, put the
source after the code, as it was before.
* module/system/vm/debug.scm (vm-backtrace): Move more code to frame.scm.
* module/system/vm/frame.scm (make-frame-chain): Include all frames, even
the bootstrap one. For a reentrant backtrace we'll have boostrap
programs anyway. Probably should check for objcode[2] == scm_op_halt,
to not show those frames in the trace.
(frame-line-number, frame-file): New helpers.
(print-frame): Print out the line number too.
(frame-call-representation): Code from print-frame-call moved here.
(print-frame-chain-as-backtrace): A backtrace printer, yays.
(program-name): Check link validity before calling frame-address on it.
* module/system/vm/program.scm (source:addr, source:line, source:column)
(source:file): New accessors for the elements of program-sources.
* module/system/vm/vm.scm (vm:last-ip): New export.
(vm-last-frame-chain): Use vm:last-ip in making the frame chain.
* src/vm.h (struct scm_vm):
* src/vm.c (make_vm, scm_vm_last_ip, scm_vm_save_stack): Save the last
instruction pointer when saving the stack. Really though, we should be
saving all of the stack data on a spaghetti stack.
* src/vm_system.c (late-variable-ref): Pointless s/REGISTER/BEFORE_GC/.
2008-08-08 12:55:57 +02:00
|
|
|
|
SYNC_REGISTER ();
|
2010-10-14 18:27:41 -07:00
|
|
|
|
resolved = resolve_variable (what, scm_program_module (program));
|
|
|
|
|
|
if (!VARIABLE_BOUNDP (resolved))
|
Add instructions for doing very late binding
Fixes the mutually-recursive toplevel definitions case. This could be
fixed by rewriting bodies as letrecs, as r6 does, but that's not really
repl-compatible.
* module/system/il/ghil.scm (ghil-lookup): Ok, if we can't locate a
variable, mark it as unresolved.
* module/system/il/compile.scm (make-glil-var): Compile unresolved
variables as <glil-late-bound> objects.
* module/system/il/glil.scm: Add <glil-late-bound> definition.
* module/system/vm/assemble.scm (codegen): And, finally, when we see a
<vlate-bound> object, allocate a slot for it in the object vector,
setting it to a symbol. Add a new pair of instructions to resolve that
symbol to a variable at the last minute.
* src/vm_loader.c (load-number): Bugfix: the radix argument should be
SCM_UNDEFINED in order to default to 10.
(late-bind): Add an unresolved symbol to the object vector. Could be
replaced with load-symbol I guess.
* src/vm_system.c (late-variable-ref, late-variable-set): New
instructions to do late symbol binding.
* testsuite/Makefile.am (vm_test_files):
* testsuite/t-mutual-toplevel-defines.scm: New test, failing for some
reason involving the core even? and odd? definitions.
2008-05-19 17:46:05 +02:00
|
|
|
|
{
|
2010-12-07 12:26:07 +01:00
|
|
|
|
finish_args = what;
|
Add instructions for doing very late binding
Fixes the mutually-recursive toplevel definitions case. This could be
fixed by rewriting bodies as letrecs, as r6 does, but that's not really
repl-compatible.
* module/system/il/ghil.scm (ghil-lookup): Ok, if we can't locate a
variable, mark it as unresolved.
* module/system/il/compile.scm (make-glil-var): Compile unresolved
variables as <glil-late-bound> objects.
* module/system/il/glil.scm: Add <glil-late-bound> definition.
* module/system/vm/assemble.scm (codegen): And, finally, when we see a
<vlate-bound> object, allocate a slot for it in the object vector,
setting it to a symbol. Add a new pair of instructions to resolve that
symbol to a variable at the last minute.
* src/vm_loader.c (load-number): Bugfix: the radix argument should be
SCM_UNDEFINED in order to default to 10.
(late-bind): Add an unresolved symbol to the object vector. Could be
replaced with load-symbol I guess.
* src/vm_system.c (late-variable-ref, late-variable-set): New
instructions to do late symbol binding.
* testsuite/Makefile.am (vm_test_files):
* testsuite/t-mutual-toplevel-defines.scm: New test, failing for some
reason involving the core even? and odd? definitions.
2008-05-19 17:46:05 +02:00
|
|
|
|
goto vm_error_unbound;
|
|
|
|
|
|
}
|
2010-10-14 18:27:41 -07:00
|
|
|
|
what = resolved;
|
compile @ and @@
* libguile/vm-engine.c (vm_run): Add new error case for resolving @ or @@
references, but there is no such module. Possible if
module-public-interface returns #f.
* libguile/vm-i-loader.c (link-now): Allow the stack arg to be a sym, as
before, or a list, indicating an absolute reference. Could be two
separate instructions, but I'm lazy.
* libguile/vm-i-system.c (late-variable-ref, late-variable-set): As in
link-now, allow the lazy reference to be a list, for @ and @@.
* module/language/scheme/translate.scm (custom-transformer-table):
Compile @ and @@, and set! forms for both of them. This will ease the
non-hygienic pain for exported macros.
* module/system/il/compile.scm (make-glil-var): Translate public and
private module variable references into glil-module variables.
* module/system/il/ghil.scm (ghil-var-at-module!): New function, resolves
a variable for @ or @@.
* module/system/il/glil.scm (<glil-module>): Revival of <glil-module>,
this time with the semantics that it really links to a particular
module.
* module/system/vm/assemble.scm (<vlink-now>, <vlink-later>): Redefine as
taking a "key" as the argument, which may be a sym or a list; see the
notes on link-now for more details.
(codegen): Compile <glil-module> appropriately. Some duplication here,
probably could use some cleanup later.
2008-09-30 00:31:17 +02:00
|
|
|
|
OBJECT_SET (objnum, what);
|
Add instructions for doing very late binding
Fixes the mutually-recursive toplevel definitions case. This could be
fixed by rewriting bodies as letrecs, as r6 does, but that's not really
repl-compatible.
* module/system/il/ghil.scm (ghil-lookup): Ok, if we can't locate a
variable, mark it as unresolved.
* module/system/il/compile.scm (make-glil-var): Compile unresolved
variables as <glil-late-bound> objects.
* module/system/il/glil.scm: Add <glil-late-bound> definition.
* module/system/vm/assemble.scm (codegen): And, finally, when we see a
<vlate-bound> object, allocate a slot for it in the object vector,
setting it to a symbol. Add a new pair of instructions to resolve that
symbol to a variable at the last minute.
* src/vm_loader.c (load-number): Bugfix: the radix argument should be
SCM_UNDEFINED in order to default to 10.
(late-bind): Add an unresolved symbol to the object vector. Could be
replaced with load-symbol I guess.
* src/vm_system.c (late-variable-ref, late-variable-set): New
instructions to do late symbol binding.
* testsuite/Makefile.am (vm_test_files):
* testsuite/t-mutual-toplevel-defines.scm: New test, failing for some
reason involving the core even? and odd? definitions.
2008-05-19 17:46:05 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
compile @ and @@
* libguile/vm-engine.c (vm_run): Add new error case for resolving @ or @@
references, but there is no such module. Possible if
module-public-interface returns #f.
* libguile/vm-i-loader.c (link-now): Allow the stack arg to be a sym, as
before, or a list, indicating an absolute reference. Could be two
separate instructions, but I'm lazy.
* libguile/vm-i-system.c (late-variable-ref, late-variable-set): As in
link-now, allow the lazy reference to be a list, for @ and @@.
* module/language/scheme/translate.scm (custom-transformer-table):
Compile @ and @@, and set! forms for both of them. This will ease the
non-hygienic pain for exported macros.
* module/system/il/compile.scm (make-glil-var): Translate public and
private module variable references into glil-module variables.
* module/system/il/ghil.scm (ghil-var-at-module!): New function, resolves
a variable for @ or @@.
* module/system/il/glil.scm (<glil-module>): Revival of <glil-module>,
this time with the semantics that it really links to a particular
module.
* module/system/vm/assemble.scm (<vlink-now>, <vlink-later>): Redefine as
taking a "key" as the argument, which may be a sym or a list; see the
notes on link-now for more details.
(codegen): Compile <glil-module> appropriately. Some duplication here,
probably could use some cleanup later.
2008-09-30 00:31:17 +02:00
|
|
|
|
PUSH (VARIABLE_REF (what));
|
Add instructions for doing very late binding
Fixes the mutually-recursive toplevel definitions case. This could be
fixed by rewriting bodies as letrecs, as r6 does, but that's not really
repl-compatible.
* module/system/il/ghil.scm (ghil-lookup): Ok, if we can't locate a
variable, mark it as unresolved.
* module/system/il/compile.scm (make-glil-var): Compile unresolved
variables as <glil-late-bound> objects.
* module/system/il/glil.scm: Add <glil-late-bound> definition.
* module/system/vm/assemble.scm (codegen): And, finally, when we see a
<vlate-bound> object, allocate a slot for it in the object vector,
setting it to a symbol. Add a new pair of instructions to resolve that
symbol to a variable at the last minute.
* src/vm_loader.c (load-number): Bugfix: the radix argument should be
SCM_UNDEFINED in order to default to 10.
(late-bind): Add an unresolved symbol to the object vector. Could be
replaced with load-symbol I guess.
* src/vm_system.c (late-variable-ref, late-variable-set): New
instructions to do late symbol binding.
* testsuite/Makefile.am (vm_test_files):
* testsuite/t-mutual-toplevel-defines.scm: New test, failing for some
reason involving the core even? and odd? definitions.
2008-05-19 17:46:05 +02:00
|
|
|
|
NEXT;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (28, long_toplevel_ref, "long-toplevel-ref", 2, 0, 1)
|
2009-07-19 19:02:30 +02:00
|
|
|
|
{
|
2010-10-14 18:27:41 -07:00
|
|
|
|
SCM what, resolved;
|
2009-07-19 19:02:30 +02:00
|
|
|
|
unsigned int objnum = FETCH ();
|
|
|
|
|
|
objnum <<= 8;
|
|
|
|
|
|
objnum += FETCH ();
|
|
|
|
|
|
CHECK_OBJECT (objnum);
|
|
|
|
|
|
what = OBJECT_REF (objnum);
|
|
|
|
|
|
|
2010-10-14 18:27:41 -07:00
|
|
|
|
if (!SCM_VARIABLEP (what))
|
2009-07-19 19:02:30 +02:00
|
|
|
|
{
|
|
|
|
|
|
SYNC_REGISTER ();
|
2010-10-14 18:27:41 -07:00
|
|
|
|
resolved = resolve_variable (what, scm_program_module (program));
|
|
|
|
|
|
if (!VARIABLE_BOUNDP (resolved))
|
2009-07-19 19:02:30 +02:00
|
|
|
|
{
|
2010-12-07 12:26:07 +01:00
|
|
|
|
finish_args = what;
|
2009-07-19 19:02:30 +02:00
|
|
|
|
goto vm_error_unbound;
|
|
|
|
|
|
}
|
2010-10-14 18:27:41 -07:00
|
|
|
|
what = resolved;
|
2009-07-19 19:02:30 +02:00
|
|
|
|
OBJECT_SET (objnum, what);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
PUSH (VARIABLE_REF (what));
|
|
|
|
|
|
NEXT;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2001-04-01 05:03:41 +00:00
|
|
|
|
/* set */
|
|
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (29, local_set, "local-set", 1, 1, 0)
|
2000-08-22 15:54:19 +00:00
|
|
|
|
{
|
VM tweaks
* libguile/vm-engine.c (VM_CHECK_OBJECT, VM_CHECK_FREE_VARIABLES): Set
to 0 for both engines. These are really internal debugging variables,
which don't affect user-visible features, provided that the compiler
is correct of course.
(VM_CHECK_UNDERFLOW): New var, also off by default: whether to check
for stack underflow when popping values.
(vm_engine): Don't declare object_count if we are not checking object
table accesses.
* libguile/vm-engine.h (CACHE_PROGRAM): Don't muck with object_count
if we are not checking object table accesses.
(CHECK_UNDERFLOW, PRE_CHECK_UNDERFLOW): Nop out if we are not checking
underflow.
(POP2, POP3): New macros which check for underflow before popping more
than one value.
* libguile/vm-i-loader.c (load_array):
* libguile/vm-i-scheme.c (set_car, set_cdr, vector_set, slot_set)
(BV_SET_WITH_ENDIANNESS, BV_FIXABLE_INT_SET, BV_INT_SET)
(BV_FLOAT_SET):
* libguile/vm-i-system.c (partial_cont_call, fix_closure, prompt)
(fluid_set): Use POP2 / POP3.
(local_set, long_local_set): Pop to locals instead of using values on
the stack then dropping; allows for underflow to be checked before the
value is accessed.
(BR): Don't NULLSTACK or DROP after the operation.
(br_if, br_if_not, br_if_eq, br_if_not_eq, br_if_null)
(br_if_not_null): Pop to locals before doing the compare and jump.
2011-05-05 14:04:23 +02:00
|
|
|
|
SCM x;
|
|
|
|
|
|
POP (x);
|
|
|
|
|
|
LOCAL_SET (FETCH (), x);
|
2000-08-22 15:54:19 +00:00
|
|
|
|
NEXT;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (30, long_local_set, "long-local-set", 2, 1, 0)
|
2000-08-22 15:54:19 +00:00
|
|
|
|
{
|
VM tweaks
* libguile/vm-engine.c (VM_CHECK_OBJECT, VM_CHECK_FREE_VARIABLES): Set
to 0 for both engines. These are really internal debugging variables,
which don't affect user-visible features, provided that the compiler
is correct of course.
(VM_CHECK_UNDERFLOW): New var, also off by default: whether to check
for stack underflow when popping values.
(vm_engine): Don't declare object_count if we are not checking object
table accesses.
* libguile/vm-engine.h (CACHE_PROGRAM): Don't muck with object_count
if we are not checking object table accesses.
(CHECK_UNDERFLOW, PRE_CHECK_UNDERFLOW): Nop out if we are not checking
underflow.
(POP2, POP3): New macros which check for underflow before popping more
than one value.
* libguile/vm-i-loader.c (load_array):
* libguile/vm-i-scheme.c (set_car, set_cdr, vector_set, slot_set)
(BV_SET_WITH_ENDIANNESS, BV_FIXABLE_INT_SET, BV_INT_SET)
(BV_FLOAT_SET):
* libguile/vm-i-system.c (partial_cont_call, fix_closure, prompt)
(fluid_set): Use POP2 / POP3.
(local_set, long_local_set): Pop to locals instead of using values on
the stack then dropping; allows for underflow to be checked before the
value is accessed.
(BR): Don't NULLSTACK or DROP after the operation.
(br_if, br_if_not, br_if_eq, br_if_not_eq, br_if_null)
(br_if_not_null): Pop to locals before doing the compare and jump.
2011-05-05 14:04:23 +02:00
|
|
|
|
SCM x;
|
2009-07-24 11:00:32 +02:00
|
|
|
|
unsigned int i = FETCH ();
|
|
|
|
|
|
i <<= 8;
|
|
|
|
|
|
i += FETCH ();
|
VM tweaks
* libguile/vm-engine.c (VM_CHECK_OBJECT, VM_CHECK_FREE_VARIABLES): Set
to 0 for both engines. These are really internal debugging variables,
which don't affect user-visible features, provided that the compiler
is correct of course.
(VM_CHECK_UNDERFLOW): New var, also off by default: whether to check
for stack underflow when popping values.
(vm_engine): Don't declare object_count if we are not checking object
table accesses.
* libguile/vm-engine.h (CACHE_PROGRAM): Don't muck with object_count
if we are not checking object table accesses.
(CHECK_UNDERFLOW, PRE_CHECK_UNDERFLOW): Nop out if we are not checking
underflow.
(POP2, POP3): New macros which check for underflow before popping more
than one value.
* libguile/vm-i-loader.c (load_array):
* libguile/vm-i-scheme.c (set_car, set_cdr, vector_set, slot_set)
(BV_SET_WITH_ENDIANNESS, BV_FIXABLE_INT_SET, BV_INT_SET)
(BV_FLOAT_SET):
* libguile/vm-i-system.c (partial_cont_call, fix_closure, prompt)
(fluid_set): Use POP2 / POP3.
(local_set, long_local_set): Pop to locals instead of using values on
the stack then dropping; allows for underflow to be checked before the
value is accessed.
(BR): Don't NULLSTACK or DROP after the operation.
(br_if, br_if_not, br_if_eq, br_if_not_eq, br_if_null)
(br_if_not_null): Pop to locals before doing the compare and jump.
2011-05-05 14:04:23 +02:00
|
|
|
|
POP (x);
|
|
|
|
|
|
LOCAL_SET (i, x);
|
2000-08-22 15:54:19 +00:00
|
|
|
|
NEXT;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (31, variable_set, "variable-set", 0, 2, 0)
|
2000-08-22 15:54:19 +00:00
|
|
|
|
{
|
2011-01-27 10:49:51 +01:00
|
|
|
|
if (SCM_UNLIKELY (!SCM_VARIABLEP (sp[0])))
|
|
|
|
|
|
{
|
|
|
|
|
|
func_name = "variable-set!";
|
|
|
|
|
|
finish_args = sp[0];
|
|
|
|
|
|
goto vm_error_not_a_variable;
|
|
|
|
|
|
}
|
2005-04-29 14:12:12 +00:00
|
|
|
|
VARIABLE_SET (sp[0], sp[-1]);
|
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
|
|
|
|
DROPN (2);
|
2000-08-22 15:54:19 +00:00
|
|
|
|
NEXT;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (32, toplevel_set, "toplevel-set", 1, 1, 0)
|
Add instructions for doing very late binding
Fixes the mutually-recursive toplevel definitions case. This could be
fixed by rewriting bodies as letrecs, as r6 does, but that's not really
repl-compatible.
* module/system/il/ghil.scm (ghil-lookup): Ok, if we can't locate a
variable, mark it as unresolved.
* module/system/il/compile.scm (make-glil-var): Compile unresolved
variables as <glil-late-bound> objects.
* module/system/il/glil.scm: Add <glil-late-bound> definition.
* module/system/vm/assemble.scm (codegen): And, finally, when we see a
<vlate-bound> object, allocate a slot for it in the object vector,
setting it to a symbol. Add a new pair of instructions to resolve that
symbol to a variable at the last minute.
* src/vm_loader.c (load-number): Bugfix: the radix argument should be
SCM_UNDEFINED in order to default to 10.
(late-bind): Add an unresolved symbol to the object vector. Could be
replaced with load-symbol I guess.
* src/vm_system.c (late-variable-ref, late-variable-set): New
instructions to do late symbol binding.
* testsuite/Makefile.am (vm_test_files):
* testsuite/t-mutual-toplevel-defines.scm: New test, failing for some
reason involving the core even? and odd? definitions.
2008-05-19 17:46:05 +02:00
|
|
|
|
{
|
2008-05-19 19:37:39 +02:00
|
|
|
|
unsigned objnum = FETCH ();
|
compile @ and @@
* libguile/vm-engine.c (vm_run): Add new error case for resolving @ or @@
references, but there is no such module. Possible if
module-public-interface returns #f.
* libguile/vm-i-loader.c (link-now): Allow the stack arg to be a sym, as
before, or a list, indicating an absolute reference. Could be two
separate instructions, but I'm lazy.
* libguile/vm-i-system.c (late-variable-ref, late-variable-set): As in
link-now, allow the lazy reference to be a list, for @ and @@.
* module/language/scheme/translate.scm (custom-transformer-table):
Compile @ and @@, and set! forms for both of them. This will ease the
non-hygienic pain for exported macros.
* module/system/il/compile.scm (make-glil-var): Translate public and
private module variable references into glil-module variables.
* module/system/il/ghil.scm (ghil-var-at-module!): New function, resolves
a variable for @ or @@.
* module/system/il/glil.scm (<glil-module>): Revival of <glil-module>,
this time with the semantics that it really links to a particular
module.
* module/system/vm/assemble.scm (<vlink-now>, <vlink-later>): Redefine as
taking a "key" as the argument, which may be a sym or a list; see the
notes on link-now for more details.
(codegen): Compile <glil-module> appropriately. Some duplication here,
probably could use some cleanup later.
2008-09-30 00:31:17 +02:00
|
|
|
|
SCM what;
|
Add instructions for doing very late binding
Fixes the mutually-recursive toplevel definitions case. This could be
fixed by rewriting bodies as letrecs, as r6 does, but that's not really
repl-compatible.
* module/system/il/ghil.scm (ghil-lookup): Ok, if we can't locate a
variable, mark it as unresolved.
* module/system/il/compile.scm (make-glil-var): Compile unresolved
variables as <glil-late-bound> objects.
* module/system/il/glil.scm: Add <glil-late-bound> definition.
* module/system/vm/assemble.scm (codegen): And, finally, when we see a
<vlate-bound> object, allocate a slot for it in the object vector,
setting it to a symbol. Add a new pair of instructions to resolve that
symbol to a variable at the last minute.
* src/vm_loader.c (load-number): Bugfix: the radix argument should be
SCM_UNDEFINED in order to default to 10.
(late-bind): Add an unresolved symbol to the object vector. Could be
replaced with load-symbol I guess.
* src/vm_system.c (late-variable-ref, late-variable-set): New
instructions to do late symbol binding.
* testsuite/Makefile.am (vm_test_files):
* testsuite/t-mutual-toplevel-defines.scm: New test, failing for some
reason involving the core even? and odd? definitions.
2008-05-19 17:46:05 +02:00
|
|
|
|
CHECK_OBJECT (objnum);
|
compile @ and @@
* libguile/vm-engine.c (vm_run): Add new error case for resolving @ or @@
references, but there is no such module. Possible if
module-public-interface returns #f.
* libguile/vm-i-loader.c (link-now): Allow the stack arg to be a sym, as
before, or a list, indicating an absolute reference. Could be two
separate instructions, but I'm lazy.
* libguile/vm-i-system.c (late-variable-ref, late-variable-set): As in
link-now, allow the lazy reference to be a list, for @ and @@.
* module/language/scheme/translate.scm (custom-transformer-table):
Compile @ and @@, and set! forms for both of them. This will ease the
non-hygienic pain for exported macros.
* module/system/il/compile.scm (make-glil-var): Translate public and
private module variable references into glil-module variables.
* module/system/il/ghil.scm (ghil-var-at-module!): New function, resolves
a variable for @ or @@.
* module/system/il/glil.scm (<glil-module>): Revival of <glil-module>,
this time with the semantics that it really links to a particular
module.
* module/system/vm/assemble.scm (<vlink-now>, <vlink-later>): Redefine as
taking a "key" as the argument, which may be a sym or a list; see the
notes on link-now for more details.
(codegen): Compile <glil-module> appropriately. Some duplication here,
probably could use some cleanup later.
2008-09-30 00:31:17 +02:00
|
|
|
|
what = OBJECT_REF (objnum);
|
Add instructions for doing very late binding
Fixes the mutually-recursive toplevel definitions case. This could be
fixed by rewriting bodies as letrecs, as r6 does, but that's not really
repl-compatible.
* module/system/il/ghil.scm (ghil-lookup): Ok, if we can't locate a
variable, mark it as unresolved.
* module/system/il/compile.scm (make-glil-var): Compile unresolved
variables as <glil-late-bound> objects.
* module/system/il/glil.scm: Add <glil-late-bound> definition.
* module/system/vm/assemble.scm (codegen): And, finally, when we see a
<vlate-bound> object, allocate a slot for it in the object vector,
setting it to a symbol. Add a new pair of instructions to resolve that
symbol to a variable at the last minute.
* src/vm_loader.c (load-number): Bugfix: the radix argument should be
SCM_UNDEFINED in order to default to 10.
(late-bind): Add an unresolved symbol to the object vector. Could be
replaced with load-symbol I guess.
* src/vm_system.c (late-variable-ref, late-variable-set): New
instructions to do late symbol binding.
* testsuite/Makefile.am (vm_test_files):
* testsuite/t-mutual-toplevel-defines.scm: New test, failing for some
reason involving the core even? and odd? definitions.
2008-05-19 17:46:05 +02:00
|
|
|
|
|
compile @ and @@
* libguile/vm-engine.c (vm_run): Add new error case for resolving @ or @@
references, but there is no such module. Possible if
module-public-interface returns #f.
* libguile/vm-i-loader.c (link-now): Allow the stack arg to be a sym, as
before, or a list, indicating an absolute reference. Could be two
separate instructions, but I'm lazy.
* libguile/vm-i-system.c (late-variable-ref, late-variable-set): As in
link-now, allow the lazy reference to be a list, for @ and @@.
* module/language/scheme/translate.scm (custom-transformer-table):
Compile @ and @@, and set! forms for both of them. This will ease the
non-hygienic pain for exported macros.
* module/system/il/compile.scm (make-glil-var): Translate public and
private module variable references into glil-module variables.
* module/system/il/ghil.scm (ghil-var-at-module!): New function, resolves
a variable for @ or @@.
* module/system/il/glil.scm (<glil-module>): Revival of <glil-module>,
this time with the semantics that it really links to a particular
module.
* module/system/vm/assemble.scm (<vlink-now>, <vlink-later>): Redefine as
taking a "key" as the argument, which may be a sym or a list; see the
notes on link-now for more details.
(codegen): Compile <glil-module> appropriately. Some duplication here,
probably could use some cleanup later.
2008-09-30 00:31:17 +02:00
|
|
|
|
if (!SCM_VARIABLEP (what))
|
Add instructions for doing very late binding
Fixes the mutually-recursive toplevel definitions case. This could be
fixed by rewriting bodies as letrecs, as r6 does, but that's not really
repl-compatible.
* module/system/il/ghil.scm (ghil-lookup): Ok, if we can't locate a
variable, mark it as unresolved.
* module/system/il/compile.scm (make-glil-var): Compile unresolved
variables as <glil-late-bound> objects.
* module/system/il/glil.scm: Add <glil-late-bound> definition.
* module/system/vm/assemble.scm (codegen): And, finally, when we see a
<vlate-bound> object, allocate a slot for it in the object vector,
setting it to a symbol. Add a new pair of instructions to resolve that
symbol to a variable at the last minute.
* src/vm_loader.c (load-number): Bugfix: the radix argument should be
SCM_UNDEFINED in order to default to 10.
(late-bind): Add an unresolved symbol to the object vector. Could be
replaced with load-symbol I guess.
* src/vm_system.c (late-variable-ref, late-variable-set): New
instructions to do late symbol binding.
* testsuite/Makefile.am (vm_test_files):
* testsuite/t-mutual-toplevel-defines.scm: New test, failing for some
reason involving the core even? and odd? definitions.
2008-05-19 17:46:05 +02:00
|
|
|
|
{
|
2008-08-05 23:08:58 +02:00
|
|
|
|
SYNC_BEFORE_GC ();
|
2009-06-05 11:47:19 +02:00
|
|
|
|
what = resolve_variable (what, scm_program_module (program));
|
compile @ and @@
* libguile/vm-engine.c (vm_run): Add new error case for resolving @ or @@
references, but there is no such module. Possible if
module-public-interface returns #f.
* libguile/vm-i-loader.c (link-now): Allow the stack arg to be a sym, as
before, or a list, indicating an absolute reference. Could be two
separate instructions, but I'm lazy.
* libguile/vm-i-system.c (late-variable-ref, late-variable-set): As in
link-now, allow the lazy reference to be a list, for @ and @@.
* module/language/scheme/translate.scm (custom-transformer-table):
Compile @ and @@, and set! forms for both of them. This will ease the
non-hygienic pain for exported macros.
* module/system/il/compile.scm (make-glil-var): Translate public and
private module variable references into glil-module variables.
* module/system/il/ghil.scm (ghil-var-at-module!): New function, resolves
a variable for @ or @@.
* module/system/il/glil.scm (<glil-module>): Revival of <glil-module>,
this time with the semantics that it really links to a particular
module.
* module/system/vm/assemble.scm (<vlink-now>, <vlink-later>): Redefine as
taking a "key" as the argument, which may be a sym or a list; see the
notes on link-now for more details.
(codegen): Compile <glil-module> appropriately. Some duplication here,
probably could use some cleanup later.
2008-09-30 00:31:17 +02:00
|
|
|
|
OBJECT_SET (objnum, what);
|
Add instructions for doing very late binding
Fixes the mutually-recursive toplevel definitions case. This could be
fixed by rewriting bodies as letrecs, as r6 does, but that's not really
repl-compatible.
* module/system/il/ghil.scm (ghil-lookup): Ok, if we can't locate a
variable, mark it as unresolved.
* module/system/il/compile.scm (make-glil-var): Compile unresolved
variables as <glil-late-bound> objects.
* module/system/il/glil.scm: Add <glil-late-bound> definition.
* module/system/vm/assemble.scm (codegen): And, finally, when we see a
<vlate-bound> object, allocate a slot for it in the object vector,
setting it to a symbol. Add a new pair of instructions to resolve that
symbol to a variable at the last minute.
* src/vm_loader.c (load-number): Bugfix: the radix argument should be
SCM_UNDEFINED in order to default to 10.
(late-bind): Add an unresolved symbol to the object vector. Could be
replaced with load-symbol I guess.
* src/vm_system.c (late-variable-ref, late-variable-set): New
instructions to do late symbol binding.
* testsuite/Makefile.am (vm_test_files):
* testsuite/t-mutual-toplevel-defines.scm: New test, failing for some
reason involving the core even? and odd? definitions.
2008-05-19 17:46:05 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
compile @ and @@
* libguile/vm-engine.c (vm_run): Add new error case for resolving @ or @@
references, but there is no such module. Possible if
module-public-interface returns #f.
* libguile/vm-i-loader.c (link-now): Allow the stack arg to be a sym, as
before, or a list, indicating an absolute reference. Could be two
separate instructions, but I'm lazy.
* libguile/vm-i-system.c (late-variable-ref, late-variable-set): As in
link-now, allow the lazy reference to be a list, for @ and @@.
* module/language/scheme/translate.scm (custom-transformer-table):
Compile @ and @@, and set! forms for both of them. This will ease the
non-hygienic pain for exported macros.
* module/system/il/compile.scm (make-glil-var): Translate public and
private module variable references into glil-module variables.
* module/system/il/ghil.scm (ghil-var-at-module!): New function, resolves
a variable for @ or @@.
* module/system/il/glil.scm (<glil-module>): Revival of <glil-module>,
this time with the semantics that it really links to a particular
module.
* module/system/vm/assemble.scm (<vlink-now>, <vlink-later>): Redefine as
taking a "key" as the argument, which may be a sym or a list; see the
notes on link-now for more details.
(codegen): Compile <glil-module> appropriately. Some duplication here,
probably could use some cleanup later.
2008-09-30 00:31:17 +02:00
|
|
|
|
VARIABLE_SET (what, *sp);
|
Add instructions for doing very late binding
Fixes the mutually-recursive toplevel definitions case. This could be
fixed by rewriting bodies as letrecs, as r6 does, but that's not really
repl-compatible.
* module/system/il/ghil.scm (ghil-lookup): Ok, if we can't locate a
variable, mark it as unresolved.
* module/system/il/compile.scm (make-glil-var): Compile unresolved
variables as <glil-late-bound> objects.
* module/system/il/glil.scm: Add <glil-late-bound> definition.
* module/system/vm/assemble.scm (codegen): And, finally, when we see a
<vlate-bound> object, allocate a slot for it in the object vector,
setting it to a symbol. Add a new pair of instructions to resolve that
symbol to a variable at the last minute.
* src/vm_loader.c (load-number): Bugfix: the radix argument should be
SCM_UNDEFINED in order to default to 10.
(late-bind): Add an unresolved symbol to the object vector. Could be
replaced with load-symbol I guess.
* src/vm_system.c (late-variable-ref, late-variable-set): New
instructions to do late symbol binding.
* testsuite/Makefile.am (vm_test_files):
* testsuite/t-mutual-toplevel-defines.scm: New test, failing for some
reason involving the core even? and odd? definitions.
2008-05-19 17:46:05 +02:00
|
|
|
|
DROP ();
|
|
|
|
|
|
NEXT;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (33, long_toplevel_set, "long-toplevel-set", 2, 1, 0)
|
2009-07-19 19:02:30 +02:00
|
|
|
|
{
|
|
|
|
|
|
SCM what;
|
|
|
|
|
|
unsigned int objnum = FETCH ();
|
|
|
|
|
|
objnum <<= 8;
|
|
|
|
|
|
objnum += FETCH ();
|
|
|
|
|
|
CHECK_OBJECT (objnum);
|
|
|
|
|
|
what = OBJECT_REF (objnum);
|
|
|
|
|
|
|
|
|
|
|
|
if (!SCM_VARIABLEP (what))
|
|
|
|
|
|
{
|
|
|
|
|
|
SYNC_BEFORE_GC ();
|
|
|
|
|
|
what = resolve_variable (what, scm_program_module (program));
|
|
|
|
|
|
OBJECT_SET (objnum, what);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
VARIABLE_SET (what, *sp);
|
|
|
|
|
|
DROP ();
|
|
|
|
|
|
NEXT;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2000-08-22 15:54:19 +00:00
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
* branch and jump
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
2009-09-17 14:58:31 +02:00
|
|
|
|
/* offset must be at least 24 bits wide, and signed */
|
compile call-with-values, woot!
* libguile/vm-engine.c (vm_run): Add another byte onto the bootstrap
program, as the offset passed to mv-call now takes two bytes.
* module/system/vm/frame.scm (bootstrap-frame?): Update for the new
bootstrap length. Really we should just check for 'halt though.
* libguile/vm-i-system.c (FETCH_OFFSET): New helper, used in BR().
(goto/nargs, call/nargs): Versions of goto/args and call, respectively,
that take the number of arguments from a value on the top of the stack.
(mv-call): Call FETCH_OFFSET to get the offset.
* module/language/scheme/translate.scm (custom-transformer-table):
Compile call-with-values to <ghil-mv-call>. There is some trickery
because of the r4rs.scm call-with-values trampolines.
* module/system/il/ghil.scm: Add <ghil-mv-call> and accessors.
* module/system/il/compile.scm (codegen): Compile <ghil-mv-call>.
* module/system/il/glil.scm: Add <glil-mv-call>, which needs some special
assembly because of the label. Fix some typos.
* module/system/vm/assemble.scm (byte-length): New helper, factored out
and made more general.
(codegen): Assemble mv-call, including the label.
(check-length): New helper, makes sure that the addressing is
consistent within the produced object code.
(stack->bytes): Rewrite to be more generic -- now `br' instructions
aren't the only ones jumping around in the instruction stream.
* module/system/vm/conv.scm (make-byte-decoder): Return two values in the
#f case.
* module/system/vm/disasm.scm (disassemble-bytecode): Rewrite, because
the previous implementation depended on a guile interpreter quirk:
namely, that multiple values could be represented within one value, and
destructured later.
2008-09-16 00:26:22 +02:00
|
|
|
|
#define FETCH_OFFSET(offset) \
|
2001-04-01 05:03:41 +00:00
|
|
|
|
{ \
|
2009-09-17 14:58:31 +02:00
|
|
|
|
offset = FETCH () << 16; \
|
|
|
|
|
|
offset += FETCH () << 8; \
|
|
|
|
|
|
offset += FETCH (); \
|
|
|
|
|
|
offset -= (offset & (1<<23)) << 1; \
|
compile call-with-values, woot!
* libguile/vm-engine.c (vm_run): Add another byte onto the bootstrap
program, as the offset passed to mv-call now takes two bytes.
* module/system/vm/frame.scm (bootstrap-frame?): Update for the new
bootstrap length. Really we should just check for 'halt though.
* libguile/vm-i-system.c (FETCH_OFFSET): New helper, used in BR().
(goto/nargs, call/nargs): Versions of goto/args and call, respectively,
that take the number of arguments from a value on the top of the stack.
(mv-call): Call FETCH_OFFSET to get the offset.
* module/language/scheme/translate.scm (custom-transformer-table):
Compile call-with-values to <ghil-mv-call>. There is some trickery
because of the r4rs.scm call-with-values trampolines.
* module/system/il/ghil.scm: Add <ghil-mv-call> and accessors.
* module/system/il/compile.scm (codegen): Compile <ghil-mv-call>.
* module/system/il/glil.scm: Add <glil-mv-call>, which needs some special
assembly because of the label. Fix some typos.
* module/system/vm/assemble.scm (byte-length): New helper, factored out
and made more general.
(codegen): Assemble mv-call, including the label.
(check-length): New helper, makes sure that the addressing is
consistent within the produced object code.
(stack->bytes): Rewrite to be more generic -- now `br' instructions
aren't the only ones jumping around in the instruction stream.
* module/system/vm/conv.scm (make-byte-decoder): Return two values in the
#f case.
* module/system/vm/disasm.scm (disassemble-bytecode): Rewrite, because
the previous implementation depended on a guile interpreter quirk:
namely, that multiple values could be represented within one value, and
destructured later.
2008-09-16 00:26:22 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
VM tweaks
* libguile/vm-engine.c (VM_CHECK_OBJECT, VM_CHECK_FREE_VARIABLES): Set
to 0 for both engines. These are really internal debugging variables,
which don't affect user-visible features, provided that the compiler
is correct of course.
(VM_CHECK_UNDERFLOW): New var, also off by default: whether to check
for stack underflow when popping values.
(vm_engine): Don't declare object_count if we are not checking object
table accesses.
* libguile/vm-engine.h (CACHE_PROGRAM): Don't muck with object_count
if we are not checking object table accesses.
(CHECK_UNDERFLOW, PRE_CHECK_UNDERFLOW): Nop out if we are not checking
underflow.
(POP2, POP3): New macros which check for underflow before popping more
than one value.
* libguile/vm-i-loader.c (load_array):
* libguile/vm-i-scheme.c (set_car, set_cdr, vector_set, slot_set)
(BV_SET_WITH_ENDIANNESS, BV_FIXABLE_INT_SET, BV_INT_SET)
(BV_FLOAT_SET):
* libguile/vm-i-system.c (partial_cont_call, fix_closure, prompt)
(fluid_set): Use POP2 / POP3.
(local_set, long_local_set): Pop to locals instead of using values on
the stack then dropping; allows for underflow to be checked before the
value is accessed.
(BR): Don't NULLSTACK or DROP after the operation.
(br_if, br_if_not, br_if_eq, br_if_not_eq, br_if_null)
(br_if_not_null): Pop to locals before doing the compare and jump.
2011-05-05 14:04:23 +02:00
|
|
|
|
#define BR(p) \
|
compile call-with-values, woot!
* libguile/vm-engine.c (vm_run): Add another byte onto the bootstrap
program, as the offset passed to mv-call now takes two bytes.
* module/system/vm/frame.scm (bootstrap-frame?): Update for the new
bootstrap length. Really we should just check for 'halt though.
* libguile/vm-i-system.c (FETCH_OFFSET): New helper, used in BR().
(goto/nargs, call/nargs): Versions of goto/args and call, respectively,
that take the number of arguments from a value on the top of the stack.
(mv-call): Call FETCH_OFFSET to get the offset.
* module/language/scheme/translate.scm (custom-transformer-table):
Compile call-with-values to <ghil-mv-call>. There is some trickery
because of the r4rs.scm call-with-values trampolines.
* module/system/il/ghil.scm: Add <ghil-mv-call> and accessors.
* module/system/il/compile.scm (codegen): Compile <ghil-mv-call>.
* module/system/il/glil.scm: Add <glil-mv-call>, which needs some special
assembly because of the label. Fix some typos.
* module/system/vm/assemble.scm (byte-length): New helper, factored out
and made more general.
(codegen): Assemble mv-call, including the label.
(check-length): New helper, makes sure that the addressing is
consistent within the produced object code.
(stack->bytes): Rewrite to be more generic -- now `br' instructions
aren't the only ones jumping around in the instruction stream.
* module/system/vm/conv.scm (make-byte-decoder): Return two values in the
#f case.
* module/system/vm/disasm.scm (disassemble-bytecode): Rewrite, because
the previous implementation depended on a guile interpreter quirk:
namely, that multiple values could be represented within one value, and
destructured later.
2008-09-16 00:26:22 +02:00
|
|
|
|
{ \
|
2009-09-17 14:58:31 +02:00
|
|
|
|
scm_t_int32 offset; \
|
compile call-with-values, woot!
* libguile/vm-engine.c (vm_run): Add another byte onto the bootstrap
program, as the offset passed to mv-call now takes two bytes.
* module/system/vm/frame.scm (bootstrap-frame?): Update for the new
bootstrap length. Really we should just check for 'halt though.
* libguile/vm-i-system.c (FETCH_OFFSET): New helper, used in BR().
(goto/nargs, call/nargs): Versions of goto/args and call, respectively,
that take the number of arguments from a value on the top of the stack.
(mv-call): Call FETCH_OFFSET to get the offset.
* module/language/scheme/translate.scm (custom-transformer-table):
Compile call-with-values to <ghil-mv-call>. There is some trickery
because of the r4rs.scm call-with-values trampolines.
* module/system/il/ghil.scm: Add <ghil-mv-call> and accessors.
* module/system/il/compile.scm (codegen): Compile <ghil-mv-call>.
* module/system/il/glil.scm: Add <glil-mv-call>, which needs some special
assembly because of the label. Fix some typos.
* module/system/vm/assemble.scm (byte-length): New helper, factored out
and made more general.
(codegen): Assemble mv-call, including the label.
(check-length): New helper, makes sure that the addressing is
consistent within the produced object code.
(stack->bytes): Rewrite to be more generic -- now `br' instructions
aren't the only ones jumping around in the instruction stream.
* module/system/vm/conv.scm (make-byte-decoder): Return two values in the
#f case.
* module/system/vm/disasm.scm (disassemble-bytecode): Rewrite, because
the previous implementation depended on a guile interpreter quirk:
namely, that multiple values could be represented within one value, and
destructured later.
2008-09-16 00:26:22 +02:00
|
|
|
|
FETCH_OFFSET (offset); \
|
2001-04-01 05:03:41 +00:00
|
|
|
|
if (p) \
|
2009-09-17 14:58:31 +02:00
|
|
|
|
ip += offset; \
|
2009-12-11 11:17:03 +01:00
|
|
|
|
if (offset < 0) \
|
|
|
|
|
|
VM_HANDLE_INTERRUPTS; \
|
2001-04-01 05:03:41 +00:00
|
|
|
|
NEXT; \
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (34, br, "br", 3, 0, 0)
|
2001-04-11 20:57:44 +00:00
|
|
|
|
{
|
2009-09-17 14:58:31 +02:00
|
|
|
|
scm_t_int32 offset;
|
2009-07-26 14:01:56 +02:00
|
|
|
|
FETCH_OFFSET (offset);
|
2009-09-17 14:58:31 +02:00
|
|
|
|
ip += offset;
|
2009-12-11 11:17:03 +01:00
|
|
|
|
if (offset < 0)
|
|
|
|
|
|
VM_HANDLE_INTERRUPTS;
|
2001-04-11 20:57:44 +00:00
|
|
|
|
NEXT;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (35, br_if, "br-if", 3, 0, 0)
|
2000-08-22 15:54:19 +00:00
|
|
|
|
{
|
VM tweaks
* libguile/vm-engine.c (VM_CHECK_OBJECT, VM_CHECK_FREE_VARIABLES): Set
to 0 for both engines. These are really internal debugging variables,
which don't affect user-visible features, provided that the compiler
is correct of course.
(VM_CHECK_UNDERFLOW): New var, also off by default: whether to check
for stack underflow when popping values.
(vm_engine): Don't declare object_count if we are not checking object
table accesses.
* libguile/vm-engine.h (CACHE_PROGRAM): Don't muck with object_count
if we are not checking object table accesses.
(CHECK_UNDERFLOW, PRE_CHECK_UNDERFLOW): Nop out if we are not checking
underflow.
(POP2, POP3): New macros which check for underflow before popping more
than one value.
* libguile/vm-i-loader.c (load_array):
* libguile/vm-i-scheme.c (set_car, set_cdr, vector_set, slot_set)
(BV_SET_WITH_ENDIANNESS, BV_FIXABLE_INT_SET, BV_INT_SET)
(BV_FLOAT_SET):
* libguile/vm-i-system.c (partial_cont_call, fix_closure, prompt)
(fluid_set): Use POP2 / POP3.
(local_set, long_local_set): Pop to locals instead of using values on
the stack then dropping; allows for underflow to be checked before the
value is accessed.
(BR): Don't NULLSTACK or DROP after the operation.
(br_if, br_if_not, br_if_eq, br_if_not_eq, br_if_null)
(br_if_not_null): Pop to locals before doing the compare and jump.
2011-05-05 14:04:23 +02:00
|
|
|
|
SCM x;
|
|
|
|
|
|
POP (x);
|
|
|
|
|
|
BR (scm_is_true (x));
|
2000-08-22 15:54:19 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (36, br_if_not, "br-if-not", 3, 0, 0)
|
2000-08-22 15:54:19 +00:00
|
|
|
|
{
|
VM tweaks
* libguile/vm-engine.c (VM_CHECK_OBJECT, VM_CHECK_FREE_VARIABLES): Set
to 0 for both engines. These are really internal debugging variables,
which don't affect user-visible features, provided that the compiler
is correct of course.
(VM_CHECK_UNDERFLOW): New var, also off by default: whether to check
for stack underflow when popping values.
(vm_engine): Don't declare object_count if we are not checking object
table accesses.
* libguile/vm-engine.h (CACHE_PROGRAM): Don't muck with object_count
if we are not checking object table accesses.
(CHECK_UNDERFLOW, PRE_CHECK_UNDERFLOW): Nop out if we are not checking
underflow.
(POP2, POP3): New macros which check for underflow before popping more
than one value.
* libguile/vm-i-loader.c (load_array):
* libguile/vm-i-scheme.c (set_car, set_cdr, vector_set, slot_set)
(BV_SET_WITH_ENDIANNESS, BV_FIXABLE_INT_SET, BV_INT_SET)
(BV_FLOAT_SET):
* libguile/vm-i-system.c (partial_cont_call, fix_closure, prompt)
(fluid_set): Use POP2 / POP3.
(local_set, long_local_set): Pop to locals instead of using values on
the stack then dropping; allows for underflow to be checked before the
value is accessed.
(BR): Don't NULLSTACK or DROP after the operation.
(br_if, br_if_not, br_if_eq, br_if_not_eq, br_if_null)
(br_if_not_null): Pop to locals before doing the compare and jump.
2011-05-05 14:04:23 +02:00
|
|
|
|
SCM x;
|
|
|
|
|
|
POP (x);
|
|
|
|
|
|
BR (scm_is_false (x));
|
2000-08-22 15:54:19 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (37, br_if_eq, "br-if-eq", 3, 0, 0)
|
2000-08-22 15:54:19 +00:00
|
|
|
|
{
|
VM tweaks
* libguile/vm-engine.c (VM_CHECK_OBJECT, VM_CHECK_FREE_VARIABLES): Set
to 0 for both engines. These are really internal debugging variables,
which don't affect user-visible features, provided that the compiler
is correct of course.
(VM_CHECK_UNDERFLOW): New var, also off by default: whether to check
for stack underflow when popping values.
(vm_engine): Don't declare object_count if we are not checking object
table accesses.
* libguile/vm-engine.h (CACHE_PROGRAM): Don't muck with object_count
if we are not checking object table accesses.
(CHECK_UNDERFLOW, PRE_CHECK_UNDERFLOW): Nop out if we are not checking
underflow.
(POP2, POP3): New macros which check for underflow before popping more
than one value.
* libguile/vm-i-loader.c (load_array):
* libguile/vm-i-scheme.c (set_car, set_cdr, vector_set, slot_set)
(BV_SET_WITH_ENDIANNESS, BV_FIXABLE_INT_SET, BV_INT_SET)
(BV_FLOAT_SET):
* libguile/vm-i-system.c (partial_cont_call, fix_closure, prompt)
(fluid_set): Use POP2 / POP3.
(local_set, long_local_set): Pop to locals instead of using values on
the stack then dropping; allows for underflow to be checked before the
value is accessed.
(BR): Don't NULLSTACK or DROP after the operation.
(br_if, br_if_not, br_if_eq, br_if_not_eq, br_if_null)
(br_if_not_null): Pop to locals before doing the compare and jump.
2011-05-05 14:04:23 +02:00
|
|
|
|
SCM x, y;
|
|
|
|
|
|
POP2 (y, x);
|
|
|
|
|
|
BR (scm_is_eq (x, y));
|
2000-08-22 15:54:19 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (38, br_if_not_eq, "br-if-not-eq", 3, 0, 0)
|
2000-08-22 15:54:19 +00:00
|
|
|
|
{
|
VM tweaks
* libguile/vm-engine.c (VM_CHECK_OBJECT, VM_CHECK_FREE_VARIABLES): Set
to 0 for both engines. These are really internal debugging variables,
which don't affect user-visible features, provided that the compiler
is correct of course.
(VM_CHECK_UNDERFLOW): New var, also off by default: whether to check
for stack underflow when popping values.
(vm_engine): Don't declare object_count if we are not checking object
table accesses.
* libguile/vm-engine.h (CACHE_PROGRAM): Don't muck with object_count
if we are not checking object table accesses.
(CHECK_UNDERFLOW, PRE_CHECK_UNDERFLOW): Nop out if we are not checking
underflow.
(POP2, POP3): New macros which check for underflow before popping more
than one value.
* libguile/vm-i-loader.c (load_array):
* libguile/vm-i-scheme.c (set_car, set_cdr, vector_set, slot_set)
(BV_SET_WITH_ENDIANNESS, BV_FIXABLE_INT_SET, BV_INT_SET)
(BV_FLOAT_SET):
* libguile/vm-i-system.c (partial_cont_call, fix_closure, prompt)
(fluid_set): Use POP2 / POP3.
(local_set, long_local_set): Pop to locals instead of using values on
the stack then dropping; allows for underflow to be checked before the
value is accessed.
(BR): Don't NULLSTACK or DROP after the operation.
(br_if, br_if_not, br_if_eq, br_if_not_eq, br_if_null)
(br_if_not_null): Pop to locals before doing the compare and jump.
2011-05-05 14:04:23 +02:00
|
|
|
|
SCM x, y;
|
|
|
|
|
|
POP2 (y, x);
|
|
|
|
|
|
BR (!scm_is_eq (x, y));
|
2001-04-01 05:03:41 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (39, br_if_null, "br-if-null", 3, 0, 0)
|
2001-04-01 05:03:41 +00:00
|
|
|
|
{
|
VM tweaks
* libguile/vm-engine.c (VM_CHECK_OBJECT, VM_CHECK_FREE_VARIABLES): Set
to 0 for both engines. These are really internal debugging variables,
which don't affect user-visible features, provided that the compiler
is correct of course.
(VM_CHECK_UNDERFLOW): New var, also off by default: whether to check
for stack underflow when popping values.
(vm_engine): Don't declare object_count if we are not checking object
table accesses.
* libguile/vm-engine.h (CACHE_PROGRAM): Don't muck with object_count
if we are not checking object table accesses.
(CHECK_UNDERFLOW, PRE_CHECK_UNDERFLOW): Nop out if we are not checking
underflow.
(POP2, POP3): New macros which check for underflow before popping more
than one value.
* libguile/vm-i-loader.c (load_array):
* libguile/vm-i-scheme.c (set_car, set_cdr, vector_set, slot_set)
(BV_SET_WITH_ENDIANNESS, BV_FIXABLE_INT_SET, BV_INT_SET)
(BV_FLOAT_SET):
* libguile/vm-i-system.c (partial_cont_call, fix_closure, prompt)
(fluid_set): Use POP2 / POP3.
(local_set, long_local_set): Pop to locals instead of using values on
the stack then dropping; allows for underflow to be checked before the
value is accessed.
(BR): Don't NULLSTACK or DROP after the operation.
(br_if, br_if_not, br_if_eq, br_if_not_eq, br_if_null)
(br_if_not_null): Pop to locals before doing the compare and jump.
2011-05-05 14:04:23 +02:00
|
|
|
|
SCM x;
|
|
|
|
|
|
POP (x);
|
|
|
|
|
|
BR (scm_is_null (x));
|
2001-04-01 05:03:41 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (40, br_if_not_null, "br-if-not-null", 3, 0, 0)
|
2001-04-01 05:03:41 +00:00
|
|
|
|
{
|
VM tweaks
* libguile/vm-engine.c (VM_CHECK_OBJECT, VM_CHECK_FREE_VARIABLES): Set
to 0 for both engines. These are really internal debugging variables,
which don't affect user-visible features, provided that the compiler
is correct of course.
(VM_CHECK_UNDERFLOW): New var, also off by default: whether to check
for stack underflow when popping values.
(vm_engine): Don't declare object_count if we are not checking object
table accesses.
* libguile/vm-engine.h (CACHE_PROGRAM): Don't muck with object_count
if we are not checking object table accesses.
(CHECK_UNDERFLOW, PRE_CHECK_UNDERFLOW): Nop out if we are not checking
underflow.
(POP2, POP3): New macros which check for underflow before popping more
than one value.
* libguile/vm-i-loader.c (load_array):
* libguile/vm-i-scheme.c (set_car, set_cdr, vector_set, slot_set)
(BV_SET_WITH_ENDIANNESS, BV_FIXABLE_INT_SET, BV_INT_SET)
(BV_FLOAT_SET):
* libguile/vm-i-system.c (partial_cont_call, fix_closure, prompt)
(fluid_set): Use POP2 / POP3.
(local_set, long_local_set): Pop to locals instead of using values on
the stack then dropping; allows for underflow to be checked before the
value is accessed.
(BR): Don't NULLSTACK or DROP after the operation.
(br_if, br_if_not, br_if_eq, br_if_not_eq, br_if_null)
(br_if_not_null): Pop to locals before doing the compare and jump.
2011-05-05 14:04:23 +02:00
|
|
|
|
SCM x;
|
|
|
|
|
|
POP (x);
|
|
|
|
|
|
BR (!scm_is_null (x));
|
2000-08-22 15:54:19 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
* Subprogram call
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (41, br_if_nargs_ne, "br-if-nargs-ne", 5, 0, 0)
|
2009-10-17 17:23:09 +02:00
|
|
|
|
{
|
|
|
|
|
|
scm_t_ptrdiff n;
|
2009-11-17 01:26:25 +01:00
|
|
|
|
scm_t_int32 offset;
|
2009-10-17 17:23:09 +02:00
|
|
|
|
n = FETCH () << 8;
|
|
|
|
|
|
n += FETCH ();
|
|
|
|
|
|
FETCH_OFFSET (offset);
|
|
|
|
|
|
if (sp - (fp - 1) != n)
|
|
|
|
|
|
ip += offset;
|
|
|
|
|
|
NEXT;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (42, br_if_nargs_lt, "br-if-nargs-lt", 5, 0, 0)
|
2009-10-17 17:23:09 +02:00
|
|
|
|
{
|
|
|
|
|
|
scm_t_ptrdiff n;
|
2009-11-17 01:26:25 +01:00
|
|
|
|
scm_t_int32 offset;
|
2009-10-17 17:23:09 +02:00
|
|
|
|
n = FETCH () << 8;
|
|
|
|
|
|
n += FETCH ();
|
|
|
|
|
|
FETCH_OFFSET (offset);
|
|
|
|
|
|
if (sp - (fp - 1) < n)
|
|
|
|
|
|
ip += offset;
|
|
|
|
|
|
NEXT;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (43, br_if_nargs_gt, "br-if-nargs-gt", 5, 0, 0)
|
2009-10-17 17:23:09 +02:00
|
|
|
|
{
|
|
|
|
|
|
scm_t_ptrdiff n;
|
2009-11-16 22:32:54 +01:00
|
|
|
|
scm_t_int32 offset;
|
|
|
|
|
|
|
2009-10-17 17:23:09 +02:00
|
|
|
|
n = FETCH () << 8;
|
|
|
|
|
|
n += FETCH ();
|
|
|
|
|
|
FETCH_OFFSET (offset);
|
|
|
|
|
|
if (sp - (fp - 1) > n)
|
|
|
|
|
|
ip += offset;
|
|
|
|
|
|
NEXT;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (44, assert_nargs_ee, "assert-nargs-ee", 2, 0, 0)
|
2009-09-27 18:16:56 -04:00
|
|
|
|
{
|
|
|
|
|
|
scm_t_ptrdiff n;
|
|
|
|
|
|
n = FETCH () << 8;
|
|
|
|
|
|
n += FETCH ();
|
2009-09-27 20:25:39 -04:00
|
|
|
|
if (sp - (fp - 1) != n)
|
2009-09-27 18:16:56 -04:00
|
|
|
|
goto vm_error_wrong_num_args;
|
|
|
|
|
|
NEXT;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (45, assert_nargs_ge, "assert-nargs-ge", 2, 0, 0)
|
2009-09-27 18:16:56 -04:00
|
|
|
|
{
|
|
|
|
|
|
scm_t_ptrdiff n;
|
|
|
|
|
|
n = FETCH () << 8;
|
|
|
|
|
|
n += FETCH ();
|
2009-09-27 20:25:39 -04:00
|
|
|
|
if (sp - (fp - 1) < n)
|
2009-09-27 18:16:56 -04:00
|
|
|
|
goto vm_error_wrong_num_args;
|
|
|
|
|
|
NEXT;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (46, bind_optionals, "bind-optionals", 2, -1, -1)
|
2009-10-17 17:23:09 +02:00
|
|
|
|
{
|
|
|
|
|
|
scm_t_ptrdiff n;
|
|
|
|
|
|
n = FETCH () << 8;
|
|
|
|
|
|
n += FETCH ();
|
|
|
|
|
|
while (sp - (fp - 1) < n)
|
|
|
|
|
|
PUSH (SCM_UNDEFINED);
|
|
|
|
|
|
NEXT;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (47, bind_optionals_shuffle, "bind-optionals/shuffle", 6, -1, -1)
|
2009-10-17 17:23:09 +02:00
|
|
|
|
{
|
|
|
|
|
|
SCM *walk;
|
|
|
|
|
|
scm_t_ptrdiff nreq, nreq_and_opt, ntotal;
|
|
|
|
|
|
nreq = FETCH () << 8;
|
|
|
|
|
|
nreq += FETCH ();
|
|
|
|
|
|
nreq_and_opt = FETCH () << 8;
|
|
|
|
|
|
nreq_and_opt += FETCH ();
|
|
|
|
|
|
ntotal = FETCH () << 8;
|
|
|
|
|
|
ntotal += FETCH ();
|
|
|
|
|
|
|
|
|
|
|
|
/* look in optionals for first keyword or last positional */
|
|
|
|
|
|
/* starting after the last required positional arg */
|
2009-10-23 15:44:22 +02:00
|
|
|
|
walk = fp + nreq;
|
2009-10-17 17:23:09 +02:00
|
|
|
|
while (/* while we have args */
|
|
|
|
|
|
walk <= sp
|
|
|
|
|
|
/* and we still have positionals to fill */
|
2009-10-23 15:44:22 +02:00
|
|
|
|
&& walk - fp < nreq_and_opt
|
2009-10-17 17:23:09 +02:00
|
|
|
|
/* and we haven't reached a keyword yet */
|
|
|
|
|
|
&& !scm_is_keyword (*walk))
|
|
|
|
|
|
/* bind this optional arg (by leaving it in place) */
|
|
|
|
|
|
walk++;
|
|
|
|
|
|
/* now shuffle up, from walk to ntotal */
|
|
|
|
|
|
{
|
2009-10-23 15:44:22 +02:00
|
|
|
|
scm_t_ptrdiff nshuf = sp - walk + 1, i;
|
2009-10-17 17:23:09 +02:00
|
|
|
|
sp = (fp - 1) + ntotal + nshuf;
|
|
|
|
|
|
CHECK_OVERFLOW ();
|
2009-10-23 15:44:22 +02:00
|
|
|
|
for (i = 0; i < nshuf; i++)
|
|
|
|
|
|
sp[-i] = walk[nshuf-i-1];
|
2009-10-17 17:23:09 +02:00
|
|
|
|
}
|
|
|
|
|
|
/* and fill optionals & keyword args with SCM_UNDEFINED */
|
2009-10-23 15:44:22 +02:00
|
|
|
|
while (walk <= (fp - 1) + ntotal)
|
2009-10-17 17:23:09 +02:00
|
|
|
|
*walk++ = SCM_UNDEFINED;
|
|
|
|
|
|
|
|
|
|
|
|
NEXT;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2009-11-16 22:32:54 +01:00
|
|
|
|
/* Flags that determine whether other keywords are allowed, and whether a
|
|
|
|
|
|
rest argument is expected. These values must match those used by the
|
|
|
|
|
|
glil->assembly compiler. */
|
|
|
|
|
|
#define F_ALLOW_OTHER_KEYS 1
|
|
|
|
|
|
#define F_REST 2
|
|
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (48, bind_kwargs, "bind-kwargs", 5, 0, 0)
|
2009-10-17 17:23:09 +02:00
|
|
|
|
{
|
|
|
|
|
|
scm_t_uint16 idx;
|
|
|
|
|
|
scm_t_ptrdiff nkw;
|
2009-11-16 22:32:54 +01:00
|
|
|
|
int kw_and_rest_flags;
|
2009-10-17 17:23:09 +02:00
|
|
|
|
SCM kw;
|
|
|
|
|
|
idx = FETCH () << 8;
|
|
|
|
|
|
idx += FETCH ();
|
2009-11-16 22:32:54 +01:00
|
|
|
|
/* XXX: We don't actually use NKW. */
|
2009-10-17 17:23:09 +02:00
|
|
|
|
nkw = FETCH () << 8;
|
|
|
|
|
|
nkw += FETCH ();
|
2009-11-16 22:32:54 +01:00
|
|
|
|
kw_and_rest_flags = FETCH ();
|
2009-10-17 17:23:09 +02:00
|
|
|
|
|
2009-11-16 22:32:54 +01:00
|
|
|
|
if (!(kw_and_rest_flags & F_REST)
|
|
|
|
|
|
&& ((sp - (fp - 1) - nkw) % 2))
|
2009-10-17 17:23:09 +02:00
|
|
|
|
goto vm_error_kwargs_length_not_even;
|
|
|
|
|
|
|
|
|
|
|
|
CHECK_OBJECT (idx);
|
|
|
|
|
|
kw = OBJECT_REF (idx);
|
2009-11-16 22:32:54 +01:00
|
|
|
|
|
|
|
|
|
|
/* Switch NKW to be a negative index below SP. */
|
|
|
|
|
|
for (nkw = -(sp - (fp - 1) - nkw) + 1; nkw < 0; nkw++)
|
2009-10-17 17:23:09 +02:00
|
|
|
|
{
|
|
|
|
|
|
SCM walk;
|
2009-11-16 22:32:54 +01:00
|
|
|
|
|
|
|
|
|
|
if (scm_is_keyword (sp[nkw]))
|
|
|
|
|
|
{
|
|
|
|
|
|
for (walk = kw; scm_is_pair (walk); walk = SCM_CDR (walk))
|
|
|
|
|
|
{
|
|
|
|
|
|
if (scm_is_eq (SCM_CAAR (walk), sp[nkw]))
|
|
|
|
|
|
{
|
|
|
|
|
|
SCM si = SCM_CDAR (walk);
|
|
|
|
|
|
LOCAL_SET (SCM_I_INUMP (si) ? SCM_I_INUM (si) : scm_to_long (si),
|
|
|
|
|
|
sp[nkw + 1]);
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
if (!(kw_and_rest_flags & F_ALLOW_OTHER_KEYS) && !scm_is_pair (walk))
|
|
|
|
|
|
goto vm_error_kwargs_unrecognized_keyword;
|
|
|
|
|
|
|
|
|
|
|
|
nkw++;
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (!(kw_and_rest_flags & F_REST))
|
|
|
|
|
|
goto vm_error_kwargs_invalid_keyword;
|
2009-10-17 17:23:09 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
NEXT;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2009-11-16 22:32:54 +01:00
|
|
|
|
#undef F_ALLOW_OTHER_KEYS
|
|
|
|
|
|
#undef F_REST
|
|
|
|
|
|
|
|
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (49, push_rest, "push-rest", 2, -1, -1)
|
2009-09-27 18:16:56 -04:00
|
|
|
|
{
|
|
|
|
|
|
scm_t_ptrdiff n;
|
2009-09-27 20:25:39 -04:00
|
|
|
|
SCM rest = SCM_EOL;
|
2009-09-27 18:16:56 -04:00
|
|
|
|
n = FETCH () << 8;
|
|
|
|
|
|
n += FETCH ();
|
2009-09-27 20:25:39 -04:00
|
|
|
|
while (sp - (fp - 1) > n)
|
2009-09-27 18:16:56 -04:00
|
|
|
|
/* No need to check for underflow. */
|
|
|
|
|
|
CONS (rest, *sp--, rest);
|
|
|
|
|
|
PUSH (rest);
|
|
|
|
|
|
NEXT;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (50, bind_rest, "bind-rest", 4, -1, -1)
|
more work towards compiling and interpreting keyword args
* libguile/_scm.h (SCM_OBJCODE_MINOR_VERSION): Bumparoo
* libguile/vm-i-system.c (push-rest, bind-rest): Logically there are
actually two rest binders -- one that pops, conses, and pushes, and
one that pops, conses, and local-sets. The latter is used on keyword
arguments, because the keyword arguments themselves have been shuffled
up on the stack. Renumber ops again.
* module/language/tree-il/compile-glil.scm (flatten): Attempt to handle
compilation of lambda-case with keyword arguments. Might need some
help.
* module/ice-9/psyntax.scm (build-lambda-case): An attempt to handle the
interpreted case correctly. This might need a couple iterations, but
at least it looks like the compile-glil code.
* module/ice-9/psyntax-pp.scm: Regenerated.
* module/language/glil.scm (<glil>): Rename "rest?" to "rest" in
<glil-opt-prelude> and <glil-kw-prelude>, as it is no longer a simple
boolean, but if true is an integer: the index of the local variable to
which the rest should be bound.
* module/language/glil/compile-assembly.scm (glil->assembly): Adapt to
"rest" vs "rest?". In the keyword case, use "bind-rest" instead of
"push-rest".
* test-suite/tests/tree-il.test: Update for opt-prelude change.
2009-10-19 22:13:08 +02:00
|
|
|
|
{
|
|
|
|
|
|
scm_t_ptrdiff n;
|
|
|
|
|
|
scm_t_uint32 i;
|
|
|
|
|
|
SCM rest = SCM_EOL;
|
|
|
|
|
|
n = FETCH () << 8;
|
|
|
|
|
|
n += FETCH ();
|
|
|
|
|
|
i = FETCH () << 8;
|
|
|
|
|
|
i += FETCH ();
|
|
|
|
|
|
while (sp - (fp - 1) > n)
|
|
|
|
|
|
/* No need to check for underflow. */
|
|
|
|
|
|
CONS (rest, *sp--, rest);
|
|
|
|
|
|
LOCAL_SET (i, rest);
|
|
|
|
|
|
NEXT;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (51, reserve_locals, "reserve-locals", 2, -1, -1)
|
2009-08-15 14:15:56 +02:00
|
|
|
|
{
|
2009-10-13 23:55:58 +02:00
|
|
|
|
SCM *old_sp;
|
2009-09-27 19:50:06 -04:00
|
|
|
|
scm_t_int32 n;
|
|
|
|
|
|
n = FETCH () << 8;
|
|
|
|
|
|
n += FETCH ();
|
2009-10-13 23:55:58 +02:00
|
|
|
|
old_sp = sp;
|
|
|
|
|
|
sp = (fp - 1) + n;
|
|
|
|
|
|
|
|
|
|
|
|
if (old_sp < sp)
|
|
|
|
|
|
{
|
|
|
|
|
|
CHECK_OVERFLOW ();
|
|
|
|
|
|
while (old_sp < sp)
|
|
|
|
|
|
*++old_sp = SCM_UNDEFINED;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
NULLSTACK (old_sp - sp);
|
|
|
|
|
|
|
2009-09-27 19:50:06 -04:00
|
|
|
|
NEXT;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (52, new_frame, "new-frame", 0, 0, 3)
|
2009-08-15 14:15:56 +02:00
|
|
|
|
{
|
runtime and debugging support for callee-parsed procedure args
* libguile/objcodes.h: Bump for metadata format change.
* libguile/frames.h: Rework so we don't frob the program's nargs, nlocs,
etc at runtime. Instead we don't really know what's a local var, an
argument, or an intermediate value. It's a little unfortunate, but
this will allow for case-lambda, and eventually for good polymorphic
generic dispatch; and the nlocs etc can be heuristically
reconstructed. Such a reconstruction would be better done at the
Scheme level, though.
(SCM_FRAME_STACK_ADDRESS): New macro, the pointer to the base of the
stack elements (not counting the program).
(SCM_FRAME_UPPER_ADDRESS): Repurpose to be the address of the last
element in the bookkeeping part of the stack -- i.e. to point to the
return address.
* libguile/vm-engine.h:
* libguile/vm-i-system.c: Adapt to removal of stack_base. Though we
still detect stack-smashing underflow, we don't do so as precisely as
we did before, because now we only detect overwriting of the frame
metadata.
* libguile/vm-engine.c (vm_engine): Remove the stack_base variable. It
is unnecessary, and difficult to keep track of in the face of
case-lambda. Also fix miscommented "ra" and "mvra" pushes. Push the
vp->ip as the first ra...
* libguile/vm-i-system.c (halt): ...because here we can restore the
vp->ip instead of setting ip to 0. Allows us to introspect ips all
down the stack, including in recursive VM invocations.
* libguile/frames.h:
* libguile/frames.c (scm_vm_frame_stack): Removed, because it's getting
more difficult to tell what's an argument and what's a temporary stack
element.
(scm_vm_frame_num_locals): New accessor.
(scm_vm_frame_instruction_pointer): New accessor.
(scm_vm_frame_arguments): Defer to an implementation in Scheme.
(scm_vm_frame_num_locals scm_vm_frame_local_ref)
(scm_vm_frame_local_set_x): Since we can get not-yet-active frames on
the stack now, with our current calling convention, we have to add a
heuristic here to jump over those frames -- because frames have
pointers in them, not Scheme values.
* libguile/programs.h:
* libguile/programs.c (scm_program_arity): Remove, in favor of..
(scm_program_arities): ...this, which a list of arities, in a new
format, occupying a slot in the metadata.
* module/language/assembly/decompile-bytecode.scm (decode-load-program):
Fix mv-call decompilation.
* module/system/vm/frame.scm (vm-frame-bindings, vm-frame-binding-ref)
(vm-frame-binding-set!): New functions, to access bindings by name in
a frame.
(vm-frame-arguments): Function now implemented in Scheme. Commented
fairly extensively.
* module/system/vm/program.scm (program-bindings-by-index)
(program-bindings-for-ip): New accessors, parsing the program bindings
metadata into something more useful.
(program-arities, program-arguments): In a case-lambda world, we have
to assume that programs can have multiple arities. But it's tough to
detect this algorithmically; instead we're going to require that the
program metadata include information about the arities, and the parts
of the program that that metadata applies to.
(program-lambda-list): New accessor.
(write-program): Show multiple arities.
* module/language/glil/compile-assembly.scm (glil->assembly): Add
"arities" to the state of the compiler, and add arities entries as
appropriate.
2009-09-27 19:25:58 -04:00
|
|
|
|
/* NB: if you change this, see frames.c:vm-frame-num-locals */
|
|
|
|
|
|
/* and frames.h, vm-engine.c, etc of course */
|
2011-03-15 23:33:32 +01:00
|
|
|
|
|
|
|
|
|
|
/* We don't initialize the dynamic link here because we don't actually
|
|
|
|
|
|
know that this frame will point to the current fp: it could be
|
|
|
|
|
|
placed elsewhere on the stack if captured in a partial
|
|
|
|
|
|
continuation, and invoked from some other context. */
|
|
|
|
|
|
PUSH (0); /* dynamic link */
|
|
|
|
|
|
PUSH (0); /* mvra */
|
|
|
|
|
|
PUSH (0); /* ra */
|
2009-08-15 14:15:56 +02:00
|
|
|
|
NEXT;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (53, call, "call", 1, -1, 1)
|
2000-08-22 15:54:19 +00:00
|
|
|
|
{
|
2001-04-01 05:03:41 +00:00
|
|
|
|
nargs = FETCH ();
|
2000-08-22 15:54:19 +00:00
|
|
|
|
|
|
|
|
|
|
vm_call:
|
smobs are applied with vm trampoline procedures
* libguile/smob.c: Instead of having special evaluator support for
applying smobs, we use the same strategy that gsubr uses, that smob
application should happen via a trampoline VM procedure, which uses a
special opcode (smob-apply). So statically allocate all of the desired
trampoline procedures here.
(scm_i_smob_apply_trampoline): Unfortunately there's no real place to
put the trampoline, so instead use a weak-key hash. It's nasty, but I
think the benefits of speeding up procedure calls in the general case
are worth it.
* libguile/smob.h (scm_smob_descriptor): Remove fields apply_0, apply_1,
apply_2, and apply_3; these were never public. Also remove the
gsubr_type field. Instead cache the trampoline objcode here.
(SCM_SMOB_APPLY_0, SCM_SMOB_APPLY_1, SCM_SMOB_APPLY_2,
SCM_SMOB_APPLY_3): Just go through scm_call_0, etc here.
* libguile/vm-i-system.c (call, tail-call, mv-call): Simplify. All
procedure calls are VM calls now.
(smob-call): New instruction, used in smob trampoline procedures.
* libguile/vm.c (apply_foreign): Remove. Yay!
* libguile/procprop.c (scm_i_procedure_arity): Refactor a bit for the
smob changes.
2010-01-09 14:12:47 +01:00
|
|
|
|
program = sp[-nargs];
|
2001-04-07 23:32:03 +00:00
|
|
|
|
|
2009-12-11 11:15:12 +01:00
|
|
|
|
VM_HANDLE_INTERRUPTS;
|
2009-02-02 23:00:36 +01:00
|
|
|
|
|
smobs are applied with vm trampoline procedures
* libguile/smob.c: Instead of having special evaluator support for
applying smobs, we use the same strategy that gsubr uses, that smob
application should happen via a trampoline VM procedure, which uses a
special opcode (smob-apply). So statically allocate all of the desired
trampoline procedures here.
(scm_i_smob_apply_trampoline): Unfortunately there's no real place to
put the trampoline, so instead use a weak-key hash. It's nasty, but I
think the benefits of speeding up procedure calls in the general case
are worth it.
* libguile/smob.h (scm_smob_descriptor): Remove fields apply_0, apply_1,
apply_2, and apply_3; these were never public. Also remove the
gsubr_type field. Instead cache the trampoline objcode here.
(SCM_SMOB_APPLY_0, SCM_SMOB_APPLY_1, SCM_SMOB_APPLY_2,
SCM_SMOB_APPLY_3): Just go through scm_call_0, etc here.
* libguile/vm-i-system.c (call, tail-call, mv-call): Simplify. All
procedure calls are VM calls now.
(smob-call): New instruction, used in smob trampoline procedures.
* libguile/vm.c (apply_foreign): Remove. Yay!
* libguile/procprop.c (scm_i_procedure_arity): Refactor a bit for the
smob changes.
2010-01-09 14:12:47 +01:00
|
|
|
|
if (SCM_UNLIKELY (!SCM_PROGRAM_P (program)))
|
2000-08-22 15:54:19 +00:00
|
|
|
|
{
|
smobs are applied with vm trampoline procedures
* libguile/smob.c: Instead of having special evaluator support for
applying smobs, we use the same strategy that gsubr uses, that smob
application should happen via a trampoline VM procedure, which uses a
special opcode (smob-apply). So statically allocate all of the desired
trampoline procedures here.
(scm_i_smob_apply_trampoline): Unfortunately there's no real place to
put the trampoline, so instead use a weak-key hash. It's nasty, but I
think the benefits of speeding up procedure calls in the general case
are worth it.
* libguile/smob.h (scm_smob_descriptor): Remove fields apply_0, apply_1,
apply_2, and apply_3; these were never public. Also remove the
gsubr_type field. Instead cache the trampoline objcode here.
(SCM_SMOB_APPLY_0, SCM_SMOB_APPLY_1, SCM_SMOB_APPLY_2,
SCM_SMOB_APPLY_3): Just go through scm_call_0, etc here.
* libguile/vm-i-system.c (call, tail-call, mv-call): Simplify. All
procedure calls are VM calls now.
(smob-call): New instruction, used in smob trampoline procedures.
* libguile/vm.c (apply_foreign): Remove. Yay!
* libguile/procprop.c (scm_i_procedure_arity): Refactor a bit for the
smob changes.
2010-01-09 14:12:47 +01:00
|
|
|
|
if (SCM_STRUCTP (program) && SCM_STRUCT_APPLICABLE_P (program))
|
2008-11-01 18:19:19 +01:00
|
|
|
|
{
|
smobs are applied with vm trampoline procedures
* libguile/smob.c: Instead of having special evaluator support for
applying smobs, we use the same strategy that gsubr uses, that smob
application should happen via a trampoline VM procedure, which uses a
special opcode (smob-apply). So statically allocate all of the desired
trampoline procedures here.
(scm_i_smob_apply_trampoline): Unfortunately there's no real place to
put the trampoline, so instead use a weak-key hash. It's nasty, but I
think the benefits of speeding up procedure calls in the general case
are worth it.
* libguile/smob.h (scm_smob_descriptor): Remove fields apply_0, apply_1,
apply_2, and apply_3; these were never public. Also remove the
gsubr_type field. Instead cache the trampoline objcode here.
(SCM_SMOB_APPLY_0, SCM_SMOB_APPLY_1, SCM_SMOB_APPLY_2,
SCM_SMOB_APPLY_3): Just go through scm_call_0, etc here.
* libguile/vm-i-system.c (call, tail-call, mv-call): Simplify. All
procedure calls are VM calls now.
(smob-call): New instruction, used in smob trampoline procedures.
* libguile/vm.c (apply_foreign): Remove. Yay!
* libguile/procprop.c (scm_i_procedure_arity): Refactor a bit for the
smob changes.
2010-01-09 14:12:47 +01:00
|
|
|
|
sp[-nargs] = SCM_STRUCT_PROCEDURE (program);
|
|
|
|
|
|
goto vm_call;
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (SCM_NIMP (program) && SCM_TYP7 (program) == scm_tc7_smob
|
|
|
|
|
|
&& SCM_SMOB_APPLICABLE_P (program))
|
|
|
|
|
|
{
|
|
|
|
|
|
SYNC_REGISTER ();
|
|
|
|
|
|
sp[-nargs] = scm_i_smob_apply_trampoline (program);
|
|
|
|
|
|
goto vm_call;
|
2008-11-01 18:19:19 +01:00
|
|
|
|
}
|
2009-12-01 21:59:42 +01:00
|
|
|
|
else
|
smobs are applied with vm trampoline procedures
* libguile/smob.c: Instead of having special evaluator support for
applying smobs, we use the same strategy that gsubr uses, that smob
application should happen via a trampoline VM procedure, which uses a
special opcode (smob-apply). So statically allocate all of the desired
trampoline procedures here.
(scm_i_smob_apply_trampoline): Unfortunately there's no real place to
put the trampoline, so instead use a weak-key hash. It's nasty, but I
think the benefits of speeding up procedure calls in the general case
are worth it.
* libguile/smob.h (scm_smob_descriptor): Remove fields apply_0, apply_1,
apply_2, and apply_3; these were never public. Also remove the
gsubr_type field. Instead cache the trampoline objcode here.
(SCM_SMOB_APPLY_0, SCM_SMOB_APPLY_1, SCM_SMOB_APPLY_2,
SCM_SMOB_APPLY_3): Just go through scm_call_0, etc here.
* libguile/vm-i-system.c (call, tail-call, mv-call): Simplify. All
procedure calls are VM calls now.
(smob-call): New instruction, used in smob trampoline procedures.
* libguile/vm.c (apply_foreign): Remove. Yay!
* libguile/procprop.c (scm_i_procedure_arity): Refactor a bit for the
smob changes.
2010-01-09 14:12:47 +01:00
|
|
|
|
goto vm_error_wrong_type_apply;
|
2000-08-22 15:54:19 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
smobs are applied with vm trampoline procedures
* libguile/smob.c: Instead of having special evaluator support for
applying smobs, we use the same strategy that gsubr uses, that smob
application should happen via a trampoline VM procedure, which uses a
special opcode (smob-apply). So statically allocate all of the desired
trampoline procedures here.
(scm_i_smob_apply_trampoline): Unfortunately there's no real place to
put the trampoline, so instead use a weak-key hash. It's nasty, but I
think the benefits of speeding up procedure calls in the general case
are worth it.
* libguile/smob.h (scm_smob_descriptor): Remove fields apply_0, apply_1,
apply_2, and apply_3; these were never public. Also remove the
gsubr_type field. Instead cache the trampoline objcode here.
(SCM_SMOB_APPLY_0, SCM_SMOB_APPLY_1, SCM_SMOB_APPLY_2,
SCM_SMOB_APPLY_3): Just go through scm_call_0, etc here.
* libguile/vm-i-system.c (call, tail-call, mv-call): Simplify. All
procedure calls are VM calls now.
(smob-call): New instruction, used in smob trampoline procedures.
* libguile/vm.c (apply_foreign): Remove. Yay!
* libguile/procprop.c (scm_i_procedure_arity): Refactor a bit for the
smob changes.
2010-01-09 14:12:47 +01:00
|
|
|
|
CACHE_PROGRAM ();
|
2011-03-15 23:33:32 +01:00
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
SCM *old_fp = fp;
|
|
|
|
|
|
|
|
|
|
|
|
fp = sp - nargs + 1;
|
|
|
|
|
|
|
|
|
|
|
|
ASSERT (SCM_FRAME_DYNAMIC_LINK (fp) == 0);
|
|
|
|
|
|
ASSERT (SCM_FRAME_RETURN_ADDRESS (fp) == 0);
|
|
|
|
|
|
ASSERT (SCM_FRAME_MV_RETURN_ADDRESS (fp) == 0);
|
|
|
|
|
|
SCM_FRAME_SET_DYNAMIC_LINK (fp, old_fp);
|
|
|
|
|
|
SCM_FRAME_SET_RETURN_ADDRESS (fp, ip);
|
|
|
|
|
|
SCM_FRAME_SET_MV_RETURN_ADDRESS (fp, 0);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
smobs are applied with vm trampoline procedures
* libguile/smob.c: Instead of having special evaluator support for
applying smobs, we use the same strategy that gsubr uses, that smob
application should happen via a trampoline VM procedure, which uses a
special opcode (smob-apply). So statically allocate all of the desired
trampoline procedures here.
(scm_i_smob_apply_trampoline): Unfortunately there's no real place to
put the trampoline, so instead use a weak-key hash. It's nasty, but I
think the benefits of speeding up procedure calls in the general case
are worth it.
* libguile/smob.h (scm_smob_descriptor): Remove fields apply_0, apply_1,
apply_2, and apply_3; these were never public. Also remove the
gsubr_type field. Instead cache the trampoline objcode here.
(SCM_SMOB_APPLY_0, SCM_SMOB_APPLY_1, SCM_SMOB_APPLY_2,
SCM_SMOB_APPLY_3): Just go through scm_call_0, etc here.
* libguile/vm-i-system.c (call, tail-call, mv-call): Simplify. All
procedure calls are VM calls now.
(smob-call): New instruction, used in smob trampoline procedures.
* libguile/vm.c (apply_foreign): Remove. Yay!
* libguile/procprop.c (scm_i_procedure_arity): Refactor a bit for the
smob changes.
2010-01-09 14:12:47 +01:00
|
|
|
|
ip = SCM_C_OBJCODE_BASE (bp);
|
2010-09-16 12:14:55 +02:00
|
|
|
|
PUSH_CONTINUATION_HOOK ();
|
smobs are applied with vm trampoline procedures
* libguile/smob.c: Instead of having special evaluator support for
applying smobs, we use the same strategy that gsubr uses, that smob
application should happen via a trampoline VM procedure, which uses a
special opcode (smob-apply). So statically allocate all of the desired
trampoline procedures here.
(scm_i_smob_apply_trampoline): Unfortunately there's no real place to
put the trampoline, so instead use a weak-key hash. It's nasty, but I
think the benefits of speeding up procedure calls in the general case
are worth it.
* libguile/smob.h (scm_smob_descriptor): Remove fields apply_0, apply_1,
apply_2, and apply_3; these were never public. Also remove the
gsubr_type field. Instead cache the trampoline objcode here.
(SCM_SMOB_APPLY_0, SCM_SMOB_APPLY_1, SCM_SMOB_APPLY_2,
SCM_SMOB_APPLY_3): Just go through scm_call_0, etc here.
* libguile/vm-i-system.c (call, tail-call, mv-call): Simplify. All
procedure calls are VM calls now.
(smob-call): New instruction, used in smob trampoline procedures.
* libguile/vm.c (apply_foreign): Remove. Yay!
* libguile/procprop.c (scm_i_procedure_arity): Refactor a bit for the
smob changes.
2010-01-09 14:12:47 +01:00
|
|
|
|
APPLY_HOOK ();
|
|
|
|
|
|
NEXT;
|
2000-08-22 15:54:19 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (54, tail_call, "tail-call", 1, -1, 1)
|
2000-08-22 15:54:19 +00:00
|
|
|
|
{
|
2001-04-01 05:03:41 +00:00
|
|
|
|
nargs = FETCH ();
|
smobs are applied with vm trampoline procedures
* libguile/smob.c: Instead of having special evaluator support for
applying smobs, we use the same strategy that gsubr uses, that smob
application should happen via a trampoline VM procedure, which uses a
special opcode (smob-apply). So statically allocate all of the desired
trampoline procedures here.
(scm_i_smob_apply_trampoline): Unfortunately there's no real place to
put the trampoline, so instead use a weak-key hash. It's nasty, but I
think the benefits of speeding up procedure calls in the general case
are worth it.
* libguile/smob.h (scm_smob_descriptor): Remove fields apply_0, apply_1,
apply_2, and apply_3; these were never public. Also remove the
gsubr_type field. Instead cache the trampoline objcode here.
(SCM_SMOB_APPLY_0, SCM_SMOB_APPLY_1, SCM_SMOB_APPLY_2,
SCM_SMOB_APPLY_3): Just go through scm_call_0, etc here.
* libguile/vm-i-system.c (call, tail-call, mv-call): Simplify. All
procedure calls are VM calls now.
(smob-call): New instruction, used in smob trampoline procedures.
* libguile/vm.c (apply_foreign): Remove. Yay!
* libguile/procprop.c (scm_i_procedure_arity): Refactor a bit for the
smob changes.
2010-01-09 14:12:47 +01:00
|
|
|
|
|
2010-01-03 14:49:40 +01:00
|
|
|
|
vm_tail_call:
|
smobs are applied with vm trampoline procedures
* libguile/smob.c: Instead of having special evaluator support for
applying smobs, we use the same strategy that gsubr uses, that smob
application should happen via a trampoline VM procedure, which uses a
special opcode (smob-apply). So statically allocate all of the desired
trampoline procedures here.
(scm_i_smob_apply_trampoline): Unfortunately there's no real place to
put the trampoline, so instead use a weak-key hash. It's nasty, but I
think the benefits of speeding up procedure calls in the general case
are worth it.
* libguile/smob.h (scm_smob_descriptor): Remove fields apply_0, apply_1,
apply_2, and apply_3; these were never public. Also remove the
gsubr_type field. Instead cache the trampoline objcode here.
(SCM_SMOB_APPLY_0, SCM_SMOB_APPLY_1, SCM_SMOB_APPLY_2,
SCM_SMOB_APPLY_3): Just go through scm_call_0, etc here.
* libguile/vm-i-system.c (call, tail-call, mv-call): Simplify. All
procedure calls are VM calls now.
(smob-call): New instruction, used in smob trampoline procedures.
* libguile/vm.c (apply_foreign): Remove. Yay!
* libguile/procprop.c (scm_i_procedure_arity): Refactor a bit for the
smob changes.
2010-01-09 14:12:47 +01:00
|
|
|
|
program = sp[-nargs];
|
2001-04-01 05:03:41 +00:00
|
|
|
|
|
2009-12-11 11:15:12 +01:00
|
|
|
|
VM_HANDLE_INTERRUPTS;
|
2000-08-22 15:54:19 +00:00
|
|
|
|
|
smobs are applied with vm trampoline procedures
* libguile/smob.c: Instead of having special evaluator support for
applying smobs, we use the same strategy that gsubr uses, that smob
application should happen via a trampoline VM procedure, which uses a
special opcode (smob-apply). So statically allocate all of the desired
trampoline procedures here.
(scm_i_smob_apply_trampoline): Unfortunately there's no real place to
put the trampoline, so instead use a weak-key hash. It's nasty, but I
think the benefits of speeding up procedure calls in the general case
are worth it.
* libguile/smob.h (scm_smob_descriptor): Remove fields apply_0, apply_1,
apply_2, and apply_3; these were never public. Also remove the
gsubr_type field. Instead cache the trampoline objcode here.
(SCM_SMOB_APPLY_0, SCM_SMOB_APPLY_1, SCM_SMOB_APPLY_2,
SCM_SMOB_APPLY_3): Just go through scm_call_0, etc here.
* libguile/vm-i-system.c (call, tail-call, mv-call): Simplify. All
procedure calls are VM calls now.
(smob-call): New instruction, used in smob trampoline procedures.
* libguile/vm.c (apply_foreign): Remove. Yay!
* libguile/procprop.c (scm_i_procedure_arity): Refactor a bit for the
smob changes.
2010-01-09 14:12:47 +01:00
|
|
|
|
if (SCM_UNLIKELY (!SCM_PROGRAM_P (program)))
|
|
|
|
|
|
{
|
|
|
|
|
|
if (SCM_STRUCTP (program) && SCM_STRUCT_APPLICABLE_P (program))
|
|
|
|
|
|
{
|
|
|
|
|
|
sp[-nargs] = SCM_STRUCT_PROCEDURE (program);
|
|
|
|
|
|
goto vm_tail_call;
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (SCM_NIMP (program) && SCM_TYP7 (program) == scm_tc7_smob
|
|
|
|
|
|
&& SCM_SMOB_APPLICABLE_P (program))
|
|
|
|
|
|
{
|
|
|
|
|
|
SYNC_REGISTER ();
|
|
|
|
|
|
sp[-nargs] = scm_i_smob_apply_trampoline (program);
|
|
|
|
|
|
goto vm_tail_call;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
goto vm_error_wrong_type_apply;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
2001-04-01 05:03:41 +00:00
|
|
|
|
{
|
2008-09-13 15:41:43 +02:00
|
|
|
|
int i;
|
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
|
|
|
|
#ifdef VM_ENABLE_STACK_NULLING
|
2009-09-27 20:25:39 -04:00
|
|
|
|
SCM *old_sp = sp;
|
|
|
|
|
|
CHECK_STACK_LEAK ();
|
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
|
|
|
|
#endif
|
2008-09-13 15:41:43 +02:00
|
|
|
|
|
|
|
|
|
|
/* switch programs */
|
|
|
|
|
|
CACHE_PROGRAM ();
|
2009-09-27 20:25:39 -04:00
|
|
|
|
/* shuffle down the program and the arguments */
|
|
|
|
|
|
for (i = -1, sp = sp - nargs + 1; i < nargs; i++)
|
|
|
|
|
|
SCM_FRAME_STACK_ADDRESS (fp)[i] = sp[i];
|
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
|
|
|
|
|
2009-08-15 14:13:08 +02:00
|
|
|
|
sp = fp + i - 1;
|
2008-09-13 15:41:43 +02:00
|
|
|
|
|
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
|
|
|
|
NULLSTACK (old_sp - sp);
|
|
|
|
|
|
|
2009-12-14 23:11:47 +01:00
|
|
|
|
ip = SCM_C_OBJCODE_BASE (bp);
|
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
|
|
|
|
|
2008-09-13 15:41:43 +02:00
|
|
|
|
APPLY_HOOK ();
|
|
|
|
|
|
NEXT;
|
2001-04-01 05:03:41 +00:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (55, subr_call, "subr-call", 1, -1, -1)
|
2010-01-05 16:51:58 +01:00
|
|
|
|
{
|
Use "pointer" instead of "foreign" when dealing with wrapped pointers.
* libguile/foreign.h (scm_t_foreign_finalizer): Rename to...
(scm_t_pointer_finalizer): ... this.
(SCM_FOREIGN_P): Rename to...
(SCM_POINTER_P): this.
(SCM_VALIDATE_FOREIGN): Rename to...
(SCM_VALIDATE_POINTER): ... this.
(SCM_FOREIGN_HAS_FINALIZER): Rename to...
(SCM_POINTER_HAS_FINALIZER): ... this.
(scm_take_foreign_pointer): Rename to...
(scm_from_pointer): ... this.
(scm_foreign_address): Rename to...
(scm_pointer_address): ... this.
(scm_foreign_to_bytevector): Rename to...
(scm_pointer_to_bytevector): ... this.
(scm_foreign_set_finalizer_x): Rename to...
(scm_set_pointer_finalizer_x): ... this.
(scm_bytevector_to_foreign): Rename to...
(scm_bytevector_to_pointer): ... this.
(scm_i_foreign_print): Rename to...
(scm_i_pointer_print): ... this.
* libguile/foreign.c: Update accordingly.
* libguile/tags.h (scm_tc7_foreign): Rename to...
(scm_tc7_pointer): ... this.
* libguile/foreign.c, libguile/deprecated.c, libguile/dynl.c,
libguile/evalext.c, libguile/gc.c, libguile/goops.c, libguile/gsubr.c,
libguile/gsubr.h, libguile/print.c, libguile/snarf.h,
libguile/vm-i-system.c, module/system/foreign.scm,
test-suite/standalone/test-ffi, test-suite/tests/foreign.test: Update
accordingly.
2010-07-27 14:54:53 +02:00
|
|
|
|
SCM pointer, ret;
|
2010-01-05 16:51:58 +01:00
|
|
|
|
SCM (*subr)();
|
Use "pointer" instead of "foreign" when dealing with wrapped pointers.
* libguile/foreign.h (scm_t_foreign_finalizer): Rename to...
(scm_t_pointer_finalizer): ... this.
(SCM_FOREIGN_P): Rename to...
(SCM_POINTER_P): this.
(SCM_VALIDATE_FOREIGN): Rename to...
(SCM_VALIDATE_POINTER): ... this.
(SCM_FOREIGN_HAS_FINALIZER): Rename to...
(SCM_POINTER_HAS_FINALIZER): ... this.
(scm_take_foreign_pointer): Rename to...
(scm_from_pointer): ... this.
(scm_foreign_address): Rename to...
(scm_pointer_address): ... this.
(scm_foreign_to_bytevector): Rename to...
(scm_pointer_to_bytevector): ... this.
(scm_foreign_set_finalizer_x): Rename to...
(scm_set_pointer_finalizer_x): ... this.
(scm_bytevector_to_foreign): Rename to...
(scm_bytevector_to_pointer): ... this.
(scm_i_foreign_print): Rename to...
(scm_i_pointer_print): ... this.
* libguile/foreign.c: Update accordingly.
* libguile/tags.h (scm_tc7_foreign): Rename to...
(scm_tc7_pointer): ... this.
* libguile/foreign.c, libguile/deprecated.c, libguile/dynl.c,
libguile/evalext.c, libguile/gc.c, libguile/goops.c, libguile/gsubr.c,
libguile/gsubr.h, libguile/print.c, libguile/snarf.h,
libguile/vm-i-system.c, module/system/foreign.scm,
test-suite/standalone/test-ffi, test-suite/tests/foreign.test: Update
accordingly.
2010-07-27 14:54:53 +02:00
|
|
|
|
|
2010-01-05 16:51:58 +01:00
|
|
|
|
nargs = FETCH ();
|
Use "pointer" instead of "foreign" when dealing with wrapped pointers.
* libguile/foreign.h (scm_t_foreign_finalizer): Rename to...
(scm_t_pointer_finalizer): ... this.
(SCM_FOREIGN_P): Rename to...
(SCM_POINTER_P): this.
(SCM_VALIDATE_FOREIGN): Rename to...
(SCM_VALIDATE_POINTER): ... this.
(SCM_FOREIGN_HAS_FINALIZER): Rename to...
(SCM_POINTER_HAS_FINALIZER): ... this.
(scm_take_foreign_pointer): Rename to...
(scm_from_pointer): ... this.
(scm_foreign_address): Rename to...
(scm_pointer_address): ... this.
(scm_foreign_to_bytevector): Rename to...
(scm_pointer_to_bytevector): ... this.
(scm_foreign_set_finalizer_x): Rename to...
(scm_set_pointer_finalizer_x): ... this.
(scm_bytevector_to_foreign): Rename to...
(scm_bytevector_to_pointer): ... this.
(scm_i_foreign_print): Rename to...
(scm_i_pointer_print): ... this.
* libguile/foreign.c: Update accordingly.
* libguile/tags.h (scm_tc7_foreign): Rename to...
(scm_tc7_pointer): ... this.
* libguile/foreign.c, libguile/deprecated.c, libguile/dynl.c,
libguile/evalext.c, libguile/gc.c, libguile/goops.c, libguile/gsubr.c,
libguile/gsubr.h, libguile/print.c, libguile/snarf.h,
libguile/vm-i-system.c, module/system/foreign.scm,
test-suite/standalone/test-ffi, test-suite/tests/foreign.test: Update
accordingly.
2010-07-27 14:54:53 +02:00
|
|
|
|
POP (pointer);
|
2010-01-05 16:51:58 +01:00
|
|
|
|
|
Use "pointer" instead of "foreign" when dealing with wrapped pointers.
* libguile/foreign.h (scm_t_foreign_finalizer): Rename to...
(scm_t_pointer_finalizer): ... this.
(SCM_FOREIGN_P): Rename to...
(SCM_POINTER_P): this.
(SCM_VALIDATE_FOREIGN): Rename to...
(SCM_VALIDATE_POINTER): ... this.
(SCM_FOREIGN_HAS_FINALIZER): Rename to...
(SCM_POINTER_HAS_FINALIZER): ... this.
(scm_take_foreign_pointer): Rename to...
(scm_from_pointer): ... this.
(scm_foreign_address): Rename to...
(scm_pointer_address): ... this.
(scm_foreign_to_bytevector): Rename to...
(scm_pointer_to_bytevector): ... this.
(scm_foreign_set_finalizer_x): Rename to...
(scm_set_pointer_finalizer_x): ... this.
(scm_bytevector_to_foreign): Rename to...
(scm_bytevector_to_pointer): ... this.
(scm_i_foreign_print): Rename to...
(scm_i_pointer_print): ... this.
* libguile/foreign.c: Update accordingly.
* libguile/tags.h (scm_tc7_foreign): Rename to...
(scm_tc7_pointer): ... this.
* libguile/foreign.c, libguile/deprecated.c, libguile/dynl.c,
libguile/evalext.c, libguile/gc.c, libguile/goops.c, libguile/gsubr.c,
libguile/gsubr.h, libguile/print.c, libguile/snarf.h,
libguile/vm-i-system.c, module/system/foreign.scm,
test-suite/standalone/test-ffi, test-suite/tests/foreign.test: Update
accordingly.
2010-07-27 14:54:53 +02:00
|
|
|
|
subr = SCM_POINTER_VALUE (pointer);
|
2010-01-05 16:51:58 +01:00
|
|
|
|
|
|
|
|
|
|
VM_HANDLE_INTERRUPTS;
|
|
|
|
|
|
SYNC_REGISTER ();
|
|
|
|
|
|
|
|
|
|
|
|
switch (nargs)
|
|
|
|
|
|
{
|
|
|
|
|
|
case 0:
|
|
|
|
|
|
ret = subr ();
|
|
|
|
|
|
break;
|
|
|
|
|
|
case 1:
|
|
|
|
|
|
ret = subr (sp[0]);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case 2:
|
|
|
|
|
|
ret = subr (sp[-1], sp[0]);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case 3:
|
|
|
|
|
|
ret = subr (sp[-2], sp[-1], sp[0]);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case 4:
|
|
|
|
|
|
ret = subr (sp[-3], sp[-2], sp[-1], sp[0]);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case 5:
|
|
|
|
|
|
ret = subr (sp[-4], sp[-3], sp[-2], sp[-1], sp[0]);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case 6:
|
|
|
|
|
|
ret = subr (sp[-5], sp[-4], sp[-3], sp[-2], sp[-1], sp[0]);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case 7:
|
|
|
|
|
|
ret = subr (sp[-6], sp[-5], sp[-4], sp[-3], sp[-2], sp[-1], sp[0]);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case 8:
|
|
|
|
|
|
ret = subr (sp[-7], sp[-6], sp[-5], sp[-4], sp[-3], sp[-2], sp[-1], sp[0]);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case 9:
|
|
|
|
|
|
ret = subr (sp[-8], sp[-7], sp[-6], sp[-5], sp[-4], sp[-3], sp[-2], sp[-1], sp[0]);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case 10:
|
|
|
|
|
|
ret = subr (sp[-9], sp[-8], sp[-7], sp[-6], sp[-5], sp[-4], sp[-3], sp[-2], sp[-1], sp[0]);
|
|
|
|
|
|
break;
|
|
|
|
|
|
default:
|
|
|
|
|
|
abort ();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
NULLSTACK_FOR_NONLOCAL_EXIT ();
|
|
|
|
|
|
|
|
|
|
|
|
if (SCM_UNLIKELY (SCM_VALUESP (ret)))
|
|
|
|
|
|
{
|
|
|
|
|
|
/* multiple values returned to continuation */
|
|
|
|
|
|
ret = scm_struct_ref (ret, SCM_INUM0);
|
|
|
|
|
|
nvalues = scm_ilength (ret);
|
|
|
|
|
|
PUSH_LIST (ret, scm_is_null);
|
|
|
|
|
|
goto vm_return_values;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
PUSH (ret);
|
|
|
|
|
|
goto vm_return;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (56, smob_call, "smob-call", 1, -1, -1)
|
smobs are applied with vm trampoline procedures
* libguile/smob.c: Instead of having special evaluator support for
applying smobs, we use the same strategy that gsubr uses, that smob
application should happen via a trampoline VM procedure, which uses a
special opcode (smob-apply). So statically allocate all of the desired
trampoline procedures here.
(scm_i_smob_apply_trampoline): Unfortunately there's no real place to
put the trampoline, so instead use a weak-key hash. It's nasty, but I
think the benefits of speeding up procedure calls in the general case
are worth it.
* libguile/smob.h (scm_smob_descriptor): Remove fields apply_0, apply_1,
apply_2, and apply_3; these were never public. Also remove the
gsubr_type field. Instead cache the trampoline objcode here.
(SCM_SMOB_APPLY_0, SCM_SMOB_APPLY_1, SCM_SMOB_APPLY_2,
SCM_SMOB_APPLY_3): Just go through scm_call_0, etc here.
* libguile/vm-i-system.c (call, tail-call, mv-call): Simplify. All
procedure calls are VM calls now.
(smob-call): New instruction, used in smob trampoline procedures.
* libguile/vm.c (apply_foreign): Remove. Yay!
* libguile/procprop.c (scm_i_procedure_arity): Refactor a bit for the
smob changes.
2010-01-09 14:12:47 +01:00
|
|
|
|
{
|
|
|
|
|
|
SCM smob, ret;
|
|
|
|
|
|
SCM (*subr)();
|
|
|
|
|
|
nargs = FETCH ();
|
|
|
|
|
|
POP (smob);
|
|
|
|
|
|
|
|
|
|
|
|
subr = SCM_SMOB_DESCRIPTOR (smob).apply;
|
|
|
|
|
|
|
|
|
|
|
|
VM_HANDLE_INTERRUPTS;
|
|
|
|
|
|
SYNC_REGISTER ();
|
|
|
|
|
|
|
|
|
|
|
|
switch (nargs)
|
|
|
|
|
|
{
|
|
|
|
|
|
case 0:
|
|
|
|
|
|
ret = subr (smob);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case 1:
|
|
|
|
|
|
ret = subr (smob, sp[0]);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case 2:
|
|
|
|
|
|
ret = subr (smob, sp[-1], sp[0]);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case 3:
|
|
|
|
|
|
ret = subr (smob, sp[-2], sp[-1], sp[0]);
|
|
|
|
|
|
break;
|
|
|
|
|
|
default:
|
|
|
|
|
|
abort ();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
NULLSTACK_FOR_NONLOCAL_EXIT ();
|
|
|
|
|
|
|
|
|
|
|
|
if (SCM_UNLIKELY (SCM_VALUESP (ret)))
|
|
|
|
|
|
{
|
|
|
|
|
|
/* multiple values returned to continuation */
|
|
|
|
|
|
ret = scm_struct_ref (ret, SCM_INUM0);
|
|
|
|
|
|
nvalues = scm_ilength (ret);
|
|
|
|
|
|
PUSH_LIST (ret, scm_is_null);
|
|
|
|
|
|
goto vm_return_values;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
PUSH (ret);
|
|
|
|
|
|
goto vm_return;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (57, foreign_call, "foreign-call", 1, -1, -1)
|
2010-01-24 18:59:19 -06:00
|
|
|
|
{
|
|
|
|
|
|
SCM foreign, ret;
|
|
|
|
|
|
nargs = FETCH ();
|
|
|
|
|
|
POP (foreign);
|
|
|
|
|
|
|
|
|
|
|
|
VM_HANDLE_INTERRUPTS;
|
|
|
|
|
|
SYNC_REGISTER ();
|
|
|
|
|
|
|
2010-01-25 18:04:45 +01:00
|
|
|
|
ret = scm_i_foreign_call (foreign, sp - nargs + 1);
|
2010-01-24 18:59:19 -06:00
|
|
|
|
|
|
|
|
|
|
NULLSTACK_FOR_NONLOCAL_EXIT ();
|
|
|
|
|
|
|
|
|
|
|
|
if (SCM_UNLIKELY (SCM_VALUESP (ret)))
|
|
|
|
|
|
{
|
|
|
|
|
|
/* multiple values returned to continuation */
|
|
|
|
|
|
ret = scm_struct_ref (ret, SCM_INUM0);
|
|
|
|
|
|
nvalues = scm_ilength (ret);
|
|
|
|
|
|
PUSH_LIST (ret, scm_is_null);
|
|
|
|
|
|
goto vm_return_values;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
PUSH (ret);
|
|
|
|
|
|
goto vm_return;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (58, continuation_call, "continuation-call", 0, -1, 0)
|
continuations are vm procedures
* libguile/vm-i-system.c (continuation-call): New op, like subr-call or
foreign-call, but for continuations.
* libguile/continuations.h: Add scm_i_continuation_call internal
declaration.
(SCM_CONTINUATIONP): Reimplement in terms of
SCM_PROGRAM_IS_CONTINUATION.
(scm_tc16_continuation, SCM_CONTREGS, SCM_CONTINUATION_LENGTH)
(SCM_SET_CONTINUATION_LENGTH, SCM_JMPBUF, SCM_DYNENV, SCM_THROW_VALUE)
(SCM_CONTINUATION_ROOT, SCM_DFRAME): Remove these from the exposed
API.
(scm_i_continuation_to_frame): New internal declaration.
* libguile/continuations.c
* libguile/continuations.c: Add trickery like in foreign.c, smob.c, and
gsubr.c, so that we can make procedural trampolines for continuations.
(scm_i_continuation_to_frame): New internal function, from stacks.c.
* libguile/programs.h (SCM_F_PROGRAM_IS_CONTINUATION)
(SCM_PROGRAM_IS_CONTINUATION): Add a flag for programs that are
continuations. Probably should add flags for the other trampoline
types too.
* libguile/programs.c (scm_i_program_print): Print continuations as
before.
* libguile/stacks.c (scm_stack_id, scm_make_stack): Use
scm_i_continuation_to_frame in the continuation case.
2010-02-06 17:00:03 +01:00
|
|
|
|
{
|
|
|
|
|
|
SCM contregs;
|
|
|
|
|
|
POP (contregs);
|
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
|
|
|
|
|
2010-03-16 15:55:24 +01:00
|
|
|
|
SYNC_ALL ();
|
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
|
|
|
|
scm_i_check_continuation (contregs);
|
|
|
|
|
|
vm_return_to_continuation (scm_i_contregs_vm (contregs),
|
|
|
|
|
|
scm_i_contregs_vm_cont (contregs),
|
|
|
|
|
|
sp - (fp - 1), fp);
|
|
|
|
|
|
scm_i_reinstate_continuation (contregs);
|
|
|
|
|
|
|
continuations are vm procedures
* libguile/vm-i-system.c (continuation-call): New op, like subr-call or
foreign-call, but for continuations.
* libguile/continuations.h: Add scm_i_continuation_call internal
declaration.
(SCM_CONTINUATIONP): Reimplement in terms of
SCM_PROGRAM_IS_CONTINUATION.
(scm_tc16_continuation, SCM_CONTREGS, SCM_CONTINUATION_LENGTH)
(SCM_SET_CONTINUATION_LENGTH, SCM_JMPBUF, SCM_DYNENV, SCM_THROW_VALUE)
(SCM_CONTINUATION_ROOT, SCM_DFRAME): Remove these from the exposed
API.
(scm_i_continuation_to_frame): New internal declaration.
* libguile/continuations.c
* libguile/continuations.c: Add trickery like in foreign.c, smob.c, and
gsubr.c, so that we can make procedural trampolines for continuations.
(scm_i_continuation_to_frame): New internal function, from stacks.c.
* libguile/programs.h (SCM_F_PROGRAM_IS_CONTINUATION)
(SCM_PROGRAM_IS_CONTINUATION): Add a flag for programs that are
continuations. Probably should add flags for the other trampoline
types too.
* libguile/programs.c (scm_i_program_print): Print continuations as
before.
* libguile/stacks.c (scm_stack_id, scm_make_stack): Use
scm_i_continuation_to_frame in the continuation case.
2010-02-06 17:00:03 +01:00
|
|
|
|
/* no NEXT */
|
|
|
|
|
|
abort ();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (59, partial_cont_call, "partial-cont-call", 0, -1, 0)
|
2010-02-22 23:00:19 +01:00
|
|
|
|
{
|
2010-02-26 13:05:25 +01:00
|
|
|
|
SCM vmcont, intwinds, prevwinds;
|
VM tweaks
* libguile/vm-engine.c (VM_CHECK_OBJECT, VM_CHECK_FREE_VARIABLES): Set
to 0 for both engines. These are really internal debugging variables,
which don't affect user-visible features, provided that the compiler
is correct of course.
(VM_CHECK_UNDERFLOW): New var, also off by default: whether to check
for stack underflow when popping values.
(vm_engine): Don't declare object_count if we are not checking object
table accesses.
* libguile/vm-engine.h (CACHE_PROGRAM): Don't muck with object_count
if we are not checking object table accesses.
(CHECK_UNDERFLOW, PRE_CHECK_UNDERFLOW): Nop out if we are not checking
underflow.
(POP2, POP3): New macros which check for underflow before popping more
than one value.
* libguile/vm-i-loader.c (load_array):
* libguile/vm-i-scheme.c (set_car, set_cdr, vector_set, slot_set)
(BV_SET_WITH_ENDIANNESS, BV_FIXABLE_INT_SET, BV_INT_SET)
(BV_FLOAT_SET):
* libguile/vm-i-system.c (partial_cont_call, fix_closure, prompt)
(fluid_set): Use POP2 / POP3.
(local_set, long_local_set): Pop to locals instead of using values on
the stack then dropping; allows for underflow to be checked before the
value is accessed.
(BR): Don't NULLSTACK or DROP after the operation.
(br_if, br_if_not, br_if_eq, br_if_not_eq, br_if_null)
(br_if_not_null): Pop to locals before doing the compare and jump.
2011-05-05 14:04:23 +02:00
|
|
|
|
POP2 (intwinds, vmcont);
|
2010-02-24 16:56:45 +01:00
|
|
|
|
SYNC_REGISTER ();
|
2010-02-25 00:18:07 +01:00
|
|
|
|
if (SCM_UNLIKELY (!SCM_VM_CONT_REWINDABLE_P (vmcont)))
|
|
|
|
|
|
{ finish_args = vmcont;
|
|
|
|
|
|
goto vm_error_continuation_not_rewindable;
|
|
|
|
|
|
}
|
2010-02-26 13:05:25 +01:00
|
|
|
|
prevwinds = scm_i_dynwinds ();
|
|
|
|
|
|
vm_reinstate_partial_continuation (vm, vmcont, intwinds, sp + 1 - fp, fp,
|
|
|
|
|
|
vm_cookie);
|
|
|
|
|
|
|
|
|
|
|
|
/* Rewind prompt jmpbuffers, if any. */
|
|
|
|
|
|
{
|
|
|
|
|
|
SCM winds = scm_i_dynwinds ();
|
|
|
|
|
|
for (; !scm_is_eq (winds, prevwinds); winds = scm_cdr (winds))
|
|
|
|
|
|
if (SCM_PROMPT_P (scm_car (winds)) && SCM_PROMPT_SETJMP (scm_car (winds)))
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2010-02-24 16:56:45 +01:00
|
|
|
|
CACHE_REGISTER ();
|
|
|
|
|
|
program = SCM_FRAME_PROGRAM (fp);
|
|
|
|
|
|
CACHE_PROGRAM ();
|
2010-02-22 23:00:19 +01:00
|
|
|
|
NEXT;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (60, tail_call_nargs, "tail-call/nargs", 0, 0, 1)
|
compile call-with-values, woot!
* libguile/vm-engine.c (vm_run): Add another byte onto the bootstrap
program, as the offset passed to mv-call now takes two bytes.
* module/system/vm/frame.scm (bootstrap-frame?): Update for the new
bootstrap length. Really we should just check for 'halt though.
* libguile/vm-i-system.c (FETCH_OFFSET): New helper, used in BR().
(goto/nargs, call/nargs): Versions of goto/args and call, respectively,
that take the number of arguments from a value on the top of the stack.
(mv-call): Call FETCH_OFFSET to get the offset.
* module/language/scheme/translate.scm (custom-transformer-table):
Compile call-with-values to <ghil-mv-call>. There is some trickery
because of the r4rs.scm call-with-values trampolines.
* module/system/il/ghil.scm: Add <ghil-mv-call> and accessors.
* module/system/il/compile.scm (codegen): Compile <ghil-mv-call>.
* module/system/il/glil.scm: Add <glil-mv-call>, which needs some special
assembly because of the label. Fix some typos.
* module/system/vm/assemble.scm (byte-length): New helper, factored out
and made more general.
(codegen): Assemble mv-call, including the label.
(check-length): New helper, makes sure that the addressing is
consistent within the produced object code.
(stack->bytes): Rewrite to be more generic -- now `br' instructions
aren't the only ones jumping around in the instruction stream.
* module/system/vm/conv.scm (make-byte-decoder): Return two values in the
#f case.
* module/system/vm/disasm.scm (disassemble-bytecode): Rewrite, because
the previous implementation depended on a guile interpreter quirk:
namely, that multiple values could be represented within one value, and
destructured later.
2008-09-16 00:26:22 +02:00
|
|
|
|
{
|
|
|
|
|
|
SCM x;
|
|
|
|
|
|
POP (x);
|
|
|
|
|
|
nargs = scm_to_int (x);
|
lambda-lifting for (lambda () ...) as consumer of call-with-values
* libguile/vm-engine.c (vm_run): Add new error case,
vm_error_not_enough_values.
* libguile/vm-i-system.c (goto/nargs, call/nargs): So, in these cases, if
we get too many values, we don't truncate the values like we do in the
single-value continuation case, or in the mvbind case. What to do? I
guess we either truncate them here, or only allow the correct number of
values. Dunno. Mark the code as a fixme.
(truncate-values): New instruction, for mv-bind: checks that the number
of values on the stack is compatible with the number of bindings we
have arranged for them, truncating if necessary.
* module/language/scheme/translate.scm (custom-transformer-table):
Compile receive as a primary form -- not so much because it is a
primary form, but more to test the mv-bind machinery. Also it's more
efficient, I think.
* module/system/il/compile.scm (lift-variables!): New helper, factored
out of `optimize'.
(optimize): Add a few more cases. Adapt `lambda' optimization, which
isn't much. I'm not happy with ghil as a mungeable language.
Add a case for call-with-values with the second argument is
a lambda: lift the lambda. Untested.
(codegen): Refactor the push-bindings! code. Compile mv-bind.
* module/system/il/ghil.scm (<ghil-mv-bind>): Add mv-bind construct,
along with its procedures.
* module/system/il/glil.scm (<glil-mv-bind>): Add mv-bind construct,
different from the high-level one. It makes sense in the source, I
think.
* module/system/vm/assemble.scm (codegen): Assemble glil-mv-bind by
pushing onto the bindings list, and actually push some code to truncate
the values.
2008-09-18 22:49:55 +02:00
|
|
|
|
/* FIXME: should truncate values? */
|
2010-01-03 14:49:40 +01:00
|
|
|
|
goto vm_tail_call;
|
compile call-with-values, woot!
* libguile/vm-engine.c (vm_run): Add another byte onto the bootstrap
program, as the offset passed to mv-call now takes two bytes.
* module/system/vm/frame.scm (bootstrap-frame?): Update for the new
bootstrap length. Really we should just check for 'halt though.
* libguile/vm-i-system.c (FETCH_OFFSET): New helper, used in BR().
(goto/nargs, call/nargs): Versions of goto/args and call, respectively,
that take the number of arguments from a value on the top of the stack.
(mv-call): Call FETCH_OFFSET to get the offset.
* module/language/scheme/translate.scm (custom-transformer-table):
Compile call-with-values to <ghil-mv-call>. There is some trickery
because of the r4rs.scm call-with-values trampolines.
* module/system/il/ghil.scm: Add <ghil-mv-call> and accessors.
* module/system/il/compile.scm (codegen): Compile <ghil-mv-call>.
* module/system/il/glil.scm: Add <glil-mv-call>, which needs some special
assembly because of the label. Fix some typos.
* module/system/vm/assemble.scm (byte-length): New helper, factored out
and made more general.
(codegen): Assemble mv-call, including the label.
(check-length): New helper, makes sure that the addressing is
consistent within the produced object code.
(stack->bytes): Rewrite to be more generic -- now `br' instructions
aren't the only ones jumping around in the instruction stream.
* module/system/vm/conv.scm (make-byte-decoder): Return two values in the
#f case.
* module/system/vm/disasm.scm (disassemble-bytecode): Rewrite, because
the previous implementation depended on a guile interpreter quirk:
namely, that multiple values could be represented within one value, and
destructured later.
2008-09-16 00:26:22 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (61, call_nargs, "call/nargs", 0, 0, 1)
|
compile call-with-values, woot!
* libguile/vm-engine.c (vm_run): Add another byte onto the bootstrap
program, as the offset passed to mv-call now takes two bytes.
* module/system/vm/frame.scm (bootstrap-frame?): Update for the new
bootstrap length. Really we should just check for 'halt though.
* libguile/vm-i-system.c (FETCH_OFFSET): New helper, used in BR().
(goto/nargs, call/nargs): Versions of goto/args and call, respectively,
that take the number of arguments from a value on the top of the stack.
(mv-call): Call FETCH_OFFSET to get the offset.
* module/language/scheme/translate.scm (custom-transformer-table):
Compile call-with-values to <ghil-mv-call>. There is some trickery
because of the r4rs.scm call-with-values trampolines.
* module/system/il/ghil.scm: Add <ghil-mv-call> and accessors.
* module/system/il/compile.scm (codegen): Compile <ghil-mv-call>.
* module/system/il/glil.scm: Add <glil-mv-call>, which needs some special
assembly because of the label. Fix some typos.
* module/system/vm/assemble.scm (byte-length): New helper, factored out
and made more general.
(codegen): Assemble mv-call, including the label.
(check-length): New helper, makes sure that the addressing is
consistent within the produced object code.
(stack->bytes): Rewrite to be more generic -- now `br' instructions
aren't the only ones jumping around in the instruction stream.
* module/system/vm/conv.scm (make-byte-decoder): Return two values in the
#f case.
* module/system/vm/disasm.scm (disassemble-bytecode): Rewrite, because
the previous implementation depended on a guile interpreter quirk:
namely, that multiple values could be represented within one value, and
destructured later.
2008-09-16 00:26:22 +02:00
|
|
|
|
{
|
|
|
|
|
|
SCM x;
|
|
|
|
|
|
POP (x);
|
|
|
|
|
|
nargs = scm_to_int (x);
|
lambda-lifting for (lambda () ...) as consumer of call-with-values
* libguile/vm-engine.c (vm_run): Add new error case,
vm_error_not_enough_values.
* libguile/vm-i-system.c (goto/nargs, call/nargs): So, in these cases, if
we get too many values, we don't truncate the values like we do in the
single-value continuation case, or in the mvbind case. What to do? I
guess we either truncate them here, or only allow the correct number of
values. Dunno. Mark the code as a fixme.
(truncate-values): New instruction, for mv-bind: checks that the number
of values on the stack is compatible with the number of bindings we
have arranged for them, truncating if necessary.
* module/language/scheme/translate.scm (custom-transformer-table):
Compile receive as a primary form -- not so much because it is a
primary form, but more to test the mv-bind machinery. Also it's more
efficient, I think.
* module/system/il/compile.scm (lift-variables!): New helper, factored
out of `optimize'.
(optimize): Add a few more cases. Adapt `lambda' optimization, which
isn't much. I'm not happy with ghil as a mungeable language.
Add a case for call-with-values with the second argument is
a lambda: lift the lambda. Untested.
(codegen): Refactor the push-bindings! code. Compile mv-bind.
* module/system/il/ghil.scm (<ghil-mv-bind>): Add mv-bind construct,
along with its procedures.
* module/system/il/glil.scm (<glil-mv-bind>): Add mv-bind construct,
different from the high-level one. It makes sense in the source, I
think.
* module/system/vm/assemble.scm (codegen): Assemble glil-mv-bind by
pushing onto the bindings list, and actually push some code to truncate
the values.
2008-09-18 22:49:55 +02:00
|
|
|
|
/* FIXME: should truncate values? */
|
compile call-with-values, woot!
* libguile/vm-engine.c (vm_run): Add another byte onto the bootstrap
program, as the offset passed to mv-call now takes two bytes.
* module/system/vm/frame.scm (bootstrap-frame?): Update for the new
bootstrap length. Really we should just check for 'halt though.
* libguile/vm-i-system.c (FETCH_OFFSET): New helper, used in BR().
(goto/nargs, call/nargs): Versions of goto/args and call, respectively,
that take the number of arguments from a value on the top of the stack.
(mv-call): Call FETCH_OFFSET to get the offset.
* module/language/scheme/translate.scm (custom-transformer-table):
Compile call-with-values to <ghil-mv-call>. There is some trickery
because of the r4rs.scm call-with-values trampolines.
* module/system/il/ghil.scm: Add <ghil-mv-call> and accessors.
* module/system/il/compile.scm (codegen): Compile <ghil-mv-call>.
* module/system/il/glil.scm: Add <glil-mv-call>, which needs some special
assembly because of the label. Fix some typos.
* module/system/vm/assemble.scm (byte-length): New helper, factored out
and made more general.
(codegen): Assemble mv-call, including the label.
(check-length): New helper, makes sure that the addressing is
consistent within the produced object code.
(stack->bytes): Rewrite to be more generic -- now `br' instructions
aren't the only ones jumping around in the instruction stream.
* module/system/vm/conv.scm (make-byte-decoder): Return two values in the
#f case.
* module/system/vm/disasm.scm (disassemble-bytecode): Rewrite, because
the previous implementation depended on a guile interpreter quirk:
namely, that multiple values could be represented within one value, and
destructured later.
2008-09-16 00:26:22 +02:00
|
|
|
|
goto vm_call;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (62, mv_call, "mv-call", 4, -1, 1)
|
add multiple values support to the vm
* libguile/vm-engine.c (vm_run): The bootstrap program now uses mv_call,
so as to allow multiple values out of the VM. (It did before, because
multiple values were represented internally as single scm_values
objects, but now that values go on the stack, we need to note the boot
frame as accepting multiple values.)
(vm_error_no_values): New error, happens if you pass no values into a
single-value continuation. Passing more than one is OK though, it just
takes the first one.
* libguile/vm-i-system.c (halt): Assume that someone has pushed the
number of values onto the stack, and package up that number of values
as a scm_values() object, for communication with the interpreter.
(mv-call): New instruction, calls a procedure with a multiple-value
continuation, even handling calls out to the interpreter.
(return/values): New instruction, returns multiple values to the
continuation. If the continuation is single-valued, takes the first
value or errors if there are no values. Otherwise it returns to the
multiple-value return address, pushing the number of values on top of
the values.
* module/system/il/compile.scm (codegen): Compile <ghil-values> forms.
* module/system/il/ghil.scm (<ghil-values>) Add new GHIL data structure
and associated procedures.
* module/language/scheme/translate.scm (custom-transformer-table):
Compile (values .. ) forms into <ghil-values>.
2008-09-14 17:06:52 +02:00
|
|
|
|
{
|
2009-09-17 14:58:31 +02:00
|
|
|
|
scm_t_int32 offset;
|
2009-07-26 14:01:56 +02:00
|
|
|
|
scm_t_uint8 *mvra;
|
add multiple values support to the vm
* libguile/vm-engine.c (vm_run): The bootstrap program now uses mv_call,
so as to allow multiple values out of the VM. (It did before, because
multiple values were represented internally as single scm_values
objects, but now that values go on the stack, we need to note the boot
frame as accepting multiple values.)
(vm_error_no_values): New error, happens if you pass no values into a
single-value continuation. Passing more than one is OK though, it just
takes the first one.
* libguile/vm-i-system.c (halt): Assume that someone has pushed the
number of values onto the stack, and package up that number of values
as a scm_values() object, for communication with the interpreter.
(mv-call): New instruction, calls a procedure with a multiple-value
continuation, even handling calls out to the interpreter.
(return/values): New instruction, returns multiple values to the
continuation. If the continuation is single-valued, takes the first
value or errors if there are no values. Otherwise it returns to the
multiple-value return address, pushing the number of values on top of
the values.
* module/system/il/compile.scm (codegen): Compile <ghil-values> forms.
* module/system/il/ghil.scm (<ghil-values>) Add new GHIL data structure
and associated procedures.
* module/language/scheme/translate.scm (custom-transformer-table):
Compile (values .. ) forms into <ghil-values>.
2008-09-14 17:06:52 +02:00
|
|
|
|
|
|
|
|
|
|
nargs = FETCH ();
|
compile call-with-values, woot!
* libguile/vm-engine.c (vm_run): Add another byte onto the bootstrap
program, as the offset passed to mv-call now takes two bytes.
* module/system/vm/frame.scm (bootstrap-frame?): Update for the new
bootstrap length. Really we should just check for 'halt though.
* libguile/vm-i-system.c (FETCH_OFFSET): New helper, used in BR().
(goto/nargs, call/nargs): Versions of goto/args and call, respectively,
that take the number of arguments from a value on the top of the stack.
(mv-call): Call FETCH_OFFSET to get the offset.
* module/language/scheme/translate.scm (custom-transformer-table):
Compile call-with-values to <ghil-mv-call>. There is some trickery
because of the r4rs.scm call-with-values trampolines.
* module/system/il/ghil.scm: Add <ghil-mv-call> and accessors.
* module/system/il/compile.scm (codegen): Compile <ghil-mv-call>.
* module/system/il/glil.scm: Add <glil-mv-call>, which needs some special
assembly because of the label. Fix some typos.
* module/system/vm/assemble.scm (byte-length): New helper, factored out
and made more general.
(codegen): Assemble mv-call, including the label.
(check-length): New helper, makes sure that the addressing is
consistent within the produced object code.
(stack->bytes): Rewrite to be more generic -- now `br' instructions
aren't the only ones jumping around in the instruction stream.
* module/system/vm/conv.scm (make-byte-decoder): Return two values in the
#f case.
* module/system/vm/disasm.scm (disassemble-bytecode): Rewrite, because
the previous implementation depended on a guile interpreter quirk:
namely, that multiple values could be represented within one value, and
destructured later.
2008-09-16 00:26:22 +02:00
|
|
|
|
FETCH_OFFSET (offset);
|
2009-09-17 14:58:31 +02:00
|
|
|
|
mvra = ip + offset;
|
add multiple values support to the vm
* libguile/vm-engine.c (vm_run): The bootstrap program now uses mv_call,
so as to allow multiple values out of the VM. (It did before, because
multiple values were represented internally as single scm_values
objects, but now that values go on the stack, we need to note the boot
frame as accepting multiple values.)
(vm_error_no_values): New error, happens if you pass no values into a
single-value continuation. Passing more than one is OK though, it just
takes the first one.
* libguile/vm-i-system.c (halt): Assume that someone has pushed the
number of values onto the stack, and package up that number of values
as a scm_values() object, for communication with the interpreter.
(mv-call): New instruction, calls a procedure with a multiple-value
continuation, even handling calls out to the interpreter.
(return/values): New instruction, returns multiple values to the
continuation. If the continuation is single-valued, takes the first
value or errors if there are no values. Otherwise it returns to the
multiple-value return address, pushing the number of values on top of
the values.
* module/system/il/compile.scm (codegen): Compile <ghil-values> forms.
* module/system/il/ghil.scm (<ghil-values>) Add new GHIL data structure
and associated procedures.
* module/language/scheme/translate.scm (custom-transformer-table):
Compile (values .. ) forms into <ghil-values>.
2008-09-14 17:06:52 +02:00
|
|
|
|
|
2009-10-31 00:08:42 +01:00
|
|
|
|
vm_mv_call:
|
smobs are applied with vm trampoline procedures
* libguile/smob.c: Instead of having special evaluator support for
applying smobs, we use the same strategy that gsubr uses, that smob
application should happen via a trampoline VM procedure, which uses a
special opcode (smob-apply). So statically allocate all of the desired
trampoline procedures here.
(scm_i_smob_apply_trampoline): Unfortunately there's no real place to
put the trampoline, so instead use a weak-key hash. It's nasty, but I
think the benefits of speeding up procedure calls in the general case
are worth it.
* libguile/smob.h (scm_smob_descriptor): Remove fields apply_0, apply_1,
apply_2, and apply_3; these were never public. Also remove the
gsubr_type field. Instead cache the trampoline objcode here.
(SCM_SMOB_APPLY_0, SCM_SMOB_APPLY_1, SCM_SMOB_APPLY_2,
SCM_SMOB_APPLY_3): Just go through scm_call_0, etc here.
* libguile/vm-i-system.c (call, tail-call, mv-call): Simplify. All
procedure calls are VM calls now.
(smob-call): New instruction, used in smob trampoline procedures.
* libguile/vm.c (apply_foreign): Remove. Yay!
* libguile/procprop.c (scm_i_procedure_arity): Refactor a bit for the
smob changes.
2010-01-09 14:12:47 +01:00
|
|
|
|
program = sp[-nargs];
|
add multiple values support to the vm
* libguile/vm-engine.c (vm_run): The bootstrap program now uses mv_call,
so as to allow multiple values out of the VM. (It did before, because
multiple values were represented internally as single scm_values
objects, but now that values go on the stack, we need to note the boot
frame as accepting multiple values.)
(vm_error_no_values): New error, happens if you pass no values into a
single-value continuation. Passing more than one is OK though, it just
takes the first one.
* libguile/vm-i-system.c (halt): Assume that someone has pushed the
number of values onto the stack, and package up that number of values
as a scm_values() object, for communication with the interpreter.
(mv-call): New instruction, calls a procedure with a multiple-value
continuation, even handling calls out to the interpreter.
(return/values): New instruction, returns multiple values to the
continuation. If the continuation is single-valued, takes the first
value or errors if there are no values. Otherwise it returns to the
multiple-value return address, pushing the number of values on top of
the values.
* module/system/il/compile.scm (codegen): Compile <ghil-values> forms.
* module/system/il/ghil.scm (<ghil-values>) Add new GHIL data structure
and associated procedures.
* module/language/scheme/translate.scm (custom-transformer-table):
Compile (values .. ) forms into <ghil-values>.
2008-09-14 17:06:52 +02:00
|
|
|
|
|
2009-12-20 23:12:34 +01:00
|
|
|
|
VM_HANDLE_INTERRUPTS;
|
|
|
|
|
|
|
smobs are applied with vm trampoline procedures
* libguile/smob.c: Instead of having special evaluator support for
applying smobs, we use the same strategy that gsubr uses, that smob
application should happen via a trampoline VM procedure, which uses a
special opcode (smob-apply). So statically allocate all of the desired
trampoline procedures here.
(scm_i_smob_apply_trampoline): Unfortunately there's no real place to
put the trampoline, so instead use a weak-key hash. It's nasty, but I
think the benefits of speeding up procedure calls in the general case
are worth it.
* libguile/smob.h (scm_smob_descriptor): Remove fields apply_0, apply_1,
apply_2, and apply_3; these were never public. Also remove the
gsubr_type field. Instead cache the trampoline objcode here.
(SCM_SMOB_APPLY_0, SCM_SMOB_APPLY_1, SCM_SMOB_APPLY_2,
SCM_SMOB_APPLY_3): Just go through scm_call_0, etc here.
* libguile/vm-i-system.c (call, tail-call, mv-call): Simplify. All
procedure calls are VM calls now.
(smob-call): New instruction, used in smob trampoline procedures.
* libguile/vm.c (apply_foreign): Remove. Yay!
* libguile/procprop.c (scm_i_procedure_arity): Refactor a bit for the
smob changes.
2010-01-09 14:12:47 +01:00
|
|
|
|
if (SCM_UNLIKELY (!SCM_PROGRAM_P (program)))
|
add multiple values support to the vm
* libguile/vm-engine.c (vm_run): The bootstrap program now uses mv_call,
so as to allow multiple values out of the VM. (It did before, because
multiple values were represented internally as single scm_values
objects, but now that values go on the stack, we need to note the boot
frame as accepting multiple values.)
(vm_error_no_values): New error, happens if you pass no values into a
single-value continuation. Passing more than one is OK though, it just
takes the first one.
* libguile/vm-i-system.c (halt): Assume that someone has pushed the
number of values onto the stack, and package up that number of values
as a scm_values() object, for communication with the interpreter.
(mv-call): New instruction, calls a procedure with a multiple-value
continuation, even handling calls out to the interpreter.
(return/values): New instruction, returns multiple values to the
continuation. If the continuation is single-valued, takes the first
value or errors if there are no values. Otherwise it returns to the
multiple-value return address, pushing the number of values on top of
the values.
* module/system/il/compile.scm (codegen): Compile <ghil-values> forms.
* module/system/il/ghil.scm (<ghil-values>) Add new GHIL data structure
and associated procedures.
* module/language/scheme/translate.scm (custom-transformer-table):
Compile (values .. ) forms into <ghil-values>.
2008-09-14 17:06:52 +02:00
|
|
|
|
{
|
smobs are applied with vm trampoline procedures
* libguile/smob.c: Instead of having special evaluator support for
applying smobs, we use the same strategy that gsubr uses, that smob
application should happen via a trampoline VM procedure, which uses a
special opcode (smob-apply). So statically allocate all of the desired
trampoline procedures here.
(scm_i_smob_apply_trampoline): Unfortunately there's no real place to
put the trampoline, so instead use a weak-key hash. It's nasty, but I
think the benefits of speeding up procedure calls in the general case
are worth it.
* libguile/smob.h (scm_smob_descriptor): Remove fields apply_0, apply_1,
apply_2, and apply_3; these were never public. Also remove the
gsubr_type field. Instead cache the trampoline objcode here.
(SCM_SMOB_APPLY_0, SCM_SMOB_APPLY_1, SCM_SMOB_APPLY_2,
SCM_SMOB_APPLY_3): Just go through scm_call_0, etc here.
* libguile/vm-i-system.c (call, tail-call, mv-call): Simplify. All
procedure calls are VM calls now.
(smob-call): New instruction, used in smob trampoline procedures.
* libguile/vm.c (apply_foreign): Remove. Yay!
* libguile/procprop.c (scm_i_procedure_arity): Refactor a bit for the
smob changes.
2010-01-09 14:12:47 +01:00
|
|
|
|
if (SCM_STRUCTP (program) && SCM_STRUCT_APPLICABLE_P (program))
|
|
|
|
|
|
{
|
|
|
|
|
|
sp[-nargs] = SCM_STRUCT_PROCEDURE (program);
|
|
|
|
|
|
goto vm_mv_call;
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (SCM_NIMP (program) && SCM_TYP7 (program) == scm_tc7_smob
|
|
|
|
|
|
&& SCM_SMOB_APPLICABLE_P (program))
|
add multiple values support to the vm
* libguile/vm-engine.c (vm_run): The bootstrap program now uses mv_call,
so as to allow multiple values out of the VM. (It did before, because
multiple values were represented internally as single scm_values
objects, but now that values go on the stack, we need to note the boot
frame as accepting multiple values.)
(vm_error_no_values): New error, happens if you pass no values into a
single-value continuation. Passing more than one is OK though, it just
takes the first one.
* libguile/vm-i-system.c (halt): Assume that someone has pushed the
number of values onto the stack, and package up that number of values
as a scm_values() object, for communication with the interpreter.
(mv-call): New instruction, calls a procedure with a multiple-value
continuation, even handling calls out to the interpreter.
(return/values): New instruction, returns multiple values to the
continuation. If the continuation is single-valued, takes the first
value or errors if there are no values. Otherwise it returns to the
multiple-value return address, pushing the number of values on top of
the values.
* module/system/il/compile.scm (codegen): Compile <ghil-values> forms.
* module/system/il/ghil.scm (<ghil-values>) Add new GHIL data structure
and associated procedures.
* module/language/scheme/translate.scm (custom-transformer-table):
Compile (values .. ) forms into <ghil-values>.
2008-09-14 17:06:52 +02:00
|
|
|
|
{
|
smobs are applied with vm trampoline procedures
* libguile/smob.c: Instead of having special evaluator support for
applying smobs, we use the same strategy that gsubr uses, that smob
application should happen via a trampoline VM procedure, which uses a
special opcode (smob-apply). So statically allocate all of the desired
trampoline procedures here.
(scm_i_smob_apply_trampoline): Unfortunately there's no real place to
put the trampoline, so instead use a weak-key hash. It's nasty, but I
think the benefits of speeding up procedure calls in the general case
are worth it.
* libguile/smob.h (scm_smob_descriptor): Remove fields apply_0, apply_1,
apply_2, and apply_3; these were never public. Also remove the
gsubr_type field. Instead cache the trampoline objcode here.
(SCM_SMOB_APPLY_0, SCM_SMOB_APPLY_1, SCM_SMOB_APPLY_2,
SCM_SMOB_APPLY_3): Just go through scm_call_0, etc here.
* libguile/vm-i-system.c (call, tail-call, mv-call): Simplify. All
procedure calls are VM calls now.
(smob-call): New instruction, used in smob trampoline procedures.
* libguile/vm.c (apply_foreign): Remove. Yay!
* libguile/procprop.c (scm_i_procedure_arity): Refactor a bit for the
smob changes.
2010-01-09 14:12:47 +01:00
|
|
|
|
SYNC_REGISTER ();
|
|
|
|
|
|
sp[-nargs] = scm_i_smob_apply_trampoline (program);
|
|
|
|
|
|
goto vm_mv_call;
|
add multiple values support to the vm
* libguile/vm-engine.c (vm_run): The bootstrap program now uses mv_call,
so as to allow multiple values out of the VM. (It did before, because
multiple values were represented internally as single scm_values
objects, but now that values go on the stack, we need to note the boot
frame as accepting multiple values.)
(vm_error_no_values): New error, happens if you pass no values into a
single-value continuation. Passing more than one is OK though, it just
takes the first one.
* libguile/vm-i-system.c (halt): Assume that someone has pushed the
number of values onto the stack, and package up that number of values
as a scm_values() object, for communication with the interpreter.
(mv-call): New instruction, calls a procedure with a multiple-value
continuation, even handling calls out to the interpreter.
(return/values): New instruction, returns multiple values to the
continuation. If the continuation is single-valued, takes the first
value or errors if there are no values. Otherwise it returns to the
multiple-value return address, pushing the number of values on top of
the values.
* module/system/il/compile.scm (codegen): Compile <ghil-values> forms.
* module/system/il/ghil.scm (<ghil-values>) Add new GHIL data structure
and associated procedures.
* module/language/scheme/translate.scm (custom-transformer-table):
Compile (values .. ) forms into <ghil-values>.
2008-09-14 17:06:52 +02:00
|
|
|
|
}
|
2009-12-01 22:11:15 +01:00
|
|
|
|
else
|
smobs are applied with vm trampoline procedures
* libguile/smob.c: Instead of having special evaluator support for
applying smobs, we use the same strategy that gsubr uses, that smob
application should happen via a trampoline VM procedure, which uses a
special opcode (smob-apply). So statically allocate all of the desired
trampoline procedures here.
(scm_i_smob_apply_trampoline): Unfortunately there's no real place to
put the trampoline, so instead use a weak-key hash. It's nasty, but I
think the benefits of speeding up procedure calls in the general case
are worth it.
* libguile/smob.h (scm_smob_descriptor): Remove fields apply_0, apply_1,
apply_2, and apply_3; these were never public. Also remove the
gsubr_type field. Instead cache the trampoline objcode here.
(SCM_SMOB_APPLY_0, SCM_SMOB_APPLY_1, SCM_SMOB_APPLY_2,
SCM_SMOB_APPLY_3): Just go through scm_call_0, etc here.
* libguile/vm-i-system.c (call, tail-call, mv-call): Simplify. All
procedure calls are VM calls now.
(smob-call): New instruction, used in smob trampoline procedures.
* libguile/vm.c (apply_foreign): Remove. Yay!
* libguile/procprop.c (scm_i_procedure_arity): Refactor a bit for the
smob changes.
2010-01-09 14:12:47 +01:00
|
|
|
|
goto vm_error_wrong_type_apply;
|
add multiple values support to the vm
* libguile/vm-engine.c (vm_run): The bootstrap program now uses mv_call,
so as to allow multiple values out of the VM. (It did before, because
multiple values were represented internally as single scm_values
objects, but now that values go on the stack, we need to note the boot
frame as accepting multiple values.)
(vm_error_no_values): New error, happens if you pass no values into a
single-value continuation. Passing more than one is OK though, it just
takes the first one.
* libguile/vm-i-system.c (halt): Assume that someone has pushed the
number of values onto the stack, and package up that number of values
as a scm_values() object, for communication with the interpreter.
(mv-call): New instruction, calls a procedure with a multiple-value
continuation, even handling calls out to the interpreter.
(return/values): New instruction, returns multiple values to the
continuation. If the continuation is single-valued, takes the first
value or errors if there are no values. Otherwise it returns to the
multiple-value return address, pushing the number of values on top of
the values.
* module/system/il/compile.scm (codegen): Compile <ghil-values> forms.
* module/system/il/ghil.scm (<ghil-values>) Add new GHIL data structure
and associated procedures.
* module/language/scheme/translate.scm (custom-transformer-table):
Compile (values .. ) forms into <ghil-values>.
2008-09-14 17:06:52 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
smobs are applied with vm trampoline procedures
* libguile/smob.c: Instead of having special evaluator support for
applying smobs, we use the same strategy that gsubr uses, that smob
application should happen via a trampoline VM procedure, which uses a
special opcode (smob-apply). So statically allocate all of the desired
trampoline procedures here.
(scm_i_smob_apply_trampoline): Unfortunately there's no real place to
put the trampoline, so instead use a weak-key hash. It's nasty, but I
think the benefits of speeding up procedure calls in the general case
are worth it.
* libguile/smob.h (scm_smob_descriptor): Remove fields apply_0, apply_1,
apply_2, and apply_3; these were never public. Also remove the
gsubr_type field. Instead cache the trampoline objcode here.
(SCM_SMOB_APPLY_0, SCM_SMOB_APPLY_1, SCM_SMOB_APPLY_2,
SCM_SMOB_APPLY_3): Just go through scm_call_0, etc here.
* libguile/vm-i-system.c (call, tail-call, mv-call): Simplify. All
procedure calls are VM calls now.
(smob-call): New instruction, used in smob trampoline procedures.
* libguile/vm.c (apply_foreign): Remove. Yay!
* libguile/procprop.c (scm_i_procedure_arity): Refactor a bit for the
smob changes.
2010-01-09 14:12:47 +01:00
|
|
|
|
CACHE_PROGRAM ();
|
2011-03-15 23:33:32 +01:00
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
SCM *old_fp = fp;
|
|
|
|
|
|
|
|
|
|
|
|
fp = sp - nargs + 1;
|
|
|
|
|
|
|
|
|
|
|
|
ASSERT (SCM_FRAME_DYNAMIC_LINK (fp) == 0);
|
|
|
|
|
|
ASSERT (SCM_FRAME_RETURN_ADDRESS (fp) == 0);
|
|
|
|
|
|
ASSERT (SCM_FRAME_MV_RETURN_ADDRESS (fp) == 0);
|
|
|
|
|
|
SCM_FRAME_SET_DYNAMIC_LINK (fp, old_fp);
|
|
|
|
|
|
SCM_FRAME_SET_RETURN_ADDRESS (fp, ip);
|
|
|
|
|
|
SCM_FRAME_SET_MV_RETURN_ADDRESS (fp, mvra);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
smobs are applied with vm trampoline procedures
* libguile/smob.c: Instead of having special evaluator support for
applying smobs, we use the same strategy that gsubr uses, that smob
application should happen via a trampoline VM procedure, which uses a
special opcode (smob-apply). So statically allocate all of the desired
trampoline procedures here.
(scm_i_smob_apply_trampoline): Unfortunately there's no real place to
put the trampoline, so instead use a weak-key hash. It's nasty, but I
think the benefits of speeding up procedure calls in the general case
are worth it.
* libguile/smob.h (scm_smob_descriptor): Remove fields apply_0, apply_1,
apply_2, and apply_3; these were never public. Also remove the
gsubr_type field. Instead cache the trampoline objcode here.
(SCM_SMOB_APPLY_0, SCM_SMOB_APPLY_1, SCM_SMOB_APPLY_2,
SCM_SMOB_APPLY_3): Just go through scm_call_0, etc here.
* libguile/vm-i-system.c (call, tail-call, mv-call): Simplify. All
procedure calls are VM calls now.
(smob-call): New instruction, used in smob trampoline procedures.
* libguile/vm.c (apply_foreign): Remove. Yay!
* libguile/procprop.c (scm_i_procedure_arity): Refactor a bit for the
smob changes.
2010-01-09 14:12:47 +01:00
|
|
|
|
ip = SCM_C_OBJCODE_BASE (bp);
|
2010-09-16 12:14:55 +02:00
|
|
|
|
PUSH_CONTINUATION_HOOK ();
|
smobs are applied with vm trampoline procedures
* libguile/smob.c: Instead of having special evaluator support for
applying smobs, we use the same strategy that gsubr uses, that smob
application should happen via a trampoline VM procedure, which uses a
special opcode (smob-apply). So statically allocate all of the desired
trampoline procedures here.
(scm_i_smob_apply_trampoline): Unfortunately there's no real place to
put the trampoline, so instead use a weak-key hash. It's nasty, but I
think the benefits of speeding up procedure calls in the general case
are worth it.
* libguile/smob.h (scm_smob_descriptor): Remove fields apply_0, apply_1,
apply_2, and apply_3; these were never public. Also remove the
gsubr_type field. Instead cache the trampoline objcode here.
(SCM_SMOB_APPLY_0, SCM_SMOB_APPLY_1, SCM_SMOB_APPLY_2,
SCM_SMOB_APPLY_3): Just go through scm_call_0, etc here.
* libguile/vm-i-system.c (call, tail-call, mv-call): Simplify. All
procedure calls are VM calls now.
(smob-call): New instruction, used in smob trampoline procedures.
* libguile/vm.c (apply_foreign): Remove. Yay!
* libguile/procprop.c (scm_i_procedure_arity): Refactor a bit for the
smob changes.
2010-01-09 14:12:47 +01:00
|
|
|
|
APPLY_HOOK ();
|
|
|
|
|
|
NEXT;
|
add multiple values support to the vm
* libguile/vm-engine.c (vm_run): The bootstrap program now uses mv_call,
so as to allow multiple values out of the VM. (It did before, because
multiple values were represented internally as single scm_values
objects, but now that values go on the stack, we need to note the boot
frame as accepting multiple values.)
(vm_error_no_values): New error, happens if you pass no values into a
single-value continuation. Passing more than one is OK though, it just
takes the first one.
* libguile/vm-i-system.c (halt): Assume that someone has pushed the
number of values onto the stack, and package up that number of values
as a scm_values() object, for communication with the interpreter.
(mv-call): New instruction, calls a procedure with a multiple-value
continuation, even handling calls out to the interpreter.
(return/values): New instruction, returns multiple values to the
continuation. If the continuation is single-valued, takes the first
value or errors if there are no values. Otherwise it returns to the
multiple-value return address, pushing the number of values on top of
the values.
* module/system/il/compile.scm (codegen): Compile <ghil-values> forms.
* module/system/il/ghil.scm (<ghil-values>) Add new GHIL data structure
and associated procedures.
* module/language/scheme/translate.scm (custom-transformer-table):
Compile (values .. ) forms into <ghil-values>.
2008-09-14 17:06:52 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (63, apply, "apply", 1, -1, 1)
|
2001-04-07 09:39:38 +00:00
|
|
|
|
{
|
2001-04-07 23:32:03 +00:00
|
|
|
|
int len;
|
|
|
|
|
|
SCM ls;
|
|
|
|
|
|
POP (ls);
|
|
|
|
|
|
|
|
|
|
|
|
nargs = FETCH ();
|
2008-10-02 11:00:55 +02:00
|
|
|
|
ASSERT (nargs >= 2);
|
2001-04-07 23:32:03 +00:00
|
|
|
|
|
|
|
|
|
|
len = scm_ilength (ls);
|
better error reporting from the vm
* libguile/vm-engine.c: Add func_name local, for error reporting.
(vm_error_apply_to_non_list): New error case.
(vm_error_wrong_type_arg): Remove this generic error case.
(vm_error_wrong_type_apply): Remove FUNC_NAME -- no sense in seeing
"vm-debug-engine" in the error report.
(vm_error_not_a_pair, vm_error_not_a_bytevector)
(vm_error_not_a_struct, vm_error_not_a_thunk): Use func_name instead
of FUNC_NAME, so we can indicate what caused the error.
* libguile/vm-i-scheme.c (VM_VALIDATE_CONS, car, cdr, set-car!)
(set-cdr!): Indicate provenance of errors.
(VM_VALIDATE_STRUCT, struct-vtable):
(VM_VALIDATE_BYTEVECTOR, BV_FIXABLE_INT_REF, BV_INT_REF)
(BV_FLOAT_REF, BV_FIXABLE_INT_SET, BV_INT_SET, BV_FLOAT_SET): Same.
* libguile/vm-i-system.c (apply, tail-apply): Use
vm_error_apply_to_non_list.
2010-07-15 12:44:15 +02:00
|
|
|
|
if (SCM_UNLIKELY (len < 0))
|
|
|
|
|
|
{
|
|
|
|
|
|
finish_args = ls;
|
|
|
|
|
|
goto vm_error_apply_to_non_list;
|
|
|
|
|
|
}
|
2001-04-07 23:32:03 +00:00
|
|
|
|
|
2009-01-04 14:06:52 +01:00
|
|
|
|
PUSH_LIST (ls, SCM_NULL_OR_NIL_P);
|
2001-04-07 23:32:03 +00:00
|
|
|
|
|
|
|
|
|
|
nargs += len - 2;
|
|
|
|
|
|
goto vm_call;
|
2001-04-07 09:39:38 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (64, tail_apply, "tail-apply", 1, -1, 1)
|
2008-09-13 19:19:10 +02:00
|
|
|
|
{
|
|
|
|
|
|
int len;
|
|
|
|
|
|
SCM ls;
|
|
|
|
|
|
POP (ls);
|
|
|
|
|
|
|
|
|
|
|
|
nargs = FETCH ();
|
2008-10-02 11:00:55 +02:00
|
|
|
|
ASSERT (nargs >= 2);
|
2008-09-13 19:19:10 +02:00
|
|
|
|
|
|
|
|
|
|
len = scm_ilength (ls);
|
better error reporting from the vm
* libguile/vm-engine.c: Add func_name local, for error reporting.
(vm_error_apply_to_non_list): New error case.
(vm_error_wrong_type_arg): Remove this generic error case.
(vm_error_wrong_type_apply): Remove FUNC_NAME -- no sense in seeing
"vm-debug-engine" in the error report.
(vm_error_not_a_pair, vm_error_not_a_bytevector)
(vm_error_not_a_struct, vm_error_not_a_thunk): Use func_name instead
of FUNC_NAME, so we can indicate what caused the error.
* libguile/vm-i-scheme.c (VM_VALIDATE_CONS, car, cdr, set-car!)
(set-cdr!): Indicate provenance of errors.
(VM_VALIDATE_STRUCT, struct-vtable):
(VM_VALIDATE_BYTEVECTOR, BV_FIXABLE_INT_REF, BV_INT_REF)
(BV_FLOAT_REF, BV_FIXABLE_INT_SET, BV_INT_SET, BV_FLOAT_SET): Same.
* libguile/vm-i-system.c (apply, tail-apply): Use
vm_error_apply_to_non_list.
2010-07-15 12:44:15 +02:00
|
|
|
|
if (SCM_UNLIKELY (len < 0))
|
|
|
|
|
|
{
|
|
|
|
|
|
finish_args = ls;
|
|
|
|
|
|
goto vm_error_apply_to_non_list;
|
|
|
|
|
|
}
|
2008-09-13 19:19:10 +02:00
|
|
|
|
|
2009-01-04 14:06:52 +01:00
|
|
|
|
PUSH_LIST (ls, SCM_NULL_OR_NIL_P);
|
2008-09-13 19:19:10 +02:00
|
|
|
|
|
|
|
|
|
|
nargs += len - 2;
|
2010-01-03 14:49:40 +01:00
|
|
|
|
goto vm_tail_call;
|
2008-09-13 19:19:10 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (65, call_cc, "call/cc", 0, 1, 1)
|
2001-04-01 05:03:41 +00:00
|
|
|
|
{
|
2008-09-25 11:07:54 +02:00
|
|
|
|
int first;
|
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
|
|
|
|
SCM proc, vm_cont, cont;
|
2008-09-25 11:07:54 +02:00
|
|
|
|
POP (proc);
|
|
|
|
|
|
SYNC_ALL ();
|
2010-02-22 23:00:19 +01:00
|
|
|
|
vm_cont = scm_i_vm_capture_stack (vp->stack_base, fp, sp, ip, NULL, 0);
|
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
|
|
|
|
cont = scm_i_make_continuation (&first, vm, vm_cont);
|
2008-09-25 11:07:54 +02:00
|
|
|
|
if (first)
|
|
|
|
|
|
{
|
2011-03-19 23:12:40 +01:00
|
|
|
|
PUSH (0); /* dynamic link */
|
2009-08-15 14:15:56 +02:00
|
|
|
|
PUSH (0); /* mvra */
|
|
|
|
|
|
PUSH (0); /* ra */
|
2008-09-25 11:07:54 +02:00
|
|
|
|
PUSH (proc);
|
|
|
|
|
|
PUSH (cont);
|
|
|
|
|
|
nargs = 1;
|
|
|
|
|
|
goto vm_call;
|
|
|
|
|
|
}
|
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
|
|
|
|
else
|
2008-09-25 11:07:54 +02:00
|
|
|
|
{
|
2010-09-16 12:48:41 +02:00
|
|
|
|
/* Otherwise, the vm continuation was reinstated, and
|
|
|
|
|
|
vm_return_to_continuation pushed on one value. We know only one
|
|
|
|
|
|
value was returned because we are in value context -- the
|
|
|
|
|
|
previous block jumped to vm_call, not vm_mv_call, after all.
|
|
|
|
|
|
|
|
|
|
|
|
So, pull our regs back down from the vp, and march on to the
|
|
|
|
|
|
next instruction. */
|
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
|
|
|
|
CACHE_REGISTER ();
|
|
|
|
|
|
program = SCM_FRAME_PROGRAM (fp);
|
|
|
|
|
|
CACHE_PROGRAM ();
|
2010-09-16 12:48:41 +02:00
|
|
|
|
RESTORE_CONTINUATION_HOOK ();
|
2008-09-25 11:07:54 +02:00
|
|
|
|
NEXT;
|
|
|
|
|
|
}
|
2000-08-22 15:54:19 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (66, tail_call_cc, "tail-call/cc", 0, 1, 1)
|
2008-09-13 19:19:10 +02:00
|
|
|
|
{
|
2008-09-25 11:07:54 +02:00
|
|
|
|
int first;
|
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
|
|
|
|
SCM proc, vm_cont, cont;
|
2008-09-25 11:07:54 +02:00
|
|
|
|
POP (proc);
|
|
|
|
|
|
SYNC_ALL ();
|
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
|
|
|
|
/* In contrast to call/cc, tail-call/cc captures the continuation without the
|
|
|
|
|
|
stack frame. */
|
2010-02-22 23:00:19 +01:00
|
|
|
|
vm_cont = scm_i_vm_capture_stack (vp->stack_base,
|
|
|
|
|
|
SCM_FRAME_DYNAMIC_LINK (fp),
|
|
|
|
|
|
SCM_FRAME_LOWER_ADDRESS (fp) - 1,
|
|
|
|
|
|
SCM_FRAME_RETURN_ADDRESS (fp),
|
|
|
|
|
|
SCM_FRAME_MV_RETURN_ADDRESS (fp),
|
|
|
|
|
|
0);
|
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
|
|
|
|
cont = scm_i_make_continuation (&first, vm, vm_cont);
|
2008-09-25 11:07:54 +02:00
|
|
|
|
if (first)
|
|
|
|
|
|
{
|
|
|
|
|
|
PUSH (proc);
|
|
|
|
|
|
PUSH (cont);
|
|
|
|
|
|
nargs = 1;
|
2010-01-03 14:49:40 +01:00
|
|
|
|
goto vm_tail_call;
|
2008-09-25 11:07:54 +02:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
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
|
|
|
|
/* Otherwise, cache regs and NEXT, as above. Invoking the continuation
|
2010-09-16 12:48:41 +02:00
|
|
|
|
does a return from the frame, either to the RA or
|
|
|
|
|
|
MVRA. */
|
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
|
|
|
|
CACHE_REGISTER ();
|
|
|
|
|
|
program = SCM_FRAME_PROGRAM (fp);
|
|
|
|
|
|
CACHE_PROGRAM ();
|
2010-09-16 12:48:41 +02:00
|
|
|
|
/* Unfortunately we don't know whether we are at the RA, and thus
|
|
|
|
|
|
have one value without an nvalues marker, or we are at the
|
|
|
|
|
|
MVRA and thus have multiple values and the nvalues
|
|
|
|
|
|
marker. Instead of adding heuristics here, we will let hook
|
|
|
|
|
|
client code do that. */
|
|
|
|
|
|
RESTORE_CONTINUATION_HOOK ();
|
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
|
|
|
|
NEXT;
|
2008-09-25 11:07:54 +02:00
|
|
|
|
}
|
2008-09-13 19:19:10 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (67, return, "return", 0, 1, 1)
|
2000-08-22 15:54:19 +00:00
|
|
|
|
{
|
|
|
|
|
|
vm_return:
|
2010-09-16 12:14:55 +02:00
|
|
|
|
POP_CONTINUATION_HOOK (1);
|
2009-12-11 11:15:12 +01:00
|
|
|
|
|
|
|
|
|
|
VM_HANDLE_INTERRUPTS;
|
|
|
|
|
|
|
2008-09-13 14:30:57 +02:00
|
|
|
|
{
|
2009-08-15 14:13:08 +02:00
|
|
|
|
SCM ret;
|
2008-09-13 14:30:57 +02:00
|
|
|
|
|
|
|
|
|
|
POP (ret);
|
runtime and debugging support for callee-parsed procedure args
* libguile/objcodes.h: Bump for metadata format change.
* libguile/frames.h: Rework so we don't frob the program's nargs, nlocs,
etc at runtime. Instead we don't really know what's a local var, an
argument, or an intermediate value. It's a little unfortunate, but
this will allow for case-lambda, and eventually for good polymorphic
generic dispatch; and the nlocs etc can be heuristically
reconstructed. Such a reconstruction would be better done at the
Scheme level, though.
(SCM_FRAME_STACK_ADDRESS): New macro, the pointer to the base of the
stack elements (not counting the program).
(SCM_FRAME_UPPER_ADDRESS): Repurpose to be the address of the last
element in the bookkeeping part of the stack -- i.e. to point to the
return address.
* libguile/vm-engine.h:
* libguile/vm-i-system.c: Adapt to removal of stack_base. Though we
still detect stack-smashing underflow, we don't do so as precisely as
we did before, because now we only detect overwriting of the frame
metadata.
* libguile/vm-engine.c (vm_engine): Remove the stack_base variable. It
is unnecessary, and difficult to keep track of in the face of
case-lambda. Also fix miscommented "ra" and "mvra" pushes. Push the
vp->ip as the first ra...
* libguile/vm-i-system.c (halt): ...because here we can restore the
vp->ip instead of setting ip to 0. Allows us to introspect ips all
down the stack, including in recursive VM invocations.
* libguile/frames.h:
* libguile/frames.c (scm_vm_frame_stack): Removed, because it's getting
more difficult to tell what's an argument and what's a temporary stack
element.
(scm_vm_frame_num_locals): New accessor.
(scm_vm_frame_instruction_pointer): New accessor.
(scm_vm_frame_arguments): Defer to an implementation in Scheme.
(scm_vm_frame_num_locals scm_vm_frame_local_ref)
(scm_vm_frame_local_set_x): Since we can get not-yet-active frames on
the stack now, with our current calling convention, we have to add a
heuristic here to jump over those frames -- because frames have
pointers in them, not Scheme values.
* libguile/programs.h:
* libguile/programs.c (scm_program_arity): Remove, in favor of..
(scm_program_arities): ...this, which a list of arities, in a new
format, occupying a slot in the metadata.
* module/language/assembly/decompile-bytecode.scm (decode-load-program):
Fix mv-call decompilation.
* module/system/vm/frame.scm (vm-frame-bindings, vm-frame-binding-ref)
(vm-frame-binding-set!): New functions, to access bindings by name in
a frame.
(vm-frame-arguments): Function now implemented in Scheme. Commented
fairly extensively.
* module/system/vm/program.scm (program-bindings-by-index)
(program-bindings-for-ip): New accessors, parsing the program bindings
metadata into something more useful.
(program-arities, program-arguments): In a case-lambda world, we have
to assume that programs can have multiple arities. But it's tough to
detect this algorithmically; instead we're going to require that the
program metadata include information about the arities, and the parts
of the program that that metadata applies to.
(program-lambda-list): New accessor.
(write-program): Show multiple arities.
* module/language/glil/compile-assembly.scm (glil->assembly): Add
"arities" to the state of the compiler, and add arities entries as
appropriate.
2009-09-27 19:25:58 -04:00
|
|
|
|
|
|
|
|
|
|
#ifdef VM_ENABLE_STACK_NULLING
|
|
|
|
|
|
SCM *old_sp = sp;
|
|
|
|
|
|
#endif
|
2008-09-13 14:30:57 +02:00
|
|
|
|
|
|
|
|
|
|
/* Restore registers */
|
|
|
|
|
|
sp = SCM_FRAME_LOWER_ADDRESS (fp);
|
2009-08-15 14:13:08 +02:00
|
|
|
|
ip = SCM_FRAME_RETURN_ADDRESS (fp);
|
|
|
|
|
|
fp = SCM_FRAME_DYNAMIC_LINK (fp);
|
runtime and debugging support for callee-parsed procedure args
* libguile/objcodes.h: Bump for metadata format change.
* libguile/frames.h: Rework so we don't frob the program's nargs, nlocs,
etc at runtime. Instead we don't really know what's a local var, an
argument, or an intermediate value. It's a little unfortunate, but
this will allow for case-lambda, and eventually for good polymorphic
generic dispatch; and the nlocs etc can be heuristically
reconstructed. Such a reconstruction would be better done at the
Scheme level, though.
(SCM_FRAME_STACK_ADDRESS): New macro, the pointer to the base of the
stack elements (not counting the program).
(SCM_FRAME_UPPER_ADDRESS): Repurpose to be the address of the last
element in the bookkeeping part of the stack -- i.e. to point to the
return address.
* libguile/vm-engine.h:
* libguile/vm-i-system.c: Adapt to removal of stack_base. Though we
still detect stack-smashing underflow, we don't do so as precisely as
we did before, because now we only detect overwriting of the frame
metadata.
* libguile/vm-engine.c (vm_engine): Remove the stack_base variable. It
is unnecessary, and difficult to keep track of in the face of
case-lambda. Also fix miscommented "ra" and "mvra" pushes. Push the
vp->ip as the first ra...
* libguile/vm-i-system.c (halt): ...because here we can restore the
vp->ip instead of setting ip to 0. Allows us to introspect ips all
down the stack, including in recursive VM invocations.
* libguile/frames.h:
* libguile/frames.c (scm_vm_frame_stack): Removed, because it's getting
more difficult to tell what's an argument and what's a temporary stack
element.
(scm_vm_frame_num_locals): New accessor.
(scm_vm_frame_instruction_pointer): New accessor.
(scm_vm_frame_arguments): Defer to an implementation in Scheme.
(scm_vm_frame_num_locals scm_vm_frame_local_ref)
(scm_vm_frame_local_set_x): Since we can get not-yet-active frames on
the stack now, with our current calling convention, we have to add a
heuristic here to jump over those frames -- because frames have
pointers in them, not Scheme values.
* libguile/programs.h:
* libguile/programs.c (scm_program_arity): Remove, in favor of..
(scm_program_arities): ...this, which a list of arities, in a new
format, occupying a slot in the metadata.
* module/language/assembly/decompile-bytecode.scm (decode-load-program):
Fix mv-call decompilation.
* module/system/vm/frame.scm (vm-frame-bindings, vm-frame-binding-ref)
(vm-frame-binding-set!): New functions, to access bindings by name in
a frame.
(vm-frame-arguments): Function now implemented in Scheme. Commented
fairly extensively.
* module/system/vm/program.scm (program-bindings-by-index)
(program-bindings-for-ip): New accessors, parsing the program bindings
metadata into something more useful.
(program-arities, program-arguments): In a case-lambda world, we have
to assume that programs can have multiple arities. But it's tough to
detect this algorithmically; instead we're going to require that the
program metadata include information about the arities, and the parts
of the program that that metadata applies to.
(program-lambda-list): New accessor.
(write-program): Show multiple arities.
* module/language/glil/compile-assembly.scm (glil->assembly): Add
"arities" to the state of the compiler, and add arities entries as
appropriate.
2009-09-27 19:25:58 -04:00
|
|
|
|
|
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
|
|
|
|
#ifdef VM_ENABLE_STACK_NULLING
|
runtime and debugging support for callee-parsed procedure args
* libguile/objcodes.h: Bump for metadata format change.
* libguile/frames.h: Rework so we don't frob the program's nargs, nlocs,
etc at runtime. Instead we don't really know what's a local var, an
argument, or an intermediate value. It's a little unfortunate, but
this will allow for case-lambda, and eventually for good polymorphic
generic dispatch; and the nlocs etc can be heuristically
reconstructed. Such a reconstruction would be better done at the
Scheme level, though.
(SCM_FRAME_STACK_ADDRESS): New macro, the pointer to the base of the
stack elements (not counting the program).
(SCM_FRAME_UPPER_ADDRESS): Repurpose to be the address of the last
element in the bookkeeping part of the stack -- i.e. to point to the
return address.
* libguile/vm-engine.h:
* libguile/vm-i-system.c: Adapt to removal of stack_base. Though we
still detect stack-smashing underflow, we don't do so as precisely as
we did before, because now we only detect overwriting of the frame
metadata.
* libguile/vm-engine.c (vm_engine): Remove the stack_base variable. It
is unnecessary, and difficult to keep track of in the face of
case-lambda. Also fix miscommented "ra" and "mvra" pushes. Push the
vp->ip as the first ra...
* libguile/vm-i-system.c (halt): ...because here we can restore the
vp->ip instead of setting ip to 0. Allows us to introspect ips all
down the stack, including in recursive VM invocations.
* libguile/frames.h:
* libguile/frames.c (scm_vm_frame_stack): Removed, because it's getting
more difficult to tell what's an argument and what's a temporary stack
element.
(scm_vm_frame_num_locals): New accessor.
(scm_vm_frame_instruction_pointer): New accessor.
(scm_vm_frame_arguments): Defer to an implementation in Scheme.
(scm_vm_frame_num_locals scm_vm_frame_local_ref)
(scm_vm_frame_local_set_x): Since we can get not-yet-active frames on
the stack now, with our current calling convention, we have to add a
heuristic here to jump over those frames -- because frames have
pointers in them, not Scheme values.
* libguile/programs.h:
* libguile/programs.c (scm_program_arity): Remove, in favor of..
(scm_program_arities): ...this, which a list of arities, in a new
format, occupying a slot in the metadata.
* module/language/assembly/decompile-bytecode.scm (decode-load-program):
Fix mv-call decompilation.
* module/system/vm/frame.scm (vm-frame-bindings, vm-frame-binding-ref)
(vm-frame-binding-set!): New functions, to access bindings by name in
a frame.
(vm-frame-arguments): Function now implemented in Scheme. Commented
fairly extensively.
* module/system/vm/program.scm (program-bindings-by-index)
(program-bindings-for-ip): New accessors, parsing the program bindings
metadata into something more useful.
(program-arities, program-arguments): In a case-lambda world, we have
to assume that programs can have multiple arities. But it's tough to
detect this algorithmically; instead we're going to require that the
program metadata include information about the arities, and the parts
of the program that that metadata applies to.
(program-lambda-list): New accessor.
(write-program): Show multiple arities.
* module/language/glil/compile-assembly.scm (glil->assembly): Add
"arities" to the state of the compiler, and add arities entries as
appropriate.
2009-09-27 19:25:58 -04:00
|
|
|
|
NULLSTACK (old_sp - sp);
|
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
|
|
|
|
#endif
|
2008-09-13 14:30:57 +02:00
|
|
|
|
|
|
|
|
|
|
/* Set return value (sp is already pushed) */
|
|
|
|
|
|
*sp = ret;
|
|
|
|
|
|
}
|
2001-04-01 05:03:41 +00:00
|
|
|
|
|
2001-04-06 10:06:32 +00:00
|
|
|
|
/* Restore the last program */
|
2001-04-23 04:28:13 +00:00
|
|
|
|
program = SCM_FRAME_PROGRAM (fp);
|
2001-04-06 05:00:10 +00:00
|
|
|
|
CACHE_PROGRAM ();
|
2008-08-11 18:35:58 +02:00
|
|
|
|
CHECK_IP ();
|
2000-08-22 15:54:19 +00:00
|
|
|
|
NEXT;
|
|
|
|
|
|
}
|
2001-04-01 05:03:41 +00:00
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (68, return_values, "return/values", 1, -1, -1)
|
add multiple values support to the vm
* libguile/vm-engine.c (vm_run): The bootstrap program now uses mv_call,
so as to allow multiple values out of the VM. (It did before, because
multiple values were represented internally as single scm_values
objects, but now that values go on the stack, we need to note the boot
frame as accepting multiple values.)
(vm_error_no_values): New error, happens if you pass no values into a
single-value continuation. Passing more than one is OK though, it just
takes the first one.
* libguile/vm-i-system.c (halt): Assume that someone has pushed the
number of values onto the stack, and package up that number of values
as a scm_values() object, for communication with the interpreter.
(mv-call): New instruction, calls a procedure with a multiple-value
continuation, even handling calls out to the interpreter.
(return/values): New instruction, returns multiple values to the
continuation. If the continuation is single-valued, takes the first
value or errors if there are no values. Otherwise it returns to the
multiple-value return address, pushing the number of values on top of
the values.
* module/system/il/compile.scm (codegen): Compile <ghil-values> forms.
* module/system/il/ghil.scm (<ghil-values>) Add new GHIL data structure
and associated procedures.
* module/language/scheme/translate.scm (custom-transformer-table):
Compile (values .. ) forms into <ghil-values>.
2008-09-14 17:06:52 +02:00
|
|
|
|
{
|
2008-09-15 00:04:34 +02:00
|
|
|
|
/* nvalues declared at top level, because for some reason gcc seems to think
|
|
|
|
|
|
that perhaps it might be used without declaration. Fooey to that, I say. */
|
|
|
|
|
|
nvalues = FETCH ();
|
|
|
|
|
|
vm_return_values:
|
2010-09-16 12:14:55 +02:00
|
|
|
|
POP_CONTINUATION_HOOK (nvalues);
|
2008-09-15 00:04:34 +02:00
|
|
|
|
|
2009-12-20 23:12:34 +01:00
|
|
|
|
VM_HANDLE_INTERRUPTS;
|
|
|
|
|
|
|
2009-08-15 14:13:08 +02:00
|
|
|
|
if (nvalues != 1 && SCM_FRAME_MV_RETURN_ADDRESS (fp))
|
2008-09-15 00:04:34 +02:00
|
|
|
|
{
|
runtime and debugging support for callee-parsed procedure args
* libguile/objcodes.h: Bump for metadata format change.
* libguile/frames.h: Rework so we don't frob the program's nargs, nlocs,
etc at runtime. Instead we don't really know what's a local var, an
argument, or an intermediate value. It's a little unfortunate, but
this will allow for case-lambda, and eventually for good polymorphic
generic dispatch; and the nlocs etc can be heuristically
reconstructed. Such a reconstruction would be better done at the
Scheme level, though.
(SCM_FRAME_STACK_ADDRESS): New macro, the pointer to the base of the
stack elements (not counting the program).
(SCM_FRAME_UPPER_ADDRESS): Repurpose to be the address of the last
element in the bookkeeping part of the stack -- i.e. to point to the
return address.
* libguile/vm-engine.h:
* libguile/vm-i-system.c: Adapt to removal of stack_base. Though we
still detect stack-smashing underflow, we don't do so as precisely as
we did before, because now we only detect overwriting of the frame
metadata.
* libguile/vm-engine.c (vm_engine): Remove the stack_base variable. It
is unnecessary, and difficult to keep track of in the face of
case-lambda. Also fix miscommented "ra" and "mvra" pushes. Push the
vp->ip as the first ra...
* libguile/vm-i-system.c (halt): ...because here we can restore the
vp->ip instead of setting ip to 0. Allows us to introspect ips all
down the stack, including in recursive VM invocations.
* libguile/frames.h:
* libguile/frames.c (scm_vm_frame_stack): Removed, because it's getting
more difficult to tell what's an argument and what's a temporary stack
element.
(scm_vm_frame_num_locals): New accessor.
(scm_vm_frame_instruction_pointer): New accessor.
(scm_vm_frame_arguments): Defer to an implementation in Scheme.
(scm_vm_frame_num_locals scm_vm_frame_local_ref)
(scm_vm_frame_local_set_x): Since we can get not-yet-active frames on
the stack now, with our current calling convention, we have to add a
heuristic here to jump over those frames -- because frames have
pointers in them, not Scheme values.
* libguile/programs.h:
* libguile/programs.c (scm_program_arity): Remove, in favor of..
(scm_program_arities): ...this, which a list of arities, in a new
format, occupying a slot in the metadata.
* module/language/assembly/decompile-bytecode.scm (decode-load-program):
Fix mv-call decompilation.
* module/system/vm/frame.scm (vm-frame-bindings, vm-frame-binding-ref)
(vm-frame-binding-set!): New functions, to access bindings by name in
a frame.
(vm-frame-arguments): Function now implemented in Scheme. Commented
fairly extensively.
* module/system/vm/program.scm (program-bindings-by-index)
(program-bindings-for-ip): New accessors, parsing the program bindings
metadata into something more useful.
(program-arities, program-arguments): In a case-lambda world, we have
to assume that programs can have multiple arities. But it's tough to
detect this algorithmically; instead we're going to require that the
program metadata include information about the arities, and the parts
of the program that that metadata applies to.
(program-lambda-list): New accessor.
(write-program): Show multiple arities.
* module/language/glil/compile-assembly.scm (glil->assembly): Add
"arities" to the state of the compiler, and add arities entries as
appropriate.
2009-09-27 19:25:58 -04:00
|
|
|
|
/* A multiply-valued continuation */
|
|
|
|
|
|
SCM *vals = sp - nvalues;
|
2008-09-15 00:04:34 +02:00
|
|
|
|
int i;
|
|
|
|
|
|
/* Restore registers */
|
|
|
|
|
|
sp = SCM_FRAME_LOWER_ADDRESS (fp) - 1;
|
2009-08-15 14:13:08 +02:00
|
|
|
|
ip = SCM_FRAME_MV_RETURN_ADDRESS (fp);
|
|
|
|
|
|
fp = SCM_FRAME_DYNAMIC_LINK (fp);
|
add multiple values support to the vm
* libguile/vm-engine.c (vm_run): The bootstrap program now uses mv_call,
so as to allow multiple values out of the VM. (It did before, because
multiple values were represented internally as single scm_values
objects, but now that values go on the stack, we need to note the boot
frame as accepting multiple values.)
(vm_error_no_values): New error, happens if you pass no values into a
single-value continuation. Passing more than one is OK though, it just
takes the first one.
* libguile/vm-i-system.c (halt): Assume that someone has pushed the
number of values onto the stack, and package up that number of values
as a scm_values() object, for communication with the interpreter.
(mv-call): New instruction, calls a procedure with a multiple-value
continuation, even handling calls out to the interpreter.
(return/values): New instruction, returns multiple values to the
continuation. If the continuation is single-valued, takes the first
value or errors if there are no values. Otherwise it returns to the
multiple-value return address, pushing the number of values on top of
the values.
* module/system/il/compile.scm (codegen): Compile <ghil-values> forms.
* module/system/il/ghil.scm (<ghil-values>) Add new GHIL data structure
and associated procedures.
* module/language/scheme/translate.scm (custom-transformer-table):
Compile (values .. ) forms into <ghil-values>.
2008-09-14 17:06:52 +02:00
|
|
|
|
|
2008-09-15 00:04:34 +02:00
|
|
|
|
/* Push return values, and the number of values */
|
|
|
|
|
|
for (i = 0; i < nvalues; i++)
|
runtime and debugging support for callee-parsed procedure args
* libguile/objcodes.h: Bump for metadata format change.
* libguile/frames.h: Rework so we don't frob the program's nargs, nlocs,
etc at runtime. Instead we don't really know what's a local var, an
argument, or an intermediate value. It's a little unfortunate, but
this will allow for case-lambda, and eventually for good polymorphic
generic dispatch; and the nlocs etc can be heuristically
reconstructed. Such a reconstruction would be better done at the
Scheme level, though.
(SCM_FRAME_STACK_ADDRESS): New macro, the pointer to the base of the
stack elements (not counting the program).
(SCM_FRAME_UPPER_ADDRESS): Repurpose to be the address of the last
element in the bookkeeping part of the stack -- i.e. to point to the
return address.
* libguile/vm-engine.h:
* libguile/vm-i-system.c: Adapt to removal of stack_base. Though we
still detect stack-smashing underflow, we don't do so as precisely as
we did before, because now we only detect overwriting of the frame
metadata.
* libguile/vm-engine.c (vm_engine): Remove the stack_base variable. It
is unnecessary, and difficult to keep track of in the face of
case-lambda. Also fix miscommented "ra" and "mvra" pushes. Push the
vp->ip as the first ra...
* libguile/vm-i-system.c (halt): ...because here we can restore the
vp->ip instead of setting ip to 0. Allows us to introspect ips all
down the stack, including in recursive VM invocations.
* libguile/frames.h:
* libguile/frames.c (scm_vm_frame_stack): Removed, because it's getting
more difficult to tell what's an argument and what's a temporary stack
element.
(scm_vm_frame_num_locals): New accessor.
(scm_vm_frame_instruction_pointer): New accessor.
(scm_vm_frame_arguments): Defer to an implementation in Scheme.
(scm_vm_frame_num_locals scm_vm_frame_local_ref)
(scm_vm_frame_local_set_x): Since we can get not-yet-active frames on
the stack now, with our current calling convention, we have to add a
heuristic here to jump over those frames -- because frames have
pointers in them, not Scheme values.
* libguile/programs.h:
* libguile/programs.c (scm_program_arity): Remove, in favor of..
(scm_program_arities): ...this, which a list of arities, in a new
format, occupying a slot in the metadata.
* module/language/assembly/decompile-bytecode.scm (decode-load-program):
Fix mv-call decompilation.
* module/system/vm/frame.scm (vm-frame-bindings, vm-frame-binding-ref)
(vm-frame-binding-set!): New functions, to access bindings by name in
a frame.
(vm-frame-arguments): Function now implemented in Scheme. Commented
fairly extensively.
* module/system/vm/program.scm (program-bindings-by-index)
(program-bindings-for-ip): New accessors, parsing the program bindings
metadata into something more useful.
(program-arities, program-arguments): In a case-lambda world, we have
to assume that programs can have multiple arities. But it's tough to
detect this algorithmically; instead we're going to require that the
program metadata include information about the arities, and the parts
of the program that that metadata applies to.
(program-lambda-list): New accessor.
(write-program): Show multiple arities.
* module/language/glil/compile-assembly.scm (glil->assembly): Add
"arities" to the state of the compiler, and add arities entries as
appropriate.
2009-09-27 19:25:58 -04:00
|
|
|
|
*++sp = vals[i+1];
|
2008-09-15 00:04:34 +02:00
|
|
|
|
*++sp = SCM_I_MAKINUM (nvalues);
|
add multiple values support to the vm
* libguile/vm-engine.c (vm_run): The bootstrap program now uses mv_call,
so as to allow multiple values out of the VM. (It did before, because
multiple values were represented internally as single scm_values
objects, but now that values go on the stack, we need to note the boot
frame as accepting multiple values.)
(vm_error_no_values): New error, happens if you pass no values into a
single-value continuation. Passing more than one is OK though, it just
takes the first one.
* libguile/vm-i-system.c (halt): Assume that someone has pushed the
number of values onto the stack, and package up that number of values
as a scm_values() object, for communication with the interpreter.
(mv-call): New instruction, calls a procedure with a multiple-value
continuation, even handling calls out to the interpreter.
(return/values): New instruction, returns multiple values to the
continuation. If the continuation is single-valued, takes the first
value or errors if there are no values. Otherwise it returns to the
multiple-value return address, pushing the number of values on top of
the values.
* module/system/il/compile.scm (codegen): Compile <ghil-values> forms.
* module/system/il/ghil.scm (<ghil-values>) Add new GHIL data structure
and associated procedures.
* module/language/scheme/translate.scm (custom-transformer-table):
Compile (values .. ) forms into <ghil-values>.
2008-09-14 17:06:52 +02:00
|
|
|
|
|
runtime and debugging support for callee-parsed procedure args
* libguile/objcodes.h: Bump for metadata format change.
* libguile/frames.h: Rework so we don't frob the program's nargs, nlocs,
etc at runtime. Instead we don't really know what's a local var, an
argument, or an intermediate value. It's a little unfortunate, but
this will allow for case-lambda, and eventually for good polymorphic
generic dispatch; and the nlocs etc can be heuristically
reconstructed. Such a reconstruction would be better done at the
Scheme level, though.
(SCM_FRAME_STACK_ADDRESS): New macro, the pointer to the base of the
stack elements (not counting the program).
(SCM_FRAME_UPPER_ADDRESS): Repurpose to be the address of the last
element in the bookkeeping part of the stack -- i.e. to point to the
return address.
* libguile/vm-engine.h:
* libguile/vm-i-system.c: Adapt to removal of stack_base. Though we
still detect stack-smashing underflow, we don't do so as precisely as
we did before, because now we only detect overwriting of the frame
metadata.
* libguile/vm-engine.c (vm_engine): Remove the stack_base variable. It
is unnecessary, and difficult to keep track of in the face of
case-lambda. Also fix miscommented "ra" and "mvra" pushes. Push the
vp->ip as the first ra...
* libguile/vm-i-system.c (halt): ...because here we can restore the
vp->ip instead of setting ip to 0. Allows us to introspect ips all
down the stack, including in recursive VM invocations.
* libguile/frames.h:
* libguile/frames.c (scm_vm_frame_stack): Removed, because it's getting
more difficult to tell what's an argument and what's a temporary stack
element.
(scm_vm_frame_num_locals): New accessor.
(scm_vm_frame_instruction_pointer): New accessor.
(scm_vm_frame_arguments): Defer to an implementation in Scheme.
(scm_vm_frame_num_locals scm_vm_frame_local_ref)
(scm_vm_frame_local_set_x): Since we can get not-yet-active frames on
the stack now, with our current calling convention, we have to add a
heuristic here to jump over those frames -- because frames have
pointers in them, not Scheme values.
* libguile/programs.h:
* libguile/programs.c (scm_program_arity): Remove, in favor of..
(scm_program_arities): ...this, which a list of arities, in a new
format, occupying a slot in the metadata.
* module/language/assembly/decompile-bytecode.scm (decode-load-program):
Fix mv-call decompilation.
* module/system/vm/frame.scm (vm-frame-bindings, vm-frame-binding-ref)
(vm-frame-binding-set!): New functions, to access bindings by name in
a frame.
(vm-frame-arguments): Function now implemented in Scheme. Commented
fairly extensively.
* module/system/vm/program.scm (program-bindings-by-index)
(program-bindings-for-ip): New accessors, parsing the program bindings
metadata into something more useful.
(program-arities, program-arguments): In a case-lambda world, we have
to assume that programs can have multiple arities. But it's tough to
detect this algorithmically; instead we're going to require that the
program metadata include information about the arities, and the parts
of the program that that metadata applies to.
(program-lambda-list): New accessor.
(write-program): Show multiple arities.
* module/language/glil/compile-assembly.scm (glil->assembly): Add
"arities" to the state of the compiler, and add arities entries as
appropriate.
2009-09-27 19:25:58 -04:00
|
|
|
|
/* Finally null the end of the stack */
|
|
|
|
|
|
NULLSTACK (vals + nvalues - sp);
|
2008-09-15 00:04:34 +02:00
|
|
|
|
}
|
|
|
|
|
|
else if (nvalues >= 1)
|
|
|
|
|
|
{
|
|
|
|
|
|
/* Multiple values for a single-valued continuation -- here's where I
|
|
|
|
|
|
break with guile tradition and try and do something sensible. (Also,
|
|
|
|
|
|
this block handles the single-valued return to an mv
|
|
|
|
|
|
continuation.) */
|
runtime and debugging support for callee-parsed procedure args
* libguile/objcodes.h: Bump for metadata format change.
* libguile/frames.h: Rework so we don't frob the program's nargs, nlocs,
etc at runtime. Instead we don't really know what's a local var, an
argument, or an intermediate value. It's a little unfortunate, but
this will allow for case-lambda, and eventually for good polymorphic
generic dispatch; and the nlocs etc can be heuristically
reconstructed. Such a reconstruction would be better done at the
Scheme level, though.
(SCM_FRAME_STACK_ADDRESS): New macro, the pointer to the base of the
stack elements (not counting the program).
(SCM_FRAME_UPPER_ADDRESS): Repurpose to be the address of the last
element in the bookkeeping part of the stack -- i.e. to point to the
return address.
* libguile/vm-engine.h:
* libguile/vm-i-system.c: Adapt to removal of stack_base. Though we
still detect stack-smashing underflow, we don't do so as precisely as
we did before, because now we only detect overwriting of the frame
metadata.
* libguile/vm-engine.c (vm_engine): Remove the stack_base variable. It
is unnecessary, and difficult to keep track of in the face of
case-lambda. Also fix miscommented "ra" and "mvra" pushes. Push the
vp->ip as the first ra...
* libguile/vm-i-system.c (halt): ...because here we can restore the
vp->ip instead of setting ip to 0. Allows us to introspect ips all
down the stack, including in recursive VM invocations.
* libguile/frames.h:
* libguile/frames.c (scm_vm_frame_stack): Removed, because it's getting
more difficult to tell what's an argument and what's a temporary stack
element.
(scm_vm_frame_num_locals): New accessor.
(scm_vm_frame_instruction_pointer): New accessor.
(scm_vm_frame_arguments): Defer to an implementation in Scheme.
(scm_vm_frame_num_locals scm_vm_frame_local_ref)
(scm_vm_frame_local_set_x): Since we can get not-yet-active frames on
the stack now, with our current calling convention, we have to add a
heuristic here to jump over those frames -- because frames have
pointers in them, not Scheme values.
* libguile/programs.h:
* libguile/programs.c (scm_program_arity): Remove, in favor of..
(scm_program_arities): ...this, which a list of arities, in a new
format, occupying a slot in the metadata.
* module/language/assembly/decompile-bytecode.scm (decode-load-program):
Fix mv-call decompilation.
* module/system/vm/frame.scm (vm-frame-bindings, vm-frame-binding-ref)
(vm-frame-binding-set!): New functions, to access bindings by name in
a frame.
(vm-frame-arguments): Function now implemented in Scheme. Commented
fairly extensively.
* module/system/vm/program.scm (program-bindings-by-index)
(program-bindings-for-ip): New accessors, parsing the program bindings
metadata into something more useful.
(program-arities, program-arguments): In a case-lambda world, we have
to assume that programs can have multiple arities. But it's tough to
detect this algorithmically; instead we're going to require that the
program metadata include information about the arities, and the parts
of the program that that metadata applies to.
(program-lambda-list): New accessor.
(write-program): Show multiple arities.
* module/language/glil/compile-assembly.scm (glil->assembly): Add
"arities" to the state of the compiler, and add arities entries as
appropriate.
2009-09-27 19:25:58 -04:00
|
|
|
|
SCM *vals = sp - nvalues;
|
2008-09-15 00:04:34 +02:00
|
|
|
|
/* Restore registers */
|
|
|
|
|
|
sp = SCM_FRAME_LOWER_ADDRESS (fp) - 1;
|
2009-08-15 14:13:08 +02:00
|
|
|
|
ip = SCM_FRAME_RETURN_ADDRESS (fp);
|
|
|
|
|
|
fp = SCM_FRAME_DYNAMIC_LINK (fp);
|
add multiple values support to the vm
* libguile/vm-engine.c (vm_run): The bootstrap program now uses mv_call,
so as to allow multiple values out of the VM. (It did before, because
multiple values were represented internally as single scm_values
objects, but now that values go on the stack, we need to note the boot
frame as accepting multiple values.)
(vm_error_no_values): New error, happens if you pass no values into a
single-value continuation. Passing more than one is OK though, it just
takes the first one.
* libguile/vm-i-system.c (halt): Assume that someone has pushed the
number of values onto the stack, and package up that number of values
as a scm_values() object, for communication with the interpreter.
(mv-call): New instruction, calls a procedure with a multiple-value
continuation, even handling calls out to the interpreter.
(return/values): New instruction, returns multiple values to the
continuation. If the continuation is single-valued, takes the first
value or errors if there are no values. Otherwise it returns to the
multiple-value return address, pushing the number of values on top of
the values.
* module/system/il/compile.scm (codegen): Compile <ghil-values> forms.
* module/system/il/ghil.scm (<ghil-values>) Add new GHIL data structure
and associated procedures.
* module/language/scheme/translate.scm (custom-transformer-table):
Compile (values .. ) forms into <ghil-values>.
2008-09-14 17:06:52 +02:00
|
|
|
|
|
2008-09-15 00:04:34 +02:00
|
|
|
|
/* Push first value */
|
runtime and debugging support for callee-parsed procedure args
* libguile/objcodes.h: Bump for metadata format change.
* libguile/frames.h: Rework so we don't frob the program's nargs, nlocs,
etc at runtime. Instead we don't really know what's a local var, an
argument, or an intermediate value. It's a little unfortunate, but
this will allow for case-lambda, and eventually for good polymorphic
generic dispatch; and the nlocs etc can be heuristically
reconstructed. Such a reconstruction would be better done at the
Scheme level, though.
(SCM_FRAME_STACK_ADDRESS): New macro, the pointer to the base of the
stack elements (not counting the program).
(SCM_FRAME_UPPER_ADDRESS): Repurpose to be the address of the last
element in the bookkeeping part of the stack -- i.e. to point to the
return address.
* libguile/vm-engine.h:
* libguile/vm-i-system.c: Adapt to removal of stack_base. Though we
still detect stack-smashing underflow, we don't do so as precisely as
we did before, because now we only detect overwriting of the frame
metadata.
* libguile/vm-engine.c (vm_engine): Remove the stack_base variable. It
is unnecessary, and difficult to keep track of in the face of
case-lambda. Also fix miscommented "ra" and "mvra" pushes. Push the
vp->ip as the first ra...
* libguile/vm-i-system.c (halt): ...because here we can restore the
vp->ip instead of setting ip to 0. Allows us to introspect ips all
down the stack, including in recursive VM invocations.
* libguile/frames.h:
* libguile/frames.c (scm_vm_frame_stack): Removed, because it's getting
more difficult to tell what's an argument and what's a temporary stack
element.
(scm_vm_frame_num_locals): New accessor.
(scm_vm_frame_instruction_pointer): New accessor.
(scm_vm_frame_arguments): Defer to an implementation in Scheme.
(scm_vm_frame_num_locals scm_vm_frame_local_ref)
(scm_vm_frame_local_set_x): Since we can get not-yet-active frames on
the stack now, with our current calling convention, we have to add a
heuristic here to jump over those frames -- because frames have
pointers in them, not Scheme values.
* libguile/programs.h:
* libguile/programs.c (scm_program_arity): Remove, in favor of..
(scm_program_arities): ...this, which a list of arities, in a new
format, occupying a slot in the metadata.
* module/language/assembly/decompile-bytecode.scm (decode-load-program):
Fix mv-call decompilation.
* module/system/vm/frame.scm (vm-frame-bindings, vm-frame-binding-ref)
(vm-frame-binding-set!): New functions, to access bindings by name in
a frame.
(vm-frame-arguments): Function now implemented in Scheme. Commented
fairly extensively.
* module/system/vm/program.scm (program-bindings-by-index)
(program-bindings-for-ip): New accessors, parsing the program bindings
metadata into something more useful.
(program-arities, program-arguments): In a case-lambda world, we have
to assume that programs can have multiple arities. But it's tough to
detect this algorithmically; instead we're going to require that the
program metadata include information about the arities, and the parts
of the program that that metadata applies to.
(program-lambda-list): New accessor.
(write-program): Show multiple arities.
* module/language/glil/compile-assembly.scm (glil->assembly): Add
"arities" to the state of the compiler, and add arities entries as
appropriate.
2009-09-27 19:25:58 -04:00
|
|
|
|
*++sp = vals[1];
|
add multiple values support to the vm
* libguile/vm-engine.c (vm_run): The bootstrap program now uses mv_call,
so as to allow multiple values out of the VM. (It did before, because
multiple values were represented internally as single scm_values
objects, but now that values go on the stack, we need to note the boot
frame as accepting multiple values.)
(vm_error_no_values): New error, happens if you pass no values into a
single-value continuation. Passing more than one is OK though, it just
takes the first one.
* libguile/vm-i-system.c (halt): Assume that someone has pushed the
number of values onto the stack, and package up that number of values
as a scm_values() object, for communication with the interpreter.
(mv-call): New instruction, calls a procedure with a multiple-value
continuation, even handling calls out to the interpreter.
(return/values): New instruction, returns multiple values to the
continuation. If the continuation is single-valued, takes the first
value or errors if there are no values. Otherwise it returns to the
multiple-value return address, pushing the number of values on top of
the values.
* module/system/il/compile.scm (codegen): Compile <ghil-values> forms.
* module/system/il/ghil.scm (<ghil-values>) Add new GHIL data structure
and associated procedures.
* module/language/scheme/translate.scm (custom-transformer-table):
Compile (values .. ) forms into <ghil-values>.
2008-09-14 17:06:52 +02:00
|
|
|
|
|
runtime and debugging support for callee-parsed procedure args
* libguile/objcodes.h: Bump for metadata format change.
* libguile/frames.h: Rework so we don't frob the program's nargs, nlocs,
etc at runtime. Instead we don't really know what's a local var, an
argument, or an intermediate value. It's a little unfortunate, but
this will allow for case-lambda, and eventually for good polymorphic
generic dispatch; and the nlocs etc can be heuristically
reconstructed. Such a reconstruction would be better done at the
Scheme level, though.
(SCM_FRAME_STACK_ADDRESS): New macro, the pointer to the base of the
stack elements (not counting the program).
(SCM_FRAME_UPPER_ADDRESS): Repurpose to be the address of the last
element in the bookkeeping part of the stack -- i.e. to point to the
return address.
* libguile/vm-engine.h:
* libguile/vm-i-system.c: Adapt to removal of stack_base. Though we
still detect stack-smashing underflow, we don't do so as precisely as
we did before, because now we only detect overwriting of the frame
metadata.
* libguile/vm-engine.c (vm_engine): Remove the stack_base variable. It
is unnecessary, and difficult to keep track of in the face of
case-lambda. Also fix miscommented "ra" and "mvra" pushes. Push the
vp->ip as the first ra...
* libguile/vm-i-system.c (halt): ...because here we can restore the
vp->ip instead of setting ip to 0. Allows us to introspect ips all
down the stack, including in recursive VM invocations.
* libguile/frames.h:
* libguile/frames.c (scm_vm_frame_stack): Removed, because it's getting
more difficult to tell what's an argument and what's a temporary stack
element.
(scm_vm_frame_num_locals): New accessor.
(scm_vm_frame_instruction_pointer): New accessor.
(scm_vm_frame_arguments): Defer to an implementation in Scheme.
(scm_vm_frame_num_locals scm_vm_frame_local_ref)
(scm_vm_frame_local_set_x): Since we can get not-yet-active frames on
the stack now, with our current calling convention, we have to add a
heuristic here to jump over those frames -- because frames have
pointers in them, not Scheme values.
* libguile/programs.h:
* libguile/programs.c (scm_program_arity): Remove, in favor of..
(scm_program_arities): ...this, which a list of arities, in a new
format, occupying a slot in the metadata.
* module/language/assembly/decompile-bytecode.scm (decode-load-program):
Fix mv-call decompilation.
* module/system/vm/frame.scm (vm-frame-bindings, vm-frame-binding-ref)
(vm-frame-binding-set!): New functions, to access bindings by name in
a frame.
(vm-frame-arguments): Function now implemented in Scheme. Commented
fairly extensively.
* module/system/vm/program.scm (program-bindings-by-index)
(program-bindings-for-ip): New accessors, parsing the program bindings
metadata into something more useful.
(program-arities, program-arguments): In a case-lambda world, we have
to assume that programs can have multiple arities. But it's tough to
detect this algorithmically; instead we're going to require that the
program metadata include information about the arities, and the parts
of the program that that metadata applies to.
(program-lambda-list): New accessor.
(write-program): Show multiple arities.
* module/language/glil/compile-assembly.scm (glil->assembly): Add
"arities" to the state of the compiler, and add arities entries as
appropriate.
2009-09-27 19:25:58 -04:00
|
|
|
|
/* Finally null the end of the stack */
|
|
|
|
|
|
NULLSTACK (vals + nvalues - sp);
|
2008-09-15 00:04:34 +02:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
goto vm_error_no_values;
|
add multiple values support to the vm
* libguile/vm-engine.c (vm_run): The bootstrap program now uses mv_call,
so as to allow multiple values out of the VM. (It did before, because
multiple values were represented internally as single scm_values
objects, but now that values go on the stack, we need to note the boot
frame as accepting multiple values.)
(vm_error_no_values): New error, happens if you pass no values into a
single-value continuation. Passing more than one is OK though, it just
takes the first one.
* libguile/vm-i-system.c (halt): Assume that someone has pushed the
number of values onto the stack, and package up that number of values
as a scm_values() object, for communication with the interpreter.
(mv-call): New instruction, calls a procedure with a multiple-value
continuation, even handling calls out to the interpreter.
(return/values): New instruction, returns multiple values to the
continuation. If the continuation is single-valued, takes the first
value or errors if there are no values. Otherwise it returns to the
multiple-value return address, pushing the number of values on top of
the values.
* module/system/il/compile.scm (codegen): Compile <ghil-values> forms.
* module/system/il/ghil.scm (<ghil-values>) Add new GHIL data structure
and associated procedures.
* module/language/scheme/translate.scm (custom-transformer-table):
Compile (values .. ) forms into <ghil-values>.
2008-09-14 17:06:52 +02:00
|
|
|
|
|
|
|
|
|
|
/* Restore the last program */
|
|
|
|
|
|
program = SCM_FRAME_PROGRAM (fp);
|
|
|
|
|
|
CACHE_PROGRAM ();
|
|
|
|
|
|
CHECK_IP ();
|
|
|
|
|
|
NEXT;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (69, return_values_star, "return/values*", 1, -1, -1)
|
2008-09-15 00:04:34 +02:00
|
|
|
|
{
|
|
|
|
|
|
SCM l;
|
|
|
|
|
|
|
|
|
|
|
|
nvalues = FETCH ();
|
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
|
|
|
|
ASSERT (nvalues >= 1);
|
2008-09-15 00:04:34 +02:00
|
|
|
|
|
|
|
|
|
|
nvalues--;
|
|
|
|
|
|
POP (l);
|
2009-11-25 23:46:17 +01:00
|
|
|
|
while (scm_is_pair (l))
|
2008-09-15 00:04:34 +02:00
|
|
|
|
{
|
|
|
|
|
|
PUSH (SCM_CAR (l));
|
|
|
|
|
|
l = SCM_CDR (l);
|
|
|
|
|
|
nvalues++;
|
|
|
|
|
|
}
|
2009-01-04 14:06:52 +01:00
|
|
|
|
if (SCM_UNLIKELY (!SCM_NULL_OR_NIL_P (l))) {
|
2009-02-05 12:28:19 +01:00
|
|
|
|
finish_args = scm_list_1 (l);
|
2009-01-04 14:06:52 +01:00
|
|
|
|
goto vm_error_improper_list;
|
|
|
|
|
|
}
|
2008-09-15 00:04:34 +02:00
|
|
|
|
|
|
|
|
|
|
goto vm_return_values;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (70, return_nvalues, "return/nvalues", 0, 1, -1)
|
2010-01-31 10:44:44 +01:00
|
|
|
|
{
|
|
|
|
|
|
SCM n;
|
|
|
|
|
|
POP (n);
|
|
|
|
|
|
nvalues = scm_to_int (n);
|
|
|
|
|
|
ASSERT (nvalues >= 0);
|
|
|
|
|
|
goto vm_return_values;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (71, truncate_values, "truncate-values", 2, -1, -1)
|
lambda-lifting for (lambda () ...) as consumer of call-with-values
* libguile/vm-engine.c (vm_run): Add new error case,
vm_error_not_enough_values.
* libguile/vm-i-system.c (goto/nargs, call/nargs): So, in these cases, if
we get too many values, we don't truncate the values like we do in the
single-value continuation case, or in the mvbind case. What to do? I
guess we either truncate them here, or only allow the correct number of
values. Dunno. Mark the code as a fixme.
(truncate-values): New instruction, for mv-bind: checks that the number
of values on the stack is compatible with the number of bindings we
have arranged for them, truncating if necessary.
* module/language/scheme/translate.scm (custom-transformer-table):
Compile receive as a primary form -- not so much because it is a
primary form, but more to test the mv-bind machinery. Also it's more
efficient, I think.
* module/system/il/compile.scm (lift-variables!): New helper, factored
out of `optimize'.
(optimize): Add a few more cases. Adapt `lambda' optimization, which
isn't much. I'm not happy with ghil as a mungeable language.
Add a case for call-with-values with the second argument is
a lambda: lift the lambda. Untested.
(codegen): Refactor the push-bindings! code. Compile mv-bind.
* module/system/il/ghil.scm (<ghil-mv-bind>): Add mv-bind construct,
along with its procedures.
* module/system/il/glil.scm (<glil-mv-bind>): Add mv-bind construct,
different from the high-level one. It makes sense in the source, I
think.
* module/system/vm/assemble.scm (codegen): Assemble glil-mv-bind by
pushing onto the bindings list, and actually push some code to truncate
the values.
2008-09-18 22:49:55 +02:00
|
|
|
|
{
|
|
|
|
|
|
SCM x;
|
|
|
|
|
|
int nbinds, rest;
|
|
|
|
|
|
POP (x);
|
|
|
|
|
|
nvalues = scm_to_int (x);
|
|
|
|
|
|
nbinds = FETCH ();
|
|
|
|
|
|
rest = FETCH ();
|
|
|
|
|
|
|
|
|
|
|
|
if (rest)
|
|
|
|
|
|
nbinds--;
|
|
|
|
|
|
|
|
|
|
|
|
if (nvalues < nbinds)
|
|
|
|
|
|
goto vm_error_not_enough_values;
|
|
|
|
|
|
|
|
|
|
|
|
if (rest)
|
|
|
|
|
|
POP_LIST (nvalues - nbinds);
|
|
|
|
|
|
else
|
|
|
|
|
|
DROPN (nvalues - nbinds);
|
|
|
|
|
|
|
|
|
|
|
|
NEXT;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (72, box, "box", 1, 1, 0)
|
2009-06-05 12:08:02 +02:00
|
|
|
|
{
|
2009-07-19 19:48:26 +02:00
|
|
|
|
SCM val;
|
|
|
|
|
|
POP (val);
|
|
|
|
|
|
SYNC_BEFORE_GC ();
|
|
|
|
|
|
LOCAL_SET (FETCH (), scm_cell (scm_tc7_variable, SCM_UNPACK (val)));
|
2009-06-05 12:08:02 +02:00
|
|
|
|
NEXT;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2009-07-19 19:48:26 +02:00
|
|
|
|
/* for letrec:
|
|
|
|
|
|
(let ((a *undef*) (b *undef*) ...)
|
|
|
|
|
|
(set! a (lambda () (b ...)))
|
|
|
|
|
|
...)
|
|
|
|
|
|
*/
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (73, empty_box, "empty-box", 1, 0, 0)
|
2009-06-05 12:08:02 +02:00
|
|
|
|
{
|
2009-07-19 19:48:26 +02:00
|
|
|
|
SYNC_BEFORE_GC ();
|
|
|
|
|
|
LOCAL_SET (FETCH (),
|
|
|
|
|
|
scm_cell (scm_tc7_variable, SCM_UNPACK (SCM_UNDEFINED)));
|
|
|
|
|
|
NEXT;
|
|
|
|
|
|
}
|
2009-06-05 12:08:02 +02:00
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (74, local_boxed_ref, "local-boxed-ref", 1, 0, 1)
|
2009-07-19 19:48:26 +02:00
|
|
|
|
{
|
|
|
|
|
|
SCM v = LOCAL_REF (FETCH ());
|
|
|
|
|
|
ASSERT_BOUND_VARIABLE (v);
|
|
|
|
|
|
PUSH (VARIABLE_REF (v));
|
|
|
|
|
|
NEXT;
|
|
|
|
|
|
}
|
2009-06-05 12:08:02 +02:00
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (75, local_boxed_set, "local-boxed-set", 1, 1, 0)
|
2009-07-19 19:48:26 +02:00
|
|
|
|
{
|
|
|
|
|
|
SCM v, val;
|
|
|
|
|
|
v = LOCAL_REF (FETCH ());
|
|
|
|
|
|
POP (val);
|
|
|
|
|
|
ASSERT_VARIABLE (v);
|
|
|
|
|
|
VARIABLE_SET (v, val);
|
2009-06-05 12:08:02 +02:00
|
|
|
|
NEXT;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (76, free_ref, "free-ref", 1, 0, 1)
|
2009-06-05 12:08:02 +02:00
|
|
|
|
{
|
2009-07-19 19:48:26 +02:00
|
|
|
|
scm_t_uint8 idx = FETCH ();
|
|
|
|
|
|
|
2009-07-23 14:36:22 +02:00
|
|
|
|
CHECK_FREE_VARIABLE (idx);
|
|
|
|
|
|
PUSH (FREE_VARIABLE_REF (idx));
|
2009-07-19 19:48:26 +02:00
|
|
|
|
NEXT;
|
|
|
|
|
|
}
|
2009-06-05 12:08:02 +02:00
|
|
|
|
|
2009-07-23 14:36:22 +02:00
|
|
|
|
/* no free-set -- if a var is assigned, it should be in a box */
|
2009-06-05 12:08:02 +02:00
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (77, free_boxed_ref, "free-boxed-ref", 1, 0, 1)
|
2009-07-19 19:48:26 +02:00
|
|
|
|
{
|
|
|
|
|
|
SCM v;
|
|
|
|
|
|
scm_t_uint8 idx = FETCH ();
|
2009-07-23 14:36:22 +02:00
|
|
|
|
CHECK_FREE_VARIABLE (idx);
|
|
|
|
|
|
v = FREE_VARIABLE_REF (idx);
|
2009-07-19 19:48:26 +02:00
|
|
|
|
ASSERT_BOUND_VARIABLE (v);
|
|
|
|
|
|
PUSH (VARIABLE_REF (v));
|
|
|
|
|
|
NEXT;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (78, free_boxed_set, "free-boxed-set", 1, 1, 0)
|
2009-07-19 19:48:26 +02:00
|
|
|
|
{
|
|
|
|
|
|
SCM v, val;
|
|
|
|
|
|
scm_t_uint8 idx = FETCH ();
|
|
|
|
|
|
POP (val);
|
2009-07-23 14:36:22 +02:00
|
|
|
|
CHECK_FREE_VARIABLE (idx);
|
|
|
|
|
|
v = FREE_VARIABLE_REF (idx);
|
2009-07-19 19:48:26 +02:00
|
|
|
|
ASSERT_BOUND_VARIABLE (v);
|
|
|
|
|
|
VARIABLE_SET (v, val);
|
|
|
|
|
|
NEXT;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (79, make_closure, "make-closure", 2, -1, 1)
|
2009-07-19 19:48:26 +02:00
|
|
|
|
{
|
allocate free variables inline to closures
* libguile/_scm.h (SCM_OBJCODE_MINOR_VERSION): Bump.
* libguile/programs.h (SCM_PROGRAM_FREE_VARIABLES)
(SCM_PROGRAM_FREE_VARIABLE_REF, SCM_PROGRAM_FREE_VARIABLE_SET)
(SCM_PROGRAM_NUM_FREE_VARIABLES):
* libguile/programs.c (scm_make_program, scm_program_num_free_variables)
(scm_program_free_variable_ref, scm_program_free_variable_set_x):
Allocate free variables inline with programs, instead of being in a
vect. Should improve locality, and require fewer local variables in
the VM.
* libguile/vm-engine.c (vm_engine): Remove free_vars and free_vars_count
variables.
* libguile/vm-engine.h (CACHE_PROGRAM): No need to muck with free_vars
and free_vars_count.
(CHECK_FREE_VARIABLE): Update for inline free vars.
* libguile/vm-i-system.c (FREE_VARIABLE_REF): Update for inline free
vars.
(make-closure, fix-closure): Take the closure vals as separate stack
args, and copy or fix them inline into the appropriate closure.
* module/language/objcode/spec.scm (program-free-variables): Define a
local version of this removed function.
* module/language/tree-il/compile-glil.scm (flatten): Adjust to not make
a vector when making closures.
* module/system/vm/program.scm: Export program-num-free-variables,
program-free-variable-ref, program-free-variable-set!, and remove
program-free-variables.
* test-suite/tests/tree-il.test ("lambda"): Update to not make vectors
when making closures.
2010-01-09 16:42:27 +01:00
|
|
|
|
size_t n, len;
|
|
|
|
|
|
SCM closure;
|
|
|
|
|
|
|
|
|
|
|
|
len = FETCH ();
|
|
|
|
|
|
len <<= 8;
|
|
|
|
|
|
len += FETCH ();
|
2009-07-19 19:48:26 +02:00
|
|
|
|
SYNC_BEFORE_GC ();
|
allocate free variables inline to closures
* libguile/_scm.h (SCM_OBJCODE_MINOR_VERSION): Bump.
* libguile/programs.h (SCM_PROGRAM_FREE_VARIABLES)
(SCM_PROGRAM_FREE_VARIABLE_REF, SCM_PROGRAM_FREE_VARIABLE_SET)
(SCM_PROGRAM_NUM_FREE_VARIABLES):
* libguile/programs.c (scm_make_program, scm_program_num_free_variables)
(scm_program_free_variable_ref, scm_program_free_variable_set_x):
Allocate free variables inline with programs, instead of being in a
vect. Should improve locality, and require fewer local variables in
the VM.
* libguile/vm-engine.c (vm_engine): Remove free_vars and free_vars_count
variables.
* libguile/vm-engine.h (CACHE_PROGRAM): No need to muck with free_vars
and free_vars_count.
(CHECK_FREE_VARIABLE): Update for inline free vars.
* libguile/vm-i-system.c (FREE_VARIABLE_REF): Update for inline free
vars.
(make-closure, fix-closure): Take the closure vals as separate stack
args, and copy or fix them inline into the appropriate closure.
* module/language/objcode/spec.scm (program-free-variables): Define a
local version of this removed function.
* module/language/tree-il/compile-glil.scm (flatten): Adjust to not make
a vector when making closures.
* module/system/vm/program.scm: Export program-num-free-variables,
program-free-variable-ref, program-free-variable-set!, and remove
program-free-variables.
* test-suite/tests/tree-il.test ("lambda"): Update to not make vectors
when making closures.
2010-01-09 16:42:27 +01:00
|
|
|
|
closure = scm_words (scm_tc7_program | (len<<16), len + 3);
|
|
|
|
|
|
SCM_SET_CELL_OBJECT_1 (closure, SCM_PROGRAM_OBJCODE (sp[-len]));
|
|
|
|
|
|
SCM_SET_CELL_OBJECT_2 (closure, SCM_PROGRAM_OBJTABLE (sp[-len]));
|
|
|
|
|
|
sp[-len] = closure;
|
|
|
|
|
|
for (n = 0; n < len; n++)
|
|
|
|
|
|
SCM_PROGRAM_FREE_VARIABLE_SET (closure, n, sp[-len + 1 + n]);
|
|
|
|
|
|
DROPN (len);
|
2009-06-05 12:08:02 +02:00
|
|
|
|
NEXT;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (80, make_variable, "make-variable", 0, 0, 1)
|
2009-07-24 11:00:32 +02:00
|
|
|
|
{
|
|
|
|
|
|
SYNC_BEFORE_GC ();
|
|
|
|
|
|
/* fixme underflow */
|
|
|
|
|
|
PUSH (scm_cell (scm_tc7_variable, SCM_UNPACK (SCM_UNDEFINED)));
|
|
|
|
|
|
NEXT;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (81, fix_closure, "fix-closure", 2, -1, 0)
|
add <fix> tree-il construct, and compile it
* libguile/vm-i-system.c (fix-closure): New instruction, for wiring
together fixpoint procedures.
* module/Makefile.am (TREE_IL_LANG_SOURCES): Add fix-letrec.scm.
* module/language/glil/compile-assembly.scm (glil->assembly): Reindent
the <glil-lexical> case, and handle 'fix for locally-bound vars.
* module/language/tree-il.scm (<fix>): Add the <fix> tree-il type and
accessors, for fixed-point bindings. This IL construct is taken from
the Waddell paper.
(parse-tree-il, unparse-tree-il, tree-il->scheme, tree-il-fold)
(pre-order!, post-order!): Update for <fix>.
* module/language/tree-il/analyze.scm (analyze-lexicals): Update for
<fix>. The difference here is that the bindings may not be assigned,
and are not marked as such. They are not boxed.
(report-unused-variables): Update for <fix>.
* module/language/tree-il/compile-glil.scm (flatten): Compile <fix> to
GLIL.
* module/language/tree-il/fix-letrec.scm: A stub implementation of
fixing letrec -- will flesh out in a separate commit.
* module/language/tree-il/inline.scm: Fix license, it was mistakenly
added with LGPL v2.1+.
* module/language/tree-il/optimize.scm (optimize!): Run the fix-letrec!
pass.
2009-08-05 17:51:40 +02:00
|
|
|
|
{
|
allocate free variables inline to closures
* libguile/_scm.h (SCM_OBJCODE_MINOR_VERSION): Bump.
* libguile/programs.h (SCM_PROGRAM_FREE_VARIABLES)
(SCM_PROGRAM_FREE_VARIABLE_REF, SCM_PROGRAM_FREE_VARIABLE_SET)
(SCM_PROGRAM_NUM_FREE_VARIABLES):
* libguile/programs.c (scm_make_program, scm_program_num_free_variables)
(scm_program_free_variable_ref, scm_program_free_variable_set_x):
Allocate free variables inline with programs, instead of being in a
vect. Should improve locality, and require fewer local variables in
the VM.
* libguile/vm-engine.c (vm_engine): Remove free_vars and free_vars_count
variables.
* libguile/vm-engine.h (CACHE_PROGRAM): No need to muck with free_vars
and free_vars_count.
(CHECK_FREE_VARIABLE): Update for inline free vars.
* libguile/vm-i-system.c (FREE_VARIABLE_REF): Update for inline free
vars.
(make-closure, fix-closure): Take the closure vals as separate stack
args, and copy or fix them inline into the appropriate closure.
* module/language/objcode/spec.scm (program-free-variables): Define a
local version of this removed function.
* module/language/tree-il/compile-glil.scm (flatten): Adjust to not make
a vector when making closures.
* module/system/vm/program.scm: Export program-num-free-variables,
program-free-variable-ref, program-free-variable-set!, and remove
program-free-variables.
* test-suite/tests/tree-il.test ("lambda"): Update to not make vectors
when making closures.
2010-01-09 16:42:27 +01:00
|
|
|
|
SCM x;
|
add <fix> tree-il construct, and compile it
* libguile/vm-i-system.c (fix-closure): New instruction, for wiring
together fixpoint procedures.
* module/Makefile.am (TREE_IL_LANG_SOURCES): Add fix-letrec.scm.
* module/language/glil/compile-assembly.scm (glil->assembly): Reindent
the <glil-lexical> case, and handle 'fix for locally-bound vars.
* module/language/tree-il.scm (<fix>): Add the <fix> tree-il type and
accessors, for fixed-point bindings. This IL construct is taken from
the Waddell paper.
(parse-tree-il, unparse-tree-il, tree-il->scheme, tree-il-fold)
(pre-order!, post-order!): Update for <fix>.
* module/language/tree-il/analyze.scm (analyze-lexicals): Update for
<fix>. The difference here is that the bindings may not be assigned,
and are not marked as such. They are not boxed.
(report-unused-variables): Update for <fix>.
* module/language/tree-il/compile-glil.scm (flatten): Compile <fix> to
GLIL.
* module/language/tree-il/fix-letrec.scm: A stub implementation of
fixing letrec -- will flesh out in a separate commit.
* module/language/tree-il/inline.scm: Fix license, it was mistakenly
added with LGPL v2.1+.
* module/language/tree-il/optimize.scm (optimize!): Run the fix-letrec!
pass.
2009-08-05 17:51:40 +02:00
|
|
|
|
unsigned int i = FETCH ();
|
allocate free variables inline to closures
* libguile/_scm.h (SCM_OBJCODE_MINOR_VERSION): Bump.
* libguile/programs.h (SCM_PROGRAM_FREE_VARIABLES)
(SCM_PROGRAM_FREE_VARIABLE_REF, SCM_PROGRAM_FREE_VARIABLE_SET)
(SCM_PROGRAM_NUM_FREE_VARIABLES):
* libguile/programs.c (scm_make_program, scm_program_num_free_variables)
(scm_program_free_variable_ref, scm_program_free_variable_set_x):
Allocate free variables inline with programs, instead of being in a
vect. Should improve locality, and require fewer local variables in
the VM.
* libguile/vm-engine.c (vm_engine): Remove free_vars and free_vars_count
variables.
* libguile/vm-engine.h (CACHE_PROGRAM): No need to muck with free_vars
and free_vars_count.
(CHECK_FREE_VARIABLE): Update for inline free vars.
* libguile/vm-i-system.c (FREE_VARIABLE_REF): Update for inline free
vars.
(make-closure, fix-closure): Take the closure vals as separate stack
args, and copy or fix them inline into the appropriate closure.
* module/language/objcode/spec.scm (program-free-variables): Define a
local version of this removed function.
* module/language/tree-il/compile-glil.scm (flatten): Adjust to not make
a vector when making closures.
* module/system/vm/program.scm: Export program-num-free-variables,
program-free-variable-ref, program-free-variable-set!, and remove
program-free-variables.
* test-suite/tests/tree-il.test ("lambda"): Update to not make vectors
when making closures.
2010-01-09 16:42:27 +01:00
|
|
|
|
size_t n, len;
|
add <fix> tree-il construct, and compile it
* libguile/vm-i-system.c (fix-closure): New instruction, for wiring
together fixpoint procedures.
* module/Makefile.am (TREE_IL_LANG_SOURCES): Add fix-letrec.scm.
* module/language/glil/compile-assembly.scm (glil->assembly): Reindent
the <glil-lexical> case, and handle 'fix for locally-bound vars.
* module/language/tree-il.scm (<fix>): Add the <fix> tree-il type and
accessors, for fixed-point bindings. This IL construct is taken from
the Waddell paper.
(parse-tree-il, unparse-tree-il, tree-il->scheme, tree-il-fold)
(pre-order!, post-order!): Update for <fix>.
* module/language/tree-il/analyze.scm (analyze-lexicals): Update for
<fix>. The difference here is that the bindings may not be assigned,
and are not marked as such. They are not boxed.
(report-unused-variables): Update for <fix>.
* module/language/tree-il/compile-glil.scm (flatten): Compile <fix> to
GLIL.
* module/language/tree-il/fix-letrec.scm: A stub implementation of
fixing letrec -- will flesh out in a separate commit.
* module/language/tree-il/inline.scm: Fix license, it was mistakenly
added with LGPL v2.1+.
* module/language/tree-il/optimize.scm (optimize!): Run the fix-letrec!
pass.
2009-08-05 17:51:40 +02:00
|
|
|
|
i <<= 8;
|
|
|
|
|
|
i += FETCH ();
|
|
|
|
|
|
/* FIXME CHECK_LOCAL (i) */
|
|
|
|
|
|
x = LOCAL_REF (i);
|
|
|
|
|
|
/* FIXME ASSERT_PROGRAM (x); */
|
allocate free variables inline to closures
* libguile/_scm.h (SCM_OBJCODE_MINOR_VERSION): Bump.
* libguile/programs.h (SCM_PROGRAM_FREE_VARIABLES)
(SCM_PROGRAM_FREE_VARIABLE_REF, SCM_PROGRAM_FREE_VARIABLE_SET)
(SCM_PROGRAM_NUM_FREE_VARIABLES):
* libguile/programs.c (scm_make_program, scm_program_num_free_variables)
(scm_program_free_variable_ref, scm_program_free_variable_set_x):
Allocate free variables inline with programs, instead of being in a
vect. Should improve locality, and require fewer local variables in
the VM.
* libguile/vm-engine.c (vm_engine): Remove free_vars and free_vars_count
variables.
* libguile/vm-engine.h (CACHE_PROGRAM): No need to muck with free_vars
and free_vars_count.
(CHECK_FREE_VARIABLE): Update for inline free vars.
* libguile/vm-i-system.c (FREE_VARIABLE_REF): Update for inline free
vars.
(make-closure, fix-closure): Take the closure vals as separate stack
args, and copy or fix them inline into the appropriate closure.
* module/language/objcode/spec.scm (program-free-variables): Define a
local version of this removed function.
* module/language/tree-il/compile-glil.scm (flatten): Adjust to not make
a vector when making closures.
* module/system/vm/program.scm: Export program-num-free-variables,
program-free-variable-ref, program-free-variable-set!, and remove
program-free-variables.
* test-suite/tests/tree-il.test ("lambda"): Update to not make vectors
when making closures.
2010-01-09 16:42:27 +01:00
|
|
|
|
len = SCM_PROGRAM_NUM_FREE_VARIABLES (x);
|
|
|
|
|
|
for (n = 0; n < len; n++)
|
|
|
|
|
|
SCM_PROGRAM_FREE_VARIABLE_SET (x, n, sp[-len + 1 + n]);
|
|
|
|
|
|
DROPN (len);
|
add <fix> tree-il construct, and compile it
* libguile/vm-i-system.c (fix-closure): New instruction, for wiring
together fixpoint procedures.
* module/Makefile.am (TREE_IL_LANG_SOURCES): Add fix-letrec.scm.
* module/language/glil/compile-assembly.scm (glil->assembly): Reindent
the <glil-lexical> case, and handle 'fix for locally-bound vars.
* module/language/tree-il.scm (<fix>): Add the <fix> tree-il type and
accessors, for fixed-point bindings. This IL construct is taken from
the Waddell paper.
(parse-tree-il, unparse-tree-il, tree-il->scheme, tree-il-fold)
(pre-order!, post-order!): Update for <fix>.
* module/language/tree-il/analyze.scm (analyze-lexicals): Update for
<fix>. The difference here is that the bindings may not be assigned,
and are not marked as such. They are not boxed.
(report-unused-variables): Update for <fix>.
* module/language/tree-il/compile-glil.scm (flatten): Compile <fix> to
GLIL.
* module/language/tree-il/fix-letrec.scm: A stub implementation of
fixing letrec -- will flesh out in a separate commit.
* module/language/tree-il/inline.scm: Fix license, it was mistakenly
added with LGPL v2.1+.
* module/language/tree-il/optimize.scm (optimize!): Run the fix-letrec!
pass.
2009-08-05 17:51:40 +02:00
|
|
|
|
NEXT;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (82, define, "define", 0, 0, 2)
|
2009-08-12 16:33:49 +02:00
|
|
|
|
{
|
|
|
|
|
|
SCM sym, val;
|
VM tweaks
* libguile/vm-engine.c (VM_CHECK_OBJECT, VM_CHECK_FREE_VARIABLES): Set
to 0 for both engines. These are really internal debugging variables,
which don't affect user-visible features, provided that the compiler
is correct of course.
(VM_CHECK_UNDERFLOW): New var, also off by default: whether to check
for stack underflow when popping values.
(vm_engine): Don't declare object_count if we are not checking object
table accesses.
* libguile/vm-engine.h (CACHE_PROGRAM): Don't muck with object_count
if we are not checking object table accesses.
(CHECK_UNDERFLOW, PRE_CHECK_UNDERFLOW): Nop out if we are not checking
underflow.
(POP2, POP3): New macros which check for underflow before popping more
than one value.
* libguile/vm-i-loader.c (load_array):
* libguile/vm-i-scheme.c (set_car, set_cdr, vector_set, slot_set)
(BV_SET_WITH_ENDIANNESS, BV_FIXABLE_INT_SET, BV_INT_SET)
(BV_FLOAT_SET):
* libguile/vm-i-system.c (partial_cont_call, fix_closure, prompt)
(fluid_set): Use POP2 / POP3.
(local_set, long_local_set): Pop to locals instead of using values on
the stack then dropping; allows for underflow to be checked before the
value is accessed.
(BR): Don't NULLSTACK or DROP after the operation.
(br_if, br_if_not, br_if_eq, br_if_not_eq, br_if_null)
(br_if_not_null): Pop to locals before doing the compare and jump.
2011-05-05 14:04:23 +02:00
|
|
|
|
POP2 (sym, val);
|
2009-08-12 16:33:49 +02:00
|
|
|
|
SYNC_REGISTER ();
|
|
|
|
|
|
VARIABLE_SET (scm_sym2var (sym, scm_current_module_lookup_closure (),
|
|
|
|
|
|
SCM_BOOL_T),
|
|
|
|
|
|
val);
|
|
|
|
|
|
NEXT;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (83, make_keyword, "make-keyword", 0, 1, 1)
|
2009-08-12 16:33:49 +02:00
|
|
|
|
{
|
|
|
|
|
|
CHECK_UNDERFLOW ();
|
|
|
|
|
|
SYNC_REGISTER ();
|
|
|
|
|
|
*sp = scm_symbol_to_keyword (*sp);
|
|
|
|
|
|
NEXT;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (84, make_symbol, "make-symbol", 0, 1, 1)
|
2009-08-12 16:33:49 +02:00
|
|
|
|
{
|
|
|
|
|
|
CHECK_UNDERFLOW ();
|
|
|
|
|
|
SYNC_REGISTER ();
|
|
|
|
|
|
*sp = scm_string_to_symbol (*sp);
|
|
|
|
|
|
NEXT;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (85, prompt, "prompt", 4, 2, 0)
|
2010-01-30 15:45:37 +01:00
|
|
|
|
{
|
|
|
|
|
|
scm_t_int32 offset;
|
2010-02-19 15:30:34 +01:00
|
|
|
|
scm_t_uint8 escape_only_p;
|
prompt as part of guile's primitive language
* libguile/control.h:
* libguile/control.c: Remove scm_atcontrol and scm_atprompt.
(scm_c_make_prompt): Remove handler arg, as the handler is inline.
(scm_abort): New primitive, exported to Scheme as `abort'. The
compiler will also recognize calls to `abort', but this is the base
case.
(scm_init_control): Remove scm_register_control, just have this
function, which adds `abort' to the `(guile)' module.
* libguile/eval.c (eval): Add SCM_M_PROMPT case.
* libguile/init.c (scm_i_init_guile): Change scm_register_control call
into a nice orderly scm_init_control call.
* libguile/memoize.h: (scm_sym_at_prompt, SCM_M_PROMPT):
* libguile/memoize.c (MAKMEMO_PROMPT, scm_m_at_prompt, unmemoize): Add
prompt support to the memoizer.
* libguile/vm-i-system.c (prompt): Fix to not expect a handler on the
stack.
* module/ice-9/boot-9.scm (prompt): Add definition in terms of @prompt.
* module/ice-9/control.scm: Simplify, and don't play with the compiler
here, now that prompt and abort are primitive.
* module/ice-9/eval.scm (primitive-eval): Add a prompt case.
* module/language/tree-il/primitives.scm
(*interesting-primitive-names*): Add @prompt and prompt.
2010-02-19 22:44:24 +01:00
|
|
|
|
SCM k, prompt;
|
2010-01-30 15:45:37 +01:00
|
|
|
|
|
|
|
|
|
|
escape_only_p = FETCH ();
|
|
|
|
|
|
FETCH_OFFSET (offset);
|
|
|
|
|
|
POP (k);
|
|
|
|
|
|
|
|
|
|
|
|
SYNC_REGISTER ();
|
2010-02-25 17:33:12 +01:00
|
|
|
|
/* Push the prompt onto the dynamic stack. */
|
2010-02-26 13:05:25 +01:00
|
|
|
|
prompt = scm_c_make_prompt (k, fp, sp, ip + offset, escape_only_p, vm_cookie,
|
|
|
|
|
|
scm_i_dynwinds ());
|
|
|
|
|
|
scm_i_set_dynwinds (scm_cons (prompt, SCM_PROMPT_DYNWINDS (prompt)));
|
2010-02-02 22:59:55 +01:00
|
|
|
|
if (SCM_PROMPT_SETJMP (prompt))
|
2010-01-30 15:45:37 +01:00
|
|
|
|
{
|
|
|
|
|
|
/* The prompt exited nonlocally. Cache the regs back from the vp, and go
|
2010-02-19 15:30:34 +01:00
|
|
|
|
to the handler.
|
2010-02-25 17:33:12 +01:00
|
|
|
|
|
|
|
|
|
|
Note, at this point, we must assume that any variable local to
|
|
|
|
|
|
vm_engine that can be assigned *has* been assigned. So we need to pull
|
|
|
|
|
|
all our state back from the ip/fp/sp.
|
2010-02-19 15:30:34 +01:00
|
|
|
|
*/
|
2010-02-25 17:33:12 +01:00
|
|
|
|
CACHE_REGISTER ();
|
|
|
|
|
|
program = SCM_FRAME_PROGRAM (fp);
|
|
|
|
|
|
CACHE_PROGRAM ();
|
2010-09-16 12:48:41 +02:00
|
|
|
|
/* The stack contains the values returned to this prompt, along
|
|
|
|
|
|
with a number-of-values marker -- like an MV return. */
|
|
|
|
|
|
ABORT_CONTINUATION_HOOK ();
|
2010-01-30 15:45:37 +01:00
|
|
|
|
NEXT;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Otherwise setjmp returned for the first time, so we go to execute the
|
|
|
|
|
|
prompt's body. */
|
|
|
|
|
|
NEXT;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (86, wind, "wind", 0, 2, 0)
|
2010-01-30 15:45:37 +01:00
|
|
|
|
{
|
|
|
|
|
|
SCM wind, unwind;
|
VM tweaks
* libguile/vm-engine.c (VM_CHECK_OBJECT, VM_CHECK_FREE_VARIABLES): Set
to 0 for both engines. These are really internal debugging variables,
which don't affect user-visible features, provided that the compiler
is correct of course.
(VM_CHECK_UNDERFLOW): New var, also off by default: whether to check
for stack underflow when popping values.
(vm_engine): Don't declare object_count if we are not checking object
table accesses.
* libguile/vm-engine.h (CACHE_PROGRAM): Don't muck with object_count
if we are not checking object table accesses.
(CHECK_UNDERFLOW, PRE_CHECK_UNDERFLOW): Nop out if we are not checking
underflow.
(POP2, POP3): New macros which check for underflow before popping more
than one value.
* libguile/vm-i-loader.c (load_array):
* libguile/vm-i-scheme.c (set_car, set_cdr, vector_set, slot_set)
(BV_SET_WITH_ENDIANNESS, BV_FIXABLE_INT_SET, BV_INT_SET)
(BV_FLOAT_SET):
* libguile/vm-i-system.c (partial_cont_call, fix_closure, prompt)
(fluid_set): Use POP2 / POP3.
(local_set, long_local_set): Pop to locals instead of using values on
the stack then dropping; allows for underflow to be checked before the
value is accessed.
(BR): Don't NULLSTACK or DROP after the operation.
(br_if, br_if_not, br_if_eq, br_if_not_eq, br_if_null)
(br_if_not_null): Pop to locals before doing the compare and jump.
2011-05-05 14:04:23 +02:00
|
|
|
|
POP2 (unwind, wind);
|
2010-01-30 15:45:37 +01:00
|
|
|
|
SYNC_REGISTER ();
|
|
|
|
|
|
/* Push wind and unwind procedures onto the dynamic stack. Note that neither
|
|
|
|
|
|
are actually called; the compiler should emit calls to wind and unwind for
|
|
|
|
|
|
the normal dynamic-wind control flow. */
|
|
|
|
|
|
if (SCM_UNLIKELY (scm_is_false (scm_thunk_p (wind))))
|
|
|
|
|
|
{
|
|
|
|
|
|
finish_args = wind;
|
|
|
|
|
|
goto vm_error_not_a_thunk;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (SCM_UNLIKELY (scm_is_false (scm_thunk_p (unwind))))
|
|
|
|
|
|
{
|
|
|
|
|
|
finish_args = unwind;
|
|
|
|
|
|
goto vm_error_not_a_thunk;
|
|
|
|
|
|
}
|
|
|
|
|
|
scm_i_set_dynwinds (scm_cons (scm_cons (wind, unwind), scm_i_dynwinds ()));
|
|
|
|
|
|
NEXT;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (87, abort, "abort", 1, -1, -1)
|
2010-01-30 15:45:37 +01:00
|
|
|
|
{
|
|
|
|
|
|
unsigned n = FETCH ();
|
|
|
|
|
|
SYNC_REGISTER ();
|
abort always dispatches to VM bytecode, to detect same-invocation aborts
* libguile/control.h:
* libguile/control.c (scm_c_make_prompt): Take an extra arg, a cookie.
Continuations will be rewindable only if the abort has the same cookie
as the prompt.
(scm_at_abort): Redefine from scm_abort, and instead of taking rest
args, take the abort values as a list directly. Also, don't allow
rewinding, because we won't support rewinding the C stack with
delimited continuations.
* libguile/eval.c (eval): Adapt to scm_c_make_prompt change.
* libguile/vm-engine.c (vm_engine): Use vp->cookie to get a unique value
corresponding to this VM invocation.
* libguile/vm-i-system.c (prompt): Pass the cookie to scm_c_make_prompt.
(abort): Take an additional tail arg.
* libguile/vm.c (vm_abort): Parse out the abort tail arg. This is for
the @abort case, or the (apply abort ...) case.
(make_vm): Initialize the cookie to 0.
* libguile/vm.h (struct scm_vm): Add cookie.
* module/ice-9/boot-9.scm (abort): Define here as a trampoline to
@abort. Needed to make sure that a call to abort dispatches to a VM
opcode, so the cookie will be the same.
* module/language/tree-il.scm (<tree-il>): Add a "tail" field to
<abort>, for the (apply abort ...) case, or (@abort tag args). Should
be #<const ()> in the normal case. Add support throughout.
* module/language/tree-il/analyze.scm (analyze-lexicals): Add abort-tail
support here too.
* module/language/tree-il/compile-glil.scm (flatten): Compile the tail
argument appropriately.
* module/language/tree-il/primitives.scm (*primitive-expand-table*): Fix
@abort and abort cases to pass the tail arg to make-abort.
2010-02-22 21:53:24 +01:00
|
|
|
|
if (sp - n - 2 <= SCM_FRAME_UPPER_ADDRESS (fp))
|
2010-02-19 16:55:36 +01:00
|
|
|
|
goto vm_error_stack_underflow;
|
2010-02-22 23:00:19 +01:00
|
|
|
|
vm_abort (vm, n, vm_cookie);
|
2010-02-19 10:49:24 +01:00
|
|
|
|
/* vm_abort should not return */
|
2010-01-30 15:45:37 +01:00
|
|
|
|
abort ();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (88, unwind, "unwind", 0, 0, 0)
|
2010-01-30 15:45:37 +01:00
|
|
|
|
{
|
|
|
|
|
|
/* A normal exit from the dynamic extent of an expression. Pop the top entry
|
|
|
|
|
|
off of the dynamic stack. */
|
|
|
|
|
|
scm_i_set_dynwinds (scm_cdr (scm_i_dynwinds ()));
|
|
|
|
|
|
NEXT;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (89, wind_fluids, "wind-fluids", 1, -1, 0)
|
2010-02-18 18:42:54 +01:00
|
|
|
|
{
|
|
|
|
|
|
unsigned n = FETCH ();
|
|
|
|
|
|
SCM wf;
|
|
|
|
|
|
|
2010-03-16 15:55:24 +01:00
|
|
|
|
SYNC_REGISTER ();
|
2010-10-13 21:18:44 +02:00
|
|
|
|
sp -= 2 * n;
|
|
|
|
|
|
CHECK_UNDERFLOW ();
|
|
|
|
|
|
wf = scm_i_make_with_fluids (n, sp + 1, sp + 1 + n);
|
|
|
|
|
|
NULLSTACK (2 * n);
|
|
|
|
|
|
|
2011-05-06 00:17:35 +02:00
|
|
|
|
scm_i_swap_with_fluids (wf, current_thread->dynamic_state);
|
2010-02-18 18:42:54 +01:00
|
|
|
|
scm_i_set_dynwinds (scm_cons (wf, scm_i_dynwinds ()));
|
|
|
|
|
|
NEXT;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (90, unwind_fluids, "unwind-fluids", 0, 0, 0)
|
2010-02-18 18:42:54 +01:00
|
|
|
|
{
|
|
|
|
|
|
SCM wf;
|
|
|
|
|
|
wf = scm_car (scm_i_dynwinds ());
|
|
|
|
|
|
scm_i_set_dynwinds (scm_cdr (scm_i_dynwinds ()));
|
2011-05-06 00:17:35 +02:00
|
|
|
|
scm_i_swap_with_fluids (wf, current_thread->dynamic_state);
|
2010-02-18 18:42:54 +01:00
|
|
|
|
NEXT;
|
|
|
|
|
|
}
|
2010-01-30 15:45:37 +01:00
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (91, fluid_ref, "fluid-ref", 0, 1, 1)
|
2010-02-19 11:40:09 +01:00
|
|
|
|
{
|
|
|
|
|
|
size_t num;
|
|
|
|
|
|
SCM fluids;
|
|
|
|
|
|
|
|
|
|
|
|
CHECK_UNDERFLOW ();
|
2011-05-06 00:17:35 +02:00
|
|
|
|
fluids = SCM_I_DYNAMIC_STATE_FLUIDS (current_thread->dynamic_state);
|
2010-07-17 12:10:52 +02:00
|
|
|
|
if (SCM_UNLIKELY (!SCM_FLUID_P (*sp))
|
2010-02-19 11:40:09 +01:00
|
|
|
|
|| ((num = SCM_I_FLUID_NUM (*sp)) >= SCM_SIMPLE_VECTOR_LENGTH (fluids)))
|
|
|
|
|
|
{
|
|
|
|
|
|
/* Punt dynstate expansion and error handling to the C proc. */
|
|
|
|
|
|
SYNC_REGISTER ();
|
|
|
|
|
|
*sp = scm_fluid_ref (*sp);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
2010-08-14 18:35:17 -04:00
|
|
|
|
{
|
|
|
|
|
|
SCM val = SCM_SIMPLE_VECTOR_REF (fluids, num);
|
scm_is_eq for SCM vals, not == or !=
* libguile/bytevectors.c (scm_make_bytevector, STRING_TO_UTF)
(UTF_TO_STRING):
* libguile/continuations.c (scm_i_check_continuation):
* libguile/expand.h (SCM_EXPANDED_P):
* libguile/fluids.c (scm_i_make_with_fluids):
* libguile/generalized-vectors.c (scm_make_generalized_vector):
* libguile/goops.c (SCM_GOOPS_UNBOUNDP, slot_definition_using_name):
(scm_c_extend_primitive_generic, more_specificp, scm_make)
* libguile/i18n.c (SCM_VALIDATE_OPTIONAL_LOCALE_COPY):
(scm_locale_string_to_integer)
* libguile/modules.c (resolve_duplicate_binding):
(scm_module_reverse_lookup)
* libguile/posix.c (scm_to_resource):
* libguile/r6rs-ports.c (scm_put_bytevector):
* libguile/socket.c (scm_connect, scm_bind, scm_sendto
* libguile/stacks.c (find_prompt):
* libguile/variable.c (scm_variable_ref, scm_variable_bound_p):
* libguile/vm-engine.h (ASSERT_BOUND_VARIABLE, ASSERT_BOUND)
* libguile/vm-i-system.c (VARIABLE_BOUNDP, local_bound)
(long_local_bound, fluid_ref): Use scm_is_eq to compare, not == / !=.
2011-05-13 12:42:01 +02:00
|
|
|
|
if (SCM_UNLIKELY (scm_is_eq (val, SCM_UNDEFINED)))
|
2010-08-14 18:35:17 -04:00
|
|
|
|
{
|
|
|
|
|
|
finish_args = *sp;
|
|
|
|
|
|
goto vm_error_unbound_fluid;
|
|
|
|
|
|
}
|
|
|
|
|
|
*sp = val;
|
|
|
|
|
|
}
|
2010-02-19 11:40:09 +01:00
|
|
|
|
|
|
|
|
|
|
NEXT;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (92, fluid_set, "fluid-set", 0, 2, 0)
|
2010-02-19 11:40:09 +01:00
|
|
|
|
{
|
|
|
|
|
|
size_t num;
|
|
|
|
|
|
SCM val, fluid, fluids;
|
|
|
|
|
|
|
VM tweaks
* libguile/vm-engine.c (VM_CHECK_OBJECT, VM_CHECK_FREE_VARIABLES): Set
to 0 for both engines. These are really internal debugging variables,
which don't affect user-visible features, provided that the compiler
is correct of course.
(VM_CHECK_UNDERFLOW): New var, also off by default: whether to check
for stack underflow when popping values.
(vm_engine): Don't declare object_count if we are not checking object
table accesses.
* libguile/vm-engine.h (CACHE_PROGRAM): Don't muck with object_count
if we are not checking object table accesses.
(CHECK_UNDERFLOW, PRE_CHECK_UNDERFLOW): Nop out if we are not checking
underflow.
(POP2, POP3): New macros which check for underflow before popping more
than one value.
* libguile/vm-i-loader.c (load_array):
* libguile/vm-i-scheme.c (set_car, set_cdr, vector_set, slot_set)
(BV_SET_WITH_ENDIANNESS, BV_FIXABLE_INT_SET, BV_INT_SET)
(BV_FLOAT_SET):
* libguile/vm-i-system.c (partial_cont_call, fix_closure, prompt)
(fluid_set): Use POP2 / POP3.
(local_set, long_local_set): Pop to locals instead of using values on
the stack then dropping; allows for underflow to be checked before the
value is accessed.
(BR): Don't NULLSTACK or DROP after the operation.
(br_if, br_if_not, br_if_eq, br_if_not_eq, br_if_null)
(br_if_not_null): Pop to locals before doing the compare and jump.
2011-05-05 14:04:23 +02:00
|
|
|
|
POP2 (val, fluid);
|
2011-05-06 00:17:35 +02:00
|
|
|
|
fluids = SCM_I_DYNAMIC_STATE_FLUIDS (current_thread->dynamic_state);
|
2010-07-17 12:10:52 +02:00
|
|
|
|
if (SCM_UNLIKELY (!SCM_FLUID_P (fluid))
|
2010-02-19 11:40:09 +01:00
|
|
|
|
|| ((num = SCM_I_FLUID_NUM (fluid)) >= SCM_SIMPLE_VECTOR_LENGTH (fluids)))
|
|
|
|
|
|
{
|
|
|
|
|
|
/* Punt dynstate expansion and error handling to the C proc. */
|
|
|
|
|
|
SYNC_REGISTER ();
|
|
|
|
|
|
scm_fluid_set_x (fluid, val);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
SCM_SIMPLE_VECTOR_SET (fluids, num, val);
|
|
|
|
|
|
|
|
|
|
|
|
NEXT;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2010-10-08 11:30:17 +02:00
|
|
|
|
VM_DEFINE_INSTRUCTION (93, assert_nargs_ee_locals, "assert-nargs-ee/locals", 1, 0, 0)
|
2010-05-02 13:41:31 +02:00
|
|
|
|
{
|
|
|
|
|
|
scm_t_ptrdiff n;
|
|
|
|
|
|
SCM *old_sp;
|
|
|
|
|
|
|
|
|
|
|
|
/* nargs = n & 0x7, nlocs = nargs + (n >> 3) */
|
|
|
|
|
|
n = FETCH ();
|
|
|
|
|
|
|
|
|
|
|
|
if (SCM_UNLIKELY (sp - (fp - 1) != (n & 0x7)))
|
|
|
|
|
|
goto vm_error_wrong_num_args;
|
|
|
|
|
|
|
|
|
|
|
|
old_sp = sp;
|
|
|
|
|
|
sp += (n >> 3);
|
|
|
|
|
|
CHECK_OVERFLOW ();
|
|
|
|
|
|
while (old_sp < sp)
|
|
|
|
|
|
*++old_sp = SCM_UNDEFINED;
|
|
|
|
|
|
|
|
|
|
|
|
NEXT;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2009-07-19 19:48:26 +02:00
|
|
|
|
|
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
|
|
|
|
/*
|
|
|
|
|
|
(defun renumber-ops ()
|
|
|
|
|
|
"start from top of buffer and renumber 'VM_DEFINE_FOO (\n' sequences"
|
|
|
|
|
|
(interactive "")
|
|
|
|
|
|
(save-excursion
|
|
|
|
|
|
(let ((counter -1)) (goto-char (point-min))
|
|
|
|
|
|
(while (re-search-forward "^VM_DEFINE_[^ ]+ (\\([^,]+\\)," (point-max) t)
|
|
|
|
|
|
(replace-match
|
|
|
|
|
|
(number-to-string (setq counter (1+ counter)))
|
|
|
|
|
|
t t nil 1)))))
|
2009-08-27 19:26:04 +02:00
|
|
|
|
(renumber-ops)
|
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
|
|
|
|
*/
|
2001-04-01 05:03:41 +00:00
|
|
|
|
/*
|
|
|
|
|
|
Local Variables:
|
|
|
|
|
|
c-file-style: "gnu"
|
|
|
|
|
|
End:
|
|
|
|
|
|
*/
|