summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AUTHORS1
-rwxr-xr-xemcc22
-rwxr-xr-xemscripten.py4
-rw-r--r--src/library.js7
-rw-r--r--src/library_gc.js71
-rw-r--r--src/relooper/Relooper.cpp16
-rw-r--r--src/relooper/test.txt4
-rw-r--r--src/relooper/test2.txt15
-rw-r--r--src/relooper/test3.txt38
-rw-r--r--src/relooper/test4.txt21
-rw-r--r--src/relooper/test6.txt15
-rw-r--r--src/relooper/test_debug.txt15
-rw-r--r--src/relooper/test_fuzz1.txt13
-rw-r--r--src/relooper/test_fuzz5.txt27
-rw-r--r--src/relooper/test_inf.txt651
-rw-r--r--system/include/gc.h9
-rw-r--r--system/include/libc/sys/features.h5
-rw-r--r--system/include/libc/sys/types.h6
-rwxr-xr-xtests/runner.py60
-rw-r--r--tools/eliminator/asm-eliminator-test-output.js8
-rw-r--r--tools/eliminator/asm-eliminator-test.js13
-rw-r--r--tools/eliminator/eliminator-test-output.js78
-rw-r--r--tools/js-optimizer.js2
-rw-r--r--tools/shared.py2
24 files changed, 594 insertions, 509 deletions
diff --git a/AUTHORS b/AUTHORS
index f491acc0..74efb628 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -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>
diff --git a/emcc b/emcc
index f21feb1f..ffce7363 100755
--- a/emcc
+++ b/emcc
@@ -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: