diff options
author | Alon Zakai <alonzakai@gmail.com> | 2013-01-11 16:17:16 -0800 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2013-01-11 16:17:16 -0800 |
commit | c47f7eba9be951c8e308e66c2541091c6b057af8 (patch) | |
tree | 59aed1cd174e91921e867955507c13f63303f40e | |
parent | ada59f0a9d23d8ec19ee6a1326977ddf6e93f5f9 (diff) | |
parent | 2113958017b5def518bd4bcf0bf77e8be233a93f (diff) |
Merge branch 'incoming'
73 files changed, 3502 insertions, 4422 deletions
@@ -2,7 +2,11 @@ *.pyc *~ *.bc +src/relooper*.js # Ignore generated files src/relooper.js src/relooper.js.raw.js +src/relooper/*.o +src/relooper/*.out + @@ -43,4 +43,5 @@ a license to everyone to use it as detailed in LICENSE.) * Xuejie Xiao <xxuejie@gmail.com> * Dominic Wong <dom@slowbunyip.org> * Alan Kligman <alan.kligman@gmail.com> (copyright owned by Mozilla Foundation) +* Anthony Liot <wolfviking0@yahoo.com> @@ -90,12 +90,14 @@ LLVM_OPT_LEVEL = { 3: 3, } +MEMCPY_ALIASES = ['memcpy', 'llvm.memcpy.i32', 'llvm.memcpy.i64', 'llvm.memcpy.p0i8.p0i8.i32', 'llvm.memcpy.p0i8.p0i8.i64'] + DEBUG = int(os.environ.get('EMCC_DEBUG') or 0) TEMP_DIR = os.environ.get('EMCC_TEMP_DIR') LEAVE_INPUTS_RAW = os.environ.get('EMCC_LEAVE_INPUTS_RAW') # Do not compile .ll files into .bc, just compile them with emscripten directly # Not recommended, this is mainly for the test runner, or if you have some other # specific need. - # One major limitation with this mode is that dlmalloc and libc++ cannot be + # One major limitation with this mode is that libc and libc++ cannot be # added in. Also, LLVM optimizations will not be done, nor dead code elimination AUTODEBUG = os.environ.get('EMCC_AUTODEBUG') # If set to 1, we will run the autodebugger (the automatic debugging tool, see tools/autodebugger). # Note that this will disable inclusion of libraries. This is useful because including @@ -338,7 +340,7 @@ Options that are modified or new in %s include: --clear-cache Manually clears the cache of compiled emscripten system libraries (libc++, - libc++abi, dlmalloc). This is normally + libc++abi, libc). This is normally handled automatically, but if you update llvm in-place (instead of having a different directory for a new version), the caching @@ -353,9 +355,9 @@ Options that are modified or new in %s include: The target file, if specified (-o <target>), defines what will be generated: - <name>.js JavaScript (default) + <name>.js JavaScript <name>.html HTML with embedded JavaScript - <name>.bc LLVM bitcode + <name>.bc LLVM bitcode (default) <name>.o LLVM bitcode (same as .bc) The -c option (which tells gcc not to run the linker) will @@ -718,8 +720,6 @@ try: if llvm_opts is None: llvm_opts = LLVM_OPT_LEVEL[opt_level] if llvm_lto is None: llvm_lto = llvm_opts > 0 if closure is None: closure = 1 if opt_level >= 2 else 0 - if minify_whitespace is None: - minify_whitespace = closure # if closure is run, minify whitespace if opt_level <= 0: keep_debug = True # always keep debug in -O0 if DEBUG: start_time = time.time() # done after parsing arguments, which might affect debug state @@ -848,9 +848,23 @@ try: exec('shared.Settings.' + key + ' = ' + value) # Apply effects from settings + if shared.Settings.ASM_JS: + if closure: + print >> sys.stderr, 'emcc: warning: disabling closure because it is not compatible with asm.js code generation' + closure = False + if shared.Settings.CORRECT_SIGNS != 1: + print >> sys.stderr, 'emcc: warning: setting CORRECT_SIGNS to 1 for asm.js code generation' + shared.Settings.CORRECT_SIGNS = 1 + if shared.Settings.CORRECT_OVERFLOWS != 1: + print >> sys.stderr, 'emcc: warning: setting CORRECT_OVERFLOWS to 1 for asm.js code generation' + shared.Settings.CORRECT_OVERFLOWS = 1 + if shared.Settings.CORRECT_SIGNS >= 2 or shared.Settings.CORRECT_OVERFLOWS >= 2 or shared.Settings.CORRECT_ROUNDINGS >= 2: keep_debug = True # must keep debug info to do line-by-line operations + if minify_whitespace is None: + minify_whitespace = closure # if closure is run, minify whitespace + ## Compile source code to bitcode if DEBUG: print >> sys.stderr, 'emcc: compiling to bitcode' @@ -922,16 +936,26 @@ try: # Note that we assume a single symbol is enough to know if we have/do not have dlmalloc etc. If you # include just a few symbols but want the rest, this will not work. - # dlmalloc - def create_dlmalloc(): - if DEBUG: print >> sys.stderr, 'emcc: building dlmalloc for cache' - execute([shared.PYTHON, shared.EMCC, shared.path_from_root('system', 'lib', 'dlmalloc.c'), '-g', '-o', in_temp('dlmalloc.o')], stdout=stdout, stderr=stderr) - # we include the libc++ new stuff here, so that the common case of using just new/delete is quick to link - execute([shared.PYTHON, shared.EMXX, shared.path_from_root('system', 'lib', 'libcxx', 'new.cpp'), '-g', '-o', in_temp('new.o')], stdout=stdout, stderr=stderr) - shared.Building.link([in_temp('dlmalloc.o'), in_temp('new.o')], in_temp('dlmalloc_full.o')) - return in_temp('dlmalloc_full.o') - def fix_dlmalloc(): - # dlmalloc needs some sign correction. # If we are in mode 0, switch to 2. We will add our lines + # libc + def create_libc(): + if DEBUG: print >> sys.stderr, 'emcc: building libc for cache' + o_s = [] + for src in ['dlmalloc.c', os.path.join('libc', 'musl', 'memcpy.c'), os.path.join('libcxx', 'new.cpp')]: + o = in_temp(os.path.basename(src) + '.o') + execute([shared.PYTHON, shared.EMCC, shared.path_from_root('system', 'lib', src), '-o', o], stdout=stdout, stderr=stderr) + o_s.append(o) + shared.Building.link(o_s, in_temp('libc.bc')) + return in_temp('libc.bc') + + def fix_libc(need): + # If an intrinsic alias of memcpy is used, we need memcpy + for memcpy_alias in MEMCPY_ALIASES: + if memcpy_alias in need: + if '_memcpy' not in shared.Settings.EXPORTED_FUNCTIONS: + shared.Settings.EXPORTED_FUNCTIONS.append('_memcpy') + break + + # libc needs some sign correction. # If we are in mode 0, switch to 2. We will add our lines try: if shared.Settings.CORRECT_SIGNS == 0: raise Exception('we need to change to 2') except: # we fail if equal to 0 - so we need to switch to 2 - or if CORRECT_SIGNS is not even in Settings @@ -942,7 +966,7 @@ try: # so all is well anyhow too. # XXX We also need to add libc symbols that use malloc, for example strdup. It's very rare to use just them and not # a normal malloc symbol (like free, after calling strdup), so we haven't hit this yet, but it is possible. - dlmalloc_symbols = open(shared.path_from_root('system', 'lib', 'dlmalloc.symbols')).read().split('\n') + libc_symbols = open(shared.path_from_root('system', 'lib', 'libc.symbols')).read().split('\n') # libcxx def create_libcxx(): @@ -954,13 +978,13 @@ try: os.append(o) shared.Building.link(os, in_temp('libcxx.bc')) return in_temp('libcxx.bc') - def fix_libcxx(): + def fix_libcxx(need): assert shared.Settings.QUANTUM_SIZE == 4, 'We do not support libc++ with QUANTUM_SIZE == 1' # libcxx might need corrections, so turn them all on. TODO: check which are actually needed shared.Settings.CORRECT_SIGNS = shared.Settings.CORRECT_OVERFLOWS = shared.Settings.CORRECT_ROUNDINGS = 1 #print >> sys.stderr, 'emcc: info: using libcxx turns on CORRECT_* options' libcxx_symbols = map(lambda line: line.strip().split(' ')[1], open(shared.path_from_root('system', 'lib', 'libcxx', 'symbols')).readlines()) - libcxx_symbols = filter(lambda symbol: symbol not in dlmalloc_symbols, libcxx_symbols) + libcxx_symbols = filter(lambda symbol: symbol not in libc_symbols, libcxx_symbols) libcxx_symbols = set(libcxx_symbols) # libcxxabi - just for dynamic_cast for now @@ -973,19 +997,19 @@ try: os.append(o) shared.Building.link(os, in_temp('libcxxabi.bc')) return in_temp('libcxxabi.bc') - def fix_libcxxabi(): + def fix_libcxxabi(need): assert shared.Settings.QUANTUM_SIZE == 4, 'We do not support libc++abi with QUANTUM_SIZE == 1' #print >> sys.stderr, 'emcc: info: using libcxxabi, this may need CORRECT_* options' #shared.Settings.CORRECT_SIGNS = shared.Settings.CORRECT_OVERFLOWS = shared.Settings.CORRECT_ROUNDINGS = 1 libcxxabi_symbols = map(lambda line: line.strip().split(' ')[1], open(shared.path_from_root('system', 'lib', 'libcxxabi', 'symbols')).readlines()) - libcxxabi_symbols = filter(lambda symbol: symbol not in dlmalloc_symbols, libcxxabi_symbols) + libcxxabi_symbols = filter(lambda symbol: symbol not in libc_symbols, libcxxabi_symbols) libcxxabi_symbols = set(libcxxabi_symbols) - force = False # If we have libcxx, we must force inclusion of dlmalloc, since libcxx uses new internally. Note: this is kind of hacky + force = False # If we have libcxx, we must force inclusion of libc, since libcxx uses new internally. Note: this is kind of hacky for name, create, fix, library_symbols in [('libcxx', create_libcxx, fix_libcxx, libcxx_symbols), ('libcxxabi', create_libcxxabi, fix_libcxxabi, libcxxabi_symbols), - ('dlmalloc', create_dlmalloc, fix_dlmalloc, dlmalloc_symbols)]: + ('libc', create_libc, fix_libc, libc_symbols)]: need = set() has = set() for temp_file in temp_files: @@ -1014,7 +1038,7 @@ try: extra_files_to_link.append(libfile) force = True if fix: - fix() + fix(need) # First, combine the bitcode files if there are several. We must also link if we have a singleton .a if len(input_files) + len(extra_files_to_link) > 1 or \ @@ -1065,6 +1089,36 @@ try: shared.Building.llvm_opt(in_temp(target_basename + '.bc'), link_opts) if DEBUG: save_intermediate('linktime', 'bc') + # Optimization and lto can add new intrinsics like memcpy that were not present before. We + # are now *after* linking in libc, so we missed our chance to get memcpy - check and add it now + # if necessary + final_symbols = shared.Building.llvm_nm(final) + need_memcpy = False + for symbol in final_symbols.undefs: + if symbol in MEMCPY_ALIASES: + need_memcpy = True + break + has_memcpy = False + for symbol in final_symbols.defs: + if symbol in MEMCPY_ALIASES: + has_memcpy = True + break + if need_memcpy and not has_memcpy: + if DEBUG: print >> sys.stderr, 'memcpy intrinsic added in optimizations, linking in optimized memcpy' + memcpy = in_temp('memcpy.bc') + force_cxx = os.environ.get('EMMAKEN_CXX') + if force_cxx is not None: del os.environ['EMMAKEN_CXX'] # memcpy must be compiled as C + execute([shared.PYTHON, shared.EMCC, shared.path_from_root('system', 'lib', 'libc', 'musl', 'memcpy.c'), '-o', memcpy], stdout=stdout, stderr=stderr) + if force_cxx is not None: os.environ['EMMAKEN_CXX'] = force_cxx + shared.Building.llvm_opt(memcpy, llvm_opts) # optimize it just like normal code; no point in lto though + next = final + '.postrinsics.bc' + shared.Building.link([final, memcpy], next) + final = next + if shared.Settings.ASM_JS: # export it so other library functions etc. can use it + if '_memcpy' not in shared.Settings.EXPORTED_FUNCTIONS: + shared.Settings.EXPORTED_FUNCTIONS.append('_memcpy') + if DEBUG: save_intermediate('postrinsics', 'bc') + # Prepare .ll for Emscripten if not LEAVE_INPUTS_RAW: final = shared.Building.llvm_dis(final, final + '.ll') @@ -1131,6 +1185,17 @@ try: execute(shlex.split(js_transform, posix=posix) + [os.path.abspath(final)]) if DEBUG: save_intermediate('transformed') + if shared.Settings.ASM_JS: # XXX temporary wrapping for testing purposes + print >> sys.stderr, 'emcc: ASM_JS mode is highly experimental, and will not work on most codebases yet. It is NOT recommended that you try this yet.' # XXX TODO: 0.0 instead of +0 for local var defs + unwrapped = open(final).read() + final += '.asmwrap.js' + open(final, 'w').write(''' +(function() { // prevent new Function from seeing the global scope +%s +}).apply(null, arguments); +''' % unwrapped) + if DEBUG: save_intermediate('asmwrap') + # It is useful to run several js optimizer passes together, to save on unneeded unparsing/reparsing js_optimizer_queue = [] def flush_js_optimizer_queue(): @@ -1156,11 +1221,21 @@ try: if DEBUG: save_intermediate('pretty') def get_eliminate(): - return 'eliminate' if not shared.Settings.ALLOW_MEMORY_GROWTH else 'eliminateMemSafe' + if shared.Settings.ASM_JS: + return 'eliminateAsm' + elif shared.Settings.ALLOW_MEMORY_GROWTH: + return 'eliminateMemSafe' + else: + return 'eliminate' + + def get_simplify_pre(): + if shared.Settings.ASM_JS: + return 'simplifyExpressionsPreAsm' + else: + return 'simplifyExpressionsPre' - js_optimizer_queue += [get_eliminate()] + js_optimizer_queue += [get_eliminate(), get_simplify_pre()] - js_optimizer_queue += ['simplifyExpressionsPre'] if shared.Settings.RELOOP: js_optimizer_queue += ['optimizeShiftsAggressive', get_eliminate()] # aggressive shifts optimization requires loops, it breaks on switches @@ -1170,6 +1245,8 @@ try: if DEBUG: print >> sys.stderr, 'emcc: running closure' final = shared.Building.closure_compiler(final) if DEBUG: save_intermediate('closure') + elif shared.Settings.ASM_JS and shared.Settings.RELOOP: + js_optimizer_queue += ['registerizeAsm'] # we can't use closure in asm, but this does much of the same if opt_level >= 1: if DEBUG: print >> sys.stderr, 'emcc: running post-closure post-opts' diff --git a/emscripten.py b/emscripten.py index 3c636447..ac13f7a3 100755 --- a/emscripten.py +++ b/emscripten.py @@ -129,10 +129,13 @@ def emscript(infile, settings, outfile, libraries=[]): # Save settings to a file to work around v8 issue 1579 settings_file = temp_files.get('.txt').name - settings_text = json.dumps(settings) - s = open(settings_file, 'w') - s.write(settings_text) - s.close() + def save_settings(): + global settings_text + settings_text = json.dumps(settings) + s = open(settings_file, 'w') + s.write(settings_text) + s.close() + save_settings() # Phase 1 - pre if DEBUG: t = time.time() @@ -170,6 +173,9 @@ def emscript(infile, settings, outfile, libraries=[]): if DEBUG: t = time.time() forwarded_json = json.loads(forwarded_data) indexed_functions = set() + if settings.get('ASM_JS'): + settings['EXPORTED_FUNCTIONS'] = forwarded_json['EXPORTED_FUNCTIONS'] + save_settings() chunks = shared.JCache.chunkify(funcs, chunk_size, 'emscript_files' if jcache else None) @@ -223,16 +229,27 @@ def emscript(infile, settings, outfile, libraries=[]): if DEBUG: print >> sys.stderr, ' emscript: phase 2 took %s seconds' % (time.time() - t) if DEBUG: t = time.time() - funcs_js = ''.join([output[0] for output in outputs]) - + # merge forwarded data + if settings.get('ASM_JS'): + all_exported_functions = set(settings['EXPORTED_FUNCTIONS']) # both asm.js and otherwise + for additional_export in ['_malloc', '_free']: # additional functions to export from asm, if they are implemented + all_exported_functions.add(additional_export) + exported_implemented_functions = set() for func_js, curr_forwarded_data in outputs: - # merge forwarded data curr_forwarded_json = json.loads(curr_forwarded_data) forwarded_json['Types']['preciseI64MathUsed'] = forwarded_json['Types']['preciseI64MathUsed'] or curr_forwarded_json['Types']['preciseI64MathUsed'] for key, value in curr_forwarded_json['Functions']['blockAddresses'].iteritems(): forwarded_json['Functions']['blockAddresses'][key] = value for key in curr_forwarded_json['Functions']['indexedFunctions'].iterkeys(): indexed_functions.add(key) + 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']['unimplementedFunctions'].iteritems(): + forwarded_json['Functions']['unimplementedFunctions'][key] = value + + funcs_js = ''.join([output[0] for output in outputs]) + outputs = None if DEBUG: print >> sys.stderr, ' emscript: phase 2b took %s seconds' % (time.time() - t) if DEBUG: t = time.time() @@ -241,6 +258,7 @@ def emscript(infile, settings, outfile, libraries=[]): forwarded_json['Functions']['indexedFunctions'] = {} i = 2 for indexed in indexed_functions: + #print >> sys.stderr, 'indaxx', indexed, i forwarded_json['Functions']['indexedFunctions'][indexed] = i # make sure not to modify this python object later - we use it in indexize i += 2 forwarded_json['Functions']['nextIndex'] = i @@ -258,8 +276,6 @@ def emscript(infile, settings, outfile, libraries=[]): pre = None #if DEBUG: outfile.write('// funcs\n') - outfile.write(blockaddrsize(indexize(funcs_js))) - funcs_js = None # forward forwarded_data = json.dumps(forwarded_json) @@ -272,8 +288,163 @@ def emscript(infile, settings, outfile, libraries=[]): post_file = temp_files.get('.post.ll').name 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)) + post, last_forwarded_data = out.split('//FORWARDED_DATA:') + last_forwarded_json = json.loads(last_forwarded_data) + + if settings.get('ASM_JS'): + simple = os.environ.get('EMCC_SIMPLE_ASM') + class Counter: + i = 0 + def make_table(sig, raw): + i = Counter.i + Counter.i += 1 + bad = 'b' + str(i) + params = ','.join(['p%d' % p for p in range(len(sig)-1)]) + coercions = ';'.join(['p%d = %sp%d%s' % (p, '+' if sig[p+1] == 'd' else '', p, '' if sig[p+1] == 'd' else '|0') for p in range(len(sig)-1)]) + ';' + ret = '' if sig[0] == 'v' else ('return %s0' % ('+' if sig[0] == 'd' else '')) + return 'function %s(%s) { %s abort(%d); %s };\n' % (bad, params, coercions, i, ret) + raw.replace('[0,', '[' + bad + ',').replace(',0,', ',' + bad + ',').replace(',0,', ',' + bad + ',').replace(',0]', ',' + bad + ']').replace(',0]', ',' + bad + ']') + function_tables_defs = '\n'.join([make_table(sig, raw) for sig, raw in last_forwarded_json['Functions']['tables'].iteritems()]) + + maths = ['Runtime.bitshift64', 'Math.floor', 'Math.min', 'Math.abs', 'Math.sqrt', 'Math.pow', 'Math.cos', 'Math.sin', 'Math.tan', 'Math.acos', 'Math.asin', 'Math.atan', 'Math.atan2', 'Math.exp', 'Math.log', 'Math.ceil'] + + if settings['USE_MATH_IMUL']: + maths += ['Math.imul'] + asm_setup = '\n'.join(['var %s = %s;' % (f.replace('.', '_'), f) for f in maths]) + fundamentals = ['buffer', 'Int8Array', 'Int16Array', 'Int32Array', 'Uint8Array', 'Uint16Array', 'Uint32Array', 'Float32Array', 'Float64Array'] + basic_funcs = ['abort', 'assert'] + [m.replace('.', '_') for m in maths] + basic_vars = ['STACKTOP', 'STACK_MAX', 'tempDoublePtr', 'ABORT'] + if forwarded_json['Types']['preciseI64MathUsed']: + basic_funcs += ['i64Math_' + op for op in ['add', 'subtract', 'multiply', 'divide', 'modulo']] + asm_setup += ''' +var i64Math_add = function(a, b, c, d) { i64Math.add(a, b, c, d) }; +var i64Math_subtract = function(a, b, c, d) { i64Math.subtract(a, b, c, d) }; +var i64Math_multiply = function(a, b, c, d) { i64Math.multiply(a, b, c, d) }; +var i64Math_divide = function(a, b, c, d, e) { i64Math.divide(a, b, c, d, e) }; +var i64Math_modulo = function(a, b, c, d, e) { i64Math.modulo(a, b, c, d, e) }; +''' + asm_runtime_funcs = ['stackAlloc', 'stackSave', 'stackRestore', 'setThrew'] + ['setTempRet%d' % i for i in range(10)] + # function tables + function_tables = ['dynCall_' + table for table in last_forwarded_json['Functions']['tables']] + function_tables_impls = [] + for sig in last_forwarded_json['Functions']['tables'].iterkeys(): + args = ','.join(['a' + str(i) for i in range(1, len(sig))]) + arg_coercions = ' '.join(['a' + str(i) + '=' + ('+' if sig[i] == 'd' else '') + 'a' + str(i) + ('|0' if sig[i] == 'i' else '') + ';' for i in range(1, len(sig))]) + function_tables_impls.append(''' + function dynCall_%s(index%s%s) { + index = index|0; + %s + %sFUNCTION_TABLE_%s[index&{{{ FTM_%s }}}](%s); + } +''' % (sig, ',' if len(sig) > 1 else '', args, arg_coercions, 'return ' if sig[0] != 'v' else '', sig, sig, args)) + # calculate exports + exported_implemented_functions = list(exported_implemented_functions) + exports = [] + if not simple: + for export in exported_implemented_functions + asm_runtime_funcs + function_tables: + exports.append("%s: %s" % (export, export)) + exports = '{ ' + ', '.join(exports) + ' }' + else: + exports = '_main' + # calculate globals + try: + del forwarded_json['Variables']['globals']['_llvm_global_ctors'] # not a true variable + except: + pass + # If no named globals, only need externals + global_vars = map(lambda g: g['name'], filter(lambda g: settings['NAMED_GLOBALS'] or g.get('external') or g.get('unIndexable'), forwarded_json['Variables']['globals'].values())) + global_funcs = ['_' + x for x in forwarded_json['Functions']['libraryFunctions'].keys()] + asm_global_funcs = ''.join([' var ' + g + '=env.' + g + ';\n' for g in basic_funcs + global_funcs]) + asm_global_vars = ''.join([' var ' + g + '=env.' + g + '|0;\n' for g in basic_vars + global_vars]) + # sent data + sending = '{ ' + ', '.join([s + ': ' + s for s in fundamentals + basic_funcs + global_funcs + basic_vars + global_vars]) + ' }' + # received + if not simple: + receiving = ';\n'.join(['var ' + s + ' = Module["' + s + '"] = asm.' + s for s in exported_implemented_functions + function_tables]) + else: + receiving = 'var _main = Module["_main"] = asm;' + # finalize + funcs_js = ''' +%s +var asmPre = (function(env, buffer) { + 'use asm'; + var HEAP8 = new env.Int8Array(buffer); + var HEAP16 = new env.Int16Array(buffer); + var HEAP32 = new env.Int32Array(buffer); + var HEAPU8 = new env.Uint8Array(buffer); + var HEAPU16 = new env.Uint16Array(buffer); + var HEAPU32 = new env.Uint32Array(buffer); + var HEAPF32 = new env.Float32Array(buffer); + var HEAPF64 = new env.Float64Array(buffer); +''' % (asm_setup,) + '\n' + asm_global_vars + ''' + var __THREW__ = 0; + var undef = 0; + var tempInt = 0, tempValue = 0; +''' + ''.join([''' + var tempRet%d = 0;''' % i for i in range(10)]) + '\n' + asm_global_funcs + ''' + function stackAlloc(size) { + size = size|0; + var ret = 0; + ret = STACKTOP; + STACKTOP = (STACKTOP + size)|0; + STACKTOP = ((STACKTOP + 3)>>2)<<2; + return ret|0; + } + function stackSave() { + return STACKTOP|0; + } + function stackRestore(top) { + top = top|0; + STACKTOP = top; + } + function setThrew(threw) { + threw = threw|0; + __THREW__ = threw; + } +''' + ''.join([''' + function setTempRet%d(value) { + value = value|0; + tempRet%d = value; + } +''' % (i, i) for i in range(10)]) + funcs_js.replace('\n', '\n ') + ''' + + %s + + return %s; +}); +if (asmPre.toSource) { // works in sm but not v8, so we get full coverage between those two + asmPre = asmPre.toSource(); + asmPre = asmPre.substr(25, asmPre.length-28); + asmPre = new Function('env', 'buffer', asmPre); +} +var asm = asmPre(%s, buffer); // pass through Function to prevent seeing outside scope +%s; +Runtime.stackAlloc = function(size) { return asm.stackAlloc(size) }; +Runtime.stackSave = function() { return asm.stackSave() }; +Runtime.stackRestore = function(top) { asm.stackRestore(top) }; +''' % (function_tables_defs.replace('\n', '\n ') + '\n' + '\n'.join(function_tables_impls), exports, sending, receiving) + + # Set function table masks + def function_table_maskize(js): + masks = {} + default = None + for sig, table in last_forwarded_json['Functions']['tables'].iteritems(): + masks[sig] = str(table.count(',')) + default = sig + def fix(m): + sig = m.groups(0)[0] + if not sig in masks: + print >> sys.stderr, 'warning: function table use without functions for it!', sig + return masks[default] # TODO: generate empty function tables for this case, even though it would fail at runtime if used + return masks[sig] + return re.sub(r'{{{ FTM_([\w\d_$]+) }}}', lambda m: fix(m), js) # masks[m.groups(0)[0]] + funcs_js = function_table_maskize(funcs_js) + else: + function_tables_defs = '\n'.join([table for table in last_forwarded_json['Functions']['tables'].itervalues()]) + outfile.write(function_tables_defs) + outfile.write(blockaddrsize(indexize(funcs_js))) + funcs_js = None + + outfile.write(indexize(post)) if DEBUG: print >> sys.stderr, ' emscript: phase 3 took %s seconds' % (time.time() - t) outfile.close() diff --git a/src/analyzer.js b/src/analyzer.js index 014579f4..0ad3e017 100644 --- a/src/analyzer.js +++ b/src/analyzer.js @@ -19,7 +19,7 @@ function recomputeLines(func) { var BRANCH_INVOKE = set('branch', 'invoke'); var SIDE_EFFECT_CAUSERS = set('call', 'invoke', 'atomic'); -var UNUNFOLDABLE = set('value', 'type', 'phiparam'); +var UNUNFOLDABLE = set('value', 'structvalue', 'type', 'phiparam'); // Analyzer @@ -120,12 +120,14 @@ function analyzer(data, sidePass) { processItem: function(data) { // Legalization if (USE_TYPED_ARRAYS == 2) { - function getLegalVars(base, bits) { - assert(!isNumber(base)); + function getLegalVars(base, bits, allowLegal) { + if (allowLegal && bits <= 32) return [{ ident: base, bits: bits }]; + if (isNumber(base)) return getLegalLiterals(base, bits); var ret = new Array(Math.ceil(bits/32)); var i = 0; + if (base == 'zeroinitializer' || base == 'undef') base = 0; while (bits > 0) { - ret[i] = { ident: base + '$' + i, bits: Math.min(32, bits) }; + ret[i] = { ident: base ? base + '$' + i : '0', bits: Math.min(32, bits) }; bits -= 32; i++; } @@ -142,6 +144,23 @@ function analyzer(data, sidePass) { } return ret; } + function getLegalStructuralParts(value) { + return value.params.slice(0); + } + function getLegalParams(params, bits) { + return params.map(function(param) { + var value = param.value || param; + if (isNumber(value.ident)) { + return getLegalLiterals(value.ident, bits); + } else if (value.intertype == 'structvalue') { + return getLegalStructuralParts(value).map(function(part) { + return { ident: part.ident, bits: part.type.substr(1) }; + }); + } else { + return getLegalVars(value.ident, bits); + } + }); + } // Uses the right factor to multiply line numbers by so that they fit in between // the line[i] and the line after it function interpLines(lines, i, toAdd) { @@ -191,6 +210,7 @@ function analyzer(data, sidePass) { // Legalize lines in labels var tempId = 0; func.labels.forEach(function(label) { + if (dcheck('legalizer')) dprint('zz legalizing: \n' + dump(label.lines)); var i = 0, bits; while (i < label.lines.length) { var item = label.lines[i]; @@ -207,8 +227,12 @@ function analyzer(data, sidePass) { if (isIllegalType(item.valueType) || isIllegalType(item.type)) { isIllegal = true; } + if ((item.intertype == 'load' || item.intertype == 'store') && isStructType(item.valueType)) { + isIllegal = true; // storing an entire structure is illegal + } }); if (!isIllegal) { + //if (dcheck('legalizer')) dprint('no need to legalize \n' + dump(item)); i++; continue; } @@ -222,10 +246,10 @@ function analyzer(data, sidePass) { if (subItem != item && (!(subItem.intertype in UNUNFOLDABLE) || (subItem.intertype == 'value' && isNumber(subItem.ident) && isIllegalType(subItem.type)))) { if (item.intertype == 'phi') { - assert(subItem.intertype == 'value', 'We can only unfold illegal constants in phis'); + assert(subItem.intertype == 'value' || subItem.intertype == 'structvalue', 'We can only unfold illegal constants in phis'); // we must handle this in the phi itself, if we unfold normally it will not be pushed back with the phi } else { - var tempIdent = '$$emscripten$temp$' + (tempId++); + var tempIdent = '$$etemp$' + (tempId++); subItem.assignTo = tempIdent; unfolded.unshift(subItem); fixUnfolded(subItem); @@ -234,7 +258,7 @@ function analyzer(data, sidePass) { } else if (subItem.intertype == 'switch' && isIllegalType(subItem.type)) { subItem.switchLabels.forEach(function(switchLabel) { if (switchLabel.value[0] != '$') { - var tempIdent = '$$emscripten$temp$' + (tempId++); + var tempIdent = '$$etemp$' + (tempId++); unfolded.unshift({ assignTo: tempIdent, intertype: 'value', @@ -258,8 +282,7 @@ function analyzer(data, sidePass) { case 'store': { var toAdd = []; bits = getBits(item.valueType); - var elements; - elements = getLegalVars(item.value.ident, bits); + var elements = getLegalParams([item.value], bits)[0]; var j = 0; elements.forEach(function(element) { var tempVar = '$st$' + i + '$' + j; @@ -290,32 +313,43 @@ function analyzer(data, sidePass) { i += removeAndAdd(label.lines, i, toAdd); continue; } - // call, return: Return value is in an unlegalized array literal. Not fully optimal. + // call, return: Return the first 32 bits, the rest are in temp case 'call': { bits = getBits(value.type); var elements = getLegalVars(item.assignTo, bits); var toAdd = [value]; // legalize parameters legalizeFunctionParameters(value.params); - if (value.assignTo) { + if (value.assignTo && isIllegalType(item.type)) { // legalize return value - var j = 0; - toAdd = toAdd.concat(elements.map(function(element) { - return { + value.assignTo = elements[0].ident; + for (var j = 1; j < elements.length; j++) { + var element = elements[j]; + toAdd.push({ intertype: 'value', assignTo: element.ident, - type: 'i' + bits, - ident: value.assignTo + '[' + (j++) + ']' - }; - })); + type: element.bits, + ident: 'tempRet' + (j - 1) + }); + assert(j<10); // TODO: dynamically create more than 10 tempRet-s + } } i += removeAndAdd(label.lines, i, toAdd); continue; } + case 'landingpad': { + // not much to legalize + i++; + continue; + } case 'return': { bits = getBits(item.type); var elements = getLegalVars(item.value.ident, bits); - item.value.ident = '[' + elements.map(function(element) { return element.ident }).join(',') + ']'; + item.value.ident = '('; + for (var j = 1; j < elements.length; j++) { + item.value.ident += 'tempRet' + (j-1) + '=' + elements[j].ident + ','; + } + item.value.ident += elements[0].ident + ')'; i++; continue; } @@ -341,6 +375,21 @@ function analyzer(data, sidePass) { i += removeAndAdd(label.lines, i, toAdd); continue; } + case 'structvalue': { + bits = getBits(value.type); + var elements = getLegalVars(item.assignTo, bits); + var toAdd = []; + for (var j = 0; j < item.params.length; j++) { + toAdd[j] = { + intertype: 'value', + assignTo: elements[j].ident, + type: 'i32', + ident: item.params[j].ident + }; + } + i += removeAndAdd(label.lines, i, toAdd); + continue; + } case 'load': { bits = getBits(value.valueType); var elements = getLegalVars(item.assignTo, bits); @@ -382,13 +431,9 @@ function analyzer(data, sidePass) { var toAdd = []; var elements = getLegalVars(item.assignTo, bits); var j = 0; - var literalValues = {}; // special handling of literals - we cannot unfold them normally - value.params.map(function(param) { - if (isNumber(param.value.ident)) { - literalValues[param.value.ident] = getLegalLiterals(param.value.ident, bits); - } - }); + var values = getLegalParams(value.params, bits); elements.forEach(function(element) { + var k = 0; toAdd.push({ intertype: 'phi', assignTo: element.ident, @@ -399,7 +444,7 @@ function analyzer(data, sidePass) { label: param.label, value: { intertype: 'value', - ident: (param.value.ident in literalValues) ? literalValues[param.value.ident][j].ident : (param.value.ident + '$' + j), + ident: values[k++][j].ident, type: 'i' + element.bits, } }; @@ -414,6 +459,62 @@ function analyzer(data, sidePass) { i++; continue; // special case, handled in makeComparison } + 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 + var index = item.indexes[0][0].text; + var parts = getStructureTypeParts(item.type); + var indexedType = parts[index]; + var targetBits = getBits(indexedType); + var sourceBits = getBits(item.type); + var elements = getLegalVars(item.assignTo, targetBits, true); // possibly illegal + var sourceElements = getLegalVars(item.ident, sourceBits); // definitely illegal + var toAdd = []; + var sourceIndex = 0; + for (var partIndex = 0; partIndex < parts.length; partIndex++) { + if (partIndex == index) { + for (var j = 0; j < elements.length; j++) { + toAdd.push({ + intertype: 'value', + assignTo: elements[j].ident, + type: 'i' + elements[j].bits, + ident: sourceElements[sourceIndex+j].ident + }); + } + break; + } + sourceIndex += getStructuralTypePartBits(parts[partIndex])/32; + } + i += removeAndAdd(label.lines, i, toAdd); + continue; + } + case 'insertvalue': { + var index = item.indexes[0][0].text; // the modified index + var parts = getStructureTypeParts(item.type); + var indexedType = parts[index]; + var indexBits = getBits(indexedType); + var bits = getBits(item.type); // source and target + bits = getBits(value.type); + var toAdd = []; + var elements = getLegalVars(item.assignTo, bits); + var sourceElements = getLegalVars(item.ident, bits); + var indexElements = getLegalVars(item.value.ident, indexBits, true); // possibly legal + var sourceIndex = 0; + for (var partIndex = 0; partIndex < parts.length; partIndex++) { + var currNum = getStructuralTypePartBits(parts[partIndex])/32; + for (var j = 0; j < currNum; j++) { + toAdd.push({ + intertype: 'value', + assignTo: elements[sourceIndex+j].ident, + type: 'i' + elements[sourceIndex+j].bits, + ident: partIndex == index ? indexElements[j].ident : sourceElements[sourceIndex+j].ident + }); + } + sourceIndex += currNum; + } + i += removeAndAdd(label.lines, i, toAdd); + continue; + } case 'bitcast': { var inType = item.type2; var outType = item.type; @@ -477,17 +578,16 @@ function analyzer(data, sidePass) { } case 'select': { sourceBits = targetBits = getBits(value.params[1].type); - var otherElementsA = getLegalVars(value.params[1].ident, sourceBits); - var otherElementsB = getLegalVars(value.params[2].ident, sourceBits); + var params = getLegalParams(value.params.slice(1), sourceBits); processor = function(result, j) { return { intertype: 'mathop', op: 'select', - type: 'i' + otherElementsA[j].bits, + type: 'i' + params[0][j].bits, params: [ value.params[0], - { intertype: 'value', ident: otherElementsA[j].ident, type: 'i' + otherElementsA[j].bits }, - { intertype: 'value', ident: otherElementsB[j].ident, type: 'i' + otherElementsB[j].bits } + { intertype: 'value', ident: params[0][j].ident, type: 'i' + params[0][j].bits }, + { intertype: 'value', ident: params[1][j].ident, type: 'i' + params[1][j].bits } ] }; }; @@ -554,9 +654,10 @@ function analyzer(data, sidePass) { // We can't statically legalize this, do the operation at runtime TODO: optimize assert(sourceBits == 64, 'TODO: handle nonconstant shifts on != 64 bits'); value.intertype = 'value'; - value.ident = 'Runtime.bitshift64(' + sourceElements[0].ident + ', ' + + value.ident = 'Runtime' + (ASM_JS ? '_' : '.') + 'bitshift64(' + sourceElements[0].ident + ', ' + sourceElements[1].ident + ',"' + value.op + '",' + value.params[1].ident + '$0);' + - 'var ' + value.assignTo + '$0 = ' + value.assignTo + '[0], ' + value.assignTo + '$1 = ' + value.assignTo + '[1];'; + 'var ' + value.assignTo + '$0 = ' + makeGetTempDouble(0) + ', ' + value.assignTo + '$1 = ' + makeGetTempDouble(1) + ';'; + value.assignTo = null; i++; continue; } diff --git a/src/compiler.js b/src/compiler.js index 35f746a5..118ca83a 100644 --- a/src/compiler.js +++ b/src/compiler.js @@ -174,18 +174,25 @@ RUNTIME_DEBUG = LIBRARY_DEBUG || GL_DEBUG; // Settings sanity checks assert(!(USE_TYPED_ARRAYS === 2 && QUANTUM_SIZE !== 4), 'For USE_TYPED_ARRAYS == 2, must have normal QUANTUM_SIZE of 4'); +if (ASM_JS) { + assert(!ALLOW_MEMORY_GROWTH, 'Cannot grow asm.js heap'); + assert((TOTAL_MEMORY&(TOTAL_MEMORY-1)) == 0, 'asm.js heap must be power of 2'); +} +assert(!(!NAMED_GLOBALS && BUILD_AS_SHARED_LIB)); // shared libraries must have named globals // Output some info and warnings based on settings -if (!MICRO_OPTS || !RELOOP || ASSERTIONS || CHECK_SIGNS || CHECK_OVERFLOWS || INIT_STACK || INIT_HEAP || - !SKIP_STACK_IN_SMALL || SAFE_HEAP || PGO || PROFILE || !DISABLE_EXCEPTION_CATCHING) { - print('// Note: Some Emscripten settings will significantly limit the speed of the generated code.'); -} else { - print('// Note: For maximum-speed code, see "Optimizing Code" on the Emscripten wiki, https://github.com/kripken/emscripten/wiki/Optimizing-Code'); -} +if (phase == 'pre') { + if (!MICRO_OPTS || !RELOOP || ASSERTIONS || CHECK_SIGNS || CHECK_OVERFLOWS || INIT_STACK || INIT_HEAP || + !SKIP_STACK_IN_SMALL || SAFE_HEAP || PGO || PROFILE || !DISABLE_EXCEPTION_CATCHING) { + print('// Note: Some Emscripten settings will significantly limit the speed of the generated code.'); + } else { + print('// Note: For maximum-speed code, see "Optimizing Code" on the Emscripten wiki, https://github.com/kripken/emscripten/wiki/Optimizing-Code'); + } -if (DOUBLE_MODE || CORRECT_SIGNS || CORRECT_OVERFLOWS || CORRECT_ROUNDINGS) { - print('// Note: Some Emscripten settings may limit the speed of the generated code.'); + if (DOUBLE_MODE || CORRECT_SIGNS || CORRECT_OVERFLOWS || CORRECT_ROUNDINGS) { + print('// Note: Some Emscripten settings may limit the speed of the generated code.'); + } } // Load compiler code diff --git a/src/intertyper.js b/src/intertyper.js index 5af291c7..5bca9236 100644 --- a/src/intertyper.js +++ b/src/intertyper.js @@ -69,11 +69,13 @@ function intertyper(data, sidePass, baseLineNums) { if (mainPass && (line[0] == '%' || line[0] == '@')) { // If this isn't a type, it's a global variable, make a note of the information now, we will need it later - var testType = /[@%\w\d\.\" $-]+ = type .*/.exec(line); + var parts = line.split(' = '); + assert(parts.length >= 2); + var left = parts[0], right = parts.slice(1).join(' = '); + var testType = /^type .*/.exec(right); if (!testType) { - var global = /([@%\w\d\.\" $-]+) = .*/.exec(line); - var globalIdent = toNiceIdent(global[1]); - var testAlias = /[@%\w\d\.\" $-]+ = (hidden )?alias .*/.exec(line); + var globalIdent = toNiceIdent(left); + var testAlias = /^(hidden )?alias .*/.exec(right); Variables.globals[globalIdent] = { name: globalIdent, alias: !!testAlias, @@ -125,6 +127,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 @@ -520,7 +523,12 @@ function intertyper(data, sidePass, baseLineNums) { if (item.tokens[3].item) { var subTokens = item.tokens[3].item.tokens; splitTokenList(subTokens).forEach(function(segment) { - ret.ctors.push(segment[1].tokens.slice(-1)[0].text); + var ctor = toNiceIdent(segment[1].tokens.slice(-1)[0].text); + ret.ctors.push(ctor); + if (ASM_JS) { // must export the global constructors from asm.js module, so mark as implemented and exported + Functions.implementedFunctions[ctor] = 'v'; + EXPORTED_FUNCTIONS[ctor] = 1; + } }); } } else if (!external) { @@ -741,6 +749,7 @@ function intertyper(data, sidePass, baseLineNums) { } var last = getTokenIndexByText(item.tokens, ';'); item.params = splitTokenList(item.tokens.slice(1, last)).map(parseLLVMSegment); + item.type = item.params[1].type; this.forwardItem(item, 'Reintegrator'); } }); diff --git a/src/jsifier.js b/src/jsifier.js index 70329b3f..e41bcf67 100644 --- a/src/jsifier.js +++ b/src/jsifier.js @@ -9,6 +9,8 @@ var STRUCT_LIST = set('struct', 'list'); var UNDERSCORE_OPENPARENS = set('_', '('); var RELOOP_IGNORED_LASTS = set('return', 'unreachable', 'resume'); +var addedLibraryItems = {}; + // JSifier function JSify(data, functionsOnly, givenFunctions) { var mainPass = !functionsOnly; @@ -42,7 +44,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 })); + }); } } @@ -258,7 +262,7 @@ function JSify(data, functionsOnly, givenFunctions) { var ret = [item]; if (item.ident == '_llvm_global_ctors') { item.JS = '\n__ATINIT__ = __ATINIT__.concat([\n' + - item.ctors.map(function(ctor) { return ' { func: ' + toNiceIdent(ctor) + ' }' }).join(',\n') + + item.ctors.map(function(ctor) { return ' { func: function() { ' + ctor + '() } }' }).join(',\n') + '\n]);\n'; return ret; } else { @@ -273,12 +277,13 @@ function JSify(data, functionsOnly, givenFunctions) { item.JS = makeGlobalDef(item.ident); } - if (item.external) { + if (item.external && !ASM_JS) { // ASM_JS considers externs to be globals // Import external global variables from the library if available. var shortident = item.ident.slice(1); if (LibraryManager.library[shortident] && LibraryManager.library[shortident].length && !BUILD_AS_SHARED_LIB) { + if (addedLibraryItems[shortident]) return ret; var val = LibraryManager.library[shortident]; var padding; if (Runtime.isNumberType(item.type) || isPointerType(item.type)) { @@ -302,7 +307,17 @@ function JSify(data, functionsOnly, givenFunctions) { index = makeGlobalUse(item.ident); // index !== null indicates we are indexing this allocator = 'ALLOC_NONE'; } - constant = parseConst(item.value, item.type, item.ident); + if (item.external) { + assert(ASM_JS); + if (Runtime.isNumberType(item.type) || isPointerType(item.type)) { + constant = zeros(Runtime.getNativeFieldSize(item.type)); + } else { + constant = makeEmptyStruct(item.type); + } + constant = JSON.stringify(constant); + } else { + constant = parseConst(item.value, item.type, item.ident); + } if (typeof constant === 'string' && constant[0] != '[') { constant = [constant]; // A single item. We may need a postset for it. } @@ -333,13 +348,17 @@ function JSify(data, functionsOnly, givenFunctions) { } js += '\n' + makePointer('[0]', null, allocator, ['void*'], index) + ';'; } - if (EXPORT_ALL || (item.ident in EXPORTED_GLOBALS)) { + if (!ASM_JS && (EXPORT_ALL || (item.ident in EXPORTED_GLOBALS))) { js += '\nModule["' + item.ident + '"] = ' + item.ident + ';'; } if (BUILD_AS_SHARED_LIB == 2 && !item.private_) { // TODO: make the assert conditional on ASSERTIONS js += 'if (globalScope) { assert(!globalScope["' + item.ident + '"]); globalScope["' + item.ident + '"] = ' + item.ident + ' }'; } + if (item.external && !NAMED_GLOBALS) { + assert(ASM_JS); + js = 'var ' + item.ident + ' = ' + js; // force an explicit naming, even if unnamed globals, for asm forwarding + } return ret.concat({ intertype: 'GlobalVariable', JS: js, @@ -377,8 +396,6 @@ function JSify(data, functionsOnly, givenFunctions) { } }); - var addedLibraryItems = {}; - // functionStub substrate.addActor('FunctionStub', { processItem: function(item) { @@ -399,13 +416,19 @@ function JSify(data, functionsOnly, givenFunctions) { var isFunction = false; if (typeof snippet === 'string') { - if (LibraryManager.library[snippet]) { + var target = LibraryManager.library[snippet]; + if (target) { // Redirection for aliases. We include the parent, and at runtime make ourselves equal to it. // This avoid having duplicate functions with identical content. redirectedIdent = snippet; deps.push(snippet); snippet = '_' + snippet; } + // In asm, we need to know about library functions. If there is a target, though, then no + // need to consider this a library function - we will call directly to it anyhow + if (ASM_JS && !redirectedIdent && (typeof target == 'function' || /Math\..+/.exec(snippet))) { + Functions.libraryFunctions[ident] = 1; + } } else if (typeof snippet === 'object') { snippet = stringifyWithFunctions(snippet); } else if (typeof snippet === 'function') { @@ -420,6 +443,7 @@ function JSify(data, functionsOnly, givenFunctions) { snippet = snippet.replace('{', '{ var ret = (function() { if (Runtime.debug) Module.print("[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.print(" [ return:" + Runtime.prettyPrint(ret)); return ret; }'; } + if (ASM_JS) Functions.libraryFunctions[ident] = 1; } var postsetId = ident + '__postset'; @@ -435,6 +459,18 @@ function JSify(data, functionsOnly, givenFunctions) { if (redirectedIdent) { deps = deps.concat(LibraryManager.library[redirectedIdent + '__deps'] || []); } + if (ASM_JS) { + // In asm, dependencies implemented in C might be needed by JS library functions. + // We don't know yet if they are implemented in C or not. To be safe, export such + // special cases. + [LIBRARY_DEPS_TO_AUTOEXPORT].forEach(function(special) { + deps.forEach(function(dep) { + if (dep == special && !EXPORTED_FUNCTIONS[dep]) { + EXPORTED_FUNCTIONS[dep] = 1; + } + }); + }); + } // $ident's are special, we do not prefix them with a '_'. if (ident[0] === '$') { ident = ident.substr(1); @@ -442,7 +478,8 @@ function JSify(data, functionsOnly, givenFunctions) { ident = '_' + ident; } var text = (deps ? '\n' + deps.map(addFromLibrary).filter(function(x) { return x != '' }).join('\n') : ''); - text += isFunction ? snippet : 'var ' + ident + '=' + snippet + ';'; + // redirected idents just need a var, but no value assigned to them - it would be unused + text += isFunction ? snippet : ('var ' + ident + (redirectedIdent ? '' : '=' + snippet) + ';'); if (EXPORT_ALL || (ident in EXPORTED_FUNCTIONS)) { text += '\nModule["' + ident + '"] = ' + ident + ';'; } @@ -532,8 +569,8 @@ function JSify(data, functionsOnly, givenFunctions) { func.JS = '\n'; var paramIdents = func.params.map(function(param) { - return (param.intertype == 'varargs') ? null : toNiceIdent(param.ident); - }).filter(function(param) { return param != null; }) + return toNiceIdent(param.ident); + }); if (CLOSURE_ANNOTATIONS) { func.JS += '/**\n'; @@ -551,6 +588,34 @@ function JSify(data, functionsOnly, givenFunctions) { func.JS += 'function ' + func.ident + '(' + paramIdents.join(', ') + ') {\n'; + if (ASM_JS) { + // spell out argument types + func.params.forEach(function(param) { + func.JS += ' ' + param.ident + ' = ' + asmCoercion(param.ident, param.type) + ';\n'; + }); + + // spell out local variables + var vars = values(func.variables).filter(function(v) { return v.origin != 'funcparam' }); + if (vars.length > 0) { + var chunkSize = 8; + var chunks = []; + var i = 0; + while (i < vars.length) { + chunks.push(vars.slice(i, i+chunkSize)); + i += chunkSize; + } + for (i = 0; i < chunks.length; i++) { + func.JS += ' var ' + chunks[i].map(function(v) { + if (v.type != 'i64') { + return v.ident + ' = ' + asmInitializer(v.type); //, func.variables[v.ident].impl); + } else { + return v.ident + '$0 = 0, ' + v.ident + '$1 = 1'; + } + }).join(', ') + ';\n'; + } + } + } + if (PROFILE) { func.JS += ' if (PROFILING) { ' + 'var __parentProfilingNode__ = PROFILING_NODE; PROFILING_NODE = PROFILING_NODE.children["' + func.ident + '"]; ' @@ -560,6 +625,21 @@ function JSify(data, functionsOnly, givenFunctions) { + '}\n'; } + if (true) { // TODO: optimize away when not needed + if (CLOSURE_ANNOTATIONS) func.JS += '/** @type {number} */'; + func.JS += ' var label = 0;\n'; + } + + if (ASM_JS) { + var hasByVal = false; + func.params.forEach(function(param) { + hasByVal = hasByVal || param.byVal; + }); + if (hasByVal) { + func.JS += ' var tempParam = 0;\n'; + } + } + // Prepare the stack, if we need one. If we have other stack allocations, force the stack to be set up. func.JS += ' ' + RuntimeGenerator.stackEnter(func.initialStack, func.otherStackAllocations) + ';\n'; @@ -574,18 +654,13 @@ function JSify(data, functionsOnly, givenFunctions) { if (param.byVal) { var type = removePointing(param.type); var typeInfo = Types.types[type]; - func.JS += ' var tempParam = ' + param.ident + '; ' + param.ident + ' = ' + RuntimeGenerator.stackAlloc(typeInfo.flatSize) + ';' + + func.JS += ' ' + (ASM_JS ? '' : 'var ') + 'tempParam = ' + param.ident + '; ' + param.ident + ' = ' + RuntimeGenerator.stackAlloc(typeInfo.flatSize) + ';' + makeCopyValues(param.ident, 'tempParam', typeInfo.flatSize, 'null', null, param.byVal) + ';\n'; } }); if (LABEL_DEBUG && functionNameFilterTest(func.ident)) func.JS += " Module.print(INDENT + ' Entering: " + func.ident + ": ' + Array.prototype.slice.call(arguments)); INDENT += ' ';\n"; - if (true) { // TODO: optimize away when not needed - if (CLOSURE_ANNOTATIONS) func.JS += '/** @type {number} */'; - func.JS += ' var label;\n'; - } - // Walk function blocks and generate JS function walkBlock(block, indent) { if (!block) return ''; @@ -664,6 +739,8 @@ function JSify(data, functionsOnly, givenFunctions) { //Relooper.setDebug(1); Relooper.init(); + if (ASM_JS) Relooper.setAsmJSMode(1); + var blockMap = {}; // add blocks for (var i = 0; i < block.labels.length; i++) { @@ -716,12 +793,12 @@ function JSify(data, functionsOnly, givenFunctions) { if (PRINT_SPLIT_FILE_MARKER) { func.JS += '\n//FUNCTION_END_MARKER_OF_SOURCE_FILE_' + associatedSourceFile + '\n'; } - - if (EXPORT_ALL || (func.ident in EXPORTED_FUNCTIONS)) { + + if (!ASM_JS && (EXPORT_ALL || (func.ident in EXPORTED_FUNCTIONS))) { func.JS += 'Module["' + func.ident + '"] = ' + func.ident + ';'; } - if (INLINING_LIMIT && func.lines.length >= INLINING_LIMIT) { + if (!ASM_JS && INLINING_LIMIT && func.lines.length >= INLINING_LIMIT) { func.JS += func.ident + '["X"]=1;'; } @@ -767,8 +844,9 @@ function JSify(data, functionsOnly, givenFunctions) { var valueJS = item.JS; item.JS = ''; if (CLOSURE_ANNOTATIONS) item.JS += '/** @type {number} */ '; - item.JS += (item.overrideSSA ? '' : 'var ') + toNiceIdent(item.assignTo); - + if (!ASM_JS || item.intertype != 'alloca' || item.funcData.variables[item.assignTo].impl == VAR_EMULATED) { // asm only needs non-allocas + item.JS += ((ASM_JS || item.overrideSSA) ? '' : 'var ') + toNiceIdent(item.assignTo); + } var value = parseNumerical(valueJS); var impl = getVarImpl(item.funcData, item.assignTo); switch (impl) { @@ -798,7 +876,7 @@ function JSify(data, functionsOnly, givenFunctions) { return substrate.addActor('Intertype:' + intertype, { processItem: function(item) { item.JS = func(item); - if (!item.JS) throw "No JS generated for " + dump(item); + if (!item.JS) throw "No JS generated for " + dump((item.funcData=null,item)); if (item.assignTo) { makeAssign(item); if (!item.JS) throw "No assign JS generated for " + dump(item); @@ -814,7 +892,7 @@ function JSify(data, functionsOnly, givenFunctions) { return ';'; }); makeFuncLineActor('var', function(item) { // assigns into phis become simple vars - return 'var ' + item.ident + ';'; + return ASM_JS ? ';' : ('var ' + item.ident + ';'); }); makeFuncLineActor('store', function(item) { var value = finalizeLLVMParameter(item.value); @@ -908,7 +986,7 @@ function JSify(data, functionsOnly, givenFunctions) { var labelSets = phiSets[label]; // FIXME: Many of the |var |s here are not needed, but without them we get slowdowns with closure compiler. TODO: remove this workaround. if (labelSets.length == 1) { - return 'var ' + labelSets[0].ident + ' = ' + labelSets[0].valueJS + ';'; + return (ASM_JS ? '' : 'var ') + labelSets[0].ident + ' = ' + labelSets[0].valueJS + ';'; } // TODO: eliminate unneeded sets (to undefined etc.) var deps = {}; // for each ident we will set, which others it depends on @@ -1044,33 +1122,36 @@ function JSify(data, functionsOnly, givenFunctions) { } ret += 'return'; if (item.value) { - ret += ' ' + finalizeLLVMParameter(item.value); + ret += ' ' + asmCoercion(finalizeLLVMParameter(item.value), item.type); } return ret + ';'; }); makeFuncLineActor('resume', function(item) { // 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, item.ident + '.f0', 'void*') + ' } ' + - 'throw ' + item.ident + '.f0;'; + 'if (' + makeGetValue('_llvm_eh_exception.buf', 0, 'void*') + ' == 0) { ' + makeSetValue('_llvm_eh_exception.buf', 0, ptr, 'void*') + ' } ' + + 'throw ' + ptr + ';'; }); makeFuncLineActor('invoke', function(item) { // Wrapping in a function lets us easily return values if we are // in an assignment var phiSets = calcPhiSets(item); var call_ = makeFunctionCall(item.ident, item.params, item.funcData, item.type); - var ret = '(function() { try { __THREW__ = false; return ' + var ret = '(function() { try { __THREW__ = 0; return ' + call_ + ' ' + '} catch(e) { ' + 'if (typeof e != "number") throw e; ' - + 'if (ABORT) throw e; __THREW__ = true; ' + + 'if (ABORT) throw e; __THREW__ = 1; ' + (EXCEPTION_DEBUG ? 'Module.print("Exception: " + e + ", currently at: " + (new Error().stack)); ' : '') + 'return null } })();'; if (item.assignTo) { ret = 'var ' + item.assignTo + ' = ' + ret; - if (isIllegalType(item.type)) { - assert(item.type == 'i64', 'Can only handle i64 invoke among illegal invokes'); - ret += 'var ' + item.assignTo + '$0 = ' + item.assignTo + '[0], ' + item.assignTo + '$1 = ' + item.assignTo + '[1];'; + if (USE_TYPED_ARRAYS == 2 && isIllegalType(item.type)) { + var bits = getBits(item.type); + for (var i = 0; i < bits/32; i++) { + ret += 'var ' + item.assignTo + '$' + i + ' = ' + (i == 0 ? item.assignTo : 'tempRet' + (i-1)) + ';' + } } item.assignTo = null; } @@ -1098,7 +1179,12 @@ function JSify(data, functionsOnly, givenFunctions) { }); makeFuncLineActor('landingpad', function(item) { var catchTypeArray = item.catchables.map(finalizeLLVMParameter).join(','); - return '___cxa_find_matching_catch('+ makeGetValue('_llvm_eh_exception.buf', '0', 'void*') +',' + makeGetValue('_llvm_eh_exception.buf', QUANTUM_SIZE, 'void*') + ',[' + catchTypeArray +'])'; + var ret = '___cxa_find_matching_catch('+ makeGetValue('_llvm_eh_exception.buf', '0', 'void*') +',' + makeGetValue('_llvm_eh_exception.buf', QUANTUM_SIZE, 'void*') + ',[' + catchTypeArray +'])'; + if (USE_TYPED_ARRAYS == 2) { + ret = makeVarDef(item.assignTo) + '$0 = ' + ret + '; ' + item.assignTo + '$1 = tempRet0;'; + item.assignTo = null; + } + return ret; }); makeFuncLineActor('load', function(item) { var value = finalizeLLVMParameter(item.pointer); @@ -1140,7 +1226,7 @@ function JSify(data, functionsOnly, givenFunctions) { makeFuncLineActor('alloca', function(item) { if (typeof item.allocatedIndex === 'number') { if (item.allocatedSize === 0) return ''; // This will not actually be shown - it's nativized - return getFastValue('__stackBase__', '+', item.allocatedIndex.toString()); + return asmCoercion(getFastValue('__stackBase__', '+', item.allocatedIndex.toString()), 'i32'); } else { return RuntimeGenerator.stackAlloc(getFastValue(calcAllocatedSize(item.allocatedType), '*', item.allocatedNum)); } @@ -1163,7 +1249,16 @@ function JSify(data, functionsOnly, givenFunctions) { // We cannot compile assembly. See comment in intertyper.js:'Call' assert(ident != 'asm', 'Inline assembly cannot be compiled to JavaScript!'); - var shortident = LibraryManager.getRootIdent(ident.slice(1)) || ident.slice(1); // ident may not be in library, if all there is is ident__inline + var shortident = ident.slice(1); + var callIdent = LibraryManager.getRootIdent(shortident); + if (callIdent) { + shortident = 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; + } var args = []; var argsTypes = []; var varargs = []; @@ -1173,6 +1268,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); @@ -1196,6 +1292,10 @@ function JSify(data, functionsOnly, givenFunctions) { }); args = args.map(function(arg, i) { return indexizeFunctions(arg, argsTypes[i]) }); + if (ASM_JS && shortident in Functions.libraryFunctions) { + args = args.map(function(arg, i) { return asmCoercion(arg, argsTypes[i]) }); + } + varargs = varargs.map(function(vararg, i) { if (ignoreFunctionIndexizing.indexOf(i) >= 0) return vararg; return vararg === 0 ? 0 : indexizeFunctions(vararg, varargsTypes[i]) @@ -1226,6 +1326,7 @@ function JSify(data, functionsOnly, givenFunctions) { }).filter(function(arg) { return arg !== null; }).join(',') + ',tempInt)'; + varargs = asmCoercion(varargs, 'i32'); } args = args.concat(varargs); @@ -1238,11 +1339,26 @@ 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 + ']'; + var returnType; + if (byPointer || ASM_JS) returnType = type.split(' ')[0]; + + if (byPointer) { + var sig = Functions.getSignature(returnType, argsTypes); + 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 + } + callIdent = Functions.getTable(sig) + '[' + callIdent + ']'; } - return ident + '(' + args.join(', ') + ')'; + var ret = callIdent + '(' + args.join(', ') + ')'; + if (ASM_JS) { // TODO: do only when needed (library functions and Math.*?) XXX && shortident in Functions.libraryFunctions) { + ret = asmCoercion(ret, returnType); + if (shortident == 'abort' && funcData.returnType != 'void') { + ret += '; return 0'; // special case: abort() can happen without return, breaking the return type of asm functions. ensure a return + } + } + return ret; } makeFuncLineActor('getelementptr', function(item) { return finalizeLLVMFunctionCall(item) }); makeFuncLineActor('call', function(item) { @@ -1297,8 +1413,9 @@ function JSify(data, functionsOnly, givenFunctions) { if (phase == 'pre' && !Variables.generatedGlobalBase) { Variables.generatedGlobalBase = true; if (Variables.nextIndexedOffset > 0) { - // Variables have been calculated, print out the base generation before we print them - print('var GLOBAL_BASE = STATICTOP;\n'); + // Variables have been calculated, get to base stuff before we print them + // GLOBAL_BASE is statically known to be equal to STACK_MAX and to TOTAL_STACK, assert on this + print('assert(STATICTOP == STACK_MAX); assert(STACK_MAX == TOTAL_STACK);\n'); print('STATICTOP += ' + Variables.nextIndexedOffset + ';\n'); print('assert(STATICTOP < TOTAL_MEMORY);\n'); } @@ -1343,8 +1460,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; } @@ -1371,11 +1487,11 @@ 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) { - print('eval(Module["read"]("' + lib + '"))(FUNCTION_TABLE.length, this);'); + print('eval(Module["read"]("' + lib + '"))(' + Functions.getTable('x') + '.length, this);'); }); print(postParts[1]); @@ -1387,6 +1503,8 @@ function JSify(data, functionsOnly, givenFunctions) { return IGNORED_FUNCTIONS.indexOf(func.ident) < 0; })) + '\n'); + PassManager.serialize(); + return null; } diff --git a/src/library.js b/src/library.js index 0b59b404..be57e445 100644 --- a/src/library.js +++ b/src/library.js @@ -20,10 +20,11 @@ LibraryManager.library = { // File system base. // ========================================================================== - stdin: 0, - stdout: 0, - stderr: 0, - _impure_ptr: 0, + // keep this low in memory, because we flatten arrays with them in them + stdin: 'allocate(1, "i32*", ALLOC_STACK)', + stdout: 'allocate(1, "i32*", ALLOC_STACK)', + stderr: 'allocate(1, "i32*", ALLOC_STACK)', + _impure_ptr: 'allocate(1, "i32*", ALLOC_STACK)', $FS__deps: ['$ERRNO_CODES', '__setErrNo', 'stdin', 'stdout', 'stderr', '_impure_ptr'], $FS__postset: '__ATINIT__.unshift({ func: function() { if (!Module["noFSInit"] && !FS.init.initialized) FS.init() } });' + @@ -572,10 +573,10 @@ LibraryManager.library = { eof: false, ungotten: [] }; - // Allocate these on the stack (and never free, we are called from ATINIT or earlier), to keep their locations low - _stdin = allocate([1], 'void*', ALLOC_STACK); - _stdout = allocate([2], 'void*', ALLOC_STACK); - _stderr = allocate([3], 'void*', ALLOC_STACK); + assert(Math.max(_stdin, _stdout, _stderr) < 128); // make sure these are low, we flatten arrays with these + {{{ makeSetValue(makeGlobalUse('_stdin'), 0, 1, 'void*') }}}; + {{{ makeSetValue(makeGlobalUse('_stdout'), 0, 2, 'void*') }}}; + {{{ makeSetValue(makeGlobalUse('_stderr'), 0, 3, 'void*') }}}; // Other system paths FS.createPath('/', 'dev/shm/tmp', true, true); // temp files @@ -591,9 +592,9 @@ LibraryManager.library = { FS.checkStreams(); assert(FS.streams.length < 1024); // at this early stage, we should not have a large set of file descriptors - just a few #endif - __impure_ptr = allocate([ allocate( + allocate([ allocate( {{{ Runtime.QUANTUM_SIZE === 4 ? '[0, 0, 0, 0, _stdin, 0, 0, 0, _stdout, 0, 0, 0, _stderr, 0, 0, 0]' : '[0, _stdin, _stdout, _stderr]' }}}, - 'void*', ALLOC_STATIC) ], 'void*', ALLOC_STATIC); + 'void*', ALLOC_STATIC) ], 'void*', ALLOC_NONE, {{{ makeGlobalUse('__impure_ptr') }}}); }, quit: function() { @@ -1226,6 +1227,15 @@ LibraryManager.library = { // http://pubs.opengroup.org/onlinepubs/009695399/functions/creat.html return _open(path, {{{ cDefine('O_WRONLY') }}} | {{{ cDefine('O_CREAT') }}} | {{{ cDefine('O_TRUNC') }}}, allocate([mode, 0, 0, 0], 'i32', ALLOC_STACK)); }, + mkstemp__deps: ['creat'], + mkstemp: function(template) { + if (!_mkstemp.counter) _mkstemp.counter = 0; + var c = (_mkstemp.counter++).toString(); + var rep = 'XXXXXX'; + while (c.length < rep.length) c = '0' + c; + writeArrayToMemory(intArrayFromString(c), template + Pointer_stringify(template).indexOf(rep)); + return _creat(template, 0600); + }, fcntl__deps: ['$FS', '__setErrNo', '$ERRNO_CODES', '__flock_struct_layout'], fcntl: function(fildes, cmd, varargs, dup2) { // int fcntl(int fildes, int cmd, ...); @@ -3068,7 +3078,7 @@ LibraryManager.library = { getchar: function() { // int getchar(void); // http://pubs.opengroup.org/onlinepubs/000095399/functions/getchar.html - return _fgetc({{{ makeGetValue('_stdin', '0', 'void*') }}}); + return _fgetc({{{ makeGetValue(makeGlobalUse('_stdin'), '0', 'void*') }}}); }, fgetpos__deps: ['$FS', '__setErrNo', '$ERRNO_CODES'], fgetpos: function(stream, pos) { @@ -3113,7 +3123,7 @@ LibraryManager.library = { gets: function(s) { // char *gets(char *s); // http://pubs.opengroup.org/onlinepubs/000095399/functions/gets.html - return _fgets(s, 1e6, {{{ makeGetValue('_stdin', '0', 'void*') }}}); + return _fgets(s, 1e6, {{{ makeGetValue(makeGlobalUse('_stdin'), '0', 'void*') }}}); }, fileno: function(stream) { // int fileno(FILE *stream); @@ -3185,7 +3195,7 @@ LibraryManager.library = { putchar: function(c) { // int putchar(int c); // http://pubs.opengroup.org/onlinepubs/000095399/functions/putchar.html - return _fputc(c, {{{ makeGetValue('_stdout', '0', 'void*') }}}); + return _fputc(c, {{{ makeGetValue(makeGlobalUse('_stdout'), '0', 'void*') }}}); }, putchar_unlocked: 'putchar', fputs__deps: ['write', 'strlen'], @@ -3199,7 +3209,7 @@ LibraryManager.library = { // int puts(const char *s); // http://pubs.opengroup.org/onlinepubs/000095399/functions/puts.html // NOTE: puts() always writes an extra newline. - var stdout = {{{ makeGetValue('_stdout', '0', 'void*') }}}; + var stdout = {{{ makeGetValue(makeGlobalUse('_stdout'), '0', 'void*') }}}; var ret = _fputs(s, stdout); if (ret < 0) { return ret; @@ -3467,7 +3477,7 @@ LibraryManager.library = { scanf: function(format, varargs) { // int scanf(const char *restrict format, ... ); // http://pubs.opengroup.org/onlinepubs/000095399/functions/scanf.html - var stdin = {{{ makeGetValue('_stdin', '0', 'void*') }}}; + var stdin = {{{ makeGetValue(makeGlobalUse('_stdin'), '0', 'void*') }}}; return _fscanf(stdin, format, varargs); }, sscanf__deps: ['_scanString'], @@ -3506,7 +3516,7 @@ LibraryManager.library = { printf: function(format, varargs) { // int printf(const char *restrict format, ...); // http://pubs.opengroup.org/onlinepubs/000095399/functions/printf.html - var stdout = {{{ makeGetValue('_stdout', '0', 'void*') }}}; + var stdout = {{{ makeGetValue(makeGlobalUse('_stdout'), '0', 'void*') }}}; return _fprintf(stdout, format, varargs); }, sprintf__deps: ['snprintf'], @@ -3535,7 +3545,7 @@ LibraryManager.library = { _ZNSo3putEc: 'putchar', _ZNSo5flushEv__deps: ['fflush', 'stdout'], _ZNSo5flushEv: function() { - _fflush({{{ makeGetValue('_stdout', '0', 'void*') }}}); + _fflush({{{ makeGetValue(makeGlobalUse('_stdout'), '0', 'void*') }}}); }, // ========================================================================== @@ -3593,6 +3603,10 @@ LibraryManager.library = { // stdlib.h // ========================================================================== + // tiny, fake malloc/free implementation. If the program actually uses malloc, + // a compiled version will be used; this will only be used if the runtime + // needs to allocate something, for which this is good enough if otherwise + // no malloc is needed. malloc: function(bytes) { /* Over-allocate to make sure it is byte-aligned by 8. * This will leak memory, but this is only the dummy @@ -3602,14 +3616,7 @@ LibraryManager.library = { ptr = Runtime.staticAlloc(bytes + 8); return (ptr+8) & 0xFFFFFFF8; }, - _Znwj: 'malloc', - _Znaj: 'malloc', - _Znam: 'malloc', - _Znwm: 'malloc', - free: function(){}, - _ZdlPv: 'free', - _ZdaPv: 'free', calloc__deps: ['malloc'], calloc: function(n, s) { @@ -3637,7 +3644,9 @@ LibraryManager.library = { }, bsearch: function(key, base, num, size, compar) { - var cmp = FUNCTION_TABLE[compar]; + var cmp = function(x, y) { + return Runtime.dynCall('iii', compar, [x, y]) + }; var left = 0; var right = num; var mid, test, addr; @@ -3831,7 +3840,7 @@ LibraryManager.library = { #if USE_TYPED_ARRAYS == 2 if (bits == 64) { - ret = [{{{ splitI64('ret') }}}]; + {{{ makeStructuralReturn(splitI64('ret')) }}}; } #endif @@ -3882,13 +3891,7 @@ LibraryManager.library = { } if (!ok) { ___setErrNo(ERRNO_CODES.EINVAL); - return [0, 0]; - } - - try { - i64Math.fromString(Pointer_stringify(start, str - start), finalBase, min, max, unsign); - } catch(e) { - ___setErrNo(ERRNO_CODES.ERANGE); // not quite correct + {{{ makeStructuralReturn(['0', '0']) }}}; } // Set end pointer. @@ -3896,9 +3899,13 @@ LibraryManager.library = { {{{ makeSetValue('endptr', 0, 'str', '*') }}} } - var ret = i64Math.result.slice(0); + try { + i64Math.fromString(Pointer_stringify(start, str - start), finalBase, min, max, unsign); + } catch(e) { + ___setErrNo(ERRNO_CODES.ERANGE); // not quite correct + } - return ret; + {{{ makeStructuralReturn([makeGetTempDouble(0), makeGetTempDouble(1)]) }}}; }, #endif strtoll__deps: ['_parseInt64'], @@ -3939,11 +3946,13 @@ LibraryManager.library = { }, qsort__deps: ['memcpy'], - qsort: function(base, num, size, comparator) { + qsort: function(base, num, size, cmp) { if (num == 0 || size == 0) return; // forward calls to the JavaScript sort method // first, sort the items logically - comparator = FUNCTION_TABLE[comparator]; + var comparator = function(x, y) { + return Runtime.dynCall('iii', cmp, [x, y]); + } var keys = []; for (var i = 0; i < num; i++) keys.push(i); keys.sort(function(a, b) { @@ -3959,9 +3968,10 @@ LibraryManager.library = { _free(temp); }, - environ: null, - __environ: null, - __buildEnvironment__deps: ['environ', '__environ'], + environ: 'allocate(1, "i32*", ALLOC_STACK)', + __environ__deps: ['environ'], + __environ: '_environ', + __buildEnvironment__deps: ['__environ'], __buildEnvironment: function(env) { // WARNING: Arbitrary limit! var MAX_ENV_VALUES = 64; @@ -3970,7 +3980,8 @@ LibraryManager.library = { // Statically allocate memory for the environment. var poolPtr; var envPtr; - if (_environ === null) { + if (!___buildEnvironment.called) { + ___buildEnvironment.called = true; // Set default values. Use string keys for Closure Compiler compatibility. ENV['USER'] = 'root'; ENV['PATH'] = '/'; @@ -3983,11 +3994,9 @@ LibraryManager.library = { envPtr = allocate(MAX_ENV_VALUES * {{{ Runtime.QUANTUM_SIZE }}}, 'i8*', ALLOC_STATIC); {{{ makeSetValue('envPtr', '0', 'poolPtr', 'i8*') }}} - _environ = allocate([envPtr], 'i8**', ALLOC_STATIC); - // Set up global variable alias. - ___environ = _environ; + {{{ makeSetValue(makeGlobalUse('_environ'), 0, 'envPtr', 'i8*') }}}; } else { - envPtr = {{{ makeGetValue('_environ', '0', 'i8**') }}}; + envPtr = {{{ makeGetValue(makeGlobalUse('_environ'), '0', 'i8**') }}}; poolPtr = {{{ makeGetValue('envPtr', '0', 'i8*') }}}; } @@ -4182,55 +4191,22 @@ LibraryManager.library = { memcpy__inline: function (dest, src, num, align) { var ret = ''; #if ASSERTIONS - ret += "assert(" + num + " % 1 === 0, 'memcpy given ' + " + num + " + ' bytes to copy. Problem with quantum=1 corrections perhaps?');"; + ret += "assert(" + num + " % 1 === 0);"; //, 'memcpy given ' + " + num + " + ' bytes to copy. Problem with quantum=1 corrections perhaps?');"; #endif ret += makeCopyValues(dest, src, num, 'null', null, align); return ret; }, - memcpy: function (dest, src, num, align) { -#if ASSERTIONS - assert(num % 1 === 0, 'memcpy given ' + num + ' bytes to copy. Problem with quantum=1 corrections perhaps?'); -#endif -#if USE_TYPED_ARRAYS == 2 - if (num >= {{{ SEEK_OPTIMAL_ALIGN_MIN }}} && src % 2 == dest % 2) { - // This is unaligned, but quite large, and potentially alignable, so work hard to get to aligned settings - if (src % 4 == dest % 4) { - var stop = src + num; - while (src % 4) { // no need to check for stop, since we have large num - HEAP8[dest++] = HEAP8[src++]; - } - var src4 = src >> 2, dest4 = dest >> 2, stop4 = stop >> 2; - while (src4 < stop4) { - HEAP32[dest4++] = HEAP32[src4++]; - } - src = src4 << 2; - dest = dest4 << 2; - while (src < stop) { - HEAP8[dest++] = HEAP8[src++]; - } - } else { - var stop = src + num; - if (src % 2) { // no need to check for stop, since we have large num - HEAP8[dest++] = HEAP8[src++]; - } - var src2 = src >> 1, dest2 = dest >> 1, stop2 = stop >> 1; - while (src2 < stop2) { - HEAP16[dest2++] = HEAP16[src2++]; - } - src = src2 << 1; - dest = dest2 << 1; - if (src < stop) { - HEAP8[dest++] = HEAP8[src++]; - } - } - } else { - while (num--) { - HEAP8[dest++] = HEAP8[src++]; - } + + memcpy: function (dest, src, num) { + // simple version, in general it should not be used - we should pull it in from libc + if (!_memcpy.shown) { + _memcpy.shown = true; + Module.printErr('warning: library.js memcpy should not be running, it is only for testing!'); } -#else - {{{ makeCopyValues('dest', 'src', 'num', 'null', null, 'align') }}}; #endif + while (num--) { + HEAP8[dest++] = HEAP8[src++]; + } }, llvm_memcpy_i32: 'memcpy', @@ -4250,7 +4226,7 @@ LibraryManager.library = { {{{ makeCopyValues('dest', 'src', 1, 'null', null, 1) }}}; } } else { - _memcpy(dest, src, num, align); + _memcpy(dest, src, num); } }, llvm_memmove_i32: 'memmove', @@ -4504,6 +4480,7 @@ LibraryManager.library = { } while (val); return 0; }, + index: 'strchr', strrchr__deps: ['strlen'], strrchr: function(ptr, chr) { @@ -4514,6 +4491,7 @@ LibraryManager.library = { } while (ptr2 >= ptr); return 0; }, + rindex: 'strrchr', strdup: function(ptr) { var len = String_len(ptr); @@ -4801,9 +4779,8 @@ LibraryManager.library = { // ========================================================================== llvm_va_start__inline: function(ptr) { - // varargs - we received a pointer to the varargs as a final 'extra' parameter - var data = 'arguments[' + Framework.currItem.funcData.ident + '.length]'; - return makeSetValue(ptr, 0, data, 'void*'); + // varargs - we received a pointer to the varargs as a final 'extra' parameter called 'varrp' + return makeSetValue(ptr, 0, 'varrp', 'void*'); }, llvm_va_end: function() {}, @@ -4832,7 +4809,7 @@ LibraryManager.library = { var retl = _llvm_bswap_i32(h)>>>0; var reth = _llvm_bswap_i32(l)>>>0; #if USE_TYPED_ARRAYS == 2 - return [retl, reth]; + {{{ makeStructuralReturn(['retl', 'reth']) }}}; #else throw 'unsupported'; #endif @@ -4852,7 +4829,7 @@ LibraryManager.library = { var ret = _llvm_ctlz_i32(h); if (ret == 32) ret += _llvm_ctlz_i32(l); #if USE_TYPED_ARRAYS == 2 - return [ret, 0]; + {{{ makeStructuralReturn(['ret', '0']) }}}; #else return ret; #endif @@ -4896,13 +4873,13 @@ LibraryManager.library = { __cxa_throw: function(ptr, type, destructor) { if (!___cxa_throw.initialized) { try { - {{{ makeSetValue('__ZTVN10__cxxabiv119__pointer_type_infoE', '0', '0', 'i32') }}}; // Workaround for libcxxabi integration bug + {{{ makeSetValue(makeGlobalUse('__ZTVN10__cxxabiv119__pointer_type_infoE'), '0', '0', 'i32') }}}; // Workaround for libcxxabi integration bug } catch(e){} try { - {{{ makeSetValue('__ZTVN10__cxxabiv117__class_type_infoE', '0', '1', 'i32') }}}; // Workaround for libcxxabi integration bug + {{{ makeSetValue(makeGlobalUse('__ZTVN10__cxxabiv117__class_type_infoE'), '0', '1', 'i32') }}}; // Workaround for libcxxabi integration bug } catch(e){} try { - {{{ makeSetValue('__ZTVN10__cxxabiv120__si_class_type_infoE', '0', '2', 'i32') }}}; // Workaround for libcxxabi integration bug + {{{ makeSetValue(makeGlobalUse('__ZTVN10__cxxabiv120__si_class_type_infoE'), '0', '2', 'i32') }}}; // Workaround for libcxxabi integration bug } catch(e){} ___cxa_throw.initialized = true; } @@ -4951,14 +4928,18 @@ LibraryManager.library = { return; } // Clear state flag. - __THREW__ = false; +#if ASM_JS + asm.setThrew(0); +#else + __THREW__ = 0; +#endif // Clear type. {{{ makeSetValue('_llvm_eh_exception.buf', QUANTUM_SIZE, '0', 'void*') }}} // Call destructor if one is registered then clear it. var ptr = {{{ makeGetValue('_llvm_eh_exception.buf', '0', 'void*') }}}; var destructor = {{{ makeGetValue('_llvm_eh_exception.buf', 2 * QUANTUM_SIZE, 'void*') }}}; if (destructor) { - FUNCTION_TABLE[destructor](ptr); + Runtime.dynCall('vi', destructor, [ptr]); {{{ makeSetValue('_llvm_eh_exception.buf', 2 * QUANTUM_SIZE, '0', 'i32') }}} } // Free ptr if it isn't null. @@ -4996,20 +4977,20 @@ LibraryManager.library = { __cxa_is_number_type: function(type) { var isNumber = false; - try { if (type == __ZTIi) isNumber = true } catch(e){} - try { if (type == __ZTIj) isNumber = true } catch(e){} - try { if (type == __ZTIl) isNumber = true } catch(e){} - try { if (type == __ZTIm) isNumber = true } catch(e){} - try { if (type == __ZTIx) isNumber = true } catch(e){} - try { if (type == __ZTIy) isNumber = true } catch(e){} - try { if (type == __ZTIf) isNumber = true } catch(e){} - try { if (type == __ZTId) isNumber = true } catch(e){} - try { if (type == __ZTIe) isNumber = true } catch(e){} - try { if (type == __ZTIc) isNumber = true } catch(e){} - try { if (type == __ZTIa) isNumber = true } catch(e){} - try { if (type == __ZTIh) isNumber = true } catch(e){} - try { if (type == __ZTIs) isNumber = true } catch(e){} - try { if (type == __ZTIt) isNumber = true } catch(e){} + try { if (type == {{{ makeGlobalUse('__ZTIi') }}}) isNumber = true } catch(e){} + try { if (type == {{{ makeGlobalUse('__ZTIj') }}}) isNumber = true } catch(e){} + try { if (type == {{{ makeGlobalUse('__ZTIl') }}}) isNumber = true } catch(e){} + try { if (type == {{{ makeGlobalUse('__ZTIm') }}}) isNumber = true } catch(e){} + try { if (type == {{{ makeGlobalUse('__ZTIx') }}}) isNumber = true } catch(e){} + try { if (type == {{{ makeGlobalUse('__ZTIy') }}}) isNumber = true } catch(e){} + try { if (type == {{{ makeGlobalUse('__ZTIf') }}}) isNumber = true } catch(e){} + try { if (type == {{{ makeGlobalUse('__ZTId') }}}) isNumber = true } catch(e){} + try { if (type == {{{ makeGlobalUse('__ZTIe') }}}) isNumber = true } catch(e){} + try { if (type == {{{ makeGlobalUse('__ZTIc') }}}) isNumber = true } catch(e){} + try { if (type == {{{ makeGlobalUse('__ZTIa') }}}) isNumber = true } catch(e){} + try { if (type == {{{ makeGlobalUse('__ZTIh') }}}) isNumber = true } catch(e){} + try { if (type == {{{ makeGlobalUse('__ZTIs') }}}) isNumber = true } catch(e){} + try { if (type == {{{ makeGlobalUse('__ZTIt') }}}) isNumber = true } catch(e){} return isNumber; }, @@ -5040,12 +5021,12 @@ LibraryManager.library = { // return the type of the catch block which should be called. for (var i = 0; i < typeArray.length; i++) { if (___cxa_does_inherit(typeArray[i], throwntype, thrown)) - return { f0:thrown, f1:typeArray[i] }; + {{{ makeStructuralReturn(['thrown', 'typeArray[i]']) }}}; } // Shouldn't happen unless we have bogus data in typeArray // or encounter a type for which emscripten doesn't have suitable // typeinfo defined. Best-efforts match just in case. - return { f0:thrown, f1 :throwntype }; + {{{ makeStructuralReturn(['thrown', 'throwntype']) }}}; }, // Recursively walks up the base types of 'possibilityType' @@ -5087,6 +5068,8 @@ LibraryManager.library = { } }, + _ZNSt9exceptionD2Ev: function(){}, // XXX a dependency of dlmalloc, but not actually needed if libcxx is not anyhow included + // RTTI hacks for exception handling, defining type_infos for common types. // The values are dummies. We simply use the addresses of these statically // allocated variables as unique identifiers. @@ -5111,73 +5094,51 @@ LibraryManager.library = { llvm_uadd_with_overflow_i8: function(x, y) { x = x & 0xff; y = y & 0xff; - return { - f0: (x+y) & 0xff, - f1: x+y > 255 - }; + {{{ makeStructuralReturn(['(x+y) & 0xff', 'x+y > 255']) }}}; }, llvm_umul_with_overflow_i8: function(x, y) { x = x & 0xff; y = y & 0xff; - return { - f0: (x*y) & 0xff, - f1: x*y > 255 - }; + {{{ makeStructuralReturn(['(x*y) & 0xff', 'x*y > 255']) }}}; }, llvm_uadd_with_overflow_i16: function(x, y) { x = x & 0xffff; y = y & 0xffff; - return { - f0: (x+y) & 0xffff, - f1: x+y > 65535 - }; + {{{ makeStructuralReturn(['(x+y) & 0xffff', 'x+y > 65535']) }}}; }, llvm_umul_with_overflow_i16: function(x, y) { x = x & 0xffff; y = y & 0xffff; - return { - f0: (x*y) & 0xffff, - f1: x*y > 65535 - }; + {{{ makeStructuralReturn(['(x*y) & 0xffff', 'x*y > 65535']) }}}; }, llvm_uadd_with_overflow_i32: function(x, y) { x = x>>>0; y = y>>>0; - return { - f0: (x+y)>>>0, - f1: x+y > 4294967295 - }; + {{{ makeStructuralReturn(['(x+y)>>>0', 'x+y > 4294967295']) }}}; }, llvm_umul_with_overflow_i32: function(x, y) { x = x>>>0; y = y>>>0; - return { - f0: (x*y)>>>0, - f1: x*y > 4294967295 - }; + {{{ makeStructuralReturn(['(x*y)>>>0', 'x*y > 4294967295']) }}}; }, llvm_uadd_with_overflow_i64__deps: [function() { Types.preciseI64MathUsed = 1 }], llvm_uadd_with_overflow_i64: function(xl, xh, yl, yh) { i64Math.add(xl, xh, yl, yh); - return { - f0: i64Math.result, - f1: 0 // XXX Need to hack support for this in long.js - }; + {{{ makeStructuralReturn(['HEAP32[tempDoublePtr>>2]', 'HEAP32[tempDoublePtr+4>>2]', '0']) }}}; + // XXX Need to hack support for second param in long.js }, llvm_umul_with_overflow_i64__deps: [function() { Types.preciseI64MathUsed = 1 }], llvm_umul_with_overflow_i64: function(xl, xh, yl, yh) { - i64Math.mul(xl, xh, yl, yh); - return { - f0: i64Math.result, - f1: 0 // XXX Need to hack support for this in long.js - }; + i64Math.multiply(xl, xh, yl, yh); + {{{ makeStructuralReturn(['HEAP32[tempDoublePtr>>2]', 'HEAP32[tempDoublePtr+4>>2]', '0']) }}}; + // XXX Need to hack support for second param in long.js }, llvm_stacksave: function() { @@ -5617,7 +5578,7 @@ LibraryManager.library = { } try { - var lib_module = eval(lib_data)(FUNCTION_TABLE.length); + var lib_module = eval(lib_data)({{{ Functions.getTable('x') }}}.length); } catch (e) { #if ASSERTIONS Module.printErr('Error in loading dynamic library: ' + e); @@ -5690,9 +5651,9 @@ LibraryManager.library = { } else { var result = lib.module[symbol]; if (typeof result == 'function') { - FUNCTION_TABLE.push(result); - FUNCTION_TABLE.push(0); - result = FUNCTION_TABLE.length - 2; + {{{ Functions.getTable('x') }}}.push(result); + {{{ Functions.getTable('x') }}}.push(0); + result = {{{ Functions.getTable('x') }}}.length - 2; lib.cached_functions = result; } return result; @@ -5760,11 +5721,11 @@ LibraryManager.library = { 'tm_gmtoff', 'tm_zone'], '%struct.tm'), // Statically allocated time struct. - __tm_current: 0, + __tm_current: 'allocate({{{ Runtime.QUANTUM_SIZE }}}*26, "i8", ALLOC_STACK)', // Statically allocated timezone strings. __tm_timezones: {}, // Statically allocated time strings. - __tm_formatted: 0, + __tm_formatted: 'allocate({{{ Runtime.QUANTUM_SIZE }}}*26, "i8", ALLOC_STACK)', mktime__deps: ['__tm_struct_layout', 'tzset'], mktime: function(tmPtr) { @@ -5787,7 +5748,6 @@ LibraryManager.library = { gmtime__deps: ['malloc', '__tm_struct_layout', '__tm_current', 'gmtime_r'], gmtime: function(time) { - if (!___tm_current) ___tm_current = _malloc(___tm_struct_layout.__size__); return _gmtime_r(time, ___tm_current); }, @@ -5821,8 +5781,8 @@ LibraryManager.library = { timegm__deps: ['mktime'], timegm: function(tmPtr) { _tzset(); - var offset = {{{ makeGetValue('__timezone', 0, 'i32') }}}; - var daylight = {{{ makeGetValue('__daylight', 0, 'i32') }}}; + var offset = {{{ makeGetValue(makeGlobalUse('__timezone'), 0, 'i32') }}}; + var daylight = {{{ makeGetValue(makeGlobalUse('__daylight'), 0, 'i32') }}}; daylight = (daylight == 1) ? 60 * 60 : 0; var ret = _mktime(tmPtr) + offset - daylight; return ret; @@ -5830,7 +5790,6 @@ LibraryManager.library = { localtime__deps: ['malloc', '__tm_struct_layout', '__tm_current', 'localtime_r'], localtime: function(time) { - if (!___tm_current) ___tm_current = _malloc(___tm_struct_layout.__size__); return _localtime_r(time, ___tm_current); }, @@ -5866,7 +5825,6 @@ LibraryManager.library = { asctime__deps: ['malloc', '__tm_formatted', 'asctime_r'], asctime: function(tmPtr) { - if (!___tm_formatted) ___tm_formatted = _malloc(26); return _asctime_r(tmPtr, ___tm_formatted); }, @@ -5901,29 +5859,27 @@ LibraryManager.library = { // TODO: Initialize these to defaults on startup from system settings. // Note: glibc has one fewer underscore for all of these. Also used in other related functions (timegm) - _tzname: null, - _daylight: null, - _timezone: null, + _tzname: 'allocate({{{ 2*Runtime.QUANTUM_SIZE }}}, "i32*", ALLOC_STACK)', + _daylight: 'allocate(1, "i32*", ALLOC_STACK)', + _timezone: 'allocate(1, "i32*", ALLOC_STACK)', tzset__deps: ['_tzname', '_daylight', '_timezone'], tzset: function() { // TODO: Use (malleable) environment variables instead of system settings. - if (__tzname) return; // glibc does not need the double __ + if (_tzset.called) return; + _tzset.called = true; - __timezone = _malloc({{{ Runtime.QUANTUM_SIZE }}}); - {{{ makeSetValue('__timezone', '0', '-(new Date()).getTimezoneOffset() * 60', 'i32') }}} + {{{ makeSetValue(makeGlobalUse('__timezone'), '0', '-(new Date()).getTimezoneOffset() * 60', 'i32') }}} - __daylight = _malloc({{{ Runtime.QUANTUM_SIZE }}}); var winter = new Date(2000, 0, 1); var summer = new Date(2000, 6, 1); - {{{ makeSetValue('__daylight', '0', 'Number(winter.getTimezoneOffset() != summer.getTimezoneOffset())', 'i32') }}} + {{{ makeSetValue(makeGlobalUse('__daylight'), '0', 'Number(winter.getTimezoneOffset() != summer.getTimezoneOffset())', 'i32') }}} var winterName = 'GMT'; // XXX do not rely on browser timezone info, it is very unpredictable | winter.toString().match(/\(([A-Z]+)\)/)[1]; var summerName = 'GMT'; // XXX do not rely on browser timezone info, it is very unpredictable | summer.toString().match(/\(([A-Z]+)\)/)[1]; var winterNamePtr = allocate(intArrayFromString(winterName), 'i8', ALLOC_NORMAL); var summerNamePtr = allocate(intArrayFromString(summerName), 'i8', ALLOC_NORMAL); - __tzname = _malloc(2 * {{{ Runtime.QUANTUM_SIZE }}}); // glibc does not need the double __ - {{{ makeSetValue('__tzname', '0', 'winterNamePtr', 'i32') }}} - {{{ makeSetValue('__tzname', Runtime.QUANTUM_SIZE, 'summerNamePtr', 'i32') }}} + {{{ makeSetValue(makeGlobalUse('__tzname'), '0', 'winterNamePtr', 'i32') }}} + {{{ makeSetValue(makeGlobalUse('__tzname'), Runtime.QUANTUM_SIZE, 'summerNamePtr', 'i32') }}} }, stime__deps: ['$ERRNO_CODES', '__setErrNo'], @@ -6084,18 +6040,26 @@ LibraryManager.library = { }, sigemptyset: function(set) { // int sigemptyset(sigset_t *set); - // TODO: Implement for real; don't hardcode offsets. - {{{ makeSetValue('set', '0', '0', 'i32') }}} - {{{ makeSetValue('set', '4', '0', 'i32') }}} - {{{ makeSetValue('set', '8', '0', 'i32') }}} - {{{ makeSetValue('set', '12', '0', 'i32') }}} + {{{ makeSetValue('set', '0', '0', 'i32') }}}; + return 0; + }, + sigfillset: function(set) { + {{{ makeSetValue('set', '0', '-1>>>0', 'i32') }}}; + return 0; + }, + sigaddset: function(set, signum) { + {{{ makeSetValue('set', '0', makeGetValue('set', '0', 'i32') + '| (1 << (signum-1))', 'i32') }}}; + return 0; + }, + sigdelset: function(set, signum) { + {{{ makeSetValue('set', '0', makeGetValue('set', '0', 'i32') + '& (~(1 << (signum-1)))', 'i32') }}}; return 0; }, - sigfillset: 'sigemptyset', - sigdelset: 'sigemptyset', + sigismember: function(set, signum) { + return {{{ makeGetValue('set', '0', 'i32') }}} & (1 << (signum-1)); + }, sigaction: function(set) { - // int sigemptyset(sigset_t *set); - // TODO: Implement for real. + // TODO: return 0; }, sigprocmask: 'sigaction', @@ -6141,6 +6105,8 @@ LibraryManager.library = { return 0; }, + freelocale: function(locale) {}, + uselocale: function(locale) { return 0; }, @@ -6580,6 +6546,8 @@ LibraryManager.library = { pthread_mutexattr_destroy: function() {}, pthread_mutex_lock: function() {}, pthread_mutex_unlock: function() {}, + pthread_cond_init: function() {}, + pthread_cond_destroy: function() {}, pthread_cond_broadcast: function() {}, pthread_self: function() { //FIXME: assumes only a single thread @@ -6613,7 +6581,7 @@ LibraryManager.library = { pthread_once: function(ptr, func) { if (!_pthread_once.seen) _pthread_once.seen = {}; if (ptr in _pthread_once.seen) return; - FUNCTION_TABLE[func](); + Runtime.dynCall('v', func); _pthread_once.seen[ptr] = 1; }, @@ -6631,7 +6599,7 @@ LibraryManager.library = { }, pthread_cleanup_push: function(routine, arg) { - __ATEXIT__.push({ func: function() { FUNCTION_TABLE[routine](arg) } }) + __ATEXIT__.push({ func: function() { Runtime.dynCall('vi', routine, [arg]) } }) _pthread_cleanup_push.level = __ATEXIT__.length; }, @@ -6777,8 +6745,12 @@ LibraryManager.library = { $Sockets__deps: ['__setErrNo', '$ERRNO_CODES'], $Sockets: { + BACKEND_WEBSOCKETS: 0, + BACKEND_WEBRTC: 1, BUFFER_SIZE: 10*1024, // initial size MAX_BUFFER_SIZE: 10*1024*1024, // maximum size we will grow the buffer + + backend: 0, // default to websockets nextFd: 1, fds: {}, sockaddr_in_layout: Runtime.generateStructInfo([ @@ -6796,24 +6768,138 @@ LibraryManager.library = { ['i32', 'msg_controllen'], ['i32', 'msg_flags'], ]), + + backends: { + 0: { // websockets + connect: function(info) { + console.log('opening ws://' + info.host + ':' + info.port); + info.socket = new WebSocket('ws://' + info.host + ':' + info.port, ['binary']); + info.socket.binaryType = 'arraybuffer'; + + var i32Temp = new Uint32Array(1); + var i8Temp = new Uint8Array(i32Temp.buffer); + + info.inQueue = []; + if (!info.stream) { + var partialBuffer = null; // inQueue contains full dgram messages; this buffers incomplete data. Must begin with the beginning of a message + } + + info.socket.onmessage = function(event) { + assert(typeof event.data !== 'string' && event.data.byteLength); // must get binary data! + var data = new Uint8Array(event.data); // make a typed array view on the array buffer +#if SOCKET_DEBUG + Module.print(['onmessage', data.length, '|', Array.prototype.slice.call(data)]); +#endif + if (info.stream) { + info.inQueue.push(data); + } else { + // we added headers with message sizes, read those to find discrete messages + if (partialBuffer) { + // append to the partial buffer + var newBuffer = new Uint8Array(partialBuffer.length + data.length); + newBuffer.set(partialBuffer); + newBuffer.set(data, partialBuffer.length); + // forget the partial buffer and work on data + data = newBuffer; + partialBuffer = null; + } + var currPos = 0; + while (currPos+4 < data.length) { + i8Temp.set(data.subarray(currPos, currPos+4)); + var currLen = i32Temp[0]; + assert(currLen > 0); + if (currPos + 4 + currLen > data.length) { + break; // not enough data has arrived + } + currPos += 4; +#if SOCKET_DEBUG + Module.print(['onmessage message', currLen, '|', Array.prototype.slice.call(data.subarray(currPos, currPos+currLen))]); +#endif + info.inQueue.push(data.subarray(currPos, currPos+currLen)); + currPos += currLen; + } + // If data remains, buffer it + if (currPos < data.length) { + partialBuffer = data.subarray(currPos); + } + } + } + function send(data) { + // TODO: if browser accepts views, can optimize this +#if SOCKET_DEBUG + Module.print('sender actually sending ' + Array.prototype.slice.call(data)); +#endif + // ok to use the underlying buffer, we created data and know that the buffer starts at the beginning + info.socket.send(data.buffer); + } + var outQueue = []; + var intervalling = false, interval; + function trySend() { + if (info.socket.readyState != info.socket.OPEN) { + if (!intervalling) { + intervalling = true; + console.log('waiting for socket in order to send'); + interval = setInterval(trySend, 100); + } + return; + } + for (var i = 0; i < outQueue.length; i++) { + send(outQueue[i]); + } + outQueue.length = 0; + if (intervalling) { + intervalling = false; + clearInterval(interval); + } + } + info.sender = function(data) { + if (!info.stream) { + // add a header with the message size + var header = new Uint8Array(4); + i32Temp[0] = data.length; + header.set(i8Temp); + outQueue.push(header); + } + outQueue.push(new Uint8Array(data)); + trySend(); + }; + } + }, + 1: { // webrtc + } + } + }, + + emscripten_set_network_backend__deps: ['$Sockets'], + emscripten_set_network_backend: function(backend) { + Sockets.backend = backend; }, socket__deps: ['$Sockets'], socket: function(family, type, protocol) { var fd = Sockets.nextFd++; + assert(fd < 64); // select() assumes socket fd values are in 0..63 + var stream = type == {{{ cDefine('SOCK_STREAM') }}}; + if (protocol) { + assert(stream == (protocol == {{{ cDefine('IPPROTO_TCP') }}})); // if stream, must be tcp + } + if (Sockets.backend == Sockets.BACKEND_WEBRTC) { + assert(!stream); // If WebRTC, we can only support datagram, not stream + } Sockets.fds[fd] = { - connected: false + connected: false, + stream: stream }; return fd; }, - connect__deps: ['$Sockets', '_inet_ntop_raw', 'ntohs', 'gethostbyname'], + connect__deps: ['$Sockets', '_inet_ntop_raw', 'htons', 'gethostbyname'], connect: function(fd, addr, addrlen) { var info = Sockets.fds[fd]; if (!info) return -1; info.connected = true; info.addr = getValue(addr + Sockets.sockaddr_in_layout.sin_addr, 'i32'); - info.port = _ntohs(getValue(addr + Sockets.sockaddr_in_layout.sin_port, 'i16')); + info.port = _htons(getValue(addr + Sockets.sockaddr_in_layout.sin_port, 'i16')); info.host = __inet_ntop_raw(info.addr); // Support 'fake' ips from gethostbyname var parts = info.host.split('.'); @@ -6823,69 +6909,7 @@ LibraryManager.library = { info.host = _gethostbyname.table[low + 0xff*high]; assert(info.host, 'problem translating fake ip ' + parts); } - console.log('opening ws://' + info.host + ':' + info.port); - info.socket = new WebSocket('ws://' + info.host + ':' + info.port, ['binary']); - info.socket.binaryType = 'arraybuffer'; - info.buffer = new Uint8Array(Sockets.BUFFER_SIZE); - info.bufferWrite = info.bufferRead = 0; - info.socket.onmessage = function (event) { - assert(typeof event.data !== 'string' && event.data.byteLength); // must get binary data! - var data = new Uint8Array(event.data); // make a typed array view on the array buffer - var len = data.length; -#if SOCKET_DEBUG - Module.print(['onmessage', window.location, data, len, '|', Array.prototype.slice.call(data)]); -#endif - for (var i = 0; i < len; i++) { // TODO: typed array set, carefully with ranges, or other trick - info.buffer[info.bufferWrite++] = data[i]; - if (info.bufferWrite == info.buffer.length) info.bufferWrite = 0; - if (info.bufferWrite == info.bufferRead) { - // grow the buffer - var currLen = info.buffer.length; - if (currLen > Sockets.MAX_BUFFER_SIZE) throw 'socket buffer overflow'; - var newBuffer = new Uint8Array(currLen*2); - for (var j = 0; j < currLen; j++) { - newBuffer[j] = info.buffer[(info.bufferRead + j)%currLen]; - } - info.bufferRead = 0; - info.bufferWrite = currLen; - info.buffer = newBuffer; - } - } - } - info.sendQueue = new Uint8Array(1024); - info.sendQueueUsed = 0; - info.senderWaiting = false; - info.sender = function(data, justQueue) { - if (data) { -#if SOCKET_DEBUG - Module.print(['sender', data, data.length, '|', Array.prototype.slice.call(data)]); -#endif - if (info.sendQueueUsed + data.length >= info.sendQueue.length) { - var newQueue = new Uint8Array(2*Math.max(info.sendQueue.length, data.length)); - newQueue.set(info.sendQueue); - info.sendQueue = newQueue; - } - info.sendQueue.set(data, info.sendQueueUsed); // must copy, because while this waits memory can change! - info.sendQueueUsed += data.length; - } else { - info.senderWaiting = false; // we are a setTimeout callback - if (info.sendQueueUsed == 0) return; - } - if (info.socket.readyState != info.socket.OPEN) { - if (!info.senderWaiting) { - console.log('waiting for socket in order to send'); - setTimeout(info.sender, 100); - info.senderWaiting = true; - } - return; - } - if (justQueue) return; -#if SOCKET_DEBUG - Module.print('sender actually sending ' + info.sendQueueUsed); -#endif - info.socket.send(new Uint8Array(info.sendQueue.subarray(0, info.sendQueueUsed)).buffer); // TODO: if browser accepts views, can optimize this - info.sendQueueUsed = 0; - }; + Sockets.backends[Sockets.backend].connect(info); return 0; }, @@ -6893,25 +6917,19 @@ LibraryManager.library = { recv: function(fd, buf, len, flags) { var info = Sockets.fds[fd]; if (!info) return -1; - if (info.bufferWrite == info.bufferRead) { + if (info.inQueue.length == 0) { ___setErrNo(ERRNO_CODES.EAGAIN); // no data, and all sockets are nonblocking, so this is the right behavior return 0; // should this be -1 like the spec says? } - var ret = 0; + var buffer = info.inQueue.shift(); #if SOCKET_DEBUG - Module.print('pre-recv: ' + [len, info.bufferWrite, info.bufferRead]); + Module.print('recv: ' + [Array.prototype.slice.call(buffer)]); #endif - while (info.bufferWrite != info.bufferRead && len > 0) { - // write out a byte - {{{ makeSetValue('buf++', '0', 'info.buffer[info.bufferRead++]', 'i8') }}}; - if (info.bufferRead == info.buffer.length) info.bufferRead = 0; - len--; - ret++; + if (len < buffer.length) { + buffer = buffer.subarray(0, len); } -#if SOCKET_DEBUG - Module.print('recv: ' + [ret, len, buf] + ' : ' + Array.prototype.slice.call(HEAPU8.subarray(buf-ret, buf))); -#endif - return ret; + HEAPU8.set(buffer, buf); + return buffer.length; }, send__deps: ['$Sockets'], @@ -6934,10 +6952,15 @@ LibraryManager.library = { } var iov = {{{ makeGetValue('msg', 'Sockets.msghdr_layout.msg_iov', 'i8*') }}}; var num = {{{ makeGetValue('msg', 'Sockets.msghdr_layout.msg_iovlen', 'i32') }}}; - var ret = 0; #if SOCKET_DEBUG Module.print('sendmsg vecs: ' + num); #endif + var totalSize = 0; + for (var i = 0; i < num; i++) { + totalSize += {{{ makeGetValue('iov', '8*i + 4', 'i32') }}}; + } + var buffer = new Uint8Array(totalSize); + var ret = 0; for (var i = 0; i < num; i++) { var currNum = {{{ makeGetValue('iov', '8*i + 4', 'i32') }}}; #if SOCKET_DEBUG @@ -6945,10 +6968,10 @@ LibraryManager.library = { #endif if (!currNum) continue; var currBuf = {{{ makeGetValue('iov', '8*i', 'i8*') }}}; - info.sender(HEAPU8.subarray(currBuf, currBuf+currNum), true); + buffer.set(HEAPU8.subarray(currBuf, currBuf+currNum), ret); ret += currNum; } - info.sender(null); // flush all of these together. Important they get sent as a single socket message + info.sender(buffer); // send all the iovs as a single message return ret; }, @@ -6965,12 +6988,12 @@ LibraryManager.library = { assert(name, 'sendmsg on non-connected socket, and no name/address in the message'); _connect(fd, name, {{{ makeGetValue('msg', 'Sockets.msghdr_layout.msg_namelen', 'i32') }}}); } - var bytes = info.bufferWrite - info.bufferRead; - if (bytes < 0) bytes += info.buffer.length; - if (bytes == 0) { + if (info.inQueue.length == 0) { ___setErrNo(ERRNO_CODES.EWOULDBLOCK); return -1; } + var buffer = info.inQueue.shift(); + var bytes = buffer.length; #if SOCKET_DEBUG Module.print('recvmsg bytes: ' + bytes); #endif @@ -6982,7 +7005,7 @@ LibraryManager.library = { var ret = bytes; var iov = {{{ makeGetValue('msg', 'Sockets.msghdr_layout.msg_iov', 'i8*') }}}; var num = {{{ makeGetValue('msg', 'Sockets.msghdr_layout.msg_iovlen', 'i32') }}}; - var data = ''; + var bufferPos = 0; for (var i = 0; i < num && bytes > 0; i++) { var currNum = {{{ makeGetValue('iov', '8*i + 4', 'i32') }}}; #if SOCKET_DEBUG @@ -6995,7 +7018,14 @@ LibraryManager.library = { #if SOCKET_DEBUG Module.print('recvmsg call recv ' + currNum); #endif - assert(_recv(fd, currBuf, currNum, 0) == currNum); + HEAPU8.set(buffer.subarray(bufferPos, bufferPos + currNum), currBuf); + bufferPos += currNum; + } + if (info.stream) { + // This is tcp (reliable), so if not all was read, keep it + if (bufferPos < bytes) { + info.inQueue.unshift(buffer.subArray(bufferPos)); + } } return ret; }, @@ -7022,11 +7052,12 @@ LibraryManager.library = { ioctl: function(fd, request, varargs) { var info = Sockets.fds[fd]; if (!info) return -1; - var start = info.bufferRead; - var end = info.bufferWrite; - if (end < start) end += info.buffer.length; + var bytes = 0; + if (info.inQueue.length > 0) { + bytes = info.inQueue[0].length; + } var dest = {{{ makeGetValue('varargs', '0', 'i32') }}}; - {{{ makeSetValue('dest', '0', 'end - start', 'i32') }}}; + {{{ makeSetValue('dest', '0', 'bytes', 'i32') }}}; return 0; }, @@ -7058,6 +7089,26 @@ LibraryManager.library = { return fd; }, + select: function(nfds, readfds, writefds, exceptfds, timeout) { + // only readfds are supported, not writefds or exceptfds + // timeout is always 0 - fully async + assert(!writefds && !exceptfds); + var ret = 0; + var l = {{{ makeGetValue('readfds', 0, 'i32') }}}; + var h = {{{ makeGetValue('readfds', 4, 'i32') }}}; + nfds = Math.min(64, nfds); // fd sets have 64 bits + for (var fd = 0; fd < nfds; fd++) { + var bit = fd % 32, int = fd < 32 ? l : h; + if (int & (1 << bit)) { + // index is in the set, check if it is ready for read + var info = Sockets.fds[fd]; + if (!info) continue; + if (info.inQueue.length > 0) ret++; + } + } + return ret; + }, + // ========================================================================== // emscripten.h // ========================================================================== diff --git a/src/library_browser.js b/src/library_browser.js index b14099f6..fd09f478 100644 --- a/src/library_browser.js +++ b/src/library_browser.js @@ -377,11 +377,11 @@ mergeInto(LibraryManager.library, { _file.substr(index +1), _url, true, true, function() { - if (onload) FUNCTION_TABLE[onload](file); + if (onload) Runtime.dynCall('vi', onload, [file]); }, function() { - if (onerror) FUNCTION_TABLE[onerror](file); - } + if (onerror) Runtime.dynCall('vi', onerror, [file]); + } ); }, @@ -396,6 +396,55 @@ mergeInto(LibraryManager.library, { }, true /* no need for run dependency, this is async but will not do any prepare etc. step */ ); }, + emscripten_async_wget2: function(url, file, request, param, arg, onload, onerror, onprogress) { + var _url = Pointer_stringify(url); + var _file = Pointer_stringify(file); + var _request = Pointer_stringify(request); + var _param = Pointer_stringify(param); + var index = _file.lastIndexOf('/'); + + var http = new XMLHttpRequest(); + http.open(_request, _url, true); + http.responseType = 'arraybuffer'; + + // LOAD + http.onload = function(e) { + if (http.status == 200) { + FS.createDataFile( _file.substr(0, index), _file.substr(index + 1), new Uint8Array(http.response), true, true); + if (onload) FUNCTION_TABLE[onload](arg, file); + } else { + if (onerror) FUNCTION_TABLE[onerror](arg, http.status); + } + }; + + // ERROR + http.onerror = function(e) { + if (onerror) FUNCTION_TABLE[onerror](arg, http.status); + }; + + // PROGRESS + http.onprogress = function(e) { + var percentComplete = (e.position / e.totalSize)*100; + if (onprogress) FUNCTION_TABLE[onprogress](arg, percentComplete); + }; + + // Useful because the browser can limit the number of redirection + try { + if (http.channel instanceof Ci.nsIHttpChannel) + http.channel.redirectionLimit = 0; + } catch (ex) { /* whatever */ } + + if (_request == "POST") { + //Send the proper header information along with the request + http.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); + http.setRequestHeader("Content-length", _param.length); + http.setRequestHeader("Connection", "close"); + http.send(_param); + } else { + http.send(null); + } + }, + emscripten_async_prepare: function(file, onload, onerror) { var _file = Pointer_stringify(file); var data = FS.analyzePath(_file); @@ -406,10 +455,10 @@ mergeInto(LibraryManager.library, { _file.substr(index +1), new Uint8Array(data.object.contents), true, true, function() { - if (onload) FUNCTION_TABLE[onload](file); + if (onload) Runtime.dynCall('vi', onload, [file]); }, function() { - if (onerror) FUNCTION_TABLE[onerror](file); + if (onerror) Runtime.dynCall('vi', onerror, [file]); }, true // don'tCreateFile - it's already there ); @@ -428,10 +477,10 @@ mergeInto(LibraryManager.library, { {{{ makeHEAPView('U8', 'data', 'data + size') }}}, true, true, function() { - if (onload) FUNCTION_TABLE[onload](arg, cname); + if (onload) Runtime.dynCall('vii', onload, [arg, cname]); }, function() { - if (onerror) FUNCTION_TABLE[onerror](arg); + if (onerror) Runtime.dynCall('vi', onerror, [arg]); }, true // don'tCreateFile - it's already there ); @@ -451,7 +500,6 @@ mergeInto(LibraryManager.library, { emscripten_set_main_loop: function(func, fps, simulateInfiniteLoop) { Module['noExitRuntime'] = true; - var jsFunc = FUNCTION_TABLE[func]; Browser.mainLoop.runner = function() { if (Browser.mainLoop.queue.length > 0) { var start = Date.now(); @@ -484,7 +532,7 @@ mergeInto(LibraryManager.library, { Module['preMainLoop'](); } - jsFunc(); + Runtime.dynCall('v', func); if (Module['postMainLoop']) { Module['postMainLoop'](); @@ -528,12 +576,16 @@ mergeInto(LibraryManager.library, { }, _emscripten_push_main_loop_blocker: function(func, arg, name) { - Browser.mainLoop.queue.push({ func: FUNCTION_TABLE[func], arg: arg, name: Pointer_stringify(name), counted: true }); + Browser.mainLoop.queue.push({ func: function() { + Runtime.dynCall('vi', func, [arg]); + }, name: Pointer_stringify(name), counted: true }); Browser.mainLoop.updateStatus(); }, _emscripten_push_uncounted_main_loop_blocker: function(func, arg, name) { - Browser.mainLoop.queue.push({ func: FUNCTION_TABLE[func], arg: arg, name: Pointer_stringify(name), counted: false }); + Browser.mainLoop.queue.push({ func: function() { + Runtime.dynCall('vi', func, [arg]); + }, name: Pointer_stringify(name), counted: false }); Browser.mainLoop.updateStatus(); }, @@ -547,7 +599,7 @@ mergeInto(LibraryManager.library, { Module['noExitRuntime'] = true; function wrapper() { - Runtime.getFuncWrapper(func)(arg); + Runtime.getFuncWrapper(func, 'vi')(arg); } if (millis >= 0) { @@ -631,7 +683,7 @@ mergeInto(LibraryManager.library, { if (callback) { callbackId = info.callbacks.length; info.callbacks.push({ - func: Runtime.getFuncWrapper(callback), + func: Runtime.getFuncWrapper(callback, 'viii'), arg: arg }); info.awaited++; diff --git a/src/library_gc.js b/src/library_gc.js index a06e2f01..fe4cbf63 100644 --- a/src/library_gc.js +++ b/src/library_gc.js @@ -1,5 +1,7 @@ if (GC_SUPPORT) { + EXPORTED_FUNCTIONS['_calloc'] = 1; + var LibraryGC = { $GC__deps: ['sbrk'], $GC: { @@ -50,7 +52,7 @@ if (GC_SUPPORT) { free: function(ptr) { // does not check if anything refers to it, this is a forced free var finalizer = GC.finalizers[ptr]; if (finalizer) { - Runtime.getFuncWrapper(finalizer)(ptr, GC.finalizerArgs[ptr]); + Runtime.getFuncWrapper(finalizer, 'vii')(ptr, GC.finalizerArgs[ptr]); GC.finalizers[ptr] = 0; } _free(ptr); diff --git a/src/library_gl.js b/src/library_gl.js index 0f28a6a0..267a6185 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 = '', func; 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,67 +1315,68 @@ 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() { Module.printErr('WARNING: empty replacement for ' + name + ' called, no-op'); return 0; }; + sig = 'v'; } } - return Runtime.addFunction(func); + return Runtime.addFunction(func, sig); } }, @@ -2079,8 +2081,9 @@ var LibraryGL = { glVertex3fv: function(p) { _glVertex3f({{{ makeGetValue('p', '0', 'float') }}}, {{{ makeGetValue('p', '4', 'float') }}}, {{{ makeGetValue('p', '8', 'float') }}}); }, + glVertex2fv__deps: ['glVertex3f'], glVertex2fv: function(p) { - _glVertex2f({{{ makeGetValue('p', '0', 'float') }}}, {{{ makeGetValue('p', '4', 'float') }}}); + _glVertex3f({{{ makeGetValue('p', '0', 'float') }}}, {{{ makeGetValue('p', '4', 'float') }}}, 0); }, glTexCoord2i: function(u, v) { @@ -2093,9 +2096,9 @@ var LibraryGL = { }, glTexCoord2f: 'glTexCoord2i', - glTexCoord2fv__deps: ['glTexCoord2f'], + glTexCoord2fv__deps: ['glTexCoord2i'], glTexCoord2fv: function(v) { - _glTexCoord2f({{{ makeGetValue('v', '0', 'float') }}}, {{{ makeGetValue('v', '4', 'float') }}}); + _glTexCoord2i({{{ makeGetValue('v', '0', 'float') }}}, {{{ makeGetValue('v', '4', 'float') }}}); }, glColor4f: function(r, g, b, a) { diff --git a/src/library_glut.js b/src/library_glut.js index 6069b484..2e662698 100644 --- a/src/library_glut.js +++ b/src/library_glut.js @@ -54,11 +54,11 @@ var LibraryGLUT = { if (GLUT.buttons == 0 && event.target == Module["canvas"] && GLUT.passiveMotionFunc) { event.preventDefault(); GLUT.saveModifiers(event); - FUNCTION_TABLE[GLUT.passiveMotionFunc](GLUT.lastX, GLUT.lastY); + Runtime.dynCall('vii', GLUT.passiveMotionFunc, [GLUT.lastX, GLUT.lastY]); } else if (GLUT.buttons != 0 && GLUT.motionFunc) { event.preventDefault(); GLUT.saveModifiers(event); - FUNCTION_TABLE[GLUT.motionFunc](GLUT.lastX, GLUT.lastY); + Runtime.dynCall('vii', GLUT.motionFunc, [GLUT.lastX, GLUT.lastY]); } }, @@ -159,7 +159,7 @@ var LibraryGLUT = { if( GLUT.specialFunc ) { event.preventDefault(); GLUT.saveModifiers(event); - FUNCTION_TABLE[GLUT.specialFunc](key, GLUT.lastX, GLUT.lastY); + Runtime.dynCall('viii', GLUT.specialFunc, [key, GLUT.lastX, GLUT.lastY]); } } else @@ -168,7 +168,7 @@ var LibraryGLUT = { if( key !== null && GLUT.keyboardFunc ) { event.preventDefault(); GLUT.saveModifiers(event); - FUNCTION_TABLE[GLUT.keyboardFunc](key, GLUT.lastX, GLUT.lastY); + Runtime.dynCall('viii', GLUT.keyboardFunc, [key, GLUT.lastX, GLUT.lastY]); } } } @@ -181,7 +181,7 @@ var LibraryGLUT = { if(GLUT.specialUpFunc) { event.preventDefault (); GLUT.saveModifiers(event); - FUNCTION_TABLE[GLUT.specialUpFunc](key, GLUT.lastX, GLUT.lastY); + Runtime.dynCall('viii', GLUT.specialUpFunc, [key, GLUT.lastX, GLUT.lastY]); } } else @@ -190,7 +190,7 @@ var LibraryGLUT = { if( key !== null && GLUT.keyboardUpFunc ) { event.preventDefault (); GLUT.saveModifiers(event); - FUNCTION_TABLE[GLUT.keyboardUpFunc](key, GLUT.lastX, GLUT.lastY); + Runtime.dynCall('viii', GLUT.keyboardUpFunc, [key, GLUT.lastX, GLUT.lastY]); } } } @@ -206,7 +206,7 @@ var LibraryGLUT = { } catch (e) {} event.preventDefault(); GLUT.saveModifiers(event); - FUNCTION_TABLE[GLUT.mouseFunc](event['button'], 0/*GLUT_DOWN*/, GLUT.lastX, GLUT.lastY); + Runtime.dynCall('viiii', GLUT.mouseFunc, [event['button'], 0/*GLUT_DOWN*/, GLUT.lastX, GLUT.lastY]); } }, @@ -217,7 +217,7 @@ var LibraryGLUT = { if(GLUT.mouseFunc) { event.preventDefault(); GLUT.saveModifiers(event); - FUNCTION_TABLE[GLUT.mouseFunc](event['button'], 1/*GLUT_UP*/, GLUT.lastX, GLUT.lastY); + Runtime.dynCall('viiii', GLUT.mouseFunc, [event['button'], 1/*GLUT_UP*/, GLUT.lastX, GLUT.lastY]); } }, @@ -241,7 +241,7 @@ var LibraryGLUT = { /* Can't call _glutReshapeWindow as that requests cancelling fullscreen. */ if (GLUT.reshapeFunc) { // console.log("GLUT.reshapeFunc (from FS): " + width + ", " + height); - FUNCTION_TABLE[GLUT.reshapeFunc](width, height); + Runtime.dynCall('vii', GLUT.reshapeFunc, [width, height]); } _glutPostRedisplay(); }, @@ -326,7 +326,7 @@ var LibraryGLUT = { glutIdleFunc: function(func) { var callback = function() { if (GLUT.idleFunc) { - FUNCTION_TABLE[GLUT.idleFunc](); + Runtime.dynCall('v', GLUT.idleFunc); window.setTimeout(callback, 0); } } @@ -336,7 +336,7 @@ var LibraryGLUT = { }, glutTimerFunc: function(msec, func, value) { - window.setTimeout(function() { FUNCTION_TABLE[func](value); }, msec); + window.setTimeout(function() { Runtime.dynCall('vi', func, [value]); }, msec); }, glutDisplayFunc: function(func) { @@ -388,7 +388,7 @@ var LibraryGLUT = { Browser.setCanvasSize(width, height); if (GLUT.reshapeFunc) { // console.log("GLUT.reshapeFunc: " + width + ", " + height); - FUNCTION_TABLE[GLUT.reshapeFunc](width, height); + Runtime.dynCall('vii', GLUT.reshapeFunc, [width, height]); } _glutPostRedisplay(); }, @@ -417,7 +417,9 @@ var LibraryGLUT = { glutPostRedisplay: function() { if (GLUT.displayFunc) { - Browser.requestAnimationFrame(FUNCTION_TABLE[GLUT.displayFunc]); + Browser.requestAnimationFrame(function() { + Runtime.dynCall('v', GLUT.displayFunc); + }); } }, diff --git a/src/library_sdl.js b/src/library_sdl.js index 1cd99534..b2ca338b 100644 --- a/src/library_sdl.js +++ b/src/library_sdl.js @@ -707,7 +707,9 @@ var LibrarySDL = { SDL_Quit: function() { for (var i = 0; i < SDL.numChannels; ++i) { - SDL.channels[i].audio.pause(); + if (SDL.channels[i].audio) { + SDL.channels[i].audio.pause(); + } } if (SDL.music.audio) { SDL.music.audio.pause(); @@ -1116,7 +1118,7 @@ var LibrarySDL = { SDL.audio.bufferSize = totalSamples*2; // hardcoded 16-bit audio SDL.audio.buffer = _malloc(SDL.audio.bufferSize); SDL.audio.caller = function() { - FUNCTION_TABLE[SDL.audio.callback](SDL.audio.userdata, SDL.audio.buffer, SDL.audio.bufferSize); + Runtime.dynCall('viii', SDL.audio.callback, [SDL.audio.userdata, SDL.audio.buffer, SDL.audio.bufferSize]); SDL.audio.pushAudio(SDL.audio.buffer, SDL.audio.bufferSize); }; // Mozilla Audio API. TODO: Other audio APIs @@ -1160,6 +1162,8 @@ var LibrarySDL = { SDL_CreateMutex: function() { return 0 }, SDL_LockMutex: function() {}, SDL_UnlockMutex: function() {}, + SDL_mutexP: function() { return 0 }, + SDL_mutexV: function() { return 0 }, SDL_DestroyMutex: function() {}, SDL_CreateCond: function() { return 0 }, @@ -1278,7 +1282,7 @@ var LibrarySDL = { channelInfo.audio = audio = audio.cloneNode(true); if (SDL.channelFinished) { audio['onended'] = function() { // TODO: cache these - Runtime.getFuncWrapper(SDL.channelFinished)(channel); + Runtime.getFuncWrapper(SDL.channelFinished, 'vi')(channel); } } // Either play the element, or load the dynamic data into it @@ -1349,7 +1353,7 @@ var LibrarySDL = { info.audio = null; } if (SDL.channelFinished) { - Runtime.getFuncWrapper(SDL.channelFinished)(channel); + Runtime.getFuncWrapper(SDL.channelFinished, 'vi')(channel); } return 0; }, @@ -1408,7 +1412,7 @@ var LibrarySDL = { audio.pause(); SDL.music.audio = null; if (SDL.hookMusicFinished) { - FUNCTION_TABLE[SDL.hookMusicFinished](); + Runtime.dynCall('v', SDL.hookMusicFinished); } return 0; }, @@ -1439,6 +1443,10 @@ var LibrarySDL = { return id; }, + TTF_CloseFont: function(font) { + SDL.fonts[font] = null; + }, + TTF_RenderText_Solid: function(font, text, color) { // XXX the font and color are ignored text = Pointer_stringify(text) || ' '; // if given an empty string, still return a valid surface @@ -1557,7 +1565,7 @@ var LibrarySDL = { SDL_AddTimer: function(interval, callback, param) { return window.setTimeout(function() { - FUNCTION_TABLE[callback](interval, param); + Runtime.dynCall('ii', callback, [interval, param]); }, interval); }, SDL_RemoveTimer: function(id) { diff --git a/src/long.js b/src/long.js index fc67733f..c3b0e605 100644 --- a/src/long.js +++ b/src/long.js @@ -1530,27 +1530,26 @@ var i64Math = (function() { // Emscripten wrapper // Emscripten wrapper var Wrapper = { - result: [0, 0], // return result stored here add: function(xl, xh, yl, yh) { var x = new goog.math.Long(xl, xh); var y = new goog.math.Long(yl, yh); var ret = x.add(y); - Wrapper.result[0] = ret.low_; - Wrapper.result[1] = ret.high_; + HEAP32[tempDoublePtr>>2] = ret.low_; + HEAP32[tempDoublePtr+4>>2] = ret.high_; }, subtract: function(xl, xh, yl, yh) { var x = new goog.math.Long(xl, xh); var y = new goog.math.Long(yl, yh); var ret = x.subtract(y); - Wrapper.result[0] = ret.low_; - Wrapper.result[1] = ret.high_; + HEAP32[tempDoublePtr>>2] = ret.low_; + HEAP32[tempDoublePtr+4>>2] = ret.high_; }, multiply: function(xl, xh, yl, yh) { var x = new goog.math.Long(xl, xh); var y = new goog.math.Long(yl, yh); var ret = x.multiply(y); - Wrapper.result[0] = ret.low_; - Wrapper.result[1] = ret.high_; + HEAP32[tempDoublePtr>>2] = ret.low_; + HEAP32[tempDoublePtr+4>>2] = ret.high_; }, ensureTemps: function() { if (Wrapper.ensuredTemps) return; @@ -1579,8 +1578,8 @@ var i64Math = (function() { // Emscripten wrapper var x = new goog.math.Long(xl, xh); var y = new goog.math.Long(yl, yh); var ret = x.div(y); - Wrapper.result[0] = ret.low_; - Wrapper.result[1] = ret.high_; + HEAP32[tempDoublePtr>>2] = ret.low_; + HEAP32[tempDoublePtr+4>>2] = ret.high_; } else { // slow precise bignum division var x = Wrapper.lh2bignum(xl >>> 0, xh >>> 0); @@ -1590,8 +1589,8 @@ var i64Math = (function() { // Emscripten wrapper var l = new BigInteger(); var h = new BigInteger(); z.divRemTo(Wrapper.two32, h, l); - Wrapper.result[0] = parseInt(l.toString()) | 0; - Wrapper.result[1] = parseInt(h.toString()) | 0; + HEAP32[tempDoublePtr>>2] = parseInt(l.toString()) | 0; + HEAP32[tempDoublePtr+4>>2] = parseInt(h.toString()) | 0; } }, modulo: function(xl, xh, yl, yh, unsigned) { @@ -1600,8 +1599,8 @@ var i64Math = (function() { // Emscripten wrapper var x = new goog.math.Long(xl, xh); var y = new goog.math.Long(yl, yh); var ret = x.modulo(y); - Wrapper.result[0] = ret.low_; - Wrapper.result[1] = ret.high_; + HEAP32[tempDoublePtr>>2] = ret.low_; + HEAP32[tempDoublePtr+4>>2] = ret.high_; } else { // slow precise bignum division var x = Wrapper.lh2bignum(xl >>> 0, xh >>> 0); @@ -1611,8 +1610,8 @@ var i64Math = (function() { // Emscripten wrapper var l = new BigInteger(); var h = new BigInteger(); z.divRemTo(Wrapper.two32, h, l); - Wrapper.result[0] = parseInt(l.toString()) | 0; - Wrapper.result[1] = parseInt(h.toString()) | 0; + HEAP32[tempDoublePtr>>2] = parseInt(l.toString()) | 0; + HEAP32[tempDoublePtr+4>>2] = parseInt(h.toString()) | 0; } }, stringify: function(l, h, unsigned) { @@ -1650,8 +1649,8 @@ var i64Math = (function() { // Emscripten wrapper error = true; } var ret = goog.math.Long.fromString(bignum.toString()); // min-max checks should have clamped this to a range goog.math.Long can handle well - Wrapper.result[0] = ret.low_; - Wrapper.result[1] = ret.high_; + HEAP32[tempDoublePtr>>2] = ret.low_; + HEAP32[tempDoublePtr+4>>2] = ret.high_; if (error) throw 'range error'; } }; diff --git a/src/modules.js b/src/modules.js index 64638be1..b5a30866 100644 --- a/src/modules.js +++ b/src/modules.js @@ -216,17 +216,29 @@ 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 + unimplementedFunctions: {}, // library etc. functions that we need to index, maps id to signature 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++) { + var type = argTypes[i]; + if (!type) break; // varargs + sig += isIntImplemented(type) ? (getBits(type) == 64 ? 'ii' : 'i') : 'f'; // legalized i64s will be i32s + } + return sig; + }, + // Mark a function as needing indexing. Python will coordinate them all getIndex: function(ident) { - if (phase != 'post') { + if (phase != 'post' && singlePhase) { this.indexedFunctions[ident] = 0; // tell python we need this indexized return '{{{ FI_' + ident + ' }}}'; // something python will replace later } else { @@ -240,27 +252,60 @@ var Functions = { } }, + getTable: function(sig) { + return ASM_JS ? 'FUNCTION_TABLE_' + sig : 'FUNCTION_TABLE'; + }, + // Generate code for function indexing generateIndexing: function() { - var vals = zeros(this.nextIndex); + var total = this.nextIndex; + if (ASM_JS) total = ceilPowerOfTwo(total); // must be power of 2 for mask + function emptyTable(sig) { + return zeros(total); + } + var tables = {}; + if (ASM_JS) { + ['v', 'vi', 'ii', 'iii'].forEach(function(sig) { // add some default signatures that are used in the library + tables[sig] = emptyTable(sig); // TODO: make them compact + }); + } for (var ident in this.indexedFunctions) { - vals[this.indexedFunctions[ident]] = ident; + var sig = ASM_JS ? Functions.implementedFunctions[ident] || Functions.unimplementedFunctions[ident] : 'x'; + assert(sig, ident); + if (!tables[sig]) tables[sig] = emptyTable(sig); // 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 generated = false; + for (var t in tables) { + generated = true; + var table = tables[t]; + for (var i = 0; i < table.length; i++) { + // Resolve multi-level aliases all the way down + 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 + } + // Resolve library aliases + if (table[i]) { + var libName = LibraryManager.getRootIdent(table[i].substr(1)); + if (libName && typeof libName == 'string') { + table[i] = (libName.indexOf('.') < 0 ? '_' : '') + libName; + } + } + } + var indices = table.toString().replace('"', ''); + if (BUILD_AS_SHARED_LIB) { + // Shared libraries reuse the parent's function table. + tables[t] = Functions.getTable(t) + '.push.apply(' + Functions.getTable(t) + ', [' + indices + ']);\n'; + } else { + tables[t] = 'var ' + Functions.getTable(t) + ' = [' + indices + '];\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;'; + if (!generated && !ASM_JS) { + tables['x'] = 'var FUNCTION_TABLE = [0, 0];\n'; // default empty table } + Functions.tables = tables; } }; @@ -311,16 +356,23 @@ var PassManager = { print('\n//FORWARDED_DATA:' + JSON.stringify({ Types: Types, Variables: Variables, - Functions: Functions + Functions: Functions, + EXPORTED_FUNCTIONS: EXPORTED_FUNCTIONS // needed for asm.js global constructors (ctors) })); } else if (phase == 'funcs') { print('\n//FORWARDED_DATA:' + JSON.stringify({ Types: { preciseI64MathUsed: Types.preciseI64MathUsed }, Functions: { blockAddresses: Functions.blockAddresses, - indexedFunctions: Functions.indexedFunctions + indexedFunctions: Functions.indexedFunctions, + implementedFunctions: ASM_JS ? Functions.implementedFunctions : [], + unimplementedFunctions: Functions.unimplementedFunctions, } })); + } else if (phase == '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 b2093da3..6cb3e776 100644 --- a/src/parseTools.js +++ b/src/parseTools.js @@ -128,16 +128,48 @@ function isStructType(type) { return type[0] == '%'; } +function isStructuralType(type) { + return /^{ ?[^}]* ?}$/.test(type); // { i32, i8 } etc. - anonymous struct types +} + +function getStructuralTypeParts(type) { // split { i32, i8 } etc. into parts + return type.replace(/[ {}]/g, '').split(','); +} + +function getStructureTypeParts(type) { + if (isStructuralType(type)) { + return type.replace(/[ {}]/g, '').split(','); + } else { + var typeData = Types.types[type]; + assert(typeData, type); + return typeData.fields; + } +} + +function getStructuralTypePartBits(part) { + return Math.ceil((getBits(part) || 32)/32)*32; // simple 32-bit alignment. || 32 is for pointers +} + function isIntImplemented(type) { return type[0] == 'i' || isPointerType(type); } -// Note: works for iX types, not pointers (even though they are implemented as ints) +// Note: works for iX types and structure types, not pointers (even though they are implemented as ints) function getBits(type) { - if (!type || type[0] != 'i') return 0; - var left = type.substr(1); - if (!isNumber(left)) return 0; - return parseInt(left); + if (!type) return 0; + if (type[0] == 'i') { + var left = type.substr(1); + if (!isNumber(left)) return 0; + return parseInt(left); + } + if (isStructuralType(type)) { + return sum(getStructuralTypeParts(type).map(getStructuralTypePartBits)); + } + if (isStructType(type)) { + var typeData = Types.types[type]; + return typeData.flatSize*8; + } + return 0; } function isIllegalType(type) { @@ -163,11 +195,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 +223,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); } @@ -310,7 +345,9 @@ function parseParamTokens(params) { if (segment.length == 1) { if (segment[0].text == '...') { ret.push({ - intertype: 'varargs' + intertype: 'varargs', + type: 'i8*', + ident: 'varrp' // the conventional name we have for this }); } else { // Clang sometimes has a parameter with just a type, @@ -360,25 +397,34 @@ var UNINDEXABLE_GLOBALS = set( '_llvm_global_ctors' // special-cased ); -function noticePtr(ptr) { - if (!NAMED_GLOBALS && !LibraryManager.loaded) UNINDEXABLE_GLOBALS[ptr] = 1; // we cannot index globals referred to in the library, since they are used there by name -} - function isIndexableGlobal(ident) { if (!(ident in Variables.globals)) return false; - if (ident in UNINDEXABLE_GLOBALS) return false; + if (ident in UNINDEXABLE_GLOBALS) { + Variables.globals[ident].unIndexable = true; + return false; + } var data = Variables.globals[ident]; - return !data.alias && !data.external; + // in asm.js, externals are just globals + return !data.alias && (ASM_JS || !data.external); } function makeGlobalDef(ident) { if (!NAMED_GLOBALS && isIndexableGlobal(ident)) return ''; - return 'var ' + ident + ';'; // TODO: add option for namespacing or offsetting to allow reducing the number of globals + return 'var ' + ident + ';'; } function makeGlobalUse(ident) { - if (!NAMED_GLOBALS && isIndexableGlobal(ident)) return '(' + getFastValue('GLOBAL_BASE', '+', Variables.indexedGlobals[ident]) + ')'; - return ident; // TODO: add option for namespacing or offsetting to allow reducing the number of globals + if (!NAMED_GLOBALS && isIndexableGlobal(ident)) { + var index = Variables.indexedGlobals[ident]; + if (index === undefined) { + // we are accessing this before we index globals, likely from the library. mark as unindexable + UNINDEXABLE_GLOBALS[ident] = 1; + return ident; + } + // We know and assert on TOTAL_STACK being equal to GLOBAL_BASE + return (TOTAL_STACK + index).toString(); + } + return ident; } function sortGlobals(globals) { @@ -447,7 +493,7 @@ function parseLLVMSegment(segment) { return { intertype: 'value', ident: toNiceIdent(segment[1].text), - type: segment[0].text + type: type }; } } @@ -922,6 +968,12 @@ function checkSafeHeap() { return SAFE_HEAP === 1 || checkSpecificSafeHeap(); } +if (ASM_JS) { + var hexMemoryMask = '0x' + (TOTAL_MEMORY-1).toString(16); + var decMemoryMask = (TOTAL_MEMORY-1).toString(); + var memoryMask = hexMemoryMask.length <= decMemoryMask.length ? hexMemoryMask : decMemoryMask; +} + function getHeapOffset(offset, type) { if (USE_TYPED_ARRAYS !== 2) { return offset; @@ -930,17 +982,64 @@ function getHeapOffset(offset, type) { type = 'i32'; // XXX we emulate 64-bit values as 32 } var shifts = Math.log(Runtime.getNativeTypeSize(type))/Math.LN2; + offset = '(' + offset + ')'; + if (ASM_JS && phase == 'funcs') offset = '(' + offset + '&' + memoryMask + ')'; if (shifts != 0) { - return '((' + offset + ')>>' + (shifts) + ')'; + return '(' + offset + '>>' + shifts + ')'; } else { - return '(' + offset + ')'; + return offset; } } } +function makeVarDef(js) { + if (!ASM_JS) js = 'var ' + js; + return js; +} + +function asmEnsureFloat(value, type) { // ensures that a float type has either 5.5 (clearly a float) or +5 (float due to asm coercion) + if (!ASM_JS) return value; + if (type in Runtime.FLOAT_TYPES && isNumber(value) && value.toString().indexOf('.') < 0) { + return '(+(' + value + '))'; + } else { + return value; + } +} + +function asmInitializer(type, impl) { + if (type in Runtime.FLOAT_TYPES) { + return '+0'; + } else { + return '0'; + } +} + +function asmCoercion(value, type) { + if (!ASM_JS) return value; + if (type == 'void') { + return value; + } else if (type in Runtime.FLOAT_TYPES) { + return '(+(' + value + '))'; + } else { + return '((' + value + ')|0)'; + } +} + +function asmMultiplyI32(a, b) { + // special-case: there is no integer multiply in asm, because there is no true integer + // multiply in JS. While we wait for Math.imul, do double multiply + if (USE_MATH_IMUL) { + return 'Math.imul(' + a + ',' + b + ')'; + } + return '(~~(+' + a + ' * +' + b + '))'; +} + +function makeGetTempDouble(i) { // TODO: Support other than i32 + return makeGetValue('tempDoublePtr', Runtime.getNativeTypeSize('i32')*i, 'i32'); +} + // See makeSetValue function makeGetValue(ptr, pos, type, noNeedFirst, unsigned, ignore, align, noSafe) { - noticePtr(ptr); if (UNALIGNED_MEMORY) align = 1; if (isStructType(type)) { var typeData = Types.types[type]; @@ -952,9 +1051,9 @@ function makeGetValue(ptr, pos, type, noNeedFirst, unsigned, ignore, align, noSa } if (DOUBLE_MODE == 1 && USE_TYPED_ARRAYS == 2 && type == 'double') { - return '(tempDoubleI32[0]=' + makeGetValue(ptr, pos, 'i32', noNeedFirst, unsigned, ignore, align) + ',' + - 'tempDoubleI32[1]=' + makeGetValue(ptr, getFastValue(pos, '+', Runtime.getNativeTypeSize('i32')), 'i32', noNeedFirst, unsigned, ignore, align) + ',' + - 'tempDoubleF64[0])'; + return '(HEAP32[tempDoublePtr>>2]=' + makeGetValue(ptr, pos, 'i32', noNeedFirst, unsigned, ignore, align) + ',' + + 'HEAP32[tempDoublePtr+4>>2]=' + makeGetValue(ptr, getFastValue(pos, '+', Runtime.getNativeTypeSize('i32')), 'i32', noNeedFirst, unsigned, ignore, align) + ',' + + 'HEAPF64[tempDoublePtr>>3])'; } if (USE_TYPED_ARRAYS == 2 && align) { @@ -977,9 +1076,9 @@ function makeGetValue(ptr, pos, type, noNeedFirst, unsigned, ignore, align, noSa } } else { if (type == 'float') { - ret += 'copyTempFloat(' + getFastValue(ptr, '+', pos) + '),tempDoubleF32[0]'; + ret += 'copyTempFloat(' + getFastValue(ptr, '+', pos) + '),HEAPF32[tempDoublePtr>>2]'; } else { - ret += 'copyTempDouble(' + getFastValue(ptr, '+', pos) + '),tempDoubleF64[0]'; + ret += 'copyTempDouble(' + getFastValue(ptr, '+', pos) + '),HEAP64[tempDoublePtr>>3]'; } } ret += ')'; @@ -993,14 +1092,24 @@ function makeGetValue(ptr, pos, type, noNeedFirst, unsigned, ignore, align, noSa if (type[0] === '#') type = type.substr(1); return 'SAFE_HEAP_LOAD(' + offset + ', ' + type + ', ' + (!!unsigned+0) + ', ' + ((!checkSafeHeap() || ignore)|0) + ')'; } else { - return makeGetSlabs(ptr, type, false, unsigned)[0] + '[' + getHeapOffset(offset, type) + ']'; + var ret = makeGetSlabs(ptr, type, false, unsigned)[0] + '[' + getHeapOffset(offset, type) + ']'; + if (ASM_JS && phase == 'funcs') { + ret = asmCoercion(ret, type); + } + return ret; } } 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.unimplementedFunctions)) { + Functions.unimplementedFunctions[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 { @@ -1021,7 +1130,6 @@ function indexizeFunctions(value, type) { //! which means we should write to all slabs, ignore type differences if any on reads, etc. //! @param noNeedFirst Whether to ignore the offset in the pointer itself. function makeSetValue(ptr, pos, value, type, noNeedFirst, ignore, align, noSafe, sep, forcedAlign) { - noticePtr(ptr); if (UNALIGNED_MEMORY && !forcedAlign) align = 1; sep = sep || ';'; if (isStructType(type)) { @@ -1039,9 +1147,9 @@ function makeSetValue(ptr, pos, value, type, noNeedFirst, ignore, align, noSafe, } if (DOUBLE_MODE == 1 && USE_TYPED_ARRAYS == 2 && type == 'double') { - return '(tempDoubleF64[0]=' + value + ',' + - makeSetValue(ptr, pos, 'tempDoubleI32[0]', 'i32', noNeedFirst, ignore, align, noSafe, ',') + ',' + - makeSetValue(ptr, getFastValue(pos, '+', Runtime.getNativeTypeSize('i32')), 'tempDoubleI32[1]', 'i32', noNeedFirst, ignore, align, noSafe, ',') + ')'; + return '(HEAPF64[tempDoublePtr>>3]=' + value + ',' + + makeSetValue(ptr, pos, 'HEAP32[tempDoublePtr>>2]', 'i32', noNeedFirst, ignore, align, noSafe, ',') + ',' + + makeSetValue(ptr, getFastValue(pos, '+', Runtime.getNativeTypeSize('i32')), 'HEAP32[tempDoublePtr+4>>2]', 'i32', noNeedFirst, ignore, align, noSafe, ',') + ')'; } else if (USE_TYPED_ARRAYS == 2 && type == 'i64') { return '(tempI64 = [' + splitI64(value) + '],' + makeSetValue(ptr, pos, 'tempI64[0]', 'i32', noNeedFirst, ignore, align, noSafe, ',') + ',' + @@ -1093,7 +1201,6 @@ var SEEK_OPTIMAL_ALIGN_MIN = 20; var UNROLL_LOOP_MAX = 8; function makeSetValues(ptr, pos, value, type, num, align) { - noticePtr(ptr); function unroll(type, num, jump, value$) { jump = jump || 1; value$ = value$ || value; @@ -1125,7 +1232,7 @@ function makeSetValues(ptr, pos, value, type, num, align) { [4, 2, 1].forEach(function(possibleAlign) { if (num == 0) return; if (align >= possibleAlign) { - if (num <= UNROLL_LOOP_MAX*possibleAlign) { + if (num <= UNROLL_LOOP_MAX*possibleAlign || ASM_JS) { // XXX test asm performance ret.push(unroll('i' + (possibleAlign*8), Math.floor(num/possibleAlign), possibleAlign, values[possibleAlign])); } else { ret.push('for (var $$dest = ' + getFastValue(ptr, '+', pos) + (possibleAlign > 1 ? '>>' + log2(possibleAlign) : '') + ', ' + @@ -1143,8 +1250,6 @@ function makeSetValues(ptr, pos, value, type, num, align) { var TYPED_ARRAY_SET_MIN = Infinity; // .set() as memcpy seems to just slow us down function makeCopyValues(dest, src, num, type, modifier, align, sep) { - noticePtr(dest); - noticePtr(src); sep = sep || ';'; function unroll(type, num, jump) { jump = jump || 1; @@ -1171,7 +1276,7 @@ function makeCopyValues(dest, src, num, type, modifier, align, sep) { } else { // USE_TYPED_ARRAYS == 2 // If we don't know how to handle this at compile-time, or handling it is best done in a large amount of code, call memset if (!isNumber(num) || (align < 4 && parseInt(num) >= SEEK_OPTIMAL_ALIGN_MIN)) { - return '_memcpy(' + dest + ', ' + src + ', ' + num + ', ' + align + ')'; + return '_memcpy(' + dest + ', ' + src + ', ' + num + ')'; } num = parseInt(num); var ret = []; @@ -1179,7 +1284,7 @@ function makeCopyValues(dest, src, num, type, modifier, align, sep) { if (num == 0) return; if (align >= possibleAlign) { // If we can unroll the loop, do so. Also do so if we must unroll it (we do not create real loops when inlined) - if (num <= UNROLL_LOOP_MAX*possibleAlign || sep == ',') { + if (num <= UNROLL_LOOP_MAX*possibleAlign || sep == ',' || ASM_JS) { // XXX test asm performance ret.push(unroll('i' + (possibleAlign*8), Math.floor(num/possibleAlign), possibleAlign)); } else { assert(sep == ';'); @@ -1245,6 +1350,9 @@ function getFastValue(a, op, b, type) { return '(' + a + '<<' + shifts + ')'; } } + if (ASM_JS && !(type in Runtime.FLOAT_TYPES)) { + return asmMultiplyI32(a, b); // unoptimized multiply, do it using asm.js's special multiply operation + } } else { if (a == '0') { return '0'; @@ -1509,8 +1617,35 @@ function handleOverflow(text, bits) { } } -function makeLLVMStruct(values) { // TODO: Use this everywhere - return '{ ' + values.map(function(value, i) { return 'f' + i + ': ' + value }).join(', ') + ' }' +function makeLLVMStruct(values) { + if (USE_TYPED_ARRAYS == 2) { + return 'DEPRECATED' + (new Error().stack) + 'XXX'; + } else { + return '{ ' + values.map(function(value, i) { return 'f' + i + ': ' + value }).join(', ') + ' }' + } +} + +function makeStructuralReturn(values) { + if (USE_TYPED_ARRAYS == 2) { + var i = 0; + return 'return (' + values.slice(1).map(function(value) { + return ASM_JS ? 'asm.setTempRet' + (i++) + '(' + value + ')' + : 'tempRet' + (i++) + ' = ' + value; + }).concat([values[0]]).join(',') + ')'; + } else { + var i = 0; + return 'return { ' + values.map(function(value) { + return 'f' + (i++) + ': ' + value; + }).join(', ') + ' }'; + } +} + +function makeStructuralAccess(ident, i) { + if (USE_TYPED_ARRAYS == 2) { + return ident + '$' + i; + } else { + return ident + '.f' + i; + } } // From parseLLVMSegment @@ -1537,6 +1672,7 @@ function finalizeLLVMParameter(param, noIndexizeFunctions) { ret = parseI64Constant(ret); } ret = parseNumerical(ret, param.type); + ret = asmEnsureFloat(ret, param.type); } else if (param.intertype == 'structvalue') { ret = makeLLVMStruct(param.params.map(function(value) { return finalizeLLVMParameter(value, noIndexizeFunctions) })); } else if (param.intertype === 'blockaddress') { @@ -1619,30 +1755,36 @@ function makeSignOp(value, type, op, force, ignore) { function makeRounding(value, bits, signed, floatConversion) { // TODO: handle roundings of i64s assert(bits); - // C rounds to 0 (-5.5 to -5, +5.5 to 5), while JS has no direct way to do that. - if (bits <= 32 && signed) return '((' + value + ')&-1)'; // This is fast and even correct, for all cases. Note that it is the same - // as |0, but &-1 hints to the js optimizer that this is a rounding correction - // Do Math.floor, which is reasonably fast, if we either don't care, or if we can be sure - // the value is non-negative - if (!correctRoundings() || (!signed && !floatConversion)) return 'Math.floor(' + value + ')'; - // We are left with >32 bits signed, or a float conversion. Check and correct inline - // Note that if converting a float, we may have the wrong sign at this point! But, we have - // been rounded properly regardless, and we will be sign-corrected later when actually used, if - // necessary. - return makeInlineCalculation('VALUE >= 0 ? Math.floor(VALUE) : Math.ceil(VALUE)', value, 'tempBigIntR'); -/* refactored version - needs perf testing TODO - if (bits <= 32) { - if (signed) { - return '((' + value + ')&-1)'; // &-1 (instead of |0) hints to the js optimizer that this is a rounding correction - } else { - return '((' + value + ')>>>0)'; + if (!ASM_JS) { + // C rounds to 0 (-5.5 to -5, +5.5 to 5), while JS has no direct way to do that. + if (bits <= 32 && signed) return '((' + value + ')&-1)'; // This is fast and even correct, for all cases. Note that it is the same + // as |0, but &-1 hints to the js optimizer that this is a rounding correction + // Do Math.floor, which is reasonably fast, if we either don't care, or if we can be sure + // the value is non-negative + if (!correctRoundings() || (!signed && !floatConversion)) return 'Math.floor(' + value + ')'; + // We are left with >32 bits signed, or a float conversion. Check and correct inline + // Note that if converting a float, we may have the wrong sign at this point! But, we have + // been rounded properly regardless, and we will be sign-corrected later when actually used, if + // necessary. + return makeInlineCalculation('VALUE >= 0 ? Math.floor(VALUE) : Math.ceil(VALUE)', value, 'tempBigIntR'); + } else { + // asm.js mode, cleaner refactoring of this function as well. TODO: use in non-asm case, most of this + if (floatConversion && bits <= 32) { + return '(~~(' + value + '))'; // explicit float-to-int conversion + } + + if (bits <= 32) { + if (signed) { + return '((' + value + ')&-1)'; // &-1 (instead of |0) hints to the js optimizer that this is a rounding correction + } else { + return '((' + value + ')>>>0)'; + } } + // Math.floor is reasonably fast if we don't care about corrections (and even correct if unsigned) + if (!correctRoundings() || !signed) return 'Math.floor(' + value + ')'; + // We are left with >32 bits + return makeInlineCalculation('VALUE >= 0 ? Math.floor(VALUE) : Math.ceil(VALUE)', value, 'tempBigIntR'); } - // Math.floor is reasonably fast if we don't care about corrections (and even correct if unsigned) - if (!correctRoundings() || !signed) return 'Math.floor(' + value + ')'; - // We are left with >32 bits - return makeInlineCalculation('VALUE >= 0 ? Math.floor(VALUE) : Math.ceil(VALUE)', value, 'tempBigIntR'); -*/ } // fptoui and fptosi are not in these, because we need to be careful about what we do there. We can't @@ -1716,8 +1858,8 @@ function processMathop(item) { } function i64PreciseOp(type, lastArg) { Types.preciseI64MathUsed = true; - return finish(['(i64Math.' + type + '(' + low1 + ',' + high1 + ',' + low2 + ',' + high2 + - (lastArg ? ',' + lastArg : '') + '),i64Math.result[0])', 'i64Math.result[1]']); + return finish(['(i64Math' + (ASM_JS ? '_' : '.') + type + '(' + low1 + ',' + high1 + ',' + low2 + ',' + high2 + + (lastArg ? ',' + lastArg : '') + '),' + makeGetValue('tempDoublePtr', 0, 'i32') + ')', makeGetValue('tempDoublePtr', Runtime.getNativeTypeSize('i32'), 'i32')]); } switch (op) { // basic integer ops @@ -1734,7 +1876,8 @@ function processMathop(item) { case 'ashr': case 'lshr': { if (!isNumber(idents[1])) { - return 'Runtime.bitshift64(' + idents[0] + '[0], ' + idents[0] + '[1],"' + op + '",' + stripCorrections(idents[1]) + '[0]|0)'; + return '(Runtime' + (ASM_JS ? '_' : '.') + 'bitshift64(' + idents[0] + '[0], ' + idents[0] + '[1],"' + op + '",' + stripCorrections(idents[1]) + '[0]|0),' + + '[' + makeGetTempDouble(0) + ',' + makeGetTempDouble(1) + '])'; } bits = parseInt(idents[1]); var ander = Math.pow(2, bits)-1; @@ -1851,15 +1994,15 @@ function processMathop(item) { var outType = item.type; if (inType in Runtime.INT_TYPES && outType in Runtime.FLOAT_TYPES) { if (legalizedI64s) { - return '(tempDoubleI32[0]=' + idents[0] + '$0, tempDoubleI32[1]=' + idents[0] + '$1, tempDoubleF64[0])'; + return '(HEAP32[tempDoublePtr>>2]=' + idents[0] + '$0, HEAP32[tempDoublePtr+4>>2]=' + idents[0] + '$1, HEAPF64[tempDoublePtr>>3])'; } else { - return makeInlineCalculation('tempDoubleI32[0]=VALUE[0],tempDoubleI32[1]=VALUE[1],tempDoubleF64[0]', idents[0], 'tempI64'); + return makeInlineCalculation('HEAP32[tempDoublePtr>>2]=VALUE[0],HEAP32[tempDoublePtr+4>>2]=VALUE[1],HEAPF64[tempDoublePtr>>>3]', idents[0], 'tempI64'); } } else if (inType in Runtime.FLOAT_TYPES && outType in Runtime.INT_TYPES) { if (legalizedI64s) { - return 'tempDoubleF64[0]=' + idents[0] + '; ' + finish(['tempDoubleI32[0]','tempDoubleI32[1]']); + return 'HEAPF64[tempDoublePtr>>3]=' + idents[0] + '; ' + finish(['HEAP32[tempDoublePtr>>2]','HEAP32[tempDoublePtr+4>>2]']); } else { - return '(tempDoubleF64[0]=' + idents[0] + ',[tempDoubleI32[0],tempDoubleI32[1]])'; + return '(HEAPF64[tempDoublePtr>>3]=' + idents[0] + ',[HEAP32[tempDoublePtr>>2],HEAP32[tempDoublePtr+4>>2]])'; } } else { throw 'Invalid USE_TYPED_ARRAYS == 2 bitcast: ' + dump(item) + ' : ' + item.params[0].type; @@ -1877,7 +2020,7 @@ function processMathop(item) { case 'mul': { if (bits == 32 && PRECISE_I32_MUL) { Types.preciseI64MathUsed = true; - return '(i64Math.multiply(' + idents[0] + ',0,' + idents[1] + ',0),i64Math.result[0])'; + return '(i64Math' + (ASM_JS ? '_' : '.') + 'multiply(' + idents[0] + ',0,' + idents[1] + ',0),' + makeGetValue('tempDoublePtr', 0, 'i32') + ')'; } else { return handleOverflow(getFastValue(idents[0], '*', idents[1], item.type), bits); } @@ -1927,7 +2070,7 @@ function processMathop(item) { case 'fdiv': return getFastValue(idents[0], '/', idents[1], item.type); case 'fmul': return getFastValue(idents[0], '*', idents[1], item.type); case 'frem': return getFastValue(idents[0], '%', idents[1], item.type); - case 'uitofp': case 'sitofp': return idents[0]; + case 'uitofp': case 'sitofp': return asmCoercion(idents[0], 'double'); case 'fptoui': case 'fptosi': return makeRounding(idents[0], bitsLeft, op === 'fptosi', true); // TODO: We sometimes generate false instead of 0, etc., in the *cmps. It seemed slightly faster before, but worth rechecking @@ -1970,7 +2113,7 @@ function processMathop(item) { // then unsigning that i32... which would give something huge. case 'zext': case 'fpext': case 'sext': return idents[0]; case 'fptrunc': return idents[0]; - case 'select': return idents[0] + ' ? ' + idents[1] + ' : ' + idents[2]; + case 'select': return idents[0] + ' ? ' + asmEnsureFloat(idents[1], item.type) + ' : ' + asmEnsureFloat(idents[2], item.type); case 'ptrtoint': case 'inttoptr': { var ret = ''; if (QUANTUM_SIZE == 1) { @@ -1998,9 +2141,9 @@ function processMathop(item) { (inType in Runtime.FLOAT_TYPES && outType in Runtime.INT_TYPES)) { assert(USE_TYPED_ARRAYS == 2, 'Can only bitcast ints <-> floats with typed arrays mode 2'); if (inType in Runtime.INT_TYPES) { - return '(tempDoubleI32[0] = ' + idents[0] + ',tempDoubleF32[0])'; + return '(HEAP32[tempDoublePtr>>2] = ' + idents[0] + ',HEAPF32[tempDoublePtr>>2])'; } else { - return '(tempDoubleF32[0] = ' + idents[0] + ',tempDoubleI32[0])'; + return '(HEAPF32[tempDoublePtr>>2] = ' + idents[0] + ',HEAP32[tempDoublePtr>>2])'; } } return idents[0]; diff --git a/src/postamble.js b/src/postamble.js index 144b5af9..5f541733 100644 --- a/src/postamble.js +++ b/src/postamble.js @@ -18,12 +18,16 @@ Module.callMain = function callMain(args) { argv = allocate(argv, 'i32', ALLOC_STATIC); #if CATCH_EXIT_CODE + var initialStackTop = STACKTOP; try { - return _main(argc, argv, 0); + return Module['_main'](argc, argv, 0); } catch(e) { if (e.name == "ExitStatus") return e.status; throw e; } + finally { + STACKTOP = initialStackTop; + } #else - return _main(argc, argv, 0); + return Module['_main'](argc, argv, 0); #endif } diff --git a/src/preamble.js b/src/preamble.js index 0917f977..cb01994f 100644 --- a/src/preamble.js +++ b/src/preamble.js @@ -275,7 +275,7 @@ Module['printProfiling'] = printProfiling; // Runtime essentials //======================================== -var __THREW__ = false; // Used in checking for thrown exceptions. +var __THREW__ = 0; // Used in checking for thrown exceptions. var setjmpId = 1; // Used in setjmp/longjmp var setjmpLabels = {}; @@ -287,6 +287,7 @@ var undef = 0; var tempValue, tempInt, tempBigInt, tempInt2, tempBigInt2, tempPair, tempBigIntI, tempBigIntR, tempBigIntS, tempBigIntP, tempBigIntD; #if USE_TYPED_ARRAYS == 2 var tempI64, tempI64b; +var tempRet0, tempRet1, tempRet2, tempRet3, tempRet4, tempRet5, tempRet6, tempRet7, tempRet8, tempRet9; #endif function abort(text) { @@ -307,18 +308,10 @@ var globalScope = this; // defined with extern "C"). // // Note: LLVM optimizations can inline and remove functions, after which you will not be -// able to call them. Adding +// able to call them. Closure can also do so. To avoid that, add your function to +// the exports using something like // -// __attribute__((used)) -// -// to the function definition will prevent that. -// -// Note: Closure optimizations will minify function names, making -// functions no longer callable. If you run closure (on by default -// in -O2 and above), you should export the functions you will call -// by calling emcc with something like -// -// -s EXPORTED_FUNCTIONS='["_func1","_func2"]' +// -s EXPORTED_FUNCTIONS='["_main", "_myfunc"]' // // @param ident The name of the C function (note that C++ functions will be name-mangled - use extern "C") // @param returnType The return type of the function, one of the JS types 'number', 'string' or 'array' (use 'number' for any C pointer, and @@ -577,9 +570,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; @@ -601,7 +591,7 @@ var STATICTOP; #if USE_TYPED_ARRAYS function enlargeMemory() { #if ALLOW_MEMORY_GROWTH == 0 - abort('Cannot enlarge memory arrays. Either (1) compile with -s TOTAL_MEMORY=X with X higher than the current value ( ' + TOTAL_MEMORY + '), (2) compile with ALLOW_MEMORY_GROWTH which adjusts the size at runtime but prevents some optimizations, or (3) set Module.TOTAL_MEMORY before the program runs.'); + abort('Cannot enlarge memory arrays. Either (1) compile with -s TOTAL_MEMORY=X with X higher than the current value, (2) compile with ALLOW_MEMORY_GROWTH which adjusts the size at runtime but prevents some optimizations, or (3) set Module.TOTAL_MEMORY before the program runs.'); #else // TOTAL_MEMORY is the current size of the actual array, and STATICTOP is the new top. #if ASSERTIONS @@ -699,47 +689,47 @@ Module['HEAPF64'] = HEAPF64; #endif STACK_ROOT = STACKTOP = Runtime.alignMemory(1); -STACK_MAX = STACK_ROOT + TOTAL_STACK; +STACK_MAX = TOTAL_STACK; // we lose a little stack here, but TOTAL_STACK is nice and round so use that as the max #if USE_TYPED_ARRAYS == 2 -var tempDoublePtr = Runtime.alignMemory(STACK_MAX, 8); -var tempDoubleI8 = HEAP8.subarray(tempDoublePtr); -var tempDoubleI32 = HEAP32.subarray(tempDoublePtr >> 2); -var tempDoubleF32 = HEAPF32.subarray(tempDoublePtr >> 2); -var tempDoubleF64 = HEAPF64.subarray(tempDoublePtr >> 3); +var tempDoublePtr = Runtime.alignMemory(allocate(12, 'i8', ALLOC_STACK), 8); +assert(tempDoublePtr % 8 == 0); function copyTempFloat(ptr) { // functions, because inlining this code is increases code size too much - tempDoubleI8[0] = HEAP8[ptr]; - tempDoubleI8[1] = HEAP8[ptr+1]; - tempDoubleI8[2] = HEAP8[ptr+2]; - tempDoubleI8[3] = HEAP8[ptr+3]; + HEAP8[tempDoublePtr] = HEAP8[ptr]; + HEAP8[tempDoublePtr+1] = HEAP8[ptr+1]; + HEAP8[tempDoublePtr+2] = HEAP8[ptr+2]; + HEAP8[tempDoublePtr+3] = HEAP8[ptr+3]; } function copyTempDouble(ptr) { - tempDoubleI8[0] = HEAP8[ptr]; - tempDoubleI8[1] = HEAP8[ptr+1]; - tempDoubleI8[2] = HEAP8[ptr+2]; - tempDoubleI8[3] = HEAP8[ptr+3]; - tempDoubleI8[4] = HEAP8[ptr+4]; - tempDoubleI8[5] = HEAP8[ptr+5]; - tempDoubleI8[6] = HEAP8[ptr+6]; - tempDoubleI8[7] = HEAP8[ptr+7]; + HEAP8[tempDoublePtr] = HEAP8[ptr]; + HEAP8[tempDoublePtr+1] = HEAP8[ptr+1]; + HEAP8[tempDoublePtr+2] = HEAP8[ptr+2]; + HEAP8[tempDoublePtr+3] = HEAP8[ptr+3]; + HEAP8[tempDoublePtr+4] = HEAP8[ptr+4]; + HEAP8[tempDoublePtr+5] = HEAP8[ptr+5]; + HEAP8[tempDoublePtr+6] = HEAP8[ptr+6]; + HEAP8[tempDoublePtr+7] = HEAP8[ptr+7]; } -STACK_MAX = tempDoublePtr + 8; #endif -STATICTOP = alignMemoryPage(STACK_MAX); - +STATICTOP = STACK_MAX; assert(STATICTOP < TOTAL_MEMORY); // Stack must fit in TOTAL_MEMORY; allocations from here on may enlarge TOTAL_MEMORY -var nullString = allocate(intArrayFromString('(null)'), 'i8', ALLOC_STATIC); +var nullString = allocate(intArrayFromString('(null)'), 'i8', ALLOC_STACK); function callRuntimeCallbacks(callbacks) { while(callbacks.length > 0) { var callback = callbacks.shift(); var func = callback.func; if (typeof func === 'number') { - func = FUNCTION_TABLE[func]; + if (callback.arg === undefined) { + Runtime.dynCall('v', func); + } else { + Runtime.dynCall('vi', func, [callback.arg]); + } + } else { + func(callback.arg === undefined ? null : callback.arg); } - func(callback.arg === undefined ? null : callback.arg); } } @@ -881,7 +871,8 @@ function removeRunDependency(id) { clearInterval(runDependencyWatcher); runDependencyWatcher = null; } - if (!calledRun) run(); + // If run has never been called, and we should call run (INVOKE_RUN is true, and Module.noInitialRun is not false) + if (!calledRun && shouldRunNow) run(); } } Module['removeRunDependency'] = removeRunDependency; diff --git a/src/relooper/Relooper.cpp b/src/relooper/Relooper.cpp index 933fda96..ae8577b1 100644 --- a/src/relooper/Relooper.cpp +++ b/src/relooper/Relooper.cpp @@ -58,6 +58,8 @@ void PutIndented(const char *String) { *OutputBuffer = 0; } +static int AsmJS = 0; + // Indenter #if EMSCRIPTEN @@ -271,7 +273,11 @@ void MultipleShape::Render(bool InLoop) { RenderLoopPrefix(); bool First = true; for (BlockShapeMap::iterator iter = InnerMap.begin(); iter != InnerMap.end(); iter++) { - PrintIndented("%sif (label == %d) {\n", First ? "" : "else ", iter->first->Id); + if (AsmJS) { + PrintIndented("%sif ((label|0) == %d) {\n", First ? "" : "else ", iter->first->Id); + } else { + PrintIndented("%sif (label == %d) {\n", First ? "" : "else ", iter->first->Id); + } First = false; Indenter::Indent(); iter->second->Render(InLoop); @@ -977,6 +983,10 @@ void Relooper::MakeOutputBuffer(int Size) { OutputBufferSize = Size; } +void Relooper::SetAsmJSMode(int On) { + AsmJS = On; +} + #if DEBUG // Debugging @@ -1018,6 +1028,10 @@ void rl_make_output_buffer(int size) { Relooper::SetOutputBuffer((char*)malloc(size), size); } +void rl_set_asm_js_mode(int on) { + Relooper::SetAsmJSMode(on); +} + void *rl_new_block(const char *text) { Block *ret = new Block(text); #if DEBUG diff --git a/src/relooper/Relooper.h b/src/relooper/Relooper.h index 08ac8e40..eac03738 100644 --- a/src/relooper/Relooper.h +++ b/src/relooper/Relooper.h @@ -200,6 +200,9 @@ struct Relooper { // Creates an output buffer. Must call this or SetOutputBuffer. static void MakeOutputBuffer(int Size); + + // Sets asm.js mode on or off (default is off) + static void SetAsmJSMode(int On); }; typedef std::set<Block*> BlockSet; @@ -231,6 +234,7 @@ extern "C" { RELOOPERDLL_API void rl_set_output_buffer(char *buffer, int size); RELOOPERDLL_API void rl_make_output_buffer(int size); +RELOOPERDLL_API void rl_set_asm_js_mode(int on); RELOOPERDLL_API void *rl_new_block(const char *text); RELOOPERDLL_API void rl_delete_block(void *block); RELOOPERDLL_API void rl_block_add_branch_to(void *from, void *to, const char *condition, const char *code); diff --git a/src/relooper/emscripten/Makefile b/src/relooper/emscripten/Makefile deleted file mode 100644 index 277dd538..00000000 --- a/src/relooper/emscripten/Makefile +++ /dev/null @@ -1,18 +0,0 @@ -EMSCRIPTEN = ~/Dev/emscripten -EMCC = $(EMSCRIPTEN)/emcc -BINDINGS_GENERATOR = $(EMSCRIPTEN)/tools/bindings_generator.py -NATIVIZER = $(EMSCRIPTEN)/tools/nativize_llvm.py - -all: relooper.js - -relooper.js: - $(EMCC) -O2 ../Relooper.cpp -I.. --post-js glue.js -o relooper.raw.js -s TOTAL_MEMORY=52428800 -s DEFAULT_LIBRARY_FUNCS_TO_INCLUDE='["memcpy", "memset", "malloc", "free", "puts"]' - echo "// Relooper, (C) 2012 Alon Zakai, MIT license, https://github.com/kripken/Relooper" > relooper.js - echo "var Relooper = (function() {" >> relooper.js - cat relooper.raw.js >> relooper.js - echo " return Module.Relooper;" >> relooper.js - echo "})();" >> relooper.js - -clean: - rm relooper.js - diff --git a/src/relooper/emscripten/glue.js b/src/relooper/emscripten/glue.js index 15998acf..36922185 100644 --- a/src/relooper/emscripten/glue.js +++ b/src/relooper/emscripten/glue.js @@ -49,6 +49,9 @@ RelooperGlue['setDebug'] = function(debug) { _rl_set_debugging(+!!debug); }; + RelooperGlue['setAsmJSMode'] = function(on) { + _rl_set_asm_js_mode(on); + }; Module['Relooper'] = RelooperGlue; diff --git a/src/relooper/test.txt b/src/relooper/test.txt index 12d0ef39..b7c8794d 100644 --- a/src/relooper/test.txt +++ b/src/relooper/test.txt @@ -54,7 +54,7 @@ while(1) { // code 2 if (!($2)) { var $x_1 = $x_0; - label = 18; + label = 19; break; } // code 3 @@ -64,7 +64,7 @@ while(1) { var $i_0 = $7;var $x_0 = $5; } } -if (label == 18) { +if (label == 19) { // code 7 } // code 4 diff --git a/src/runtime.js b/src/runtime.js index dd14e779..9d5e5e1f 100644 --- a/src/runtime.js +++ b/src/runtime.js @@ -13,7 +13,7 @@ var RuntimeGenerator = { if (init) { ret += sep + '_memset(' + type + 'TOP, 0, ' + size + ')'; } - ret += sep + type + 'TOP += ' + size; + ret += sep + type + 'TOP = (' + type + 'TOP + ' + size + ')|0'; if ({{{ QUANTUM_SIZE }}} > 1 && !ignoreAlign) { ret += sep + RuntimeGenerator.alignMemory(type + 'TOP', {{{ QUANTUM_SIZE }}}); } @@ -23,27 +23,27 @@ var RuntimeGenerator = { // An allocation that lives as long as the current function call stackAlloc: function(size, sep) { sep = sep || ';'; - if (USE_TYPED_ARRAYS === 2) 'STACKTOP += STACKTOP % ' + ({{{ QUANTUM_SIZE }}} - (isNumber(size) ? Math.min(size, {{{ QUANTUM_SIZE }}}) : {{{ QUANTUM_SIZE }}})) + sep; + if (USE_TYPED_ARRAYS === 2) 'STACKTOP = (STACKTOP + STACKTOP|0 % ' + ({{{ QUANTUM_SIZE }}} - (isNumber(size) ? Math.min(size, {{{ QUANTUM_SIZE }}}) : {{{ QUANTUM_SIZE }}})) + ')' + sep; // The stack is always QUANTUM SIZE aligned, so we may not need to force alignment here var ret = RuntimeGenerator.alloc(size, 'STACK', INIT_STACK, sep, USE_TYPED_ARRAYS != 2 || (isNumber(size) && parseInt(size) % {{{ QUANTUM_SIZE }}} == 0)); if (ASSERTIONS) { - ret += sep + 'assert(STACKTOP < STACK_ROOT + STACK_MAX, "Ran out of stack")'; + ret += sep + 'assert(STACKTOP|0 < STACK_MAX|0)'; } return ret; }, stackEnter: function(initial, force) { if (initial === 0 && SKIP_STACK_IN_SMALL && !force) return ''; - var ret = 'var __stackBase__ = STACKTOP'; - if (initial > 0) ret += '; STACKTOP += ' + initial; + var ret = 'var __stackBase__ = ' + (ASM_JS ? '0; __stackBase__ = ' : '') + 'STACKTOP'; + if (initial > 0) ret += '; STACKTOP = (STACKTOP + ' + initial + ')|0'; if (USE_TYPED_ARRAYS == 2) { assert(initial % QUANTUM_SIZE == 0); if (ASSERTIONS) { - ret += '; assert(STACKTOP % {{{ QUANTUM_SIZE }}} == 0, "Stack is unaligned")'; + ret += '; assert(STACKTOP|0 % {{{ QUANTUM_SIZE }}} == 0)'; } } if (ASSERTIONS) { - ret += '; assert(STACKTOP < STACK_MAX, "Ran out of stack")'; + ret += '; assert(STACKTOP < STACK_MAX)'; } if (INIT_STACK) { ret += '; _memset(__stackBase__, 0, ' + initial + ')'; @@ -124,36 +124,50 @@ var Runtime = { // Mirrors processMathop's treatment of constants (which we optimize directly) bitshift64: function(low, high, op, bits) { + var ret; var ander = Math.pow(2, bits)-1; if (bits < 32) { switch (op) { case 'shl': - return [low << bits, (high << bits) | ((low&(ander << (32 - bits))) >>> (32 - bits))]; + ret = [low << bits, (high << bits) | ((low&(ander << (32 - bits))) >>> (32 - bits))]; + break; case 'ashr': - return [(((low >>> bits ) | ((high&ander) << (32 - bits))) >> 0) >>> 0, (high >> bits) >>> 0]; + ret = [(((low >>> bits ) | ((high&ander) << (32 - bits))) >> 0) >>> 0, (high >> bits) >>> 0]; + break; case 'lshr': - return [((low >>> bits) | ((high&ander) << (32 - bits))) >>> 0, high >>> bits]; + ret = [((low >>> bits) | ((high&ander) << (32 - bits))) >>> 0, high >>> bits]; + break; } } else if (bits == 32) { switch (op) { case 'shl': - return [0, low]; + ret = [0, low]; + break; case 'ashr': - return [high, (high|0) < 0 ? ander : 0]; + ret = [high, (high|0) < 0 ? ander : 0]; + break; case 'lshr': - return [high, 0]; + ret = [high, 0]; + break; } } else { // bits > 32 switch (op) { case 'shl': - return [0, low << (bits - 32)]; + ret = [0, low << (bits - 32)]; + break; case 'ashr': - return [(high >> (bits - 32)) >>> 0, (high|0) < 0 ? ander : 0]; + ret = [(high >> (bits - 32)) >>> 0, (high|0) < 0 ? ander : 0]; + break; case 'lshr': - return [high >>> (bits - 32) , 0]; + ret = [high >>> (bits - 32) , 0]; + break; } } - abort('unknown bitshift64 op: ' + [value, op, bits]); +#if ASSERTIONS + assert(ret); +#endif + HEAP32[tempDoublePtr>>2] = ret[0]; // cannot use utility functions since we are in runtime itself + HEAP32[tempDoublePtr+4>>2] = ret[1]; }, // Imprecise bitops utilities @@ -311,10 +325,35 @@ var Runtime = { return ret; }, - addFunction: function(func) { - var ret = FUNCTION_TABLE.length; - FUNCTION_TABLE.push(func); - FUNCTION_TABLE.push(0); + dynCall: function(sig, ptr, args) { + if (args && args.length) { +#if ASSERTIONS + assert(args.length == sig.length-1); +#endif +#if ASM_JS + args.splice(0, 0, ptr); + return Module['dynCall_' + sig].apply(null, args); +#else + return FUNCTION_TABLE[ptr].apply(null, args); +#endif + } else { +#if ASSERTIONS + assert(sig.length == 1); +#endif +#if ASM_JS + return Module['dynCall_' + sig].call(null, ptr); +#else + return FUNCTION_TABLE[ptr](); +#endif + } + }, + + addFunction: function(func, sig) { + assert(sig); + var table = FUNCTION_TABLE; // TODO: support asm + var ret = table.length; + table.push(func); + table.push(0); return ret; }, @@ -328,10 +367,11 @@ var Runtime = { funcWrappers: {}, - getFuncWrapper: function(func) { + getFuncWrapper: function(func, sig) { + assert(sig); if (!Runtime.funcWrappers[func]) { Runtime.funcWrappers[func] = function() { - FUNCTION_TABLE[func].apply(null, arguments); + Runtime.dynCall(sig, func, arguments); }; } return Runtime.funcWrappers[func]; diff --git a/src/settings.js b/src/settings.js index c4d1df48..8ae287f9 100644 --- a/src/settings.js +++ b/src/settings.js @@ -43,7 +43,7 @@ var TOTAL_STACK = 5*1024*1024; // The total stack size. There is no way to enlar // value must be large enough for the program's requirements. If // assertions are on, we will assert on not exceeding this, otherwise, // it will fail silently. -var TOTAL_MEMORY = 10*1024*1024; // The total amount of memory to use. Using more memory than this will +var TOTAL_MEMORY = 16777216; // The total amount of memory to use. Using more memory than this will // cause us to expand the heap, which can be costly with typed arrays: // we need to copy the old heap into a new one in that case. var FAST_MEMORY = 2*1024*1024; // The amount of memory to initialize to 0. This ensures it will be @@ -118,7 +118,9 @@ var INLINING_LIMIT = 50; // A limit on inlining. If 0, we will inline normally i var CATCH_EXIT_CODE = 0; // If set, causes exit() to throw an exception object which is caught // in a try..catch block and results in the exit status being // returned from run(). If zero (the default), the program is just - // terminated with an error message. + // terminated with an error message, that is, the exception thrown + // by exit() is not handled in any way (in particular, the stack + // position will not be reset). // Generated code debugging options var SAFE_HEAP = 0; // Check each write to the heap, for example, this will give a clear @@ -138,7 +140,7 @@ var LABEL_FUNCTION_FILTERS = []; // Filters for function label debug. // labels of functions that is equaled to // one of the filters are printed out // When the array is empty, the filter is disabled. -var EXCEPTION_DEBUG = 1; // Print out exceptions in emscriptened code +var EXCEPTION_DEBUG = 0; // Print out exceptions in emscriptened code var LIBRARY_DEBUG = 0; // Print out when we enter a library call (library*.js). You can also unset // Runtime.debug at runtime for logging to cease, and can set it when you @@ -200,7 +202,7 @@ var PGO = 0; // Profile-guided optimization. // All CORRECT_* options default to 1 with PGO builds. // See https://github.com/kripken/emscripten/wiki/Optimizing-Code for more info -var NAMED_GLOBALS = 1; // If 1, we use global variables for globals. Otherwise +var NAMED_GLOBALS = 0; // If 1, we use global variables for globals. Otherwise // they are referred to by a base plus an offset (called an indexed global), // saving global variables but adding runtime overhead. @@ -220,6 +222,12 @@ var DEFAULT_LIBRARY_FUNCS_TO_INCLUDE = ['memcpy', 'memset', 'malloc', 'free', '$ // add it here (and in EXPORTED FUNCTIONS with prefix // "_", for closure). +var LIBRARY_DEPS_TO_AUTOEXPORT = ['memcpy']; // This list is also used to determine + // auto-exporting of library dependencies (i.e., functions that + // might be dependencies of JS library functions, that if + // so we must export so that if they are implemented in C + // they will be accessible, in ASM_JS mode). + var IGNORED_FUNCTIONS = []; // Functions that we should not generate, neither a stub nor a complete function. // This is useful if your project code includes a function, and you want to replace // that in the compiled code with your own handwritten JS. (Of course even without @@ -301,6 +309,11 @@ var HEADLESS = 0; // If 1, will include shim code that tries to 'fake' a browser // very partial - it is hard to fake a whole browser! - so // keep your expectations low for this to work. +var ASM_JS = 0; // If 1, generate code in asm.js format. XXX This is highly experimental, + // and will not work on most codebases yet. It is NOT recommended that you + // try this yet. +var USE_MATH_IMUL = 0; // If 1, use Math.imul when useful + var NECESSARY_BLOCKADDRS = []; // List of (function, block) for all block addresses that are taken. // Compiler debugging options @@ -1186,6 +1199,8 @@ var C_DEFINES = {'SI_MESGQ': '5', '_SC_TTY_NAME_MAX': '41', 'AF_INET': '1', 'AF_INET6': '6', - 'FIONREAD': '1' + 'FIONREAD': '1', + 'SOCK_STREAM': '200', + 'IPPROTO_TCP': 1 }; diff --git a/src/utility.js b/src/utility.js index 84b50ce9..63582ae8 100644 --- a/src/utility.js +++ b/src/utility.js @@ -321,6 +321,12 @@ function isPowerOfTwo(x) { return x > 0 && ((x & (x-1)) == 0); } +function ceilPowerOfTwo(x) { + var ret = 1; + while (ret < x) ret <<= 1; + return ret; +} + function Benchmarker() { var starts = {}, times = {}, counts = {}; this.start = function(id) { diff --git a/system/include/emscripten/emscripten.h b/system/include/emscripten/emscripten.h index 926fe2e5..93551f39 100644 --- a/system/include/emscripten/emscripten.h +++ b/system/include/emscripten/emscripten.h @@ -20,10 +20,11 @@ extern "C" { * closure may still eliminate it at the JS level, for which you * should use EXPORTED_FUNCTIONS (see settings.js). * - * Example usage: - * void EMSCRIPTEN_KEEPALIVE my_function() { .. } + * **DEPRECATED**: Use EXPORTED_FUNCTIONS instead, which will work + * with closure, asm.js, etc. For example + * -s EXPORTED_FUNCTIONS=["_main", "myfunc"] */ -#define EMSCRIPTEN_KEEPALIVE __attribute__((used)) +/* #define EMSCRIPTEN_KEEPALIVE __attribute__((used)) */ /* * Interface to the underlying JS engine. This function will @@ -211,6 +212,23 @@ void emscripten_async_wget(const char* url, const char* file, void (*onload)(con void emscripten_async_wget_data(const char* url, void *arg, void (*onload)(void*, void*, int), void (*onerror)(void*)); /* + * More feature-complete version of emscripten_async_wget. Note: + * this version is experimental. + * + * The requestype is 'GET' or 'POST', + * If is post request, param is the post parameter + * like key=value&key2=value2. + * The param 'arg' is a pointer will be pass to the callback + * When file is ready then 'onload' callback will called. + * During the download 'onprogress' callback will called. + * If any error occurred 'onerror' will called. + * The callbacks are called with an object pointer give in parameter + * and file if is a success, the progress value during progress + * and http status code if is an error. + */ +void emscripten_async_wget2(const char* url, const char* file, const char* requesttype, const char* param, void *arg, void (*onload)(void*, const char*), void (*onerror)(void*, int), void (*onprogress)(void*, int)); + +/* * Prepare a file in asynchronous way. This does just the * preparation part of emscripten_async_wget, that is, it * works on file data already present, and asynchronously @@ -304,6 +322,17 @@ void emscripten_worker_respond(char *data, int size); int emscripten_get_worker_queue_size(worker_handle worker); /* + * Select the networking backend to use. By default emscripten's + * socket/networking implementation will use websockets, with this + * function you can change that to WebRTC. + * This function must be called before any network functions are + * called. + */ +#define EMSCRIPTEN_NETWORK_WEBSOCKETS 0 +#define EMSCRIPTEN_NETWORK_WEBRTC 1 +void emscripten_set_network_backend(int backend); + +/* * Profiling tools. * INIT must be called first, with the maximum identifier that * will be used. BEGIN will add some code that marks diff --git a/system/include/sysexits.h b/system/include/sysexits.h new file mode 100644 index 00000000..cc3e786b --- /dev/null +++ b/system/include/sysexits.h @@ -0,0 +1,108 @@ +/* +* Copyright (c) 1987, 1993 +* The Regents of the University of California. All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* 1. Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* 2. Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* 4. Neither the name of the University nor the names of its contributors +* may be used to endorse or promote products derived from this software +* without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +* SUCH DAMAGE. +* +* @(#)sysexits.h 8.1 (Berkeley) 6/2/93 +*/ +#ifndef _SYSEXITS_H +#define _SYSEXITS_H 1 +/* +* SYSEXITS.H -- Exit status codes for system programs. +* +* This include file attempts to categorize possible error +* exit statuses for system programs, notably delivermail +* and the Berkeley network. +* +* Error numbers begin at EX__BASE to reduce the possibility of +* clashing with other exit statuses that random programs may +* already return. The meaning of the codes is approximately +* as follows: +* +* EX_USAGE -- The command was used incorrectly, e.g., with +* the wrong number of arguments, a bad flag, a bad +* syntax in a parameter, or whatever. +* EX_DATAERR -- The input data was incorrect in some way. +* This should only be used for user's data & not +* system files. +* EX_NOINPUT -- An input file (not a system file) did not +* exist or was not readable. This could also include +* errors like "No message" to a mailer (if it cared +* to catch it). +* EX_NOUSER -- The user specified did not exist. This might +* be used for mail addresses or remote logins. +* EX_NOHOST -- The host specified did not exist. This is used +* in mail addresses or network requests. +* EX_UNAVAILABLE -- A service is unavailable. This can occur +* if a support program or file does not exist. This +* can also be used as a catchall message when something +* you wanted to do doesn't work, but you don't know +* why. +* EX_SOFTWARE -- An internal software error has been detected. +* This should be limited to non-operating system related +* errors as possible. +* EX_OSERR -- An operating system error has been detected. +* This is intended to be used for such things as "cannot +* fork", "cannot create pipe", or the like. It includes +* things like getuid returning a user that does not +* exist in the passwd file. +* EX_OSFILE -- Some system file (e.g., /etc/passwd, /etc/utmp, +* etc.) does not exist, cannot be opened, or has some +* sort of error (e.g., syntax error). +* EX_CANTCREAT -- A (user specified) output file cannot be +* created. +* EX_IOERR -- An error occurred while doing I/O on some file. +* EX_TEMPFAIL -- temporary failure, indicating something that +* is not really an error. In sendmail, this means +* that a mailer (e.g.) could not create a connection, +* and the request should be reattempted later. +* EX_PROTOCOL -- the remote system returned something that +* was "not possible" during a protocol exchange. +* EX_NOPERM -- You did not have sufficient permission to +* perform the operation. This is not intended for +* file system problems, which should use NOINPUT or +* CANTCREAT, but rather for higher level permissions. +*/ +#define EX_OK 0 /* successful termination */ +#define EX__BASE 64 /* base value for error messages */ +#define EX_USAGE 64 /* command line usage error */ +#define EX_DATAERR 65 /* data format error */ +#define EX_NOINPUT 66 /* cannot open input */ +#define EX_NOUSER 67 /* addressee unknown */ +#define EX_NOHOST 68 /* host name unknown */ +#define EX_UNAVAILABLE 69 /* service unavailable */ +#define EX_SOFTWARE 70 /* internal software error */ +#define EX_OSERR 71 /* system error (e.g., can't fork) */ +#define EX_OSFILE 72 /* critical OS file missing */ +#define EX_CANTCREAT 73 /* can't create (user) output file */ +#define EX_IOERR 74 /* input/output error */ +#define EX_TEMPFAIL 75 /* temp failure; user is invited to retry */ +#define EX_PROTOCOL 76 /* remote error in protocol */ +#define EX_NOPERM 77 /* permission denied */ +#define EX_CONFIG 78 /* configuration error */ +#define EX__MAX 78 /* maximum listed value */ +#endif /* sysexits.h */ + diff --git a/system/lib/dlmalloc.symbols b/system/lib/libc.symbols index d41f4140..b98a79e4 100644 --- a/system/lib/dlmalloc.symbols +++ b/system/lib/libc.symbols @@ -48,3 +48,8 @@ _ZNSt20bad_array_new_lengthC2Ev _ZNSt20bad_array_new_lengthD0Ev _ZNSt20bad_array_new_lengthD1Ev _ZNSt20bad_array_new_lengthD2Ev +memcpy +llvm.memcpy.i32 +llvm.memcpy.i64 +llvm.memcpy.p0i8.p0i8.i32 +llvm.memcpy.p0i8.p0i8.i64 diff --git a/system/lib/libc/musl/COPYRIGHT b/system/lib/libc/musl/COPYRIGHT new file mode 100644 index 00000000..c0817619 --- /dev/null +++ b/system/lib/libc/musl/COPYRIGHT @@ -0,0 +1,92 @@ +musl as a whole is licensed under the following standard MIT license: + +Copyright © 2005-2012 Rich Felker + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +Portions of this software are contributed or derived from software +authored by third parties. Complete details on the copyright status of +all code included in musl follows below: + + +The TRE regular expression implementation (src/regex/reg* and +src/regex/tre*) is Copyright © 2001-2008 Ville Laurikari and licensed +under a 2-clause BSD license (license text in the source files). The +included version has been heavily modified by Rich Felker in 2012, in +the interests of size, simplicity, and namespace cleanliness. + +Most of the math library code (src/math/* and src/complex/*) is +Copyright © 1993,2004 Sun Microsystems or +Copyright © 2003-2011 David Schultz or +Copyright © 2003-2009 Steven G. Kargl or +Copyright © 2003-2009 Bruce D. Evans or +Copyright © 2008 Stephen L. Moshier +and labelled as such. All have been licensed under extremely +permissive terms. See the comments in the individual files for +details. + +The implementation of DES for crypt (src/misc/crypt_des.c) is +Copyright © 1994 David Burren. It is licensed under a BSD license. + +The implementation of blowfish crypt (src/misc/crypt_blowfish.c) was +originally written by Solar Designer and placed into the public +domain. The code also comes with a fallback permissive license for use +in jurisdictions that may not recognize the public domain. + +The smoothsort implementation (src/stdlib/qsort.c) is Copyright © 2011 +Valentin Ochs and is licensed under an MIT-style license. + +The BSD PRNG implementation (src/prng/random.c) and XSI search API +(src/search/*.c) functions are Copyright © 2011 Szabolcs Nagy and +licensed under following terms: "Permission to use, copy, modify, +and/or distribute this code for any purpose with or without fee is +hereby granted. There is no warranty." + +The x86_64 port was written by Nicholas J. Kain. Several files (crt) +were released into the public domain; others are licensed under the +standard MIT license terms at the top of this file. See individual +files for their copyright status. + +The mips and microblaze ports were originally written by Richard +Pennington for use in the ellcc project. The original code was adapted +by Rich Felker for build system and code conventions during upstream +integration. It is licensed under the standard MIT terms. + +The powerpc port was also originally written by Richard Pennington, +and later supplemented and integrated by John Spencer. It is licensed +under the standard MIT terms. + +All other files which have no copyright comments are original works +Copyright © 2005-2012 Rich Felker, the main author of this library. +The decision to exclude such comments is intentional, as it should be +possible to carry around the complete source code on tiny storage +media. All public header files (include/*) should be treated as Public +Domain as they intentionally contain no content which can be covered +by copyright. Some source modules may fall in this category as well. +If you believe that a file is so trivial that it should be in the +Public Domain, please contact me and, if I agree, I will explicitly +release it from copyright. + +The following files are trivial, in my opinion not copyrightable in +the first place, and hereby explicitly released to the Public Domain: + +All public headers: include/* +Startup files: crt/* diff --git a/system/lib/libc/musl/memcpy.c b/system/lib/libc/musl/memcpy.c new file mode 100644 index 00000000..8e98302f --- /dev/null +++ b/system/lib/libc/musl/memcpy.c @@ -0,0 +1,29 @@ +#include <string.h> +#include <stdlib.h> +#include <stdint.h> + +#define SS (sizeof(size_t)) +#define ALIGN (sizeof(size_t)-1) +#define ONES ((size_t)-1/UCHAR_MAX) + +void *memcpy(void *restrict dest, const void *restrict src, size_t n) +{ + unsigned char *d = dest; + const unsigned char *s = src; + + if (((uintptr_t)d & ALIGN) != ((uintptr_t)s & ALIGN)) + goto misaligned; + + for (; ((uintptr_t)d & ALIGN) && n; n--) *d++ = *s++; + if (n) { + size_t *wd = (void *)d; + const size_t *ws = (const void *)s; + + for (; n>=SS; n-=SS) *wd++ = *ws++; + d = (void *)wd; + s = (const void *)ws; +misaligned: + for (; n; n--) *d++ = *s++; + } + return dest; +} diff --git a/tests/cases/aliasbitcast2.ll b/tests/cases/aliasbitcast2_noasm.ll index 8537e272..8537e272 100644 --- a/tests/cases/aliasbitcast2.ll +++ b/tests/cases/aliasbitcast2_noasm.ll diff --git a/tests/cases/aliasbitcast3.ll b/tests/cases/aliasbitcast3_noasm.ll index 4ff969e3..4ff969e3 100644 --- a/tests/cases/aliasbitcast3.ll +++ b/tests/cases/aliasbitcast3_noasm.ll diff --git a/tests/cases/aliasbitcastdollar.ll b/tests/cases/aliasbitcastdollar_noasm.ll index 1ecf6047..1ecf6047 100644 --- a/tests/cases/aliasbitcastdollar.ll +++ b/tests/cases/aliasbitcastdollar_noasm.ll diff --git a/tests/cases/gepoverflow.txt b/tests/cases/gepoverflow.txt index e01c78dd..31d67161 100644 --- a/tests/cases/gepoverflow.txt +++ b/tests/cases/gepoverflow.txt @@ -1,2 +1,2 @@ -*5246470,5247040* +*5242366,5242936* *-514,56* diff --git a/tests/cases/longjmp_tiny.ll b/tests/cases/longjmp_tiny_noasm.ll index 0045847c..0045847c 100644 --- a/tests/cases/longjmp_tiny.ll +++ b/tests/cases/longjmp_tiny_noasm.ll diff --git a/tests/cases/longjmp_tiny.txt b/tests/cases/longjmp_tiny_noasm.txt index 8a0aa386..8a0aa386 100644 --- a/tests/cases/longjmp_tiny.txt +++ b/tests/cases/longjmp_tiny_noasm.txt diff --git a/tests/cases/selectstruct.ll b/tests/cases/selectstruct.ll index 90c15ac7..5c9fecf7 100644 --- a/tests/cases/selectstruct.ll +++ b/tests/cases/selectstruct.ll @@ -10,7 +10,8 @@ entry: %retval = alloca i32, align 4 ; [#uses=1 type=i32*] %. = select i1 %retval, { i32, i32 } { i32 55, i32 99 }, { i32, i32 } { i32 2, i32 6 } ; [#uses=1 type={ i32, i32 }] store i32 0, i32* %retval - %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([15 x i8]* @.str, i32 0, i32 0), i32 %.) ; [#uses=0 type=i32] + %.1 = extractvalue { i32, i32 } %., 0 + %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([15 x i8]* @.str, i32 0, i32 0), i32 %.1) ; [#uses=0 type=i32] ret i32 1 } diff --git a/tests/cases/structparam.ll b/tests/cases/structparam.ll new file mode 100644 index 00000000..c59ad600 --- /dev/null +++ b/tests/cases/structparam.ll @@ -0,0 +1,36 @@ +; ModuleID = '/dev/shm/tmp/src.cpp.o' +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32" +target triple = "i386-pc-linux-gnu" + +@.str = private unnamed_addr constant [15 x i8] c"hello, %d %d!\0A\00", align 1 ; [#uses=1 type=[15 x i8]*] +@_dispatchTable = internal global i64 0 + +define i32 @doit(i32 %x, { i32, i32 } %y) { + %y0 = extractvalue { i32, i32 } %y, 0 + %y1 = extractvalue { i32, i32 } %y, 1 + %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([15 x i8]* @.str, i32 0, i32 0), i32 %y0, i32 %y1) ; [#uses=0 type=i32] [debug line = 5:13] + ret i32 0 +} + +define i32 @main() { +entry: + %retval = alloca i32, align 4 ; [#uses=1 type=i32*] + %myi64 = alloca i64, align 4 + %comp = alloca { i32, i32 }, align 4 ; [#uses=1] + store i32 0, i32* %retval + br label %cond.end + +cond.null: + br label %cond.end + +cond.end: ; preds = %cond.false, %cond.true + %cond = phi { i32, i32 } [ { i32 5, i32 6 }, %entry ], [ zeroinitializer, %cond.null ] ; [#uses=1] + store { i32, i32 } %cond, { i32, i32 }* %comp + %call = call i32 (i32, { i32, i32 })* @doit(i32 1, { i32, i32 } %cond) ; + store { i32, i32 } { i32 ptrtoint (i64* @_dispatchTable to i32), i32 0 }, { i32, i32 }* getelementptr inbounds ([1 x i64]* @_dispatchTable, i32 0, i32 0, i32 1), align 4 + ret i32 0 ; [debug line = 6:13] +} + +; [#uses=1] +declare i32 @printf(i8*, ...) + diff --git a/tests/cases/structparam.txt b/tests/cases/structparam.txt new file mode 100644 index 00000000..b2a63262 --- /dev/null +++ b/tests/cases/structparam.txt @@ -0,0 +1 @@ +hello, 5 6! diff --git a/tests/cases/typestr.ll b/tests/cases/typestr.ll new file mode 100644 index 00000000..49074637 --- /dev/null +++ b/tests/cases/typestr.ll @@ -0,0 +1,19 @@ +; ModuleID = 'tests/hello_world.bc' +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32-S128" +target triple = "i386-pc-linux-gnu" + +@.str = private unnamed_addr constant [15 x i8] c"hello, world!\0A\00", align 1 ; [#uses=1 type=[15 x i8]*] +@.str1227 = private unnamed_addr constant [9 x i8] c" = type \00", align 1 + +; [#uses=0] +define i32 @main() { +entry: + %retval = alloca i32, align 4 ; [#uses=1 type=i32*] + store i32 0, i32* %retval + %call0 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([9 x i8]* @.str1227, i32 0, i32 0)) ; [#uses=0 type=i32] + %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([15 x i8]* @.str, i32 0, i32 0)) ; [#uses=0 type=i32] + ret i32 1 +} + +; [#uses=1] +declare i32 @printf(i8*, ...) diff --git a/tests/cases/uadd_overflow.ll b/tests/cases/uadd_overflow.ll deleted file mode 100644 index a808b9de..00000000 --- a/tests/cases/uadd_overflow.ll +++ /dev/null @@ -1,25 +0,0 @@ -; ModuleID = 'tests/hello_world.bc' -target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32-S128" -target triple = "i386-pc-linux-gnu" - -@.str2 = private constant [9 x i8] c"*%d,%d*\0A\00", align 1 ; [#uses=1] - -; [#uses=0] -define i32 @main() { -entry: - %retval = alloca i32, align 4 ; [#uses=1 type=i32*] - %mul7 = bitcast i32 -259741926 to i32 - %shl10 = shl i32 4014, 16 - %uadd1 = tail call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %mul7, i32 %shl10) - %a0 = extractvalue { i32, i1 } %uadd1, 0 - %a1 = extractvalue { i32, i1 } %uadd1, 1 - %a2 = zext i1 %a1 to i32 - call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([9 x i8]* @.str2, i32 0, i32 0), i32 %a0, i32 %a2) ; [#uses=0] - ret i32 1 -} - -; [#uses=1] -declare i32 @printf(i8*, ...) - -declare { i32, i1 } @llvm.uadd.with.overflow.i32(i32, i32) nounwind readnone - diff --git a/tests/cases/uadd_overflow.txt b/tests/cases/uadd_overflow.txt deleted file mode 100644 index dcda9240..00000000 --- a/tests/cases/uadd_overflow.txt +++ /dev/null @@ -1 +0,0 @@ -*3319578,1* diff --git a/tests/cases/uadd_overflow_ta2.ll b/tests/cases/uadd_overflow_ta2.ll new file mode 100644 index 00000000..81a76bcd --- /dev/null +++ b/tests/cases/uadd_overflow_ta2.ll @@ -0,0 +1,44 @@ +; ModuleID = 'tests/hello_world.bc' +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32-S128" +target triple = "i386-pc-linux-gnu" + +@.str2 = private constant [9 x i8] c"*%d,%d*\0A\00", align 1 ; [#uses=1] + +; [#uses=0] +define i32 @main() { +entry: + %retval = alloca i32, align 4 ; [#uses=1 type=i32*] + %mul7 = bitcast i32 -259741926 to i32 + %shl10 = shl i32 4014, 16 + %uadd1 = tail call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %mul7, i32 %shl10) + %a0 = extractvalue { i32, i1 } %uadd1, 0 + %a1 = extractvalue { i32, i1 } %uadd1, 1 + %a2 = zext i1 %a1 to i32 + call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([9 x i8]* @.str2, i32 0, i32 0), i32 %a0, i32 %a2) ; [#uses=0] + + %buadd1prepre = tail call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %mul7, i32 %shl10) + %buadd1pre = insertvalue { i32, i1 } %buadd1prepre, i1 0, 1 + %buadd1 = insertvalue { i32, i1 } %buadd1pre, i32 5177, 0 + %ba0 = extractvalue { i32, i1 } %buadd1, 0 + %ba1 = extractvalue { i32, i1 } %buadd1, 1 + %ba2 = zext i1 %ba1 to i32 + call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([9 x i8]* @.str2, i32 0, i32 0), i32 %ba0, i32 %ba2) ; [#uses=0] + + %64buadd1pre = tail call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 5000, i64 3000) + %64buadd1 = insertvalue { i64, i1 } %64buadd1pre, i64 9875, 0 + %64buadd2 = insertvalue { i64, i1 } %64buadd1, i1 1, 1 + %64ba0pre = extractvalue { i64, i1 } %64buadd2, 0 + %64ba0 = trunc i64 %64ba0pre to i32 + %64ba1 = extractvalue { i64, i1 } %64buadd2, 1 + %64ba2 = zext i1 %64ba1 to i32 + call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([9 x i8]* @.str2, i32 0, i32 0), i32 %64ba0, i32 %64ba2) ; [#uses=0] + + ret i32 1 +} + +; [#uses=1] +declare i32 @printf(i8*, ...) + +declare { i32, i1 } @llvm.uadd.with.overflow.i32(i32, i32) nounwind readnone +declare { i64, i1 } @llvm.uadd.with.overflow.i64(i64, i32) nounwind readnone + diff --git a/tests/cases/uadd_overflow_ta2.txt b/tests/cases/uadd_overflow_ta2.txt new file mode 100644 index 00000000..bcd04599 --- /dev/null +++ b/tests/cases/uadd_overflow_ta2.txt @@ -0,0 +1,3 @@ +*3319578,1* +*5177,0* +*9875,1* diff --git a/tests/emscripten_fs_api_browser.cpp b/tests/emscripten_fs_api_browser.cpp index 9936a09c..0355287a 100644 --- a/tests/emscripten_fs_api_browser.cpp +++ b/tests/emscripten_fs_api_browser.cpp @@ -13,6 +13,7 @@ int data_ok = 0; int data_bad = 0; void onLoadedData(void *arg, void *buffer, int size) { + printf("onLoadedData %d\n", (int)arg); get_count++; assert(size == 329895); assert((int)arg == 135); @@ -25,29 +26,41 @@ void onLoadedData(void *arg, void *buffer, int size) { } void onErrorData(void *arg) { + printf("onErrorData %d\n", (int)arg); get_count++; assert((int)arg == 246); data_bad = 1; } +int counter = 0; void wait_wgets() { + if (counter++ == 60) { + printf("%d\n", get_count); + counter = 0; + } + if (get_count == 3) { - emscripten_async_wget_data( - "http://localhost:8888/screenshot.png", - (void*)135, - onLoadedData, - onErrorData); - emscripten_async_wget_data( - "http://localhost:8888/fail_me", - (void*)246, - onLoadedData, - onErrorData); + static bool fired = false; + if (!fired) { + fired = true; + emscripten_async_wget_data( + "http://localhost:8888/screenshot.png", + (void*)135, + onLoadedData, + onErrorData); + emscripten_async_wget_data( + "http://localhost:8888/fail_me", + (void*)246, + onLoadedData, + onErrorData); + } } else if (get_count == 5) { assert(IMG_Load("/tmp/screen_shot.png")); assert(data_ok == 1 && data_bad == 1); emscripten_cancel_main_loop(); REPORT_RESULT(); } + assert(get_count <= 5); } void onLoaded(const char* file) { @@ -55,8 +68,6 @@ void onLoaded(const char* file) { result = 0; } - printf("loaded: %s\n", file); - if (FILE * f = fopen(file, "r")) { printf("exists: %s\n", file); int c = fgetc (f); @@ -71,6 +82,7 @@ void onLoaded(const char* file) { } get_count++; + printf("onLoaded %s\n", file); } void onError(const char* file) { @@ -78,8 +90,8 @@ void onError(const char* file) { result = 0; } - printf("error: %s\n", file); get_count++; + printf("onError %s\n", file); } int main() { diff --git a/tests/enet_client.c b/tests/enet_client.c index 78c8f314..601b8769 100644 --- a/tests/enet_client.c +++ b/tests/enet_client.c @@ -10,7 +10,7 @@ void main_loop() { #if EMSCRIPTEN counter++; #endif - if (counter == 10) { + if (counter == 100) { printf("stop!\n"); emscripten_cancel_main_loop(); return; diff --git a/tests/enet_server.c b/tests/enet_server.c index 87c64038..a8167e16 100644 --- a/tests/enet_server.c +++ b/tests/enet_server.c @@ -29,7 +29,7 @@ void main_loop() { #if EMSCRIPTEN counter++; #endif - if (counter == 10) { + if (counter == 100) { printf("stop!\n"); emscripten_cancel_main_loop(); return; diff --git a/tests/files.cpp b/tests/files.cpp index e1a38421..04baa151 100644 --- a/tests/files.cpp +++ b/tests/files.cpp @@ -1,6 +1,7 @@ #include <assert.h> #include <stdio.h> #include <stdlib.h> +#include <string.h> int main() { @@ -103,6 +104,23 @@ int main() fclose(inf); printf("fscanfed: %d - %s\n", number, text); + // temp files + const char *tname = "file_XXXXXX.txt"; + char tname1[100]; + char tname2[100]; + strcpy(tname1, tname); + strcpy(tname2, tname); + assert(!strcmp(tname1, tname2)); // equal + int f1 = mkstemp(tname1); + int f2 = mkstemp(tname2); + assert(f1 != f2); + //printf("%d,%d,%s,%s\n", f1, f2, tname1, tname2); + assert(strcmp(tname1, tname2)); // not equal + assert(fopen(tname1, "r")); + assert(fopen(tname2, "r")); + assert(!fopen(tname2+1, "r")); // sanity check that we can't open just anything + printf("ok.\n"); + return 0; } diff --git a/tests/http.cpp b/tests/http.cpp new file mode 100644 index 00000000..07931e3c --- /dev/null +++ b/tests/http.cpp @@ -0,0 +1,286 @@ +// +// http.cpp +// Player Javascript +// +// Created by Anthony Liot on 23/11/12. +// + +#include "http.h" +#include <emscripten/emscripten.h> +#include <stdio.h> +#include <stdlib.h> + +int http::uid = 0; + +/* +- Useful for download an url on other domain +<?php +header("Access-Control-Allow-Origin: *"); +// verifie si on a les bons parametres +if( isset($_GET['url']) ) { + + $fileName = $_GET['url']; + if($f = fopen($fileName,'rb') ){ + $fSize = 0; + while(!feof($f)){ + ++$fSize; + $data = fread($f,1); + } + fclose($f); + if( $fSize < 1 ) { + header($_SERVER['SERVER_PROTOCOL'] . ' 404 Not Found'); + echo 'For empty file ' . $fileName; + die(); + } else { + header("POST ".$fileName." HTTP/1.1\r\n"); + header('Content-Description: File Transfer'); + header('Content-Transfer-Encoding: binary'); + header('Content-Disposition: attachment; filename="' . basename($fileName) . "\";"); + header('Content-Type: application/octet-stream'); + header('Content-Length: '.$fSize); + + header('Expires: 0'); + header('Cache-Control: must-revalidate'); + header('Pragma: public'); + ob_clean(); + flush(); + readfile($fileName); + exit; + } + } else { + header($_SERVER['SERVER_PROTOCOL'] . ' 404 Not Found'); + echo 'For filename ' . $fileName; + } +} else { + header($_SERVER['SERVER_PROTOCOL'] . ' 403 Forbidden'); +} +?> +*/ +// http://..../download.php?url= +std::string http::cross_domain = ""; + + +//---------------------------------------------------------------------------------------- +// HTTP CLASS +//---------------------------------------------------------------------------------------- + +void http::onLoaded(void* parent, const char * file) { + http* req = reinterpret_cast<http*>(parent); + req->onLoaded(file); +} + +void http::onError(void* parent, int statuserror) { + http* req = reinterpret_cast<http*>(parent); + req->onError(statuserror); +} + +void http::onProgress(void* parent, int progress) { + http* req = reinterpret_cast<http*>(parent); + req->onProgress(progress); +} + +/** +* Constructeur +*/ +http::http(const char* hostname, int requestType, const char* targetFilename) : _hostname(hostname), _page(""), _targetFileName(targetFilename), _param(""), _content(""), _error(""), _request((RequestType)requestType), _status(ST_PENDING), _assync(ASSYNC_THREAD) { + _progressValue = -1; + _uid = uid++; +} + + +/** +* Destructeur +*/ +http::~http() { +} + +/** +* Effectue la requete +*/ +void http::runRequest(const char* page, int assync) { + _page = page; + _status = ST_PENDING; + _assync = (AssyncMode)assync; + _progressValue = 0; + + std::string url = cross_domain; + url += _hostname + _page; + + if (_hostname.size() > 0 && _page.size() > 0) { + + printf("URL : %s\n",url.c_str()); + printf("REQUEST : %s\n",(_request==REQUEST_GET) ? "GET":"POST"); + printf("PARAMS : %s\n",_param.c_str()); + + if (_targetFileName.size() == 0 ) { + _targetFileName = format("prepare%d",_uid); + } + + emscripten_async_wget2(url.c_str(), _targetFileName.c_str(), (_request==REQUEST_GET) ? "GET":"POST", _param.c_str(), this, http::onLoaded, http::onError, http::onProgress); + + } else { + _error = format("malformed url : %s\n",url.c_str()); + _content = ""; + _status = ST_FAILED; + _progressValue = -1; + } +} + +/** +* Accede a la reponse +*/ +const char* http::getContent() { + return _content.c_str(); +} + +/** +* Accede a l'erreur +*/ +const char* http::getError() { + return _error.c_str(); +} + +/** +* Accede au status +*/ +int http::getStatus() { + return _status; +} + +/** +* Accede a la progression between 0 & 100 +*/ +float http::getProgress() { + return (float)_progressValue; +} + +/** +* Accede a la progression between 0 & 100 +*/ +int http::getId() { + return _uid; +} + +/** +* Post +*/ +void http::addValue(const char* key, const char* value) { + if (_param.size() > 0) { + _param += "&"; + _param += key; + _param += "="; + _param += value; + } else { + _param += key; + _param += "="; + _param += value; + } +} + +void http::onProgress(int progress) { + _progressValue = progress; +} + +void http::onLoaded(const char* file) { + + if (strstr(file,"prepare")) { + FILE* f = fopen(file,"rb"); + if (f) { + fseek (f, 0, SEEK_END); + int size=ftell (f); + fseek (f, 0, SEEK_SET); + + char* data = new char[size]; + fread(data,size,1,f); + _content = data; + delete data; + fclose(f); + } else { + _content = file; + } + + } else { + _content = file; + } + + _progressValue = 100; + _status = ST_OK; +} + +void http::onError(int error) { + + printf("Error status : %d\n",error); + + _error = ""; + _content = ""; + _status = ST_FAILED; + _progressValue = -1; +} + +/// TEST +int num_request = 0; +float time_elapsed = 0.0f; + +void wait_https() { + if (num_request == 0) { + printf("End of all download ... %fs\n",(emscripten_get_now() - time_elapsed) / 1000.f); + emscripten_cancel_main_loop(); + int result = 0; + REPORT_RESULT(); + } +} + +void wait_http(void* request) { + http* req = reinterpret_cast<http*>(request); + if (req != 0) { + if (req->getStatus() == http::ST_PENDING) { + if ((int)req->getProgress()>0) { + printf("Progress Request n°%d : %d\n",req->getId(),(int)req->getProgress()); + } + emscripten_async_call(wait_http,request,500); + + } else { + if (req->getStatus() == http::ST_OK) { + printf("Success Request n°%d : %s\n",req->getId(),req->getContent()); + + } else { + printf("Error Request n°%d : %s\n",req->getId(), req->getError()); + } + + num_request --; + } + } else { + num_request --; + } +} + + +int main() { + time_elapsed = emscripten_get_now(); + + http* http1 = new http("https://github.com",http::REQUEST_GET,"emscripten_master.zip"); + http1->runRequest("/kripken/emscripten/archive/master.zip",http::ASSYNC_THREAD); + + http* http2 = new http("https://github.com",http::REQUEST_GET,"wolfviking_master.zip"); + http2->runRequest("/wolfviking0/image.js/archive/master.zip",http::ASSYNC_THREAD); + + http* http3 = new http("https://raw.github.com",http::REQUEST_GET); + http3->runRequest("/kripken/emscripten/master/LICENSE",http::ASSYNC_THREAD); + + num_request ++; + emscripten_async_call(wait_http,http1,500); + num_request ++; + emscripten_async_call(wait_http,http2,500); + num_request ++; + emscripten_async_call(wait_http,http3,500); + + /* + Http* http4 = new Http("http://www.---.com",Http::REQUEST_POST); + http4->addValue("app","123"); + http4->runRequest("/test.php",Http::ASSYNC_THREAD); + num_request ++; + emscripten_async_call(wait_http,http4,500); + */ + + emscripten_set_main_loop(wait_https, 0, 0); +} diff --git a/tests/http.h b/tests/http.h new file mode 100644 index 00000000..7eff7013 --- /dev/null +++ b/tests/http.h @@ -0,0 +1,151 @@ +// +// Http.h +// Player Javascript +// +// Created by Anthony Liot on 23/11/12. +// + +#ifndef __HTTP_H__ +#define __HTTP_H__ + +#include <string> + + +/* + */ +class http { + + public: + + enum Status { + ST_PENDING = 0, + ST_FAILED, + ST_OK + }; + + enum RequestType { + REQUEST_GET = 0, + REQUEST_POST , + }; + + enum AssyncMode { + ASSYNC_THREAD + }; + + // enregistrement sur unigine + static void RegisterAsExtension(bool regis); + + // Callback + static void onLoaded(void* parent, const char * file); + static void onError(void* parent, int statuserror); + static void onProgress(void* parent, int progress); + + // Constructeur + http(const char* hostname, int requestType, const char* targetFileName = ""); + + //Destructeur + virtual ~http(); + + /** + * Effectue la requete + */ + void runRequest(const char* page, int assync); + + /** + * Accede a la reponse + */ + const char* getContent(); + + /** + * Accede a l'erreur + */ + const char* getError(); + + /** + * Accede au status + */ + int getStatus(); + + /** + * Accede a la progression + */ + float getProgress(); + + /** + * Get Id of http Class + */ + int getId(); + + /** + * + */ + void addValue(const char* key, const char* value); + + /** + * Callback + */ + void onProgress(int progress); + void onLoaded(const char* file); + void onError(int error); + + // Static parameter + static int uid; + static std::string cross_domain ; + + private: + + // Id of request + int _uid; + + // nom de l'hote + std::string _hostname; + + // nom de la page + std::string _page; + + // target filename + std::string _targetFileName; + + // param + std::string _param; + + // resultat + std::string _content; + + // probleme + std::string _error; + + // request type + RequestType _request; + + // status + int _status; + + // progress value + int _progressValue; + + // mode assyncrone courant + AssyncMode _assync; + +}; + +//this is safe and convenient but not exactly efficient +inline std::string format(const char* fmt, ...){ + int size = 512; + char* buffer = 0; + buffer = new char[size]; + va_list vl; + va_start(vl,fmt); + int nsize = vsnprintf(buffer,size,fmt,vl); + if(size<=nsize){//fail delete buffer and try again + delete buffer; buffer = 0; + buffer = new char[nsize+1];//+1 for /0 + nsize = vsnprintf(buffer,size,fmt,vl); + } + std::string ret(buffer); + va_end(vl); + delete buffer; + return ret; +} + +#endif /* __HTTP_H__ */ diff --git a/tests/lua/lua.ll b/tests/lua/lua.ll index 81c7bc27..cffaa3a2 100644 --- a/tests/lua/lua.ll +++ b/tests/lua/lua.ll @@ -13914,7 +13914,7 @@ define hidden void @_Z10luaD_throwP9lua_Statei(%struct.lua_State* %L, i32 %errco %10 = getelementptr inbounds %struct.lua_State* %9, i32 0, i32 25, !dbg !9995 ; [#uses=1] %11 = load %struct.lua_longjmp** %10, align 4, !dbg !9995 ; [#uses=1] %12 = getelementptr inbounds %struct.lua_longjmp* %11, i32 0, i32 2, !dbg !9995 ; [#uses=1] - volatile store i32 %8, i32* %12, align 4, !dbg !9995 + store i32 %8, i32* %12, align 4, !dbg !9995 %13 = call i8* @__cxa_allocate_exception(i32 4) nounwind, !dbg !9997 ; [#uses=2] %14 = bitcast i8* %13 to %struct.lua_longjmp**, !dbg !9997 ; [#uses=1] %15 = load %struct.lua_State** %1, align 4, !dbg !9997 ; [#uses=1] @@ -14032,7 +14032,7 @@ define hidden i32 @_Z20luaD_rawrunprotectedP9lua_StatePFvS0_PvES1_(%struct.lua_S call void @llvm.dbg.declare(metadata !743, metadata !10030), !dbg !10031 call void @llvm.dbg.declare(metadata !743, metadata !10032), !dbg !10034 %5 = getelementptr inbounds %struct.lua_longjmp* %lj, i32 0, i32 2, !dbg !10035 ; [#uses=1] - volatile store i32 0, i32* %5, align 4, !dbg !10035 + store i32 0, i32* %5, align 4, !dbg !10035 %6 = load %struct.lua_State** %1, align 4, !dbg !10036 ; [#uses=1] %7 = getelementptr inbounds %struct.lua_State* %6, i32 0, i32 25, !dbg !10036 ; [#uses=1] %8 = load %struct.lua_longjmp** %7, align 4, !dbg !10036 ; [#uses=1] @@ -14044,8 +14044,9 @@ define hidden i32 @_Z20luaD_rawrunprotectedP9lua_StatePFvS0_PvES1_(%struct.lua_S %12 = load void (%struct.lua_State*, i8*)** %2, align 4, !dbg !10038 ; [#uses=1] %13 = load %struct.lua_State** %1, align 4, !dbg !10038 ; [#uses=1] %14 = load i8** %3, align 4, !dbg !10038 ; [#uses=1] - invoke void %12(%struct.lua_State* %13, i8* %14) - to label %15 unwind label %24, !dbg !10038 + call void %12(%struct.lua_State* %13, i8* %14) + ; to label %15 unwind label %24, !dbg !10038 + %15 = load i8** %3 ; <label>:15 ; preds = %0 br label %28, !dbg !10038 @@ -14054,13 +14055,13 @@ define hidden i32 @_Z20luaD_rawrunprotectedP9lua_StatePFvS0_PvES1_(%struct.lua_S %17 = load i8** %4, !dbg !10038 ; [#uses=1] %18 = call i8* @__cxa_begin_catch(i8* %17) nounwind, !dbg !10038 ; [#uses=0] %19 = getelementptr inbounds %struct.lua_longjmp* %lj, i32 0, i32 2, !dbg !10038 ; [#uses=1] - %20 = volatile load i32* %19, align 4, !dbg !10038 ; [#uses=1] + %20 = load i32* %19, align 4, !dbg !10038 ; [#uses=1] %21 = icmp eq i32 %20, 0, !dbg !10038 ; [#uses=1] br i1 %21, label %22, label %27, !dbg !10038 ; <label>:22 ; preds = %16 %23 = getelementptr inbounds %struct.lua_longjmp* %lj, i32 0, i32 2, !dbg !10038 ; [#uses=1] - volatile store i32 -1, i32* %23, align 4, !dbg !10038 + store i32 -1, i32* %23, align 4, !dbg !10038 br label %27, !dbg !10038 ; <label>:24 ; preds = %0 @@ -14080,7 +14081,7 @@ define hidden i32 @_Z20luaD_rawrunprotectedP9lua_StatePFvS0_PvES1_(%struct.lua_S %32 = getelementptr inbounds %struct.lua_State* %31, i32 0, i32 25, !dbg !10039 ; [#uses=1] store %struct.lua_longjmp* %30, %struct.lua_longjmp** %32, align 4, !dbg !10039 %33 = getelementptr inbounds %struct.lua_longjmp* %lj, i32 0, i32 2, !dbg !10040 ; [#uses=1] - %34 = volatile load i32* %33, align 4, !dbg !10040 ; [#uses=1] + %34 = load i32* %33, align 4, !dbg !10040 ; [#uses=1] ret i32 %34, !dbg !10040 } diff --git a/tests/runner.py b/tests/runner.py index b1852ff2..d3471f62 100755 --- a/tests/runner.py +++ b/tests/runner.py @@ -263,7 +263,7 @@ process(sys.argv[1]) if output_processor is not None: output_processor(open(filename + '.o.js').read()) - def run_generated_code(self, engine, filename, args=[], check_timeout=True): + def run_generated_code(self, engine, filename, args=[], check_timeout=True, output_nicerizer=None): stdout = os.path.join(self.get_dir(), 'stdout') # use files, as PIPE can get too full and hang us stderr = os.path.join(self.get_dir(), 'stderr') try: @@ -274,7 +274,12 @@ process(sys.argv[1]) run_js(filename, engine, args, check_timeout, stdout=open(stdout, 'w'), stderr=open(stderr, 'w')) if cwd is not None: os.chdir(cwd) - ret = open(stdout, 'r').read() + open(stderr, 'r').read() + out = open(stdout, 'r').read() + err = open(stderr, 'r').read() + if output_nicerizer: + ret = output_nicerizer(out, err) + else: + ret = out + err assert 'strict warning:' not in ret, 'We should pass all strict mode checks: ' + ret return ret @@ -428,7 +433,7 @@ if 'benchmark' not in str(sys.argv) and 'sanity' not in str(sys.argv) and 'brows if len(sys.argv) == 2 and 'ALL.' in sys.argv[1]: ignore, test = sys.argv[1].split('.') print 'Running all test modes on test "%s"' % test - sys.argv = [sys.argv[0], 'default.'+test, 'o1.'+test, 'o2.'+test, 's_0_0.'+test, 's_0_1.'+test, 's_0_1_q1.'+test, 's_1_0.'+test, 's_1_1.'+test, 's_1_1_q1.'+test] + sys.argv = [sys.argv[0], 'default.'+test, 'o1.'+test, 'o2.'+test, 'asm2.'+test, 's_0_0.'+test, 's_0_1.'+test, 's_0_1_q1.'+test, 's_1_0.'+test, 's_1_1.'+test, 's_1_1_q1.'+test] class T(RunnerCore): # Short name, to make it more fun to use manually on the commandline ## Does a complete test - builds, runs, checks output, etc. @@ -451,9 +456,7 @@ if 'benchmark' not in str(sys.argv) and 'sanity' not in str(sys.argv) and 'brows js_engines = filter(lambda engine: engine not in self.banned_js_engines, js_engines) if len(js_engines) == 0: return self.skip('No JS engine present to run this test with. Check %s and the paths therein.' % EM_CONFIG) for engine in js_engines: - js_output = self.run_generated_code(engine, filename + '.o.js', args) - if output_nicerizer is not None: - js_output = output_nicerizer(js_output) + js_output = self.run_generated_code(engine, filename + '.o.js', args, output_nicerizer=output_nicerizer) self.assertContained(expected_output, js_output.replace('\r\n', '\n')) self.assertNotContained('ERROR', js_output) @@ -836,6 +839,7 @@ if 'benchmark' not in str(sys.argv) and 'sanity' not in str(sys.argv) and 'brows def test_i64_cmp2(self): if Settings.USE_TYPED_ARRAYS != 2: return self.skip('full i64 stuff only in ta2') + src = r''' #include <inttypes.h> #include <stdio.h> @@ -881,6 +885,8 @@ m_divisor is 1091269979 def test_i64_double(self): if Settings.USE_TYPED_ARRAYS != 2: return self.skip('full i64 stuff only in ta2') + + src = r''' #include <stdio.h> @@ -923,6 +929,7 @@ m_divisor is 1091269979 def test_i64_umul(self): if Settings.USE_TYPED_ARRAYS != 2: return self.skip('full i64 stuff only in ta2') + src = r''' #include <inttypes.h> #include <stdio.h> @@ -1272,6 +1279,7 @@ Succeeded! self.do_run(open(path_from_root('tests', 'cube2md5.cpp')).read(), open(path_from_root('tests', 'cube2md5.ok')).read()) def test_cube2hash(self): + try: old_chunk_size = os.environ.get('EMSCRIPT_MAX_CHUNK_SIZE') or '' os.environ['EMSCRIPT_MAX_CHUNK_SIZE'] = '1' # test splitting out each function to a chunk in emscripten.py (21 functions here) @@ -1401,7 +1409,7 @@ Succeeded! # corrections otherwise if Settings.USE_TYPED_ARRAYS == 2: Settings.CORRECT_SIGNS = 0 - Settings.CHECK_SIGNS = 1 + Settings.CHECK_SIGNS = 1 if not Settings.ASM_JS else 0 else: Settings.CORRECT_SIGNS = 1 Settings.CHECK_SIGNS = 0 @@ -1758,15 +1766,14 @@ Succeeded! return 0; } ''' - for named, expected in [(0, range(100, 200)), (1, [0])]: + for named in (0, 1): print named Settings.NAMED_GLOBALS = named self.do_run(src, '4:10,177,543,def\n4\nwowie\ntoo\n76\n5\n(null)\n/* a comment */\n// another\ntest\n', ['wowie', 'too', '74']) if self.emcc_args == []: gen = open(self.in_dir('src.cpp.o.js')).read() - count = gen.count('GLOBAL_BASE') - assert count in expected, count - print ' counted' + assert ('var __str1;' in gen) == named + assert (gen.count('ALLOC_NONE') < 8) == named def test_strcmp_uni(self): src = ''' @@ -1934,6 +1941,7 @@ Succeeded! self.do_run(self.gen_struct_src.replace('{{gen_struct}}', '(S*)malloc(sizeof(S))').replace('{{del_struct}}', 'free'), '*51,62*') def test_newstruct(self): + if self.emcc_args is None: return self.skip('requires emcc') self.do_run(self.gen_struct_src.replace('{{gen_struct}}', 'new S').replace('{{del_struct}}', 'delete'), '*51,62*') def test_addr_of_stacked(self): @@ -2077,6 +2085,8 @@ Succeeded! self.do_run(src, 'Assertion failed: 1 == false') def test_longjmp(self): + if Settings.ASM_JS: return self.skip('asm does not support longjmp') + src = r''' #include <stdio.h> #include <setjmp.h> @@ -2112,6 +2122,8 @@ Succeeded! self.do_run(src, 'second\nmain: 0\n') def test_longjmp2(self): + if Settings.ASM_JS: return self.skip('asm does not support longjmp') + src = r''' #include <setjmp.h> #include <stdio.h> @@ -2158,6 +2170,8 @@ Exiting stack_manipulate_func, level: 0 ''') def test_longjmp3(self): + if Settings.ASM_JS: return self.skip('asm does not support longjmp') + src = r''' #include <setjmp.h> #include <stdio.h> @@ -2210,6 +2224,8 @@ Exiting setjmp function, level: 0 ''') def test_longjmp4(self): + if Settings.ASM_JS: return self.skip('asm does not support longjmp') + src = r''' #include <setjmp.h> #include <stdio.h> @@ -2263,6 +2279,8 @@ Exception execution path of first function! 1 def test_exceptions(self): if Settings.QUANTUM_SIZE == 1: return self.skip("we don't support libcxx in q1") + Settings.EXCEPTION_DEBUG = 1 + self.banned_js_engines = [NODE_JS] # node issue 1669, exception causes stdout not to be flushed Settings.DISABLE_EXCEPTION_CATCHING = 0 if self.emcc_args is None: @@ -2354,7 +2372,6 @@ Exception execution path of first function! 1 if '-O2' in self.emcc_args: self.emcc_args += ['--closure', '1'] # Use closure here for some additional coverage - Settings.EXCEPTION_DEBUG = 0 # Messes up expected output. Settings.DISABLE_EXCEPTION_CATCHING = 0 src = r''' @@ -2394,14 +2411,12 @@ Exception execution path of first function! 1 def test_typed_exceptions(self): Settings.DISABLE_EXCEPTION_CATCHING = 0 Settings.SAFE_HEAP = 0 # Throwing null will cause an ignorable null pointer access. - Settings.EXCEPTION_DEBUG = 0 # Messes up expected output. src = open(path_from_root('tests', 'exceptions', 'typed.cpp'), 'r').read() expected = open(path_from_root('tests', 'exceptions', 'output.txt'), 'r').read() self.do_run(src, expected) def test_multiexception(self): Settings.DISABLE_EXCEPTION_CATCHING = 0 - Settings.EXCEPTION_DEBUG = 0 # Messes up expected output. src = r''' #include <stdio.h> @@ -2462,6 +2477,53 @@ setjmp exception execution path, level: 0, prev_jmp: -1 Exiting setjmp function, level: 0, prev_jmp: -1 ''') + def test_exit_stack(self): + if self.emcc_args is None: return self.skip('requires emcc') + if Settings.ASM_JS: return self.skip('uses report_stack without exporting') + + Settings.CATCH_EXIT_CODE = 1 + + src = r''' + #include <stdio.h> + #include <stdlib.h> + + extern "C" { + extern void report_stack(int x); + } + + char moar() { + char temp[125]; + for (int i = 0; i < 125; i++) temp[i] = i*i; + for (int i = 1; i < 125; i++) temp[i] += temp[i-1]/2; + if (temp[100] != 99) exit(1); + return temp[120]; + } + + int main(int argc, char *argv[]) { + report_stack((int)alloca(4)); + printf("*%d*\n", moar()); + return 0; + } + ''' + + open(os.path.join(self.get_dir(), 'pre.js'), 'w').write(''' + var initialStack = -1; + var _report_stack = function(x) { + Module.print('reported'); + initialStack = x; + } + var Module = { + postRun: function() { + Module.print('postRun'); + assert(initialStack == STACKTOP, [initialStack, STACKTOP]); + Module.print('ok.'); + } + }; + ''') + + self.emcc_args += ['--pre-js', 'pre.js'] + self.do_run(src, '''reported\npostRun\nok.\nExit Status: 1\n''') + def test_class(self): src = ''' #include <stdio.h> @@ -2532,6 +2594,7 @@ Exiting setjmp function, level: 0, prev_jmp: -1 self.do_run(src, '3.14159') def test_polymorph(self): + if self.emcc_args is None: return self.skip('requires emcc') src = ''' #include <stdio.h> struct Pure { @@ -2570,6 +2633,7 @@ Exiting setjmp function, level: 0, prev_jmp: -1 def test_segfault(self): if self.emcc_args is None: return self.skip('SAFE_HEAP without ta2 means we check types too, which hide segfaults') + if Settings.ASM_JS: return self.skip('asm does not support safe heap') Settings.SAFE_HEAP = 1 @@ -2707,6 +2771,7 @@ Exiting setjmp function, level: 0, prev_jmp: -1 self.do_run(src, 'fn2(-5) = 5, fn(10) = 3.16') def test_emptyclass(self): + if self.emcc_args is None: return self.skip('requires emcc') src = ''' #include <stdio.h> @@ -3042,6 +3107,7 @@ Exiting setjmp function, level: 0, prev_jmp: -1 self.do_run(src, '*0,0,0,4,8,12,16,20*\n*1,0,0*\n*0*\n0:1,1\n1:1,1\n2:1,1\n*12,20,20*') def test_ptrtoint(self): + if self.emcc_args is None: return self.skip('requires emcc') src = ''' #include <stdio.h> @@ -3064,6 +3130,7 @@ Exiting setjmp function, level: 0, prev_jmp: -1 self.do_run(src, '*5*', output_processor=check_warnings) def test_sizeof(self): + if self.emcc_args is None: return self.skip('requires emcc') # Has invalid writes between printouts Settings.SAFE_HEAP = 0 @@ -3096,7 +3163,7 @@ Exiting setjmp function, level: 0, prev_jmp: -1 return 0; } ''' - self.do_run(src, '*2,2,5,8,8***8,8,5,8,8***7,2,6,990,7,2*', [], lambda x: x.replace('\n', '*')) + self.do_run(src, '*2,2,5,8,8***8,8,5,8,8***7,2,6,990,7,2*', [], lambda x, err: x.replace('\n', '*')) def test_emscripten_api(self): #if Settings.MICRO_OPTS or Settings.RELOOP or Building.LLVM_OPTS: return self.skip('FIXME') @@ -3106,7 +3173,7 @@ Exiting setjmp function, level: 0, prev_jmp: -1 #include "emscripten.h" extern "C" { - void EMSCRIPTEN_KEEPALIVE save_me_aimee() { printf("mann\n"); } + void save_me_aimee() { printf("mann\n"); } } int main() { @@ -3114,7 +3181,7 @@ Exiting setjmp function, level: 0, prev_jmp: -1 emscripten_run_script("Module.print('hello world' + '!')"); printf("*%d*\n", emscripten_run_script_int("5*20")); printf("*%s*\n", emscripten_run_script_string("'five'+'six'")); - emscripten_run_script("_save_me_aimee()"); + emscripten_run_script("Module['_save_me_aimee']()"); return 0; } ''' @@ -3124,7 +3191,7 @@ def process(filename): src = open(filename, 'r').read() # TODO: restore this (see comment in emscripten.h) assert '// hello from the source' in src ''' - + Settings.EXPORTED_FUNCTIONS = ['_main', '_save_me_aimee'] self.do_run(src, 'hello world!\n*100*\n*fivesix*\nmann\n', post_build=check) def test_inlinejs(self): @@ -3148,6 +3215,7 @@ def process(filename): def test_memorygrowth(self): if Settings.USE_TYPED_ARRAYS == 0: return self.skip('memory growth is only supported with typed arrays') + if Settings.ASM_JS: return self.skip('asm does not support memory growth yet') # With typed arrays in particular, it is dangerous to use more memory than TOTAL_MEMORY, # since we then need to enlarge the heap(s). @@ -3234,6 +3302,7 @@ def process(filename): self.do_run(src, '''*16*\n0:22016,0,32,48\n1:22018,1,48,32\n''') def test_tinyfuncstr(self): + if self.emcc_args is None: return self.skip('requires emcc') src = ''' #include <stdio.h> @@ -3338,6 +3407,7 @@ def process(filename): def test_varargs(self): if Settings.QUANTUM_SIZE == 1: return self.skip('FIXME: Add support for this') + if Settings.ASM_JS: return self.skip('varargs by function pointer not yet supported') src = ''' #include <stdio.h> @@ -3584,6 +3654,7 @@ The current type of b is: 9 assert 'Casting a function pointer type to another with a different number of arguments' in output[1], 'Missing expected warning' def test_stdlibs(self): + if self.emcc_args is None: return self.skip('requires emcc') if Settings.USE_TYPED_ARRAYS == 2: # Typed arrays = 2 + safe heap prints a warning that messes up our output. Settings.SAFE_HEAP = 0 @@ -3787,6 +3858,8 @@ The current type of b is: 9 self.do_run(src, '*staticccz*\n*1.00,2.00,3.00*') def test_copyop(self): + if self.emcc_args is None: return self.skip('requires emcc') + # clang generated code is vulnerable to this, as it uses # memcpy for assignments, with hardcoded numbers of bytes # (llvm-gcc copies items one by one). See QUANTUM_SIZE in @@ -3859,7 +3932,7 @@ The current type of b is: 9 return 0; } ''' - def check(result): + def check(result, err): return hashlib.sha1(result).hexdigest() self.do_run(src, '6c9cdfe937383b79e52ca7a2cce83a21d9f5422c', output_nicerizer = check) @@ -4010,13 +4083,14 @@ The current type of b is: 9 def test_runtimelink(self): if Building.LLVM_OPTS: return self.skip('LLVM opts will optimize printf into puts in the parent, and the child will still look for puts') - if Settings.NAMED_GLOBALS == 0: return self.skip('dlopen cannot work without named globals, TODO') + if Settings.ASM_JS: return self.skip('asm does not support runtime linking') main, supp = self.setup_runtimelink_test() self.banned_js_engines = [NODE_JS] # node's global scope behaves differently than everything else, needs investigation FIXME Settings.LINKABLE = 1 Settings.BUILD_AS_SHARED_LIB = 2 + Settings.NAMED_GLOBALS = 1 self.build(supp, self.get_dir(), self.in_dir('supp.c')) shutil.move(self.in_dir('supp.c.o.js'), self.in_dir('liblib.so')) @@ -4026,6 +4100,9 @@ The current type of b is: 9 self.do_run(main, 'supp: 54,2\nmain: 56\nsupp see: 543\nmain see: 76\nok.') def test_dlfcn_basic(self): + if Settings.ASM_JS: return self.skip('TODO: dlopen in asm') + + Settings.NAMED_GLOBALS = 1 Settings.LINKABLE = 1 lib_src = ''' @@ -4077,7 +4154,11 @@ def process(filename): post_build=add_pre_run_and_checks) def test_dlfcn_qsort(self): + if self.emcc_args is None: return self.skip('requires emcc') + if Settings.ASM_JS: return self.skip('TODO: dlopen in asm') + Settings.LINKABLE = 1 + Settings.NAMED_GLOBALS = 1 if Settings.USE_TYPED_ARRAYS == 2: Settings.CORRECT_SIGNS = 1 # Needed for unsafe optimizations @@ -4165,14 +4246,15 @@ def process(filename): open(filename, 'w').write(src) ''' self.do_run(src, 'Sort with main comparison: 5 4 3 2 1 *Sort with lib comparison: 1 2 3 4 5 *', - output_nicerizer=lambda x: x.replace('\n', '*'), + output_nicerizer=lambda x, err: x.replace('\n', '*'), post_build=add_pre_run_and_checks) def test_dlfcn_data_and_fptr(self): + if Settings.ASM_JS: return self.skip('TODO: dlopen in asm') if Building.LLVM_OPTS: return self.skip('LLVM opts will optimize out parent_func') - if Settings.NAMED_GLOBALS == 0: return self.skip('dlopen cannot work without named globals, TODO') Settings.LINKABLE = 1 + Settings.NAMED_GLOBALS = 1 lib_src = ''' #include <stdio.h> @@ -4268,14 +4350,16 @@ def process(filename): open(filename, 'w').write(src) ''' self.do_run(src, 'In func: 13*First calling main_fptr from lib.*Second calling lib_fptr from main.*parent_func called from child*parent_func called from child*Var: 42*', - output_nicerizer=lambda x: x.replace('\n', '*'), + output_nicerizer=lambda x, err: x.replace('\n', '*'), post_build=add_pre_run_and_checks) def test_dlfcn_alias(self): + if Settings.ASM_JS: return self.skip('TODO: dlopen in asm') + Settings.LINKABLE = 1 + Settings.NAMED_GLOBALS = 1 if Building.LLVM_OPTS == 2: return self.skip('LLVM LTO will optimize away stuff we expect from the shared library') - if Settings.NAMED_GLOBALS == 0: return self.skip('dlopen cannot work without named globals, TODO') lib_src = r''' #include <stdio.h> @@ -4321,13 +4405,16 @@ def process(filename): open(filename, 'w').write(src) ''' self.do_run(src, 'Parent global: 123.*Parent global: 456.*', - output_nicerizer=lambda x: x.replace('\n', '*'), + output_nicerizer=lambda x, err: x.replace('\n', '*'), post_build=add_pre_run_and_checks, extra_emscripten_args=['-H', 'libc/fcntl.h,libc/sys/unistd.h,poll.h,libc/math.h,libc/time.h,libc/langinfo.h']) Settings.INCLUDE_FULL_LIBRARY = 0 def test_dlfcn_varargs(self): + if Settings.ASM_JS: return self.skip('TODO: dlopen in asm') + Settings.LINKABLE = 1 + Settings.NAMED_GLOBALS = 1 if Building.LLVM_OPTS == 2: return self.skip('LLVM LTO will optimize things that prevent shared objects from working') if Settings.QUANTUM_SIZE == 1: return self.skip('FIXME: Add support for this') @@ -4993,7 +5080,7 @@ def process(filename): other.close() src = open(path_from_root('tests', 'files.cpp'), 'r').read() - self.do_run(src, 'size: 7\ndata: 100,-56,50,25,10,77,123\nloop: 100 -56 50 25 10 77 123 \ninput:hi there!\ntexto\ntexte\n$\n5 : 10,30,20,11,88\nother=some data.\nseeked=me da.\nseeked=ata.\nseeked=ta.\nfscanfed: 10 - hello\n', + self.do_run(src, 'size: 7\ndata: 100,-56,50,25,10,77,123\nloop: 100 -56 50 25 10 77 123 \ninput:hi there!\ntexto\ntexte\n$\n5 : 10,30,20,11,88\nother=some data.\nseeked=me da.\nseeked=ata.\nseeked=ta.\nfscanfed: 10 - hello\nok.\n', post_build=post, extra_emscripten_args=['-H', 'libc/fcntl.h']) def test_files_m(self): @@ -5457,7 +5544,8 @@ def process(filename): printf( "%i %i %i", one, two, three ); } ''' - for linkable in [0, 1]: + for linkable in [0]:#, 1]: + print linkable Settings.LINKABLE = linkable # regression check for issue #273 self.do_run(src, "1 2 3") @@ -5898,6 +5986,7 @@ int main(int argc, char **argv) { self.do_run(src, 'hello world\n77.\n') def test_stdvec(self): + if self.emcc_args is None: return self.skip('requires emcc') src = ''' #include <vector> #include <stdio.h> @@ -6021,6 +6110,7 @@ int main(int argc, char **argv) { self.do_run(src, 'Pfannkuchen(%d) = %d.' % (i,j), [str(i)], no_build=i>1) def test_raytrace(self): + if self.emcc_args is None: return self.skip('requires emcc') if Settings.USE_TYPED_ARRAYS == 2: return self.skip('Relies on double value rounding, extremely sensitive') src = open(path_from_root('tests', 'raytrace.cpp'), 'r').read().replace('double', 'float') @@ -6028,18 +6118,20 @@ int main(int argc, char **argv) { self.do_run(src, output, ['3', '16'])#, build_ll_hook=self.do_autodebug) def test_fasta(self): + if self.emcc_args is None: return self.skip('requires emcc') results = [ (1,'''GG*ctt**tgagc*'''), (20,'''GGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTT*cttBtatcatatgctaKggNcataaaSatgtaaaDcDRtBggDtctttataattcBgtcg**tacgtgtagcctagtgtttgtgttgcgttatagtctatttgtggacacagtatggtcaaa**tgacgtcttttgatctgacggcgttaacaaagatactctg*'''), (50,'''GGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGA*TCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACAT*cttBtatcatatgctaKggNcataaaSatgtaaaDcDRtBggDtctttataattcBgtcg**tactDtDagcctatttSVHtHttKtgtHMaSattgWaHKHttttagacatWatgtRgaaa**NtactMcSMtYtcMgRtacttctWBacgaa**agatactctgggcaacacacatacttctctcatgttgtttcttcggacctttcataacct**ttcctggcacatggttagctgcacatcacaggattgtaagggtctagtggttcagtgagc**ggaatatcattcgtcggtggtgttaatctatctcggtgtagcttataaatgcatccgtaa**gaatattatgtttatttgtcggtacgttcatggtagtggtgtcgccgatttagacgtaaa**ggcatgtatg*''') ] for i, j in results: src = open(path_from_root('tests', 'fasta.cpp'), 'r').read() - self.do_run(src, j, [str(i)], lambda x: x.replace('\n', '*'), no_build=i>1) + self.do_run(src, j, [str(i)], lambda x, err: x.replace('\n', '*'), no_build=i>1) def test_dlmalloc(self): if self.emcc_args is None: self.emcc_args = [] # dlmalloc auto-inclusion is only done if we use emcc + self.banned_js_engines = [NODE_JS] # slower, and fail on 64-bit Settings.CORRECT_SIGNS = 2 Settings.CORRECT_SIGNS_LINES = ['src.cpp:' + str(i+4) for i in [4816, 4191, 4246, 4199, 4205, 4235, 4227]] - Settings.TOTAL_MEMORY = 100*1024*1024 # needed with typed arrays + Settings.TOTAL_MEMORY = 128*1024*1024 # needed with typed arrays src = open(path_from_root('system', 'lib', 'dlmalloc.c'), 'r').read() + '\n\n\n' + open(path_from_root('tests', 'dlmalloc_test.c'), 'r').read() self.do_run(src, '*1,0*', ['200', '1']) @@ -6054,7 +6146,7 @@ int main(int argc, char **argv) { # emcc should build in dlmalloc automatically, and do all the sign correction etc. for it try_delete(os.path.join(self.get_dir(), 'src.cpp.o.js')) - output = Popen([PYTHON, EMCC, path_from_root('tests', 'dlmalloc_test.c'), '-s', 'TOTAL_MEMORY=100000000', + output = Popen([PYTHON, EMCC, path_from_root('tests', 'dlmalloc_test.c'), '-s', 'TOTAL_MEMORY=' + str(128*1024*1024), '-o', os.path.join(self.get_dir(), 'src.cpp.o.js')], stdout=PIPE, stderr=self.stderr_redirect).communicate() self.do_run('x', '*1,0*', ['200', '1'], no_build=True) @@ -6105,6 +6197,7 @@ operator new(size_t size) self.do_run(src, 'got 0x7b\nfreed') def test_libcxx(self): + if self.emcc_args is None: return self.skip('requires emcc') self.do_run(open(path_from_root('tests', 'hashtest.cpp')).read(), 'june -> 30\nPrevious (in alphabetical order) is july\nNext (in alphabetical order) is march') @@ -6241,7 +6334,10 @@ void*:16 self.do_run(src, '*10,22*') def test_mmap(self): - Settings.TOTAL_MEMORY = 100*1024*1024 + if self.emcc_args is None: return self.skip('requires emcc') + self.banned_js_engines = [NODE_JS] # slower, and fail on 64-bit + + Settings.TOTAL_MEMORY = 128*1024*1024 src = ''' #include <stdio.h> @@ -6310,6 +6406,7 @@ void*:16 self.do_run(src, '*\ndata from the file .\nfrom the file ......\n*\n') def test_cubescript(self): + if self.emcc_args is None: return self.skip('requires emcc') if self.emcc_args is not None and '-O2' in self.emcc_args: self.emcc_args += ['--closure', '1'] # Use closure here for some additional coverage @@ -6326,7 +6423,7 @@ void*:16 self.do_run(path_from_root('tests', 'cubescript'), '*\nTemp is 33\n9\n5\nhello, everyone\n*', main_file='command.cpp') def test_gcc_unmangler(self): - Settings.NAMED_GLOBALS = 0 # test coverage for this + Settings.NAMED_GLOBALS = 1 # test coverage for this Building.COMPILER_TEST_OPTS = ['-I' + path_from_root('third_party')] @@ -6343,27 +6440,22 @@ void*:16 # print opt, "FAIL" def test_lua(self): - if self.emcc_args is None and Building.LLVM_OPTS: return self.skip('llvm 3.1 and safe llvm opts break lua') + if self.emcc_args is None: return self.skip('requires emcc') - try: - os.environ['EMCC_LEAVE_INPUTS_RAW'] = '1' + if Settings.QUANTUM_SIZE == 1: return self.skip('TODO: make this work') - if Settings.QUANTUM_SIZE == 1: return self.skip('TODO: make this work') + # Overflows in luaS_newlstr hash loop + if self.emcc_args is None: Settings.SAFE_HEAP = 0 # Has various warnings, with copied HEAP_HISTORY values (fixed if we copy 'null' as the type) + Settings.CORRECT_OVERFLOWS = 1 + Settings.CHECK_OVERFLOWS = 0 + Settings.CORRECT_SIGNS = 1 # Not sure why, but needed + Settings.INIT_STACK = 1 # TODO: Investigate why this is necessary - # Overflows in luaS_newlstr hash loop - if self.emcc_args is None: Settings.SAFE_HEAP = 0 # Has various warnings, with copied HEAP_HISTORY values (fixed if we copy 'null' as the type) - Settings.CORRECT_OVERFLOWS = 1 - Settings.CHECK_OVERFLOWS = 0 - Settings.CORRECT_SIGNS = 1 # Not sure why, but needed - Settings.INIT_STACK = 1 # TODO: Investigate why this is necessary - - self.do_ll_run(path_from_root('tests', 'lua', 'lua.ll'), - 'hello lua world!\n17\n1\n2\n3\n4\n7', - args=['-e', '''print("hello lua world!");print(17);for x = 1,4 do print(x) end;print(10-3)'''], - output_nicerizer=lambda string: string.replace('\n\n', '\n').replace('\n\n', '\n'), - extra_emscripten_args=['-H', 'libc/fcntl.h,libc/sys/unistd.h,poll.h,libc/math.h,libc/langinfo.h,libc/time.h']) - finally: - del os.environ['EMCC_LEAVE_INPUTS_RAW'] + self.do_ll_run(path_from_root('tests', 'lua', 'lua.ll'), + 'hello lua world!\n17\n1\n2\n3\n4\n7', + args=['-e', '''print("hello lua world!");print(17);for x = 1,4 do print(x) end;print(10-3)'''], + output_nicerizer=lambda string, err: (string + err).replace('\n\n', '\n').replace('\n\n', '\n'), + extra_emscripten_args=['-H', 'libc/fcntl.h,libc/sys/unistd.h,poll.h,libc/math.h,libc/langinfo.h,libc/time.h']) def get_freetype(self): Settings.INIT_STACK = 1 # TODO: Investigate why this is necessary @@ -6371,7 +6463,9 @@ void*:16 os.path.join('objs', '.libs', 'libfreetype.a')) def test_freetype(self): + if self.emcc_args is None: return self.skip('requires emcc') if Settings.QUANTUM_SIZE == 1: return self.skip('TODO: Figure out and try to fix') + if Settings.ASM_JS: return self.skip('asm does not support longjmp') if Settings.CORRECT_SIGNS == 0: Settings.CORRECT_SIGNS = 1 # Not sure why, but needed @@ -6428,16 +6522,13 @@ def process(filename): if self.emcc_args is None: return self.skip('Very slow without ta2, and we would also need to include dlmalloc manually without emcc') if Settings.QUANTUM_SIZE == 1: return self.skip('TODO FIXME') - pgo_data = read_pgo_data(path_from_root('tests', 'sqlite', 'sqlite-autooptimize.fails.txt')) - Settings.CORRECT_SIGNS = 1 # XXX: in default, we fail with 2 here, even though the pgo_data should be correct (and works in s_0_0). Investigate this. - Settings.CORRECT_SIGNS_LINES = pgo_data['signs_lines'] Settings.CORRECT_OVERFLOWS = 0 Settings.CORRECT_ROUNDINGS = 0 if self.emcc_args is None: Settings.SAFE_HEAP = 0 # uses time.h to set random bytes, other stuff Settings.DISABLE_EXCEPTION_CATCHING = 1 Settings.FAST_MEMORY = 4*1024*1024 - Settings.EXPORTED_FUNCTIONS = ['_main', '_sqlite3_open', '_sqlite3_close', '_sqlite3_exec', '_sqlite3_free', '_callback']; + Settings.EXPORTED_FUNCTIONS += ['_sqlite3_open', '_sqlite3_close', '_sqlite3_exec', '_sqlite3_free', '_callback']; self.do_run(r''' #define SQLITE_DISABLE_LFS @@ -6463,6 +6554,7 @@ def process(filename): force_c=True) def test_the_bullet(self): # Called thus so it runs late in the alphabetical cycle... it is long + if self.emcc_args is None: return self.skip('requires emcc') if Building.LLVM_OPTS and self.emcc_args is None: Settings.SAFE_HEAP = 0 # Optimizations make it so we do not have debug info on the line we need to ignore # Note: this is also a good test of per-file and per-line changes (since we have multiple files, and correct specific lines) @@ -6483,6 +6575,7 @@ def process(filename): def test_poppler(self): if self.emcc_args is None: return self.skip('very slow, we only do this in emcc runs') + if Settings.ASM_JS: return self.skip('asm does not support relying on function pointers being cast to different types') Settings.CORRECT_OVERFLOWS = 1 Settings.CORRECT_SIGNS = 1 @@ -6572,7 +6665,7 @@ def process(filename): # We use doubles in JS, so we get slightly different values than native code. So we # check our output by comparing the average pixel difference - def image_compare(output): + def image_compare(output, err): # Get the image generated by JS, from the JSON.stringify'd array m = re.search('\[[\d, -]*\]', output) try: @@ -6646,6 +6739,7 @@ def process(filename): print >> sys.stderr, 'not doing debug check' def test_python(self): + if self.emcc_args is None: return self.skip('requires emcc') if Settings.QUANTUM_SIZE == 1: return self.skip('TODO: make this work') # Overflows in string_hash @@ -6653,7 +6747,7 @@ def process(filename): Settings.CHECK_OVERFLOWS = 0 if self.emcc_args is None: Settings.SAFE_HEAP = 0 # Has bitfields which are false positives. Also the PyFloat_Init tries to detect endianness. Settings.CORRECT_SIGNS = 1 # Not sure why, but needed - Settings.EXPORTED_FUNCTIONS = ['_main', '_PyRun_SimpleStringFlags'] # for the demo + Settings.EXPORTED_FUNCTIONS += ['_PyRun_SimpleStringFlags'] # for the demo self.do_ll_run(path_from_root('tests', 'python', 'python.small.bc'), 'hello python world!\n[0, 2, 4, 6]\n5\n22\n5.470000', @@ -6662,17 +6756,9 @@ def process(filename): def test_lifetime(self): if self.emcc_args is None: return self.skip('test relies on emcc opts') - try: - os.environ['EMCC_LEAVE_INPUTS_RAW'] = '1' - - self.do_ll_run(path_from_root('tests', 'lifetime.ll'), 'hello, world!\n') - if '-O1' in self.emcc_args or '-O2' in self.emcc_args: - assert 'a18' not in open(os.path.join(self.get_dir(), 'src.cpp.o.js')).read(), 'lifetime stuff and their vars must be culled' - else: - assert 'a18' in open(os.path.join(self.get_dir(), 'src.cpp.o.js')).read(), "without opts, it's there" - - finally: - del os.environ['EMCC_LEAVE_INPUTS_RAW'] + self.do_ll_run(path_from_root('tests', 'lifetime.ll'), 'hello, world!\n') + if '-O1' in self.emcc_args or '-O2' in self.emcc_args: + assert 'a18' not in open(os.path.join(self.get_dir(), 'src.cpp.o.js')).read(), 'lifetime stuff and their vars must be culled' # Test cases in separate files. Note that these files may contain invalid .ll! # They are only valid enough for us to read for test purposes, not for llvm-as @@ -6691,6 +6777,9 @@ def process(filename): if '_ta2' in shortname and not Settings.USE_TYPED_ARRAYS == 2: print self.skip('case "%s" only relevant for ta2' % shortname) continue + if '_noasm' in shortname and Settings.ASM_JS: + print self.skip('case "%s" not relevant for asm.js' % shortname) + continue print >> sys.stderr, "Testing case '%s'..." % shortname output_file = path_from_root('tests', 'cases', shortname + '.txt') if Settings.QUANTUM_SIZE == 1: @@ -6764,6 +6853,8 @@ def process(filename): self.do_run(src, '''AD:-1,1''', build_ll_hook=self.do_autodebug) def test_profiling(self): + if Settings.ASM_JS: return self.skip('asm does not support profiling') + src = ''' #include <emscripten.h> #include <unistd.h> @@ -6805,18 +6896,15 @@ Block 0: ''', post_build=post1) src = r''' #include <stdio.h> - // Optimizations might wipe out our functions without this - #define KEEPALIVE __attribute__((used)) - extern "C" { - int KEEPALIVE get_int() { return 5; } - float KEEPALIVE get_float() { return 3.14; } - char * KEEPALIVE get_string() { return "hello world"; } - void KEEPALIVE print_int(int x) { printf("%d\n", x); } - void KEEPALIVE print_float(float x) { printf("%.2f\n", x); } - void KEEPALIVE print_string(char *x) { printf("%s\n", x); } - int KEEPALIVE multi(int x, float y, int z, char *str) { if (x) puts(str); return (x+y)*z; } - int * KEEPALIVE pointer(int *in) { printf("%d\n", *in); static int ret = 21; return &ret; } + int get_int() { return 5; } + float get_float() { return 3.14; } + char * get_string() { return "hello world"; } + void print_int(int x) { printf("%d\n", x); } + void print_float(float x) { printf("%.2f\n", x); } + void print_string(char *x) { printf("%s\n", x); } + int multi(int x, float y, int z, char *str) { if (x) puts(str); return (x+y)*z; } + int * pointer(int *in) { printf("%d\n", *in); static int ret = 21; return &ret; } } int main(int argc, char **argv) { @@ -6868,11 +6956,14 @@ def process(filename): open(filename, 'w').write(src) ''' - Settings.EXPORTED_FUNCTIONS = ['_get_int', '_get_float', '_get_string', '_print_int', '_print_float', '_print_string', '_multi', '_pointer', '_malloc'] + Settings.EXPORTED_FUNCTIONS += ['_get_int', '_get_float', '_get_string', '_print_int', '_print_float', '_print_string', '_multi', '_pointer', '_malloc'] self.do_run(src, '*\nnumber,5\nnumber,3.14\nstring,hello world\n12\nundefined\n14.56\nundefined\ncheez\nundefined\narr-ay\nundefined\nmore\nnumber,10\n650\nnumber,21\n*\natr\n10\nbret\n53\n*\nstack is ok.\n', post_build=post) def test_scriptaclass(self): + if self.emcc_args is None: return self.skip('requires emcc') + if Settings.ASM_JS: return self.skip('asm does not bindings generator yet') + header_filename = os.path.join(self.get_dir(), 'header.h') header = ''' struct ScriptMe { @@ -7117,6 +7208,9 @@ Child2:9 ''', post_build=[post2, post3]) def test_scriptaclass_2(self): + if self.emcc_args is None: return self.skip('requires emcc') + if Settings.ASM_JS: return self.skip('asm does not bindings generator yet') + header_filename = os.path.join(self.get_dir(), 'header.h') header = ''' #include <stdio.h> @@ -7219,8 +7313,8 @@ def process(filename): src = ''' #include<stdio.h> - int main() { - int *x = new int; + #include<stdlib.h> + int main() { int *x = (int*)malloc(sizeof(int)); *x = 20; float *y = (float*)x; printf("%f\\n", *y); @@ -7265,8 +7359,8 @@ def process(filename): module = ''' #include<stdio.h> - void callFunc() { - int *x = new int; + #include<stdlib.h> + void callFunc() { int *x = (int*)malloc(sizeof(int)); *x = 20; float *y = (float*)x; printf("%f\\n", *y); @@ -7277,10 +7371,10 @@ def process(filename): main = ''' #include<stdio.h> + #include<stdlib.h> extern void callFunc(); - int main() { - callFunc(); - int *x = new int; + int main() { callFunc(); + int *x = (int*)malloc(sizeof(int)); *x = 20; float *y = (float*)x; printf("%f\\n", *y); @@ -7320,6 +7414,8 @@ def process(filename): assert 'Assertion failed: Load-store consistency assumption failure!' in str(e), str(e) def test_check_overflow(self): + if Settings.ASM_JS: return self.skip('asm always corrects, and cannot check') + Settings.CHECK_OVERFLOWS = 1 Settings.CORRECT_OVERFLOWS = 0 @@ -7374,6 +7470,8 @@ def process(filename): assert 'Assertion failed' in str(e), str(e) def test_linespecific(self): + if Settings.ASM_JS: return self.skip('asm always has corrections on') + if '-g' not in Building.COMPILER_TEST_OPTS: Building.COMPILER_TEST_OPTS.append('-g') if self.emcc_args: self.emcc_args += ['--llvm-opts', '0'] # llvm full opts make the expected failures here not happen @@ -7531,6 +7629,8 @@ def process(filename): Settings.CORRECT_SIGNS = 0 def test_pgo(self): + if Settings.ASM_JS: return self.skip('asm does not support pgo') + if '-g' not in Building.COMPILER_TEST_OPTS: Building.COMPILER_TEST_OPTS.append('-g') Settings.PGO = Settings.CHECK_OVERFLOWS = Settings.CORRECT_OVERFLOWS = Settings.CHECK_SIGNS = Settings.CORRECT_SIGNS = 1 @@ -7553,7 +7653,7 @@ def process(filename): } ''' - def check(output): + def check(output, err): # TODO: check the line # if self.emcc_args is None or self.emcc_args == []: # LLVM full opts optimize out some corrections assert re.search('^Overflow\|.*src.cpp:6 : 60 hits, %20 failures$', output, re.M), 'no indication of Overflow corrections: ' + output @@ -7606,6 +7706,7 @@ def process(filename): def test_gc(self): if self.emcc_args == None: return self.skip('needs ta2') + if Settings.ASM_JS: return self.skip('asm cannot support generic function table') Settings.GC_SUPPORT = 1 @@ -7788,6 +7889,10 @@ TT = %s # Make one run with -O2, but without closure (we enable closure in specific tests, otherwise on everything it is too slow) exec('o2 = make_run("o2", compiler=CLANG, emcc_args=["-O2", "--closure", "0"])') + # asm.js + #exec('asm = make_run("asm", compiler=CLANG, emcc_args=["-O0", "--closure", "0", "-s", "ASM_JS=1"])') + exec('asm2 = make_run("asm2", compiler=CLANG, emcc_args=["-O2", "--closure", "0", "-s", "ASM_JS=1"])') + # Make custom runs with various options for compiler, quantum, embetter, typed_arrays, llvm_opts in [ (CLANG, 1, 1, 0, 0), @@ -7908,6 +8013,7 @@ Options that are modified or new in %s include: # dlmalloc. dlmalloc is special in that it is the only part of libc that is (1) hard to write well, and # very speed-sensitive. So we do not implement it in JS in library.js, instead we compile it from source for source, has_malloc in [('hello_world' + suffix, False), ('hello_malloc.cpp', True)]: + print source, has_malloc self.clear() output = Popen([PYTHON, compiler, path_from_root('tests', source)], stdout=PIPE, stderr=PIPE).communicate() assert os.path.exists('a.out.js'), '\n'.join(output) @@ -8337,6 +8443,8 @@ f.close() self.assertContained('hello from lib', run_js(os.path.join(self.get_dir(), 'a.out.js'))) def test_runtimelink_multi(self): + if Settings.ASM_JS: return self.skip('asm does not support runtime linking yet') + if SPIDERMONKEY_ENGINE not in JS_ENGINES: return self.skip('cannot run without spidermonkey due to node limitations') open('testa.h', 'w').write(r''' @@ -8394,9 +8502,9 @@ f.close() } ''') - Popen([PYTHON, EMCC, 'testa.cpp', '-o', 'liba.js', '-s', 'BUILD_AS_SHARED_LIB=2', '-s', 'LINKABLE=1', '-I.']).communicate() - Popen([PYTHON, EMCC, 'testb.cpp', '-o', 'libb.js', '-s', 'BUILD_AS_SHARED_LIB=2', '-s', 'LINKABLE=1', '-I.']).communicate() - Popen([PYTHON, EMCC, 'main.cpp', '-o', 'main.js', '-s', 'RUNTIME_LINKED_LIBS=["liba.js", "libb.js"]', '-I.']).communicate() + Popen([PYTHON, EMCC, 'testa.cpp', '-o', 'liba.js', '-s', 'BUILD_AS_SHARED_LIB=2', '-s', 'LINKABLE=1', '-s', 'NAMED_GLOBALS=1', '-I.']).communicate() + Popen([PYTHON, EMCC, 'testb.cpp', '-o', 'libb.js', '-s', 'BUILD_AS_SHARED_LIB=2', '-s', 'LINKABLE=1', '-s', 'NAMED_GLOBALS=1', '-I.']).communicate() + Popen([PYTHON, EMCC, 'main.cpp', '-o', 'main.js', '-s', 'RUNTIME_LINKED_LIBS=["liba.js", "libb.js"]', '-s', 'NAMED_GLOBALS=1', '-I.']).communicate() Popen([PYTHON, EMCC, 'main.cpp', 'testa.cpp', 'testb.cpp', '-o', 'full.js', '-I.']).communicate() @@ -8668,6 +8776,48 @@ f.close() Popen([PYTHON, EMCC, os.path.join(self.get_dir(), 'main.cpp')]).communicate() self.assertContained('1234, 1234, 4321\n', run_js(os.path.join(self.get_dir(), 'a.out.js'))) + def test_link_memcpy(self): + # memcpy can show up *after* optimizations, so after our opportunity to link in libc, so it must be special-cased + open(os.path.join(self.get_dir(), 'main.cpp'), 'w').write(r''' + #include <stdio.h> + + int main(int argc, char **argv) { + int num = argc + 10; + char buf[num], buf2[num]; + for (int i = 0; i < num; i++) { + buf[i] = i*i+i/3; + } + for (int i = 1; i < num; i++) { + buf[i] += buf[i-1]; + } + for (int i = 0; i < num; i++) { + buf2[i] = buf[i]; + } + for (int i = 1; i < num; i++) { + buf2[i] += buf2[i-1]; + } + for (int i = 0; i < num; i++) { + printf("%d:%d\n", i, buf2[i]); + } + return 0; + } + ''') + Popen([PYTHON, EMCC, '-O2', '--closure', '-0', os.path.join(self.get_dir(), 'main.cpp')]).communicate() + output = run_js(os.path.join(self.get_dir(), 'a.out.js'), full_output=True, stderr=PIPE) + self.assertContained('''0:0 +1:1 +2:6 +3:21 +4:53 +5:111 +6:-49 +7:98 +8:55 +9:96 +10:-16 +''', output) + self.assertNotContained('warning: library.js memcpy should not be running, it is only for testing!', output) + def test_warn_undefined(self): open(os.path.join(self.get_dir(), 'main.cpp'), 'w').write(r''' #include <stdio.h> @@ -8738,9 +8888,13 @@ f.close() self.assertNotContained('pre-run\nhello from main\npost-run\n', run_js(os.path.join(self.get_dir(), 'a.out.js'))) # noInitialRun prevents run - for no_initial_run in [0, 1]: + for no_initial_run, run_dep in [(0, 0), (1, 0), (0, 1), (1, 1)]: + print no_initial_run, run_dep Popen([PYTHON, EMCC, os.path.join(self.get_dir(), 'main.cpp')]).communicate() src = 'var Module = { noInitialRun: %d };\n' % no_initial_run + open(os.path.join(self.get_dir(), 'a.out.js')).read() + if run_dep: + src = src.replace('// {{PRE_RUN_ADDITIONS}}', '// {{PRE_RUN_ADDITIONS}}\naddRunDependency("test");') \ + .replace('// {{POST_RUN_ADDITIONS}}', '// {{POST_RUN_ADDITIONS}}\nremoveRunDependency("test");') open(os.path.join(self.get_dir(), 'a.out.js'), 'w').write(src) assert ('hello from main' in run_js(os.path.join(self.get_dir(), 'a.out.js'))) != no_initial_run, 'only run if no noInitialRun' @@ -8825,6 +8979,12 @@ f.close() ['eliminate']), (path_from_root('tools', 'eliminator', 'safe-eliminator-test.js'), open(path_from_root('tools', 'eliminator', 'safe-eliminator-test-output.js')).read(), ['eliminateMemSafe']), + (path_from_root('tools', 'eliminator', 'asm-eliminator-test.js'), open(path_from_root('tools', 'eliminator', 'asm-eliminator-test-output.js')).read(), + ['eliminateAsm']), + (path_from_root('tools', 'test-js-optimizer-asm-regs.js'), open(path_from_root('tools', 'test-js-optimizer-asm-regs-output.js')).read(), + ['registerizeAsm']), + (path_from_root('tools', 'test-js-optimizer-asm-pre.js'), open(path_from_root('tools', 'test-js-optimizer-asm-pre-output.js')).read(), + ['simplifyExpressionsPreAsm']), ]: output = Popen([NODE_JS, path_from_root('tools', 'js-optimizer.js'), input] + passes, stdin=PIPE, stdout=PIPE).communicate()[0] self.assertIdentical(expected, output.replace('\r\n', '\n').replace('\n\n', '\n')) @@ -10107,10 +10267,10 @@ elif 'browser' in str(sys.argv): main, supp = self.setup_runtimelink_test() open(self.in_dir('supp.cpp'), 'w').write(supp) - Popen([PYTHON, EMCC, self.in_dir('supp.cpp'), '-o', 'supp.js', '-s', 'LINKABLE=1', '-s', 'BUILD_AS_SHARED_LIB=2', '-O2', '--closure', '0']).communicate() + Popen([PYTHON, EMCC, self.in_dir('supp.cpp'), '-o', 'supp.js', '-s', 'LINKABLE=1', '-s', 'NAMED_GLOBALS=1', '-s', 'BUILD_AS_SHARED_LIB=2', '-O2', '--closure', '0']).communicate() shutil.move(self.in_dir('supp.js'), self.in_dir('supp.so')) - self.btest(main, args=['-s', 'LINKABLE=1', '-s', 'RUNTIME_LINKED_LIBS=["supp.so"]', '-DBROWSER=1', '-O2', '--closure', '0'], expected='76') + self.btest(main, args=['-s', 'LINKABLE=1', '-s', 'NAMED_GLOBALS=1', '-s', 'RUNTIME_LINKED_LIBS=["supp.so"]', '-DBROWSER=1', '-O2', '--closure', '0'], expected='76') def test_pre_run_deps(self): # Adding a dependency in preRun will delay run @@ -10134,6 +10294,9 @@ elif 'browser' in str(sys.argv): Popen([PYTHON, EMCC, path_from_root('tests', 'worker_api_2_worker.cpp'), '-o', 'worker.js', '-s', 'BUILD_AS_WORKER=1', '-O2', '--minify', '0', '-s', 'EXPORTED_FUNCTIONS=["_one", "_two", "_three", "_four"]']).communicate() self.btest('worker_api_2_main.cpp', args=['-O2', '--minify', '0'], expected='11') + def test_emscripten_async_wget2(self): + self.btest('http.cpp', expected='0', args=['-I' + path_from_root('tests')]) + pids_to_clean = [] def clean_pids(self): import signal, errno @@ -10213,7 +10376,7 @@ elif 'browser' in str(sys.argv): # always run these tests last # make sure to use different ports in each one because it takes a while for the processes to be cleaned up - def test_zz_websockets(self): + def test_websockets(self): try: with self.WebsockHarness(8990): self.btest('websockets.c', expected='571') @@ -10228,16 +10391,17 @@ elif 'browser' in str(sys.argv): proc.communicate() return relay_server - def test_zz_websockets_bi(self): - try: - with self.WebsockHarness(8992, self.make_relay_server(8992, 8994)): - with self.WebsockHarness(8994, no_server=True): - Popen([PYTHON, EMCC, path_from_root('tests', 'websockets_bi_side.c'), '-o', 'side.html', '-DSOCKK=8995']).communicate() - self.btest('websockets_bi.c', expected='2499') - finally: - self.clean_pids() + def test_websockets_bi(self): + for datagram in [0,1]: + try: + with self.WebsockHarness(8992, self.make_relay_server(8992, 8994)): + with self.WebsockHarness(8994, no_server=True): + Popen([PYTHON, EMCC, path_from_root('tests', 'websockets_bi_side.c'), '-o', 'side.html', '-DSOCKK=8995', '-DTEST_DGRAM=%d' % datagram]).communicate() + self.btest('websockets_bi.c', expected='2499', args=['-DTEST_DGRAM=%d' % datagram]) + finally: + self.clean_pids() - def test_zz_websockets_bi_listen(self): + def test_websockets_bi_listen(self): try: with self.WebsockHarness(6992, self.make_relay_server(6992, 6994)): with self.WebsockHarness(6994, no_server=True): @@ -10246,14 +10410,14 @@ elif 'browser' in str(sys.argv): finally: self.clean_pids() - def test_zz_websockets_gethostbyname(self): + def test_websockets_gethostbyname(self): try: with self.WebsockHarness(7000): self.btest('websockets_gethostbyname.c', expected='571', args=['-O2']) finally: self.clean_pids() - def test_zz_websockets_bi_bigdata(self): + def test_websockets_bi_bigdata(self): try: with self.WebsockHarness(3992, self.make_relay_server(3992, 3994)): with self.WebsockHarness(3994, no_server=True): @@ -10262,7 +10426,7 @@ elif 'browser' in str(sys.argv): finally: self.clean_pids() - def test_zz_enet(self): + def test_enet(self): try_delete(self.in_dir('enet')) shutil.copytree(path_from_root('tests', 'enet'), self.in_dir('enet')) pwd = os.getcwd() @@ -10375,8 +10539,8 @@ elif 'benchmark' in str(sys.argv): try_delete(final_filename) output = Popen([PYTHON, EMCC, filename, #'-O3', - '-O2', '-s', 'INLINING_LIMIT=0', '-s', 'DOUBLE_MODE=0', '-s', 'PRECISE_I64_MATH=0', - '-s', 'TOTAL_MEMORY=100*1024*1024', '-s', 'FAST_MEMORY=10*1024*1024', + '-O2', '-s', 'INLINING_LIMIT=0', '-s', 'DOUBLE_MODE=0', '-s', 'PRECISE_I64_MATH=0',# '-s', 'ASM_JS=1', + '-s', 'TOTAL_MEMORY=128*1024*1024', '-s', 'FAST_MEMORY=10*1024*1024', '-o', final_filename] + emcc_args, stdout=PIPE, stderr=self.stderr_redirect).communicate() assert os.path.exists(final_filename), 'Failed to compile file: ' + output[0] @@ -10386,6 +10550,8 @@ elif 'benchmark' in str(sys.argv): for i in range(TEST_REPS): start = time.time() js_output = self.run_generated_code(JS_ENGINE, final_filename, args, check_timeout=False) + if i == 0 and 'Successfully compiled asm.js code' in js_output: + print "[%s was asm.js'ified]" % name curr = time.time()-start times.append(curr) total_times[tests_done] += curr @@ -10681,9 +10847,9 @@ elif 'sanity' in str(sys.argv): self.assertContained(content, config_file) # The guessed config should be ok XXX This depends on your local system! it is possible `which` guesses wrong - try_delete('a.out.js') - output = Popen([PYTHON, EMCC, path_from_root('tests', 'hello_world.c')], stdout=PIPE, stderr=PIPE).communicate() - self.assertContained('hello, world!', run_js('a.out.js'), output) + #try_delete('a.out.js') + #output = Popen([PYTHON, EMCC, path_from_root('tests', 'hello_world.c')], stdout=PIPE, stderr=PIPE).communicate() + #self.assertContained('hello, world!', run_js('a.out.js'), output) # Second run, with bad EM_CONFIG for settings in ['blah', 'LLVM_ROOT="blarg"; JS_ENGINES=[]; COMPILER_ENGINE=NODE_JS=SPIDERMONKEY_ENGINE=[]']: @@ -10904,8 +11070,8 @@ fi # Building a file that doesn't need cached stuff should not trigger cache generation output = self.do([EMCC, path_from_root('tests', 'hello_world.cpp')]) - assert INCLUDING_MESSAGE.replace('X', 'dlmalloc') not in output - assert BUILDING_MESSAGE.replace('X', 'dlmalloc') not in output + assert INCLUDING_MESSAGE.replace('X', 'libc') not in output + assert BUILDING_MESSAGE.replace('X', 'libc') not in output self.assertContained('hello, world!', run_js('a.out.js')) assert not os.path.exists(EMCC_CACHE) try_delete('a.out.js') @@ -10913,26 +11079,24 @@ fi basebc_name = os.path.join(TEMP_DIR, 'emscripten_temp', 'emcc-0-basebc.bc') dcebc_name1 = os.path.join(TEMP_DIR, 'emscripten_temp', 'emcc-1-linktime.bc') dcebc_name2 = os.path.join(TEMP_DIR, 'emscripten_temp', 'emcc-2-linktime.bc') - ll_name1 = os.path.join(TEMP_DIR, 'emscripten_temp', 'emcc-2-ll.ll') - ll_name2 = os.path.join(TEMP_DIR, 'emscripten_temp', 'emcc-3-ll.ll') + ll_names = [os.path.join(TEMP_DIR, 'emscripten_temp', 'emcc-X-ll.ll').replace('X', str(x)) for x in range(2,5)] # Building a file that *does* need dlmalloc *should* trigger cache generation, but only the first time - for filename, libname in [('hello_malloc.cpp', 'dlmalloc'), ('hello_libcxx.cpp', 'libcxx')]: + for filename, libname in [('hello_malloc.cpp', 'libc'), ('hello_libcxx.cpp', 'libcxx')]: for i in range(3): print filename, libname, i self.clear() dcebc_name = dcebc_name1 if i == 0 else dcebc_name2 - ll_name = ll_name1 if i == 0 else ll_name2 try_delete(basebc_name) # we might need to check this file later try_delete(dcebc_name) # we might need to check this file later - try_delete(ll_name) # we might need to check this file later + for ll_name in ll_names: try_delete(ll_name) output = self.do([EMCC, '-O' + str(i), '--closure', '0', '-s', 'RELOOP=0', '--llvm-lto', '0', path_from_root('tests', filename)]) #print output assert INCLUDING_MESSAGE.replace('X', libname) in output - if libname == 'dlmalloc': + if libname == 'libc': assert INCLUDING_MESSAGE.replace('X', 'libcxx') not in output # we don't need libcxx in this code else: - assert INCLUDING_MESSAGE.replace('X', 'dlmalloc') in output # libcxx always forces inclusion of dlmalloc + assert INCLUDING_MESSAGE.replace('X', 'libc') in output # libcxx always forces inclusion of libc assert (BUILDING_MESSAGE.replace('X', libname) in output) == (i == 0), 'Must only build the first time' self.assertContained('hello, world!', run_js('a.out.js')) assert os.path.exists(EMCC_CACHE) @@ -10943,10 +11107,16 @@ fi assert os.stat(basebc_name).st_size > 1800000, 'libc++ is indeed big' assert os.stat(dcebc_name).st_size < 750000, 'Dead code elimination must remove most of libc++' # should only have metadata in -O0, not 1 and 2 - ll = open(ll_name).read() - if (ll.count('\n!') < 10) == (i == 0): # a few lines are left even in -O1 and -O2 - print i, 'll metadata should be removed in -O1 and O2 by default', ll[-300:] - assert False + if i > 0: + for ll_name in ll_names: + ll = None + try: + ll = open(ll_name).read() + break + except: + pass + assert ll + assert ll.count('\n!') < 10 # a few lines are left even in -O1 and -O2 finally: del os.environ['EMCC_DEBUG'] @@ -11023,7 +11193,7 @@ fi (['--jcache'], 'hello_libcxx.cpp', False, True, False, True, False, True, []), ([], 'hello_libcxx.cpp', False, False, False, False, False, False, []), # finally, build a file close to the previous, to see that some chunks are found in the cache and some not - (['--jcache'], 'hello_libcxx_mod1.cpp', False, True, True, True, True, True, []), # win on pre, mix on funcs, mix on jsfuncs + (['--jcache'], 'hello_libcxx_mod1.cpp', False, True, True, True, True, False, []), # win on pre, mix on funcs, lose on jsfuncs (['--jcache'], 'hello_libcxx_mod1.cpp', False, True, False, True, False, True, []), ]: print >> sys.stderr, args, input_file, expect_pre_save, expect_pre_load, expect_funcs_save, expect_funcs_load, expect_jsfuncs_save, expect_jsfuncs_load, expected diff --git a/tests/sqlite/sqlite-autooptimize.fails.txt b/tests/sqlite/sqlite-autooptimize.fails.txt deleted file mode 100644 index a8fb95c9..00000000 --- a/tests/sqlite/sqlite-autooptimize.fails.txt +++ /dev/null @@ -1,3436 +0,0 @@ -UnSign|src.c:53573 : 5437030 hits, %0 failures -UnSign|src.c:48532 : 5148135 hits, %0 failures -UnSign|src.c:48527 : 5100537 hits, %0 failures -UnSign|src.c:52005 : 4073874 hits, %0 failures -UnSign|src.c:53050 : 3934072 hits, %0 failures -UnSign|src.c:18445 : 3774770 hits, %0 failures -ReSign|src.c:53625 : 3436900 hits, %0 failures -ReSign|src.c:53628 : 3425390 hits, %0 failures -UnSign|src.c:60549 : 3283684 hits, %0 failures -UnSign|src.c:60553 : 3273669 hits, %0 failures -UnSign|src.c:48406 : 3040270 hits, %0 failures -ReSign|src.c:20723 : 2661440 hits, %0 failures -ReSign|src.c:60568 : 2383652 hits, %0 failures -ReSign|src.c:57231 : 2322446 hits, %0 failures -UnSign|src.c:20762 : 2255540 hits, %0 failures -ReSign|src.c:53571 : 2197772 hits, %0 failures -ReSign|src.c:60549 : 2182456 hits, %0 failures -ReSign|src.c:60554 : 2182446 hits, %0 failures -ReSign|src.c:60562 : 2182446 hits, %0 failures -UnSign|src.c:60543 : 2096937 hits, %0 failures -ReSign|src.c:52033 : 2036931 hits, %0 failures -ReSign|src.c:104878 : 1954211 hits, %0 failures -ReSign|src.c:20762 : 1904614 hits, %0 failures -ReSign|src.c:104872 : 1779034 hits, %0 failures -ReSign|src.c:53101 : 1720386 hits, %0 failures -UnSign|src.c:48501 : 1716045 hits, %0 failures -ReSign|src.c:48513 : 1716045 hits, %0 failures -UnSign|src.c:48545 : 1716045 hits, %0 failures -UnSign|src.c:53627 : 1712695 hits, %0 failures -UnSign|src.c:53104 : 1701640 hits, %0 failures -UnSign|src.c:53106 : 1701640 hits, %0 failures -ReSign|src.c:48527 : 1700179 hits, %0 failures -ReSign|src.c:20618 : 1582657 hits, %0 failures -ReSign|src.c:82816 : 1520000 hits, %0 failures -ReSign|src.c:57232 : 1374742 hits, %0 failures -ReSign|src.c:52083 : 1357954 hits, %0 failures -ReSign|src.c:107278 : 1330720 hits, %0 failures -ReSign|src.c:18445 : 1271522 hits, %0 failures -ReSign|src.c:106763 : 1253037 hits, %0 failures -ReSign|src.c:18496 : 1251458 hits, %0 failures -ReSign|src.c:53561 : 1239128 hits, %0 failures -ReSign|src.c:48399 : 1227618 hits, %0 failures -ReSign|src.c:48394 : 1221863 hits, %0 failures -UnSign|src.c:57190 : 1161232 hits, %0 failures -UnSign|src.c:57191 : 1161232 hits, %0 failures -ReSign|src.c:57198 : 1161232 hits, %0 failures -ReSign|src.c:57206 : 1161232 hits, %0 failures -ReSign|src.c:57207 : 1161223 hits, %0 failures -ReSign|src.c:57210 : 1161223 hits, %0 failures -ReSign|src.c:57213 : 1161223 hits, %0 failures -ReSign|src.c:12957 : 1159636 hits, %0 failures -ReSign|src.c:107458 : 1127259 hits, %0 failures -ReSign|src.c:60553 : 1091223 hits, %0 failures -ReSign|src.c:60564 : 1091223 hits, %0 failures -ReSign|src.c:52086 : 1086554 hits, %0 failures -ReSign|src.c:18497 : 1071311 hits, %0 failures -ReSign|src.c:18501 : 1071311 hits, %0 failures -UnSign|src.c:48434 : 1050126 hits, %0 failures -ReSign|src.c:63375 : 1035403 hits, %0 failures -ReSign|src.c:63377 : 1035403 hits, %0 failures -ReSign|src.c:63416 : 1035403 hits, %0 failures -UnSign|src.c:63436 : 1035403 hits, %0 failures -ReSign|src.c:63436 : 1035403 hits, %0 failures -UnSign|src.c:63477 : 1035403 hits, %1 failures -UnSign|src.c:65084 : 990123 hits, %0 failures -ReSign|src.c:18476 : 983487 hits, %0 failures -UnSign|src.c:104878 : 952092 hits, %0 failures -ReSign|src.c:18631 : 951200 hits, %0 failures -ReSign|src.c:65081 : 940100 hits, %0 failures -UnSign|src.c:107411 : 902598 hits, %0 failures -UnSign|src.c:48491 : 850065 hits, %0 failures -UnSign|src.c:58216 : 800956 hits, %0 failures -UnSign|src.c:104870 : 776776 hits, %0 failures -ReSign|src.c:106658 : 776773 hits, %0 failures -ReSign|src.c:107463 : 751466 hits, %0 failures -ReSign|src.c:18639 : 750974 hits, %0 failures -ReSign|src.c:57991 : 750898 hits, %0 failures -ReSign|src.c:57712 : 750896 hits, %0 failures -UnSign|src.c:57989 : 750895 hits, %1 failures -ReSign|src.c:57989 : 750895 hits, %0 failures -ReSign|src.c:21066 : 750278 hits, %0 failures -ReSign|dlmalloc.c:4240 : 744231 hits, %0 failures -UnSign|src.c:48449 : 735069 hits, %0 failures -UnSign|src.c:21501 : 728920 hits, %0 failures -UnSign|src.c:57991 : 725878 hits, %1 failures -UnSign|src.c:58639 : 700848 hits, %0 failures -ReSign|src.c:60543 : 698979 hits, %0 failures -UnSign|src.c:60545 : 698979 hits, %0 failures -ReSign|src.c:60545 : 698979 hits, %0 failures -UnSign|src.c:60548 : 698979 hits, %0 failures -UnSign|src.c:60577 : 693974 hits, %0 failures -ReSign|src.c:60577 : 693974 hits, %0 failures -ReSign|src.c:60317 : 683799 hits, %0 failures -UnSign|src.c:60317 : 683799 hits, %0 failures -ReSign|src.c:52006 : 678979 hits, %0 failures -ReSign|src.c:52067 : 678979 hits, %0 failures -UnSign|src.c:52032 : 678977 hits, %0 failures -UnSign|src.c:52033 : 678977 hits, %0 failures -ReSign|src.c:52078 : 678977 hits, %0 failures -UnSign|src.c:107277 : 665360 hits, %0 failures -ReSign|src.c:107277 : 665360 hits, %0 failures -ReSign|src.c:20722 : 665360 hits, %0 failures -UnSign|src.c:65082 : 660082 hits, %0 failures -UnSign|src.c:65087 : 660082 hits, %0 failures -UnSign|src.c:20140 : 660000 hits, %0 failures -UnSign|src.c:20141 : 660000 hits, %0 failures -UnSign|src.c:60170 : 655075 hits, %0 failures -UnSign|src.c:56685 : 640140 hits, %0 failures -ReSign|src.c:56685 : 640140 hits, %0 failures -ReSign|src.c:62565 : 630092 hits, %0 failures -UnSign|src.c:48394 : 613809 hits, %0 failures -UnSign|src.c:48398 : 613809 hits, %0 failures -UnSign|src.c:104882 : 601752 hits, %0 failures -ReSign|src.c:62574 : 580020 hits, %0 failures -UnSign|src.c:52949 : 574492 hits, %0 failures -UnSign|src.c:65110 : 560036 hits, %0 failures -UnSign|src.c:60174 : 555027 hits, %0 failures -ReSign|src.c:35705 : 546585 hits, %0 failures -ReSign|src.c:35973 : 543546 hits, %0 failures -UnSign|src.c:60126 : 525078 hits, %0 failures -ReSign|src.c:60129 : 525078 hits, %0 failures -ReSign|src.c:60132 : 525078 hits, %0 failures -UnSign|src.c:48438 : 525063 hits, %0 failures -UnSign|src.c:104877 : 501069 hits, %0 failures -ReSign|src.c:73314 : 500922 hits, %0 failures -ReSign|src.c:58163 : 500579 hits, %0 failures -UnSign|src.c:65266 : 500064 hits, %0 failures -UnSign|src.c:65309 : 500064 hits, %0 failures -UnSign|src.c:65313 : 500064 hits, %0 failures -UnSign|src.c:60447 : 500000 hits, %0 failures -UnSign|src.c:48453 : 490046 hits, %0 failures -ReSign|src.c:106663 : 476264 hits, %0 failures -UnSign|src.c:106514 : 476264 hits, %100 failures -UnSign|src.c:106515 : 476264 hits, %0 failures -UnSign|src.c:106517 : 476264 hits, %0 failures -ReSign|src.c:104942 : 476264 hits, %0 failures -UnSign|src.c:104945 : 476264 hits, %0 failures -UnSign|src.c:104954 : 476264 hits, %0 failures -ReSign|src.c:106518 : 476264 hits, %0 failures -ReSign|src.c:106524 : 476244 hits, %0 failures -ReSign|src.c:18625 : 475798 hits, %0 failures -ReSign|src.c:18627 : 475786 hits, %0 failures -ReSign|src.c:18630 : 475786 hits, %0 failures -UnSign|src.c:18631 : 475600 hits, %0 failures -ReSign|src.c:82818 : 475000 hits, %0 failures -UnSign|src.c:82818 : 475000 hits, %0 failures -ReSign|src.c:65110 : 460036 hits, %0 failures -ReSign|src.c:107411 : 451299 hits, %0 failures -ReSign|src.c:60137 : 450024 hits, %0 failures -ReSign|src.c:60140 : 450024 hits, %0 failures -UnSign|src.c:60147 : 450024 hits, %0 failures -UnSign|src.c:34405 : 429302 hits, %0 failures -ReSign|src.c:58005 : 425545 hits, %0 failures -ReSign|src.c:60312 : 422021 hits, %0 failures -UnSign|src.c:65026 : 420027 hits, %0 failures -UnSign|src.c:48442 : 420012 hits, %0 failures -ReSign|src.c:60266 : 419766 hits, %0 failures -UnSign|src.c:51654 : 415194 hits, %0 failures -ReSign|src.c:51654 : 415194 hits, %0 failures -ReSign|src.c:104896 : 401065 hits, %0 failures -UnSign|src.c:106968 : 400964 hits, %0 failures -ReSign|src.c:104995 : 400841 hits, %0 failures -UnSign|src.c:60322 : 400822 hits, %0 failures -ReSign|src.c:57985 : 400478 hits, %0 failures -ReSign|src.c:18462 : 400410 hits, %0 failures -UnSign|src.c:107315 : 400116 hits, %0 failures -ReSign|src.c:48147 : 400016 hits, %0 failures -ReSign|src.c:60447 : 400000 hits, %0 failures -ReSign|src.c:53661 : 392936 hits, %0 failures -ReSign|src.c:51745 : 389964 hits, %0 failures -ReSign|src.c:48244 : 380058 hits, %0 failures -UnSign|src.c:107153 : 375733 hits, %0 failures -ReSign|src.c:18633 : 375487 hits, %0 failures -UnSign|src.c:57988 : 375448 hits, %1 failures -UnSign|src.c:58005 : 375448 hits, %0 failures -ReSign|src.c:58217 : 375448 hits, %7 failures -ReSign|src.c:48400 : 374580 hits, %0 failures -ReSign|src.c:14805 : 366584 hits, %0 failures -UnSign|src.c:36054 : 364390 hits, %0 failures -ReSign|src.c:34970 : 364390 hits, %0 failures -ReSign|src.c:34989 : 364390 hits, %0 failures -UnSign|src.c:35972 : 364386 hits, %0 failures -ReSign|src.c:41807 : 362867 hits, %0 failures -UnSign|src.c:49129 : 361314 hits, %0 failures -UnSign|src.c:57994 : 350436 hits, %1 failures -ReSign|src.c:57994 : 350436 hits, %0 failures -UnSign|src.c:57996 : 350436 hits, %1 failures -ReSign|src.c:57996 : 350436 hits, %0 failures -ReSign|src.c:59118 : 350374 hits, %0 failures -UnSign|src.c:65311 : 350052 hits, %0 failures -ReSign|src.c:34758 : 343676 hits, %0 failures -ReSign|src.c:65084 : 330041 hits, %0 failures -ReSign|src.c:21492 : 325038 hits, %0 failures -UnSign|src.c:60254 : 325034 hits, %0 failures -ReSign|src.c:12969 : 302946 hits, %0 failures -UnSign|src.c:60568 : 301730 hits, %0 failures -UnSign|src.c:104918 : 300533 hits, %0 failures -ReSign|src.c:106632 : 300529 hits, %0 failures -ReSign|src.c:106647 : 300529 hits, %0 failures -UnSign|src.c:106647 : 300529 hits, %0 failures -ReSign|src.c:107490 : 300491 hits, %0 failures -ReSign|src.c:18781 : 300473 hits, %0 failures -UnSign|src.c:58654 : 300370 hits, %0 failures -ReSign|src.c:58654 : 300370 hits, %0 failures -ReSign|src.c:71511 : 300360 hits, %0 failures -UnSign|src.c:60450 : 300000 hits, %0 failures -ReSign|src.c:52164 : 299700 hits, %0 failures -UnSign|src.c:60148 : 299250 hits, %0 failures -UnSign|src.c:52095 : 297650 hits, %0 failures -ReSign|dlmalloc.c:4816 : 290833 hits, %0 failures -ReSign|src.c:51102 : 286959 hits, %0 failures -ReSign|src.c:64945 : 280054 hits, %0 failures -UnSign|src.c:64981 : 280054 hits, %0 failures -ReSign|src.c:64992 : 280054 hits, %0 failures -UnSign|src.c:65016 : 280018 hits, %0 failures -ReSign|src.c:65056 : 280018 hits, %0 failures -ReSign|src.c:49151 : 277476 hits, %0 failures -UnSign|dlmalloc.c:4746 : 276872 hits, %0 failures -ReSign|src.c:51643 : 276796 hits, %0 failures -UnSign|dlmalloc.c:4776 : 276734 hits, %0 failures -UnSign|src.c:104874 : 275707 hits, %0 failures -ReSign|src.c:73312 : 275374 hits, %0 failures -ReSign|src.c:58656 : 275364 hits, %0 failures -ReSign|src.c:56504 : 275189 hits, %0 failures -ReSign|src.c:51998 : 271404 hits, %0 failures -UnSign|dlmalloc.c:4816 : 265512 hits, %0 failures -ReSign|src.c:18308 : 265362 hits, %0 failures -ReSign|src.c:53012 : 263997 hits, %0 failures -UnSign|src.c:53661 : 261628 hits, %0 failures -ReSign|src.c:71858 : 250490 hits, %0 failures -UnSign|src.c:58958 : 250308 hits, %0 failures -ReSign|src.c:58283 : 250250 hits, %0 failures -ReSign|src.c:56494 : 250226 hits, %0 failures -ReSign|src.c:56452 : 250146 hits, %0 failures -UnSign|src.c:48430 : 245023 hits, %0 failures -ReSign|src.c:48432 : 245023 hits, %0 failures -ReSign|src.c:48453 : 245023 hits, %0 failures -UnSign|src.c:53060 : 243828 hits, %0 failures -UnSign|src.c:62526 : 240010 hits, %0 failures -ReSign|src.c:62526 : 240010 hits, %0 failures -UnSign|src.c:62578 : 240010 hits, %0 failures -ReSign|src.c:62578 : 240010 hits, %0 failures -ReSign|src.c:21148 : 233522 hits, %0 failures -ReSign|dlmalloc.c:4678 : 226376 hits, %0 failures -UnSign|dlmalloc.c:4191 : 226332 hits, %0 failures -ReSign|src.c:69940 : 225884 hits, %0 failures -ReSign|src.c:106972 : 225598 hits, %0 failures -ReSign|src.c:90019 : 225198 hits, %0 failures -ReSign|src.c:85988 : 225048 hits, %0 failures -UnSign|src.c:42240 : 216588 hits, %0 failures -ReSign|src.c:37792 : 216588 hits, %0 failures -UnSign|src.c:42215 : 216588 hits, %0 failures -ReSign|src.c:51833 : 214830 hits, %0 failures -ReSign|src.c:34404 : 214651 hits, %0 failures -ReSign|src.c:42143 : 212714 hits, %0 failures -UnSign|src.c:42145 : 212714 hits, %0 failures -ReSign|src.c:82790 : 210000 hits, %0 failures -ReSign|dlmalloc.c:4778 : 208952 hits, %0 failures -UnSign|src.c:51191 : 205008 hits, %0 failures -ReSign|src.c:51191 : 205008 hits, %0 failures -UnSign|src.c:104879 : 200536 hits, %0 failures -ReSign|src.c:104879 : 200536 hits, %0 failures -UnSign|src.c:107408 : 200534 hits, %0 failures -UnSign|src.c:104895 : 200533 hits, %0 failures -UnSign|src.c:104916 : 200533 hits, %0 failures -UnSign|src.c:104896 : 200532 hits, %0 failures -ReSign|src.c:60322 : 200411 hits, %0 failures -ReSign|src.c:59190 : 200248 hits, %0 failures -ReSign|src.c:72334 : 200194 hits, %0 failures -ReSign|src.c:91875 : 200136 hits, %0 failures -ReSign|src.c:86205 : 200064 hits, %0 failures -ReSign|src.c:107315 : 200058 hits, %0 failures -ReSign|src.c:85709 : 200040 hits, %0 failures -ReSign|src.c:85965 : 200040 hits, %0 failures -ReSign|src.c:48146 : 200018 hits, %0 failures -UnSign|src.c:51212 : 200018 hits, %0 failures -ReSign|src.c:51212 : 200018 hits, %0 failures -ReSign|dlmalloc.c:4215 : 197420 hits, %0 failures -UnSign|dlmalloc.c:4199 : 190700 hits, %43 failures -ReSign|src.c:56535 : 190085 hits, %0 failures -ReSign|src.c:60052 : 190029 hits, %0 failures -ReSign|src.c:60068 : 190029 hits, %0 failures -UnSign|src.c:48239 : 190029 hits, %0 failures -ReSign|src.c:48239 : 190029 hits, %0 failures -ReSign|src.c:48240 : 190029 hits, %0 failures -UnSign|src.c:48244 : 190029 hits, %0 failures -ReSign|src.c:60071 : 190029 hits, %0 failures -ReSign|src.c:60072 : 190029 hits, %0 failures -ReSign|dlmalloc.c:4799 : 186357 hits, %0 failures -ReSign|src.c:35977 : 183718 hits, %0 failures -ReSign|src.c:34904 : 182197 hits, %0 failures -ReSign|src.c:41785 : 182195 hits, %0 failures -ReSign|src.c:41791 : 182195 hits, %0 failures -ReSign|src.c:34916 : 182195 hits, %0 failures -UnSign|src.c:34916 : 182195 hits, %0 failures -ReSign|src.c:34917 : 182195 hits, %0 failures -UnSign|src.c:35971 : 182195 hits, %0 failures -ReSign|src.c:36054 : 182195 hits, %0 failures -ReSign|src.c:36058 : 182195 hits, %0 failures -ReSign|src.c:34921 : 182195 hits, %0 failures -ReSign|src.c:34956 : 182195 hits, %0 failures -ReSign|src.c:34957 : 182195 hits, %0 failures -ReSign|src.c:34974 : 182195 hits, %0 failures -ReSign|src.c:34979 : 182195 hits, %0 failures -ReSign|src.c:41797 : 182195 hits, %0 failures -ReSign|src.c:49080 : 182195 hits, %0 failures -ReSign|src.c:49054 : 182195 hits, %0 failures -ReSign|src.c:41905 : 182195 hits, %0 failures -ReSign|src.c:41718 : 182195 hits, %0 failures -ReSign|src.c:35701 : 182195 hits, %0 failures -ReSign|src.c:48911 : 180663 hits, %0 failures -ReSign|src.c:49133 : 180657 hits, %0 failures -ReSign|src.c:49135 : 180657 hits, %0 failures -UnSign|src.c:48715 : 177520 hits, %0 failures -UnSign|src.c:34992 : 176430 hits, %0 failures -ReSign|src.c:34992 : 176430 hits, %0 failures -UnSign|src.c:53012 : 175998 hits, %0 failures -ReSign|src.c:18596 : 175318 hits, %0 failures -ReSign|src.c:58629 : 175222 hits, %0 failures -ReSign|src.c:56507 : 175111 hits, %0 failures -UnSign|src.c:56452 : 175099 hits, %0 failures -ReSign|src.c:65268 : 175026 hits, %0 failures -ReSign|src.c:65269 : 175026 hits, %0 failures -UnSign|src.c:65271 : 175026 hits, %0 failures -ReSign|src.c:65271 : 175026 hits, %0 failures -UnSign|src.c:65278 : 175026 hits, %0 failures -ReSign|src.c:65278 : 175026 hits, %0 failures -ReSign|src.c:65282 : 175026 hits, %0 failures -UnSign|src.c:21197 : 175023 hits, %0 failures -ReSign|src.c:21199 : 175023 hits, %0 failures -ReSign|src.c:48433 : 175021 hits, %0 failures -ReSign|src.c:48434 : 175021 hits, %0 failures -UnSign|src.c:21206 : 174110 hits, %0 failures -ReSign|src.c:21208 : 174110 hits, %0 failures -ReSign|src.c:34802 : 171875 hits, %0 failures -ReSign|src.c:34794 : 171838 hits, %0 failures -ReSign|src.c:34799 : 171838 hits, %0 failures -ReSign|src.c:34766 : 171838 hits, %0 failures -ReSign|src.c:34772 : 171838 hits, %0 failures -ReSign|src.c:52092 : 171400 hits, %0 failures -UnSign|src.c:51953 : 169341 hits, %0 failures -ReSign|src.c:51953 : 169341 hits, %0 failures -UnSign|src.c:48697 : 162552 hits, %0 failures -UnSign|src.c:48698 : 162552 hits, %0 failures -ReSign|src.c:48699 : 162552 hits, %0 failures -ReSign|src.c:48709 : 162552 hits, %0 failures -UnSign|src.c:53042 : 162552 hits, %0 failures -UnSign|dlmalloc.c:4235 : 161074 hits, %50 failures -UnSign|dlmalloc.c:4236 : 161072 hits, %0 failures -UnSign|dlmalloc.c:4239 : 161072 hits, %0 failures -ReSign|src.c:51566 : 160011 hits, %0 failures -UnSign|src.c:51568 : 160011 hits, %0 failures -ReSign|src.c:51568 : 160011 hits, %0 failures -UnSign|src.c:51573 : 160011 hits, %0 failures -ReSign|src.c:51574 : 160011 hits, %0 failures -ReSign|src.c:51579 : 160011 hits, %0 failures -ReSign|dlmalloc.c:4790 : 159632 hits, %0 failures -ReSign|dlmalloc.c:4225 : 156108 hits, %0 failures -ReSign|src.c:69944 : 150695 hits, %0 failures -UnSign|src.c:107160 : 150564 hits, %0 failures -UnSign|src.c:106972 : 150356 hits, %0 failures -ReSign|src.c:74962 : 150255 hits, %0 failures -ReSign|src.c:71530 : 150220 hits, %0 failures -UnSign|src.c:71864 : 150218 hits, %0 failures -ReSign|src.c:71864 : 150218 hits, %0 failures -ReSign|src.c:47514 : 150204 hits, %0 failures -ReSign|src.c:20644 : 150182 hits, %0 failures -ReSign|src.c:90198 : 150180 hits, %0 failures -ReSign|src.c:80587 : 150144 hits, %0 failures -ReSign|src.c:71202 : 150142 hits, %0 failures -UnSign|src.c:71210 : 150142 hits, %0 failures -ReSign|src.c:86929 : 150132 hits, %0 failures -ReSign|src.c:72233 : 150132 hits, %0 failures -ReSign|src.c:61132 : 150132 hits, %0 failures -ReSign|src.c:77513 : 150120 hits, %0 failures -ReSign|src.c:70643 : 150118 hits, %0 failures -UnSign|src.c:57375 : 150094 hits, %0 failures -UnSign|src.c:57393 : 150094 hits, %0 failures -ReSign|src.c:57393 : 150094 hits, %0 failures -ReSign|src.c:74130 : 150056 hits, %0 failures -ReSign|src.c:86206 : 150052 hits, %0 failures -ReSign|src.c:51743 : 150052 hits, %0 failures -ReSign|src.c:74135 : 150044 hits, %0 failures -ReSign|src.c:85967 : 150032 hits, %0 failures -ReSign|src.c:54323 : 150016 hits, %0 failures -ReSign|src.c:52823 : 150014 hits, %0 failures -ReSign|src.c:65289 : 150012 hits, %0 failures -ReSign|src.c:65293 : 150012 hits, %0 failures -UnSign|src.c:65308 : 150012 hits, %0 failures -ReSign|src.c:52878 : 150012 hits, %0 failures -ReSign|src.c:52890 : 150012 hits, %0 failures -ReSign|src.c:60257 : 150008 hits, %0 failures -ReSign|src.c:64149 : 150000 hits, %0 failures -UnSign|src.c:60444 : 150000 hits, %0 failures -UnSign|src.c:52141 : 149850 hits, %0 failures -ReSign|src.c:52141 : 149850 hits, %0 failures -ReSign|src.c:52142 : 149850 hits, %0 failures -UnSign|src.c:52146 : 149850 hits, %0 failures -ReSign|src.c:52146 : 149850 hits, %0 failures -ReSign|src.c:52150 : 149850 hits, %0 failures -ReSign|src.c:52157 : 149850 hits, %0 failures -ReSign|src.c:52158 : 149850 hits, %0 failures -UnSign|src.c:52158 : 149850 hits, %0 failures -UnSign|src.c:52164 : 149850 hits, %0 failures -ReSign|src.c:67157 : 145009 hits, %0 failures -ReSign|src.c:67161 : 145009 hits, %0 failures -ReSign|src.c:67165 : 145009 hits, %0 failures -UnSign|src.c:67171 : 145009 hits, %0 failures -ReSign|src.c:67171 : 145009 hits, %0 failures -ReSign|src.c:67175 : 145009 hits, %0 failures -ReSign|src.c:67177 : 144999 hits, %0 failures -ReSign|src.c:52190 : 144727 hits, %0 failures -ReSign|src.c:48747 : 143902 hits, %0 failures -UnSign|src.c:56533 : 140047 hits, %0 failures -ReSign|src.c:56533 : 140047 hits, %0 failures -UnSign|src.c:56534 : 140047 hits, %0 failures -UnSign|src.c:64918 : 140027 hits, %0 failures -ReSign|src.c:64939 : 140027 hits, %0 failures -ReSign|src.c:64942 : 140027 hits, %0 failures -ReSign|src.c:64943 : 140027 hits, %0 failures -ReSign|src.c:64976 : 140027 hits, %0 failures -ReSign|src.c:65123 : 140027 hits, %0 failures -ReSign|src.c:65125 : 140027 hits, %0 failures -ReSign|src.c:65152 : 140027 hits, %0 failures -UnSign|src.c:64561 : 140018 hits, %0 failures -UnSign|src.c:64618 : 140018 hits, %0 failures -UnSign|src.c:64619 : 140018 hits, %0 failures -ReSign|src.c:64948 : 140009 hits, %0 failures -ReSign|src.c:65002 : 140009 hits, %0 failures -ReSign|src.c:65005 : 140009 hits, %0 failures -ReSign|src.c:65026 : 140009 hits, %0 failures -UnSign|src.c:65037 : 140009 hits, %0 failures -ReSign|src.c:65064 : 140009 hits, %0 failures -ReSign|src.c:18277 : 138436 hits, %0 failures -UnSign|dlmalloc.c:4621 : 138436 hits, %0 failures -ReSign|src.c:14774 : 138436 hits, %0 failures -ReSign|src.c:18293 : 138436 hits, %0 failures -ReSign|dlmalloc.c:4733 : 138436 hits, %0 failures -ReSign|dlmalloc.c:4746 : 138436 hits, %0 failures -ReSign|dlmalloc.c:4749 : 138436 hits, %0 failures -ReSign|src.c:51636 : 138398 hits, %0 failures -ReSign|src.c:51647 : 138398 hits, %0 failures -ReSign|dlmalloc.c:4776 : 138367 hits, %0 failures -ReSign|dlmalloc.c:4777 : 138367 hits, %0 failures -ReSign|src.c:51982 : 135702 hits, %0 failures -UnSign|src.c:51994 : 135702 hits, %0 failures -ReSign|src.c:51995 : 135702 hits, %0 failures -ReSign|src.c:52090 : 135700 hits, %0 failures -ReSign|src.c:52097 : 135700 hits, %0 failures -ReSign|src.c:21145 : 133506 hits, %0 failures -ReSign|src.c:18317 : 132681 hits, %0 failures -ReSign|src.c:18479 : 132681 hits, %0 failures -ReSign|src.c:54292 : 126028 hits, %0 failures -ReSign|src.c:20617 : 125321 hits, %0 failures -ReSign|src.c:21857 : 125288 hits, %0 failures -ReSign|src.c:21858 : 125283 hits, %0 failures -ReSign|src.c:18733 : 125219 hits, %0 failures -ReSign|src.c:18738 : 125203 hits, %0 failures -ReSign|src.c:58956 : 125170 hits, %0 failures -UnSign|src.c:58283 : 125125 hits, %0 failures -ReSign|src.c:58291 : 125125 hits, %0 failures -ReSign|src.c:58295 : 125125 hits, %0 failures -ReSign|src.c:58297 : 125125 hits, %0 failures -ReSign|src.c:86953 : 125124 hits, %0 failures -ReSign|src.c:56493 : 125113 hits, %0 failures -UnSign|src.c:56507 : 125113 hits, %0 failures -ReSign|src.c:56512 : 125113 hits, %0 failures -UnSign|src.c:56515 : 125113 hits, %0 failures -ReSign|src.c:56518 : 125113 hits, %0 failures -ReSign|src.c:71630 : 125101 hits, %0 failures -ReSign|src.c:104840 : 125090 hits, %0 failures -UnSign|src.c:18463 : 125057 hits, %0 failures -UnSign|src.c:51618 : 125009 hits, %0 failures -ReSign|src.c:51618 : 125009 hits, %0 failures -UnSign|src.c:51581 : 125009 hits, %0 failures -ReSign|src.c:82791 : 120000 hits, %0 failures -ReSign|src.c:82829 : 120000 hits, %0 failures -UnSign|src.c:53662 : 119285 hits, %0 failures -UnSign|src.c:53663 : 119285 hits, %0 failures -UnSign|dlmalloc.c:4684 : 115690 hits, %0 failures -UnSign|dlmalloc.c:4674 : 113210 hits, %0 failures -ReSign|dlmalloc.c:4191 : 113166 hits, %0 failures -ReSign|dlmalloc.c:4192 : 113166 hits, %0 failures -ReSign|dlmalloc.c:4235 : 113166 hits, %0 failures -ReSign|src.c:42135 : 110231 hits, %0 failures -UnSign|src.c:51188 : 110004 hits, %0 failures -ReSign|src.c:51188 : 110004 hits, %0 failures -UnSign|dlmalloc.c:4246 : 109879 hits, %0 failures -ReSign|dlmalloc.c:4801 : 109584 hits, %0 failures -UnSign|src.c:42246 : 108294 hits, %0 failures -ReSign|src.c:42107 : 108294 hits, %0 failures -ReSign|src.c:42111 : 108294 hits, %0 failures -UnSign|src.c:42124 : 108294 hits, %0 failures -ReSign|src.c:42124 : 108294 hits, %0 failures -UnSign|src.c:35034 : 108294 hits, %0 failures -UnSign|src.c:35036 : 108294 hits, %0 failures -ReSign|src.c:35036 : 108294 hits, %0 failures -ReSign|src.c:37580 : 106445 hits, %0 failures -UnSign|src.c:37580 : 106445 hits, %0 failures -ReSign|src.c:42208 : 106357 hits, %0 failures -UnSign|src.c:42194 : 106351 hits, %0 failures -ReSign|src.c:42194 : 106351 hits, %0 failures -UnSign|src.c:42195 : 106351 hits, %0 failures -ReSign|dlmalloc.c:4246 : 104139 hits, %0 failures -ReSign|dlmalloc.c:4206 : 103611 hits, %0 failures -UnSign|src.c:48824 : 103034 hits, %0 failures -UnSign|dlmalloc.c:4240 : 101712 hits, %0 failures -ReSign|src.c:71649 : 100442 hits, %0 failures -UnSign|src.c:106971 : 100379 hits, %0 failures -ReSign|src.c:106971 : 100379 hits, %0 failures -ReSign|src.c:104882 : 100340 hits, %0 failures -ReSign|src.c:18652 : 100311 hits, %0 failures -ReSign|src.c:20763 : 100281 hits, %0 failures -ReSign|src.c:107408 : 100267 hits, %0 failures -ReSign|src.c:106967 : 100267 hits, %0 failures -ReSign|src.c:106968 : 100241 hits, %0 failures -ReSign|src.c:90137 : 100202 hits, %0 failures -ReSign|src.c:90138 : 100202 hits, %0 failures -ReSign|src.c:77634 : 100188 hits, %0 failures -ReSign|src.c:72331 : 100168 hits, %0 failures -ReSign|src.c:18786 : 100159 hits, %0 failures -UnSign|src.c:18781 : 100157 hits, %0 failures -ReSign|src.c:20724 : 100140 hits, %0 failures -ReSign|src.c:107498 : 100136 hits, %0 failures -UnSign|src.c:59190 : 100124 hits, %0 failures -UnSign|src.c:18668 : 100122 hits, %0 failures -ReSign|src.c:18668 : 100122 hits, %0 failures -ReSign|src.c:18669 : 100122 hits, %0 failures -ReSign|src.c:80463 : 100096 hits, %0 failures -ReSign|src.c:80487 : 100096 hits, %0 failures -ReSign|src.c:58302 : 100091 hits, %0 failures -ReSign|src.c:58305 : 100091 hits, %0 failures -ReSign|src.c:58326 : 100091 hits, %0 failures -ReSign|src.c:59709 : 100088 hits, %0 failures -ReSign|src.c:77464 : 100084 hits, %0 failures -ReSign|src.c:58329 : 100081 hits, %0 failures -ReSign|src.c:58334 : 100081 hits, %0 failures -ReSign|src.c:104806 : 100076 hits, %0 failures -UnSign|src.c:104711 : 100076 hits, %0 failures -UnSign|src.c:104817 : 100076 hits, %0 failures -ReSign|src.c:65778 : 100056 hits, %0 failures -ReSign|src.c:21059 : 100048 hits, %0 failures -ReSign|src.c:21062 : 100048 hits, %0 failures -ReSign|src.c:21065 : 100048 hits, %0 failures -UnSign|src.c:60171 : 100048 hits, %0 failures -UnSign|src.c:107322 : 100028 hits, %0 failures -ReSign|src.c:107322 : 100028 hits, %0 failures -UnSign|src.c:107332 : 100028 hits, %0 failures -ReSign|src.c:51067 : 100028 hits, %0 failures -ReSign|src.c:51068 : 100028 hits, %0 failures -ReSign|src.c:21132 : 100016 hits, %0 failures -UnSign|src.c:21146 : 100016 hits, %0 failures -ReSign|src.c:85724 : 100016 hits, %0 failures -ReSign|src.c:60432 : 100000 hits, %0 failures -ReSign|src.c:60450 : 100000 hits, %0 failures -ReSign|src.c:52811 : 100000 hits, %0 failures -ReSign|src.c:48830 : 94673 hits, %0 failures -ReSign|src.c:68079 : 90000 hits, %0 failures -ReSign|src.c:83531 : 90000 hits, %0 failures -ReSign|src.c:48715 : 88760 hits, %0 failures -UnSign|dlmalloc.c:4810 : 88677 hits, %0 failures -ReSign|dlmalloc.c:4818 : 88552 hits, %0 failures -ReSign|src.c:52998 : 87999 hits, %0 failures -ReSign|src.c:53000 : 87999 hits, %0 failures -UnSign|dlmalloc.c:4227 : 85884 hits, %17 failures -UnSign|src.c:52092 : 85700 hits, %0 failures -ReSign|src.c:52103 : 85700 hits, %0 failures -ReSign|src.c:52107 : 85700 hits, %0 failures -ReSign|dlmalloc.c:4201 : 85299 hits, %0 failures -ReSign|src.c:53026 : 81276 hits, %0 failures -UnSign|src.c:53032 : 81276 hits, %0 failures -UnSign|src.c:53033 : 81276 hits, %0 failures -UnSign|src.c:48678 : 81276 hits, %0 failures -UnSign|src.c:48695 : 81276 hits, %0 failures -ReSign|src.c:48704 : 81276 hits, %0 failures -ReSign|src.c:53036 : 81276 hits, %0 failures -ReSign|src.c:53044 : 81276 hits, %0 failures -ReSign|src.c:53062 : 81276 hits, %0 failures -UnSign|dlmalloc.c:4241 : 80536 hits, %0 failures -UnSign|src.c:53476 : 80360 hits, %0 failures -UnSign|src.c:48828 : 80070 hits, %0 failures -UnSign|src.c:48829 : 80070 hits, %0 failures -ReSign|src.c:82833 : 80000 hits, %0 failures -ReSign|src.c:82865 : 80000 hits, %0 failures -ReSign|src.c:82873 : 80000 hits, %0 failures -ReSign|src.c:69964 : 75350 hits, %0 failures -UnSign|src.c:69944 : 75292 hits, %0 failures -ReSign|src.c:69946 : 75292 hits, %0 failures -ReSign|src.c:107160 : 75282 hits, %0 failures -ReSign|src.c:69947 : 75258 hits, %0 failures -UnSign|src.c:69948 : 75258 hits, %0 failures -ReSign|src.c:69948 : 75258 hits, %0 failures -ReSign|src.c:69951 : 75258 hits, %0 failures -ReSign|src.c:107469 : 75242 hits, %0 failures -ReSign|src.c:59645 : 75162 hits, %0 failures -ReSign|src.c:57110 : 75146 hits, %0 failures -ReSign|src.c:71182 : 75118 hits, %0 failures -ReSign|src.c:71629 : 75109 hits, %0 failures -ReSign|src.c:71637 : 75109 hits, %0 failures -ReSign|src.c:71640 : 75109 hits, %0 failures -UnSign|src.c:71568 : 75109 hits, %0 failures -ReSign|src.c:71568 : 75109 hits, %0 failures -ReSign|src.c:71537 : 75109 hits, %0 failures -UnSign|src.c:70483 : 75109 hits, %0 failures -ReSign|src.c:70483 : 75109 hits, %0 failures -UnSign|src.c:70484 : 75109 hits, %0 failures -UnSign|src.c:70494 : 75109 hits, %0 failures -UnSign|src.c:71861 : 75109 hits, %0 failures -ReSign|src.c:71861 : 75109 hits, %0 failures -UnSign|src.c:71867 : 75109 hits, %0 failures -ReSign|src.c:71867 : 75109 hits, %0 failures -UnSign|src.c:71873 : 75109 hits, %0 failures -ReSign|src.c:71873 : 75109 hits, %0 failures -UnSign|src.c:107094 : 75104 hits, %0 failures -ReSign|src.c:71690 : 75101 hits, %0 failures -ReSign|src.c:71695 : 75101 hits, %0 failures -ReSign|src.c:71702 : 75101 hits, %0 failures -ReSign|src.c:71729 : 75101 hits, %0 failures -UnSign|src.c:56896 : 75097 hits, %0 failures -ReSign|src.c:56896 : 75097 hits, %0 failures -UnSign|src.c:56901 : 75097 hits, %0 failures -ReSign|src.c:56901 : 75097 hits, %0 failures -UnSign|src.c:56904 : 75097 hits, %0 failures -ReSign|src.c:71641 : 75091 hits, %0 failures -ReSign|src.c:20646 : 75090 hits, %0 failures -ReSign|src.c:57540 : 75090 hits, %0 failures -ReSign|src.c:77553 : 75090 hits, %0 failures -ReSign|src.c:90255 : 75090 hits, %0 failures -ReSign|src.c:90282 : 75090 hits, %0 failures -ReSign|src.c:73511 : 75086 hits, %0 failures -ReSign|src.c:73516 : 75086 hits, %0 failures -UnSign|src.c:73519 : 75086 hits, %1 failures -ReSign|src.c:77872 : 75084 hits, %0 failures -ReSign|src.c:77871 : 75072 hits, %0 failures -ReSign|src.c:80480 : 75072 hits, %0 failures -ReSign|src.c:51762 : 75072 hits, %0 failures -UnSign|src.c:56585 : 75072 hits, %0 failures -ReSign|src.c:56585 : 75072 hits, %0 failures -ReSign|src.c:71186 : 75071 hits, %0 failures -UnSign|src.c:71192 : 75071 hits, %0 failures -ReSign|src.c:71205 : 75071 hits, %0 failures -ReSign|src.c:71210 : 75071 hits, %0 failures -ReSign|src.c:72226 : 75066 hits, %0 failures -ReSign|src.c:90032 : 75066 hits, %0 failures -ReSign|src.c:71207 : 75064 hits, %0 failures -UnSign|src.c:70643 : 75059 hits, %0 failures -ReSign|src.c:60154 : 75054 hits, %0 failures -ReSign|src.c:60159 : 75054 hits, %0 failures -ReSign|src.c:60163 : 75054 hits, %0 failures -UnSign|src.c:60163 : 75054 hits, %0 failures -ReSign|src.c:57365 : 75047 hits, %0 failures -UnSign|src.c:57371 : 75047 hits, %0 failures -ReSign|src.c:57371 : 75047 hits, %0 failures -UnSign|src.c:57376 : 75047 hits, %0 failures -ReSign|src.c:57376 : 75047 hits, %0 failures -UnSign|src.c:57377 : 75047 hits, %0 failures -ReSign|src.c:57377 : 75047 hits, %0 failures -ReSign|src.c:51782 : 75036 hits, %0 failures -UnSign|src.c:105942 : 75035 hits, %0 failures -ReSign|src.c:58338 : 75035 hits, %0 failures -UnSign|src.c:57378 : 75032 hits, %0 failures -UnSign|src.c:57379 : 75032 hits, %0 failures -ReSign|src.c:57379 : 75032 hits, %0 failures -UnSign|src.c:74130 : 75028 hits, %1 failures -UnSign|src.c:86209 : 75026 hits, %0 failures -ReSign|src.c:86210 : 75026 hits, %0 failures -UnSign|src.c:51735 : 75026 hits, %0 failures -ReSign|src.c:51735 : 75026 hits, %0 failures -UnSign|src.c:51782 : 75026 hits, %0 failures -UnSign|src.c:51789 : 75026 hits, %0 failures -ReSign|src.c:51789 : 75026 hits, %0 failures -ReSign|src.c:85710 : 75016 hits, %0 failures -ReSign|src.c:85975 : 75016 hits, %0 failures -ReSign|src.c:85976 : 75016 hits, %0 failures -ReSign|src.c:85990 : 75016 hits, %0 failures -ReSign|src.c:85992 : 75016 hits, %0 failures -UnSign|src.c:54219 : 75008 hits, %0 failures -ReSign|src.c:54219 : 75008 hits, %0 failures -ReSign|src.c:54238 : 75008 hits, %0 failures -ReSign|src.c:54254 : 75008 hits, %0 failures -ReSign|src.c:54255 : 75008 hits, %0 failures -ReSign|src.c:48184 : 75008 hits, %0 failures -ReSign|src.c:48193 : 75008 hits, %0 failures -ReSign|src.c:54257 : 75008 hits, %0 failures -ReSign|src.c:54261 : 75008 hits, %0 failures -ReSign|src.c:49527 : 75008 hits, %0 failures -ReSign|src.c:54271 : 75008 hits, %0 failures -ReSign|src.c:52790 : 75008 hits, %0 failures -ReSign|src.c:52793 : 75008 hits, %0 failures -ReSign|src.c:52806 : 75008 hits, %0 failures -UnSign|src.c:52818 : 75008 hits, %0 failures -UnSign|src.c:52819 : 75008 hits, %0 failures -UnSign|src.c:52821 : 75008 hits, %0 failures -ReSign|src.c:54273 : 75008 hits, %0 failures -ReSign|src.c:54276 : 75008 hits, %0 failures -UnSign|src.c:54276 : 75008 hits, %0 failures -ReSign|src.c:54277 : 75008 hits, %0 failures -UnSign|src.c:54323 : 75008 hits, %0 failures -UnSign|src.c:65256 : 75006 hits, %0 failures -ReSign|src.c:65302 : 75006 hits, %0 failures -ReSign|src.c:65322 : 75006 hits, %0 failures -ReSign|src.c:52824 : 75006 hits, %0 failures -ReSign|src.c:52889 : 75006 hits, %0 failures -ReSign|src.c:52901 : 75006 hits, %0 failures -ReSign|src.c:51960 : 75006 hits, %0 failures -UnSign|src.c:67177 : 75001 hits, %0 failures -UnSign|src.c:48525 : 73841 hits, %0 failures -UnSign|dlmalloc.c:4799 : 73506 hits, %0 failures -ReSign|dlmalloc.c:4194 : 70273 hits, %0 failures -ReSign|src.c:64561 : 70009 hits, %0 failures -UnSign|src.c:64586 : 70009 hits, %0 failures -ReSign|src.c:64587 : 70009 hits, %0 failures -ReSign|src.c:64590 : 70009 hits, %0 failures -UnSign|src.c:64594 : 70009 hits, %0 failures -ReSign|src.c:64594 : 70009 hits, %0 failures -UnSign|src.c:64595 : 70009 hits, %0 failures -ReSign|src.c:64595 : 70009 hits, %0 failures -UnSign|src.c:64598 : 70009 hits, %0 failures -UnSign|src.c:64607 : 70009 hits, %0 failures -ReSign|src.c:64607 : 70009 hits, %0 failures -ReSign|src.c:64613 : 70009 hits, %0 failures -ReSign|src.c:48442 : 70002 hits, %0 failures -ReSign|src.c:82789 : 70000 hits, %0 failures -UnSign|src.c:82790 : 70000 hits, %0 failures -UnSign|dlmalloc.c:4220 : 69355 hits, %0 failures -UnSign|src.c:52938 : 68892 hits, %0 failures -ReSign|src.c:48717 : 67236 hits, %0 failures -ReSign|dlmalloc.c:4208 : 66565 hits, %0 failures -UnSign|dlmalloc.c:4704 : 65468 hits, %0 failures -ReSign|src.c:53744 : 61694 hits, %0 failures -UnSign|src.c:21223 : 60318 hits, %0 failures -ReSign|src.c:21225 : 60318 hits, %0 failures -ReSign|src.c:57330 : 60006 hits, %0 failures -UnSign|src.c:60149 : 60000 hits, %0 failures -UnSign|src.c:82791 : 60000 hits, %0 failures -ReSign|src.c:48824 : 51517 hits, %0 failures -UnSign|src.c:54292 : 51022 hits, %0 failures -ReSign|src.c:54294 : 51016 hits, %0 failures -UnSign|src.c:54294 : 51016 hits, %0 failures -UnSign|dlmalloc.c:4641 : 50388 hits, %0 failures -ReSign|src.c:20713 : 50165 hits, %0 failures -ReSign|src.c:20715 : 50149 hits, %0 failures -ReSign|src.c:56495 : 50142 hits, %0 failures -ReSign|src.c:77942 : 50140 hits, %0 failures -ReSign|src.c:77636 : 50136 hits, %0 failures -ReSign|src.c:57812 : 50134 hits, %0 failures -ReSign|src.c:21849 : 50112 hits, %0 failures -ReSign|src.c:59750 : 50107 hits, %0 failures -UnSign|src.c:77312 : 50106 hits, %0 failures -ReSign|src.c:77312 : 50106 hits, %0 failures -ReSign|src.c:90136 : 50099 hits, %0 failures -ReSign|src.c:21911 : 50096 hits, %0 failures -ReSign|src.c:21917 : 50096 hits, %0 failures -ReSign|src.c:77635 : 50082 hits, %0 failures -ReSign|src.c:59192 : 50072 hits, %0 failures -ReSign|src.c:107279 : 50070 hits, %0 failures -ReSign|src.c:47516 : 50068 hits, %0 failures -ReSign|src.c:107525 : 50068 hits, %0 failures -UnSign|src.c:59068 : 50064 hits, %0 failures -ReSign|src.c:107515 : 50064 hits, %0 failures -ReSign|src.c:90589 : 50064 hits, %0 failures -ReSign|src.c:90200 : 50060 hits, %0 failures -ReSign|src.c:59105 : 50060 hits, %0 failures -ReSign|src.c:60007 : 50060 hits, %0 failures -ReSign|src.c:77430 : 50060 hits, %0 failures -ReSign|src.c:58109 : 50060 hits, %0 failures -ReSign|src.c:61194 : 50057 hits, %0 failures -ReSign|src.c:61234 : 50057 hits, %0 failures -ReSign|src.c:77639 : 50056 hits, %0 failures -ReSign|src.c:58633 : 50054 hits, %0 failures -ReSign|src.c:21579 : 50052 hits, %0 failures -ReSign|src.c:21584 : 50052 hits, %0 failures -ReSign|src.c:59963 : 50052 hits, %0 failures -ReSign|src.c:59688 : 50052 hits, %0 failures -ReSign|src.c:59180 : 50052 hits, %0 failures -ReSign|src.c:59188 : 50052 hits, %0 failures -ReSign|src.c:59198 : 50052 hits, %0 failures -ReSign|src.c:59201 : 50052 hits, %0 failures -ReSign|src.c:59692 : 50052 hits, %0 failures -ReSign|src.c:65906 : 50052 hits, %0 failures -ReSign|src.c:65935 : 50052 hits, %0 failures -ReSign|src.c:63711 : 50050 hits, %0 failures -ReSign|src.c:90020 : 50048 hits, %0 failures -ReSign|src.c:80483 : 50048 hits, %0 failures -UnSign|src.c:51762 : 50048 hits, %0 failures -UnSign|src.c:90020 : 50044 hits, %0 failures -ReSign|src.c:50178 : 50044 hits, %0 failures -ReSign|src.c:80549 : 50044 hits, %0 failures -ReSign|src.c:93606 : 50044 hits, %0 failures -ReSign|src.c:63522 : 50044 hits, %0 failures -ReSign|src.c:65910 : 50044 hits, %0 failures -ReSign|src.c:61134 : 50044 hits, %0 failures -ReSign|src.c:61136 : 50044 hits, %0 failures -UnSign|src.c:86994 : 50044 hits, %0 failures -ReSign|src.c:90042 : 50044 hits, %0 failures -ReSign|src.c:18704 : 50042 hits, %0 failures -ReSign|src.c:77514 : 50040 hits, %0 failures -ReSign|src.c:77527 : 50040 hits, %0 failures -ReSign|src.c:63604 : 50040 hits, %0 failures -ReSign|src.c:50991 : 50036 hits, %0 failures -ReSign|src.c:80408 : 50028 hits, %0 failures -ReSign|src.c:65647 : 50026 hits, %0 failures -UnSign|src.c:62442 : 50025 hits, %0 failures -ReSign|src.c:62443 : 50025 hits, %0 failures -ReSign|src.c:62446 : 50025 hits, %0 failures -ReSign|src.c:21076 : 50024 hits, %0 failures -ReSign|src.c:21080 : 50024 hits, %0 failures -ReSign|src.c:21083 : 50024 hits, %0 failures -UnSign|src.c:65883 : 50020 hits, %50 failures -ReSign|src.c:65883 : 50020 hits, %0 failures -ReSign|src.c:48000 : 50016 hits, %0 failures -ReSign|src.c:66790 : 50016 hits, %0 failures -ReSign|src.c:51956 : 50016 hits, %0 failures -ReSign|src.c:56690 : 50016 hits, %0 failures -UnSign|src.c:107317 : 50014 hits, %0 failures -ReSign|src.c:107317 : 50014 hits, %0 failures -ReSign|src.c:107332 : 50014 hits, %0 failures -ReSign|src.c:95210 : 50012 hits, %0 failures -ReSign|src.c:81648 : 50012 hits, %0 failures -ReSign|src.c:42912 : 50012 hits, %0 failures -ReSign|src.c:62449 : 50010 hits, %0 failures -ReSign|src.c:62452 : 50010 hits, %0 failures -ReSign|src.c:71631 : 50010 hits, %0 failures -UnSign|src.c:71642 : 50010 hits, %0 failures -UnSign|src.c:73192 : 50010 hits, %0 failures -ReSign|src.c:73192 : 50010 hits, %0 failures -ReSign|src.c:73195 : 50010 hits, %0 failures -ReSign|src.c:51967 : 50008 hits, %0 failures -UnSign|src.c:51973 : 50008 hits, %0 failures -ReSign|src.c:51973 : 50008 hits, %0 failures -ReSign|src.c:85516 : 50008 hits, %0 failures -ReSign|src.c:85575 : 50008 hits, %0 failures -ReSign|src.c:85587 : 50008 hits, %0 failures -ReSign|src.c:85777 : 50008 hits, %0 failures -ReSign|src.c:86542 : 50008 hits, %0 failures -ReSign|src.c:85798 : 50008 hits, %0 failures -ReSign|src.c:86048 : 50008 hits, %0 failures -ReSign|src.c:86061 : 50006 hits, %0 failures -UnSign|src.c:64832 : 50002 hits, %0 failures -ReSign|src.c:64832 : 50002 hits, %0 failures -ReSign|src.c:66984 : 50002 hits, %0 failures -ReSign|src.c:66987 : 50002 hits, %0 failures -ReSign|src.c:66990 : 50002 hits, %0 failures -ReSign|src.c:67000 : 50002 hits, %0 failures -ReSign|src.c:67001 : 50002 hits, %0 failures -UnSign|src.c:64152 : 50000 hits, %0 failures -ReSign|src.c:64152 : 50000 hits, %0 failures -ReSign|src.c:64158 : 50000 hits, %50 failures -ReSign|src.c:57558 : 50000 hits, %0 failures -ReSign|src.c:82923 : 50000 hits, %0 failures -ReSign|src.c:82942 : 50000 hits, %0 failures -ReSign|src.c:82799 : 50000 hits, %0 failures -ReSign|src.c:82804 : 50000 hits, %0 failures -ReSign|src.c:67212 : 50000 hits, %0 failures -UnSign|src.c:67214 : 50000 hits, %0 failures -ReSign|src.c:67214 : 50000 hits, %0 failures -ReSign|src.c:67215 : 50000 hits, %0 failures -UnSign|src.c:67218 : 50000 hits, %0 failures -ReSign|src.c:67218 : 50000 hits, %0 failures -UnSign|src.c:60431 : 50000 hits, %0 failures -UnSign|src.c:60441 : 50000 hits, %0 failures -ReSign|src.c:60444 : 50000 hits, %0 failures -ReSign|src.c:48188 : 50000 hits, %0 failures -UnSign|src.c:60483 : 50000 hits, %0 failures -ReSign|src.c:60483 : 50000 hits, %0 failures -ReSign|dlmalloc.c:4782 : 49320 hits, %0 failures -UnSign|dlmalloc.c:4786 : 49320 hits, %0 failures -ReSign|src.c:53692 : 47066 hits, %0 failures -ReSign|src.c:53772 : 47066 hits, %0 failures -ReSign|src.c:53985 : 47066 hits, %0 failures -UnSign|src.c:51834 : 46608 hits, %0 failures -ReSign|src.c:51835 : 46608 hits, %0 failures -ReSign|dlmalloc.c:4217 : 46500 hits, %0 failures -ReSign|src.c:53547 : 45980 hits, %0 failures -ReSign|src.c:53982 : 45980 hits, %0 failures -ReSign|src.c:53578 : 45950 hits, %0 failures -ReSign|src.c:48807 : 45544 hits, %0 failures -UnSign|src.c:61387 : 45005 hits, %0 failures -ReSign|src.c:61387 : 45005 hits, %0 failures -UnSign|src.c:68074 : 45000 hits, %0 failures -UnSign|src.c:68096 : 45000 hits, %0 failures -ReSign|src.c:68096 : 45000 hits, %0 failures -ReSign|src.c:68103 : 45000 hits, %0 failures -ReSign|src.c:82812 : 45000 hits, %0 failures -ReSign|src.c:82813 : 45000 hits, %0 failures -ReSign|src.c:82814 : 45000 hits, %0 failures -UnSign|src.c:82814 : 45000 hits, %0 failures -ReSign|src.c:82815 : 45000 hits, %0 failures -UnSign|src.c:82815 : 45000 hits, %0 failures -ReSign|src.c:82825 : 45000 hits, %0 failures -ReSign|dlmalloc.c:4763 : 44824 hits, %0 failures -ReSign|dlmalloc.c:4231 : 42942 hits, %0 failures -ReSign|src.c:60718 : 40004 hits, %0 failures -UnSign|src.c:82829 : 40000 hits, %0 failures -UnSign|src.c:82833 : 40000 hits, %0 failures -ReSign|src.c:82869 : 40000 hits, %0 failures -ReSign|src.c:82870 : 40000 hits, %0 failures -UnSign|src.c:82870 : 40000 hits, %0 failures -ReSign|src.c:82871 : 40000 hits, %0 failures -UnSign|src.c:82871 : 40000 hits, %0 failures -UnSign|src.c:48846 : 38640 hits, %0 failures -ReSign|src.c:48846 : 38640 hits, %0 failures -UnSign|src.c:53745 : 37648 hits, %0 failures -UnSign|src.c:49031 : 37516 hits, %0 failures -UnSign|src.c:48807 : 35662 hits, %0 failures -ReSign|src.c:53694 : 35556 hits, %0 failures -ReSign|src.c:53741 : 35556 hits, %0 failures -ReSign|src.c:53787 : 35556 hits, %0 failures -UnSign|src.c:51810 : 35399 hits, %0 failures -ReSign|src.c:48525 : 35191 hits, %0 failures -UnSign|src.c:51609 : 35002 hits, %0 failures -ReSign|src.c:51609 : 35002 hits, %0 failures -UnSign|src.c:51583 : 35002 hits, %0 failures -UnSign|src.c:53458 : 34993 hits, %0 failures -UnSign|src.c:53467 : 34470 hits, %0 failures -UnSign|src.c:53559 : 34470 hits, %0 failures -UnSign|src.c:48720 : 33618 hits, %0 failures -ReSign|src.c:48721 : 33618 hits, %0 failures -ReSign|src.c:51808 : 30375 hits, %0 failures -ReSign|src.c:82797 : 30000 hits, %0 failures -UnSign|src.c:35525 : 29128 hits, %0 failures -UnSign|src.c:52093 : 26170 hits, %0 failures -UnSign|dlmalloc.c:4624 : 25226 hits, %0 failures -UnSign|dlmalloc.c:4626 : 25226 hits, %0 failures -ReSign|dlmalloc.c:4628 : 25226 hits, %0 failures -UnSign|dlmalloc.c:4687 : 25111 hits, %0 failures -ReSign|src.c:57818 : 25067 hits, %0 failures -ReSign|src.c:57833 : 25067 hits, %0 failures -UnSign|src.c:59750 : 25064 hits, %0 failures -ReSign|src.c:49970 : 25062 hits, %0 failures -ReSign|src.c:47763 : 25047 hits, %0 failures -ReSign|src.c:61484 : 25044 hits, %0 failures -UnSign|src.c:61484 : 25044 hits, %0 failures -ReSign|src.c:60853 : 25043 hits, %0 failures -ReSign|src.c:50070 : 25043 hits, %0 failures -UnSign|src.c:49970 : 25043 hits, %0 failures -ReSign|src.c:77316 : 25042 hits, %0 failures -UnSign|src.c:50070 : 25041 hits, %0 failures -ReSign|src.c:58131 : 25041 hits, %0 failures -ReSign|src.c:80842 : 25040 hits, %0 failures -ReSign|src.c:80844 : 25040 hits, %0 failures -ReSign|src.c:80849 : 25040 hits, %0 failures -ReSign|src.c:90057 : 25038 hits, %0 failures -ReSign|src.c:90060 : 25038 hits, %0 failures -ReSign|src.c:59100 : 25038 hits, %0 failures -ReSign|src.c:50994 : 25038 hits, %0 failures -ReSign|src.c:68358 : 25036 hits, %0 failures -UnSign|src.c:62570 : 25036 hits, %0 failures -ReSign|src.c:62570 : 25036 hits, %0 failures -UnSign|src.c:62573 : 25036 hits, %0 failures -ReSign|src.c:72237 : 25035 hits, %0 failures -UnSign|src.c:72241 : 25035 hits, %0 failures -UnSign|src.c:107273 : 25035 hits, %0 failures -UnSign|src.c:107279 : 25035 hits, %0 failures -ReSign|src.c:107286 : 25035 hits, %0 failures -ReSign|src.c:60861 : 25035 hits, %0 failures -ReSign|src.c:61295 : 25035 hits, %0 failures -ReSign|src.c:61159 : 25035 hits, %0 failures -ReSign|src.c:61189 : 25035 hits, %0 failures -ReSign|src.c:61199 : 25035 hits, %0 failures -ReSign|src.c:61221 : 25035 hits, %0 failures -ReSign|src.c:63348 : 25035 hits, %0 failures -ReSign|src.c:63358 : 25035 hits, %0 failures -ReSign|src.c:63361 : 25035 hits, %0 failures -UnSign|src.c:63361 : 25035 hits, %0 failures -ReSign|src.c:61241 : 25035 hits, %0 failures -ReSign|src.c:61250 : 25035 hits, %0 failures -UnSign|src.c:61265 : 25035 hits, %0 failures -ReSign|src.c:61265 : 25035 hits, %0 failures -ReSign|src.c:61300 : 25035 hits, %0 failures -ReSign|src.c:61306 : 25035 hits, %0 failures -ReSign|src.c:86988 : 25035 hits, %0 failures -UnSign|src.c:74947 : 25035 hits, %0 failures -ReSign|src.c:74947 : 25035 hits, %0 failures -ReSign|src.c:97494 : 25034 hits, %0 failures -ReSign|src.c:107439 : 25034 hits, %0 failures -ReSign|src.c:104686 : 25034 hits, %0 failures -ReSign|src.c:107447 : 25034 hits, %0 failures -ReSign|src.c:107457 : 25034 hits, %0 failures -ReSign|src.c:77490 : 25034 hits, %0 failures -ReSign|src.c:77491 : 25034 hits, %0 failures -ReSign|src.c:59068 : 25034 hits, %0 failures -ReSign|src.c:59095 : 25034 hits, %0 failures -ReSign|src.c:104839 : 25034 hits, %0 failures -ReSign|src.c:107512 : 25034 hits, %0 failures -ReSign|src.c:107519 : 25034 hits, %0 failures -UnSign|src.c:107530 : 25034 hits, %0 failures -ReSign|src.c:107530 : 25034 hits, %0 failures -ReSign|src.c:107540 : 25034 hits, %0 failures -ReSign|src.c:95614 : 25034 hits, %0 failures -ReSign|src.c:107549 : 25034 hits, %0 failures -ReSign|src.c:107552 : 25034 hits, %0 failures -ReSign|src.c:107557 : 25034 hits, %0 failures -ReSign|src.c:107562 : 25034 hits, %0 failures -ReSign|src.c:72228 : 25031 hits, %0 failures -ReSign|src.c:90322 : 25030 hits, %0 failures -ReSign|src.c:90166 : 25030 hits, %0 failures -ReSign|src.c:90203 : 25030 hits, %0 failures -ReSign|src.c:90216 : 25030 hits, %0 failures -ReSign|src.c:77492 : 25030 hits, %0 failures -ReSign|src.c:57605 : 25030 hits, %0 failures -ReSign|src.c:57607 : 25030 hits, %0 failures -ReSign|src.c:91878 : 25030 hits, %0 failures -ReSign|src.c:57680 : 25030 hits, %0 failures -ReSign|src.c:57682 : 25030 hits, %0 failures -UnSign|src.c:57683 : 25030 hits, %0 failures -ReSign|src.c:57686 : 25030 hits, %0 failures -ReSign|src.c:57713 : 25030 hits, %0 failures -ReSign|src.c:77500 : 25030 hits, %0 failures -ReSign|src.c:77509 : 25030 hits, %0 failures -ReSign|src.c:77561 : 25030 hits, %0 failures -UnSign|src.c:59069 : 25030 hits, %0 failures -ReSign|src.c:59069 : 25030 hits, %0 failures -ReSign|src.c:59103 : 25030 hits, %0 failures -ReSign|src.c:59110 : 25030 hits, %0 failures -ReSign|src.c:59112 : 25030 hits, %0 failures -ReSign|src.c:59115 : 25030 hits, %0 failures -ReSign|src.c:90239 : 25030 hits, %0 failures -ReSign|src.c:90242 : 25030 hits, %0 failures -ReSign|src.c:90243 : 25030 hits, %0 failures -ReSign|src.c:90246 : 25030 hits, %0 failures -ReSign|src.c:90249 : 25030 hits, %0 failures -UnSign|src.c:90255 : 25030 hits, %0 failures -UnSign|src.c:90278 : 25030 hits, %0 failures -ReSign|src.c:90278 : 25030 hits, %0 failures -UnSign|src.c:90282 : 25030 hits, %0 failures -ReSign|src.c:90289 : 25030 hits, %0 failures -ReSign|src.c:90297 : 25030 hits, %0 failures -ReSign|src.c:90328 : 25030 hits, %0 failures -ReSign|src.c:59698 : 25030 hits, %0 failures -ReSign|src.c:59840 : 25030 hits, %0 failures -ReSign|src.c:59849 : 25030 hits, %0 failures -ReSign|src.c:59857 : 25030 hits, %0 failures -ReSign|src.c:59862 : 25030 hits, %0 failures -ReSign|src.c:59900 : 25030 hits, %0 failures -ReSign|src.c:60022 : 25030 hits, %0 failures -ReSign|src.c:60024 : 25030 hits, %0 failures -ReSign|src.c:60030 : 25030 hits, %0 failures -ReSign|src.c:60000 : 25030 hits, %0 failures -UnSign|src.c:60001 : 25030 hits, %0 failures -ReSign|src.c:60002 : 25030 hits, %0 failures -ReSign|src.c:58214 : 25030 hits, %0 failures -UnSign|src.c:77872 : 25030 hits, %0 failures -ReSign|src.c:58536 : 25030 hits, %0 failures -ReSign|src.c:59132 : 25028 hits, %0 failures -ReSign|src.c:77664 : 25026 hits, %0 failures -ReSign|src.c:77669 : 25026 hits, %0 failures -ReSign|src.c:77424 : 25026 hits, %0 failures -ReSign|src.c:80858 : 25026 hits, %0 failures -ReSign|src.c:65866 : 25026 hits, %0 failures -UnSign|src.c:65880 : 25026 hits, %0 failures -ReSign|src.c:65880 : 25026 hits, %0 failures -ReSign|src.c:65889 : 25026 hits, %0 failures -ReSign|src.c:62492 : 25026 hits, %0 failures -ReSign|src.c:62498 : 25026 hits, %0 failures -ReSign|src.c:62502 : 25026 hits, %0 failures -ReSign|src.c:62507 : 25026 hits, %0 failures -ReSign|src.c:62510 : 25026 hits, %0 failures -ReSign|src.c:65915 : 25026 hits, %0 failures -ReSign|src.c:65926 : 25026 hits, %0 failures -UnSign|src.c:65935 : 25026 hits, %0 failures -ReSign|src.c:65936 : 25026 hits, %0 failures -UnSign|src.c:65936 : 25026 hits, %0 failures -ReSign|src.c:59135 : 25026 hits, %0 failures -ReSign|src.c:59139 : 25026 hits, %0 failures -ReSign|src.c:59143 : 25026 hits, %0 failures -ReSign|src.c:71652 : 25025 hits, %0 failures -UnSign|src.c:63694 : 25025 hits, %0 failures -ReSign|src.c:63694 : 25025 hits, %0 failures -ReSign|src.c:80538 : 25024 hits, %0 failures -ReSign|src.c:80540 : 25024 hits, %0 failures -ReSign|src.c:80543 : 25024 hits, %0 failures -ReSign|src.c:80544 : 25024 hits, %0 failures -ReSign|src.c:80548 : 25024 hits, %0 failures -ReSign|src.c:80552 : 25024 hits, %0 failures -ReSign|src.c:80586 : 25024 hits, %0 failures -ReSign|src.c:51007 : 25024 hits, %0 failures -ReSign|src.c:51751 : 25024 hits, %0 failures -ReSign|src.c:51089 : 25024 hits, %0 failures -ReSign|src.c:51094 : 25024 hits, %0 failures -ReSign|src.c:51099 : 25024 hits, %0 failures -ReSign|src.c:86924 : 25022 hits, %0 failures -ReSign|src.c:86925 : 25022 hits, %0 failures -ReSign|src.c:90014 : 25022 hits, %0 failures -UnSign|src.c:90014 : 25022 hits, %0 failures -ReSign|src.c:77441 : 25022 hits, %0 failures -UnSign|src.c:77467 : 25022 hits, %0 failures -ReSign|src.c:86936 : 25022 hits, %0 failures -ReSign|src.c:86939 : 25022 hits, %0 failures -UnSign|src.c:61194 : 25022 hits, %0 failures -ReSign|src.c:61204 : 25022 hits, %0 failures -ReSign|src.c:61211 : 25022 hits, %0 failures -UnSign|src.c:61217 : 25022 hits, %0 failures -ReSign|src.c:61217 : 25022 hits, %0 failures -ReSign|src.c:68793 : 25022 hits, %0 failures -UnSign|src.c:68358 : 25022 hits, %0 failures -ReSign|src.c:55592 : 25022 hits, %0 failures -ReSign|src.c:68364 : 25022 hits, %0 failures -UnSign|src.c:59709 : 25022 hits, %0 failures -ReSign|src.c:59711 : 25022 hits, %0 failures -ReSign|src.c:59740 : 25022 hits, %0 failures -ReSign|src.c:59802 : 25022 hits, %0 failures -ReSign|src.c:59820 : 25022 hits, %0 failures -ReSign|src.c:59830 : 25022 hits, %0 failures -ReSign|src.c:59842 : 25022 hits, %0 failures -ReSign|src.c:46509 : 25022 hits, %0 failures -ReSign|src.c:61244 : 25022 hits, %0 failures -ReSign|src.c:59901 : 25022 hits, %0 failures -ReSign|src.c:59908 : 25022 hits, %0 failures -ReSign|src.c:59913 : 25022 hits, %0 failures -ReSign|src.c:86991 : 25022 hits, %0 failures -ReSign|src.c:86994 : 25022 hits, %0 failures -ReSign|src.c:87005 : 25022 hits, %0 failures -ReSign|src.c:87009 : 25022 hits, %0 failures -ReSign|src.c:87018 : 25022 hits, %0 failures -UnSign|src.c:90032 : 25022 hits, %0 failures -UnSign|src.c:57816 : 25020 hits, %0 failures -ReSign|src.c:80846 : 25020 hits, %0 failures -ReSign|src.c:80861 : 25020 hits, %0 failures -ReSign|src.c:77516 : 25020 hits, %0 failures -UnSign|src.c:77516 : 25020 hits, %0 failures -UnSign|src.c:77517 : 25020 hits, %0 failures -ReSign|src.c:77517 : 25020 hits, %0 failures -ReSign|src.c:85272 : 25020 hits, %0 failures -ReSign|src.c:65636 : 25020 hits, %0 failures -ReSign|src.c:65638 : 25020 hits, %0 failures -ReSign|src.c:65643 : 25020 hits, %0 failures -ReSign|src.c:63628 : 25020 hits, %0 failures -ReSign|src.c:63633 : 25020 hits, %0 failures -ReSign|src.c:63639 : 25020 hits, %0 failures -ReSign|src.c:63644 : 25020 hits, %0 failures -UnSign|src.c:60377 : 25019 hits, %0 failures -ReSign|src.c:60381 : 25019 hits, %0 failures -ReSign|src.c:56536 : 25019 hits, %0 failures -UnSign|src.c:56541 : 25019 hits, %0 failures -UnSign|src.c:85063 : 25018 hits, %0 failures -ReSign|src.c:85063 : 25018 hits, %0 failures -ReSign|src.c:85066 : 25018 hits, %0 failures -UnSign|src.c:60274 : 25018 hits, %0 failures -UnSign|src.c:60280 : 25018 hits, %0 failures -ReSign|src.c:60280 : 25018 hits, %0 failures -ReSign|src.c:59587 : 25018 hits, %0 failures -ReSign|src.c:57622 : 25016 hits, %0 failures -ReSign|src.c:81638 : 25014 hits, %0 failures -ReSign|src.c:65772 : 25014 hits, %0 failures -ReSign|src.c:80897 : 25010 hits, %0 failures -UnSign|src.c:80900 : 25010 hits, %0 failures -UnSign|src.c:81638 : 25010 hits, %0 failures -UnSign|src.c:50991 : 25010 hits, %0 failures -ReSign|src.c:64600 : 25009 hits, %0 failures -UnSign|src.c:64600 : 25009 hits, %0 failures -ReSign|src.c:81612 : 25008 hits, %0 failures -ReSign|src.c:81615 : 25008 hits, %0 failures -UnSign|src.c:66755 : 25008 hits, %0 failures -ReSign|src.c:66755 : 25008 hits, %0 failures -UnSign|src.c:66766 : 25008 hits, %0 failures -ReSign|src.c:66766 : 25008 hits, %0 failures -UnSign|src.c:66767 : 25008 hits, %0 failures -ReSign|src.c:66767 : 25008 hits, %0 failures -UnSign|src.c:66768 : 25008 hits, %0 failures -ReSign|src.c:66768 : 25008 hits, %0 failures -UnSign|src.c:66774 : 25008 hits, %0 failures -ReSign|src.c:66774 : 25008 hits, %0 failures -UnSign|src.c:66775 : 25008 hits, %0 failures -ReSign|src.c:66775 : 25008 hits, %0 failures -UnSign|src.c:66781 : 25008 hits, %0 failures -UnSign|src.c:48001 : 25008 hits, %0 failures -ReSign|src.c:48001 : 25008 hits, %0 failures -UnSign|src.c:56686 : 25008 hits, %0 failures -ReSign|src.c:56686 : 25008 hits, %0 failures -UnSign|src.c:56690 : 25008 hits, %0 failures -UnSign|src.c:56694 : 25008 hits, %0 failures -ReSign|src.c:56694 : 25008 hits, %0 failures -UnSign|src.c:56696 : 25008 hits, %0 failures -ReSign|src.c:56696 : 25008 hits, %0 failures -ReSign|src.c:95796 : 25006 hits, %0 failures -ReSign|src.c:95206 : 25006 hits, %0 failures -ReSign|src.c:95213 : 25006 hits, %0 failures -ReSign|src.c:95224 : 25006 hits, %0 failures -ReSign|src.c:95800 : 25006 hits, %0 failures -ReSign|src.c:95805 : 25006 hits, %0 failures -ReSign|src.c:95808 : 25006 hits, %0 failures -UnSign|src.c:97840 : 25006 hits, %0 failures -ReSign|src.c:97840 : 25006 hits, %0 failures -ReSign|src.c:79111 : 25006 hits, %0 failures -UnSign|src.c:79114 : 25006 hits, %0 failures -ReSign|src.c:79114 : 25006 hits, %0 failures -ReSign|src.c:79121 : 25006 hits, %0 failures -UnSign|src.c:81637 : 25006 hits, %0 failures -ReSign|src.c:81637 : 25006 hits, %0 failures -ReSign|src.c:86195 : 25006 hits, %0 failures -ReSign|src.c:86251 : 25006 hits, %0 failures -ReSign|src.c:86270 : 25006 hits, %0 failures -ReSign|src.c:86349 : 25006 hits, %0 failures -ReSign|src.c:86445 : 25006 hits, %0 failures -ReSign|src.c:86480 : 25006 hits, %0 failures -ReSign|src.c:86481 : 25006 hits, %0 failures -ReSign|src.c:85142 : 25006 hits, %0 failures -ReSign|src.c:86493 : 25006 hits, %0 failures -ReSign|src.c:86499 : 25006 hits, %0 failures -ReSign|src.c:86502 : 25006 hits, %0 failures -ReSign|src.c:86506 : 25006 hits, %0 failures -UnSign|src.c:65647 : 25006 hits, %0 failures -ReSign|src.c:66565 : 25006 hits, %0 failures -ReSign|src.c:66593 : 25006 hits, %0 failures -ReSign|src.c:66595 : 25006 hits, %0 failures -UnSign|src.c:51880 : 25006 hits, %0 failures -ReSign|src.c:51880 : 25006 hits, %0 failures -ReSign|src.c:51895 : 25006 hits, %0 failures -UnSign|src.c:51896 : 25006 hits, %0 failures -ReSign|src.c:51896 : 25006 hits, %0 failures -ReSign|src.c:66597 : 25006 hits, %0 failures -ReSign|src.c:66600 : 25006 hits, %0 failures -ReSign|src.c:66615 : 25006 hits, %0 failures -ReSign|src.c:66645 : 25006 hits, %0 failures -ReSign|src.c:66647 : 25006 hits, %0 failures -ReSign|src.c:59783 : 25005 hits, %0 failures -ReSign|src.c:59784 : 25005 hits, %0 failures -ReSign|src.c:59804 : 25005 hits, %0 failures -UnSign|src.c:56985 : 25005 hits, %0 failures -ReSign|src.c:56985 : 25005 hits, %0 failures -UnSign|src.c:105905 : 25004 hits, %0 failures -UnSign|src.c:85516 : 25004 hits, %0 failures -ReSign|src.c:85524 : 25004 hits, %0 failures -ReSign|src.c:85526 : 25004 hits, %0 failures -ReSign|src.c:85533 : 25004 hits, %0 failures -ReSign|src.c:85542 : 25004 hits, %0 failures -UnSign|src.c:85542 : 25004 hits, %0 failures -ReSign|src.c:85558 : 25004 hits, %0 failures -ReSign|src.c:85566 : 25004 hits, %0 failures -ReSign|src.c:85573 : 25004 hits, %0 failures -UnSign|src.c:85574 : 25004 hits, %0 failures -ReSign|src.c:85574 : 25004 hits, %0 failures -UnSign|src.c:85575 : 25004 hits, %0 failures -ReSign|src.c:86665 : 25004 hits, %0 failures -UnSign|src.c:85232 : 25004 hits, %0 failures -ReSign|src.c:85232 : 25004 hits, %0 failures -ReSign|src.c:85604 : 25004 hits, %0 failures -ReSign|src.c:85708 : 25004 hits, %0 failures -UnSign|src.c:85719 : 25004 hits, %0 failures -ReSign|src.c:85719 : 25004 hits, %0 failures -ReSign|src.c:85730 : 25004 hits, %0 failures -ReSign|src.c:85746 : 25004 hits, %0 failures -ReSign|src.c:85783 : 25004 hits, %0 failures -ReSign|src.c:85789 : 25004 hits, %0 failures -UnSign|src.c:86530 : 25004 hits, %0 failures -ReSign|src.c:86530 : 25004 hits, %0 failures -ReSign|src.c:86535 : 25004 hits, %0 failures -ReSign|src.c:85795 : 25004 hits, %0 failures -ReSign|src.c:85804 : 25004 hits, %0 failures -ReSign|src.c:85816 : 25004 hits, %0 failures -UnSign|src.c:85835 : 25004 hits, %0 failures -ReSign|src.c:85835 : 25004 hits, %0 failures -ReSign|src.c:85844 : 25004 hits, %0 failures -ReSign|src.c:85916 : 25004 hits, %0 failures -UnSign|src.c:85917 : 25004 hits, %0 failures -ReSign|src.c:85917 : 25004 hits, %0 failures -ReSign|src.c:85921 : 25004 hits, %0 failures -UnSign|src.c:85953 : 25004 hits, %0 failures -ReSign|src.c:85953 : 25004 hits, %0 failures -ReSign|src.c:85301 : 25004 hits, %0 failures -UnSign|src.c:86003 : 25004 hits, %0 failures -ReSign|src.c:86003 : 25004 hits, %0 failures -ReSign|src.c:86013 : 25004 hits, %0 failures -UnSign|src.c:86013 : 25004 hits, %0 failures -UnSign|src.c:84537 : 25004 hits, %0 failures -ReSign|src.c:84543 : 25004 hits, %0 failures -ReSign|src.c:86017 : 25004 hits, %0 failures -UnSign|src.c:86017 : 25004 hits, %0 failures -UnSign|src.c:86500 : 25004 hits, %0 failures -UnSign|src.c:86503 : 25004 hits, %0 failures -ReSign|src.c:86025 : 25004 hits, %0 failures -ReSign|src.c:86029 : 25004 hits, %0 failures -ReSign|src.c:86039 : 25004 hits, %0 failures -ReSign|src.c:86043 : 25004 hits, %0 failures -UnSign|src.c:86048 : 25004 hits, %0 failures -ReSign|src.c:86051 : 25004 hits, %0 failures -UnSign|src.c:86061 : 25004 hits, %0 failures -ReSign|src.c:86070 : 25004 hits, %0 failures -UnSign|src.c:64824 : 25002 hits, %0 failures -ReSign|src.c:64824 : 25002 hits, %0 failures -UnSign|src.c:56796 : 25002 hits, %0 failures -ReSign|src.c:56796 : 25002 hits, %0 failures -UnSign|src.c:56798 : 25002 hits, %0 failures -ReSign|src.c:56798 : 25002 hits, %0 failures -ReSign|src.c:56799 : 25002 hits, %0 failures -UnSign|src.c:64830 : 25002 hits, %0 failures -ReSign|src.c:64834 : 25002 hits, %0 failures -ReSign|src.c:86497 : 25002 hits, %0 failures -UnSign|src.c:86497 : 25002 hits, %0 failures -ReSign|src.c:85319 : 25002 hits, %0 failures -ReSign|src.c:59821 : 25002 hits, %0 failures -ReSign|src.c:51838 : 25002 hits, %0 failures -UnSign|src.c:51839 : 25002 hits, %0 failures -ReSign|src.c:51839 : 25002 hits, %0 failures -ReSign|src.c:51903 : 25002 hits, %0 failures -ReSign|src.c:66606 : 25002 hits, %0 failures -UnSign|src.c:51960 : 25002 hits, %0 failures -ReSign|src.c:64602 : 25000 hits, %0 failures -UnSign|src.c:64602 : 25000 hits, %0 failures -UnSign|src.c:64139 : 25000 hits, %0 failures -UnSign|src.c:64176 : 25000 hits, %0 failures -UnSign|src.c:64179 : 25000 hits, %0 failures -ReSign|src.c:64179 : 25000 hits, %0 failures -UnSign|src.c:57558 : 25000 hits, %0 failures -UnSign|src.c:57559 : 25000 hits, %0 failures -ReSign|src.c:57559 : 25000 hits, %0 failures -ReSign|src.c:82929 : 25000 hits, %0 failures -UnSign|src.c:82804 : 25000 hits, %0 failures -ReSign|src.c:64192 : 25000 hits, %0 failures -ReSign|src.c:64198 : 25000 hits, %0 failures -ReSign|src.c:64209 : 25000 hits, %0 failures -UnSign|src.c:64215 : 25000 hits, %0 failures -ReSign|src.c:64217 : 25000 hits, %0 failures -ReSign|src.c:82826 : 25000 hits, %0 failures -ReSign|src.c:53750 : 24046 hits, %0 failures -UnSign|src.c:53794 : 24046 hits, %0 failures -ReSign|src.c:53470 : 23130 hits, %0 failures -UnSign|src.c:18409 : 23020 hits, %0 failures -UnSign|src.c:52934 : 22964 hits, %0 failures -ReSign|src.c:48813 : 22964 hits, %0 failures -UnSign|src.c:48820 : 22964 hits, %0 failures -UnSign|src.c:52947 : 22964 hits, %0 failures -UnSign|src.c:53590 : 22960 hits, %0 failures -ReSign|src.c:54097 : 21546 hits, %0 failures -ReSign|src.c:67341 : 20002 hits, %0 failures -ReSign|src.c:67347 : 20002 hits, %0 failures -ReSign|src.c:57323 : 20002 hits, %0 failures -UnSign|src.c:57330 : 20002 hits, %0 failures -ReSign|src.c:60724 : 20002 hits, %0 failures -UnSign|src.c:67357 : 20002 hits, %0 failures -ReSign|src.c:67357 : 20002 hits, %0 failures -ReSign|src.c:67363 : 20002 hits, %0 failures -ReSign|src.c:64604 : 20000 hits, %0 failures -UnSign|src.c:64604 : 20000 hits, %0 failures -UnSign|src.c:48876 : 18764 hits, %0 failures -ReSign|src.c:48878 : 18764 hits, %0 failures -ReSign|src.c:49024 : 18758 hits, %0 failures -UnSign|src.c:49027 : 18758 hits, %0 failures -UnSign|src.c:49028 : 18758 hits, %0 failures -ReSign|src.c:49028 : 18758 hits, %0 failures -UnSign|src.c:49029 : 18758 hits, %0 failures -UnSign|src.c:49030 : 18758 hits, %0 failures -UnSign|src.c:49032 : 18758 hits, %0 failures -UnSign|src.c:53086 : 18746 hits, %0 failures -UnSign|src.c:53099 : 18746 hits, %0 failures -UnSign|src.c:53110 : 18746 hits, %0 failures -ReSign|src.c:53651 : 17778 hits, %0 failures -ReSign|src.c:48883 : 17654 hits, %0 failures -ReSign|src.c:53463 : 17235 hits, %0 failures -ReSign|src.c:53468 : 17235 hits, %0 failures -UnSign|src.c:53560 : 17235 hits, %0 failures -ReSign|src.c:53560 : 17235 hits, %0 failures -ReSign|src.c:53699 : 17235 hits, %0 failures -UnSign|src.c:54097 : 16605 hits, %0 failures -ReSign|src.c:48515 : 15866 hits, %0 failures -ReSign|src.c:52180 : 15336 hits, %0 failures -UnSign|src.c:64846 : 15000 hits, %0 failures -ReSign|src.c:64846 : 15000 hits, %0 failures -ReSign|src.c:35492 : 14564 hits, %0 failures -ReSign|src.c:54076 : 13384 hits, %0 failures -ReSign|src.c:54079 : 13384 hits, %0 failures -ReSign|src.c:48808 : 12698 hits, %0 failures -ReSign|src.c:54106 : 12531 hits, %0 failures -UnSign|src.c:53629 : 12023 hits, %0 failures -ReSign|src.c:53631 : 12023 hits, %0 failures -ReSign|src.c:53634 : 12023 hits, %0 failures -ReSign|src.c:53796 : 12023 hits, %0 failures -ReSign|src.c:53832 : 12023 hits, %0 failures -ReSign|src.c:53798 : 11891 hits, %0 failures -UnSign|src.c:53823 : 11891 hits, %0 failures -ReSign|src.c:53823 : 11891 hits, %0 failures -UnSign|src.c:53470 : 11650 hits, %0 failures -UnSign|src.c:53440 : 11510 hits, %0 failures -UnSign|src.c:53455 : 11510 hits, %0 failures -ReSign|src.c:53455 : 11510 hits, %0 failures -ReSign|src.c:53719 : 11510 hits, %0 failures -ReSign|src.c:52926 : 11482 hits, %0 failures -UnSign|src.c:52933 : 11482 hits, %0 failures -UnSign|src.c:52935 : 11482 hits, %0 failures -ReSign|src.c:48788 : 11482 hits, %0 failures -UnSign|src.c:48803 : 11482 hits, %0 failures -ReSign|src.c:52943 : 11482 hits, %0 failures -UnSign|src.c:52959 : 11482 hits, %0 failures -UnSign|src.c:52960 : 11482 hits, %0 failures -UnSign|src.c:53478 : 11480 hits, %0 failures -ReSign|src.c:53492 : 11480 hits, %0 failures -UnSign|src.c:53503 : 11480 hits, %0 failures -UnSign|src.c:53584 : 11480 hits, %0 failures -UnSign|src.c:53587 : 11480 hits, %0 failures -UnSign|src.c:53588 : 11480 hits, %0 failures -ReSign|src.c:53591 : 11480 hits, %0 failures -ReSign|src.c:53448 : 11406 hits, %0 failures -UnSign|src.c:53599 : 11363 hits, %0 failures -ReSign|src.c:53599 : 11363 hits, %0 failures -UnSign|src.c:54106 : 10595 hits, %0 failures -ReSign|src.c:52173 : 10244 hits, %0 failures -UnSign|src.c:52180 : 10224 hits, %0 failures -UnSign|dlmalloc.c:4761 : 10192 hits, %0 failures -ReSign|dlmalloc.c:4762 : 10192 hits, %0 failures -ReSign|src.c:51810 : 10114 hits, %0 failures -ReSign|src.c:48629 : 9520 hits, %0 failures -ReSign|src.c:48641 : 9520 hits, %0 failures -ReSign|src.c:48832 : 9363 hits, %0 failures -ReSign|src.c:48725 : 9325 hits, %0 failures -UnSign|src.c:35773 : 9224 hits, %0 failures -UnSign|src.c:48850 : 7968 hits, %0 failures -ReSign|src.c:34814 : 7645 hits, %0 failures -ReSign|src.c:53847 : 7344 hits, %0 failures -ReSign|src.c:35524 : 7284 hits, %0 failures -ReSign|src.c:35504 : 7282 hits, %0 failures -ReSign|src.c:35509 : 7282 hits, %0 failures -UnSign|src.c:53214 : 6776 hits, %0 failures -ReSign|src.c:54170 : 6729 hits, %0 failures -ReSign|src.c:53013 : 6723 hits, %0 failures -ReSign|src.c:53017 : 6723 hits, %0 failures -UnSign|src.c:53020 : 6723 hits, %0 failures -UnSign|src.c:54101 : 6723 hits, %0 failures -ReSign|src.c:54104 : 6723 hits, %0 failures -UnSign|src.c:54068 : 6655 hits, %0 failures -ReSign|src.c:54172 : 6655 hits, %0 failures -ReSign|src.c:54330 : 6655 hits, %0 failures -UnSign|src.c:48835 : 6242 hits, %0 failures -UnSign|src.c:48836 : 6242 hits, %0 failures -UnSign|src.c:48838 : 6242 hits, %0 failures -ReSign|src.c:35776 : 6133 hits, %0 failures -ReSign|src.c:48730 : 6124 hits, %0 failures -ReSign|src.c:41824 : 6092 hits, %0 failures -ReSign|src.c:51698 : 6090 hits, %0 failures -UnSign|src.c:34416 : 5847 hits, %0 failures -ReSign|src.c:54148 : 5755 hits, %0 failures -UnSign|src.c:54148 : 5755 hits, %0 failures -ReSign|src.c:53425 : 5755 hits, %0 failures -ReSign|src.c:53441 : 5755 hits, %0 failures -ReSign|src.c:18364 : 5755 hits, %0 failures -ReSign|src.c:18372 : 5755 hits, %0 failures -ReSign|src.c:18375 : 5755 hits, %0 failures -ReSign|src.c:53521 : 5755 hits, %0 failures -UnSign|src.c:53545 : 5755 hits, %0 failures -UnSign|src.c:53546 : 5755 hits, %0 failures -UnSign|src.c:53624 : 5755 hits, %0 failures -UnSign|src.c:53687 : 5755 hits, %0 failures -UnSign|src.c:53691 : 5755 hits, %0 failures -ReSign|src.c:53842 : 5755 hits, %0 failures -ReSign|src.c:53868 : 5755 hits, %0 failures -ReSign|src.c:18398 : 5755 hits, %0 failures -ReSign|src.c:18425 : 5755 hits, %0 failures -ReSign|src.c:54149 : 5755 hits, %0 failures -ReSign|src.c:53446 : 5730 hits, %0 failures -UnSign|dlmalloc.c:4763 : 5429 hits, %0 failures -ReSign|src.c:52165 : 5123 hits, %0 failures -ReSign|src.c:52179 : 5112 hits, %0 failures -ReSign|dlmalloc.c:4751 : 5096 hits, %0 failures -ReSign|src.c:52182 : 5058 hits, %0 failures -UnSign|src.c:60604 : 5005 hits, %0 failures -ReSign|src.c:60604 : 5005 hits, %0 failures -ReSign|src.c:128523 : 5001 hits, %0 failures -ReSign|src.c:128524 : 5000 hits, %0 failures -ReSign|src.c:128525 : 5000 hits, %0 failures -ReSign|src.c:128526 : 5000 hits, %0 failures -ReSign|src.c:128527 : 5000 hits, %0 failures -ReSign|src.c:128528 : 5000 hits, %0 failures -UnSign|src.c:53218 : 4892 hits, %0 failures -UnSign|src.c:54944 : 4840 hits, %0 failures -ReSign|src.c:48619 : 4828 hits, %0 failures -UnSign|src.c:48622 : 4760 hits, %0 failures -UnSign|src.c:48848 : 3984 hits, %0 failures -ReSign|src.c:54931 : 3912 hits, %0 failures -UnSign|src.c:35670 : 3594 hits, %0 failures -ReSign|src.c:35673 : 3584 hits, %0 failures -UnSign|src.c:35674 : 3584 hits, %0 failures -UnSign|src.c:20755 : 3429 hits, %0 failures -UnSign|src.c:48832 : 3121 hits, %0 failures -ReSign|src.c:35050 : 3058 hits, %0 failures -ReSign|src.c:38501 : 3054 hits, %0 failures -UnSign|src.c:35777 : 3050 hits, %0 failures -UnSign|src.c:36007 : 3046 hits, %0 failures -UnSign|src.c:36042 : 3046 hits, %0 failures -UnSign|src.c:41830 : 3046 hits, %0 failures -UnSign|src.c:52299 : 3042 hits, %0 failures -UnSign|src.c:52494 : 3042 hits, %0 failures -ReSign|src.c:52494 : 3042 hits, %0 failures -UnSign|src.c:41842 : 3042 hits, %0 failures -UnSign|src.c:48516 : 2910 hits, %0 failures -UnSign|src.c:48634 : 2380 hits, %0 failures -ReSign|src.c:53218 : 2276 hits, %0 failures -ReSign|src.c:20755 : 2101 hits, %0 failures -ReSign|src.c:54925 : 1960 hits, %0 failures -ReSign|src.c:54941 : 1956 hits, %0 failures -UnSign|src.c:54931 : 1956 hits, %0 failures -ReSign|src.c:34405 : 1949 hits, %0 failures -ReSign|src.c:34407 : 1949 hits, %0 failures -UnSign|src.c:34415 : 1949 hits, %0 failures -ReSign|src.c:34416 : 1949 hits, %0 failures -ReSign|src.c:19061 : 1894 hits, %0 failures -ReSign|src.c:54080 : 1720 hits, %0 failures -UnSign|dlmalloc.c:2557 : 1700 hits, %0 failures -ReSign|dlmalloc.c:4026 : 1700 hits, %0 failures -UnSign|dlmalloc.c:4026 : 1700 hits, %0 failures -UnSign|src.c:53847 : 1589 hits, %0 failures -ReSign|src.c:35061 : 1536 hits, %0 failures -UnSign|src.c:35037 : 1529 hits, %0 failures -UnSign|src.c:35047 : 1529 hits, %0 failures -ReSign|src.c:35047 : 1529 hits, %0 failures -UnSign|src.c:35049 : 1529 hits, %0 failures -ReSign|src.c:14658 : 1528 hits, %0 failures -ReSign|src.c:14664 : 1528 hits, %0 failures -ReSign|src.c:35999 : 1523 hits, %0 failures -ReSign|src.c:36012 : 1523 hits, %0 failures -ReSign|src.c:36033 : 1523 hits, %0 failures -ReSign|src.c:36034 : 1523 hits, %0 failures -ReSign|src.c:35573 : 1523 hits, %0 failures -ReSign|src.c:35575 : 1523 hits, %0 failures -ReSign|src.c:36038 : 1523 hits, %0 failures -ReSign|src.c:36041 : 1523 hits, %0 failures -UnSign|src.c:41824 : 1523 hits, %0 failures -UnSign|src.c:41829 : 1523 hits, %0 failures -ReSign|src.c:41829 : 1523 hits, %0 failures -ReSign|src.c:41834 : 1523 hits, %0 failures -ReSign|src.c:35592 : 1523 hits, %0 failures -ReSign|src.c:35594 : 1523 hits, %0 failures -UnSign|src.c:52302 : 1521 hits, %0 failures -ReSign|src.c:52492 : 1521 hits, %0 failures -UnSign|src.c:52497 : 1521 hits, %0 failures -ReSign|src.c:52497 : 1521 hits, %0 failures -ReSign|src.c:52520 : 1521 hits, %0 failures -ReSign|src.c:52522 : 1521 hits, %0 failures -ReSign|src.c:52533 : 1521 hits, %0 failures -ReSign|src.c:35233 : 1521 hits, %0 failures -ReSign|src.c:52534 : 1521 hits, %0 failures -UnSign|src.c:20361 : 1350 hits, %0 failures -ReSign|dlmalloc.c:4024 : 1275 hits, %0 failures -ReSign|src.c:57124 : 1256 hits, %0 failures -UnSign|src.c:20756 : 1140 hits, %0 failures -ReSign|src.c:108432 : 1002 hits, %0 failures -ReSign|src.c:54909 : 990 hits, %0 failures -ReSign|src.c:54900 : 980 hits, %0 failures -ReSign|src.c:54908 : 980 hits, %0 failures -UnSign|src.c:54909 : 980 hits, %0 failures -ReSign|src.c:54923 : 980 hits, %0 failures -ReSign|src.c:54940 : 978 hits, %0 failures -UnSign|src.c:54940 : 978 hits, %0 failures -UnSign|src.c:54941 : 978 hits, %0 failures -ReSign|src.c:48516 : 970 hits, %0 failures -UnSign|src.c:54910 : 970 hits, %0 failures -UnSign|src.c:53165 : 968 hits, %0 failures -ReSign|src.c:53165 : 968 hits, %0 failures -ReSign|src.c:53173 : 968 hits, %0 failures -ReSign|src.c:53194 : 968 hits, %0 failures -UnSign|src.c:53216 : 968 hits, %0 failures -ReSign|src.c:53216 : 968 hits, %0 failures -UnSign|src.c:53221 : 968 hits, %0 failures -UnSign|src.c:53225 : 968 hits, %0 failures -ReSign|src.c:54933 : 968 hits, %0 failures -ReSign|src.c:54934 : 968 hits, %0 failures -ReSign|src.c:19452 : 920 hits, %0 failures -ReSign|src.c:19470 : 920 hits, %0 failures -UnSign|dlmalloc.c:3876 : 852 hits, %0 failures -UnSign|dlmalloc.c:3996 : 852 hits, %0 failures -UnSign|dlmalloc.c:4052 : 852 hits, %0 failures -ReSign|dlmalloc.c:3930 : 850 hits, %0 failures -ReSign|src.c:19451 : 768 hits, %0 failures -UnSign|src.c:53456 : 756 hits, %0 failures -ReSign|src.c:19136 : 645 hits, %0 failures -ReSign|src.c:73426 : 627 hits, %0 failures -ReSign|src.c:73427 : 570 hits, %0 failures -ReSign|src.c:53703 : 543 hits, %0 failures -ReSign|src.c:53708 : 543 hits, %0 failures -ReSign|src.c:19468 : 512 hits, %0 failures -UnSign|src.c:19903 : 512 hits, %0 failures -ReSign|src.c:74966 : 460 hits, %0 failures -ReSign|src.c:20361 : 450 hits, %0 failures -UnSign|src.c:20362 : 444 hits, %0 failures -ReSign|src.c:20362 : 444 hits, %0 failures -ReSign|src.c:19435 : 432 hits, %0 failures -ReSign|dlmalloc.c:3873 : 427 hits, %0 failures -ReSign|dlmalloc.c:3876 : 426 hits, %0 failures -ReSign|dlmalloc.c:3904 : 426 hits, %0 failures -ReSign|dlmalloc.c:3906 : 426 hits, %0 failures -ReSign|dlmalloc.c:3910 : 426 hits, %0 failures -ReSign|dlmalloc.c:3936 : 426 hits, %0 failures -ReSign|dlmalloc.c:3963 : 426 hits, %0 failures -ReSign|dlmalloc.c:3975 : 426 hits, %0 failures -ReSign|dlmalloc.c:3994 : 426 hits, %0 failures -ReSign|dlmalloc.c:3999 : 426 hits, %0 failures -ReSign|dlmalloc.c:3729 : 426 hits, %0 failures -UnSign|dlmalloc.c:3929 : 425 hits, %0 failures -ReSign|src.c:73407 : 397 hits, %0 failures -UnSign|src.c:20763 : 396 hits, %0 failures -ReSign|src.c:73406 : 331 hits, %0 failures -ReSign|src.c:98930 : 304 hits, %0 failures -ReSign|src.c:70225 : 290 hits, %0 failures -UnSign|src.c:19539 : 274 hits, %0 failures -ReSign|src.c:19547 : 274 hits, %0 failures -ReSign|src.c:19550 : 274 hits, %0 failures -ReSign|src.c:19899 : 257 hits, %0 failures -ReSign|src.c:19902 : 257 hits, %0 failures -ReSign|src.c:19903 : 256 hits, %0 failures -UnSign|src.c:19904 : 256 hits, %0 failures -UnSign|src.c:19905 : 256 hits, %0 failures -ReSign|src.c:70196 : 252 hits, %0 failures -ReSign|src.c:74965 : 252 hits, %0 failures -ReSign|src.c:98754 : 240 hits, %0 failures -ReSign|src.c:98755 : 240 hits, %0 failures -ReSign|src.c:19135 : 215 hits, %0 failures -UnSign|src.c:78319 : 208 hits, %0 failures -ReSign|src.c:19056 : 208 hits, %0 failures -ReSign|src.c:78388 : 200 hits, %0 failures -ReSign|dlmalloc.c:4278 : 190 hits, %0 failures -ReSign|src.c:81358 : 187 hits, %0 failures -ReSign|src.c:72361 : 178 hits, %0 failures -ReSign|src.c:81387 : 175 hits, %0 failures -ReSign|src.c:78318 : 168 hits, %0 failures -ReSign|src.c:70191 : 168 hits, %0 failures -ReSign|src.c:81388 : 162 hits, %0 failures -ReSign|src.c:59320 : 153 hits, %0 failures -ReSign|src.c:59352 : 153 hits, %0 failures -ReSign|src.c:59364 : 153 hits, %0 failures -ReSign|src.c:78389 : 148 hits, %0 failures -UnSign|src.c:78389 : 148 hits, %0 failures -ReSign|src.c:78391 : 148 hits, %0 failures -ReSign|src.c:78393 : 144 hits, %0 failures -ReSign|src.c:78395 : 144 hits, %0 failures -ReSign|src.c:19065 : 142 hits, %0 failures -ReSign|src.c:19094 : 138 hits, %0 failures -ReSign|src.c:19539 : 137 hits, %0 failures -ReSign|src.c:19544 : 137 hits, %0 failures -ReSign|src.c:70226 : 137 hits, %0 failures -ReSign|src.c:98793 : 135 hits, %0 failures -UnSign|src.c:81405 : 130 hits, %0 failures -ReSign|src.c:78397 : 128 hits, %0 failures -ReSign|src.c:78401 : 128 hits, %0 failures -ReSign|src.c:78404 : 128 hits, %0 failures -ReSign|src.c:78407 : 128 hits, %0 failures -ReSign|src.c:78411 : 128 hits, %0 failures -ReSign|src.c:71286 : 127 hits, %0 failures -ReSign|dlmalloc.c:4811 : 125 hits, %0 failures -ReSign|src.c:61509 : 125 hits, %0 failures -ReSign|src.c:69965 : 120 hits, %0 failures -ReSign|src.c:70405 : 118 hits, %0 failures -ReSign|src.c:70025 : 112 hits, %0 failures -ReSign|src.c:94265 : 112 hits, %0 failures -ReSign|src.c:78319 : 108 hits, %0 failures -UnSign|src.c:19235 : 106 hits, %0 failures -UnSign|src.c:19236 : 106 hits, %0 failures -ReSign|dlmalloc.c:4668 : 105 hits, %0 failures -ReSign|src.c:91493 : 105 hits, %0 failures -ReSign|src.c:70234 : 102 hits, %0 failures -ReSign|src.c:70235 : 102 hits, %0 failures -ReSign|src.c:98929 : 100 hits, %0 failures -UnSign|src.c:57160 : 98 hits, %0 failures -ReSign|src.c:57169 : 98 hits, %0 failures -UnSign|dlmalloc.c:4262 : 95 hits, %0 failures -ReSign|src.c:96342 : 92 hits, %0 failures -ReSign|dlmalloc.c:4642 : 90 hits, %0 failures -ReSign|src.c:74325 : 90 hits, %0 failures -ReSign|src.c:73375 : 90 hits, %0 failures -UnSign|src.c:72366 : 90 hits, %0 failures -UnSign|src.c:72361 : 88 hits, %0 failures -ReSign|src.c:19138 : 86 hits, %0 failures -ReSign|src.c:80570 : 84 hits, %0 failures -ReSign|src.c:93675 : 84 hits, %0 failures -ReSign|src.c:93740 : 84 hits, %0 failures -ReSign|src.c:70003 : 84 hits, %0 failures -ReSign|src.c:71022 : 84 hits, %0 failures -ReSign|src.c:70265 : 84 hits, %0 failures -ReSign|src.c:70431 : 84 hits, %0 failures -ReSign|src.c:71031 : 84 hits, %0 failures -ReSign|src.c:93928 : 84 hits, %0 failures -ReSign|src.c:102820 : 84 hits, %0 failures -ReSign|src.c:91655 : 84 hits, %0 failures -ReSign|src.c:57140 : 84 hits, %0 failures -ReSign|src.c:91604 : 84 hits, %0 failures -ReSign|src.c:91491 : 84 hits, %0 failures -UnSign|src.c:19918 : 84 hits, %0 failures -ReSign|src.c:19057 : 83 hits, %0 failures -ReSign|src.c:77845 : 80 hits, %0 failures -ReSign|dlmalloc.c:4765 : 79 hits, %0 failures -ReSign|src.c:69966 : 76 hits, %0 failures -ReSign|src.c:71531 : 76 hits, %0 failures -ReSign|src.c:63912 : 76 hits, %0 failures -ReSign|src.c:86971 : 76 hits, %0 failures -UnSign|src.c:98794 : 73 hits, %33 failures -ReSign|src.c:98794 : 73 hits, %0 failures -ReSign|src.c:77699 : 72 hits, %0 failures -ReSign|src.c:71341 : 72 hits, %0 failures -ReSign|src.c:19083 : 71 hits, %0 failures -ReSign|src.c:19086 : 71 hits, %0 failures -ReSign|src.c:19099 : 71 hits, %0 failures -ReSign|src.c:19103 : 71 hits, %0 failures -ReSign|src.c:19120 : 71 hits, %0 failures -ReSign|src.c:19150 : 71 hits, %0 failures -UnSign|src.c:19175 : 71 hits, %0 failures -ReSign|src.c:19511 : 71 hits, %0 failures -ReSign|src.c:19514 : 71 hits, %0 failures -ReSign|src.c:19518 : 71 hits, %0 failures -ReSign|src.c:19521 : 71 hits, %0 failures -ReSign|src.c:19528 : 71 hits, %0 failures -ReSign|src.c:70027 : 70 hits, %0 failures -ReSign|src.c:102926 : 70 hits, %0 failures -ReSign|src.c:102990 : 70 hits, %0 failures -ReSign|src.c:59248 : 70 hits, %0 failures -ReSign|src.c:19596 : 69 hits, %0 failures -ReSign|src.c:19063 : 68 hits, %0 failures -ReSign|src.c:86961 : 68 hits, %0 failures -ReSign|src.c:81487 : 68 hits, %0 failures -UnSign|src.c:48614 : 68 hits, %0 failures -ReSign|src.c:48658 : 68 hits, %0 failures -UnSign|src.c:48750 : 68 hits, %0 failures -ReSign|src.c:61677 : 66 hits, %0 failures -ReSign|src.c:81405 : 65 hits, %0 failures -ReSign|src.c:81407 : 65 hits, %0 failures -ReSign|dlmalloc.c:4634 : 64 hits, %0 failures -ReSign|src.c:78311 : 64 hits, %0 failures -ReSign|src.c:78434 : 64 hits, %0 failures -ReSign|src.c:91666 : 63 hits, %0 failures -ReSign|src.c:91494 : 63 hits, %0 failures -ReSign|src.c:69891 : 62 hits, %0 failures -ReSign|src.c:69776 : 62 hits, %0 failures -ReSign|src.c:74328 : 60 hits, %0 failures -ReSign|src.c:96466 : 60 hits, %0 failures -ReSign|dlmalloc.c:4266 : 58 hits, %0 failures -ReSign|src.c:70317 : 58 hits, %0 failures -UnSign|src.c:99994 : 58 hits, %0 failures -ReSign|src.c:102867 : 56 hits, %0 failures -ReSign|src.c:102928 : 56 hits, %0 failures -ReSign|src.c:103079 : 56 hits, %0 failures -ReSign|src.c:103141 : 56 hits, %0 failures -ReSign|src.c:103273 : 56 hits, %0 failures -ReSign|src.c:102606 : 56 hits, %0 failures -ReSign|src.c:91662 : 56 hits, %0 failures -ReSign|src.c:59276 : 56 hits, %0 failures -UnSign|src.c:59281 : 56 hits, %0 failures -ReSign|src.c:91477 : 56 hits, %0 failures -UnSign|src.c:19915 : 56 hits, %0 failures -UnSign|src.c:19916 : 56 hits, %0 failures -ReSign|src.c:69773 : 56 hits, %0 failures -ReSign|src.c:71374 : 56 hits, %0 failures -ReSign|src.c:81485 : 55 hits, %0 failures -ReSign|src.c:73271 : 55 hits, %0 failures -ReSign|src.c:73272 : 55 hits, %0 failures -UnSign|src.c:52166 : 55 hits, %0 failures -ReSign|src.c:52167 : 55 hits, %0 failures -UnSign|dlmalloc.c:4811 : 54 hits, %0 failures -ReSign|src.c:83823 : 53 hits, %0 failures -UnSign|src.c:19237 : 53 hits, %0 failures -ReSign|src.c:19454 : 52 hits, %0 failures -UnSign|src.c:19454 : 52 hits, %0 failures -ReSign|src.c:38480 : 52 hits, %0 failures -ReSign|src.c:50118 : 51 hits, %0 failures -ReSign|src.c:101217 : 51 hits, %0 failures -ReSign|src.c:98072 : 51 hits, %0 failures -ReSign|src.c:55493 : 51 hits, %0 failures -UnSign|src.c:55493 : 51 hits, %0 failures -ReSign|src.c:81362 : 51 hits, %0 failures -ReSign|src.c:38483 : 50 hits, %0 failures -ReSign|src.c:21745 : 50 hits, %0 failures -ReSign|src.c:81509 : 49 hits, %0 failures -ReSign|src.c:103107 : 49 hits, %0 failures -ReSign|src.c:57115 : 49 hits, %0 failures -UnSign|src.c:57120 : 49 hits, %0 failures -ReSign|src.c:57120 : 49 hits, %0 failures -ReSign|src.c:57121 : 49 hits, %0 failures -UnSign|src.c:57123 : 49 hits, %0 failures -ReSign|src.c:57123 : 49 hits, %0 failures -UnSign|src.c:57128 : 49 hits, %0 failures -ReSign|src.c:57135 : 49 hits, %0 failures -ReSign|src.c:57160 : 49 hits, %0 failures -UnSign|src.c:57161 : 49 hits, %0 failures -ReSign|src.c:57161 : 49 hits, %0 failures -UnSign|src.c:57164 : 49 hits, %0 failures -ReSign|src.c:57164 : 49 hits, %0 failures -ReSign|src.c:77703 : 48 hits, %0 failures -ReSign|src.c:80662 : 48 hits, %0 failures -ReSign|src.c:70669 : 48 hits, %0 failures -ReSign|src.c:108689 : 48 hits, %0 failures -ReSign|src.c:108691 : 48 hits, %0 failures -UnSign|src.c:81455 : 46 hits, %0 failures -ReSign|src.c:98847 : 46 hits, %0 failures -ReSign|src.c:34548 : 45 hits, %0 failures -ReSign|src.c:81481 : 44 hits, %0 failures -UnSign|src.c:98800 : 44 hits, %0 failures -ReSign|src.c:98800 : 44 hits, %0 failures -ReSign|src.c:98810 : 44 hits, %0 failures -ReSign|src.c:128446 : 44 hits, %0 failures -UnSign|src.c:74243 : 43 hits, %0 failures -ReSign|src.c:74194 : 43 hits, %0 failures -ReSign|src.c:74267 : 43 hits, %0 failures -ReSign|src.c:80628 : 42 hits, %0 failures -ReSign|src.c:80635 : 42 hits, %0 failures -ReSign|src.c:94223 : 42 hits, %0 failures -ReSign|src.c:90818 : 42 hits, %0 failures -ReSign|src.c:93860 : 42 hits, %0 failures -ReSign|src.c:70029 : 42 hits, %0 failures -ReSign|src.c:70195 : 42 hits, %0 failures -ReSign|src.c:70205 : 42 hits, %0 failures -ReSign|src.c:70219 : 42 hits, %0 failures -ReSign|src.c:70335 : 42 hits, %0 failures -ReSign|src.c:70360 : 42 hits, %0 failures -ReSign|src.c:70375 : 42 hits, %0 failures -ReSign|src.c:70385 : 42 hits, %0 failures -ReSign|src.c:70421 : 42 hits, %0 failures -ReSign|src.c:70423 : 42 hits, %0 failures -ReSign|src.c:77255 : 42 hits, %0 failures -ReSign|src.c:101191 : 42 hits, %0 failures -ReSign|src.c:103277 : 42 hits, %0 failures -ReSign|src.c:91650 : 42 hits, %0 failures -ReSign|src.c:91667 : 42 hits, %0 failures -UnSign|src.c:57137 : 42 hits, %0 failures -ReSign|src.c:57137 : 42 hits, %0 failures -UnSign|src.c:57138 : 42 hits, %0 failures -ReSign|src.c:57138 : 42 hits, %0 failures -ReSign|src.c:57143 : 42 hits, %0 failures -ReSign|src.c:37880 : 42 hits, %0 failures -ReSign|src.c:50085 : 41 hits, %0 failures -ReSign|src.c:81324 : 40 hits, %0 failures -ReSign|src.c:81273 : 40 hits, %0 failures -ReSign|src.c:81331 : 40 hits, %0 failures -ReSign|src.c:106591 : 40 hits, %0 failures -UnSign|src.c:107211 : 40 hits, %0 failures -ReSign|src.c:85153 : 40 hits, %0 failures -ReSign|src.c:49916 : 39 hits, %0 failures -UnSign|dlmalloc.c:4274 : 38 hits, %0 failures -UnSign|dlmalloc.c:4277 : 38 hits, %0 failures -ReSign|src.c:98734 : 38 hits, %0 failures -ReSign|src.c:74112 : 38 hits, %0 failures -ReSign|src.c:71391 : 38 hits, %0 failures -UnSign|src.c:34802 : 37 hits, %0 failures -ReSign|src.c:102793 : 36 hits, %0 failures -ReSign|src.c:99804 : 36 hits, %0 failures -ReSign|src.c:50655 : 36 hits, %0 failures -UnSign|src.c:71275 : 36 hits, %53 failures -ReSign|src.c:71276 : 36 hits, %0 failures -ReSign|src.c:71281 : 36 hits, %0 failures -ReSign|src.c:38841 : 36 hits, %0 failures -UnSign|src.c:91662 : 35 hits, %40 failures -ReSign|src.c:19931 : 35 hits, %0 failures -UnSign|src.c:81331 : 34 hits, %0 failures -ReSign|src.c:41517 : 34 hits, %0 failures -ReSign|src.c:41519 : 34 hits, %0 failures -ReSign|src.c:50120 : 34 hits, %0 failures -UnSign|src.c:50150 : 34 hits, %0 failures -ReSign|src.c:50150 : 34 hits, %0 failures -ReSign|src.c:70406 : 34 hits, %0 failures -ReSign|src.c:70408 : 34 hits, %0 failures -ReSign|src.c:59322 : 34 hits, %0 failures -ReSign|src.c:59354 : 34 hits, %0 failures -ReSign|src.c:59366 : 34 hits, %0 failures -ReSign|src.c:47906 : 34 hits, %0 failures -UnSign|src.c:38805 : 34 hits, %0 failures -ReSign|src.c:38805 : 34 hits, %0 failures -ReSign|src.c:101402 : 34 hits, %0 failures -UnSign|src.c:81365 : 34 hits, %0 failures -ReSign|src.c:81365 : 34 hits, %0 failures -UnSign|src.c:48609 : 34 hits, %0 failures -UnSign|src.c:48610 : 34 hits, %0 failures -UnSign|src.c:48611 : 34 hits, %0 failures -UnSign|src.c:48658 : 34 hits, %0 failures -ReSign|src.c:48749 : 34 hits, %0 failures -UnSign|dlmalloc.c:3745 : 33 hits, %0 failures -ReSign|src.c:19594 : 33 hits, %0 failures -UnSign|src.c:19596 : 33 hits, %0 failures -ReSign|src.c:108065 : 32 hits, %0 failures -ReSign|src.c:78309 : 32 hits, %0 failures -ReSign|src.c:78317 : 32 hits, %0 failures -ReSign|src.c:78325 : 32 hits, %0 failures -ReSign|src.c:101105 : 32 hits, %0 failures -ReSign|src.c:101400 : 32 hits, %0 failures -ReSign|src.c:96330 : 32 hits, %0 failures -ReSign|src.c:57436 : 32 hits, %0 failures -ReSign|src.c:96338 : 32 hits, %0 failures -ReSign|src.c:73248 : 32 hits, %0 failures -ReSign|src.c:73222 : 32 hits, %0 failures -ReSign|src.c:77432 : 32 hits, %0 failures -ReSign|src.c:71466 : 32 hits, %0 failures -ReSign|src.c:81209 : 32 hits, %0 failures -ReSign|src.c:81216 : 32 hits, %0 failures -ReSign|src.c:63914 : 32 hits, %0 failures -ReSign|src.c:103311 : 32 hits, %0 failures -ReSign|src.c:73537 : 31 hits, %0 failures -ReSign|src.c:73542 : 31 hits, %0 failures -UnSign|src.c:69891 : 31 hits, %0 failures -ReSign|src.c:69775 : 31 hits, %0 failures -ReSign|src.c:69778 : 31 hits, %0 failures -ReSign|dlmalloc.c:4284 : 30 hits, %0 failures -ReSign|src.c:49836 : 30 hits, %0 failures -UnSign|src.c:73378 : 30 hits, %0 failures -ReSign|src.c:73378 : 30 hits, %0 failures -ReSign|src.c:73381 : 30 hits, %0 failures -ReSign|src.c:96467 : 30 hits, %0 failures -ReSign|src.c:98689 : 30 hits, %0 failures -UnSign|src.c:74962 : 30 hits, %0 failures -UnSign|src.c:38842 : 30 hits, %0 failures -ReSign|src.c:98977 : 29 hits, %0 failures -ReSign|src.c:102541 : 29 hits, %0 failures -ReSign|src.c:98651 : 29 hits, %0 failures -ReSign|src.c:99495 : 29 hits, %0 failures -ReSign|src.c:71383 : 29 hits, %0 failures -UnSign|src.c:105736 : 28 hits, %0 failures -ReSign|src.c:72298 : 28 hits, %0 failures -ReSign|src.c:80691 : 28 hits, %0 failures -ReSign|src.c:80693 : 28 hits, %0 failures -ReSign|src.c:93659 : 28 hits, %0 failures -ReSign|src.c:93708 : 28 hits, %0 failures -ReSign|src.c:93726 : 28 hits, %0 failures -UnSign|src.c:93742 : 28 hits, %0 failures -ReSign|src.c:93742 : 28 hits, %0 failures -UnSign|src.c:93745 : 28 hits, %0 failures -ReSign|src.c:93745 : 28 hits, %0 failures -ReSign|src.c:93747 : 28 hits, %0 failures -ReSign|src.c:69979 : 28 hits, %0 failures -ReSign|src.c:69980 : 28 hits, %0 failures -ReSign|src.c:69981 : 28 hits, %0 failures -ReSign|src.c:69982 : 28 hits, %0 failures -ReSign|src.c:69983 : 28 hits, %0 failures -ReSign|src.c:69984 : 28 hits, %0 failures -ReSign|src.c:69985 : 28 hits, %0 failures -ReSign|src.c:70030 : 28 hits, %0 failures -ReSign|src.c:70002 : 28 hits, %0 failures -ReSign|src.c:70004 : 28 hits, %0 failures -ReSign|src.c:70031 : 28 hits, %0 failures -ReSign|src.c:93984 : 28 hits, %0 failures -ReSign|src.c:70997 : 28 hits, %0 failures -ReSign|src.c:71024 : 28 hits, %0 failures -ReSign|src.c:71047 : 28 hits, %0 failures -ReSign|src.c:71086 : 28 hits, %0 failures -ReSign|src.c:93986 : 28 hits, %0 failures -ReSign|src.c:93930 : 28 hits, %0 failures -ReSign|src.c:94242 : 28 hits, %0 failures -UnSign|src.c:94245 : 28 hits, %0 failures -ReSign|src.c:90996 : 28 hits, %0 failures -UnSign|src.c:94312 : 28 hits, %0 failures -ReSign|src.c:74722 : 28 hits, %0 failures -ReSign|src.c:71336 : 28 hits, %0 failures -ReSign|src.c:71339 : 28 hits, %0 failures -ReSign|src.c:81235 : 28 hits, %0 failures -ReSign|src.c:71361 : 28 hits, %0 failures -ReSign|src.c:102742 : 28 hits, %0 failures -ReSign|src.c:102752 : 28 hits, %0 failures -ReSign|src.c:102823 : 28 hits, %0 failures -UnSign|src.c:102933 : 28 hits, %0 failures -ReSign|src.c:102934 : 28 hits, %0 failures -ReSign|src.c:102941 : 28 hits, %0 failures -ReSign|src.c:99989 : 28 hits, %0 failures -ReSign|src.c:103051 : 28 hits, %0 failures -ReSign|src.c:103088 : 28 hits, %0 failures -ReSign|src.c:91039 : 28 hits, %0 failures -ReSign|src.c:91216 : 28 hits, %0 failures -ReSign|src.c:103226 : 28 hits, %0 failures -UnSign|src.c:103277 : 28 hits, %0 failures -ReSign|src.c:98661 : 28 hits, %0 failures -ReSign|src.c:94853 : 28 hits, %0 failures -UnSign|src.c:91650 : 28 hits, %0 failures -ReSign|src.c:91658 : 28 hits, %0 failures -ReSign|src.c:91659 : 28 hits, %0 failures -UnSign|src.c:91479 : 28 hits, %25 failures -ReSign|src.c:91580 : 28 hits, %0 failures -ReSign|src.c:72279 : 28 hits, %0 failures -ReSign|src.c:99503 : 28 hits, %0 failures -UnSign|src.c:37880 : 28 hits, %0 failures -ReSign|src.c:19893 : 28 hits, %0 failures -UnSign|src.c:19914 : 28 hits, %0 failures -UnSign|src.c:19917 : 28 hits, %0 failures -UnSign|src.c:19919 : 28 hits, %0 failures -UnSign|src.c:38195 : 28 hits, %0 failures -UnSign|src.c:38233 : 28 hits, %0 failures -UnSign|dlmalloc.c:4278 : 28 hits, %0 failures -ReSign|src.c:74937 : 28 hits, %0 failures -ReSign|src.c:94483 : 28 hits, %0 failures -ReSign|src.c:103312 : 28 hits, %0 failures -UnSign|src.c:19446 : 26 hits, %0 failures -ReSign|src.c:19446 : 26 hits, %0 failures -ReSign|src.c:19448 : 26 hits, %0 failures -UnSign|src.c:19448 : 26 hits, %0 failures -ReSign|src.c:19449 : 26 hits, %0 failures -ReSign|src.c:19456 : 26 hits, %0 failures -ReSign|src.c:19466 : 26 hits, %0 failures -ReSign|src.c:19472 : 26 hits, %0 failures -ReSign|src.c:103098 : 26 hits, %0 failures -ReSign|src.c:103282 : 26 hits, %0 failures -ReSign|src.c:63828 : 26 hits, %0 failures -UnSign|src.c:49892 : 26 hits, %0 failures -UnSign|src.c:49893 : 26 hits, %0 failures -ReSign|src.c:49901 : 26 hits, %0 failures -ReSign|src.c:81499 : 25 hits, %0 failures -UnSign|src.c:63914 : 25 hits, %0 failures -UnSign|src.c:61509 : 25 hits, %0 failures -ReSign|src.c:61569 : 25 hits, %0 failures -ReSign|src.c:86973 : 25 hits, %0 failures -ReSign|src.c:89699 : 24 hits, %0 failures -ReSign|src.c:77700 : 24 hits, %0 failures -UnSign|src.c:50085 : 24 hits, %0 failures -ReSign|src.c:19429 : 24 hits, %0 failures -UnSign|src.c:19431 : 24 hits, %0 failures -ReSign|src.c:19431 : 24 hits, %0 failures -ReSign|src.c:19434 : 24 hits, %0 failures -ReSign|src.c:70925 : 24 hits, %0 failures -ReSign|src.c:70880 : 24 hits, %0 failures -ReSign|src.c:91250 : 24 hits, %0 failures -UnSign|src.c:71340 : 24 hits, %0 failures -ReSign|src.c:71347 : 24 hits, %0 failures -ReSign|src.c:71348 : 24 hits, %0 failures -ReSign|src.c:99834 : 24 hits, %0 failures -ReSign|src.c:59333 : 24 hits, %0 failures -UnSign|src.c:107349 : 24 hits, %0 failures -ReSign|src.c:96438 : 24 hits, %0 failures -ReSign|src.c:96462 : 24 hits, %0 failures -ReSign|src.c:96692 : 24 hits, %0 failures -ReSign|src.c:57775 : 24 hits, %0 failures -ReSign|src.c:74271 : 24 hits, %0 failures -UnSign|src.c:48933 : 24 hits, %0 failures -UnSign|src.c:48934 : 24 hits, %0 failures -UnSign|src.c:48935 : 24 hits, %0 failures -UnSign|src.c:48974 : 24 hits, %0 failures -ReSign|src.c:77015 : 24 hits, %0 failures -ReSign|src.c:77792 : 24 hits, %0 failures -ReSign|src.c:108704 : 24 hits, %0 failures -ReSign|src.c:18335 : 23 hits, %0 failures -ReSign|src.c:81455 : 23 hits, %0 failures -ReSign|src.c:81460 : 23 hits, %0 failures -ReSign|src.c:94356 : 22 hits, %0 failures -ReSign|src.c:98733 : 22 hits, %0 failures -ReSign|src.c:101265 : 22 hits, %0 failures -ReSign|src.c:101447 : 22 hits, %0 failures -ReSign|src.c:101472 : 22 hits, %0 failures -ReSign|src.c:103104 : 22 hits, %0 failures -UnSign|src.c:74971 : 22 hits, %0 failures -ReSign|src.c:61685 : 22 hits, %0 failures -ReSign|src.c:58152 : 22 hits, %0 failures -ReSign|src.c:94407 : 21 hits, %0 failures -ReSign|src.c:91665 : 21 hits, %0 failures -ReSign|src.c:91671 : 21 hits, %0 failures -ReSign|src.c:91673 : 21 hits, %0 failures -ReSign|src.c:91678 : 21 hits, %0 failures -ReSign|src.c:91681 : 21 hits, %0 failures -ReSign|src.c:91488 : 21 hits, %0 failures -ReSign|src.c:91502 : 21 hits, %0 failures -ReSign|src.c:91524 : 21 hits, %0 failures -ReSign|src.c:91541 : 21 hits, %0 failures -ReSign|src.c:91544 : 21 hits, %0 failures -ReSign|src.c:91546 : 21 hits, %0 failures -ReSign|src.c:91554 : 21 hits, %0 failures -UnSign|src.c:19182 : 21 hits, %0 failures -ReSign|src.c:19182 : 21 hits, %0 failures -ReSign|src.c:19184 : 21 hits, %0 failures -ReSign|src.c:19191 : 21 hits, %0 failures -ReSign|src.c:19200 : 21 hits, %0 failures -ReSign|src.c:19201 : 21 hits, %0 failures -ReSign|src.c:19214 : 21 hits, %0 failures -UnSign|src.c:19215 : 21 hits, %0 failures -ReSign|src.c:19215 : 21 hits, %0 failures -UnSign|src.c:19219 : 21 hits, %0 failures -ReSign|src.c:19219 : 21 hits, %0 failures -UnSign|src.c:19232 : 21 hits, %0 failures -UnSign|src.c:19233 : 21 hits, %0 failures -ReSign|src.c:19240 : 21 hits, %0 failures -ReSign|src.c:19243 : 21 hits, %0 failures -UnSign|src.c:19244 : 21 hits, %0 failures -ReSign|src.c:19244 : 21 hits, %0 failures -ReSign|dlmalloc.c:4076 : 21 hits, %0 failures -ReSign|dlmalloc.c:4113 : 21 hits, %0 failures -ReSign|src.c:74936 : 21 hits, %0 failures -ReSign|src.c:109580 : 20 hits, %0 failures -ReSign|src.c:109583 : 20 hits, %0 failures -ReSign|src.c:78055 : 20 hits, %0 failures -ReSign|src.c:107499 : 20 hits, %0 failures -UnSign|src.c:107299 : 20 hits, %0 failures -ReSign|src.c:107211 : 20 hits, %0 failures -ReSign|src.c:96468 : 20 hits, %0 failures -ReSign|src.c:96476 : 20 hits, %0 failures -ReSign|src.c:96693 : 20 hits, %0 failures -UnSign|dlmalloc.c:4268 : 20 hits, %0 failures -ReSign|src.c:69813 : 20 hits, %0 failures -UnSign|dlmalloc.c:4648 : 20 hits, %0 failures -ReSign|src.c:94007 : 20 hits, %0 failures -ReSign|src.c:94053 : 20 hits, %0 failures -ReSign|src.c:94033 : 20 hits, %0 failures -ReSign|src.c:73359 : 20 hits, %0 failures -UnSign|dlmalloc.c:4279 : 19 hits, %0 failures -UnSign|src.c:50628 : 19 hits, %0 failures -ReSign|src.c:50628 : 19 hits, %0 failures -UnSign|src.c:50711 : 19 hits, %0 failures -ReSign|src.c:50711 : 19 hits, %0 failures -UnSign|src.c:50655 : 19 hits, %0 failures -UnSign|src.c:50666 : 19 hits, %0 failures -ReSign|src.c:50666 : 19 hits, %0 failures -ReSign|src.c:38540 : 19 hits, %0 failures -ReSign|src.c:38544 : 19 hits, %0 failures -ReSign|src.c:38589 : 19 hits, %0 failures -ReSign|src.c:98040 : 19 hits, %0 failures -UnSign|src.c:98734 : 19 hits, %0 failures -UnSign|src.c:19597 : 18 hits, %0 failures -ReSign|src.c:19597 : 18 hits, %0 failures -ReSign|src.c:19602 : 18 hits, %0 failures -ReSign|src.c:19654 : 18 hits, %0 failures -ReSign|src.c:70671 : 18 hits, %0 failures -ReSign|src.c:101194 : 18 hits, %0 failures -ReSign|src.c:101247 : 18 hits, %0 failures -ReSign|src.c:99813 : 18 hits, %0 failures -UnSign|src.c:101285 : 18 hits, %0 failures -ReSign|src.c:101286 : 18 hits, %0 failures -ReSign|src.c:101311 : 18 hits, %0 failures -ReSign|src.c:101327 : 18 hits, %0 failures -ReSign|src.c:101371 : 18 hits, %0 failures -ReSign|src.c:101460 : 18 hits, %0 failures -ReSign|src.c:103233 : 18 hits, %0 failures -UnSign|src.c:106038 : 18 hits, %0 failures -UnSign|src.c:71697 : 18 hits, %0 failures -ReSign|src.c:71697 : 18 hits, %0 failures -UnSign|src.c:71704 : 18 hits, %0 failures -ReSign|src.c:71704 : 18 hits, %0 failures -ReSign|src.c:72320 : 18 hits, %0 failures -ReSign|src.c:98935 : 18 hits, %0 failures -UnSign|src.c:71440 : 18 hits, %0 failures -UnSign|src.c:57259 : 18 hits, %0 failures -ReSign|src.c:57259 : 18 hits, %0 failures -ReSign|src.c:108529 : 18 hits, %0 failures -UnSign|src.c:36146 : 18 hits, %0 failures -ReSign|src.c:78636 : 18 hits, %0 failures -ReSign|src.c:108705 : 18 hits, %0 failures -UnSign|src.c:50075 : 17 hits, %0 failures -ReSign|src.c:50075 : 17 hits, %0 failures -ReSign|src.c:50087 : 17 hits, %0 failures -ReSign|src.c:50096 : 17 hits, %0 failures -ReSign|src.c:50107 : 17 hits, %0 failures -ReSign|src.c:50109 : 17 hits, %0 failures -UnSign|src.c:50109 : 17 hits, %0 failures -UnSign|src.c:41517 : 17 hits, %0 failures -UnSign|src.c:41519 : 17 hits, %0 failures -ReSign|src.c:41689 : 17 hits, %0 failures -UnSign|src.c:41694 : 17 hits, %0 failures -ReSign|src.c:41694 : 17 hits, %0 failures -ReSign|src.c:41699 : 17 hits, %0 failures -ReSign|src.c:49827 : 17 hits, %0 failures -ReSign|src.c:49829 : 17 hits, %0 failures -ReSign|src.c:49839 : 17 hits, %0 failures -UnSign|src.c:49944 : 17 hits, %0 failures -UnSign|src.c:49945 : 17 hits, %0 failures -UnSign|src.c:49947 : 17 hits, %0 failures -ReSign|src.c:50131 : 17 hits, %0 failures -ReSign|src.c:50134 : 17 hits, %0 failures -ReSign|src.c:50137 : 17 hits, %0 failures -UnSign|src.c:50138 : 17 hits, %0 failures -ReSign|src.c:50138 : 17 hits, %0 failures -ReSign|src.c:50141 : 17 hits, %0 failures -ReSign|src.c:50149 : 17 hits, %0 failures -ReSign|src.c:50153 : 17 hits, %0 failures -ReSign|src.c:59754 : 17 hits, %0 failures -ReSign|src.c:59756 : 17 hits, %0 failures -ReSign|src.c:59328 : 17 hits, %0 failures -ReSign|src.c:59349 : 17 hits, %0 failures -UnSign|src.c:50718 : 17 hits, %0 failures -ReSign|src.c:50718 : 17 hits, %0 failures -ReSign|src.c:47890 : 17 hits, %0 failures -ReSign|src.c:50669 : 17 hits, %0 failures -UnSign|src.c:38807 : 17 hits, %0 failures -ReSign|src.c:38807 : 17 hits, %0 failures -ReSign|src.c:38811 : 17 hits, %0 failures -ReSign|src.c:59370 : 17 hits, %0 failures -ReSign|src.c:59769 : 17 hits, %0 failures -ReSign|src.c:59772 : 17 hits, %0 failures -ReSign|src.c:83704 : 17 hits, %0 failures -ReSign|src.c:101550 : 17 hits, %0 failures -UnSign|src.c:101401 : 17 hits, %0 failures -ReSign|src.c:101401 : 17 hits, %0 failures -UnSign|src.c:101403 : 17 hits, %0 failures -ReSign|src.c:101403 : 17 hits, %0 failures -ReSign|src.c:74534 : 17 hits, %0 failures -ReSign|src.c:74535 : 17 hits, %0 failures -ReSign|src.c:71291 : 17 hits, %0 failures -ReSign|src.c:71292 : 17 hits, %0 failures -ReSign|src.c:21942 : 16 hits, %0 failures -ReSign|src.c:21948 : 16 hits, %0 failures -ReSign|src.c:21959 : 16 hits, %0 failures -ReSign|src.c:108976 : 16 hits, %0 failures -ReSign|src.c:78135 : 16 hits, %0 failures -ReSign|src.c:78151 : 16 hits, %0 failures -ReSign|src.c:78205 : 16 hits, %0 failures -ReSign|src.c:78824 : 16 hits, %0 failures -ReSign|src.c:80663 : 16 hits, %0 failures -ReSign|src.c:80665 : 16 hits, %0 failures -ReSign|src.c:103058 : 16 hits, %0 failures -ReSign|src.c:103068 : 16 hits, %0 failures -ReSign|src.c:101969 : 16 hits, %0 failures -UnSign|src.c:101969 : 16 hits, %0 failures -ReSign|src.c:103285 : 16 hits, %0 failures -ReSign|src.c:103303 : 16 hits, %0 failures -UnSign|src.c:71463 : 16 hits, %0 failures -ReSign|src.c:71463 : 16 hits, %0 failures -UnSign|src.c:71466 : 16 hits, %0 failures -ReSign|src.c:81206 : 16 hits, %0 failures -ReSign|src.c:81239 : 16 hits, %0 failures -ReSign|src.c:71471 : 16 hits, %0 failures -ReSign|src.c:74994 : 16 hits, %0 failures -ReSign|src.c:79930 : 16 hits, %0 failures -ReSign|src.c:79991 : 16 hits, %0 failures -ReSign|src.c:80246 : 16 hits, %0 failures -ReSign|src.c:81099 : 16 hits, %0 failures -ReSign|src.c:85110 : 16 hits, %0 failures -ReSign|src.c:18584 : 15 hits, %0 failures -UnSign|src.c:101217 : 15 hits, %0 failures -ReSign|src.c:101219 : 15 hits, %0 failures -ReSign|src.c:99464 : 15 hits, %0 failures -UnSign|src.c:99471 : 15 hits, %0 failures -ReSign|src.c:99472 : 15 hits, %0 failures -ReSign|src.c:99479 : 15 hits, %0 failures -UnSign|src.c:99485 : 15 hits, %0 failures -ReSign|src.c:99485 : 15 hits, %0 failures -UnSign|src.c:98847 : 15 hits, %0 failures -UnSign|src.c:99595 : 15 hits, %0 failures -ReSign|src.c:99595 : 15 hits, %0 failures -UnSign|src.c:83704 : 15 hits, %0 failures -ReSign|src.c:99008 : 15 hits, %0 failures -ReSign|src.c:99596 : 15 hits, %0 failures -UnSign|src.c:99091 : 15 hits, %0 failures -ReSign|src.c:99091 : 15 hits, %0 failures -ReSign|src.c:99655 : 15 hits, %0 failures -UnSign|src.c:98930 : 15 hits, %0 failures -UnSign|src.c:99995 : 15 hits, %0 failures -ReSign|src.c:99995 : 15 hits, %0 failures -UnSign|src.c:102545 : 15 hits, %0 failures -ReSign|src.c:102545 : 15 hits, %0 failures -UnSign|src.c:98652 : 15 hits, %0 failures -ReSign|src.c:98652 : 15 hits, %0 failures -UnSign|src.c:98655 : 15 hits, %0 failures -ReSign|src.c:98655 : 15 hits, %0 failures -UnSign|src.c:98657 : 15 hits, %0 failures -ReSign|src.c:98657 : 15 hits, %0 failures -UnSign|src.c:57388 : 15 hits, %0 failures -UnSign|src.c:56612 : 15 hits, %0 failures -ReSign|src.c:56623 : 15 hits, %0 failures -ReSign|src.c:56633 : 15 hits, %0 failures -ReSign|src.c:19740 : 15 hits, %0 failures -ReSign|src.c:19122 : 15 hits, %0 failures -ReSign|src.c:19123 : 15 hits, %0 failures -ReSign|src.c:19125 : 15 hits, %0 failures -UnSign|src.c:19138 : 15 hits, %0 failures -UnSign|src.c:56641 : 15 hits, %0 failures -ReSign|src.c:14306 : 15 hits, %0 failures -ReSign|src.c:70589 : 15 hits, %0 failures -ReSign|src.c:93581 : 15 hits, %0 failures -ReSign|src.c:18720 : 15 hits, %0 failures -ReSign|src.c:18726 : 15 hits, %0 failures -ReSign|src.c:109592 : 14 hits, %0 failures -ReSign|src.c:21961 : 14 hits, %0 failures -UnSign|src.c:21966 : 14 hits, %0 failures -ReSign|src.c:21972 : 14 hits, %0 failures -ReSign|src.c:21776 : 14 hits, %0 failures -ReSign|src.c:21783 : 14 hits, %0 failures -ReSign|src.c:21791 : 14 hits, %0 failures -ReSign|src.c:80638 : 14 hits, %0 failures -ReSign|src.c:80640 : 14 hits, %0 failures -ReSign|src.c:90556 : 14 hits, %0 failures -ReSign|src.c:90560 : 14 hits, %0 failures -ReSign|src.c:90569 : 14 hits, %0 failures -ReSign|src.c:90577 : 14 hits, %0 failures -UnSign|src.c:94223 : 14 hits, %0 failures -ReSign|src.c:94226 : 14 hits, %0 failures -UnSign|src.c:94229 : 14 hits, %0 failures -ReSign|src.c:94229 : 14 hits, %0 failures -ReSign|src.c:93980 : 14 hits, %0 failures -UnSign|src.c:93982 : 14 hits, %0 failures -ReSign|src.c:93982 : 14 hits, %0 failures -ReSign|src.c:93656 : 14 hits, %0 failures -UnSign|src.c:93659 : 14 hits, %0 failures -UnSign|src.c:93662 : 14 hits, %0 failures -ReSign|src.c:80569 : 14 hits, %0 failures -ReSign|src.c:80571 : 14 hits, %0 failures -ReSign|src.c:80573 : 14 hits, %0 failures -ReSign|src.c:93677 : 14 hits, %0 failures -ReSign|src.c:93683 : 14 hits, %0 failures -ReSign|src.c:93705 : 14 hits, %0 failures -UnSign|src.c:93708 : 14 hits, %0 failures -ReSign|src.c:93719 : 14 hits, %0 failures -UnSign|src.c:93726 : 14 hits, %0 failures -UnSign|src.c:93984 : 14 hits, %0 failures -UnSign|src.c:70974 : 14 hits, %0 failures -ReSign|src.c:70974 : 14 hits, %0 failures -UnSign|src.c:70989 : 14 hits, %0 failures -ReSign|src.c:70989 : 14 hits, %0 failures -ReSign|src.c:70994 : 14 hits, %0 failures -UnSign|src.c:70994 : 14 hits, %0 failures -UnSign|src.c:71000 : 14 hits, %0 failures -ReSign|src.c:71007 : 14 hits, %0 failures -ReSign|src.c:71008 : 14 hits, %0 failures -ReSign|src.c:71033 : 14 hits, %0 failures -UnSign|src.c:71047 : 14 hits, %0 failures -ReSign|src.c:71055 : 14 hits, %0 failures -ReSign|src.c:71069 : 14 hits, %0 failures -ReSign|src.c:71070 : 14 hits, %0 failures -ReSign|src.c:70922 : 14 hits, %0 failures -ReSign|src.c:71089 : 14 hits, %0 failures -ReSign|src.c:71096 : 14 hits, %0 failures -ReSign|src.c:71120 : 14 hits, %0 failures -UnSign|src.c:93986 : 14 hits, %0 failures -UnSign|src.c:93924 : 14 hits, %0 failures -ReSign|src.c:93924 : 14 hits, %0 failures -UnSign|src.c:93925 : 14 hits, %0 failures -UnSign|src.c:93930 : 14 hits, %0 failures -UnSign|src.c:94242 : 14 hits, %0 failures -ReSign|src.c:94245 : 14 hits, %0 failures -ReSign|src.c:94251 : 14 hits, %0 failures -UnSign|src.c:90995 : 14 hits, %0 failures -ReSign|src.c:94257 : 14 hits, %0 failures -ReSign|src.c:94271 : 14 hits, %0 failures -ReSign|src.c:94312 : 14 hits, %0 failures -ReSign|src.c:94317 : 14 hits, %0 failures -UnSign|src.c:94343 : 14 hits, %0 failures -ReSign|src.c:94343 : 14 hits, %0 failures -ReSign|src.c:94368 : 14 hits, %0 failures -UnSign|src.c:94382 : 14 hits, %0 failures -ReSign|src.c:94382 : 14 hits, %0 failures -ReSign|src.c:91910 : 14 hits, %0 failures -ReSign|src.c:91920 : 14 hits, %0 failures -UnSign|src.c:94394 : 14 hits, %0 failures -ReSign|src.c:94394 : 14 hits, %0 failures -UnSign|src.c:102752 : 14 hits, %0 failures -ReSign|src.c:102768 : 14 hits, %0 failures -ReSign|src.c:74298 : 14 hits, %0 failures -UnSign|src.c:102823 : 14 hits, %0 failures -ReSign|src.c:102845 : 14 hits, %0 failures -UnSign|src.c:102926 : 14 hits, %0 failures -ReSign|src.c:102933 : 14 hits, %0 failures -ReSign|src.c:102936 : 14 hits, %0 failures -ReSign|src.c:102940 : 14 hits, %0 failures -ReSign|src.c:102942 : 14 hits, %0 failures -UnSign|src.c:102948 : 14 hits, %0 failures -ReSign|src.c:102948 : 14 hits, %0 failures -UnSign|src.c:101064 : 14 hits, %0 failures -ReSign|src.c:101064 : 14 hits, %0 failures -ReSign|src.c:101070 : 14 hits, %0 failures -UnSign|src.c:101090 : 14 hits, %0 failures -ReSign|src.c:101090 : 14 hits, %0 failures -UnSign|src.c:99989 : 14 hits, %0 failures -ReSign|src.c:100100 : 14 hits, %0 failures -ReSign|src.c:100104 : 14 hits, %0 failures -ReSign|src.c:102966 : 14 hits, %0 failures -ReSign|src.c:103006 : 14 hits, %0 failures -ReSign|src.c:103014 : 14 hits, %0 failures -ReSign|src.c:103021 : 14 hits, %0 failures -ReSign|src.c:103038 : 14 hits, %0 failures -UnSign|src.c:103051 : 14 hits, %0 failures -UnSign|src.c:103068 : 14 hits, %0 failures -UnSign|src.c:103083 : 14 hits, %0 failures -UnSign|src.c:103088 : 14 hits, %0 failures -ReSign|src.c:103092 : 14 hits, %0 failures -ReSign|src.c:103116 : 14 hits, %0 failures -ReSign|src.c:103120 : 14 hits, %0 failures -ReSign|src.c:103134 : 14 hits, %0 failures -UnSign|src.c:103143 : 14 hits, %0 failures -UnSign|src.c:101865 : 14 hits, %0 failures -ReSign|src.c:101865 : 14 hits, %0 failures -UnSign|src.c:101966 : 14 hits, %0 failures -ReSign|src.c:101968 : 14 hits, %0 failures -UnSign|src.c:101968 : 14 hits, %0 failures -UnSign|src.c:101989 : 14 hits, %0 failures -ReSign|src.c:101989 : 14 hits, %0 failures -ReSign|src.c:101996 : 14 hits, %0 failures -ReSign|src.c:102039 : 14 hits, %0 failures -ReSign|src.c:102564 : 14 hits, %0 failures -UnSign|src.c:91031 : 14 hits, %0 failures -ReSign|src.c:91036 : 14 hits, %0 failures -ReSign|src.c:91038 : 14 hits, %0 failures -UnSign|src.c:91038 : 14 hits, %0 failures -ReSign|src.c:90945 : 14 hits, %0 failures -ReSign|src.c:91045 : 14 hits, %0 failures -ReSign|src.c:91050 : 14 hits, %0 failures -ReSign|src.c:91058 : 14 hits, %0 failures -ReSign|src.c:91062 : 14 hits, %0 failures -ReSign|src.c:91067 : 14 hits, %0 failures -UnSign|src.c:91067 : 14 hits, %0 failures -ReSign|src.c:91075 : 14 hits, %0 failures -ReSign|src.c:91185 : 14 hits, %0 failures -ReSign|src.c:91190 : 14 hits, %0 failures -UnSign|src.c:103229 : 14 hits, %15 failures -ReSign|src.c:103229 : 14 hits, %0 failures -ReSign|src.c:103245 : 14 hits, %0 failures -UnSign|src.c:103274 : 14 hits, %0 failures -ReSign|src.c:102604 : 14 hits, %0 failures -ReSign|src.c:102608 : 14 hits, %0 failures -ReSign|src.c:102615 : 14 hits, %0 failures -ReSign|src.c:94824 : 14 hits, %0 failures -ReSign|src.c:94831 : 14 hits, %0 failures -UnSign|src.c:94853 : 14 hits, %0 failures -ReSign|src.c:91645 : 14 hits, %0 failures -ReSign|src.c:91652 : 14 hits, %0 failures -UnSign|src.c:91652 : 14 hits, %0 failures -ReSign|src.c:91653 : 14 hits, %0 failures -UnSign|src.c:91653 : 14 hits, %0 failures -UnSign|src.c:59242 : 14 hits, %0 failures -ReSign|src.c:59247 : 14 hits, %0 failures -ReSign|src.c:72273 : 14 hits, %0 failures -UnSign|src.c:99498 : 14 hits, %0 failures -ReSign|src.c:99498 : 14 hits, %0 failures -ReSign|src.c:99500 : 14 hits, %0 failures -ReSign|src.c:98893 : 14 hits, %0 failures -ReSign|src.c:98895 : 14 hits, %0 failures -UnSign|src.c:99503 : 14 hits, %86 failures -UnSign|src.c:109445 : 14 hits, %0 failures -ReSign|src.c:42052 : 14 hits, %0 failures -ReSign|src.c:41947 : 14 hits, %0 failures -UnSign|src.c:38146 : 14 hits, %0 failures -ReSign|src.c:38154 : 14 hits, %0 failures -ReSign|src.c:38233 : 14 hits, %0 failures -ReSign|src.c:50167 : 14 hits, %0 failures -ReSign|src.c:42704 : 14 hits, %0 failures -ReSign|src.c:38629 : 14 hits, %0 failures -ReSign|src.c:74860 : 14 hits, %0 failures -ReSign|src.c:74865 : 14 hits, %0 failures -ReSign|src.c:80354 : 14 hits, %0 failures -ReSign|src.c:80363 : 14 hits, %0 failures -ReSign|src.c:71430 : 14 hits, %0 failures -ReSign|src.c:98953 : 14 hits, %0 failures -ReSign|src.c:98956 : 14 hits, %0 failures -ReSign|src.c:81538 : 14 hits, %0 failures -ReSign|src.c:94419 : 13 hits, %0 failures -ReSign|src.c:69781 : 13 hits, %0 failures -ReSign|src.c:69785 : 13 hits, %0 failures -UnSign|src.c:57033 : 13 hits, %0 failures -ReSign|src.c:57033 : 13 hits, %0 failures -UnSign|src.c:57034 : 13 hits, %0 failures -UnSign|src.c:57036 : 13 hits, %0 failures -UnSign|src.c:63828 : 13 hits, %0 failures -UnSign|src.c:74197 : 13 hits, %0 failures -ReSign|src.c:74197 : 13 hits, %0 failures -ReSign|src.c:63877 : 13 hits, %0 failures -ReSign|src.c:63900 : 13 hits, %0 failures -ReSign|src.c:63921 : 13 hits, %0 failures -ReSign|src.c:86956 : 13 hits, %0 failures -ReSign|src.c:86969 : 13 hits, %0 failures -ReSign|src.c:86979 : 13 hits, %0 failures -ReSign|src.c:49844 : 13 hits, %0 failures -UnSign|src.c:49856 : 13 hits, %0 failures -ReSign|src.c:49856 : 13 hits, %0 failures -UnSign|src.c:49859 : 13 hits, %0 failures -ReSign|src.c:49859 : 13 hits, %0 failures -UnSign|src.c:49871 : 13 hits, %0 failures -ReSign|src.c:49871 : 13 hits, %0 failures -ReSign|src.c:49889 : 13 hits, %0 failures -ReSign|src.c:49893 : 13 hits, %0 failures -UnSign|src.c:49900 : 13 hits, %0 failures -UnSign|src.c:49920 : 13 hits, %0 failures -ReSign|src.c:49926 : 13 hits, %0 failures -ReSign|src.c:49927 : 13 hits, %0 failures -ReSign|src.c:128447 : 13 hits, %0 failures -ReSign|src.c:108126 : 12 hits, %0 failures -ReSign|src.c:14534 : 12 hits, %0 failures -ReSign|src.c:40288 : 12 hits, %0 failures -ReSign|src.c:21597 : 12 hits, %0 failures -ReSign|src.c:78026 : 12 hits, %0 failures -UnSign|src.c:78026 : 12 hits, %0 failures -ReSign|src.c:77706 : 12 hits, %0 failures -ReSign|src.c:89877 : 12 hits, %0 failures -ReSign|src.c:105857 : 12 hits, %0 failures -ReSign|src.c:70871 : 12 hits, %0 failures -ReSign|src.c:70873 : 12 hits, %0 failures -ReSign|src.c:74299 : 12 hits, %0 failures -ReSign|src.c:101248 : 12 hits, %0 failures -ReSign|src.c:99855 : 12 hits, %0 failures -ReSign|src.c:99866 : 12 hits, %0 failures -ReSign|src.c:99743 : 12 hits, %0 failures -ReSign|src.c:99878 : 12 hits, %0 failures -UnSign|src.c:103098 : 12 hits, %0 failures -UnSign|src.c:103100 : 12 hits, %0 failures -ReSign|src.c:103100 : 12 hits, %0 failures -ReSign|src.c:102059 : 12 hits, %0 failures -ReSign|src.c:102124 : 12 hits, %0 failures -ReSign|src.c:58243 : 12 hits, %0 failures -UnSign|src.c:103230 : 12 hits, %0 failures -ReSign|src.c:67108 : 12 hits, %0 failures -ReSign|src.c:67117 : 12 hits, %0 failures -ReSign|src.c:107349 : 12 hits, %0 failures -ReSign|src.c:18673 : 12 hits, %0 failures -ReSign|src.c:86958 : 12 hits, %0 failures -UnSign|src.c:34455 : 12 hits, %0 failures -UnSign|src.c:53310 : 12 hits, %0 failures -UnSign|src.c:53312 : 12 hits, %0 failures -UnSign|src.c:48927 : 12 hits, %0 failures -UnSign|src.c:48932 : 12 hits, %0 failures -UnSign|src.c:48948 : 12 hits, %0 failures -UnSign|src.c:48975 : 12 hits, %0 failures -ReSign|src.c:49000 : 12 hits, %0 failures -ReSign|src.c:57990 : 12 hits, %0 failures -ReSign|src.c:73342 : 12 hits, %0 failures -ReSign|src.c:79997 : 12 hits, %0 failures -ReSign|src.c:101586 : 12 hits, %0 failures -ReSign|src.c:77822 : 12 hits, %0 failures -ReSign|src.c:108657 : 12 hits, %0 failures -ReSign|src.c:108670 : 12 hits, %0 failures -ReSign|src.c:56356 : 11 hits, %0 failures -ReSign|src.c:35102 : 11 hits, %0 failures -ReSign|src.c:35117 : 11 hits, %0 failures -UnSign|src.c:58152 : 11 hits, %0 failures -ReSign|src.c:73358 : 11 hits, %0 failures -ReSign|src.c:73341 : 11 hits, %0 failures -UnSign|src.c:109577 : 10 hits, %0 failures -ReSign|src.c:109622 : 10 hits, %0 failures -UnSign|src.c:109626 : 10 hits, %0 failures -ReSign|src.c:78219 : 10 hits, %0 failures -ReSign|src.c:107299 : 10 hits, %0 failures -UnSign|src.c:101339 : 10 hits, %0 failures -ReSign|src.c:101341 : 10 hits, %0 failures -ReSign|src.c:47910 : 10 hits, %0 failures -ReSign|src.c:96463 : 10 hits, %0 failures -ReSign|src.c:96491 : 10 hits, %0 failures -ReSign|src.c:96493 : 10 hits, %0 failures -ReSign|src.c:96697 : 10 hits, %0 failures -ReSign|src.c:77875 : 10 hits, %0 failures -ReSign|src.c:97519 : 10 hits, %0 failures -UnSign|src.c:56771 : 10 hits, %0 failures -ReSign|src.c:56772 : 10 hits, %0 failures -UnSign|src.c:56850 : 10 hits, %0 failures -UnSign|src.c:54284 : 10 hits, %0 failures -ReSign|src.c:101404 : 10 hits, %0 failures -ReSign|src.c:102546 : 10 hits, %0 failures -ReSign|src.c:102554 : 10 hits, %0 failures -UnSign|src.c:74555 : 10 hits, %0 failures -UnSign|src.c:74568 : 10 hits, %0 failures -UnSign|src.c:102558 : 10 hits, %0 failures -UnSign|dlmalloc.c:4284 : 10 hits, %0 failures -ReSign|src.c:51856 : 10 hits, %0 failures -UnSign|src.c:51857 : 10 hits, %0 failures -ReSign|src.c:51857 : 10 hits, %0 failures -ReSign|src.c:67110 : 10 hits, %0 failures -UnSign|dlmalloc.c:4634 : 10 hits, %0 failures -UnSign|src.c:54942 : 10 hits, %0 failures -ReSign|src.c:94004 : 10 hits, %0 failures -ReSign|src.c:94107 : 10 hits, %0 failures -ReSign|src.c:94805 : 10 hits, %0 failures -ReSign|src.c:56656 : 10 hits, %0 failures -UnSign|src.c:60608 : 10 hits, %0 failures -ReSign|src.c:14244 : 9 hits, %0 failures -UnSign|src.c:74950 : 9 hits, %0 failures -UnSign|src.c:71495 : 9 hits, %0 failures -ReSign|src.c:57240 : 9 hits, %0 failures -ReSign|src.c:57241 : 9 hits, %0 failures -ReSign|src.c:57244 : 9 hits, %0 failures -ReSign|src.c:57258 : 9 hits, %0 failures -ReSign|src.c:108531 : 9 hits, %0 failures -ReSign|src.c:35105 : 9 hits, %0 failures -ReSign|src.c:14530 : 8 hits, %0 failures -ReSign|src.c:55559 : 8 hits, %0 failures -ReSign|src.c:109536 : 8 hits, %0 failures -ReSign|src.c:109539 : 8 hits, %0 failures -ReSign|src.c:78114 : 8 hits, %0 failures -ReSign|src.c:78115 : 8 hits, %0 failures -ReSign|src.c:78121 : 8 hits, %0 failures -ReSign|src.c:78125 : 8 hits, %0 failures -ReSign|src.c:78126 : 8 hits, %0 failures -ReSign|src.c:78129 : 8 hits, %0 failures -ReSign|src.c:78138 : 8 hits, %0 failures -ReSign|src.c:78145 : 8 hits, %0 failures -ReSign|src.c:78164 : 8 hits, %0 failures -UnSign|src.c:89689 : 8 hits, %0 failures -ReSign|src.c:89690 : 8 hits, %0 failures -ReSign|src.c:89696 : 8 hits, %0 failures -ReSign|src.c:89697 : 8 hits, %0 failures -ReSign|src.c:21096 : 8 hits, %0 failures -ReSign|src.c:78166 : 8 hits, %0 failures -ReSign|src.c:78170 : 8 hits, %0 failures -ReSign|src.c:78179 : 8 hits, %0 failures -ReSign|src.c:78186 : 8 hits, %0 failures -ReSign|src.c:78328 : 8 hits, %0 failures -UnSign|src.c:78824 : 8 hits, %0 failures -ReSign|src.c:78828 : 8 hits, %0 failures -ReSign|src.c:78837 : 8 hits, %0 failures -ReSign|src.c:78862 : 8 hits, %0 failures -ReSign|src.c:78872 : 8 hits, %0 failures -ReSign|src.c:78988 : 8 hits, %0 failures -ReSign|src.c:89717 : 8 hits, %0 failures -ReSign|src.c:60880 : 8 hits, %0 failures -ReSign|src.c:60890 : 8 hits, %0 failures -ReSign|src.c:59914 : 8 hits, %0 failures -ReSign|src.c:72565 : 8 hits, %0 failures -ReSign|src.c:72566 : 8 hits, %0 failures -ReSign|src.c:101361 : 8 hits, %0 failures -UnSign|src.c:77433 : 8 hits, %0 failures -ReSign|src.c:85002 : 8 hits, %0 failures -ReSign|src.c:77844 : 8 hits, %0 failures -ReSign|src.c:97447 : 8 hits, %0 failures -ReSign|src.c:97520 : 8 hits, %0 failures -ReSign|src.c:54869 : 8 hits, %0 failures -ReSign|src.c:54872 : 8 hits, %0 failures -ReSign|src.c:65726 : 8 hits, %0 failures -ReSign|src.c:65734 : 8 hits, %0 failures -ReSign|src.c:34760 : 8 hits, %0 failures -ReSign|dlmalloc.c:4652 : 8 hits, %0 failures -ReSign|src.c:71760 : 8 hits, %0 failures -ReSign|src.c:70550 : 8 hits, %0 failures -ReSign|src.c:70565 : 8 hits, %0 failures -ReSign|src.c:70573 : 8 hits, %0 failures -UnSign|src.c:70573 : 8 hits, %0 failures -ReSign|src.c:70576 : 8 hits, %0 failures -ReSign|src.c:70578 : 8 hits, %0 failures -ReSign|src.c:70593 : 8 hits, %0 failures -ReSign|src.c:70596 : 8 hits, %0 failures -ReSign|src.c:70601 : 8 hits, %0 failures -ReSign|src.c:70605 : 8 hits, %0 failures -ReSign|src.c:70607 : 8 hits, %0 failures -UnSign|src.c:101337 : 8 hits, %0 failures -UnSign|src.c:79782 : 8 hits, %0 failures -ReSign|src.c:79782 : 8 hits, %0 failures -ReSign|src.c:79809 : 8 hits, %0 failures -ReSign|src.c:76981 : 8 hits, %0 failures -ReSign|src.c:79824 : 8 hits, %0 failures -ReSign|src.c:79903 : 8 hits, %0 failures -ReSign|src.c:80000 : 8 hits, %0 failures -ReSign|src.c:80036 : 8 hits, %0 failures -ReSign|src.c:82203 : 8 hits, %0 failures -ReSign|src.c:101268 : 8 hits, %0 failures -ReSign|src.c:77794 : 8 hits, %0 failures -ReSign|src.c:81533 : 8 hits, %0 failures -UnSign|src.c:81545 : 8 hits, %0 failures -ReSign|src.c:81545 : 8 hits, %0 failures -ReSign|src.c:77808 : 8 hits, %0 failures -ReSign|src.c:108701 : 8 hits, %0 failures -ReSign|src.c:14557 : 7 hits, %0 failures -ReSign|2639 : 7 hits, %0 failures -ReSign|src.c:94412 : 7 hits, %0 failures -ReSign|src.c:50121 : 7 hits, %0 failures -ReSign|src.c:50124 : 7 hits, %0 failures -UnSign|src.c:50124 : 7 hits, %0 failures -ReSign|src.c:109445 : 7 hits, %0 failures -ReSign|src.c:42020 : 7 hits, %0 failures -UnSign|src.c:42024 : 7 hits, %0 failures -ReSign|src.c:42024 : 7 hits, %0 failures -ReSign|src.c:42027 : 7 hits, %0 failures -ReSign|src.c:42057 : 7 hits, %0 failures -ReSign|src.c:50125 : 7 hits, %0 failures -UnSign|src.c:49990 : 7 hits, %0 failures -ReSign|src.c:41945 : 7 hits, %0 failures -UnSign|src.c:41947 : 7 hits, %0 failures -ReSign|src.c:34392 : 7 hits, %0 failures -ReSign|src.c:41949 : 7 hits, %0 failures -ReSign|src.c:41954 : 7 hits, %0 failures -UnSign|src.c:41955 : 7 hits, %0 failures -ReSign|src.c:41955 : 7 hits, %0 failures -ReSign|src.c:41979 : 7 hits, %0 failures -ReSign|src.c:38055 : 7 hits, %0 failures -UnSign|src.c:38183 : 7 hits, %0 failures -ReSign|src.c:38183 : 7 hits, %0 failures -ReSign|src.c:41989 : 7 hits, %0 failures -ReSign|src.c:42126 : 7 hits, %0 failures -ReSign|src.c:50158 : 7 hits, %0 failures -UnSign|src.c:50158 : 7 hits, %0 failures -UnSign|src.c:73223 : 7 hits, %0 failures -ReSign|src.c:73223 : 7 hits, %0 failures -UnSign|src.c:73224 : 7 hits, %0 failures -ReSign|src.c:59324 : 7 hits, %0 failures -ReSign|src.c:42490 : 7 hits, %0 failures -ReSign|src.c:40452 : 7 hits, %0 failures -ReSign|src.c:50632 : 7 hits, %0 failures -ReSign|src.c:42537 : 7 hits, %0 failures -UnSign|src.c:42543 : 7 hits, %0 failures -ReSign|src.c:42543 : 7 hits, %0 failures -ReSign|src.c:42545 : 7 hits, %0 failures -ReSign|src.c:42732 : 7 hits, %0 failures -UnSign|src.c:42751 : 7 hits, %0 failures -ReSign|src.c:42751 : 7 hits, %0 failures -UnSign|src.c:42761 : 7 hits, %0 failures -UnSign|src.c:38708 : 7 hits, %0 failures -ReSign|src.c:38708 : 7 hits, %0 failures -ReSign|src.c:38714 : 7 hits, %0 failures -ReSign|src.c:38718 : 7 hits, %0 failures -ReSign|src.c:34549 : 7 hits, %0 failures -ReSign|src.c:38767 : 7 hits, %0 failures -ReSign|src.c:38775 : 7 hits, %0 failures -ReSign|src.c:38784 : 7 hits, %0 failures -ReSign|src.c:50724 : 7 hits, %0 failures -ReSign|dlmalloc.c:4661 : 7 hits, %0 failures -UnSign|src.c:48976 : 7 hits, %0 failures -ReSign|src.c:48976 : 7 hits, %0 failures -UnSign|src.c:71206 : 7 hits, %0 failures -UnSign|src.c:71048 : 7 hits, %0 failures -ReSign|src.c:94448 : 7 hits, %0 failures -ReSign|src.c:94475 : 7 hits, %0 failures -UnSign|src.c:74782 : 7 hits, %100 failures -ReSign|src.c:74855 : 7 hits, %0 failures -ReSign|src.c:80359 : 7 hits, %0 failures -ReSign|src.c:74870 : 7 hits, %0 failures -ReSign|src.c:74877 : 7 hits, %0 failures -UnSign|src.c:74879 : 7 hits, %0 failures -ReSign|src.c:74879 : 7 hits, %0 failures -ReSign|src.c:94479 : 7 hits, %0 failures -ReSign|src.c:94487 : 7 hits, %0 failures -ReSign|src.c:94492 : 7 hits, %0 failures -ReSign|src.c:94699 : 7 hits, %0 failures -ReSign|src.c:73760 : 7 hits, %0 failures -ReSign|src.c:73764 : 7 hits, %0 failures -ReSign|src.c:74329 : 7 hits, %0 failures -ReSign|src.c:57147 : 7 hits, %0 failures -UnSign|src.c:57990 : 7 hits, %0 failures -UnSign|src.c:101413 : 7 hits, %0 failures -ReSign|src.c:101413 : 7 hits, %0 failures -UnSign|src.c:98935 : 7 hits, %0 failures -ReSign|src.c:71406 : 7 hits, %0 failures -ReSign|src.c:71424 : 7 hits, %0 failures -UnSign|src.c:71430 : 7 hits, %0 failures -ReSign|src.c:98943 : 7 hits, %0 failures -ReSign|src.c:102248 : 7 hits, %0 failures -ReSign|src.c:108076 : 6 hits, %0 failures -ReSign|src.c:108087 : 6 hits, %0 failures -ReSign|src.c:108090 : 6 hits, %0 failures -ReSign|src.c:108092 : 6 hits, %0 failures -ReSign|src.c:108100 : 6 hits, %0 failures -ReSign|src.c:108108 : 6 hits, %0 failures -ReSign|src.c:108152 : 6 hits, %0 failures -ReSign|src.c:14537 : 6 hits, %0 failures -ReSign|src.c:81275 : 6 hits, %0 failures -ReSign|src.c:81292 : 6 hits, %0 failures -ReSign|src.c:49238 : 6 hits, %0 failures -ReSign|src.c:40287 : 6 hits, %0 failures -ReSign|src.c:40314 : 6 hits, %0 failures -ReSign|src.c:78994 : 6 hits, %0 failures -ReSign|src.c:79004 : 6 hits, %0 failures -ReSign|src.c:79008 : 6 hits, %0 failures -ReSign|src.c:20355 : 6 hits, %0 failures -UnSign|src.c:70667 : 6 hits, %0 failures -ReSign|src.c:70667 : 6 hits, %0 failures -ReSign|src.c:70928 : 6 hits, %0 failures -UnSign|src.c:72451 : 6 hits, %0 failures -ReSign|src.c:72451 : 6 hits, %0 failures -UnSign|src.c:72455 : 6 hits, %0 failures -ReSign|src.c:70936 : 6 hits, %0 failures -ReSign|src.c:70950 : 6 hits, %0 failures -UnSign|src.c:70871 : 6 hits, %0 failures -ReSign|src.c:70881 : 6 hits, %0 failures -ReSign|src.c:74723 : 6 hits, %0 failures -ReSign|src.c:91245 : 6 hits, %0 failures -ReSign|src.c:91253 : 6 hits, %0 failures -UnSign|src.c:101248 : 6 hits, %0 failures -UnSign|src.c:99813 : 6 hits, %0 failures -ReSign|src.c:99819 : 6 hits, %0 failures -ReSign|src.c:99822 : 6 hits, %0 failures -UnSign|src.c:99854 : 6 hits, %0 failures -ReSign|src.c:99877 : 6 hits, %0 failures -UnSign|src.c:99877 : 6 hits, %0 failures -ReSign|src.c:101250 : 6 hits, %0 failures -ReSign|src.c:101254 : 6 hits, %0 failures -ReSign|src.c:102070 : 6 hits, %0 failures -ReSign|src.c:102075 : 6 hits, %0 failures -ReSign|src.c:102103 : 6 hits, %0 failures -ReSign|src.c:102105 : 6 hits, %0 failures -ReSign|src.c:102121 : 6 hits, %0 failures -ReSign|src.c:102129 : 6 hits, %0 failures -ReSign|src.c:58240 : 6 hits, %0 failures -ReSign|src.c:58244 : 6 hits, %0 failures -ReSign|src.c:19186 : 6 hits, %0 failures -ReSign|src.c:107350 : 6 hits, %0 failures -UnSign|src.c:105971 : 6 hits, %0 failures -ReSign|src.c:105971 : 6 hits, %0 failures -ReSign|src.c:105976 : 6 hits, %0 failures -ReSign|src.c:18672 : 6 hits, %0 failures -UnSign|src.c:18673 : 6 hits, %0 failures -ReSign|src.c:96551 : 6 hits, %0 failures -ReSign|src.c:66496 : 6 hits, %0 failures -UnSign|src.c:52010 : 6 hits, %0 failures -ReSign|src.c:66501 : 6 hits, %0 failures -ReSign|src.c:66505 : 6 hits, %0 failures -ReSign|src.c:108532 : 6 hits, %0 failures -ReSign|src.c:42145 : 6 hits, %0 failures -UnSign|src.c:42166 : 6 hits, %0 failures -ReSign|src.c:42169 : 6 hits, %0 failures -ReSign|src.c:42171 : 6 hits, %0 failures -ReSign|src.c:42173 : 6 hits, %0 failures -ReSign|src.c:34441 : 6 hits, %0 failures -UnSign|src.c:34445 : 6 hits, %0 failures -UnSign|src.c:34454 : 6 hits, %0 failures -ReSign|src.c:42189 : 6 hits, %0 failures -ReSign|src.c:54026 : 6 hits, %0 failures -ReSign|src.c:53295 : 6 hits, %0 failures -UnSign|src.c:53299 : 6 hits, %0 failures -ReSign|src.c:53300 : 6 hits, %0 failures -ReSign|src.c:48927 : 6 hits, %0 failures -ReSign|src.c:53321 : 6 hits, %0 failures -ReSign|src.c:53329 : 6 hits, %0 failures -ReSign|src.c:54029 : 6 hits, %0 failures -ReSign|src.c:54033 : 6 hits, %0 failures -UnSign|src.c:54045 : 6 hits, %0 failures -UnSign|src.c:54049 : 6 hits, %0 failures -UnSign|src.c:54050 : 6 hits, %0 failures -ReSign|src.c:54088 : 6 hits, %0 failures -ReSign|src.c:102136 : 6 hits, %0 failures -ReSign|src.c:101414 : 6 hits, %0 failures -ReSign|src.c:71539 : 6 hits, %0 failures -ReSign|src.c:98811 : 6 hits, %0 failures -ReSign|src.c:74982 : 6 hits, %0 failures -ReSign|src.c:73845 : 6 hits, %0 failures -ReSign|src.c:79998 : 6 hits, %0 failures -ReSign|src.c:80027 : 6 hits, %0 failures -UnSign|src.c:78635 : 6 hits, %0 failures -ReSign|src.c:80191 : 6 hits, %0 failures -ReSign|src.c:101744 : 6 hits, %0 failures -UnSign|src.c:72489 : 6 hits, %100 failures -ReSign|src.c:72489 : 6 hits, %0 failures -ReSign|src.c:72533 : 6 hits, %0 failures -UnSign|src.c:72534 : 6 hits, %100 failures -ReSign|src.c:72534 : 6 hits, %0 failures -ReSign|src.c:72539 : 6 hits, %0 failures -ReSign|src.c:108659 : 6 hits, %0 failures -ReSign|src.c:128473 : 6 hits, %0 failures -UnSign|src.c:31200 : 5 hits, %0 failures -UnSign|src.c:35659 : 5 hits, %0 failures -ReSign|src.c:35664 : 5 hits, %0 failures -ReSign|src.c:35666 : 5 hits, %0 failures -ReSign|src.c:35668 : 5 hits, %0 failures -ReSign|src.c:35685 : 5 hits, %0 failures -ReSign|src.c:36007 : 5 hits, %0 failures -UnSign|src.c:101550 : 5 hits, %0 failures -UnSign|src.c:101554 : 5 hits, %0 failures -ReSign|src.c:101555 : 5 hits, %0 failures -ReSign|src.c:93548 : 5 hits, %0 failures -UnSign|src.c:93550 : 5 hits, %100 failures -ReSign|src.c:93550 : 5 hits, %0 failures -UnSign|src.c:93551 : 5 hits, %0 failures -ReSign|src.c:93551 : 5 hits, %0 failures -ReSign|src.c:93553 : 5 hits, %0 failures -ReSign|src.c:94784 : 5 hits, %0 failures -ReSign|src.c:94001 : 5 hits, %0 failures -ReSign|src.c:94009 : 5 hits, %0 failures -UnSign|src.c:94799 : 5 hits, %0 failures -ReSign|src.c:94800 : 5 hits, %0 failures -ReSign|src.c:94059 : 5 hits, %0 failures -ReSign|src.c:94067 : 5 hits, %0 failures -UnSign|src.c:94072 : 5 hits, %0 failures -ReSign|src.c:94072 : 5 hits, %0 failures -ReSign|src.c:94090 : 5 hits, %0 failures -UnSign|src.c:94805 : 5 hits, %0 failures -ReSign|src.c:94036 : 5 hits, %0 failures -ReSign|src.c:61388 : 5 hits, %0 failures -ReSign|src.c:61396 : 5 hits, %0 failures -ReSign|src.c:83547 : 5 hits, %0 failures -ReSign|src.c:68133 : 5 hits, %0 failures -UnSign|src.c:68136 : 5 hits, %0 failures -ReSign|src.c:68138 : 5 hits, %0 failures -ReSign|src.c:99042 : 5 hits, %0 failures -UnSign|src.c:60606 : 5 hits, %0 failures -ReSign|src.c:60606 : 5 hits, %0 failures -ReSign|src.c:128475 : 5 hits, %0 failures -ReSign|src.c:75243 : 4 hits, %0 failures -ReSign|src.c:31201 : 4 hits, %0 failures -UnSign|src.c:31201 : 4 hits, %0 failures -ReSign|src.c:14552 : 4 hits, %0 failures -ReSign|src.c:14528 : 4 hits, %0 failures -ReSign|src.c:14532 : 4 hits, %0 failures -ReSign|src.c:109775 : 4 hits, %0 failures -ReSign|src.c:49267 : 4 hits, %0 failures -ReSign|src.c:41117 : 4 hits, %0 failures -UnSign|src.c:40287 : 4 hits, %0 failures -ReSign|src.c:40294 : 4 hits, %0 failures -UnSign|src.c:40304 : 4 hits, %0 failures -ReSign|src.c:40313 : 4 hits, %0 failures -ReSign|src.c:41302 : 4 hits, %0 failures -UnSign|src.c:49372 : 4 hits, %0 failures -ReSign|src.c:49383 : 4 hits, %0 failures -ReSign|src.c:35261 : 4 hits, %0 failures -ReSign|src.c:81557 : 4 hits, %0 failures -ReSign|src.c:81562 : 4 hits, %0 failures -UnSign|src.c:81564 : 4 hits, %0 failures -ReSign|src.c:81564 : 4 hits, %0 failures -ReSign|src.c:108612 : 4 hits, %0 failures -UnSign|src.c:109539 : 4 hits, %0 failures -ReSign|src.c:108412 : 4 hits, %0 failures -UnSign|src.c:78055 : 4 hits, %0 failures -ReSign|src.c:78057 : 4 hits, %0 failures -ReSign|src.c:89811 : 4 hits, %0 failures -ReSign|src.c:89816 : 4 hits, %0 failures -ReSign|src.c:89828 : 4 hits, %0 failures -ReSign|src.c:89833 : 4 hits, %0 failures -UnSign|src.c:89834 : 4 hits, %0 failures -ReSign|src.c:89840 : 4 hits, %0 failures -UnSign|src.c:55527 : 4 hits, %0 failures -ReSign|src.c:35880 : 4 hits, %0 failures -ReSign|src.c:89937 : 4 hits, %0 failures -ReSign|src.c:89996 : 4 hits, %0 failures -ReSign|src.c:78258 : 4 hits, %0 failures -ReSign|src.c:19105 : 4 hits, %0 failures -ReSign|src.c:19106 : 4 hits, %0 failures -ReSign|src.c:19108 : 4 hits, %0 failures -ReSign|src.c:19109 : 4 hits, %0 failures -ReSign|src.c:77596 : 4 hits, %0 failures -ReSign|src.c:77601 : 4 hits, %0 failures -ReSign|src.c:18677 : 4 hits, %0 failures -UnSign|src.c:18678 : 4 hits, %0 failures -ReSign|src.c:96402 : 4 hits, %0 failures -ReSign|src.c:96547 : 4 hits, %0 failures -ReSign|src.c:77433 : 4 hits, %0 failures -ReSign|src.c:96659 : 4 hits, %0 failures -ReSign|src.c:96760 : 4 hits, %0 failures -ReSign|src.c:85148 : 4 hits, %0 failures -ReSign|src.c:65730 : 4 hits, %0 failures -UnSign|src.c:67504 : 4 hits, %0 failures -ReSign|src.c:67504 : 4 hits, %0 failures -ReSign|src.c:54483 : 4 hits, %0 failures -ReSign|src.c:54586 : 4 hits, %0 failures -ReSign|src.c:54590 : 4 hits, %0 failures -ReSign|src.c:52013 : 4 hits, %0 failures -ReSign|src.c:52068 : 4 hits, %0 failures -ReSign|src.c:67545 : 4 hits, %0 failures -ReSign|src.c:67552 : 4 hits, %0 failures -ReSign|src.c:67560 : 4 hits, %0 failures -ReSign|src.c:67565 : 4 hits, %0 failures -ReSign|src.c:65554 : 4 hits, %0 failures -ReSign|src.c:65561 : 4 hits, %0 failures -ReSign|src.c:108594 : 4 hits, %0 failures -ReSign|src.c:100108 : 4 hits, %0 failures -UnSign|src.c:100115 : 4 hits, %0 failures -ReSign|src.c:102377 : 4 hits, %0 failures -UnSign|src.c:102529 : 4 hits, %0 failures -ReSign|src.c:73846 : 4 hits, %0 failures -UnSign|src.c:106257 : 4 hits, %0 failures -ReSign|src.c:106264 : 4 hits, %0 failures -ReSign|src.c:79785 : 4 hits, %0 failures -ReSign|src.c:79792 : 4 hits, %0 failures -ReSign|src.c:79800 : 4 hits, %0 failures -ReSign|src.c:79807 : 4 hits, %0 failures -ReSign|src.c:79815 : 4 hits, %0 failures -ReSign|src.c:77013 : 4 hits, %0 failures -ReSign|src.c:77016 : 4 hits, %0 failures -ReSign|src.c:77036 : 4 hits, %0 failures -ReSign|src.c:77025 : 4 hits, %0 failures -ReSign|src.c:77057 : 4 hits, %0 failures -ReSign|src.c:77026 : 4 hits, %0 failures -ReSign|src.c:79816 : 4 hits, %0 failures -UnSign|src.c:79824 : 4 hits, %0 failures -ReSign|src.c:79836 : 4 hits, %0 failures -ReSign|src.c:79842 : 4 hits, %0 failures -UnSign|src.c:79848 : 4 hits, %0 failures -ReSign|src.c:79848 : 4 hits, %0 failures -ReSign|src.c:79867 : 4 hits, %0 failures -ReSign|src.c:79869 : 4 hits, %0 failures -ReSign|src.c:79870 : 4 hits, %0 failures -ReSign|src.c:79873 : 4 hits, %0 failures -ReSign|src.c:79879 : 4 hits, %0 failures -ReSign|src.c:79907 : 4 hits, %0 failures -ReSign|src.c:79908 : 4 hits, %0 failures -ReSign|src.c:79918 : 4 hits, %0 failures -ReSign|src.c:79932 : 4 hits, %0 failures -ReSign|src.c:79956 : 4 hits, %0 failures -ReSign|src.c:79969 : 4 hits, %0 failures -UnSign|src.c:79969 : 4 hits, %0 failures -UnSign|src.c:79975 : 4 hits, %0 failures -ReSign|src.c:79975 : 4 hits, %0 failures -ReSign|src.c:80012 : 4 hits, %0 failures -ReSign|src.c:80023 : 4 hits, %0 failures -UnSign|src.c:80031 : 4 hits, %0 failures -UnSign|src.c:80244 : 4 hits, %0 failures -UnSign|src.c:80248 : 4 hits, %0 failures -UnSign|src.c:80250 : 4 hits, %0 failures -ReSign|src.c:80250 : 4 hits, %0 failures -ReSign|src.c:80099 : 4 hits, %0 failures -ReSign|src.c:81095 : 4 hits, %0 failures -ReSign|src.c:81108 : 4 hits, %0 failures -ReSign|src.c:82205 : 4 hits, %0 failures -ReSign|src.c:82214 : 4 hits, %0 failures -ReSign|src.c:85093 : 4 hits, %0 failures -ReSign|src.c:85106 : 4 hits, %0 failures -UnSign|src.c:80191 : 4 hits, %0 failures -ReSign|src.c:80210 : 4 hits, %0 failures -UnSign|src.c:65909 : 4 hits, %0 failures -ReSign|src.c:48978 : 4 hits, %0 failures -UnSign|src.c:48982 : 4 hits, %0 failures -UnSign|src.c:48983 : 4 hits, %0 failures -ReSign|src.c:60763 : 4 hits, %0 failures -UnSign|src.c:102331 : 4 hits, %0 failures -ReSign|src.c:102337 : 4 hits, %0 failures -ReSign|src.c:77770 : 4 hits, %0 failures -UnSign|src.c:81547 : 4 hits, %0 failures -ReSign|src.c:108672 : 4 hits, %0 failures -ReSign|src.c:35750 : 4 hits, %0 failures -ReSign|src.c:49579 : 4 hits, %0 failures -ReSign|src.c:108693 : 4 hits, %0 failures -ReSign|src.c:87939 : 4 hits, %0 failures -ReSign|src.c:14509 : 3 hits, %0 failures -ReSign|src.c:14515 : 3 hits, %0 failures -ReSign|src.c:14516 : 3 hits, %0 failures -UnSign|src.c:101196 : 3 hits, %0 failures -ReSign|src.c:101196 : 3 hits, %0 failures -UnSign|src.c:101207 : 3 hits, %0 failures -ReSign|src.c:101207 : 3 hits, %0 failures -UnSign|src.c:101235 : 3 hits, %0 failures -ReSign|src.c:101235 : 3 hits, %0 failures -UnSign|src.c:101626 : 3 hits, %0 failures -ReSign|src.c:101626 : 3 hits, %0 failures -ReSign|src.c:65541 : 3 hits, %0 failures -ReSign|src.c:65546 : 3 hits, %0 failures -ReSign|src.c:74260 : 3 hits, %0 failures -ReSign|src.c:99016 : 3 hits, %0 failures -ReSign|src.c:57547 : 3 hits, %0 failures -UnSign|src.c:48984 : 3 hits, %0 failures -ReSign|src.c:48984 : 3 hits, %0 failures -UnSign|src.c:72491 : 3 hits, %100 failures -ReSign|src.c:72491 : 3 hits, %0 failures -UnSign|src.c:72492 : 3 hits, %0 failures -ReSign|src.c:72516 : 3 hits, %0 failures -UnSign|src.c:72536 : 3 hits, %100 failures -ReSign|src.c:72536 : 3 hits, %0 failures -UnSign|src.c:72537 : 3 hits, %0 failures -UnSign|src.c:72539 : 3 hits, %0 failures -ReSign|src.c:102256 : 3 hits, %0 failures -UnSign|src.c:102256 : 3 hits, %0 failures -ReSign|src.c:102257 : 3 hits, %0 failures -UnSign|src.c:102257 : 3 hits, %0 failures -ReSign|src.c:102258 : 3 hits, %0 failures -ReSign|src.c:101577 : 3 hits, %0 failures -ReSign|src.c:101591 : 3 hits, %0 failures -ReSign|src.c:101596 : 3 hits, %0 failures -ReSign|src.c:102331 : 3 hits, %0 failures -ReSign|src.c:66228 : 3 hits, %0 failures -ReSign|src.c:100866 : 3 hits, %0 failures -ReSign|src.c:108226 : 2 hits, %0 failures -ReSign|src.c:108095 : 2 hits, %0 failures -ReSign|dlmalloc.c:2982 : 2 hits, %0 failures -ReSign|dlmalloc.c:3919 : 2 hits, %0 failures -ReSign|dlmalloc.c:4009 : 2 hits, %0 failures -ReSign|src.c:35465 : 2 hits, %0 failures -ReSign|src.c:109984 : 2 hits, %0 failures -ReSign|src.c:110003 : 2 hits, %0 failures -ReSign|src.c:110005 : 2 hits, %0 failures -ReSign|src.c:110007 : 2 hits, %0 failures -ReSign|src.c:110009 : 2 hits, %0 failures -ReSign|src.c:110014 : 2 hits, %0 failures -ReSign|src.c:110016 : 2 hits, %0 failures -ReSign|src.c:110045 : 2 hits, %0 failures -ReSign|src.c:110046 : 2 hits, %0 failures -ReSign|src.c:57405 : 2 hits, %0 failures -ReSign|src.c:110096 : 2 hits, %0 failures -ReSign|src.c:109942 : 2 hits, %0 failures -ReSign|src.c:109949 : 2 hits, %0 failures -ReSign|src.c:109954 : 2 hits, %0 failures -ReSign|src.c:110109 : 2 hits, %0 failures -UnSign|src.c:49238 : 2 hits, %0 failures -ReSign|src.c:49247 : 2 hits, %0 failures -ReSign|src.c:49246 : 2 hits, %0 failures -UnSign|src.c:49247 : 2 hits, %0 failures -ReSign|src.c:49261 : 2 hits, %0 failures -ReSign|src.c:49264 : 2 hits, %0 failures -ReSign|src.c:49271 : 2 hits, %0 failures -ReSign|src.c:49286 : 2 hits, %0 failures -ReSign|src.c:49336 : 2 hits, %0 failures -ReSign|src.c:49349 : 2 hits, %0 failures -ReSign|src.c:41102 : 2 hits, %0 failures -UnSign|src.c:41102 : 2 hits, %0 failures -ReSign|src.c:41103 : 2 hits, %0 failures -UnSign|src.c:41103 : 2 hits, %0 failures -ReSign|src.c:41127 : 2 hits, %0 failures -ReSign|src.c:41137 : 2 hits, %0 failures -ReSign|src.c:41192 : 2 hits, %0 failures -ReSign|src.c:41205 : 2 hits, %0 failures -ReSign|src.c:41226 : 2 hits, %0 failures -ReSign|src.c:41283 : 2 hits, %0 failures -UnSign|src.c:40294 : 2 hits, %0 failures -ReSign|src.c:40297 : 2 hits, %0 failures -ReSign|src.c:40299 : 2 hits, %0 failures -ReSign|src.c:40302 : 2 hits, %0 failures -ReSign|src.c:34877 : 2 hits, %0 failures -ReSign|src.c:41292 : 2 hits, %0 failures -UnSign|src.c:41302 : 2 hits, %0 failures -ReSign|src.c:41309 : 2 hits, %0 failures -UnSign|src.c:41332 : 2 hits, %0 failures -ReSign|src.c:41332 : 2 hits, %0 failures -UnSign|src.c:41333 : 2 hits, %0 failures -ReSign|src.c:41333 : 2 hits, %0 failures -ReSign|src.c:39325 : 2 hits, %0 failures -UnSign|src.c:39332 : 2 hits, %0 failures -UnSign|src.c:39335 : 2 hits, %0 failures -ReSign|src.c:41342 : 2 hits, %0 failures -ReSign|src.c:41344 : 2 hits, %0 failures -ReSign|src.c:49355 : 2 hits, %0 failures -ReSign|src.c:40399 : 2 hits, %0 failures -ReSign|src.c:49358 : 2 hits, %0 failures -UnSign|src.c:49373 : 2 hits, %0 failures -UnSign|src.c:49397 : 2 hits, %0 failures -ReSign|src.c:49398 : 2 hits, %0 failures -UnSign|src.c:49399 : 2 hits, %0 failures -ReSign|src.c:49405 : 2 hits, %0 failures -ReSign|src.c:49430 : 2 hits, %0 failures -ReSign|src.c:49459 : 2 hits, %0 failures -ReSign|src.c:49471 : 2 hits, %0 failures -ReSign|src.c:49475 : 2 hits, %0 failures -ReSign|src.c:110119 : 2 hits, %0 failures -ReSign|src.c:110139 : 2 hits, %0 failures -ReSign|src.c:109150 : 2 hits, %0 failures -ReSign|src.c:108981 : 2 hits, %0 failures -ReSign|src.c:108993 : 2 hits, %0 failures -ReSign|src.c:108995 : 2 hits, %0 failures -ReSign|src.c:109018 : 2 hits, %0 failures -ReSign|src.c:81500 : 2 hits, %0 failures -ReSign|src.c:109031 : 2 hits, %0 failures -ReSign|src.c:109039 : 2 hits, %0 failures -ReSign|src.c:83657 : 2 hits, %0 failures -ReSign|src.c:88073 : 2 hits, %0 failures -ReSign|src.c:110155 : 2 hits, %0 failures -ReSign|src.c:108397 : 2 hits, %0 failures -ReSign|src.c:108404 : 2 hits, %0 failures -ReSign|src.c:108410 : 2 hits, %0 failures -ReSign|src.c:108411 : 2 hits, %0 failures -ReSign|src.c:108415 : 2 hits, %0 failures -ReSign|src.c:108427 : 2 hits, %0 failures -ReSign|src.c:108439 : 2 hits, %0 failures -ReSign|src.c:109294 : 2 hits, %0 failures -ReSign|src.c:110211 : 2 hits, %0 failures -ReSign|src.c:110216 : 2 hits, %0 failures -ReSign|src.c:110219 : 2 hits, %0 failures -ReSign|src.c:55527 : 2 hits, %0 failures -ReSign|src.c:89851 : 2 hits, %0 failures -ReSign|src.c:35851 : 2 hits, %0 failures -ReSign|src.c:35861 : 2 hits, %0 failures -ReSign|src.c:35862 : 2 hits, %0 failures -ReSign|src.c:34909 : 2 hits, %0 failures -ReSign|src.c:89853 : 2 hits, %0 failures -ReSign|src.c:89887 : 2 hits, %0 failures -UnSign|src.c:89905 : 2 hits, %0 failures -ReSign|src.c:89909 : 2 hits, %0 failures -ReSign|src.c:21671 : 2 hits, %0 failures -ReSign|src.c:89911 : 2 hits, %0 failures -UnSign|src.c:89923 : 2 hits, %0 failures -ReSign|src.c:89923 : 2 hits, %0 failures -UnSign|src.c:89926 : 2 hits, %0 failures -ReSign|src.c:89926 : 2 hits, %0 failures -ReSign|src.c:89960 : 2 hits, %0 failures -ReSign|src.c:89963 : 2 hits, %0 failures -ReSign|src.c:76440 : 2 hits, %0 failures -ReSign|src.c:76450 : 2 hits, %0 failures -ReSign|src.c:89968 : 2 hits, %0 failures -ReSign|src.c:89972 : 2 hits, %0 failures -UnSign|src.c:89981 : 2 hits, %0 failures -ReSign|src.c:89990 : 2 hits, %0 failures -ReSign|src.c:50743 : 2 hits, %0 failures -ReSign|src.c:90022 : 2 hits, %0 failures -UnSign|src.c:78115 : 2 hits, %0 failures -ReSign|src.c:89841 : 2 hits, %0 failures -UnSign|src.c:89842 : 2 hits, %0 failures -ReSign|src.c:90035 : 2 hits, %0 failures -ReSign|src.c:78226 : 2 hits, %0 failures -ReSign|src.c:78240 : 2 hits, %0 failures -UnSign|src.c:78244 : 2 hits, %0 failures -ReSign|src.c:77957 : 2 hits, %0 failures -ReSign|src.c:77960 : 2 hits, %0 failures -ReSign|src.c:78880 : 2 hits, %0 failures -ReSign|src.c:78887 : 2 hits, %0 failures -ReSign|src.c:78912 : 2 hits, %0 failures -ReSign|src.c:78936 : 2 hits, %0 failures -ReSign|src.c:78949 : 2 hits, %0 failures -UnSign|src.c:105889 : 2 hits, %0 failures -UnSign|src.c:96402 : 2 hits, %0 failures -ReSign|src.c:96410 : 2 hits, %0 failures -ReSign|src.c:96418 : 2 hits, %0 failures -UnSign|src.c:96418 : 2 hits, %0 failures -ReSign|src.c:96430 : 2 hits, %0 failures -ReSign|src.c:96433 : 2 hits, %0 failures -ReSign|src.c:96437 : 2 hits, %0 failures -ReSign|src.c:96446 : 2 hits, %0 failures -ReSign|src.c:84715 : 2 hits, %0 failures -ReSign|src.c:96507 : 2 hits, %0 failures -ReSign|src.c:96508 : 2 hits, %0 failures -ReSign|src.c:96512 : 2 hits, %0 failures -ReSign|src.c:96530 : 2 hits, %0 failures -UnSign|src.c:96531 : 2 hits, %0 failures -ReSign|src.c:96531 : 2 hits, %0 failures -UnSign|src.c:96536 : 2 hits, %0 failures -ReSign|src.c:96536 : 2 hits, %0 failures -ReSign|src.c:96558 : 2 hits, %0 failures -ReSign|src.c:96566 : 2 hits, %0 failures -ReSign|src.c:96574 : 2 hits, %0 failures -ReSign|src.c:101238 : 2 hits, %0 failures -ReSign|src.c:96582 : 2 hits, %0 failures -UnSign|src.c:96583 : 2 hits, %0 failures -ReSign|src.c:96588 : 2 hits, %0 failures -ReSign|src.c:96599 : 2 hits, %0 failures -ReSign|src.c:96604 : 2 hits, %0 failures -ReSign|src.c:96611 : 2 hits, %0 failures -ReSign|src.c:96612 : 2 hits, %0 failures -ReSign|src.c:96616 : 2 hits, %0 failures -ReSign|src.c:96623 : 2 hits, %0 failures -ReSign|src.c:96634 : 2 hits, %0 failures -ReSign|src.c:96652 : 2 hits, %0 failures -ReSign|src.c:96245 : 2 hits, %0 failures -ReSign|src.c:96250 : 2 hits, %0 failures -ReSign|src.c:96716 : 2 hits, %0 failures -ReSign|src.c:96743 : 2 hits, %0 failures -ReSign|src.c:96747 : 2 hits, %0 failures -ReSign|src.c:96751 : 2 hits, %0 failures -ReSign|src.c:82169 : 2 hits, %0 failures -ReSign|src.c:96765 : 2 hits, %0 failures -ReSign|src.c:96775 : 2 hits, %0 failures -ReSign|src.c:96782 : 2 hits, %0 failures -ReSign|src.c:96191 : 2 hits, %0 failures -ReSign|src.c:96796 : 2 hits, %0 failures -UnSign|src.c:96807 : 2 hits, %0 failures -ReSign|src.c:96807 : 2 hits, %0 failures -ReSign|src.c:96816 : 2 hits, %0 failures -ReSign|src.c:77351 : 2 hits, %0 failures -UnSign|src.c:78968 : 2 hits, %0 failures -ReSign|src.c:78968 : 2 hits, %0 failures -ReSign|src.c:49997 : 2 hits, %0 failures -UnSign|src.c:50015 : 2 hits, %0 failures -UnSign|src.c:50016 : 2 hits, %0 failures -UnSign|src.c:64339 : 2 hits, %0 failures -ReSign|src.c:64339 : 2 hits, %0 failures -UnSign|src.c:64347 : 2 hits, %0 failures -ReSign|src.c:52008 : 2 hits, %0 failures -ReSign|src.c:52010 : 2 hits, %0 failures -UnSign|src.c:52068 : 2 hits, %0 failures -UnSign|src.c:64858 : 2 hits, %0 failures -ReSign|src.c:64858 : 2 hits, %0 failures -ReSign|src.c:54281 : 2 hits, %0 failures -ReSign|src.c:54285 : 2 hits, %0 failures -UnSign|src.c:52699 : 2 hits, %0 failures -ReSign|src.c:52699 : 2 hits, %0 failures -UnSign|src.c:54290 : 2 hits, %0 failures -ReSign|src.c:54291 : 2 hits, %0 failures -UnSign|src.c:65541 : 2 hits, %0 failures -UnSign|src.c:65561 : 2 hits, %0 failures -ReSign|src.c:65562 : 2 hits, %0 failures -ReSign|src.c:65566 : 2 hits, %0 failures -ReSign|src.c:65570 : 2 hits, %0 failures -ReSign|src.c:65579 : 2 hits, %0 failures -UnSign|src.c:93590 : 2 hits, %0 failures -ReSign|src.c:93590 : 2 hits, %0 failures -UnSign|src.c:93591 : 2 hits, %100 failures -ReSign|src.c:93591 : 2 hits, %0 failures -UnSign|src.c:93592 : 2 hits, %0 failures -ReSign|src.c:93592 : 2 hits, %0 failures -UnSign|src.c:93593 : 2 hits, %0 failures -ReSign|src.c:93593 : 2 hits, %0 failures -ReSign|src.c:94736 : 2 hits, %0 failures -ReSign|src.c:94741 : 2 hits, %0 failures -ReSign|src.c:94748 : 2 hits, %0 failures -UnSign|src.c:94124 : 2 hits, %0 failures -ReSign|src.c:94124 : 2 hits, %0 failures -ReSign|src.c:65345 : 2 hits, %0 failures -UnSign|src.c:107229 : 2 hits, %0 failures -ReSign|src.c:107229 : 2 hits, %0 failures -ReSign|src.c:107232 : 2 hits, %0 failures -UnSign|src.c:107214 : 2 hits, %0 failures -ReSign|src.c:107214 : 2 hits, %0 failures -ReSign|src.c:107217 : 2 hits, %0 failures -ReSign|src.c:107220 : 2 hits, %0 failures -ReSign|src.c:74261 : 2 hits, %0 failures -UnSign|src.c:74261 : 2 hits, %0 failures -ReSign|src.c:72370 : 2 hits, %0 failures -ReSign|src.c:83714 : 2 hits, %0 failures -UnSign|src.c:83726 : 2 hits, %0 failures -ReSign|src.c:73839 : 2 hits, %0 failures -UnSign|src.c:73849 : 2 hits, %0 failures -ReSign|src.c:73849 : 2 hits, %0 failures -ReSign|src.c:79874 : 2 hits, %0 failures -ReSign|src.c:80137 : 2 hits, %0 failures -ReSign|src.c:80148 : 2 hits, %0 failures -ReSign|src.c:80151 : 2 hits, %0 failures -ReSign|src.c:80163 : 2 hits, %0 failures -ReSign|src.c:80176 : 2 hits, %0 failures -ReSign|src.c:79680 : 2 hits, %0 failures -ReSign|src.c:79690 : 2 hits, %0 failures -ReSign|src.c:79691 : 2 hits, %0 failures -ReSign|src.c:79700 : 2 hits, %0 failures -ReSign|src.c:82212 : 2 hits, %0 failures -UnSign|src.c:79707 : 2 hits, %0 failures -ReSign|src.c:79707 : 2 hits, %0 failures -ReSign|src.c:65901 : 2 hits, %0 failures -UnSign|src.c:48978 : 2 hits, %0 failures -ReSign|src.c:80105 : 2 hits, %0 failures -ReSign|src.c:80111 : 2 hits, %0 failures -ReSign|src.c:80192 : 2 hits, %0 failures -ReSign|src.c:68333 : 2 hits, %0 failures -UnSign|dlmalloc.c:4661 : 2 hits, %0 failures -ReSign|src.c:101270 : 2 hits, %0 failures -ReSign|src.c:101274 : 2 hits, %0 failures -ReSign|src.c:101342 : 2 hits, %0 failures -ReSign|src.c:101354 : 2 hits, %0 failures -UnSign|src.c:102212 : 2 hits, %0 failures -ReSign|src.c:102212 : 2 hits, %0 failures -ReSign|src.c:102225 : 2 hits, %0 failures -ReSign|src.c:102229 : 2 hits, %0 failures -ReSign|src.c:101737 : 2 hits, %0 failures -ReSign|src.c:101754 : 2 hits, %0 failures -ReSign|src.c:101768 : 2 hits, %0 failures -UnSign|src.c:102258 : 2 hits, %0 failures -ReSign|src.c:102262 : 2 hits, %0 failures -UnSign|src.c:102288 : 2 hits, %0 failures -ReSign|src.c:102302 : 2 hits, %0 failures -ReSign|src.c:102335 : 2 hits, %0 failures -ReSign|src.c:102347 : 2 hits, %0 failures -ReSign|src.c:102356 : 2 hits, %0 failures -ReSign|src.c:102366 : 2 hits, %0 failures -ReSign|src.c:102368 : 2 hits, %0 failures -ReSign|src.c:58406 : 2 hits, %0 failures -ReSign|src.c:58413 : 2 hits, %0 failures -UnSign|src.c:103313 : 2 hits, %0 failures -ReSign|src.c:103313 : 2 hits, %0 failures -UnSign|src.c:103323 : 2 hits, %0 failures -ReSign|src.c:103323 : 2 hits, %0 failures -ReSign|src.c:66130 : 2 hits, %0 failures -UnSign|src.c:66131 : 2 hits, %0 failures -ReSign|src.c:66133 : 2 hits, %0 failures -UnSign|src.c:66215 : 2 hits, %0 failures -ReSign|src.c:66215 : 2 hits, %0 failures -ReSign|src.c:66217 : 2 hits, %0 failures -ReSign|src.c:66227 : 2 hits, %0 failures -ReSign|src.c:66249 : 2 hits, %0 failures -ReSign|src.c:100867 : 2 hits, %0 failures -UnSign|src.c:102248 : 2 hits, %0 failures -ReSign|src.c:102269 : 2 hits, %0 failures -ReSign|src.c:102310 : 2 hits, %0 failures -ReSign|src.c:108628 : 2 hits, %0 failures -ReSign|src.c:108631 : 2 hits, %0 failures -ReSign|src.c:77878 : 2 hits, %0 failures -ReSign|src.c:108649 : 2 hits, %0 failures -ReSign|src.c:55533 : 2 hits, %0 failures -UnSign|src.c:55533 : 2 hits, %0 failures -ReSign|src.c:49551 : 2 hits, %0 failures -ReSign|src.c:50821 : 2 hits, %0 failures -UnSign|src.c:50834 : 2 hits, %0 failures -ReSign|src.c:50834 : 2 hits, %0 failures -ReSign|src.c:49571 : 2 hits, %0 failures -UnSign|src.c:40551 : 2 hits, %0 failures -ReSign|src.c:45430 : 2 hits, %0 failures -ReSign|src.c:40555 : 2 hits, %0 failures -ReSign|src.c:38546 : 2 hits, %0 failures -ReSign|src.c:38559 : 2 hits, %0 failures -ReSign|src.c:37855 : 2 hits, %0 failures -ReSign|src.c:38571 : 2 hits, %0 failures -ReSign|src.c:35129 : 2 hits, %0 failures -ReSign|src.c:49590 : 2 hits, %0 failures -ReSign|src.c:49591 : 2 hits, %0 failures -ReSign|src.c:108675 : 2 hits, %0 failures -ReSign|src.c:108713 : 2 hits, %0 failures -ReSign|src.c:108724 : 2 hits, %0 failures -ReSign|src.c:108742 : 2 hits, %0 failures -ReSign|src.c:18167 : 1 hits, %0 failures -ReSign|src.c:18171 : 1 hits, %0 failures -ReSign|src.c:18174 : 1 hits, %0 failures -ReSign|src.c:18196 : 1 hits, %0 failures -ReSign|src.c:108131 : 1 hits, %0 failures -ReSign|src.c:34828 : 1 hits, %0 failures -ReSign|src.c:35801 : 1 hits, %0 failures -ReSign|src.c:108134 : 1 hits, %0 failures -ReSign|dlmalloc.c:2958 : 1 hits, %0 failures -ReSign|dlmalloc.c:3912 : 1 hits, %0 failures -ReSign|dlmalloc.c:3915 : 1 hits, %0 failures -UnSign|dlmalloc.c:3918 : 1 hits, %0 failures -ReSign|dlmalloc.c:4000 : 1 hits, %0 failures -ReSign|src.c:14487 : 1 hits, %0 failures -ReSign|src.c:108138 : 1 hits, %0 failures -ReSign|src.c:35460 : 1 hits, %0 failures -ReSign|src.c:35469 : 1 hits, %0 failures -ReSign|src.c:128492 : 1 hits, %0 failures -ReSign|src.c:128515 : 1 hits, %0 failures -ReSign|src.c:128517 : 1 hits, %0 failures -ReSign|src.c:128518 : 1 hits, %0 failures -ReSign|src.c:80712 : 1 hits, %0 failures -ReSign|src.c:80716 : 1 hits, %0 failures -ReSign|src.c:80717 : 1 hits, %0 failures -ReSign|src.c:128520 : 1 hits, %0 failures -ReSign|src.c:128530 : 1 hits, %0 failures -ReSign|src.c:80737 : 1 hits, %0 failures -ReSign|src.c:80741 : 1 hits, %0 failures -ReSign|src.c:128532 : 1 hits, %0 failures -ReSign|src.c:128533 : 1 hits, %0 failures -ReSign|src.c:128536 : 1 hits, %0 failures -ReSign|src.c:128537 : 1 hits, %0 failures -ReSign|src.c:128538 : 1 hits, %0 failures -ReSign|src.c:106054 : 1 hits, %0 failures -ReSign|src.c:106057 : 1 hits, %0 failures -UnSign|src.c:106057 : 1 hits, %0 failures -ReSign|src.c:74257 : 1 hits, %0 failures -UnSign|src.c:74200 : 1 hits, %0 failures -ReSign|src.c:74200 : 1 hits, %0 failures -UnSign|src.c:74201 : 1 hits, %0 failures -UnSign|src.c:99551 : 1 hits, %0 failures -ReSign|src.c:99551 : 1 hits, %0 failures -UnSign|src.c:99577 : 1 hits, %0 failures -ReSign|src.c:99577 : 1 hits, %0 failures -UnSign|src.c:83714 : 1 hits, %0 failures -ReSign|src.c:83726 : 1 hits, %0 failures -UnSign|src.c:99016 : 1 hits, %0 failures -UnSign|src.c:99024 : 1 hits, %0 failures -ReSign|src.c:99025 : 1 hits, %0 failures -ReSign|src.c:99028 : 1 hits, %0 failures -ReSign|src.c:99037 : 1 hits, %0 failures -ReSign|src.c:99040 : 1 hits, %0 failures -ReSign|src.c:99045 : 1 hits, %0 failures -ReSign|src.c:99073 : 1 hits, %0 failures -UnSign|src.c:99073 : 1 hits, %0 failures -ReSign|src.c:99094 : 1 hits, %0 failures -UnSign|src.c:101427 : 1 hits, %0 failures -ReSign|src.c:101427 : 1 hits, %0 failures -UnSign|src.c:73783 : 1 hits, %0 failures -ReSign|src.c:73783 : 1 hits, %0 failures -ReSign|src.c:73788 : 1 hits, %0 failures -ReSign|src.c:73793 : 1 hits, %0 failures -UnSign|src.c:73802 : 1 hits, %0 failures -ReSign|src.c:73802 : 1 hits, %0 failures -ReSign|src.c:73818 : 1 hits, %0 failures -UnSign|src.c:73839 : 1 hits, %0 failures -ReSign|src.c:98231 : 1 hits, %0 failures -UnSign|src.c:98232 : 1 hits, %0 failures -ReSign|src.c:98232 : 1 hits, %0 failures -ReSign|src.c:98234 : 1 hits, %0 failures -UnSign|src.c:98235 : 1 hits, %0 failures -ReSign|src.c:98235 : 1 hits, %0 failures -UnSign|src.c:73853 : 1 hits, %0 failures -ReSign|src.c:73853 : 1 hits, %0 failures -ReSign|src.c:73860 : 1 hits, %0 failures -ReSign|src.c:74652 : 1 hits, %0 failures -UnSign|src.c:74652 : 1 hits, %0 failures -ReSign|src.c:128539 : 1 hits, %0 failures -ReSign|src.c:128540 : 1 hits, %0 failures -UnSign|src.c:48989 : 1 hits, %0 failures -ReSign|src.c:128543 : 1 hits, %0 failures -ReSign|src.c:128544 : 1 hits, %0 failures -ReSign|src.c:128545 : 1 hits, %0 failures -ReSign|src.c:101748 : 1 hits, %0 failures -ReSign|src.c:101755 : 1 hits, %0 failures -UnSign|src.c:101764 : 1 hits, %0 failures -ReSign|src.c:101764 : 1 hits, %0 failures -ReSign|src.c:101767 : 1 hits, %0 failures -ReSign|src.c:101771 : 1 hits, %0 failures -ReSign|src.c:102281 : 1 hits, %0 failures -ReSign|src.c:66230 : 1 hits, %0 failures -ReSign|src.c:128547 : 1 hits, %0 failures -UnSign|src.c:100866 : 1 hits, %0 failures -ReSign|src.c:101223 : 1 hits, %0 failures -ReSign|src.c:101228 : 1 hits, %0 failures -UnSign|src.c:102265 : 1 hits, %0 failures -ReSign|src.c:102265 : 1 hits, %0 failures -ReSign|src.c:102268 : 1 hits, %0 failures -ReSign|src.c:102275 : 1 hits, %0 failures -UnSign|src.c:102306 : 1 hits, %0 failures -ReSign|src.c:102306 : 1 hits, %0 failures -ReSign|src.c:102309 : 1 hits, %0 failures -ReSign|src.c:102316 : 1 hits, %0 failures -ReSign|src.c:128548 : 1 hits, %0 failures -ReSign|src.c:128549 : 1 hits, %0 failures -ReSign|src.c:128468 : 1 hits, %0 failures diff --git a/tests/websockets.c b/tests/websockets.c index 8a8a0919..57549e94 100644 --- a/tests/websockets.c +++ b/tests/websockets.c @@ -8,6 +8,7 @@ #include <string.h> #include <unistd.h> #include <sys/ioctl.h> +#include <assert.h> #if EMSCRIPTEN #include <emscripten.h> #endif @@ -16,11 +17,25 @@ int SocketFD; +int not_always_data = 0; + unsigned int get_all_buf(int sock, char* output, unsigned int maxsize) { + // select check for IO + fd_set sett; + FD_ZERO(&sett); + assert(select(64, &sett, NULL, NULL, NULL) == 0); // empty set + FD_SET(sock, &sett); + assert(select(0, &sett, NULL, NULL, NULL) == 0); // max FD to check is 0 + int select_says_yes = select(64, &sett, NULL, NULL, NULL); + + // ioctl check for IO int bytes; - if (ioctl(sock, FIONREAD, &bytes)) return 0; - if (bytes == 0) return 0; + if (ioctl(sock, FIONREAD, &bytes) || bytes == 0) { + not_always_data = 1; + return 0; + } + assert(select_says_yes); // ioctl must agree with select char buffer[1024]; int n; @@ -67,6 +82,8 @@ void iter(void *arg) { printf("sum: %d\n", sum); #if EMSCRIPTEN + assert(not_always_data == 1); + int result = sum; REPORT_RESULT(); #endif diff --git a/tests/websockets_bi.c b/tests/websockets_bi.c index 73d061d2..c2dbb7da 100644 --- a/tests/websockets_bi.c +++ b/tests/websockets_bi.c @@ -81,7 +81,11 @@ int main(void) struct sockaddr_in stSockAddr; int Res; +#if !TEST_DGRAM SocketFD = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); +#else + SocketFD = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); +#endif if (-1 == SocketFD) { diff --git a/tests/websockets_bi_side.c b/tests/websockets_bi_side.c index c9c50618..12b790fd 100644 --- a/tests/websockets_bi_side.c +++ b/tests/websockets_bi_side.c @@ -18,7 +18,11 @@ int main(void) { struct sockaddr_in stSockAddr; int Res; +#if !TEST_DGRAM int SocketFD = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); +#else + int SocketFD = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); +#endif if (-1 == SocketFD) { diff --git a/tools/bisect_pair.py b/tools/bisect_pair.py index 8eea0d61..cdb76286 100644 --- a/tools/bisect_pair.py +++ b/tools/bisect_pair.py @@ -23,9 +23,15 @@ rightf = open('right', 'w') rightf.write(file2) rightf.close() +def run_code(name): + ret = run_js(name, stderr=PIPE, full_output=True) + # fix stack traces + ret = filter(lambda line: not line.startswith(' at ') and not name in line, ret.split('\n')) + return '\n'.join(ret) + print 'running files' -left_result = run_js('left', stderr=PIPE) -right_result = run_js('right', stderr=PIPE) # right as in left-right, not as in correct +left_result = run_code('left') +right_result = run_code('right') # right as in left-right, not as in correct assert left_result != right_result # Calculate diff chunks @@ -52,31 +58,31 @@ high = len(chunks) print 'beginning bisection, %d chunks' % high for mid in range(high): - print ' current: %d' % mid + print ' current: %d' % mid, # Take chunks from the middle and on. This is important because the eliminator removes variables, so starting from the beginning will add errors curr_diff = '\n'.join(map(lambda parts: '\n'.join(parts), chunks[mid:])) + '\n' difff = open('diff.diff', 'w') difff.write(curr_diff) difff.close() shutil.copy('left', 'middle') - Popen(['patch', 'middle', 'diff.diff'], stdout=PIPE, stderr=PIPE).communicate() - result = run_js('middle', stderr=PIPE) - if result == left_result: - print 'found where it starts to work: %d' % mid + Popen(['patch', 'middle', 'diff.diff'], stdout=PIPE).communicate() + shutil.copyfile('middle', 'middle' + str(mid)) + result = run_code('middle') + print result == left_result, result == right_result#, 'XXX', left_result, 'YYY', result, 'ZZZ', right_result + if mid == 0: + assert result == right_result, '<<< ' + result + ' ??? ' + right_result + ' >>>' + print 'sanity check passed (a)' + if mid == high-1: + assert result == left_result, '<<< ' + result + ' ??? ' + left_result + ' >>>' + print 'sanity check passed (b)' + if result != right_result: + print 'found where it changes: %d' % mid found = mid break -critical = '\n'.join(chunks[found-1]) + '\n' - +critical = Popen(['diff', '-U', '5', 'middle' + str(mid-1), 'middle' + str(mid)], stdout=PIPE).communicate()[0] c = open('critical.diff', 'w') c.write(critical) c.close() -print 'sanity check' -shutil.copy('middle', 'middle2') -Popen(['patch', 'middle2', 'critical.diff'], stdout=PIPE, stderr=PIPE).communicate() -assert run_js('middle', stderr=PIPE) == left_result, 'middle was expected %s' % left_result -assert run_js('middle2', stderr=PIPE) != left_result, 'middle2 was expected NOT %s' % left_result - -print 'middle is like left, middle2 is like right, critical.diff is the difference that matters,' -print critical +print 'middle%d is like left, middle%d is like right, critical.diff is the difference that matters' % (mid-1, mid), 'diff:', critical diff --git a/tools/eliminator/asm-eliminator-test-output.js b/tools/eliminator/asm-eliminator-test-output.js new file mode 100644 index 00000000..3170bd9c --- /dev/null +++ b/tools/eliminator/asm-eliminator-test-output.js @@ -0,0 +1,103 @@ +function asm(x, y) { + x = +x; + y = y | 0; + var a = 0; + a = cheez(y + ~~x | 0) | 0; + fleefl(a * a | 0, a | 0); +} +function __Z11printResultPiS_j($needle, $haystack, $len) { + $needle = $needle | 0; + $haystack = $haystack | 0; + $len = $len | 0; + var $3 = 0, __stackBase__ = 0; + __stackBase__ = STACKTOP; + $3 = _bsearch($needle, $haystack, $len, 4, 2); + if (($3 | 0) == 0) { + _puts(_str | 0); + STACKTOP = __stackBase__; + return; + } else { + _printf(__str1 | 0, (tempInt = STACKTOP, STACKTOP = STACKTOP + 4 | 0, HEAP32[(tempInt & 16777215) >> 2] = HEAP32[($3 & 16777215) >> 2] | 0, tempInt)); + STACKTOP = __stackBase__; + return; + } +} +function _segment_holding($addr) { + $addr = $addr | 0; + var $sp_0 = 0, $3 = 0, $12 = 0, $_0 = 0, label = 0; + $sp_0 = __gm_ + 444 | 0; + while (1) { + $3 = HEAP32[(($sp_0 | 0) & 16777215) >> 2] | 0; + if (!($3 >>> 0 > $addr >>> 0)) { + if (($3 + (HEAP32[(($sp_0 + 4 | 0) & 16777215) >> 2] | 0) | 0) >>> 0 > $addr >>> 0) { + $_0 = $sp_0; + label = 1658; + break; + } + } + $12 = HEAP32[(($sp_0 + 8 | 0) & 16777215) >> 2] | 0; + if (($12 | 0) == 0) { + $_0 = 0; + label = 1659; + break; + } else { + $sp_0 = $12; + } + } + if (label == 1659) { + return $_0; + } else if (label == 1658) { + return $_0; + } +} +function __ZN5identC2EiPKcPci($this, $n, $a) { + $this = $this | 0; + $n = $n | 0; + $a = $a | 0; + HEAP32[($this & 16777215) >> 2] = __ZTV5ident + 8 | 0; + HEAP32[($this + 4 & 16777215) >> 2] = 5; + HEAP32[($this + 8 & 16777215) >> 2] = $n; + HEAP32[($this + 20 & 16777215) >> 2] = 2147483647; + HEAP32[($this + 24 & 16777215) >> 2] = 0; + HEAP32[($this + 28 & 16777215) >> 2] = $a; + HEAP32[($this + 32 & 16777215) >> 2] = 0; + HEAP32[($this + 40 & 16777215) >> 2] = 1; + return; +} +function _vec2Length($this) { + $this = $this | 0; + var $__first_addr_i = 0, $__last_addr_i = 0, __stackBase__ = 0; + __stackBase__ = STACKTOP; + STACKTOP = STACKTOP + 8 | 0; + $__first_addr_i = __stackBase__; + $__last_addr_i = __stackBase__ + 4; + STACKTOP = __stackBase__; + return 0; +} +function exc($this) { + $this = $this | 0; + var $1 = 0, $5 = 0; + $1 = (function() { + try { + __THREW__ = false; + return __ZNSt3__16locale8__globalEv(); + } catch (e) { + if (typeof e != "number") throw e; + if (ABORT) throw e; + __THREW__ = true; + Module.print("Exception: " + e + ", currently at: " + (new Error).stack); + return null; + } + })(); + if (!__THREW__) { + $5 = HEAP32[(($1 | 0) & 16777215) >> 2] | 0; + HEAP32[(($this | 0) & 16777215) >> 2] = $5; + __ZNSt3__114__shared_count12__add_sharedEv($5 | 0); + return; + } else { + $8$0 = ___cxa_find_matching_catch(HEAP32[(_llvm_eh_exception.buf & 16777215) >> 2] | 0, HEAP32[(_llvm_eh_exception.buf + 4 & 16777215) >> 2] | 0, []); + $8$1 = tempRet0; + ___cxa_call_unexpected($8$0); + } +} + diff --git a/tools/eliminator/asm-eliminator-test.js b/tools/eliminator/asm-eliminator-test.js new file mode 100644 index 00000000..ce34a7a6 --- /dev/null +++ b/tools/eliminator/asm-eliminator-test.js @@ -0,0 +1,134 @@ +function asm(x, y) { + x = +x; + y = y|0; + var a = 0, b = +0, c = 0; + var label = 0; + a = cheez((y+~~x)|0)|0; + b = a*a; + fleefl(b|0, a|0); +} +function __Z11printResultPiS_j($needle, $haystack, $len) { + $needle = $needle | 0; + $haystack = $haystack | 0; + $len = $len | 0; + var $1 = 0, $2 = 0, $3 = 0, $4 = 0, $puts = 0, $7 = 0, $8 = 0, $9 = 0; + var label = 0; + var __stackBase__ = 0; + __stackBase__ = STACKTOP; + $1 = $needle; + $2 = $haystack; + $3 = _bsearch($1, $2, $len, 4, 2); + $4 = ($3 | 0) == 0; + if ($4) { + $puts = _puts(_str | 0); + STACKTOP = __stackBase__; + return; + } else { + $7 = $3; + $8 = HEAP32[($7 & 16777215) >> 2] | 0; + $9 = _printf(__str1 | 0, (tempInt = STACKTOP, STACKTOP = STACKTOP + 4 | 0, HEAP32[(tempInt & 16777215) >> 2] = $8, tempInt)); + STACKTOP = __stackBase__; + return; + } +} +function _segment_holding($addr) { + $addr = $addr | 0; + var $sp_0 = 0, $2 = 0, $3 = 0, $4 = 0, $6 = 0, $7 = 0, $8 = 0, $9 = 0; + var $11 = 0, $12 = 0, $13 = 0, $_0 = 0; + var label = 0; + $sp_0 = __gm_ + 444 | 0; + while (1) { + $2 = $sp_0 | 0; + $3 = HEAP32[($2 & 16777215) >> 2] | 0; + $4 = $3 >>> 0 > $addr >>> 0; + if (!$4) { + $6 = $sp_0 + 4 | 0; + $7 = HEAP32[($6 & 16777215) >> 2] | 0; + $8 = $3 + $7 | 0; + $9 = $8 >>> 0 > $addr >>> 0; + if ($9) { + $_0 = $sp_0; + label = 1658; + break; + } + } + $11 = $sp_0 + 8 | 0; + $12 = HEAP32[($11 & 16777215) >> 2] | 0; + $13 = ($12 | 0) == 0; + if ($13) { + $_0 = 0; + label = 1659; + break; + } else { + $sp_0 = $12; + } + } + if (label == 1659) { + return $_0; + } else if (label == 1658) { + return $_0; + } +} +function __ZN5identC2EiPKcPci($this, $n, $a) { + $this = $this | 0; + $n = $n | 0; + $a = $a | 0; + HEAP32[($this & 16777215) >> 2] = __ZTV5ident + 8 | 0; + HEAP32[($this + 4 & 16777215) >> 2] = 5; + HEAP32[($this + 8 & 16777215) >> 2] = $n; + HEAP32[($this + 20 & 16777215) >> 2] = 2147483647; + HEAP32[($this + 24 & 16777215) >> 2] = 0; + HEAP32[($this + 28 & 16777215) >> 2] = $a; + HEAP32[($this + 32 & 16777215) >> 2] = 0; + HEAP32[($this + 40 & 16777215) >> 2] = 1; + return; +} +function _vec2Length($this) { + $this = $this | 0; + var $__first_addr_i = 0, $__last_addr_i = 0, $__comp_addr_i = 0, $a13 = 0, $a14 = 0, $a18 = 0, $a19 = 0; + var label = 0; + var __stackBase__ = 0; + __stackBase__ = STACKTOP; + STACKTOP = STACKTOP + 8 | 0; + $__first_addr_i = __stackBase__; + $__last_addr_i = __stackBase__ + 4; + $a13 = $__first_addr_i; + $a14 = $__last_addr_i; + $a18 = $__first_addr_i; + $a19 = $__last_addr_i; + STACKTOP = __stackBase__; + return 0; +} +function exc($this) { + $this = $this | 0; + var $1 = 0, $3 = 0, $4 = 0, $5 = 0, $6 = 0, $8 = +0, $9 = 0; + var label = 0; + var $1 = (function() { + try { + __THREW__ = false; + return __ZNSt3__16locale8__globalEv(); + } catch (e) { + if (typeof e != "number") throw e; + if (ABORT) throw e; + __THREW__ = true; + Module.print("Exception: " + e + ", currently at: " + (new Error).stack); + return null; + } + })(); + if (!__THREW__) { + $3 = $this | 0; + $4 = $1 | 0; + $5 = HEAP32[($4 & 16777215) >> 2] | 0; + HEAP32[($3 & 16777215) >> 2] = $5; + $6 = $5 | 0; + __ZNSt3__114__shared_count12__add_sharedEv($6); + return; + } else { + $8$0 = ___cxa_find_matching_catch(HEAP32[(_llvm_eh_exception.buf & 16777215) >> 2] | 0, HEAP32[(_llvm_eh_exception.buf + 4 & 16777215) >> 2] | 0, []); + $8$1 = tempRet0; + $9 = $8$0; + ___cxa_call_unexpected($9); + } +} +// EMSCRIPTEN_GENERATED_FUNCTIONS: ["asm", "__Z11printResultPiS_j", "_segment_holding", "__ZN5identC2EiPKcPci", "_vec2Length", "exc"] + diff --git a/tools/eliminator/eliminator-test-output.js b/tools/eliminator/eliminator-test-output.js index 37a5d104..a005a0a5 100644 --- a/tools/eliminator/eliminator-test-output.js +++ b/tools/eliminator/eliminator-test-output.js @@ -6132,6 +6132,14 @@ function _mallocNoU($bytes) { return $mem_0; return null; } +function asm(x, y) { + x = +x; + y = y | 0; + var a = 0, b = +0; + a = cheez(y + ~~x | 0) | 0; + b = a * a; + fleefl(b | 0, a | 0); +} function phi() { if (wat()) { var $10 = 1; diff --git a/tools/eliminator/eliminator-test.js b/tools/eliminator/eliminator-test.js index 32bb9d5b..13ecab59 100644 --- a/tools/eliminator/eliminator-test.js +++ b/tools/eliminator/eliminator-test.js @@ -8828,6 +8828,15 @@ function _mallocNoU($bytes) { return $mem_0; return null; } +function asm(x, y) { // asm-style code, without special asm requested so will not be fully optimized + x = +x; + y = y|0; + var a = 0, b = +0, c = 0; + var label = 0; + a = cheez((y+~~x)|0)|0; + b = a*a; + fleefl(b|0, a|0); +} function phi() { if (wat()) { var $10 = 1; diff --git a/tools/js-optimizer.js b/tools/js-optimizer.js index dbef9c0c..ed9aa46d 100644 --- a/tools/js-optimizer.js +++ b/tools/js-optimizer.js @@ -263,6 +263,10 @@ function emptyNode() { // XXX do we need to create new nodes here? can't we reus return ['toplevel', []] } +function isEmptyNode(node) { + return node.length == 2 && node[0] == 'toplevel' && node[1].length == 0; +} + // Passes // Dump the AST. Useful for debugging. For example, @@ -400,7 +404,7 @@ function removeUnneededLabelSettings(ast) { // Various expression simplifications. Pre run before closure (where we still have metadata), Post run after. -function simplifyExpressionsPre(ast) { +function simplifyExpressionsPre(ast, asm) { // When there is a bunch of math like (((8+5)|0)+12)|0, only the external |0 is needed, one correction is enough. // At each node, ((X|0)+Y)|0 can be transformed into (X+Y): The inner corrections are not needed // TODO: Is the same is true for 0xff, 0xffff? @@ -409,25 +413,36 @@ function simplifyExpressionsPre(ast) { function simplifyBitops(ast) { var USEFUL_BINARY_OPS = set('<<', '>>', '|', '&', '^'); - var SAFE_BINARY_OPS = set('+', '-', '*', '%'); // division is unsafe as it creates non-ints in JS + var SAFE_BINARY_OPS = set('+', '-', '*'); // division is unsafe as it creates non-ints in JS; mod is unsafe as signs matter so we can't remove |0's var ZERO = ['num', 0]; var rerun = true; while (rerun) { rerun = false; - traverseGenerated(ast, function(node, type, stack) { - if (type == 'binary' && node[1] == '|' && (jsonCompare(node[2], ZERO) || jsonCompare(node[3], ZERO))) { - stack.push(1); // From here on up, no need for this kind of correction, it's done at the top - - // We might be able to remove this correction - for (var i = stack.length-2; i >= 0; i--) { - if (stack[i] == 1) { - // Great, we can eliminate - rerun = true; - return jsonCompare(node[2], ZERO) ? node[3] : node[2]; - } else if (stack[i] == -1) { - break; // Too bad, we can't + traverseGenerated(ast, function process(node, type, stack) { + if (type == 'binary' && node[1] == '|') { + if (node[2][0] == 'num' && node[3][0] == 'num') { + return ['num', node[2][1] | node[3][1]]; + } else if (jsonCompare(node[2], ZERO) || jsonCompare(node[3], ZERO)) { + // We might be able to remove this correction + for (var i = stack.length-1; i >= 0; i--) { + if (stack[i] == 1) { + // we will replace ourselves with the non-zero side. Recursively process that node. + var result = jsonCompare(node[2], ZERO) ? node[3] : node[2], other; + // Great, we can eliminate + rerun = true; + while (other = process(result, result[0], stack)) { + result = other; + } + return result; + } else if (stack[i] == -1) { + break; // Too bad, we can't + } else if (asm) { + break; // we must keep a coercion right on top of a heap access in asm mode + } } } + stack.push(1); // From here on up, no need for this kind of correction, it's done at the top + // (Add this at the end, so it is only added if we did not remove it) } else if (type == 'binary' && node[1] in USEFUL_BINARY_OPS) { stack.push(1); } else if ((type == 'binary' && node[1] in SAFE_BINARY_OPS) || type == 'num' || type == 'name') { @@ -437,6 +452,33 @@ function simplifyExpressionsPre(ast) { } }, null, []); } + + // &-related optimizations + traverseGenerated(ast, function(node, type) { + if (type == 'binary' && node[1] == '&' && node[3][0] == 'num') { + if (node[2][0] == 'num') return ['num', node[2][1] & node[3][1]]; + var input = node[2]; + var amount = node[3][1]; + if (input[0] == 'binary' && input[1] == '&' && input[3][0] == 'num') { + // Collapse X & 255 & 1 + node[3][1] = amount & input[3][1]; + node[2] = input[2]; + } else if (input[0] == 'sub' && input[1][0] == 'name') { + // HEAP8[..] & 255 => HEAPU8[..] + var name = input[1][1]; + if (name.substr(0, 4) == 'HEAP') { + var unsigned = name[4] == 'U'; + var bits = parseInt(name.substr(unsigned ? 5 : 4)); + if (amount == Math.pow(2, bits)-1) { + if (!unsigned) { + input[1][1] = 'HEAPU' + bits; // make unsigned + } + return input; + } + } + } + } + }); } // The most common mathop is addition, e.g. in getelementptr done repeatedly. We can join all of those, @@ -487,6 +529,10 @@ function simplifyExpressionsPre(ast) { // simplifyZeroComp(ast); TODO: investigate performance } +function simplifyExpressionsPreAsm(ast) { + simplifyExpressionsPre(ast, true); +} + // In typed arrays mode 2, we can have // HEAP[x >> 2] // very often. We can in some cases do the shift on the variable itself when it is set, @@ -1197,39 +1243,182 @@ function loopOptimizer(ast) { vacuum(ast); } +function unVarify(vars, ret) { // transform var x=1, y=2 etc. into (x=1, y=2), i.e., the same assigns, but without a var definition + ret = ret || []; + ret[0] = 'stat'; + if (vars.length == 1) { + ret[1] = ['assign', true, ['name', vars[0][0]], vars[0][1]]; + } else { + ret[1] = []; + var curr = ret[1]; + for (var i = 0; i < vars.length-1; i++) { + curr[0] = 'seq'; + curr[1] = ['assign', true, ['name', vars[i][0]], vars[i][1]]; + if (i != vars.length-2) curr = curr[2] = []; + } + curr[2] = ['assign', true, ['name', vars[vars.length-1][0]], vars[vars.length-1][1]]; + } + return ret; +} + +// asm.js support code - normalize (convert asm.js code to 'normal' JS, without +// annotations, plus explicit metadata) and denormalize (vice versa) +var ASM_INT = 0; +var ASM_DOUBLE = 1; + +function detectAsmCoercion(node) { + // for params, +x vs x|0, for vars, 0.0 vs 0 + if (node[0] == 'num' && node[1].toString().indexOf('.') >= 0) return ASM_DOUBLE; + return node[0] == 'unary-prefix' ? ASM_DOUBLE : ASM_INT; +} + +function makeAsmParamCoercion(param, type) { + return type == ASM_INT ? ['binary', '|', ['name', param], ['num', 0]] : ['unary-prefix', '+', ['name', param]]; +} + +function makeAsmVarDef(v, type) { + return [v, type == ASM_INT ? ['num', 0] : ['unary-prefix', '+', ['num', 0]]]; +} + +function normalizeAsm(func) { + //printErr('pre-normalize \n\n' + astToSrc(func) + '\n\n'); + var data = { + params: {}, // ident => ASM_* type + vars: {}, // ident => ASM_* type + }; + // process initial params + var stats = func[3]; + var i = 0; + while (i < stats.length) { + var node = stats[i]; + if (node[0] != 'stat' || node[1][0] != 'assign' || node[1][2][0] != 'name') break; + node = node[1]; + data.params[node[2][1]] = detectAsmCoercion(node[3]); + stats[i] = emptyNode(); + i++; + } + // process initial variable definitions + outer: + while (i < stats.length) { + var node = stats[i]; + if (node[0] != 'var') break; + for (var j = 0; j < node[1].length; j++) { + var v = node[1][j]; + var name = v[0]; + var value = v[1]; + if (!(name in data.vars)) { + assert(value[0] == 'num' || (value[0] == 'unary-prefix' && value[2][0] == 'num')); // must be valid coercion no-op + data.vars[name] = detectAsmCoercion(value); + v.length = 1; // make an un-assigning var + } else { + break outer; + } + } + i++; + } + // finally, look for other var definitions and collect them + while (i < stats.length) { + traverse(stats[i], function(node, type) { + if (type == 'var') { + unVarify(node[1], node); + } else if (type == 'dot') { + if (node[1][0] == 'name' && node[1][1] == 'Math') { + // transform Math.max to Math_max; we forward in the latter version + node[0] = 'name'; + node[1] = 'Math_' + node[2]; + } + } + }); + i++; + } + //printErr('normalized \n\n' + astToSrc(func) + '\n\nwith: ' + JSON.stringify(data)); + return data; +} + +function denormalizeAsm(func, data) { + //printErr('pre-denormalize \n\n' + astToSrc(func) + '\n\nwith: ' + JSON.stringify(data)); + var stats = func[3]; + // Remove var definitions, if any + for (var i = 0; i < stats.length; i++) { + if (stats[i][0] == 'var') { + stats[i] = emptyNode(); + } else { + if (!isEmptyNode(stats[i])) break; + } + } + // each param needs a line; reuse emptyNodes as much as we can + var numParams = 0; + for (var i in data.params) numParams++; + var emptyNodes = 0; + while (emptyNodes < stats.length) { + if (!isEmptyNode(stats[emptyNodes])) break; + emptyNodes++; + } + var neededEmptyNodes = numParams + 1; // params plus one big var + if (neededEmptyNodes > emptyNodes) { + var args = [0, 0]; + for (var i = 0; i < neededEmptyNodes - emptyNodes; i++) args[i+2] = 0; + stats.splice.apply(stats, args); + } + // add param coercions + var next = 0; + func[2].forEach(function(param) { + stats[next++] = ['stat', ['assign', true, ['name', param], makeAsmParamCoercion(param, data.params[param])]]; + }); + // add variable definitions + var varDefs = []; + for (var v in data.vars) { + varDefs.push(makeAsmVarDef(v, data.vars[v])); + } + if (varDefs.length) { + stats[next] = ['var', varDefs]; + } else { + stats[next] = emptyNode(); + } + //printErr('denormalized \n\n' + astToSrc(func) + '\n\n'); +} + // Very simple 'registerization', coalescing of variables into a smaller number. // We do not optimize when there are switches, so this pass only makes sense with // relooping. // TODO: Consider how this fits in with the rest of the optimization toolchain. Do // we still need the eliminator? Closure? And in what order? Perhaps just // closure simple? -function registerize(ast) { +function registerize(ast, asm) { traverseGeneratedFunctions(ast, function(fun) { + if (asm) var asmData = normalizeAsm(fun); + // Add parameters as a first (fake) var (with assignment), so they get taken into consideration + var params = {}; // note: params are special, they can never share a register between them (see later) + if (fun[2] && fun[2].length) { + var assign = ['num', 0]; + fun[3].unshift(['var', fun[2].map(function(param) { + params[param] = 1; + return [param, assign]; + })]); + } + if (asm) { + // copy params into vars + for (var p in asmData.params) asmData.vars[p] = asmData.params[p]; + //printErr('fake params: \n\n' + astToSrc(fun) + '\n\n'); + } // Replace all var definitions with assignments; we will add var definitions at the top after we registerize // We also mark local variables - i.e., having a var definition var localVars = {}; var hasSwitch = false; // we cannot optimize variables if there is a switch + var hasReturnValue = false; traverse(fun, function(node, type) { if (type == 'var') { node[1].forEach(function(defined) { localVars[defined[0]] = 1 }); var vars = node[1].filter(function(varr) { return varr[1] }); - if (vars.length > 1) { - var ret = ['stat', []]; - var curr = ret[1]; - for (var i = 0; i < vars.length-1; i++) { - curr[0] = 'seq'; - curr[1] = ['assign', true, ['name', vars[i][0]], vars[i][1]]; - if (i != vars.length-2) curr = curr[2] = []; - } - curr[2] = ['assign', true, ['name', vars[vars.length-1][0]], vars[vars.length-1][1]]; - return ret; - } else if (vars.length == 1) { - return ['stat', ['assign', true, ['name', vars[0][0]], vars[0][1]]]; + if (vars.length >= 1) { + return unVarify(vars); } else { return emptyNode(); } } else if (type == 'switch') { hasSwitch = true; + } else if (asm && type == 'return' && node[1]) { + hasReturnValue = true; } }); vacuum(fun); @@ -1293,7 +1482,7 @@ function registerize(ast) { // we just use a fresh register to make sure we avoid this, but it could be // optimized to check for safe registers (free, and not used in this loop level). var varRegs = {}; // maps variables to the register they will use all their life - var freeRegs = []; + var freeRegsClasses = asm ? [[], []] : []; // two classes for asm, one otherwise var nextReg = 1; var fullNames = {}; var loopRegs = {}; // for each loop nesting level, the list of bound variables @@ -1301,18 +1490,24 @@ function registerize(ast) { var saved = 0; var activeOptimizables = {}; var optimizableLoops = {}; + var paramRegs = {}; // true if the register is used by a parameter (and so needs no def at start of function; also cannot + // be shared with another param, each needs its own) function decUse(name) { if (!varUses[name]) return false; // no uses left, or not a relevant variable if (optimizables[name]) activeOptimizables[name] = 1; var reg = varRegs[name]; + if (asm) assert(name in asmData.vars, name); + var freeRegs = asm ? freeRegsClasses[asmData.vars[name]] : freeRegsClasses; if (!reg) { // acquire register - if (optimizables[name] && freeRegs.length > 0) { + if (optimizables[name] && freeRegs.length > 0 && + !(params[name] && paramRegs[freeRegs[freeRegs.length-1]])) { // do not share registers between parameters reg = freeRegs.pop(); saved++; } else { reg = nextReg++; - fullNames[reg] = 'r' + reg; // TODO: even smaller names + fullNames[reg] = (asm ? (asmData.vars[name] ? 'd' : 'i') : 'r') + reg; // TODO: even smaller names + if (params[name]) paramRegs[reg] = 1; } varRegs[name] = reg; } @@ -1353,24 +1548,70 @@ function registerize(ast) { if (type in LOOP) { // Free registers that were locked to this loop if (loopRegs[loops]) { - freeRegs = freeRegs.concat(loopRegs[loops]); - loopRegs[loops] = []; + if (asm) { + loopRegs[loops].forEach(function(loopReg) { + freeRegsClasses[fullNames[loopReg][0] == 'i' ? ASM_INT : ASM_DOUBLE].push(loopReg); + }); + } else { + freeRegsClasses = freeRegsClasses.concat(loopRegs[loops]); + } + loopRegs[loops].length = 0; } loops--; } }); - // Add vars at the beginning - if (nextReg > 1) { - var vars = []; + if (fun[2] && fun[2].length) { + fun[2].length = 0; // clear params, we will fill with registers + fun[3].shift(); // remove fake initial var + } + //printErr('var regs: ' + JSON.stringify(varRegs) + '\n\nparam regs: ' + JSON.stringify(paramRegs)); + if (!asm) { + if (nextReg > 1) { + var vars = []; + for (var i = 1; i < nextReg; i++) { + var reg = fullNames[i]; + if (!paramRegs[i]) { + vars.push([reg]); + } else { + fun[2].push(reg); + } + } + getStatements(fun).unshift(['var', vars]); + } + } else { + //printErr('unfake params: \n\n' + astToSrc(fun) + '\n\n'); + var finalAsmData = { + params: {}, + vars: {}, + }; for (var i = 1; i < nextReg; i++) { - vars.push([fullNames[i]]); + var reg = fullNames[i]; + var type = reg[0] == 'i' ? ASM_INT : ASM_DOUBLE + if (!paramRegs[i]) { + finalAsmData.vars[reg] = type; + } else { + finalAsmData.params[reg] = type; + fun[2].push(reg); + } + } + denormalizeAsm(fun, finalAsmData); + // Add a final return if one is missing. This is not strictly a register operation, but + // this pass traverses the entire AST anyhow so adding it here is efficient. + if (hasReturnValue) { + var stats = getStatements(fun); + var last = stats[stats.length-1]; + if (last[0] != 'return') { + stats.push(['return', ['num', 0]]); + } } - getStatements(fun).unshift(['var', vars]); } - //printErr(fun[1] + ': saved ' + saved + ' / ' + (saved + nextReg - 1) + ' vars through registerization'); // not totally accurate }); } +function registerizeAsm(ast) { + registerize(ast, true); +} + // Eliminator aka Expressionizer // // The goal of this pass is to eliminate unneeded variables (which represent one of the infinite registers in the LLVM @@ -1408,9 +1649,10 @@ var NODES_WITHOUT_ELIMINATION_SIDE_EFFECTS = set('name', 'num', 'string', 'binar var IGNORABLE_ELIMINATOR_SCAN_NODES = set('num', 'toplevel', 'string', 'break', 'continue', 'dot'); // dot can only be STRING_TABLE.* var ABORTING_ELIMINATOR_SCAN_NODES = set('new', 'object', 'function', 'defun', 'switch', 'for', 'while', 'array', 'throw'); // we could handle some of these, TODO, but nontrivial (e.g. for while, the condition is hit multiple times after the body) -function eliminate(ast, memSafe) { +function eliminate(ast, memSafe, asm) { // Find variables that have a single use, and if they can be eliminated, do so traverseGeneratedFunctions(ast, function(func, type) { + if (asm) var asmData = normalizeAsm(func); //printErr('eliminate in ' + func[1]); // First, find the potentially eliminatable functions: that have one definition and one use @@ -1418,7 +1660,7 @@ function eliminate(ast, memSafe) { var uses = {}; var values = {}; var locals = {}; - var varsToRemove = {}; // variables being removed, that we can eliminate all 'var x;' of + var varsToRemove = {}; // variables being removed, that we can eliminate all 'var x;' of (this refers to 'var' nodes we should remove) var varsToTryToRemove = {}; // variables that have 0 uses, but have side effects - when we scan we can try to remove them // add arguments as locals if (func[2]) { @@ -1435,7 +1677,7 @@ function eliminate(ast, memSafe) { var name = node1i[0]; var value = node1i[1]; if (value) { - if (!definitions[name]) definitions[name] = 0; + if (!(name in definitions)) definitions[name] = 0; definitions[name]++; if (!values[name]) values[name] = value; } @@ -1450,7 +1692,7 @@ function eliminate(ast, memSafe) { var target = node[2]; if (target[0] == 'name') { var name = target[1]; - if (!definitions[name]) definitions[name] = 0; + if (!(name in definitions)) definitions[name] = 0; definitions[name]++; if (!uses[name]) uses[name] = 0; if (!values[name]) values[name] = node[3]; @@ -1461,6 +1703,7 @@ function eliminate(ast, memSafe) { } }); var potentials = {}; // local variables with 1 definition and 1 use + var sideEffectFree = {}; // whether a local variable has no side effects in its definition for (var name in locals) { if (definitions[name] == 1 && uses[name] == 1) { potentials[name] = 1; @@ -1476,6 +1719,7 @@ function eliminate(ast, memSafe) { } if (!hasSideEffects) { varsToRemove[name] = 1; // remove it normally + sideEffectFree[name] = true; } else { varsToTryToRemove[name] = 1; // try to remove it later during scanning } @@ -1483,10 +1727,11 @@ function eliminate(ast, memSafe) { } //printErr('defs: ' + JSON.stringify(definitions)); //printErr('uses: ' + JSON.stringify(uses)); + //printErr('values: ' + JSON.stringify(values)); //printErr('locals: ' + JSON.stringify(locals)); //printErr('varsToRemove: ' + JSON.stringify(varsToRemove)); - //printErr('2varsToTryToRemove: ' + JSON.stringify(varsToTryToRemove)); - definitions = uses = values = null; + //printErr('varsToTryToRemove: ' + JSON.stringify(varsToTryToRemove)); + definitions = values = null; //printErr('potentials: ' + JSON.stringify(potentials)); // We can now proceed through the function. In each list of statements, we try to eliminate var tracked = {}; @@ -1618,6 +1863,12 @@ function eliminate(ast, memSafe) { invalidateGlobals(); globalsInvalidated = true; } + // if we can track this name (that we assign into), and it has 0 uses and we want to remove its 'var' + // definition - then remove it right now, there is no later chance + if (allowTracking && (name in varsToRemove) && uses[name] == 0) { + track(name, node[3], node); + doEliminate(name, node); + } } else { // replace it in-place node.length = value.length; @@ -1772,24 +2023,31 @@ function eliminate(ast, memSafe) { var info = tracked[name]; delete tracked[name]; var defNode = info.defNode; - if (defNode[0] == 'var') { - defNode[1].forEach(function(pair) { - if (pair[0] == name) { - value = pair[1]; - } - }); - assert(value); - } else { // assign - value = defNode[3]; - // wipe out the assign - defNode[0] = 'toplevel'; - defNode[1] = []; - defNode.length = 2; - } - // replace this node in-place - node.length = 0; - for (var i = 0; i < value.length; i++) { - node[i] = value[i]; + if (!sideEffectFree[name]) { + if (defNode[0] == 'var') { + defNode[1].forEach(function(pair) { + if (pair[0] == name) { + value = pair[1]; + } + }); + assert(value); + } else { // assign + value = defNode[3]; + // wipe out the assign + defNode[0] = 'toplevel'; + defNode[1] = []; + defNode.length = 2; + } + // replace this node in-place + node.length = 0; + for (var i = 0; i < value.length; i++) { + node[i] = value[i]; + } + } else { + // empty it out in-place + node.length = 0; + node[0] = 'toplevel'; + node[1] = []; } } traverse(func, function(block) { @@ -1812,6 +2070,7 @@ function eliminate(ast, memSafe) { tracked = {}; // not a var or assign, break all potential elimination so far } } + //printErr('delete StatBlock'); }); // clean up vars @@ -1826,6 +2085,13 @@ function eliminate(ast, memSafe) { } } }); + + if (asm) { + for (var v in varsToRemove) { + delete asmData.vars[v]; + } + denormalizeAsm(func, asmData); + } }); // A class for optimizing expressions. We know that it is legitimate to collapse @@ -1876,6 +2142,10 @@ function eliminateMemSafe(ast) { eliminate(ast, true); } +function eliminateAsm(ast) { + eliminate(ast, false, true); +} + // Passes table var compress = false, printMetadata = true; @@ -1887,14 +2157,17 @@ var passes = { removeAssignsToUndefined: removeAssignsToUndefined, //removeUnneededLabelSettings: removeUnneededLabelSettings, simplifyExpressionsPre: simplifyExpressionsPre, + simplifyExpressionsPreAsm: simplifyExpressionsPreAsm, optimizeShiftsConservative: optimizeShiftsConservative, optimizeShiftsAggressive: optimizeShiftsAggressive, simplifyExpressionsPost: simplifyExpressionsPost, hoistMultiples: hoistMultiples, loopOptimizer: loopOptimizer, registerize: registerize, + registerizeAsm: registerizeAsm, eliminate: eliminate, eliminateMemSafe: eliminateMemSafe, + eliminateAsm: eliminateAsm, compress: function() { compress = true; }, noPrintMetadata: function() { printMetadata = false; } }; @@ -1911,7 +2184,6 @@ if (metadata) setGeneratedFunctions(metadata); arguments_.slice(1).forEach(function(arg) { passes[arg](ast); }); - var js = astToSrc(ast, compress), old; // remove unneeded newlines+spaces, and print diff --git a/tools/js_optimizer.py b/tools/js_optimizer.py index 3f978605..b72a2084 100644 --- a/tools/js_optimizer.py +++ b/tools/js_optimizer.py @@ -54,7 +54,7 @@ def run_on_js(filename, passes, js_engine, jcache): jcache = False # If we process only generated code, find that and save the rest on the side - func_sig = re.compile('function (_[\w$]+)\(') + func_sig = re.compile('( *)function (_[\w$]+)\(') if suffix: pos = 0 gen_start = 0 @@ -63,12 +63,13 @@ def run_on_js(filename, passes, js_engine, jcache): m = func_sig.search(js, pos) if not m: break pos = m.end() - ident = m.group(1) + indent = m.group(1) + ident = m.group(2) if ident in generated: if not gen_start: gen_start = m.start() assert gen_start - gen_end = js.find('\n}\n', m.end()) + 3 + gen_end = js.find('\n%s}\n' % indent, m.end()) + (3 + len(indent)) assert gen_end > gen_start pre = js[:gen_start] post = js[gen_end:] @@ -116,7 +117,7 @@ def run_on_js(filename, passes, js_engine, jcache): if len(chunks) > 0: def write_chunk(chunk, i): - temp_file = temp_files.get('.jsfunc_%d.ll' % i).name + temp_file = temp_files.get('.jsfunc_%d.js' % i).name f = open(temp_file, 'w') f.write(chunk) f.write(suffix) @@ -129,6 +130,7 @@ def run_on_js(filename, passes, js_engine, jcache): if len(filenames) > 0: # XXX Use '--nocrankshaft' to disable crankshaft to work around v8 bug 1895, needed for older v8/node (node 0.6.8+ should be ok) commands = map(lambda filename: [js_engine, JS_OPTIMIZER, filename, 'noPrintMetadata'] + passes, filenames) + #print [' '.join(command) for command in commands] cores = min(multiprocessing.cpu_count(), filenames) if len(chunks) > 1 and cores >= 2: diff --git a/tools/shared.py b/tools/shared.py index ede0d741..a78db8e0 100644 --- a/tools/shared.py +++ b/tools/shared.py @@ -172,7 +172,7 @@ def check_node_version(): # we re-check sanity when the settings are changed) # We also re-check sanity and clear the cache when the version changes -EMSCRIPTEN_VERSION = '1.1.0' +EMSCRIPTEN_VERSION = '1.2.3' def check_sanity(force=False): try: @@ -446,7 +446,7 @@ def check_engine(engine): print 'Checking JS engine %s failed. Check %s. Details: %s' % (str(engine), EM_CONFIG, str(e)) return False -def timeout_run(proc, timeout, note='unnamed process'): +def timeout_run(proc, timeout, note='unnamed process', full_output=False): start = time.time() if timeout is not None: while time.time() - start < timeout and proc.poll() is None: @@ -454,13 +454,14 @@ def timeout_run(proc, timeout, note='unnamed process'): if proc.poll() is None: proc.kill() # XXX bug: killing emscripten.py does not kill it's child process! raise Exception("Timed out: " + note) - return proc.communicate()[0] + out = proc.communicate() + return '\n'.join(out) if full_output else out[0] -def run_js(filename, engine=None, args=[], check_timeout=False, stdout=PIPE, stderr=None, cwd=None): +def run_js(filename, engine=None, args=[], check_timeout=False, stdout=PIPE, stderr=None, cwd=None, full_output=False): if engine is None: engine = JS_ENGINES[0] if type(engine) is not list: engine = [engine] command = engine + [filename] + (['--'] if 'd8' in engine[0] else []) + args - return timeout_run(Popen(command, stdout=stdout, stderr=stderr, cwd=cwd), 15*60 if check_timeout else None, 'Execution') + return timeout_run(Popen(command, stdout=stdout, stderr=stderr, cwd=cwd), 15*60 if check_timeout else None, 'Execution', full_output=full_output) def to_cc(cxx): # By default, LLVM_GCC and CLANG are really the C++ versions. This gets an explicit C version @@ -1126,7 +1127,7 @@ set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)''' % { 'winfix': '' if not WINDOWS e Building.emcc(os.path.join('relooper', 'Relooper.cpp'), ['-I' + os.path.join('relooper'), '--post-js', os.path.join('relooper', 'emscripten', 'glue.js'), '-s', 'TOTAL_MEMORY=52428800', - '-s', 'EXPORTED_FUNCTIONS=["_rl_set_output_buffer","_rl_make_output_buffer","_rl_new_block","_rl_delete_block","_rl_block_add_branch_to","_rl_new_relooper","_rl_delete_relooper","_rl_relooper_add_block","_rl_relooper_calculate","_rl_relooper_render"]', + '-s', 'EXPORTED_FUNCTIONS=["_rl_set_output_buffer","_rl_make_output_buffer","_rl_new_block","_rl_delete_block","_rl_block_add_branch_to","_rl_new_relooper","_rl_delete_relooper","_rl_relooper_add_block","_rl_relooper_calculate","_rl_relooper_render", "_rl_set_asm_js_mode"]', '-s', 'DEFAULT_LIBRARY_FUNCS_TO_INCLUDE=["memcpy", "memset", "malloc", "free", "puts"]', '-O' + str(opt_level), '--closure', '0'], raw) f = open(RELOOPER, 'w') diff --git a/tools/test-js-optimizer-asm-pre-output.js b/tools/test-js-optimizer-asm-pre-output.js new file mode 100644 index 00000000..afd43893 --- /dev/null +++ b/tools/test-js-optimizer-asm-pre-output.js @@ -0,0 +1,8 @@ +function a() { + f((HEAPU8[10202] | 0) + 5 | 0); + f(HEAPU8[10202] | 0); + f(347); + f(351); + f(8); +} + diff --git a/tools/test-js-optimizer-asm-pre.js b/tools/test-js-optimizer-asm-pre.js new file mode 100644 index 00000000..6c9e64c1 --- /dev/null +++ b/tools/test-js-optimizer-asm-pre.js @@ -0,0 +1,8 @@ +function a() { + f((HEAPU8[10202] | 0) + 5 | 0); + f((HEAPU8[10202] | 0) | 0); + f(347 | 0); + f(347 | 12); + f(347 & 12); +} +// EMSCRIPTEN_GENERATED_FUNCTIONS: ["a"] diff --git a/tools/test-js-optimizer-asm-regs-output.js b/tools/test-js-optimizer-asm-regs-output.js new file mode 100644 index 00000000..26d1d134 --- /dev/null +++ b/tools/test-js-optimizer-asm-regs-output.js @@ -0,0 +1,34 @@ +function asm(d1, i2) { + d1 = +d1; + i2 = i2 | 0; + var i3 = 0, d4 = +0; + i2 = d1 + d1 | 0; + d1 = d(Math_max(10, Math_min(5, f()))); + i3 = i2 + 2 | 0; + print(i3); + d4 = d1 * 5; + return d4; +} +function _doit(i1, i2, i3) { + i1 = i1 | 0; + i2 = i2 | 0; + i3 = i3 | 0; + i1 = STACKTOP; + _printf(__str | 0, (tempInt = STACKTOP, STACKTOP = STACKTOP + 8 | 0, HEAP32[(tempInt & 16777215) >> 2] = i2, HEAP32[(tempInt + 4 & 16777215) >> 2] = i3, tempInt)); + STACKTOP = i1; + return 0 | 0; +} +function rett() { + if (f()) { + g(); + return 5; + } + return 0; +} +function ret2t() { + if (f()) { + g(); + return; + } +} + diff --git a/tools/test-js-optimizer-asm-regs.js b/tools/test-js-optimizer-asm-regs.js new file mode 100644 index 00000000..9192f32e --- /dev/null +++ b/tools/test-js-optimizer-asm-regs.js @@ -0,0 +1,38 @@ +function asm(x, y) { + x = +x; + y = y | 0; + var int1 = 0, int2 = 0; // do not mix the types! + var double1 = +0, double2 = +0; + int1 = (x+x)|0; + double1 = d(Math.max(10, Math_min(5, f()))); + int2 = (int1+2)|0; + print(int2); + double2 = double1*5; + return double2; +} +function _doit($x, $y$0, $y$1) { + $x = $x | 0; + $y$0 = $y$0 | 0; + $y$1 = $y$1 | 0; + var __stackBase__ = 0; + __stackBase__ = STACKTOP; + _printf(__str | 0, (tempInt = STACKTOP, STACKTOP = STACKTOP + 8 | 0, HEAP32[(tempInt & 16777215) >> 2] = $y$0, HEAP32[(tempInt + 4 & 16777215) >> 2] = $y$1, tempInt)); + STACKTOP = __stackBase__; + return 0 | 0; +} +function rett() { + if (f()) { + g(); + return 5; + } + // missing final return, need to add it +} +function ret2t() { + if (f()) { + g(); + return; + } + // missing final return, but no need +} +// EMSCRIPTEN_GENERATED_FUNCTIONS: ["asm", "_doit", "rett", "ret2t"] + diff --git a/tools/test-js-optimizer-output.js b/tools/test-js-optimizer-output.js index 730426b1..5c06475e 100644 --- a/tools/test-js-optimizer-output.js +++ b/tools/test-js-optimizer-output.js @@ -42,7 +42,7 @@ function ignoreLoopy() { } } function bits() { - print(($s & 65535) + (($f & 65535) << 16 >> 16) * (($f & 65535) << 16 >> 16) % 256 & 65535); + print(($s & 65535) + ((($f & 65535) << 16 >> 16) * (($f & 65535) << 16 >> 16) | 0) % 256 & 65535); z(HEAP32[$id + 40 >> 2]); z($f << 2); z($f | 255); @@ -50,7 +50,7 @@ function bits() { z($f ^ 1); z($f << 2); z($f * 100 << 2); - z($f % 2 | 255); + z(($f | 0) % 2 | 255); z(($f | 0) / 55 & 255); z($f - 22 ^ 1); z($f + 15 << 2); @@ -279,4 +279,19 @@ function notComps() { function tricky() { var $conv642 = $conv6374 - (($132 << 16 >> 16 | 0) / 2 & -1) & 65535; } +function asmy() { + f(HEAPU8[_buf + i6 & 16777215]); + f(HEAPU8[_buf + i6 & 16777215]); + f(HEAP8[_buf + i6 & 16777215] & 1); + f(HEAPU8[_buf + i6 & 16777215] & 1); + f(HEAP8[_buf + i6 & 16777215] & 1); + f(HEAPU8[_buf + i6 & 16777215] & 1); + f((HEAP8[_buf + i6 & 16777215] & 1) + i5 | 0); + f((HEAPU8[_buf + i6 & 16777215] & 1) + i5 | 0); + f((HEAP8[_buf + i6 & 16777215] & 1) + i5 | 0); + f((HEAPU8[_buf + i6 & 16777215] & 1) + i5 | 0); + if ((_sbrk($419 | 0) | 0) == -1) { + print("fleefl"); + } +} diff --git a/tools/test-js-optimizer-regs-output.js b/tools/test-js-optimizer-regs-output.js index 90b67a47..36006b7c 100644 --- a/tools/test-js-optimizer-regs-output.js +++ b/tools/test-js-optimizer-regs-output.js @@ -197,32 +197,32 @@ function ex() { }))(); } } -function switchey(x) { - var r1, r2, r3, r4, r5, r6, r7, r8; - r1 = 5; +function switchey(r1) { + var r2, r3, r4, r5, r6, r7, r8, r9; + r2 = 5; while (1) { - switch (x = f(x, r1)) { + switch (r1 = f(r1, r2)) { case 1: - g(r1); - r2 = x + 1; - x--; + g(r2); + r3 = r1 + 1; + r1--; break; case 2: - g(r1 * 2); - r3 = x + 22; - r4 = r3 + 5; - x -= 20; + g(r2 * 2); + r4 = r1 + 22; + r5 = r4 + 5; + r1 -= 20; break; default: - r5 = x + 22; - r6 = r3 + 5; - ch(r5, r6 * r3); + r6 = r1 + 22; + r7 = r4 + 5; + ch(r6, r7 * r4); throw 99; } } - r7 = x + 1; - p(r1, r7); - r8 = x + 2; - pp(r8); + r8 = r1 + 1; + p(r2, r8); + r9 = r1 + 2; + pp(r9); } diff --git a/tools/test-js-optimizer.js b/tools/test-js-optimizer.js index dc48575c..982e3230 100644 --- a/tools/test-js-optimizer.js +++ b/tools/test-js-optimizer.js @@ -389,4 +389,19 @@ function tricky() { // The &-1 is a rounding correction, and must not be removed var $conv642 = ($conv6374 - (($132 << 16 >> 16 | 0) / 2 & -1) | 0) & 65535; } -// EMSCRIPTEN_GENERATED_FUNCTIONS: ["abc", "xyz", "xyz2", "expr", "loopy", "bits", "maths", "hoisting", "demangle", "lua", "moreLabels", "notComps", "tricky"] +function asmy() { + f(HEAP8[_buf + i6 & 16777215] & 255); + f(HEAPU8[_buf + i6 & 16777215] & 255); + f(HEAP8[_buf + i6 & 16777215] & 255 & 1); + f(HEAPU8[_buf + i6 & 16777215] & 255 & 1); + f(HEAP8[_buf + i6 & 16777215] & 1 & 255); + f(HEAPU8[_buf + i6 & 16777215] & 1 & 255); + f((HEAP8[_buf + i6 & 16777215] & 255 & 1) + i5 | 0); + f((HEAPU8[_buf + i6 & 16777215] & 255 & 1) + i5 | 0); + f((HEAP8[_buf + i6 & 16777215] & 1 & 255) + i5 | 0); + f((HEAPU8[_buf + i6 & 16777215] & 1 & 255) + i5 | 0); + if ((_sbrk($419 | 0) | 0 | 0) == -1) { + print('fleefl'); + } +} +// EMSCRIPTEN_GENERATED_FUNCTIONS: ["abc", "xyz", "xyz2", "expr", "loopy", "bits", "maths", "hoisting", "demangle", "lua", "moreLabels", "notComps", "tricky", "asmy"] |