From e8504a410ae7aaabcfb63d72681537c854d34e02 Mon Sep 17 00:00:00 2001 From: mattkae Date: Thu, 8 Dec 2022 09:08:24 -0500 Subject: WIP --- themes/Snowflake.cpp | 58 ++--- themes/Snowflake.h | 3 - themes/dist/output.js | 653 +++++++++--------------------------------------- themes/dist/output.wasm | Bin 135640 -> 134949 bytes 4 files changed, 128 insertions(+), 586 deletions(-) diff --git a/themes/Snowflake.cpp b/themes/Snowflake.cpp index d5373f4..186c97a 100644 --- a/themes/Snowflake.cpp +++ b/themes/Snowflake.cpp @@ -36,6 +36,7 @@ inline void initFlake(SnowflakeParticleRenderer* renderer, SnowflakeUpdateData* ud->vtxIdx = renderer->vertices.numElements; generateSnowflakeShape(&renderer->vertices, randomIntBetween(4, 16), randomFloatBetween(8.f, 16.f), randomFloatBetween(2.f, 6.f)); ud->numVertices = renderer->vertices.numElements - ud->vtxIdx; + ud->isAlive = false; } inline void spawnFlake(SnowflakeParticleRenderer* renderer, SnowflakeUpdateData* ud) { @@ -45,20 +46,16 @@ inline void spawnFlake(SnowflakeParticleRenderer* renderer, SnowflakeUpdateData* } inline void findAndSpawnNextFlake(SnowflakeParticleRenderer* renderer) { - do { - renderer->endIndex++; - - if (renderer->endIndex >= renderer->numSnowflakes) - renderer->endIndex = 0; - } while (renderer->updateData[renderer->endIndex].isAlive); - - spawnFlake(renderer, &renderer->updateData[renderer->endIndex]); + for (i32 i = 0; i < renderer->numSnowflakes; i++) { + if (!renderer->updateData[i].isAlive) { + spawnFlake(renderer, &renderer->updateData[i]); + break; + } + } } void SnowflakeParticleRenderer::load(SnowflakeLoadParameters params, Renderer2d* renderer) { - startIndex = 0; spawnIntervalSeconds = params.spawnIntervalSeconds; - endIndex = params.initialSnowflakeCount; numSnowflakes = params.maxSnowflakes; updateData = new SnowflakeUpdateData[params.maxSnowflakes]; @@ -70,10 +67,6 @@ void SnowflakeParticleRenderer::load(SnowflakeLoadParameters params, Renderer2d* for (i32 s = 0; s < numSnowflakes; s++) { auto ud = &updateData[s]; initFlake(this, ud); - - if (s < endIndex) { - spawnFlake(this, ud); - } } useShader(renderer->shader); @@ -108,18 +101,16 @@ void SnowflakeParticleRenderer::load(SnowflakeLoadParameters params, Renderer2d* } inline void updateFlake(SnowflakeParticleRenderer* renderer, SnowflakeUpdateData* ud, i32 s, f32 dtSeconds, bool addWind) { - // Once the snowflake has been set to die in this interval, we try and increment the - // startIndex - if (!ud->isAlive && renderer->startIndex == s) { - renderer->startIndex = (renderer->startIndex + 1) % renderer->numSnowflakes; + if (!ud->isAlive) { return; } if (addWind) ud->velocity += renderer->windSpeed; ud->position += ud->velocity * dtSeconds; - if (ud->position.y < 0) + if (ud->position.y < 0) { ud->isAlive = false; + } Mat4x4 m = Mat4x4().translateByVec2(ud->position); for (i32 v = ud->vtxIdx; v < (ud->vtxIdx + ud->numVertices); v++) { @@ -142,37 +133,20 @@ void SnowflakeParticleRenderer::update(f32 dtSeconds) { addWind = true; } - if (startIndex < endIndex) { - for (i32 s = startIndex; s < endIndex; s++) { - SnowflakeUpdateData* ud = &updateData[s]; - updateFlake(this, ud, s, dtSeconds, addWind); - } - } - else { - i32 endRange = startIndex - numSnowflakes; - for (i32 s = endIndex - 1; s >= endRange; s--) { - SnowflakeUpdateData* ud; - if (s < 0) - ud = &updateData[numSnowflakes + s]; - else - ud = &updateData[s]; - - updateFlake(this, ud, s, dtSeconds, addWind); - } - } + for (i32 s = 0; s < numSnowflakes; s++) { + SnowflakeUpdateData* ud = &updateData[s]; + updateFlake(this, ud, s, dtSeconds, addWind); + } } void SnowflakeParticleRenderer::render(Renderer2d* renderer) { - auto startVertex = &updateData[startIndex]; - auto endVertex = &updateData[endIndex]; - i32 numVertices = (endVertex->vtxIdx + endVertex->numVertices) - startVertex->vtxIdx; setShaderMat4(renderer->uniforms.model, model); glBindBuffer(GL_ARRAY_BUFFER, vbo); - glBufferSubData(GL_ARRAY_BUFFER, 0, numVertices * sizeof(Vertex2D), &vertices.data[startVertex->vtxIdx]); + glBufferSubData(GL_ARRAY_BUFFER, 0, vertices.numElements * sizeof(Vertex2D), &vertices.data[0]); glBindVertexArray(vao); - glDrawArrays(GL_TRIANGLES, 0, numVertices); + glDrawArrays(GL_TRIANGLES, 0, vertices.numElements); glBindVertexArray(0); } diff --git a/themes/Snowflake.h b/themes/Snowflake.h index 248034c..ae0c82f 100644 --- a/themes/Snowflake.h +++ b/themes/Snowflake.h @@ -7,7 +7,6 @@ struct Vertex2D; struct SnowflakeLoadParameters { i32 maxSnowflakes = 1000; - i32 initialSnowflakeCount = 100; f32 rateOfSnowfall = 0.1f; Vector2 flakeV0 = { 0, 1 }; f32 flakeSize = 5.f; @@ -34,8 +33,6 @@ struct SnowflakeParticleRenderer { f32 yMax = 0; f32 spawnIntervalSeconds = 0.3; f32 windIntervalSeconds = 1.5; - i32 startIndex = 0; - i32 endIndex = 0; i32 numSnowflakes = 0; Vector2 windSpeed; SnowflakeUpdateData* updateData; diff --git a/themes/dist/output.js b/themes/dist/output.js index 05324da..83ee836 100644 --- a/themes/dist/output.js +++ b/themes/dist/output.js @@ -82,12 +82,8 @@ function logExceptionOnExit(e) { err('exiting due to exception: ' + toLog); } -var fs; -var nodePath; -var requireNodeFS; - if (ENVIRONMENT_IS_NODE) { - if (!(typeof process == 'object' && typeof require == 'function')) throw new Error('not compiled for this environment (did you build to HTML and try to run it not on the web, or set ENVIRONMENT to something - like node - and run it someplace else - like on the web?)'); + if (typeof process == 'undefined' || !process.release || process.release.name !== 'node') throw new Error('not compiled for this environment (did you build to HTML and try to run it not on the web, or set ENVIRONMENT to something - like node - and run it someplace else - like on the web?)'); if (ENVIRONMENT_IS_WORKER) { scriptDirectory = require('path').dirname(scriptDirectory) + '/'; } else { @@ -97,18 +93,22 @@ if (ENVIRONMENT_IS_NODE) { // include: node_shell_read.js -requireNodeFS = () => { - // Use nodePath as the indicator for these not being initialized, - // since in some environments a global fs may have already been - // created. - if (!nodePath) { - fs = require('fs'); - nodePath = require('path'); - } -}; +// These modules will usually be used on Node.js. Load them eagerly to avoid +// the complexity of lazy-loading. However, for now we must guard on require() +// actually existing: if the JS is put in a .mjs file (ES6 module) and run on +// node, then we'll detect node as the environment and get here, but require() +// does not exist (since ES6 modules should use |import|). If the code actually +// uses the node filesystem then it will crash, of course, but in the case of +// code that never uses it we don't want to crash here, so the guarding if lets +// such code work properly. See discussion in +// https://github.com/emscripten-core/emscripten/pull/17851 +var fs, nodePath; +if (typeof require === 'function') { + fs = require('fs'); + nodePath = require('path'); +} -read_ = function shell_read(filename, binary) { - requireNodeFS(); +read_ = (filename, binary) => { filename = nodePath['normalize'](filename); return fs.readFileSync(filename, binary ? undefined : 'utf8'); }; @@ -123,7 +123,6 @@ readBinary = (filename) => { }; readAsync = (filename, onload, onerror) => { - requireNodeFS(); filename = nodePath['normalize'](filename); fs.readFile(filename, function(err, data) { if (err) onerror(err); @@ -396,6 +395,14 @@ function missingLibrarySymbol(sym) { // Can't `abort()` here because it would break code that does runtime // checks. e.g. `if (typeof SDL === 'undefined')`. var msg = '`' + sym + '` is a library symbol and not included by default; add it to your library.js __deps or to DEFAULT_LIBRARY_FUNCS_TO_INCLUDE on the command line'; + // DEFAULT_LIBRARY_FUNCS_TO_INCLUDE requires the name as it appears in + // library.js, which means $name for a JS name with no prefix, or name + // for a JS name like _name. + var librarySymbol = sym; + if (!librarySymbol.startsWith('_')) { + librarySymbol = '$' + sym; + } + msg += " (e.g. -sDEFAULT_LIBRARY_FUNCS_TO_INCLUDE=" + librarySymbol + ")"; if (isExportedByForceFilesystem(sym)) { msg += '. Alternatively, forcing filesystem support (-sFORCE_FILESYSTEM) can export this for you'; } @@ -422,10 +429,6 @@ function unexportedRuntimeSymbol(sym) { } // end include: runtime_debug.js -var tempRet0 = 0; -var setTempRet0 = (value) => { tempRet0 = value; }; -var getTempRet0 = () => tempRet0; - // === Preamble library stuff === @@ -698,8 +701,8 @@ function writeStackCookie() { // The stack grow downwards towards _emscripten_stack_get_end. // We write cookies to the final two words in the stack and detect if they are // ever overwritten. - HEAP32[((max)>>2)] = 0x2135467; - HEAP32[(((max)+(4))>>2)] = 0x89BACDFE; + HEAPU32[((max)>>2)] = 0x2135467; + HEAPU32[(((max)+(4))>>2)] = 0x89BACDFE; // Also test the global address 0 for integrity. HEAPU32[0] = 0x63736d65; /* 'emsc' */ } @@ -1166,7 +1169,7 @@ function createWasm() { return exports; } catch(e) { err('Module.instantiateWasm callback failed with error: ' + e); - return false; + return false; } } @@ -1315,13 +1318,15 @@ var ASM_CONSTS = { HEAP8.set(array, buffer); } - function __emscripten_date_now() { - return Date.now(); - } - function __emscripten_fetch_free(id) { - //Note: should just be [id], but indexes off by 1 (see: #8803) - delete Fetch.xhrs[id-1]; + var xhr = Fetch.xhrs[id]; + if (xhr) { + delete Fetch.xhrs[id]; + // check if fetch is still in progress and should be aborted + if (xhr.readyState > 0 && xhr.readyState < 4) { + xhr.abort(); + } + } } function readI53FromI64(ptr) { @@ -1404,6 +1409,10 @@ var ASM_CONSTS = { abort('native code called abort()'); } + function _emscripten_date_now() { + return Date.now(); + } + var JSEvents = {inEventHandler:0,removeAllEventListeners:function() { for (var i = JSEvents.eventHandlers.length-1; i >= 0; --i) { JSEvents._removeHandler(i); @@ -1748,7 +1757,7 @@ var ASM_CONSTS = { return 0; } - var Fetch = {xhrs:[],setu64:function(addr, val) { + var Fetch = {xhrs:{},setu64:function(addr, val) { HEAPU32[addr >> 2] = val; HEAPU32[addr + 4 >> 2] = (val / 4294967296)|0; },openDatabase:function(dbname, dbversion, onsuccess, onerror) { @@ -1845,9 +1854,8 @@ var ASM_CONSTS = { xhr.setRequestHeader(keyStr, valueStr); } } - Fetch.xhrs.push(xhr); - var id = Fetch.xhrs.length; - HEAPU32[fetch + 0 >> 2] = id; + var id = HEAPU32[fetch + 0 >> 2]; + Fetch.xhrs[id] = xhr; var data = (dataPtr && dataLength) ? HEAPU8.slice(dataPtr, dataPtr + dataLength) : null; // TODO: Support specifying custom headers to the request. @@ -1855,11 +1863,13 @@ var ASM_CONSTS = { // and on error (despite an error, there may be a response, like a 404 page). // This receives a condition, which determines whether to save the xhr's // response, or just 0. - function saveResponse(condition) { + function saveResponseAndStatus() { var ptr = 0; var ptrLen = 0; - if (condition) { - ptrLen = xhr.response ? xhr.response.byteLength : 0; + if (xhr.response && fetchAttrLoadToMemory && HEAPU32[fetch + 12 >> 2] === 0) { + ptrLen = xhr.response.byteLength; + } + if (ptrLen > 0) { // The data pointer malloc()ed here has the same lifetime as the emscripten_fetch_t structure itself has, and is // freed when emscripten_fetch_close() is called. ptr = _malloc(ptrLen); @@ -1867,12 +1877,8 @@ var ASM_CONSTS = { } HEAPU32[fetch + 12 >> 2] = ptr; Fetch.setu64(fetch + 16, ptrLen); - } - - xhr.onload = (e) => { - saveResponse(fetchAttrLoadToMemory && !fetchAttrStreamData); - var len = xhr.response ? xhr.response.byteLength : 0; Fetch.setu64(fetch + 24, 0); + var len = xhr.response ? xhr.response.byteLength : 0; if (len) { // If the final XHR.onload handler receives the bytedata to compute total length, report that, // otherwise don't write anything out here, which will retain the latest byte size reported in @@ -1882,6 +1888,14 @@ var ASM_CONSTS = { HEAPU16[fetch + 40 >> 1] = xhr.readyState; HEAPU16[fetch + 42 >> 1] = xhr.status; if (xhr.statusText) stringToUTF8(xhr.statusText, fetch + 44, 64); + } + + xhr.onload = (e) => { + // check if xhr was aborted by user and don't try to call back + if (!(id in Fetch.xhrs)) { + return; + } + saveResponseAndStatus(); if (xhr.status >= 200 && xhr.status < 300) { if (onsuccess) onsuccess(fetch, xhr, e); } else { @@ -1889,21 +1903,28 @@ var ASM_CONSTS = { } }; xhr.onerror = (e) => { - saveResponse(fetchAttrLoadToMemory); - var status = xhr.status; // XXX TODO: Overwriting xhr.status doesn't work here, so don't override anywhere else either. - Fetch.setu64(fetch + 24, 0); - Fetch.setu64(fetch + 32, xhr.response ? xhr.response.byteLength : 0); - HEAPU16[fetch + 40 >> 1] = xhr.readyState; - HEAPU16[fetch + 42 >> 1] = status; + // check if xhr was aborted by user and don't try to call back + if (!(id in Fetch.xhrs)) { + return; + } + saveResponseAndStatus(); if (onerror) onerror(fetch, xhr, e); }; xhr.ontimeout = (e) => { + // check if xhr was aborted by user and don't try to call back + if (!(id in Fetch.xhrs)) { + return; + } if (onerror) onerror(fetch, xhr, e); }; xhr.onprogress = (e) => { + // check if xhr was aborted by user and don't try to call back + if (!(id in Fetch.xhrs)) { + return; + } var ptrLen = (fetchAttrLoadToMemory && fetchAttrStreamData && xhr.response) ? xhr.response.byteLength : 0; var ptr = 0; - if (fetchAttrLoadToMemory && fetchAttrStreamData) { + if (ptrLen > 0 && fetchAttrLoadToMemory && fetchAttrStreamData) { assert(onprogress, 'When doing a streaming fetch, you should have an onprogress handler registered to receive the chunks!'); // Allocate byte data in Emscripten heap for the streamed memory block (freed immediately after onprogress call) ptr = _malloc(ptrLen); @@ -1924,6 +1945,11 @@ var ASM_CONSTS = { } }; xhr.onreadystatechange = (e) => { + // check if xhr was aborted by user and don't try to call back + if (!(id in Fetch.xhrs)) { + + return; + } HEAPU16[fetch + 40 >> 1] = xhr.readyState; if (xhr.readyState >= 2) { HEAPU16[fetch + 42 >> 1] = xhr.status; @@ -3070,10 +3096,6 @@ var ASM_CONSTS = { GLctx.vertexAttribPointer(index, size, type, !!normalized, stride, ptr); } - function _setTempRet0(val) { - setTempRet0(val); - } - function _proc_exit(code) { EXITSTATUS = code; if (!keepRuntimeAlive()) { @@ -3096,478 +3118,6 @@ var ASM_CONSTS = { _proc_exit(status); } - - function allocateUTF8OnStack(str) { - var size = lengthBytesUTF8(str) + 1; - var ret = stackAlloc(size); - stringToUTF8Array(str, HEAP8, ret, size); - return ret; - } - - function uleb128Encode(n, target) { - assert(n < 16384); - if (n < 128) { - target.push(n); - } else { - target.push((n % 128) | 128, n >> 7); - } - } - - function sigToWasmTypes(sig) { - var typeNames = { - 'i': 'i32', - 'j': 'i64', - 'f': 'f32', - 'd': 'f64', - 'p': 'i32', - }; - var type = { - parameters: [], - results: sig[0] == 'v' ? [] : [typeNames[sig[0]]] - }; - for (var i = 1; i < sig.length; ++i) { - assert(sig[i] in typeNames, 'invalid signature char: ' + sig[i]); - type.parameters.push(typeNames[sig[i]]); - } - return type; - } - function convertJsFunctionToWasm(func, sig) { - - // If the type reflection proposal is available, use the new - // "WebAssembly.Function" constructor. - // Otherwise, construct a minimal wasm module importing the JS function and - // re-exporting it. - if (typeof WebAssembly.Function == "function") { - return new WebAssembly.Function(sigToWasmTypes(sig), func); - } - - // The module is static, with the exception of the type section, which is - // generated based on the signature passed in. - var typeSectionBody = [ - 0x01, // count: 1 - 0x60, // form: func - ]; - var sigRet = sig.slice(0, 1); - var sigParam = sig.slice(1); - var typeCodes = { - 'i': 0x7f, // i32 - 'p': 0x7f, // i32 - 'j': 0x7e, // i64 - 'f': 0x7d, // f32 - 'd': 0x7c, // f64 - }; - - // Parameters, length + signatures - uleb128Encode(sigParam.length, typeSectionBody); - for (var i = 0; i < sigParam.length; ++i) { - assert(sigParam[i] in typeCodes, 'invalid signature char: ' + sigParam[i]); - typeSectionBody.push(typeCodes[sigParam[i]]); - } - - // Return values, length + signatures - // With no multi-return in MVP, either 0 (void) or 1 (anything else) - if (sigRet == 'v') { - typeSectionBody.push(0x00); - } else { - typeSectionBody.push(0x01, typeCodes[sigRet]); - } - - // Rest of the module is static - var bytes = [ - 0x00, 0x61, 0x73, 0x6d, // magic ("\0asm") - 0x01, 0x00, 0x00, 0x00, // version: 1 - 0x01, // Type section code - ]; - // Write the overall length of the type section followed by the body - uleb128Encode(typeSectionBody.length, bytes); - bytes.push.apply(bytes, typeSectionBody); - - // The rest of the module is static - bytes.push( - 0x02, 0x07, // import section - // (import "e" "f" (func 0 (type 0))) - 0x01, 0x01, 0x65, 0x01, 0x66, 0x00, 0x00, - 0x07, 0x05, // export section - // (export "f" (func 0 (type 0))) - 0x01, 0x01, 0x66, 0x00, 0x00, - ); - - // We can compile this wasm module synchronously because it is very small. - // This accepts an import (at "e.f"), that it reroutes to an export (at "f") - var module = new WebAssembly.Module(new Uint8Array(bytes)); - var instance = new WebAssembly.Instance(module, { 'e': { 'f': func } }); - var wrappedFunc = instance.exports['f']; - return wrappedFunc; - } - - function updateTableMap(offset, count) { - if (functionsInTableMap) { - for (var i = offset; i < offset + count; i++) { - var item = getWasmTableEntry(i); - // Ignore null values. - if (item) { - functionsInTableMap.set(item, i); - } - } - } - } - - var functionsInTableMap = undefined; - - var freeTableIndexes = []; - function getEmptyTableSlot() { - // Reuse a free index if there is one, otherwise grow. - if (freeTableIndexes.length) { - return freeTableIndexes.pop(); - } - // Grow the table - try { - wasmTable.grow(1); - } catch (err) { - if (!(err instanceof RangeError)) { - throw err; - } - throw 'Unable to grow wasm table. Set ALLOW_TABLE_GROWTH.'; - } - return wasmTable.length - 1; - } - - function setWasmTableEntry(idx, func) { - wasmTable.set(idx, func); - // With ABORT_ON_WASM_EXCEPTIONS wasmTable.get is overriden to return wrapped - // functions so we need to call it here to retrieve the potential wrapper correctly - // instead of just storing 'func' directly into wasmTableMirror - wasmTableMirror[idx] = wasmTable.get(idx); - } - /** @param {string=} sig */ - function addFunction(func, sig) { - assert(typeof func != 'undefined'); - - // Check if the function is already in the table, to ensure each function - // gets a unique index. First, create the map if this is the first use. - if (!functionsInTableMap) { - functionsInTableMap = new WeakMap(); - updateTableMap(0, wasmTable.length); - } - if (functionsInTableMap.has(func)) { - return functionsInTableMap.get(func); - } - - // It's not in the table, add it now. - - var ret = getEmptyTableSlot(); - - // Set the new value. - try { - // Attempting to call this with JS function will cause of table.set() to fail - setWasmTableEntry(ret, func); - } catch (err) { - if (!(err instanceof TypeError)) { - throw err; - } - assert(typeof sig != 'undefined', 'Missing signature argument to addFunction: ' + func); - var wrapped = convertJsFunctionToWasm(func, sig); - setWasmTableEntry(ret, wrapped); - } - - functionsInTableMap.set(func, ret); - - return ret; - } - - function removeFunction(index) { - functionsInTableMap.delete(getWasmTableEntry(index)); - freeTableIndexes.push(index); - } - - var ALLOC_NORMAL = 0; - - var ALLOC_STACK = 1; - function allocate(slab, allocator) { - var ret; - assert(typeof allocator == 'number', 'allocate no longer takes a type argument') - assert(typeof slab != 'number', 'allocate no longer takes a number as arg0') - - if (allocator == ALLOC_STACK) { - ret = stackAlloc(slab.length); - } else { - ret = _malloc(slab.length); - } - - if (!slab.subarray && !slab.slice) { - slab = new Uint8Array(slab); - } - HEAPU8.set(slab, ret); - return ret; - } - - - - function AsciiToString(ptr) { - var str = ''; - while (1) { - var ch = HEAPU8[((ptr++)>>0)]; - if (!ch) return str; - str += String.fromCharCode(ch); - } - } - - /** @param {boolean=} dontAddNull */ - function writeAsciiToMemory(str, buffer, dontAddNull) { - for (var i = 0; i < str.length; ++i) { - assert(str.charCodeAt(i) === (str.charCodeAt(i) & 0xff)); - HEAP8[((buffer++)>>0)] = str.charCodeAt(i); - } - // Null-terminate the pointer to the HEAP. - if (!dontAddNull) HEAP8[((buffer)>>0)] = 0; - } - function stringToAscii(str, outPtr) { - return writeAsciiToMemory(str, outPtr, false); - } - - var UTF16Decoder = typeof TextDecoder != 'undefined' ? new TextDecoder('utf-16le') : undefined;; - function UTF16ToString(ptr, maxBytesToRead) { - assert(ptr % 2 == 0, 'Pointer passed to UTF16ToString must be aligned to two bytes!'); - var endPtr = ptr; - // TextDecoder needs to know the byte length in advance, it doesn't stop on null terminator by itself. - // Also, use the length info to avoid running tiny strings through TextDecoder, since .subarray() allocates garbage. - var idx = endPtr >> 1; - var maxIdx = idx + maxBytesToRead / 2; - // If maxBytesToRead is not passed explicitly, it will be undefined, and this - // will always evaluate to true. This saves on code size. - while (!(idx >= maxIdx) && HEAPU16[idx]) ++idx; - endPtr = idx << 1; - - if (endPtr - ptr > 32 && UTF16Decoder) { - return UTF16Decoder.decode(HEAPU8.subarray(ptr, endPtr)); - } else { - var str = ''; - - // If maxBytesToRead is not passed explicitly, it will be undefined, and the for-loop's condition - // will always evaluate to true. The loop is then terminated on the first null char. - for (var i = 0; !(i >= maxBytesToRead / 2); ++i) { - var codeUnit = HEAP16[(((ptr)+(i*2))>>1)]; - if (codeUnit == 0) break; - // fromCharCode constructs a character from a UTF-16 code unit, so we can pass the UTF16 string right through. - str += String.fromCharCode(codeUnit); - } - - return str; - } - } - - function stringToUTF16(str, outPtr, maxBytesToWrite) { - assert(outPtr % 2 == 0, 'Pointer passed to stringToUTF16 must be aligned to two bytes!'); - assert(typeof maxBytesToWrite == 'number', 'stringToUTF16(str, outPtr, maxBytesToWrite) is missing the third parameter that specifies the length of the output buffer!'); - // Backwards compatibility: if max bytes is not specified, assume unsafe unbounded write is allowed. - if (maxBytesToWrite === undefined) { - maxBytesToWrite = 0x7FFFFFFF; - } - if (maxBytesToWrite < 2) return 0; - maxBytesToWrite -= 2; // Null terminator. - var startPtr = outPtr; - var numCharsToWrite = (maxBytesToWrite < str.length*2) ? (maxBytesToWrite / 2) : str.length; - for (var i = 0; i < numCharsToWrite; ++i) { - // charCodeAt returns a UTF-16 encoded code unit, so it can be directly written to the HEAP. - var codeUnit = str.charCodeAt(i); // possibly a lead surrogate - HEAP16[((outPtr)>>1)] = codeUnit; - outPtr += 2; - } - // Null-terminate the pointer to the HEAP. - HEAP16[((outPtr)>>1)] = 0; - return outPtr - startPtr; - } - - function lengthBytesUTF16(str) { - return str.length*2; - } - - function UTF32ToString(ptr, maxBytesToRead) { - assert(ptr % 4 == 0, 'Pointer passed to UTF32ToString must be aligned to four bytes!'); - var i = 0; - - var str = ''; - // If maxBytesToRead is not passed explicitly, it will be undefined, and this - // will always evaluate to true. This saves on code size. - while (!(i >= maxBytesToRead / 4)) { - var utf32 = HEAP32[(((ptr)+(i*4))>>2)]; - if (utf32 == 0) break; - ++i; - // Gotcha: fromCharCode constructs a character from a UTF-16 encoded code (pair), not from a Unicode code point! So encode the code point to UTF-16 for constructing. - // See http://unicode.org/faq/utf_bom.html#utf16-3 - if (utf32 >= 0x10000) { - var ch = utf32 - 0x10000; - str += String.fromCharCode(0xD800 | (ch >> 10), 0xDC00 | (ch & 0x3FF)); - } else { - str += String.fromCharCode(utf32); - } - } - return str; - } - - function stringToUTF32(str, outPtr, maxBytesToWrite) { - assert(outPtr % 4 == 0, 'Pointer passed to stringToUTF32 must be aligned to four bytes!'); - assert(typeof maxBytesToWrite == 'number', 'stringToUTF32(str, outPtr, maxBytesToWrite) is missing the third parameter that specifies the length of the output buffer!'); - // Backwards compatibility: if max bytes is not specified, assume unsafe unbounded write is allowed. - if (maxBytesToWrite === undefined) { - maxBytesToWrite = 0x7FFFFFFF; - } - if (maxBytesToWrite < 4) return 0; - var startPtr = outPtr; - var endPtr = startPtr + maxBytesToWrite - 4; - for (var i = 0; i < str.length; ++i) { - // Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code unit, not a Unicode code point of the character! We must decode the string to UTF-32 to the heap. - // See http://unicode.org/faq/utf_bom.html#utf16-3 - var codeUnit = str.charCodeAt(i); // possibly a lead surrogate - if (codeUnit >= 0xD800 && codeUnit <= 0xDFFF) { - var trailSurrogate = str.charCodeAt(++i); - codeUnit = 0x10000 + ((codeUnit & 0x3FF) << 10) | (trailSurrogate & 0x3FF); - } - HEAP32[((outPtr)>>2)] = codeUnit; - outPtr += 4; - if (outPtr + 4 > endPtr) break; - } - // Null-terminate the pointer to the HEAP. - HEAP32[((outPtr)>>2)] = 0; - return outPtr - startPtr; - } - - function lengthBytesUTF32(str) { - var len = 0; - for (var i = 0; i < str.length; ++i) { - // Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code unit, not a Unicode code point of the character! We must decode the string to UTF-32 to the heap. - // See http://unicode.org/faq/utf_bom.html#utf16-3 - var codeUnit = str.charCodeAt(i); - if (codeUnit >= 0xD800 && codeUnit <= 0xDFFF) ++i; // possibly a lead surrogate, so skip over the tail surrogate. - len += 4; - } - - return len; - } - - - - /** @deprecated @param {boolean=} dontAddNull */ - function writeStringToMemory(string, buffer, dontAddNull) { - warnOnce('writeStringToMemory is deprecated and should not be called! Use stringToUTF8() instead!'); - - var /** @type {number} */ lastChar, /** @type {number} */ end; - if (dontAddNull) { - // stringToUTF8Array always appends null. If we don't want to do that, remember the - // character that existed at the location where the null will be placed, and restore - // that after the write (below). - end = buffer + lengthBytesUTF8(string); - lastChar = HEAP8[end]; - } - stringToUTF8(string, buffer, Infinity); - if (dontAddNull) HEAP8[end] = lastChar; // Restore the value under the null character. - } - - - - /** @type {function(string, boolean=, number=)} */ - function 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; - } - - function intArrayToString(array) { - var ret = []; - for (var i = 0; i < array.length; i++) { - var chr = array[i]; - if (chr > 0xFF) { - if (ASSERTIONS) { - assert(false, 'Character code ' + chr + ' (' + String.fromCharCode(chr) + ') at offset ' + i + ' not in 0x00-0xFF.'); - } - chr &= 0xFF; - } - ret.push(String.fromCharCode(chr)); - } - return ret.join(''); - } - - - function getCFunc(ident) { - var func = Module['_' + ident]; // closure exported function - assert(func, 'Cannot call unknown function ' + ident + ', make sure it is exported'); - return func; - } - - /** - * @param {string|null=} returnType - * @param {Array=} argTypes - * @param {Arguments|Array=} args - * @param {Object=} opts - */ - function ccall(ident, returnType, argTypes, args, opts) { - // For fast lookup of conversion functions - var toC = { - 'string': (str) => { - var ret = 0; - if (str !== null && str !== undefined && str !== 0) { // null string - // at most 4 bytes per UTF-8 code point, +1 for the trailing '\0' - var len = (str.length << 2) + 1; - ret = stackAlloc(len); - stringToUTF8(str, ret, len); - } - 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; - assert(returnType !== 'array', 'Return type should not be "array".'); - 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(ret) { - if (stack !== 0) stackRestore(stack); - return convertReturnValue(ret); - } - - ret = onDone(ret); - return ret; - } - - - /** - * @param {string=} returnType - * @param {Array=} argTypes - * @param {Object=} opts - */ - function cwrap(ident, returnType, argTypes, opts) { - return function() { - return ccall(ident, returnType, argTypes, arguments, opts); - } - } - Fetch.staticInit();; var GLctx;; var miniTempWebGLFloatBuffersStorage = new Float32Array(288); @@ -3581,11 +3131,11 @@ function checkIncomingModuleAPI() { ignoredModuleProp('fetchSettings'); } var asmLibraryArg = { - "_emscripten_date_now": __emscripten_date_now, "_emscripten_fetch_free": __emscripten_fetch_free, "_localtime_js": __localtime_js, "_tzset_js": __tzset_js, "abort": _abort, + "emscripten_date_now": _emscripten_date_now, "emscripten_get_element_css_size": _emscripten_get_element_css_size, "emscripten_is_main_browser_thread": _emscripten_is_main_browser_thread, "emscripten_memcpy_big": _emscripten_memcpy_big, @@ -3634,8 +3184,7 @@ var asmLibraryArg = { "glUniformMatrix4fv": _glUniformMatrix4fv, "glUseProgram": _glUseProgram, "glVertexAttribDivisor": _glVertexAttribDivisor, - "glVertexAttribPointer": _glVertexAttribPointer, - "setTempRet0": _setTempRet0 + "glVertexAttribPointer": _glVertexAttribPointer }; var asm = createWasm(); /** @type {function(...*):?} */ @@ -3725,15 +3274,15 @@ var unexportedRuntimeSymbols = [ 'getCompilerSetting', 'print', 'printErr', - 'getTempRet0', - 'setTempRet0', 'callMain', 'abort', 'keepRuntimeAlive', 'wasmMemory', + 'stackAlloc', 'stackSave', 'stackRestore', - 'stackAlloc', + 'getTempRet0', + 'setTempRet0', 'writeStackCookie', 'checkStackCookie', 'ptrToString', @@ -3797,6 +3346,7 @@ var unexportedRuntimeSymbols = [ 'cwrap', 'uleb128Encode', 'sigToWasmTypes', + 'generateFuncType', 'convertJsFunctionToWasm', 'freeTableIndexes', 'functionsInTableMap', @@ -3887,6 +3437,7 @@ var unexportedRuntimeSymbols = [ 'checkWasiClock', 'flush_NO_FILESYSTEM', 'dlopenMissingError', + 'createDyncallWrapper', 'setImmediateWrapped', 'clearImmediateWrapped', 'polyfillSetImmediate', @@ -3986,11 +3537,35 @@ var missingLibrarySymbols = [ 'convertI32PairToI53', 'convertI32PairToI53Checked', 'convertU32PairToI53', + 'getCFunc', + 'ccall', + 'cwrap', + 'uleb128Encode', + 'sigToWasmTypes', + 'generateFuncType', + 'convertJsFunctionToWasm', + 'getEmptyTableSlot', + 'updateTableMap', + 'addFunction', + 'removeFunction', 'reallyNegative', 'unSign', 'strLen', 'reSign', 'formatString', + 'intArrayFromString', + 'intArrayToString', + 'AsciiToString', + 'stringToAscii', + 'UTF16ToString', + 'stringToUTF16', + 'lengthBytesUTF16', + 'UTF32ToString', + 'stringToUTF32', + 'lengthBytesUTF32', + 'allocateUTF8OnStack', + 'writeStringToMemory', + 'writeAsciiToMemory', 'getSocketFromFD', 'getSocketAddress', 'registerKeyEventCallback', @@ -4030,6 +3605,7 @@ var missingLibrarySymbols = [ 'getCanvasElementSize', 'getEnvStrings', 'checkWasiClock', + 'createDyncallWrapper', 'setImmediateWrapped', 'clearImmediateWrapped', 'polyfillSetImmediate', @@ -4054,6 +3630,9 @@ var missingLibrarySymbols = [ 'GLFW_Window', 'runAndAbortIfError', 'emscriptenWebGLGetIndexed', + 'ALLOC_NORMAL', + 'ALLOC_STACK', + 'allocate', ]; missingLibrarySymbols.forEach(missingLibrarySymbol) @@ -4072,16 +3651,8 @@ function callMain(args) { var entryFunction = Module['_main']; - args = args || []; - args.unshift(thisProgram); - - var argc = args.length; - var argv = stackAlloc((argc + 1) * 4); - var argv_ptr = argv >> 2; - args.forEach((arg) => { - HEAP32[argv_ptr++] = allocateUTF8OnStack(arg); - }); - HEAP32[argv_ptr] = 0; + var argc = 0; + var argv = 0; try { diff --git a/themes/dist/output.wasm b/themes/dist/output.wasm index 1d42a88..4e62096 100755 Binary files a/themes/dist/output.wasm and b/themes/dist/output.wasm differ -- cgit v1.2.1