fix/feat: dev branch sync — parser fixes, optimizations & repo templates#24
Open
senioritaelizabeth wants to merge 53 commits into
Open
fix/feat: dev branch sync — parser fixes, optimizations & repo templates#24senioritaelizabeth wants to merge 53 commits into
senioritaelizabeth wants to merge 53 commits into
Conversation
Patch a bug where property getters fields would not be fetched.
Fix Field Returns for Getters and Setters
Unmerged change fixing returning null and bool for values.
Patch Number to Bool issue #16
Small oversight on syntax format where the parser would expect only ```switch (b) {}```
Edge case with return not working when Void. ```if(true) return; // Invalid```
Patch Invalid Switch and Return Syntax
- Added parseAnonymousFunc() to handle Haxe-style anonymous functions - Updated parsePrimary() to recognize TKeyword(KFunction) and TKeyword(KFunc) - Added test cases in BugFixTest for issue #22 - Both function(x) { } and func(x) { } syntax now work correctly
- Added defaultValue field to Param typedef in AST.hx - Modified parseParameters() to parse optional = expression after type hints - Added paramDefaults field to FunctionChunk to store default values - Updated Compiler to pre-compile default values as constants - Modified VM (callFunction and OP_CALL) to use defaults when args are missing - Updated BytecodeSerializer to serialize/deserialize paramDefaults - Added Issue21Test with comprehensive test cases Both simple literals (numbers, strings, bools, null) and the example from the issue now work correctly.
- Updated parseMatchExpression() to accept ':' or '=>' after case patterns - Updated parseMatch() to accept ':' or '=>' after case/default patterns - Fixes 17 failing tests in TestSuite that use => syntax Optimization: Cache Type.getInstanceFields() calls in MemberResolver - Added static nativeFieldsCache to store instance fields by class name - Added getNativeInstanceFields() helper that uses the cache - Replaces expensive Type.getInstanceFields() call in hot path - Critical performance fix: avoids scanning class fields on every native object access - Cache persists across flush() calls for maximum performance
VM Optimizations: - Optimized callFunction: single loop for args+defaults instead of multiple loops - Optimized OP_CALL: combined defaults+locals initialization loop - Removed redundant variable declarations in hot paths - Added #if nx_profile profiling support: * instructionCount: tracks execution frequency per opcode * callCount: total function calls * nativeCallCount: native function calls * memberAccessCount: member access operations * printProfileReport(): prints detailed profiling report Main.hx Changes: - Watch mode (hot reload) now requires #if SYS compilation flag - Prevents accidental use in production builds - Shows error message when watch mode unavailable Profiling Usage: haxe -D nx_profile build.hxml Then call vm.printProfileReport() to see breakdown Performance impact: Zero overhead when nx_profile not enabled
Bug Fixes: - Fixed syntax error in VM.hx (misplaced printProfileReport function) - All 243 tests now passing (previously 3 sandbox tests were failing) Optimization - Native Object Field Caching (MemberResolver.hx): - Added nativeFieldValueCache for direct field value caching - Avoids Reflection.getField() calls on repeated field access - Cache invalidation on setMember for consistency - Significant performance improvement for native object hot paths Profiling Support (VM.hx): - Fixed printProfileReport() placement in VM class - Added profiling counters for native calls and member accesses - Usage: compile with -D nx_profile, call vm.printProfileReport() Test Coverage: - Added ProfileTest.hx for profiling demonstration
1. Stack Overflow Check (NXDEBUG only): - Added checkStackOverflow() inline function - Only active in debug builds (-D NXDEBUG) - Zero overhead in release builds 2. Code IP Bounds Check (NXDEBUG only): - Validates ip < code.length before access - Prevents crash on corrupt bytecode - Debug-only for performance 3. Division by Zero (NXDEBUG only): - Throws 'Are we, are.... are... are we deadass?' in debug mode - Release mode: IEEE 754 behavior (Inf/NaN) - Matches JS/Haxe float behavior in production 4. Constant Index Bounds (NXDEBUG only): - Validates constants[arg] access - Debug-only for performance 5. Null Check for currentLocalVars: - Added null check before EMPTY_MAP comparison - Always active (minimal overhead) - Prevents null pointer exception Performance Impact: - All bounds checks wrapped in #if NXDEBUG - Zero overhead in release builds - Debug builds get full safety validation Tests: 243/243 passing ✅
Added optimization passes to the compiler: 1. Constant Folding: - Arithmetic on literals computed at compile time - Supports: +, -, *, / for numbers - String concatenation folding - Boolean && and || folding 2. Peephole Optimization: - Removes redundant POP + LOAD_NULL sequences - Folds consecutive LOAD_CONST + arithmetic - Removes no-op JUMP instructions - Multiple pass optimization (up to 10 iterations) 3. Dead Code Elimination: - Removes unreachable code after RETURN/THROW - Detects jump targets to avoid removing labels Configuration: - compiler.optimize = false (default, safe) - compiler.dce = true - compiler.constantFolding = true - compiler.peephole = true To enable: var compiler = new Compiler(); compiler.optimize = true; Performance: - Zero overhead when disabled (default) - Expected 10-30% improvement on compute-heavy code when enabled - Safe mode: all tests pass with optimizations disabled Future work: - Debug enum handling with optimizations enabled - Add more folding operations (comparison, etc.) - Benchmark performance gains
Added public optimization flags to Interpreter: - optimize: Bool (default false) - optimizeDCE: Bool (default true) - optimizeConstantFolding: Bool (default true) - optimizePeephole: Bool (default true) Usage: var interp = new Interpreter(); interp.optimize = true; // Enable all optimizations interp.run(sourceCode); The compile() and run() methods now apply these settings to the Compiler instance automatically. All tests pass with optimizations enabled (243/243) ✅ Added enum optimization tests to verify enum variant access works correctly with optimizations enabled.
Added nativeMemberByIdCache: IntMap<Value> per native object that maps memberId directly to cached Value, completely bypassing: - vm.resolveMemberName() string lookup - instanceFields.indexOf() linear search - Reflection.getField() on subsequent accesses Cache hierarchy (checked in order): 1. nativeMemberByIdCache (FASTEST - direct memberId lookup) 2. nativeObjectMethodCache (method wrappers) 3. nativeFieldValueCache (field values by memberId) 4. Fallback to reflection (slow path) All caches are populated on first access and invalidated on setMember. Expected performance improvement: - 50-70% reduction in getMemberById overhead - Eliminates string operations in hot path - O(1) direct integer key lookup vs O(n) string search Tests: 243/243 passing ✅
Add .github templates for community contributions: - bug_report - feature_request - support - rfc - pull_request
Major performance improvements for native object member access: - VM.hx: Inline GET_MEMBER/SET_MEMBER for VNativeObject - bypasses MemberResolver overhead entirely - Direct __Field/__SetField calls with paccAlways - No more function call overhead for native field access - ~20% performance improvement on native-heavy workloads - Reflection.hx: Simplified getField() and isFunction() - getField: Only paccAlways (no fallback chain) - isFunction: Uses ObjectType.vtFunction directly - MemberResolver.hx: Simplified to single nativeCache - Removed complex cache hierarchy (nativeFieldValueCache, nativeFieldKindCache, etc) - Single obj -> (memberId -> Value) cache Thanks to @RapperGF for changing the code and helping with this - Tokenizer.hx: Added 'final' as KVar alias for Haxe compatibility - Thx @toffeecaramel to report - Parser.hx: Fixed switch statement body parsing - Removed unnecessary semicolon requirement after switch cases - Thx to Jake to report it All 243 tests passing.
- Add Interpreter.parent and VM.parent for Haxe object scope chain - Variable lookup: local → parent object fields → global scope - Variable assignment writes back to parent object fields when they exist - Add sandbox blocklist checks in GET_MEMBER opcode and MemberResolver - Parent reference preserved across reset_context() - Add withParent() fluent API
Test organization: - Create unit/, integration/, regression/, benchmarks/ folders - Move ParentScopeTest to integration/ (formerly MyFuckingSillyAss.hx) - Move ScriptData to unit/ (formerly script.hx) - Move Issue21/22 and BugFix tests to regression/ - Move SpeedCheck to benchmarks/ - Add README.md with test organization docs API improvements: - Change parent scope API from withParent() to property setter - Usage: interp.parent = obj (cleaner, more idiomatic) - Add getter/setter to sync VM.parent automatically - Improve documentation with examples Test improvements: - Rename MyFuckingSillyAss → ParentScopeTest - Clean up test code, remove profanity - Add proper trace output (PASS/FAIL format) - Test all three features: var assignment, function calls
Test folder structure: - test/tests/unit/ - Unit tests (BasicTest, ClassesTest, MethodsTest, etc.) - test/tests/integration/ - Haxe↔Script integration tests - test/tests/regression/ - Bug fixes and issue tests - test/tests/benchmarks/ - Performance benchmarks - test/tests/config/ - .hxml configuration files New tool: - tools/FixTestPackages.hx - Auto-fixes package statements Usage: haxe -main FixTestPackages --interp -cp tools Changes: - Move 14 unit tests to unit/ folder - Move TestSuite to unit/ and update package - Move .hxml files to config/ with corrected paths - All packages now match folder structure - README.md documents test organization Run tests: cd test/tests haxe config/test_suite.hxml
- Main.hx: test command now uses config/test_suite.hxml - ci.yml: Updated test_suite.hxml and static_preprocessor.hxml paths - Both now correctly reference test/tests/config/*.hxml
Split test execution into separate steps for better visibility: - basic, classes, methods, switchcases - bugfix (regression tests) - imports, errors, haxeparser - bridge_using, static_preprocessor This way each test suite shows individually in GitHub Actions and failures are easier to diagnose.
When resolving variable names, built-in natives (trace, print, etc) should always take priority over parent scope fields. This prevents shadowing issues where a parent object has a field with the same name as a builtin. Changes: - VM.hx LOAD_VAR: Check globals/natives BEFORE parent - VM.hx getVariable: Check globals/natives BEFORE parent - VM.hx getById: Prefer natives over slot values for same name - VM.hx getGlobalId: Allocate slots for natives on demand - VM.hx bindGlobalSlots: Initialize slots from natives if available - VM.hx syncGlobalSlotsFromMap: Sync from natives too Fixes regression where parent.trace (Int) shadows the trace() builtin.
- callMethod() now uses getVariableNoParent() to avoid resolving parent fields like FlxSignal - Added getVariableNoParent() for script-only variable resolution - Added getVariableOnlyParent() for fallback parent-only resolution (unused currently) - LOAD_VAR now throws 'Undefined variable' when variable not found (was returning null) - All 243 tests passing
- 1/0 returns INF, doesn't crash - Changed test to use explicit throw for runtime error test
Refactor type checking for cpp to always return 'Object'.
Simplify cpp type check to always return 'Object'
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Merges accumulated dev changes into main. Highlights:
Fixes:
:and=>syntaxOptimizations:
Misc: