xbintsc 0.2.8 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +17 -2
- package/README.zh-CN.md +16 -2
- package/bin/xbintsc.js +49 -10
- package/dist/src/ast/expressions.d.ts +2 -0
- package/dist/src/binder/binder.d.ts +24 -98
- package/dist/src/binder/binder.js +13 -559
- package/dist/src/binder/binder.js.map +1 -1
- package/dist/src/binder/declarations.d.ts +16 -0
- package/dist/src/binder/declarations.js +168 -0
- package/dist/src/binder/declarations.js.map +1 -0
- package/dist/src/binder/helpers.d.ts +11 -0
- package/dist/src/binder/helpers.js +46 -0
- package/dist/src/binder/helpers.js.map +1 -0
- package/dist/src/binder/references.d.ts +21 -0
- package/dist/src/binder/references.js +349 -0
- package/dist/src/binder/references.js.map +1 -0
- package/dist/src/binder/types.d.ts +114 -0
- package/dist/src/binder/types.js +27 -0
- package/dist/src/binder/types.js.map +1 -0
- package/dist/src/cli/main.d.ts +1 -0
- package/dist/src/cli/main.js +40 -0
- package/dist/src/cli/main.js.map +1 -1
- package/dist/src/codegen/generator/calls/access.d.ts +13 -0
- package/dist/src/codegen/generator/calls/access.js +115 -0
- package/dist/src/codegen/generator/calls/access.js.map +1 -0
- package/dist/src/codegen/generator/calls/closures.d.ts +11 -0
- package/dist/src/codegen/generator/calls/closures.js +50 -0
- package/dist/src/codegen/generator/calls/closures.js.map +1 -0
- package/dist/src/codegen/generator/calls/invocation.d.ts +18 -0
- package/dist/src/codegen/generator/calls/invocation.js +242 -0
- package/dist/src/codegen/generator/calls/invocation.js.map +1 -0
- package/dist/src/codegen/generator/calls/literals.d.ts +10 -0
- package/dist/src/codegen/generator/calls/literals.js +69 -0
- package/dist/src/codegen/generator/calls/literals.js.map +1 -0
- package/dist/src/codegen/generator/calls/super.d.ts +10 -0
- package/dist/src/codegen/generator/calls/super.js +47 -0
- package/dist/src/codegen/generator/calls/super.js.map +1 -0
- package/dist/src/codegen/generator/calls.d.ts +15 -24
- package/dist/src/codegen/generator/calls.js +15 -482
- 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/context.js +2 -2
- package/dist/src/codegen/generator/context.js.map +1 -1
- package/dist/src/codegen/generator/expressions/assignment.d.ts +13 -0
- package/dist/src/codegen/generator/expressions/assignment.js +203 -0
- package/dist/src/codegen/generator/expressions/assignment.js.map +1 -0
- package/dist/src/codegen/generator/expressions/operators.d.ts +14 -0
- package/dist/src/codegen/generator/expressions/operators.js +163 -0
- package/dist/src/codegen/generator/expressions/operators.js.map +1 -0
- package/dist/src/codegen/generator/expressions/primary.d.ts +17 -0
- package/dist/src/codegen/generator/expressions/primary.js +260 -0
- package/dist/src/codegen/generator/expressions/primary.js.map +1 -0
- package/dist/src/codegen/generator/expressions.d.ts +11 -21
- package/dist/src/codegen/generator/expressions.js +11 -494
- package/dist/src/codegen/generator/expressions.js.map +1 -1
- package/dist/src/codegen/generator/module.js +16 -4
- package/dist/src/codegen/generator/module.js.map +1 -1
- package/dist/src/codegen/generator/state.js +8 -0
- package/dist/src/codegen/generator/state.js.map +1 -1
- package/dist/src/codegen/generator/statements/control-flow.d.ts +14 -0
- package/dist/src/codegen/generator/statements/control-flow.js +199 -0
- package/dist/src/codegen/generator/statements/control-flow.js.map +1 -0
- package/dist/src/codegen/generator/statements/dispatch.d.ts +12 -0
- package/dist/src/codegen/generator/statements/dispatch.js +100 -0
- package/dist/src/codegen/generator/statements/dispatch.js.map +1 -0
- package/dist/src/codegen/generator/statements/loops.d.ts +13 -0
- package/dist/src/codegen/generator/statements/loops.js +152 -0
- package/dist/src/codegen/generator/statements/loops.js.map +1 -0
- package/dist/src/codegen/generator/statements/variables.d.ts +13 -0
- package/dist/src/codegen/generator/statements/variables.js +146 -0
- package/dist/src/codegen/generator/statements/variables.js.map +1 -0
- package/dist/src/codegen/generator/statements.d.ts +13 -21
- package/dist/src/codegen/generator/statements.js +13 -568
- package/dist/src/codegen/generator/statements.js.map +1 -1
- package/dist/src/codegen/generator/tables.js +7 -0
- package/dist/src/codegen/generator/tables.js.map +1 -1
- package/dist/src/codegen/values.d.ts +17 -17
- package/dist/src/codegen/values.js +21 -57
- package/dist/src/codegen/values.js.map +1 -1
- package/dist/src/diagnostics/diagnostic.d.ts +1 -0
- package/dist/src/diagnostics/diagnostic.js +1 -0
- package/dist/src/diagnostics/diagnostic.js.map +1 -1
- package/dist/src/diagnostics/source.d.ts +1 -1
- package/dist/src/diagnostics/source.js +7 -12
- package/dist/src/diagnostics/source.js.map +1 -1
- package/dist/src/driver/compiler.d.ts +4 -0
- package/dist/src/driver/compiler.js +51 -16
- package/dist/src/driver/compiler.js.map +1 -1
- package/dist/src/driver/index.d.ts +5 -2
- package/dist/src/driver/index.js +5 -2
- package/dist/src/driver/index.js.map +1 -1
- package/dist/src/driver/paths.d.ts +20 -0
- package/dist/src/driver/paths.js +49 -0
- package/dist/src/driver/paths.js.map +1 -1
- package/dist/src/driver/runtime-lib.d.ts +18 -0
- package/dist/src/driver/runtime-lib.js +31 -0
- package/dist/src/driver/runtime-lib.js.map +1 -0
- package/dist/src/driver/toolchain-download.d.ts +50 -0
- package/dist/src/driver/toolchain-download.js +76 -0
- package/dist/src/driver/toolchain-download.js.map +1 -0
- package/dist/src/driver/toolchain-provider.d.ts +33 -0
- package/dist/src/driver/toolchain-provider.js +71 -0
- package/dist/src/driver/toolchain-provider.js.map +1 -0
- package/dist/src/driver/toolchain.d.ts +9 -4
- package/dist/src/driver/toolchain.js +6 -10
- package/dist/src/driver/toolchain.js.map +1 -1
- package/dist/src/extensions/node/child_process/index.d.ts +4 -2
- package/dist/src/extensions/node/child_process/index.js +4 -2
- package/dist/src/extensions/node/child_process/index.js.map +1 -1
- package/dist/src/extensions/node/events/index.d.ts +10 -0
- package/dist/src/extensions/node/events/index.js +22 -0
- package/dist/src/extensions/node/events/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/querystring/index.d.ts +10 -0
- package/dist/src/extensions/node/querystring/index.js +25 -0
- package/dist/src/extensions/node/querystring/index.js.map +1 -0
- package/dist/src/extensions/node/util/index.d.ts +11 -0
- package/dist/src/extensions/node/util/index.js +41 -0
- package/dist/src/extensions/node/util/index.js.map +1 -0
- package/dist/src/extensions/registry.d.ts +6 -0
- package/dist/src/extensions/registry.js.map +1 -1
- package/dist/src/index.d.ts +1 -1
- package/dist/src/index.js +1 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/lexer/scanner/identifiers.d.ts +9 -0
- package/dist/src/lexer/scanner/identifiers.js +33 -0
- package/dist/src/lexer/scanner/identifiers.js.map +1 -0
- package/dist/src/lexer/scanner/numbers.d.ts +10 -0
- package/dist/src/lexer/scanner/numbers.js +89 -0
- package/dist/src/lexer/scanner/numbers.js.map +1 -0
- package/dist/src/lexer/scanner/punctuation.d.ts +9 -0
- package/dist/src/lexer/scanner/punctuation.js +151 -0
- package/dist/src/lexer/scanner/punctuation.js.map +1 -0
- package/dist/src/lexer/scanner/regex.d.ts +11 -0
- package/dist/src/lexer/scanner/regex.js +69 -0
- package/dist/src/lexer/scanner/regex.js.map +1 -0
- package/dist/src/lexer/scanner/strings.d.ts +13 -0
- package/dist/src/lexer/scanner/strings.js +118 -0
- package/dist/src/lexer/scanner/strings.js.map +1 -0
- package/dist/src/lexer/scanner.d.ts +20 -27
- package/dist/src/lexer/scanner.js +11 -415
- package/dist/src/lexer/scanner.js.map +1 -1
- package/dist/src/parser/declarations/classes.d.ts +14 -0
- package/dist/src/parser/declarations/classes.js +191 -0
- package/dist/src/parser/declarations/classes.js.map +1 -0
- package/dist/src/parser/declarations/functions.d.ts +17 -0
- package/dist/src/parser/declarations/functions.js +241 -0
- package/dist/src/parser/declarations/functions.js.map +1 -0
- package/dist/src/parser/declarations/type-members.d.ts +16 -0
- package/dist/src/parser/declarations/type-members.js +156 -0
- package/dist/src/parser/declarations/type-members.js.map +1 -0
- package/dist/src/parser/declarations.d.ts +13 -24
- package/dist/src/parser/declarations.js +13 -571
- package/dist/src/parser/declarations.js.map +1 -1
- package/dist/src/parser/helpers.js +13 -4
- package/dist/src/parser/helpers.js.map +1 -1
- package/dist/src/parser/literals.js +10 -1
- package/dist/src/parser/literals.js.map +1 -1
- package/dist/tests/codegen/llvm.test.js +24 -0
- package/dist/tests/codegen/llvm.test.js.map +1 -1
- package/dist/tests/driver/compiler.test.js +3 -0
- package/dist/tests/driver/compiler.test.js.map +1 -1
- package/dist/tests/driver/paths.test.d.ts +1 -0
- package/dist/tests/driver/paths.test.js +26 -0
- package/dist/tests/driver/paths.test.js.map +1 -0
- package/dist/tests/driver/toolchain-download.test.d.ts +1 -0
- package/dist/tests/driver/toolchain-download.test.js +38 -0
- package/dist/tests/driver/toolchain-download.test.js.map +1 -0
- package/dist/tests/driver/toolchain-provider.test.d.ts +1 -0
- package/dist/tests/driver/toolchain-provider.test.js +37 -0
- package/dist/tests/driver/toolchain-provider.test.js.map +1 -0
- package/dist/tests/e2e/compile-node.test.d.ts +7 -0
- package/dist/tests/e2e/compile-node.test.js +123 -0
- package/dist/tests/e2e/compile-node.test.js.map +1 -0
- package/dist/tests/e2e/compile.test.d.ts +4 -1
- package/dist/tests/e2e/compile.test.js +90 -130
- package/dist/tests/e2e/compile.test.js.map +1 -1
- package/dist/tests/e2e/harness.d.ts +36 -0
- package/dist/tests/e2e/harness.js +64 -0
- package/dist/tests/e2e/harness.js.map +1 -0
- package/dist/tests/e2e/node-modules.test.js +60 -0
- package/dist/tests/e2e/node-modules.test.js.map +1 -1
- package/dist/tests/extensions/registry.test.js +4 -0
- package/dist/tests/extensions/registry.test.js.map +1 -1
- package/package.json +5 -3
- package/runtime/ext_node/buffer/buffer.c +12 -552
- package/runtime/ext_node/buffer/parts/byte-access.inc +35 -0
- package/runtime/ext_node/buffer/parts/construction.inc +60 -0
- package/runtime/ext_node/buffer/parts/integer-io.inc +119 -0
- package/runtime/ext_node/buffer/parts/methods.inc +135 -0
- package/runtime/ext_node/buffer/parts/prototype.inc +54 -0
- package/runtime/ext_node/buffer/parts/search.inc +86 -0
- package/runtime/ext_node/buffer/parts/static-api.inc +58 -0
- package/runtime/ext_node/child_process/child_process.c +37 -3
- package/runtime/ext_node/events/events.c +285 -0
- package/runtime/ext_node/http/http.c +11 -736
- package/runtime/ext_node/http/parts/client.inc +290 -0
- package/runtime/ext_node/http/parts/helpers.inc +45 -0
- package/runtime/ext_node/http/parts/prototypes.inc +57 -0
- package/runtime/ext_node/http/parts/response.inc +149 -0
- package/runtime/ext_node/http/parts/server.inc +133 -0
- package/runtime/ext_node/http/parts/string-builder.inc +58 -0
- package/runtime/ext_node/net/net.c +12 -504
- package/runtime/ext_node/net/parts/construction.inc +22 -0
- package/runtime/ext_node/net/parts/platform.inc +60 -0
- package/runtime/ext_node/net/parts/prototypes.inc +35 -0
- package/runtime/ext_node/net/parts/read-loop.inc +58 -0
- package/runtime/ext_node/net/parts/server.inc +131 -0
- package/runtime/ext_node/net/parts/socket-methods.inc +100 -0
- package/runtime/ext_node/net/parts/static-api.inc +93 -0
- package/runtime/ext_node/querystring/querystring.c +251 -0
- package/runtime/ext_node/util/util.c +456 -0
- package/runtime/rt.h +8 -2
- package/runtime/rt_internal.h +34 -0
- package/runtime/xt_bigint/arithmetic.inc +135 -0
- package/runtime/xt_bigint/bits.inc +98 -0
- package/runtime/xt_bigint/bitwise.inc +103 -0
- package/runtime/xt_bigint/compare.inc +30 -0
- package/runtime/xt_bigint/conversions.inc +51 -0
- package/runtime/xt_bigint/division.inc +85 -0
- package/runtime/xt_bigint/format.inc +145 -0
- package/runtime/xt_bigint/helpers.inc +92 -0
- package/runtime/xt_bigint/magnitude.inc +88 -0
- package/runtime/xt_bigint/public.inc +59 -0
- package/runtime/xt_bigint/small-arithmetic.inc +58 -0
- package/runtime/xt_bigint.c +42 -0
- package/runtime/xt_builtins.c +40 -5
- package/runtime/xt_io.c +7 -0
- package/runtime/xt_stdlib/arrays.inc +161 -0
- package/runtime/xt_stdlib/dispatch.inc +116 -0
- package/runtime/xt_stdlib/helpers.inc +23 -0
- package/runtime/xt_stdlib/math.inc +72 -0
- package/runtime/xt_stdlib/strings.inc +178 -0
- package/runtime/xt_stdlib.c +10 -549
- package/runtime/xt_stdlib2/array-statics.inc +37 -0
- package/runtime/xt_stdlib2/arrays.inc +189 -0
- package/runtime/xt_stdlib2/container.inc +23 -0
- package/runtime/xt_stdlib2/date.inc +72 -0
- package/runtime/xt_stdlib2/error.inc +22 -0
- package/runtime/xt_stdlib2/helpers.inc +43 -0
- package/runtime/xt_stdlib2/json.inc +213 -0
- package/runtime/xt_stdlib2/map.inc +95 -0
- package/runtime/xt_stdlib2/number-string-statics.inc +73 -0
- package/runtime/xt_stdlib2/numbers.inc +38 -0
- package/runtime/xt_stdlib2/objects.inc +41 -0
- package/runtime/xt_stdlib2/regexp-match.inc +204 -0
- package/runtime/xt_stdlib2/regexp.inc +20 -0
- package/runtime/xt_stdlib2/set.inc +105 -0
- package/runtime/xt_stdlib2/strings.inc +94 -0
- package/runtime/xt_stdlib2.c +19 -1278
- package/runtime/xt_values.c +155 -12
- package/scripts/build-runtime.ts +109 -0
- package/scripts/fetch-toolchain.ts +101 -0
- package/scripts/package-release.ts +192 -0
- package/src/ast/expressions.ts +2 -0
- package/src/binder/binder.ts +40 -725
- package/src/binder/declarations.ts +203 -0
- package/src/binder/helpers.ts +47 -0
- package/src/binder/references.ts +410 -0
- package/src/binder/types.ts +134 -0
- package/src/cli/main.ts +43 -0
- package/src/codegen/generator/calls/access.ts +139 -0
- package/src/codegen/generator/calls/closures.ts +60 -0
- package/src/codegen/generator/calls/invocation.ts +282 -0
- package/src/codegen/generator/calls/literals.ts +77 -0
- package/src/codegen/generator/calls/super.ts +61 -0
- package/src/codegen/generator/calls.ts +30 -552
- package/src/codegen/generator/context.ts +2 -2
- package/src/codegen/generator/expressions/assignment.ts +226 -0
- package/src/codegen/generator/expressions/operators.ts +182 -0
- package/src/codegen/generator/expressions/primary.ts +304 -0
- package/src/codegen/generator/expressions.ts +22 -553
- package/src/codegen/generator/module.ts +14 -4
- package/src/codegen/generator/state.ts +8 -0
- package/src/codegen/generator/statements/control-flow.ts +225 -0
- package/src/codegen/generator/statements/dispatch.ts +122 -0
- package/src/codegen/generator/statements/loops.ts +173 -0
- package/src/codegen/generator/statements/variables.ts +152 -0
- package/src/codegen/generator/statements.ts +26 -612
- package/src/codegen/generator/tables.ts +7 -0
- package/src/codegen/values.ts +22 -57
- package/src/diagnostics/diagnostic.ts +1 -0
- package/src/diagnostics/source.ts +7 -12
- package/src/driver/compiler.ts +61 -18
- package/src/driver/index.ts +17 -2
- package/src/driver/paths.ts +54 -0
- package/src/driver/runtime-lib.ts +32 -0
- package/src/driver/toolchain-download.ts +108 -0
- package/src/driver/toolchain-provider.ts +91 -0
- package/src/driver/toolchain.ts +29 -11
- package/src/extensions/node/child_process/index.ts +4 -2
- package/src/extensions/node/events/index.ts +27 -0
- package/src/extensions/node/index.ts +6 -0
- package/src/extensions/node/querystring/index.ts +29 -0
- package/src/extensions/node/util/index.ts +48 -0
- package/src/extensions/registry.ts +6 -0
- package/src/index.ts +1 -0
- package/src/lexer/scanner/identifiers.ts +37 -0
- package/src/lexer/scanner/numbers.ts +84 -0
- package/src/lexer/scanner/punctuation.ts +132 -0
- package/src/lexer/scanner/regex.ts +79 -0
- package/src/lexer/scanner/strings.ts +128 -0
- package/src/lexer/scanner.ts +35 -401
- package/src/parser/declarations/classes.ts +215 -0
- package/src/parser/declarations/functions.ts +254 -0
- package/src/parser/declarations/type-members.ts +181 -0
- package/src/parser/declarations.ts +32 -609
- package/src/parser/helpers.ts +13 -6
- package/src/parser/literals.ts +10 -1
- package/scripts/build-runtime.mjs +0 -55
|
@@ -1,555 +1,33 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Call lowering: aggregates the invocation, access, literal, closure and super
|
|
3
|
+
* method groups into the `CallMethods` mixin consumed by the generator.
|
|
4
|
+
*
|
|
5
|
+
* The implementation is split by functional area under `calls/`:
|
|
6
|
+
* - `invocation` — direct calls, built-ins, imports and argument marshalling
|
|
7
|
+
* - `access` — property/element reads, `delete` and optional chaining
|
|
8
|
+
* - `literals` — array and object literals
|
|
9
|
+
* - `closures` — arrow/function expressions and captured environments
|
|
10
|
+
* - `super` — parent constructor/method delegation
|
|
3
11
|
*/
|
|
4
12
|
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
GLOBAL_FUNCTIONS,
|
|
27
|
-
MATH_CONSTANTS,
|
|
28
|
-
MATH_FUNCTIONS,
|
|
29
|
-
NAMESPACE_PROPERTIES,
|
|
30
|
-
NAMESPACE_STATICS,
|
|
31
|
-
propertyNameText,
|
|
32
|
-
} from "./tables.js";
|
|
33
|
-
import type { Generator } from "./generator.js";
|
|
34
|
-
|
|
35
|
-
export interface CallMethods {
|
|
36
|
-
emitCall(this: Generator, node: CallExpression): string;
|
|
37
|
-
tryEmitBuiltinCall(this: Generator, node: CallExpression, callee: PropertyAccessExpression): string | undefined;
|
|
38
|
-
runtimeCall(this: Generator, name: string, args: readonly string[]): string;
|
|
39
|
-
emitArguments(this: Generator, args: readonly Expression[]): { argc: string; ptr: string };
|
|
40
|
-
emitDelete(this: Generator, node: DeleteExpression): string;
|
|
41
|
-
emitPropertyAccess(this: Generator, node: PropertyAccessExpression): string;
|
|
42
|
-
emitElementAccess(this: Generator, node: ElementAccessExpression): string;
|
|
43
|
-
emitOptional(this: Generator, objectValue: string, compute: () => string): string;
|
|
44
|
-
emitArrayLiteral(this: Generator, node: ArrayLiteralExpression): string;
|
|
45
|
-
emitObjectLiteral(this: Generator, node: ObjectLiteralExpression): string;
|
|
46
|
-
emitClosure(this: Generator, node: ArrowFunction | FunctionExpression): string;
|
|
47
|
-
emitClosureValue(this: Generator, fn: FunctionInfo): string;
|
|
48
|
-
emitSuperConstructor(this: Generator, node: CallExpression): string;
|
|
49
|
-
emitSuperCall(this: Generator, node: CallExpression, access: PropertyAccessExpression): string;
|
|
50
|
-
emitModuleExport(this: Generator, node: CallExpression, exported: ModuleExport): string;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
export const callMethods: CallMethods = {
|
|
54
|
-
emitCall(node: CallExpression): string {
|
|
55
|
-
const callee = node.expression;
|
|
56
|
-
if (node.optional) {
|
|
57
|
-
const calleeValue = this.emitExpression(callee);
|
|
58
|
-
return this.emitOptional(calleeValue, () => {
|
|
59
|
-
const args = this.emitArguments(node.arguments);
|
|
60
|
-
const result = this.reg();
|
|
61
|
-
this.emit(` ${result} = call i64 @xt_closure_call(i64 ${calleeValue}, i32 ${args.argc}, i64* ${args.ptr})`);
|
|
62
|
-
return result;
|
|
63
|
-
});
|
|
64
|
-
}
|
|
65
|
-
if (
|
|
66
|
-
(callee.kind === SyntaxKind.PropertyAccessExpression || callee.kind === SyntaxKind.ElementAccessExpression) &&
|
|
67
|
-
(callee as PropertyAccessExpression | ElementAccessExpression).optional
|
|
68
|
-
) {
|
|
69
|
-
// `obj?.method(args)` / `obj?.[key](args)`: guard the receiver, then
|
|
70
|
-
// dispatch through the runtime, which understands object methods as well
|
|
71
|
-
// as the built-in array/string methods.
|
|
72
|
-
const access = callee as PropertyAccessExpression | ElementAccessExpression;
|
|
73
|
-
const object = this.emitExpression(access.expression);
|
|
74
|
-
return this.emitOptional(object, () => {
|
|
75
|
-
const name =
|
|
76
|
-
access.kind === SyntaxKind.PropertyAccessExpression
|
|
77
|
-
? this.stringValue((access as PropertyAccessExpression).name.text)
|
|
78
|
-
: this.emitExpression((access as ElementAccessExpression).argumentExpression);
|
|
79
|
-
const args = this.emitArguments(node.arguments);
|
|
80
|
-
const result = this.reg();
|
|
81
|
-
this.emit(
|
|
82
|
-
` ${result} = call i64 @xt_call_method(i64 ${object}, i64 ${name}, i32 ${args.argc}, i64* ${args.ptr})`,
|
|
83
|
-
);
|
|
84
|
-
return result;
|
|
85
|
-
});
|
|
86
|
-
}
|
|
87
|
-
if (callee.kind === SyntaxKind.PropertyAccessExpression) {
|
|
88
|
-
const access = callee as PropertyAccessExpression;
|
|
89
|
-
const special = this.tryEmitBuiltinCall(node, access);
|
|
90
|
-
if (special) return special;
|
|
91
|
-
if (access.expression.kind === SyntaxKind.Identifier && (access.expression as Identifier).text === "super") {
|
|
92
|
-
return this.emitSuperCall(node, access);
|
|
93
|
-
}
|
|
94
|
-
const object = this.emitExpression(access.expression);
|
|
95
|
-
const name = this.stringValue(access.name.text);
|
|
96
|
-
const args = this.emitArguments(node.arguments);
|
|
97
|
-
const result = this.reg();
|
|
98
|
-
this.emit(` ${result} = call i64 @xt_call_method(i64 ${object}, i64 ${name}, i32 ${args.argc}, i64* ${args.ptr})`);
|
|
99
|
-
return result;
|
|
100
|
-
}
|
|
101
|
-
if (callee.kind === SyntaxKind.ElementAccessExpression) {
|
|
102
|
-
const access = callee as ElementAccessExpression;
|
|
103
|
-
const object = this.emitExpression(access.expression);
|
|
104
|
-
const name = this.emitExpression(access.argumentExpression);
|
|
105
|
-
const args = this.emitArguments(node.arguments);
|
|
106
|
-
const result = this.reg();
|
|
107
|
-
this.emit(` ${result} = call i64 @xt_call_method(i64 ${object}, i64 ${name}, i32 ${args.argc}, i64* ${args.ptr})`);
|
|
108
|
-
return result;
|
|
109
|
-
}
|
|
110
|
-
if (callee.kind === SyntaxKind.Identifier) {
|
|
111
|
-
if ((callee as Identifier).text === "super") return this.emitSuperConstructor(node);
|
|
112
|
-
const symbol = this.binding.symbolOfIdentifier.get(callee as Identifier);
|
|
113
|
-
if (symbol && symbol.kind === SymbolKind.Import) {
|
|
114
|
-
const exported = this.importExports.get(symbol.id);
|
|
115
|
-
if (exported) return this.emitModuleExport(node, exported);
|
|
116
|
-
}
|
|
117
|
-
if (symbol && symbol.kind === SymbolKind.Function) {
|
|
118
|
-
const declaration = symbol.declarations[0];
|
|
119
|
-
const fn = declaration ? this.binding.functionOfNode.get(declaration) : undefined;
|
|
120
|
-
if (fn) {
|
|
121
|
-
const args = this.emitArguments(node.arguments);
|
|
122
|
-
const result = this.reg();
|
|
123
|
-
this.emit(
|
|
124
|
-
` ${result} = call i64 @${this.functionName(fn)}(i64 ${i64(XT_UNDEFINED)}, i64 ${i64(XT_UNDEFINED)}, i32 ${args.argc}, i64* ${args.ptr})`,
|
|
125
|
-
);
|
|
126
|
-
return result;
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
const globalFunction = !symbol ? GLOBAL_FUNCTIONS[(callee as Identifier).text] : undefined;
|
|
130
|
-
if (globalFunction) {
|
|
131
|
-
const args = this.emitArguments(node.arguments);
|
|
132
|
-
const result = this.reg();
|
|
133
|
-
this.emit(` ${result} = call i64 @${globalFunction}(i32 ${args.argc}, i64* ${args.ptr})`);
|
|
134
|
-
return result;
|
|
135
|
-
}
|
|
136
|
-
const builtin = this.builtins[(callee as Identifier).text];
|
|
137
|
-
if (!symbol && builtin) {
|
|
138
|
-
this.extraDeclarations.add(
|
|
139
|
-
builtin.returnVoid ? `declare void @${builtin.symbol}(i32, i64*)` : `declare i64 @${builtin.symbol}(i32, i64*)`,
|
|
140
|
-
);
|
|
141
|
-
const args = this.emitArguments(node.arguments);
|
|
142
|
-
if (builtin.returnVoid) {
|
|
143
|
-
this.emit(` call void @${builtin.symbol}(i32 ${args.argc}, i64* ${args.ptr})`);
|
|
144
|
-
return i64(XT_UNDEFINED);
|
|
145
|
-
}
|
|
146
|
-
const result = this.reg();
|
|
147
|
-
this.emit(` ${result} = call i64 @${builtin.symbol}(i32 ${args.argc}, i64* ${args.ptr})`);
|
|
148
|
-
return result;
|
|
149
|
-
}
|
|
150
|
-
const ctor = !symbol ? CTOR_FUNCTIONS[(callee as Identifier).text] : undefined;
|
|
151
|
-
if (ctor) {
|
|
152
|
-
const args = this.emitArguments(node.arguments);
|
|
153
|
-
const result = this.reg();
|
|
154
|
-
this.emit(` ${result} = call i64 @${ctor}(i32 ${args.argc}, i64* ${args.ptr})`);
|
|
155
|
-
return result;
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
const calleeValue = this.emitExpression(callee);
|
|
159
|
-
const args = this.emitArguments(node.arguments);
|
|
160
|
-
const result = this.reg();
|
|
161
|
-
this.emit(` ${result} = call i64 @xt_closure_call(i64 ${calleeValue}, i32 ${args.argc}, i64* ${args.ptr})`);
|
|
162
|
-
return result;
|
|
163
|
-
},
|
|
164
|
-
|
|
165
|
-
tryEmitBuiltinCall(node: CallExpression, callee: PropertyAccessExpression): string | undefined {
|
|
166
|
-
const target = callee.expression;
|
|
167
|
-
const method = callee.name.text;
|
|
168
|
-
const targetIdentifier = target.kind === SyntaxKind.Identifier ? (target as Identifier) : undefined;
|
|
169
|
-
const targetSymbol = targetIdentifier ? this.binding.symbolOfIdentifier.get(targetIdentifier) : undefined;
|
|
170
|
-
|
|
171
|
-
if (targetIdentifier && targetIdentifier.text === "console" && !targetSymbol) {
|
|
172
|
-
const consoleFn = CONSOLE_METHODS[method];
|
|
173
|
-
if (consoleFn) {
|
|
174
|
-
const args = this.emitArguments(node.arguments);
|
|
175
|
-
this.emit(` call void @${consoleFn}(i32 ${args.argc}, i64* ${args.ptr})`);
|
|
176
|
-
return i64(XT_UNDEFINED);
|
|
177
|
-
}
|
|
178
|
-
return undefined;
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
if (targetIdentifier && targetIdentifier.text === "Math" && !targetSymbol) {
|
|
182
|
-
if (!MATH_FUNCTIONS.has(method)) return undefined;
|
|
183
|
-
const name = this.stringValue(method);
|
|
184
|
-
const args = this.emitArguments(node.arguments);
|
|
185
|
-
const result = this.reg();
|
|
186
|
-
this.emit(` ${result} = call i64 @xt_math_call(i64 ${name}, i32 ${args.argc}, i64* ${args.ptr})`);
|
|
187
|
-
return result;
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
if (targetIdentifier && targetIdentifier.text === "JSON" && !targetSymbol) {
|
|
191
|
-
const fn = method === "parse" ? "xt_json_parse" : method === "stringify" ? "xt_json_stringify" : undefined;
|
|
192
|
-
if (!fn) return undefined;
|
|
193
|
-
const args = this.emitArguments(node.arguments);
|
|
194
|
-
const result = this.reg();
|
|
195
|
-
this.emit(` ${result} = call i64 @${fn}(i32 ${args.argc}, i64* ${args.ptr})`);
|
|
196
|
-
return result;
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
if (targetIdentifier && !targetSymbol) {
|
|
200
|
-
const dispatcher = NAMESPACE_STATICS[targetIdentifier.text];
|
|
201
|
-
if (dispatcher && targetIdentifier.text !== "Math" && targetIdentifier.text !== "JSON") {
|
|
202
|
-
const name = this.stringValue(method);
|
|
203
|
-
const args = this.emitArguments(node.arguments);
|
|
204
|
-
const result = this.reg();
|
|
205
|
-
this.emit(` ${result} = call i64 @${dispatcher}(i64 ${name}, i32 ${args.argc}, i64* ${args.ptr})`);
|
|
206
|
-
return result;
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
// `import * as ns from "path"` (or a default import) aliases a runtime
|
|
211
|
-
// namespace: `ns.join(...)` lowers to the same dispatcher as `path.join`.
|
|
212
|
-
if (targetIdentifier) {
|
|
213
|
-
const namespace = this.namespaceOfSymbol(targetSymbol);
|
|
214
|
-
if (namespace) {
|
|
215
|
-
const dispatcher = NAMESPACE_STATICS[namespace];
|
|
216
|
-
if (dispatcher) {
|
|
217
|
-
const name = this.stringValue(method);
|
|
218
|
-
const args = this.emitArguments(node.arguments);
|
|
219
|
-
const result = this.reg();
|
|
220
|
-
this.emit(` ${result} = call i64 @${dispatcher}(i64 ${name}, i32 ${args.argc}, i64* ${args.ptr})`);
|
|
221
|
-
return result;
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
void BUILTIN_METHODS;
|
|
227
|
-
return undefined;
|
|
228
|
-
},
|
|
229
|
-
|
|
230
|
-
/** Lower a call to an imported module binding to its runtime symbol. */
|
|
231
|
-
emitModuleExport(node: CallExpression, exported: ModuleExport): string {
|
|
232
|
-
const args = this.emitArguments(node.arguments);
|
|
233
|
-
if (exported.symbol) {
|
|
234
|
-
this.extraDeclarations.add(
|
|
235
|
-
exported.returnVoid
|
|
236
|
-
? `declare void @${exported.symbol}(i32, i64*)`
|
|
237
|
-
: `declare i64 @${exported.symbol}(i32, i64*)`,
|
|
238
|
-
);
|
|
239
|
-
if (exported.returnVoid) {
|
|
240
|
-
this.emit(` call void @${exported.symbol}(i32 ${args.argc}, i64* ${args.ptr})`);
|
|
241
|
-
return i64(XT_UNDEFINED);
|
|
242
|
-
}
|
|
243
|
-
const result = this.reg();
|
|
244
|
-
this.emit(` ${result} = call i64 @${exported.symbol}(i32 ${args.argc}, i64* ${args.ptr})`);
|
|
245
|
-
return result;
|
|
246
|
-
}
|
|
247
|
-
if (exported.namespace && exported.method) {
|
|
248
|
-
const dispatcher = NAMESPACE_STATICS[exported.namespace];
|
|
249
|
-
if (dispatcher) {
|
|
250
|
-
const name = this.stringValue(exported.method);
|
|
251
|
-
const result = this.reg();
|
|
252
|
-
this.emit(` ${result} = call i64 @${dispatcher}(i64 ${name}, i32 ${args.argc}, i64* ${args.ptr})`);
|
|
253
|
-
return result;
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
this.unsupported(node, "imported function");
|
|
257
|
-
return i64(XT_UNDEFINED);
|
|
258
|
-
},
|
|
259
|
-
|
|
260
|
-
runtimeCall(name: string, args: readonly string[]): string {
|
|
261
|
-
const result = this.reg();
|
|
262
|
-
this.emit(` ${result} = call i64 @${name}(${args.map((a) => `i64 ${a}`).join(", ")})`);
|
|
263
|
-
return result;
|
|
264
|
-
},
|
|
265
|
-
|
|
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
|
-
}
|
|
292
|
-
}
|
|
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 };
|
|
298
|
-
},
|
|
299
|
-
|
|
300
|
-
emitDelete(node: DeleteExpression): string {
|
|
301
|
-
const target = node.expression;
|
|
302
|
-
if (target.kind === SyntaxKind.PropertyAccessExpression) {
|
|
303
|
-
const access = target as PropertyAccessExpression;
|
|
304
|
-
const object = this.emitExpression(access.expression);
|
|
305
|
-
const key = this.stringValue(access.name.text);
|
|
306
|
-
return this.runtimeCall("xt_delete", [object, key]);
|
|
307
|
-
}
|
|
308
|
-
if (target.kind === SyntaxKind.ElementAccessExpression) {
|
|
309
|
-
const access = target as ElementAccessExpression;
|
|
310
|
-
const object = this.emitExpression(access.expression);
|
|
311
|
-
const key = this.emitExpression(access.argumentExpression);
|
|
312
|
-
return this.runtimeCall("xt_delete", [object, key]);
|
|
313
|
-
}
|
|
314
|
-
return i64(XT_TRUE);
|
|
315
|
-
},
|
|
316
|
-
|
|
317
|
-
emitPropertyAccess(node: PropertyAccessExpression): string {
|
|
318
|
-
if (node.expression.kind === SyntaxKind.Identifier && (node.expression as Identifier).text === "super") {
|
|
319
|
-
const thisValue = this.emitThis();
|
|
320
|
-
const proto = this.reg();
|
|
321
|
-
this.emit(` ${proto} = call i64 @xt_object_get_prototype(i64 ${thisValue})`);
|
|
322
|
-
const parentProto = this.reg();
|
|
323
|
-
this.emit(` ${parentProto} = call i64 @xt_object_get_prototype(i64 ${proto})`);
|
|
324
|
-
const key = this.stringValue(node.name.text);
|
|
325
|
-
const value = this.reg();
|
|
326
|
-
this.emit(` ${value} = call i64 @xt_get(i64 ${parentProto}, i64 ${key})`);
|
|
327
|
-
return value;
|
|
328
|
-
}
|
|
329
|
-
if (
|
|
330
|
-
node.name.text in MATH_CONSTANTS &&
|
|
331
|
-
node.expression.kind === SyntaxKind.Identifier &&
|
|
332
|
-
(node.expression as Identifier).text === "Math" &&
|
|
333
|
-
!this.binding.symbolOfIdentifier.get(node.expression as Identifier)
|
|
334
|
-
) {
|
|
335
|
-
return numberLiteral(MATH_CONSTANTS[node.name.text]!);
|
|
336
|
-
}
|
|
337
|
-
if (
|
|
338
|
-
node.expression.kind === SyntaxKind.Identifier &&
|
|
339
|
-
!this.binding.symbolOfIdentifier.get(node.expression as Identifier)
|
|
340
|
-
) {
|
|
341
|
-
const getter = NAMESPACE_PROPERTIES[(node.expression as Identifier).text];
|
|
342
|
-
if (getter) {
|
|
343
|
-
const key = this.stringValue(node.name.text);
|
|
344
|
-
const result = this.reg();
|
|
345
|
-
this.emit(` ${result} = call i64 @${getter}(i64 ${key})`);
|
|
346
|
-
return result;
|
|
347
|
-
}
|
|
348
|
-
}
|
|
349
|
-
if (node.expression.kind === SyntaxKind.Identifier) {
|
|
350
|
-
const namespace = this.namespaceOfSymbol(
|
|
351
|
-
this.binding.symbolOfIdentifier.get(node.expression as Identifier),
|
|
352
|
-
);
|
|
353
|
-
if (namespace) {
|
|
354
|
-
const getter = NAMESPACE_PROPERTIES[namespace];
|
|
355
|
-
if (getter) {
|
|
356
|
-
const key = this.stringValue(node.name.text);
|
|
357
|
-
const result = this.reg();
|
|
358
|
-
this.emit(` ${result} = call i64 @${getter}(i64 ${key})`);
|
|
359
|
-
return result;
|
|
360
|
-
}
|
|
361
|
-
}
|
|
362
|
-
}
|
|
363
|
-
const object = this.emitExpression(node.expression);
|
|
364
|
-
const access = (): string => {
|
|
365
|
-
if (node.name.text === "length") {
|
|
366
|
-
const result = this.reg();
|
|
367
|
-
this.emit(` ${result} = call i64 @xt_array_length(i64 ${object})`);
|
|
368
|
-
return result;
|
|
369
|
-
}
|
|
370
|
-
const key = this.stringValue(node.name.text);
|
|
371
|
-
const result = this.reg();
|
|
372
|
-
this.emit(` ${result} = call i64 @xt_get(i64 ${object}, i64 ${key})`);
|
|
373
|
-
return result;
|
|
374
|
-
};
|
|
375
|
-
return node.optional ? this.emitOptional(object, access) : access();
|
|
376
|
-
},
|
|
377
|
-
|
|
378
|
-
emitElementAccess(node: ElementAccessExpression): string {
|
|
379
|
-
const object = this.emitExpression(node.expression);
|
|
380
|
-
const access = (): string => {
|
|
381
|
-
const key = this.emitExpression(node.argumentExpression);
|
|
382
|
-
const result = this.reg();
|
|
383
|
-
this.emit(` ${result} = call i64 @xt_get(i64 ${object}, i64 ${key})`);
|
|
384
|
-
return result;
|
|
385
|
-
};
|
|
386
|
-
return node.optional ? this.emitOptional(object, access) : access();
|
|
387
|
-
},
|
|
388
|
-
|
|
389
|
-
/**
|
|
390
|
-
* Evaluate `object` once and, when it is neither `null` nor `undefined`, run
|
|
391
|
-
* `compute` to produce the value; otherwise short-circuit to `undefined`.
|
|
392
|
-
*/
|
|
393
|
-
emitOptional(objectValue: string, compute: () => string): string {
|
|
394
|
-
const result = this.alloca();
|
|
395
|
-
this.emit(` store i64 ${i64(XT_UNDEFINED)}, i64* ${result}`);
|
|
396
|
-
const nullish = this.reg();
|
|
397
|
-
this.emit(` ${nullish} = call i64 @xt_is_nullish(i64 ${objectValue})`);
|
|
398
|
-
const truthy = this.reg();
|
|
399
|
-
this.emit(` ${truthy} = call i32 @xt_truthy(i64 ${nullish})`);
|
|
400
|
-
const condition = this.reg();
|
|
401
|
-
this.emit(` ${condition} = icmp ne i32 ${truthy}, 0`);
|
|
402
|
-
const someLabel = this.label("opt.some");
|
|
403
|
-
const endLabel = this.label("opt.end");
|
|
404
|
-
this.terminate(`br i1 ${condition}, label %${endLabel}, label %${someLabel}`);
|
|
405
|
-
this.startBlock(someLabel);
|
|
406
|
-
const value = compute();
|
|
407
|
-
this.emit(` store i64 ${value}, i64* ${result}`);
|
|
408
|
-
this.terminate(`br label %${endLabel}`);
|
|
409
|
-
this.startBlock(endLabel);
|
|
410
|
-
const merged = this.reg();
|
|
411
|
-
this.emit(` ${merged} = load i64, i64* ${result}`);
|
|
412
|
-
return merged;
|
|
413
|
-
},
|
|
414
|
-
|
|
415
|
-
emitArrayLiteral(node: ArrayLiteralExpression): string {
|
|
416
|
-
const hasSpread = node.elements.some((element) => element.kind === SyntaxKind.SpreadElement);
|
|
417
|
-
if (!hasSpread) {
|
|
418
|
-
const args = this.emitArguments(node.elements);
|
|
419
|
-
const result = this.reg();
|
|
420
|
-
this.emit(` ${result} = call i64 @xt_array_new(i32 ${args.argc}, i64* ${args.ptr})`);
|
|
421
|
-
return result;
|
|
422
|
-
}
|
|
423
|
-
const array = this.reg();
|
|
424
|
-
this.emit(` ${array} = call i64 @xt_array_new(i32 0, i64* null)`);
|
|
425
|
-
for (const element of node.elements) {
|
|
426
|
-
if (element.kind === SyntaxKind.SpreadElement) {
|
|
427
|
-
const spread = this.emitExpression((element as { expression: Expression }).expression);
|
|
428
|
-
this.emit(` call i64 @xt_array_spread(i64 ${array}, i64 ${spread})`);
|
|
429
|
-
} else {
|
|
430
|
-
const value = this.emitExpression(element);
|
|
431
|
-
this.emit(` call i64 @xt_array_push(i64 ${array}, i64 ${value})`);
|
|
432
|
-
}
|
|
433
|
-
}
|
|
434
|
-
return array;
|
|
435
|
-
},
|
|
436
|
-
|
|
437
|
-
emitObjectLiteral(node: ObjectLiteralExpression): string {
|
|
438
|
-
const object = this.reg();
|
|
439
|
-
this.emit(` ${object} = call i64 @xt_object_new()`);
|
|
440
|
-
for (const property of node.properties) {
|
|
441
|
-
if (property.kind === SyntaxKind.PropertyAssignment) {
|
|
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
|
-
}
|
|
451
|
-
const value = this.emitExpression(property.initializer);
|
|
452
|
-
this.emit(` call i64 @xt_set(i64 ${object}, i64 ${key}, i64 ${value})`);
|
|
453
|
-
} else if (property.kind === SyntaxKind.ShorthandPropertyAssignment) {
|
|
454
|
-
const identifier = property.name;
|
|
455
|
-
const key = this.stringValue(identifier.text);
|
|
456
|
-
const value = this.emitIdentifier(identifier);
|
|
457
|
-
this.emit(` call i64 @xt_set(i64 ${object}, i64 ${key}, i64 ${value})`);
|
|
458
|
-
} else if (property.kind === SyntaxKind.SpreadElement) {
|
|
459
|
-
const spread = this.emitExpression((property as { expression: Expression }).expression);
|
|
460
|
-
this.emit(` call i64 @xt_object_spread(i64 ${object}, i64 ${spread})`);
|
|
461
|
-
} else {
|
|
462
|
-
this.unsupported(property, "object spread");
|
|
463
|
-
}
|
|
464
|
-
}
|
|
465
|
-
return object;
|
|
466
|
-
},
|
|
467
|
-
|
|
468
|
-
emitClosure(node: ArrowFunction | FunctionExpression): string {
|
|
469
|
-
const fn = this.binding.functionOfNode.get(node);
|
|
470
|
-
if (!fn) {
|
|
471
|
-
this.unsupported(node, "closure");
|
|
472
|
-
return i64(XT_UNDEFINED);
|
|
473
|
-
}
|
|
474
|
-
return this.emitClosureValue(fn);
|
|
475
|
-
},
|
|
476
|
-
|
|
477
|
-
emitClosureValue(fn: FunctionInfo): string {
|
|
478
|
-
const count = fn.captures.length + (fn.capturesThis ? 1 : 0);
|
|
479
|
-
let envPtr = "null";
|
|
480
|
-
if (count > 0) {
|
|
481
|
-
envPtr = `%env${this.current.allocas.length}`;
|
|
482
|
-
this.current.allocas.push(`${envPtr} = alloca i64, i32 ${count}`);
|
|
483
|
-
for (let index = 0; index < fn.captures.length; index++) {
|
|
484
|
-
const symbol = fn.captures[index]!;
|
|
485
|
-
const slot = this.current.slots.get(symbol.id);
|
|
486
|
-
let raw = i64(XT_UNDEFINED);
|
|
487
|
-
if (slot) {
|
|
488
|
-
raw = this.reg();
|
|
489
|
-
this.emit(` ${raw} = load i64, i64* ${slot.ptr}`);
|
|
490
|
-
}
|
|
491
|
-
const target = this.reg();
|
|
492
|
-
this.emit(` ${target} = getelementptr i64, i64* ${envPtr}, i32 ${index}`);
|
|
493
|
-
this.emit(` store i64 ${raw}, i64* ${target}`);
|
|
494
|
-
}
|
|
495
|
-
if (fn.capturesThis) {
|
|
496
|
-
let thisValue = i64(XT_UNDEFINED);
|
|
497
|
-
if (this.current.thisPtr) {
|
|
498
|
-
thisValue = this.reg();
|
|
499
|
-
this.emit(` ${thisValue} = load i64, i64* ${this.current.thisPtr}`);
|
|
500
|
-
}
|
|
501
|
-
const target = this.reg();
|
|
502
|
-
this.emit(` ${target} = getelementptr i64, i64* ${envPtr}, i32 ${fn.captures.length}`);
|
|
503
|
-
this.emit(` store i64 ${thisValue}, i64* ${target}`);
|
|
504
|
-
}
|
|
505
|
-
}
|
|
506
|
-
const cast = this.reg();
|
|
507
|
-
this.emit(` ${cast} = bitcast i64 (i64, i64, i32, i64*)* @${this.functionName(fn)} to i8*`);
|
|
508
|
-
const closure = this.reg();
|
|
509
|
-
this.emit(` ${closure} = call i64 @xt_closure_new(i8* ${cast}, i32 ${count}, i64* ${envPtr})`);
|
|
510
|
-
return closure;
|
|
511
|
-
},
|
|
512
|
-
|
|
513
|
-
emitSuperConstructor(node: CallExpression): string {
|
|
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
|
-
}
|
|
528
|
-
const proto = this.reg();
|
|
529
|
-
this.emit(` ${proto} = call i64 @xt_object_get_prototype(i64 ${thisValue})`);
|
|
530
|
-
const parentProto = this.reg();
|
|
531
|
-
this.emit(` ${parentProto} = call i64 @xt_object_get_prototype(i64 ${proto})`);
|
|
532
|
-
const key = this.stringValue("__ctor");
|
|
533
|
-
const ctor = this.reg();
|
|
534
|
-
this.emit(` ${ctor} = call i64 @xt_get(i64 ${parentProto}, i64 ${key})`);
|
|
535
|
-
const args = this.emitArguments(node.arguments);
|
|
536
|
-
const result = this.reg();
|
|
537
|
-
this.emit(` ${result} = call i64 @xt_call_with_this(i64 ${ctor}, i64 ${thisValue}, i32 ${args.argc}, i64* ${args.ptr})`);
|
|
538
|
-
return result;
|
|
539
|
-
},
|
|
540
|
-
|
|
541
|
-
emitSuperCall(node: CallExpression, access: PropertyAccessExpression): string {
|
|
542
|
-
const thisValue = this.emitThis();
|
|
543
|
-
const proto = this.reg();
|
|
544
|
-
this.emit(` ${proto} = call i64 @xt_object_get_prototype(i64 ${thisValue})`);
|
|
545
|
-
const parentProto = this.reg();
|
|
546
|
-
this.emit(` ${parentProto} = call i64 @xt_object_get_prototype(i64 ${proto})`);
|
|
547
|
-
const key = this.stringValue(access.name.text);
|
|
548
|
-
const method = this.reg();
|
|
549
|
-
this.emit(` ${method} = call i64 @xt_get(i64 ${parentProto}, i64 ${key})`);
|
|
550
|
-
const args = this.emitArguments(node.arguments);
|
|
551
|
-
const result = this.reg();
|
|
552
|
-
this.emit(` ${result} = call i64 @xt_call_with_this(i64 ${method}, i64 ${thisValue}, i32 ${args.argc}, i64* ${args.ptr})`);
|
|
553
|
-
return result;
|
|
554
|
-
},
|
|
555
|
-
};
|
|
13
|
+
import { invocationCallMethods, type InvocationCallMethods } from "./calls/invocation.js";
|
|
14
|
+
import { accessCallMethods, type AccessCallMethods } from "./calls/access.js";
|
|
15
|
+
import { literalCallMethods, type LiteralCallMethods } from "./calls/literals.js";
|
|
16
|
+
import { closureCallMethods, type ClosureCallMethods } from "./calls/closures.js";
|
|
17
|
+
import { superCallMethods, type SuperCallMethods } from "./calls/super.js";
|
|
18
|
+
|
|
19
|
+
export interface CallMethods
|
|
20
|
+
extends InvocationCallMethods,
|
|
21
|
+
AccessCallMethods,
|
|
22
|
+
LiteralCallMethods,
|
|
23
|
+
ClosureCallMethods,
|
|
24
|
+
SuperCallMethods {}
|
|
25
|
+
|
|
26
|
+
export const callMethods: CallMethods = Object.assign(
|
|
27
|
+
{},
|
|
28
|
+
invocationCallMethods,
|
|
29
|
+
accessCallMethods,
|
|
30
|
+
literalCallMethods,
|
|
31
|
+
closureCallMethods,
|
|
32
|
+
superCallMethods,
|
|
33
|
+
);
|
|
@@ -117,8 +117,8 @@ export class GeneratorContext {
|
|
|
117
117
|
return ptr;
|
|
118
118
|
}
|
|
119
119
|
|
|
120
|
-
const(
|
|
121
|
-
return i64(
|
|
120
|
+
const(value: bigint): string {
|
|
121
|
+
return i64(value);
|
|
122
122
|
}
|
|
123
123
|
|
|
124
124
|
// -- variables -----------------------------------------------------------
|