@marioslab/ulang-vm
Version:
Virtual machine & assembler for recreational programming like it's 1992.
1,373 lines (1,369 loc) • 53.9 kB
JavaScript
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