@scriptc/compiler 0.0.7 → 0.0.9
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/ambient/scriptc-node-fallback.d.ts +13 -0
- package/dist/backend/cc.js +14 -0
- package/dist/backend/cc.js.map +1 -1
- package/dist/backend/emission/emit-exprs.js +155 -6
- package/dist/backend/emission/emit-exprs.js.map +1 -1
- package/dist/backend/emission/emit-island.js +9 -1
- package/dist/backend/emission/emit-island.js.map +1 -1
- package/dist/backend/emission/emit-stmts.js +3 -1
- package/dist/backend/emission/emit-stmts.js.map +1 -1
- package/dist/backend/emission/emit-types.d.ts +3 -0
- package/dist/backend/emission/emit-types.js +12 -0
- package/dist/backend/emission/emit-types.js.map +1 -1
- package/dist/backend/emission/emit-walkers.d.ts +7 -5
- package/dist/backend/emission/emit-walkers.js +45 -18
- package/dist/backend/emission/emit-walkers.js.map +1 -1
- package/dist/backend/emission/emitter.d.ts +1 -1
- package/dist/backend/emission/emitter.js +35 -10
- package/dist/backend/emission/emitter.js.map +1 -1
- package/dist/backend/emission/may-throw.js +4 -3
- package/dist/backend/emission/may-throw.js.map +1 -1
- package/dist/backend/llvm/emitter.js +300 -18
- package/dist/backend/llvm/emitter.js.map +1 -1
- package/dist/diagnostics/diagnostic.d.ts +98 -11
- package/dist/diagnostics/diagnostic.js +185 -25
- package/dist/diagnostics/diagnostic.js.map +1 -1
- package/dist/frontend/lib-contract.d.ts +24 -6
- package/dist/frontend/lib-contract.js +125 -44
- package/dist/frontend/lib-contract.js.map +1 -1
- package/dist/frontend/lowering/lower-assert.js +16 -0
- package/dist/frontend/lowering/lower-assert.js.map +1 -1
- package/dist/frontend/lowering/lower-builtins.d.ts +11 -0
- package/dist/frontend/lowering/lower-builtins.js +127 -4
- package/dist/frontend/lowering/lower-builtins.js.map +1 -1
- package/dist/frontend/lowering/lower-calls.d.ts +77 -18
- package/dist/frontend/lowering/lower-calls.js +978 -44
- package/dist/frontend/lowering/lower-calls.js.map +1 -1
- package/dist/frontend/lowering/lower-classes.d.ts +14 -1
- package/dist/frontend/lowering/lower-classes.js +112 -16
- package/dist/frontend/lowering/lower-classes.js.map +1 -1
- package/dist/frontend/lowering/lower-containers.d.ts +4 -2
- package/dist/frontend/lowering/lower-containers.js +236 -44
- package/dist/frontend/lowering/lower-containers.js.map +1 -1
- package/dist/frontend/lowering/lower-emitter.js +55 -1
- package/dist/frontend/lowering/lower-emitter.js.map +1 -1
- package/dist/frontend/lowering/lower-exprs.d.ts +26 -3
- package/dist/frontend/lowering/lower-exprs.js +507 -47
- package/dist/frontend/lowering/lower-exprs.js.map +1 -1
- package/dist/frontend/lowering/lower-island.d.ts +7 -0
- package/dist/frontend/lowering/lower-island.js +71 -10
- package/dist/frontend/lowering/lower-island.js.map +1 -1
- package/dist/frontend/lowering/lower-mixins.d.ts +1 -1
- package/dist/frontend/lowering/lower-mixins.js +1 -1
- package/dist/frontend/lowering/lower-modules.js +95 -4
- package/dist/frontend/lowering/lower-modules.js.map +1 -1
- package/dist/frontend/lowering/lower-stmts.js +866 -56
- package/dist/frontend/lowering/lower-stmts.js.map +1 -1
- package/dist/frontend/lowering/lower-stream.js +28 -2
- package/dist/frontend/lowering/lower-stream.js.map +1 -1
- package/dist/frontend/lowering/lowerer.d.ts +85 -17
- package/dist/frontend/lowering/lowerer.js +459 -37
- package/dist/frontend/lowering/lowerer.js.map +1 -1
- package/dist/frontend/lowering/surfaces.js +20 -3
- package/dist/frontend/lowering/surfaces.js.map +1 -1
- package/dist/frontend/npm-static-rewrite.d.ts +7 -2
- package/dist/frontend/npm-static-rewrite.js +566 -138
- package/dist/frontend/npm-static-rewrite.js.map +1 -1
- package/dist/frontend/npm-static.js +11 -2
- package/dist/frontend/npm-static.js.map +1 -1
- package/dist/frontend/program.js +5 -5
- package/dist/frontend/program.js.map +1 -1
- package/dist/frontend/shared.d.ts +6 -1
- package/dist/frontend/shared.js +46 -1
- package/dist/frontend/shared.js.map +1 -1
- package/dist/frontend/types.d.ts +28 -1
- package/dist/frontend/types.js +304 -10
- package/dist/frontend/types.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +181 -26
- package/dist/index.js.map +1 -1
- package/dist/ir/nodes.d.ts +159 -9
- package/dist/ir/nodes.js +76 -6
- package/dist/ir/nodes.js.map +1 -1
- package/dist/ir/validate.js +93 -14
- package/dist/ir/validate.js.map +1 -1
- package/dist/library/profile.d.ts +17 -3
- package/dist/library/profile.js +38 -9
- package/dist/library/profile.js.map +1 -1
- package/dist/library/sidecar.js +162 -43
- package/dist/library/sidecar.js.map +1 -1
- package/dist/library/trap-teaching.d.ts +11 -0
- package/dist/library/trap-teaching.js +49 -0
- package/dist/library/trap-teaching.js.map +1 -0
- package/package.json +2 -2
- package/surface-manifest.json +46 -4
|
@@ -568,6 +568,19 @@ export declare function genericOverrideBelow(L: Lowerer, info: ClassInfo, name:
|
|
|
568
568
|
* new D()` receiver is exactly D, not its annotation. Distinct from
|
|
569
569
|
* exactClassOfReceiver, which answers for CLASS-VALUE receivers. */
|
|
570
570
|
export declare function exactInstanceClassOf(L: Lowerer, expr: ts.Expression): ClassInfo | null;
|
|
571
|
+
/** `const r: Repo = new MemRepo()` where EVERY member of the annotation's
|
|
572
|
+
* checker type is a generic-callable method (`interface Repo { get<T>(id:
|
|
573
|
+
* string): T }`): the record shape maps EMPTY — generic members are
|
|
574
|
+
* excluded (no closure slot can hold a generic function) — so the
|
|
575
|
+
* copy-reshape width coercion would DROP the exact class the method
|
|
576
|
+
* calls monomorphize against, and in JS the binding IS the instance (no
|
|
577
|
+
* copy exists). The binding keeps the initializer's class
|
|
578
|
+
* representation instead: generic-method calls resolve like class-typed
|
|
579
|
+
* receivers (exactInstanceClassOf reads the same const+new discipline),
|
|
580
|
+
* and uses that want the empty record width-coerce at the use site.
|
|
581
|
+
* Const + direct `new` only — a reassignable binding or a produced
|
|
582
|
+
* value keeps today's record story and its fences. */
|
|
583
|
+
export declare function genericIfaceBindingKeepsClass(L: Lowerer, decl: ts.VariableDeclaration, declaredType: IrType): boolean;
|
|
571
584
|
/** `recv.m<T>(args)` — a GENERIC method call, dispatched STATICALLY: the
|
|
572
585
|
* checker's resolved signature (type arguments substituted, inferred or
|
|
573
586
|
* explicit) keys one instantiation of the nearest declarer's body, and
|
|
@@ -579,7 +592,7 @@ export declare function exactInstanceClassOf(L: Lowerer, expr: ts.Expression): C
|
|
|
579
592
|
export declare function lowerClassGenericMethodCall(L: Lowerer, call: ts.CallExpression, access: ts.PropertyAccessExpression, recvInfo: ClassInfo, found: {
|
|
580
593
|
declarer: ClassInfo;
|
|
581
594
|
info: GenericFnInfo;
|
|
582
|
-
}): IrExpr;
|
|
595
|
+
}, recvIr?: IrExpr): IrExpr;
|
|
583
596
|
/** Wraps a derived-class expression in an upcast when the target base
|
|
584
597
|
* class differs (a no-op reinterpret at runtime; keeps IR types exact). */
|
|
585
598
|
export declare function upcastTo(L: Lowerer, expr: IrExpr, className: string): IrExpr;
|
|
@@ -4,12 +4,13 @@
|
|
|
4
4
|
* accessor access, upcasts, `new` expressions, and the builtin Error
|
|
5
5
|
* hierarchy registration. */
|
|
6
6
|
import * as ts from "../ts7/adapter.js";
|
|
7
|
-
import { BOOL, DYN, F64, JSVAL, RUNTIME_EMITTER_CLASS, RUNTIME_ERROR_CLASSES, RUNTIME_STREAM_CLASSES, STRING, UNDEFINED_T, URL_T, VOID, arrayOf, isSupportedMapKey, isUnitType, typeEquals } from "../../ir/nodes.js";
|
|
7
|
+
import { BOOL, DYN, F64, bytesOf, JSVAL, RUNTIME_EMITTER_CLASS, RUNTIME_ERROR_CLASSES, RUNTIME_STREAM_CLASSES, STRING, UNDEFINED_T, URL_T, VOID, arrayOf, isSupportedMapKey, isUnitType, typeEquals } from "../../ir/nodes.js";
|
|
8
8
|
import { MAX_GENERIC_INSTANCES, genericCallInstance, implicitAnyParamSymbolsOf, implicitCallInstance, implicitMonoFile, omittedArgFor } from "./lower-calls.js";
|
|
9
9
|
import { isGenericCallableMemberType, typeKey } from "../types.js";
|
|
10
10
|
import { cjsClassExprWholeExportOf, isCjsJsFile, isJsSourceFile, isModuleExportsAccess, isNodeTypesPath, locOf } from "../program.js";
|
|
11
11
|
import { PoisonError, dynFallbackType, dynUndefinedExpr, newFnCtx, own } from "./lowerer.js";
|
|
12
12
|
import { bufEncoding, lowerMapSeedArrayNew } from "./lower-containers.js";
|
|
13
|
+
import { pureReemittable } from "./lower-exprs.js";
|
|
13
14
|
import { lowerSearchParamsNew } from "./lower-builtins.js";
|
|
14
15
|
import { requiresDynamicPackageDiag, unsupportedDiag } from "../../diagnostics/diagnostic.js";
|
|
15
16
|
import { STREAM_API_MEMBERS, STREAM_PROP_MEMBERS, UNDERSCORE_METHODS, lowerStreamNew, lowerStreamSuperCall, streamCtorShape } from "./lower-stream.js";
|
|
@@ -2802,13 +2803,28 @@ export function lowerStaticMethodCall(L, call, access) {
|
|
|
2802
2803
|
return null;
|
|
2803
2804
|
return staticCallOn(L, call, access, info, throughValue);
|
|
2804
2805
|
}
|
|
2806
|
+
/** True when a class-VALUE receiver can only hold `info`'s own class
|
|
2807
|
+
* object at runtime: the receiver provably IS the class
|
|
2808
|
+
* (exactClassOfReceiver — the name, or a const bound to the class
|
|
2809
|
+
* expression / class name), or `info` is a LEAF class, so no strict
|
|
2810
|
+
* descendant exists to flow into the slot (the static-write path's
|
|
2811
|
+
* rule — a rebindable decorated name rides this arm, since replacement
|
|
2812
|
+
* decorators fence any class with subclasses before minting the
|
|
2813
|
+
* rebindable global). Exactly then a #private static access through
|
|
2814
|
+
* the value always carries the declaring class's brand — Node's
|
|
2815
|
+
* TypeError cannot arise. */
|
|
2816
|
+
function classValueIsExactlyOwn(L, recv, info) {
|
|
2817
|
+
return exactClassOfReceiver(L, recv) === info || info.subclasses.length === 0;
|
|
2818
|
+
}
|
|
2805
2819
|
function staticCallOn(L, call, access, info, throughValue) {
|
|
2806
2820
|
const loc = locOf(call);
|
|
2807
|
-
// #private statics: through-a-VALUE
|
|
2808
|
-
//
|
|
2809
|
-
//
|
|
2810
|
-
// only
|
|
2811
|
-
|
|
2821
|
+
// #private statics: through-a-VALUE receiver the call devirtualizes
|
|
2822
|
+
// exactly when the value can only BE the declaring class
|
|
2823
|
+
// (classValueIsExactlyOwn — a slot that could hold a descendant at
|
|
2824
|
+
// runtime fences, since only the declaring class object carries the
|
|
2825
|
+
// brand in JS), and the direct spelling resolves only on the
|
|
2826
|
+
// declaring class itself — `D.#s` is Node's TypeError.
|
|
2827
|
+
if (access.name.text.startsWith("#") && throughValue && !classValueIsExactlyOwn(L, access.expression, info)) {
|
|
2812
2828
|
L.unsupported("SC1090", call, `calling the private static '${access.name.text}' through a class value (JS brands the declaring class object alone — call it through the class's own name)`);
|
|
2813
2829
|
}
|
|
2814
2830
|
const found = findStaticOn(L, info, access.name.text);
|
|
@@ -2897,13 +2913,21 @@ export function lowerClassValueProperty(L, expr) {
|
|
|
2897
2913
|
if (!found) {
|
|
2898
2914
|
L.unsupported("SC1090", expr, `the static member '${member}' of class '${info.def.name.replace(/^%|^%m\d+\./, "")}' (static accessors and initializer-less static fields have no lowering, and Function members like .call/.bind/.prototype have no value form)`);
|
|
2899
2915
|
}
|
|
2900
|
-
// #private statics
|
|
2901
|
-
//
|
|
2902
|
-
//
|
|
2903
|
-
//
|
|
2904
|
-
//
|
|
2916
|
+
// #private statics read through a class VALUE exactly when the value
|
|
2917
|
+
// can only BE the declaring class (classValueIsExactlyOwn — a const
|
|
2918
|
+
// bound to the class expression / class name, or a leaf class): a
|
|
2919
|
+
// slot that could hold a descendant at runtime fences, since JS
|
|
2920
|
+
// brands the declaring class object alone (Node's TypeError on any
|
|
2921
|
+
// other receiver). The direct class-name spelling resolved in
|
|
2922
|
+
// lowerStaticFieldRead, so a private reaching here is a
|
|
2923
|
+
// classval-typed binding.
|
|
2905
2924
|
if (member.startsWith("#")) {
|
|
2906
|
-
L
|
|
2925
|
+
if (!classValueIsExactlyOwn(L, expr.expression, info)) {
|
|
2926
|
+
L.unsupported("SC1090", expr, `reading the private static '${member}' through a class value (JS brands the declaring class object alone — spell the declaring class's name)`);
|
|
2927
|
+
}
|
|
2928
|
+
if (found.declarer !== info) {
|
|
2929
|
+
L.unsupported("SC1090", expr, `reading the private static '${member}' through the subclass '${info.def.name.replace(/^%|^%m\d+\./, "")}' (JS brands the declaring class object alone — Node throws a TypeError here; spell the declaring class's name)`);
|
|
2930
|
+
}
|
|
2907
2931
|
}
|
|
2908
2932
|
if (staticShadowBelow(L, info, member)) {
|
|
2909
2933
|
L.unsupported("SC1090", expr, `reading the static member '${member}' through a class value (a subclass of '${info.def.name.replace(/^%|^%m\d+\./, "")}' redeclares it, so the runtime class decides which declaration answers)`);
|
|
@@ -3012,6 +3036,39 @@ export function exactInstanceClassOf(L, expr) {
|
|
|
3012
3036
|
init = init.expression;
|
|
3013
3037
|
return classOfNew(init);
|
|
3014
3038
|
}
|
|
3039
|
+
/** `const r: Repo = new MemRepo()` where EVERY member of the annotation's
|
|
3040
|
+
* checker type is a generic-callable method (`interface Repo { get<T>(id:
|
|
3041
|
+
* string): T }`): the record shape maps EMPTY — generic members are
|
|
3042
|
+
* excluded (no closure slot can hold a generic function) — so the
|
|
3043
|
+
* copy-reshape width coercion would DROP the exact class the method
|
|
3044
|
+
* calls monomorphize against, and in JS the binding IS the instance (no
|
|
3045
|
+
* copy exists). The binding keeps the initializer's class
|
|
3046
|
+
* representation instead: generic-method calls resolve like class-typed
|
|
3047
|
+
* receivers (exactInstanceClassOf reads the same const+new discipline),
|
|
3048
|
+
* and uses that want the empty record width-coerce at the use site.
|
|
3049
|
+
* Const + direct `new` only — a reassignable binding or a produced
|
|
3050
|
+
* value keeps today's record story and its fences. */
|
|
3051
|
+
export function genericIfaceBindingKeepsClass(L, decl, declaredType) {
|
|
3052
|
+
if (declaredType.kind !== "record")
|
|
3053
|
+
return false;
|
|
3054
|
+
if (!ts.isIdentifier(decl.name) || decl.initializer === undefined || decl.type === undefined)
|
|
3055
|
+
return false;
|
|
3056
|
+
if ((ts.getCombinedNodeFlags(decl) & ts.NodeFlags.Const) === 0)
|
|
3057
|
+
return false;
|
|
3058
|
+
let init = decl.initializer;
|
|
3059
|
+
while (ts.isParenthesizedExpression(init))
|
|
3060
|
+
init = init.expression;
|
|
3061
|
+
if (!ts.isNewExpression(init))
|
|
3062
|
+
return false;
|
|
3063
|
+
const shape = L.shapes.get(declaredType.shapeId);
|
|
3064
|
+
if (!shape || shape.fields.length > 0 || shape.indexValue !== undefined || shape.tuple === true)
|
|
3065
|
+
return false;
|
|
3066
|
+
const annT = L.typeOf(decl.name);
|
|
3067
|
+
const props = L.checker.getPropertiesOfType(annT);
|
|
3068
|
+
if (props.length === 0)
|
|
3069
|
+
return false;
|
|
3070
|
+
return props.every((p) => isGenericCallableMemberType(L.checker.getTypeOfSymbol(p), L.checker));
|
|
3071
|
+
}
|
|
3015
3072
|
/** `recv.m<T>(args)` — a GENERIC method call, dispatched STATICALLY: the
|
|
3016
3073
|
* checker's resolved signature (type arguments substituted, inferred or
|
|
3017
3074
|
* explicit) keys one instantiation of the nearest declarer's body, and
|
|
@@ -3020,7 +3077,7 @@ export function exactInstanceClassOf(L, expr) {
|
|
|
3020
3077
|
* runtime class could OVERRIDE the method (genericOverrideBelow) must be
|
|
3021
3078
|
* statically exact (exactInstanceClassOf) — the override set then
|
|
3022
3079
|
* resolves at compile time — or fences by name. */
|
|
3023
|
-
export function lowerClassGenericMethodCall(L, call, access, recvInfo, found) {
|
|
3080
|
+
export function lowerClassGenericMethodCall(L, call, access, recvInfo, found, recvIr) {
|
|
3024
3081
|
const name = access.name.text;
|
|
3025
3082
|
let { declarer, info } = found;
|
|
3026
3083
|
if (genericOverrideBelow(L, recvInfo, name)) {
|
|
@@ -3038,7 +3095,7 @@ export function lowerClassGenericMethodCall(L, call, access, recvInfo, found) {
|
|
|
3038
3095
|
const instance = info.implicitParams
|
|
3039
3096
|
? implicitCallInstance(L, call, info)
|
|
3040
3097
|
: genericCallInstance(L, call, info);
|
|
3041
|
-
const receiver = L.lowerExpr(access.expression);
|
|
3098
|
+
const receiver = recvIr ?? L.lowerExpr(access.expression);
|
|
3042
3099
|
const loc = locOf(call);
|
|
3043
3100
|
// The declarer sits at/above the receiver's static class on the plain
|
|
3044
3101
|
// path; the EXACT path can land below it (a base-typed const provably
|
|
@@ -4426,8 +4483,8 @@ export function lowerNew(L, expr) {
|
|
|
4426
4483
|
// construct-and-set loop, pairs in array order, duplicates
|
|
4427
4484
|
// overwrite). Other seeds — another Map, general iterables — keep
|
|
4428
4485
|
// the fence: never silently an empty map. Unsupported key/value
|
|
4429
|
-
// types get their half named specifically instead of the
|
|
4430
|
-
//
|
|
4486
|
+
// types get their half named specifically instead of the component
|
|
4487
|
+
// fence (SC2009, which names Map slots at value positions elsewhere).
|
|
4431
4488
|
// `new Array<T>()` and the ELEMENTS forms (`new Array('hi', 'bye')`,
|
|
4432
4489
|
// any argument list that is not one lone number) ARE array literals
|
|
4433
4490
|
// — the spec's ArrayCreate + element writes. The one-NUMBER form
|
|
@@ -4514,6 +4571,20 @@ export function lowerNew(L, expr) {
|
|
|
4514
4571
|
return { kind: "mapNew", seed, type: mapped, loc };
|
|
4515
4572
|
}
|
|
4516
4573
|
const targs = L.checker.getTypeArguments(tsType);
|
|
4574
|
+
// JAVASCRIPT `new Map()` whose arguments never resolved past
|
|
4575
|
+
// Map<any, any> (no annotation, no contextual type, no seed): the
|
|
4576
|
+
// WeakMap stance below — the VALUE lowers as an opaque DOM object
|
|
4577
|
+
// (identity and truthiness are real), and every reached METHOD use
|
|
4578
|
+
// meets its own per-site fence at runtime. The formatter's
|
|
4579
|
+
// config-cache shape: module init constructs the caches
|
|
4580
|
+
// unconditionally; the format path never touches them. TypeScript
|
|
4581
|
+
// keeps the compile fence.
|
|
4582
|
+
if (isJsSourceFile(expr.getSourceFile()) &&
|
|
4583
|
+
(expr.arguments?.length ?? 0) === 0 &&
|
|
4584
|
+
targs.length > 0 &&
|
|
4585
|
+
targs.every((t) => (t.flags & ts.TypeFlags.Any) !== 0)) {
|
|
4586
|
+
return { kind: "dynObjLit", type: DYN, loc };
|
|
4587
|
+
}
|
|
4517
4588
|
const keyIr = targs[0] ? L.mapTypeOf(targs[0]) : null;
|
|
4518
4589
|
if (targs[0] && (!keyIr || !isSupportedMapKey(keyIr))) {
|
|
4519
4590
|
L.unsupported("SC1090", expr, `Map keys of type '${L.checker.typeToString(targs[0])}' ` +
|
|
@@ -4687,6 +4758,30 @@ export function lowerNew(L, expr) {
|
|
|
4687
4758
|
// families carry pointed hints: each states WHY no honest static
|
|
4688
4759
|
// lowering exists (or what to use instead).
|
|
4689
4760
|
if (L.isStdlibSymbol(symbol ?? undefined)) {
|
|
4761
|
+
// The deprecated `new Buffer(string, encoding?)` ctor's string arm
|
|
4762
|
+
// with a NON-STRING first argument and a string second: Node
|
|
4763
|
+
// throws ERR_INVALID_ARG_TYPE synchronously (and DEP0005 never
|
|
4764
|
+
// fires on this throwing path, so the compiled silence matches).
|
|
4765
|
+
// Every other new Buffer form keeps the fence below — the
|
|
4766
|
+
// constructing forms would owe the deprecation warning.
|
|
4767
|
+
if (expr.expression.text === "Buffer" &&
|
|
4768
|
+
expr.arguments?.length === 2 &&
|
|
4769
|
+
!expr.arguments.some(ts.isSpreadElement) &&
|
|
4770
|
+
L.mapTypeOf(L.typeOf(expr.arguments[0]))?.kind !== "string" &&
|
|
4771
|
+
L.mapTypeOf(L.typeOf(expr.arguments[1]))?.kind === "string") {
|
|
4772
|
+
const first = L.lowerExpr(expr.arguments[0]);
|
|
4773
|
+
if (first.kind === "unitLit" || first.type.kind === "dyn" || L.dynConvertible(first.type)) {
|
|
4774
|
+
const got = first.type.kind === "dyn" ? first : { kind: "dynFrom", value: first, type: DYN, loc };
|
|
4775
|
+
// The encoding argument still evaluates in Node before the
|
|
4776
|
+
// throw only via the ctor body's later reads — it does NOT
|
|
4777
|
+
// observe it before throwing, so dropping it is exact for
|
|
4778
|
+
// effect-free operands; effectful ones keep the fence.
|
|
4779
|
+
const enc = L.lowerExpr(expr.arguments[1]);
|
|
4780
|
+
if (enc.kind === "strLit" || pureReemittable(enc)) {
|
|
4781
|
+
return { kind: "libCall", fn: "buffer.newStringFail", args: [got], type: bytesOf("u8"), loc };
|
|
4782
|
+
}
|
|
4783
|
+
}
|
|
4784
|
+
}
|
|
4690
4785
|
const ctorHints = {
|
|
4691
4786
|
RegExp: "use a regex literal (/pattern/flags) — constructed regexes have no lowering",
|
|
4692
4787
|
String: "boxed wrapper objects have no lowering — use the string primitive (the box is only distinguishable via typeof/identity, which nothing here can honor)",
|
|
@@ -4697,6 +4792,7 @@ export function lowerNew(L, expr) {
|
|
|
4697
4792
|
WeakRef: "deref()-after-collect exposes GC timing — genuinely dynamic; hold a strong reference instead",
|
|
4698
4793
|
FinalizationRegistry: "finalization callbacks expose GC timing — genuinely dynamic; release resources explicitly instead",
|
|
4699
4794
|
SharedArrayBuffer: "no shared-memory threads exist in a compiled program — Uint8Array is the byte storage",
|
|
4795
|
+
ArrayBuffer: "no free-standing ArrayBuffer value exists — typed arrays own their storage: allocate the view directly (new Uint8Array(n)), or erase a fresh buffer into one (new Uint8Array(new ArrayBuffer(n)), new DataView(new ArrayBuffer(n), ...))",
|
|
4700
4796
|
Proxy: "property-access metaprogramming has no static lowering (every property read must resolve at compile time)",
|
|
4701
4797
|
Function: "runtime code generation cannot be compiled ahead of time (the eval stance) — write the function",
|
|
4702
4798
|
};
|