|
| 1 | +/* eslint-disable no-eval */ |
| 2 | +/* eslint-disable no-undef */ |
| 3 | +import * as emnapiCore from '../../node_modules/@emnapi/core/dist/emnapi-core.full.js' |
| 4 | +import { v8, asyncWork, tsfn } from '../../node_modules/@emnapi/core/dist/plugins/index.js' |
| 5 | +// import * as emnapi from '../runtime/dist/emnapi.js' |
| 6 | + |
| 7 | +(function () { |
| 8 | + // const log = (...args) => { |
| 9 | + // const str = require('util').format(...args) |
| 10 | + // require('fs').writeSync(1, str + '\n') |
| 11 | + // } |
| 12 | + // const error = (...args) => { |
| 13 | + // const str = require('util').format(...args) |
| 14 | + // require('fs').writeSync(2, str + '\n') |
| 15 | + // } |
| 16 | + let require, fs, WASI, ready |
| 17 | + |
| 18 | + const ENVIRONMENT_IS_NODE = |
| 19 | + typeof process === 'object' && process !== null && |
| 20 | + typeof process.versions === 'object' && process.versions !== null && |
| 21 | + typeof process.versions.node === 'string' |
| 22 | + |
| 23 | + if (ENVIRONMENT_IS_NODE) { |
| 24 | + ready = (async function () { |
| 25 | + let parentPort |
| 26 | + Object.assign(globalThis, { |
| 27 | + self: globalThis, |
| 28 | + importScripts: function (f) { |
| 29 | + (0, eval)(fs.readFileSync(f, 'utf8') + '//# sourceURL=' + f) |
| 30 | + }, |
| 31 | + postMessage: function (msg) { |
| 32 | + parentPort?.postMessage(msg) |
| 33 | + } |
| 34 | + }) |
| 35 | + |
| 36 | + const { createRequire } = await import('node:module') |
| 37 | + require = createRequire(import.meta.url) |
| 38 | + const nodeWorkerThreads = require('worker_threads') |
| 39 | + |
| 40 | + parentPort = nodeWorkerThreads.parentPort |
| 41 | + |
| 42 | + parentPort.on('message', (data) => { |
| 43 | + globalThis.onmessage({ data }) |
| 44 | + }) |
| 45 | + |
| 46 | + fs = require('fs') |
| 47 | + |
| 48 | + Object.assign(globalThis, { |
| 49 | + require, |
| 50 | + Worker: nodeWorkerThreads.Worker |
| 51 | + }) |
| 52 | + |
| 53 | + WASI = require('node:wasi').WASI |
| 54 | + })() |
| 55 | + } else { |
| 56 | + ready = (async function () { |
| 57 | + const { Buffer } = await import('https://esm.sh/buffer@6.0.3') |
| 58 | + globalThis.Buffer = Buffer |
| 59 | + const memfs = await import('../../node_modules/memfs-browser/dist/memfs.esm.js') |
| 60 | + const wasmUtil = await import('../../node_modules/@tybys/wasm-util/dist/wasm-util.esm.js') |
| 61 | + const { Volume, createFsFromVolume } = memfs |
| 62 | + fs = createFsFromVolume(Volume.fromJSON({ |
| 63 | + '/': null |
| 64 | + })) |
| 65 | + WASI = wasmUtil.WASI |
| 66 | + })() |
| 67 | + } |
| 68 | + |
| 69 | + const { instantiateNapiModule, MessageHandler } = emnapiCore |
| 70 | + |
| 71 | + const handler = new MessageHandler({ |
| 72 | + async onLoad ({ wasmModule, wasmMemory }) { |
| 73 | + await ready |
| 74 | + const wasi = new WASI({ |
| 75 | + fs, |
| 76 | + version: 'preview1', |
| 77 | + print: ENVIRONMENT_IS_NODE |
| 78 | + ? (...args) => { |
| 79 | + const str = require('util').format(...args) |
| 80 | + fs.writeSync(1, str + '\n') |
| 81 | + } |
| 82 | + : function () { console.log.apply(console, arguments) } |
| 83 | + }) |
| 84 | + |
| 85 | + const UTF8ToString = (ptr) => { |
| 86 | + ptr >>>= 0 |
| 87 | + if (!ptr) return '' |
| 88 | + const HEAPU8 = new Uint8Array(wasmMemory.buffer) |
| 89 | + let end |
| 90 | + for (end = ptr; HEAPU8[end];) ++end |
| 91 | + const shared = (typeof SharedArrayBuffer === 'function') && (wasmMemory.buffer instanceof SharedArrayBuffer) |
| 92 | + return new TextDecoder().decode(shared ? HEAPU8.slice(ptr, end) : HEAPU8.subarray(ptr, end)) |
| 93 | + } |
| 94 | + |
| 95 | + return instantiateNapiModule(wasmModule, { |
| 96 | + childThread: true, |
| 97 | + wasi, |
| 98 | + overwriteImports (importObject) { |
| 99 | + importObject.env.memory = wasmMemory |
| 100 | + importObject.env.console_log = function (fmt, ...args) { |
| 101 | + const fmtString = UTF8ToString(fmt) |
| 102 | + console.log(fmtString, ...args) |
| 103 | + return 0 |
| 104 | + } |
| 105 | + importObject.env.sleep = function (n) { |
| 106 | + const end = Date.now() + n * 1000 |
| 107 | + while (Date.now() < end) { |
| 108 | + // ignore |
| 109 | + } |
| 110 | + } |
| 111 | + }, |
| 112 | + plugins: [v8, asyncWork, tsfn] |
| 113 | + }) |
| 114 | + } |
| 115 | + }) |
| 116 | + |
| 117 | + globalThis.onmessage = function (e) { |
| 118 | + handler.handle(e) |
| 119 | + // handle other messages |
| 120 | + } |
| 121 | +})() |
0 commit comments