gofront 1.4.0 → 1.6.0
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 +174 -403
- package/package.json +16 -19
- package/src/{codegen → backend/js}/expressions.js +265 -77
- package/src/{codegen → backend/js}/index.js +120 -89
- package/src/{codegen → backend/js}/runtime.js +102 -0
- package/src/{codegen → backend/js}/source-map.js +32 -0
- package/src/{codegen → backend/js}/statements.js +139 -64
- package/src/backend/js/stdlib/bits.js +32 -0
- package/src/{codegen → backend/js}/stdlib/errors.js +2 -2
- package/src/{codegen → backend/js}/stdlib/fmt.js +26 -8
- package/src/{codegen → backend/js}/stdlib/index.js +6 -0
- package/src/{codegen → backend/js}/stdlib/maps.js +1 -1
- package/src/{codegen → backend/js}/stdlib/path.js +2 -2
- package/src/backend/js/stdlib/shared.js +17 -0
- package/src/{codegen → backend/js}/stdlib/slices.js +1 -1
- package/src/{codegen → backend/js}/stdlib/sort.js +1 -1
- package/src/backend/js/stdlib/strconv.js +58 -0
- package/src/{codegen → backend/js}/stdlib/strings.js +4 -1
- package/src/{codegen → backend/js}/stdlib/testing.js +2 -2
- package/src/{codegen → backend/js}/stdlib/time.js +3 -3
- package/src/{codegen → backend/js}/templ.js +3 -3
- package/src/backend/wasm/boundary.js +1798 -0
- package/src/backend/wasm/emit-builtins.js +1103 -0
- package/src/backend/wasm/emit-exprs.js +1908 -0
- package/src/backend/wasm/emit-maps.js +1863 -0
- package/src/backend/wasm/emit-shared.js +519 -0
- package/src/backend/wasm/emit-stdlib.js +3006 -0
- package/src/backend/wasm/emit-stmts.js +2472 -0
- package/src/backend/wasm/emit.js +1376 -0
- package/src/backend/wasm/encode.js +937 -0
- package/src/backend/wasm/glue.js +144 -0
- package/src/backend/wasm/index.js +2790 -0
- package/src/backend/wasm/monomorph.js +711 -0
- package/src/backend/wasm/optimize.js +227 -0
- package/src/backend/wasm/types.js +544 -0
- package/src/backend/wasm/wat.js +302 -0
- package/src/cli-core.js +323 -75
- package/src/compiler.js +447 -14
- package/src/dev-server.js +56 -15
- package/src/index.js +99 -120
- package/src/lexer.js +18 -0
- package/src/lower/boxing.js +35 -0
- package/src/lower/captures.js +172 -0
- package/src/lower/embedding.js +30 -0
- package/src/lower/escape.js +164 -0
- package/src/lower/functions.js +302 -0
- package/src/lower/globals.js +316 -0
- package/src/lower/index.js +118 -0
- package/src/lower/ownership.js +137 -0
- package/src/lower/range.js +67 -0
- package/src/lower/walk.js +25 -0
- package/src/minifier.js +2 -0
- package/src/parser/index.js +8 -3
- package/src/resolver.js +3 -1
- package/src/test-runner.js +94 -20
- package/src/typechecker/assignability.js +42 -1
- package/src/typechecker/expressions.js +182 -3
- package/src/typechecker/index.js +261 -5
- package/src/typechecker/resolve.js +35 -6
- package/src/typechecker/stdlib/core.js +34 -19
- package/src/typechecker/stdlib/extended.js +18 -3
- package/src/typechecker/stdlib/shared.js +53 -0
- package/src/typechecker/stdlib.js +2 -0
- package/src/typechecker/types.js +259 -6
- package/src/vendor.js +2 -2
- package/src/codegen/stdlib/strconv.js +0 -33
- /package/src/{codegen → backend/js}/stdlib/builder.js +0 -0
- /package/src/{codegen → backend/js}/stdlib/bytes.js +0 -0
- /package/src/{codegen → backend/js}/stdlib/gom.js +0 -0
- /package/src/{codegen → backend/js}/stdlib/html.js +0 -0
- /package/src/{codegen → backend/js}/stdlib/io.js +0 -0
- /package/src/{codegen → backend/js}/stdlib/math.js +0 -0
- /package/src/{codegen → backend/js}/stdlib/os.js +0 -0
- /package/src/{codegen → backend/js}/stdlib/rand.js +0 -0
- /package/src/{codegen → backend/js}/stdlib/regexp.js +0 -0
- /package/src/{codegen → backend/js}/stdlib/unicode.js +0 -0
- /package/src/{codegen → backend/js}/stdlib/utf8.js +0 -0
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
// src/backend/wasm/glue.js
|
|
2
|
+
// Runtime imports and JS glue for executing GoFront WASM modules.
|
|
3
|
+
|
|
4
|
+
import { WASM_IMPORTS_JS, WASM_STDLIB_JS } from "./boundary.js";
|
|
5
|
+
|
|
6
|
+
// The import table is authored once as source text (it is spliced into the
|
|
7
|
+
// production bundle by the facade); evaluate that same text here so tests
|
|
8
|
+
// exercise exactly what ships. The text is a compile-time constant.
|
|
9
|
+
const makeImports = new Function(
|
|
10
|
+
`${WASM_IMPORTS_JS}\n${WASM_STDLIB_JS}\nreturn __gfw_imports;`,
|
|
11
|
+
)();
|
|
12
|
+
|
|
13
|
+
function createWasmImports({
|
|
14
|
+
stringTable = [],
|
|
15
|
+
panicTag = null,
|
|
16
|
+
stdout = null,
|
|
17
|
+
extra = {},
|
|
18
|
+
} = {}) {
|
|
19
|
+
const tag = panicTag ?? new WebAssembly.Tag({ parameters: ["externref"] });
|
|
20
|
+
const write = stdout ?? ((s) => console.log(s));
|
|
21
|
+
const { env: _ignored, Math: extraMath, ...extraModules } = extra;
|
|
22
|
+
const imports = makeImports(stringTable, extra.env ?? {}, tag, write);
|
|
23
|
+
Object.assign(imports.Math, extraMath);
|
|
24
|
+
Object.assign(imports, extraModules);
|
|
25
|
+
return { imports, panicTag: tag };
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const NIL_DEREF_PATTERNS = [
|
|
29
|
+
"dereferencing a null pointer", // V8
|
|
30
|
+
"dereferencing null pointer", // SpiderMonkey
|
|
31
|
+
"null pointer dereference", // SpiderMonkey
|
|
32
|
+
"null dereference", // JavaScriptCore
|
|
33
|
+
];
|
|
34
|
+
|
|
35
|
+
function safeString(v) {
|
|
36
|
+
try {
|
|
37
|
+
return String(v);
|
|
38
|
+
} catch {
|
|
39
|
+
return "[panic object]";
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function isNilDerefTrap(e) {
|
|
44
|
+
if (
|
|
45
|
+
typeof WebAssembly !== "undefined" &&
|
|
46
|
+
e instanceof WebAssembly.RuntimeError
|
|
47
|
+
) {
|
|
48
|
+
const msg = e.message || "";
|
|
49
|
+
return NIL_DEREF_PATTERNS.some((p) => msg.includes(p));
|
|
50
|
+
}
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export function instantiateWasm(
|
|
55
|
+
wasmBytes,
|
|
56
|
+
{ stringTable = [], stdout = null, extraImports = {} } = {},
|
|
57
|
+
) {
|
|
58
|
+
const { imports, panicTag: defaultPanicTag } = createWasmImports({
|
|
59
|
+
stringTable,
|
|
60
|
+
stdout,
|
|
61
|
+
extra: extraImports,
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
const module = new WebAssembly.Module(wasmBytes);
|
|
65
|
+
const instance = new WebAssembly.Instance(module, imports);
|
|
66
|
+
imports.__bind?.(instance.exports);
|
|
67
|
+
|
|
68
|
+
// The module exports its panic tag if defined internally, or uses the imported one
|
|
69
|
+
const tag = instance.exports.panicTag ?? defaultPanicTag;
|
|
70
|
+
|
|
71
|
+
// Wrap exports to convert WASM panic exceptions into standard JS Errors
|
|
72
|
+
const wrappedExports = {};
|
|
73
|
+
for (const [name, val] of Object.entries(instance.exports)) {
|
|
74
|
+
if (typeof val === "function") {
|
|
75
|
+
wrappedExports[name] = (...args) => {
|
|
76
|
+
let cur = [...args];
|
|
77
|
+
for (let attempt = 0; attempt <= cur.length; attempt++) {
|
|
78
|
+
try {
|
|
79
|
+
return val(...cur);
|
|
80
|
+
} catch (e) {
|
|
81
|
+
if (instance.exports.__panic) {
|
|
82
|
+
instance.exports.__panic.value = null;
|
|
83
|
+
}
|
|
84
|
+
if (tag && e instanceof WebAssembly.Exception && e.is(tag)) {
|
|
85
|
+
const msg = e.getArg(tag, 0);
|
|
86
|
+
throw new Error(safeString(msg));
|
|
87
|
+
}
|
|
88
|
+
if (isNilDerefTrap(e)) {
|
|
89
|
+
throw new Error(
|
|
90
|
+
"runtime error: invalid memory address or nil pointer dereference",
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
if (e instanceof TypeError && e.message.includes("to a BigInt")) {
|
|
94
|
+
let coercedAny = false;
|
|
95
|
+
for (let j = 0; j < cur.length; j++) {
|
|
96
|
+
if (typeof cur[j] === "number" && Number.isInteger(cur[j])) {
|
|
97
|
+
const testArgs = [...cur];
|
|
98
|
+
testArgs[j] = BigInt(testArgs[j]);
|
|
99
|
+
try {
|
|
100
|
+
return val(...testArgs);
|
|
101
|
+
} catch (inner) {
|
|
102
|
+
if (
|
|
103
|
+
tag &&
|
|
104
|
+
inner instanceof WebAssembly.Exception &&
|
|
105
|
+
inner.is(tag)
|
|
106
|
+
) {
|
|
107
|
+
const msg = inner.getArg(tag, 0);
|
|
108
|
+
throw new Error(safeString(msg));
|
|
109
|
+
}
|
|
110
|
+
if (isNilDerefTrap(inner)) {
|
|
111
|
+
throw new Error(
|
|
112
|
+
"runtime error: invalid memory address or nil pointer dereference",
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
if (
|
|
116
|
+
inner instanceof TypeError &&
|
|
117
|
+
inner.message.includes("to a BigInt")
|
|
118
|
+
) {
|
|
119
|
+
cur = testArgs;
|
|
120
|
+
coercedAny = true;
|
|
121
|
+
break;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
if (!coercedAny) throw e;
|
|
127
|
+
} else {
|
|
128
|
+
throw e;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
} else {
|
|
134
|
+
wrappedExports[name] = val;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
return {
|
|
139
|
+
instance,
|
|
140
|
+
module,
|
|
141
|
+
exports: wrappedExports,
|
|
142
|
+
rawExports: instance.exports,
|
|
143
|
+
};
|
|
144
|
+
}
|