|
| @@ -7,12 +7,57 @@ reference answers for 33 575 expressions (tokens with positions, error |
| 7 | | messages, result kinds, string coercions, `toJSON` output), and | 7 | | messages, result kinds, string coercions, `toJSON` output), and |
| 8 | | `TestOracle` replays it. `gen/oracle.mjs` regenerates it, `gen/golden.mjs` the | 8 | | `TestOracle` replays it. `gen/oracle.mjs` regenerates it, `gen/golden.mjs` the |
| 9 | | `testdata/tojson` goldens, and `gen/casing_dump.mjs` + `gen/casing.go` the | 9 | | `testdata/tojson` goldens, and `gen/casing_dump.mjs` + `gen/casing.go` the |
| 10 | - | casing tables (Node 25 / V8 14.1, Unicode 16; Go 1.27 ships Unicode 15). | 10 | + | casing tables (`go generate ./expr`; Node 25 / V8 14.1, Unicode 16). The |
| | | 11 | + | tables are relative to the Go toolchain's own Unicode tables |
| | | 12 | + | (`unicode.Version`); `TestCasingTablesMatchGoUnicodeVersion` fails with the |
| | | 13 | + | regeneration command when the toolchain changes. The oracle records the |
| | | 14 | + | npm integrity (sha512) of the reference tarball and the Node/V8/Unicode |
| | | 15 | + | versions in its `reference` field, and `TestOracle` logs them. |
| 11 | | | 16 | | |
| 12 | | The C# runner (actions/runner, `DistributedTask/Expressions2`) is the | 17 | | The C# runner (actions/runner, `DistributedTask/Expressions2`) is the |
| 13 | | implementation that runs on github.com. It was not available while this was | 18 | | implementation that runs on github.com. It was not available while this was |
| 14 | | written. Nothing below has been checked against it. | 19 | | written. Nothing below has been checked against it. |
| 15 | | | 20 | | |
| | | 21 | + | ## Limits added by this port (not in the JavaScript) |
| | | 22 | + | |
| | | 23 | + | The reference has no bound on what an evaluation may build. These are |
| | | 24 | + | additions, each reported as an `*EvalError` (or `*Error` for the parser) and |
| | | 25 | + | none changes the result of an evaluation that stays within them. |
| | | 26 | + | |
| | | 27 | + | - **Output budget** (`MaxResultBytes`, 1 MiB by default, `EvalContext. |
| | | 28 | + | MaxResultBytes` to override, negative to disable). One budget per |
| | | 29 | + | `Evaluate`, charged by `format` (every piece appended), `join` (items and |
| | | 30 | + | separators), `toJSON` (the encoder stops as soon as the output would exceed |
| | | 31 | + | what is left) and by every element of the arrays built by `.*` / `[*]` |
| | | 32 | + | (16 bytes each). `format('{0}{0}', format('{0}{0}', ...))` chains and |
| | | 33 | + | `a.*.*.*` fan-outs over shared arrays are cut off instead of exhausting |
| | | 34 | + | memory. Strings that come out of `fromJSON` are not charged: their size is |
| | | 35 | + | bounded by the input the caller provided. The cost per filtered element is a |
| | | 36 | + | guess; revisit it if real workflows hit the limit. |
| | | 37 | + | - **Cancellation**: `Evaluate(ctx, ...)` checks `ctx` every 64 nodes and in the |
| | | 38 | + | loops of filters, `join` and `contains`, and passes `ctx` to extension |
| | | 39 | + | functions. |
| | | 40 | + | - **Evaluation depth** of 1000 for hand-built trees (parsed trees stay far |
| | | 41 | + | below it), **JSON depth** `MaxJSONDepth` = 1000 for `FromJSON` and for the |
| | | 42 | + | encoder (cyclic values built with `Array.Append` yield an error from |
| | | 43 | + | `EncodeJSON`, `"null"` from `ToJSON`, an `*EvalError` from `toJSON()`). |
| | | 44 | + | The JS recursion limit is engine-dependent, around 5 000 to 10 000. |
| | | 45 | + | - **Built-in arity is re-checked at evaluation**, so a hand-built AST gets an |
| | | 46 | + | `*EvalError`, not a panic. |
| | | 47 | + | - **Input length** is checked before the input is converted, without |
| | | 48 | + | allocating. |
| | | 49 | + | |
| | | 50 | + | Other limits that exist in the JS and are ported: expression length 21000 |
| | | 51 | + | UTF-16 units and parser depth 50 (see below). |
| | | 52 | + | |
| | | 53 | + | ## Performance notes (deferred) |
| | | 54 | + | |
| | | 55 | + | - GO-008: `Evaluate` rebuilds the case-folded context and function maps on |
| | | 56 | + | every call, and `foldKey` lower-cases on each lookup. Fine for per-step |
| | | 57 | + | evaluation; when a caller evaluates thousands of expressions against the |
| | | 58 | + | same contexts, add a prepared `Environment` (fold once, reuse) and cache |
| | | 59 | + | folded names in the AST. |
| | | 60 | + | |
| 16 | | ## Where the JavaScript is believed to differ from the C# runner | 61 | | ## Where the JavaScript is believed to differ from the C# runner |
| 17 | | | 62 | | |
| 18 | | Each item is implemented as the JavaScript does. Check the runner's tests | 63 | | Each item is implemented as the JavaScript does. Check the runner's tests |
|
| @@ -125,7 +170,15 @@ a bug. |
| 125 | | evaluating e.g. `github.true` with an empty context: the reference does not | 170 | | evaluating e.g. `github.true` with an empty context: the reference does not |
| 126 | | handle a missing root context. Here it is null. | 171 | | handle a missing root context. Here it is null. |
| 127 | | - Recursion limits: JS recursion depth for `fromJSON` input is engine | 172 | | - Recursion limits: JS recursion depth for `fromJSON` input is engine |
| 128 | - | dependent (about 5 000 to 10 000 levels). `FromJSON` accepts 10 000 levels. | 173 | + | dependent (about 5 000 to 10 000 levels). `FromJSON` accepts `MaxJSONDepth` |
| | | 174 | + | (1000) levels. |
| | | 175 | + | - Lone surrogates: JS strings are UTF-16 and can hold them; Go strings are |
| | | 176 | + | UTF-8. They are kept as WTF-8 (`0xED 0xA0-0xBF xx`) so that `fromJSON` / |
| | | 177 | + | `toJSON` round-trip, `==`/`<`/`contains`/`startsWith`/`endsWith` compare |
| | | 178 | + | them like code units, case mapping copies them, and `format`/`join` rejoin a |
| | | 179 | + | high surrogate followed by a low one into the character they form. This is |
| | | 180 | + | covered by oracle cases. Two surrogate strings concatenated by other means |
| | | 181 | + | (an extension function) are not rejoined. |
| 129 | | | 182 | | |
| 130 | | ## Other things to check once the runner is available | 183 | | ## Other things to check once the runner is available |
| 131 | | | 184 | | |