blob: eec7dee33a8c1e202453400f78f6657dc5c793df [file] [log] [blame]
// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
const jsRuntimeBlobPart1 = r'''
let buildArgsList;
// `modulePromise` is a promise to the `WebAssembly.module` object to be
// instantiated.
// `importObjectPromise` is a promise to an object that contains any additional
// imports needed by the module that aren't provided by the standard runtime.
// The fields on this object will be merged into the importObject with which
// the module will be instantiated.
// This function returns a promise to the instantiated module.
export const instantiate = async (modulePromise, importObjectPromise) => {
let dartInstance;
''';
const jsRuntimeBlobPart3 = r'''
// 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: " + js;
}
// Converts a Dart List to a JS array. Any Dart objects will be converted, but
// this will be cheap for JSValues.
function arrayFromDartList(constructor, list) {
const length = dartInstance.exports.$listLength(list);
const array = new constructor(length);
for (let i = 0; i < length; i++) {
array[i] = dartInstance.exports.$listRead(list, i);
}
return array;
}
buildArgsList = function(list) {
const dartList = dartInstance.exports.$makeStringList();
for (let i = 0; i < list.length; i++) {
dartInstance.exports.$listAdd(dartList, stringToDartString(list[i]));
}
return dartList;
}
// 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 = {
''';
// We break inside the 'dart2wasm' object to enable injection of methods. We
// could use interpolation, but then we'd have to escape characters.
const jsRuntimeBlobPart4 = r'''
};
const baseImports = {
dart2wasm: dart2wasm,
''';
// We break inside of `baseImports` to inject internalized strings.
const jsRuntimeBlobPart5 = r'''
Math: Math,
Date: Date,
Object: Object,
Array: Array,
Reflect: Reflect,
};
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),
};
dartInstance = await WebAssembly.instantiate(await modulePromise, {
...baseImports,
...(await importObjectPromise),
"wasm:js-string": jsStringPolyfill,
});
return dartInstance;
}
// Call the main function for the instantiated module
// `moduleInstance` is the instantiated dart2wasm module
// `args` are any arguments that should be passed into the main function.
export const invoke = (moduleInstance, ...args) => {
const dartMain = moduleInstance.exports.$getMain();
const dartArgs = buildArgsList(args);
moduleInstance.exports.$invokeMain(dartMain, dartArgs);
}
''';