"use strict"; /** Relative header `id` offset. */ const ID_OFFSET = -8; /** Relative header `size` offset. */ const SIZE_OFFSET = -4; /** Unique runtime id of an `ArrayBuffer`. */ const ARRAYBUFFER_ID = 0; /** Unique runtime id of a `String`. */ const STRING_ID = 1; /** Whether BigInt arrays are supported. */ const SUPPORTS_BIGINT = typeof BigUint64Array !== "undefined"; /** Unique symbol for memoized 'this'. */ const THIS = Symbol(); /** Gets a string from an U32 and an U16 view on a memory. */ function getStringImpl(U32, U16, ptr) { var length = U32[(ptr + SIZE_OFFSET) >>> 2] >>> 1; var offset = ptr >>> 1; var parts = []; const chunkSize = 1024; while (length > chunkSize) { let last = U16[offset + chunkSize - 1]; let size = last >= 0xD800 && last < 0xDC00 ? chunkSize - 1 : chunkSize; let part = U16.subarray(offset, offset += size); parts.push(String.fromCharCode.apply(String, part)); length -= size; } return parts.join("") + String.fromCharCode.apply(String, U16.subarray(offset, offset + length)); } /** Prepares the base module prior to instantiation. */ function preInstantiate(imports) { var baseModule = {}; function getString(memory, ptr) { if (!memory) return ""; var buffer = memory.buffer; return getStringImpl(new Uint32Array(buffer), new Uint16Array(buffer), ptr); } // add common imports used by stdlib for convenience var env = (imports.env = imports.env || {}); env.abort = env.abort || function abort(mesg, file, line, colm) { var memory = baseModule.memory || env.memory; // prefer exported, otherwise try imported throw Error("abort: " + getString(memory, mesg) + " at " + getString(memory, file) + ":" + line + ":" + colm); } env.trace = env.trace || function trace(mesg, n) { var memory = baseModule.memory || env.memory; console.log("trace: " + getString(memory, mesg) + (n ? " " : "") + Array.prototype.slice.call(arguments, 2, 2 + n).join(", ")); } imports.Math = imports.Math || Math; imports.Date = imports.Date || Date; return baseModule; } /** Prepares the final module once instantiation is complete. */ function postInstantiate(baseModule, instance) { var rawExports = instance.exports; var memory = rawExports.memory; var alloc = rawExports["__alloc"]; var free = rawExports["__free"]; var setargc = rawExports["__setargc"] || function() {}; var memory_fill = rawExports["memory.fill"]; var table = rawExports.table; // Provide views for all sorts of basic values var buffer, I8, U8, I16, U16, I32, U32, F32, F64, I64, U64; /** Updates memory views if memory has grown meanwhile. */ function checkMem() { // see: https://github.com/WebAssembly/design/issues/1210 if (buffer !== memory.buffer) { buffer = memory.buffer; I8 = new Int8Array(buffer); U8 = new Uint8Array(buffer); I16 = new Int16Array(buffer); U16 = new Uint16Array(buffer); I32 = new Int32Array(buffer); U32 = new Uint32Array(buffer); if (SUPPORTS_BIGINT) { I64 = new BigInt64Array(buffer); U64 = new BigUint64Array(buffer); } F32 = new Float32Array(buffer); F64 = new Float64Array(buffer); } } checkMem(); /** Allocates a new string in the module's memory and returns its pointer. */ function newString(str) { var length = str.length; var ptr = alloc(length << 1, STRING_ID); checkMem(); for (let i = 0, j = ptr >>> 1; i < length; ++i) U16[j + i] = str.charCodeAt(i); return ptr; } baseModule.newString = newString; /** Gets a string from the module's memory by its pointer. */ function getString(ptr) { checkMem(); return getStringImpl(U32, U16, ptr); } baseModule.getString = getString; // function computeBufferSize(byteLength) { // const HEADER_SIZE = 8; // return 1 << (32 - Math.clz32(byteLength + HEADER_SIZE - 1)); // } // /** Creates a new typed array in the module's memory and returns its pointer. */ // function newArray(view, length, unsafe) { // var ctor = view.constructor; // if (ctor === Function) { // TypedArray constructor created in memory // ctor = view; // view = null; // } else { // TypedArray instance copied into memory // if (length === undefined) length = view.length; // } // var elementSize = ctor.BYTES_PER_ELEMENT; // if (!elementSize) throw Error("not a typed array"); // var byteLength = elementSize * length; // var ptr = alloc(12); // TypedArray header // var buf = alloc(computeBufferSize(byteLength)); // ArrayBuffer // checkMem(); // U32[ ptr >>> 2] = buf; // .buffer // U32[(ptr + 4) >>> 2] = 0; // .byteOffset // U32[(ptr + 8) >>> 2] = byteLength; // .byteLength // U32[ buf >>> 2] = byteLength; // .byteLength // U32[(buf + 4) >>> 2] = 0; // 0 // if (view) { // new ctor(buffer, buf + 8, length).set(view); // if (view.length < length && !unsafe) { // let setLength = elementSize * view.length; // memory_fill(buf + 8 + setLength, 0, byteLength - setLength); // } // } else if (!unsafe) { // memory_fill(buf + 8, 0, byteLength); // } // return ptr; // } // baseModule.newArray = newArray; // /** Gets a view on a typed array in the module's memory by its pointer. */ // function getArray(ctor, ptr) { // var elementSize = ctor.BYTES_PER_ELEMENT; // if (!elementSize) throw Error("not a typed array"); // checkMem(); // var buf = U32[ ptr >>> 2]; // var byteOffset = U32[(ptr + 4) >>> 2]; // var byteLength = U32[(ptr + 8) >>> 2]; // return new ctor(buffer, buf + 8 + byteOffset, (byteLength - byteOffset) / elementSize); // } // baseModule.getArray = getArray; // /** Frees a typed array in the module's memory. Must not be accessed anymore afterwards. */ // function freeArray(ptr) { // checkMem(); // var buf = U32[ptr >>> 2]; // free(buf); // free(ptr); // } // baseModule.freeArray = freeArray; // /** // * Creates a new function in the module's table and returns its pointer. Note that only actual // * WebAssembly functions, i.e. as exported by the module, are supported. // */ // function newFunction(fn) { // if (typeof fn.original === "function") fn = fn.original; // var index = table.length; // table.grow(1); // table.set(index, fn); // return index; // } // baseModule.newFunction = newFunction; // /** Gets a function by its pointer. */ // function getFunction(ptr) { // return wrapFunction(table.get(ptr), setargc); // } // baseModule.getFunction = getFunction; // Pull basic exports to baseModule so code in preInstantiate can use them baseModule.memory = baseModule.memory || memory; baseModule.table = baseModule.table || table; // Demangle exports and provide the usual utility on the prototype return demangle(rawExports, Object.defineProperties(baseModule, { I8: { get: function() { checkMem(); return I8; } }, U8: { get: function() { checkMem(); return U8; } }, I16: { get: function() { checkMem(); return I16; } }, U16: { get: function() { checkMem(); return U16; } }, I32: { get: function() { checkMem(); return I32; } }, U32: { get: function() { checkMem(); return U32; } }, I64: { get: function() { checkMem(); return I64; } }, U64: { get: function() { checkMem(); return U64; } }, F32: { get: function() { checkMem(); return F32; } }, F64: { get: function() { checkMem(); return F64; } } })); } /** Wraps a WebAssembly function while also taking care of variable arguments. */ function wrapFunction(fn, setargc) { var wrap = (...args) => { setargc(args.length); return fn(...args); } // adding a function to the table with `newFunction` is limited to actual WebAssembly functions, // hence we can't use the wrapper and instead need to provide a reference to the original wrap.original = fn; return wrap; } /** Instantiates an AssemblyScript module using the specified imports. */ function instantiate(module, imports) { return postInstantiate( preInstantiate(imports || (imports = {})), new WebAssembly.Instance(module, imports) ); } exports.instantiate = instantiate; /** Instantiates an AssemblyScript module from a buffer using the specified imports. */ function instantiateBuffer(buffer, imports) { return instantiate(new WebAssembly.Module(buffer), imports); } exports.instantiateBuffer = instantiateBuffer; /** Instantiates an AssemblyScript module from a response using the specified imports. */ async function instantiateStreaming(response, imports) { return postInstantiate( preInstantiate(imports || (imports = {})), (await WebAssembly.instantiateStreaming(response, imports)).instance ); } exports.instantiateStreaming = instantiateStreaming; /** Demangles an AssemblyScript module's exports to a friendly object structure. */ function demangle(exports, baseModule) { var module = baseModule ? Object.create(baseModule) : {}; var setargc = exports["__setargc"] || function() {}; function hasOwnProperty(elem, prop) { return Object.prototype.hasOwnProperty.call(elem, prop); } for (let internalName in exports) { if (!hasOwnProperty(exports, internalName)) continue; let elem = exports[internalName]; let parts = internalName.split("."); let curr = module; while (parts.length > 1) { let part = parts.shift(); if (!hasOwnProperty(curr, part)) curr[part] = {}; curr = curr[part]; } let name = parts[0]; let hash = name.indexOf("#"); if (hash >= 0) { let className = name.substring(0, hash); let classElem = curr[className]; if (typeof classElem === "undefined" || !classElem.prototype) { let ctor = function(...args) { return ctor.wrap(ctor.prototype.constructor(0, ...args)); }; ctor.prototype = {}; ctor.wrap = function(thisValue) { return Object.create(ctor.prototype, { [THIS]: { value: thisValue, writable: false } }); }; if (classElem) Object.getOwnPropertyNames(classElem).forEach(name => Object.defineProperty(ctor, name, Object.getOwnPropertyDescriptor(classElem, name)) ); curr[className] = ctor; } name = name.substring(hash + 1); curr = curr[className].prototype; if (/^(get|set):/.test(name)) { if (!hasOwnProperty(curr, name = name.substring(4))) { let getter = exports[internalName.replace("set:", "get:")]; let setter = exports[internalName.replace("get:", "set:")]; Object.defineProperty(curr, name, { get: function() { return getter(this[THIS]); }, set: function(value) { setter(this[THIS], value); }, enumerable: true }); } } else { if (name === 'constructor') { curr[name] = wrapFunction(elem, setargc); } else { // for methods Object.defineProperty(curr, name, { value: function (...args) { setargc(args.length); return elem(this[THIS], ...args); } }); } } } else { if (/^(get|set):/.test(name)) { if (!hasOwnProperty(curr, name = name.substring(4))) { Object.defineProperty(curr, name, { get: exports[internalName.replace("set:", "get:")], set: exports[internalName.replace("get:", "set:")], enumerable: true }); } } else if (typeof elem === "function") { curr[name] = wrapFunction(elem, setargc); } else { curr[name] = elem; } } } return module; } exports.demangle = demangle;