diff options
Diffstat (limited to 'src/jsifier.js')
-rw-r--r-- | src/jsifier.js | 72 |
1 files changed, 52 insertions, 20 deletions
diff --git a/src/jsifier.js b/src/jsifier.js index ff58ece2..4263618a 100644 --- a/src/jsifier.js +++ b/src/jsifier.js @@ -397,6 +397,20 @@ function JSify(data, functionsOnly, givenFunctions) { } }); + function processLibraryFunction(snippet, ident) { + snippet = snippet.toString(); + assert(snippet.indexOf('XXX missing C define') == -1, + 'Trying to include a library function with missing C defines: ' + ident + ' | ' + snippet); + + // name the function; overwrite if it's already named + snippet = snippet.replace(/function(?:\s+([^(]+))?\s*\(/, 'function _' + ident + '('); + if (LIBRARY_DEBUG) { + 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; \n}'; + } + return snippet; + } + // functionStub substrate.addActor('FunctionStub', { processItem: function(item) { @@ -434,16 +448,7 @@ function JSify(data, functionsOnly, givenFunctions) { snippet = stringifyWithFunctions(snippet); } else if (typeof snippet === 'function') { isFunction = true; - snippet = snippet.toString(); - assert(snippet.indexOf('XXX missing C define') == -1, - 'Trying to include a library function with missing C defines: ' + ident + ' | ' + snippet); - - // name the function; overwrite if it's already named - snippet = snippet.replace(/function(?:\s+([^(]+))?\s*\(/, 'function _' + ident + '('); - if (LIBRARY_DEBUG) { - 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; \n}'; - } + snippet = processLibraryFunction(snippet, ident); if (ASM_JS) Functions.libraryFunctions[ident] = 1; } @@ -600,6 +605,10 @@ function JSify(data, functionsOnly, givenFunctions) { func.JS += 'function ' + func.ident + '(' + paramIdents.join(', ') + ') {\n'; + if (PGO) { + func.JS += ' PGOMonitor.called["' + func.ident + '"] = 1;\n'; + } + if (ASM_JS) { // spell out argument types func.params.forEach(function(param) { @@ -731,7 +740,7 @@ function JSify(data, functionsOnly, givenFunctions) { return indent + ' case ' + getLabelId(label.ident) + ': ' + (SHOW_LABELS ? '// ' + getOriginalLabelId(label.ident) : '') + '\n' + getLabelLines(label, indent + ' '); }).join('\n') + '\n'; - if (ASSERTIONS) ret += indent + ' default: assert(0, "bad label: " + label);\n'; + if (ASSERTIONS) ret += indent + ' default: assert(0' + (ASM_JS ? '' : ', "bad label: " + label') + ');\n'; ret += indent + '}\n'; if (func.setjmpTable) { ret += ' } catch(e) { if (!e.longjmp || !(e.id in mySetjmpIds)) throw(e); setjmpTable[setjmpLabels[e.id]](e.value) }'; @@ -1312,6 +1321,8 @@ function JSify(data, functionsOnly, givenFunctions) { } else { callIdent = ident; } + if (callIdent == '0') return 'abort(-2)'; + var args = []; var argsTypes = []; var varargs = []; @@ -1414,6 +1425,12 @@ function JSify(data, functionsOnly, givenFunctions) { returnType = getReturnType(type); } + if (callIdent in DEAD_FUNCTIONS) { + var ret = 'abort(' + DEAD_FUNCTIONS[callIdent] + ')'; + if (ASM_JS) ret = asmCoercion(ret, returnType); + return ret; + } + if (byPointer) { var sig = Functions.getSignature(returnType, argsTypes, hasVarArgs); if (ASM_JS) { @@ -1443,7 +1460,7 @@ function JSify(data, functionsOnly, givenFunctions) { makeFuncLineActor('unreachable', function(item) { if (ASSERTIONS) { - return 'throw "Reached an unreachable!"'; + return ASM_JS ? 'abort()' : 'throw "Reached an unreachable!"'; } else { return ';'; } @@ -1552,16 +1569,25 @@ function JSify(data, functionsOnly, givenFunctions) { // This is the main 'post' pass. Print out the generated code that we have here, together with the // rest of the output that we started to print out earlier (see comment on the // "Final shape that will be created"). - if (CORRUPTION_CHECK) { - assert(!ASM_JS); // cannot monkeypatch asm! - print(processMacros(read('corruptionCheck.js'))); - } if (PRECISE_I64_MATH && Types.preciseI64MathUsed) { + if (!INCLUDE_FULL_LIBRARY) { + ['i64Add', 'bitshift64Shl', 'bitshift64Lshr', 'bitshift64Ashr'].forEach(function(func) { + print(processLibraryFunction(LibraryManager.library[func], func)); // must be first to be close to generated code + Functions.implementedFunctions['_' + func] = LibraryManager.library[func + '__sig']; + }); + } + print('// EMSCRIPTEN_END_FUNCS\n'); print(read('long.js')); } else { + print('// EMSCRIPTEN_END_FUNCS\n'); print('// Warning: printing of i64 values may be slightly rounded! No deep i64 math used, so precise i64 code not included'); print('var i64Math = null;'); } + + if (CORRUPTION_CHECK) { + assert(!ASM_JS); // cannot monkeypatch asm! + print(processMacros(read('corruptionCheck.js'))); + } if (HEADLESS) { print('if (!ENVIRONMENT_IS_WEB) {'); print(read('headless.js').replace("'%s'", "'http://emscripten.org'").replace("'?%s'", "''").replace('%s,', 'null,').replace('%d', '0')); @@ -1587,11 +1613,17 @@ function JSify(data, functionsOnly, givenFunctions) { var shellParts = read(shellFile).split('{{BODY}}'); print(shellParts[1]); - // Print out some useful metadata (for additional optimizations later, like the eliminator) - if (EMIT_GENERATED_FUNCTIONS) { - print('// EMSCRIPTEN_GENERATED_FUNCTIONS: ' + JSON.stringify(keys(Functions.implementedFunctions).filter(function(func) { + // Print out some useful metadata + if (EMIT_GENERATED_FUNCTIONS || PGO) { + var generatedFunctions = JSON.stringify(keys(Functions.implementedFunctions).filter(function(func) { return IGNORED_FUNCTIONS.indexOf(func.ident) < 0; - })) + '\n'); + })); + if (PGO) { + print('PGOMonitor.allGenerated = ' + generatedFunctions + ';\nremoveRunDependency("pgo");\n'); + } + if (EMIT_GENERATED_FUNCTIONS) { + print('// EMSCRIPTEN_GENERATED_FUNCTIONS: ' + generatedFunctions + '\n'); + } } PassManager.serialize(); |