wasm-idle 1.1.0 → 1.1.2
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 +140 -37
- package/dist/playground/assetBridge.js +106 -31
- package/dist/playground/assets.d.ts +2 -2
- package/dist/playground/c3.js +22 -0
- package/dist/playground/c3Memory.d.ts +19 -0
- package/dist/playground/c3Memory.js +117 -0
- package/dist/playground/cachedClang.js +143 -34
- package/dist/playground/clangAssetIntegrity.js +6 -6
- package/dist/playground/clangWorkerProtocol.d.ts +12 -1
- package/dist/playground/cobol.d.ts +3 -0
- package/dist/playground/cobol.js +10 -1
- package/dist/playground/commonlispAssets.d.ts +2 -2
- package/dist/playground/compiledArtifactCache.d.ts +3 -1
- package/dist/playground/compiledArtifactCache.js +31 -5
- package/dist/playground/container/ContainerExplorer.svelte +307 -0
- package/dist/playground/container/ContainerExplorer.svelte.d.ts +14 -0
- package/dist/playground/container/binding.d.ts +26 -0
- package/dist/playground/container/binding.js +247 -0
- package/dist/playground/container/clang-runtime.d.ts +38 -0
- package/dist/playground/container/clang-runtime.js +343 -0
- package/dist/playground/container/client.d.ts +15 -0
- package/dist/playground/container/client.js +189 -0
- package/dist/playground/container/explorer.d.ts +31 -0
- package/dist/playground/container/explorer.js +112 -0
- package/dist/playground/container/owner.worker.js +390 -0
- package/dist/playground/container/protocol.d.ts +73 -0
- package/dist/playground/container/protocol.js +28 -0
- package/dist/playground/container/release.d.ts +31 -0
- package/dist/playground/container/release.js +612 -0
- package/dist/playground/container/runtime-adapter.d.ts +73 -0
- package/dist/playground/container/runtime-adapter.js +474 -0
- package/dist/playground/container/shell-control.d.ts +49 -0
- package/dist/playground/container/shell-control.js +303 -0
- package/dist/playground/container/workspace.d.ts +8 -0
- package/dist/playground/container/workspace.js +29 -0
- package/dist/playground/d.d.ts +6 -1
- package/dist/playground/d.js +83 -5
- package/dist/playground/dotnet.js +6 -8
- package/dist/playground/fortran.d.ts +3 -0
- package/dist/playground/fortran.js +10 -1
- package/dist/playground/go.js +14 -3
- package/dist/playground/goDebugInstrumentation.js +184 -54
- package/dist/playground/java.js +3 -2
- package/dist/playground/javaRuntimeErrors.d.ts +9 -0
- package/dist/playground/javaRuntimeErrors.js +60 -0
- package/dist/playground/lean4Assets.d.ts +4 -4
- package/dist/playground/lfortran.js +10 -0
- package/dist/playground/lfortranAssets.d.ts +2 -2
- package/dist/playground/nim.js +22 -0
- package/dist/playground/objectivec.d.ts +3 -0
- package/dist/playground/objectivec.js +11 -2
- package/dist/playground/options.d.ts +2 -0
- package/dist/playground/python.js +8 -0
- package/dist/playground/runtimeAssetCache.d.ts +1 -32
- package/dist/playground/runtimeAssetCache.js +1 -193
- package/dist/playground/runtimeSession.d.ts +2 -2
- package/dist/playground/runtimeSession.js +11 -11
- package/dist/playground/rust.d.ts +6 -0
- package/dist/playground/rust.js +103 -6
- package/dist/playground/staticStdinRing.d.ts +2 -1
- package/dist/playground/staticStdinRing.js +21 -10
- package/dist/playground/staticWorkerRuntime.d.ts +15 -1
- package/dist/playground/staticWorkerRuntime.js +119 -17
- package/dist/playground/tinygo.d.ts +3 -0
- package/dist/playground/tinygo.js +81 -6
- package/dist/playground/v.d.ts +3 -0
- package/dist/playground/v.js +10 -1
- package/dist/playground/wasmAwkVersion.d.ts +13 -13
- package/dist/playground/wasmAwkVersion.js +4 -4
- package/dist/playground/wasmBqnVersion.d.ts +2 -2
- package/dist/playground/wasmBqnVersion.js +2 -2
- package/dist/playground/wasmC3Version.d.ts +2 -2
- package/dist/playground/wasmC3Version.js +2 -2
- package/dist/playground/wasmClojureScriptVersion.d.ts +2 -2
- package/dist/playground/wasmClojureScriptVersion.js +2 -2
- package/dist/playground/wasmCommonLispVersion.d.ts +2 -2
- package/dist/playground/wasmCommonLispVersion.js +2 -2
- package/dist/playground/wasmDIntegrity.d.ts +5 -5
- package/dist/playground/wasmDIntegrity.js +5 -5
- package/dist/playground/wasmDVersion.d.ts +16 -1
- package/dist/playground/wasmDVersion.js +16 -1
- package/dist/playground/wasmDebugVersion.d.ts +1 -1
- package/dist/playground/wasmDebugVersion.js +1 -1
- package/dist/playground/wasmForthVersion.d.ts +2 -2
- package/dist/playground/wasmForthVersion.js +2 -2
- package/dist/playground/wasmGleamVersion.d.ts +2 -2
- package/dist/playground/wasmGleamVersion.js +2 -2
- package/dist/playground/wasmGrainVersion.d.ts +2 -2
- package/dist/playground/wasmGrainVersion.js +2 -2
- package/dist/playground/wasmJVersion.d.ts +2 -2
- package/dist/playground/wasmJVersion.js +2 -2
- package/dist/playground/wasmJanetVersion.js +2 -2
- package/dist/playground/wasmJuliaVersion.js +2 -2
- package/dist/playground/wasmLean4Version.d.ts +5 -5
- package/dist/playground/wasmLean4Version.js +5 -5
- package/dist/playground/wasmLfortranVersion.d.ts +2 -2
- package/dist/playground/wasmLfortranVersion.js +2 -2
- package/dist/playground/wasmNimVersion.d.ts +9 -9
- package/dist/playground/wasmNimVersion.js +6 -6
- package/dist/playground/wasmOcamlVersion.d.ts +2 -2
- package/dist/playground/wasmOcamlVersion.js +1 -1
- package/dist/playground/wasmPascalVersion.js +2 -2
- package/dist/playground/wasmPerlVersion.js +2 -2
- package/dist/playground/wasmPrologVersion.d.ts +2 -2
- package/dist/playground/wasmPrologVersion.js +2 -2
- package/dist/playground/wasmReScriptVersion.d.ts +2 -2
- package/dist/playground/wasmReScriptVersion.js +2 -2
- package/dist/playground/wasmRustVersion.d.ts +8 -8
- package/dist/playground/wasmRustVersion.js +7 -7
- package/dist/playground/wasmTclVersion.d.ts +4 -4
- package/dist/playground/wasmTclVersion.js +2 -2
- package/dist/playground/wasmTinyGoVersion.d.ts +14 -14
- package/dist/playground/wasmTinyGoVersion.js +14 -14
- package/dist/playground/wasmTypeScriptVersion.d.ts +5 -5
- package/dist/playground/wasmTypeScriptVersion.js +5 -5
- package/dist/playground/worker/cachedClangCompile.js +52 -4
- package/dist/playground/worker/cachedClangExecute.js +6 -5
- package/dist/playground/worker/clang.js +32 -10
- package/dist/playground/worker/cobol.js +2 -2
- package/dist/playground/worker/d.js +12 -5
- package/dist/playground/worker/fortran.js +2 -2
- package/dist/playground/worker/go.js +16 -5
- package/dist/playground/worker/haskell.js +10 -7
- package/dist/playground/worker/java.js +75 -10
- package/dist/playground/worker/lua.js +2 -3
- package/dist/playground/worker/php.js +15 -9
- package/dist/playground/worker/python.js +46 -9
- package/dist/playground/worker/pythonExecution.js +17 -1
- package/dist/playground/worker/pythonWorkspaceFiles.d.ts +6 -0
- package/dist/playground/worker/pythonWorkspaceFiles.js +26 -0
- package/dist/playground/worker/pythonWorkspaceImports.d.ts +4 -0
- package/dist/playground/worker/pythonWorkspaceImports.js +129 -0
- package/dist/playground/worker/r.js +13 -6
- package/dist/playground/worker/rust.js +34 -2
- package/dist/playground/worker/sqlite.js +4 -3
- package/dist/playground/worker/tinygo.js +11 -3
- package/dist/playground/worker/typescript.js +2 -3
- package/dist/playground/worker/v.js +2 -2
- package/dist/playground/worker/wat.js +2 -3
- package/dist/playground/worker/zig.js +20 -6
- package/dist/playground/workerSession.d.ts +1 -28
- package/dist/playground/workerSession.js +1 -164
- package/package.json +20 -13
- package/dist/playground/worker/python.runtime.cases.js +0 -374
- /package/dist/playground/{worker/python.runtime.cases.d.ts → container/owner.worker.d.ts} +0 -0
|
@@ -69,59 +69,112 @@ function stripLineComment(line) {
|
|
|
69
69
|
const commentStart = lineCommentStart(line);
|
|
70
70
|
return commentStart === -1 ? line : line.slice(0, commentStart);
|
|
71
71
|
}
|
|
72
|
-
|
|
73
|
-
const
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
72
|
+
const goKeywords = new Set([
|
|
73
|
+
...'break case chan const continue default defer else fallthrough for func go'.split(' '),
|
|
74
|
+
...'goto if import interface map package range return select struct switch type var'.split(' ')
|
|
75
|
+
]);
|
|
76
|
+
// Final tokens after which Go inserts a semicolon at a line break. Literals are tokenized as
|
|
77
|
+
// '0' (number), '"' (string), "'" (rune) and '`' (raw string).
|
|
78
|
+
const statementEndTokens = new Set([
|
|
79
|
+
...'break continue fallthrough return ++ -- ) ] }'.split(' '),
|
|
80
|
+
...['0', '"', "'", '`']
|
|
81
|
+
]);
|
|
82
|
+
function isIdentifier(token) {
|
|
83
|
+
return token !== undefined && /^[\p{L}_]/u.test(token) && !goKeywords.has(token);
|
|
84
|
+
}
|
|
85
|
+
function endsStatement(token) {
|
|
86
|
+
return statementEndTokens.has(token) || isIdentifier(token);
|
|
87
|
+
}
|
|
88
|
+
// Inside an if/for/switch header Go reads `T{` as the block, but `[]T{`, `[N]*pkg.T{`,
|
|
89
|
+
// `map[K]V{` and `struct{...}{` still open composite literals.
|
|
90
|
+
function followsLiteralType(tokens, braceIndex, closedFrame) {
|
|
91
|
+
let index = braceIndex - 1;
|
|
92
|
+
if (tokens[index] === '}')
|
|
93
|
+
return closedFrame === 'type';
|
|
94
|
+
if (!isIdentifier(tokens[index]))
|
|
95
|
+
return false;
|
|
96
|
+
index -= 1;
|
|
97
|
+
if (tokens[index] === '.' && isIdentifier(tokens[index - 1]))
|
|
98
|
+
index -= 2;
|
|
99
|
+
const pointer = tokens[index] === '*';
|
|
100
|
+
while (tokens[index] === '*')
|
|
101
|
+
index -= 1;
|
|
102
|
+
if (tokens[index] !== ']')
|
|
103
|
+
return false;
|
|
104
|
+
if (!pointer)
|
|
105
|
+
return true;
|
|
106
|
+
// `a[i] * b {` multiplies; only `[]*T` and `map[K]*V` are element types.
|
|
107
|
+
let open = index - 1;
|
|
108
|
+
for (let depth = 1; open >= 0; open -= 1) {
|
|
109
|
+
if (tokens[open] === ']')
|
|
110
|
+
depth += 1;
|
|
111
|
+
else if (tokens[open] === '[' && --depth === 0)
|
|
112
|
+
break;
|
|
113
|
+
}
|
|
114
|
+
return open === index - 1 || tokens[open - 1] === 'map';
|
|
115
|
+
}
|
|
116
|
+
function lineTokens(line, state) {
|
|
117
|
+
const tokens = [];
|
|
118
|
+
const wordPattern = /[\p{L}_][\p{L}\p{N}_]*|\.?\d[\p{L}\p{N}_.]*/uy;
|
|
119
|
+
let index = 0;
|
|
120
|
+
while (index < line.length) {
|
|
121
|
+
if (state.rawString || state.blockComment) {
|
|
122
|
+
const end = line.indexOf(state.rawString ? '`' : '*/', index);
|
|
123
|
+
if (end === -1)
|
|
124
|
+
break;
|
|
125
|
+
if (state.rawString)
|
|
126
|
+
tokens.push('`');
|
|
127
|
+
index = end + (state.rawString ? 1 : 2);
|
|
128
|
+
state.rawString = false;
|
|
129
|
+
state.blockComment = false;
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
132
|
+
const character = line[index] || '';
|
|
133
|
+
if (/\s/.test(character)) {
|
|
134
|
+
index += 1;
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
137
|
+
if (line.startsWith('//', index))
|
|
138
|
+
break;
|
|
139
|
+
if (line.startsWith('/*', index)) {
|
|
140
|
+
state.blockComment = true;
|
|
141
|
+
index += 2;
|
|
142
|
+
continue;
|
|
143
|
+
}
|
|
144
|
+
if (character === '`') {
|
|
145
|
+
state.rawString = true;
|
|
146
|
+
index += 1;
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
149
|
+
if (character === '"' || character === "'") {
|
|
150
|
+
index += 1;
|
|
151
|
+
while (index < line.length && line[index] !== character) {
|
|
152
|
+
index += line[index] === '\\' ? 2 : 1;
|
|
93
153
|
}
|
|
94
|
-
|
|
95
|
-
|
|
154
|
+
tokens.push(character);
|
|
155
|
+
index += 1;
|
|
96
156
|
continue;
|
|
97
157
|
}
|
|
98
|
-
|
|
99
|
-
|
|
158
|
+
wordPattern.lastIndex = index;
|
|
159
|
+
const word = wordPattern.exec(line)?.[0];
|
|
160
|
+
if (word) {
|
|
161
|
+
tokens.push(/^[\p{L}_]/u.test(word) ? word : '0');
|
|
162
|
+
index += word.length;
|
|
100
163
|
continue;
|
|
101
164
|
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
else if (character === '(')
|
|
107
|
-
parens += 1;
|
|
108
|
-
else if (character === ')')
|
|
109
|
-
parens -= 1;
|
|
110
|
-
else if (character === '[')
|
|
111
|
-
brackets += 1;
|
|
112
|
-
else if (character === ']')
|
|
113
|
-
brackets -= 1;
|
|
165
|
+
const operator = ['++', '--', ':=', '...'].find((candidate) => line.startsWith(candidate, index)) ||
|
|
166
|
+
character;
|
|
167
|
+
tokens.push(operator);
|
|
168
|
+
index += operator.length;
|
|
114
169
|
}
|
|
115
|
-
return
|
|
170
|
+
return tokens;
|
|
116
171
|
}
|
|
117
172
|
function functionNameFromLine(line) {
|
|
118
173
|
const source = stripLineComment(line).trim();
|
|
119
174
|
const match = source.match(/^func\s+(?:\([^)]*\)\s*)?([A-Za-z_]\w*)\s*\(/);
|
|
120
175
|
return match?.[1] || null;
|
|
121
176
|
}
|
|
122
|
-
function shouldInstrumentLine(line
|
|
123
|
-
if (parenDepth > 0 || bracketDepth > 0)
|
|
124
|
-
return false;
|
|
177
|
+
function shouldInstrumentLine(line) {
|
|
125
178
|
const trimmed = stripLineComment(line).trim();
|
|
126
179
|
if (!trimmed)
|
|
127
180
|
return false;
|
|
@@ -190,31 +243,108 @@ function instrumentFunctionLines(source) {
|
|
|
190
243
|
const lines = source.split('\n');
|
|
191
244
|
const instrumented = [];
|
|
192
245
|
const functionStack = [];
|
|
246
|
+
const lexState = { rawString: false, blockComment: false };
|
|
247
|
+
const frames = [];
|
|
248
|
+
// Frame depths where a `func` signature still awaits its body, and where an if/for/switch
|
|
249
|
+
// header still awaits its block.
|
|
250
|
+
let pendingFunctionDepths = [];
|
|
251
|
+
let headerDepth = -1;
|
|
252
|
+
let closedFrame;
|
|
253
|
+
let previousToken = ';';
|
|
254
|
+
let continuesStatement = false;
|
|
255
|
+
let followsLabel = false;
|
|
193
256
|
let braceDepth = 0;
|
|
194
|
-
let parenDepth = 0;
|
|
195
|
-
let bracketDepth = 0;
|
|
196
257
|
for (let index = 0; index < lines.length; index += 1) {
|
|
197
258
|
const line = lines[index] || '';
|
|
198
259
|
const lineNumber = index + 1;
|
|
199
|
-
const
|
|
260
|
+
const startsInCode = !lexState.rawString && !lexState.blockComment;
|
|
261
|
+
const functionName = startsInCode ? functionNameFromLine(line) : null;
|
|
200
262
|
const inFunction = functionStack.length > 0;
|
|
201
263
|
const indent = line.match(/^\s*/)?.[0] || '';
|
|
202
|
-
|
|
264
|
+
// Only hook lines that start a statement directly inside a block: not inside a raw
|
|
265
|
+
// string, comment, composite literal, call or index, and not continuing the previous line.
|
|
266
|
+
if (inFunction &&
|
|
267
|
+
startsInCode &&
|
|
268
|
+
frames.at(-1) === 'block' &&
|
|
269
|
+
!frames.includes('(') &&
|
|
270
|
+
!frames.includes('[') &&
|
|
271
|
+
!continuesStatement &&
|
|
272
|
+
!followsLabel &&
|
|
273
|
+
shouldInstrumentLine(line)) {
|
|
203
274
|
instrumented.push(`${indent}__wasmIdleDebugLine(${lineNumber})`);
|
|
204
275
|
}
|
|
205
276
|
instrumented.push(line);
|
|
206
|
-
const
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
277
|
+
const tokens = lineTokens(line, lexState);
|
|
278
|
+
let braces = 0;
|
|
279
|
+
for (let tokenIndex = 0; tokenIndex < tokens.length; tokenIndex += 1) {
|
|
280
|
+
const token = tokens[tokenIndex] || '';
|
|
281
|
+
const depth = frames.length;
|
|
282
|
+
if (token === '(' || token === '[') {
|
|
283
|
+
frames.push(token);
|
|
284
|
+
}
|
|
285
|
+
else if (token === ')' || token === ']' || token === '}') {
|
|
286
|
+
closedFrame = frames.pop();
|
|
287
|
+
if (token === '}')
|
|
288
|
+
braces -= 1;
|
|
289
|
+
pendingFunctionDepths = pendingFunctionDepths.filter((pending) => pending <= frames.length);
|
|
290
|
+
if (headerDepth > frames.length)
|
|
291
|
+
headerDepth = -1;
|
|
292
|
+
}
|
|
293
|
+
else if (token === '{') {
|
|
294
|
+
let frame = '{';
|
|
295
|
+
if (pendingFunctionDepths.includes(depth)) {
|
|
296
|
+
frame = 'block';
|
|
297
|
+
pendingFunctionDepths = pendingFunctionDepths.filter((pending) => pending !== depth);
|
|
298
|
+
}
|
|
299
|
+
else if (previousToken === 'struct' || previousToken === 'interface') {
|
|
300
|
+
frame = 'type';
|
|
301
|
+
}
|
|
302
|
+
else if (['else', 'for', 'switch', 'select'].includes(previousToken) ||
|
|
303
|
+
(headerDepth === depth &&
|
|
304
|
+
tokenIndex === tokens.length - 1 &&
|
|
305
|
+
!followsLiteralType(tokens, tokenIndex, closedFrame)) ||
|
|
306
|
+
([';', '{', ':'].includes(previousToken) &&
|
|
307
|
+
(frames.at(-1) ?? 'block') === 'block')) {
|
|
308
|
+
// Go ends an if/for/switch header at the `{` that closes its line; any other
|
|
309
|
+
// `{` after an operand (`P{`, `[]int{`) opens a literal.
|
|
310
|
+
frame = 'block';
|
|
311
|
+
if (headerDepth === depth)
|
|
312
|
+
headerDepth = -1;
|
|
313
|
+
}
|
|
314
|
+
frames.push(frame);
|
|
315
|
+
braces += 1;
|
|
316
|
+
}
|
|
317
|
+
else if (token === 'func' && previousToken !== ']' && previousToken !== 'chan') {
|
|
318
|
+
pendingFunctionDepths.push(depth);
|
|
319
|
+
}
|
|
320
|
+
else if (['if', 'for', 'switch', 'select'].includes(token)) {
|
|
321
|
+
headerDepth = depth;
|
|
322
|
+
}
|
|
323
|
+
else if ([',', ';', '=', ':='].includes(token)) {
|
|
324
|
+
pendingFunctionDepths = pendingFunctionDepths.filter((pending) => pending !== depth);
|
|
325
|
+
}
|
|
326
|
+
previousToken = token;
|
|
327
|
+
}
|
|
328
|
+
const lastToken = tokens.at(-1);
|
|
329
|
+
if (lastToken !== undefined) {
|
|
330
|
+
const trimmed = stripLineComment(line).trim();
|
|
331
|
+
continuesStatement = !endsStatement(lastToken) && !['{', ':', ';'].includes(lastToken);
|
|
332
|
+
followsLabel = /^[A-Za-z_]\w*:$/.test(trimmed) && trimmed !== 'default:';
|
|
333
|
+
if (endsStatement(lastToken)) {
|
|
334
|
+
previousToken = ';';
|
|
335
|
+
pendingFunctionDepths = pendingFunctionDepths.filter((pending) => pending < frames.length);
|
|
336
|
+
if (headerDepth >= frames.length)
|
|
337
|
+
headerDepth = -1;
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
// A signature line that ends inside a raw string or block comment has no place for the
|
|
341
|
+
// entry hook; leave that function uninstrumented rather than edit the literal.
|
|
342
|
+
if (functionName && braces > 0 && !lexState.rawString && !lexState.blockComment) {
|
|
211
343
|
const bodyIndent = `${indent}\t`;
|
|
212
344
|
instrumented.push(`${bodyIndent}__wasmIdleDebugEnter(${JSON.stringify(functionName)}, ${lineNumber})`, `${bodyIndent}defer __wasmIdleDebugLeave()`);
|
|
213
|
-
functionStack.push({ depth:
|
|
345
|
+
functionStack.push({ depth: braceDepth + braces, name: functionName });
|
|
214
346
|
}
|
|
215
|
-
braceDepth
|
|
216
|
-
parenDepth = nextParenDepth;
|
|
217
|
-
bracketDepth = nextBracketDepth;
|
|
347
|
+
braceDepth += braces;
|
|
218
348
|
while (functionStack.length &&
|
|
219
349
|
braceDepth < functionStack[functionStack.length - 1].depth) {
|
|
220
350
|
functionStack.pop();
|
package/dist/playground/java.js
CHANGED
|
@@ -687,8 +687,9 @@ class Java {
|
|
|
687
687
|
resolve(results);
|
|
688
688
|
return;
|
|
689
689
|
}
|
|
690
|
-
if (error)
|
|
691
|
-
failRun(error);
|
|
690
|
+
if (Object.hasOwn(event.data, 'error')) {
|
|
691
|
+
failRun(error === '' ? 'Java execution failed' : error);
|
|
692
|
+
}
|
|
692
693
|
}
|
|
693
694
|
catch (error) {
|
|
694
695
|
failRun(error, true);
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/** A real Java entry point keeps exception formatting inside the Java class library. */
|
|
2
|
+
export declare function prepareJavaExceptionBridge(mainClass: string, sourceTexts: readonly string[], classFiles: readonly string[]): {
|
|
3
|
+
mainClass: string;
|
|
4
|
+
sourceFileName: string;
|
|
5
|
+
formatterSourceFileName: string;
|
|
6
|
+
formatExport: string;
|
|
7
|
+
source: string;
|
|
8
|
+
formatterSource: string;
|
|
9
|
+
};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/** A real Java entry point keeps exception formatting inside the Java class library. */
|
|
2
|
+
export function prepareJavaExceptionBridge(mainClass, sourceTexts, classFiles) {
|
|
3
|
+
const packageName = mainClass.slice(0, Math.max(0, mainClass.lastIndexOf('.')));
|
|
4
|
+
const packagePath = packageName ? `${packageName.replaceAll('.', '/')}/` : '';
|
|
5
|
+
const entryClass = mainClass.slice(mainClass.lastIndexOf('.') + 1);
|
|
6
|
+
const sourcePrefix = packageName ? `package ${packageName};\n\n` : '';
|
|
7
|
+
let className = 'WasmIdleJavaEntryPoint';
|
|
8
|
+
while (classFiles.some((path) => path === `${packagePath}${className}.class` ||
|
|
9
|
+
path.startsWith(`${packagePath}${className}$`)))
|
|
10
|
+
className += '_';
|
|
11
|
+
let formatterClass = 'WasmIdleJavaExceptionBridge';
|
|
12
|
+
while (classFiles.some((path) => path === `${packagePath}${formatterClass}.class` ||
|
|
13
|
+
path.startsWith(`${packagePath}${formatterClass}$`)))
|
|
14
|
+
formatterClass += '_';
|
|
15
|
+
// Conservatively reserve names even when user identifiers use Java Unicode escapes.
|
|
16
|
+
const decodedSources = sourceTexts.map((source) => source.replace(/\\u+([0-9a-f]{4})/gi, (_, hex) => String.fromCharCode(parseInt(hex, 16))));
|
|
17
|
+
let formatExport = 'wasmIdleFormatJavaException';
|
|
18
|
+
while (decodedSources.some((source) => source.includes(formatExport)))
|
|
19
|
+
formatExport += '_';
|
|
20
|
+
return {
|
|
21
|
+
mainClass: packageName ? `${packageName}.${formatterClass}` : formatterClass,
|
|
22
|
+
sourceFileName: `${className}.java`,
|
|
23
|
+
formatterSourceFileName: `${formatterClass}.java`,
|
|
24
|
+
formatExport,
|
|
25
|
+
// No imported types can hide the user entry class, even when it is named String.
|
|
26
|
+
source: `${sourcePrefix}final class ${className} {
|
|
27
|
+
static ${formatterClass}.Program program() {
|
|
28
|
+
return ${entryClass}::main;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
`,
|
|
32
|
+
formatterSource: `${sourcePrefix}import java.lang.String;
|
|
33
|
+
import java.lang.Throwable;
|
|
34
|
+
import java.io.StringWriter;
|
|
35
|
+
import java.io.PrintWriter;
|
|
36
|
+
import org.teavm.jso.JSExport;
|
|
37
|
+
import org.teavm.jso.JSObject;
|
|
38
|
+
import org.teavm.jso.JSExceptions;
|
|
39
|
+
|
|
40
|
+
final class ${formatterClass} {
|
|
41
|
+
interface Program {
|
|
42
|
+
void run(String[] args) throws Throwable;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
public static void main(String[] args) throws Throwable {
|
|
46
|
+
${className}.program().run(args);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
@JSExport
|
|
50
|
+
public static String ${formatExport}(JSObject error) {
|
|
51
|
+
Throwable exception = JSExceptions.getJavaException(error);
|
|
52
|
+
if (exception == null) return null;
|
|
53
|
+
StringWriter text = new StringWriter();
|
|
54
|
+
exception.printStackTrace(new PrintWriter(text));
|
|
55
|
+
return text.toString();
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
`
|
|
59
|
+
};
|
|
60
|
+
}
|
|
@@ -8,10 +8,10 @@ export declare const LEAN4_RUNTIME_MANIFEST: import("@wasm-idle/core").RuntimeRe
|
|
|
8
8
|
export declare function resolveLean4RuntimeAssetConfig(runtimeAssets: string | PlaygroundRuntimeAssets, currentUrl: string): {
|
|
9
9
|
baseUrl: string;
|
|
10
10
|
workerUrl: string;
|
|
11
|
-
manifestFingerprint: "
|
|
11
|
+
manifestFingerprint: "335bd6e1720371fc161859cb7c2858600ec12314c30da1f0e5e503e324a96d42";
|
|
12
12
|
workerReceipt: {
|
|
13
|
-
readonly bytes:
|
|
14
|
-
readonly sha256: "
|
|
13
|
+
readonly bytes: 16049;
|
|
14
|
+
readonly sha256: "3611a263c4304246c9ee2967c07be2a1c70764a39d642db87ba0b86bfbe9d519";
|
|
15
15
|
};
|
|
16
16
|
};
|
|
17
17
|
export declare function preflightLean4RuntimeAssets(baseUrl: string, options: {
|
|
@@ -21,5 +21,5 @@ export declare function preflightLean4RuntimeAssets(baseUrl: string, options: {
|
|
|
21
21
|
reportProgress?: (value: number, stage: string) => void;
|
|
22
22
|
fetch?: typeof globalThis.fetch;
|
|
23
23
|
}): Promise<Readonly<{
|
|
24
|
-
fingerprint: "
|
|
24
|
+
fingerprint: "335bd6e1720371fc161859cb7c2858600ec12314c30da1f0e5e503e324a96d42";
|
|
25
25
|
}>>;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { StaticWorkerRuntimeSandbox } from './staticWorkerRuntime';
|
|
2
2
|
import { preflightLfortranRuntimeAssets, resolveLfortranRuntimeAssetConfig } from './lfortranAssets';
|
|
3
|
+
import { WASM_LFORTRAN_PROFILE as profile } from './wasmLfortranVersion';
|
|
3
4
|
/** Real upstream FortranEvaluator using LLVM and Emscripten dynamic side modules. */
|
|
4
5
|
export default class LFortran extends StaticWorkerRuntimeSandbox {
|
|
5
6
|
memoryEvidence;
|
|
@@ -20,6 +21,15 @@ export default class LFortran extends StaticWorkerRuntimeSandbox {
|
|
|
20
21
|
},
|
|
21
22
|
stdin: { mode: 'streaming', sourceHintPattern: /\bread\b/i },
|
|
22
23
|
resolveRuntimeAssets: resolveLfortranRuntimeAssetConfig,
|
|
24
|
+
compilerModules() {
|
|
25
|
+
return {
|
|
26
|
+
compiler: {
|
|
27
|
+
receipt: profile.assets['lfortran.wasm'],
|
|
28
|
+
// Defined memories live in fresh instances; the compiler imports the job's bounded memory.
|
|
29
|
+
compileKey: 'lfortran-native-imported-memory-v1'
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
},
|
|
23
33
|
async preflightRuntimeAssets(urls, context) {
|
|
24
34
|
memoryEvidence.current = undefined;
|
|
25
35
|
return context.createOwnedDelivery(await preflightLfortranRuntimeAssets(urls.baseUrl, context));
|
|
@@ -7,8 +7,8 @@ export declare function resolveLfortranRuntimeAssetConfig(assets: string | Playg
|
|
|
7
7
|
workerUrl: string;
|
|
8
8
|
manifestFingerprint: "11c9baef85c5221440edc4462690312cda62b48998a133b9a397ce32c6a97c45";
|
|
9
9
|
workerReceipt: {
|
|
10
|
-
readonly bytes:
|
|
11
|
-
readonly sha256: "
|
|
10
|
+
readonly bytes: 13875;
|
|
11
|
+
readonly sha256: "6443226c53cdadbbfdc25d43d1c07c4f13d8855cfe5cfd609f45ca9b29a96cdf";
|
|
12
12
|
};
|
|
13
13
|
};
|
|
14
14
|
export declare function preflightLfortranRuntimeAssets(baseUrl: string, options: {
|
package/dist/playground/nim.js
CHANGED
|
@@ -14,6 +14,28 @@ class Nim extends StaticWorkerRuntimeSandbox {
|
|
|
14
14
|
sourceHintPattern: /\b(?:stdin|readLine|readAll|lines)\b/i
|
|
15
15
|
},
|
|
16
16
|
inlineVerifiedWorker: true,
|
|
17
|
+
includeExecutionLimits: true,
|
|
18
|
+
compilerModules(urls) {
|
|
19
|
+
const profile = snapshotNimRuntimePreflightProfile(urls.preflightProfile);
|
|
20
|
+
return Object.fromEntries([
|
|
21
|
+
['nim', profile.nimWasmReceipt],
|
|
22
|
+
['clang', profile.clangWasmReceipt],
|
|
23
|
+
['lld', profile.lldWasmReceipt],
|
|
24
|
+
['memfs', profile.memfsWasmReceipt]
|
|
25
|
+
].map(([key, receipt]) => {
|
|
26
|
+
const integrity = receipt;
|
|
27
|
+
return [
|
|
28
|
+
key,
|
|
29
|
+
{
|
|
30
|
+
receipt: {
|
|
31
|
+
bytes: integrity.uncompressedBytes,
|
|
32
|
+
sha256: integrity.uncompressedSha256
|
|
33
|
+
},
|
|
34
|
+
compileKey: 'nim-llvm8-native-v1'
|
|
35
|
+
}
|
|
36
|
+
];
|
|
37
|
+
}));
|
|
38
|
+
},
|
|
17
39
|
resolveRuntimeAssets(runtimeAssets, currentUrl) {
|
|
18
40
|
const resolved = resolveNimRuntimeAssetConfig(runtimeAssets, currentUrl);
|
|
19
41
|
const profile = snapshotNimRuntimePreflightProfile(resolved.preflightProfile);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { WorkerAssetBridge } from './assetBridge';
|
|
2
|
+
import type { RuntimeAssetCache } from './runtimeAssetCache';
|
|
2
3
|
import type { DebugCommand, DebugSessionEvent } from './options';
|
|
3
4
|
import { type PlaygroundRuntimeAssets } from './assets';
|
|
4
5
|
import type { SandboxExecutionOptions } from './options';
|
|
@@ -24,8 +25,10 @@ declare class ObjectiveC implements Sandbox {
|
|
|
24
25
|
exit: boolean;
|
|
25
26
|
assetBridge: WorkerAssetBridge | null;
|
|
26
27
|
activeObjectiveCAssetsKey: string;
|
|
28
|
+
private runtimeAssetCache?;
|
|
27
29
|
private readonly workerSession;
|
|
28
30
|
constructor(language?: ObjectiveCSandboxLanguage);
|
|
31
|
+
setRuntimeAssetCache(cache: RuntimeAssetCache): void;
|
|
29
32
|
load(runtimeAssets?: string | PlaygroundRuntimeAssets, code?: string, log?: boolean, args?: string[], options?: SandboxExecutionOptions, progress?: SandboxProgress): Promise<void>;
|
|
30
33
|
write(input: string): void;
|
|
31
34
|
eof(): void;
|
|
@@ -5,7 +5,7 @@ import { createWasmIdleSharedBuffer, requireSharedArrayBuffer } from './sharedBu
|
|
|
5
5
|
import { WorkerSession } from './workerSession';
|
|
6
6
|
import { reportWorkerInputReady } from './workerProgress';
|
|
7
7
|
import { bufferedSequence, flushBufferedEof, flushQueuedStdin, resetBufferedStdin, waitForBufferedSequenceChange } from './stdinBuffer';
|
|
8
|
-
import { AssetTooLargeError, createRuntimeAssetsKey, resolveExecutionLimits } from '@wasm-idle/core';
|
|
8
|
+
import { AssetTooLargeError, RuntimeConfigurationError, createRuntimeAssetsKey, resolveExecutionLimits } from '@wasm-idle/core';
|
|
9
9
|
const debugBreakpointBufferInts = 1028;
|
|
10
10
|
const objectiveCAssetsKey = (assets) => createRuntimeAssetsKey({ objectivec: assets }) || '';
|
|
11
11
|
class ObjectiveC {
|
|
@@ -28,6 +28,7 @@ class ObjectiveC {
|
|
|
28
28
|
exit = true;
|
|
29
29
|
assetBridge = null;
|
|
30
30
|
activeObjectiveCAssetsKey = '';
|
|
31
|
+
runtimeAssetCache;
|
|
31
32
|
workerSession = new WorkerSession({
|
|
32
33
|
label: 'Objective-C',
|
|
33
34
|
onDispose: (worker) => {
|
|
@@ -52,6 +53,14 @@ class ObjectiveC {
|
|
|
52
53
|
constructor(language = 'OBJC') {
|
|
53
54
|
this.language = language;
|
|
54
55
|
}
|
|
56
|
+
setRuntimeAssetCache(cache) {
|
|
57
|
+
if (this.runtimeAssetCache === cache)
|
|
58
|
+
return;
|
|
59
|
+
if (this.worker) {
|
|
60
|
+
throw new RuntimeConfigurationError('Cannot replace an active Objective-C compiler cache');
|
|
61
|
+
}
|
|
62
|
+
this.runtimeAssetCache = cache;
|
|
63
|
+
}
|
|
55
64
|
load(runtimeAssets = '', code = '', log = true, args = [], options = {}, progress) {
|
|
56
65
|
let limits;
|
|
57
66
|
try {
|
|
@@ -93,7 +102,7 @@ class ObjectiveC {
|
|
|
93
102
|
if (!this.workerSession.attach(worker, operation))
|
|
94
103
|
return;
|
|
95
104
|
this.worker = worker;
|
|
96
|
-
this.assetBridge = new WorkerAssetBridge(this.worker, 'clang', clangAssets, progress, limits.maxAssetBytes);
|
|
105
|
+
this.assetBridge = new WorkerAssetBridge(this.worker, 'clang', clangAssets, progress, limits.maxAssetBytes, false, this.runtimeAssetCache);
|
|
97
106
|
this.activeObjectiveCAssetsKey = nextObjectiveCAssetsKey;
|
|
98
107
|
this.worker.onmessage = (event) => {
|
|
99
108
|
if (!this.workerSession.isActive(operation))
|
|
@@ -40,6 +40,8 @@ export interface SandboxExecutionOptions {
|
|
|
40
40
|
workspaceFiles?: SandboxWorkspaceFile[];
|
|
41
41
|
compileArgs?: string[];
|
|
42
42
|
programArgs?: string[];
|
|
43
|
+
/** Requested environment overrides; a runtime may reject unsupported options. */
|
|
44
|
+
env?: Record<string, string>;
|
|
43
45
|
cppVersion?: string;
|
|
44
46
|
cVersion?: string;
|
|
45
47
|
rustTargetTriple?: RustTargetTriple;
|
|
@@ -380,6 +380,14 @@ class Python {
|
|
|
380
380
|
activePath = options.activePath;
|
|
381
381
|
debugPath = options.debugPath;
|
|
382
382
|
workspaceFiles = options.workspaceFiles;
|
|
383
|
+
if (this.workerLanguage === 'python') {
|
|
384
|
+
if (_args.length || options.programArgs?.length) {
|
|
385
|
+
throw new RuntimeConfigurationError('Python does not support program arguments', { runtimeId: this.runtimeId });
|
|
386
|
+
}
|
|
387
|
+
if (options.env !== undefined) {
|
|
388
|
+
throw new RuntimeConfigurationError('Python does not support environment overrides', { runtimeId: this.runtimeId });
|
|
389
|
+
}
|
|
390
|
+
}
|
|
383
391
|
if (this.usesInterpreterStdio) {
|
|
384
392
|
limits = resolveExecutionLimits(options.limits);
|
|
385
393
|
if (_args.length || options.programArgs?.length) {
|
|
@@ -1,32 +1 @@
|
|
|
1
|
-
|
|
2
|
-
export declare class RuntimeAssetCache {
|
|
3
|
-
private readonly maxBytes;
|
|
4
|
-
private readonly maxEntries;
|
|
5
|
-
private entries;
|
|
6
|
-
private inFlight;
|
|
7
|
-
private inFlightKeyBytes;
|
|
8
|
-
private identities;
|
|
9
|
-
private nextIdentity;
|
|
10
|
-
private bytes;
|
|
11
|
-
private hits;
|
|
12
|
-
private misses;
|
|
13
|
-
private disposed;
|
|
14
|
-
constructor(maxBytes?: number, maxEntries?: number);
|
|
15
|
-
/** Identity is owner-local; a custom loader must never alias another loader. */
|
|
16
|
-
identity(value: object | undefined): number;
|
|
17
|
-
get<T>(key: string): T | undefined;
|
|
18
|
-
/** Only the trusted host publishes fully verified results; failures are never retained. */
|
|
19
|
-
set<T>(key: string, value: T, bytes: number): void;
|
|
20
|
-
/** Share work, but give every consumer its own cancellation and progress subscription. */
|
|
21
|
-
share<T, Progress = never>(key: string, signal: AbortSignal, start: (signal: AbortSignal, report: (progress: Progress, progressKey?: string) => void) => Promise<T>, onProgress?: (progress: Progress) => void): Promise<T>;
|
|
22
|
-
private removeOperation;
|
|
23
|
-
stats(): {
|
|
24
|
-
hits: number;
|
|
25
|
-
misses: number;
|
|
26
|
-
entries: number;
|
|
27
|
-
bytes: number;
|
|
28
|
-
inFlight: number;
|
|
29
|
-
disposed: boolean;
|
|
30
|
-
};
|
|
31
|
-
dispose(): void;
|
|
32
|
-
}
|
|
1
|
+
export { RuntimeAssetCache } from '@wasm-idle/core';
|