Commit Graph

70 Commits

Author SHA1 Message Date
Bob Nystrom
83254bbde3 feat: track max stack slots per function for dynamic stack growth
Add `numSlots` and `maxSlots` fields to `Compiler` struct to track current and maximum stack usage during compilation. Introduce `stackEffects` array mapping each opcode to its net stack delta, defined via updated `OPCODE` macro in `wren_opcodes.h` now taking a second argument. Modify `initCompiler` to initialize slot tracking from `numLocals`, update `emitByte` and related emit functions to adjust `numSlots` and update `maxSlots` when a new peak is reached. Extend `ObjFn` with `maxSlots` field, pass it through `wrenNewFunction` calls (including `makeCallStub`), and fix a null-check in `wrenDumpCode` for core module name.
2015-12-14 06:57:40 +00:00
Bob Nystrom
0f0d3f0c2d fix: propagate compile errors from imported modules and update test runner to skip them 2015-12-08 15:49:37 +00:00
Bob Nystrom
7fcd513b23 fix: add explicit casts to C++ compile errors in wren_value.c and wren_vm.c
Add explicit casts from void* to Obj** for reallocateFn calls in wrenNewVM and wrenFreeVM, and remove trailing whitespace on blank lines throughout wren_value.c to resolve C++ compilation errors.
2015-11-04 15:07:33 +00:00
Bob Nystrom
8afa5c3d68 fix: refactor GC gray set to use count/capacity and handle empty set edge cases
- Rename grayDepth to grayCount and maxGray to grayCapacity for clarity
- Fix gray stack growth condition to check capacity instead of depth
- Use config.reallocateFn directly instead of wrenReallocate wrapper
- Change blacken loop from do-while to while to handle empty gray set
- Remove separate initializeGC function and inline allocation in wrenNewVM
- Add explicit System.gc() calls in deeply_nested_gc and many_reallocations tests
- Normalize test output strings to lowercase "done"
2015-10-29 14:38:09 +00:00
Bob Nystrom
9fe0b2475e refactor: rename GC marking functions to tri-color terminology and add wrenGrayObj helper
Rename `wrenMarkValue` to `wrenGrayValue`, `wrenMarkBuffer` to `wrenGrayBuffer`, and `wrenDarkenObjs` to `wrenBlackenObjects` to make the tri-color garbage collection abstraction explicit. Introduce `wrenGrayObj` as a new helper that handles adding objects to the gray stack with cycle detection via the `isDark` flag. Update all call sites in the compiler, value, and VM modules to use the new names. Fix a typo in the VM header comment ("garbace" → "garbage").
2015-10-28 14:55:04 +00:00
Will Speak
140fb7738e feat: replace recursive mark with iterative gray/darken GC to prevent stack overflow
The previous recursive `wrenMarkObj` approach could overflow the C stack when marking deeply nested object graphs. This commit introduces an iterative two-phase collector: objects are first "grayed" onto an explicit stack in the WrenVM struct, then `wrenDarkenObjs` iteratively processes the gray stack until all reachable objects are marked as "dark". The `marked` field is renamed to `isDark` to reflect the new semantics. A `gray` array with `grayDepth` and `maxGray` tracking is added to `WrenVM`, initialized in `initializeGC` and freed in `wrenFreeVM`. All internal mark calls (`markClass`, `markClosure`, `markFiber`, `wrenCollectGarbage`) are updated to use `wrenGrayObj` instead of `wrenMarkObj`. Two new test files (`deeply_nested_gc.wren` and `many_reallocations.wren`) verify that deeply nested object graphs and repeated GC cycles complete without stack overflow.
2015-10-19 21:45:15 +00:00
Bob Nystrom
c9a7dba0c1 chore: rename auxiliary modules to optional and update all references
Rename the `src/aux/` directory to `src/optional/`, update all include guards, preprocessor defines, and file references from `WREN_AUX_*` to `WREN_OPT_*`, and adjust build system, Xcode project, and code generation scripts accordingly.
2015-10-24 16:23:25 +00:00
Bob Nystrom
88a4e0a4e9 refactor: move meta and random modules from vm and cli into new aux library category
Restructure module hierarchy by extracting meta and random from the core VM and CLI-specific modules into a new "aux" (auxiliary) directory. This introduces WREN_AUX_META and WREN_AUX_RANDOM configuration flags, updates include paths and build system to compile aux sources separately, removes random module registration from CLI modules.c, and adjusts the VM's module loading to implicitly import core into all modules regardless of name.
2015-10-18 05:09:48 +00:00
Bob Nystrom
0f932e1f3a fix: make UNREACHABLE() macro safe on compilers lacking __builtin_unreachable
Add fallback empty UNREACHABLE() definition for GCC < 4.5 and non-MSVC compilers, and insert return/break statements after all UNREACHABLE() calls to prevent -Wreturn-type warnings when the macro expands to nothing. Also cast malloc result to char* in io.c to suppress C++ compilation warning.
2015-10-17 04:51:30 +00:00
Bob Nystrom
8b70246acd refactor: remove sourcePath parameter from wrenInterpret and related module functions
The sourcePath field on ObjModule was redundant since it always matched the module name except for the main script. This change removes the parameter from wrenInterpret, wrenInterpretInModule, and wrenNewModule, and replaces all references to module->sourcePath with module->name in error reporting and debug output.
2015-10-16 01:17:42 +00:00
Bob Nystrom
c65fdb2f94 refactor: extract Meta class into separate module and add eval method with compile support 2015-10-16 01:08:56 +00:00
Bob Nystrom
419a5dfda0 refactor: move source path from FnDebug to ObjModule for centralized debug path storage
Remove the `sourcePath` field from `FnDebug` struct and the `Parser` struct, and instead store it directly in `ObjModule`. This eliminates duplication of the debug path across all functions in a module and simplifies the compiler interface by removing the `sourcePath` parameter from `wrenCompile()` and `wrenNewFunction()`. Update all call sites to reference `module->sourcePath` instead, including stack trace printing, code dumping, and the `meta_eval` primitive.
2015-10-14 14:37:13 +00:00
Bob Nystrom
21c5611bf0 fix: close only existing upvalues for locals in scope during stack unwinding
The previous implementation unconditionally closed the first open upvalue when
executing CLOSE_UPVALUE, which could crash when a local variable was never
actually captured by a closure. Changed closeUpvalue to closeUpvalues with a
stack threshold parameter, so only upvalues whose stack slot is at or above the
given pointer are closed. This prevents closing nonexistent upvalues for locals
that were never closed over, fixing segfaults in unused closure scenarios.

Added regression tests for unused closures and for nested scopes where only
some locals are captured.
2015-10-08 15:06:29 +00:00
Bob Nystrom
640779a81c refactor: replace PrimitiveResult enum with boolean return type for primitive functions
The PrimitiveResult enum (PRIM_VALUE/PRIM_FIBER) is removed and replaced with a simple bool return value where `true` indicates a normal value return and `false` signals a fiber switch or runtime error. This simplifies the interpreter dispatch in `runInterpreter` by converting the switch on enum cases into a single if/else branch, and reduces branching in the common value-returning path. All primitive function signatures, the `RETURN_VAL`/`RETURN_ERROR` macros, and the `runFiber` helper are updated accordingly.
2015-10-04 03:43:12 +00:00
Bob Nystrom
4d1d6d03f4 feat: remove PRIM_CALL result type and add METHOD_FN_CALL for function call special-casing
Replace the special "call" primitive result type (PRIM_CALL) with a new METHOD_FN_CALL method type that marks function call methods. Add checkArity helper to validate argument count before invoking function closures, and update the interpreter dispatch to handle the new method type instead of relying on the removed PRIM_CALL result.
2015-10-04 02:04:11 +00:00
Bob Nystrom
1ebb7f2507 refactor: remove explicit ObjFiber parameter from all primitive function signatures
Replace the `ObjFiber* fiber` parameter in `DEF_PRIMITIVE` macro and `Primitive` typedef with direct access to `vm->fiber` inside each primitive implementation. Update all call sites in `fiber_current`, `fiber_try`, `fiber_yield`, `fiber_yield1`, `meta_eval`, and the interpreter dispatch to use `vm->fiber` or a local `current` variable instead of the passed-in `fiber` argument.
2015-10-02 14:51:12 +00:00
Bob Nystrom
b3086333f0 refactor: unify PRIM_ERROR and PRIM_RUN_FIBER into single PRIM_FIBER enum value
Replace separate PRIM_ERROR and PRIM_RUN_FIBER return codes with a unified PRIM_FIBER in PrimitiveResult enum, updating all primitive implementations and the interpreter switch case to use the new combined value.
2015-09-30 14:32:39 +00:00
Bob Nystrom
2dcb3660b5 feat: add Fiber.transferError and allow non-string error objects in fiber abort
Refactor runtime error handling to store errors directly in the fiber's error field instead of on the stack, enabling any object (except null) as an error value. Add Fiber.transferError(_) primitive for transferring errors between fibers. Update validation helpers to accept Value arguments directly and modify RETURN_ERROR macro to set fiber error. Adjust GC marking to use wrenMarkValue for the error field. Add tests for aborting with non-string errors and null abort behavior.
2015-09-30 05:57:03 +00:00
Bob Nystrom
f6c36ec85b feat: add va_list version of wrenCall and fix GC bug with return values
- Introduce wrenCallVarArgs as an explicit va_list variant, allowing variadic functions to forward their arguments directly without re-parsing.
- Fix a garbage collection issue in wrenCall where return values could be prematurely collected by ensuring proper root handling.
- Refactor the call API test to avoid re-entering the VM by moving test execution into an afterLoad callback instead of a foreign method.
2015-09-30 02:29:10 +00:00
Bob Nystrom
b19d85f618 feat: add 'a' format specifier and null-value support to wrenCall, plus tests for strings with null bytes
Add a new 'a' format specifier to wrenCall that accepts an explicit byte array and length, enabling callers to pass strings containing null bytes without truncation. Also allow passing NULL for 'v' specifier arguments to produce a Wren NULL value. Rename setForeignCallbacks to setTestCallbacks for clarity. Extend the test suite with a new call.c test file that exercises all argument types including 'a' and 'v' with NULL, and add returnString/returnBytes foreign methods to verify wrenReturnString handles both null-terminated and explicit-length strings correctly.
2015-09-24 15:02:31 +00:00
Bob Nystrom
3a8582af89 feat: allow super calls in static methods by removing compiler error and fixing metaclass binding
Remove the compiler check that prevented 'super' from being used inside static methods, and fix the runtime binding logic in bindMethod to correctly resolve the superclass for static method dispatch. The key change moves the metaclass lookup (classObj->obj.classObj) to occur before wrenBindMethodCode so that bytecode patching uses the actual class rather than the metaclass, while preserving the original class name for foreign method resolution.
2015-09-19 22:19:41 +00:00
Bob Nystrom
ffe87c271d feat: add configurable write callback for System.print output delegation
Add a `WrenWriteFn` callback to `WrenConfiguration` that allows host applications to control how text from `System.print()` and related functions is displayed. When set, the VM invokes this callback instead of directly calling `printf`. If the callback is NULL, printed text is silently discarded. The CLI's `initVM()` now registers a simple `write` function that prints to stdout, while the core `system_writeString` primitive checks for the callback before outputting. This change also refactors `wrenInitConfiguration` to set `defaultReallocate` as the default reallocation function and consolidates configuration fields into a single `WrenConfiguration` struct stored directly in `WrenVM`, removing separate member fields for reallocate, bindForeignMethod, bindForeignClass, loadModule, minNextGC, and heapScalePercent.
2015-09-16 06:01:43 +00:00
Bob Nystrom
aa72900a9e feat: replace IO class with System class and remove separate IO module
- Delete wren_io.c, wren_io.h, and io.wren source files
- Remove multi-arity print overloads and IO.read/IO.time methods
- Add System class with print, printAll, write, writeAll methods to core.wren
- Update all documentation examples and README to use System.print instead of IO.print
2015-09-15 14:46:09 +00:00
Bob Nystrom
95626bb136 feat: replace inline C string literals with auto-generated .wren.inc includes
Replace the manually embedded C string constants for builtin Wren modules with
a new build system that automatically generates `.wren.inc` header files from
`.wren` source files. The old `script/generate_builtins.py` is removed and
replaced by `script/wren_to_c_string.py`, which produces standalone include
files with a `PREAMBLE` containing the module name and source path. The Makefile
gains pattern rules to rebuild these `.wren.inc` files whenever the
corresponding `.wren` source changes, and the `builtin` phony target is removed
since the generation is now automatic. The `wren.mk` wildcard lists are updated
to include the new `.wren.inc` files as dependencies. The `timer.c` and
`wren_core.c` source files now `#include` their respective `.wren.inc` headers
instead of defining the string literals inline, and the `timer.wren` trailing
newline is removed.
2015-09-13 17:03:02 +00:00
Bob Nystrom
eba4911485 fix: error when class inherits from null instead of defaulting to Object
Previously, inheriting from null would silently fall back to Object superclass. Now validates superclass and raises runtime error if null is provided. Refactored defineClass to remove implicit null-to-Object fallback, added loadCoreVariable helper for module-level core imports, and updated CLASS/FOREIGN_CLASS opcode comments to reflect that null is no longer a valid superclass. Added test case for inherit_from_null.
2015-09-12 17:14:04 +00:00
Bob Nystrom
4665ec1913 feat: implement foreign object finalization and expose wrenCollectGarbage API
Add finalizer invocation for foreign objects during garbage collection by calling wrenFinalizeForeign in wrenFreeObj. Expose wrenCollectGarbage as a public API function and update internal calls accordingly. Ensure the "<finalize>" symbol is always registered in the symbol table even when no finalizer is provided. Add test fixtures for Resource class with finalizer and Api.gc/Api.finalized methods to verify finalization behavior across multiple GC cycles.
2015-09-01 04:56:21 +00:00
Bob Nystrom
2a8847fa57 feat: replace WrenMethod with WrenValue for method handles and update wrenCall signature to return WrenInterpretResult 2015-08-31 14:57:48 +00:00
Bob Nystrom
7e111d19da feat: replace fiber run() with transfer() and suspend() for scheduler-friendly semantics
Remove the run() method from fibers and introduce transfer() for non-stack-based fiber switching, along with suspend() to pause the interpreter and return control to the host application. Update Timer.sleep() to use runNextScheduled_() instead of Fiber.yield(), and add Timer.schedule() for creating independently scheduled fibers. Refactor the core fiber runtime to support transfer semantics, including proper error handling for aborted fibers and self-transfer edge cases. Fix a missing quote in test.py's runtime error validation string.
2015-08-31 05:15:37 +00:00
Bob Nystrom
2dc209e585 feat: add foreign class support with allocation, construct opcodes, and CLI callback wiring
Implement the initial infrastructure for foreign classes in the Wren VM, including new opcodes (FOREIGN_CONSTRUCT, FOREIGN_CLASS), a WrenBindForeignClassFn callback type in the public API, and updated CLI vm.c to store and forward foreign binding callbacks via setForeignCallbacks(). The compiler now tracks whether a class is foreign via a new isForeign flag in ClassCompiler, emits CODE_FOREIGN_CONSTRUCT instead of CODE_CONSTRUCT for foreign class constructors, and errors on field definitions inside foreign classes. The debug dump and opcode header gain entries for the new opcodes, and wrenBindSuperclass handles the -1 numFields sentinel for foreign classes to prevent field inheritance from superclasses.
2015-08-15 19:07:53 +00:00
Bob Nystrom
f9f8b55b29 feat: add support for passing WrenValue pointers as 'v' type argument to wrenCall
Extend the wrenCall variadic argument handling to accept a new 'v' type specifier,
which allows callers to pass a previously acquired WrenValue* directly without
implicitly releasing it. This enables reusing existing Wren values across multiple
calls without unnecessary string or number conversions.

The implementation reads a WrenValue* from the variadic arguments and extracts
its internal Value for the call. Additionally, fix the parameter counting logic
in makeCallStub to correctly count underscore parameters only within the
parenthesized signature portion, preventing off-by-one errors for methods with
trailing parentheses in their signature strings.
2015-08-07 14:57:23 +00:00
Bob Nystrom
592772a97d feat: add WrenValue handle API for persistent object references outside VM
Introduce WrenValue type and wrenGetArgumentValue/wrenReleaseValue functions to allow C code to hold GC-safe references to Wren objects across foreign calls. Implement doubly-linked list management in VM struct, mark value handles during garbage collection, and add assertion in wrenFreeVM to detect unreleased values. Update test infrastructure with new get_value test case and rename existing test binding functions to camelCase convention.
2015-08-07 05:24:15 +00:00
Bob Nystrom
45c717b11b feat: add module parameter to wrenFindVariable and expose wrenGetCoreModule
Refactor wrenFindVariable to accept an explicit ObjModule* parameter instead of
implicitly using the main module. Promote the internal getCoreModule helper to
a public wrenGetCoreModule function declared in wren_vm.h. Update all call sites
in wren_core.c and wren_meta.c to pass the core module when looking up core
variables, and replace inline getCoreModule calls in wren_vm.c with the new
public function. Remove the NULL-module fallback documentation from
wrenDeclareVariable and wrenDefineVariable.
2015-08-06 14:13:11 +00:00
Bob Nystrom
67f1480bf0 chore: migrate Travis CI to container-based builds and update README links
- Switch Travis CI from sudo-based apt-get to addons.apt.packages for gcc-multilib
- Enable container-based builds with `sudo: false`
- Update README.md call-to-action links to point to getting-started and browser playground
- Replace `printList_` with `printAll` in IO class and remove redundant `IO.` prefixes
- Add IO.read() method documentation and update IO.print docs for up to 16 arguments
- Reorganize community page with Libraries, Language bindings, and Tools sections
- Add wrenjs JavaScript binding and Sublime Text syntax highlighting
- Fix typo "no where" to "nowhere" in fibers documentation
- Add indentation to preprocessor defines in wren_common.h for consistency
- Remove unreachable `return 0` after UNREACHABLE() in wren_compiler.c
- Fix Windows color output by wrapping text in str() in test script
2015-07-19 19:49:23 +00:00
Bob Nystrom
bb7ce3b10a refactor: extract inline helper for retrieving ObjFn from CallFrame
Replace three duplicated switch-on-type patterns (in wrenDebugPrintStackTrace, wrenAppendCallFrame, and runInterpreter) with a single static inline wrenGetFrameFunction that handles OBJ_FN and OBJ_CLOSURE cases with an UNREACHABLE default.
2015-07-19 17:16:54 +00:00
Bob Nystrom
177d53fe68 fix: align preprocessor indentation and remove dead code after UNREACHABLE in non-nan-tagged and non-computed-goto modes 2015-07-19 17:16:27 +00:00
Bob Nystrom
e19ff59cce feat: replace new keyword with this constructor syntax and ClassName.new() calls across core library and docs
Replace all uses of the `new` reserved word with explicit `this new()` constructor definitions and `ClassName.new()` instantiation calls in builtin/core.wren. Update all documentation files (classes.markdown, fiber.markdown, fn.markdown, sequence.markdown, error-handling.markdown, expressions.markdown, fibers.markdown, functions.markdown) to reflect the new constructor syntax, removing `new` keyword examples and replacing them with `ClassName.new()` patterns and `this new()` definitions.
2015-07-10 16:18:22 +00:00
Bob Nystrom
29ca6f4ffc feat: dynamically grow fiber call frame array instead of fixed MAX_CALL_FRAMES
Replace the statically-sized CallFrame array in ObjFiber with a dynamically
allocated array that starts at INITIAL_CALL_FRAMES (4) and doubles when
capacity is exceeded. This reduces memory for new fibers and improves
fiber creation benchmark performance by ~45%.
2015-07-01 07:00:25 +00:00
Bob Nystrom
43af98f1a5 refactor: merge duplicate call-handling logic between CODE_CALL and CODE_SUPER into shared code block
Eliminate the performance penalty of an if-test inside the call instruction loop by using explicit goto to share the common tail-end call-handling code between normal and superclass calls. This improves interpreter throughput across multiple benchmarks, with gains of up to 23% on the 'for' benchmark and 14% on 'fib'.
2015-06-28 17:58:48 +00:00
Bob Nystrom
862d1dfb07 fix: change runInterpreter signature to return WrenInterpretResult and accept explicit fiber parameter 2015-06-27 15:56:52 +00:00
Bob Nystrom
ab12bc97e0 fix: remove redundant free in setRootDirectory and fix memory leak in runFile 2015-06-27 06:01:07 +00:00
Bob Nystrom
cd64d67c11 fix: prevent memory leaks by freeing rootDirectory and clearing compiler constants 2015-06-27 05:49:24 +00:00
Bob Nystrom
846f2bb003 refactor: extract module lookup into getModule helper and simplify loadModule logic 2015-06-23 14:15:22 +00:00
Bob Nystrom
a4f5ee0280 refactor: replace dedicated CODE_IS opcode with infix operator method call for "is" 2015-06-19 14:58:07 +00:00
Bob Nystrom
275b2ca4e4 refactor: remove redundant null checks before wrenMarkObj calls in compiler, value, and vm modules
The wrenMarkObj function already handles null pointers internally, making the explicit
`if (x != NULL)` guards unnecessary. This change removes three such checks in
wrenMarkCompiler, markFn, and collectGarbage, simplifying the code without changing
behavior.
2015-06-18 14:52:05 +00:00
André Althaus
8c9e3c794e fix: replace realloc with custom defaultReallocate to handle zero-size case correctly 2015-06-02 18:57:41 +00:00
Bob Nystrom
1fd1c76661 fix: statically dispatch super() calls by binding superclass at compile time
The super() call resolution is changed from dynamic runtime lookup (walking the receiver's class hierarchy) to static binding at class definition time. This ensures correct method dispatch when a method containing a super call is inherited by another subclass.

Key changes:
- In `callSignature()`, when compiling a `CODE_SUPER_0` instruction, a constant slot is created and filled with NULL, to be populated with the superclass reference when the method is bound.
- In `getNumArguments()`, the `CODE_SUPER_0` through `CODE_SUPER_16` cases are moved after the newly added 2-argument opcodes (`CODE_JUMP`, `CODE_LOOP`, etc.) to maintain correct ordering.
- In `dumpInstruction()`, the debug output now prints the superclass constant index alongside the method symbol.
- In `runInterpreter()`, the super call execution reads the superclass directly from the function's constant table instead of deriving it from the receiver's class at runtime.
2015-06-02 14:33:39 +00:00
Luchs
167ad288f0 fix: undefine READ_BYTE and READ_SHORT macros after use in wren_debug.c and wren_vm.c
The READ_BYTE and READ_SHORT macros are defined locally within functions
in wren_debug.c and wren_vm.c but were not being undefined after use,
causing potential redefinition warnings or errors when these macros
conflict with other definitions in the same translation unit. This
change adds #undef directives at the end of dumpInstruction in
wren_debug.c and runInterpreter in wren_vm.c to properly clean up
the macro definitions.
2015-03-26 20:16:43 +00:00
Bob Nystrom
4b3b967674 chore: remove double space in finishParameterList and rephrase static method comment 2015-04-06 13:53:53 +00:00
Bob Nystrom
d92a8f1c93 fix: replace foreign Meta.eval with primitive and suppress compile errors in wrenCompile 2015-04-04 04:22:58 +00:00
Bob Nystrom
b6e2229b58 feat: move primitive class definitions from C into core.wren library source
Move the definitions of Bool, Fiber, Fn, Null, and Num classes from hardcoded C code in wren_core.c into the core.wren library source, allowing them to be parsed and created during library initialization. Simplify defineClass to always use wrenNewSingleClass, remove redundant root pushing in wrenNewClass, and adjust the class creation in the interpreter to use a Value instead of ObjClass*.
2015-04-03 15:00:55 +00:00