@scriptc/compiler 0.4.3 → 0.4.4
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 +73 -29
- package/dist/backend/llvm/bytes-loop-versions.js +6 -0
- package/dist/backend/llvm/bytes-loop-versions.js.map +1 -1
- package/dist/backend/llvm/bytes-loop-versions.test.js +7 -2
- package/dist/backend/llvm/bytes-loop-versions.test.js.map +1 -1
- package/dist/backend/llvm/debug-info.js +2 -5
- package/dist/backend/llvm/debug-info.js.map +1 -1
- package/dist/backend/llvm/dyn.d.ts +4 -0
- package/dist/backend/llvm/dyn.js +21 -9
- package/dist/backend/llvm/dyn.js.map +1 -1
- package/dist/backend/llvm/emit-function.js +2 -8
- package/dist/backend/llvm/emit-function.js.map +1 -1
- package/dist/backend/llvm/emit-module.js +16 -6
- package/dist/backend/llvm/emit-module.js.map +1 -1
- package/dist/backend/llvm/emitter.d.ts +10 -0
- package/dist/backend/llvm/emitter.js +9 -5
- package/dist/backend/llvm/emitter.js.map +1 -1
- package/dist/backend/llvm/emitter.test.js +11 -2
- package/dist/backend/llvm/emitter.test.js.map +1 -1
- package/dist/backend/llvm/expr-async.js +11 -13
- package/dist/backend/llvm/expr-async.js.map +1 -1
- package/dist/backend/llvm/expr-bytes.js +14 -8
- package/dist/backend/llvm/expr-bytes.js.map +1 -1
- package/dist/backend/llvm/expr-containers.js +14 -0
- package/dist/backend/llvm/expr-containers.js.map +1 -1
- package/dist/backend/llvm/expr-primitives.js +20 -11
- package/dist/backend/llvm/expr-primitives.js.map +1 -1
- package/dist/backend/llvm/expr-stream-bridges.js +16 -4
- package/dist/backend/llvm/expr-stream-bridges.js.map +1 -1
- package/dist/backend/llvm/integer-values.d.ts +5 -0
- package/dist/backend/llvm/integer-values.js +27 -3
- package/dist/backend/llvm/integer-values.js.map +1 -1
- package/dist/backend/llvm/lib-dispatch.js +133 -3
- package/dist/backend/llvm/lib-dispatch.js.map +1 -1
- package/dist/backend/llvm/lib-process.js +37 -1
- package/dist/backend/llvm/lib-process.js.map +1 -1
- package/dist/backend/llvm/lib-shared.js +21 -0
- package/dist/backend/llvm/lib-shared.js.map +1 -1
- package/dist/backend/llvm/publish.js +3 -3
- package/dist/backend/llvm/publish.js.map +1 -1
- package/dist/backend/llvm/reference-effects.js +3 -0
- package/dist/backend/llvm/reference-effects.js.map +1 -1
- package/dist/backend/llvm/shapes.js +2 -7
- package/dist/backend/llvm/shapes.js.map +1 -1
- package/dist/backend/llvm/stack-captures.js +1 -5
- package/dist/backend/llvm/stack-captures.js.map +1 -1
- package/dist/backend/llvm/union-repr.d.ts +4 -3
- package/dist/backend/llvm/union-repr.js +6 -5
- package/dist/backend/llvm/union-repr.js.map +1 -1
- package/dist/backend/llvm/walkers.js +13 -0
- package/dist/backend/llvm/walkers.js.map +1 -1
- package/dist/backend/native-codegen-core.d.ts +5 -3
- package/dist/backend/native-codegen-core.js +13 -6
- package/dist/backend/native-codegen-core.js.map +1 -1
- package/dist/backend/native-codegen.test.js +6 -4
- package/dist/backend/native-codegen.test.js.map +1 -1
- package/dist/backend/target-cpu.d.ts +26 -0
- package/dist/backend/target-cpu.js +98 -0
- package/dist/backend/target-cpu.js.map +1 -0
- package/dist/backend/target-cpu.test.d.ts +1 -0
- package/dist/backend/target-cpu.test.js +38 -0
- package/dist/backend/target-cpu.test.js.map +1 -0
- package/dist/cli/command.js +20 -1
- package/dist/cli/command.js.map +1 -1
- package/dist/cli/usage.d.ts +4 -1
- package/dist/cli/usage.js +7 -0
- package/dist/cli/usage.js.map +1 -1
- package/dist/compile-types.d.ts +7 -0
- package/dist/diagnostics/diagnostic.js +1 -1
- package/dist/diagnostics/diagnostic.js.map +1 -1
- package/dist/executable/executable-cache.d.ts +3 -0
- package/dist/executable/executable-cache.js +4 -0
- package/dist/executable/executable-cache.js.map +1 -1
- package/dist/executable/executable-cache.test.js +2 -0
- package/dist/executable/executable-cache.test.js.map +1 -1
- package/dist/frontend/decl-projection.js +105 -10
- package/dist/frontend/decl-projection.js.map +1 -1
- package/dist/frontend/lowering/builtins/async-context.d.ts +8 -2
- package/dist/frontend/lowering/builtins/async-context.js +62 -3
- package/dist/frontend/lowering/builtins/async-context.js.map +1 -1
- package/dist/frontend/lowering/builtins/crypto.js +3 -1
- package/dist/frontend/lowering/builtins/crypto.js.map +1 -1
- package/dist/frontend/lowering/builtins/dates.js +4 -1
- package/dist/frontend/lowering/builtins/dates.js.map +1 -1
- package/dist/frontend/lowering/builtins/filesystem-calls.js +3 -3
- package/dist/frontend/lowering/builtins/filesystem-calls.js.map +1 -1
- package/dist/frontend/lowering/builtins/fs-glob.js +6 -3
- package/dist/frontend/lowering/builtins/fs-glob.js.map +1 -1
- package/dist/frontend/lowering/builtins/fs-paths.d.ts +43 -5
- package/dist/frontend/lowering/builtins/fs-paths.js +245 -93
- package/dist/frontend/lowering/builtins/fs-paths.js.map +1 -1
- package/dist/frontend/lowering/builtins/module-calls.js +6 -3
- package/dist/frontend/lowering/builtins/module-calls.js.map +1 -1
- package/dist/frontend/lowering/builtins/promises.d.ts +1 -1
- package/dist/frontend/lowering/builtins/promises.js +149 -138
- package/dist/frontend/lowering/builtins/promises.js.map +1 -1
- package/dist/frontend/lowering/call-signatures.js +0 -1
- package/dist/frontend/lowering/call-signatures.js.map +1 -1
- package/dist/frontend/lowering/cjs-exports-object.js +1 -1
- package/dist/frontend/lowering/cjs-exports-object.js.map +1 -1
- package/dist/frontend/lowering/cjs-inline-require.d.ts +32 -0
- package/dist/frontend/lowering/cjs-inline-require.js +307 -4
- package/dist/frontend/lowering/cjs-inline-require.js.map +1 -1
- package/dist/frontend/lowering/class-dynamic-dispatch.d.ts +10 -0
- package/dist/frontend/lowering/class-dynamic-dispatch.js +114 -0
- package/dist/frontend/lowering/class-dynamic-dispatch.js.map +1 -1
- package/dist/frontend/lowering/class-method-mutations.js +54 -18
- package/dist/frontend/lowering/class-method-mutations.js.map +1 -1
- package/dist/frontend/lowering/class-protocols.d.ts +25 -0
- package/dist/frontend/lowering/class-protocols.js +183 -1
- package/dist/frontend/lowering/class-protocols.js.map +1 -1
- package/dist/frontend/lowering/completion-callbacks.d.ts +4 -0
- package/dist/frontend/lowering/completion-callbacks.js +146 -0
- package/dist/frontend/lowering/completion-callbacks.js.map +1 -0
- package/dist/frontend/lowering/containers/array-callbacks.d.ts +5 -4
- package/dist/frontend/lowering/containers/array-callbacks.js +7 -6
- package/dist/frontend/lowering/containers/array-callbacks.js.map +1 -1
- package/dist/frontend/lowering/containers/array-construction.js +5 -0
- package/dist/frontend/lowering/containers/array-construction.js.map +1 -1
- package/dist/frontend/lowering/containers/array-methods.js +11 -3
- package/dist/frontend/lowering/containers/array-methods.js.map +1 -1
- package/dist/frontend/lowering/containers/bytes.d.ts +25 -17
- package/dist/frontend/lowering/containers/bytes.js +453 -45
- package/dist/frontend/lowering/containers/bytes.js.map +1 -1
- package/dist/frontend/lowering/date-values.d.ts +11 -0
- package/dist/frontend/lowering/date-values.js +207 -0
- package/dist/frontend/lowering/date-values.js.map +1 -0
- package/dist/frontend/lowering/expressions/array-literals.js +6 -0
- package/dist/frontend/lowering/expressions/array-literals.js.map +1 -1
- package/dist/frontend/lowering/expressions/binary.js +64 -26
- package/dist/frontend/lowering/expressions/binary.js.map +1 -1
- package/dist/frontend/lowering/expressions/element-access.js +79 -0
- package/dist/frontend/lowering/expressions/element-access.js.map +1 -1
- package/dist/frontend/lowering/expressions/identifiers.js +31 -1
- package/dist/frontend/lowering/expressions/identifiers.js.map +1 -1
- package/dist/frontend/lowering/expressions/property-access.js +56 -0
- package/dist/frontend/lowering/expressions/property-access.js.map +1 -1
- package/dist/frontend/lowering/expressions/typeof.js +6 -0
- package/dist/frontend/lowering/expressions/typeof.js.map +1 -1
- package/dist/frontend/lowering/expressions/updates.js +17 -0
- package/dist/frontend/lowering/expressions/updates.js.map +1 -1
- package/dist/frontend/lowering/function-returns.js +15 -0
- package/dist/frontend/lowering/function-returns.js.map +1 -1
- package/dist/frontend/lowering/indexed-unions.d.ts +54 -0
- package/dist/frontend/lowering/indexed-unions.js +401 -0
- package/dist/frontend/lowering/indexed-unions.js.map +1 -0
- package/dist/frontend/lowering/key-order-witness.js +210 -32
- package/dist/frontend/lowering/key-order-witness.js.map +1 -1
- package/dist/frontend/lowering/key-order-witness.test.js +104 -4
- package/dist/frontend/lowering/key-order-witness.test.js.map +1 -1
- package/dist/frontend/lowering/lower-assert.js +15 -3
- package/dist/frontend/lowering/lower-assert.js.map +1 -1
- package/dist/frontend/lowering/lower-calls.js +19 -3
- package/dist/frontend/lowering/lower-calls.js.map +1 -1
- package/dist/frontend/lowering/lower-classes.js +22 -47
- package/dist/frontend/lowering/lower-classes.js.map +1 -1
- package/dist/frontend/lowering/lower-exprs.js +205 -1
- package/dist/frontend/lowering/lower-exprs.js.map +1 -1
- package/dist/frontend/lowering/lower-generators.js +1 -1
- package/dist/frontend/lowering/lower-generators.js.map +1 -1
- package/dist/frontend/lowering/lower-inspect.d.ts +1 -1
- package/dist/frontend/lowering/lower-inspect.js +35 -11
- package/dist/frontend/lowering/lower-inspect.js.map +1 -1
- package/dist/frontend/lowering/lower-modules.js +21 -5
- package/dist/frontend/lowering/lower-modules.js.map +1 -1
- package/dist/frontend/lowering/lower-stmts.js +100 -34
- package/dist/frontend/lowering/lower-stmts.js.map +1 -1
- package/dist/frontend/lowering/lowerer.d.ts +30 -2
- package/dist/frontend/lowering/lowerer.js +68 -7
- package/dist/frontend/lowering/lowerer.js.map +1 -1
- package/dist/frontend/lowering/object-factory-new.d.ts +5 -0
- package/dist/frontend/lowering/object-factory-new.js +20 -6
- package/dist/frontend/lowering/object-factory-new.js.map +1 -1
- package/dist/frontend/lowering/overload-choice.d.ts +33 -0
- package/dist/frontend/lowering/overload-choice.js +190 -0
- package/dist/frontend/lowering/overload-choice.js.map +1 -0
- package/dist/frontend/lowering/surfaces.js +55 -2
- package/dist/frontend/lowering/surfaces.js.map +1 -1
- package/dist/frontend/pipeline.js +1 -1
- package/dist/frontend/pipeline.js.map +1 -1
- package/dist/frontend/program-analysis.d.ts +5 -1
- package/dist/frontend/program-analysis.js +5 -0
- package/dist/frontend/program-analysis.js.map +1 -1
- package/dist/frontend/program.d.ts +13 -5
- package/dist/frontend/program.js +197 -14
- package/dist/frontend/program.js.map +1 -1
- package/dist/frontend/ts7/semantic-model.d.ts +3 -0
- package/dist/frontend/ts7/semantic-model.js +5 -0
- package/dist/frontend/ts7/semantic-model.js.map +1 -1
- package/dist/frontend/ts7/semantic-model.test.js +6 -1
- package/dist/frontend/ts7/semantic-model.test.js.map +1 -1
- package/dist/frontend/ts7/semantic-types.d.ts +1 -1
- package/dist/frontend/ts7/semantic-types.js +1 -1
- package/dist/frontend/ts7/semantic-types.js.map +1 -1
- package/dist/frontend/type-mapper.js +45 -16
- package/dist/frontend/type-mapper.js.map +1 -1
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -1
- package/dist/ir/builtin-effects.js +8 -0
- package/dist/ir/builtin-effects.js.map +1 -1
- package/dist/ir/builtin-signatures.d.ts +1 -1
- package/dist/ir/builtin-signatures.js +56 -0
- package/dist/ir/builtin-signatures.js.map +1 -1
- package/dist/ir/int32-slots.js +7 -0
- package/dist/ir/int32-slots.js.map +1 -1
- package/dist/ir/int32-slots.test.js +33 -0
- package/dist/ir/int32-slots.test.js.map +1 -1
- package/dist/ir/integer-loops.js +14 -4
- package/dist/ir/integer-loops.js.map +1 -1
- package/dist/ir/ir.d.ts +13 -3
- package/dist/ir/ir.js +19 -5
- package/dist/ir/ir.js.map +1 -1
- package/dist/ir/ir.test.js +2 -1
- package/dist/ir/ir.test.js.map +1 -1
- package/dist/ir/js-ic.d.ts +2 -15
- package/dist/ir/js-ic.js +11 -79
- package/dist/ir/js-ic.js.map +1 -1
- package/dist/ir/js-ic.test.js +0 -142
- package/dist/ir/js-ic.test.js.map +1 -1
- package/dist/ir/runtime-features.js +25 -1
- package/dist/ir/runtime-features.js.map +1 -1
- package/dist/ir/validate.js +46 -5
- package/dist/ir/validate.js.map +1 -1
- package/dist/library/ir-policy.js +1 -0
- package/dist/library/ir-policy.js.map +1 -1
- package/dist/native/prepare.d.ts +1 -1
- package/dist/native/prepare.js +11 -1
- package/dist/native/prepare.js.map +1 -1
- package/dist/native/prepare.test.js +18 -2
- package/dist/native/prepare.test.js.map +1 -1
- package/package.json +20 -20
- package/surface-manifest.json +2 -4
|
@@ -1,17 +1,20 @@
|
|
|
1
1
|
import { keyedHelperName } from "../stable-names.js";
|
|
2
|
-
import {
|
|
2
|
+
import { allBytesArms, indexedUnionArms, lowerIndexedUnionMethod } from "../indexed-unions.js";
|
|
3
|
+
import { boolLit, dynUndefinedExpr, nodeThrowExpr, numLit, varRef } from "../../../ir/build.js";
|
|
3
4
|
import { BUF_NUM_METHODS } from "./buffer-numeric-methods.js";
|
|
4
5
|
import * as ts from "../../ts7/adapter.js";
|
|
6
|
+
import { constituentTypes } from "../../ts7/checker.js";
|
|
5
7
|
import { BIGINT_T, BOOL, BYTES_ELEMENT_NAME, BYTES_U8, DYN, F64, STRING, UNDEFINED_T, VOID, arrayOf, bytesOf, funcOf, isUnitType, typeEquals, } from "../../../ir/ir.js";
|
|
6
8
|
import { isJsSourceFile, locOf } from "../../program.js";
|
|
7
9
|
import { stdlibGlobalNameOf } from "../surfaces.js";
|
|
8
|
-
import { newFnCtx, own } from "../lowerer.js";
|
|
10
|
+
import { ENTRY_NAME, newFnCtx, own } from "../lowerer.js";
|
|
11
|
+
import { everyStmt } from "../../../ir/traverse.js";
|
|
9
12
|
import { buildBytesSortFn, closureKeyOrder } from "../lower-array-sort.js";
|
|
10
13
|
import { isSafeToDiscard } from "../expressions/evaluation-safety.js";
|
|
11
14
|
import { lowerDynObjectLiteral } from "../expressions/object-literals.js";
|
|
12
15
|
import { defaultAfterUndefined, lowerOptionalArgument, lowerStaticallyUndefinedArgument, } from "../optional-arguments.js";
|
|
13
16
|
import { lowerArraySpreadItems, lowerCheckedArrayFrom } from "./array-construction.js";
|
|
14
|
-
import { lowerToNumberArgument } from "../lower-exprs.js";
|
|
17
|
+
import { lowerOptionalNumber, lowerToNumberArgument } from "../lower-exprs.js";
|
|
15
18
|
import { lowerBytesIteratorValue } from "../iterator-adapters.js";
|
|
16
19
|
import { lowerArrayCallback } from "./callback-arguments.js";
|
|
17
20
|
import { callbackSite, findPredicateOk, predicateToBoolean } from "./array-callbacks.js";
|
|
@@ -726,6 +729,109 @@ function lowerDataViewNew(lowerer, expr) {
|
|
|
726
729
|
lowerer.noLowering("DataView constructor argument count", expr);
|
|
727
730
|
return lowerArrayBufferView(lowerer, args, "dv", locOf(expr));
|
|
728
731
|
}
|
|
732
|
+
/** `receiver.set(src, offset?)` on a lowered typed-array receiver. */
|
|
733
|
+
function bytesSetIntrinsic(lowerer, receiver, argNodes, loc) {
|
|
734
|
+
const src = lowerer.lowerExpr(argNodes[0]);
|
|
735
|
+
const method = src.type.kind === "bytes" ? "setFrom" : "setFromDyn";
|
|
736
|
+
const args = [src.type.kind === "bytes" ? src : lowerer.coerceInto(argNodes[0], src, DYN)];
|
|
737
|
+
if (argNodes.length === 2)
|
|
738
|
+
args.push(lowerOptionalArgument(lowerer, argNodes[1], F64, {
|
|
739
|
+
kind: "numLit",
|
|
740
|
+
value: 0,
|
|
741
|
+
type: F64,
|
|
742
|
+
loc,
|
|
743
|
+
}));
|
|
744
|
+
return { kind: "bytesIntrinsic", method, receiver, args, type: VOID, loc };
|
|
745
|
+
}
|
|
746
|
+
/** `Uint8Array.prototype.set.call(target, src, offset?)`, through any typed
|
|
747
|
+
* array constructor's prototype (they share %TypedArray%.prototype.set). A
|
|
748
|
+
* target the checker types as a typed array or Buffer lowers like
|
|
749
|
+
* `target.set(src, offset)`. Any other target, a DataView included, is
|
|
750
|
+
* checked at run time: a typed array calls its `set`, and
|
|
751
|
+
* anything else throws Node's TypeError "this is not a typed array.",
|
|
752
|
+
* after every argument is evaluated. */
|
|
753
|
+
export function lowerBytesPrototypeSetCall(lowerer, call, access) {
|
|
754
|
+
if (call.questionDotToken ||
|
|
755
|
+
access.questionDotToken ||
|
|
756
|
+
access.name.text !== "call" ||
|
|
757
|
+
!ts.isPropertyAccessExpression(access.expression))
|
|
758
|
+
return null;
|
|
759
|
+
const method = access.expression;
|
|
760
|
+
const proto = method.expression;
|
|
761
|
+
if (method.questionDotToken ||
|
|
762
|
+
method.name.text !== "set" ||
|
|
763
|
+
!ts.isPropertyAccessExpression(proto) ||
|
|
764
|
+
proto.questionDotToken ||
|
|
765
|
+
proto.name.text !== "prototype" ||
|
|
766
|
+
!ts.isIdentifier(proto.expression) ||
|
|
767
|
+
!lowerer.isStdlibMember(method))
|
|
768
|
+
return null;
|
|
769
|
+
const ctor = lowerer.resolveValueSymbol(proto.expression);
|
|
770
|
+
if (!ctor || !lowerer.isStdlibSymbol(ctor) || !own(BYTES_CTORS, ts.symbolName(ctor)))
|
|
771
|
+
return null;
|
|
772
|
+
const argNodes = call.arguments.nodes;
|
|
773
|
+
if (argNodes.length < 2 || argNodes.length > 3 || argNodes.some(ts.isSpreadElement))
|
|
774
|
+
return null;
|
|
775
|
+
const loc = locOf(call);
|
|
776
|
+
const target = lowerer.lowerExpr(argNodes[0]);
|
|
777
|
+
// A DataView lowers to the same bytes type, so the checker type decides:
|
|
778
|
+
// only a typed array (or a Buffer) takes the method's path.
|
|
779
|
+
const targetSymbol = lowerer.typeOf(argNodes[0]).getSymbol();
|
|
780
|
+
if (target.type.kind === "bytes" &&
|
|
781
|
+
targetSymbol !== undefined &&
|
|
782
|
+
lowerer.isStdlibSymbol(targetSymbol) &&
|
|
783
|
+
(own(BYTES_CTORS, ts.symbolName(targetSymbol)) !== undefined ||
|
|
784
|
+
ts.symbolName(targetSymbol) === "Buffer"))
|
|
785
|
+
return bytesSetIntrinsic(lowerer, target, argNodes.slice(1), loc);
|
|
786
|
+
const slot = (value) => {
|
|
787
|
+
const local = lowerer.declareHiddenLocal("%setArg", DYN);
|
|
788
|
+
return {
|
|
789
|
+
decl: { kind: "varDecl", localId: local.id, init: value, loc },
|
|
790
|
+
read: varRef(local.id, DYN, loc),
|
|
791
|
+
};
|
|
792
|
+
};
|
|
793
|
+
const slots = [
|
|
794
|
+
slot(lowerer.coerceInto(argNodes[0], target, DYN)),
|
|
795
|
+
...argNodes.slice(1).map((arg) => slot(lowerer.lowerExprExpecting(arg, DYN))),
|
|
796
|
+
];
|
|
797
|
+
const isTypedArray = {
|
|
798
|
+
kind: "libCall",
|
|
799
|
+
fn: "util.typeIs",
|
|
800
|
+
args: [slots[0].read, { kind: "strLit", value: "isTypedArray", type: STRING, loc }],
|
|
801
|
+
type: BOOL,
|
|
802
|
+
loc,
|
|
803
|
+
};
|
|
804
|
+
return {
|
|
805
|
+
kind: "seqExpr",
|
|
806
|
+
stmts: [
|
|
807
|
+
...slots.map((s) => s.decl),
|
|
808
|
+
{
|
|
809
|
+
kind: "if",
|
|
810
|
+
cond: { kind: "unary", op: "!", operand: isTypedArray, type: BOOL, loc },
|
|
811
|
+
then: [
|
|
812
|
+
{
|
|
813
|
+
kind: "exprStmt",
|
|
814
|
+
expr: nodeThrowExpr(1, "", "this is not a typed array.", VOID, loc),
|
|
815
|
+
loc,
|
|
816
|
+
},
|
|
817
|
+
],
|
|
818
|
+
else_: null,
|
|
819
|
+
loc,
|
|
820
|
+
},
|
|
821
|
+
],
|
|
822
|
+
result: {
|
|
823
|
+
kind: "dynInvoke",
|
|
824
|
+
recv: slots[0].read,
|
|
825
|
+
method: "set",
|
|
826
|
+
calleeName: ts.getTextOfNode(method),
|
|
827
|
+
args: slots.slice(1).map((s) => s.read),
|
|
828
|
+
type: DYN,
|
|
829
|
+
loc,
|
|
830
|
+
},
|
|
831
|
+
type: DYN,
|
|
832
|
+
loc,
|
|
833
|
+
};
|
|
834
|
+
}
|
|
729
835
|
/** Method calls on typed-array/Buffer receivers: slice (copy), subarray
|
|
730
836
|
* (shared view), toReversed, copyWithin, set(src,
|
|
731
837
|
* offset?), and the u8-only Buffer surface: toString(enc?) plus the
|
|
@@ -733,11 +839,131 @@ function lowerDataViewNew(lowerer, expr) {
|
|
|
733
839
|
* variable-width read/writeUIntLE quartet — BUF_NUM_METHODS). Everything
|
|
734
840
|
* else the lib declares (fill, indexOf, reverse, ...) falls through to
|
|
735
841
|
* the SC2020 member fence. Null when this isn't a bytes method call. */
|
|
842
|
+
/** The [needle, fromIndex] arguments of TypedArray indexOf, lastIndexOf
|
|
843
|
+
* and includes. A present fromIndex converts even when it is undefined
|
|
844
|
+
* (NaN, which ToIntegerOrInfinity makes 0); an absent one is 0, or
|
|
845
|
+
* +Infinity for lastIndexOf, which starts at the last element. */
|
|
846
|
+
function elementSearchArgs(lowerer, call, name) {
|
|
847
|
+
const nodes = call.arguments.nodes;
|
|
848
|
+
const loc = locOf(call);
|
|
849
|
+
const needle = lowerer.lowerExprExpecting(nodes[0], F64);
|
|
850
|
+
const from = nodes[1]
|
|
851
|
+
? lowerOptionalNumber(lowerer, lowerer.lowerExpr(nodes[1]), locOf(nodes[1]), nodes[1])
|
|
852
|
+
: {
|
|
853
|
+
kind: "numLit",
|
|
854
|
+
value: name === "lastIndexOf" ? Infinity : 0,
|
|
855
|
+
type: F64,
|
|
856
|
+
loc,
|
|
857
|
+
};
|
|
858
|
+
// An undefined fromIndex is NaN once converted, which starts at 0.
|
|
859
|
+
if (from.kind === "unitLit")
|
|
860
|
+
return [needle, { kind: "numLit", value: NaN, type: F64, loc }];
|
|
861
|
+
if (from.type.kind === "undefinedT" || from.type.kind === "void")
|
|
862
|
+
return [
|
|
863
|
+
needle,
|
|
864
|
+
{
|
|
865
|
+
kind: "seqExpr",
|
|
866
|
+
stmts: [{ kind: "exprStmt", expr: from, loc }],
|
|
867
|
+
result: { kind: "numLit", value: NaN, type: F64, loc },
|
|
868
|
+
type: F64,
|
|
869
|
+
loc,
|
|
870
|
+
},
|
|
871
|
+
];
|
|
872
|
+
if (from.type.kind !== "f64")
|
|
873
|
+
lowerer.noLowering(`.${name} with a non-number fromIndex`, call);
|
|
874
|
+
return [needle, from];
|
|
875
|
+
}
|
|
876
|
+
const ELEMENT_SEARCHES = {
|
|
877
|
+
indexOf: "indexOfElem",
|
|
878
|
+
lastIndexOf: "lastIndexOfElem",
|
|
879
|
+
includes: "includesElem",
|
|
880
|
+
};
|
|
881
|
+
/** Whether a union has a Buffer arm, under any alias name: each arm's own
|
|
882
|
+
* symbol names it. */
|
|
883
|
+
function hasBufferArm(type) {
|
|
884
|
+
const arms = type.flags & ts.TypeFlags.Union ? constituentTypes(type) : [type];
|
|
885
|
+
return arms.some((arm) => {
|
|
886
|
+
const symbol = arm.getSymbol();
|
|
887
|
+
return symbol !== undefined && ts.symbolName(symbol) === "Buffer";
|
|
888
|
+
});
|
|
889
|
+
}
|
|
890
|
+
/** The element-kind-generic typed-array methods on a union of typed
|
|
891
|
+
* arrays (indexed-unions.ts): the arguments lower as for one typed array,
|
|
892
|
+
* and each arm runs the method on its own receiver. Null for the methods
|
|
893
|
+
* that need a narrowing to one kind first. */
|
|
894
|
+
function lowerUnionBytesMethodCall(lowerer, call, access, name) {
|
|
895
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(call)))
|
|
896
|
+
return null;
|
|
897
|
+
// A Buffer arm's methods differ from a typed array's (slice aliases, fill
|
|
898
|
+
// checks its range, searches take strings and wrap numbers), so such a
|
|
899
|
+
// union narrows to its arms first.
|
|
900
|
+
if (hasBufferArm(lowerer.typeOf(access.expression)))
|
|
901
|
+
return null;
|
|
902
|
+
const nodes = call.arguments.nodes;
|
|
903
|
+
if (nodes.some(ts.isSpreadElement))
|
|
904
|
+
return null;
|
|
905
|
+
const loc = locOf(call);
|
|
906
|
+
const num = (value) => ({ kind: "numLit", value, type: F64, loc });
|
|
907
|
+
const optional = (i, fallback, type = F64) => nodes[i] ? lowerOptionalArgument(lowerer, nodes[i], type, fallback) : fallback;
|
|
908
|
+
let method;
|
|
909
|
+
let args;
|
|
910
|
+
let result;
|
|
911
|
+
if ((name === "slice" || name === "subarray") && nodes.length <= 2) {
|
|
912
|
+
method = name;
|
|
913
|
+
args = () => [optional(0, num(0)), optional(1, num(Infinity))];
|
|
914
|
+
result = "receiver";
|
|
915
|
+
}
|
|
916
|
+
else if (name === "fill" && nodes.length <= 3) {
|
|
917
|
+
method = "fillElem";
|
|
918
|
+
args = () => [optional(0, num(0)), optional(1, num(0)), optional(2, num(Infinity))];
|
|
919
|
+
result = "receiver";
|
|
920
|
+
}
|
|
921
|
+
else if (name === "copyWithin" && nodes.length <= 3) {
|
|
922
|
+
method = "copyWithin";
|
|
923
|
+
args = () => [optional(0, num(0)), optional(1, num(0)), optional(2, num(Infinity))];
|
|
924
|
+
result = "receiver";
|
|
925
|
+
}
|
|
926
|
+
else if (name === "toReversed" && nodes.length === 0) {
|
|
927
|
+
method = "toReversed";
|
|
928
|
+
args = () => [];
|
|
929
|
+
result = "receiver";
|
|
930
|
+
}
|
|
931
|
+
else if (Object.hasOwn(ELEMENT_SEARCHES, name) && (nodes.length === 1 || nodes.length === 2)) {
|
|
932
|
+
method = ELEMENT_SEARCHES[name];
|
|
933
|
+
args = () => elementSearchArgs(lowerer, call, name);
|
|
934
|
+
result = name === "includes" ? BOOL : F64;
|
|
935
|
+
}
|
|
936
|
+
else if (name === "join" && nodes.length <= 1) {
|
|
937
|
+
method = "join";
|
|
938
|
+
args = () => [optional(0, { kind: "strLit", value: ",", type: STRING, loc }, STRING)];
|
|
939
|
+
result = STRING;
|
|
940
|
+
}
|
|
941
|
+
else if (name === "set" && (nodes.length === 1 || nodes.length === 2)) {
|
|
942
|
+
const source = lowerer.mapTypeOf(lowerer.typeOf(nodes[0]));
|
|
943
|
+
method = source?.kind === "bytes" ? "setFrom" : "setFromDyn";
|
|
944
|
+
args = () => {
|
|
945
|
+
const src = lowerer.lowerExpr(nodes[0]);
|
|
946
|
+
const first = src.type.kind === "bytes" ? src : lowerer.coerceInto(nodes[0], src, DYN);
|
|
947
|
+
return nodes.length === 2 ? [first, optional(1, num(0))] : [first];
|
|
948
|
+
};
|
|
949
|
+
result = VOID;
|
|
950
|
+
}
|
|
951
|
+
else
|
|
952
|
+
return null;
|
|
953
|
+
const receiver = lowerer.lowerExpr(access.expression);
|
|
954
|
+
const arms = indexedUnionArms(lowerer, receiver.type);
|
|
955
|
+
if (!arms || !allBytesArms(arms))
|
|
956
|
+
return null;
|
|
957
|
+
return lowerIndexedUnionMethod(lowerer, receiver, arms, method, args(), result, loc);
|
|
958
|
+
}
|
|
736
959
|
export function lowerBytesMethodCall(lowerer, call, access) {
|
|
737
960
|
if (lowerer.chainBlocked(access, call))
|
|
738
961
|
return null;
|
|
739
962
|
const name = access.name.text;
|
|
740
963
|
const receiverIr = lowerer.mapTypeOf(lowerer.typeOf(access.expression));
|
|
964
|
+
const unionArms = receiverIr ? indexedUnionArms(lowerer, receiverIr) : null;
|
|
965
|
+
if (unionArms && allBytesArms(unionArms) && lowerer.isStdlibMember(access))
|
|
966
|
+
return lowerUnionBytesMethodCall(lowerer, call, access, name);
|
|
741
967
|
if (receiverIr?.kind !== "bytes")
|
|
742
968
|
return null;
|
|
743
969
|
if (!lowerer.isStdlibMember(access))
|
|
@@ -780,6 +1006,25 @@ export function lowerBytesMethodCall(lowerer, call, access) {
|
|
|
780
1006
|
return value;
|
|
781
1007
|
}
|
|
782
1008
|
}
|
|
1009
|
+
// TypedArray indexOf / lastIndexOf / includes (the Buffer-declared forms,
|
|
1010
|
+
// which also take string and Buffer needles, lowered above).
|
|
1011
|
+
if (Object.hasOwn(ELEMENT_SEARCHES, name) &&
|
|
1012
|
+
!lowerer.checker
|
|
1013
|
+
.getSymbolAtLocation(access.name)
|
|
1014
|
+
?.declarations.some((d) => ts.isInterfaceDeclaration(d.parent) && d.parent.name.text === "Buffer")) {
|
|
1015
|
+
if (nArgs < 1 || nArgs > 2 || call.arguments.nodes.some(ts.isSpreadElement)) {
|
|
1016
|
+
lowerer.noLowering(`.${name} with ${nArgs} arguments on typed arrays`, call);
|
|
1017
|
+
}
|
|
1018
|
+
const receiver = lowerer.lowerExprExpecting(access.expression, receiverIr);
|
|
1019
|
+
return {
|
|
1020
|
+
kind: "bytesIntrinsic",
|
|
1021
|
+
method: ELEMENT_SEARCHES[name],
|
|
1022
|
+
receiver,
|
|
1023
|
+
args: elementSearchArgs(lowerer, call, name),
|
|
1024
|
+
type: name === "includes" ? BOOL : F64,
|
|
1025
|
+
loc,
|
|
1026
|
+
};
|
|
1027
|
+
}
|
|
783
1028
|
if (name === "toReversed") {
|
|
784
1029
|
if (nArgs !== 0) {
|
|
785
1030
|
lowerer.noLowering(`.toReversed with ${nArgs} arguments on typed arrays`, call);
|
|
@@ -906,19 +1151,7 @@ export function lowerBytesMethodCall(lowerer, call, access) {
|
|
|
906
1151
|
lowerer.noLowering(`.set with ${nArgs} arguments on typed arrays`, call);
|
|
907
1152
|
}
|
|
908
1153
|
const receiver = lowerer.lowerExprExpecting(access.expression, receiverIr);
|
|
909
|
-
|
|
910
|
-
const method = src.type.kind === "bytes" ? "setFrom" : "setFromDyn";
|
|
911
|
-
const args = [
|
|
912
|
-
src.type.kind === "bytes" ? src : lowerer.coerceInto(call.arguments.nodes[0], src, DYN),
|
|
913
|
-
];
|
|
914
|
-
if (nArgs === 2)
|
|
915
|
-
args.push(lowerOptionalArgument(lowerer, call.arguments.nodes[1], F64, {
|
|
916
|
-
kind: "numLit",
|
|
917
|
-
value: 0,
|
|
918
|
-
type: F64,
|
|
919
|
-
loc,
|
|
920
|
-
}));
|
|
921
|
-
return { kind: "bytesIntrinsic", method, receiver, args, type: VOID, loc };
|
|
1154
|
+
return bytesSetIntrinsic(lowerer, receiver, call.arguments.nodes, loc);
|
|
922
1155
|
}
|
|
923
1156
|
if (name === "toString") {
|
|
924
1157
|
// Buffer's toString(encoding?) — utf8 by default. A 0-arg toString
|
|
@@ -1055,6 +1288,8 @@ export function lowerBytesMethodCall(lowerer, call, access) {
|
|
|
1055
1288
|
if (receiverIr.elem !== "u8") {
|
|
1056
1289
|
lowerer.noLowering(`.${name} on a '${lowerer.fmt(receiverIr)}'`, call, "the numeric families read/write Buffer bytes");
|
|
1057
1290
|
}
|
|
1291
|
+
if (!numericArguments(lowerer, call))
|
|
1292
|
+
return dynNumericCall(lowerer, call, access, name, receiverIr, loc);
|
|
1058
1293
|
const write = name.startsWith("write");
|
|
1059
1294
|
const required = write ? 1 : 0; // value; offset defaults to 0
|
|
1060
1295
|
if (nArgs < required || nArgs > required + 1) {
|
|
@@ -1223,6 +1458,30 @@ const BUF_BIGINT_METHODS = {
|
|
|
1223
1458
|
writeBigUint64BE: { sign: false, le: false },
|
|
1224
1459
|
writeBigUint64LE: { sign: false, le: true },
|
|
1225
1460
|
};
|
|
1461
|
+
/** Whether every argument of a numeric read/write is statically a number. */
|
|
1462
|
+
function numericArguments(lowerer, call) {
|
|
1463
|
+
return call.arguments.nodes.every((a) => lowerer.mapTypeOf(lowerer.typeOf(a))?.kind === "f64");
|
|
1464
|
+
}
|
|
1465
|
+
/** A numeric read/write with an argument that is not a number (a string
|
|
1466
|
+
* offset from untyped JavaScript): the checked-dynamic Buffer method runs
|
|
1467
|
+
* Node's argument validation at runtime. */
|
|
1468
|
+
function dynNumericCall(lowerer, call, access, name, receiverIr, loc) {
|
|
1469
|
+
const receiver = lowerer.lowerExprExpecting(access.expression, receiverIr);
|
|
1470
|
+
return {
|
|
1471
|
+
kind: "dynCheck",
|
|
1472
|
+
value: {
|
|
1473
|
+
kind: "dynInvoke",
|
|
1474
|
+
recv: { kind: "dynFrom", value: receiver, type: DYN, loc, liveRef: true },
|
|
1475
|
+
method: name,
|
|
1476
|
+
calleeName: ts.getTextOfNode(access),
|
|
1477
|
+
args: call.arguments.nodes.map((a) => lowerer.lowerExprExpecting(a, DYN)),
|
|
1478
|
+
type: DYN,
|
|
1479
|
+
loc,
|
|
1480
|
+
},
|
|
1481
|
+
type: F64,
|
|
1482
|
+
loc,
|
|
1483
|
+
};
|
|
1484
|
+
}
|
|
1226
1485
|
/** The variable-width quartet (offset + byteLength) → sign/endian token. */
|
|
1227
1486
|
const BUF_NUM_VAR_METHODS = {
|
|
1228
1487
|
readUIntBE: "ube",
|
|
@@ -1565,7 +1824,7 @@ function knownBufferProducer(lowerer, source, seen = new Set()) {
|
|
|
1565
1824
|
* or empty encoding and throws ERR_UNKNOWN_ENCODING for an unknown name; an
|
|
1566
1825
|
* ArrayBuffer takes the second argument as its byte offset; other sources
|
|
1567
1826
|
* ignore it. */
|
|
1568
|
-
function dynBufferFromParts(source, encoding, loc) {
|
|
1827
|
+
function dynBufferFromParts(source, encoding, loc, length) {
|
|
1569
1828
|
const utf8 = { kind: "strLit", value: "utf8", type: STRING, loc };
|
|
1570
1829
|
const isString = (x) => ({
|
|
1571
1830
|
kind: "dynTest",
|
|
@@ -1606,19 +1865,39 @@ function dynBufferFromParts(source, encoding, loc) {
|
|
|
1606
1865
|
type: BYTES_U8,
|
|
1607
1866
|
loc,
|
|
1608
1867
|
},
|
|
1609
|
-
// An ArrayBuffer takes the second argument as its byte offset
|
|
1610
|
-
// (
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1868
|
+
// An ArrayBuffer takes the second argument as its byte offset and the
|
|
1869
|
+
// third as its length (scr_buffer_from_dyn_range_pooled); other values
|
|
1870
|
+
// convert with utf8.
|
|
1871
|
+
else_: length
|
|
1872
|
+
? {
|
|
1873
|
+
kind: "libCall",
|
|
1874
|
+
fn: "buffer.poolFromDynRange",
|
|
1875
|
+
args: [source, encoding, length],
|
|
1876
|
+
type: BYTES_U8,
|
|
1877
|
+
loc,
|
|
1878
|
+
}
|
|
1879
|
+
: {
|
|
1880
|
+
kind: "libCall",
|
|
1881
|
+
fn: "buffer.poolFromDynOffset",
|
|
1882
|
+
args: [source, encoding],
|
|
1883
|
+
type: BYTES_U8,
|
|
1884
|
+
loc,
|
|
1885
|
+
},
|
|
1618
1886
|
type: BYTES_U8,
|
|
1619
1887
|
loc,
|
|
1620
1888
|
};
|
|
1621
1889
|
}
|
|
1890
|
+
/** Buffer.from(arrayBuffer, byteOffset[, length]): each argument in order
|
|
1891
|
+
* as a checked-dynamic value, read by the runtime as Node's
|
|
1892
|
+
* fromArrayBuffer reads them. */
|
|
1893
|
+
function bufferFromArrayBufferRange(lowerer, args, loc, first) {
|
|
1894
|
+
const operands = [0, 1, 2].map((i) => i === 0 && first
|
|
1895
|
+
? first
|
|
1896
|
+
: args[i]
|
|
1897
|
+
? lowerer.lowerExprExpecting(args[i], DYN)
|
|
1898
|
+
: dynUndefinedExpr(loc));
|
|
1899
|
+
return { kind: "libCall", fn: "buffer.poolFromDynRange", args: operands, type: BYTES_U8, loc };
|
|
1900
|
+
}
|
|
1622
1901
|
/** Lowers `source` and `encNode` (or undefined) into hidden dyn locals, in
|
|
1623
1902
|
* source order, and builds the result from their references. */
|
|
1624
1903
|
function withDynBufferArguments(lowerer, source, encNode, loc, build) {
|
|
@@ -1651,30 +1930,37 @@ function dynBufferFromRuntimeEncoding(lowerer, value, encNode, loc) {
|
|
|
1651
1930
|
return null;
|
|
1652
1931
|
return withDynBufferArguments(lowerer, value, encNode, loc, (source, encoding) => dynBufferFromParts(source, encoding, loc));
|
|
1653
1932
|
}
|
|
1654
|
-
/** The deprecated `
|
|
1655
|
-
*
|
|
1656
|
-
*
|
|
1657
|
-
*
|
|
1658
|
-
*
|
|
1659
|
-
*
|
|
1660
|
-
* converts as Buffer.from does.
|
|
1661
|
-
*
|
|
1662
|
-
export function
|
|
1663
|
-
|
|
1664
|
-
if (!isJsSourceFile(sf) || !/[\\/]node_modules[\\/]/.test(sf.fileName))
|
|
1933
|
+
/** The deprecated `Buffer(arg[, encodingOrOffset[, length]])`, called or
|
|
1934
|
+
* constructed through the global or an alias of it, as Node's Buffer
|
|
1935
|
+
* function runs it: the arguments evaluate in order, DEP0005 is reported
|
|
1936
|
+
* on the next tick (once, and never for a call made from node_modules,
|
|
1937
|
+
* which only counts toward Node's 10000-call check), then a number
|
|
1938
|
+
* allocates zero-filled bytes (and throws ERR_INVALID_ARG_TYPE beside a
|
|
1939
|
+
* string second argument) and anything else converts as Buffer.from does.
|
|
1940
|
+
* Null for spread arguments and more than three. */
|
|
1941
|
+
export function lowerBufferConstruct(lowerer, expr) {
|
|
1942
|
+
if (ts.isCallExpression(expr) && expr.questionDotToken)
|
|
1665
1943
|
return null;
|
|
1666
1944
|
const args = expr.arguments?.nodes ?? [];
|
|
1667
|
-
if (args.length
|
|
1945
|
+
if (args.length > 3 || args.some(ts.isSpreadElement))
|
|
1668
1946
|
return null;
|
|
1669
1947
|
if (stdlibGlobalNameOf(lowerer, expr.expression) !== "Buffer")
|
|
1670
1948
|
return null;
|
|
1671
1949
|
const loc = locOf(expr);
|
|
1672
|
-
const
|
|
1950
|
+
const locals = [0, 1, 2].slice(0, Math.max(args.length, 2)).map((i) => {
|
|
1951
|
+
const local = lowerer.declareHiddenLocal("%bufferArgument", DYN);
|
|
1952
|
+
const node = args[i];
|
|
1953
|
+
const init = node === undefined ? dynUndefinedExpr(loc) : lowerer.lowerExprExpecting(node, DYN);
|
|
1954
|
+
return { local, init };
|
|
1955
|
+
});
|
|
1956
|
+
const [source, second, third] = locals.map(({ local }) => varRef(local.id, DYN, loc));
|
|
1957
|
+
const inNodeModules = /[\\/]node_modules[\\/]/.test(expr.getSourceFile().fileName);
|
|
1958
|
+
const value = {
|
|
1673
1959
|
kind: "ternary",
|
|
1674
1960
|
cond: { kind: "dynTest", test: "number", value: source, type: BOOL, loc },
|
|
1675
1961
|
then: {
|
|
1676
1962
|
kind: "ternary",
|
|
1677
|
-
cond: { kind: "dynTest", test: "string", value:
|
|
1963
|
+
cond: { kind: "dynTest", test: "string", value: second, type: BOOL, loc },
|
|
1678
1964
|
then: { kind: "libCall", fn: "buffer.newStringFail", args: [source], type: BYTES_U8, loc },
|
|
1679
1965
|
else_: {
|
|
1680
1966
|
kind: "libCall",
|
|
@@ -1686,11 +1972,35 @@ export function lowerNodeModulesBufferConstruct(lowerer, expr) {
|
|
|
1686
1972
|
type: BYTES_U8,
|
|
1687
1973
|
loc,
|
|
1688
1974
|
},
|
|
1689
|
-
else_: dynBufferFromParts(source,
|
|
1975
|
+
else_: dynBufferFromParts(source, second, loc, third),
|
|
1690
1976
|
type: BYTES_U8,
|
|
1691
1977
|
loc,
|
|
1692
|
-
}
|
|
1693
|
-
return {
|
|
1978
|
+
};
|
|
1979
|
+
return {
|
|
1980
|
+
kind: "seqExpr",
|
|
1981
|
+
stmts: [
|
|
1982
|
+
...locals.map(({ local, init }) => ({
|
|
1983
|
+
kind: "varDecl",
|
|
1984
|
+
localId: local.id,
|
|
1985
|
+
init,
|
|
1986
|
+
loc,
|
|
1987
|
+
})),
|
|
1988
|
+
{
|
|
1989
|
+
kind: "exprStmt",
|
|
1990
|
+
expr: {
|
|
1991
|
+
kind: "libCall",
|
|
1992
|
+
fn: inNodeModules ? "buffer.deprecationCount" : "buffer.deprecation",
|
|
1993
|
+
args: [],
|
|
1994
|
+
type: VOID,
|
|
1995
|
+
loc,
|
|
1996
|
+
},
|
|
1997
|
+
loc,
|
|
1998
|
+
},
|
|
1999
|
+
],
|
|
2000
|
+
result: { kind: "libCall", fn: "buffer.brand", args: [value], type: BYTES_U8, loc },
|
|
2001
|
+
type: BYTES_U8,
|
|
2002
|
+
loc,
|
|
2003
|
+
};
|
|
1694
2004
|
}
|
|
1695
2005
|
/** Buffer.from(array or bytes, extra): Node copies an array-like source and
|
|
1696
2006
|
* ignores the encoding/offset argument (yazl passes its `encoding` through
|
|
@@ -1737,7 +2047,18 @@ function lowerBufferStaticValue(lowerer, call, access) {
|
|
|
1737
2047
|
!args.some(ts.isSpreadElement) &&
|
|
1738
2048
|
((symbol) => symbol != null &&
|
|
1739
2049
|
(ts.symbolName(symbol) === "ArrayBuffer" || ts.symbolName(symbol) === "SharedArrayBuffer"))(lowerer.typeOf(args[0]).getSymbol())) {
|
|
1740
|
-
|
|
2050
|
+
// A byte offset or length follows Node's fromArrayBuffer (its
|
|
2051
|
+
// conversions and ERR_BUFFER_OUT_OF_BOUNDS), not the typed-array view.
|
|
2052
|
+
if (args.length === 1)
|
|
2053
|
+
return lowerArrayBufferView(lowerer, args, "u8", loc);
|
|
2054
|
+
return bufferFromArrayBufferRange(lowerer, args, loc);
|
|
2055
|
+
}
|
|
2056
|
+
// Buffer.from(value, byteOffset, length) over an untyped value: an
|
|
2057
|
+
// ArrayBuffer's range, or the two-argument conversion of other values.
|
|
2058
|
+
if (args.length === 3 && !args.some(ts.isSpreadElement)) {
|
|
2059
|
+
const first = lowerer.lowerExpr(args[0]);
|
|
2060
|
+
if (first.type.kind === "dyn")
|
|
2061
|
+
return bufferFromArrayBufferRange(lowerer, args, loc, first);
|
|
1741
2062
|
}
|
|
1742
2063
|
// Buffer.from(x.buffer[, byteOffset[, length]]): a u8 VIEW sharing
|
|
1743
2064
|
// x's storage (Node shares the ArrayBuffer; length is in BYTES).
|
|
@@ -2132,8 +2453,95 @@ function lowerBufferStaticValue(lowerer, call, access) {
|
|
|
2132
2453
|
const s = lowerer.lowerExprExpecting(args[0], STRING);
|
|
2133
2454
|
return { kind: "libCall", fn: "buffer.isEncoding", args: [s], type: BOOL, loc };
|
|
2134
2455
|
}
|
|
2135
|
-
|
|
2456
|
+
// Any other single argument: Node answers false for non-strings.
|
|
2457
|
+
if (args.length === 1 && !ts.isSpreadElement(args[0])) {
|
|
2458
|
+
const value = lowerer.declareHiddenLocal("%bufferEncoding", DYN);
|
|
2459
|
+
const ref = varRef(value.id, DYN, loc);
|
|
2460
|
+
return {
|
|
2461
|
+
kind: "seqExpr",
|
|
2462
|
+
stmts: [
|
|
2463
|
+
{
|
|
2464
|
+
kind: "varDecl",
|
|
2465
|
+
localId: value.id,
|
|
2466
|
+
init: lowerer.lowerExprExpecting(args[0], DYN),
|
|
2467
|
+
loc,
|
|
2468
|
+
},
|
|
2469
|
+
],
|
|
2470
|
+
result: {
|
|
2471
|
+
kind: "logical",
|
|
2472
|
+
op: "&&",
|
|
2473
|
+
left: { kind: "dynTest", test: "string", value: ref, type: BOOL, loc },
|
|
2474
|
+
right: {
|
|
2475
|
+
kind: "libCall",
|
|
2476
|
+
fn: "buffer.isEncoding",
|
|
2477
|
+
args: [{ kind: "dynCheck", value: ref, type: STRING, loc }],
|
|
2478
|
+
type: BOOL,
|
|
2479
|
+
loc,
|
|
2480
|
+
},
|
|
2481
|
+
type: BOOL,
|
|
2482
|
+
loc,
|
|
2483
|
+
},
|
|
2484
|
+
type: BOOL,
|
|
2485
|
+
loc,
|
|
2486
|
+
};
|
|
2487
|
+
}
|
|
2488
|
+
lowerer.noLowering("Buffer.isEncoding with this argument shape", call, "one argument is the lowered form");
|
|
2136
2489
|
}
|
|
2137
2490
|
return null; // of, copyBytesFrom, ... → the SC2020 member fence
|
|
2138
2491
|
}
|
|
2492
|
+
/** `Buffer.prototype.<name>` or `Buffer.prototype[key]` read in JavaScript
|
|
2493
|
+
* (smart-buffer's `typeof Buffer.prototype[method]` probe): the member as
|
|
2494
|
+
* scr_buffer_prototype_member answers it. Null for other expressions. */
|
|
2495
|
+
export function lowerBufferPrototypeMember(lowerer, expr) {
|
|
2496
|
+
if (expr.questionDotToken || !isJsSourceFile(expr.getSourceFile()))
|
|
2497
|
+
return null;
|
|
2498
|
+
const receiver = expr.expression;
|
|
2499
|
+
if (!ts.isPropertyAccessExpression(receiver) ||
|
|
2500
|
+
receiver.questionDotToken ||
|
|
2501
|
+
receiver.name.text !== "prototype" ||
|
|
2502
|
+
stdlibGlobalNameOf(lowerer, receiver.expression) !== "Buffer")
|
|
2503
|
+
return null;
|
|
2504
|
+
const loc = locOf(expr);
|
|
2505
|
+
const key = ts.isPropertyAccessExpression(expr)
|
|
2506
|
+
? {
|
|
2507
|
+
kind: "dynFrom",
|
|
2508
|
+
value: { kind: "strLit", value: expr.name.text, type: STRING, loc },
|
|
2509
|
+
type: DYN,
|
|
2510
|
+
loc,
|
|
2511
|
+
}
|
|
2512
|
+
: lowerer.lowerExprExpecting(expr.argumentExpression, DYN);
|
|
2513
|
+
return { kind: "libCall", fn: "buffer.prototypeMember", args: [key], type: DYN, loc };
|
|
2514
|
+
}
|
|
2515
|
+
const BUFFER_VALUE_FNS = new Set([
|
|
2516
|
+
"buffer.constructor",
|
|
2517
|
+
"buffer.staticValue",
|
|
2518
|
+
"buffer.prototypeMember",
|
|
2519
|
+
]);
|
|
2520
|
+
/** A program that reads the Buffer function's value installs it in %main,
|
|
2521
|
+
* so a Buffer's `.constructor` answers the same function. */
|
|
2522
|
+
export function installBufferValue(functions) {
|
|
2523
|
+
let found = false;
|
|
2524
|
+
const visitor = {
|
|
2525
|
+
expr: (e) => {
|
|
2526
|
+
if (e.kind === "libCall" && BUFFER_VALUE_FNS.has(e.fn))
|
|
2527
|
+
found = true;
|
|
2528
|
+
return !found;
|
|
2529
|
+
},
|
|
2530
|
+
stmt: () => !found,
|
|
2531
|
+
};
|
|
2532
|
+
for (const fn of functions) {
|
|
2533
|
+
for (const s of fn.body)
|
|
2534
|
+
everyStmt(s, visitor);
|
|
2535
|
+
if (found)
|
|
2536
|
+
break;
|
|
2537
|
+
}
|
|
2538
|
+
const main = functions.find((fn) => fn.name === ENTRY_NAME);
|
|
2539
|
+
if (!found || !main)
|
|
2540
|
+
return;
|
|
2541
|
+
main.body.unshift({
|
|
2542
|
+
kind: "exprStmt",
|
|
2543
|
+
expr: { kind: "libCall", fn: "buffer.installValue", args: [], type: VOID, loc: main.loc },
|
|
2544
|
+
loc: main.loc,
|
|
2545
|
+
});
|
|
2546
|
+
}
|
|
2139
2547
|
//# sourceMappingURL=bytes.js.map
|