@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.
@@ -614,7 +614,14 @@ declare module "types:tensionscript/src/diagnosticMessages.generated" {
614
614
  A_spawn_produces_a_Task_this_one_is_never_awaited_so_the_task_s_result_is_discarded = 6401,
615
615
  An_await_forces_an_immediate_read_of_lazy_so_the_deferral_is_nullified_drop_the_lazy_or_remove_the_await = 6402,
616
616
  An_enum_underlying_type_must_be_one_of_i8_u8_i16_u16_i32_or_u32_not_0 = 6403,
617
- Enum_member_0_does_not_fit_the_underlying_type_1 = 6404
617
+ Enum_member_0_does_not_fit_the_underlying_type_1 = 6404,
618
+ _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,
619
+ _abi_align_0_the_alignment_must_be_at_least_1 = 6406,
620
+ _abi_align_0_the_alignment_must_be_a_power_of_two = 6407,
621
+ _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,
622
+ _abi_align_0_is_too_large_the_maximum_is_1 = 6409,
623
+ Alignment_is_a_property_of_the_field_not_its_type_Place_abi_align_N_on_the_field_declaration = 6410,
624
+ 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
618
625
  }
619
626
  /** Translates a diagnostic code to its respective string. */
620
627
  export function diagnosticCodeToString(code: DiagnosticCode): string;
@@ -2681,8 +2688,9 @@ declare module "types:tensionscript/src/types" {
2681
2688
  * own model is still on the `Type`
2682
2689
  * (`type.classReference.hasDecorator(...)`). The boundary emitters want both —
2683
2690
  * the override decides *how the parameter crosses*, the type decides what may
2684
- * be done with it. See `docs/memconv-signature-scope.md` §5.2 for why rooting
2685
- * deliberately reads only the second.
2691
+ * be done with it. Rooting deliberately reads only the second: the override
2692
+ * says how the parameter crosses, while the type says what may be done with
2693
+ * it.
2686
2694
  */
2687
2695
  memoryModelOf(sourceIndex: number): number;
2688
2696
  /**
@@ -2699,6 +2707,21 @@ declare module "types:tensionscript/src/types" {
2699
2707
  * all of them.
2700
2708
  */
2701
2709
  static wasmParamCountOf(type: Type): number;
2710
+ /**
2711
+ * Appends the **leaf** types of an `@inline struct`, in declaration order,
2712
+ * depth first.
2713
+ *
2714
+ * A leaf is a field that occupies one WASM local: a scalar or a reference. A
2715
+ * field whose type is itself an `@inline struct` is not a leaf — it is several
2716
+ * locals behind a map — so the walk recurses into it. This is the type-level
2717
+ * twin of the `fieldLocals` tree the compiler builds
2718
+ * (`Compiler#fillSroaFieldLocals`), and the two must agree in **order** as
2719
+ * well as count: the callee binds WASM parameter *k* to the *k*th leaf, and
2720
+ * the caller pushes operands in the same walk.
2721
+ */
2722
+ static leafTypesOf(type: Type, out: Type[]): void;
2723
+ /** The number of leaf locals an `@inline struct` occupies. */
2724
+ static leafCountOf(type: Type): number;
2702
2725
  /**
2703
2726
  * How many WASM operands **this signature** spends on source parameter
2704
2727
  * `sourceIndex`.
@@ -2715,6 +2738,18 @@ declare module "types:tensionscript/src/types" {
2715
2738
  * the same source parameter.
2716
2739
  */
2717
2740
  wasmParamSlotCountOf(sourceIndex: number): number;
2741
+ /**
2742
+ * Whether source parameter `sourceIndex` is a **view**: `@unmanaged` at the
2743
+ * declaration over a type that is an `@inline struct`.
2744
+ *
2745
+ * The type still says *value* — every use of `MyStruct` shares one `Type`, and
2746
+ * that is what makes a member lookup work on the parameter — while the model
2747
+ * says this use is an address. One `i32` slot, no field locals, a load at the
2748
+ * field's offset: the same crossing an `@unmanaged struct` parameter already
2749
+ * takes, with the model recorded at the declaration instead of on a pointer
2750
+ * type.
2751
+ */
2752
+ isViewParam(sourceIndex: number): boolean;
2718
2753
  /**
2719
2754
  * Whether source parameter `sourceIndex` **crosses by value** — one `i32`
2720
2755
  * address instead of one WASM operand per field.
@@ -2728,8 +2763,12 @@ declare module "types:tensionscript/src/types" {
2728
2763
  * address, and the override asks for a copy of what is there — the same
2729
2764
  * copy, read from memory instead of from SROA locals.
2730
2765
  *
2731
- * The reverse is not a thing: `@unmanaged`/`@managed` over an `@inline`
2732
- * declaration is refused (`TS6395`), because a value has no address to lend.
2766
+ * The reverse is partly a thing now. `@unmanaged` over an `@inline`
2767
+ * declaration is legal where the use supplies an address — a parameter (a
2768
+ * view parameter, `isViewParam`) or `changetype`'s type argument — and a view
2769
+ * parameter crosses as a pointer, so it is asked before this predicate. Every
2770
+ * other cell still refuses (`TS6395`), and `@managed` over `@inline` refuses
2771
+ * at every position: a value has no GC header and no address to lend.
2733
2772
  */
2734
2773
  crossesByValueParam(sourceIndex: number): boolean;
2735
2774
  /**
@@ -2752,9 +2791,17 @@ declare module "types:tensionscript/src/types" {
2752
2791
  get byValPointerParams(): boolean;
2753
2792
  /** Whether `type` is an `@inline struct`. */
2754
2793
  static isInlineStructRef(type: Type): boolean;
2755
- /** The number of fields an `@inline struct` has (0 for a record with none).
2756
- * Distinct from `wasmParamCountOf`, which cannot express "one field" and
2757
- * "one operand" differently. */
2794
+ /**
2795
+ * How many **WASM slots** an `@inline struct` spends — its leaf count.
2796
+ *
2797
+ * Leaf count, not direct-field count: a nested inline field is several locals,
2798
+ * so `Outer1 { a: u32; inner: Inner{x,y} }` is 3, not 2. A record with no
2799
+ * members is 0.
2800
+ *
2801
+ * Callers that made sense of "direct fields" are listed in the Phase C audit
2802
+ * (`docs`); the one place that genuinely needs the direct count is layout, and
2803
+ * layout reads `members` itself rather than asking this.
2804
+ */
2758
2805
  static fieldCountOf(type: Type): number;
2759
2806
  /**
2760
2807
  * Whether a call to this signature passes a hidden destination pointer.
@@ -3088,6 +3135,60 @@ declare module "types:tensionscript/src/resolver" {
3088
3135
  currentElementExpression: Expression | null;
3089
3136
  /** Whether a new override has been discovered. */
3090
3137
  discoveredOverride: boolean;
3138
+ /**
3139
+ * Whether a use-site `@unmanaged` over an `@inline` declaration is being
3140
+ * resolved as the **type argument of `changetype`**.
3141
+ *
3142
+ * That position is the one where the operand can supply the address the value
3143
+ * itself does not have, so the refusal's premise does not hold there (see
3144
+ * `checkMemoryModelOverride`). Every other position — a parameter, a local, a
3145
+ * field, a return type — still refuses with `TS6395`, which is what keeps the
3146
+ * function-parameter form (`Phase 2`) out of this change.
3147
+ *
3148
+ * The compiler sets this around the one `resolveTypeArguments` call it makes
3149
+ * for a `changetype` builtin (`Compiler#compileCallExpressionBuiltin`), and
3150
+ * resets it immediately: the flag is a scope, not a mode.
3151
+ */
3152
+ allowInlineView: boolean;
3153
+ /**
3154
+ * Whether a use-site `@unmanaged` over an `@inline` declaration is being
3155
+ * resolved in a **parameter position** — the cell where the caller supplies
3156
+ * the address, so `f(a: @unmanaged T)` with an inline `T` is a view parameter.
3157
+ *
3158
+ * Distinct from {@link allowInlineView} (Phase 1, `changetype`'s type
3159
+ * argument, where the operand supplies the address at the point of use).
3160
+ *
3161
+ * **Saved and restored, never blindly cleared.** Resolving one parameter's
3162
+ * type can resolve another function (a default value's call, a nested
3163
+ * signature), and a nested window that reset the flag to `false` on the way
3164
+ * out closed the outer window — measured: the owner's pattern reported TS6395
3165
+ * with both flags reading `false` while inside `resolveFunction`'s own loop.
3166
+ */
3167
+ allowInlineViewParam: boolean;
3168
+ /**
3169
+ * Call expressions that are **views of caller bytes**: an inline-typed
3170
+ * `changetype<@unmanaged T>(ptr)`.
3171
+ *
3172
+ * Marked here, at resolution, because the compiler asks this question while
3173
+ * compiling the *field access* — which happens before the `changetype` it
3174
+ * wraps is ever compiled. Recording it at codegen time (the first attempt)
3175
+ * produced a field read that never saw the mark and compiled to
3176
+ * `unreachable`.
3177
+ *
3178
+ * Keyed on the AST node rather than on the type, because the type is the
3179
+ * declaration's (`T` is still an `@inline struct`) and the model is the
3180
+ * *use's*: there is one `Type` per class, shared by every use.
3181
+ */
3182
+ private viewCalls;
3183
+ /**
3184
+ * Records `node` as a view call. The resolver marks the ones it resolves;
3185
+ * `Compiler#compileCallExpressionBuiltin` marks the ones it resolves itself,
3186
+ * because a builtin's type arguments are resolved on the *codegen* path and
3187
+ * never pass through `maybeInferCall`.
3188
+ */
3189
+ markViewCall(node: Expression): void;
3190
+ /** Whether `node` is an inline-typed `changetype<@unmanaged T>(...)`. */
3191
+ isViewCall(node: Expression): boolean;
3091
3192
  /** Constructs the resolver for the specified program. */
3092
3193
  constructor(
3093
3194
  /** The program to construct a resolver for. */
@@ -3115,10 +3216,14 @@ declare module "types:tensionscript/src/resolver" {
3115
3216
  * - **`@managed` over an `@unmanaged` declaration** — the collector traces a
3116
3217
  * reference through a header the record does not have. No emitter can
3117
3218
  * invent the header, so a use cannot confer provenance. (`TS6394`.)
3118
- * - **`@unmanaged`/`@managed` over an `@inline` declaration** — a value is
3119
- * stored as one local per field and has **no address** at all, so there is
3120
- * nothing to lend as a pointer and nothing a header could sit in front of.
3121
- * (`TS6395`.)
3219
+ * - **`@managed` over an `@inline` declaration** — a value has neither a
3220
+ * header nor an address, at any position. (`TS6395`.)
3221
+ * - **`@unmanaged` over an `@inline` declaration**, *except* where the use
3222
+ * supplies an address: `changetype`'s type argument (the operand supplies
3223
+ * it) and a parameter (the caller supplies it). Those two windows are
3224
+ * `allowInlineView` and `allowInlineViewParam`, and they are the whole
3225
+ * difference between a view and a claim. Every other position — a return
3226
+ * type, a local, a field — still has nothing to lend. (`TS6395`.)
3122
3227
  *
3123
3228
  * Everything else is left to the emitters: `@unmanaged` over `@managed` is
3124
3229
  * the identity cell (10.0a), `@inline` over a pointer declaration is the
@@ -3756,6 +3861,14 @@ declare module "types:tensionscript/src/program" {
3756
3861
  function fromUnaryPostfixToken(token: Token): OperatorKind;
3757
3862
  }
3758
3863
  /** Represents an AssemblyScript program. */
3864
+ /** How many WASM slots a parameter binding consumed — see
3865
+ * `Program#bindSroaParameterLeaves`. A one-field wrapper because this compiler
3866
+ * reports the count and the caller advances past it; a bare `i32` return would
3867
+ * be the same information with no name at the call site. */
3868
+ export class BindResult {
3869
+ leafCount: number;
3870
+ constructor(leafCount: number);
3871
+ }
3759
3872
  export class Program extends DiagnosticEmitter {
3760
3873
  /** Compiler options. */
3761
3874
  options: Options;
@@ -4472,6 +4585,17 @@ declare module "types:tensionscript/src/program" {
4472
4585
  * therefore cannot alias.
4473
4586
  */
4474
4587
  fieldLocals: Map<string, Local> | null;
4588
+ /**
4589
+ * Whether this local is a **view parameter**: `a: @unmanaged T` where `T` is
4590
+ * an inline type.
4591
+ *
4592
+ * Its `type` is still the inline record, because that is what makes `a.field`
4593
+ * resolve — every use of `T` shares one `Type`. Its *storage* is the one `i32`
4594
+ * WASM parameter holding the caller's address, which is why a field read goes
4595
+ * through `load` at the field's offset rather than through `fieldLocals`
4596
+ * (there are none: a view has no per-field locals to copy into).
4597
+ */
4598
+ isViewParam: boolean;
4475
4599
  /** Constructs a new local variable. */
4476
4600
  constructor(
4477
4601
  /** Simple name. */
@@ -4583,6 +4707,20 @@ declare module "types:tensionscript/src/program" {
4583
4707
  nextInlineId: number;
4584
4708
  /** Counting id of anonymous inner functions. */
4585
4709
  nextAnonymousId: number;
4710
+ /**
4711
+ * Binds an `@inline struct` parameter's **leaves** to the WASM parameters that
4712
+ * carry them, building the `fieldLocals` tree a read path walks.
4713
+ *
4714
+ * `localIndex` is the index of the parameter's first WASM slot; the walk
4715
+ * consumes one slot per leaf in the same depth-first order
4716
+ * `Signature.leafTypesOf` declares and the caller pushes operands in. Returns
4717
+ * how many slots were consumed, so the caller advances past them.
4718
+ *
4719
+ * A nested field gets a placeholder `Local` (index `-1`) carrying its own map,
4720
+ * exactly as `fillSroaFieldLocals` builds one for a local — the tree shape is
4721
+ * one structure regardless of where the leaves' storage came from.
4722
+ */
4723
+ bindSroaParameterLeaves(type: Type, path: string, into: Map<string, Local>, localIndex: number, flow: Flow): BindResult;
4586
4724
  /** Constructs a new concrete function. */
4587
4725
  constructor(
4588
4726
  /** Name incl. type parameters, i.e. `foo<i32>`. */
@@ -5277,7 +5415,7 @@ declare module "types:tensionscript/src/compiler" {
5277
5415
  import { Range, DiagnosticEmitter } from "types:tensionscript/src/diagnostics";
5278
5416
  import { Module, MemorySegment, ExpressionRef, TypeRef, GlobalRef } from "types:tensionscript/src/module";
5279
5417
  import { Feature, Target, Runtime } from "types:tensionscript/src/common";
5280
- import { Program, Class, Element, DeclaredElement, Enum, Function, Global, Property, VariableLikeElement, File } from "types:tensionscript/src/program";
5418
+ import { Program, Class, Element, DeclaredElement, Enum, Function, Global, Local, Property, VariableLikeElement, File } from "types:tensionscript/src/program";
5281
5419
  import { Flow, ConditionKind } from "types:tensionscript/src/flow";
5282
5420
  import { Resolver } from "types:tensionscript/src/resolver";
5283
5421
  import { Node, FunctionTypeNode, Statement, Expression } from "types:tensionscript/src/ast";
@@ -5940,11 +6078,27 @@ declare module "types:tensionscript/src/compiler" {
5940
6078
  /**
5941
6079
  * The SROA local an expression names, or `null`.
5942
6080
  *
5943
- * Only a bare identifier can be one: `p.x.y` where `x` is itself an inline
5944
- * struct cannot happen this phase (a nested field is refused at declaration),
5945
- * so the receiver of a field access is either an SROA local or an ordinary
5946
- * expression that has an address.
6081
+ * The receiver is either an SROA local (base identifier) or a chain of field
6082
+ * accesses into one (`o.inner` in `o.inner.x`). The chain is walked from the
6083
+ * base outward, one hop per `fieldLocals` lookup: a nested inline field is
6084
+ * entered through the placeholder `Local` its creation installed
6085
+ * (`fillSroaFieldLocals`), so the walk and the tree are one structure rather
6086
+ * than two that could disagree.
6087
+ *
6088
+ * Returns the `Local` the final hop resolved to, or `null` when any step does
6089
+ * not hold — a non-local base, a field with no entry, or a leaf reached before
6090
+ * the chain ends. `null` is not an error here: the caller falls through to the
6091
+ * ordinary address paths, which refuse a value with no address.
6092
+ */
6093
+ /**
6094
+ * Pushes one operand per **leaf** of a `fieldLocals` tree, depth first.
6095
+ *
6096
+ * Shared by the call site (`expandSroaArgument`) so the operand order is the
6097
+ * one `Signature.leafTypesOf` declares and the binder indexes into — three
6098
+ * walks, one order. A nested field's entry is a placeholder (index `-1`)
6099
+ * carrying its own map, so the walk descends through it.
5947
6100
  */
6101
+ private pushSroaLeafOperands;
5948
6102
  private resolveSroaReceiver;
5949
6103
  /** Size of the static call-temp region, in bytes. 4 KB is 256 slots at the
5950
6104
  * 16-byte fixture record size. Overflow aborts (see `makeSretCallBlock`);
@@ -6034,6 +6188,15 @@ declare module "types:tensionscript/src/compiler" {
6034
6188
  /** `base + mark + extra`, freshly built. Callers must not share the node:
6035
6189
  * Binaryen's passes assume a single parent per expression. */
6036
6190
  private makeSretAddressPlus;
6191
+ /**
6192
+ * Stores a by-value argument's leaves into the static call-temp region.
6193
+ *
6194
+ * The same tree walk as `copyInto` (`emitSroaStores`) and `copySroaValue`:
6195
+ * leaves become stores at `tempAddress + field offset`, a nested field is
6196
+ * descended into. Keeping one recursion is what makes a nested value cross a
6197
+ * host boundary at the layout the C side expects.
6198
+ */
6199
+ emitTempArgumentLeaves(type: Type, fieldLocals: Map<string, Local>, base: number, markLocal: Local, baseOffset: number, stmts: ExpressionRef[]): void;
6037
6200
  /**
6038
6201
  * Materialises one `@inline struct` argument of an `@external` call on the
6039
6202
  * static call-temp stack and returns the address to pass.
@@ -6104,6 +6267,93 @@ declare module "types:tensionscript/src/compiler" {
6104
6267
  * Returns true when the declaration was handled here (the caller must not fall
6105
6268
  * through to the ordinary local path).
6106
6269
  */
6270
+ /**
6271
+ * Fills `into` with one entry per field of an `@inline struct` value.
6272
+ *
6273
+ * A **leaf** field (scalar, or a reference) gets one WASM local, named
6274
+ * `<path>$<field>` — a synthetic name keeps it out of user scope, so nothing
6275
+ * can look one up by accident.
6276
+ *
6277
+ * A field whose type is itself an `@inline struct` is **not a leaf**: it is
6278
+ * recursed into, and its entry is a placeholder `Local` (index `-1`) carrying
6279
+ * its own map. That makes `fieldLocals` a **tree** whose shape is the value's
6280
+ * nesting, which is what lets a read path walk `o.inner.x` a hop at a time
6281
+ * without a second representation. The placeholder is never `local.get`-ed:
6282
+ * the bare-read guard refuses a value read and the receiver walk descends to
6283
+ * a leaf before emitting anything.
6284
+ *
6285
+ * Returns `false` when a field was refused, having reported why. The refusal
6286
+ * is per **leaf**, so a nested value inherits exactly the rules the flat one
6287
+ * has — a `T[N]` field or a GC-reference field is refused at any depth.
6288
+ */
6289
+ private fillSroaFieldLocals;
6290
+ /**
6291
+ * Copies one SROA value's leaves into another's, following the tree.
6292
+ *
6293
+ * `from` and `to` are the two `fieldLocals` maps — the same shape
6294
+ * `fillSroaFieldLocals` builds, so a nested field is a placeholder on both
6295
+ * sides and the recursion descends through it rather than trying to move a
6296
+ * value that has no single representation.
6297
+ *
6298
+ * This is what makes `let q = p` and `q = p` **copies** rather than aliases:
6299
+ * one `local.set` per leaf, so a later write to `q` cannot be seen through
6300
+ * `p`. Both sides come from this compiler's own maps, so there is no aliasing
6301
+ * question to answer — the leaves are distinct locals by construction.
6302
+ */
6303
+ private copySroaValue;
6304
+ /**
6305
+ * Stores a `fieldLocals` tree's leaves into the hidden destination slot at
6306
+ * `destIndex`, one store per leaf.
6307
+ *
6308
+ * The third destination shape for the same recursion: `emitSroaStores` writes
6309
+ * to a compiled `usize`, `emitTempArgumentLeaves` to a call-temp address, and
6310
+ * this one to a **parameter** — the sret slot a `return p` fills. The address
6311
+ * is a fresh `local.get` per store, because Binaryen's passes assume one
6312
+ * parent per node.
6313
+ */
6314
+ emitSroaStoresToLocal(type: Type, fieldLocals: Map<string, Local>, destIndex: number, baseOffset: number, stmts: ExpressionRef[]): void;
6315
+ /**
6316
+ * Zeroes every **leaf** of an `@inline struct` in the destination slot.
6317
+ *
6318
+ * `return new P()` has no local to copy from — the value is all zeroes — but
6319
+ * the slot is stack space that a previous sret call may have filled, so the
6320
+ * bytes still have to be written. Walking the type rather than the direct
6321
+ * fields is what zeroes a nested field's leaves: measured before this,
6322
+ * `return new Outer1()` with `Inner{x,y}` stored only offset 0 and left
6323
+ * offsets 4 and 8 holding whatever was there.
6324
+ */
6325
+ emitSroaZerosToLocal(type: Type, destIndex: number, baseOffset: number, stmts: ExpressionRef[]): void;
6326
+ /**
6327
+ * Loads an `@inline struct`'s leaves out of the sret slot into a target's
6328
+ * field locals, one load per leaf.
6329
+ *
6330
+ * The mirror of {@link emitSroaStoresToLocal}: `let q = make()` reads the slot
6331
+ * back into the leaf locals a read path walks. A fresh slot address per load,
6332
+ * for the same one-parent-per-node reason.
6333
+ */
6334
+ emitSretLoadsInto(type: Type, fieldLocals: Map<string, Local>, base: number, markLocal: Local, baseOffset: number, stmts: ExpressionRef[]): void;
6335
+ /**
6336
+ * The `fieldLocals` tree behind an SROA-tracked expression, or `null`.
6337
+ *
6338
+ * The public face of {@link resolveSroaReceiver} for code outside this class —
6339
+ * today only the `copyInto` builtin, which needs the *tree* (to store its
6340
+ * leaves) rather than a single receiver.
6341
+ */
6342
+ sroaTreeOf(expression: Expression): Map<string, Local> | null;
6343
+ /**
6344
+ * Stores an inline value's leaves at `dest + offset`.
6345
+ *
6346
+ * The third leaf consumer, beside `copySroaValue` (local-to-local) and the
6347
+ * read path (local-to-stack): same tree, same recursion, an expression
6348
+ * reference instead of a destination map. The offsets come from the **type**
6349
+ * (`property.memoryOffset`, the layout the C side sees), so what lands in
6350
+ * memory is the wire layout, not a packing of the locals.
6351
+ *
6352
+ * Leaves whose local is missing are skipped rather than stored as `-1`: a
6353
+ * field refused at declaration was never part of the value (`isSroaFieldType`
6354
+ * has already reported why), and the caller has been told.
6355
+ */
6356
+ emitSroaStores(type: Type, fieldLocals: Map<string, Local>, dest: ExpressionRef, baseOffset: number, stmts: ExpressionRef[]): void;
6107
6357
  private compileSroaLocal;
6108
6358
  /**
6109
6359
  * The instance fields of an `@inline struct`, in declaration order, or `null`
@@ -6289,6 +6539,7 @@ declare module "types:tensionscript/src/builtins" {
6289
6539
  const select = "~lib/builtins/select";
6290
6540
  const unreachable = "~lib/builtins/unreachable";
6291
6541
  const changetype = "~lib/builtins/changetype";
6542
+ const copyInto = "~lib/builtins/copyInto";
6292
6543
  const assert = "~lib/builtins/assert";
6293
6544
  const call_indirect = "~lib/builtins/call_indirect";
6294
6545
  const unchecked = "~lib/builtins/unchecked";