@yabgu_gm/tensionscript 0.10.0 → 0.11.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -11,7 +11,7 @@ and the package are its own: it does not collide with `asc` (AssemblyScript's
11
11
  compiler) or `tsc` (TypeScript's), so a project that installs both compilers
12
12
  always resolves the one it named.
13
13
 
14
- **Current version: 0.10.0.** The [feature showcase](docs/showcase.md) has one
14
+ **Current version: 0.11.0.** The [feature showcase](docs/showcase.md) has one
15
15
  section per capability, with runnable examples and the refused forms; the scoping
16
16
  notes it draws from are in [`docs/`](docs/).
17
17
 
@@ -109,7 +109,7 @@ the record layout builds on AS's `Type` machinery, and std gains
109
109
 
110
110
  The fork is a fork. The divergence is deliberate, it is bounded, and each change
111
111
  lands with fixtures — see *What this fork adds* above for the list, and
112
- [`docs/fork-arc-scope.md`](docs/fork-arc-scope.md) for the measurement that
112
+ [`docs/fork-posture.md`](docs/fork-posture.md) for the measurement that
113
113
  established the posture. Features AssemblyScript cannot express — memory-model
114
114
  overrides, the scheduler contract — are in scope here; a feature is not rejected
115
115
  for lacking an AS equivalent.
@@ -120,9 +120,9 @@ for lacking an AS equivalent.
120
120
  what it deliberately shares with AssemblyScript, what it diverges on, and the
121
121
  quarterly sync cadence. [`docs/showcase.md`](docs/showcase.md) is the
122
122
  per-capability reference — examples, semantics, and what each feature refuses.
123
- [`docs/fork-arc-scope.md`](docs/fork-arc-scope.md) sequences the remaining work.
124
- Deferred and named, each with its reason in
125
- [`docs/session-findings.md`](docs/session-findings.md):
123
+ [`docs/roadmap.md`](docs/roadmap.md) carries the deferred items, the durable
124
+ findings, and the workflow this repository uses. Deferred and named, each with
125
+ its reason there:
126
126
 
127
127
  - **Inline nesting** — an `@inline struct` as a field of another record.
128
128
  - **`T[N]` fields in `@inline struct`** — deep SROA, one local per element.
@@ -135,7 +135,7 @@ Deferred and named, each with its reason in
135
135
  requirement (`TS6399`).
136
136
 
137
137
  The full deferred list, with the reason for each, is
138
- [showcase §9](docs/showcase.md) and [posture §6](docs/fork-posture.md).
138
+ [showcase §9](docs/showcase.md) and [`docs/roadmap.md`](docs/roadmap.md).
139
139
 
140
140
  ## Links
141
141
 
@@ -143,10 +143,8 @@ The full deferred list, with the reason for each, is
143
143
  - TensionScript (this compiler): https://github.com/Yabgu/TensionScript
144
144
  - Fork posture — what the fork is, what it shares, how it stays current:
145
145
  [`docs/fork-posture.md`](docs/fork-posture.md)
146
- - Fork arc and phase sequencing:
147
- [`docs/fork-arc-scope.md`](docs/fork-arc-scope.md)
148
- - Session findings — what each measurement found, and the traps:
149
- [`docs/session-findings.md`](docs/session-findings.md)
146
+ - Roadmap — deferred features, durable findings, and the workflow:
147
+ [`docs/roadmap.md`](docs/roadmap.md)
150
148
  - Scheduler contract: [`docs/scheduler-contract.md`](docs/scheduler-contract.md)
151
149
  - Changelog: [`CHANGELOG.md`](CHANGELOG.md)
152
150
 
@@ -2039,7 +2039,14 @@ declare module "types:tensionscript/src/diagnosticMessages.generated" {
2039
2039
  A_spawn_produces_a_Task_this_one_is_never_awaited_so_the_task_s_result_is_discarded = 6401,
2040
2040
  An_await_forces_an_immediate_read_of_lazy_so_the_deferral_is_nullified_drop_the_lazy_or_remove_the_await = 6402,
2041
2041
  An_enum_underlying_type_must_be_one_of_i8_u8_i16_u16_i32_or_u32_not_0 = 6403,
2042
- Enum_member_0_does_not_fit_the_underlying_type_1 = 6404
2042
+ Enum_member_0_does_not_fit_the_underlying_type_1 = 6404,
2043
+ _abi_align_requires_a_single_integer_literal_argument_the_alignment_is_a_compile_time_constant_so_a_computed_value_cannot_be_read_where_the_layout_is_decided = 6405,
2044
+ _abi_align_0_the_alignment_must_be_at_least_1 = 6406,
2045
+ _abi_align_0_the_alignment_must_be_a_power_of_two = 6407,
2046
+ _abi_align_0_is_less_than_the_field_type_s_natural_alignment_1_asking_for_less_is_a_lie_so_it_is_refused_rather_than_silently_ignored = 6408,
2047
+ _abi_align_0_is_too_large_the_maximum_is_1 = 6409,
2048
+ Alignment_is_a_property_of_the_field_not_its_type_Place_abi_align_N_on_the_field_declaration = 6410,
2049
+ A_view_parameter_unmanaged_0_over_an_inline_type_cannot_appear_in_a_host_visible_signature_an_external_or_exported_parameter_is_supplied_by_the_host_and_a_view_is_an_address_this_compiler_did_not_materialise = 6411
2043
2050
  }
2044
2051
  /** Translates a diagnostic code to its respective string. */
2045
2052
  export function diagnosticCodeToString(code: DiagnosticCode): string;
@@ -2951,6 +2958,60 @@ declare module "types:tensionscript/src/resolver" {
2951
2958
  currentElementExpression: Expression | null;
2952
2959
  /** Whether a new override has been discovered. */
2953
2960
  discoveredOverride: boolean;
2961
+ /**
2962
+ * Whether a use-site `@unmanaged` over an `@inline` declaration is being
2963
+ * resolved as the **type argument of `changetype`**.
2964
+ *
2965
+ * That position is the one where the operand can supply the address the value
2966
+ * itself does not have, so the refusal's premise does not hold there (see
2967
+ * `checkMemoryModelOverride`). Every other position — a parameter, a local, a
2968
+ * field, a return type — still refuses with `TS6395`, which is what keeps the
2969
+ * function-parameter form (`Phase 2`) out of this change.
2970
+ *
2971
+ * The compiler sets this around the one `resolveTypeArguments` call it makes
2972
+ * for a `changetype` builtin (`Compiler#compileCallExpressionBuiltin`), and
2973
+ * resets it immediately: the flag is a scope, not a mode.
2974
+ */
2975
+ allowInlineView: boolean;
2976
+ /**
2977
+ * Whether a use-site `@unmanaged` over an `@inline` declaration is being
2978
+ * resolved in a **parameter position** — the cell where the caller supplies
2979
+ * the address, so `f(a: @unmanaged T)` with an inline `T` is a view parameter.
2980
+ *
2981
+ * Distinct from {@link allowInlineView} (Phase 1, `changetype`'s type
2982
+ * argument, where the operand supplies the address at the point of use).
2983
+ *
2984
+ * **Saved and restored, never blindly cleared.** Resolving one parameter's
2985
+ * type can resolve another function (a default value's call, a nested
2986
+ * signature), and a nested window that reset the flag to `false` on the way
2987
+ * out closed the outer window — measured: the owner's pattern reported TS6395
2988
+ * with both flags reading `false` while inside `resolveFunction`'s own loop.
2989
+ */
2990
+ allowInlineViewParam: boolean;
2991
+ /**
2992
+ * Call expressions that are **views of caller bytes**: an inline-typed
2993
+ * `changetype<@unmanaged T>(ptr)`.
2994
+ *
2995
+ * Marked here, at resolution, because the compiler asks this question while
2996
+ * compiling the *field access* — which happens before the `changetype` it
2997
+ * wraps is ever compiled. Recording it at codegen time (the first attempt)
2998
+ * produced a field read that never saw the mark and compiled to
2999
+ * `unreachable`.
3000
+ *
3001
+ * Keyed on the AST node rather than on the type, because the type is the
3002
+ * declaration's (`T` is still an `@inline struct`) and the model is the
3003
+ * *use's*: there is one `Type` per class, shared by every use.
3004
+ */
3005
+ private viewCalls;
3006
+ /**
3007
+ * Records `node` as a view call. The resolver marks the ones it resolves;
3008
+ * `Compiler#compileCallExpressionBuiltin` marks the ones it resolves itself,
3009
+ * because a builtin's type arguments are resolved on the *codegen* path and
3010
+ * never pass through `maybeInferCall`.
3011
+ */
3012
+ markViewCall(node: Expression): void;
3013
+ /** Whether `node` is an inline-typed `changetype<@unmanaged T>(...)`. */
3014
+ isViewCall(node: Expression): boolean;
2954
3015
  /** Constructs the resolver for the specified program. */
2955
3016
  constructor(
2956
3017
  /** The program to construct a resolver for. */
@@ -2978,10 +3039,14 @@ declare module "types:tensionscript/src/resolver" {
2978
3039
  * - **`@managed` over an `@unmanaged` declaration** — the collector traces a
2979
3040
  * reference through a header the record does not have. No emitter can
2980
3041
  * invent the header, so a use cannot confer provenance. (`TS6394`.)
2981
- * - **`@unmanaged`/`@managed` over an `@inline` declaration** — a value is
2982
- * stored as one local per field and has **no address** at all, so there is
2983
- * nothing to lend as a pointer and nothing a header could sit in front of.
2984
- * (`TS6395`.)
3042
+ * - **`@managed` over an `@inline` declaration** — a value has neither a
3043
+ * header nor an address, at any position. (`TS6395`.)
3044
+ * - **`@unmanaged` over an `@inline` declaration**, *except* where the use
3045
+ * supplies an address: `changetype`'s type argument (the operand supplies
3046
+ * it) and a parameter (the caller supplies it). Those two windows are
3047
+ * `allowInlineView` and `allowInlineViewParam`, and they are the whole
3048
+ * difference between a view and a claim. Every other position — a return
3049
+ * type, a local, a field — still has nothing to lend. (`TS6395`.)
2985
3050
  *
2986
3051
  * Everything else is left to the emitters: `@unmanaged` over `@managed` is
2987
3052
  * the identity cell (10.0a), `@inline` over a pointer declaration is the
@@ -3619,6 +3684,14 @@ declare module "types:tensionscript/src/program" {
3619
3684
  function fromUnaryPostfixToken(token: Token): OperatorKind;
3620
3685
  }
3621
3686
  /** Represents an AssemblyScript program. */
3687
+ /** How many WASM slots a parameter binding consumed — see
3688
+ * `Program#bindSroaParameterLeaves`. A one-field wrapper because this compiler
3689
+ * reports the count and the caller advances past it; a bare `i32` return would
3690
+ * be the same information with no name at the call site. */
3691
+ export class BindResult {
3692
+ leafCount: number;
3693
+ constructor(leafCount: number);
3694
+ }
3622
3695
  export class Program extends DiagnosticEmitter {
3623
3696
  /** Compiler options. */
3624
3697
  options: Options;
@@ -4335,6 +4408,17 @@ declare module "types:tensionscript/src/program" {
4335
4408
  * therefore cannot alias.
4336
4409
  */
4337
4410
  fieldLocals: Map<string, Local> | null;
4411
+ /**
4412
+ * Whether this local is a **view parameter**: `a: @unmanaged T` where `T` is
4413
+ * an inline type.
4414
+ *
4415
+ * Its `type` is still the inline record, because that is what makes `a.field`
4416
+ * resolve — every use of `T` shares one `Type`. Its *storage* is the one `i32`
4417
+ * WASM parameter holding the caller's address, which is why a field read goes
4418
+ * through `load` at the field's offset rather than through `fieldLocals`
4419
+ * (there are none: a view has no per-field locals to copy into).
4420
+ */
4421
+ isViewParam: boolean;
4338
4422
  /** Constructs a new local variable. */
4339
4423
  constructor(
4340
4424
  /** Simple name. */
@@ -4446,6 +4530,20 @@ declare module "types:tensionscript/src/program" {
4446
4530
  nextInlineId: number;
4447
4531
  /** Counting id of anonymous inner functions. */
4448
4532
  nextAnonymousId: number;
4533
+ /**
4534
+ * Binds an `@inline struct` parameter's **leaves** to the WASM parameters that
4535
+ * carry them, building the `fieldLocals` tree a read path walks.
4536
+ *
4537
+ * `localIndex` is the index of the parameter's first WASM slot; the walk
4538
+ * consumes one slot per leaf in the same depth-first order
4539
+ * `Signature.leafTypesOf` declares and the caller pushes operands in. Returns
4540
+ * how many slots were consumed, so the caller advances past them.
4541
+ *
4542
+ * A nested field gets a placeholder `Local` (index `-1`) carrying its own map,
4543
+ * exactly as `fillSroaFieldLocals` builds one for a local — the tree shape is
4544
+ * one structure regardless of where the leaves' storage came from.
4545
+ */
4546
+ bindSroaParameterLeaves(type: Type, path: string, into: Map<string, Local>, localIndex: number, flow: Flow): BindResult;
4449
4547
  /** Constructs a new concrete function. */
4450
4548
  constructor(
4451
4549
  /** Name incl. type parameters, i.e. `foo<i32>`. */
@@ -5134,8 +5232,9 @@ declare module "types:tensionscript/src/types" {
5134
5232
  * own model is still on the `Type`
5135
5233
  * (`type.classReference.hasDecorator(...)`). The boundary emitters want both —
5136
5234
  * the override decides *how the parameter crosses*, the type decides what may
5137
- * be done with it. See `docs/memconv-signature-scope.md` §5.2 for why rooting
5138
- * deliberately reads only the second.
5235
+ * be done with it. Rooting deliberately reads only the second: the override
5236
+ * says how the parameter crosses, while the type says what may be done with
5237
+ * it.
5139
5238
  */
5140
5239
  memoryModelOf(sourceIndex: number): number;
5141
5240
  /**
@@ -5152,6 +5251,21 @@ declare module "types:tensionscript/src/types" {
5152
5251
  * all of them.
5153
5252
  */
5154
5253
  static wasmParamCountOf(type: Type): number;
5254
+ /**
5255
+ * Appends the **leaf** types of an `@inline struct`, in declaration order,
5256
+ * depth first.
5257
+ *
5258
+ * A leaf is a field that occupies one WASM local: a scalar or a reference. A
5259
+ * field whose type is itself an `@inline struct` is not a leaf — it is several
5260
+ * locals behind a map — so the walk recurses into it. This is the type-level
5261
+ * twin of the `fieldLocals` tree the compiler builds
5262
+ * (`Compiler#fillSroaFieldLocals`), and the two must agree in **order** as
5263
+ * well as count: the callee binds WASM parameter *k* to the *k*th leaf, and
5264
+ * the caller pushes operands in the same walk.
5265
+ */
5266
+ static leafTypesOf(type: Type, out: Type[]): void;
5267
+ /** The number of leaf locals an `@inline struct` occupies. */
5268
+ static leafCountOf(type: Type): number;
5155
5269
  /**
5156
5270
  * How many WASM operands **this signature** spends on source parameter
5157
5271
  * `sourceIndex`.
@@ -5168,6 +5282,18 @@ declare module "types:tensionscript/src/types" {
5168
5282
  * the same source parameter.
5169
5283
  */
5170
5284
  wasmParamSlotCountOf(sourceIndex: number): number;
5285
+ /**
5286
+ * Whether source parameter `sourceIndex` is a **view**: `@unmanaged` at the
5287
+ * declaration over a type that is an `@inline struct`.
5288
+ *
5289
+ * The type still says *value* — every use of `MyStruct` shares one `Type`, and
5290
+ * that is what makes a member lookup work on the parameter — while the model
5291
+ * says this use is an address. One `i32` slot, no field locals, a load at the
5292
+ * field's offset: the same crossing an `@unmanaged struct` parameter already
5293
+ * takes, with the model recorded at the declaration instead of on a pointer
5294
+ * type.
5295
+ */
5296
+ isViewParam(sourceIndex: number): boolean;
5171
5297
  /**
5172
5298
  * Whether source parameter `sourceIndex` **crosses by value** — one `i32`
5173
5299
  * address instead of one WASM operand per field.
@@ -5181,8 +5307,12 @@ declare module "types:tensionscript/src/types" {
5181
5307
  * address, and the override asks for a copy of what is there — the same
5182
5308
  * copy, read from memory instead of from SROA locals.
5183
5309
  *
5184
- * The reverse is not a thing: `@unmanaged`/`@managed` over an `@inline`
5185
- * declaration is refused (`TS6395`), because a value has no address to lend.
5310
+ * The reverse is partly a thing now. `@unmanaged` over an `@inline`
5311
+ * declaration is legal where the use supplies an address — a parameter (a
5312
+ * view parameter, `isViewParam`) or `changetype`'s type argument — and a view
5313
+ * parameter crosses as a pointer, so it is asked before this predicate. Every
5314
+ * other cell still refuses (`TS6395`), and `@managed` over `@inline` refuses
5315
+ * at every position: a value has no GC header and no address to lend.
5186
5316
  */
5187
5317
  crossesByValueParam(sourceIndex: number): boolean;
5188
5318
  /**
@@ -5205,9 +5335,17 @@ declare module "types:tensionscript/src/types" {
5205
5335
  get byValPointerParams(): boolean;
5206
5336
  /** Whether `type` is an `@inline struct`. */
5207
5337
  static isInlineStructRef(type: Type): boolean;
5208
- /** The number of fields an `@inline struct` has (0 for a record with none).
5209
- * Distinct from `wasmParamCountOf`, which cannot express "one field" and
5210
- * "one operand" differently. */
5338
+ /**
5339
+ * How many **WASM slots** an `@inline struct` spends — its leaf count.
5340
+ *
5341
+ * Leaf count, not direct-field count: a nested inline field is several locals,
5342
+ * so `Outer1 { a: u32; inner: Inner{x,y} }` is 3, not 2. A record with no
5343
+ * members is 0.
5344
+ *
5345
+ * Callers that made sense of "direct fields" are listed in the Phase C audit
5346
+ * (`docs`); the one place that genuinely needs the direct count is layout, and
5347
+ * layout reads `members` itself rather than asking this.
5348
+ */
5211
5349
  static fieldCountOf(type: Type): number;
5212
5350
  /**
5213
5351
  * Whether a call to this signature passes a hidden destination pointer.
@@ -5370,6 +5508,7 @@ declare module "types:tensionscript/src/builtins" {
5370
5508
  const select = "~lib/builtins/select";
5371
5509
  const unreachable = "~lib/builtins/unreachable";
5372
5510
  const changetype = "~lib/builtins/changetype";
5511
+ const copyInto = "~lib/builtins/copyInto";
5373
5512
  const assert = "~lib/builtins/assert";
5374
5513
  const call_indirect = "~lib/builtins/call_indirect";
5375
5514
  const unchecked = "~lib/builtins/unchecked";
@@ -9804,7 +9943,7 @@ declare module "types:tensionscript/src/compiler" {
9804
9943
  import { Range, DiagnosticEmitter } from "types:tensionscript/src/diagnostics";
9805
9944
  import { Module, MemorySegment, ExpressionRef, TypeRef, GlobalRef } from "types:tensionscript/src/module";
9806
9945
  import { Feature, Target, Runtime } from "types:tensionscript/src/common";
9807
- import { Program, Class, Element, DeclaredElement, Enum, Function, Global, Property, VariableLikeElement, File } from "types:tensionscript/src/program";
9946
+ import { Program, Class, Element, DeclaredElement, Enum, Function, Global, Local, Property, VariableLikeElement, File } from "types:tensionscript/src/program";
9808
9947
  import { Flow, ConditionKind } from "types:tensionscript/src/flow";
9809
9948
  import { Resolver } from "types:tensionscript/src/resolver";
9810
9949
  import { Node, FunctionTypeNode, Statement, Expression } from "types:tensionscript/src/ast";
@@ -10467,11 +10606,27 @@ declare module "types:tensionscript/src/compiler" {
10467
10606
  /**
10468
10607
  * The SROA local an expression names, or `null`.
10469
10608
  *
10470
- * Only a bare identifier can be one: `p.x.y` where `x` is itself an inline
10471
- * struct cannot happen this phase (a nested field is refused at declaration),
10472
- * so the receiver of a field access is either an SROA local or an ordinary
10473
- * expression that has an address.
10609
+ * The receiver is either an SROA local (base identifier) or a chain of field
10610
+ * accesses into one (`o.inner` in `o.inner.x`). The chain is walked from the
10611
+ * base outward, one hop per `fieldLocals` lookup: a nested inline field is
10612
+ * entered through the placeholder `Local` its creation installed
10613
+ * (`fillSroaFieldLocals`), so the walk and the tree are one structure rather
10614
+ * than two that could disagree.
10615
+ *
10616
+ * Returns the `Local` the final hop resolved to, or `null` when any step does
10617
+ * not hold — a non-local base, a field with no entry, or a leaf reached before
10618
+ * the chain ends. `null` is not an error here: the caller falls through to the
10619
+ * ordinary address paths, which refuse a value with no address.
10620
+ */
10621
+ /**
10622
+ * Pushes one operand per **leaf** of a `fieldLocals` tree, depth first.
10623
+ *
10624
+ * Shared by the call site (`expandSroaArgument`) so the operand order is the
10625
+ * one `Signature.leafTypesOf` declares and the binder indexes into — three
10626
+ * walks, one order. A nested field's entry is a placeholder (index `-1`)
10627
+ * carrying its own map, so the walk descends through it.
10474
10628
  */
10629
+ private pushSroaLeafOperands;
10475
10630
  private resolveSroaReceiver;
10476
10631
  /** Size of the static call-temp region, in bytes. 4 KB is 256 slots at the
10477
10632
  * 16-byte fixture record size. Overflow aborts (see `makeSretCallBlock`);
@@ -10561,6 +10716,15 @@ declare module "types:tensionscript/src/compiler" {
10561
10716
  /** `base + mark + extra`, freshly built. Callers must not share the node:
10562
10717
  * Binaryen's passes assume a single parent per expression. */
10563
10718
  private makeSretAddressPlus;
10719
+ /**
10720
+ * Stores a by-value argument's leaves into the static call-temp region.
10721
+ *
10722
+ * The same tree walk as `copyInto` (`emitSroaStores`) and `copySroaValue`:
10723
+ * leaves become stores at `tempAddress + field offset`, a nested field is
10724
+ * descended into. Keeping one recursion is what makes a nested value cross a
10725
+ * host boundary at the layout the C side expects.
10726
+ */
10727
+ emitTempArgumentLeaves(type: Type, fieldLocals: Map<string, Local>, base: number, markLocal: Local, baseOffset: number, stmts: ExpressionRef[]): void;
10564
10728
  /**
10565
10729
  * Materialises one `@inline struct` argument of an `@external` call on the
10566
10730
  * static call-temp stack and returns the address to pass.
@@ -10631,6 +10795,93 @@ declare module "types:tensionscript/src/compiler" {
10631
10795
  * Returns true when the declaration was handled here (the caller must not fall
10632
10796
  * through to the ordinary local path).
10633
10797
  */
10798
+ /**
10799
+ * Fills `into` with one entry per field of an `@inline struct` value.
10800
+ *
10801
+ * A **leaf** field (scalar, or a reference) gets one WASM local, named
10802
+ * `<path>$<field>` — a synthetic name keeps it out of user scope, so nothing
10803
+ * can look one up by accident.
10804
+ *
10805
+ * A field whose type is itself an `@inline struct` is **not a leaf**: it is
10806
+ * recursed into, and its entry is a placeholder `Local` (index `-1`) carrying
10807
+ * its own map. That makes `fieldLocals` a **tree** whose shape is the value's
10808
+ * nesting, which is what lets a read path walk `o.inner.x` a hop at a time
10809
+ * without a second representation. The placeholder is never `local.get`-ed:
10810
+ * the bare-read guard refuses a value read and the receiver walk descends to
10811
+ * a leaf before emitting anything.
10812
+ *
10813
+ * Returns `false` when a field was refused, having reported why. The refusal
10814
+ * is per **leaf**, so a nested value inherits exactly the rules the flat one
10815
+ * has — a `T[N]` field or a GC-reference field is refused at any depth.
10816
+ */
10817
+ private fillSroaFieldLocals;
10818
+ /**
10819
+ * Copies one SROA value's leaves into another's, following the tree.
10820
+ *
10821
+ * `from` and `to` are the two `fieldLocals` maps — the same shape
10822
+ * `fillSroaFieldLocals` builds, so a nested field is a placeholder on both
10823
+ * sides and the recursion descends through it rather than trying to move a
10824
+ * value that has no single representation.
10825
+ *
10826
+ * This is what makes `let q = p` and `q = p` **copies** rather than aliases:
10827
+ * one `local.set` per leaf, so a later write to `q` cannot be seen through
10828
+ * `p`. Both sides come from this compiler's own maps, so there is no aliasing
10829
+ * question to answer — the leaves are distinct locals by construction.
10830
+ */
10831
+ private copySroaValue;
10832
+ /**
10833
+ * Stores a `fieldLocals` tree's leaves into the hidden destination slot at
10834
+ * `destIndex`, one store per leaf.
10835
+ *
10836
+ * The third destination shape for the same recursion: `emitSroaStores` writes
10837
+ * to a compiled `usize`, `emitTempArgumentLeaves` to a call-temp address, and
10838
+ * this one to a **parameter** — the sret slot a `return p` fills. The address
10839
+ * is a fresh `local.get` per store, because Binaryen's passes assume one
10840
+ * parent per node.
10841
+ */
10842
+ emitSroaStoresToLocal(type: Type, fieldLocals: Map<string, Local>, destIndex: number, baseOffset: number, stmts: ExpressionRef[]): void;
10843
+ /**
10844
+ * Zeroes every **leaf** of an `@inline struct` in the destination slot.
10845
+ *
10846
+ * `return new P()` has no local to copy from — the value is all zeroes — but
10847
+ * the slot is stack space that a previous sret call may have filled, so the
10848
+ * bytes still have to be written. Walking the type rather than the direct
10849
+ * fields is what zeroes a nested field's leaves: measured before this,
10850
+ * `return new Outer1()` with `Inner{x,y}` stored only offset 0 and left
10851
+ * offsets 4 and 8 holding whatever was there.
10852
+ */
10853
+ emitSroaZerosToLocal(type: Type, destIndex: number, baseOffset: number, stmts: ExpressionRef[]): void;
10854
+ /**
10855
+ * Loads an `@inline struct`'s leaves out of the sret slot into a target's
10856
+ * field locals, one load per leaf.
10857
+ *
10858
+ * The mirror of {@link emitSroaStoresToLocal}: `let q = make()` reads the slot
10859
+ * back into the leaf locals a read path walks. A fresh slot address per load,
10860
+ * for the same one-parent-per-node reason.
10861
+ */
10862
+ emitSretLoadsInto(type: Type, fieldLocals: Map<string, Local>, base: number, markLocal: Local, baseOffset: number, stmts: ExpressionRef[]): void;
10863
+ /**
10864
+ * The `fieldLocals` tree behind an SROA-tracked expression, or `null`.
10865
+ *
10866
+ * The public face of {@link resolveSroaReceiver} for code outside this class —
10867
+ * today only the `copyInto` builtin, which needs the *tree* (to store its
10868
+ * leaves) rather than a single receiver.
10869
+ */
10870
+ sroaTreeOf(expression: Expression): Map<string, Local> | null;
10871
+ /**
10872
+ * Stores an inline value's leaves at `dest + offset`.
10873
+ *
10874
+ * The third leaf consumer, beside `copySroaValue` (local-to-local) and the
10875
+ * read path (local-to-stack): same tree, same recursion, an expression
10876
+ * reference instead of a destination map. The offsets come from the **type**
10877
+ * (`property.memoryOffset`, the layout the C side sees), so what lands in
10878
+ * memory is the wire layout, not a packing of the locals.
10879
+ *
10880
+ * Leaves whose local is missing are skipped rather than stored as `-1`: a
10881
+ * field refused at declaration was never part of the value (`isSroaFieldType`
10882
+ * has already reported why), and the caller has been told.
10883
+ */
10884
+ emitSroaStores(type: Type, fieldLocals: Map<string, Local>, dest: ExpressionRef, baseOffset: number, stmts: ExpressionRef[]): void;
10634
10885
  private compileSroaLocal;
10635
10886
  /**
10636
10887
  * The instance fields of an `@inline struct`, in declaration order, or `null`
package/dist/asc.js CHANGED
@@ -5,7 +5,7 @@
5
5
  * SPDX-License-Identifier: Apache-2.0
6
6
  */
7
7
  var le=Object.defineProperty;var Me=Object.getOwnPropertyDescriptor;var Pe=Object.getOwnPropertyNames;var Ve=Object.prototype.hasOwnProperty;var cn=(e,t,n)=>()=>{if(n)throw n[0];try{return e&&(t=e(e=0)),t}catch(r){throw n=[r],r}};var nn=(e,t)=>{for(var n in t)le(e,n,{get:t[n],enumerable:!0})},se=(e,t,n,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of Pe(t))!Ve.call(e,s)&&s!==n&&le(e,s,{get:()=>t[s],enumerable:!(r=Me(t,s))||r.enumerable});return e},Dn=(e,t,n)=>(se(e,t,"default"),n&&se(n,t,"default"));var ue={};nn(ue,{promises:()=>je});var je,fe=cn(()=>{"use strict";je={}});var ce={};nn(ce,{createRequire:()=>Ge});function Ge(){return function(t){throw new Error(`Cannot find module: '${t}'`)}}var de=cn(()=>{"use strict"});var kn={};nn(kn,{argv:()=>Ke,cwd:()=>In,exit:()=>qe,hrtime:()=>Ye,platform:()=>Xe,umask:()=>He});function In(){return"."}function He(){return 0}function qe(e=0){throw Error(`exit ${e}`)}function Ye(e){var t=We.call(xe),n=Math.floor(t*.001),r=Math.floor(t*1e6-n*1e9);return e&&(n-=e[0],r-=e[1],r<0&&(n--,r+=1e9)),[n,r]}var Xe,Ke,xe,We,On=cn(()=>{"use strict";Xe="linux";Ke=[];xe=globalThis.performance||{},We=xe.now||function(){return new Date().getTime()}});var Rn={};nn(Rn,{basename:()=>et,delimiter:()=>at,dirname:()=>nt,extname:()=>tt,format:()=>it,isAbsolute:()=>Ze,join:()=>Je,normalize:()=>he,parse:()=>rt,relative:()=>Qe,resolve:()=>dn,sep:()=>Ln,win32:()=>ot});function j(e){if(typeof e!="string")throw new TypeError("Path must be a string. Received "+JSON.stringify(e))}function pe(e,t){for(var n="",r=0,s=-1,o=0,f,c=0;c<=e.length;++c){if(c<e.length)f=e.charCodeAt(c);else{if(f===47)break;f=47}if(f===47){if(!(s===c-1||o===1))if(s!==c-1&&o===2){if(n.length<2||r!==2||n.charCodeAt(n.length-1)!==46||n.charCodeAt(n.length-2)!==46){if(n.length>2){var p=n.lastIndexOf("/");if(p!==n.length-1){p===-1?(n="",r=0):(n=n.slice(0,p),r=n.length-1-n.lastIndexOf("/")),s=c,o=0;continue}}else if(n.length===2||n.length===1){n="",r=0,s=c,o=0;continue}}t&&(n.length>0?n+="/..":n="..",r=2)}else n.length>0?n+="/"+e.slice(s+1,c):n=e.slice(s+1,c),r=c-s-1;s=c,o=0}else f===46&&o!==-1?++o:o=-1}return n}function $e(e,t){var n=t.dir||t.root,r=t.base||(t.name||"")+(t.ext||"");return n?n===t.root?n+r:n+e+r:r}function dn(){for(var e="",t=!1,n,r=arguments.length-1;r>=-1&&!t;r--){var s;r>=0?s=arguments[r]:(n===void 0&&(n=In()),s=n),j(s),s.length!==0&&(e=s+"/"+e,t=s.charCodeAt(0)===47)}return e=pe(e,!t),t?e.length>0?"/"+e:"/":e.length>0?e:"."}function he(e){if(j(e),e.length===0)return".";var t=e.charCodeAt(0)===47,n=e.charCodeAt(e.length-1)===47;return e=pe(e,!t),e.length===0&&!t&&(e="."),e.length>0&&n&&(e+="/"),t?"/"+e:e}function Ze(e){return j(e),e.length>0&&e.charCodeAt(0)===47}function Je(){if(arguments.length===0)return".";for(var e,t=0;t<arguments.length;++t){var n=arguments[t];j(n),n.length>0&&(e===void 0?e=n:e+="/"+n)}return e===void 0?".":he(e)}function Qe(e,t){if(j(e),j(t),e===t||(e=dn(e),t=dn(t),e===t))return"";if(e===".")return t;for(var n=1;n<e.length&&e.charCodeAt(n)===47;++n);for(var r=e.length,s=r-n,o=1;o<t.length&&t.charCodeAt(o)===47;++o);for(var f=t.length,c=f-o,p=s<c?s:c,b=-1,d=0;d<=p;++d){if(d===p){if(c>p){if(t.charCodeAt(o+d)===47)return t.slice(o+d+1);if(d===0)return t.slice(o+d)}else s>p&&(e.charCodeAt(n+d)===47?b=d:d===0&&(b=0));break}var g=e.charCodeAt(n+d),y=t.charCodeAt(o+d);if(g!==y)break;g===47&&(b=d)}var m="";for(d=n+b+1;d<=r;++d)(d===r||e.charCodeAt(d)===47)&&(m.length===0?m+="..":m+="/..");return m.length>0?m+t.slice(o+b):(o+=b,t.charCodeAt(o)===47&&++o,t.slice(o))}function nt(e){if(j(e),e.length===0)return".";for(var t=e.charCodeAt(0),n=t===47,r=-1,s=!0,o=e.length-1;o>=1;--o)if(t=e.charCodeAt(o),t===47){if(!s){r=o;break}}else s=!1;return r===-1?n?"/":".":n&&r===1?"//":e.slice(0,r)}function et(e,t){if(t!==void 0&&typeof t!="string")throw new TypeError('"ext" argument must be a string');j(e);var n=0,r=-1,s=!0,o;if(t!==void 0&&t.length>0&&t.length<=e.length){if(t.length===e.length&&t===e)return"";var f=t.length-1,c=-1;for(o=e.length-1;o>=0;--o){var p=e.charCodeAt(o);if(p===47){if(!s){n=o+1;break}}else c===-1&&(s=!1,c=o+1),f>=0&&(p===t.charCodeAt(f)?--f===-1&&(r=o):(f=-1,r=c))}return n===r?r=c:r===-1&&(r=e.length),e.slice(n,r)}else{for(o=e.length-1;o>=0;--o)if(e.charCodeAt(o)===47){if(!s){n=o+1;break}}else r===-1&&(s=!1,r=o+1);return r===-1?"":e.slice(n,r)}}function tt(e){j(e);for(var t=-1,n=0,r=-1,s=!0,o=0,f=e.length-1;f>=0;--f){var c=e.charCodeAt(f);if(c===47){if(!s){n=f+1;break}continue}r===-1&&(s=!1,r=f+1),c===46?t===-1?t=f:o!==1&&(o=1):t!==-1&&(o=-1)}return t===-1||r===-1||o===0||o===1&&t===r-1&&t===n+1?"":e.slice(t,r)}function it(e){if(e===null||typeof e!="object")throw new TypeError('The "pathObject" argument must be of type Object. Received type '+typeof e);return $e("/",e)}function rt(e){j(e);var t={root:"",dir:"",base:"",ext:"",name:""};if(e.length===0)return t;var n=e.charCodeAt(0),r=n===47,s;r?(t.root="/",s=1):s=0;for(var o=-1,f=0,c=-1,p=!0,b=e.length-1,d=0;b>=s;--b){if(n=e.charCodeAt(b),n===47){if(!p){f=b+1;break}continue}c===-1&&(p=!1,c=b+1),n===46?o===-1?o=b:d!==1&&(d=1):o!==-1&&(d=-1)}return o===-1||c===-1||d===0||d===1&&o===c-1&&o===f+1?c!==-1&&(f===0&&r?t.base=t.name=e.slice(1,c):t.base=t.name=e.slice(f,c)):(f===0&&r?(t.name=e.slice(1,o),t.base=e.slice(1,c)):(t.name=e.slice(f,o),t.base=e.slice(f,c)),t.ext=e.slice(o,c)),f>0?t.dir=e.slice(0,f-1):r&&(t.dir="/"),t}var Ln,at,ot,Nn=cn(()=>{"use strict";On();Ln="/",at=":",ot=null});var ge={};nn(ge,{pathToFileURL:()=>lt});function st(e){return e.replace(/%/g,"%25").replace(/\\/g,"%5C").replace(/\n/g,"%0A").replace(/\r/g,"%0D").replace(/\t/g,"%09")}function lt(e){let t=dn(e);e.charCodeAt(e.length-1)===47&&t[t.length-1]!==Ln&&(t+="/");let n=new URL("file://");return n.pathname=st(t),n}var me=cn(()=>{"use strict";Nn()});var Wn={};nn(Wn,{Stats:()=>Cn,checkDiagnostics:()=>Tn,compileString:()=>Dt,configToArguments:()=>qn,createMemoryStream:()=>Hn,default:()=>Wn,defaultOptimizeLevel:()=>we,defaultShrinkLevel:()=>Se,definitionFiles:()=>St,libraryFiles:()=>G,libraryPrefix:()=>L,main:()=>De,options:()=>wt,tscOptions:()=>It,version:()=>Xn});var ut=Object.prototype.toString.call(typeof globalThis.process<"u"?globalThis.process:0)==="[object process]",X,sn,v,P,xn;ut?(X=await import("fs"),sn=await import("module"),v=await import("path"),P=globalThis.process,xn=await import("url")):(X=await Promise.resolve().then(()=>(fe(),ue)),sn=await Promise.resolve().then(()=>(de(),ce)),v=await Promise.resolve().then(()=>(Nn(),Rn)),P=await Promise.resolve().then(()=>(On(),kn)),xn=await Promise.resolve().then(()=>(me(),ge)));var En=typeof process<"u"&&process||{},ft=En.env&&"CI"in En.env,ct="\x1B[90m",dt="\x1B[91m",xt="\x1B[92m",pt="\x1B[93m",ht="\x1B[94m",gt="\x1B[95m",mt="\x1B[96m",bt="\x1B[97m",W="\x1B[0m",en=class{constructor(t){this.stream=t,this.enabled=!!(this.stream&&this.stream.isTTY||ft)}gray(t){return this.enabled?ct+t+W:t}red(t){return this.enabled?dt+t+W:t}green(t){return this.enabled?xt+t+W:t}yellow(t){return this.enabled?pt+t+W:t}blue(t){return this.enabled?ht+t+W:t}magenta(t){return this.enabled?gt+t+W:t}cyan(t){return this.enabled?mt+t+W:t}white(t){return this.enabled?bt+t+W:t}},An=new en(En.stdout),Lt=new en(En.stderr);function yt(e){for(var t=0,n=0,r=e.length;n<r;++n){let s=e.charCodeAt(n);s<128?t+=1:s<2048?t+=2:(s&64512)===55296&&n+1<r&&(e.charCodeAt(n+1)&64512)===56320?(++n,t+=4):t+=3}return t}function Ft(e,t,n){var r=n-t;if(r<1)return"";for(var s=null,o=[],f=0,c;t<n;)c=e[t++],c<128?o[f++]=c:c>191&&c<224?o[f++]=(c&31)<<6|e[t++]&63:c>239&&c<365?(c=((c&7)<<18|(e[t++]&63)<<12|(e[t++]&63)<<6|e[t++]&63)-65536,o[f++]=55296+(c>>10),o[f++]=56320+(c&1023)):o[f++]=(c&15)<<12|(e[t++]&63)<<6|e[t++]&63,f>=8192&&((s||(s=[])).push(String.fromCharCode(...o)),f=0);return s?(f&&s.push(String.fromCharCode(...o.slice(0,f))),s.join("")):String.fromCharCode(...o.slice(0,f))}function vt(e,t,n){for(var r=n,s=0,o=e.length;s<o;++s){let f=e.charCodeAt(s),c;f<128?t[n++]=f:f<2048?(t[n++]=f>>6|192,t[n++]=f&63|128):(f&64512)===55296&&s+1<o&&((c=e.charCodeAt(s+1))&64512)===56320?(f=65536+((f&1023)<<10)+(c&1023),++s,t[n++]=f>>18|240,t[n++]=f>>12&63|128,t[n++]=f>>6&63|128,t[n++]=f&63|128):(t[n++]=f>>12|224,t[n++]=f>>6&63|128,t[n++]=f&63|128)}return n-r}var _n={length:yt,read:Ft,write:vt};var be=sn.createRequire(import.meta.url);function Fe(e,t,n=!0){var r={},s=[],o=[],f=[],c={};Object.keys(t).forEach(d=>{if(!d.startsWith(" ")){var g=t[d];g.alias!=null&&(typeof g.alias=="string"?c[g.alias]=d:Array.isArray(g.alias)&&g.alias.forEach(y=>c[y]=d)),n&&g.default!=null&&(r[d]=g.default)}});for(var p=0,b=(e=e.slice()).length;p<b;++p){let d=e[p];if(d=="--"){++p;break}let g=/^(?:(-\w)(?:=(.*))?|(--\w{2,})(?:=(.*))?)$/.exec(d),y,m;if(g)t[d]?y=t[m=d]:g[1]!=null?(y=t[m=c[g[1].substring(1)]],y&&g[2]!=null&&(e[p--]=g[2])):g[3]!=null&&(y=t[m=g[3].substring(2)],y&&g[4]!=null&&(e[p--]=g[4]));else if(d.charCodeAt(0)==45)y=t[m=d];else{o.push(d);continue}if(y)if(y.value)Object.keys(y.value).forEach(a=>r[a]=y.value[a]);else if(y.type==null||y.type==="b")r[m]=!0;else if(p+1<e.length&&e[p+1].charCodeAt(0)!=45)switch(y.type){case"i":r[m]=parseInt(e[++p],10);break;case"I":r[m]=(r[m]||[]).concat(parseInt(e[++p],10));break;case"f":r[m]=parseFloat(e[++p]);break;case"F":r[m]=(r[m]||[]).concat(parseFloat(e[++p]));break;case"s":r[m]=String(e[++p]);break;case"S":r[m]=(r[m]||[]).concat(e[++p].split(","));break;default:s.push(d),--p}else switch(y.type){case"i":case"f":r[m]=y.default||0;break;case"s":r[m]=y.default||"";break;case"I":case"F":case"S":r[m]=y.default||[];break;default:s.push(d)}else s.push(d)}for(;p<b;)f.push(e[p++]);return n&&Mn(t,r),{options:r,unknown:s,arguments:o,trailing:f}}function ve(e,t){t||(t={});var n=t.indent||2,r=t.padding||24,s=t.eol||`
8
- `,o={},f=[];Object.keys(e).forEach(b=>{var d=e[b];if(d.description!=null){for(var g="";g.length<n;)g+=" ";for(g+="--"+b,d.alias&&(g+=", -"+d.alias);g.length<r;)g+=" ";var y;!t.noCategories&&d.category?(y=o[d.category])||(o[d.category]=y=[]):y=f,Array.isArray(d.description)?y.push(g+d.description[0]+d.description.slice(1).map(m=>{for(let a=0;a<r;++a)m=" "+m;return s+m}).join("")):y.push(g+d.description)}});var c=[],p=!1;return Object.keys(o).forEach(b=>{p=!0,c.push(s+" "+An.gray(b)+s),c.push(o[b].join(s))}),p&&f.length&&c.push(s+" "+An.gray("Other")+s),c.push(f.join(s)),c.join(s)}function ye(e,t){if(e!=null)switch(t){case void 0:case"b":return!!e;case"i":return Math.trunc(e)||0;case"f":return Number(e)||0;case"s":return e===!0?"":e===!1?null:String(e);case"I":return Array.isArray(e)||(e=[e]),e.map(n=>Math.trunc(n)||0);case"F":return Array.isArray(e)||(e=[e]),e.map(n=>Number(n)||0);case"S":return Array.isArray(e)||(e=[e]),e.map(String)}}function Un(e,t,n,r){let s={};for(let[o,{type:f,mutuallyExclusive:c,isPath:p,useNodeResolution:b,cliOnly:d}]of Object.entries(e)){let g=ye(t[o],f),y=ye(n[o],f);if(g==null){if(y!=null){if(d)continue;if(Array.isArray(y)){let m;p&&(y=y.map(a=>tn(a,r,b))),c!=null&&(m=t[c])?s[o]=y.filter(a=>!m.includes(a)):s[o]=y.slice()}else p&&(y=tn(y,r,b)),s[o]=y}}else if(y==null)Array.isArray(g)?s[o]=g.slice():s[o]=g;else if(Array.isArray(g)){if(d){s[o]=g.slice();continue}let m;p&&(y=y.map(a=>tn(a,r,b))),c!=null&&(m=t[c])?s[o]=[...g,...y.filter(a=>!g.includes(a)&&!m.includes(a))]:s[o]=[...g,...y.filter(a=>!g.includes(a))]}else s[o]=g}return s}function Et(e){let t=v.parse(e);return t.root||(t.root="./"),v.format(t)}function tn(e,t,n=!1){return v.isAbsolute(e)?e:n&&!e.startsWith(".")&&be.resolve?be.resolve(e,{paths:[t]}):Et(v.join(t,e))}function Mn(e,t){for(let[n,{default:r}]of Object.entries(e))t[n]==null&&r!=null&&(t[n]=r)}var Ee="0.10.0",Y={version:{category:"General",description:"Prints just the compiler's version and exits.",type:"b",alias:"v"},help:{category:"General",description:"Prints this message and exits.",type:"b",alias:"h"},config:{category:"General",description:"Configuration file to apply. CLI arguments take precedence.",type:"s",cliOnly:!0},target:{category:"General",description:"Configuration file target to use. Defaults to 'release'.",type:"s",cliOnly:!0},optimize:{category:"Optimization",description:["Optimizes the module. Typical shorthands are:",""," Default optimizations -O"," Make a release build -O --noAssert"," Make a debug build --debug"," Optimize for speed -Ospeed"," Optimize for size -Osize",""],type:"b",alias:"O"},optimizeLevel:{category:"Optimization",description:"How much to focus on optimizing code. [0-3]",type:"i"},shrinkLevel:{category:"Optimization",description:"How much to focus on shrinking code size. [0-2, s=1, z=2]",type:"i"},converge:{category:"Optimization",description:"Re-optimizes until no further improvements can be made.",type:"b",default:!1},noAssert:{category:"Optimization",description:"Replaces assertions with just their value without trapping.",type:"b",default:!1},outFile:{category:"Output",description:"Specifies the WebAssembly output file (.wasm).",type:"s",alias:"o",isPath:!0},textFile:{category:"Output",description:"Specifies the WebAssembly text output file (.wat).",type:"s",alias:"t",isPath:!0},bindings:{category:"Output",description:["Specifies the bindings to generate (.js + .d.ts).",""," esm JavaScript bindings & typings for ESM integration."," raw Like esm, but exports just the instantiate function."," Useful where modules are meant to be instantiated"," multiple times or non-ESM imports must be provided."],type:"S",alias:"b"},sourceMap:{category:"Debugging",description:["Enables source map generation. Optionally takes the URL","used to reference the source map from the binary file."],type:"s"},uncheckedBehavior:{category:"Debugging",description:["Changes the behavior of unchecked() expressions.","Using this option can potentially cause breakage.",""," default The default behavior: unchecked operations are"," only used inside of unchecked()."," never Unchecked operations are never used, even when"," inside of unchecked()."," always Unchecked operations are always used if possible,"," whether or not unchecked() is used."],type:"s",default:"default"},debug:{category:"Debugging",description:"Enables debug information in emitted binaries.",type:"b",default:!1},importMemory:{category:"Features",description:"Imports the memory from 'env.memory'.",type:"b",default:!1},noExportMemory:{category:"Features",description:"Does not export the memory as 'memory'.",type:"b",default:!1},initialMemory:{category:"Features",description:"Sets the initial memory size in pages.",type:"i",default:0},maximumMemory:{category:"Features",description:"Sets the maximum memory size in pages.",type:"i",default:0},sharedMemory:{category:"Features",description:"Declare memory as shared. Requires maximumMemory.",type:"b",default:!1},zeroFilledMemory:{category:"Features",description:"Assume imported memory is zeroed. Requires importMemory.",type:"b",default:!1},importTable:{category:"Features",description:"Imports the function table from 'env.table'.",type:"b",default:!1},exportTable:{category:"Features",description:"Exports the function table as 'table'.",type:"b",default:!1},exportStart:{category:"Features",description:["Exports the start function using the specified name instead","of calling it implicitly. Useful to obtain the exported memory","before executing any code accessing it."],type:"s"},runtime:{category:"Features",description:["Specifies the runtime variant to include in the program.",""," incremental TLSF + incremental GC (default)"," minimal TLSF + lightweight GC invoked externally"," stub Minimal runtime stub (never frees)"," ... Path to a custom runtime implementation",""],type:"s",default:"incremental"},exportRuntime:{category:"Features",description:["Always exports the runtime helpers (__new, __collect, __pin etc.).","Automatically determined when generation of --bindings is enabled."],type:"b",default:!1},stackSize:{category:"Features",description:["Overrides the stack size. Only relevant for incremental GC","or when using a custom runtime that requires stack space.","Defaults to 0 without and to 32768 with incremental GC."],default:0,type:"i"},enable:{category:"Features",description:["Enables WebAssembly features being disabled by default.",""," threads Threading and atomic operations."," simd SIMD types and operations."," reference-types Reference types and operations."," gc Garbage collection (WIP)."," stringref String reference types."," relaxed-simd Relaxed SIMD operations.",""],TODO_doesNothingYet:[" exception-handling Exception handling."," tail-calls Tail call operations."," multi-value Multi value types."," memory64 Memory64 operations."," extended-const Extended const expressions."],type:"S",mutuallyExclusive:"disable"},disable:{category:"Features",description:["Disables WebAssembly features being enabled by default.",""," mutable-globals Mutable global imports and exports."," sign-extension Sign-extension operations"," nontrapping-f2i Non-trapping float to integer ops."," bulk-memory Bulk memory operations.",""],type:"S",mutuallyExclusive:"enable"},use:{category:"Features",description:["Aliases a global object under another name, e.g., to switch","the default 'Math' implementation used: --use Math=JSMath","Can also be used to introduce an integer constant."],type:"S",alias:"u"},lowMemoryLimit:{category:"Features",description:"Enforces very low (<64k) memory constraints.",default:0,type:"i"},memoryBase:{category:"Linking",description:"Sets the start offset of emitted memory segments.",type:"i",default:0},tableBase:{category:"Linking",description:"Sets the start offset of emitted table elements.",type:"i",default:0},transform:{category:"API",description:"Specifies the path to a custom transform to load.",type:"S",isPath:!0,useNodeResolution:!0},trapMode:{category:"Binaryen",description:["Sets the trap mode to use.",""," allow Allow trapping operations. This is the default."," clamp Replace trapping operations with clamping semantics."," js Replace trapping operations with JS semantics.",""],type:"s",default:"allow"},runPasses:{category:"Binaryen",description:["Specifies additional Binaryen passes to run after other","optimizations, if any. See: Binaryen/src/passes/pass.cpp"],type:"s"},noValidate:{category:"Binaryen",description:"Skips validating the module using Binaryen.",type:"b",default:!1},baseDir:{description:"Specifies the base directory of input and output files.",type:"s",default:"."},noColors:{description:"Disables terminal colors.",type:"b",default:!1},noUnsafe:{description:["Disallows the use of unsafe features in user code.","Does not affect library files and external modules."],type:"b",default:!1},disableWarning:{description:["Disables warnings matching the given diagnostic code.","If no diagnostic code is given, all warnings are disabled."],type:"I"},noEmit:{description:"Performs compilation as usual but does not emit code.",type:"b",default:!1},showConfig:{description:"Print computed compiler options and exit.",type:"b",default:!1},stats:{description:"Prints statistics on I/O and compile times.",type:"b",default:!1},pedantic:{description:"Make yourself sad for no good reason.",type:"b",default:!1},lib:{description:["Adds one or multiple paths to custom library components and","uses exports of all top-level files at this path as globals."],type:"S",isPath:!0},path:{description:["Adds one or multiple paths to package resolution, similar","to node_modules. Prefers an 'ascMain' entry in a package's","package.json and falls back to an inner 'assembly/' folder."],type:"S",isPath:!0},wasm:{description:"Uses the specified Wasm binary of the compiler.",type:"s"}," ...":{description:"Specifies node.js options (CLI only). See: node --help"},"-Os":{value:{optimizeLevel:0,shrinkLevel:1}},"-Oz":{value:{optimizeLevel:0,shrinkLevel:2}},"-O0":{value:{optimizeLevel:0,shrinkLevel:0}},"-O1":{value:{optimizeLevel:1,shrinkLevel:0}},"-O2":{value:{optimizeLevel:2,shrinkLevel:0}},"-O3":{value:{optimizeLevel:3,shrinkLevel:0}},"-O0s":{value:{optimizeLevel:0,shrinkLevel:1}},"-O1s":{value:{optimizeLevel:1,shrinkLevel:1}},"-O2s":{value:{optimizeLevel:2,shrinkLevel:1}},"-O3s":{value:{optimizeLevel:3,shrinkLevel:1}},"-O0z":{value:{optimizeLevel:0,shrinkLevel:2}},"-O1z":{value:{optimizeLevel:1,shrinkLevel:2}},"-O2z":{value:{optimizeLevel:2,shrinkLevel:2}},"-O3z":{value:{optimizeLevel:3,shrinkLevel:2}},"-Ospeed":{value:{optimizeLevel:3,shrinkLevel:0}},"-Osize":{value:{optimizeLevel:0,shrinkLevel:2,converge:!0}},"--measure":{value:{stats:!0}}},Ae="~lib/",_e={array:`/// <reference path="./rt/index.d.ts" />
8
+ `,o={},f=[];Object.keys(e).forEach(b=>{var d=e[b];if(d.description!=null){for(var g="";g.length<n;)g+=" ";for(g+="--"+b,d.alias&&(g+=", -"+d.alias);g.length<r;)g+=" ";var y;!t.noCategories&&d.category?(y=o[d.category])||(o[d.category]=y=[]):y=f,Array.isArray(d.description)?y.push(g+d.description[0]+d.description.slice(1).map(m=>{for(let a=0;a<r;++a)m=" "+m;return s+m}).join("")):y.push(g+d.description)}});var c=[],p=!1;return Object.keys(o).forEach(b=>{p=!0,c.push(s+" "+An.gray(b)+s),c.push(o[b].join(s))}),p&&f.length&&c.push(s+" "+An.gray("Other")+s),c.push(f.join(s)),c.join(s)}function ye(e,t){if(e!=null)switch(t){case void 0:case"b":return!!e;case"i":return Math.trunc(e)||0;case"f":return Number(e)||0;case"s":return e===!0?"":e===!1?null:String(e);case"I":return Array.isArray(e)||(e=[e]),e.map(n=>Math.trunc(n)||0);case"F":return Array.isArray(e)||(e=[e]),e.map(n=>Number(n)||0);case"S":return Array.isArray(e)||(e=[e]),e.map(String)}}function Un(e,t,n,r){let s={};for(let[o,{type:f,mutuallyExclusive:c,isPath:p,useNodeResolution:b,cliOnly:d}]of Object.entries(e)){let g=ye(t[o],f),y=ye(n[o],f);if(g==null){if(y!=null){if(d)continue;if(Array.isArray(y)){let m;p&&(y=y.map(a=>tn(a,r,b))),c!=null&&(m=t[c])?s[o]=y.filter(a=>!m.includes(a)):s[o]=y.slice()}else p&&(y=tn(y,r,b)),s[o]=y}}else if(y==null)Array.isArray(g)?s[o]=g.slice():s[o]=g;else if(Array.isArray(g)){if(d){s[o]=g.slice();continue}let m;p&&(y=y.map(a=>tn(a,r,b))),c!=null&&(m=t[c])?s[o]=[...g,...y.filter(a=>!g.includes(a)&&!m.includes(a))]:s[o]=[...g,...y.filter(a=>!g.includes(a))]}else s[o]=g}return s}function Et(e){let t=v.parse(e);return t.root||(t.root="./"),v.format(t)}function tn(e,t,n=!1){return v.isAbsolute(e)?e:n&&!e.startsWith(".")&&be.resolve?be.resolve(e,{paths:[t]}):Et(v.join(t,e))}function Mn(e,t){for(let[n,{default:r}]of Object.entries(e))t[n]==null&&r!=null&&(t[n]=r)}var Ee="0.11.1",Y={version:{category:"General",description:"Prints just the compiler's version and exits.",type:"b",alias:"v"},help:{category:"General",description:"Prints this message and exits.",type:"b",alias:"h"},config:{category:"General",description:"Configuration file to apply. CLI arguments take precedence.",type:"s",cliOnly:!0},target:{category:"General",description:"Configuration file target to use. Defaults to 'release'.",type:"s",cliOnly:!0},optimize:{category:"Optimization",description:["Optimizes the module. Typical shorthands are:",""," Default optimizations -O"," Make a release build -O --noAssert"," Make a debug build --debug"," Optimize for speed -Ospeed"," Optimize for size -Osize",""],type:"b",alias:"O"},optimizeLevel:{category:"Optimization",description:"How much to focus on optimizing code. [0-3]",type:"i"},shrinkLevel:{category:"Optimization",description:"How much to focus on shrinking code size. [0-2, s=1, z=2]",type:"i"},converge:{category:"Optimization",description:"Re-optimizes until no further improvements can be made.",type:"b",default:!1},noAssert:{category:"Optimization",description:"Replaces assertions with just their value without trapping.",type:"b",default:!1},outFile:{category:"Output",description:"Specifies the WebAssembly output file (.wasm).",type:"s",alias:"o",isPath:!0},textFile:{category:"Output",description:"Specifies the WebAssembly text output file (.wat).",type:"s",alias:"t",isPath:!0},bindings:{category:"Output",description:["Specifies the bindings to generate (.js + .d.ts).",""," esm JavaScript bindings & typings for ESM integration."," raw Like esm, but exports just the instantiate function."," Useful where modules are meant to be instantiated"," multiple times or non-ESM imports must be provided."],type:"S",alias:"b"},sourceMap:{category:"Debugging",description:["Enables source map generation. Optionally takes the URL","used to reference the source map from the binary file."],type:"s"},uncheckedBehavior:{category:"Debugging",description:["Changes the behavior of unchecked() expressions.","Using this option can potentially cause breakage.",""," default The default behavior: unchecked operations are"," only used inside of unchecked()."," never Unchecked operations are never used, even when"," inside of unchecked()."," always Unchecked operations are always used if possible,"," whether or not unchecked() is used."],type:"s",default:"default"},debug:{category:"Debugging",description:"Enables debug information in emitted binaries.",type:"b",default:!1},importMemory:{category:"Features",description:"Imports the memory from 'env.memory'.",type:"b",default:!1},noExportMemory:{category:"Features",description:"Does not export the memory as 'memory'.",type:"b",default:!1},initialMemory:{category:"Features",description:"Sets the initial memory size in pages.",type:"i",default:0},maximumMemory:{category:"Features",description:"Sets the maximum memory size in pages.",type:"i",default:0},sharedMemory:{category:"Features",description:"Declare memory as shared. Requires maximumMemory.",type:"b",default:!1},zeroFilledMemory:{category:"Features",description:"Assume imported memory is zeroed. Requires importMemory.",type:"b",default:!1},importTable:{category:"Features",description:"Imports the function table from 'env.table'.",type:"b",default:!1},exportTable:{category:"Features",description:"Exports the function table as 'table'.",type:"b",default:!1},exportStart:{category:"Features",description:["Exports the start function using the specified name instead","of calling it implicitly. Useful to obtain the exported memory","before executing any code accessing it."],type:"s"},runtime:{category:"Features",description:["Specifies the runtime variant to include in the program.",""," incremental TLSF + incremental GC (default)"," minimal TLSF + lightweight GC invoked externally"," stub Minimal runtime stub (never frees)"," ... Path to a custom runtime implementation",""],type:"s",default:"incremental"},exportRuntime:{category:"Features",description:["Always exports the runtime helpers (__new, __collect, __pin etc.).","Automatically determined when generation of --bindings is enabled."],type:"b",default:!1},stackSize:{category:"Features",description:["Overrides the stack size. Only relevant for incremental GC","or when using a custom runtime that requires stack space.","Defaults to 0 without and to 32768 with incremental GC."],default:0,type:"i"},enable:{category:"Features",description:["Enables WebAssembly features being disabled by default.",""," threads Threading and atomic operations."," simd SIMD types and operations."," reference-types Reference types and operations."," gc Garbage collection (WIP)."," stringref String reference types."," relaxed-simd Relaxed SIMD operations.",""],TODO_doesNothingYet:[" exception-handling Exception handling."," tail-calls Tail call operations."," multi-value Multi value types."," memory64 Memory64 operations."," extended-const Extended const expressions."],type:"S",mutuallyExclusive:"disable"},disable:{category:"Features",description:["Disables WebAssembly features being enabled by default.",""," mutable-globals Mutable global imports and exports."," sign-extension Sign-extension operations"," nontrapping-f2i Non-trapping float to integer ops."," bulk-memory Bulk memory operations.",""],type:"S",mutuallyExclusive:"enable"},use:{category:"Features",description:["Aliases a global object under another name, e.g., to switch","the default 'Math' implementation used: --use Math=JSMath","Can also be used to introduce an integer constant."],type:"S",alias:"u"},lowMemoryLimit:{category:"Features",description:"Enforces very low (<64k) memory constraints.",default:0,type:"i"},memoryBase:{category:"Linking",description:"Sets the start offset of emitted memory segments.",type:"i",default:0},tableBase:{category:"Linking",description:"Sets the start offset of emitted table elements.",type:"i",default:0},transform:{category:"API",description:"Specifies the path to a custom transform to load.",type:"S",isPath:!0,useNodeResolution:!0},trapMode:{category:"Binaryen",description:["Sets the trap mode to use.",""," allow Allow trapping operations. This is the default."," clamp Replace trapping operations with clamping semantics."," js Replace trapping operations with JS semantics.",""],type:"s",default:"allow"},runPasses:{category:"Binaryen",description:["Specifies additional Binaryen passes to run after other","optimizations, if any. See: Binaryen/src/passes/pass.cpp"],type:"s"},noValidate:{category:"Binaryen",description:"Skips validating the module using Binaryen.",type:"b",default:!1},baseDir:{description:"Specifies the base directory of input and output files.",type:"s",default:"."},noColors:{description:"Disables terminal colors.",type:"b",default:!1},noUnsafe:{description:["Disallows the use of unsafe features in user code.","Does not affect library files and external modules."],type:"b",default:!1},disableWarning:{description:["Disables warnings matching the given diagnostic code.","If no diagnostic code is given, all warnings are disabled."],type:"I"},noEmit:{description:"Performs compilation as usual but does not emit code.",type:"b",default:!1},showConfig:{description:"Print computed compiler options and exit.",type:"b",default:!1},stats:{description:"Prints statistics on I/O and compile times.",type:"b",default:!1},pedantic:{description:"Make yourself sad for no good reason.",type:"b",default:!1},lib:{description:["Adds one or multiple paths to custom library components and","uses exports of all top-level files at this path as globals."],type:"S",isPath:!0},path:{description:["Adds one or multiple paths to package resolution, similar","to node_modules. Prefers an 'ascMain' entry in a package's","package.json and falls back to an inner 'assembly/' folder."],type:"S",isPath:!0},wasm:{description:"Uses the specified Wasm binary of the compiler.",type:"s"}," ...":{description:"Specifies node.js options (CLI only). See: node --help"},"-Os":{value:{optimizeLevel:0,shrinkLevel:1}},"-Oz":{value:{optimizeLevel:0,shrinkLevel:2}},"-O0":{value:{optimizeLevel:0,shrinkLevel:0}},"-O1":{value:{optimizeLevel:1,shrinkLevel:0}},"-O2":{value:{optimizeLevel:2,shrinkLevel:0}},"-O3":{value:{optimizeLevel:3,shrinkLevel:0}},"-O0s":{value:{optimizeLevel:0,shrinkLevel:1}},"-O1s":{value:{optimizeLevel:1,shrinkLevel:1}},"-O2s":{value:{optimizeLevel:2,shrinkLevel:1}},"-O3s":{value:{optimizeLevel:3,shrinkLevel:1}},"-O0z":{value:{optimizeLevel:0,shrinkLevel:2}},"-O1z":{value:{optimizeLevel:1,shrinkLevel:2}},"-O2z":{value:{optimizeLevel:2,shrinkLevel:2}},"-O3z":{value:{optimizeLevel:3,shrinkLevel:2}},"-Ospeed":{value:{optimizeLevel:3,shrinkLevel:0}},"-Osize":{value:{optimizeLevel:0,shrinkLevel:2,converge:!0}},"--measure":{value:{stats:!0}}},Ae="~lib/",_e={array:`/// <reference path="./rt/index.d.ts" />
9
9
 
10
10
  import { BLOCK_MAXSIZE } from "./rt/common";
11
11
  import { Runtime } from "shared/runtime";
@@ -1224,6 +1224,21 @@ export declare function alignof<T>(): usize; // | u32 / u64
1224
1224
  @builtin
1225
1225
  export declare function offsetof<T>(fieldName?: string): usize; // | u32 / u64
1226
1226
 
1227
+ /**
1228
+ * Copies an \`@inline struct\` value's leaves into memory at \`dest\`, one store
1229
+ * per leaf at \`dest + offsetof(leaf)\`.
1230
+ *
1231
+ * The value must be **SROA-tracked**: a local of the value, or a path into one
1232
+ * (\`copyInto(at, outer.inner)\`). There is no value expression to evaluate \u2014 an
1233
+ * inline value has no representation and no address \u2014 which is why
1234
+ * \`changetype<usize>(value)\` stays refused: the address it would return belongs
1235
+ * to a temp nobody tracks. \`copyInto\` names the destination instead, so the
1236
+ * copy is explicit and the bytes land where the caller chose.
1237
+ */
1238
+ // @ts-ignore: decorator
1239
+ @builtin
1240
+ export declare function copyInto(dest: usize, value: any): void;
1241
+
1227
1242
  /**
1228
1243
  * The ABI name of a field: its \`@abi.alias("\u2026")\` if the declaration has one,
1229
1244
  * else the field's TypeScript name. Compile-time, like \`offsetof\`.
@@ -20501,6 +20516,8 @@ declare function offsetof<T>(): usize;
20501
20516
  declare function offsetof<T>(fieldName: keyof T | string): usize;
20502
20517
  /** Determines the offset of the specified field within the given class type. Returns the class type's end offset if field name has been omitted. Compiles to a constant. */
20503
20518
  declare function offsetof<T>(fieldName?: string): usize;
20519
+ /** Copies an \`@inline struct\` value's leaves into memory at \`dest\`, one store per leaf at \`dest + offsetof(leaf)\`. The value must be held in a local (or a path into one); an inline value has no address to lend, which is why \`changetype<usize>(value)\` stays refused. */
20520
+ declare function copyInto(dest: usize, value: any): void;
20504
20521
  /** Determines the ABI name of the specified field: its \`@abi.alias\` if declared, else the field's TypeScript name. Compiles to a constant. */
20505
20522
  declare function abiNameOf<T>(fieldName: string): string;
20506
20523
  /** Determines the name of a given type. */