UNPKG

rc-js-util

Version:

A collection of TS and C++ utilities to help writing performant and correct applications, achieved through strict typing and (removable) invariant checking.

139 lines 5.86 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.EmscriptenWrapperOptions = exports.getEmscriptenWrapper = void 0; const tslib_1 = require("tslib"); const shim_web_assembly_memory_js_1 = require("../util/shim-web-assembly-memory.js"); const broadcast_channel_js_1 = require("../../eventing/broadcast-channel.js"); const _debug_js_1 = require("../../debug/_debug.js"); const debug_weak_broadcast_event_js_1 = require("../../debug/debug-weak-broadcast-event.js"); const debug_shared_object_life_cycle_checker_js_1 = require("../../debug/debug-shared-object-life-cycle-checker.js"); const debug_weak_store_js_1 = require("../../debug/debug-weak-store.js"); const rtti_interop_js_1 = require("../../runtime/rtti-interop.js"); /** * @public * Factory for creating wrapped emscripten module. */ function getEmscriptenWrapper(memory_1, emscriptenModuleFactory_1, lifecycleStrategy_1, options_1) { return tslib_1.__awaiter(this, arguments, void 0, function* (memory, emscriptenModuleFactory, lifecycleStrategy, options, extension = {}) { let debugLabel = undefined; try { if (_BUILD.DEBUG) { debugLabel = _debug_js_1._Debug.label; _debug_js_1._Debug.label = "EmscriptenWrapper"; } const memoryListener = _BUILD.DEBUG ? new debug_weak_broadcast_event_js_1.DebugWeakBroadcastChannel("onMemoryResize") : new broadcast_channel_js_1.BroadcastChannel("onMemoryResize"); const debug = new EmscriptenDebug(); const binder = new EmscriptenBinder(); if (_BUILD.DEBUG) { const debugInstance = extension; debugInstance.JSU_DEBUG_UTIL = debug; } const instance = yield emscriptenModuleFactory(Object.assign({ wasmMemory: memory, INITIAL_MEMORY: memory.buffer.byteLength, JSU_BINDER: binder }, extension)); const wrapper = new EmscriptenWrapper(memoryListener, instance, memory, debug, binder, lifecycleStrategy, options); lifecycleStrategy.setWrapper(wrapper); // this depends on the lifecycle strategy having being initialized... wrapper.interopIds.initialize(); initializeSubmodules(instance); return wrapper; } finally { if (_BUILD.DEBUG) { _debug_js_1._Debug.label = debugLabel; } } }); } exports.getEmscriptenWrapper = getEmscriptenWrapper; /** * @public */ class EmscriptenWrapperOptions { constructor(initializeCallbacks) { this.initializeCallbacks = initializeCallbacks; } extend(options) { return new EmscriptenWrapperOptions(this.initializeCallbacks.concat(options.initializeCallbacks)); } } exports.EmscriptenWrapperOptions = EmscriptenWrapperOptions; class EmscriptenWrapper { constructor(memoryResize, instance, memory, debugUtils, binder, lifecycleStrategy, options, rootNode = lifecycleStrategy.createRootNode()) { this.memoryResize = memoryResize; this.instance = instance; this.memory = memory; this.debugUtils = debugUtils; this.binder = binder; this.lifecycleStrategy = lifecycleStrategy; this.rootNode = rootNode; this.interopIds = new rtti_interop_js_1.StableIdStore(this); const state = this.state = new EWState(new DataView(memory.buffer)); // in debug builds there are retainers on the wasm memory from libraries, sidestep by passing sub-object // don't reference `this` here... (0, shim_web_assembly_memory_js_1.shimWebAssemblyMemory)(memory, (buffer, previous, delta) => { _BUILD.DEBUG && _debug_js_1._Debug.verboseLog(["WASM", "MEMORY"], `WebAssembly memory grew from ${previous} to ${previous + delta} pages.`); state.dataView = new DataView(memory.buffer); memoryResize.emit(buffer, previous, delta); }); const callbacks = options.initializeCallbacks; for (let i = 0, iEnd = callbacks.length; i < iEnd; i++) { callbacks[i](this); } } destroyLinked() { this.rootNode.getLinked().unlinkAll(); } getDataView() { return this.state.dataView; } } class EmscriptenDebug { constructor() { this.onAllocate = new debug_weak_broadcast_event_js_1.DebugWeakBroadcastChannel("debugOnAllocate"); this.protectedViews = new debug_weak_store_js_1.DebugWeakStore(); this.sharedObjectLifeCycleChecks = new debug_shared_object_life_cycle_checker_js_1.DebugSharedObjectLifeCycleChecker(); this.uniquePointers = new Set(); } error(message) { _debug_js_1._Debug.error(message); } verboseLog(tags, message) { _debug_js_1._Debug.verboseLog(tags, message); } } class EmscriptenBinder { constructor() { this.bindingObjects = new Map(); this.counter = 0; } pushBinder(interopObject) { const index = this.counter; ++this.counter; this.bindingObjects.set(index, interopObject); return index; } getBinder(index) { return this.bindingObjects.get(index); } removeBinder(index) { return this.bindingObjects.delete(index); } } class EWState { constructor(dataView) { this.dataView = dataView; } } function initializeSubmodules(instance) { const keys = Object.keys(instance); for (let i = 0, iEnd = keys.length; i < iEnd; i++) { const key = keys[i]; if (key.startsWith("_jsuInitialize")) { const fn = instance[key]; _BUILD.DEBUG && _debug_js_1._Debug.assert(fn.length === 0, "initialization function must be parameterless"); fn(); } } } //# sourceMappingURL=get-emscripten-wrapper.js.map