import * as path from 'node:path';
import {existsSync} from 'node:fs';
import assert from 'node:assert';
import {
addToCompileTimeContext,
error,
readFile,
runInMacroContext,
pushCurrentFile,
popCurrentFile,
localFile,
warn,
srcDir,
} from './utility.mjs';
const FOUR_GB = 4 * 1024 * 1024 * 1024;
const WASM_PAGE_SIZE = 64 * 1024;
const FLOAT_TYPES = new Set(['float', 'double']);
const TARGET_NOT_SUPPORTED = 0x7fffffff;
export function processMacros(text, filename) {
pushCurrentFile(filename);
try {
return text.replace(/{{{([\s\S]+?)}}}/g, (_, str) => {
const ret = runInMacroContext(str, {filename: filename});
return ret?.toString() ?? '';
});
} finally {
popCurrentFile();
}
}
function findIncludeFile(filename, currentDir) {
if (path.isAbsolute(filename)) {
return existsSync(filename) ? filename : null;
}
const includePath = [currentDir, srcDir];
for (const p of includePath) {
const f = path.join(p, filename);
if (existsSync(f)) {
return f;
}
}
return null;
}
export function preprocess(filename) {
let text = readFile(filename);
if (EXPORT_ES6) {
text = text
.replace(/\bimport\.meta\b/g, 'EMSCRIPTEN$IMPORT$META')
.replace(/\bawait import\b/g, 'EMSCRIPTEN$AWAIT$IMPORT');
}
if (MODULARIZE) {
text = text.replace(/\bawait createWasm\(\)/g, 'EMSCRIPTEN$AWAIT(createWasm())');
}
text = text.replace(/\r\n/g, '\n');
const IGNORE = 0;
const SHOW = 1;
const IGNORE_ALL = 2;
const showStack = [];
const showCurrentLine = () => showStack.every((x) => x == SHOW);
const fileExt = filename.split('.').pop().toLowerCase();
const isHtml = fileExt === 'html' || fileExt === 'htm' ? true : false;
let inStyle = false;
const lines = text.split('\n');
if (!lines[lines.length - 1]) {
lines.pop();
}
let ret = '';
let emptyLine = false;
pushCurrentFile(filename);
try {
for (let [i, line] of lines.entries()) {
if (isHtml) {
if (line.includes('<style') && !inStyle) {
inStyle = true;
}
if (line.includes('</style') && inStyle) {
inStyle = false;
}
if (inStyle) {
if (showCurrentLine()) {
ret += line + '\n';
}
continue;
}
}
const trimmed = line.trim();
if (trimmed.startsWith('#')) {
const first = trimmed.split(' ', 1)[0];
if (first == '#if' || first == '#ifdef' || first == '#elif') {
if (first == '#ifdef') {
warn('use of #ifdef in js library. Use #if instead.');
}
if (first == '#elif') {
const curr = showStack.pop();
if (curr == SHOW || curr == IGNORE_ALL) {
showStack.push(IGNORE_ALL);
continue;
}
}
const after = trimmed.substring(trimmed.indexOf(' '));
const truthy = !!runInMacroContext(after, {
filename,
lineOffset: i,
columnOffset: line.indexOf(after),
});
showStack.push(truthy ? SHOW : IGNORE);
} else if (first === '#include') {
if (showCurrentLine()) {
let includeFile = line.slice(line.indexOf(' ') + 1);
if (includeFile.startsWith('"')) {
includeFile = includeFile.slice(1, -1);
}
const absPath = findIncludeFile(includeFile, path.dirname(filename));
if (!absPath) {
error(`file not found: ${includeFile}`, i + 1);
continue;
}
const result = preprocess(absPath);
if (result) {
ret += `// include: ${includeFile}\n`;
ret += result;
ret += `// end include: ${includeFile}\n`;
}
}
} else if (first === '#else') {
if (showStack.length == 0) {
error('#else without matching #if', i + 1);
}
const curr = showStack.pop();
if (curr == IGNORE) {
showStack.push(SHOW);
} else {
showStack.push(IGNORE);
}
} else if (first === '#endif') {
if (showStack.length == 0) {
error('#endif without matching #if', i + 1);
}
showStack.pop();
} else if (first === '#warning') {
if (showCurrentLine()) {
warn(`#warning ${trimmed.substring(trimmed.indexOf(' ')).trim()}`, i + 1);
}
} else if (first === '#error') {
if (showCurrentLine()) {
error(`#error ${trimmed.substring(trimmed.indexOf(' ')).trim()}`, i + 1);
}
} else if (first === '#preprocess') {
} else {
error(`Unknown preprocessor directive ${first}`, i + 1);
}
} else {
if (showCurrentLine()) {
if (emptyLine && !line) {
continue;
}
ret += line + '\n';
if (!line) {
emptyLine = true;
} else {
emptyLine = false;
}
}
}
}
assert(
showStack.length == 0,
`preprocessing error in file ${filename}, \
no matching #endif found (${showStack.length$}' unmatched preprocessing directives on stack)`,
);
return ret;
} finally {
popCurrentFile();
}
}
function isNiceIdent(ident) {
return /^\(?[$_]+[\w$_\d ]*\)?$/.test(ident);
}
export const POINTER_SIZE = MEMORY64 ? 8 : 4;
const POINTER_MAX = MEMORY64 ? 'Number.MAX_SAFE_INTEGER' : '0xFFFFFFFF';
const STACK_ALIGN = 16;
const POINTER_BITS = POINTER_SIZE * 8;
const POINTER_TYPE = `u${POINTER_BITS}`;
const POINTER_JS_TYPE = MEMORY64 ? "'bigint'" : "'number'";
const POINTER_SHIFT = MEMORY64 ? '3' : '2';
const POINTER_HEAP = MEMORY64 ? 'HEAP64' : 'HEAP32';
const LONG_TYPE = `i${POINTER_BITS}`;
const SIZE_TYPE = POINTER_TYPE;
const POINTER_WASM_TYPE = `i${POINTER_BITS}`;
function isPointerType(type) {
return type.endsWith('*');
}
function makeInlineCalculation(expression, value, tempVar) {
if (!isNiceIdent(value)) {
expression = `${tempVar} = ${value},${expression}`;
value = tempVar;
}
return `(${expression.replace(/VALUE/g, value)})`;
}
function splitI64(value) {
if (WASM_BIGINT) {
return `BigInt(${value})`;
}
const low = value + '>>>0';
const high = makeInlineCalculation(
asmCoercion('Math.abs(VALUE)', 'double') + ' >= ' + asmEnsureFloat('1', 'double') + ' ? ' +
'(VALUE > ' + asmEnsureFloat('0', 'double') + ' ? ' +
asmCoercion('Math.floor((VALUE)/' +
asmEnsureFloat(4294967296, 'double') + ')', 'double') + '>>>0' +
' : ' +
asmFloatToInt(asmCoercion('Math.ceil((VALUE - +((' + asmFloatToInt('VALUE') + ')>>>0))/' +
asmEnsureFloat(4294967296, 'double') + ')', 'double')) + '>>>0' +
')' +
' : 0',
value,
'tempDouble',
);
return [low, high];
}
export function indentify(text, indent) {
if (text.length > 1024 * 1024) return text;
if (typeof indent == 'number') {
const len = indent;
indent = '';
for (let i = 0; i < len; i++) {
indent += ' ';
}
}
return text.replace(/\n/g, `\n${indent}`);
}
function getNativeTypeSize(type) {
switch (type) {
case 'i1': case 'i8': case 'u8': return 1;
case 'i16': case 'u16': return 2;
case 'i32': case 'u32': return 4;
case 'i64': case 'u64': return 8;
case 'float': return 4;
case 'double': return 8;
default: {
if (type.endsWith('*')) {
return POINTER_SIZE;
}
if (type[0] === 'i') {
const bits = Number(type.slice(1));
return bits / 8;
}
return 0;
}
}
}
function getHeapOffset(offset, type) {
const sz = getNativeTypeSize(type);
if (sz == 1) {
return offset;
}
if (MEMORY64 == 1) {
return `((${offset})/${sz})`;
}
const shifts = Math.log(sz) / Math.LN2;
if (CAN_ADDRESS_2GB) {
return `((${offset})>>>${shifts})`;
}
return `((${offset})>>${shifts})`;
}
function ensureDot(value) {
value = value.toString();
if (value.includes('.') || /[IN]/.test(value)) return value;
const e = value.indexOf('e');
if (e < 0) return value + '.0';
return value.slice(0, e) + '.0' + value.slice(e);
}
export function isNumber(x) {
return x == parseFloat(x) || (typeof x == 'string' && x.match(/^-?\d+$/)) || x == 'NaN';
}
function asmEnsureFloat(value, type) {
if (!isNumber(value)) return value;
if (type === 'float') {
if (value == 0) return 'Math.fround(0)';
value = ensureDot(value);
return `Math.fround(${value})`;
}
if (FLOAT_TYPES.has(type)) {
return ensureDot(value);
}
return value;
}
function asmCoercion(value, type) {
assert(arguments.length == 2, 'asmCoercion takes exactly two arguments');
if (type == 'void') {
return value;
}
if (FLOAT_TYPES.has(type)) {
if (isNumber(value)) {
return asmEnsureFloat(value, type);
}
if (type === 'float') {
return `Math.fround(${value})`;
}
return `(+(${value}))`;
}
return `((${value})|0)`;
}
function asmFloatToInt(x) {
return `(~~(${x}))`;
}
function makeGetValue(ptr, pos, type) {
assert(arguments.length == 3, 'makeGetValue expects 3 arguments');
const offset = calcFastOffset(ptr, pos);
if (type === 'i53' || type === 'u53') {
const unsigned = type.startsWith('u');
return `readI53From${unsigned ? 'U' : 'I'}64(${offset})`;
}
const slab = getHeapForType(type);
let ret = `${slab}[${getHeapOffset(offset, type)}]`;
if (MEMORY64 && isPointerType(type)) {
ret = `Number(${ret})`;
}
return ret;
}
function makeSetValue(ptr, pos, value, type) {
var rtn = makeSetValueImpl(ptr, pos, value, type);
if (ASSERTIONS == 2 && (type.startsWith('i') || type.startsWith('u'))) {
const width = getBitWidth(type);
const assertion = `checkInt${width}(${value})`;
rtn += `;${assertion}`;
}
return rtn;
}
function makeSetValueImpl(ptr, pos, value, type) {
if (type == 'i64' && !WASM_BIGINT) {
return '(tempI64 = [' + splitI64(value) + '], ' +
makeSetValueImpl(ptr, pos, 'tempI64[0]', 'i32') + ',' +
makeSetValueImpl(ptr, getFastValue(pos, '+', getNativeTypeSize('i32')), 'tempI64[1]', 'i32') + ')';
}
const offset = calcFastOffset(ptr, pos);
if (type === 'i53') {
return `writeI53ToI64(${offset}, ${value})`;
}
const slab = getHeapForType(type);
if (slab == 'HEAPU64' || slab == 'HEAP64') {
value = `BigInt(${value})`;
}
return `${slab}[${getHeapOffset(offset, type)}] = ${value}`;
}
function makeHEAPView(which, start, end) {
const type = {
8: 'i8',
U8: 'u8',
16: 'i16',
U16: 'u16',
32: 'i32',
U32: 'u32',
64: 'i64',
U64: 'u64',
F32: 'float',
F64: 'double',
}[which];
const heap = getHeapForType(type);
start = getHeapOffset(start, type);
end = getHeapOffset(end, type);
return `${heap}.subarray((${start}), ${end})`;
}
function getFastValue(a, op, b) {
assert(op == '+');
a = a === 'true' ? '1' : a === 'false' ? '0' : a;
b = b === 'true' ? '1' : b === 'false' ? '0' : b;
let aNumber = null;
let bNumber = null;
if (typeof a == 'number') {
aNumber = a;
a = a.toString();
} else if (isNumber(a)) {
aNumber = parseFloat(a);
}
if (typeof b == 'number') {
bNumber = b;
b = b.toString();
} else if (isNumber(b)) {
bNumber = parseFloat(b);
}
if (aNumber !== null && bNumber !== null) {
return (aNumber + bNumber).toString();
}
if (aNumber !== null) {
const c = b;
b = a;
a = c;
const cNumber = bNumber;
bNumber = aNumber;
aNumber = cNumber;
}
if (aNumber === 0) {
return b;
} else if (bNumber === 0) {
return a;
}
if (b[0] === '-') {
op = '-';
b = b.slice(1);
}
return `(${a})${op}(${b})`;
}
function calcFastOffset(ptr, pos) {
return getFastValue(ptr, '+', pos);
}
function getBitWidth(type) {
if (type == 'i53' || type == 'u53') return 53;
return getNativeTypeSize(type) * 8;
}
function getHeapForType(type) {
assert(type);
if (isPointerType(type)) {
type = POINTER_TYPE;
}
if (WASM_BIGINT) {
switch (type) {
case 'i64':
return 'HEAP64';
case 'u64':
return 'HEAPU64';
}
}
switch (type) {
case 'i1':
case 'i8': return 'HEAP8';
case 'u8': return 'HEAPU8';
case 'i16': return 'HEAP16';
case 'u16': return 'HEAPU16';
case 'i32': return 'HEAP32';
case 'u32': return 'HEAPU32';
case 'double': return 'HEAPF64';
case 'float': return 'HEAPF32';
case 'i64':
case 'u64': error('use i53/u53, or avoid i64/u64 without WASM_BIGINT');
}
assert(false, `bad heap type: ${type}`);
}
export function makeReturn64(value) {
if (WASM_BIGINT) {
return `BigInt(${value})`;
}
const pair = splitI64(value);
return `(setTempRet0(${pair[1]}), ${pair[0]})`;
}
function makeThrow(excPtr) {
if (ASSERTIONS && DISABLE_EXCEPTION_CATCHING) {
var assertInfo =
'Exception thrown, but exception catching is not enabled. Compile with -sNO_DISABLE_EXCEPTION_CATCHING or -sEXCEPTION_CATCHING_ALLOWED=[..] to catch.';
if (MAIN_MODULE) {
assertInfo +=
' (note: in dynamic linking, if a side module wants exceptions, the main module must be built with that support)';
}
return `assert(false, '${assertInfo}');`;
}
return `throw ${excPtr};`;
}
function storeException(varName, excPtr) {
var exceptionToStore = EXCEPTION_STACK_TRACES ? `new CppException(${excPtr})` : `${excPtr}`;
return `${varName} = ${exceptionToStore};`;
}
function charCode(char) {
return char.charCodeAt(0);
}
function makeDynCall(sig, funcPtr, promising = false) {
assert(
!sig.includes('j'),
'Cannot specify 64-bit signatures ("j" in signature string) with makeDynCall!',
);
assert(!(DYNCALLS && promising), 'DYNCALLS cannot be used with JSPI.');
let args = [];
for (let i = 1; i < sig.length; ++i) {
args.push(`a${i}`);
}
args = args.join(', ');
const needArgConversion = MEMORY64 && sig.includes('p');
let callArgs = args;
if (needArgConversion) {
callArgs = [];
for (let i = 1; i < sig.length; ++i) {
if (sig[i] == 'p') {
callArgs.push(`BigInt(a${i})`);
} else {
callArgs.push(`a${i}`);
}
}
callArgs = callArgs.join(', ');
}
if (sig.includes('p')) {
let normalizedSig = '';
for (let sigChr of sig) {
if (sigChr == 'p') {
sigChr = MEMORY64 ? 'j' : 'i';
}
normalizedSig += sigChr;
}
sig = normalizedSig;
}
if (funcPtr === undefined) {
warn(`
Legacy use of {{{ makeDynCall("${sig}") }}}(funcPtr, arg1, arg2, ...). \
Starting from Emscripten 2.0.2 (Aug 31st 2020), syntax for makeDynCall has changed. \
New syntax is {{{ makeDynCall("${sig}", "funcPtr") }}}(arg1, arg2, ...). \
Please update to new syntax.`);
if (DYNCALLS) {
if (!hasExportedSymbol(`dynCall_${sig}`)) {
if (ASSERTIONS) {
return `((${args}) => { throw 'Internal Error! Attempted to invoke wasm function pointer with signature "${sig}", but no such functions have gotten exported!' })`;
} else {
return `((${args}) => {} /* a dynamic function call to signature ${sig}, but there are no exported function pointers with that signature, so this path should never be taken. Build with ASSERTIONS enabled to validate. */)`;
}
}
return `((cb, ${args}) => getDynCaller("${sig}", cb)(${callArgs}))`;
} else {
return `((cb, ${args}) => getWasmTableEntry(cb)(${callArgs}))`;
}
}
if (DYNCALLS) {
if (!hasExportedSymbol(`dynCall_${sig}`)) {
if (ASSERTIONS) {
return `((${args}) => { throw 'Internal Error! Attempted to invoke wasm function pointer with signature "${sig}", but no such functions have gotten exported!' })`;
} else {
return `((${args}) => {} /* a dynamic function call to signature ${sig}, but there are no exported function pointers with that signature, so this path should never be taken. Build with ASSERTIONS enabled to validate. */)`;
}
}
const dyncall = `dynCall_${sig}`;
if (sig.length > 1) {
return `((${args}) => ${dyncall}(${funcPtr}, ${callArgs}))`;
}
return `(() => ${dyncall}(${funcPtr}))`;
}
let getWasmTableEntry = `getWasmTableEntry(${funcPtr})`;
if (promising) {
getWasmTableEntry = `WebAssembly.promising(${getWasmTableEntry})`;
}
if (needArgConversion) {
return `((${args}) => ${getWasmTableEntry}.call(null, ${callArgs}))`;
}
return getWasmTableEntry;
}
function makeEval(code) {
if (DYNAMIC_EXECUTION == 0) {
return "abort('DYNAMIC_EXECUTION=0 was set, cannot eval');";
}
let ret = '';
if (DYNAMIC_EXECUTION == 2) {
ret +=
"err('Warning: DYNAMIC_EXECUTION=2 was set, but calling eval in the following location:');\n";
ret += 'err(stackTrace());\n';
}
ret += code;
return ret;
}
export const ATMODULES = [];
function addAtModule(code) {
ATMODULES.push(code);
}
export const ATPRERUNS = [];
function addAtPreRun(code) {
ATPRERUNS.push(code);
}
export const ATINITS = [];
function addAtInit(code) {
ATINITS.push(code);
}
export const ATPOSTCTORS = [];
function addAtPostCtor(code) {
ATPOSTCTORS.push(code);
}
export const ATMAINS = [];
function addAtPreMain(code) {
ATMAINS.push(code);
}
export const ATEXITS = [];
function addAtExit(code) {
if (EXIT_RUNTIME) {
ATEXITS.push(code);
}
}
export const ATPOSTRUNS = [];
function addAtPostRun(code) {
ATPOSTRUNS.push(code);
}
function makeRetainedCompilerSettings() {
const ignore = new Set();
if (STRICT) {
for (const setting of LEGACY_SETTINGS) {
ignore.add(setting);
}
}
const ret = {};
for (const x in global) {
if (!ignore.has(x) && x[0] !== '_' && x == x.toUpperCase()) {
const value = global[x];
if (
typeof value == 'number' ||
typeof value == 'boolean' ||
typeof value == 'string' ||
Array.isArray(x)
) {
ret[x] = value;
}
}
}
return ret;
}
export function modifyJSFunction(text, func) {
let async_;
let args;
let rest;
let oneliner = false;
let match = text.match(/^\s*(async\s+)?function\s+([^(]*)?\s*\(([^)]*)\)/);
if (match) {
async_ = match[1] || '';
args = match[3];
rest = text.slice(match[0].length);
} else {
let match = text.match(/^\s*(var (\w+) = )?(async\s+)?\(([^)]*)\)\s+=>\s+/);
if (match) {
async_ = match[3] || '';
args = match[4];
rest = text.slice(match[0].length);
rest = rest.trim();
oneliner = rest[0] != '{';
} else {
match = text.match(/^\s*(async\s+)?function\(([^)]*)\)/);
assert(match, `could not match function:\n${text}\n`);
async_ = match[1] || '';
args = match[2];
rest = text.slice(match[0].length);
}
}
let body = rest;
if (!oneliner) {
const bodyStart = rest.indexOf('{');
const bodyEnd = rest.lastIndexOf('}');
assert(bodyEnd > 0);
body = rest.substring(bodyStart + 1, bodyEnd);
}
return func(args, body, async_, oneliner);
}
export function runIfMainThread(text) {
if (WASM_WORKERS || PTHREADS) {
return `if (${ENVIRONMENT_IS_MAIN_THREAD()}) { ${text} }`;
} else {
return text;
}
}
function runIfWorkerThread(text) {
if (WASM_WORKERS || PTHREADS) {
return `if (${ENVIRONMENT_IS_WORKER_THREAD()}) { ${text} }`;
} else {
return '';
}
}
function expectToReceiveOnModule(name) {
return INCOMING_MODULE_JS_API.has(name);
}
function isSymbolNeeded(symName) {
if (DEFAULT_LIBRARY_FUNCS_TO_INCLUDE.includes(symName)) {
return true;
}
if (symName.startsWith('$') && EXPORTED_RUNTIME_METHODS.has(symName.slice(1))) {
return true;
}
return false;
}
function checkReceiving(name) {
assert(ALL_INCOMING_MODULE_JS_API.has(name), `${name} is not part of INCOMING_MODULE_JS_API`);
}
function makeModuleReceive(localName, moduleName) {
moduleName ||= localName;
checkReceiving(moduleName);
let ret = '';
if (expectToReceiveOnModule(moduleName)) {
ret = `if (Module['${moduleName}']) ${localName} = Module['${moduleName}'];`;
}
return ret;
}
function makeModuleReceiveExpr(name, defaultValue) {
checkReceiving(name);
if (expectToReceiveOnModule(name)) {
return `Module['${name}'] || ${defaultValue}`;
} else {
return `${defaultValue}`;
}
}
function makeModuleReceiveWithVar(localName, moduleName, defaultValue) {
moduleName ||= localName;
checkReceiving(moduleName);
let ret = `var ${localName}`;
if (defaultValue) {
ret += ` = ${defaultValue}`;
}
ret += ';';
if (expectToReceiveOnModule(moduleName)) {
addAtModule(`if (Module['${moduleName}']) ${localName} = Module['${moduleName}'];`);
}
return ret;
}
function makeRemovedFSAssert(fsName) {
assert(ASSERTIONS);
const lower = fsName.toLowerCase();
if (JS_LIBRARIES.includes(localFile(path.join('lib', `lib${lower}.js`)))) return '';
return `var ${fsName} = '${fsName} is no longer included by default; build with -l${lower}.js';`;
}
function buildStringArray(array) {
if (array.length > 0) {
return "['" + array.join("','") + "']";
} else {
return '[]';
}
}
function hasExportedSymbol(sym) {
return WASM_EXPORTS.has(sym);
}
function receivedSymbol(sym) {
if (EXPORTED_RUNTIME_METHODS.has(sym)) {
return `Module['${sym}'] = ${sym};`;
}
return '';
}
export function defineI64Param(name) {
if (WASM_BIGINT) {
return name;
}
return `${name}_low, ${name}_high`;
}
export function receiveI64ParamAsI53(name, onError, handleErrors = true) {
var errorHandler = handleErrors ? `if (isNaN(${name})) { return ${onError}; }` : '';
if (WASM_BIGINT) {
return `${name} = bigintToI53Checked(${name});${errorHandler}`;
}
return `var ${name} = convertI32PairToI53Checked(${name}_low, ${name}_high);${errorHandler}`;
}
function receiveI64ParamAsI53Unchecked(name) {
if (WASM_BIGINT) {
return `${name} = Number(${name});`;
}
return `var ${name} = convertI32PairToI53(${name}_low, ${name}_high);`;
}
function from64(x) {
if (!MEMORY64) return '';
return `${x} = Number(${x});`;
}
function from64Expr(x) {
if (!MEMORY64) return x;
return `Number(${x})`;
}
function toIndexType(x) {
if (MEMORY64 == 1) return `BigInt(${x})`;
return x;
}
function to64(x) {
if (!MEMORY64) return x;
return `BigInt(${x})`;
}
function asyncIf(condition) {
return condition ? 'async ' : '';
}
function awaitIf(condition) {
return condition ? 'await ' : '';
}
function runtimeKeepalivePush() {
if (MINIMAL_RUNTIME || (EXIT_RUNTIME == 0 && PTHREADS == 0)) return '';
return 'runtimeKeepalivePush();';
}
function runtimeKeepalivePop() {
if (MINIMAL_RUNTIME || (EXIT_RUNTIME == 0 && PTHREADS == 0)) return '';
return 'runtimeKeepalivePop();';
}
function getUnsharedTextDecoderView(heap, start, end) {
const shared = `${heap}.slice(${start}, ${end})`;
const unshared = `${heap}.subarray(${start}, ${end})`;
if (!SHARED_MEMORY) return unshared;
if (SHRINK_LEVEL == 2 || heap == 'HEAPU8') return shared;
return `${heap}.buffer instanceof ArrayBuffer ? ${unshared} : ${shared}`;
}
function getEntryFunction() {
var entryFunction = 'main';
if (STANDALONE_WASM) {
if (EXPECT_MAIN) {
entryFunction = '_start';
} else {
entryFunction = '_initialize';
}
} else if (PROXY_TO_PTHREAD) {
entryFunction = '_emscripten_proxy_main';
}
if (MAIN_MODULE) {
return `resolveGlobalSymbol('${entryFunction}').sym;`;
}
return `_${entryFunction}`;
}
function formattedMinNodeVersion() {
var major = MIN_NODE_VERSION / 10000;
var minor = (MIN_NODE_VERSION / 100) % 100;
var rev = MIN_NODE_VERSION % 100;
return `v${major}.${minor}.${rev}`;
}
function getPerformanceNow() {
if (DETERMINISTIC) {
return 'deterministicNow';
} else {
return 'performance.now';
}
}
function ENVIRONMENT_IS_MAIN_THREAD() {
return `(!${ENVIRONMENT_IS_WORKER_THREAD()})`;
}
function ENVIRONMENT_IS_WORKER_THREAD() {
assert(PTHREADS || WASM_WORKERS);
var envs = [];
if (PTHREADS) envs.push('ENVIRONMENT_IS_PTHREAD');
if (WASM_WORKERS) envs.push('ENVIRONMENT_IS_WASM_WORKER');
return '(' + envs.join('||') + ')';
}
function nodeDetectionCode() {
if (ENVIRONMENT == 'node') {
return 'true';
}
return "typeof process == 'object' && process.versions?.node && process.type != 'renderer'";
}
function nodePthreadDetection() {
if (EXPORT_ES6) {
return "(await import('worker_threads')).workerData === 'em-pthread'";
} else {
return "require('worker_threads').workerData === 'em-pthread'";
}
}
function nodeWWDetection() {
if (EXPORT_ES6) {
return "(await import('worker_threads')).workerData === 'em-ww'";
} else {
return "require('worker_threads').workerData === 'em-ww'";
}
}
addToCompileTimeContext({
ATEXITS,
ATPRERUNS,
ATINITS,
ATPOSTCTORS,
ATMAINS,
ATPOSTRUNS,
FOUR_GB,
LONG_TYPE,
POINTER_HEAP,
POINTER_BITS,
POINTER_JS_TYPE,
POINTER_MAX,
POINTER_SHIFT,
POINTER_SIZE,
POINTER_TYPE,
POINTER_WASM_TYPE,
SIZE_TYPE,
STACK_ALIGN,
TARGET_NOT_SUPPORTED,
WASM_PAGE_SIZE,
ENVIRONMENT_IS_MAIN_THREAD,
ENVIRONMENT_IS_WORKER_THREAD,
addAtExit,
addAtPreRun,
addAtModule,
addAtInit,
addAtPostCtor,
addAtPreMain,
addAtPostRun,
asyncIf,
awaitIf,
buildStringArray,
charCode,
defineI64Param,
expectToReceiveOnModule,
formattedMinNodeVersion,
from64,
from64Expr,
getEntryFunction,
getHeapForType,
getHeapOffset,
getNativeTypeSize,
getPerformanceNow,
getUnsharedTextDecoderView,
hasExportedSymbol,
isSymbolNeeded,
makeDynCall,
makeEval,
makeGetValue,
makeHEAPView,
makeModuleReceive,
makeModuleReceiveExpr,
makeModuleReceiveWithVar,
makeRemovedFSAssert,
makeRetainedCompilerSettings,
makeReturn64,
makeSetValue,
makeThrow,
modifyJSFunction,
nodeDetectionCode,
receiveI64ParamAsI53,
receiveI64ParamAsI53Unchecked,
receivedSymbol,
runIfMainThread,
runIfWorkerThread,
runtimeKeepalivePop,
runtimeKeepalivePush,
splitI64,
storeException,
to64,
toIndexType,
nodePthreadDetection,
nodeWWDetection,
});