aboutsummaryrefslogtreecommitdiff
path: root/src/modules.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/modules.js')
-rw-r--r--src/modules.js77
1 files changed, 61 insertions, 16 deletions
diff --git a/src/modules.js b/src/modules.js
index 64638be1..dd027f73 100644
--- a/src/modules.js
+++ b/src/modules.js
@@ -216,14 +216,26 @@ var Types = {
};
var Functions = {
- // All functions that will be implemented in this file
+ // All functions that will be implemented in this file. Maps id to signature
implementedFunctions: {},
+ libraryFunctions: {}, // functions added from the library
+ unimplementedFunctions: {}, // library etc. functions that we need to index, maps id to signature
indexedFunctions: {},
nextIndex: 2, // Start at a non-0 (even, see below) value
blockAddresses: {}, // maps functions to a map of block labels to label ids
+ getSignature: function(returnType, argTypes) {
+ var sig = returnType == 'void' ? 'v' : (isIntImplemented(returnType) ? 'i' : 'f');
+ for (var i = 0; i < argTypes.length; i++) {
+ var type = argTypes[i];
+ if (!type) break; // varargs
+ sig += isIntImplemented(type) ? (getBits(type) == 64 ? 'ii' : 'i') : 'f'; // legalized i64s will be i32s
+ }
+ return sig;
+ },
+
// Mark a function as needing indexing. Python will coordinate them all
getIndex: function(ident) {
if (phase != 'post') {
@@ -240,27 +252,53 @@ var Functions = {
}
},
+ getTable: function(sig) {
+ return ASM_JS ? 'FUNCTION_TABLE_' + sig : 'FUNCTION_TABLE';
+ },
+
// Generate code for function indexing
generateIndexing: function() {
- var vals = zeros(this.nextIndex);
+ 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 = {};
+ 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
+ });
+ }
for (var ident in this.indexedFunctions) {
- vals[this.indexedFunctions[ident]] = ident;
+ var sig = ASM_JS ? Functions.implementedFunctions[ident] || Functions.unimplementedFunctions[ident] : 'x';
+ assert(sig, ident);
+ if (!tables[sig]) tables[sig] = emptyTable(sig); // TODO: make them compact
+ tables[sig][this.indexedFunctions[ident]] = ident;
}
// Resolve multi-level aliases all the way down
- for (var i = 0; i < vals.length; i++) {
- while (1) {
- var varData = Variables.globals[vals[i]];
- if (!(varData && varData.resolvedAlias)) break;
- vals[i] = vals[+varData.resolvedAlias || eval(varData.resolvedAlias)]; // might need to eval to turn (6) into 6
+ var generated = false;
+ for (var t in tables) {
+ generated = true;
+ var table = tables[t];
+ for (var i = 0; i < table.length; i++) {
+ while (1) {
+ var varData = Variables.globals[table[i]];
+ if (!(varData && varData.resolvedAlias)) break;
+ table[i] = table[+varData.resolvedAlias || eval(varData.resolvedAlias)]; // might need to eval to turn (6) into 6
+ }
+ }
+ var indices = table.toString().replace('"', '');
+ if (BUILD_AS_SHARED_LIB) {
+ // Shared libraries reuse the parent's function table.
+ tables[t] = Functions.getTable(t) + '.push.apply(' + Functions.getTable(t) + ', [' + indices + ']);\n';
+ } else {
+ tables[t] = 'var ' + Functions.getTable(t) + ' = [' + indices + '];\n';
}
}
- var indices = vals.toString().replace('"', '');
- if (BUILD_AS_SHARED_LIB) {
- // Shared libraries reuse the parent's function table.
- return 'FUNCTION_TABLE.push.apply(FUNCTION_TABLE, [' + indices + ']);';
- } else {
- return 'FUNCTION_TABLE = [' + indices + ']; Module["FUNCTION_TABLE"] = FUNCTION_TABLE;';
+ if (!generated && !ASM_JS) {
+ tables['x'] = 'var FUNCTION_TABLE = [0, 0];\n'; // default empty table
}
+ Functions.tables = tables;
}
};
@@ -311,16 +349,23 @@ var PassManager = {
print('\n//FORWARDED_DATA:' + JSON.stringify({
Types: Types,
Variables: Variables,
- Functions: Functions
+ Functions: Functions,
+ EXPORTED_FUNCTIONS: EXPORTED_FUNCTIONS // needed for asm.js global constructors (ctors)
}));
} else if (phase == 'funcs') {
print('\n//FORWARDED_DATA:' + JSON.stringify({
Types: { preciseI64MathUsed: Types.preciseI64MathUsed },
Functions: {
blockAddresses: Functions.blockAddresses,
- indexedFunctions: Functions.indexedFunctions
+ indexedFunctions: Functions.indexedFunctions,
+ implementedFunctions: ASM_JS ? Functions.implementedFunctions : [],
+ unimplementedFunctions: Functions.unimplementedFunctions,
}
}));
+ } else if (phase == 'post') {
+ print('\n//FORWARDED_DATA:' + JSON.stringify({
+ Functions: { tables: Functions.tables }
+ }));
}
},
load: function(json) {