#include "buffer.h" #include "util.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include extern "C" { #include } template void profile_thing(int iter, const char *name, F f) { constexpr int BUFFER_SIZE = 1024; auto startTime = std::chrono::high_resolution_clock::now(); for (int i = 0; i < iter; i++) { f(); } auto endTime = std::chrono::high_resolution_clock::now(); std::cout << (std::chrono::duration_cast(endTime - startTime) .count()) / (float)iter << "ms per " << name << "\n"; } emscripten_lock_t worker_lock; std::map modulePaths; extern "C" void _embind_initialize_bindings(); void worker_start() { _embind_initialize_bindings(); emscripten_lock_raii lg(worker_lock); auto it = modulePaths.find(emscripten_wasm_worker_self_id()); if (it == modulePaths.end()) { return; } auto modulePath = it->second; modulePaths.erase(it); EM_ASM({self.__emModule = Module}); EM_ASM({ import(UTF8ToString($0)); }, modulePath.c_str()); } emscripten::val doImportInWorker(const std::string &module) { emscripten_lock_raii lg(worker_lock); emscripten_wasm_worker_t worker = emscripten_malloc_wasm_worker(/*stackSize: */ 3670016); emscripten_wasm_worker_post_function_v(worker, worker_start); modulePaths[worker] = module; EM_ASM({window.__emWasmWorkers = _wasmWorkers}); return emscripten::val::global("__emWasmWorkers")[(int)worker]; } __attribute__((noinline)) void testFaultInJs2() { EM_ASM({ throw new Error("test fault in js"); }); } __attribute__((noinline)) void testFaultInJs() { testFaultInJs2(); } EMSCRIPTEN_BINDINGS(main) { using namespace emscripten; function("doImportInWorker", &doImportInWorker); function("testFaultInJs", &testFaultInJs); }; int main() { emscripten_lock_init(&worker_lock); av_log_set_level(AV_LOG_QUIET); av_log_set_callback(nullptr); return 0; }