Commit Graph

344 Commits

Author SHA1 Message Date
underscorediscovery
4fed82adc8 fix: cast AS_NUM result to int in wrenDefineVariable to suppress implicit conversion warning 2019-10-08 06:43:05 +00:00
underscorediscovery
4954c0b4f2 feat: add clearer error message for forward-referenced lowercase module variables
Add a new error code (-3) from wrenDefineVariable to detect when a lowercase (local-style) module variable is referenced before its definition. The compiler now reports the line of the first use, improving diagnostics for forward-declared top-level variables.
2019-10-01 03:30:27 +00:00
underscorediscovery
4495cf9ae9 fix: guard null pointer access when printing module name in compile error
The `printError` function in `wren_compiler.c` previously dereferenced
`parser->module->name->value` without checking if the module name is null,
causing a crash when compiling modules without assigned names. Now safely
falls back to the string `"<unknown>"` when the module name pointer is null.
2019-09-19 05:49:01 +00:00
Sven Bergström
98e74d560e fix: guard against local variable array overflow in for-loop hidden variables
Add bounds check in forStatement to ensure compiler->numLocals + 2 does not exceed MAX_LOCALS before calling addLocal for the hidden 'seq ' and iterator variables. Includes regression test with deeply nested for-loops that previously caused an array overflow.
2019-09-18 07:20:03 +00:00
underscorediscovery
a3f679c204 fix: rename static call to call_fn in wren_core.c to avoid symbol collision with wren_compiler.c during amalgamation 2019-09-18 07:08:07 +00:00
underscorediscovery
771b06aba7 fix: cast strtoll result to double in makeNumber to suppress MSVC C4244 warning
When parsing hex numeric literals, the return value of strtoll (__int64) is
implicitly converted to double via the NUM_VAL macro. This adds an explicit
cast to double to silence the MSVC warning C4244 about potential loss of data
from a 64-bit integer to a double.
2019-09-18 07:05:16 +00:00
Matus Novak
de396887af fix: check for fiber error after foreign class allocation to support wrenAbortFiber
When a foreign class allocator calls wrenAbortFiber, the error flag is set on the fiber but the interpreter continues execution, causing the abort to be ignored. Add an explicit error check after createForeign() in the FOREIGN_CONSTRUCT case to trigger a runtime error and properly unwind the fiber when the allocator aborts.
2019-09-17 17:43:53 +00:00
Robert Nystrom
5f0d1f909b fix: replace hashBits with V8's integer hash to fix catastrophic collision for numeric keys
The old hashBits function XORed the two 32-bit halves of a double and applied
Java HashMap-style mixing, but for small integers the low bits of the double
representation are mostly zero, causing nearly all keys to map to entry zero.
This replaces it with Thomas Wang's integer hash (as used by V8's
ComputeLongHash), which properly scatters bits across the 32-bit key space.
Also updates the map_numeric benchmark to iterate 2,000,000 entries (up from
1,000,000) and adjusts the expected output in util/benchmark.py accordingly.
2019-07-27 20:34:07 +00:00
Walter Schell
2049f1bfb1 feat: add String.fromByte primitive with validation and unit tests
Implement a new String.fromByte(_) static method that creates a single-byte string from an integer 0-255. Includes runtime validation for non-integer, non-numeric, negative, and out-of-range values. Adds the underlying wrenStringFromByte helper in wren_value.c and exposes it via a new DEF_PRIMITIVE in wren_core.c. Documents the method in the core string markdown and provides six test cases covering happy path and all error conditions.
2019-02-27 13:05:07 +00:00
Bob Nystrom
460d0d2855 fix: rename include guard in wren_compiler.h from wren_parser_h to wren_compiler_h
The include guard macro in src/vm/wren_compiler.h was incorrectly named
wren_parser_h, likely a copy-paste artifact from the parser header.
This change corrects it to wren_compiler_h to match the actual filename
and prevent potential ODR violations when both headers are included.
2019-02-15 15:30:46 +00:00
Bob Nystrom
609d90493e fix: remove unused wrenInterpretInModule prototype from wren_vm.h 2019-02-15 15:30:16 +00:00
Bob Nystrom
38b70b4648 fix: correct null-check assert in insertEntry to guard against empty entries array 2019-02-14 15:51:57 +00:00
Bob Nystrom
8e5ad18146 fix: prevent buffer overflow in error label for long tokens in wren_compiler.c
Replace fixed-size ERROR_MESSAGE_SIZE buffer with dynamically sized array based on MAX_VARIABLE_NAME to avoid stack overflow when formatting error messages for tokens exceeding the original buffer capacity.
2019-02-14 15:42:12 +00:00
Bob Nystrom
673d5c57cd feat: add wrenHasError helper and replace raw IS_NULL checks on fiber->error
Introduce a static inline `wrenHasError` function in `wren_value.h` that encapsulates the `!IS_NULL(fiber->error)` pattern, improving code readability and maintainability. Replace all direct `IS_NULL(fiber->error)` checks across `wren_core.c`, `wren_vm.c`, and the interpreter loop with calls to this new helper. Additionally, clean up commented-out debug print statements and extraneous blank lines in the `trim` methods within the embedded core module source string, and add Michel Hermier to the AUTHORS file.
2019-02-11 15:52:38 +00:00
Bob Nystrom
523e157c6a feat: allow re-entrant wrenCall from foreign methods by resetting apiStack to NULL
The core change in wren_vm.c replaces the save/restore pattern for vm->apiStack with a simple NULL assignment after foreign calls, enabling nested wrenCall invocations from within foreign method handlers. This is accompanied by new test files (call_calls_foreign.c/.h/.wren) that verify the re-entrant call path works correctly, along with Makefile and Xcode project updates to build and run the new tests. A minor typo fix in reset_stack_after_call_abort.c renames a handle variable from 'afterConstruct' to 'afterAbort' for consistency.
2019-02-09 01:09:39 +00:00
Taylor Rose
23263881e0 fix: increase error label buffer to avoid compiler warning on long tokens
The previous fixed-size buffer `ERROR_MESSAGE_SIZE` could trigger a compiler warning
about truncation when formatting error labels with maximum-length variable names.
The new buffer size `10 + MAX_VARIABLE_NAME + 4 + 1` precisely accommodates the
format string "Error at '...'" plus the longest possible token name and null terminator,
eliminating the false positive warning on line 449.
2018-10-31 20:42:02 +00:00
Jean-François Geyelin
fa479c50c2 fix: remove unused wrenInterpretInModule prototype from wren_vm.h 2018-09-27 13:01:41 +00:00
FICTURE7
086766f9ba chore: rename include guard in wren_compiler.h from wren_parser_h to wren_compiler_h
The header guard was updated to match the actual filename, preventing potential
conflicts with a separate parser header and improving consistency across the codebase.
2018-07-27 14:57:17 +00:00
Michel Hermier
93ccdb5ddc chore: remove blank lines and commented debug prints from wren_core.wren.inc 2018-07-25 09:58:50 +00:00
Bob Nystrom
4b160f017b feat: prevent calling root fiber and refactor fiber state tracking
Add explicit check in `runFiber()` to reject calls to the root fiber, preventing VM crashes when a completed fiber's caller tries to resume it. Replace the boolean `callerIsTrying` field with a `FiberState` enum (`FIBER_TRY`, `FIBER_ROOT`, `FIBER_OTHER`) to track fiber invocation mode, updating all relevant primitives and initialization. Include new test cases (`call_root.wren`, `call_wren_call_root.*`) and re-entrancy documentation notes.
2018-07-21 17:02:29 +00:00
Michel Hermier
596f64685d refactor: extract inline fiber error check into dedicated wrenHasError function
Replace direct `!IS_NULL(fiber->error)` checks across vm and core files with calls to the new `wrenHasError()` inline function, improving code readability and centralizing the error detection logic.
2018-07-19 15:57:51 +00:00
Bob Nystrom
daeff98b83 refactor: replace special METHOD_FN_CALL type with regular primitives for Fn.call() overloads
Remove the dedicated METHOD_FN_CALL method type and its associated arity-checking dispatch logic in the VM. Instead, define a shared `call()` helper that validates argument count and invokes `wrenCallFunction`, then generate individual `fn_call0` through `fn_call16` primitives via a macro. This eliminates the special-case method type while preserving identical behavior for all 17 call overloads.

Also rename the `fn` union member to `as` in the `Method` struct, update all references accordingly, and add a `benchmark_baseline` Makefile target for generating performance baselines.
2018-07-18 15:20:11 +00:00
Bob Nystrom
a8005feb21 chore: add Travis CI docs deployment job and update build dependencies
- Add automatic docs deployment stage for master branch pushes in .travis.yml
- Include python3-markdown, python3-pygments, python3-setuptools, and ruby-sass as build dependencies
- Switch from container-based to sudo-required builds with trusty dist for custom Pygments lexer installation
- Ensure build directory exists before generating docs in Makefile
2018-07-16 04:01:14 +00:00
Bob Nystrom
45368f1038 feat: add logical import support with wren_modules directory resolution and path type classification
Introduce a path type classification system (absolute, relative, simple) to distinguish logical imports from relative ones. Implement automatic discovery of a "wren_modules" directory by walking up from the root directory. Refactor the CLI to return interpret results and exit codes instead of exiting directly. Extract cross-platform stat macros into a shared header. Update test API calls to use explicit relative paths.
2018-07-16 03:09:41 +00:00
Bob Nystrom
ffc9ec950c feat: add trim, trimEnd, trimStart methods with optional chars argument to String class
Implement six new trimming methods on String: trim(), trim(chars), trimEnd(), trimEnd(chars), trimStart(), trimStart(chars). The core logic uses a private trim_ helper that accepts a chars string, converts it to code points, and iterates from the start and/or end of the string to remove matching characters. Default whitespace set is tab, carriage return, newline, and space. Includes comprehensive test coverage for default and custom character trimming, edge cases (empty strings, all-trimmed strings, 8-bit clean data), and runtime error when chars argument is not a string.
2018-07-15 17:48:56 +00:00
Aleksi Salmela
5268170c89 fix: guard against local variable array overflow from for-loop hidden variables
Add a bounds check in `forStatement` to ensure there is space for the two hidden local variables (sequence slot and iterator) before calling `addLocal`. Without this check, deeply nested for-loops could overflow the `locals` array, causing a buffer overrun. The fix emits a clear compiler error when `numLocals + 2` exceeds `MAX_LOCALS`, and includes a regression test with 85 nested for-loops that previously triggered the overflow.
2018-06-12 21:31:28 +00:00
Bob Nystrom
52d65d48df fix: ensure expression compilation consumes all input by checking for EOF token
When compiling a single expression, the parser now explicitly consumes the TOKEN_EOF token after parsing the expression. This ensures that any trailing garbage or unexpected tokens after the expression are caught and reported as errors, rather than being silently ignored. The comment for the non-expression path is also updated to clarify that it checks for end of file rather than end of block.
2018-04-28 23:54:33 +00:00
Bob Nystrom
be6c17558d fix: replace strncpy with memcpy and increase error message buffer size
Replace strncpy with memcpy in readBuiltInModule to avoid potential string termination issues
when copying module source code, and increase ERROR_MESSAGE_SIZE from 60 to 80 to provide
more room for compiler error messages with long variable names.
2018-04-28 23:38:09 +00:00
Bob Nystrom
c3aad8049e fix: mark field symbol tables during class compilation to prevent GC from freeing field strings 2018-04-28 19:13:03 +00:00
Bob Nystrom
2b165f9649 refactor: replace raw String struct with ObjString* in symbol tables and GC handling
Migrate the internal `String` struct to use the heap-allocated `ObjString*` throughout the compiler, debugger, VM, and value system. This unifies string representation, enables proper garbage collection of symbol table entries via new `wrenBlackenSymbolTable` function, and removes manual memory management for symbol names.
2018-04-28 17:22:42 +00:00
Bob Nystrom
883754094a fix: remove redundant braces and update comment for UTF-8 BOM skip in wrenCompile 2018-04-28 17:07:04 +00:00
Bob Nystrom
91ddcea168 feat: skip UTF-8 BOM in source input and add regression test
Add handling for UTF-8 byte order mark (BOM) at the start of source code
in wrenCompile function by checking for the three-byte sequence \xEF\xBB\xBF
and advancing the source pointer past it. Include a regression test file
(test/regression/520.wren) that contains a BOM to verify the fix works
correctly.
2018-04-28 17:00:59 +00:00
Bob Nystrom
5c3d883204 fix: guard signature string overflow when too many parameters are passed
Add a MAX_PARAMETERS bound to the loop in signatureParameterList to prevent
buffer overflow when a method signature has an excessive number of parameters.
A compile error is already reported in such cases, but the unbounded loop could
still write past the end of the name buffer. Also add regression test 494.wren
to cover this scenario.
2018-04-27 16:13:40 +00:00
Bob Nystrom
248e3a69f0 fix: pre-allocate slot zero in every compiled chunk to fix REPL local variable declarations
The compiler now always reserves slot zero for either the closure or method
receiver, eliminating a corner case where top-level REPL code lacked the
pre-allocated slot that function/method bodies expect. This ensures local
variables declared in REPL loops (e.g. `for (i in 1..2)`) get correct slot
indexes.

Additionally, inlines `wrenResetFiber` into `wrenNewFiber` and stores the
imported module's closure on the stack before invoking it, preventing a GC
from collecting the closure during import.
2018-04-27 15:20:49 +00:00
jclc
75e828913f refactor: replace manual BOM offset tracking with pointer arithmetic in wrenCompile 2018-04-07 03:04:32 +00:00
jclc
021f4d6eb3 chore: remove trailing blank line and whitespace in wrenCompile function 2018-04-04 02:14:05 +00:00
jclc
a296b6d546 fix: skip UTF-8 BOM when compiling Wren source in wrenCompile function 2018-04-04 02:11:59 +00:00
Michel Hermier
0f74a07c86 feat: add wrenStringEqualStrLength and wrenStringsEqual helpers for string comparison
Introduce two new inline functions in wren_value.h: wrenStringEqualStrLength
compares an ObjString against a raw C string with known length, while
wrenStringsEqual compares two ObjString instances using hash pre-check and
delegating to wrenStringEqualStrLength. Refactor wrenSymbolTableFind in
wren_utils.c and wrenValuesEqual in wren_value.c to use these new helpers,
replacing inline memcmp calls for improved code clarity and reuse.
2018-03-29 07:12:32 +00:00
Michel Hermier
4e53cda68d refactor: replace custom String struct with ObjString* in symbol table and method names
Unify string representation across the codebase by switching SymbolTable and method name storage from a manually-managed `String` struct (char* buffer + length) to `ObjString*` pointers. This eliminates duplicate string allocations in the meta API's `metaGetModuleVariables`, reduces memory management overhead by leveraging the existing GC for symbol strings, and adds `wrenBlackenSymbolTable` to properly trace these GC-roots during collection. The change touches the compiler, debug dumper, VM runtime error formatting, and module variable initialization to use `->value` and `->length` fields directly from `ObjString`.
2018-03-28 16:12:50 +00:00
Michel Hermier
44e0714458 refactor: move Obj* forward declarations to wren_common.h and unify struct naming
Consolidate all Obj* type forward declarations from wren_value.h into wren_common.h
to centralize type definitions and reduce header dependencies. Convert anonymous
typedef structs to named structs with sObj* tags for consistent naming convention
across all object types.
2018-03-28 15:51:34 +00:00
Bob Nystrom
5d0814f85d fix: correct argument count for import opcodes and fix field offset in bind method code 2018-03-26 14:50:49 +00:00
Bob Nystrom
5b9640909c fix: correct assertion check in wrenGetVariable to validate name instead of module
The assertion for the `name` parameter in `wrenGetVariable` was incorrectly checking `module != NULL` instead of `name != NULL`. This fix ensures the variable name parameter is properly validated, preventing potential null pointer dereferences when retrieving variables.

Additionally, adds Marshall Bowers to the AUTHORS file.
2018-03-26 14:50:16 +00:00
Bob Nystrom
d11c0b0d4b fix: correct opcode argument counts and field offset in wrenBindMethodCode
The getNumArguments function had CODE_IMPORT_MODULE incorrectly returning 1 instead of 2, and CODE_IMPORT_VARIABLE returning 2 instead of 4. Additionally, wrenBindMethodCode had two bugs: it was incrementing ip before reading the instruction, causing incorrect opcode dispatch, and it was using ip++ instead of ip+1 for field offset adjustment, corrupting subsequent bytecode. The super instruction handling also incorrectly skipped over the symbol bytes before reading the constant index.
2018-03-26 14:49:54 +00:00
Bob Nystrom
761032c0fc feat: add WrenResolveModuleFn callback and module name parameter to wrenInterpret for relative import resolution
This breaking API change introduces a new `WrenResolveModuleFn` callback in the configuration that allows the host to canonicalize import module names, enabling relative imports. The `wrenInterpret()` function now requires a `module` parameter to specify the module name for the code being interpreted. The `wrenInterpretInModule()` function is removed in favor of the updated `wrenInterpret()`. The `metaCompile` function now dynamically looks up the caller's module name instead of hardcoding "main". New test files `resolution.c`, `resolution.h`, and `resolution.wren` are added to verify resolver behavior including null default, NULL return error, string rewriting, shared module deduplication, and importer propagation.
2018-03-23 14:54:09 +00:00
Bob Nystrom
88ad0fc138 feat: replace module import string operand with direct ObjModule reference in IMPORT_VARIABLE
Add CODE_END_MODULE opcode to store the current ObjModule in vm->lastModule after module body execution. Modify IMPORT_VARIABLE to load variables from vm->lastModule instead of using a constant string operand for the module name. Update opcode definitions, debug dump, compiler import logic, and interpreter dispatch accordingly. Refactor variable lookup into getModuleVariable helper. Adjust formatting in wren_primitive.c and wren_opt_meta.c.
2018-03-20 13:54:51 +00:00
Bob Nystrom
cf05cd7c8c refactor: change wrenCompileSource to return ObjClosure instead of ObjFiber and inline import execution
The compileInModule function now returns a closure directly instead of wrapping it in a fiber, simplifying the compilation pipeline and removing unnecessary fiber overhead for module imports. The wrenImportModule function is moved into wren_vm.c and rewritten to execute the imported module's closure immediately rather than returning a fiber for deferred execution. This change also adds a test for yielding from an imported module to verify correct behavior with the new execution model.
2018-03-17 16:33:33 +00:00
Bob Nystrom
2bbd385f69 refactor: consolidate duplicate wrenPopRoot calls in wrenCompileSource
Remove redundant NULL-check branches for module parameter by merging the
wrenPopRoot call into a single conditional after compileInModule, eliminating
the early return path and simplifying control flow in the compilation entry point.
2018-03-17 16:13:51 +00:00
Marshall Bowers
512ba07c22 fix: correct assertion to validate variable name instead of module in wrenGetVariable
The assertion in `wrenGetVariable` was incorrectly checking `module != NULL` twice,
instead of checking `name != NULL` for the variable name parameter. This fix
ensures the second assertion validates the correct parameter, preventing
potential null pointer dereference when a NULL variable name is passed.
2018-01-18 05:46:58 +00:00
Michel Hermier
28b3234fa5 fix: correct opcode argument counts and field offset patching in wrenBindMethodCode
The getNumArguments function had CODE_IMPORT_MODULE incorrectly listed as a 1-argument
opcode and CODE_IMPORT_VARIABLE as a 2-argument opcode. This swap caused incorrect
bytecode parsing during method binding. Additionally, wrenBindMethodCode had two bugs:
the instruction fetch was incrementing ip before reading the opcode, and field offset
patching was using ip++ instead of ip+1, corrupting subsequent bytecode. The super
instruction handling also had an incorrect ip+=2 skip that removed the symbol offset
before reading the constant index.
2018-01-11 10:56:03 +00:00
Bob Nystrom
3a1d93e2a8 fix: add unreachable return after switch in getNumArguments to fix compiler warning
The switch statement in getNumArguments covers all opcode cases, but the compiler
cannot prove exhaustiveness. Adding UNREACHABLE() followed by return 0 eliminates
the "control reaches end of non-void function" warning on strict compiler settings.
2017-11-01 05:07:07 +00:00