@scriptc/compiler 0.0.0 → 0.0.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/LICENSE +202 -0
- package/ambient/package.json +3 -0
- package/ambient/scriptc-node-fallback.d.ts +3001 -0
- package/ambient/scriptc-overrides.d.ts +95 -0
- package/ambient/scriptc.d.ts +74 -0
- package/dist/backend/cc.d.ts +169 -0
- package/dist/backend/cc.js +897 -0
- package/dist/backend/cc.js.map +1 -0
- package/dist/backend/emission/emit-async.d.ts +145 -0
- package/dist/backend/emission/emit-async.js +996 -0
- package/dist/backend/emission/emit-async.js.map +1 -0
- package/dist/backend/emission/emit-exprs.d.ts +3 -0
- package/dist/backend/emission/emit-exprs.js +5947 -0
- package/dist/backend/emission/emit-exprs.js.map +1 -0
- package/dist/backend/emission/emit-island.d.ts +45 -0
- package/dist/backend/emission/emit-island.js +271 -0
- package/dist/backend/emission/emit-island.js.map +1 -0
- package/dist/backend/emission/emit-shapes.d.ts +142 -0
- package/dist/backend/emission/emit-shapes.js +575 -0
- package/dist/backend/emission/emit-shapes.js.map +1 -0
- package/dist/backend/emission/emit-stmts.d.ts +78 -0
- package/dist/backend/emission/emit-stmts.js +960 -0
- package/dist/backend/emission/emit-stmts.js.map +1 -0
- package/dist/backend/emission/emit-types.d.ts +65 -0
- package/dist/backend/emission/emit-types.js +652 -0
- package/dist/backend/emission/emit-types.js.map +1 -0
- package/dist/backend/emission/emit-walkers.d.ts +154 -0
- package/dist/backend/emission/emit-walkers.js +1587 -0
- package/dist/backend/emission/emit-walkers.js.map +1 -0
- package/dist/backend/emission/emitter.d.ts +452 -0
- package/dist/backend/emission/emitter.js +1249 -0
- package/dist/backend/emission/emitter.js.map +1 -0
- package/dist/backend/emission/may-throw.d.ts +15 -0
- package/dist/backend/emission/may-throw.js +250 -0
- package/dist/backend/emission/may-throw.js.map +1 -0
- package/dist/backend/llvm/blocks.d.ts +21 -0
- package/dist/backend/llvm/blocks.js +68 -0
- package/dist/backend/llvm/blocks.js.map +1 -0
- package/dist/backend/llvm/classes.d.ts +84 -0
- package/dist/backend/llvm/classes.js +438 -0
- package/dist/backend/llvm/classes.js.map +1 -0
- package/dist/backend/llvm/dyn.d.ts +123 -0
- package/dist/backend/llvm/dyn.js +2624 -0
- package/dist/backend/llvm/dyn.js.map +1 -0
- package/dist/backend/llvm/emitter.d.ts +3 -0
- package/dist/backend/llvm/emitter.js +10087 -0
- package/dist/backend/llvm/emitter.js.map +1 -0
- package/dist/backend/llvm/shapes.d.ts +78 -0
- package/dist/backend/llvm/shapes.js +754 -0
- package/dist/backend/llvm/shapes.js.map +1 -0
- package/dist/backend/llvm/unsupported.d.ts +6 -0
- package/dist/backend/llvm/unsupported.js +12 -0
- package/dist/backend/llvm/unsupported.js.map +1 -0
- package/dist/backend/llvm/walkers.d.ts +58 -0
- package/dist/backend/llvm/walkers.js +793 -0
- package/dist/backend/llvm/walkers.js.map +1 -0
- package/dist/backend/mangle.d.ts +124 -0
- package/dist/backend/mangle.js +232 -0
- package/dist/backend/mangle.js.map +1 -0
- package/dist/coverage/report.d.ts +64 -0
- package/dist/coverage/report.js +226 -0
- package/dist/coverage/report.js.map +1 -0
- package/dist/diagnostics/diagnostic.d.ts +140 -0
- package/dist/diagnostics/diagnostic.js +458 -0
- package/dist/diagnostics/diagnostic.js.map +1 -0
- package/dist/diagnostics/render.d.ts +11 -0
- package/dist/diagnostics/render.js +58 -0
- package/dist/diagnostics/render.js.map +1 -0
- package/dist/frontend/cjs-lexer.d.ts +20 -0
- package/dist/frontend/cjs-lexer.js +813 -0
- package/dist/frontend/cjs-lexer.js.map +1 -0
- package/dist/frontend/lowering/http2-constants.d.ts +1 -0
- package/dist/frontend/lowering/http2-constants.js +251 -0
- package/dist/frontend/lowering/http2-constants.js.map +1 -0
- package/dist/frontend/lowering/lib-boundary.d.ts +6 -0
- package/dist/frontend/lowering/lib-boundary.js +143 -0
- package/dist/frontend/lowering/lib-boundary.js.map +1 -0
- package/dist/frontend/lowering/lower-assert.d.ts +18 -0
- package/dist/frontend/lowering/lower-assert.js +1269 -0
- package/dist/frontend/lowering/lower-assert.js.map +1 -0
- package/dist/frontend/lowering/lower-builtins.d.ts +511 -0
- package/dist/frontend/lowering/lower-builtins.js +5249 -0
- package/dist/frontend/lowering/lower-builtins.js.map +1 -0
- package/dist/frontend/lowering/lower-calls.d.ts +581 -0
- package/dist/frontend/lowering/lower-calls.js +6281 -0
- package/dist/frontend/lowering/lower-calls.js.map +1 -0
- package/dist/frontend/lowering/lower-classes.d.ts +727 -0
- package/dist/frontend/lowering/lower-classes.js +4701 -0
- package/dist/frontend/lowering/lower-classes.js.map +1 -0
- package/dist/frontend/lowering/lower-comptime.d.ts +53 -0
- package/dist/frontend/lowering/lower-comptime.js +244 -0
- package/dist/frontend/lowering/lower-comptime.js.map +1 -0
- package/dist/frontend/lowering/lower-containers.d.ts +483 -0
- package/dist/frontend/lowering/lower-containers.js +6281 -0
- package/dist/frontend/lowering/lower-containers.js.map +1 -0
- package/dist/frontend/lowering/lower-dgram.d.ts +20 -0
- package/dist/frontend/lowering/lower-dgram.js +319 -0
- package/dist/frontend/lowering/lower-dgram.js.map +1 -0
- package/dist/frontend/lowering/lower-emitter.d.ts +10 -0
- package/dist/frontend/lowering/lower-emitter.js +688 -0
- package/dist/frontend/lowering/lower-emitter.js.map +1 -0
- package/dist/frontend/lowering/lower-enums.d.ts +22 -0
- package/dist/frontend/lowering/lower-enums.js +235 -0
- package/dist/frontend/lowering/lower-enums.js.map +1 -0
- package/dist/frontend/lowering/lower-expando.d.ts +35 -0
- package/dist/frontend/lowering/lower-expando.js +276 -0
- package/dist/frontend/lowering/lower-expando.js.map +1 -0
- package/dist/frontend/lowering/lower-exprs.d.ts +524 -0
- package/dist/frontend/lowering/lower-exprs.js +8099 -0
- package/dist/frontend/lowering/lower-exprs.js.map +1 -0
- package/dist/frontend/lowering/lower-generators.d.ts +50 -0
- package/dist/frontend/lowering/lower-generators.js +421 -0
- package/dist/frontend/lowering/lower-generators.js.map +1 -0
- package/dist/frontend/lowering/lower-inspect.d.ts +20 -0
- package/dist/frontend/lowering/lower-inspect.js +1069 -0
- package/dist/frontend/lowering/lower-inspect.js.map +1 -0
- package/dist/frontend/lowering/lower-island.d.ts +108 -0
- package/dist/frontend/lowering/lower-island.js +650 -0
- package/dist/frontend/lowering/lower-island.js.map +1 -0
- package/dist/frontend/lowering/lower-mixins.d.ts +96 -0
- package/dist/frontend/lowering/lower-mixins.js +534 -0
- package/dist/frontend/lowering/lower-mixins.js.map +1 -0
- package/dist/frontend/lowering/lower-modules.d.ts +135 -0
- package/dist/frontend/lowering/lower-modules.js +1613 -0
- package/dist/frontend/lowering/lower-modules.js.map +1 -0
- package/dist/frontend/lowering/lower-namespaces.d.ts +168 -0
- package/dist/frontend/lowering/lower-namespaces.js +706 -0
- package/dist/frontend/lowering/lower-namespaces.js.map +1 -0
- package/dist/frontend/lowering/lower-server.d.ts +90 -0
- package/dist/frontend/lowering/lower-server.js +3471 -0
- package/dist/frontend/lowering/lower-server.js.map +1 -0
- package/dist/frontend/lowering/lower-stmts.d.ts +361 -0
- package/dist/frontend/lowering/lower-stmts.js +5341 -0
- package/dist/frontend/lowering/lower-stmts.js.map +1 -0
- package/dist/frontend/lowering/lower-stream.d.ts +88 -0
- package/dist/frontend/lowering/lower-stream.js +1533 -0
- package/dist/frontend/lowering/lower-stream.js.map +1 -0
- package/dist/frontend/lowering/lower-test.d.ts +27 -0
- package/dist/frontend/lowering/lower-test.js +353 -0
- package/dist/frontend/lowering/lower-test.js.map +1 -0
- package/dist/frontend/lowering/lowerer.d.ts +1748 -0
- package/dist/frontend/lowering/lowerer.js +6256 -0
- package/dist/frontend/lowering/lowerer.js.map +1 -0
- package/dist/frontend/lowering/surfaces.d.ts +272 -0
- package/dist/frontend/lowering/surfaces.js +1096 -0
- package/dist/frontend/lowering/surfaces.js.map +1 -0
- package/dist/frontend/npm-static.d.ts +55 -0
- package/dist/frontend/npm-static.js +300 -0
- package/dist/frontend/npm-static.js.map +1 -0
- package/dist/frontend/npm.d.ts +330 -0
- package/dist/frontend/npm.js +1259 -0
- package/dist/frontend/npm.js.map +1 -0
- package/dist/frontend/program.d.ts +186 -0
- package/dist/frontend/program.js +2172 -0
- package/dist/frontend/program.js.map +1 -0
- package/dist/frontend/provenance-registry.d.ts +48 -0
- package/dist/frontend/provenance-registry.js +87 -0
- package/dist/frontend/provenance-registry.js.map +1 -0
- package/dist/frontend/provenance.d.ts +6 -0
- package/dist/frontend/provenance.js +459 -0
- package/dist/frontend/provenance.js.map +1 -0
- package/dist/frontend/resolve.d.ts +56 -0
- package/dist/frontend/resolve.js +682 -0
- package/dist/frontend/resolve.js.map +1 -0
- package/dist/frontend/shared.d.ts +60 -0
- package/dist/frontend/shared.js +232 -0
- package/dist/frontend/shared.js.map +1 -0
- package/dist/frontend/ts7/adapter.d.ts +7 -0
- package/dist/frontend/ts7/adapter.js +54 -0
- package/dist/frontend/ts7/adapter.js.map +1 -0
- package/dist/frontend/ts7/ast.d.ts +50 -0
- package/dist/frontend/ts7/ast.js +211 -0
- package/dist/frontend/ts7/ast.js.map +1 -0
- package/dist/frontend/ts7/census-check.d.ts +1 -0
- package/dist/frontend/ts7/census-check.js +12 -0
- package/dist/frontend/ts7/census-check.js.map +1 -0
- package/dist/frontend/ts7/checker.d.ts +140 -0
- package/dist/frontend/ts7/checker.js +544 -0
- package/dist/frontend/ts7/checker.js.map +1 -0
- package/dist/frontend/ts7/enums.d.ts +18 -0
- package/dist/frontend/ts7/enums.js +43 -0
- package/dist/frontend/ts7/enums.js.map +1 -0
- package/dist/frontend/ts7/program.d.ts +99 -0
- package/dist/frontend/ts7/program.js +278 -0
- package/dist/frontend/ts7/program.js.map +1 -0
- package/dist/frontend/ts7/world-check.d.ts +3 -0
- package/dist/frontend/ts7/world-check.js +34 -0
- package/dist/frontend/ts7/world-check.js.map +1 -0
- package/dist/frontend/types.d.ts +205 -0
- package/dist/frontend/types.js +2485 -0
- package/dist/frontend/types.js.map +1 -0
- package/dist/index.d.ts +85 -0
- package/dist/index.js +424 -0
- package/dist/index.js.map +1 -0
- package/dist/ir/nodes.d.ts +4334 -0
- package/dist/ir/nodes.js +1906 -0
- package/dist/ir/nodes.js.map +1 -0
- package/dist/ir/serialize.d.ts +4 -0
- package/dist/ir/serialize.js +34 -0
- package/dist/ir/serialize.js.map +1 -0
- package/dist/ir/validate.d.ts +36 -0
- package/dist/ir/validate.js +4884 -0
- package/dist/ir/validate.js.map +1 -0
- package/package.json +30 -6
- package/README.md +0 -3
- package/index.js +0 -2
|
@@ -0,0 +1,652 @@
|
|
|
1
|
+
import { RUNTIME_EMITTER_CLASS, RUNTIME_ERROR_CLASSES, RUNTIME_STREAM_CLASSES } from "../../ir/nodes.js";
|
|
2
|
+
import { mangleClassRelease, mangleClassRetain, mangleClassStruct, mangleRecordRelease, mangleRecordRetain, mangleRecordStruct, } from "../mangle.js";
|
|
3
|
+
export function cType(t) {
|
|
4
|
+
switch (t.kind) {
|
|
5
|
+
case "f64":
|
|
6
|
+
return "double";
|
|
7
|
+
case "bool":
|
|
8
|
+
return "bool";
|
|
9
|
+
case "string":
|
|
10
|
+
return "ScrStr *";
|
|
11
|
+
case "array":
|
|
12
|
+
return "ScrArr *";
|
|
13
|
+
case "map":
|
|
14
|
+
case "set":
|
|
15
|
+
// Sets ARE the map runtime with the value slot unused (SCR_MAP_VAL_F64
|
|
16
|
+
// storing a constant 0) — one struct, one RC family, one allocator.
|
|
17
|
+
return "ScrMap *";
|
|
18
|
+
case "regex":
|
|
19
|
+
return "ScrRegex *";
|
|
20
|
+
case "bytes":
|
|
21
|
+
// One struct for every element kind (the runtime dispatches on the
|
|
22
|
+
// stored elem tag) — exactly the ScrArr pattern.
|
|
23
|
+
return "ScrBytes *";
|
|
24
|
+
case "url":
|
|
25
|
+
return "ScrUrl *";
|
|
26
|
+
case "searchParams":
|
|
27
|
+
return "ScrSearchParams *";
|
|
28
|
+
case "symbol":
|
|
29
|
+
return "ScrSym *";
|
|
30
|
+
case "stats":
|
|
31
|
+
return "ScrStats *";
|
|
32
|
+
case "spawnRes":
|
|
33
|
+
return "ScrSpawnRes *";
|
|
34
|
+
case "child":
|
|
35
|
+
return "ScrChild *";
|
|
36
|
+
case "netServer":
|
|
37
|
+
return "ScrNetServer *";
|
|
38
|
+
case "netSocket":
|
|
39
|
+
return "ScrNetSocket *";
|
|
40
|
+
case "http2Session":
|
|
41
|
+
return "ScrH2Session *";
|
|
42
|
+
case "http2Stream":
|
|
43
|
+
return "ScrH2Stream *";
|
|
44
|
+
case "dgramSocket":
|
|
45
|
+
return "ScrDgramSocket *";
|
|
46
|
+
case "testCtx":
|
|
47
|
+
return "ScrTestCtx *";
|
|
48
|
+
case "httpReq":
|
|
49
|
+
return "ScrHttpReq *";
|
|
50
|
+
case "httpRes":
|
|
51
|
+
return "ScrHttpRes *";
|
|
52
|
+
case "httpClientReq":
|
|
53
|
+
return "ScrHttpClientReq *";
|
|
54
|
+
case "secureCtx":
|
|
55
|
+
return "ScrSecureCtx *";
|
|
56
|
+
case "fsWatcher":
|
|
57
|
+
return "ScrWatcher *";
|
|
58
|
+
case "childStream":
|
|
59
|
+
return "ScrChildStream *";
|
|
60
|
+
case "procStream":
|
|
61
|
+
// A SCALAR kind: the stream value IS its fd (1 = stdout, 2 =
|
|
62
|
+
// stderr) — no heap, no refcount.
|
|
63
|
+
return "double";
|
|
64
|
+
case "func":
|
|
65
|
+
return "ScrClosure *";
|
|
66
|
+
case "classval":
|
|
67
|
+
// ONE struct type for every class (the fields are class-independent).
|
|
68
|
+
return "ScrClassObj *";
|
|
69
|
+
case "object":
|
|
70
|
+
// Runtime-provided error classes share the runtime's ScrError struct
|
|
71
|
+
// (all four builtins have the same layout; user subclasses embed it
|
|
72
|
+
// as their emitted struct's prefix).
|
|
73
|
+
if (RUNTIME_ERROR_CLASSES.has(t.className))
|
|
74
|
+
return "ScrError *";
|
|
75
|
+
// The runtime emitter class shares the runtime's ScrEmitter struct
|
|
76
|
+
// (user subclasses embed its prefix in their emitted structs).
|
|
77
|
+
if (t.className === RUNTIME_EMITTER_CLASS)
|
|
78
|
+
return "ScrEmitter *";
|
|
79
|
+
// The five runtime stream classes share ONE runtime struct (the
|
|
80
|
+
// emitter prefix plus the stream-state pointer) — upcasts among
|
|
81
|
+
// them and to ScrEmitter are pointer reinterprets.
|
|
82
|
+
if (RUNTIME_STREAM_CLASSES.has(t.className))
|
|
83
|
+
return "ScrStream *";
|
|
84
|
+
return `${mangleClassStruct(t.className)} *`;
|
|
85
|
+
case "record":
|
|
86
|
+
return `${mangleRecordStruct(t.shapeId)} *`;
|
|
87
|
+
case "union":
|
|
88
|
+
return "ScrUnion *";
|
|
89
|
+
case "dyn":
|
|
90
|
+
return "ScrDyn *";
|
|
91
|
+
case "jsval":
|
|
92
|
+
return "ScrJsval *";
|
|
93
|
+
case "caught":
|
|
94
|
+
return "ScrCaught *";
|
|
95
|
+
case "promise":
|
|
96
|
+
return "ScrPromise *";
|
|
97
|
+
case "generator":
|
|
98
|
+
return "ScrGen *";
|
|
99
|
+
case "void":
|
|
100
|
+
return "void";
|
|
101
|
+
case "undefinedT":
|
|
102
|
+
case "nullT":
|
|
103
|
+
// Unit kinds have no C value form: they exist only as union arms
|
|
104
|
+
// (the box carries the tag and nothing else) — a unit type asked to
|
|
105
|
+
// declare a C value is an emitter bug.
|
|
106
|
+
throw new Error(`emitter bug: ${t.kind} has no C value form`);
|
|
107
|
+
default: {
|
|
108
|
+
const _exhaustive = t;
|
|
109
|
+
void _exhaustive;
|
|
110
|
+
throw new Error("unreachable");
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
/** The retain call (+1, returns the value) for one refcounted type. */
|
|
115
|
+
export function retainCallC(type, expr) {
|
|
116
|
+
switch (type.kind) {
|
|
117
|
+
case "string":
|
|
118
|
+
return `scr_str_retain(${expr})`;
|
|
119
|
+
case "array":
|
|
120
|
+
return `scr_arr_retain(${expr})`;
|
|
121
|
+
case "map":
|
|
122
|
+
case "set":
|
|
123
|
+
return `scr_map_retain(${expr})`;
|
|
124
|
+
case "regex":
|
|
125
|
+
return `scr_regex_retain(${expr})`;
|
|
126
|
+
case "bytes":
|
|
127
|
+
return `scr_bytes_retain(${expr})`;
|
|
128
|
+
case "url":
|
|
129
|
+
return `scr_url_retain(${expr})`;
|
|
130
|
+
case "searchParams":
|
|
131
|
+
return `scr_sp_retain(${expr})`;
|
|
132
|
+
case "symbol":
|
|
133
|
+
return `scr_sym_retain(${expr})`;
|
|
134
|
+
case "stats":
|
|
135
|
+
return `scr_stats_retain(${expr})`;
|
|
136
|
+
case "spawnRes":
|
|
137
|
+
return `scr_spawn_res_retain(${expr})`;
|
|
138
|
+
case "child":
|
|
139
|
+
return `scr_child_retain(${expr})`;
|
|
140
|
+
case "netServer":
|
|
141
|
+
return `scr_net_server_retain(${expr})`;
|
|
142
|
+
case "netSocket":
|
|
143
|
+
return `scr_net_sock_retain(${expr})`;
|
|
144
|
+
case "http2Session":
|
|
145
|
+
return `scr_http2_session_retain(${expr})`;
|
|
146
|
+
case "http2Stream":
|
|
147
|
+
return `scr_http2_stream_retain(${expr})`;
|
|
148
|
+
case "dgramSocket":
|
|
149
|
+
return `scr_dgram_retain(${expr})`;
|
|
150
|
+
case "testCtx":
|
|
151
|
+
return `scr_testctx_retain(${expr})`;
|
|
152
|
+
case "httpReq":
|
|
153
|
+
return `scr_http_req_retain(${expr})`;
|
|
154
|
+
case "httpRes":
|
|
155
|
+
return `scr_http_res_retain(${expr})`;
|
|
156
|
+
case "httpClientReq":
|
|
157
|
+
return `scr_http_client_retain(${expr})`;
|
|
158
|
+
case "secureCtx":
|
|
159
|
+
return `scr_secure_ctx_retain(${expr})`;
|
|
160
|
+
case "fsWatcher":
|
|
161
|
+
return `scr_watcher_retain(${expr})`;
|
|
162
|
+
case "childStream":
|
|
163
|
+
return `scr_child_stream_retain(${expr})`;
|
|
164
|
+
case "func":
|
|
165
|
+
return `scr_closure_retain(${expr})`;
|
|
166
|
+
case "classval":
|
|
167
|
+
// A no-op on the immortal static — kept for ownership uniformity.
|
|
168
|
+
return `scr_classobj_retain(${expr})`;
|
|
169
|
+
case "object":
|
|
170
|
+
if (RUNTIME_ERROR_CLASSES.has(type.className))
|
|
171
|
+
return `scr_error_retain(${expr})`;
|
|
172
|
+
if (type.className === RUNTIME_EMITTER_CLASS)
|
|
173
|
+
return `scr_emitter_retain(${expr})`;
|
|
174
|
+
if (RUNTIME_STREAM_CLASSES.has(type.className))
|
|
175
|
+
return `scr_stream_retain(${expr})`;
|
|
176
|
+
return `${mangleClassRetain(type.className)}(${expr})`;
|
|
177
|
+
case "record":
|
|
178
|
+
return `${mangleRecordRetain(type.shapeId)}(${expr})`;
|
|
179
|
+
case "promise":
|
|
180
|
+
return `scr_promise_retain(${expr})`;
|
|
181
|
+
case "generator":
|
|
182
|
+
return `scr_gen_retain(${expr})`;
|
|
183
|
+
case "union":
|
|
184
|
+
return `scr_union_retain(${expr})`;
|
|
185
|
+
case "dyn":
|
|
186
|
+
return `scr_dyn_retain(${expr})`;
|
|
187
|
+
case "jsval":
|
|
188
|
+
return `scr_jsval_retain(${expr})`;
|
|
189
|
+
case "caught":
|
|
190
|
+
return `scr_caught_retain(${expr})`;
|
|
191
|
+
default:
|
|
192
|
+
throw new Error(`emitter bug: retain of non-refcounted type ${type.kind}`);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
/** The release call for one owned refcounted value (all NULL-tolerant). */
|
|
196
|
+
export function releaseCallC(type, expr) {
|
|
197
|
+
switch (type.kind) {
|
|
198
|
+
case "string":
|
|
199
|
+
return `scr_str_release(${expr})`;
|
|
200
|
+
case "array":
|
|
201
|
+
return `scr_arr_release(${expr})`;
|
|
202
|
+
case "map":
|
|
203
|
+
case "set":
|
|
204
|
+
return `scr_map_release(${expr})`;
|
|
205
|
+
case "regex":
|
|
206
|
+
return `scr_regex_release(${expr})`;
|
|
207
|
+
case "bytes":
|
|
208
|
+
return `scr_bytes_release(${expr})`;
|
|
209
|
+
case "url":
|
|
210
|
+
return `scr_url_release(${expr})`;
|
|
211
|
+
case "searchParams":
|
|
212
|
+
return `scr_sp_release(${expr})`;
|
|
213
|
+
case "symbol":
|
|
214
|
+
return `scr_sym_release(${expr})`;
|
|
215
|
+
case "stats":
|
|
216
|
+
return `scr_stats_release(${expr})`;
|
|
217
|
+
case "spawnRes":
|
|
218
|
+
return `scr_spawn_res_release(${expr})`;
|
|
219
|
+
case "child":
|
|
220
|
+
return `scr_child_release(${expr})`;
|
|
221
|
+
case "netServer":
|
|
222
|
+
return `scr_net_server_release(${expr})`;
|
|
223
|
+
case "netSocket":
|
|
224
|
+
return `scr_net_sock_release(${expr})`;
|
|
225
|
+
case "http2Session":
|
|
226
|
+
return `scr_http2_session_release(${expr})`;
|
|
227
|
+
case "http2Stream":
|
|
228
|
+
return `scr_http2_stream_release(${expr})`;
|
|
229
|
+
case "dgramSocket":
|
|
230
|
+
return `scr_dgram_release(${expr})`;
|
|
231
|
+
case "testCtx":
|
|
232
|
+
return `scr_testctx_release(${expr})`;
|
|
233
|
+
case "httpReq":
|
|
234
|
+
return `scr_http_req_release(${expr})`;
|
|
235
|
+
case "httpRes":
|
|
236
|
+
return `scr_http_res_release(${expr})`;
|
|
237
|
+
case "httpClientReq":
|
|
238
|
+
return `scr_http_client_release(${expr})`;
|
|
239
|
+
case "secureCtx":
|
|
240
|
+
return `scr_secure_ctx_release(${expr})`;
|
|
241
|
+
case "fsWatcher":
|
|
242
|
+
return `scr_watcher_release(${expr})`;
|
|
243
|
+
case "childStream":
|
|
244
|
+
return `scr_child_stream_release(${expr})`;
|
|
245
|
+
case "func":
|
|
246
|
+
return `scr_closure_release(${expr})`;
|
|
247
|
+
case "classval":
|
|
248
|
+
return `scr_classobj_release(${expr})`;
|
|
249
|
+
case "object":
|
|
250
|
+
if (RUNTIME_ERROR_CLASSES.has(type.className))
|
|
251
|
+
return `scr_error_release(${expr})`;
|
|
252
|
+
if (type.className === RUNTIME_EMITTER_CLASS)
|
|
253
|
+
return `scr_emitter_release(${expr})`;
|
|
254
|
+
if (RUNTIME_STREAM_CLASSES.has(type.className))
|
|
255
|
+
return `scr_stream_release(${expr})`;
|
|
256
|
+
return `${mangleClassRelease(type.className)}(${expr})`;
|
|
257
|
+
case "record":
|
|
258
|
+
return `${mangleRecordRelease(type.shapeId)}(${expr})`;
|
|
259
|
+
case "promise":
|
|
260
|
+
return `scr_promise_release(${expr})`;
|
|
261
|
+
case "generator":
|
|
262
|
+
return `scr_gen_release(${expr})`;
|
|
263
|
+
case "union":
|
|
264
|
+
return `scr_union_release(${expr})`;
|
|
265
|
+
case "dyn":
|
|
266
|
+
return `scr_dyn_release(${expr})`;
|
|
267
|
+
case "jsval":
|
|
268
|
+
return `scr_jsval_release(${expr})`;
|
|
269
|
+
case "caught":
|
|
270
|
+
return `scr_caught_release(${expr})`;
|
|
271
|
+
default:
|
|
272
|
+
throw new Error(`emitter bug: release of non-refcounted type ${type.kind}`);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
/** The runtime's box-kind tag for a boxed (captured) variable's type. */
|
|
276
|
+
export function boxKindC(t) {
|
|
277
|
+
switch (t.kind) {
|
|
278
|
+
case "f64":
|
|
279
|
+
return "SCR_BOX_F64";
|
|
280
|
+
case "bool":
|
|
281
|
+
return "SCR_BOX_BOOL";
|
|
282
|
+
case "string":
|
|
283
|
+
return "SCR_BOX_STR";
|
|
284
|
+
case "array":
|
|
285
|
+
return "SCR_BOX_ARR";
|
|
286
|
+
case "func":
|
|
287
|
+
return "SCR_BOX_FUNC";
|
|
288
|
+
case "object":
|
|
289
|
+
case "classval":
|
|
290
|
+
case "record":
|
|
291
|
+
case "union":
|
|
292
|
+
case "map":
|
|
293
|
+
case "set":
|
|
294
|
+
case "regex":
|
|
295
|
+
case "url":
|
|
296
|
+
case "searchParams":
|
|
297
|
+
case "symbol":
|
|
298
|
+
case "stats":
|
|
299
|
+
case "spawnRes":
|
|
300
|
+
case "child":
|
|
301
|
+
case "netServer":
|
|
302
|
+
case "netSocket":
|
|
303
|
+
case "http2Session":
|
|
304
|
+
case "http2Stream":
|
|
305
|
+
case "dgramSocket":
|
|
306
|
+
case "testCtx":
|
|
307
|
+
case "httpReq":
|
|
308
|
+
case "httpRes":
|
|
309
|
+
case "httpClientReq":
|
|
310
|
+
case "secureCtx":
|
|
311
|
+
case "fsWatcher":
|
|
312
|
+
case "childStream":
|
|
313
|
+
case "bytes":
|
|
314
|
+
throw new Error(`emitter bug: ${t.kind} boxes go through boxNewC, not boxKindC`);
|
|
315
|
+
case "procStream":
|
|
316
|
+
// Scalar (the fd double) — the f64 box carries it.
|
|
317
|
+
return "SCR_BOX_F64";
|
|
318
|
+
case "dyn":
|
|
319
|
+
// dyn never rides capture boxes (frontend rejects dyn captures).
|
|
320
|
+
throw new Error("emitter bug: box of dyn");
|
|
321
|
+
case "jsval":
|
|
322
|
+
throw new Error("emitter bug: jsval boxes go through boxNewC, not boxKindC");
|
|
323
|
+
case "promise":
|
|
324
|
+
// promises ride obj-boxes (boxNewC), never plain kind boxes
|
|
325
|
+
throw new Error("emitter bug: promise boxes go through boxNewC");
|
|
326
|
+
case "generator":
|
|
327
|
+
// generators ride obj-boxes too (boxNewC — vAdapters carries the
|
|
328
|
+
// ScrGen RC entry points; no trace, like child).
|
|
329
|
+
throw new Error("emitter bug: generator boxes go through boxNewC");
|
|
330
|
+
case "undefinedT":
|
|
331
|
+
case "nullT":
|
|
332
|
+
case "caught":
|
|
333
|
+
// unit kinds never stand alone (and catch bindings never box), so
|
|
334
|
+
// nothing to box
|
|
335
|
+
throw new Error(`emitter bug: box of ${t.kind}`);
|
|
336
|
+
case "void":
|
|
337
|
+
throw new Error("emitter bug: box of void");
|
|
338
|
+
default: {
|
|
339
|
+
const _exhaustive = t;
|
|
340
|
+
void _exhaustive;
|
|
341
|
+
throw new Error("unreachable");
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
/** The runtime `_v` (void*-signature) RC entry points for one refcounted
|
|
346
|
+
* type — the currency of every generic container that must retain/release
|
|
347
|
+
* payloads whose concrete struct it cannot know: union values, capture
|
|
348
|
+
* boxes, promises, and the exception cell. Classes and records use their
|
|
349
|
+
* emitted per-shape adapters; everything else has runtime-provided ones.
|
|
350
|
+
* Bare symbol names — call sites prefix `&` where a fn ptr is passed. */
|
|
351
|
+
export function vAdapters(t) {
|
|
352
|
+
switch (t.kind) {
|
|
353
|
+
case "string":
|
|
354
|
+
return { retain: "scr_str_retain_v", release: "scr_str_release_v" };
|
|
355
|
+
case "array":
|
|
356
|
+
return { retain: "scr_arr_retain_v", release: "scr_arr_release_v" };
|
|
357
|
+
case "map":
|
|
358
|
+
case "set":
|
|
359
|
+
return { retain: "scr_map_retain_v", release: "scr_map_release_v" };
|
|
360
|
+
case "regex":
|
|
361
|
+
return { retain: "scr_regex_retain_v", release: "scr_regex_release_v" };
|
|
362
|
+
case "bytes":
|
|
363
|
+
return { retain: "scr_bytes_retain_v", release: "scr_bytes_release_v" };
|
|
364
|
+
case "url":
|
|
365
|
+
return { retain: "scr_url_retain_v", release: "scr_url_release_v" };
|
|
366
|
+
case "searchParams":
|
|
367
|
+
return { retain: "scr_sp_retain_v", release: "scr_sp_release_v" };
|
|
368
|
+
case "symbol":
|
|
369
|
+
return { retain: "scr_sym_retain_v", release: "scr_sym_release_v" };
|
|
370
|
+
case "stats":
|
|
371
|
+
return { retain: "scr_stats_retain_v", release: "scr_stats_release_v" };
|
|
372
|
+
case "spawnRes":
|
|
373
|
+
return { retain: "scr_spawn_res_retain_v", release: "scr_spawn_res_release_v" };
|
|
374
|
+
case "child":
|
|
375
|
+
return { retain: "scr_child_retain_v", release: "scr_child_release_v" };
|
|
376
|
+
case "netServer":
|
|
377
|
+
return { retain: "scr_net_server_retain_v", release: "scr_net_server_release_v" };
|
|
378
|
+
case "netSocket":
|
|
379
|
+
return { retain: "scr_net_sock_retain_v", release: "scr_net_sock_release_v" };
|
|
380
|
+
case "http2Session":
|
|
381
|
+
return { retain: "scr_http2_session_retain_v", release: "scr_http2_session_release_v" };
|
|
382
|
+
case "http2Stream":
|
|
383
|
+
return { retain: "scr_http2_stream_retain_v", release: "scr_http2_stream_release_v" };
|
|
384
|
+
case "dgramSocket":
|
|
385
|
+
return { retain: "scr_dgram_retain_v", release: "scr_dgram_release_v" };
|
|
386
|
+
case "testCtx":
|
|
387
|
+
return { retain: "scr_testctx_retain_v", release: "scr_testctx_release_v" };
|
|
388
|
+
case "httpReq":
|
|
389
|
+
return { retain: "scr_http_req_retain_v", release: "scr_http_req_release_v" };
|
|
390
|
+
case "httpRes":
|
|
391
|
+
return { retain: "scr_http_res_retain_v", release: "scr_http_res_release_v" };
|
|
392
|
+
case "httpClientReq":
|
|
393
|
+
return { retain: "scr_http_client_retain_v", release: "scr_http_client_release_v" };
|
|
394
|
+
case "secureCtx":
|
|
395
|
+
return { retain: "scr_secure_ctx_retain_v", release: "scr_secure_ctx_release_v" };
|
|
396
|
+
case "fsWatcher":
|
|
397
|
+
return { retain: "scr_watcher_retain_v", release: "scr_watcher_release_v" };
|
|
398
|
+
case "childStream":
|
|
399
|
+
return { retain: "scr_child_stream_retain_v", release: "scr_child_stream_release_v" };
|
|
400
|
+
case "func":
|
|
401
|
+
return { retain: "scr_closure_retain_v", release: "scr_closure_release_v" };
|
|
402
|
+
case "classval":
|
|
403
|
+
// No-ops on the immortal class object; the container machinery
|
|
404
|
+
// stays uniform.
|
|
405
|
+
return { retain: "scr_classobj_retain_v", release: "scr_classobj_release_v" };
|
|
406
|
+
case "union":
|
|
407
|
+
return { retain: "scr_union_retain_v", release: "scr_union_release_v" };
|
|
408
|
+
case "object":
|
|
409
|
+
if (RUNTIME_ERROR_CLASSES.has(t.className)) {
|
|
410
|
+
return { retain: "scr_error_retain_v", release: "scr_error_release_v" };
|
|
411
|
+
}
|
|
412
|
+
if (t.className === RUNTIME_EMITTER_CLASS) {
|
|
413
|
+
return { retain: "scr_emitter_retain_v", release: "scr_emitter_release_v" };
|
|
414
|
+
}
|
|
415
|
+
if (RUNTIME_STREAM_CLASSES.has(t.className)) {
|
|
416
|
+
return { retain: "scr_stream_retain_v", release: "scr_stream_release_v" };
|
|
417
|
+
}
|
|
418
|
+
return { retain: `${mangleClassRetain(t.className)}_v`, release: `${mangleClassRelease(t.className)}_v` };
|
|
419
|
+
case "record":
|
|
420
|
+
return { retain: `${mangleRecordRetain(t.shapeId)}_v`, release: `${mangleRecordRelease(t.shapeId)}_v` };
|
|
421
|
+
case "promise":
|
|
422
|
+
return { retain: "scr_promise_retain_v", release: "scr_promise_release_v" };
|
|
423
|
+
case "generator":
|
|
424
|
+
return { retain: "scr_gen_retain_v", release: "scr_gen_release_v" };
|
|
425
|
+
case "dyn":
|
|
426
|
+
return { retain: "scr_dyn_retain_v", release: "scr_dyn_release_v" };
|
|
427
|
+
case "jsval":
|
|
428
|
+
return { retain: "scr_jsval_retain_v", release: "scr_jsval_release_v" };
|
|
429
|
+
default:
|
|
430
|
+
throw new Error(`emitter bug: no RC adapters for ${t.kind}`);
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
/** Box accessor suffix: scalars stored unboxed, ref kinds as pointers. */
|
|
434
|
+
export function boxAccess(t) {
|
|
435
|
+
// procStream is a scalar (the stream's fd double — boxKindC agrees with
|
|
436
|
+
// SCR_BOX_F64), so its captures ride the f64 slot like any number.
|
|
437
|
+
return t.kind === "f64" || t.kind === "procStream" ? "f64" : t.kind === "bool" ? "bool" : "ref";
|
|
438
|
+
}
|
|
439
|
+
/** C function-pointer cast for calling through a closure: the callee
|
|
440
|
+
* receives its own ScrClosure first, then the declared params. */
|
|
441
|
+
export function cFnPtrCast(ft) {
|
|
442
|
+
const params = ["ScrClosure *", ...ft.params.map((p) => cType(p).trim())].join(", ");
|
|
443
|
+
return `(${cType(ft.ret).trim()} (*)(${params}))`;
|
|
444
|
+
}
|
|
445
|
+
/** The runtime's element-kind tag for an array's element type. Record/
|
|
446
|
+
* object/union elements are SCR_ELEM_REF (void* slots + per-array RC entry
|
|
447
|
+
* points); array elements answer SCR_ELEM_ARR here, but a CYCLE-CAPABLE
|
|
448
|
+
* inner array rides SCR_ELEM_REF instead so the outer array's trace can
|
|
449
|
+
* reach it — that answer needs emitter state, so construction goes through
|
|
450
|
+
* CEmitter.arrNewC, which overrides this for traced-array elements. */
|
|
451
|
+
export function elemKindC(elem) {
|
|
452
|
+
switch (elem.kind) {
|
|
453
|
+
case "f64":
|
|
454
|
+
return "SCR_ELEM_F64";
|
|
455
|
+
case "bool":
|
|
456
|
+
return "SCR_ELEM_BOOL";
|
|
457
|
+
case "string":
|
|
458
|
+
return "SCR_ELEM_STR";
|
|
459
|
+
case "array":
|
|
460
|
+
return "SCR_ELEM_ARR";
|
|
461
|
+
case "bytes":
|
|
462
|
+
return "SCR_ELEM_BYTES";
|
|
463
|
+
case "record":
|
|
464
|
+
case "object":
|
|
465
|
+
case "union":
|
|
466
|
+
// Island handles are ordinary refcounted pointers (scr_jsval_retain/
|
|
467
|
+
// release adapters) — `any[]` under --dynamic is a native array of
|
|
468
|
+
// handles, one element per island value.
|
|
469
|
+
case "jsval":
|
|
470
|
+
// Spawned child handles (ChildProcess[] — the running-apps list):
|
|
471
|
+
// ordinary refcounted pointers, no trace (they drop their closures at
|
|
472
|
+
// reap, so never part of a cycle).
|
|
473
|
+
case "child":
|
|
474
|
+
// Server handles (ProxyServer[] — the [...set] drain of the auxiliary
|
|
475
|
+
// registries): same refcounted-pointer story; listeners drop at close,
|
|
476
|
+
// so a handle-in-array cycle is temporary like child's.
|
|
477
|
+
case "netServer":
|
|
478
|
+
// Symbols (symbol[] — heterogeneous sentinel lists): refcounted
|
|
479
|
+
// identity pointers holding only strings — no trace, no cycles ever.
|
|
480
|
+
case "symbol":
|
|
481
|
+
// Class objects ((typeof Shape)[] — the registry idiom): immortal
|
|
482
|
+
// statics behind no-op RC adapters — no trace, no cycles ever;
|
|
483
|
+
// indexOf/includes/=== are the REF kind's pointer identity, exactly
|
|
484
|
+
// JS class identity.
|
|
485
|
+
case "classval":
|
|
486
|
+
return "SCR_ELEM_REF";
|
|
487
|
+
// Closures: refcounted, cycle-headered (captures can reach back
|
|
488
|
+
// through boxes), scr_closure_* `_v` adapters + scr_closure_trace_v.
|
|
489
|
+
// Identity semantics (indexOf/includes/===) are the REF kind's
|
|
490
|
+
// pointer identity — exactly JS function identity.
|
|
491
|
+
case "func":
|
|
492
|
+
return "SCR_ELEM_REF";
|
|
493
|
+
case "map":
|
|
494
|
+
case "set":
|
|
495
|
+
case "regex":
|
|
496
|
+
case "url":
|
|
497
|
+
case "searchParams":
|
|
498
|
+
case "stats":
|
|
499
|
+
case "spawnRes":
|
|
500
|
+
case "netSocket":
|
|
501
|
+
case "http2Session":
|
|
502
|
+
case "http2Stream":
|
|
503
|
+
case "dgramSocket":
|
|
504
|
+
case "testCtx":
|
|
505
|
+
case "httpReq":
|
|
506
|
+
case "httpRes":
|
|
507
|
+
case "httpClientReq":
|
|
508
|
+
case "secureCtx":
|
|
509
|
+
case "fsWatcher":
|
|
510
|
+
case "childStream":
|
|
511
|
+
case "procStream":
|
|
512
|
+
case "dyn":
|
|
513
|
+
case "caught":
|
|
514
|
+
case "promise":
|
|
515
|
+
case "generator":
|
|
516
|
+
case "undefinedT":
|
|
517
|
+
case "nullT":
|
|
518
|
+
throw new Error(`emitter bug: array of ${elem.kind} (frontend rejects these)`);
|
|
519
|
+
case "void":
|
|
520
|
+
throw new Error("emitter bug: array of void");
|
|
521
|
+
default: {
|
|
522
|
+
const _exhaustive = elem;
|
|
523
|
+
void _exhaustive;
|
|
524
|
+
throw new Error("unreachable");
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
/** The runtime's element-kind tag for a bytes (typed array) type. */
|
|
529
|
+
export function bytesElemKindC(elem) {
|
|
530
|
+
return elem === "u8" ? "SCR_BYTES_U8" : elem === "u32" ? "SCR_BYTES_U32" : elem === "i32" ? "SCR_BYTES_I32" : "SCR_BYTES_F32";
|
|
531
|
+
}
|
|
532
|
+
/** The runtime's ScrBytesNumKind tag + littleEndian flag per readNum/
|
|
533
|
+
* writeNum kind token (the strLit args[0] the frontend mints). The
|
|
534
|
+
* variable-width family's tokens map to sign + endian flags instead. */
|
|
535
|
+
export const BYTES_NUM_KIND_C = {
|
|
536
|
+
u8: { kind: "SCR_BN_U8", le: false },
|
|
537
|
+
i8: { kind: "SCR_BN_I8", le: false },
|
|
538
|
+
u16be: { kind: "SCR_BN_U16", le: false },
|
|
539
|
+
u16le: { kind: "SCR_BN_U16", le: true },
|
|
540
|
+
i16be: { kind: "SCR_BN_I16", le: false },
|
|
541
|
+
i16le: { kind: "SCR_BN_I16", le: true },
|
|
542
|
+
u32be: { kind: "SCR_BN_U32", le: false },
|
|
543
|
+
u32le: { kind: "SCR_BN_U32", le: true },
|
|
544
|
+
i32be: { kind: "SCR_BN_I32", le: false },
|
|
545
|
+
i32le: { kind: "SCR_BN_I32", le: true },
|
|
546
|
+
f32be: { kind: "SCR_BN_F32", le: false },
|
|
547
|
+
f32le: { kind: "SCR_BN_F32", le: true },
|
|
548
|
+
f64be: { kind: "SCR_BN_F64", le: false },
|
|
549
|
+
f64le: { kind: "SCR_BN_F64", le: true },
|
|
550
|
+
};
|
|
551
|
+
/** The variable-width (read/writeUIntLE-style) kind tokens: sign + endian. */
|
|
552
|
+
export const BYTES_NUM_VAR_C = {
|
|
553
|
+
ube: { sign: false, le: false },
|
|
554
|
+
ule: { sign: false, le: true },
|
|
555
|
+
ibe: { sign: true, le: false },
|
|
556
|
+
ile: { sign: true, le: true },
|
|
557
|
+
};
|
|
558
|
+
/** The runtime's ScrDataViewGet tag per dvGet* bytesIntrinsic method. */
|
|
559
|
+
export const DV_GET_KIND_C = {
|
|
560
|
+
dvGetUint8: "SCR_DV_U8",
|
|
561
|
+
dvGetInt8: "SCR_DV_I8",
|
|
562
|
+
dvGetUint16: "SCR_DV_U16",
|
|
563
|
+
dvGetInt16: "SCR_DV_I16",
|
|
564
|
+
dvGetUint32: "SCR_DV_U32",
|
|
565
|
+
dvGetInt32: "SCR_DV_I32",
|
|
566
|
+
dvGetFloat32: "SCR_DV_F32",
|
|
567
|
+
dvGetFloat64: "SCR_DV_F64",
|
|
568
|
+
dvGetBigUint64Number: "SCR_DV_BIGU64",
|
|
569
|
+
dvGetBigInt64Number: "SCR_DV_BIGI64",
|
|
570
|
+
};
|
|
571
|
+
/** Runtime accessor suffix for an element type: arrays store f64 and bool
|
|
572
|
+
* unboxed and everything refcounted as a pointer (`_ref`). */
|
|
573
|
+
export function elemAccess(elem) {
|
|
574
|
+
return elem.kind === "f64" ? "f64" : elem.kind === "bool" ? "bool" : "ref";
|
|
575
|
+
}
|
|
576
|
+
/** Runtime suffix for a map's KEY kind (f64 with SameValueZero, or string
|
|
577
|
+
* content) — the first suffix of the scr_map_* two-suffix family. */
|
|
578
|
+
export function mapKeyAccess(key) {
|
|
579
|
+
if (key.kind === "f64")
|
|
580
|
+
return "f64";
|
|
581
|
+
if (key.kind === "string")
|
|
582
|
+
return "str";
|
|
583
|
+
// Handle-kind SET elements (identity hashing — isSupportedSetElem);
|
|
584
|
+
// Map keys proper stay f64/string.
|
|
585
|
+
if (key.kind === "netServer" || key.kind === "symbol")
|
|
586
|
+
return "ref";
|
|
587
|
+
throw new Error(`emitter bug: map key of ${key.kind} (frontend rejects these)`);
|
|
588
|
+
}
|
|
589
|
+
/** The runtime's key-kind/value-kind tags for scr_map_new. */
|
|
590
|
+
export function mapKeyKindC(key) {
|
|
591
|
+
const acc = mapKeyAccess(key);
|
|
592
|
+
return acc === "str" ? "SCR_MAP_KEY_STR" : acc === "ref" ? "SCR_MAP_KEY_REF" : "SCR_MAP_KEY_F64";
|
|
593
|
+
}
|
|
594
|
+
export function mapValKindC(value) {
|
|
595
|
+
return value.kind === "f64"
|
|
596
|
+
? "SCR_MAP_VAL_F64"
|
|
597
|
+
: value.kind === "bool"
|
|
598
|
+
? "SCR_MAP_VAL_BOOL"
|
|
599
|
+
: "SCR_MAP_VAL_REF";
|
|
600
|
+
}
|
|
601
|
+
/** UTF-8 bytes as an unambiguous C string literal (octal escapes are always
|
|
602
|
+
* three digits, so a following digit can never extend them — unlike \xHH). */
|
|
603
|
+
export function cStringLiteral(bytes) {
|
|
604
|
+
let out = '"';
|
|
605
|
+
for (const b of bytes) {
|
|
606
|
+
if (b === 0x22)
|
|
607
|
+
out += '\\"';
|
|
608
|
+
else if (b === 0x5c)
|
|
609
|
+
out += "\\\\";
|
|
610
|
+
// '?' escapes to defuse TRIGRAPHS: under -std=c11 the preprocessor
|
|
611
|
+
// rewrites `??=` (and the other eight `??x` sequences) INSIDE string
|
|
612
|
+
// literals — an embedded JS `wasmBinaryFile ??= f()` would reach the
|
|
613
|
+
// engine as `wasmBinaryFile #` and die as a SyntaxError. `\?` is
|
|
614
|
+
// standard C, exactly for this.
|
|
615
|
+
else if (b === 0x3f)
|
|
616
|
+
out += "\\?";
|
|
617
|
+
else if (b >= 0x20 && b < 0x7f)
|
|
618
|
+
out += String.fromCharCode(b);
|
|
619
|
+
else
|
|
620
|
+
out += "\\" + b.toString(8).padStart(3, "0");
|
|
621
|
+
}
|
|
622
|
+
return out + '"';
|
|
623
|
+
}
|
|
624
|
+
/** JS shortest-roundtrip decimal re-parses to the identical double in C
|
|
625
|
+
* (strtod is correctly rounded), so String(value) is a faithful C literal. */
|
|
626
|
+
export function cNumberLiteral(value) {
|
|
627
|
+
// ±Infinity and NaN numLits are real (the globals `Infinity`/`NaN`); C
|
|
628
|
+
// spells them with math.h's INFINITY/NAN macros (the emitted unit always
|
|
629
|
+
// includes math.h).
|
|
630
|
+
if (value === Infinity)
|
|
631
|
+
return "INFINITY";
|
|
632
|
+
if (value === -Infinity)
|
|
633
|
+
return "-INFINITY";
|
|
634
|
+
if (Number.isNaN(value))
|
|
635
|
+
return "NAN";
|
|
636
|
+
if (Object.is(value, -0))
|
|
637
|
+
return "-0.0"; // String(-0) is "0", which would lose the sign
|
|
638
|
+
const text = String(value);
|
|
639
|
+
// Integral shortest-roundtrip text ("118059162071741140000") would be a
|
|
640
|
+
// C INTEGER literal — invalid beyond unsigned long long's range, and in
|
|
641
|
+
// [2^63, 2^64) clang's unsigned-interpretation extension would let a
|
|
642
|
+
// NEGATED literal wrap modulo 2^64, a silent wrong value; the ".0" keeps
|
|
643
|
+
// every numLit a double literal (decimal parsing is correctly rounded
|
|
644
|
+
// either way).
|
|
645
|
+
return /[.eE]/.test(text) ? text : text + ".0";
|
|
646
|
+
}
|
|
647
|
+
/** `<type> <name>` with pointer types spaced C-style (`ScrStr *x`). */
|
|
648
|
+
export function cDecl(type, name) {
|
|
649
|
+
const t = cType(type);
|
|
650
|
+
return t.endsWith("*") ? t + name : `${t} ${name}`;
|
|
651
|
+
}
|
|
652
|
+
//# sourceMappingURL=emit-types.js.map
|