xbintsc 0.2.4 → 0.2.6
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/dist/src/ast/declarations.d.ts +20 -1
- package/dist/src/ast/expressions.d.ts +6 -2
- package/dist/src/ast/kinds.d.ts +6 -1
- package/dist/src/ast/kinds.js +5 -0
- package/dist/src/ast/kinds.js.map +1 -1
- package/dist/src/ast/statements.d.ts +2 -1
- package/dist/src/binder/binder.js +73 -9
- package/dist/src/binder/binder.js.map +1 -1
- package/dist/src/cli/main.js +2 -4
- package/dist/src/cli/main.js.map +1 -1
- package/dist/src/codegen/generator/calls.d.ts +1 -1
- package/dist/src/codegen/generator/calls.js +57 -14
- package/dist/src/codegen/generator/calls.js.map +1 -1
- package/dist/src/codegen/generator/context.d.ts +1 -1
- package/dist/src/codegen/generator/expressions.js +39 -3
- package/dist/src/codegen/generator/expressions.js.map +1 -1
- package/dist/src/codegen/generator/module.js +73 -7
- package/dist/src/codegen/generator/module.js.map +1 -1
- package/dist/src/codegen/generator/state.js +16 -0
- package/dist/src/codegen/generator/state.js.map +1 -1
- package/dist/src/codegen/generator/statements.d.ts +4 -1
- package/dist/src/codegen/generator/statements.js +141 -10
- package/dist/src/codegen/generator/statements.js.map +1 -1
- package/dist/src/codegen/generator/tables.d.ts +3 -0
- package/dist/src/codegen/generator/tables.js +13 -0
- package/dist/src/codegen/generator/tables.js.map +1 -1
- package/dist/src/codegen/values.d.ts +18 -11
- package/dist/src/codegen/values.js +92 -15
- package/dist/src/codegen/values.js.map +1 -1
- package/dist/src/diagnostics/source.d.ts +1 -1
- package/dist/src/diagnostics/source.js +12 -7
- package/dist/src/diagnostics/source.js.map +1 -1
- package/dist/src/driver/compiler.d.ts +5 -0
- package/dist/src/driver/compiler.js +42 -2
- package/dist/src/driver/compiler.js.map +1 -1
- package/dist/src/driver/modules.js +29 -4
- package/dist/src/driver/modules.js.map +1 -1
- package/dist/src/extensions/node/child_process/index.d.ts +7 -0
- package/dist/src/extensions/node/child_process/index.js +19 -0
- package/dist/src/extensions/node/child_process/index.js.map +1 -0
- package/dist/src/extensions/node/crypto/index.d.ts +6 -0
- package/dist/src/extensions/node/crypto/index.js +18 -0
- package/dist/src/extensions/node/crypto/index.js.map +1 -0
- package/dist/src/extensions/node/index.js +6 -0
- package/dist/src/extensions/node/index.js.map +1 -1
- package/dist/src/extensions/node/module.d.ts +9 -1
- package/dist/src/extensions/node/module.js +14 -1
- package/dist/src/extensions/node/module.js.map +1 -1
- package/dist/src/extensions/node/url/index.d.ts +7 -0
- package/dist/src/extensions/node/url/index.js +21 -0
- package/dist/src/extensions/node/url/index.js.map +1 -0
- package/dist/src/lexer/scanner.js +4 -5
- package/dist/src/lexer/scanner.js.map +1 -1
- package/dist/src/lexer/token.d.ts +10 -0
- package/dist/src/lexer/token.js +69 -0
- package/dist/src/lexer/token.js.map +1 -1
- package/dist/src/parser/context.js +4 -16
- package/dist/src/parser/context.js.map +1 -1
- package/dist/src/parser/declarations.d.ts +2 -0
- package/dist/src/parser/declarations.js +146 -33
- package/dist/src/parser/declarations.js.map +1 -1
- package/dist/src/parser/expressions.js +20 -3
- package/dist/src/parser/expressions.js.map +1 -1
- package/dist/src/parser/helpers.js +2 -0
- package/dist/src/parser/helpers.js.map +1 -1
- package/dist/src/parser/modules.js +7 -2
- package/dist/src/parser/modules.js.map +1 -1
- package/dist/src/parser/statements.js +28 -3
- package/dist/src/parser/statements.js.map +1 -1
- package/dist/src/parser/types.js +5 -0
- package/dist/src/parser/types.js.map +1 -1
- package/dist/tests/codegen/llvm.test.js +16 -0
- package/dist/tests/codegen/llvm.test.js.map +1 -1
- package/dist/tests/driver/compiler.test.js +13 -1
- package/dist/tests/driver/compiler.test.js.map +1 -1
- package/dist/tests/e2e/compile.test.js +57 -0
- package/dist/tests/e2e/compile.test.js.map +1 -1
- package/dist/tests/parser/parser.test.js +53 -0
- package/dist/tests/parser/parser.test.js.map +1 -1
- package/package.json +1 -1
- package/runtime/ext_node/child_process/child_process.c +213 -0
- package/runtime/ext_node/crypto/crypto.c +177 -0
- package/runtime/ext_node/process/process.c +37 -3
- package/runtime/ext_node/url/url.c +85 -0
- package/runtime/rt.h +20 -0
- package/runtime/rt_internal.h +11 -0
- package/runtime/xt_builtins.c +23 -0
- package/runtime/xt_containers.c +136 -10
- package/runtime/xt_io.c +53 -0
- package/runtime/xt_regex.h +16 -6
- package/runtime/xt_stdlib.c +11 -2
- package/runtime/xt_stdlib2.c +250 -13
- package/runtime/xt_values.c +2 -1
- package/src/ast/declarations.ts +26 -1
- package/src/ast/expressions.ts +7 -2
- package/src/ast/kinds.ts +5 -0
- package/src/ast/statements.ts +2 -1
- package/src/binder/binder.ts +75 -9
- package/src/cli/main.ts +2 -3
- package/src/codegen/generator/calls.ts +59 -16
- package/src/codegen/generator/context.ts +1 -1
- package/src/codegen/generator/expressions.ts +39 -3
- package/src/codegen/generator/module.ts +79 -7
- package/src/codegen/generator/state.ts +16 -0
- package/src/codegen/generator/statements.ts +139 -11
- package/src/codegen/generator/tables.ts +14 -0
- package/src/codegen/values.ts +85 -16
- package/src/diagnostics/source.ts +12 -7
- package/src/driver/compiler.ts +44 -2
- package/src/driver/modules.ts +28 -3
- package/src/extensions/node/child_process/index.ts +24 -0
- package/src/extensions/node/crypto/index.ts +23 -0
- package/src/extensions/node/index.ts +6 -0
- package/src/extensions/node/module.ts +13 -1
- package/src/extensions/node/url/index.ts +26 -0
- package/src/lexer/scanner.ts +4 -4
- package/src/lexer/token.ts +73 -0
- package/src/parser/context.ts +4 -15
- package/src/parser/declarations.ts +140 -29
- package/src/parser/expressions.ts +20 -4
- package/src/parser/helpers.ts +2 -0
- package/src/parser/modules.ts +7 -2
- package/src/parser/statements.ts +27 -3
- package/src/parser/types.ts +5 -0
package/src/ast/declarations.ts
CHANGED
|
@@ -14,7 +14,7 @@ import type { TypeElement } from "./types.js";
|
|
|
14
14
|
|
|
15
15
|
export interface Parameter extends Node {
|
|
16
16
|
readonly kind: SyntaxKind.Parameter;
|
|
17
|
-
readonly name:
|
|
17
|
+
readonly name: BindingName;
|
|
18
18
|
readonly modifiers: Modifier[];
|
|
19
19
|
readonly dotDotDotToken: boolean;
|
|
20
20
|
readonly questionToken: boolean;
|
|
@@ -22,6 +22,29 @@ export interface Parameter extends Node {
|
|
|
22
22
|
readonly initializer?: Expression;
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
+
// -- binding patterns (destructuring) --------------------------------------
|
|
26
|
+
|
|
27
|
+
export type BindingName = Identifier | ArrayBindingPattern | ObjectBindingPattern;
|
|
28
|
+
|
|
29
|
+
export interface BindingElement extends Node {
|
|
30
|
+
readonly kind: SyntaxKind.BindingElement;
|
|
31
|
+
readonly name: BindingName;
|
|
32
|
+
/** For `{ a: b }` the `a`; absent for shorthand and array patterns. */
|
|
33
|
+
readonly propertyName?: PropertyName;
|
|
34
|
+
readonly dotDotDotToken: boolean;
|
|
35
|
+
readonly initializer?: Expression;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface ArrayBindingPattern extends Node {
|
|
39
|
+
readonly kind: SyntaxKind.ArrayBindingPattern;
|
|
40
|
+
readonly elements: (BindingElement | undefined)[];
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export interface ObjectBindingPattern extends Node {
|
|
44
|
+
readonly kind: SyntaxKind.ObjectBindingPattern;
|
|
45
|
+
readonly elements: BindingElement[];
|
|
46
|
+
}
|
|
47
|
+
|
|
25
48
|
export interface TypeParameterDeclaration extends Node {
|
|
26
49
|
readonly kind: SyntaxKind.TypeParameterDeclaration;
|
|
27
50
|
readonly name: Identifier;
|
|
@@ -74,6 +97,8 @@ export interface MethodDeclaration extends Node {
|
|
|
74
97
|
readonly body?: Block;
|
|
75
98
|
readonly flags: NodeFlags;
|
|
76
99
|
readonly optional: boolean;
|
|
100
|
+
/** Present for `get x()` / `set x(v)` accessors. */
|
|
101
|
+
readonly accessor?: "get" | "set";
|
|
77
102
|
}
|
|
78
103
|
|
|
79
104
|
export interface ConstructorDeclaration extends Node {
|
package/src/ast/expressions.ts
CHANGED
|
@@ -40,7 +40,7 @@ export interface NumericLiteral extends Node {
|
|
|
40
40
|
export interface BigIntLiteral extends Node {
|
|
41
41
|
readonly kind: SyntaxKind.BigIntLiteral;
|
|
42
42
|
readonly text: string;
|
|
43
|
-
readonly value:
|
|
43
|
+
readonly value: number;
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
export interface StringLiteral extends Node {
|
|
@@ -127,7 +127,12 @@ export interface ObjectLiteralExpression extends Node {
|
|
|
127
127
|
readonly properties: ObjectLiteralElementLike[];
|
|
128
128
|
}
|
|
129
129
|
|
|
130
|
-
export type PropertyName = Identifier | StringLiteral | NumericLiteral | PrivateIdentifier;
|
|
130
|
+
export type PropertyName = Identifier | StringLiteral | NumericLiteral | PrivateIdentifier | ComputedPropertyName;
|
|
131
|
+
|
|
132
|
+
export interface ComputedPropertyName extends Node {
|
|
133
|
+
readonly kind: SyntaxKind.ComputedPropertyName;
|
|
134
|
+
readonly expression: Expression;
|
|
135
|
+
}
|
|
131
136
|
|
|
132
137
|
export interface FunctionExpression extends Node {
|
|
133
138
|
readonly kind: SyntaxKind.FunctionExpression;
|
package/src/ast/kinds.ts
CHANGED
|
@@ -59,6 +59,10 @@ export const enum SyntaxKind {
|
|
|
59
59
|
AwaitExpression = 43,
|
|
60
60
|
YieldExpression = 44,
|
|
61
61
|
TaggedTemplateExpression = 45,
|
|
62
|
+
ArrayBindingPattern = 46,
|
|
63
|
+
ObjectBindingPattern = 47,
|
|
64
|
+
BindingElement = 48,
|
|
65
|
+
ComputedPropertyName = 49,
|
|
62
66
|
|
|
63
67
|
// Statements
|
|
64
68
|
ExpressionStatement = 60,
|
|
@@ -173,4 +177,5 @@ export const enum ModifierKind {
|
|
|
173
177
|
Static = "static",
|
|
174
178
|
Readonly = "readonly",
|
|
175
179
|
Async = "async",
|
|
180
|
+
Const = "const",
|
|
176
181
|
}
|
package/src/ast/statements.ts
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
import { SyntaxKind } from "./kinds.js";
|
|
6
6
|
import type { Expression, Modifier, Node, Statement, TypeNode } from "./common.js";
|
|
7
7
|
import type { Identifier } from "./expressions.js";
|
|
8
|
+
import type { BindingName } from "./declarations.js";
|
|
8
9
|
|
|
9
10
|
// ---------------------------------------------------------------------------
|
|
10
11
|
// Statements
|
|
@@ -30,7 +31,7 @@ export interface DebuggerStatement extends Node {
|
|
|
30
31
|
|
|
31
32
|
export interface VariableDeclaration extends Node {
|
|
32
33
|
readonly kind: SyntaxKind.VariableDeclaration;
|
|
33
|
-
readonly name:
|
|
34
|
+
readonly name: BindingName;
|
|
34
35
|
readonly exclamation: boolean;
|
|
35
36
|
readonly type?: TypeNode;
|
|
36
37
|
readonly initializer?: Expression;
|
package/src/binder/binder.ts
CHANGED
|
@@ -13,6 +13,7 @@ import { NodeFlags, ModifierKind } from "../ast/kinds.js";
|
|
|
13
13
|
import {
|
|
14
14
|
SyntaxKind,
|
|
15
15
|
type ArrowFunction,
|
|
16
|
+
type BindingName,
|
|
16
17
|
type Block,
|
|
17
18
|
type ClassDeclaration,
|
|
18
19
|
type ClassExpression,
|
|
@@ -244,6 +245,27 @@ class Binder {
|
|
|
244
245
|
return { kind, node, parent, fn: this.current, symbols: new Map() };
|
|
245
246
|
}
|
|
246
247
|
|
|
248
|
+
/** Declare every identifier introduced by a (possibly destructured) binding. */
|
|
249
|
+
private declareBinding(
|
|
250
|
+
name: BindingName,
|
|
251
|
+
kind: SymbolKind,
|
|
252
|
+
declaration: Node,
|
|
253
|
+
scope: Scope,
|
|
254
|
+
mutable: boolean,
|
|
255
|
+
): SymbolInfo | undefined {
|
|
256
|
+
if (name.kind === SyntaxKind.Identifier) {
|
|
257
|
+
return this.declare(name.text, kind, declaration, scope, mutable);
|
|
258
|
+
}
|
|
259
|
+
let first: SymbolInfo | undefined;
|
|
260
|
+
const pattern = name as import("../ast/declarations.js").ArrayBindingPattern | import("../ast/declarations.js").ObjectBindingPattern;
|
|
261
|
+
for (const element of pattern.elements) {
|
|
262
|
+
if (!element) continue;
|
|
263
|
+
const symbol = this.declareBinding(element.name, kind, element.name, scope, mutable);
|
|
264
|
+
if (!first) first = symbol;
|
|
265
|
+
}
|
|
266
|
+
return first;
|
|
267
|
+
}
|
|
268
|
+
|
|
247
269
|
private declare(
|
|
248
270
|
name: string,
|
|
249
271
|
kind: SymbolKind,
|
|
@@ -334,7 +356,7 @@ class Binder {
|
|
|
334
356
|
? SymbolKind.Var
|
|
335
357
|
: SymbolKind.Let;
|
|
336
358
|
for (const declaration of list.declarations) {
|
|
337
|
-
this.
|
|
359
|
+
this.declareBinding(declaration.name, kind, declaration, scope, kind !== SymbolKind.Const);
|
|
338
360
|
}
|
|
339
361
|
}
|
|
340
362
|
|
|
@@ -369,9 +391,9 @@ class Binder {
|
|
|
369
391
|
const decl = node as VariableStatement;
|
|
370
392
|
if (decl.declarationList.declarationKind === "var") {
|
|
371
393
|
for (const d of decl.declarationList.declarations) {
|
|
372
|
-
const existing = fn.scope.symbols.get(d.name.text);
|
|
373
|
-
if (!existing) this.
|
|
374
|
-
else this.symbolOfDeclaration.set(d, existing);
|
|
394
|
+
const existing = d.name.kind === SyntaxKind.Identifier ? fn.scope.symbols.get(d.name.text) : undefined;
|
|
395
|
+
if (!existing) this.declareBinding(d.name, SymbolKind.Var, d, fn.scope, true);
|
|
396
|
+
else if (d.name.kind === SyntaxKind.Identifier) this.symbolOfDeclaration.set(d, existing);
|
|
375
397
|
}
|
|
376
398
|
}
|
|
377
399
|
return;
|
|
@@ -432,6 +454,35 @@ class Binder {
|
|
|
432
454
|
case SyntaxKind.Identifier:
|
|
433
455
|
this.reference(node as Identifier, scope);
|
|
434
456
|
return;
|
|
457
|
+
case SyntaxKind.PropertyAccessExpression:
|
|
458
|
+
// `obj.name` reads a property, not a variable named `name`.
|
|
459
|
+
this.bindNode((node as unknown as { expression: Expression }).expression, scope);
|
|
460
|
+
return;
|
|
461
|
+
case SyntaxKind.ElementAccessExpression: {
|
|
462
|
+
const access = node as unknown as { expression: Expression; argumentExpression: Expression };
|
|
463
|
+
this.bindNode(access.expression, scope);
|
|
464
|
+
this.bindNode(access.argumentExpression, scope);
|
|
465
|
+
return;
|
|
466
|
+
}
|
|
467
|
+
case SyntaxKind.PropertyAssignment: {
|
|
468
|
+
// `{ key: value }` / `{ key() {} }`: only the value is an expression,
|
|
469
|
+
// except a computed key (`{ [expr]: value }`) whose expression is real.
|
|
470
|
+
const property = node as unknown as { name: PropertyName; initializer: Expression };
|
|
471
|
+
if (property.name.kind === SyntaxKind.ComputedPropertyName) {
|
|
472
|
+
this.bindNode((property.name as unknown as { expression: Expression }).expression, scope);
|
|
473
|
+
}
|
|
474
|
+
this.bindNode(property.initializer, scope);
|
|
475
|
+
return;
|
|
476
|
+
}
|
|
477
|
+
case SyntaxKind.ShorthandPropertyAssignment:
|
|
478
|
+
this.reference((node as unknown as { name: Identifier }).name, scope);
|
|
479
|
+
return;
|
|
480
|
+
case SyntaxKind.LabeledStatement:
|
|
481
|
+
this.bindNode((node as unknown as { statement: Node }).statement, scope);
|
|
482
|
+
return;
|
|
483
|
+
case SyntaxKind.BreakStatement:
|
|
484
|
+
case SyntaxKind.ContinueStatement:
|
|
485
|
+
return;
|
|
435
486
|
case SyntaxKind.ThisKeyword:
|
|
436
487
|
this.current.usesThis = true;
|
|
437
488
|
return;
|
|
@@ -506,11 +557,26 @@ class Binder {
|
|
|
506
557
|
private bindVariableList(list: VariableDeclarationList, scope: Scope): void {
|
|
507
558
|
for (const declaration of list.declarations) {
|
|
508
559
|
const symbol = this.symbolOfDeclaration.get(declaration);
|
|
509
|
-
if (declaration.name
|
|
560
|
+
if (declaration.name.kind === SyntaxKind.Identifier) {
|
|
561
|
+
this.symbolOfDeclaration.set(declaration.name, symbol ?? this.symbolOfDeclaration.get(declaration) as SymbolInfo);
|
|
562
|
+
} else {
|
|
563
|
+
this.bindBindingPattern(declaration.name, scope);
|
|
564
|
+
}
|
|
510
565
|
this.bindNode(declaration.initializer, scope);
|
|
511
566
|
}
|
|
512
567
|
}
|
|
513
568
|
|
|
569
|
+
/** Bind default-value expressions inside a binding pattern. */
|
|
570
|
+
private bindBindingPattern(name: BindingName, scope: Scope): void {
|
|
571
|
+
if (name.kind === SyntaxKind.Identifier) return;
|
|
572
|
+
const pattern = name as import("../ast/declarations.js").ArrayBindingPattern | import("../ast/declarations.js").ObjectBindingPattern;
|
|
573
|
+
for (const element of pattern.elements) {
|
|
574
|
+
if (!element) continue;
|
|
575
|
+
if (element.initializer) this.bindNode(element.initializer, scope);
|
|
576
|
+
this.bindBindingPattern(element.name, scope);
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
|
|
514
580
|
private bindFunction(
|
|
515
581
|
node: FunctionDeclaration | FunctionExpression | ArrowFunction,
|
|
516
582
|
parentScope: Scope,
|
|
@@ -533,8 +599,8 @@ class Binder {
|
|
|
533
599
|
// Parameters live in the function scope.
|
|
534
600
|
const params: SymbolInfo[] = [];
|
|
535
601
|
for (const parameter of node.parameters) {
|
|
536
|
-
const paramSymbol = this.
|
|
537
|
-
params.push(paramSymbol);
|
|
602
|
+
const paramSymbol = this.declareBinding(parameter.name, SymbolKind.Parameter, parameter, scope, true);
|
|
603
|
+
if (paramSymbol) params.push(paramSymbol);
|
|
538
604
|
if (parameter.initializer) this.bindNode(parameter.initializer, scope);
|
|
539
605
|
}
|
|
540
606
|
(fn as { params: SymbolInfo[] }).params = params;
|
|
@@ -651,8 +717,8 @@ class Binder {
|
|
|
651
717
|
|
|
652
718
|
const params: SymbolInfo[] = [];
|
|
653
719
|
for (const parameter of parameters) {
|
|
654
|
-
const paramSymbol = this.
|
|
655
|
-
params.push(paramSymbol);
|
|
720
|
+
const paramSymbol = this.declareBinding(parameter.name, SymbolKind.Parameter, parameter, scope, true);
|
|
721
|
+
if (paramSymbol) params.push(paramSymbol);
|
|
656
722
|
if (parameter.initializer) this.bindNode(parameter.initializer, scope);
|
|
657
723
|
}
|
|
658
724
|
(fn as { params: SymbolInfo[] }).params = params;
|
package/src/cli/main.ts
CHANGED
|
@@ -16,7 +16,7 @@ import { resolve } from "node:path";
|
|
|
16
16
|
import { pathToFileURL } from "node:url";
|
|
17
17
|
import { DiagnosticBag, formatDiagnostic, type Diagnostic } from "../diagnostics/diagnostic.js";
|
|
18
18
|
import { SourceFile } from "../diagnostics/source.js";
|
|
19
|
-
import { build,
|
|
19
|
+
import { build, compileEntry, COMPILER_VERSION, type EmitKind } from "../driver/compiler.js";
|
|
20
20
|
import { createDefaultRegistry, type ExtensionRegistry } from "../extensions/registry.js";
|
|
21
21
|
import { nodeExtension } from "../extensions/node/index.js";
|
|
22
22
|
|
|
@@ -152,9 +152,8 @@ export function run(argv: readonly string[], io: CliIo = defaultIo): number {
|
|
|
152
152
|
io.stderr("xbintsc: emit requires a source file\n");
|
|
153
153
|
return 1;
|
|
154
154
|
}
|
|
155
|
-
const source = readFileSync(resolve(entry), "utf8");
|
|
156
155
|
const registry = buildRegistry(args.flags);
|
|
157
|
-
const { ir, diagnostics } =
|
|
156
|
+
const { ir, diagnostics } = compileEntry(entry, registry);
|
|
158
157
|
if (diagnostics.some((d) => d.category === "error")) {
|
|
159
158
|
printDiagnostics(diagnostics, entry, io);
|
|
160
159
|
return 1;
|
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
type Identifier,
|
|
15
15
|
type ObjectLiteralExpression,
|
|
16
16
|
type PropertyAccessExpression,
|
|
17
|
+
type SpreadElement,
|
|
17
18
|
} from "../../ast/nodes.js";
|
|
18
19
|
import { SymbolKind, type FunctionInfo } from "../../binder/binder.js";
|
|
19
20
|
import type { ModuleExport } from "../../extensions/registry.js";
|
|
@@ -35,7 +36,7 @@ export interface CallMethods {
|
|
|
35
36
|
emitCall(this: Generator, node: CallExpression): string;
|
|
36
37
|
tryEmitBuiltinCall(this: Generator, node: CallExpression, callee: PropertyAccessExpression): string | undefined;
|
|
37
38
|
runtimeCall(this: Generator, name: string, args: readonly string[]): string;
|
|
38
|
-
emitArguments(this: Generator, args: readonly Expression[]): { argc:
|
|
39
|
+
emitArguments(this: Generator, args: readonly Expression[]): { argc: string; ptr: string };
|
|
39
40
|
emitDelete(this: Generator, node: DeleteExpression): string;
|
|
40
41
|
emitPropertyAccess(this: Generator, node: PropertyAccessExpression): string;
|
|
41
42
|
emitElementAccess(this: Generator, node: ElementAccessExpression): string;
|
|
@@ -262,17 +263,38 @@ export const callMethods: CallMethods = {
|
|
|
262
263
|
return result;
|
|
263
264
|
},
|
|
264
265
|
|
|
265
|
-
emitArguments(args: readonly Expression[]): { argc:
|
|
266
|
-
if (args.length === 0) return { argc: 0, ptr: "null" };
|
|
267
|
-
const
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
266
|
+
emitArguments(args: readonly Expression[]): { argc: string; ptr: string } {
|
|
267
|
+
if (args.length === 0) return { argc: "0", ptr: "null" };
|
|
268
|
+
const hasSpread = args.some((element) => element.kind === SyntaxKind.SpreadElement);
|
|
269
|
+
if (!hasSpread) {
|
|
270
|
+
const ptr = `%args${this.current.allocas.length}`;
|
|
271
|
+
this.current.allocas.push(`${ptr} = alloca i64, i32 ${args.length}`);
|
|
272
|
+
for (let index = 0; index < args.length; index++) {
|
|
273
|
+
const value = this.emitExpression(args[index]!);
|
|
274
|
+
const slot = this.reg();
|
|
275
|
+
this.emit(` ${slot} = getelementptr i64, i64* ${ptr}, i32 ${index}`);
|
|
276
|
+
this.emit(` store i64 ${value}, i64* ${slot}`);
|
|
277
|
+
}
|
|
278
|
+
return { argc: String(args.length), ptr };
|
|
279
|
+
}
|
|
280
|
+
// At least one `...spread`: accumulate the argument list in a runtime
|
|
281
|
+
// array, which grows to whatever length the spread produces.
|
|
282
|
+
const array = this.reg();
|
|
283
|
+
this.emit(` ${array} = call i64 @xt_array_new(i32 0, i64* null)`);
|
|
284
|
+
for (const element of args) {
|
|
285
|
+
if (element.kind === SyntaxKind.SpreadElement) {
|
|
286
|
+
const value = this.emitExpression((element as SpreadElement).expression);
|
|
287
|
+
this.emit(` call i64 @xt_array_spread(i64 ${array}, i64 ${value})`);
|
|
288
|
+
} else {
|
|
289
|
+
const value = this.emitExpression(element);
|
|
290
|
+
this.emit(` call i64 @xt_array_push(i64 ${array}, i64 ${value})`);
|
|
291
|
+
}
|
|
274
292
|
}
|
|
275
|
-
|
|
293
|
+
const argc = this.reg();
|
|
294
|
+
this.emit(` ${argc} = call i32 @xt_array_size(i64 ${array})`);
|
|
295
|
+
const ptr = this.reg();
|
|
296
|
+
this.emit(` ${ptr} = call i64* @xt_array_items(i64 ${array})`);
|
|
297
|
+
return { argc, ptr };
|
|
276
298
|
},
|
|
277
299
|
|
|
278
300
|
emitDelete(node: DeleteExpression): string {
|
|
@@ -398,14 +420,15 @@ export const callMethods: CallMethods = {
|
|
|
398
420
|
this.emit(` ${result} = call i64 @xt_array_new(i32 ${args.argc}, i64* ${args.ptr})`);
|
|
399
421
|
return result;
|
|
400
422
|
}
|
|
401
|
-
|
|
423
|
+
const array = this.reg();
|
|
424
|
+
this.emit(` ${array} = call i64 @xt_array_new(i32 0, i64* null)`);
|
|
402
425
|
for (const element of node.elements) {
|
|
403
426
|
if (element.kind === SyntaxKind.SpreadElement) {
|
|
404
427
|
const spread = this.emitExpression((element as { expression: Expression }).expression);
|
|
405
|
-
|
|
428
|
+
this.emit(` call i64 @xt_array_spread(i64 ${array}, i64 ${spread})`);
|
|
406
429
|
} else {
|
|
407
430
|
const value = this.emitExpression(element);
|
|
408
|
-
|
|
431
|
+
this.emit(` call i64 @xt_array_push(i64 ${array}, i64 ${value})`);
|
|
409
432
|
}
|
|
410
433
|
}
|
|
411
434
|
return array;
|
|
@@ -416,8 +439,15 @@ export const callMethods: CallMethods = {
|
|
|
416
439
|
this.emit(` ${object} = call i64 @xt_object_new()`);
|
|
417
440
|
for (const property of node.properties) {
|
|
418
441
|
if (property.kind === SyntaxKind.PropertyAssignment) {
|
|
419
|
-
const
|
|
420
|
-
|
|
442
|
+
const nameNode = property.name;
|
|
443
|
+
let key: string;
|
|
444
|
+
if (nameNode.kind === SyntaxKind.ComputedPropertyName) {
|
|
445
|
+
const keyValue = this.emitExpression((nameNode as { expression: Expression }).expression);
|
|
446
|
+
key = this.reg();
|
|
447
|
+
this.emit(` ${key} = call i64 @xt_to_string(i64 ${keyValue})`);
|
|
448
|
+
} else {
|
|
449
|
+
key = this.stringValue(propertyNameText(nameNode));
|
|
450
|
+
}
|
|
421
451
|
const value = this.emitExpression(property.initializer);
|
|
422
452
|
this.emit(` call i64 @xt_set(i64 ${object}, i64 ${key}, i64 ${value})`);
|
|
423
453
|
} else if (property.kind === SyntaxKind.ShorthandPropertyAssignment) {
|
|
@@ -482,6 +512,19 @@ export const callMethods: CallMethods = {
|
|
|
482
512
|
|
|
483
513
|
emitSuperConstructor(node: CallExpression): string {
|
|
484
514
|
const thisValue = this.emitThis();
|
|
515
|
+
const classInfo = this.current.fn.classInfo;
|
|
516
|
+
const parent = classInfo?.parentExpression;
|
|
517
|
+
const unboundBuiltin =
|
|
518
|
+
parent !== undefined &&
|
|
519
|
+
parent.kind === SyntaxKind.Identifier &&
|
|
520
|
+
(parent as Identifier).text === "Error" &&
|
|
521
|
+
!this.binding.symbolOfIdentifier.get(parent as Identifier);
|
|
522
|
+
if (unboundBuiltin) {
|
|
523
|
+
const args = this.emitArguments(node.arguments);
|
|
524
|
+
const result = this.reg();
|
|
525
|
+
this.emit(` ${result} = call i64 @xt_error_init(i64 ${thisValue}, i32 ${args.argc}, i64* ${args.ptr})`);
|
|
526
|
+
return result;
|
|
527
|
+
}
|
|
485
528
|
const proto = this.reg();
|
|
486
529
|
this.emit(` ${proto} = call i64 @xt_object_get_prototype(i64 ${thisValue})`);
|
|
487
530
|
const parentProto = this.reg();
|
|
@@ -33,7 +33,7 @@ import {
|
|
|
33
33
|
import { SymbolKind, type SymbolInfo } from "../../binder/binder.js";
|
|
34
34
|
import { DiagnosticCode } from "../../diagnostics/diagnostic.js";
|
|
35
35
|
import { i64, numberLiteral, XT_FALSE, XT_NULL, XT_TRUE, XT_UNDEFINED } from "../values.js";
|
|
36
|
-
import { BINARY_RUNTIME, compoundToBinary, isAssignmentOperator, CTOR_FUNCTIONS } from "./tables.js";
|
|
36
|
+
import { BINARY_RUNTIME, compoundToBinary, isAssignmentOperator, BUILTIN_FUNCTION_VALUES, CTOR_FUNCTIONS } from "./tables.js";
|
|
37
37
|
import type { Generator } from "./generator.js";
|
|
38
38
|
|
|
39
39
|
export interface ExpressionMethods {
|
|
@@ -64,11 +64,27 @@ export const expressionMethods: ExpressionMethods = {
|
|
|
64
64
|
return numberLiteral(value);
|
|
65
65
|
}
|
|
66
66
|
case SyntaxKind.BigIntLiteral:
|
|
67
|
-
return numberLiteral(
|
|
67
|
+
return numberLiteral((node as { value: number }).value);
|
|
68
68
|
case SyntaxKind.StringLiteral:
|
|
69
69
|
return this.stringValue((node as { value: string }).value);
|
|
70
70
|
case SyntaxKind.NoSubstitutionTemplateLiteral:
|
|
71
71
|
return this.stringValue((node as { value: string }).value);
|
|
72
|
+
case SyntaxKind.RegularExpressionLiteral: {
|
|
73
|
+
const regex = node as { pattern: string; flags: string };
|
|
74
|
+
const pattern = this.stringValue(regex.pattern);
|
|
75
|
+
const flags = this.stringValue(regex.flags);
|
|
76
|
+
const ptr = `%regex${this.current.allocas.length}`;
|
|
77
|
+
this.current.allocas.push(`${ptr} = alloca i64, i32 2`);
|
|
78
|
+
const slot0 = this.reg();
|
|
79
|
+
this.emit(` ${slot0} = getelementptr i64, i64* ${ptr}, i32 0`);
|
|
80
|
+
this.emit(` store i64 ${pattern}, i64* ${slot0}`);
|
|
81
|
+
const slot1 = this.reg();
|
|
82
|
+
this.emit(` ${slot1} = getelementptr i64, i64* ${ptr}, i32 1`);
|
|
83
|
+
this.emit(` store i64 ${flags}, i64* ${slot1}`);
|
|
84
|
+
const result = this.reg();
|
|
85
|
+
this.emit(` ${result} = call i64 @xt_regexp_ctor(i32 2, i64* ${ptr})`);
|
|
86
|
+
return result;
|
|
87
|
+
}
|
|
72
88
|
case SyntaxKind.TemplateLiteral:
|
|
73
89
|
return this.emitTemplate(node as TemplateLiteral);
|
|
74
90
|
case SyntaxKind.TrueKeyword:
|
|
@@ -87,6 +103,15 @@ export const expressionMethods: ExpressionMethods = {
|
|
|
87
103
|
return this.emitExpression((node as { expression: Expression }).expression);
|
|
88
104
|
case SyntaxKind.DeleteExpression:
|
|
89
105
|
return this.emitDelete(node as DeleteExpression);
|
|
106
|
+
case SyntaxKind.TypeOfExpression: {
|
|
107
|
+
const operand = this.emitExpression((node as { expression: Expression }).expression);
|
|
108
|
+
const result = this.reg();
|
|
109
|
+
this.emit(` ${result} = call i64 @xt_typeof(i64 ${operand})`);
|
|
110
|
+
return result;
|
|
111
|
+
}
|
|
112
|
+
case SyntaxKind.VoidExpression:
|
|
113
|
+
this.emitExpression((node as { expression: Expression }).expression);
|
|
114
|
+
return i64(XT_UNDEFINED);
|
|
90
115
|
case SyntaxKind.ThisKeyword:
|
|
91
116
|
return this.emitThis();
|
|
92
117
|
case SyntaxKind.NewExpression:
|
|
@@ -172,7 +197,17 @@ export const expressionMethods: ExpressionMethods = {
|
|
|
172
197
|
this.emit(` ${rest} = call i64 @xt_rest_args(i32 ${argc}, i64* ${argv}, i32 0)`);
|
|
173
198
|
return rest;
|
|
174
199
|
}
|
|
175
|
-
default:
|
|
200
|
+
default: {
|
|
201
|
+
const builtinValue = BUILTIN_FUNCTION_VALUES[identifier.text];
|
|
202
|
+
if (builtinValue) {
|
|
203
|
+
// A global like `Boolean` used as a value (`arr.filter(Boolean)`):
|
|
204
|
+
// wrap its runtime trampoline in a closure object.
|
|
205
|
+
const cast = this.reg();
|
|
206
|
+
this.emit(` ${cast} = bitcast i64 (i64, i64, i32, i64*)* @${builtinValue} to i8*`);
|
|
207
|
+
const closure = this.reg();
|
|
208
|
+
this.emit(` ${closure} = call i64 @xt_closure_new(i8* ${cast}, i32 0, i64* null)`);
|
|
209
|
+
return closure;
|
|
210
|
+
}
|
|
176
211
|
this.diagnostics.error(
|
|
177
212
|
DiagnosticCode.CannotFindName,
|
|
178
213
|
`Cannot find name '${identifier.text}'`,
|
|
@@ -180,6 +215,7 @@ export const expressionMethods: ExpressionMethods = {
|
|
|
180
215
|
this.sourceFile.fileName,
|
|
181
216
|
);
|
|
182
217
|
return i64(XT_UNDEFINED);
|
|
218
|
+
}
|
|
183
219
|
}
|
|
184
220
|
},
|
|
185
221
|
|
|
@@ -4,18 +4,32 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import {
|
|
7
|
+
ModifierKind,
|
|
7
8
|
SyntaxKind,
|
|
8
9
|
type ArrowFunction,
|
|
9
10
|
type Block,
|
|
10
11
|
type Expression,
|
|
12
|
+
type Identifier,
|
|
11
13
|
type Parameter,
|
|
12
14
|
} from "../../ast/nodes.js";
|
|
13
15
|
import type { ClassInfo, FunctionInfo, SymbolInfo } from "../../binder/binder.js";
|
|
14
16
|
import { SymbolKind } from "../../binder/binder.js";
|
|
15
17
|
import { i64, XT_UNDEFINED } from "../values.js";
|
|
16
18
|
import { RUNTIME_DECLARATIONS, type FunctionState } from "./state.js";
|
|
19
|
+
import { propertyNameText } from "./tables.js";
|
|
17
20
|
import type { Generator } from "./generator.js";
|
|
18
21
|
|
|
22
|
+
/** Accessibility/`readonly` parameter modifiers make a constructor parameter a property. */
|
|
23
|
+
function isParameterProperty(parameter: Parameter): boolean {
|
|
24
|
+
return parameter.modifiers.some(
|
|
25
|
+
(modifier) =>
|
|
26
|
+
modifier.modifierKind === ModifierKind.Public ||
|
|
27
|
+
modifier.modifierKind === ModifierKind.Private ||
|
|
28
|
+
modifier.modifierKind === ModifierKind.Protected ||
|
|
29
|
+
modifier.modifierKind === ModifierKind.Readonly,
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
|
|
19
33
|
export interface ModuleMethods {
|
|
20
34
|
run(this: Generator): string;
|
|
21
35
|
emitFunction(this: Generator, fn: FunctionInfo): void;
|
|
@@ -40,8 +54,11 @@ export const moduleMethods: ModuleMethods = {
|
|
|
40
54
|
const moduleScope = this.binding.scopes.get(this.sourceFile);
|
|
41
55
|
if (moduleScope) {
|
|
42
56
|
for (const symbol of moduleScope.symbols.values()) {
|
|
43
|
-
const isVariable =
|
|
44
|
-
|
|
57
|
+
const isVariable =
|
|
58
|
+
symbol.kind === SymbolKind.Var || symbol.kind === SymbolKind.Let || symbol.kind === SymbolKind.Const;
|
|
59
|
+
const isEnum = symbol.kind === SymbolKind.Enum;
|
|
60
|
+
if ((!isVariable && !isEnum) || !symbol.fn?.isModule) continue;
|
|
61
|
+
if (isVariable && !symbol.boxed) continue;
|
|
45
62
|
const globalName = `@g.${symbol.id}`;
|
|
46
63
|
this.moduleGlobals.set(symbol.id, globalName);
|
|
47
64
|
this.globals.push(`${globalName} = internal global i64 ${i64(XT_UNDEFINED)}`);
|
|
@@ -116,6 +133,31 @@ export const moduleMethods: ModuleMethods = {
|
|
|
116
133
|
this.emit(` store i64 ${inherited}, i64* %saved.this`);
|
|
117
134
|
}
|
|
118
135
|
|
|
136
|
+
// A derived class with no explicit constructor gets an implicit one that
|
|
137
|
+
// forwards every argument to the parent constructor (`super(...arguments)`).
|
|
138
|
+
if (fn.isConstructor && fn.classInfo?.parentExpression) {
|
|
139
|
+
const explicitBody = (fn.node as { body?: Block }).body;
|
|
140
|
+
const parent = fn.classInfo.parentExpression;
|
|
141
|
+
const unboundBuiltin =
|
|
142
|
+
parent.kind === SyntaxKind.Identifier &&
|
|
143
|
+
(parent as Identifier).text === "Error" &&
|
|
144
|
+
!this.binding.symbolOfIdentifier.get(parent as Identifier);
|
|
145
|
+
if (!explicitBody && !unboundBuiltin) {
|
|
146
|
+
const parentValue = this.emitExpression(parent);
|
|
147
|
+
const parentProto = this.reg();
|
|
148
|
+
this.emit(` ${parentProto} = call i64 @xt_function_get_prototype(i64 ${parentValue})`);
|
|
149
|
+
const ctorKey = this.stringValue("__ctor");
|
|
150
|
+
const parentCtor = this.reg();
|
|
151
|
+
this.emit(` ${parentCtor} = call i64 @xt_get(i64 ${parentProto}, i64 ${ctorKey})`);
|
|
152
|
+
const superThis = this.emitThis();
|
|
153
|
+
this.emit(` call i64 @xt_call_with_this(i64 ${parentCtor}, i64 ${superThis}, i32 %argc, i64* %argv)`);
|
|
154
|
+
} else if (!explicitBody && unboundBuiltin) {
|
|
155
|
+
// `extends Error` with no explicit constructor: initialise message/name.
|
|
156
|
+
const superThis = this.emitThis();
|
|
157
|
+
this.emit(` call i64 @xt_error_init(i64 ${superThis}, i32 %argc, i64* %argv)`);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
119
161
|
// Instance field initializers run before the constructor body.
|
|
120
162
|
if (fn.isConstructor && fn.classInfo) {
|
|
121
163
|
const thisValue = this.emitThis();
|
|
@@ -127,6 +169,20 @@ export const moduleMethods: ModuleMethods = {
|
|
|
127
169
|
}
|
|
128
170
|
}
|
|
129
171
|
|
|
172
|
+
// Constructor parameter properties (`constructor(private readonly x: T) {}`)
|
|
173
|
+
// copy the incoming argument onto `this`.
|
|
174
|
+
if (fn.isConstructor) {
|
|
175
|
+
const thisValue = this.emitThis();
|
|
176
|
+
for (let index = 0; index < fn.params.length; index++) {
|
|
177
|
+
const parameter = parameterNodes[index];
|
|
178
|
+
if (!parameter || !isParameterProperty(parameter)) continue;
|
|
179
|
+
const symbol = fn.params[index]!;
|
|
180
|
+
const key = this.stringValue(propertyNameText(parameter.name));
|
|
181
|
+
const value = this.readSlot(symbol);
|
|
182
|
+
this.emit(` call i64 @xt_set(i64 ${thisValue}, i64 ${key}, i64 ${value})`);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
130
186
|
// Body.
|
|
131
187
|
if (fn.node.kind === SyntaxKind.SourceFile) {
|
|
132
188
|
this.emitStatements(this.sourceFile.statements);
|
|
@@ -199,15 +255,31 @@ export const moduleMethods: ModuleMethods = {
|
|
|
199
255
|
const proto = this.reg();
|
|
200
256
|
this.emit(` ${proto} = call i64 @xt_object_new()`);
|
|
201
257
|
if (classInfo.parentExpression) {
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
258
|
+
// `extends Error` (and other host builtins) have no runtime class value;
|
|
259
|
+
// the subclass still works, it simply does not inherit a prototype.
|
|
260
|
+
const parent = classInfo.parentExpression;
|
|
261
|
+
const unboundBuiltin =
|
|
262
|
+
parent.kind === SyntaxKind.Identifier &&
|
|
263
|
+
(parent as Identifier).text === "Error" &&
|
|
264
|
+
!this.binding.symbolOfIdentifier.get(parent as Identifier);
|
|
265
|
+
if (!unboundBuiltin) {
|
|
266
|
+
const parentValue = this.emitExpression(parent);
|
|
267
|
+
const parentProto = this.reg();
|
|
268
|
+
this.emit(` ${parentProto} = call i64 @xt_function_get_prototype(i64 ${parentValue})`);
|
|
269
|
+
this.emit(` call i64 @xt_object_set_prototype(i64 ${proto}, i64 ${parentProto})`);
|
|
270
|
+
}
|
|
206
271
|
}
|
|
207
272
|
for (const method of classInfo.methods) {
|
|
208
273
|
const fnValue = this.emitClosureValue(method);
|
|
209
274
|
const key = this.stringValue(method.name);
|
|
210
|
-
|
|
275
|
+
const accessor = (method.node as { accessor?: "get" | "set" }).accessor;
|
|
276
|
+
if (accessor === "get") {
|
|
277
|
+
this.emit(` call i64 @xt_object_define_getter(i64 ${proto}, i64 ${key}, i64 ${fnValue})`);
|
|
278
|
+
} else if (accessor === "set") {
|
|
279
|
+
this.emit(` call i64 @xt_object_define_setter(i64 ${proto}, i64 ${key}, i64 ${fnValue})`);
|
|
280
|
+
} else {
|
|
281
|
+
this.emit(` call i64 @xt_set(i64 ${proto}, i64 ${key}, i64 ${fnValue})`);
|
|
282
|
+
}
|
|
211
283
|
}
|
|
212
284
|
const ctor = this.emitClosureValue(classInfo.ctor!);
|
|
213
285
|
this.emit(` call i64 @xt_function_set_prototype(i64 ${ctor}, i64 ${proto})`);
|
|
@@ -68,6 +68,8 @@ export const RUNTIME_DECLARATIONS: readonly string[] = [
|
|
|
68
68
|
"declare i64 @xt_object_new_with_proto(i64)",
|
|
69
69
|
"declare i64 @xt_object_get_prototype(i64)",
|
|
70
70
|
"declare i64 @xt_object_set_prototype(i64, i64)",
|
|
71
|
+
"declare i64 @xt_object_define_getter(i64, i64, i64)",
|
|
72
|
+
"declare i64 @xt_object_define_setter(i64, i64, i64)",
|
|
71
73
|
"declare i64 @xt_await(i64)",
|
|
72
74
|
"declare void @xt_drain_microtasks()",
|
|
73
75
|
"declare void @xt_run_event_loop()",
|
|
@@ -101,6 +103,8 @@ export const RUNTIME_DECLARATIONS: readonly string[] = [
|
|
|
101
103
|
"declare i64 @xt_set_ctor(i32, i64*)",
|
|
102
104
|
"declare i64 @xt_date_ctor(i32, i64*)",
|
|
103
105
|
"declare i64 @xt_regexp_ctor(i32, i64*)",
|
|
106
|
+
"declare i64 @xt_error_ctor(i32, i64*)",
|
|
107
|
+
"declare i64 @xt_error_init(i64, i32, i64*)",
|
|
104
108
|
"declare i64 @xt_json_parse(i32, i64*)",
|
|
105
109
|
"declare i64 @xt_json_stringify(i32, i64*)",
|
|
106
110
|
"declare i64 @xt_object_from_entries(i64)",
|
|
@@ -168,10 +172,22 @@ export const RUNTIME_DECLARATIONS: readonly string[] = [
|
|
|
168
172
|
"declare i64 @xt_delete(i64, i64)",
|
|
169
173
|
"declare i64 @xt_rest_args(i32, i64*, i32)",
|
|
170
174
|
"declare void @xt_set_program_args(i32, i8**)",
|
|
175
|
+
"declare i64 @xt_import_meta(i64)",
|
|
171
176
|
"declare i64 @xt_array_new(i32, i64*)",
|
|
172
177
|
"declare i64 @xt_array_push(i64, i64)",
|
|
173
178
|
"declare i64 @xt_array_length(i64)",
|
|
174
179
|
"declare i64 @xt_array_spread(i64, i64)",
|
|
180
|
+
"declare i64 @xt_iter_length(i64)",
|
|
181
|
+
"declare i64 @xt_iter_value(i64, i64)",
|
|
182
|
+
"declare i32 @xt_array_size(i64)",
|
|
183
|
+
"declare i64* @xt_array_items(i64)",
|
|
184
|
+
"declare i64 @xt_builtin_value_parseInt(i64, i64, i32, i64*)",
|
|
185
|
+
"declare i64 @xt_builtin_value_parseFloat(i64, i64, i32, i64*)",
|
|
186
|
+
"declare i64 @xt_builtin_value_isNaN(i64, i64, i32, i64*)",
|
|
187
|
+
"declare i64 @xt_builtin_value_isFinite(i64, i64, i32, i64*)",
|
|
188
|
+
"declare i64 @xt_builtin_value_number(i64, i64, i32, i64*)",
|
|
189
|
+
"declare i64 @xt_builtin_value_string(i64, i64, i32, i64*)",
|
|
190
|
+
"declare i64 @xt_builtin_value_boolean(i64, i64, i32, i64*)",
|
|
175
191
|
"declare i64 @xt_get(i64, i64)",
|
|
176
192
|
"declare i64 @xt_set(i64, i64, i64)",
|
|
177
193
|
"declare i64 @xt_box_new(i64)",
|