aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xemscripten.py8
-rw-r--r--src/jsifier.js4
-rw-r--r--src/modules.js1
-rw-r--r--src/utility.js6
4 files changed, 18 insertions, 1 deletions
diff --git a/emscripten.py b/emscripten.py
index 3222e12f..5ad06bbc 100755
--- a/emscripten.py
+++ b/emscripten.py
@@ -390,6 +390,14 @@ Runtime.stackAlloc = function(size) { return asm.stackAlloc(size) };
Runtime.stackSave = function() { return asm.stackSave() };
Runtime.stackRestore = function(top) { asm.stackRestore(top) };
''' % (function_tables_defs.replace('\n', '\n ') + '\n' + '\n'.join(function_tables_impls), exports, sending, receiving)
+
+ # Set function table masks
+ def function_table_maskize(js):
+ masks = {}
+ for sig, table in last_forwarded_json['Functions']['tables'].iteritems():
+ masks[sig] = str(table.count(','))
+ return re.sub(r'{{{ FTM_([vdi]+) }}}', lambda m: masks[m.groups(0)[0]], js)
+ funcs_js = function_table_maskize(funcs_js)
else:
outfile.write(function_tables_defs)
outfile.write(blockaddrsize(indexize(funcs_js)))
diff --git a/src/jsifier.js b/src/jsifier.js
index a83b2d3d..50824562 100644
--- a/src/jsifier.js
+++ b/src/jsifier.js
@@ -1278,10 +1278,12 @@ function JSify(data, functionsOnly, givenFunctions) {
if (byPointer) {
var returnType = type.split(' ')[0];
+ var sig = Functions.getSignature(returnType, argsTypes);
if (ASM_JS) {
assert(returnType.search(/\("'\[,/) == -1); // XXX need isFunctionType(type, out)
+ ident = '(' + ident + ')&{{{ FTM_' + sig + ' }}}'; // the function table mask is set in emscripten.py
}
- ident = Functions.getTable(Functions.getSignature(returnType, argsTypes)) + '[' + ident + ']';
+ ident = Functions.getTable(sig) + '[' + ident + ']';
}
return ident + '(' + args.join(', ') + ')';
diff --git a/src/modules.js b/src/modules.js
index 71fec0cd..5c1d6a1d 100644
--- a/src/modules.js
+++ b/src/modules.js
@@ -259,6 +259,7 @@ 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);
}
diff --git a/src/utility.js b/src/utility.js
index 84b50ce9..63582ae8 100644
--- a/src/utility.js
+++ b/src/utility.js
@@ -321,6 +321,12 @@ function isPowerOfTwo(x) {
return x > 0 && ((x & (x-1)) == 0);
}
+function ceilPowerOfTwo(x) {
+ var ret = 1;
+ while (ret < x) ret <<= 1;
+ return ret;
+}
+
function Benchmarker() {
var starts = {}, times = {}, counts = {};
this.start = function(id) {