aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2012-11-24 23:06:44 +0100
committerAlon Zakai <alonzakai@gmail.com>2012-12-07 14:23:18 -0800
commit26e9eba5aa1db69ad6fa36f6b6f27aed7532623c (patch)
treebfd1414c2dfdefca1f7afb4cea96b12fd3d217f7
parentff39897223947c89af7066f3a9421db28e796605 (diff)
generate separate type-specific function tables
-rwxr-xr-xemscripten.py5
-rw-r--r--src/intertyper.js1
-rw-r--r--src/jsifier.js18
-rw-r--r--src/library_gl.js115
-rw-r--r--src/modules.js56
-rw-r--r--src/parseTools.js15
-rw-r--r--src/preamble.js5
-rw-r--r--src/runtime.js20
-rwxr-xr-xtests/runner.py2
9 files changed, 141 insertions, 96 deletions
diff --git a/emscripten.py b/emscripten.py
index a9a1824d..bb78e311 100755
--- a/emscripten.py
+++ b/emscripten.py
@@ -236,6 +236,8 @@ def emscript(infile, settings, outfile, libraries=[]):
if settings.get('ASM_JS'):
for key in curr_forwarded_json['Functions']['implementedFunctions'].iterkeys():
if key in all_exported_functions: exported_implemented_functions.add(key)
+ for key, value in curr_forwarded_json['Functions']['libraryFunctions'].iteritems():
+ forwarded_json['Functions']['libraryFunctions'][key] = value
funcs_js = ''.join([output[0] for output in outputs])
@@ -247,7 +249,7 @@ def emscript(infile, settings, outfile, libraries=[]):
exports = '{ ' + ', '.join(exports) + ' }'
# caculate globals
global_vars = forwarded_json['Variables']['globals'].keys()
- global_funcs = ['_' + x for x in forwarded_json['Functions']['libraryFunctions']]
+ global_funcs = ['_' + x for x in forwarded_json['Functions']['libraryFunctions'].keys()]
asm_globals = ''.join([' var ' + g + '=env.' + g + ';\n' for g in global_vars + global_funcs])
# sent data
basics = ['buffer', 'Int8Array', 'Int16Array', 'Int32Array', 'Uint8Array', 'Uint16Array', 'Uint32Array', 'Float32Array', 'Float64Array']
@@ -311,6 +313,7 @@ for (var _export in asm) Module[_export] = asm[_export];
open(post_file, 'w').write('\n') # no input, just processing of forwarded data
out = shared.run_js(compiler, shared.COMPILER_ENGINE, [settings_file, post_file, 'post', forwarded_file] + libraries, stdout=subprocess.PIPE, cwd=path_from_root('src'))
#if DEBUG: outfile.write('// post\n')
+
outfile.write(indexize(out))
if DEBUG: print >> sys.stderr, ' emscript: phase 3 took %s seconds' % (time.time() - t)
diff --git a/src/intertyper.js b/src/intertyper.js
index 7db1a2fe..4957ae31 100644
--- a/src/intertyper.js
+++ b/src/intertyper.js
@@ -125,6 +125,7 @@ function intertyper(data, sidePass, baseLineNums) {
// We need this early, to know basic function info - ident, params, varargs
ident: toNiceIdent(func.ident),
params: func.params,
+ returnType: func.returnType,
hasVarArgs: func.hasVarArgs,
lineNum: currFunctionLineNum,
lines: currFunctionLines
diff --git a/src/jsifier.js b/src/jsifier.js
index 3a9d6ab5..6f40e2d4 100644
--- a/src/jsifier.js
+++ b/src/jsifier.js
@@ -42,7 +42,9 @@ function JSify(data, functionsOnly, givenFunctions) {
var pre = processMacros(preprocess(read(preFile).replace('{{RUNTIME}}', getRuntime())));
print(pre);
- Functions.implementedFunctions = set(data.unparsedFunctions.map(function(func) { return func.ident }));
+ data.unparsedFunctions.forEach(function(func) {
+ Functions.implementedFunctions[func.ident] = Functions.getSignature(func.returnType, func.params.map(function(param) { return param.type }));
+ });
}
}
@@ -420,7 +422,7 @@ function JSify(data, functionsOnly, givenFunctions) {
snippet = snippet.replace('{', '{ var ret = (function() { if (Runtime.debug) Module.printErr("[library call:' + ident + ': " + Array.prototype.slice.call(arguments).map(Runtime.prettyPrint) + "]"); ');
snippet = snippet.substr(0, snippet.length-1) + '}).apply(this, arguments); if (Runtime.debug && typeof ret !== "undefined") Module.printErr(" [ return:" + Runtime.prettyPrint(ret)); return ret; }';
}
- if (ASM_JS) Functions.libraryFunctions.push(ident);
+ if (ASM_JS) Functions.libraryFunctions[ident] = 1;
}
var postsetId = ident + '__postset';
@@ -1159,6 +1161,7 @@ function JSify(data, functionsOnly, givenFunctions) {
var useJSArgs = (shortident + '__jsargs') in LibraryManager.library;
var hasVarArgs = isVarArgsFunctionType(type);
var normalArgs = (hasVarArgs && !useJSArgs) ? countNormalArgs(type) : -1;
+ var byPointer = getVarData(funcData, ident);
params.forEach(function(param, i) {
var val = finalizeParam(param);
@@ -1224,8 +1227,8 @@ function JSify(data, functionsOnly, givenFunctions) {
return inline.apply(null, args); // Warning: inlining does not prevent recalculation of the arguments. They should be simple identifiers
}
- if (getVarData(funcData, ident)) {
- ident = 'FUNCTION_TABLE[' + ident + ']';
+ if (byPointer) {
+ ident = 'FUNCTION_TABLE_' + Functions.getSignature(type, argsTypes) + '[' + ident + ']';
}
return ident + '(' + args.join(', ') + ')';
@@ -1324,8 +1327,7 @@ function JSify(data, functionsOnly, givenFunctions) {
}
if (phase == 'pre' || phase == 'funcs') {
- // serialize out the data that later passes need
- PassManager.serialize(); // XXX for funcs pass, do not serialize it all. I think we just need which were indexized.
+ PassManager.serialize();
return;
}
@@ -1352,7 +1354,7 @@ function JSify(data, functionsOnly, givenFunctions) {
var postParts = processMacros(preprocess(read(postFile))).split('{{GLOBAL_VARS}}');
print(postParts[0]);
- print(Functions.generateIndexing()); // done last, as it may rely on aliases set in postsets
+ Functions.generateIndexing(); // done last, as it may rely on aliases set in postsets
// Load runtime-linked libraries
RUNTIME_LINKED_LIBS.forEach(function(lib) {
@@ -1368,6 +1370,8 @@ function JSify(data, functionsOnly, givenFunctions) {
return IGNORED_FUNCTIONS.indexOf(func.ident) < 0;
})) + '\n');
+ PassManager.serialize();
+
return null;
}
diff --git a/src/library_gl.js b/src/library_gl.js
index b4098813..6927c3ec 100644
--- a/src/library_gl.js
+++ b/src/library_gl.js
@@ -1275,11 +1275,12 @@ var LibraryGL = {
getProcAddress: function(name) {
name = name.replace('EXT', '').replace('ARB', '');
// Do the translation carefully because of closure
+ var sig = '';
switch (name) {
- case 'glCreateShaderObject': case 'glCreateShader': func = _glCreateShader; break;
- case 'glCreateProgramObject': case 'glCreateProgram': func = _glCreateProgram; break;
- case 'glAttachObject': case 'glAttachShader': func = _glAttachShader; break;
- case 'glUseProgramObject': case 'glUseProgram': func = _glUseProgram; break;
+ case 'glCreateShaderObject': case 'glCreateShader': func = _glCreateShader; sig = 'ii'; break;
+ case 'glCreateProgramObject': case 'glCreateProgram': func = _glCreateProgram; sig = 'ii'; break;
+ case 'glAttachObject': case 'glAttachShader': func = _glAttachShader; sig = 'vi'; break;
+ case 'glUseProgramObject': case 'glUseProgram': func = _glUseProgram; sig = 'vi'; break;
case 'glDeleteObject': func = function(id) {
if (GL.programs[id]) {
_glDeleteProgram(id);
@@ -1288,7 +1289,7 @@ var LibraryGL = {
} else {
Module.printErr('WARNING: deleteObject received invalid id: ' + id);
}
- }; break;
+ }; sig = 'vi'; break;
case 'glGetObjectParameteriv': func = function(id, type, result) {
if (GL.programs[id]) {
if (type == 0x8B84) { // GL_OBJECT_INFO_LOG_LENGTH_ARB
@@ -1305,7 +1306,7 @@ var LibraryGL = {
} else {
Module.printErr('WARNING: getObjectParameteriv received invalid id: ' + id);
}
- }; break;
+ }; sig = 'viii'; break;
case 'glGetInfoLog': func = function(id, maxLength, length, infoLog) {
if (GL.programs[id]) {
_glGetProgramInfoLog(id, maxLength, length, infoLog);
@@ -1314,58 +1315,58 @@ var LibraryGL = {
} else {
Module.printErr('WARNING: getObjectParameteriv received invalid id: ' + id);
}
- }; break;
+ }; sig = 'viiii'; break;
case 'glBindProgram': func = function(type, id) {
assert(id == 0);
- }; break;
- case 'glDrawRangeElements': func = _glDrawRangeElements; break;
- case 'glShaderSource': func = _glShaderSource; break;
- case 'glCompileShader': func = _glCompileShader; break;
- case 'glLinkProgram': func = _glLinkProgram; break;
- case 'glGetUniformLocation': func = _glGetUniformLocation; break;
- case 'glUniform1f': func = _glUniform1f; break;
- case 'glUniform2f': func = _glUniform2f; break;
- case 'glUniform3f': func = _glUniform3f; break;
- case 'glUniform4f': func = _glUniform4f; break;
- case 'glUniform1fv': func = _glUniform1fv; break;
- case 'glUniform2fv': func = _glUniform2fv; break;
- case 'glUniform3fv': func = _glUniform3fv; break;
- case 'glUniform4fv': func = _glUniform4fv; break;
- case 'glUniform1i': func = _glUniform1i; break;
- case 'glUniform2i': func = _glUniform2i; break;
- case 'glUniform3i': func = _glUniform3i; break;
- case 'glUniform4i': func = _glUniform4i; break;
- case 'glUniform1iv': func = _glUniform1iv; break;
- case 'glUniform2iv': func = _glUniform2iv; break;
- case 'glUniform3iv': func = _glUniform3iv; break;
- case 'glUniform4iv': func = _glUniform4iv; break;
- case 'glBindAttribLocation': func = _glBindAttribLocation; break;
- case 'glGetActiveUniform': func = _glGetActiveUniform; break;
- case 'glGenBuffers': func = _glGenBuffers; break;
- case 'glBindBuffer': func = _glBindBuffer; break;
- case 'glBufferData': func = _glBufferData; break;
- case 'glBufferSubData': func = _glBufferSubData; break;
- case 'glDeleteBuffers': func = _glDeleteBuffers; break;
- case 'glActiveTexture': func = _glActiveTexture; break;
- case 'glClientActiveTexture': func = _glClientActiveTexture; break;
- case 'glGetProgramiv': func = _glGetProgramiv; break;
- case 'glEnableVertexAttribArray': func = _glEnableVertexAttribArray; break;
- case 'glDisableVertexAttribArray': func = _glDisableVertexAttribArray; break;
- case 'glVertexAttribPointer': func = _glVertexAttribPointer; break;
- case 'glBindRenderbuffer': func = _glBindRenderbuffer; break;
- case 'glDeleteRenderbuffers': func = _glDeleteRenderbuffers; break;
- case 'glGenRenderbuffers': func = _glGenRenderbuffers; break;
- case 'glCompressedTexImage2D': func = _glCompressedTexImage2D; break;
- case 'glCompressedTexSubImage2D': func = _glCompressedTexSubImage2D; break;
- case 'glBindFramebuffer': func = _glBindFramebuffer; break;
- case 'glGenFramebuffers': func = _glGenFramebuffers; break;
- case 'glDeleteFramebuffers': func = _glDeleteFramebuffers; break;
- case 'glFramebufferRenderbuffer': func = _glFramebufferRenderbuffer; break;
- case 'glFramebufferTexture2D': func = _glFramebufferTexture2D; break;
- case 'glGetFramebufferAttachmentParameteriv': func = _glGetFramebufferAttachmentParameteriv; break;
- case 'glIsFramebuffer': func = _glIsFramebuffer; break;
- case 'glCheckFramebufferStatus': func = _glCheckFramebufferStatus; break;
- case 'glRenderbufferStorage': func = _glRenderbufferStorage; break;
+ }; sig = 'vii'; break;
+ case 'glDrawRangeElements': func = _glDrawRangeElements; sig = 'viiiiii'; break;
+ case 'glShaderSource': func = _glShaderSource; sig = 'viiii'; break;
+ case 'glCompileShader': func = _glCompileShader; sig = 'vi'; break;
+ case 'glLinkProgram': func = _glLinkProgram; sig = 'vi'; break;
+ case 'glGetUniformLocation': func = _glGetUniformLocation; sig = 'iii'; break;
+ case 'glUniform1f': func = _glUniform1f; sig = 'vid'; break;
+ case 'glUniform2f': func = _glUniform2f; sig = 'vidd'; break;
+ case 'glUniform3f': func = _glUniform3f; sig = 'viddd'; break;
+ case 'glUniform4f': func = _glUniform4f; sig = 'vidddd'; break;
+ case 'glUniform1fv': func = _glUniform1fv; sig = 'viii'; break;
+ case 'glUniform2fv': func = _glUniform2fv; sig = 'viii'; break;
+ case 'glUniform3fv': func = _glUniform3fv; sig = 'viii'; break;
+ case 'glUniform4fv': func = _glUniform4fv; sig = 'viii'; break;
+ case 'glUniform1i': func = _glUniform1i; sig = 'vii'; break;
+ case 'glUniform2i': func = _glUniform2i; sig = 'viii'; break;
+ case 'glUniform3i': func = _glUniform3i; sig = 'viiii'; break;
+ case 'glUniform4i': func = _glUniform4i; sig = 'viiii'; break;
+ case 'glUniform1iv': func = _glUniform1iv; sig = 'viii'; break;
+ case 'glUniform2iv': func = _glUniform2iv; sig = 'viii'; break;
+ case 'glUniform3iv': func = _glUniform3iv; sig = 'viii'; break;
+ case 'glUniform4iv': func = _glUniform4iv; sig = 'viii'; break;
+ case 'glBindAttribLocation': func = _glBindAttribLocation; sig = 'viii'; break;
+ case 'glGetActiveUniform': func = _glGetActiveUniform; sig = 'viiiiiii'; break;
+ case 'glGenBuffers': func = _glGenBuffers; sig = 'iii'; break;
+ case 'glBindBuffer': func = _glBindBuffer; sig = 'vii'; break;
+ case 'glBufferData': func = _glBufferData; sig = 'viiii'; break;
+ case 'glBufferSubData': func = _glBufferSubData; sig = 'viiii'; break;
+ case 'glDeleteBuffers': func = _glDeleteBuffers; sig = 'vii'; break;
+ case 'glActiveTexture': func = _glActiveTexture; sig = 'vi'; break;
+ case 'glClientActiveTexture': func = _glClientActiveTexture; sig = 'vi'; break;
+ case 'glGetProgramiv': func = _glGetProgramiv; sig = 'viii'; break;
+ case 'glEnableVertexAttribArray': func = _glEnableVertexAttribArray; sig = 'vi'; break;
+ case 'glDisableVertexAttribArray': func = _glDisableVertexAttribArray; sig = 'vi'; break;
+ case 'glVertexAttribPointer': func = _glVertexAttribPointer; sig = 'viiiiii'; break;
+ case 'glBindRenderbuffer': func = _glBindRenderbuffer; sig = 'vii'; break;
+ case 'glDeleteRenderbuffers': func = _glDeleteRenderbuffers; sig = 'vii'; break;
+ case 'glGenRenderbuffers': func = _glGenRenderbuffers; sig = 'vii'; break;
+ case 'glCompressedTexImage2D': func = _glCompressedTexImage2D; sig = 'viiiiiiii'; break;
+ case 'glCompressedTexSubImage2D': func = _glCompressedTexSubImage2D; sig = 'viiiiiiiii'; break;
+ case 'glBindFramebuffer': func = _glBindFramebuffer; sig = 'vii'; break;
+ case 'glGenFramebuffers': func = _glGenFramebuffers; sig = 'vii'; break;
+ case 'glDeleteFramebuffers': func = _glDeleteFramebuffers; sig = 'vii'; break;
+ case 'glFramebufferRenderbuffer': func = _glFramebufferRenderbuffer; sig = 'viiii'; break;
+ case 'glFramebufferTexture2D': func = _glFramebufferTexture2D; sig = 'viiiii'; break;
+ case 'glGetFramebufferAttachmentParameteriv': func = _glGetFramebufferAttachmentParameteriv; sig = 'viiii'; break;
+ case 'glIsFramebuffer': func = _glIsFramebuffer; sig = 'ii'; break;
+ case 'glCheckFramebufferStatus': func = _glCheckFramebufferStatus; sig = 'ii'; break;
+ case 'glRenderbufferStorage': func = _glRenderbufferStorage; sig = 'viiii'; break;
default: {
Module.printErr('WARNING: getProcAddress failed for ' + name);
func = function() {
@@ -1374,7 +1375,7 @@ var LibraryGL = {
};
}
}
- return Runtime.addFunction(func);
+ return Runtime.addFunction(func, sig);
}
},
diff --git a/src/modules.js b/src/modules.js
index 94fe582c..2dc6c342 100644
--- a/src/modules.js
+++ b/src/modules.js
@@ -216,15 +216,23 @@ 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
+ libraryFunctions: {}, // functions added from the library. Maps id to 1, or to a signature if we need indexing
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++) {
+ sig += isIntImplemented(argTypes[i]) ? 'i' : 'f';
+ }
+ return sig;
+ },
+
// Mark a function as needing indexing. Python will coordinate them all
getIndex: function(ident) {
if (phase != 'post') {
@@ -243,25 +251,33 @@ var Functions = {
// Generate code for function indexing
generateIndexing: function() {
- var vals = zeros(this.nextIndex);
+ var tables = {};
for (var ident in this.indexedFunctions) {
- vals[this.indexedFunctions[ident]] = ident;
+ var sig = Functions.implementedFunctions[ident] || Functions.libraryFunctions[ident];
+ assert(sig);
+ if (!tables[sig]) tables[sig] = zeros(this.nextIndex); // 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 ret = '';
+ for (var t in tables) {
+ 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.
+ ret += 'FUNCTION_TABLE.push.apply(FUNCTION_TABLE_' + t + ', [' + indices + ']);\n';
+ } else {
+ ret += 'FUNCTION_TABLE_' + t + ' = [' + indices + '];\nModule["FUNCTION_TABLE_' + t + '"] = FUNCTION_TABLE_' + t + ';\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;';
- }
+ Functions.tables = ret;
}
};
@@ -320,9 +336,15 @@ var PassManager = {
Functions: {
blockAddresses: Functions.blockAddresses,
indexedFunctions: Functions.indexedFunctions,
- implementedFunctions: ASM_JS ? Functions.implementedFunctions : []
+ implementedFunctions: ASM_JS ? Functions.implementedFunctions : [],
+ libraryFunctions: ASM_JS ? Functions.libraryFunctions : {},
}
}));
+ } else if (phase == 'post') {
+printErr('forward post!');
+ print('\n//FORWARDED_DATA:' + JSON.stringify({
+ Functions: { tables: Functions.tables }
+ }));
}
},
load: function(json) {
diff --git a/src/parseTools.js b/src/parseTools.js
index 4a76a9a2..080ef6fd 100644
--- a/src/parseTools.js
+++ b/src/parseTools.js
@@ -163,11 +163,13 @@ function isFunctionDef(token, out) {
var subtext = segment[0].text;
fail = fail || segment.length > 1 || !(isType(subtext) || subtext == '...');
});
- if (out) out.numArgs = segments.length;
+ if (out) {
+ out.segments = segments;
+ out.numArgs = segments.length;
+ }
return !fail;
}
-
function isPossiblyFunctionType(type) {
// A quick but unreliable way to see if something is a function type. Yes is just 'maybe', no is definite.
var len = type.length;
@@ -189,6 +191,7 @@ function isFunctionType(type, out) {
if (pointingLevels(type) !== 1) return false;
var text = removeAllPointing(parts.slice(1).join(' '));
if (!text) return false;
+ if (out) out.returnType = parts[0];
return isType(parts[0]) && isFunctionDef({ text: text, item: tokenize(text.substr(1, text.length-2), true) }, out);
}
@@ -1000,7 +1003,13 @@ function makeGetValue(ptr, pos, type, noNeedFirst, unsigned, ignore, align, noSa
function indexizeFunctions(value, type) {
assert((type && type !== '?') || (typeof value === 'string' && value.substr(0, 6) === 'CHECK_'), 'No type given for function indexizing');
assert(value !== type, 'Type set to value');
- if (type && isFunctionType(type) && value[0] === '_') { // checking for _ differentiates from $ (local vars)
+ var out = {};
+ if (type && isFunctionType(type, out) && value[0] === '_') { // checking for _ differentiates from $ (local vars)
+ // add signature to library functions that we now know need indexing
+ if (!(value in Functions.implementedFunctions) && !(value in Functions.libraryFunctions)) {
+ Functions.libraryFunctions[value] = Functions.getSignature(out.returnType, out.segments ? out.segments.map(function(segment) { return segment[0].text }) : []);
+ }
+
if (BUILD_AS_SHARED_LIB) {
return '(FUNCTION_TABLE_OFFSET + ' + Functions.getIndex(value) + ')';
} else {
diff --git a/src/preamble.js b/src/preamble.js
index 9342bf2b..931c8f51 100644
--- a/src/preamble.js
+++ b/src/preamble.js
@@ -575,9 +575,6 @@ Module['Array_stringify'] = Array_stringify;
// Memory management
-var FUNCTION_TABLE; // XXX: In theory the indexes here can be equal to pointers to stacked or malloced memory. Such comparisons should
- // be false, but can turn out true. We should probably set the top bit to prevent such issues.
-
var PAGE_SIZE = 4096;
function alignMemoryPage(x) {
return ((x+4095)>>12)<<12;
@@ -735,7 +732,7 @@ function callRuntimeCallbacks(callbacks) {
var callback = callbacks.shift();
var func = callback.func;
if (typeof func === 'number') {
- func = FUNCTION_TABLE[func];
+ func = FUNCTION_TABLE_v[func]; // void()
}
func(callback.arg === undefined ? null : callback.arg);
}
diff --git a/src/runtime.js b/src/runtime.js
index dd14e779..8c1fbd65 100644
--- a/src/runtime.js
+++ b/src/runtime.js
@@ -311,10 +311,16 @@ var Runtime = {
return ret;
},
- addFunction: function(func) {
- var ret = FUNCTION_TABLE.length;
- FUNCTION_TABLE.push(func);
- FUNCTION_TABLE.push(0);
+ getFunctionTable: function(sig) { // return value, param types e.g. "vid" void (int, double)
+ return Module['FUNCTION_TABLE_' + sig];
+ },
+
+ addFunction: function(func, sig) {
+ assert(sig);
+ var table = Runtime.getFunctionTable(sig);
+ var ret = table.length;
+ table.push(func);
+ table.push(0);
return ret;
},
@@ -328,10 +334,12 @@ var Runtime = {
funcWrappers: {},
- getFuncWrapper: function(func) {
+ getFuncWrapper: function(func, sig) {
+ assert(sig);
+ var table = Runtime.getFunctionTable(sig);
if (!Runtime.funcWrappers[func]) {
Runtime.funcWrappers[func] = function() {
- FUNCTION_TABLE[func].apply(null, arguments);
+ table[func].apply(null, arguments);
};
}
return Runtime.funcWrappers[func];
diff --git a/tests/runner.py b/tests/runner.py
index 102fc470..44d833cd 100755
--- a/tests/runner.py
+++ b/tests/runner.py
@@ -7489,7 +7489,7 @@ TT = %s
exec('o2 = make_run("o2", compiler=CLANG, emcc_args=["-O2", "--closure", "0"])')
# asm.js
- exec('asm = make_run("asm", compiler=CLANG, emcc_args=["-O2", "--closure", "0", "-s", "ASM_JS=1"])')
+ exec('asm = make_run("asm", compiler=CLANG, emcc_args=["-O0", "--closure", "0", "-s", "ASM_JS=1"])')
# Make custom runs with various options
for compiler, quantum, embetter, typed_arrays, llvm_opts in [