Skip to content

Add data-oriented flat expression tree (ExprTree/ExprNode) with LightExpression conversion#519

Closed
Copilot wants to merge 3 commits into
masterfrom
copilot/optimize-expression-serialization
Closed

Add data-oriented flat expression tree (ExprTree/ExprNode) with LightExpression conversion#519
Copilot wants to merge 3 commits into
masterfrom
copilot/optimize-expression-serialization

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 19, 2026

Implements a compact, struct-based, stack-friendly representation of expression trees as described in the issue — suitable for serialization, structural equality, and future compiler integration.

Core design

  • ExprNode — a single node with Type, Obj (payload), and a packed ulong _data:

    [NodeType:8][Extra:8][Unused:16][ChildCount:16][FirstChildPoolIdx:16]
    

    Extra encodes auxiliary per-type data (lambda param count, block var count, goto kind, try variant, by-ref flag, instance flag).

  • ExprTree — the flat container:

    public struct ExprTree {
        public SmallList<ExprNode, Stack16<ExprNode>, NoArrayPool<ExprNode>> Nodes;
        public SmallList<ushort, Stack16<ushort>, NoArrayPool<ushort>> ChildPool;
    }

    First 16 nodes and 16 child-pool slots live on the stack; larger trees spill to the heap.

Non-intrusive child pool

Uses a flat ChildPool (array of ushort indices) instead of the intrusive NextSiblingIdx approach sketched in the issue. This avoids corruption when the same node (e.g. a Parameter) appears as a child of multiple parents — the common case for lambda parameters used in the body.

API

Factory methods on ExprTree return ushort node indices:

var e = default(ExprTree);
var p = e.Parameter<int>("x");
var body = e.Add(p, e.Constant(10));
var lam = e.Lambda<Func<int, int>>(body, p);

// Convert to LightExpression for compilation
var f = e.ToLambdaExpression(lam).CompileFast<Func<int, int>>();
// f(5) == 15

Covers all expression types supported by LightExpression: constants, parameters/variables, constructors, method calls, field/property/index access, all binary and unary ops, lambda, block, conditional, loop, try/catch/finally/fault, label, goto/return/break/continue, switch, type tests, default, invoke, array init/bounds, member init, list init.

Conversion to LightExpression

ToLightExpression(ushort) recursively converts with a ParameterExpression[] cache (indexed by node index) to ensure the same ParameterExpression instance is reused across all references to the same parameter node — required by the LightExpression/FEC compiler.

Not wired into the FEC compiler directly yet; conversion via ToLightExpression enables full test coverage of all expression shapes.

Copilot AI changed the title [WIP] Optimize data-oriented representation of Expression for serialization Add data-oriented flat expression tree (ExprTree/ExprNode) with LightExpression conversion Apr 19, 2026
Copilot AI requested a review from dadhi April 19, 2026 22:24
@dadhi
Copy link
Copy Markdown
Owner

dadhi commented Apr 20, 2026

Wrong

@dadhi dadhi closed this Apr 20, 2026
@dadhi dadhi deleted the copilot/optimize-expression-serialization branch April 21, 2026 06:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants