aboutsummaryrefslogtreecommitdiff
path: root/src/jsifier.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/jsifier.js')
-rw-r--r--src/jsifier.js72
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();