diff options
Diffstat (limited to 'src/modules.js')
-rw-r--r-- | src/modules.js | 41 |
1 files changed, 31 insertions, 10 deletions
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') { |