diff options
Diffstat (limited to 'src/jsifier.js')
-rw-r--r-- | src/jsifier.js | 65 |
1 files changed, 47 insertions, 18 deletions
diff --git a/src/jsifier.js b/src/jsifier.js index 23fbb4c5..926be71a 100644 --- a/src/jsifier.js +++ b/src/jsifier.js @@ -108,7 +108,7 @@ function JSify(data, functionsOnly, givenFunctions) { } }); - if (phase == 'funcs') { // pre has function shells, just to defined implementedFunctions + if (phase == 'funcs') { // || phase == 'pre') { // pre has function shells, just to defined implementedFunctions var MAX_BATCH_FUNC_LINES = 1000; while (data.unparsedFunctions.length > 0) { var currFuncLines = []; @@ -468,7 +468,7 @@ function JSify(data, functionsOnly, givenFunctions) { asmLibraryFunctions.push(contentText); contentText = ' '; EXPORTED_FUNCTIONS[ident] = 1; - delete Functions.libraryFunctions[ident.substr(1)]; + Functions.libraryFunctions[ident.substr(1)] = 2; } } if ((!ASM_JS || phase == 'pre') && @@ -1149,20 +1149,21 @@ function JSify(data, functionsOnly, givenFunctions) { } // If there is no current exception, set this one as it (during a resume, the current exception can be wiped out) var ptr = makeStructuralAccess(item.ident, 0); - return (EXCEPTION_DEBUG ? 'Module.print("Resuming exception");' : '') + - 'if (' + makeGetValue('_llvm_eh_exception.buf', 0, 'void*') + ' == 0) { ' + makeSetValue('_llvm_eh_exception.buf', 0, ptr, 'void*') + ' } ' + - makeThrow(ptr) + ';'; + return '___resumeException(' + asmCoercion(ptr, 'i32') + ')'; }); makeFuncLineActor('invoke', function(item) { // Wrapping in a function lets us easily return values if we are // in an assignment + var disabled = DISABLE_EXCEPTION_CATCHING == 2 && !(item.funcData.ident in EXCEPTION_CATCHING_WHITELIST); var phiSets = calcPhiSets(item); - var call_ = makeFunctionCall(item.ident, item.params, item.funcData, item.type); - + var call_ = makeFunctionCall(item.ident, item.params, item.funcData, item.type, ASM_JS && !disabled); + var ret; - if (DISABLE_EXCEPTION_CATCHING == 2 && !(item.funcData.ident in EXCEPTION_CATCHING_WHITELIST)) { + if (disabled) { ret = call_ + ';'; + } else if (ASM_JS) { + ret = '(__THREW__ = 0,' + call_ + ');'; } else { ret = '(function() { try { __THREW__ = 0; return ' + call_ + ' ' @@ -1173,7 +1174,6 @@ function JSify(data, functionsOnly, givenFunctions) { + 'return null } })();'; } - if (item.assignTo) { ret = 'var ' + item.assignTo + ' = ' + ret; if (USE_TYPED_ARRAYS == 2 && isIllegalType(item.type)) { @@ -1210,8 +1210,8 @@ function JSify(data, functionsOnly, givenFunctions) { } }); makeFuncLineActor('landingpad', function(item) { - var catchTypeArray = item.catchables.map(finalizeLLVMParameter).join(','); - var ret = '___cxa_find_matching_catch('+ makeGetValue('_llvm_eh_exception.buf', '0', 'void*') +',' + makeGetValue('_llvm_eh_exception.buf', QUANTUM_SIZE, 'void*') + ',[' + catchTypeArray +'])'; + var catchTypeArray = item.catchables.map(finalizeLLVMParameter).map(function(element) { return asmCoercion(element, 'i32') }).join(','); + var ret = asmCoercion('___cxa_find_matching_catch(-1, -1' + (catchTypeArray.length > 0 ? ',' + catchTypeArray : '') +')', 'i32'); if (USE_TYPED_ARRAYS == 2) { ret = makeVarDef(item.assignTo) + '$0 = ' + ret + '; ' + item.assignTo + '$1 = tempRet0;'; item.assignTo = null; @@ -1291,7 +1291,7 @@ function JSify(data, functionsOnly, givenFunctions) { return ret; }); - function makeFunctionCall(ident, params, funcData, type) { + function makeFunctionCall(ident, params, funcData, type, forceByPointer) { // We cannot compile assembly. See comment in intertyper.js:'Call' assert(ident != 'asm', 'Inline assembly cannot be compiled to JavaScript!'); @@ -1319,6 +1319,11 @@ function JSify(data, functionsOnly, givenFunctions) { var hasVarArgs = isVarArgsFunctionType(type); var normalArgs = (hasVarArgs && !useJSArgs) ? countNormalArgs(type) : -1; var byPointer = getVarData(funcData, ident); + var byPointerForced = false; + + if (forceByPointer && !byPointer) { + byPointer = byPointerForced = true; + } params.forEach(function(param, i) { var val = finalizeParam(param); @@ -1343,7 +1348,7 @@ function JSify(data, functionsOnly, givenFunctions) { args = args.map(function(arg, i) { return indexizeFunctions(arg, argsTypes[i]) }); if (ASM_JS) { - if (shortident in Functions.libraryFunctions || simpleIdent in Functions.libraryFunctions) { + if (shortident in Functions.libraryFunctions || simpleIdent in Functions.libraryFunctions || byPointerForced) { args = args.map(function(arg, i) { return asmCoercion(arg, argsTypes[i]) }); } else { args = args.map(function(arg, i) { return asmEnsureFloat(arg, argsTypes[i]) }); @@ -1421,12 +1426,20 @@ function JSify(data, functionsOnly, givenFunctions) { var sig = Functions.getSignature(returnType, argsTypes, hasVarArgs); if (ASM_JS) { assert(returnType.search(/\("'\[,/) == -1); // XXX need isFunctionType(type, out) - callIdent = '(' + callIdent + ')&{{{ FTM_' + sig + ' }}}'; // the function table mask is set in emscripten.py + if (!byPointerForced) { + callIdent = '(' + callIdent + ')&{{{ FTM_' + sig + ' }}}'; // the function table mask is set in emscripten.py + } else { + // This is a forced call, through an invoke_*. + // note: no need to update argsTypes at this point + Functions.unimplementedFunctions[callIdent] = sig; + args.unshift(byPointerForced ? Functions.getIndex(callIdent) : callIdent); + callIdent = 'invoke_' + sig; + } } else if (SAFE_DYNCALLS) { assert(!ASM_JS, 'cannot emit safe dyncalls in asm'); callIdent = '(tempInt=' + callIdent + ',tempInt < 0 || tempInt >= FUNCTION_TABLE.length-1 || !FUNCTION_TABLE[tempInt] ? abort("dyncall error: ' + sig + ' " + FUNCTION_TABLE_NAMES[tempInt]) : tempInt)'; } - callIdent = Functions.getTable(sig) + '[' + callIdent + ']'; + if (!byPointerForced) callIdent = Functions.getTable(sig) + '[' + callIdent + ']'; } var ret = callIdent + '(' + args.join(', ') + ')'; @@ -1593,10 +1606,26 @@ function JSify(data, functionsOnly, givenFunctions) { // "Final shape that will be created"). 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']; + // first row are utilities called from generated code, second are needed from fastLong + ['i64Add', 'i64Subtract', 'bitshift64Shl', 'bitshift64Lshr', 'bitshift64Ashr', + 'llvm_ctlz_i32', 'llvm_cttz_i32'].forEach(function(func) { + if (!Functions.libraryFunctions[func]) { + print(processLibraryFunction(LibraryManager.library[func], func)); // must be first to be close to generated code + Functions.implementedFunctions['_' + func] = LibraryManager.library[func + '__sig']; + Functions.libraryFunctions[func] = 1; + // limited dependency handling + var deps = LibraryManager.library[func + '__deps']; + if (deps) { + deps.forEach(function(dep) { + assert(typeof dep == 'function'); + var text = dep(); + assert(text.indexOf('\n') < 0); + print('/* PRE_ASM */ ' + text + '\n'); + }); + } + } }); + print(read('fastLong.js')); } print('// EMSCRIPTEN_END_FUNCS\n'); print(read('long.js')); |