Move libuv download location from build/ to deps/ so that make clean does not
remove the downloaded source. Introduce per-architecture libuv static library
naming (build/libuv-32.a, build/libuv-64.a) and pass arch parameter through
build_libuv_linux and build_libuv functions. Add cleanall target to remove
deps/ separately from build artifacts.
Set BUILD_DIR=out in xcodebuild invocation for Mac and remove conditional LIBUV_BUILD variable, so both platforms consistently use build/libuv/out/Release/libuv.a instead of Mac using build/libuv/build/Release/libuv.a.
The timerCallback function previously freed the uv_timer_t handle directly after completion, which could cause undefined behavior if libuv still needed the handle. Now it properly calls uv_close with a new timerCloseCallback that frees the handle after the close operation finishes. Additionally, the strncpy call in timerGetSource was copying only length bytes without the null terminator; it now copies length + 1 bytes to ensure proper null termination of the returned source string.
Add libuv library path to both Debug and Win32 configurations in the MSVC project file, include timer module source and header files in the project filters, and implement the Windows libuv build script by calling vcbuild.bat instead of exiting with an unimplemented error. Also add a cross-platform remove_dir helper to handle directory cleanup on Windows where shutil.rmtree fails on readonly files.
- Changed C_OPTIONS from -std=c99 to -std=gnu99 to enable GNU C99 extensions
- Reordered linker flags in bin/$(WREN) and test targets: moved -lm before -lpthread and object files before libraries to fix potential linking order issues
Remove the LIB_UV_LINK variable that used -luv and -lpthread flags for linking, and instead pass the libuv static object directly via $^ in the bin/wren and test/wren link commands. This changes the linking strategy from dynamic library to object inclusion, simplifying the build and avoiding external library dependencies at link time.
The linker rules for both the main wren binary and the test binary were using
the automatic variable $^ which included libuv.a as a prerequisite. This
caused libuv.a to be passed as an object file to the linker, leading to
unnecessary static library inclusion. The fix explicitly lists only the
required object file groups (CLI_OBJECTS, MODULE_OBJECTS, VM_OBJECTS) and
the test-specific cli/io.o and cli/vm.o, removing libuv.a from the link
invocation while keeping it as a build dependency via LIBUV.
Reorder -luv before -lpthread in LIB_UV_LINK to fix potential linker ordering issues on some systems, and remove the @ prefix from the bin/ and test/ link commands to allow verbose output during linking.
The -pthread compiler flag was removed from the global CFLAGS and instead
incorporated into a new LIB_UV_LINK variable that includes -lpthread alongside
the libuv library path. This change applies the pthread linking only to
executables that depend on libuv (the CLI binary and test binary), rather than
to all compilation units, preventing potential issues with modules or static
library builds that do not require threading support.
Add -pthread to CFLAGS in the Linux/Unix shared library build path
to ensure proper thread support when compiling with gcc, which does
not enable it by default unlike some other compilers.
The previous value of 500 was insufficient for libuv's POSIX requirements,
causing compilation failures on Linux systems. Upgrading to 600 ensures
the necessary POSIX 2004 extensions are available, allowing libuv to
function correctly with the build system.
The build_libuv_linux function previously used the 'out' directory for the make
command, but now correctly targets the 'build' directory to match the output
generated by gyp_uv.py on Linux.
Add type and range checks to Timer.sleep() in both C source and Wren
implementation, aborting with descriptive errors for non-numeric or
negative arguments. Introduce six new test files covering sleep with
fibers, float durations, main fiber, zero milliseconds, negative
values, and non-numeric input. Fix stack trace parsing in test runner
to skip builtin library frames by iterating through error lines until
a main-line match is found.
Add a vertical slice of real libuv integration by introducing a "timer" CLI module with a Timer class and static sleep() method. This required significant infrastructure changes: setting up libuv event loop in the CLI, creating a new src/module directory for CLI modules, updating all build scripts (Makefile, wren.mk, Xcode project) to handle the new module compilation, and reorganizing CLI code by moving REPL logic from main.c to vm.c. The generate_builtins.py script was also updated to support copying Wren sources into the module directory.
- Extend wrenCall's variadic argument handling to accept 'v' type specifier,
which passes a previously acquired WrenValue* without releasing it.
- Update documentation comment in wren.h to describe the new 'v' argument type.
- Fix parameter counting in makeCallStub to correctly parse parenthesized
signatures by scanning backwards from the closing parenthesis.
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.
Introduce a new `WrenValue` handle type that allows C code to hold a persistent reference to a Wren object, preventing garbage collection until explicitly released. The implementation adds a doubly-linked list of value handles to the VM, integrates them into the garbage collector's marking phase, and provides `wrenGetArgumentValue`, `wrenReleaseValue`, and `wrenReturnValue` functions. The commit also includes a new `get_value` API test that exercises storing and retrieving a value across GC cycles, and refactors the test registration macro to use camelCase naming for consistency across all existing API tests.
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.
Refactor `signatureFromToken` to return a `Signature` struct instead of mutating a pointer parameter, enabling cleaner method call signature construction in the compiler. Expose `wrenGetCoreModule` as a public API function and update `defineClass`, `wrenFindVariable`, and `wrenLoadMetaLibrary` to accept an explicit `ObjModule*` parameter, removing the implicit core module assumption. Fix a critical bug in `addEntry` where tombstone entries were not immediately reused for new key-value pairs, causing potential infinite loops during map insertion. Add a regression test `test/core/map/churn.wren` that verifies correct map behavior under heavy insert/remove churn.
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.
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.
The build_libuv_linux function previously ran the make command without
specifying a working directory, causing it to execute relative to the
current process directory. This change adds the cwd parameter to the
run call, ensuring make operates inside the correct LIB_UV_DIR path
where the out directory exists.
Replace the stub that printed "not implemented" and exited with actual build
steps: invoke gyp_uv.py to generate Makefiles, then run make in the out/
directory. This enables libuv compilation on Linux targets.
Add a Python script to download and compile libuv v1.6.1, hook it into the Makefile so release and debug targets depend on the static library, and link libuv when building the CLI interpreter. Introduce a new "vm" target that builds only the VM library without requiring libuv. Update the Xcode project to link libuv.a into the executable.
Add TOKEN_CONSTRUCT as a new reserved word in the Wren compiler lexer and parser, and update the grammar rule table so that 'construct' triggers a constructor signature instead of 'this'. Modify all built-in class definitions in core.wren, wren_core.c, benchmark files, and test fixtures to use 'construct new(...)' and 'construct named(...)' syntax. Update documentation in classes.markdown and syntax.markdown to reflect the new keyword, and remove the deprecated test files for 'new' and infix class expressions.
The example previously used `new Fiber { ... }` which is incorrect Wren syntax; changed to `Fiber.new { ... }` to match the language's constructor pattern.
- 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
- Fix `validate_runtime_error` to reference `self.runtime_error_message` instead of undefined `runtime_error_message`
- Ensure `color_text` returns `str(text)` on Windows to avoid type mismatch when non-string input is passed
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.
The diff shows that in `script/test.py`, the `self.fail()` call on line 158 was passing `runtime_error_message` (the actual error) instead of `self.runtime_error_message` (the expected error) when formatting the failure message. This fix swaps the argument to display the correct expected error string in the test output.
The diff fixes a single-word typo in the fibers documentation markdown file,
changing the incorrect two-word phrase "no where" to the correct compound word
"nowhere" in the sentence explaining why the first value sent to a fiber is ignored.
Rename private `printList_` to public `printAll` across all overloaded `IO.print` methods in both Wren source and embedded C string. Update `IO.read` to require explicit `()` call syntax in test and documentation. Revise IO documentation to clarify `print`, `printAll`, `write`, and `read` semantics with updated examples.
Add a new benchmark file that measures performance of string equality comparisons
across various lengths and match/mismatch scenarios, including type mismatch
between string and integer.
Replace manual apt-get install steps with declarative addons.apt.packages for gcc-multilib, and set sudo: false to enable container-based builds for faster CI execution.
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.
The test runner previously short-circuited when a test expected an error and found at least one, causing it to miss other expected errors that didn't occur. This commit fixes the error pattern regex to exclude line-specific error expectations, removes specific error message strings from test files (since the runner doesn't validate them yet), and refactors the monolithic test function into a dedicated Test class with parse and run methods for better maintainability.
Fix the misspelling of "incomplete" in the AUTHORS file header and append
Starbeamrainbowlabs with their email address to the end of the contributor list.
Add a new doc page for the IO class covering its three static methods:
IO.print() for printing multiple values with a trailing newline, IO.write()
for printing a single value without a newline, and IO.read() for reading a
line of text from the console with a prompt. Also update the core index page
and template sidebar to include a link to the new IO documentation.
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%.
Extract the common pattern of returning the receiver argument into a single
DEF_PRIMITIVE(return_this) function, and refactor fiber_instantiate,
fn_instantiate, and the default Object constructor to use it instead of
inline RETURN_VAL(args[0]) calls. Also fix trailing whitespace on isEmpty
and class_toString lines in the core library source string.
Extract class name retrieval from object_toString into a new class_toString primitive, registered on the Class metaclass. This removes the IS_CLASS branch from object_toString, which now only handles instances and falls back to "<object>". The change ensures Class objects return their own name directly via toString rather than relying on the generic object handler.
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'.
When a block is passed as an argument to a method call, the generated
function's debug name now includes the method's signature followed by
" block argument" instead of the generic "(fn)" placeholder. This
improves debugging by showing which method the block belongs to.
Add test cases for single-byte incomplete two-octet and three-octet UTF-8 sequences
in code_point_at_incomplete.wren, and remove the resolved TODO comment about testing
truncated UTF-8 buffer reads in wrenUtf8Decode.
- Insert block argument patterns: `fields { block }`, `fields {|a, b| block }`, and variants with parentheses
- Add all infix operators (+, -, *, /, %, <, >, <=, >=, ==, !=, &, |) and prefix operators (!, ~, -) with string return values
- Fix class name capitalization from `literals` to `Literals` and update comment formatting for consistency
- Modify unicode escape example string to include extra characters between code points
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.
Super calls were dynamically resolved by walking the receiver's class hierarchy at runtime, which broke when a method containing a super call was inherited by a subclass. This change stores a reference to the superclass in a constant table slot during compilation, and the interpreter reads that constant directly to find the correct superclass method table. Also fixes getNumArguments ordering for CODE_SUPER cases and adds two test cases verifying super calls work correctly in inherited methods and closures within inherited methods.
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.
The ASCII diagrams in the NaN tagging documentation had misaligned
brackets and inconsistent dash counts that made the bit layout
confusing. Updated the exponent/mantissa separator from parentheses
to brackets, fixed the NaN bits indicator alignment, and corrected
the highest mantissa bit marker position to match the actual bit
positions in the IEEE 754 double representation.
- Add test executable build target in Makefile and wren.mk with new TEST_SOURCES variable
- Refactor createVM() and runFile() to accept WrenBindForeignMethodFn parameter
- Remove deprecated safeToString_ method from String class and simplify toString implementations
- Delete example/set.wren and add example/syntax.wren with syntax highlighting examples
- Refactor test runner script with color helper functions and add TEST_APP path
- Remove .DELETE_ON_ERROR from Makefile and add test dependency in test target
Introduce two new test suites under test/api/: return_double exercises wrenReturnDouble with integer and floating-point values, and return_null verifies that a foreign function returning nothing yields null. Refactor bindForeign dispatch in main.c to use a REGISTER_TEST macro, rename returnBoolBindForeign to return_boolBindForeign for consistency, and add an exit(1) on unknown foreign methods to prevent silent NULL returns.
Add a global `expectations` counter and increment it each time an `EXPECT_PATTERN` match is found in test scripts. Display the total count alongside existing Passed/Failed/Skipped stats in the test runner output.
Add a new test runner under `test/api/` that compiles C test cases against the Wren VM, along with Makefile and Python test script changes to build and execute them. The first test (`return_bool`) exercises `wrenReturnBool` via foreign methods. The CLI's `createVM` and `runFile` now accept an optional `WrenBindForeignMethodFn` callback to support custom bindings in tests.
Add a new test framework for exercising the Wren C embedding API directly from C code, including a Makefile target, test runner modifications, and the first API test case for boolean return values. The build system now compiles test sources from `test/api/` into a separate test executable, and the CLI's `createVM` and `runFile` functions accept an optional `WrenBindForeignMethodFn` callback to enable foreign method binding in tests. The test runner (`script/test.py`) is refactored to support both script and API test types, passing the test name instead of the full path for API tests. The initial `return_bool` test verifies that `wrenReturnBool` correctly returns `true` and `false` from foreign methods.
Add a `run_example` function that invokes `run_test` with `example=True`, which suppresses output comparison for example files. Extend the `walk` function with an `ignored` parameter to skip directories like `benchmark`. Update the test script to walk both `test` and `example` directories, enabling example files to be executed as tests to catch regressions like #266.
Add a comprehensive example file `example/syntax.wren` that demonstrates all major syntactic constructs of the wren programming language, including class definitions, constructors, methods, control flow, literals, and reserved words. This file is primarily intended for testing syntax highlighters and covers nested comments, field declarations, static methods, setters, inheritance with `is`, and various control structures like `while`, `for`, `if`/`else`, and `break`.
Add a comprehensive example file `example/syntax.wren` demonstrating syntactic constructs of the Wren programming language, including class definitions, constructors, methods, reserved words, literals, and control flow structures. This file is primarily intended for testing syntax highlighters and covers nested comments, field declarations, static methods, setters, inheritance with `is`, and various keyword usage patterns.
The safeToString_ mechanism introduced in 40897f33 used per-fiber maps and lists to detect recursive toString calls, but leaked memory when runtime errors occurred before cleanup. This reverts to direct toString implementations for List and Map, removing the recursive detection logic and updating tests to mark self-referencing containers as TODO.
Add two new test files covering super behavior in Wren's class inheritance:
- super_in_closure_in_inherited_method.wren tests super.toString inside a closure
within an inherited method, expecting "instance of B" output.
- super_in_inherited_method.wren tests direct super.toString call in an inherited
method, also expecting "instance of B". Both tests are currently expected to fail.
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.
Add `String.safeToString_` static method that tracks objects currently being
converted to string per fiber, returning "..." when recursion is detected.
Wrap List.toString and Map.toString with this guard to handle self-referential
and mutually recursive structures without crashing.
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.
Introduce a new static method `Object.same(obj1, obj2)` that exposes the VM's
built-in equality semantics (`wrenValuesEqual`) directly, bypassing any
user-defined `==` overrides. This required creating a dedicated metaclass for
Object (subclass of Class) to host the static method without polluting every
class with a `same` method. The implementation wires up a new `Object metaclass`
in the core initialization sequence, adjusts the class hierarchy setup order,
and adds comprehensive tests covering value types, identity comparison, and
verification that `Object.same` ignores custom `==` operators.
Add a new test file `lowercase_name_inside_body.wren` that verifies a class can correctly reference its own lowercase name from both static and instance methods. The test ensures that `foo` resolves to the class itself in static context and to the instance method `foo` in instance context, addressing issue #251.
- Shorten "wren bird" to "bird" to avoid redundancy
- Change "User groups" to "User group" for singular accuracy
- Rephrase "embedding APIs for Wren" to "Wren bindings for other languages"
- Add call-to-action for pull requests at the end of the page
Add a new community.markdown page to the documentation site that provides
information about Wren's user groups, third-party libraries written in Wren,
embedding API bindings for Rust, and editor integrations for Vim and Emacs.
Also update the site navigation template to include a link to the new
community page.
The diff shows the reserved words list in the syntax markdown documentation was updated to include 'import' and reorder the words, moving 'new' to the second line.
The Makefile now defines an explicit `amalgamation` target that writes the combined source into `build/wren.c` instead of the default `wren.c` in the project root. The `generate_amalgamation.py` script is updated with whitespace formatting improvements for readability. The `.PHONY` list is extended to include the new `amalgamation` target.
Add a Makefile target to generate a single-file amalgamation of all Wren library sources using a new Python script. Rename the static `libSource` variables in core, io, and meta modules to `coreLibSource`, `ioLibSource`, and `metaLibSource` respectively to avoid name collisions in the amalgamated output. Update the `callFunction` helper to `callFn` and fix the regex pattern in `generate_builtins.py` to match the renamed constant.
The "import" keyword was omitted from the reserved words list in the syntax documentation. This commit adds it between "if" and "in" in the alphabetically ordered list, ensuring the documentation accurately reflects all language keywords.