From 2485711025ee7685c8d39bca55c5f1aee5a03128 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jukka=20Jyl=C3=A4nki?= Date: Thu, 26 Jan 2023 14:35:57 +0200 Subject: [PATCH 1/6] Make WebGL bindings library 4GB and MEMORY64 aware, with a general machinery to manage pointers in each build mode. --- src/library_webgl.js | 169 +++++++++++++++++++++--------------------- src/library_webgl2.js | 54 +++++++------- src/parseTools.js | 51 ++++++++++++- 3 files changed, 161 insertions(+), 113 deletions(-) diff --git a/src/library_webgl.js b/src/library_webgl.js index 48b4d044035c7..8fa5383c4cbca 100644 --- a/src/library_webgl.js +++ b/src/library_webgl.js @@ -1511,13 +1511,12 @@ var LibraryGL = { $emscriptenWebGLGetTexPixelData: function(type, format, width, height, pixels, internalFormat) { var heap = heapObjectForWebGLType(type); var shift = heapAccessShiftForWebGLHeap(heap); - var byteSize = 1<> shift) << shift == pixels, 'Pointer to texture data passed to texture get function must be aligned to the byte size of the pixel type!'); + assert({{{ isPtrAligned('pixels', '(1 << shift)') }}}, 'Pointer to texture data passed to texture get function must be aligned to the byte size of the pixel type!'); #endif - return heap.subarray(pixels >> shift, pixels + bytes >> shift); + return heap.subarray({{{ ptrToIdx('pixels', 'shift') }}}, {{{ ptrToIdx('pixels + bytes', 'shift') }}}); }, glTexImage2D__sig: 'viiiiiiiii', @@ -1552,7 +1551,7 @@ var LibraryGL = { GLctx.texImage2D(target, level, internalFormat, width, height, border, format, type, pixels); } else if (pixels) { var heap = heapObjectForWebGLType(type); - GLctx.texImage2D(target, level, internalFormat, width, height, border, format, type, heap, pixels >> heapAccessShiftForWebGLHeap(heap)); + GLctx.texImage2D(target, level, internalFormat, width, height, border, format, type, heap, {{{ idxToMemory53(ptrToIdx('pixels', 'heapAccessShiftForWebGLHeap(heap)')) }}}); } else { GLctx.texImage2D(target, level, internalFormat, width, height, border, format, type, null); } @@ -1584,7 +1583,7 @@ var LibraryGL = { GLctx.texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels); } else if (pixels) { var heap = heapObjectForWebGLType(type); - GLctx.texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, heap, pixels >> heapAccessShiftForWebGLHeap(heap)); + GLctx.texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, heap, {{{ idxToMemory53(ptrToIdx('pixels', 'heapAccessShiftForWebGLHeap(heap)')) }}}); } else { GLctx.texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, null); } @@ -1609,7 +1608,7 @@ var LibraryGL = { GLctx.readPixels(x, y, width, height, format, type, pixels); } else { var heap = heapObjectForWebGLType(type); - GLctx.readPixels(x, y, width, height, format, type, heap, pixels >> heapAccessShiftForWebGLHeap(heap)); + GLctx.readPixels(x, y, width, height, format, type, heap, {{{ idxToMemory53(ptrToIdx('pixels', 'heapAccessShiftForWebGLHeap(heap)')) }}}); } return; } @@ -2366,19 +2365,19 @@ var LibraryGL = { glUniform1iv: function(location, count, value) { #if GL_ASSERTIONS GL.validateGLObjectID(GLctx.currentProgram.uniformLocsById, location, 'glUniform1iv', 'location'); - assert((value & 3) == 0, 'Pointer to integer data passed to glUniform1iv must be aligned to four bytes!'); + assert({{{ isPtrAligned('value', 4) }}}, 'Pointer to integer data passed to glUniform1iv must be aligned to four bytes!'); #endif #if MIN_WEBGL_VERSION >= 2 #if GL_ASSERTIONS assert(GL.currentContext.version >= 2); #endif - count && GLctx.uniform1iv(webglGetUniformLocation(location), HEAP32, value>>2, count); + count && GLctx.uniform1iv(webglGetUniformLocation(location), HEAP32, {{{ idxToMemory53(ptrToIdx('value', 2)) }}}, count); #else #if MAX_WEBGL_VERSION >= 2 if ({{{ isCurrentContextWebGL2() }}}) { // WebGL 2 provides new garbage-free entry points to call to WebGL. Use those always when possible. - count && GLctx.uniform1iv(webglGetUniformLocation(location), HEAP32, value>>2, count); + count && GLctx.uniform1iv(webglGetUniformLocation(location), HEAP32, {{{ idxToMemory53(ptrToIdx('value', 2)) }}}, count); return; } #endif @@ -2411,19 +2410,19 @@ var LibraryGL = { glUniform2iv: function(location, count, value) { #if GL_ASSERTIONS GL.validateGLObjectID(GLctx.currentProgram.uniformLocsById, location, 'glUniform2iv', 'location'); - assert((value & 3) == 0, 'Pointer to integer data passed to glUniform2iv must be aligned to four bytes!'); + assert({{{ isPtrAligned('value', 4) }}}, 'Pointer to integer data passed to glUniform2iv must be aligned to four bytes!'); #endif #if MIN_WEBGL_VERSION >= 2 #if GL_ASSERTIONS assert(GL.currentContext.version >= 2); #endif - count && GLctx.uniform2iv(webglGetUniformLocation(location), HEAP32, value>>2, count*2); + count && GLctx.uniform2iv(webglGetUniformLocation(location), HEAP32, {{{ idxToMemory53(ptrToIdx('value', 2)) }}}, count*2); #else #if MAX_WEBGL_VERSION >= 2 if ({{{ isCurrentContextWebGL2() }}}) { // WebGL 2 provides new garbage-free entry points to call to WebGL. Use those always when possible. - count && GLctx.uniform2iv(webglGetUniformLocation(location), HEAP32, value>>2, count*2); + count && GLctx.uniform2iv(webglGetUniformLocation(location), HEAP32, {{{ idxToMemory53(ptrToIdx('value', 2)) }}}, count*2); return; } #endif @@ -2457,19 +2456,19 @@ var LibraryGL = { glUniform3iv: function(location, count, value) { #if GL_ASSERTIONS GL.validateGLObjectID(GLctx.currentProgram.uniformLocsById, location, 'glUniform3iv', 'location'); - assert((value & 3) == 0, 'Pointer to integer data passed to glUniform3iv must be aligned to four bytes!'); + assert({{{ isPtrAligned('value', 4) }}}, 'Pointer to integer data passed to glUniform3iv must be aligned to four bytes!'); #endif #if MIN_WEBGL_VERSION >= 2 #if GL_ASSERTIONS assert(GL.currentContext.version >= 2); #endif - count && GLctx.uniform3iv(webglGetUniformLocation(location), HEAP32, value>>2, count*3); + count && GLctx.uniform3iv(webglGetUniformLocation(location), HEAP32, {{{ idxToMemory53(ptrToIdx('value', 2)) }}}, count*3); #else #if MAX_WEBGL_VERSION >= 2 if ({{{ isCurrentContextWebGL2() }}}) { // WebGL 2 provides new garbage-free entry points to call to WebGL. Use those always when possible. - count && GLctx.uniform3iv(webglGetUniformLocation(location), HEAP32, value>>2, count*3); + count && GLctx.uniform3iv(webglGetUniformLocation(location), HEAP32, {{{ idxToMemory53(ptrToIdx('value', 2)) }}}, count*3); return; } #endif @@ -2504,19 +2503,19 @@ var LibraryGL = { glUniform4iv: function(location, count, value) { #if GL_ASSERTIONS GL.validateGLObjectID(GLctx.currentProgram.uniformLocsById, location, 'glUniform4iv', 'location'); - assert((value & 3) == 0, 'Pointer to integer data passed to glUniform4iv must be aligned to four bytes!'); + assert({{{ isPtrAligned('value', 4) }}}, 'Pointer to integer data passed to glUniform4iv must be aligned to four bytes!'); #endif #if MIN_WEBGL_VERSION >= 2 #if GL_ASSERTIONS assert(GL.currentContext.version >= 2); #endif - count && GLctx.uniform4iv(webglGetUniformLocation(location), HEAP32, value>>2, count*4); + count && GLctx.uniform4iv(webglGetUniformLocation(location), HEAP32, {{{ idxToMemory53(ptrToIdx('value', 2)) }}}, count*4); #else #if MAX_WEBGL_VERSION >= 2 if ({{{ isCurrentContextWebGL2() }}}) { // WebGL 2 provides new garbage-free entry points to call to WebGL. Use those always when possible. - count && GLctx.uniform4iv(webglGetUniformLocation(location), HEAP32, value>>2, count*4); + count && GLctx.uniform4iv(webglGetUniformLocation(location), HEAP32, {{{ idxToMemory53(ptrToIdx('value', 2)) }}}, count*4); return; } #endif @@ -2552,19 +2551,19 @@ var LibraryGL = { glUniform1fv: function(location, count, value) { #if GL_ASSERTIONS GL.validateGLObjectID(GLctx.currentProgram.uniformLocsById, location, 'glUniform1fv', 'location'); - assert((value & 3) == 0, 'Pointer to float data passed to glUniform1fv must be aligned to four bytes!'); + assert({{{ isPtrAligned('value', 4) }}}, 'Pointer to float data passed to glUniform1fv must be aligned to four bytes!'); #endif #if MIN_WEBGL_VERSION >= 2 #if GL_ASSERTIONS assert(GL.currentContext.version >= 2); #endif - count && GLctx.uniform1fv(webglGetUniformLocation(location), HEAPF32, value>>2, count); + count && GLctx.uniform1fv(webglGetUniformLocation(location), HEAPF32, {{{ idxToMemory53(ptrToIdx('value', 2)) }}}, count); #else #if MAX_WEBGL_VERSION >= 2 if ({{{ isCurrentContextWebGL2() }}}) { // WebGL 2 provides new garbage-free entry points to call to WebGL. Use those always when possible. - count && GLctx.uniform1fv(webglGetUniformLocation(location), HEAPF32, value>>2, count); + count && GLctx.uniform1fv(webglGetUniformLocation(location), HEAPF32, {{{ idxToMemory53(ptrToIdx('value', 2)) }}}, count); return; } #endif @@ -2597,19 +2596,19 @@ var LibraryGL = { glUniform2fv: function(location, count, value) { #if GL_ASSERTIONS GL.validateGLObjectID(GLctx.currentProgram.uniformLocsById, location, 'glUniform2fv', 'location'); - assert((value & 3) == 0, 'Pointer to float data passed to glUniform2fv must be aligned to four bytes!'); + assert({{{ isPtrAligned('value', 4) }}}, 'Pointer to float data passed to glUniform2fv must be aligned to four bytes!'); #endif #if MIN_WEBGL_VERSION >= 2 #if GL_ASSERTIONS assert(GL.currentContext.version >= 2); #endif - count && GLctx.uniform2fv(webglGetUniformLocation(location), HEAPF32, value>>2, count*2); + count && GLctx.uniform2fv(webglGetUniformLocation(location), HEAPF32, {{{ idxToMemory53(ptrToIdx('value', 2)) }}}, count*2); #else #if MAX_WEBGL_VERSION >= 2 if ({{{ isCurrentContextWebGL2() }}}) { // WebGL 2 provides new garbage-free entry points to call to WebGL. Use those always when possible. - count && GLctx.uniform2fv(webglGetUniformLocation(location), HEAPF32, value>>2, count*2); + count && GLctx.uniform2fv(webglGetUniformLocation(location), HEAPF32, {{{ idxToMemory53(ptrToIdx('value', 2)) }}}, count*2); return; } #endif @@ -2643,19 +2642,19 @@ var LibraryGL = { glUniform3fv: function(location, count, value) { #if GL_ASSERTIONS GL.validateGLObjectID(GLctx.currentProgram.uniformLocsById, location, 'glUniform3fv', 'location'); - assert((value & 3) == 0, 'Pointer to float data passed to glUniform3fv must be aligned to four bytes!' + value); + assert({{{ isPtrAligned('value', 4) }}}, 'Pointer to float data passed to glUniform3fv must be aligned to four bytes!'); #endif #if MIN_WEBGL_VERSION >= 2 #if GL_ASSERTIONS assert(GL.currentContext.version >= 2); #endif - count && GLctx.uniform3fv(webglGetUniformLocation(location), HEAPF32, value>>2, count*3); + count && GLctx.uniform3fv(webglGetUniformLocation(location), HEAPF32, {{{ idxToMemory53(ptrToIdx('value', 2)) }}}, count*3); #else #if MAX_WEBGL_VERSION >= 2 if ({{{ isCurrentContextWebGL2() }}}) { // WebGL 2 provides new garbage-free entry points to call to WebGL. Use those always when possible. - count && GLctx.uniform3fv(webglGetUniformLocation(location), HEAPF32, value>>2, count*3); + count && GLctx.uniform3fv(webglGetUniformLocation(location), HEAPF32, {{{ idxToMemory53(ptrToIdx('value', 2)) }}}, count*3); return; } #endif @@ -2690,19 +2689,19 @@ var LibraryGL = { glUniform4fv: function(location, count, value) { #if GL_ASSERTIONS GL.validateGLObjectID(GLctx.currentProgram.uniformLocsById, location, 'glUniform4fv', 'location'); - assert((value & 3) == 0, 'Pointer to float data passed to glUniform4fv must be aligned to four bytes!'); + assert({{{ isPtrAligned('value', 4) }}}, 'Pointer to float data passed to glUniform4fv must be aligned to four bytes!'); #endif #if MIN_WEBGL_VERSION >= 2 #if GL_ASSERTIONS assert(GL.currentContext.version >= 2); #endif - count && GLctx.uniform4fv(webglGetUniformLocation(location), HEAPF32, value>>2, count*4); + count && GLctx.uniform4fv(webglGetUniformLocation(location), HEAPF32, {{{ idxToMemory53(ptrToIdx('value', 2)) }}}, count*4); #else #if MAX_WEBGL_VERSION >= 2 if ({{{ isCurrentContextWebGL2() }}}) { // WebGL 2 provides new garbage-free entry points to call to WebGL. Use those always when possible. - count && GLctx.uniform4fv(webglGetUniformLocation(location), HEAPF32, value>>2, count*4); + count && GLctx.uniform4fv(webglGetUniformLocation(location), HEAPF32, {{{ idxToMemory53(ptrToIdx('value', 2)) }}}, count*4); return; } #endif @@ -2711,15 +2710,14 @@ var LibraryGL = { if (count <= {{{ GL_POOL_TEMP_BUFFERS_SIZE / 4 }}}) { // avoid allocation when uploading few enough uniforms var view = miniTempWebGLFloatBuffers[4*count-1]; - // hoist the heap out of the loop for size and for pthreads+growth. + // hoist the heap out of the loop for pthreads+growth. var heap = HEAPF32; - value >>= 2; + {{{ convertPtrToIdx('value', 2) }}}; for (var i = 0; i < 4 * count; i += 4) { - var dst = value + i; - view[i] = heap[dst]; - view[i + 1] = heap[dst + 1]; - view[i + 2] = heap[dst + 2]; - view[i + 3] = heap[dst + 3]; + view[i] = heap[value++]; + view[i + 1] = heap[value++]; + view[i + 2] = heap[value++]; + view[i + 3] = heap[value++]; } } else #endif @@ -2742,19 +2740,19 @@ var LibraryGL = { glUniformMatrix2fv: function(location, count, transpose, value) { #if GL_ASSERTIONS GL.validateGLObjectID(GLctx.currentProgram.uniformLocsById, location, 'glUniformMatrix2fv', 'location'); - assert((value & 3) == 0, 'Pointer to float data passed to glUniformMatrix2fv must be aligned to four bytes!'); + assert({{{ isPtrAligned('value', 4) }}}, 'Pointer to float data passed to glUniformMatrix2fv must be aligned to four bytes!'); #endif #if MIN_WEBGL_VERSION >= 2 #if GL_ASSERTIONS assert(GL.currentContext.version >= 2); #endif - count && GLctx.uniformMatrix2fv(webglGetUniformLocation(location), !!transpose, HEAPF32, value>>2, count*4); + count && GLctx.uniformMatrix2fv(webglGetUniformLocation(location), !!transpose, HEAPF32, {{{ idxToMemory53(ptrToIdx('value', 2)) }}}, count*4); #else #if MAX_WEBGL_VERSION >= 2 if ({{{ isCurrentContextWebGL2() }}}) { // WebGL 2 provides new garbage-free entry points to call to WebGL. Use those always when possible. - count && GLctx.uniformMatrix2fv(webglGetUniformLocation(location), !!transpose, HEAPF32, value>>2, count*4); + count && GLctx.uniformMatrix2fv(webglGetUniformLocation(location), !!transpose, HEAPF32, {{{ idxToMemory53(ptrToIdx('value', 2)) }}}, count*4); return; } #endif @@ -2790,19 +2788,19 @@ var LibraryGL = { glUniformMatrix3fv: function(location, count, transpose, value) { #if GL_ASSERTIONS GL.validateGLObjectID(GLctx.currentProgram.uniformLocsById, location, 'glUniformMatrix3fv', 'location'); - assert((value & 3) == 0, 'Pointer to float data passed to glUniformMatrix3fv must be aligned to four bytes!'); + assert({{{ isPtrAligned('value', 4) }}}, 'Pointer to float data passed to glUniformMatrix3fv must be aligned to four bytes!'); #endif #if MIN_WEBGL_VERSION >= 2 #if GL_ASSERTIONS assert(GL.currentContext.version >= 2); #endif - count && GLctx.uniformMatrix3fv(webglGetUniformLocation(location), !!transpose, HEAPF32, value>>2, count*9); + count && GLctx.uniformMatrix3fv(webglGetUniformLocation(location), !!transpose, HEAPF32, {{{ idxToMemory53(ptrToIdx('value', 2)) }}}, count*9); #else #if MAX_WEBGL_VERSION >= 2 if ({{{ isCurrentContextWebGL2() }}}) { // WebGL 2 provides new garbage-free entry points to call to WebGL. Use those always when possible. - count && GLctx.uniformMatrix3fv(webglGetUniformLocation(location), !!transpose, HEAPF32, value>>2, count*9); + count && GLctx.uniformMatrix3fv(webglGetUniformLocation(location), !!transpose, HEAPF32, {{{ idxToMemory53(ptrToIdx('value', 2)) }}}, count*9); return; } #endif @@ -2843,19 +2841,19 @@ var LibraryGL = { glUniformMatrix4fv: function(location, count, transpose, value) { #if GL_ASSERTIONS GL.validateGLObjectID(GLctx.currentProgram.uniformLocsById, location, 'glUniformMatrix4fv', 'location'); - assert((value & 3) == 0, 'Pointer to float data passed to glUniformMatrix4fv must be aligned to four bytes!'); + assert({{{ isPtrAligned('value', 4) }}}, 'Pointer to float data passed to glUniformMatrix4fv must be aligned to four bytes!'); #endif #if MIN_WEBGL_VERSION >= 2 #if GL_ASSERTIONS assert(GL.currentContext.version >= 2); #endif - count && GLctx.uniformMatrix4fv(webglGetUniformLocation(location), !!transpose, HEAPF32, value>>2, count*16); + count && GLctx.uniformMatrix4fv(webglGetUniformLocation(location), !!transpose, HEAPF32, {{{ idxToMemory53(ptrToIdx('value', 2)) }}}, count*16); #else #if MAX_WEBGL_VERSION >= 2 if ({{{ isCurrentContextWebGL2() }}}) { // WebGL 2 provides new garbage-free entry points to call to WebGL. Use those always when possible. - count && GLctx.uniformMatrix4fv(webglGetUniformLocation(location), !!transpose, HEAPF32, value>>2, count*16); + count && GLctx.uniformMatrix4fv(webglGetUniformLocation(location), !!transpose, HEAPF32, {{{ idxToMemory53(ptrToIdx('value', 2)) }}}, count*16); return; } #endif @@ -2864,27 +2862,26 @@ var LibraryGL = { if (count <= {{{ GL_POOL_TEMP_BUFFERS_SIZE / 16 }}}) { // avoid allocation when uploading few enough uniforms var view = miniTempWebGLFloatBuffers[16*count-1]; - // hoist the heap out of the loop for size and for pthreads+growth. + // hoist the heap out of the loop for pthreads+growth. var heap = HEAPF32; - value >>= 2; + {{{ convertPtrToIdx('value', 2) }}}; for (var i = 0; i < 16 * count; i += 16) { - var dst = value + i; - view[i] = heap[dst]; - view[i + 1] = heap[dst + 1]; - view[i + 2] = heap[dst + 2]; - view[i + 3] = heap[dst + 3]; - view[i + 4] = heap[dst + 4]; - view[i + 5] = heap[dst + 5]; - view[i + 6] = heap[dst + 6]; - view[i + 7] = heap[dst + 7]; - view[i + 8] = heap[dst + 8]; - view[i + 9] = heap[dst + 9]; - view[i + 10] = heap[dst + 10]; - view[i + 11] = heap[dst + 11]; - view[i + 12] = heap[dst + 12]; - view[i + 13] = heap[dst + 13]; - view[i + 14] = heap[dst + 14]; - view[i + 15] = heap[dst + 15]; + view[i] = heap[value++]; + view[i + 1] = heap[value++]; + view[i + 2] = heap[value++]; + view[i + 3] = heap[value++]; + view[i + 4] = heap[value++]; + view[i + 5] = heap[value++]; + view[i + 6] = heap[value++]; + view[i + 7] = heap[value++]; + view[i + 8] = heap[value++]; + view[i + 9] = heap[value++]; + view[i + 10] = heap[value++]; + view[i + 11] = heap[value++]; + view[i + 12] = heap[value++]; + view[i + 13] = heap[value++]; + view[i + 14] = heap[value++]; + view[i + 15] = heap[value++]; } } else #endif @@ -2935,41 +2932,43 @@ var LibraryGL = { glVertexAttrib1fv__sig: 'vii', glVertexAttrib1fv: function(index, v) { #if GL_ASSERTIONS - assert((v & 3) == 0, 'Pointer to float data passed to glVertexAttrib1fv must be aligned to four bytes!'); + assert({{{ isPtrAligned('v', 4) }}}, 'Pointer to float data passed to glVertexAttrib1fv must be aligned to four bytes!'); assert(v != 0, 'Null pointer passed to glVertexAttrib1fv!'); #endif - GLctx.vertexAttrib1f(index, HEAPF32[v>>2]); + GLctx.vertexAttrib1f(index, HEAPF32[{{{ ptrToIdx('v', 2) }}}]); }, glVertexAttrib2fv__sig: 'vii', glVertexAttrib2fv: function(index, v) { #if GL_ASSERTIONS - assert((v & 3) == 0, 'Pointer to float data passed to glVertexAttrib2fv must be aligned to four bytes!'); + assert({{{ isPtrAligned('v', 4) }}}, 'Pointer to float data passed to glVertexAttrib2fv must be aligned to four bytes!'); assert(v != 0, 'Null pointer passed to glVertexAttrib2fv!'); #endif - GLctx.vertexAttrib2f(index, HEAPF32[v>>2], HEAPF32[v+4>>2]); + {{{ convertPtrToIdx('v', 2) }}}; + GLctx.vertexAttrib2f(index, HEAPF32[v++], HEAPF32[v]); }, glVertexAttrib3fv__sig: 'vii', glVertexAttrib3fv: function(index, v) { #if GL_ASSERTIONS - assert((v & 3) == 0, 'Pointer to float data passed to glVertexAttrib3fv must be aligned to four bytes!'); + assert({{{ isPtrAligned('v', 4) }}}, 'Pointer to float data passed to glVertexAttrib3fv must be aligned to four bytes!'); assert(v != 0, 'Null pointer passed to glVertexAttrib3fv!'); #endif - GLctx.vertexAttrib3f(index, HEAPF32[v>>2], HEAPF32[v+4>>2], HEAPF32[v+8>>2]); + {{{ convertPtrToIdx('v', 2) }}}; + GLctx.vertexAttrib3f(index, HEAPF32[v++], HEAPF32[v++], HEAPF32[v]); }, glVertexAttrib4fv__sig: 'vii', glVertexAttrib4fv: function(index, v) { #if GL_ASSERTIONS - assert((v & 3) == 0, 'Pointer to float data passed to glVertexAttrib4fv must be aligned to four bytes!'); assert(v != 0, 'Null pointer passed to glVertexAttrib4fv!'); #endif - GLctx.vertexAttrib4f(index, HEAPF32[v>>2], HEAPF32[v+4>>2], HEAPF32[v+8>>2], HEAPF32[v+12>>2]); + {{{ convertPtrToIdx('v', 2) }}}; + GLctx.vertexAttrib4f(index, HEAPF32[v++], HEAPF32[v++], HEAPF32[v++], HEAPF32[v]); }, glGetAttribLocation__sig: 'iii', @@ -3937,9 +3936,9 @@ var LibraryGL = { GLctx.multiDrawWebgl['multiDrawArraysWEBGL']( mode, HEAP32, - firsts >> 2, + {{{ idxToMemory53(ptrToIdx('firsts', 2)) }}}, HEAP32, - counts >> 2, + {{{ idxToMemory53(ptrToIdx('counts', 2)) }}}, drawcount); }, @@ -3949,11 +3948,11 @@ var LibraryGL = { GLctx.multiDrawWebgl['multiDrawArraysInstancedWEBGL']( mode, HEAP32, - firsts >> 2, + {{{ idxToMemory53(ptrToIdx('firsts', 2)) }}}, HEAP32, - counts >> 2, + {{{ idxToMemory53(ptrToIdx('counts', 2)) }}}, HEAP32, - instanceCounts >> 2, + {{{ idxToMemory53(ptrToIdx('instanceCounts', 2)) }}}, drawcount); }, @@ -3964,10 +3963,10 @@ var LibraryGL = { GLctx.multiDrawWebgl['multiDrawElementsWEBGL']( mode, HEAP32, - counts >> 2, + {{{ idxToMemory53(ptrToIdx('counts', 2)) }}}, type, HEAP32, - offsets >> 2, + {{{ idxToMemory53(ptrToIdx('offsets', 2)) }}}, drawcount); }, @@ -3977,12 +3976,12 @@ var LibraryGL = { GLctx.multiDrawWebgl['multiDrawElementsInstancedWEBGL']( mode, HEAP32, - counts >> 2, + {{{ idxToMemory53(ptrToIdx('counts', 2)) }}}, type, HEAP32, - offsets >> 2, + {{{ idxToMemory53(ptrToIdx('offsets', 2)) }}}, HEAP32, - instanceCounts >> 2, + {{{ idxToMemory53(ptrToIdx('instanceCounts', 2)) }}}, drawcount); }, diff --git a/src/library_webgl2.js b/src/library_webgl2.js index 8ee79961e91f8..71e776e7bb4b6 100644 --- a/src/library_webgl2.js +++ b/src/library_webgl2.js @@ -167,7 +167,7 @@ var LibraryWebGL2 = { GLctx['texImage3D'](target, level, internalFormat, width, height, depth, border, format, type, pixels); } else if (pixels) { var heap = heapObjectForWebGLType(type); - GLctx['texImage3D'](target, level, internalFormat, width, height, depth, border, format, type, heap, pixels >> heapAccessShiftForWebGLHeap(heap)); + GLctx['texImage3D'](target, level, internalFormat, width, height, depth, border, format, type, heap, {{{ ptrToIdx('pixels', 'heapAccessShiftForWebGLHeap(heap)') }}}); } else { GLctx['texImage3D'](target, level, internalFormat, width, height, depth, border, format, type, null); } @@ -180,7 +180,7 @@ var LibraryWebGL2 = { GLctx['texSubImage3D'](target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels); } else if (pixels) { var heap = heapObjectForWebGLType(type); - GLctx['texSubImage3D'](target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, heap, pixels >> heapAccessShiftForWebGLHeap(heap)); + GLctx['texSubImage3D'](target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, heap, {{{ ptrToIdx('pixels', 'heapAccessShiftForWebGLHeap(heap)') }}}); } else { GLctx['texSubImage3D'](target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, null); } @@ -677,7 +677,7 @@ var LibraryWebGL2 = { assert((value & 3) == 0, 'Pointer to integer data passed to glClearBufferiv must be aligned to four bytes!'); #endif - GLctx['clearBufferiv'](buffer, drawbuffer, HEAP32, value>>2); + GLctx['clearBufferiv'](buffer, drawbuffer, HEAP32, {{{ ptrToIdx('value', 2) }}}); }, glClearBufferuiv__sig: 'viii', @@ -686,7 +686,7 @@ var LibraryWebGL2 = { assert((value & 3) == 0, 'Pointer to integer data passed to glClearBufferuiv must be aligned to four bytes!'); #endif - GLctx['clearBufferuiv'](buffer, drawbuffer, HEAPU32, value>>2); + GLctx['clearBufferuiv'](buffer, drawbuffer, HEAPU32, {{{ ptrToIdx('value', 2) }}}); }, glClearBufferfv__sig: 'viii', @@ -695,7 +695,7 @@ var LibraryWebGL2 = { assert((value & 3) == 0, 'Pointer to float data passed to glClearBufferfv must be aligned to four bytes!'); #endif - GLctx['clearBufferfv'](buffer, drawbuffer, HEAPF32, value>>2); + GLctx['clearBufferfv'](buffer, drawbuffer, HEAPF32, {{{ ptrToIdx('value', 2) }}}); }, glFenceSync__sig: 'iii', @@ -851,7 +851,7 @@ var LibraryWebGL2 = { GL.validateGLObjectID(GLctx.currentProgram.uniformLocsById, location, 'glUniform1uiv', 'location'); assert((value & 3) == 0, 'Pointer to integer data passed to glUniform1uiv must be aligned to four bytes!'); #endif - count && GLctx.uniform1uiv(webglGetUniformLocation(location), HEAPU32, value>>2, count); + count && GLctx.uniform1uiv(webglGetUniformLocation(location), HEAPU32, {{{ ptrToIdx('value', 2) }}}, count); }, glUniform2uiv__sig: 'viii', @@ -861,7 +861,7 @@ var LibraryWebGL2 = { GL.validateGLObjectID(GLctx.currentProgram.uniformLocsById, location, 'glUniform2uiv', 'location'); assert((value & 3) == 0, 'Pointer to integer data passed to glUniform2uiv must be aligned to four bytes!'); #endif - count && GLctx.uniform2uiv(webglGetUniformLocation(location), HEAPU32, value>>2, count*2); + count && GLctx.uniform2uiv(webglGetUniformLocation(location), HEAPU32, {{{ ptrToIdx('value', 2) }}}, count*2); }, glUniform3uiv__sig: 'viii', @@ -871,7 +871,7 @@ var LibraryWebGL2 = { GL.validateGLObjectID(GLctx.currentProgram.uniformLocsById, location, 'glUniform3uiv', 'location'); assert((value & 3) == 0, 'Pointer to integer data passed to glUniform3uiv must be aligned to four bytes!'); #endif - count && GLctx.uniform3uiv(webglGetUniformLocation(location), HEAPU32, value>>2, count*3); + count && GLctx.uniform3uiv(webglGetUniformLocation(location), HEAPU32, {{{ ptrToIdx('value', 2) }}}, count*3); }, glUniform4uiv__sig: 'viii', @@ -881,7 +881,7 @@ var LibraryWebGL2 = { GL.validateGLObjectID(GLctx.currentProgram.uniformLocsById, location, 'glUniform4uiv', 'location'); assert((value & 3) == 0, 'Pointer to integer data passed to glUniform4uiv must be aligned to four bytes!'); #endif - count && GLctx.uniform4uiv(webglGetUniformLocation(location), HEAPU32, value>>2, count*4); + count && GLctx.uniform4uiv(webglGetUniformLocation(location), HEAPU32, {{{ ptrToIdx('value', 2) }}}, count*4); }, glUniformMatrix2x3fv__sig: 'viiii', @@ -891,7 +891,7 @@ var LibraryWebGL2 = { GL.validateGLObjectID(GLctx.currentProgram.uniformLocsById, location, 'glUniformMatrix2x3fv', 'location'); assert((value & 3) == 0, 'Pointer to float data passed to glUniformMatrix2x3fv must be aligned to four bytes!'); #endif - count && GLctx.uniformMatrix2x3fv(webglGetUniformLocation(location), !!transpose, HEAPF32, value>>2, count*6); + count && GLctx.uniformMatrix2x3fv(webglGetUniformLocation(location), !!transpose, HEAPF32, {{{ ptrToIdx('value', 2) }}}, count*6); }, glUniformMatrix3x2fv__sig: 'viiii', @@ -901,7 +901,7 @@ var LibraryWebGL2 = { GL.validateGLObjectID(GLctx.currentProgram.uniformLocsById, location, 'glUniformMatrix3x2fv', 'location'); assert((value & 3) == 0, 'Pointer to float data passed to glUniformMatrix3x2fv must be aligned to four bytes!'); #endif - count && GLctx.uniformMatrix3x2fv(webglGetUniformLocation(location), !!transpose, HEAPF32, value>>2, count*6); + count && GLctx.uniformMatrix3x2fv(webglGetUniformLocation(location), !!transpose, HEAPF32, {{{ ptrToIdx('value', 2) }}}, count*6); }, glUniformMatrix2x4fv__sig: 'viiii', @@ -911,7 +911,7 @@ var LibraryWebGL2 = { GL.validateGLObjectID(GLctx.currentProgram.uniformLocsById, location, 'glUniformMatrix2x4fv', 'location'); assert((value & 3) == 0, 'Pointer to float data passed to glUniformMatrix2x4fv must be aligned to four bytes!'); #endif - count && GLctx.uniformMatrix2x4fv(webglGetUniformLocation(location), !!transpose, HEAPF32, value>>2, count*8); + count && GLctx.uniformMatrix2x4fv(webglGetUniformLocation(location), !!transpose, HEAPF32, {{{ ptrToIdx('value', 2) }}}, count*8); }, glUniformMatrix4x2fv__sig: 'viiii', @@ -921,7 +921,7 @@ var LibraryWebGL2 = { GL.validateGLObjectID(GLctx.currentProgram.uniformLocsById, location, 'glUniformMatrix4x2fv', 'location'); assert((value & 3) == 0, 'Pointer to float data passed to glUniformMatrix4x2fv must be aligned to four bytes!'); #endif - count && GLctx.uniformMatrix4x2fv(webglGetUniformLocation(location), !!transpose, HEAPF32, value>>2, count*8); + count && GLctx.uniformMatrix4x2fv(webglGetUniformLocation(location), !!transpose, HEAPF32, {{{ ptrToIdx('value', 2) }}}, count*8); }, glUniformMatrix3x4fv__sig: 'viiii', @@ -931,7 +931,7 @@ var LibraryWebGL2 = { GL.validateGLObjectID(GLctx.currentProgram.uniformLocsById, location, 'glUniformMatrix3x4fv', 'location'); assert((value & 3) == 0, 'Pointer to float data passed to glUniformMatrix3x4fv must be aligned to four bytes!'); #endif - count && GLctx.uniformMatrix3x4fv(webglGetUniformLocation(location), !!transpose, HEAPF32, value>>2, count*12); + count && GLctx.uniformMatrix3x4fv(webglGetUniformLocation(location), !!transpose, HEAPF32, {{{ ptrToIdx('value', 2) }}}, count*12); }, glUniformMatrix4x3fv__sig: 'viiii', @@ -941,7 +941,7 @@ var LibraryWebGL2 = { GL.validateGLObjectID(GLctx.currentProgram.uniformLocsById, location, 'glUniformMatrix4x3fv', 'location'); assert((value & 3) == 0, 'Pointer to float data passed to glUniformMatrix4x3fv must be aligned to four bytes!'); #endif - count && GLctx.uniformMatrix4x3fv(webglGetUniformLocation(location), !!transpose, HEAPF32, value>>2, count*12); + count && GLctx.uniformMatrix4x3fv(webglGetUniformLocation(location), !!transpose, HEAPF32, {{{ ptrToIdx('value', 2) }}}, count*12); }, glVertexAttribI4iv__sig: 'vii', @@ -950,7 +950,8 @@ var LibraryWebGL2 = { assert((v & 3) == 0, 'Pointer to integer data passed to glVertexAttribI4iv must be aligned to four bytes!'); assert(v != 0, 'Null pointer passed to glVertexAttribI4iv!'); #endif - GLctx.vertexAttribI4i(index, HEAP32[v>>2], HEAP32[v+4>>2], HEAP32[v+8>>2], HEAP32[v+12>>2]); + {{{ convertPtrToIdx('v', 2) }}} + GLctx.vertexAttribI4i(index, HEAP32[v++], HEAP32[v++], HEAP32[v++], HEAP32[v]); }, glVertexAttribI4uiv__sig: 'vii', @@ -959,7 +960,8 @@ var LibraryWebGL2 = { assert((v & 3) == 0, 'Pointer to integer data passed to glVertexAttribI4uiv must be aligned to four bytes!'); assert(v != 0, 'Null pointer passed to glVertexAttribI4uiv!'); #endif - GLctx.vertexAttribI4ui(index, HEAPU32[v>>2], HEAPU32[v+4>>2], HEAPU32[v+8>>2], HEAPU32[v+12>>2]); + {{{ convertPtrToIdx('v', 2) }}} + GLctx.vertexAttribI4ui(index, HEAPU32[v++], HEAPU32[v++], HEAPU32[v++], HEAPU32[v]); }, glProgramParameteri__sig: 'viii', @@ -1059,13 +1061,13 @@ var LibraryWebGL2 = { GLctx.mdibvbi['multiDrawArraysInstancedBaseInstanceWEBGL']( mode, HEAP32, - firsts >> 2, + {{{ ptrToIdx('firsts', 2) }}}, HEAP32, - counts >> 2, + {{{ ptrToIdx('counts', 2) }}}, HEAP32, - instanceCounts >> 2, + {{{ ptrToIdx('instanceCounts', 2) }}}, HEAPU32, - baseInstances >> 2, + {{{ ptrToIdx('baseInstances', 2) }}}, drawCount); }, glMultiDrawArraysInstancedBaseInstanceANGLE: 'glMultiDrawArraysInstancedBaseInstanceWEBGL', @@ -1075,16 +1077,16 @@ var LibraryWebGL2 = { GLctx.mdibvbi['multiDrawElementsInstancedBaseVertexBaseInstanceWEBGL']( mode, HEAP32, - counts >> 2, + {{{ ptrToIdx('counts', 2) }}}, type, HEAP32, - offsets >> 2, + {{{ ptrToIdx('offsets', 2) }}}, HEAP32, - instanceCounts >> 2, + {{{ ptrToIdx('instanceCounts', 2) }}}, HEAP32, - baseVertices >> 2, + {{{ ptrToIdx('baseVertices', 2) }}}, HEAPU32, - baseInstances >> 2, + {{{ ptrToIdx('baseInstances', 2) }}}, drawCount); }, glMultiDrawElementsInstancedBaseVertexBaseInstanceANGLE: 'glMultiDrawElementsInstancedBaseVertexBaseInstanceWEBGL', diff --git a/src/parseTools.js b/src/parseTools.js index 388b3f06e8d50..7fe09d5715136 100644 --- a/src/parseTools.js +++ b/src/parseTools.js @@ -1019,8 +1019,55 @@ function from64(x) { } function to64(x) { - if (!MEMORY64) return x; - return `BigInt(${x})`; + if (MEMORY64) return /^\d+$/.test(x) ? `${x}n` : `BigInt(${x})`; + return x; +} + +// Generates an expression that tests whether a pointer (either a BigInt or a signed int32 JS Number) is aligned to the given byte multiple. +function isPtrAligned(ptr, alignment) { + if (MEMORY64) return /^\d+$/.test(alignment) ? `${ptr} % ${alignment}n == 0` : `${ptr} % BigInt(${alignment}) == 0`; + return `${ptr} % ${alignment} == 0`; +} + +let MAX_MEMORY53 = 2**53; // == 9007199254740992 + +// Converts a pointer (either a BigInt or a signed int32 JS Number) in-place to an index on the heap (a BigInt or an unsigned JS Number). +// N.B. in ASSERTIONS mode may generate two statements (in form "a;b;"). +function convertPtrToIdx(ptr, accessWidth) { + var assertPointerAlignment = ASSERTIONS ? `${isPtrAligned(ptr, accessWidth)};` : ''; + + var conversion; + if (MEMORY64) { + if (MAXIMUM_MEMORY > MAX_MEMORY53) conversion = /^\d+$/.test(accessWidth) ? `${ptr} >>= ${accessWidth}n` : `${ptr} >>= BigInt(${accessWidth})`; + else conversion = `${ptr} = Number(${ptr}) / ${accessWidth}`; + } + else if (MAXIMUM_MEMORY > 2*1024*1024*1024) conversion = `${ptr} >>>= ${accessWidth}`; + else conversion = accessWidth ? `${ptr} >>= ${accessWidth}` : ''; + + return assertPointerAlignment + conversion; +} + +// Returns a pointer (either a BigInt or a signed int32 JS Number) shifted to an index on the heap (a BigInt or an unsigned JS Number). +function ptrToIdx(ptr, accessWidth) { + if (MEMORY64) { + if (MAXIMUM_MEMORY > MAX_MEMORY53) return /^\d+$/.test(accessWidth) ? `${ptr} >> ${accessWidth}n` : `${ptr} >> BigInt(${accessWidth})`; + return `Number(${ptr}) / ${accessWidth}`; + } + if (MAXIMUM_MEMORY > 2*1024*1024*1024) return `${ptr} >>> ${accessWidth}`; + return accessWidth ? `${ptr} >> ${accessWidth}` : ptr; +} + +// Converts a given JS Number (e.g. a pointer offset) to a heap index type (either a BigInt or a JS Number) +function createHeapIdx(number) { + if (MAXIMUM_MEMORY > MAX_MEMORY53) return /^-?\d+$/.test(number) ? `${number}n` : `BigInt(${number})`; + return number; +} + +// Browsers might not support passing BigInts to different API entry points that take in addresses, so convert those to Number()s before calling into the browser APIs. +function idxToMemory53(heapIndex) { + if (MAXIMUM_MEMORY <= MAX_MEMORY53) return heapIndex; // If not building with large 64-bit memory, heap indices will not be BigInts. + if (ASSERTIONS) return `BigInt(Number(${heapIndex})) == ${heapIndex} ? abort('Invalid pointer that does not fit in 53-bits address space!') : Number(${heapIndex})`; + return `Number(${heapIndex})`; } // Add assertions to catch common errors when using the Promise object we From aedd114d6374609ced87572825418170ae8f5f53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jukka=20Jyl=C3=A4nki?= Date: Thu, 4 Nov 2021 19:55:07 +0200 Subject: [PATCH 2/6] Use const --- src/parseTools.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/parseTools.js b/src/parseTools.js index 7fe09d5715136..87be5671f7df0 100644 --- a/src/parseTools.js +++ b/src/parseTools.js @@ -1029,7 +1029,7 @@ function isPtrAligned(ptr, alignment) { return `${ptr} % ${alignment} == 0`; } -let MAX_MEMORY53 = 2**53; // == 9007199254740992 +const MAX_MEMORY53 = 2**53; // == 9007199254740992 // Converts a pointer (either a BigInt or a signed int32 JS Number) in-place to an index on the heap (a BigInt or an unsigned JS Number). // N.B. in ASSERTIONS mode may generate two statements (in form "a;b;"). From 4ec3cdaafe253cee9c4660ac7e6c194face57bc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jukka=20Jyl=C3=A4nki?= Date: Thu, 4 Nov 2021 19:56:38 +0200 Subject: [PATCH 3/6] lint --- src/parseTools.js | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/parseTools.js b/src/parseTools.js index 87be5671f7df0..32912b64aa65a 100644 --- a/src/parseTools.js +++ b/src/parseTools.js @@ -1029,20 +1029,22 @@ function isPtrAligned(ptr, alignment) { return `${ptr} % ${alignment} == 0`; } -const MAX_MEMORY53 = 2**53; // == 9007199254740992 +const MAX_MEMORY53 = 2 ** 53; // == 9007199254740992 // Converts a pointer (either a BigInt or a signed int32 JS Number) in-place to an index on the heap (a BigInt or an unsigned JS Number). // N.B. in ASSERTIONS mode may generate two statements (in form "a;b;"). function convertPtrToIdx(ptr, accessWidth) { - var assertPointerAlignment = ASSERTIONS ? `${isPtrAligned(ptr, accessWidth)};` : ''; + let assertPointerAlignment = ASSERTIONS ? `${isPtrAligned(ptr, accessWidth)};` : ''; - var conversion; + let conversion; if (MEMORY64) { if (MAXIMUM_MEMORY > MAX_MEMORY53) conversion = /^\d+$/.test(accessWidth) ? `${ptr} >>= ${accessWidth}n` : `${ptr} >>= BigInt(${accessWidth})`; else conversion = `${ptr} = Number(${ptr}) / ${accessWidth}`; + } else if (MAXIMUM_MEMORY > 2 * 1024 * 1024 * 1024) { + conversion = `${ptr} >>>= ${accessWidth}`; + } else { + conversion = accessWidth ? `${ptr} >>= ${accessWidth}` : ''; } - else if (MAXIMUM_MEMORY > 2*1024*1024*1024) conversion = `${ptr} >>>= ${accessWidth}`; - else conversion = accessWidth ? `${ptr} >>= ${accessWidth}` : ''; return assertPointerAlignment + conversion; } @@ -1053,7 +1055,7 @@ function ptrToIdx(ptr, accessWidth) { if (MAXIMUM_MEMORY > MAX_MEMORY53) return /^\d+$/.test(accessWidth) ? `${ptr} >> ${accessWidth}n` : `${ptr} >> BigInt(${accessWidth})`; return `Number(${ptr}) / ${accessWidth}`; } - if (MAXIMUM_MEMORY > 2*1024*1024*1024) return `${ptr} >>> ${accessWidth}`; + if (MAXIMUM_MEMORY > 2 * 1024 * 1024 * 1024) return `${ptr} >>> ${accessWidth}`; return accessWidth ? `${ptr} >> ${accessWidth}` : ptr; } From 34c6a3137014542e89e9d6e0266f4e3512cb8318 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jukka=20Jyl=C3=A4nki?= Date: Thu, 4 Nov 2021 21:57:06 +0200 Subject: [PATCH 4/6] lint --- src/parseTools.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/parseTools.js b/src/parseTools.js index 32912b64aa65a..35971ed28aa24 100644 --- a/src/parseTools.js +++ b/src/parseTools.js @@ -1034,7 +1034,7 @@ const MAX_MEMORY53 = 2 ** 53; // == 9007199254740992 // Converts a pointer (either a BigInt or a signed int32 JS Number) in-place to an index on the heap (a BigInt or an unsigned JS Number). // N.B. in ASSERTIONS mode may generate two statements (in form "a;b;"). function convertPtrToIdx(ptr, accessWidth) { - let assertPointerAlignment = ASSERTIONS ? `${isPtrAligned(ptr, accessWidth)};` : ''; + const assertPointerAlignment = ASSERTIONS ? `${isPtrAligned(ptr, accessWidth)};` : ''; let conversion; if (MEMORY64) { From 51b10eb1eb1c39a7df42a0abc765a17053435eeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jukka=20Jyl=C3=A4nki?= Date: Thu, 26 Jan 2023 14:42:42 +0200 Subject: [PATCH 5/6] Disallow >53-bit memories --- src/parseTools.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/parseTools.js b/src/parseTools.js index 35971ed28aa24..1eb12bcf4db39 100644 --- a/src/parseTools.js +++ b/src/parseTools.js @@ -1038,8 +1038,10 @@ function convertPtrToIdx(ptr, accessWidth) { let conversion; if (MEMORY64) { - if (MAXIMUM_MEMORY > MAX_MEMORY53) conversion = /^\d+$/.test(accessWidth) ? `${ptr} >>= ${accessWidth}n` : `${ptr} >>= BigInt(${accessWidth})`; - else conversion = `${ptr} = Number(${ptr}) / ${accessWidth}`; + // if our address space would ever get larger than 53 bits, we could do something like this: + // if (MAXIMUM_MEMORY > MAX_MEMORY53) conversion = /^\d+$/.test(accessWidth) ? `${ptr} >>= ${accessWidth}n` : `${ptr} >>= BigInt(${accessWidth})`; + assert(MAXIMUM_MEMORY <= MAX_MEMORY53); + else conversion = `${ptr} = Number(${ptr}) / ${1 << accessWidth}`; } else if (MAXIMUM_MEMORY > 2 * 1024 * 1024 * 1024) { conversion = `${ptr} >>>= ${accessWidth}`; } else { @@ -1052,8 +1054,8 @@ function convertPtrToIdx(ptr, accessWidth) { // Returns a pointer (either a BigInt or a signed int32 JS Number) shifted to an index on the heap (a BigInt or an unsigned JS Number). function ptrToIdx(ptr, accessWidth) { if (MEMORY64) { - if (MAXIMUM_MEMORY > MAX_MEMORY53) return /^\d+$/.test(accessWidth) ? `${ptr} >> ${accessWidth}n` : `${ptr} >> BigInt(${accessWidth})`; - return `Number(${ptr}) / ${accessWidth}`; + assert(MAXIMUM_MEMORY <= MAX_MEMORY53); + return `Number(${ptr}) / ${1 << accessWidth}`; } if (MAXIMUM_MEMORY > 2 * 1024 * 1024 * 1024) return `${ptr} >>> ${accessWidth}`; return accessWidth ? `${ptr} >> ${accessWidth}` : ptr; From e018a554d331a45b0ab198428619434b48793b0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jukka=20Jyl=C3=A4nki?= Date: Fri, 3 Feb 2023 14:04:36 +0200 Subject: [PATCH 6/6] Fix typo --- src/parseTools.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/parseTools.js b/src/parseTools.js index 1eb12bcf4db39..0d5db6589f977 100644 --- a/src/parseTools.js +++ b/src/parseTools.js @@ -1041,7 +1041,7 @@ function convertPtrToIdx(ptr, accessWidth) { // if our address space would ever get larger than 53 bits, we could do something like this: // if (MAXIMUM_MEMORY > MAX_MEMORY53) conversion = /^\d+$/.test(accessWidth) ? `${ptr} >>= ${accessWidth}n` : `${ptr} >>= BigInt(${accessWidth})`; assert(MAXIMUM_MEMORY <= MAX_MEMORY53); - else conversion = `${ptr} = Number(${ptr}) / ${1 << accessWidth}`; + conversion = `${ptr} = Number(${ptr}) / ${1 << accessWidth}`; } else if (MAXIMUM_MEMORY > 2 * 1024 * 1024 * 1024) { conversion = `${ptr} >>>= ${accessWidth}`; } else {