CoolFace
Apppublic

Jofthomas/Everchanging-Quest

sourceHugging Faceapache-2.0updated 2y agoView on Hugging Face
187likes
index.worker.js159 linesDownload Raw Back to root
1/**2 * @license3 * Copyright 2015 The Emscripten Authors4 * SPDX-License-Identifier: MIT5 */6 7// Pthread Web Worker startup routine:8// This is the entry point file that is loaded first by each Web Worker9// that executes pthreads on the Emscripten application.10 11'use strict';12 13var Module = {};14 15// Thread-local guard variable for one-time init of the JS state16var initializedJS = false;17 18function assert(condition, text) {19  if (!condition) abort('Assertion failed: ' + text);20}21 22function threadPrintErr() {23  var text = Array.prototype.slice.call(arguments).join(' ');24  console.error(text);25}26function threadAlert() {27  var text = Array.prototype.slice.call(arguments).join(' ');28  postMessage({cmd: 'alert', text, threadId: Module['_pthread_self']()});29}30// We don't need out() for now, but may need to add it if we want to use it31// here. Or, if this code all moves into the main JS, that problem will go32// away. (For now, adding it here increases code size for no benefit.)33var out = () => { throw 'out() is not defined in worker.js.'; }34var err = threadPrintErr;35self.alert = threadAlert;36var dbg = threadPrintErr;37 38Module['instantiateWasm'] = (info, receiveInstance) => {39  // Instantiate from the module posted from the main thread.40  // We can just use sync instantiation in the worker.41  var module = Module['wasmModule'];42  // We don't need the module anymore; new threads will be spawned from the main thread.43  Module['wasmModule'] = null;44  var instance = new WebAssembly.Instance(module, info);45  // TODO: Due to Closure regression https://github.com/google/closure-compiler/issues/3193,46  // the above line no longer optimizes out down to the following line.47  // When the regression is fixed, we can remove this if/else.48  return receiveInstance(instance);49}50 51// Turn unhandled rejected promises into errors so that the main thread will be52// notified about them.53self.onunhandledrejection = (e) => {54  throw e.reason || e;55};56 57function handleMessage(e) {58  try {59    if (e.data.cmd === 'load') { // Preload command that is called once per worker to parse and load the Emscripten code.60 61    // Until we initialize the runtime, queue up any further incoming messages.62    let messageQueue = [];63    self.onmessage = (e) => messageQueue.push(e);64 65    // And add a callback for when the runtime is initialized.66    self.startWorker = (instance) => {67      Module = instance;68      // Notify the main thread that this thread has loaded.69      postMessage({ 'cmd': 'loaded' });70      // Process any messages that were queued before the thread was ready.71      for (let msg of messageQueue) {72        handleMessage(msg);73      }74      // Restore the real message handler.75      self.onmessage = handleMessage;76    };77 78      // Module and memory were sent from main thread79      Module['wasmModule'] = e.data.wasmModule;80 81      // Use `const` here to ensure that the variable is scoped only to82      // that iteration, allowing safe reference from a closure.83      for (const handler of e.data.handlers) {84        Module[handler] = (...args) => {85          postMessage({ cmd: 'callHandler', handler, args: args });86        }87      }88 89      Module['wasmMemory'] = e.data.wasmMemory;90 91      Module['buffer'] = Module['wasmMemory'].buffer;92 93      Module['workerID'] = e.data.workerID;94 95      Module['ENVIRONMENT_IS_PTHREAD'] = true;96 97      if (typeof e.data.urlOrBlob == 'string') {98        importScripts(e.data.urlOrBlob);99      } else {100        var objectUrl = URL.createObjectURL(e.data.urlOrBlob);101        importScripts(objectUrl);102        URL.revokeObjectURL(objectUrl);103      }104      Godot(Module);105    } else if (e.data.cmd === 'run') {106      // Pass the thread address to wasm to store it for fast access.107      Module['__emscripten_thread_init'](e.data.pthread_ptr, /*is_main=*/0, /*is_runtime=*/0, /*can_block=*/1);108 109      // Await mailbox notifications with `Atomics.waitAsync` so we can start110      // using the fast `Atomics.notify` notification path.111      Module['__emscripten_thread_mailbox_await'](e.data.pthread_ptr);112 113      assert(e.data.pthread_ptr);114      // Also call inside JS module to set up the stack frame for this pthread in JS module scope115      Module['establishStackSpace']();116      Module['PThread'].receiveObjectTransfer(e.data);117      Module['PThread'].threadInitTLS();118 119      if (!initializedJS) {120        initializedJS = true;121      }122 123      try {124        Module['invokeEntryPoint'](e.data.start_routine, e.data.arg);125      } catch(ex) {126        if (ex != 'unwind') {127          // The pthread "crashed".  Do not call `_emscripten_thread_exit` (which128          // would make this thread joinable).  Instead, re-throw the exception129          // and let the top level handler propagate it back to the main thread.130          throw ex;131        }132      }133    } else if (e.data.cmd === 'cancel') { // Main thread is asking for a pthread_cancel() on this thread.134      if (Module['_pthread_self']()) {135        Module['__emscripten_thread_exit'](-1);136      }137    } else if (e.data.target === 'setimmediate') {138      // no-op139    } else if (e.data.cmd === 'checkMailbox') {140      if (initializedJS) {141        Module['checkMailbox']();142      }143    } else if (e.data.cmd) {144      // The received message looks like something that should be handled by this message145      // handler, (since there is a e.data.cmd field present), but is not one of the146      // recognized commands:147      err(`worker.js received unknown command ${e.data.cmd}`);148      err(e.data);149    }150  } catch(ex) {151    err(`worker.js onmessage() captured an uncaught exception: ${ex}`);152    if (ex?.stack) err(ex.stack);153    Module['__emscripten_thread_crashed']?.();154    throw ex;155  }156};157 158self.onmessage = handleMessage;159