forked from mirrors/gecko-dev
Bug 1509549 - Add a ProfilerGetSymbols module which can dump symbols with the help of a dynamically-loaded WebAssembly module. r=kmag
The module can dump ELF binaries, Mach-O binaries, and pdb files. So it works for all our supported platforms. The module is currently hosted on https://zealous-rosalind-a98ce8.netlify.com/ , which is a netlify server that serves files from the following repo: https://github.com/mstange/profiler-assets To make all of this look a bit more official, I'm planning on doing two things: - Move the github repo under the devtools-html organization - Get a firefox.com subdomain such as profiler-assets.firefox.com for hosting Depends on D13004 Differential Revision: https://phabricator.services.mozilla.com/D13005 --HG-- extra : moz-landing-system : lando
This commit is contained in:
parent
2e24ac202f
commit
6dbd19aac8
6 changed files with 415 additions and 0 deletions
|
|
@ -65,6 +65,8 @@ browser/components/sessionstore/test/unit/data/sessionstore_invalid.js
|
||||||
# for documentation purposes (policies.json) but to be accessed by the
|
# for documentation purposes (policies.json) but to be accessed by the
|
||||||
# code as a .jsm (schema.jsm)
|
# code as a .jsm (schema.jsm)
|
||||||
browser/components/enterprisepolicies/schemas/schema.jsm
|
browser/components/enterprisepolicies/schemas/schema.jsm
|
||||||
|
# Ignore generated code from wasm-bindgen
|
||||||
|
browser/components/extensions/profiler_get_symbols.js
|
||||||
# generated & special files in cld2
|
# generated & special files in cld2
|
||||||
browser/components/translation/cld2/**
|
browser/components/translation/cld2/**
|
||||||
# Screenshots is imported as a system add-on and has
|
# Screenshots is imported as a system add-on and has
|
||||||
|
|
|
||||||
128
browser/components/extensions/ProfilerGetSymbols-worker.js
Normal file
128
browser/components/extensions/ProfilerGetSymbols-worker.js
Normal file
|
|
@ -0,0 +1,128 @@
|
||||||
|
/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||||
|
/* vim: set sts=2 sw=2 et tw=80: */
|
||||||
|
/* eslint-env mozilla/chrome-worker */
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
importScripts("resource://gre/modules/osfile.jsm",
|
||||||
|
"resource://app/modules/profiler_get_symbols.js");
|
||||||
|
|
||||||
|
// This worker uses the wasm module that was generated from https://github.com/mstange/profiler-get-symbols.
|
||||||
|
// See ProfilerGetSymbols.jsm for more information.
|
||||||
|
//
|
||||||
|
// The worker instantiates the module, reads the binary into wasm memory, runs
|
||||||
|
// the wasm code, and returns the symbol table or an error. Then it shuts down
|
||||||
|
// itself.
|
||||||
|
|
||||||
|
// Read an open OS.File instance into the Uint8Array dataBuf.
|
||||||
|
function readFileInto(file, dataBuf) {
|
||||||
|
// Ideally we'd be able to call file.readTo(dataBuf) here, but readTo no
|
||||||
|
// longer exists.
|
||||||
|
// So instead, we copy the file over into wasm memory in 4MB chunks. This
|
||||||
|
// will take 425 invocations for a a 1.7GB file (such as libxul.so for a
|
||||||
|
// Firefox for Android build) and not take up too much memory per call.
|
||||||
|
const dataBufLen = dataBuf.byteLength;
|
||||||
|
const chunkSize = 4 * 1024 * 1024;
|
||||||
|
let pos = 0;
|
||||||
|
while (pos < dataBufLen) {
|
||||||
|
const chunkData = file.read({bytes: chunkSize});
|
||||||
|
const chunkBytes = chunkData.byteLength;
|
||||||
|
if (chunkBytes === 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
dataBuf.set(chunkData, pos);
|
||||||
|
pos += chunkBytes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onmessage = async e => {
|
||||||
|
try {
|
||||||
|
const {binaryPath, debugPath, breakpadId, module} = e.data;
|
||||||
|
|
||||||
|
if (!(module instanceof WebAssembly.Module)) {
|
||||||
|
throw new Error("invalid WebAssembly module");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Instantiate the WASM module.
|
||||||
|
await wasm_bindgen(module);
|
||||||
|
|
||||||
|
const {CompactSymbolTable, wasm} = wasm_bindgen;
|
||||||
|
|
||||||
|
const binaryFile = OS.File.open(binaryPath, {read: true});
|
||||||
|
const binaryDataBufLen = binaryFile.stat().size;
|
||||||
|
|
||||||
|
// Read the binary file into WASM memory.
|
||||||
|
const binaryDataBufPtr = wasm.__wbindgen_malloc(binaryDataBufLen);
|
||||||
|
const binaryDataBuf = new Uint8Array(wasm.memory.buffer, binaryDataBufPtr, binaryDataBufLen);
|
||||||
|
readFileInto(binaryFile, binaryDataBuf);
|
||||||
|
binaryFile.close();
|
||||||
|
|
||||||
|
// Do the same for the debug file, if it is supplied and different from the
|
||||||
|
// binary file. This is only the case on Windows.
|
||||||
|
let debugDataBufLen = binaryDataBufLen;
|
||||||
|
let debugDataBufPtr = binaryDataBufPtr;
|
||||||
|
if (debugPath && debugPath !== binaryPath) {
|
||||||
|
const debugFile = OS.File.open(debugPath, {read: true});
|
||||||
|
debugDataBufLen = debugFile.stat().size;
|
||||||
|
debugDataBufPtr = wasm.__wbindgen_malloc(debugDataBufLen);
|
||||||
|
const debugDataBuf = new Uint8Array(wasm.memory.buffer, debugDataBufPtr, debugDataBufLen);
|
||||||
|
readFileInto(debugFile, debugDataBuf);
|
||||||
|
debugFile.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Call get_compact_symbol_table. We're calling the raw wasm function
|
||||||
|
// instead of the binding function that wasm-bindgen generated for us,
|
||||||
|
// because the generated function doesn't let us pass binaryDataBufPtr
|
||||||
|
// or debugDataBufPtr and would force another copy.
|
||||||
|
//
|
||||||
|
// The rust definition of get_compact_symbol_table is:
|
||||||
|
//
|
||||||
|
// #[wasm_bindgen]
|
||||||
|
// pub fn get_compact_symbol_table(binary_data: &[u8], debug_data: &[u8], breakpad_id: &str, dest: &mut CompactSymbolTable) -> bool
|
||||||
|
//
|
||||||
|
// It gets exposed as a wasm function with the following signature:
|
||||||
|
//
|
||||||
|
// pub fn get_compact_symbol_table(binaryDataBufPtr: u32, binaryDataBufLen: u32, debugDataBufPtr: u32, debugDataBufLen: u32, breakpadIdPtr: u32, breakpadIdLen: u32, destPtr: u32) -> u32
|
||||||
|
//
|
||||||
|
// We're relying on implementation details of wasm-bindgen here. The above
|
||||||
|
// is true as of wasm-bindgen 0.2.32.
|
||||||
|
|
||||||
|
// Convert the breakpadId string into bytes in wasm memory.
|
||||||
|
const breakpadIdBuf = new TextEncoder("utf-8").encode(breakpadId);
|
||||||
|
const breakpadIdLen = breakpadIdBuf.length;
|
||||||
|
const breakpadIdPtr = wasm.__wbindgen_malloc(breakpadIdLen);
|
||||||
|
new Uint8Array(wasm.memory.buffer).set(breakpadIdBuf, breakpadIdPtr);
|
||||||
|
|
||||||
|
const output = new CompactSymbolTable();
|
||||||
|
let succeeded;
|
||||||
|
try {
|
||||||
|
succeeded =
|
||||||
|
wasm.get_compact_symbol_table(binaryDataBufPtr, binaryDataBufLen,
|
||||||
|
debugDataBufPtr, debugDataBufLen,
|
||||||
|
breakpadIdPtr, breakpadIdLen,
|
||||||
|
output.ptr) !== 0;
|
||||||
|
} catch (e) {
|
||||||
|
succeeded = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
wasm.__wbindgen_free(breakpadIdPtr, breakpadIdLen);
|
||||||
|
wasm.__wbindgen_free(binaryDataBufPtr, binaryDataBufLen);
|
||||||
|
if (debugDataBufPtr != binaryDataBufPtr) {
|
||||||
|
wasm.__wbindgen_free(debugDataBufPtr, debugDataBufLen);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!succeeded) {
|
||||||
|
output.free();
|
||||||
|
throw new Error("get_compact_symbol_table returned false");
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = [output.take_addr(), output.take_index(), output.take_buffer()];
|
||||||
|
output.free();
|
||||||
|
|
||||||
|
postMessage({result}, result.map(r => r.buffer));
|
||||||
|
} catch (error) {
|
||||||
|
postMessage({error: error.toString()});
|
||||||
|
}
|
||||||
|
close();
|
||||||
|
};
|
||||||
95
browser/components/extensions/ProfilerGetSymbols.jsm
Normal file
95
browser/components/extensions/ProfilerGetSymbols.jsm
Normal file
|
|
@ -0,0 +1,95 @@
|
||||||
|
/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||||
|
/* vim: set sts=2 sw=2 et tw=80: */
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
const EXPORTED_SYMBOLS = ["ProfilerGetSymbols"];
|
||||||
|
|
||||||
|
ChromeUtils.defineModuleGetter(this, "setTimeout",
|
||||||
|
"resource://gre/modules/Timer.jsm");
|
||||||
|
ChromeUtils.defineModuleGetter(this, "clearTimeout",
|
||||||
|
"resource://gre/modules/Timer.jsm");
|
||||||
|
|
||||||
|
Cu.importGlobalProperties(["fetch"]);
|
||||||
|
|
||||||
|
// This module obtains symbol tables for binaries.
|
||||||
|
// It does so with the help of a WASM module which gets pulled in from the
|
||||||
|
// internet on demand. We're doing this purely for the purposes of saving on
|
||||||
|
// code size. The contents of the WASM module are expected to be static, they
|
||||||
|
// are checked against the hash specified below.
|
||||||
|
// The WASM code is run on a ChromeWorker thread. It takes the raw byte
|
||||||
|
// contents of the to-be-dumped binary (and of an additional optional pdb file
|
||||||
|
// on Windows) as its input, and returns a set of typed arrays which make up
|
||||||
|
// the symbol table.
|
||||||
|
|
||||||
|
// Don't let the strange looking URLs and strings below scare you.
|
||||||
|
// The hash check ensures that the contents of the wasm module are what we
|
||||||
|
// expect them to be.
|
||||||
|
// The source code is at https://github.com/mstange/profiler-get-symbols/ .
|
||||||
|
|
||||||
|
// Generated from https://github.com/mstange/profiler-get-symbols/commit/0a0aadc68d6196823a5f102feacb2f04424cd681
|
||||||
|
const WASM_MODULE_URL =
|
||||||
|
"https://zealous-rosalind-a98ce8.netlify.com/wasm/4af7553b4848038c5a1e33a15ec107094bd0572e16fe2a367235bcb50a630b148ac4fe1d165859d7a9bb4ca4e2572c0e.wasm";
|
||||||
|
const WASM_MODULE_INTEGRITY =
|
||||||
|
"sha384-SvdVO0hIA4xaHjOhXsEHCUvQVy4W/io2cjW8tQpjCxSKxP4dFlhZ16m7TKTiVywO";
|
||||||
|
|
||||||
|
const EXPIRY_TIME_IN_MS = 5 * 60 * 1000; // 5 minutes
|
||||||
|
|
||||||
|
let gCachedWASMModulePromise = null;
|
||||||
|
let gCachedWASMModuleExpiryTimer = 0;
|
||||||
|
|
||||||
|
function clearCachedWASMModule() {
|
||||||
|
gCachedWASMModulePromise = null;
|
||||||
|
gCachedWASMModuleExpiryTimer = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getWASMProfilerGetSymbolsModule() {
|
||||||
|
if (!gCachedWASMModulePromise) {
|
||||||
|
gCachedWASMModulePromise = (async function() {
|
||||||
|
const request = new Request(WASM_MODULE_URL, {
|
||||||
|
integrity: WASM_MODULE_INTEGRITY,
|
||||||
|
credentials: "omit",
|
||||||
|
});
|
||||||
|
return WebAssembly.compileStreaming(fetch(request));
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset expiry timer.
|
||||||
|
clearTimeout(gCachedWASMModuleExpiryTimer);
|
||||||
|
gCachedWASMModuleExpiryTimer = setTimeout(clearCachedWASMModule, EXPIRY_TIME_IN_MS);
|
||||||
|
|
||||||
|
return gCachedWASMModulePromise;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.ProfilerGetSymbols = {
|
||||||
|
/**
|
||||||
|
* Obtain symbols for the binary at the specified location.
|
||||||
|
*
|
||||||
|
* @param {string} binaryPath The absolute path to the binary on the local
|
||||||
|
* file system.
|
||||||
|
* @param {string} debugPath The absolute path to the binary's pdb file on the
|
||||||
|
* local file system if on Windows, otherwise the same as binaryPath.
|
||||||
|
* @param {string} breakpadId The breakpadId for the binary whose symbols
|
||||||
|
* should be obtained. This is used for two purposes: 1) to locate the
|
||||||
|
* correct single-arch binary in "FatArch" files, and 2) to make sure the
|
||||||
|
* binary at the given path is actually the one that we want. If no ID match
|
||||||
|
* is found, this function throws (rejects the promise).
|
||||||
|
* @returns {Promise} The symbol table in SymbolTableAsTuple format, see the
|
||||||
|
* documentation for nsIProfiler.getSymbolTable.
|
||||||
|
*/
|
||||||
|
async getSymbolTable(binaryPath, debugPath, breakpadId) {
|
||||||
|
const module = await getWASMProfilerGetSymbolsModule();
|
||||||
|
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const worker =
|
||||||
|
new ChromeWorker("resource://app/modules/ProfilerGetSymbols-worker.js");
|
||||||
|
worker.onmessage = (e) => {
|
||||||
|
if (e.data.error) {
|
||||||
|
reject(e.data.error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
resolve(e.data.result);
|
||||||
|
};
|
||||||
|
worker.postMessage({binaryPath, debugPath, breakpadId, module});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
@ -19,6 +19,9 @@ EXTRA_JS_MODULES += [
|
||||||
'ParseBreakpadSymbols-worker.js',
|
'ParseBreakpadSymbols-worker.js',
|
||||||
'ParseNMSymbols-worker.js',
|
'ParseNMSymbols-worker.js',
|
||||||
'ParseSymbols.jsm',
|
'ParseSymbols.jsm',
|
||||||
|
'profiler_get_symbols.js',
|
||||||
|
'ProfilerGetSymbols-worker.js',
|
||||||
|
'ProfilerGetSymbols.jsm',
|
||||||
]
|
]
|
||||||
|
|
||||||
DIRS += ['schemas']
|
DIRS += ['schemas']
|
||||||
|
|
|
||||||
186
browser/components/extensions/profiler_get_symbols.js
Normal file
186
browser/components/extensions/profiler_get_symbols.js
Normal file
|
|
@ -0,0 +1,186 @@
|
||||||
|
//
|
||||||
|
// THIS FILE IS AUTOGENERATED by wasm-bindgen.
|
||||||
|
//
|
||||||
|
// Generated from:
|
||||||
|
// https://github.com/mstange/profiler-get-symbols/commit/0a0aadc68d6196823a5f102feacb2f04424cd681
|
||||||
|
// by following the instructions in that repository's Readme.md
|
||||||
|
//
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
var wasm;
|
||||||
|
const __exports = {};
|
||||||
|
|
||||||
|
|
||||||
|
let cachegetUint32Memory = null;
|
||||||
|
function getUint32Memory() {
|
||||||
|
if (cachegetUint32Memory === null || cachegetUint32Memory.buffer !== wasm.memory.buffer) {
|
||||||
|
cachegetUint32Memory = new Uint32Array(wasm.memory.buffer);
|
||||||
|
}
|
||||||
|
return cachegetUint32Memory;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getArrayU32FromWasm(ptr, len) {
|
||||||
|
return getUint32Memory().subarray(ptr / 4, ptr / 4 + len);
|
||||||
|
}
|
||||||
|
|
||||||
|
let cachedGlobalArgumentPtr = null;
|
||||||
|
function globalArgumentPtr() {
|
||||||
|
if (cachedGlobalArgumentPtr === null) {
|
||||||
|
cachedGlobalArgumentPtr = wasm.__wbindgen_global_argument_ptr();
|
||||||
|
}
|
||||||
|
return cachedGlobalArgumentPtr;
|
||||||
|
}
|
||||||
|
|
||||||
|
let cachegetUint8Memory = null;
|
||||||
|
function getUint8Memory() {
|
||||||
|
if (cachegetUint8Memory === null || cachegetUint8Memory.buffer !== wasm.memory.buffer) {
|
||||||
|
cachegetUint8Memory = new Uint8Array(wasm.memory.buffer);
|
||||||
|
}
|
||||||
|
return cachegetUint8Memory;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getArrayU8FromWasm(ptr, len) {
|
||||||
|
return getUint8Memory().subarray(ptr / 1, ptr / 1 + len);
|
||||||
|
}
|
||||||
|
|
||||||
|
function passArray8ToWasm(arg) {
|
||||||
|
const ptr = wasm.__wbindgen_malloc(arg.length * 1);
|
||||||
|
getUint8Memory().set(arg, ptr / 1);
|
||||||
|
return [ptr, arg.length];
|
||||||
|
}
|
||||||
|
|
||||||
|
let cachedTextEncoder = new TextEncoder('utf-8');
|
||||||
|
|
||||||
|
function passStringToWasm(arg) {
|
||||||
|
|
||||||
|
const buf = cachedTextEncoder.encode(arg);
|
||||||
|
const ptr = wasm.__wbindgen_malloc(buf.length);
|
||||||
|
getUint8Memory().set(buf, ptr);
|
||||||
|
return [ptr, buf.length];
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @param {Uint8Array} arg0
|
||||||
|
* @param {Uint8Array} arg1
|
||||||
|
* @param {string} arg2
|
||||||
|
* @param {CompactSymbolTable} arg3
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
__exports.get_compact_symbol_table = function(arg0, arg1, arg2, arg3) {
|
||||||
|
const [ptr0, len0] = passArray8ToWasm(arg0);
|
||||||
|
const [ptr1, len1] = passArray8ToWasm(arg1);
|
||||||
|
const [ptr2, len2] = passStringToWasm(arg2);
|
||||||
|
try {
|
||||||
|
return (wasm.get_compact_symbol_table(ptr0, len0, ptr1, len1, ptr2, len2, arg3.ptr)) !== 0;
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
wasm.__wbindgen_free(ptr0, len0 * 1);
|
||||||
|
wasm.__wbindgen_free(ptr1, len1 * 1);
|
||||||
|
wasm.__wbindgen_free(ptr2, len2 * 1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
function freeCompactSymbolTable(ptr) {
|
||||||
|
|
||||||
|
wasm.__wbg_compactsymboltable_free(ptr);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
class CompactSymbolTable {
|
||||||
|
|
||||||
|
free() {
|
||||||
|
const ptr = this.ptr;
|
||||||
|
this.ptr = 0;
|
||||||
|
freeCompactSymbolTable(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns {}
|
||||||
|
*/
|
||||||
|
constructor() {
|
||||||
|
this.ptr = wasm.compactsymboltable_new();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @returns {Uint32Array}
|
||||||
|
*/
|
||||||
|
take_addr() {
|
||||||
|
const retptr = globalArgumentPtr();
|
||||||
|
wasm.compactsymboltable_take_addr(retptr, this.ptr);
|
||||||
|
const mem = getUint32Memory();
|
||||||
|
const rustptr = mem[retptr / 4];
|
||||||
|
const rustlen = mem[retptr / 4 + 1];
|
||||||
|
|
||||||
|
const realRet = getArrayU32FromWasm(rustptr, rustlen).slice();
|
||||||
|
wasm.__wbindgen_free(rustptr, rustlen * 4);
|
||||||
|
return realRet;
|
||||||
|
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @returns {Uint32Array}
|
||||||
|
*/
|
||||||
|
take_index() {
|
||||||
|
const retptr = globalArgumentPtr();
|
||||||
|
wasm.compactsymboltable_take_index(retptr, this.ptr);
|
||||||
|
const mem = getUint32Memory();
|
||||||
|
const rustptr = mem[retptr / 4];
|
||||||
|
const rustlen = mem[retptr / 4 + 1];
|
||||||
|
|
||||||
|
const realRet = getArrayU32FromWasm(rustptr, rustlen).slice();
|
||||||
|
wasm.__wbindgen_free(rustptr, rustlen * 4);
|
||||||
|
return realRet;
|
||||||
|
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @returns {Uint8Array}
|
||||||
|
*/
|
||||||
|
take_buffer() {
|
||||||
|
const retptr = globalArgumentPtr();
|
||||||
|
wasm.compactsymboltable_take_buffer(retptr, this.ptr);
|
||||||
|
const mem = getUint32Memory();
|
||||||
|
const rustptr = mem[retptr / 4];
|
||||||
|
const rustlen = mem[retptr / 4 + 1];
|
||||||
|
|
||||||
|
const realRet = getArrayU8FromWasm(rustptr, rustlen).slice();
|
||||||
|
wasm.__wbindgen_free(rustptr, rustlen * 1);
|
||||||
|
return realRet;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
__exports.CompactSymbolTable = CompactSymbolTable;
|
||||||
|
|
||||||
|
let cachedTextDecoder = new TextDecoder('utf-8');
|
||||||
|
|
||||||
|
function getStringFromWasm(ptr, len) {
|
||||||
|
return cachedTextDecoder.decode(getUint8Memory().subarray(ptr, ptr + len));
|
||||||
|
}
|
||||||
|
|
||||||
|
__exports.__wbindgen_throw = function(ptr, len) {
|
||||||
|
throw new Error(getStringFromWasm(ptr, len));
|
||||||
|
};
|
||||||
|
|
||||||
|
function init(path_or_module) {
|
||||||
|
let instantiation;
|
||||||
|
const imports = { './profiler_get_symbols': __exports };
|
||||||
|
if (path_or_module instanceof WebAssembly.Module) {
|
||||||
|
instantiation = WebAssembly.instantiate(path_or_module, imports)
|
||||||
|
.then(instance => {
|
||||||
|
return { instance, module: path_or_module }
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
const data = fetch(path_or_module);
|
||||||
|
if (typeof WebAssembly.instantiateStreaming === 'function') {
|
||||||
|
instantiation = WebAssembly.instantiateStreaming(data, imports);
|
||||||
|
} else {
|
||||||
|
instantiation = data
|
||||||
|
.then(response => response.arrayBuffer())
|
||||||
|
.then(buffer => WebAssembly.instantiate(buffer, imports));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return instantiation.then(({instance}) => {
|
||||||
|
wasm = init.wasm = instance.exports;
|
||||||
|
return;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
self.wasm_bindgen = Object.assign(init, __exports);
|
||||||
|
})();
|
||||||
|
|
@ -170,6 +170,7 @@
|
||||||
"prefs.js": ["PrefsEngine", "PrefRec"],
|
"prefs.js": ["PrefsEngine", "PrefRec"],
|
||||||
"prefs.jsm": ["Preference"],
|
"prefs.jsm": ["Preference"],
|
||||||
"pretty-fast.js": ["prettyFast"],
|
"pretty-fast.js": ["prettyFast"],
|
||||||
|
"profiler_get_symbols.js": ["wasm_bindgen"],
|
||||||
"PromiseWorker.jsm": ["BasePromiseWorker"],
|
"PromiseWorker.jsm": ["BasePromiseWorker"],
|
||||||
"PushCrypto.jsm": ["PushCrypto", "concatArray"],
|
"PushCrypto.jsm": ["PushCrypto", "concatArray"],
|
||||||
"quit.js": ["goQuitApplication"],
|
"quit.js": ["goQuitApplication"],
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue