gofront 1.4.0 → 1.5.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.
Files changed (61) hide show
  1. package/README.md +72 -9
  2. package/package.json +2 -1
  3. package/src/{codegen → backend/js}/expressions.js +217 -60
  4. package/src/{codegen → backend/js}/index.js +21 -35
  5. package/src/{codegen → backend/js}/statements.js +43 -48
  6. package/src/backend/js/stdlib/bits.js +32 -0
  7. package/src/{codegen → backend/js}/stdlib/index.js +3 -0
  8. package/src/{codegen → backend/js}/templ.js +2 -2
  9. package/src/backend/wasm/boundary.js +1345 -0
  10. package/src/backend/wasm/emit.js +5779 -0
  11. package/src/backend/wasm/encode.js +789 -0
  12. package/src/backend/wasm/glue.js +130 -0
  13. package/src/backend/wasm/index.js +1413 -0
  14. package/src/backend/wasm/types.js +420 -0
  15. package/src/backend/wasm/wat.js +255 -0
  16. package/src/cli-core.js +52 -7
  17. package/src/compiler.js +322 -12
  18. package/src/dev-server.js +56 -15
  19. package/src/index.js +17 -9
  20. package/src/lexer.js +18 -0
  21. package/src/lower/boxing.js +36 -0
  22. package/src/lower/captures.js +179 -0
  23. package/src/lower/embedding.js +30 -0
  24. package/src/lower/escape.js +169 -0
  25. package/src/lower/functions.js +30 -0
  26. package/src/lower/globals.js +324 -0
  27. package/src/lower/index.js +115 -0
  28. package/src/lower/ownership.js +142 -0
  29. package/src/lower/range.js +70 -0
  30. package/src/minifier.js +2 -0
  31. package/src/parser/index.js +8 -3
  32. package/src/resolver.js +1 -0
  33. package/src/test-runner.js +74 -20
  34. package/src/typechecker/expressions.js +40 -1
  35. package/src/typechecker/index.js +234 -4
  36. package/src/typechecker/statements.js +7 -0
  37. package/src/typechecker/stdlib/core.js +17 -0
  38. package/src/typechecker/types.js +56 -2
  39. /package/src/{codegen → backend/js}/runtime.js +0 -0
  40. /package/src/{codegen → backend/js}/source-map.js +0 -0
  41. /package/src/{codegen → backend/js}/stdlib/builder.js +0 -0
  42. /package/src/{codegen → backend/js}/stdlib/bytes.js +0 -0
  43. /package/src/{codegen → backend/js}/stdlib/errors.js +0 -0
  44. /package/src/{codegen → backend/js}/stdlib/fmt.js +0 -0
  45. /package/src/{codegen → backend/js}/stdlib/gom.js +0 -0
  46. /package/src/{codegen → backend/js}/stdlib/html.js +0 -0
  47. /package/src/{codegen → backend/js}/stdlib/io.js +0 -0
  48. /package/src/{codegen → backend/js}/stdlib/maps.js +0 -0
  49. /package/src/{codegen → backend/js}/stdlib/math.js +0 -0
  50. /package/src/{codegen → backend/js}/stdlib/os.js +0 -0
  51. /package/src/{codegen → backend/js}/stdlib/path.js +0 -0
  52. /package/src/{codegen → backend/js}/stdlib/rand.js +0 -0
  53. /package/src/{codegen → backend/js}/stdlib/regexp.js +0 -0
  54. /package/src/{codegen → backend/js}/stdlib/slices.js +0 -0
  55. /package/src/{codegen → backend/js}/stdlib/sort.js +0 -0
  56. /package/src/{codegen → backend/js}/stdlib/strconv.js +0 -0
  57. /package/src/{codegen → backend/js}/stdlib/strings.js +0 -0
  58. /package/src/{codegen → backend/js}/stdlib/testing.js +0 -0
  59. /package/src/{codegen → backend/js}/stdlib/time.js +0 -0
  60. /package/src/{codegen → backend/js}/stdlib/unicode.js +0 -0
  61. /package/src/{codegen → backend/js}/stdlib/utf8.js +0 -0
@@ -0,0 +1,130 @@
1
+ // src/backend/wasm/glue.js
2
+ // Runtime imports and JS glue for executing GoFront WASM modules.
3
+
4
+ import { WASM_IMPORTS_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(`${WASM_IMPORTS_JS}\nreturn __gfw_imports;`)();
10
+
11
+ export function createWasmImports({
12
+ stringTable = [],
13
+ panicTag = null,
14
+ stdout = null,
15
+ extra = {},
16
+ } = {}) {
17
+ const tag = panicTag ?? new WebAssembly.Tag({ parameters: ["externref"] });
18
+ const write = stdout ?? ((s) => console.log(s));
19
+ const { env: _ignored, Math: extraMath, ...extraModules } = extra;
20
+ const imports = makeImports(stringTable, extra.env ?? {}, tag, write);
21
+ Object.assign(imports.Math, extraMath);
22
+ Object.assign(imports, extraModules);
23
+ return { imports, panicTag: tag };
24
+ }
25
+
26
+ const NIL_DEREF_PATTERNS = [
27
+ "dereferencing a null pointer", // V8
28
+ "dereferencing null pointer", // SpiderMonkey
29
+ "null pointer dereference", // SpiderMonkey
30
+ "null dereference", // JavaScriptCore
31
+ ];
32
+
33
+ function isNilDerefTrap(e) {
34
+ if (
35
+ typeof WebAssembly !== "undefined" &&
36
+ e instanceof WebAssembly.RuntimeError
37
+ ) {
38
+ const msg = e.message || "";
39
+ return NIL_DEREF_PATTERNS.some((p) => msg.includes(p));
40
+ }
41
+ return false;
42
+ }
43
+
44
+ export function instantiateWasm(
45
+ wasmBytes,
46
+ { stringTable = [], stdout = null, extraImports = {} } = {},
47
+ ) {
48
+ const { imports, panicTag: defaultPanicTag } = createWasmImports({
49
+ stringTable,
50
+ stdout,
51
+ extra: extraImports,
52
+ });
53
+
54
+ const module = new WebAssembly.Module(wasmBytes);
55
+ const instance = new WebAssembly.Instance(module, imports);
56
+
57
+ // The module exports its panic tag if defined internally, or uses the imported one
58
+ const tag = instance.exports.panicTag ?? defaultPanicTag;
59
+
60
+ // Wrap exports to convert WASM panic exceptions into standard JS Errors
61
+ const wrappedExports = {};
62
+ for (const [name, val] of Object.entries(instance.exports)) {
63
+ if (typeof val === "function") {
64
+ wrappedExports[name] = (...args) => {
65
+ let cur = [...args];
66
+ for (let attempt = 0; attempt <= cur.length; attempt++) {
67
+ try {
68
+ return val(...cur);
69
+ } catch (e) {
70
+ if (tag && e instanceof WebAssembly.Exception && e.is(tag)) {
71
+ const msg = e.getArg(tag, 0);
72
+ throw new Error(String(msg));
73
+ }
74
+ if (isNilDerefTrap(e)) {
75
+ throw new Error(
76
+ "runtime error: invalid memory address or nil pointer dereference",
77
+ );
78
+ }
79
+ if (e instanceof TypeError && e.message.includes("to a BigInt")) {
80
+ let coercedAny = false;
81
+ for (let j = 0; j < cur.length; j++) {
82
+ if (typeof cur[j] === "number" && Number.isInteger(cur[j])) {
83
+ const testArgs = [...cur];
84
+ testArgs[j] = BigInt(testArgs[j]);
85
+ try {
86
+ return val(...testArgs);
87
+ } catch (inner) {
88
+ if (
89
+ tag &&
90
+ inner instanceof WebAssembly.Exception &&
91
+ inner.is(tag)
92
+ ) {
93
+ const msg = inner.getArg(tag, 0);
94
+ throw new Error(String(msg));
95
+ }
96
+ if (isNilDerefTrap(inner)) {
97
+ throw new Error(
98
+ "runtime error: invalid memory address or nil pointer dereference",
99
+ );
100
+ }
101
+ if (
102
+ inner instanceof TypeError &&
103
+ inner.message.includes("to a BigInt")
104
+ ) {
105
+ cur = testArgs;
106
+ coercedAny = true;
107
+ break;
108
+ }
109
+ }
110
+ }
111
+ }
112
+ if (!coercedAny) throw e;
113
+ } else {
114
+ throw e;
115
+ }
116
+ }
117
+ }
118
+ };
119
+ } else {
120
+ wrappedExports[name] = val;
121
+ }
122
+ }
123
+
124
+ return {
125
+ instance,
126
+ module,
127
+ exports: wrappedExports,
128
+ rawExports: instance.exports,
129
+ };
130
+ }