UNPKG

@marioslab/ulang-vm

Version:

Virtual machine & assembler for recreational programming like it's 1992.

1,373 lines (1,369 loc) 53.9 kB
var ulang = (() => { var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var __async = (__this, __arguments, generator) => { return new Promise((resolve, reject) => { var fulfilled = (value) => { try { step(generator.next(value)); } catch (e) { reject(e); } }; var rejected = (value) => { try { step(generator.throw(value)); } catch (e) { reject(e); } }; var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected); step((generator = generator.apply(__this, __arguments)).next()); }); }; // vm/src/index.ts var src_exports = {}; __export(src_exports, { LogLevel: () => LogLevel, UlangPlayer: () => UlangPlayer, VirtualMachine: () => VirtualMachine, VirtualMachineState: () => VirtualMachineState, compile: () => compile, createPlayerFromGist: () => createPlayerFromGist, loadUlang: () => loadUlang2, printMemory: () => printMemory }); // vm/src/ulang.js var loadWasm = (() => { var _scriptDir = typeof document !== "undefined" && document.currentScript ? document.currentScript.src : void 0; return function(loadWasm2) { loadWasm2 = loadWasm2 || {}; null; var Module = typeof loadWasm2 != "undefined" ? loadWasm2 : {}; var readyPromiseResolve, readyPromiseReject; Module["ready"] = new Promise(function(resolve, reject) { readyPromiseResolve = resolve; readyPromiseReject = reject; }); var moduleOverrides = Object.assign({}, Module); var arguments_ = []; var thisProgram = "./this.program"; var quit_ = (status, toThrow) => { throw toThrow; }; var ENVIRONMENT_IS_WEB = true; var ENVIRONMENT_IS_WORKER = false; var scriptDirectory = ""; function locateFile(path) { if (Module["locateFile"]) { return Module["locateFile"](path, scriptDirectory); } return scriptDirectory + path; } var read_, readAsync, readBinary, setWindowTitle; if (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) { if (ENVIRONMENT_IS_WORKER) { scriptDirectory = self.location.href; } else if (typeof document != "undefined" && document.currentScript) { scriptDirectory = document.currentScript.src; } if (_scriptDir) { scriptDirectory = _scriptDir; } if (scriptDirectory.indexOf("blob:") !== 0) { scriptDirectory = scriptDirectory.substr(0, scriptDirectory.replace(/[?#].*/, "").lastIndexOf("/") + 1); } else { scriptDirectory = ""; } { read_ = (url) => { var xhr = new XMLHttpRequest(); xhr.open("GET", url, false); xhr.send(null); return xhr.responseText; }; 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 = (url, onload, onerror) => { var xhr = new XMLHttpRequest(); xhr.open("GET", url, true); xhr.responseType = "arraybuffer"; xhr.onload = () => { if (xhr.status == 200 || xhr.status == 0 && xhr.response) { onload(xhr.response); return; } onerror(); }; xhr.onerror = onerror; xhr.send(null); }; } setWindowTitle = (title) => document.title = title; } else { } var out = Module["print"] || console.log.bind(console); var err = Module["printErr"] || console.warn.bind(console); Object.assign(Module, moduleOverrides); moduleOverrides = null; if (Module["arguments"]) arguments_ = Module["arguments"]; if (Module["thisProgram"]) thisProgram = Module["thisProgram"]; if (Module["quit"]) quit_ = Module["quit"]; function convertJsFunctionToWasm(func, sig) { if (typeof WebAssembly.Function == "function") { var typeNames = { "i": "i32", "j": "i64", "f": "f32", "d": "f64" }; var type = { parameters: [], results: sig[0] == "v" ? [] : [typeNames[sig[0]]] }; for (var i = 1; i < sig.length; ++i) { type.parameters.push(typeNames[sig[i]]); } return new WebAssembly.Function(type, func); } var typeSection = [1, 0, 1, 96]; var sigRet = sig.slice(0, 1); var sigParam = sig.slice(1); var typeCodes = { "i": 127, "j": 126, "f": 125, "d": 124 }; typeSection.push(sigParam.length); for (var i = 0; i < sigParam.length; ++i) { typeSection.push(typeCodes[sigParam[i]]); } if (sigRet == "v") { typeSection.push(0); } else { typeSection = typeSection.concat([1, typeCodes[sigRet]]); } typeSection[1] = typeSection.length - 2; var bytes = new Uint8Array([0, 97, 115, 109, 1, 0, 0, 0].concat(typeSection, [2, 7, 1, 1, 101, 1, 102, 0, 0, 7, 5, 1, 1, 102, 0, 0])); var module2 = new WebAssembly.Module(bytes); var instance = new WebAssembly.Instance(module2, { "e": { "f": func } }); var wrappedFunc = instance.exports["f"]; return wrappedFunc; } var freeTableIndexes = []; var functionsInTableMap; function getEmptyTableSlot() { if (freeTableIndexes.length) { return freeTableIndexes.pop(); } try { wasmTable.grow(1); } catch (err2) { if (!(err2 instanceof RangeError)) { throw err2; } throw "Unable to grow wasm table. Set ALLOW_TABLE_GROWTH."; } return wasmTable.length - 1; } function updateTableMap(offset, count) { for (var i = offset; i < offset + count; i++) { var item = getWasmTableEntry(i); if (item) { functionsInTableMap.set(item, i); } } } function addFunction2(func, sig) { if (!functionsInTableMap) { functionsInTableMap = /* @__PURE__ */ new WeakMap(); updateTableMap(0, wasmTable.length); } if (functionsInTableMap.has(func)) { return functionsInTableMap.get(func); } var ret = getEmptyTableSlot(); try { setWasmTableEntry(ret, func); } catch (err2) { if (!(err2 instanceof TypeError)) { throw err2; } var wrapped = convertJsFunctionToWasm(func, sig); setWasmTableEntry(ret, wrapped); } functionsInTableMap.set(func, ret); return ret; } var wasmBinary; if (Module["wasmBinary"]) wasmBinary = Module["wasmBinary"]; var noExitRuntime = Module["noExitRuntime"] || true; if (typeof WebAssembly != "object") { abort("no native wasm support detected"); } var wasmMemory; var ABORT = false; var EXITSTATUS; function getCFunc(ident) { var func = Module["_" + ident]; return func; } function ccall(ident, returnType, argTypes, args, opts) { var toC = { "string": function(str) { var ret2 = 0; if (str !== null && str !== void 0 && str !== 0) { var len = (str.length << 2) + 1; ret2 = stackAlloc(len); stringToUTF8(str, ret2, len); } return ret2; }, "array": function(arr) { var ret2 = stackAlloc(arr.length); writeArrayToMemory(arr, ret2); return ret2; } }; function convertReturnValue(ret2) { if (returnType === "string") return UTF8ToString(ret2); if (returnType === "boolean") return Boolean(ret2); return ret2; } 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 ret = func.apply(null, cArgs); function onDone(ret2) { if (stack !== 0) stackRestore(stack); return convertReturnValue(ret2); } ret = onDone(ret); return ret; } function cwrap(ident, returnType, argTypes, opts) { argTypes = argTypes || []; var numericArgs = argTypes.every(function(type) { return type === "number"; }); var numericRet = returnType !== "string"; if (numericRet && numericArgs && !opts) { return getCFunc(ident); } return function() { return ccall(ident, returnType, argTypes, arguments, opts); }; } var UTF8Decoder = typeof TextDecoder != "undefined" ? new TextDecoder("utf8") : void 0; function UTF8ArrayToString2(heap, idx, maxBytesToRead) { var endIdx = idx + maxBytesToRead; var endPtr = idx; while (heap[endPtr] && !(endPtr >= endIdx)) ++endPtr; if (endPtr - idx > 16 && heap.subarray && UTF8Decoder) { return UTF8Decoder.decode(heap.subarray(idx, endPtr)); } else { var str = ""; while (idx < endPtr) { var u0 = heap[idx++]; if (!(u0 & 128)) { str += String.fromCharCode(u0); continue; } var u1 = heap[idx++] & 63; if ((u0 & 224) == 192) { str += String.fromCharCode((u0 & 31) << 6 | u1); continue; } var u2 = heap[idx++] & 63; if ((u0 & 240) == 224) { u0 = (u0 & 15) << 12 | u1 << 6 | u2; } else { u0 = (u0 & 7) << 18 | u1 << 12 | u2 << 6 | heap[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; } function UTF8ToString(ptr, maxBytesToRead) { return ptr ? UTF8ArrayToString2(HEAPU82, ptr, maxBytesToRead) : ""; } function 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.charCodeAt(i); if (u >= 55296 && u <= 57343) { var u1 = str.charCodeAt(++i); u = 65536 + ((u & 1023) << 10) | u1 & 1023; } 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; } } heap[outIdx] = 0; return outIdx - startIdx; } function stringToUTF8(str, outPtr, maxBytesToWrite) { return stringToUTF8Array(str, HEAPU82, outPtr, maxBytesToWrite); } function lengthBytesUTF8(str) { var len = 0; for (var i = 0; i < str.length; ++i) { var u = str.charCodeAt(i); if (u >= 55296 && u <= 57343) u = 65536 + ((u & 1023) << 10) | str.charCodeAt(++i) & 1023; if (u <= 127) ++len; else if (u <= 2047) len += 2; else if (u <= 65535) len += 3; else len += 4; } return len; } function allocateUTF8(str) { var size = lengthBytesUTF8(str) + 1; var ret = _malloc(size); if (ret) stringToUTF8Array(str, HEAP8, ret, size); return ret; } function writeArrayToMemory(array, buffer2) { HEAP8.set(array, buffer2); } var buffer, HEAP8, HEAPU82, HEAP16, HEAPU16, HEAP32, HEAPU32, HEAPF32, HEAPF64; function updateGlobalBufferAndViews(buf) { buffer = buf; Module["HEAP8"] = HEAP8 = new Int8Array(buf); Module["HEAP16"] = HEAP16 = new Int16Array(buf); Module["HEAP32"] = HEAP32 = new Int32Array(buf); Module["HEAPU8"] = HEAPU82 = new Uint8Array(buf); Module["HEAPU16"] = HEAPU16 = new Uint16Array(buf); Module["HEAPU32"] = HEAPU32 = new Uint32Array(buf); Module["HEAPF32"] = HEAPF32 = new Float32Array(buf); Module["HEAPF64"] = HEAPF64 = new Float64Array(buf); } var INITIAL_MEMORY = Module["INITIAL_MEMORY"] || 16777216; var wasmTable; var __ATPRERUN__ = []; var __ATINIT__ = []; var __ATPOSTRUN__ = []; var runtimeInitialized = false; function preRun() { if (Module["preRun"]) { if (typeof Module["preRun"] == "function") Module["preRun"] = [Module["preRun"]]; while (Module["preRun"].length) { addOnPreRun(Module["preRun"].shift()); } } callRuntimeCallbacks(__ATPRERUN__); } function initRuntime() { runtimeInitialized = true; callRuntimeCallbacks(__ATINIT__); } function postRun() { if (Module["postRun"]) { if (typeof Module["postRun"] == "function") Module["postRun"] = [Module["postRun"]]; while (Module["postRun"].length) { addOnPostRun(Module["postRun"].shift()); } } callRuntimeCallbacks(__ATPOSTRUN__); } function addOnPreRun(cb) { __ATPRERUN__.unshift(cb); } function addOnInit(cb) { __ATINIT__.unshift(cb); } function addOnPostRun(cb) { __ATPOSTRUN__.unshift(cb); } var runDependencies = 0; var runDependencyWatcher = null; var dependenciesFulfilled = null; function addRunDependency(id) { runDependencies++; if (Module["monitorRunDependencies"]) { Module["monitorRunDependencies"](runDependencies); } } function removeRunDependency(id) { runDependencies--; if (Module["monitorRunDependencies"]) { Module["monitorRunDependencies"](runDependencies); } if (runDependencies == 0) { if (runDependencyWatcher !== null) { clearInterval(runDependencyWatcher); runDependencyWatcher = null; } if (dependenciesFulfilled) { var callback = dependenciesFulfilled; dependenciesFulfilled = null; callback(); } } } Module["preloadedImages"] = {}; Module["preloadedAudios"] = {}; function abort(what) { { if (Module["onAbort"]) { Module["onAbort"](what); } } what = "Aborted(" + what + ")"; err(what); ABORT = true; EXITSTATUS = 1; what += ". Build with -s ASSERTIONS=1 for more info."; var e = new WebAssembly.RuntimeError(what); readyPromiseReject(e); throw e; } var dataURIPrefix = "data:application/octet-stream;base64,"; function isDataURI(filename) { return filename.startsWith(dataURIPrefix); } var wasmBinaryFile; wasmBinaryFile = "ulang.wasm"; if (!isDataURI(wasmBinaryFile)) { wasmBinaryFile = locateFile(wasmBinaryFile); } function getBinary(file) { try { if (file == wasmBinaryFile && wasmBinary) { return new Uint8Array(wasmBinary); } if (readBinary) { return readBinary(file); } else { throw "both async and sync fetching of the wasm failed"; } } catch (err2) { abort(err2); } } function getBinaryPromise() { if (!wasmBinary && (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER)) { if (typeof fetch == "function") { return fetch(wasmBinaryFile, { credentials: "same-origin" }).then(function(response) { if (!response["ok"]) { throw "failed to load wasm binary file at '" + wasmBinaryFile + "'"; } return response["arrayBuffer"](); }).catch(function() { return getBinary(wasmBinaryFile); }); } } return Promise.resolve().then(function() { return getBinary(wasmBinaryFile); }); } function createWasm() { var info = { "a": asmLibraryArg }; function receiveInstance(instance, module2) { var exports2 = instance.exports; Module["asm"] = exports2; wasmMemory = Module["asm"]["d"]; updateGlobalBufferAndViews(wasmMemory.buffer); wasmTable = Module["asm"]["F"]; addOnInit(Module["asm"]["e"]); removeRunDependency("wasm-instantiate"); } addRunDependency("wasm-instantiate"); function receiveInstantiationResult(result) { receiveInstance(result["instance"]); } function instantiateArrayBuffer(receiver) { return getBinaryPromise().then(function(binary) { return WebAssembly.instantiate(binary, info); }).then(function(instance) { return instance; }).then(receiver, function(reason) { err("failed to asynchronously prepare wasm: " + reason); abort(reason); }); } function instantiateAsync() { if (!wasmBinary && typeof WebAssembly.instantiateStreaming == "function" && !isDataURI(wasmBinaryFile) && typeof fetch == "function") { return fetch(wasmBinaryFile, { credentials: "same-origin" }).then(function(response) { var result = WebAssembly.instantiateStreaming(response, info); return result.then(receiveInstantiationResult, function(reason) { err("wasm streaming compile failed: " + reason); err("falling back to ArrayBuffer instantiation"); return instantiateArrayBuffer(receiveInstantiationResult); }); }); } else { return instantiateArrayBuffer(receiveInstantiationResult); } } if (Module["instantiateWasm"]) { try { var exports = Module["instantiateWasm"](info, receiveInstance); return exports; } catch (e) { err("Module.instantiateWasm callback failed with error: " + e); return false; } } instantiateAsync().catch(readyPromiseReject); return {}; } function callRuntimeCallbacks(callbacks) { while (callbacks.length > 0) { var callback = callbacks.shift(); if (typeof callback == "function") { callback(Module); continue; } var func = callback.func; if (typeof func == "number") { if (callback.arg === void 0) { getWasmTableEntry(func)(); } else { getWasmTableEntry(func)(callback.arg); } } else { func(callback.arg === void 0 ? null : callback.arg); } } } var wasmTableMirror = []; function getWasmTableEntry(funcPtr) { var func = wasmTableMirror[funcPtr]; if (!func) { if (funcPtr >= wasmTableMirror.length) wasmTableMirror.length = funcPtr + 1; wasmTableMirror[funcPtr] = func = wasmTable.get(funcPtr); } return func; } function setWasmTableEntry(idx, func) { wasmTable.set(idx, func); wasmTableMirror[idx] = func; } function _emscripten_memcpy_big(dest, src, num) { HEAPU82.copyWithin(dest, src, src + num); } function _emscripten_get_heap_max() { return 2147483648; } function emscripten_realloc_buffer(size) { try { wasmMemory.grow(size - buffer.byteLength + 65535 >>> 16); updateGlobalBufferAndViews(wasmMemory.buffer); return 1; } catch (e) { } } function _emscripten_resize_heap(requestedSize) { var oldSize = HEAPU82.length; requestedSize = requestedSize >>> 0; var maxHeapSize = _emscripten_get_heap_max(); if (requestedSize > maxHeapSize) { return false; } let alignUp = (x, multiple) => x + (multiple - x % multiple) % multiple; 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, alignUp(Math.max(requestedSize, overGrownHeapSize), 65536)); var replacement = emscripten_realloc_buffer(newSize); if (replacement) { return true; } } return false; } var SYSCALLS = { buffers: [null, [], []], printChar: function(stream, curr) { var buffer2 = SYSCALLS.buffers[stream]; if (curr === 0 || curr === 10) { (stream === 1 ? out : err)(UTF8ArrayToString2(buffer2, 0)); buffer2.length = 0; } else { buffer2.push(curr); } }, varargs: void 0, get: function() { SYSCALLS.varargs += 4; var ret = HEAP32[SYSCALLS.varargs - 4 >> 2]; return ret; }, getStr: function(ptr) { var ret = UTF8ToString(ptr); return ret; }, get64: function(low, high) { return low; } }; function _fd_write(fd, iov, iovcnt, pnum) { var num = 0; for (var i = 0; i < iovcnt; i++) { var ptr = HEAP32[iov >> 2]; var len = HEAP32[iov + 4 >> 2]; iov += 8; for (var j = 0; j < len; j++) { SYSCALLS.printChar(fd, HEAPU82[ptr + j]); } num += len; } HEAP32[pnum >> 2] = num; return 0; } var asmLibraryArg = { "c": _emscripten_memcpy_big, "b": _emscripten_resize_heap, "a": _fd_write }; var asm = createWasm(); var ___wasm_call_ctors = Module["___wasm_call_ctors"] = function() { return (___wasm_call_ctors = Module["___wasm_call_ctors"] = Module["asm"]["e"]).apply(null, arguments); }; var _malloc = Module["_malloc"] = function() { return (_malloc = Module["_malloc"] = Module["asm"]["f"]).apply(null, arguments); }; var _free = Module["_free"] = function() { return (_free = Module["_free"] = Module["asm"]["g"]).apply(null, arguments); }; var _ulang_free = Module["_ulang_free"] = function() { return (_ulang_free = Module["_ulang_free"] = Module["asm"]["h"]).apply(null, arguments); }; var _ulang_calloc = Module["_ulang_calloc"] = function() { return (_ulang_calloc = Module["_ulang_calloc"] = Module["asm"]["i"]).apply(null, arguments); }; var _ulang_print_memory = Module["_ulang_print_memory"] = function() { return (_ulang_print_memory = Module["_ulang_print_memory"] = Module["asm"]["j"]).apply(null, arguments); }; var _ulang_file_from_memory = Module["_ulang_file_from_memory"] = function() { return (_ulang_file_from_memory = Module["_ulang_file_from_memory"] = Module["asm"]["k"]).apply(null, arguments); }; var _ulang_file_free = Module["_ulang_file_free"] = function() { return (_ulang_file_free = Module["_ulang_file_free"] = Module["asm"]["l"]).apply(null, arguments); }; var _ulang_error_free = Module["_ulang_error_free"] = function() { return (_ulang_error_free = Module["_ulang_error_free"] = Module["asm"]["m"]).apply(null, arguments); }; var _ulang_error_print = Module["_ulang_error_print"] = function() { return (_ulang_error_print = Module["_ulang_error_print"] = Module["asm"]["n"]).apply(null, arguments); }; var _ulang_compile = Module["_ulang_compile"] = function() { return (_ulang_compile = Module["_ulang_compile"] = Module["asm"]["o"]).apply(null, arguments); }; var _ulang_program_free = Module["_ulang_program_free"] = function() { return (_ulang_program_free = Module["_ulang_program_free"] = Module["asm"]["p"]).apply(null, arguments); }; var _ulang_vm_print = Module["_ulang_vm_print"] = function() { return (_ulang_vm_print = Module["_ulang_vm_print"] = Module["asm"]["q"]).apply(null, arguments); }; var _ulang_vm_step = Module["_ulang_vm_step"] = function() { return (_ulang_vm_step = Module["_ulang_vm_step"] = Module["asm"]["r"]).apply(null, arguments); }; var _ulang_vm_init = Module["_ulang_vm_init"] = function() { return (_ulang_vm_init = Module["_ulang_vm_init"] = Module["asm"]["s"]).apply(null, arguments); }; var _ulang_vm_step_n = Module["_ulang_vm_step_n"] = function() { return (_ulang_vm_step_n = Module["_ulang_vm_step_n"] = Module["asm"]["t"]).apply(null, arguments); }; var _ulang_vm_step_n_bp = Module["_ulang_vm_step_n_bp"] = function() { return (_ulang_vm_step_n_bp = Module["_ulang_vm_step_n_bp"] = Module["asm"]["u"]).apply(null, arguments); }; var _ulang_vm_pop_int = Module["_ulang_vm_pop_int"] = function() { return (_ulang_vm_pop_int = Module["_ulang_vm_pop_int"] = Module["asm"]["v"]).apply(null, arguments); }; var _ulang_vm_pop_uint = Module["_ulang_vm_pop_uint"] = function() { return (_ulang_vm_pop_uint = Module["_ulang_vm_pop_uint"] = Module["asm"]["w"]).apply(null, arguments); }; var _ulang_vm_pop_float = Module["_ulang_vm_pop_float"] = function() { return (_ulang_vm_pop_float = Module["_ulang_vm_pop_float"] = Module["asm"]["x"]).apply(null, arguments); }; var _ulang_vm_push_int = Module["_ulang_vm_push_int"] = function() { return (_ulang_vm_push_int = Module["_ulang_vm_push_int"] = Module["asm"]["y"]).apply(null, arguments); }; var _ulang_vm_push_uint = Module["_ulang_vm_push_uint"] = function() { return (_ulang_vm_push_uint = Module["_ulang_vm_push_uint"] = Module["asm"]["z"]).apply(null, arguments); }; var _ulang_vm_push_float = Module["_ulang_vm_push_float"] = function() { return (_ulang_vm_push_float = Module["_ulang_vm_push_float"] = Module["asm"]["A"]).apply(null, arguments); }; var _ulang_vm_free = Module["_ulang_vm_free"] = function() { return (_ulang_vm_free = Module["_ulang_vm_free"] = Module["asm"]["B"]).apply(null, arguments); }; var _ulang_sizeof = Module["_ulang_sizeof"] = function() { return (_ulang_sizeof = Module["_ulang_sizeof"] = Module["asm"]["C"]).apply(null, arguments); }; var _ulang_print_offsets = Module["_ulang_print_offsets"] = function() { return (_ulang_print_offsets = Module["_ulang_print_offsets"] = Module["asm"]["D"]).apply(null, arguments); }; var _ulang_argb_to_rgba = Module["_ulang_argb_to_rgba"] = function() { return (_ulang_argb_to_rgba = Module["_ulang_argb_to_rgba"] = Module["asm"]["E"]).apply(null, arguments); }; var stackSave = Module["stackSave"] = function() { return (stackSave = Module["stackSave"] = Module["asm"]["G"]).apply(null, arguments); }; var stackRestore = Module["stackRestore"] = function() { return (stackRestore = Module["stackRestore"] = Module["asm"]["H"]).apply(null, arguments); }; var stackAlloc = Module["stackAlloc"] = function() { return (stackAlloc = Module["stackAlloc"] = Module["asm"]["I"]).apply(null, arguments); }; Module["cwrap"] = cwrap; Module["UTF8ArrayToString"] = UTF8ArrayToString2; Module["addFunction"] = addFunction2; Module["allocateUTF8"] = allocateUTF8; var calledRun; dependenciesFulfilled = function runCaller() { if (!calledRun) run(); if (!calledRun) dependenciesFulfilled = runCaller; }; function run(args) { args = args || arguments_; if (runDependencies > 0) { return; } preRun(); if (runDependencies > 0) { return; } function doRun() { if (calledRun) return; calledRun = true; Module["calledRun"] = true; if (ABORT) return; initRuntime(); readyPromiseResolve(Module); if (Module["onRuntimeInitialized"]) Module["onRuntimeInitialized"](); postRun(); } if (Module["setStatus"]) { Module["setStatus"]("Running..."); setTimeout(function() { setTimeout(function() { Module["setStatus"](""); }, 1); doRun(); }, 1); } else { doRun(); } } Module["run"] = run; if (Module["preInit"]) { if (typeof Module["preInit"] == "function") Module["preInit"] = [Module["preInit"]]; while (Module["preInit"].length > 0) { Module["preInit"].pop()(); } } run(); return loadWasm2.ready; }; })(); var ulang_default = loadWasm; // vm/src/wrapper.ts var module = { onRuntimeInitialized: createWrappers }; function loadUlang() { return __async(this, null, function* () { return yield ulang_default(module); }); } var ulang_calloc; var ulang_free; var ulang_print_memory; var ulang_file_from_memory; var ulang_file_free; var ulang_error_print; var ulang_error_free; var ulang_compile; var ulang_program_free; var ulang_vm_init; var ulang_vm_step; var ulang_vm_step_n; var ulang_vm_step_n_bp; var ulang_vm_print; var ulang_vm_pop_int; var ulang_vm_pop_uint; var ulang_vm_pop_float; var ulang_vm_push_int; var ulang_vm_push_uint; var ulang_vm_push_float; var ulang_vm_free; var ulang_sizeof; var ulang_print_offsets; var ulang_argb_to_rgba; var getInt8 = (ptr) => new DataView(module.HEAPU8.buffer).getInt8(ptr); var getInt16 = (ptr) => new DataView(module.HEAPU8.buffer).getInt16(ptr, true); var getUint32 = (ptr) => new DataView(module.HEAPU8.buffer).getUint32(ptr, true); var setUint32 = (ptr, val) => new DataView(module.HEAPU8.buffer).setUint32(ptr, val, true); var getInt32 = (ptr) => new DataView(module.HEAPU8.buffer).getInt32(ptr, true); var getFloat32 = (ptr) => new DataView(module.HEAPU8.buffer).getFloat32(ptr, true); var argbToRgba; var addFunction; var UTF8ArrayToString; var HEAPU8; function createWrappers() { ulang_calloc = module.cwrap("ulang_calloc", "ptr", ["number"]); ulang_free = module.cwrap("ulang_free", "void", ["ptr"]); ulang_print_memory = module.cwrap("ulang_print_memory", "void", []); ulang_file_from_memory = module.cwrap("ulang_file_from_memory", "number", ["ptr", "ptr", "ptr"]); ulang_file_free = module.cwrap("ulang_file_free", "void", ["ptr"]); ulang_error_print = module.cwrap("ulang_error_print", "void", ["ptr"]); ulang_error_free = module.cwrap("ulang_error_free", "void", ["ptr"]); ulang_compile = module.cwrap("ulang_compile", "number", ["ptr", "ptr", "ptr"]); ulang_program_free = module.cwrap("ulang_program_free", "void", ["ptr"]); ulang_vm_init = module.cwrap("ulang_vm_init", "void", ["ptr", "ptr"]); ulang_vm_step = module.cwrap("ulang_vm_step", "number", ["ptr"]); ulang_vm_step_n = module.cwrap("ulang_vm_step_n", "number", ["ptr", "number"]); ulang_vm_step_n_bp = module.cwrap("ulang_vm_step_n_bp", "number", ["ptr", "number", "ptr", "number"]); ulang_vm_print = module.cwrap("ulang_vm_print", "void", ["ptr"]); ulang_vm_pop_int = module.cwrap("ulang_vm_pop_int", "number", ["ptr"]); ulang_vm_pop_uint = module.cwrap("ulang_vm_pop_uint", "number", ["ptr"]); ulang_vm_pop_float = module.cwrap("ulang_vm_pop_float", "number", ["ptr"]); ulang_vm_push_int = module.cwrap("ulang_vm_push_int", "void", ["ptr", "number"]); ulang_vm_push_uint = module.cwrap("ulang_vm_push_uint", "void", ["ptr", "number"]); ulang_vm_push_float = module.cwrap("ulang_vm_push_float", "void", ["ptr", "number"]); ulang_vm_free = module.cwrap("ulang_vm_free", "void", ["ptr"]); ulang_sizeof = module.cwrap("ulang_sizeof", "number", ["number"]); ulang_print_offsets = module.cwrap("ulang_print_offsets", "void", []); argbToRgba = ulang_argb_to_rgba = module.cwrap("ulang_argb_to_rgba", "ptr", ["ptr", "ptr", "number"]); addFunction = module.addFunction; UTF8ArrayToString = module.UTF8ArrayToString; HEAPU8 = () => module.HEAP8; } function ptrToUlangString(stringPtr) { return { ptr: stringPtr, data: () => getUint32(stringPtr), length: () => getUint32(stringPtr + 4), toString: () => module.UTF8ArrayToString(module.HEAPU8, getUint32(stringPtr), getUint32(stringPtr + 4)) }; } function ptrToUlangSpan(spanPtr) { return { ptr: spanPtr, data: () => ptrToUlangString(spanPtr), startLine: () => getUint32(spanPtr + 8), endLine: () => getUint32(spanPtr + 12) }; } function ptrToUlangLine(linePtr) { return { ptr: linePtr, data: () => ptrToUlangString(linePtr), lineNumber: () => getUint32(linePtr + 8) }; } function ptrToUlangFile(filePtr) { return { ptr: filePtr, fileName: () => ptrToUlangString(filePtr), data: () => ptrToUlangString(filePtr + 8), lines: () => { let lines = []; let linesPtr = getUint32(filePtr + 16); let numLines = getUint32(filePtr + 20); for (let i = 0; i < numLines + 1; i++) { lines.push(ptrToUlangLine(linesPtr)); linesPtr += 12; } return lines; }, free: () => { ulang_file_free(filePtr); ulang_free(filePtr); } }; } function ptrToUlangError(errorPtr) { return { ptr: errorPtr, file: () => ptrToUlangFile(getUint32(errorPtr)), span: () => ptrToUlangSpan(errorPtr + 4), message: () => ptrToUlangString(errorPtr + 20), isSet: () => getInt32(errorPtr + 28) != 0, print: () => ulang_error_print(errorPtr), free: () => { ulang_error_free(errorPtr); ulang_free(errorPtr); } }; } function ptrToUlangLabel(labelPtr) { return { ptr: labelPtr, label: () => ptrToUlangSpan(labelPtr), target: () => getUint32(labelPtr + 16), address: () => getUint32(labelPtr + 20) }; } function ptrToUlangProgram(progPtr) { return { ptr: progPtr, code: () => new DataView(module.HEAPU8.buffer, getUint32(progPtr), getUint32(progPtr + 4)), data: () => new DataView(module.HEAPU8.buffer, getUint32(progPtr + 8), getUint32(progPtr + 12)), reservedBytes: () => getUint32(progPtr + 16), labels: () => { let labels = []; let labelsPtr = getUint32(progPtr + 20); let labelsLength = getUint32(progPtr + 24); for (let i = 0; i < labelsLength; i++) { labels.push(ptrToUlangLabel(labelsPtr)); labelsPtr += 24; } return labels; }, constants: () => { let constants = []; let constantsPtr = getUint32(progPtr + 28); let constantsLength = getUint32(progPtr + 32); for (let i = 0; i < constantsLength; i++) { constants.push(ptrToUlangLabel(constantsPtr)); constantsPtr += 24; } return constants; }, file: () => { return ptrToUlangFile(progPtr + 36); }, addressToLine: () => { let addressToLine = []; let addressToLinePtr = getUint32(progPtr + 40); let addressToLineLength = getUint32(progPtr + 44); for (let i = 0; i < addressToLineLength; i++) { addressToLine.push(getUint32(addressToLinePtr)); addressToLinePtr += 4; } return addressToLine; }, free: () => { ulang_program_free(progPtr); ulang_free(progPtr); } }; } function ptrToUlangValue(valPtr) { return { ptr: valPtr, b: () => getInt8(valPtr), s: () => getInt16(valPtr), i: () => getInt32(valPtr), ui: () => getUint32(valPtr), f: () => getFloat32(valPtr) }; } function ptrToUlangVm(vmPtr) { return { ptr: vmPtr, registers: () => { let regs = []; let regsPtr = vmPtr; for (let i = 0; i < 16; i++) { regs.push(ptrToUlangValue(regsPtr)); regsPtr += 4; } return regs; }, memory: () => new DataView(module.HEAPU8, getUint32(vmPtr + 64), getUint32(vmPtr + 68)), memoryPtr: () => getUint32(vmPtr + 64), error: () => ptrToUlangError(getUint32(vmPtr + 1096)), program: () => ptrToUlangProgram(getUint32(vmPtr + 1128)), setSyscall: (num, call) => { if (num < 0 || num > 255) return; setUint32(vmPtr + 72 + num * 4, call); }, step: () => ulang_vm_step(vmPtr) != 0, stepN: (n) => ulang_vm_step_n(vmPtr, n) != 0, stepNBP: (n, bpPtr, numBp) => ulang_vm_step_n_bp(vmPtr, n, bpPtr, numBp), print: () => ulang_vm_print(vmPtr), popInt: () => ulang_vm_pop_int(vmPtr), popUint: () => ulang_vm_pop_uint(vmPtr), popFloat: () => ulang_vm_pop_float(vmPtr), pushInt: (val) => ulang_vm_push_int(vmPtr, val), pushUint: (val) => ulang_vm_push_uint(vmPtr, val), pushFloat: (val) => ulang_vm_push_float(vmPtr, val), free: () => { ulang_vm_free(vmPtr); ulang_free(vmPtr); } }; } function alloc(numBytes) { return ulang_calloc(numBytes); } function allocType(type) { return ulang_calloc(ulang_sizeof(type)); } function free(ptr) { return ulang_free(ptr); } function printMemory() { ulang_print_memory(); } function newFile(sourceName, sourceData) { let name = module.allocateUTF8(sourceName); let data = module.allocateUTF8(sourceData); let filePtr = allocType(0 /* UL_TYPE_FILE */); ulang_file_from_memory(name, data, filePtr); module._free(name); module._free(data); return ptrToUlangFile(filePtr); } function newError() { return ptrToUlangError(allocType(1 /* UL_TYPE_ERROR */)); } function newProgram() { return ptrToUlangProgram(allocType(2 /* UL_TYPE_PROGRAM */)); } function compile(source) { let error = newError(); let file = newFile("source", source); let program = newProgram(); let result = { error, file, program, free: () => { program.free(); file.free(); error.free(); } }; ulang_compile(result.file.ptr, result.program.ptr, result.error.ptr); return result; } function newVm(program) { let vm = ptrToUlangVm(allocType(3 /* UL_TYPE_VM */)); ulang_vm_init(vm.ptr, program.ptr); return vm; } var UL_VM_MEMORY_SIZE = 1024 * 1024 * 32; // vm/src/index.ts var VirtualMachineState = /* @__PURE__ */ ((VirtualMachineState2) => { VirtualMachineState2[VirtualMachineState2["Stopped"] = 0] = "Stopped"; VirtualMachineState2[VirtualMachineState2["Running"] = 1] = "Running"; VirtualMachineState2[VirtualMachineState2["Paused"] = 2] = "Paused"; return VirtualMachineState2; })(VirtualMachineState || {}); var LogLevel = /* @__PURE__ */ ((LogLevel2) => { LogLevel2[LogLevel2["None"] = 0] = "None"; LogLevel2[LogLevel2["Info"] = 1] = "Info"; return LogLevel2; })(LogLevel || {}); var VirtualMachine = class { constructor(canvasElement) { this.state = 0 /* Stopped */; this.compilerResult = null; this.vmStart = 0; this.executedInstructions = 0; this.vsyncHit = false; this.debugSyscallHit = false; this.breakpoints = []; this.bpPtr = 0; this.numBps = 0; this.syscallHandlerPtr = 0; this.lastStepHitBreakpoint = false; this.stateChangeListener = null; this.logLevel = 1 /* Info */; this.mouseX = 0; this.mouseY = 0; this.mouseButtonDown = false; this.keys = /* @__PURE__ */ new Map(); this.listeners = []; if (typeof canvasElement === "string") this.canvas = document.getElementById(canvasElement); else this.canvas = canvasElement; this.rgbaFramePtr = alloc(320 * 240 * 4); this.addEventListener("mousemove", (e) => { var rect = this.canvas.getBoundingClientRect(); this.mouseX = (e.clientX - rect.left) / this.canvas.clientWidth * 320 | 0; this.mouseY = (e.clientY - rect.top) / this.canvas.clientHeight * 240 | 0; }); this.addEventListener("mousedown", (e) => { var rect = this.canvas.getBoundingClientRect(); this.mouseX = (e.clientX - rect.left) / this.canvas.clientWidth * 320 | 0; this.mouseY = (e.clientY - rect.top) / this.canvas.clientHeight * 240 | 0; this.mouseButtonDown = true; }); this.addEventListener("mouseup", (e) => { var rect = this.canvas.getBoundingClientRect(); this.mouseX = (e.clientX - rect.left) / this.canvas.clientWidth * 320 | 0; this.mouseY = (e.clientY - rect.top) / this.canvas.clientHeight * 240 | 0; this.mouseButtonDown = false; }); this.addEventListener("mouseleave", (e) => { var rect = this.canvas.getBoundingClientRect(); this.mouseX = (e.clientX - rect.left) / this.canvas.clientWidth * 320 | 0; this.mouseY = (e.clientY - rect.top) / this.canvas.clientHeight * 240 | 0; this.mouseButtonDown = false; }); let syscallHandler = (syscall, vmPtr) => { let vm = ptrToUlangVm(vmPtr); switch (syscall) { case 0: this.pause(); this.debugSyscallHit = true; return 0; case 1: let buffer = vm.popUint(); argbToRgba(vm.memoryPtr() + buffer, this.rgbaFramePtr, 320 * 240); let frame = new Uint8ClampedArray(HEAPU8().buffer, this.rgbaFramePtr, 320 * 240 * 4); let imageData = new ImageData(frame, 320, 240); this.canvas.getContext("2d").putImageData(imageData, 0, 0); this.vsyncHit = true; return 0; case 2: { let str = ""; while (true) { let argType = vm.popUint(); if (argType == 6) break; switch (argType) { case 0: str += vm.popInt(); break; case 1: str += "0x" + vm.popInt().toString(16); break; case 2: str += vm.popFloat(); break; case 3: let strAddr = vm.popUint(); str += UTF8ArrayToString(HEAPU8(), vm.memoryPtr() + strAddr); break; case 4: str += " "; break; case 5: str += "\n"; break; default: break; } } console.log(str); return -1; } case 3: { vm.pushInt(this.mouseX); vm.pushInt(this.mouseY); vm.pushInt(this.mouseButtonDown ? -1 : 0); return -1; } case 4: { } case 5: { vm.pushFloat(performance.now() / 1e3); return -1; } } }; this.syscallHandlerPtr = addFunction(syscallHandler, "iii"); } addEventListener(type, listener) { this.canvas.addEventListener(type, listener); this.listeners.push({ type, listener }); } dipose() { this.stop(); for (let i = 0; i < this.listeners.length; i++) { let listener = this.listeners[i]; this.canvas.removeEventListener(listener.type, listener.listener); } free(this.rgbaFramePtr); } setLogLevel(logLevel) { this.logLevel = logLevel; } setStateChangeListener(listener) { this.stateChangeListener = listener; } setBreakpoints(breakpoints) { this.breakpoints = breakpoints; if (this.bpPtr != 0) { free(this.bpPtr); this.bpPtr = 0; this.numBps = 0; } if (this.state != 0 /* Stopped */) this.calculateBreakpoints(); } calculateBreakpoints() { if (this.bpPtr != 0) return this.bpPtr; let addressToLine = this.vm.program().addressToLine(); let p = this.bpPtr = alloc(4 * this.breakpoints.length); for (let i = 0; i < this.breakpoints.length; i++) { let bpLine = this.breakpoints[i]; for (let j = 0; j < addressToLine.length; j++) { if (addressToLine[j] == bpLine) { setUint32(p, j * 4); p += 4; this.numBps++; break; } } } return this.bpPtr; } run(source) { if (this.compilerResult) { this.compilerResult.free(); this.compilerResult = null; } if (this.vm) { this.vm.free(); this.vm = null; } this.compilerResult = compile(source); if (this.compilerResult.error.isSet()) { alert("Can't run program with errors."); this.compilerResult.error.print(); this.compilerResult.free(); if (this.stateChangeListener) this.stateChangeListener(this, this.state); return; } this.vm = newVm(this.compilerResult.program); for (let i = 0; i <= 255; i++) { this.vm.setSyscall(i, this.syscallHandlerPtr); } this.vmStart = performance.now(); this.executedInstructions = 0; this.lastStepHitBreakpoint = false; this.state = 1 /* Running */; if (this.stateChangeListener) this.stateChangeListener(this, this.state); requestAnimationFrame(() => this.frame()); } stop() { if (this.state != 1 /* Running */ && this.state != 2 /* Paused */) return; this.state = 0 /* Stopped */; if (this.stateChangeListener) this.stateChangeListener(this, this.state); this.printVmTime(); this.printVmState(); } pause() { if (this.state != 1 /* Running */) return; this.state = 2 /* Paused */; if (this.stateChangeListener) this.stateChangeListener(this, this.state); this.printVmState(); } continue() { if (this.state != 2 /* Paused */) return; this.state = 1 /* Running */; if (this.stateChangeListener) this.stateChangeListener(this, this.state); this.printVmState(); requestAnimationFrame(() => this.frame()); } step() { if (this.state != 2 /* Paused */) return; if (!this.vm.step()) { if (this.vsyncHit || this.debugSyscallHit) { this.vsyncHit = false; this.debugSyscallHit = false; } else { this.state = 0 /* Stopped */; if (this.stateChangeListener) this.stateChangeListener(this, this.state); return; } } if (this.stateChangeListener) this.stateChangeListener(this, this.state); this.printVmState(); } getCurrentLine() { if (this.state != 2 /* Paused */) return -1; let pc = this.vm.registers()[14].ui() >> 2; let addressToLine = this.vm.program().addressToLine(); if (pc >= addressToLine.length) return -1; return addressToLine[pc]; } getState() { return this.state; } getRegisters() { return this.vm.registers(); } getProgram() { return this.vm.program(); } getInt(addr) { return getInt32(this.vm.memoryPtr() + addr); } getFloat