10091 lines
265 KiB
JavaScript
10091 lines
265 KiB
JavaScript
const dependencyFilename = new URL("./php.wasm", import.meta.url).href;
|
|
export { dependencyFilename };
|
|
export const dependenciesTotalSize = 21019221;
|
|
const phpVersionString = '8.5.8';
|
|
export function init(RuntimeName, PHPLoader) {
|
|
// The rest of the code comes from the built php.js file and esm-suffix.js
|
|
var Module = typeof PHPLoader != 'undefined' ? PHPLoader : {};
|
|
var ENVIRONMENT_IS_WEB = RuntimeName === 'WEB';
|
|
var ENVIRONMENT_IS_WORKER = RuntimeName === 'WORKER';
|
|
var ENVIRONMENT_IS_NODE = RuntimeName === 'NODE';
|
|
var arguments_ = [];
|
|
var thisProgram = './this.program';
|
|
var quit_ = (status, toThrow) => {
|
|
throw toThrow;
|
|
};
|
|
var _scriptName = globalThis.document?.currentScript?.src;
|
|
if (ENVIRONMENT_IS_WORKER) {
|
|
_scriptName = self.location.href;
|
|
}
|
|
var scriptDirectory = '';
|
|
function locateFile(path) {
|
|
if (Module['locateFile']) {
|
|
return Module['locateFile'](path, scriptDirectory);
|
|
}
|
|
return scriptDirectory + path;
|
|
}
|
|
var readAsync, readBinary;
|
|
if (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) {
|
|
try {
|
|
scriptDirectory = new URL('.', _scriptName).href;
|
|
} catch {}
|
|
{
|
|
if (ENVIRONMENT_IS_WORKER) {
|
|
readBinary = (url) => {
|
|
var xhr = new XMLHttpRequest();
|
|
xhr.open('GET', url, false);
|
|
xhr.responseType = 'arraybuffer';
|
|
xhr.send(null);
|
|
return new Uint8Array(xhr.response);
|
|
};
|
|
}
|
|
readAsync = async (url) => {
|
|
var response = await fetch(url, { credentials: 'same-origin' });
|
|
if (response.ok) {
|
|
return response.arrayBuffer();
|
|
}
|
|
throw new Error(response.status + ' : ' + response.url);
|
|
};
|
|
}
|
|
} else {
|
|
}
|
|
var out = console.log.bind(console);
|
|
var err = console.error.bind(console);
|
|
var dynamicLibraries = [];
|
|
var wasmBinary;
|
|
var ABORT = false;
|
|
var EXITSTATUS;
|
|
var HEAP8, HEAPU8, HEAP16, HEAPU16, HEAP32, HEAPU32, HEAPF32, HEAPF64;
|
|
var HEAP64, HEAPU64;
|
|
var runtimeInitialized = false;
|
|
var runtimeExited = false;
|
|
function updateMemoryViews() {
|
|
var b = wasmMemory.buffer;
|
|
HEAP8 = new Int8Array(b);
|
|
HEAP16 = new Int16Array(b);
|
|
Module['HEAPU8'] = HEAPU8 = new Uint8Array(b);
|
|
HEAPU16 = new Uint16Array(b);
|
|
HEAP32 = new Int32Array(b);
|
|
Module['HEAPU32'] = HEAPU32 = new Uint32Array(b);
|
|
HEAPF32 = new Float32Array(b);
|
|
HEAPF64 = new Float64Array(b);
|
|
HEAP64 = new BigInt64Array(b);
|
|
HEAPU64 = new BigUint64Array(b);
|
|
}
|
|
var __RELOC_FUNCS__ = [];
|
|
function preRun() {
|
|
if (Module['preRun']) {
|
|
if (typeof Module['preRun'] == 'function')
|
|
Module['preRun'] = [Module['preRun']];
|
|
while (Module['preRun'].length) {
|
|
addOnPreRun(Module['preRun'].shift());
|
|
}
|
|
}
|
|
callRuntimeCallbacks(onPreRuns);
|
|
}
|
|
function initRuntime() {
|
|
runtimeInitialized = true;
|
|
callRuntimeCallbacks(__RELOC_FUNCS__);
|
|
callRuntimeCallbacks(onInits);
|
|
if (!Module['noFSInit'] && !FS.initialized) FS.init();
|
|
TTY.init();
|
|
SOCKFS.root = FS.mount(SOCKFS, {}, null);
|
|
PIPEFS.root = FS.mount(PIPEFS, {}, null);
|
|
wasmExports['__wasm_call_ctors']();
|
|
callRuntimeCallbacks(onPostCtors);
|
|
FS.ignorePermissions = false;
|
|
}
|
|
function preMain() {}
|
|
function exitRuntime() {
|
|
___funcs_on_exit();
|
|
FS.quit();
|
|
TTY.shutdown();
|
|
runtimeExited = true;
|
|
}
|
|
function postRun() {
|
|
if (Module['postRun']) {
|
|
if (typeof Module['postRun'] == 'function')
|
|
Module['postRun'] = [Module['postRun']];
|
|
while (Module['postRun'].length) {
|
|
addOnPostRun(Module['postRun'].shift());
|
|
}
|
|
}
|
|
callRuntimeCallbacks(onPostRuns);
|
|
}
|
|
function abort(what) {
|
|
Module['onAbort']?.(what);
|
|
what = 'Aborted(' + what + ')';
|
|
err(what);
|
|
ABORT = true;
|
|
what += '. Build with -sASSERTIONS for more info.';
|
|
var e = new WebAssembly.RuntimeError(what);
|
|
throw e;
|
|
}
|
|
var wasmBinaryFile;
|
|
function findWasmBinary() {
|
|
return locateFile(dependencyFilename);
|
|
}
|
|
function getBinarySync(file) {
|
|
if (file == wasmBinaryFile && wasmBinary) {
|
|
return new Uint8Array(wasmBinary);
|
|
}
|
|
if (readBinary) {
|
|
return readBinary(file);
|
|
}
|
|
throw 'both async and sync fetching of the wasm failed';
|
|
}
|
|
async function getWasmBinary(binaryFile) {
|
|
if (!wasmBinary) {
|
|
try {
|
|
var response = await readAsync(binaryFile);
|
|
return new Uint8Array(response);
|
|
} catch {}
|
|
}
|
|
return getBinarySync(binaryFile);
|
|
}
|
|
async function instantiateArrayBuffer(binaryFile, imports) {
|
|
try {
|
|
var binary = await getWasmBinary(binaryFile);
|
|
var instance = await WebAssembly.instantiate(binary, imports);
|
|
return instance;
|
|
} catch (reason) {
|
|
err(`failed to asynchronously prepare wasm: ${reason}`);
|
|
abort(reason);
|
|
}
|
|
}
|
|
async function instantiateAsync(binary, binaryFile, imports) {
|
|
if (!binary) {
|
|
try {
|
|
var response = fetch(binaryFile, {
|
|
credentials: 'same-origin',
|
|
});
|
|
var instantiationResult =
|
|
await WebAssembly.instantiateStreaming(response, imports);
|
|
return instantiationResult;
|
|
} catch (reason) {
|
|
err(`wasm streaming compile failed: ${reason}`);
|
|
err('falling back to ArrayBuffer instantiation');
|
|
}
|
|
}
|
|
return instantiateArrayBuffer(binaryFile, imports);
|
|
}
|
|
function getWasmImports() {
|
|
var imports = {
|
|
env: wasmImports,
|
|
wasi_snapshot_preview1: wasmImports,
|
|
'GOT.mem': new Proxy(wasmImports, GOTHandler),
|
|
'GOT.func': new Proxy(wasmImports, GOTHandler),
|
|
};
|
|
return imports;
|
|
}
|
|
async function createWasm() {
|
|
function receiveInstance(instance, module) {
|
|
wasmExports = instance.exports;
|
|
var origExports = (wasmExports = relocateExports(wasmExports));
|
|
wasmExports = Asyncify.instrumentWasmExports(wasmExports);
|
|
mergeLibSymbols(wasmExports, 'main');
|
|
var metadata = getDylinkMetadata(module);
|
|
if (metadata.neededDynlibs) {
|
|
dynamicLibraries =
|
|
metadata.neededDynlibs.concat(dynamicLibraries);
|
|
}
|
|
assignWasmExports(wasmExports);
|
|
updateGOT(origExports);
|
|
Module['wasmExports'] = wasmExports;
|
|
LDSO.init();
|
|
loadDylibs();
|
|
updateMemoryViews();
|
|
removeRunDependency('wasm-instantiate');
|
|
return wasmExports;
|
|
}
|
|
addRunDependency('wasm-instantiate');
|
|
function receiveInstantiationResult(result) {
|
|
return receiveInstance(result['instance'], result['module']);
|
|
}
|
|
var info = getWasmImports();
|
|
if (Module['instantiateWasm']) {
|
|
return new Promise((resolve, reject) => {
|
|
Module['instantiateWasm'](info, (inst, mod) => {
|
|
resolve(receiveInstance(inst, mod));
|
|
});
|
|
});
|
|
}
|
|
wasmBinaryFile ??= findWasmBinary();
|
|
var result = await instantiateAsync(wasmBinary, wasmBinaryFile, info);
|
|
var exports = receiveInstantiationResult(result);
|
|
return exports;
|
|
}
|
|
var asyncifyStubs = {};
|
|
class ExitStatus {
|
|
name = 'ExitStatus';
|
|
constructor(status) {
|
|
this.message = `Program terminated with exit(${status})`;
|
|
this.status = status;
|
|
}
|
|
}
|
|
ExitStatus = class PHPExitStatus extends Error {
|
|
constructor(status) {
|
|
super(status);
|
|
this.name = 'ExitStatus';
|
|
this.message = 'Program terminated with exit(' + status + ')';
|
|
this.status = status;
|
|
}
|
|
};
|
|
var GOT = {};
|
|
var currentModuleWeakSymbols = new Set([]);
|
|
var GOTHandler = {
|
|
get(obj, symName) {
|
|
var rtn = GOT[symName];
|
|
if (!rtn) {
|
|
rtn = GOT[symName] = new WebAssembly.Global(
|
|
{ value: 'i32', mutable: true },
|
|
-1
|
|
);
|
|
}
|
|
if (!currentModuleWeakSymbols.has(symName)) {
|
|
rtn.required = true;
|
|
}
|
|
return rtn;
|
|
},
|
|
};
|
|
var callRuntimeCallbacks = (callbacks) => {
|
|
while (callbacks.length > 0) {
|
|
callbacks.shift()(Module);
|
|
}
|
|
};
|
|
var onPostRuns = [];
|
|
var addOnPostRun = (cb) => onPostRuns.push(cb);
|
|
var onPreRuns = [];
|
|
var addOnPreRun = (cb) => onPreRuns.push(cb);
|
|
var runDependencies = 0;
|
|
var dependenciesFulfilled = null;
|
|
var removeRunDependency = (id) => {
|
|
runDependencies--;
|
|
Module['monitorRunDependencies']?.(runDependencies);
|
|
if (runDependencies == 0) {
|
|
if (dependenciesFulfilled) {
|
|
var callback = dependenciesFulfilled;
|
|
dependenciesFulfilled = null;
|
|
callback();
|
|
}
|
|
}
|
|
};
|
|
var addRunDependency = (id) => {
|
|
runDependencies++;
|
|
Module['monitorRunDependencies']?.(runDependencies);
|
|
};
|
|
var dynCalls = {};
|
|
var dynCallLegacy = (sig, ptr, args) => {
|
|
sig = sig.replace(/p/g, 'i');
|
|
var f = dynCalls[sig];
|
|
return f(ptr, ...args);
|
|
};
|
|
var dynCall = (sig, ptr, args = [], promising = false) => {
|
|
var rtn = dynCallLegacy(sig, ptr, args);
|
|
function convert(rtn) {
|
|
return rtn;
|
|
}
|
|
return convert(rtn);
|
|
};
|
|
var UTF8Decoder = globalThis.TextDecoder && new TextDecoder();
|
|
var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
|
|
var maxIdx = idx + maxBytesToRead;
|
|
if (ignoreNul) return maxIdx;
|
|
while (heapOrArray[idx] && !(idx >= maxIdx)) ++idx;
|
|
return idx;
|
|
};
|
|
var UTF8ArrayToString = (
|
|
heapOrArray,
|
|
idx = 0,
|
|
maxBytesToRead,
|
|
ignoreNul
|
|
) => {
|
|
var endPtr = findStringEnd(heapOrArray, idx, maxBytesToRead, ignoreNul);
|
|
if (endPtr - idx > 16 && heapOrArray.buffer && UTF8Decoder) {
|
|
return UTF8Decoder.decode(heapOrArray.subarray(idx, endPtr));
|
|
}
|
|
var str = '';
|
|
while (idx < endPtr) {
|
|
var u0 = heapOrArray[idx++];
|
|
if (!(u0 & 128)) {
|
|
str += String.fromCharCode(u0);
|
|
continue;
|
|
}
|
|
var u1 = heapOrArray[idx++] & 63;
|
|
if ((u0 & 224) == 192) {
|
|
str += String.fromCharCode(((u0 & 31) << 6) | u1);
|
|
continue;
|
|
}
|
|
var u2 = heapOrArray[idx++] & 63;
|
|
if ((u0 & 240) == 224) {
|
|
u0 = ((u0 & 15) << 12) | (u1 << 6) | u2;
|
|
} else {
|
|
u0 =
|
|
((u0 & 7) << 18) |
|
|
(u1 << 12) |
|
|
(u2 << 6) |
|
|
(heapOrArray[idx++] & 63);
|
|
}
|
|
if (u0 < 65536) {
|
|
str += String.fromCharCode(u0);
|
|
} else {
|
|
var ch = u0 - 65536;
|
|
str += String.fromCharCode(
|
|
55296 | (ch >> 10),
|
|
56320 | (ch & 1023)
|
|
);
|
|
}
|
|
}
|
|
return str;
|
|
};
|
|
var getDylinkMetadata = (binary) => {
|
|
var offset = 0;
|
|
var end = 0;
|
|
function getU8() {
|
|
return binary[offset++];
|
|
}
|
|
function getLEB() {
|
|
var ret = 0;
|
|
var mul = 1;
|
|
while (1) {
|
|
var byte = binary[offset++];
|
|
ret += (byte & 127) * mul;
|
|
mul *= 128;
|
|
if (!(byte & 128)) break;
|
|
}
|
|
return ret;
|
|
}
|
|
function getString() {
|
|
var len = getLEB();
|
|
offset += len;
|
|
return UTF8ArrayToString(binary, offset - len, len);
|
|
}
|
|
function getStringList() {
|
|
var count = getLEB();
|
|
var rtn = [];
|
|
while (count--) rtn.push(getString());
|
|
return rtn;
|
|
}
|
|
function failIf(condition, message) {
|
|
if (condition) throw new Error(message);
|
|
}
|
|
if (binary instanceof WebAssembly.Module) {
|
|
var dylinkSection = WebAssembly.Module.customSections(
|
|
binary,
|
|
'dylink.0'
|
|
);
|
|
failIf(dylinkSection.length === 0, 'need dylink section');
|
|
binary = new Uint8Array(dylinkSection[0]);
|
|
end = binary.length;
|
|
} else {
|
|
var int32View = new Uint32Array(
|
|
new Uint8Array(binary.subarray(0, 24)).buffer
|
|
);
|
|
var magicNumberFound = int32View[0] == 1836278016;
|
|
failIf(!magicNumberFound, 'need to see wasm magic number');
|
|
failIf(binary[8] !== 0, 'need the dylink section to be first');
|
|
offset = 9;
|
|
var section_size = getLEB();
|
|
end = offset + section_size;
|
|
var name = getString();
|
|
failIf(name !== 'dylink.0');
|
|
}
|
|
var customSection = {
|
|
neededDynlibs: [],
|
|
tlsExports: new Set(),
|
|
weakImports: new Set(),
|
|
runtimePaths: [],
|
|
};
|
|
var WASM_DYLINK_MEM_INFO = 1;
|
|
var WASM_DYLINK_NEEDED = 2;
|
|
var WASM_DYLINK_EXPORT_INFO = 3;
|
|
var WASM_DYLINK_IMPORT_INFO = 4;
|
|
var WASM_DYLINK_RUNTIME_PATH = 5;
|
|
var WASM_SYMBOL_TLS = 256;
|
|
var WASM_SYMBOL_BINDING_MASK = 3;
|
|
var WASM_SYMBOL_BINDING_WEAK = 1;
|
|
while (offset < end) {
|
|
var subsectionType = getU8();
|
|
var subsectionSize = getLEB();
|
|
if (subsectionType === WASM_DYLINK_MEM_INFO) {
|
|
customSection.memorySize = getLEB();
|
|
customSection.memoryAlign = getLEB();
|
|
customSection.tableSize = getLEB();
|
|
customSection.tableAlign = getLEB();
|
|
} else if (subsectionType === WASM_DYLINK_NEEDED) {
|
|
customSection.neededDynlibs = getStringList();
|
|
} else if (subsectionType === WASM_DYLINK_EXPORT_INFO) {
|
|
var count = getLEB();
|
|
while (count--) {
|
|
var symname = getString();
|
|
var flags = getLEB();
|
|
if (flags & WASM_SYMBOL_TLS) {
|
|
customSection.tlsExports.add(symname);
|
|
}
|
|
}
|
|
} else if (subsectionType === WASM_DYLINK_IMPORT_INFO) {
|
|
var count = getLEB();
|
|
while (count--) {
|
|
var modname = getString();
|
|
var symname = getString();
|
|
var flags = getLEB();
|
|
if (
|
|
(flags & WASM_SYMBOL_BINDING_MASK) ==
|
|
WASM_SYMBOL_BINDING_WEAK
|
|
) {
|
|
customSection.weakImports.add(symname);
|
|
}
|
|
}
|
|
} else if (subsectionType === WASM_DYLINK_RUNTIME_PATH) {
|
|
customSection.runtimePaths = getStringList();
|
|
} else {
|
|
offset += subsectionSize;
|
|
}
|
|
}
|
|
return customSection;
|
|
};
|
|
var newDSO = (name, handle, syms) => {
|
|
var dso = { refcount: Infinity, name, exports: syms, global: true };
|
|
LDSO.loadedLibsByName[name] = dso;
|
|
if (handle != undefined) {
|
|
LDSO.loadedLibsByHandle[handle] = dso;
|
|
}
|
|
return dso;
|
|
};
|
|
var LDSO = {
|
|
loadedLibsByName: {},
|
|
loadedLibsByHandle: {},
|
|
init() {
|
|
newDSO('__main__', 0, wasmImports);
|
|
},
|
|
};
|
|
var alignMemory = (size, alignment) =>
|
|
Math.ceil(size / alignment) * alignment;
|
|
var getMemory = (size) => {
|
|
if (runtimeInitialized) {
|
|
return _calloc(size, 1);
|
|
}
|
|
var ret = ___heap_base;
|
|
var end = ret + alignMemory(size, 16);
|
|
___heap_base = end;
|
|
var sbrk_ptr = _emscripten_get_sbrk_ptr();
|
|
HEAPU32[sbrk_ptr >> 2] = end;
|
|
return ret;
|
|
};
|
|
var isInternalSym = (symName) =>
|
|
[
|
|
'memory',
|
|
'__memory_base',
|
|
'__table_base',
|
|
'__stack_pointer',
|
|
'__indirect_function_table',
|
|
'__cpp_exception',
|
|
'__c_longjmp',
|
|
'__wasm_apply_data_relocs',
|
|
'__dso_handle',
|
|
'__tls_size',
|
|
'__tls_align',
|
|
'__set_stack_limits',
|
|
'_emscripten_tls_init',
|
|
'__wasm_init_tls',
|
|
'__wasm_call_ctors',
|
|
'__start_em_asm',
|
|
'__stop_em_asm',
|
|
'__start_em_js',
|
|
'__stop_em_js',
|
|
].includes(symName) || symName.startsWith('__em_js__');
|
|
var wasmTableMirror = [];
|
|
var getWasmTableEntry = (funcPtr) => {
|
|
var func = wasmTableMirror[funcPtr];
|
|
if (!func) {
|
|
wasmTableMirror[funcPtr] = func = wasmTable.get(funcPtr);
|
|
}
|
|
return func;
|
|
};
|
|
var updateTableMap = (offset, count) => {
|
|
if (functionsInTableMap) {
|
|
for (var i = offset; i < offset + count; i++) {
|
|
var item = getWasmTableEntry(i);
|
|
if (item) {
|
|
functionsInTableMap.set(item, i);
|
|
}
|
|
}
|
|
}
|
|
};
|
|
var functionsInTableMap;
|
|
var getFunctionAddress = (func) => {
|
|
if (!functionsInTableMap) {
|
|
functionsInTableMap = new WeakMap();
|
|
updateTableMap(0, wasmTable.length);
|
|
}
|
|
return functionsInTableMap.get(func) || 0;
|
|
};
|
|
var freeTableIndexes = [];
|
|
var getEmptyTableSlot = () => {
|
|
if (freeTableIndexes.length) {
|
|
return freeTableIndexes.pop();
|
|
}
|
|
return wasmTable['grow'](1);
|
|
};
|
|
var setWasmTableEntry = (idx, func) => {
|
|
wasmTable.set(idx, func);
|
|
wasmTableMirror[idx] = wasmTable.get(idx);
|
|
};
|
|
var uleb128EncodeWithLen = (arr) => {
|
|
const n = arr.length;
|
|
return [(n % 128) | 128, n >> 7, ...arr];
|
|
};
|
|
var wasmTypeCodes = { i: 127, p: 127, j: 126, f: 125, d: 124, e: 111 };
|
|
var generateTypePack = (types) =>
|
|
uleb128EncodeWithLen(
|
|
Array.from(types, (type) => {
|
|
var code = wasmTypeCodes[type];
|
|
return code;
|
|
})
|
|
);
|
|
var convertJsFunctionToWasm = (func, sig) => {
|
|
var bytes = Uint8Array.of(
|
|
0,
|
|
97,
|
|
115,
|
|
109,
|
|
1,
|
|
0,
|
|
0,
|
|
0,
|
|
1,
|
|
...uleb128EncodeWithLen([
|
|
1,
|
|
96,
|
|
...generateTypePack(sig.slice(1)),
|
|
...generateTypePack(sig[0] === 'v' ? '' : sig[0]),
|
|
]),
|
|
2,
|
|
7,
|
|
1,
|
|
1,
|
|
101,
|
|
1,
|
|
102,
|
|
0,
|
|
0,
|
|
7,
|
|
5,
|
|
1,
|
|
1,
|
|
102,
|
|
0,
|
|
0
|
|
);
|
|
var module = new WebAssembly.Module(bytes);
|
|
var instance = new WebAssembly.Instance(module, { e: { f: func } });
|
|
var wrappedFunc = instance.exports['f'];
|
|
return wrappedFunc;
|
|
};
|
|
var addFunction = (func, sig) => {
|
|
var rtn = getFunctionAddress(func);
|
|
if (rtn) {
|
|
return rtn;
|
|
}
|
|
var ret = getEmptyTableSlot();
|
|
try {
|
|
setWasmTableEntry(ret, func);
|
|
} catch (err) {
|
|
if (!(err instanceof TypeError)) {
|
|
throw err;
|
|
}
|
|
var wrapped = convertJsFunctionToWasm(func, sig);
|
|
setWasmTableEntry(ret, wrapped);
|
|
}
|
|
functionsInTableMap.set(func, ret);
|
|
return ret;
|
|
};
|
|
var updateGOT = (exports, replace) => {
|
|
for (var symName in exports) {
|
|
if (isInternalSym(symName)) {
|
|
continue;
|
|
}
|
|
var value = exports[symName];
|
|
var existingEntry = GOT[symName] && GOT[symName].value != -1;
|
|
if (replace || !existingEntry) {
|
|
var newValue;
|
|
if (typeof value == 'function') {
|
|
newValue = addFunction(value);
|
|
} else if (typeof value == 'number') {
|
|
newValue = value;
|
|
} else {
|
|
continue;
|
|
}
|
|
GOT[symName] ??= new WebAssembly.Global({
|
|
value: 'i32',
|
|
mutable: true,
|
|
});
|
|
GOT[symName].value = newValue;
|
|
}
|
|
}
|
|
};
|
|
var isImmutableGlobal = (val) => {
|
|
if (val instanceof WebAssembly.Global) {
|
|
try {
|
|
val.value = val.value;
|
|
} catch {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
};
|
|
var relocateExports = (exports, memoryBase = 0) => {
|
|
function relocateExport(name, value) {
|
|
if (isImmutableGlobal(value)) {
|
|
return value.value + memoryBase;
|
|
}
|
|
return value;
|
|
}
|
|
var relocated = {};
|
|
for (var e in exports) {
|
|
relocated[e] = relocateExport(e, exports[e]);
|
|
}
|
|
return relocated;
|
|
};
|
|
var isSymbolDefined = (symName) => {
|
|
var existing = wasmImports[symName];
|
|
if (!existing || existing.stub) {
|
|
return false;
|
|
}
|
|
if (symName in asyncifyStubs && !asyncifyStubs[symName]) {
|
|
return false;
|
|
}
|
|
return true;
|
|
};
|
|
var createNamedFunction = (name, func) =>
|
|
Object.defineProperty(func, 'name', { value: name });
|
|
var stackSave = () => _emscripten_stack_get_current();
|
|
var stackRestore = (val) => __emscripten_stack_restore(val);
|
|
var createInvokeFunction =
|
|
(sig) =>
|
|
(ptr, ...args) => {
|
|
var sp = stackSave();
|
|
try {
|
|
return dynCall(sig, ptr, args);
|
|
} catch (e) {
|
|
stackRestore(sp);
|
|
if (e !== e + 0) throw e;
|
|
_setThrew(1, 0);
|
|
if (sig[0] == 'j') return 0n;
|
|
}
|
|
};
|
|
var resolveGlobalSymbol = (symName, direct = false) => {
|
|
var sym;
|
|
if (isSymbolDefined(symName)) {
|
|
sym = wasmImports[symName];
|
|
} else if (symName.startsWith('invoke_')) {
|
|
sym = wasmImports[symName] = createNamedFunction(
|
|
symName,
|
|
createInvokeFunction(symName.split('_')[1])
|
|
);
|
|
}
|
|
return { sym, name: symName };
|
|
};
|
|
var onPostCtors = [];
|
|
var addOnPostCtor = (cb) => onPostCtors.push(cb);
|
|
var UTF8ToString = (ptr, maxBytesToRead, ignoreNul) =>
|
|
ptr ? UTF8ArrayToString(HEAPU8, ptr, maxBytesToRead, ignoreNul) : '';
|
|
var loadWebAssemblyModule = (
|
|
binary,
|
|
flags,
|
|
libName,
|
|
localScope,
|
|
handle
|
|
) => {
|
|
var metadata = getDylinkMetadata(binary);
|
|
function loadModule() {
|
|
var memAlign = Math.pow(2, metadata.memoryAlign);
|
|
var memoryBase = metadata.memorySize
|
|
? alignMemory(
|
|
getMemory(metadata.memorySize + memAlign),
|
|
memAlign
|
|
)
|
|
: 0;
|
|
var tableBase = metadata.tableSize ? wasmTable.length : 0;
|
|
if (handle) {
|
|
HEAP8[handle + 8] = 1;
|
|
HEAPU32[(handle + 12) >> 2] = memoryBase;
|
|
HEAP32[(handle + 16) >> 2] = metadata.memorySize;
|
|
HEAPU32[(handle + 20) >> 2] = tableBase;
|
|
HEAP32[(handle + 24) >> 2] = metadata.tableSize;
|
|
}
|
|
if (metadata.tableSize) {
|
|
wasmTable.grow(metadata.tableSize);
|
|
}
|
|
var moduleExports;
|
|
function resolveSymbol(sym) {
|
|
var resolved = resolveGlobalSymbol(sym).sym;
|
|
if (!resolved && localScope) {
|
|
resolved = localScope[sym];
|
|
}
|
|
if (!resolved) {
|
|
resolved = moduleExports[sym];
|
|
}
|
|
return resolved;
|
|
}
|
|
var proxyHandler = {
|
|
get(stubs, prop) {
|
|
switch (prop) {
|
|
case '__memory_base':
|
|
return memoryBase;
|
|
case '__table_base':
|
|
return tableBase;
|
|
}
|
|
if (prop in wasmImports && !wasmImports[prop].stub) {
|
|
var res = wasmImports[prop];
|
|
if (res.orig) {
|
|
res = res.orig;
|
|
}
|
|
return res;
|
|
}
|
|
if (!(prop in stubs)) {
|
|
var resolved;
|
|
stubs[prop] = (...args) => {
|
|
resolved ||= resolveSymbol(prop);
|
|
return resolved(...args);
|
|
};
|
|
}
|
|
return stubs[prop];
|
|
},
|
|
};
|
|
var proxy = new Proxy({}, proxyHandler);
|
|
currentModuleWeakSymbols = metadata.weakImports;
|
|
var info = {
|
|
'GOT.mem': new Proxy({}, GOTHandler),
|
|
'GOT.func': new Proxy({}, GOTHandler),
|
|
env: proxy,
|
|
wasi_snapshot_preview1: proxy,
|
|
};
|
|
function postInstantiation(module, instance) {
|
|
updateTableMap(tableBase, metadata.tableSize);
|
|
moduleExports = relocateExports(instance.exports, memoryBase);
|
|
updateGOT(moduleExports);
|
|
moduleExports = Asyncify.instrumentWasmExports(moduleExports);
|
|
if (!flags.allowUndefined) {
|
|
reportUndefinedSymbols();
|
|
}
|
|
function addEmAsm(addr, body) {
|
|
var args = [];
|
|
for (var arity = 0; ; arity++) {
|
|
var argName = '$' + arity;
|
|
if (!body.includes(argName)) break;
|
|
args.push(argName);
|
|
}
|
|
args = args.join(',');
|
|
var func = `(${args}) => { ${body} };`;
|
|
ASM_CONSTS[start] = eval(func);
|
|
}
|
|
if ('__start_em_asm' in moduleExports) {
|
|
var start = moduleExports['__start_em_asm'];
|
|
var stop = moduleExports['__stop_em_asm'];
|
|
while (start < stop) {
|
|
var jsString = UTF8ToString(start);
|
|
addEmAsm(start, jsString);
|
|
start = HEAPU8.indexOf(0, start) + 1;
|
|
}
|
|
}
|
|
function addEmJs(name, cSig, body) {
|
|
var jsArgs = [];
|
|
cSig = cSig.slice(1, -1);
|
|
if (cSig != 'void') {
|
|
cSig = cSig.split(',');
|
|
for (var arg of cSig) {
|
|
var jsArg = arg.split(' ').pop();
|
|
jsArgs.push(jsArg.replace('*', ''));
|
|
}
|
|
}
|
|
var func = `(${jsArgs}) => ${body};`;
|
|
moduleExports[name] = eval(func);
|
|
}
|
|
for (var name in moduleExports) {
|
|
if (name.startsWith('__em_js__')) {
|
|
var start = moduleExports[name];
|
|
var jsString = UTF8ToString(start);
|
|
var [sig, body] = jsString.split('<::>');
|
|
addEmJs(name.replace('__em_js__', ''), sig, body);
|
|
delete moduleExports[name];
|
|
}
|
|
}
|
|
var applyRelocs = moduleExports['__wasm_apply_data_relocs'];
|
|
if (applyRelocs) {
|
|
if (runtimeInitialized) {
|
|
applyRelocs();
|
|
} else {
|
|
__RELOC_FUNCS__.push(applyRelocs);
|
|
}
|
|
}
|
|
var init = moduleExports['__wasm_call_ctors'];
|
|
if (init) {
|
|
if (runtimeInitialized) {
|
|
init();
|
|
} else {
|
|
addOnPostCtor(init);
|
|
}
|
|
}
|
|
return moduleExports;
|
|
}
|
|
if (flags.loadAsync) {
|
|
return (async () => {
|
|
var instance;
|
|
if (binary instanceof WebAssembly.Module) {
|
|
instance = new WebAssembly.Instance(binary, info);
|
|
} else {
|
|
({ module: binary, instance } =
|
|
await WebAssembly.instantiate(binary, info));
|
|
}
|
|
return postInstantiation(binary, instance);
|
|
})();
|
|
}
|
|
var module =
|
|
binary instanceof WebAssembly.Module
|
|
? binary
|
|
: new WebAssembly.Module(binary);
|
|
var instance = new WebAssembly.Instance(module, info);
|
|
return postInstantiation(module, instance);
|
|
}
|
|
flags = {
|
|
...flags,
|
|
rpath: { parentLibPath: libName, paths: metadata.runtimePaths },
|
|
};
|
|
if (flags.loadAsync) {
|
|
return metadata.neededDynlibs
|
|
.reduce(
|
|
(chain, dynNeeded) =>
|
|
chain.then(() =>
|
|
loadDynamicLibrary(dynNeeded, flags, localScope)
|
|
),
|
|
Promise.resolve()
|
|
)
|
|
.then(loadModule);
|
|
}
|
|
for (var needed of metadata.neededDynlibs) {
|
|
loadDynamicLibrary(needed, flags, localScope);
|
|
}
|
|
return loadModule();
|
|
};
|
|
var mergeLibSymbols = (exports, libName) => {
|
|
registerDynCallSymbols(exports);
|
|
for (var [sym, exp] of Object.entries(exports)) {
|
|
const setImport = (target) => {
|
|
if (target in asyncifyStubs) {
|
|
asyncifyStubs[target] = exp;
|
|
}
|
|
if (!isSymbolDefined(target)) {
|
|
wasmImports[target] = exp;
|
|
}
|
|
};
|
|
setImport(sym);
|
|
const main_alias = '__main_argc_argv';
|
|
if (sym == 'main') {
|
|
setImport(main_alias);
|
|
}
|
|
if (sym == main_alias) {
|
|
setImport('main');
|
|
}
|
|
}
|
|
};
|
|
var asyncLoad = async (url) => {
|
|
var arrayBuffer = await readAsync(url);
|
|
return new Uint8Array(arrayBuffer);
|
|
};
|
|
var preloadPlugins = [];
|
|
var registerWasmPlugin = () => {
|
|
var wasmPlugin = {
|
|
promiseChainEnd: Promise.resolve(),
|
|
canHandle: (name) =>
|
|
!Module['noWasmDecoding'] && name.endsWith('.so'),
|
|
handle: async (byteArray, name) =>
|
|
(wasmPlugin.promiseChainEnd = wasmPlugin.promiseChainEnd.then(
|
|
async () => {
|
|
try {
|
|
var exports = await loadWebAssemblyModule(
|
|
byteArray,
|
|
{ loadAsync: true, nodelete: true },
|
|
name,
|
|
{}
|
|
);
|
|
} catch (error) {
|
|
throw new Error(
|
|
`failed to instantiate wasm: ${name}: ${error}`
|
|
);
|
|
}
|
|
preloadedWasm[name] = exports;
|
|
return byteArray;
|
|
}
|
|
)),
|
|
};
|
|
preloadPlugins.push(wasmPlugin);
|
|
};
|
|
var preloadedWasm = {};
|
|
var PATH = {
|
|
isAbs: (path) => path.charAt(0) === '/',
|
|
splitPath: (filename) => {
|
|
var splitPathRe =
|
|
/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;
|
|
return splitPathRe.exec(filename).slice(1);
|
|
},
|
|
normalizeArray: (parts, allowAboveRoot) => {
|
|
var up = 0;
|
|
for (var i = parts.length - 1; i >= 0; i--) {
|
|
var last = parts[i];
|
|
if (last === '.') {
|
|
parts.splice(i, 1);
|
|
} else if (last === '..') {
|
|
parts.splice(i, 1);
|
|
up++;
|
|
} else if (up) {
|
|
parts.splice(i, 1);
|
|
up--;
|
|
}
|
|
}
|
|
if (allowAboveRoot) {
|
|
for (; up; up--) {
|
|
parts.unshift('..');
|
|
}
|
|
}
|
|
return parts;
|
|
},
|
|
normalize: (path) => {
|
|
var isAbsolute = PATH.isAbs(path),
|
|
trailingSlash = path.slice(-1) === '/';
|
|
path = PATH.normalizeArray(
|
|
path.split('/').filter((p) => !!p),
|
|
!isAbsolute
|
|
).join('/');
|
|
if (!path && !isAbsolute) {
|
|
path = '.';
|
|
}
|
|
if (path && trailingSlash) {
|
|
path += '/';
|
|
}
|
|
return (isAbsolute ? '/' : '') + path;
|
|
},
|
|
dirname: (path) => {
|
|
var result = PATH.splitPath(path),
|
|
root = result[0],
|
|
dir = result[1];
|
|
if (!root && !dir) {
|
|
return '.';
|
|
}
|
|
if (dir) {
|
|
dir = dir.slice(0, -1);
|
|
}
|
|
return root + dir;
|
|
},
|
|
basename: (path) => path && path.match(/([^\/]+|\/)\/*$/)[1],
|
|
join: (...paths) => PATH.normalize(paths.join('/')),
|
|
join2: (l, r) => PATH.normalize(l + '/' + r),
|
|
};
|
|
var replaceORIGIN = (parentLibName, rpath) => {
|
|
if (rpath.startsWith('$ORIGIN')) {
|
|
var origin = PATH.dirname(parentLibName);
|
|
return rpath.replace('$ORIGIN', origin);
|
|
}
|
|
return rpath;
|
|
};
|
|
var withStackSave = (f) => {
|
|
var stack = stackSave();
|
|
var ret = f();
|
|
stackRestore(stack);
|
|
return ret;
|
|
};
|
|
var stackAlloc = (sz) => __emscripten_stack_alloc(sz);
|
|
var lengthBytesUTF8 = (str) => {
|
|
var len = 0;
|
|
for (var i = 0; i < str.length; ++i) {
|
|
var c = str.charCodeAt(i);
|
|
if (c <= 127) {
|
|
len++;
|
|
} else if (c <= 2047) {
|
|
len += 2;
|
|
} else if (c >= 55296 && c <= 57343) {
|
|
len += 4;
|
|
++i;
|
|
} else {
|
|
len += 3;
|
|
}
|
|
}
|
|
return len;
|
|
};
|
|
var stringToUTF8Array = (str, heap, outIdx, maxBytesToWrite) => {
|
|
if (!(maxBytesToWrite > 0)) return 0;
|
|
var startIdx = outIdx;
|
|
var endIdx = outIdx + maxBytesToWrite - 1;
|
|
for (var i = 0; i < str.length; ++i) {
|
|
var u = str.codePointAt(i);
|
|
if (u <= 127) {
|
|
if (outIdx >= endIdx) break;
|
|
heap[outIdx++] = u;
|
|
} else if (u <= 2047) {
|
|
if (outIdx + 1 >= endIdx) break;
|
|
heap[outIdx++] = 192 | (u >> 6);
|
|
heap[outIdx++] = 128 | (u & 63);
|
|
} else if (u <= 65535) {
|
|
if (outIdx + 2 >= endIdx) break;
|
|
heap[outIdx++] = 224 | (u >> 12);
|
|
heap[outIdx++] = 128 | ((u >> 6) & 63);
|
|
heap[outIdx++] = 128 | (u & 63);
|
|
} else {
|
|
if (outIdx + 3 >= endIdx) break;
|
|
heap[outIdx++] = 240 | (u >> 18);
|
|
heap[outIdx++] = 128 | ((u >> 12) & 63);
|
|
heap[outIdx++] = 128 | ((u >> 6) & 63);
|
|
heap[outIdx++] = 128 | (u & 63);
|
|
i++;
|
|
}
|
|
}
|
|
heap[outIdx] = 0;
|
|
return outIdx - startIdx;
|
|
};
|
|
var stringToUTF8 = (str, outPtr, maxBytesToWrite) =>
|
|
stringToUTF8Array(str, HEAPU8, outPtr, maxBytesToWrite);
|
|
var stringToUTF8OnStack = (str) => {
|
|
var size = lengthBytesUTF8(str) + 1;
|
|
var ret = stackAlloc(size);
|
|
stringToUTF8(str, ret, size);
|
|
return ret;
|
|
};
|
|
var initRandomFill = () => (view) => crypto.getRandomValues(view);
|
|
var randomFill = (view) => {
|
|
(randomFill = initRandomFill())(view);
|
|
};
|
|
var PATH_FS = {
|
|
resolve: (...args) => {
|
|
var resolvedPath = '',
|
|
resolvedAbsolute = false;
|
|
for (var i = args.length - 1; i >= -1 && !resolvedAbsolute; i--) {
|
|
var path = i >= 0 ? args[i] : FS.cwd();
|
|
if (typeof path != 'string') {
|
|
throw new TypeError(
|
|
'Arguments to path.resolve must be strings'
|
|
);
|
|
} else if (!path) {
|
|
return '';
|
|
}
|
|
resolvedPath = path + '/' + resolvedPath;
|
|
resolvedAbsolute = PATH.isAbs(path);
|
|
}
|
|
resolvedPath = PATH.normalizeArray(
|
|
resolvedPath.split('/').filter((p) => !!p),
|
|
!resolvedAbsolute
|
|
).join('/');
|
|
return (resolvedAbsolute ? '/' : '') + resolvedPath || '.';
|
|
},
|
|
relative: (from, to) => {
|
|
from = PATH_FS.resolve(from).slice(1);
|
|
to = PATH_FS.resolve(to).slice(1);
|
|
function trim(arr) {
|
|
var start = 0;
|
|
for (; start < arr.length; start++) {
|
|
if (arr[start] !== '') break;
|
|
}
|
|
var end = arr.length - 1;
|
|
for (; end >= 0; end--) {
|
|
if (arr[end] !== '') break;
|
|
}
|
|
if (start > end) return [];
|
|
return arr.slice(start, end - start + 1);
|
|
}
|
|
var fromParts = trim(from.split('/'));
|
|
var toParts = trim(to.split('/'));
|
|
var length = Math.min(fromParts.length, toParts.length);
|
|
var samePartsLength = length;
|
|
for (var i = 0; i < length; i++) {
|
|
if (fromParts[i] !== toParts[i]) {
|
|
samePartsLength = i;
|
|
break;
|
|
}
|
|
}
|
|
var outputParts = [];
|
|
for (var i = samePartsLength; i < fromParts.length; i++) {
|
|
outputParts.push('..');
|
|
}
|
|
outputParts = outputParts.concat(toParts.slice(samePartsLength));
|
|
return outputParts.join('/');
|
|
},
|
|
};
|
|
var FS_stdin_getChar_buffer = [];
|
|
var intArrayFromString = (stringy, dontAddNull, length) => {
|
|
var len = length > 0 ? length : lengthBytesUTF8(stringy) + 1;
|
|
var u8array = new Array(len);
|
|
var numBytesWritten = stringToUTF8Array(
|
|
stringy,
|
|
u8array,
|
|
0,
|
|
u8array.length
|
|
);
|
|
if (dontAddNull) u8array.length = numBytesWritten;
|
|
return u8array;
|
|
};
|
|
var FS_stdin_getChar = () => {
|
|
if (!FS_stdin_getChar_buffer.length) {
|
|
var result = null;
|
|
if (globalThis.window?.prompt) {
|
|
result = window.prompt('Input: ');
|
|
if (result !== null) {
|
|
result += '\n';
|
|
}
|
|
} else {
|
|
}
|
|
if (!result) {
|
|
return null;
|
|
}
|
|
FS_stdin_getChar_buffer = intArrayFromString(result, true);
|
|
}
|
|
return FS_stdin_getChar_buffer.shift();
|
|
};
|
|
var TTY = {
|
|
ttys: [],
|
|
init() {},
|
|
shutdown() {},
|
|
register(dev, ops) {
|
|
TTY.ttys[dev] = { input: [], output: [], ops };
|
|
FS.registerDevice(dev, TTY.stream_ops);
|
|
},
|
|
stream_ops: {
|
|
open(stream) {
|
|
var tty = TTY.ttys[stream.node.rdev];
|
|
if (!tty) {
|
|
throw new FS.ErrnoError(43);
|
|
}
|
|
stream.tty = tty;
|
|
stream.seekable = false;
|
|
},
|
|
close(stream) {
|
|
stream.tty.ops.fsync(stream.tty);
|
|
},
|
|
fsync(stream) {
|
|
stream.tty.ops.fsync(stream.tty);
|
|
},
|
|
read(stream, buffer, offset, length, pos) {
|
|
if (!stream.tty || !stream.tty.ops.get_char) {
|
|
throw new FS.ErrnoError(60);
|
|
}
|
|
var bytesRead = 0;
|
|
for (var i = 0; i < length; i++) {
|
|
var result;
|
|
try {
|
|
result = stream.tty.ops.get_char(stream.tty);
|
|
} catch (e) {
|
|
throw new FS.ErrnoError(29);
|
|
}
|
|
if (result === undefined && bytesRead === 0) {
|
|
throw new FS.ErrnoError(6);
|
|
}
|
|
if (result === null || result === undefined) break;
|
|
bytesRead++;
|
|
buffer[offset + i] = result;
|
|
}
|
|
if (bytesRead) {
|
|
stream.node.atime = Date.now();
|
|
}
|
|
return bytesRead;
|
|
},
|
|
write(stream, buffer, offset, length, pos) {
|
|
if (!stream.tty || !stream.tty.ops.put_char) {
|
|
throw new FS.ErrnoError(60);
|
|
}
|
|
try {
|
|
for (var i = 0; i < length; i++) {
|
|
stream.tty.ops.put_char(stream.tty, buffer[offset + i]);
|
|
}
|
|
} catch (e) {
|
|
throw new FS.ErrnoError(29);
|
|
}
|
|
if (length) {
|
|
stream.node.mtime = stream.node.ctime = Date.now();
|
|
}
|
|
return i;
|
|
},
|
|
},
|
|
default_tty_ops: {
|
|
get_char(tty) {
|
|
return FS_stdin_getChar();
|
|
},
|
|
put_char(tty, val) {
|
|
if (val === null || val === 10) {
|
|
out(UTF8ArrayToString(tty.output));
|
|
tty.output = [];
|
|
} else {
|
|
if (val != 0) tty.output.push(val);
|
|
}
|
|
},
|
|
fsync(tty) {
|
|
if (tty.output?.length > 0) {
|
|
out(UTF8ArrayToString(tty.output));
|
|
tty.output = [];
|
|
}
|
|
},
|
|
ioctl_tcgets(tty) {
|
|
return {
|
|
c_iflag: 25856,
|
|
c_oflag: 5,
|
|
c_cflag: 191,
|
|
c_lflag: 35387,
|
|
c_cc: [
|
|
3, 28, 127, 21, 4, 0, 1, 0, 17, 19, 26, 0, 18, 15, 23,
|
|
22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
],
|
|
};
|
|
},
|
|
ioctl_tcsets(tty, optional_actions, data) {
|
|
return 0;
|
|
},
|
|
ioctl_tiocgwinsz(tty) {
|
|
return [24, 80];
|
|
},
|
|
},
|
|
default_tty1_ops: {
|
|
put_char(tty, val) {
|
|
if (val === null || val === 10) {
|
|
err(UTF8ArrayToString(tty.output));
|
|
tty.output = [];
|
|
} else {
|
|
if (val != 0) tty.output.push(val);
|
|
}
|
|
},
|
|
fsync(tty) {
|
|
if (tty.output?.length > 0) {
|
|
err(UTF8ArrayToString(tty.output));
|
|
tty.output = [];
|
|
}
|
|
},
|
|
},
|
|
};
|
|
var zeroMemory = (ptr, size) => HEAPU8.fill(0, ptr, ptr + size);
|
|
var mmapAlloc = (size) => {
|
|
size = alignMemory(size, 65536);
|
|
var ptr = _emscripten_builtin_memalign(65536, size);
|
|
if (ptr) zeroMemory(ptr, size);
|
|
return ptr;
|
|
};
|
|
var MEMFS = {
|
|
ops_table: null,
|
|
mount(mount) {
|
|
return MEMFS.createNode(null, '/', 16895, 0);
|
|
},
|
|
createNode(parent, name, mode, dev) {
|
|
if (FS.isBlkdev(mode) || FS.isFIFO(mode)) {
|
|
throw new FS.ErrnoError(63);
|
|
}
|
|
MEMFS.ops_table ||= {
|
|
dir: {
|
|
node: {
|
|
getattr: MEMFS.node_ops.getattr,
|
|
setattr: MEMFS.node_ops.setattr,
|
|
lookup: MEMFS.node_ops.lookup,
|
|
mknod: MEMFS.node_ops.mknod,
|
|
rename: MEMFS.node_ops.rename,
|
|
unlink: MEMFS.node_ops.unlink,
|
|
rmdir: MEMFS.node_ops.rmdir,
|
|
readdir: MEMFS.node_ops.readdir,
|
|
symlink: MEMFS.node_ops.symlink,
|
|
},
|
|
stream: { llseek: MEMFS.stream_ops.llseek },
|
|
},
|
|
file: {
|
|
node: {
|
|
getattr: MEMFS.node_ops.getattr,
|
|
setattr: MEMFS.node_ops.setattr,
|
|
},
|
|
stream: {
|
|
llseek: MEMFS.stream_ops.llseek,
|
|
read: MEMFS.stream_ops.read,
|
|
write: MEMFS.stream_ops.write,
|
|
mmap: MEMFS.stream_ops.mmap,
|
|
msync: MEMFS.stream_ops.msync,
|
|
},
|
|
},
|
|
link: {
|
|
node: {
|
|
getattr: MEMFS.node_ops.getattr,
|
|
setattr: MEMFS.node_ops.setattr,
|
|
readlink: MEMFS.node_ops.readlink,
|
|
},
|
|
stream: {},
|
|
},
|
|
chrdev: {
|
|
node: {
|
|
getattr: MEMFS.node_ops.getattr,
|
|
setattr: MEMFS.node_ops.setattr,
|
|
},
|
|
stream: FS.chrdev_stream_ops,
|
|
},
|
|
};
|
|
var node = FS.createNode(parent, name, mode, dev);
|
|
if (FS.isDir(node.mode)) {
|
|
node.node_ops = MEMFS.ops_table.dir.node;
|
|
node.stream_ops = MEMFS.ops_table.dir.stream;
|
|
node.contents = {};
|
|
} else if (FS.isFile(node.mode)) {
|
|
node.node_ops = MEMFS.ops_table.file.node;
|
|
node.stream_ops = MEMFS.ops_table.file.stream;
|
|
node.usedBytes = 0;
|
|
node.contents = null;
|
|
} else if (FS.isLink(node.mode)) {
|
|
node.node_ops = MEMFS.ops_table.link.node;
|
|
node.stream_ops = MEMFS.ops_table.link.stream;
|
|
} else if (FS.isChrdev(node.mode)) {
|
|
node.node_ops = MEMFS.ops_table.chrdev.node;
|
|
node.stream_ops = MEMFS.ops_table.chrdev.stream;
|
|
}
|
|
node.atime = node.mtime = node.ctime = Date.now();
|
|
if (parent) {
|
|
parent.contents[name] = node;
|
|
parent.atime = parent.mtime = parent.ctime = node.atime;
|
|
}
|
|
return node;
|
|
},
|
|
getFileDataAsTypedArray(node) {
|
|
if (!node.contents) return new Uint8Array(0);
|
|
if (node.contents.subarray)
|
|
return node.contents.subarray(0, node.usedBytes);
|
|
return new Uint8Array(node.contents);
|
|
},
|
|
expandFileStorage(node, newCapacity) {
|
|
var prevCapacity = node.contents ? node.contents.length : 0;
|
|
if (prevCapacity >= newCapacity) return;
|
|
var CAPACITY_DOUBLING_MAX = 1024 * 1024;
|
|
newCapacity = Math.max(
|
|
newCapacity,
|
|
(prevCapacity *
|
|
(prevCapacity < CAPACITY_DOUBLING_MAX ? 2 : 1.125)) >>>
|
|
0
|
|
);
|
|
if (prevCapacity != 0) newCapacity = Math.max(newCapacity, 256);
|
|
var oldContents = node.contents;
|
|
node.contents = new Uint8Array(newCapacity);
|
|
if (node.usedBytes > 0)
|
|
node.contents.set(oldContents.subarray(0, node.usedBytes), 0);
|
|
},
|
|
resizeFileStorage(node, newSize) {
|
|
if (node.usedBytes == newSize) return;
|
|
if (newSize == 0) {
|
|
node.contents = null;
|
|
node.usedBytes = 0;
|
|
} else {
|
|
var oldContents = node.contents;
|
|
node.contents = new Uint8Array(newSize);
|
|
if (oldContents) {
|
|
node.contents.set(
|
|
oldContents.subarray(
|
|
0,
|
|
Math.min(newSize, node.usedBytes)
|
|
)
|
|
);
|
|
}
|
|
node.usedBytes = newSize;
|
|
}
|
|
},
|
|
node_ops: {
|
|
getattr(node) {
|
|
var attr = {};
|
|
attr.dev = FS.isChrdev(node.mode) ? node.id : 1;
|
|
attr.ino = node.id;
|
|
attr.mode = node.mode;
|
|
attr.nlink = 1;
|
|
attr.uid = 0;
|
|
attr.gid = 0;
|
|
attr.rdev = node.rdev;
|
|
if (FS.isDir(node.mode)) {
|
|
attr.size = 4096;
|
|
} else if (FS.isFile(node.mode)) {
|
|
attr.size = node.usedBytes;
|
|
} else if (FS.isLink(node.mode)) {
|
|
attr.size = node.link.length;
|
|
} else {
|
|
attr.size = 0;
|
|
}
|
|
attr.atime = new Date(node.atime);
|
|
attr.mtime = new Date(node.mtime);
|
|
attr.ctime = new Date(node.ctime);
|
|
attr.blksize = 4096;
|
|
attr.blocks = Math.ceil(attr.size / attr.blksize);
|
|
return attr;
|
|
},
|
|
setattr(node, attr) {
|
|
for (const key of ['mode', 'atime', 'mtime', 'ctime']) {
|
|
if (attr[key] != null) {
|
|
node[key] = attr[key];
|
|
}
|
|
}
|
|
if (attr.size !== undefined) {
|
|
MEMFS.resizeFileStorage(node, attr.size);
|
|
}
|
|
},
|
|
lookup(parent, name) {
|
|
if (!MEMFS.doesNotExistError) {
|
|
MEMFS.doesNotExistError = new FS.ErrnoError(44);
|
|
MEMFS.doesNotExistError.stack = '<generic error, no stack>';
|
|
}
|
|
throw MEMFS.doesNotExistError;
|
|
},
|
|
mknod(parent, name, mode, dev) {
|
|
return MEMFS.createNode(parent, name, mode, dev);
|
|
},
|
|
rename(old_node, new_dir, new_name) {
|
|
var new_node;
|
|
try {
|
|
new_node = FS.lookupNode(new_dir, new_name);
|
|
} catch (e) {}
|
|
if (new_node) {
|
|
if (FS.isDir(old_node.mode)) {
|
|
for (var i in new_node.contents) {
|
|
throw new FS.ErrnoError(55);
|
|
}
|
|
}
|
|
FS.hashRemoveNode(new_node);
|
|
}
|
|
delete old_node.parent.contents[old_node.name];
|
|
new_dir.contents[new_name] = old_node;
|
|
old_node.name = new_name;
|
|
new_dir.ctime =
|
|
new_dir.mtime =
|
|
old_node.parent.ctime =
|
|
old_node.parent.mtime =
|
|
Date.now();
|
|
},
|
|
unlink(parent, name) {
|
|
delete parent.contents[name];
|
|
parent.ctime = parent.mtime = Date.now();
|
|
},
|
|
rmdir(parent, name) {
|
|
var node = FS.lookupNode(parent, name);
|
|
for (var i in node.contents) {
|
|
throw new FS.ErrnoError(55);
|
|
}
|
|
delete parent.contents[name];
|
|
parent.ctime = parent.mtime = Date.now();
|
|
},
|
|
readdir(node) {
|
|
return ['.', '..', ...Object.keys(node.contents)];
|
|
},
|
|
symlink(parent, newname, oldpath) {
|
|
var node = MEMFS.createNode(parent, newname, 511 | 40960, 0);
|
|
node.link = oldpath;
|
|
return node;
|
|
},
|
|
readlink(node) {
|
|
if (!FS.isLink(node.mode)) {
|
|
throw new FS.ErrnoError(28);
|
|
}
|
|
return node.link;
|
|
},
|
|
},
|
|
stream_ops: {
|
|
read(stream, buffer, offset, length, position) {
|
|
var contents = stream.node.contents;
|
|
if (position >= stream.node.usedBytes) return 0;
|
|
var size = Math.min(stream.node.usedBytes - position, length);
|
|
if (size > 8 && contents.subarray) {
|
|
buffer.set(
|
|
contents.subarray(position, position + size),
|
|
offset
|
|
);
|
|
} else {
|
|
for (var i = 0; i < size; i++)
|
|
buffer[offset + i] = contents[position + i];
|
|
}
|
|
return size;
|
|
},
|
|
write(stream, buffer, offset, length, position, canOwn) {
|
|
if (buffer.buffer === HEAP8.buffer) {
|
|
canOwn = false;
|
|
}
|
|
if (!length) return 0;
|
|
var node = stream.node;
|
|
node.mtime = node.ctime = Date.now();
|
|
if (
|
|
buffer.subarray &&
|
|
(!node.contents || node.contents.subarray)
|
|
) {
|
|
if (canOwn) {
|
|
node.contents = buffer.subarray(
|
|
offset,
|
|
offset + length
|
|
);
|
|
node.usedBytes = length;
|
|
return length;
|
|
} else if (node.usedBytes === 0 && position === 0) {
|
|
node.contents = buffer.slice(offset, offset + length);
|
|
node.usedBytes = length;
|
|
return length;
|
|
} else if (position + length <= node.usedBytes) {
|
|
node.contents.set(
|
|
buffer.subarray(offset, offset + length),
|
|
position
|
|
);
|
|
return length;
|
|
}
|
|
}
|
|
MEMFS.expandFileStorage(node, position + length);
|
|
if (node.contents.subarray && buffer.subarray) {
|
|
node.contents.set(
|
|
buffer.subarray(offset, offset + length),
|
|
position
|
|
);
|
|
} else {
|
|
for (var i = 0; i < length; i++) {
|
|
node.contents[position + i] = buffer[offset + i];
|
|
}
|
|
}
|
|
node.usedBytes = Math.max(node.usedBytes, position + length);
|
|
return length;
|
|
},
|
|
llseek(stream, offset, whence) {
|
|
var position = offset;
|
|
if (whence === 1) {
|
|
position += stream.position;
|
|
} else if (whence === 2) {
|
|
if (FS.isFile(stream.node.mode)) {
|
|
position += stream.node.usedBytes;
|
|
}
|
|
}
|
|
if (position < 0) {
|
|
throw new FS.ErrnoError(28);
|
|
}
|
|
return position;
|
|
},
|
|
mmap(stream, length, position, prot, flags) {
|
|
if (!FS.isFile(stream.node.mode)) {
|
|
throw new FS.ErrnoError(43);
|
|
}
|
|
var ptr;
|
|
var allocated;
|
|
var contents = stream.node.contents;
|
|
if (
|
|
!(flags & 2) &&
|
|
contents &&
|
|
contents.buffer === HEAP8.buffer
|
|
) {
|
|
allocated = false;
|
|
ptr = contents.byteOffset;
|
|
} else {
|
|
allocated = true;
|
|
ptr = mmapAlloc(length);
|
|
if (!ptr) {
|
|
throw new FS.ErrnoError(48);
|
|
}
|
|
if (contents) {
|
|
if (
|
|
position > 0 ||
|
|
position + length < contents.length
|
|
) {
|
|
if (contents.subarray) {
|
|
contents = contents.subarray(
|
|
position,
|
|
position + length
|
|
);
|
|
} else {
|
|
contents = Array.prototype.slice.call(
|
|
contents,
|
|
position,
|
|
position + length
|
|
);
|
|
}
|
|
}
|
|
HEAP8.set(contents, ptr);
|
|
}
|
|
}
|
|
return { ptr, allocated };
|
|
},
|
|
msync(stream, buffer, offset, length, mmapFlags) {
|
|
MEMFS.stream_ops.write(
|
|
stream,
|
|
buffer,
|
|
0,
|
|
length,
|
|
offset,
|
|
false
|
|
);
|
|
return 0;
|
|
},
|
|
},
|
|
};
|
|
var FS_modeStringToFlags = (str) => {
|
|
var flagModes = {
|
|
r: 0,
|
|
'r+': 2,
|
|
w: 512 | 64 | 1,
|
|
'w+': 512 | 64 | 2,
|
|
a: 1024 | 64 | 1,
|
|
'a+': 1024 | 64 | 2,
|
|
};
|
|
var flags = flagModes[str];
|
|
if (typeof flags == 'undefined') {
|
|
throw new Error(`Unknown file open mode: ${str}`);
|
|
}
|
|
return flags;
|
|
};
|
|
var FS_getMode = (canRead, canWrite) => {
|
|
var mode = 0;
|
|
if (canRead) mode |= 292 | 73;
|
|
if (canWrite) mode |= 146;
|
|
return mode;
|
|
};
|
|
var ERRNO_CODES = {
|
|
EPERM: 63,
|
|
ENOENT: 44,
|
|
ESRCH: 71,
|
|
EINTR: 27,
|
|
EIO: 29,
|
|
ENXIO: 60,
|
|
E2BIG: 1,
|
|
ENOEXEC: 45,
|
|
EBADF: 8,
|
|
ECHILD: 12,
|
|
EAGAIN: 6,
|
|
EWOULDBLOCK: 6,
|
|
ENOMEM: 48,
|
|
EACCES: 2,
|
|
EFAULT: 21,
|
|
ENOTBLK: 105,
|
|
EBUSY: 10,
|
|
EEXIST: 20,
|
|
EXDEV: 75,
|
|
ENODEV: 43,
|
|
ENOTDIR: 54,
|
|
EISDIR: 31,
|
|
EINVAL: 28,
|
|
ENFILE: 41,
|
|
EMFILE: 33,
|
|
ENOTTY: 59,
|
|
ETXTBSY: 74,
|
|
EFBIG: 22,
|
|
ENOSPC: 51,
|
|
ESPIPE: 70,
|
|
EROFS: 69,
|
|
EMLINK: 34,
|
|
EPIPE: 64,
|
|
EDOM: 18,
|
|
ERANGE: 68,
|
|
ENOMSG: 49,
|
|
EIDRM: 24,
|
|
ECHRNG: 106,
|
|
EL2NSYNC: 156,
|
|
EL3HLT: 107,
|
|
EL3RST: 108,
|
|
ELNRNG: 109,
|
|
EUNATCH: 110,
|
|
ENOCSI: 111,
|
|
EL2HLT: 112,
|
|
EDEADLK: 16,
|
|
ENOLCK: 46,
|
|
EBADE: 113,
|
|
EBADR: 114,
|
|
EXFULL: 115,
|
|
ENOANO: 104,
|
|
EBADRQC: 103,
|
|
EBADSLT: 102,
|
|
EDEADLOCK: 16,
|
|
EBFONT: 101,
|
|
ENOSTR: 100,
|
|
ENODATA: 116,
|
|
ETIME: 117,
|
|
ENOSR: 118,
|
|
ENONET: 119,
|
|
ENOPKG: 120,
|
|
EREMOTE: 121,
|
|
ENOLINK: 47,
|
|
EADV: 122,
|
|
ESRMNT: 123,
|
|
ECOMM: 124,
|
|
EPROTO: 65,
|
|
EMULTIHOP: 36,
|
|
EDOTDOT: 125,
|
|
EBADMSG: 9,
|
|
ENOTUNIQ: 126,
|
|
EBADFD: 127,
|
|
EREMCHG: 128,
|
|
ELIBACC: 129,
|
|
ELIBBAD: 130,
|
|
ELIBSCN: 131,
|
|
ELIBMAX: 132,
|
|
ELIBEXEC: 133,
|
|
ENOSYS: 52,
|
|
ENOTEMPTY: 55,
|
|
ENAMETOOLONG: 37,
|
|
ELOOP: 32,
|
|
EOPNOTSUPP: 138,
|
|
EPFNOSUPPORT: 139,
|
|
ECONNRESET: 15,
|
|
ENOBUFS: 42,
|
|
EAFNOSUPPORT: 5,
|
|
EPROTOTYPE: 67,
|
|
ENOTSOCK: 57,
|
|
ENOPROTOOPT: 50,
|
|
ESHUTDOWN: 140,
|
|
ECONNREFUSED: 14,
|
|
EADDRINUSE: 3,
|
|
ECONNABORTED: 13,
|
|
ENETUNREACH: 40,
|
|
ENETDOWN: 38,
|
|
ETIMEDOUT: 73,
|
|
EHOSTDOWN: 142,
|
|
EHOSTUNREACH: 23,
|
|
EINPROGRESS: 26,
|
|
EALREADY: 7,
|
|
EDESTADDRREQ: 17,
|
|
EMSGSIZE: 35,
|
|
EPROTONOSUPPORT: 66,
|
|
ESOCKTNOSUPPORT: 137,
|
|
EADDRNOTAVAIL: 4,
|
|
ENETRESET: 39,
|
|
EISCONN: 30,
|
|
ENOTCONN: 53,
|
|
ETOOMANYREFS: 141,
|
|
EUSERS: 136,
|
|
EDQUOT: 19,
|
|
ESTALE: 72,
|
|
ENOTSUP: 138,
|
|
ENOMEDIUM: 148,
|
|
EILSEQ: 25,
|
|
EOVERFLOW: 61,
|
|
ECANCELED: 11,
|
|
ENOTRECOVERABLE: 56,
|
|
EOWNERDEAD: 62,
|
|
ESTRPIPE: 135,
|
|
};
|
|
var PROXYFS = {
|
|
mount(mount) {
|
|
return PROXYFS.createNode(
|
|
null,
|
|
'/',
|
|
mount.opts.fs.lstat(mount.opts.root).mode,
|
|
0
|
|
);
|
|
},
|
|
createNode(parent, name, mode, dev) {
|
|
if (!FS.isDir(mode) && !FS.isFile(mode) && !FS.isLink(mode)) {
|
|
throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
|
|
}
|
|
var node = FS.createNode(parent, name, mode);
|
|
node.node_ops = PROXYFS.node_ops;
|
|
node.stream_ops = PROXYFS.stream_ops;
|
|
return node;
|
|
},
|
|
realPath(node) {
|
|
var parts = [];
|
|
while (node.parent !== node) {
|
|
parts.push(node.name);
|
|
node = node.parent;
|
|
}
|
|
parts.push(node.mount.opts.root);
|
|
parts.reverse();
|
|
return PATH.join(...parts);
|
|
},
|
|
node_ops: {
|
|
getattr(node) {
|
|
var path = PROXYFS.realPath(node);
|
|
var stat;
|
|
try {
|
|
stat = node.mount.opts.fs.lstat(path);
|
|
} catch (e) {
|
|
if (!e.code) throw e;
|
|
throw new FS.ErrnoError(ERRNO_CODES[e.code]);
|
|
}
|
|
return {
|
|
dev: stat.dev,
|
|
ino: stat.ino,
|
|
mode: stat.mode,
|
|
nlink: stat.nlink,
|
|
uid: stat.uid,
|
|
gid: stat.gid,
|
|
rdev: stat.rdev,
|
|
size: stat.size,
|
|
atime: stat.atime,
|
|
mtime: stat.mtime,
|
|
ctime: stat.ctime,
|
|
blksize: stat.blksize,
|
|
blocks: stat.blocks,
|
|
};
|
|
},
|
|
setattr(node, attr) {
|
|
var path = PROXYFS.realPath(node);
|
|
try {
|
|
if (attr.mode !== undefined) {
|
|
node.mount.opts.fs.chmod(path, attr.mode);
|
|
node.mode = attr.mode;
|
|
}
|
|
if (attr.atime || attr.mtime) {
|
|
var atime = new Date(attr.atime || attr.mtime);
|
|
var mtime = new Date(attr.mtime || attr.atime);
|
|
node.mount.opts.fs.utime(path, atime, mtime);
|
|
}
|
|
if (attr.size !== undefined) {
|
|
node.mount.opts.fs.truncate(path, attr.size);
|
|
}
|
|
} catch (e) {
|
|
if (!e.code) throw e;
|
|
throw new FS.ErrnoError(ERRNO_CODES[e.code]);
|
|
}
|
|
},
|
|
lookup(parent, name) {
|
|
try {
|
|
var path = PATH.join2(PROXYFS.realPath(parent), name);
|
|
var mode = parent.mount.opts.fs.lstat(path).mode;
|
|
var node = PROXYFS.createNode(parent, name, mode);
|
|
return node;
|
|
} catch (e) {
|
|
if (!e.code) throw e;
|
|
throw new FS.ErrnoError(ERRNO_CODES[e.code]);
|
|
}
|
|
},
|
|
mknod(parent, name, mode, dev) {
|
|
var node = PROXYFS.createNode(parent, name, mode, dev);
|
|
var path = PROXYFS.realPath(node);
|
|
try {
|
|
if (FS.isDir(node.mode)) {
|
|
node.mount.opts.fs.mkdir(path, node.mode);
|
|
} else {
|
|
node.mount.opts.fs.writeFile(path, '', {
|
|
mode: node.mode,
|
|
});
|
|
}
|
|
} catch (e) {
|
|
if (!e.code) throw e;
|
|
throw new FS.ErrnoError(ERRNO_CODES[e.code]);
|
|
}
|
|
return node;
|
|
},
|
|
rename(oldNode, newDir, newName) {
|
|
var oldPath = PROXYFS.realPath(oldNode);
|
|
var newPath = PATH.join2(PROXYFS.realPath(newDir), newName);
|
|
try {
|
|
oldNode.mount.opts.fs.rename(oldPath, newPath);
|
|
oldNode.name = newName;
|
|
} catch (e) {
|
|
if (!e.code) throw e;
|
|
throw new FS.ErrnoError(ERRNO_CODES[e.code]);
|
|
}
|
|
},
|
|
unlink(parent, name) {
|
|
var path = PATH.join2(PROXYFS.realPath(parent), name);
|
|
try {
|
|
parent.mount.opts.fs.unlink(path);
|
|
} catch (e) {
|
|
if (!e.code) throw e;
|
|
throw new FS.ErrnoError(ERRNO_CODES[e.code]);
|
|
}
|
|
},
|
|
rmdir(parent, name) {
|
|
var path = PATH.join2(PROXYFS.realPath(parent), name);
|
|
try {
|
|
parent.mount.opts.fs.rmdir(path);
|
|
} catch (e) {
|
|
if (!e.code) throw e;
|
|
throw new FS.ErrnoError(ERRNO_CODES[e.code]);
|
|
}
|
|
},
|
|
readdir(node) {
|
|
var path = PROXYFS.realPath(node);
|
|
try {
|
|
return node.mount.opts.fs.readdir(path);
|
|
} catch (e) {
|
|
if (!e.code) throw e;
|
|
throw new FS.ErrnoError(ERRNO_CODES[e.code]);
|
|
}
|
|
},
|
|
symlink(parent, newName, oldPath) {
|
|
var newPath = PATH.join2(PROXYFS.realPath(parent), newName);
|
|
try {
|
|
parent.mount.opts.fs.symlink(oldPath, newPath);
|
|
} catch (e) {
|
|
if (!e.code) throw e;
|
|
throw new FS.ErrnoError(ERRNO_CODES[e.code]);
|
|
}
|
|
},
|
|
readlink(node) {
|
|
var path = PROXYFS.realPath(node);
|
|
try {
|
|
return node.mount.opts.fs.readlink(path);
|
|
} catch (e) {
|
|
if (!e.code) throw e;
|
|
throw new FS.ErrnoError(ERRNO_CODES[e.code]);
|
|
}
|
|
},
|
|
},
|
|
stream_ops: {
|
|
open(stream) {
|
|
var path = PROXYFS.realPath(stream.node);
|
|
try {
|
|
stream.nfd = stream.node.mount.opts.fs.open(
|
|
path,
|
|
stream.flags
|
|
);
|
|
} catch (e) {
|
|
if (!e.code) throw e;
|
|
throw new FS.ErrnoError(ERRNO_CODES[e.code]);
|
|
}
|
|
},
|
|
close(stream) {
|
|
try {
|
|
stream.node.mount.opts.fs.close(stream.nfd);
|
|
} catch (e) {
|
|
if (!e.code) throw e;
|
|
throw new FS.ErrnoError(ERRNO_CODES[e.code]);
|
|
}
|
|
},
|
|
read(stream, buffer, offset, length, position) {
|
|
try {
|
|
return stream.node.mount.opts.fs.read(
|
|
stream.nfd,
|
|
buffer,
|
|
offset,
|
|
length,
|
|
position
|
|
);
|
|
} catch (e) {
|
|
if (!e.code) throw e;
|
|
throw new FS.ErrnoError(ERRNO_CODES[e.code]);
|
|
}
|
|
},
|
|
write(stream, buffer, offset, length, position) {
|
|
try {
|
|
return stream.node.mount.opts.fs.write(
|
|
stream.nfd,
|
|
buffer,
|
|
offset,
|
|
length,
|
|
position
|
|
);
|
|
} catch (e) {
|
|
if (!e.code) throw e;
|
|
throw new FS.ErrnoError(ERRNO_CODES[e.code]);
|
|
}
|
|
},
|
|
llseek(stream, offset, whence) {
|
|
var position = offset;
|
|
if (whence === 1) {
|
|
position += stream.position;
|
|
} else if (whence === 2) {
|
|
if (FS.isFile(stream.node.mode)) {
|
|
try {
|
|
var stat = stream.node.node_ops.getattr(
|
|
stream.node
|
|
);
|
|
position += stat.size;
|
|
} catch (e) {
|
|
throw new FS.ErrnoError(ERRNO_CODES[e.code]);
|
|
}
|
|
}
|
|
}
|
|
if (position < 0) {
|
|
throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
|
|
}
|
|
return position;
|
|
},
|
|
},
|
|
};
|
|
var FS_createDataFile = (...args) => FS.createDataFile(...args);
|
|
var getUniqueRunDependency = (id) => id;
|
|
var FS_handledByPreloadPlugin = async (byteArray, fullname) => {
|
|
if (typeof Browser != 'undefined') Browser.init();
|
|
for (var plugin of preloadPlugins) {
|
|
if (plugin['canHandle'](fullname)) {
|
|
return plugin['handle'](byteArray, fullname);
|
|
}
|
|
}
|
|
return byteArray;
|
|
};
|
|
var FS_preloadFile = async (
|
|
parent,
|
|
name,
|
|
url,
|
|
canRead,
|
|
canWrite,
|
|
dontCreateFile,
|
|
canOwn,
|
|
preFinish
|
|
) => {
|
|
var fullname = name
|
|
? PATH_FS.resolve(PATH.join2(parent, name))
|
|
: parent;
|
|
var dep = getUniqueRunDependency(`cp ${fullname}`);
|
|
addRunDependency(dep);
|
|
try {
|
|
var byteArray = url;
|
|
if (typeof url == 'string') {
|
|
byteArray = await asyncLoad(url);
|
|
}
|
|
byteArray = await FS_handledByPreloadPlugin(byteArray, fullname);
|
|
preFinish?.();
|
|
if (!dontCreateFile) {
|
|
FS_createDataFile(
|
|
parent,
|
|
name,
|
|
byteArray,
|
|
canRead,
|
|
canWrite,
|
|
canOwn
|
|
);
|
|
}
|
|
} finally {
|
|
removeRunDependency(dep);
|
|
}
|
|
};
|
|
var FS_createPreloadedFile = (
|
|
parent,
|
|
name,
|
|
url,
|
|
canRead,
|
|
canWrite,
|
|
onload,
|
|
onerror,
|
|
dontCreateFile,
|
|
canOwn,
|
|
preFinish
|
|
) => {
|
|
FS_preloadFile(
|
|
parent,
|
|
name,
|
|
url,
|
|
canRead,
|
|
canWrite,
|
|
dontCreateFile,
|
|
canOwn,
|
|
preFinish
|
|
)
|
|
.then(onload)
|
|
.catch(onerror);
|
|
};
|
|
var FS = {
|
|
root: null,
|
|
mounts: [],
|
|
devices: {},
|
|
streams: [],
|
|
nextInode: 1,
|
|
nameTable: null,
|
|
currentPath: '/',
|
|
initialized: false,
|
|
ignorePermissions: true,
|
|
filesystems: null,
|
|
syncFSRequests: 0,
|
|
readFiles: {},
|
|
ErrnoError: class {
|
|
name = 'ErrnoError';
|
|
constructor(errno) {
|
|
this.errno = errno;
|
|
}
|
|
},
|
|
FSStream: class {
|
|
shared = {};
|
|
get object() {
|
|
return this.node;
|
|
}
|
|
set object(val) {
|
|
this.node = val;
|
|
}
|
|
get isRead() {
|
|
return (this.flags & 2097155) !== 1;
|
|
}
|
|
get isWrite() {
|
|
return (this.flags & 2097155) !== 0;
|
|
}
|
|
get isAppend() {
|
|
return this.flags & 1024;
|
|
}
|
|
get flags() {
|
|
return this.shared.flags;
|
|
}
|
|
set flags(val) {
|
|
this.shared.flags = val;
|
|
}
|
|
get position() {
|
|
return this.shared.position;
|
|
}
|
|
set position(val) {
|
|
this.shared.position = val;
|
|
}
|
|
},
|
|
FSNode: class {
|
|
node_ops = {};
|
|
stream_ops = {};
|
|
readMode = 292 | 73;
|
|
writeMode = 146;
|
|
mounted = null;
|
|
constructor(parent, name, mode, rdev) {
|
|
if (!parent) {
|
|
parent = this;
|
|
}
|
|
this.parent = parent;
|
|
this.mount = parent.mount;
|
|
this.id = FS.nextInode++;
|
|
this.name = name;
|
|
this.mode = mode;
|
|
this.rdev = rdev;
|
|
this.atime = this.mtime = this.ctime = Date.now();
|
|
}
|
|
get read() {
|
|
return (this.mode & this.readMode) === this.readMode;
|
|
}
|
|
set read(val) {
|
|
val
|
|
? (this.mode |= this.readMode)
|
|
: (this.mode &= ~this.readMode);
|
|
}
|
|
get write() {
|
|
return (this.mode & this.writeMode) === this.writeMode;
|
|
}
|
|
set write(val) {
|
|
val
|
|
? (this.mode |= this.writeMode)
|
|
: (this.mode &= ~this.writeMode);
|
|
}
|
|
get isFolder() {
|
|
return FS.isDir(this.mode);
|
|
}
|
|
get isDevice() {
|
|
return FS.isChrdev(this.mode);
|
|
}
|
|
},
|
|
lookupPath(path, opts = {}) {
|
|
if (!path) {
|
|
throw new FS.ErrnoError(44);
|
|
}
|
|
opts.follow_mount ??= true;
|
|
if (!PATH.isAbs(path)) {
|
|
path = FS.cwd() + '/' + path;
|
|
}
|
|
linkloop: for (var nlinks = 0; nlinks < 40; nlinks++) {
|
|
var parts = path.split('/').filter((p) => !!p);
|
|
var current = FS.root;
|
|
var current_path = '/';
|
|
for (var i = 0; i < parts.length; i++) {
|
|
var islast = i === parts.length - 1;
|
|
if (islast && opts.parent) {
|
|
break;
|
|
}
|
|
if (parts[i] === '.') {
|
|
continue;
|
|
}
|
|
if (parts[i] === '..') {
|
|
current_path = PATH.dirname(current_path);
|
|
if (FS.isRoot(current)) {
|
|
path =
|
|
current_path +
|
|
'/' +
|
|
parts.slice(i + 1).join('/');
|
|
nlinks--;
|
|
continue linkloop;
|
|
} else {
|
|
current = current.parent;
|
|
}
|
|
continue;
|
|
}
|
|
current_path = PATH.join2(current_path, parts[i]);
|
|
try {
|
|
current = FS.lookupNode(current, parts[i]);
|
|
} catch (e) {
|
|
if (e?.errno === 44 && islast && opts.noent_okay) {
|
|
return { path: current_path };
|
|
}
|
|
throw e;
|
|
}
|
|
if (
|
|
FS.isMountpoint(current) &&
|
|
(!islast || opts.follow_mount)
|
|
) {
|
|
current = current.mounted.root;
|
|
}
|
|
if (FS.isLink(current.mode) && (!islast || opts.follow)) {
|
|
if (!current.node_ops.readlink) {
|
|
throw new FS.ErrnoError(52);
|
|
}
|
|
var link = current.node_ops.readlink(current);
|
|
if (!PATH.isAbs(link)) {
|
|
link = PATH.dirname(current_path) + '/' + link;
|
|
}
|
|
path = link + '/' + parts.slice(i + 1).join('/');
|
|
continue linkloop;
|
|
}
|
|
}
|
|
return { path: current_path, node: current };
|
|
}
|
|
throw new FS.ErrnoError(32);
|
|
},
|
|
getPath(node) {
|
|
var path;
|
|
while (true) {
|
|
if (FS.isRoot(node)) {
|
|
var mount = node.mount.mountpoint;
|
|
if (!path) return mount;
|
|
return mount[mount.length - 1] !== '/'
|
|
? `${mount}/${path}`
|
|
: mount + path;
|
|
}
|
|
path = path ? `${node.name}/${path}` : node.name;
|
|
node = node.parent;
|
|
}
|
|
},
|
|
hashName(parentid, name) {
|
|
var hash = 0;
|
|
for (var i = 0; i < name.length; i++) {
|
|
hash = ((hash << 5) - hash + name.charCodeAt(i)) | 0;
|
|
}
|
|
return ((parentid + hash) >>> 0) % FS.nameTable.length;
|
|
},
|
|
hashAddNode(node) {
|
|
var hash = FS.hashName(node.parent.id, node.name);
|
|
node.name_next = FS.nameTable[hash];
|
|
FS.nameTable[hash] = node;
|
|
},
|
|
hashRemoveNode(node) {
|
|
var hash = FS.hashName(node.parent.id, node.name);
|
|
if (FS.nameTable[hash] === node) {
|
|
FS.nameTable[hash] = node.name_next;
|
|
} else {
|
|
var current = FS.nameTable[hash];
|
|
while (current) {
|
|
if (current.name_next === node) {
|
|
current.name_next = node.name_next;
|
|
break;
|
|
}
|
|
current = current.name_next;
|
|
}
|
|
}
|
|
},
|
|
lookupNode(parent, name) {
|
|
var errCode = FS.mayLookup(parent);
|
|
if (errCode) {
|
|
throw new FS.ErrnoError(errCode);
|
|
}
|
|
var hash = FS.hashName(parent.id, name);
|
|
for (var node = FS.nameTable[hash]; node; node = node.name_next) {
|
|
var nodeName = node.name;
|
|
if (node.parent.id === parent.id && nodeName === name) {
|
|
return node;
|
|
}
|
|
}
|
|
return FS.lookup(parent, name);
|
|
},
|
|
createNode(parent, name, mode, rdev) {
|
|
var node = new FS.FSNode(parent, name, mode, rdev);
|
|
FS.hashAddNode(node);
|
|
return node;
|
|
},
|
|
destroyNode(node) {
|
|
FS.hashRemoveNode(node);
|
|
},
|
|
isRoot(node) {
|
|
return node === node.parent;
|
|
},
|
|
isMountpoint(node) {
|
|
return !!node.mounted;
|
|
},
|
|
isFile(mode) {
|
|
return (mode & 61440) === 32768;
|
|
},
|
|
isDir(mode) {
|
|
return (mode & 61440) === 16384;
|
|
},
|
|
isLink(mode) {
|
|
return (mode & 61440) === 40960;
|
|
},
|
|
isChrdev(mode) {
|
|
return (mode & 61440) === 8192;
|
|
},
|
|
isBlkdev(mode) {
|
|
return (mode & 61440) === 24576;
|
|
},
|
|
isFIFO(mode) {
|
|
return (mode & 61440) === 4096;
|
|
},
|
|
isSocket(mode) {
|
|
return (mode & 49152) === 49152;
|
|
},
|
|
flagsToPermissionString(flag) {
|
|
var perms = ['r', 'w', 'rw'][flag & 3];
|
|
if (flag & 512) {
|
|
perms += 'w';
|
|
}
|
|
return perms;
|
|
},
|
|
nodePermissions(node, perms) {
|
|
if (FS.ignorePermissions) {
|
|
return 0;
|
|
}
|
|
if (perms.includes('r') && !(node.mode & 292)) {
|
|
return 2;
|
|
} else if (perms.includes('w') && !(node.mode & 146)) {
|
|
return 2;
|
|
} else if (perms.includes('x') && !(node.mode & 73)) {
|
|
return 2;
|
|
}
|
|
return 0;
|
|
},
|
|
mayLookup(dir) {
|
|
if (!FS.isDir(dir.mode)) return 54;
|
|
var errCode = FS.nodePermissions(dir, 'x');
|
|
if (errCode) return errCode;
|
|
if (!dir.node_ops.lookup) return 2;
|
|
return 0;
|
|
},
|
|
mayCreate(dir, name) {
|
|
if (!FS.isDir(dir.mode)) {
|
|
return 54;
|
|
}
|
|
try {
|
|
var node = FS.lookupNode(dir, name);
|
|
return 20;
|
|
} catch (e) {}
|
|
return FS.nodePermissions(dir, 'wx');
|
|
},
|
|
mayDelete(dir, name, isdir) {
|
|
var node;
|
|
try {
|
|
node = FS.lookupNode(dir, name);
|
|
} catch (e) {
|
|
return e.errno;
|
|
}
|
|
var errCode = FS.nodePermissions(dir, 'wx');
|
|
if (errCode) {
|
|
return errCode;
|
|
}
|
|
if (isdir) {
|
|
if (!FS.isDir(node.mode)) {
|
|
return 54;
|
|
}
|
|
if (FS.isRoot(node) || FS.getPath(node) === FS.cwd()) {
|
|
return 10;
|
|
}
|
|
} else {
|
|
if (FS.isDir(node.mode)) {
|
|
return 31;
|
|
}
|
|
}
|
|
return 0;
|
|
},
|
|
mayOpen(node, flags) {
|
|
if (!node) {
|
|
return 44;
|
|
}
|
|
if (FS.isLink(node.mode)) {
|
|
return 32;
|
|
} else if (FS.isDir(node.mode)) {
|
|
if (
|
|
FS.flagsToPermissionString(flags) !== 'r' ||
|
|
flags & (512 | 64)
|
|
) {
|
|
return 31;
|
|
}
|
|
}
|
|
return FS.nodePermissions(node, FS.flagsToPermissionString(flags));
|
|
},
|
|
checkOpExists(op, err) {
|
|
if (!op) {
|
|
throw new FS.ErrnoError(err);
|
|
}
|
|
return op;
|
|
},
|
|
MAX_OPEN_FDS: 4096,
|
|
nextfd() {
|
|
for (var fd = 0; fd <= FS.MAX_OPEN_FDS; fd++) {
|
|
if (!FS.streams[fd]) {
|
|
return fd;
|
|
}
|
|
}
|
|
throw new FS.ErrnoError(33);
|
|
},
|
|
getStreamChecked(fd) {
|
|
var stream = FS.getStream(fd);
|
|
if (!stream) {
|
|
throw new FS.ErrnoError(8);
|
|
}
|
|
return stream;
|
|
},
|
|
getStream: (fd) => FS.streams[fd],
|
|
createStream(stream, fd = -1) {
|
|
stream = Object.assign(new FS.FSStream(), stream);
|
|
if (fd == -1) {
|
|
fd = FS.nextfd();
|
|
}
|
|
stream.fd = fd;
|
|
FS.streams[fd] = stream;
|
|
return stream;
|
|
},
|
|
closeStream(fd) {
|
|
FS.streams[fd] = null;
|
|
},
|
|
dupStream(origStream, fd = -1) {
|
|
var stream = FS.createStream(origStream, fd);
|
|
stream.stream_ops?.dup?.(stream);
|
|
return stream;
|
|
},
|
|
doSetAttr(stream, node, attr) {
|
|
var setattr = stream?.stream_ops.setattr;
|
|
var arg = setattr ? stream : node;
|
|
setattr ??= node.node_ops.setattr;
|
|
FS.checkOpExists(setattr, 63);
|
|
setattr(arg, attr);
|
|
},
|
|
chrdev_stream_ops: {
|
|
open(stream) {
|
|
var device = FS.getDevice(stream.node.rdev);
|
|
stream.stream_ops = device.stream_ops;
|
|
stream.stream_ops.open?.(stream);
|
|
},
|
|
llseek() {
|
|
throw new FS.ErrnoError(70);
|
|
},
|
|
},
|
|
major: (dev) => dev >> 8,
|
|
minor: (dev) => dev & 255,
|
|
makedev: (ma, mi) => (ma << 8) | mi,
|
|
registerDevice(dev, ops) {
|
|
FS.devices[dev] = { stream_ops: ops };
|
|
},
|
|
getDevice: (dev) => FS.devices[dev],
|
|
getMounts(mount) {
|
|
var mounts = [];
|
|
var check = [mount];
|
|
while (check.length) {
|
|
var m = check.pop();
|
|
mounts.push(m);
|
|
check.push(...m.mounts);
|
|
}
|
|
return mounts;
|
|
},
|
|
syncfs(populate, callback) {
|
|
if (typeof populate == 'function') {
|
|
callback = populate;
|
|
populate = false;
|
|
}
|
|
FS.syncFSRequests++;
|
|
if (FS.syncFSRequests > 1) {
|
|
err(
|
|
`warning: ${FS.syncFSRequests} FS.syncfs operations in flight at once, probably just doing extra work`
|
|
);
|
|
}
|
|
var mounts = FS.getMounts(FS.root.mount);
|
|
var completed = 0;
|
|
function doCallback(errCode) {
|
|
FS.syncFSRequests--;
|
|
return callback(errCode);
|
|
}
|
|
function done(errCode) {
|
|
if (errCode) {
|
|
if (!done.errored) {
|
|
done.errored = true;
|
|
return doCallback(errCode);
|
|
}
|
|
return;
|
|
}
|
|
if (++completed >= mounts.length) {
|
|
doCallback(null);
|
|
}
|
|
}
|
|
for (var mount of mounts) {
|
|
if (mount.type.syncfs) {
|
|
mount.type.syncfs(mount, populate, done);
|
|
} else {
|
|
done(null);
|
|
}
|
|
}
|
|
},
|
|
mount(type, opts, mountpoint) {
|
|
var root = mountpoint === '/';
|
|
var pseudo = !mountpoint;
|
|
var node;
|
|
if (root && FS.root) {
|
|
throw new FS.ErrnoError(10);
|
|
} else if (!root && !pseudo) {
|
|
var lookup = FS.lookupPath(mountpoint, { follow_mount: false });
|
|
mountpoint = lookup.path;
|
|
node = lookup.node;
|
|
if (FS.isMountpoint(node)) {
|
|
throw new FS.ErrnoError(10);
|
|
}
|
|
}
|
|
var mount = { type, opts, mountpoint, mounts: [] };
|
|
var mountRoot = type.mount(mount);
|
|
mountRoot.mount = mount;
|
|
mount.root = mountRoot;
|
|
if (root) {
|
|
FS.root = mountRoot;
|
|
} else if (node) {
|
|
node.mounted = mount;
|
|
if (node.mount) {
|
|
node.mount.mounts.push(mount);
|
|
}
|
|
}
|
|
return mountRoot;
|
|
},
|
|
unmount(mountpoint) {
|
|
var lookup = FS.lookupPath(mountpoint, { follow_mount: false });
|
|
if (!FS.isMountpoint(lookup.node)) {
|
|
throw new FS.ErrnoError(28);
|
|
}
|
|
var node = lookup.node;
|
|
var mount = node.mounted;
|
|
var mounts = FS.getMounts(mount);
|
|
for (var [hash, current] of Object.entries(FS.nameTable)) {
|
|
while (current) {
|
|
var next = current.name_next;
|
|
if (mounts.includes(current.mount)) {
|
|
FS.destroyNode(current);
|
|
}
|
|
current = next;
|
|
}
|
|
}
|
|
node.mounted = null;
|
|
var idx = node.mount.mounts.indexOf(mount);
|
|
node.mount.mounts.splice(idx, 1);
|
|
},
|
|
lookup(parent, name) {
|
|
return parent.node_ops.lookup(parent, name);
|
|
},
|
|
mknod(path, mode, dev) {
|
|
var lookup = FS.lookupPath(path, { parent: true });
|
|
var parent = lookup.node;
|
|
var name = PATH.basename(path);
|
|
if (!name) {
|
|
throw new FS.ErrnoError(28);
|
|
}
|
|
if (name === '.' || name === '..') {
|
|
throw new FS.ErrnoError(20);
|
|
}
|
|
var errCode = FS.mayCreate(parent, name);
|
|
if (errCode) {
|
|
throw new FS.ErrnoError(errCode);
|
|
}
|
|
if (!parent.node_ops.mknod) {
|
|
throw new FS.ErrnoError(63);
|
|
}
|
|
return parent.node_ops.mknod(parent, name, mode, dev);
|
|
},
|
|
statfs(path) {
|
|
return FS.statfsNode(FS.lookupPath(path, { follow: true }).node);
|
|
},
|
|
statfsStream(stream) {
|
|
return FS.statfsNode(stream.node);
|
|
},
|
|
statfsNode(node) {
|
|
var rtn = {
|
|
bsize: 4096,
|
|
frsize: 4096,
|
|
blocks: 1e6,
|
|
bfree: 5e5,
|
|
bavail: 5e5,
|
|
files: FS.nextInode,
|
|
ffree: FS.nextInode - 1,
|
|
fsid: 42,
|
|
flags: 2,
|
|
namelen: 255,
|
|
};
|
|
if (node.node_ops.statfs) {
|
|
Object.assign(rtn, node.node_ops.statfs(node.mount.opts.root));
|
|
}
|
|
return rtn;
|
|
},
|
|
create(path, mode = 438) {
|
|
mode &= 4095;
|
|
mode |= 32768;
|
|
return FS.mknod(path, mode, 0);
|
|
},
|
|
mkdir(path, mode = 511) {
|
|
mode &= 511 | 512;
|
|
mode |= 16384;
|
|
return FS.mknod(path, mode, 0);
|
|
},
|
|
mkdirTree(path, mode) {
|
|
var dirs = path.split('/');
|
|
var d = '';
|
|
for (var dir of dirs) {
|
|
if (!dir) continue;
|
|
if (d || PATH.isAbs(path)) d += '/';
|
|
d += dir;
|
|
try {
|
|
FS.mkdir(d, mode);
|
|
} catch (e) {
|
|
if (e.errno != 20) throw e;
|
|
}
|
|
}
|
|
},
|
|
mkdev(path, mode, dev) {
|
|
if (typeof dev == 'undefined') {
|
|
dev = mode;
|
|
mode = 438;
|
|
}
|
|
mode |= 8192;
|
|
return FS.mknod(path, mode, dev);
|
|
},
|
|
symlink(oldpath, newpath) {
|
|
if (!PATH_FS.resolve(oldpath)) {
|
|
throw new FS.ErrnoError(44);
|
|
}
|
|
var lookup = FS.lookupPath(newpath, { parent: true });
|
|
var parent = lookup.node;
|
|
if (!parent) {
|
|
throw new FS.ErrnoError(44);
|
|
}
|
|
var newname = PATH.basename(newpath);
|
|
var errCode = FS.mayCreate(parent, newname);
|
|
if (errCode) {
|
|
throw new FS.ErrnoError(errCode);
|
|
}
|
|
if (!parent.node_ops.symlink) {
|
|
throw new FS.ErrnoError(63);
|
|
}
|
|
return parent.node_ops.symlink(parent, newname, oldpath);
|
|
},
|
|
rename(old_path, new_path) {
|
|
var old_dirname = PATH.dirname(old_path);
|
|
var new_dirname = PATH.dirname(new_path);
|
|
var old_name = PATH.basename(old_path);
|
|
var new_name = PATH.basename(new_path);
|
|
var lookup, old_dir, new_dir;
|
|
lookup = FS.lookupPath(old_path, { parent: true });
|
|
old_dir = lookup.node;
|
|
lookup = FS.lookupPath(new_path, { parent: true });
|
|
new_dir = lookup.node;
|
|
if (!old_dir || !new_dir) throw new FS.ErrnoError(44);
|
|
if (old_dir.mount !== new_dir.mount) {
|
|
throw new FS.ErrnoError(75);
|
|
}
|
|
var old_node = FS.lookupNode(old_dir, old_name);
|
|
var relative = PATH_FS.relative(old_path, new_dirname);
|
|
if (relative.charAt(0) !== '.') {
|
|
throw new FS.ErrnoError(28);
|
|
}
|
|
relative = PATH_FS.relative(new_path, old_dirname);
|
|
if (relative.charAt(0) !== '.') {
|
|
throw new FS.ErrnoError(55);
|
|
}
|
|
var new_node;
|
|
try {
|
|
new_node = FS.lookupNode(new_dir, new_name);
|
|
} catch (e) {}
|
|
if (old_node === new_node) {
|
|
return;
|
|
}
|
|
var isdir = FS.isDir(old_node.mode);
|
|
var errCode = FS.mayDelete(old_dir, old_name, isdir);
|
|
if (errCode) {
|
|
throw new FS.ErrnoError(errCode);
|
|
}
|
|
errCode = new_node
|
|
? FS.mayDelete(new_dir, new_name, isdir)
|
|
: FS.mayCreate(new_dir, new_name);
|
|
if (errCode) {
|
|
throw new FS.ErrnoError(errCode);
|
|
}
|
|
if (!old_dir.node_ops.rename) {
|
|
throw new FS.ErrnoError(63);
|
|
}
|
|
if (
|
|
FS.isMountpoint(old_node) ||
|
|
(new_node && FS.isMountpoint(new_node))
|
|
) {
|
|
throw new FS.ErrnoError(10);
|
|
}
|
|
if (new_dir !== old_dir) {
|
|
errCode = FS.nodePermissions(old_dir, 'w');
|
|
if (errCode) {
|
|
throw new FS.ErrnoError(errCode);
|
|
}
|
|
}
|
|
FS.hashRemoveNode(old_node);
|
|
try {
|
|
old_dir.node_ops.rename(old_node, new_dir, new_name);
|
|
old_node.parent = new_dir;
|
|
} catch (e) {
|
|
throw e;
|
|
} finally {
|
|
FS.hashAddNode(old_node);
|
|
}
|
|
},
|
|
rmdir(path) {
|
|
var lookup = FS.lookupPath(path, { parent: true });
|
|
var parent = lookup.node;
|
|
var name = PATH.basename(path);
|
|
var node = FS.lookupNode(parent, name);
|
|
var errCode = FS.mayDelete(parent, name, true);
|
|
if (errCode) {
|
|
throw new FS.ErrnoError(errCode);
|
|
}
|
|
if (!parent.node_ops.rmdir) {
|
|
throw new FS.ErrnoError(63);
|
|
}
|
|
if (FS.isMountpoint(node)) {
|
|
throw new FS.ErrnoError(10);
|
|
}
|
|
parent.node_ops.rmdir(parent, name);
|
|
FS.destroyNode(node);
|
|
},
|
|
readdir(path) {
|
|
var lookup = FS.lookupPath(path, { follow: true });
|
|
var node = lookup.node;
|
|
var readdir = FS.checkOpExists(node.node_ops.readdir, 54);
|
|
return readdir(node);
|
|
},
|
|
unlink(path) {
|
|
var lookup = FS.lookupPath(path, { parent: true });
|
|
var parent = lookup.node;
|
|
if (!parent) {
|
|
throw new FS.ErrnoError(44);
|
|
}
|
|
var name = PATH.basename(path);
|
|
var node = FS.lookupNode(parent, name);
|
|
var errCode = FS.mayDelete(parent, name, false);
|
|
if (errCode) {
|
|
throw new FS.ErrnoError(errCode);
|
|
}
|
|
if (!parent.node_ops.unlink) {
|
|
throw new FS.ErrnoError(63);
|
|
}
|
|
if (FS.isMountpoint(node)) {
|
|
throw new FS.ErrnoError(10);
|
|
}
|
|
parent.node_ops.unlink(parent, name);
|
|
FS.destroyNode(node);
|
|
},
|
|
readlink(path) {
|
|
var lookup = FS.lookupPath(path);
|
|
var link = lookup.node;
|
|
if (!link) {
|
|
throw new FS.ErrnoError(44);
|
|
}
|
|
if (!link.node_ops.readlink) {
|
|
throw new FS.ErrnoError(28);
|
|
}
|
|
return link.node_ops.readlink(link);
|
|
},
|
|
stat(path, dontFollow) {
|
|
var lookup = FS.lookupPath(path, { follow: !dontFollow });
|
|
var node = lookup.node;
|
|
var getattr = FS.checkOpExists(node.node_ops.getattr, 63);
|
|
return getattr(node);
|
|
},
|
|
fstat(fd) {
|
|
var stream = FS.getStreamChecked(fd);
|
|
var node = stream.node;
|
|
var getattr = stream.stream_ops.getattr;
|
|
var arg = getattr ? stream : node;
|
|
getattr ??= node.node_ops.getattr;
|
|
FS.checkOpExists(getattr, 63);
|
|
return getattr(arg);
|
|
},
|
|
lstat(path) {
|
|
return FS.stat(path, true);
|
|
},
|
|
doChmod(stream, node, mode, dontFollow) {
|
|
FS.doSetAttr(stream, node, {
|
|
mode: (mode & 4095) | (node.mode & ~4095),
|
|
ctime: Date.now(),
|
|
dontFollow,
|
|
});
|
|
},
|
|
chmod(path, mode, dontFollow) {
|
|
var node;
|
|
if (typeof path == 'string') {
|
|
var lookup = FS.lookupPath(path, { follow: !dontFollow });
|
|
node = lookup.node;
|
|
} else {
|
|
node = path;
|
|
}
|
|
FS.doChmod(null, node, mode, dontFollow);
|
|
},
|
|
lchmod(path, mode) {
|
|
FS.chmod(path, mode, true);
|
|
},
|
|
fchmod(fd, mode) {
|
|
var stream = FS.getStreamChecked(fd);
|
|
FS.doChmod(stream, stream.node, mode, false);
|
|
},
|
|
doChown(stream, node, dontFollow) {
|
|
FS.doSetAttr(stream, node, { timestamp: Date.now(), dontFollow });
|
|
},
|
|
chown(path, uid, gid, dontFollow) {
|
|
var node;
|
|
if (typeof path == 'string') {
|
|
var lookup = FS.lookupPath(path, { follow: !dontFollow });
|
|
node = lookup.node;
|
|
} else {
|
|
node = path;
|
|
}
|
|
FS.doChown(null, node, dontFollow);
|
|
},
|
|
lchown(path, uid, gid) {
|
|
FS.chown(path, uid, gid, true);
|
|
},
|
|
fchown(fd, uid, gid) {
|
|
var stream = FS.getStreamChecked(fd);
|
|
FS.doChown(stream, stream.node, false);
|
|
},
|
|
doTruncate(stream, node, len) {
|
|
if (FS.isDir(node.mode)) {
|
|
throw new FS.ErrnoError(31);
|
|
}
|
|
if (!FS.isFile(node.mode)) {
|
|
throw new FS.ErrnoError(28);
|
|
}
|
|
var errCode = FS.nodePermissions(node, 'w');
|
|
if (errCode) {
|
|
throw new FS.ErrnoError(errCode);
|
|
}
|
|
FS.doSetAttr(stream, node, { size: len, timestamp: Date.now() });
|
|
},
|
|
truncate(path, len) {
|
|
if (len < 0) {
|
|
throw new FS.ErrnoError(28);
|
|
}
|
|
var node;
|
|
if (typeof path == 'string') {
|
|
var lookup = FS.lookupPath(path, { follow: true });
|
|
node = lookup.node;
|
|
} else {
|
|
node = path;
|
|
}
|
|
FS.doTruncate(null, node, len);
|
|
},
|
|
ftruncate(fd, len) {
|
|
var stream = FS.getStreamChecked(fd);
|
|
if (len < 0 || (stream.flags & 2097155) === 0) {
|
|
throw new FS.ErrnoError(28);
|
|
}
|
|
FS.doTruncate(stream, stream.node, len);
|
|
},
|
|
utime(path, atime, mtime) {
|
|
var lookup = FS.lookupPath(path, { follow: true });
|
|
var node = lookup.node;
|
|
var setattr = FS.checkOpExists(node.node_ops.setattr, 63);
|
|
setattr(node, { atime, mtime });
|
|
},
|
|
open(path, flags, mode = 438) {
|
|
if (path === '') {
|
|
throw new FS.ErrnoError(44);
|
|
}
|
|
flags =
|
|
typeof flags == 'string' ? FS_modeStringToFlags(flags) : flags;
|
|
if (flags & 64) {
|
|
mode = (mode & 4095) | 32768;
|
|
} else {
|
|
mode = 0;
|
|
}
|
|
var node;
|
|
var isDirPath;
|
|
if (typeof path == 'object') {
|
|
node = path;
|
|
} else {
|
|
isDirPath = path.endsWith('/');
|
|
var lookup = FS.lookupPath(path, {
|
|
follow: !(flags & 131072),
|
|
noent_okay: true,
|
|
});
|
|
node = lookup.node;
|
|
path = lookup.path;
|
|
}
|
|
var created = false;
|
|
if (flags & 64) {
|
|
if (node) {
|
|
if (flags & 128) {
|
|
throw new FS.ErrnoError(20);
|
|
}
|
|
} else if (isDirPath) {
|
|
throw new FS.ErrnoError(31);
|
|
} else {
|
|
node = FS.mknod(path, mode | 511, 0);
|
|
created = true;
|
|
}
|
|
}
|
|
if (!node) {
|
|
throw new FS.ErrnoError(44);
|
|
}
|
|
if (FS.isChrdev(node.mode)) {
|
|
flags &= ~512;
|
|
}
|
|
if (flags & 65536 && !FS.isDir(node.mode)) {
|
|
throw new FS.ErrnoError(54);
|
|
}
|
|
if (!created) {
|
|
var errCode = FS.mayOpen(node, flags);
|
|
if (errCode) {
|
|
throw new FS.ErrnoError(errCode);
|
|
}
|
|
}
|
|
if (flags & 512 && !created) {
|
|
FS.truncate(node, 0);
|
|
}
|
|
flags &= ~(128 | 512 | 131072);
|
|
var stream = FS.createStream({
|
|
node,
|
|
path: FS.getPath(node),
|
|
flags,
|
|
seekable: true,
|
|
position: 0,
|
|
stream_ops: node.stream_ops,
|
|
ungotten: [],
|
|
error: false,
|
|
});
|
|
if (stream.stream_ops.open) {
|
|
stream.stream_ops.open(stream);
|
|
}
|
|
if (created) {
|
|
FS.chmod(node, mode & 511);
|
|
}
|
|
if (Module['logReadFiles'] && !(flags & 1)) {
|
|
if (!(path in FS.readFiles)) {
|
|
FS.readFiles[path] = 1;
|
|
}
|
|
}
|
|
return stream;
|
|
},
|
|
close(stream) {
|
|
if (FS.isClosed(stream)) {
|
|
throw new FS.ErrnoError(8);
|
|
}
|
|
if (stream.getdents) stream.getdents = null;
|
|
try {
|
|
if (stream.stream_ops.close) {
|
|
stream.stream_ops.close(stream);
|
|
}
|
|
} catch (e) {
|
|
throw e;
|
|
} finally {
|
|
FS.closeStream(stream.fd);
|
|
}
|
|
stream.fd = null;
|
|
},
|
|
isClosed(stream) {
|
|
return stream.fd === null;
|
|
},
|
|
llseek(stream, offset, whence) {
|
|
if (FS.isClosed(stream)) {
|
|
throw new FS.ErrnoError(8);
|
|
}
|
|
if (!stream.seekable || !stream.stream_ops.llseek) {
|
|
throw new FS.ErrnoError(70);
|
|
}
|
|
if (whence != 0 && whence != 1 && whence != 2) {
|
|
throw new FS.ErrnoError(28);
|
|
}
|
|
stream.position = stream.stream_ops.llseek(stream, offset, whence);
|
|
stream.ungotten = [];
|
|
return stream.position;
|
|
},
|
|
read(stream, buffer, offset, length, position) {
|
|
if (length < 0 || position < 0) {
|
|
throw new FS.ErrnoError(28);
|
|
}
|
|
if (FS.isClosed(stream)) {
|
|
throw new FS.ErrnoError(8);
|
|
}
|
|
if ((stream.flags & 2097155) === 1) {
|
|
throw new FS.ErrnoError(8);
|
|
}
|
|
if (FS.isDir(stream.node.mode)) {
|
|
throw new FS.ErrnoError(31);
|
|
}
|
|
if (!stream.stream_ops.read) {
|
|
throw new FS.ErrnoError(28);
|
|
}
|
|
var seeking = typeof position != 'undefined';
|
|
if (!seeking) {
|
|
position = stream.position;
|
|
} else if (!stream.seekable) {
|
|
throw new FS.ErrnoError(70);
|
|
}
|
|
var bytesRead = stream.stream_ops.read(
|
|
stream,
|
|
buffer,
|
|
offset,
|
|
length,
|
|
position
|
|
);
|
|
if (!seeking) stream.position += bytesRead;
|
|
return bytesRead;
|
|
},
|
|
write(stream, buffer, offset, length, position, canOwn) {
|
|
if (length < 0 || position < 0) {
|
|
throw new FS.ErrnoError(28);
|
|
}
|
|
if (FS.isClosed(stream)) {
|
|
throw new FS.ErrnoError(8);
|
|
}
|
|
if ((stream.flags & 2097155) === 0) {
|
|
throw new FS.ErrnoError(8);
|
|
}
|
|
if (FS.isDir(stream.node.mode)) {
|
|
throw new FS.ErrnoError(31);
|
|
}
|
|
if (!stream.stream_ops.write) {
|
|
throw new FS.ErrnoError(28);
|
|
}
|
|
if (stream.seekable && stream.flags & 1024) {
|
|
FS.llseek(stream, 0, 2);
|
|
}
|
|
var seeking = typeof position != 'undefined';
|
|
if (!seeking) {
|
|
position = stream.position;
|
|
} else if (!stream.seekable) {
|
|
throw new FS.ErrnoError(70);
|
|
}
|
|
var bytesWritten = stream.stream_ops.write(
|
|
stream,
|
|
buffer,
|
|
offset,
|
|
length,
|
|
position,
|
|
canOwn
|
|
);
|
|
if (!seeking) stream.position += bytesWritten;
|
|
return bytesWritten;
|
|
},
|
|
mmap(stream, length, position, prot, flags) {
|
|
if (
|
|
(prot & 2) !== 0 &&
|
|
(flags & 2) === 0 &&
|
|
(stream.flags & 2097155) !== 2
|
|
) {
|
|
throw new FS.ErrnoError(2);
|
|
}
|
|
if ((stream.flags & 2097155) === 1) {
|
|
throw new FS.ErrnoError(2);
|
|
}
|
|
if (!stream.stream_ops.mmap) {
|
|
throw new FS.ErrnoError(43);
|
|
}
|
|
if (!length) {
|
|
throw new FS.ErrnoError(28);
|
|
}
|
|
return stream.stream_ops.mmap(
|
|
stream,
|
|
length,
|
|
position,
|
|
prot,
|
|
flags
|
|
);
|
|
},
|
|
msync(stream, buffer, offset, length, mmapFlags) {
|
|
if (!stream.stream_ops.msync) {
|
|
return 0;
|
|
}
|
|
return stream.stream_ops.msync(
|
|
stream,
|
|
buffer,
|
|
offset,
|
|
length,
|
|
mmapFlags
|
|
);
|
|
},
|
|
ioctl(stream, cmd, arg) {
|
|
if (!stream.stream_ops.ioctl) {
|
|
throw new FS.ErrnoError(59);
|
|
}
|
|
return stream.stream_ops.ioctl(stream, cmd, arg);
|
|
},
|
|
readFile(path, opts = {}) {
|
|
opts.flags = opts.flags || 0;
|
|
opts.encoding = opts.encoding || 'binary';
|
|
if (opts.encoding !== 'utf8' && opts.encoding !== 'binary') {
|
|
abort(`Invalid encoding type "${opts.encoding}"`);
|
|
}
|
|
var stream = FS.open(path, opts.flags);
|
|
var stat = FS.stat(path);
|
|
var length = stat.size;
|
|
var buf = new Uint8Array(length);
|
|
FS.read(stream, buf, 0, length, 0);
|
|
if (opts.encoding === 'utf8') {
|
|
buf = UTF8ArrayToString(buf);
|
|
}
|
|
FS.close(stream);
|
|
return buf;
|
|
},
|
|
writeFile(path, data, opts = {}) {
|
|
opts.flags = opts.flags || 577;
|
|
var stream = FS.open(path, opts.flags, opts.mode);
|
|
if (typeof data == 'string') {
|
|
data = new Uint8Array(intArrayFromString(data, true));
|
|
}
|
|
if (ArrayBuffer.isView(data)) {
|
|
FS.write(
|
|
stream,
|
|
data,
|
|
0,
|
|
data.byteLength,
|
|
undefined,
|
|
opts.canOwn
|
|
);
|
|
} else {
|
|
abort('Unsupported data type');
|
|
}
|
|
FS.close(stream);
|
|
},
|
|
cwd: () => FS.currentPath,
|
|
chdir(path) {
|
|
var lookup = FS.lookupPath(path, { follow: true });
|
|
if (lookup.node === null) {
|
|
throw new FS.ErrnoError(44);
|
|
}
|
|
if (!FS.isDir(lookup.node.mode)) {
|
|
throw new FS.ErrnoError(54);
|
|
}
|
|
var errCode = FS.nodePermissions(lookup.node, 'x');
|
|
if (errCode) {
|
|
throw new FS.ErrnoError(errCode);
|
|
}
|
|
FS.currentPath = lookup.path;
|
|
},
|
|
createDefaultDirectories() {
|
|
FS.mkdir('/tmp');
|
|
FS.mkdir('/home');
|
|
FS.mkdir('/home/web_user');
|
|
},
|
|
createDefaultDevices() {
|
|
FS.mkdir('/dev');
|
|
FS.registerDevice(FS.makedev(1, 3), {
|
|
read: () => 0,
|
|
write: (stream, buffer, offset, length, pos) => length,
|
|
llseek: () => 0,
|
|
});
|
|
FS.mkdev('/dev/null', FS.makedev(1, 3));
|
|
TTY.register(FS.makedev(5, 0), TTY.default_tty_ops);
|
|
TTY.register(FS.makedev(6, 0), TTY.default_tty1_ops);
|
|
FS.mkdev('/dev/tty', FS.makedev(5, 0));
|
|
FS.mkdev('/dev/tty1', FS.makedev(6, 0));
|
|
var randomBuffer = new Uint8Array(1024),
|
|
randomLeft = 0;
|
|
var randomByte = () => {
|
|
if (randomLeft === 0) {
|
|
randomFill(randomBuffer);
|
|
randomLeft = randomBuffer.byteLength;
|
|
}
|
|
return randomBuffer[--randomLeft];
|
|
};
|
|
FS.createDevice('/dev', 'random', randomByte);
|
|
FS.createDevice('/dev', 'urandom', randomByte);
|
|
FS.mkdir('/dev/shm');
|
|
FS.mkdir('/dev/shm/tmp');
|
|
},
|
|
createSpecialDirectories() {
|
|
FS.mkdir('/proc');
|
|
var proc_self = FS.mkdir('/proc/self');
|
|
FS.mkdir('/proc/self/fd');
|
|
FS.mount(
|
|
{
|
|
mount() {
|
|
var node = FS.createNode(proc_self, 'fd', 16895, 73);
|
|
node.stream_ops = { llseek: MEMFS.stream_ops.llseek };
|
|
node.node_ops = {
|
|
lookup(parent, name) {
|
|
var fd = +name;
|
|
var stream = FS.getStreamChecked(fd);
|
|
var ret = {
|
|
parent: null,
|
|
mount: { mountpoint: 'fake' },
|
|
node_ops: { readlink: () => stream.path },
|
|
id: fd + 1,
|
|
};
|
|
ret.parent = ret;
|
|
return ret;
|
|
},
|
|
readdir() {
|
|
return Array.from(FS.streams.entries())
|
|
.filter(([k, v]) => v)
|
|
.map(([k, v]) => k.toString());
|
|
},
|
|
};
|
|
return node;
|
|
},
|
|
},
|
|
{},
|
|
'/proc/self/fd'
|
|
);
|
|
},
|
|
createStandardStreams(input, output, error) {
|
|
if (input) {
|
|
FS.createDevice('/dev', 'stdin', input);
|
|
} else {
|
|
FS.symlink('/dev/tty', '/dev/stdin');
|
|
}
|
|
if (output) {
|
|
FS.createDevice('/dev', 'stdout', null, output);
|
|
} else {
|
|
FS.symlink('/dev/tty', '/dev/stdout');
|
|
}
|
|
if (error) {
|
|
FS.createDevice('/dev', 'stderr', null, error);
|
|
} else {
|
|
FS.symlink('/dev/tty1', '/dev/stderr');
|
|
}
|
|
var stdin = FS.open('/dev/stdin', 0);
|
|
var stdout = FS.open('/dev/stdout', 1);
|
|
var stderr = FS.open('/dev/stderr', 1);
|
|
},
|
|
staticInit() {
|
|
FS.nameTable = new Array(4096);
|
|
FS.mount(MEMFS, {}, '/');
|
|
FS.createDefaultDirectories();
|
|
FS.createDefaultDevices();
|
|
FS.createSpecialDirectories();
|
|
FS.filesystems = { MEMFS, PROXYFS };
|
|
},
|
|
init(input, output, error) {
|
|
FS.initialized = true;
|
|
input ??= Module['stdin'];
|
|
output ??= Module['stdout'];
|
|
error ??= Module['stderr'];
|
|
FS.createStandardStreams(input, output, error);
|
|
},
|
|
quit() {
|
|
FS.initialized = false;
|
|
_fflush(0);
|
|
for (var stream of FS.streams) {
|
|
if (stream) {
|
|
FS.close(stream);
|
|
}
|
|
}
|
|
},
|
|
findObject(path, dontResolveLastLink) {
|
|
var ret = FS.analyzePath(path, dontResolveLastLink);
|
|
if (!ret.exists) {
|
|
return null;
|
|
}
|
|
return ret.object;
|
|
},
|
|
analyzePath(path, dontResolveLastLink) {
|
|
try {
|
|
var lookup = FS.lookupPath(path, {
|
|
follow: !dontResolveLastLink,
|
|
});
|
|
path = lookup.path;
|
|
} catch (e) {}
|
|
var ret = {
|
|
isRoot: false,
|
|
exists: false,
|
|
error: 0,
|
|
name: null,
|
|
path: null,
|
|
object: null,
|
|
parentExists: false,
|
|
parentPath: null,
|
|
parentObject: null,
|
|
};
|
|
try {
|
|
var lookup = FS.lookupPath(path, { parent: true });
|
|
ret.parentExists = true;
|
|
ret.parentPath = lookup.path;
|
|
ret.parentObject = lookup.node;
|
|
ret.name = PATH.basename(path);
|
|
lookup = FS.lookupPath(path, { follow: !dontResolveLastLink });
|
|
ret.exists = true;
|
|
ret.path = lookup.path;
|
|
ret.object = lookup.node;
|
|
ret.name = lookup.node.name;
|
|
ret.isRoot = lookup.path === '/';
|
|
} catch (e) {
|
|
ret.error = e.errno;
|
|
}
|
|
return ret;
|
|
},
|
|
createPath(parent, path, canRead, canWrite) {
|
|
parent = typeof parent == 'string' ? parent : FS.getPath(parent);
|
|
var parts = path.split('/').reverse();
|
|
while (parts.length) {
|
|
var part = parts.pop();
|
|
if (!part) continue;
|
|
var current = PATH.join2(parent, part);
|
|
try {
|
|
FS.mkdir(current);
|
|
} catch (e) {
|
|
if (e.errno != 20) throw e;
|
|
}
|
|
parent = current;
|
|
}
|
|
return current;
|
|
},
|
|
createFile(parent, name, properties, canRead, canWrite) {
|
|
var path = PATH.join2(
|
|
typeof parent == 'string' ? parent : FS.getPath(parent),
|
|
name
|
|
);
|
|
var mode = FS_getMode(canRead, canWrite);
|
|
return FS.create(path, mode);
|
|
},
|
|
createDataFile(parent, name, data, canRead, canWrite, canOwn) {
|
|
var path = name;
|
|
if (parent) {
|
|
parent =
|
|
typeof parent == 'string' ? parent : FS.getPath(parent);
|
|
path = name ? PATH.join2(parent, name) : parent;
|
|
}
|
|
var mode = FS_getMode(canRead, canWrite);
|
|
var node = FS.create(path, mode);
|
|
if (data) {
|
|
if (typeof data == 'string') {
|
|
var arr = new Array(data.length);
|
|
for (var i = 0, len = data.length; i < len; ++i)
|
|
arr[i] = data.charCodeAt(i);
|
|
data = arr;
|
|
}
|
|
FS.chmod(node, mode | 146);
|
|
var stream = FS.open(node, 577);
|
|
FS.write(stream, data, 0, data.length, 0, canOwn);
|
|
FS.close(stream);
|
|
FS.chmod(node, mode);
|
|
}
|
|
},
|
|
createDevice(parent, name, input, output) {
|
|
var path = PATH.join2(
|
|
typeof parent == 'string' ? parent : FS.getPath(parent),
|
|
name
|
|
);
|
|
var mode = FS_getMode(!!input, !!output);
|
|
FS.createDevice.major ??= 64;
|
|
var dev = FS.makedev(FS.createDevice.major++, 0);
|
|
FS.registerDevice(dev, {
|
|
open(stream) {
|
|
stream.seekable = false;
|
|
},
|
|
close(stream) {
|
|
if (output?.buffer?.length) {
|
|
output(10);
|
|
}
|
|
},
|
|
read(stream, buffer, offset, length, pos) {
|
|
var bytesRead = 0;
|
|
for (var i = 0; i < length; i++) {
|
|
var result;
|
|
try {
|
|
result = input();
|
|
} catch (e) {
|
|
throw new FS.ErrnoError(29);
|
|
}
|
|
if (result === undefined && bytesRead === 0) {
|
|
throw new FS.ErrnoError(6);
|
|
}
|
|
if (result === null || result === undefined) break;
|
|
bytesRead++;
|
|
buffer[offset + i] = result;
|
|
}
|
|
if (bytesRead) {
|
|
stream.node.atime = Date.now();
|
|
}
|
|
return bytesRead;
|
|
},
|
|
write(stream, buffer, offset, length, pos) {
|
|
for (var i = 0; i < length; i++) {
|
|
try {
|
|
output(buffer[offset + i]);
|
|
} catch (e) {
|
|
throw new FS.ErrnoError(29);
|
|
}
|
|
}
|
|
if (length) {
|
|
stream.node.mtime = stream.node.ctime = Date.now();
|
|
}
|
|
return i;
|
|
},
|
|
});
|
|
return FS.mkdev(path, mode, dev);
|
|
},
|
|
forceLoadFile(obj) {
|
|
if (obj.isDevice || obj.isFolder || obj.link || obj.contents)
|
|
return true;
|
|
if (globalThis.XMLHttpRequest) {
|
|
abort(
|
|
'Lazy loading should have been performed (contents set) in createLazyFile, but it was not. Lazy loading only works in web workers. Use --embed-file or --preload-file in emcc on the main thread.'
|
|
);
|
|
} else {
|
|
try {
|
|
obj.contents = readBinary(obj.url);
|
|
} catch (e) {
|
|
throw new FS.ErrnoError(29);
|
|
}
|
|
}
|
|
},
|
|
createLazyFile(parent, name, url, canRead, canWrite) {
|
|
class LazyUint8Array {
|
|
lengthKnown = false;
|
|
chunks = [];
|
|
get(idx) {
|
|
if (idx > this.length - 1 || idx < 0) {
|
|
return undefined;
|
|
}
|
|
var chunkOffset = idx % this.chunkSize;
|
|
var chunkNum = (idx / this.chunkSize) | 0;
|
|
return this.getter(chunkNum)[chunkOffset];
|
|
}
|
|
setDataGetter(getter) {
|
|
this.getter = getter;
|
|
}
|
|
cacheLength() {
|
|
var xhr = new XMLHttpRequest();
|
|
xhr.open('HEAD', url, false);
|
|
xhr.send(null);
|
|
if (
|
|
!(
|
|
(xhr.status >= 200 && xhr.status < 300) ||
|
|
xhr.status === 304
|
|
)
|
|
)
|
|
abort(
|
|
"Couldn't load " + url + '. Status: ' + xhr.status
|
|
);
|
|
var datalength = Number(
|
|
xhr.getResponseHeader('Content-length')
|
|
);
|
|
var header;
|
|
var hasByteServing =
|
|
(header = xhr.getResponseHeader('Accept-Ranges')) &&
|
|
header === 'bytes';
|
|
var usesGzip =
|
|
(header = xhr.getResponseHeader('Content-Encoding')) &&
|
|
header === 'gzip';
|
|
var chunkSize = 1024 * 1024;
|
|
if (!hasByteServing) chunkSize = datalength;
|
|
var doXHR = (from, to) => {
|
|
if (from > to)
|
|
abort(
|
|
'invalid range (' +
|
|
from +
|
|
', ' +
|
|
to +
|
|
') or no bytes requested!'
|
|
);
|
|
if (to > datalength - 1)
|
|
abort(
|
|
'only ' +
|
|
datalength +
|
|
' bytes available! programmer error!'
|
|
);
|
|
var xhr = new XMLHttpRequest();
|
|
xhr.open('GET', url, false);
|
|
if (datalength !== chunkSize)
|
|
xhr.setRequestHeader(
|
|
'Range',
|
|
'bytes=' + from + '-' + to
|
|
);
|
|
xhr.responseType = 'arraybuffer';
|
|
if (xhr.overrideMimeType) {
|
|
xhr.overrideMimeType(
|
|
'text/plain; charset=x-user-defined'
|
|
);
|
|
}
|
|
xhr.send(null);
|
|
if (
|
|
!(
|
|
(xhr.status >= 200 && xhr.status < 300) ||
|
|
xhr.status === 304
|
|
)
|
|
)
|
|
abort(
|
|
"Couldn't load " +
|
|
url +
|
|
'. Status: ' +
|
|
xhr.status
|
|
);
|
|
if (xhr.response !== undefined) {
|
|
return new Uint8Array(xhr.response || []);
|
|
}
|
|
return intArrayFromString(xhr.responseText || '', true);
|
|
};
|
|
var lazyArray = this;
|
|
lazyArray.setDataGetter((chunkNum) => {
|
|
var start = chunkNum * chunkSize;
|
|
var end = (chunkNum + 1) * chunkSize - 1;
|
|
end = Math.min(end, datalength - 1);
|
|
if (typeof lazyArray.chunks[chunkNum] == 'undefined') {
|
|
lazyArray.chunks[chunkNum] = doXHR(start, end);
|
|
}
|
|
if (typeof lazyArray.chunks[chunkNum] == 'undefined')
|
|
abort('doXHR failed!');
|
|
return lazyArray.chunks[chunkNum];
|
|
});
|
|
if (usesGzip || !datalength) {
|
|
chunkSize = datalength = 1;
|
|
datalength = this.getter(0).length;
|
|
chunkSize = datalength;
|
|
out(
|
|
'LazyFiles on gzip forces download of the whole file when length is accessed'
|
|
);
|
|
}
|
|
this._length = datalength;
|
|
this._chunkSize = chunkSize;
|
|
this.lengthKnown = true;
|
|
}
|
|
get length() {
|
|
if (!this.lengthKnown) {
|
|
this.cacheLength();
|
|
}
|
|
return this._length;
|
|
}
|
|
get chunkSize() {
|
|
if (!this.lengthKnown) {
|
|
this.cacheLength();
|
|
}
|
|
return this._chunkSize;
|
|
}
|
|
}
|
|
if (globalThis.XMLHttpRequest) {
|
|
if (!ENVIRONMENT_IS_WORKER)
|
|
abort(
|
|
'Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc'
|
|
);
|
|
var lazyArray = new LazyUint8Array();
|
|
var properties = { isDevice: false, contents: lazyArray };
|
|
} else {
|
|
var properties = { isDevice: false, url };
|
|
}
|
|
var node = FS.createFile(
|
|
parent,
|
|
name,
|
|
properties,
|
|
canRead,
|
|
canWrite
|
|
);
|
|
if (properties.contents) {
|
|
node.contents = properties.contents;
|
|
} else if (properties.url) {
|
|
node.contents = null;
|
|
node.url = properties.url;
|
|
}
|
|
Object.defineProperties(node, {
|
|
usedBytes: {
|
|
get: function () {
|
|
return this.contents.length;
|
|
},
|
|
},
|
|
});
|
|
var stream_ops = {};
|
|
for (const [key, fn] of Object.entries(node.stream_ops)) {
|
|
stream_ops[key] = (...args) => {
|
|
FS.forceLoadFile(node);
|
|
return fn(...args);
|
|
};
|
|
}
|
|
function writeChunks(stream, buffer, offset, length, position) {
|
|
var contents = stream.node.contents;
|
|
if (position >= contents.length) return 0;
|
|
var size = Math.min(contents.length - position, length);
|
|
if (contents.slice) {
|
|
for (var i = 0; i < size; i++) {
|
|
buffer[offset + i] = contents[position + i];
|
|
}
|
|
} else {
|
|
for (var i = 0; i < size; i++) {
|
|
buffer[offset + i] = contents.get(position + i);
|
|
}
|
|
}
|
|
return size;
|
|
}
|
|
stream_ops.read = (stream, buffer, offset, length, position) => {
|
|
FS.forceLoadFile(node);
|
|
return writeChunks(stream, buffer, offset, length, position);
|
|
};
|
|
stream_ops.mmap = (stream, length, position, prot, flags) => {
|
|
FS.forceLoadFile(node);
|
|
var ptr = mmapAlloc(length);
|
|
if (!ptr) {
|
|
throw new FS.ErrnoError(48);
|
|
}
|
|
writeChunks(stream, HEAP8, ptr, length, position);
|
|
return { ptr, allocated: true };
|
|
};
|
|
node.stream_ops = stream_ops;
|
|
return node;
|
|
},
|
|
};
|
|
var findLibraryFS = (libName, rpath) => {
|
|
if (!runtimeInitialized) {
|
|
return undefined;
|
|
}
|
|
if (PATH.isAbs(libName)) {
|
|
try {
|
|
FS.lookupPath(libName);
|
|
return libName;
|
|
} catch (e) {
|
|
return undefined;
|
|
}
|
|
}
|
|
var rpathResolved = (rpath?.paths || []).map((p) =>
|
|
replaceORIGIN(rpath?.parentLibPath, p)
|
|
);
|
|
return withStackSave(() => {
|
|
var bufSize = 2 * 255 + 2;
|
|
var buf = stackAlloc(bufSize);
|
|
var rpathC = stringToUTF8OnStack(rpathResolved.join(':'));
|
|
var libNameC = stringToUTF8OnStack(libName);
|
|
var resLibNameC = __emscripten_find_dylib(
|
|
buf,
|
|
rpathC,
|
|
libNameC,
|
|
bufSize
|
|
);
|
|
return resLibNameC ? UTF8ToString(resLibNameC) : undefined;
|
|
});
|
|
};
|
|
var registerDynCallSymbols = (exports) => {
|
|
for (var [sym, exp] of Object.entries(exports)) {
|
|
if (sym.startsWith('dynCall_')) {
|
|
var sig = sym.substring(8);
|
|
if (!dynCalls.hasOwnProperty(sig)) {
|
|
dynCalls[sig] = exp;
|
|
}
|
|
}
|
|
}
|
|
};
|
|
function loadDynamicLibrary(
|
|
libName,
|
|
flags = { global: true, nodelete: true },
|
|
localScope,
|
|
handle
|
|
) {
|
|
var dso = LDSO.loadedLibsByName[libName];
|
|
if (dso) {
|
|
if (!flags.global) {
|
|
if (localScope) {
|
|
Object.assign(localScope, dso.exports);
|
|
}
|
|
registerDynCallSymbols(dso.exports);
|
|
} else if (!dso.global) {
|
|
dso.global = true;
|
|
mergeLibSymbols(dso.exports, libName);
|
|
}
|
|
if (flags.nodelete && dso.refcount !== Infinity) {
|
|
dso.refcount = Infinity;
|
|
}
|
|
dso.refcount++;
|
|
if (handle) {
|
|
LDSO.loadedLibsByHandle[handle] = dso;
|
|
}
|
|
return flags.loadAsync ? Promise.resolve(true) : true;
|
|
}
|
|
dso = newDSO(libName, handle, 'loading');
|
|
dso.refcount = flags.nodelete ? Infinity : 1;
|
|
dso.global = flags.global;
|
|
function loadLibData() {
|
|
if (handle) {
|
|
var data = HEAPU32[(handle + 28) >> 2];
|
|
var dataSize = HEAPU32[(handle + 32) >> 2];
|
|
if (data && dataSize) {
|
|
var libData = HEAP8.slice(data, data + dataSize);
|
|
return flags.loadAsync ? Promise.resolve(libData) : libData;
|
|
}
|
|
}
|
|
var f = findLibraryFS(libName, flags.rpath);
|
|
if (f) {
|
|
var libData = FS.readFile(f, { encoding: 'binary' });
|
|
return flags.loadAsync ? Promise.resolve(libData) : libData;
|
|
}
|
|
var libFile = locateFile(libName);
|
|
if (flags.loadAsync) {
|
|
return asyncLoad(libFile);
|
|
}
|
|
if (!readBinary) {
|
|
throw new Error(
|
|
`${libFile}: file not found, and synchronous loading of external files is not available`
|
|
);
|
|
}
|
|
return readBinary(libFile);
|
|
}
|
|
function getExports() {
|
|
var preloaded = preloadedWasm[libName];
|
|
if (preloaded) {
|
|
return flags.loadAsync ? Promise.resolve(preloaded) : preloaded;
|
|
}
|
|
if (flags.loadAsync) {
|
|
return loadLibData().then((libData) =>
|
|
loadWebAssemblyModule(
|
|
libData,
|
|
flags,
|
|
libName,
|
|
localScope,
|
|
handle
|
|
)
|
|
);
|
|
}
|
|
return loadWebAssemblyModule(
|
|
loadLibData(),
|
|
flags,
|
|
libName,
|
|
localScope,
|
|
handle
|
|
);
|
|
}
|
|
function moduleLoaded(exports) {
|
|
if (dso.global) {
|
|
mergeLibSymbols(exports, libName);
|
|
} else if (localScope) {
|
|
Object.assign(localScope, exports);
|
|
registerDynCallSymbols(exports);
|
|
}
|
|
dso.exports = exports;
|
|
}
|
|
if (flags.loadAsync) {
|
|
return getExports().then((exports) => {
|
|
moduleLoaded(exports);
|
|
return true;
|
|
});
|
|
}
|
|
moduleLoaded(getExports());
|
|
return true;
|
|
}
|
|
var reportUndefinedSymbols = () => {
|
|
for (var [symName, entry] of Object.entries(GOT)) {
|
|
if (entry.value == -1) {
|
|
var value = resolveGlobalSymbol(symName, true).sym;
|
|
if (!value && !entry.required) {
|
|
entry.value = 0;
|
|
continue;
|
|
}
|
|
if (typeof value == 'function') {
|
|
entry.value = addFunction(value, value.sig);
|
|
} else if (typeof value == 'number') {
|
|
entry.value = value;
|
|
} else {
|
|
throw new Error(
|
|
`bad export type for '${symName}': ${typeof value} (${value})`
|
|
);
|
|
}
|
|
}
|
|
}
|
|
};
|
|
var loadDylibs = async () => {
|
|
if (!dynamicLibraries.length) {
|
|
reportUndefinedSymbols();
|
|
return;
|
|
}
|
|
addRunDependency('loadDylibs');
|
|
for (var lib of dynamicLibraries) {
|
|
await loadDynamicLibrary(lib, {
|
|
loadAsync: true,
|
|
global: true,
|
|
nodelete: true,
|
|
allowUndefined: true,
|
|
});
|
|
}
|
|
reportUndefinedSymbols();
|
|
removeRunDependency('loadDylibs');
|
|
};
|
|
var noExitRuntime = false;
|
|
var ___assert_fail = (condition, filename, line, func) =>
|
|
abort(
|
|
`Assertion failed: ${UTF8ToString(condition)}, at: ` +
|
|
[
|
|
filename ? UTF8ToString(filename) : 'unknown filename',
|
|
line,
|
|
func ? UTF8ToString(func) : 'unknown function',
|
|
]
|
|
);
|
|
___assert_fail.sig = 'vppip';
|
|
var ___asyncify_data = new WebAssembly.Global(
|
|
{ value: 'i32', mutable: true },
|
|
0
|
|
);
|
|
var ___asyncify_state = new WebAssembly.Global(
|
|
{ value: 'i32', mutable: true },
|
|
0
|
|
);
|
|
var ___call_sighandler = (fp, sig) => ((a1) => dynCall_vi(fp, a1))(sig);
|
|
___call_sighandler.sig = 'vpi';
|
|
var SOCKFS = {
|
|
websocketArgs: {},
|
|
callbacks: {},
|
|
on(event, callback) {
|
|
SOCKFS.callbacks[event] = callback;
|
|
},
|
|
emit(event, param) {
|
|
SOCKFS.callbacks[event]?.(param);
|
|
},
|
|
mount(mount) {
|
|
SOCKFS.websocketArgs = Module['websocket'] || {};
|
|
(Module['websocket'] ??= {})['on'] = SOCKFS.on;
|
|
return FS.createNode(null, '/', 16895, 0);
|
|
},
|
|
createSocket(family, type, protocol) {
|
|
if (family != 2) {
|
|
throw new FS.ErrnoError(5);
|
|
}
|
|
type &= ~526336;
|
|
if (type != 1 && type != 2) {
|
|
throw new FS.ErrnoError(28);
|
|
}
|
|
var streaming = type == 1;
|
|
if (streaming && protocol && protocol != 6) {
|
|
throw new FS.ErrnoError(66);
|
|
}
|
|
var sock = {
|
|
family,
|
|
type,
|
|
protocol,
|
|
server: null,
|
|
error: null,
|
|
peers: {},
|
|
pending: [],
|
|
recv_queue: [],
|
|
sock_ops: SOCKFS.websocket_sock_ops,
|
|
};
|
|
var name = SOCKFS.nextname();
|
|
var node = FS.createNode(SOCKFS.root, name, 49152, 0);
|
|
node.sock = sock;
|
|
var stream = FS.createStream({
|
|
path: name,
|
|
node,
|
|
flags: 2,
|
|
seekable: false,
|
|
stream_ops: SOCKFS.stream_ops,
|
|
});
|
|
sock.stream = stream;
|
|
return sock;
|
|
},
|
|
getSocket(fd) {
|
|
var stream = FS.getStream(fd);
|
|
if (!stream || !FS.isSocket(stream.node.mode)) {
|
|
return null;
|
|
}
|
|
return stream.node.sock;
|
|
},
|
|
stream_ops: {
|
|
poll(stream) {
|
|
var sock = stream.node.sock;
|
|
return sock.sock_ops.poll(sock);
|
|
},
|
|
ioctl(stream, request, varargs) {
|
|
var sock = stream.node.sock;
|
|
return sock.sock_ops.ioctl(sock, request, varargs);
|
|
},
|
|
read(stream, buffer, offset, length, position) {
|
|
var sock = stream.node.sock;
|
|
var msg = sock.sock_ops.recvmsg(sock, length);
|
|
if (!msg) {
|
|
return 0;
|
|
}
|
|
buffer.set(msg.buffer, offset);
|
|
return msg.buffer.length;
|
|
},
|
|
write(stream, buffer, offset, length, position) {
|
|
var sock = stream.node.sock;
|
|
return sock.sock_ops.sendmsg(sock, buffer, offset, length);
|
|
},
|
|
close(stream) {
|
|
var sock = stream.node.sock;
|
|
sock.sock_ops.close(sock);
|
|
},
|
|
},
|
|
nextname() {
|
|
if (!SOCKFS.nextname.current) {
|
|
SOCKFS.nextname.current = 0;
|
|
}
|
|
return `socket[${SOCKFS.nextname.current++}]`;
|
|
},
|
|
websocket_sock_ops: {
|
|
createPeer(sock, addr, port) {
|
|
var ws;
|
|
if (typeof addr == 'object') {
|
|
ws = addr;
|
|
addr = null;
|
|
port = null;
|
|
}
|
|
if (ws) {
|
|
if (ws._socket) {
|
|
addr = ws._socket.remoteAddress;
|
|
port = ws._socket.remotePort;
|
|
} else {
|
|
var result = /ws[s]?:\/\/([^:]+):(\d+)/.exec(ws.url);
|
|
if (!result) {
|
|
throw new Error(
|
|
'WebSocket URL must be in the format ws(s)://address:port'
|
|
);
|
|
}
|
|
addr = result[1];
|
|
port = parseInt(result[2], 10);
|
|
}
|
|
} else {
|
|
try {
|
|
var url = 'ws://'.replace('#', '//');
|
|
var subProtocols = 'binary';
|
|
var opts = undefined;
|
|
if ('function' === typeof SOCKFS.websocketArgs['url']) {
|
|
url = SOCKFS.websocketArgs['url'](...arguments);
|
|
} else if (
|
|
'string' === typeof SOCKFS.websocketArgs['url']
|
|
) {
|
|
url = SOCKFS.websocketArgs['url'];
|
|
}
|
|
if (SOCKFS.websocketArgs['subprotocol']) {
|
|
subProtocols = SOCKFS.websocketArgs['subprotocol'];
|
|
} else if (
|
|
SOCKFS.websocketArgs['subprotocol'] === null
|
|
) {
|
|
subProtocols = 'null';
|
|
}
|
|
if (url === 'ws://' || url === 'wss://') {
|
|
var parts = addr.split('/');
|
|
url =
|
|
url +
|
|
parts[0] +
|
|
':' +
|
|
port +
|
|
'/' +
|
|
parts.slice(1).join('/');
|
|
}
|
|
if (subProtocols !== 'null') {
|
|
subProtocols = subProtocols
|
|
.replace(/^ +| +$/g, '')
|
|
.split(/ *, */);
|
|
opts = subProtocols;
|
|
}
|
|
var WebSocketConstructor;
|
|
{
|
|
WebSocketConstructor = WebSocket;
|
|
}
|
|
if (Module['websocket']['decorator']) {
|
|
WebSocketConstructor =
|
|
Module['websocket']['decorator'](
|
|
WebSocketConstructor
|
|
);
|
|
}
|
|
ws = new WebSocketConstructor(url, opts);
|
|
ws.binaryType = 'arraybuffer';
|
|
} catch (e) {
|
|
throw new FS.ErrnoError(23);
|
|
}
|
|
}
|
|
var peer = { addr, port, socket: ws, msg_send_queue: [] };
|
|
SOCKFS.websocket_sock_ops.addPeer(sock, peer);
|
|
SOCKFS.websocket_sock_ops.handlePeerEvents(sock, peer);
|
|
if (sock.type === 2 && typeof sock.sport != 'undefined') {
|
|
peer.msg_send_queue.push(
|
|
new Uint8Array([
|
|
255,
|
|
255,
|
|
255,
|
|
255,
|
|
'p'.charCodeAt(0),
|
|
'o'.charCodeAt(0),
|
|
'r'.charCodeAt(0),
|
|
't'.charCodeAt(0),
|
|
(sock.sport & 65280) >> 8,
|
|
sock.sport & 255,
|
|
])
|
|
);
|
|
}
|
|
return peer;
|
|
},
|
|
getPeer(sock, addr, port) {
|
|
return sock.peers[addr + ':' + port];
|
|
},
|
|
addPeer(sock, peer) {
|
|
sock.peers[peer.addr + ':' + peer.port] = peer;
|
|
},
|
|
removePeer(sock, peer) {
|
|
delete sock.peers[peer.addr + ':' + peer.port];
|
|
},
|
|
handlePeerEvents(sock, peer) {
|
|
var first = true;
|
|
var handleOpen = function () {
|
|
sock.connecting = false;
|
|
SOCKFS.emit('open', sock.stream.fd);
|
|
try {
|
|
var queued = peer.msg_send_queue.shift();
|
|
while (queued) {
|
|
peer.socket.send(queued);
|
|
queued = peer.msg_send_queue.shift();
|
|
}
|
|
} catch (e) {
|
|
peer.socket.close();
|
|
}
|
|
};
|
|
function handleMessage(data) {
|
|
if (typeof data == 'string') {
|
|
var encoder = new TextEncoder();
|
|
data = encoder.encode(data);
|
|
} else {
|
|
if (data.byteLength == 0) {
|
|
return;
|
|
}
|
|
data = new Uint8Array(data);
|
|
}
|
|
var wasfirst = first;
|
|
first = false;
|
|
if (
|
|
wasfirst &&
|
|
data.length === 10 &&
|
|
data[0] === 255 &&
|
|
data[1] === 255 &&
|
|
data[2] === 255 &&
|
|
data[3] === 255 &&
|
|
data[4] === 'p'.charCodeAt(0) &&
|
|
data[5] === 'o'.charCodeAt(0) &&
|
|
data[6] === 'r'.charCodeAt(0) &&
|
|
data[7] === 't'.charCodeAt(0)
|
|
) {
|
|
var newport = (data[8] << 8) | data[9];
|
|
SOCKFS.websocket_sock_ops.removePeer(sock, peer);
|
|
peer.port = newport;
|
|
SOCKFS.websocket_sock_ops.addPeer(sock, peer);
|
|
return;
|
|
}
|
|
sock.recv_queue.push({
|
|
addr: peer.addr,
|
|
port: peer.port,
|
|
data,
|
|
});
|
|
SOCKFS.emit('message', sock.stream.fd);
|
|
}
|
|
if (ENVIRONMENT_IS_NODE) {
|
|
peer.socket.on('open', handleOpen);
|
|
peer.socket.on('message', function (data, isBinary) {
|
|
if (!isBinary) {
|
|
return;
|
|
}
|
|
handleMessage(new Uint8Array(data).buffer);
|
|
});
|
|
peer.socket.on('close', function () {
|
|
SOCKFS.emit('close', sock.stream.fd);
|
|
});
|
|
peer.socket.on('error', function (error) {
|
|
sock.error = 14;
|
|
SOCKFS.emit('error', [
|
|
sock.stream.fd,
|
|
sock.error,
|
|
'ECONNREFUSED: Connection refused',
|
|
]);
|
|
});
|
|
} else {
|
|
peer.socket.onopen = handleOpen;
|
|
peer.socket.onclose = function () {
|
|
SOCKFS.emit('close', sock.stream.fd);
|
|
};
|
|
peer.socket.onmessage = function peer_socket_onmessage(
|
|
event
|
|
) {
|
|
handleMessage(event.data);
|
|
};
|
|
peer.socket.onerror = function (error) {
|
|
sock.error = 14;
|
|
SOCKFS.emit('error', [
|
|
sock.stream.fd,
|
|
sock.error,
|
|
'ECONNREFUSED: Connection refused',
|
|
]);
|
|
};
|
|
}
|
|
},
|
|
poll(sock) {
|
|
if (sock.type === 1 && sock.server) {
|
|
return sock.pending.length ? 64 | 1 : 0;
|
|
}
|
|
var mask = 0;
|
|
var dest =
|
|
sock.type === 1
|
|
? SOCKFS.websocket_sock_ops.getPeer(
|
|
sock,
|
|
sock.daddr,
|
|
sock.dport
|
|
)
|
|
: null;
|
|
if (
|
|
sock.recv_queue.length ||
|
|
!dest ||
|
|
(dest && dest.socket.readyState === dest.socket.CLOSING) ||
|
|
(dest && dest.socket.readyState === dest.socket.CLOSED)
|
|
) {
|
|
mask |= 64 | 1;
|
|
}
|
|
if (
|
|
!dest ||
|
|
(dest && dest.socket.readyState === dest.socket.OPEN)
|
|
) {
|
|
mask |= 4;
|
|
}
|
|
if (
|
|
(dest && dest.socket.readyState === dest.socket.CLOSING) ||
|
|
(dest && dest.socket.readyState === dest.socket.CLOSED)
|
|
) {
|
|
if (sock.connecting) {
|
|
mask |= 4;
|
|
} else {
|
|
mask |= 16;
|
|
}
|
|
}
|
|
return mask;
|
|
},
|
|
ioctl(sock, request, arg) {
|
|
switch (request) {
|
|
case 21531:
|
|
var bytes = 0;
|
|
if (sock.recv_queue.length) {
|
|
bytes = sock.recv_queue[0].data.length;
|
|
}
|
|
HEAP32[arg >> 2] = bytes;
|
|
return 0;
|
|
case 21537:
|
|
var on = HEAP32[arg >> 2];
|
|
if (on) {
|
|
sock.stream.flags |= 2048;
|
|
} else {
|
|
sock.stream.flags &= ~2048;
|
|
}
|
|
return 0;
|
|
default:
|
|
return 28;
|
|
}
|
|
},
|
|
close(sock) {
|
|
if (sock.server) {
|
|
try {
|
|
sock.server.close();
|
|
} catch (e) {}
|
|
sock.server = null;
|
|
}
|
|
for (var peer of Object.values(sock.peers)) {
|
|
try {
|
|
peer.socket.close();
|
|
} catch (e) {}
|
|
SOCKFS.websocket_sock_ops.removePeer(sock, peer);
|
|
}
|
|
return 0;
|
|
},
|
|
bind(sock, addr, port) {
|
|
if (
|
|
typeof sock.saddr != 'undefined' ||
|
|
typeof sock.sport != 'undefined'
|
|
) {
|
|
throw new FS.ErrnoError(28);
|
|
}
|
|
sock.saddr = addr;
|
|
sock.sport = port;
|
|
if (sock.type === 2) {
|
|
if (sock.server) {
|
|
sock.server.close();
|
|
sock.server = null;
|
|
}
|
|
try {
|
|
sock.sock_ops.listen(sock, 0);
|
|
} catch (e) {
|
|
if (!(e.name === 'ErrnoError')) throw e;
|
|
if (e.errno !== 138) throw e;
|
|
}
|
|
}
|
|
},
|
|
connect(sock, addr, port) {
|
|
if (sock.server) {
|
|
throw new FS.ErrnoError(138);
|
|
}
|
|
if (
|
|
typeof sock.daddr != 'undefined' &&
|
|
typeof sock.dport != 'undefined'
|
|
) {
|
|
var dest = SOCKFS.websocket_sock_ops.getPeer(
|
|
sock,
|
|
sock.daddr,
|
|
sock.dport
|
|
);
|
|
if (dest) {
|
|
if (dest.socket.readyState === dest.socket.CONNECTING) {
|
|
throw new FS.ErrnoError(7);
|
|
} else {
|
|
throw new FS.ErrnoError(30);
|
|
}
|
|
}
|
|
}
|
|
var peer = SOCKFS.websocket_sock_ops.createPeer(
|
|
sock,
|
|
addr,
|
|
port
|
|
);
|
|
sock.daddr = peer.addr;
|
|
sock.dport = peer.port;
|
|
sock.connecting = true;
|
|
},
|
|
listen(sock, backlog) {
|
|
if (!ENVIRONMENT_IS_NODE) {
|
|
throw new FS.ErrnoError(138);
|
|
}
|
|
},
|
|
accept(listensock) {
|
|
if (!listensock.server || !listensock.pending.length) {
|
|
throw new FS.ErrnoError(28);
|
|
}
|
|
var newsock = listensock.pending.shift();
|
|
newsock.stream.flags = listensock.stream.flags;
|
|
return newsock;
|
|
},
|
|
getname(sock, peer) {
|
|
var addr, port;
|
|
if (peer) {
|
|
if (sock.daddr === undefined || sock.dport === undefined) {
|
|
throw new FS.ErrnoError(53);
|
|
}
|
|
addr = sock.daddr;
|
|
port = sock.dport;
|
|
} else {
|
|
addr = sock.saddr || 0;
|
|
port = sock.sport || 0;
|
|
}
|
|
return { addr, port };
|
|
},
|
|
sendmsg(sock, buffer, offset, length, addr, port) {
|
|
if (sock.type === 2) {
|
|
if (addr === undefined || port === undefined) {
|
|
addr = sock.daddr;
|
|
port = sock.dport;
|
|
}
|
|
if (addr === undefined || port === undefined) {
|
|
throw new FS.ErrnoError(17);
|
|
}
|
|
} else {
|
|
addr = sock.daddr;
|
|
port = sock.dport;
|
|
}
|
|
var dest = SOCKFS.websocket_sock_ops.getPeer(sock, addr, port);
|
|
if (sock.type === 1) {
|
|
if (
|
|
!dest ||
|
|
dest.socket.readyState === dest.socket.CLOSING ||
|
|
dest.socket.readyState === dest.socket.CLOSED
|
|
) {
|
|
throw new FS.ErrnoError(53);
|
|
}
|
|
}
|
|
if (ArrayBuffer.isView(buffer)) {
|
|
offset += buffer.byteOffset;
|
|
buffer = buffer.buffer;
|
|
}
|
|
var data = buffer.slice(offset, offset + length);
|
|
if (!dest || dest.socket.readyState !== dest.socket.OPEN) {
|
|
if (sock.type === 2) {
|
|
if (
|
|
!dest ||
|
|
dest.socket.readyState === dest.socket.CLOSING ||
|
|
dest.socket.readyState === dest.socket.CLOSED
|
|
) {
|
|
dest = SOCKFS.websocket_sock_ops.createPeer(
|
|
sock,
|
|
addr,
|
|
port
|
|
);
|
|
}
|
|
}
|
|
dest.msg_send_queue.push(data);
|
|
return length;
|
|
}
|
|
try {
|
|
dest.socket.send(data);
|
|
return length;
|
|
} catch (e) {
|
|
throw new FS.ErrnoError(28);
|
|
}
|
|
},
|
|
recvmsg(sock, length, flags) {
|
|
if (sock.type === 1 && sock.server) {
|
|
throw new FS.ErrnoError(53);
|
|
}
|
|
var queued = sock.recv_queue.shift();
|
|
if (!queued) {
|
|
if (sock.type === 1) {
|
|
var dest = SOCKFS.websocket_sock_ops.getPeer(
|
|
sock,
|
|
sock.daddr,
|
|
sock.dport
|
|
);
|
|
if (!dest) {
|
|
throw new FS.ErrnoError(53);
|
|
}
|
|
if (
|
|
dest.socket.readyState === dest.socket.CLOSING ||
|
|
dest.socket.readyState === dest.socket.CLOSED
|
|
) {
|
|
return null;
|
|
}
|
|
throw new FS.ErrnoError(6);
|
|
}
|
|
throw new FS.ErrnoError(6);
|
|
}
|
|
var queuedLength = queued.data.byteLength || queued.data.length;
|
|
var queuedOffset = queued.data.byteOffset || 0;
|
|
var queuedBuffer = queued.data.buffer || queued.data;
|
|
var bytesRead = Math.min(length, queuedLength);
|
|
var res = {
|
|
buffer: new Uint8Array(
|
|
queuedBuffer,
|
|
queuedOffset,
|
|
bytesRead
|
|
),
|
|
addr: queued.addr,
|
|
port: queued.port,
|
|
};
|
|
if (flags & 2) {
|
|
bytesRead = 0;
|
|
}
|
|
if (sock.type === 1 && bytesRead < queuedLength) {
|
|
var bytesRemaining = queuedLength - bytesRead;
|
|
queued.data = new Uint8Array(
|
|
queuedBuffer,
|
|
queuedOffset + bytesRead,
|
|
bytesRemaining
|
|
);
|
|
sock.recv_queue.unshift(queued);
|
|
}
|
|
return res;
|
|
},
|
|
},
|
|
};
|
|
var getSocketFromFD = (fd) => {
|
|
var socket = SOCKFS.getSocket(fd);
|
|
if (!socket) throw new FS.ErrnoError(8);
|
|
return socket;
|
|
};
|
|
var inetPton4 = (str) => {
|
|
var b = str.split('.');
|
|
for (var i = 0; i < 4; i++) {
|
|
var tmp = Number(b[i]);
|
|
if (isNaN(tmp)) return null;
|
|
b[i] = tmp;
|
|
}
|
|
return (b[0] | (b[1] << 8) | (b[2] << 16) | (b[3] << 24)) >>> 0;
|
|
};
|
|
var inetPton6 = (str) => {
|
|
var words;
|
|
var w, offset, z;
|
|
var valid6regx =
|
|
/^((?=.*::)(?!.*::.+::)(::)?([\dA-F]{1,4}:(:|\b)|){5}|([\dA-F]{1,4}:){6})((([\dA-F]{1,4}((?!\3)::|:\b|$))|(?!\2\3)){2}|(((2[0-4]|1\d|[1-9])?\d|25[0-5])\.?\b){4})$/i;
|
|
var parts = [];
|
|
if (!valid6regx.test(str)) {
|
|
return null;
|
|
}
|
|
if (str === '::') {
|
|
return [0, 0, 0, 0, 0, 0, 0, 0];
|
|
}
|
|
if (str.startsWith('::')) {
|
|
str = str.replace('::', 'Z:');
|
|
} else {
|
|
str = str.replace('::', ':Z:');
|
|
}
|
|
if (str.indexOf('.') > 0) {
|
|
str = str.replace(new RegExp('[.]', 'g'), ':');
|
|
words = str.split(':');
|
|
words[words.length - 4] =
|
|
Number(words[words.length - 4]) +
|
|
Number(words[words.length - 3]) * 256;
|
|
words[words.length - 3] =
|
|
Number(words[words.length - 2]) +
|
|
Number(words[words.length - 1]) * 256;
|
|
words = words.slice(0, words.length - 2);
|
|
} else {
|
|
words = str.split(':');
|
|
}
|
|
offset = 0;
|
|
z = 0;
|
|
for (w = 0; w < words.length; w++) {
|
|
if (typeof words[w] == 'string') {
|
|
if (words[w] === 'Z') {
|
|
for (z = 0; z < 8 - words.length + 1; z++) {
|
|
parts[w + z] = 0;
|
|
}
|
|
offset = z - 1;
|
|
} else {
|
|
parts[w + offset] = _htons(parseInt(words[w], 16));
|
|
}
|
|
} else {
|
|
parts[w + offset] = words[w];
|
|
}
|
|
}
|
|
return [
|
|
(parts[1] << 16) | parts[0],
|
|
(parts[3] << 16) | parts[2],
|
|
(parts[5] << 16) | parts[4],
|
|
(parts[7] << 16) | parts[6],
|
|
];
|
|
};
|
|
var writeSockaddr = (sa, family, addr, port, addrlen) => {
|
|
switch (family) {
|
|
case 2:
|
|
addr = inetPton4(addr);
|
|
zeroMemory(sa, 16);
|
|
if (addrlen) {
|
|
HEAP32[addrlen >> 2] = 16;
|
|
}
|
|
HEAP16[sa >> 1] = family;
|
|
HEAP32[(sa + 4) >> 2] = addr;
|
|
HEAP16[(sa + 2) >> 1] = _htons(port);
|
|
break;
|
|
case 10:
|
|
addr = inetPton6(addr);
|
|
zeroMemory(sa, 28);
|
|
if (addrlen) {
|
|
HEAP32[addrlen >> 2] = 28;
|
|
}
|
|
HEAP32[sa >> 2] = family;
|
|
HEAP32[(sa + 8) >> 2] = addr[0];
|
|
HEAP32[(sa + 12) >> 2] = addr[1];
|
|
HEAP32[(sa + 16) >> 2] = addr[2];
|
|
HEAP32[(sa + 20) >> 2] = addr[3];
|
|
HEAP16[(sa + 2) >> 1] = _htons(port);
|
|
break;
|
|
default:
|
|
return 5;
|
|
}
|
|
return 0;
|
|
};
|
|
var DNS = {
|
|
address_map: { id: 1, addrs: {}, names: {} },
|
|
lookup_name(name) {
|
|
var res = inetPton4(name);
|
|
if (res !== null) {
|
|
return name;
|
|
}
|
|
res = inetPton6(name);
|
|
if (res !== null) {
|
|
return name;
|
|
}
|
|
var addr;
|
|
if (DNS.address_map.addrs[name]) {
|
|
addr = DNS.address_map.addrs[name];
|
|
} else {
|
|
var id = DNS.address_map.id++;
|
|
addr = '172.29.' + (id & 255) + '.' + (id & 65280);
|
|
DNS.address_map.names[addr] = name;
|
|
DNS.address_map.addrs[name] = addr;
|
|
}
|
|
return addr;
|
|
},
|
|
lookup_addr(addr) {
|
|
if (DNS.address_map.names[addr]) {
|
|
return DNS.address_map.names[addr];
|
|
}
|
|
return null;
|
|
},
|
|
};
|
|
function ___syscall_accept4(fd, addr, addrlen, flags, d1, d2) {
|
|
try {
|
|
var sock = getSocketFromFD(fd);
|
|
var newsock = sock.sock_ops.accept(sock);
|
|
if (addr) {
|
|
var errno = writeSockaddr(
|
|
addr,
|
|
newsock.family,
|
|
DNS.lookup_name(newsock.daddr),
|
|
newsock.dport,
|
|
addrlen
|
|
);
|
|
}
|
|
return newsock.stream.fd;
|
|
} catch (e) {
|
|
if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
|
|
return -e.errno;
|
|
}
|
|
}
|
|
___syscall_accept4.sig = 'iippiii';
|
|
var inetNtop4 = (addr) =>
|
|
(addr & 255) +
|
|
'.' +
|
|
((addr >> 8) & 255) +
|
|
'.' +
|
|
((addr >> 16) & 255) +
|
|
'.' +
|
|
((addr >> 24) & 255);
|
|
var inetNtop6 = (ints) => {
|
|
var str = '';
|
|
var word = 0;
|
|
var longest = 0;
|
|
var lastzero = 0;
|
|
var zstart = 0;
|
|
var len = 0;
|
|
var i = 0;
|
|
var parts = [
|
|
ints[0] & 65535,
|
|
ints[0] >> 16,
|
|
ints[1] & 65535,
|
|
ints[1] >> 16,
|
|
ints[2] & 65535,
|
|
ints[2] >> 16,
|
|
ints[3] & 65535,
|
|
ints[3] >> 16,
|
|
];
|
|
var hasipv4 = true;
|
|
var v4part = '';
|
|
for (i = 0; i < 5; i++) {
|
|
if (parts[i] !== 0) {
|
|
hasipv4 = false;
|
|
break;
|
|
}
|
|
}
|
|
if (hasipv4) {
|
|
v4part = inetNtop4(parts[6] | (parts[7] << 16));
|
|
if (parts[5] === -1) {
|
|
str = '::ffff:';
|
|
str += v4part;
|
|
return str;
|
|
}
|
|
if (parts[5] === 0) {
|
|
str = '::';
|
|
if (v4part === '0.0.0.0') v4part = '';
|
|
if (v4part === '0.0.0.1') v4part = '1';
|
|
str += v4part;
|
|
return str;
|
|
}
|
|
}
|
|
for (word = 0; word < 8; word++) {
|
|
if (parts[word] === 0) {
|
|
if (word - lastzero > 1) {
|
|
len = 0;
|
|
}
|
|
lastzero = word;
|
|
len++;
|
|
}
|
|
if (len > longest) {
|
|
longest = len;
|
|
zstart = word - longest + 1;
|
|
}
|
|
}
|
|
for (word = 0; word < 8; word++) {
|
|
if (longest > 1) {
|
|
if (
|
|
parts[word] === 0 &&
|
|
word >= zstart &&
|
|
word < zstart + longest
|
|
) {
|
|
if (word === zstart) {
|
|
str += ':';
|
|
if (zstart === 0) str += ':';
|
|
}
|
|
continue;
|
|
}
|
|
}
|
|
str += Number(_ntohs(parts[word] & 65535)).toString(16);
|
|
str += word < 7 ? ':' : '';
|
|
}
|
|
return str;
|
|
};
|
|
var readSockaddr = (sa, salen) => {
|
|
var family = HEAP16[sa >> 1];
|
|
var port = _ntohs(HEAPU16[(sa + 2) >> 1]);
|
|
var addr;
|
|
switch (family) {
|
|
case 2:
|
|
if (salen !== 16) {
|
|
return { errno: 28 };
|
|
}
|
|
addr = HEAP32[(sa + 4) >> 2];
|
|
addr = inetNtop4(addr);
|
|
break;
|
|
case 10:
|
|
if (salen !== 28) {
|
|
return { errno: 28 };
|
|
}
|
|
addr = [
|
|
HEAP32[(sa + 8) >> 2],
|
|
HEAP32[(sa + 12) >> 2],
|
|
HEAP32[(sa + 16) >> 2],
|
|
HEAP32[(sa + 20) >> 2],
|
|
];
|
|
addr = inetNtop6(addr);
|
|
break;
|
|
default:
|
|
return { errno: 5 };
|
|
}
|
|
return { family, addr, port };
|
|
};
|
|
var getSocketAddress = (addrp, addrlen) => {
|
|
var info = readSockaddr(addrp, addrlen);
|
|
if (info.errno) throw new FS.ErrnoError(info.errno);
|
|
info.addr = DNS.lookup_addr(info.addr) || info.addr;
|
|
return info;
|
|
};
|
|
function ___syscall_bind(fd, addr, addrlen, d1, d2, d3) {
|
|
try {
|
|
var sock = getSocketFromFD(fd);
|
|
var info = getSocketAddress(addr, addrlen);
|
|
sock.sock_ops.bind(sock, info.addr, info.port);
|
|
return 0;
|
|
} catch (e) {
|
|
if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
|
|
return -e.errno;
|
|
}
|
|
}
|
|
___syscall_bind.sig = 'iippiii';
|
|
var SYSCALLS = {
|
|
DEFAULT_POLLMASK: 5,
|
|
calculateAt(dirfd, path, allowEmpty) {
|
|
if (PATH.isAbs(path)) {
|
|
return path;
|
|
}
|
|
var dir;
|
|
if (dirfd === -100) {
|
|
dir = FS.cwd();
|
|
} else {
|
|
var dirstream = SYSCALLS.getStreamFromFD(dirfd);
|
|
dir = dirstream.path;
|
|
}
|
|
if (path.length == 0) {
|
|
if (!allowEmpty) {
|
|
throw new FS.ErrnoError(44);
|
|
}
|
|
return dir;
|
|
}
|
|
return dir + '/' + path;
|
|
},
|
|
writeStat(buf, stat) {
|
|
HEAPU32[buf >> 2] = stat.dev;
|
|
HEAPU32[(buf + 4) >> 2] = stat.mode;
|
|
HEAPU32[(buf + 8) >> 2] = stat.nlink;
|
|
HEAPU32[(buf + 12) >> 2] = stat.uid;
|
|
HEAPU32[(buf + 16) >> 2] = stat.gid;
|
|
HEAPU32[(buf + 20) >> 2] = stat.rdev;
|
|
HEAP64[(buf + 24) >> 3] = BigInt(stat.size);
|
|
HEAP32[(buf + 32) >> 2] = 4096;
|
|
HEAP32[(buf + 36) >> 2] = stat.blocks;
|
|
var atime = stat.atime.getTime();
|
|
var mtime = stat.mtime.getTime();
|
|
var ctime = stat.ctime.getTime();
|
|
HEAP64[(buf + 40) >> 3] = BigInt(Math.floor(atime / 1e3));
|
|
HEAPU32[(buf + 48) >> 2] = (atime % 1e3) * 1e3 * 1e3;
|
|
HEAP64[(buf + 56) >> 3] = BigInt(Math.floor(mtime / 1e3));
|
|
HEAPU32[(buf + 64) >> 2] = (mtime % 1e3) * 1e3 * 1e3;
|
|
HEAP64[(buf + 72) >> 3] = BigInt(Math.floor(ctime / 1e3));
|
|
HEAPU32[(buf + 80) >> 2] = (ctime % 1e3) * 1e3 * 1e3;
|
|
HEAP64[(buf + 88) >> 3] = BigInt(stat.ino);
|
|
return 0;
|
|
},
|
|
writeStatFs(buf, stats) {
|
|
HEAPU32[(buf + 4) >> 2] = stats.bsize;
|
|
HEAPU32[(buf + 60) >> 2] = stats.bsize;
|
|
HEAP64[(buf + 8) >> 3] = BigInt(stats.blocks);
|
|
HEAP64[(buf + 16) >> 3] = BigInt(stats.bfree);
|
|
HEAP64[(buf + 24) >> 3] = BigInt(stats.bavail);
|
|
HEAP64[(buf + 32) >> 3] = BigInt(stats.files);
|
|
HEAP64[(buf + 40) >> 3] = BigInt(stats.ffree);
|
|
HEAPU32[(buf + 48) >> 2] = stats.fsid;
|
|
HEAPU32[(buf + 64) >> 2] = stats.flags;
|
|
HEAPU32[(buf + 56) >> 2] = stats.namelen;
|
|
},
|
|
doMsync(addr, stream, len, flags, offset) {
|
|
if (!FS.isFile(stream.node.mode)) {
|
|
throw new FS.ErrnoError(43);
|
|
}
|
|
if (flags & 2) {
|
|
return 0;
|
|
}
|
|
var buffer = HEAPU8.slice(addr, addr + len);
|
|
FS.msync(stream, buffer, offset, len, flags);
|
|
},
|
|
getStreamFromFD(fd) {
|
|
var stream = FS.getStreamChecked(fd);
|
|
return stream;
|
|
},
|
|
varargs: undefined,
|
|
getStr(ptr) {
|
|
var ret = UTF8ToString(ptr);
|
|
return ret;
|
|
},
|
|
};
|
|
function ___syscall_chdir(path) {
|
|
try {
|
|
path = SYSCALLS.getStr(path);
|
|
FS.chdir(path);
|
|
return 0;
|
|
} catch (e) {
|
|
if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
|
|
return -e.errno;
|
|
}
|
|
}
|
|
___syscall_chdir.sig = 'ip';
|
|
function ___syscall_chmod(path, mode) {
|
|
try {
|
|
path = SYSCALLS.getStr(path);
|
|
FS.chmod(path, mode);
|
|
return 0;
|
|
} catch (e) {
|
|
if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
|
|
return -e.errno;
|
|
}
|
|
}
|
|
___syscall_chmod.sig = 'ipi';
|
|
var allocateUTF8OnStack = (...args) => stringToUTF8OnStack(...args);
|
|
var onInits = [];
|
|
var addOnInit = (cb) => onInits.push(cb);
|
|
function _js_getpid() {
|
|
return PHPLoader.processId ?? 42;
|
|
}
|
|
function _js_wasm_trace(format, ...args) {
|
|
if (PHPLoader.trace instanceof Function) {
|
|
PHPLoader.trace(_js_getpid(), format, ...args);
|
|
}
|
|
}
|
|
var PHPWASM = {
|
|
O_APPEND: 1024,
|
|
O_NONBLOCK: 2048,
|
|
POLLHUP: 16,
|
|
SETFL_MASK: 3072,
|
|
socketTimeouts: new Map(),
|
|
init: function () {
|
|
if (PHPLoader.bindUserSpace) {
|
|
addOnInit(() => {
|
|
if (typeof PHPLoader.processId !== 'number') {
|
|
throw new Error(
|
|
'PHPLoader.processId must be set before init'
|
|
);
|
|
}
|
|
Module['userSpace'] = PHPLoader.bindUserSpace({
|
|
pid: PHPLoader.processId,
|
|
constants: {
|
|
F_GETFL: Number('3'),
|
|
O_ACCMODE: Number('2097155'),
|
|
O_RDONLY: Number('0'),
|
|
O_WRONLY: Number('1'),
|
|
O_APPEND: Number('1024'),
|
|
O_NONBLOCK: Number('2048'),
|
|
F_SETFL: Number('4'),
|
|
F_GETLK: Number('12'),
|
|
F_SETLK: Number('13'),
|
|
F_SETLKW: Number('14'),
|
|
SEEK_SET: Number('0'),
|
|
SEEK_CUR: Number('1'),
|
|
SEEK_END: Number('2'),
|
|
F_GETFL: Number('3'),
|
|
O_ACCMODE: Number('2097155'),
|
|
O_RDONLY: Number('0'),
|
|
O_WRONLY: Number('1'),
|
|
O_APPEND: Number('1024'),
|
|
O_NONBLOCK: Number('2048'),
|
|
F_SETFL: Number('4'),
|
|
F_GETLK: Number('12'),
|
|
F_SETLK: Number('13'),
|
|
F_SETLKW: Number('14'),
|
|
SEEK_SET: Number('0'),
|
|
SEEK_CUR: Number('1'),
|
|
SEEK_END: Number('2'),
|
|
F_RDLCK: 0,
|
|
F_WRLCK: 1,
|
|
F_UNLCK: 2,
|
|
LOCK_SH: 1,
|
|
LOCK_EX: 2,
|
|
LOCK_NB: 4,
|
|
LOCK_UN: 8,
|
|
},
|
|
errnoCodes: ERRNO_CODES,
|
|
memory: {
|
|
HEAP8: {
|
|
get(offset) {
|
|
return HEAP8[offset];
|
|
},
|
|
set(offset, value) {
|
|
HEAP8[offset] = value;
|
|
},
|
|
},
|
|
HEAPU8: {
|
|
get(offset) {
|
|
return HEAPU8[offset];
|
|
},
|
|
set(offset, value) {
|
|
HEAPU8[offset] = value;
|
|
},
|
|
},
|
|
HEAP16: {
|
|
get(offset) {
|
|
return HEAP16[offset];
|
|
},
|
|
set(offset, value) {
|
|
HEAP16[offset] = value;
|
|
},
|
|
},
|
|
HEAPU16: {
|
|
get(offset) {
|
|
return HEAPU16[offset];
|
|
},
|
|
set(offset, value) {
|
|
HEAPU16[offset] = value;
|
|
},
|
|
},
|
|
HEAP32: {
|
|
get(offset) {
|
|
return HEAP32[offset];
|
|
},
|
|
set(offset, value) {
|
|
HEAP32[offset] = value;
|
|
},
|
|
},
|
|
HEAPU32: {
|
|
get(offset) {
|
|
return HEAPU32[offset];
|
|
},
|
|
set(offset, value) {
|
|
HEAPU32[offset] = value;
|
|
},
|
|
},
|
|
HEAPF32: {
|
|
get(offset) {
|
|
return HEAPF32[offset];
|
|
},
|
|
set(offset, value) {
|
|
HEAPF32[offset] = value;
|
|
},
|
|
},
|
|
HEAP64: {
|
|
get(offset) {
|
|
return HEAP64[offset];
|
|
},
|
|
set(offset, value) {
|
|
HEAP64[offset] = value;
|
|
},
|
|
},
|
|
HEAPU64: {
|
|
get(offset) {
|
|
return HEAPU64[offset];
|
|
},
|
|
set(offset, value) {
|
|
HEAPU64[offset] = value;
|
|
},
|
|
},
|
|
HEAPF64: {
|
|
get(offset) {
|
|
return HEAPF64[offset];
|
|
},
|
|
set(offset, value) {
|
|
HEAPF64[offset] = value;
|
|
},
|
|
},
|
|
},
|
|
wasmImports: Object.assign(
|
|
{},
|
|
wasmImports,
|
|
typeof _builtin_fd_close === 'function'
|
|
? { builtin_fd_close: _builtin_fd_close }
|
|
: {},
|
|
typeof _builtin_fcntl64 === 'function'
|
|
? { builtin_fcntl64: _builtin_fcntl64 }
|
|
: {}
|
|
),
|
|
wasmExports,
|
|
syscalls: SYSCALLS,
|
|
FS,
|
|
PROXYFS,
|
|
NODEFS,
|
|
});
|
|
});
|
|
}
|
|
Module['ENV'] = Module['ENV'] || {};
|
|
Module['ENV']['PATH'] = [
|
|
Module['ENV']['PATH'],
|
|
'/internal/shared/bin',
|
|
]
|
|
.filter(Boolean)
|
|
.join(':');
|
|
FS.mkdir('/request');
|
|
FS.mkdir('/internal');
|
|
if (PHPLoader.nativeInternalDirPath) {
|
|
FS.mount(
|
|
FS.filesystems.NODEFS,
|
|
{ root: PHPLoader.nativeInternalDirPath },
|
|
'/internal'
|
|
);
|
|
}
|
|
FS.mkdirTree('/internal/shared');
|
|
FS.mkdirTree('/internal/shared/preload');
|
|
FS.mkdirTree('/internal/shared/bin');
|
|
const originalOnRuntimeInitialized = Module['onRuntimeInitialized'];
|
|
Module['onRuntimeInitialized'] = () => {
|
|
const { node: phpBinaryNode } = FS.lookupPath(
|
|
'/internal/shared/bin/php',
|
|
{ noent_okay: true }
|
|
);
|
|
if (!phpBinaryNode) {
|
|
FS.writeFile(
|
|
'/internal/shared/bin/php',
|
|
new TextEncoder().encode('#!/bin/sh\nphp "$@"')
|
|
);
|
|
FS.chmod('/internal/shared/bin/php', 493);
|
|
}
|
|
originalOnRuntimeInitialized();
|
|
};
|
|
FS.registerDevice(FS.makedev(64, 0), {
|
|
open: () => {},
|
|
close: () => {},
|
|
read: () => 0,
|
|
write: (stream, buffer, offset, length, pos) => {
|
|
const chunk = buffer.subarray(offset, offset + length);
|
|
PHPWASM.onStdout(chunk);
|
|
return length;
|
|
},
|
|
});
|
|
FS.mkdev('/request/stdout', FS.makedev(64, 0));
|
|
FS.registerDevice(FS.makedev(63, 0), {
|
|
open: () => {},
|
|
close: () => {},
|
|
read: () => 0,
|
|
write: (stream, buffer, offset, length, pos) => {
|
|
const chunk = buffer.subarray(offset, offset + length);
|
|
PHPWASM.onStderr(chunk);
|
|
return length;
|
|
},
|
|
});
|
|
FS.mkdev('/request/stderr', FS.makedev(63, 0));
|
|
FS.registerDevice(FS.makedev(62, 0), {
|
|
open: () => {},
|
|
close: () => {},
|
|
read: () => 0,
|
|
write: (stream, buffer, offset, length, pos) => {
|
|
const chunk = buffer.subarray(offset, offset + length);
|
|
PHPWASM.onHeaders(chunk);
|
|
return length;
|
|
},
|
|
});
|
|
FS.mkdev('/request/headers', FS.makedev(62, 0));
|
|
PHPWASM.EventEmitter = ENVIRONMENT_IS_NODE
|
|
? require('events').EventEmitter
|
|
: class EventEmitter {
|
|
constructor() {
|
|
this.listeners = {};
|
|
}
|
|
emit(eventName, data) {
|
|
if (this.listeners[eventName]) {
|
|
this.listeners[eventName].forEach(
|
|
(callback) => {
|
|
callback(data);
|
|
}
|
|
);
|
|
}
|
|
}
|
|
once(eventName, callback) {
|
|
const self = this;
|
|
function removedCallback() {
|
|
callback(...arguments);
|
|
self.removeListener(eventName, removedCallback);
|
|
}
|
|
this.on(eventName, removedCallback);
|
|
}
|
|
removeAllListeners(eventName) {
|
|
if (eventName) {
|
|
delete this.listeners[eventName];
|
|
} else {
|
|
this.listeners = {};
|
|
}
|
|
}
|
|
removeListener(eventName, callback) {
|
|
if (this.listeners[eventName]) {
|
|
const idx =
|
|
this.listeners[eventName].indexOf(callback);
|
|
if (idx !== -1) {
|
|
this.listeners[eventName].splice(idx, 1);
|
|
}
|
|
}
|
|
}
|
|
};
|
|
PHPWASM.processTable = {};
|
|
PHPWASM.input_devices = {};
|
|
const originalWrite = TTY.stream_ops.write;
|
|
TTY.stream_ops.write = function (stream, ...rest) {
|
|
const retval = originalWrite(stream, ...rest);
|
|
stream.tty.ops.fsync(stream.tty);
|
|
return retval;
|
|
};
|
|
const originalPutChar = TTY.stream_ops.put_char;
|
|
TTY.stream_ops.put_char = function (tty, val) {
|
|
if (val === 10) tty.output.push(val);
|
|
return originalPutChar(tty, val);
|
|
};
|
|
},
|
|
onHeaders: function (chunk) {
|
|
if (Module['onHeaders']) {
|
|
Module['onHeaders'](chunk);
|
|
return;
|
|
}
|
|
console.log('headers', { chunk });
|
|
},
|
|
onStdout: function (chunk) {
|
|
if (Module['onStdout']) {
|
|
Module['onStdout'](chunk);
|
|
return;
|
|
}
|
|
if (ENVIRONMENT_IS_NODE) {
|
|
process.stdout.write(chunk);
|
|
} else {
|
|
console.log('stdout', { chunk });
|
|
}
|
|
},
|
|
onStderr: function (chunk) {
|
|
if (Module['onStderr']) {
|
|
Module['onStderr'](chunk);
|
|
return;
|
|
}
|
|
if (ENVIRONMENT_IS_NODE) {
|
|
process.stderr.write(chunk);
|
|
} else {
|
|
console.warn('stderr', { chunk });
|
|
}
|
|
},
|
|
getAllWebSockets: function (sock) {
|
|
const webSockets = new Set();
|
|
if (sock.server) {
|
|
sock.server.clients.forEach((ws) => {
|
|
webSockets.add(ws);
|
|
});
|
|
}
|
|
for (const peer of PHPWASM.getAllPeers(sock)) {
|
|
webSockets.add(peer.socket);
|
|
}
|
|
return Array.from(webSockets);
|
|
},
|
|
getAllPeers: function (sock) {
|
|
const peers = new Set();
|
|
if (sock.server) {
|
|
sock.pending
|
|
.filter((pending) => pending.peers)
|
|
.forEach((pending) => {
|
|
for (const peer of Object.values(pending.peers)) {
|
|
peers.add(peer);
|
|
}
|
|
});
|
|
}
|
|
if (sock.peers) {
|
|
for (const peer of Object.values(sock.peers)) {
|
|
peers.add(peer);
|
|
}
|
|
}
|
|
return Array.from(peers);
|
|
},
|
|
awaitData: function (ws) {
|
|
return PHPWASM.awaitEvent(ws, 'message');
|
|
},
|
|
awaitConnection: function (ws) {
|
|
if (ws.OPEN === ws.readyState) {
|
|
return [Promise.resolve(), PHPWASM.noop];
|
|
}
|
|
return PHPWASM.awaitEvent(ws, 'open');
|
|
},
|
|
awaitClose: function (ws) {
|
|
if ([ws.CLOSING, ws.CLOSED].includes(ws.readyState)) {
|
|
return [Promise.resolve(), PHPWASM.noop];
|
|
}
|
|
return PHPWASM.awaitEvent(ws, 'close');
|
|
},
|
|
awaitError: function (ws) {
|
|
if ([ws.CLOSING, ws.CLOSED].includes(ws.readyState)) {
|
|
return [Promise.resolve(), PHPWASM.noop];
|
|
}
|
|
return PHPWASM.awaitEvent(ws, 'error');
|
|
},
|
|
awaitEvent: function (ws, event) {
|
|
let resolve;
|
|
const listener = () => {
|
|
resolve();
|
|
};
|
|
const promise = new Promise(function (_resolve) {
|
|
resolve = _resolve;
|
|
ws.once(event, listener);
|
|
});
|
|
const cancel = () => {
|
|
ws.removeListener(event, listener);
|
|
setTimeout(resolve);
|
|
};
|
|
return [promise, cancel];
|
|
},
|
|
noop: function () {},
|
|
parseSocketTimeout: function (optionValuePtr, optionLen) {
|
|
if (!optionValuePtr || optionLen < 8) {
|
|
return null;
|
|
}
|
|
let seconds;
|
|
let microseconds;
|
|
if (optionLen >= 16) {
|
|
seconds = Number(HEAP64[optionValuePtr >> 3]);
|
|
microseconds = Number(HEAP64[(optionValuePtr + 8) >> 3]);
|
|
} else {
|
|
seconds = HEAP32[optionValuePtr >> 2];
|
|
microseconds = HEAP32[(optionValuePtr + 4) >> 2];
|
|
}
|
|
if (
|
|
!Number.isFinite(seconds) ||
|
|
!Number.isFinite(microseconds) ||
|
|
seconds < 0 ||
|
|
microseconds < 0
|
|
) {
|
|
return null;
|
|
}
|
|
return seconds * 1e3 + Math.ceil(microseconds / 1e3);
|
|
},
|
|
spawnProcess: function (command, args, options) {
|
|
if (Module['spawnProcess']) {
|
|
const spawned = Module['spawnProcess'](command, args, {
|
|
...options,
|
|
shell: true,
|
|
stdio: ['pipe', 'pipe', 'pipe'],
|
|
});
|
|
if (spawned && !('then' in spawned) && 'on' in spawned) {
|
|
return spawned;
|
|
}
|
|
return Promise.resolve(spawned).then(function (spawned) {
|
|
if (!spawned || !spawned.on) {
|
|
throw new Error(
|
|
'spawnProcess() must return an EventEmitter but returned a different type.'
|
|
);
|
|
}
|
|
return spawned;
|
|
});
|
|
}
|
|
const e = new Error(
|
|
'popen(), proc_open() etc. are unsupported on this PHP instance. Call php.setSpawnHandler() ' +
|
|
'and provide a callback to handle spawning processes, or disable a popen(), proc_open() ' +
|
|
'and similar functions via php.ini.'
|
|
);
|
|
e.code = 'SPAWN_UNSUPPORTED';
|
|
throw e;
|
|
},
|
|
shutdownSocket: function (socketd, how) {
|
|
PHPWASM.socketTimeouts.delete(socketd);
|
|
const sock = getSocketFromFD(socketd);
|
|
const peer = Object.values(sock.peers)[0];
|
|
if (!peer) {
|
|
return -1;
|
|
}
|
|
try {
|
|
peer.socket.close();
|
|
SOCKFS.websocket_sock_ops.removePeer(sock, peer);
|
|
return 0;
|
|
} catch (e) {
|
|
console.log('Socket shutdown error', e);
|
|
return -1;
|
|
}
|
|
},
|
|
};
|
|
function _wasm_connect(sockfd, addr, addrlen) {
|
|
if (!('Suspending' in WebAssembly)) {
|
|
var sock = getSocketFromFD(sockfd);
|
|
var info = getSocketAddress(addr, addrlen);
|
|
sock.sock_ops.connect(sock, info.addr, info.port);
|
|
return 0;
|
|
}
|
|
return Asyncify.handleSleep((wakeUp) => {
|
|
let sock;
|
|
try {
|
|
sock = getSocketFromFD(sockfd);
|
|
} catch (e) {
|
|
wakeUp(-ERRNO_CODES.EBADF);
|
|
return;
|
|
}
|
|
if (!sock) {
|
|
wakeUp(-ERRNO_CODES.EBADF);
|
|
return;
|
|
}
|
|
let info;
|
|
try {
|
|
info = getSocketAddress(addr, addrlen);
|
|
} catch (e) {
|
|
if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) {
|
|
wakeUp(-ERRNO_CODES.EFAULT);
|
|
return;
|
|
}
|
|
wakeUp(-e.errno);
|
|
return;
|
|
}
|
|
try {
|
|
sock.sock_ops.connect(sock, info.addr, info.port);
|
|
} catch (e) {
|
|
if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) {
|
|
wakeUp(-ERRNO_CODES.ECONNREFUSED);
|
|
return;
|
|
}
|
|
wakeUp(-e.errno);
|
|
return;
|
|
}
|
|
const webSockets = PHPWASM.getAllWebSockets(sock);
|
|
if (!webSockets.length) {
|
|
wakeUp(-ERRNO_CODES.ECONNREFUSED);
|
|
return;
|
|
}
|
|
const ws = webSockets[0];
|
|
if (ws.readyState === ws.OPEN) {
|
|
wakeUp(0);
|
|
return;
|
|
}
|
|
if (ws.readyState === ws.CLOSING || ws.readyState === ws.CLOSED) {
|
|
wakeUp(-ERRNO_CODES.ECONNREFUSED);
|
|
return;
|
|
}
|
|
const sendTimeout = PHPWASM.socketTimeouts.get(sockfd)?.send;
|
|
const timeout = sendTimeout ?? 3e4;
|
|
let resolved = false;
|
|
let timeoutId;
|
|
let handleOpen;
|
|
let handleError;
|
|
let handleClose;
|
|
const peer = PHPWASM.getAllPeers(sock).find(
|
|
(candidate) => candidate.socket === ws
|
|
);
|
|
const cleanupConnectListeners = () => {
|
|
if (typeof timeoutId !== 'undefined') {
|
|
clearTimeout(timeoutId);
|
|
}
|
|
ws.removeEventListener('open', handleOpen);
|
|
ws.removeEventListener('error', handleError);
|
|
ws.removeEventListener('close', handleClose);
|
|
};
|
|
const cleanupFailedConnect = (errno) => {
|
|
try {
|
|
if (
|
|
ws.readyState !== ws.CLOSING &&
|
|
ws.readyState !== ws.CLOSED
|
|
) {
|
|
ws.close();
|
|
}
|
|
} catch (e) {}
|
|
if (peer) {
|
|
SOCKFS.websocket_sock_ops.removePeer(sock, peer);
|
|
}
|
|
sock.connecting = false;
|
|
sock.error = errno;
|
|
};
|
|
const finishConnect = (result) => {
|
|
if (!resolved) {
|
|
resolved = true;
|
|
cleanupConnectListeners();
|
|
if (result < 0) {
|
|
cleanupFailedConnect(-result);
|
|
}
|
|
wakeUp(result);
|
|
}
|
|
};
|
|
if (timeout > 0) {
|
|
timeoutId = setTimeout(() => {
|
|
finishConnect(-ERRNO_CODES.ETIMEDOUT);
|
|
}, timeout);
|
|
}
|
|
handleOpen = () => {
|
|
finishConnect(0);
|
|
};
|
|
handleError = () => {
|
|
finishConnect(-ERRNO_CODES.ECONNREFUSED);
|
|
};
|
|
handleClose = () => {
|
|
finishConnect(-ERRNO_CODES.ECONNREFUSED);
|
|
};
|
|
ws.addEventListener('open', handleOpen);
|
|
ws.addEventListener('error', handleError);
|
|
ws.addEventListener('close', handleClose);
|
|
});
|
|
}
|
|
function ___syscall_connect(sockfd, addr, addrlen, d1, d2, d3) {
|
|
return _wasm_connect(sockfd, addr, addrlen);
|
|
}
|
|
___syscall_connect.sig = 'iippiii';
|
|
function ___syscall_dup(fd) {
|
|
try {
|
|
var old = SYSCALLS.getStreamFromFD(fd);
|
|
return FS.dupStream(old).fd;
|
|
} catch (e) {
|
|
if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
|
|
return -e.errno;
|
|
}
|
|
}
|
|
___syscall_dup.sig = 'ii';
|
|
function ___syscall_dup3(fd, newfd, flags) {
|
|
try {
|
|
var old = SYSCALLS.getStreamFromFD(fd);
|
|
if (old.fd === newfd) return -28;
|
|
if (newfd < 0 || newfd >= FS.MAX_OPEN_FDS) return -8;
|
|
var existing = FS.getStream(newfd);
|
|
if (existing) FS.close(existing);
|
|
return FS.dupStream(old, newfd).fd;
|
|
} catch (e) {
|
|
if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
|
|
return -e.errno;
|
|
}
|
|
}
|
|
___syscall_dup3.sig = 'iiii';
|
|
function ___syscall_faccessat(dirfd, path, amode, flags) {
|
|
try {
|
|
path = SYSCALLS.getStr(path);
|
|
path = SYSCALLS.calculateAt(dirfd, path);
|
|
if (amode & ~7) {
|
|
return -28;
|
|
}
|
|
var lookup = FS.lookupPath(path, { follow: true });
|
|
var node = lookup.node;
|
|
if (!node) {
|
|
return -44;
|
|
}
|
|
var perms = '';
|
|
if (amode & 4) perms += 'r';
|
|
if (amode & 2) perms += 'w';
|
|
if (amode & 1) perms += 'x';
|
|
if (perms && FS.nodePermissions(node, perms)) {
|
|
return -2;
|
|
}
|
|
return 0;
|
|
} catch (e) {
|
|
if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
|
|
return -e.errno;
|
|
}
|
|
}
|
|
___syscall_faccessat.sig = 'iipii';
|
|
function ___syscall_fchmod(fd, mode) {
|
|
try {
|
|
FS.fchmod(fd, mode);
|
|
return 0;
|
|
} catch (e) {
|
|
if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
|
|
return -e.errno;
|
|
}
|
|
}
|
|
___syscall_fchmod.sig = 'iii';
|
|
function ___syscall_fchown32(fd, owner, group) {
|
|
try {
|
|
FS.fchown(fd, owner, group);
|
|
return 0;
|
|
} catch (e) {
|
|
if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
|
|
return -e.errno;
|
|
}
|
|
}
|
|
___syscall_fchown32.sig = 'iiii';
|
|
function ___syscall_fchownat(dirfd, path, owner, group, flags) {
|
|
try {
|
|
path = SYSCALLS.getStr(path);
|
|
var nofollow = flags & 256;
|
|
flags = flags & ~256;
|
|
path = SYSCALLS.calculateAt(dirfd, path);
|
|
(nofollow ? FS.lchown : FS.chown)(path, owner, group);
|
|
return 0;
|
|
} catch (e) {
|
|
if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
|
|
return -e.errno;
|
|
}
|
|
}
|
|
___syscall_fchownat.sig = 'iipiii';
|
|
var syscallGetVarargI = () => {
|
|
var ret = HEAP32[+SYSCALLS.varargs >> 2];
|
|
SYSCALLS.varargs += 4;
|
|
return ret;
|
|
};
|
|
var syscallGetVarargP = syscallGetVarargI;
|
|
function ___syscall_fcntl64(fd, cmd, varargs) {
|
|
SYSCALLS.varargs = varargs;
|
|
try {
|
|
var stream = SYSCALLS.getStreamFromFD(fd);
|
|
switch (cmd) {
|
|
case 0: {
|
|
var arg = syscallGetVarargI();
|
|
if (arg < 0) {
|
|
return -28;
|
|
}
|
|
while (FS.streams[arg]) {
|
|
arg++;
|
|
}
|
|
var newStream;
|
|
newStream = FS.dupStream(stream, arg);
|
|
return newStream.fd;
|
|
}
|
|
case 1:
|
|
case 2:
|
|
return 0;
|
|
case 3:
|
|
return stream.flags;
|
|
case 4: {
|
|
var arg = syscallGetVarargI();
|
|
stream.flags |= arg;
|
|
return 0;
|
|
}
|
|
case 12: {
|
|
var arg = syscallGetVarargP();
|
|
var offset = 0;
|
|
HEAP16[(arg + offset) >> 1] = 2;
|
|
return 0;
|
|
}
|
|
case 13:
|
|
case 14:
|
|
return 0;
|
|
}
|
|
return -28;
|
|
} catch (e) {
|
|
if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
|
|
return -e.errno;
|
|
}
|
|
}
|
|
___syscall_fcntl64.sig = 'iiip';
|
|
function ___syscall_fdatasync(fd) {
|
|
try {
|
|
var stream = SYSCALLS.getStreamFromFD(fd);
|
|
return 0;
|
|
} catch (e) {
|
|
if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
|
|
return -e.errno;
|
|
}
|
|
}
|
|
___syscall_fdatasync.sig = 'ii';
|
|
function ___syscall_fstat64(fd, buf) {
|
|
try {
|
|
return SYSCALLS.writeStat(buf, FS.fstat(fd));
|
|
} catch (e) {
|
|
if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
|
|
return -e.errno;
|
|
}
|
|
}
|
|
___syscall_fstat64.sig = 'iip';
|
|
var INT53_MAX = 9007199254740992;
|
|
var INT53_MIN = -9007199254740992;
|
|
var bigintToI53Checked = (num) =>
|
|
num < INT53_MIN || num > INT53_MAX ? NaN : Number(num);
|
|
function ___syscall_ftruncate64(fd, length) {
|
|
length = bigintToI53Checked(length);
|
|
try {
|
|
if (isNaN(length)) return -61;
|
|
FS.ftruncate(fd, length);
|
|
return 0;
|
|
} catch (e) {
|
|
if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
|
|
return -e.errno;
|
|
}
|
|
}
|
|
___syscall_ftruncate64.sig = 'iij';
|
|
function ___syscall_getcwd(buf, size) {
|
|
try {
|
|
if (size === 0) return -28;
|
|
var cwd = FS.cwd();
|
|
var cwdLengthInBytes = lengthBytesUTF8(cwd) + 1;
|
|
if (size < cwdLengthInBytes) return -68;
|
|
stringToUTF8(cwd, buf, size);
|
|
return cwdLengthInBytes;
|
|
} catch (e) {
|
|
if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
|
|
return -e.errno;
|
|
}
|
|
}
|
|
___syscall_getcwd.sig = 'ipp';
|
|
function ___syscall_getdents64(fd, dirp, count) {
|
|
try {
|
|
var stream = SYSCALLS.getStreamFromFD(fd);
|
|
stream.getdents ||= FS.readdir(stream.path);
|
|
var struct_size = 280;
|
|
var pos = 0;
|
|
var off = FS.llseek(stream, 0, 1);
|
|
var startIdx = Math.floor(off / struct_size);
|
|
var endIdx = Math.min(
|
|
stream.getdents.length,
|
|
startIdx + Math.floor(count / struct_size)
|
|
);
|
|
for (var idx = startIdx; idx < endIdx; idx++) {
|
|
var id;
|
|
var type;
|
|
var name = stream.getdents[idx];
|
|
if (name === '.') {
|
|
id = stream.node.id;
|
|
type = 4;
|
|
} else if (name === '..') {
|
|
var lookup = FS.lookupPath(stream.path, { parent: true });
|
|
id = lookup.node.id;
|
|
type = 4;
|
|
} else {
|
|
var child;
|
|
try {
|
|
child = FS.lookupNode(stream.node, name);
|
|
} catch (e) {
|
|
if (e?.errno === 28) {
|
|
continue;
|
|
}
|
|
throw e;
|
|
}
|
|
id = child.id;
|
|
type = FS.isChrdev(child.mode)
|
|
? 2
|
|
: FS.isDir(child.mode)
|
|
? 4
|
|
: FS.isLink(child.mode)
|
|
? 10
|
|
: 8;
|
|
}
|
|
HEAP64[(dirp + pos) >> 3] = BigInt(id);
|
|
HEAP64[(dirp + pos + 8) >> 3] = BigInt((idx + 1) * struct_size);
|
|
HEAP16[(dirp + pos + 16) >> 1] = 280;
|
|
HEAP8[dirp + pos + 18] = type;
|
|
stringToUTF8(name, dirp + pos + 19, 256);
|
|
pos += struct_size;
|
|
}
|
|
FS.llseek(stream, idx * struct_size, 0);
|
|
return pos;
|
|
} catch (e) {
|
|
if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
|
|
return -e.errno;
|
|
}
|
|
}
|
|
___syscall_getdents64.sig = 'iipp';
|
|
function ___syscall_getpeername(fd, addr, addrlen, d1, d2, d3) {
|
|
try {
|
|
var sock = getSocketFromFD(fd);
|
|
if (!sock.daddr) {
|
|
return -53;
|
|
}
|
|
var errno = writeSockaddr(
|
|
addr,
|
|
sock.family,
|
|
DNS.lookup_name(sock.daddr),
|
|
sock.dport,
|
|
addrlen
|
|
);
|
|
return 0;
|
|
} catch (e) {
|
|
if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
|
|
return -e.errno;
|
|
}
|
|
}
|
|
___syscall_getpeername.sig = 'iippiii';
|
|
function ___syscall_getsockname(fd, addr, addrlen, d1, d2, d3) {
|
|
try {
|
|
var sock = getSocketFromFD(fd);
|
|
var errno = writeSockaddr(
|
|
addr,
|
|
sock.family,
|
|
DNS.lookup_name(sock.saddr || '0.0.0.0'),
|
|
sock.sport,
|
|
addrlen
|
|
);
|
|
return 0;
|
|
} catch (e) {
|
|
if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
|
|
return -e.errno;
|
|
}
|
|
}
|
|
___syscall_getsockname.sig = 'iippiii';
|
|
function ___syscall_getsockopt(fd, level, optname, optval, optlen, d1) {
|
|
try {
|
|
var sock = getSocketFromFD(fd);
|
|
if (level === 1) {
|
|
if (optname === 4) {
|
|
HEAP32[optval >> 2] = sock.error;
|
|
HEAP32[optlen >> 2] = 4;
|
|
sock.error = null;
|
|
return 0;
|
|
}
|
|
}
|
|
return -50;
|
|
} catch (e) {
|
|
if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
|
|
return -e.errno;
|
|
}
|
|
}
|
|
___syscall_getsockopt.sig = 'iiiippi';
|
|
function ___syscall_ioctl(fd, op, varargs) {
|
|
SYSCALLS.varargs = varargs;
|
|
try {
|
|
var stream = SYSCALLS.getStreamFromFD(fd);
|
|
switch (op) {
|
|
case 21509: {
|
|
if (!stream.tty) return -59;
|
|
return 0;
|
|
}
|
|
case 21505: {
|
|
if (!stream.tty) return -59;
|
|
if (stream.tty.ops.ioctl_tcgets) {
|
|
var termios = stream.tty.ops.ioctl_tcgets(stream);
|
|
var argp = syscallGetVarargP();
|
|
HEAP32[argp >> 2] = termios.c_iflag || 0;
|
|
HEAP32[(argp + 4) >> 2] = termios.c_oflag || 0;
|
|
HEAP32[(argp + 8) >> 2] = termios.c_cflag || 0;
|
|
HEAP32[(argp + 12) >> 2] = termios.c_lflag || 0;
|
|
for (var i = 0; i < 32; i++) {
|
|
HEAP8[argp + i + 17] = termios.c_cc[i] || 0;
|
|
}
|
|
return 0;
|
|
}
|
|
return 0;
|
|
}
|
|
case 21510:
|
|
case 21511:
|
|
case 21512: {
|
|
if (!stream.tty) return -59;
|
|
return 0;
|
|
}
|
|
case 21506:
|
|
case 21507:
|
|
case 21508: {
|
|
if (!stream.tty) return -59;
|
|
if (stream.tty.ops.ioctl_tcsets) {
|
|
var argp = syscallGetVarargP();
|
|
var c_iflag = HEAP32[argp >> 2];
|
|
var c_oflag = HEAP32[(argp + 4) >> 2];
|
|
var c_cflag = HEAP32[(argp + 8) >> 2];
|
|
var c_lflag = HEAP32[(argp + 12) >> 2];
|
|
var c_cc = [];
|
|
for (var i = 0; i < 32; i++) {
|
|
c_cc.push(HEAP8[argp + i + 17]);
|
|
}
|
|
return stream.tty.ops.ioctl_tcsets(stream.tty, op, {
|
|
c_iflag,
|
|
c_oflag,
|
|
c_cflag,
|
|
c_lflag,
|
|
c_cc,
|
|
});
|
|
}
|
|
return 0;
|
|
}
|
|
case 21519: {
|
|
if (!stream.tty) return -59;
|
|
var argp = syscallGetVarargP();
|
|
HEAP32[argp >> 2] = 0;
|
|
return 0;
|
|
}
|
|
case 21520: {
|
|
if (!stream.tty) return -59;
|
|
return -28;
|
|
}
|
|
case 21537:
|
|
case 21531: {
|
|
var argp = syscallGetVarargP();
|
|
return FS.ioctl(stream, op, argp);
|
|
}
|
|
case 21523: {
|
|
if (!stream.tty) return -59;
|
|
if (stream.tty.ops.ioctl_tiocgwinsz) {
|
|
var winsize = stream.tty.ops.ioctl_tiocgwinsz(
|
|
stream.tty
|
|
);
|
|
var argp = syscallGetVarargP();
|
|
HEAP16[argp >> 1] = winsize[0];
|
|
HEAP16[(argp + 2) >> 1] = winsize[1];
|
|
}
|
|
return 0;
|
|
}
|
|
case 21524: {
|
|
if (!stream.tty) return -59;
|
|
return 0;
|
|
}
|
|
case 21515: {
|
|
if (!stream.tty) return -59;
|
|
return 0;
|
|
}
|
|
default:
|
|
return -28;
|
|
}
|
|
} catch (e) {
|
|
if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
|
|
return -e.errno;
|
|
}
|
|
}
|
|
___syscall_ioctl.sig = 'iiip';
|
|
function ___syscall_listen(fd, backlog) {
|
|
try {
|
|
var sock = getSocketFromFD(fd);
|
|
sock.sock_ops.listen(sock, backlog);
|
|
return 0;
|
|
} catch (e) {
|
|
if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
|
|
return -e.errno;
|
|
}
|
|
}
|
|
___syscall_listen.sig = 'iiiiiii';
|
|
function ___syscall_lstat64(path, buf) {
|
|
try {
|
|
path = SYSCALLS.getStr(path);
|
|
return SYSCALLS.writeStat(buf, FS.lstat(path));
|
|
} catch (e) {
|
|
if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
|
|
return -e.errno;
|
|
}
|
|
}
|
|
___syscall_lstat64.sig = 'ipp';
|
|
function ___syscall_mkdirat(dirfd, path, mode) {
|
|
try {
|
|
path = SYSCALLS.getStr(path);
|
|
path = SYSCALLS.calculateAt(dirfd, path);
|
|
FS.mkdir(path, mode, 0);
|
|
return 0;
|
|
} catch (e) {
|
|
if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
|
|
return -e.errno;
|
|
}
|
|
}
|
|
___syscall_mkdirat.sig = 'iipi';
|
|
function ___syscall_newfstatat(dirfd, path, buf, flags) {
|
|
try {
|
|
path = SYSCALLS.getStr(path);
|
|
var nofollow = flags & 256;
|
|
var allowEmpty = flags & 4096;
|
|
flags = flags & ~6400;
|
|
path = SYSCALLS.calculateAt(dirfd, path, allowEmpty);
|
|
return SYSCALLS.writeStat(
|
|
buf,
|
|
nofollow ? FS.lstat(path) : FS.stat(path)
|
|
);
|
|
} catch (e) {
|
|
if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
|
|
return -e.errno;
|
|
}
|
|
}
|
|
___syscall_newfstatat.sig = 'iippi';
|
|
function ___syscall_openat(dirfd, path, flags, varargs) {
|
|
SYSCALLS.varargs = varargs;
|
|
try {
|
|
path = SYSCALLS.getStr(path);
|
|
path = SYSCALLS.calculateAt(dirfd, path);
|
|
var mode = varargs ? syscallGetVarargI() : 0;
|
|
return FS.open(path, flags, mode).fd;
|
|
} catch (e) {
|
|
if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
|
|
return -e.errno;
|
|
}
|
|
}
|
|
___syscall_openat.sig = 'iipip';
|
|
var PIPEFS = {
|
|
BUCKET_BUFFER_SIZE: 8192,
|
|
mount(mount) {
|
|
return FS.createNode(null, '/', 16384 | 511, 0);
|
|
},
|
|
createPipe() {
|
|
var pipe = { buckets: [], refcnt: 2, timestamp: new Date() };
|
|
pipe.buckets.push({
|
|
buffer: new Uint8Array(PIPEFS.BUCKET_BUFFER_SIZE),
|
|
offset: 0,
|
|
roffset: 0,
|
|
});
|
|
var rName = PIPEFS.nextname();
|
|
var wName = PIPEFS.nextname();
|
|
var rNode = FS.createNode(PIPEFS.root, rName, 4096, 0);
|
|
var wNode = FS.createNode(PIPEFS.root, wName, 4096, 0);
|
|
rNode.pipe = pipe;
|
|
wNode.pipe = pipe;
|
|
var readableStream = FS.createStream({
|
|
path: rName,
|
|
node: rNode,
|
|
flags: 0,
|
|
seekable: false,
|
|
stream_ops: PIPEFS.stream_ops,
|
|
});
|
|
rNode.stream = readableStream;
|
|
var writableStream = FS.createStream({
|
|
path: wName,
|
|
node: wNode,
|
|
flags: 1,
|
|
seekable: false,
|
|
stream_ops: PIPEFS.stream_ops,
|
|
});
|
|
wNode.stream = writableStream;
|
|
return {
|
|
readable_fd: readableStream.fd,
|
|
writable_fd: writableStream.fd,
|
|
};
|
|
},
|
|
stream_ops: {
|
|
getattr(stream) {
|
|
var node = stream.node;
|
|
var timestamp = node.pipe.timestamp;
|
|
return {
|
|
dev: 14,
|
|
ino: node.id,
|
|
mode: 4480,
|
|
nlink: 1,
|
|
uid: 0,
|
|
gid: 0,
|
|
rdev: 0,
|
|
size: 0,
|
|
atime: timestamp,
|
|
mtime: timestamp,
|
|
ctime: timestamp,
|
|
blksize: 4096,
|
|
blocks: 0,
|
|
};
|
|
},
|
|
poll(stream) {
|
|
var pipe = stream.node.pipe;
|
|
if ((stream.flags & 2097155) === 1) {
|
|
return 256 | 4;
|
|
}
|
|
for (var bucket of pipe.buckets) {
|
|
if (bucket.offset - bucket.roffset > 0) {
|
|
return 64 | 1;
|
|
}
|
|
}
|
|
return 0;
|
|
},
|
|
dup(stream) {
|
|
stream.node.pipe.refcnt++;
|
|
},
|
|
ioctl(stream, request, varargs) {
|
|
return 28;
|
|
},
|
|
fsync(stream) {
|
|
return 28;
|
|
},
|
|
read(stream, buffer, offset, length, position) {
|
|
var pipe = stream.node.pipe;
|
|
var currentLength = 0;
|
|
for (var bucket of pipe.buckets) {
|
|
currentLength += bucket.offset - bucket.roffset;
|
|
}
|
|
var data = buffer.subarray(offset, offset + length);
|
|
if (length <= 0) {
|
|
return 0;
|
|
}
|
|
if (currentLength == 0) {
|
|
if (pipe.refcnt < 2) {
|
|
return 0;
|
|
}
|
|
throw new FS.ErrnoError(6);
|
|
}
|
|
var toRead = Math.min(currentLength, length);
|
|
var totalRead = toRead;
|
|
var toRemove = 0;
|
|
for (var bucket of pipe.buckets) {
|
|
var bucketSize = bucket.offset - bucket.roffset;
|
|
if (toRead <= bucketSize) {
|
|
var tmpSlice = bucket.buffer.subarray(
|
|
bucket.roffset,
|
|
bucket.offset
|
|
);
|
|
if (toRead < bucketSize) {
|
|
tmpSlice = tmpSlice.subarray(0, toRead);
|
|
bucket.roffset += toRead;
|
|
} else {
|
|
toRemove++;
|
|
}
|
|
data.set(tmpSlice);
|
|
break;
|
|
} else {
|
|
var tmpSlice = bucket.buffer.subarray(
|
|
bucket.roffset,
|
|
bucket.offset
|
|
);
|
|
data.set(tmpSlice);
|
|
data = data.subarray(tmpSlice.byteLength);
|
|
toRead -= tmpSlice.byteLength;
|
|
toRemove++;
|
|
}
|
|
}
|
|
if (toRemove && toRemove == pipe.buckets.length) {
|
|
toRemove--;
|
|
pipe.buckets[toRemove].offset = 0;
|
|
pipe.buckets[toRemove].roffset = 0;
|
|
}
|
|
pipe.buckets.splice(0, toRemove);
|
|
return totalRead;
|
|
},
|
|
write(stream, buffer, offset, length, position) {
|
|
var pipe = stream.node.pipe;
|
|
var data = buffer.subarray(offset, offset + length);
|
|
var dataLen = data.byteLength;
|
|
if (dataLen <= 0) {
|
|
return 0;
|
|
}
|
|
var currBucket = null;
|
|
if (pipe.buckets.length == 0) {
|
|
currBucket = {
|
|
buffer: new Uint8Array(PIPEFS.BUCKET_BUFFER_SIZE),
|
|
offset: 0,
|
|
roffset: 0,
|
|
};
|
|
pipe.buckets.push(currBucket);
|
|
} else {
|
|
currBucket = pipe.buckets[pipe.buckets.length - 1];
|
|
}
|
|
var freeBytesInCurrBuffer =
|
|
PIPEFS.BUCKET_BUFFER_SIZE - currBucket.offset;
|
|
if (freeBytesInCurrBuffer >= dataLen) {
|
|
currBucket.buffer.set(data, currBucket.offset);
|
|
currBucket.offset += dataLen;
|
|
return dataLen;
|
|
} else if (freeBytesInCurrBuffer > 0) {
|
|
currBucket.buffer.set(
|
|
data.subarray(0, freeBytesInCurrBuffer),
|
|
currBucket.offset
|
|
);
|
|
currBucket.offset += freeBytesInCurrBuffer;
|
|
data = data.subarray(
|
|
freeBytesInCurrBuffer,
|
|
data.byteLength
|
|
);
|
|
}
|
|
var numBuckets =
|
|
(data.byteLength / PIPEFS.BUCKET_BUFFER_SIZE) | 0;
|
|
var remElements = data.byteLength % PIPEFS.BUCKET_BUFFER_SIZE;
|
|
for (var i = 0; i < numBuckets; i++) {
|
|
var newBucket = {
|
|
buffer: new Uint8Array(PIPEFS.BUCKET_BUFFER_SIZE),
|
|
offset: PIPEFS.BUCKET_BUFFER_SIZE,
|
|
roffset: 0,
|
|
};
|
|
pipe.buckets.push(newBucket);
|
|
newBucket.buffer.set(
|
|
data.subarray(0, PIPEFS.BUCKET_BUFFER_SIZE)
|
|
);
|
|
data = data.subarray(
|
|
PIPEFS.BUCKET_BUFFER_SIZE,
|
|
data.byteLength
|
|
);
|
|
}
|
|
if (remElements > 0) {
|
|
var newBucket = {
|
|
buffer: new Uint8Array(PIPEFS.BUCKET_BUFFER_SIZE),
|
|
offset: data.byteLength,
|
|
roffset: 0,
|
|
};
|
|
pipe.buckets.push(newBucket);
|
|
newBucket.buffer.set(data);
|
|
}
|
|
return dataLen;
|
|
},
|
|
close(stream) {
|
|
var pipe = stream.node.pipe;
|
|
pipe.refcnt--;
|
|
if (pipe.refcnt === 0) {
|
|
pipe.buckets = null;
|
|
}
|
|
},
|
|
},
|
|
nextname() {
|
|
if (!PIPEFS.nextname.current) {
|
|
PIPEFS.nextname.current = 0;
|
|
}
|
|
return 'pipe[' + PIPEFS.nextname.current++ + ']';
|
|
},
|
|
};
|
|
function ___syscall_pipe(fdPtr) {
|
|
try {
|
|
if (fdPtr == 0) {
|
|
throw new FS.ErrnoError(21);
|
|
}
|
|
var res = PIPEFS.createPipe();
|
|
HEAP32[fdPtr >> 2] = res.readable_fd;
|
|
HEAP32[(fdPtr + 4) >> 2] = res.writable_fd;
|
|
return 0;
|
|
} catch (e) {
|
|
if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
|
|
return -e.errno;
|
|
}
|
|
}
|
|
___syscall_pipe.sig = 'ip';
|
|
function ___syscall_poll(fds, nfds, timeout) {
|
|
try {
|
|
var nonzero = 0;
|
|
for (var i = 0; i < nfds; i++) {
|
|
var pollfd = fds + 8 * i;
|
|
var fd = HEAP32[pollfd >> 2];
|
|
var events = HEAP16[(pollfd + 4) >> 1];
|
|
var mask = 32;
|
|
var stream = FS.getStream(fd);
|
|
if (stream) {
|
|
mask = SYSCALLS.DEFAULT_POLLMASK;
|
|
if (stream.stream_ops?.poll) {
|
|
mask = stream.stream_ops.poll(stream, -1);
|
|
}
|
|
}
|
|
mask &= events | 8 | 16;
|
|
if (mask) nonzero++;
|
|
HEAP16[(pollfd + 6) >> 1] = mask;
|
|
}
|
|
return nonzero;
|
|
} catch (e) {
|
|
if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
|
|
return -e.errno;
|
|
}
|
|
}
|
|
___syscall_poll.sig = 'ipii';
|
|
function ___syscall_readlinkat(dirfd, path, buf, bufsize) {
|
|
try {
|
|
path = SYSCALLS.getStr(path);
|
|
path = SYSCALLS.calculateAt(dirfd, path);
|
|
if (bufsize <= 0) return -28;
|
|
var ret = FS.readlink(path);
|
|
var len = Math.min(bufsize, lengthBytesUTF8(ret));
|
|
var endChar = HEAP8[buf + len];
|
|
stringToUTF8(ret, buf, bufsize + 1);
|
|
HEAP8[buf + len] = endChar;
|
|
return len;
|
|
} catch (e) {
|
|
if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
|
|
return -e.errno;
|
|
}
|
|
}
|
|
___syscall_readlinkat.sig = 'iippp';
|
|
function ___syscall_recvfrom(fd, buf, len, flags, addr, addrlen) {
|
|
try {
|
|
var sock = getSocketFromFD(fd);
|
|
var msg = sock.sock_ops.recvmsg(
|
|
sock,
|
|
len,
|
|
typeof flags !== 'undefined' ? flags : 0
|
|
);
|
|
if (!msg) return 0;
|
|
if (addr) {
|
|
var errno = writeSockaddr(
|
|
addr,
|
|
sock.family,
|
|
DNS.lookup_name(msg.addr),
|
|
msg.port,
|
|
addrlen
|
|
);
|
|
}
|
|
HEAPU8.set(msg.buffer, buf);
|
|
return msg.buffer.byteLength;
|
|
} catch (e) {
|
|
if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
|
|
return -e.errno;
|
|
}
|
|
}
|
|
___syscall_recvfrom.sig = 'iippipp';
|
|
function ___syscall_renameat(olddirfd, oldpath, newdirfd, newpath) {
|
|
try {
|
|
oldpath = SYSCALLS.getStr(oldpath);
|
|
newpath = SYSCALLS.getStr(newpath);
|
|
oldpath = SYSCALLS.calculateAt(olddirfd, oldpath);
|
|
newpath = SYSCALLS.calculateAt(newdirfd, newpath);
|
|
FS.rename(oldpath, newpath);
|
|
return 0;
|
|
} catch (e) {
|
|
if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
|
|
return -e.errno;
|
|
}
|
|
}
|
|
___syscall_renameat.sig = 'iipip';
|
|
function ___syscall_rmdir(path) {
|
|
try {
|
|
path = SYSCALLS.getStr(path);
|
|
FS.rmdir(path);
|
|
return 0;
|
|
} catch (e) {
|
|
if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
|
|
return -e.errno;
|
|
}
|
|
}
|
|
___syscall_rmdir.sig = 'ip';
|
|
function ___syscall_sendto(fd, message, length, flags, addr, addr_len) {
|
|
try {
|
|
var sock = getSocketFromFD(fd);
|
|
if (!addr) {
|
|
return FS.write(sock.stream, HEAP8, message, length);
|
|
}
|
|
var dest = getSocketAddress(addr, addr_len);
|
|
return sock.sock_ops.sendmsg(
|
|
sock,
|
|
HEAP8,
|
|
message,
|
|
length,
|
|
dest.addr,
|
|
dest.port
|
|
);
|
|
} catch (e) {
|
|
if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
|
|
return -e.errno;
|
|
}
|
|
}
|
|
___syscall_sendto.sig = 'iippipp';
|
|
function ___syscall_socket(domain, type, protocol) {
|
|
try {
|
|
var sock = SOCKFS.createSocket(domain, type, protocol);
|
|
return sock.stream.fd;
|
|
} catch (e) {
|
|
if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
|
|
return -e.errno;
|
|
}
|
|
}
|
|
___syscall_socket.sig = 'iiiiiii';
|
|
function ___syscall_stat64(path, buf) {
|
|
try {
|
|
path = SYSCALLS.getStr(path);
|
|
return SYSCALLS.writeStat(buf, FS.stat(path));
|
|
} catch (e) {
|
|
if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
|
|
return -e.errno;
|
|
}
|
|
}
|
|
___syscall_stat64.sig = 'ipp';
|
|
function ___syscall_statfs64(path, size, buf) {
|
|
try {
|
|
SYSCALLS.writeStatFs(buf, FS.statfs(SYSCALLS.getStr(path)));
|
|
return 0;
|
|
} catch (e) {
|
|
if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
|
|
return -e.errno;
|
|
}
|
|
}
|
|
___syscall_statfs64.sig = 'ippp';
|
|
function ___syscall_symlinkat(target, dirfd, linkpath) {
|
|
try {
|
|
target = SYSCALLS.getStr(target);
|
|
linkpath = SYSCALLS.getStr(linkpath);
|
|
linkpath = SYSCALLS.calculateAt(dirfd, linkpath);
|
|
FS.symlink(target, linkpath);
|
|
return 0;
|
|
} catch (e) {
|
|
if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
|
|
return -e.errno;
|
|
}
|
|
}
|
|
___syscall_symlinkat.sig = 'ipip';
|
|
function ___syscall_unlinkat(dirfd, path, flags) {
|
|
try {
|
|
path = SYSCALLS.getStr(path);
|
|
path = SYSCALLS.calculateAt(dirfd, path);
|
|
if (!flags) {
|
|
FS.unlink(path);
|
|
} else if (flags === 512) {
|
|
FS.rmdir(path);
|
|
} else {
|
|
return -28;
|
|
}
|
|
return 0;
|
|
} catch (e) {
|
|
if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
|
|
return -e.errno;
|
|
}
|
|
}
|
|
___syscall_unlinkat.sig = 'iipi';
|
|
var readI53FromI64 = (ptr) =>
|
|
HEAPU32[ptr >> 2] + HEAP32[(ptr + 4) >> 2] * 4294967296;
|
|
function ___syscall_utimensat(dirfd, path, times, flags) {
|
|
try {
|
|
path = SYSCALLS.getStr(path);
|
|
path = SYSCALLS.calculateAt(dirfd, path, true);
|
|
var now = Date.now(),
|
|
atime,
|
|
mtime;
|
|
if (!times) {
|
|
atime = now;
|
|
mtime = now;
|
|
} else {
|
|
var seconds = readI53FromI64(times);
|
|
var nanoseconds = HEAP32[(times + 8) >> 2];
|
|
if (nanoseconds == 1073741823) {
|
|
atime = now;
|
|
} else if (nanoseconds == 1073741822) {
|
|
atime = null;
|
|
} else {
|
|
atime = seconds * 1e3 + nanoseconds / (1e3 * 1e3);
|
|
}
|
|
times += 16;
|
|
seconds = readI53FromI64(times);
|
|
nanoseconds = HEAP32[(times + 8) >> 2];
|
|
if (nanoseconds == 1073741823) {
|
|
mtime = now;
|
|
} else if (nanoseconds == 1073741822) {
|
|
mtime = null;
|
|
} else {
|
|
mtime = seconds * 1e3 + nanoseconds / (1e3 * 1e3);
|
|
}
|
|
}
|
|
if ((mtime ?? atime) !== null) {
|
|
FS.utime(path, atime, mtime);
|
|
}
|
|
return 0;
|
|
} catch (e) {
|
|
if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
|
|
return -e.errno;
|
|
}
|
|
}
|
|
___syscall_utimensat.sig = 'iippi';
|
|
var __abort_js = () => abort('');
|
|
__abort_js.sig = 'v';
|
|
var dlSetError = (msg) => {
|
|
var sp = stackSave();
|
|
var cmsg = stringToUTF8OnStack(msg);
|
|
___dl_seterr(cmsg, 0);
|
|
stackRestore(sp);
|
|
};
|
|
var dlopenInternal = (handle, jsflags) => {
|
|
var filename = UTF8ToString(handle + 36);
|
|
var flags = HEAP32[(handle + 4) >> 2];
|
|
filename = PATH.normalize(filename);
|
|
var global = Boolean(flags & 256);
|
|
var localScope = global ? null : {};
|
|
var combinedFlags = {
|
|
global,
|
|
nodelete: Boolean(flags & 4096),
|
|
loadAsync: jsflags.loadAsync,
|
|
};
|
|
if (jsflags.loadAsync) {
|
|
return loadDynamicLibrary(
|
|
filename,
|
|
combinedFlags,
|
|
localScope,
|
|
handle
|
|
);
|
|
}
|
|
try {
|
|
return loadDynamicLibrary(
|
|
filename,
|
|
combinedFlags,
|
|
localScope,
|
|
handle
|
|
);
|
|
} catch (e) {
|
|
dlSetError(`could not load dynamic lib: ${filename}\n${e}`);
|
|
return 0;
|
|
}
|
|
};
|
|
function __dlopen_js(handle) {
|
|
var jsflags = { loadAsync: false };
|
|
return dlopenInternal(handle, jsflags);
|
|
}
|
|
__dlopen_js.sig = 'pp';
|
|
var __dlsym_js = (handle, symbol, symbolIndex) => {
|
|
symbol = UTF8ToString(symbol);
|
|
var result;
|
|
var newSymIndex;
|
|
var lib = LDSO.loadedLibsByHandle[handle];
|
|
newSymIndex = Object.keys(lib.exports).indexOf(symbol);
|
|
if (newSymIndex == -1 || lib.exports[symbol].stub) {
|
|
dlSetError(
|
|
`Tried to lookup unknown symbol "${symbol}" in dynamic lib: ${lib.name}`
|
|
);
|
|
return 0;
|
|
}
|
|
result = lib.exports[symbol];
|
|
if (typeof result == 'function') {
|
|
if (result.orig) {
|
|
result = result.orig;
|
|
}
|
|
var addr = getFunctionAddress(result);
|
|
if (addr) {
|
|
result = addr;
|
|
} else {
|
|
result = addFunction(result, result.sig);
|
|
HEAPU32[symbolIndex >> 2] = newSymIndex;
|
|
}
|
|
}
|
|
return result;
|
|
};
|
|
__dlsym_js.sig = 'pppp';
|
|
var __emscripten_lookup_name = (name) => {
|
|
var nameString = UTF8ToString(name);
|
|
return inetPton4(DNS.lookup_name(nameString));
|
|
};
|
|
__emscripten_lookup_name.sig = 'ip';
|
|
var runtimeKeepaliveCounter = 0;
|
|
var __emscripten_runtime_keepalive_clear = () => {
|
|
noExitRuntime = false;
|
|
runtimeKeepaliveCounter = 0;
|
|
};
|
|
__emscripten_runtime_keepalive_clear.sig = 'v';
|
|
var __emscripten_throw_longjmp = () => {
|
|
throw Infinity;
|
|
};
|
|
__emscripten_throw_longjmp.sig = 'v';
|
|
function __gmtime_js(time, tmPtr) {
|
|
time = bigintToI53Checked(time);
|
|
var date = new Date(time * 1e3);
|
|
HEAP32[tmPtr >> 2] = date.getUTCSeconds();
|
|
HEAP32[(tmPtr + 4) >> 2] = date.getUTCMinutes();
|
|
HEAP32[(tmPtr + 8) >> 2] = date.getUTCHours();
|
|
HEAP32[(tmPtr + 12) >> 2] = date.getUTCDate();
|
|
HEAP32[(tmPtr + 16) >> 2] = date.getUTCMonth();
|
|
HEAP32[(tmPtr + 20) >> 2] = date.getUTCFullYear() - 1900;
|
|
HEAP32[(tmPtr + 24) >> 2] = date.getUTCDay();
|
|
var start = Date.UTC(date.getUTCFullYear(), 0, 1, 0, 0, 0, 0);
|
|
var yday = ((date.getTime() - start) / (1e3 * 60 * 60 * 24)) | 0;
|
|
HEAP32[(tmPtr + 28) >> 2] = yday;
|
|
}
|
|
__gmtime_js.sig = 'vjp';
|
|
var isLeapYear = (year) =>
|
|
year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0);
|
|
var MONTH_DAYS_LEAP_CUMULATIVE = [
|
|
0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335,
|
|
];
|
|
var MONTH_DAYS_REGULAR_CUMULATIVE = [
|
|
0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334,
|
|
];
|
|
var ydayFromDate = (date) => {
|
|
var leap = isLeapYear(date.getFullYear());
|
|
var monthDaysCumulative = leap
|
|
? MONTH_DAYS_LEAP_CUMULATIVE
|
|
: MONTH_DAYS_REGULAR_CUMULATIVE;
|
|
var yday = monthDaysCumulative[date.getMonth()] + date.getDate() - 1;
|
|
return yday;
|
|
};
|
|
function __localtime_js(time, tmPtr) {
|
|
time = bigintToI53Checked(time);
|
|
var date = new Date(time * 1e3);
|
|
HEAP32[tmPtr >> 2] = date.getSeconds();
|
|
HEAP32[(tmPtr + 4) >> 2] = date.getMinutes();
|
|
HEAP32[(tmPtr + 8) >> 2] = date.getHours();
|
|
HEAP32[(tmPtr + 12) >> 2] = date.getDate();
|
|
HEAP32[(tmPtr + 16) >> 2] = date.getMonth();
|
|
HEAP32[(tmPtr + 20) >> 2] = date.getFullYear() - 1900;
|
|
HEAP32[(tmPtr + 24) >> 2] = date.getDay();
|
|
var yday = ydayFromDate(date) | 0;
|
|
HEAP32[(tmPtr + 28) >> 2] = yday;
|
|
HEAP32[(tmPtr + 36) >> 2] = -(date.getTimezoneOffset() * 60);
|
|
var start = new Date(date.getFullYear(), 0, 1);
|
|
var summerOffset = new Date(
|
|
date.getFullYear(),
|
|
6,
|
|
1
|
|
).getTimezoneOffset();
|
|
var winterOffset = start.getTimezoneOffset();
|
|
var dst =
|
|
(summerOffset != winterOffset &&
|
|
date.getTimezoneOffset() ==
|
|
Math.min(winterOffset, summerOffset)) | 0;
|
|
HEAP32[(tmPtr + 32) >> 2] = dst;
|
|
}
|
|
__localtime_js.sig = 'vjp';
|
|
var __mktime_js = function (tmPtr) {
|
|
var ret = (() => {
|
|
var date = new Date(
|
|
HEAP32[(tmPtr + 20) >> 2] + 1900,
|
|
HEAP32[(tmPtr + 16) >> 2],
|
|
HEAP32[(tmPtr + 12) >> 2],
|
|
HEAP32[(tmPtr + 8) >> 2],
|
|
HEAP32[(tmPtr + 4) >> 2],
|
|
HEAP32[tmPtr >> 2],
|
|
0
|
|
);
|
|
var dst = HEAP32[(tmPtr + 32) >> 2];
|
|
var guessedOffset = date.getTimezoneOffset();
|
|
var start = new Date(date.getFullYear(), 0, 1);
|
|
var summerOffset = new Date(
|
|
date.getFullYear(),
|
|
6,
|
|
1
|
|
).getTimezoneOffset();
|
|
var winterOffset = start.getTimezoneOffset();
|
|
var dstOffset = Math.min(winterOffset, summerOffset);
|
|
if (dst < 0) {
|
|
HEAP32[(tmPtr + 32) >> 2] = Number(
|
|
summerOffset != winterOffset && dstOffset == guessedOffset
|
|
);
|
|
} else if (dst > 0 != (dstOffset == guessedOffset)) {
|
|
var nonDstOffset = Math.max(winterOffset, summerOffset);
|
|
var trueOffset = dst > 0 ? dstOffset : nonDstOffset;
|
|
date.setTime(
|
|
date.getTime() + (trueOffset - guessedOffset) * 6e4
|
|
);
|
|
}
|
|
HEAP32[(tmPtr + 24) >> 2] = date.getDay();
|
|
var yday = ydayFromDate(date) | 0;
|
|
HEAP32[(tmPtr + 28) >> 2] = yday;
|
|
HEAP32[tmPtr >> 2] = date.getSeconds();
|
|
HEAP32[(tmPtr + 4) >> 2] = date.getMinutes();
|
|
HEAP32[(tmPtr + 8) >> 2] = date.getHours();
|
|
HEAP32[(tmPtr + 12) >> 2] = date.getDate();
|
|
HEAP32[(tmPtr + 16) >> 2] = date.getMonth();
|
|
HEAP32[(tmPtr + 20) >> 2] = date.getYear();
|
|
var timeMs = date.getTime();
|
|
if (isNaN(timeMs)) {
|
|
return -1;
|
|
}
|
|
return timeMs / 1e3;
|
|
})();
|
|
return BigInt(ret);
|
|
};
|
|
__mktime_js.sig = 'jp';
|
|
function __mmap_js(len, prot, flags, fd, offset, allocated, addr) {
|
|
offset = bigintToI53Checked(offset);
|
|
try {
|
|
var stream = SYSCALLS.getStreamFromFD(fd);
|
|
var res = FS.mmap(stream, len, offset, prot, flags);
|
|
var ptr = res.ptr;
|
|
HEAP32[allocated >> 2] = res.allocated;
|
|
HEAPU32[addr >> 2] = ptr;
|
|
return 0;
|
|
} catch (e) {
|
|
if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
|
|
return -e.errno;
|
|
}
|
|
}
|
|
__mmap_js.sig = 'ipiiijpp';
|
|
function __munmap_js(addr, len, prot, flags, fd, offset) {
|
|
offset = bigintToI53Checked(offset);
|
|
try {
|
|
var stream = SYSCALLS.getStreamFromFD(fd);
|
|
if (prot & 2) {
|
|
SYSCALLS.doMsync(addr, stream, len, flags, offset);
|
|
}
|
|
} catch (e) {
|
|
if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
|
|
return -e.errno;
|
|
}
|
|
}
|
|
__munmap_js.sig = 'ippiiij';
|
|
var timers = {};
|
|
var handleException = (e) => {
|
|
if (e instanceof ExitStatus || e == 'unwind') {
|
|
return EXITSTATUS;
|
|
}
|
|
quit_(1, e);
|
|
};
|
|
var keepRuntimeAlive = () => noExitRuntime || runtimeKeepaliveCounter > 0;
|
|
var _proc_exit = (code) => {
|
|
EXITSTATUS = code;
|
|
if (!keepRuntimeAlive()) {
|
|
Module['onExit']?.(code);
|
|
ABORT = true;
|
|
}
|
|
quit_(code, new ExitStatus(code));
|
|
};
|
|
_proc_exit.sig = 'vi';
|
|
var exitJS = (status, implicit) => {
|
|
EXITSTATUS = status;
|
|
if (!keepRuntimeAlive()) {
|
|
exitRuntime();
|
|
}
|
|
_proc_exit(status);
|
|
};
|
|
var _exit = exitJS;
|
|
_exit.sig = 'vi';
|
|
var maybeExit = () => {
|
|
if (runtimeExited) {
|
|
return;
|
|
}
|
|
if (!keepRuntimeAlive()) {
|
|
try {
|
|
_exit(EXITSTATUS);
|
|
} catch (e) {
|
|
handleException(e);
|
|
}
|
|
}
|
|
};
|
|
var callUserCallback = (func) => {
|
|
if (runtimeExited || ABORT) {
|
|
return;
|
|
}
|
|
try {
|
|
func();
|
|
maybeExit();
|
|
} catch (e) {
|
|
handleException(e);
|
|
}
|
|
};
|
|
var _emscripten_get_now = () => performance.now();
|
|
_emscripten_get_now.sig = 'd';
|
|
var __setitimer_js = (which, timeout_ms) => {
|
|
if (timers[which]) {
|
|
clearTimeout(timers[which].id);
|
|
delete timers[which];
|
|
}
|
|
if (!timeout_ms) return 0;
|
|
var id = setTimeout(() => {
|
|
delete timers[which];
|
|
callUserCallback(() =>
|
|
__emscripten_timeout(which, _emscripten_get_now())
|
|
);
|
|
}, timeout_ms);
|
|
timers[which] = { id, timeout_ms };
|
|
return 0;
|
|
};
|
|
__setitimer_js.sig = 'iid';
|
|
var __tzset_js = (timezone, daylight, std_name, dst_name) => {
|
|
var currentYear = new Date().getFullYear();
|
|
var winter = new Date(currentYear, 0, 1);
|
|
var summer = new Date(currentYear, 6, 1);
|
|
var winterOffset = winter.getTimezoneOffset();
|
|
var summerOffset = summer.getTimezoneOffset();
|
|
var stdTimezoneOffset = Math.max(winterOffset, summerOffset);
|
|
HEAPU32[timezone >> 2] = stdTimezoneOffset * 60;
|
|
HEAP32[daylight >> 2] = Number(winterOffset != summerOffset);
|
|
var extractZone = (timezoneOffset) => {
|
|
var sign = timezoneOffset >= 0 ? '-' : '+';
|
|
var absOffset = Math.abs(timezoneOffset);
|
|
var hours = String(Math.floor(absOffset / 60)).padStart(2, '0');
|
|
var minutes = String(absOffset % 60).padStart(2, '0');
|
|
return `UTC${sign}${hours}${minutes}`;
|
|
};
|
|
var winterName = extractZone(winterOffset);
|
|
var summerName = extractZone(summerOffset);
|
|
if (summerOffset < winterOffset) {
|
|
stringToUTF8(winterName, std_name, 17);
|
|
stringToUTF8(summerName, dst_name, 17);
|
|
} else {
|
|
stringToUTF8(winterName, dst_name, 17);
|
|
stringToUTF8(summerName, std_name, 17);
|
|
}
|
|
};
|
|
__tzset_js.sig = 'vpppp';
|
|
var _emscripten_date_now = () => Date.now();
|
|
_emscripten_date_now.sig = 'd';
|
|
var nowIsMonotonic = 1;
|
|
var checkWasiClock = (clock_id) => clock_id >= 0 && clock_id <= 3;
|
|
function _clock_time_get(clk_id, ignored_precision, ptime) {
|
|
ignored_precision = bigintToI53Checked(ignored_precision);
|
|
if (!checkWasiClock(clk_id)) {
|
|
return 28;
|
|
}
|
|
var now;
|
|
if (clk_id === 0) {
|
|
now = _emscripten_date_now();
|
|
} else if (nowIsMonotonic) {
|
|
now = _emscripten_get_now();
|
|
} else {
|
|
return 52;
|
|
}
|
|
var nsec = Math.round(now * 1e3 * 1e3);
|
|
HEAP64[ptime >> 3] = BigInt(nsec);
|
|
return 0;
|
|
}
|
|
_clock_time_get.sig = 'iijp';
|
|
var getHeapMax = () => 2147483648;
|
|
var _emscripten_get_heap_max = () => getHeapMax();
|
|
_emscripten_get_heap_max.sig = 'p';
|
|
var growMemory = (size) => {
|
|
var oldHeapSize = wasmMemory.buffer.byteLength;
|
|
var pages = ((size - oldHeapSize + 65535) / 65536) | 0;
|
|
try {
|
|
wasmMemory.grow(pages);
|
|
updateMemoryViews();
|
|
return 1;
|
|
} catch (e) {}
|
|
};
|
|
var _emscripten_resize_heap = (requestedSize) => {
|
|
var oldSize = HEAPU8.length;
|
|
requestedSize >>>= 0;
|
|
var maxHeapSize = getHeapMax();
|
|
if (requestedSize > maxHeapSize) {
|
|
return false;
|
|
}
|
|
for (var cutDown = 1; cutDown <= 4; cutDown *= 2) {
|
|
var overGrownHeapSize = oldSize * (1 + 0.2 / cutDown);
|
|
overGrownHeapSize = Math.min(
|
|
overGrownHeapSize,
|
|
requestedSize + 100663296
|
|
);
|
|
var newSize = Math.min(
|
|
maxHeapSize,
|
|
alignMemory(Math.max(requestedSize, overGrownHeapSize), 65536)
|
|
);
|
|
var replacement = growMemory(newSize);
|
|
if (replacement) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
};
|
|
_emscripten_resize_heap.sig = 'ip';
|
|
var runtimeKeepalivePush = () => {
|
|
runtimeKeepaliveCounter += 1;
|
|
};
|
|
runtimeKeepalivePush.sig = 'v';
|
|
var runtimeKeepalivePop = () => {
|
|
runtimeKeepaliveCounter -= 1;
|
|
};
|
|
runtimeKeepalivePop.sig = 'v';
|
|
var safeSetTimeout = (func, timeout) => {
|
|
runtimeKeepalivePush();
|
|
return setTimeout(() => {
|
|
runtimeKeepalivePop();
|
|
callUserCallback(func);
|
|
}, timeout);
|
|
};
|
|
var _emscripten_sleep = (ms) =>
|
|
Asyncify.handleSleep((wakeUp) => safeSetTimeout(wakeUp, ms));
|
|
_emscripten_sleep.sig = 'vi';
|
|
_emscripten_sleep.isAsync = true;
|
|
var ENV = PHPLoader.ENV || {};
|
|
var getExecutableName = () => thisProgram || './this.program';
|
|
var getEnvStrings = () => {
|
|
if (!getEnvStrings.strings) {
|
|
var lang =
|
|
(
|
|
(typeof navigator == 'object' && navigator.language) ||
|
|
'C'
|
|
).replace('-', '_') + '.UTF-8';
|
|
var env = {
|
|
USER: 'web_user',
|
|
LOGNAME: 'web_user',
|
|
PATH: '/',
|
|
PWD: '/',
|
|
HOME: '/home/web_user',
|
|
LANG: lang,
|
|
_: getExecutableName(),
|
|
};
|
|
for (var x in ENV) {
|
|
if (ENV[x] === undefined) delete env[x];
|
|
else env[x] = ENV[x];
|
|
}
|
|
var strings = [];
|
|
for (var x in env) {
|
|
strings.push(`${x}=${env[x]}`);
|
|
}
|
|
getEnvStrings.strings = strings;
|
|
}
|
|
return getEnvStrings.strings;
|
|
};
|
|
var _environ_get = (__environ, environ_buf) => {
|
|
var bufSize = 0;
|
|
var envp = 0;
|
|
for (var string of getEnvStrings()) {
|
|
var ptr = environ_buf + bufSize;
|
|
HEAPU32[(__environ + envp) >> 2] = ptr;
|
|
bufSize += stringToUTF8(string, ptr, Infinity) + 1;
|
|
envp += 4;
|
|
}
|
|
return 0;
|
|
};
|
|
_environ_get.sig = 'ipp';
|
|
var _environ_sizes_get = (penviron_count, penviron_buf_size) => {
|
|
var strings = getEnvStrings();
|
|
HEAPU32[penviron_count >> 2] = strings.length;
|
|
var bufSize = 0;
|
|
for (var string of strings) {
|
|
bufSize += lengthBytesUTF8(string) + 1;
|
|
}
|
|
HEAPU32[penviron_buf_size >> 2] = bufSize;
|
|
return 0;
|
|
};
|
|
_environ_sizes_get.sig = 'ipp';
|
|
function _fd_close(fd) {
|
|
try {
|
|
var stream = SYSCALLS.getStreamFromFD(fd);
|
|
FS.close(stream);
|
|
return 0;
|
|
} catch (e) {
|
|
if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
|
|
return e.errno;
|
|
}
|
|
}
|
|
_fd_close.sig = 'ii';
|
|
function _fd_fdstat_get(fd, pbuf) {
|
|
try {
|
|
var rightsBase = 0;
|
|
var rightsInheriting = 0;
|
|
var flags = 0;
|
|
{
|
|
var stream = SYSCALLS.getStreamFromFD(fd);
|
|
var type = stream.tty
|
|
? 2
|
|
: FS.isDir(stream.mode)
|
|
? 3
|
|
: FS.isLink(stream.mode)
|
|
? 7
|
|
: 4;
|
|
}
|
|
HEAP8[pbuf] = type;
|
|
HEAP16[(pbuf + 2) >> 1] = flags;
|
|
HEAP64[(pbuf + 8) >> 3] = BigInt(rightsBase);
|
|
HEAP64[(pbuf + 16) >> 3] = BigInt(rightsInheriting);
|
|
return 0;
|
|
} catch (e) {
|
|
if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
|
|
return e.errno;
|
|
}
|
|
}
|
|
_fd_fdstat_get.sig = 'iip';
|
|
var doReadv = (stream, iov, iovcnt, offset) => {
|
|
var ret = 0;
|
|
for (var i = 0; i < iovcnt; i++) {
|
|
var ptr = HEAPU32[iov >> 2];
|
|
var len = HEAPU32[(iov + 4) >> 2];
|
|
iov += 8;
|
|
var curr = FS.read(stream, HEAP8, ptr, len, offset);
|
|
if (curr < 0) return -1;
|
|
ret += curr;
|
|
if (curr < len) break;
|
|
if (typeof offset != 'undefined') {
|
|
offset += curr;
|
|
}
|
|
}
|
|
return ret;
|
|
};
|
|
function _fd_read(fd, iov, iovcnt, pnum) {
|
|
try {
|
|
var stream = SYSCALLS.getStreamFromFD(fd);
|
|
var num = doReadv(stream, iov, iovcnt);
|
|
HEAPU32[pnum >> 2] = num;
|
|
return 0;
|
|
} catch (e) {
|
|
if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
|
|
return e.errno;
|
|
}
|
|
}
|
|
_fd_read.sig = 'iippp';
|
|
function _fd_seek(fd, offset, whence, newOffset) {
|
|
offset = bigintToI53Checked(offset);
|
|
try {
|
|
if (isNaN(offset)) return 61;
|
|
var stream = SYSCALLS.getStreamFromFD(fd);
|
|
FS.llseek(stream, offset, whence);
|
|
HEAP64[newOffset >> 3] = BigInt(stream.position);
|
|
if (stream.getdents && offset === 0 && whence === 0)
|
|
stream.getdents = null;
|
|
return 0;
|
|
} catch (e) {
|
|
if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
|
|
return e.errno;
|
|
}
|
|
}
|
|
_fd_seek.sig = 'iijip';
|
|
var _fd_sync = function (fd) {
|
|
try {
|
|
var stream = SYSCALLS.getStreamFromFD(fd);
|
|
return Asyncify.handleSleep((wakeUp) => {
|
|
var mount = stream.node.mount;
|
|
if (!mount.type.syncfs) {
|
|
wakeUp(0);
|
|
return;
|
|
}
|
|
mount.type.syncfs(mount, false, (err) => {
|
|
wakeUp(err ? 29 : 0);
|
|
});
|
|
});
|
|
} catch (e) {
|
|
if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
|
|
return e.errno;
|
|
}
|
|
};
|
|
_fd_sync.sig = 'ii';
|
|
_fd_sync.isAsync = true;
|
|
var doWritev = (stream, iov, iovcnt, offset) => {
|
|
var ret = 0;
|
|
for (var i = 0; i < iovcnt; i++) {
|
|
var ptr = HEAPU32[iov >> 2];
|
|
var len = HEAPU32[(iov + 4) >> 2];
|
|
iov += 8;
|
|
var curr = FS.write(stream, HEAP8, ptr, len, offset);
|
|
if (curr < 0) return -1;
|
|
ret += curr;
|
|
if (curr < len) {
|
|
break;
|
|
}
|
|
if (typeof offset != 'undefined') {
|
|
offset += curr;
|
|
}
|
|
}
|
|
return ret;
|
|
};
|
|
function _fd_write(fd, iov, iovcnt, pnum) {
|
|
try {
|
|
var stream = SYSCALLS.getStreamFromFD(fd);
|
|
var num = doWritev(stream, iov, iovcnt);
|
|
HEAPU32[pnum >> 2] = num;
|
|
return 0;
|
|
} catch (e) {
|
|
if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
|
|
return e.errno;
|
|
}
|
|
}
|
|
_fd_write.sig = 'iippp';
|
|
var _getaddrinfo = (node, service, hint, out) => {
|
|
var addr = 0;
|
|
var port = 0;
|
|
var flags = 0;
|
|
var family = 0;
|
|
var type = 0;
|
|
var proto = 0;
|
|
var ai;
|
|
function allocaddrinfo(family, type, proto, canon, addr, port) {
|
|
var sa, salen, ai;
|
|
var errno;
|
|
salen = family === 10 ? 28 : 16;
|
|
addr = family === 10 ? inetNtop6(addr) : inetNtop4(addr);
|
|
sa = _malloc(salen);
|
|
errno = writeSockaddr(sa, family, addr, port);
|
|
ai = _malloc(32);
|
|
HEAP32[(ai + 4) >> 2] = family;
|
|
HEAP32[(ai + 8) >> 2] = type;
|
|
HEAP32[(ai + 12) >> 2] = proto;
|
|
HEAPU32[(ai + 24) >> 2] = canon;
|
|
HEAPU32[(ai + 20) >> 2] = sa;
|
|
if (family === 10) {
|
|
HEAP32[(ai + 16) >> 2] = 28;
|
|
} else {
|
|
HEAP32[(ai + 16) >> 2] = 16;
|
|
}
|
|
HEAP32[(ai + 28) >> 2] = 0;
|
|
return ai;
|
|
}
|
|
if (hint) {
|
|
flags = HEAP32[hint >> 2];
|
|
family = HEAP32[(hint + 4) >> 2];
|
|
type = HEAP32[(hint + 8) >> 2];
|
|
proto = HEAP32[(hint + 12) >> 2];
|
|
}
|
|
if (type && !proto) {
|
|
proto = type === 2 ? 17 : 6;
|
|
}
|
|
if (!type && proto) {
|
|
type = proto === 17 ? 2 : 1;
|
|
}
|
|
if (proto === 0) {
|
|
proto = 6;
|
|
}
|
|
if (type === 0) {
|
|
type = 1;
|
|
}
|
|
if (!node && !service) {
|
|
return -2;
|
|
}
|
|
if (flags & ~(1 | 2 | 4 | 1024 | 8 | 16 | 32)) {
|
|
return -1;
|
|
}
|
|
if (hint !== 0 && HEAP32[hint >> 2] & 2 && !node) {
|
|
return -1;
|
|
}
|
|
if (flags & 32) {
|
|
return -2;
|
|
}
|
|
if (type !== 0 && type !== 1 && type !== 2) {
|
|
return -7;
|
|
}
|
|
if (family !== 0 && family !== 2 && family !== 10) {
|
|
return -6;
|
|
}
|
|
if (service) {
|
|
service = UTF8ToString(service);
|
|
port = parseInt(service, 10);
|
|
if (isNaN(port)) {
|
|
if (flags & 1024) {
|
|
return -2;
|
|
}
|
|
return -8;
|
|
}
|
|
}
|
|
if (!node) {
|
|
if (family === 0) {
|
|
family = 2;
|
|
}
|
|
if ((flags & 1) === 0) {
|
|
if (family === 2) {
|
|
addr = _htonl(2130706433);
|
|
} else {
|
|
addr = [0, 0, 0, _htonl(1)];
|
|
}
|
|
}
|
|
ai = allocaddrinfo(family, type, proto, null, addr, port);
|
|
HEAPU32[out >> 2] = ai;
|
|
return 0;
|
|
}
|
|
node = UTF8ToString(node);
|
|
addr = inetPton4(node);
|
|
if (addr !== null) {
|
|
if (family === 0 || family === 2) {
|
|
family = 2;
|
|
} else if (family === 10 && flags & 8) {
|
|
addr = [0, 0, _htonl(65535), addr];
|
|
family = 10;
|
|
} else {
|
|
return -2;
|
|
}
|
|
} else {
|
|
addr = inetPton6(node);
|
|
if (addr !== null) {
|
|
if (family === 0 || family === 10) {
|
|
family = 10;
|
|
} else {
|
|
return -2;
|
|
}
|
|
}
|
|
}
|
|
if (addr != null) {
|
|
ai = allocaddrinfo(family, type, proto, node, addr, port);
|
|
HEAPU32[out >> 2] = ai;
|
|
return 0;
|
|
}
|
|
if (flags & 4) {
|
|
return -2;
|
|
}
|
|
node = DNS.lookup_name(node);
|
|
addr = inetPton4(node);
|
|
if (family === 0) {
|
|
family = 2;
|
|
} else if (family === 10) {
|
|
addr = [0, 0, _htonl(65535), addr];
|
|
}
|
|
ai = allocaddrinfo(family, type, proto, null, addr, port);
|
|
HEAPU32[out >> 2] = ai;
|
|
return 0;
|
|
};
|
|
_getaddrinfo.sig = 'ipppp';
|
|
var _getcontext = () => abort('missing function: ${name}');
|
|
var _getdtablesize = () => abort('missing function: ${name}');
|
|
var _getnameinfo = (sa, salen, node, nodelen, serv, servlen, flags) => {
|
|
var info = readSockaddr(sa, salen);
|
|
if (info.errno) {
|
|
return -6;
|
|
}
|
|
var port = info.port;
|
|
var addr = info.addr;
|
|
var overflowed = false;
|
|
if (node && nodelen) {
|
|
var lookup;
|
|
if (flags & 1 || !(lookup = DNS.lookup_addr(addr))) {
|
|
if (flags & 8) {
|
|
return -2;
|
|
}
|
|
} else {
|
|
addr = lookup;
|
|
}
|
|
var numBytesWrittenExclNull = stringToUTF8(addr, node, nodelen);
|
|
if (numBytesWrittenExclNull + 1 >= nodelen) {
|
|
overflowed = true;
|
|
}
|
|
}
|
|
if (serv && servlen) {
|
|
port = '' + port;
|
|
var numBytesWrittenExclNull = stringToUTF8(port, serv, servlen);
|
|
if (numBytesWrittenExclNull + 1 >= servlen) {
|
|
overflowed = true;
|
|
}
|
|
}
|
|
if (overflowed) {
|
|
return -12;
|
|
}
|
|
return 0;
|
|
};
|
|
_getnameinfo.sig = 'ipipipii';
|
|
var Protocols = { list: [], map: {} };
|
|
var stringToAscii = (str, buffer) => {
|
|
for (var i = 0; i < str.length; ++i) {
|
|
HEAP8[buffer++] = str.charCodeAt(i);
|
|
}
|
|
HEAP8[buffer] = 0;
|
|
};
|
|
var _setprotoent = (stayopen) => {
|
|
function allocprotoent(name, proto, aliases) {
|
|
var nameBuf = _malloc(name.length + 1);
|
|
stringToAscii(name, nameBuf);
|
|
var j = 0;
|
|
var length = aliases.length;
|
|
var aliasListBuf = _malloc((length + 1) * 4);
|
|
for (var i = 0; i < length; i++, j += 4) {
|
|
var alias = aliases[i];
|
|
var aliasBuf = _malloc(alias.length + 1);
|
|
stringToAscii(alias, aliasBuf);
|
|
HEAPU32[(aliasListBuf + j) >> 2] = aliasBuf;
|
|
}
|
|
HEAPU32[(aliasListBuf + j) >> 2] = 0;
|
|
var pe = _malloc(12);
|
|
HEAPU32[pe >> 2] = nameBuf;
|
|
HEAPU32[(pe + 4) >> 2] = aliasListBuf;
|
|
HEAP32[(pe + 8) >> 2] = proto;
|
|
return pe;
|
|
}
|
|
var list = Protocols.list;
|
|
var map = Protocols.map;
|
|
if (list.length === 0) {
|
|
var entry = allocprotoent('tcp', 6, ['TCP']);
|
|
list.push(entry);
|
|
map['tcp'] = map['6'] = entry;
|
|
entry = allocprotoent('udp', 17, ['UDP']);
|
|
list.push(entry);
|
|
map['udp'] = map['17'] = entry;
|
|
}
|
|
_setprotoent.index = 0;
|
|
};
|
|
_setprotoent.sig = 'vi';
|
|
var _getprotobyname = (name) => {
|
|
name = UTF8ToString(name);
|
|
_setprotoent(true);
|
|
var result = Protocols.map[name];
|
|
return result;
|
|
};
|
|
_getprotobyname.sig = 'pp';
|
|
var _getprotobynumber = (number) => {
|
|
_setprotoent(true);
|
|
var result = Protocols.map[number];
|
|
return result;
|
|
};
|
|
_getprotobynumber.sig = 'pi';
|
|
function _js_open_process(
|
|
command,
|
|
argsPtr,
|
|
argsLength,
|
|
descriptorsPtr,
|
|
descriptorsLength,
|
|
cwdPtr,
|
|
cwdLength,
|
|
envPtr,
|
|
envLength
|
|
) {
|
|
if (!command) {
|
|
___errno_location(ERRNO_CODES.EINVAL);
|
|
return -1;
|
|
}
|
|
const cmdstr = UTF8ToString(command);
|
|
if (!cmdstr.length) {
|
|
___errno_location(ERRNO_CODES.EINVAL);
|
|
return -1;
|
|
}
|
|
let argsArray = [];
|
|
if (argsLength) {
|
|
for (var i = 0; i < argsLength; i++) {
|
|
const charPointer = argsPtr + i * 4;
|
|
argsArray.push(UTF8ToString(HEAPU32[charPointer >> 2]));
|
|
}
|
|
}
|
|
const cwdstr = cwdPtr ? UTF8ToString(cwdPtr) : FS.cwd();
|
|
let envObject = null;
|
|
if (envLength) {
|
|
envObject = {};
|
|
for (var i = 0; i < envLength; i++) {
|
|
const envPointer = envPtr + i * 4;
|
|
const envEntry = UTF8ToString(HEAPU32[envPointer >> 2]);
|
|
const splitAt = envEntry.indexOf('=');
|
|
if (splitAt === -1) {
|
|
continue;
|
|
}
|
|
const key = envEntry.substring(0, splitAt);
|
|
const value = envEntry.substring(splitAt + 1);
|
|
envObject[key] = value;
|
|
}
|
|
}
|
|
var std = {};
|
|
for (var i = 0; i < descriptorsLength; i++) {
|
|
const descriptorPtr = HEAPU32[(descriptorsPtr + i * 4) >> 2];
|
|
std[HEAPU32[descriptorPtr >> 2]] = {
|
|
child: HEAPU32[(descriptorPtr + 4) >> 2],
|
|
parent: HEAPU32[(descriptorPtr + 8) >> 2],
|
|
};
|
|
if (i === 0) {
|
|
HEAPU32[(descriptorPtr + 8) >> 2] =
|
|
std[HEAPU32[descriptorPtr >> 2]].parent;
|
|
HEAPU32[(descriptorPtr + 4) >> 2] =
|
|
std[HEAPU32[descriptorPtr >> 2]].child;
|
|
}
|
|
}
|
|
return Asyncify.handleAsync(async () => {
|
|
let cp;
|
|
try {
|
|
const options = {};
|
|
if (cwdstr !== null) {
|
|
options.cwd = cwdstr;
|
|
}
|
|
if (envObject !== null) {
|
|
options.env = envObject;
|
|
}
|
|
cp = PHPWASM.spawnProcess(cmdstr, argsArray, options);
|
|
if (cp instanceof Promise) {
|
|
cp = await cp;
|
|
}
|
|
} catch (e) {
|
|
if (e.code === 'SPAWN_UNSUPPORTED') {
|
|
___errno_location(ERRNO_CODES.ENOSYS);
|
|
return -1;
|
|
}
|
|
if (typeof FS == 'undefined' || !(e.name === 'ErrnoError'))
|
|
throw e;
|
|
___errno_location(e.code);
|
|
return -1;
|
|
}
|
|
const ProcInfo = { pid: cp.pid, exited: false };
|
|
PHPWASM.processTable[ProcInfo.pid] = ProcInfo;
|
|
const stdinParentFd = std[0]?.parent,
|
|
stdinChildFd = std[0]?.child,
|
|
stdoutChildFd = std[1]?.child,
|
|
stdoutParentFd = std[1]?.parent,
|
|
stderrChildFd = std[2]?.child,
|
|
stderrParentFd = std[2]?.parent;
|
|
const detachPipeDataListeners = [];
|
|
cp.on('exit', function (code) {
|
|
for (const detach of detachPipeDataListeners) {
|
|
detach();
|
|
}
|
|
for (const fd of [stdoutChildFd, stderrChildFd, stdinChildFd]) {
|
|
if (FS.streams[fd] && !FS.isClosed(FS.streams[fd])) {
|
|
FS.close(FS.streams[fd]);
|
|
}
|
|
}
|
|
ProcInfo.exitCode = code;
|
|
ProcInfo.exited = true;
|
|
});
|
|
if (stdoutChildFd) {
|
|
const stdoutStream = SYSCALLS.getStreamFromFD(stdoutChildFd);
|
|
let stdoutAt = 0;
|
|
const onStdoutData = function (data) {
|
|
try {
|
|
stdoutStream.stream_ops.write(
|
|
stdoutStream,
|
|
data,
|
|
0,
|
|
data.length,
|
|
stdoutAt
|
|
);
|
|
stdoutAt += data.length;
|
|
} catch {
|
|
cp.stdout.off('data', onStdoutData);
|
|
}
|
|
};
|
|
cp.stdout.on('data', onStdoutData);
|
|
detachPipeDataListeners.push(() =>
|
|
cp.stdout.off('data', onStdoutData)
|
|
);
|
|
}
|
|
if (stderrChildFd) {
|
|
const stderrStream = SYSCALLS.getStreamFromFD(stderrChildFd);
|
|
let stderrAt = 0;
|
|
const onStderrData = function (data) {
|
|
try {
|
|
stderrStream.stream_ops.write(
|
|
stderrStream,
|
|
data,
|
|
0,
|
|
data.length,
|
|
stderrAt
|
|
);
|
|
stderrAt += data.length;
|
|
} catch {
|
|
cp.stderr.off('data', onStderrData);
|
|
}
|
|
};
|
|
cp.stderr.on('data', onStderrData);
|
|
detachPipeDataListeners.push(() =>
|
|
cp.stderr.off('data', onStderrData)
|
|
);
|
|
}
|
|
try {
|
|
await new Promise((resolve, reject) => {
|
|
let resolved = false;
|
|
cp.on('spawn', () => {
|
|
if (resolved) return;
|
|
resolved = true;
|
|
resolve();
|
|
});
|
|
cp.on('error', (e) => {
|
|
if (resolved) return;
|
|
resolved = true;
|
|
reject(e);
|
|
});
|
|
cp.on('exit', function (code) {
|
|
if (resolved) return;
|
|
resolved = true;
|
|
if (code === 0) {
|
|
resolve();
|
|
} else {
|
|
reject(
|
|
new Error(`Process exited with code ${code}`)
|
|
);
|
|
}
|
|
});
|
|
setTimeout(() => {
|
|
if (resolved) return;
|
|
resolved = true;
|
|
reject(new Error('Process timed out'));
|
|
}, 5e3);
|
|
});
|
|
} catch (e) {
|
|
console.error(e);
|
|
return ProcInfo.pid;
|
|
}
|
|
if (stdinChildFd) {
|
|
let stdinStream;
|
|
try {
|
|
stdinStream = SYSCALLS.getStreamFromFD(stdinChildFd);
|
|
} catch (e) {
|
|
___errno_location(ERRNO_CODES.EBADF);
|
|
return ProcInfo.pid;
|
|
}
|
|
if (!stdinStream?.node) {
|
|
return ProcInfo.pid;
|
|
}
|
|
const CHUNK_SIZE = 1024;
|
|
const iov = _malloc(16);
|
|
const pnum = _malloc(4);
|
|
const buffer = _malloc(CHUNK_SIZE);
|
|
HEAPU32[iov >> 2] = buffer;
|
|
HEAPU32[(iov + 4) >> 2] = CHUNK_SIZE;
|
|
function pump() {
|
|
try {
|
|
while (true) {
|
|
if (cp.killed) {
|
|
stopPumpingAndCloseStdin();
|
|
return;
|
|
}
|
|
const result = js_fd_read(
|
|
stdinChildFd,
|
|
iov,
|
|
1,
|
|
pnum,
|
|
false
|
|
);
|
|
const bytesRead = HEAPU32[pnum >> 2];
|
|
if (result === 0 && bytesRead > 0) {
|
|
const wrote = HEAPU8.subarray(
|
|
buffer,
|
|
buffer + bytesRead
|
|
);
|
|
cp.stdin.write(wrote);
|
|
} else if (result === 0 && bytesRead === 0) {
|
|
stopPumpingAndCloseStdin();
|
|
break;
|
|
} else if (result === ERRNO_CODES.EAGAIN) {
|
|
break;
|
|
} else {
|
|
throw new FS.ErrnoError(result);
|
|
}
|
|
}
|
|
} catch (e) {
|
|
if (
|
|
typeof FS == 'undefined' ||
|
|
!(e.name === 'ErrnoError')
|
|
) {
|
|
throw e;
|
|
}
|
|
___errno_location(e.errno);
|
|
stopPumpingAndCloseStdin();
|
|
}
|
|
}
|
|
function stopPumpingAndCloseStdin() {
|
|
clearInterval(interval);
|
|
if (!cp.stdin.closed) {
|
|
cp.stdin.end();
|
|
}
|
|
_wasm_free(buffer);
|
|
_wasm_free(iov);
|
|
_wasm_free(pnum);
|
|
}
|
|
const interval = setInterval(pump, 20);
|
|
pump();
|
|
} else {
|
|
/**
|
|
* Descriptor 0 was not provided, so the child process must observe EOF.
|
|
* Closing stdin explicitly lets spawn handlers distinguish that case from
|
|
* a valid pipe whose first bytes have not arrived yet.
|
|
*/
|
|
cp.stdin.end();
|
|
}
|
|
return ProcInfo.pid;
|
|
});
|
|
}
|
|
function _js_popen_clear_pid_for_fd(fd) {
|
|
for (const pid in PHPWASM.processTable) {
|
|
if (PHPWASM.processTable[pid].fd === fd) {
|
|
delete PHPWASM.processTable[pid].fd;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
function _js_popen_get_pid_for_fd(fd) {
|
|
for (const pid in PHPWASM.processTable) {
|
|
if (PHPWASM.processTable[pid].fd === fd) {
|
|
return PHPWASM.processTable[pid].pid;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
function _js_popen_set_pid_for_fd(fd, pid) {
|
|
if (PHPWASM.processTable[pid]) {
|
|
PHPWASM.processTable[pid].fd = fd;
|
|
}
|
|
}
|
|
function _js_process_status(pid, exitCodePtr) {
|
|
if (!PHPWASM.processTable[pid]) {
|
|
return -1;
|
|
}
|
|
if (PHPWASM.processTable[pid].exited) {
|
|
HEAPU32[exitCodePtr >> 2] = PHPWASM.processTable[pid].exitCode;
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
function _js_waitpid(pid, exitCodePtr) {
|
|
if (!PHPWASM.processTable[pid]) {
|
|
return -1;
|
|
}
|
|
return Asyncify.handleSleep((wakeUp) => {
|
|
const poll = function () {
|
|
if (PHPWASM.processTable[pid]?.exited) {
|
|
HEAPU32[exitCodePtr >> 2] =
|
|
PHPWASM.processTable[pid].exitCode;
|
|
wakeUp(pid);
|
|
} else {
|
|
setTimeout(poll, 50);
|
|
}
|
|
};
|
|
poll();
|
|
});
|
|
}
|
|
var _makecontext = () => abort('missing function: ${name}');
|
|
var arraySum = (array, index) => {
|
|
var sum = 0;
|
|
for (var i = 0; i <= index; sum += array[i++]) {}
|
|
return sum;
|
|
};
|
|
var MONTH_DAYS_LEAP = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
|
|
var MONTH_DAYS_REGULAR = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
|
|
var addDays = (date, days) => {
|
|
var newDate = new Date(date.getTime());
|
|
while (days > 0) {
|
|
var leap = isLeapYear(newDate.getFullYear());
|
|
var currentMonth = newDate.getMonth();
|
|
var daysInCurrentMonth = (
|
|
leap ? MONTH_DAYS_LEAP : MONTH_DAYS_REGULAR
|
|
)[currentMonth];
|
|
if (days > daysInCurrentMonth - newDate.getDate()) {
|
|
days -= daysInCurrentMonth - newDate.getDate() + 1;
|
|
newDate.setDate(1);
|
|
if (currentMonth < 11) {
|
|
newDate.setMonth(currentMonth + 1);
|
|
} else {
|
|
newDate.setMonth(0);
|
|
newDate.setFullYear(newDate.getFullYear() + 1);
|
|
}
|
|
} else {
|
|
newDate.setDate(newDate.getDate() + days);
|
|
return newDate;
|
|
}
|
|
}
|
|
return newDate;
|
|
};
|
|
var _strptime = (buf, format, tm) => {
|
|
var pattern = UTF8ToString(format);
|
|
var SPECIAL_CHARS = '\\!@#$^&*()+=-[]/{}|:<>?,.';
|
|
for (var i = 0, ii = SPECIAL_CHARS.length; i < ii; ++i) {
|
|
pattern = pattern.replace(
|
|
new RegExp('\\' + SPECIAL_CHARS[i], 'g'),
|
|
'\\' + SPECIAL_CHARS[i]
|
|
);
|
|
}
|
|
var EQUIVALENT_MATCHERS = {
|
|
A: '%a',
|
|
B: '%b',
|
|
c: '%a %b %d %H:%M:%S %Y',
|
|
D: '%m\\/%d\\/%y',
|
|
e: '%d',
|
|
F: '%Y-%m-%d',
|
|
h: '%b',
|
|
R: '%H\\:%M',
|
|
r: '%I\\:%M\\:%S\\s%p',
|
|
T: '%H\\:%M\\:%S',
|
|
x: '%m\\/%d\\/(?:%y|%Y)',
|
|
X: '%H\\:%M\\:%S',
|
|
};
|
|
var DATE_PATTERNS = {
|
|
a: '(?:Sun(?:day)?)|(?:Mon(?:day)?)|(?:Tue(?:sday)?)|(?:Wed(?:nesday)?)|(?:Thu(?:rsday)?)|(?:Fri(?:day)?)|(?:Sat(?:urday)?)',
|
|
b: '(?:Jan(?:uary)?)|(?:Feb(?:ruary)?)|(?:Mar(?:ch)?)|(?:Apr(?:il)?)|May|(?:Jun(?:e)?)|(?:Jul(?:y)?)|(?:Aug(?:ust)?)|(?:Sep(?:tember)?)|(?:Oct(?:ober)?)|(?:Nov(?:ember)?)|(?:Dec(?:ember)?)',
|
|
C: '\\d\\d',
|
|
d: '0[1-9]|[1-9](?!\\d)|1\\d|2\\d|30|31',
|
|
H: '\\d(?!\\d)|[0,1]\\d|20|21|22|23',
|
|
I: '\\d(?!\\d)|0\\d|10|11|12',
|
|
j: '00[1-9]|0?[1-9](?!\\d)|0?[1-9]\\d(?!\\d)|[1,2]\\d\\d|3[0-6]\\d',
|
|
m: '0[1-9]|[1-9](?!\\d)|10|11|12',
|
|
M: '0\\d|\\d(?!\\d)|[1-5]\\d',
|
|
n: ' ',
|
|
p: 'AM|am|PM|pm|A\\.M\\.|a\\.m\\.|P\\.M\\.|p\\.m\\.',
|
|
S: '0\\d|\\d(?!\\d)|[1-5]\\d|60',
|
|
U: '0\\d|\\d(?!\\d)|[1-4]\\d|50|51|52|53',
|
|
W: '0\\d|\\d(?!\\d)|[1-4]\\d|50|51|52|53',
|
|
w: '[0-6]',
|
|
y: '\\d\\d',
|
|
Y: '\\d\\d\\d\\d',
|
|
t: ' ',
|
|
z: 'Z|(?:[\\+\\-]\\d\\d:?(?:\\d\\d)?)',
|
|
};
|
|
var MONTH_NUMBERS = {
|
|
JAN: 0,
|
|
FEB: 1,
|
|
MAR: 2,
|
|
APR: 3,
|
|
MAY: 4,
|
|
JUN: 5,
|
|
JUL: 6,
|
|
AUG: 7,
|
|
SEP: 8,
|
|
OCT: 9,
|
|
NOV: 10,
|
|
DEC: 11,
|
|
};
|
|
var DAY_NUMBERS_SUN_FIRST = {
|
|
SUN: 0,
|
|
MON: 1,
|
|
TUE: 2,
|
|
WED: 3,
|
|
THU: 4,
|
|
FRI: 5,
|
|
SAT: 6,
|
|
};
|
|
var DAY_NUMBERS_MON_FIRST = {
|
|
MON: 0,
|
|
TUE: 1,
|
|
WED: 2,
|
|
THU: 3,
|
|
FRI: 4,
|
|
SAT: 5,
|
|
SUN: 6,
|
|
};
|
|
var capture = [];
|
|
var pattern_out = pattern
|
|
.replace(/%(.)/g, (m, c) => EQUIVALENT_MATCHERS[c] || m)
|
|
.replace(/%(.)/g, (_, c) => {
|
|
let pat = DATE_PATTERNS[c];
|
|
if (pat) {
|
|
capture.push(c);
|
|
return `(${pat})`;
|
|
} else {
|
|
return c;
|
|
}
|
|
})
|
|
.replace(/\s+/g, '\\s*');
|
|
var matches = new RegExp('^' + pattern_out, 'i').exec(
|
|
UTF8ToString(buf)
|
|
);
|
|
function initDate() {
|
|
function fixup(value, min, max) {
|
|
return typeof value != 'number' || isNaN(value)
|
|
? min
|
|
: value >= min
|
|
? value <= max
|
|
? value
|
|
: max
|
|
: min;
|
|
}
|
|
return {
|
|
year: fixup(HEAP32[(tm + 20) >> 2] + 1900, 1970, 9999),
|
|
month: fixup(HEAP32[(tm + 16) >> 2], 0, 11),
|
|
day: fixup(HEAP32[(tm + 12) >> 2], 1, 31),
|
|
hour: fixup(HEAP32[(tm + 8) >> 2], 0, 23),
|
|
min: fixup(HEAP32[(tm + 4) >> 2], 0, 59),
|
|
sec: fixup(HEAP32[tm >> 2], 0, 59),
|
|
gmtoff: 0,
|
|
};
|
|
}
|
|
if (matches) {
|
|
var date = initDate();
|
|
var value;
|
|
var getMatch = (symbol) => {
|
|
var pos = capture.indexOf(symbol);
|
|
if (pos >= 0) {
|
|
return matches[pos + 1];
|
|
}
|
|
return;
|
|
};
|
|
if ((value = getMatch('S'))) {
|
|
date.sec = Number(value);
|
|
}
|
|
if ((value = getMatch('M'))) {
|
|
date.min = Number(value);
|
|
}
|
|
if ((value = getMatch('H'))) {
|
|
date.hour = Number(value);
|
|
} else if ((value = getMatch('I'))) {
|
|
var hour = Number(value);
|
|
if ((value = getMatch('p'))) {
|
|
hour += value.toUpperCase()[0] === 'P' ? 12 : 0;
|
|
}
|
|
date.hour = hour;
|
|
}
|
|
if ((value = getMatch('Y'))) {
|
|
date.year = Number(value);
|
|
} else if ((value = getMatch('y'))) {
|
|
var year = Number(value);
|
|
if ((value = getMatch('C'))) {
|
|
year += Number(value) * 100;
|
|
} else {
|
|
year += year < 69 ? 2e3 : 1900;
|
|
}
|
|
date.year = year;
|
|
}
|
|
if ((value = getMatch('m'))) {
|
|
date.month = Number(value) - 1;
|
|
} else if ((value = getMatch('b'))) {
|
|
date.month =
|
|
MONTH_NUMBERS[value.substring(0, 3).toUpperCase()] || 0;
|
|
}
|
|
if ((value = getMatch('d'))) {
|
|
date.day = Number(value);
|
|
} else if ((value = getMatch('j'))) {
|
|
var day = Number(value);
|
|
var leapYear = isLeapYear(date.year);
|
|
for (var month = 0; month < 12; ++month) {
|
|
var daysUntilMonth = arraySum(
|
|
leapYear ? MONTH_DAYS_LEAP : MONTH_DAYS_REGULAR,
|
|
month - 1
|
|
);
|
|
if (
|
|
day <=
|
|
daysUntilMonth +
|
|
(leapYear ? MONTH_DAYS_LEAP : MONTH_DAYS_REGULAR)[
|
|
month
|
|
]
|
|
) {
|
|
date.day = day - daysUntilMonth;
|
|
}
|
|
}
|
|
} else if ((value = getMatch('a'))) {
|
|
var weekDay = value.substring(0, 3).toUpperCase();
|
|
if ((value = getMatch('U'))) {
|
|
var weekDayNumber = DAY_NUMBERS_SUN_FIRST[weekDay];
|
|
var weekNumber = Number(value);
|
|
var janFirst = new Date(date.year, 0, 1);
|
|
var endDate;
|
|
if (janFirst.getDay() === 0) {
|
|
endDate = addDays(
|
|
janFirst,
|
|
weekDayNumber + 7 * (weekNumber - 1)
|
|
);
|
|
} else {
|
|
endDate = addDays(
|
|
janFirst,
|
|
7 -
|
|
janFirst.getDay() +
|
|
weekDayNumber +
|
|
7 * (weekNumber - 1)
|
|
);
|
|
}
|
|
date.day = endDate.getDate();
|
|
date.month = endDate.getMonth();
|
|
} else if ((value = getMatch('W'))) {
|
|
var weekDayNumber = DAY_NUMBERS_MON_FIRST[weekDay];
|
|
var weekNumber = Number(value);
|
|
var janFirst = new Date(date.year, 0, 1);
|
|
var endDate;
|
|
if (janFirst.getDay() === 1) {
|
|
endDate = addDays(
|
|
janFirst,
|
|
weekDayNumber + 7 * (weekNumber - 1)
|
|
);
|
|
} else {
|
|
endDate = addDays(
|
|
janFirst,
|
|
7 -
|
|
janFirst.getDay() +
|
|
1 +
|
|
weekDayNumber +
|
|
7 * (weekNumber - 1)
|
|
);
|
|
}
|
|
date.day = endDate.getDate();
|
|
date.month = endDate.getMonth();
|
|
}
|
|
}
|
|
if ((value = getMatch('z'))) {
|
|
if (value.toLowerCase() === 'z') {
|
|
date.gmtoff = 0;
|
|
} else {
|
|
var match = value.match(/^((?:\-|\+)\d\d):?(\d\d)?/);
|
|
date.gmtoff = match[1] * 3600;
|
|
if (match[2]) {
|
|
date.gmtoff +=
|
|
date.gmtoff > 0 ? match[2] * 60 : -match[2] * 60;
|
|
}
|
|
}
|
|
}
|
|
var fullDate = new Date(
|
|
date.year,
|
|
date.month,
|
|
date.day,
|
|
date.hour,
|
|
date.min,
|
|
date.sec,
|
|
0
|
|
);
|
|
HEAP32[tm >> 2] = fullDate.getSeconds();
|
|
HEAP32[(tm + 4) >> 2] = fullDate.getMinutes();
|
|
HEAP32[(tm + 8) >> 2] = fullDate.getHours();
|
|
HEAP32[(tm + 12) >> 2] = fullDate.getDate();
|
|
HEAP32[(tm + 16) >> 2] = fullDate.getMonth();
|
|
HEAP32[(tm + 20) >> 2] = fullDate.getFullYear() - 1900;
|
|
HEAP32[(tm + 24) >> 2] = fullDate.getDay();
|
|
HEAP32[(tm + 28) >> 2] =
|
|
arraySum(
|
|
isLeapYear(fullDate.getFullYear())
|
|
? MONTH_DAYS_LEAP
|
|
: MONTH_DAYS_REGULAR,
|
|
fullDate.getMonth() - 1
|
|
) +
|
|
fullDate.getDate() -
|
|
1;
|
|
HEAP32[(tm + 32) >> 2] = 0;
|
|
HEAP32[(tm + 36) >> 2] = date.gmtoff;
|
|
return buf + lengthBytesUTF8(matches[0]);
|
|
}
|
|
return 0;
|
|
};
|
|
_strptime.sig = 'pppp';
|
|
var _swapcontext = () => abort('missing function: ${name}');
|
|
function _wasm_close(socketd) {
|
|
return PHPWASM.shutdownSocket(socketd, 2);
|
|
}
|
|
function _wasm_setsockopt(
|
|
socketd,
|
|
level,
|
|
optionName,
|
|
optionValuePtr,
|
|
optionLen
|
|
) {
|
|
const optionValue = HEAPU8[optionValuePtr];
|
|
const SOL_SOCKET = 1;
|
|
const SO_KEEPALIVE = 9;
|
|
const SO_RCVTIMEO = 66;
|
|
const SO_SNDTIMEO = 67;
|
|
const IPPROTO_TCP = 6;
|
|
const TCP_NODELAY = 1;
|
|
if (
|
|
level === SOL_SOCKET &&
|
|
(optionName === SO_RCVTIMEO || optionName === SO_SNDTIMEO)
|
|
) {
|
|
const timeoutMs = PHPWASM.parseSocketTimeout(
|
|
optionValuePtr,
|
|
optionLen
|
|
);
|
|
if (timeoutMs === null) {
|
|
return -1;
|
|
}
|
|
const timeouts = PHPWASM.socketTimeouts.get(socketd) || {};
|
|
if (optionName === SO_RCVTIMEO) {
|
|
timeouts.receive = timeoutMs;
|
|
} else {
|
|
timeouts.send = timeoutMs;
|
|
}
|
|
PHPWASM.socketTimeouts.set(socketd, timeouts);
|
|
return 0;
|
|
}
|
|
const isForwardable =
|
|
(level === SOL_SOCKET && optionName === SO_KEEPALIVE) ||
|
|
(level === IPPROTO_TCP && optionName === TCP_NODELAY);
|
|
if (!isForwardable) {
|
|
console.warn(
|
|
`Unsupported socket option: ${level}, ${optionName}, ${optionValue}`
|
|
);
|
|
return -1;
|
|
}
|
|
const ws = PHPWASM.getAllWebSockets(socketd)[0];
|
|
if (!ws) {
|
|
return -1;
|
|
}
|
|
ws.setSocketOpt(level, optionName, optionValuePtr);
|
|
return 0;
|
|
}
|
|
function _wasm_shutdown(socketd, how) {
|
|
return PHPWASM.shutdownSocket(socketd, how);
|
|
}
|
|
var runAndAbortIfError = (func) => {
|
|
try {
|
|
return func();
|
|
} catch (e) {
|
|
abort(e);
|
|
}
|
|
};
|
|
var Asyncify = {
|
|
instrumentWasmImports(imports) {
|
|
var importPattern =
|
|
/^(invoke_i|invoke_ii|invoke_iii|invoke_iiii|invoke_iiiii|invoke_iiiiii|invoke_iiiiiii|invoke_iiiiiiii|invoke_iiiiiiiii|invoke_iiiiiiiiii|invoke_v|invoke_vi|invoke_vii|invoke_viidii|invoke_viii|invoke_viiii|invoke_viiiii|invoke_viiiiii|invoke_viiiiiii|invoke_viiiiiiiii|invoke_i|invoke_ii|invoke_iii|invoke_iiii|invoke_iiiii|invoke_iiiiii|invoke_iiiiiii|invoke_iiiiiiii|invoke_iiiiiiiiii|invoke_iij|invoke_iiji|invoke_iiij|invoke_iijii|invoke_iijiji|invoke_jii|invoke_jiii|invoke_viijii|invoke_vji|js_open_process|_js_open_process|_asyncjs__js_open_process|js_popen_to_file|_js_popen_to_file|_asyncjs__js_popen_to_file|__syscall_fcntl64|___syscall_fcntl64|_asyncjs___syscall_fcntl64|js_release_file_locks|_js_release_file_locks|_async_js_release_file_locks|js_flock|_js_flock|_async_js_flock|js_fd_read|_js_fd_read|fd_close|_fd_close|_asyncjs__fd_close|close|_close|js_module_onMessage|zend_hash_str_find|_js_module_onMessage|_asyncjs__js_module_onMessage|js_waitpid|_js_waitpid|_asyncjs__js_waitpid|wasm_poll_socket|_wasm_poll_socket|_asyncjs__wasm_poll_socket|_wasm_shutdown|_asyncjs__wasm_shutdown|recv|_recv|setsockopt|_setsockopt|wasm_connect|_wasm_connect|__asyncjs__.*)$/;
|
|
for (let [x, original] of Object.entries(imports)) {
|
|
if (typeof original == 'function') {
|
|
let isAsyncifyImport =
|
|
original.isAsync || importPattern.test(x);
|
|
}
|
|
}
|
|
},
|
|
instrumentFunction(original) {
|
|
var wrapper = (...args) => {
|
|
Asyncify.exportCallStack.push(original);
|
|
try {
|
|
return original(...args);
|
|
} finally {
|
|
if (!ABORT) {
|
|
var top = Asyncify.exportCallStack.pop();
|
|
Asyncify.maybeStopUnwind();
|
|
}
|
|
}
|
|
};
|
|
Asyncify.funcWrappers.set(original, wrapper);
|
|
wrapper.orig = original;
|
|
return wrapper;
|
|
},
|
|
instrumentWasmExports(exports) {
|
|
var ret = {};
|
|
for (let [x, original] of Object.entries(exports)) {
|
|
if (typeof original == 'function') {
|
|
var wrapper = Asyncify.instrumentFunction(original);
|
|
ret[x] = wrapper;
|
|
} else {
|
|
ret[x] = original;
|
|
}
|
|
}
|
|
return ret;
|
|
},
|
|
State: { Normal: 0, Unwinding: 1, Rewinding: 2, Disabled: 3 },
|
|
state: 0,
|
|
StackSize: 4096,
|
|
currData: null,
|
|
handleSleepReturnValue: 0,
|
|
exportCallStack: [],
|
|
callstackFuncToId: new Map(),
|
|
callStackIdToFunc: new Map(),
|
|
funcWrappers: new Map(),
|
|
callStackId: 0,
|
|
asyncPromiseHandlers: null,
|
|
sleepCallbacks: [],
|
|
getCallStackId(func) {
|
|
if (!Asyncify.callstackFuncToId.has(func)) {
|
|
var id = Asyncify.callStackId++;
|
|
Asyncify.callstackFuncToId.set(func, id);
|
|
Asyncify.callStackIdToFunc.set(id, func);
|
|
}
|
|
return Asyncify.callstackFuncToId.get(func);
|
|
},
|
|
maybeStopUnwind() {
|
|
if (
|
|
Asyncify.currData &&
|
|
Asyncify.state === Asyncify.State.Unwinding &&
|
|
Asyncify.exportCallStack.length === 0
|
|
) {
|
|
Asyncify.state = Asyncify.State.Normal;
|
|
runtimeKeepalivePush();
|
|
runAndAbortIfError(_asyncify_stop_unwind);
|
|
if (typeof Fibers != 'undefined') {
|
|
Fibers.trampoline();
|
|
}
|
|
}
|
|
},
|
|
whenDone() {
|
|
return new Promise((resolve, reject) => {
|
|
Asyncify.asyncPromiseHandlers = { resolve, reject };
|
|
});
|
|
},
|
|
allocateData() {
|
|
var ptr = _malloc(12 + Asyncify.StackSize);
|
|
Asyncify.setDataHeader(ptr, ptr + 12, Asyncify.StackSize);
|
|
Asyncify.setDataRewindFunc(ptr);
|
|
return ptr;
|
|
},
|
|
setDataHeader(ptr, stack, stackSize) {
|
|
HEAPU32[ptr >> 2] = stack;
|
|
HEAPU32[(ptr + 4) >> 2] = stack + stackSize;
|
|
},
|
|
setDataRewindFunc(ptr) {
|
|
var bottomOfCallStack = Asyncify.exportCallStack[0];
|
|
var rewindId = Asyncify.getCallStackId(bottomOfCallStack);
|
|
HEAP32[(ptr + 8) >> 2] = rewindId;
|
|
},
|
|
getDataRewindFunc(ptr) {
|
|
var id = HEAP32[(ptr + 8) >> 2];
|
|
var func = Asyncify.callStackIdToFunc.get(id);
|
|
return func;
|
|
},
|
|
doRewind(ptr) {
|
|
var original = Asyncify.getDataRewindFunc(ptr);
|
|
var func = Asyncify.funcWrappers.get(original);
|
|
runtimeKeepalivePop();
|
|
return func();
|
|
},
|
|
handleSleep(startAsync) {
|
|
if (ABORT) return;
|
|
if (Asyncify.state === Asyncify.State.Normal) {
|
|
var reachedCallback = false;
|
|
var reachedAfterCallback = false;
|
|
startAsync((handleSleepReturnValue = 0) => {
|
|
if (ABORT) return;
|
|
Asyncify.handleSleepReturnValue = handleSleepReturnValue;
|
|
reachedCallback = true;
|
|
if (!reachedAfterCallback) {
|
|
return;
|
|
}
|
|
Asyncify.state = Asyncify.State.Rewinding;
|
|
runAndAbortIfError(() =>
|
|
_asyncify_start_rewind(Asyncify.currData)
|
|
);
|
|
if (typeof MainLoop != 'undefined' && MainLoop.func) {
|
|
MainLoop.resume();
|
|
}
|
|
var asyncWasmReturnValue,
|
|
isError = false;
|
|
try {
|
|
asyncWasmReturnValue = Asyncify.doRewind(
|
|
Asyncify.currData
|
|
);
|
|
} catch (err) {
|
|
asyncWasmReturnValue = err;
|
|
isError = true;
|
|
}
|
|
var handled = false;
|
|
if (!Asyncify.currData) {
|
|
var asyncPromiseHandlers =
|
|
Asyncify.asyncPromiseHandlers;
|
|
if (asyncPromiseHandlers) {
|
|
Asyncify.asyncPromiseHandlers = null;
|
|
(isError
|
|
? asyncPromiseHandlers.reject
|
|
: asyncPromiseHandlers.resolve)(
|
|
asyncWasmReturnValue
|
|
);
|
|
handled = true;
|
|
}
|
|
}
|
|
if (isError && !handled) {
|
|
throw asyncWasmReturnValue;
|
|
}
|
|
});
|
|
reachedAfterCallback = true;
|
|
if (!reachedCallback) {
|
|
Asyncify.state = Asyncify.State.Unwinding;
|
|
if (!Asyncify._cachedData) {
|
|
Asyncify._cachedData = Asyncify.allocateData();
|
|
} else {
|
|
Asyncify.setDataHeader(
|
|
Asyncify._cachedData,
|
|
Asyncify._cachedData + 12,
|
|
Asyncify.StackSize
|
|
);
|
|
Asyncify.setDataRewindFunc(Asyncify._cachedData);
|
|
}
|
|
Asyncify.currData = Asyncify._cachedData;
|
|
if (typeof MainLoop != 'undefined' && MainLoop.func) {
|
|
MainLoop.pause();
|
|
}
|
|
runAndAbortIfError(() =>
|
|
_asyncify_start_unwind(Asyncify.currData)
|
|
);
|
|
}
|
|
} else if (Asyncify.state === Asyncify.State.Rewinding) {
|
|
Asyncify.state = Asyncify.State.Normal;
|
|
runAndAbortIfError(_asyncify_stop_rewind);
|
|
Asyncify.currData = null;
|
|
Asyncify.sleepCallbacks.forEach(callUserCallback);
|
|
} else {
|
|
abort(`invalid state: ${Asyncify.state}`);
|
|
}
|
|
return Asyncify.handleSleepReturnValue;
|
|
},
|
|
handleAsync: (startAsync) =>
|
|
Asyncify.handleSleep((wakeUp) => {
|
|
startAsync().then(wakeUp);
|
|
}),
|
|
};
|
|
var getCFunc = (ident) => {
|
|
var func = Module['_' + ident];
|
|
return func;
|
|
};
|
|
var writeArrayToMemory = (array, buffer) => {
|
|
HEAP8.set(array, buffer);
|
|
};
|
|
var ccall = (ident, returnType, argTypes, args, opts) => {
|
|
var toC = {
|
|
string: (str) => {
|
|
var ret = 0;
|
|
if (str !== null && str !== undefined && str !== 0) {
|
|
ret = stringToUTF8OnStack(str);
|
|
}
|
|
return ret;
|
|
},
|
|
array: (arr) => {
|
|
var ret = stackAlloc(arr.length);
|
|
writeArrayToMemory(arr, ret);
|
|
return ret;
|
|
},
|
|
};
|
|
function convertReturnValue(ret) {
|
|
if (returnType === 'string') {
|
|
return UTF8ToString(ret);
|
|
}
|
|
if (returnType === 'boolean') return Boolean(ret);
|
|
return ret;
|
|
}
|
|
var func = getCFunc(ident);
|
|
var cArgs = [];
|
|
var stack = 0;
|
|
if (args) {
|
|
for (var i = 0; i < args.length; i++) {
|
|
var converter = toC[argTypes[i]];
|
|
if (converter) {
|
|
if (stack === 0) stack = stackSave();
|
|
cArgs[i] = converter(args[i]);
|
|
} else {
|
|
cArgs[i] = args[i];
|
|
}
|
|
}
|
|
}
|
|
var previousAsync = Asyncify.currData;
|
|
var ret = func(...cArgs);
|
|
function onDone(ret) {
|
|
runtimeKeepalivePop();
|
|
if (stack !== 0) stackRestore(stack);
|
|
return convertReturnValue(ret);
|
|
}
|
|
var asyncMode = opts?.async;
|
|
runtimeKeepalivePush();
|
|
if (Asyncify.currData != previousAsync) {
|
|
return Asyncify.whenDone().then(onDone);
|
|
}
|
|
ret = onDone(ret);
|
|
if (asyncMode) return Promise.resolve(ret);
|
|
return ret;
|
|
};
|
|
var FS_createPath = (...args) => FS.createPath(...args);
|
|
var FS_unlink = (...args) => FS.unlink(...args);
|
|
var FS_createLazyFile = (...args) => FS.createLazyFile(...args);
|
|
var FS_createDevice = (...args) => FS.createDevice(...args);
|
|
class ExceptionInfo {
|
|
constructor(excPtr) {
|
|
this.excPtr = excPtr;
|
|
this.ptr = excPtr - 24;
|
|
}
|
|
set_type(type) {
|
|
HEAPU32[(this.ptr + 4) >> 2] = type;
|
|
}
|
|
get_type() {
|
|
return HEAPU32[(this.ptr + 4) >> 2];
|
|
}
|
|
set_destructor(destructor) {
|
|
HEAPU32[(this.ptr + 8) >> 2] = destructor;
|
|
}
|
|
get_destructor() {
|
|
return HEAPU32[(this.ptr + 8) >> 2];
|
|
}
|
|
set_caught(caught) {
|
|
caught = caught ? 1 : 0;
|
|
HEAP8[this.ptr + 12] = caught;
|
|
}
|
|
get_caught() {
|
|
return HEAP8[this.ptr + 12] != 0;
|
|
}
|
|
set_rethrown(rethrown) {
|
|
rethrown = rethrown ? 1 : 0;
|
|
HEAP8[this.ptr + 13] = rethrown;
|
|
}
|
|
get_rethrown() {
|
|
return HEAP8[this.ptr + 13] != 0;
|
|
}
|
|
init(type, destructor) {
|
|
this.set_adjusted_ptr(0);
|
|
this.set_type(type);
|
|
this.set_destructor(destructor);
|
|
}
|
|
set_adjusted_ptr(adjustedPtr) {
|
|
HEAPU32[(this.ptr + 16) >> 2] = adjustedPtr;
|
|
}
|
|
get_adjusted_ptr() {
|
|
return HEAPU32[(this.ptr + 16) >> 2];
|
|
}
|
|
}
|
|
var exceptionLast = 0;
|
|
var uncaughtExceptionCount = 0;
|
|
var ___cxa_throw = (ptr, type, destructor) => {
|
|
var info = new ExceptionInfo(ptr);
|
|
info.init(type, destructor);
|
|
exceptionLast = ptr;
|
|
uncaughtExceptionCount++;
|
|
throw exceptionLast;
|
|
};
|
|
___cxa_throw.sig = 'vppp';
|
|
registerWasmPlugin();
|
|
FS.createPreloadedFile = FS_createPreloadedFile;
|
|
FS.preloadFile = FS_preloadFile;
|
|
FS.staticInit();
|
|
PHPWASM.init();
|
|
{
|
|
if (Module['preloadPlugins']) preloadPlugins = Module['preloadPlugins'];
|
|
if (Module['noExitRuntime']) noExitRuntime = Module['noExitRuntime'];
|
|
if (Module['print']) out = Module['print'];
|
|
if (Module['printErr']) err = Module['printErr'];
|
|
if (Module['dynamicLibraries'])
|
|
dynamicLibraries = Module['dynamicLibraries'];
|
|
if (Module['wasmBinary']) wasmBinary = Module['wasmBinary'];
|
|
if (Module['arguments']) arguments_ = Module['arguments'];
|
|
if (Module['thisProgram']) thisProgram = Module['thisProgram'];
|
|
if (Module['quit']) quit_ = Module['quit'];
|
|
if (Module['preInit']) {
|
|
if (typeof Module['preInit'] == 'function')
|
|
Module['preInit'] = [Module['preInit']];
|
|
while (Module['preInit'].length > 0) {
|
|
Module['preInit'].shift()();
|
|
}
|
|
}
|
|
}
|
|
Module['wasmExports'] = wasmExports;
|
|
Module['addRunDependency'] = addRunDependency;
|
|
Module['removeRunDependency'] = removeRunDependency;
|
|
Module['ccall'] = ccall;
|
|
Module['UTF8ToString'] = UTF8ToString;
|
|
Module['stringToUTF8'] = stringToUTF8;
|
|
Module['lengthBytesUTF8'] = lengthBytesUTF8;
|
|
Module['FS_preloadFile'] = FS_preloadFile;
|
|
Module['FS_unlink'] = FS_unlink;
|
|
Module['FS_createPath'] = FS_createPath;
|
|
Module['FS_createDevice'] = FS_createDevice;
|
|
Module['FS_createDataFile'] = FS_createDataFile;
|
|
Module['FS_createLazyFile'] = FS_createLazyFile;
|
|
Module['PROXYFS'] = PROXYFS;
|
|
Module['UTF8ToString'] = UTF8ToString;
|
|
Module['lengthBytesUTF8'] = lengthBytesUTF8;
|
|
Module['stringToUTF8'] = stringToUTF8;
|
|
Module['FS'] = FS;
|
|
Module['___assert_fail'] = ___assert_fail;
|
|
Module['___asyncify_data'] = ___asyncify_data;
|
|
Module['___asyncify_state'] = ___asyncify_state;
|
|
Module['_exit'] = _exit;
|
|
Module['_emscripten_sleep'] = _emscripten_sleep;
|
|
Module['___cxa_throw'] = ___cxa_throw;
|
|
var ASM_CONSTS = {};
|
|
function js_popen_to_file(command, mode, exitCodePtr) {
|
|
const returnCallback = (resolver) => Asyncify.handleSleep(resolver);
|
|
if (!command) return 1;
|
|
const cmdstr = UTF8ToString(command);
|
|
if (!cmdstr.length) return 0;
|
|
const modestr = UTF8ToString(mode);
|
|
if (!modestr.length) return 0;
|
|
if (modestr === 'w') {
|
|
console.error('popen($cmd, "w") is not implemented yet');
|
|
}
|
|
return returnCallback(async (wakeUp) => {
|
|
let cp;
|
|
try {
|
|
cp = PHPWASM.spawnProcess(cmdstr, []);
|
|
if (cp instanceof Promise) {
|
|
cp = await cp;
|
|
}
|
|
} catch (e) {
|
|
console.error(e);
|
|
if (e.code === 'SPAWN_UNSUPPORTED') {
|
|
return 1;
|
|
}
|
|
throw e;
|
|
}
|
|
const outByteArrays = [];
|
|
cp.stdout.on('data', function (data) {
|
|
outByteArrays.push(data);
|
|
});
|
|
const outputPath = '/tmp/popen_output';
|
|
cp.on('exit', function (exitCode) {
|
|
const outBytes = new Uint8Array(
|
|
outByteArrays.reduce((acc, curr) => acc + curr.length, 0)
|
|
);
|
|
let offset = 0;
|
|
for (const byteArray of outByteArrays) {
|
|
outBytes.set(byteArray, offset);
|
|
offset += byteArray.length;
|
|
}
|
|
FS.writeFile(outputPath, outBytes);
|
|
HEAPU8[exitCodePtr] = exitCode;
|
|
wakeUp(allocateUTF8OnStack(outputPath));
|
|
});
|
|
});
|
|
}
|
|
js_popen_to_file.sig = 'iiii';
|
|
function wasm_poll_socket(socketd, events, timeout) {
|
|
const returnCallback = (resolver) => Asyncify.handleSleep(resolver);
|
|
const POLLIN = 1;
|
|
const POLLPRI = 2;
|
|
const POLLOUT = 4;
|
|
const POLLERR = 8;
|
|
const POLLHUP = 16;
|
|
const POLLNVAL = 32;
|
|
return returnCallback((wakeUp) => {
|
|
const polls = [];
|
|
const stream = FS.getStream(socketd);
|
|
if (FS.isSocket(stream?.node.mode)) {
|
|
const sock = getSocketFromFD(socketd);
|
|
if (!sock) {
|
|
wakeUp(0);
|
|
return;
|
|
}
|
|
const lookingFor = new Set();
|
|
if (events & POLLIN || events & POLLPRI) {
|
|
if (sock.server) {
|
|
for (const client of sock.pending) {
|
|
if ((client.recv_queue || []).length > 0) {
|
|
wakeUp(1);
|
|
return;
|
|
}
|
|
}
|
|
} else if ((sock.recv_queue || []).length > 0) {
|
|
wakeUp(1);
|
|
return;
|
|
}
|
|
}
|
|
const webSockets = PHPWASM.getAllWebSockets(sock);
|
|
if (!webSockets.length) {
|
|
wakeUp(0);
|
|
return;
|
|
}
|
|
for (const ws of webSockets) {
|
|
if (events & POLLIN || events & POLLPRI) {
|
|
polls.push(PHPWASM.awaitData(ws));
|
|
lookingFor.add('POLLIN');
|
|
}
|
|
if (events & POLLOUT) {
|
|
polls.push(PHPWASM.awaitConnection(ws));
|
|
lookingFor.add('POLLOUT');
|
|
}
|
|
if (
|
|
events & POLLHUP ||
|
|
events & POLLIN ||
|
|
events & POLLOUT ||
|
|
events & POLLERR
|
|
) {
|
|
polls.push(PHPWASM.awaitClose(ws));
|
|
lookingFor.add('POLLHUP');
|
|
}
|
|
if (events & POLLERR || events & POLLNVAL) {
|
|
polls.push(PHPWASM.awaitError(ws));
|
|
lookingFor.add('POLLERR');
|
|
}
|
|
}
|
|
} else if (stream?.stream_ops?.poll) {
|
|
let interrupted = false;
|
|
async function poll() {
|
|
try {
|
|
while (true) {
|
|
var mask = POLLNVAL;
|
|
mask = SYSCALLS.DEFAULT_POLLMASK;
|
|
if (FS.isClosed(stream)) {
|
|
return ERRNO_CODES.EBADF;
|
|
}
|
|
if (stream.stream_ops?.poll) {
|
|
mask = stream.stream_ops.poll(stream, -1);
|
|
}
|
|
mask &= events | POLLERR | POLLHUP;
|
|
if (mask) {
|
|
return mask;
|
|
}
|
|
if (interrupted) {
|
|
return ERRNO_CODES.ETIMEDOUT;
|
|
}
|
|
await new Promise((resolve) =>
|
|
setTimeout(resolve, 10)
|
|
);
|
|
}
|
|
} catch (e) {
|
|
if (
|
|
typeof FS == 'undefined' ||
|
|
!(e.name === 'ErrnoError')
|
|
)
|
|
throw e;
|
|
return -e.errno;
|
|
}
|
|
}
|
|
polls.push([
|
|
poll(),
|
|
() => {
|
|
interrupted = true;
|
|
},
|
|
]);
|
|
} else {
|
|
setTimeout(function () {
|
|
wakeUp(1);
|
|
}, timeout);
|
|
return;
|
|
}
|
|
if (polls.length === 0) {
|
|
console.warn(
|
|
'Unsupported poll event ' +
|
|
events +
|
|
', defaulting to setTimeout().'
|
|
);
|
|
setTimeout(function () {
|
|
wakeUp(0);
|
|
}, timeout);
|
|
return;
|
|
}
|
|
const promises = polls.map(([promise]) => promise);
|
|
const clearPolling = () => polls.forEach(([, clear]) => clear());
|
|
let awaken = false;
|
|
let timeoutId;
|
|
Promise.race(promises).then(function (results) {
|
|
if (!awaken) {
|
|
awaken = true;
|
|
wakeUp(1);
|
|
if (timeoutId) {
|
|
clearTimeout(timeoutId);
|
|
}
|
|
clearPolling();
|
|
}
|
|
});
|
|
if (timeout !== -1) {
|
|
timeoutId = setTimeout(function () {
|
|
if (!awaken) {
|
|
awaken = true;
|
|
wakeUp(0);
|
|
clearPolling();
|
|
}
|
|
}, timeout);
|
|
}
|
|
});
|
|
}
|
|
wasm_poll_socket.sig = 'iiii';
|
|
function js_fd_read(fd, iov, iovcnt, pnum) {
|
|
const returnCallback = (resolver) => Asyncify.handleSleep(resolver);
|
|
const pollAsync = arguments[4] === undefined ? true : !!arguments[4];
|
|
if (
|
|
Asyncify?.State?.Normal === undefined ||
|
|
Asyncify?.state === Asyncify?.State?.Normal
|
|
) {
|
|
var stream;
|
|
try {
|
|
stream = SYSCALLS.getStreamFromFD(fd);
|
|
HEAPU32[pnum >> 2] = doReadv(stream, iov, iovcnt);
|
|
return 0;
|
|
} catch (e) {
|
|
if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) {
|
|
throw e;
|
|
}
|
|
if (
|
|
e.errno !== ERRNO_CODES.EWOULDBLOCK &&
|
|
e.errno !== ERRNO_CODES.EAGAIN
|
|
) {
|
|
return e.errno;
|
|
}
|
|
const nonBlocking = stream.flags & PHPWASM.O_NONBLOCK;
|
|
if (nonBlocking) {
|
|
return e.errno;
|
|
}
|
|
}
|
|
}
|
|
if (false === pollAsync) {
|
|
return ERRNO_CODES.EWOULDBLOCK;
|
|
}
|
|
return returnCallback(async (wakeUp) => {
|
|
var retries = 0;
|
|
var interval = 50;
|
|
var timeout = 5e3;
|
|
var maxRetries = timeout / interval;
|
|
while (true) {
|
|
var returnCode;
|
|
var stream;
|
|
let num;
|
|
try {
|
|
stream = SYSCALLS.getStreamFromFD(fd);
|
|
num = doReadv(stream, iov, iovcnt);
|
|
returnCode = 0;
|
|
} catch (e) {
|
|
if (
|
|
typeof FS == 'undefined' ||
|
|
!(e.name === 'ErrnoError')
|
|
) {
|
|
console.error(e);
|
|
throw e;
|
|
}
|
|
returnCode = e.errno;
|
|
}
|
|
if (returnCode === 0) {
|
|
HEAPU32[pnum >> 2] = num;
|
|
return wakeUp(0);
|
|
}
|
|
if (
|
|
++retries > maxRetries ||
|
|
!stream ||
|
|
FS.isClosed(stream) ||
|
|
returnCode !== ERRNO_CODES.EWOULDBLOCK ||
|
|
('pipe' in stream.node && stream.node.pipe.refcnt < 2)
|
|
) {
|
|
HEAPU32[pnum >> 2] = num;
|
|
return wakeUp(returnCode);
|
|
}
|
|
await new Promise((resolve) => setTimeout(resolve, interval));
|
|
}
|
|
});
|
|
}
|
|
js_fd_read.sig = 'iiiii';
|
|
function __asyncjs__js_module_onMessage(data, response_buffer) {
|
|
return Asyncify.handleAsync(async () => {
|
|
if (Module['onMessage']) {
|
|
const dataStr = UTF8ToString(data);
|
|
return Module['onMessage'](dataStr)
|
|
.then((response) => {
|
|
const responseBytes =
|
|
typeof response === 'string'
|
|
? new TextEncoder().encode(response)
|
|
: response;
|
|
const responseSize = responseBytes.byteLength;
|
|
const responsePtr = _malloc(responseSize + 1);
|
|
HEAPU8.set(responseBytes, responsePtr);
|
|
HEAPU8[responsePtr + responseSize] = 0;
|
|
HEAPU8[response_buffer] = responsePtr;
|
|
HEAPU8[response_buffer + 1] = responsePtr >> 8;
|
|
HEAPU8[response_buffer + 2] = responsePtr >> 16;
|
|
HEAPU8[response_buffer + 3] = responsePtr >> 24;
|
|
return responseSize;
|
|
})
|
|
.catch((e) => {
|
|
console.error(e);
|
|
return -1;
|
|
});
|
|
}
|
|
});
|
|
}
|
|
__asyncjs__js_module_onMessage.sig = 'iii';
|
|
var _php_date_get_date_ce,
|
|
_php_date_get_interface_ce,
|
|
_php_date_get_timezone_ce,
|
|
_get_timezone_info,
|
|
_php_info_print_table_header,
|
|
_php_info_print_table_row,
|
|
_php_info_print_table_start,
|
|
_php_info_print_table_end,
|
|
_php_error_docref,
|
|
_display_ini_entries,
|
|
_ap_php_slprintf,
|
|
_ap_php_snprintf,
|
|
_ap_php_vsnprintf,
|
|
__emalloc_24,
|
|
__emalloc_32,
|
|
__emalloc_40,
|
|
__emalloc_56,
|
|
__emalloc_128,
|
|
__emalloc_160,
|
|
__efree_56,
|
|
__emalloc,
|
|
__efree,
|
|
__erealloc,
|
|
__safe_emalloc,
|
|
___zend_malloc,
|
|
__safe_erealloc,
|
|
___zend_realloc,
|
|
__ecalloc,
|
|
__estrdup,
|
|
__estrndup,
|
|
_zend_get_parameters_array_ex,
|
|
_zend_zval_value_name,
|
|
_zend_wrong_parameters_none_error,
|
|
_zend_wrong_parameters_count_error,
|
|
_zend_wrong_parameter_error,
|
|
_zend_argument_type_error,
|
|
_zend_argument_value_error,
|
|
_zend_argument_error,
|
|
_zend_argument_must_not_be_empty_error,
|
|
_zend_parse_arg_bool_slow,
|
|
_zend_flf_parse_arg_bool_slow,
|
|
_zend_parse_arg_long_slow,
|
|
_zend_flf_parse_arg_long_slow,
|
|
_zend_parse_arg_str_slow,
|
|
_zend_flf_parse_arg_str_slow,
|
|
_zend_parse_arg_str_or_long_slow,
|
|
_zend_release_fcall_info_cache,
|
|
_zend_parse_parameters,
|
|
_zend_parse_method_parameters,
|
|
_object_properties_init,
|
|
_object_init_ex,
|
|
_object_init_with_constructor,
|
|
_add_assoc_long_ex,
|
|
_add_assoc_bool_ex,
|
|
_add_assoc_str_ex,
|
|
_add_assoc_string_ex,
|
|
_add_next_index_long,
|
|
_add_next_index_str,
|
|
_add_next_index_string,
|
|
_add_next_index_stringl,
|
|
_zend_register_internal_class_with_flags,
|
|
_zend_class_implements,
|
|
_zend_fcall_info_init,
|
|
_zend_declare_typed_property,
|
|
_zend_try_assign_typed_ref_bool,
|
|
_zend_try_assign_typed_ref_long,
|
|
_zend_try_assign_typed_ref_str,
|
|
_zend_try_assign_typed_ref_arr,
|
|
_zend_declare_typed_class_constant,
|
|
_zend_update_property,
|
|
_zend_add_attribute,
|
|
_zend_register_long_constant,
|
|
_zend_register_string_constant,
|
|
_zend_throw_exception,
|
|
_zend_throw_exception_ex,
|
|
_zend_throw_error_exception,
|
|
_get_active_class_name,
|
|
_get_active_function_or_method_name,
|
|
_zend_call_function,
|
|
_zend_call_known_function,
|
|
_zend_call_known_instance_method_with_2_params,
|
|
_gc_possible_root,
|
|
_zend_get_gc_buffer_create,
|
|
_zend_get_gc_buffer_grow,
|
|
_zend_hash_str_find_ptr_lc,
|
|
_zend_hash_str_find,
|
|
__zend_hash_init,
|
|
__zend_new_array_0,
|
|
__zend_new_array,
|
|
_zend_hash_real_init_packed,
|
|
_zend_hash_update,
|
|
_zend_hash_str_update,
|
|
_zend_hash_next_index_insert,
|
|
_zend_hash_index_update,
|
|
_zend_hash_destroy,
|
|
_zend_array_destroy,
|
|
_zend_hash_copy,
|
|
_zend_hash_index_find,
|
|
_zend_hash_sort_ex,
|
|
_zend_register_ini_entries_ex,
|
|
_zend_unregister_ini_entries_ex,
|
|
_zend_alter_ini_entry,
|
|
_zend_ini_parse_quantity_warn,
|
|
_zend_ini_boolean_displayer_cb,
|
|
_OnUpdateBool,
|
|
_OnUpdateStringUnempty,
|
|
_zend_call_method,
|
|
_zend_create_internal_iterator_zval,
|
|
_zend_iterator_init,
|
|
_zend_std_get_properties,
|
|
_zend_std_compare_objects,
|
|
_zend_objects_store_del,
|
|
_zend_object_std_init,
|
|
_zend_object_std_dtor,
|
|
_zend_objects_clone_members,
|
|
__is_numeric_string_ex,
|
|
_zval_try_get_long,
|
|
_convert_to_long,
|
|
_zval_get_long_func,
|
|
_convert_to_double,
|
|
__try_convert_to_string,
|
|
_zval_get_double_func,
|
|
_zval_get_string_func,
|
|
_numeric_compare_function,
|
|
_compare_function,
|
|
_instanceof_function_slow,
|
|
_zend_str_tolower,
|
|
_zend_memnstr_ex,
|
|
_smart_str_erealloc,
|
|
_smart_str_realloc,
|
|
_zend_sort,
|
|
_zend_string_concat3,
|
|
_zend_strtod,
|
|
_zval_ptr_dtor,
|
|
_zval_ptr_safe_dtor,
|
|
_zval_add_ref,
|
|
_zend_spprintf,
|
|
_zend_error,
|
|
_zend_throw_error,
|
|
_zend_illegal_container_offset,
|
|
_zend_argument_count_error,
|
|
_zend_value_error,
|
|
_strtoll,
|
|
_strlen,
|
|
_memcmp,
|
|
_free,
|
|
_malloc,
|
|
_snprintf,
|
|
_strchr,
|
|
_dlopen,
|
|
_dlsym,
|
|
_dlclose,
|
|
_strcmp,
|
|
_getenv,
|
|
_atoi,
|
|
___errno_location,
|
|
_strrchr,
|
|
_strcasecmp,
|
|
_memchr,
|
|
_isalnum,
|
|
_fwrite,
|
|
_strncmp,
|
|
_strtok_r,
|
|
_unlink,
|
|
_fileno,
|
|
_fread,
|
|
_fclose,
|
|
_strtoul,
|
|
_strstr,
|
|
_close,
|
|
_tolower,
|
|
_fseek,
|
|
_stat,
|
|
_gettimeofday,
|
|
_fopen,
|
|
_open,
|
|
_rename,
|
|
_mkdir,
|
|
_rmdir,
|
|
_opendir,
|
|
_strncpy,
|
|
_realloc,
|
|
_localtime_r,
|
|
_strtol,
|
|
_pow,
|
|
_strtod,
|
|
_round,
|
|
_sin,
|
|
_cos,
|
|
_atan2,
|
|
_acos,
|
|
_tan,
|
|
_asin,
|
|
_atan,
|
|
_log,
|
|
_fmod,
|
|
_setlocale,
|
|
_calloc,
|
|
_qsort,
|
|
_readdir,
|
|
_closedir,
|
|
_isdigit,
|
|
_wasm_php_exec,
|
|
_php_pollfd_for,
|
|
_htons,
|
|
_ntohs,
|
|
_htonl,
|
|
_tzset,
|
|
_wasm_sleep,
|
|
_fflush,
|
|
_expf,
|
|
_abort,
|
|
_mmap,
|
|
_munmap,
|
|
_fgets,
|
|
_initgroups,
|
|
_atol,
|
|
_strcat,
|
|
_strcpy,
|
|
_ftell,
|
|
_wasm_read,
|
|
_feof,
|
|
_strncat,
|
|
___ctype_get_mb_cur_max,
|
|
___wrap_usleep,
|
|
_wasm_popen,
|
|
_wasm_pclose,
|
|
___wrap_select,
|
|
_wasm_set_sapi_name,
|
|
_wasm_set_phpini_path,
|
|
_wasm_add_cli_arg,
|
|
_run_cli,
|
|
_wasm_add_SERVER_entry,
|
|
_wasm_add_ENV_entry,
|
|
_wasm_set_query_string,
|
|
_wasm_set_path_translated,
|
|
_wasm_set_skip_shebang,
|
|
_wasm_set_request_uri,
|
|
_wasm_set_request_method,
|
|
_wasm_set_request_host,
|
|
_wasm_set_content_type,
|
|
_wasm_set_request_body,
|
|
_wasm_set_content_length,
|
|
_wasm_set_cookies,
|
|
_wasm_set_request_port,
|
|
_wasm_sapi_request_shutdown,
|
|
_wasm_sapi_handle_request,
|
|
_php_wasm_init,
|
|
_wasm_free,
|
|
_wasm_trace,
|
|
_sqlite3_auto_extension,
|
|
_sqlite3_cancel_auto_extension,
|
|
_rewind,
|
|
_modf,
|
|
___funcs_on_exit,
|
|
___cxa_atexit,
|
|
_div,
|
|
___dl_seterr,
|
|
__emscripten_find_dylib,
|
|
_mbstowcs,
|
|
_emscripten_builtin_memalign,
|
|
__emscripten_timeout,
|
|
___extenddftf2,
|
|
___letf2,
|
|
_tanhf,
|
|
_wcstombs,
|
|
_emscripten_get_sbrk_ptr,
|
|
_setThrew,
|
|
___floatunditf,
|
|
__emscripten_stack_restore,
|
|
__emscripten_stack_alloc,
|
|
_emscripten_stack_get_current,
|
|
__ZNSt3__211__call_onceERVmPvPFvS2_E,
|
|
__ZNSt3__218condition_variable10notify_allEv,
|
|
__ZNSt3__25mutex4lockEv,
|
|
__ZNSt3__25mutex6unlockEv,
|
|
___cxa_bad_typeid,
|
|
___cxa_allocate_exception,
|
|
___cxa_pure_virtual,
|
|
___dynamic_cast,
|
|
__ZNSt20bad_array_new_lengthD1Ev,
|
|
__ZNSt12length_errorD1Ev,
|
|
dynCall_vii,
|
|
dynCall_vi,
|
|
dynCall_viiiii,
|
|
dynCall_iii,
|
|
dynCall_iiii,
|
|
dynCall_ii,
|
|
dynCall_iiiii,
|
|
dynCall_iiiiii,
|
|
dynCall_iiiiiii,
|
|
dynCall_i,
|
|
dynCall_v,
|
|
dynCall_viii,
|
|
dynCall_iijii,
|
|
dynCall_viiii,
|
|
dynCall_jii,
|
|
dynCall_jiii,
|
|
dynCall_jijj,
|
|
dynCall_viiiiiiii,
|
|
dynCall_jiiiii,
|
|
dynCall_jiiii,
|
|
dynCall_iiiiiiiiii,
|
|
dynCall_vjiii,
|
|
dynCall_iiji,
|
|
dynCall_iidddd,
|
|
dynCall_iijjjj,
|
|
dynCall_ji,
|
|
dynCall_viji,
|
|
dynCall_iiij,
|
|
dynCall_vji,
|
|
dynCall_vijj,
|
|
dynCall_iij,
|
|
dynCall_iijiji,
|
|
dynCall_iiiiiiii,
|
|
dynCall_iiiij,
|
|
dynCall_jiji,
|
|
dynCall_viiij,
|
|
dynCall_viiiiiii,
|
|
dynCall_iiiiiiiii,
|
|
dynCall_viiiiii,
|
|
dynCall_viiiiiiiii,
|
|
dynCall_vidi,
|
|
dynCall_iiijii,
|
|
dynCall_iiidii,
|
|
dynCall_jiiji,
|
|
dynCall_jj,
|
|
dynCall_jiiiji,
|
|
dynCall_jiij,
|
|
dynCall_iiiji,
|
|
dynCall_ij,
|
|
dynCall_vijii,
|
|
dynCall_iiiiiij,
|
|
dynCall_iiid,
|
|
dynCall_dii,
|
|
dynCall_vid,
|
|
dynCall_vij,
|
|
dynCall_di,
|
|
dynCall_iiiiijii,
|
|
dynCall_j,
|
|
dynCall_iiiiji,
|
|
dynCall_iiiijii,
|
|
dynCall_viiji,
|
|
dynCall_viijii,
|
|
dynCall_iiiiiiiiiii,
|
|
dynCall_iiiijji,
|
|
dynCall_dd,
|
|
dynCall_ddd,
|
|
dynCall_diiii,
|
|
dynCall_diiiiiiii,
|
|
dynCall_fi,
|
|
dynCall_fii,
|
|
dynCall_iiiiiiiiiiii,
|
|
dynCall_viiiiiiiiiii,
|
|
dynCall_viiiiiiiiiiiii,
|
|
dynCall_viiiiiiiiiiiiiii,
|
|
dynCall_iiiijj,
|
|
dynCall_jiiiiiiiii,
|
|
dynCall_jiiiiii,
|
|
dynCall_jiiiiiiii,
|
|
dynCall_iidiiii,
|
|
_asyncify_start_unwind,
|
|
_asyncify_stop_unwind,
|
|
_asyncify_start_rewind,
|
|
_asyncify_stop_rewind,
|
|
memory,
|
|
___stack_pointer,
|
|
__indirect_function_table,
|
|
wasmTable,
|
|
wasmMemory;
|
|
function assignWasmExports(wasmExports) {
|
|
_php_date_get_date_ce = Module['_php_date_get_date_ce'] =
|
|
wasmExports['php_date_get_date_ce'];
|
|
_php_date_get_interface_ce = Module['_php_date_get_interface_ce'] =
|
|
wasmExports['php_date_get_interface_ce'];
|
|
_php_date_get_timezone_ce = Module['_php_date_get_timezone_ce'] =
|
|
wasmExports['php_date_get_timezone_ce'];
|
|
_get_timezone_info = Module['_get_timezone_info'] =
|
|
wasmExports['get_timezone_info'];
|
|
_php_info_print_table_header = Module['_php_info_print_table_header'] =
|
|
wasmExports['php_info_print_table_header'];
|
|
_php_info_print_table_row = Module['_php_info_print_table_row'] =
|
|
wasmExports['php_info_print_table_row'];
|
|
_php_info_print_table_start = Module['_php_info_print_table_start'] =
|
|
wasmExports['php_info_print_table_start'];
|
|
_php_info_print_table_end = Module['_php_info_print_table_end'] =
|
|
wasmExports['php_info_print_table_end'];
|
|
_php_error_docref = Module['_php_error_docref'] =
|
|
wasmExports['php_error_docref'];
|
|
_display_ini_entries = Module['_display_ini_entries'] =
|
|
wasmExports['display_ini_entries'];
|
|
_ap_php_slprintf = Module['_ap_php_slprintf'] =
|
|
wasmExports['ap_php_slprintf'];
|
|
_ap_php_snprintf = Module['_ap_php_snprintf'] =
|
|
wasmExports['ap_php_snprintf'];
|
|
_ap_php_vsnprintf = Module['_ap_php_vsnprintf'] =
|
|
wasmExports['ap_php_vsnprintf'];
|
|
__emalloc_24 = Module['__emalloc_24'] = wasmExports['_emalloc_24'];
|
|
__emalloc_32 = Module['__emalloc_32'] = wasmExports['_emalloc_32'];
|
|
__emalloc_40 = Module['__emalloc_40'] = wasmExports['_emalloc_40'];
|
|
__emalloc_56 = Module['__emalloc_56'] = wasmExports['_emalloc_56'];
|
|
__emalloc_128 = Module['__emalloc_128'] = wasmExports['_emalloc_128'];
|
|
__emalloc_160 = Module['__emalloc_160'] = wasmExports['_emalloc_160'];
|
|
__efree_56 = Module['__efree_56'] = wasmExports['_efree_56'];
|
|
__emalloc = Module['__emalloc'] = wasmExports['_emalloc'];
|
|
__efree = Module['__efree'] = wasmExports['_efree'];
|
|
__erealloc = Module['__erealloc'] = wasmExports['_erealloc'];
|
|
__safe_emalloc = Module['__safe_emalloc'] =
|
|
wasmExports['_safe_emalloc'];
|
|
___zend_malloc = Module['___zend_malloc'] =
|
|
wasmExports['__zend_malloc'];
|
|
__safe_erealloc = Module['__safe_erealloc'] =
|
|
wasmExports['_safe_erealloc'];
|
|
___zend_realloc = Module['___zend_realloc'] =
|
|
wasmExports['__zend_realloc'];
|
|
__ecalloc = Module['__ecalloc'] = wasmExports['_ecalloc'];
|
|
__estrdup = Module['__estrdup'] = wasmExports['_estrdup'];
|
|
__estrndup = Module['__estrndup'] = wasmExports['_estrndup'];
|
|
_zend_get_parameters_array_ex = Module[
|
|
'_zend_get_parameters_array_ex'
|
|
] = wasmExports['zend_get_parameters_array_ex'];
|
|
_zend_zval_value_name = Module['_zend_zval_value_name'] =
|
|
wasmExports['zend_zval_value_name'];
|
|
_zend_wrong_parameters_none_error = Module[
|
|
'_zend_wrong_parameters_none_error'
|
|
] = wasmExports['zend_wrong_parameters_none_error'];
|
|
_zend_wrong_parameters_count_error = Module[
|
|
'_zend_wrong_parameters_count_error'
|
|
] = wasmExports['zend_wrong_parameters_count_error'];
|
|
_zend_wrong_parameter_error = Module['_zend_wrong_parameter_error'] =
|
|
wasmExports['zend_wrong_parameter_error'];
|
|
_zend_argument_type_error = Module['_zend_argument_type_error'] =
|
|
wasmExports['zend_argument_type_error'];
|
|
_zend_argument_value_error = Module['_zend_argument_value_error'] =
|
|
wasmExports['zend_argument_value_error'];
|
|
_zend_argument_error = Module['_zend_argument_error'] =
|
|
wasmExports['zend_argument_error'];
|
|
_zend_argument_must_not_be_empty_error = Module[
|
|
'_zend_argument_must_not_be_empty_error'
|
|
] = wasmExports['zend_argument_must_not_be_empty_error'];
|
|
_zend_parse_arg_bool_slow = Module['_zend_parse_arg_bool_slow'] =
|
|
wasmExports['zend_parse_arg_bool_slow'];
|
|
_zend_flf_parse_arg_bool_slow = Module[
|
|
'_zend_flf_parse_arg_bool_slow'
|
|
] = wasmExports['zend_flf_parse_arg_bool_slow'];
|
|
_zend_parse_arg_long_slow = Module['_zend_parse_arg_long_slow'] =
|
|
wasmExports['zend_parse_arg_long_slow'];
|
|
_zend_flf_parse_arg_long_slow = Module[
|
|
'_zend_flf_parse_arg_long_slow'
|
|
] = wasmExports['zend_flf_parse_arg_long_slow'];
|
|
_zend_parse_arg_str_slow = Module['_zend_parse_arg_str_slow'] =
|
|
wasmExports['zend_parse_arg_str_slow'];
|
|
_zend_flf_parse_arg_str_slow = Module['_zend_flf_parse_arg_str_slow'] =
|
|
wasmExports['zend_flf_parse_arg_str_slow'];
|
|
_zend_parse_arg_str_or_long_slow = Module[
|
|
'_zend_parse_arg_str_or_long_slow'
|
|
] = wasmExports['zend_parse_arg_str_or_long_slow'];
|
|
_zend_release_fcall_info_cache = Module[
|
|
'_zend_release_fcall_info_cache'
|
|
] = wasmExports['zend_release_fcall_info_cache'];
|
|
_zend_parse_parameters = Module['_zend_parse_parameters'] =
|
|
wasmExports['zend_parse_parameters'];
|
|
_zend_parse_method_parameters = Module[
|
|
'_zend_parse_method_parameters'
|
|
] = wasmExports['zend_parse_method_parameters'];
|
|
_object_properties_init = Module['_object_properties_init'] =
|
|
wasmExports['object_properties_init'];
|
|
_object_init_ex = Module['_object_init_ex'] =
|
|
wasmExports['object_init_ex'];
|
|
_object_init_with_constructor = Module[
|
|
'_object_init_with_constructor'
|
|
] = wasmExports['object_init_with_constructor'];
|
|
_add_assoc_long_ex = Module['_add_assoc_long_ex'] =
|
|
wasmExports['add_assoc_long_ex'];
|
|
_add_assoc_bool_ex = Module['_add_assoc_bool_ex'] =
|
|
wasmExports['add_assoc_bool_ex'];
|
|
_add_assoc_str_ex = Module['_add_assoc_str_ex'] =
|
|
wasmExports['add_assoc_str_ex'];
|
|
_add_assoc_string_ex = Module['_add_assoc_string_ex'] =
|
|
wasmExports['add_assoc_string_ex'];
|
|
_add_next_index_long = Module['_add_next_index_long'] =
|
|
wasmExports['add_next_index_long'];
|
|
_add_next_index_str = Module['_add_next_index_str'] =
|
|
wasmExports['add_next_index_str'];
|
|
_add_next_index_string = Module['_add_next_index_string'] =
|
|
wasmExports['add_next_index_string'];
|
|
_add_next_index_stringl = Module['_add_next_index_stringl'] =
|
|
wasmExports['add_next_index_stringl'];
|
|
_zend_register_internal_class_with_flags = Module[
|
|
'_zend_register_internal_class_with_flags'
|
|
] = wasmExports['zend_register_internal_class_with_flags'];
|
|
_zend_class_implements = Module['_zend_class_implements'] =
|
|
wasmExports['zend_class_implements'];
|
|
_zend_fcall_info_init = Module['_zend_fcall_info_init'] =
|
|
wasmExports['zend_fcall_info_init'];
|
|
_zend_declare_typed_property = Module['_zend_declare_typed_property'] =
|
|
wasmExports['zend_declare_typed_property'];
|
|
_zend_try_assign_typed_ref_bool = Module[
|
|
'_zend_try_assign_typed_ref_bool'
|
|
] = wasmExports['zend_try_assign_typed_ref_bool'];
|
|
_zend_try_assign_typed_ref_long = Module[
|
|
'_zend_try_assign_typed_ref_long'
|
|
] = wasmExports['zend_try_assign_typed_ref_long'];
|
|
_zend_try_assign_typed_ref_str = Module[
|
|
'_zend_try_assign_typed_ref_str'
|
|
] = wasmExports['zend_try_assign_typed_ref_str'];
|
|
_zend_try_assign_typed_ref_arr = Module[
|
|
'_zend_try_assign_typed_ref_arr'
|
|
] = wasmExports['zend_try_assign_typed_ref_arr'];
|
|
_zend_declare_typed_class_constant = Module[
|
|
'_zend_declare_typed_class_constant'
|
|
] = wasmExports['zend_declare_typed_class_constant'];
|
|
_zend_update_property = Module['_zend_update_property'] =
|
|
wasmExports['zend_update_property'];
|
|
_zend_add_attribute = Module['_zend_add_attribute'] =
|
|
wasmExports['zend_add_attribute'];
|
|
_zend_register_long_constant = Module['_zend_register_long_constant'] =
|
|
wasmExports['zend_register_long_constant'];
|
|
_zend_register_string_constant = Module[
|
|
'_zend_register_string_constant'
|
|
] = wasmExports['zend_register_string_constant'];
|
|
_zend_throw_exception = Module['_zend_throw_exception'] =
|
|
wasmExports['zend_throw_exception'];
|
|
_zend_throw_exception_ex = Module['_zend_throw_exception_ex'] =
|
|
wasmExports['zend_throw_exception_ex'];
|
|
_zend_throw_error_exception = Module['_zend_throw_error_exception'] =
|
|
wasmExports['zend_throw_error_exception'];
|
|
_get_active_class_name = Module['_get_active_class_name'] =
|
|
wasmExports['get_active_class_name'];
|
|
_get_active_function_or_method_name = Module[
|
|
'_get_active_function_or_method_name'
|
|
] = wasmExports['get_active_function_or_method_name'];
|
|
_zend_call_function = Module['_zend_call_function'] =
|
|
wasmExports['zend_call_function'];
|
|
_zend_call_known_function = Module['_zend_call_known_function'] =
|
|
wasmExports['zend_call_known_function'];
|
|
_zend_call_known_instance_method_with_2_params = Module[
|
|
'_zend_call_known_instance_method_with_2_params'
|
|
] = wasmExports['zend_call_known_instance_method_with_2_params'];
|
|
_gc_possible_root = Module['_gc_possible_root'] =
|
|
wasmExports['gc_possible_root'];
|
|
_zend_get_gc_buffer_create = Module['_zend_get_gc_buffer_create'] =
|
|
wasmExports['zend_get_gc_buffer_create'];
|
|
_zend_get_gc_buffer_grow = Module['_zend_get_gc_buffer_grow'] =
|
|
wasmExports['zend_get_gc_buffer_grow'];
|
|
_zend_hash_str_find_ptr_lc = Module['_zend_hash_str_find_ptr_lc'] =
|
|
wasmExports['zend_hash_str_find_ptr_lc'];
|
|
_zend_hash_str_find = Module['_zend_hash_str_find'] =
|
|
wasmExports['zend_hash_str_find'];
|
|
__zend_hash_init = Module['__zend_hash_init'] =
|
|
wasmExports['_zend_hash_init'];
|
|
__zend_new_array_0 = Module['__zend_new_array_0'] =
|
|
wasmExports['_zend_new_array_0'];
|
|
__zend_new_array = Module['__zend_new_array'] =
|
|
wasmExports['_zend_new_array'];
|
|
_zend_hash_real_init_packed = Module['_zend_hash_real_init_packed'] =
|
|
wasmExports['zend_hash_real_init_packed'];
|
|
_zend_hash_update = Module['_zend_hash_update'] =
|
|
wasmExports['zend_hash_update'];
|
|
_zend_hash_str_update = Module['_zend_hash_str_update'] =
|
|
wasmExports['zend_hash_str_update'];
|
|
_zend_hash_next_index_insert = Module['_zend_hash_next_index_insert'] =
|
|
wasmExports['zend_hash_next_index_insert'];
|
|
_zend_hash_index_update = Module['_zend_hash_index_update'] =
|
|
wasmExports['zend_hash_index_update'];
|
|
_zend_hash_destroy = Module['_zend_hash_destroy'] =
|
|
wasmExports['zend_hash_destroy'];
|
|
_zend_array_destroy = Module['_zend_array_destroy'] =
|
|
wasmExports['zend_array_destroy'];
|
|
_zend_hash_copy = Module['_zend_hash_copy'] =
|
|
wasmExports['zend_hash_copy'];
|
|
_zend_hash_index_find = Module['_zend_hash_index_find'] =
|
|
wasmExports['zend_hash_index_find'];
|
|
_zend_hash_sort_ex = Module['_zend_hash_sort_ex'] =
|
|
wasmExports['zend_hash_sort_ex'];
|
|
_zend_register_ini_entries_ex = Module[
|
|
'_zend_register_ini_entries_ex'
|
|
] = wasmExports['zend_register_ini_entries_ex'];
|
|
_zend_unregister_ini_entries_ex = Module[
|
|
'_zend_unregister_ini_entries_ex'
|
|
] = wasmExports['zend_unregister_ini_entries_ex'];
|
|
_zend_alter_ini_entry = Module['_zend_alter_ini_entry'] =
|
|
wasmExports['zend_alter_ini_entry'];
|
|
_zend_ini_parse_quantity_warn = Module[
|
|
'_zend_ini_parse_quantity_warn'
|
|
] = wasmExports['zend_ini_parse_quantity_warn'];
|
|
_zend_ini_boolean_displayer_cb = Module[
|
|
'_zend_ini_boolean_displayer_cb'
|
|
] = wasmExports['zend_ini_boolean_displayer_cb'];
|
|
_OnUpdateBool = Module['_OnUpdateBool'] = wasmExports['OnUpdateBool'];
|
|
_OnUpdateStringUnempty = Module['_OnUpdateStringUnempty'] =
|
|
wasmExports['OnUpdateStringUnempty'];
|
|
_zend_call_method = Module['_zend_call_method'] =
|
|
wasmExports['zend_call_method'];
|
|
_zend_create_internal_iterator_zval = Module[
|
|
'_zend_create_internal_iterator_zval'
|
|
] = wasmExports['zend_create_internal_iterator_zval'];
|
|
_zend_iterator_init = Module['_zend_iterator_init'] =
|
|
wasmExports['zend_iterator_init'];
|
|
_zend_std_get_properties = Module['_zend_std_get_properties'] =
|
|
wasmExports['zend_std_get_properties'];
|
|
_zend_std_compare_objects = Module['_zend_std_compare_objects'] =
|
|
wasmExports['zend_std_compare_objects'];
|
|
_zend_objects_store_del = Module['_zend_objects_store_del'] =
|
|
wasmExports['zend_objects_store_del'];
|
|
_zend_object_std_init = Module['_zend_object_std_init'] =
|
|
wasmExports['zend_object_std_init'];
|
|
_zend_object_std_dtor = Module['_zend_object_std_dtor'] =
|
|
wasmExports['zend_object_std_dtor'];
|
|
_zend_objects_clone_members = Module['_zend_objects_clone_members'] =
|
|
wasmExports['zend_objects_clone_members'];
|
|
__is_numeric_string_ex = Module['__is_numeric_string_ex'] =
|
|
wasmExports['_is_numeric_string_ex'];
|
|
_zval_try_get_long = Module['_zval_try_get_long'] =
|
|
wasmExports['zval_try_get_long'];
|
|
_convert_to_long = Module['_convert_to_long'] =
|
|
wasmExports['convert_to_long'];
|
|
_zval_get_long_func = Module['_zval_get_long_func'] =
|
|
wasmExports['zval_get_long_func'];
|
|
_convert_to_double = Module['_convert_to_double'] =
|
|
wasmExports['convert_to_double'];
|
|
__try_convert_to_string = Module['__try_convert_to_string'] =
|
|
wasmExports['_try_convert_to_string'];
|
|
_zval_get_double_func = Module['_zval_get_double_func'] =
|
|
wasmExports['zval_get_double_func'];
|
|
_zval_get_string_func = Module['_zval_get_string_func'] =
|
|
wasmExports['zval_get_string_func'];
|
|
_numeric_compare_function = Module['_numeric_compare_function'] =
|
|
wasmExports['numeric_compare_function'];
|
|
_compare_function = Module['_compare_function'] =
|
|
wasmExports['compare_function'];
|
|
_instanceof_function_slow = Module['_instanceof_function_slow'] =
|
|
wasmExports['instanceof_function_slow'];
|
|
_zend_str_tolower = Module['_zend_str_tolower'] =
|
|
wasmExports['zend_str_tolower'];
|
|
_zend_memnstr_ex = Module['_zend_memnstr_ex'] =
|
|
wasmExports['zend_memnstr_ex'];
|
|
_smart_str_erealloc = Module['_smart_str_erealloc'] =
|
|
wasmExports['smart_str_erealloc'];
|
|
_smart_str_realloc = Module['_smart_str_realloc'] =
|
|
wasmExports['smart_str_realloc'];
|
|
_zend_sort = Module['_zend_sort'] = wasmExports['zend_sort'];
|
|
_zend_string_concat3 = Module['_zend_string_concat3'] =
|
|
wasmExports['zend_string_concat3'];
|
|
_zend_strtod = Module['_zend_strtod'] = wasmExports['zend_strtod'];
|
|
_zval_ptr_dtor = Module['_zval_ptr_dtor'] =
|
|
wasmExports['zval_ptr_dtor'];
|
|
_zval_ptr_safe_dtor = Module['_zval_ptr_safe_dtor'] =
|
|
wasmExports['zval_ptr_safe_dtor'];
|
|
_zval_add_ref = Module['_zval_add_ref'] = wasmExports['zval_add_ref'];
|
|
_zend_spprintf = Module['_zend_spprintf'] =
|
|
wasmExports['zend_spprintf'];
|
|
_zend_error = Module['_zend_error'] = wasmExports['zend_error'];
|
|
_zend_throw_error = Module['_zend_throw_error'] =
|
|
wasmExports['zend_throw_error'];
|
|
_zend_illegal_container_offset = Module[
|
|
'_zend_illegal_container_offset'
|
|
] = wasmExports['zend_illegal_container_offset'];
|
|
_zend_argument_count_error = Module['_zend_argument_count_error'] =
|
|
wasmExports['zend_argument_count_error'];
|
|
_zend_value_error = Module['_zend_value_error'] =
|
|
wasmExports['zend_value_error'];
|
|
_strtoll = Module['_strtoll'] = wasmExports['strtoll'];
|
|
_strlen = Module['_strlen'] = wasmExports['strlen'];
|
|
_memcmp = Module['_memcmp'] = wasmExports['memcmp'];
|
|
_free = Module['_free'] = wasmExports['free'];
|
|
_malloc =
|
|
PHPLoader['malloc'] =
|
|
Module['_malloc'] =
|
|
wasmExports['malloc'];
|
|
_snprintf = Module['_snprintf'] = wasmExports['snprintf'];
|
|
_strchr = Module['_strchr'] = wasmExports['strchr'];
|
|
_dlopen = Module['_dlopen'] = wasmExports['dlopen'];
|
|
_dlsym = Module['_dlsym'] = wasmExports['dlsym'];
|
|
_dlclose = Module['_dlclose'] = wasmExports['dlclose'];
|
|
_strcmp = Module['_strcmp'] = wasmExports['strcmp'];
|
|
_getenv = Module['_getenv'] = wasmExports['getenv'];
|
|
_atoi = Module['_atoi'] = wasmExports['atoi'];
|
|
___errno_location = Module['___errno_location'] =
|
|
wasmExports['__errno_location'];
|
|
_strrchr = Module['_strrchr'] = wasmExports['strrchr'];
|
|
_strcasecmp = Module['_strcasecmp'] = wasmExports['strcasecmp'];
|
|
_memchr = Module['_memchr'] = wasmExports['memchr'];
|
|
_isalnum = Module['_isalnum'] = wasmExports['isalnum'];
|
|
_fwrite = Module['_fwrite'] = wasmExports['fwrite'];
|
|
_strncmp = Module['_strncmp'] = wasmExports['strncmp'];
|
|
_strtok_r = Module['_strtok_r'] = wasmExports['strtok_r'];
|
|
_unlink = Module['_unlink'] = wasmExports['unlink'];
|
|
_fileno = Module['_fileno'] = wasmExports['fileno'];
|
|
_fread = Module['_fread'] = wasmExports['fread'];
|
|
_fclose = Module['_fclose'] = wasmExports['fclose'];
|
|
_strtoul = Module['_strtoul'] = wasmExports['strtoul'];
|
|
_strstr = Module['_strstr'] = wasmExports['strstr'];
|
|
_close = Module['_close'] = wasmExports['close'];
|
|
_tolower = Module['_tolower'] = wasmExports['tolower'];
|
|
_fseek = Module['_fseek'] = wasmExports['fseek'];
|
|
_stat = Module['_stat'] = wasmExports['stat'];
|
|
_gettimeofday = Module['_gettimeofday'] = wasmExports['gettimeofday'];
|
|
_fopen = Module['_fopen'] = wasmExports['fopen'];
|
|
_open = Module['_open'] = wasmExports['open'];
|
|
_rename = Module['_rename'] = wasmExports['rename'];
|
|
_mkdir = Module['_mkdir'] = wasmExports['mkdir'];
|
|
_rmdir = Module['_rmdir'] = wasmExports['rmdir'];
|
|
_opendir = Module['_opendir'] = wasmExports['opendir'];
|
|
_strncpy = Module['_strncpy'] = wasmExports['strncpy'];
|
|
_realloc = Module['_realloc'] = wasmExports['realloc'];
|
|
_localtime_r = Module['_localtime_r'] = wasmExports['localtime_r'];
|
|
_strtol = Module['_strtol'] = wasmExports['strtol'];
|
|
_pow = Module['_pow'] = wasmExports['pow'];
|
|
_strtod = Module['_strtod'] = wasmExports['strtod'];
|
|
_round = Module['_round'] = wasmExports['round'];
|
|
_sin = Module['_sin'] = wasmExports['sin'];
|
|
_cos = Module['_cos'] = wasmExports['cos'];
|
|
_atan2 = Module['_atan2'] = wasmExports['atan2'];
|
|
_acos = Module['_acos'] = wasmExports['acos'];
|
|
_tan = Module['_tan'] = wasmExports['tan'];
|
|
_asin = Module['_asin'] = wasmExports['asin'];
|
|
_atan = Module['_atan'] = wasmExports['atan'];
|
|
_log = Module['_log'] = wasmExports['log'];
|
|
_fmod = Module['_fmod'] = wasmExports['fmod'];
|
|
_setlocale = Module['_setlocale'] = wasmExports['setlocale'];
|
|
_calloc = wasmExports['calloc'];
|
|
_qsort = Module['_qsort'] = wasmExports['qsort'];
|
|
_readdir = Module['_readdir'] = wasmExports['readdir'];
|
|
_closedir = Module['_closedir'] = wasmExports['closedir'];
|
|
_isdigit = Module['_isdigit'] = wasmExports['isdigit'];
|
|
_wasm_php_exec = Module['_wasm_php_exec'] =
|
|
wasmExports['wasm_php_exec'];
|
|
_php_pollfd_for = Module['_php_pollfd_for'] =
|
|
wasmExports['php_pollfd_for'];
|
|
_htons = wasmExports['htons'];
|
|
_ntohs = wasmExports['ntohs'];
|
|
_htonl = wasmExports['htonl'];
|
|
_tzset = Module['_tzset'] = wasmExports['tzset'];
|
|
_wasm_sleep = Module['_wasm_sleep'] = wasmExports['wasm_sleep'];
|
|
_fflush = Module['_fflush'] = wasmExports['fflush'];
|
|
_expf = Module['_expf'] = wasmExports['expf'];
|
|
_abort = Module['_abort'] = wasmExports['abort'];
|
|
_mmap = Module['_mmap'] = wasmExports['mmap'];
|
|
_munmap = Module['_munmap'] = wasmExports['munmap'];
|
|
_fgets = Module['_fgets'] = wasmExports['fgets'];
|
|
_initgroups = Module['_initgroups'] = wasmExports['initgroups'];
|
|
_atol = Module['_atol'] = wasmExports['atol'];
|
|
_strcat = Module['_strcat'] = wasmExports['strcat'];
|
|
_strcpy = Module['_strcpy'] = wasmExports['strcpy'];
|
|
_ftell = Module['_ftell'] = wasmExports['ftell'];
|
|
_wasm_read = Module['_wasm_read'] = wasmExports['wasm_read'];
|
|
_feof = Module['_feof'] = wasmExports['feof'];
|
|
_strncat = Module['_strncat'] = wasmExports['strncat'];
|
|
___ctype_get_mb_cur_max = Module['___ctype_get_mb_cur_max'] =
|
|
wasmExports['__ctype_get_mb_cur_max'];
|
|
___wrap_usleep = Module['___wrap_usleep'] =
|
|
wasmExports['__wrap_usleep'];
|
|
_wasm_popen = Module['_wasm_popen'] = wasmExports['wasm_popen'];
|
|
_wasm_pclose = Module['_wasm_pclose'] = wasmExports['wasm_pclose'];
|
|
___wrap_select = Module['___wrap_select'] =
|
|
wasmExports['__wrap_select'];
|
|
_wasm_set_sapi_name = Module['_wasm_set_sapi_name'] =
|
|
wasmExports['wasm_set_sapi_name'];
|
|
_wasm_set_phpini_path = Module['_wasm_set_phpini_path'] =
|
|
wasmExports['wasm_set_phpini_path'];
|
|
_wasm_add_cli_arg = Module['_wasm_add_cli_arg'] =
|
|
wasmExports['wasm_add_cli_arg'];
|
|
_run_cli = Module['_run_cli'] = wasmExports['run_cli'];
|
|
_wasm_add_SERVER_entry = Module['_wasm_add_SERVER_entry'] =
|
|
wasmExports['wasm_add_SERVER_entry'];
|
|
_wasm_add_ENV_entry = Module['_wasm_add_ENV_entry'] =
|
|
wasmExports['wasm_add_ENV_entry'];
|
|
_wasm_set_query_string = Module['_wasm_set_query_string'] =
|
|
wasmExports['wasm_set_query_string'];
|
|
_wasm_set_path_translated = Module['_wasm_set_path_translated'] =
|
|
wasmExports['wasm_set_path_translated'];
|
|
_wasm_set_skip_shebang = Module['_wasm_set_skip_shebang'] =
|
|
wasmExports['wasm_set_skip_shebang'];
|
|
_wasm_set_request_uri = Module['_wasm_set_request_uri'] =
|
|
wasmExports['wasm_set_request_uri'];
|
|
_wasm_set_request_method = Module['_wasm_set_request_method'] =
|
|
wasmExports['wasm_set_request_method'];
|
|
_wasm_set_request_host = Module['_wasm_set_request_host'] =
|
|
wasmExports['wasm_set_request_host'];
|
|
_wasm_set_content_type = Module['_wasm_set_content_type'] =
|
|
wasmExports['wasm_set_content_type'];
|
|
_wasm_set_request_body = Module['_wasm_set_request_body'] =
|
|
wasmExports['wasm_set_request_body'];
|
|
_wasm_set_content_length = Module['_wasm_set_content_length'] =
|
|
wasmExports['wasm_set_content_length'];
|
|
_wasm_set_cookies = Module['_wasm_set_cookies'] =
|
|
wasmExports['wasm_set_cookies'];
|
|
_wasm_set_request_port = Module['_wasm_set_request_port'] =
|
|
wasmExports['wasm_set_request_port'];
|
|
_wasm_sapi_request_shutdown = Module['_wasm_sapi_request_shutdown'] =
|
|
wasmExports['wasm_sapi_request_shutdown'];
|
|
_wasm_sapi_handle_request = Module['_wasm_sapi_handle_request'] =
|
|
wasmExports['wasm_sapi_handle_request'];
|
|
_php_wasm_init = Module['_php_wasm_init'] =
|
|
wasmExports['php_wasm_init'];
|
|
_wasm_free =
|
|
PHPLoader['free'] =
|
|
Module['_wasm_free'] =
|
|
wasmExports['wasm_free'];
|
|
_wasm_trace = Module['_wasm_trace'] = wasmExports['wasm_trace'];
|
|
_sqlite3_auto_extension = Module['_sqlite3_auto_extension'] =
|
|
wasmExports['sqlite3_auto_extension'];
|
|
_sqlite3_cancel_auto_extension = Module[
|
|
'_sqlite3_cancel_auto_extension'
|
|
] = wasmExports['sqlite3_cancel_auto_extension'];
|
|
_rewind = Module['_rewind'] = wasmExports['rewind'];
|
|
_modf = Module['_modf'] = wasmExports['modf'];
|
|
___funcs_on_exit = wasmExports['__funcs_on_exit'];
|
|
___cxa_atexit = Module['___cxa_atexit'] = wasmExports['__cxa_atexit'];
|
|
_div = Module['_div'] = wasmExports['div'];
|
|
___dl_seterr = wasmExports['__dl_seterr'];
|
|
__emscripten_find_dylib = wasmExports['_emscripten_find_dylib'];
|
|
_mbstowcs = Module['_mbstowcs'] = wasmExports['mbstowcs'];
|
|
_emscripten_builtin_memalign =
|
|
wasmExports['emscripten_builtin_memalign'];
|
|
__emscripten_timeout = wasmExports['_emscripten_timeout'];
|
|
___extenddftf2 = Module['___extenddftf2'] =
|
|
wasmExports['__extenddftf2'];
|
|
___letf2 = Module['___letf2'] = wasmExports['__letf2'];
|
|
_tanhf = Module['_tanhf'] = wasmExports['tanhf'];
|
|
_wcstombs = Module['_wcstombs'] = wasmExports['wcstombs'];
|
|
_emscripten_get_sbrk_ptr = wasmExports['emscripten_get_sbrk_ptr'];
|
|
_setThrew = wasmExports['setThrew'];
|
|
___floatunditf = Module['___floatunditf'] =
|
|
wasmExports['__floatunditf'];
|
|
__emscripten_stack_restore = wasmExports['_emscripten_stack_restore'];
|
|
__emscripten_stack_alloc = wasmExports['_emscripten_stack_alloc'];
|
|
_emscripten_stack_get_current =
|
|
wasmExports['emscripten_stack_get_current'];
|
|
__ZNSt3__211__call_onceERVmPvPFvS2_E = Module[
|
|
'__ZNSt3__211__call_onceERVmPvPFvS2_E'
|
|
] = wasmExports['_ZNSt3__211__call_onceERVmPvPFvS2_E'];
|
|
__ZNSt3__218condition_variable10notify_allEv = Module[
|
|
'__ZNSt3__218condition_variable10notify_allEv'
|
|
] = wasmExports['_ZNSt3__218condition_variable10notify_allEv'];
|
|
__ZNSt3__25mutex4lockEv = Module['__ZNSt3__25mutex4lockEv'] =
|
|
wasmExports['_ZNSt3__25mutex4lockEv'];
|
|
__ZNSt3__25mutex6unlockEv = Module['__ZNSt3__25mutex6unlockEv'] =
|
|
wasmExports['_ZNSt3__25mutex6unlockEv'];
|
|
___cxa_bad_typeid = Module['___cxa_bad_typeid'] =
|
|
wasmExports['__cxa_bad_typeid'];
|
|
___cxa_allocate_exception = Module['___cxa_allocate_exception'] =
|
|
wasmExports['__cxa_allocate_exception'];
|
|
___cxa_pure_virtual = Module['___cxa_pure_virtual'] =
|
|
wasmExports['__cxa_pure_virtual'];
|
|
___dynamic_cast = Module['___dynamic_cast'] =
|
|
wasmExports['__dynamic_cast'];
|
|
__ZNSt20bad_array_new_lengthD1Ev = Module[
|
|
'__ZNSt20bad_array_new_lengthD1Ev'
|
|
] = wasmExports['_ZNSt20bad_array_new_lengthD1Ev'];
|
|
__ZNSt12length_errorD1Ev = Module['__ZNSt12length_errorD1Ev'] =
|
|
wasmExports['_ZNSt12length_errorD1Ev'];
|
|
dynCall_vii = dynCalls['vii'] = wasmExports['dynCall_vii'];
|
|
dynCall_vi = dynCalls['vi'] = wasmExports['dynCall_vi'];
|
|
dynCall_viiiii = dynCalls['viiiii'] = wasmExports['dynCall_viiiii'];
|
|
dynCall_iii = dynCalls['iii'] = wasmExports['dynCall_iii'];
|
|
dynCall_iiii = dynCalls['iiii'] = wasmExports['dynCall_iiii'];
|
|
dynCall_ii = dynCalls['ii'] = wasmExports['dynCall_ii'];
|
|
dynCall_iiiii = dynCalls['iiiii'] = wasmExports['dynCall_iiiii'];
|
|
dynCall_iiiiii = dynCalls['iiiiii'] = wasmExports['dynCall_iiiiii'];
|
|
dynCall_iiiiiii = dynCalls['iiiiiii'] = wasmExports['dynCall_iiiiiii'];
|
|
dynCall_i = dynCalls['i'] = wasmExports['dynCall_i'];
|
|
dynCall_v = dynCalls['v'] = wasmExports['dynCall_v'];
|
|
dynCall_viii = dynCalls['viii'] = wasmExports['dynCall_viii'];
|
|
dynCall_iijii = dynCalls['iijii'] = wasmExports['dynCall_iijii'];
|
|
dynCall_viiii = dynCalls['viiii'] = wasmExports['dynCall_viiii'];
|
|
dynCall_jii = dynCalls['jii'] = wasmExports['dynCall_jii'];
|
|
dynCall_jiii = dynCalls['jiii'] = wasmExports['dynCall_jiii'];
|
|
dynCall_jijj = dynCalls['jijj'] = wasmExports['dynCall_jijj'];
|
|
dynCall_viiiiiiii = dynCalls['viiiiiiii'] =
|
|
wasmExports['dynCall_viiiiiiii'];
|
|
dynCall_jiiiii = dynCalls['jiiiii'] = wasmExports['dynCall_jiiiii'];
|
|
dynCall_jiiii = dynCalls['jiiii'] = wasmExports['dynCall_jiiii'];
|
|
dynCall_iiiiiiiiii = dynCalls['iiiiiiiiii'] =
|
|
wasmExports['dynCall_iiiiiiiiii'];
|
|
dynCall_vjiii = dynCalls['vjiii'] = wasmExports['dynCall_vjiii'];
|
|
dynCall_iiji = dynCalls['iiji'] = wasmExports['dynCall_iiji'];
|
|
dynCall_iidddd = dynCalls['iidddd'] = wasmExports['dynCall_iidddd'];
|
|
dynCall_iijjjj = dynCalls['iijjjj'] = wasmExports['dynCall_iijjjj'];
|
|
dynCall_ji = dynCalls['ji'] = wasmExports['dynCall_ji'];
|
|
dynCall_viji = dynCalls['viji'] = wasmExports['dynCall_viji'];
|
|
dynCall_iiij = dynCalls['iiij'] = wasmExports['dynCall_iiij'];
|
|
dynCall_vji = dynCalls['vji'] = wasmExports['dynCall_vji'];
|
|
dynCall_vijj = dynCalls['vijj'] = wasmExports['dynCall_vijj'];
|
|
dynCall_iij = dynCalls['iij'] = wasmExports['dynCall_iij'];
|
|
dynCall_iijiji = dynCalls['iijiji'] = wasmExports['dynCall_iijiji'];
|
|
dynCall_iiiiiiii = dynCalls['iiiiiiii'] =
|
|
wasmExports['dynCall_iiiiiiii'];
|
|
dynCall_iiiij = dynCalls['iiiij'] = wasmExports['dynCall_iiiij'];
|
|
dynCall_jiji = dynCalls['jiji'] = wasmExports['dynCall_jiji'];
|
|
dynCall_viiij = dynCalls['viiij'] = wasmExports['dynCall_viiij'];
|
|
dynCall_viiiiiii = dynCalls['viiiiiii'] =
|
|
wasmExports['dynCall_viiiiiii'];
|
|
dynCall_iiiiiiiii = dynCalls['iiiiiiiii'] =
|
|
wasmExports['dynCall_iiiiiiiii'];
|
|
dynCall_viiiiii = dynCalls['viiiiii'] = wasmExports['dynCall_viiiiii'];
|
|
dynCall_viiiiiiiii = dynCalls['viiiiiiiii'] =
|
|
wasmExports['dynCall_viiiiiiiii'];
|
|
dynCall_vidi = dynCalls['vidi'] = wasmExports['dynCall_vidi'];
|
|
dynCall_iiijii = dynCalls['iiijii'] = wasmExports['dynCall_iiijii'];
|
|
dynCall_iiidii = dynCalls['iiidii'] = wasmExports['dynCall_iiidii'];
|
|
dynCall_jiiji = dynCalls['jiiji'] = wasmExports['dynCall_jiiji'];
|
|
dynCall_jj = dynCalls['jj'] = wasmExports['dynCall_jj'];
|
|
dynCall_jiiiji = dynCalls['jiiiji'] = wasmExports['dynCall_jiiiji'];
|
|
dynCall_jiij = dynCalls['jiij'] = wasmExports['dynCall_jiij'];
|
|
dynCall_iiiji = dynCalls['iiiji'] = wasmExports['dynCall_iiiji'];
|
|
dynCall_ij = dynCalls['ij'] = wasmExports['dynCall_ij'];
|
|
dynCall_vijii = dynCalls['vijii'] = wasmExports['dynCall_vijii'];
|
|
dynCall_iiiiiij = dynCalls['iiiiiij'] = wasmExports['dynCall_iiiiiij'];
|
|
dynCall_iiid = dynCalls['iiid'] = wasmExports['dynCall_iiid'];
|
|
dynCall_dii = dynCalls['dii'] = wasmExports['dynCall_dii'];
|
|
dynCall_vid = dynCalls['vid'] = wasmExports['dynCall_vid'];
|
|
dynCall_vij = dynCalls['vij'] = wasmExports['dynCall_vij'];
|
|
dynCall_di = dynCalls['di'] = wasmExports['dynCall_di'];
|
|
dynCall_iiiiijii = dynCalls['iiiiijii'] =
|
|
wasmExports['dynCall_iiiiijii'];
|
|
dynCall_j = dynCalls['j'] = wasmExports['dynCall_j'];
|
|
dynCall_iiiiji = dynCalls['iiiiji'] = wasmExports['dynCall_iiiiji'];
|
|
dynCall_iiiijii = dynCalls['iiiijii'] = wasmExports['dynCall_iiiijii'];
|
|
dynCall_viiji = dynCalls['viiji'] = wasmExports['dynCall_viiji'];
|
|
dynCall_viijii = dynCalls['viijii'] = wasmExports['dynCall_viijii'];
|
|
dynCall_iiiiiiiiiii = dynCalls['iiiiiiiiiii'] =
|
|
wasmExports['dynCall_iiiiiiiiiii'];
|
|
dynCall_iiiijji = dynCalls['iiiijji'] = wasmExports['dynCall_iiiijji'];
|
|
dynCall_dd = dynCalls['dd'] = wasmExports['dynCall_dd'];
|
|
dynCall_ddd = dynCalls['ddd'] = wasmExports['dynCall_ddd'];
|
|
dynCall_diiii = dynCalls['diiii'] = wasmExports['dynCall_diiii'];
|
|
dynCall_diiiiiiii = dynCalls['diiiiiiii'] =
|
|
wasmExports['dynCall_diiiiiiii'];
|
|
dynCall_fi = dynCalls['fi'] = wasmExports['dynCall_fi'];
|
|
dynCall_fii = dynCalls['fii'] = wasmExports['dynCall_fii'];
|
|
dynCall_iiiiiiiiiiii = dynCalls['iiiiiiiiiiii'] =
|
|
wasmExports['dynCall_iiiiiiiiiiii'];
|
|
dynCall_viiiiiiiiiii = dynCalls['viiiiiiiiiii'] =
|
|
wasmExports['dynCall_viiiiiiiiiii'];
|
|
dynCall_viiiiiiiiiiiii = dynCalls['viiiiiiiiiiiii'] =
|
|
wasmExports['dynCall_viiiiiiiiiiiii'];
|
|
dynCall_viiiiiiiiiiiiiii = dynCalls['viiiiiiiiiiiiiii'] =
|
|
wasmExports['dynCall_viiiiiiiiiiiiiii'];
|
|
dynCall_iiiijj = dynCalls['iiiijj'] = wasmExports['dynCall_iiiijj'];
|
|
dynCall_jiiiiiiiii = dynCalls['jiiiiiiiii'] =
|
|
wasmExports['dynCall_jiiiiiiiii'];
|
|
dynCall_jiiiiii = dynCalls['jiiiiii'] = wasmExports['dynCall_jiiiiii'];
|
|
dynCall_jiiiiiiii = dynCalls['jiiiiiiii'] =
|
|
wasmExports['dynCall_jiiiiiiii'];
|
|
dynCall_iidiiii = dynCalls['iidiiii'] = wasmExports['dynCall_iidiiii'];
|
|
_asyncify_start_unwind = wasmExports['asyncify_start_unwind'];
|
|
_asyncify_stop_unwind = wasmExports['asyncify_stop_unwind'];
|
|
_asyncify_start_rewind = wasmExports['asyncify_start_rewind'];
|
|
_asyncify_stop_rewind = wasmExports['asyncify_stop_rewind'];
|
|
memory = wasmMemory = wasmExports['memory'];
|
|
___stack_pointer = Module['___stack_pointer'] =
|
|
wasmExports['__stack_pointer'];
|
|
__indirect_function_table = wasmTable =
|
|
wasmExports['__indirect_function_table'];
|
|
}
|
|
var _compiler_globals = (Module['_compiler_globals'] = 17464888);
|
|
var _executor_globals = (Module['_executor_globals'] = 17465304);
|
|
var _zend_ce_exception = (Module['_zend_ce_exception'] = 17461324);
|
|
var _zend_empty_array = (Module['_zend_empty_array'] = 16978640);
|
|
var _zend_ce_aggregate = (Module['_zend_ce_aggregate'] = 17347712);
|
|
var _zend_ce_iterator = (Module['_zend_ce_iterator'] = 17347716);
|
|
var _zend_ce_countable = (Module['_zend_ce_countable'] = 17347728);
|
|
var _std_object_handlers = (Module['_std_object_handlers'] = 16962032);
|
|
var _zend_empty_string = (Module['_zend_empty_string'] = 17463652);
|
|
var _zend_known_strings = (Module['_zend_known_strings'] = 17463656);
|
|
var _zend_string_init_interned = (Module['_zend_string_init_interned'] =
|
|
17463724);
|
|
var ___memory_base = (Module['___memory_base'] = 0);
|
|
var ___table_base = (Module['___table_base'] = 1);
|
|
var _stdout = (Module['_stdout'] = 17340608);
|
|
var _timezone = (Module['_timezone'] = 17796056);
|
|
var _tzname = (Module['_tzname'] = 17796064);
|
|
var ___heap_base = 18857760;
|
|
var __ZNSt3__25ctypeIcE2idE = (Module['__ZNSt3__25ctypeIcE2idE'] =
|
|
17809172);
|
|
var __ZTVN10__cxxabiv120__si_class_type_infoE = (Module[
|
|
'__ZTVN10__cxxabiv120__si_class_type_infoE'
|
|
] = 17340856);
|
|
var __ZTVN10__cxxabiv117__class_type_infoE = (Module[
|
|
'__ZTVN10__cxxabiv117__class_type_infoE'
|
|
] = 17340816);
|
|
var __ZTVN10__cxxabiv121__vmi_class_type_infoE = (Module[
|
|
'__ZTVN10__cxxabiv121__vmi_class_type_infoE'
|
|
] = 17340908);
|
|
var __ZTISt20bad_array_new_length = (Module[
|
|
'__ZTISt20bad_array_new_length'
|
|
] = 17340980);
|
|
var __ZTVSt12length_error = (Module['__ZTVSt12length_error'] = 17341024);
|
|
var __ZTISt12length_error = (Module['__ZTISt12length_error'] = 17341044);
|
|
var wasmImports = {
|
|
__assert_fail: ___assert_fail,
|
|
__asyncify_data: ___asyncify_data,
|
|
__asyncify_state: ___asyncify_state,
|
|
__asyncjs__js_module_onMessage,
|
|
__call_sighandler: ___call_sighandler,
|
|
__syscall_accept4: ___syscall_accept4,
|
|
__syscall_bind: ___syscall_bind,
|
|
__syscall_chdir: ___syscall_chdir,
|
|
__syscall_chmod: ___syscall_chmod,
|
|
__syscall_connect: ___syscall_connect,
|
|
__syscall_dup: ___syscall_dup,
|
|
__syscall_dup3: ___syscall_dup3,
|
|
__syscall_faccessat: ___syscall_faccessat,
|
|
__syscall_fchmod: ___syscall_fchmod,
|
|
__syscall_fchown32: ___syscall_fchown32,
|
|
__syscall_fchownat: ___syscall_fchownat,
|
|
__syscall_fcntl64: ___syscall_fcntl64,
|
|
__syscall_fdatasync: ___syscall_fdatasync,
|
|
__syscall_fstat64: ___syscall_fstat64,
|
|
__syscall_ftruncate64: ___syscall_ftruncate64,
|
|
__syscall_getcwd: ___syscall_getcwd,
|
|
__syscall_getdents64: ___syscall_getdents64,
|
|
__syscall_getpeername: ___syscall_getpeername,
|
|
__syscall_getsockname: ___syscall_getsockname,
|
|
__syscall_getsockopt: ___syscall_getsockopt,
|
|
__syscall_ioctl: ___syscall_ioctl,
|
|
__syscall_listen: ___syscall_listen,
|
|
__syscall_lstat64: ___syscall_lstat64,
|
|
__syscall_mkdirat: ___syscall_mkdirat,
|
|
__syscall_newfstatat: ___syscall_newfstatat,
|
|
__syscall_openat: ___syscall_openat,
|
|
__syscall_pipe: ___syscall_pipe,
|
|
__syscall_poll: ___syscall_poll,
|
|
__syscall_readlinkat: ___syscall_readlinkat,
|
|
__syscall_recvfrom: ___syscall_recvfrom,
|
|
__syscall_renameat: ___syscall_renameat,
|
|
__syscall_rmdir: ___syscall_rmdir,
|
|
__syscall_sendto: ___syscall_sendto,
|
|
__syscall_socket: ___syscall_socket,
|
|
__syscall_stat64: ___syscall_stat64,
|
|
__syscall_statfs64: ___syscall_statfs64,
|
|
__syscall_symlinkat: ___syscall_symlinkat,
|
|
__syscall_unlinkat: ___syscall_unlinkat,
|
|
__syscall_utimensat: ___syscall_utimensat,
|
|
_abort_js: __abort_js,
|
|
_dlopen_js: __dlopen_js,
|
|
_dlsym_js: __dlsym_js,
|
|
_emscripten_lookup_name: __emscripten_lookup_name,
|
|
_emscripten_runtime_keepalive_clear:
|
|
__emscripten_runtime_keepalive_clear,
|
|
_emscripten_throw_longjmp: __emscripten_throw_longjmp,
|
|
_gmtime_js: __gmtime_js,
|
|
_localtime_js: __localtime_js,
|
|
_mktime_js: __mktime_js,
|
|
_mmap_js: __mmap_js,
|
|
_munmap_js: __munmap_js,
|
|
_setitimer_js: __setitimer_js,
|
|
_tzset_js: __tzset_js,
|
|
clock_time_get: _clock_time_get,
|
|
emscripten_date_now: _emscripten_date_now,
|
|
emscripten_get_heap_max: _emscripten_get_heap_max,
|
|
emscripten_get_now: _emscripten_get_now,
|
|
emscripten_resize_heap: _emscripten_resize_heap,
|
|
emscripten_sleep: _emscripten_sleep,
|
|
environ_get: _environ_get,
|
|
environ_sizes_get: _environ_sizes_get,
|
|
exit: _exit,
|
|
fd_close: _fd_close,
|
|
fd_fdstat_get: _fd_fdstat_get,
|
|
fd_read: _fd_read,
|
|
fd_seek: _fd_seek,
|
|
fd_sync: _fd_sync,
|
|
fd_write: _fd_write,
|
|
getaddrinfo: _getaddrinfo,
|
|
getcontext: _getcontext,
|
|
getdtablesize: _getdtablesize,
|
|
getnameinfo: _getnameinfo,
|
|
getprotobyname: _getprotobyname,
|
|
getprotobynumber: _getprotobynumber,
|
|
invoke_i,
|
|
invoke_ii,
|
|
invoke_iii,
|
|
invoke_iiidii,
|
|
invoke_iiii,
|
|
invoke_iiiii,
|
|
invoke_iiiiii,
|
|
invoke_iiiiiii,
|
|
invoke_iiiiiiii,
|
|
invoke_iiiiiiiii,
|
|
invoke_iiiiiiiiii,
|
|
invoke_iiiiiiiiiii,
|
|
invoke_iiiiiiiiiiii,
|
|
invoke_iiiijj,
|
|
invoke_iiij,
|
|
invoke_iiijii,
|
|
invoke_iij,
|
|
invoke_iiji,
|
|
invoke_iijii,
|
|
invoke_iijiji,
|
|
invoke_ij,
|
|
invoke_ji,
|
|
invoke_jii,
|
|
invoke_jiii,
|
|
invoke_v,
|
|
invoke_vi,
|
|
invoke_vii,
|
|
invoke_viii,
|
|
invoke_viiii,
|
|
invoke_viiiii,
|
|
invoke_viiiiii,
|
|
invoke_viiiiiii,
|
|
invoke_viiiiiiii,
|
|
invoke_viiiiiiiii,
|
|
invoke_viiiiiiiiiii,
|
|
invoke_viiiiiiiiiiiii,
|
|
invoke_viiiiiiiiiiiiiii,
|
|
invoke_viiij,
|
|
invoke_vijj,
|
|
invoke_vji,
|
|
js_fd_read,
|
|
js_open_process: _js_open_process,
|
|
js_popen_clear_pid_for_fd: _js_popen_clear_pid_for_fd,
|
|
js_popen_get_pid_for_fd: _js_popen_get_pid_for_fd,
|
|
js_popen_set_pid_for_fd: _js_popen_set_pid_for_fd,
|
|
js_popen_to_file,
|
|
js_process_status: _js_process_status,
|
|
js_waitpid: _js_waitpid,
|
|
js_wasm_trace: _js_wasm_trace,
|
|
makecontext: _makecontext,
|
|
proc_exit: _proc_exit,
|
|
strptime: _strptime,
|
|
swapcontext: _swapcontext,
|
|
wasm_close: _wasm_close,
|
|
wasm_poll_socket,
|
|
wasm_setsockopt: _wasm_setsockopt,
|
|
wasm_shutdown: _wasm_shutdown,
|
|
};
|
|
function invoke_iiiiiii(index, a1, a2, a3, a4, a5, a6) {
|
|
var sp = stackSave();
|
|
try {
|
|
return dynCalls['iiiiiii'](index, a1, a2, a3, a4, a5, a6);
|
|
} catch (e) {
|
|
stackRestore(sp);
|
|
if (e !== e + 0) throw e;
|
|
_setThrew(1, 0);
|
|
}
|
|
}
|
|
function invoke_vi(index, a1) {
|
|
var sp = stackSave();
|
|
try {
|
|
dynCalls['vi'](index, a1);
|
|
} catch (e) {
|
|
stackRestore(sp);
|
|
if (e !== e + 0) throw e;
|
|
_setThrew(1, 0);
|
|
}
|
|
}
|
|
function invoke_iii(index, a1, a2) {
|
|
var sp = stackSave();
|
|
try {
|
|
return dynCalls['iii'](index, a1, a2);
|
|
} catch (e) {
|
|
stackRestore(sp);
|
|
if (e !== e + 0) throw e;
|
|
_setThrew(1, 0);
|
|
}
|
|
}
|
|
function invoke_iiiii(index, a1, a2, a3, a4) {
|
|
var sp = stackSave();
|
|
try {
|
|
return dynCalls['iiiii'](index, a1, a2, a3, a4);
|
|
} catch (e) {
|
|
stackRestore(sp);
|
|
if (e !== e + 0) throw e;
|
|
_setThrew(1, 0);
|
|
}
|
|
}
|
|
function invoke_ii(index, a1) {
|
|
var sp = stackSave();
|
|
try {
|
|
return dynCalls['ii'](index, a1);
|
|
} catch (e) {
|
|
stackRestore(sp);
|
|
if (e !== e + 0) throw e;
|
|
_setThrew(1, 0);
|
|
}
|
|
}
|
|
function invoke_iiii(index, a1, a2, a3) {
|
|
var sp = stackSave();
|
|
try {
|
|
return dynCalls['iiii'](index, a1, a2, a3);
|
|
} catch (e) {
|
|
stackRestore(sp);
|
|
if (e !== e + 0) throw e;
|
|
_setThrew(1, 0);
|
|
}
|
|
}
|
|
function invoke_viiii(index, a1, a2, a3, a4) {
|
|
var sp = stackSave();
|
|
try {
|
|
dynCalls['viiii'](index, a1, a2, a3, a4);
|
|
} catch (e) {
|
|
stackRestore(sp);
|
|
if (e !== e + 0) throw e;
|
|
_setThrew(1, 0);
|
|
}
|
|
}
|
|
function invoke_iiiiiiiiii(index, a1, a2, a3, a4, a5, a6, a7, a8, a9) {
|
|
var sp = stackSave();
|
|
try {
|
|
return dynCalls['iiiiiiiiii'](
|
|
index,
|
|
a1,
|
|
a2,
|
|
a3,
|
|
a4,
|
|
a5,
|
|
a6,
|
|
a7,
|
|
a8,
|
|
a9
|
|
);
|
|
} catch (e) {
|
|
stackRestore(sp);
|
|
if (e !== e + 0) throw e;
|
|
_setThrew(1, 0);
|
|
}
|
|
}
|
|
function invoke_jii(index, a1, a2) {
|
|
var sp = stackSave();
|
|
try {
|
|
return dynCalls['jii'](index, a1, a2);
|
|
} catch (e) {
|
|
stackRestore(sp);
|
|
if (e !== e + 0) throw e;
|
|
_setThrew(1, 0);
|
|
return 0n;
|
|
}
|
|
}
|
|
function invoke_vii(index, a1, a2) {
|
|
var sp = stackSave();
|
|
try {
|
|
dynCalls['vii'](index, a1, a2);
|
|
} catch (e) {
|
|
stackRestore(sp);
|
|
if (e !== e + 0) throw e;
|
|
_setThrew(1, 0);
|
|
}
|
|
}
|
|
function invoke_v(index) {
|
|
var sp = stackSave();
|
|
try {
|
|
dynCalls['v'](index);
|
|
} catch (e) {
|
|
stackRestore(sp);
|
|
if (e !== e + 0) throw e;
|
|
_setThrew(1, 0);
|
|
}
|
|
}
|
|
function invoke_i(index) {
|
|
var sp = stackSave();
|
|
try {
|
|
return dynCalls['i'](index);
|
|
} catch (e) {
|
|
stackRestore(sp);
|
|
if (e !== e + 0) throw e;
|
|
_setThrew(1, 0);
|
|
}
|
|
}
|
|
function invoke_vji(index, a1, a2) {
|
|
var sp = stackSave();
|
|
try {
|
|
dynCalls['vji'](index, a1, a2);
|
|
} catch (e) {
|
|
stackRestore(sp);
|
|
if (e !== e + 0) throw e;
|
|
_setThrew(1, 0);
|
|
}
|
|
}
|
|
function invoke_iiiiii(index, a1, a2, a3, a4, a5) {
|
|
var sp = stackSave();
|
|
try {
|
|
return dynCalls['iiiiii'](index, a1, a2, a3, a4, a5);
|
|
} catch (e) {
|
|
stackRestore(sp);
|
|
if (e !== e + 0) throw e;
|
|
_setThrew(1, 0);
|
|
}
|
|
}
|
|
function invoke_iiijii(index, a1, a2, a3, a4, a5) {
|
|
var sp = stackSave();
|
|
try {
|
|
return dynCalls['iiijii'](index, a1, a2, a3, a4, a5);
|
|
} catch (e) {
|
|
stackRestore(sp);
|
|
if (e !== e + 0) throw e;
|
|
_setThrew(1, 0);
|
|
}
|
|
}
|
|
function invoke_iiidii(index, a1, a2, a3, a4, a5) {
|
|
var sp = stackSave();
|
|
try {
|
|
return dynCalls['iiidii'](index, a1, a2, a3, a4, a5);
|
|
} catch (e) {
|
|
stackRestore(sp);
|
|
if (e !== e + 0) throw e;
|
|
_setThrew(1, 0);
|
|
}
|
|
}
|
|
function invoke_viii(index, a1, a2, a3) {
|
|
var sp = stackSave();
|
|
try {
|
|
dynCalls['viii'](index, a1, a2, a3);
|
|
} catch (e) {
|
|
stackRestore(sp);
|
|
if (e !== e + 0) throw e;
|
|
_setThrew(1, 0);
|
|
}
|
|
}
|
|
function invoke_jiii(index, a1, a2, a3) {
|
|
var sp = stackSave();
|
|
try {
|
|
return dynCalls['jiii'](index, a1, a2, a3);
|
|
} catch (e) {
|
|
stackRestore(sp);
|
|
if (e !== e + 0) throw e;
|
|
_setThrew(1, 0);
|
|
return 0n;
|
|
}
|
|
}
|
|
function invoke_iiij(index, a1, a2, a3) {
|
|
var sp = stackSave();
|
|
try {
|
|
return dynCalls['iiij'](index, a1, a2, a3);
|
|
} catch (e) {
|
|
stackRestore(sp);
|
|
if (e !== e + 0) throw e;
|
|
_setThrew(1, 0);
|
|
}
|
|
}
|
|
function invoke_ji(index, a1) {
|
|
var sp = stackSave();
|
|
try {
|
|
return dynCalls['ji'](index, a1);
|
|
} catch (e) {
|
|
stackRestore(sp);
|
|
if (e !== e + 0) throw e;
|
|
_setThrew(1, 0);
|
|
return 0n;
|
|
}
|
|
}
|
|
function invoke_vijj(index, a1, a2, a3) {
|
|
var sp = stackSave();
|
|
try {
|
|
dynCalls['vijj'](index, a1, a2, a3);
|
|
} catch (e) {
|
|
stackRestore(sp);
|
|
if (e !== e + 0) throw e;
|
|
_setThrew(1, 0);
|
|
}
|
|
}
|
|
function invoke_iij(index, a1, a2) {
|
|
var sp = stackSave();
|
|
try {
|
|
return dynCalls['iij'](index, a1, a2);
|
|
} catch (e) {
|
|
stackRestore(sp);
|
|
if (e !== e + 0) throw e;
|
|
_setThrew(1, 0);
|
|
}
|
|
}
|
|
function invoke_viiiii(index, a1, a2, a3, a4, a5) {
|
|
var sp = stackSave();
|
|
try {
|
|
dynCalls['viiiii'](index, a1, a2, a3, a4, a5);
|
|
} catch (e) {
|
|
stackRestore(sp);
|
|
if (e !== e + 0) throw e;
|
|
_setThrew(1, 0);
|
|
}
|
|
}
|
|
function invoke_iijii(index, a1, a2, a3, a4) {
|
|
var sp = stackSave();
|
|
try {
|
|
return dynCalls['iijii'](index, a1, a2, a3, a4);
|
|
} catch (e) {
|
|
stackRestore(sp);
|
|
if (e !== e + 0) throw e;
|
|
_setThrew(1, 0);
|
|
}
|
|
}
|
|
function invoke_iijiji(index, a1, a2, a3, a4, a5) {
|
|
var sp = stackSave();
|
|
try {
|
|
return dynCalls['iijiji'](index, a1, a2, a3, a4, a5);
|
|
} catch (e) {
|
|
stackRestore(sp);
|
|
if (e !== e + 0) throw e;
|
|
_setThrew(1, 0);
|
|
}
|
|
}
|
|
function invoke_iiiiiiii(index, a1, a2, a3, a4, a5, a6, a7) {
|
|
var sp = stackSave();
|
|
try {
|
|
return dynCalls['iiiiiiii'](index, a1, a2, a3, a4, a5, a6, a7);
|
|
} catch (e) {
|
|
stackRestore(sp);
|
|
if (e !== e + 0) throw e;
|
|
_setThrew(1, 0);
|
|
}
|
|
}
|
|
function invoke_iiji(index, a1, a2, a3) {
|
|
var sp = stackSave();
|
|
try {
|
|
return dynCalls['iiji'](index, a1, a2, a3);
|
|
} catch (e) {
|
|
stackRestore(sp);
|
|
if (e !== e + 0) throw e;
|
|
_setThrew(1, 0);
|
|
}
|
|
}
|
|
function invoke_viiij(index, a1, a2, a3, a4) {
|
|
var sp = stackSave();
|
|
try {
|
|
dynCalls['viiij'](index, a1, a2, a3, a4);
|
|
} catch (e) {
|
|
stackRestore(sp);
|
|
if (e !== e + 0) throw e;
|
|
_setThrew(1, 0);
|
|
}
|
|
}
|
|
function invoke_viiiiiii(index, a1, a2, a3, a4, a5, a6, a7) {
|
|
var sp = stackSave();
|
|
try {
|
|
dynCalls['viiiiiii'](index, a1, a2, a3, a4, a5, a6, a7);
|
|
} catch (e) {
|
|
stackRestore(sp);
|
|
if (e !== e + 0) throw e;
|
|
_setThrew(1, 0);
|
|
}
|
|
}
|
|
function invoke_iiiiiiiii(index, a1, a2, a3, a4, a5, a6, a7, a8) {
|
|
var sp = stackSave();
|
|
try {
|
|
return dynCalls['iiiiiiiii'](index, a1, a2, a3, a4, a5, a6, a7, a8);
|
|
} catch (e) {
|
|
stackRestore(sp);
|
|
if (e !== e + 0) throw e;
|
|
_setThrew(1, 0);
|
|
}
|
|
}
|
|
function invoke_viiiiiiii(index, a1, a2, a3, a4, a5, a6, a7, a8) {
|
|
var sp = stackSave();
|
|
try {
|
|
dynCalls['viiiiiiii'](index, a1, a2, a3, a4, a5, a6, a7, a8);
|
|
} catch (e) {
|
|
stackRestore(sp);
|
|
if (e !== e + 0) throw e;
|
|
_setThrew(1, 0);
|
|
}
|
|
}
|
|
function invoke_viiiiii(index, a1, a2, a3, a4, a5, a6) {
|
|
var sp = stackSave();
|
|
try {
|
|
dynCalls['viiiiii'](index, a1, a2, a3, a4, a5, a6);
|
|
} catch (e) {
|
|
stackRestore(sp);
|
|
if (e !== e + 0) throw e;
|
|
_setThrew(1, 0);
|
|
}
|
|
}
|
|
function invoke_viiiiiiiii(index, a1, a2, a3, a4, a5, a6, a7, a8, a9) {
|
|
var sp = stackSave();
|
|
try {
|
|
dynCalls['viiiiiiiii'](index, a1, a2, a3, a4, a5, a6, a7, a8, a9);
|
|
} catch (e) {
|
|
stackRestore(sp);
|
|
if (e !== e + 0) throw e;
|
|
_setThrew(1, 0);
|
|
}
|
|
}
|
|
function invoke_viiiiiiiiiiiii(
|
|
index,
|
|
a1,
|
|
a2,
|
|
a3,
|
|
a4,
|
|
a5,
|
|
a6,
|
|
a7,
|
|
a8,
|
|
a9,
|
|
a10,
|
|
a11,
|
|
a12,
|
|
a13
|
|
) {
|
|
var sp = stackSave();
|
|
try {
|
|
dynCalls['viiiiiiiiiiiii'](
|
|
index,
|
|
a1,
|
|
a2,
|
|
a3,
|
|
a4,
|
|
a5,
|
|
a6,
|
|
a7,
|
|
a8,
|
|
a9,
|
|
a10,
|
|
a11,
|
|
a12,
|
|
a13
|
|
);
|
|
} catch (e) {
|
|
stackRestore(sp);
|
|
if (e !== e + 0) throw e;
|
|
_setThrew(1, 0);
|
|
}
|
|
}
|
|
function invoke_viiiiiiiiiiiiiii(
|
|
index,
|
|
a1,
|
|
a2,
|
|
a3,
|
|
a4,
|
|
a5,
|
|
a6,
|
|
a7,
|
|
a8,
|
|
a9,
|
|
a10,
|
|
a11,
|
|
a12,
|
|
a13,
|
|
a14,
|
|
a15
|
|
) {
|
|
var sp = stackSave();
|
|
try {
|
|
dynCalls['viiiiiiiiiiiiiii'](
|
|
index,
|
|
a1,
|
|
a2,
|
|
a3,
|
|
a4,
|
|
a5,
|
|
a6,
|
|
a7,
|
|
a8,
|
|
a9,
|
|
a10,
|
|
a11,
|
|
a12,
|
|
a13,
|
|
a14,
|
|
a15
|
|
);
|
|
} catch (e) {
|
|
stackRestore(sp);
|
|
if (e !== e + 0) throw e;
|
|
_setThrew(1, 0);
|
|
}
|
|
}
|
|
function invoke_iiiiiiiiiiii(
|
|
index,
|
|
a1,
|
|
a2,
|
|
a3,
|
|
a4,
|
|
a5,
|
|
a6,
|
|
a7,
|
|
a8,
|
|
a9,
|
|
a10,
|
|
a11
|
|
) {
|
|
var sp = stackSave();
|
|
try {
|
|
return dynCalls['iiiiiiiiiiii'](
|
|
index,
|
|
a1,
|
|
a2,
|
|
a3,
|
|
a4,
|
|
a5,
|
|
a6,
|
|
a7,
|
|
a8,
|
|
a9,
|
|
a10,
|
|
a11
|
|
);
|
|
} catch (e) {
|
|
stackRestore(sp);
|
|
if (e !== e + 0) throw e;
|
|
_setThrew(1, 0);
|
|
}
|
|
}
|
|
function invoke_iiiijj(index, a1, a2, a3, a4, a5) {
|
|
var sp = stackSave();
|
|
try {
|
|
return dynCalls['iiiijj'](index, a1, a2, a3, a4, a5);
|
|
} catch (e) {
|
|
stackRestore(sp);
|
|
if (e !== e + 0) throw e;
|
|
_setThrew(1, 0);
|
|
}
|
|
}
|
|
function invoke_ij(index, a1) {
|
|
var sp = stackSave();
|
|
try {
|
|
return dynCalls['ij'](index, a1);
|
|
} catch (e) {
|
|
stackRestore(sp);
|
|
if (e !== e + 0) throw e;
|
|
_setThrew(1, 0);
|
|
}
|
|
}
|
|
function invoke_iiiiiiiiiii(
|
|
index,
|
|
a1,
|
|
a2,
|
|
a3,
|
|
a4,
|
|
a5,
|
|
a6,
|
|
a7,
|
|
a8,
|
|
a9,
|
|
a10
|
|
) {
|
|
var sp = stackSave();
|
|
try {
|
|
return dynCalls['iiiiiiiiiii'](
|
|
index,
|
|
a1,
|
|
a2,
|
|
a3,
|
|
a4,
|
|
a5,
|
|
a6,
|
|
a7,
|
|
a8,
|
|
a9,
|
|
a10
|
|
);
|
|
} catch (e) {
|
|
stackRestore(sp);
|
|
if (e !== e + 0) throw e;
|
|
_setThrew(1, 0);
|
|
}
|
|
}
|
|
function invoke_viiiiiiiiiii(
|
|
index,
|
|
a1,
|
|
a2,
|
|
a3,
|
|
a4,
|
|
a5,
|
|
a6,
|
|
a7,
|
|
a8,
|
|
a9,
|
|
a10,
|
|
a11
|
|
) {
|
|
var sp = stackSave();
|
|
try {
|
|
dynCalls['viiiiiiiiiii'](
|
|
index,
|
|
a1,
|
|
a2,
|
|
a3,
|
|
a4,
|
|
a5,
|
|
a6,
|
|
a7,
|
|
a8,
|
|
a9,
|
|
a10,
|
|
a11
|
|
);
|
|
} catch (e) {
|
|
stackRestore(sp);
|
|
if (e !== e + 0) throw e;
|
|
_setThrew(1, 0);
|
|
}
|
|
}
|
|
function callMain(args = []) {
|
|
var entryFunction = resolveGlobalSymbol('main').sym;
|
|
if (!entryFunction) return;
|
|
args.unshift(thisProgram);
|
|
var argc = args.length;
|
|
var argv = stackAlloc((argc + 1) * 4);
|
|
var argv_ptr = argv;
|
|
for (var arg of args) {
|
|
HEAPU32[argv_ptr >> 2] = stringToUTF8OnStack(arg);
|
|
argv_ptr += 4;
|
|
}
|
|
HEAPU32[argv_ptr >> 2] = 0;
|
|
try {
|
|
var ret = entryFunction(argc, argv);
|
|
exitJS(ret, true);
|
|
return ret;
|
|
} catch (e) {
|
|
return handleException(e);
|
|
}
|
|
}
|
|
function run(args = arguments_) {
|
|
if (runDependencies > 0) {
|
|
dependenciesFulfilled = run;
|
|
return;
|
|
}
|
|
preRun();
|
|
if (runDependencies > 0) {
|
|
dependenciesFulfilled = run;
|
|
return;
|
|
}
|
|
function doRun() {
|
|
Module['calledRun'] = true;
|
|
if (ABORT) return;
|
|
initRuntime();
|
|
preMain();
|
|
Module['onRuntimeInitialized']?.();
|
|
var noInitialRun = Module['noInitialRun'] || true;
|
|
if (!noInitialRun) callMain(args);
|
|
postRun();
|
|
}
|
|
if (Module['setStatus']) {
|
|
Module['setStatus']('Running...');
|
|
setTimeout(() => {
|
|
setTimeout(() => Module['setStatus'](''), 1);
|
|
doRun();
|
|
}, 1);
|
|
} else {
|
|
doRun();
|
|
}
|
|
}
|
|
var wasmExports;
|
|
createWasm();
|
|
run();
|
|
/**
|
|
* Emscripten resolves `localhost` to a random IP address. Let's
|
|
* make it always resolve to 127.0.0.1.
|
|
*/
|
|
DNS.address_map.addrs.localhost = '127.0.0.1';
|
|
|
|
/**
|
|
* Debugging Asyncify errors is tricky because the stack trace is lost when the
|
|
* error is thrown. This code saves the stack trace in a global variable
|
|
* so that it can be inspected later.
|
|
*/
|
|
PHPLoader.debug = 'debug' in PHPLoader ? PHPLoader.debug : true;
|
|
if (PHPLoader.debug && typeof Asyncify !== 'undefined') {
|
|
const originalHandleSleep = Asyncify.handleSleep;
|
|
Asyncify.handleSleep = function (startAsync) {
|
|
if (!ABORT) {
|
|
Module['lastAsyncifyStackSource'] = new Error();
|
|
}
|
|
return originalHandleSleep(startAsync);
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Data dependencies call removeRunDependency() when they are loaded.
|
|
* The synchronous call stack then continues to run. If an error occurs
|
|
* in PHP initialization, e.g. Out Of Memory error, it will not be
|
|
* caught by any try/catch. This override propagates the failure to
|
|
* PHPLoader.onAbort() so that it can be handled.
|
|
*/
|
|
const originalRemoveRunDependency = PHPLoader['removeRunDependency'];
|
|
PHPLoader['removeRunDependency'] = function (...args) {
|
|
try {
|
|
originalRemoveRunDependency(...args);
|
|
} catch (e) {
|
|
PHPLoader['onAbort'](e);
|
|
}
|
|
};
|
|
|
|
if (typeof NODEFS === 'object') {
|
|
// We override NODEFS.createNode() to add an `isSharedFS` flag to all NODEFS
|
|
// nodes. This way we can tell whether file-locking is needed and possible
|
|
// for an FS node, even if wrapped with PROXYFS.
|
|
const originalNodeFsCreateNode = NODEFS.createNode;
|
|
NODEFS.createNode = function createNodeWithSharedFlag() {
|
|
const node = originalNodeFsCreateNode.apply(NODEFS, arguments);
|
|
node.isSharedFS = true;
|
|
return node;
|
|
};
|
|
|
|
var originalHashAddNode = FS.hashAddNode;
|
|
FS.hashAddNode = function hashAddNodeIfNotSharedFS(node) {
|
|
if (node?.isSharedFS) {
|
|
// Avoid caching shared VFS nodes so multiple instances
|
|
// can access the same underlying filesystem without
|
|
// conflicting caches.
|
|
return;
|
|
}
|
|
return originalHashAddNode.apply(FS, arguments);
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Expose the PHP version so the PHP class can make version-specific
|
|
* adjustments to `php.ini`.
|
|
*/
|
|
PHPLoader['phpVersion'] = (() => {
|
|
const [major, minor, patch] = phpVersionString.split('.').map(Number);
|
|
return { major, minor, patch };
|
|
})();
|
|
|
|
return PHPLoader;
|
|
|
|
// Close the opening bracket from esm-prefix.js:
|
|
}
|