blob: 0db8290d9cc5b74383fbb83971a0c99dda292583 [file]
// Compiles a dart2wasm-generated main module from `source` which can then
// be instantiated via the `instantiate` method.
//
// `source` needs to be a `Response` object (or promise thereof) e.g. created
// via the `fetch()` JS API.
export async function compileStreaming(source) {
const builtins = {builtins: ['js-string']};
return new CompiledApp(
await WebAssembly.compileStreaming(source, builtins), builtins);
}
// Compiles a dart2wasm-generated wasm module from `bytes` which is then
// instantiable via the `instantiate` method.
export async function compile(bytes) {
const builtins = {builtins: ['js-string']};
return new CompiledApp(await WebAssembly.compile(bytes, builtins), builtins);
}
class CompiledApp {
constructor(module, builtins) {
this.module = module;
this.builtins = builtins;
}
// The second argument is an options object containing:
// `loadDeferredModules` is a JS function that takes an array of module names
// matching wasm files produced by the dart2wasm compiler. It also takes a
// callback that should be invoked for each loaded module with 2 arguments:
// (1) the module name, (2) the loaded module in a format supported by
// `WebAssembly.compile` or `WebAssembly.compileStreaming`. The callback
// returns a Promise that resolves when the module is instantiated.
// loadDeferredModules should return a Promise that resolves when all the
// modules have been loaded and the callback promises have resolved.
// `loadDeferredId` is a JS function that takes load ID produced by the
// compiler when the `use-load-ids` option is passed. Each load ID maps to
// one or more wasm files as specified in the emitted JSON file. It also
// takes a callback that should be invoked for each loaded module with 2
// arguments: (1) the module name, (2) the loaded module in a format
// supported by `WebAssembly.compile` or `WebAssembly.compileStreaming`.
// The callback returns a Promise that resolves when the module is
// instantiated.
// loadDeferredId should return a Promise that resolves when all the
// modules have been loaded and the callback promises have resolved.
async instantiate(additionalImports, {loadDeferredModules, loadDeferredId} = {}) {
let dartInstance;
// Prints to the console
function printToConsole(value) {
if (typeof dartPrint == "function") {
dartPrint(value);
return;
}
if (typeof console == "object" && typeof console.log != "undefined") {
console.log(value);
return;
}
if (typeof print == "function") {
print(value);
return;
}
throw "Unable to print message: " + value;
}
// A special symbol attached to functions that wrap Dart functions.
const jsWrappedDartFunctionSymbol = Symbol("JSWrappedDartFunction");
function finalizeWrapper(dartFunction, wrapped) {
wrapped.dartFunction = dartFunction;
wrapped[jsWrappedDartFunctionSymbol] = true;
return wrapped;
}
// Imports
const dart2wasm = {
AB: (a, i, v) => a[i] = v,
AC: (handle) => clearInterval(handle),
AD: x0 => new Uint8ClampedArray(x0),
AE: x0 => x0.url,
B: s => printToConsole(s),
BB: (a, s) => a.join(s),
BC: (s) => +s,
BD: x0 => new Int16Array(x0),
BE: x0 => x0.status,
C: Function.prototype.call.bind(Number.prototype.toString),
CB: (a, i) => a[i],
CC: s => {
if (!/^\s*[+-]?(?:Infinity|NaN|(?:\.\d+|\d+(?:\.\d*)?)(?:[eE][+-]?\d+)?)\s*$/.test(s)) {
return NaN;
}
return parseFloat(s);
},
CD: x0 => new Uint16Array(x0),
CE: x0 => x0.getReader(),
D: Function.prototype.call.bind(String.prototype.indexOf),
DB: (a, i) => a.push(i),
DC: () => typeof dartUseDateNowForTicks !== "undefined",
DD: (jsArray, jsArrayOffset, wasmArray, wasmArrayOffset, length) => {
const getValue = dartInstance.exports.$wasmI16ArrayGet;
for (let i = 0; i < length; i++) {
jsArray[jsArrayOffset + i] = getValue(wasmArray, wasmArrayOffset + i);
}
},
DE: x0 => x0.read(),
E: o => o,
EB: a => a.length,
EC: () => Date.now(),
ED: x0 => new Int32Array(x0),
EE: x0 => x0.value,
F: s => JSON.stringify(s),
FB: (o, p, r) => o.replaceAll(p, () => r),
FC: () => 1000 * performance.now(),
FD: (jsArray, jsArrayOffset, wasmArray, wasmArrayOffset, length) => {
const getValue = dartInstance.exports.$wasmI32ArrayGet;
for (let i = 0; i < length; i++) {
jsArray[jsArrayOffset + i] = getValue(wasmArray, wasmArrayOffset + i);
}
},
FE: x0 => x0.done,
G: o => {
if (o === undefined || o === null) return 0;
if (typeof o === 'number') return 1;
return 2;
},
GB: s => s.trim(),
GC: (handle) => clearTimeout(handle),
GD: x0 => new Uint32Array(x0),
GE: x0 => x0.cancel(),
H: x0 => x0.index,
HB: (o, p) => p in o,
HC: s => new Date(s * 1000).getTimezoneOffset() * 60,
HD: x0 => new Float32Array(x0),
HE: x0 => x0.body,
I: (exn) => {
let stackString = exn.toString();
let frames = stackString.split('\n');
let drop = 4;
if (frames[0].startsWith('Error')) {
drop += 1;
}
return frames.slice(drop).join('\n');
},
IB: o => typeof o === 'function' && o[jsWrappedDartFunctionSymbol] === true,
IC: Date.now,
ID: x0 => new Float64Array(x0),
IE: o => {
if (o === null || o === undefined) return 0;
if (typeof(o) === 'string') return 1;
return 2;
},
J: () => new Error().stack,
JB: f => f.dartFunction,
JC: (b, o) => new DataView(b, o),
JD: (jsArray, jsArrayOffset, wasmArray, wasmArrayOffset, length) => {
const getValue = dartInstance.exports.$wasmF64ArrayGet;
for (let i = 0; i < length; i++) {
jsArray[jsArrayOffset + i] = getValue(wasmArray, wasmArrayOffset + i);
}
},
JE: x0 => x0.headers,
K: o => String(o),
KB: (wasmFunction,f) => finalizeWrapper(f, function(x0) { return wasmFunction(f,arguments.length,x0) }),
KC: (b, o, l) => new DataView(b, o, l),
KD: x0 => new ArrayBuffer(x0),
KE: x0 => x0.signal,
L: o => o === undefined,
LB: (wasmFunction,f) => finalizeWrapper(f, function(x0,x1) { return wasmFunction(f,arguments.length,x0,x1) }),
LC: (t, s) => t.set(s),
LD: (x0,x1,x2) => new Uint8Array(x0,x1,x2),
LE: s => s.trimLeft(),
M: (x0,x1) => x0.exec(x1),
MB: (p, s, f) => p.then(s, (e) => f(e, e === undefined)),
MC: (a, b) => a == b ? 0 : (a > b ? 1 : -1),
MD: (x0,x1,x2) => new DataView(x0,x1,x2),
ME: x0 => x0.abort(),
N: (x0,x1) => { x0.lastIndex = x1 },
NB: Function.prototype.call.bind(Object.getOwnPropertyDescriptor(DataView.prototype, 'byteLength').get),
NC: x0 => new WeakRef(x0),
ND: (o, p) => o[p],
NE: (x0,x1) => x0.getRandomValues(x1),
O: o => o,
OB: o => o.buffer,
OC: x0 => x0.deref(),
OD: x0 => new Array(x0),
OE: () => globalThis.crypto,
P: (s, m) => {
try {
return new RegExp(s, m);
} catch (e) {
return String(e);
}
},
PB: (o) => new DataView(o.buffer, o.byteOffset, o.byteLength),
PC: () => globalThis.WeakRef,
PD: (x0,x1,x2) => { x0[x1] = x2 },
PE: l => new DataView(new ArrayBuffer(l)),
Q: o => o instanceof RegExp,
QB: (o, start, length) => new Float64Array(o.buffer, o.byteOffset + start, length),
QC: x0 => x0.clearMarks(),
QD: o => {
if (o === null || o === undefined) return 0;
if (o instanceof Float64Array) return 1;
return 2;
},
QE: x0 => new DecompressionStream(x0),
R: (string, times) => string.repeat(times),
RB: Function.prototype.call.bind(DataView.prototype.setFloat64),
RC: x0 => x0.clearMeasures(),
RD: o => {
if (o === null || o === undefined) return 0;
if (o instanceof Float32Array) return 1;
return 2;
},
RE: x0 => x0.getWriter(),
S: (s, p, i) => s.lastIndexOf(p, i),
SB: Function.prototype.call.bind(DataView.prototype.getFloat64),
SC: (x0,x1) => x0.parse(x1),
SD: o => {
if (o === null || o === undefined) return 0;
if (o instanceof Uint32Array) return 1;
return 2;
},
SE: (x0,x1) => x0.write(x1),
T: o => o,
TB: (o, start, length) => new Float32Array(o.buffer, o.byteOffset + start, length),
TC: (x0,x1,x2) => x0.mark(x1,x2),
TD: o => {
if (o === null || o === undefined) return 0;
if (o instanceof Int32Array) return 1;
return 2;
},
TE: x0 => x0.close(),
U: o => {
if (o === undefined || o === null) return 0;
if (typeof o === 'boolean') return 1;
return 2;
},
UB: Function.prototype.call.bind(DataView.prototype.setFloat32),
UC: (x0,x1,x2,x3) => x0.measure(x1,x2,x3),
UD: o => o instanceof Uint16Array,
UE: x0 => x0.releaseLock(),
V: x0 => x0.dotAll,
VB: Function.prototype.call.bind(DataView.prototype.getFloat32),
VC: (o) => {
const typeofValue = typeof o;
return (typeofValue === 'object') ||
typeofValue === 'function';
},
VD: o => o instanceof Int16Array,
VE: x0 => x0.readable,
W: x0 => x0.unicode,
WB: (o, start, length) => new Uint32Array(o.buffer, o.byteOffset + start, length),
WC: () => globalThis.JSON,
WD: o => o instanceof Uint8ClampedArray,
WE: x0 => x0.writable,
X: x0 => x0.ignoreCase,
XB: Function.prototype.call.bind(DataView.prototype.setUint32),
XC: x0 => x0.clearMarks,
XD: o => {
if (o === null || o === undefined) return 0;
if (o instanceof Uint8Array) return 1;
return 2;
},
XE: s => {
if (/[[\]{}()*+?.\\^$|]/.test(s)) {
s = s.replace(/[[\]{}()*+?.\\^$|]/g, '\\$&');
}
return s;
},
Y: x0 => x0.multiline,
YB: Function.prototype.call.bind(DataView.prototype.getUint32),
YC: x0 => x0.clearMeasures,
YD: o => {
if (o === null || o === undefined) return 0;
if (o instanceof Int8Array) return 1;
return 2;
},
YE: (d, precision) => d.toPrecision(precision),
Z: Function.prototype.call.bind(Number.prototype.toString),
ZB: (o, start, length) => new Int32Array(o.buffer, o.byteOffset + start, length),
ZC: x0 => x0.mark,
ZD: () => new Array(),
ZE: (wasmFunction,f) => finalizeWrapper(f, function(x0) { return wasmFunction(f,arguments.length,x0) }),
a: Function.prototype.call.bind(BigInt.prototype.toString),
aB: Function.prototype.call.bind(DataView.prototype.setInt32),
aC: x0 => x0.measure,
aD: (x0,x1) => new WebSocket(x0,x1),
aE: (wasmFunction,f) => finalizeWrapper(f, function(x0) { return wasmFunction(f,arguments.length,x0) }),
b: (exn) => {
if (exn instanceof Error) {
return exn.stack;
} else {
return null;
}
},
bB: Function.prototype.call.bind(DataView.prototype.getInt32),
bC: () => globalThis.performance,
bD: x0 => x0.reason,
bE: x0 => x0.start(),
c: (c) =>
queueMicrotask(() => dartInstance.exports.$invokeCallback(c)),
cB: (o, start, length) => new Uint16Array(o.buffer, o.byteOffset + start, length),
cC: (a, i) => a.splice(i, 1),
cD: x0 => x0.code,
cE: x0 => x0.close(),
d: (map, o, v) => map.set(o, v),
dB: Function.prototype.call.bind(DataView.prototype.setUint16),
dC: a => a.pop(),
dD: (x0,x1,x2,x3) => x0.addEventListener(x1,x2,x3),
dE: (x0,x1,x2) => x0.postMessage(x1,x2),
e: (map, o) => map.get(o),
eB: Function.prototype.call.bind(DataView.prototype.getUint16),
eC: o => o.byteOffset,
eD: (wasmFunction,f) => finalizeWrapper(f, function(x0) { return wasmFunction(f,arguments.length,x0) }),
eE: (x0,x1) => { x0.onmessageerror = x1 },
f: x0 => x0.random(),
fB: (o, start, length) => new Int16Array(o.buffer, o.byteOffset + start, length),
fC: o => o.byteLength,
fD: (x0,x1,x2,x3) => x0.removeEventListener(x1,x2,x3),
fE: x0 => x0.origin,
g: () => globalThis.Math,
gB: Function.prototype.call.bind(DataView.prototype.setInt16),
gC: (ms, c) =>
setInterval(() => dartInstance.exports.$invokeCallback(c), ms),
gD: (wasmFunction,f) => finalizeWrapper(f, function(x0) { return wasmFunction(f,arguments.length,x0) }),
gE: x0 => x0.ports,
h: (l, r) => l === r,
hB: Function.prototype.call.bind(DataView.prototype.getInt16),
hC: () => Date.now(),
hD: o => {
if (o === null || o === undefined) return 0;
if (o instanceof ArrayBuffer) return 1;
if (globalThis.SharedArrayBuffer !== undefined &&
o instanceof SharedArrayBuffer) {
return 2;
}
return 3;
},
hE: (x0,x1) => { x0.onmessage = x1 },
i: s => s.toUpperCase(),
iB: (o, start, length) => new Uint8ClampedArray(o.buffer, o.byteOffset + start, length),
iC: (o, offsetInBytes, lengthInBytes) => {
var dst = new ArrayBuffer(lengthInBytes);
new Uint8Array(dst).set(new Uint8Array(o, offsetInBytes, lengthInBytes));
return new DataView(dst);
},
iD: (o, c) => o instanceof c,
iE: x0 => x0.pubHostedUrl,
j: Object.is,
jB: Function.prototype.call.bind(DataView.prototype.setUint8),
jC: (a, s, e) => a.slice(s, e),
jD: () => globalThis,
jE: x0 => x0.assetBaseUrl,
k: (jsArray, jsArrayOffset, wasmArray, wasmArrayOffset, length) => {
const setValue = dartInstance.exports.$wasmI8ArraySet;
for (let i = 0; i < length; i++) {
setValue(wasmArray, wasmArrayOffset + i, jsArray[jsArrayOffset + i]);
}
},
kB: Function.prototype.call.bind(DataView.prototype.getUint8),
kC: () => new WeakMap(),
kD: (o, t) => typeof o === t,
kE: () => globalThis._workerOptions,
l: (x0,x1) => x0.test(x1),
lB: (o, start, length) => new Int8Array(o.buffer, o.byteOffset + start, length),
lC: (a, i) => a.splice(i, 1)[0],
lD: x0 => x0.data,
m: x0 => x0.pop(),
mB: Function.prototype.call.bind(DataView.prototype.setInt8),
mC: (a, l) => a.length = l,
mD: x0 => x0.readyState,
n: x0 => x0.flags,
nB: Function.prototype.call.bind(DataView.prototype.getInt8),
nC: s => s.trimRight(),
nD: (x0,x1) => { x0.binaryType = x1 },
o: Function.prototype.call.bind(String.prototype.toLowerCase),
oB: (o, i) => o[i],
oC: (d, digits) => d.toFixed(digits),
oD: o => [o],
p: (x0,x1) => x0[x1],
pB: o => o.length,
pC: x0 => x0.protocol,
pD: (o0, o1) => [o0, o1],
q: x0 => x0.length,
qB: o => {
if (o === undefined) return 1;
var type = typeof o;
if (type === 'boolean') return 2;
if (type === 'number') return 3;
if (type === 'string') return 4;
if (o instanceof Array) return 5;
if (ArrayBuffer.isView(o)) {
if (o instanceof Int8Array) return 6;
if (o instanceof Uint8Array) return 7;
if (o instanceof Uint8ClampedArray) return 8;
if (o instanceof Int16Array) return 9;
if (o instanceof Uint16Array) return 10;
if (o instanceof Int32Array) return 11;
if (o instanceof Uint32Array) return 12;
if (o instanceof Float32Array) return 13;
if (o instanceof Float64Array) return 14;
if (o instanceof DataView) return 15;
}
if (o instanceof ArrayBuffer) return 16;
// Feature check for `SharedArrayBuffer` before doing a type-check.
if (globalThis.SharedArrayBuffer !== undefined &&
o instanceof SharedArrayBuffer) {
return 17;
}
if (o instanceof Promise) return 18;
return 19;
},
qC: (x0,x1,x2) => x0.close(x1,x2),
qD: (o0, o1, o2) => [o0, o1, o2],
r: (decoder, codeUnits) => decoder.decode(codeUnits),
rB: (o, p) => o[p],
rC: x0 => x0.close(),
rD: (o0, o1, o2, o3) => [o0, o1, o2, o3],
s: (o, start, length) => new Uint8Array(o.buffer, o.byteOffset + start, length),
sB: x0 => x0.groups,
sC: (x0,x1) => x0.send(x1),
sD: () => new AbortController(),
t: () => new TextDecoder("utf-8", {fatal: true}),
tB: (x0,x1) => x0.error(x1),
tC: () => ({}),
tD: (x0,x1,x2,x3,x4,x5) => ({method: x0,headers: x1,body: x2,credentials: x3,redirect: x4,signal: x5}),
u: () => new TextDecoder("utf-8", {fatal: false}),
uB: () => globalThis.console,
uC: (o, p, v) => o[p] = v,
uD: (x0,x1) => globalThis.fetch(x0,x1),
v: () => {
return typeof process != "undefined" &&
Object.prototype.toString.call(process) == "[object process]" &&
process.platform == "win32"
},
vB: (x0,x1) => x0.reject(x1),
vC: () => [],
vD: (x0,x1) => x0.get(x1),
w: () => {
// On browsers return `globalThis.location.href`
if (globalThis.location != null) {
return globalThis.location.href;
}
return null;
},
wB: (wasmFunction,f) => finalizeWrapper(f, function(x0) { return wasmFunction(f,arguments.length,x0) }),
wC: b => !!b,
wD: (wasmFunction,f) => finalizeWrapper(f, function(x0,x1,x2) { return wasmFunction(f,arguments.length,x0,x1,x2) }),
x: (o, p, r) => o.replace(p, () => r),
xB: (x0,x1) => x0.resolve(x1),
xC: x0 => new Int8Array(x0),
xD: (x0,x1) => x0.forEach(x1),
y: (string, token) => string.split(token),
yB: (a, l) => a.length = l,
yC: (jsArray, jsArrayOffset, wasmArray, wasmArrayOffset, length) => {
const getValue = dartInstance.exports.$wasmI8ArrayGet;
for (let i = 0; i < length; i++) {
jsArray[jsArrayOffset + i] = getValue(wasmArray, wasmArrayOffset + i);
}
},
yD: x0 => x0.name,
z: o => o instanceof Array,
zB: (ms, c) =>
setTimeout(() => dartInstance.exports.$invokeCallback(c),ms),
zC: x0 => new Uint8Array(x0),
zD: x0 => x0.statusText,
};
const baseImports = {
_: dart2wasm,
Math: Math,
Date: Date,
Object: Object,
Array: Array,
Reflect: Reflect,
WebAssembly: {
JSTag: WebAssembly.JSTag,
},
"": new Proxy({}, { get(_, prop) { return prop; } }),
};
const jsStringPolyfill = {
"charCodeAt": (s, i) => s.charCodeAt(i),
"compare": (s1, s2) => {
if (s1 < s2) return -1;
if (s1 > s2) return 1;
return 0;
},
"concat": (s1, s2) => s1 + s2,
"equals": (s1, s2) => s1 === s2,
"fromCharCode": (i) => String.fromCharCode(i),
"length": (s) => s.length,
"substring": (s, a, b) => s.substring(a, b),
"fromCharCodeArray": (a, start, end) => {
if (end <= start) return '';
const read = dartInstance.exports.$wasmI16ArrayGet;
let result = '';
let index = start;
const chunkLength = Math.min(end - index, 500);
let array = new Array(chunkLength);
while (index < end) {
const newChunkLength = Math.min(end - index, 500);
for (let i = 0; i < newChunkLength; i++) {
array[i] = read(a, index++);
}
if (newChunkLength < chunkLength) {
array = array.slice(0, newChunkLength);
}
result += String.fromCharCode(...array);
}
return result;
},
"intoCharCodeArray": (s, a, start) => {
if (s === '') return 0;
const write = dartInstance.exports.$wasmI16ArraySet;
for (var i = 0; i < s.length; ++i) {
write(a, start++, s.charCodeAt(i));
}
return s.length;
},
"test": (s) => typeof s == "string",
};
dartInstance = await WebAssembly.instantiate(this.module, {
...baseImports,
...additionalImports,
"wasm:js-string": jsStringPolyfill,
});
return new InstantiatedApp(this, dartInstance);
}
}
class InstantiatedApp {
constructor(compiledApp, instantiatedModule) {
this.compiledApp = compiledApp;
this.instantiatedModule = instantiatedModule;
}
// Call the main function with the given arguments.
invokeMain(...args) {
this.instantiatedModule.exports.$invokeMain(args);
}
}