aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AUTHORS1
-rwxr-xr-xemcc36
-rwxr-xr-xemscripten.py4
-rw-r--r--src/library.js17
-rw-r--r--src/library_gc.js71
-rw-r--r--src/library_jansson.js2
-rw-r--r--src/parseTools.js17
-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--src/runtime.js2
-rw-r--r--src/settings.js8
-rw-r--r--system/include/GLES/gl.h770
-rw-r--r--system/include/GLES/glext.h1278
-rw-r--r--system/include/GLES/glplatform.h30
-rw-r--r--system/include/dlfcn.h3
-rw-r--r--system/include/gc.h12
-rw-r--r--system/include/libc/sys/features.h5
-rw-r--r--system/include/libc/sys/types.h6
-rw-r--r--tests/hello_cxx03.cpp10
-rw-r--r--tests/hello_cxx11.cpp10
-rwxr-xr-xtests/runner.py155
-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.js13
-rw-r--r--tools/shared.py2
-rw-r--r--tools/test-js-optimizer-asm-pre-output.js2
-rw-r--r--tools/test-js-optimizer-asm-pre.js2
35 files changed, 2784 insertions, 570 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 73f12cda..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,
@@ -596,6 +603,10 @@ try:
keep_debug = False
bind = False
jcache = False
+ if use_cxx:
+ default_cxx_std = '-std=c++03' # Enforce a consistent C++ standard when compiling .cpp files, if user does not specify one on the cmdline.
+ else:
+ default_cxx_std = '' # Compiling C code with .c files, don't enforce a default C++ std.
def check_bad_eq(arg):
assert '=' not in arg, 'Invalid parameter (do not use "=" with "--" options)'
@@ -659,7 +670,11 @@ try:
keep_debug = True
elif newargs[i] == '--bind':
bind = True
- newargs[i] = '-std=c++11' # Force C++11 for embind code
+ newargs[i] = ''
+ if default_cxx_std:
+ default_cxx_std = '-std=c++11' # Force C++11 for embind code, but only if user has not explicitly overridden a standard.
+ elif newargs[i].startswith('-std='):
+ default_cxx_std = '' # User specified a standard to use, clear Emscripten from specifying it.
elif newargs[i].startswith('--embed-file'):
check_bad_eq(newargs[i])
embed_files.append(newargs[i+1])
@@ -717,6 +732,10 @@ try:
absolute_warning_shown = True
newargs = [ arg for arg in newargs if arg is not '' ]
+ # If user did not specify a default -std for C++ code, specify the emscripten default.
+ if default_cxx_std:
+ newargs = newargs + [default_cxx_std]
+
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
@@ -940,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)
@@ -948,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')
@@ -1195,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..623d1626 100644
--- a/src/library.js
+++ b/src/library.js
@@ -252,7 +252,7 @@ LibraryManager.library = {
var properties = {isFolder: true, isDevice: false, contents: {}};
return FS.createObject(parent, name, properties, canRead, canWrite);
},
- // Creates a a folder and all its missing parents.
+ // Creates a folder and all its missing parents.
createPath: function(parent, path, canRead, canWrite) {
var current = FS.findObject(parent);
if (current === null) throw new Error('Invalid parent.');
@@ -414,7 +414,7 @@ LibraryManager.library = {
processData(url);
}
},
- // Creates a link to a sepcific local path.
+ // Creates a link to a specific local path.
createLink: function(parent, name, target, canRead, canWrite) {
var properties = {isDevice: false, link: target};
return FS.createFile(parent, name, properties, canRead, canWrite);
@@ -1120,7 +1120,7 @@ LibraryManager.library = {
open: function(path, oflag, varargs) {
// int open(const char *path, int oflag, ...);
// http://pubs.opengroup.org/onlinepubs/009695399/functions/open.html
- // NOTE: This implementation tries to mimic glibc rather that strictly
+ // NOTE: This implementation tries to mimic glibc rather than strictly
// following the POSIX standard.
var mode = {{{ makeGetValue('varargs', 0, 'i32') }}};
@@ -1341,7 +1341,7 @@ LibraryManager.library = {
poll: function(fds, nfds, timeout) {
// int poll(struct pollfd fds[], nfds_t nfds, int timeout);
// http://pubs.opengroup.org/onlinepubs/009695399/functions/poll.html
- // NOTE: This is pretty much a no-op mimicing glibc.
+ // NOTE: This is pretty much a no-op mimicking glibc.
var offsets = ___pollfd_struct_layout;
var nonzero = 0;
for (var i = 0; i < nfds; i++) {
@@ -1505,7 +1505,7 @@ LibraryManager.library = {
// long fpathconf(int fildes, int name);
// http://pubs.opengroup.org/onlinepubs/000095399/functions/encrypt.html
// NOTE: The first parameter is ignored, so pathconf == fpathconf.
- // The constants here aren't real values. Just mimicing glibc.
+ // The constants here aren't real values. Just mimicking glibc.
switch (name) {
case {{{ cDefine('_PC_LINK_MAX') }}}:
return 32000;
@@ -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/library_jansson.js b/src/library_jansson.js
index 368584a7..93f239fc 100644
--- a/src/library_jansson.js
+++ b/src/library_jansson.js
@@ -74,7 +74,7 @@ var LibraryJansson = {
_free(node['stringValuePtr']);
},
- // Loads a string into the Javascript JSNON context
+ // Loads a string into the Javascript JSON context
// Only the root node is loaded. Child nodes are loaded on demand via `loadChildNodes` method.
load: function(string, flags, error) {
// This is potentially a security problem.
diff --git a/src/parseTools.js b/src/parseTools.js
index f5e2f33f..e081d0de 100644
--- a/src/parseTools.js
+++ b/src/parseTools.js
@@ -111,7 +111,7 @@ function isStructPointerType(type) {
// |%5()| as a function call (like |i32 (i8*)| etc.). So
// we must check later on, in call(), where we have more
// context, to differentiate such cases.
- // A similar thing happns in isStructType()
+ // A similar thing happens in isStructType()
return !Runtime.isNumberType(type) && type[0] == '%';
}
@@ -1045,9 +1045,14 @@ function asmCoercion(value, type, signedness) {
}
}
+var TWO_TWENTY = Math.pow(2, 20);
+
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 ((isNumber(a) && Math.abs(a) < TWO_TWENTY) || (isNumber(b) && Math.abs(b) < TWO_TWENTY)) {
+ return '(((' + a + ')*(' + b + '))&-1)'; // small enough to emit directly as a multiply
+ }
if (USE_MATH_IMUL) {
return 'Math.imul(' + a + ',' + b + ')';
}
@@ -1949,6 +1954,7 @@ function processMathop(item) {
if (item.type[0] === 'i') {
bits = parseInt(item.type.substr(1));
}
+ var bitsBefore = parseInt((item.params[0] ? item.params[0].type : item.type).substr(1)); // remove i to leave the number of bits left after this
var bitsLeft = parseInt(((item.params[1] && item.params[1].ident) ? item.params[1].ident : item.type).substr(1)); // remove i to leave the number of bits left after this operation
function integerizeBignum(value) {
@@ -2230,7 +2236,14 @@ function processMathop(item) {
}
// Note that zext has sign checking, see above. We must guard against -33 in i8 turning into -33 in i32
// then unsigning that i32... which would give something huge.
- case 'zext': case 'fpext': case 'sext': return idents[0];
+ case 'zext': {
+ if (EXPLICIT_ZEXT && bitsBefore == 1 && bitsLeft > 1) {
+ return '(' + originalIdents[0] + '?1:0)'; // explicit bool-to-int conversion, work around v8 issue 2513
+ break;
+ }
+ // otherwise, fall through
+ }
+ case 'fpext': case 'sext': return idents[0];
case 'fptrunc': return idents[0];
case 'select': return idents[0] + ' ? ' + asmEnsureFloat(idents[1], item.type) + ' : ' + asmEnsureFloat(idents[2], item.type);
case 'ptrtoint': case 'inttoptr': {
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)) {