diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/analyzer.js | 2 | ||||
-rw-r--r-- | src/compiler.js | 2 | ||||
-rw-r--r-- | src/intertyper.js | 2 | ||||
-rw-r--r-- | src/jsifier.js | 2 | ||||
-rw-r--r-- | src/library.js | 64 | ||||
-rw-r--r-- | src/library_sdl.js | 60 | ||||
-rw-r--r-- | src/long.js | 11 | ||||
-rw-r--r-- | src/relooper/Relooper.cpp | 156 | ||||
-rw-r--r-- | src/relooper/fuzzer.py | 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-- | src/runtime.js | 5 | ||||
-rw-r--r-- | src/settings.js | 2 |
19 files changed, 636 insertions, 469 deletions
diff --git a/src/analyzer.js b/src/analyzer.js index ecb5ea6b..dbbb267d 100644 --- a/src/analyzer.js +++ b/src/analyzer.js @@ -1380,7 +1380,7 @@ function analyzer(data, sidePass) { var label = func.labels[i]; for (var j = 0; j < label.lines.length; j++) { var line = label.lines[j]; - if (line.intertype == 'call' && line.ident == setjmp) { + if ((line.intertype == 'call' || line.intertype == 'invoke') && line.ident == setjmp) { // Add a new label var oldIdent = label.ident; var newIdent = func.labelIdCounter++; diff --git a/src/compiler.js b/src/compiler.js index 1cd09c30..3047daf1 100644 --- a/src/compiler.js +++ b/src/compiler.js @@ -199,7 +199,7 @@ load('parseTools.js'); load('intertyper.js'); load('analyzer.js'); load('jsifier.js'); -if (RELOOP) load('relooper.js') +if (RELOOP) load(RELOOPER) globalEval(processMacros(preprocess(read('runtime.js')))); Runtime.QUANTUM_SIZE = QUANTUM_SIZE; diff --git a/src/intertyper.js b/src/intertyper.js index 6c88e765..2103ecfa 100644 --- a/src/intertyper.js +++ b/src/intertyper.js @@ -677,7 +677,7 @@ function intertyper(data, sidePass, baseLineNums) { item.type = item.tokens[1].text; Types.needAnalysis[item.type] = 0; while (['@', '%'].indexOf(item.tokens[2].text[0]) == -1 && !(item.tokens[2].text in PARSABLE_LLVM_FUNCTIONS) && - item.tokens[2].text != 'null' && item.tokens[2].text != 'asm') { + item.tokens[2].text != 'null' && item.tokens[2].text != 'asm' && item.tokens[2].text != 'undef') { assert(item.tokens[2].text != 'asm', 'Inline assembly cannot be compiled to JavaScript!'); item.tokens.splice(2, 1); } diff --git a/src/jsifier.js b/src/jsifier.js index ca404258..ff58ece2 100644 --- a/src/jsifier.js +++ b/src/jsifier.js @@ -1210,7 +1210,7 @@ function JSify(data, functionsOnly, givenFunctions) { case 'xchg': return '(tempValue=' + makeGetValue(param1, 0, type) + ',' + makeSetValue(param1, 0, param2, type, null, null, null, null, ',') + ',tempValue)'; case 'cmpxchg': { var param3 = finalizeLLVMParameter(item.params[2]); - return '(tempValue=' + makeGetValue(param1, 0, type) + ',(' + makeGetValue(param1, 0, type) + '==' + param2 + ' ? ' + makeSetValue(param1, 0, param3, type, null, null, null, null, ',') + ' : 0),tempValue)'; + return '(tempValue=' + makeGetValue(param1, 0, type) + ',(' + makeGetValue(param1, 0, type) + '==(' + param2 + '|0) ? ' + makeSetValue(param1, 0, param3, type, null, null, null, null, ',') + ' : 0),tempValue)'; } default: throw 'unhandled atomic op: ' + item.op; } diff --git a/src/library.js b/src/library.js index 1676a82c..848a2571 100644 --- a/src/library.js +++ b/src/library.js @@ -2403,6 +2403,7 @@ LibraryManager.library = { case {{{ cDefine('_SC_STREAM_MAX') }}}: return 16; case {{{ cDefine('_SC_TZNAME_MAX') }}}: return 6; case {{{ cDefine('_SC_THREAD_DESTRUCTOR_ITERATIONS') }}}: return 4; + case {{{ cDefine('_SC_NPROCESSORS_ONLN') }}}: return 1; } ___setErrNo(ERRNO_CODES.EINVAL); return -1; @@ -3669,6 +3670,17 @@ LibraryManager.library = { abs: 'Math.abs', labs: 'Math.abs', +#if USE_TYPED_ARRAYS == 2 + llabs__deps: [function() { Types.preciseI64MathUsed = 1 }], + llabs: function(lo, hi) { + i64Math.abs(lo, hi); + {{{ makeStructuralReturn([makeGetTempDouble(0, 'i32'), makeGetTempDouble(1, 'i32')]) }}}; + }, +#else + llabs: function(lo, hi) { + throw 'unsupported llabs'; + }, +#endif exit__deps: ['_exit'], exit: function(status) { @@ -5506,6 +5518,14 @@ LibraryManager.library = { return -a; }, copysignf: 'copysign', + __signbit__deps: ['copysign'], + __signbit: function(x) { + // We implement using copysign so that we get support + // for negative zero (once copysign supports that). + return _copysign(1.0, x) < 0; + }, + __signbitf: '__signbit', + __signbitd: '__signbit', hypot: function(a, b) { return Math.sqrt(a*a + b*b); }, @@ -6064,6 +6084,15 @@ LibraryManager.library = { __timespec_struct_layout: Runtime.generateStructInfo([ ['i32', 'tv_sec'], ['i32', 'tv_nsec']]), + nanosleep__deps: ['usleep', '__timespec_struct_layout'], + nanosleep: function(rqtp, rmtp) { + // int nanosleep(const struct timespec *rqtp, struct timespec *rmtp); + var seconds = {{{ makeGetValue('rqtp', '___timespec_struct_layout.tv_sec', 'i32') }}}; + var nanoseconds = {{{ makeGetValue('rqtp', '___timespec_struct_layout.tv_nsec', 'i32') }}}; + {{{ makeSetValue('rmtp', '___timespec_struct_layout.tv_sec', '0', 'i32') }}} + {{{ makeSetValue('rmtp', '___timespec_struct_layout.tv_nsec', '0', 'i32') }}} + return _usleep((seconds * 1e6) + (nanoseconds / 1000)); + }, // TODO: Implement these for real. clock_gettime__deps: ['__timespec_struct_layout'], clock_gettime: function(clk_id, tp) { @@ -6693,6 +6722,13 @@ LibraryManager.library = { }, // ========================================================================== + // sched.h (stubs only - no thread support yet!) + // ========================================================================== + sched_yield: function() { + return 0; + }, + + // ========================================================================== // pthread.h (stubs for mutexes only - no thread support yet!) // ========================================================================== @@ -6708,8 +6744,15 @@ LibraryManager.library = { }, pthread_cond_init: function() {}, pthread_cond_destroy: function() {}, - pthread_cond_broadcast: function() {}, - pthread_cond_wait: function() {}, + pthread_cond_broadcast: function() { + return 0; + }, + pthread_cond_wait: function() { + return 0; + }, + pthread_cond_timedwait: function() { + return 0; + }, pthread_self: function() { //FIXME: assumes only a single thread return 0; @@ -7368,6 +7411,23 @@ LibraryManager.library = { emscripten_random: function() { return Math.random(); }, + + emscripten_jcache_printf___deps: ['_formatString'], + emscripten_jcache_printf_: function(varargs) { + var MAX = 10240; + if (!_emscripten_jcache_printf_.buffer) { + _emscripten_jcache_printf_.buffer = _malloc(MAX); + } + var i = 0; + do { + var curr = {{{ makeGetValue('varargs', 'i*4', 'i8') }}}; + {{{ makeSetValue('_emscripten_jcache_printf_.buffer', 'i', 'curr', 'i8') }}}; + i++; + assert(i*4 < MAX); + } while (curr != 0); + Module.print(intArrayToString(__formatString(_emscripten_jcache_printf_.buffer, varargs + i*4)).replace('\\n', '')); + Runtime.stackAlloc(-4*i); // free up the stack space we know is ok to free + }, }; function autoAddDeps(object, name) { diff --git a/src/library_sdl.js b/src/library_sdl.js index 96ae6fa2..d707a8bf 100644 --- a/src/library_sdl.js +++ b/src/library_sdl.js @@ -1463,10 +1463,70 @@ var LibrarySDL = { return (SDL.music.audio && !SDL.music.audio.paused) ? 1 : 0; }, + // http://www.libsdl.org/projects/SDL_mixer/docs/SDL_mixer_38.html#SEC38 + // "Note: Does not check if the channel has been paused." + Mix_Playing: function(id) { + if (id === -1) { + var count = 0; + for (var i = 0; i < SDL.audios.length; i++) { + count += SDL.Mix_Playing(i); + } + return count; + } + var info = SDL.audios[id]; + if (info && info.audio && !info.audio.paused) { + return 1; + } + return 0; + }, + + Mix_Pause: function(id) { + if (id === -1) { + for (var i = 0; i<SDL.audios.length;i++) { + SDL.Mix_Pause(i); + } + return; + } + var info = SDL.audios[id]; + if (info && info.audio) { + info.audio.pause(); + } + }, + + // http://www.libsdl.org/projects/SDL_mixer/docs/SDL_mixer_39.html#SEC39 + Mix_Paused: function(id) { + if (id === -1) { + var pausedCount = 0; + for (var i = 0; i<SDL.audios.length;i++) { + pausedCount += SDL.Mix_Paused(i); + } + return pausedCount; + } + var info = SDL.audios[id]; + if (info && info.audio && info.audio.paused) { + return 1; + } + return 0; + }, + Mix_PausedMusic: function() { return (SDL.music.audio && SDL.music.audio.paused) ? 1 : 0; }, + // http://www.libsdl.org/projects/SDL_mixer/docs/SDL_mixer_33.html#SEC33 + Mix_Resume: function(id) { + if (id === -1) { + for (var i = 0; i<SDL.audios.length;i++) { + SDL.Mix_Resume(i); + } + return; + } + var info = SDL.audios[id]; + if (info && info.audio) { + info.audio.play(); + } + }, + // SDL TTF TTF_Init: function() { return 0 }, diff --git a/src/long.js b/src/long.js index c3b0e605..c3651bd9 100644 --- a/src/long.js +++ b/src/long.js @@ -1551,6 +1551,17 @@ var i64Math = (function() { // Emscripten wrapper HEAP32[tempDoublePtr>>2] = ret.low_; HEAP32[tempDoublePtr+4>>2] = ret.high_; }, + abs: function(l, h) { + var x = new goog.math.Long(l, h); + var ret; + if (x.isNegative()) { + ret = x.negate(); + } else { + ret = x; + } + HEAP32[tempDoublePtr>>2] = ret.low_; + HEAP32[tempDoublePtr+4>>2] = ret.high_; + }, ensureTemps: function() { if (Wrapper.ensuredTemps) return; Wrapper.ensuredTemps = true; diff --git a/src/relooper/Relooper.cpp b/src/relooper/Relooper.cpp index ae8577b1..ae393de3 100644 --- a/src/relooper/Relooper.cpp +++ b/src/relooper/Relooper.cpp @@ -347,17 +347,25 @@ struct RelooperRecursor { RelooperRecursor(Relooper *ParentInit) : Parent(ParentInit) {} }; +typedef std::list<Block*> BlockList; + void Relooper::Calculate(Block *Entry) { // Scan and optimize the input struct PreOptimizer : public RelooperRecursor { PreOptimizer(Relooper *Parent) : RelooperRecursor(Parent) {} BlockSet Live; - void FindLive(Block *Curr) { - if (Live.find(Curr) != Live.end()) return; - Live.insert(Curr); - for (BlockBranchMap::iterator iter = Curr->BranchesOut.begin(); iter != Curr->BranchesOut.end(); iter++) { - FindLive(iter->first); + void FindLive(Block *Root) { + BlockList ToInvestigate; + ToInvestigate.push_back(Root); + while (ToInvestigate.size() > 0) { + Block *Curr = ToInvestigate.front(); + ToInvestigate.pop_front(); + if (Live.find(Curr) != Live.end()) continue; + Live.insert(Curr); + for (BlockBranchMap::iterator iter = Curr->BranchesOut.begin(); iter != Curr->BranchesOut.end(); iter++) { + ToInvestigate.push_back(iter->first); + } } } @@ -529,7 +537,6 @@ void Relooper::Calculate(Block *Entry) { // ignore directly reaching the entry itself by another entry. void FindIndependentGroups(BlockSet &Blocks, BlockSet &Entries, BlockBlockSetMap& IndependentGroups) { typedef std::map<Block*, Block*> BlockBlockMap; - typedef std::list<Block*> BlockList; struct HelperClass { BlockBlockSetMap& IndependentGroups; @@ -872,33 +879,38 @@ void Relooper::Calculate(Block *Entry) { // A flow operation is trivially unneeded if the shape we naturally get to by normal code // execution is the same as the flow forces us to. void RemoveUnneededFlows(Shape *Root, Shape *Natural=NULL) { - SHAPE_SWITCH(Root, { - // If there is a next block, we already know at Simple creation time to make direct branches, - // and we can do nothing more. If there is no next however, then Natural is where we will - // go to by doing nothing, so we can potentially optimize some branches to direct. - if (Simple->Next) { - RemoveUnneededFlows(Simple->Next, Natural); - } else { - for (BlockBranchMap::iterator iter = Simple->Inner->ProcessedBranchesOut.begin(); iter != Simple->Inner->ProcessedBranchesOut.end(); iter++) { - Block *Target = iter->first; - Branch *Details = iter->second; - if (Details->Type != Branch::Direct && Target->Parent == Natural) { - Details->Type = Branch::Direct; - if (MultipleShape *Multiple = Shape::IsMultiple(Details->Ancestor)) { - Multiple->NeedLoop--; + Shape *Next = Root; + while (Next) { + Root = Next; + Next = NULL; + SHAPE_SWITCH(Root, { + // If there is a next block, we already know at Simple creation time to make direct branches, + // and we can do nothing more. If there is no next however, then Natural is where we will + // go to by doing nothing, so we can potentially optimize some branches to direct. + if (Simple->Next) { + Next = Simple->Next; + } else { + for (BlockBranchMap::iterator iter = Simple->Inner->ProcessedBranchesOut.begin(); iter != Simple->Inner->ProcessedBranchesOut.end(); iter++) { + Block *Target = iter->first; + Branch *Details = iter->second; + if (Details->Type != Branch::Direct && Target->Parent == Natural) { + Details->Type = Branch::Direct; + if (MultipleShape *Multiple = Shape::IsMultiple(Details->Ancestor)) { + Multiple->NeedLoop--; + } } } } - } - }, { - for (BlockShapeMap::iterator iter = Multiple->InnerMap.begin(); iter != Multiple->InnerMap.end(); iter++) { - RemoveUnneededFlows(iter->second, Multiple->Next); - } - RemoveUnneededFlows(Multiple->Next, Natural); - }, { - RemoveUnneededFlows(Loop->Inner, Loop->Inner); - RemoveUnneededFlows(Loop->Next, Natural); - }); + }, { + for (BlockShapeMap::iterator iter = Multiple->InnerMap.begin(); iter != Multiple->InnerMap.end(); iter++) { + RemoveUnneededFlows(iter->second, Multiple->Next); + } + Next = Multiple->Next; + }, { + RemoveUnneededFlows(Loop->Inner, Loop->Inner); + Next = Loop->Next; + }); + } } // After we know which loops exist, we can calculate which need to be labeled @@ -909,48 +921,54 @@ void Relooper::Calculate(Block *Entry) { } std::stack<Shape*> &LoopStack = *((std::stack<Shape*>*)Closure); - SHAPE_SWITCH(Root, { - MultipleShape *Fused = Shape::IsMultiple(Root->Next); - // If we are fusing a Multiple with a loop into this Simple, then visit it now - if (Fused && Fused->NeedLoop) { - LoopStack.push(Fused); - RECURSE_MULTIPLE_MANUAL(FindLabeledLoops, Fused); - } - for (BlockBranchMap::iterator iter = Simple->Inner->ProcessedBranchesOut.begin(); iter != Simple->Inner->ProcessedBranchesOut.end(); iter++) { - Block *Target = iter->first; - Branch *Details = iter->second; - if (Details->Type != Branch::Direct) { - assert(LoopStack.size() > 0); - if (Details->Ancestor != LoopStack.top()) { - LabeledShape *Labeled = Shape::IsLabeled(Details->Ancestor); - Labeled->Labeled = true; - Details->Labeled = true; - } else { - Details->Labeled = false; + Shape *Next = Root; + while (Next) { + Root = Next; + Next = NULL; + + SHAPE_SWITCH(Root, { + MultipleShape *Fused = Shape::IsMultiple(Root->Next); + // If we are fusing a Multiple with a loop into this Simple, then visit it now + if (Fused && Fused->NeedLoop) { + LoopStack.push(Fused); + RECURSE_MULTIPLE_MANUAL(FindLabeledLoops, Fused); + } + for (BlockBranchMap::iterator iter = Simple->Inner->ProcessedBranchesOut.begin(); iter != Simple->Inner->ProcessedBranchesOut.end(); iter++) { + Block *Target = iter->first; + Branch *Details = iter->second; + if (Details->Type != Branch::Direct) { + assert(LoopStack.size() > 0); + if (Details->Ancestor != LoopStack.top()) { + LabeledShape *Labeled = Shape::IsLabeled(Details->Ancestor); + Labeled->Labeled = true; + Details->Labeled = true; + } else { + Details->Labeled = false; + } } } - } - if (Fused && Fused->NeedLoop) { - LoopStack.pop(); - if (Fused->Next) FindLabeledLoops(Fused->Next); - } else { - if (Root->Next) FindLabeledLoops(Root->Next); - } - }, { - if (Multiple->NeedLoop) { - LoopStack.push(Multiple); - } - RECURSE_MULTIPLE(FindLabeledLoops); - if (Multiple->NeedLoop) { + if (Fused && Fused->NeedLoop) { + LoopStack.pop(); + Next = Fused->Next; + } else { + Next = Root->Next; + } + }, { + if (Multiple->NeedLoop) { + LoopStack.push(Multiple); + } + RECURSE_MULTIPLE(FindLabeledLoops); + if (Multiple->NeedLoop) { + LoopStack.pop(); + } + Next = Root->Next; + }, { + LoopStack.push(Loop); + RECURSE_LOOP(FindLabeledLoops); LoopStack.pop(); - } - if (Root->Next) FindLabeledLoops(Root->Next); - }, { - LoopStack.push(Loop); - RECURSE_LOOP(FindLabeledLoops); - LoopStack.pop(); - if (Root->Next) FindLabeledLoops(Root->Next); - }); + Next = Root->Next; + }); + } if (First) { delete (std::stack<Shape*>*)Closure; diff --git a/src/relooper/fuzzer.py b/src/relooper/fuzzer.py index 887eab3b..96929028 100644 --- a/src/relooper/fuzzer.py +++ b/src/relooper/fuzzer.py @@ -98,14 +98,14 @@ int main() { open('fuzz.slow.js', 'w').write(slow) open('fuzz.cpp', 'w').write(fast) print '_' - slow_out = subprocess.Popen(['/home/alon/Dev/mozilla-central/js/src/fast/js', '-m', '-n', 'fuzz.slow.js'], stdout=subprocess.PIPE).communicate()[0] + slow_out = subprocess.Popen(['/home/alon/Dev/odinmonkey/js/src/fast/js', '-m', '-n', 'fuzz.slow.js'], stdout=subprocess.PIPE).communicate()[0] print '.' subprocess.call(['g++', 'fuzz.cpp', 'Relooper.o', '-o', 'fuzz', '-g']) print '*' subprocess.call(['./fuzz'], stdout=open('fuzz.fast.js', 'w')) print '-' - fast_out = subprocess.Popen(['/home/alon/Dev/mozilla-central/js/src/fast/js', '-m', '-n', 'fuzz.fast.js'], stdout=subprocess.PIPE).communicate()[0] + fast_out = subprocess.Popen(['/home/alon/Dev/odinmonkey/js/src/fast/js', '-m', '-n', 'fuzz.fast.js'], stdout=subprocess.PIPE).communicate()[0] print if slow_out != fast_out: diff --git a/src/relooper/test2.txt b/src/relooper/test2.txt index a847e806..c77ce491 100644 --- a/src/relooper/test2.txt +++ b/src/relooper/test2.txt @@ -1,11 +1,12 @@ ep -L1: -if (ep -> LBB1) { - LBB1 - if (!(LBB1 -> LBB2)) { - break L1; +do { + if (ep -> LBB1) { + LBB1 + if (!(LBB1 -> LBB2)) { + break; + } + LBB2 } - LBB2 -} +} while(0); LBB3 diff --git a/src/relooper/test3.txt b/src/relooper/test3.txt index 7d06f06a..696542ef 100644 --- a/src/relooper/test3.txt +++ b/src/relooper/test3.txt @@ -1,25 +1,27 @@ ep -L1: -if (ep -> LBB1) { - LBB1 - if (!(LBB1 -> LBB2)) { - break L1; +do { + if (ep -> LBB1) { + LBB1 + if (!(LBB1 -> LBB2)) { + break; + } + LBB2 } - LBB2 -} +} while(0); LBB3 -L5: -if (LBB3 -> LBB4) { - LBB4 - if (!(LBB4 -> LBB5)) { - break L5; - } - while(1) { - LBB5 - if (LBB5 -> LBB6) { - break L5; +L5: do { + if (LBB3 -> LBB4) { + LBB4 + if (!(LBB4 -> LBB5)) { + break; + } + while(1) { + LBB5 + if (LBB5 -> LBB6) { + break L5; + } } } -} +} while(0); LBB6 diff --git a/src/relooper/test4.txt b/src/relooper/test4.txt index 2ab3265a..f0bfb972 100644 --- a/src/relooper/test4.txt +++ b/src/relooper/test4.txt @@ -1,16 +1,17 @@ //19 -L1: -if ( 1 ) { - //20 - if (!( 1 )) { +do { + if ( 1 ) { + //20 + if (!( 1 )) { + label = 4; + break; + } + //21 + break; + } else { label = 4; - break L1; } - //21 - break L1; -} else { - label = 4; -} +} while(0); if (label == 4) { //22 } diff --git a/src/relooper/test6.txt b/src/relooper/test6.txt index 0ec7e666..c5effd08 100644 --- a/src/relooper/test6.txt +++ b/src/relooper/test6.txt @@ -1,11 +1,12 @@ //0 -L1: -if (check(0)) { - //1 - if (!(check(1))) { - break L1; +do { + if (check(0)) { + //1 + if (!(check(1))) { + break; + } + //2 } - //2 -} +} while(0); //3 diff --git a/src/relooper/test_debug.txt b/src/relooper/test_debug.txt index 02377fb7..1c7d0508 100644 --- a/src/relooper/test_debug.txt +++ b/src/relooper/test_debug.txt @@ -83,13 +83,14 @@ int main() { // === Optimizing shapes === // Fusing Multiple to Simple ep -L1: -if (ep -> LBB1) { - LBB1 - if (!(LBB1 -> LBB2)) { - break L1; +do { + if (ep -> LBB1) { + LBB1 + if (!(LBB1 -> LBB2)) { + break; + } + LBB2 } - LBB2 -} +} while(0); LBB3 diff --git a/src/relooper/test_fuzz1.txt b/src/relooper/test_fuzz1.txt index 09edb594..5122257e 100644 --- a/src/relooper/test_fuzz1.txt +++ b/src/relooper/test_fuzz1.txt @@ -3,12 +3,13 @@ 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(); -L3: -if (state == 7) { - print(7); state = check(); - label = 3; - break L3; -} +do { + if (state == 7) { + print(7); state = check(); + label = 3; + break; + } +} while(0); L5: while(1) { if (label == 3) { label = 0; diff --git a/src/relooper/test_fuzz5.txt b/src/relooper/test_fuzz5.txt index 7c795d53..9548205c 100644 --- a/src/relooper/test_fuzz5.txt +++ b/src/relooper/test_fuzz5.txt @@ -3,21 +3,22 @@ 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(); - L3: - if (state % 3 == 1) { - label = 3; - } else if (state % 3 == 0) { - print(8); state = check(); - if (state % 2 == 0) { - label = 5; - break L3; + 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; + } } else { - label = 7; - break L3; + break L1; } - } else { - break L1; - } + } while(0); while(1) { if (label == 3) { label = 0; diff --git a/src/relooper/test_inf.txt b/src/relooper/test_inf.txt index 3e292433..379d2083 100644 --- a/src/relooper/test_inf.txt +++ b/src/relooper/test_inf.txt @@ -5,34 +5,35 @@ if (uint(i4) >= uint(i5)) { code 1 } code 3 -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; +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; + } } } -} +} while(0); code 15 if (uint(i4) >= uint(i5)) { code 17 @@ -40,178 +41,179 @@ if (uint(i4) >= uint(i5)) { code 16 } code 18 -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 |