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.

184 lines 7.35 kB
import { SharedBufferView } from "../web-assembly/shared-memory/shared-buffer-view.js"; import { _Debug } from "../debug/_debug.js"; import { numberGetHexString } from "../number/impl/number-get-hex-string.js"; /** * @public * Matches ENumberIdentifier in `RTTI.hpp`. */ export var ENumberIdentifier; (function (ENumberIdentifier) { ENumberIdentifier[ENumberIdentifier["U8"] = 0] = "U8"; ENumberIdentifier[ENumberIdentifier["U16"] = 1] = "U16"; ENumberIdentifier[ENumberIdentifier["U32"] = 2] = "U32"; ENumberIdentifier[ENumberIdentifier["U64"] = 3] = "U64"; ENumberIdentifier[ENumberIdentifier["I8"] = 4] = "I8"; ENumberIdentifier[ENumberIdentifier["I16"] = 5] = "I16"; ENumberIdentifier[ENumberIdentifier["I32"] = 6] = "I32"; ENumberIdentifier[ENumberIdentifier["I64"] = 7] = "I64"; ENumberIdentifier[ENumberIdentifier["F32"] = 8] = "F32"; ENumberIdentifier[ENumberIdentifier["F64"] = 9] = "F64"; })(ENumberIdentifier || (ENumberIdentifier = {})); /** * @public * Given a typed array constructor, get the identifier which matches up with ENumberIdentifier in `RTTI.hpp`. */ export function getNumberIdentifier(ctor) { _BUILD.DEBUG && _Debug.assert(numberIdentifierMapping.has(ctor), "expected to find ctor..."); return numberIdentifierMapping.get(ctor); } const numberIdentifierMapping = new Map([ [Uint8Array, ENumberIdentifier.U8], [Uint8ClampedArray, ENumberIdentifier.U8], [Uint16Array, ENumberIdentifier.U16], [Uint32Array, ENumberIdentifier.U32], [BigUint64Array, ENumberIdentifier.U64], [Int8Array, ENumberIdentifier.I8], [Int16Array, ENumberIdentifier.I16], [Int32Array, ENumberIdentifier.I32], [BigInt64Array, ENumberIdentifier.I64], [Float32Array, ENumberIdentifier.F32], [Float64Array, ENumberIdentifier.F64], ]); /** * @public * Mirrors the C++ class of the same name. This can be used as a key to get a unique number which can be matched on the C++ side. */ export class StableId { constructor(name) { this.name = name; } } /** * @public * Mirrors the C++ class of the same name. Each category can have multiple kinds of specializations. * * @remarks There should only be one instance of a conceptual class (which should have a unique name) */ export class IdCategory extends StableId { } /** * @public * Mirrors the C++ class of the same name. A specialization of a conceptual category. E.g. a number (category) which is a float 32 (specialization). * * @remarks There should only be one instance of a conceptual class (which should have a unique name) */ export class IdSpecialization extends StableId { constructor(category, specializationName) { super(specializationName); this.category = category; } } /** * @public * Supported types of number across C++ and JavaScript. */ export const numberCategory = new IdCategory("JSU_NUMBER"); /** * @public * A buffer that can be shared with C++. */ export const bufferCategory = new IdCategory("JSU_BUFFER"); /** * @public * Given a Typed array constructor, get back the associated {@link StableId}. */ export function getNumberSpecialization(ctor) { return numberSpecializationMapping.get(ctor); } /** * @public * {@link IdSpecialization} for all supported number types. */ export const numberSpecializations = new class NumberSpecializations { constructor() { this.u8 = new IdSpecialization(numberCategory, "JSU_U8"); this.u16 = new IdSpecialization(numberCategory, "JSU_U16"); this.u32 = new IdSpecialization(numberCategory, "JSU_U32"); this.u64 = new IdSpecialization(numberCategory, "JSU_U64"); this.i8 = new IdSpecialization(numberCategory, "JSU_I8"); this.i16 = new IdSpecialization(numberCategory, "JSU_I16"); this.i32 = new IdSpecialization(numberCategory, "JSU_I32"); this.i64 = new IdSpecialization(numberCategory, "JSU_I64"); this.f32 = new IdSpecialization(numberCategory, "JSU_F32"); this.f64 = new IdSpecialization(numberCategory, "JSU_F64"); } }(); const numberSpecializationMapping = new Map([ [Uint8Array, numberSpecializations.u8], [Uint16Array, numberSpecializations.u16], [Uint32Array, numberSpecializations.u32], [BigUint64Array, numberSpecializations.u64], [Int8Array, numberSpecializations.i8], [Int16Array, numberSpecializations.i16], [Int32Array, numberSpecializations.i32], [BigInt64Array, numberSpecializations.i64], [Float32Array, numberSpecializations.f32], [Float64Array, numberSpecializations.f64], ]); /** * @internal */ export function populateTypedArrayConstructorMap(constructors) { const m = new Map(); m.set(Float64Array, constructors.f64); m.set(Float32Array, constructors.f32); if (constructors.i64 != null) { m.set(BigInt64Array, constructors.i64); } if (constructors.u64 != null) { m.set(BigUint64Array, constructors.u64); } m.set(Int32Array, constructors.i32); m.set(Uint32Array, constructors.u32); m.set(Int16Array, constructors.i16); m.set(Uint16Array, constructors.u16); m.set(Int8Array, constructors.i8); m.set(Uint8Array, constructors.u8); m.set(Uint8ClampedArray, constructors.u8c); return m; } /** * @public * {@inheritDoc IStableStore} */ export class StableIdStore { constructor(wrapper) { this.wrapper = wrapper; this.ids = new Map(); /** * @internal */ this.idBuffer = null; } initialize() { this.idBuffer = new SharedBufferView(this.wrapper, this.wrapper.rootNode, Uint16Array, this.wrapper.instance._jsUtilGetRuntimeMappingAddress(), 32 * Uint16Array.BYTES_PER_ELEMENT); } getId(key) { let id = this.ids.get(key); if (id == null) { const namePtr = this.wrapper.instance.stringToNewUTF8(key.name); if (_BUILD.DEBUG) { _Debug.verboseLog(["WASM", "MEMORY", "ALLOCATIONS"], `StableIdStore: created temporary string at ${numberGetHexString(namePtr)} (${key.name}).`); } id = this.wrapper.instance._jsUtilGetRuntimeMappingId(namePtr); this.ids.set(key, id); this.wrapper.instance._jsUtilFree(namePtr); } return id; } setSpecializations(sharedObjectHandle, specializations) { _BUILD.DEBUG && _Debug.assert(this.idBuffer != null, "attempted to set ids before initialization happened..."); _BUILD.DEBUG && _Debug.assert(specializations.length <= 32, "a maximum of 32 specializations can be added at one time"); const idBuffer = this.idBuffer.getArray(); // [[category, specialization], ...] for (let i = 0, iEnd = specializations.length; i < iEnd; i++) { const specialization = specializations[i]; idBuffer[i * 2] = this.getId(specialization); idBuffer[i * 2 + 1] = this.getId(specialization.category); } this.wrapper.instance._jsUtilAddRuntimeMappings(specializations.length, sharedObjectHandle.pointer); } hasId(sharedObjectHandle, specialization) { return Boolean(this.wrapper.instance._jsUtilHasRuntimeMappingId(sharedObjectHandle.pointer, this.getId(specialization.category), this.getId(specialization))); } } //# sourceMappingURL=rtti-interop.js.map