diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/jsifier.js | 1 | ||||
-rw-r--r-- | src/library.js | 3 | ||||
-rw-r--r-- | src/library_gl.js | 11 | ||||
-rw-r--r-- | src/modules.js | 41 | ||||
-rw-r--r-- | src/settings.js | 4 |
5 files changed, 45 insertions, 15 deletions
diff --git a/src/jsifier.js b/src/jsifier.js index 8270b443..3f52337f 100644 --- a/src/jsifier.js +++ b/src/jsifier.js @@ -1463,6 +1463,7 @@ function JSify(data, functionsOnly, givenFunctions) { if (!byPointerForced && !funcData.setjmpTable) { // normal asm function pointer call callIdent = '(' + callIdent + ')&{{{ FTM_' + sig + ' }}}'; // the function table mask is set in emscripten.py + Functions.neededTables[sig] = 1; } else { // This is a call through an invoke_*, either a forced one, or a setjmp-required one // note: no need to update argsTypes at this point diff --git a/src/library.js b/src/library.js index 84071b68..d19fd531 100644 --- a/src/library.js +++ b/src/library.js @@ -3482,7 +3482,8 @@ LibraryManager.library = { } else if (oldObj.isRoot || oldObj.path == FS.currentPath) { ___setErrNo(ERRNO_CODES.EBUSY); return -1; - } else if (newObj.path && newObj.path.indexOf(oldObj.path) == 0) { + } else if (newObj.parentPath && + newObj.parentPath.indexOf(oldObj.path) == 0) { ___setErrNo(ERRNO_CODES.EINVAL); return -1; } else if (newObj.exists && newObj.object.isFolder) { diff --git a/src/library_gl.js b/src/library_gl.js index 0f6fb670..2e59f0d0 100644 --- a/src/library_gl.js +++ b/src/library_gl.js @@ -2880,7 +2880,7 @@ var LibraryGL = { // Vertex array object (VAO) support. TODO: when the WebGL extension is popular, use that and remove this code and GL.vaos glGenVertexArrays__deps: ['$GLEMulation'], - glGenVertexArrays__sig: ['vii'], + glGenVertexArrays__sig: 'vii', glGenVertexArrays: function(n, vaos) { for (var i = 0; i < n; i++) { var id = GL.getNewId(GLEmulation.vaos); @@ -2895,7 +2895,7 @@ var LibraryGL = { {{{ makeSetValue('vaos', 'i*4', 'id', 'i32') }}}; } }, - glDeleteVertexArrays__sig: ['vii'], + glDeleteVertexArrays__sig: 'vii', glDeleteVertexArrays: function(n, vaos) { for (var i = 0; i < n; i++) { var id = {{{ makeGetValue('vaos', 'i*4', 'i32') }}}; @@ -2903,7 +2903,7 @@ var LibraryGL = { if (GLEmulation.currentVao && GLEmulation.currentVao.id == id) GLEmulation.currentVao = null; } }, - glBindVertexArray__sig: ['vi'], + glBindVertexArray__sig: 'vi', glBindVertexArray: function(vao) { // undo vao-related things, wipe the slate clean, both for vao of 0 or an actual vao GLEmulation.currentVao = null; // make sure the commands we run here are not recorded @@ -3331,7 +3331,10 @@ for (var item in LibraryGL) { } LibraryGL.$GLEmulation__deps = LibraryGL.$GLEmulation__deps.concat(glFuncs); LibraryGL.$GLEmulation__deps.push(function() { - for (var func in Functions.getIndex.tentative) Functions.getIndex(func); + for (var func in Functions.getIndex.tentative) { + Functions.getIndex(func); + Functions.unimplementedFunctions[func] = LibraryGL[func.substr(1) + '__sig']; + } }); if (FORCE_GL_EMULATION) { diff --git a/src/modules.js b/src/modules.js index 2775bfbd..e4093078 100644 --- a/src/modules.js +++ b/src/modules.js @@ -229,6 +229,8 @@ var Types = { preciseI64MathUsed: (PRECISE_I64_MATH == 2) }; +var firstTableIndex = (ASM_JS ? 2*RESERVED_FUNCTION_POINTERS : 0) + 2; + var Functions = { // All functions that will be implemented in this file. Maps id to signature implementedFunctions: {}, @@ -236,7 +238,9 @@ var Functions = { unimplementedFunctions: {}, // library etc. functions that we need to index, maps id to signature indexedFunctions: {}, - nextIndex: (ASM_JS ? 2*RESERVED_FUNCTION_POINTERS : 0) + 2, // Start at a non-0 (even, see below) value + nextIndex: firstTableIndex, // Start at a non-0 (even, see below) value + neededTables: set('v', 'vi', 'ii', 'iii'), // signatures that appeared (initialized with library stuff + // we always use), and we will need a function table for blockAddresses: {}, // maps functions to a map of block labels to label ids @@ -261,6 +265,7 @@ var Functions = { if (!doNotCreate) this.indexedFunctions[ident] = 0; // tell python we need this indexized return "'{{ FI_" + toNiceIdent(ident) + " }}'"; // something python will replace later } else { + if (!singlePhase) return 'NO_INDEX'; // Should not index functions in post var ret = this.indexedFunctions[ident]; if (!ret) { if (doNotCreate) return '0'; @@ -278,25 +283,25 @@ var Functions = { // Generate code for function indexing generateIndexing: function() { - var total = this.nextIndex; - if (ASM_JS) total = ceilPowerOfTwo(total); // must be power of 2 for mask - function emptyTable(sig) { - return zeros(total); - } var tables = { pre: '' }; if (ASM_JS) { - ['v', 'vi', 'ii', 'iii'].forEach(function(sig) { // add some default signatures that are used in the library - tables[sig] = emptyTable(sig); // TODO: make them compact + keys(Functions.neededTables).forEach(function(sig) { // add some default signatures that are used in the library + tables[sig] = zeros(firstTableIndex); }); } for (var ident in this.indexedFunctions) { var sig = ASM_JS ? Functions.implementedFunctions[ident] || Functions.unimplementedFunctions[ident] || LibraryManager.library[ident.substr(1) + '__sig'] : 'x'; assert(sig, ident); - if (!tables[sig]) tables[sig] = emptyTable(sig); // TODO: make them compact - tables[sig][this.indexedFunctions[ident]] = ident; + if (!tables[sig]) tables[sig] = zeros(firstTableIndex); + var index = this.indexedFunctions[ident]; + for (var i = tables[sig].length; i < index; i++) { + tables[sig][i] = 0; // keep flat + } + tables[sig][index] = ident; } var generated = false; var wrapped = {}; + var maxTable = 0; for (var t in tables) { if (t == 'pre') continue; generated = true; @@ -351,6 +356,21 @@ var Functions = { j += 10; } } + maxTable = Math.max(maxTable, table.length); + } + if (ASM_JS) maxTable = ceilPowerOfTwo(maxTable); + for (var t in tables) { + if (t == 'pre') continue; + var table = tables[t]; + if (ASM_JS) { + // asm function table mask must be power of two + // if nonaliasing, then standardize function table size, to avoid aliasing pointers through the &M mask (in a small table using a big index) + var fullSize = ALIASING_FUNCTION_POINTERS ? ceilPowerOfTwo(table.length) : maxTable; + for (var i = table.length; i < fullSize; i++) { + table[i] = 0; + } + } + // finalize table var indices = table.toString().replace('"', ''); if (BUILD_AS_SHARED_LIB) { // Shared libraries reuse the parent's function table. @@ -428,6 +448,7 @@ var PassManager = { indexedFunctions: Functions.indexedFunctions, implementedFunctions: ASM_JS ? Functions.implementedFunctions : [], unimplementedFunctions: Functions.unimplementedFunctions, + neededTables: Functions.neededTables } })); } else if (phase == 'post') { diff --git a/src/settings.js b/src/settings.js index 8766277b..d3abb06e 100644 --- a/src/settings.js +++ b/src/settings.js @@ -142,6 +142,10 @@ var SAFE_DYNCALLS = 0; // Show stack traces on missing function pointer/virtual var RESERVED_FUNCTION_POINTERS = 0; // In asm.js mode, we cannot simply add function pointers to // function tables, so we reserve some slots for them. +var ALIASING_FUNCTION_POINTERS = 0; // Whether to allow function pointers to alias if they have + // a different type. This can greatly decrease table sizes + // in asm.js, but can break code that compares function + // pointers across different types. var ASM_HEAP_LOG = 0; // Simple heap logging, like SAFE_HEAP_LOG but cheaper, and in asm.js |