@wasm-oj/server 0.2.0 → 0.2.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.
@@ -1,97 +1,786 @@
1
- import { C as JAVA_COMPILE_CLASSLIB_ASSET_PATH, E as JAVA_RUNTIME_CLASSLIB_SHA256, S as JAVA_COMPILER_PACKAGE_SHA256, T as JAVA_RUNTIME_CLASSLIB_ASSET_PATH, b as JAVA_COMPILER_COMPRESSED_PACKAGE_SHA256, w as JAVA_COMPILE_CLASSLIB_SHA256, y as JAVA_COMPILER_ASSET_PATH } from "./chunks/toolchains-C6KuA1yM.js";
2
- import { n as javaMainClass, r as parseJavaDiagnostics, t as JAVA_COMPILE_TIMEOUT_MS } from "./chunks/java-toolchain-DajoRCHu.js";
1
+ import { C as JAVA_COMPILE_CLASSLIB_SHA256, S as JAVA_COMPILE_CLASSLIB_ASSET_PATH, T as JAVA_RUNTIME_CLASSLIB_SHA256, w as JAVA_RUNTIME_CLASSLIB_ASSET_PATH, x as JAVA_COMPILER_SHA256, y as JAVA_COMPILER_ASSET_PATH } from "./chunks/toolchains-uz3XbZGI.js";
3
2
  import { writeFileSync } from "node:fs";
4
3
  import { readFile } from "node:fs/promises";
5
4
  import { createHash } from "node:crypto";
6
5
  import path from "node:path";
7
- import { gunzipSync } from "node:zlib";
8
- import { Directory, Runtime, Wasmer, init } from "@wasmer/sdk/node";
9
- //#region src/server/java-stage.mjs
10
- var runtime;
11
- var packageHandle;
12
- var project;
13
- var toolchain;
14
- var exitCode = 0;
15
- try {
16
- const encoded = JSON.parse(await readStdin());
17
- if (encoded.request?.entry === void 0) throw new Error("The Java compiler stage received no entry file.");
18
- await init({ log: "error" });
19
- runtime = new Runtime({ registry: null });
20
- const compilerBytes = await loadCompiler(requiredToolchainAsset(encoded, JAVA_COMPILER_ASSET_PATH), encoded.verifiedToolchain === true);
21
- packageHandle = await Wasmer.fromFile(compilerBytes, runtime);
22
- const command = packageHandle.commands["java-compiler"];
23
- if (!command) throw new Error("The pinned Java compiler package does not expose java-compiler.");
24
- project = new Directory(Object.fromEntries(encoded.request.files.map((file) => [`/${file.path}`, file.content])));
25
- await project.createDir("/build");
26
- toolchain = new Directory({
27
- "/compile-classlib-teavm.bin": await loadRaw(requiredToolchainAsset(encoded, JAVA_COMPILE_CLASSLIB_ASSET_PATH), JAVA_COMPILE_CLASSLIB_SHA256, encoded.verifiedToolchain === true),
28
- "/runtime-classlib-teavm.bin": await loadRaw(requiredToolchainAsset(encoded, JAVA_RUNTIME_CLASSLIB_ASSET_PATH), JAVA_RUNTIME_CLASSLIB_SHA256, encoded.verifiedToolchain === true)
6
+ //#region src/compiler/vendor/java-compiler-runtime.mjs
7
+ var exceptionFrameRegex = /.+:wasm-function\[[0-9]+]:0x([0-9a-f]+).*/;
8
+ var getGlobalName = function(name) {
9
+ return name.split(".").reduce((object, key) => object[key], globalThis);
10
+ };
11
+ var setGlobalName = function(name, value) {
12
+ const path = name.split(".");
13
+ const key = path.pop();
14
+ const object = path.reduce((object, key) => object[key], globalThis);
15
+ object[key] = value;
16
+ };
17
+ function defaults(imports, userExports, options, module, stringBuiltins) {
18
+ let context = {
19
+ exports: null,
20
+ userExports,
21
+ stackDeobfuscator: null
22
+ };
23
+ if (!stringBuiltins) stringImports(imports);
24
+ dateImports(imports);
25
+ consoleImports(imports, context);
26
+ coreImports(imports, context, options, module);
27
+ asyncImports(imports, context);
28
+ jsoImports(imports, context, stringBuiltins, options);
29
+ imports.teavmMath = Math;
30
+ return {
31
+ supplyExports(exports) {
32
+ context.exports = exports;
33
+ },
34
+ supplyStackDeobfuscator(deobfuscator) {
35
+ context.stackDeobfuscator = deobfuscator;
36
+ }
37
+ };
38
+ }
39
+ var javaExceptionSymbol = Symbol("javaException");
40
+ var JavaError = class extends Error {
41
+ #context;
42
+ constructor(context, javaException) {
43
+ super();
44
+ this.#context = context;
45
+ this[javaExceptionSymbol] = javaException;
46
+ context.exports["teavm.setJsException"](javaException, this);
47
+ }
48
+ get message() {
49
+ let exceptionMessage = this.#context.exports["teavm.exceptionMessage"];
50
+ let stringToJs = this.#context.exports["teavm.stringToJs"];
51
+ if (typeof exceptionMessage === "function" && typeof stringToJs === "function") {
52
+ let message = exceptionMessage(this[javaExceptionSymbol]);
53
+ if (message != null) return stringToJs(message);
54
+ }
55
+ return "(could not fetch message)";
56
+ }
57
+ };
58
+ function stringImports(imports) {
59
+ imports["wasm:js-string"] = {
60
+ fromCharCode: (code) => String.fromCharCode(code),
61
+ fromCharCodeArray: () => {
62
+ throw new Error("Not supported");
63
+ },
64
+ intoCharCodeArray: () => {
65
+ throw new Error("Not supported");
66
+ },
67
+ concat: (first, second) => first + second,
68
+ charCodeAt: (string, index) => string.charCodeAt(index),
69
+ length: (s) => s.length,
70
+ substring: (s, start, end) => s.substring(start, end)
71
+ };
72
+ }
73
+ function dateImports(imports) {
74
+ imports.teavmDate = {
75
+ currentTimeMillis: () => (/* @__PURE__ */ new Date()).getTime(),
76
+ dateToString: (timestamp) => new Date(timestamp).toString(),
77
+ getYear: (timestamp) => new Date(timestamp).getFullYear(),
78
+ setYear(timestamp, year) {
79
+ let date = new Date(timestamp);
80
+ date.setFullYear(year);
81
+ return date.getTime();
82
+ },
83
+ getMonth: (timestamp) => new Date(timestamp).getMonth(),
84
+ setMonth(timestamp, month) {
85
+ let date = new Date(timestamp);
86
+ date.setMonth(month);
87
+ return date.getTime();
88
+ },
89
+ getDate: (timestamp) => new Date(timestamp).getDate(),
90
+ setDate(timestamp, value) {
91
+ let date = new Date(timestamp);
92
+ date.setDate(value);
93
+ return date.getTime();
94
+ },
95
+ create: (year, month, date, hrs, min, sec) => new Date(year, month, date, hrs, min, sec).getTime(),
96
+ createFromUTC: (year, month, date, hrs, min, sec) => Date.UTC(year, month, date, hrs, min, sec)
97
+ };
98
+ }
99
+ function consoleImports(imports) {
100
+ let stderr = "";
101
+ let stdout = "";
102
+ imports.teavmConsole = {
103
+ putcharStderr(c) {
104
+ if (c === 10) {
105
+ console.error(stderr);
106
+ stderr = "";
107
+ } else stderr += String.fromCharCode(c);
108
+ },
109
+ putcharStdout(c) {
110
+ if (c === 10) {
111
+ console.log(stdout);
112
+ stdout = "";
113
+ } else stdout += String.fromCharCode(c);
114
+ }
115
+ };
116
+ }
117
+ function coreImports(imports, context, options, module) {
118
+ let memoryOptions = options.memory || {};
119
+ let finalizationRegistry = new FinalizationRegistry((heldValue) => {
120
+ let report = context.exports["teavm.reportGarbageCollectedValue"];
121
+ if (typeof report !== "undefined") report(heldValue.queue, heldValue.ref);
29
122
  });
30
- const entrySource = encoded.request.files.find((file) => file.path === encoded.request.entry);
31
- if (!entrySource) throw new Error(`Java entry '${encoded.request.entry}' does not exist.`);
32
- const output = await withTimeout((await command.run({
33
- args: [
34
- "/toolchain/compile-classlib-teavm.bin",
35
- "/toolchain/runtime-classlib-teavm.bin",
36
- javaMainClass(encoded.request.entry, entrySource.content),
37
- "/project/build/app.wasm",
38
- ...encoded.request.files.filter((file) => file.path.endsWith(".java")).map((file) => `/project/${file.path}`)
39
- ],
40
- mount: {
41
- "/project": project,
42
- "/toolchain": toolchain
123
+ let stringFinalizationRegistry = new FinalizationRegistry((heldValue) => {
124
+ let report = context.exports["teavm.reportGarbageCollectedString"];
125
+ if (typeof report === "function") report(heldValue);
126
+ });
127
+ imports.teavm = {
128
+ createWeakRef(value, ref, queue) {
129
+ if (queue !== null) finalizationRegistry.register(value, {
130
+ ref,
131
+ queue
132
+ });
133
+ return new WeakRef(value);
134
+ },
135
+ deref: (weakRef) => {
136
+ let result = weakRef.deref();
137
+ return result !== void 0 ? result : null;
138
+ },
139
+ createStringWeakRef(value, heldValue) {
140
+ stringFinalizationRegistry.register(value, heldValue);
141
+ return new WeakRef(value);
142
+ },
143
+ stringDeref: (weakRef) => weakRef.deref(),
144
+ takeStackTrace() {
145
+ let stack = (/* @__PURE__ */ new Error()).stack;
146
+ let addresses = [];
147
+ for (let line of stack.split("\n")) {
148
+ let match = exceptionFrameRegex.exec(line);
149
+ if (match !== null && match.length >= 2) {
150
+ let address = parseInt(match[1], 16);
151
+ addresses.push(address);
152
+ }
153
+ }
154
+ return { getStack() {
155
+ let result;
156
+ if (context.stackDeobfuscator) try {
157
+ result = context.stackDeobfuscator(addresses);
158
+ } catch (e) {
159
+ console.warn("Could not deobfuscate stack", e);
160
+ }
161
+ if (!result) result = addresses.map((address) => {
162
+ return {
163
+ className: "java.lang.Throwable$FakeClass",
164
+ method: "fakeMethod",
165
+ file: "Throwable.java",
166
+ line: address
167
+ };
168
+ });
169
+ return result;
170
+ } };
171
+ },
172
+ decorateException(javaException) {
173
+ new JavaError(context, javaException);
174
+ },
175
+ linearMemory() {
176
+ return context.exports["teavm.memory"].buffer;
177
+ },
178
+ notifyHeapResized: memoryOptions.onResize || function() {}
179
+ };
180
+ if (module) {
181
+ let memDefaults = getMemoryDefaults(module);
182
+ if (memDefaults !== null ? memDefaults.imported : hasImportedMemory(module)) {
183
+ let memoryInstance = memoryOptions["external"];
184
+ if (!memoryInstance) {
185
+ if (memDefaults === null) memDefaults = {};
186
+ let minSize = memoryOptions.minSize || memDefaults.min || 0;
187
+ let maxSize = memoryOptions.maxSize || memDefaults.max;
188
+ memoryInstance = new WebAssembly.Memory({
189
+ shared: memoryOptions.shared === true,
190
+ initial: minSize,
191
+ maximum: maxSize
192
+ });
193
+ }
194
+ imports.teavm.memory = memoryInstance;
43
195
  }
44
- })).wait(), JAVA_COMPILE_TIMEOUT_MS);
45
- const diagnostics = parseJavaDiagnostics(`${output.stderr}\n${output.stdout}`, encoded.request.entry);
46
- let wasmBase64;
47
- if (output.ok) {
48
- const wasm = await project.readFile("/build/app.wasm");
196
+ }
197
+ }
198
+ function asyncImports(imports) {
199
+ imports.teavmAsync = {
200
+ offer(instance, fn, time) {
201
+ let dt = Math.max(0, time - Date.now());
202
+ return setTimeout(() => {
203
+ fn(instance);
204
+ }, dt);
205
+ },
206
+ kill(id) {
207
+ clearTimeout(id);
208
+ }
209
+ };
210
+ }
211
+ function hasImportedMemory(module) {
212
+ return WebAssembly.Module.imports(module).findIndex(({ module, name, kind }) => module === "teavm" && name === "memory" && kind === "memory") >= 0;
213
+ }
214
+ function getMemoryDefaults(module) {
215
+ let sections = WebAssembly.Module.customSections(module, "teavm.memoryRequirements");
216
+ if (sections.length !== 1) return null;
217
+ return JSON.parse(new TextDecoder().decode(sections[0]));
218
+ }
219
+ function jsoImports(imports, context, stringBuiltins, options) {
220
+ let javaObjectSymbol = Symbol("javaObject");
221
+ let functionsSymbol = Symbol("functions");
222
+ let functionOriginSymbol = Symbol("functionOrigin");
223
+ let wrapperCallMarkerSymbol = Symbol("wrapperCallMarker");
224
+ let jsWrappers = /* @__PURE__ */ new WeakMap();
225
+ let javaWrappers = /* @__PURE__ */ new WeakMap();
226
+ let primitiveWrappers = /* @__PURE__ */ new Map();
227
+ let primitiveFinalization = new FinalizationRegistry((token) => primitiveWrappers.delete(token));
228
+ let hashCodes = /* @__PURE__ */ new WeakMap();
229
+ let lastHashCode = 2463534242;
230
+ let nextHashCode = () => {
231
+ let x = lastHashCode;
232
+ x ^= x << 13;
233
+ x ^= x >>> 17;
234
+ x ^= x << 5;
235
+ lastHashCode = x;
236
+ return x;
237
+ };
238
+ function identity(value) {
239
+ return value;
240
+ }
241
+ function sanitizeName(str) {
242
+ let result = "";
243
+ let firstChar = str.charAt(0);
244
+ result += isIdentifierStart(firstChar) ? firstChar : "_";
245
+ for (let i = 1; i < str.length; ++i) {
246
+ let c = str.charAt(i);
247
+ result += isIdentifierPart(c) ? c : "_";
248
+ }
249
+ return result;
250
+ }
251
+ function isIdentifierStart(s) {
252
+ return s >= "A" && s <= "Z" || s >= "a" && s <= "z" || s === "_" || s === "$";
253
+ }
254
+ function isIdentifierPart(s) {
255
+ return isIdentifierStart(s) || s >= "0" && s <= "9";
256
+ }
257
+ function setProperty(obj, prop, value) {
258
+ if (obj === null) setGlobalName(prop, value);
259
+ else obj[prop] = value;
260
+ }
261
+ function javaExceptionToJs(e) {
262
+ if (e instanceof WebAssembly.Exception) {
263
+ let tag = context.exports["teavm.javaException"];
264
+ let getJsException = context.exports["teavm.getJsException"];
265
+ if (e.is(tag)) {
266
+ let javaException = e.getArg(tag, 0);
267
+ let extracted = extractException(javaException);
268
+ if (extracted !== null) return extracted;
269
+ let wrapper = getJsException(javaException);
270
+ if (typeof wrapper === "undefined") wrapper = new JavaError(context, javaException);
271
+ return wrapper;
272
+ }
273
+ }
274
+ return e;
275
+ }
276
+ function jsExceptionAsJava(e) {
277
+ if (javaExceptionSymbol in e) return e[javaExceptionSymbol];
278
+ else return context.exports["teavm.js.wrapException"](e);
279
+ }
280
+ function rethrowJsAsJava(e) {
281
+ context.exports["teavm.js.throwException"](jsExceptionAsJava(e));
282
+ }
283
+ function extractException(e) {
284
+ return context.exports["teavm.js.extractException"](e);
285
+ }
286
+ function rethrowJavaAsJs(e) {
287
+ throw javaExceptionToJs(e);
288
+ }
289
+ function getProperty(obj, prop) {
290
+ try {
291
+ return obj !== null ? obj[prop] : getGlobalName(prop);
292
+ } catch (e) {
293
+ rethrowJsAsJava(e);
294
+ }
295
+ }
296
+ function defineFunction(fn, vararg) {
297
+ const count = fn.length - (vararg ? 1 : 0);
298
+ const wrapper = function(...args) {
299
+ try {
300
+ return vararg ? fn(...Array.from({ length: count }, (_, index) => args[index]), args.slice(count)) : fn(...Array.from({ length: count }, (_, index) => args[index]));
301
+ } catch (e) {
302
+ rethrowJavaAsJs(e);
303
+ }
304
+ };
305
+ Object.defineProperty(wrapper, "length", { value: count });
306
+ return wrapper;
307
+ }
308
+ function renameConstructor(name, constructor) {
309
+ return { [name]: function(marker, javaObject) {
310
+ return constructor.call(this, marker, javaObject);
311
+ } }[name];
312
+ }
313
+ imports.teavmJso = {
314
+ stringBuiltinsSupported: () => stringBuiltins,
315
+ isUndefined: (o) => typeof o === "undefined",
316
+ emptyArray: () => [],
317
+ appendToArray: (array, e) => array.push(e),
318
+ unwrapBoolean: (value) => value ? 1 : 0,
319
+ wrapBoolean: (value) => !!value,
320
+ getProperty,
321
+ setProperty,
322
+ setPropertyPure: setProperty,
323
+ global(name) {
324
+ try {
325
+ return getGlobalName(name);
326
+ } catch (e) {
327
+ rethrowJsAsJava(e);
328
+ }
329
+ },
330
+ createClass(name, parent, constructor) {
331
+ name = sanitizeName(name || "JavaObject");
332
+ let action;
333
+ let fn = renameConstructor(name, function(marker, javaObject) {
334
+ if (marker === wrapperCallMarkerSymbol) action.call(this, javaObject);
335
+ else if (constructor === null) throw new Error("This class can't be instantiated directly");
336
+ else try {
337
+ return constructor.apply(null, arguments);
338
+ } catch (e) {
339
+ rethrowJavaAsJs(e);
340
+ }
341
+ });
342
+ if (parent === null) action = function(javaObject) {
343
+ this[javaObjectSymbol] = javaObject;
344
+ this[functionsSymbol] = null;
345
+ };
346
+ else action = function(javaObject) {
347
+ parent.call(this, javaObject);
348
+ };
349
+ fn.prototype = Object.create(parent ? parent.prototype : Object.prototype);
350
+ fn.prototype.constructor = fn;
351
+ let boundFn = renameConstructor(name, function(javaObject) {
352
+ return fn.call(this, wrapperCallMarkerSymbol, javaObject);
353
+ });
354
+ boundFn[wrapperCallMarkerSymbol] = fn;
355
+ boundFn.prototype = fn.prototype;
356
+ return boundFn;
357
+ },
358
+ exportClass(cls) {
359
+ return cls[wrapperCallMarkerSymbol];
360
+ },
361
+ defineMethod(cls, name, fn, vararg) {
362
+ const method = defineFunction(fn, vararg);
363
+ cls.prototype[name] = function(...args) {
364
+ return method(this, ...args);
365
+ };
366
+ Object.defineProperty(cls.prototype[name], "length", { value: method.length - 1 });
367
+ },
368
+ defineStaticMethod(cls, name, fn, vararg) {
369
+ cls[name] = defineFunction(fn, vararg);
370
+ },
371
+ defineFunction,
372
+ defineProperty(cls, name, getFn, setFn) {
373
+ let descriptor = { get() {
374
+ try {
375
+ return getFn(this);
376
+ } catch (e) {
377
+ rethrowJavaAsJs(e);
378
+ }
379
+ } };
380
+ if (setFn !== null) descriptor.set = function(value) {
381
+ try {
382
+ setFn(this, value);
383
+ } catch (e) {
384
+ rethrowJavaAsJs(e);
385
+ }
386
+ };
387
+ Object.defineProperty(cls.prototype, name, descriptor);
388
+ },
389
+ defineStaticProperty(cls, name, getFn, setFn) {
390
+ let descriptor = { get() {
391
+ try {
392
+ return getFn();
393
+ } catch (e) {
394
+ rethrowJavaAsJs(e);
395
+ }
396
+ } };
397
+ if (setFn !== null) descriptor.set = function(value) {
398
+ try {
399
+ setFn(value);
400
+ } catch (e) {
401
+ rethrowJavaAsJs(e);
402
+ }
403
+ };
404
+ Object.defineProperty(cls, name, descriptor);
405
+ },
406
+ javaObjectToJS(instance, cls) {
407
+ if (instance === null) return null;
408
+ let existing = jsWrappers.get(instance);
409
+ if (typeof existing != "undefined") {
410
+ let result = existing.deref();
411
+ if (typeof result !== "undefined") return result;
412
+ }
413
+ let obj = new cls(instance);
414
+ jsWrappers.set(instance, new WeakRef(obj));
415
+ return obj;
416
+ },
417
+ unwrapJavaObject(instance) {
418
+ return instance[javaObjectSymbol];
419
+ },
420
+ asFunction(instance, propertyName) {
421
+ if (instance === null || instance === void 0) return null;
422
+ let functions = instance[functionsSymbol];
423
+ if (functions === null) {
424
+ functions = Object.create(null);
425
+ instance[functionsSymbol] = functions;
426
+ }
427
+ let result = functions[propertyName];
428
+ if (typeof result !== "function") {
429
+ result = function() {
430
+ return instance[propertyName].apply(instance, arguments);
431
+ };
432
+ result[functionOriginSymbol] = instance;
433
+ functions[propertyName] = result;
434
+ }
435
+ return result;
436
+ },
437
+ functionAsObject(fn, property) {
438
+ if (fn === null || fn === void 0) return null;
439
+ let origin = fn[functionOriginSymbol];
440
+ if (typeof origin !== "undefined") {
441
+ let functions = origin[functionsSymbol];
442
+ if (functions !== void 0 && functions[property] === fn) return origin;
443
+ }
444
+ return { [property]: function(...args) {
445
+ try {
446
+ return fn(...args);
447
+ } catch (e) {
448
+ rethrowJavaAsJs(e);
449
+ }
450
+ } };
451
+ },
452
+ wrapObject(obj) {
453
+ if (obj === null) return null;
454
+ if (typeof obj === "object" || typeof obj === "function" || false) {
455
+ let result = obj[javaObjectSymbol];
456
+ if (typeof result === "object") return result;
457
+ result = javaWrappers.get(obj);
458
+ if (result !== void 0) {
459
+ result = result.deref();
460
+ if (result !== void 0) return result;
461
+ }
462
+ result = context.exports["teavm.jso.createWrapper"](obj);
463
+ javaWrappers.set(obj, new WeakRef(result));
464
+ return result;
465
+ } else {
466
+ let result = primitiveWrappers.get(obj);
467
+ if (result !== void 0) {
468
+ result = result.deref();
469
+ if (result !== void 0) return result;
470
+ }
471
+ result = context.exports["teavm.jso.createWrapper"](obj);
472
+ primitiveWrappers.set(obj, new WeakRef(result));
473
+ primitiveFinalization.register(result, obj);
474
+ return result;
475
+ }
476
+ },
477
+ isPrimitive: (value, type) => typeof value === type || value === null,
478
+ instanceOf: (value, type) => value instanceof type,
479
+ instanceOfOrNull: (value, type) => value === null || value instanceof type,
480
+ sameRef: (a, b) => a === b,
481
+ hashCode: (obj) => {
482
+ if (typeof obj === "object" || typeof obj === "function" || typeof obj === "symbol") {
483
+ let code = hashCodes.get(obj);
484
+ if (typeof code === "number") return code;
485
+ code = nextHashCode();
486
+ hashCodes.set(obj, code);
487
+ return code;
488
+ } else if (typeof obj === "number") return obj | 0;
489
+ else if (typeof obj === "bigint") return BigInt.asIntN(obj, 32);
490
+ else if (typeof obj === "boolean") return obj ? 1 : 0;
491
+ else return 0;
492
+ },
493
+ apply: (instance, method, args) => {
494
+ try {
495
+ if (instance === null) return getGlobalName(method)(...args);
496
+ else return instance[method](...args);
497
+ } catch (e) {
498
+ rethrowJsAsJava(e);
499
+ }
500
+ },
501
+ concatArray: (a, b) => [...a, ...b],
502
+ getJavaException: (e) => e[javaExceptionSymbol],
503
+ getJSException: (e) => {
504
+ let getJsException = context.exports["teavm.getJsException"];
505
+ return getJsException(e);
506
+ },
507
+ jsExports: () => context.userExports
508
+ };
509
+ for (let name of [
510
+ "wrapByte",
511
+ "wrapShort",
512
+ "wrapChar",
513
+ "wrapInt",
514
+ "wrapLong",
515
+ "wrapFloat",
516
+ "wrapDouble",
517
+ "unwrapByte",
518
+ "unwrapShort",
519
+ "unwrapChar",
520
+ "unwrapInt",
521
+ "unwrapLong",
522
+ "unwrapFloat",
523
+ "unwrapDouble"
524
+ ]) imports.teavmJso[name] = identity;
525
+ function wrapCallFromJavaToJs(call) {
526
+ try {
527
+ return call();
528
+ } catch (e) {
529
+ rethrowJsAsJava(e);
530
+ }
531
+ }
532
+ for (let i = 0; i < 32; ++i) {
533
+ imports.teavmJso["createFunction" + i] = function(...parts) {
534
+ const factory = options.jsBodyFactories?.get(JSON.stringify(parts));
535
+ if (!factory) throw new Error("Missing statically compiled TeaVM JavaScript body");
536
+ return factory.bind(this, wrapCallFromJavaToJs);
537
+ };
538
+ imports.teavmJso["bindFunction" + i] = (f, ...args) => f.bind(null, ...args);
539
+ imports.teavmJso["callFunction" + i] = (fn, ...args) => {
540
+ try {
541
+ return fn(...args);
542
+ } catch (e) {
543
+ rethrowJsAsJava(e);
544
+ }
545
+ };
546
+ imports.teavmJso["callMethod" + i] = (instance, method, ...args) => {
547
+ try {
548
+ return instance !== null ? instance[method](...args) : getGlobalName(method)(...args);
549
+ } catch (e) {
550
+ rethrowJsAsJava(e);
551
+ }
552
+ };
553
+ imports.teavmJso["construct" + i] = (constructor, ...args) => {
554
+ try {
555
+ return Reflect.construct(constructor, args);
556
+ } catch (e) {
557
+ rethrowJsAsJava(e);
558
+ }
559
+ };
560
+ imports.teavmJso["arrayOf" + i] = (...args) => args;
561
+ }
562
+ }
563
+ var hasStringBuiltinsPromise = null;
564
+ function hasStringBuiltins() {
565
+ if (hasStringBuiltinsPromise === null) hasStringBuiltinsPromise = (async () => {
566
+ let bytes = new Int8Array([
567
+ 0,
568
+ 97,
569
+ 115,
570
+ 109,
571
+ 1,
572
+ 0,
573
+ 0,
574
+ 0,
575
+ 1,
576
+ 7,
577
+ 1,
578
+ 96,
579
+ 1,
580
+ 127,
581
+ 1,
582
+ 100,
583
+ 111,
584
+ 2,
585
+ 31,
586
+ 1,
587
+ 14,
588
+ 119,
589
+ 97,
590
+ 115,
591
+ 109,
592
+ 58,
593
+ 106,
594
+ 115,
595
+ 45,
596
+ 115,
597
+ 116,
598
+ 114,
599
+ 105,
600
+ 110,
601
+ 103,
602
+ 12,
603
+ 102,
604
+ 114,
605
+ 111,
606
+ 109,
607
+ 67,
608
+ 104,
609
+ 97,
610
+ 114,
611
+ 67,
612
+ 111,
613
+ 100,
614
+ 101,
615
+ 0,
616
+ 0,
617
+ 3,
618
+ 1,
619
+ 0,
620
+ 5,
621
+ 4,
622
+ 1,
623
+ 1,
624
+ 0,
625
+ 0,
626
+ 7,
627
+ 10,
628
+ 1,
629
+ 6,
630
+ 109,
631
+ 101,
632
+ 109,
633
+ 111,
634
+ 114,
635
+ 121,
636
+ 2,
637
+ 0,
638
+ 10,
639
+ -127,
640
+ -128,
641
+ -128,
642
+ 0,
643
+ 0
644
+ ]);
645
+ try {
646
+ let response = new Response(bytes, { headers: { "Content-Type": "application/wasm" } });
647
+ let module = await WebAssembly.compileStreaming(response, { builtins: ["js-string"] });
648
+ await WebAssembly.instantiate(module, {}, { builtins: ["js-string"] });
649
+ return true;
650
+ } catch (e) {
651
+ return false;
652
+ }
653
+ })();
654
+ return hasStringBuiltinsPromise;
655
+ }
656
+ var compileJavaModule = (bytes) => WebAssembly.compile(bytes, { builtins: ["js-string"] });
657
+ //#endregion
658
+ //#region src/compiler/vendor/java-compiler-bindings.mjs
659
+ var jsBodyFactories = /* @__PURE__ */ new Map([
660
+ ["[\"return Object.create(null);\"]", function(wrapCallFromJavaToJs) {
661
+ return Object.create(null);
662
+ }],
663
+ ["[\"array\",\"return array;\"]", function(wrapCallFromJavaToJs, array) {
664
+ return array;
665
+ }],
666
+ ["[\"str\",\"return str;\"]", function(wrapCallFromJavaToJs, str) {
667
+ return str;
668
+ }],
669
+ ["[\"__this__\",\"return __this__;\"]", function(wrapCallFromJavaToJs, __this__) {
670
+ return __this__;
671
+ }],
672
+ ["[\"number\",\"return number;\"]", function(wrapCallFromJavaToJs, number) {
673
+ return number;
674
+ }],
675
+ ["[\"str\",\"return str;\"]", function(wrapCallFromJavaToJs, str) {
676
+ return str;
677
+ }],
678
+ ["[\"size\",\"return new Array(size);\"]", function(wrapCallFromJavaToJs, size) {
679
+ return new Array(size);
680
+ }]
681
+ ]);
682
+ //#endregion
683
+ //#region src/compiler/java-gc.ts
684
+ async function loadJavaGcEngine(bytes) {
685
+ const wasmModule = await compileJavaModule(bytes);
686
+ const imports = {};
687
+ const exports = {};
688
+ const context = defaults(imports, exports, { jsBodyFactories }, wasmModule, await hasStringBuiltins());
689
+ const instance = await WebAssembly.instantiate(wasmModule, imports);
690
+ context.supplyExports(instance.exports);
691
+ for (const [key, value] of Object.entries(instance.exports)) if (value instanceof WebAssembly.Global) Object.defineProperty(exports, key, { get: () => value.value });
692
+ if (typeof exports.createCompiler !== "function") throw new Error("The pinned Java compiler has no createCompiler export.");
693
+ return exports;
694
+ }
695
+ async function compileJavaGc(engine, request, classlibs) {
696
+ if (!request.files.find((file) => file.path === request.entry)) throw new Error(`Java entry '${request.entry}' does not exist.`);
697
+ const compiler = engine.createCompiler();
698
+ compiler.setSdk(new Int8Array(classlibs.sdk.buffer, classlibs.sdk.byteOffset, classlibs.sdk.byteLength));
699
+ compiler.setTeaVMClasslib(new Int8Array(classlibs.runtime.buffer, classlibs.runtime.byteOffset, classlibs.runtime.byteLength));
700
+ const diagnostics = [];
701
+ const backendErrors = [];
702
+ compiler.onDiagnostic((diagnostic) => {
703
+ if (diagnostic.type !== "javac") {
704
+ if (diagnostic.severity === "error") backendErrors.push(diagnostic.message);
705
+ return;
706
+ }
707
+ diagnostics.push({
708
+ severity: diagnostic.severity,
709
+ message: diagnostic.message,
710
+ source: "java",
711
+ line: Math.max(1, diagnostic.lineNumber),
712
+ column: 1,
713
+ file: diagnostic.fileName ?? request.entry
714
+ });
715
+ });
716
+ for (const file of request.files) if (file.path.endsWith(".java")) compiler.addSourceFile(file.path, file.content);
717
+ const compiled = compiler.compile();
718
+ const stderr = diagnostics.map((diagnostic) => `${diagnostic.file ?? request.entry}:${diagnostic.line ?? 1}: ${diagnostic.severity}: ${diagnostic.message}`).join("\n");
719
+ if (diagnostics.some((diagnostic) => diagnostic.severity === "error")) return {
720
+ success: false,
721
+ stdout: "",
722
+ stderr,
723
+ diagnostics
724
+ };
725
+ if (!compiled) throw new Error("Java compilation failed without source diagnostics.");
726
+ const mainClass = compiler.findEntryClass(request.entry);
727
+ if (!mainClass) throw new Error(`Java entry '${request.entry}' did not emit its named class.`);
728
+ if (!compiler.generateWebAssembly({
729
+ mainClass,
730
+ outputName: "app",
731
+ optimization: request.optimization
732
+ }) || backendErrors.length) throw new Error(`Java WASI backend failed.${backendErrors.length ? `\n${backendErrors.join("\n")}` : ""}`);
733
+ const output = compiler.getWebAssemblyOutputFile("app");
734
+ if (!output) throw new Error("Java compiler did not produce app.wasm.");
735
+ const wasm = Uint8Array.from(output);
736
+ try {
49
737
  await WebAssembly.compile(wasm);
50
- wasmBase64 = Buffer.from(wasm).toString("base64");
738
+ } catch (cause) {
739
+ throw new Error("Java compiler produced invalid WebAssembly.", { cause });
51
740
  }
741
+ return {
742
+ success: true,
743
+ stdout: "",
744
+ stderr,
745
+ diagnostics,
746
+ wasm
747
+ };
748
+ }
749
+ //#endregion
750
+ //#region src/server/java-stage.mjs
751
+ var exitCode = 0;
752
+ try {
753
+ const chunks = [];
754
+ for await (const chunk of process.stdin) chunks.push(chunk);
755
+ const encoded = JSON.parse(Buffer.concat(chunks).toString("utf8"));
756
+ const [compiler, sdk, runtime] = await Promise.all([
757
+ loadAsset(encoded, JAVA_COMPILER_ASSET_PATH, JAVA_COMPILER_SHA256),
758
+ loadAsset(encoded, JAVA_COMPILE_CLASSLIB_ASSET_PATH, JAVA_COMPILE_CLASSLIB_SHA256),
759
+ loadAsset(encoded, JAVA_RUNTIME_CLASSLIB_ASSET_PATH, JAVA_RUNTIME_CLASSLIB_SHA256)
760
+ ]);
761
+ const { wasm, ...result } = await compileJavaGc(await loadJavaGcEngine(compiler), encoded.request, {
762
+ sdk,
763
+ runtime
764
+ });
52
765
  writeResult({
53
- success: output.ok && typeof wasmBase64 === "string",
54
- wasmBase64,
55
- stdout: output.stdout,
56
- stderr: output.stderr,
57
- diagnostics
766
+ ...result,
767
+ wasmBase64: wasm ? Buffer.from(wasm).toString("base64") : void 0
58
768
  });
59
769
  } catch (error) {
60
770
  writeResult(void 0, error instanceof Error ? error.message : String(error));
61
771
  exitCode = 1;
62
772
  } finally {
63
- toolchain?.free();
64
- project?.free();
65
- packageHandle?.free();
66
- runtime?.free();
67
773
  setTimeout(() => process.exit(exitCode), 10);
68
774
  }
69
- async function loadCompiler(file, verified) {
70
- const compressed = await readFile(file);
71
- if (!verified) verifyDigest(file, compressed, JAVA_COMPILER_COMPRESSED_PACKAGE_SHA256);
72
- const bytes = new Uint8Array(gunzipSync(compressed));
73
- if (!verified) verifyDigest(file, bytes, JAVA_COMPILER_PACKAGE_SHA256);
74
- return bytes;
75
- }
76
- async function loadRaw(file, expected, verified) {
77
- const bytes = new Uint8Array(await readFile(file));
78
- if (!verified) verifyDigest(file, bytes, expected);
79
- return bytes;
80
- }
81
- function requiredToolchainAsset(encoded, assetPath) {
775
+ async function loadAsset(encoded, assetPath, expected) {
82
776
  const file = encoded?.toolchainAssets?.[assetPath];
83
777
  if (typeof file !== "string" || !path.isAbsolute(file)) throw new Error(`The Java compiler stage did not receive absolute asset '${assetPath}'.`);
84
- return file;
85
- }
86
- function verifyDigest(label, bytes, expected) {
87
- const actual = createHash("sha256").update(bytes).digest("hex");
88
- if (actual !== expected) throw new Error(`Pinned Java asset '${label}' has digest ${actual}; expected ${expected}.`);
89
- }
90
- function withTimeout(promise, timeoutMs) {
91
- let timer;
92
- return Promise.race([promise, new Promise((_, reject) => {
93
- timer = setTimeout(() => reject(/* @__PURE__ */ new Error(`Java compilation exceeded ${timeoutMs} ms.`)), timeoutMs);
94
- })]).finally(() => clearTimeout(timer));
778
+ const bytes = new Uint8Array(await readFile(file));
779
+ if (encoded.verifiedToolchain !== true) {
780
+ const actual = createHash("sha256").update(bytes).digest("hex");
781
+ if (actual !== expected) throw new Error(`Pinned Java asset '${assetPath}' has digest ${actual}; expected ${expected}.`);
782
+ }
783
+ return bytes;
95
784
  }
96
785
  function writeResult(result, error) {
97
786
  writeFileSync(3, JSON.stringify(result ? {
@@ -102,10 +791,5 @@ function writeResult(result, error) {
102
791
  error
103
792
  }));
104
793
  }
105
- async function readStdin() {
106
- const chunks = [];
107
- for await (const chunk of process.stdin) chunks.push(chunk);
108
- return Buffer.concat(chunks).toString("utf8");
109
- }
110
794
  //#endregion
111
795
  export {};