diff options
-rw-r--r-- | AUTHORS | 1 | ||||
-rwxr-xr-x | emcc | 22 | ||||
-rwxr-xr-x | emscripten.py | 4 | ||||
-rw-r--r-- | src/library.js | 7 | ||||
-rw-r--r-- | src/library_gc.js | 71 | ||||
-rw-r--r-- | src/relooper/Relooper.cpp | 16 | ||||
-rw-r--r-- | src/relooper/test.txt | 4 | ||||
-rw-r--r-- | src/relooper/test2.txt | 15 | ||||
-rw-r--r-- | src/relooper/test3.txt | 38 | ||||
-rw-r--r-- | src/relooper/test4.txt | 21 | ||||
-rw-r--r-- | src/relooper/test6.txt | 15 | ||||
-rw-r--r-- | src/relooper/test_debug.txt | 15 | ||||
-rw-r--r-- | src/relooper/test_fuzz1.txt | 13 | ||||
-rw-r--r-- | src/relooper/test_fuzz5.txt | 27 | ||||
-rw-r--r-- | src/relooper/test_inf.txt | 651 | ||||
-rw-r--r-- | system/include/gc.h | 9 | ||||
-rw-r--r-- | system/include/libc/sys/features.h | 5 | ||||
-rw-r--r-- | system/include/libc/sys/types.h | 6 | ||||
-rwxr-xr-x | tests/runner.py | 60 | ||||
-rw-r--r-- | tools/eliminator/asm-eliminator-test-output.js | 8 | ||||
-rw-r--r-- | tools/eliminator/asm-eliminator-test.js | 13 | ||||
-rw-r--r-- | tools/eliminator/eliminator-test-output.js | 78 | ||||
-rw-r--r-- | tools/js-optimizer.js | 2 | ||||
-rw-r--r-- | tools/shared.py | 2 |
24 files changed, 594 insertions, 509 deletions
@@ -47,6 +47,7 @@ a license to everyone to use it as detailed in LICENSE.) * Michael Riss <Michael.Riss@gmx.de> * Jasper St. Pierre <jstpierre@mecheye.net> * Manuel Schölling <manuel.schoelling@gmx.de> +* Bruce Mitchener, Jr. <bruce.mitchener@gmail.com> @@ -90,8 +90,6 @@ 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 @@ -248,6 +246,15 @@ Options that are modified or new in %s include: are compiling to. To run your code, you will need both the .html and the .data. + emcc runs tools/file_packager.py to do the + actual packaging of embedded and preloaded + files. You can run the file packager yourself + if you want, see docs inside that file. You + should then put the output of the file packager + in an emcc --pre-js, so that it executes before + your main compiled code (or run it before in + some other way). + --compression <codec> Compress both the compiled code and embedded/ preloaded files. <codec> should be a triple, @@ -952,7 +959,7 @@ try: 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')]: + for src in ['dlmalloc.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) @@ -960,13 +967,6 @@ try: 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') @@ -1207,7 +1207,7 @@ try: js_optimizer_queue += [get_eliminate(), 'simplifyExpressionsPre'] - if shared.Settings.RELOOP: + if shared.Settings.RELOOP and not shared.Settings.ASM_JS: js_optimizer_queue += ['optimizeShiftsAggressive', get_eliminate()] # aggressive shifts optimization requires loops, it breaks on switches if closure: diff --git a/emscripten.py b/emscripten.py index 2ceb5e13..af762a21 100755 --- a/emscripten.py +++ b/emscripten.py @@ -321,12 +321,14 @@ def emscript(infile, settings, outfile, libraries=[]): infos = [make_table(sig, raw) for sig, raw in last_forwarded_json['Functions']['tables'].iteritems()] function_tables_defs = '\n'.join([info[0] for info in infos] + [info[1] for info in infos]) + asm_setup = '' maths = ['Math.' + func for func in ['floor', 'abs', 'sqrt', 'pow', 'cos', 'sin', 'tan', 'acos', 'asin', 'atan', 'atan2', 'exp', 'log', 'ceil']] if settings['USE_MATH_IMUL']: maths += ['Math.imul'] + asm_setup += 'if (!Math.imul) Math.imul = function(x, y) { return (x*y)|0 }; // # not a real polyfill since semantics not identical, but close and fairly fast\n' fundamentals = ['Math', 'Int8Array', 'Int16Array', 'Int32Array', 'Uint8Array', 'Uint16Array', 'Uint32Array', 'Float32Array', 'Float64Array'] math_envs = ['Runtime.bitshift64', 'Math.min'] # TODO: move min to maths - asm_setup = '\n'.join(['var %s = %s;' % (f.replace('.', '_'), f) for f in math_envs]) + asm_setup += '\n'.join(['var %s = %s;' % (f.replace('.', '_'), f) for f in math_envs]) basic_funcs = ['abort', 'assert', 'asmPrintInt', 'asmPrintFloat', 'copyTempDouble', 'copyTempFloat'] + [m.replace('.', '_') for m in math_envs] if settings['SAFE_HEAP']: basic_funcs += ['SAFE_HEAP_LOAD', 'SAFE_HEAP_STORE', 'SAFE_HEAP_CLEAR'] basic_vars = ['STACKTOP', 'STACK_MAX', 'tempDoublePtr', 'ABORT'] diff --git a/src/library.js b/src/library.js index 5071552a..9b97b795 100644 --- a/src/library.js +++ b/src/library.js @@ -4221,8 +4221,11 @@ LibraryManager.library = { memcpy__sig: 'iiii', memcpy: function (dest, src, num) { dest = dest|0; src = src|0; num = num|0; + var ret = 0; + ret = dest|0; if ((dest&3) == (src&3)) { - while (dest & 3 & num) { + while (dest & 3) { + if ((num|0) == 0) return ret|0; {{{ makeSetValueAsm('dest', 0, makeGetValueAsm('src', 0, 'i8'), 'i8') }}}; dest = (dest+1)|0; src = (src+1)|0; @@ -4241,7 +4244,7 @@ LibraryManager.library = { src = (src+1)|0; num = (num-1)|0; } - return dest|0; + return ret|0; }, wmemcpy: function() { throw 'wmemcpy not implemented' }, diff --git a/src/library_gc.js b/src/library_gc.js index fe4cbf63..083019ca 100644 --- a/src/library_gc.js +++ b/src/library_gc.js @@ -1,14 +1,16 @@ if (GC_SUPPORT) { EXPORTED_FUNCTIONS['_calloc'] = 1; + EXPORTED_FUNCTIONS['_realloc'] = 1; var LibraryGC = { - $GC__deps: ['sbrk'], + $GC__deps: ['sbrk', 'realloc'], $GC: { ALLOCATIONS_TO_GC: 1*1024*1024, sizes: {}, // if in this map, then a live allocated object. this is iterable scannables: {}, + uncollectables: {}, finalizers: {}, finalizerArgs: {}, @@ -34,7 +36,7 @@ if (GC_SUPPORT) { } }, - malloc: function(bytes, clear, scannable) { + malloc: function(bytes, clear, scannable, collectable) { if (!bytes) return 0; var ptr; if (clear) { @@ -42,6 +44,9 @@ if (GC_SUPPORT) { } else { ptr = _malloc(bytes); } + if (!collectable) { + GC.uncollectables[ptr] = true; + } GC.scannables[ptr] = scannable; GC.sizes[ptr] = bytes; GC.totalAllocations += bytes; @@ -49,6 +54,41 @@ if (GC_SUPPORT) { return ptr; }, + realloc: function(ptr, newBytes) { + if (newBytes != 0) { + var oldBytes = GC.sizes[ptr]; + var newPtr = _realloc(ptr, newBytes); + if (newBytes > oldBytes) { + _memset(newPtr + oldBytes, 0, newBytes - oldBytes); + } + delete GC.sizes[ptr]; + GC.sizes[newPtr] = newBytes; + scannable = GC.scannables[ptr]; + delete GC.scannables[ptr]; + GC.scannables[newPtr] = scannable; + var finalizer = GC.finalizers[ptr]; + if (finalizer) { + delete GC.finalizers[ptr]; + GC.finalizers[newPtr] = finalizer; + } + var finalizerArgs = GC.finalizerArgs[ptr]; + if (finalizerArgs) { + delete GC.finalizerArgs[ptr]; + GC.finalizerArgs[newPtr] = finalizerArgs; + } + var uncollectable = GC.uncollectables[ptr]; + if (uncollectable) { + delete GC.uncollectables[ptr]; + GC.uncollectables[newPtr] = true; + } + GC.totalAllocations += (newBytes - oldBytes); + return newPtr; + } else { + GC.free(ptr); + return 0; + } + }, + free: function(ptr) { // does not check if anything refers to it, this is a forced free var finalizer = GC.finalizers[ptr]; if (finalizer) { @@ -56,8 +96,8 @@ if (GC_SUPPORT) { GC.finalizers[ptr] = 0; } _free(ptr); - delete GC.sizes[ptr]; GC.totalAllocations -= GC.sizes[ptr]; + delete GC.sizes[ptr]; }, registerFinalizer: function(ptr, func, arg, oldFunc, oldArg) { @@ -74,6 +114,10 @@ if (GC_SUPPORT) { GC.finalizerArgs[ptr] = arg; }, + getHeapSize: function() { + return GC.totalAllocations; + }, + maybeCollect: function() { if (GC.needCollect()) GC.collect(); }, @@ -123,7 +167,7 @@ if (GC_SUPPORT) { sweep: function() { // traverse all objects and free all unreachable var freeList = []; for (var ptr in GC.sizes) { - if (!GC.reachable[ptr]) { + if (!GC.reachable[ptr] && !GC.uncollectables[ptr]) { freeList.push(parseInt(ptr)); } } @@ -140,12 +184,22 @@ if (GC_SUPPORT) { GC_MALLOC__deps: ['$GC'], GC_MALLOC: function(bytes) { - return GC.malloc(bytes, true, true); + return GC.malloc(bytes, true, true, true); }, GC_MALLOC_ATOMIC__deps: ['$GC'], GC_MALLOC_ATOMIC: function(bytes) { - return GC.malloc(bytes, false, false); + return GC.malloc(bytes, false, false, true); + }, + + GC_MALLOC_UNCOLLECTABLE__deps: ['$GC'], + GC_MALLOC_UNCOLLECTABLE: function(bytes) { + return GC.malloc(bytes, true, true, false); + }, + + GC_REALLOC__deps: ['$GC'], + GC_REALLOC: function(ptr, newBytes) { + return GC.realloc(ptr, newBytes); }, GC_FREE__deps: ['$GC'], @@ -158,6 +212,11 @@ if (GC_SUPPORT) { GC.registerFinalizer(ptr, func, arg, old_func, old_arg); }, + GC_get_heap_size__deps: ['$GC'], + GC_get_heap_size: function() { + return GC.getHeapSize(); + }, + GC_MAYBE_COLLECT__deps: ['$GC'], GC_MAYBE_COLLECT: function() { GC.maybeCollect(); diff --git a/src/relooper/Relooper.cpp b/src/relooper/Relooper.cpp index ae8577b1..6ea9e7f4 100644 --- a/src/relooper/Relooper.cpp +++ b/src/relooper/Relooper.cpp @@ -253,20 +253,11 @@ int Shape::IdCounter = 0; void MultipleShape::RenderLoopPrefix() { if (NeedLoop) { - if (Labeled) { - PrintIndented("L%d: do {\n", Id); - } else { - PrintIndented("do {\n"); - } - Indenter::Indent(); + PrintIndented("L%d: \n", Id); } } void MultipleShape::RenderLoopPostfix() { - if (NeedLoop) { - Indenter::Unindent(); - PrintIndented("} while(0);\n"); - } } void MultipleShape::Render(bool InLoop) { @@ -921,7 +912,10 @@ void Relooper::Calculate(Block *Entry) { Branch *Details = iter->second; if (Details->Type != Branch::Direct) { assert(LoopStack.size() > 0); - if (Details->Ancestor != LoopStack.top()) { + // If the ancestor is not at the top of the stack, we need a labelled break. We also + // always need a labeled break for multiple blocks, which are always labeled. + MultipleShape *Multiple; + if (Details->Ancestor != LoopStack.top() || Shape::IsMultiple(Details->Ancestor)) { LabeledShape *Labeled = Shape::IsLabeled(Details->Ancestor); Labeled->Labeled = true; Details->Labeled = true; diff --git a/src/relooper/test.txt b/src/relooper/test.txt index b7c8794d..12d0ef39 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 = 19; + label = 18; break; } // code 3 @@ -64,7 +64,7 @@ while(1) { var $i_0 = $7;var $x_0 = $5; } } -if (label == 19) { +if (label == 18) { // code 7 } // code 4 diff --git a/src/relooper/test2.txt b/src/relooper/test2.txt index c77ce491..a847e806 100644 --- a/src/relooper/test2.txt +++ b/src/relooper/test2.txt @@ -1,12 +1,11 @@ ep -do { - if (ep -> LBB1) { - LBB1 - if (!(LBB1 -> LBB2)) { - break; - } - LBB2 +L1: +if (ep -> LBB1) { + LBB1 + if (!(LBB1 -> LBB2)) { + break L1; } -} while(0); + LBB2 +} LBB3 diff --git a/src/relooper/test3.txt b/src/relooper/test3.txt index 696542ef..7d06f06a 100644 --- a/src/relooper/test3.txt +++ b/src/relooper/test3.txt @@ -1,27 +1,25 @@ ep -do { - if (ep -> LBB1) { - LBB1 - if (!(LBB1 -> LBB2)) { - break; - } - LBB2 +L1: +if (ep -> LBB1) { + LBB1 + if (!(LBB1 -> LBB2)) { + break L1; } -} while(0); + LBB2 +} LBB3 -L5: do { - if (LBB3 -> LBB4) { - LBB4 - if (!(LBB4 -> LBB5)) { - break; - } - while(1) { - LBB5 - if (LBB5 -> LBB6) { - break L5; - } +L5: +if (LBB3 -> LBB4) { + LBB4 + if (!(LBB4 -> LBB5)) { + break L5; + } + while(1) { + LBB5 + if (LBB5 -> LBB6) { + break L5; } } -} while(0); +} LBB6 diff --git a/src/relooper/test4.txt b/src/relooper/test4.txt index f0bfb972..2ab3265a 100644 --- a/src/relooper/test4.txt +++ b/src/relooper/test4.txt @@ -1,17 +1,16 @@ //19 -do { - if ( 1 ) { - //20 - if (!( 1 )) { - label = 4; - break; - } - //21 - break; - } else { +L1: +if ( 1 ) { + //20 + if (!( 1 )) { label = 4; + break L1; } -} while(0); + //21 + break L1; +} else { + label = 4; +} if (label == 4) { //22 } diff --git a/src/relooper/test6.txt b/src/relooper/test6.txt index c5effd08..0ec7e666 100644 --- a/src/relooper/test6.txt +++ b/src/relooper/test6.txt @@ -1,12 +1,11 @@ //0 -do { - if (check(0)) { - //1 - if (!(check(1))) { - break; - } - //2 +L1: +if (check(0)) { + //1 + if (!(check(1))) { + break L1; } -} while(0); + //2 +} //3 diff --git a/src/relooper/test_debug.txt b/src/relooper/test_debug.txt index 1c7d0508..02377fb7 100644 --- a/src/relooper/test_debug.txt +++ b/src/relooper/test_debug.txt @@ -83,14 +83,13 @@ int main() { // === Optimizing shapes === // Fusing Multiple to Simple ep -do { - if (ep -> LBB1) { - LBB1 - if (!(LBB1 -> LBB2)) { - break; - } - LBB2 +L1: +if (ep -> LBB1) { + LBB1 + if (!(LBB1 -> LBB2)) { + break L1; } -} while(0); + LBB2 +} LBB3 diff --git a/src/relooper/test_fuzz1.txt b/src/relooper/test_fuzz1.txt index 5122257e..09edb594 100644 --- a/src/relooper/test_fuzz1.txt +++ b/src/relooper/test_fuzz1.txt @@ -3,13 +3,12 @@ print('entry'); var label; var state; var decisions = [4, 1, 7, 2, 6, 6, 8]; var index = 0; function check() { if (index == decisions.length) throw 'HALT'; return decisions[index++] } print(5); state = check(); print(6); state = check(); -do { - if (state == 7) { - print(7); state = check(); - label = 3; - break; - } -} while(0); +L3: +if (state == 7) { + print(7); state = check(); + label = 3; + break L3; +} L5: while(1) { if (label == 3) { label = 0; diff --git a/src/relooper/test_fuzz5.txt b/src/relooper/test_fuzz5.txt index 9548205c..7c795d53 100644 --- a/src/relooper/test_fuzz5.txt +++ b/src/relooper/test_fuzz5.txt @@ -3,22 +3,21 @@ print('entry'); var label; var state; var decisions = [133, 98, 134, 143, 162, 187, 130, 87, 91, 49, 102, 47, 9, 132, 179, 176, 157, 25, 64, 161, 57, 107, 16, 167, 185, 45, 191, 180, 23, 131]; var index = 0; function check() { if (index == decisions.length) throw 'HALT'; return decisions[index++] } L1: while(1) { print(7); state = check(); - do { - if (state % 3 == 1) { - label = 3; - } else if (state % 3 == 0) { - print(8); state = check(); - if (state % 2 == 0) { - label = 5; - break; - } else { - label = 7; - break; - } + L3: + if (state % 3 == 1) { + label = 3; + } else if (state % 3 == 0) { + print(8); state = check(); + if (state % 2 == 0) { + label = 5; + break L3; } else { - break L1; + label = 7; + break L3; } - } while(0); + } else { + break L1; + } while(1) { if (label == 3) { label = 0; diff --git a/src/relooper/test_inf.txt b/src/relooper/test_inf.txt index 379d2083..3e292433 100644 --- a/src/relooper/test_inf.txt +++ b/src/relooper/test_inf.txt @@ -5,35 +5,34 @@ if (uint(i4) >= uint(i5)) { code 1 } code 3 -L5: do { - if (!(i2 == 0)) { - code 4 - while(1) { - code 5 - if (uint(i6) >= uint(i7)) { - code 7 - } else { - code 6 - } - code 8 - if (uint(i6) >= uint(i7)) { - code 10 - } else { - code 9 - } - code 11 - if (uint(i5) >= uint(i6)) { - code 13 - } else { - code 12 - } - code 14 - if (!(i2 != 0)) { - break L5; - } +L5: +if (!(i2 == 0)) { + code 4 + while(1) { + code 5 + if (uint(i6) >= uint(i7)) { + code 7 + } else { + code 6 + } + code 8 + if (uint(i6) >= uint(i7)) { + code 10 + } else { + code 9 + } + code 11 + if (uint(i5) >= uint(i6)) { + code 13 + } else { + code 12 + } + code 14 + if (!(i2 != 0)) { + break L5; } } -} while(0); +} code 15 if (uint(i4) >= uint(i5)) { code 17 @@ -41,179 +40,178 @@ if (uint(i4) >= uint(i5)) { code 16 } code 18 -L26: do { - if (!(i2 == 0)) { - code 19 - while(1) { - code 20 - if (uint(i5) >= uint(i6)) { - code 22 - } else { - code 21 - } - code 23 - if (uint(i5) >= uint(i6)) { - code 25 - } else { - code 24 - } - code 26 - if (uint(i5) >= uint(i6)) { - code 28 - } else { - code 27 - } - code 29 - if (uint(i5) >= uint(i6)) { - code 31 - } else { - code 30 - } - code 32 - if (uint(i5) >= uint(i6)) { - code 34 - } else { - code 33 - } - code 35 - if (uint(i5) >= uint(i6)) { - code 37 - } else { - code 36 - } - code 38 - if (uint(i5) >= uint(i6)) { - code 40 - } else { - code 39 - } - code 41 - if (uint(i5) >= uint(i6)) { - code 43 - } else { - code 42 - } - code 44 - if (uint(i5) >= uint(i6)) { - code 46 - } else { - code 45 - } - code 47 - if (uint(i5) >= uint(i6)) { - code 49 - } else { - code 48 - } - code 50 - if (uint(i5) >= uint(i6)) { - code 52 - } else { - code 51 - } - code 53 - if (uint(i5) >= uint(i6)) { - code 55 - } else { - code 54 - } - code 56 - if (uint(i5) >= uint(i6)) { - code 58 - } else { - code 57 - } - code 59 - if (uint(i5) >= uint(i6)) { - code 61 - } else { - code 60 - } - code 62 - if (uint(i5) >= uint(i6)) { - code 64 - } else { - code 63 - } - code 65 - if (uint(i5) >= uint(i6)) { - code 67 - } else { - code 66 - } - code 68 - if (uint(i5) >= uint(i6)) { - code 70 - } else { - code 69 - } - code 71 - if (uint(i5) >= uint(i6)) { - code 73 - } else { - code 72 - } - code 74 - if (uint(i5) >= uint(i6)) { - code 76 - } else { - code 75 - } - code 77 - if (uint(i5) >= uint(i6)) { - code 79 - } else { - code 78 - } - code 80 - if (uint(i5) >= uint(i6)) { - code 82 - } else { - code 81 - } - code 83 - if (uint(i5) >= uint(i6)) { - code 85 - } else { - code 84 - } - code 86 - if (uint(i5) >= uint(i6)) { - code 88 - } else { - code 87 - } - code 89 - if (uint(i5) >= uint(i6)) { - code 91 - } else { - code 90 - } - code 92 - if (uint(i5) >= uint(i6)) { - code 94 - } else { - code 93 - } - code 95 - if (uint(i5) >= uint(i6)) { - code 97 - } else { - code 96 - } - code 98 - if (uint(i5) >= uint(i6)) { - code 100 - } else { - code 99 - } - code 101 - if (!(i2 != 0)) { - break L26; - } +L26: +if (!(i2 == 0)) { + code 19 + while(1) { + code 20 + if (uint(i5) >= uint(i6)) { + code 22 + } else { + code 21 + } + code 23 + if (uint(i5) >= uint(i6)) { + code 25 + } else { + code 24 + } + code 26 + if (uint(i5) >= uint(i6)) { + code 28 + } else { + code 27 + } + code 29 + if (uint(i5) >= uint(i6)) { + code 31 + } else { + code 30 + } + code 32 + if (uint(i5) >= uint(i6)) { + code 34 + } else { + code 33 + } + code 35 + if (uint(i5) >= uint(i6)) { + code 37 + } else { + code 36 + } + code 38 + if (uint(i5) >= uint(i6)) { + code 40 + } else { + code 39 + } + code 41 + if (uint(i5) >= uint(i6)) { + code 43 + } else { + code 42 + } + code 44 + if (uint(i5) >= uint(i6)) { + code 46 + } else { + code 45 + } + code 47 + if (uint(i5) >= uint(i6)) { + code 49 + } else { + code 48 + } + code 50 + if (uint(i5) >= uint(i6)) { + code 52 + } else { + code 51 + } + code 53 + if (uint(i5) >= uint(i6)) { + code 55 + } else { + code 54 + } + code 56 + if (uint(i5) >= uint(i6)) { + code 58 + } else { + code 57 + } + code 59 + if (uint(i5) >= uint(i6)) { + code 61 + } else { + code 60 + } + code 62 + if (uint(i5) >= uint(i6)) { + code 64 + } else { + code 63 + } + code 65 + if (uint(i5) >= uint(i6)) { + code 67 + } else { + code 66 + } + code 68 + if (uint(i5) >= uint(i6)) { + code 70 + } else { + code 69 + } + code 71 + if (uint(i5) >= uint(i6)) { + code 73 + } else { + code 72 + } + code 74 + if (uint(i5) >= uint(i6)) { + code 76 + } else { + code 75 + } + code 77 + if (uint(i5) >= uint(i6)) { + code 79 + } else { + code 78 + } + code 80 + if (uint(i5) >= uint(i6)) { + code 82 + } else { + code 81 + } + code 83 + if (uint(i5) >= uint(i6)) { + code 85 + } else { + code 84 + } + code 86 + if (uint(i5) >= uint(i6)) { + code 88 + } else { + code 87 + } + code 89 + if (uint(i5) >= uint(i6)) { + code 91 + } else { + code 90 + } + code 92 + if (uint(i5) >= uint(i6)) { + code 94 + } else { + code 93 + } + code 95 + if (uint(i5) >= uint(i6)) { + code 97 + } else { + code 96 + } + code 98 + if (uint(i5) >= uint(i6)) { + code 100 + } else { + code 99 + } + code 101 + if (!(i2 != 0)) { + break L26; } } -} while(0); +} code 102 if (uint(i4) >= uint(i5)) { code 104 @@ -221,137 +219,136 @@ if (uint(i4) >= uint(i5)) { code 103 } code 105 -L143: do { - if (!(i2 == 0)) { - code 106 - while(1) { - code 107 - if (uint(i5) >= uint(i6)) { - code 109 - } else { - code 108 - } - code 110 - if (uint(i5) >= uint(i6)) { - code 112 - } else { - code 111 - } - code 113 - if (uint(i5) >= uint(i6)) { - code 115 - } else { - code 114 - } - code 116 - if (uint(i5) >= uint(i6)) { - code 118 - } else { - code 117 - } - code 119 - if (uint(i5) >= uint(i6)) { - code 121 - } else { - code 120 - } - code 122 - if (uint(i5) >= uint(i6)) { - code 124 - } else { - code 123 - } - code 125 - if (uint(i5) >= uint(i6)) { - code 127 - } else { - code 126 - } - code 128 - if (uint(i5) >= uint(i6)) { - code 130 - } else { - code 129 - } - code 131 - if (uint(i5) >= uint(i6)) { - code 133 - } else { - code 132 - } - code 134 - if (uint(i5) >= uint(i6)) { - code 136 - } else { - code 135 - } - code 137 - if (uint(i5) >= uint(i6)) { - code 139 - } else { - code 138 - } - code 140 - if (uint(i5) >= uint(i6)) { - code 142 - } else { - code 141 - } - code 143 - if (uint(i5) >= uint(i6)) { - code 145 - } else { - code 144 - } - code 146 - if (uint(i5) >= uint(i6)) { - code 148 - } else { - code 147 - } - code 149 - if (uint(i5) >= uint(i6)) { - code 151 - } else { - code 150 - } - code 152 - if (uint(i5) >= uint(i6)) { - code 154 - } else { - code 153 - } - code 155 - if (uint(i5) >= uint(i6)) { - code 157 - } else { - code 156 - } - code 158 - if (uint(i5) >= uint(i6)) { - code 160 - } else { - code 159 - } - code 161 - if (uint(i5) >= uint(i6)) { - code 163 - } else { - code 162 - } - code 164 - if (uint(i5) >= uint(i6)) { - code 166 - } else { - code 165 - } - code 167 - if (!(i2 != 0)) { - break L143; - } +L143: +if (!(i2 == 0)) { + code 106 + while(1) { + code 107 + if (uint(i5) >= uint(i6)) { + code 109 + } else { + code 108 + } + code 110 + if (uint(i5) >= uint(i6)) { + code 112 + } else { + code 111 + } + code 113 + if (uint(i5) >= uint(i6)) { + code 115 + } else { + code 114 + } + code 116 + if (uint(i5) >= uint(i6)) { + code 118 + } else { + code 117 + } + code 119 + if (uint(i5) >= uint(i6)) { + code 121 + } else { + code 120 + } + code 122 + if (uint(i5) >= uint(i6)) { + code 124 + } else { + code 123 + } + code 125 + if (uint(i5) >= uint(i6)) { + code 127 + } else { + code 126 + } + code 128 + if (uint(i5) >= uint(i6)) { + code 130 + } else { + code 129 + } + code 131 + if (uint(i5) >= uint(i6)) { + code 133 + } else { + code 132 + } + code 134 + if (uint(i5) >= uint(i6)) { + code 136 + } else { + code 135 + } + code 137 + if (uint(i5) >= uint(i6)) { + code 139 + } else { + code 138 + } + code 140 + if (uint(i5) >= uint(i6)) { + code 142 + } else { + code 141 + } + code 143 + if (uint(i5) >= uint(i6)) { + code 145 + } else { + code 144 + } + code 146 + if (uint(i5) >= uint(i6)) { + code 148 + } else { + code 147 + } + code 149 + if (uint(i5) >= uint(i6)) { + code 151 + } else { + code 150 + } + code 152 + if (uint(i5) >= uint(i6)) { + code 154 + } else { + code 153 + } + code 155 + if (uint(i5) >= uint(i6)) { + code 157 + } else { + code 156 + } + code 158 + if (uint(i5) >= uint(i6)) { + code 160 + } else { + code 159 + } + code 161 + if (uint(i5) >= uint(i6)) { + code 163 + } else { + code 162 + } + code 164 + if (uint(i5) >= uint(i6)) { + code 166 + } else { + code 165 + } + code 167 + if (!(i2 != 0)) { + break L143; } } -} while(0); +} code 168 if (uint(i4) >= uint(i5)) { code 170 diff --git a/system/include/gc.h b/system/include/gc.h index e0419dcb..8c5a8989 100644 --- a/system/include/gc.h +++ b/system/include/gc.h @@ -29,6 +29,12 @@ void *GC_MALLOC(int bytes); /* Allocate memory for an object that the user promises will not contain pointers. */ void *GC_MALLOC_ATOMIC(int bytes); +/* Allocate memory that might container pointers but that can't be collected. */ +void *GC_MALLOC_UNCOLLECTABLE(int bytes); + +/* Reallocate a GC managed memory block to a new size. */ +void *GC_REALLOC(void *ptr, int newBytes); + /* Explicitly deallocate an object. Dangerous as it forces a free and does not check if the object is reffed. */ void GC_FREE(void *ptr); @@ -36,6 +42,9 @@ void GC_FREE(void *ptr); void GC_REGISTER_FINALIZER_NO_ORDER(void *ptr, void (*func)(void *, void *), void *arg, void *(*old_func)(void *, void *), void *old_arg); +/* Gets the bytes allocated and managed by the GC */ +int GC_get_heap_size(); + /* Non-Boehm additions */ /* Call this once per frame or such, it will collect if necessary */ diff --git a/system/include/libc/sys/features.h b/system/include/libc/sys/features.h index 87a520a0..8c32bf04 100644 --- a/system/include/libc/sys/features.h +++ b/system/include/libc/sys/features.h @@ -26,7 +26,10 @@ extern "C" { #endif #if EMSCRIPTEN -#define _POSIX_REALTIME_SIGNALS 1 +#define _POSIX_REALTIME_SIGNALS 1 +#define _POSIX_THREADS 200112L +#define _UNIX98_THREAD_MUTEX_ATTRIBUTES 1 +#define _POSIX_READER_WRITER_LOCKS 200112L #endif /* RTEMS adheres to POSIX -- 1003.1b with some features from annexes. */ diff --git a/system/include/libc/sys/types.h b/system/include/libc/sys/types.h index e90a74ac..c36f724c 100644 --- a/system/include/libc/sys/types.h +++ b/system/include/libc/sys/types.h @@ -24,12 +24,6 @@ #include <machine/_types.h> -#if EMSCRIPTEN - #define _POSIX_THREADS - #define _UNIX98_THREAD_MUTEX_ATTRIBUTES - #define _POSIX_READER_WRITER_LOCKS -#endif - #if defined(__rtems__) || defined(__XMK__) || defined(EMSCRIPTEN) /* * The following section is RTEMS specific and is needed to more diff --git a/tests/runner.py b/tests/runner.py index 383254aa..66936e5a 100755 --- a/tests/runner.py +++ b/tests/runner.py @@ -2199,7 +2199,7 @@ Succeeded! } int main() { - int x = 0; + volatile int x = 0; if ( ! setjmp(buf) ) { x++; first(); // when executed, setjmp returns 0 @@ -2210,11 +2210,7 @@ Succeeded! return 0; } ''' - # gcc -O0 and -O2 differ in what they do with the saved state of local vars - and we match that - if self.emcc_args is None or ('-O1' not in self.emcc_args and '-O2' not in self.emcc_args): - self.do_run(src, 'second\nmain: 1\n') - else: - self.do_run(src, 'second\nmain: 0\n') + self.do_run(src, 'second\nmain: 1\n') def test_longjmp2(self): if Settings.ASM_JS: return self.skip('asm does not support longjmp') @@ -4134,6 +4130,31 @@ The current type of b is: 9 self.do_run(src, '6c9cdfe937383b79e52ca7a2cce83a21d9f5422c', output_nicerizer = check) + def test_memcpy2(self): + src = r''' + #include <stdio.h> + #include <string.h> + #include <assert.h> + int main() { + char buffer[256]; + for (int i = 0; i < 10; i++) { + for (int j = 0; j < 10; j++) { + for (int k = 0; k < 35; k++) { + for (int t = 0; t < 256; t++) buffer[t] = t; + char *dest = buffer + i + 128; + char *src = buffer+j; + //printf("%d, %d, %d\n", i, j, k); + assert(memcpy(dest, src, k) == dest); + assert(memcmp(dest, src, k) == 0); + } + } + } + printf("ok.\n"); + return 1; + } + ''' + self.do_run(src, 'ok.'); + def test_memmove(self): src = ''' #include <stdio.h> @@ -7915,7 +7936,7 @@ def process(filename): int main() { GC_INIT(); - void *local, *local2, *local3, *local4; + void *local, *local2, *local3, *local4, *local5, *local6; // Hold on to global, drop locals @@ -7960,6 +7981,20 @@ def process(filename): GC_REGISTER_FINALIZER_NO_ORDER(local3, finalizer, (void*)3, 0, 0); local4 = GC_MALLOC(12); GC_REGISTER_FINALIZER_NO_ORDER(local4, finalizer, (void*)4, 0, 0); + local5 = GC_MALLOC_UNCOLLECTABLE(12); + // This should never trigger since local5 is uncollectable + GC_REGISTER_FINALIZER_NO_ORDER(local5, finalizer, (void*)5, 0, 0); + + printf("heap size = %d\n", GC_get_heap_size()); + + local4 = GC_REALLOC(local4, 24); + + printf("heap size = %d\n", GC_get_heap_size()); + + local6 = GC_MALLOC(12); + GC_REGISTER_FINALIZER_NO_ORDER(local6, finalizer, (void*)6, 0, 0); + // This should be the same as a free + GC_REALLOC(local6, 0); void **globalData = (void**)global; globalData[0] = local; @@ -7996,6 +8031,9 @@ finalizing2 2 (global == 0) finalizing2 3 (global == 0) * finalizing 0 (global == 1) +heap size = 72 +heap size = 84 +finalizing 6 (global == 0) object scan test test finalizing 4 (global == 0) * @@ -8256,7 +8294,7 @@ Options that are modified or new in %s include: assert ('assert(STACKTOP < STACK_MAX' in generated) == (opt_level == 0), 'assertions should be in opt == 0' assert 'var $i;' in generated or 'var $i_0' in generated or 'var $storemerge3;' in generated or 'var $storemerge4;' in generated or 'var $i_04;' in generated, 'micro opts should always be on' if opt_level >= 2: - assert 'HEAP8[$0 + ($i_' in generated or 'HEAP8[$0 + (($i_0' in generated or 'HEAP8[HEAP32[' in generated or 'HEAP8[$vla1 + (($storemerge4 | 0) / 2 & -1) | 0]' in generated or 'HEAP8[$vla1 + (($storemerge4 | 0) / 2 & -1) | 0]' in generated or 'HEAP8[$vla1 + (($i_04 | 0) / 2 & -1) | 0]' in generated or 'HEAP8[$vla1 + ($i_04 / 2 & -1)]' in generated or 'HEAP8[$1 + (($i_01 | 0) / 2 & -1) | 0]' in generated or 'HEAP8[$1 + (($i_01 | 0) / 2 & -1) | 0]' in generated or 'HEAP8[$1 + ($i_01 / 2 & -1)]' in generated, 'eliminator should create compound expressions, and fewer one-time vars' # also in -O1, but easier to test in -O2 + assert re.search('HEAP8\[\$\w+ \+ \(+\$\w+ ', generated) or re.search('HEAP8\[HEAP32\[', generated), 'eliminator should create compound expressions, and fewer one-time vars' # also in -O1, but easier to test in -O2 assert ('_puts(' in generated) == (opt_level >= 1), 'with opt >= 1, llvm opts are run and they should optimize printf to puts' assert ('function _malloc(bytes) {' in generated) == (not has_malloc), 'If malloc is needed, it should be there, if not not' assert 'function _main() {' in generated, 'Should be unminified, including whitespace' @@ -10723,7 +10761,7 @@ elif 'benchmark' in str(sys.argv): total_native_times = map(lambda x: 0., range(TOTAL_TESTS)) class benchmark(RunnerCore): - def print_stats(self, times, native_times, last=False): + def print_stats(self, times, native_times, last=False, reps=TEST_REPS): mean = sum(times)/len(times) squared_times = map(lambda x: x*x, times) mean_of_squared = sum(squared_times)/len(times) @@ -10752,7 +10790,7 @@ elif 'benchmark' in str(sys.argv): return print - print ' JavaScript: mean: %.3f (+-%.3f) secs median: %.3f range: %.3f-%.3f (noise: %3.3f%%) (%d runs)' % (mean, std, median, min(times), max(times), 100*std/mean, TEST_REPS) + print ' JavaScript: mean: %.3f (+-%.3f) secs median: %.3f range: %.3f-%.3f (noise: %3.3f%%) (%d runs)' % (mean, std, median, min(times), max(times), 100*std/mean, reps) print ' Native : mean: %.3f (+-%.3f) secs median: %.3f range: %.3f-%.3f (noise: %3.3f%%) JS is %.2f X slower' % (mean_native, std_native, median_native, min(native_times), max(native_times), 100*std_native/mean_native, final) def do_benchmark(self, name, src, args=[], expected_output='FAIL', emcc_args=[], native_args=[], shared_args=[], force_c=False, reps=TEST_REPS): @@ -10800,7 +10838,7 @@ elif 'benchmark' in str(sys.argv): native_times.append(curr) total_native_times[tests_done] += curr - self.print_stats(times, native_times) + self.print_stats(times, native_times, reps=reps) #tests_done += 1 #if tests_done == TOTAL_TESTS: diff --git a/tools/eliminator/asm-eliminator-test-output.js b/tools/eliminator/asm-eliminator-test-output.js index 3170bd9c..4cf15c62 100644 --- a/tools/eliminator/asm-eliminator-test-output.js +++ b/tools/eliminator/asm-eliminator-test-output.js @@ -100,4 +100,12 @@ function exc($this) { ___cxa_call_unexpected($8$0); } } +function label() { + if (f()) { + g(); + } + L100 : if (h()) { + i(); + } +} diff --git a/tools/eliminator/asm-eliminator-test.js b/tools/eliminator/asm-eliminator-test.js index ce34a7a6..d2c0507c 100644 --- a/tools/eliminator/asm-eliminator-test.js +++ b/tools/eliminator/asm-eliminator-test.js @@ -130,5 +130,16 @@ function exc($this) { ___cxa_call_unexpected($9); } } -// EMSCRIPTEN_GENERATED_FUNCTIONS: ["asm", "__Z11printResultPiS_j", "_segment_holding", "__ZN5identC2EiPKcPci", "_vec2Length", "exc"] +function label() { + var $1 = 0, $2 = 0; + $1 = f(); + if ($1) { + g(); + } + $2 = h(); + L100: if ($2) { + i(); + } +} +// EMSCRIPTEN_GENERATED_FUNCTIONS: ["asm", "__Z11printResultPiS_j", "_segment_holding", "__ZN5identC2EiPKcPci", "_vec2Length", "exc", "label"] diff --git a/tools/eliminator/eliminator-test-output.js b/tools/eliminator/eliminator-test-output.js index a005a0a5..32b7ddcf 100644 --- a/tools/eliminator/eliminator-test-output.js +++ b/tools/eliminator/eliminator-test-output.js @@ -242,9 +242,8 @@ function _inflate($strm, $flush) { STACKTOP += 4; var __label__; var $hbuf = __stackBase__; - var $cmp = ($strm | 0) == 0; $_$2 : do { - if ($cmp) { + if (($strm | 0) == 0) { var $retval_0 = -2; } else { var $0 = HEAPU32[($strm + 28 | 0) >> 2]; @@ -1129,9 +1128,8 @@ function _inflate($strm, $flush) { var $hold_23 = $hold_24 >>> 3; var $bits_23 = $bits_24 - 3 | 0; } - var $cmp850111 = $122 >>> 0 < 19; $_$131 : do { - if ($cmp850111) { + if ($122 >>> 0 < 19) { var $126 = $122; while (1) { var $126; @@ -2880,9 +2878,8 @@ function _inflate($strm, $flush) { } function _malloc($bytes) { var __label__; - var $1 = $bytes >>> 0 < 245; $_$2 : do { - if ($1) { + if ($bytes >>> 0 < 245) { if ($bytes >>> 0 < 11) { var $8 = 16; } else { @@ -3102,9 +3099,8 @@ function _malloc($bytes) { } } while (0); var $R_1_i; - var $232 = ($198 | 0) == 0; $_$62 : do { - if (!$232) { + if (!(($198 | 0) == 0)) { var $234 = $v_0_i + 28 | 0; var $236 = __gm_ + 304 + (HEAP32[$234 >> 2] << 2) | 0; do { @@ -3245,9 +3241,8 @@ function _malloc($bytes) { } while (0); var $idx_0_i; var $376 = HEAPU32[(__gm_ + 304 + ($idx_0_i << 2) | 0) >> 2]; - var $377 = ($376 | 0) == 0; $_$110 : do { - if ($377) { + if (($376 | 0) == 0) { var $v_2_i = 0; var $rsize_2_i = $346; var $t_1_i = 0; @@ -3329,9 +3324,8 @@ function _malloc($bytes) { var $t_2_ph_i = $t_1_i; } var $t_2_ph_i; - var $438 = ($t_2_ph_i | 0) == 0; $_$125 : do { - if ($438) { + if (($t_2_ph_i | 0) == 0) { var $rsize_3_lcssa_i = $rsize_2_i; var $v_3_lcssa_i = $v_2_i; } else { @@ -3442,9 +3436,8 @@ function _malloc($bytes) { } } while (0); var $R_1_i19; - var $499 = ($465 | 0) == 0; $_$151 : do { - if (!$499) { + if (!(($465 | 0) == 0)) { var $501 = $v_3_lcssa_i + 28 | 0; var $503 = __gm_ + 304 + (HEAP32[$501 >> 2] << 2) | 0; do { @@ -3496,9 +3489,8 @@ function _malloc($bytes) { } } } while (0); - var $557 = $rsize_3_lcssa_i >>> 0 < 16; $_$179 : do { - if ($557) { + if ($rsize_3_lcssa_i >>> 0 < 16) { var $559 = $rsize_3_lcssa_i + $342 | 0; HEAP32[($v_3_lcssa_i + 4 | 0) >> 2] = $559 | 3; var $563 = $456 + ($559 + 4 | 0) | 0; @@ -3669,13 +3661,11 @@ function _malloc($bytes) { } } } while (0); - var $765 = (HEAP32[(__gm_ + 440 | 0) >> 2] & 4 | 0) == 0; $_$234 : do { - if ($765) { + if ((HEAP32[(__gm_ + 440 | 0) >> 2] & 4 | 0) == 0) { var $767 = HEAP32[(__gm_ + 24 | 0) >> 2]; - var $768 = ($767 | 0) == 0; $_$236 : do { - if (!$768) { + if (!(($767 | 0) == 0)) { var $770 = $767; var $sp_0_i_i = __gm_ + 444 | 0; while (1) { @@ -3846,9 +3836,8 @@ function _malloc($bytes) { HEAP32[(__gm_ + 436 | 0) >> 2] = $871; } var $876 = HEAPU32[(__gm_ + 24 | 0) >> 2]; - var $877 = ($876 | 0) == 0; $_$275 : do { - if ($877) { + if (($876 | 0) == 0) { var $879 = HEAPU32[(__gm_ + 16 | 0) >> 2]; if (($879 | 0) == 0 | $tbase_243_i >>> 0 < $879 >>> 0) { HEAP32[(__gm_ + 16 | 0) >> 2] = $tbase_243_i; @@ -3970,9 +3959,8 @@ function _malloc($bytes) { var $998 = $997; var $999 = ($992 - ($tbase_243_i + $981 | 0) | 0) - $nb_0 | 0; HEAP32[($tbase_243_i + ($981 + 4 | 0) | 0) >> 2] = $nb_0 | 3; - var $1004 = ($993 | 0) == (HEAP32[(__gm_ + 24 | 0) >> 2] | 0); $_$314 : do { - if ($1004) { + if (($993 | 0) == (HEAP32[(__gm_ + 24 | 0) >> 2] | 0)) { var $1007 = HEAP32[(__gm_ + 12 | 0) >> 2] + $999 | 0; HEAP32[(__gm_ + 12 | 0) >> 2] = $1007; HEAP32[(__gm_ + 24 | 0) >> 2] = $998; @@ -3990,9 +3978,8 @@ function _malloc($bytes) { if (($1025 & 3 | 0) == 1) { var $1029 = $1025 & -8; var $1030 = $1025 >>> 3; - var $1031 = $1025 >>> 0 < 256; $_$322 : do { - if ($1031) { + if ($1025 >>> 0 < 256) { var $1035 = HEAPU32[($tbase_243_i + (($991 | 8) + $tsize_242_i | 0) | 0) >> 2]; var $1038 = HEAPU32[($tbase_243_i + (($tsize_242_i + 12 | 0) + $991 | 0) | 0) >> 2]; if (($1035 | 0) == ($1038 | 0)) { @@ -4327,9 +4314,8 @@ function _malloc($bytes) { HEAP32[(__gm_ + 452 | 0) >> 2] = $1337; var $1360 = $1336 + 28 | 0; HEAP32[$1360 >> 2] = 7; - var $1362 = ($1336 + 32 | 0) >>> 0 < $1322 >>> 0; $_$426 : do { - if ($1362) { + if (($1336 + 32 | 0) >>> 0 < $1322 >>> 0) { var $1363 = $1360; while (1) { var $1363; @@ -4507,9 +4493,8 @@ function _malloc($bytes) { } function _mallocNoU($bytes) { var __label__; - var $1 = $bytes >>> 0 < 245; $_$2 : do { - if ($1) { + if ($bytes >>> 0 < 245) { if ($bytes >>> 0 < 11) { var $8 = 16; } else { @@ -4729,9 +4714,8 @@ function _mallocNoU($bytes) { } } while (0); var $R_1_i; - var $232 = ($198 | 0) == 0; $_$62 : do { - if (!$232) { + if (!(($198 | 0) == 0)) { var $234 = $v_0_i + 28 | 0; var $236 = __gm_ + 304 + (HEAP32[$234 >> 2] << 2) | 0; do { @@ -4872,9 +4856,8 @@ function _mallocNoU($bytes) { } while (0); var $idx_0_i; var $376 = HEAP32[(__gm_ + 304 + ($idx_0_i << 2) | 0) >> 2]; - var $377 = ($376 | 0) == 0; $_$110 : do { - if ($377) { + if (($376 | 0) == 0) { var $v_2_i = 0; var $rsize_2_i = $346; var $t_1_i = 0; @@ -4956,9 +4939,8 @@ function _mallocNoU($bytes) { var $t_2_ph_i = $t_1_i; } var $t_2_ph_i; - var $438 = ($t_2_ph_i | 0) == 0; $_$125 : do { - if ($438) { + if (($t_2_ph_i | 0) == 0) { var $rsize_3_lcssa_i = $rsize_2_i; var $v_3_lcssa_i = $v_2_i; } else { @@ -5069,9 +5051,8 @@ function _mallocNoU($bytes) { } } while (0); var $R_1_i19; - var $499 = ($465 | 0) == 0; $_$151 : do { - if (!$499) { + if (!(($465 | 0) == 0)) { var $501 = $v_3_lcssa_i + 28 | 0; var $503 = __gm_ + 304 + (HEAP32[$501 >> 2] << 2) | 0; do { @@ -5123,9 +5104,8 @@ function _mallocNoU($bytes) { } } } while (0); - var $557 = $rsize_3_lcssa_i >>> 0 < 16; $_$179 : do { - if ($557) { + if ($rsize_3_lcssa_i >>> 0 < 16) { var $559 = $rsize_3_lcssa_i + $342 | 0; HEAP32[($v_3_lcssa_i + 4 | 0) >> 2] = $559 | 3; var $563 = $456 + ($559 + 4 | 0) | 0; @@ -5296,13 +5276,11 @@ function _mallocNoU($bytes) { } } } while (0); - var $765 = (HEAP32[(__gm_ + 440 | 0) >> 2] & 4 | 0) == 0; $_$234 : do { - if ($765) { + if ((HEAP32[(__gm_ + 440 | 0) >> 2] & 4 | 0) == 0) { var $767 = HEAP32[(__gm_ + 24 | 0) >> 2]; - var $768 = ($767 | 0) == 0; $_$236 : do { - if (!$768) { + if (!(($767 | 0) == 0)) { var $770 = $767; var $sp_0_i_i = __gm_ + 444 | 0; while (1) { @@ -5473,9 +5451,8 @@ function _mallocNoU($bytes) { HEAP32[(__gm_ + 436 | 0) >> 2] = $871; } var $876 = HEAP32[(__gm_ + 24 | 0) >> 2]; - var $877 = ($876 | 0) == 0; $_$275 : do { - if ($877) { + if (($876 | 0) == 0) { var $879 = HEAP32[(__gm_ + 16 | 0) >> 2]; if (($879 | 0) == 0 | $tbase_243_i >>> 0 < $879 >>> 0) { HEAP32[(__gm_ + 16 | 0) >> 2] = $tbase_243_i; @@ -5597,9 +5574,8 @@ function _mallocNoU($bytes) { var $998 = $997; var $999 = ($992 - ($tbase_243_i + $981 | 0) | 0) - $nb_0 | 0; HEAP32[($tbase_243_i + ($981 + 4 | 0) | 0) >> 2] = $nb_0 | 3; - var $1004 = ($993 | 0) == (HEAP32[(__gm_ + 24 | 0) >> 2] | 0); $_$314 : do { - if ($1004) { + if (($993 | 0) == (HEAP32[(__gm_ + 24 | 0) >> 2] | 0)) { var $1007 = HEAP32[(__gm_ + 12 | 0) >> 2] + $999 | 0; HEAP32[(__gm_ + 12 | 0) >> 2] = $1007; HEAP32[(__gm_ + 24 | 0) >> 2] = $998; @@ -5617,9 +5593,8 @@ function _mallocNoU($bytes) { if (($1025 & 3 | 0) == 1) { var $1029 = $1025 & -8; var $1030 = $1025 >>> 3; - var $1031 = $1025 >>> 0 < 256; $_$322 : do { - if ($1031) { + if ($1025 >>> 0 < 256) { var $1035 = HEAP32[($tbase_243_i + (($991 | 8) + $tsize_242_i | 0) | 0) >> 2]; var $1038 = HEAP32[($tbase_243_i + (($tsize_242_i + 12 | 0) + $991 | 0) | 0) >> 2]; if (($1035 | 0) == ($1038 | 0)) { @@ -5954,9 +5929,8 @@ function _mallocNoU($bytes) { HEAP32[(__gm_ + 452 | 0) >> 2] = $1337; var $1360 = $1336 + 28 | 0; HEAP32[$1360 >> 2] = 7; - var $1362 = ($1336 + 32 | 0) >>> 0 < $1322 >>> 0; $_$426 : do { - if ($1362) { + if (($1336 + 32 | 0) >>> 0 < $1322 >>> 0) { var $1363 = $1360; while (1) { var $1363; diff --git a/tools/js-optimizer.js b/tools/js-optimizer.js index 12754bb2..634d7dda 100644 --- a/tools/js-optimizer.js +++ b/tools/js-optimizer.js @@ -1653,7 +1653,7 @@ function registerize(ast) { // In memSafe mode, we are more careful and assume functions can replace HEAP and FUNCTION_TABLE, which // can happen in ALLOW_MEMORY_GROWTH mode -var ELIMINATION_SAFE_NODES = set('var', 'assign', 'call', 'if', 'toplevel', 'do', 'return'); // do is checked carefully, however +var ELIMINATION_SAFE_NODES = set('var', 'assign', 'call', 'if', 'toplevel', 'do', 'return', 'label'); // do is checked carefully, however var NODES_WITHOUT_ELIMINATION_SIDE_EFFECTS = set('name', 'num', 'string', 'binary', 'sub', 'unary-prefix'); 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) diff --git a/tools/shared.py b/tools/shared.py index b55e60dc..c283c1f5 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.2.3' +EMSCRIPTEN_VERSION = '1.2.4' def check_sanity(force=False): try: |