Develop#138
Merged
Merged
Conversation
* Fix value-type boxing in Transition (#126), add failing test for #123, expand ExpressionRuntimeOptions - Fix #126: Add EnsureConvert helper to Transition base class that wraps value-type expressions in Convert() when assigning to reference-type variables (boxing). Applied in Transition.SetResult and FinalTransition.AddExpressions. - Add failing test for #123: IfThen with Return(label, value) in BlockAsync returns null instead of expected value. Root cause is in the lowering phase where Returns inside non-lowered conditionals are not converted to _finalResultVariable assignments. - Expand ExpressionRuntimeOptions with Optimize flag (default true) to conditionally skip StateOptimizer, and SourceHandler callback to capture the generated state machine expression for debugging. * Change SourceHandler to Action<string> with UnsafeAccessor for DebugView, add tests * fix(expressions): Ensure Return gotos inside non-lowered expressions set final result * test(expressions): Add regression test for Return labels in async TryCatch * test(compiler): Add FastExpressionCompiler compatibility test for Return gotos with assignments * Update nugets and cleanup
* feat(compiler): scaffold Hyperbee.ExpressionCompiler library with stub API Adds the new Hyperbee.ExpressionCompiler class library (net8.0;net9.0;net10.0) with HyperbeeCompiler static API (Compile, TryCompile, CompileWithFallback) and HyperbeeCompilerExtensions. All methods are stubs; TryCompile returns null so CompileWithFallback falls back to Expression.Compile(). Updates solution file. * feat(compiler): scaffold Hyperbee.Expressions.Compiler library with stub API * test(compiler): add CompilerType enum, ExpressionVerifier, and binary/constant/conditional tests * test(compiler): seed FEC issue regression tests * bench(compiler): add compilation and execution benchmarks * chore(compiler): remove incorrectly named Hyperbee.ExpressionCompiler project * chore(compiler): restore version.json accidentally removed in cleanup * feat(compiler): add IR instruction set (IROp, IRInstruction, IRBuilder) Add the foundational IR types for the Hyperbee expression compiler: - IROp enum with all opcodes for Phase 1+ compilation - IRInstruction readonly struct for cache-friendly instruction storage - IRBuilder with instruction stream, operand table, locals, and labels - LocalInfo and LabelInfo readonly record structs for metadata * feat(compiler): add ExpressionLowerer for Phase 1 expression types Single-pass expression tree visitor that lowers to flat IR instructions. Supports constants, parameters, binary/unary ops, method calls, conditionals (ternary + IfThen), member access, new objects, blocks, assignment, default, type conversions, short-circuit logic, and operator overloads. Unsupported types throw NotSupportedException. * feat(compiler): add ILEmissionPass for IR-to-CIL generation 1:1 mapping from IR opcodes to CIL via ILGenerator. Handles all Phase 1 operations including arithmetic, checked variants, comparisons, conversions, method calls, branching, fields, boxing/unboxing, and non-embeddable constants loaded from a closure object[] array. Uses short-form opcodes for locals 0-3 and args 0-3. * feat(compiler): wire HyperbeeCompiler pipeline and pass all Phase 1 tests Complete the compiler pipeline: expression tree pre-scan for non-embeddable constants, lowering to IR, IL emission via DynamicMethod, and delegate creation. TryCompile now returns a working delegate for all Phase 1 patterns. All 81 compiler tests and 6 issue regression tests pass across net8.0, net9.0, and net10.0. * feat(compiler): add Phase 2 exception handling with try/catch/finally/throw/goto/label - Add Leave IROp for exiting try/catch blocks - Implement TryCatch/Throw/Rethrow/Goto/Label lowering in ExpressionLowerer - Add StackSpillPass to convert Branch to Leave at exception boundaries - Update ILEmissionPass with BeginTry/BeginCatch/BeginFinally/EndTryCatch/Throw/Rethrow/Leave emission - Wire StackSpillPass into HyperbeeCompiler pipeline between lowering and emission - Extend NeedsConstantsArray scanner for TryExpression/GotoExpression/LabelExpression - Add 62 exception handling tests (basic try/catch, typed catch, catch variable, try/catch/finally, throw/rethrow, goto/label, void try, nested try, value results) - Add 4 HyperbeeCompiler.Compile native tests for Pattern 1 and Pattern 2 in IssueTests - All 143 Compiler.Tests + 10 IssueTests pass on net8.0/net9.0/net10.0 * refactor(compiler): extract Compile pipeline into discrete SRP methods LowerToIR, RunPasses, EmitDelegate each own a single responsibility. Removes stale rationale comments and dead NeedsConstantsArray wrapper. * refactor(compiler): rename RunPasses to TransformIR * feat(compiler): add Phase 3 closure support with captured variables and nested lambdas Implement support for Expression.Lambda and Expression.Invoke with captured variables using the StrongBox<T> pattern: - Add CaptureScanner to detect variables captured by nested lambdas - Extend ExpressionLowerer with Lambda/Invoke handling and StrongBox access for captured variables (load via LoadField, store via StoreField) - Rewrite inner lambdas to accept StrongBox<T> parameters and compile with System compiler, enabling shared mutable state between outer and inner delegates - Update HyperbeeCompiler to integrate capture scanning before lowering - Add ScanForNonEmbeddableConstants support for Lambda/Invoke nodes - Add ClosureTests with 12 test cases covering no-capture, single capture, multiple captures, mutable captures, and mixed scenarios - Add native HyperbeeCompiler.Compile tests for Pattern 3 in FecKnownIssues (no longer needs CompileWithFallback) All 167 compiler tests + 12 issue tests pass across net8.0/net9.0/net10.0. * feat(compiler): add Phase 4 completeness — loop, switch, array, collection init, coalesce, quote Add support for all remaining expression types to make HyperbeeCompiler a drop-in replacement for Expression.Compile(): Lowering (ExpressionLowerer): - Loop expressions with break/continue labels - Switch expressions with int/string cases, multiple test values, custom comparison - NewArrayInit and NewArrayBounds (single and multi-dimensional) - ArrayIndex (binary), ArrayLength (unary), Index (indexer property or array) - ListInit (List, Dictionary collection initializers) - MemberInit (property and field assignment bindings) - Coalesce (null coalescing for reference types and nullable value types) - TypeEqual (exact type match via GetType() == typeof(T)) - Quote (expression tree as data) - Power (Math.Pow) - Unbox (unbox.any) - DebugInfo (no-op) IL emission (ILEmissionPass): - NewArray (newarr), LoadElement/StoreElement (typed ldelem/stelem variants) - LoadArrayLength (ldlen + conv.i4), LoadAddress (ldloca) Also fixes void conditional handling in full ternary path to pop non-void results when the conditional type is void. 60 new tests across 6 test files, all passing on net8.0/net9.0/net10.0. * feat(compiler): add Phase 5 optimization — PeepholePass, allocation reduction, benchmark updates Add PeepholePass with 7 peephole patterns: StoreLocal/LoadLocal to Dup/StoreLocal, dead load elimination (LoadConst/Pop, LoadNull/Pop, LoadLocal/Pop), identity Box/UnboxAny removal, Dup/Pop elimination, and branch-to-fallthrough removal. Reduce allocations: pre-size IRBuilder lists and ExpressionLowerer dictionaries, optimize BuildConstantsMapping from O(operands*instructions) to O(operands+instructions) using a HashSet pre-scan. Update benchmarks to use HyperbeeCompiler.Compile directly (no fallback needed) and add Loop and Switch tier benchmarks. Results show Hyperbee within 1.3-1.8x of FEC compilation speed and 8-30x faster than System compiler. * fix(compiler): remove CompileWithFallback masking, fix 30 IR lowering bugs CompilerType.Hyperbee was using CompileWithFallback which silently fell back to the System compiler on any failure, masking all bugs. Changed to use HyperbeeCompiler.Compile directly. Fixed lowering bugs exposed by removing fallback: - LowerDefault: removed broken InitObj+StoreLocal pattern, use zero-initialized local - LowerConditional: non-void ternary stores branch results to temp local - LowerAndAlso/OrElse: replaced Dup across labels with result-local pattern - LowerCoalesce: rewrote both nullable and reference paths with temp locals - Added ExpressionType.Increment/Decrement to unary handler - NewExpression without constructor now handles value-type default - LowerAssign now supports IndexExpression (array/indexer assignment) - IRValidator: moved LoadArrayLength from push to neutral category Also includes allocation reduction (lazy dictionaries, reduced capacities, StackSpillPass fast-exit), nullable warning fixes, new Phase 9 tests (559 total), and FEC IssueTests patterns 4-10. * fix(compiler): Pattern 8 native, switch result-local, increment/decrement tests - Pattern 8 (box/unbox in conditional) now uses HyperbeeCompiler.Compile natively after LowerConditional fix - LowerSwitch: non-void switch uses result-local pattern so stack is empty at labels, fixing string switch without explicit comparison - Added PostIncrementAssign, PreIncrementAssign, PostDecrementAssign tests - Added string switch without explicit comparison test * feat(compiler): Phase 6 — nullable lifted ops, exception filters, RuntimeVariables - Add lifted nullable binary operations (arithmetic + comparisons) via LowerLiftedBinary, LowerLiftedComparison, LowerLiftedArithmetic - Add lifted nullable unary operations via LowerLiftedUnary - Add Nullable<T> ↔ T conversions and enum underlying-type conversions in LowerConvert (fixes TypeConversionTests for Hyperbee compiler) - Add exception filter support: BeginFilter / BeginFilteredCatch IR ops, IL emission, DeadCodePass sentinel, IRValidator stack depth - Add RuntimeVariables support: RuntimeVariablesHelper, CaptureScanner FindRuntimeVariablesCaptures, LowerRuntimeVariables with StrongBox array - Fix TypeIs to use ldtoken + Type.GetTypeFromHandle (embeddable in CompileToMethod) - Add OnesComplement to supported unary ops - Improve closure binding: BuildClosureBinder for non-invoked captured lambdas - Remove obsolete IROp entries: LoadClosureVar, StoreClosureVar, CreateDelegate - Add README.md with architecture overview and benchmark comparison table - Add FecKnownIssues patterns 11-20 (AddAssign, TypeAs, closures, filter, etc.) - Add test files: BitwiseTests, CompileToMethodTests, DynamicExpressionTests, RuntimeVariablesTests (679 tests passing across net8/net9/net10) * fix(compiler): document FEC crash on Not(bool?) as known failure FEC generates incorrect IL for Not(Nullable<bool>): calling the compiled delegate with any argument causes AccessViolationException (crashes the test host process). The bug exists because FEC does not null-guard the lifted Not operation — it attempts to dereference the nullable value without checking HasValue first. - NullableTests.Not_NullableBool(Fast): guard before delegate invocation with Assert.Fail, documenting the bug rather than crashing the host - FecKnownIssues.Pattern21: add native Hyperbee verification test with explanation of why the FEC variant cannot be safely tested Effect: 808 tests total, 807 pass, 1 documented FEC failure (no crash). Previously: 648 tests appeared to pass, then host crashed (160 tests never ran due to the fatal AccessViolationException mid-run). * feat(compiler): Phase 7 — test suite expansion, FEC policy enforcement, IR fixes Compiler fixes: - Add unsigned checked IR opcodes (AddCheckedUn, SubCheckedUn, MulCheckedUn, ConvertCheckedUn) to IROp, IRValidator, ILEmissionPass, and ExpressionLowerer - Fix float/double comparisons to use IsUnsignedOrFloat (clt.un/cgt.un for unordered NaN semantics) - Fix nullable Power lowering to emit null-propagation guard - Fix ~30 additional expression lowering correctness bugs Test infrastructure: - Remove FEC→System fallback from CompileFast — FEC failures now surface as test failures - FecKnownIssues.cs rewritten: only FEC-specific _FecBug and CompileWithFallback tests (no redundant _HyperbeeNative tests); added Pattern23 (ulong LessThan) and Pattern25 (ConvertChecked ulong→long) as verifiable _FecBug tests - Policy: System fails → remove test; FEC fails → suppress + FecKnownIssues link; Hyperbee fails → fix - Remove two invalid all-compiler-crash patterns (NewArrayInit_NullableIntArray, ConvertChecked_NullableIntToByte_Overflow) New test files (6): - BlockTests.cs, ControlFlowTests.cs, ConvertCheckedTests.cs - LambdaTests.cs, NullableArithmeticTests.cs, NullableBitwiseTests.cs Expanded test files (11): - ArrayTests, BinaryTests, CollectionInitTests, ComparisonTests, ConditionalTests - ExceptionHandlingTests, LoopTests, NullableTests, SwitchTests, TypeConversionTests, UnaryTests Result: 1,559 total test instances — 1,551 passed, 8 skipped (all FEC-only), 0 failed * feat(compiler): Phase 8 — expand test suite to 2,426 instances, fix compiler bugs Expand HyperbeeCompiler test suite from ~1,766 to 2,426 instances (0 failures): Compiler fixes: - Add RightShiftUn opcode (shr.un) for unsigned logical right shift; uint/ulong RightShift now correctly emits shr.un instead of sign-extending shr - Fix IRValidator false positive: track expected stack depth per label from branch sites so conditional sub-expressions inside arithmetic no longer fail stack-depth validation - Add lifted IsFalse/IsTrue support in LowerLiftedUnary for bool? operands New test coverage: - ComparisonTests: NaN comparisons (all 6 ops × float/double), infinity comparisons, float basic comparisons, decimal comparisons (+20 methods) - ArrayTests: 2D/3D array bounds creation, 2D read/write, zero-length arrays, nullable array, bool/long/string arrays, out-of-bounds throws (+11 methods) - BoundaryValueTests: float NaN propagation, infinity arithmetic, int boundary wrapping, float/double divide by zero (+10 methods) - UnaryTests: fix IsFalse/IsTrue nullable semantics (bool? → bool?), fix Negate_SByte (widening pattern), FEC suppress for PostIncrementAssign_Double (+fixes) - ExceptionHandlingTests: fix 3 tests with try/catch type mismatch (void vs value) - Multiple type-complete arithmetic/comparison tests across session * fix(compiler): fix null Nullable<T> constant crash, update benchmarks and README - Fix AccessViolationException in LowerConstant: Constant(null, typeof(int?)) was emitting ldnull, but stelem for a value type expects a struct on the stack. CLR zeroes locals on declaration, so a fresh temp local already holds default(Nullable<T>) — emit LoadLocal directly instead of LoadNull. - Re-enable NewArrayInit_NullableIntArray_AccessElements test (3 DataRows). - Update README compilation benchmarks to latest run (9–34x vs System, 1.11–1.47x vs FEC); add execution benchmarks table; document CompileToMethod API. * revert(expressions): remove MoveNextCompiler hook, restore clean AsyncStateMachineBuilder Reverts premature integration of HEC into hyperbee.expressions before the compiler was proven correct on state-machine patterns. MoveNextCompiler option removed from ExpressionRuntimeOptions; compiler project reference removed from expressions test project. * feat(compiler): add CompileToInstanceMethod + state-machine pattern tests - CompileToInstanceMethodTests: covers field read/write, non-embeddable constant rejection, and the StateMachineCompiler sentinel - StateMachinePatternTests: 12 tests proving HEC compiles every pattern produced by the async state machine lowerer — Switch dispatch tables, instance field read/write, IfThen+Return (suspend pattern), ref parameter calls, TryCatch wrapping, and multi-state MoveNext shapes — all verified against System compiler * feat(compiler): Milestone 1 — pluggable coroutine builder interfaces Introduce ICoroutineDelegateBuilder and ICoroutineImplementationBuilder as the abstraction layer for async state machine compilation, replacing the previous IEntryPointGenerator / IStateMachineGenerator names. "Coroutine" is the CS term for the suspend/resume pattern underlying both async/await and yield-return — not tied to state machines and safe for future .NET runtime-native async (e.g. .NET 11+). Changes: - ICoroutineBuilder.cs: defines ICoroutineDelegateBuilder (public) and ICoroutineImplementationBuilder (internal, reserved for M3) - AsyncStateMachineBuilder.cs: DefaultCoroutineDelegateBuilder replaces SystemEntryPointGenerator; raw-lambda embedding preserved for default, Constant(delegate) used for custom builders - ExpressionRuntimeOptions.cs: EntryPointGenerator → DelegateBuilder - HyperbeeCoroutineDelegateBuilder.cs: HEC implementation (was HecEntryPointGenerator) - CompilerDiagnostics.cs + IRFormatter.cs: diagnostic infrastructure - nestedCompiler wired in ExpressionLowerer for recursive HEC compilation - BlockAsyncHecTests.cs: integration tests (3 pass, 8 known HEC bugs) All Hyperbee.Expressions.Tests pass (669/3). No regressions. * refactor(compiler): rename AsyncInterpreterTaskBuilder to AsyncTaskMethodBuilderBox Replaces the misleadingly named AsyncInterpreterTaskBuilder<TResult> with AsyncTaskMethodBuilderBox<TResult>, which clearly communicates its purpose: a typed heap box around the AsyncTaskMethodBuilder<TResult> struct, required because expression tree MemberExpression access copies struct fields, making direct struct mutation impossible without a class wrapper. Adds XML doc comments explaining the struct-copy problem, the box pattern, and why StrongBox<T> alone would not suffice. * feat(compiler): Milestone 2 — HEC compiles all BlockAsync patterns, test suite 2547/21 Compiler fixes: - HyperbeeCompiler: ScanForNonEmbeddableConstants now returns true for extension nodes so AsyncBlockExpression reduction is handled correctly (SingleAwait, VoidResult) - ILEmissionPass: short branch auto-upgraded to long branch when offset exceeds ±127 bytes (fixes ConditionalAwait illegal one-byte branch) - ExpressionLowerer: struct field method calls emit Constrained prefix + LoadFieldAddress for TaskAwaiter<T> fields (fixes stack underflow in SequentialAwaits/TryCatch) Test reorganization: - BlockAsync*Tests moved from Expressions/ to Integration/ — these are pipeline integration tests, not HEC expression pattern tests - StateMachinePatternTests deleted; patterns redistributed: - Ref/out parameter tests added to MethodCallTests (AwaitOnCompleted pattern) - Switch dispatch-table tests added to SwitchTests (state-dispatch pattern) Test expansion: - MethodCallTests: +5 ref/out parameter tests - SwitchTests: +3 switch-as-dispatch-table tests (null default, Goto-bodied cases) - CompileToInstanceMethodTests: 7 → 17 tests - RuntimeVariablesTests: 5 → 13 tests Results: 2547 passed, 21 skipped, 0 failed (net9.0) * feat(compiler): Milestone 3 — ambient CoroutineBuilderContext, IExpressionCompiler, remove DelegateBuilder from options - Add CoroutineBuilderContext (AsyncLocal per-compilation + static process-wide default) with Exchange(), SetScope(), SetDefault() — compiler choice never passes through BlockAsync options - Add IExpressionCompiler interface + SystemExpressionCompiler in Hyperbee.Expressions - Add HyperbeeExpressionCompiler (DI-injectable adapter) in Hyperbee.Expressions.Compiler - HyperbeeCompiler.Compile() sets ambient via Exchange() in try/finally; adds UseAsDefault()/ClearDefault() - AsyncStateMachineBuilder reads CoroutineBuilderContext.Current directly; removes DefaultCoroutineDelegateBuilder - Remove ExpressionRuntimeOptions.DelegateBuilder — options describe behavior only, not compiler choice - Simplify AsyncBlockExpression.Reduce(); remove ResolvedOptions() - Integration tests: remove HecOptions() from all BlockAsync tests; IRCapture test uses SetScope() - Add BlockAsyncContextTests covering ambient and process-wide default paths * refactor(tests): move FEC Pattern 28 to FecKnownIssues, remove always-Inconclusive test - Add FecKnownIssues.Pattern28: Return(label, Assign(...)) inside async-lowered TryCatch generates invalid IL in FEC (incomplete error 1007 detection; FEC issue #495) - Update BlockAsyncTryCatchTests: standardize Fast suppress message to reference Pattern28 - Remove CompileFast_ShouldReturnNull_ForReturnGotoFromTryCatchWithAssign from CompilerCompatibilityTests — always-Inconclusive placeholder, now documented in FecKnownIssues - Solution skips: 23 total (2 Expressions.Tests + 21 Compiler.Tests), all FEC suppressions * fix(compiler): Phase 5 IL optimization — eliminate merge-point locals, fix void-assign and ldelema bugs Remove unnecessary merge-point result locals from conditional, logical, and coalesce lowering by leaving values on the evaluation stack at merge points (valid in CIL when stack depth is consistent across all paths). Saves 3–5 instructions and 1–2 locals per occurrence. Void-lambda with bare Assign body: set _discardResult=true to suppress the Dup that was incorrectly leaving a value on the stack before Ret. Void block ending in Assign: extend suppressAssign logic so the final Pop is not emitted after an Assign (the value was never pushed in the first place). ldelema fix: Assign to a field of a struct stored in an array element requires ldelema (managed pointer) not ldelem (value copy). Add IROp.LoadElementAddress, emit Ldelema in ILEmissionPass, handle in IRValidator/IRFormatter. New EmitInstanceForFieldAssign helper routes value-type instances through EmitLoadAddress, which now handles ArrayIndex-on-value-type via ldelema. Fix also covers mutating instance method calls on struct array elements. Add test coverage: void-lambda assign patterns (5 tests), struct-array-element field and property assignment patterns (5 tests) — all passing for System, FEC, and HEC. * refactor(compiler): remove dead code, fix Exchange perf, add benchmark delta columns - Remove IROp.Switch (never emitted), IRValidator.ValidateAlways (never called) - Remove scope subsystem: IROp.BeginScope/EndScope, IRBuilder.EnterScope/ExitScope, LocalInfo.ScopeDepth — entire subsystem was no-op (no IL emitted, no pass consumed it) - Remove CompilerDiagnostics.ILCapture (declared but never wired or invoked) - Gate CoroutineBuilderContext.Exchange on ScanForNonEmbeddableConstants to avoid unnecessary AsyncLocal writes for simple expressions; pass pre-computed result into LowerToIR to eliminate redundant traversal — restores 9-34x speedup vs SEC - Add BenchmarkExpressions (shared definitions), BenchmarkColumns (RatioToColumn for vs-SEC and vs-FEC delta columns), expand ExecutionBenchmarks to all 6 tiers - Update README with current benchmark numbers and expanded execution table * docs: comprehensive just-the-docs documentation structure Add full documentation for Hyperbee.Expressions, Hyperbee.Expressions.Compiler, and Hyperbee.Expressions.Lab following the established just-the-docs pattern used across sibling projects (hyperbee.pipeline, hyperbee.json, hyperbee.xs). Structure (27 markdown files across 4 sections): - index.md — landing page with package table, quick start, expression type index - expressions/ — parent + 12 children (async-block, enumerable-block, await, yield, for, foreach, while, using, debug, string-format, inject, configuration-value) - configuration/ — parent + 3 children (runtime-options, module-providers, dependency-injection) - compiler/ — parent + 4 children (overview, api, diagnostics, performance) - lab/ — parent + 3 children (fetch, json, map-reduce) Infrastructure: - _config.yml — adds baseurl, url, footer_content, nav_external_links - _includes/nav_footer_custom.html — branded footer - docs.projitems — updated to include all 27 pages * docs: replace non-ASCII characters with ASCII equivalents Replace em/en dashes, arrows, box-drawing, micro sign, and other non-ASCII Unicode with ASCII-only substitutions so all docs .md files are plain ASCII. * Remove non-ascii chars from docs * feat: Add IR opcodes for fused comparison branches and CIL switch * feat: Support new IR opcodes in IR pipeline diagnostics and validation * feat: Implement CIL emission for fused branch and switch instructions * perf: Implement peephole optimizations for fused comparison branches and redundant assignments * fix: Optimize redundant IROp.Leave instructions in exception blocks * feat: Enhance SwitchExpression lowering with CIL jump table optimization * test: Introduce ILComparisonTool for compiler output diagnostics * docs: Update README with minor formatting and text improvements
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.
Description
Fixes async expression compiler bugs and updates nugets (#133)
Fix [BUG]: Incorrect handling of value-type to object assignment when using BlockAsync (missing boxing) #126: Add EnsureConvert helper to Transition base class that wraps
value-type expressions in Convert() when assigning to reference-type
variables (boxing). Applied in Transition.SetResult and
FinalTransition.AddExpressions.
Add failing test for [BUG]: Usage of a conditional return label results in an unexpected null value #123: IfThen with Return(label, value) in
BlockAsync returns null instead of expected value. Root cause is in the
lowering phase where Returns inside non-lowered conditionals are not
converted to _finalResultVariable assignments.
Expand ExpressionRuntimeOptions with Optimize flag (default true) to
conditionally skip StateOptimizer, and SourceHandler callback to
capture the generated state machine expression for debugging.
Change SourceHandler to Action with UnsafeAccessor for DebugView, add tests
fix(expressions): Ensure Return gotos inside non-lowered expressions set final result
test(expressions): Add regression test for Return labels in async TryCatch
test(compiler): Add FastExpressionCompiler compatibility test for Return gotos with assignments
Update nugets and cleanup
Type of Change
Checklist