summaryrefslogtreecommitdiff
path: root/libguile/vm-engine.h
AgeCommit message (Collapse)AuthorFilesLines
2011-07-06VM: Keep jump table address in a register.Ludovic Courtès1-0/+8
* libguile/vm-engine.c (VM_NAME)[HAVE_LABELS_AS_VALUES]: Rename `jump_table' to `jump_table_pointer'. Add `jump_table' as a local variable, initialize it. * libguile/vm-engine.h (JT_REG): New macro.
2011-05-13scm_is_eq for SCM vals, not == or !=Andy Wingo1-2/+2
* 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-06avoid tls gets when handling interrupts in the vmAndy Wingo1-1/+1
* libguile/__scm.h (SCM_ASYNC_TICK_WITH_CODE): Redefine to take a scm_i_thread* as well. OK to do because it's within a BUILDING_LIBGUILE block. * libguile/vm-engine.c (vm_engine): Cache the scm_i_thread* instead of the dynstate, so we can use the thread for ticks. * libguile/vm-engine.h (VM_HANDLE_INTERRUPTS): Tick with the scm_i_thread* local var, to avoid excessive tls calls. * libguile/vm-i-system.c: Fix dynstate users to use current_thread->dynamic_state.
2011-05-05VM tweaksAndy Wingo1-6/+20
* 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.
2010-09-16add vm-abort-continuation-hook, vm-restore-continuation-hookAndy Wingo1-0/+4
* libguile/vm-i-system.c (call_cc, tail_call_cc): Call the new RESTORE_CONTINUATION_HOOK when a continuation is restored. (prompt): Call the new ABORT_CONTINUATION_HOOK when entering the abort handler's continuation. * libguile/vm-engine.h (ABORT_CONTINUATION_HOOK) (RESTORE_CONTINUATION_HOOK): * libguile/vm.h (SCM_VM_ABORT_CONTINUATION_HOOK) (SCM_VM_RESTORE_CONTINUATION_HOOK): * libguile/vm.c: (scm_vm_abort_continuation_hook): New hook, called when entering an abort handler. (scm_vm_restore_continuation_hook): New hook, called after returning to a continuation. * module/system/vm/vm.scm: Add hooks to export list.
2010-09-16trim our set of vm hooksAndy Wingo1-8/+8
* libguile/vm.h (SCM_VM_PUSH_CONTINUATION_HOOK) (SCM_VM_POP_CONTINUATION_HOOK): New hooks, to replace enter/exit/return. (SCM_VM_BOOT_HOOK, SCM_VM_HALT_HOOK, SCM_VM_BREAK_HOOK): Remove these useless hooks. * libguile/vm.c (scm_vm_push_continuation_hook) (scm_vm_pop_continuation_hook): New accessors. * libguile/vm-i-system.c: Remove boot, halt, break, enter, exit, and return hooks. Also remove the break instruction. Instead now when we push a new continuation onto the stack we call PUSH_CONTINUATION_HOOK, and when we pop via a return we call POP_CONTINUATION_HOOK. APPLY_HOOK is now decoupled from continuation pushes and pops. * libguile/vm-engine.h: * libguile/vm-engine.c: Adapt for hooks. * module/system/vm/trace.scm (vm-trace): Adapt for hooks. Also revive the #:instructions? #t mode. * module/system/vm/vm.scm: Adapt exports for new set of hooks.
2010-05-02add SCM_UNLIKELY to CHECK_UNDERFLOWAndy Wingo1-4/+8
* libguile/vm-engine.h (CHECK_OVERFLOW, CHECK_UNDERFLOW): Add SCM_UNLIKELY blocks. Fix off-by-one error in CHECK_UNDERFLOW. (PRE_CHECK_UNDERFLOW): New macro, for checking underflow before accessing the current sp. (POP): Use PRE_CHECK_UNDERFLOW.
2010-03-15Make sure the whole VM stack is always scanned by the GC.Ludovic Courtès1-1/+5
Thanks to Andy for noticing this. * libguile/vm-engine.h (SYNC_REGISTER, CACHE_REGISTER): Add comment. * libguile/vm-i-scheme.c (make_struct): Call `SYNC_REGISTER ()' in all cases since the GC is going to run. (struct_ref, struct_set): Call `SYNC_REGISTER ()' on the slow path. (BV_REF_WITH_ENDIANNESS, BV_FIXABLE_INT_REF, BV_INT_REF): Likewise. (BV_FLOAT_REF): Always `SYNC_REGISTER ()'.
2010-01-13RETURN_HOOK communicates the number of returned valuesAndy Wingo1-1/+13
* libguile/vm-engine.h (RUN_HOOK1): Add some machinery whereby a hook can push an arg on the stack, run the hook, then drop the value. (RETURN_HOOK): Use it here, so we push the number of returned values. * libguile/vm-i-system.c (return, return-values): Adapt to RETURN_HOOK changes.
2010-01-09allocate free variables inline to closuresAndy Wingo1-15/+5
* 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.
2009-12-21rework vm tracingAndy Wingo1-9/+8
* libguile/vm-engine.c (VM_NAME): Engines take the VM itself (not the vp), so they can pass the VM to hooks. No more hook args, we dispatch without them. * libguile/vm-engine.h (RUN_HOOK): Dispatch the hook if the trace level is positive (instead of if the hook is there). Don't cache registers on return from the dispatch. * libguile/vm.h: * libguile/vm.c (vm_dispatch_hook): Don't bother with a dynwind; instead decrement the trace level when going into a hook, and if we have a nonlocal exit, the trace level never gets incremented again. Worse is better. (make_vm, scm_vm_trace_level, scm_set_vm_trace_level_x): New concept, trace level. If positive, we run the hooks, otherwise we don't. Should work. Removed scm_vm_trace_frame, I don't think that was the right way to do it. * module/system/vm/vm.scm: Replace vm-trace-frame with vm-trace-level and set-vm-trace-level!; the hooks actually get the frame as an argument now.
2009-12-11vm no longer measures bogoclock or times, relies on os for thatAndy Wingo1-8/+0
* libguile/vm.h (struct scm_vm): Remove "time" and "clock" members. The time was bogusly measured, and the "clock" measured instructions retired, which is not a very useful measurement, and it was causing lots of memory accesses. Not that I have done a proper profile, though... (scm_vm_stats): Remove this procedure, which provided access to "time" and "clock". * libguile/vm.c: * libguile/vm-engine.h: * libguile/vm-engine.c: * libguile/vm-i-system.c: Adapt to scm_vm changes and scm_vm_stats removal. * module/system/repl/command.scm: * module/system/vm/vm.scm: Adapt to vm-stats removal by removing vm-stats from <repl>.
2009-12-11less overhead for handling interrupts in the vmAndy Wingo1-0/+3
* libguile/__scm.h (SCM_ASYNC_TICK): Add some branch prediction. (SCM_ASYNC_TICK_WITH_CODE): New helper for when BUILDING_LIBGUILE, runs code only if we're going to call async_click(). * libguile/vm-engine.h (VM_HANDLE_INTERRUPTS): New helper, uses SCM_ASYNC_TICK_WITH_CODE to only save regs if we'll handle an interrupt. * libguile/vm-i-system.c (call, goto/args, return): use VM_HANDLE_INTERRUPTS.
2009-11-28Remove remaining uses of discouraged constructs, really.Ludovic Courtès1-1/+1
* libguile/throw.c, libguile/vm-engine.h, libguile/vm-i-system.c, libguile/vm.c: Replace uses of discouraged constructs by their current counterparts.
2009-10-23callees now check their args, cons rest list, reserve localsAndy Wingo1-37/+0
* gdbinit: Ignore SIGPWR and SIGXCPU, which the BDW GC seems to use. * libguile/vm-engine.h (FETCH_WIDTH): Remove unused macro. (INIT_ARGS, INIT_FRAME): Remove; callees now check their args and reserve space for their locals. * libguile/vm-engine.c: * libguile/vm-i-system.c: Turn on callee arg checking and local reservation. Seems to work!
2009-10-23runtime and debugging support for callee-parsed procedure argsAndy Wingo1-3/+1
* 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-08-28Merge branch 'master' into boehm-demers-weiser-gcLudovic Courtès1-17/+12
Conflicts: libguile/Makefile.am libguile/bytevectors.c libguile/gc-card.c libguile/gc-mark.c libguile/programs.c libguile/srcprop.c libguile/srfi-14.c libguile/symbols.c libguile/threads.c libguile/unif.c libguile/vm.c
2009-08-20reorder frame layoutAndy Wingo1-17/+12
* libguile/frames.h: Reorder the frame layout so the return address comes below the arguments.working (SCM_FRAME_SET_RETURN_ADDRESS, SCM_FRAME_SET_MV_RETURN_ADDRESS): New macros. * libguile/frames.c (scm_vm_frame_arguments): Use the macros to access the arguments. * libguile/vm-engine.c (vm_engine): Fix for new calling convention. * libguile/vm-engine.h (INIT_FRAME): New macro. Does part of what NEW_FRAME used to do. * libguile/vm-i-system.c (call, mv-call): Shuffle args up to make room for the stack, and adapt to new calling convention. (goto/args): Shuffling down is easier now. (return, return/args): Adapt to new frame layout. * libguile/vm.c (vm_mark_stack): Adapt to new frame layout, and the possibility of there being crap on the stack. (really_make_boot_program): Remove extraneous comment.
2009-08-20Fix bogus computation of `vm->stack_limit'.Ludovic Courtès1-1/+1
* libguile/vm.c (make_vm): Remove bogus "- 3" when computing `stack_size'. * libguile/vm-engine.h (CHECK_OVERFLOW): Change accordingly.
2009-08-08Add Unicode strings and symbolsMichael Gran1-0/+1
This adds full Unicode strings as a datatype, and it adds some minimal functionality. The terminal and port encoding is assumed to be ISO-8859-1. Non-ISO-8859-1 characters are written or input as string character escapes. The string character escapes now have 3 forms: \xXX \uXXXX and \UXXXXXX, for unprintable characters that have 2, 4 or 6 hex digits. The process for writing to strings has been modified. There is now a function scm_i_string_start_writing that does the copy-on-write conversion if necessary. To compile strings that may be wide, the VM storage of strings and string-likes has changed. Most string-using functions have not yet been updated and may break when used with wide strings. * module/language/assembly/compile-bytecode.scm (write-bytecode): use variable width string bytecode format * module/language/assembly.scm (byte-length): use variable width bytecode format * libguile/vm-i-loader.c (load-string, load-symbol): (load-keyword, define): use variable-width bytecode format * libguile/vm-engine.h (FETCH_WIDTH): new macro * libguile/strings.h: new declarations * libguile/strings.c (make_wide_stringbuf): new function (widen_stringbuf): new function (scm_i_make_wide_string): new function (scm_i_is_narrow_string): new function (scm_i_string_wide_chars): new function (scm_i_string_start_writing): new function (scm_i_string_ref): new function (scm_i_string_set_x): new function (scm_i_is_narrow_symbol): new function (scm_i_symbol_wide_chars, scm_i_symbol_ref): new function (scm_string_width): new function (unistring_escapes_to_guile_escapes): new function (scm_to_stringn): new function (scm_i_stringbuf_free): modify for wide strings (scm_i_substring_copy): modify for wide strings (scm_i_string_chars, scm_string_append): modify for wide strings (scm_i_make_symbol, scm_to_locale_stringn): modify for wide strings (scm_string_dump, scm_symbol_dump, scm_to_locale_stringbuf): (scm_string, scm_i_deprecated_string_chars): modify for wide strings (scm_from_locale_string, scm_from_locale_stringn): add null test * libguile/srfi-13.c: add calls for scm_i_string_start_writing for each call of scm_i_string_stop_writing (scm_string_for_each): modify for wide strings * libguile/socket.c: add calls for scm_i_string_start_writing for each call of scm_i_string_stop_writing * libguile/rw.c: add calls for scm_i_string_start_writing for each call of scm_i_string_stop_writing * libguile/read.c (scm_read_string): allow reading of wide strings * libguile/print.h: add declaration for scm_charprint * libguile/print.c (iprin1): print wide strings and add new string escapes (scm_charprint): new function * libguile/ports.h: new declarations for scm_lfwrite_substr and scm_lfwrite_str * libguile/ports.c (update_port_lf): new function (scm_lfwrite): use update_port_lf (scm_lfwrite_substr): new function (scm_lfwrite_str): new function * test-suite/tests/asm-to-bytecode.test ("compiler"): add string width byte to sting-like asm tests
2009-07-26make sure all programs are 8-byte alignedAndy Wingo1-0/+4
* libguile/objcodes.c (OBJCODE_COOKIE): Bump objcode cookie, as we added to struct scm_objcode. * libguile/objcodes.h (struct scm_objcode): Add a uint32 after metalen and before base, so that if the structure has 8-byte alignment, base will have 8-byte alignment too. (Before, base was 12 bytes from the start of the structure, now it's 16 bytes.) * libguile/vm-engine.h (ASSERT_ALIGNED_PROCEDURE): Add a check that can be turned on with VM_ENABLE_PARANOID_ASSERTIONS. (CACHE_PROGRAM): Call ASSERT_ALIGNED_PROCEDURE. * libguile/vm-i-system.c (long-local-ref): Add a missing semicolon. * libguile/vm.c (really_make_boot_program): Rework to operate directly on a malloc'd buffer, so that the program will be 8-byte aligned. * module/language/assembly.scm (*program-header-len*): Add another 4 for the padding. (object->assembly): Fix case in which we would return (make-int8 0) instead of (make-int8:0). This would throw off compile-assembly.scm's use of addr+. * module/language/assembly/compile-bytecode.scm (write-bytecode): Write out the padding int. * module/language/assembly/decompile-bytecode.scm (decode-load-program): And pop off the padding int too. * module/language/glil/compile-assembly.scm (glil->assembly): Don't pack the assembly, assume that assembly.scm has done it for us. If a program has a meta, pad out the program so that meta will be aligned. * test-suite/tests/asm-to-bytecode.test: Adapt to expect programs to have the extra 4-byte padding int.
2009-07-23rename "closure-ref" to "free-ref"; s/vars/variables/ in some namesAndy Wingo1-9/+9
* libguile/programs.h: * libguile/programs.c: (SCM_PROGRAM_FREE_VARIABLES): Rename from SCM_PROGRAM_FREE_VARS. Callers changed. * libguile/programs.c (scm_make_program): Rename arg to "free_variables". (scm_program_free_variables): Rename from program-free-vars. * libguile/vm-engine.h: * libguile/vm-engine.c (VM_CHECK_FREE_VARIABLES): Rename from VM_CHECK_CLOSURE. (vm_engine, CACHE_PROGRAM): Rename closure and closure_count to free_vars and free_vars_vount. * libguile/vm-i-system.c (FREE_VARIABLE_REF): Rename from CLOSURE_REF. (free-ref, free-boxed-ref, free-boxed-set): Rename from closure-ref, closure-boxed-ref, closure-boxed-set. (make-closure): Renamed from make-closure2. * module/language/glil/compile-assembly.scm (glil->assembly): Hack to never write out the the old "make-closure" instruction. Will fix better later. Change to emit free-ref etc instead of closure-ref. * module/language/tree-il/compile-glil.scm (flatten): Emit make-closure instead of make-closure2, now that the old make-closure is gone. * module/system/vm/program.scm (system): Rename program-free-vars to program-free-variables. * test-suite/tests/tree-il.test ("lambda"): Update for make-closure.
2009-07-23remove "externals" from the vmAndy Wingo1-30/+6
* libguile/frames.c (scm_frame_external_link): Removed. * libguile/frames.h: No need to have the "external link" in the stack frame -- update macros to take the new situation into account. * libguile/objcodes.h (struct scm_objcode): Rename the nexts field to "unused". In the future we can use it for nlocs, I think. (SCM_OBJCODE_NEXTS): removed. * libguile/programs.h: * libguile/programs.c (scm_make_program): Expect the third argument to be a vector of free variables, not a list of free variables. SCM_BOOL_F indicates no free variables, not SCM_EOL. (program_mark): Adapt. (scm_program_arity): No more nexts. (scm_program_free_vars): Replaces scm_program_externals. * libguile/vm-engine.c (VM_CHECK_EXTERNAL) (vm_engine): No need for the "external" var. * libguile/vm-engine.h (CACHE_PROGRAM): Update for SCM_PROGRAM_FREE_VARS instead of SCM_PROGRAM_EXTERNALS. (NEW_FRAME): Update for new frame size, and no need to cons up externals. Yay :) * libguile/vm-i-loader.c (load-program): Update for scm_make_program. * libguile/vm-i-system.c (external-ref, external-set): No more. (make-closure): No more. (goto/args): No need to re-cons externals here. Update for new stack frame size. (mv-call, return, return/values): Update for new frame size. No need to reinstate externals on return. * libguile/vm.c (really_make_boot_program, scm_load_compiled_with_vm): Update for scm_make_program. * module/language/objcode/spec.scm (objcode-env-externals): Treat '() as #f, for the externals. Need to clean this up later... * module/system/vm/program.scm (arity:nexts): Remove. Rename program-external to program-free-vars.
2009-07-22vm support for display closuresAndy Wingo1-0/+30
* libguile/vm-i-system.c (box, empty-box): Boxing values and storing them in local variables. (local-boxed-ref, local-boxed-set): A combination of local-ref then variable-ref/set. (make-closure2, closure-ref, closure-boxed-ref, closure-boxed-set): New ops. The idea is to migrate Guile over to using flat dispay closures. See the paper "Three Implementation Models for Scheme" by Kent Dybvig for more details; this is the "stack-based" model. * libguile/vm-engine.c: * libguile/vm-engine.h: Add the necessary infrastructure to keep track of a "closure" variable, like our "externals" in semantics, but minimal, flat, and O(1) in implementation.
2009-06-26add bytevector ops to the vmAndy Wingo1-8/+4
* libguile/instructions.h (SCM_VM_NUM_INSTRUCTIONS): Enlarge to 255. Not sure what performance effects this will have. * libguile/vm-engine.c: Add new error case, vm_error_not_a_bytevector. * libguile/vm-engine.h: Don't assign specific registers for i386. Having added the new VM vector ops, GCC 4.4 is erroring for me now. * libguile/vm-i-scheme.c: Add bytevector-specific ops to the VM. We don't actually use them yet, though.
2009-06-17Change Guile license to LGPLv3+Neil Jerram1-6/+7
(Not quite finished, the following will be done tomorrow. module/srfi/*.scm module/rnrs/*.scm module/scripts/*.scm testsuite/*.scm guile-readline/* )
2009-05-26adjust VM copyright notices to LGPL, use SCM_INTERNAL/API properlyAndy Wingo1-36/+12
* libguile/frames.c: * libguile/frames.h: * libguile/instructions.c: * libguile/instructions.h: * libguile/objcodes.c: * libguile/objcodes.h: * libguile/programs.c: * libguile/programs.h: * libguile/vm-bootstrap.h: * libguile/vm-engine.c: * libguile/vm-engine.h: * libguile/vm-expand.h: * libguile/vm-i-scheme.c: * libguile/vm.c: * libguile/vm.h: Update to use SCM_API and SCM_INTERNAL correctly. Adjust copyright to be the same as the copyright of Guile itself, which should be fine given that the FSF holds the whole thing.
2009-05-20and, or, cond etc use syntax-rules, compile scheme through tree-ilAndy Wingo1-0/+4
* 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-02-25don't crash etch's gccAndy Wingo1-0/+4
* libguile/vm-engine.h: Don't allocate registers in registers if we're on Etch's GCC.
2009-02-05in debug mode, make sure that calls to the vm can be captured via make-stackAndy Wingo1-1/+1
* libguile/vm-engine.c (VM_PUSH_DEBUG_FRAMES): New knob, if true we much with the scm_i_last_debug_frame when entering the VM, because sometimes the evaluator doesn't do it for us. (VM_ENGINE): Plug through debug frame fondling. Now, program exit comes back to the main text. Rename err_args to finish_args, and reuse for the return value. * libguile/vm-engine.h (PUSH_LIST): * libguile/vm-i-loader.c: * libguile/vm-i-scheme.c: * libguile/vm-i-system.c: Update for finish_args. (halt): goto vm_done, now, instead of returning directly.
2009-02-05inline call to scm_make_program when making closuresAndy Wingo1-2/+2
* libguile/programs.c (scm_make_program): Add a comment. * libguile/vm-engine.h (INIT_ARGS): Add a couple of UNLIKELY notes. * libguile/vm-i-system.c (make-closure): Inline the call to scm_make_program, which avoids some redundant checks.
2009-02-04enable multiple vm engines (regular, debug, ...)Andy Wingo1-12/+3
* libguile/vm-engine.c (VM_USE_HOOKS, VM_USE_CLOCK, VM_CHECK_EXTERNAL) (VM_CHECK_OBJECT): Update to define these here, before including vm-engine.h. (vm_run): Change so that we can make different engines. Also, we take an array of arguments, and the struct scm_vm directly, so as to avoid any need to cons. * libguile/vm-engine.h (CHECK_EXTERNAL, CHECK_OBJECT): Add some UNLIKELY bits; don't seem to help. * libguile/vm.c (vm_dispatch_hook): Change to not pass the VP. This needs some love, and perhaps we revert to the old way. (VM_ENGINE): Actually make two engines, vm_regular_engine and vm_debug_engine. Probably there is room for improvement here. Actually their speeds are the same at the moment. (make_vm): Choose which engine to run; currently the debug engine by default. (scm_c_vm_run): A thin wrapper to invoke a VM without consing. (scm_vm_apply): Use scm_c_vm_run. (scm_load_compiled_with_vm): Use scm_c_vm_run.
2009-01-29static opcodes; refactor program/objcode division; use new assembly pipelineAndy Wingo1-7/+7
* 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-17move module and meta inside programs' object tablesAndy Wingo1-9/+7
* libguile/programs.h (struct scm_program): Remove the module and meta fields. * libguile/programs.c (scm_c_make_program): Add a new argument, `objs'. If it's a vector, we'll look for the module and the metadata in there, instead of having them in the scm_program structure. (scm_c_make_closure, program_mark, scm_program_meta) (scm_c_program_source, scm_program_module): Adapt to the new program representation. * libguile/objcodes.c (scm_objcode_to_program): Pass #f as the object table when making the program. * libguile/vm-engine.h (CACHE_PROGRAM): * libguile/vm-engine.c (vm_run): Rework to use the simple vector API for getting the current object table. Call the helper, vm_make_boot_program, to make the boot program. * libguile/vm-i-loader.c (load-program): Set the current module and the meta in the object vector, which we pass to scm_c_make_program. * libguile/vm-i-system.c (toplevel-ref, toplevel-set): Adapt to the new program representation. * module/language/glil/compile-objcode.scm (codegen): Clarify.
2009-01-04allow `apply' on %nil-terminated listsAndy Wingo1-2/+2
* libguile/vm-engine.h (PUSH_LIST): Add a parameter to check that the list was proper. * libguile/vm-i-system.c: Adapt PUSH_LIST callsites to pass SCM_NULLP or SCM_NULL_OR_NIL_P, as appropriate. Add a check to return/values*. * libguile/vm.c: Add lang.h header for SCM_NULL_OR_NIL_P. * test-suite/tests/elisp.test: Fix XFAIL for elisp + apply.
2008-12-26remove heap links in VM frames, incorporate vm frames into normal backtracesAndy Wingo1-77/+6
* doc/ref/vm.texi (Stack Layout): Update to remove references to the "heap link". * gdbinit: Update for "heap link" removal. * libguile/frames.c: * libguile/frames.h: Update macros and diagram for removal of "heap link". As part of this, we also remove "heap frames", replacing them with "vm frames", which are much like the interpreter's debug objects, but for VM stacks. That is to say, they don't actually hold the stack themselves, just the pointers into stack that's held by a continuation (either captured or current). * libguile/stacks.c (stack_depth, read_frames): Since a "stack" object is really a copy of information that comes from somewhere else, it makes sense to copy over info from the VM, just as `make-stack' does from the evaluator. The tricky bit is to figure out how to interleave VM and interpreter frames. We do that by starting in the interpreter, and whenever the current frame's procedure is actually a program, we switch to the VM stack, switching back when we reach a "bootstrap frame". The last bit is hacky, but it does work... (is_vm_bootstrap_frame): Hacky predicate to see if a VM frame is a bootstrap frame. (scm_make_stack): Accept a VM frame in addition to debug frames. Probably has some bugs in this case. But in the case that the arg is #t (a common case), do the right thing, capturing the top VM frame as well, and interleaving those frames appropriately on the stack. As an accident, we lost the ability to limit the number of frames in the backtrace. We could add that back, but personally I always want *all* frames in the trace... Narrowing still works fine, though there are some hiccups sometimes -- e.g. an outer cut to a procedure that does a tail-call in VM code will never find the cut, as it no longer exists in the continuation. * libguile/vm.h (struct scm_vm): So! Now that we have switched to save stacks in the normal make-stack, there's no more need for `this_frame' or `last_frame'. On the other hand, we can take this opportunity to fix tracing: when we're in a trace hook, we set `trace_frame' on the VM, so we know not to fire hooks when we're already in a hook. (struct scm_vm_cont): Expose this, as make-stack needs it to make VM frames from VM continuations. * libguile/vm.c (scm_vm_trace_frame): New function, gets the current trace frame. (vm_mark, make_vm): Hook up the trace frame. (vm_dispatch_hook): New hook dispatcher, with a dynwind so it does the right thing if the hook exits nonlocally. * libguile/vm-engine.c (vm_run): No more this_frame in the wind data. * libguile/vm-engine.h (RUN_HOOK): Run hooks through the dispatcher. (ALIGN_AS_NON_IMMEDIATE, POP_LIST_ON_STACK): Remove unused code. (NEW_FRAME): Adapt for no HL in the frame. * libguile/vm-i-system.c (goto/args, mv-call, return, return/values): Adapt for no HL in the frame. * module/system/vm/frame.scm: * module/system/vm/vm.scm: Beginnings of some reworkings, needs more thought.
2008-10-16ensure that lists pushed onto the stack are properAndy Wingo1-0/+12
I saw this problem when running elisp.test -- it tries to apply a function to an arglist ending in nil, which obviously is not null. * libguile/vm-engine.h (PUSH_LIST): New helper macro, pushes the elements of a list onto the stack. Checks to make sure that the list is proper. * libguile/vm-i-system.c (list-break, mv-call, apply, goto/apply) (goto/cc): Use LIST_BREAK. * libguile/vm-engine.c (vm_error_improper_list): New error case.
2008-10-09NULLSTACK fixes for nonlocal exits in reentrant pre-wind handlersAndy Wingo1-0/+7
* libguile/vm-i-system.c (goto/cc): Add some asserts here. * libguile/vm.c (capture_vm_cont): Add some asserts here too. (reinstate_vm_cont): Null the correct number of bytes. Add a FIXME. (vm_reset_stack): Make the code a bit clearer. Null the correct number of bytes. * libguile/vm-engine.h (NULLSTACK_FOR_NONLOCAL_EXIT): New macro, handles a very tricky case that took me days to find! Amply commented. Expands to nothing in the normal case. * libguile/vm-i-system.c (call, goto/args, mv-call): Call NULLSTACK_FOR_NONLOCAL_EXIT in the right places. Fixes continuations.test.
2008-10-03precise stack marking, fix some missed references, still imperfectAndy Wingo1-16/+33
* 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-02be more like the interpreter in signalling wrong-num-argsAndy Wingo1-0/+9
* libguile/vm-engine.c: Call scm_wrong_num_args in the wrong-num-args case, to be more like the interpreter. * libguile/vm-engine.h (ASSERT): New macro. * libguile/vm-i-system.c (apply, goto/apply): Assert that nargs >= 2, because the compiler should always feed us correct instructions. (call/cc): If no values are returned to the continuation, signal no_values instead of wrong_num_args.
2008-09-30fix compilation of quasiquote with splicing and improper listsAndy Wingo1-0/+13
* libguile/vm-engine.h (POP_CONS_MARK): New macro, analagous to POP_LIST_MARK; used in quasiquote on improper lists. * libguile/vm-i-system.c (cons-mark): New instruction. You know the drill, remove all your .go files please. * module/system/il/compile.scm (codegen): Compile quasiquoted improper lists with splices correctly. Additionally check that we don't have slices in the CDR of an improper list. * testsuite/t-quasiquote.scm: Add a test for unquote-splicing in improper lists.
2008-09-13add a multiple values return address to stack framesAndy Wingo1-2/+3
* libguile/frames.c (frame-mv-return-address): New accessor. * libguile/frames.h: Update frame diagram. (SCM_FRAME_UPPER_ADDRESS): Update for data area growing by one pointer. (SCM_FRAME_MV_RETURN_ADDRESS): New macro. * libguile/vm-engine.h (NEW_FRAME): Update for frame getting bigger by a pointer. In a normal NEW_FRAME, set the MV return address to NULL, to indicate that this continuation does not accept multiple values. * libguile/vm-i-system.c (tail-call): Update frame replacement code to understand the MV return address. (return): Make room for the MVRA.
2008-09-13inline frame replacement in tail-callAndy Wingo1-29/+0
* libguile/programs.c (program_print): Only try to lookup write-program if the module system is booted. * libguile/vm-engine.h (FREE_FRAME): Remove, it's now inlined everywhere. * libguile/vm-i-system.c (tail-call): Inline FREE_FRAME, and implement the calling bits here. Will make things more hackable.
2008-09-13inline FREE_FRAME in return, sync stack_base in CACHE_REGISTERAndy Wingo1-0/+1
* libguile/vm-engine.h (CACHE_REGISTER): Sync stack_base too. * libguile/vm-i-system.c (return): Inline FREE_FRAME here, micro-optimizing a wee bit. Sounds silly, but it's to enable some refactoring.
2008-09-13clean up NEW_FRAME macroAndy Wingo1-16/+20
* libguile/vm-engine.h (NEW_FRAME): Clean up this macro.
2008-09-13readability improvement in vm-i-schemeAndy Wingo1-11/+0
* libguile/vm-engine.h: * libguile/vm-i-scheme.c: Move some helper macros closer to their use sites.
2008-08-21merge guile-vm into libguile itselfAndy Wingo1-0/+487
* ice-9/boot-9.scm: Only define load-compiled as #f if it's not already defined, which won't normally be the case. * libguile/guile-vm.c: Removed, there's no more guile-vm binary. * libguile/frames.c: (with change frame? -> heap-frame?) * libguile/frames.h: * libguile/instructions.c: * libguile/instructions.h: * libguile/objcodes.c: * libguile/objcodes.h: * libguile/programs.c: * libguile/programs.h: * libguile/vm-bootstrap.h: (was bootstrap.h) * libguile/vm-engine.c: (was vm_engine.c) * libguile/vm-engine.h: (was vm_engine.h) * libguile/vm-expand.h: (was vm_expand.h) * libguile/vm-i-loader.c: (was vm_loader.c) * libguile/vm-i-scheme.c: (was vm_scheme.c) * libguile/vm-i-system.c: (was vm_system.c) * libguile/vm.c: * libguile/vm.h: These files moved here from src/, as guile-vm is now a part of libguile. * libguile/init.c: Bootstrap the VM. Yay! * libguile/Makefile.am: The necessary chicanery here. * module/system/vm/Makefile.am: * module/system/vm/bootstrap.scm: * module/system/vm/frame.scm: * module/system/vm/instruction.scm: * module/system/vm/objcode.scm: * module/system/vm/program.scm: * module/system/vm/vm.scm: * pre-inst-guile-env.in: Add builddirs to the load path; add module/ to the path in the empty-$GUILE_LOAD_PATH case as well. * src/Makefile.am: Moved out everything except guilec and guile-disasm, which probably should be moved to the scripts directory? * testsuite/Makefile.am: Update to find guile-vm in the right place. * module/system/vm/Makefile.am: * module/system/vm/bootstrap.scm: Removed bootstrap.scm, scm_init_guile handles the bootstrapping for us. * module/system/vm/frame.scm: * module/system/vm/instruction.scm: * module/system/vm/objcode.scm: * module/system/vm/program.scm: * module/system/vm/vm.scm: Call the init functions in libguile; should fix at some point to avoid the dlopen?