diff options
91 files changed, 32720 insertions, 78816 deletions
@@ -441,6 +441,10 @@ Options that are modified or new in %s include: (also a global property) does not invalidate everything. + Note that you must add -g during the linking + stage (bitcode to JS), for jcache to work + (otherwise, JS minification can confuse it). + --clear-cache Manually clears the cache of compiled emscripten system libraries (libc++, libc++abi, libc). This is normally @@ -557,6 +561,7 @@ if CONFIGURE_CONFIG or CMAKE_CONFIG: cmd = [compiler] + list(filter_emscripten_options(sys.argv[1:])) if not use_js: cmd += shared.EMSDK_OPTS + ['-DEMSCRIPTEN'] + if use_js: cmd += ['-s', 'ERROR_ON_UNDEFINED_SYMBOLS=1'] # configure tests should fail when an undefined symbol exists if DEBUG: print >> sys.stderr, 'emcc, just configuring: ', ' '.join(cmd) if debug_configure: open(tempout, 'a').write('emcc, just configuring: ' + ' '.join(cmd) + '\n\n') @@ -1029,9 +1034,24 @@ try: print >> sys.stderr, 'emcc: warning: disabling closure because debug info was requested' closure = False + if jcache: + assert keep_js_debug, 'must run jcache with -g during link stage' # js minification can confuse jcache + if minify_whitespace is None: minify_whitespace = opt_level >= 2 and not keep_js_debug + assert shared.LLVM_TARGET in shared.COMPILER_OPTS + if shared.LLVM_TARGET == 'i386-pc-linux-gnu': + shared.Settings.TARGET_X86 = 1 + shared.Settings.TARGET_LE32 = 0 + assert 'le32-unknown-nacl' not in shared.COMPILER_OPTS + elif shared.LLVM_TARGET == 'le32-unknown-nacl': + shared.Settings.TARGET_LE32 = 1 + shared.Settings.TARGET_X86 = 0 + assert 'i386-pc-linux-gnu' not in shared.COMPILER_OPTS + else: + raise Exception('unknown llvm target: ' + str(shared.LLVM_TARGET)) + ## Compile source code to bitcode if DEBUG: print >> sys.stderr, 'emcc: compiling to bitcode' diff --git a/emconfigure b/emconfigure index 51e57c64..ce98af22 100755 --- a/emconfigure +++ b/emconfigure @@ -18,6 +18,10 @@ Relevant defines: import os, sys from tools import shared +from subprocess import CalledProcessError -shared.Building.configure(sys.argv[1:]) +try: + shared.Building.configure(sys.argv[1:]) +except CalledProcessError, e: + sys.exit(e.returncode) @@ -20,6 +20,10 @@ generate JavaScript. import os, sys from tools import shared +from subprocess import CalledProcessError -shared.Building.make(sys.argv[1:]) +try: + shared.Building.make(sys.argv[1:]) +except CalledProcessError, e: + sys.exit(e.returncode) diff --git a/emscripten.py b/emscripten.py index 6c758942..f4bfed82 100755 --- a/emscripten.py +++ b/emscripten.py @@ -529,7 +529,7 @@ var asm = (function(global, env, buffer) { var ret = 0; ret = STACKTOP; STACKTOP = (STACKTOP + size)|0; - STACKTOP = ((STACKTOP + 3)>>2)<<2; +''' + ('STACKTOP = ((STACKTOP + 3)>>2)<<2;' if settings['TARGET_X86'] else 'STACKTOP = ((STACKTOP + 7)>>3)<<3;') + ''' return ret|0; } function stackSave() { diff --git a/src/analyzer.js b/src/analyzer.js index 7fbdf24d..03d44cb7 100644 --- a/src/analyzer.js +++ b/src/analyzer.js @@ -469,6 +469,23 @@ function analyzer(data, sidePass) { i++; continue; // special case, handled in makeComparison } + case 'va_arg': { + assert(value.type == 'i64'); + assert(value.value.type == 'i32*', value.value.type); + i += removeAndAdd(label.lines, i, range(2).map(function(x) { + return { + intertype: 'va_arg', + assignTo: value.assignTo + '$' + x, + type: 'i32', + value: { + intertype: 'value', + ident: value.value.ident, // We read twice from the same i32* var, incrementing // + '$' + x, + type: 'i32*' + } + }; + })); + continue; + } case 'extractvalue': { // XXX we assume 32-bit alignment in extractvalue/insertvalue, // but in theory they can run on packed structs too (see use getStructuralTypePartBits) // potentially legalize the actual extracted value too if it is >32 bits, not just the extraction in general @@ -1492,7 +1509,7 @@ function analyzer(data, sidePass) { calcAllocatedSize(item.allocatedType)*item.allocatedNum: 0; if (USE_TYPED_ARRAYS === 2) { // We need to keep the stack aligned - item.allocatedSize = Runtime.forceAlign(item.allocatedSize, QUANTUM_SIZE); + item.allocatedSize = Runtime.forceAlign(item.allocatedSize, Runtime.STACK_ALIGN); } } var index = 0; diff --git a/src/corruptionCheck.js b/src/corruptionCheck.js index 315f5cf0..8b37120a 100644 --- a/src/corruptionCheck.js +++ b/src/corruptionCheck.js @@ -42,7 +42,7 @@ var CorruptionChecker = { CorruptionChecker.checkAll(); var size = CorruptionChecker.ptrs[ptr]; //Module.printErr('free ' + ptr + ' of size ' + size); - assert(size); + assert(size, ptr); var allocation = ptr - size*CorruptionChecker.BUFFER_FACTOR; //Module.printErr('free ' + ptr + ' of size ' + size + ' and allocation ' + allocation); delete CorruptionChecker.ptrs[ptr]; @@ -67,12 +67,12 @@ var CorruptionChecker = { }, fillBuffer: function(buffer, size) { for (var x = buffer; x < buffer + size; x++) { - {{{ makeSetValue('x', 0, 'CorruptionChecker.canary(x)', 'i8') }}}; + {{{ makeSetValue('x', 0, 'CorruptionChecker.canary(x)', 'i8', null, null, null, 1) }}}; } }, checkBuffer: function(buffer, size) { for (var x = buffer; x < buffer + size; x++) { - if (({{{ makeGetValue('x', 0, 'i8') }}}&255) != CorruptionChecker.canary(x)) { + if (({{{ makeGetValue('x', 0, 'i8', null, null, null, null, 1) }}}&255) != CorruptionChecker.canary(x)) { assert(0, 'Heap corruption detected!' + [x, buffer, size, {{{ makeGetValue('x', 0, 'i8') }}}&255, CorruptionChecker.canary(x)]); } } diff --git a/src/intertyper.js b/src/intertyper.js index 57e3011d..445c37f4 100644 --- a/src/intertyper.js +++ b/src/intertyper.js @@ -336,6 +336,8 @@ function intertyper(data, sidePass, baseLineNums) { return 'InsertValue'; if (tokensLength >= 3 && token0Text == 'phi') return 'Phi'; + if (tokensLength >= 3 && token0Text == 'va_arg') + return 'va_arg'; if (tokensLength >= 3 && token0Text == 'landingpad') return 'Landingpad'; if (token0Text == 'fence') @@ -817,6 +819,16 @@ function intertyper(data, sidePass, baseLineNums) { this.forwardItem(item, 'Reintegrator'); } }); + // 'phi' + substrate.addActor('va_arg', { + processItem: function(item) { + item.intertype = 'va_arg'; + var segments = splitTokenList(item.tokens.slice(1)); + item.type = segments[1][0].text; + item.value = parseLLVMSegment(segments[0]); + this.forwardItem(item, 'Reintegrator'); + } + }); // mathops substrate.addActor('Mathops', { processItem: function(item) { diff --git a/src/jsifier.js b/src/jsifier.js index 5fcf6b18..9207f65d 100644 --- a/src/jsifier.js +++ b/src/jsifier.js @@ -1295,6 +1295,14 @@ function JSify(data, functionsOnly, givenFunctions) { return RuntimeGenerator.stackAlloc(getFastValue(calcAllocatedSize(item.allocatedType), '*', item.allocatedNum)); } }); + makeFuncLineActor('va_arg', function(item) { + assert(TARGET_LE32); + var ident = item.value.ident; + var move = Runtime.STACK_ALIGN; + return '(tempInt=' + makeGetValue(ident, 4, '*') + ',' + + makeSetValue(ident, 4, 'tempInt + ' + move, '*') + ',' + + makeGetValue(makeGetValue(ident, 0, '*'), 'tempInt', item.type) + ')'; + }); makeFuncLineActor('mathop', processMathop); @@ -1318,16 +1326,21 @@ function JSify(data, functionsOnly, givenFunctions) { ident = Variables.resolveAliasToIdent(ident); var shortident = ident.slice(1); var simpleIdent = shortident; - var callIdent = LibraryManager.getRootIdent(simpleIdent); - if (callIdent) { - simpleIdent = callIdent; // ident may not be in library, if all there is is ident__inline, but in this case it is - if (callIdent.indexOf('.') < 0) { - callIdent = '_' + callIdent; // Not Math.*, so add the normal prefix - } + if (isLocalVar(ident)) { + var callIdent = ident; } else { - callIdent = ident; + // Not a local var, check if in library + var callIdent = LibraryManager.getRootIdent(simpleIdent); + if (callIdent) { + simpleIdent = callIdent; // ident may not be in library, if all there is is ident__inline, but in this case it is + if (callIdent.indexOf('.') < 0) { + callIdent = '_' + callIdent; // Not Math.*, so add the normal prefix + } + } else { + callIdent = ident; + } + if (callIdent == '0') return 'abort(-2)'; } - if (callIdent == '0') return 'abort(-2)'; var args = []; var argsTypes = []; @@ -1358,6 +1371,7 @@ function JSify(data, functionsOnly, givenFunctions) { } else { size = Runtime.getNativeFieldSize(param.type); } + size = Runtime.alignMemory(size, Runtime.STACK_ALIGN); varargs.push(val); varargs = varargs.concat(zeros(size-1)); // TODO: replace concats like this with push @@ -1391,15 +1405,14 @@ function JSify(data, functionsOnly, givenFunctions) { var type = varargsTypes[i]; if (type == 0) return null; var ret; + assert(offset % Runtime.STACK_ALIGN == 0); // varargs must be aligned if (!varargsByVals[i]) { ret = makeSetValue(getFastValue('tempInt', '+', offset), 0, arg, type, null, null, QUANTUM_SIZE, null, ','); - offset += Runtime.getNativeFieldSize(type); + offset += Runtime.alignMemory(Runtime.getNativeFieldSize(type), Runtime.STACK_ALIGN); } else { - assert(offset % 4 == 0); // varargs must be aligned var size = calcAllocatedSize(removeAllPointing(type)); - assert(size % 4 == 0); // varargs must stay aligned |