Commit Graph

35 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
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
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
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
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
85750ca338 feat: add StringCodePointSequence class and expose codePoints property on String
Extract codePointAt() logic into a dedicated StringCodePointSequence class that wraps a string and implements the Sequence interface, enabling iteration over code points. Add a `codePoints` getter to String that returns a new instance of this sequence. Refactor the underlying C implementation of `codePointAt_` to decode UTF-8 into actual code point integers (returning raw bytes for invalid sequences) and rename the primitive to use trailing underscore convention. Update all related tests to reflect the new behavior where mid-sequence byte indices return the raw byte string instead of an empty string, and add new test files for the code point sequence iteration.
2015-09-11 14:56:01 +00:00
Bob Nystrom
21765218c4 fix: correct wrenUtf8DecodeNumBytes signature to accept single byte and fix range subscript bug
The function was previously taking a string and index, then indexing into the string internally. Changed to accept the byte directly, which fixes incorrect behavior when wrenNewStringFromRange and wrenStringCodePointAt passed a raw byte value instead of a string pointer. Also fixed a typo in wrenNewStringFromRange where wrenUtf8EncodeNumBytes was called instead of wrenUtf8DecodeNumBytes.
2015-09-09 03:59:47 +00:00
Bob Nystrom
a619851cf2 feat: implement UTF-8 aware string subscript ranges with new wrenNewStringFromRange helper
Add wrenNewStringFromRange function to wren_value.c that decodes UTF-8 code points from source string and re-encodes them into result, enabling correct range subscripts on multi-byte characters. Rename wrenUtf8NumBytes to wrenUtf8EncodeNumBytes and make wrenUtf8Encode return written byte count for use in range construction. Add wrenUtf8DecodeNumBytes utility to skip continuation bytes when iterating by byte index. Remove all skip directives from test files and add UTF-8 specific test cases verifying correct slicing across code point boundaries.
2015-09-02 05:14:55 +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
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
5e7ea2f135 fix: correct tombstone handling in map insertion to prevent deadlock
The addEntry function was incorrectly skipping tombstone entries when inserting new keys, causing the map to fill up with tombstones and eventually deadlock on insert. The fix removes the tombstone check that prevented overwriting tombstone slots with new entries, allowing proper reuse of removed entries.

A regression test (test/core/map/churn.wren) was added to verify that inserting and removing entries in a loop correctly maintains the map count without deadlocking.
2015-08-06 13:55:30 +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
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
ab12bc97e0 fix: remove redundant free in setRootDirectory and fix memory leak in runFile 2015-06-27 06:01: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
Bob Nystrom
13f63e0d04 feat: add wrenByteBufferFill and wrenMethodBufferFill for bulk buffer growth
Replace the loop-based single-element writes in readUnicodeEscape and wrenBindMethod with a new BufferFill macro that grows the buffer by a specified count in one allocation. The macro doubles capacity until it fits the requested count, then fills the new slots with the given data. The existing BufferWrite is reimplemented as a call to BufferFill with count=1.
2015-05-05 13:54:13 +00:00
Bob Nystrom
cd1cc07c6f feat: allow fibers as map keys by adding unique fiber IDs and hash support
Add a unique numeric ID to each fiber allocation, enabling fibers to be used as map keys. This includes updating the hash function for OBJ_FIBER to return the fiber's ID, modifying key validation to accept fibers, updating documentation to describe the new capability, and adjusting all relevant test expectations and error messages.
2015-05-03 18:10:31 +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
Bob Nystrom
b7904a89c9 feat: add String.fromCodePoint static method and refactor UTF-8 encoding into reusable utilities
Implement the `String.fromCodePoint(_)` primitive that creates a string from a Unicode code point, with validation for integer range 0–0x10ffff. Extract inline UTF-8 encoding logic from `readUnicodeEscape` in the compiler into new `wrenUtf8NumBytes` and `wrenUtf8Encode` utility functions in `wren_utils`, and add `wrenStringFromCodePoint` helper in `wren_value`. Update documentation for core classes to add "Methods" and "Static Methods" section headers, and include `String.fromCodePoint` docs with example. Add a test file `from_code_point.wren` covering various code points.
2015-03-27 14:43:36 +00:00
Bob Nystrom
a350d7c26a feat: add foreign method binding infrastructure with IO library integration
Implement the `WrenBindForeignMethodFn` callback type and `bindForeignMethodFn` configuration field to allow host applications to resolve foreign method declarations at class definition time. Refactor the IO library to use this new binding mechanism instead of the previous `wrenDefineStaticMethod` approach, adding `foreign` keyword support to the lexer and compiler. Introduce `freeCompiler` helper for cleanup, store module names in `ObjModule`, and update the VM to call the binder when processing `CODE_METHOD_INSTANCE` and `CODE_METHOD_STATIC` opcodes for foreign methods.
2015-03-24 14:58:15 +00:00
Bob Nystrom
46b6763877 refactor: rename Upvalue to ObjUpvalue for consistency with Obj naming convention
Rename the `Upvalue` struct and all related type references to `ObjUpvalue` across
wren_value.c, wren_value.h, and wren_vm.c. This aligns with the existing pattern
where Obj-derived types (like ObjModule, ObjClosure) use the Obj prefix even when
the type is not first-class in the language. The change touches function signatures,
variable declarations, pointer arithmetic in memory tracking, and the struct
definition itself.
2015-03-23 05:31:03 +00:00
Bob Nystrom
15f9273aab refactor: remove unused WrenVM* parameter from buffer init, string find, and debug print functions
Remove the `WrenVM* vm` parameter from `wrenValueBufferInit`, `wrenByteBufferInit`,
`wrenIntBufferInit`, `wrenStringBufferInit`, `wrenSymbolTableInit`,
`wrenMethodBufferInit`, `wrenStringFind`, and `wrenDebugPrintStackTrace`
functions across the compiler, core, debug, utils, value, and VM modules.
Update all call sites and macro definitions to match the simplified signatures,
eliminating dead parameters that were never used within the function bodies.
2015-03-23 05:17:40 +00:00
Bob Nystrom
96a829fc8f refactor: replace ObjList manual array management with ValueBuffer in Compiler and ObjList
Replace the hand-rolled capacity/count/elements fields in ObjList with a
ValueBuffer struct, and update Compiler to use a ValueBuffer for its
constant pool instead of an ObjList. This eliminates the separate
ensureListCapacity and wrenListAdd functions, centralizing buffer growth
logic in wrenValueBufferWrite. Adjust all list primitives (add, clear,
count, iterate, iteratorValue) and the GC marking path to operate on the
embedded ValueBuffer. Add wrenMarkBuffer helper for marking buffer
contents during sweep.
2015-03-22 19:22:47 +00:00
Bob Nystrom
07240ccb00 refactor: migrate list index and size types from int to uint32_t across core and value layers
Convert `validateIndexValue` and `validateIndex` return types to `uint32_t` with `UINT32_MAX` sentinel, update `wrenNewList`, `wrenListInsert`, `wrenListRemoveAt` signatures, and remove the TODO comment about type unification with `ObjMap`.
2015-03-21 19:22:04 +00:00
Bob Nystrom
69f135cc43 fix: change list capacity and count fields from int to uint32_t for consistency 2015-03-21 15:46:01 +00:00
Bob Nystrom
398a693d3c fix: replace constant-time string hash with full O(n) scan over all bytes 2015-03-19 14:38:05 +00:00
Bob Nystrom
1e842bbb2e feat: store precomputed hash in ObjString and use it for equality and hashing
Cache the FNV-1a hash code in the ObjString struct at creation time, replacing the
on-the-fly sampling hash in hashObject() and enabling constant-time string equality
checks. Refactor string allocation into allocateString() and hashString() helpers,
remove the old wrenNewUninitializedString() declaration, and add a CONST_STRING
macro. Disable the unimplemented subscript range operator with a runtime error and
skip the related UTF-8 tests. Add a string_equals benchmark to measure the speedup.
2015-03-18 14:09:03 +00:00
Bob Nystrom
f6da4700f4 fix: guard string hash loop against zero-length strings causing division by zero 2015-03-17 14:00:54 +00:00
Bob Nystrom
9314cbfd72 refactor: replace manual string concatenation with wrenStringFormat across VM core
Replace ad-hoc string construction using wrenNewString, wrenStringConcat, and sprintf with the new wrenStringFormat helper. This centralizes string formatting logic, reduces code duplication, and eliminates manual length calculations in wren_compiler.c, wren_core.c, wren_value.c, and wren_vm.c. Also introduces CONST_STRING macro for compile-time string literals and changes wrenNewUninitializedString return type from Value to ObjString* for consistency.
2015-03-16 05:32:20 +00:00
Bob Nystrom
d731e554e6 refactor: rename debug print functions to dump and move value printing to wren_debug.c 2015-03-15 17:09:43 +00:00
Bob Nystrom
18cf57d5f5 refactor: split source tree into vm/ and cli/ directories with updated build system
Separate Wren VM library sources from CLI tool sources by moving them into
src/vm/ and src/cli/ subdirectories respectively. Update the Makefile to use
separate wildcard patterns for each directory, generate distinct object file
paths under build/vm/ and build/cli/, and adjust include paths to src/include.
Also update the Xcode project file to reference the new file locations.
2015-03-14 22:00:50 +00:00
Peter Reijnders
875c74b211 fix: align ObjList capacity and count types with ObjMap's uint32_t
Change the `capacity` and `count` fields in `ObjList` from `int` to `uint32_t` to match the
types used in `ObjMap`, ensuring consistency between the two structures. Update all loop
variables and index calculations in `wren_core.c` and `wren_value.c` that interact with
these fields to use `uint32_t` instead of `int`, and remove the now-unnecessary negative
bounds check in `list_iterate` since unsigned types cannot be negative.
2015-03-08 11:33:29 +00:00