xbintsc 0.1.6 → 0.1.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -4
- package/dist/src/ast/common.d.ts +33 -0
- package/dist/src/ast/common.js +7 -0
- package/dist/src/ast/common.js.map +1 -0
- package/dist/src/ast/declarations.d.ts +110 -0
- package/dist/src/ast/declarations.js +5 -0
- package/dist/src/ast/declarations.js.map +1 -0
- package/dist/src/ast/expressions.d.ts +219 -0
- package/dist/src/ast/expressions.js +6 -0
- package/dist/src/ast/expressions.js.map +1 -0
- package/dist/src/ast/kinds.d.ts +160 -0
- package/dist/src/ast/kinds.js +171 -0
- package/dist/src/ast/kinds.js.map +1 -0
- package/dist/src/ast/modules.d.ts +61 -0
- package/dist/src/ast/modules.js +5 -0
- package/dist/src/ast/modules.js.map +1 -0
- package/dist/src/ast/nodes.d.ts +11 -839
- package/dist/src/ast/nodes.js +11 -237
- package/dist/src/ast/nodes.js.map +1 -1
- package/dist/src/ast/operators.d.ts +71 -0
- package/dist/src/ast/operators.js +77 -0
- package/dist/src/ast/operators.js.map +1 -0
- package/dist/src/ast/statements.d.ts +120 -0
- package/dist/src/ast/statements.js +5 -0
- package/dist/src/ast/statements.js.map +1 -0
- package/dist/src/ast/types.d.ts +123 -0
- package/dist/src/ast/types.js +6 -0
- package/dist/src/ast/types.js.map +1 -0
- package/dist/src/binder/binder.d.ts +35 -1
- package/dist/src/binder/binder.js +138 -0
- package/dist/src/binder/binder.js.map +1 -1
- package/dist/src/codegen/generator/calls.d.ts +26 -0
- package/dist/src/codegen/generator/calls.js +373 -0
- package/dist/src/codegen/generator/calls.js.map +1 -0
- package/dist/src/codegen/generator/context.d.ts +47 -0
- package/dist/src/codegen/generator/context.js +164 -0
- package/dist/src/codegen/generator/context.js.map +1 -0
- package/dist/src/codegen/generator/expressions.d.ts +25 -0
- package/dist/src/codegen/generator/expressions.js +454 -0
- package/dist/src/codegen/generator/expressions.js.map +1 -0
- package/dist/src/codegen/generator/generator.d.ts +22 -0
- package/dist/src/codegen/generator/generator.js +21 -0
- package/dist/src/codegen/generator/generator.js.map +1 -0
- package/dist/src/codegen/generator/module.d.ts +19 -0
- package/dist/src/codegen/generator/module.js +214 -0
- package/dist/src/codegen/generator/module.js.map +1 -0
- package/dist/src/codegen/generator/state.d.ts +42 -0
- package/dist/src/codegen/generator/state.js +125 -0
- package/dist/src/codegen/generator/state.js.map +1 -0
- package/dist/src/codegen/generator/statements.d.ts +22 -0
- package/dist/src/codegen/generator/statements.js +433 -0
- package/dist/src/codegen/generator/statements.js.map +1 -0
- package/dist/src/codegen/generator/tables.d.ts +23 -0
- package/dist/src/codegen/generator/tables.js +186 -0
- package/dist/src/codegen/generator/tables.js.map +1 -0
- package/dist/src/codegen/llvm.d.ts +4 -13
- package/dist/src/codegen/llvm.js +4 -1537
- package/dist/src/codegen/llvm.js.map +1 -1
- package/dist/src/driver/compiler.js +36 -11
- package/dist/src/driver/compiler.js.map +1 -1
- package/dist/src/driver/modules.d.ts +24 -0
- package/dist/src/driver/modules.js +347 -0
- package/dist/src/driver/modules.js.map +1 -0
- package/dist/src/lexer/char.d.ts +78 -0
- package/dist/src/lexer/char.js +106 -0
- package/dist/src/lexer/char.js.map +1 -0
- package/dist/src/lexer/scanner.js +1 -98
- package/dist/src/lexer/scanner.js.map +1 -1
- package/dist/src/parser/context.d.ts +58 -0
- package/dist/src/parser/context.js +174 -0
- package/dist/src/parser/context.js.map +1 -0
- package/dist/src/parser/declarations.d.ts +26 -0
- package/dist/src/parser/declarations.js +461 -0
- package/dist/src/parser/declarations.js.map +1 -0
- package/dist/src/parser/expressions.d.ts +27 -0
- package/dist/src/parser/expressions.js +440 -0
- package/dist/src/parser/expressions.js.map +1 -0
- package/dist/src/parser/helpers.d.ts +7 -0
- package/dist/src/parser/helpers.js +36 -0
- package/dist/src/parser/helpers.js.map +1 -0
- package/dist/src/parser/literals.d.ts +16 -0
- package/dist/src/parser/literals.js +193 -0
- package/dist/src/parser/literals.js.map +1 -0
- package/dist/src/parser/modules.d.ts +12 -0
- package/dist/src/parser/modules.js +175 -0
- package/dist/src/parser/modules.js.map +1 -0
- package/dist/src/parser/operators.d.ts +12 -0
- package/dist/src/parser/operators.js +172 -0
- package/dist/src/parser/operators.js.map +1 -0
- package/dist/src/parser/parser.d.ts +17 -122
- package/dist/src/parser/parser.js +18 -2311
- package/dist/src/parser/parser.js.map +1 -1
- package/dist/src/parser/speculation.d.ts +6 -0
- package/dist/src/parser/speculation.js +10 -0
- package/dist/src/parser/speculation.js.map +1 -0
- package/dist/src/parser/statements.d.ts +28 -0
- package/dist/src/parser/statements.js +402 -0
- package/dist/src/parser/statements.js.map +1 -0
- package/dist/src/parser/types.d.ts +21 -0
- package/dist/src/parser/types.js +338 -0
- package/dist/src/parser/types.js.map +1 -0
- package/dist/tests/codegen/llvm.test.js +1 -1
- package/dist/tests/codegen/llvm.test.js.map +1 -1
- package/dist/tests/e2e/compile.test.js +86 -0
- package/dist/tests/e2e/compile.test.js.map +1 -1
- package/package.json +1 -1
- package/runtime/rt.h +55 -4
- package/runtime/rt_internal.h +169 -0
- package/runtime/xt_alloc.c +38 -0
- package/runtime/xt_builtins.c +238 -0
- package/runtime/xt_containers.c +312 -0
- package/runtime/xt_io.c +246 -0
- package/runtime/xt_promise.c +292 -0
- package/runtime/xt_stdlib.c +556 -0
- package/runtime/xt_stdlib2.c +1043 -0
- package/runtime/xt_values.c +291 -0
- package/scripts/build-runtime.mjs +8 -1
- package/src/ast/common.ts +210 -0
- package/src/ast/declarations.ts +130 -0
- package/src/ast/expressions.ts +275 -0
- package/src/ast/kinds.ts +176 -0
- package/src/ast/modules.ts +73 -0
- package/src/ast/nodes.ts +11 -1101
- package/src/ast/operators.ts +76 -0
- package/src/ast/statements.ts +148 -0
- package/src/ast/types.ts +173 -0
- package/src/binder/binder.ts +196 -0
- package/src/codegen/generator/calls.ts +433 -0
- package/src/codegen/generator/context.ts +190 -0
- package/src/codegen/generator/expressions.ts +508 -0
- package/src/codegen/generator/generator.ts +35 -0
- package/src/codegen/generator/module.ts +244 -0
- package/src/codegen/generator/state.ts +169 -0
- package/src/codegen/generator/statements.ts +480 -0
- package/src/codegen/generator/tables.ts +206 -0
- package/src/codegen/llvm.ts +4 -1720
- package/src/driver/compiler.ts +45 -12
- package/src/driver/modules.ts +377 -0
- package/src/lexer/char.ts +116 -0
- package/src/lexer/scanner.ts +9 -109
- package/src/parser/context.ts +196 -0
- package/src/parser/declarations.ts +502 -0
- package/src/parser/expressions.ts +468 -0
- package/src/parser/helpers.ts +42 -0
- package/src/parser/literals.ts +207 -0
- package/src/parser/modules.ts +194 -0
- package/src/parser/operators.ts +181 -0
- package/src/parser/parser.ts +35 -2373
- package/src/parser/speculation.ts +9 -0
- package/src/parser/statements.ts +457 -0
- package/src/parser/types.ts +365 -0
- package/runtime/xt_runtime.c +0 -1372
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Module-level generation: emitting functions, the entry point and the overall
|
|
3
|
+
* IR text, plus default-parameter initialization.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
SyntaxKind,
|
|
8
|
+
type ArrowFunction,
|
|
9
|
+
type Block,
|
|
10
|
+
type Expression,
|
|
11
|
+
type Parameter,
|
|
12
|
+
} from "../../ast/nodes.js";
|
|
13
|
+
import type { ClassInfo, FunctionInfo, SymbolInfo } from "../../binder/binder.js";
|
|
14
|
+
import { SymbolKind } from "../../binder/binder.js";
|
|
15
|
+
import { i64, XT_UNDEFINED } from "../values.js";
|
|
16
|
+
import { RUNTIME_DECLARATIONS, type FunctionState } from "./state.js";
|
|
17
|
+
import type { Generator } from "./generator.js";
|
|
18
|
+
|
|
19
|
+
export interface ModuleMethods {
|
|
20
|
+
run(this: Generator): string;
|
|
21
|
+
emitFunction(this: Generator, fn: FunctionInfo): void;
|
|
22
|
+
emitMain(this: Generator): void;
|
|
23
|
+
functionName(this: Generator, fn: FunctionInfo): string;
|
|
24
|
+
wrapAsync(this: Generator, value: string): string;
|
|
25
|
+
classGlobal(this: Generator, classInfo: ClassInfo): string;
|
|
26
|
+
emitClassReference(this: Generator, classInfo: ClassInfo): string;
|
|
27
|
+
emitClassSetup(this: Generator, classInfo: ClassInfo): void;
|
|
28
|
+
emitDefaultParameter(this: Generator, symbol: SymbolInfo, value: string, initializer: Expression): void;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export const moduleMethods: ModuleMethods = {
|
|
32
|
+
run(): string {
|
|
33
|
+
for (const classInfo of this.binding.classes) {
|
|
34
|
+
const globalName = `@class.${classInfo.id}`;
|
|
35
|
+
this.classGlobals.set(classInfo.id, globalName);
|
|
36
|
+
this.globals.push(`${globalName} = internal global i64 0`);
|
|
37
|
+
}
|
|
38
|
+
// Module-level bindings captured by functions live in globals so that a
|
|
39
|
+
// top-level function can see them without a closure environment.
|
|
40
|
+
const moduleScope = this.binding.scopes.get(this.sourceFile);
|
|
41
|
+
if (moduleScope) {
|
|
42
|
+
for (const symbol of moduleScope.symbols.values()) {
|
|
43
|
+
const isVariable = symbol.kind === SymbolKind.Var || symbol.kind === SymbolKind.Let || symbol.kind === SymbolKind.Const;
|
|
44
|
+
if (!isVariable || !symbol.boxed || !symbol.fn.isModule) continue;
|
|
45
|
+
const globalName = `@g.${symbol.id}`;
|
|
46
|
+
this.moduleGlobals.set(symbol.id, globalName);
|
|
47
|
+
this.globals.push(`${globalName} = internal global i64 ${i64(XT_UNDEFINED)}`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
for (const fn of this.binding.functions) this.emitFunction(fn);
|
|
51
|
+
this.emitMain();
|
|
52
|
+
const header = ["; ModuleID = 'xbintsc'", "source_filename = \"" + this.sourceFile.fileName + "\"", ""];
|
|
53
|
+
return [...header, ...RUNTIME_DECLARATIONS, ...this.extraDeclarations, "", ...this.globals, "", ...this.functions, ""].join("\n");
|
|
54
|
+
},
|
|
55
|
+
|
|
56
|
+
// -- module level --------------------------------------------------------
|
|
57
|
+
|
|
58
|
+
emitFunction(fn: FunctionInfo): void {
|
|
59
|
+
const name = this.functionName(fn);
|
|
60
|
+
const state: FunctionState = {
|
|
61
|
+
fn,
|
|
62
|
+
buffer: [],
|
|
63
|
+
allocas: [],
|
|
64
|
+
slots: new Map(),
|
|
65
|
+
reg: 0,
|
|
66
|
+
label: 0,
|
|
67
|
+
terminated: false,
|
|
68
|
+
loops: [],
|
|
69
|
+
tryFrames: [],
|
|
70
|
+
escapePointers: [],
|
|
71
|
+
usesTry: false,
|
|
72
|
+
};
|
|
73
|
+
this.current = state;
|
|
74
|
+
|
|
75
|
+
const header = `define i64 @${name}(i64 %this, i64 %env, i32 %argc, i64* %argv) {`;
|
|
76
|
+
this.emit(`%saved.env = alloca i64`);
|
|
77
|
+
this.emit(`store i64 %env, i64* %saved.env`);
|
|
78
|
+
this.emit(`%saved.this = alloca i64`);
|
|
79
|
+
this.emit(`store i64 %this, i64* %saved.this`);
|
|
80
|
+
state.thisPtr = "%saved.this";
|
|
81
|
+
this.emit(`%saved.argc = alloca i32`);
|
|
82
|
+
this.emit(`store i32 %argc, i32* %saved.argc`);
|
|
83
|
+
this.emit(`%saved.argv = alloca i64*`);
|
|
84
|
+
this.emit(`store i64* %argv, i64** %saved.argv`);
|
|
85
|
+
|
|
86
|
+
// Parameters.
|
|
87
|
+
const parameterNodes = (fn.node as { parameters?: Parameter[] }).parameters ?? [];
|
|
88
|
+
for (let index = 0; index < fn.params.length; index++) {
|
|
89
|
+
const symbol = fn.params[index]!;
|
|
90
|
+
const parameter = parameterNodes[index];
|
|
91
|
+
if (parameter?.dotDotDotToken) {
|
|
92
|
+
const rest = this.reg();
|
|
93
|
+
this.emit(` ${rest} = call i64 @xt_rest_args(i32 %argc, i64* %argv, i32 ${index})`);
|
|
94
|
+
this.declareSlot(symbol, rest);
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
const value = this.reg();
|
|
98
|
+
this.emit(` ${value} = call i64 @xt_arg(i32 %argc, i64* %argv, i32 ${index})`);
|
|
99
|
+
this.declareSlot(symbol, value);
|
|
100
|
+
if (parameter?.initializer) this.emitDefaultParameter(symbol, value, parameter.initializer);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Captures threaded through the environment.
|
|
104
|
+
for (const symbol of fn.captures) {
|
|
105
|
+
if (this.moduleGlobals.has(symbol.id)) continue;
|
|
106
|
+
const index = fn.captureIndex.get(symbol.id)!;
|
|
107
|
+
const value = this.reg();
|
|
108
|
+
this.emit(` ${value} = call i64 @xt_closure_env(i64 %env, i32 ${index})`);
|
|
109
|
+
this.defineCaptureSlot(symbol, value);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// Arrow functions inherit `this` lexically; it travels as an extra capture.
|
|
113
|
+
if (fn.isArrow && fn.capturesThis) {
|
|
114
|
+
const inherited = this.reg();
|
|
115
|
+
this.emit(` ${inherited} = call i64 @xt_closure_env(i64 %env, i32 ${fn.captures.length})`);
|
|
116
|
+
this.emit(` store i64 ${inherited}, i64* %saved.this`);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// Instance field initializers run before the constructor body.
|
|
120
|
+
if (fn.isConstructor && fn.classInfo) {
|
|
121
|
+
const thisValue = this.emitThis();
|
|
122
|
+
for (const field of fn.classInfo.fields) {
|
|
123
|
+
if (field.isStatic) continue;
|
|
124
|
+
const key = this.stringValue(field.name);
|
|
125
|
+
const value = field.initializer ? this.emitExpression(field.initializer) : i64(XT_UNDEFINED);
|
|
126
|
+
this.emit(` call i64 @xt_set(i64 ${thisValue}, i64 ${key}, i64 ${value})`);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// Body.
|
|
131
|
+
if (fn.node.kind === SyntaxKind.SourceFile) {
|
|
132
|
+
this.emitStatements(this.sourceFile.statements);
|
|
133
|
+
} else if (fn.node.kind === SyntaxKind.ArrowFunction && (fn.node as ArrowFunction).body.kind !== SyntaxKind.Block) {
|
|
134
|
+
const value = this.emitExpression((fn.node as ArrowFunction).body as Expression);
|
|
135
|
+
this.terminate(`ret i64 ${fn.isAsync ? this.wrapAsync(value) : value}`);
|
|
136
|
+
} else {
|
|
137
|
+
const body = (fn.node as { body: Block }).body;
|
|
138
|
+
if (body) this.emitStatements(body.statements);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
if (!this.current.terminated) {
|
|
142
|
+
const fallback = fn.isAsync ? this.wrapAsync(i64(XT_UNDEFINED)) : i64(XT_UNDEFINED);
|
|
143
|
+
this.terminate(`ret i64 ${fallback}`);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
const escapes = state.usesTry
|
|
147
|
+
? state.escapePointers.map((ptr) => ` call void asm sideeffect "", "r"(i64* ${ptr})`)
|
|
148
|
+
: [];
|
|
149
|
+
const lines = [...state.allocas.map((a) => ` ${a}`), ...escapes, ...state.buffer];
|
|
150
|
+
this.functions.push([header, ...lines, "}", ""].join("\n"));
|
|
151
|
+
},
|
|
152
|
+
|
|
153
|
+
emitMain(): void {
|
|
154
|
+
const moduleName = this.functionName(this.binding.moduleFunction);
|
|
155
|
+
this.functions.push(
|
|
156
|
+
[
|
|
157
|
+
"define i32 @main(i32 %argc, i8** %argv) {",
|
|
158
|
+
` %result = call i64 @${moduleName}(i64 ${i64(XT_UNDEFINED)}, i64 ${i64(XT_UNDEFINED)}, i32 0, i64* null)`,
|
|
159
|
+
" call void @xt_drain_microtasks()",
|
|
160
|
+
" ret i32 0",
|
|
161
|
+
"}",
|
|
162
|
+
"",
|
|
163
|
+
].join("\n"),
|
|
164
|
+
);
|
|
165
|
+
},
|
|
166
|
+
|
|
167
|
+
functionName(fn: FunctionInfo): string {
|
|
168
|
+
return fn.isModule ? "xt_module" : `xt_fn_${fn.id}`;
|
|
169
|
+
},
|
|
170
|
+
|
|
171
|
+
/** Wrap a returned value in a resolved promise (for `async` functions). */
|
|
172
|
+
wrapAsync(value: string): string {
|
|
173
|
+
const result = this.reg();
|
|
174
|
+
this.emit(` ${result} = call i64 @xt_promise_resolve(i64 ${value})`);
|
|
175
|
+
return result;
|
|
176
|
+
},
|
|
177
|
+
|
|
178
|
+
classGlobal(classInfo: ClassInfo): string {
|
|
179
|
+
const existing = this.classGlobals.get(classInfo.id);
|
|
180
|
+
if (existing) return existing;
|
|
181
|
+
const name = `@class.${classInfo.id}`;
|
|
182
|
+
this.classGlobals.set(classInfo.id, name);
|
|
183
|
+
this.globals.push(`${name} = internal global i64 0`);
|
|
184
|
+
return name;
|
|
185
|
+
},
|
|
186
|
+
|
|
187
|
+
emitClassReference(classInfo: ClassInfo): string {
|
|
188
|
+
const globalName = this.classGlobal(classInfo);
|
|
189
|
+
const value = this.reg();
|
|
190
|
+
this.emit(` ${value} = load i64, i64* ${globalName}`);
|
|
191
|
+
return value;
|
|
192
|
+
},
|
|
193
|
+
|
|
194
|
+
/** Build a class value (constructor closure + prototype) and store it in its global. */
|
|
195
|
+
emitClassSetup(classInfo: ClassInfo): void {
|
|
196
|
+
const globalName = this.classGlobal(classInfo);
|
|
197
|
+
const proto = this.reg();
|
|
198
|
+
this.emit(` ${proto} = call i64 @xt_object_new()`);
|
|
199
|
+
if (classInfo.parentExpression) {
|
|
200
|
+
const parent = this.emitExpression(classInfo.parentExpression);
|
|
201
|
+
const parentProto = this.reg();
|
|
202
|
+
this.emit(` ${parentProto} = call i64 @xt_function_get_prototype(i64 ${parent})`);
|
|
203
|
+
this.emit(` call i64 @xt_object_set_prototype(i64 ${proto}, i64 ${parentProto})`);
|
|
204
|
+
}
|
|
205
|
+
for (const method of classInfo.methods) {
|
|
206
|
+
const fnValue = this.emitClosureValue(method);
|
|
207
|
+
const key = this.stringValue(method.name);
|
|
208
|
+
this.emit(` call i64 @xt_set(i64 ${proto}, i64 ${key}, i64 ${fnValue})`);
|
|
209
|
+
}
|
|
210
|
+
const ctor = this.emitClosureValue(classInfo.ctor!);
|
|
211
|
+
this.emit(` call i64 @xt_function_set_prototype(i64 ${ctor}, i64 ${proto})`);
|
|
212
|
+
const ctorKey = this.stringValue("__ctor");
|
|
213
|
+
this.emit(` call i64 @xt_set(i64 ${proto}, i64 ${ctorKey}, i64 ${ctor})`);
|
|
214
|
+
for (const method of classInfo.statics) {
|
|
215
|
+
const fnValue = this.emitClosureValue(method);
|
|
216
|
+
const key = this.stringValue(method.name);
|
|
217
|
+
this.emit(` call i64 @xt_set(i64 ${ctor}, i64 ${key}, i64 ${fnValue})`);
|
|
218
|
+
}
|
|
219
|
+
for (const field of classInfo.fields) {
|
|
220
|
+
if (!field.isStatic) continue;
|
|
221
|
+
const key = this.stringValue(field.name);
|
|
222
|
+
const value = field.initializer ? this.emitExpression(field.initializer) : i64(XT_UNDEFINED);
|
|
223
|
+
this.emit(` call i64 @xt_set(i64 ${ctor}, i64 ${key}, i64 ${value})`);
|
|
224
|
+
}
|
|
225
|
+
this.emit(` store i64 ${ctor}, i64* ${globalName}`);
|
|
226
|
+
},
|
|
227
|
+
|
|
228
|
+
emitDefaultParameter(symbol: SymbolInfo, value: string, initializer: Expression): void {
|
|
229
|
+
const isUndefined = this.reg();
|
|
230
|
+
this.emit(` ${isUndefined} = call i64 @xt_seq(i64 ${value}, i64 ${i64(XT_UNDEFINED)})`);
|
|
231
|
+
const truthy = this.reg();
|
|
232
|
+
this.emit(` ${truthy} = call i32 @xt_truthy(i64 ${isUndefined})`);
|
|
233
|
+
const condition = this.reg();
|
|
234
|
+
this.emit(` ${condition} = icmp ne i32 ${truthy}, 0`);
|
|
235
|
+
const applyLabel = this.label("param.default");
|
|
236
|
+
const endLabel = this.label("param.end");
|
|
237
|
+
this.terminate(`br i1 ${condition}, label %${applyLabel}, label %${endLabel}`);
|
|
238
|
+
this.startBlock(applyLabel);
|
|
239
|
+
const fallback = this.emitExpression(initializer);
|
|
240
|
+
this.writeSlot(symbol, fallback);
|
|
241
|
+
this.terminate(`br label %${endLabel}`);
|
|
242
|
+
this.startBlock(endLabel);
|
|
243
|
+
},
|
|
244
|
+
};
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared state types and the runtime declaration list for the LLVM generator.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import type { FunctionInfo } from "../../binder/binder.js";
|
|
6
|
+
import type { BindResult } from "../../binder/binder.js";
|
|
7
|
+
import type { BuiltinFunction } from "../../extensions/registry.js";
|
|
8
|
+
|
|
9
|
+
export interface Slot {
|
|
10
|
+
/** Register holding the `i64*` to the storage. */
|
|
11
|
+
readonly ptr: string;
|
|
12
|
+
readonly boxed: boolean;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface LoopLabels {
|
|
16
|
+
readonly breakLabel: string;
|
|
17
|
+
readonly continueLabel: string;
|
|
18
|
+
/** Number of enclosing `try` frames when the loop was entered. */
|
|
19
|
+
readonly tryDepth?: number;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface FunctionState {
|
|
23
|
+
readonly fn: FunctionInfo;
|
|
24
|
+
readonly buffer: string[];
|
|
25
|
+
readonly allocas: string[];
|
|
26
|
+
readonly slots: Map<number, Slot>;
|
|
27
|
+
reg: number;
|
|
28
|
+
label: number;
|
|
29
|
+
terminated: boolean;
|
|
30
|
+
readonly loops: LoopLabels[];
|
|
31
|
+
readonly tryFrames: string[];
|
|
32
|
+
readonly escapePointers: string[];
|
|
33
|
+
/** Alloca holding the `this` binding for the current function. */
|
|
34
|
+
thisPtr?: string;
|
|
35
|
+
/** Set when the function contains a `try`, forcing locals to live in memory. */
|
|
36
|
+
usesTry: boolean;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export interface CodegenResult {
|
|
40
|
+
readonly ir: string;
|
|
41
|
+
readonly binding: BindResult;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export interface CodegenOptions {
|
|
45
|
+
/** Global names supplied by registered extensions. */
|
|
46
|
+
readonly builtins?: Readonly<Record<string, BuiltinFunction>>;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export const RUNTIME_DECLARATIONS: readonly string[] = [
|
|
50
|
+
"declare i64 @xt_undefined()",
|
|
51
|
+
"declare i64 @xt_null()",
|
|
52
|
+
"declare i64 @xt_bool(i32)",
|
|
53
|
+
"declare i64 @xt_number(double)",
|
|
54
|
+
"declare i64 @xt_string_new(i8*, i64)",
|
|
55
|
+
"declare i64 @xt_string_from_cstr(i8*)",
|
|
56
|
+
"declare i64 @xt_arg(i32, i64*, i32)",
|
|
57
|
+
"declare i64 @xt_closure_new(i8*, i32, i64*)",
|
|
58
|
+
"declare i64 @xt_closure_call(i64, i32, i64*)",
|
|
59
|
+
"declare i64 @xt_closure_env(i64, i32)",
|
|
60
|
+
"declare i64 @xt_call_with_this(i64, i64, i32, i64*)",
|
|
61
|
+
"declare i64 @xt_this()",
|
|
62
|
+
"declare i64 @xt_new(i64, i32, i64*)",
|
|
63
|
+
"declare i64 @xt_instance_of(i64, i64)",
|
|
64
|
+
"declare i64 @xt_function_set_prototype(i64, i64)",
|
|
65
|
+
"declare i64 @xt_function_get_prototype(i64)",
|
|
66
|
+
"declare i64 @xt_object_new_with_proto(i64)",
|
|
67
|
+
"declare i64 @xt_object_get_prototype(i64)",
|
|
68
|
+
"declare i64 @xt_object_set_prototype(i64, i64)",
|
|
69
|
+
"declare i64 @xt_await(i64)",
|
|
70
|
+
"declare void @xt_drain_microtasks()",
|
|
71
|
+
"declare i64 @xt_promise_resolve(i64)",
|
|
72
|
+
"declare i64 @xt_promise_reject(i64)",
|
|
73
|
+
"declare i64 @xt_promise_ctor(i32, i64*)",
|
|
74
|
+
"declare i64 @xt_promise_static(i64, i32, i64*)",
|
|
75
|
+
"declare i64 @xt_array_static(i64, i32, i64*)",
|
|
76
|
+
"declare i64 @xt_object_static(i64, i32, i64*)",
|
|
77
|
+
"declare i64 @xt_number_static(i64, i32, i64*)",
|
|
78
|
+
"declare i64 @xt_string_static(i64, i32, i64*)",
|
|
79
|
+
"declare i64 @xt_date_static(i64, i32, i64*)",
|
|
80
|
+
"declare i64 @xt_map_ctor(i32, i64*)",
|
|
81
|
+
"declare i64 @xt_set_ctor(i32, i64*)",
|
|
82
|
+
"declare i64 @xt_date_ctor(i32, i64*)",
|
|
83
|
+
"declare i64 @xt_regexp_ctor(i32, i64*)",
|
|
84
|
+
"declare i64 @xt_json_parse(i32, i64*)",
|
|
85
|
+
"declare i64 @xt_json_stringify(i32, i64*)",
|
|
86
|
+
"declare i64 @xt_object_from_entries(i64)",
|
|
87
|
+
"declare i64 @xt_object_freeze(i64)",
|
|
88
|
+
"declare i32 @xt_object_is_frozen(i64)",
|
|
89
|
+
"declare i64 @xt_object_has_own(i64, i64)",
|
|
90
|
+
"declare i64 @xt_console_dir(i32, i64*)",
|
|
91
|
+
"declare i64 @xt_console_trace(i32, i64*)",
|
|
92
|
+
"declare i64 @xt_console_assert(i32, i64*)",
|
|
93
|
+
"declare i64 @xt_console_count(i32, i64*)",
|
|
94
|
+
"declare i64 @xt_console_count_reset(i32, i64*)",
|
|
95
|
+
"declare i64 @xt_console_group(i32, i64*)",
|
|
96
|
+
"declare i64 @xt_console_group_end(i32, i64*)",
|
|
97
|
+
"declare i64 @xt_console_table(i32, i64*)",
|
|
98
|
+
"declare i64 @xt_console_time(i32, i64*)",
|
|
99
|
+
"declare i64 @xt_console_time_end(i32, i64*)",
|
|
100
|
+
"declare i64 @xt_console_time_log(i32, i64*)",
|
|
101
|
+
"declare i32 @xt_truthy(i64)",
|
|
102
|
+
"declare double @xt_to_number(i64)",
|
|
103
|
+
"declare i64 @xt_to_string(i64)",
|
|
104
|
+
"declare i64 @xt_typeof(i64)",
|
|
105
|
+
"declare i64 @xt_add(i64, i64)",
|
|
106
|
+
"declare i64 @xt_sub(i64, i64)",
|
|
107
|
+
"declare i64 @xt_mul(i64, i64)",
|
|
108
|
+
"declare i64 @xt_div(i64, i64)",
|
|
109
|
+
"declare i64 @xt_mod(i64, i64)",
|
|
110
|
+
"declare i64 @xt_pow(i64, i64)",
|
|
111
|
+
"declare i64 @xt_neg(i64)",
|
|
112
|
+
"declare i64 @xt_pos(i64)",
|
|
113
|
+
"declare i64 @xt_bit_and(i64, i64)",
|
|
114
|
+
"declare i64 @xt_bit_or(i64, i64)",
|
|
115
|
+
"declare i64 @xt_bit_xor(i64, i64)",
|
|
116
|
+
"declare i64 @xt_bit_not(i64)",
|
|
117
|
+
"declare i64 @xt_shl(i64, i64)",
|
|
118
|
+
"declare i64 @xt_shr(i64, i64)",
|
|
119
|
+
"declare i64 @xt_ushr(i64, i64)",
|
|
120
|
+
"declare i64 @xt_lt(i64, i64)",
|
|
121
|
+
"declare i64 @xt_le(i64, i64)",
|
|
122
|
+
"declare i64 @xt_gt(i64, i64)",
|
|
123
|
+
"declare i64 @xt_ge(i64, i64)",
|
|
124
|
+
"declare i64 @xt_eq(i64, i64)",
|
|
125
|
+
"declare i64 @xt_ne(i64, i64)",
|
|
126
|
+
"declare i64 @xt_seq(i64, i64)",
|
|
127
|
+
"declare i64 @xt_sne(i64, i64)",
|
|
128
|
+
"declare i64 @xt_not(i64)",
|
|
129
|
+
"declare i64 @xt_object_new()",
|
|
130
|
+
"declare i64 @xt_object_get_cstr(i64, i8*)",
|
|
131
|
+
"declare i64 @xt_object_set(i64, i64, i64)",
|
|
132
|
+
"declare i64 @xt_object_has(i64, i64)",
|
|
133
|
+
"declare i64 @xt_object_keys(i64)",
|
|
134
|
+
"declare i64 @xt_object_values(i64)",
|
|
135
|
+
"declare i64 @xt_object_entries(i64)",
|
|
136
|
+
"declare i64 @xt_object_assign(i32, i64*)",
|
|
137
|
+
"declare i64 @xt_object_spread(i64, i64)",
|
|
138
|
+
"declare i64 @xt_call_method(i64, i64, i32, i64*)",
|
|
139
|
+
"declare i64 @xt_math_call(i64, i32, i64*)",
|
|
140
|
+
"declare i64 @xt_parse_int(i32, i64*)",
|
|
141
|
+
"declare i64 @xt_parse_float(i32, i64*)",
|
|
142
|
+
"declare i64 @xt_is_nan(i32, i64*)",
|
|
143
|
+
"declare i64 @xt_is_finite(i32, i64*)",
|
|
144
|
+
"declare i64 @xt_number_ctor(i32, i64*)",
|
|
145
|
+
"declare i64 @xt_string_ctor(i32, i64*)",
|
|
146
|
+
"declare i64 @xt_boolean_ctor(i32, i64*)",
|
|
147
|
+
"declare i64 @xt_in(i64, i64)",
|
|
148
|
+
"declare i64 @xt_delete(i64, i64)",
|
|
149
|
+
"declare i64 @xt_rest_args(i32, i64*, i32)",
|
|
150
|
+
"declare i64 @xt_array_new(i32, i64*)",
|
|
151
|
+
"declare i64 @xt_array_push(i64, i64)",
|
|
152
|
+
"declare i64 @xt_array_length(i64)",
|
|
153
|
+
"declare i64 @xt_array_spread(i64, i64)",
|
|
154
|
+
"declare i64 @xt_get(i64, i64)",
|
|
155
|
+
"declare i64 @xt_set(i64, i64, i64)",
|
|
156
|
+
"declare i64 @xt_box_new(i64)",
|
|
157
|
+
"declare i64 @xt_box_get(i64)",
|
|
158
|
+
"declare i64 @xt_box_set(i64, i64)",
|
|
159
|
+
"declare i64 @xt_is_nullish(i64)",
|
|
160
|
+
"declare void @xt_throw(i64)",
|
|
161
|
+
"declare i32 @_setjmp(i8*) returns_twice",
|
|
162
|
+
"declare i8* @xt_try_enter()",
|
|
163
|
+
"declare i64 @xt_try_exception(i8*)",
|
|
164
|
+
"declare void @xt_try_leave(i8*)",
|
|
165
|
+
"declare void @xt_console_log(i32, i64*)",
|
|
166
|
+
"declare void @xt_console_info(i32, i64*)",
|
|
167
|
+
"declare void @xt_console_warn(i32, i64*)",
|
|
168
|
+
"declare void @xt_console_error(i32, i64*)",
|
|
169
|
+
];
|