@cowasm/kernel
Advanced tools
+2
-2
| { | ||
| "name": "@cowasm/kernel", | ||
| "version": "0.27.2", | ||
| "version": "0.27.3", | ||
| "description": "@cowasm/kernel -- the Kernel of CoWasm: Collaborative WebAssembly for Servers and Browsers", | ||
@@ -22,3 +22,3 @@ "main": "./dist/kernel/node.js", | ||
| }, | ||
| "bin": "./bin/cowasm", | ||
| "bin": "./dist/kernel/node-terminal.js", | ||
| "repository": { | ||
@@ -25,0 +25,0 @@ "type": "git", |
+3
-0
@@ -10,1 +10,4 @@ # @cowasm/kernel: Collaborative WebAssembly for Servers and Browsers | ||
| ## Running CoWasm binaries | ||
| Use `npx @cowasm/kernel path/to/binary` . |
Sorry, the diff of this file is not supported yet
| import type { WasmInstanceAsync, WasmInstanceSync } from "../wasm/types"; | ||
| import type { FileSystemSpec } from "wasi-js"; | ||
| interface Options { | ||
| env?: { | ||
| [name: string]: string; | ||
| }; | ||
| fs?: FileSystemSpec[]; | ||
| } | ||
| export declare function syncKernel(opts?: Options): Promise<WasmInstanceSync>; | ||
| export declare function asyncKernel(opts?: Options): Promise<WasmInstanceAsync>; | ||
| export declare function supportsPosix(): boolean; | ||
| export {}; |
| "use strict"; | ||
| var __importDefault = (this && this.__importDefault) || function (mod) { | ||
| return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
| }; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.supportsPosix = exports.asyncKernel = exports.syncKernel = void 0; | ||
| const import_browser_1 = __importDefault(require("../wasm/import-browser")); | ||
| const browser_1 = __importDefault(require("../wasm/worker/browser")); | ||
| const kernel_1 = require("./kernel"); | ||
| const kernel_wasm_1 = __importDefault(require("./kernel.wasm")); | ||
| function getOptions(wasmImport, opts) { | ||
| const fs = opts?.fs ?? [{ type: "dev" }]; | ||
| const env = { | ||
| TERMCAP: "/usr/lib/python3.11/termcap", | ||
| TERM: "xterm-256color", | ||
| PS1: "(cowasm)$ ", | ||
| ...opts?.env, | ||
| }; | ||
| return { | ||
| programName: "/bin/cowasm", | ||
| wasmSource: kernel_wasm_1.default, | ||
| wasmImport, | ||
| fs, | ||
| env, | ||
| }; | ||
| } | ||
| async function syncKernel(opts) { | ||
| return await (0, kernel_1.createSyncKernel)(getOptions(browser_1.default, opts)); | ||
| } | ||
| exports.syncKernel = syncKernel; | ||
| async function asyncKernel(opts) { | ||
| return await (0, kernel_1.createAsyncKernel)(getOptions(import_browser_1.default, opts)); | ||
| } | ||
| exports.asyncKernel = asyncKernel; | ||
| function supportsPosix() { | ||
| return false; | ||
| } | ||
| exports.supportsPosix = supportsPosix; | ||
| //# sourceMappingURL=browser.js.map |
| {"version":3,"file":"browser.js","sourceRoot":"","sources":["../../src/kernel/browser.ts"],"names":[],"mappings":";;;;;;AACA,4EAAqD;AACrD,qEAAoD;AACpD,qCAA+D;AAG/D,gEAAoC;AAOpC,SAAS,UAAU,CAAC,UAAU,EAAE,IAAc;IAC5C,MAAM,EAAE,GAAqB,IAAI,EAAE,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAC3D,MAAM,GAAG,GAAG;QACV,OAAO,EAAE,6BAA6B;QACtC,IAAI,EAAE,gBAAgB;QACtB,GAAG,EAAE,YAAY;QACjB,GAAG,IAAI,EAAE,GAAG;KACb,CAAC;IAEF,OAAO;QACL,WAAW,EAAE,aAAa;QAC1B,UAAU,EAAE,qBAAO;QACnB,UAAU;QACV,EAAE;QACF,GAAG;KACJ,CAAC;AACJ,CAAC;AAEM,KAAK,UAAU,UAAU,CAAC,IAAc;IAC7C,OAAO,MAAM,IAAA,yBAAgB,EAAC,UAAU,CAAC,iBAAc,EAAE,IAAI,CAAC,CAAC,CAAC;AAClE,CAAC;AAFD,gCAEC;AAEM,KAAK,UAAU,WAAW,CAAC,IAAc;IAC9C,OAAO,MAAM,IAAA,0BAAiB,EAAC,UAAU,CAAC,wBAAe,EAAE,IAAI,CAAC,CAAC,CAAC;AACpE,CAAC;AAFD,kCAEC;AAED,SAAgB,aAAa;IAC3B,OAAO,KAAK,CAAC;AACf,CAAC;AAFD,sCAEC"} |
| import type { WasmInstanceAsync, WasmInstanceSync } from "../wasm/types"; | ||
| import { Options as ImportOptions } from "../wasm/import"; | ||
| import type { FileSystemSpec } from "wasi-js"; | ||
| declare type WASMImportFunction = (wasmSource: string, options: ImportOptions, log?: (...args: any[]) => void) => Promise<WasmInstanceSync | WasmInstanceAsync>; | ||
| interface KernelOptions { | ||
| wasmSource: string; | ||
| programName?: string; | ||
| wasmImport: WASMImportFunction; | ||
| fs: FileSystemSpec[]; | ||
| env: { | ||
| [name: string]: string; | ||
| }; | ||
| wasmEnv?: { | ||
| [name: string]: Function; | ||
| }; | ||
| noStdio?: boolean; | ||
| } | ||
| export declare function createAsyncKernel({ wasmSource, wasmImport, fs, env, noStdio, }: KernelOptions): Promise<WasmInstanceAsync>; | ||
| export declare function createSyncKernel({ wasmSource, wasmImport, fs, env, wasmEnv, }: KernelOptions): Promise<WasmInstanceSync>; | ||
| export {}; |
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.createSyncKernel = exports.createAsyncKernel = void 0; | ||
| async function createAsyncKernel({ wasmSource, wasmImport, fs, env, noStdio, }) { | ||
| const kernel = (await wasmImport(wasmSource, { | ||
| env, | ||
| fs, | ||
| noStdio, | ||
| })); | ||
| // critical to do this first, because otherwise process.cwd() gets | ||
| // set to '/' (the default in WASM) when any posix call happens. | ||
| await kernel.callWithString("chdir", process.cwd()); | ||
| return kernel; | ||
| } | ||
| exports.createAsyncKernel = createAsyncKernel; | ||
| async function createSyncKernel({ wasmSource, wasmImport, fs, env, wasmEnv, }) { | ||
| const kernel = (await wasmImport(wasmSource, { | ||
| env, | ||
| fs, | ||
| wasmEnv, | ||
| })); | ||
| kernel.callWithString("chdir", process.cwd()); | ||
| return kernel; | ||
| } | ||
| exports.createSyncKernel = createSyncKernel; | ||
| //# sourceMappingURL=kernel.js.map |
| {"version":3,"file":"kernel.js","sourceRoot":"","sources":["../../src/kernel/kernel.ts"],"names":[],"mappings":";;;AAsBO,KAAK,UAAU,iBAAiB,CAAC,EACtC,UAAU,EACV,UAAU,EACV,EAAE,EACF,GAAG,EACH,OAAO,GACO;IACd,MAAM,MAAM,GAAG,CAAC,MAAM,UAAU,CAAC,UAAU,EAAE;QAC3C,GAAG;QACH,EAAE;QACF,OAAO;KACR,CAAC,CAAsB,CAAC;IACzB,kEAAkE;IAClE,gEAAgE;IAChE,MAAM,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IACpD,OAAO,MAAM,CAAC;AAChB,CAAC;AAhBD,8CAgBC;AAEM,KAAK,UAAU,gBAAgB,CAAC,EACrC,UAAU,EACV,UAAU,EACV,EAAE,EACF,GAAG,EACH,OAAO,GACO;IACd,MAAM,MAAM,GAAG,CAAC,MAAM,UAAU,CAAC,UAAU,EAAE;QAC3C,GAAG;QACH,EAAE;QACF,OAAO;KACR,CAAC,CAAqB,CAAC;IACxB,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IAC9C,OAAO,MAAM,CAAC;AAChB,CAAC;AAdD,4CAcC"} |
Sorry, the diff of this file is not supported yet
| export {}; |
| {"version":3,"file":"node-terminal.js","sourceRoot":"","sources":["../../src/kernel/node-terminal.ts"],"names":[],"mappings":";;;;;AAAA,+BAA+B;AAC/B,iCAAoC;AACpC,4DAA+B;AAE/B,KAAK,UAAU,IAAI;IACjB,IAAI,OAAO,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,EAAE;QAC5B,OAAO,CAAC,KAAK,CAAC,kCAAkC,CAAC,CAAC;QAClD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;KACjB;IACD,kFAAkF;IAClF,MAAM,MAAM,GAAG,MAAM,IAAA,iBAAU,GAAE,CAAC;IAClC,MAAM,OAAO,GAAG,IAAA,cAAO,EAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IACzC,MAAM,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IACrD,IAAI;QACF,oBAAK,CAAC,cAAc,EAAE,EAAE,CAAC;KAC1B;IAAC,OAAO,IAAI,EAAE;QACb,2DAA2D;QAC3D,IAAI;YACF,oBAAK,CAAC,iBAAiB,EAAE,EAAE,CAAC;SAC7B;QAAC,OAAO,IAAI,EAAE,GAAE;KAClB;IACD,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC5B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,IAAI,EAAE,CAAC"} |
| import type { WasmInstanceAsync, WasmInstanceSync } from "../wasm/types"; | ||
| export { WasmInstanceAsync, WasmInstanceSync }; | ||
| import type { FileSystemSpec } from "wasi-js"; | ||
| export { FileSystemSpec }; | ||
| interface Options { | ||
| env?: { | ||
| [name: string]: string; | ||
| }; | ||
| fs?: FileSystemSpec[]; | ||
| wasmEnv?: { | ||
| [name: string]: Function; | ||
| }; | ||
| interactive?: boolean; | ||
| noStdio?: boolean; | ||
| } | ||
| export declare function syncKernel(opts?: Options): Promise<WasmInstanceSync>; | ||
| export declare function asyncKernel(opts?: Options): Promise<WasmInstanceAsync>; | ||
| export declare function supportsPosix(): boolean; |
| "use strict"; | ||
| var __importDefault = (this && this.__importDefault) || function (mod) { | ||
| return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
| }; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.supportsPosix = exports.asyncKernel = exports.syncKernel = void 0; | ||
| const import_node_1 = __importDefault(require("../wasm/import-node")); | ||
| const node_1 = __importDefault(require("../wasm/worker/node")); | ||
| const kernel_1 = require("./kernel"); | ||
| const path_1 = require("path"); | ||
| const constants_1 = require("../wasm/constants"); | ||
| const posix_node_1 = __importDefault(require("posix-node")); | ||
| const KERNEL_WASM = "kernel.wasm"; | ||
| // Our tiny termcap file only has one entry, which is for xterm | ||
| // so that's all we give you, even if you have a different terminal. | ||
| const TERM = "xterm-256color"; | ||
| function getOptions(wasmImport, opts) { | ||
| const path = __dirname; | ||
| const env = { | ||
| ...process.env, | ||
| TERM, | ||
| TERMCAP: (0, path_1.join)(path, "..", "termcap"), | ||
| PS1: "(cowasm)$ ", | ||
| ...opts?.env, | ||
| }; | ||
| //PS1: 'cowasm: (pwd | sed "s|^$HOME|~|")$ ' | ||
| return { | ||
| programName: process.env.PROGRAM_NAME, | ||
| wasmSource: (0, path_1.join)(path, KERNEL_WASM), | ||
| wasmImport, | ||
| fs: opts?.fs ?? [{ type: "native" }], | ||
| env, | ||
| wasmEnv: opts?.wasmEnv, | ||
| noStdio: opts?.noStdio, | ||
| }; | ||
| } | ||
| // NOTE: we can't just use 'process.on("SIGINT", () => { signal_state = SIGINT; });' | ||
| // since the WASM program is blocking events. They just don't happen. Hence | ||
| // we use Zig code against libc for the sync kernel. | ||
| // NOTE: Every program needs their own way of explicitly checking for signals, and | ||
| // this is only implemented for Python right now. I'll add it for other things eventually. | ||
| function wasmGetSignalState() { | ||
| const state = posix_node_1.default.getSignalState?.(constants_1.SIGINT) ?? 0; | ||
| return state ? constants_1.SIGINT : 0; | ||
| } | ||
| async function syncKernel(opts) { | ||
| posix_node_1.default.watchForSignal?.(constants_1.SIGINT); | ||
| const kernel = await (0, kernel_1.createSyncKernel)(getOptions(node_1.default, { | ||
| ...opts, | ||
| wasmEnv: { wasmGetSignalState, ...opts?.wasmEnv }, | ||
| })); | ||
| return kernel; | ||
| } | ||
| exports.syncKernel = syncKernel; | ||
| async function asyncKernel(opts) { | ||
| const kernel = await (0, kernel_1.createAsyncKernel)(getOptions(import_node_1.default, opts)); | ||
| if (opts?.interactive && !opts?.noStdio) { | ||
| asyncIO(kernel); | ||
| } | ||
| return kernel; | ||
| } | ||
| exports.asyncKernel = asyncKernel; | ||
| function supportsPosix() { | ||
| return posix_node_1.default.makeStdinBlocking != null; | ||
| } | ||
| exports.supportsPosix = supportsPosix; | ||
| function asyncIO(kernel) { | ||
| const keyHandler = (key) => { | ||
| kernel.writeToStdin(key); | ||
| }; | ||
| process.stdin.on("data", keyHandler); | ||
| const sigintHandler = () => { | ||
| kernel.signal(constants_1.SIGINT); | ||
| }; | ||
| process.on("SIGINT", sigintHandler); | ||
| kernel.on("terminate", () => { | ||
| process.stdin.removeListener("data", keyHandler); | ||
| process.removeListener("SIGINT", sigintHandler); | ||
| }); | ||
| } | ||
| //# sourceMappingURL=node.js.map |
| {"version":3,"file":"node.js","sourceRoot":"","sources":["../../src/kernel/node.ts"],"names":[],"mappings":"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"} |
| export declare const SIGINT = 2; |
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.SIGINT = void 0; | ||
| exports.SIGINT = 2; | ||
| //# sourceMappingURL=constants.js.map |
| {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/wasm/constants.ts"],"names":[],"mappings":";;;AAAa,QAAA,MAAM,GAAG,CAAC,CAAC"} |
| /// <reference types="node" /> | ||
| import { Options, WasmInstanceAbstractBaseClass } from "./import"; | ||
| import { EventEmitter } from "events"; | ||
| import type { WasmInstanceAsync } from "./types"; | ||
| declare class WorkerThread extends EventEmitter { | ||
| postMessage: (message: any) => void; | ||
| terminate: () => void; | ||
| constructor(worker: Worker); | ||
| } | ||
| export declare class WasmInstance extends WasmInstanceAbstractBaseClass { | ||
| protected initWorker(): WorkerThread; | ||
| } | ||
| export default function wasmImportBrowserWorker(wasmSource: string, options?: Options): Promise<WasmInstanceAsync>; | ||
| export {}; |
| "use strict"; | ||
| var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { | ||
| if (k2 === undefined) k2 = k; | ||
| var desc = Object.getOwnPropertyDescriptor(m, k); | ||
| if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { | ||
| desc = { enumerable: true, get: function() { return m[k]; } }; | ||
| } | ||
| Object.defineProperty(o, k2, desc); | ||
| }) : (function(o, m, k, k2) { | ||
| if (k2 === undefined) k2 = k; | ||
| o[k2] = m[k]; | ||
| })); | ||
| var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { | ||
| Object.defineProperty(o, "default", { enumerable: true, value: v }); | ||
| }) : function(o, v) { | ||
| o["default"] = v; | ||
| }); | ||
| var __importStar = (this && this.__importStar) || function (mod) { | ||
| if (mod && mod.__esModule) return mod; | ||
| var result = {}; | ||
| if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); | ||
| __setModuleDefault(result, mod); | ||
| return result; | ||
| }; | ||
| var __importDefault = (this && this.__importDefault) || function (mod) { | ||
| return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
| }; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.WasmInstance = void 0; | ||
| const import_1 = require("./import"); | ||
| const events_1 = require("events"); | ||
| const io_using_atomics_1 = __importDefault(require("./io-using-atomics")); | ||
| const io_using_service_worker_1 = __importStar(require("./io-using-service-worker")); | ||
| class WorkerThread extends events_1.EventEmitter { | ||
| constructor(worker) { | ||
| super(); | ||
| this.setMaxListeners(100); | ||
| this.postMessage = worker.postMessage.bind(worker); | ||
| this.terminate = worker.terminate.bind(worker); | ||
| worker.onmessage = ({ data: message }) => { | ||
| if (message?.event == "service-worker-broken") { | ||
| (0, io_using_service_worker_1.fixServiceWorker)(); | ||
| return; | ||
| } | ||
| this.emit("message", message); | ||
| }; | ||
| } | ||
| } | ||
| class WasmInstance extends import_1.WasmInstanceAbstractBaseClass { | ||
| initWorker() { | ||
| // @ts-ignore this import.meta.url issue -- actually only consumed by webpack in calling code... | ||
| const worker = new Worker(new URL("./worker/browser.js", import.meta.url)); | ||
| return new WorkerThread(worker); | ||
| } | ||
| } | ||
| exports.WasmInstance = WasmInstance; | ||
| async function wasmImportBrowserWorker(wasmSource, options = {}) { | ||
| const IOProvider = crossOriginIsolated | ||
| ? io_using_atomics_1.default | ||
| : io_using_service_worker_1.default; | ||
| return new WasmInstance(wasmSource, options, IOProvider); | ||
| } | ||
| exports.default = wasmImportBrowserWorker; | ||
| //# sourceMappingURL=import-browser.js.map |
| {"version":3,"file":"import-browser.js","sourceRoot":"","sources":["../../src/wasm/import-browser.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,qCAAkE;AAClE,mCAAsC;AACtC,0EAAwD;AACxD,qFAEmC;AAGnC,MAAM,YAAa,SAAQ,qBAAY;IAIrC,YAAY,MAAc;QACxB,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC;QAC1B,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACnD,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC/C,MAAM,CAAC,SAAS,GAAG,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE;YACvC,IAAI,OAAO,EAAE,KAAK,IAAI,uBAAuB,EAAE;gBAC7C,IAAA,0CAAgB,GAAE,CAAC;gBACnB,OAAO;aACR;YACD,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QAChC,CAAC,CAAC;IACJ,CAAC;CACF;AAED,MAAa,YAAa,SAAQ,sCAA6B;IACnD,UAAU;QAClB,gGAAgG;QAChG,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,GAAG,CAAC,qBAAqB,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;QAC3E,OAAO,IAAI,YAAY,CAAC,MAAM,CAAC,CAAC;IAClC,CAAC;CACF;AAND,oCAMC;AAEc,KAAK,UAAU,uBAAuB,CACnD,UAAkB,EAClB,UAAmB,EAAE;IAErB,MAAM,UAAU,GAAG,mBAAmB;QACpC,CAAC,CAAC,0BAAsB;QACxB,CAAC,CAAC,iCAA4B,CAAC;IACjC,OAAO,IAAI,YAAY,CAAC,UAAU,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC;AAC3D,CAAC;AARD,0CAQC"} |
| import { Options, WasmInstanceAbstractBaseClass, WorkerThread } from "./import"; | ||
| import type { WasmInstanceAsync } from "./types"; | ||
| export declare class WasmInstance extends WasmInstanceAbstractBaseClass { | ||
| protected initWorker(): WorkerThread; | ||
| protected configureTerminal(): void; | ||
| } | ||
| export default function wasmImportNodeWorker(wasmSource: string, // name of the wasm file | ||
| options: Options): Promise<WasmInstanceAsync>; |
| "use strict"; | ||
| var __importDefault = (this && this.__importDefault) || function (mod) { | ||
| return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
| }; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.WasmInstance = void 0; | ||
| const import_1 = require("./import"); | ||
| const worker_threads_1 = require("worker_threads"); | ||
| const path_1 = require("path"); | ||
| const node_process_1 = __importDefault(require("node:process")); | ||
| const debug_1 = __importDefault(require("debug")); | ||
| const io_using_atomics_1 = __importDefault(require("./io-using-atomics")); | ||
| const log = (0, debug_1.default)("wasm:import-node"); | ||
| class WasmInstance extends import_1.WasmInstanceAbstractBaseClass { | ||
| initWorker() { | ||
| const path = (0, path_1.join)(__dirname, "worker", "node.js"); | ||
| return new worker_threads_1.Worker(path, { | ||
| trackUnmanagedFds: false, // this seems incompatible with our use of unionfs/memfs (lots of warnings). | ||
| }); | ||
| } | ||
| configureTerminal() { | ||
| const stdinListeners = node_process_1.default.stdin.listeners("data"); | ||
| for (const f of stdinListeners) { | ||
| // save listeners on stdin so we can restore them | ||
| // when the terminal finishes | ||
| node_process_1.default.stdin.removeListener("data", f); | ||
| } | ||
| if (this.worker == null) | ||
| throw Error("configureTerminal - bug"); | ||
| this.worker.on("exit", () => { | ||
| // put back the original listeners on stdin | ||
| for (const f of stdinListeners) { | ||
| node_process_1.default.stdin.addListener("data", f); | ||
| } | ||
| }); | ||
| node_process_1.default.stdin.on("data", (data) => { | ||
| if (log.enabled) { | ||
| log("stdin", data.toString()); | ||
| } | ||
| this.writeToStdin(data); | ||
| }); | ||
| } | ||
| } | ||
| exports.WasmInstance = WasmInstance; | ||
| async function wasmImportNodeWorker(wasmSource, // name of the wasm file | ||
| options) { | ||
| return new WasmInstance(wasmSource, options, io_using_atomics_1.default); | ||
| } | ||
| exports.default = wasmImportNodeWorker; | ||
| //# sourceMappingURL=import-node.js.map |
| {"version":3,"file":"import-node.js","sourceRoot":"","sources":["../../src/wasm/import-node.ts"],"names":[],"mappings":";;;;;;AAAA,qCAAgF;AAChF,mDAAwC;AACxC,+BAA4B;AAC5B,gEAAmC;AACnC,kDAA0B;AAC1B,0EAAwD;AAGxD,MAAM,GAAG,GAAG,IAAA,eAAK,EAAC,kBAAkB,CAAC,CAAC;AAEtC,MAAa,YAAa,SAAQ,sCAA6B;IACnD,UAAU;QAClB,MAAM,IAAI,GAAG,IAAA,WAAI,EAAC,SAAS,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;QAClD,OAAO,IAAI,uBAAM,CAAC,IAAI,EAAE;YACtB,iBAAiB,EAAE,KAAK,EAAE,4EAA4E;SACvG,CAAC,CAAC;IACL,CAAC;IAES,iBAAiB;QACzB,MAAM,cAAc,GAAU,sBAAO,CAAC,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QAC9D,KAAK,MAAM,CAAC,IAAI,cAAc,EAAE;YAC9B,iDAAiD;YACjD,6BAA6B;YAC7B,sBAAO,CAAC,KAAK,CAAC,cAAc,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;SACzC;QACD,IAAI,IAAI,CAAC,MAAM,IAAI,IAAI;YAAE,MAAM,KAAK,CAAC,yBAAyB,CAAC,CAAC;QAChE,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE;YAC1B,2CAA2C;YAC3C,KAAK,MAAM,CAAC,IAAI,cAAc,EAAE;gBAC9B,sBAAO,CAAC,KAAK,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;aACtC;QACH,CAAC,CAAC,CAAC;QACH,sBAAO,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;YAChC,IAAI,GAAG,CAAC,OAAO,EAAE;gBACf,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;aAC/B;YACD,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;QAC1B,CAAC,CAAC,CAAC;IACL,CAAC;CACF;AA7BD,oCA6BC;AAEc,KAAK,UAAU,oBAAoB,CAChD,UAAkB,EAAE,wBAAwB;AAC5C,OAAgB;IAEhB,OAAO,IAAI,YAAY,CAAC,UAAU,EAAE,OAAO,EAAE,0BAAsB,CAAC,CAAC;AACvE,CAAC;AALD,uCAKC"} |
| /// <reference types="node" /> | ||
| import type { Options } from "./worker/import"; | ||
| import { EventEmitter } from "events"; | ||
| import { SendToWasmAbstractBase } from "./worker/send-to-wasm"; | ||
| import { RecvFromWasmAbstractBase } from "./worker/recv-from-wasm"; | ||
| export { Options }; | ||
| export interface WorkerThread extends EventEmitter { | ||
| postMessage: (message: object) => void; | ||
| terminate: () => void; | ||
| } | ||
| export declare class WasmInstanceAbstractBaseClass extends EventEmitter { | ||
| private callId; | ||
| private options; | ||
| private ioProvider; | ||
| private outputMonitorDelay; | ||
| result: any; | ||
| exports: any; | ||
| wasmSource: string; | ||
| protected worker?: WorkerThread; | ||
| send: SendToWasmAbstractBase; | ||
| recv: RecvFromWasmAbstractBase; | ||
| constructor(wasmSource: string, options: Options, IOProviderClass: any); | ||
| signal(sig?: number): void; | ||
| protected initWorker(): WorkerThread; | ||
| writeToStdin(data: any): void; | ||
| private init; | ||
| private readOutput; | ||
| monitorOutput(): Promise<void>; | ||
| terminate(): void; | ||
| callWithString(name: string | { | ||
| name: string; | ||
| dll: string; | ||
| }, str: string | string[], ...args: any[]): Promise<any>; | ||
| waitUntilFsLoaded(): Promise<void>; | ||
| private waitForResponse; | ||
| protected configureTerminal(): void; | ||
| exec(argv?: string[]): Promise<number>; | ||
| getFunction(_name: string, _dll?: string): Function | undefined; | ||
| getcwd(): string; | ||
| fetch(url: string, path: string, mode?: number | string): Promise<void>; | ||
| } |
| "use strict"; | ||
| var __importDefault = (this && this.__importDefault) || function (mod) { | ||
| return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
| }; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.WasmInstanceAbstractBaseClass = void 0; | ||
| const awaiting_1 = require("awaiting"); | ||
| const events_1 = require("events"); | ||
| const reuseInFlight_1 = __importDefault(require("./reuseInFlight")); | ||
| const send_to_wasm_1 = require("./worker/send-to-wasm"); | ||
| const recv_from_wasm_1 = require("./worker/recv-from-wasm"); | ||
| const types_1 = require("./types"); | ||
| const constants_1 = require("./constants"); | ||
| const debug_1 = __importDefault(require("debug")); | ||
| const MAX_OUTPUT_DELAY_MS = 250; | ||
| const log = (0, debug_1.default)("wasm-main"); | ||
| // TODO: typescript actually has "export abstract class" ! No need to fake it... | ||
| // This implements WasmInstanceAsync from ./ | ||
| class WasmInstanceAbstractBaseClass extends events_1.EventEmitter { | ||
| constructor(wasmSource, options, IOProviderClass) { | ||
| super(); | ||
| this.callId = 0; | ||
| this.outputMonitorDelay = MAX_OUTPUT_DELAY_MS; | ||
| log("constructor", options); | ||
| this.wasmSource = wasmSource; | ||
| this.options = options; | ||
| this.init = (0, reuseInFlight_1.default)(this.init); | ||
| this.send = new send_to_wasm_1.SendToWasmAbstractBase(); | ||
| this.recv = new recv_from_wasm_1.RecvFromWasmAbstractBase(); | ||
| this.ioProvider = new IOProviderClass(); | ||
| } | ||
| signal(sig = constants_1.SIGINT) { | ||
| this.ioProvider.signal(sig); | ||
| } | ||
| // MUST override in derived class | ||
| initWorker() { | ||
| abstract("initWorker"); | ||
| return null; // for typescript | ||
| } | ||
| writeToStdin(data) { | ||
| log("writeToStdin", data); | ||
| this.ioProvider.writeToStdin(Buffer.from(data)); | ||
| if (data.toString().includes("\u0003")) { | ||
| this.signal(constants_1.SIGINT); | ||
| // This is a hack, but for some reason everything feels better with this included: | ||
| this.ioProvider.writeToStdin(Buffer.from("\n")); | ||
| } | ||
| setTimeout(() => { | ||
| this.readOutput(); | ||
| }, 1); | ||
| } | ||
| async init() { | ||
| if (this.worker) | ||
| return; | ||
| this.worker = this.initWorker(); | ||
| if (!this.worker) | ||
| throw Error("init - bug"); | ||
| const options = { ...this.ioProvider.getExtraOptions(), ...this.options }; | ||
| log("options = ", options); | ||
| this.worker.postMessage({ | ||
| event: "init", | ||
| name: this.wasmSource, | ||
| options, | ||
| // debug: this passes the debug state from the main thread to the worker thread; otherwise, | ||
| // we would have no way to ever see any debug logging from worker. This is really nice! | ||
| debug: debug_1.default.load(), | ||
| }); | ||
| this.worker.on("exit", () => this.terminate()); | ||
| this.worker.on("message", (message) => { | ||
| if (message == null) | ||
| return; | ||
| log("main thread got message", message); | ||
| // This can be useful in some low-level debugging situations: | ||
| // if (message.event == "stderr" || message.event == "stdout") { | ||
| // console.warn(new TextDecoder().decode(message.data)); | ||
| // } | ||
| // message with id handled elsewhere -- used for getting data back. | ||
| if (message.id != null) { | ||
| // message with id handled elsewhere -- used for getting data back. | ||
| this.emit("id", message); | ||
| return; | ||
| } | ||
| switch (message.event) { | ||
| case "init": | ||
| this.emit("init", message); | ||
| return; | ||
| case "stdout": | ||
| this.emit("stdout", message.data); | ||
| break; | ||
| case "stderr": | ||
| this.emit("stderr", message.data); | ||
| break; | ||
| } | ||
| }); | ||
| this.monitorOutput(); | ||
| await (0, awaiting_1.callback)((cb) => this.once("init", (message) => { | ||
| cb(message.error); | ||
| })); | ||
| } | ||
| async readOutput() { | ||
| if (this.worker == null) | ||
| return 0; | ||
| const data = await this.ioProvider.readOutput(); | ||
| if (data.length > 0) { | ||
| this.outputMonitorDelay = 1; | ||
| this.emit(data[0] == types_1.Stream.STDOUT ? "stdout" : "stderr", data.subarray(1)); | ||
| } | ||
| else { | ||
| this.outputMonitorDelay = Math.min(MAX_OUTPUT_DELAY_MS, this.outputMonitorDelay * 1.3); | ||
| } | ||
| return data.length; | ||
| } | ||
| async monitorOutput() { | ||
| while (this.worker != null) { | ||
| await this.readOutput(); | ||
| await delay(this.outputMonitorDelay); | ||
| } | ||
| } | ||
| terminate() { | ||
| if (this.worker == null) | ||
| return; | ||
| const worker = this.worker; | ||
| delete this.worker; | ||
| worker.emit("exit"); | ||
| worker.terminate(); | ||
| worker.removeAllListeners(); | ||
| this.emit("terminate"); | ||
| this.removeAllListeners(); | ||
| } | ||
| async callWithString(name, str, ...args) { | ||
| await this.init(); | ||
| if (!this.worker) { | ||
| throw Error(`callWithString (name=${JSON.stringify(name)}, str='${JSON.stringify(str)}') - worker is not running`); | ||
| } | ||
| this.callId += 1; | ||
| this.worker.postMessage({ | ||
| id: this.callId, | ||
| event: "callWithString", | ||
| name, | ||
| str, | ||
| args, | ||
| }); | ||
| return await this.waitForResponse(this.callId); | ||
| } | ||
| async waitUntilFsLoaded() { | ||
| if (!this.worker) { | ||
| throw Error(`waitUntilFsLoaded - bug; worker must be defined`); | ||
| } | ||
| this.callId += 1; | ||
| this.worker.postMessage({ | ||
| id: this.callId, | ||
| event: "waitUntilFsLoaded", | ||
| }); | ||
| await this.waitForResponse(this.callId); | ||
| } | ||
| async waitForResponse(id) { | ||
| return (await (0, awaiting_1.callback)((cb) => { | ||
| const removeListeners = () => { | ||
| this.removeListener("id", messageListener); | ||
| this.removeListener("sigint", sigintListener); | ||
| }; | ||
| const messageListener = (message) => { | ||
| if (message.id == id) { | ||
| removeListeners(); | ||
| if (message.error) { | ||
| cb(message.error); | ||
| } | ||
| else { | ||
| cb(undefined, message); | ||
| } | ||
| } | ||
| }; | ||
| this.on("id", messageListener); | ||
| const sigintListener = () => { | ||
| removeListeners(); | ||
| cb("KeyboardInterrupt"); | ||
| }; | ||
| this.once("sigint", sigintListener); | ||
| this.worker?.on("exit", () => { | ||
| removeListeners(); | ||
| cb("exit"); | ||
| }); | ||
| })).result; | ||
| } | ||
| // Optionally override in derived class | ||
| configureTerminal() { } | ||
| async exec(argv = ["command"]) { | ||
| await this.init(); | ||
| if (this.worker == null) | ||
| throw Error("exec: bug - worker must be defined"); | ||
| if (!this.options.noStdio) { | ||
| this.configureTerminal(); | ||
| } | ||
| let r = 0; | ||
| try { | ||
| r = await this.callWithString("cowasm_exec", argv); | ||
| this.terminate(); | ||
| } | ||
| catch (_) { | ||
| // expected to fail -- call doesn't get output... | ||
| } | ||
| return r; | ||
| } | ||
| getFunction(_name, _dll) { | ||
| throw Error("not implemented"); | ||
| } | ||
| getcwd() { | ||
| throw Error("not implemented"); | ||
| } | ||
| async fetch(url, path, mode) { | ||
| if (this.worker == null) | ||
| throw Error("fetch: bug - worker must be defined"); | ||
| this.callId += 1; | ||
| this.worker.postMessage({ | ||
| id: this.callId, | ||
| event: "fetch", | ||
| url, | ||
| path, | ||
| mode, | ||
| }); | ||
| await this.waitForResponse(this.callId); | ||
| } | ||
| } | ||
| exports.WasmInstanceAbstractBaseClass = WasmInstanceAbstractBaseClass; | ||
| function abstract(name) { | ||
| throw Error(`${name} -- must be defined in derived class`); | ||
| } | ||
| function delay(milliseconds) { | ||
| return new Promise((resolve) => setTimeout(resolve, milliseconds)); | ||
| } | ||
| //# sourceMappingURL=import.js.map |
| {"version":3,"file":"import.js","sourceRoot":"","sources":["../../src/wasm/import.ts"],"names":[],"mappings":"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"} |
| /// <reference types="node" /> | ||
| import type { IOProvider } from "./types"; | ||
| interface Buffers { | ||
| stdinBuffer: SharedArrayBuffer; | ||
| stdinLengthBuffer: SharedArrayBuffer; | ||
| outputBuffer: SharedArrayBuffer; | ||
| outputLengthBuffer: SharedArrayBuffer; | ||
| signalBuffer: SharedArrayBuffer; | ||
| } | ||
| export default class IOProviderUsingAtomics implements IOProvider { | ||
| private stdinLength; | ||
| private stdinUint8Array; | ||
| private outputLength; | ||
| private outputUint8Array; | ||
| private signalInt32Array; | ||
| private buffers; | ||
| constructor(); | ||
| writeToStdin(data: Buffer): void; | ||
| readOutput(): Promise<Buffer>; | ||
| getExtraOptions(): Buffers; | ||
| signal(sig?: number): void; | ||
| } | ||
| export {}; |
| "use strict"; | ||
| /* | ||
| Synchronous blocking IO using Atomics and SharedArrayBuffers. | ||
| This requires cross-origin isolation, so the two headers have to be set by the | ||
| server as follows. This is VERY restrictive, but if you can do this, it's optimal: | ||
| "Cross-Origin-Opener-Policy": "same-origin" | ||
| "Cross-Origin-Embedder-Policy": "require-corp" | ||
| */ | ||
| var __importDefault = (this && this.__importDefault) || function (mod) { | ||
| return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
| }; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| const constants_1 = require("./constants"); | ||
| const debug_1 = __importDefault(require("debug")); | ||
| const log = (0, debug_1.default)("wasm:io-provider"); | ||
| class IOProviderUsingAtomics { | ||
| constructor() { | ||
| log("IOProviderUsingAtomics"); | ||
| const stdinLengthBuffer = new SharedArrayBuffer(4); | ||
| this.stdinLength = new Int32Array(stdinLengthBuffer); | ||
| // TODO: size?! -- implementation right now will start dropping data at this size, I think. | ||
| const stdinBuffer = new SharedArrayBuffer(10000); | ||
| this.stdinUint8Array = Buffer.from(stdinBuffer); | ||
| const outputLengthBuffer = new SharedArrayBuffer(4); | ||
| this.outputLength = new Int32Array(outputLengthBuffer); | ||
| const outputBuffer = new SharedArrayBuffer(10000); | ||
| this.outputUint8Array = Buffer.from(outputBuffer); | ||
| const signalBuffer = new SharedArrayBuffer(4); | ||
| this.signalInt32Array = new Int32Array(signalBuffer); | ||
| this.buffers = { | ||
| stdinBuffer, | ||
| stdinLengthBuffer, | ||
| outputBuffer, | ||
| outputLengthBuffer, | ||
| signalBuffer, | ||
| }; | ||
| } | ||
| writeToStdin(data) { | ||
| log("writeToStdin", data); | ||
| // place the new data in the stdinBuffer, so that the worker can receive | ||
| // it when it next checks for stdin. | ||
| data.copy(this.stdinUint8Array, this.stdinLength[0]); | ||
| log("setting writeToStdin input buffer size to ", data.length + this.stdinLength[0]); | ||
| Atomics.store(this.stdinLength, 0, data.length + this.stdinLength[0]); | ||
| Atomics.notify(this.stdinLength, 0); | ||
| } | ||
| // not really async, but we do this for consistent api with service worker. | ||
| async readOutput() { | ||
| if (this.outputUint8Array[0] == 0) { | ||
| // locked -- in the process of modifying in the worker thread. | ||
| return Buffer.alloc(0); | ||
| } | ||
| const n = this.outputLength[0]; | ||
| if (n == 0) { | ||
| return Buffer.alloc(0); | ||
| } | ||
| const data = Buffer.from(this.outputUint8Array.subarray(0, this.outputLength[0])); | ||
| Atomics.store(this.outputLength, 0, 0); | ||
| Atomics.notify(this.outputLength, 0); | ||
| return data; | ||
| } | ||
| getExtraOptions() { | ||
| return this.buffers; | ||
| } | ||
| signal(sig = constants_1.SIGINT) { | ||
| log("signal", sig); | ||
| // tell worker about this signal. | ||
| Atomics.store(this.signalInt32Array, 0, sig); | ||
| Atomics.notify(this.signalInt32Array, 0); | ||
| } | ||
| } | ||
| exports.default = IOProviderUsingAtomics; | ||
| //# sourceMappingURL=io-using-atomics.js.map |
| {"version":3,"file":"io-using-atomics.js","sourceRoot":"","sources":["../../src/wasm/io-using-atomics.ts"],"names":[],"mappings":"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"} |
| /// <reference types="node" /> | ||
| import type { IOProvider } from "./types"; | ||
| export default class IOProviderUsingServiceWorker implements IOProvider { | ||
| private id; | ||
| constructor(); | ||
| getExtraOptions(): { | ||
| id: string; | ||
| }; | ||
| private send; | ||
| signal(sig?: number): void; | ||
| writeToStdin(data: Buffer): void; | ||
| readOutput(): Promise<Buffer>; | ||
| } | ||
| export declare function fixServiceWorker(): Promise<void>; |
| "use strict"; | ||
| /* | ||
| Synchronous blocking IO using service workers and XMLHttpRequest, | ||
| in cases when can't use atomics. By "IO", we also include "IO with | ||
| the system", e.g., signals. | ||
| This is inspired by the sync-message package. | ||
| References: | ||
| - https://github.com/alexmojaki/sync-message | ||
| - https://jasonformat.com/javascript-sleep/ | ||
| - https://stackoverflow.com/questions/10590213/synchronously-wait-for-message-in-web-worker | ||
| - https://github.com/pyodide/pyodide/issues/1503 | ||
| */ | ||
| var __importDefault = (this && this.__importDefault) || function (mod) { | ||
| return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
| }; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.fixServiceWorker = void 0; | ||
| const constants_1 = require("./constants"); | ||
| const debug_1 = __importDefault(require("debug")); | ||
| const uuid_1 = require("uuid"); | ||
| const log = (0, debug_1.default)("wasm:io-provider"); | ||
| class IOProviderUsingServiceWorker { | ||
| constructor() { | ||
| this.id = (0, uuid_1.v4)(); | ||
| log("IOProviderUsingXMLHttpRequest", "id = ", this.id); | ||
| registerServiceWorker(); | ||
| } | ||
| getExtraOptions() { | ||
| return { id: this.id }; | ||
| } | ||
| async send(target, body) { | ||
| const url = `/python-wasm-sw/${target}`; | ||
| try { | ||
| return await fetch(url, { method: "POST", body: JSON.stringify(body) }); | ||
| } | ||
| catch (err) { | ||
| console.warn("failed to send to service worker", { url, body }, err); | ||
| } | ||
| } | ||
| signal(sig = constants_1.SIGINT) { | ||
| log("signal", sig); | ||
| this.send("write-signal", { sig, id: this.id }); | ||
| } | ||
| writeToStdin(data) { | ||
| log("writeToStdin", data); | ||
| this.send("write-stdin", { data: data.toString(), id: this.id }); | ||
| } | ||
| async readOutput() { | ||
| const output = await this.send("read-output", { id: this.id }); | ||
| return Buffer.from(await output.text()); | ||
| } | ||
| } | ||
| exports.default = IOProviderUsingServiceWorker; | ||
| function getURL() { | ||
| // @ts-ignore this import.meta.url issue -- actually only consumed by webpack | ||
| const url = new URL("./worker/service-worker.js", import.meta.url).href; | ||
| console.log("service worker url = ", url); | ||
| return url; | ||
| } | ||
| function hasServiceWorker() { | ||
| if (!navigator.serviceWorker) { | ||
| console.warn("WARNING: service worker is not available, so nothing is going to work"); | ||
| return false; | ||
| } | ||
| return true; | ||
| } | ||
| async function registerServiceWorker() { | ||
| if (!hasServiceWorker()) | ||
| return; | ||
| const url = getURL(); | ||
| const reg = await navigator.serviceWorker.register(url); | ||
| if (reg.active?.state != "activated") { | ||
| // I think there is no way around this, since it is an unfortunate | ||
| // part of the service worker spec. | ||
| console.warn("Reloading page to activate service worker..."); | ||
| if (localStorage["python-wasm-service-worker-broken"]) { | ||
| // use local storage to avoid DOS of server | ||
| setTimeout(() => { | ||
| location.reload(); | ||
| }, 3000); | ||
| } | ||
| else { | ||
| localStorage["python-wasm-service-worker-broken"] = true; | ||
| location.reload(); | ||
| } | ||
| } | ||
| else { | ||
| // It probably worked. | ||
| delete localStorage["python-wasm-service-worker-broken"]; | ||
| } | ||
| } | ||
| /* | ||
| fixServiceWorker: | ||
| There is exactly one situation where I know this is definitely needed, though | ||
| browsers I think could revoke the service worker at any time, so it is good to | ||
| have an automated way to fix this. Also, this may be useful if we upgrade the | ||
| service worker and add a new URL endpoint, since this will get triggered. | ||
| 1. Open python-wasm using a service worker on an iphone or ipad in safari. | ||
| 2. Maybe open another page so the python-wasm page is in the background. | ||
| (Probably not needed.) | ||
| 3. Suspend your phone and wait 1 minute. | ||
| 4. Turn phone back on. The service worker *might* be completely broken and no | ||
| amount of refreshing fixes it. Without the workaround below, the only option is | ||
| for the user to clear all private data associated with the site, or wait a while | ||
| (maybe an hour) and things maybe start to work again. | ||
| I think this is caused by the page suspending in the middle of a "get stdin" | ||
| call. This code below does seem to effectively work around the problem, at the | ||
| expense of a page refresh when you return to the page. This isn't uncommon on | ||
| safari anyways though, since it often dumps pages to save memory. | ||
| This doesn't seem to happen on any desktop browsers (including safari) as far | ||
| as I can tell, even when suspending/resuming a laptop. | ||
| There may be a better fix involving changing how the service worker behaves, | ||
| but that is for another commit, and another day. | ||
| */ | ||
| async function fixServiceWorker() { | ||
| if (!hasServiceWorker()) | ||
| return; | ||
| console.warn("The service work seems to be disabled. Fixing it..."); | ||
| const url = getURL(); | ||
| try { | ||
| const reg = await navigator.serviceWorker.register(url); | ||
| await reg.unregister(); | ||
| } | ||
| catch (err) { | ||
| console.warn(err); | ||
| } | ||
| location.reload(); | ||
| } | ||
| exports.fixServiceWorker = fixServiceWorker; | ||
| //# sourceMappingURL=io-using-service-worker.js.map |
| {"version":3,"file":"io-using-service-worker.js","sourceRoot":"","sources":["../../src/wasm/io-using-service-worker.ts"],"names":[],"mappings":"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"} |
| declare const CONSTANTS: readonly ["AT_FDCWD", "E2BIG", "EACCES", "EAGAIN", "EBADF", "EBUSY", "ECHILD", "EDEADLK", "EEXIST", "EFAULT", "EFBIG", "EINTR", "EINVAL", "EIO", "EISDIR", "EMFILE", "EMLINK", "ENFILE", "ENODEV", "ENOENT", "ENOEXEC", "ENOMEM", "ENOSPC", "ENOTDIR", "ENOTTY", "ENXIO", "EPERM", "EPIPE", "EROFS", "ESPIPE", "ESRCH", "ETXTBSY", "EXDEV", "ENOTCONN", "EADDRINUSE", "EADDRNOTAVAIL", "EAFNOSUPPORT", "EALREADY", "ECONNREFUSED", "EFAULT", "EHOSTUNREACH", "EINPROGRESS", "EISCONN", "ENETDOWN", "ENETUNREACH", "ENOBUFS", "ENOTSOCK", "ENOPROTOOPT", "EOPNOTSUPP", "EPROTOTYPE", "ETIMEDOUT", "ECONNRESET", "ELOOP", "ENAMETOOLONG", "SIG_BLOCK", "SIG_UNBLOCK", "SIG_SETMASK", "AF_INET", "AF_INET6", "F_ULOCK", "F_LOCK", "F_TLOCK", "F_TEST", "IFNAMSIZ", "ENOTSUP", "WNOHANG", "WUNTRACED", "MSG_OOB", "MSG_PEEK", "MSG_WAITALL", "MSG_DONTROUTE", "O_CLOEXEC", "O_NONBLOCK", "O_APPEND", "SO_ACCEPTCONN", "SO_ATTACH_BPF", "SO_ATTACH_FILTER", "SO_ATTACH_REUSEPORT_CBPF", "SO_ATTACH_REUSEPORT_EBPF", "SO_BINDTODEVICE", "SO_BINDTOIFINDEX", "SO_BPF_EXTENSIONS", "SO_BROADCAST", "SO_BSDCOMPAT", "SO_BUSY_POLL", "SO_CNX_ADVICE", "SO_COOKIE", "SO_DEBUG", "SO_DETACH_BPF", "SO_DETACH_FILTER", "SO_DETACH_REUSEPORT_BPF", "SO_DOMAIN", "SO_DONTROUTE", "SO_ERROR", "SO_GET_FILTER", "SO_INCOMING_CPU", "SO_INCOMING_NAPI_ID", "SO_KEEPALIVE", "SO_LINGER", "SO_LOCK_FILTER", "SO_MARK", "SO_MAX_PACING_RATE", "SO_MEMINFO", "SO_NOFCS", "SO_NO_CHECK", "SO_OOBINLINE", "SO_PASSCRED", "SO_PASSSEC", "SO_PEEK_OFF", "SO_PEERCRED", "SO_PEERGROUPS", "SO_PEERNAME", "SO_PEERSEC", "SO_PRIORITY", "SO_PROTOCOL", "SO_RCVBUF", "SO_RCVBUFFORCE", "SO_RCVLOWAT", "SO_RCVTIMEO", "SO_REUSEADDR", "SO_REUSEPORT", "SO_RXQ_OVFL", "SO_SECURITY_AUTHENTICATION", "SO_SECURITY_ENCRYPTION_NETWORK", "SO_SECURITY_ENCRYPTION_TRANSPORT", "SO_SELECT_ERR_QUEUE", "SO_SNDBUF", "SO_SNDBUFFORCE", "SO_SNDLOWAT", "SO_SNDTIMEO", "SO_TIMESTAMP", "SO_TIMESTAMPING", "SO_TIMESTAMPNS", "SO_TXTIME", "SO_TYPE", "SO_WIFI_STATUS", "SO_ZEROCOPY", "SOL_SOCKET", "POLLIN", "POLLOUT"]; | ||
| export declare type Constant = typeof CONSTANTS[number]; | ||
| declare const constants: { | ||
| [name: string]: number; | ||
| }; | ||
| export default constants; | ||
| export declare function initConstants(context: any): void; |
| "use strict"; | ||
| var __importDefault = (this && this.__importDefault) || function (mod) { | ||
| return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
| }; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.initConstants = void 0; | ||
| const debug_1 = __importDefault(require("debug")); | ||
| const log = (0, debug_1.default)("posix:constants"); | ||
| // These are purely for typescript, and I can only update this (when the zig code changes) | ||
| // by just printing out the constants at runtime. | ||
| const CONSTANTS = [ | ||
| "AT_FDCWD", | ||
| "E2BIG", | ||
| "EACCES", | ||
| "EAGAIN", | ||
| "EBADF", | ||
| "EBUSY", | ||
| "ECHILD", | ||
| "EDEADLK", | ||
| "EEXIST", | ||
| "EFAULT", | ||
| "EFBIG", | ||
| "EINTR", | ||
| "EINVAL", | ||
| "EIO", | ||
| "EISDIR", | ||
| "EMFILE", | ||
| "EMLINK", | ||
| "ENFILE", | ||
| "ENODEV", | ||
| "ENOENT", | ||
| "ENOEXEC", | ||
| "ENOMEM", | ||
| "ENOSPC", | ||
| "ENOTDIR", | ||
| "ENOTTY", | ||
| "ENXIO", | ||
| "EPERM", | ||
| "EPIPE", | ||
| "EROFS", | ||
| "ESPIPE", | ||
| "ESRCH", | ||
| "ETXTBSY", | ||
| "EXDEV", | ||
| "ENOTCONN", | ||
| "EADDRINUSE", | ||
| "EADDRNOTAVAIL", | ||
| "EAFNOSUPPORT", | ||
| "EALREADY", | ||
| "ECONNREFUSED", | ||
| "EFAULT", | ||
| "EHOSTUNREACH", | ||
| "EINPROGRESS", | ||
| "EISCONN", | ||
| "ENETDOWN", | ||
| "ENETUNREACH", | ||
| "ENOBUFS", | ||
| "ENOTSOCK", | ||
| "ENOPROTOOPT", | ||
| "EOPNOTSUPP", | ||
| "EPROTOTYPE", | ||
| "ETIMEDOUT", | ||
| "ECONNRESET", | ||
| "ELOOP", | ||
| "ENAMETOOLONG", | ||
| "SIG_BLOCK", | ||
| "SIG_UNBLOCK", | ||
| "SIG_SETMASK", | ||
| "AF_INET", | ||
| "AF_INET6", | ||
| "F_ULOCK", | ||
| "F_LOCK", | ||
| "F_TLOCK", | ||
| "F_TEST", | ||
| "IFNAMSIZ", | ||
| "ENOTSUP", | ||
| "WNOHANG", | ||
| "WUNTRACED", | ||
| "MSG_OOB", | ||
| "MSG_PEEK", | ||
| "MSG_WAITALL", | ||
| "MSG_DONTROUTE", | ||
| "O_CLOEXEC", | ||
| "O_NONBLOCK", | ||
| "O_APPEND", | ||
| "SO_ACCEPTCONN", | ||
| "SO_ATTACH_BPF", | ||
| "SO_ATTACH_FILTER", | ||
| "SO_ATTACH_REUSEPORT_CBPF", | ||
| "SO_ATTACH_REUSEPORT_EBPF", | ||
| "SO_BINDTODEVICE", | ||
| "SO_BINDTOIFINDEX", | ||
| "SO_BPF_EXTENSIONS", | ||
| "SO_BROADCAST", | ||
| "SO_BSDCOMPAT", | ||
| "SO_BUSY_POLL", | ||
| "SO_CNX_ADVICE", | ||
| "SO_COOKIE", | ||
| "SO_DEBUG", | ||
| "SO_DETACH_BPF", | ||
| "SO_DETACH_FILTER", | ||
| "SO_DETACH_REUSEPORT_BPF", | ||
| "SO_DOMAIN", | ||
| "SO_DONTROUTE", | ||
| "SO_ERROR", | ||
| "SO_GET_FILTER", | ||
| "SO_INCOMING_CPU", | ||
| "SO_INCOMING_NAPI_ID", | ||
| "SO_KEEPALIVE", | ||
| "SO_LINGER", | ||
| "SO_LOCK_FILTER", | ||
| "SO_MARK", | ||
| "SO_MAX_PACING_RATE", | ||
| "SO_MEMINFO", | ||
| "SO_NOFCS", | ||
| "SO_NO_CHECK", | ||
| "SO_OOBINLINE", | ||
| "SO_PASSCRED", | ||
| "SO_PASSSEC", | ||
| "SO_PEEK_OFF", | ||
| "SO_PEERCRED", | ||
| "SO_PEERGROUPS", | ||
| "SO_PEERNAME", | ||
| "SO_PEERSEC", | ||
| "SO_PRIORITY", | ||
| "SO_PROTOCOL", | ||
| "SO_RCVBUF", | ||
| "SO_RCVBUFFORCE", | ||
| "SO_RCVLOWAT", | ||
| "SO_RCVTIMEO", | ||
| "SO_REUSEADDR", | ||
| "SO_REUSEPORT", | ||
| "SO_RXQ_OVFL", | ||
| "SO_SECURITY_AUTHENTICATION", | ||
| "SO_SECURITY_ENCRYPTION_NETWORK", | ||
| "SO_SECURITY_ENCRYPTION_TRANSPORT", | ||
| "SO_SELECT_ERR_QUEUE", | ||
| "SO_SNDBUF", | ||
| "SO_SNDBUFFORCE", | ||
| "SO_SNDLOWAT", | ||
| "SO_SNDTIMEO", | ||
| "SO_TIMESTAMP", | ||
| "SO_TIMESTAMPING", | ||
| "SO_TIMESTAMPNS", | ||
| "SO_TXTIME", | ||
| "SO_TYPE", | ||
| "SO_WIFI_STATUS", | ||
| "SO_ZEROCOPY", | ||
| "SOL_SOCKET", | ||
| "POLLIN", | ||
| "POLLOUT", | ||
| ]; | ||
| const constants = {}; | ||
| exports.default = constants; | ||
| function recvJsonObject({ callFunction, recv }, name) { | ||
| let ptr = callFunction(name); | ||
| if (ptr == 0) { | ||
| throw Error("unable to receive JSON object"); | ||
| } | ||
| return JSON.parse(recv.string(ptr)); | ||
| } | ||
| function initConstants(context) { | ||
| const { names, values } = recvJsonObject(context, "getConstants"); | ||
| for (let i = 0; i < names.length; i++) { | ||
| constants[names[i]] = values[i]; | ||
| } | ||
| log(constants); | ||
| } | ||
| exports.initConstants = initConstants; | ||
| //# sourceMappingURL=constants.js.map |
| {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../src/wasm/posix/constants.ts"],"names":[],"mappings":"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"} |
| export default function epoll({ sleep }: { | ||
| sleep?: any; | ||
| }): { | ||
| epoll_create: (_size: number) => number; | ||
| epoll_create1: (_flags: number) => number; | ||
| epoll_ctl: (_epfd: number, _op: number, _fd: number, _epoll_event_ptr: number) => number; | ||
| epoll_wait: (_epfd: number, _epoll_event_ptr: number, _maxevents: number, timeout: number) => number; | ||
| }; |
| "use strict"; | ||
| /* | ||
| See https://en.wikipedia.org/wiki/Epoll | ||
| This is a stub implementation of epoll that doesn't do anything in terms | ||
| of actually detecting file changes, but also appears not broken to the user. | ||
| It's very reasonable that we could implement a real version of epoll. | ||
| For linux it could just be a lightweight wrapper around real epoll, and for | ||
| other environments, something else depending on constraints. | ||
| This is used by the tail coreutils command to watch a file... | ||
| */ | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| function epoll({ sleep }) { | ||
| return { | ||
| // int epoll_create(int flags); | ||
| epoll_create: (_size) => { | ||
| return 0; | ||
| }, | ||
| // int epoll_create1(int flags); | ||
| epoll_create1: (_flags) => { | ||
| return 0; | ||
| }, | ||
| // int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event); | ||
| epoll_ctl: (_epfd, _op, _fd, _epoll_event_ptr) => { | ||
| return 0; | ||
| }, | ||
| // int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout); | ||
| epoll_wait: (_epfd, _epoll_event_ptr, _maxevents, timeout) => { | ||
| // if blocking sleep is available, we wait timeout *milliseconds*, then return 0 | ||
| sleep?.(timeout); | ||
| return 0; | ||
| }, | ||
| }; | ||
| } | ||
| exports.default = epoll; | ||
| //# sourceMappingURL=epoll.js.map |
| {"version":3,"file":"epoll.js","sourceRoot":"","sources":["../../../src/wasm/posix/epoll.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;EAWE;;AAEF,SAAwB,KAAK,CAAC,EAAE,KAAK,EAAc;IACjD,OAAO;QACL,+BAA+B;QAC/B,YAAY,EAAE,CAAC,KAAa,EAAU,EAAE;YACtC,OAAO,CAAC,CAAC;QACX,CAAC;QACD,gCAAgC;QAChC,aAAa,EAAE,CAAC,MAAc,EAAU,EAAE;YACxC,OAAO,CAAC,CAAC;QACX,CAAC;QAED,sEAAsE;QACtE,SAAS,EAAE,CACT,KAAa,EACb,GAAW,EACX,GAAW,EACX,gBAAwB,EAChB,EAAE;YACV,OAAO,CAAC,CAAC;QACX,CAAC;QAED,oFAAoF;QACpF,UAAU,EAAE,CACV,KAAa,EACb,gBAAwB,EACxB,UAAkB,EAClB,OAAe,EACP,EAAE;YACV,gFAAgF;YAChF,KAAK,EAAE,CAAC,OAAO,CAAC,CAAC;YACjB,OAAO,CAAC,CAAC;QACX,CAAC;KACF,CAAC;AACJ,CAAC;AAjCD,wBAiCC"} |
| import { Constant } from "./constants"; | ||
| export default function Errno(error: Constant): Error; | ||
| export declare function nativeToWasm(posix: any): { | ||
| [native: number]: number; | ||
| }; |
| "use strict"; | ||
| var __importDefault = (this && this.__importDefault) || function (mod) { | ||
| return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
| }; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.nativeToWasm = void 0; | ||
| const constants_1 = __importDefault(require("./constants")); | ||
| function Errno(error) { | ||
| const errno = constants_1.default[error]; | ||
| const err = Error(`Error ${error} (errno=${errno}).`); | ||
| err.wasiErrno = errno; | ||
| return err; | ||
| } | ||
| exports.default = Errno; | ||
| // Return map from standard native error codes to | ||
| // WASM error codes. These can be *very* different | ||
| // and have to be translated. | ||
| function nativeToWasm(posix) { | ||
| // DO **NOT** add anything more to this, e.g., ENOTSUP, since we are making | ||
| // a mapping back and forth usig it, and any overlaps will lead to subtle errors! | ||
| const names = [ | ||
| "E2BIG", | ||
| "EACCES", | ||
| "EBADF", | ||
| "EBUSY", | ||
| "ECHILD", | ||
| "EDEADLK", | ||
| "EEXIST", | ||
| "EFAULT", | ||
| "EFBIG", | ||
| "EINTR", | ||
| "EINVAL", | ||
| "EIO", | ||
| "EISDIR", | ||
| "EMFILE", | ||
| "EMLINK", | ||
| "ENFILE", | ||
| "ENODEV", | ||
| "ENOENT", | ||
| "ENOEXEC", | ||
| "ENOMEM", | ||
| "ENOSPC", | ||
| "ENOTDIR", | ||
| "ENOTTY", | ||
| "ENXIO", | ||
| "EPERM", | ||
| "EPIPE", | ||
| "EROFS", | ||
| "ESPIPE", | ||
| "ESRCH", | ||
| "ETXTBSY", | ||
| "EXDEV", | ||
| ]; | ||
| const map = {}; | ||
| for (const name of names) { | ||
| const eNative = posix.constants?.[name]; | ||
| if (!eNative) { | ||
| throw Error(`posix constant ${name} not known`); | ||
| } | ||
| const eWasm = constants_1.default[name]; | ||
| if (!eWasm) { | ||
| throw Error(`wasm constant ${name} not known`); | ||
| } | ||
| map[eNative] = eWasm; | ||
| } | ||
| return map; | ||
| } | ||
| exports.nativeToWasm = nativeToWasm; | ||
| //# sourceMappingURL=errno.js.map |
| {"version":3,"file":"errno.js","sourceRoot":"","sources":["../../../src/wasm/posix/errno.ts"],"names":[],"mappings":";;;;;;AAAA,4DAAkD;AAElD,SAAwB,KAAK,CAAC,KAAe;IAC3C,MAAM,KAAK,GAAG,mBAAS,CAAC,KAAK,CAAC,CAAC;IAC/B,MAAM,GAAG,GAAG,KAAK,CAAC,SAAS,KAAK,YAAY,KAAK,IAAI,CAAC,CAAC;IACtD,GAAW,CAAC,SAAS,GAAG,KAAK,CAAC;IAC/B,OAAO,GAAG,CAAC;AACb,CAAC;AALD,wBAKC;AAED,iDAAiD;AACjD,mDAAmD;AACnD,6BAA6B;AAC7B,SAAgB,YAAY,CAAC,KAAK;IAChC,2EAA2E;IAC3E,iFAAiF;IACjF,MAAM,KAAK,GAAG;QACZ,OAAO;QACP,QAAQ;QACR,OAAO;QACP,OAAO;QACP,QAAQ;QACR,SAAS;QACT,QAAQ;QACR,QAAQ;QACR,OAAO;QACP,OAAO;QACP,QAAQ;QACR,KAAK;QACL,QAAQ;QACR,QAAQ;QACR,QAAQ;QACR,QAAQ;QACR,QAAQ;QACR,QAAQ;QACR,SAAS;QACT,QAAQ;QACR,QAAQ;QACR,SAAS;QACT,QAAQ;QACR,OAAO;QACP,OAAO;QACP,OAAO;QACP,OAAO;QACP,QAAQ;QACR,OAAO;QACP,SAAS;QACT,OAAO;KACR,CAAC;IACF,MAAM,GAAG,GAAiC,EAAE,CAAC;IAC7C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE;QACxB,MAAM,OAAO,GAAG,KAAK,CAAC,SAAS,EAAE,CAAC,IAAI,CAAC,CAAC;QACxC,IAAI,CAAC,OAAO,EAAE;YACZ,MAAM,KAAK,CAAC,kBAAkB,IAAI,YAAY,CAAC,CAAC;SACjD;QACD,MAAM,KAAK,GAAG,mBAAS,CAAC,IAAI,CAAC,CAAC;QAC9B,IAAI,CAAC,KAAK,EAAE;YACV,MAAM,KAAK,CAAC,iBAAiB,IAAI,YAAY,CAAC,CAAC;SAChD;QACD,GAAG,CAAC,OAAO,CAAC,GAAG,KAAK,CAAC;KACtB;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAjDD,oCAiDC"} |
| export default function fork_exec({ posix, recv, wasi, run, fs, child_process, }: { | ||
| posix: any; | ||
| recv: any; | ||
| wasi: any; | ||
| run: any; | ||
| fs: any; | ||
| child_process: any; | ||
| }): { | ||
| python_wasm_set_inheritable: (fd: number, inheritable: number) => number; | ||
| python_wasm_fork_exec: (exec_array_ptr: any, argv_ptr: any, envp_ptr: any, cwd: any, p2cread: any, p2cwrite: any, c2pread: any, c2pwrite: any, errread: any, errwrite: any, errpipe_read: any, errpipe_write: any, close_fds: any, restore_signals: any, call_setsid: any, pgid_to_set: any, call_setgid: any, gid: any, call_setgroups: any, groups_size: any, groups: any, call_setuid: any, uid: any, child_umask: any, child_sigmask: any, py_fds_to_keep: any) => number; | ||
| cowasm_vforkexec: (argvPtr: number, pathPtr?: number) => number; | ||
| }; |
| "use strict"; | ||
| /* | ||
| TODO: refactor -- some of this code will go in a new python-wasm module? | ||
| extern int python_wasm_fork_exec( | ||
| char *const exec_array[], | ||
| char *const argv[], | ||
| char *const envp[], | ||
| const char *cwd, | ||
| int p2cread, int p2cwrite, | ||
| int c2pread, int c2pwrite, | ||
| int errread, int errwrite, | ||
| int errpipe_read, int errpipe_write, | ||
| int close_fds, int restore_signals, | ||
| int call_setsid, pid_t pgid_to_set, | ||
| int call_setgid, gid_t gid, | ||
| int call_setgroups, size_t groups_size, const gid_t *groups, | ||
| int call_setuid, uid_t uid, | ||
| int child_umask, | ||
| const void *child_sigmask, | ||
| int *py_fds_to_keep // null or a null terminated int[] | ||
| ); | ||
| */ | ||
| var __importDefault = (this && this.__importDefault) || function (mod) { | ||
| return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
| }; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| const debug_1 = __importDefault(require("debug")); | ||
| const errno_1 = require("./errno"); | ||
| const constants_1 = __importDefault(require("./constants")); | ||
| const path_1 = require("path"); | ||
| const log = (0, debug_1.default)("posix:fork-exec"); | ||
| const WASM = Buffer.from("\0asm"); | ||
| function fork_exec({ posix, recv, wasi, run, fs, child_process, }) { | ||
| function isWasm(filename) { | ||
| const fd = fs.openSync(filename, "r"); | ||
| const b = Buffer.alloc(4); | ||
| fs.readSync(fd, b, 0, 4, 0); | ||
| return WASM.equals(b); | ||
| } | ||
| function runNative(argv) { | ||
| if (child_process == null) { | ||
| console.log("ERROR: Running native commands not yet implemented in this environment."); | ||
| return 1; | ||
| } | ||
| try { | ||
| child_process.execFileSync(argv[0], argv.slice(1), { | ||
| stdio: "inherit", | ||
| }); | ||
| return 0; | ||
| } | ||
| catch (err) { | ||
| return err.status; | ||
| } | ||
| } | ||
| function real_fd(virtual_fd) { | ||
| const data = wasi.FD_MAP.get(virtual_fd); | ||
| if (data == null) { | ||
| return -1; | ||
| } | ||
| return data.real; | ||
| } | ||
| // map from wasi number to real fd number, for each inheritable file descriptor | ||
| function getInheritableDescriptorsMap() { | ||
| const map = {}; | ||
| for (const wasi_fd of wasi.FD_MAP.keys()) { | ||
| const data = wasi.FD_MAP.get(wasi_fd); | ||
| try { | ||
| if (posix.is_inheritable(data.real)) { | ||
| map[wasi_fd] = data.real; | ||
| } | ||
| } | ||
| catch (err) { | ||
| log("getInheritableDescriptorsMap", data.real, err); | ||
| } | ||
| } | ||
| return map; | ||
| } | ||
| return { | ||
| // We have to implement this since fcntl -- which python library calls -- is too | ||
| // much of a no-op. This is needed for subprocess support only, of course. | ||
| // This can ONLY work on actual fd in the node.js process itself, e.g., pipes. | ||
| // When we implement this in the browser, we will also have fd's that correspond | ||
| // to pipes, where this works. | ||
| python_wasm_set_inheritable: (fd, inheritable) => { | ||
| if (posix.set_inheritable == null) { | ||
| // no-op on platform where we aren't going to ever fork anyways. | ||
| return 0; | ||
| } | ||
| const real = real_fd(fd); | ||
| if (real == -1) { | ||
| throw Error("invalid file descriptor"); | ||
| } | ||
| try { | ||
| // This will fail if real isn't a pipe or actual native file descriptor. | ||
| // In that case, we treat as a no-op, since there is nothing we can possibly do. | ||
| posix.set_inheritable(real, !!inheritable); | ||
| } | ||
| catch (_) { | ||
| return 0; | ||
| } | ||
| return 0; | ||
| }, | ||
| // Our custom implementation of the entire fork-exec process. We can't use Python's | ||
| // since node.js would need to get run in the forked process to do arbitrarily complicated | ||
| // things, and node.js is not written in a way to support actual forking. In practice, | ||
| // doing that sort of works, but **RANDOMLY CRASHES** and will drive you insane. So | ||
| // we just did the hard work and wrote this. | ||
| python_wasm_fork_exec: (exec_array_ptr, argv_ptr, envp_ptr, cwd, p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite, errpipe_read, errpipe_write, close_fds, restore_signals, call_setsid, pgid_to_set, call_setgid, gid, call_setgroups, groups_size, groups, call_setuid, uid, child_umask, child_sigmask, py_fds_to_keep) => { | ||
| log("called fork_exec"); | ||
| log("ignoring these: ", { | ||
| restore_signals, | ||
| call_setsid, | ||
| pgid_to_set, | ||
| call_setgid, | ||
| gid, | ||
| call_setgroups, | ||
| groups_size, | ||
| groups, | ||
| call_setuid, | ||
| uid, | ||
| child_umask, | ||
| child_sigmask, | ||
| }); | ||
| log("before change", { | ||
| p2cread, | ||
| p2cwrite, | ||
| c2pread, | ||
| c2pwrite, | ||
| errread, | ||
| errwrite, | ||
| errpipe_read, | ||
| errpipe_write, | ||
| }); | ||
| const err_map = []; | ||
| const n2w = (0, errno_1.nativeToWasm)(posix); | ||
| for (let native_errno = 0; native_errno < 100; native_errno++) { | ||
| err_map[native_errno] = n2w[native_errno] ?? constants_1.default.ENOENT; | ||
| } | ||
| // if envp is empty, then explicitly give WASI_FD_INFO below; otherwise, | ||
| // we just include WASI_FD_INFO in envp. | ||
| const WASI_FD_INFO = JSON.stringify(getInheritableDescriptorsMap()); | ||
| const envp = recv.arrayOfStrings(envp_ptr); | ||
| if (envp.length > 0) { | ||
| envp.push(`WASI_FD_INFO=${WASI_FD_INFO}`); | ||
| } | ||
| const opts = { | ||
| exec_array: recv.arrayOfStrings(exec_array_ptr), | ||
| argv: recv.arrayOfStrings(argv_ptr), | ||
| envp, | ||
| cwd: recv.string(cwd), | ||
| p2cread: real_fd(p2cread), | ||
| p2cwrite: real_fd(p2cwrite), | ||
| c2pread: real_fd(c2pread), | ||
| c2pwrite: real_fd(c2pwrite), | ||
| errread: real_fd(errread), | ||
| errwrite: real_fd(errwrite), | ||
| errpipe_read: real_fd(errpipe_read), | ||
| errpipe_write: real_fd(errpipe_write), | ||
| close_fds, | ||
| fds_to_keep: recv.arrayOfI32(py_fds_to_keep).map(real_fd), | ||
| err_map, | ||
| WASI_FD_INFO, | ||
| }; | ||
| log("opts", opts); | ||
| log("descriptors map = ", getInheritableDescriptorsMap()); | ||
| try { | ||
| const pid = posix.fork_exec(opts); | ||
| log("got subprocess = ", pid); | ||
| return pid; | ||
| } | ||
| catch (err) { | ||
| log("error doing fork", err); | ||
| return -1; | ||
| } | ||
| }, | ||
| // Kind of similar to above but blocking and **supports webassembly programs** | ||
| // through some amazing "magic": | ||
| // extern int cowasm_vforkexec(char **argv, const char *path); | ||
| cowasm_vforkexec: (argvPtr, pathPtr = 0) => { | ||
| const argv = recv.arrayOfStrings(argvPtr); | ||
| const path = pathPtr ? recv.string(pathPtr) : ""; | ||
| log("cowasm_vforkexec", argv); | ||
| if (!argv[0]) { | ||
| log("cowasm_vforkexec", "no argv[0]"); | ||
| throw Error("argv[0] must be defined"); | ||
| } | ||
| try { | ||
| if (!argv[0].includes("/")) { | ||
| // search path | ||
| log("cowasm_vforkexec", "go through search path to find", argv[0]); | ||
| for (const dir of path.split(":")) { | ||
| const pathToCmd = (0, path_1.join)((0, path_1.resolve)(dir), argv[0]); | ||
| try { | ||
| const stat = fs.statSync(pathToCmd); | ||
| if (stat.mode & fs.constants.S_IXUSR) { | ||
| argv[0] = pathToCmd; | ||
| break; | ||
| } | ||
| } | ||
| catch (_err) { } | ||
| } | ||
| log("cowasm_vforkexec", "found", argv[0]); | ||
| } | ||
| if (!argv[0].includes("/") || !fs.existsSync(argv[0])) { | ||
| log("cowasm_vforkexec", "could not find executable"); | ||
| console.error(`${argv[0]}: not found\n`); | ||
| // couldn't find it | ||
| return 127; | ||
| } | ||
| const stat = fs.statSync(argv[0]); | ||
| if (!(stat.mode & fs.constants.S_IXUSR)) { | ||
| log("cowasm_vforkexec", "executable has wrong permissions (missing IXUSR)"); | ||
| console.error(`${argv[0]}: Permission denied\n`); | ||
| // not executable | ||
| return 126; | ||
| } | ||
| const wasm = isWasm(argv[0]); | ||
| log("isWasm = ", wasm); | ||
| if (wasm) { | ||
| log("running wasm executable", argv[0]); | ||
| return run(argv); | ||
| } | ||
| else if (child_process != null) { | ||
| log("running native executable", argv[0]); | ||
| return runNative(argv); | ||
| } | ||
| log("can't run anything"); | ||
| console.error(`${argv[0]}: cannot execute binary file\n`); | ||
| } | ||
| catch (err) { | ||
| console.trace(`${argv[0]}: ${err}`); | ||
| } | ||
| // anything that didn't work | ||
| return 127; | ||
| }, | ||
| }; | ||
| } | ||
| exports.default = fork_exec; | ||
| //# sourceMappingURL=fork-exec.js.map |
| {"version":3,"file":"fork-exec.js","sourceRoot":"","sources":["../../../src/wasm/posix/fork-exec.ts"],"names":[],"mappings":"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"} |
| import WASI from "wasi-js"; | ||
| import SendToWasm from "../worker/send-to-wasm"; | ||
| import RecvFromWasm from "../worker/recv-from-wasm"; | ||
| export interface Context { | ||
| state: { | ||
| [name: string]: any; | ||
| }; | ||
| fs: FileSystem; | ||
| send: SendToWasm; | ||
| recv: RecvFromWasm; | ||
| wasi: WASI; | ||
| run: (args: string[]) => number; | ||
| process: { | ||
| getpid?: () => number; | ||
| getuid?: () => number; | ||
| pid?: number; | ||
| cwd?: () => string; | ||
| }; | ||
| os: { | ||
| loadavg?: () => [number, number, number]; | ||
| getPriority?: (pid?: number) => number; | ||
| setPriority?: (pid: number, priority?: number) => void; | ||
| platform?: () => // we care about darwin/linux/win32 for our runtime. | ||
| "darwin" | "linux" | "win32" | "aix" | "freebsd" | "openbsd" | "sunos"; | ||
| }; | ||
| child_process: { | ||
| spawnSync?: (command: string) => number; | ||
| }; | ||
| memory: WebAssembly.Memory; | ||
| posix: { | ||
| getpgid?: () => number; | ||
| constants?: { | ||
| [code: string]: number; | ||
| }; | ||
| chdir?: (string: any) => void; | ||
| }; | ||
| free: (ptr: number) => void; | ||
| callFunction: (name: string, ...args: any[]) => number | undefined; | ||
| callWithString: (func: string | { | ||
| name: string; | ||
| dll: string; | ||
| } | Function, str?: string | string[], ...args: any[]) => number | undefined; | ||
| getcwd: () => string; | ||
| sleep?: (milliseconds: number) => void; | ||
| noStdio: boolean; | ||
| } | ||
| export declare type PosixEnv = { | ||
| [name: string]: Function; | ||
| }; | ||
| export default function posix(context: Context): PosixEnv; |
| "use strict"; | ||
| /* | ||
| NOTES: | ||
| - emscripten/src/library_syscall.js is useful inspiration in some cases! | ||
| */ | ||
| var __importDefault = (this && this.__importDefault) || function (mod) { | ||
| return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
| }; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| const fork_exec_1 = __importDefault(require("./fork-exec")); | ||
| const epoll_1 = __importDefault(require("./epoll")); | ||
| const netdb_1 = __importDefault(require("./netdb")); | ||
| const netif_1 = __importDefault(require("./netif")); | ||
| const other_1 = __importDefault(require("./other")); | ||
| const sched_1 = __importDefault(require("./sched")); | ||
| const signal_1 = __importDefault(require("./signal")); | ||
| const socket_1 = __importDefault(require("./socket")); | ||
| const spawn_1 = __importDefault(require("./spawn")); | ||
| const stdlib_1 = __importDefault(require("./stdlib")); | ||
| const stdio_1 = __importDefault(require("./stdio")); | ||
| const stat_1 = __importDefault(require("./stat")); | ||
| const termios_1 = __importDefault(require("./termios")); | ||
| const time_1 = __importDefault(require("./time")); | ||
| const unistd_1 = __importDefault(require("./unistd")); | ||
| const wait_1 = __importDefault(require("./wait")); | ||
| const constants_1 = require("./constants"); | ||
| const constants_2 = __importDefault(require("./constants")); | ||
| const debug_1 = __importDefault(require("debug")); | ||
| const logNotImplemented = (0, debug_1.default)("posix:not-implemented"); | ||
| const logCall = (0, debug_1.default)("posix:call"); | ||
| const logReturn = (0, debug_1.default)("posix:return"); | ||
| const logError = (0, debug_1.default)("posix:error"); | ||
| // For some reason this code | ||
| // import os; print(os.popen('ls').read()) | ||
| // hangs when run in **linux only** under python-wasm, but not python-wasm-debug, | ||
| // except if I set any random env variable here... and then it doesn't hang. | ||
| // This is weird. | ||
| process.env.__STUPID_HACK__ = ""; | ||
| function posix(context) { | ||
| const P = { | ||
| ...(0, epoll_1.default)(context), | ||
| ...(0, fork_exec_1.default)(context), | ||
| ...(0, netdb_1.default)(context), | ||
| ...(0, netif_1.default)(context), | ||
| ...(0, other_1.default)(context), | ||
| ...(0, sched_1.default)(context), | ||
| ...(0, signal_1.default)(context), | ||
| ...(0, socket_1.default)(context), | ||
| ...(0, spawn_1.default)(context), | ||
| ...(0, stat_1.default)(context), | ||
| ...(0, stdlib_1.default)(context), | ||
| ...(0, stdio_1.default)(context), | ||
| ...(0, time_1.default)(context), | ||
| ...(0, termios_1.default)(context), | ||
| ...(0, unistd_1.default)(context), | ||
| ...(0, wait_1.default)(context), | ||
| }; | ||
| const Q = {}; | ||
| let nativeErrnoToSymbol = {}; | ||
| if (context.posix.constants != null) { | ||
| for (const symbol in context.posix.constants) { | ||
| nativeErrnoToSymbol[context.posix.constants[symbol]] = symbol; | ||
| } | ||
| } | ||
| function setErrnoFromNative(nativeErrno, name, args) { | ||
| if (nativeErrno == 0 || isNaN(nativeErrno)) { | ||
| // TODO: could put a log or something in that name raised error with no code. | ||
| context.callFunction("setErrno", nativeErrno); | ||
| return; | ||
| } | ||
| // The error code comes from native posix, so we translate it to WASI first | ||
| const symbol = nativeErrnoToSymbol[nativeErrno]; | ||
| if (symbol != null) { | ||
| const wasiErrno = constants_2.default[symbol]; | ||
| if (wasiErrno != null) { | ||
| if (logError.enabled) { | ||
| logError({ name, nativeErrno, wasiErrno, symbol, args }); | ||
| } | ||
| context.callFunction("setErrno", wasiErrno); | ||
| return; | ||
| } | ||
| } | ||
| const mesg = symbol != null | ||
| ? `WARNING in posix '${name}': Unable to map nativeErrno ${nativeErrno}: add ${symbol} to WASM posix constants in @cowasm/kernel` | ||
| : `WARNING in posix '${name}': Unable to map nativeErrno ${nativeErrno}: add native symbol corresponding to errno=${nativeErrno} to the posix-node package`; | ||
| console.warn(mesg); | ||
| logNotImplemented(mesg); | ||
| } | ||
| // It's critical to ensure the directories of the host env is the same as | ||
| // the WASM env, if meaningful or possible. This only matters right now | ||
| // under node.js, but is really critical there. Thus we wrap *all* posix calls | ||
| // in this syncdir below. | ||
| // TODO: optimize. This seems dangerously expensive. | ||
| let syncdir; | ||
| if (context.posix.chdir != null) { | ||
| syncdir = () => { | ||
| // TODO: it is expected that this may fail, e.g., if we are using a sandbox filesystem | ||
| // deal with this in a better way. | ||
| try { | ||
| context.posix.chdir?.(context.getcwd()); | ||
| } | ||
| catch (_err) { } | ||
| }; | ||
| } | ||
| else { | ||
| syncdir = () => { }; | ||
| } | ||
| for (const name in P) { | ||
| Q[name] = (...args) => { | ||
| syncdir(); | ||
| try { | ||
| logCall(name, args); | ||
| const ret = P[name](...args); | ||
| logReturn(name, ret); | ||
| return ret; | ||
| } | ||
| catch (err) { | ||
| logError(name, err); | ||
| if (err.wasiErrno != null) { | ||
| context.callFunction("setErrno", err.wasiErrno); | ||
| } | ||
| else if (err.code != null) { | ||
| setErrnoFromNative(parseInt(err.code), name, args); | ||
| } | ||
| else { | ||
| // err.code not yet set (TODO), so we log and try heuristic. | ||
| // On error, for now -1 is returned, and errno should get set to some sort of error indicator | ||
| // TODO: how should we set errno? | ||
| // @ts-ignore -- this is just temporary while we sort out setting errno... | ||
| if (err.name == "NotImplementedError") { | ||
| // ENOSYS means "Function not implemented (POSIX.1-2001)." | ||
| context.callFunction("setErrno", constants_2.default.ENOSYS); | ||
| } | ||
| else { | ||
| console.trace(`WARNING: Posix library call to ${name} raised exception without error code. The raised error is '${err}'`); | ||
| logNotImplemented(`Posix call to ${name} raised exception without error code`, err); | ||
| } | ||
| } | ||
| return err.ret ?? -1; | ||
| } | ||
| }; | ||
| } | ||
| Q.init = () => { | ||
| (0, constants_1.initConstants)(context); | ||
| }; | ||
| return Q; | ||
| } | ||
| exports.default = posix; | ||
| //# sourceMappingURL=index.js.map |
| {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/wasm/posix/index.ts"],"names":[],"mappings":"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"} |
| export default function netdb({ memory, posix, callFunction, recv, send, free, }: { | ||
| memory: any; | ||
| posix: any; | ||
| callFunction: any; | ||
| recv: any; | ||
| send: any; | ||
| free: any; | ||
| }): any; | ||
| export declare function wasmToNativeFamily(posix: any, family: number): number; | ||
| export declare function nativeToWasmFamily(posix: any, family: number): number; | ||
| export declare function wasmToNativeSocktype(posix: any, socktype: number): number; | ||
| export declare function sendSockaddr(send: any, memory: any, ptr: any, sa_family: any, ai_addrlen: any, sa_data: any): number; |
| "use strict"; | ||
| /* | ||
| Functions from netdb. | ||
| These are all very hard to implement with node, without just writing a node extension | ||
| module which is what I'll likely have to do. | ||
| */ | ||
| var __importDefault = (this && this.__importDefault) || function (mod) { | ||
| return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
| }; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.sendSockaddr = exports.wasmToNativeSocktype = exports.nativeToWasmFamily = exports.wasmToNativeFamily = void 0; | ||
| const util_1 = require("./util"); | ||
| const constants_1 = __importDefault(require("./constants")); | ||
| function netdb({ memory, posix, callFunction, recv, send, free, }) { | ||
| const names = " getprotobyname getservbyname getservbyport getnameinfo"; | ||
| const netdb = {}; | ||
| for (const name of names.split(/\s+/)) { | ||
| netdb[name] = () => (0, util_1.notImplemented)(name); | ||
| } | ||
| function recvHints(hintsPtr) { | ||
| const view = new DataView(memory.buffer); | ||
| const flags = view.getUint32(hintsPtr, true); | ||
| hintsPtr += 4; | ||
| let family = wasmToNativeFamily(posix, view.getUint32(hintsPtr, true)); | ||
| hintsPtr += 4; | ||
| const socktype = wasmToNativeSocktype(posix, view.getUint32(hintsPtr, true)); | ||
| hintsPtr += 4; | ||
| const protocol = view.getUint32(hintsPtr, true); | ||
| return { | ||
| flags, | ||
| family, | ||
| socktype, | ||
| protocol, | ||
| }; | ||
| } | ||
| // this is null terminated. | ||
| function sendArrayOfStrings(v) { | ||
| const ptr = send.malloc(4 * (v.length + 1)); | ||
| if (ptr == 0) { | ||
| throw Error("out of memory"); | ||
| } | ||
| for (let i = 0; i < v.length; i++) { | ||
| const sPtr = send.string(v[i]); | ||
| send.pointer(ptr + 4 * i, sPtr); | ||
| } | ||
| send.pointer(ptr + 4 * v.length, 0); | ||
| return ptr; | ||
| } | ||
| function sendHostent(hostent) { | ||
| // Convert from native posix constant to musl-wasm constant for address type. | ||
| const h_addrtype = nativeToWasmFamily(posix, hostent.h_addrtype); | ||
| return callFunction("sendHostent", send.string(hostent.h_name), sendArrayOfStrings(hostent.h_aliases), h_addrtype, hostent.h_length, sendArrayOfStrings(hostent.h_addr_list), hostent.h_addr_list.length); | ||
| } | ||
| // struct hostent *gethostbyname(const char *name); | ||
| // struct hostent | ||
| // { | ||
| // char *h_name; /* Official domain name of host */ | ||
| // char **h_aliases; /* Null-terminated array of domain names */ | ||
| // int h_addrtype; /* Host address type (AF_INET) */ | ||
| // int h_length; /* Length of an address, in bytes */ | ||
| // char **h_addr_list; /* Null-terminated array of in_addr structs */ | ||
| // }; | ||
| // struct in_addr | ||
| // { | ||
| // unsigned int s_addr; /* Network byte order (big-endian) */ | ||
| // }; | ||
| netdb.gethostbyname = (namePtr) => { | ||
| try { | ||
| if (posix.gethostbyname == null) { | ||
| (0, util_1.notImplemented)("gethostbyaddr", 0); | ||
| } | ||
| const name = recv.string(namePtr); | ||
| const hostent = posix.gethostbyname(name); | ||
| return sendHostent(hostent); | ||
| } | ||
| catch (err) { | ||
| err.ret = 0; | ||
| throw err; | ||
| } | ||
| }; | ||
| // struct hostent *gethostbyaddr(const void *addr, | ||
| // socklen_t len, int type); | ||
| netdb.gethostbyaddr = (addrPtr, _len, type) => { | ||
| try { | ||
| if (posix.gethostbyaddr == null) { | ||
| (0, util_1.notImplemented)("gethostbyaddr", 0); | ||
| } | ||
| const addrStringPtr = callFunction("recvAddr", addrPtr, type); | ||
| if (addrStringPtr == 0) { | ||
| return 0; | ||
| } | ||
| const addrString = recv.string(addrStringPtr); | ||
| free(addrStringPtr); | ||
| const hostent = posix.gethostbyaddr(addrString); | ||
| return sendHostent(hostent); | ||
| } | ||
| catch (err) { | ||
| err.ret = 0; | ||
| throw err; | ||
| } | ||
| }; | ||
| /* int getaddrinfo(const char *restrict node, | ||
| const char *restrict service, | ||
| const struct addrinfo *restrict hints, | ||
| struct addrinfo **restrict res); | ||
| Since we are allocating this explicitly using malloc for the result, | ||
| it's critical to know precisely what this really is in 32-bit WebAssembly, | ||
| but nowhere else, which we due by grepping zig/lib/libc sources. | ||
| struct addrinfo { | ||
| int ai_flags; | ||
| int ai_family; | ||
| int ai_socktype; | ||
| int ai_protocol; | ||
| socklen_t ai_addrlen; | ||
| struct sockaddr *ai_addr; | ||
| char *ai_canonname; | ||
| struct addrinfo *ai_next; | ||
| } | ||
| typedef unsigned socklen_t; | ||
| struct sockaddr { | ||
| _Alignas(max_align_t) sa_family_t sa_family; | ||
| char sa_data[0]; | ||
| }; | ||
| typedef unsigned short sa_family_t; // unsigned short is 2 bytes | ||
| That "char sa_data[0]" is scary but OK, since just a pointer; think of it as a char*. | ||
| */ | ||
| netdb.getaddrinfo = (nodePtr, servicePtr, hintsPtr, resPtr) => { | ||
| if (posix.getaddrinfo == null) { | ||
| (0, util_1.notImplemented)("getaddrinfo"); | ||
| return -1; | ||
| } | ||
| const node = recv.string(nodePtr); | ||
| const service = recv.string(servicePtr); | ||
| const hints = recvHints(hintsPtr); | ||
| let addrinfoArray; | ||
| try { | ||
| addrinfoArray = posix.getaddrinfo(node, service, hints); | ||
| } | ||
| catch (err) { | ||
| if (err.code) { | ||
| // the exception has the error code, which should be returned. | ||
| return parseInt(err.code); | ||
| } | ||
| else { | ||
| // just let it prop | ||
| throw err; | ||
| } | ||
| } | ||
| let ai_next = 0; | ||
| let addrinfo = 0; | ||
| let n = addrinfoArray.length - 1; | ||
| while (n >= 0) { | ||
| const info = addrinfoArray[n]; | ||
| info.ai_socktype = nativeToWasmSocktype(posix, info.ai_socktype); | ||
| info.ai_family = info.sa_family = nativeToWasmFamily(posix, info.ai_family); | ||
| const ai_addr = sendSockaddr(send, memory, null, info.sa_family, info.ai_addrlen, info.sa_data); | ||
| if (!ai_addr) { | ||
| throw Error("error creating sockaddr"); | ||
| } | ||
| addrinfo = callFunction("sendAddrinfo", info.ai_flags, info.ai_family, info.ai_socktype, info.ai_protocol, info.ai_addrlen, ai_addr, info.ai_canonname != null ? send.string(info.ai_canonname) : 0, ai_next); | ||
| if (!addrinfo) { | ||
| throw Error("error creating addrinfo structure"); | ||
| } | ||
| ai_next = addrinfo; | ||
| n -= 1; | ||
| } | ||
| if (!addrinfo) { | ||
| throw Error("error creating addrinfo structure"); | ||
| } | ||
| send.pointer(resPtr, addrinfo); | ||
| return 0; | ||
| }; | ||
| // use a cache to only leak memory once per error code. | ||
| const gai_strerror_cache = {}; | ||
| netdb.gai_strerror = (errcode) => { | ||
| if (gai_strerror_cache[errcode] != null) { | ||
| return gai_strerror_cache[errcode]; | ||
| } | ||
| const strPtr = send.string(posix.gai_strerror?.(errcode) ?? "Unknown error"); | ||
| gai_strerror_cache[errcode] = strPtr; | ||
| return strPtr; | ||
| }; | ||
| const hstrerror_cache = {}; | ||
| netdb.hstrerror = (errcode) => { | ||
| if (hstrerror_cache[errcode] != null) { | ||
| return hstrerror_cache[errcode]; | ||
| } | ||
| const strPtr = send.string(posix.hstrerror?.(errcode) ?? "Unknown error"); | ||
| hstrerror_cache[errcode] = strPtr; | ||
| return strPtr; | ||
| }; | ||
| let h_errno_ptr = null; | ||
| netdb.__h_errno_location = () => { | ||
| /* After reading sources, this __h_errno_location returns the memory | ||
| location of an i32 where an error number is stored in memory. See: | ||
| int h_errno; | ||
| int *__h_errno_location(void) { | ||
| if (!__pthread_self()->stack) return &h_errno; } | ||
| Elsewhere, h_errno is #defined to calling the above and deref. | ||
| So for now we define such an i32 and set it to 0. This is a lot | ||
| better than returning 0 (the stub) and causing a segfault! | ||
| TODO: in the future, we could somehow mirror the error code from the | ||
| native side...? | ||
| */ | ||
| if (h_errno_ptr == null) { | ||
| h_errno_ptr = send.malloc(4); // an i32 | ||
| send.i32(h_errno_ptr, 0); // set it to 0. | ||
| } | ||
| if (h_errno_ptr == null) | ||
| throw Error("bug"); | ||
| return h_errno_ptr; | ||
| }; | ||
| return netdb; | ||
| } | ||
| exports.default = netdb; | ||
| function wasmToNativeFamily(posix, family) { | ||
| if (family == 0) | ||
| return family; // default no flag given | ||
| // convert from musl-wasm AF_INET to native AF_INET | ||
| // (are totally different, and different for each native platform!). | ||
| if (family == constants_1.default.AF_INET) { | ||
| return posix.constants.AF_INET; | ||
| } | ||
| else if (family == constants_1.default.AF_INET6) { | ||
| return posix.constants.AF_INET6; | ||
| } | ||
| else { | ||
| throw Error(`unsupported WASM address family: ${family}`); | ||
| } | ||
| } | ||
| exports.wasmToNativeFamily = wasmToNativeFamily; | ||
| function nativeToWasmFamily(posix, family) { | ||
| if (family == 0) | ||
| return family; // default no flag given | ||
| if (family == posix.constants.AF_INET) { | ||
| return constants_1.default.AF_INET; | ||
| } | ||
| else if (family == posix.constants.AF_INET6) { | ||
| return constants_1.default.AF_INET6; | ||
| } | ||
| else { | ||
| throw Error(`unsupported native address family: ${family}`); | ||
| } | ||
| } | ||
| exports.nativeToWasmFamily = nativeToWasmFamily; | ||
| // multiple socktypes can be |d together. E.g., Python does this in the socketmodule.c module | ||
| // where they do "type | SOCK_CLOEXEC". | ||
| function wasmToNativeSocktype(posix, socktype) { | ||
| if (!socktype) | ||
| return socktype; | ||
| let nativeSocktype = 0; | ||
| for (const name in constants_1.default) { | ||
| if (name.startsWith("SOCK") && constants_1.default[name] & socktype) { | ||
| if (posix.constants[name] == null) { | ||
| const err = `We need the constant ${name} to be defined in the posix-node module.`; | ||
| console.warn(err); | ||
| throw Error(err); | ||
| } | ||
| nativeSocktype |= posix.constants[name]; | ||
| socktype &= ~constants_1.default[name]; | ||
| } | ||
| } | ||
| if (socktype != 0) { | ||
| const err = `Unable to convert remainging socktype ${socktype} to native. Make sure all SOCK* constants are defined.`; | ||
| console.warn(err); | ||
| throw Error(err); | ||
| } | ||
| return nativeSocktype; | ||
| } | ||
| exports.wasmToNativeSocktype = wasmToNativeSocktype; | ||
| function nativeToWasmSocktype(posix, socktype) { | ||
| if (!socktype) | ||
| return socktype; | ||
| let wasmSocktype = 0; | ||
| for (const name in posix.constants) { | ||
| if (name.startsWith("SOCK") && posix.constants[name] & socktype) { | ||
| if (constants_1.default[name] == null) { | ||
| const err = `We need the constant ${name} to be defined in the posix-node module.`; | ||
| console.warn(err); | ||
| throw Error(err); | ||
| } | ||
| wasmSocktype |= constants_1.default[name]; | ||
| socktype &= ~posix.constants[name]; | ||
| } | ||
| } | ||
| if (socktype != 0) { | ||
| const err = `Unable to convert remainging socktype ${socktype} to native. Make sure all SOCK* posix.constants are defined.`; | ||
| console.warn(err); | ||
| throw Error(err); | ||
| } | ||
| return wasmSocktype; | ||
| } | ||
| // This can't properly be done using zig, since struct sockaddr | ||
| // intensely abuses the C data types... | ||
| function sendSockaddr(send, memory, ptr, sa_family, ai_addrlen, sa_data) { | ||
| if (ptr == null) { | ||
| ptr = send.malloc(2 + ai_addrlen); | ||
| } | ||
| const view = new DataView(memory.buffer); | ||
| view.setUint16(ptr, sa_family, true); | ||
| for (let i = 0; i < ai_addrlen; i++) { | ||
| view.setUint8(ptr + 2 + i, sa_data[i]); | ||
| } | ||
| return ptr; | ||
| } | ||
| exports.sendSockaddr = sendSockaddr; | ||
| //# sourceMappingURL=netdb.js.map |
| {"version":3,"file":"netdb.js","sourceRoot":"","sources":["../../../src/wasm/posix/netdb.ts"],"names":[],"mappings":"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"} |
| export default function netif({ posix, recv, send, callFunction }: { | ||
| posix: any; | ||
| recv: any; | ||
| send: any; | ||
| callFunction: any; | ||
| }): { | ||
| if_indextoname: (ifindex: number, ifnamePtr: number) => number; | ||
| if_nametoindex: (ifnamePtr: number) => number; | ||
| if_nameindex: () => number; | ||
| if_freenameindex: (ptr: any) => void; | ||
| }; |
| "use strict"; | ||
| /* | ||
| Functions from net/if.h | ||
| NOTE: node.js has require('os').networkInterfaces(), but it is not equivalent | ||
| to the system calls in net/if.h. E.g., on my mac if_indextoname(2) is "gif0", | ||
| but "gif0" isn't in require('os').networkInterfaces(). This is because | ||
| networkInterface "Returns an object containing network interfaces that | ||
| have been assigned a network address." and gif0 hasn't been. | ||
| */ | ||
| var __importDefault = (this && this.__importDefault) || function (mod) { | ||
| return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
| }; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| const util_1 = require("./util"); | ||
| const constants_1 = __importDefault(require("./constants")); | ||
| function netif({ posix, recv, send, callFunction }) { | ||
| return { | ||
| // char *if_indextoname(unsigned int ifindex, char *ifname); | ||
| if_indextoname: (ifindex, ifnamePtr) => { | ||
| const { if_indextoname } = posix; | ||
| if (if_indextoname == null) { | ||
| (0, util_1.notImplemented)("if_indextoname"); | ||
| } | ||
| let ifname; | ||
| try { | ||
| ifname = if_indextoname(ifindex); | ||
| } | ||
| catch (_err) { | ||
| return 0; | ||
| } | ||
| send.string(ifname, { | ||
| ptr: ifnamePtr, | ||
| len: constants_1.default.IFNAMSIZ, | ||
| }); | ||
| return ifnamePtr; | ||
| }, | ||
| // unsigned int if_nametoindex(const char *ifname); | ||
| if_nametoindex: (ifnamePtr) => { | ||
| const { if_nametoindex } = posix; | ||
| if (if_nametoindex == null) { | ||
| (0, util_1.notImplemented)("if_nametoindex"); | ||
| } | ||
| const ifname = recv.string(ifnamePtr); | ||
| try { | ||
| return if_nametoindex(ifname); | ||
| } | ||
| catch (_err) { | ||
| return 0; | ||
| } | ||
| }, | ||
| if_nameindex: () => { | ||
| const { if_nameindex } = posix; | ||
| try { | ||
| if (if_nameindex == null) { | ||
| const ptr = callFunction("createNameIndexArray", 0); | ||
| if (ptr == 0) { | ||
| throw Error("out of memory"); | ||
| } | ||
| return ptr; | ||
| } | ||
| const ni = if_nameindex(); | ||
| const ptr = callFunction("createNameIndexArray", ni.length); | ||
| if (ptr == 0) { | ||
| throw Error("out of memory"); | ||
| } | ||
| for (let i = 0; i < ni.length; i++) { | ||
| callFunction("setNameIndexElement", ptr, i, ni[i][0], send.string(ni[i][1])); | ||
| } | ||
| return ptr; | ||
| } | ||
| catch (err) { | ||
| // ret = 0 since pointer and null pointer indicates error. | ||
| err.ret = 0; | ||
| throw err; | ||
| } | ||
| }, | ||
| if_freenameindex: (ptr) => { | ||
| callFunction("freeNameIndexArray", ptr); | ||
| }, | ||
| }; | ||
| } | ||
| exports.default = netif; | ||
| //# sourceMappingURL=netif.js.map |
| {"version":3,"file":"netif.js","sourceRoot":"","sources":["../../../src/wasm/posix/netif.ts"],"names":[],"mappings":";AAAA;;;;;;;;EAQE;;;;;AAEF,iCAAwC;AACxC,4DAAoC;AAEpC,SAAwB,KAAK,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,YAAY,EAAE;IAC/D,OAAO;QACL,4DAA4D;QAC5D,cAAc,EAAE,CAAC,OAAe,EAAE,SAAiB,EAAU,EAAE;YAC7D,MAAM,EAAE,cAAc,EAAE,GAAG,KAAK,CAAC;YACjC,IAAI,cAAc,IAAI,IAAI,EAAE;gBAC1B,IAAA,qBAAc,EAAC,gBAAgB,CAAC,CAAC;aAClC;YACD,IAAI,MAAM,CAAC;YACX,IAAI;gBACF,MAAM,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;aAClC;YAAC,OAAO,IAAI,EAAE;gBACb,OAAO,CAAC,CAAC;aACV;YACD,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE;gBAClB,GAAG,EAAE,SAAS;gBACd,GAAG,EAAE,mBAAS,CAAC,QAAQ;aACxB,CAAC,CAAC;YACH,OAAO,SAAS,CAAC;QACnB,CAAC;QAED,mDAAmD;QACnD,cAAc,EAAE,CAAC,SAAiB,EAAU,EAAE;YAC5C,MAAM,EAAE,cAAc,EAAE,GAAG,KAAK,CAAC;YACjC,IAAI,cAAc,IAAI,IAAI,EAAE;gBAC1B,IAAA,qBAAc,EAAC,gBAAgB,CAAC,CAAC;aAClC;YACD,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;YACtC,IAAI;gBACF,OAAO,cAAc,CAAC,MAAM,CAAC,CAAC;aAC/B;YAAC,OAAO,IAAI,EAAE;gBACb,OAAO,CAAC,CAAC;aACV;QACH,CAAC;QAED,YAAY,EAAE,GAAW,EAAE;YACzB,MAAM,EAAE,YAAY,EAAE,GAAG,KAAK,CAAC;YAC/B,IAAI;gBACF,IAAI,YAAY,IAAI,IAAI,EAAE;oBACxB,MAAM,GAAG,GAAG,YAAY,CAAC,sBAAsB,EAAE,CAAC,CAAC,CAAC;oBACpD,IAAI,GAAG,IAAI,CAAC,EAAE;wBACZ,MAAM,KAAK,CAAC,eAAe,CAAC,CAAC;qBAC9B;oBACD,OAAO,GAAG,CAAC;iBACZ;gBACD,MAAM,EAAE,GAAG,YAAY,EAAE,CAAC;gBAC1B,MAAM,GAAG,GAAG,YAAY,CAAC,sBAAsB,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC;gBAC5D,IAAI,GAAG,IAAI,CAAC,EAAE;oBACZ,MAAM,KAAK,CAAC,eAAe,CAAC,CAAC;iBAC9B;gBACD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;oBAClC,YAAY,CACV,qBAAqB,EACrB,GAAG,EACH,CAAC,EACD,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EACR,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CACtB,CAAC;iBACH;gBACD,OAAO,GAAG,CAAC;aACZ;YAAC,OAAO,GAAG,EAAE;gBACZ,0DAA0D;gBAC1D,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC;gBACZ,MAAM,GAAG,CAAC;aACX;QACH,CAAC;QAED,gBAAgB,EAAE,CAAC,GAAG,EAAQ,EAAE;YAC9B,YAAY,CAAC,oBAAoB,EAAE,GAAG,CAAC,CAAC;QAC1C,CAAC;KACF,CAAC;AACJ,CAAC;AAvED,wBAuEC"} |
| export default function other(context: any): { | ||
| syslog: () => void; | ||
| login_tty: (fd: number) => number; | ||
| statvfs: (pathPtr: string, bufPtr: number) => number; | ||
| fstatvfs: (fd: number, bufPtr: number) => number; | ||
| ctermid: (ptr?: number) => number; | ||
| getpwnam_r: (_namePtr: number, _passwdPtr: number, _bufferPtr: number, _bufsize: number, result_ptr_ptr: number) => number; | ||
| getpwuid: () => number; | ||
| getpwuid_r: (_uid: number, _passwdPtr: number, _bufferPtr: number, _bufsize: number, result_ptr_ptr: number) => number; | ||
| openpty: () => void; | ||
| msync: () => void; | ||
| madvise: () => void; | ||
| mremap: () => void; | ||
| tmpfile: () => void; | ||
| openlog: () => void; | ||
| tcflush: () => void; | ||
| getpwnam: () => number; | ||
| getrlimit: () => void; | ||
| setrlimit: () => void; | ||
| user_from_uid: (uid: number, nouser?: number) => number; | ||
| group_from_gid: (gid: number, nogroup?: number) => number; | ||
| getrusage: (_who: number, _r_usage_ptr: number) => number; | ||
| _Znwm: () => void; | ||
| _ZdlPv: () => void; | ||
| __cxa_throw: () => void; | ||
| __cxa_allocate_exception: () => void; | ||
| _ZNSt20bad_array_new_lengthC1Ev: () => void; | ||
| _ZNSt20bad_array_new_lengthD1Ev: () => void; | ||
| _ZTISt20bad_array_new_length: () => void; | ||
| ngettext: () => void; | ||
| dngettext: () => void; | ||
| dcngettext: () => void; | ||
| }; |
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| const util_1 = require("./util"); | ||
| function other(context) { | ||
| const { callFunction, posix, recv, send, wasi } = context; | ||
| context.state.user_from_uid_cache = {}; | ||
| function sendStatvfs(bufPtr, x) { | ||
| callFunction("set_statvfs", bufPtr, x.f_bsize, x.f_frsize, BigInt(x.f_blocks), BigInt(x.f_bfree), BigInt(x.f_bavail), BigInt(x.f_files), BigInt(x.f_ffree), BigInt(x.f_favail), x.f_fsid, x.f_flag, x.f_namemax); | ||
| } | ||
| function real_fd(virtual_fd) { | ||
| const data = wasi.FD_MAP.get(virtual_fd); | ||
| if (data == null) { | ||
| return -1; | ||
| } | ||
| return data.real; | ||
| } | ||
| const lib = { | ||
| syslog: () => { | ||
| (0, util_1.notImplemented)("syslog"); | ||
| }, | ||
| login_tty: (fd) => { | ||
| if (posix.login_tty == null) { | ||
| (0, util_1.notImplemented)("login_tty"); | ||
| } | ||
| posix.login_tty(real_fd(fd)); | ||
| return 0; | ||
| }, | ||
| // TODO: worry about virtual filesystem that WASI provides, | ||
| // versus this just being the straight real one?! | ||
| // int statvfs(const char *restrict path, struct statvfs *restrict buf); | ||
| statvfs: (pathPtr, bufPtr) => { | ||
| if (posix.statvfs == null) { | ||
| (0, util_1.notImplemented)("statvfs"); | ||
| } | ||
| const path = recv.string(pathPtr); | ||
| sendStatvfs(bufPtr, posix.statvfs(path)); | ||
| return 0; | ||
| }, | ||
| // int fstatvfs(int fd, struct statvfs *buf); | ||
| fstatvfs: (fd, bufPtr) => { | ||
| if (posix.fstatvfs == null) { | ||
| (0, util_1.notImplemented)("fstatvfs"); | ||
| } | ||
| sendStatvfs(bufPtr, posix.fstatvfs(real_fd(fd))); | ||
| return 0; | ||
| }, | ||
| ctermid: (ptr) => { | ||
| if (posix.ctermid == null) { | ||
| (0, util_1.notImplemented)("ctermid"); | ||
| } | ||
| if (ptr) { | ||
| const s = posix.ctermid(); | ||
| send.string(s, { ptr, len: s.length + 1 }); | ||
| return ptr; | ||
| } | ||
| if (context.state.ctermidPtr) { | ||
| return context.state.ctermidPtr; | ||
| } | ||
| const s = posix.ctermid(); | ||
| return (context.state.ctermidPtr = send.string(s)); | ||
| }, | ||
| // password stuff | ||
| // int getpwnam_r(const char *name, struct passwd *pwd, char *buffer, size_t bufsize, struct passwd **result); | ||
| getpwnam_r: (_namePtr, _passwdPtr, _bufferPtr, _bufsize, result_ptr_ptr) => { | ||
| // this means "not found". | ||
| send.pointer(result_ptr_ptr, 0); | ||
| return 0; | ||
| }, | ||
| // struct passwd *getpwuid(uid_t uid); | ||
| getpwuid: () => { | ||
| // not found | ||
| return 0; | ||
| }, | ||
| // int getpwuid_r(uid_t uid, struct passwd *pwd, char *buffer, | ||
| // size_t bufsize, struct passwd **result); | ||
| getpwuid_r: (_uid, _passwdPtr, _bufferPtr, _bufsize, result_ptr_ptr) => { | ||
| send.pointer(result_ptr_ptr, 0); | ||
| return 0; | ||
| }, | ||
| openpty: () => { | ||
| // TOOD: plan to do this inspired by https://github.com/microsoft/node-pty, either | ||
| // using that or just a little inspired by it to add to posix-node. | ||
| (0, util_1.notImplemented)("openpty"); | ||
| }, | ||
| msync: () => { | ||
| // This is part of mmap. | ||
| (0, util_1.notImplemented)("msync"); | ||
| }, | ||
| madvise: () => { | ||
| (0, util_1.notImplemented)("madvise"); | ||
| }, | ||
| mremap: () => { | ||
| (0, util_1.notImplemented)("mremap"); | ||
| }, | ||
| // The curses cpython module wants this: | ||
| // FILE *tmpfile(void); | ||
| /* ~/test/tmpfile$ more a.c | ||
| #include<stdio.h> | ||
| int main() { | ||
| FILE* f = tmpfile(); | ||
| printf("f = %p\n", f); | ||
| } | ||
| ~/test/tmpfile$ zig cc -target wasm32-wasi ./a.c | ||
| ./a.c:3:14: warning: 'tmpfile' is deprecated: tmpfile is not defined on WASI [-Wdeprecated-declarations] | ||
| */ | ||
| tmpfile: () => { | ||
| (0, util_1.notImplemented)("tmpfile"); | ||
| }, | ||
| openlog: () => { | ||
| (0, util_1.notImplemented)("openlog"); | ||
| }, | ||
| // curses also wants this: | ||
| // int tcflush(int fildes, int action); | ||
| tcflush: () => { | ||
| (0, util_1.notImplemented)("tcflush"); | ||
| }, | ||
| // struct passwd *getpwnam(const char *login); | ||
| getpwnam: () => { | ||
| console.log("STUB: getpwnam"); | ||
| // return 0 indicates failure | ||
| return 0; | ||
| }, | ||
| // int getrlimit(int resource, struct rlimit *rlp); | ||
| getrlimit: () => { | ||
| (0, util_1.notImplemented)("getrlimit"); | ||
| }, | ||
| // int setrlimit(int resource, const struct rlimit *rlp); | ||
| setrlimit: () => { | ||
| (0, util_1.notImplemented)("setrlimit"); | ||
| }, | ||
| // numpy wants this thing that can't exist in wasm: | ||
| // int backtrace(void** array, int size); | ||
| // Commenting this out and instead patching numpy to not try to use this, since we | ||
| // have to do that anyways to get it to build with clang15. | ||
| // backtrace: () => { | ||
| // notImplemented("backgrace"); | ||
| // }, | ||
| // These are for coreutils, and we come up with a WebAssembly version, | ||
| // which is the documented fallback. | ||
| // char * user_from_uid(uid_t uid, int nouser); | ||
| // char * group_from_gid(gid_t gid, int nogroup); | ||
| // TODO: for speed this would be better at the C level. | ||
| user_from_uid: (uid, nouser = 0) => { | ||
| if (nouser) { | ||
| return 0; | ||
| } | ||
| // cache the pointers for speed and to reduce memory leaks | ||
| if (context.state.user_from_uid_cache[uid]) { | ||
| return context.state.user_from_uid_cache[uid]; | ||
| } | ||
| return (context.state.user_from_uid_cache[uid] = send.string(`${uid}`)); | ||
| }, | ||
| group_from_gid: (gid, nogroup = 0) => { | ||
| return lib.user_from_uid(gid, nogroup); | ||
| }, | ||
| // TODO -- see how this is used in code, or maybe make it | ||
| // do something like "#define getrusage(A,B) memset(B,0,sizeof(*B))" | ||
| // to make everything 0, as a stub. | ||
| // int getrusage(int who, struct rusage *r_usage); | ||
| getrusage: (_who, _r_usage_ptr) => { | ||
| (0, util_1.notImplemented)("getrusage"); | ||
| return 0; | ||
| }, | ||
| // C++ stuff we don't support: | ||
| _Znwm: () => { | ||
| // operator new | ||
| (0, util_1.notImplemented)("_Znwm"); | ||
| }, | ||
| _ZdlPv: () => { | ||
| // operator delete | ||
| (0, util_1.notImplemented)("_ZdlPv"); | ||
| }, | ||
| __cxa_throw: () => { | ||
| (0, util_1.notImplemented)("__cxa_throw"); | ||
| }, | ||
| // exception | ||
| __cxa_allocate_exception: () => { | ||
| (0, util_1.notImplemented)("__cxa_allocate_exception"); | ||
| }, | ||
| _ZNSt20bad_array_new_lengthC1Ev: () => { | ||
| (0, util_1.notImplemented)("_ZNSt20bad_array_new_lengthC1Ev"); | ||
| }, | ||
| _ZNSt20bad_array_new_lengthD1Ev: () => { | ||
| (0, util_1.notImplemented)("_ZNSt20bad_array_new_lengthD1Ev"); | ||
| }, | ||
| _ZTISt20bad_array_new_length: () => { | ||
| (0, util_1.notImplemented)("_ZTISt20bad_array_new_length"); | ||
| }, | ||
| ngettext: () => { | ||
| (0, util_1.notImplemented)("ngettext"); | ||
| }, | ||
| dngettext: () => { | ||
| (0, util_1.notImplemented)("dngettext"); | ||
| }, | ||
| dcngettext: () => { | ||
| (0, util_1.notImplemented)("dcngettext"); | ||
| }, | ||
| }; | ||
| return lib; | ||
| } | ||
| exports.default = other; | ||
| //# sourceMappingURL=other.js.map |
| {"version":3,"file":"other.js","sourceRoot":"","sources":["../../../src/wasm/posix/other.ts"],"names":[],"mappings":"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"} |
| export default function sched({}: {}): any; |
| "use strict"; | ||
| /* | ||
| Functions from sched.h. | ||
| These are all very hard to implement with node, without just writing a node extension | ||
| module which is what I'll likely have to do... | ||
| */ | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| const util_1 = require("./util"); | ||
| function sched({}) { | ||
| const names = "sched_get_priority_max sched_get_priority_min sched_getparam sched_getscheduler sched_rr_get_interval sched_setparam sched_setscheduler"; | ||
| const sched = {}; | ||
| for (const name of names.split(/\s+/)) { | ||
| sched[name] = () => (0, util_1.notImplemented)(name); | ||
| } | ||
| return sched; | ||
| } | ||
| exports.default = sched; | ||
| //# sourceMappingURL=sched.js.map |
| {"version":3,"file":"sched.js","sourceRoot":"","sources":["../../../src/wasm/posix/sched.ts"],"names":[],"mappings":";AAAA;;;;;EAKE;;AAEF,iCAAwC;AAExC,SAAwB,KAAK,CAAC,EAAE;IAC9B,MAAM,KAAK,GACT,yIAAyI,CAAC;IAC5I,MAAM,KAAK,GAAQ,EAAE,CAAC;IACtB,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE;QACrC,KAAK,CAAC,IAAI,CAAC,GAAG,GAAG,EAAE,CAAC,IAAA,qBAAc,EAAC,IAAI,CAAC,CAAC;KAC1C;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AARD,wBAQC"} |
| export declare function getSignalSet(setPtr: number): Set<number>; | ||
| export declare function setSignalSet(setPtr: number, value: Set<number>): void; | ||
| export default function signal({ process }: { | ||
| process: any; | ||
| }): { | ||
| kill: (pid: number, signal: number) => number; | ||
| raise: (sig: number) => number; | ||
| killpg: (pid: number, signal: number) => number; | ||
| sigemptyset: (setPtr: number) => number; | ||
| sigfillset: (setPtr: number) => number; | ||
| sigaddset: (setPtr: number, signum: number) => number; | ||
| sigdelset: (setPtr: number, signum: number) => number; | ||
| sigismember: (setPtr: number, signum: number) => number; | ||
| sigprocmask: (how: number, setPtr: number, oldsetPtr: number) => number; | ||
| sigsuspend: () => void; | ||
| }; |
| "use strict"; | ||
| /* | ||
| NOTES: | ||
| A key fact is that zig defines sigset_t to be "unsigned char", instead of a much | ||
| more useful larger struct. Thus we only have 8 bits, so can't really represent | ||
| all the signals. So instead we just use the pointer and a higher level Javascript | ||
| Set data structure. Since any nontrivial signal functionality has to be at the | ||
| Javascript level anyways, this is probably just fine. | ||
| They say this in the zig sources, and just worrying about the pointer makes things | ||
| agnostic. | ||
| // TODO: This is just a placeholder for now. Keep this in sync with musl. | ||
| typedef unsigned char sigset_t; | ||
| NOTE: below we implement more than just what's needed for Python. This may be helpful | ||
| for other libraries. | ||
| */ | ||
| var __importDefault = (this && this.__importDefault) || function (mod) { | ||
| return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
| }; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.setSignalSet = exports.getSignalSet = void 0; | ||
| const constants_1 = __importDefault(require("./constants")); | ||
| const util_1 = require("./util"); | ||
| const signal_t = {}; | ||
| function getSignalSet(setPtr) { | ||
| if (signal_t[setPtr] == null) { | ||
| signal_t[setPtr] = new Set(); | ||
| } | ||
| return signal_t[setPtr]; | ||
| } | ||
| exports.getSignalSet = getSignalSet; | ||
| function setSignalSet(setPtr, value) { | ||
| signal_t[setPtr] = value; | ||
| } | ||
| exports.setSignalSet = setSignalSet; | ||
| // The global signal mask for this process. | ||
| const signalMask = new Set(); | ||
| function setSignalSetToMask(setPtr) { | ||
| const set = getSignalSet(setPtr); | ||
| set.clear(); | ||
| for (const x of signalMask) { | ||
| set.add(x); | ||
| } | ||
| } | ||
| function signal({ process }) { | ||
| const signal = { | ||
| // int kill(pid_t pid, int sig); | ||
| kill: (pid, signal) => { | ||
| if (process.kill == null) | ||
| return 0; | ||
| process.kill(pid, signal); | ||
| return 0; | ||
| }, | ||
| // NOTE: this is the single threaded version! | ||
| // int raise(int sig); | ||
| // according to man is same as "kill(getpid(), sig);" for single thread. | ||
| raise: (sig) => { | ||
| return signal.kill(process.pid ?? 1, sig); | ||
| }, | ||
| // int killpg(int pgrp, int sig); | ||
| killpg: (pid, signal) => { | ||
| if (process.kill == null) | ||
| return 0; | ||
| process.kill(-pid, signal); | ||
| return 0; | ||
| }, | ||
| // int sigemptyset(sigset_t *set); | ||
| sigemptyset: (setPtr) => { | ||
| getSignalSet(setPtr).clear(); | ||
| return 0; | ||
| }, | ||
| // int sigfillset(sigset_t *set); | ||
| sigfillset: (setPtr) => { | ||
| const set = getSignalSet(setPtr); | ||
| for (let sig = 1; sig <= 31; sig++) { | ||
| set.add(sig); | ||
| } | ||
| return 0; | ||
| }, | ||
| // int sigfillset(sigset_t *set); | ||
| // int sigaddset(sigset_t *set, int signum); | ||
| sigaddset: (setPtr, signum) => { | ||
| getSignalSet(setPtr).add(signum); | ||
| return 0; | ||
| }, | ||
| // int sigdelset(sigset_t *set, int signum); | ||
| sigdelset: (setPtr, signum) => { | ||
| getSignalSet(setPtr).delete(signum); | ||
| return 0; | ||
| }, | ||
| // int sigismember(const sigset_t *set, int signum); | ||
| sigismember: (setPtr, signum) => { | ||
| if (getSignalSet(setPtr).has(signum)) { | ||
| return 1; | ||
| } | ||
| else { | ||
| return 0; | ||
| } | ||
| }, | ||
| // int sigprocmask(int how, const sigset_t *set, sigset_t *oldset); | ||
| // "sigprocmask() is used to fetch and/or change the signal mask of | ||
| // the calling thread. The signal mask is the set of signals whose | ||
| // delivery is currently blocked for the caller." | ||
| sigprocmask: (how, setPtr, oldsetPtr) => { | ||
| try { | ||
| if (!setPtr) | ||
| return 0; | ||
| const set = getSignalSet(setPtr); | ||
| switch (how) { | ||
| case constants_1.default.SIG_BLOCK: | ||
| for (const s of set) { | ||
| signalMask.add(s); | ||
| } | ||
| return 0; | ||
| case constants_1.default.SIG_UNBLOCK: | ||
| for (const s of set) { | ||
| signalMask.delete(s); | ||
| } | ||
| return 0; | ||
| case constants_1.default.SIG_SETMASK: | ||
| signalMask.clear(); | ||
| for (const s of set) { | ||
| signalMask.add(s); | ||
| } | ||
| return 0; | ||
| default: | ||
| throw Error(`sigprocmask - invalid how=${how}`); | ||
| } | ||
| } | ||
| finally { | ||
| if (oldsetPtr) { | ||
| setSignalSetToMask(oldsetPtr); | ||
| } | ||
| } | ||
| }, | ||
| // int sigsuspend(const sigset_t *sigmask); | ||
| sigsuspend: () => { | ||
| (0, util_1.notImplemented)("sigsuspend"); | ||
| }, | ||
| }; | ||
| // for single threaded programs, these are the same: | ||
| // @ts-ignore | ||
| signal.pthread_sigmask = signal.sigprocmask; | ||
| return signal; | ||
| } | ||
| exports.default = signal; | ||
| //# sourceMappingURL=signal.js.map |
| {"version":3,"file":"signal.js","sourceRoot":"","sources":["../../../src/wasm/posix/signal.ts"],"names":[],"mappings":"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"} |
| export default function socket({ callFunction, posix, recv, wasi, send, memory, }: { | ||
| callFunction: any; | ||
| posix: any; | ||
| recv: any; | ||
| wasi: any; | ||
| send: any; | ||
| memory: any; | ||
| }): { | ||
| socket(family: number, socktype: number, protocol: number): number; | ||
| bind(socket: number, sockaddrPtr: number, address_len: number): number; | ||
| connect(socket: number, sockaddrPtr: number, address_len: number): number; | ||
| getsockname(socket: number, sockaddrPtr: number, addressLenPtr: number): number; | ||
| getpeername(socket: number, sockaddrPtr: number, addressLenPtr: number): number; | ||
| recv(socket: number, bufPtr: number, length: number, flags: number): number; | ||
| recvfrom(socket: number, bufPtr: number, length: number, flags: number, sockaddrPtr: number, sockaddrLenPtr: number): number; | ||
| send(socket: number, bufPtr: number, length: number, flags: number): number; | ||
| sendto(socket: number, bufPtr: number, length: number, flags: number, addressPtr: number, addressLen: number): number; | ||
| shutdown(socket: number, how: number): number; | ||
| listen(socket: number, backlog: number): number; | ||
| accept(socket: number, sockaddrPtr: number, socklenPtr: number): number; | ||
| getsockopt(socket: number, level: number, option_name: number, option_value_ptr: number, option_len_ptr: number): number; | ||
| setsockopt(socket: number, level: number, option_name: number, option_value_ptr: number, option_len: number): number; | ||
| pollSocket(socket: number, type: "read" | "write", timeout_ms: number): number; | ||
| }; |
| "use strict"; | ||
| /* | ||
| This is an implementation of POSIX Sockets. | ||
| Of course, much of the code for this is written in zig in the posix-node package | ||
| in this file packages/posix-node/src/socket.zig | ||
| RELATED WORK: I wrote most of this, then searched and found it is solving | ||
| a similar problem to emscripten's "Full POSIX Sockets over WebSocket Proxy Server": | ||
| - https://emscripten.org/docs/porting/networking.html#full-posix-sockets-over-websocket-proxy-server | ||
| - https://github.com/emscripten-core/emscripten/tree/main/tools/websocket_to_posix_proxy | ||
| - https://github.com/emscripten-core/emscripten/pull/7670 (interesting discussion) | ||
| Of course, the architecture of the CoWasm solution is massively different. | ||
| It looks like Emscripten's is a full multithreaded standalone C++ program | ||
| for proxying many network connections from (presumably) many clients. | ||
| In contrast, CoWasm's solution is partly written in zig as a node extension | ||
| and integrated with Javascript. It can be used standalone with other Javascript | ||
| projects having nothing to do with cowasm, by using the posix-node package, | ||
| so there is potential for more community feedback and development. | ||
| We would likely have to have one Javascript worker/thread per client, but | ||
| this could be integrated with accessing other resources on the server. | ||
| It's also nice that CoWasm also can operate with exactly the same code | ||
| in a mode that doesn't involving proxying to a backend server, with | ||
| everything in the same process (which is all that is implemented here | ||
| right now!), since that should be fast and good for automated testing. | ||
| */ | ||
| var __importDefault = (this && this.__importDefault) || function (mod) { | ||
| return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
| }; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| const errno_1 = __importDefault(require("./errno")); | ||
| const netdb_1 = require("./netdb"); | ||
| const constants_1 = __importDefault(require("./constants")); | ||
| const wasi_js_1 = require("wasi-js"); | ||
| const debug_1 = __importDefault(require("debug")); | ||
| const log = (0, debug_1.default)("posix:socket"); | ||
| function socket({ callFunction, posix, recv, wasi, send, memory, }) { | ||
| function sendNativeSockaddr(sockaddr, ptr) { | ||
| (0, netdb_1.sendSockaddr)(send, memory, ptr, (0, netdb_1.nativeToWasmFamily)(posix, sockaddr.sa_family), sockaddr.sa_len, sockaddr.sa_data); | ||
| } | ||
| function getSockaddr(sockaddrPtr, address_len) { | ||
| const sa_family = (0, netdb_1.wasmToNativeFamily)(posix, callFunction("recv_sockaddr_sa_family", sockaddrPtr)); | ||
| const sa_len = address_len - 2; | ||
| const sa_data = recv.buffer(callFunction("recv_sockaddr_sa_data", sockaddrPtr), sa_len); | ||
| for (let i = sa_len; i < sa_len; i++) { | ||
| sa_data[i] = 0; | ||
| } | ||
| return { sa_family, sa_len, sa_data }; | ||
| } | ||
| function native_fd(virtual_fd) { | ||
| const data = wasi.FD_MAP.get(virtual_fd); | ||
| if (data == null) { | ||
| throw Error(`invalid fd=${virtual_fd}`); | ||
| } | ||
| return data.real; | ||
| } | ||
| function getSocktype(virtual_fd) { | ||
| const data = wasi.FD_MAP.get(virtual_fd); | ||
| if (data == null) { | ||
| throw Error(`unknown sock type for fd=${virtual_fd}`); | ||
| } | ||
| return data.socktype; | ||
| } | ||
| // Convert flags from wasi to native. (Right now it looks | ||
| // like only MSG_WAITALL is different.) | ||
| function native_flags(wasi_flags) { | ||
| let flags = 0; | ||
| for (const name of [ | ||
| "MSG_OOB", | ||
| "MSG_PEEK", | ||
| "MSG_WAITALL", | ||
| "MSG_DONTROUTE", | ||
| ]) { | ||
| if (wasi_flags & constants_1.default[name]) { | ||
| flags |= posix.constants[name]; | ||
| } | ||
| } | ||
| return flags; | ||
| } | ||
| function native_level(level) { | ||
| if (level == constants_1.default.SOL_SOCKET) { | ||
| return posix.constants.SOL_SOCKET; | ||
| } | ||
| return level; | ||
| } | ||
| function native_option_name(option_name) { | ||
| for (const name in constants_1.default) { | ||
| if (name.startsWith("SO_") && option_name == constants_1.default[name]) { | ||
| const x = posix.constants[name]; | ||
| if (x == null) { | ||
| throw Error(`unsupported option name "${name}" -- defined in WebAssembly but not natively`); | ||
| } | ||
| return x; | ||
| } | ||
| } | ||
| throw Error(`unknown option name ${option_name}`); | ||
| } | ||
| function createWasiFd(native_fd, socktype) { | ||
| // TODO: I'm starting the socket fd's at value over 1000 entirely because | ||
| // if wstart at the default smallest possible when doing | ||
| // "python-wasm -m pip" it crashes, since the fd=4 gets assigned | ||
| // to some socket for a moment, then freed and then 4 gets used | ||
| // for a directory (maybe at the same time), and this somehow | ||
| // confuses things. Maybe there is a bug somewhere in WASI or Python. | ||
| // For now we just workaround it by putting the socket fd's | ||
| // way out of reach of the normal file fd's. | ||
| const wasi_fd = wasi.getUnusedFileDescriptor(1000); | ||
| wasi.FD_MAP.set(wasi_fd, { | ||
| real: native_fd, | ||
| rights: { | ||
| base: wasi_js_1.SOCKET_DEFAULT_RIGHTS, | ||
| inheriting: BigInt(0), | ||
| }, | ||
| filetype: wasi_js_1.constants.WASI_FILETYPE_SOCKET_STREAM, | ||
| socktype, // constants.SOCK_STREAM (tcp) or constants.SOCK_DGRAM (udp) | ||
| }); | ||
| return wasi_fd; | ||
| } | ||
| return { | ||
| socket(family, socktype, protocol) { | ||
| if (posix.socket == null) { | ||
| throw (0, errno_1.default)("ENOTSUP"); | ||
| } | ||
| log("socket", { family, socktype, protocol }); | ||
| const familyNative = (0, netdb_1.wasmToNativeFamily)(posix, family); | ||
| let inheritable; | ||
| if (constants_1.default.SOCK_CLOEXEC & socktype) { | ||
| // SOCK_CLOEXEC is defined on Linux and WASI (weirdly) but not MacOS, | ||
| // so we manually implement it to avoid weird hacks in C code. | ||
| socktype &= ~constants_1.default.SOCK_CLOEXEC; // remove it | ||
| inheritable = false; // below we will do what SOCK_CLOEXEC would do manually. | ||
| } | ||
| else { | ||
| inheritable = true; | ||
| } | ||
| const socktypeNative = (0, netdb_1.wasmToNativeSocktype)(posix, socktype); | ||
| // TODO? I don't know how to translate this or if it is necessary. | ||
| const protocolNative = protocol; | ||
| const native_fd = posix.socket(familyNative, socktypeNative, protocolNative); | ||
| if (!inheritable) { | ||
| posix.set_inheritable(native_fd, inheritable); | ||
| } | ||
| return createWasiFd(native_fd, socktype); | ||
| }, | ||
| // int bind(int socket, const struct sockaddr *address, socklen_t address_len); | ||
| bind(socket, sockaddrPtr, address_len) { | ||
| log("bind", socket); | ||
| if (posix.bind == null) { | ||
| throw (0, errno_1.default)("ENOTSUP"); | ||
| } | ||
| const sockaddr = getSockaddr(sockaddrPtr, address_len); | ||
| log("bind: address", sockaddr); | ||
| posix.bind(native_fd(socket), sockaddr); | ||
| return 0; | ||
| }, | ||
| connect(socket, sockaddrPtr, address_len) { | ||
| if (posix.connect == null) { | ||
| throw (0, errno_1.default)("ENOTSUP"); | ||
| } | ||
| const sockaddr = getSockaddr(sockaddrPtr, address_len); | ||
| log("connect", { socket, sockaddr, address_len }); | ||
| posix.connect(native_fd(socket), sockaddr); | ||
| return 0; | ||
| }, | ||
| /* | ||
| int getsockname(int sockfd, struct sockaddr* addr, socklen_t* addrlen); | ||
| */ | ||
| getsockname(socket, sockaddrPtr, addressLenPtr) { | ||
| if (posix.getsockname == null) { | ||
| throw (0, errno_1.default)("ENOTSUP"); | ||
| } | ||
| log("getsockname", socket); | ||
| const sockaddr = posix.getsockname(native_fd(socket)); | ||
| sendNativeSockaddr(sockaddr, sockaddrPtr); | ||
| send.u32(addressLenPtr, sockaddr.sa_len); | ||
| return 0; | ||
| }, | ||
| /* | ||
| int getpeername(int sockfd, struct sockaddr* addr, socklen_t* addrlen); | ||
| */ | ||
| getpeername(socket, sockaddrPtr, addressLenPtr) { | ||
| log("getpeername", socket); | ||
| const sockaddr = posix.getpeername(native_fd(socket)); | ||
| sendNativeSockaddr(sockaddr, sockaddrPtr); | ||
| send.u32(addressLenPtr, sockaddr.sa_len); | ||
| return 0; | ||
| }, | ||
| /* | ||
| ssize_t recv(int socket, void *buffer, size_t length, int flags); | ||
| NOTE: send and recv are less efficient than they might otherwise | ||
| be due to a lot of extra copying of data to/from dynamically allocated | ||
| Buffers. Probably the cost of calling to Javascript at all exceeds | ||
| this though. | ||
| */ | ||
| recv(socket, bufPtr, length, flags) { | ||
| log("recv", { socket, bufPtr, length, flags }); | ||
| if (posix.recv == null) { | ||
| throw (0, errno_1.default)("ENOTSUP"); | ||
| } | ||
| const buffer = Buffer.alloc(length); | ||
| const bytesReceived = posix.recv(native_fd(socket), buffer, native_flags(flags)); | ||
| //log("recv got ", { buffer, bytesReceived }); | ||
| send.buffer(buffer, bufPtr); | ||
| return bytesReceived; | ||
| }, | ||
| /* | ||
| TODO: | ||
| ssize_t | ||
| recvfrom(int socket, void *buffer, size_t length, int flags, | ||
| struct sockaddr *address, socklen_t *address_len); | ||
| */ | ||
| recvfrom(socket, bufPtr, length, flags, sockaddrPtr, sockaddrLenPtr) { | ||
| log("recvfrom", { | ||
| socket, | ||
| bufPtr, | ||
| length, | ||
| flags, | ||
| sockaddrPtr, | ||
| sockaddrLenPtr, | ||
| }); | ||
| if (posix.recvfrom == null) { | ||
| throw (0, errno_1.default)("ENOTSUP"); | ||
| } | ||
| const buffer = Buffer.alloc(length); | ||
| const { bytesReceived, sockaddr } = posix.recvfrom(native_fd(socket), buffer, native_flags(flags)); | ||
| log("recvfrom got ", { buffer, bytesReceived, sockaddr }); | ||
| send.buffer(buffer, bufPtr); | ||
| sendNativeSockaddr(sockaddr, sockaddrPtr); | ||
| send.u32(sockaddrLenPtr, sockaddr.sa_len); | ||
| return bytesReceived; | ||
| }, | ||
| /* | ||
| ssize_t send(int socket, const void *buffer, size_t length, int flags); | ||
| */ | ||
| send(socket, bufPtr, length, flags) { | ||
| log("send", { socket, bufPtr, length, flags }); | ||
| if (posix.send == null) { | ||
| throw (0, errno_1.default)("ENOTSUP"); | ||
| } | ||
| const buffer = recv.buffer(bufPtr, length); | ||
| return posix.send(native_fd(socket), buffer, native_flags(flags)); | ||
| }, | ||
| /* | ||
| TODO: | ||
| ssize_t | ||
| sendto(int socket, const void *buffer, size_t length, int flags, | ||
| const struct sockaddr *dest_addr, socklen_t dest_len); | ||
| */ | ||
| sendto(socket, bufPtr, length, flags, addressPtr, addressLen) { | ||
| log("sendto", { | ||
| socket, | ||
| bufPtr, | ||
| length, | ||
| flags, | ||
| addressPtr, | ||
| addressLen, | ||
| }); | ||
| if (posix.sendto == null) { | ||
| throw (0, errno_1.default)("ENOTSUP"); | ||
| } | ||
| const buffer = Buffer.alloc(length); | ||
| const destination = getSockaddr(addressPtr, addressLen); | ||
| const bytesSent = posix.sendto(native_fd(socket), buffer, native_flags(flags), destination); | ||
| log("sendto sent ", bytesSent); | ||
| return bytesSent; | ||
| }, | ||
| /* | ||
| int shutdown(int socket, int how); | ||
| */ | ||
| shutdown(socket, how) { | ||
| log("shutdown", { socket, how }); | ||
| if (posix.shutdown == null) { | ||
| throw (0, errno_1.default)("ENOTSUP"); | ||
| } | ||
| let real_how = -1; | ||
| for (const name of ["SHUT_RD", "SHUT_WR", "SHUT_RDWR"]) { | ||
| if (how == constants_1.default[name]) { | ||
| real_how = posix.constants[name]; | ||
| break; | ||
| } | ||
| } | ||
| if (real_how == -1) { | ||
| throw (0, errno_1.default)("EINVAL"); | ||
| } | ||
| posix.shutdown(native_fd(socket), real_how); | ||
| return 0; | ||
| }, | ||
| /* | ||
| listen – listen for connections on a socket | ||
| int listen(int socket, int backlog); | ||
| */ | ||
| listen(socket, backlog) { | ||
| log("listen", { socket, backlog }); | ||
| if (posix.listen == null) { | ||
| throw (0, errno_1.default)("ENOTSUP"); | ||
| } | ||
| return posix.listen(native_fd(socket), backlog); | ||
| }, | ||
| /* | ||
| accept – accept a connection on a socket | ||
| int accept(int socket, struct sockaddr *address, socklen_t *address_len); | ||
| */ | ||
| accept(socket, sockaddrPtr, socklenPtr) { | ||
| log("accept", { socket }); | ||
| if (posix.accept == null) { | ||
| throw (0, errno_1.default)("ENOTSUP"); | ||
| } | ||
| const { fd, sockaddr } = posix.accept(native_fd(socket)); | ||
| sendNativeSockaddr(sockaddr, sockaddrPtr); | ||
| send.u32(socklenPtr, sockaddr.sa_len); | ||
| log("accept got back ", { fd, sockaddr }); | ||
| return createWasiFd(fd, getSocktype(socket)); | ||
| }, | ||
| /* | ||
| int getsockopt(int socket, int level, int option_name, void *option_value, | ||
| socklen_t *option_len); | ||
| TODO: This is of very limited value right now since the result | ||
| native, hence just wrong, and it's so opaque I don't know how to convert | ||
| it back in general. That said, I did socktype as a special case properly. | ||
| */ | ||
| getsockopt(socket, level, option_name, option_value_ptr, option_len_ptr) { | ||
| log("getsockopt", { | ||
| socket, | ||
| level, | ||
| option_name, | ||
| option_value_ptr, | ||
| option_len_ptr, | ||
| }); | ||
| if (level == constants_1.default.SOL_SOCKET && option_name == constants_1.default.SO_TYPE) { | ||
| // special case we can handle easily -- getting the type of a socket. | ||
| const socktype = getSocktype(socket); | ||
| const ab = new ArrayBuffer(4); | ||
| const dv = new DataView(ab); | ||
| dv.setUint32(0, socktype, true); | ||
| const option = Buffer.from(ab); | ||
| send.buffer(option, option_value_ptr); | ||
| send.i32(option_len_ptr, option.length); | ||
| return 0; | ||
| } | ||
| if (posix.getsockopt == null) { | ||
| throw (0, errno_1.default)("ENOTSUP"); | ||
| } | ||
| const option = posix.getsockopt(native_fd(socket), native_level(level), native_option_name(option_name), recv.i32(option_len_ptr)); | ||
| send.buffer(option, option_value_ptr); | ||
| send.i32(option_len_ptr, option.length); | ||
| return 0; | ||
| }, | ||
| /* | ||
| int setsockopt(int socket, int level, int option_name, const void *option_value, | ||
| socklen_t option_len); | ||
| */ | ||
| setsockopt(socket, level, option_name, option_value_ptr, option_len) { | ||
| log("setsockopt", { | ||
| socket, | ||
| level, | ||
| option_name, | ||
| option_value_ptr, | ||
| option_len, | ||
| }); | ||
| if (posix.setsockopt == null) { | ||
| throw (0, errno_1.default)("ENOTSUP"); | ||
| } | ||
| const option = recv.buffer(option_value_ptr, option_len); | ||
| posix.setsockopt(native_fd(socket), native_level(level), native_option_name(option_name), option); | ||
| return 0; | ||
| }, | ||
| pollSocket(socket, type, timeout_ms) { | ||
| //log("pollForSocket", { socket, type, timeout_ms }); | ||
| //return 0; | ||
| // TODO: The code below doesn't work properly -- it ALWAYS waits for the full timeout_ms, | ||
| // which is very annoying in practice, e.g., making pip hang 15s before each operation. | ||
| // Thus we replace the timeout with the min of the timeout and 250ms for now. | ||
| if (posix.pollSocket == null) { | ||
| return 0; // stub | ||
| // return wasi_constants.WASI_ENOSYS; | ||
| } | ||
| posix.pollSocket(native_fd(socket), type == "read" ? constants_1.default.POLLIN : constants_1.default.POLLOUT, Math.min(250, timeout_ms)); | ||
| return 0; | ||
| }, | ||
| }; | ||
| } | ||
| exports.default = socket; | ||
| //# sourceMappingURL=socket.js.map |
| {"version":3,"file":"socket.js","sourceRoot":"","sources":["../../../src/wasm/posix/socket.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4BE;;;;;AAEF,oDAA4B;AAC5B,mCAKiB;AACjB,4DAAoC;AACpC,qCAA6E;AAC7E,kDAA0B;AAE1B,MAAM,GAAG,GAAG,IAAA,eAAK,EAAC,cAAc,CAAC,CAAC;AAElC,SAAwB,MAAM,CAAC,EAC7B,YAAY,EACZ,KAAK,EACL,IAAI,EACJ,IAAI,EACJ,IAAI,EACJ,MAAM,GACP;IACC,SAAS,kBAAkB,CAAC,QAAQ,EAAE,GAAW;QAC/C,IAAA,oBAAY,EACV,IAAI,EACJ,MAAM,EACN,GAAG,EACH,IAAA,0BAAkB,EAAC,KAAK,EAAE,QAAQ,CAAC,SAAS,CAAC,EAC7C,QAAQ,CAAC,MAAM,EACf,QAAQ,CAAC,OAAO,CACjB,CAAC;IACJ,CAAC;IAED,SAAS,WAAW,CAAC,WAAmB,EAAE,WAAmB;QAC3D,MAAM,SAAS,GAAG,IAAA,0BAAkB,EAClC,KAAK,EACL,YAAY,CAAC,yBAAyB,EAAE,WAAW,CAAC,CACrD,CAAC;QACF,MAAM,MAAM,GAAG,WAAW,GAAG,CAAC,CAAC;QAC/B,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CACzB,YAAY,CAAC,uBAAuB,EAAE,WAAW,CAAC,EAClD,MAAM,CACP,CAAC;QACF,KAAK,IAAI,CAAC,GAAG,MAAM,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,EAAE;YACpC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;SAChB;QACD,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;IACxC,CAAC;IAED,SAAS,SAAS,CAAC,UAAkB;QACnC,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QACzC,IAAI,IAAI,IAAI,IAAI,EAAE;YAChB,MAAM,KAAK,CAAC,cAAc,UAAU,EAAE,CAAC,CAAC;SACzC;QACD,OAAO,IAAI,CAAC,IAAI,CAAC;IACnB,CAAC;IAED,SAAS,WAAW,CAAC,UAAkB;QACrC,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QACzC,IAAI,IAAI,IAAI,IAAI,EAAE;YAChB,MAAM,KAAK,CAAC,4BAA4B,UAAU,EAAE,CAAC,CAAC;SACvD;QACD,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;IAED,0DAA0D;IAC1D,uCAAuC;IACvC,SAAS,YAAY,CAAC,UAAkB;QACtC,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,KAAK,MAAM,IAAI,IAAI;YACjB,SAAS;YACT,UAAU;YACV,aAAa;YACb,eAAe;SAChB,EAAE;YACD,IAAI,UAAU,GAAG,mBAAS,CAAC,IAAI,CAAC,EAAE;gBAChC,KAAK,IAAI,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;aAChC;SACF;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,SAAS,YAAY,CAAC,KAAa;QACjC,IAAI,KAAK,IAAI,mBAAS,CAAC,UAAU,EAAE;YACjC,OAAO,KAAK,CAAC,SAAS,CAAC,UAAU,CAAC;SACnC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,SAAS,kBAAkB,CAAC,WAAmB;QAC7C,KAAK,MAAM,IAAI,IAAI,mBAAS,EAAE;YAC5B,IAAI,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,WAAW,IAAI,mBAAS,CAAC,IAAI,CAAC,EAAE;gBAC5D,MAAM,CAAC,GAAG,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;gBAChC,IAAI,CAAC,IAAI,IAAI,EAAE;oBACb,MAAM,KAAK,CACT,4BAA4B,IAAI,8CAA8C,CAC/E,CAAC;iBACH;gBACD,OAAO,CAAC,CAAC;aACV;SACF;QACD,MAAM,KAAK,CAAC,uBAAuB,WAAW,EAAE,CAAC,CAAC;IACpD,CAAC;IAED,SAAS,YAAY,CAAC,SAAiB,EAAE,QAAgB;QACvD,yEAAyE;QACzE,wDAAwD;QACxD,gEAAgE;QAChE,+DAA+D;QAC/D,6DAA6D;QAC7D,sEAAsE;QACtE,2DAA2D;QAC3D,4CAA4C;QAC5C,MAAM,OAAO,GAAG,IAAI,CAAC,uBAAuB,CAAC,IAAI,CAAC,CAAC;QACnD,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE;YACvB,IAAI,EAAE,SAAS;YACf,MAAM,EAAE;gBACN,IAAI,EAAE,+BAAqB;gBAC3B,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC;aACtB;YACD,QAAQ,EAAE,mBAAc,CAAC,2BAA2B;YACpD,QAAQ,EAAE,4DAA4D;SACvE,CAAC,CAAC;QACH,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,OAAO;QACL,MAAM,CAAC,MAAc,EAAE,QAAgB,EAAE,QAAgB;YACvD,IAAI,KAAK,CAAC,MAAM,IAAI,IAAI,EAAE;gBACxB,MAAM,IAAA,eAAK,EAAC,SAAS,CAAC,CAAC;aACxB;YACD,GAAG,CAAC,QAAQ,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC;YAE9C,MAAM,YAAY,GAAG,IAAA,0BAAkB,EAAC,KAAK,EAAE,MAAM,CAAC,CAAC;YAEvD,IAAI,WAAW,CAAC;YAChB,IAAI,mBAAS,CAAC,YAAY,GAAG,QAAQ,EAAE;gBACrC,qEAAqE;gBACrE,8DAA8D;gBAC9D,QAAQ,IAAI,CAAC,mBAAS,CAAC,YAAY,CAAC,CAAC,YAAY;gBACjD,WAAW,GAAG,KAAK,CAAC,CAAC,wDAAwD;aAC9E;iBAAM;gBACL,WAAW,GAAG,IAAI,CAAC;aACpB;YAED,MAAM,cAAc,GAAG,IAAA,4BAAoB,EAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;YAE7D,kEAAkE;YAClE,MAAM,cAAc,GAAG,QAAQ,CAAC;YAEhC,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,CAC5B,YAAY,EACZ,cAAc,EACd,cAAc,CACf,CAAC;YAEF,IAAI,CAAC,WAAW,EAAE;gBAChB,KAAK,CAAC,eAAe,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;aAC/C;YACD,OAAO,YAAY,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;QAC3C,CAAC;QAED,+EAA+E;QAC/E,IAAI,CAAC,MAAc,EAAE,WAAmB,EAAE,WAAmB;YAC3D,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;YACpB,IAAI,KAAK,CAAC,IAAI,IAAI,IAAI,EAAE;gBACtB,MAAM,IAAA,eAAK,EAAC,SAAS,CAAC,CAAC;aACxB;YACD,MAAM,QAAQ,GAAG,WAAW,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;YACvD,GAAG,CAAC,eAAe,EAAE,QAAQ,CAAC,CAAC;YAC/B,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,QAAQ,CAAC,CAAC;YAExC,OAAO,CAAC,CAAC;QACX,CAAC;QAED,OAAO,CAAC,MAAc,EAAE,WAAmB,EAAE,WAAmB;YAC9D,IAAI,KAAK,CAAC,OAAO,IAAI,IAAI,EAAE;gBACzB,MAAM,IAAA,eAAK,EAAC,SAAS,CAAC,CAAC;aACxB;YACD,MAAM,QAAQ,GAAG,WAAW,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;YACvD,GAAG,CAAC,SAAS,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,CAAC,CAAC;YAClD,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,QAAQ,CAAC,CAAC;YAC3C,OAAO,CAAC,CAAC;QACX,CAAC;QAED;;UAEE;QACF,WAAW,CACT,MAAc,EACd,WAAmB,EACnB,aAAqB;YAErB,IAAI,KAAK,CAAC,WAAW,IAAI,IAAI,EAAE;gBAC7B,MAAM,IAAA,eAAK,EAAC,SAAS,CAAC,CAAC;aACxB;YACD,GAAG,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;YAC3B,MAAM,QAAQ,GAAG,KAAK,CAAC,WAAW,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;YACtD,kBAAkB,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;YAC1C,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;YACzC,OAAO,CAAC,CAAC;QACX,CAAC;QAED;;UAEE;QACF,WAAW,CACT,MAAc,EACd,WAAmB,EACnB,aAAqB;YAErB,GAAG,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;YAC3B,MAAM,QAAQ,GAAG,KAAK,CAAC,WAAW,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;YACtD,kBAAkB,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;YAC1C,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;YACzC,OAAO,CAAC,CAAC;QACX,CAAC;QAED;;;;;;;UAOE;QACF,IAAI,CACF,MAAc,EACd,MAAc,EACd,MAAc,EACd,KAAa;YAEb,GAAG,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;YAC/C,IAAI,KAAK,CAAC,IAAI,IAAI,IAAI,EAAE;gBACtB,MAAM,IAAA,eAAK,EAAC,SAAS,CAAC,CAAC;aACxB;YACD,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YACpC,MAAM,aAAa,GAAG,KAAK,CAAC,IAAI,CAC9B,SAAS,CAAC,MAAM,CAAC,EACjB,MAAM,EACN,YAAY,CAAC,KAAK,CAAC,CACpB,CAAC;YACF,8CAA8C;YAC9C,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;YAC5B,OAAO,aAAa,CAAC;QACvB,CAAC;QAED;;;;;UAKE;QACF,QAAQ,CACN,MAAc,EACd,MAAc,EACd,MAAc,EACd,KAAa,EACb,WAAmB,EACnB,cAAsB;YAEtB,GAAG,CAAC,UAAU,EAAE;gBACd,MAAM;gBACN,MAAM;gBACN,MAAM;gBACN,KAAK;gBACL,WAAW;gBACX,cAAc;aACf,CAAC,CAAC;YACH,IAAI,KAAK,CAAC,QAAQ,IAAI,IAAI,EAAE;gBAC1B,MAAM,IAAA,eAAK,EAAC,SAAS,CAAC,CAAC;aACxB;YACD,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YACpC,MAAM,EAAE,aAAa,EAAE,QAAQ,EAAE,GAAG,KAAK,CAAC,QAAQ,CAChD,SAAS,CAAC,MAAM,CAAC,EACjB,MAAM,EACN,YAAY,CAAC,KAAK,CAAC,CACpB,CAAC;YACF,GAAG,CAAC,eAAe,EAAE,EAAE,MAAM,EAAE,aAAa,EAAE,QAAQ,EAAE,CAAC,CAAC;YAC1D,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;YAC5B,kBAAkB,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;YAC1C,IAAI,CAAC,GAAG,CAAC,cAAc,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;YAC1C,OAAO,aAAa,CAAC;QACvB,CAAC;QAED;;UAEE;QACF,IAAI,CACF,MAAc,EACd,MAAc,EACd,MAAc,EACd,KAAa;YAEb,GAAG,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;YAC/C,IAAI,KAAK,CAAC,IAAI,IAAI,IAAI,EAAE;gBACtB,MAAM,IAAA,eAAK,EAAC,SAAS,CAAC,CAAC;aACxB;YACD,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;YAC3C,OAAO,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC;QACpE,CAAC;QAED;;;;;;UAME;QACF,MAAM,CACJ,MAAc,EACd,MAAc,EACd,MAAc,EACd,KAAa,EACb,UAAkB,EAClB,UAAkB;YAElB,GAAG,CAAC,QAAQ,EAAE;gBACZ,MAAM;gBACN,MAAM;gBACN,MAAM;gBACN,KAAK;gBACL,UAAU;gBACV,UAAU;aACX,CAAC,CAAC;YACH,IAAI,KAAK,CAAC,MAAM,IAAI,IAAI,EAAE;gBACxB,MAAM,IAAA,eAAK,EAAC,SAAS,CAAC,CAAC;aACxB;YACD,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YACpC,MAAM,WAAW,GAAG,WAAW,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;YACxD,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,CAC5B,SAAS,CAAC,MAAM,CAAC,EACjB,MAAM,EACN,YAAY,CAAC,KAAK,CAAC,EACnB,WAAW,CACZ,CAAC;YAEF,GAAG,CAAC,cAAc,EAAE,SAAS,CAAC,CAAC;YAC/B,OAAO,SAAS,CAAC;QACnB,CAAC;QAED;;UAEE;QACF,QAAQ,CAAC,MAAc,EAAE,GAAW;YAClC,GAAG,CAAC,UAAU,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;YACjC,IAAI,KAAK,CAAC,QAAQ,IAAI,IAAI,EAAE;gBAC1B,MAAM,IAAA,eAAK,EAAC,SAAS,CAAC,CAAC;aACxB;YACD,IAAI,QAAQ,GAAG,CAAC,CAAC,CAAC;YAClB,KAAK,MAAM,IAAI,IAAI,CAAC,SAAS,EAAE,SAAS,EAAE,WAAW,CAAC,EAAE;gBACtD,IAAI,GAAG,IAAI,mBAAS,CAAC,IAAI,CAAC,EAAE;oBAC1B,QAAQ,GAAG,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;oBACjC,MAAM;iBACP;aACF;YACD,IAAI,QAAQ,IAAI,CAAC,CAAC,EAAE;gBAClB,MAAM,IAAA,eAAK,EAAC,QAAQ,CAAC,CAAC;aACvB;YACD,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,QAAQ,CAAC,CAAC;YAC5C,OAAO,CAAC,CAAC;QACX,CAAC;QAED;;;;UAIE;QACF,MAAM,CAAC,MAAc,EAAE,OAAe;YACpC,GAAG,CAAC,QAAQ,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC;YACnC,IAAI,KAAK,CAAC,MAAM,IAAI,IAAI,EAAE;gBACxB,MAAM,IAAA,eAAK,EAAC,SAAS,CAAC,CAAC;aACxB;YACD,OAAO,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,CAAC;QAClD,CAAC;QAED;;;UAGE;QACF,MAAM,CAAC,MAAc,EAAE,WAAmB,EAAE,UAAkB;YAC5D,GAAG,CAAC,QAAQ,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;YAC1B,IAAI,KAAK,CAAC,MAAM,IAAI,IAAI,EAAE;gBACxB,MAAM,IAAA,eAAK,EAAC,SAAS,CAAC,CAAC;aACxB;YACD,MAAM,EAAE,EAAE,EAAE,QAAQ,EAAE,GAAG,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;YACzD,kBAAkB,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;YAC1C,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;YACtC,GAAG,CAAC,kBAAkB,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC;YAC1C,OAAO,YAAY,CAAC,EAAE,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC;QAC/C,CAAC;QAED;;;;;;;UAOE;QACF,UAAU,CACR,MAAc,EACd,KAAa,EACb,WAAmB,EACnB,gBAAwB,EACxB,cAAsB;YAEtB,GAAG,CAAC,YAAY,EAAE;gBAChB,MAAM;gBACN,KAAK;gBACL,WAAW;gBACX,gBAAgB;gBAChB,cAAc;aACf,CAAC,CAAC;YAEH,IAAI,KAAK,IAAI,mBAAS,CAAC,UAAU,IAAI,WAAW,IAAI,mBAAS,CAAC,OAAO,EAAE;gBACrE,qEAAqE;gBACrE,MAAM,QAAQ,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;gBACrC,MAAM,EAAE,GAAG,IAAI,WAAW,CAAC,CAAC,CAAC,CAAC;gBAC9B,MAAM,EAAE,GAAG,IAAI,QAAQ,CAAC,EAAE,CAAC,CAAC;gBAC5B,EAAE,CAAC,SAAS,CAAC,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;gBAChC,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;gBAC/B,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;gBACtC,IAAI,CAAC,GAAG,CAAC,cAAc,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;gBACxC,OAAO,CAAC,CAAC;aACV;YAED,IAAI,KAAK,CAAC,UAAU,IAAI,IAAI,EAAE;gBAC5B,MAAM,IAAA,eAAK,EAAC,SAAS,CAAC,CAAC;aACxB;YACD,MAAM,MAAM,GAAG,KAAK,CAAC,UAAU,CAC7B,SAAS,CAAC,MAAM,CAAC,EACjB,YAAY,CAAC,KAAK,CAAC,EACnB,kBAAkB,CAAC,WAAW,CAAC,EAC/B,IAAI,CAAC,GAAG,CAAC,cAAc,CAAC,CACzB,CAAC;YACF,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;YACtC,IAAI,CAAC,GAAG,CAAC,cAAc,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;YACxC,OAAO,CAAC,CAAC;QACX,CAAC;QAED;;;UAGE;QACF,UAAU,CACR,MAAc,EACd,KAAa,EACb,WAAmB,EACnB,gBAAwB,EACxB,UAAkB;YAElB,GAAG,CAAC,YAAY,EAAE;gBAChB,MAAM;gBACN,KAAK;gBACL,WAAW;gBACX,gBAAgB;gBAChB,UAAU;aACX,CAAC,CAAC;YACH,IAAI,KAAK,CAAC,UAAU,IAAI,IAAI,EAAE;gBAC5B,MAAM,IAAA,eAAK,EAAC,SAAS,CAAC,CAAC;aACxB;YACD,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,gBAAgB,EAAE,UAAU,CAAC,CAAC;YACzD,KAAK,CAAC,UAAU,CACd,SAAS,CAAC,MAAM,CAAC,EACjB,YAAY,CAAC,KAAK,CAAC,EACnB,kBAAkB,CAAC,WAAW,CAAC,EAC/B,MAAM,CACP,CAAC;YACF,OAAO,CAAC,CAAC;QACX,CAAC;QAED,UAAU,CACR,MAAc,EACd,IAAsB,EACtB,UAAkB;YAElB,qDAAqD;YACrD,WAAW;YACX,yFAAyF;YACzF,uFAAuF;YACvF,6EAA6E;YAC7E,IAAI,KAAK,CAAC,UAAU,IAAI,IAAI,EAAE;gBAC5B,OAAO,CAAC,CAAC,CAAC,OAAO;gBACjB,qCAAqC;aACtC;YACD,KAAK,CAAC,UAAU,CACd,SAAS,CAAC,MAAM,CAAC,EACjB,IAAI,IAAI,MAAM,CAAC,CAAC,CAAC,mBAAS,CAAC,MAAM,CAAC,CAAC,CAAC,mBAAS,CAAC,OAAO,EACrD,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,UAAU,CAAC,CAC1B,CAAC;YACF,OAAO,CAAC,CAAC;QACX,CAAC;KACF,CAAC;AACJ,CAAC;AAheD,yBAgeC"} |
| export default function spawn(context: any): { | ||
| posix_spawnattr_setschedparam: (attrPtr: number, schedparamPtr: number) => number; | ||
| posix_spawnattr_getschedparam: (attrPtr: number, schedparamPtr: number) => number; | ||
| posix_spawnattr_setschedpolicy: (attrPtr: number, schedpolicy: number) => number; | ||
| posix_spawnattr_getschedpolicy: (attrPtr: number, schedpolicyPtr: number) => number; | ||
| posix_spawnattr_init: (attrPtr: number) => number; | ||
| posix_spawnattr_destroy: (attrPtr: number) => number; | ||
| posix_spawnattr_setflags: (attrPtr: number, flags: number) => number; | ||
| posix_spawnattr_getflags: (attrPtr: number, flagsPtr: number) => number; | ||
| posix_spawnattr_setpgroup: (attrPtr: number, pgroup: number) => number; | ||
| posix_spawnattr_getpgroup: (attrPtr: number, pgroupPtr: number) => number; | ||
| posix_spawnattr_setsigmask: (attrPtr: number, sigmaskPtr: number) => number; | ||
| posix_spawnattr_getsigmask: (attrPtr: number, sigmaskPtr: number) => number; | ||
| posix_spawnattr_setsigdefault: (attrPtr: number, sigdefaultPtr: number) => number; | ||
| posix_spawnattr_getsigdefault: (attrPtr: number, sigdefaultPtr: number) => number; | ||
| posix_spawn: (pidPtr: any, pathPtr: any, fileActionsPtr: any, attrPtr: any, argvPtr: any, envpPtr: any) => number; | ||
| posix_spawnp: (pidPtr: any, pathPtr: any, fileActionsPtr: any, attrPtr: any, argvPtr: any, envpPtr: any) => number; | ||
| posix_spawn_file_actions_init: (fileActionsPtr: number) => number; | ||
| posix_spawn_file_actions_destroy: (fileActionsPtr: number) => number; | ||
| posix_spawn_file_actions_addclose: (fileActionsPtr: number, fd: number) => number; | ||
| posix_spawn_file_actions_addopen: (fileActionsPtr: number, fd: number, pathPtr: number, oflag: number, mode: number) => number; | ||
| posix_spawn_file_actions_adddup2: (fileActionsPtr: number, fd: number, new_fd: number) => number; | ||
| }; |
| "use strict"; | ||
| /* | ||
| I do intend to implement all the spawn system calls using node.js at some point, so that python-wasm on nodejs is | ||
| able to create and use subprocesses, at least when in an insecure mode. In the browser, it could also create | ||
| other webassembly workers for a restricted collection of "commands". However, for now, these shall all throw | ||
| an error. | ||
| SEE fork-exec.ts and posix-context.ts for partial solutions to the above for the fork/exec pattern! | ||
| */ | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| const util_1 = require("./util"); | ||
| const signal_1 = require("./signal"); | ||
| function spawn(context) { | ||
| const { callFunction, posix, recv, send } = context; | ||
| function getFileActions() { | ||
| if (context.state.fileActions == null) { | ||
| context.state.spawn_fileActions = {}; | ||
| } | ||
| return context.state.spawn_fileActions; | ||
| } | ||
| function getAttrs() { | ||
| if (context.state.spawn_attrs == null) { | ||
| context.state.spawn_attrs = {}; | ||
| } | ||
| return context.state.spawn_attrs; | ||
| } | ||
| function getAttr(ptr, expand = false) { | ||
| const attrs = getAttrs(); | ||
| if (attrs[ptr] == null) { | ||
| return (attrs[ptr] = {}); | ||
| } | ||
| const attr = attrs[ptr]; | ||
| if (attr != null) { | ||
| if (expand) { | ||
| if (attr.sigdefaultPtr != null) { | ||
| attr.sigdefault = (0, signal_1.getSignalSet)(attr.sigdefaultPtr); | ||
| } | ||
| if (attr.sigmaskPtr != null) { | ||
| attr.sigmask = (0, signal_1.getSignalSet)(attr.sigmaskPtr); | ||
| } | ||
| } | ||
| return attr; | ||
| } | ||
| else { | ||
| throw Error("bug"); // impossible | ||
| } | ||
| } | ||
| return { | ||
| posix_spawnattr_setschedparam: (attrPtr, schedparamPtr) => { | ||
| getAttr(attrPtr).schedparam = { | ||
| sched_priority: callFunction("get_posix_spawnattr_schedparam_sched_priority", schedparamPtr), | ||
| }; | ||
| return 0; | ||
| }, | ||
| posix_spawnattr_getschedparam: (attrPtr, schedparamPtr) => { | ||
| const sched_priority = getAttr(attrPtr).schedparam ?? 0; | ||
| callFunction("set_posix_spawnattr_schedparam_sched_priority", schedparamPtr, sched_priority); | ||
| return 0; | ||
| }, | ||
| posix_spawnattr_setschedpolicy: (attrPtr, schedpolicy) => { | ||
| getAttr(attrPtr).schedpolicy = schedpolicy; | ||
| return 0; | ||
| }, | ||
| posix_spawnattr_getschedpolicy: (attrPtr, schedpolicyPtr) => { | ||
| send.i32(schedpolicyPtr, getAttr(attrPtr).schedpolicy ?? 0); | ||
| return 0; | ||
| }, | ||
| posix_spawnattr_init: (attrPtr) => { | ||
| const attrs = getAttrs(); | ||
| attrs[attrPtr] = {}; | ||
| return 0; | ||
| }, | ||
| posix_spawnattr_destroy: (attrPtr) => { | ||
| const attrs = getAttrs(); | ||
| delete attrs[attrPtr]; | ||
| return 0; | ||
| }, | ||
| posix_spawnattr_setflags: (attrPtr, flags) => { | ||
| getAttr(attrPtr).flags = flags; | ||
| return 0; | ||
| }, | ||
| posix_spawnattr_getflags: (attrPtr, flagsPtr) => { | ||
| send.i32(flagsPtr, getAttr(attrPtr).flags ?? 0); | ||
| return 0; | ||
| }, | ||
| posix_spawnattr_setpgroup: (attrPtr, pgroup) => { | ||
| getAttr(attrPtr).pgroup = pgroup; | ||
| return 0; | ||
| }, | ||
| posix_spawnattr_getpgroup: (attrPtr, pgroupPtr) => { | ||
| send.i32(pgroupPtr, getAttr(attrPtr).pgroup ?? 0); | ||
| return 0; | ||
| }, | ||
| posix_spawnattr_setsigmask: (attrPtr, sigmaskPtr) => { | ||
| getAttr(attrPtr).sigmaskPtr = sigmaskPtr; | ||
| return 0; | ||
| }, | ||
| posix_spawnattr_getsigmask: (attrPtr, sigmaskPtr) => { | ||
| const cur = getAttr(attrPtr).sigmaskPtr; | ||
| (0, signal_1.setSignalSet)(sigmaskPtr, (0, signal_1.getSignalSet)(cur)); | ||
| return 0; | ||
| }, | ||
| posix_spawnattr_setsigdefault: (attrPtr, sigdefaultPtr) => { | ||
| getAttr(attrPtr).sigdefaultPtr = sigdefaultPtr; | ||
| return 0; | ||
| }, | ||
| posix_spawnattr_getsigdefault: (attrPtr, sigdefaultPtr) => { | ||
| const cur = getAttr(attrPtr).sigdefaultPtr; | ||
| (0, signal_1.setSignalSet)(sigdefaultPtr, (0, signal_1.getSignalSet)(cur)); | ||
| return 0; | ||
| }, | ||
| posix_spawn: (pidPtr, pathPtr, fileActionsPtr, attrPtr, argvPtr, envpPtr) => { | ||
| if (posix.posix_spawn == null) { | ||
| (0, util_1.notImplemented)("posix_spawn"); | ||
| } | ||
| const path = recv.string(pathPtr); | ||
| const argv = recv.arrayOfStrings(argvPtr); | ||
| const envp = recv.arrayOfStrings(envpPtr); | ||
| const fileActions = getFileActions(); | ||
| const pid = posix.posix_spawn(path, fileActions[fileActionsPtr], getAttr(attrPtr, true), argv, envp); | ||
| send.i32(pidPtr, pid); | ||
| return 0; | ||
| }, | ||
| posix_spawnp: (pidPtr, pathPtr, fileActionsPtr, attrPtr, argvPtr, envpPtr) => { | ||
| if (posix.posix_spawnp == null) { | ||
| (0, util_1.notImplemented)("posix_spawnp"); | ||
| } | ||
| const path = recv.string(pathPtr); | ||
| const argv = recv.arrayOfStrings(argvPtr); | ||
| const envp = recv.arrayOfStrings(envpPtr); | ||
| const fileActions = getFileActions(); | ||
| const pid = posix.posix_spawnp(path, fileActions[fileActionsPtr], getAttr(attrPtr, true), argv, envp); | ||
| send.i32(pidPtr, pid); | ||
| return 0; | ||
| }, | ||
| posix_spawn_file_actions_init: (fileActionsPtr) => { | ||
| const fileActions = getFileActions(); | ||
| fileActions[fileActionsPtr] = []; | ||
| return 0; | ||
| }, | ||
| posix_spawn_file_actions_destroy: (fileActionsPtr) => { | ||
| const fileActions = getFileActions(); | ||
| delete fileActions[fileActionsPtr]; | ||
| return 0; | ||
| }, | ||
| posix_spawn_file_actions_addclose: (fileActionsPtr, fd) => { | ||
| const fileActions = getFileActions(); | ||
| if (fileActions[fileActionsPtr] == null) { | ||
| fileActions[fileActionsPtr] = []; | ||
| } | ||
| fileActions[fileActionsPtr].push(["addclose", fd]); | ||
| return 0; | ||
| }, | ||
| posix_spawn_file_actions_addopen: (fileActionsPtr, fd, pathPtr, oflag, mode) => { | ||
| const fileActions = getFileActions(); | ||
| if (fileActions[fileActionsPtr] == null) { | ||
| fileActions[fileActionsPtr] = []; | ||
| } | ||
| const path = recv.string(pathPtr); | ||
| fileActions[fileActionsPtr].push(["addopen", fd, path, oflag, mode]); | ||
| return 0; | ||
| }, | ||
| posix_spawn_file_actions_adddup2: (fileActionsPtr, fd, new_fd) => { | ||
| const fileActions = getFileActions(); | ||
| if (fileActions[fileActionsPtr] == null) { | ||
| fileActions[fileActionsPtr] = []; | ||
| } | ||
| fileActions[fileActionsPtr].push(["adddup2", fd, new_fd]); | ||
| return 0; | ||
| }, | ||
| }; | ||
| } | ||
| exports.default = spawn; | ||
| //# sourceMappingURL=spawn.js.map |
| {"version":3,"file":"spawn.js","sourceRoot":"","sources":["../../../src/wasm/posix/spawn.ts"],"names":[],"mappings":"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"} |
| export default function stats({ fs, process, recv, wasi }: { | ||
| fs: any; | ||
| process: any; | ||
| recv: any; | ||
| wasi: any; | ||
| }): { | ||
| chmod: (pathPtr: number, mode: number) => -1 | 0; | ||
| _fchmod: (fd: number, mode: number) => number; | ||
| fchmodat: (dirfd: number, pathPtr: number, mode: number, _flags: number) => number; | ||
| lchmod: (pathPtr: number, mode: number) => -1 | 0; | ||
| umask: (mask: number) => any; | ||
| mkfifo: () => void; | ||
| mknod: () => void; | ||
| }; |
| "use strict"; | ||
| var __importDefault = (this && this.__importDefault) || function (mod) { | ||
| return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
| }; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| const path_1 = require("path"); | ||
| const constants_1 = __importDefault(require("./constants")); | ||
| const errno_1 = __importDefault(require("./errno")); | ||
| const util_1 = require("./util"); | ||
| function stats({ fs, process, recv, wasi }) { | ||
| function calculateAt(dirfd, path, allowEmpty = false) { | ||
| if ((0, path_1.isAbsolute)("path")) { | ||
| return path; | ||
| } | ||
| let dir; | ||
| if (dirfd == constants_1.default.AT_FDCWD) { | ||
| dir = process.cwd?.() ?? "/"; | ||
| } | ||
| else { | ||
| // it is a file descriptor | ||
| const entry = wasi.FD_MAP.get(dirfd); | ||
| if (!entry) { | ||
| throw (0, errno_1.default)("EBADF"); | ||
| } | ||
| dir = entry.path; | ||
| } | ||
| if (path.length == 0) { | ||
| if (!allowEmpty) { | ||
| throw (0, errno_1.default)("ENOENT"); | ||
| } | ||
| return dir; | ||
| } | ||
| return (0, path_1.join)(dir, path); | ||
| } | ||
| // because wasi's structs don't have sufficient info to deal with permissions, we make ALL of these | ||
| // chmods into stubs, below, despite having implemented them! | ||
| // This in particular totally broke libgit2 working at all. | ||
| // TODO: an alternative may be to always set the mode to 0777. I'm not sure how bad that would be. | ||
| return { | ||
| chmod: (pathPtr, mode) => { | ||
| return 0; // stubbed due to wasi shortcomings | ||
| if (!mode) { | ||
| // It is impossible for stat calls by wasi to return anything except 0 at present due to this bug: | ||
| // See https://github.com/WebAssembly/wasi-filesystem/issues/34 | ||
| // Thus they will often then set the mode to 0, e.g., shutil.copy in python does this to all files. | ||
| // In such cases, we silently make this a successful no-op instead of breaking everything horribly. | ||
| // This comes up a lot with using Python as part of a build process. | ||
| return 0; | ||
| } | ||
| const path = recv.string(pathPtr); | ||
| fs.chmodSync(path, mode); | ||
| return 0; | ||
| }, | ||
| _fchmod: (fd, mode) => { | ||
| return 0; // stubbed due to wasi shortcomings | ||
| if (!mode) { | ||
| // see above. | ||
| return 0; | ||
| } | ||
| const entry = wasi.FD_MAP.get(fd); | ||
| if (!entry) { | ||
| console.warn("bad file descriptor, fchmod"); | ||
| return -1; | ||
| } | ||
| fs.fchmodSync(entry.real, mode); | ||
| return 0; | ||
| }, | ||
| // int fchmodat(int dirfd, const char *pathname, mode_t mode, int flags); | ||
| fchmodat: (dirfd, pathPtr, mode, _flags) => { | ||
| return 0; // stubbed due to wasi shortcomings | ||
| if (!mode) { | ||
| // see above. | ||
| return 0; | ||
| } | ||
| /* "The fchmodat() system call operates in exactly the same way as chmod(2), except... If the | ||
| pathname given in pathname is relative, then it is interpreted relative to the directory referred | ||
| to by the file descriptor dirfd (rather than relative to the current working directory of the | ||
| calling process, as is done by chmod(2) for a relative pathname). If pathname is relative and | ||
| dirfd is the special value AT_FDCWD, then pathname is interpreted relative to the current | ||
| working directory of the calling process (like chmod(2)). If pathname is absolute, then dirfd | ||
| is ignored. This flag is not currently implemented." | ||
| */ | ||
| const path = recv.string(pathPtr); | ||
| const pathAt = calculateAt(dirfd, path); | ||
| fs.chmodSync(pathAt, mode); | ||
| return 0; | ||
| }, | ||
| lchmod: (pathPtr, mode) => { | ||
| return 0; // stubbed due to wasi shortcomings | ||
| if (!mode) { | ||
| // see above. | ||
| return 0; | ||
| } | ||
| const path = recv.string(pathPtr); | ||
| fs.lchmodSync(path, mode); | ||
| return 0; | ||
| }, | ||
| // mode_t umask(mode_t mask); | ||
| umask: (mask) => { | ||
| // we return 18 when there's no process.umask function, since that's | ||
| // like umask 022, i.e., it's a reasonable default. | ||
| return process.umask?.(mask) ?? 18; | ||
| }, | ||
| // not in wasi and we haven't done it yet... | ||
| mkfifo: () => { | ||
| (0, util_1.notImplemented)("mkfifo"); | ||
| }, | ||
| mknod: () => { | ||
| (0, util_1.notImplemented)("mknod"); | ||
| }, | ||
| }; | ||
| } | ||
| exports.default = stats; | ||
| //# sourceMappingURL=stat.js.map |
| {"version":3,"file":"stat.js","sourceRoot":"","sources":["../../../src/wasm/posix/stat.ts"],"names":[],"mappings":"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"} |
| export default function stdio(context: any): { | ||
| tmpnam(sPtr: number): number; | ||
| popen(_commandPtr: number, _typePtr: number): number; | ||
| pclose(_streamPtr: number): number; | ||
| }; |
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| function stdio(context) { | ||
| const { fs, send } = context; | ||
| return { | ||
| /* char *tmpnam(char *s); | ||
| Linux manpage is funny and clear: | ||
| The tmpnam() function returns a pointer to a string that is a valid filename, | ||
| and such that a file with this name did not exist at some point in time, so that | ||
| naive programmers may think it a suitable name for a temporary file. If the | ||
| argument s is NULL, this name is generated in an internal static buffer and may | ||
| be overwritten by the next call to tmpnam(). If s is not NULL, the name is copied to | ||
| the character array (of length at least L_tmpnam) pointed to by s and the value s | ||
| is returned in case of success. | ||
| */ | ||
| tmpnam(sPtr) { | ||
| let s = "/tmp/tmpnam_"; | ||
| for (let i = 0; i < 1000; i++) { | ||
| let name = s; | ||
| // very naive, but WASM is a single user VM so a lot of security issues disappear | ||
| for (let j = 0; j < 6; j++) { | ||
| name += String.fromCharCode(65 + Math.floor(26 * Math.random())); | ||
| } | ||
| if (!fs.existsSync(name)) { | ||
| if (sPtr) { | ||
| send.string(name, { ptr: sPtr, len: 20 }); | ||
| return sPtr; | ||
| } | ||
| else { | ||
| if (!context.state.tmpnam_buf) { | ||
| context.state.tmpnam_buf = send.malloc(20); | ||
| } | ||
| send.string(name, { ptr: context.state.tmpnam_buf, len: 20 }); | ||
| return context.state.tmpnam_buf; | ||
| } | ||
| } | ||
| } | ||
| return 0; // error | ||
| }, | ||
| /* | ||
| Stubs for popen and pclose that throw an error. I think these would be kind of impossible | ||
| to do in WASM (without multiple threads... hence sync'd filesystem) because they are | ||
| nonblocking...? | ||
| FILE* popen(const char* command, const char* type); | ||
| int pclose(FILE* stream); | ||
| */ | ||
| popen(_commandPtr, _typePtr) { | ||
| // returning 0 means it couldn't do it. | ||
| return 0; | ||
| }, | ||
| pclose(_streamPtr) { | ||
| return -1; | ||
| }, | ||
| }; | ||
| } | ||
| exports.default = stdio; | ||
| //# sourceMappingURL=stdio.js.map |
| {"version":3,"file":"stdio.js","sourceRoot":"","sources":["../../../src/wasm/posix/stdio.ts"],"names":[],"mappings":";;AAAA,SAAwB,KAAK,CAAC,OAAO;IACnC,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC;IAC7B,OAAO;QACL;;;;;;;;;;;UAWE;QAEF,MAAM,CAAC,IAAY;YACjB,IAAI,CAAC,GAAG,cAAc,CAAC;YACvB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE,EAAE;gBAC7B,IAAI,IAAI,GAAG,CAAC,CAAC;gBACb,iFAAiF;gBACjF,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE;oBAC1B,IAAI,IAAI,MAAM,CAAC,YAAY,CAAC,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;iBAClE;gBACD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE;oBACxB,IAAI,IAAI,EAAE;wBACR,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC,CAAC;wBAC1C,OAAO,IAAI,CAAC;qBACb;yBAAM;wBACL,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,UAAU,EAAE;4BAC7B,OAAO,CAAC,KAAK,CAAC,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;yBAC5C;wBACD,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,GAAG,EAAE,OAAO,CAAC,KAAK,CAAC,UAAU,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC,CAAC;wBAC9D,OAAO,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC;qBACjC;iBACF;aACF;YACD,OAAO,CAAC,CAAC,CAAC,QAAQ;QACpB,CAAC;QAED;;;;;;;UAOE;QACF,KAAK,CAAC,WAAmB,EAAE,QAAgB;YACzC,uCAAuC;YACvC,OAAO,CAAC,CAAC;QACX,CAAC;QAED,MAAM,CAAC,UAAkB;YACvB,OAAO,CAAC,CAAC,CAAC;QACZ,CAAC;KACF,CAAC;AACJ,CAAC;AAzDD,wBAyDC"} |
| export default function stdlib({ child_process, os, recv, send, fs }: { | ||
| child_process: any; | ||
| os: any; | ||
| recv: any; | ||
| send: any; | ||
| fs: any; | ||
| }): { | ||
| setjmp: () => number; | ||
| longjmp: () => number; | ||
| siglongjmp: () => number; | ||
| sigsetjmp: () => number; | ||
| getloadavg: (loadavgDoubleArrayPtr: number, nelem: number) => number; | ||
| system: (commandPtr: any) => number; | ||
| realpath: (pathPtr: any, resolvedPathPtr: any) => number; | ||
| }; |
| "use strict"; | ||
| var __importDefault = (this && this.__importDefault) || function (mod) { | ||
| return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
| }; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| const util_1 = require("./util"); | ||
| const debug_1 = __importDefault(require("debug")); | ||
| const log = (0, debug_1.default)("posix:stdlib"); | ||
| function stdlib({ child_process, os, recv, send, fs }) { | ||
| return { | ||
| setjmp: () => { | ||
| // Return 0 so it doesn't do the failure care of the setjmp. | ||
| log("STUB: setjmp - no op"); | ||
| return 0; | ||
| }, | ||
| // void longjmp(jmp_buf env, int val); | ||
| longjmp: () => { | ||
| log("STUB: longjmp - no op"); | ||
| return 0; | ||
| }, | ||
| siglongjmp: () => { | ||
| log("STUB: siglongjmp - no op"); | ||
| return 0; | ||
| }, | ||
| sigsetjmp: () => { | ||
| log("STUB: sigsetjmp - no op"); | ||
| return 0; | ||
| }, | ||
| // int getloadavg(double loadavg[], int nelem); | ||
| getloadavg: (loadavgDoubleArrayPtr, nelem) => { | ||
| const { loadavg } = os; | ||
| if (loadavg == null) { | ||
| // load average is not attainable | ||
| return -1; | ||
| } | ||
| const avg = loadavg(); | ||
| send.f64(loadavgDoubleArrayPtr, avg[0]); | ||
| send.f64(loadavgDoubleArrayPtr + 8, avg[1]); // double = 8 bytes in WASM | ||
| send.f64(loadavgDoubleArrayPtr + 16, avg[2]); | ||
| // number of samples (not provided by loadavg). In python itself if you don't get | ||
| // all of them (3 are requested), it just gives an error. | ||
| return nelem; | ||
| }, | ||
| // int system(const char *command); | ||
| // This below is not exactly like system because it runs until the command completes with no visible output | ||
| // until it completes. | ||
| // TODO: this only works once then gets totally broken when using webworkers! It works fine | ||
| // for the blocking version only. | ||
| system: (commandPtr) => { | ||
| if (child_process.spawnSync == null) { | ||
| (0, util_1.notImplemented)("system is not implemented yet"); | ||
| } | ||
| const command = recv.string(commandPtr); | ||
| const { stdout, stderr, status } = child_process.spawnSync(command, { | ||
| shell: true, | ||
| }); | ||
| console.log(stdout.toString()); | ||
| console.warn(stderr.toString()); | ||
| return status; | ||
| }, | ||
| // char *realpath(const char *path, char *resolved_path); | ||
| realpath: (pathPtr, resolvedPathPtr) => { | ||
| try { | ||
| const path = recv.string(pathPtr); | ||
| log("realpath", { path }); | ||
| const resolvedPath = fs.realpathSync(path); | ||
| return send.string(resolvedPath, { ptr: resolvedPathPtr, len: 4096 }); | ||
| } | ||
| catch (err) { | ||
| log("realpath error ", err); | ||
| // It can be normal to check for a file that doesn't exist only console.warn in case of low level debugging. | ||
| // console.warn("ERROR", err); | ||
| // return 0 to indicate error, NOT -1! | ||
| return 0; | ||
| } | ||
| }, | ||
| /* | ||
| We need mkstemp since it used in editline/readline.c to do history file truncation. | ||
| (Python doesn't use this since it has its own implementation.) | ||
| */ | ||
| // Commented out since we have a C implementation in stdlib.c; the one below should work fine though...? | ||
| /* | ||
| mkstemp: (templatePtr: number): number => { | ||
| let template = recv.string(templatePtr); | ||
| // template ends in XXXXXX | ||
| if (template.slice(-6) != "XXXXXX") { | ||
| throw Error("template must end in XXXXXX"); | ||
| } | ||
| // the algorithm in musl is to try 100 randomizations of the last 6 characters | ||
| let retries = 100; | ||
| while (retries > 0) { | ||
| // See https://stackoverflow.com/questions/1349404/generate-random-string-characters-in-javascript | ||
| template = | ||
| template.slice(0, -6) + | ||
| (Math.random().toString(36) + "00000000000000000").slice(2, 8); | ||
| try { | ||
| return fs.openSync( | ||
| template, | ||
| fs.constants?.O_RDWR | fs.constants?.O_CREAT | fs.constants?.O_EXCL, | ||
| 0o600 | ||
| ); | ||
| } catch (err) { | ||
| retries -= 1; | ||
| if (retries == 0) { | ||
| console.warn(err); | ||
| } | ||
| } | ||
| } | ||
| // failed | ||
| return -1; | ||
| }, | ||
| */ | ||
| }; | ||
| } | ||
| exports.default = stdlib; | ||
| //# sourceMappingURL=stdlib.js.map |
| {"version":3,"file":"stdlib.js","sourceRoot":"","sources":["../../../src/wasm/posix/stdlib.ts"],"names":[],"mappings":"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"} |
| export default function termios({ posix, recv, send, wasi, noStdio }: { | ||
| posix: any; | ||
| recv: any; | ||
| send: any; | ||
| wasi: any; | ||
| noStdio: any; | ||
| }): { | ||
| tcgetattr(wasi_fd: number, tioPtr: number): number; | ||
| tcsetattr(wasi_fd: number, _optional_actions: number, tioPtr: number): number; | ||
| tcdrain(): number; | ||
| tcflow(): number; | ||
| tcflush(): number; | ||
| tcsendbreak(): number; | ||
| }; |
| "use strict"; | ||
| /* | ||
| RANDOM NOTES | ||
| MAJOR TODO: For xterm.js entirely in browser (and MS Windows), we may still | ||
| have to implement this stuff. Hopefully this will be much easier, since we | ||
| implemented everything via our posix-node and can observe what's expected | ||
| by programs. | ||
| Also, for example, one of the flags is | ||
| "ISIG When any of the characters INTR, QUIT, SUSP, or DSUSP are received, generate the corresponding signal." | ||
| and since we are implementing signals and watching characters, of course this is some | ||
| logic that we would do. | ||
| On a POSIX server, a complete and easy option is to directly call the c library via | ||
| an extension module, translating flags back and forth between native and wasi, | ||
| and we do exactly that here. | ||
| Right now on non-POSIX, the following are partially stub functions, but not minimal. | ||
| IMPORTANT! We can't do NOTHING! For example, libedit will | ||
| randomly not work if we do nothing (which drove me crazy for days)! | ||
| This is because of the line | ||
| if (tcgetattr(fileno(rl_instream), &t) != -1 && (t.c_lflag & ECHO) == 0) | ||
| in packages/libedit/build/wasm/src/readline.c. If t.c_lflag doesn't have the ECHO | ||
| flag, then libedit will be totally broken for interactive use. | ||
| We set at least that below for fd=0 and intend to do more (TODO!). | ||
| tcflag_t c_iflag; // input modes | ||
| tcflag_t c_oflag; // output modes | ||
| tcflag_t c_cflag; // control modes | ||
| tcflag_t c_lflag; // local modes | ||
| cc_t c_cc[NCCS]; /; special characters | ||
| I think for us c_lflag is mostly what matters. | ||
| Another key point that is subtle, is we can't just worry about a subset of "official | ||
| posix flags" and forget about the rest. We have to see what was changed at the | ||
| wasi level, then modify exactly what is true natively to match that. This makes | ||
| the code below a bit odd. | ||
| */ | ||
| var __importDefault = (this && this.__importDefault) || function (mod) { | ||
| return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
| }; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| const debug_1 = __importDefault(require("debug")); | ||
| const constants_1 = __importDefault(require("./constants")); | ||
| const log = (0, debug_1.default)("posix:termios"); | ||
| const FLAGS = { | ||
| c_iflag: [ | ||
| "IGNBRK", | ||
| "BRKINT", | ||
| "IGNPAR", | ||
| "PARMRK", | ||
| "INPCK", | ||
| "ISTRIP", | ||
| "INLCR", | ||
| "IGNCR", | ||
| "ICRNL", | ||
| "IXON", | ||
| "IXANY", | ||
| "IXOFF", | ||
| "IMAXBEL", | ||
| "IUTF8", | ||
| ], | ||
| c_oflag: ["OPOST", "ONLCR", "OCRNL", "ONOCR", "ONLRET", "OFILL", "OFDEL"], | ||
| c_cflag: [ | ||
| "CSIZE", | ||
| "CS5", | ||
| "CS6", | ||
| "CS7", | ||
| "CS8", | ||
| "CSTOPB", | ||
| "CREAD", | ||
| "PARENB", | ||
| "PARODD", | ||
| "HUPCL", | ||
| "CLOCAL", | ||
| ], | ||
| c_lflag: [ | ||
| "ISIG", | ||
| "ICANON", | ||
| "ECHO", | ||
| "ECHOE", | ||
| "ECHOK", | ||
| "ECHONL", | ||
| "NOFLSH", | ||
| "TOSTOP", | ||
| "IEXTEN", | ||
| ], | ||
| }; | ||
| function termios({ posix, recv, send, wasi, noStdio }) { | ||
| function termios_set(tioPtr, { c_iflag, c_oflag, c_cflag, c_lflag }) { | ||
| const size = 4; | ||
| send.u32(tioPtr, c_iflag ?? 0); | ||
| send.u32(tioPtr + size, c_oflag ?? 0); | ||
| send.u32(tioPtr + 2 * size, c_cflag ?? 0); | ||
| send.u32(tioPtr + 3 * size, c_lflag ?? 0); | ||
| } | ||
| function termios_get(tioPtr) { | ||
| const size = 4; | ||
| return { | ||
| c_iflag: recv.u32(tioPtr), | ||
| c_oflag: recv.u32(tioPtr + size), | ||
| c_cflag: recv.u32(tioPtr + 2 * size), | ||
| c_lflag: recv.u32(tioPtr + 3 * size), | ||
| }; | ||
| } | ||
| function native_to_wasi(tio_native) { | ||
| // now translate the flags from native to WASI | ||
| const tio_wasi = { | ||
| c_iflag: 0, | ||
| c_oflag: 0, | ||
| c_cflag: 0, | ||
| c_lflag: 0, | ||
| }; | ||
| let s = []; | ||
| for (const key in tio_native) { | ||
| tio_wasi[key] = 0; | ||
| for (const name of FLAGS[key]) { | ||
| if (tio_native[key] & posix.constants[name]) { | ||
| tio_wasi[key] |= constants_1.default[name]; | ||
| if (log.enabled) { | ||
| s.push(name); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| if (log.enabled) { | ||
| s.sort(); | ||
| log("NATIVE: ", s.join(" ")); | ||
| } | ||
| return tio_wasi; | ||
| } | ||
| /* | ||
| // this doesn't end up getting used, so commented out. | ||
| function wasi_to_native(tio_wasi: Termios): Termios { | ||
| const tio_native: Termios = { | ||
| c_iflag: 0, | ||
| c_oflag: 0, | ||
| c_cflag: 0, | ||
| c_lflag: 0, | ||
| }; | ||
| // let s: string[] = []; | ||
| for (const key in FLAGS) { | ||
| tio_native[key] = 0; | ||
| for (const name of FLAGS[key]) { | ||
| if (tio_wasi[key] & constants[name]) { | ||
| tio_native[key] |= posix.constants[name]; | ||
| // s.push(name); | ||
| } | ||
| } | ||
| } | ||
| // s.sort(); | ||
| //console.log(s.join(" ")); | ||
| //require("fs").appendFileSync("/tmp/log", s + "\n"); | ||
| return tio_native; | ||
| } | ||
| */ | ||
| return { | ||
| /* | ||
| These two functions are critical to applications that use | ||
| the terminal. They do a huge amount in a traditional POSIX system, | ||
| e.g., setting baud rates, ICANON mode, echo, etc. | ||
| I think xterm.js is orthogonal to this; it just reflects how the | ||
| underlying terminal behaves. | ||
| int | ||
| tcgetattr(int fildes, struct termios *termios_p); | ||
| int | ||
| tcsetattr(int fildes, int optional_actions, | ||
| const struct termios *termios_p); | ||
| */ | ||
| tcgetattr(wasi_fd, tioPtr) { | ||
| const fd = wasi.FD_MAP.get(wasi_fd).real; | ||
| let tio_wasi; | ||
| let tio_native; | ||
| if (!noStdio && posix.tcgetattr != null) { | ||
| tio_native = posix.tcgetattr(fd); | ||
| // now translate the flags from native to WASI | ||
| tio_wasi = native_to_wasi(tio_native); | ||
| } | ||
| else { | ||
| tio_native = {}; // just for logging below | ||
| if (fd == 0 || fd == 1) { | ||
| // I copied this from running it and observing. | ||
| // NO MATTER what we must c_lflag: constants.ECHO as below, though maybe | ||
| // having everything is better. | ||
| tio_wasi = { | ||
| c_iflag: 27906, | ||
| c_oflag: 5, | ||
| c_cflag: 1200, | ||
| c_lflag: 32827, | ||
| }; | ||
| // // stdin - do something to avoid total disaster (see comment in header) | ||
| // tio_wasi = { | ||
| // c_iflag: 0, | ||
| // c_oflag: 0, | ||
| // c_cflag: 0, | ||
| // c_lflag: constants.ECHO, // at least this is needed or nothing will work. | ||
| // }; | ||
| } | ||
| else { | ||
| tio_wasi = { | ||
| c_iflag: 0, | ||
| c_oflag: 0, | ||
| c_cflag: 0, | ||
| c_lflag: 0, | ||
| }; | ||
| } | ||
| } | ||
| //console.log("tcgetattr", { wasi_fd, fd, tio_wasi, tio_native }); | ||
| //console.log("GET"); | ||
| //wasi_to_native(tio_wasi); | ||
| termios_set(tioPtr, tio_wasi); | ||
| return 0; | ||
| }, | ||
| tcsetattr(wasi_fd, _optional_actions, // ignored (involves buffering and when change happens) | ||
| tioPtr) { | ||
| const fd = wasi.FD_MAP.get(wasi_fd).real; | ||
| const tio_wasi = termios_get(tioPtr); | ||
| if (noStdio || posix.tcsetattr == null || posix.tcgetattr == null) { | ||
| return 0; | ||
| } | ||
| const tio_native = posix.tcgetattr(fd); | ||
| const tio_native_orig = { ...tio_native }; | ||
| const tio_wasi_current = native_to_wasi(tio_native); | ||
| // We change in native **exactly** what they changed, leaving everything | ||
| // else the same. | ||
| let somethingChanged = false; | ||
| for (const key in FLAGS) { | ||
| for (const name of FLAGS[key]) { | ||
| if ((tio_wasi[key] & constants_1.default[name]) != | ||
| (tio_wasi_current[key] & constants_1.default[name])) { | ||
| // name was changed | ||
| somethingChanged = true; | ||
| if (tio_wasi[key] & constants_1.default[name]) { | ||
| // set it | ||
| tio_native[key] |= posix.constants[name]; | ||
| } | ||
| else { | ||
| // unset it | ||
| tio_native[key] &= ~posix.constants[name]; | ||
| } | ||
| } | ||
| } | ||
| } | ||
| if (!somethingChanged) { | ||
| log("tcsetattr: nothing changed"); | ||
| return 0; | ||
| } | ||
| log("tcsetattr", { fd, tio_native, tio_native_orig }); | ||
| posix.tcsetattr(fd, posix.constants.TCSANOW, tio_native); | ||
| return 0; | ||
| }, | ||
| // These are stubs for now: | ||
| // int tcdrain(int fildes); | ||
| tcdrain() { | ||
| log("tcdrain - STUB"); | ||
| return 0; | ||
| }, | ||
| // int tcflow(int fildes, int action); | ||
| tcflow() { | ||
| log("tcflow - STUB"); | ||
| return 0; | ||
| }, | ||
| // int tcflush(int fildes, int action); | ||
| tcflush() { | ||
| log("tcflush - STUB"); | ||
| return 0; | ||
| }, | ||
| // int tcsendbreak(int fildes, int duration); | ||
| tcsendbreak() { | ||
| log("tcsendbreak - STUB"); | ||
| return 0; | ||
| }, | ||
| }; | ||
| } | ||
| exports.default = termios; | ||
| //# sourceMappingURL=termios.js.map |
| {"version":3,"file":"termios.js","sourceRoot":"","sources":["../../../src/wasm/posix/termios.ts"],"names":[],"mappings":"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"} |
| export default function time({ child_process, memory, os }: { | ||
| child_process: any; | ||
| memory: any; | ||
| os: any; | ||
| }): { | ||
| adjtime(): void; | ||
| settimeofday(): void; | ||
| clock_settime(_clk_id: number, timespec: number): number; | ||
| }; |
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| const dateFormat = require("date-format"); | ||
| const util_1 = require("./util"); | ||
| function time({ child_process, memory, os }) { | ||
| return { | ||
| // int adjtime (const struct timeval *, struct timeval *); | ||
| adjtime() { | ||
| // TODO: similar to clock_settime below... but really maybe not necessary since | ||
| // cowasm should be pretty sandboxed! | ||
| (0, util_1.notImplemented)("TODO: implement adjtime"); | ||
| }, | ||
| settimeofday() { | ||
| (0, util_1.notImplemented)("TODO: settimeofday"); | ||
| }, | ||
| // int clock_settime(clockid_t clk_id, const struct timespec *tp); | ||
| clock_settime(_clk_id, timespec) { | ||
| if (child_process.spawnSync == null) { | ||
| throw Error("clock_settime is not supported on this platform"); | ||
| } | ||
| // NOTE: We assume the clk_id is CLOCK_REALTIME without a check. | ||
| const view = new DataView(memory.buffer); | ||
| const tv_sec = view.getUint32(timespec, true); | ||
| // we ignore nanoseconds here; the date commands aren't that precise anyways. | ||
| let cmd, cmd2 = "", args, args2 = []; | ||
| switch (os.platform?.()) { | ||
| case "darwin": | ||
| // date -f "%s" "1660173350" # <-- number of seconds. | ||
| cmd = "date"; | ||
| args = ["-f", "%s", `${tv_sec}`]; | ||
| break; | ||
| case "linux": | ||
| // date --date='@2147483647' # <-- number of seconds | ||
| cmd = "date"; | ||
| args = [`--set=@${tv_sec}`]; | ||
| break; | ||
| case "win32": | ||
| const dateTime = new Date(1000 * tv_sec); | ||
| cmd = "date"; | ||
| args = [dateFormat("m/d/yyyy", dateTime)]; | ||
| cmd2 = "time"; | ||
| args = [dateFormat("HH:MM:ss", dateTime)]; | ||
| break; | ||
| default: | ||
| throw Error(`clock_settime not supported on platform = ${os.platform?.()}`); | ||
| } | ||
| const { status, stderr } = child_process.spawnSync(cmd, args); | ||
| if (status) { | ||
| throw Error(`clock_settime failed - ${stderr}`); | ||
| } | ||
| if (cmd2) { | ||
| const { status, stderr } = child_process.spawnSync(cmd2, args2); | ||
| if (status) { | ||
| throw Error(`clock_settime failed - ${stderr}`); | ||
| } | ||
| } | ||
| return 0; | ||
| }, | ||
| }; | ||
| } | ||
| exports.default = time; | ||
| //# sourceMappingURL=time.js.map |
| {"version":3,"file":"time.js","sourceRoot":"","sources":["../../../src/wasm/posix/time.ts"],"names":[],"mappings":";;AAAA,MAAM,UAAU,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;AAC1C,iCAAwC;AAExC,SAAwB,IAAI,CAAC,EAAE,aAAa,EAAE,MAAM,EAAE,EAAE,EAAE;IACxD,OAAO;QACL,0DAA0D;QAC1D,OAAO;YACL,+EAA+E;YAC/E,qCAAqC;YACrC,IAAA,qBAAc,EAAC,yBAAyB,CAAC,CAAC;QAC5C,CAAC;QACD,YAAY;YACV,IAAA,qBAAc,EAAC,oBAAoB,CAAC,CAAC;QACvC,CAAC;QACD,kEAAkE;QAClE,aAAa,CAAC,OAAe,EAAE,QAAgB;YAC7C,IAAI,aAAa,CAAC,SAAS,IAAI,IAAI,EAAE;gBACnC,MAAM,KAAK,CAAC,iDAAiD,CAAC,CAAC;aAChE;YACD,gEAAgE;YAEhE,MAAM,IAAI,GAAG,IAAI,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YACzC,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;YAC9C,6EAA6E;YAE7E,IAAI,GAAG,EACL,IAAI,GAAG,EAAE,EACT,IAAI,EACJ,KAAK,GAAG,EAAE,CAAC;YAEb,QAAQ,EAAE,CAAC,QAAQ,EAAE,EAAE,EAAE;gBACvB,KAAK,QAAQ;oBACX,sDAAsD;oBACtD,GAAG,GAAG,MAAM,CAAC;oBACb,IAAI,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,MAAM,EAAE,CAAC,CAAC;oBACjC,MAAM;gBACR,KAAK,OAAO;oBACV,oDAAoD;oBACpD,GAAG,GAAG,MAAM,CAAC;oBACb,IAAI,GAAG,CAAC,UAAU,MAAM,EAAE,CAAC,CAAC;oBAC5B,MAAM;gBACR,KAAK,OAAO;oBACV,MAAM,QAAQ,GAAG,IAAI,IAAI,CAAC,IAAI,GAAG,MAAM,CAAC,CAAC;oBACzC,GAAG,GAAG,MAAM,CAAC;oBACb,IAAI,GAAG,CAAC,UAAU,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC,CAAC;oBAC1C,IAAI,GAAG,MAAM,CAAC;oBACd,IAAI,GAAG,CAAC,UAAU,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC,CAAC;oBAC1C,MAAM;gBACR;oBACE,MAAM,KAAK,CACT,8CAA8C,EAAE,CAAC,QAAQ,EAAE,EAAE,EAAE,CAChE,CAAC;aACL;YACD,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,aAAa,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;YAC9D,IAAI,MAAM,EAAE;gBACV,MAAM,KAAK,CAAC,0BAA0B,MAAM,EAAE,CAAC,CAAC;aACjD;YACD,IAAI,IAAI,EAAE;gBACR,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,aAAa,CAAC,SAAS,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;gBAChE,IAAI,MAAM,EAAE;oBACV,MAAM,KAAK,CAAC,0BAA0B,MAAM,EAAE,CAAC,CAAC;iBACjD;aACF;YACD,OAAO,CAAC,CAAC;QACX,CAAC;KACF,CAAC;AACJ,CAAC;AA/DD,uBA+DC"} |
| export default function unistd(context: any): { | ||
| chown: (pathPtr: number, uid: number, gid: number) => -1 | 0; | ||
| lchown: (pathPtr: number, uid: number, gid: number) => -1 | 0; | ||
| _fchown: (fd: number, uid: number, gid: number) => number; | ||
| getuid: () => any; | ||
| getgid: () => any; | ||
| _geteuid: () => any; | ||
| getegid: () => any; | ||
| getgroups: (gidsetsize: any, grouplistPtr: any) => number; | ||
| getpid: () => any; | ||
| getpgid: (pid: number) => number; | ||
| setpgid: (pid: number, pgid: number) => number; | ||
| getpgrp: () => number; | ||
| nice: (incr: number) => void; | ||
| getpriority: (which: number, who: number) => number; | ||
| setpriority: (which: number, who: number, value: number) => number; | ||
| dup: (oldfd: number) => number; | ||
| dup2: (oldfd: number, newfd: number) => number; | ||
| sync: () => void; | ||
| setuid: () => never; | ||
| seteuid: (uid: number) => number; | ||
| setegid: (gid: number) => number; | ||
| setgid: (gid: number) => number; | ||
| setsid: (sid: any) => any; | ||
| getsid: () => void; | ||
| setreuid: (uid: any) => number; | ||
| setregid: (gid: any) => number; | ||
| getppid: () => any; | ||
| setgroups: () => void; | ||
| setpgrp: () => void; | ||
| tcgetpgrp: () => void; | ||
| tcsetpgrp: () => void; | ||
| fork: () => any; | ||
| fork1: () => void; | ||
| vfork: () => any; | ||
| forkpty: () => void; | ||
| getlogin: () => number; | ||
| gethostname: (namePtr: number, len: number) => number; | ||
| sethostname: (namePtr: number, len: number) => number; | ||
| ttyname: (fd: number) => number; | ||
| ttyname_r: (fd: number, ptr: number, len: number) => number; | ||
| alarm: (seconds: number) => number; | ||
| getresuid: (ruidPtr: number, euidPtr: number, suidPtr: number) => number; | ||
| getresgid: (rgidPtr: number, egidPtr: number, sgidPtr: number) => number; | ||
| setresuid: (ruid: number, euid: number, suid: number) => number; | ||
| setresgid: (rgid: number, egid: number, sgid: number) => number; | ||
| execve: (pathnamePtr: number, argvPtr: number, envpPtr: number) => number; | ||
| execv: (pathnamePtr: number, argvPtr: number) => number; | ||
| execvp: (filePtr: number, argvPtr: number) => number; | ||
| execlp: () => void; | ||
| fexecve: (fd: number, argvPtr: number, envpPtr: number) => number; | ||
| pipe: (pipefdPtr: number) => number; | ||
| pipe2: (pipefdPtr: number, flags: number) => number; | ||
| lockf: (fd: number, cmd: number, size: number) => number; | ||
| pause: () => number; | ||
| initgroups: (userPtr: number, group: number) => number; | ||
| getgrouplist: (userPtr: number, group: number, groupPtr: number, ngroupsPtr: number) => number; | ||
| fchdir: (fd: number) => number; | ||
| fcntlSetFlags: (fd: number, flags: number) => number; | ||
| }; |
| "use strict"; | ||
| var __importDefault = (this && this.__importDefault) || function (mod) { | ||
| return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
| }; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| const util_1 = require("./util"); | ||
| const constants_1 = __importDefault(require("./constants")); | ||
| const debug_1 = __importDefault(require("debug")); | ||
| const wasi_js_1 = require("wasi-js"); | ||
| const log = (0, debug_1.default)("posix:unistd"); | ||
| function unistd(context) { | ||
| const { fs, os, process, recv, send, wasi, posix, memory, callWithString } = context; | ||
| // TODO: this doesn't throw an error yet if the target filesystem isn't native. | ||
| function toNativeFd(fd) { | ||
| // OBVIOUSLY -- these functions won't work if the target | ||
| // is in a wasi memfs, since the host posix libc knows nothing about that. | ||
| // We do translate file descriptors at least. | ||
| // Do we need to check and throw an error if target path isn't native? | ||
| // Of course, that will happen anyways since the syscall will immediately | ||
| // reject the invalid file descriptor anyways. | ||
| const x = wasi.FD_MAP.get(fd); | ||
| if (x == null) { | ||
| throw Error("invalid file descriptor"); | ||
| } | ||
| return x.real; | ||
| } | ||
| // We use the rights from stdin and stdout when making | ||
| // a pipe. These can get closed after startup (e.g., in | ||
| // the test_subprocess.py cpython tests), so we have to | ||
| // make a copy here. This also avoids having to keep a data | ||
| // structure in sync with wasi-js. | ||
| const STDIN = wasi.FD_MAP.get(0); | ||
| const STDOUT = wasi.FD_MAP.get(1); | ||
| const unistd = { | ||
| chown: (pathPtr, uid, gid) => { | ||
| const path = recv.string(pathPtr); | ||
| fs.chownSync(path, uid, gid); | ||
| return 0; | ||
| }, | ||
| lchown: (pathPtr, uid, gid) => { | ||
| const path = recv.string(pathPtr); | ||
| fs.lchownSync(path, uid, gid); | ||
| return 0; | ||
| }, | ||
| // int fchown(int fd, uid_t owner, gid_t group); | ||
| _fchown: (fd, uid, gid) => { | ||
| if (uid == 0 || gid == 0) { | ||
| // if either is 0 = root, we just do nothing. | ||
| // TODO: We really need to get rid of anything that involves uid/gid, which | ||
| // just doesn't make sense for the model of WASM. | ||
| return 0; | ||
| } | ||
| fs.fchownSync(toNativeFd(fd), uid, gid); | ||
| return 0; | ||
| }, | ||
| getuid: () => process.getuid?.() ?? 0, | ||
| getgid: () => process.getgid?.() ?? 0, | ||
| _geteuid: () => process.geteuid?.() ?? 0, | ||
| getegid: () => process.getegid?.() ?? 0, | ||
| // int getgroups(int gidsetsize, gid_t grouplist[]); | ||
| // in WASI, "typedef unsigned gid_t" | ||
| getgroups: (gidsetsize, grouplistPtr) => { | ||
| const groups = process.getgroups?.(); | ||
| if (groups == null) { | ||
| return 0; // no groups | ||
| } | ||
| if (gidsetsize == 0) { | ||
| // yep, we end up computing getgroups twice, since the | ||
| // posix api is a bit awkward... | ||
| return groups.length; | ||
| } | ||
| const count = Math.min(groups.length, gidsetsize); | ||
| if (count == 0) { | ||
| return 0; | ||
| } | ||
| const view = new DataView(memory.buffer); | ||
| for (let i = 0; i < count; i++) { | ||
| view.setUint32(grouplistPtr + 4 * i, groups[i], true); | ||
| } | ||
| return count; | ||
| }, | ||
| getpid: () => process.pid ?? 1, | ||
| getpgid: (pid) => { | ||
| return posix.getpgid?.(pid) ?? 1; | ||
| }, | ||
| // int setpgid(pid_t pid, pid_t pgid); | ||
| setpgid: (pid, pgid) => { | ||
| if (posix.setpgid == null) { | ||
| (0, util_1.notImplemented)("setpgid"); | ||
| } | ||
| posix.setpgid(pid, pgid); | ||
| return 0; // success | ||
| }, | ||
| getpgrp: () => { | ||
| return posix.getpgrp?.() ?? 1; | ||
| }, | ||
| nice: (incr) => { | ||
| const p = os.getPriority?.(); | ||
| if (p != null) { | ||
| os.setPriority?.(p + incr); | ||
| } | ||
| }, | ||
| // int getpriority(int which, id_t who); | ||
| getpriority: (which, who) => { | ||
| if (os.getPriority == null) { | ||
| // environ with no info about processes (e.g., browser). | ||
| return 0; | ||
| } | ||
| if (which != 0) { | ||
| console.warn("getpriority can only be implemented in node.js for *process id*"); | ||
| return 0; // minimal info. | ||
| } | ||
| return os.getPriority?.(who); | ||
| }, | ||
| // int setpriority(int which, id_t who, int value); | ||
| setpriority: (which, who, value) => { | ||
| if (os.setPriority == null) { | ||
| // environ with no info about processes (e.g., browser). | ||
| return 0; | ||
| } | ||
| if (which != 0) { | ||
| console.warn("setpriority can only be implemented in node.js for *process id*"); | ||
| return -1; | ||
| } | ||
| return os.setPriority?.(who, value); | ||
| }, | ||
| // int dup(int oldfd); | ||
| dup: (oldfd) => { | ||
| if (posix.dup == null) { | ||
| (0, util_1.notImplemented)("dup"); | ||
| } | ||
| // Considered in 2022, but closed by node developers: https://github.com/libuv/libuv/issues/3448#issuecomment-1174786218 | ||
| const x = wasi.FD_MAP.get(oldfd); | ||
| const newfd_real = posix.dup(x.real); | ||
| const newfd = wasi.getUnusedFileDescriptor(); | ||
| wasi.FD_MAP.set(newfd, { ...x, real: newfd_real }); | ||
| return newfd; | ||
| }, | ||
| // int dup2(int oldfd, int newfd); | ||
| dup2: (oldfd, newfd) => { | ||
| if (posix.dup2 == null) { | ||
| (0, util_1.notImplemented)("dup2"); | ||
| } | ||
| const x_old = wasi.FD_MAP.get(oldfd); | ||
| let x_new; | ||
| // I'm not 100% happy with this. | ||
| if (wasi.FD_MAP.has(newfd)) { | ||
| x_new = wasi.FD_MAP.get(newfd).real ?? newfd; | ||
| } | ||
| else { | ||
| x_new = newfd; | ||
| } | ||
| const newfd_real = posix.dup2(x_old.real, x_new); | ||
| wasi.FD_MAP.set(newfd, { ...x_old, real: newfd_real }); | ||
| return newfd; | ||
| }, | ||
| sync: () => { | ||
| // nodejs doesn't expose sync, but it does expose fsync for a file descriptor, so we call it on | ||
| // all the open file descriptors | ||
| if (fs.fsyncSync == null) | ||
| return; | ||
| for (const [_, { real }] of wasi.FD_MAP) { | ||
| fs.fsyncSync(real); | ||
| } | ||
| }, | ||
| // In nodejs these set*id function can't be done in a worker thread: | ||
| // https://nodejs.org/api/process.html#processsetgidid | ||
| // TODO: maybe we should implement these by sending a message to | ||
| // the main thread requesting to do them? For now, you'll get | ||
| // an error unless you run in a mode without a worker thread. | ||
| setuid: () => { | ||
| throw Error("setuid is not supported"); | ||
| }, | ||
| seteuid: (uid) => { | ||
| if (posix.seteuid == null) { | ||
| (0, util_1.notImplemented)("seteuid"); | ||
| } | ||
| posix.seteuid(uid); | ||
| return 0; | ||
| }, | ||
| setegid: (gid) => { | ||
| if (posix.setegid == null) { | ||
| (0, util_1.notImplemented)("setegid"); | ||
| } | ||
| posix.setegid(gid); | ||
| return 0; | ||
| }, | ||
| setgid: (gid) => { | ||
| if (process.setgid == null) { | ||
| (0, util_1.notImplemented)("setgid"); | ||
| } | ||
| process.setgid(gid); | ||
| return 0; | ||
| }, | ||
| setsid: (sid) => { | ||
| if (posix.setsid == null) { | ||
| (0, util_1.notImplemented)("setsid"); | ||
| } | ||
| return posix.setsid(sid); | ||
| }, | ||
| // TODO! | ||
| getsid: () => { | ||
| (0, util_1.notImplemented)("getsid"); | ||
| }, | ||
| setreuid: (uid) => { | ||
| if (posix.setreuid == null) { | ||
| (0, util_1.notImplemented)("setreuid"); | ||
| } | ||
| posix.setreuid(uid); | ||
| return 0; | ||
| }, | ||
| setregid: (gid) => { | ||
| if (posix.setregid == null) { | ||
| (0, util_1.notImplemented)("setregid"); | ||
| } | ||
| posix.setregid(gid); | ||
| return 0; | ||
| }, | ||
| getppid: () => { | ||
| if (posix.getppid == null) { | ||
| // in browser -- only one process id: | ||
| return unistd.getpid(); | ||
| } | ||
| return posix.getppid(); | ||
| }, | ||
| setgroups: () => { | ||
| (0, util_1.notImplemented)("setgroups"); | ||
| }, | ||
| setpgrp: () => { | ||
| (0, util_1.notImplemented)("setpgrp"); | ||
| }, | ||
| tcgetpgrp: () => { | ||
| (0, util_1.notImplemented)("tcgetpgrp"); | ||
| }, | ||
| tcsetpgrp: () => { | ||
| (0, util_1.notImplemented)("tcsetpgrp"); | ||
| }, | ||
| fork: () => { | ||
| if (posix.fork == null) { | ||
| (0, util_1.notImplemented)("fork"); | ||
| } | ||
| const pid = posix.fork(); | ||
| if (pid == 0) { | ||
| // we end the event loop in the child, because hopefully usually anything | ||
| // that is using fork is about to exec* anyways. It seems that trying | ||
| // to actually use the Node.js event loop after forking tends to randomly | ||
| // hang, so isn't really viable. | ||
| posix.close_event_loop?.(); | ||
| } | ||
| return pid; | ||
| }, | ||
| fork1: () => { | ||
| (0, util_1.notImplemented)("fork1"); | ||
| }, | ||
| vfork: () => { | ||
| // "this system call behaves identically to the fork(2) system call, except without | ||
| // calling any handlers registered with pthread_atfork(2)." | ||
| return unistd.fork(); | ||
| }, | ||
| forkpty: () => { | ||
| (0, util_1.notImplemented)("forkpty"); | ||
| }, | ||
| getlogin: () => { | ||
| if (context.state.getlogin_ptr != null) | ||
| return context.state.getlogin_ptr; | ||
| // returns the username of the signed in user; if not available, e.g., | ||
| // in a browser, returns "user". | ||
| const username = os.userInfo?.()?.username ?? "user"; | ||
| return (context.state.getlogin_ptr = send.string(username)); | ||
| }, | ||
| // int gethostname(char *name, size_t len); | ||
| gethostname: (namePtr, len) => { | ||
| if (os.hostname == null) { | ||
| throw Error("gethostname not supported on this platform"); | ||
| } | ||
| const name = os.hostname(); | ||
| send.string(name, { ptr: namePtr, len }); | ||
| return 0; | ||
| }, | ||
| // int sethostname(const char *name, size_t len); | ||
| sethostname: (namePtr, len) => { | ||
| if (posix.sethostname == null) { | ||
| throw Error("sethostname not supported on this platform"); | ||
| } | ||
| const name = recv.string(namePtr, len); | ||
| posix.sethostname(name); | ||
| return 0; | ||
| }, | ||
| // char *ttyname(int fd); | ||
| ttyname: (fd) => { | ||
| if (posix.ttyname == null) { | ||
| throw Error("ttyname_r is not supported on this platform"); | ||
| } | ||
| if (context.state.ttyname_ptr != null) | ||
| return context.state.ttyname_ptr; | ||
| const len = 128; | ||
| context.state.ttyname_ptr = send.malloc(len); | ||
| send.string(posix.ttyname(fd), { ptr: context.state.ttyname_ptr, len }); | ||
| return context.state.ttyname_ptr; | ||
| }, | ||
| // int ttyname_r(int fd, char *buf, size_t buflen); | ||
| ttyname_r: (fd, ptr, len) => { | ||
| if (posix.ttyname == null) { | ||
| throw Error("ttyname_r is not supported on this platform"); | ||
| } | ||
| send.string(posix.ttyname(fd), { ptr, len }); | ||
| return 0; | ||
| }, | ||
| alarm: (seconds) => { | ||
| if (posix.alarm == null) { | ||
| throw Error("alarm is not supported on this platform"); | ||
| } | ||
| return posix.alarm(seconds); | ||
| }, | ||
| // The following 4 are actually only available on a Linux host, | ||
| // though wasi-musl defines them, | ||
| // so cpython-wasm thinks they exist. | ||
| // For CoWasm, let's just make these no-ops when not available, | ||
| // since they are about multiple users, which we shouldn't | ||
| // support in WASM. | ||
| getresuid: (ruidPtr, euidPtr, suidPtr) => { | ||
| let ruid, euid, suid; | ||
| if (posix.getresuid == null) { | ||
| ruid = euid = suid = 0; | ||
| } | ||
| else { | ||
| ({ ruid, euid, suid } = posix.getresuid()); | ||
| } | ||
| const view = new DataView(memory.buffer); | ||
| view.setUint32(ruidPtr, ruid, true); | ||
| view.setUint32(euidPtr, euid, true); | ||
| view.setUint32(suidPtr, suid, true); | ||
| return 0; | ||
| }, | ||
| getresgid: (rgidPtr, egidPtr, sgidPtr) => { | ||
| let rgid, egid, sgid; | ||
| if (posix.getresgid == null) { | ||
| rgid = egid = sgid = 0; | ||
| } | ||
| else { | ||
| ({ rgid, egid, sgid } = posix.getresgid()); | ||
| } | ||
| const view = new DataView(memory.buffer); | ||
| view.setUint32(rgidPtr, rgid, true); | ||
| view.setUint32(egidPtr, egid, true); | ||
| view.setUint32(sgidPtr, sgid, true); | ||
| return 0; | ||
| }, | ||
| setresuid: (ruid, euid, suid) => { | ||
| if (posix.setresuid != null) { | ||
| posix.setresuid(ruid, euid, suid); | ||
| } | ||
| return 0; | ||
| }, | ||
| setresgid: (rgid, egid, sgid) => { | ||
| if (posix.setresgid != null) { | ||
| posix.setresgid(rgid, egid, sgid); | ||
| } | ||
| return 0; | ||
| }, | ||
| // int execve(const char *pathname, char *const argv[], char *const envp[]); | ||
| execve: (pathnamePtr, argvPtr, envpPtr) => { | ||
| if (posix._execve == null) { | ||
| (0, util_1.notImplemented)("execve"); | ||
| } | ||
| const pathname = recv.string(pathnamePtr); | ||
| const argv = recv.arrayOfStrings(argvPtr); | ||
| const envp = recv.arrayOfStrings(envpPtr); | ||
| log("execve", pathname, argv, envp); | ||
| posix._execve(pathname, argv, envp); | ||
| return 0; // this won't happen because execve takes over, or there's an error | ||
| }, | ||
| execv: (pathnamePtr, argvPtr) => { | ||
| if (posix.execv == null) { | ||
| (0, util_1.notImplemented)("execv"); | ||
| } | ||
| const pathname = recv.string(pathnamePtr); | ||
| const argv = recv.arrayOfStrings(argvPtr); | ||
| log("execv", pathname, argv); | ||
| posix.execv(pathname, argv); | ||
| return 0; // this won't happen because execv takes over | ||
| }, | ||
| // execvp is like execv but takes the filename rather than the path. | ||
| // int execvp(const char *file, char *const argv[]); | ||
| execvp: (filePtr, argvPtr) => { | ||
| if (posix.execvp == null) { | ||
| (0, util_1.notImplemented)("execvp"); | ||
| } | ||
| const file = recv.string(filePtr); | ||
| const argv = recv.arrayOfStrings(argvPtr); | ||
| log("execvp", file, argv); | ||
| posix.execvp(file, argv); | ||
| return 0; // this won't happen because execvp takes over | ||
| }, | ||
| // execlp is so far only by libedit to launch vim to edit | ||
| // the history. So it's safe to just disable. Python doesn't | ||
| // use this at all. | ||
| execlp: () => { | ||
| (0, util_1.notImplemented)("execlp"); | ||
| }, | ||
| /* | ||
| I don't have automated testing for this, since it quits node. | ||
| However, here is what works on Linux. There is no fexecve on macos. | ||
| >>> import os; a = os.open("/bin/ls",os.O_RDONLY | os.O_CREAT) | ||
| >>> os.execve(a,['-l','/'],{}) | ||
| bin dev home media opt root sbin sys usr | ||
| boot etc lib mnt proc run srv tmp var | ||
| */ | ||
| fexecve: (fd, argvPtr, envpPtr) => { | ||
| if (posix._fexecve == null) { | ||
| (0, util_1.notImplemented)("fexecve"); | ||
| } | ||
| const argv = recv.arrayOfStrings(argvPtr); | ||
| const envp = recv.arrayOfStrings(envpPtr); | ||
| posix._fexecve(toNativeFd(fd), argv, envp); | ||
| return 0; // this won't happen because execve takes over | ||
| }, | ||
| // int pipe(int pipefd[2]); | ||
| pipe: (pipefdPtr) => { | ||
| if (posix.pipe == null) { | ||
| (0, util_1.notImplemented)("pipe"); | ||
| } | ||
| const { readfd, writefd } = posix.pipe(); | ||
| // readfd and writefd are genuine native file descriptors that we just created. | ||
| const wasi_readfd = wasi.getUnusedFileDescriptor(); | ||
| wasi.FD_MAP.set(wasi_readfd, { | ||
| real: readfd, | ||
| rights: STDIN.rights, | ||
| filetype: wasi_js_1.constants.WASI_FILETYPE_SOCKET_STREAM, | ||
| }); | ||
| const wasi_writefd = wasi.getUnusedFileDescriptor(); | ||
| wasi.FD_MAP.set(wasi_writefd, { | ||
| real: writefd, | ||
| rights: STDOUT.rights, | ||
| filetype: wasi_js_1.constants.WASI_FILETYPE_SOCKET_STREAM, | ||
| }); | ||
| send.i32(pipefdPtr, wasi_readfd); | ||
| send.i32(pipefdPtr + 4, wasi_writefd); | ||
| return 0; | ||
| }, | ||
| pipe2: (pipefdPtr, flags) => { | ||
| if (posix.pipe2 == null) { | ||
| (0, util_1.notImplemented)("pipe2"); | ||
| } | ||
| let nativeFlags = 0; | ||
| if (flags & constants_1.default.O_NONBLOCK) { | ||
| nativeFlags += posix.constants?.O_NONBLOCK ?? 0; | ||
| } | ||
| // NOTE: wasi defined O_CLOEXEC to be 0, which is super annoying. | ||
| // We thus never set it, since otherwise it would always get set. | ||
| /* if (flags & constants.O_CLOEXEC) { | ||
| nativeFlags += posix.constants?.O_CLOEXEC ?? 0; | ||
| }*/ | ||
| const { readfd, writefd } = posix.pipe2(nativeFlags); | ||
| console.warn("pipe2 -- TODO: we almost certainly need to abstract these through our WASI fd object!"); | ||
| send.i32(pipefdPtr, readfd); | ||
| send.i32(pipefdPtr + 4, writefd); | ||
| return 0; | ||
| }, | ||
| lockf: (fd, cmd, size) => { | ||
| const { lockf } = posix; | ||
| if (lockf == null) { | ||
| (0, util_1.notImplemented)("lockf"); | ||
| } | ||
| let cmdNative = undefined; | ||
| for (const x of ["F_ULOCK", "F_LOCK", "F_TLOCK", "F_TEST"]) { | ||
| if (cmd == constants_1.default[x]) { | ||
| cmdNative = posix.constants[x]; | ||
| break; | ||
| } | ||
| } | ||
| if (cmdNative == null) { | ||
| throw Error(`invalid cmd ${cmd}`); | ||
| } | ||
| lockf(toNativeFd(fd), cmdNative, BigInt(size)); | ||
| return 0; | ||
| }, | ||
| pause: () => { | ||
| const { pause } = posix; | ||
| if (pause == null) { | ||
| // this could be implemented in case of worker | ||
| (0, util_1.notImplemented)("pause"); | ||
| } | ||
| return pause(); | ||
| }, | ||
| // initgroups in node, so easier... | ||
| // int initgroups(const char *user, gid_t group); | ||
| initgroups: (userPtr, group) => { | ||
| const { initgroups } = process; | ||
| if (initgroups == null) { | ||
| (0, util_1.notImplemented)("initgroups"); | ||
| } | ||
| const user = recv.string(userPtr); | ||
| initgroups(user, group); | ||
| return 0; | ||
| }, | ||
| // int getgrouplist(const char *user, gid_t group, gid_t *groups, int *ngroups); | ||
| getgrouplist: (userPtr, group, groupPtr, ngroupsPtr) => { | ||
| const { getgrouplist } = posix; | ||
| const user = recv.string(userPtr); | ||
| const ngroups = recv.i32(ngroupsPtr); | ||
| let v; | ||
| if (getgrouplist == null) { | ||
| v = [group]; | ||
| } | ||
| else { | ||
| v = getgrouplist(user, group); | ||
| } | ||
| const k = Math.min(v.length, ngroups); | ||
| for (let i = 0; i < k; i++) { | ||
| send.u32(groupPtr + 4 * i, v[i]); | ||
| } | ||
| send.i32(ngroupsPtr, v.length); | ||
| if (k < v.length) { | ||
| return -1; | ||
| } | ||
| return 0; | ||
| }, | ||
| // just like chdir, but uses a file descriptor. WASI doesn't have it, so we | ||
| // add it. | ||
| fchdir: (fd) => { | ||
| const dir = wasi.FD_MAP.get(fd)?.path; | ||
| if (!dir) { | ||
| console.error(`fchdir: invalid file descriptor: ${fd}`); | ||
| return -1; | ||
| } | ||
| return callWithString("chdir", dir); | ||
| }, | ||
| // This is not a system call exactly. It's used by WASI. | ||
| // It is supposed to "Adjust the flags associated with a file descriptor." | ||
| // and it doesn't acctually just set them because WASI doesn't | ||
| // have a way to get. So what we do is change the three things | ||
| // that can be changed and leave everything else alone! | ||
| fcntlSetFlags: (fd, flags) => { | ||
| if (posix.fcntlSetFlags == null || posix.fcntlGetFlags == null) { | ||
| (0, util_1.notImplemented)("fcntlSetFlags"); | ||
| return 0; | ||
| } | ||
| const real_fd = wasi.FD_MAP.get(fd)?.real; | ||
| if (real_fd == null) { | ||
| throw Error("invalid file descriptor"); | ||
| } | ||
| let current_native_flags = posix.fcntlGetFlags(real_fd); | ||
| let new_native_flags = current_native_flags; | ||
| for (const name of ["O_NONBLOCK", "O_APPEND"]) { | ||
| if (flags & constants_1.default[name]) { | ||
| // do want name | ||
| new_native_flags |= posix.constants[name]; | ||
| } | ||
| else { | ||
| // do not want name | ||
| new_native_flags &= ~posix.constants[name]; | ||
| } | ||
| } | ||
| if (current_native_flags == new_native_flags) { | ||
| log("fcntlSetFlags - unchanged"); | ||
| } | ||
| else { | ||
| log("fcntlSetFlags ", current_native_flags, " to", new_native_flags); | ||
| posix.fcntlSetFlags(real_fd, new_native_flags); | ||
| } | ||
| return 0; | ||
| }, | ||
| }; | ||
| return unistd; | ||
| } | ||
| exports.default = unistd; | ||
| //# sourceMappingURL=unistd.js.map |
| {"version":3,"file":"unistd.js","sourceRoot":"","sources":["../../../src/wasm/posix/unistd.ts"],"names":[],"mappings":"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"} |
| export declare class NotImplementedError extends Error { | ||
| ret: number; | ||
| constructor(functionName: string, ret?: number); | ||
| } | ||
| export declare function notImplemented(functionName: string, ret?: number): void; |
| "use strict"; | ||
| var __importDefault = (this && this.__importDefault) || function (mod) { | ||
| return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
| }; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.notImplemented = exports.NotImplementedError = void 0; | ||
| const debug_1 = __importDefault(require("debug")); | ||
| const log = (0, debug_1.default)("posix"); | ||
| class NotImplementedError extends Error { | ||
| constructor(functionName, ret) { | ||
| super(`${functionName} is not implemented yet`); | ||
| this.name = "NotImplementedError"; // name is a standard exception property. | ||
| if (ret != null) { | ||
| this.ret = ret; | ||
| } | ||
| } | ||
| } | ||
| exports.NotImplementedError = NotImplementedError; | ||
| function notImplemented(functionName, ret = -1) { | ||
| console.warn("WARNING: calling NOT IMPLEMENTED function", functionName); | ||
| log("WARNING: calling NOT IMPLEMENTED function", functionName); | ||
| throw new NotImplementedError(functionName, ret); | ||
| } | ||
| exports.notImplemented = notImplemented; | ||
| //# sourceMappingURL=util.js.map |
| {"version":3,"file":"util.js","sourceRoot":"","sources":["../../../src/wasm/posix/util.ts"],"names":[],"mappings":";;;;;;AAAA,kDAA0B;AAC1B,MAAM,GAAG,GAAG,IAAA,eAAK,EAAC,OAAO,CAAC,CAAC;AAE3B,MAAa,mBAAoB,SAAQ,KAAK;IAE5C,YAAY,YAAoB,EAAE,GAAY;QAC5C,KAAK,CAAC,GAAG,YAAY,yBAAyB,CAAC,CAAC;QAChD,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAC,CAAC,yCAAyC;QAC5E,IAAI,GAAG,IAAI,IAAI,EAAE;YACf,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;SAChB;IACH,CAAC;CACF;AATD,kDASC;AAED,SAAgB,cAAc,CAAC,YAAoB,EAAE,MAAc,CAAC,CAAC;IACnE,OAAO,CAAC,IAAI,CAAC,2CAA2C,EAAE,YAAY,CAAC,CAAC;IACxE,GAAG,CAAC,2CAA2C,EAAE,YAAY,CAAC,CAAC;IAC/D,MAAM,IAAI,mBAAmB,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC;AACnD,CAAC;AAJD,wCAIC"} |
| export default function wait({ posix, send }: { | ||
| posix: any; | ||
| send: any; | ||
| }): { | ||
| wait: (wstatusPtr: number) => number; | ||
| waitid: () => number; | ||
| waitpid: (pid: number, wstatusPtr: number, options: number) => number; | ||
| wait3: (wstatusPtr: number, options: number, rusagePtr: number) => number; | ||
| }; |
| "use strict"; | ||
| var __importDefault = (this && this.__importDefault) || function (mod) { | ||
| return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
| }; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| const util_1 = require("./util"); | ||
| const constants_1 = __importDefault(require("./constants")); | ||
| function wait({ posix, send }) { | ||
| function nativeOptions(options) { | ||
| let native_options = 0; | ||
| for (const option of ["WNOHANG", "WUNTRACED"]) { | ||
| if (options & constants_1.default[option]) { | ||
| native_options |= posix.constants[option]; | ||
| } | ||
| } | ||
| return native_options; | ||
| } | ||
| function wasm_wstatus(wstatus) { | ||
| // TODO -- need to parse status and encode in wstatusPtr correctly. I don't | ||
| // know that wstatus native is the same as wstatus in WASI!!?! | ||
| return wstatus; | ||
| } | ||
| const obj = { | ||
| wait: (wstatusPtr) => { | ||
| if (posix.wait == null) { | ||
| (0, util_1.notImplemented)("wait"); | ||
| } | ||
| const { ret, wstatus } = posix.wait(); | ||
| send.i32(wstatusPtr, wasm_wstatus(wstatus)); | ||
| return ret; | ||
| }, | ||
| waitid: () => { | ||
| // waitid is linux only | ||
| (0, util_1.notImplemented)("waitid"); | ||
| return -1; | ||
| }, | ||
| // pid_t waitpid(pid_t pid, int *wstatus, int options); | ||
| // waitpid(pid: number, options : number) => {status: Status, ret:number} | ||
| waitpid: (pid, wstatusPtr, options) => { | ||
| if (posix.waitpid == null) { | ||
| (0, util_1.notImplemented)("waitpid"); | ||
| } | ||
| // TODO -- need to parse status and encode in wstatusPtr correctly. I don't | ||
| // know that wstatus native is the same as wstatus in WASI!!?! | ||
| const { ret, wstatus } = posix.waitpid(pid, nativeOptions(options)); | ||
| send.i32(wstatusPtr, wasm_wstatus(wstatus)); | ||
| return ret; | ||
| }, | ||
| // pid_t wait3(int *stat_loc, int options, struct rusage *rusage); | ||
| wait3: (wstatusPtr, options, rusagePtr) => { | ||
| if (posix.wait3 == null) { | ||
| (0, util_1.notImplemented)("wait3"); | ||
| } | ||
| if (rusagePtr != 0) { | ||
| console.warn("wait3 not implemented for non-NULL *rusage"); | ||
| (0, util_1.notImplemented)("wait3"); | ||
| } | ||
| const { ret, wstatus } = posix.wait3(nativeOptions(options)); | ||
| send.i32(wstatusPtr, wasm_wstatus(wstatus)); | ||
| return ret; | ||
| }, | ||
| }; | ||
| return obj; | ||
| } | ||
| exports.default = wait; | ||
| //# sourceMappingURL=wait.js.map |
| {"version":3,"file":"wait.js","sourceRoot":"","sources":["../../../src/wasm/posix/wait.ts"],"names":[],"mappings":";;;;;AAAA,iCAAwC;AACxC,4DAAoC;AAEpC,SAAwB,IAAI,CAAC,EAAE,KAAK,EAAE,IAAI,EAAC;IACzC,SAAS,aAAa,CAAC,OAAe;QACpC,IAAI,cAAc,GAAG,CAAC,CAAC;QACvB,KAAK,MAAM,MAAM,IAAI,CAAC,SAAS,EAAE,WAAW,CAAC,EAAE;YAC7C,IAAI,OAAO,GAAG,mBAAS,CAAC,MAAM,CAAC,EAAE;gBAC/B,cAAc,IAAI,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;aAC3C;SACF;QACD,OAAO,cAAc,CAAC;IACxB,CAAC;IAED,SAAS,YAAY,CAAC,OAAe;QACnC,4EAA4E;QAC5E,8DAA8D;QAC9D,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,MAAM,GAAG,GAAG;QACV,IAAI,EAAE,CAAC,UAAkB,EAAU,EAAE;YACnC,IAAI,KAAK,CAAC,IAAI,IAAI,IAAI,EAAE;gBACtB,IAAA,qBAAc,EAAC,MAAM,CAAC,CAAC;aACxB;YACD,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;YACtC,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC;YAC5C,OAAO,GAAG,CAAC;QACb,CAAC;QAED,MAAM,EAAE,GAAW,EAAE;YACnB,uBAAuB;YACvB,IAAA,qBAAc,EAAC,QAAQ,CAAC,CAAC;YACzB,OAAO,CAAC,CAAC,CAAC;QACZ,CAAC;QAED,wDAAwD;QACxD,yEAAyE;QAEzE,OAAO,EAAE,CAAC,GAAW,EAAE,UAAkB,EAAE,OAAe,EAAU,EAAE;YACpE,IAAI,KAAK,CAAC,OAAO,IAAI,IAAI,EAAE;gBACzB,IAAA,qBAAc,EAAC,SAAS,CAAC,CAAC;aAC3B;YACD,4EAA4E;YAC5E,8DAA8D;YAC9D,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC;YACpE,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC;YAC5C,OAAO,GAAG,CAAC;QACb,CAAC;QAED,kEAAkE;QAClE,KAAK,EAAE,CAAC,UAAkB,EAAE,OAAe,EAAE,SAAiB,EAAU,EAAE;YACxE,IAAI,KAAK,CAAC,KAAK,IAAI,IAAI,EAAE;gBACvB,IAAA,qBAAc,EAAC,OAAO,CAAC,CAAC;aACzB;YACD,IAAI,SAAS,IAAI,CAAC,EAAE;gBAClB,OAAO,CAAC,IAAI,CAAC,4CAA4C,CAAC,CAAC;gBAC3D,IAAA,qBAAc,EAAC,OAAO,CAAC,CAAC;aACzB;YACD,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,KAAK,CAAC,KAAK,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC;YAC7D,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC;YAC5C,OAAO,GAAG,CAAC;QACb,CAAC;KACF,CAAC;IACF,OAAO,GAAG,CAAC;AACb,CAAC;AA9DD,uBA8DC"} |
| export default function reuseInFlight(asyncFn: any, config: any): (...args: any[]) => any; |
| "use strict"; | ||
| /* This is from the ISC licensed async-await-utils project, from here: | ||
| https://github.com/masotime/async-await-utils/blob/master/src/hof/reuseInFlight.js | ||
| Including that quite heavy (due to babel dep) project just for this one function | ||
| is a bit much, so I copy/pasted it here. | ||
| */ | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| const DEFAULT_CONFIG = { | ||
| createKey(args) { | ||
| return JSON.stringify(args); | ||
| }, | ||
| ignoreSingleUndefined: false, | ||
| }; | ||
| // for a given Promise-generating function, track each execution by the stringified | ||
| // arguments. if the function is called again with the same arguments, then instead | ||
| // of generating a new promise, an existing in-flight promise is used instead. This | ||
| // prevents unnecessary repetition of async function calls while the same function | ||
| // is still in flight. | ||
| function reuseInFlight(asyncFn, config) { | ||
| config = { | ||
| ...DEFAULT_CONFIG, | ||
| ...(config || {}), | ||
| }; | ||
| const inflight = {}; | ||
| return function debounced(...args) { | ||
| if (config.ignoreSingleUndefined && | ||
| args.length === 1 && | ||
| args[0] === undefined) { | ||
| console.warn("Ignoring single undefined arg (reuseInFlight)"); | ||
| args = []; | ||
| } | ||
| const key = config.createKey(args); | ||
| if (!inflight.hasOwnProperty(key)) { | ||
| // WE DO NOT AWAIT, we are storing the promise itself | ||
| inflight[key] = asyncFn.apply(this, args).then((results) => { | ||
| // self invalidate | ||
| delete inflight[key]; | ||
| return results; | ||
| }, (err) => { | ||
| // still self-invalidate, then rethrow | ||
| delete inflight[key]; | ||
| throw err; | ||
| }); | ||
| } | ||
| return inflight[key]; | ||
| }; | ||
| } | ||
| exports.default = reuseInFlight; | ||
| //# sourceMappingURL=reuseInFlight.js.map |
| {"version":3,"file":"reuseInFlight.js","sourceRoot":"","sources":["../../src/wasm/reuseInFlight.js"],"names":[],"mappings":";AAAA;;;;EAIE;;AAEF,MAAM,cAAc,GAAG;IACrB,SAAS,CAAC,IAAI;QACZ,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IAC9B,CAAC;IACD,qBAAqB,EAAE,KAAK;CAC7B,CAAC;AAEF,mFAAmF;AACnF,mFAAmF;AACnF,mFAAmF;AACnF,kFAAkF;AAClF,sBAAsB;AACtB,SAAwB,aAAa,CAAC,OAAO,EAAE,MAAM;IACnD,MAAM,GAAG;QACP,GAAG,cAAc;QACjB,GAAG,CAAC,MAAM,IAAI,EAAE,CAAC;KAClB,CAAC;IAEF,MAAM,QAAQ,GAAG,EAAE,CAAC;IAEpB,OAAO,SAAS,SAAS,CAAC,GAAG,IAAI;QAC/B,IACE,MAAM,CAAC,qBAAqB;YAC5B,IAAI,CAAC,MAAM,KAAK,CAAC;YACjB,IAAI,CAAC,CAAC,CAAC,KAAK,SAAS,EACrB;YACA,OAAO,CAAC,IAAI,CAAC,+CAA+C,CAAC,CAAC;YAC9D,IAAI,GAAG,EAAE,CAAC;SACX;QAED,MAAM,GAAG,GAAG,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QACnC,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE;YACjC,qDAAqD;YACrD,QAAQ,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,IAAI,CAC5C,CAAC,OAAO,EAAE,EAAE;gBACV,kBAAkB;gBAClB,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC;gBACrB,OAAO,OAAO,CAAC;YACjB,CAAC,EACD,CAAC,GAAG,EAAE,EAAE;gBACN,sCAAsC;gBACtC,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC;gBACrB,MAAM,GAAG,CAAC;YACZ,CAAC,CACF,CAAC;SACH;QAED,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC;IACvB,CAAC,CAAC;AACJ,CAAC;AArCD,gCAqCC"} |
| /// <reference types="node" /> | ||
| /// <reference types="node" /> | ||
| import { EventEmitter } from "events"; | ||
| import type WASI from "wasi-js"; | ||
| import type { WASIFileSystem } from "wasi-js"; | ||
| import type { SendToWasmAbstractBase } from "./worker/send-to-wasm"; | ||
| import type { RecvFromWasmAbstractBase } from "./worker/recv-from-wasm"; | ||
| import type PosixContext from "./worker/posix-context"; | ||
| export { Stream } from "./worker/types"; | ||
| declare class WasmInstance extends EventEmitter { | ||
| fs?: WASIFileSystem; | ||
| table?: WebAssembly.Table; | ||
| wasi?: WASI; | ||
| posixContext?: PosixContext; | ||
| send: SendToWasmAbstractBase; | ||
| recv: RecvFromWasmAbstractBase; | ||
| terminate(): void; | ||
| writeToStdin(_data: any): void; | ||
| waitUntilFsLoaded(): Promise<void>; | ||
| signal(_sig?: number): void; | ||
| getcwd(): string; | ||
| fetch(_url: string, _path: string, _mode?: number | string): Promise<void>; | ||
| } | ||
| export declare class WasmInstanceSync extends WasmInstance { | ||
| getFunction(_name: string, _dll?: string): Function | undefined; | ||
| callWithString(_name: string | { | ||
| name: string; | ||
| dll: string; | ||
| } | Function, _str?: string | string[], ..._args: any[]): any; | ||
| exec(_argv?: string[]): number; | ||
| } | ||
| export declare class WasmInstanceAsync extends WasmInstance { | ||
| callWithString(_name: string | { | ||
| name: string; | ||
| dll: string; | ||
| }, _str?: string | string[], ..._args: any[]): Promise<any>; | ||
| exec(_argv?: string[]): Promise<number>; | ||
| } | ||
| export declare class IOProvider { | ||
| signal: (sig: number) => void; | ||
| getExtraOptions: () => object; | ||
| writeToStdin: (data: Buffer) => void; | ||
| readOutput: () => Promise<Buffer>; | ||
| } |
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.IOProvider = exports.WasmInstanceAsync = exports.WasmInstanceSync = exports.Stream = void 0; | ||
| const events_1 = require("events"); | ||
| var types_1 = require("./worker/types"); | ||
| Object.defineProperty(exports, "Stream", { enumerable: true, get: function () { return types_1.Stream; } }); | ||
| class WasmInstance extends events_1.EventEmitter { | ||
| // kill and free up anything associated with this. Any use | ||
| // after calling this is not defined. | ||
| terminate() { | ||
| throw Error("not implemented"); | ||
| } | ||
| writeToStdin(_data) { | ||
| throw Error("not implemented"); | ||
| } | ||
| // Wait until the filesystem is loaded enough to run user code. | ||
| waitUntilFsLoaded() { | ||
| throw Error("not implemented"); | ||
| } | ||
| signal(_sig) { | ||
| throw Error("not implemented"); | ||
| } | ||
| // Get the current working directory. | ||
| getcwd() { | ||
| throw Error("not implemented"); | ||
| } | ||
| // fetch the data at url and save it to path. | ||
| async fetch(_url, _path, _mode) { | ||
| throw Error("not implemented"); | ||
| } | ||
| } | ||
| class WasmInstanceSync extends WasmInstance { | ||
| getFunction(_name, _dll) { | ||
| throw Error("not implemented"); | ||
| } | ||
| callWithString(_name, _str, ..._args) { | ||
| throw Error("not implemented"); | ||
| } | ||
| exec(_argv = ["command"]) { | ||
| throw Error("not implemented"); | ||
| } | ||
| } | ||
| exports.WasmInstanceSync = WasmInstanceSync; | ||
| class WasmInstanceAsync extends WasmInstance { | ||
| async callWithString(_name, _str, ..._args) { | ||
| throw Error("not implemented"); | ||
| } | ||
| async exec(_argv = ["command"]) { | ||
| throw Error("not implemented"); | ||
| } | ||
| } | ||
| exports.WasmInstanceAsync = WasmInstanceAsync; | ||
| class IOProvider { | ||
| } | ||
| exports.IOProvider = IOProvider; | ||
| //# sourceMappingURL=types.js.map |
| {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/wasm/types.ts"],"names":[],"mappings":";;;AAAA,mCAAsC;AAMtC,wCAAwC;AAA/B,+FAAA,MAAM,OAAA;AAEf,MAAM,YAAa,SAAQ,qBAAY;IASrC,2DAA2D;IAC3D,qCAAqC;IACrC,SAAS;QACP,MAAM,KAAK,CAAC,iBAAiB,CAAC,CAAC;IACjC,CAAC;IAED,YAAY,CAAC,KAAK;QAChB,MAAM,KAAK,CAAC,iBAAiB,CAAC,CAAC;IACjC,CAAC;IAED,+DAA+D;IAC/D,iBAAiB;QACf,MAAM,KAAK,CAAC,iBAAiB,CAAC,CAAC;IACjC,CAAC;IAED,MAAM,CAAC,IAAa;QAClB,MAAM,KAAK,CAAC,iBAAiB,CAAC,CAAC;IACjC,CAAC;IAED,qCAAqC;IACrC,MAAM;QACJ,MAAM,KAAK,CAAC,iBAAiB,CAAC,CAAC;IACjC,CAAC;IAED,6CAA6C;IAC7C,KAAK,CAAC,KAAK,CACT,IAAY,EACZ,KAAa,EACb,KAAuB;QAEvB,MAAM,KAAK,CAAC,iBAAiB,CAAC,CAAC;IACjC,CAAC;CACF;AAED,MAAa,gBAAiB,SAAQ,YAAY;IAChD,WAAW,CAAC,KAAa,EAAE,IAAa;QACtC,MAAM,KAAK,CAAC,iBAAiB,CAAC,CAAC;IACjC,CAAC;IAED,cAAc,CACZ,KAAwD,EACxD,IAAwB,EACxB,GAAG,KAAK;QAER,MAAM,KAAK,CAAC,iBAAiB,CAAC,CAAC;IACjC,CAAC;IAED,IAAI,CAAC,QAAkB,CAAC,SAAS,CAAC;QAChC,MAAM,KAAK,CAAC,iBAAiB,CAAC,CAAC;IACjC,CAAC;CACF;AAhBD,4CAgBC;AAED,MAAa,iBAAkB,SAAQ,YAAY;IACjD,KAAK,CAAC,cAAc,CAClB,KAA6C,EAC7C,IAAwB,EACxB,GAAG,KAAK;QAER,MAAM,KAAK,CAAC,iBAAiB,CAAC,CAAC;IACjC,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,QAAkB,CAAC,SAAS,CAAC;QACtC,MAAM,KAAK,CAAC,iBAAiB,CAAC,CAAC;IACjC,CAAC;CACF;AAZD,8CAYC;AAED,MAAa,UAAU;CAKtB;AALD,gCAKC"} |
| import type WasmInstanceSync from "./instance"; | ||
| import { Options } from "./import"; | ||
| export default function wasmImportBrowser(wasmUrl: string, options?: Options): Promise<WasmInstanceSync>; |
| "use strict"; | ||
| /* | ||
| This is the Worker script when importing the wasm module in a web browser. | ||
| */ | ||
| var __importDefault = (this && this.__importDefault) || function (mod) { | ||
| return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
| }; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| const wasi_js_1 = require("wasi-js"); | ||
| const browser_1 = __importDefault(require("wasi-js/dist/bindings/browser")); | ||
| const import_1 = __importDefault(require("./import")); | ||
| const init_1 = __importDefault(require("./init")); | ||
| const debug_1 = __importDefault(require("debug")); | ||
| const events_1 = require("events"); | ||
| const posix_browser_1 = __importDefault(require("./posix-browser")); | ||
| const io_using_atomics_1 = __importDefault(require("./io-using-atomics")); | ||
| const io_using_service_worker_1 = __importDefault(require("./io-using-service-worker")); | ||
| const log = (0, debug_1.default)("wasm:worker:browser"); | ||
| async function wasmImportBrowser(wasmUrl, options = {}) { | ||
| log("wasmImportBrowser"); | ||
| // also fix zip path, if necessary and read in any zip files (so | ||
| // they can be loaded into memfs). | ||
| log("processing fs=", options.fs); | ||
| const fsSpec = []; | ||
| for (const X of options.fs ?? []) { | ||
| if (X.type == "zipurl") { | ||
| let Y; | ||
| if (!X.async) { | ||
| Y = { | ||
| type: "zip", | ||
| data: await (await fetch(X.zipurl)).arrayBuffer(), | ||
| mountpoint: X.mountpoint, | ||
| }; | ||
| } | ||
| else { | ||
| // we asynchronously load it irregardless of whatever else is happening... | ||
| // TODO: | ||
| Y = { | ||
| type: "zip-async", | ||
| getData: async () => await (await fetch(X.zipurl)).arrayBuffer(), | ||
| mountpoint: X.mountpoint, | ||
| }; | ||
| } | ||
| fsSpec.push(Y); | ||
| } | ||
| else { | ||
| fsSpec.push(X); | ||
| } | ||
| } | ||
| const fs = (0, wasi_js_1.createFileSystem)(fsSpec); | ||
| // Assumed to be loaded into memfs. | ||
| function importWebAssemblySync(path, options) { | ||
| const binary = new Uint8Array(fs.readFileSync(path)); | ||
| const mod = new WebAssembly.Module(binary); | ||
| return new WebAssembly.Instance(mod, options); | ||
| } | ||
| const wasm = await (0, import_1.default)({ | ||
| source: wasmUrl, | ||
| bindings: { ...browser_1.default, fs, posix: posix_browser_1.default }, | ||
| options, | ||
| importWebAssembly, | ||
| importWebAssemblySync, | ||
| readFileSync: (path) => { | ||
| return fs.readFileSync(path); | ||
| }, | ||
| maxMemoryMB: 1000, | ||
| }); | ||
| return wasm; | ||
| } | ||
| exports.default = wasmImportBrowser; | ||
| // Download from our server. | ||
| async function importWebAssembly(path, options) { | ||
| const { instance } = await WebAssembly.instantiateStreaming(fetch(path), options); | ||
| return instance; | ||
| } | ||
| function main() { | ||
| // in a worker, so do worker stuff | ||
| log("initializing worker"); | ||
| class Parent extends events_1.EventEmitter { | ||
| constructor() { | ||
| super(); | ||
| this.postMessage = self.postMessage.bind(self); | ||
| self.onmessage = ({ data: message }) => { | ||
| this.emit("message", message); | ||
| }; | ||
| } | ||
| } | ||
| const parent = new Parent(); | ||
| (0, init_1.default)({ | ||
| wasmImport: wasmImportBrowser, | ||
| parent, | ||
| captureOutput: true, | ||
| IOHandler: crossOriginIsolated | ||
| ? io_using_atomics_1.default | ||
| : io_using_service_worker_1.default, | ||
| }); | ||
| } | ||
| if (self.document == null) { | ||
| main(); | ||
| } | ||
| //# sourceMappingURL=browser.js.map |
| {"version":3,"file":"browser.js","sourceRoot":"","sources":["../../../src/wasm/worker/browser.ts"],"names":[],"mappings":"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"} |
| /// <reference types="node" /> | ||
| import type { FileSystemSpec, WASIBindings } from "wasi-js"; | ||
| import WasmInstanceSync from "./instance"; | ||
| export declare function strlen(charPtr: number, memory: WebAssembly.Memory): number; | ||
| export interface Options { | ||
| wasmEnv?: { | ||
| [name: string]: Function; | ||
| }; | ||
| env?: { | ||
| [name: string]: string; | ||
| }; | ||
| time?: boolean; | ||
| sleep?: (milliseconds: number) => void; | ||
| stdinBuffer?: SharedArrayBuffer; | ||
| signalBuffer?: SharedArrayBuffer; | ||
| getStdin?: () => Buffer; | ||
| sendStdout?: (Buffer: any) => void; | ||
| sendStderr?: (Buffer: any) => void; | ||
| fs?: FileSystemSpec[]; | ||
| locks?: { | ||
| spinLockBuffer: SharedArrayBuffer; | ||
| stdinLockBuffer: SharedArrayBuffer; | ||
| }; | ||
| noStdio?: boolean; | ||
| } | ||
| declare type WasmImportFunction = typeof doWasmImport; | ||
| declare function doWasmImport({ source, bindings, options, importWebAssemblySync, importWebAssembly, readFileSync, maxMemoryMB, }: { | ||
| source: string; | ||
| bindings: WASIBindings; | ||
| options: Options; | ||
| importWebAssemblySync: (path: string, opts: WebAssembly.Imports) => WebAssembly.Instance; | ||
| importWebAssembly: (path: string, opts: WebAssembly.Imports) => Promise<WebAssembly.Instance>; | ||
| readFileSync: any; | ||
| maxMemoryMB?: number; | ||
| }): Promise<WasmInstanceSync>; | ||
| declare const wasmImport: WasmImportFunction; | ||
| export default wasmImport; |
| "use strict"; | ||
| var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { | ||
| if (k2 === undefined) k2 = k; | ||
| var desc = Object.getOwnPropertyDescriptor(m, k); | ||
| if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { | ||
| desc = { enumerable: true, get: function() { return m[k]; } }; | ||
| } | ||
| Object.defineProperty(o, k2, desc); | ||
| }) : (function(o, m, k, k2) { | ||
| if (k2 === undefined) k2 = k; | ||
| o[k2] = m[k]; | ||
| })); | ||
| var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { | ||
| Object.defineProperty(o, "default", { enumerable: true, value: v }); | ||
| }) : function(o, v) { | ||
| o["default"] = v; | ||
| }); | ||
| var __importStar = (this && this.__importStar) || function (mod) { | ||
| if (mod && mod.__esModule) return mod; | ||
| var result = {}; | ||
| if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); | ||
| __setModuleDefault(result, mod); | ||
| return result; | ||
| }; | ||
| var __importDefault = (this && this.__importDefault) || function (mod) { | ||
| return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
| }; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.strlen = void 0; | ||
| const wasi_js_1 = __importDefault(require("wasi-js")); | ||
| const reuseInFlight_1 = __importDefault(require("../reuseInFlight")); | ||
| const instance_1 = __importDefault(require("./instance")); | ||
| const dylink_1 = __importStar(require("dylink")); | ||
| const trampoline_1 = __importDefault(require("./trampoline")); | ||
| const debug_1 = __importDefault(require("debug")); | ||
| const posix_context_1 = __importDefault(require("./posix-context")); | ||
| const log = (0, debug_1.default)("wasm-worker"); | ||
| function strlen(charPtr, memory) { | ||
| const mem = new Uint8Array(memory.buffer); | ||
| let i = charPtr; | ||
| while (mem[i]) { | ||
| i += 1; | ||
| } | ||
| return i - charPtr; | ||
| } | ||
| exports.strlen = strlen; | ||
| const cache = {}; | ||
| async function doWasmImport({ source, bindings, options = {}, importWebAssemblySync, importWebAssembly, readFileSync, maxMemoryMB, }) { | ||
| log("doWasmImport", source); | ||
| if (source == null) { | ||
| throw Error("source must be defined"); | ||
| } | ||
| if (cache[source] != null) { | ||
| return cache[source]; | ||
| } | ||
| const t = new Date().valueOf(); | ||
| const memory = new WebAssembly.Memory({ | ||
| initial: (0, dylink_1.MBtoPages)(10), | ||
| ...(maxMemoryMB ? { maximum: (0, dylink_1.MBtoPages)(maxMemoryMB) } : {}), | ||
| }); | ||
| const table = new WebAssembly.Table({ initial: 10000, element: "anyfunc" }); | ||
| const wasmEnv = { | ||
| reportError: (ptr, len) => { | ||
| // @ts-ignore | ||
| const slice = memory.buffer.slice(ptr, ptr + len); | ||
| const textDecoder = new TextDecoder(); | ||
| throw Error(textDecoder.decode(slice)); | ||
| }, | ||
| }; | ||
| // NOTE: if we want to try to use WebAssembly.Table for something, | ||
| // then set env.__indirect_function_table to it. The name | ||
| // __indirect_function_table is the arbitrary hardcoded name that zig | ||
| // just happens to use for the table it imports when you compile | ||
| // with --import-table. I only figured this out by decompiling and reading. See | ||
| // https://github.com/ziglang/zig/pull/10382/files#diff-e2879374d581d6e9422f4f6f09ae3c8ee5f429f7581d7b899f3863319afff4e0R648 | ||
| const wasmOpts = { | ||
| env: { | ||
| ...wasmEnv, | ||
| ...options.wasmEnv, | ||
| memory, | ||
| __indirect_function_table: table, | ||
| }, | ||
| }; | ||
| let wasm; | ||
| if (wasmOpts.env.wasmGetSignalState == null) { | ||
| console.warn("wasmGetSignalState not defined; using STUB"); | ||
| wasmOpts.env.wasmGetSignalState = () => { | ||
| return 0; | ||
| }; | ||
| } | ||
| if (wasmOpts.env.wasmSendString == null) { | ||
| // This sends a string from WebAssembly back to Typescript and places | ||
| // it in the result variable. | ||
| wasmOpts.env.wasmSendString = (ptr, len) => { | ||
| wasm.result = wasm.recv.string(ptr, len); | ||
| }; | ||
| } | ||
| if (wasmOpts.env.wasmSetException == null) { | ||
| wasmOpts.env.wasmSetException = () => { | ||
| wasm.resultException = true; | ||
| }; | ||
| } | ||
| if (wasmOpts.env.getrandom == null) { | ||
| // TODO: didn't need to do this get fixed in newer zig? | ||
| wasmOpts.env.getrandom = (bufPtr, bufLen, _flags) => { | ||
| // NOTE: returning 0 here (our default stub behavior) | ||
| // would result in Python hanging on startup! | ||
| bindings.randomFillSync( | ||
| // @ts-ignore | ||
| new Uint8Array(memory.buffer), bufPtr, bufLen); | ||
| return bufLen; | ||
| }; | ||
| } | ||
| if (wasmOpts.env.main == null) { | ||
| // TODO: this seems suspect | ||
| wasmOpts.env.main = () => { | ||
| return 0; | ||
| }; | ||
| } | ||
| if (wasmOpts.env._Py_emscripten == null) { | ||
| // TODO: this seems suspect | ||
| wasmOpts.env._Py_emscripten_runtime = () => { | ||
| return 0; | ||
| }; | ||
| } | ||
| (0, trampoline_1.default)(table, wasmOpts.env); | ||
| const { fs } = bindings; | ||
| const wasiConfig = { | ||
| preopens: { "/": "/" }, | ||
| bindings, | ||
| args: process.argv, | ||
| env: options.env, | ||
| sleep: options.sleep, | ||
| getStdin: options.getStdin, | ||
| sendStdout: options.sendStdout, | ||
| sendStderr: options.sendStderr, | ||
| }; | ||
| const wasi = new wasi_js_1.default(wasiConfig); | ||
| wasmOpts.wasi_snapshot_preview1 = wasi.wasiImport; | ||
| const dylinkOptions = { | ||
| importWebAssemblySync, | ||
| importWebAssembly, | ||
| readFileSync, | ||
| stub: false, | ||
| }; | ||
| const posixContext = new posix_context_1.default({ | ||
| memory, | ||
| wasi, | ||
| wasiConfig, | ||
| noStdio: !!options.noStdio, | ||
| }); | ||
| // This adds the posix functions into env *and* also adds socket | ||
| // functionality to wasi_snapshot_preview1. | ||
| posixContext.injectFunctions(wasmOpts); | ||
| const instance = await (0, dylink_1.default)({ | ||
| ...dylinkOptions, | ||
| path: source, | ||
| importObject: wasmOpts, | ||
| }); | ||
| if (wasi != null) { | ||
| // wasi assumes this is called. | ||
| wasi.start(instance, memory); | ||
| } | ||
| wasm = new instance_1.default(instance, memory, fs, table); | ||
| posixContext.init(wasm); | ||
| cache[source] = wasm; | ||
| if (options.time && log.enabled) { | ||
| log(`imported ${source} in ${new Date().valueOf() - t}ms`); | ||
| } | ||
| wasm.table = table; | ||
| wasm.wasi = wasi; | ||
| wasm.posixContext = posixContext; | ||
| wasm.instance = instance; | ||
| return wasm; | ||
| } | ||
| const wasmImport = (0, reuseInFlight_1.default)(doWasmImport, { | ||
| createKey: (args) => args[0], | ||
| }); | ||
| exports.default = wasmImport; | ||
| //# sourceMappingURL=import.js.map |
| {"version":3,"file":"import.js","sourceRoot":"","sources":["../../../src/wasm/worker/import.ts"],"names":[],"mappings":"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"} |
| interface Parent { | ||
| on: Function; | ||
| postMessage: Function; | ||
| } | ||
| export default function initWorker({ wasmImport, parent, captureOutput, IOHandler, }: { | ||
| wasmImport: Function; | ||
| parent: Parent; | ||
| captureOutput?: boolean; | ||
| IOHandler: any; | ||
| }): void; | ||
| export {}; |
| "use strict"; | ||
| var __importDefault = (this && this.__importDefault) || function (mod) { | ||
| return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
| }; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| const debug_1 = __importDefault(require("debug")); | ||
| const types_1 = require("./types"); | ||
| const log = (0, debug_1.default)("wasm:worker:init"); | ||
| function initWorker({ wasmImport, parent, captureOutput, IOHandler, }) { | ||
| let wasm = undefined; | ||
| async function handleMessage(message) { | ||
| log("worker got message ", message); | ||
| switch (message.event) { | ||
| case "init": | ||
| const ioHandler = new IOHandler(message.options, () => { | ||
| parent.postMessage({ event: "service-worker-broken" }); | ||
| }); | ||
| if (message.debug) { | ||
| // Enable debug logging to match main thread. Otherwise, there is no possible | ||
| // way to have any logging inside the WebWorker. | ||
| debug_1.default.enable(message.debug); | ||
| } | ||
| const opts = { | ||
| ...message.options, | ||
| sleep: ioHandler.sleep.bind(ioHandler), | ||
| getStdin: ioHandler.getStdin.bind(ioHandler), | ||
| wasmEnv: { | ||
| wasmGetSignalState: ioHandler.getSignalState.bind(ioHandler), | ||
| }, | ||
| }; | ||
| if (captureOutput || message.options.noStdio) { | ||
| opts.sendStdout = (data) => { | ||
| ioHandler.sendOutput(types_1.Stream.STDOUT, data); | ||
| }; | ||
| opts.sendStderr = (data) => { | ||
| ioHandler.sendOutput(types_1.Stream.STDERR, data); | ||
| }; | ||
| } | ||
| wasm = await wasmImport(message.name, opts); | ||
| return { event: "init", status: "ok" }; | ||
| case "callWithString": | ||
| if (wasm == null) { | ||
| throw Error("wasm must be initialized"); | ||
| } | ||
| return { | ||
| result: wasm.callWithString(message.name, message.str, // this is a string or string[] | ||
| ...message.args), | ||
| }; | ||
| case "call": | ||
| if (wasm == null) { | ||
| throw Error("wasm must be initialized"); | ||
| } | ||
| return { | ||
| result: wasm.callWithString(message.name, "", []), | ||
| }; | ||
| case "waitUntilFsLoaded": | ||
| if (wasm?.fs == null) { | ||
| throw Error("wasm.fs must be initialized"); | ||
| } | ||
| // it might not be defined, e.g., if not using unionfs at all | ||
| const { waitUntilLoaded } = wasm.fs; | ||
| if (waitUntilLoaded == null) { | ||
| log("waitUntilLoaded - no wait function defined"); | ||
| } | ||
| else { | ||
| await waitUntilLoaded(); | ||
| log("waited and now file system"); | ||
| } | ||
| if (log.enabled) { | ||
| // takes effort | ||
| log("ls / = ", wasm.fs.readdirSync("/")); | ||
| } | ||
| return; | ||
| case "fetch": | ||
| if (wasm?.fs == null) { | ||
| throw Error("wasm.fs must be initialized"); | ||
| } | ||
| await wasm.fetch(message.url, message.path, message.mode); | ||
| return; | ||
| } | ||
| } | ||
| parent.on("message", async (message) => { | ||
| try { | ||
| const resp = { | ||
| id: message.id, | ||
| ...(await handleMessage(message)), | ||
| }; | ||
| parent.postMessage(resp); | ||
| } | ||
| catch (error) { | ||
| parent.postMessage({ | ||
| id: message.id, | ||
| error, | ||
| }); | ||
| } | ||
| }); | ||
| } | ||
| exports.default = initWorker; | ||
| //# sourceMappingURL=init.js.map |
| {"version":3,"file":"init.js","sourceRoot":"","sources":["../../../src/wasm/worker/init.ts"],"names":[],"mappings":"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"} |
| /// <reference types="node" /> | ||
| import type { WASIFileSystem } from "wasi-js"; | ||
| import type WASI from "wasi-js"; | ||
| import { EventEmitter } from "events"; | ||
| import SendToWasm from "./send-to-wasm"; | ||
| import RecvFromWasm from "./recv-from-wasm"; | ||
| import type PosixContext from "./posix-context"; | ||
| export default class WasmInstanceSync extends EventEmitter { | ||
| result: any; | ||
| resultException: boolean; | ||
| exports: { | ||
| [name: string]: any; | ||
| }; | ||
| instance: any; | ||
| memory: WebAssembly.Memory; | ||
| smallStringPtr?: number; | ||
| _getFunctionCache: { | ||
| [name: string]: Function; | ||
| }; | ||
| fs?: WASIFileSystem; | ||
| table?: WebAssembly.Table; | ||
| wasi?: WASI; | ||
| run?: (path: string) => number; | ||
| posixContext?: PosixContext; | ||
| send: SendToWasm; | ||
| recv: RecvFromWasm; | ||
| constructor(instance: any, memory: WebAssembly.Memory, fs?: WASIFileSystem, table?: WebAssembly.Table); | ||
| terminate(): void; | ||
| exec(argv?: string[]): number; | ||
| writeToStdin(_data: any): void; | ||
| callWithString(func: string | { | ||
| name: string; | ||
| dll: string; | ||
| } | Function, str?: string | string[], ...args: any[]): any; | ||
| private getSmallStringPtr; | ||
| private callWithSmallString; | ||
| getFunction(name: string, dll?: string): Function | undefined; | ||
| private getFunctionUsingDlopen; | ||
| closeDynamicLibrary(path: string): void; | ||
| getcwd(): string; | ||
| waitUntilFsLoaded(): Promise<void>; | ||
| signal(_sig?: number): void; | ||
| fetch(url: string, path: string, mode?: number | string): Promise<void>; | ||
| } |
| "use strict"; | ||
| var __importDefault = (this && this.__importDefault) || function (mod) { | ||
| return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
| }; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| const events_1 = require("events"); | ||
| const send_to_wasm_1 = __importDefault(require("./send-to-wasm")); | ||
| const recv_from_wasm_1 = __importDefault(require("./recv-from-wasm")); | ||
| const awaiting_1 = require("awaiting"); | ||
| const path_1 = require("path"); | ||
| const encoder = new TextEncoder(); | ||
| // Massive optimization -- when calling a WASM function via | ||
| // callWithString (so first arg is a string), we reuse the | ||
| // same string buffer every time as long as the string is | ||
| // at most 8KB. This avoids tons of mallocs, frees, saves | ||
| // memory, and gives an order of magnitude speedup. | ||
| const SMALL_STRING_SIZE = 1024 * 8; | ||
| class WasmInstanceSync extends events_1.EventEmitter { | ||
| constructor(instance, memory, fs, table) { | ||
| super(); | ||
| this.result = undefined; | ||
| this.resultException = false; | ||
| // functions never go away and getFunction is expensive if | ||
| // it has to use the table, and same function gets called often, | ||
| // so this is well worth doing. | ||
| this._getFunctionCache = {}; | ||
| this.exports = instance.exports; | ||
| this.instance = instance; | ||
| this.memory = memory; | ||
| this.table = table; | ||
| this.fs = fs; | ||
| const opts = { | ||
| memory: this.memory, | ||
| callFunction: (name, ...args) => { | ||
| const f = this.getFunction(name); | ||
| if (f == null) { | ||
| throw Error(`error - ${name} is not defined`); | ||
| } | ||
| return f(...args); | ||
| }, | ||
| callWithString: this.callWithString.bind(this), | ||
| }; | ||
| this.send = new send_to_wasm_1.default(opts); | ||
| this.recv = new recv_from_wasm_1.default(opts); | ||
| } | ||
| terminate() { | ||
| // nothing to do, since nothing can possibly be *running* when this is called. | ||
| } | ||
| exec(argv = ["command"]) { | ||
| return this.callWithString("cowasm_exec", argv); | ||
| } | ||
| writeToStdin(_data) { | ||
| throw Error("not implemented"); | ||
| } | ||
| // When you pass str of type str[] it calls name with (len(str), char**, ...). | ||
| // i.e., it's the main call signature than than null terminate char** like some | ||
| // C library code. | ||
| callWithString(func, str, ...args) { | ||
| let f = undefined; | ||
| if (typeof func == "string") { | ||
| f = this.getFunction(func); | ||
| } | ||
| else if (typeof func == "object") { | ||
| f = this.getFunction(func.name, func.dll); | ||
| } | ||
| else { | ||
| f = func; | ||
| } | ||
| if (f == null) { | ||
| throw Error(`no function "${typeof func == "object" ? JSON.stringify(func) : func}" defined in wasm module`); | ||
| } | ||
| this.result = undefined; | ||
| this.resultException = false; | ||
| let r; | ||
| if (str == null) { | ||
| // just calling it. | ||
| r = f(); | ||
| } | ||
| else if (typeof str == "string") { | ||
| const strAsArray = encoder.encode(str); | ||
| if (strAsArray.length < SMALL_STRING_SIZE) { | ||
| r = this.callWithSmallString(f, strAsArray); | ||
| return this.result ?? r; | ||
| } | ||
| const ptr = this.send.encodedString(strAsArray); | ||
| try { | ||
| // @ts-ignore | ||
| r = f(ptr, ...args); | ||
| } | ||
| finally { | ||
| // @ts-ignore | ||
| this.exports.c_free(ptr); | ||
| } | ||
| } | ||
| else { | ||
| // TODO: solve problem in more generality, obviously! | ||
| // Convert array of strings to char** of null terminated | ||
| // strings, with a null char* at the end as well (common for clib functions) | ||
| const ptrs = []; | ||
| for (const s of str) { | ||
| ptrs.push(this.send.string(s)); | ||
| } | ||
| const len = ptrs.length; | ||
| const ptr = this.exports.c_malloc((len + 1) * 4); // sizeof(char*) = 4 in WASM. | ||
| const array = new Int32Array(this.memory.buffer, ptr, len + 1); | ||
| let i = 0; | ||
| for (const p of ptrs) { | ||
| array[i] = p; | ||
| i += 1; | ||
| } | ||
| array[len] = 0; // final null pointer. | ||
| try { | ||
| // @ts-ignore | ||
| r = f(len, ptr, ...args); | ||
| } | ||
| finally { | ||
| // @ts-ignore | ||
| this.exports.c_free(ptr); | ||
| for (const p of ptrs) { | ||
| this.exports.c_free(p); | ||
| } | ||
| } | ||
| } | ||
| if (this.resultException) { | ||
| throw Error("RuntimeError"); | ||
| } | ||
| return this.result ?? r; | ||
| } | ||
| getSmallStringPtr() { | ||
| if (this.smallStringPtr == null) { | ||
| this.smallStringPtr = this.exports.c_malloc(SMALL_STRING_SIZE); | ||
| if (!this.smallStringPtr) { | ||
| throw Error("MemoryError -- out of memory allocating small string buffer"); | ||
| } | ||
| } | ||
| return this.smallStringPtr; | ||
| } | ||
| callWithSmallString(f, strAsArray, ...args) { | ||
| const ptr = this.getSmallStringPtr(); | ||
| const len = strAsArray.length + 1; | ||
| const array = new Int8Array(this.memory.buffer, ptr, len); | ||
| array.set(strAsArray); | ||
| array[len - 1] = 0; | ||
| return f(ptr, ...args); | ||
| } | ||
| // - If dll is not given gets a function from the main instance | ||
| // or undefined if the function is not defined. Result is cached. | ||
| // - If dll is given, loads the given dynamic library (if it isn't | ||
| // already loaded), then gets the named function from there. In the | ||
| // dll case throws an error explaining what went wrong if anything | ||
| // goes wrong, rather than undefined (since a lot can go wrong). | ||
| // TODO: maybe getFunction should throw instead of returning undefined | ||
| // in all cases? Result is NOT cached, since dlclose+cache = crash. | ||
| getFunction(name, dll) { | ||
| if (dll != null) { | ||
| return this.getFunctionUsingDlopen(name, dll); | ||
| } | ||
| let f = this._getFunctionCache[name]; | ||
| if (f != null) { | ||
| return f; | ||
| } | ||
| if (this.table != null) { | ||
| // first try pointer: | ||
| const getPtr = this.exports[`__WASM_EXPORT__${name}`]; | ||
| if (getPtr != null) { | ||
| f = this.table.get(getPtr()); | ||
| if (f != null) { | ||
| this._getFunctionCache[name] = f; | ||
| return f; | ||
| } | ||
| } | ||
| } | ||
| f = this.exports[name] ?? this.instance.env[name]; | ||
| this._getFunctionCache[name] = f; | ||
| return f; | ||
| } | ||
| // Opens dynamic library if not already open, then gets the function. | ||
| // Throws errors if anything doesn't exist or work. | ||
| getFunctionUsingDlopen(name, path) { | ||
| const handle = this.callWithString("dlopen", path); | ||
| const dlsym = this.getFunction("dlsym"); | ||
| if (dlsym == null) { | ||
| throw Error("dlsym must be defined"); | ||
| } | ||
| const ptr = this.getSmallStringPtr(); | ||
| this.send.string(name, { ptr, len: SMALL_STRING_SIZE }); | ||
| const fPtr = dlsym(handle, ptr); | ||
| return this.table?.get(fPtr); | ||
| } | ||
| closeDynamicLibrary(path) { | ||
| const handle = this.callWithString("dlopen", path); | ||
| if (handle != 0) { | ||
| const dlclose = this.getFunction("dlclose"); | ||
| if (dlclose == null) { | ||
| // should definitely never happen | ||
| throw Error("dlclose not defined"); | ||
| } | ||
| dlclose(handle); | ||
| } | ||
| } | ||
| // Get the current working directory in the WASM instance. | ||
| // The motivation for implementing this and ensuring it is fast | ||
| // is that we need it when calling things like exec in our | ||
| // posix compat layer, since we must ensure the host runtime | ||
| // has the same working directory before any posix call that | ||
| // uses the host. | ||
| getcwd() { | ||
| const getcwd = this.getFunction("getcwd"); | ||
| if (getcwd == null) { | ||
| // this should be enforced by dylink and libc. | ||
| throw Error("C library function getcwd must be exported"); | ||
| } | ||
| return this.recv.string(getcwd(this.getSmallStringPtr(), SMALL_STRING_SIZE)); | ||
| } | ||
| async waitUntilFsLoaded() { | ||
| if (this.fs == null) { | ||
| throw Error("fs must be defined"); | ||
| } | ||
| // it might not be defined, e.g., if not using unionfs at all | ||
| return await this.fs.waitUntilLoaded?.(); | ||
| } | ||
| signal(_sig) { | ||
| throw Error("not implemented"); | ||
| } | ||
| async fetch(url, path, mode) { | ||
| // TODO: this can't work in older versions of node... but also we should probably only | ||
| // use fetch in the browser. Could require clarification or the node-fetch module. | ||
| const data = await (await fetch(url)).arrayBuffer(); | ||
| const { fs } = this; | ||
| if (fs == null) { | ||
| throw Error("fs must be defined"); | ||
| } | ||
| const dir = (0, path_1.dirname)(path); | ||
| await (0, awaiting_1.callback)((cb) => { | ||
| fs.mkdir(dir, { recursive: true }, cb); | ||
| }); | ||
| await (0, awaiting_1.callback)((cb) => { | ||
| fs.writeFile(path, Buffer.from(data), cb); | ||
| }); | ||
| if (mode) { | ||
| // set file mode, typically for executables | ||
| await (0, awaiting_1.callback)((cb) => { | ||
| fs.chmod(path, mode, cb); | ||
| }); | ||
| } | ||
| } | ||
| } | ||
| exports.default = WasmInstanceSync; | ||
| //# sourceMappingURL=instance.js.map |
| {"version":3,"file":"instance.js","sourceRoot":"","sources":["../../../src/wasm/worker/instance.ts"],"names":[],"mappings":"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"} |
| /// <reference types="node" /> | ||
| import { IOHandlerClass, Stream } from "./types"; | ||
| export default class IOHandler implements IOHandlerClass { | ||
| private stdinBuffer; | ||
| private stdinLength; | ||
| private outputBuffer; | ||
| private outputLength; | ||
| private signalState; | ||
| private sleepArray; | ||
| constructor(opts: any); | ||
| sleep(milliseconds: number): void; | ||
| getStdin(milliseconds?: number): Buffer; | ||
| sendOutput(stream: Stream, data: Buffer): void; | ||
| getSignalState(): number; | ||
| } |
| "use strict"; | ||
| var __importDefault = (this && this.__importDefault) || function (mod) { | ||
| return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
| }; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| const debug_1 = __importDefault(require("debug")); | ||
| const log = (0, debug_1.default)("wasm:worker:io-using-atomics"); | ||
| class IOHandler { | ||
| constructor(opts) { | ||
| log("creating ioHandler"); | ||
| if (opts.stdinLengthBuffer == null) { | ||
| throw Error("must define stdinLengthBuffer"); | ||
| } | ||
| if (opts.stdinBuffer == null) { | ||
| throw Error("must define stdinBuffer"); | ||
| } | ||
| if (opts.outputLengthBuffer == null) { | ||
| throw Error("must define outputLengthBuffer"); | ||
| } | ||
| if (opts.outputBuffer == null) { | ||
| throw Error("must define outputBuffer"); | ||
| } | ||
| if (opts.signalBuffer == null) { | ||
| throw Error("must define signalBuffer"); | ||
| } | ||
| this.stdinBuffer = Buffer.from(opts.stdinBuffer); | ||
| this.stdinLength = new Int32Array(opts.stdinLengthBuffer); | ||
| this.outputBuffer = Buffer.from(opts.outputBuffer); | ||
| this.outputLength = new Int32Array(opts.outputLengthBuffer); | ||
| this.signalState = new Int32Array(opts.signalBuffer); | ||
| this.sleepArray = new Int32Array(new SharedArrayBuffer(4)); | ||
| } | ||
| sleep(milliseconds) { | ||
| log("sleep starting, milliseconds=", milliseconds); | ||
| // wait for sleepArray[0] to change from 0, which | ||
| // will never happen. The only hitch is we need to periodically | ||
| // check for signals. | ||
| while (milliseconds > 0) { | ||
| const t = Math.min(milliseconds, 500); | ||
| Atomics.wait(this.sleepArray, 0, 0, t); | ||
| milliseconds -= t; | ||
| if (Atomics.load(this.signalState, 0)) { | ||
| // there's a signal waiting | ||
| // TODO: there could be signals that maybe don't interrupt sleep? | ||
| return; | ||
| } | ||
| } | ||
| } | ||
| // NOTE: we support a milliseconds timeout, but we don't actually use it | ||
| // anywhere (at least when I wrote this). | ||
| getStdin(milliseconds) { | ||
| // wait to change to a positive value, i.e., some input to arrive | ||
| const start = milliseconds != null ? new Date().valueOf() : 0; | ||
| while (this.stdinLength[0] == 0) { | ||
| // wait with a timeout of 1s for it to change. | ||
| log("getStdin: waiting for some new stdin"); | ||
| Atomics.wait(this.stdinLength, 0, 0, milliseconds ?? 1000); | ||
| if (Atomics.load(this.signalState, 0)) { | ||
| // check for any signals | ||
| // TODO: there could be signals that maybe don't interrupt input? | ||
| return Buffer.from(""); | ||
| } | ||
| if (milliseconds != null && | ||
| this.stdinLength[0] == 0 && | ||
| new Date().valueOf() - start > milliseconds) { | ||
| return Buffer.from(""); | ||
| } | ||
| } | ||
| // Now there is stdin waiting for us: how much? | ||
| const len = this.stdinLength[0]; | ||
| log("getStdin: have stdin, processing ", len, " bytes"); | ||
| const data = Buffer.alloc(len); | ||
| this.stdinBuffer.copy(data, 0, 0, len); | ||
| // Reset the buffer: | ||
| Atomics.store(this.stdinLength, 0, 0); | ||
| Atomics.notify(this.stdinLength, 0); | ||
| return data; | ||
| } | ||
| sendOutput(stream, data) { | ||
| if (log.enabled) { | ||
| log("sendOutput", stream, data, { len: this.outputLength[0] }, new TextDecoder().decode(data)); | ||
| } | ||
| // place the new data in the outputBuffer, so that the main thread can receive it. | ||
| // The format is: | ||
| // [1|2][all of the actual data] | ||
| // where 1 = stdout and 2 = stderr. | ||
| // Also we use 0 as a temporary lock. | ||
| // Putting both stdout and stderr in the same | ||
| // buffer means one less buffer to deal with, *and* is a very simple way to avoid | ||
| // any issues with mixing up the ordering of output. | ||
| // That said, if there is stdout in the buffer and you write stderr, we must first | ||
| // wait until the main thread empties the buffer first, since our data structure | ||
| // is so simple that we can't store both stdout and stderr in the buffer at the | ||
| // same time. | ||
| while (data.length > 0) { | ||
| while ((this.outputLength[0] > 0 && this.outputBuffer[0] != stream) || | ||
| this.outputLength[0] == this.outputBuffer.length) { | ||
| // wait for main thread to read, because our buffer only holds one | ||
| // type of stream at a time, for simplicity. | ||
| // Or, we have no more space. | ||
| Atomics.wait(this.outputLength, 0, this.outputLength[0]); | ||
| } | ||
| this.outputBuffer[0] = 0; // lock it so main thread doesn't try to read while we are copying and setting length | ||
| if (this.outputLength[0] == 0) { | ||
| // initialize stream type field. | ||
| this.outputLength[0] = 1; | ||
| } | ||
| // copy as much data as we can. | ||
| const copied = data.copy(this.outputBuffer, this.outputLength[0]); | ||
| data = data.subarray(copied); | ||
| const n = copied + this.outputLength[0]; | ||
| log("setting output buffer size to ", n); | ||
| Atomics.store(this.outputLength, 0, n); | ||
| this.outputBuffer[0] = stream; | ||
| Atomics.notify(this.outputLength, 0); | ||
| } | ||
| } | ||
| // TODO: in general there could be more than one signal at once... of course, right now we only support sigint = 2. | ||
| getSignalState() { | ||
| const signal = Atomics.load(this.signalState, 0); | ||
| if (signal) { | ||
| log("signalState", this.signalState[0]); | ||
| // clear signal state so we can get a new signal | ||
| Atomics.store(this.signalState, 0, 0); | ||
| // tell C program about the signal we found. | ||
| return signal; | ||
| } | ||
| return 0; | ||
| } | ||
| } | ||
| exports.default = IOHandler; | ||
| //# sourceMappingURL=io-using-atomics.js.map |
| {"version":3,"file":"io-using-atomics.js","sourceRoot":"","sources":["../../../src/wasm/worker/io-using-atomics.ts"],"names":[],"mappings":"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"} |
| /// <reference types="node" /> | ||
| import { IOHandlerClass, Stream } from "./types"; | ||
| export default class IOHandler implements IOHandlerClass { | ||
| private id; | ||
| private lastSignalCheck; | ||
| private serviceWorkerBroken; | ||
| constructor(opts: any, serviceWorkerBroken: Function); | ||
| private request; | ||
| sleep(milliseconds: number): void; | ||
| getStdin(milliseconds?: number): Buffer; | ||
| private getSignal; | ||
| sendOutput(stream: Stream, data: Buffer): void; | ||
| getSignalState(): number; | ||
| } |
| "use strict"; | ||
| var __importDefault = (this && this.__importDefault) || function (mod) { | ||
| return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
| }; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| const debug_1 = __importDefault(require("debug")); | ||
| const log = (0, debug_1.default)("wasm:worker:io-using-atomics"); | ||
| const SIGNAL_CHECK_MS = 500; | ||
| const decoder = new TextDecoder(); | ||
| class IOHandler { | ||
| constructor(opts, serviceWorkerBroken) { | ||
| this.lastSignalCheck = 0; | ||
| log(opts); | ||
| this.id = opts.id; | ||
| this.serviceWorkerBroken = serviceWorkerBroken; | ||
| if (this.id == null) { | ||
| throw Error(`${this.id} must be a v4 uuid`); | ||
| } | ||
| } | ||
| request(url, body = {}) { | ||
| const request = new XMLHttpRequest(); | ||
| request.open("POST", `/python-wasm-sw/${url}`, false); // false = synchronous | ||
| request.setRequestHeader("cache-control", "no-cache, no-store, max-age=0"); | ||
| try { | ||
| request.send(JSON.stringify(body)); | ||
| } | ||
| catch (err) { | ||
| this.serviceWorkerBroken(); | ||
| warnBroken(err); | ||
| } | ||
| if (request.status != 200 && request.status != 304) { | ||
| this.serviceWorkerBroken(); | ||
| warnBroken(`invalid status=${request.status}`); | ||
| } | ||
| return request; | ||
| } | ||
| sleep(milliseconds) { | ||
| log("sleep ", milliseconds); | ||
| const start = new Date().valueOf(); | ||
| while (new Date().valueOf() - start <= milliseconds) { | ||
| try { | ||
| // We don't sleep the entire, because (1) we want to check for signals periodically, | ||
| // and (2) long synchronous requests CRASH the service worker! On Safari, it will kill | ||
| // the worker and ban it. So do NOT do that. | ||
| this.request("sleep", { ms: Math.min(milliseconds, 500) }); | ||
| } | ||
| catch (err) { | ||
| log("sleep error", err); | ||
| return; | ||
| } | ||
| if (this.getSignal(false)) { | ||
| // TODO: there could be signals that maybe don't interrupt sleep? | ||
| return; | ||
| } | ||
| } | ||
| } | ||
| getStdin(milliseconds) { | ||
| // Despite blocking when milliseconds is not set, this doesn't block | ||
| // control+c signal because we send "^C" to stdin when getting that signal. | ||
| const request = this.request("read-stdin", { | ||
| id: this.id, | ||
| ms: milliseconds ?? 3000, | ||
| }); | ||
| if (request.status == 200) { | ||
| return Buffer.from(request.responseText ?? ""); | ||
| } | ||
| else { | ||
| // TIMEOUT -- will try again soon. | ||
| // NOTE: we try for a few seconds to get output, then fail and let client call | ||
| // this again. It **does not work** to just allow for a very long synchronous | ||
| // request and long response in the service worker. | ||
| return Buffer.from(""); | ||
| } | ||
| } | ||
| getSignal(clear) { | ||
| const request = this.request("read-signal", { clear, id: this.id }); | ||
| return parseInt(request.responseText) ?? 0; | ||
| } | ||
| sendOutput(stream, data) { | ||
| let str; | ||
| try { | ||
| str = decoder.decode(data); | ||
| } | ||
| catch (_err) { | ||
| // discard data we can't decode. Won't be able to display anyways. | ||
| return; | ||
| } | ||
| log("sendOutput", str); | ||
| // send new data to the service worker, so that the main thread can receive it. | ||
| this.request("write-output", { | ||
| id: this.id, | ||
| stream: `${stream}`, | ||
| data: str, | ||
| }); | ||
| } | ||
| // Python kernel will call this VERY frequently, which is fine for | ||
| // checking an atomic, but NOT for using xmlhttprequest. | ||
| getSignalState() { | ||
| const now = new Date().valueOf(); | ||
| if (now - this.lastSignalCheck < SIGNAL_CHECK_MS) { | ||
| return 0; | ||
| } | ||
| this.lastSignalCheck = now; | ||
| return this.getSignal(true); | ||
| } | ||
| } | ||
| exports.default = IOHandler; | ||
| function warnBroken(err, milliseconds = 3000) { | ||
| // Something strongly suggests the service worker isn't working, e.g., which would happen over | ||
| // non https non localhost (or even firefox incognito in all cases). | ||
| // If we just silently ignore this, then we'll likely DOS our server, so instead we do a CPU | ||
| // consuming lock for a while, since I don't know what else to do. This burns CPU, but stops DOS. | ||
| // OK, upon experimenting, it turns out this sort of thing happens every once in a while. | ||
| // In some cases, it can happen constantly, e.g., Firefox over http, so we do guard against it. | ||
| console.warn("service worker not working, so burning CPU to avoid DOS'ing the server -- ", err); | ||
| const t0 = new Date().valueOf(); | ||
| while (new Date().valueOf() - t0 <= milliseconds) { } | ||
| } | ||
| //# sourceMappingURL=io-using-service-worker.js.map |
| {"version":3,"file":"io-using-service-worker.js","sourceRoot":"","sources":["../../../src/wasm/worker/io-using-service-worker.ts"],"names":[],"mappings":"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"} |
| import { Options } from "./import"; | ||
| import type { WasmInstanceSync } from "../types"; | ||
| export default function wasmImportNode(name: string, options: Options): Promise<WasmInstanceSync>; |
| "use strict"; | ||
| /* | ||
| Initialize our WASM setup. | ||
| This can be run as a Worker script when importing the wasm module in node.js | ||
| in the mode where we use a Worker. | ||
| */ | ||
| var __importDefault = (this && this.__importDefault) || function (mod) { | ||
| return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
| }; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| const promises_1 = require("fs/promises"); | ||
| const wasi_js_1 = require("wasi-js"); | ||
| const node_1 = __importDefault(require("wasi-js/dist/bindings/node")); | ||
| const path_1 = require("path"); | ||
| const import_1 = __importDefault(require("./import")); | ||
| const worker_threads_1 = require("worker_threads"); | ||
| const init_1 = __importDefault(require("./init")); | ||
| const debug_1 = __importDefault(require("debug")); | ||
| const os_1 = __importDefault(require("os")); | ||
| const child_process_1 = __importDefault(require("child_process")); | ||
| const posix_node_1 = __importDefault(require("posix-node")); | ||
| const io_using_atomics_1 = __importDefault(require("./io-using-atomics")); | ||
| const log = (0, debug_1.default)("wasm:worker"); | ||
| async function wasmImportNode(name, options) { | ||
| log("wasmImportNode"); | ||
| const path = (0, path_1.dirname)((0, path_1.join)(__filename, "..", "..")); | ||
| if (!(0, path_1.isAbsolute)(name)) { | ||
| // it's critical to make this canonical BEFORE calling the debounced function, | ||
| // or randomly otherwise end up with same module imported twice, which will | ||
| // result in a "hellish nightmare" of subtle bugs. | ||
| name = (0, path_1.join)(path, name); | ||
| } | ||
| // also fix zip path, if necessary and read in any zip files (so they can be loaded into memfs). | ||
| const fsSpec = []; | ||
| for (const X of options.fs ?? []) { | ||
| if (X.type == "zipfile") { | ||
| if (!(0, path_1.isAbsolute)(X.zipfile)) { | ||
| X.zipfile = (0, path_1.join)(path, X.zipfile); | ||
| } | ||
| let Y; | ||
| if (X.async) { | ||
| Y = { | ||
| type: "zip-async", | ||
| getData: async () => await (0, promises_1.readFile)(X.zipfile), | ||
| mountpoint: X.mountpoint, | ||
| }; | ||
| } | ||
| else { | ||
| try { | ||
| Y = { | ||
| type: "zip", | ||
| data: await (0, promises_1.readFile)(X.zipfile), | ||
| mountpoint: X.mountpoint, | ||
| }; | ||
| } | ||
| catch (err) { | ||
| // non-fatal | ||
| // We *might* use this eventually when building the datafile itself, if we switch to using cpython wasm to build | ||
| // instead of native cpython. | ||
| console.warn(`WARNING: Unable to read filesystem datafile '${X.zipfile}' -- falling back to filesystem.`); | ||
| } | ||
| } | ||
| fsSpec.push(Y); | ||
| } | ||
| else { | ||
| fsSpec.push(X); | ||
| } | ||
| } | ||
| const fs = (0, wasi_js_1.createFileSystem)(fsSpec, node_1.default.fs); | ||
| function importWebAssemblySync(path, opts) { | ||
| const binary = new Uint8Array(fs.readFileSync(path)); | ||
| const mod = new WebAssembly.Module(binary); | ||
| return new WebAssembly.Instance(mod, opts); | ||
| } | ||
| async function importWebAssembly(path, opts) { | ||
| const binary = new Uint8Array(await (0, promises_1.readFile)(path)); | ||
| const mod = new WebAssembly.Module(binary); | ||
| return new WebAssembly.Instance(mod, opts); | ||
| } | ||
| if (options.sleep == null && posix_node_1.default.sleep != null && posix_node_1.default.usleep != null) { | ||
| // don't have sleep support (since single thread), and we can provide | ||
| // that via posix and not burn 100% cpu. | ||
| const { sleep, usleep } = posix_node_1.default; | ||
| options.sleep = (milliseconds) => { | ||
| const seconds = Math.floor(milliseconds / 1000); | ||
| if (seconds > 0) { | ||
| sleep(seconds); | ||
| } | ||
| const microseconds = Math.floor(1000000 * (milliseconds / 1000 - seconds)); | ||
| if (microseconds > 0) { | ||
| usleep(microseconds); | ||
| } | ||
| }; | ||
| } | ||
| return await (0, import_1.default)({ | ||
| source: name, | ||
| bindings: { ...node_1.default, fs, os: os_1.default, child_process: child_process_1.default, posix: posix_node_1.default }, | ||
| options, | ||
| importWebAssembly, | ||
| importWebAssemblySync, | ||
| readFileSync: fs.readFileSync, | ||
| }); | ||
| } | ||
| exports.default = wasmImportNode; | ||
| if (!worker_threads_1.isMainThread && worker_threads_1.parentPort != null) { | ||
| log("running as a worker thread."); | ||
| (0, init_1.default)({ | ||
| wasmImport: wasmImportNode, | ||
| parent: worker_threads_1.parentPort, | ||
| IOHandler: io_using_atomics_1.default, | ||
| }); | ||
| } | ||
| else { | ||
| log("running in the main thread"); | ||
| // We enable blocking stdin if at all possible | ||
| // so that when wasi does | ||
| // fs.readSync(stdin, ...) | ||
| // it blocks and waits | ||
| // for an input character, rather than immediately | ||
| // giving an error or 0 characters, except when one | ||
| // is ready. This is much better than a loop with | ||
| // 100% cpu usage! | ||
| // NOTE | ||
| // - right now enableRawInput is only available on | ||
| // macos and linux platforms, e.g., not on windows. | ||
| try { | ||
| posix_node_1.default.makeStdinBlocking?.(); | ||
| } | ||
| catch (_err) { | ||
| console.warn("POSIX blocking stdin not available. Try using --worker."); | ||
| } | ||
| } | ||
| //# sourceMappingURL=node.js.map |
| {"version":3,"file":"node.js","sourceRoot":"","sources":["../../../src/wasm/worker/node.ts"],"names":[],"mappings":"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"} |
| import type { Posix } from "posix-node"; | ||
| declare const posix: Posix; | ||
| export default posix; |
| "use strict"; | ||
| // Create a simulated posix environment for the browser. | ||
| // We will want to move this to its own package. | ||
| // It makes more sense though to put all the assumptions about what "posix in the browser" is in | ||
| // its own module, rather than randomly in the files in src/wasm/posix. | ||
| // Also, we can ensure this has the same interface as posix-node provides. | ||
| // TODO: Maybe this goes in posix-node as the fallback in case we're on Windows (say). | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| const posix = { | ||
| getpid: () => { | ||
| return process.pid; | ||
| }, | ||
| getppid: () => { | ||
| return posix.getpid?.() ?? 1; | ||
| }, | ||
| }; | ||
| exports.default = posix; | ||
| //# sourceMappingURL=posix-browser.js.map |
| {"version":3,"file":"posix-browser.js","sourceRoot":"","sources":["../../../src/wasm/worker/posix-browser.ts"],"names":[],"mappings":";AAAA,wDAAwD;AACxD,gDAAgD;AAChD,gGAAgG;AAChG,wEAAwE;AACxE,0EAA0E;AAC1E,sFAAsF;;AAItF,MAAM,KAAK,GAAU;IACnB,MAAM,EAAE,GAAG,EAAE;QACX,OAAO,OAAO,CAAC,GAAG,CAAC;IACrB,CAAC;IAED,OAAO,EAAE,GAAG,EAAE;QACZ,OAAO,KAAK,CAAC,MAAM,EAAE,EAAE,IAAI,CAAC,CAAC;IAC/B,CAAC;CACF,CAAC;AAEF,kBAAe,KAAK,CAAC"} |
| import WASI from "wasi-js"; | ||
| import type { WASIConfig } from "wasi-js"; | ||
| import WasmInstanceSync from "./instance"; | ||
| interface Options { | ||
| wasiConfig: WASIConfig; | ||
| memory: WebAssembly.Memory; | ||
| wasi: WASI; | ||
| noStdio: boolean; | ||
| } | ||
| export default class PosixContext { | ||
| private posixEnv; | ||
| private wasm?; | ||
| private wasi; | ||
| private memory; | ||
| private context; | ||
| private wasiConfig; | ||
| constructor({ wasiConfig, memory, wasi, noStdio }: Options); | ||
| private createPosixEnv; | ||
| init(wasm: WasmInstanceSync): void; | ||
| injectFunctions({ env, wasi_snapshot_preview1, }: { | ||
| env: { | ||
| [name: string]: Function; | ||
| }; | ||
| wasi_snapshot_preview1: { | ||
| [name: string]: Function; | ||
| }; | ||
| }): void; | ||
| private callWithString; | ||
| private callFunction; | ||
| private getcwd; | ||
| private free; | ||
| private run; | ||
| } | ||
| export {}; |
| "use strict"; | ||
| var __importDefault = (this && this.__importDefault) || function (mod) { | ||
| return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
| }; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| const posix_1 = __importDefault(require("../posix")); | ||
| const send_to_wasm_1 = __importDefault(require("./send-to-wasm")); | ||
| const recv_from_wasm_1 = __importDefault(require("./recv-from-wasm")); | ||
| const lodash_1 = require("lodash"); | ||
| const debug_1 = __importDefault(require("debug")); | ||
| const log = (0, debug_1.default)("kernel:posix-context"); | ||
| class PosixContext { | ||
| constructor({ wasiConfig, memory, wasi, noStdio }) { | ||
| log("noStdio", noStdio); | ||
| this.memory = memory; | ||
| this.wasi = wasi; | ||
| this.wasiConfig = wasiConfig; | ||
| const { bindings, sleep } = wasiConfig; | ||
| const callFunction = this.callFunction.bind(this); | ||
| const callWithString = this.callWithString.bind(this); | ||
| this.posixEnv = this.createPosixEnv({ | ||
| memory, | ||
| wasi, | ||
| bindings, | ||
| callFunction, | ||
| callWithString, | ||
| sleep, | ||
| noStdio, | ||
| }); | ||
| } | ||
| createPosixEnv({ bindings, memory, wasi, callFunction, callWithString, sleep, noStdio, }) { | ||
| this.context = { | ||
| state: {}, | ||
| fs: bindings.fs, | ||
| send: new send_to_wasm_1.default({ memory, callFunction }), | ||
| recv: new recv_from_wasm_1.default({ memory, callFunction }), | ||
| wasi, | ||
| run: this.run.bind(this), | ||
| process, | ||
| os: bindings.os ?? {}, | ||
| posix: bindings.posix ?? {}, | ||
| child_process: bindings.child_process ?? {}, | ||
| memory, | ||
| callFunction, | ||
| callWithString, | ||
| getcwd: this.getcwd.bind(this), | ||
| free: this.free.bind(this), | ||
| sleep, | ||
| noStdio, | ||
| }; | ||
| return (0, posix_1.default)(this.context); | ||
| } | ||
| init(wasm) { | ||
| this.wasm = wasm; | ||
| this.posixEnv.init(); | ||
| } | ||
| // set all the posix functions in env, but do NOT overwrite | ||
| // anything that is already set. Also, add socket functionality | ||
| // to wasi. | ||
| injectFunctions({ env, wasi_snapshot_preview1, }) { | ||
| for (const name in this.posixEnv) { | ||
| if (env[name] == null) { | ||
| env[name] = this.posixEnv[name]; | ||
| } | ||
| } | ||
| // Add socket functionality to WASI. This just works around | ||
| // that there is a tiny amount in wasi v0 itself and we have | ||
| // to replace it. Someday wasi may have more that we have | ||
| // to replace or implement. See | ||
| // https://github.com/WebAssembly/wasi-sockets/ | ||
| for (const name of [ | ||
| "recv", | ||
| "send", | ||
| "shutdown", | ||
| "fcntlSetFlags", | ||
| "pollSocket", | ||
| ]) { | ||
| if (this.posixEnv[name] != null) { | ||
| wasi_snapshot_preview1[`sock_${name}`] = this.posixEnv[name]; | ||
| } | ||
| } | ||
| } | ||
| callWithString(func, str, ...args) { | ||
| if (this.wasm == null) { | ||
| throw Error("wasm must be define"); | ||
| } | ||
| return this.wasm.callWithString(func, str, ...args); | ||
| } | ||
| callFunction(name, ...args) { | ||
| if (this.wasm == null) { | ||
| throw Error("wasm must be define"); | ||
| } | ||
| const f = this.wasm.getFunction(name); | ||
| if (f == null) { | ||
| throw Error(`error - ${name} is not defined`); | ||
| } | ||
| return f(...args); | ||
| } | ||
| getcwd() { | ||
| if (this.wasm == null) { | ||
| throw Error("wasm must be define"); | ||
| } | ||
| if (this.wasm.getcwd == null) { | ||
| throw Error(`error - getcwd is not defined`); | ||
| } | ||
| return this.wasm.getcwd(); | ||
| } | ||
| free(ptr) { | ||
| this.wasm?.exports.c_free(ptr); | ||
| } | ||
| run(args) { | ||
| log("run", args); | ||
| const { wasm } = this; | ||
| if (wasm == null) { | ||
| throw Error("wasm must be define"); | ||
| } | ||
| const path = args[0]; | ||
| if (path == null) { | ||
| throw Error("args must have length at least 1"); | ||
| } | ||
| // save memory and function caching context | ||
| const state = { | ||
| memory: new Uint8Array(this.memory.buffer).slice(), | ||
| context: this.context.state, | ||
| wasi: this.wasi.getState(), | ||
| exit: this.wasiConfig.bindings.exit, | ||
| dlopen: wasm.instance.getDlopenState(), | ||
| }; | ||
| // I wonder if I could use immer.js instead for any of this? It might be slower. | ||
| this.context.state = (0, lodash_1.cloneDeep)(state.context); | ||
| const wasi_state = (0, lodash_1.cloneDeep)(state.wasi); | ||
| let return_code = -1; // not set ==> something went wrong since exit never called. | ||
| wasi_state.bindings.exit = (code) => { | ||
| // uncomment this for debugging only | ||
| // console.trace(`exit(${code}) called`); | ||
| return_code = code; | ||
| // after this, the main call below throws an exception | ||
| // then the return_code gets returned right after the | ||
| // finally cleansthings up. | ||
| }; | ||
| try { | ||
| this.wasi.setState(wasi_state); | ||
| let main; | ||
| try { | ||
| // this does dlopen of args[0]: | ||
| main = wasm.getFunction("__main_argc_argv", args[0]); | ||
| if (main == null) { | ||
| throw Error("__main_argc_argv is null"); | ||
| } | ||
| } | ||
| catch (_err) { | ||
| try { | ||
| main = wasm.getFunction("main", args[0]); | ||
| if (main == null) { | ||
| throw Error("main and __main_argc_argv are both null"); | ||
| } | ||
| } | ||
| catch (err) { | ||
| console.error(`${args[0]}: ${err}`); | ||
| return 127; | ||
| } | ||
| } | ||
| try { | ||
| return main(args.length, wasm.send.arrayOfStrings(args)); | ||
| } | ||
| catch (err) { | ||
| if (return_code == -1) { | ||
| // code did not get set -- something crashed badly. | ||
| console.error(args[0], err); | ||
| return 139; // segfault return code. | ||
| } | ||
| } | ||
| if (return_code == -1) { | ||
| // code did not get set -- something bad? | ||
| return 139; // segfault return code. | ||
| } | ||
| return return_code; | ||
| } | ||
| finally { | ||
| // Free up tables allocated to the dynamic library in Javascript memory. These | ||
| // would persist even after resetting memory below, which would break everything. | ||
| wasm.instance.setDlopenState(state.dlopen); | ||
| // Restore memory to how it was before running the subprocess. | ||
| // This of course safely frees up and undoes all changes made to | ||
| // the memory when running code. | ||
| new Uint8Array(this.memory.buffer).set(state.memory); | ||
| // Restore posix context to before running the subprocess. | ||
| this.context.state = state.context; | ||
| this.wasi.setState(state.wasi); | ||
| } | ||
| } | ||
| } | ||
| exports.default = PosixContext; | ||
| //# sourceMappingURL=posix-context.js.map |
| {"version":3,"file":"posix-context.js","sourceRoot":"","sources":["../../../src/wasm/worker/posix-context.ts"],"names":[],"mappings":"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"} |
| /// <reference types="node" /> | ||
| interface Options { | ||
| memory: WebAssembly.Memory; | ||
| callFunction: (strings: any, ...args: any[]) => number | undefined; | ||
| } | ||
| export declare class RecvFromWasmAbstractBase { | ||
| protected memory: WebAssembly.Memory; | ||
| protected callFunction: (strings: any, ...args: any[]) => number | undefined; | ||
| protected view(): DataView; | ||
| strlen(charPtr: number): number; | ||
| pointer(ptr: number): number; | ||
| u32(ptr: number): number; | ||
| i32(ptr: number): number; | ||
| pointer2(ptr: number): number; | ||
| string(ptr: number, bytes?: number): string; | ||
| buffer(ptr: number, bytes: number): Buffer; | ||
| arrayOfStrings(ptr: number): string[]; | ||
| arrayOfI32(ptr: number): number[]; | ||
| } | ||
| export default class RecvFromWasm extends RecvFromWasmAbstractBase { | ||
| constructor({ memory, callFunction }: Options); | ||
| } | ||
| export {}; |
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.RecvFromWasmAbstractBase = void 0; | ||
| const textDecoder = new TextDecoder(); | ||
| // size of a pointer in bytes | ||
| const SIZEOF_POINTER = 4; | ||
| class RecvFromWasmAbstractBase { | ||
| // always get the view any time after a malloc may have happened! | ||
| view() { | ||
| return new DataView(this.memory.buffer); | ||
| } | ||
| // Returns the number of *bytes* in a char*. | ||
| strlen(charPtr) { | ||
| // TODO: benchmark the JS vs wasm implementation! | ||
| // return this.callFunction("stringLength", charPtr); | ||
| const mem = new Uint8Array(this.memory.buffer); | ||
| let i = charPtr; | ||
| while (mem[i]) { | ||
| i += 1; | ||
| } | ||
| return i - charPtr; | ||
| } | ||
| pointer(ptr) { | ||
| return this.view().getUint32(ptr, true); | ||
| } | ||
| u32(ptr) { | ||
| return this.view().getUint32(ptr, true); | ||
| } | ||
| i32(ptr) { | ||
| return this.view().getInt32(ptr, true); | ||
| } | ||
| pointer2(ptr) { | ||
| return new Uint32Array(this.memory.buffer)[ptr]; | ||
| } | ||
| // len is the number of bytes, not the number of utf-8 characters. | ||
| string(ptr, bytes) { | ||
| if (bytes == null) { | ||
| // no len in bytes given, so assume it is a null terminated string. | ||
| bytes = this.strlen(ptr); | ||
| if (bytes == null) | ||
| throw Error("bug"); | ||
| } | ||
| const slice = this.memory.buffer.slice(ptr, ptr + bytes); | ||
| return textDecoder.decode(slice); | ||
| } | ||
| buffer(ptr, bytes) { | ||
| // console.log(this.memory.buffer.slice(ptr, ptr + bytes)); | ||
| // this.memory.buffer.slice makes a copy of the memory. | ||
| return Buffer.from(this.memory.buffer.slice(ptr, ptr + bytes)); | ||
| } | ||
| // Receive a null-terminated array of strings. | ||
| arrayOfStrings(ptr) { | ||
| const v = []; | ||
| while (true) { | ||
| const p = this.pointer(ptr); | ||
| if (!p) | ||
| break; | ||
| v.push(this.string(p)); | ||
| ptr += SIZEOF_POINTER; | ||
| } | ||
| return v; | ||
| } | ||
| // Receive a null-terminated array of ints | ||
| arrayOfI32(ptr) { | ||
| const v = []; | ||
| if (ptr == 0) { | ||
| return v; | ||
| } | ||
| while (true) { | ||
| const p = this.pointer(ptr); | ||
| if (!p) | ||
| break; | ||
| v.push(this.i32(p)); | ||
| ptr += SIZEOF_POINTER; | ||
| } | ||
| return v; | ||
| } | ||
| } | ||
| exports.RecvFromWasmAbstractBase = RecvFromWasmAbstractBase; | ||
| class RecvFromWasm extends RecvFromWasmAbstractBase { | ||
| constructor({ memory, callFunction }) { | ||
| super(); | ||
| this.memory = memory; | ||
| this.callFunction = callFunction; | ||
| } | ||
| } | ||
| exports.default = RecvFromWasm; | ||
| //# sourceMappingURL=recv-from-wasm.js.map |
| {"version":3,"file":"recv-from-wasm.js","sourceRoot":"","sources":["../../../src/wasm/worker/recv-from-wasm.ts"],"names":[],"mappings":"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"} |
| /// <reference types="node" /> | ||
| interface Options { | ||
| memory: WebAssembly.Memory; | ||
| callFunction: (strings: any, ...args: any[]) => number | undefined; | ||
| } | ||
| export declare class SendToWasmAbstractBase { | ||
| protected memory: WebAssembly.Memory; | ||
| protected callFunction: (strings: any, ...args: any[]) => number | undefined; | ||
| malloc(bytes: number): number; | ||
| free(ptr: number): void; | ||
| protected view(): DataView; | ||
| pointer(address: number, ptr: number): void; | ||
| i32(ptr: number, value: number): void; | ||
| f64(ptr: number, value: number): void; | ||
| f32(ptr: number, value: number): void; | ||
| u32(ptr: number, value: number): void; | ||
| string(str: string, dest?: { | ||
| ptr: number; | ||
| len: number; | ||
| }): number; | ||
| encodedString(strAsArray: any, dest?: { | ||
| ptr: number; | ||
| len: number; | ||
| }): number; | ||
| arrayOfStrings(v: string[]): number; | ||
| buffer(buf: Buffer, ptr?: number): number; | ||
| } | ||
| export default class SendToWasm extends SendToWasmAbstractBase { | ||
| constructor({ memory, callFunction }: Options); | ||
| } | ||
| export {}; |
| "use strict"; | ||
| /* | ||
| Functions for sending objects from Javascript to WASM. | ||
| */ | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.SendToWasmAbstractBase = void 0; | ||
| const encoder = new TextEncoder(); | ||
| class SendToWasmAbstractBase { | ||
| // malloc is public in Send since it's "sending random bytes". | ||
| malloc(bytes) { | ||
| const ptr = this.callFunction("c_malloc", bytes); | ||
| if (!ptr) { | ||
| throw Error("Out of Memory"); | ||
| } | ||
| return ptr; | ||
| } | ||
| free(ptr) { | ||
| this.callFunction("c_free", ptr); | ||
| } | ||
| // always get the view any time after a malloc may have happened! | ||
| view() { | ||
| return new DataView(this.memory.buffer); | ||
| } | ||
| pointer(address, ptr) { | ||
| this.view().setUint32(address, ptr, true); // true = little endian!! | ||
| } | ||
| i32(ptr, value) { | ||
| this.view().setInt32(ptr, value, true); | ||
| } | ||
| f64(ptr, value) { | ||
| this.view().setFloat64(ptr, value, true); | ||
| } | ||
| f32(ptr, value) { | ||
| this.view().setFloat32(ptr, value, true); | ||
| } | ||
| u32(ptr, value) { | ||
| this.view().setUint32(ptr, value, true); | ||
| } | ||
| // WARNING: this returns a pointer to memory that | ||
| // was malloced. Depending on your use, you might | ||
| // want to free it. | ||
| // If dest is given, that's a pointer to where to copy | ||
| // the string (null terminated), with a bound of len bytes | ||
| // including a terminating null byte. | ||
| // Caller is responsible for freeing the returned char* from stringToU8 | ||
| // using this.exports.c_free, e.g., as done in callWithString here. | ||
| // If dest and len are given, string is copied into memory starting | ||
| // at dest instead, but truncated to len (including the null byte). | ||
| string(str, dest) { | ||
| return this.encodedString(encoder.encode(str), dest); | ||
| } | ||
| // same as string above, but input is already encoded. | ||
| encodedString(strAsArray, dest) { | ||
| if (dest != null) { | ||
| if (!dest.len) { | ||
| console.warn("send-to-wasm: encodedString -- suspicious dest.len = 0!"); | ||
| } | ||
| strAsArray = strAsArray.slice(0, dest.len - 1); // ensure it will fit | ||
| } | ||
| const len = strAsArray.length + 1; | ||
| const ptr = dest?.ptr ?? this.malloc(len); | ||
| const array = new Int8Array(this.memory.buffer, ptr, len); | ||
| array.set(strAsArray); | ||
| array[len - 1] = 0; | ||
| return ptr; | ||
| } | ||
| // This is null terminated, i.e., it's "*char[]", where the last char[] is 0, | ||
| // which is what a lot of posix functions want. | ||
| arrayOfStrings(v) { | ||
| const ptr = this.malloc(4 * (v.length + 1)); | ||
| for (let i = 0; i < v.length; i++) { | ||
| const sPtr = this.string(v[i]); | ||
| this.pointer(ptr + 4 * i, sPtr); | ||
| } | ||
| this.pointer(ptr + 4 * v.length, 0); | ||
| return ptr; | ||
| } | ||
| buffer(buf, ptr) { | ||
| if (ptr == null) { | ||
| ptr = this.malloc(buf.byteLength); | ||
| } | ||
| const array = new Uint8Array(this.memory.buffer); | ||
| buf.copy(array, ptr); | ||
| return ptr; | ||
| } | ||
| } | ||
| exports.SendToWasmAbstractBase = SendToWasmAbstractBase; | ||
| class SendToWasm extends SendToWasmAbstractBase { | ||
| constructor({ memory, callFunction }) { | ||
| super(); | ||
| this.memory = memory; | ||
| this.callFunction = callFunction; | ||
| } | ||
| } | ||
| exports.default = SendToWasm; | ||
| //# sourceMappingURL=send-to-wasm.js.map |
| {"version":3,"file":"send-to-wasm.js","sourceRoot":"","sources":["../../../src/wasm/worker/send-to-wasm.ts"],"names":[],"mappings":"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"} |
| declare function delay(milliseconds: any): Promise<any>; | ||
| declare function handleSleep(e: any): Promise<Response>; | ||
| declare function handleWriteSignal(e: any): Promise<Response>; | ||
| declare function handleReadSignal(e: any): Promise<Response>; | ||
| declare function handleWriteStdin(e: any): Promise<Response>; | ||
| declare function waitForStdin(id: any, milliseconds?: number): Promise<void>; | ||
| declare function handleReadStdin(e: any): Promise<Response>; | ||
| declare function handleWriteOutput(e: any): Promise<Response>; | ||
| declare function handleReadOutput(e: any): Promise<Response>; | ||
| declare const VERSION: 6; | ||
| declare function log(...args: any[]): void; | ||
| declare const PREFIX: "/python-wasm-sw/"; | ||
| declare namespace cache { | ||
| const sig: {}; | ||
| const stdin: {}; | ||
| const callOnStdin: {}; | ||
| const output: {}; | ||
| } |
| /* | ||
| NOTES: | ||
| - This is not in typescript and can't use require without using a webpack plugin | ||
| or complicating the configuration, as explained here | ||
| https://stackoverflow.com/questions/64549183/how-to-load-a-service-worker-using-webpack-5 | ||
| We choose to keep this low level due to our usability requirements. | ||
| - To debug in chrome, look at chrome://inspect/#service-workers | ||
| - Requires https, except on localhost with chrome or firefox + special config. | ||
| - IMPORTANT! On Safari it is **absolutely critical** that this only take a few seconds max to | ||
| respond to any requests. If it takes longer, then Safari kills the service worker and blacklists | ||
| it so it won't work at all. Perhaps Firefox and Chrome might do something similar, but | ||
| with different parameters, though I didn't see that. Figuring out that this is the case | ||
| was pretty difficult for me, since I couldn't find it in any docs anywhere, and somehow I | ||
| just figured it out. That's why we have a timeout for waiting for stdin, and similar | ||
| comments in io-using-service-worker.ts. | ||
| REFERENCES: | ||
| - This blog post was helpful: https://jasonformat.com/javascript-sleep/ | ||
| - This library: https://github.com/alexmojaki/sync-message | ||
| */ | ||
| // Version is only used for some logging right now. | ||
| const VERSION = 6; | ||
| const log = (...args) => { | ||
| // for debugging, uncomment this. | ||
| //console.log("service-worker.js - v", VERSION, ...args); | ||
| }; | ||
| // This MUST match what's in io-using-service-worker.ts and ../io-using-service-worker.ts | ||
| const PREFIX = "/python-wasm-sw/"; | ||
| self.addEventListener("install", (e) => { | ||
| log("install - python-wasm service worker, version: ", VERSION, e); | ||
| }); | ||
| self.addEventListener("activate", (e) => { | ||
| log("activate - python-wasm service worker, version: ", VERSION, e); | ||
| }); | ||
| function delay(milliseconds) { | ||
| return new Promise((resolve) => setTimeout(resolve, milliseconds)); | ||
| } | ||
| async function handleSleep(e) { | ||
| const body = await e.request.json(); | ||
| const ms = Math.round(body?.ms) ?? 100; | ||
| log("sleep", ms); | ||
| await delay(ms); | ||
| return new Response({ status: 304 }); | ||
| } | ||
| const cache = { | ||
| sig: {}, | ||
| stdin: {}, | ||
| callOnStdin: {}, | ||
| output: {}, | ||
| }; | ||
| async function handleWriteSignal(e) { | ||
| const { sig, id } = await e.request.json(); | ||
| log("signal", { id, sig }); | ||
| cache.sig[id] = sig; | ||
| return new Response(`${sig}`, { status: 200 }); | ||
| } | ||
| async function handleReadSignal(e) { | ||
| const { clear, id } = await e.request.json(); | ||
| const curSig = cache.sig[id] ?? 0; | ||
| if (clear) { | ||
| cache.sig[id] = 0; | ||
| } | ||
| return new Response(`${curSig}`, { status: 200 }); | ||
| } | ||
| async function handleWriteStdin(e) { | ||
| const { data, id } = await e.request.json(); | ||
| log("write to stdin", { id, data }); | ||
| if (cache.stdin[id] == null) { | ||
| cache.stdin[id] = data; | ||
| } | ||
| else { | ||
| cache.stdin[id] += data; | ||
| } | ||
| const f = cache.callOnStdin[id]; | ||
| if (f != null) { | ||
| f(); | ||
| cache.callOnStdin[id] = null; | ||
| } | ||
| return new Response(`${cache.stdin[id].length}`, { status: 200 }); | ||
| } | ||
| // Wait up to milliseconds for new stdin. Throws an error | ||
| // if not appears. | ||
| // NOTE: this will NOT get called more than once at the same time | ||
| // for the same id because the client is a single threaded synchronous | ||
| // WASM process. That's why cache.callOnStdin[id] is a single function | ||
| // instead of a list of functions. | ||
| async function waitForStdin(id, milliseconds = 3000) { | ||
| if (cache.stdin[id]) { | ||
| // DONE: there is already input waiting. | ||
| return; | ||
| } | ||
| // We make a promise that resolves when input arrives | ||
| // and rejects if the amount of time elapses. This code | ||
| // feels a bit awkward, but works. | ||
| await new Promise((resolve, reject) => { | ||
| let resolved = false; | ||
| let cancelled = false; | ||
| let timer = 0; | ||
| const f = () => { | ||
| if (cancelled) | ||
| return; | ||
| clearTimeout(timer); | ||
| resolved = true; | ||
| resolve(); | ||
| }; | ||
| cache.callOnStdin[id] = f; | ||
| timer = setTimeout(() => { | ||
| if (!resolved) { | ||
| cache.callOnStdin[id] = null; | ||
| cancelled = true; | ||
| reject("timeout"); | ||
| } | ||
| }, milliseconds); | ||
| }); | ||
| } | ||
| async function handleReadStdin(e) { | ||
| const { id, ms } = await e.request.json(); | ||
| log("read from stdin", { id }); | ||
| // wait until there is something in stdin | ||
| try { | ||
| await waitForStdin(id, ms ?? 3000); | ||
| } | ||
| catch (_err) { | ||
| // Just ignore the error and send back "" below is fine. | ||
| } | ||
| const data = cache.stdin[id]; | ||
| cache.stdin[id] = ""; | ||
| return new Response(data, { status: 200 }); | ||
| } | ||
| async function handleWriteOutput(e) { | ||
| let { stream, data, id } = await e.request.json(); | ||
| log("write to output", { id, stream, data }); | ||
| if (!cache.output[id]) { | ||
| cache.output[id] = stream; | ||
| } | ||
| else if (cache.output[id][0] != stream) { | ||
| const start = new Date().valueOf(); | ||
| let d = 1; | ||
| while (cache.output[id] && cache.output[id][0] != stream) { | ||
| if (new Date().valueOf() - start > 3000) { | ||
| // give up -- shouldn't happen since frontend should handle | ||
| // all IO within a fraction of a second. | ||
| return new Response("", { status: 200 }); | ||
| } | ||
| await delay(d); | ||
| d = Math.min(d * 1.3, 200); | ||
| } | ||
| if (!cache.output[id]) { | ||
| cache.output[id] = stream; | ||
| } | ||
| } | ||
| cache.output[id] += data; | ||
| return new Response("", { status: 200 }); | ||
| } | ||
| // Unlike handleReadStdin, this doesn't wait for stdin to be available, | ||
| // and instead reads what is already in the buffer. | ||
| async function handleReadOutput(e) { | ||
| const { id } = await e.request.json(); | ||
| const data = cache.output[id]; | ||
| cache.output[id] = ""; | ||
| return new Response(data, { status: 200 }); | ||
| } | ||
| self.addEventListener("fetch", (e) => { | ||
| const { pathname } = new URL(e.request.url); | ||
| if (!pathname.startsWith(PREFIX)) { | ||
| return false; | ||
| } | ||
| switch (pathname.slice(PREFIX.length)) { | ||
| case "sleep": | ||
| e.respondWith(handleSleep(e)); | ||
| return; | ||
| case "write-stdin": | ||
| e.respondWith(handleWriteStdin(e)); | ||
| return; | ||
| case "read-stdin": | ||
| e.respondWith(handleReadStdin(e)); | ||
| return; | ||
| case "write-output": | ||
| e.respondWith(handleWriteOutput(e)); | ||
| return; | ||
| case "read-output": | ||
| e.respondWith(handleReadOutput(e)); | ||
| return; | ||
| case "write-signal": | ||
| e.respondWith(handleWriteSignal(e)); | ||
| return; | ||
| case "read-signal": | ||
| e.respondWith(handleReadSignal(e)); | ||
| return; | ||
| } | ||
| }); | ||
| //# sourceMappingURL=service-worker.js.map |
| {"version":3,"file":"service-worker.js","sourceRoot":"","sources":["../../../src/wasm/worker/service-worker.js"],"names":[],"mappings":"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"} |
| export default function initPythonTrampolineCalls(table: WebAssembly.Table, env: object): void; |
| "use strict"; | ||
| var __importDefault = (this && this.__importDefault) || function (mod) { | ||
| return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
| }; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| /* Python Trampoline Calls */ | ||
| const debug_1 = __importDefault(require("debug")); | ||
| const log = (0, debug_1.default)("python-wasm-trampoline"); | ||
| function initPythonTrampolineCalls(table, env) { | ||
| env["_PyImport_InitFunc_TrampolineCall"] = (ptr) => { | ||
| const r = table.get(ptr)(); | ||
| log("_PyImport_InitFunc_TrampolineCall - ptr=", ptr, " r=", r); | ||
| return r; | ||
| }; | ||
| env["_PyCFunctionWithKeywords_TrampolineCall"] = (ptr, self, args, kwds) => { | ||
| // log("_PyCFunctionWithKeywords_TrampolineCall - ptr=", ptr); | ||
| return table.get(ptr)(self, args, kwds); | ||
| }; | ||
| env["descr_set_trampoline_call"] = (set, obj, value, closure) => { | ||
| // log("descr_set_trampoline_call"); | ||
| return table.get(set)(obj, value, closure); | ||
| }; | ||
| env["descr_get_trampoline_call"] = (get, obj, closure) => { | ||
| // log("descr_get_trampoline_call"); | ||
| return table.get(get)(obj, closure); | ||
| }; | ||
| } | ||
| exports.default = initPythonTrampolineCalls; | ||
| //# sourceMappingURL=trampoline.js.map |
| {"version":3,"file":"trampoline.js","sourceRoot":"","sources":["../../../src/wasm/worker/trampoline.ts"],"names":[],"mappings":";;;;;AAAA,6BAA6B;AAC7B,kDAA0B;AAC1B,MAAM,GAAG,GAAG,IAAA,eAAK,EAAC,wBAAwB,CAAC,CAAC;AAE5C,SAAwB,yBAAyB,CAC/C,KAAwB,EACxB,GAAW;IAEX,GAAG,CAAC,mCAAmC,CAAC,GAAG,CAAC,GAAW,EAAU,EAAE;QACjE,MAAM,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;QAC3B,GAAG,CAAC,0CAA0C,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;QAC/D,OAAO,CAAC,CAAC;IACX,CAAC,CAAC;IAEF,GAAG,CAAC,yCAAyC,CAAC,GAAG,CAC/C,GAAW,EACX,IAAY,EACZ,IAAY,EACZ,IAAY,EACZ,EAAE;QACF,8DAA8D;QAC9D,OAAO,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;IAC1C,CAAC,CAAC;IAEF,GAAG,CAAC,2BAA2B,CAAC,GAAG,CACjC,GAAW,EACX,GAAW,EACX,KAAa,EACb,OAAe,EACf,EAAE;QACF,oCAAoC;QACpC,OAAO,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;IAC7C,CAAC,CAAC;IAEF,GAAG,CAAC,2BAA2B,CAAC,GAAG,CACjC,GAAW,EACX,GAAW,EACX,OAAe,EACf,EAAE;QACF,oCAAoC;QACpC,OAAO,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IACtC,CAAC,CAAC;AACJ,CAAC;AAtCD,4CAsCC"} |
| /// <reference types="node" /> | ||
| export declare enum Stream { | ||
| STDOUT = 1, | ||
| STDERR = 2 | ||
| } | ||
| export interface IOHandlerClass { | ||
| sleep: (milliseconds: number) => void; | ||
| getStdin: (milliseconds?: number) => Buffer; | ||
| getSignalState: () => number; | ||
| sendOutput(stream: Stream, data: Buffer): void; | ||
| } |
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.Stream = void 0; | ||
| var Stream; | ||
| (function (Stream) { | ||
| Stream[Stream["STDOUT"] = 1] = "STDOUT"; | ||
| Stream[Stream["STDERR"] = 2] = "STDERR"; | ||
| })(Stream = exports.Stream || (exports.Stream = {})); | ||
| //# sourceMappingURL=types.js.map |
| {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/wasm/worker/types.ts"],"names":[],"mappings":";;;AAAA,IAAY,MAGX;AAHD,WAAY,MAAM;IAChB,uCAAU,CAAA;IACV,uCAAU,CAAA;AACZ,CAAC,EAHW,MAAM,GAAN,cAAM,KAAN,cAAM,QAGjB"} |
Sorry, the diff of this file is not supported yet
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Shell access
Supply chain riskThis module accesses the system shell. Accessing the system shell increases the risk of executing arbitrary code.
Found 1 instance in 1 package
Debug access
Supply chain riskUses debug, reflection and dynamic code execution features.
Found 3 instances in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 3 instances in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 2 instances in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
13
30%0
-100%1
-95.24%52994
-95.28%7
-95.21%40
-99.38%