summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2013-08-26 14:50:01 -0700
committerAlon Zakai <alonzakai@gmail.com>2013-08-26 14:50:01 -0700
commit1cc28b8e9e94267041bc71afebfbbe3059db4a3f (patch)
tree107571ed84b48bab5bfb5aea6b7e5b01b814929f
parent06e7518718115977026830676b80c7279e924b5f (diff)
parent422d9a1f3227ae8f47fa8bd0037c2220bb2017f7 (diff)
Merge branch 'incoming'
-rw-r--r--AUTHORS2
-rw-r--r--em++.bat2
-rw-r--r--em-config.bat2
-rw-r--r--emar.bat2
-rwxr-xr-xemcc60
-rw-r--r--emcc.bat2
-rw-r--r--emconfigure.bat2
-rw-r--r--emlibtool.bat2
-rw-r--r--emmake.bat2
-rw-r--r--emranlib.bat2
-rwxr-xr-xemscripten.py86
-rw-r--r--src/compiler.js3
-rw-r--r--src/headless.js703
-rw-r--r--src/headlessCanvas.js618
-rw-r--r--src/jsifier.js83
-rw-r--r--src/library.js28
-rw-r--r--src/library_browser.js24
-rw-r--r--src/library_fs.js12
-rw-r--r--src/library_glut.js26
-rw-r--r--src/library_memfs.js51
-rw-r--r--src/library_openal.js33
-rw-r--r--src/library_sdl.js51
-rw-r--r--src/parseTools.js28
-rw-r--r--src/postamble.js8
-rw-r--r--src/preamble.js1
-rw-r--r--src/relooper/Relooper.cpp82
-rw-r--r--src/relooper/Relooper.h5
-rw-r--r--src/relooper/emscripten/glue.js11
-rw-r--r--src/relooper/fuzzer.py29
-rw-r--r--src/relooper/test.cpp100
-rw-r--r--src/relooper/test.txt177
-rw-r--r--src/relooper/test2.c26
-rw-r--r--src/relooper/test2.txt20
-rw-r--r--src/relooper/test3.c14
-rw-r--r--src/relooper/test3.txt43
-rw-r--r--src/relooper/test4.cpp14
-rw-r--r--src/relooper/test4.txt35
-rw-r--r--src/relooper/test5.cpp12
-rw-r--r--src/relooper/test5.txt44
-rw-r--r--src/relooper/test6.cpp8
-rw-r--r--src/relooper/test6.txt20
-rw-r--r--src/relooper/test_dead.cpp4
-rw-r--r--src/relooper/test_debug.cpp8
-rw-r--r--src/relooper/test_debug.txt20
-rw-r--r--src/relooper/test_fuzz1.cpp18
-rw-r--r--src/relooper/test_fuzz1.txt50
-rw-r--r--src/relooper/test_fuzz2.cpp8
-rw-r--r--src/relooper/test_fuzz2.txt19
-rw-r--r--src/relooper/test_fuzz3.cpp10
-rw-r--r--src/relooper/test_fuzz3.txt16
-rw-r--r--src/relooper/test_fuzz4.cpp10
-rw-r--r--src/relooper/test_fuzz4.txt28
-rw-r--r--src/relooper/test_fuzz5.cpp20
-rw-r--r--src/relooper/test_fuzz5.txt64
-rw-r--r--src/relooper/test_fuzz6.cpp184
-rw-r--r--src/relooper/test_fuzz6.txt219
-rw-r--r--src/relooper/test_inf.cpp368
-rw-r--r--src/relooper/test_inf.txt1410
-rw-r--r--src/runtime.js40
-rw-r--r--src/settings.js22
-rw-r--r--src/shell.html2
-rw-r--r--system/include/emscripten/emscripten.h16
-rw-r--r--tests/aniso.c1
-rw-r--r--tests/cubegeom_color.c1
-rw-r--r--tests/cubegeom_pre.c1
-rw-r--r--tests/cubegeom_pre2.c1
-rw-r--r--tests/cubegeom_pre2_vao.c1
-rw-r--r--tests/cubegeom_pre2_vao2.c1
-rw-r--r--tests/cubegeom_pre3.c1
-rw-r--r--tests/cubegeom_pre_vao.c1
-rw-r--r--tests/cubegeom_texturematrix.c1
-rw-r--r--tests/float_tex.cpp2
-rw-r--r--tests/gl_matrix_identity.c1
-rw-r--r--tests/glshaderinfo.cpp2
-rw-r--r--tests/glut_touchevents.c64
-rw-r--r--tests/http.h1
-rw-r--r--tests/pthread/specific.c60
-rw-r--r--tests/pthread/specific.c.txt8
-rwxr-xr-xtests/runner.py1
-rw-r--r--tests/s3tc.c1
-rw-r--r--tests/s3tc_crunch.c1
-rw-r--r--tests/sdl_canvas.c11
-rw-r--r--tests/sdl_headless.c65
-rw-r--r--tests/sdl_image_prepare_data.c2
-rw-r--r--tests/sdl_pumpevents.c16
-rw-r--r--tests/sockets/test_enet_client.c2
-rw-r--r--tests/sockets/test_sockets_echo_server.c2
-rw-r--r--tests/sockets/test_sockets_partial_server.c5
-rw-r--r--tests/sockets/test_sockets_select_server_down_client.c (renamed from tests/sockets/test_sockets_select_server_no_accept_client.c)0
-rw-r--r--tests/sockets/test_sockets_select_server_down_server.c (renamed from tests/sockets/test_sockets_select_server_no_accept_server.c)41
-rw-r--r--tests/test_browser.py23
-rw-r--r--tests/test_core.py149
-rw-r--r--tests/test_other.py29
-rw-r--r--tests/test_sanity.py27
-rw-r--r--tests/test_sockets.py9
-rw-r--r--tests/tex_nonbyte.c1
-rw-r--r--tests/unistd/misc.out7
-rw-r--r--tools/file_packager.py107
-rw-r--r--tools/js-optimizer.js95
-rw-r--r--tools/js_optimizer.py4
-rw-r--r--tools/jsrun.py2
-rw-r--r--tools/shared.py2
-rw-r--r--tools/test-js-optimizer-asm-outline1-output.js136
-rw-r--r--tools/test-js-optimizer-asm-outline1.js48
104 files changed, 4030 insertions, 1912 deletions
diff --git a/AUTHORS b/AUTHORS
index 5161f7ad..59eb27d3 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -93,4 +93,6 @@ a license to everyone to use it as detailed in LICENSE.)
* Yu Kobayashi <yukoba@accelart.jp>
* Pin Zhang <zhangpin04@gmail.com>
* Nick Bray <ncbray@chromium.org> (copyright owned by Google, Inc.)
+* Aidan Hobson Sayers <aidanhs@cantab.net>
+* Charlie Birks <admin@daftgames.net>
diff --git a/em++.bat b/em++.bat
index b639ff29..e486fcea 100644
--- a/em++.bat
+++ b/em++.bat
@@ -1,2 +1,2 @@
@echo off
-python %~dp0\em++ %* \ No newline at end of file
+python "%~dp0\em++" %* \ No newline at end of file
diff --git a/em-config.bat b/em-config.bat
index 63b15ea4..52d1af0e 100644
--- a/em-config.bat
+++ b/em-config.bat
@@ -1,2 +1,2 @@
@echo off
-python %~dp0\em-config %* \ No newline at end of file
+python "%~dp0\em-config" %* \ No newline at end of file
diff --git a/emar.bat b/emar.bat
index 2cfb0850..9ebc2d41 100644
--- a/emar.bat
+++ b/emar.bat
@@ -1,2 +1,2 @@
@echo off
-python %~dp0\emar %* \ No newline at end of file
+python "%~dp0\emar" %* \ No newline at end of file
diff --git a/emcc b/emcc
index df2ef38c..a07ce4f1 100755
--- a/emcc
+++ b/emcc
@@ -1577,6 +1577,35 @@ try:
js_transform_tempfiles = [final]
+ if memory_init_file:
+ if shared.Settings.USE_TYPED_ARRAYS != 2:
+ if type(memory_init_file) == int: logging.warning('memory init file requires typed arrays mode 2')
+ else:
+ memfile = target + '.mem'
+ shared.try_delete(memfile)
+ def repl(m):
+ # handle chunking of the memory initializer
+ s = re.sub('[\[\]\n\(\)\. ]', '', m.groups(0)[0])
+ s = s.replace('concat', ',')
+ if s[-1] == ',': s = s[:-1]
+ open(memfile, 'wb').write(''.join(map(lambda x: chr(int(x or '0')), s.split(','))))
+ if DEBUG:
+ # Copy into temp dir as well, so can be run there too
+ temp_memfile = os.path.join(shared.EMSCRIPTEN_TEMP_DIR, os.path.basename(memfile))
+ if os.path.abspath(memfile) != os.path.abspath(memfile):
+ shutil.copyfile(memfile, temp_memfile)
+ return 'loadMemoryInitializer("%s");' % os.path.basename(memfile)
+ src = re.sub(shared.JS.memory_initializer_pattern, repl, open(final).read(), count=1)
+ open(final + '.mem.js', 'w').write(src)
+ final += '.mem.js'
+ js_transform_tempfiles[-1] = final # simple text substitution preserves comment line number mappings
+ if DEBUG:
+ if os.path.exists(memfile):
+ save_intermediate('meminit')
+ logging.debug('wrote memory initialization to %s' % memfile)
+ else:
+ logging.debug('did not see memory initialization')
+
# It is useful to run several js optimizer passes together, to save on unneeded unparsing/reparsing
js_optimizer_queue = []
js_optimizer_extra_info = {}
@@ -1631,7 +1660,7 @@ try:
if DEBUG: save_intermediate('closure')
if js_opts:
- if shared.Settings.OUTLINING_LIMIT > 0:
+ if shared.Settings.OUTLINING_LIMIT > 0 and shared.Settings.ASM_JS:
js_optimizer_queue += ['outline']
js_optimizer_extra_info['sizeToOutline'] = shared.Settings.OUTLINING_LIMIT
@@ -1654,35 +1683,6 @@ try:
src = re.sub(r'\n+[ \n]*\n+', '\n', src)
open(final, 'w').write(src)
- if memory_init_file:
- if shared.Settings.USE_TYPED_ARRAYS != 2:
- if type(memory_init_file) == int: logging.warning('memory init file requires typed arrays mode 2')
- else:
- memfile = target + '.mem'
- shared.try_delete(memfile)
- def repl(m):
- # handle chunking of the memory initializer
- s = re.sub('[\[\]\n\(\)\. ]', '', m.groups(0)[0])
- s = s.replace('concat', ',')
- if s[-1] == ',': s = s[:-1]
- open(memfile, 'wb').write(''.join(map(lambda x: chr(int(x or '0')), s.split(','))))
- if DEBUG:
- # Copy into temp dir as well, so can be run there too
- temp_memfile = os.path.join(shared.EMSCRIPTEN_TEMP_DIR, os.path.basename(memfile))
- if os.path.abspath(memfile) != os.path.abspath(memfile):
- shutil.copyfile(memfile, temp_memfile)
- return 'loadMemoryInitializer("%s");' % os.path.basename(memfile)
- src = re.sub(shared.JS.memory_initializer_pattern, repl, src, count=1)
- open(final + '.mem.js', 'w').write(src)
- final += '.mem.js'
- js_transform_tempfiles[-1] = final # simple text substitution preserves comment line number mappings
- if DEBUG:
- if os.path.exists(memfile):
- save_intermediate('meminit')
- logging.debug('wrote memory initialization to %s' % memfile)
- else:
- logging.debug('did not see memory initialization')
-
def generate_source_map(map_file_base_name, offset=0):
jsrun.run_js(shared.path_from_root('tools', 'source-maps', 'sourcemapper.js'),
shared.NODE_JS, js_transform_tempfiles +
diff --git a/emcc.bat b/emcc.bat
index 2cb3a3e1..e1ca45c7 100644
--- a/emcc.bat
+++ b/emcc.bat
@@ -1,2 +1,2 @@
@echo off
-python %~dp0\emcc %* \ No newline at end of file
+python "%~dp0\emcc" %* \ No newline at end of file
diff --git a/emconfigure.bat b/emconfigure.bat
index f900f407..651ccf05 100644
--- a/emconfigure.bat
+++ b/emconfigure.bat
@@ -1,2 +1,2 @@
@echo off
-python %~dp0\emconfigure %* \ No newline at end of file
+python "%~dp0\emconfigure" %* \ No newline at end of file
diff --git a/emlibtool.bat b/emlibtool.bat
index 76ce48c3..4ea705be 100644
--- a/emlibtool.bat
+++ b/emlibtool.bat
@@ -1,2 +1,2 @@
@echo off
-python %~dp0\emlibtool %* \ No newline at end of file
+python "%~dp0\emlibtool" %* \ No newline at end of file
diff --git a/emmake.bat b/emmake.bat
index 2db09d07..a86ba6e2 100644
--- a/emmake.bat
+++ b/emmake.bat
@@ -1,2 +1,2 @@
@echo off
-python %~dp0\emmake %* \ No newline at end of file
+python "%~dp0\emmake" %* \ No newline at end of file
diff --git a/emranlib.bat b/emranlib.bat
index 69bf8aa4..a8af4ef7 100644
--- a/emranlib.bat
+++ b/emranlib.bat
@@ -1,2 +1,2 @@
@echo off
-python %~dp0\emranlib %* \ No newline at end of file
+python "%~dp0\emranlib" %* \ No newline at end of file
diff --git a/emscripten.py b/emscripten.py
index a156ca73..c5e235d8 100755
--- a/emscripten.py
+++ b/emscripten.py
@@ -552,52 +552,52 @@ var asm = (function(global, env, buffer) {
''' + ''.join(['''
var tempRet%d = 0;''' % i for i in range(10)]) + '\n' + asm_global_funcs + '''
// EMSCRIPTEN_START_FUNCS
- function stackAlloc(size) {
- size = size|0;
- var ret = 0;
- ret = STACKTOP;
- STACKTOP = (STACKTOP + size)|0;
+function stackAlloc(size) {
+ size = size|0;
+ var ret = 0;
+ ret = STACKTOP;
+ STACKTOP = (STACKTOP + size)|0;
''' + ('STACKTOP = ((STACKTOP + 3)>>2)<<2;' if settings['TARGET_X86'] else 'STACKTOP = ((STACKTOP + 7)>>3)<<3;') + '''
- return ret|0;
- }
- function stackSave() {
- return STACKTOP|0;
- }
- function stackRestore(top) {
- top = top|0;
- STACKTOP = top;
- }
- function setThrew(threw, value) {
- threw = threw|0;
- value = value|0;
- if ((__THREW__|0) == 0) {
- __THREW__ = threw;
- threwValue = value;
- }
- }
- function copyTempFloat(ptr) {
- ptr = ptr|0;
- HEAP8[tempDoublePtr] = HEAP8[ptr];
- HEAP8[tempDoublePtr+1|0] = HEAP8[ptr+1|0];
- HEAP8[tempDoublePtr+2|0] = HEAP8[ptr+2|0];
- HEAP8[tempDoublePtr+3|0] = HEAP8[ptr+3|0];
- }
- function copyTempDouble(ptr) {
- ptr = ptr|0;
- HEAP8[tempDoublePtr] = HEAP8[ptr];
- HEAP8[tempDoublePtr+1|0] = HEAP8[ptr+1|0];
- HEAP8[tempDoublePtr+2|0] = HEAP8[ptr+2|0];
- HEAP8[tempDoublePtr+3|0] = HEAP8[ptr+3|0];
- HEAP8[tempDoublePtr+4|0] = HEAP8[ptr+4|0];
- HEAP8[tempDoublePtr+5|0] = HEAP8[ptr+5|0];
- HEAP8[tempDoublePtr+6|0] = HEAP8[ptr+6|0];
- HEAP8[tempDoublePtr+7|0] = HEAP8[ptr+7|0];
+ return ret|0;
+}
+function stackSave() {
+ return STACKTOP|0;
+}
+function stackRestore(top) {
+ top = top|0;
+ STACKTOP = top;
+}
+function setThrew(threw, value) {
+ threw = threw|0;
+ value = value|0;
+ if ((__THREW__|0) == 0) {
+ __THREW__ = threw;
+ threwValue = value;
}
+}
+function copyTempFloat(ptr) {
+ ptr = ptr|0;
+ HEAP8[tempDoublePtr] = HEAP8[ptr];
+ HEAP8[tempDoublePtr+1|0] = HEAP8[ptr+1|0];
+ HEAP8[tempDoublePtr+2|0] = HEAP8[ptr+2|0];
+ HEAP8[tempDoublePtr+3|0] = HEAP8[ptr+3|0];
+}
+function copyTempDouble(ptr) {
+ ptr = ptr|0;
+ HEAP8[tempDoublePtr] = HEAP8[ptr];
+ HEAP8[tempDoublePtr+1|0] = HEAP8[ptr+1|0];
+ HEAP8[tempDoublePtr+2|0] = HEAP8[ptr+2|0];
+ HEAP8[tempDoublePtr+3|0] = HEAP8[ptr+3|0];
+ HEAP8[tempDoublePtr+4|0] = HEAP8[ptr+4|0];
+ HEAP8[tempDoublePtr+5|0] = HEAP8[ptr+5|0];
+ HEAP8[tempDoublePtr+6|0] = HEAP8[ptr+6|0];
+ HEAP8[tempDoublePtr+7|0] = HEAP8[ptr+7|0];
+}
''' + ''.join(['''
- function setTempRet%d(value) {
- value = value|0;
- tempRet%d = value;
- }
+function setTempRet%d(value) {
+ value = value|0;
+ tempRet%d = value;
+}
''' % (i, i) for i in range(10)])] + [PostSets.js + '\n'] + funcs_js + ['''
%s
diff --git a/src/compiler.js b/src/compiler.js
index 2390f4c9..0baec95e 100644
--- a/src/compiler.js
+++ b/src/compiler.js
@@ -185,8 +185,7 @@ if (ASM_JS) {
assert(!ALLOW_MEMORY_GROWTH, 'Cannot grow asm.js heap');
assert((TOTAL_MEMORY&(TOTAL_MEMORY-1)) == 0, 'asm.js heap must be power of 2');
}
-assert(!BUILD_AS_SHARED_LIB, 'shared libs are deprecated');
-//assert(!(!NAMED_GLOBALS && BUILD_AS_SHARED_LIB), 'shared libraries must have named globals');
+assert(!(!NAMED_GLOBALS && BUILD_AS_SHARED_LIB), 'shared libraries must have named globals');
// Output some info and warnings based on settings
diff --git a/src/headless.js b/src/headless.js
index 097a42f7..e5458641 100644
--- a/src/headless.js
+++ b/src/headless.js
@@ -1,54 +1,50 @@
//== HEADLESS ==//
-// TODO: sync from bananabread headless.js
+var headlessPrint = function(x) {
+ //print(x);
+}
var window = {
- eventListeners: {},
- addEventListener: function(id, func) {
- var listeners = this.eventListeners[id];
- if (!listeners) {
- listeners = this.eventListeners[id] = [];
- }
- listeners.push(func);
- },
- callEventListeners: function(id) {
- var listeners = this.eventListeners[id];
- if (listeners) {
- listeners.forEach(function(listener) { listener() });
- }
- },
+ // adjustable parameters
location: {
toString: function() {
return '%s';
},
search: '?%s',
+ pathname: '%s',
},
+ onIdle: function(){ headlessPrint('triggering click'); document.querySelector('.fullscreen-button.low-res').callEventListeners('click'); window.onIdle = null; },
+ dirsToDrop: 0, // go back to root dir if first_js is in a subdir
+ //
+
+ headless: true,
+
+ stopped: false,
fakeNow: 0, // we don't use Date.now()
rafs: [],
timeouts: [],
uid: 0,
requestAnimationFrame: function(func) {
func.uid = window.uid++;
- print('adding raf ' + func.uid);
+ headlessPrint('adding raf ' + func.uid);
window.rafs.push(func);
},
setTimeout: function(func, ms) {
func.uid = window.uid++;
- print('adding timeout ' + func.uid);
+ headlessPrint('adding timeout ' + func.uid);
window.timeouts.push({
func: func,
when: window.fakeNow + (ms || 0)
});
window.timeouts.sort(function(x, y) { return y.when - x.when });
},
- onIdle: %s,
runEventLoop: function() {
// run forever until an exception stops this replay
var iter = 0;
- while (1) {
- var start = Recorder.dnow();
- print('event loop: ' + (iter++));
+ while (!this.stopped) {
+ var start = Date.realNow();
+ headlessPrint('event loop: ' + (iter++));
if (window.rafs.length == 0 && window.timeouts.length == 0) {
if (window.onIdle) {
window.onIdle();
@@ -61,7 +57,7 @@ var window = {
window.rafs = [];
for (var i = 0; i < currRafs.length; i++) {
var raf = currRafs[i];
- print('calling raf: ' + raf.uid);// + ': ' + raf.toString().substring(0, 50));
+ headlessPrint('calling raf: ' + raf.uid);// + ': ' + raf.toString().substring(0, 50));
raf();
}
// timeouts
@@ -70,23 +66,14 @@ var window = {
window.timeouts = [];
while (timeouts.length && timeouts[timeouts.length-1].when <= now) {
var timeout = timeouts.pop();
- print('calling timeout: ' + timeout.func.uid);// + ': ' + timeout.func.toString().substring(0, 50));
+ headlessPrint('calling timeout: ' + timeout.func.uid);// + ': ' + timeout.func.toString().substring(0, 50));
timeout.func();
}
// increment 'time'
window.fakeNow += 16.666;
- print('main event loop iteration took ' + (Recorder.dnow() - start) + ' ms');
+ headlessPrint('main event loop iteration took ' + (Date.realNow() - start) + ' ms');
}
},
- URL: {
- createObjectURL: function(x) {
- return x; // the blob itself is returned
- },
- revokeObjectURL: function(x) {},
- },
-};
-var setTimeout = window.setTimeout;
-var document = {
eventListeners: {},
addEventListener: function(id, func) {
var listeners = this.eventListeners[id];
@@ -101,619 +88,25 @@ var document = {
listeners.forEach(function(listener) { listener() });
}
},
+ URL: {
+ createObjectURL: function(x) {
+ return x; // the blob itself is returned
+ },
+ revokeObjectURL: function(x) {},
+ },
+ encodeURIComponent: function(x) { return x },
+};
+var setTimeout = window.setTimeout;
+var document = {
+ headless: true,
+ eventListeners: {},
+ addEventListener: window.addEventListener,
+ callEventListeners: window.callEventListeners,
getElementById: function(id) {
switch(id) {
case 'canvas': {
if (this.canvas) return this.canvas;
- return this.canvas = {
- getContext: function(which) {
- switch(which) {
- case 'experimental-webgl': {
- return {
- /* ClearBufferMask */
- DEPTH_BUFFER_BIT : 0x00000100,
- STENCIL_BUFFER_BIT : 0x00000400,
- COLOR_BUFFER_BIT : 0x00004000,
-
- /* BeginMode */
- POINTS : 0x0000,
- LINES : 0x0001,
- LINE_LOOP : 0x0002,
- LINE_STRIP : 0x0003,
- TRIANGLES : 0x0004,
- TRIANGLE_STRIP : 0x0005,
- TRIANGLE_FAN : 0x0006,
-
- /* AlphaFunction (not supported in ES20) */
- /* NEVER */
- /* LESS */
- /* EQUAL */
- /* LEQUAL */
- /* GREATER */
- /* NOTEQUAL */
- /* GEQUAL */
- /* ALWAYS */
-
- /* BlendingFactorDest */
- ZERO : 0,
- ONE : 1,
- SRC_COLOR : 0x0300,
- ONE_MINUS_SRC_COLOR : 0x0301,
- SRC_ALPHA : 0x0302,
- ONE_MINUS_SRC_ALPHA : 0x0303,
- DST_ALPHA : 0x0304,
- ONE_MINUS_DST_ALPHA : 0x0305,
-
- /* BlendingFactorSrc */
- /* ZERO */
- /* ONE */
- DST_COLOR : 0x0306,
- ONE_MINUS_DST_COLOR : 0x0307,
- SRC_ALPHA_SATURATE : 0x0308,
- /* SRC_ALPHA */
- /* ONE_MINUS_SRC_ALPHA */
- /* DST_ALPHA */
- /* ONE_MINUS_DST_ALPHA */
-
- /* BlendEquationSeparate */
- FUNC_ADD : 0x8006,
- BLEND_EQUATION : 0x8009,
- BLEND_EQUATION_RGB : 0x8009, /* same as BLEND_EQUATION */
- BLEND_EQUATION_ALPHA : 0x883D,
-
- /* BlendSubtract */
- FUNC_SUBTRACT : 0x800A,
- FUNC_REVERSE_SUBTRACT : 0x800B,
-
- /* Separate Blend Functions */
- BLEND_DST_RGB : 0x80C8,
- BLEND_SRC_RGB : 0x80C9,
- BLEND_DST_ALPHA : 0x80CA,
- BLEND_SRC_ALPHA : 0x80CB,
- CONSTANT_COLOR : 0x8001,
- ONE_MINUS_CONSTANT_COLOR : 0x8002,
- CONSTANT_ALPHA : 0x8003,
- ONE_MINUS_CONSTANT_ALPHA : 0x8004,
- BLEND_COLOR : 0x8005,
-
- /* Buffer Objects */
- ARRAY_BUFFER : 0x8892,
- ELEMENT_ARRAY_BUFFER : 0x8893,
- ARRAY_BUFFER_BINDING : 0x8894,
- ELEMENT_ARRAY_BUFFER_BINDING : 0x8895,
-
- STREAM_DRAW : 0x88E0,
- STATIC_DRAW : 0x88E4,
- DYNAMIC_DRAW : 0x88E8,
-
- BUFFER_SIZE : 0x8764,
- BUFFER_USAGE : 0x8765,
-
- CURRENT_VERTEX_ATTRIB : 0x8626,
-
- /* CullFaceMode */
- FRONT : 0x0404,
- BACK : 0x0405,
- FRONT_AND_BACK : 0x0408,
-
- /* DepthFunction */
- /* NEVER */
- /* LESS */
- /* EQUAL */
- /* LEQUAL */
- /* GREATER */
- /* NOTEQUAL */
- /* GEQUAL */
- /* ALWAYS */
-
- /* EnableCap */
- /* TEXTURE_2D */
- CULL_FACE : 0x0B44,
- BLEND : 0x0BE2,
- DITHER : 0x0BD0,
- STENCIL_TEST : 0x0B90,
- DEPTH_TEST : 0x0B71,
- SCISSOR_TEST : 0x0C11,
- POLYGON_OFFSET_FILL : 0x8037,
- SAMPLE_ALPHA_TO_COVERAGE : 0x809E,
- SAMPLE_COVERAGE : 0x80A0,
-
- /* ErrorCode */
- NO_ERROR : 0,
- INVALID_ENUM : 0x0500,
- INVALID_VALUE : 0x0501,
- INVALID_OPERATION : 0x0502,
- OUT_OF_MEMORY : 0x0505,
-
- /* FrontFaceDirection */
- CW : 0x0900,
- CCW : 0x0901,
-
- /* GetPName */
- LINE_WIDTH : 0x0B21,
- ALIASED_POINT_SIZE_RANGE : 0x846D,
- ALIASED_LINE_WIDTH_RANGE : 0x846E,
- CULL_FACE_MODE : 0x0B45,
- FRONT_FACE : 0x0B46,
- DEPTH_RANGE : 0x0B70,
- DEPTH_WRITEMASK : 0x0B72,
- DEPTH_CLEAR_VALUE : 0x0B73,
- DEPTH_FUNC : 0x0B74,
- STENCIL_CLEAR_VALUE : 0x0B91,
- STENCIL_FUNC : 0x0B92,
- STENCIL_FAIL : 0x0B94,
- STENCIL_PASS_DEPTH_FAIL : 0x0B95,
- STENCIL_PASS_DEPTH_PASS : 0x0B96,
- STENCIL_REF : 0x0B97,
- STENCIL_VALUE_MASK : 0x0B93,
- STENCIL_WRITEMASK : 0x0B98,
- STENCIL_BACK_FUNC : 0x8800,
- STENCIL_BACK_FAIL : 0x8801,
- STENCIL_BACK_PASS_DEPTH_FAIL : 0x8802,
- STENCIL_BACK_PASS_DEPTH_PASS : 0x8803,
- STENCIL_BACK_REF : 0x8CA3,
- STENCIL_BACK_VALUE_MASK : 0x8CA4,
- STENCIL_BACK_WRITEMASK : 0x8CA5,
- VIEWPORT : 0x0BA2,
- SCISSOR_BOX : 0x0C10,
- /* SCISSOR_TEST */
- COLOR_CLEAR_VALUE : 0x0C22,
- COLOR_WRITEMASK : 0x0C23,
- UNPACK_ALIGNMENT : 0x0CF5,
- PACK_ALIGNMENT : 0x0D05,
- MAX_TEXTURE_SIZE : 0x0D33,
- MAX_VIEWPORT_DIMS : 0x0D3A,
- SUBPIXEL_BITS : 0x0D50,
- RED_BITS : 0x0D52,
- GREEN_BITS : 0x0D53,
- BLUE_BITS : 0x0D54,
- ALPHA_BITS : 0x0D55,
- DEPTH_BITS : 0x0D56,
- STENCIL_BITS : 0x0D57,
- POLYGON_OFFSET_UNITS : 0x2A00,
- /* POLYGON_OFFSET_FILL */
- POLYGON_OFFSET_FACTOR : 0x8038,
- TEXTURE_BINDING_2D : 0x8069,
- SAMPLE_BUFFERS : 0x80A8,
- SAMPLES : 0x80A9,
- SAMPLE_COVERAGE_VALUE : 0x80AA,
- SAMPLE_COVERAGE_INVERT : 0x80AB,
-
- /* GetTextureParameter */
- /* TEXTURE_MAG_FILTER */
- /* TEXTURE_MIN_FILTER */
- /* TEXTURE_WRAP_S */
- /* TEXTURE_WRAP_T */
-
- COMPRESSED_TEXTURE_FORMATS : 0x86A3,
-
- /* HintMode */
- DONT_CARE : 0x1100,
- FASTEST : 0x1101,
- NICEST : 0x1102,
-
- /* HintTarget */
- GENERATE_MIPMAP_HINT : 0x8192,
-
- /* DataType */
- BYTE : 0x1400,
- UNSIGNED_BYTE : 0x1401,
- SHORT : 0x1402,
- UNSIGNED_SHORT : 0x1403,
- INT : 0x1404,
- UNSIGNED_INT : 0x1405,
- FLOAT : 0x1406,
-
- /* PixelFormat */
- DEPTH_COMPONENT : 0x1902,
- ALPHA : 0x1906,
- RGB : 0x1907,
- RGBA : 0x1908,
- LUMINANCE : 0x1909,
- LUMINANCE_ALPHA : 0x190A,
-
- /* PixelType */
- /* UNSIGNED_BYTE */
- UNSIGNED_SHORT_4_4_4_4 : 0x8033,
- UNSIGNED_SHORT_5_5_5_1 : 0x8034,
- UNSIGNED_SHORT_5_6_5 : 0x8363,
-
- /* Shaders */
- FRAGMENT_SHADER : 0x8B30,
- VERTEX_SHADER : 0x8B31,
- MAX_VERTEX_ATTRIBS : 0x8869,
- MAX_VERTEX_UNIFORM_VECTORS : 0x8DFB,
- MAX_VARYING_VECTORS : 0x8DFC,
- MAX_COMBINED_TEXTURE_IMAGE_UNITS : 0x8B4D,
- MAX_VERTEX_TEXTURE_IMAGE_UNITS : 0x8B4C,
- MAX_TEXTURE_IMAGE_UNITS : 0x8872,
- MAX_FRAGMENT_UNIFORM_VECTORS : 0x8DFD,
- SHADER_TYPE : 0x8B4F,
- DELETE_STATUS : 0x8B80,
- LINK_STATUS : 0x8B82,
- VALIDATE_STATUS : 0x8B83,
- ATTACHED_SHADERS : 0x8B85,
- ACTIVE_UNIFORMS : 0x8B86,
- ACTIVE_ATTRIBUTES : 0x8B89,
- SHADING_LANGUAGE_VERSION : 0x8B8C,
- CURRENT_PROGRAM : 0x8B8D,
-
- /* StencilFunction */
- NEVER : 0x0200,
- LESS : 0x0201,
- EQUAL : 0x0202,
- LEQUAL : 0x0203,
- GREATER : 0x0204,
- NOTEQUAL : 0x0205,
- GEQUAL : 0x0206,
- ALWAYS : 0x0207,
-
- /* StencilOp */
- /* ZERO */
- KEEP : 0x1E00,
- REPLACE : 0x1E01,
- INCR : 0x1E02,
- DECR : 0x1E03,
- INVERT : 0x150A,
- INCR_WRAP : 0x8507,
- DECR_WRAP : 0x8508,
-
- /* StringName */
- VENDOR : 0x1F00,
- RENDERER : 0x1F01,
- VERSION : 0x1F02,
-
- /* TextureMagFilter */
- NEAREST : 0x2600,
- LINEAR : 0x2601,
-
- /* TextureMinFilter */
- /* NEAREST */
- /* LINEAR */
- NEAREST_MIPMAP_NEAREST : 0x2700,
- LINEAR_MIPMAP_NEAREST : 0x2701,
- NEAREST_MIPMAP_LINEAR : 0x2702,
- LINEAR_MIPMAP_LINEAR : 0x2703,
-
- /* TextureParameterName */
- TEXTURE_MAG_FILTER : 0x2800,
- TEXTURE_MIN_FILTER : 0x2801,
- TEXTURE_WRAP_S : 0x2802,
- TEXTURE_WRAP_T : 0x2803,
-
- /* TextureTarget */
- TEXTURE_2D : 0x0DE1,
- TEXTURE : 0x1702,
-
- TEXTURE_CUBE_MAP : 0x8513,
- TEXTURE_BINDING_CUBE_MAP : 0x8514,
- TEXTURE_CUBE_MAP_POSITIVE_X : 0x8515,
- TEXTURE_CUBE_MAP_NEGATIVE_X : 0x8516,
- TEXTURE_CUBE_MAP_POSITIVE_Y : 0x8517,
- TEXTURE_CUBE_MAP_NEGATIVE_Y : 0x8518,
- TEXTURE_CUBE_MAP_POSITIVE_Z : 0x8519,
- TEXTURE_CUBE_MAP_NEGATIVE_Z : 0x851A,
- MAX_CUBE_MAP_TEXTURE_SIZE : 0x851C,
-
- /* TextureUnit */
- TEXTURE0 : 0x84C0,
- TEXTURE1 : 0x84C1,
- TEXTURE2 : 0x84C2,
- TEXTURE3 : 0x84C3,
- TEXTURE4 : 0x84C4,
- TEXTURE5 : 0x84C5,
- TEXTURE6 : 0x84C6,
- TEXTURE7 : 0x84C7,
- TEXTURE8 : 0x84C8,
- TEXTURE9 : 0x84C9,
- TEXTURE10 : 0x84CA,
- TEXTURE11 : 0x84CB,
- TEXTURE12 : 0x84CC,
- TEXTURE13 : 0x84CD,
- TEXTURE14 : 0x84CE,
- TEXTURE15 : 0x84CF,
- TEXTURE16 : 0x84D0,
- TEXTURE17 : 0x84D1,
- TEXTURE18 : 0x84D2,
- TEXTURE19 : 0x84D3,
- TEXTURE20 : 0x84D4,
- TEXTURE21 : 0x84D5,
- TEXTURE22 : 0x84D6,
- TEXTURE23 : 0x84D7,
- TEXTURE24 : 0x84D8,
- TEXTURE25 : 0x84D9,
- TEXTURE26 : 0x84DA,
- TEXTURE27 : 0x84DB,
- TEXTURE28 : 0x84DC,
- TEXTURE29 : 0x84DD,
- TEXTURE30 : 0x84DE,
- TEXTURE31 : 0x84DF,
- ACTIVE_TEXTURE : 0x84E0,
-
- /* TextureWrapMode */
- REPEAT : 0x2901,
- CLAMP_TO_EDGE : 0x812F,
- MIRRORED_REPEAT : 0x8370,
-
- /* Uniform Types */
- FLOAT_VEC2 : 0x8B50,
- FLOAT_VEC3 : 0x8B51,
- FLOAT_VEC4 : 0x8B52,
- INT_VEC2 : 0x8B53,
- INT_VEC3 : 0x8B54,
- INT_VEC4 : 0x8B55,
- BOOL : 0x8B56,
- BOOL_VEC2 : 0x8B57,
- BOOL_VEC3 : 0x8B58,
- BOOL_VEC4 : 0x8B59,
- FLOAT_MAT2 : 0x8B5A,
- FLOAT_MAT3 : 0x8B5B,
- FLOAT_MAT4 : 0x8B5C,
- SAMPLER_2D : 0x8B5E,
- SAMPLER_CUBE : 0x8B60,
-
- /* Vertex Arrays */
- VERTEX_ATTRIB_ARRAY_ENABLED : 0x8622,
- VERTEX_ATTRIB_ARRAY_SIZE : 0x8623,
- VERTEX_ATTRIB_ARRAY_STRIDE : 0x8624,
- VERTEX_ATTRIB_ARRAY_TYPE : 0x8625,
- VERTEX_ATTRIB_ARRAY_NORMALIZED : 0x886A,
- VERTEX_ATTRIB_ARRAY_POINTER : 0x8645,
- VERTEX_ATTRIB_ARRAY_BUFFER_BINDING : 0x889F,
-
- /* Shader Source */
- COMPILE_STATUS : 0x8B81,
-
- /* Shader Precision-Specified Types */
- LOW_FLOAT : 0x8DF0,
- MEDIUM_FLOAT : 0x8DF1,
- HIGH_FLOAT : 0x8DF2,
- LOW_INT : 0x8DF3,
- MEDIUM_INT : 0x8DF4,
- HIGH_INT : 0x8DF5,
-
- /* Framebuffer Object. */
- FRAMEBUFFER : 0x8D40,
- RENDERBUFFER : 0x8D41,
-
- RGBA4 : 0x8056,
- RGB5_A1 : 0x8057,
- RGB565 : 0x8D62,
- DEPTH_COMPONENT16 : 0x81A5,
- STENCIL_INDEX : 0x1901,
- STENCIL_INDEX8 : 0x8D48,
- DEPTH_STENCIL : 0x84F9,
-
- RENDERBUFFER_WIDTH : 0x8D42,
- RENDERBUFFER_HEIGHT : 0x8D43,
- RENDERBUFFER_INTERNAL_FORMAT : 0x8D44,
- RENDERBUFFER_RED_SIZE : 0x8D50,
- RENDERBUFFER_GREEN_SIZE : 0x8D51,
- RENDERBUFFER_BLUE_SIZE : 0x8D52,
- RENDERBUFFER_ALPHA_SIZE : 0x8D53,
- RENDERBUFFER_DEPTH_SIZE : 0x8D54,
- RENDERBUFFER_STENCIL_SIZE : 0x8D55,
-
- FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE : 0x8CD0,
- FRAMEBUFFER_ATTACHMENT_OBJECT_NAME : 0x8CD1,
- FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL : 0x8CD2,
- FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE : 0x8CD3,
-
- COLOR_ATTACHMENT0 : 0x8CE0,
- DEPTH_ATTACHMENT : 0x8D00,
- STENCIL_ATTACHMENT : 0x8D20,
- DEPTH_STENCIL_ATTACHMENT : 0x821A,
-
- NONE : 0,
-
- FRAMEBUFFER_COMPLETE : 0x8CD5,
- FRAMEBUFFER_INCOMPLETE_ATTACHMENT : 0x8CD6,
- FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT : 0x8CD7,
- FRAMEBUFFER_INCOMPLETE_DIMENSIONS : 0x8CD9,
- FRAMEBUFFER_UNSUPPORTED : 0x8CDD,
-
- FRAMEBUFFER_BINDING : 0x8CA6,
- RENDERBUFFER_BINDING : 0x8CA7,
- MAX_RENDERBUFFER_SIZE : 0x84E8,
-
- INVALID_FRAMEBUFFER_OPERATION : 0x0506,
-
- /* WebGL-specific enums */
- UNPACK_FLIP_Y_WEBGL : 0x9240,
- UNPACK_PREMULTIPLY_ALPHA_WEBGL : 0x9241,
- CONTEXT_LOST_WEBGL : 0x9242,
- UNPACK_COLORSPACE_CONVERSION_WEBGL : 0x9243,
- BROWSER_DEFAULT_WEBGL : 0x9244,
-
- items: {},
- id: 0,
- getExtension: function() { return 1 },
- createBuffer: function() {
- var id = this.id++;
- this.items[id] = {
- which: 'buffer',
- };
- return id;
- },
- deleteBuffer: function(){},
- bindBuffer: function(){},
- bufferData: function(){},
- getParameter: function(pname) {
- switch(pname) {
- case /* GL_VENDOR */ 0x1F00: return 'FakeShellGLVendor';
- case /* GL_RENDERER */ 0x1F01: return 'FakeShellGLRenderer';
- case /* GL_VERSION */ 0x1F02: return '0.0.1';
- case /* GL_MAX_TEXTURE_SIZE */ 0x0D33: return 16384;
- case /* GL_MAX_CUBE_MAP_TEXTURE_SIZE */ 0x851C: return 16384;
- case /* GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT */ 0x84FF: return 16;
- case /* GL_MAX_TEXTURE_IMAGE_UNITS_NV */ 0x8872: return 16;
- case /* GL_MAX_VERTEX_UNIFORM_VECTORS */ 0x8DFB: return 4096;
- case /* GL_MAX_FRAGMENT_UNIFORM_VECTORS */ 0x8DFD: return 4096;
- case /* GL_MAX_VARYING_VECTORS */ 0x8DFC: return 32;
- case /* GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS */ 0x8B4D: return 32;
- default: console.log('getParameter ' + pname + '?'); return 0;
- }
- },
- getSupportedExtensions: function() {
- return ["OES_texture_float", "OES_standard_derivatives", "EXT_texture_filter_anisotropic", "MOZ_EXT_texture_filter_anisotropic", "MOZ_WEBGL_lose_context", "MOZ_WEBGL_compressed_texture_s3tc", "MOZ_WEBGL_depth_texture"];
- },
- createShader: function(type) {
- var id = this.id++;
- this.items[id] = {
- which: 'shader',
- type: type,
- };
- return id;
- },
- getShaderParameter: function(shader, pname) {
- switch(pname) {
- case /* GL_SHADER_TYPE */ 0x8B4F: return this.items[shader].type;
- case /* GL_COMPILE_STATUS */ 0x8B81: return true;
- default: throw 'getShaderParameter ' + pname;
- }
- },
- shaderSource: function(){},
- compileShader: function(){},
- createProgram: function() {
- var id = this.id++;
- this.items[id] = {
- which: 'program',
- shaders: [],
- };
- return id;
- },
- attachShader: function(program, shader) {
- this.items[program].shaders.push(shader);
- },
- bindAttribLocation: function(){},
- linkProgram: function(){},
- getProgramParameter: function(program, pname) {
- switch(pname) {
- case /* LINK_STATUS */ 0x8B82: return true;
- case /* ACTIVE_UNIFORMS */ 0x8B86: return 4;
- default: throw 'getProgramParameter ' + pname;
- }
- },
- deleteShader: function(){},
- deleteProgram: function(){},
- viewport: function(){},
- clearColor: function(){},
- clearDepth: function(){},
- depthFunc: function(){},
- enable: function(){},
- disable: function(){},
- frontFace: function(){},
- cullFace: function(){},
- activeTexture: function(){},
- createTexture: function() {
- var id = this.id++;
- this.items[id] = {
- which: 'texture',
- };
- return id;
- },
- deleteTexture: function(){},
- boundTextures: {},
- bindTexture: function(target, texture) {
- this.boundTextures[target] = texture;
- },
- texParameteri: function(){},
- pixelStorei: function(){},
- texImage2D: function(){},
- compressedTexImage2D: function(){},
- useProgram: function(){},
- getUniformLocation: function() {
- return null;
- },
- getActiveUniform: function(program, index) {
- return {
- size: 1,
- type: /* INT_VEC3 */ 0x8B54,
- name: 'activeUniform' + index,
- };
- },
- clear: function(){},
- uniform4fv: function(){},
- uniform1i: function(){},
- getAttribLocation: function() { return 1 },
- vertexAttribPointer: function(){},
- enableVertexAttribArray: function(){},
- disableVertexAttribArray: function(){},
- drawElements: function(){},
- drawArrays: function(){},
- depthMask: function(){},
- depthRange: function(){},
- bufferSubData: function(){},
- blendFunc: function(){},
- createFramebuffer: function() {
- var id = this.id++;
- this.items[id] = {
- which: 'framebuffer',
- shaders: [],
- };
- return id;
- },
- bindFramebuffer: function(){},
- framebufferTexture2D: function(){},
- checkFramebufferStatus: function() {
- return /* FRAMEBUFFER_COMPLETE */ 0x8CD5;
- },
- createRenderbuffer: function() {
- var id = this.id++;
- this.items[id] = {
- which: 'renderbuffer',
- shaders: [],
- };
- return id;
- },
- bindRenderbuffer: function(){},
- renderbufferStorage: function(){},
- framebufferRenderbuffer: function(){},
- scissor: function(){},
- colorMask: function(){},
- lineWidth: function(){},
- };
- }
- case '2d': {
- return {
- drawImage: function(){},
- getImageData: function(x, y, w, h) {
- return {
- width: w,
- height: h,
- data: new Uint8ClampedArray(w*h),
- };
- },
- save: function(){},
- restore: function(){},
- fillRect: function(){},
- measureText: function() { return 10 },
- fillText: function(){},
- };
- }
- default: throw 'canvas.getContext: ' + which;
- }
- },
- requestPointerLock: function() {
- document.pointerLockElement = document.getElementById('canvas');
- window.setTimeout(function() {
- document.callEventListeners('pointerlockchange');
- });
- },
- exitPointerLock: function(){},
- style: {},
- eventListeners: {},
- addEventListener: document.addEventListener,
- callEventListeners: document.callEventListeners,
- requestFullScreen: function() {
- document.fullscreenElement = document.getElementById('canvas');
- window.setTimeout(function() {
- document.callEventListeners('fullscreenchange');
- });
- },
- offsetTop: 0,
- offsetLeft: 0,
- };
+ return this.canvas = headlessCanvas();
}
case 'status-text': case 'progress': {
return {};
@@ -727,9 +120,9 @@ var document = {
case 'script': {
var ret = {};
window.setTimeout(function() {
- print('loading script: ' + ret.src);
+ headlessPrint('loading script: ' + ret.src);
load(ret.src);
- print(' script loaded.');
+ headlessPrint(' script loaded.');
if (ret.onload) {
window.setTimeout(function() {
ret.onload(); // yeah yeah this might vanish
@@ -769,16 +162,14 @@ var document = {
var alert = function(x) {
print(x);
};
-var originalDateNow = Date.now;
var performance = {
now: function() {
- return originalDateNow.call(Date);
+ return Date.now();
},
};
function fixPath(path) {
if (path[0] == '/') path = path.substring(1);
- var dirsToDrop = %d; // go back to root dir if first_js is in a subdir
- for (var i = 0; i < dirsToDrop; i++) {
+ for (var i = 0; i < window.dirsToDrop; i++) {
path = '../' + path;
}
return path
@@ -833,11 +224,11 @@ var Worker = function(workerPath) {
workerPath = fixPath(workerPath);
var workerCode = read(workerPath);
workerCode = workerCode.replace(/Module/g, 'zzModuleyy' + (Worker.id++)). // prevent collision with the global Module object. Note that this becomes global, so we need unique ids
- replace(/Date.now/g, 'Recorder.dnow'). // recorded values are just for the "main thread" - workers were not recorded, and should not consume
- replace(/performance.now/g, 'Recorder.pnow').
- replace(/Math.random/g, 'Recorder.random').
+ //replace(/Date.now/g, 'Recorder.dnow'). // recorded values are just for the "main thread" - workers were not recorded, and should not consume
+ //replace(/performance.now/g, 'Recorder.pnow').
+ //replace(/Math.random/g, 'Recorder.random').
replace(/\nonmessage = /, '\nvar onmessage = '); // workers commonly do "onmessage = ", we need to varify that to sandbox
- print('loading worker ' + workerPath + ' : ' + workerCode.substring(0, 50));
+ headlessPrint('loading worker ' + workerPath + ' : ' + workerCode.substring(0, 50));
eval(workerCode); // will implement onmessage()
function duplicateJSON(json) {
@@ -852,18 +243,18 @@ var Worker = function(workerPath) {
this.terminate = function(){};
this.postMessage = function(msg) {
msg.messageId = Worker.messageId++;
- print('main thread sending message ' + msg.messageId + ' to worker ' + workerPath);
+ headlessPrint('main thread sending message ' + msg.messageId + ' to worker ' + workerPath);
window.setTimeout(function() {
- print('worker ' + workerPath + ' receiving message ' + msg.messageId);
+ headlessPrint('worker ' + workerPath + ' receiving message ' + msg.messageId);
onmessage({ data: duplicateJSON(msg) });
});
};
var thisWorker = this;
var postMessage = function(msg) {
msg.messageId = Worker.messageId++;
- print('worker ' + workerPath + ' sending message ' + msg.messageId);
+ headlessPrint('worker ' + workerPath + ' sending message ' + msg.messageId);
window.setTimeout(function() {
- print('main thread receiving message ' + msg.messageId + ' from ' + workerPath);
+ headlessPrint('main thread receiving message ' + msg.messageId + ' from ' + workerPath);
thisWorker.onmessage({ data: duplicateJSON(msg) });
});
};
diff --git a/src/headlessCanvas.js b/src/headlessCanvas.js
new file mode 100644
index 00000000..4951aed8
--- /dev/null
+++ b/src/headlessCanvas.js
@@ -0,0 +1,618 @@
+function headlessCanvas() {
+ return {
+ headless: true,
+ getContext: function(which) {
+ switch(which) {
+ case 'experimental-webgl': {
+ return {
+ /* ClearBufferMask */
+ DEPTH_BUFFER_BIT : 0x00000100,
+ STENCIL_BUFFER_BIT : 0x00000400,
+ COLOR_BUFFER_BIT : 0x00004000,
+
+ /* BeginMode */
+ POINTS : 0x0000,
+ LINES : 0x0001,
+ LINE_LOOP : 0x0002,
+ LINE_STRIP : 0x0003,
+ TRIANGLES : 0x0004,
+ TRIANGLE_STRIP : 0x0005,
+ TRIANGLE_FAN : 0x0006,
+
+ /* AlphaFunction (not supported in ES20) */
+ /* NEVER */
+ /* LESS */
+ /* EQUAL */
+ /* LEQUAL */
+ /* GREATER */
+ /* NOTEQUAL */
+ /* GEQUAL */
+ /* ALWAYS */
+
+ /* BlendingFactorDest */
+ ZERO : 0,
+ ONE : 1,
+ SRC_COLOR : 0x0300,
+ ONE_MINUS_SRC_COLOR : 0x0301,
+ SRC_ALPHA : 0x0302,
+ ONE_MINUS_SRC_ALPHA : 0x0303,
+ DST_ALPHA : 0x0304,
+ ONE_MINUS_DST_ALPHA : 0x0305,
+
+ /* BlendingFactorSrc */
+ /* ZERO */
+ /* ONE */
+ DST_COLOR : 0x0306,
+ ONE_MINUS_DST_COLOR : 0x0307,
+ SRC_ALPHA_SATURATE : 0x0308,
+ /* SRC_ALPHA */
+ /* ONE_MINUS_SRC_ALPHA */
+ /* DST_ALPHA */
+ /* ONE_MINUS_DST_ALPHA */
+
+ /* BlendEquationSeparate */
+ FUNC_ADD : 0x8006,
+ BLEND_EQUATION : 0x8009,
+ BLEND_EQUATION_RGB : 0x8009, /* same as BLEND_EQUATION */
+ BLEND_EQUATION_ALPHA : 0x883D,
+
+ /* BlendSubtract */
+ FUNC_SUBTRACT : 0x800A,
+ FUNC_REVERSE_SUBTRACT : 0x800B,
+
+ /* Separate Blend Functions */
+ BLEND_DST_RGB : 0x80C8,
+ BLEND_SRC_RGB : 0x80C9,
+ BLEND_DST_ALPHA : 0x80CA,
+ BLEND_SRC_ALPHA : 0x80CB,
+ CONSTANT_COLOR : 0x8001,
+ ONE_MINUS_CONSTANT_COLOR : 0x8002,
+ CONSTANT_ALPHA : 0x8003,
+ ONE_MINUS_CONSTANT_ALPHA : 0x8004,
+ BLEND_COLOR : 0x8005,
+
+ /* Buffer Objects */
+ ARRAY_BUFFER : 0x8892,
+ ELEMENT_ARRAY_BUFFER : 0x8893,
+ ARRAY_BUFFER_BINDING : 0x8894,
+ ELEMENT_ARRAY_BUFFER_BINDING : 0x8895,
+
+ STREAM_DRAW : 0x88E0,
+ STATIC_DRAW : 0x88E4,
+ DYNAMIC_DRAW : 0x88E8,
+
+ BUFFER_SIZE : 0x8764,
+ BUFFER_USAGE : 0x8765,
+
+ CURRENT_VERTEX_ATTRIB : 0x8626,
+
+ /* CullFaceMode */
+ FRONT : 0x0404,
+ BACK : 0x0405,
+ FRONT_AND_BACK : 0x0408,
+
+ /* DepthFunction */
+ /* NEVER */
+ /* LESS */
+ /* EQUAL */
+ /* LEQUAL */
+ /* GREATER */
+ /* NOTEQUAL */
+ /* GEQUAL */
+ /* ALWAYS */
+
+ /* EnableCap */
+ /* TEXTURE_2D */
+ CULL_FACE : 0x0B44,
+ BLEND : 0x0BE2,
+ DITHER : 0x0BD0,
+ STENCIL_TEST : 0x0B90,
+ DEPTH_TEST : 0x0B71,
+ SCISSOR_TEST : 0x0C11,
+ POLYGON_OFFSET_FILL : 0x8037,
+ SAMPLE_ALPHA_TO_COVERAGE : 0x809E,
+ SAMPLE_COVERAGE : 0x80A0,
+
+ /* ErrorCode */
+ NO_ERROR : 0,
+ INVALID_ENUM : 0x0500,
+ INVALID_VALUE : 0x0501,
+ INVALID_OPERATION : 0x0502,
+ OUT_OF_MEMORY : 0x0505,
+
+ /* FrontFaceDirection */
+ CW : 0x0900,
+ CCW : 0x0901,
+
+ /* GetPName */
+ LINE_WIDTH : 0x0B21,
+ ALIASED_POINT_SIZE_RANGE : 0x846D,
+ ALIASED_LINE_WIDTH_RANGE : 0x846E,
+ CULL_FACE_MODE : 0x0B45,
+ FRONT_FACE : 0x0B46,
+ DEPTH_RANGE : 0x0B70,
+ DEPTH_WRITEMASK : 0x0B72,
+ DEPTH_CLEAR_VALUE : 0x0B73,
+ DEPTH_FUNC : 0x0B74,
+ STENCIL_CLEAR_VALUE : 0x0B91,
+ STENCIL_FUNC : 0x0B92,
+ STENCIL_FAIL : 0x0B94,
+ STENCIL_PASS_DEPTH_FAIL : 0x0B95,
+ STENCIL_PASS_DEPTH_PASS : 0x0B96,
+ STENCIL_REF : 0x0B97,
+ STENCIL_VALUE_MASK : 0x0B93,
+ STENCIL_WRITEMASK : 0x0B98,
+ STENCIL_BACK_FUNC : 0x8800,
+ STENCIL_BACK_FAIL : 0x8801,
+ STENCIL_BACK_PASS_DEPTH_FAIL : 0x8802,
+ STENCIL_BACK_PASS_DEPTH_PASS : 0x8803,
+ STENCIL_BACK_REF : 0x8CA3,
+ STENCIL_BACK_VALUE_MASK : 0x8CA4,
+ STENCIL_BACK_WRITEMASK : 0x8CA5,
+ VIEWPORT : 0x0BA2,
+ SCISSOR_BOX : 0x0C10,
+ /* SCISSOR_TEST */
+ COLOR_CLEAR_VALUE : 0x0C22,
+ COLOR_WRITEMASK : 0x0C23,
+ UNPACK_ALIGNMENT : 0x0CF5,
+ PACK_ALIGNMENT : 0x0D05,
+ MAX_TEXTURE_SIZE : 0x0D33,
+ MAX_VIEWPORT_DIMS : 0x0D3A,
+ SUBPIXEL_BITS : 0x0D50,
+ RED_BITS : 0x0D52,
+ GREEN_BITS : 0x0D53,
+ BLUE_BITS : 0x0D54,
+ ALPHA_BITS : 0x0D55,
+ DEPTH_BITS : 0x0D56,
+ STENCIL_BITS : 0x0D57,
+ POLYGON_OFFSET_UNITS : 0x2A00,
+ /* POLYGON_OFFSET_FILL */
+ POLYGON_OFFSET_FACTOR : 0x8038,
+ TEXTURE_BINDING_2D : 0x8069,
+ SAMPLE_BUFFERS : 0x80A8,
+ SAMPLES : 0x80A9,
+ SAMPLE_COVERAGE_VALUE : 0x80AA,
+ SAMPLE_COVERAGE_INVERT : 0x80AB,
+
+ /* GetTextureParameter */
+ /* TEXTURE_MAG_FILTER */
+ /* TEXTURE_MIN_FILTER */
+ /* TEXTURE_WRAP_S */
+ /* TEXTURE_WRAP_T */
+
+ COMPRESSED_TEXTURE_FORMATS : 0x86A3,
+
+ /* HintMode */
+ DONT_CARE : 0x1100,
+ FASTEST : 0x1101,
+ NICEST : 0x1102,
+
+ /* HintTarget */
+ GENERATE_MIPMAP_HINT : 0x8192,
+
+ /* DataType */
+ BYTE : 0x1400,
+ UNSIGNED_BYTE : 0x1401,
+ SHORT : 0x1402,
+ UNSIGNED_SHORT : 0x1403,
+ INT : 0x1404,
+ UNSIGNED_INT : 0x1405,
+ FLOAT : 0x1406,
+
+ /* PixelFormat */
+ DEPTH_COMPONENT : 0x1902,
+ ALPHA : 0x1906,
+ RGB : 0x1907,
+ RGBA : 0x1908,
+ LUMINANCE : 0x1909,
+ LUMINANCE_ALPHA : 0x190A,
+
+ /* PixelType */
+ /* UNSIGNED_BYTE */
+ UNSIGNED_SHORT_4_4_4_4 : 0x8033,
+ UNSIGNED_SHORT_5_5_5_1 : 0x8034,
+ UNSIGNED_SHORT_5_6_5 : 0x8363,
+
+ /* Shaders */
+ FRAGMENT_SHADER : 0x8B30,
+ VERTEX_SHADER : 0x8B31,
+ MAX_VERTEX_ATTRIBS : 0x8869,
+ MAX_VERTEX_UNIFORM_VECTORS : 0x8DFB,
+ MAX_VARYING_VECTORS : 0x8DFC,
+ MAX_COMBINED_TEXTURE_IMAGE_UNITS : 0x8B4D,
+ MAX_VERTEX_TEXTURE_IMAGE_UNITS : 0x8B4C,
+ MAX_TEXTURE_IMAGE_UNITS : 0x8872,
+ MAX_FRAGMENT_UNIFORM_VECTORS : 0x8DFD,
+ SHADER_TYPE : 0x8B4F,
+ DELETE_STATUS : 0x8B80,
+ LINK_STATUS : 0x8B82,
+ VALIDATE_STATUS : 0x8B83,
+ ATTACHED_SHADERS : 0x8B85,
+ ACTIVE_UNIFORMS : 0x8B86,
+ ACTIVE_ATTRIBUTES : 0x8B89,
+ SHADING_LANGUAGE_VERSION : 0x8B8C,
+ CURRENT_PROGRAM : 0x8B8D,
+
+ /* StencilFunction */
+ NEVER : 0x0200,
+ LESS : 0x0201,
+ EQUAL : 0x0202,
+ LEQUAL : 0x0203,
+ GREATER : 0x0204,
+ NOTEQUAL : 0x0205,
+ GEQUAL : 0x0206,
+ ALWAYS : 0x0207,
+
+ /* StencilOp */
+ /* ZERO */
+ KEEP : 0x1E00,
+ REPLACE : 0x1E01,
+ INCR : 0x1E02,
+ DECR : 0x1E03,
+ INVERT : 0x150A,
+ INCR_WRAP : 0x8507,
+ DECR_WRAP : 0x8508,
+
+ /* StringName */
+ VENDOR : 0x1F00,
+ RENDERER : 0x1F01,
+ VERSION : 0x1F02,
+
+ /* TextureMagFilter */
+ NEAREST : 0x2600,
+ LINEAR : 0x2601,
+
+ /* TextureMinFilter */
+ /* NEAREST */
+ /* LINEAR */
+ NEAREST_MIPMAP_NEAREST : 0x2700,
+ LINEAR_MIPMAP_NEAREST : 0x2701,
+ NEAREST_MIPMAP_LINEAR : 0x2702,
+ LINEAR_MIPMAP_LINEAR : 0x2703,
+
+ /* TextureParameterName */
+ TEXTURE_MAG_FILTER : 0x2800,
+ TEXTURE_MIN_FILTER : 0x2801,
+ TEXTURE_WRAP_S : 0x2802,
+ TEXTURE_WRAP_T : 0x2803,
+
+ /* TextureTarget */
+ TEXTURE_2D : 0x0DE1,
+ TEXTURE : 0x1702,
+
+ TEXTURE_CUBE_MAP : 0x8513,
+ TEXTURE_BINDING_CUBE_MAP : 0x8514,
+ TEXTURE_CUBE_MAP_POSITIVE_X : 0x8515,
+ TEXTURE_CUBE_MAP_NEGATIVE_X : 0x8516,
+ TEXTURE_CUBE_MAP_POSITIVE_Y : 0x8517,
+ TEXTURE_CUBE_MAP_NEGATIVE_Y : 0x8518,
+ TEXTURE_CUBE_MAP_POSITIVE_Z : 0x8519,
+ TEXTURE_CUBE_MAP_NEGATIVE_Z : 0x851A,
+ MAX_CUBE_MAP_TEXTURE_SIZE : 0x851C,
+
+ /* TextureUnit */
+ TEXTURE0 : 0x84C0,
+ TEXTURE1 : 0x84C1,
+ TEXTURE2 : 0x84C2,
+ TEXTURE3 : 0x84C3,
+ TEXTURE4 : 0x84C4,
+ TEXTURE5 : 0x84C5,
+ TEXTURE6 : 0x84C6,
+ TEXTURE7 : 0x84C7,
+ TEXTURE8 : 0x84C8,
+ TEXTURE9 : 0x84C9,
+ TEXTURE10 : 0x84CA,
+ TEXTURE11 : 0x84CB,
+ TEXTURE12 : 0x84CC,
+ TEXTURE13 : 0x84CD,
+ TEXTURE14 : 0x84CE,
+ TEXTURE15 : 0x84CF,
+ TEXTURE16 : 0x84D0,
+ TEXTURE17 : 0x84D1,
+ TEXTURE18 : 0x84D2,
+ TEXTURE19 : 0x84D3,
+ TEXTURE20 : 0x84D4,
+ TEXTURE21 : 0x84D5,
+ TEXTURE22 : 0x84D6,
+ TEXTURE23 : 0x84D7,
+ TEXTURE24 : 0x84D8,
+ TEXTURE25 : 0x84D9,
+ TEXTURE26 : 0x84DA,
+ TEXTURE27 : 0x84DB,
+ TEXTURE28 : 0x84DC,
+ TEXTURE29 : 0x84DD,
+ TEXTURE30 : 0x84DE,
+ TEXTURE31 : 0x84DF,
+ ACTIVE_TEXTURE : 0x84E0,
+
+ /* TextureWrapMode */
+ REPEAT : 0x2901,
+ CLAMP_TO_EDGE : 0x812F,
+ MIRRORED_REPEAT : 0x8370,
+
+ /* Uniform Types */
+ FLOAT_VEC2 : 0x8B50,
+ FLOAT_VEC3 : 0x8B51,
+ FLOAT_VEC4 : 0x8B52,
+ INT_VEC2 : 0x8B53,
+ INT_VEC3 : 0x8B54,
+ INT_VEC4 : 0x8B55,
+ BOOL : 0x8B56,
+ BOOL_VEC2 : 0x8B57,
+ BOOL_VEC3 : 0x8B58,
+ BOOL_VEC4 : 0x8B59,
+ FLOAT_MAT2 : 0x8B5A,
+ FLOAT_MAT3 : 0x8B5B,
+ FLOAT_MAT4 : 0x8B5C,
+ SAMPLER_2D : 0x8B5E,
+ SAMPLER_CUBE : 0x8B60,
+
+ /* Vertex Arrays */
+ VERTEX_ATTRIB_ARRAY_ENABLED : 0x8622,
+ VERTEX_ATTRIB_ARRAY_SIZE : 0x8623,
+ VERTEX_ATTRIB_ARRAY_STRIDE : 0x8624,
+ VERTEX_ATTRIB_ARRAY_TYPE : 0x8625,
+ VERTEX_ATTRIB_ARRAY_NORMALIZED : 0x886A,
+ VERTEX_ATTRIB_ARRAY_POINTER : 0x8645,
+ VERTEX_ATTRIB_ARRAY_BUFFER_BINDING : 0x889F,
+
+ /* Shader Source */
+ COMPILE_STATUS : 0x8B81,
+
+ /* Shader Precision-Specified Types */
+ LOW_FLOAT : 0x8DF0,
+ MEDIUM_FLOAT : 0x8DF1,
+ HIGH_FLOAT : 0x8DF2,
+ LOW_INT : 0x8DF3,
+ MEDIUM_INT : 0x8DF4,
+ HIGH_INT : 0x8DF5,
+
+ /* Framebuffer Object. */
+ FRAMEBUFFER : 0x8D40,
+ RENDERBUFFER : 0x8D41,
+
+ RGBA4 : 0x8056,
+ RGB5_A1 : 0x8057,
+ RGB565 : 0x8D62,
+ DEPTH_COMPONENT16 : 0x81A5,
+ STENCIL_INDEX : 0x1901,
+ STENCIL_INDEX8 : 0x8D48,
+ DEPTH_STENCIL : 0x84F9,
+
+ RENDERBUFFER_WIDTH : 0x8D42,
+ RENDERBUFFER_HEIGHT : 0x8D43,
+ RENDERBUFFER_INTERNAL_FORMAT : 0x8D44,
+ RENDERBUFFER_RED_SIZE : 0x8D50,
+ RENDERBUFFER_GREEN_SIZE : 0x8D51,
+ RENDERBUFFER_BLUE_SIZE : 0x8D52,
+ RENDERBUFFER_ALPHA_SIZE : 0x8D53,
+ RENDERBUFFER_DEPTH_SIZE : 0x8D54,
+ RENDERBUFFER_STENCIL_SIZE : 0x8D55,
+
+ FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE : 0x8CD0,
+ FRAMEBUFFER_ATTACHMENT_OBJECT_NAME : 0x8CD1,
+ FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL : 0x8CD2,
+ FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE : 0x8CD3,
+
+ COLOR_ATTACHMENT0 : 0x8CE0,
+ DEPTH_ATTACHMENT : 0x8D00,
+ STENCIL_ATTACHMENT : 0x8D20,
+ DEPTH_STENCIL_ATTACHMENT : 0x821A,
+
+ NONE : 0,
+
+ FRAMEBUFFER_COMPLETE : 0x8CD5,
+ FRAMEBUFFER_INCOMPLETE_ATTACHMENT : 0x8CD6,
+ FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT : 0x8CD7,
+ FRAMEBUFFER_INCOMPLETE_DIMENSIONS : 0x8CD9,
+ FRAMEBUFFER_UNSUPPORTED : 0x8CDD,
+
+ FRAMEBUFFER_BINDING : 0x8CA6,
+ RENDERBUFFER_BINDING : 0x8CA7,
+ MAX_RENDERBUFFER_SIZE : 0x84E8,
+
+ INVALID_FRAMEBUFFER_OPERATION : 0x0506,
+
+ /* WebGL-specific enums */
+ UNPACK_FLIP_Y_WEBGL : 0x9240,
+ UNPACK_PREMULTIPLY_ALPHA_WEBGL : 0x9241,
+ CONTEXT_LOST_WEBGL : 0x9242,
+ UNPACK_COLORSPACE_CONVERSION_WEBGL : 0x9243,
+ BROWSER_DEFAULT_WEBGL : 0x9244,
+
+ items: {},
+ id: 0,
+ getExtension: function() { return 1 },
+ createBuffer: function() {
+ var id = this.id++;
+ this.items[id] = {
+ which: 'buffer',
+ };
+ return id;
+ },
+ deleteBuffer: function(){},
+ bindBuffer: function(){},
+ bufferData: function(){},
+ getParameter: function(pname) {
+ switch(pname) {
+ case /* GL_VENDOR */ 0x1F00: return 'FakeShellGLVendor';
+ case /* GL_RENDERER */ 0x1F01: return 'FakeShellGLRenderer';
+ case /* GL_VERSION */ 0x1F02: return '0.0.1';
+ case /* GL_MAX_TEXTURE_SIZE */ 0x0D33: return 16384;
+ case /* GL_MAX_CUBE_MAP_TEXTURE_SIZE */ 0x851C: return 16384;
+ case /* GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT */ 0x84FF: return 16;
+ case /* GL_MAX_TEXTURE_IMAGE_UNITS_NV */ 0x8872: return 16;
+ case /* GL_MAX_VERTEX_UNIFORM_VECTORS */ 0x8DFB: return 4096;
+ case /* GL_MAX_FRAGMENT_UNIFORM_VECTORS */ 0x8DFD: return 4096;
+ case /* GL_MAX_VARYING_VECTORS */ 0x8DFC: return 32;
+ case /* GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS */ 0x8B4D: return 32;
+ default: console.log('getParameter ' + pname + '?'); return 0;
+ }
+ },
+ getSupportedExtensions: function() {
+ return ["OES_texture_float", "OES_standard_derivatives", "EXT_texture_filter_anisotropic", "MOZ_EXT_texture_filter_anisotropic", "MOZ_WEBGL_lose_context", "MOZ_WEBGL_compressed_texture_s3tc", "MOZ_WEBGL_depth_texture"];
+ },
+ createShader: function(type) {
+ var id = this.id++;
+ this.items[id] = {
+ which: 'shader',
+ type: type,
+ };
+ return id;
+ },
+ getShaderParameter: function(shader, pname) {
+ switch(pname) {
+ case /* GL_SHADER_TYPE */ 0x8B4F: return this.items[shader].type;
+ case /* GL_COMPILE_STATUS */ 0x8B81: return true;
+ default: throw 'getShaderParameter ' + pname;
+ }
+ },
+ shaderSource: function(){},
+ compileShader: function(){},
+ createProgram: function() {
+ var id = this.id++;
+ this.items[id] = {
+ which: 'program',
+ shaders: [],
+ };
+ return id;
+ },
+ attachShader: function(program, shader) {
+ this.items[program].shaders.push(shader);
+ },
+ bindAttribLocation: function(){},
+ linkProgram: function(){},
+ getProgramParameter: function(program, pname) {
+ switch(pname) {
+ case /* LINK_STATUS */ 0x8B82: return true;
+ case /* ACTIVE_UNIFORMS */ 0x8B86: return 4;
+ default: throw 'getProgramParameter ' + pname;
+ }
+ },
+ deleteShader: function(){},
+ deleteProgram: function(){},
+ viewport: function(){},
+ clearColor: function(){},
+ clearDepth: function(){},
+ depthFunc: function(){},
+ enable: function(){},
+ disable: function(){},
+ frontFace: function(){},
+ cullFace: function(){},
+ activeTexture: function(){},
+ createTexture: function() {
+ var id = this.id++;
+ this.items[id] = {
+ which: 'texture',
+ };
+ return id;
+ },
+ deleteTexture: function(){},
+ boundTextures: {},
+ bindTexture: function(target, texture) {
+ this.boundTextures[target] = texture;
+ },
+ texParameteri: function(){},
+ pixelStorei: function(){},
+ texImage2D: function(){},
+ compressedTexImage2D: function(){},
+ useProgram: function(){},
+ getUniformLocation: function() {
+ return null;
+ },
+ getActiveUniform: function(program, index) {
+ return {
+ size: 1,
+ type: /* INT_VEC3 */ 0x8B54,
+ name: 'activeUniform' + index,
+ };
+ },
+ clear: function(){},
+ uniform4fv: function(){},
+ uniform1i: function(){},
+ getAttribLocation: function() { return 1 },
+ vertexAttribPointer: function(){},
+ enableVertexAttribArray: function(){},
+ disableVertexAttribArray: function(){},
+ drawElements: function(){},
+ drawArrays: function(){},
+ depthMask: function(){},
+ depthRange: function(){},
+ bufferSubData: function(){},
+ blendFunc: function(){},
+ createFramebuffer: function() {
+ var id = this.id++;
+ this.items[id] = {
+ which: 'framebuffer',
+ shaders: [],
+ };
+ return id;
+ },
+ bindFramebuffer: function(){},
+ framebufferTexture2D: function(){},
+ checkFramebufferStatus: function() {
+ return /* FRAMEBUFFER_COMPLETE */ 0x8CD5;
+ },
+ createRenderbuffer: function() {
+ var id = this.id++;
+ this.items[id] = {
+ which: 'renderbuffer',
+ shaders: [],
+ };
+ return id;
+ },
+ bindRenderbuffer: function(){},
+ renderbufferStorage: function(){},
+ framebufferRenderbuffer: function(){},
+ scissor: function(){},
+ colorMask: function(){},
+ lineWidth: function(){},
+ vertexAttrib4fv: function(){},
+ };
+ }
+ case '2d': {
+ return {
+ drawImage: function(){},
+ getImageData: function(x, y, w, h) {
+ return {
+ width: w,
+ height: h,
+ data: new Uint8ClampedArray(w*h),
+ };
+ },
+ save: function(){},
+ restore: function(){},
+ fillRect: function(){},
+ measureText: function() { return 10 },
+ fillText: function(){},
+ };
+ }
+ default: throw 'canvas.getContext: ' + which;
+ }
+ },
+ requestPointerLock: function() {
+ document.pointerLockElement = document.getElementById('canvas');
+ window.setTimeout(function() {
+ document.callEventListeners('pointerlockchange');
+ });
+ },
+ exitPointerLock: function(){},
+ style: {},
+ eventListeners: {},
+ addEventListener: function(){},
+ requestFullScreen: function() {
+ document.fullscreenElement = document.getElementById('canvas');
+ window.setTimeout(function() {
+ document.callEventListeners('fullscreenchange');
+ });
+ },
+ offsetTop: 0,
+ offsetLeft: 0,
+ // generics
+ classList: {
+ add: function(){},
+ remove: function(){},
+ },
+ };
+}
+
diff --git a/src/jsifier.js b/src/jsifier.js
index 8ed19194..179a910a 100644
--- a/src/jsifier.js
+++ b/src/jsifier.js
@@ -280,7 +280,7 @@ function JSify(data, functionsOnly, givenFunctions) {
// they would shadow similarly-named globals in the parent.
item.JS = '';
} else {
- item.JS = makeGlobalDef(item.ident);
+ item.JS = makeGlobalDef(item.ident);
}
if (!NAMED_GLOBALS && isIndexableGlobal(item.ident)) {
@@ -795,7 +795,13 @@ function JSify(data, functionsOnly, givenFunctions) {
var label = block.labels[i];
var content = getLabelLines(label, '', true);
//printErr(func.ident + ' : ' + label.ident + ' : ' + content + '\n');
- blockMap[label.ident] = Relooper.addBlock(content);
+ var last = label.lines[label.lines.length-1];
+ if (!last.signedIdent) {
+ blockMap[label.ident] = Relooper.addBlock(content);
+ } else {
+ assert(last.intertype == 'switch');
+ blockMap[label.ident] = Relooper.addBlock(content, last.signedIdent);
+ }
}
// add branchings
function relevant(x) { return x && x.length > 2 ? x : 0 } // ignores ';' which valueJS and label*JS can be if empty
@@ -1125,7 +1131,19 @@ function JSify(data, functionsOnly, givenFunctions) {
}
});
makeFuncLineActor('switch', function(item) {
- var useIfs = RELOOP || item.switchLabels.length < 1024; // with a huge number of cases, if-else which looks nested to js parsers can cause problems
+ // use a switch if the range is not too big or sparse
+ var minn = Infinity, maxx = -Infinity;
+ item.switchLabels.forEach(function(switchLabel) {
+ var curr = Math.abs(parseInt(switchLabel.value));
+ minn = Math.min(minn, curr);
+ maxx = Math.max(maxx, curr);
+ });
+ var range = maxx - minn;
+ var useIfs = (item.switchLabels.length+1) < 6 || range > 10*1024 || (range/item.switchLabels.length) > 1024; // heuristics
+ if (VERBOSE && useIfs && item.switchLabels.length > 2) {
+ warn('not optimizing llvm switch into js switch because ' + [range, range/item.switchLabels.length]);
+ }
+
var phiSets = calcPhiSets(item);
// Consolidate checks that go to the same label. This is important because it makes the relooper simpler and faster.
var targetLabels = {}; // for each target label, the list of values going to it
@@ -1139,7 +1157,8 @@ function JSify(data, functionsOnly, givenFunctions) {
});
var ret = '';
var first = true;
- var signedIdent = makeSignOp(item.ident, item.type, 're'); // we need to standardize for purpose of comparison
+ signedIdent = makeSignOp(item.ident, item.type, 're'); // we need to standardize for purpose of comparison
+ if (!useIfs) item.signedIdent = signedIdent;
if (RELOOP) {
item.groupedLabels = [];
}
@@ -1635,7 +1654,7 @@ function JSify(data, functionsOnly, givenFunctions) {
//
if (!mainPass) {
- if (phase == 'pre' && !Variables.generatedGlobalBase) {
+ if (phase == 'pre' && !Variables.generatedGlobalBase && !BUILD_AS_SHARED_LIB) {
Variables.generatedGlobalBase = true;
// Globals are done, here is the rest of static memory
assert((TARGET_LE32 && Runtime.GLOBAL_BASE == 8) || (TARGET_X86 && Runtime.GLOBAL_BASE == 4)); // this is assumed in e.g. relocations for linkable modules
@@ -1679,24 +1698,26 @@ function JSify(data, functionsOnly, givenFunctions) {
print('}\n');
if (USE_TYPED_ARRAYS == 2) {
- print('var tempDoublePtr = Runtime.alignMemory(allocate(12, "i8", ALLOC_STATIC), 8);\n');
- print('assert(tempDoublePtr % 8 == 0);\n');
- print('function copyTempFloat(ptr) { // functions, because inlining this code increases code size too much\n');
- print(' HEAP8[tempDoublePtr] = HEAP8[ptr];\n');
- print(' HEAP8[tempDoublePtr+1] = HEAP8[ptr+1];\n');
- print(' HEAP8[tempDoublePtr+2] = HEAP8[ptr+2];\n');
- print(' HEAP8[tempDoublePtr+3] = HEAP8[ptr+3];\n');
- print('}\n');
- print('function copyTempDouble(ptr) {\n');
- print(' HEAP8[tempDoublePtr] = HEAP8[ptr];\n');
- print(' HEAP8[tempDoublePtr+1] = HEAP8[ptr+1];\n');
- print(' HEAP8[tempDoublePtr+2] = HEAP8[ptr+2];\n');
- print(' HEAP8[tempDoublePtr+3] = HEAP8[ptr+3];\n');
- print(' HEAP8[tempDoublePtr+4] = HEAP8[ptr+4];\n');
- print(' HEAP8[tempDoublePtr+5] = HEAP8[ptr+5];\n');
- print(' HEAP8[tempDoublePtr+6] = HEAP8[ptr+6];\n');
- print(' HEAP8[tempDoublePtr+7] = HEAP8[ptr+7];\n');
- print('}\n');
+ if (!BUILD_AS_SHARED_LIB) {
+ print('var tempDoublePtr = Runtime.alignMemory(allocate(12, "i8", ALLOC_STATIC), 8);\n');
+ print('assert(tempDoublePtr % 8 == 0);\n');
+ print('function copyTempFloat(ptr) { // functions, because inlining this code increases code size too much\n');
+ print(' HEAP8[tempDoublePtr] = HEAP8[ptr];\n');
+ print(' HEAP8[tempDoublePtr+1] = HEAP8[ptr+1];\n');
+ print(' HEAP8[tempDoublePtr+2] = HEAP8[ptr+2];\n');
+ print(' HEAP8[tempDoublePtr+3] = HEAP8[ptr+3];\n');
+ print('}\n');
+ print('function copyTempDouble(ptr) {\n');
+ print(' HEAP8[tempDoublePtr] = HEAP8[ptr];\n');
+ print(' HEAP8[tempDoublePtr+1] = HEAP8[ptr+1];\n');
+ print(' HEAP8[tempDoublePtr+2] = HEAP8[ptr+2];\n');
+ print(' HEAP8[tempDoublePtr+3] = HEAP8[ptr+3];\n');
+ print(' HEAP8[tempDoublePtr+4] = HEAP8[ptr+4];\n');
+ print(' HEAP8[tempDoublePtr+5] = HEAP8[ptr+5];\n');
+ print(' HEAP8[tempDoublePtr+6] = HEAP8[ptr+6];\n');
+ print(' HEAP8[tempDoublePtr+7] = HEAP8[ptr+7];\n');
+ print('}\n');
+ }
}
}
@@ -1731,11 +1752,13 @@ function JSify(data, functionsOnly, givenFunctions) {
legalizedI64s = legalizedI64sDefault;
- print('STACK_BASE = STACKTOP = Runtime.alignMemory(STATICTOP);\n');
- print('staticSealed = true; // seal the static portion of memory\n');
- print('STACK_MAX = STACK_BASE + ' + TOTAL_STACK + ';\n');
- print('DYNAMIC_BASE = DYNAMICTOP = Runtime.alignMemory(STACK_MAX);\n');
- print('assert(DYNAMIC_BASE < TOTAL_MEMORY); // Stack must fit in TOTAL_MEMORY; allocations from here on may enlarge TOTAL_MEMORY\n');
+ if (!BUILD_AS_SHARED_LIB) {
+ print('STACK_BASE = STACKTOP = Runtime.alignMemory(STATICTOP);\n');
+ print('staticSealed = true; // seal the static portion of memory\n');
+ print('STACK_MAX = STACK_BASE + ' + TOTAL_STACK + ';\n');
+ print('DYNAMIC_BASE = DYNAMICTOP = Runtime.alignMemory(STACK_MAX);\n');
+ print('assert(DYNAMIC_BASE < TOTAL_MEMORY); // Stack must fit in TOTAL_MEMORY; allocations from here on may enlarge TOTAL_MEMORY\n');
+ }
if (asmLibraryFunctions.length > 0) {
print('// ASM_LIBRARY FUNCTIONS');
@@ -1802,7 +1825,9 @@ function JSify(data, functionsOnly, givenFunctions) {
}
if (HEADLESS) {
print('if (!ENVIRONMENT_IS_WEB) {');
- print(read('headless.js').replace("'%s'", "'http://emscripten.org'").replace("'?%s'", "''").replace('%s,', 'null,').replace('%d', '0'));
+ print(read('headlessCanvas.js'));
+ print('\n');
+ print(read('headless.js').replace("'%s'", "'http://emscripten.org'").replace("'?%s'", "''").replace("'?%s'", "'/'").replace('%s,', 'null,').replace('%d', '0'));
print('}');
}
if (RUNTIME_TYPE_INFO) {
diff --git a/src/library.js b/src/library.js
index 9e78db13..3ba2f56b 100644
--- a/src/library.js
+++ b/src/library.js
@@ -6808,24 +6808,38 @@ LibraryManager.library = {
_pthread_once.seen[ptr] = 1;
},
+ $PTHREAD_SPECIFIC: {},
+ $PTHREAD_SPECIFIC_NEXT_KEY: 1,
+ pthread_key_create__deps: ['$PTHREAD_SPECIFIC', '$PTHREAD_SPECIFIC_NEXT_KEY', '$ERRNO_CODES'],
pthread_key_create: function(key, destructor) {
- if (!_pthread_key_create.keys) _pthread_key_create.keys = {};
+ if (key == 0) {
+ return ERRNO_CODES.EINVAL;
+ }
+ {{{ makeSetValue('key', '0', 'PTHREAD_SPECIFIC_NEXT_KEY', 'i32*') }}}
// values start at 0
- _pthread_key_create.keys[key] = 0;
+ PTHREAD_SPECIFIC[PTHREAD_SPECIFIC_NEXT_KEY] = 0;
+ PTHREAD_SPECIFIC_NEXT_KEY++;
+ return 0;
},
+ pthread_getspecific__deps: ['$PTHREAD_SPECIFIC'],
pthread_getspecific: function(key) {
- return _pthread_key_create.keys[key] || 0;
+ return PTHREAD_SPECIFIC[key] || 0;
},
+ pthread_setspecific__deps: ['$PTHREAD_SPECIFIC', '$ERRNO_CODES'],
pthread_setspecific: function(key, value) {
- _pthread_key_create.keys[key] = value;
+ if (value == 0) {
+ return ERRNO_CODES.EINVAL;
+ }
+ PTHREAD_SPECIFIC[key] = value;
+ return 0;
},
- pthread_key_delete: ['$ERRNO_CODES'],
+ pthread_key_delete__deps: ['$PTHREAD_SPECIFIC', '$ERRNO_CODES'],
pthread_key_delete: function(key) {
- if (_pthread_key_create.keys[key]) {
- delete _pthread_key_create.keys[key];
+ if (key in PTHREAD_SPECIFIC) {
+ delete PTHREAD_SPECIFIC[key];
return 0;
}
return ERRNO_CODES.EINVAL;
diff --git a/src/library_browser.js b/src/library_browser.js
index 511e158e..591a3c11 100644
--- a/src/library_browser.js
+++ b/src/library_browser.js
@@ -452,8 +452,21 @@ mergeInto(LibraryManager.library, {
// Otherwise, calculate the movement based on the changes
// in the coordinates.
var rect = Module["canvas"].getBoundingClientRect();
- var x = event.pageX - (window.scrollX + rect.left);
- var y = event.pageY - (window.scrollY + rect.top);
+ var x, y;
+ if (event.type == 'touchstart' ||
+ event.type == 'touchend' ||
+ event.type == 'touchmove') {
+ var t = event.touches.item(0);
+ if (t) {
+ x = t.pageX - (window.scrollX + rect.left);
+ y = t.pageY - (window.scrollY + rect.top);
+ } else {
+ return;
+ }
+ } else {
+ x = event.pageX - (window.scrollX + rect.left);
+ y = event.pageY - (window.scrollY + rect.top);
+ }
// the canvas might be CSS-scaled compared to its backbuffer;
// SDL-using content will want mouse coordinates in terms
@@ -808,6 +821,13 @@ mergeInto(LibraryManager.library, {
emscripten_set_canvas_size: function(width, height) {
Browser.setCanvasSize(width, height);
},
+
+ emscripten_get_canvas_size: function(width, height, isFullscreen) {
+ var canvas = Module['canvas'];
+ {{{ makeSetValue('width', '0', 'canvas.width', 'i32') }}};
+ {{{ makeSetValue('height', '0', 'canvas.height', 'i32') }}};
+ {{{ makeSetValue('isFullscreen', '0', 'Browser.isFullScreen ? 1 : 0', 'i32') }}};
+ },
emscripten_get_now: function() {
if (ENVIRONMENT_IS_NODE) {
diff --git a/src/library_fs.js b/src/library_fs.js
index 9d1f0cfd..e1397356 100644
--- a/src/library_fs.js
+++ b/src/library_fs.js
@@ -509,7 +509,7 @@ mergeInto(LibraryManager.library, {
var mode = FS.getMode(canRead, canWrite);
return FS.create(path, mode);
},
- createDataFile: function(parent, name, data, canRead, canWrite) {
+ createDataFile: function(parent, name, data, canRead, canWrite, canOwn) {
var path = PATH.join(typeof parent === 'string' ? parent : FS.getPath(parent), name);
var mode = FS.getMode(canRead, canWrite);
var node = FS.create(path, mode);
@@ -522,7 +522,7 @@ mergeInto(LibraryManager.library, {
// make sure we can write to the file
FS.chmod(path, mode | {{{ cDefine('S_IWUGO') }}});
var stream = FS.open(path, 'w');
- FS.write(stream, data, 0, data.length, 0);
+ FS.write(stream, data, 0, data.length, 0, canOwn);
FS.close(stream);
FS.chmod(path, mode);
}
@@ -766,7 +766,7 @@ mergeInto(LibraryManager.library, {
// You can also call this with a typed array instead of a url. It will then
// do preloading for the Image/Audio part, as if the typed array were the
// result of an XHR that you did manually.
- createPreloadedFile: function(parent, name, url, canRead, canWrite, onload, onerror, dontCreateFile) {
+ createPreloadedFile: function(parent, name, url, canRead, canWrite, onload, onerror, dontCreateFile, canOwn) {
Browser.init();
// TODO we should allow people to just pass in a complete filename instead
// of parent and name being that we just join them anyways
@@ -774,7 +774,7 @@ mergeInto(LibraryManager.library, {
function processData(byteArray) {
function finish(byteArray) {
if (!dontCreateFile) {
- FS.createDataFile(parent, name, byteArray, canRead, canWrite);
+ FS.createDataFile(parent, name, byteArray, canRead, canWrite, canOwn);
}
if (onload) onload();
removeRunDependency('cp ' + fullname);
@@ -1323,7 +1323,7 @@ mergeInto(LibraryManager.library, {
if (!seeking) stream.position += bytesRead;
return bytesRead;
},
- write: function(stream, buffer, offset, length, position) {
+ write: function(stream, buffer, offset, length, position, canOwn) {
if (length < 0 || position < 0) {
throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
}
@@ -1347,7 +1347,7 @@ mergeInto(LibraryManager.library, {
// seek to the end before writing in append mode
FS.llseek(stream, 0, {{{ cDefine('SEEK_END') }}});
}
- var bytesWritten = stream.stream_ops.write(stream, buffer, offset, length, position);
+ var bytesWritten = stream.stream_ops.write(stream, buffer, offset, length, position, canOwn);
if (!seeking) stream.position += bytesWritten;
return bytesWritten;
},
diff --git a/src/library_glut.js b/src/library_glut.js
index 29957e6f..60dc6540 100644
--- a/src/library_glut.js
+++ b/src/library_glut.js
@@ -267,11 +267,19 @@ var LibraryGLUT = {
// Ignore arguments
GLUT.initTime = Date.now();
+ var isTouchDevice = 'ontouchstart' in document.documentElement;
+
window.addEventListener("keydown", GLUT.onKeydown, true);
window.addEventListener("keyup", GLUT.onKeyup, true);
- window.addEventListener("mousemove", GLUT.onMousemove, true);
- window.addEventListener("mousedown", GLUT.onMouseButtonDown, true);
- window.addEventListener("mouseup", GLUT.onMouseButtonUp, true);
+ if (isTouchDevice) {
+ window.addEventListener("touchmove", GLUT.onMousemove, true);
+ window.addEventListener("touchstart", GLUT.onMouseButtonDown, true);
+ window.addEventListener("touchend", GLUT.onMouseButtonUp, true);
+ } else {
+ window.addEventListener("mousemove", GLUT.onMousemove, true);
+ window.addEventListener("mousedown", GLUT.onMouseButtonDown, true);
+ window.addEventListener("mouseup", GLUT.onMouseButtonUp, true);
+ }
Browser.resizeListeners.push(function(width, height) {
if (GLUT.reshapeFunc) {
@@ -282,9 +290,15 @@ var LibraryGLUT = {
__ATEXIT__.push({ func: function() {
window.removeEventListener("keydown", GLUT.onKeydown, true);
window.removeEventListener("keyup", GLUT.onKeyup, true);
- window.removeEventListener("mousemove", GLUT.onMousemove, true);
- window.removeEventListener("mousedown", GLUT.onMouseButtonDown, true);
- window.removeEventListener("mouseup", GLUT.onMouseButtonUp, true);
+ if (isTouchDevice) {
+ window.removeEventListener("touchmove", GLUT.onMousemove, true);
+ window.removeEventListener("touchstart", GLUT.onMouseButtonDown, true);
+ window.removeEventListener("touchend", GLUT.onMouseButtonUp, true);
+ } else {
+ window.removeEventListener("mousemove", GLUT.onMousemove, true);
+ window.removeEventListener("mousedown", GLUT.onMouseButtonDown, true);
+ window.removeEventListener("mouseup", GLUT.onMouseButtonUp, true);
+ }
Module["canvas"].width = Module["canvas"].height = 1;
} });
},
diff --git a/src/library_memfs.js b/src/library_memfs.js
index 0fa6cdfb..63326c42 100644
--- a/src/library_memfs.js
+++ b/src/library_memfs.js
@@ -1,6 +1,22 @@
mergeInto(LibraryManager.library, {
$MEMFS__deps: ['$FS'],
$MEMFS: {
+ // content modes
+ CONTENT_OWNING: 1, // contains a subarray into the heap, and we own it - need to free() when no longer needed
+ CONTENT_FLEXIBLE: 2, // has been modified or never set to anything, and is a flexible js array that can grow/shrink
+ CONTENT_FIXED: 3, // contains some fixed-size content written into it, in a typed array
+ ensureFlexible: function(node) {
+ if (node.contentMode !== MEMFS.CONTENT_FLEXIBLE) {
+ var contents = node.contents;
+ node.contents = Array.prototype.slice.call(contents);
+ if (node.contentMode === MEMFS.CONTENT_OWNING) {
+ assert(contents.byteOffset);
+ Module['_free'](contents.byteOffset);
+ }
+ node.contentMode = MEMFS.CONTENT_FLEXIBLE;
+ }
+ },
+
mount: function(mount) {
return MEMFS.create_node(null, '/', {{{ cDefine('S_IFDIR') }}} | 0777, 0);
},
@@ -40,6 +56,7 @@ mergeInto(LibraryManager.library, {
mmap: MEMFS.stream_ops.mmap
};
node.contents = [];
+ node.contentMode = MEMFS.CONTENT_FLEXIBLE;
} else if (FS.isLink(node.mode)) {
node.node_ops = {
getattr: MEMFS.node_ops.getattr,
@@ -98,6 +115,7 @@ mergeInto(LibraryManager.library, {
node.timestamp = attr.timestamp;
}
if (attr.size !== undefined) {
+ MEMFS.ensureFlexible(node);
var contents = node.contents;
if (attr.size < contents.length) contents.length = attr.size;
else while (attr.size > contents.length) contents.push(0);
@@ -165,7 +183,7 @@ mergeInto(LibraryManager.library, {
var contents = stream.node.contents;
var size = Math.min(contents.length - position, length);
#if USE_TYPED_ARRAYS == 2
- if (contents.subarray) { // typed array
+ if (size > 8 && contents.subarray) { // non-trivial, and typed array
buffer.set(contents.subarray(position, position + size), offset);
} else
#endif
@@ -176,13 +194,30 @@ mergeInto(LibraryManager.library, {
}
return size;
},
- write: function(stream, buffer, offset, length, position) {
- var contents = stream.node.contents;
+ write: function(stream, buffer, offset, length, position, canOwn) {
+ var node = stream.node;
+ node.timestamp = Date.now();
+ var contents = node.contents;
+#if USE_TYPED_ARRAYS == 2
+ if (length && contents.length === 0 && position === 0 && buffer.subarray) {
+ // just replace it with the new data
+ assert(buffer.length);
+ if (canOwn && buffer.buffer === HEAP8.buffer && offset === 0) {
+ node.contents = buffer; // this is a subarray of the heap, and we can own it
+ node.contentMode = MEMFS.CONTENT_OWNING;
+ } else {
+ node.contents = new Uint8Array(buffer.subarray(offset, offset+length));
+ node.contentMode = MEMFS.CONTENT_FIXED;
+ }
+ return length;
+ }
+#endif
+ MEMFS.ensureFlexible(node);
+ var contents = node.contents;
while (contents.length < position) contents.push(0);
for (var i = 0; i < length; i++) {
contents[position + i] = buffer[offset + i];
}
- stream.node.timestamp = Date.now();
return length;
},
llseek: function(stream, offset, whence) {
@@ -202,6 +237,7 @@ mergeInto(LibraryManager.library, {
return position;
},
allocate: function(stream, offset, length) {
+ MEMFS.ensureFlexible(stream.node);
var contents = stream.node.contents;
var limit = offset + length;
while (limit > contents.length) contents.push(0);
@@ -214,10 +250,10 @@ mergeInto(LibraryManager.library, {
var allocated;
var contents = stream.node.contents;
// Only make a new copy when MAP_PRIVATE is specified.
- if (!(flags & {{{ cDefine('MAP_PRIVATE') }}})) {
+ if ( !(flags & {{{ cDefine('MAP_PRIVATE') }}}) &&
+ (contents.buffer === buffer || contents.buffer === buffer.buffer) ) {
// We can't emulate MAP_SHARED when the file is not backed by the buffer
// we're mapping to (e.g. the HEAP buffer).
- assert(contents.buffer === buffer || contents.buffer === buffer.buffer);
allocated = false;
ptr = contents.byteOffset;
} else {
@@ -240,4 +276,5 @@ mergeInto(LibraryManager.library, {
},
}
}
-}); \ No newline at end of file
+});
+
diff --git a/src/library_openal.js b/src/library_openal.js
index cbb5c0bb..dea986f3 100644
--- a/src/library_openal.js
+++ b/src/library_openal.js
@@ -8,6 +8,12 @@ var LibraryOpenAL = {
QUEUE_INTERVAL: 25,
QUEUE_LOOKAHEAD: 100,
+ getCurrentTime: function(context) {
+ // currentTime is frozen during execution, use performance timers to
+ // emulate the current time at call time
+ return (window['performance']['now']() - context.startTime) / 1000.0;
+ },
+
updateSources: function(context) {
for (var i = 0; i < context.src.length; i++) {
AL.updateSource(context.src[i]);
@@ -22,7 +28,7 @@ var LibraryOpenAL = {
return;
}
- var currentTime = AL.currentContext.ctx.currentTime;
+ var currentTime = AL.getCurrentTime(AL.currentContext);
var startTime = src.bufferPosition;
for (var i = src.buffersPlayed; i < src.queue.length; i++) {
@@ -73,7 +79,7 @@ var LibraryOpenAL = {
if (src.state !== 0x1013 /* AL_PAUSED */) {
src.state = 0x1012 /* AL_PLAYING */;
// Reset our position.
- src.bufferPosition = AL.currentContext.ctx.currentTime;
+ src.bufferPosition = AL.getCurrentTime(AL.currentContext);
src.buffersPlayed = 0;
#if OPENAL_DEBUG
console.log('setSourceState resetting and playing source ' + idx);
@@ -81,7 +87,7 @@ var LibraryOpenAL = {
} else {
src.state = 0x1012 /* AL_PLAYING */;
// Use the current offset from src.bufferPosition to resume at the correct point.
- src.bufferPosition = AL.currentContext.ctx.currentTime - src.bufferPosition;
+ src.bufferPosition = AL.getCurrentTime(AL.currentContext) - src.bufferPosition;
#if OPENAL_DEBUG
console.log('setSourceState resuming source ' + idx + ' at ' + src.bufferPosition.toFixed(4));
#endif
@@ -92,7 +98,7 @@ var LibraryOpenAL = {
if (src.state === 0x1012 /* AL_PLAYING */) {
src.state = 0x1013 /* AL_PAUSED */;
// Store off the current offset to restore with on resume.
- src.bufferPosition = AL.currentContext.ctx.currentTime - src.bufferPosition;
+ src.bufferPosition = AL.getCurrentTime(AL.currentContext) - src.bufferPosition;
AL.stopSourceQueue(src);
#if OPENAL_DEBUG
console.log('setSourceState pausing source ' + idx + ' at ' + src.bufferPosition.toFixed(4));
@@ -206,7 +212,8 @@ var LibraryOpenAL = {
err: 0,
src: [],
buf: [],
- interval: setInterval(function() { AL.updateSources(context); }, AL.QUEUE_INTERVAL)
+ interval: setInterval(function() { AL.updateSources(context); }, AL.QUEUE_INTERVAL),
+ startTime: window['performance']['now']()
};
AL.contexts.push(context);
return AL.contexts.length;
@@ -237,7 +244,6 @@ var LibraryOpenAL = {
#if OPENAL_DEBUG
console.error("alDeleteSources called without a valid context");
#endif
- AL.currentContext.err = 0xA004 /* AL_INVALID_OPERATION */;
return;
}
for (var i = 0; i < count; ++i) {
@@ -251,7 +257,6 @@ var LibraryOpenAL = {
#if OPENAL_DEBUG
console.error("alGenSources called without a valid context");
#endif
- AL.currentContext.err = 0xA004 /* AL_INVALID_OPERATION */;
return;
}
for (var i = 0; i < count; ++i) {
@@ -311,7 +316,6 @@ var LibraryOpenAL = {
#if OPENAL_DEBUG
console.error("alSourcei called without a valid context");
#endif
- AL.currentContext.err = 0xA004 /* AL_INVALID_OPERATION */;
return;
}
var src = AL.currentContext.src[source - 1];
@@ -380,7 +384,6 @@ var LibraryOpenAL = {
#if OPENAL_DEBUG
console.error("alSourcef called without a valid context");
#endif
- AL.currentContext.err = 0xA004 /* AL_INVALID_OPERATION */;
return;
}
var src = AL.currentContext.src[source - 1];
@@ -433,7 +436,6 @@ var LibraryOpenAL = {
#if OPENAL_DEBUG
console.error("alSource3f called without a valid context");
#endif
- AL.currentContext.err = 0xA004 /* AL_INVALID_OPERATION */;
return;
}
var src = AL.currentContext.src[source - 1];
@@ -474,7 +476,6 @@ var LibraryOpenAL = {
#if OPENAL_DEBUG
console.error("alSourceQueueBuffers called without a valid context");
#endif
- AL.currentContext.err = 0xA004 /* AL_INVALID_OPERATION */;
return;
}
var src = AL.currentContext.src[source - 1];
@@ -511,7 +512,6 @@ var LibraryOpenAL = {
#if OPENAL_DEBUG
console.error("alSourceUnqueueBuffers called without a valid context");
#endif
- AL.currentContext.err = 0xA004 /* AL_INVALID_OPERATION */;
return;
}
var src = AL.currentContext.src[source - 1];
@@ -550,7 +550,6 @@ var LibraryOpenAL = {
#if OPENAL_DEBUG
console.error("alDeleteBuffers called without a valid context");
#endif
- AL.currentContext.err = 0xA004 /* AL_INVALID_OPERATION */;
return;
}
if (count > AL.currentContext.buf.length) {
@@ -594,7 +593,6 @@ var LibraryOpenAL = {
#if OPENAL_DEBUG
console.error("alGenBuffers called without a valid context");
#endif
- AL.currentContext.err = 0xA004 /* AL_INVALID_OPERATION */;
return;
}
for (var i = 0; i < count; ++i) {
@@ -608,7 +606,6 @@ var LibraryOpenAL = {
#if OPENAL_DEBUG
console.error("alBufferData called without a valid context");
#endif
- AL.currentContext.err = 0xA004 /* AL_INVALID_OPERATION */;
return;
}
if (buffer > AL.currentContext.buf.length) {
@@ -673,7 +670,6 @@ var LibraryOpenAL = {
#if OPENAL_DEBUG
console.error("alSourcePlay called without a valid context");
#endif
- AL.currentContext.err = 0xA004 /* AL_INVALID_OPERATION */;
return;
}
var src = AL.currentContext.src[source - 1];
@@ -693,7 +689,6 @@ var LibraryOpenAL = {
#if OPENAL_DEBUG
console.error("alSourceStop called without a valid context");
#endif
- AL.currentContext.err = 0xA004 /* AL_INVALID_OPERATION */;
return;
}
var src = AL.currentContext.src[source - 1];
@@ -713,7 +708,6 @@ var LibraryOpenAL = {
#if OPENAL_DEBUG
console.error("alSourcePause called without a valid context");
#endif
- AL.currentContext.err = 0xA004 /* AL_INVALID_OPERATION */;
return;
}
var src = AL.currentContext.src[source - 1];
@@ -733,7 +727,6 @@ var LibraryOpenAL = {
#if OPENAL_DEBUG
console.error("alGetSourcei called without a valid context");
#endif
- AL.currentContext.err = 0xA004 /* AL_INVALID_OPERATION */;
return;
}
var src = AL.currentContext.src[source - 1];
@@ -797,7 +790,6 @@ var LibraryOpenAL = {
#if OPENAL_DEBUG
console.error("alGetSourcef called without a valid context");
#endif
- AL.currentContext.err = 0xA004 /* AL_INVALID_OPERATION */;
return;
}
var src = AL.currentContext.src[source - 1];
@@ -858,7 +850,6 @@ var LibraryOpenAL = {
#if OPENAL_DEBUG
console.error("alListenerfv called without a valid context");
#endif
- AL.currentContext.err = 0xA004 /* AL_INVALID_OPERATION */;
return;
}
switch (param) {
diff --git a/src/library_sdl.js b/src/library_sdl.js
index 236ab1bf..1fb75724 100644
--- a/src/library_sdl.js
+++ b/src/library_sdl.js
@@ -379,7 +379,8 @@ var LibrarySDL = {
SDL.surfaces[surf] = null;
},
- touchX:0, touchY: 0,
+ touchX: 0, touchY: 0,
+ savedKeydown: null,
receiveEvent: function(event) {
switch(event.type) {
@@ -466,11 +467,29 @@ var LibrarySDL = {
SDL.DOMButtons[event.button] = 0;
}
- if (event.type == 'keypress' && !SDL.textInput) {
- break;
+ // SDL expects a unicode character to be passed to its keydown events.
+ // Unfortunately, the browser APIs only provide a charCode property on
+ // keypress events, so we must backfill in keydown events with their
+ // subsequent keypress event's charCode.
+ if (event.type === 'keypress' && SDL.savedKeydown) {
+ // charCode is read-only
+ SDL.savedKeydown.keypressCharCode = event.charCode;
+ SDL.savedKeydown = null;
+ } else if (event.type === 'keydown') {
+ SDL.savedKeydown = event;
+ }
+
+ // If we preventDefault on keydown events, the subsequent keypress events
+ // won't fire. However, it's fine (and in some cases necessary) to
+ // preventDefault for keys that don't generate a character.
+ if (event.type !== 'keydown' || (event.keyCode === 8 /* backspace */ || event.keyCode === 9 /* tab */)) {
+ event.preventDefault();
+ }
+
+ // Don't push keypress events unless SDL_StartTextInput has been called.
+ if (event.type !== 'keypress' || SDL.textInput) {
+ SDL.events.push(event);
}
-
- SDL.events.push(event);
break;
case 'mouseout':
// Un-press all pressed mouse buttons, because we might miss the release outside of the canvas
@@ -485,6 +504,7 @@ var LibrarySDL = {
SDL.DOMButtons[i] = 0;
}
}
+ event.preventDefault();
break;
case 'blur':
case 'visibilitychange': {
@@ -495,6 +515,7 @@ var LibrarySDL = {
keyCode: SDL.keyboardMap[code]
});
}
+ event.preventDefault();
break;
}
case 'unload':
@@ -506,16 +527,16 @@ var LibrarySDL = {
return;
case 'resize':
SDL.events.push(event);
+ // manually triggered resize event doesn't have a preventDefault member
+ if (event.preventDefault) {
+ event.preventDefault();
+ }
break;
}
if (SDL.events.length >= 10000) {
Module.printErr('SDL event queue full, dropping events');
SDL.events = SDL.events.slice(0, 10000);
}
- // manually triggered resize event doesn't have a preventDefault member
- if (event.preventDefault) {
- event.preventDefault();
- }
return;
},
@@ -526,7 +547,12 @@ var LibrarySDL = {
switch (event.type) {
case 'keydown': case 'keyup': {
var down = event.type === 'keydown';
- var code = SDL.keyCodes[event.keyCode] || event.keyCode;
+ var code = event.keyCode;
+ if (code >= 65 && code <= 90) {
+ code += 32; // make lowercase for SDL
+ } else {
+ code = SDL.keyCodes[event.keyCode] || event.keyCode;
+ }
{{{ makeSetValue('SDL.keyboardState', 'code', 'down', 'i8') }}};
// TODO: lmeta, rmeta, numlock, capslock, KMOD_MODE, KMOD_RESERVED
@@ -590,8 +616,9 @@ var LibrarySDL = {
{{{ makeSetValue('ptr', 'SDL.structs.KeyboardEvent.repeat', '0', 'i8') }}} // TODO
{{{ makeSetValue('ptr', 'SDL.structs.KeyboardEvent.keysym + SDL.structs.keysym.scancode', 'scan', 'i32') }}}
{{{ makeSetValue('ptr', 'SDL.structs.KeyboardEvent.keysym + SDL.structs.keysym.sym', 'key', 'i32') }}}
- {{{ makeSetValue('ptr', 'SDL.structs.KeyboardEvent.keysym + SDL.structs.keysym.mod', 'SDL.modState', 'i32') }}}
- {{{ makeSetValue('ptr', 'SDL.structs.KeyboardEvent.keysym + SDL.structs.keysym.unicode', 'key', 'i32') }}}
+ {{{ makeSetValue('ptr', 'SDL.structs.KeyboardEvent.keysym + SDL.structs.keysym.mod', 'SDL.modState', 'i16') }}}
+ // some non-character keys (e.g. backspace and tab) won't have keypressCharCode set, fill in with the keyCode.
+ {{{ makeSetValue('ptr', 'SDL.structs.KeyboardEvent.keysym + SDL.structs.keysym.unicode', 'event.keypressCharCode || key', 'i32') }}}
break;
}
diff --git a/src/parseTools.js b/src/parseTools.js
index 65e96264..046dac1b 100644
--- a/src/parseTools.js
+++ b/src/parseTools.js
@@ -727,15 +727,37 @@ function makeI64(low, high) {
// Splits a number (an integer in a double, possibly > 32 bits) into an USE_TYPED_ARRAYS == 2 i64 value.
// Will suffer from rounding. mergeI64 does the opposite.
function splitI64(value, floatConversion) {
- // We need to min here, since our input might be a double, and large values are rounded, so they can
+ // general idea:
+ //
+ // $1$0 = ~~$d >>> 0;
+ // $1$1 = Math_abs($d) >= 1 ? (
+ // $d > 0 ? Math.min(Math_floor(($d)/ 4294967296.0), 4294967295.0)
+ // : Math_ceil(Math.min(-4294967296.0, $d - $1$0)/ 4294967296.0)
+ // ) : 0;
+ //
+ // We need to min on positive values here, since our input might be a double, and large values are rounded, so they can
// be slightly higher than expected. And if we get 4294967296, that will turn into a 0 if put into a
// HEAP32 or |0'd, etc.
+ //
+ // For negatives, we need to ensure a -1 if the value is overall negative, even if not significant negative component
+
var lowInput = legalizedI64s ? value : 'VALUE';
if (floatConversion && ASM_JS) lowInput = asmFloatToInt(lowInput);
+ var low = lowInput + '>>>0';
+ var high = makeInlineCalculation(
+ asmCoercion('Math.abs(VALUE)', 'double') + ' >= ' + asmEnsureFloat('1', 'double') + ' ? ' +
+ '(VALUE > ' + asmEnsureFloat('0', 'double') + ' ? ' +
+ asmCoercion('Math.min(' + asmCoercion('Math.floor((VALUE)/' + asmEnsureFloat(4294967296, 'float') + ')', 'double') + ', ' + asmEnsureFloat(4294967295, 'float') + ')', 'i32') + '>>>0' +
+ ' : ' + asmFloatToInt(asmCoercion('Math.ceil((VALUE - +((' + asmFloatToInt('VALUE') + ')>>>0))/' + asmEnsureFloat(4294967296, 'float') + ')', 'double')) + '>>>0' +
+ ')' +
+ ' : 0',
+ value,
+ 'tempDouble'
+ );
if (legalizedI64s) {
- return [lowInput + '>>>0', asmCoercion('Math.min(' + asmCoercion('Math.floor((' + value + ')/' + asmEnsureFloat(4294967296, 'float') + ')', 'double') + ', ' + asmEnsureFloat(4294967295, 'float') + ')', 'i32') + '>>>0'];
+ return [low, high];
} else {
- return makeInlineCalculation(makeI64(lowInput + '>>>0', asmCoercion('Math.min(' + asmCoercion('Math.floor(VALUE/' + asmEnsureFloat(4294967296, 'float') + ')', 'double') + ', ' + asmEnsureFloat(4294967295, 'float') + ')', 'i32') + '>>>0'), value, 'tempBigIntP');
+ return makeI64(low, high);
}
}
function mergeI64(value, unsigned) {
diff --git a/src/postamble.js b/src/postamble.js
index 08c3a9d8..df844121 100644
--- a/src/postamble.js
+++ b/src/postamble.js
@@ -11,12 +11,18 @@ ExitStatus.prototype.constructor = ExitStatus;
var initialStackTop;
+var preloadStartTime = null;
+
Module['callMain'] = Module.callMain = function callMain(args) {
assert(runDependencies == 0, 'cannot call main when async dependencies remain! (listen on __ATMAIN__)');
assert(__ATPRERUN__.length == 0, 'cannot call main when preRun functions remain to be called');
args = args || [];
+ if (ENVIRONMENT_IS_WEB && preloadStartTime !== null) {
+ Module.printErr('preload time: ' + (Date.now() - preloadStartTime) + ' ms');
+ }
+
ensureInitRuntime();
var argc = args.length+1;
@@ -72,6 +78,8 @@ Module['callMain'] = Module.callMain = function callMain(args) {
function run(args) {
args = args || Module['arguments'];
+ if (preloadStartTime === null) preloadStartTime = Date.now();
+
if (runDependencies > 0) {
Module.printErr('run() called, but dependencies remain, so not running');
return;
diff --git a/src/preamble.js b/src/preamble.js
index 0f3f52c9..4cae05a6 100644
--- a/src/preamble.js
+++ b/src/preamble.js
@@ -524,6 +524,7 @@ function allocate(slab, types, allocator, ptr) {
Module['allocate'] = allocate;
function Pointer_stringify(ptr, /* optional */ length) {
+ // TODO: use TextDecoder
// Find the length, and check for UTF while doing so
var hasUtf = false;
var t;
diff --git a/src/relooper/Relooper.cpp b/src/relooper/Relooper.cpp
index a457914b..afb6ecc8 100644
--- a/src/relooper/Relooper.cpp
+++ b/src/relooper/Relooper.cpp
@@ -104,12 +104,14 @@ void Branch::Render(Block *Target, bool SetLabel) {
int Block::IdCounter = 1; // 0 is reserved for clearings
-Block::Block(const char *CodeInit) : Parent(NULL), Id(Block::IdCounter++), IsCheckedMultipleEntry(false) {
+Block::Block(const char *CodeInit, const char *BranchVarInit) : Parent(NULL), Id(Block::IdCounter++), IsCheckedMultipleEntry(false) {
Code = strdup(CodeInit);
+ BranchVar = BranchVarInit ? strdup(BranchVarInit) : NULL;
}
Block::~Block() {
if (Code) free((void*)Code);
+ if (BranchVar) free((void*)BranchVar);
for (BlockBranchMap::iterator iter = ProcessedBranchesOut.begin(); iter != ProcessedBranchesOut.end(); iter++) {
delete iter->second;
}
@@ -189,8 +191,14 @@ void Block::Render(bool InLoop) {
}
assert(DefaultTarget); // Since each block *must* branch somewhere, this must be set
+ bool useSwitch = BranchVar != NULL;
+
+ if (useSwitch) {
+ PrintIndented("switch (%s) {\n", BranchVar);
+ }
+
ministring RemainingConditions;
- bool First = true;
+ bool First = !useSwitch; // when using a switch, there is no special first
for (BlockBranchMap::iterator iter = ProcessedBranchesOut.begin();; iter++) {
Block *Target;
Branch *Details;
@@ -208,26 +216,39 @@ void Block::Render(bool InLoop) {
bool HasContent = SetCurrLabel || Details->Type != Branch::Direct || HasFusedContent || Details->Code;
if (iter != ProcessedBranchesOut.end()) {
// If there is nothing to show in this branch, omit the condition
- if (HasContent) {
- PrintIndented("%sif (%s) {\n", First ? "" : "} else ", Details->Condition);
- First = false;
+ if (useSwitch) {
+ PrintIndented("%s {\n", Details->Condition);
} else {
- if (RemainingConditions.size() > 0) RemainingConditions += " && ";
- RemainingConditions += "!(";
- RemainingConditions += Details->Condition;
- RemainingConditions += ")";
+ if (HasContent) {
+ PrintIndented("%sif (%s) {\n", First ? "" : "} else ", Details->Condition);
+ First = false;
+ } else {
+ if (RemainingConditions.size() > 0) RemainingConditions += " && ";
+ RemainingConditions += "!(";
+ if (BranchVar) {
+ RemainingConditions += BranchVar;
+ RemainingConditions += " == ";
+ }
+ RemainingConditions += Details->Condition;
+ RemainingConditions += ")";
+ }
}
} else {
- if (HasContent) {
- if (RemainingConditions.size() > 0) {
- if (First) {
- PrintIndented("if (%s) {\n", RemainingConditions.c_str());
- First = false;
- } else {
- PrintIndented("} else if (%s) {\n", RemainingConditions.c_str());
+ // this is the default
+ if (useSwitch) {
+ PrintIndented("default: {\n");
+ } else {
+ if (HasContent) {
+ if (RemainingConditions.size() > 0) {
+ if (First) {
+ PrintIndented("if (%s) {\n", RemainingConditions.c_str());
+ First = false;
+ } else {
+ PrintIndented("} else if (%s) {\n", RemainingConditions.c_str());
+ }
+ } else if (!First) {
+ PrintIndented("} else {\n");
}
- } else if (!First) {
- PrintIndented("} else {\n");
}
}
}
@@ -236,7 +257,13 @@ void Block::Render(bool InLoop) {
if (HasFusedContent) {
Fused->InnerMap.find(Target)->second->Render(InLoop);
}
+ if (useSwitch && iter != ProcessedBranchesOut.end()) {
+ PrintIndented("break;\n");
+ }
if (!First) Indenter::Unindent();
+ if (useSwitch) {
+ PrintIndented("}\n");
+ }
if (iter == ProcessedBranchesOut.end()) break;
}
if (!First) PrintIndented("}\n");
@@ -392,7 +419,7 @@ void Relooper::Calculate(Block *Entry) {
PrintDebug("Splitting block %d\n", Original->Id);
for (BlockSet::iterator iter = Original->BranchesIn.begin(); iter != Original->BranchesIn.end(); iter++) {
Block *Prior = *iter;
- Block *Split = new Block(Original->Code);
+ Block *Split = new Block(Original->Code, Original->BranchVar);
Parent->Blocks.push_back(Split);
PrintDebug(" to %d\n", Split->Id);
Split->BranchesIn.insert(Prior);
@@ -975,6 +1002,8 @@ void Relooper::Calculate(Block *Entry) {
Root = Next;
Next = NULL;
SHAPE_SWITCH(Root, {
+ if (Simple->Inner->BranchVar) LastLoop = NULL; // a switch clears out the loop (TODO: only for breaks, not continue)
+
// 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.
@@ -1028,6 +1057,11 @@ void Relooper::Calculate(Block *Entry) {
// If we are fusing a Multiple with a loop into this Simple, then visit it now
if (Fused && Fused->NeedLoop) {
LoopStack.push(Fused);
+ }
+ if (Simple->Inner->BranchVar) {
+ LoopStack.push(NULL); // a switch means breaks are now useless, push a dummy
+ }
+ if (Fused) {
RECURSE_Multiple(Fused, FindLabeledLoops);
}
for (BlockBranchMap::iterator iter = Simple->Inner->ProcessedBranchesOut.begin(); iter != Simple->Inner->ProcessedBranchesOut.end(); iter++) {
@@ -1038,14 +1072,18 @@ void Relooper::Calculate(Block *Entry) {
if (Details->Ancestor != LoopStack.top() && Details->Labeled) {
LabeledShape *Labeled = Shape::IsLabeled(Details->Ancestor);
Labeled->Labeled = true;
- Details->Labeled = true;
} else {
Details->Labeled = false;
}
}
}
+ if (Simple->Inner->BranchVar) {
+ LoopStack.pop();
+ }
if (Fused && Fused->NeedLoop) {
LoopStack.pop();
+ }
+ if (Fused) {
Next = Fused->Next;
} else {
Next = Root->Next;
@@ -1173,8 +1211,8 @@ void rl_set_asm_js_mode(int on) {
Relooper::SetAsmJSMode(on);
}
-void *rl_new_block(const char *text) {
- Block *ret = new Block(text);
+void *rl_new_block(const char *text, const char *branch_var) {
+ Block *ret = new Block(text, branch_var);
#if DEBUG
printf(" void *b%d = rl_new_block(\"// code %d\");\n", ret->Id, ret->Id);
__blockDebugMap__[ret] = ret->Id;
diff --git a/src/relooper/Relooper.h b/src/relooper/Relooper.h
index e54b578c..f3dedf8c 100644
--- a/src/relooper/Relooper.h
+++ b/src/relooper/Relooper.h
@@ -59,9 +59,10 @@ struct Block {
Shape *Parent; // The shape we are directly inside
int Id; // A unique identifier
const char *Code; // The string representation of the code in this block. Owning pointer (we copy the input)
+ const char *BranchVar; // If we have more than one branch out, the variable whose value determines where we go
bool IsCheckedMultipleEntry; // If true, we are a multiple entry, so reaching us requires setting the label variable
- Block(const char *CodeInit);
+ Block(const char *CodeInit, const char *BranchVarInit);
~Block();
void AddBranchTo(Block *Target, const char *Condition, const char *Code=NULL);
@@ -235,7 +236,7 @@ extern "C" {
RELOOPERDLL_API void rl_set_output_buffer(char *buffer, int size);
RELOOPERDLL_API void rl_make_output_buffer(int size);
RELOOPERDLL_API void rl_set_asm_js_mode(int on);
-RELOOPERDLL_API void *rl_new_block(const char *text);
+RELOOPERDLL_API void *rl_new_block(const char *text, const char *branch_var);
RELOOPERDLL_API void rl_delete_block(void *block);
RELOOPERDLL_API void rl_block_add_branch_to(void *from, void *to, const char *condition, const char *code);
RELOOPERDLL_API void *rl_new_relooper();
diff --git a/src/relooper/emscripten/glue.js b/src/relooper/emscripten/glue.js
index 36922185..40ddabec 100644
--- a/src/relooper/emscripten/glue.js
+++ b/src/relooper/emscripten/glue.js
@@ -6,15 +6,22 @@
var TBUFFER_SIZE = 10*1024*1024;
var tbuffer = _malloc(TBUFFER_SIZE);
+ var VBUFFER_SIZE = 256;
+ var vbuffer = _malloc(VBUFFER_SIZE);
+
var RelooperGlue = {};
RelooperGlue['init'] = function() {
this.r = _rl_new_relooper();
},
- RelooperGlue['addBlock'] = function(text) {
+ RelooperGlue['addBlock'] = function(text, branchVar) {
assert(this.r);
assert(text.length+1 < TBUFFER_SIZE);
writeStringToMemory(text, tbuffer);
- var b = _rl_new_block(tbuffer);
+ if (branchVar) {
+ assert(branchVar.length+1 < VBUFFER_SIZE);
+ writeStringToMemory(branchVar, vbuffer);
+ }
+ var b = _rl_new_block(tbuffer, branchVar ? vbuffer : 0);
_rl_relooper_add_block(this.r, b);
return b;
};
diff --git a/src/relooper/fuzzer.py b/src/relooper/fuzzer.py
index 5f6bae3d..50846d10 100644
--- a/src/relooper/fuzzer.py
+++ b/src/relooper/fuzzer.py
@@ -26,13 +26,13 @@ while True:
pass
# parts
- entry = '''print('entry'); var label; var state; var decisions = %s; var index = 0; function check() { if (index == decisions.length) throw 'HALT'; return decisions[index++] }''' % str(decisions)
+ entry = '''print('entry'); var label; var state; var modded; var decisions = %s; var index = 0; function check() { if (index == decisions.length) throw 'HALT'; return decisions[index++] }''' % str(decisions)
slow = entry + '\n'
for i in range(len(branches[0])):
if i > 0: slow += 'else '
b = branches[0]
- slow += 'if (state %% %d == %d) { label = %d; }\n' % (len(b)+1, i, b[i]) # TODO: split range 1-n into these options
+ slow += 'if (modded == %d) { label = %d; }\n' % (i, b[i]) # TODO: split range 1-n into these options
if len(branches[0]): slow += 'else '
slow += 'label = %d;\n' % defaults[0]
@@ -51,26 +51,35 @@ int main() {
'''
for i in range(1, num):
- slow += ' case %d: print(%d); state = check(); \n' % (i, i)
+ slow += ' case %d: print(%d); state = check(); modded = state %% %d\n' % (i, i, len(branches[i])+1)
b = branches[i]
for j in range(len(b)):
- slow += ' if (state %% %d == %d) { label = %d; break }\n' % (len(b)+1, j, b[j]) # TODO: split range 1-n into these options
+ slow += ' if (modded == %d) { label = %d; break }\n' % (j, b[j]) # TODO: split range 1-n into these options
slow += ' label = %d; break\n' % defaults[i]
+ branch_vars = []
for i in range(num):
+ branch_var = '"modded"' if len(branches[i]) > 0 and not (len(branches[i]) == 1 and random.random() < 0.5) else 'NULL'
+ branch_vars.append(branch_var)
+
if i == 0:
fast += '''
- Block *b%d = new Block("%s");
-''' % (i, entry)
+ Block *b%d = new Block("%s", %s);
+''' % (i, entry, branch_var)
else:
- fast += ''' Block *b%d = new Block("print(%d); state = check();%s");
-''' % (i, i, '// ' + ('.' * int(random.expovariate(0.5/num))))
+ fast += ''' Block *b%d = new Block("print(%d); state = check(); modded = state %% %d; %s", %s);
+''' % (i, i, len(branches[i])+1, '// ' + ('.' * int(random.expovariate(0.5/num))), branch_var)
for i in range(num):
+ branch_var = branch_vars[i]
b = branches[i]
for j in range(len(b)):
- fast += ''' b%d->AddBranchTo(b%d, "state %% %d == %d");
-''' % (i, b[j], len(b)+1, j)
+ if branch_var == 'NULL':
+ fast += ''' b%d->AddBranchTo(b%d, "modded == %d");
+''' % (i, b[j], j)
+ else:
+ fast += ''' b%d->AddBranchTo(b%d, "case %d:");
+''' % (i, b[j], j)
fast += ''' b%d->AddBranchTo(b%d, NULL);
''' % (i, defaults[i])
diff --git a/src/relooper/test.cpp b/src/relooper/test.cpp
index b2d500d7..fbd9c7aa 100644
--- a/src/relooper/test.cpp
+++ b/src/relooper/test.cpp
@@ -7,11 +7,11 @@ int main() {
if (1) {
Relooper::SetOutputBuffer(buffer, sizeof(buffer));
- printf("\n\n-- If pattern --\n\n");
+ printf("\n\n-- If pattern --\n\n", "the_var");
- Block *b_a = new Block("// block A\n");
- Block *b_b = new Block("// block B\n");
- Block *b_c = new Block("// block C\n");
+ Block *b_a = new Block("// block A\n", "the_var");
+ Block *b_b = new Block("// block B\n", "the_var");
+ Block *b_c = new Block("// block C\n", "the_var");
b_a->AddBranchTo(b_b, "check == 10", "atob();");
b_a->AddBranchTo(b_c, NULL, "atoc();");
@@ -24,7 +24,7 @@ int main() {
r.AddBlock(b_c);
r.Calculate(b_a);
- printf("\n\n");
+ printf("\n\n", "the_var");
r.Render();
puts(buffer);
@@ -33,12 +33,12 @@ int main() {
if (1) {
Relooper::SetOutputBuffer(buffer, sizeof(buffer));
- printf("\n\n-- If-else pattern --\n\n");
+ printf("\n\n-- If-else pattern --\n\n", "the_var");
- Block *b_a = new Block("// block A\n");
- Block *b_b = new Block("// block B\n");
- Block *b_c = new Block("// block C\n");
- Block *b_d = new Block("// block D\n");
+ Block *b_a = new Block("// block A\n", "the_var");
+ Block *b_b = new Block("// block B\n", "the_var");
+ Block *b_c = new Block("// block C\n", "the_var");
+ Block *b_d = new Block("// block D\n", "the_var");
b_a->AddBranchTo(b_b, "check == 15");
b_a->AddBranchTo(b_c, NULL);
@@ -54,7 +54,7 @@ int main() {
r.AddBlock(b_d);
r.Calculate(b_a);
- printf("\n\n");
+ printf("\n\n", "the_var");
r.Render();
puts(buffer);
@@ -63,11 +63,11 @@ int main() {
if (1) {
Relooper::SetOutputBuffer(buffer, sizeof(buffer));
- printf("\n\n-- Loop + tail pattern --\n\n");
+ printf("\n\n-- Loop + tail pattern --\n\n", "the_var");
- Block *b_a = new Block("// block A\nvar check = maybe();\n");
- Block *b_b = new Block("// block B\n");
- Block *b_c = new Block("// block C\n");
+ Block *b_a = new Block("// block A\nvar check = maybe();\n", "the_var");
+ Block *b_b = new Block("// block B\n", "the_var");
+ Block *b_c = new Block("// block C\n", "the_var");
b_a->AddBranchTo(b_b, NULL);
@@ -80,7 +80,7 @@ int main() {
r.AddBlock(b_c);
r.Calculate(b_a);
- printf("\n\n");
+ printf("\n\n", "the_var");
r.Render();
puts(buffer);
@@ -89,29 +89,29 @@ int main() {
if (1) {
Relooper::SetOutputBuffer(buffer, sizeof(buffer));
- printf("\n\n-- Loop with phi to head \n\n");
+ printf("\n\n-- Loop with phi to head \n\n", "the_var");
void *block_map[10000];
void *rl = rl_new_relooper();
- void *b1 = rl_new_block("// code 1");
+ void *b1 = rl_new_block("// code 1", "the_var");
block_map[1] = b1;
rl_relooper_add_block(rl, block_map[1]);
- void *b2 = rl_new_block("// code 2");
+ void *b2 = rl_new_block("// code 2", "the_var");
block_map[2] = b2;
rl_relooper_add_block(rl, block_map[2]);
- void *b3 = rl_new_block("// code 3");
+ void *b3 = rl_new_block("// code 3", "the_var");
block_map[3] = b3;
rl_relooper_add_block(rl, block_map[3]);
- void *b4 = rl_new_block("// code 4");
+ void *b4 = rl_new_block("// code 4", "the_var");
block_map[4] = b4;
rl_relooper_add_block(rl, block_map[4]);
- void *b5 = rl_new_block("// code 5");
+ void *b5 = rl_new_block("// code 5", "the_var");
block_map[5] = b5;
rl_relooper_add_block(rl, block_map[5]);
- void *b6 = rl_new_block("// code 6");
+ void *b6 = rl_new_block("// code 6", "the_var");
block_map[6] = b6;
rl_relooper_add_block(rl, block_map[6]);
- void *b7 = rl_new_block("// code 7");
+ void *b7 = rl_new_block("// code 7", "the_var");
block_map[7] = b7;
rl_relooper_add_block(rl, block_map[7]);
rl_block_add_branch_to(block_map[1], block_map[2], NULL, "var $i_0 = 0;var $x_0 = 5; ");
@@ -132,13 +132,13 @@ int main() {
if (1) {
Relooper::SetOutputBuffer(buffer, sizeof(buffer));
- printf("\n\n-- phi on split dead ends --\n\n");
+ printf("\n\n-- phi on split dead ends --\n\n", "the_var");
- Block *b_a = new Block("// block A...................................................................................................\n");
- Block *b_b = new Block("// block B...................................................................................................\n");
- Block *b_c = new Block("// block C...................................................................................................\n");
- Block *b_d = new Block("// block D\n"); // small and splittable!
- Block *b_e = new Block("// block E\n");
+ Block *b_a = new Block("// block A...................................................................................................\n", "the_var");
+ Block *b_b = new Block("// block B...................................................................................................\n", "the_var");
+ Block *b_c = new Block("// block C...................................................................................................\n", "the_var");
+ Block *b_d = new Block("// block D\n", "the_var"); // small and splittable!
+ Block *b_e = new Block("// block E\n", "the_var");
b_a->AddBranchTo(b_b, "chak()", "atob();");
b_a->AddBranchTo(b_c, NULL, "atoc();");
@@ -155,7 +155,7 @@ int main() {
r.AddBlock(b_e);
r.Calculate(b_a);
- printf("\n\n");
+ printf("\n\n", "the_var");
r.Render();
puts(buffer);
@@ -164,12 +164,12 @@ int main() {
if (1) {
Relooper::SetOutputBuffer(buffer, sizeof(buffer));
- printf("\n\n-- Unbalanced with a dead end --\n\n");
+ printf("\n\n-- Unbalanced with a dead end --\n\n", "the_var");
- Block *b_a = new Block("// block A\n");
- Block *b_b = new Block("// block B\n");
- Block *b_c = new Block("return C;\n");
- Block *b_d = new Block("// block D\n");
+ Block *b_a = new Block("// block A\n", "the_var");
+ Block *b_b = new Block("// block B\n", "the_var");
+ Block *b_c = new Block("return C;\n", "the_var");
+ Block *b_d = new Block("// block D\n", "the_var");
b_a->AddBranchTo(b_b, "check == 10");
b_a->AddBranchTo(b_c, NULL); // c is a dead end
@@ -185,7 +185,7 @@ int main() {
r.AddBlock(b_d);
r.Calculate(b_a);
- printf("\n\n");
+ printf("\n\n", "the_var");
r.Render();
puts(buffer);
@@ -194,14 +194,14 @@ int main() {
if (1) {
Relooper::SetOutputBuffer(buffer, sizeof(buffer));
- printf("\n\n-- if (expensive || expensive2) X else Y; Z --\n\n");
+ printf("\n\n-- if (expensive || expensive2) X else Y; Z --\n\n", "the_var");
- Block *b_a = new Block("// block A\n");
- Block *b_b = new Block("// block B\n");
- Block *b_c = new Block("// block C;\n");
- Block *b_d = new Block("// block D\n");
- Block *b_e = new Block("// block E\n");
- Block *b_f = new Block("// block F\n");
+ Block *b_a = new Block("// block A\n", "the_var");
+ Block *b_b = new Block("// block B\n", "the_var");
+ Block *b_c = new Block("// block C;\n", "the_var");
+ Block *b_d = new Block("// block D\n", "the_var");
+ Block *b_e = new Block("// block E\n", "the_var");
+ Block *b_f = new Block("// block F\n", "the_var");
b_a->AddBranchTo(b_c, "expensive()");
b_a->AddBranchTo(b_b, NULL);
@@ -226,7 +226,7 @@ int main() {
r.AddBlock(b_f);
r.Calculate(b_a);
- printf("\n\n");
+ printf("\n\n", "the_var");
r.Render();
puts(buffer);
@@ -235,11 +235,11 @@ int main() {
if (1) {
Relooper::SetOutputBuffer(buffer, sizeof(buffer));
- printf("\n\n-- conditional loop --\n\n");
+ printf("\n\n-- conditional loop --\n\n", "the_var");
- Block *b_a = new Block("// block A\n");
- Block *b_b = new Block("// block B\n");
- Block *b_c = new Block("// block C\n");
+ Block *b_a = new Block("// block A\n", "the_var");
+ Block *b_b = new Block("// block B\n", "the_var");
+ Block *b_c = new Block("// block C\n", "the_var");
b_a->AddBranchTo(b_b, "shouldLoop()");
b_a->AddBranchTo(b_c, NULL);
@@ -253,7 +253,7 @@ int main() {
r.AddBlock(b_c);
r.Calculate(b_a);
- printf("\n\n");
+ printf("\n\n", "the_var");
r.Render();
puts(buffer);
diff --git a/src/relooper/test.txt b/src/relooper/test.txt
index 6c910846..2c530567 100644
--- a/src/relooper/test.txt
+++ b/src/relooper/test.txt
@@ -5,13 +5,21 @@
// block A
-if (check == 10) {
+switch (the_var) {
+check == 10 {
atob();
// block B
- btoc();
-} else {
+ switch (the_var) {
+ default: {
+ btoc();
+ }
+ }
+ break;
+}
+default: {
atoc();
}
+}
// block C
@@ -21,10 +29,22 @@ if (check == 10) {
// block A
-if (check == 15) {
+switch (the_var) {
+check == 15 {
// block B
-} else {
+ switch (the_var) {
+ default: {
+ }
+ }
+ break;
+}
+default: {
// block C
+ switch (the_var) {
+ default: {
+ }
+ }
+}
}
// block D
@@ -34,13 +54,22 @@ if (check == 15) {
-while(1) {
+L9: while(1) {
// block A
var check = maybe();
+ switch (the_var) {
+ default: {
+ }
+ }
// block B
- if (!(check == 41)) {
+ switch (the_var) {
+ check == 41 {
break;
}
+ default: {
+ break L9;
+ }
+ }
}
// block C
@@ -49,30 +78,56 @@ while(1) {
-- Loop with phi to head
// code 1
-var $i_0 = 0;var $x_0 = 5;
-while(1) {
+switch (the_var) {
+default: {
+ var $i_0 = 0;var $x_0 = 5;
+}
+}
+L14: while(1) {
// code 2
- if (!($2)) {
+ switch (the_var) {
+ $2 {
+ break;
+ }
+ default: {
var $x_1 = $x_0;
label = 18;
- break;
+ break L14;
+ }
}
// code 3
- if ($6) {
+ switch (the_var) {
+ $6 {
+ break L14;
break;
- } else {
+ }
+ default: {
var $i_0 = $7;var $x_0 = $5;
}
+ }
}
if (label == 18) {
// code 7
}
// code 4
-if ($10) {
+switch (the_var) {
+$10 {
// code 5
+ switch (the_var) {
+ default: {
+ }
+ }
+ break;
+}
+default: {
+}
}
// code 6
-var $x_1 = $13;
+switch (the_var) {
+default: {
+ var $x_1 = $13;
+}
+}
// code 7
@@ -82,17 +137,29 @@ var $x_1 = $13;
// block A...................................................................................................
-if (chak()) {
+switch (the_var) {
+chak() {
atob();
// block B...................................................................................................
- btod();
+ switch (the_var) {
+ default: {
+ btod();
+ }
+ }
// block D
-} else {
+ break;
+}
+default: {
atoc();
// block C...................................................................................................
- ctod2();
+ switch (the_var) {
+ default: {
+ ctod2();
+ }
+ }
// block D
}
+}
@@ -101,12 +168,25 @@ if (chak()) {
// block A
-if (!(check == 10)) {
+switch (the_var) {
+check == 10 {
+ break;
+}
+default: {
return C;
}
+}
while(1) {
// block B
+ switch (the_var) {
+ default: {
+ }
+ }
// block D
+ switch (the_var) {
+ default: {
+ }
+ }
}
@@ -116,24 +196,49 @@ while(1) {
// block A
-do {
- if (expensive()) {
+L37: do {
+ switch (the_var) {
+ expensive() {
label = 33;
- } else {
+ break;
+ }
+ default: {
// block B
- if (expensive2()) {
+ switch (the_var) {
+ expensive2() {
label = 33;
+ break L37;
break;
}
+ default: {
+ }
+ }
// block D
+ switch (the_var) {
+ default: {
+ }
+ }
+ }
}
} while(0);
if (label == 33) {
// block C;
+ switch (the_var) {
+ default: {
+ }
+ }
}
while(1) {
// block E
+ switch (the_var) {
+ default: {
+ }
+ }
// block F
+ switch (the_var) {
+ default: {
+ }
+ }
}
@@ -143,13 +248,25 @@ while(1) {
// block A
-if (shouldLoop()) {
- while(1) {
- // block B
- if (!(moarLoop())) {
- break;
+L46: do {
+ switch (the_var) {
+ shouldLoop() {
+ while(1) {
+ // block B
+ switch (the_var) {
+ moarLoop() {
+ break;
+ }
+ default: {
+ break L46;
+ }
+ }
}
+ break;
}
-}
+ default: {
+ }
+ }
+} while(0);
// block C
diff --git a/src/relooper/test2.c b/src/relooper/test2.c
index 118a2627..156945c3 100644
--- a/src/relooper/test2.c
+++ b/src/relooper/test2.c
@@ -6,20 +6,20 @@ int main() {
rl_set_output_buffer(buffer, sizeof(buffer));
void *r = rl_new_relooper();
- void *ep = rl_new_block("ep");
+ void *ep = rl_new_block("ep", "var");
rl_relooper_add_block(r, ep);
- void *LBB1 = rl_new_block("LBB1");
+ void *LBB1 = rl_new_block("LBB1", "the_var");
rl_relooper_add_block(r, LBB1);
- void *LBB2 = rl_new_block("LBB2");
+ void *LBB2 = rl_new_block("LBB2", "the_var");
rl_relooper_add_block(r, LBB2);
- void *LBB3 = rl_new_block("LBB3");
+ void *LBB3 = rl_new_block("LBB3", "the_var");
rl_relooper_add_block(r, LBB3);
/*
- void *LBB4 = rl_new_block("LBB4");
+ void *LBB4 = rl_new_block("LBB4", "the_var");
rl_relooper_add_block(r, LBB4);
- void *LBB5 = rl_new_block("LBB5");
+ void *LBB5 = rl_new_block("LBB5", "the_var");
rl_relooper_add_block(r, LBB5);
- void *LBB6 = rl_new_block("LBB6");
+ void *LBB6 = rl_new_block("LBB6", "the_var");
rl_relooper_add_block(r, LBB6);
*/
rl_block_add_branch_to(ep, LBB1, "ep -> LBB1", NULL);
@@ -27,13 +27,13 @@ int main() {
rl_block_add_branch_to(LBB1, LBB2, "LBB1 -> LBB2", NULL);
rl_block_add_branch_to(LBB1, LBB3, NULL, NULL);
rl_block_add_branch_to(LBB2, LBB3, NULL, NULL);
-// rl_block_add_branch_to(LBB3, LBB4, "LBB3 -> LBB4");
-// rl_block_add_branch_to(LBB3, LBB6, "LBB3 -> LBB6");
+// rl_block_add_branch_to(LBB3, LBB4, "LBB3 -> LBB4", "the_var");
+// rl_block_add_branch_to(LBB3, LBB6, "LBB3 -> LBB6", "the_var");
/*
- rl_block_add_branch_to(LBB4, LBB5, "LBB4 -> LBB5");
- rl_block_add_branch_to(LBB4, LBB6, "LBB4 -> LBB6");
- rl_block_add_branch_to(LBB5, LBB6, "LBB5 -> LBB6");
- rl_block_add_branch_to(LBB5, LBB5, "LBB5 -> LBB5");
+ rl_block_add_branch_to(LBB4, LBB5, "LBB4 -> LBB5", "the_var");
+ rl_block_add_branch_to(LBB4, LBB6, "LBB4 -> LBB6", "the_var");
+ rl_block_add_branch_to(LBB5, LBB6, "LBB5 -> LBB6", "the_var");
+ rl_block_add_branch_to(LBB5, LBB5, "LBB5 -> LBB5", "the_var");
*/
rl_relooper_calculate(r, ep);
rl_relooper_render(r);
diff --git a/src/relooper/test2.txt b/src/relooper/test2.txt
index 2f3e5ca1..a558a8b7 100644
--- a/src/relooper/test2.txt
+++ b/src/relooper/test2.txt
@@ -1,11 +1,25 @@
ep
-do {
- if (ep -> LBB1) {
+L1: do {
+ switch (var) {
+ ep -> LBB1 {
LBB1
- if (!(LBB1 -> LBB2)) {
+ switch (the_var) {
+ LBB1 -> LBB2 {
break;
}
+ default: {
+ break L1;
+ }
+ }
LBB2
+ switch (the_var) {
+ default: {
+ }
+ }
+ break;
+ }
+ default: {
+ }
}
} while(0);
LBB3
diff --git a/src/relooper/test3.c b/src/relooper/test3.c
index 2cef14fb..f652a2bc 100644
--- a/src/relooper/test3.c
+++ b/src/relooper/test3.c
@@ -6,19 +6,19 @@ int main() {
rl_set_output_buffer(buffer, sizeof(buffer));
void *r = rl_new_relooper();
- void *ep = rl_new_block("ep");
+ void *ep = rl_new_block("ep", "the_var");
rl_relooper_add_block(r, ep);
- void *LBB1 = rl_new_block("LBB1");
+ void *LBB1 = rl_new_block("LBB1", "the_var");
rl_relooper_add_block(r, LBB1);
- void *LBB2 = rl_new_block("LBB2");
+ void *LBB2 = rl_new_block("LBB2", "the_var");
rl_relooper_add_block(r, LBB2);
- void *LBB3 = rl_new_block("LBB3");
+ void *LBB3 = rl_new_block("LBB3", "the_var");
rl_relooper_add_block(r, LBB3);
- void *LBB4 = rl_new_block("LBB4");
+ void *LBB4 = rl_new_block("LBB4", "the_var");
rl_relooper_add_block(r, LBB4);
- void *LBB5 = rl_new_block("LBB5");
+ void *LBB5 = rl_new_block("LBB5", "the_var");
rl_relooper_add_block(r, LBB5);
- void *LBB6 = rl_new_block("LBB6");
+ void *LBB6 = rl_new_block("LBB6", "the_var");
rl_relooper_add_block(r, LBB6);
rl_block_add_branch_to(ep, LBB1, "ep -> LBB1", NULL);
diff --git a/src/relooper/test3.txt b/src/relooper/test3.txt
index 51199f72..f77e2618 100644
--- a/src/relooper/test3.txt
+++ b/src/relooper/test3.txt
@@ -1,26 +1,55 @@
ep
-do {
- if (ep -> LBB1) {
+L1: do {
+ switch (the_var) {
+ ep -> LBB1 {
LBB1
- if (!(LBB1 -> LBB2)) {
+ switch (the_var) {
+ LBB1 -> LBB2 {
break;
}
+ default: {
+ break L1;
+ }
+ }
LBB2
+ switch (the_var) {
+ default: {
+ }
+ }
+ break;
+ }
+ default: {
+ }
}
} while(0);
LBB3
-do {
- if (LBB3 -> LBB4) {
+L5: do {
+ switch (the_var) {
+ LBB3 -> LBB4 {
LBB4
- if (!(LBB4 -> LBB5)) {
+ switch (the_var) {
+ LBB4 -> LBB5 {
break;
}
+ default: {
+ break L5;
+ }
+ }
while(1) {
LBB5
- if (LBB5 -> LBB6) {
+ switch (the_var) {
+ LBB5 -> LBB6 {
+ break L5;
break;
}
+ default: {
+ }
+ }
}
+ break;
+ }
+ default: {
+ }
}
} while(0);
LBB6
diff --git a/src/relooper/test4.cpp b/src/relooper/test4.cpp
index 76fc8ec0..8cbc024c 100644
--- a/src/relooper/test4.cpp
+++ b/src/relooper/test4.cpp
@@ -7,19 +7,19 @@ int main() {
void *r = rl_new_relooper();
- void *b19 = rl_new_block("//19");
+ void *b19 = rl_new_block("//19", "the_var");
rl_relooper_add_block(r, b19);
- void *b20 = rl_new_block("//20");
+ void *b20 = rl_new_block("//20", "the_var");
rl_relooper_add_block(r, b20);
- void *b21 = rl_new_block("//21");
+ void *b21 = rl_new_block("//21", "the_var");
rl_relooper_add_block(r, b21);
- void *b22 = rl_new_block("//22");
+ void *b22 = rl_new_block("//22", "the_var");
rl_relooper_add_block(r, b22);
- void *b23 = rl_new_block("//23");
+ void *b23 = rl_new_block("//23", "the_var");
rl_relooper_add_block(r, b23);
- void *b24 = rl_new_block("//24");
+ void *b24 = rl_new_block("//24", "the_var");
rl_relooper_add_block(r, b24);
- void *b28 = rl_new_block("//28");
+ void *b28 = rl_new_block("//28", "the_var");
rl_relooper_add_block(r, b28);
rl_block_add_branch_to(b19, b20, " 1 ", NULL);
diff --git a/src/relooper/test4.txt b/src/relooper/test4.txt
index ab7051c1..1829e523 100644
--- a/src/relooper/test4.txt
+++ b/src/relooper/test4.txt
@@ -1,23 +1,44 @@
//19
-do {
- if ( 1 ) {
+L1: do {
+ switch (the_var) {
+ 1 {
//20
- if (!( 1 )) {
- label = 4;
+ switch (the_var) {
+ 1 {
break;
}
+ default: {
+ label = 4;
+ break L1;
+ }
+ }
//21
- } else {
+ switch (the_var) {
+ default: {
+ }
+ }
+ break;
+ }
+ default: {
label = 4;
}
+ }
} while(0);
if (label == 4) {
//22
+ switch (the_var) {
+ default: {
+ }
+ }
}
//23
-if ( 1 ) {
+switch (the_var) {
+ 1 {
//24
-} else {
+ break;
+}
+default: {
//28
}
+}
diff --git a/src/relooper/test5.cpp b/src/relooper/test5.cpp
index f86da2b3..d04d157d 100644
--- a/src/relooper/test5.cpp
+++ b/src/relooper/test5.cpp
@@ -7,17 +7,17 @@ int main() {
void *r = rl_new_relooper();
- void *b0 = rl_new_block("//0");
+ void *b0 = rl_new_block("//0", "the_var");
rl_relooper_add_block(r, b0);
- void *b1 = rl_new_block("//1");
+ void *b1 = rl_new_block("//1", "the_var");
rl_relooper_add_block(r, b1);
- void *b2 = rl_new_block("//2");
+ void *b2 = rl_new_block("//2", "the_var");
rl_relooper_add_block(r, b2);
- void *b3 = rl_new_block("//3");
+ void *b3 = rl_new_block("//3", "the_var");
rl_relooper_add_block(r, b3);
- void *b4 = rl_new_block("//4");
+ void *b4 = rl_new_block("//4", "the_var");
rl_relooper_add_block(r, b4);
- void *b5 = rl_new_block("//5");
+ void *b5 = rl_new_block("//5", "the_var");
rl_relooper_add_block(r, b5);
rl_block_add_branch_to(b0, b1, "check(0)", NULL);
diff --git a/src/relooper/test5.txt b/src/relooper/test5.txt
index 83755289..82ef5edf 100644
--- a/src/relooper/test5.txt
+++ b/src/relooper/test5.txt
@@ -1,32 +1,56 @@
//0
-if (check(0)) {
- while(1) {
+switch (the_var) {
+check(0) {
+ L2: while(1) {
//1
- if (!(check(1))) {
+ switch (the_var) {
+ check(1) {
break;
}
+ default: {
+ break L2;
+ }
+ }
}
- while(1) {
+ L4: while(1) {
//2
- if (!(check(2))) {
+ switch (the_var) {
+ check(2) {
break;
}
+ default: {
+ break L4;
+ }
+ }
}
//3
-} else {
+ break;
+}
+default: {
goingFrom0to4();
- while(1) {
+ L7: while(1) {
//4
- if (!(check(4))) {
+ switch (the_var) {
+ check(4) {
break;
}
+ default: {
+ break L7;
+ }
+ }
}
- while(1) {
+ L9: while(1) {
//5
- if (check(5)) {
+ switch (the_var) {
+ check(5) {
+ break L9;
break;
}
+ default: {
+ }
+ }
}
//3
}
+}
diff --git a/src/relooper/test6.cpp b/src/relooper/test6.cpp
index 90453d4c..c292e79c 100644
--- a/src/relooper/test6.cpp
+++ b/src/relooper/test6.cpp
@@ -7,13 +7,13 @@ int main() {
void *r = rl_new_relooper();
- void *b0 = rl_new_block("//0");
+ void *b0 = rl_new_block("//0", "the_var");
rl_relooper_add_block(r, b0);
- void *b1 = rl_new_block("//1");
+ void *b1 = rl_new_block("//1", "the_var");
rl_relooper_add_block(r, b1);
- void *b2 = rl_new_block("//2");
+ void *b2 = rl_new_block("//2", "the_var");
rl_relooper_add_block(r, b2);
- void *b3 = rl_new_block("//3");
+ void *b3 = rl_new_block("//3", "the_var");
rl_relooper_add_block(r, b3);
rl_block_add_branch_to(b0, b1, "check(0)", NULL);
diff --git a/src/relooper/test6.txt b/src/relooper/test6.txt
index 4f29f292..f9d6e93a 100644
--- a/src/relooper/test6.txt
+++ b/src/relooper/test6.txt
@@ -1,11 +1,25 @@
//0
-do {
- if (check(0)) {
+L1: do {
+ switch (the_var) {
+ check(0) {
//1
- if (!(check(1))) {
+ switch (the_var) {
+ check(1) {
break;
}
+ default: {
+ break L1;
+ }
+ }
//2
+ switch (the_var) {
+ default: {
+ }
+ }
+ break;
+ }
+ default: {
+ }
}
} while(0);
//3
diff --git a/src/relooper/test_dead.cpp b/src/relooper/test_dead.cpp
index 887d254c..5c9fde1b 100644
--- a/src/relooper/test_dead.cpp
+++ b/src/relooper/test_dead.cpp
@@ -8,8 +8,8 @@ int main() {
printf("\n\n-- If pattern --\n\n");
- Block *b_a = new Block("// block A\n");
- Block *b_b = new Block("// block B\n"); // never reached
+ Block *b_a = new Block("// block A\n", "the_var");
+ Block *b_b = new Block("// block B\n", "waka"); // never reached
b_b->AddBranchTo(b_b, NULL);
diff --git a/src/relooper/test_debug.cpp b/src/relooper/test_debug.cpp
index 14511b62..91b6c9d7 100644
--- a/src/relooper/test_debug.cpp
+++ b/src/relooper/test_debug.cpp
@@ -6,13 +6,13 @@ int main() {
rl_set_output_buffer(buffer, sizeof(buffer));
void *r = rl_new_relooper();
- void *ep = rl_new_block("ep");
+ void *ep = rl_new_block("ep", "the_var");
rl_relooper_add_block(r, ep);
- void *LBB1 = rl_new_block("LBB1");
+ void *LBB1 = rl_new_block("LBB1", "the_var");
rl_relooper_add_block(r, LBB1);
- void *LBB2 = rl_new_block("LBB2");
+ void *LBB2 = rl_new_block("LBB2", "the_var");
rl_relooper_add_block(r, LBB2);
- void *LBB3 = rl_new_block("LBB3");
+ void *LBB3 = rl_new_block("LBB3", "the_var");
rl_relooper_add_block(r, LBB3);
rl_block_add_branch_to(ep, LBB1, "ep -> LBB1", NULL);
diff --git a/src/relooper/test_debug.txt b/src/relooper/test_debug.txt
index 4a42e642..eb33fdbc 100644
--- a/src/relooper/test_debug.txt
+++ b/src/relooper/test_debug.txt
@@ -115,13 +115,27 @@ int main() {
// === Optimizing shapes ===
// Fusing Multiple to Simple
ep
-do {
- if (ep -> LBB1) {
+L1: do {
+ switch (the_var) {
+ ep -> LBB1 {
LBB1
- if (!(LBB1 -> LBB2)) {
+ switch (the_var) {
+ LBB1 -> LBB2 {
break;
}
+ default: {
+ break L1;
+ }
+ }
LBB2
+ switch (the_var) {
+ default: {
+ }
+ }
+ break;
+ }
+ default: {
+ }
}
} while(0);
LBB3
diff --git a/src/relooper/test_fuzz1.cpp b/src/relooper/test_fuzz1.cpp
index 54205694..ef48ea93 100644
--- a/src/relooper/test_fuzz1.cpp
+++ b/src/relooper/test_fuzz1.cpp
@@ -8,15 +8,15 @@ int main() {
char *buffer = (char*)malloc(SIZE);
Relooper::SetOutputBuffer(buffer, SIZE);
- Block *b0 = new Block("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++] }");
- Block *b1 = new Block("print(1); state = check();");
- Block *b2 = new Block("print(2); state = check();");
- Block *b3 = new Block("print(3); state = check();");
- Block *b4 = new Block("print(4); state = check();");
- Block *b5 = new Block("print(5); state = check();");
- Block *b6 = new Block("print(6); state = check();");
- Block *b7 = new Block("print(7); state = check();");
- Block *b8 = new Block("print(8); state = check();");
+ Block *b0 = new Block("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++] }", "the_var");
+ Block *b1 = new Block("print(1); state = check();", "the_var");
+ Block *b2 = new Block("print(2); state = check();", "the_var");
+ Block *b3 = new Block("print(3); state = check();", "the_var");
+ Block *b4 = new Block("print(4); state = check();", "the_var");
+ Block *b5 = new Block("print(5); state = check();", "the_var");
+ Block *b6 = new Block("print(6); state = check();", "the_var");
+ Block *b7 = new Block("print(7); state = check();", "the_var");
+ Block *b8 = new Block("print(8); state = check();", "the_var");
b0->AddBranchTo(b5, NULL);
b1->AddBranchTo(b3, NULL);
b2->AddBranchTo(b1, NULL);
diff --git a/src/relooper/test_fuzz1.txt b/src/relooper/test_fuzz1.txt
index becbc0d2..d887f5b8 100644
--- a/src/relooper/test_fuzz1.txt
+++ b/src/relooper/test_fuzz1.txt
@@ -1,32 +1,72 @@
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++] }
+switch (the_var) {
+default: {
+}
+}
print(5); state = check();
+switch (the_var) {
+default: {
+}
+}
print(6); state = check();
-if (state == 7) {
+switch (the_var) {
+state == 7 {
print(7); state = check();
- label = 3;
+ switch (the_var) {
+ default: {
+ label = 3;
+ }
+ }
+ break;
+}
+default: {
+}
}
L5: while(1) {
if (label == 3) {
label = 0;
print(2); state = check();
+ switch (the_var) {
+ default: {
+ }
+ }
}
print(1); state = check();
+ switch (the_var) {
+ default: {
+ }
+ }
while(1) {
print(3); state = check();
- if (!(state == 8)) {
+ switch (the_var) {
+ state == 8 {
+ break;
+ }
+ default: {
continue L5;
}
+ }
print(8); state = check();
- if (!(state == 4)) {
+ switch (the_var) {
+ state == 4 {
+ break;
+ }
+ default: {
label = 3;
continue L5;
}
+ }
print(4); state = check();
- if (!(state == 3)) {
+ switch (the_var) {
+ state == 3 {
+ break;
+ }
+ default: {
continue L5;
}
+ }
}
}
diff --git a/src/relooper/test_fuzz2.cpp b/src/relooper/test_fuzz2.cpp
index 00375340..8a66b113 100644
--- a/src/relooper/test_fuzz2.cpp
+++ b/src/relooper/test_fuzz2.cpp
@@ -8,10 +8,10 @@ int main() {
char *buffer = (char*)malloc(SIZE);
Relooper::SetOutputBuffer(buffer, SIZE);
- Block *b0 = new Block("print('entry'); var label; var state; var decisions = [4, 1, 4, 3, 4, 1, 2, 5, 1, 3, 5, 5, 1, 5, 2, 4, 4, 3]; var index = 0; function check() { if (index == decisions.length) throw 'HALT'; return decisions[index++] }");
- Block *b1 = new Block("print(1); state = check();");
- Block *b2 = new Block("print(2); state = check();");
- Block *b3 = new Block("print(3); state = check();");
+ Block *b0 = new Block("print('entry'); var label; var state; var decisions = [4, 1, 4, 3, 4, 1, 2, 5, 1, 3, 5, 5, 1, 5, 2, 4, 4, 3]; var index = 0; function check() { if (index == decisions.length) throw 'HALT'; return decisions[index++] }", "the_var");
+ Block *b1 = new Block("print(1); state = check();", "the_var");
+ Block *b2 = new Block("print(2); state = check();", "the_var");
+ Block *b3 = new Block("print(3); state = check();", "the_var");
b0->AddBranchTo(b1, "state == 1");
b0->AddBranchTo(b3, NULL);
b1->AddBranchTo(b1, NULL);
diff --git a/src/relooper/test_fuzz2.txt b/src/relooper/test_fuzz2.txt
index 02b2c83b..69f4350c 100644
--- a/src/relooper/test_fuzz2.txt
+++ b/src/relooper/test_fuzz2.txt
@@ -1,13 +1,30 @@
print('entry'); var label; var state; var decisions = [4, 1, 4, 3, 4, 1, 2, 5, 1, 3, 5, 5, 1, 5, 2, 4, 4, 3]; var index = 0; function check() { if (index == decisions.length) throw 'HALT'; return decisions[index++] }
-if (state == 1) {
+switch (the_var) {
+state == 1 {
while(1) {
print(1); state = check();
+ switch (the_var) {
+ default: {
+ }
+ }
}
+ break;
+}
+default: {
+}
}
while(1) {
print(3); state = check();
+ switch (the_var) {
+ default: {
+ }
+ }
print(2); state = check();
+ switch (the_var) {
+ default: {
+ }
+ }
}
diff --git a/src/relooper/test_fuzz3.cpp b/src/relooper/test_fuzz3.cpp
index 3f39f5da..cb37d50f 100644
--- a/src/relooper/test_fuzz3.cpp
+++ b/src/relooper/test_fuzz3.cpp
@@ -8,11 +8,11 @@ int main() {
char *buffer = (char*)malloc(SIZE);
Relooper::SetOutputBuffer(buffer, SIZE);
- Block *b0 = new Block("print('entry'); var label; var state; var decisions = [3, 3, 4, 1, 2, 1, 2, 4, 4, 4, 2, 3, 3, 1, 2]; var index = 0; function check() { if (index == decisions.length) throw 'HALT'; return decisions[index++] }");
- Block *b1 = new Block("print(1); state = check();");
- Block *b2 = new Block("print(2); state = check();");
- Block *b3 = new Block("print(3); state = check();");
- Block *b4 = new Block("print(4); state = check();");
+ Block *b0 = new Block("print('entry'); var label; var state; var decisions = [3, 3, 4, 1, 2, 1, 2, 4, 4, 4, 2, 3, 3, 1, 2]; var index = 0; function check() { if (index == decisions.length) throw 'HALT'; return decisions[index++] }", "the_var");
+ Block *b1 = new Block("print(1); state = check();", "the_var");
+ Block *b2 = new Block("print(2); state = check();", "the_var");
+ Block *b3 = new Block("print(3); state = check();", "the_var");
+ Block *b4 = new Block("print(4); state = check();", "the_var");
b0->AddBranchTo(b1, NULL);
b1->AddBranchTo(b3, NULL);
b2->AddBranchTo(b1, NULL);
diff --git a/src/relooper/test_fuzz3.txt b/src/relooper/test_fuzz3.txt
index b4b1831d..398b4803 100644
--- a/src/relooper/test_fuzz3.txt
+++ b/src/relooper/test_fuzz3.txt
@@ -1,9 +1,25 @@
print('entry'); var label; var state; var decisions = [3, 3, 4, 1, 2, 1, 2, 4, 4, 4, 2, 3, 3, 1, 2]; var index = 0; function check() { if (index == decisions.length) throw 'HALT'; return decisions[index++] }
+switch (the_var) {
+default: {
+}
+}
print(1); state = check();
+switch (the_var) {
+default: {
+}
+}
print(3); state = check();
+switch (the_var) {
+default: {
+}
+}
while(1) {
print(4); state = check();
+ switch (the_var) {
+ default: {
+ }
+ }
}
diff --git a/src/relooper/test_fuzz4.cpp b/src/relooper/test_fuzz4.cpp
index 8f969386..8cd93984 100644
--- a/src/relooper/test_fuzz4.cpp
+++ b/src/relooper/test_fuzz4.cpp
@@ -8,11 +8,11 @@ int main() {
char *buffer = (char*)malloc(SIZE);
Relooper::SetOutputBuffer(buffer, SIZE);
- Block *b0 = new Block("print('entry'); var label; var state; var decisions = [2, 2, 1, 3, 2, 2, 1, 3, 2, 3, 3, 1, 3, 2, 1]; var index = 0; function check() { if (index == decisions.length) throw 'HALT'; return decisions[index++] }");
- Block *b1 = new Block("print(1); state = check();");
- Block *b2 = new Block("print(2); state = check();");
- Block *b3 = new Block("print(3); state = check();");
- Block *b4 = new Block("print(4); state = check();");
+ Block *b0 = new Block("print('entry'); var label; var state; var decisions = [2, 2, 1, 3, 2, 2, 1, 3, 2, 3, 3, 1, 3, 2, 1]; var index = 0; function check() { if (index == decisions.length) throw 'HALT'; return decisions[index++] }", "the_var");
+ Block *b1 = new Block("print(1); state = check();", "the_var");
+ Block *b2 = new Block("print(2); state = check();", "the_var");
+ Block *b3 = new Block("print(3); state = check();", "the_var");
+ Block *b4 = new Block("print(4); state = check();", "the_var");
b0->AddBranchTo(b2, "state == 2");
b0->AddBranchTo(b4, NULL);
b1->AddBranchTo(b1, NULL);
diff --git a/src/relooper/test_fuzz4.txt b/src/relooper/test_fuzz4.txt
index 766ebdb6..2e2f2c6f 100644
--- a/src/relooper/test_fuzz4.txt
+++ b/src/relooper/test_fuzz4.txt
@@ -1,19 +1,41 @@
print('entry'); var label; var state; var decisions = [2, 2, 1, 3, 2, 2, 1, 3, 2, 3, 3, 1, 3, 2, 1]; var index = 0; function check() { if (index == decisions.length) throw 'HALT'; return decisions[index++] }
-if (state == 2) {
+switch (the_var) {
+state == 2 {
while(1) {
print(2); state = check();
+ switch (the_var) {
+ default: {
+ }
+ }
}
+ break;
}
-while(1) {
+default: {
+}
+}
+L4: while(1) {
print(4); state = check();
- if (!(state == 4)) {
+ switch (the_var) {
+ state == 4 {
break;
}
+ default: {
+ break L4;
+ }
+ }
}
print(3); state = check();
+switch (the_var) {
+default: {
+}
+}
while(1) {
print(1); state = check();
+ switch (the_var) {
+ default: {
+ }
+ }
}
diff --git a/src/relooper/test_fuzz5.cpp b/src/relooper/test_fuzz5.cpp
index f48c31ee..a58e19ba 100644
--- a/src/relooper/test_fuzz5.cpp
+++ b/src/relooper/test_fuzz5.cpp
@@ -8,16 +8,16 @@ int main() {
char *buffer = (char*)malloc(SIZE);
Relooper::SetOutputBuffer(buffer, SIZE);
- Block *b0 = new Block("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++] }");
- Block *b1 = new Block("print(1); state = check();");
- Block *b2 = new Block("print(2); state = check();");
- Block *b3 = new Block("print(3); state = check();");
- Block *b4 = new Block("print(4); state = check();");
- Block *b5 = new Block("print(5); state = check();");
- Block *b6 = new Block("print(6); state = check();");
- Block *b7 = new Block("print(7); state = check();");
- Block *b8 = new Block("print(8); state = check();");
- Block *b9 = new Block("print(9); state = check();");
+ Block *b0 = new Block("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++] }", "the_var");
+ Block *b1 = new Block("print(1); state = check();", "the_var");
+ Block *b2 = new Block("print(2); state = check();", "the_var");
+ Block *b3 = new Block("print(3); state = check();", "the_var");
+ Block *b4 = new Block("print(4); state = check();", "the_var");
+ Block *b5 = new Block("print(5); state = check();", "the_var");
+ Block *b6 = new Block("print(6); state = check();", "the_var");
+ Block *b7 = new Block("print(7); state = check();", "the_var");
+ Block *b8 = new Block("print(8); state = check();", "the_var");
+ Block *b9 = new Block("print(9); state = check();", "the_var");
b0->AddBranchTo(b7, NULL);
b1->AddBranchTo(b4, "state % 2 == 0");
b1->AddBranchTo(b6, NULL);
diff --git a/src/relooper/test_fuzz5.txt b/src/relooper/test_fuzz5.txt
index 0f76d1ed..f87e5b79 100644
--- a/src/relooper/test_fuzz5.txt
+++ b/src/relooper/test_fuzz5.txt
@@ -1,52 +1,86 @@
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++] }
+switch (the_var) {
+default: {
+}
+}
L1: while(1) {
print(7); state = check();
- if (state % 3 == 1) {
+ switch (the_var) {
+ state % 3 == 1 {
label = 3;
- } else if (state % 3 == 0) {
+ break;
+ }
+ state % 3 == 0 {
print(8); state = check();
- if (state % 2 == 0) {
+ switch (the_var) {
+ state % 2 == 0 {
label = 5;
- } else {
+ break;
+ }
+ default: {
label = 7;
}
- } else {
+ }
break;
}
- while(1) {
+ default: {
+ break L1;
+ }
+ }
+ L5: while(1) {
if (label == 3) {
label = 0;
print(2); state = check();
+ switch (the_var) {
+ default: {
+ }
+ }
print(1); state = check();
- if (state % 2 == 0) {
+ switch (the_var) {
+ state % 2 == 0 {
label = 5;
- continue;
- } else {
+ continue L5;
+ break;
+ }
+ default: {
label = 7;
- continue;
+ continue L5;
+ }
}
}
else if (label == 5) {
label = 0;
print(4); state = check();
- label = 3;
- continue;
+ switch (the_var) {
+ default: {
+ label = 3;
+ continue L5;
+ }
+ }
}
else if (label == 7) {
label = 0;
print(6); state = check();
- if (state % 2 == 0) {
+ switch (the_var) {
+ state % 2 == 0 {
continue L1;
- } else {
+ break;
+ }
+ default: {
label = 7;
- continue;
+ continue L5;
+ }
}
}
}
}
while(1) {
print(3); state = check();
+ switch (the_var) {
+ default: {
+ }
+ }
}
diff --git a/src/relooper/test_fuzz6.cpp b/src/relooper/test_fuzz6.cpp
index 76a016d6..bea834ae 100644
--- a/src/relooper/test_fuzz6.cpp
+++ b/src/relooper/test_fuzz6.cpp
@@ -8,98 +8,98 @@ int main() {
char *buffer = (char*)malloc(SIZE);
Relooper::SetOutputBuffer(buffer, SIZE);
- Block *b0 = new Block("print('entry'); var label; var state; var decisions = [759, 1223, 618, 1805, 277, 512, 204, 1545, 606, 734, 585, 447, 1670, 1031, 665, 1728, 353, 634, 1033, 13, 658, 589, 474, 854, 405, 1111, 1640, 697, 1156, 1357, 317, 618, 990, 1401, 405, 564, 497, 829, 653, 1194, 25, 322, 1178, 198, 1565, 1419, 1608, 486, 368, 606, 813, 22, 148, 141, 261, 375, 472, 964, 1106, 694, 205, 771, 44, 675, 545, 1027, 1528, 240, 1289, 564, 792, 744, 366, 668, 823, 210, 428, 1009, 1662, 1317, 1183, 681, 14, 1334, 712, 506, 224, 695, 401, 1035, 384, 486, 1519, 122, 1186, 1487, 1819, 1702, 463, 1706, 660, 1642, 847, 991, 976, 940, 867, 46, 23, 1449, 56, 1711, 634, 404, 1558, 168, 710, 1581, 1302, 870, 997, 1295, 1739, 769, 1005, 291, 1638, 1771, 842, 659, 1695, 713, 935, 802, 1173, 1572, 850, 607, 996, 55, 1576, 321, 1815, 662, 1044, 1612, 1680, 1050, 844, 553, 278, 1447, 1662, 1094, 1797, 774, 1013, 1204, 907, 340, 1172, 1460, 869, 1264, 111, 1176, 484, 845, 258, 417, 1246, 1017, 745, 189, 333, 1658, 1395, 1764, 1786, 165, 404, 847, 1429, 1574, 403, 718, 1118, 1756, 94, 56, 1498, 1696, 1355, 840, 50, 82, 371, 1087, 875, 1337, 267, 958, 1209, 1167, 1025, 1684, 184, 962, 1496, 201, 127, 372, 1, 1005, 402, 1387, 213, 1143, 1271, 167, 10, 12, 1060, 1390, 1366, 893, 747, 1005, 481, 876, 227, 514, 589, 250, 273, 1188, 1052, 719, 219, 1006, 38, 120, 1454, 489, 672, 149, 534, 1081, 1721, 586, 330, 25, 356, 1743, 1607, 336, 981, 419, 1036, 1293, 1026, 1300, 1453, 792, 22, 45, 420, 409, 1027, 1437, 1421, 795, 136, 1276, 1610, 1593]; var index = 0; function check() { if (index == decisions.length) throw 'HALT'; return decisions[index++] }");
- Block *b1 = new Block("print(1); state = check();// ...........................................................................");
- Block *b2 = new Block("print(2); state = check();// .........");
- Block *b3 = new Block("print(3); state = check();// ..................................");
- Block *b4 = new Block("print(4); state = check();// ...........................................................................................................................");
- Block *b5 = new Block("print(5); state = check();// ..........................................................................................................................................");
- Block *b6 = new Block("print(6); state = check();// .........");
- Block *b7 = new Block("print(7); state = check();// .............................................................................................................................................................................................");
- Block *b8 = new Block("print(8); state = check();// ....................................................................................................................................................................................................................................................");
- Block *b9 = new Block("print(9); state = check();// ...................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................");
- Block *b10 = new Block("print(10); state = check();// ...................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................");
- Block *b11 = new Block("print(11); state = check();// ........................................................");
- Block *b12 = new Block("print(12); state = check();// ................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................");
- Block *b13 = new Block("print(13); state = check();// ...................");
- Block *b14 = new Block("print(14); state = check();// .............................");
- Block *b15 = new Block("print(15); state = check();// ..................................................");
- Block *b16 = new Block("print(16); state = check();// ................................................................................................................................................................................................................................................................................................................................................................");
- Block *b17 = new Block("print(17); state = check();// ................................................................");
- Block *b18 = new Block("print(18); state = check();// ..............................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................");
- Block *b19 = new Block("print(19); state = check();// ......................................................................................................................................................................................................................");
- Block *b20 = new Block("print(20); state = check();// ..................................................................................................................................................................");
- Block *b21 = new Block("print(21); state = check();// ...........................");
- Block *b22 = new Block("print(22); state = check();// .........................................................................................................");
- Block *b23 = new Block("print(23); state = check();// .................................................................................................................................................................................................................");
- Block *b24 = new Block("print(24); state = check();// ...........................");
- Block *b25 = new Block("print(25); state = check();// ......................................................................................................................................................");
- Block *b26 = new Block("print(26); state = check();// .........................................................................................................................................................................................................................................................................");
- Block *b27 = new Block("print(27); state = check();// .............................................................................................................................................................................");
- Block *b28 = new Block("print(28); state = check();// ..............................................................................................................");
- Block *b29 = new Block("print(29); state = check();// ...............");
- Block *b30 = new Block("print(30); state = check();// .................................................................................................................................................................................................................");
- Block *b31 = new Block("print(31); state = check();// ..........................................................................................................................................................................................................");
- Block *b32 = new Block("print(32); state = check();// ......................................................................................................");
- Block *b33 = new Block("print(33); state = check();// ....");
- Block *b34 = new Block("print(34); state = check();// ..........................................................................................................................................");
- Block *b35 = new Block("print(35); state = check();// .................................");
- Block *b36 = new Block("print(36); state = check();// .........................");
- Block *b37 = new Block("print(37); state = check();// ................................................................................................................................");
- Block *b38 = new Block("print(38); state = check();// ............................................................................................................................................................................................................................................................................................................................................");
- Block *b39 = new Block("print(39); state = check();// ................");
- Block *b40 = new Block("print(40); state = check();// ................................................................................................................................................");
- Block *b41 = new Block("print(41); state = check();// ...................................................................................................................................");
- Block *b42 = new Block("print(42); state = check();// .....................................................");
- Block *b43 = new Block("print(43); state = check();// .........");
- Block *b44 = new Block("print(44); state = check();// .....................................................................................................................................................");
- Block *b45 = new Block("print(45); state = check();// ............................");
- Block *b46 = new Block("print(46); state = check();// .............................................................................");
- Block *b47 = new Block("print(47); state = check();// ....................................................................................................................................");
- Block *b48 = new Block("print(48); state = check();// ............");
- Block *b49 = new Block("print(49); state = check();// ............................................................................................................................................................................................................................................................................................");
- Block *b50 = new Block("print(50); state = check();// ........................................");
- Block *b51 = new Block("print(51); state = check();// .............................................................................................");
- Block *b52 = new Block("print(52); state = check();// ..............................................................................");
- Block *b53 = new Block("print(53); state = check();// ..............................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................");
- Block *b54 = new Block("print(54); state = check();// .....................................");
- Block *b55 = new Block("print(55); state = check();// ...........................................................................................................................................................................................................");
- Block *b56 = new Block("print(56); state = check();// ....................................................................................................................................................................................................................");
- Block *b57 = new Block("print(57); state = check();// ...........................................................................................................................................................................................................................................................................................................................");
- Block *b58 = new Block("print(58); state = check();// ......................................................................................");
- Block *b59 = new Block("print(59); state = check();// ...................................");
- Block *b60 = new Block("print(60); state = check();// ......................................................................................................................................................................................................................................");
- Block *b61 = new Block("print(61); state = check();// .........................................................................................................................................................");
- Block *b62 = new Block("print(62); state = check();// .......................................................................................");
- Block *b63 = new Block("print(63); state = check();// .....................................................................................................................................................................");
- Block *b64 = new Block("print(64); state = check();// .......................................................................................................................................................................................................................................................................");
- Block *b65 = new Block("print(65); state = check();// .........................................................");
- Block *b66 = new Block("print(66); state = check();// ...............................................................................................................");
- Block *b67 = new Block("print(67); state = check();// .....................................................................................................................................................................................................................");
- Block *b68 = new Block("print(68); state = check();// ......................................................................................................................................................................................................................................................................................................................");
- Block *b69 = new Block("print(69); state = check();// ......................................................................................................................................................");
- Block *b70 = new Block("print(70); state = check();// ..........................................................................................................................");
- Block *b71 = new Block("print(71); state = check();// ...........................................................................................................................................................................................................");
- Block *b72 = new Block("print(72); state = check();// ..........................................................................................................");
- Block *b73 = new Block("print(73); state = check();// .");
- Block *b74 = new Block("print(74); state = check();// ..............................................");
- Block *b75 = new Block("print(75); state = check();// .............................................");
- Block *b76 = new Block("print(76); state = check();// ..............................................................................................................................................................................................................................................................................................................................................................................................................................");
- Block *b77 = new Block("print(77); state = check();// ...........................................................................................................................................................................................................................................................................................");
- Block *b78 = new Block("print(78); state = check();// ..........................................................................................");
- Block *b79 = new Block("print(79); state = check();// ...................................................................................................................................................................................................................................................");
- Block *b80 = new Block("print(80); state = check();// ....................................");
- Block *b81 = new Block("print(81); state = check();// ................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................");
- Block *b82 = new Block("print(82); state = check();// ....................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................");
- Block *b83 = new Block("print(83); state = check();// ........................................................................................");
- Block *b84 = new Block("print(84); state = check();// ...................");
- Block *b85 = new Block("print(85); state = check();// .........................................................................................................................................................................................................................................................................................................................................................");
- Block *b86 = new Block("print(86); state = check();// .................................................................................................................................................................................................................................................");
- Block *b87 = new Block("print(87); state = check();// ......");
- Block *b88 = new Block("print(88); state = check();// ....................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................");
- Block *b89 = new Block("print(89); state = check();// ......................................................................................................................................................................................................................................................................................................................................................");
- Block *b90 = new Block("print(90); state = check();// ...........................................................................................................................................................................................................................");
- Block *b91 = new Block("print(91); state = check();// ..............................................");
+ Block *b0 = new Block("print('entry'); var label; var state; var decisions = [759, 1223, 618, 1805, 277, 512, 204, 1545, 606, 734, 585, 447, 1670, 1031, 665, 1728, 353, 634, 1033, 13, 658, 589, 474, 854, 405, 1111, 1640, 697, 1156, 1357, 317, 618, 990, 1401, 405, 564, 497, 829, 653, 1194, 25, 322, 1178, 198, 1565, 1419, 1608, 486, 368, 606, 813, 22, 148, 141, 261, 375, 472, 964, 1106, 694, 205, 771, 44, 675, 545, 1027, 1528, 240, 1289, 564, 792, 744, 366, 668, 823, 210, 428, 1009, 1662, 1317, 1183, 681, 14, 1334, 712, 506, 224, 695, 401, 1035, 384, 486, 1519, 122, 1186, 1487, 1819, 1702, 463, 1706, 660, 1642, 847, 991, 976, 940, 867, 46, 23, 1449, 56, 1711, 634, 404, 1558, 168, 710, 1581, 1302, 870, 997, 1295, 1739, 769, 1005, 291, 1638, 1771, 842, 659, 1695, 713, 935, 802, 1173, 1572, 850, 607, 996, 55, 1576, 321, 1815, 662, 1044, 1612, 1680, 1050, 844, 553, 278, 1447, 1662, 1094, 1797, 774, 1013, 1204, 907, 340, 1172, 1460, 869, 1264, 111, 1176, 484, 845, 258, 417, 1246, 1017, 745, 189, 333, 1658, 1395, 1764, 1786, 165, 404, 847, 1429, 1574, 403, 718, 1118, 1756, 94, 56, 1498, 1696, 1355, 840, 50, 82, 371, 1087, 875, 1337, 267, 958, 1209, 1167, 1025, 1684, 184, 962, 1496, 201, 127, 372, 1, 1005, 402, 1387, 213, 1143, 1271, 167, 10, 12, 1060, 1390, 1366, 893, 747, 1005, 481, 876, 227, 514, 589, 250, 273, 1188, 1052, 719, 219, 1006, 38, 120, 1454, 489, 672, 149, 534, 1081, 1721, 586, 330, 25, 356, 1743, 1607, 336, 981, 419, 1036, 1293, 1026, 1300, 1453, 792, 22, 45, 420, 409, 1027, 1437, 1421, 795, 136, 1276, 1610, 1593]; var index = 0; function check() { if (index == decisions.length) throw 'HALT'; return decisions[index++] }", "the_var");
+ Block *b1 = new Block("print(1); state = check();// ...........................................................................", "the_var");
+ Block *b2 = new Block("print(2); state = check();// .........", "the_var");
+ Block *b3 = new Block("print(3); state = check();// ..................................", "the_var");
+ Block *b4 = new Block("print(4); state = check();// ...........................................................................................................................", "the_var");
+ Block *b5 = new Block("print(5); state = check();// ..........................................................................................................................................", "the_var");
+ Block *b6 = new Block("print(6); state = check();// .........", "the_var");
+ Block *b7 = new Block("print(7); state = check();// .............................................................................................................................................................................................", "the_var");
+ Block *b8 = new Block("print(8); state = check();// ....................................................................................................................................................................................................................................................", "the_var");
+ Block *b9 = new Block("print(9); state = check();// ...................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", "the_var");
+ Block *b10 = new Block("print(10); state = check();// ...................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", "the_var");
+ Block *b11 = new Block("print(11); state = check();// ........................................................", "the_var");
+ Block *b12 = new Block("print(12); state = check();// ................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", "the_var");
+ Block *b13 = new Block("print(13); state = check();// ...................", "the_var");
+ Block *b14 = new Block("print(14); state = check();// .............................", "the_var");
+ Block *b15 = new Block("print(15); state = check();// ..................................................", "the_var");
+ Block *b16 = new Block("print(16); state = check();// ................................................................................................................................................................................................................................................................................................................................................................", "the_var");
+ Block *b17 = new Block("print(17); state = check();// ................................................................", "the_var");
+ Block *b18 = new Block("print(18); state = check();// ..............................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", "the_var");
+ Block *b19 = new Block("print(19); state = check();// ......................................................................................................................................................................................................................", "the_var");
+ Block *b20 = new Block("print(20); state = check();// ..................................................................................................................................................................", "the_var");
+ Block *b21 = new Block("print(21); state = check();// ...........................", "the_var");
+ Block *b22 = new Block("print(22); state = check();// .........................................................................................................", "the_var");
+ Block *b23 = new Block("print(23); state = check();// .................................................................................................................................................................................................................", "the_var");
+ Block *b24 = new Block("print(24); state = check();// ...........................", "the_var");
+ Block *b25 = new Block("print(25); state = check();// ......................................................................................................................................................", "the_var");
+ Block *b26 = new Block("print(26); state = check();// .........................................................................................................................................................................................................................................................................", "the_var");
+ Block *b27 = new Block("print(27); state = check();// .............................................................................................................................................................................", "the_var");
+ Block *b28 = new Block("print(28); state = check();// ..............................................................................................................", "the_var");
+ Block *b29 = new Block("print(29); state = check();// ...............", "the_var");
+ Block *b30 = new Block("print(30); state = check();// .................................................................................................................................................................................................................", "the_var");
+ Block *b31 = new Block("print(31); state = check();// ..........................................................................................................................................................................................................", "the_var");
+ Block *b32 = new Block("print(32); state = check();// ......................................................................................................", "the_var");
+ Block *b33 = new Block("print(33); state = check();// ....", "the_var");
+ Block *b34 = new Block("print(34); state = check();// ..........................................................................................................................................", "the_var");
+ Block *b35 = new Block("print(35); state = check();// .................................", "the_var");
+ Block *b36 = new Block("print(36); state = check();// .........................", "the_var");
+ Block *b37 = new Block("print(37); state = check();// ................................................................................................................................", "the_var");
+ Block *b38 = new Block("print(38); state = check();// ............................................................................................................................................................................................................................................................................................................................................", "the_var");
+ Block *b39 = new Block("print(39); state = check();// ................", "the_var");
+ Block *b40 = new Block("print(40); state = check();// ................................................................................................................................................", "the_var");
+ Block *b41 = new Block("print(41); state = check();// ...................................................................................................................................", "the_var");
+ Block *b42 = new Block("print(42); state = check();// .....................................................", "the_var");
+ Block *b43 = new Block("print(43); state = check();// .........", "the_var");
+ Block *b44 = new Block("print(44); state = check();// .....................................................................................................................................................", "the_var");
+ Block *b45 = new Block("print(45); state = check();// ............................", "the_var");
+ Block *b46 = new Block("print(46); state = check();// .............................................................................", "the_var");
+ Block *b47 = new Block("print(47); state = check();// ....................................................................................................................................", "the_var");
+ Block *b48 = new Block("print(48); state = check();// ............", "the_var");
+ Block *b49 = new Block("print(49); state = check();// ............................................................................................................................................................................................................................................................................................", "the_var");
+ Block *b50 = new Block("print(50); state = check();// ........................................", "the_var");
+ Block *b51 = new Block("print(51); state = check();// .............................................................................................", "the_var");
+ Block *b52 = new Block("print(52); state = check();// ..............................................................................", "the_var");
+ Block *b53 = new Block("print(53); state = check();// ..............................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", "the_var");
+ Block *b54 = new Block("print(54); state = check();// .....................................", "the_var");
+ Block *b55 = new Block("print(55); state = check();// ...........................................................................................................................................................................................................", "the_var");
+ Block *b56 = new Block("print(56); state = check();// ....................................................................................................................................................................................................................", "the_var");
+ Block *b57 = new Block("print(57); state = check();// ...........................................................................................................................................................................................................................................................................................................................", "the_var");
+ Block *b58 = new Block("print(58); state = check();// ......................................................................................", "the_var");
+ Block *b59 = new Block("print(59); state = check();// ...................................", "the_var");
+ Block *b60 = new Block("print(60); state = check();// ......................................................................................................................................................................................................................................", "the_var");
+ Block *b61 = new Block("print(61); state = check();// .........................................................................................................................................................", "the_var");
+ Block *b62 = new Block("print(62); state = check();// .......................................................................................", "the_var");
+ Block *b63 = new Block("print(63); state = check();// .....................................................................................................................................................................", "the_var");
+ Block *b64 = new Block("print(64); state = check();// .......................................................................................................................................................................................................................................................................", "the_var");
+ Block *b65 = new Block("print(65); state = check();// .........................................................", "the_var");
+ Block *b66 = new Block("print(66); state = check();// ...............................................................................................................", "the_var");
+ Block *b67 = new Block("print(67); state = check();// .....................................................................................................................................................................................................................", "the_var");
+ Block *b68 = new Block("print(68); state = check();// ......................................................................................................................................................................................................................................................................................................................", "the_var");
+ Block *b69 = new Block("print(69); state = check();// ......................................................................................................................................................", "the_var");
+ Block *b70 = new Block("print(70); state = check();// ..........................................................................................................................", "the_var");
+ Block *b71 = new Block("print(71); state = check();// ...........................................................................................................................................................................................................", "the_var");
+ Block *b72 = new Block("print(72); state = check();// ..........................................................................................................", "the_var");
+ Block *b73 = new Block("print(73); state = check();// .", "the_var");
+ Block *b74 = new Block("print(74); state = check();// ..............................................", "the_var");
+ Block *b75 = new Block("print(75); state = check();// .............................................", "the_var");
+ Block *b76 = new Block("print(76); state = check();// ..............................................................................................................................................................................................................................................................................................................................................................................................................................", "the_var");
+ Block *b77 = new Block("print(77); state = check();// ...........................................................................................................................................................................................................................................................................................", "the_var");
+ Block *b78 = new Block("print(78); state = check();// ..........................................................................................", "the_var");
+ Block *b79 = new Block("print(79); state = check();// ...................................................................................................................................................................................................................................................", "the_var");
+ Block *b80 = new Block("print(80); state = check();// ....................................", "the_var");
+ Block *b81 = new Block("print(81); state = check();// ................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", "the_var");
+ Block *b82 = new Block("print(82); state = check();// ....................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", "the_var");
+ Block *b83 = new Block("print(83); state = check();// ........................................................................................", "the_var");
+ Block *b84 = new Block("print(84); state = check();// ...................", "the_var");
+ Block *b85 = new Block("print(85); state = check();// .........................................................................................................................................................................................................................................................................................................................................................", "the_var");
+ Block *b86 = new Block("print(86); state = check();// .................................................................................................................................................................................................................................................", "the_var");
+ Block *b87 = new Block("print(87); state = check();// ......", "the_var");
+ Block *b88 = new Block("print(88); state = check();// ....................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", "the_var");
+ Block *b89 = new Block("print(89); state = check();// ......................................................................................................................................................................................................................................................................................................................................................", "the_var");
+ Block *b90 = new Block("print(90); state = check();// ...........................................................................................................................................................................................................................", "the_var");
+ Block *b91 = new Block("print(91); state = check();// ..............................................", "the_var");
b0->AddBranchTo(b30, NULL);
b1->AddBranchTo(b66, NULL);
b2->AddBranchTo(b51, NULL);
diff --git a/src/relooper/test_fuzz6.txt b/src/relooper/test_fuzz6.txt
index cd93958c..b9c1499a 100644
--- a/src/relooper/test_fuzz6.txt
+++ b/src/relooper/test_fuzz6.txt
@@ -1,108 +1,291 @@
print('entry'); var label; var state; var decisions = [759, 1223, 618, 1805, 277, 512, 204, 1545, 606, 734, 585, 447, 1670, 1031, 665, 1728, 353, 634, 1033, 13, 658, 589, 474, 854, 405, 1111, 1640, 697, 1156, 1357, 317, 618, 990, 1401, 405, 564, 497, 829, 653, 1194, 25, 322, 1178, 198, 1565, 1419, 1608, 486, 368, 606, 813, 22, 148, 141, 261, 375, 472, 964, 1106, 694, 205, 771, 44, 675, 545, 1027, 1528, 240, 1289, 564, 792, 744, 366, 668, 823, 210, 428, 1009, 1662, 1317, 1183, 681, 14, 1334, 712, 506, 224, 695, 401, 1035, 384, 486, 1519, 122, 1186, 1487, 1819, 1702, 463, 1706, 660, 1642, 847, 991, 976, 940, 867, 46, 23, 1449, 56, 1711, 634, 404, 1558, 168, 710, 1581, 1302, 870, 997, 1295, 1739, 769, 1005, 291, 1638, 1771, 842, 659, 1695, 713, 935, 802, 1173, 1572, 850, 607, 996, 55, 1576, 321, 1815, 662, 1044, 1612, 1680, 1050, 844, 553, 278, 1447, 1662, 1094, 1797, 774, 1013, 1204, 907, 340, 1172, 1460, 869, 1264, 111, 1176, 484, 845, 258, 417, 1246, 1017, 745, 189, 333, 1658, 1395, 1764, 1786, 165, 404, 847, 1429, 1574, 403, 718, 1118, 1756, 94, 56, 1498, 1696, 1355, 840, 50, 82, 371, 1087, 875, 1337, 267, 958, 1209, 1167, 1025, 1684, 184, 962, 1496, 201, 127, 372, 1, 1005, 402, 1387, 213, 1143, 1271, 167, 10, 12, 1060, 1390, 1366, 893, 747, 1005, 481, 876, 227, 514, 589, 250, 273, 1188, 1052, 719, 219, 1006, 38, 120, 1454, 489, 672, 149, 534, 1081, 1721, 586, 330, 25, 356, 1743, 1607, 336, 981, 419, 1036, 1293, 1026, 1300, 1453, 792, 22, 45, 420, 409, 1027, 1437, 1421, 795, 136, 1276, 1610, 1593]; var index = 0; function check() { if (index == decisions.length) throw 'HALT'; return decisions[index++] }
-while(1) {
+switch (the_var) {
+default: {
+}
+}
+L1: while(1) {
print(30); state = check();// .................................................................................................................................................................................................................
- if (state % 3 == 1) {
- label = 67;
+ switch (the_var) {
+ state % 3 == 0 {
break;
- } else if (!(state % 3 == 0)) {
+ }
+ state % 3 == 1 {
+ label = 67;
+ break L1;
break;
}
+ default: {
+ break L1;
+ }
+ }
print(58); state = check();// ......................................................................................
+ switch (the_var) {
+ default: {
+ }
+ }
}
if (label == 67) {
print(66); state = check();// ...............................................................................................................
+ switch (the_var) {
+ default: {
+ }
+ }
}
print(6); state = check();// .........
+switch (the_var) {
+default: {
+}
+}
while(1) {
print(88); state = check();// ....................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................
+ switch (the_var) {
+ default: {
+ }
+ }
print(70); state = check();// ..........................................................................................................................
+ switch (the_var) {
+ default: {
+ }
+ }
L10: while(1) {
print(47); state = check();// ....................................................................................................................................
+ switch (the_var) {
+ default: {
+ }
+ }
print(28); state = check();// ..............................................................................................................
- while(1) {
+ switch (the_var) {
+ default: {
+ }
+ }
+ L13: while(1) {
print(75); state = check();// .............................................
+ switch (the_var) {
+ default: {
+ }
+ }
print(7); state = check();// .............................................................................................................................................................................................
- if (!(state % 2 == 0)) {
+ switch (the_var) {
+ state % 2 == 0 {
break;
}
+ default: {
+ break L13;
+ }
+ }
}
print(89); state = check();// ......................................................................................................................................................................................................................................................................................................................................................
+ switch (the_var) {
+ default: {
+ }
+ }
print(68); state = check();// ......................................................................................................................................................................................................................................................................................................................
+ switch (the_var) {
+ default: {
+ }
+ }
L18: while(1) {
print(51); state = check();// .............................................................................................
+ switch (the_var) {
+ default: {
+ }
+ }
L20: while(1) {
print(36); state = check();// .........................
- if (state % 2 == 0) {
+ switch (the_var) {
+ state % 2 == 0 {
+ break L20;
break;
}
+ default: {
+ }
+ }
print(16); state = check();// ................................................................................................................................................................................................................................................................................................................................................................
+ switch (the_var) {
+ default: {
+ }
+ }
print(57); state = check();// ...........................................................................................................................................................................................................................................................................................................................
+ switch (the_var) {
+ default: {
+ }
+ }
print(39); state = check();// ................
- if (state % 3 == 1) {
+ switch (the_var) {
+ state % 3 == 0 {
+ break;
+ }
+ state % 3 == 1 {
label = 74;
- } else if (!(state % 3 == 0)) {
- label = 32;
break;
}
- while(1) {
+ default: {
+ label = 32;
+ break L20;
+ }
+ }
+ L25: while(1) {
if (label == 74) {
label = 0;
print(73); state = check();// .
- if (state % 3 == 1) {
+ switch (the_var) {
+ state % 3 == 1 {
label = 32;
break L20;
- } else if (state % 3 == 0) {
break;
}
+ state % 3 == 0 {
+ break L25;
+ break;
+ }
+ default: {
+ }
+ }
print(43); state = check();// .........
+ switch (the_var) {
+ default: {
+ }
+ }
print(32); state = check();// ......................................................................................................
+ switch (the_var) {
+ default: {
+ }
+ }
print(83); state = check();// ........................................................................................
+ switch (the_var) {
+ default: {
+ }
+ }
print(77); state = check();// ...........................................................................................................................................................................................................................................................................................
+ switch (the_var) {
+ default: {
+ }
+ }
print(76); state = check();// ..............................................................................................................................................................................................................................................................................................................................................................................................................................
+ switch (the_var) {
+ default: {
+ }
+ }
print(22); state = check();// .........................................................................................................
+ switch (the_var) {
+ default: {
+ }
+ }
}
print(72); state = check();// ..........................................................................................................
- if (state % 2 == 0) {
+ switch (the_var) {
+ state % 2 == 0 {
label = 92;
break L20;
+ break;
+ }
+ default: {
+ }
}
print(80); state = check();// ....................................
- if (state % 2 == 0) {
+ switch (the_var) {
+ state % 2 == 0 {
continue L18;
+ break;
+ }
+ default: {
+ }
}
print(50); state = check();// ........................................
+ switch (the_var) {
+ default: {
+ }
+ }
print(29); state = check();// ...............
+ switch (the_var) {
+ default: {
+ }
+ }
print(8); state = check();// ....................................................................................................................................................................................................................................................
- if (state % 2 == 0) {
+ switch (the_var) {
+ state % 2 == 0 {
continue L10;
+ break;
+ }
+ default: {
+ }
}
print(19); state = check();// ......................................................................................................................................................................................................................
+ switch (the_var) {
+ default: {
+ }
+ }
print(56); state = check();// ....................................................................................................................................................................................................................
+ switch (the_var) {
+ default: {
+ }
+ }
print(34); state = check();// ..........................................................................................................................................
- label = 74;
+ switch (the_var) {
+ default: {
+ label = 74;
+ }
+ }
}
print(62); state = check();// .......................................................................................
+ switch (the_var) {
+ default: {
+ }
+ }
}
if (label == 32) {
label = 0;
print(31); state = check();// ..........................................................................................................................................................................................................
+ switch (the_var) {
+ default: {
+ }
+ }
}
else if (label == 92) {
label = 0;
print(91); state = check();// ..............................................
+ switch (the_var) {
+ default: {
+ }
+ }
print(33); state = check();// ....
+ switch (the_var) {
+ default: {
+ }
+ }
}
print(60); state = check();// ......................................................................................................................................................................................................................................
+ switch (the_var) {
+ default: {
+ }
+ }
print(10); state = check();// ...................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................
+ switch (the_var) {
+ default: {
+ }
+ }
print(52); state = check();// ..............................................................................
- if (state % 2 == 0) {
+ switch (the_var) {
+ state % 2 == 0 {
break L10;
+ break;
+ }
+ default: {
+ }
}
print(2); state = check();// .........
+ switch (the_var) {
+ default: {
+ }
+ }
}
}
print(61); state = check();// .........................................................................................................................................................
+ switch (the_var) {
+ default: {
+ }
+ }
}
diff --git a/src/relooper/test_inf.cpp b/src/relooper/test_inf.cpp
index 66e712ed..1363bf4b 100644
--- a/src/relooper/test_inf.cpp
+++ b/src/relooper/test_inf.cpp
@@ -4,556 +4,556 @@ int main() {
void *rl = rl_new_relooper();
char buffer[100000];
rl_set_output_buffer(buffer, sizeof(buffer));
- void *b0 = rl_new_block("code 0");
+ void *b0 = rl_new_block("code 0", "the_var");
block_map[0] = b0;
rl_relooper_add_block(rl, block_map[0]);
- void *b1 = rl_new_block("code 1");
+ void *b1 = rl_new_block("code 1", "the_var");
block_map[1] = b1;
rl_relooper_add_block(rl, block_map[1]);
- void *b2 = rl_new_block("code 2");
+ void *b2 = rl_new_block("code 2", "the_var");
block_map[2] = b2;
rl_relooper_add_block(rl, block_map[2]);
- void *b3 = rl_new_block("code 3");
+ void *b3 = rl_new_block("code 3", "the_var");
block_map[3] = b3;
rl_relooper_add_block(rl, block_map[3]);
- void *b4 = rl_new_block("code 4");
+ void *b4 = rl_new_block("code 4", "the_var");
block_map[4] = b4;
rl_relooper_add_block(rl, block_map[4]);
- void *b5 = rl_new_block("code 5");
+ void *b5 = rl_new_block("code 5", "the_var");
block_map[5] = b5;
rl_relooper_add_block(rl, block_map[5]);
- void *b6 = rl_new_block("code 6");
+ void *b6 = rl_new_block("code 6", "the_var");
block_map[6] = b6;
rl_relooper_add_block(rl, block_map[6]);
- void *b7 = rl_new_block("code 7");
+ void *b7 = rl_new_block("code 7", "the_var");
block_map[7] = b7;
rl_relooper_add_block(rl, block_map[7]);
- void *b8 = rl_new_block("code 8");
+ void *b8 = rl_new_block("code 8", "the_var");
block_map[8] = b8;
rl_relooper_add_block(rl, block_map[8]);
- void *b9 = rl_new_block("code 9");
+ void *b9 = rl_new_block("code 9", "the_var");
block_map[9] = b9;
rl_relooper_add_block(rl, block_map[9]);
- void *b10 = rl_new_block("code 10");
+ void *b10 = rl_new_block("code 10", "the_var");
block_map[10] = b10;
rl_relooper_add_block(rl, block_map[10]);
- void *b11 = rl_new_block("code 11");
+ void *b11 = rl_new_block("code 11", "the_var");
block_map[11] = b11;
rl_relooper_add_block(rl, block_map[11]);
- void *b12 = rl_new_block("code 12");
+ void *b12 = rl_new_block("code 12", "the_var");
block_map[12] = b12;
rl_relooper_add_block(rl, block_map[12]);
- void *b13 = rl_new_block("code 13");
+ void *b13 = rl_new_block("code 13", "the_var");
block_map[13] = b13;
rl_relooper_add_block(rl, block_map[13]);
- void *b14 = rl_new_block("code 14");
+ void *b14 = rl_new_block("code 14", "the_var");
block_map[14] = b14;
rl_relooper_add_block(rl, block_map[14]);
- void *b15 = rl_new_block("code 15");
+ void *b15 = rl_new_block("code 15", "the_var");
block_map[15] = b15;
rl_relooper_add_block(rl, block_map[15]);
- void *b16 = rl_new_block("code 16");
+ void *b16 = rl_new_block("code 16", "the_var");
block_map[16] = b16;
rl_relooper_add_block(rl, block_map[16]);
- void *b17 = rl_new_block("code 17");
+ void *b17 = rl_new_block("code 17", "the_var");
block_map[17] = b17;
rl_relooper_add_block(rl, block_map[17]);
- void *b18 = rl_new_block("code 18");
+ void *b18 = rl_new_block("code 18", "the_var");
block_map[18] = b18;
rl_relooper_add_block(rl, block_map[18]);
- void *b19 = rl_new_block("code 19");
+ void *b19 = rl_new_block("code 19", "the_var");
block_map[19] = b19;
rl_relooper_add_block(rl, block_map[19]);
- void *b20 = rl_new_block("code 20");
+ void *b20 = rl_new_block("code 20", "the_var");
block_map[20] = b20;
rl_relooper_add_block(rl, block_map[20]);
- void *b21 = rl_new_block("code 21");
+ void *b21 = rl_new_block("code 21", "the_var");
block_map[21] = b21;
rl_relooper_add_block(rl, block_map[21]);
- void *b22 = rl_new_block("code 22");
+ void *b22 = rl_new_block("code 22", "the_var");
block_map[22] = b22;
rl_relooper_add_block(rl, block_map[22]);
- void *b23 = rl_new_block("code 23");
+ void *b23 = rl_new_block("code 23", "the_var");
block_map[23] = b23;
rl_relooper_add_block(rl, block_map[23]);
- void *b24 = rl_new_block("code 24");
+ void *b24 = rl_new_block("code 24", "the_var");
block_map[24] = b24;
rl_relooper_add_block(rl, block_map[24]);
- void *b25 = rl_new_block("code 25");
+ void *b25 = rl_new_block("code 25", "the_var");
block_map[25] = b25;
rl_relooper_add_block(rl, block_map[25]);
- void *b26 = rl_new_block("code 26");
+ void *b26 = rl_new_block("code 26", "the_var");
block_map[26] = b26;
rl_relooper_add_block(rl, block_map[26]);
- void *b27 = rl_new_block("code 27");
+ void *b27 = rl_new_block("code 27", "the_var");
block_map[27] = b27;
rl_relooper_add_block(rl, block_map[27]);
- void *b28 = rl_new_block("code 28");
+ void *b28 = rl_new_block("code 28", "the_var");
block_map[28] = b28;
rl_relooper_add_block(rl, block_map[28]);
- void *b29 = rl_new_block("code 29");
+ void *b29 = rl_new_block("code 29", "the_var");
block_map[29] = b29;
rl_relooper_add_block(rl, block_map[29]);
- void *b30 = rl_new_block("code 30");
+ void *b30 = rl_new_block("code 30", "the_var");
block_map[30] = b30;
rl_relooper_add_block(rl, block_map[30]);
- void *b31 = rl_new_block("code 31");
+ void *b31 = rl_new_block("code 31", "the_var");
block_map[31] = b31;
rl_relooper_add_block(rl, block_map[31]);
- void *b32 = rl_new_block("code 32");
+ void *b32 = rl_new_block("code 32", "the_var");
block_map[32] = b32;
rl_relooper_add_block(rl, block_map[32]);
- void *b33 = rl_new_block("code 33");
+ void *b33 = rl_new_block("code 33", "the_var");
block_map[33] = b33;
rl_relooper_add_block(rl, block_map[33]);
- void *b34 = rl_new_block("code 34");
+ void *b34 = rl_new_block("code 34", "the_var");
block_map[34] = b34;
rl_relooper_add_block(rl, block_map[34]);
- void *b35 = rl_new_block("code 35");
+ void *b35 = rl_new_block("code 35", "the_var");
block_map[35] = b35;
rl_relooper_add_block(rl, block_map[35]);
- void *b36 = rl_new_block("code 36");
+ void *b36 = rl_new_block("code 36", "the_var");
block_map[36] = b36;
rl_relooper_add_block(rl, block_map[36]);
- void *b37 = rl_new_block("code 37");
+ void *b37 = rl_new_block("code 37", "the_var");
block_map[37] = b37;
rl_relooper_add_block(rl, block_map[37]);
- void *b38 = rl_new_block("code 38");
+ void *b38 = rl_new_block("code 38", "the_var");
block_map[38] = b38;
rl_relooper_add_block(rl, block_map[38]);
- void *b39 = rl_new_block("code 39");
+ void *b39 = rl_new_block("code 39", "the_var");
block_map[39] = b39;
rl_relooper_add_block(rl, block_map[39]);
- void *b40 = rl_new_block("code 40");
+ void *b40 = rl_new_block("code 40", "the_var");
block_map[40] = b40;
rl_relooper_add_block(rl, block_map[40]);
- void *b41 = rl_new_block("code 41");
+ void *b41 = rl_new_block("code 41", "the_var");
block_map[41] = b41;
rl_relooper_add_block(rl, block_map[41]);
- void *b42 = rl_new_block("code 42");
+ void *b42 = rl_new_block("code 42", "the_var");
block_map[42] = b42;
rl_relooper_add_block(rl, block_map[42]);
- void *b43 = rl_new_block("code 43");
+ void *b43 = rl_new_block("code 43", "the_var");
block_map[43] = b43;
rl_relooper_add_block(rl, block_map[43]);
- void *b44 = rl_new_block("code 44");
+ void *b44 = rl_new_block("code 44", "the_var");
block_map[44] = b44;
rl_relooper_add_block(rl, block_map[44]);
- void *b45 = rl_new_block("code 45");
+ void *b45 = rl_new_block("code 45", "the_var");
block_map[45] = b45;
rl_relooper_add_block(rl, block_map[45]);
- void *b46 = rl_new_block("code 46");
+ void *b46 = rl_new_block("code 46", "the_var");
block_map[46] = b46;
rl_relooper_add_block(rl, block_map[46]);
- void *b47 = rl_new_block("code 47");
+ void *b47 = rl_new_block("code 47", "the_var");
block_map[47] = b47;
rl_relooper_add_block(rl, block_map[47]);
- void *b48 = rl_new_block("code 48");
+ void *b48 = rl_new_block("code 48", "the_var");
block_map[48] = b48;
rl_relooper_add_block(rl, block_map[48]);
- void *b49 = rl_new_block("code 49");
+ void *b49 = rl_new_block("code 49", "the_var");
block_map[49] = b49;
rl_relooper_add_block(rl, block_map[49]);
- void *b50 = rl_new_block("code 50");
+ void *b50 = rl_new_block("code 50", "the_var");
block_map[50] = b50;
rl_relooper_add_block(rl, block_map[50]);
- void *b51 = rl_new_block("code 51");
+ void *b51 = rl_new_block("code 51", "the_var");
block_map[51] = b51;
rl_relooper_add_block(rl, block_map[51]);
- void *b52 = rl_new_block("code 52");
+ void *b52 = rl_new_block("code 52", "the_var");
block_map[52] = b52;
rl_relooper_add_block(rl, block_map[52]);
- void *b53 = rl_new_block("code 53");
+ void *b53 = rl_new_block("code 53", "the_var");
block_map[53] = b53;
rl_relooper_add_block(rl, block_map[53]);
- void *b54 = rl_new_block("code 54");
+ void *b54 = rl_new_block("code 54", "the_var");
block_map[54] = b54;
rl_relooper_add_block(rl, block_map[54]);
- void *b55 = rl_new_block("code 55");
+ void *b55 = rl_new_block("code 55", "the_var");
block_map[55] = b55;
rl_relooper_add_block(rl, block_map[55]);
- void *b56 = rl_new_block("code 56");
+ void *b56 = rl_new_block("code 56", "the_var");
block_map[56] = b56;
rl_relooper_add_block(rl, block_map[56]);
- void *b57 = rl_new_block("code 57");
+ void *b57 = rl_new_block("code 57", "the_var");
block_map[57] = b57;
rl_relooper_add_block(rl, block_map[57]);
- void *b58 = rl_new_block("code 58");
+ void *b58 = rl_new_block("code 58", "the_var");
block_map[58] = b58;
rl_relooper_add_block(rl, block_map[58]);
- void *b59 = rl_new_block("code 59");
+ void *b59 = rl_new_block("code 59", "the_var");
block_map[59] = b59;
rl_relooper_add_block(rl, block_map[59]);
- void *b60 = rl_new_block("code 60");
+ void *b60 = rl_new_block("code 60", "the_var");
block_map[60] = b60;
rl_relooper_add_block(rl, block_map[60]);
- void *b61 = rl_new_block("code 61");
+ void *b61 = rl_new_block("code 61", "the_var");
block_map[61] = b61;
rl_relooper_add_block(rl, block_map[61]);
- void *b62 = rl_new_block("code 62");
+ void *b62 = rl_new_block("code 62", "the_var");
block_map[62] = b62;
rl_relooper_add_block(rl, block_map[62]);
- void *b63 = rl_new_block("code 63");
+ void *b63 = rl_new_block("code 63", "the_var");
block_map[63] = b63;
rl_relooper_add_block(rl, block_map[63]);
- void *b64 = rl_new_block("code 64");
+ void *b64 = rl_new_block("code 64", "the_var");
block_map[64] = b64;
rl_relooper_add_block(rl, block_map[64]);
- void *b65 = rl_new_block("code 65");
+ void *b65 = rl_new_block("code 65", "the_var");
block_map[65] = b65;
rl_relooper_add_block(rl, block_map[65]);
- void *b66 = rl_new_block("code 66");
+ void *b66 = rl_new_block("code 66", "the_var");
block_map[66] = b66;
rl_relooper_add_block(rl, block_map[66]);
- void *b67 = rl_new_block("code 67");
+ void *b67 = rl_new_block("code 67", "the_var");
block_map[67] = b67;
rl_relooper_add_block(rl, block_map[67]);
- void *b68 = rl_new_block("code 68");
+ void *b68 = rl_new_block("code 68", "the_var");
block_map[68] = b68;
rl_relooper_add_block(rl, block_map[68]);
- void *b69 = rl_new_block("code 69");
+ void *b69 = rl_new_block("code 69", "the_var");
block_map[69] = b69;
rl_relooper_add_block(rl, block_map[69]);
- void *b70 = rl_new_block("code 70");
+ void *b70 = rl_new_block("code 70", "the_var");
block_map[70] = b70;
rl_relooper_add_block(rl, block_map[70]);
- void *b71 = rl_new_block("code 71");
+ void *b71 = rl_new_block("code 71", "the_var");
block_map[71] = b71;
rl_relooper_add_block(rl, block_map[71]);
- void *b72 = rl_new_block("code 72");
+ void *b72 = rl_new_block("code 72", "the_var");
block_map[72] = b72;
rl_relooper_add_block(rl, block_map[72]);
- void *b73 = rl_new_block("code 73");
+ void *b73 = rl_new_block("code 73", "the_var");
block_map[73] = b73;
rl_relooper_add_block(rl, block_map[73]);
- void *b74 = rl_new_block("code 74");
+ void *b74 = rl_new_block("code 74", "the_var");
block_map[74] = b74;
rl_relooper_add_block(rl, block_map[74]);
- void *b75 = rl_new_block("code 75");
+ void *b75 = rl_new_block("code 75", "the_var");
block_map[75] = b75;
rl_relooper_add_block(rl, block_map[75]);
- void *b76 = rl_new_block("code 76");
+ void *b76 = rl_new_block("code 76", "the_var");
block_map[76] = b76;
rl_relooper_add_block(rl, block_map[76]);
- void *b77 = rl_new_block("code 77");
+ void *b77 = rl_new_block("code 77", "the_var");
block_map[77] = b77;
rl_relooper_add_block(rl, block_map[77]);
- void *b78 = rl_new_block("code 78");
+ void *b78 = rl_new_block("code 78", "the_var");
block_map[78] = b78;
rl_relooper_add_block(rl, block_map[78]);
- void *b79 = rl_new_block("code 79");
+ void *b79 = rl_new_block("code 79", "the_var");
block_map[79] = b79;
rl_relooper_add_block(rl, block_map[79]);
- void *b80 = rl_new_block("code 80");
+ void *b80 = rl_new_block("code 80", "the_var");
block_map[80] = b80;
rl_relooper_add_block(rl, block_map[80]);
- void *b81 = rl_new_block("code 81");
+ void *b81 = rl_new_block("code 81", "the_var");
block_map[81] = b81;
rl_relooper_add_block(rl, block_map[81]);
- void *b82 = rl_new_block("code 82");
+ void *b82 = rl_new_block("code 82", "the_var");
block_map[82] = b82;
rl_relooper_add_block(rl, block_map[82]);
- void *b83 = rl_new_block("code 83");
+ void *b83 = rl_new_block("code 83", "the_var");
block_map[83] = b83;
rl_relooper_add_block(rl, block_map[83]);
- void *b84 = rl_new_block("code 84");
+ void *b84 = rl_new_block("code 84", "the_var");
block_map[84] = b84;
rl_relooper_add_block(rl, block_map[84]);
- void *b85 = rl_new_block("code 85");
+ void *b85 = rl_new_block("code 85", "the_var");
block_map[85] = b85;
rl_relooper_add_block(rl, block_map[85]);
- void *b86 = rl_new_block("code 86");
+ void *b86 = rl_new_block("code 86", "the_var");
block_map[86] = b86;
rl_relooper_add_block(rl, block_map[86]);
- void *b87 = rl_new_block("code 87");
+ void *b87 = rl_new_block("code 87", "the_var");
block_map[87] = b87;
rl_relooper_add_block(rl, block_map[87]);
- void *b88 = rl_new_block("code 88");
+ void *b88 = rl_new_block("code 88", "the_var");
block_map[88] = b88;
rl_relooper_add_block(rl, block_map[88]);
- void *b89 = rl_new_block("code 89");
+ void *b89 = rl_new_block("code 89", "the_var");
block_map[89] = b89;
rl_relooper_add_block(rl, block_map[89]);
- void *b90 = rl_new_block("code 90");
+ void *b90 = rl_new_block("code 90", "the_var");
block_map[90] = b90;
rl_relooper_add_block(rl, block_map[90]);
- void *b91 = rl_new_block("code 91");
+ void *b91 = rl_new_block("code 91", "the_var");
block_map[91] = b91;
rl_relooper_add_block(rl, block_map[91]);
- void *b92 = rl_new_block("code 92");
+ void *b92 = rl_new_block("code 92", "the_var");
block_map[92] = b92;
rl_relooper_add_block(rl, block_map[92]);
- void *b93 = rl_new_block("code 93");
+ void *b93 = rl_new_block("code 93", "the_var");
block_map[93] = b93;
rl_relooper_add_block(rl, block_map[93]);
- void *b94 = rl_new_block("code 94");
+ void *b94 = rl_new_block("code 94", "the_var");
block_map[94] = b94;
rl_relooper_add_block(rl, block_map[94]);
- void *b95 = rl_new_block("code 95");
+ void *b95 = rl_new_block("code 95", "the_var");
block_map[95] = b95;
rl_relooper_add_block(rl, block_map[95]);
- void *b96 = rl_new_block("code 96");
+ void *b96 = rl_new_block("code 96", "the_var");
block_map[96] = b96;
rl_relooper_add_block(rl, block_map[96]);
- void *b97 = rl_new_block("code 97");
+ void *b97 = rl_new_block("code 97", "the_var");
block_map[97] = b97;
rl_relooper_add_block(rl, block_map[97]);
- void *b98 = rl_new_block("code 98");
+ void *b98 = rl_new_block("code 98", "the_var");
block_map[98] = b98;
rl_relooper_add_block(rl, block_map[98]);
- void *b99 = rl_new_block("code 99");
+ void *b99 = rl_new_block("code 99", "the_var");
block_map[99] = b99;
rl_relooper_add_block(rl, block_map[99]);
- void *b100 = rl_new_block("code 100");
+ void *b100 = rl_new_block("code 100", "the_var");
block_map[100] = b100;
rl_relooper_add_block(rl, block_map[100]);
- void *b101 = rl_new_block("code 101");
+ void *b101 = rl_new_block("code 101", "the_var");
block_map[101] = b101;
rl_relooper_add_block(rl, block_map[101]);
- void *b102 = rl_new_block("code 102");
+ void *b102 = rl_new_block("code 102", "the_var");
block_map[102] = b102;
rl_relooper_add_block(rl, block_map[102]);
- void *b103 = rl_new_block("code 103");
+ void *b103 = rl_new_block("code 103", "the_var");
block_map[103] = b103;
rl_relooper_add_block(rl, block_map[103]);
- void *b104 = rl_new_block("code 104");
+ void *b104 = rl_new_block("code 104", "the_var");
block_map[104] = b104;
rl_relooper_add_block(rl, block_map[104]);
- void *b105 = rl_new_block("code 105");
+ void *b105 = rl_new_block("code 105", "the_var");
block_map[105] = b105;
rl_relooper_add_block(rl, block_map[105]);
- void *b106 = rl_new_block("code 106");
+ void *b106 = rl_new_block("code 106", "the_var");
block_map[106] = b106;
rl_relooper_add_block(rl, block_map[106]);
- void *b107 = rl_new_block("code 107");
+ void *b107 = rl_new_block("code 107", "the_var");
block_map[107] = b107;
rl_relooper_add_block(rl, block_map[107]);
- void *b108 = rl_new_block("code 108");
+ void *b108 = rl_new_block("code 108", "the_var");
block_map[108] = b108;
rl_relooper_add_block(rl, block_map[108]);
- void *b109 = rl_new_block("code 109");
+ void *b109 = rl_new_block("code 109", "the_var");
block_map[109] = b109;
rl_relooper_add_block(rl, block_map[109]);
- void *b110 = rl_new_block("code 110");
+ void *b110 = rl_new_block("code 110", "the_var");
block_map[110] = b110;
rl_relooper_add_block(rl, block_map[110]);
- void *b111 = rl_new_block("code 111");
+ void *b111 = rl_new_block("code 111", "the_var");
block_map[111] = b111;
rl_relooper_add_block(rl, block_map[111]);
- void *b112 = rl_new_block("code 112");
+ void *b112 = rl_new_block("code 112", "the_var");
block_map[112] = b112;
rl_relooper_add_block(rl, block_map[112]);
- void *b113 = rl_new_block("code 113");
+ void *b113 = rl_new_block("code 113", "the_var");
block_map[113] = b113;
rl_relooper_add_block(rl, block_map[113]);
- void *b114 = rl_new_block("code 114");
+ void *b114 = rl_new_block("code 114", "the_var");
block_map[114] = b114;
rl_relooper_add_block(rl, block_map[114]);
- void *b115 = rl_new_block("code 115");
+ void *b115 = rl_new_block("code 115", "the_var");
block_map[115] = b115;
rl_relooper_add_block(rl, block_map[115]);
- void *b116 = rl_new_block("code 116");
+ void *b116 = rl_new_block("code 116", "the_var");
block_map[116] = b116;
rl_relooper_add_block(rl, block_map[116]);
- void *b117 = rl_new_block("code 117");
+ void *b117 = rl_new_block("code 117", "the_var");
block_map[117] = b117;
rl_relooper_add_block(rl, block_map[117]);
- void *b118 = rl_new_block("code 118");
+ void *b118 = rl_new_block("code 118", "the_var");
block_map[118] = b118;
rl_relooper_add_block(rl, block_map[118]);
- void *b119 = rl_new_block("code 119");
+ void *b119 = rl_new_block("code 119", "the_var");
block_map[119] = b119;
rl_relooper_add_block(rl, block_map[119]);
- void *b120 = rl_new_block("code 120");
+ void *b120 = rl_new_block("code 120", "the_var");
block_map[120] = b120;
rl_relooper_add_block(rl, block_map[120]);
- void *b121 = rl_new_block("code 121");
+ void *b121 = rl_new_block("code 121", "the_var");
block_map[121] = b121;
rl_relooper_add_block(rl, block_map[121]);
- void *b122 = rl_new_block("code 122");
+ void *b122 = rl_new_block("code 122", "the_var");
block_map[122] = b122;
rl_relooper_add_block(rl, block_map[122]);
- void *b123 = rl_new_block("code 123");
+ void *b123 = rl_new_block("code 123", "the_var");
block_map[123] = b123;
rl_relooper_add_block(rl, block_map[123]);
- void *b124 = rl_new_block("code 124");
+ void *b124 = rl_new_block("code 124", "the_var");
block_map[124] = b124;
rl_relooper_add_block(rl, block_map[124]);
- void *b125 = rl_new_block("code 125");
+ void *b125 = rl_new_block("code 125", "the_var");
block_map[125] = b125;
rl_relooper_add_block(rl, block_map[125]);
- void *b126 = rl_new_block("code 126");
+ void *b126 = rl_new_block("code 126", "the_var");
block_map[126] = b126;
rl_relooper_add_block(rl, block_map[126]);
- void *b127 = rl_new_block("code 127");
+ void *b127 = rl_new_block("code 127", "the_var");
block_map[127] = b127;
rl_relooper_add_block(rl, block_map[127]);
- void *b128 = rl_new_block("code 128");
+ void *b128 = rl_new_block("code 128", "the_var");
block_map[128] = b128;
rl_relooper_add_block(rl, block_map[128]);
- void *b129 = rl_new_block("code 129");
+ void *b129 = rl_new_block("code 129", "the_var");
block_map[129] = b129;
rl_relooper_add_block(rl, block_map[129]);
- void *b130 = rl_new_block("code 130");
+ void *b130 = rl_new_block("code 130", "the_var");
block_map[130] = b130;
rl_relooper_add_block(rl, block_map[130]);
- void *b131 = rl_new_block("code 131");
+ void *b131 = rl_new_block("code 131", "the_var");
block_map[131] = b131;
rl_relooper_add_block(rl, block_map[131]);
- void *b132 = rl_new_block("code 132");
+ void *b132 = rl_new_block("code 132", "the_var");
block_map[132] = b132;
rl_relooper_add_block(rl, block_map[132]);
- void *b133 = rl_new_block("code 133");
+ void *b133 = rl_new_block("code 133", "the_var");
block_map[133] = b133;
rl_relooper_add_block(rl, block_map[133]);
- void *b134 = rl_new_block("code 134");
+ void *b134 = rl_new_block("code 134", "the_var");
block_map[134] = b134;
rl_relooper_add_block(rl, block_map[134]);
- void *b135 = rl_new_block("code 135");
+ void *b135 = rl_new_block("code 135", "the_var");
block_map[135] = b135;
rl_relooper_add_block(rl, block_map[135]);
- void *b136 = rl_new_block("code 136");
+ void *b136 = rl_new_block("code 136", "the_var");
block_map[136] = b136;
rl_relooper_add_block(rl, block_map[136]);
- void *b137 = rl_new_block("code 137");
+ void *b137 = rl_new_block("code 137", "the_var");
block_map[137] = b137;
rl_relooper_add_block(rl, block_map[137]);
- void *b138 = rl_new_block("code 138");
+ void *b138 = rl_new_block("code 138", "the_var");
block_map[138] = b138;
rl_relooper_add_block(rl, block_map[138]);
- void *b139 = rl_new_block("code 139");
+ void *b139 = rl_new_block("code 139", "the_var");
block_map[139] = b139;
rl_relooper_add_block(rl, block_map[139]);
- void *b140 = rl_new_block("code 140");
+ void *b140 = rl_new_block("code 140", "the_var");
block_map[140] = b140;
rl_relooper_add_block(rl, block_map[140]);
- void *b141 = rl_new_block("code 141");
+ void *b141 = rl_new_block("code 141", "the_var");
block_map[141] = b141;
rl_relooper_add_block(rl, block_map[141]);
- void *b142 = rl_new_block("code 142");
+ void *b142 = rl_new_block("code 142", "the_var");
block_map[142] = b142;
rl_relooper_add_block(rl, block_map[142]);
- void *b143 = rl_new_block("code 143");
+ void *b143 = rl_new_block("code 143", "the_var");
block_map[143] = b143;
rl_relooper_add_block(rl, block_map[143]);
- void *b144 = rl_new_block("code 144");
+ void *b144 = rl_new_block("code 144", "the_var");
block_map[144] = b144;
rl_relooper_add_block(rl, block_map[144]);
- void *b145 = rl_new_block("code 145");
+ void *b145 = rl_new_block("code 145", "the_var");
block_map[145] = b145;
rl_relooper_add_block(rl, block_map[145]);
- void *b146 = rl_new_block("code 146");
+ void *b146 = rl_new_block("code 146", "the_var");
block_map[146] = b146;
rl_relooper_add_block(rl, block_map[146]);
- void *b147 = rl_new_block("code 147");
+ void *b147 = rl_new_block("code 147", "the_var");
block_map[147] = b147;
rl_relooper_add_block(rl, block_map[147]);
- void *b148 = rl_new_block("code 148");
+ void *b148 = rl_new_block("code 148", "the_var");
block_map[148] = b148;
rl_relooper_add_block(rl, block_map[148]);
- void *b149 = rl_new_block("code 149");
+ void *b149 = rl_new_block("code 149", "the_var");
block_map[149] = b149;
rl_relooper_add_block(rl, block_map[149]);
- void *b150 = rl_new_block("code 150");
+ void *b150 = rl_new_block("code 150", "the_var");
block_map[150] = b150;
rl_relooper_add_block(rl, block_map[150]);
- void *b151 = rl_new_block("code 151");
+ void *b151 = rl_new_block("code 151", "the_var");
block_map[151] = b151;
rl_relooper_add_block(rl, block_map[151]);
- void *b152 = rl_new_block("code 152");
+ void *b152 = rl_new_block("code 152", "the_var");
block_map[152] = b152;
rl_relooper_add_block(rl, block_map[152]);
- void *b153 = rl_new_block("code 153");
+ void *b153 = rl_new_block("code 153", "the_var");
block_map[153] = b153;
rl_relooper_add_block(rl, block_map[153]);
- void *b154 = rl_new_block("code 154");
+ void *b154 = rl_new_block("code 154", "the_var");
block_map[154] = b154;
rl_relooper_add_block(rl, block_map[154]);
- void *b155 = rl_new_block("code 155");
+ void *b155 = rl_new_block("code 155", "the_var");
block_map[155] = b155;
rl_relooper_add_block(rl, block_map[155]);
- void *b156 = rl_new_block("code 156");
+ void *b156 = rl_new_block("code 156", "the_var");
block_map[156] = b156;
rl_relooper_add_block(rl, block_map[156]);
- void *b157 = rl_new_block("code 157");
+ void *b157 = rl_new_block("code 157", "the_var");
block_map[157] = b157;
rl_relooper_add_block(rl, block_map[157]);
- void *b158 = rl_new_block("code 158");
+ void *b158 = rl_new_block("code 158", "the_var");
block_map[158] = b158;
rl_relooper_add_block(rl, block_map[158]);
- void *b159 = rl_new_block("code 159");
+ void *b159 = rl_new_block("code 159", "the_var");
block_map[159] = b159;
rl_relooper_add_block(rl, block_map[159]);
- void *b160 = rl_new_block("code 160");
+ void *b160 = rl_new_block("code 160", "the_var");
block_map[160] = b160;
rl_relooper_add_block(rl, block_map[160]);
- void *b161 = rl_new_block("code 161");
+ void *b161 = rl_new_block("code 161", "the_var");
block_map[161] = b161;
rl_relooper_add_block(rl, block_map[161]);
- void *b162 = rl_new_block("code 162");
+ void *b162 = rl_new_block("code 162", "the_var");
block_map[162] = b162;
rl_relooper_add_block(rl, block_map[162]);
- void *b163 = rl_new_block("code 163");
+ void *b163 = rl_new_block("code 163", "the_var");
block_map[163] = b163;
rl_relooper_add_block(rl, block_map[163]);
- void *b164 = rl_new_block("code 164");
+ void *b164 = rl_new_block("code 164", "the_var");
block_map[164] = b164;
rl_relooper_add_block(rl, block_map[164]);
- void *b165 = rl_new_block("code 165");
+ void *b165 = rl_new_block("code 165", "the_var");
block_map[165] = b165;
rl_relooper_add_block(rl, block_map[165]);
- void *b166 = rl_new_block("code 166");
+ void *b166 = rl_new_block("code 166", "the_var");
block_map[166] = b166;
rl_relooper_add_block(rl, block_map[166]);
- void *b167 = rl_new_block("code 167");
+ void *b167 = rl_new_block("code 167", "the_var");
block_map[167] = b167;
rl_relooper_add_block(rl, block_map[167]);
- void *b168 = rl_new_block("code 168");
+ void *b168 = rl_new_block("code 168", "the_var");
block_map[168] = b168;
rl_relooper_add_block(rl, block_map[168]);
- void *b169 = rl_new_block("code 169");
+ void *b169 = rl_new_block("code 169", "the_var");
block_map[169] = b169;
rl_relooper_add_block(rl, block_map[169]);
- void *b170 = rl_new_block("code 170");
+ void *b170 = rl_new_block("code 170", "the_var");
block_map[170] = b170;
rl_relooper_add_block(rl, block_map[170]);
- void *b171 = rl_new_block("code 171");
+ void *b171 = rl_new_block("code 171", "the_var");
block_map[171] = b171;
rl_relooper_add_block(rl, block_map[171]);
- void *b172 = rl_new_block("code 172");
+ void *b172 = rl_new_block("code 172", "the_var");
block_map[172] = b172;
rl_relooper_add_block(rl, block_map[172]);
- void *b173 = rl_new_block("code 173");
+ void *b173 = rl_new_block("code 173", "the_var");
block_map[173] = b173;
rl_relooper_add_block(rl, block_map[173]);
- void *b174 = rl_new_block("code 174");
+ void *b174 = rl_new_block("code 174", "the_var");
block_map[174] = b174;
rl_relooper_add_block(rl, block_map[174]);
- void *b175 = rl_new_block("code 175");
+ void *b175 = rl_new_block("code 175", "the_var");
block_map[175] = b175;
rl_relooper_add_block(rl, block_map[175]);
- void *b176 = rl_new_block("code 176");
+ void *b176 = rl_new_block("code 176", "the_var");
block_map[176] = b176;
rl_relooper_add_block(rl, block_map[176]);
- void *b177 = rl_new_block("code 177");
+ void *b177 = rl_new_block("code 177", "the_var");
block_map[177] = b177;
rl_relooper_add_block(rl, block_map[177]);
- void *b178 = rl_new_block("code 178");
+ void *b178 = rl_new_block("code 178", "the_var");
block_map[178] = b178;
rl_relooper_add_block(rl, block_map[178]);
- void *b179 = rl_new_block("code 179");
+ void *b179 = rl_new_block("code 179", "the_var");
block_map[179] = b179;
rl_relooper_add_block(rl, block_map[179]);
- void *b180 = rl_new_block("code 180");
+ void *b180 = rl_new_block("code 180", "the_var");
block_map[180] = b180;
rl_relooper_add_block(rl, block_map[180]);
- void *b181 = rl_new_block("code 181");
+ void *b181 = rl_new_block("code 181", "the_var");
block_map[181] = b181;
rl_relooper_add_block(rl, block_map[181]);
- void *b182 = rl_new_block("code 182");
+ void *b182 = rl_new_block("code 182", "the_var");
block_map[182] = b182;
rl_relooper_add_block(rl, block_map[182]);
- void *b183 = rl_new_block("code 183");
+ void *b183 = rl_new_block("code 183", "the_var");
block_map[183] = b183;
rl_relooper_add_block(rl, block_map[183]);
rl_block_add_branch_to(block_map[0], block_map[2], "uint(i4) >= uint(i5)", NULL);
diff --git a/src/relooper/test_inf.txt b/src/relooper/test_inf.txt
index bc2fad3e..6db32edb 100644
--- a/src/relooper/test_inf.txt
+++ b/src/relooper/test_inf.txt
@@ -1,385 +1,1131 @@
code 0
-if (uint(i4) >= uint(i5)) {
+switch (the_var) {
+uint(i4) >= uint(i5) {
code 2
-} else {
+ switch (the_var) {
+ default: {
+ }
+ }
+ break;
+}
+default: {
code 1
+ switch (the_var) {
+ default: {
+ }
+ }
+}
}
code 3
-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
+L5: do {
+ switch (the_var) {
+ i2 == 0 {
+ break;
+ }
+ default: {
+ code 4
+ switch (the_var) {
+ default: {
}
- code 11
- if (uint(i5) >= uint(i6)) {
- code 13
- } else {
- code 12
}
- code 14
- if (!(i2 != 0)) {
- break;
+ while(1) {
+ code 5
+ switch (the_var) {
+ uint(i6) >= uint(i7) {
+ code 7
+ switch (the_var) {
+ default: {
+ }
+ }
+ break;
+ }
+ default: {
+ code 6
+ switch (the_var) {
+ default: {
+ }
+ }
+ }
+ }
+ code 8
+ switch (the_var) {
+ uint(i6) >= uint(i7) {
+ code 10
+ switch (the_var) {
+ default: {
+ }
+ }
+ break;
+ }
+ default: {
+ code 9
+ switch (the_var) {
+ default: {
+ }
+ }
+ }
+ }
+ code 11
+ switch (the_var) {
+ uint(i5) >= uint(i6) {
+ code 13
+ switch (the_var) {
+ default: {
+ }
+ }
+ break;
+ }
+ default: {
+ code 12
+ switch (the_var) {
+ default: {
+ }
+ }
+ }
+ }
+ code 14
+ switch (the_var) {
+ i2 != 0 {
+ break;
+ }
+ default: {
+ break L5;
+ }
+ }
}
}
-}
+ }
+} while(0);
code 15
-if (uint(i4) >= uint(i5)) {
+switch (the_var) {
+uint(i4) >= uint(i5) {
code 17
-} else {
+ switch (the_var) {
+ default: {
+ }
+ }
+ break;
+}
+default: {
code 16
+ switch (the_var) {
+ default: {
+ }
+ }
+}
}
code 18
-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
+L26: do {
+ switch (the_var) {
+ i2 == 0 {
+ break;
+ }
+ default: {
+ code 19
+ switch (the_var) {
+ default: {
}
- code 98
- if (uint(i5) >= uint(i6)) {
- code 100
- } else {
- code 99
}
- code 101
- if (!(i2 != 0)) {
- break;
+ while(1) {
+ code 20
+ switch (the_var) {
+ uint(i5) >= uint(i6) {
+ code 22
+ switch (the_var) {
+ default: {
+ }
+ }
+ break;
+ }
+ default: {
+ code 21
+ switch (the_var) {
+ default: {
+ }
+ }
+ }
+ }
+ code 23
+ switch (the_var) {
+ uint(i5) >= uint(i6) {
+ code 25
+ switch (the_var) {
+ default: {
+ }
+ }
+ break;
+ }
+ default: {
+ code 24
+ switch (the_var) {
+ default: {
+ }
+ }
+ }
+ }
+ code 26
+ switch (the_var) {
+ uint(i5) >= uint(i6) {
+ code 28
+ switch (the_var) {
+ default: {
+ }
+ }
+ break;
+ }
+ default: {
+ code 27
+ switch (the_var) {
+ default: {
+ }
+ }
+ }
+ }
+ code 29
+ switch (the_var) {
+ uint(i5) >= uint(i6) {
+ code 31
+ switch (the_var) {
+ default: {
+ }
+ }
+ break;
+ }
+ default: {
+ code 30
+ switch (the_var) {
+ default: {
+ }
+ }
+ }
+ }
+ code 32
+ switch (the_var) {
+ uint(i5) >= uint(i6) {
+ code 34
+ switch (the_var) {
+ default: {
+ }
+ }
+ break;
+ }
+ default: {
+ code 33
+ switch (the_var) {
+ default: {
+ }
+ }
+ }
+ }
+ code 35
+ switch (the_var) {
+ uint(i5) >= uint(i6) {
+ code 37
+ switch (the_var) {
+ default: {
+ }
+ }
+ break;
+ }
+ default: {
+ code 36
+ switch (the_var) {
+ default: {
+ }
+ }
+ }
+ }
+ code 38
+ switch (the_var) {
+ uint(i5) >= uint(i6) {
+ code 40
+ switch (the_var) {
+ default: {
+ }
+ }
+ break;
+ }
+ default: {
+ code 39
+ switch (the_var) {
+ default: {
+ }
+ }
+ }
+ }
+ code 41
+ switch (the_var) {
+ uint(i5) >= uint(i6) {
+ code 43
+ switch (the_var) {
+ default: {
+ }
+ }
+ break;
+ }
+ default: {
+ code 42
+ switch (the_var) {
+ default: {
+ }
+ }
+ }
+ }
+ code 44
+ switch (the_var) {
+ uint(i5) >= uint(i6) {
+ code 46
+ switch (the_var) {
+ default: {
+ }
+ }
+ break;
+ }
+ default: {
+ code 45
+ switch (the_var) {
+ default: {
+ }
+ }
+ }
+ }
+ code 47
+ switch (the_var) {
+ uint(i5) >= uint(i6) {
+ code 49
+ switch (the_var) {
+ default: {
+ }
+ }
+ break;
+ }
+ default: {
+ code 48
+ switch (the_var) {
+ default: {
+ }
+ }
+ }
+ }
+ code 50
+ switch (the_var) {
+ uint(i5) >= uint(i6) {
+ code 52
+ switch (the_var) {
+ default: {
+ }
+ }
+ break;
+ }
+ default: {
+ code 51
+ switch (the_var) {
+ default: {
+ }
+ }
+ }
+ }
+ code 53
+ switch (the_var) {
+ uint(i5) >= uint(i6) {
+ code 55
+ switch (the_var) {
+ default: {
+ }
+ }
+ break;
+ }
+ default: {
+ code 54
+ switch (the_var) {
+ default: {
+ }
+ }
+ }
+ }
+ code 56
+ switch (the_var) {
+ uint(i5) >= uint(i6) {
+ code 58
+ switch (the_var) {
+ default: {
+ }
+ }
+ break;
+ }
+ default: {
+ code 57
+ switch (the_var) {
+ default: {
+ }
+ }
+ }
+ }
+ code 59
+ switch (the_var) {
+ uint(i5) >= uint(i6) {
+ code 61
+ switch (the_var) {
+ default: {
+ }
+ }
+ break;
+ }
+ default: {
+ code 60
+ switch (the_var) {
+ default: {
+ }
+ }
+ }
+ }
+ code 62
+ switch (the_var) {
+ uint(i5) >= uint(i6) {
+ code 64
+ switch (the_var) {
+ default: {
+ }
+ }
+ break;
+ }
+ default: {
+ code 63
+ switch (the_var) {
+ default: {
+ }
+ }
+ }
+ }
+ code 65
+ switch (the_var) {
+ uint(i5) >= uint(i6) {
+ code 67
+ switch (the_var) {
+ default: {
+ }
+ }
+ break;
+ }
+ default: {
+ code 66
+ switch (the_var) {
+ default: {
+ }
+ }
+ }
+ }
+ code 68
+ switch (the_var) {
+ uint(i5) >= uint(i6) {
+ code 70
+ switch (the_var) {
+ default: {
+ }
+ }
+ break;
+ }
+ default: {
+ code 69
+ switch (the_var) {
+ default: {
+ }
+ }
+ }
+ }
+ code 71
+ switch (the_var) {
+ uint(i5) >= uint(i6) {
+ code 73
+ switch (the_var) {
+ default: {
+ }
+ }
+ break;
+ }
+ default: {
+ code 72
+ switch (the_var) {
+ default: {
+ }
+ }
+ }
+ }
+ code 74
+ switch (the_var) {
+ uint(i5) >= uint(i6) {
+ code 76
+ switch (the_var) {
+ default: {
+ }
+ }
+ break;
+ }
+ default: {
+ code 75
+ switch (the_var) {
+ default: {
+ }
+ }
+ }
+ }
+ code 77
+ switch (the_var) {
+ uint(i5) >= uint(i6) {
+ code 79
+ switch (the_var) {
+ default: {
+ }
+ }
+ break;
+ }
+ default: {
+ code 78
+ switch (the_var) {
+ default: {
+ }
+ }
+ }
+ }
+ code 80
+ switch (the_var) {
+ uint(i5) >= uint(i6) {
+ code 82
+ switch (the_var) {
+ default: {
+ }
+ }
+ break;
+ }
+ default: {
+ code 81
+ switch (the_var) {
+ default: {
+ }
+ }
+ }
+ }
+ code 83
+ switch (the_var) {
+ uint(i5) >= uint(i6) {
+ code 85
+ switch (the_var) {
+ default: {
+ }
+ }
+ break;
+ }
+ default: {
+ code 84
+ switch (the_var) {
+ default: {
+ }
+ }
+ }
+ }
+ code 86
+ switch (the_var) {
+ uint(i5) >= uint(i6) {
+ code 88
+ switch (the_var) {
+ default: {
+ }
+ }
+ break;
+ }
+ default: {
+ code 87
+ switch (the_var) {
+ default: {
+ }
+ }
+ }
+ }
+ code 89
+ switch (the_var) {
+ uint(i5) >= uint(i6) {
+ code 91
+ switch (the_var) {
+ default: {
+ }
+ }
+ break;
+ }
+ default: {
+ code 90
+ switch (the_var) {
+ default: {
+ }
+ }
+ }
+ }
+ code 92
+ switch (the_var) {
+ uint(i5) >= uint(i6) {
+ code 94
+ switch (the_var) {
+ default: {
+ }
+ }
+ break;
+ }
+ default: {
+ code 93
+ switch (the_var) {
+ default: {
+ }
+ }
+ }
+ }
+ code 95
+ switch (the_var) {
+ uint(i5) >= uint(i6) {
+ code 97
+ switch (the_var) {
+ default: {
+ }
+ }
+ break;
+ }
+ default: {
+ code 96
+ switch (the_var) {
+ default: {
+ }
+ }
+ }
+ }
+ code 98
+ switch (the_var) {
+ uint(i5) >= uint(i6) {
+ code 100
+ switch (the_var) {
+ default: {
+ }
+ }
+ break;
+ }
+ default: {
+ code 99
+ switch (the_var) {
+ default: {
+ }
+ }
+ }
+ }
+ code 101
+ switch (the_var) {
+ i2 != 0 {
+ break;
+ }
+ default: {
+ break L26;
+ }
+ }
}
}
-}
+ }
+} while(0);
code 102
-if (uint(i4) >= uint(i5)) {
+switch (the_var) {
+uint(i4) >= uint(i5) {
code 104
-} else {
+ switch (the_var) {
+ default: {
+ }
+ }
+ break;
+}
+default: {
code 103
+ switch (the_var) {
+ default: {
+ }
+ }
+}
}
code 105
-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
+L143: do {
+ switch (the_var) {
+ i2 == 0 {
+ break;
+ }
+ default: {
+ code 106
+ switch (the_var) {
+ default: {
}
- code 164
- if (uint(i5) >= uint(i6)) {
- code 166
- } else {
- code 165
}
- code 167
- if (!(i2 != 0)) {
- break;
+ while(1) {
+ code 107
+ switch (the_var) {
+ uint(i5) >= uint(i6) {
+ code 109
+ switch (the_var) {
+ default: {
+ }
+ }
+ break;
+ }
+ default: {
+ code 108
+ switch (the_var) {
+ default: {
+ }
+ }
+ }
+ }
+ code 110
+ switch (the_var) {
+ uint(i5) >= uint(i6) {
+ code 112
+ switch (the_var) {
+ default: {
+ }
+ }
+ break;
+ }
+ default: {
+ code 111
+ switch (the_var) {
+ default: {
+ }
+ }
+ }
+ }
+ code 113
+ switch (the_var) {
+ uint(i5) >= uint(i6) {
+ code 115
+ switch (the_var) {
+ default: {
+ }
+ }
+ break;
+ }
+ default: {
+ code 114
+ switch (the_var) {
+ default: {
+ }
+ }
+ }
+ }
+ code 116
+ switch (the_var) {
+ uint(i5) >= uint(i6) {
+ code 118
+ switch (the_var) {
+ default: {
+ }
+ }
+ break;
+ }
+ default: {
+ code 117
+ switch (the_var) {
+ default: {
+ }
+ }
+ }
+ }
+ code 119
+ switch (the_var) {
+ uint(i5) >= uint(i6) {
+ code 121
+ switch (the_var) {
+ default: {
+ }
+ }
+ break;
+ }
+ default: {
+ code 120
+ switch (the_var) {
+ default: {
+ }
+ }
+ }
+ }
+ code 122
+ switch (the_var) {
+ uint(i5) >= uint(i6) {
+ code 124
+ switch (the_var) {
+ default: {
+ }
+ }
+ break;
+ }
+ default: {
+ code 123
+ switch (the_var) {
+ default: {
+ }
+ }
+ }
+ }
+ code 125
+ switch (the_var) {
+ uint(i5) >= uint(i6) {
+ code 127
+ switch (the_var) {
+ default: {
+ }
+ }
+ break;
+ }
+ default: {
+ code 126
+ switch (the_var) {
+ default: {
+ }
+ }
+ }
+ }
+ code 128
+ switch (the_var) {
+ uint(i5) >= uint(i6) {
+ code 130
+ switch (the_var) {
+ default: {
+ }
+ }
+ break;
+ }
+ default: {
+ code 129
+ switch (the_var) {
+ default: {
+ }
+ }
+ }
+ }
+ code 131
+ switch (the_var) {
+ uint(i5) >= uint(i6) {
+ code 133
+ switch (the_var) {
+ default: {
+ }
+ }
+ break;
+ }
+ default: {
+ code 132
+ switch (the_var) {
+ default: {
+ }
+ }
+ }
+ }
+ code 134
+ switch (the_var) {
+ uint(i5) >= uint(i6) {
+ code 136
+ switch (the_var) {
+ default: {
+ }
+ }
+ break;
+ }
+ default: {
+ code 135
+ switch (the_var) {
+ default: {
+ }
+ }
+ }
+ }
+ code 137
+ switch (the_var) {
+ uint(i5) >= uint(i6) {
+ code 139
+ switch (the_var) {
+ default: {
+ }
+ }
+ break;
+ }
+ default: {
+ code 138
+ switch (the_var) {
+ default: {
+ }
+ }
+ }
+ }
+ code 140
+ switch (the_var) {
+ uint(i5) >= uint(i6) {
+ code 142
+ switch (the_var) {
+ default: {
+ }
+ }
+ break;
+ }
+ default: {
+ code 141
+ switch (the_var) {
+ default: {
+ }
+ }
+ }
+ }
+ code 143
+ switch (the_var) {
+ uint(i5) >= uint(i6) {
+ code 145
+ switch (the_var) {
+ default: {
+ }
+ }
+ break;
+ }
+ default: {
+ code 144
+ switch (the_var) {
+ default: {
+ }
+ }
+ }
+ }
+ code 146
+ switch (the_var) {
+ uint(i5) >= uint(i6) {
+ code 148
+ switch (the_var) {
+ default: {
+ }
+ }
+ break;
+ }
+ default: {
+ code 147
+ switch (the_var) {
+ default: {
+ }
+ }
+ }
+ }
+ code 149
+ switch (the_var) {
+ uint(i5) >= uint(i6) {
+ code 151
+ switch (the_var) {
+ default: {
+ }
+ }
+ break;
+ }
+ default: {
+ code 150
+ switch (the_var) {
+ default: {
+ }
+ }
+ }
+ }
+ code 152
+ switch (the_var) {
+ uint(i5) >= uint(i6) {
+ code 154
+ switch (the_var) {
+ default: {
+ }
+ }
+ break;
+ }
+ default: {
+ code 153
+ switch (the_var) {
+ default: {
+ }
+ }
+ }
+ }
+ code 155
+ switch (the_var) {
+ uint(i5) >= uint(i6) {
+ code 157
+ switch (the_var) {
+ default: {
+ }
+ }
+ break;
+ }
+ default: {
+ code 156
+ switch (the_var) {
+ default: {
+ }
+ }
+ }
+ }
+ code 158
+ switch (the_var) {
+ uint(i5) >= uint(i6) {
+ code 160
+ switch (the_var) {
+ default: {
+ }
+ }
+ break;
+ }
+ default: {
+ code 159
+ switch (the_var) {
+ default: {
+ }
+ }
+ }
+ }
+ code 161
+ switch (the_var) {
+ uint(i5) >= uint(i6) {
+ code 163
+ switch (the_var) {
+ default: {
+ }
+ }
+ break;
+ }
+ default: {
+ code 162
+ switch (the_var) {
+ default: {
+ }
+ }
+ }
+ }
+ code 164
+ switch (the_var) {
+ uint(i5) >= uint(i6) {
+ code 166
+ switch (the_var) {
+ default: {
+ }
+ }
+ break;
+ }
+ default: {
+ code 165
+ switch (the_var) {
+ default: {
+ }
+ }
+ }
+ }
+ code 167
+ switch (the_var) {
+ i2 != 0 {
+ break;
+ }
+ default: {
+ break L143;
+ }
+ }
}
}
-}
+ }
+} while(0);
code 168
-if (uint(i4) >= uint(i5)) {
+switch (the_var) {
+uint(i4) >= uint(i5) {
code 170
-} else {
+ switch (the_var) {
+ default: {
+ }
+ }
+ break;
+}
+default: {
code 169
+ switch (the_var) {
+ default: {
+ }
+ }
+}
}
code 171
-if (i2 == 0) {
+switch (the_var) {
+i2 == 0 {
code 183
+ break;
+}
+default: {
+}
}
code 172
-while(1) {
+switch (the_var) {
+default: {
+}
+}
+L235: while(1) {
code 173
- if (uint(i5) >= uint(i6)) {
+ switch (the_var) {
+ uint(i5) >= uint(i6) {
code 175
- } else {
+ switch (the_var) {
+ default: {
+ }
+ }
+ break;
+ }
+ default: {
code 174
+ switch (the_var) {
+ default: {
+ }
+ }
+ }
}
code 176
- if (uint(i5) >= uint(i6)) {
+ switch (the_var) {
+ uint(i5) >= uint(i6) {
code 178
- } else {
+ switch (the_var) {
+ default: {
+ }
+ }
+ break;
+ }
+ default: {
code 177
+ switch (the_var) {
+ default: {
+ }
+ }
+ }
}
code 179
- if (uint(i4) >= uint(i5)) {
+ switch (the_var) {
+ uint(i4) >= uint(i5) {
code 181
- } else {
+ switch (the_var) {
+ default: {
+ }
+ }
+ break;
+ }
+ default: {
code 180
+ switch (the_var) {
+ default: {
+ }
+ }
+ }
}
code 182
- if (!(i2 != 0)) {
+ switch (the_var) {
+ i2 != 0 {
break;
}
+ default: {
+ break L235;
+ }
+ }
}
code 183
diff --git a/src/runtime.js b/src/runtime.js
index e07d5054..33088ad9 100644
--- a/src/runtime.js
+++ b/src/runtime.js
@@ -386,35 +386,51 @@ var Runtime = {
// Returns a processor of UTF.
// processCChar() receives characters from a C-like UTF representation and returns JS string fragments.
+ // See RFC3629 for details, the bytes are assumed to be valid UTF-8
// processJSString() receives a JS string and returns a C-like UTF representation in an array
UTF8Processor: function() {
var buffer = [];
var needed = 0;
this.processCChar = function (code) {
- code = code & 0xff;
- if (needed) {
- buffer.push(code);
- needed--;
- }
+ code = code & 0xFF;
+
if (buffer.length == 0) {
- if (code < 128) return String.fromCharCode(code);
+ if ((code & 0x80) == 0x00) { // 0xxxxxxx
+ return String.fromCharCode(code);
+ }
buffer.push(code);
- if (code > 191 && code < 224) {
+ if ((code & 0xE0) == 0xC0) { // 110xxxxx
needed = 1;
- } else {
+ } else if ((code & 0xF0) == 0xE0) { // 1110xxxx
needed = 2;
+ } else { // 11110xxx
+ needed = 3;
}
return '';
}
- if (needed > 0) return '';
+
+ if (needed) {
+ buffer.push(code);
+ needed--;
+ if (needed > 0) return '';
+ }
+
var c1 = buffer[0];
var c2 = buffer[1];
var c3 = buffer[2];
+ var c4 = buffer[3];
var ret;
- if (c1 > 191 && c1 < 224) {
- ret = String.fromCharCode(((c1 & 31) << 6) | (c2 & 63));
+ if (buffer.length == 2) {
+ ret = String.fromCharCode(((c1 & 0x1F) << 6) | (c2 & 0x3F));
+ } else if (buffer.length == 3) {
+ ret = String.fromCharCode(((c1 & 0x0F) << 12) | ((c2 & 0x3F) << 6) | (c3 & 0x3F));
} else {
- ret = String.fromCharCode(((c1 & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
+ // http://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae
+ var codePoint = ((c1 & 0x07) << 18) | ((c2 & 0x3F) << 12) |
+ ((c3 & 0x3F) << 6) | (c4 & 0x3F);
+ ret = String.fromCharCode(
+ Math.floor((codePoint - 0x10000) / 0x400) + 0xD800,
+ (codePoint - 0x10000) % 0x400 + 0xDC00);
}
buffer.length = 0;
return ret;
diff --git a/src/settings.js b/src/settings.js
index 8757f7b9..03b4ed64 100644
--- a/src/settings.js
+++ b/src/settings.js
@@ -6,6 +6,11 @@
// emcc -s OPTION1=VALUE1 -s OPTION2=VALUE2 [..other stuff..]
//
// See https://github.com/kripken/emscripten/wiki/Code-Generation-Modes/
+//
+// Note that the values here are the defaults in -O0, that is, unoptimized
+// mode. See apply_opt_level in tools/shared.py for how -O1,2,3 affect these
+// flags.
+//
// Tuning
var QUANTUM_SIZE = 4; // This is the size of an individual field in a structure. 1 would
@@ -131,6 +136,16 @@ var OUTLINING_LIMIT = 0; // A function size above which we try to automatically
// large functions (JS engines often compile them very slowly,
// compile them with lower optimizations, or do not optimize them
// at all). If 0, we do not perform outlining at all.
+ // To see which funcs are large, you can inspect the source
+ // in a debug build (-g2 or -g for example), and can run
+ // tools/find_bigfuncs.py on that to get a sorted list by size.
+ // Another possibility is to look in the web console in firefox,
+ // which will note slowly-compiling functions.
+ // You will probably want to experiment with various values to
+ // see the impact on compilation time, code size and runtime
+ // throughput. It is hard to say what values to start testing
+ // with, but something around 20,000 to 100,000 might make sense.
+ // (The unit size is number of AST nodes.)
// Generated code debugging options
var SAFE_HEAP = 0; // Check each write to the heap, for example, this will give a clear
@@ -315,11 +330,12 @@ var SIDE_MODULE = 0; // Corresponds to MAIN_MODULE
var BUILD_AS_SHARED_LIB = 0; // Whether to build the code as a shared library
// 0 here means this is not a shared lib: It is a main file.
- // All shared library options (1 and 2) are currently deprecated XXX
// 1 means this is a normal shared lib, load it with dlopen()
// 2 means this is a shared lib that will be linked at runtime,
// which means it will insert its functions into
// the global namespace. See STATIC_LIBS_TO_LOAD.
+ //
+ // Value 2 is currently deprecated.
var RUNTIME_LINKED_LIBS = []; // If this is a main file (BUILD_AS_SHARED_LIB == 0), then
// we will link these at runtime. They must have been built with
// BUILD_AS_SHARED_LIB == 2.
@@ -379,9 +395,7 @@ var HEADLESS = 0; // If 1, will include shim code that tries to 'fake' a browser
var BENCHMARK = 0; // If 1, will just time how long main() takes to execute, and not
// print out anything at all whatsoever. This is useful for benchmarking.
-var ASM_JS = 0; // If 1, generate code in asm.js format. XXX This is highly experimental,
- // and will not work on most codebases yet. It is NOT recommended that you
- // try this yet.
+var ASM_JS = 0; // If 1, generate code in asm.js format.
var PGO = 0; // Enables profile-guided optimization in the form of runtime checks for
// which functions are actually called. Emits a list during shutdown that you
diff --git a/src/shell.html b/src/shell.html
index 22bc9de9..ff5f6e35 100644
--- a/src/shell.html
+++ b/src/shell.html
@@ -87,6 +87,6 @@
};
Module.setStatus('Downloading...');
</script>
- <script type='text/javascript'>{{{ SCRIPT_CODE }}}</script>
+ <script async type='text/javascript'>{{{ SCRIPT_CODE }}}</script>
</body>
</html>
diff --git a/system/include/emscripten/emscripten.h b/system/include/emscripten/emscripten.h
index f0df8dca..1b9a8f25 100644
--- a/system/include/emscripten/emscripten.h
+++ b/system/include/emscripten/emscripten.h
@@ -19,6 +19,16 @@ extern "C" {
#endif
/*
+ * Convenient syntax for inline assembly/js. Allows stuff like
+ *
+ * EM_ASM(window.alert('hai'));
+ *
+ * Note: double-quotes (") are not supported, but you can use
+ * single-quotes (') in js anyhow.
+ */
+#define EM_ASM(...) asm(#__VA_ARGS__)
+
+/*
* Forces LLVM to not dead-code-eliminate a function. Note that
* you still need to use EXPORTED_FUNCTIONS so it stays alive
* in JS, e.g.
@@ -160,6 +170,12 @@ void emscripten_hide_mouse();
void emscripten_set_canvas_size(int width, int height);
/*
+ * Get the current pixel width and height of the <canvas> element
+ * as well as whether the canvas is fullscreen or not.
+ */
+void emscripten_get_canvas_size(int *width, int *height, int *isFullscreen);
+
+/*
* Returns the highest-precision representation of the
* current time that the browser provides. This uses either
* Date.now or performance.now. The result is *not* an
diff --git a/tests/aniso.c b/tests/aniso.c
index f210e5a5..e8d7bd3f 100644
--- a/tests/aniso.c
+++ b/tests/aniso.c
@@ -27,6 +27,7 @@ REDISTRIBUTION OF THIS SOFTWARE.
#include "SDL/SDL_opengl.h"
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#include <assert.h>
diff --git a/tests/cubegeom_color.c b/tests/cubegeom_color.c
index 7d384324..ff30e1a9 100644
--- a/tests/cubegeom_color.c
+++ b/tests/cubegeom_color.c
@@ -26,6 +26,7 @@ REDISTRIBUTION OF THIS SOFTWARE.
#endif
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#include <assert.h>
diff --git a/tests/cubegeom_pre.c b/tests/cubegeom_pre.c
index fb1a5e02..40b03cf7 100644
--- a/tests/cubegeom_pre.c
+++ b/tests/cubegeom_pre.c
@@ -26,6 +26,7 @@ REDISTRIBUTION OF THIS SOFTWARE.
#endif
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#include <assert.h>
diff --git a/tests/cubegeom_pre2.c b/tests/cubegeom_pre2.c
index 51961bf7..df04ae31 100644
--- a/tests/cubegeom_pre2.c
+++ b/tests/cubegeom_pre2.c
@@ -26,6 +26,7 @@ REDISTRIBUTION OF THIS SOFTWARE.
#endif
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#include <assert.h>
diff --git a/tests/cubegeom_pre2_vao.c b/tests/cubegeom_pre2_vao.c
index cba262ff..733c8fc6 100644
--- a/tests/cubegeom_pre2_vao.c
+++ b/tests/cubegeom_pre2_vao.c
@@ -26,6 +26,7 @@ REDISTRIBUTION OF THIS SOFTWARE.
#endif
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#include <assert.h>
diff --git a/tests/cubegeom_pre2_vao2.c b/tests/cubegeom_pre2_vao2.c
index 3784006c..69096833 100644
--- a/tests/cubegeom_pre2_vao2.c
+++ b/tests/cubegeom_pre2_vao2.c
@@ -26,6 +26,7 @@ REDISTRIBUTION OF THIS SOFTWARE.
#endif
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#include <assert.h>
diff --git a/tests/cubegeom_pre3.c b/tests/cubegeom_pre3.c
index 4ba2a779..ceaa757e 100644
--- a/tests/cubegeom_pre3.c
+++ b/tests/cubegeom_pre3.c
@@ -26,6 +26,7 @@ REDISTRIBUTION OF THIS SOFTWARE.
#endif
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#include <assert.h>
diff --git a/tests/cubegeom_pre_vao.c b/tests/cubegeom_pre_vao.c
index cae68cfc..8c598143 100644
--- a/tests/cubegeom_pre_vao.c
+++ b/tests/cubegeom_pre_vao.c
@@ -26,6 +26,7 @@ REDISTRIBUTION OF THIS SOFTWARE.
#endif
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#include <assert.h>
diff --git a/tests/cubegeom_texturematrix.c b/tests/cubegeom_texturematrix.c
index 99a4469e..abb667eb 100644
--- a/tests/cubegeom_texturematrix.c
+++ b/tests/cubegeom_texturematrix.c
@@ -26,6 +26,7 @@ REDISTRIBUTION OF THIS SOFTWARE.
#endif
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#include <assert.h>
diff --git a/tests/float_tex.cpp b/tests/float_tex.cpp
index 61531124..c40ff786 100644
--- a/tests/float_tex.cpp
+++ b/tests/float_tex.cpp
@@ -113,7 +113,7 @@ static void gl_init(void) {
/* Store the vertices in a vertex buffer object (VBO) */
glGenBuffers(1, &indicesVBO);
glBindBuffer(GL_ARRAY_BUFFER, indicesVBO);
- glBufferData(GL_ARRAY_BUFFER, elements.size() * sizeof(uint), &elements[0], GL_STATIC_DRAW);
+ glBufferData(GL_ARRAY_BUFFER, elements.size() * sizeof(float), &elements[0], GL_STATIC_DRAW);
/* Get the locations of the uniforms so we can access them */
nodeSamplerLocation = glGetUniformLocation(program, "nodeInfo");
glBindAttribLocation(program, 0, "indices");
diff --git a/tests/gl_matrix_identity.c b/tests/gl_matrix_identity.c
index 98b1c21f..9f990a77 100644
--- a/tests/gl_matrix_identity.c
+++ b/tests/gl_matrix_identity.c
@@ -26,6 +26,7 @@ REDISTRIBUTION OF THIS SOFTWARE.
#endif
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#include <assert.h>
diff --git a/tests/glshaderinfo.cpp b/tests/glshaderinfo.cpp
index 8ec393a8..56da2414 100644
--- a/tests/glshaderinfo.cpp
+++ b/tests/glshaderinfo.cpp
@@ -1,8 +1,6 @@
#define GL_GLEXT_PROTOTYPES
#define EGL_EGLEXT_PROTOTYPES
-#define _GNU_SOURCE
-
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
diff --git a/tests/glut_touchevents.c b/tests/glut_touchevents.c
new file mode 100644
index 00000000..2a0054bb
--- /dev/null
+++ b/tests/glut_touchevents.c
@@ -0,0 +1,64 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <GL/glut.h>
+#include <EGL/egl.h>
+#include <emscripten.h>
+
+#define MULTILINE(...) #__VA_ARGS__
+
+int touch_started = 0;
+int touch_ended = 0;
+
+int result = 0;
+
+void mouseCB(int button, int state, int x, int y)
+{
+ if(button == GLUT_LEFT_BUTTON)
+ {
+ if(state == GLUT_DOWN)
+ {
+ touch_started = 1;
+ }
+ else if(state == GLUT_UP)
+ {
+ touch_ended = 1;
+ }
+ }
+}
+
+int main(int argc, char *argv[])
+{
+ emscripten_run_script(MULTILINE(
+ Module.injectEvent = function(eventType, x, y) {
+ // Desktop browsers do not have the event types for touch events,
+ // so we fake them by creating a plain-vanilla UIEvent and then
+ // filling in the fields that we look for with appropriate values.
+ var touch = {
+ pageX: x,
+ pageY: y
+ };
+ var touches = [ touch ];
+ touches.item = function(i) { return this[i]; };
+
+ var event = document.createEvent('UIEvent');
+ event.target = Module['canvas'];
+ event.button = 0;
+ event.touches = touches;
+ event.initUIEvent(eventType, true, true, window, 1);
+ Module['canvas'].dispatchEvent(event);
+ }
+ ));
+
+ // Fake a touch device so that glut sets up the appropriate event handlers.
+ emscripten_run_script("document.documentElement['ontouchstart'] = 1");
+ glutInit(&argc, argv);
+
+ glutMouseFunc(&mouseCB);
+
+ emscripten_run_script("Module.injectEvent('touchend', 100, 100)");
+ emscripten_run_script("Module.injectEvent('touchstart', 100, 100)");
+ result = touch_started && touch_ended;
+
+ REPORT_RESULT();
+ return 0;
+}
diff --git a/tests/http.h b/tests/http.h
index 7eff7013..d20f012b 100644
--- a/tests/http.h
+++ b/tests/http.h
@@ -8,6 +8,7 @@
#ifndef __HTTP_H__
#define __HTTP_H__
+#include <stdarg.h>
#include <string>
diff --git a/tests/pthread/specific.c b/tests/pthread/specific.c
new file mode 100644
index 00000000..914884e7
--- /dev/null
+++ b/tests/pthread/specific.c
@@ -0,0 +1,60 @@
+#include <stdio.h>
+#include <assert.h>
+#include <errno.h>
+#include <pthread.h>
+
+static void destr_function(void *arg)
+{
+ // Not implemented yet in Emscripten
+}
+
+int main(void)
+{
+ pthread_key_t key = 0;
+ int rv;
+ int data = 123;
+ int *data2;
+
+ assert(pthread_key_delete(key) != 0);
+ assert(pthread_getspecific(key) == NULL);
+
+ rv = pthread_key_create(&key, &destr_function);
+ printf("pthread_key_create = %d\n", rv);
+ assert(rv == 0);
+
+ assert(pthread_getspecific(key) == NULL);
+
+ rv = pthread_setspecific(key, (void*) &data);
+ printf("pthread_setspecific = %d\n", rv);
+ assert(rv == 0);
+
+ data2 = pthread_getspecific(key);
+ assert(data2 != NULL);
+ printf("pthread_getspecific = %d\n", *data2);
+ assert(*data2 == 123);
+
+ rv = pthread_key_create(&key, &destr_function);
+ data2 = pthread_getspecific(key);
+ printf("pthread_getspecific after key recreate = %p\n", data2);
+ assert(data2 == NULL);
+
+ rv = pthread_key_delete(key);
+ printf("pthread_key_delete = %d\n", rv);
+ assert(rv == 0);
+
+ rv = pthread_key_delete(key);
+ printf("pthread_key_delete repeated = %d\n", rv);
+ assert(rv == EINVAL);
+
+ rv = pthread_setspecific(key, NULL);
+ printf("pthread_setspecific for value NULL = %d\n", rv);
+ assert(rv == EINVAL);
+
+ rv = pthread_key_create(&key, &destr_function);
+ assert(rv == 0);
+ rv = pthread_key_delete(key);
+ printf("pthread_key_delete just after created = %d\n", rv);
+ assert(rv == 0);
+
+ return 0;
+}
diff --git a/tests/pthread/specific.c.txt b/tests/pthread/specific.c.txt
new file mode 100644
index 00000000..ad122b3d
--- /dev/null
+++ b/tests/pthread/specific.c.txt
@@ -0,0 +1,8 @@
+pthread_key_create = 0
+pthread_setspecific = 0
+pthread_getspecific = 123
+pthread_getspecific after key recreate = (nil)
+pthread_key_delete = 0
+pthread_key_delete repeated = 22
+pthread_setspecific for value NULL = 22
+pthread_key_delete just after created = 0
diff --git a/tests/runner.py b/tests/runner.py
index 318946e6..bbbc23e5 100755
--- a/tests/runner.py
+++ b/tests/runner.py
@@ -732,6 +732,7 @@ if __name__ == '__main__':
==============================================================================
Running the main part of the test suite. Don't forget to run the other parts!
+ other - tests separate from the main suite
sanity - tests for first run, etc., modifies ~/.emscripten
benchmark - run before and after each set of changes before pushing to
master, verify no regressions
diff --git a/tests/s3tc.c b/tests/s3tc.c
index 16ee783f..5f7bee83 100644
--- a/tests/s3tc.c
+++ b/tests/s3tc.c
@@ -27,6 +27,7 @@ REDISTRIBUTION OF THIS SOFTWARE.
#include "SDL/SDL_opengl.h"
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#include <assert.h>
diff --git a/tests/s3tc_crunch.c b/tests/s3tc_crunch.c
index 90ed02d9..c2606c8f 100644
--- a/tests/s3tc_crunch.c
+++ b/tests/s3tc_crunch.c
@@ -27,6 +27,7 @@ REDISTRIBUTION OF THIS SOFTWARE.
#include "SDL/SDL_opengl.h"
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#include <assert.h>
diff --git a/tests/sdl_canvas.c b/tests/sdl_canvas.c
index 10044ff4..6bd659b8 100644
--- a/tests/sdl_canvas.c
+++ b/tests/sdl_canvas.c
@@ -1,4 +1,5 @@
#include <stdio.h>
+#include <stdlib.h>
#include <SDL/SDL.h>
#include <SDL/SDL_ttf.h>
#include <emscripten.h>
@@ -43,6 +44,16 @@ int main(int argc, char **argv) {
SDL_Flip(screen);
SDL_LockSurface(screen);
+
+ int width, height, isFullscreen;
+ emscripten_get_canvas_size(&width, &height, &isFullscreen);
+
+ if (width != 600 && height != 450)
+ {
+ printf("error: wrong width/height\n");
+ abort();
+ }
+
int sum = 0;
for (int i = 0; i < screen->h; i++) {
sum += *((char*)screen->pixels + i*screen->w*4 + i*4 + 0);
diff --git a/tests/sdl_headless.c b/tests/sdl_headless.c
new file mode 100644
index 00000000..349c5e26
--- /dev/null
+++ b/tests/sdl_headless.c
@@ -0,0 +1,65 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <SDL/SDL.h>
+#include <SDL/SDL_ttf.h>
+#include <emscripten.h>
+
+
+int main(int argc, char **argv) {
+#if EMSCRIPTEN
+ // include GL stuff, to check that we can compile hybrid 2d/GL apps
+ extern void glBegin(int mode);
+ extern void glBindBuffer(int target, int buffer);
+ if (argc == 9876) {
+ glBegin(0);
+ glBindBuffer(0, 0);
+ }
+#endif
+
+ SDL_Init(SDL_INIT_VIDEO);
+ SDL_Surface *screen = SDL_SetVideoMode(600, 450, 32, SDL_HWSURFACE);
+
+ printf("Init: %d\n", TTF_Init());
+
+ TTF_Font *font = TTF_OpenFont("sans-serif", 40);
+ printf("Font: %p\n", font);
+
+ SDL_Color color = { 0xff, 0x99, 0x00, 0xff };
+
+ SDL_Surface *text = TTF_RenderText_Solid(font, "hello orange world", color);
+
+ SDL_Color color2 = { 0xbb, 0, 0xff, 0xff };
+ SDL_Surface *text2 = TTF_RenderText_Solid(font, "a second line, purple", color2);
+
+ // render
+ SDL_Rect dest = { 0, 50, 0, 0 };
+ SDL_BlitSurface (text, NULL, screen, NULL);
+ dest.y = 100;
+ SDL_BlitSurface (text2, NULL, screen, &dest);
+
+ // fill stuff
+ SDL_Rect rect = { 200, 200, 175, 125 };
+ SDL_FillRect(screen, &rect, SDL_MapRGBA(screen->format, 0x22, 0x22, 0xff, 0xff));
+
+ SDL_Flip(screen);
+
+ SDL_LockSurface(screen);
+
+ int sum = 0;
+ for (int i = 0; i < screen->h; i++) {
+ sum += *((char*)screen->pixels + i*screen->w*4 + i*4 + 0);
+ }
+ printf("Sum: %d\n", sum);
+
+ printf("you should see two lines of text in different colors and a blue rectangle\n");
+
+ SDL_Quit();
+
+ printf("done.\n");
+
+ int result = sum > 3000 && sum < 5000; // varies a little on different browsers, font differences?
+ REPORT_RESULT();
+
+ return 0;
+}
+
diff --git a/tests/sdl_image_prepare_data.c b/tests/sdl_image_prepare_data.c
index d45a2e60..043ace47 100644
--- a/tests/sdl_image_prepare_data.c
+++ b/tests/sdl_image_prepare_data.c
@@ -58,7 +58,7 @@ int main() {
printf("prepare..\n");
#define SIZE 203164
- FILE *f = open("screenshot.not", "rb");
+ FILE *f = fopen("screenshot.not", "rb");
char *buffer = malloc(SIZE);
fread(buffer, SIZE, 1, f);
fclose(f);
diff --git a/tests/sdl_pumpevents.c b/tests/sdl_pumpevents.c
index 64becaad..e765d285 100644
--- a/tests/sdl_pumpevents.c
+++ b/tests/sdl_pumpevents.c
@@ -40,6 +40,20 @@ int loop2()
return r;
}
+int alphakey()
+{
+ unsigned i;
+ int r = 0;
+
+ SDL_PumpEvents();
+
+ const Uint8 *keys = SDL_GetKeyState(NULL);
+ if (keys[SDLK_a])
+ r = 4;
+
+ return r;
+}
+
int main(int argc, char *argv[])
{
SDL_Init(SDL_INIT_EVERYTHING);
@@ -49,6 +63,8 @@ int main(int argc, char *argv[])
result += loop1();
emscripten_run_script("keydown(39);"); // right
result += loop2();
+ emscripten_run_script("keydown(65);"); // A
+ result += alphakey();
REPORT_RESULT();
return 0;
}
diff --git a/tests/sockets/test_enet_client.c b/tests/sockets/test_enet_client.c
index bf14375c..afcdcae8 100644
--- a/tests/sockets/test_enet_client.c
+++ b/tests/sockets/test_enet_client.c
@@ -93,6 +93,7 @@ int main (int argc, char ** argv)
}
#if EMSCRIPTEN
+#if USE_IFRAME
emscripten_run_script("console.log('adding iframe');"
"var iframe = document.createElement('iframe');"
"iframe.src = 'server.html';"
@@ -101,6 +102,7 @@ int main (int argc, char ** argv)
"document.body.appendChild(iframe);"
"console.log('added.');");
#endif
+#endif
#if EMSCRIPTEN
emscripten_set_main_loop(main_loop, 3, 1);
diff --git a/tests/sockets/test_sockets_echo_server.c b/tests/sockets/test_sockets_echo_server.c
index 38e27cac..f01004c3 100644
--- a/tests/sockets/test_sockets_echo_server.c
+++ b/tests/sockets/test_sockets_echo_server.c
@@ -111,7 +111,7 @@ int main() {
int res;
atexit(cleanup);
- signal(SIGTERM, cleanup);
+ //signal(SIGTERM, cleanup);
memset(&server, 0, sizeof(server_t));
memset(&client, 0, sizeof(client_t));
diff --git a/tests/sockets/test_sockets_partial_server.c b/tests/sockets/test_sockets_partial_server.c
index dfe0e249..44ad40a3 100644
--- a/tests/sockets/test_sockets_partial_server.c
+++ b/tests/sockets/test_sockets_partial_server.c
@@ -38,13 +38,12 @@ void do_send(int sockfd) {
int i;
int res;
char *buffer;
- struct sockaddr_in addr;
socklen_t addrlen;
for (i = 0; i < sizeof(buffers) / sizeof(char*); i++) {
buffer = buffers[i];
- res = sendto(sockfd, buffer, strlen(buffer), 0, (struct sockaddr *)&addr, sizeof(addr));
+ res = send(sockfd, buffer, strlen(buffer), 0);
if (res == -1) {
perror("send failed");
exit(EXIT_FAILURE);
@@ -87,7 +86,7 @@ int main() {
int res;
atexit(cleanup);
- signal(SIGTERM, cleanup);
+ //signal(SIGTERM, cleanup);
// create the socket
serverfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
diff --git a/tests/sockets/test_sockets_select_server_no_accept_client.c b/tests/sockets/test_sockets_select_server_down_client.c
index e05bd4c8..e05bd4c8 100644
--- a/tests/sockets/test_sockets_select_server_no_accept_client.c
+++ b/tests/sockets/test_sockets_select_server_down_client.c
diff --git a/tests/sockets/test_sockets_select_server_no_accept_server.c b/tests/sockets/test_sockets_select_server_down_server.c
index 4a399ed1..c2e70f33 100644
--- a/tests/sockets/test_sockets_select_server_no_accept_server.c
+++ b/tests/sockets/test_sockets_select_server_down_server.c
@@ -14,38 +14,13 @@
#include <emscripten.h>
#endif
-int serverfd = -1;
-
-void iter(void *arg) {
- int res;
- fd_set fdr;
- fd_set fdw;
-
- // see if there are any connections to accept / write to
- FD_ZERO(&fdr);
- FD_ZERO(&fdw);
- FD_SET(serverfd, &fdr);
- if (clientfd != -1) FD_SET(clientfd, &fdw);
- res = select(64, &fdr, &fdw, NULL, NULL);
- if (res == -1) {
- perror("select failed");
- exit(EXIT_SUCCESS);
- }
-
- if (FD_ISSET(serverfd, &fdr)) {
- printf("accepted someone\n");
- clientfd = accept(serverfd, NULL, NULL);
- assert(clientfd != -1);
- }
-
- if (FD_ISSET(clientfd, &fdw)) {
- do_send(clientfd);
- }
+void main_loop(void *arg) {
}
int main() {
struct sockaddr_in addr;
int res;
+ int serverfd;
// create the socket
serverfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
@@ -55,7 +30,7 @@ int main() {
}
fcntl(serverfd, F_SETFL, O_NONBLOCK);
- // bind and listen to the supplied port
+ // bind to the supplied port
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(SOCKK);
@@ -70,16 +45,12 @@ int main() {
exit(EXIT_FAILURE);
}
- res = listen(serverfd, 50);
- if (res == -1) {
- perror("listen failed");
- exit(EXIT_FAILURE);
- }
+ close(serverfd);
#if EMSCRIPTEN
- emscripten_set_main_loop(iter, 60, 0);
+ emscripten_set_main_loop(main_loop, 60, 0);
#else
- while (1) iter(NULL);
+ while (1) main_loop(NULL); sleep(1);
#endif
return EXIT_SUCCESS;
diff --git a/tests/test_browser.py b/tests/test_browser.py
index 69fb6f7e..1c9cbfad 100644
--- a/tests/test_browser.py
+++ b/tests/test_browser.py
@@ -38,8 +38,6 @@ class browser(BrowserCore):
message='You should see "hello, world!" and a colored cube.')
def test_html_source_map(self):
- if 'test_html_source_map' not in str(sys.argv): return self.skip('''This test
-requires manual intervention; will not be run unless explicitly requested''')
cpp_file = os.path.join(self.get_dir(), 'src.cpp')
html_file = os.path.join(self.get_dir(), 'src.html')
# browsers will try to 'guess' the corresponding original line if a
@@ -64,14 +62,20 @@ requires manual intervention; will not be run unless explicitly requested''')
''')
# use relative paths when calling emcc, because file:// URIs can only load
# sourceContent when the maps are relative paths
+ try_delete(html_file)
+ try_delete(html_file + '.map')
Popen([PYTHON, EMCC, 'src.cpp', '-o', 'src.html', '-g4'],
cwd=self.get_dir()).communicate()
+ assert os.path.exists(html_file)
+ assert os.path.exists(html_file + '.map')
+ import webbrowser, time
webbrowser.open_new('file://' + html_file)
+ time.sleep(1)
print '''
-Set the debugger to pause on exceptions
-You should see an exception thrown at src.cpp:7.
-Press any key to continue.'''
- raw_input()
+If manually bisecting:
+ Check that you see src.cpp among the page sources.
+ Even better, add a breakpoint, e.g. on the printf, then reload, then step through and see the print (best to run with EM_SAVE_DIR=1 for the reload).
+'''
def build_native_lzma(self):
lzma_native = path_from_root('third_party', 'lzma.js', 'lzma-native')
@@ -787,6 +791,9 @@ Press any key to continue.'''
Popen([PYTHON, EMCC, os.path.join(self.get_dir(), 'sdl_mouse.c'), '-O2', '--minify', '0', '-o', 'sdl_mouse.js', '--pre-js', 'pre.js']).communicate()
self.run_browser('page.html', '', '/report_result?600')
+ def test_glut_touchevents(self):
+ self.btest('glut_touchevents.c', '1')
+
def test_sdl_pumpevents(self):
# key events should be detected using SDL_PumpEvents
open(os.path.join(self.get_dir(), 'pre.js'), 'w').write('''
@@ -798,7 +805,7 @@ Press any key to continue.'''
document.dispatchEvent(event);
}
''')
- self.btest('sdl_pumpevents.c', expected='3', args=['--pre-js', 'pre.js'])
+ self.btest('sdl_pumpevents.c', expected='7', args=['--pre-js', 'pre.js'])
def test_sdl_audio(self):
shutil.copyfile(path_from_root('tests', 'sounds', 'alarmvictory_1.ogg'), os.path.join(self.get_dir(), 'sound.ogg'))
@@ -1350,7 +1357,7 @@ Press any key to continue.'''
self.btest('perspective.c', reference='perspective.png', args=['-s', 'LEGACY_GL_EMULATION=1'])
def test_runtimelink(self):
- return self.skip('shared libs are deprecated')
+ return self.skip('BUILD_AS_SHARED_LIB=2 is deprecated')
main, supp = self.setup_runtimelink_test()
open(self.in_dir('supp.cpp'), 'w').write(supp)
diff --git a/tests/test_core.py b/tests/test_core.py
index 88f6674a..7c5b651f 100644
--- a/tests/test_core.py
+++ b/tests/test_core.py
@@ -808,6 +808,80 @@ nada
'''
self.do_run(src, ',0,,2,C!,0,C!,0,,65535,C!,0,')
+ def test_double_i64_conversion(self):
+ if Settings.USE_TYPED_ARRAYS != 2: return self.skip('needs ta2')
+
+ src = r'''
+ #include <cassert>
+ #include <inttypes.h>
+ #include <stdio.h>
+
+ __attribute((noinline)) bool eq(double d, int64_t i) {
+ int64_t i2 = (int64_t)d;
+ if (i != i2) {
+ printf("%.20g converted to int64 returns %lld, not %lld as expected!\n", d, i2, i);
+ }
+ return i == i2;
+ }
+
+ int main() {
+ assert(eq(0.0, 0));
+ assert(eq(-0.0, 0));
+ assert(eq(0.1, 0));
+ assert(eq(-0.1, 0));
+ assert(eq(0.6, 0));
+ assert(eq(-0.6, 0));
+ assert(eq(1.0, 1));
+ assert(eq(-1.0, -1));
+ assert(eq(1.1, 1));
+ assert(eq(-1.1, -1));
+ assert(eq(1.6, 1));
+ assert(eq(-1.6, -1));
+ assert(eq(4294967295.0, 4294967295LL));
+ assert(eq(4294967295.5, 4294967295LL));
+ assert(eq(4294967296.0, 4294967296LL));
+ assert(eq(4294967296.5, 4294967296LL));
+ assert(eq(14294967295.0, 14294967295LL));
+ assert(eq(14294967295.5, 14294967295LL));
+ assert(eq(14294967296.0, 14294967296LL));
+ assert(eq(14294967296.5, 14294967296LL));
+ assert(eq(-4294967295.0, -4294967295LL));
+ assert(eq(-4294967295.5, -4294967295LL));
+ assert(eq(-4294967296.0, -4294967296LL));
+ assert(eq(-4294967296.5, -4294967296LL));
+ assert(eq(-14294967295.0, -14294967295LL));
+ assert(eq(-14294967295.5, -14294967295LL));
+ assert(eq(-14294967296.0, -14294967296LL));
+ assert(eq(-14294967296.5, -14294967296LL));
+
+ assert(eq(4294967295.3, 4294967295LL));
+ assert(eq(4294967296.3, 4294967296LL));
+ assert(eq(14294967295.3, 14294967295LL));
+ assert(eq(14294967296.3, 14294967296LL));
+ assert(eq(-4294967295.3, -4294967295LL));
+ assert(eq(-4294967296.3, -4294967296LL));
+ assert(eq(-14294967295.3, -14294967295LL));
+ assert(eq(-14294967296.3, -14294967296LL));
+
+ assert(eq(4294967295.8, 4294967295LL));
+ assert(eq(4294967296.8, 4294967296LL));
+ assert(eq(14294967295.8, 14294967295LL));
+ assert(eq(14294967296.8, 14294967296LL));
+ assert(eq(-4294967295.8, -4294967295LL));
+ assert(eq(-4294967296.8, -4294967296LL));
+ assert(eq(-14294967295.8, -14294967295LL));
+ assert(eq(-14294967296.8, -14294967296LL));
+
+ // The following number is the largest double such that all integers smaller than this can exactly be represented in a double.
+ assert(eq(9007199254740992.0, 9007199254740992LL /* == 2^53 */));
+ assert(eq(-9007199254740992.0, -9007199254740992LL /* == -2^53 */));
+
+ printf("OK!\n");
+ return 0;
+ }
+ '''
+ self.do_run(src, 'OK!\n');
+
def test_negative_zero(self):
src = r'''
#include <stdio.h>
@@ -3678,7 +3752,7 @@ def process(filename):
}
'''
- self.do_run(src, 'Inline JS is very cool\n3.64')
+ self.do_run(src, 'Inline JS is very cool\n3.64\n')
def test_inlinejs2(self):
if Settings.ASM_JS: return self.skip('asm does not support random code, TODO: something that works in asm')
@@ -3705,6 +3779,27 @@ def process(filename):
self.do_run(src, '4\n200\n')
+ def test_inlinejs3(self):
+ if Settings.ASM_JS: return self.skip('asm does not support random code, TODO: something that works in asm')
+ src = r'''
+ #include <stdio.h>
+ #include <emscripten.h>
+
+ int main() {
+ EM_ASM(Module.print('hello dere1'));
+ EM_ASM(
+ Module.print('hello dere2');
+ );
+ EM_ASM(
+ Module.print('hello dere3');
+ Module.print('hello dere' + 4);
+ );
+ return 0;
+ }
+ '''
+
+ self.do_run(src, 'hello dere1\nhello dere2\nhello dere3\nhello dere4\n')
+
def test_memorygrowth(self):
if Settings.USE_TYPED_ARRAYS == 0: return self.skip('memory growth is only supported with typed arrays')
if Settings.ASM_JS: return self.skip('asm does not support memory growth yet')
@@ -3861,8 +3956,7 @@ def process(filename):
self.do_run(src, 'Hello world!')
def test_bigswitch(self):
- if Settings.RELOOP: return self.skip('TODO: switch in relooper, issue #781')
- if Settings.ASM_JS: return self.skip('TODO: switch too large for asm')
+ if self.run_name != 'default': return self.skip('TODO: issue #781')
src = open(path_from_root('tests', 'bigswitch.cpp')).read()
self.do_run(src, '''34962: GL_ARRAY_BUFFER (0x8892)
@@ -4570,6 +4664,12 @@ The current type of b is: 9
'''
self.do_run(src, 'BA')
+ def test_pthread_specific(self):
+ if self.emcc_args is None: return self.skip('requires emcc')
+ src = open(path_from_root('tests', 'pthread', 'specific.c'), 'r').read()
+ expected = open(path_from_root('tests', 'pthread', 'specific.c.txt'), 'r').read()
+ self.do_run(src, expected, force_c=True)
+
def test_time(self):
# XXX Not sure what the right output is here. Looks like the test started failing with daylight savings changes. Modified it to pass again.
src = open(path_from_root('tests', 'time', 'src.c'), 'r').read()
@@ -5451,7 +5551,7 @@ The current type of b is: 9
self.do_run(src, '*16,0,4,8,8,12|20,0,4,4,8,12,12,16|24,0,20,0,4,4,8,12,12,16*\n*0,0,0,1,2,64,68,69,72*\n*2*')
def test_runtimelink(self):
- return self.skip('shared libs are deprecated')
+ return self.skip('BUILD_AS_SHARED_LIB=2 is deprecated')
if Building.LLVM_OPTS: return self.skip('LLVM opts will optimize printf into puts in the parent, and the child will still look for puts')
if Settings.ASM_JS: return self.skip('asm does not support runtime linking')
@@ -5470,11 +5570,9 @@ The current type of b is: 9
self.do_run(main, 'supp: 54,2\nmain: 56\nsupp see: 543\nmain see: 76\nok.')
def test_dlfcn_basic(self):
- return self.skip('shared libs are deprecated')
if Settings.ASM_JS: return self.skip('TODO: dlopen in asm')
Settings.NAMED_GLOBALS = 1
- Settings.LINKABLE = 1
lib_src = '''
#include <cstdio>
@@ -5525,7 +5623,6 @@ def process(filename):
post_build=add_pre_run_and_checks)
def test_dlfcn_qsort(self):
- return self.skip('shared libs are deprecated')
if self.emcc_args is None: return self.skip('requires emcc')
if Settings.ASM_JS: return self.skip('TODO: dlopen in asm')
@@ -5622,7 +5719,6 @@ def process(filename):
post_build=add_pre_run_and_checks)
def test_dlfcn_data_and_fptr(self):
- return self.skip('shared libs are deprecated')
if Settings.ASM_JS: return self.skip('TODO: dlopen in asm')
if Building.LLVM_OPTS: return self.skip('LLVM opts will optimize out parent_func')
@@ -5727,7 +5823,6 @@ def process(filename):
post_build=add_pre_run_and_checks)
def test_dlfcn_alias(self):
- return self.skip('shared libs are deprecated')
if Settings.ASM_JS: return self.skip('TODO: dlopen in asm')
Settings.LINKABLE = 1
@@ -5785,7 +5880,6 @@ def process(filename):
Settings.INCLUDE_FULL_LIBRARY = 0
def test_dlfcn_varargs(self):
- return self.skip('shared libs are deprecated')
if Settings.ASM_JS: return self.skip('TODO: dlopen in asm')
Settings.LINKABLE = 1
@@ -6673,6 +6767,7 @@ date: 18.07.2013w; day 18, month 7, year 2013, extra: 201, 3
def test_files(self):
if self.emcc_args is not None and '-O2' in self.emcc_args:
self.emcc_args += ['--closure', '1'] # Use closure here, to test we don't break FS stuff
+ self.emcc_args = filter(lambda x: x != '-g', self.emcc_args) # ensure we test --closure 1 --memory-init-file 1 (-g would disable closure)
Settings.CORRECT_SIGNS = 1 # Just so our output is what we expect. Can flip them both.
post = '''
@@ -6699,8 +6794,13 @@ def process(filename):
other.close()
src = open(path_from_root('tests', 'files.cpp'), 'r').read()
+
+ mem_file = 'src.cpp.o.js.mem'
+ try_delete(mem_file)
self.do_run(src, ('size: 7\ndata: 100,-56,50,25,10,77,123\nloop: 100 -56 50 25 10 77 123 \ninput:hi there!\ntexto\n$\n5 : 10,30,20,11,88\nother=some data.\nseeked=me da.\nseeked=ata.\nseeked=ta.\nfscanfed: 10 - hello\nok.\ntexte\n', 'size: 7\ndata: 100,-56,50,25,10,77,123\nloop: 100 -56 50 25 10 77 123 \ninput:hi there!\ntexto\ntexte\n$\n5 : 10,30,20,11,88\nother=some data.\nseeked=me da.\nseeked=ata.\nseeked=ta.\nfscanfed: 10 - hello\nok.\n'),
post_build=post, extra_emscripten_args=['-H', 'libc/fcntl.h'])
+ if self.emcc_args and '--memory-init-file' in self.emcc_args:
+ assert os.path.exists(mem_file)
def test_files_m(self):
# Test for Module.stdin etc.
@@ -7036,14 +7136,15 @@ def process(filename):
#include <emscripten.h>
int main() {
- char *c = "μ†ℱ ╋ℯ╳╋";
+ char *c = "μ†ℱ ╋ℯ╳╋ 😇";
printf("%d %d %d %d %s\n", c[0]&0xff, c[1]&0xff, c[2]&0xff, c[3]&0xff, c);
- emscripten_run_script("cheez = _malloc(100);"
- "Module.writeStringToMemory(\"μ†ℱ ╋ℯ╳╋\", cheez);"
- "Module.print([Pointer_stringify(cheez), Module.getValue(cheez, 'i8')&0xff, Module.getValue(cheez+1, 'i8')&0xff, Module.getValue(cheez+2, 'i8')&0xff, Module.getValue(cheez+3, 'i8')&0xff, ]);");
+ emscripten_run_script(
+ "cheez = _malloc(100);"
+ "Module.writeStringToMemory(\"μ†ℱ ╋ℯ╳╋ 😇\", cheez);"
+ "Module.print([Pointer_stringify(cheez), Module.getValue(cheez, 'i8')&0xff, Module.getValue(cheez+1, 'i8')&0xff, Module.getValue(cheez+2, 'i8')&0xff, Module.getValue(cheez+3, 'i8')&0xff, ]);");
}
'''
- self.do_run(src, '206 188 226 128 μ†ℱ ╋ℯ╳╋\nμ†ℱ ╋ℯ╳╋,206,188,226,128\n');
+ self.do_run(src, '206 188 226 128 μ†ℱ ╋ℯ╳╋ 😇\nμ†ℱ ╋ℯ╳╋ 😇,206,188,226,128\n');
def test_direct_string_constant_usage(self):
if self.emcc_args is None: return self.skip('requires libcxx')
@@ -8232,13 +8333,15 @@ def process(filename):
shutil.copyfile(path_from_root('tests', 'freetype', 'LiberationSansBold.ttf'), os.path.join(self.get_dir(), 'font.ttf'))
# Main
- self.do_run(open(path_from_root('tests', 'freetype', 'main.c'), 'r').read(),
- open(path_from_root('tests', 'freetype', 'ref.txt'), 'r').read(),
- ['font.ttf', 'test!', '150', '120', '25'],
- libraries=self.get_freetype(),
- includes=[path_from_root('tests', 'freetype', 'include')],
- post_build=post)
- #build_ll_hook=self.do_autodebug)
+ for outlining in [0, 5000]:
+ Settings.OUTLINING_LIMIT = outlining
+ print >> sys.stderr, 'outlining:', outlining
+ self.do_run(open(path_from_root('tests', 'freetype', 'main.c'), 'r').read(),
+ open(path_from_root('tests', 'freetype', 'ref.txt'), 'r').read(),
+ ['font.ttf', 'test!', '150', '120', '25'],
+ libraries=self.get_freetype(),
+ includes=[path_from_root('tests', 'freetype', 'include')],
+ post_build=post)
# github issue 324
print '[issue 324]'
@@ -10071,4 +10174,4 @@ for compiler, quantum, embetter, typed_arrays in [
)
locals()[fullname] = make_run(fullname, fullname, compiler, embetter, quantum, typed_arrays)
-del T # T is just a shape for the specific subclasses, we don't test it itself \ No newline at end of file
+del T # T is just a shape for the specific subclasses, we don't test it itself
diff --git a/tests/test_other.py b/tests/test_other.py
index b3e8a2a1..a6813b07 100644
--- a/tests/test_other.py
+++ b/tests/test_other.py
@@ -330,27 +330,6 @@ f.close()
os.chdir(path_from_root('tests')) # Move away from the directory we are about to remove.
shutil.rmtree(tempdirname)
- def test_nostdincxx(self):
- try:
- old = os.environ.get('EMCC_LLVM_TARGET') or ''
- for compiler in [EMCC, EMXX]:
- for target in ['i386-pc-linux-gnu', 'le32-unknown-nacl']:
- print compiler, target
- os.environ['EMCC_LLVM_TARGET'] = target
- out, err = Popen([PYTHON, EMCC, path_from_root('tests', 'hello_world.cpp'), '-v'], stdout=PIPE, stderr=PIPE).communicate()
- out2, err2 = Popen([PYTHON, EMCC, path_from_root('tests', 'hello_world.cpp'), '-v', '-nostdinc++'], stdout=PIPE, stderr=PIPE).communicate()
- assert out == out2
- def focus(e):
- assert 'search starts here:' in e, e
- assert e.count('End of search list.') == 1, e
- return e[e.index('search starts here:'):e.index('End of search list.')+20]
- err = focus(err)
- err2 = focus(err2)
- assert err == err2, err + '\n\n\n\n' + err2
- finally:
- if old:
- os.environ['EMCC_LLVM_TARGET'] = old
-
def test_failure_error_code(self):
for compiler in [EMCC, EMXX]:
# Test that if one file is missing from the build, then emcc shouldn't succeed, and shouldn't try to produce an output file.
@@ -802,8 +781,8 @@ f.close()
for test_opts, expected_ranges in [
([], {
- 100: (190, 250),
- 250: (200, 330),
+ 100: (190, 275),
+ 250: (200, 500),
500: (250, 500),
1000: (230, 1000),
2000: (380, 2000),
@@ -1033,7 +1012,7 @@ int main(int argc, char const *argv[])
self.assertContained('hello from lib', run_js(os.path.join(self.get_dir(), 'a.out.js')))
def test_runtimelink_multi(self):
- return self.skip('shared libs are deprecated')
+ return self.skip('BUILD_AS_SHARED_LIB=2 is deprecated')
if Settings.ASM_JS: return self.skip('asm does not support runtime linking yet')
if SPIDERMONKEY_ENGINE not in JS_ENGINES: return self.skip('cannot run without spidermonkey due to node limitations')
@@ -1902,7 +1881,7 @@ seeked= file.
if SPIDERMONKEY_ENGINE not in JS_ENGINES: return self.skip('cannot run without spidermonkey due to node limitations (Uint8ClampedArray etc.)')
shutil.copyfile(path_from_root('tests', 'screenshot.png'), os.path.join(self.get_dir(), 'example.png'))
- Popen([PYTHON, EMCC, path_from_root('tests', 'sdl_canvas.c'), '-s', 'HEADLESS=1']).communicate()
+ Popen([PYTHON, EMCC, path_from_root('tests', 'sdl_headless.c'), '-s', 'HEADLESS=1']).communicate()
output = run_js('a.out.js', engine=SPIDERMONKEY_ENGINE, stderr=PIPE)
assert '''Init: 0
Font: 0x1
diff --git a/tests/test_sanity.py b/tests/test_sanity.py
index 931645e2..4188afff 100644
--- a/tests/test_sanity.py
+++ b/tests/test_sanity.py
@@ -519,4 +519,29 @@ fi
finally:
del os.environ['EMCC_DEBUG']
- del os.environ['EMCC_JSOPT_MIN_CHUNK_SIZE'] \ No newline at end of file
+ del os.environ['EMCC_JSOPT_MIN_CHUNK_SIZE']
+
+ def test_nostdincxx(self):
+ restore()
+ Cache.erase()
+
+ try:
+ old = os.environ.get('EMCC_LLVM_TARGET') or ''
+ for compiler in [EMCC, EMXX]:
+ for target in ['i386-pc-linux-gnu', 'le32-unknown-nacl']:
+ print compiler, target
+ os.environ['EMCC_LLVM_TARGET'] = target
+ out, err = Popen([PYTHON, EMCC, path_from_root('tests', 'hello_world.cpp'), '-v'], stdout=PIPE, stderr=PIPE).communicate()
+ out2, err2 = Popen([PYTHON, EMCC, path_from_root('tests', 'hello_world.cpp'), '-v', '-nostdinc++'], stdout=PIPE, stderr=PIPE).communicate()
+ assert out == out2
+ def focus(e):
+ assert 'search starts here:' in e, e
+ assert e.count('End of search list.') == 1, e
+ return e[e.index('search starts here:'):e.index('End of search list.')+20]
+ err = focus(err)
+ err2 = focus(err2)
+ assert err == err2, err + '\n\n\n\n' + err2
+ finally:
+ if old:
+ os.environ['EMCC_LLVM_TARGET'] = old
+
diff --git a/tests/test_sockets.py b/tests/test_sockets.py
index 4f6ee2a9..82ddc6fe 100644
--- a/tests/test_sockets.py
+++ b/tests/test_sockets.py
@@ -142,11 +142,12 @@ class sockets(BrowserCore):
# def test_sockets_gethostbyname(self):
# self.btest(os.path.join('sockets', 'test_sockets_gethostbyname.c'), expected='0', args=['-O2', '-DSOCKK=8997'])
- def test_sockets_select_server_no_accept(self):
+ def test_sockets_select_server_down(self):
for harness in [
- WebsockifyServerHarness(os.path.join('sockets', 'test_sockets_select_server_no_accept_server.c'), ['-DSOCKK=8995'], 8996, 8995)
+ WebsockifyServerHarness(os.path.join('sockets', 'test_sockets_select_server_down_server.c'), ['-DSOCKK=9002'], 9003, 9002)
]:
- self.btest(os.path.join('sockets', 'test_sockets_select_server_no_accept_client.c'), expected='266', args=['-DSOCKK=8996'])
+ with harness:
+ self.btest(os.path.join('sockets', 'test_sockets_select_server_down_client.c'), expected='266', args=['-DSOCKK=9003'])
def test_sockets_select_server_closes_connection_rw(self):
sockets_include = '-I'+path_from_root('tests', 'sockets')
@@ -178,7 +179,7 @@ class sockets(BrowserCore):
try:
proc = make_relay_server(2234, 2236)
pids.append(proc.pid)
- self.btest(os.path.join('sockets', 'test_enet_client.c'), expected='0', args=['-DSOCKK=2237'] + enet)
+ self.btest(os.path.join('sockets', 'test_enet_client.c'), expected='0', args=['-DSOCKK=2237', '-DUSE_IFRAME'] + enet)
finally:
clean_pids(pids);
diff --git a/tests/tex_nonbyte.c b/tests/tex_nonbyte.c
index 8f2ec162..960d0efb 100644
--- a/tests/tex_nonbyte.c
+++ b/tests/tex_nonbyte.c
@@ -37,6 +37,7 @@ REDISTRIBUTION OF THIS SOFTWARE.
#endif
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#include <assert.h>
diff --git a/tests/unistd/misc.out b/tests/unistd/misc.out
index 43971955..8f03f688 100644
--- a/tests/unistd/misc.out
+++ b/tests/unistd/misc.out
@@ -44,3 +44,10 @@ setgid: -1, errno: 1
setegid: -1, errno: 1
setuid: -1, errno: 1
seteuid: -1, errno: 1
+setpgrp: -1, errno: 1
+setsid: -1, errno: 1
+setpgid: -1, errno: 1
+setregid: -1, errno: 1
+setreuid: -1, errno: 1
+getgroups: 1, result: 0, errno: 0
+setgroups: -1, errno: 1
diff --git a/tools/file_packager.py b/tools/file_packager.py
index 33ccebad..bb62e905 100644
--- a/tools/file_packager.py
+++ b/tools/file_packager.py
@@ -329,13 +329,55 @@ if has_preloaded:
# Data requests - for getting a block of data out of the big archive - have a similar API to XHRs
code += '''
- function DataRequest() {}
+ function DataRequest(start, end, crunched, audio) {
+ this.start = start;
+ this.end = end;
+ this.crunched = crunched;
+ this.audio = audio;
+ }
DataRequest.prototype = {
requests: {},
open: function(mode, name) {
+ this.name = name;
this.requests[name] = this;
+ Module['addRunDependency']('fp ' + this.name);
+ },
+ send: function() {},
+ onload: function() {
+ var data = this.byteArray.subarray(this.start, this.end);
+ var size = this.end - this.start;
+ var ptr = Module['_malloc'](size); // XXX leaked if a preload plugin replaces with new data
+ Module['HEAPU8'].set(data, ptr);
+ var arrayBuffer = Module['HEAPU8'].subarray(ptr, ptr + size);
+ assert(arrayBuffer, 'Loading file ' + name + ' failed');
+ var byteArray = !arrayBuffer.subarray ? new Uint8Array(arrayBuffer) : arrayBuffer;
+
+ if (this.crunched) {
+ var ddsHeader = byteArray.subarray(0, 128);
+ var that = this;
+ requestDecrunch(this.name, byteArray.subarray(128), function(ddsData) {
+ byteArray = new Uint8Array(ddsHeader.length + ddsData.length);
+ byteArray.set(ddsHeader, 0);
+ byteArray.set(ddsData, 128);
+ that.finish(byteArray);
+ });
+ } else {
+ this.finish(byteArray);
+ }
+ },
+ finish: function(byteArray) {
+ var that = this;
+ Module['FS_createPreloadedFile'](PATH.dirname(this.name), PATH.basename(this.name), byteArray, true, true, function() {
+ Module['removeRunDependency']('fp ' + that.name);
+ }, function() {
+ if (that.audio) {
+ Module['removeRunDependency']('fp ' + that.name); // workaround for chromium bug 124926 (still no audio with this, but at least we don't hang)
+ } else {
+ Runtime.warn('Preloading file ' + that.name + ' failed');
+ }
+ });
+ this.requests[this.name] = null;
},
- send: function() {}
};
'''
@@ -364,66 +406,23 @@ for file_ in data_files:
# Preload
varname = 'filePreload%d' % counter
counter += 1
- dds = crunch and filename.endswith(CRUNCH_INPUT_SUFFIX)
-
- prepare = ''
- finish = "Module['removeRunDependency']('fp %s');\n" % filename
-
- if dds:
- # decompress crunch format into dds
- prepare = '''
- var ddsHeader = byteArray.subarray(0, %(dds_header_size)d);
- requestDecrunch('%(filename)s', byteArray.subarray(%(dds_header_size)d), function(ddsData) {
- byteArray = new Uint8Array(ddsHeader.length + ddsData.length);
- byteArray.set(ddsHeader, 0);
- byteArray.set(ddsData, %(dds_header_size)d);
-''' % { 'filename': filename, 'dds_header_size': DDS_HEADER_SIZE }
-
- finish += '''
- });
-'''
-
- code += '''
- var %(varname)s = new %(request)s();
- %(varname)s.open('GET', '%(filename)s', true);
- %(varname)s.responseType = 'arraybuffer';
- %(varname)s.onload = function() {
- var arrayBuffer = %(varname)s.response;
- assert(arrayBuffer, 'Loading file %(filename)s failed.');
- var byteArray = !arrayBuffer.subarray ? new Uint8Array(arrayBuffer) : arrayBuffer;
- %(prepare)s
- Module['FS_createPreloadedFile']('%(dirname)s', '%(basename)s', byteArray, true, true, function() {
- %(finish)s
- }%(fail)s);
- };
- Module['addRunDependency']('fp %(filename)s');
- %(varname)s.send(null);
+ code += ''' new DataRequest(%(start)d, %(end)d, %(crunched)s, %(audio)s).open('GET', '%(filename)s');
''' % {
- 'request': 'DataRequest', # In the past we also supported XHRs here
- 'varname': varname,
- 'filename': filename,
- 'dirname': dirname,
- 'basename': basename,
- 'prepare': prepare,
- 'finish': finish,
- 'fail': '' if filename[-4:] not in AUDIO_SUFFIXES else ''', function() { Module['removeRunDependency']('fp %s') }''' % filename # workaround for chromium bug 124926 (still no audio with this, but at least we don't hang)
- }
+ 'filename': file_['dstpath'],
+ 'start': file_['data_start'],
+ 'end': file_['data_end'],
+ 'crunched': '1' if crunch and filename.endswith(CRUNCH_INPUT_SUFFIX) else '0',
+ 'audio': '1' if filename[-4:] in AUDIO_SUFFIXES else '0',
+ }
else:
assert 0
if has_preloaded:
# Get the big archive and split it up
- use_data = ''
+ use_data = ' DataRequest.prototype.byteArray = byteArray;\n'
for file_ in data_files:
if file_['mode'] == 'preload':
- use_data += '''
- curr = DataRequest.prototype.requests['%s'];
- var data = byteArray.subarray(%d, %d);
- var ptr = Module['_malloc'](%d);
- Module['HEAPU8'].set(data, ptr);
- curr.response = Module['HEAPU8'].subarray(ptr, ptr + %d);
- curr.onload();
- ''' % (file_['dstpath'], file_['data_start'], file_['data_end'], file_['data_end'] - file_['data_start'], file_['data_end'] - file_['data_start'])
+ use_data += ' DataRequest.prototype.requests["%s"].onload();\n' % (file_['dstpath'])
use_data += " Module['removeRunDependency']('datafile_%s');\n" % data_target
if Compression.on:
diff --git a/tools/js-optimizer.js b/tools/js-optimizer.js
index e61317af..9a5104bf 100644
--- a/tools/js-optimizer.js
+++ b/tools/js-optimizer.js
@@ -1236,7 +1236,7 @@ function vacuum(ast) {
}
} break;
case 'label': {
- if (node[2][0] === 'toplevel' && (!node[2][1] || node[2][1].length === 0)) {
+ if (node[2] && node[2][0] === 'toplevel' && (!node[2][1] || node[2][1].length === 0)) {
return emptyNode();
}
} break;
@@ -3026,58 +3026,90 @@ function outline(ast) {
if (ignore.indexOf(node) >= 0) continue;
var type = node[0];
if (measureSize(node) >= minSize) {
- if (type === 'if' && node[3]) {
+ if ((type === 'if' && node[3]) || type === 'switch') {
+ var isIf = type === 'if';
var reps = [];
var helper = getHelper();
// clear helper
reps.push(['stat', ['assign', true, ['name', helper], ['num', 1]]]); // 1 means continue in ifs
// gather parts
- var parts = [];
- var curr = node;
- while (1) {
- parts.push({ condition: curr[1], body: curr[2] });
- curr = curr[3];
- if (!curr) break;
- if (curr[0] != 'if') {
- parts.push({ condition: null, body: curr });
- break;
+ var parts;
+ if (isIf) {
+ parts = [];
+ var curr = node;
+ while (1) {
+ parts.push({ condition: curr[1], body: curr[2] });
+ curr = curr[3];
+ if (!curr) break;
+ if (curr[0] != 'if') {
+ parts.push({ condition: null, body: curr });
+ break;
+ }
}
+ } else { // switch
+ var switchVar = getHelper(); // switch var could be an expression
+ reps.push(['stat', ['assign', true, ['name', switchVar], node[1]]]);
+ parts = node[2].map(function(case_) {
+ return { condition: case_[0], body: case_[1] };
+ });
}
// chunkify. Each chunk is a chain of if-elses, with the new overhead just on entry and exit
var chunks = [];
var currSize = 0;
var currChunk = [];
+ var force = false; // when we hit a case X: that falls through, we force inclusion of everything until a full case
parts.forEach(function(part) {
var size = (part.condition ? measureSize(part.condition) : 0) + measureSize(part.body) + 5; // add constant for overhead of extra code
assert(size > 0);
- if (size + currSize >= minSize && currSize) {
+ if (size + currSize >= minSize && currSize && !force) {
chunks.push(currChunk);
currChunk = [];
currSize = 0;
}
currChunk.push(part);
currSize += size;
+ if (!isIf) {
+ var last = part.body;
+ last = last[stats.length-1];
+ if (last && last[0] === 'block') last = last[1][last[1].length-1];
+ if (last && last[0] === 'stat') last = last[1];
+ force = !last || last[0] !== 'break';
+ }
});
assert(currSize);
chunks.push(currChunk);
// generate flattened code
chunks.forEach(function(chunk) {
var pre = ['stat', ['assign', true, ['name', helper], ['num', 0]]];
- var chain = null, tail = null;
- chunk.forEach(function(part) {
- // add to chain
- var contents = makeIf(part.condition || ['num', 1], part.body[1]);
- if (chain) {
- tail[3] = contents;
- } else {
- chain = contents;
- ignore.push(contents);
+ if (isIf) {
+ var chain = null, tail = null;
+ chunk.forEach(function(part) {
+ // add to chain
+ var contents = makeIf(part.condition || ['num', 1], part.body[1]);
+ if (chain) {
+ tail[3] = contents;
+ } else {
+ chain = contents;
+ ignore.push(contents);
+ }
+ tail = contents;
+ });
+ // if none of the ifs were entered, in the final else note that we need to continue
+ tail[3] = ['block', [['stat', ['assign', true, ['name', helper], ['num', 1]]]]];
+ reps.push(makeIf(['name', helper], [pre, chain]));
+ } else { // switch
+ var hasDefault;
+ var s = makeSwitch(['binary', '|', ['name', switchVar], ['num', 0]], chunk.map(function(part) {
+ hasDefault = hasDefault || part.condition === null;
+ return [part.condition, part.body];
+ }));
+ // if no default, add one where we note that we need to continue
+ if (!hasDefault) {
+ s[2].push([null, [['block', [['stat', ['assign', true, ['name', helper], ['num', 1]]]]]]]);
}
- tail = contents;
- });
- // if none of the ifs were entered, in the final else note that we need to continue
- tail[3] = ['block', [['stat', ['assign', true, ['name', helper], ['num', 1]]]]];
- reps.push(makeIf(['name', helper], [pre, chain]));
+ ignore.push(s);
+ reps.push(makeIf(['name', helper], [pre, s]));
+ }
});
// replace code and update i
stats.splice.apply(stats, [i, 1].concat(reps));
@@ -3091,6 +3123,8 @@ function outline(ast) {
});
}
+ var maxTotalOutlinings = Infinity; // debugging tool
+
// Prepares information for spilling of local variables
function analyzeFunction(func, asmData) {
var stack = []; // list of variables, each gets 8 bytes
@@ -3110,7 +3144,7 @@ function outline(ast) {
// The control variables are zeroed out when calling an outlined function, and after using
// the value after they return.
var size = measureSize(func);
- asmData.maxOutlinings = Math.round(3*size/extraInfo.sizeToOutline);
+ asmData.maxOutlinings = Math.min(Math.round(3*size/extraInfo.sizeToOutline), maxTotalOutlinings);
asmData.intendedPieces = Math.ceil(size/extraInfo.sizeToOutline);
asmData.totalStackSize = stackSize + (stack.length + 2*asmData.maxOutlinings)*8;
asmData.controlStackPos = function(i) { return stackSize + (stack.length + i)*8 };
@@ -3440,6 +3474,7 @@ function outline(ast) {
asmData.splitCounter--;
return [];
}
+ maxTotalOutlinings--;
for (var v in owned) {
if (v != 'sp') delete asmData.vars[v]; // parent does not need these anymore
}
@@ -3596,6 +3631,8 @@ function outline(ast) {
var funcs = ast[1];
+ var maxTotalFunctions = Infinity; // debugging tool
+
var more = true;
while (more) {
more = false;
@@ -3603,9 +3640,11 @@ function outline(ast) {
var newFuncs = [];
funcs.forEach(function(func) {
+ vacuum(func); // clear out empty nodes that affect code size
var asmData = normalizeAsm(func);
var size = measureSize(func);
- if (size >= extraInfo.sizeToOutline) {
+ if (size >= extraInfo.sizeToOutline && maxTotalFunctions > 0) {
+ maxTotalFunctions--;
aggressiveVariableElimination(func, asmData);
flatten(func, asmData);
analyzeFunction(func, asmData);
diff --git a/tools/js_optimizer.py b/tools/js_optimizer.py
index acb87460..5d7dc562 100644
--- a/tools/js_optimizer.py
+++ b/tools/js_optimizer.py
@@ -224,6 +224,10 @@ EMSCRIPTEN_FUNCS();
total_size = len(js)
js = None
+ if 'last' in passes and len(funcs) > 0:
+ if max([len(func[1]) for func in funcs]) > 200000:
+ print >> sys.stderr, 'warning: Output contains some very large functions, consider using OUTLINING_LIMIT to break them up (see settings.js)'
+
# if we are making source maps, we want our debug numbering to start from the
# top of the file, so avoid breaking the JS into chunks
cores = 1 if source_map else int(os.environ.get('EMCC_CORES') or multiprocessing.cpu_count())
diff --git a/tools/jsrun.py b/tools/jsrun.py
index 27c55350..571e9cee 100644
--- a/tools/jsrun.py
+++ b/tools/jsrun.py
@@ -15,7 +15,7 @@ def timeout_run(proc, timeout, note='unnamed process', full_output=False):
def run_js(filename, engine=None, args=[], check_timeout=False, stdout=PIPE, stderr=None, cwd=None, full_output=False):
if type(engine) is not list:
engine = [engine]
- command = engine + [filename] + (['--'] if 'd8' in engine[0] else []) + args
+ command = engine + [filename] + (['--'] if 'd8' in engine[0] or 'jsc' in engine[0] else []) + args
return timeout_run(
Popen(
command,
diff --git a/tools/shared.py b/tools/shared.py
index 0d0f20d4..3ee5db23 100644
--- a/tools/shared.py
+++ b/tools/shared.py
@@ -290,7 +290,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.5.5'
+EMSCRIPTEN_VERSION = '1.5.6'
def generate_sanity():
return EMSCRIPTEN_VERSION + '|' + get_llvm_target() + '|' + LLVM_ROOT
diff --git a/tools/test-js-optimizer-asm-outline1-output.js b/tools/test-js-optimizer-asm-outline1-output.js
index d8ea9446..895004d8 100644
--- a/tools/test-js-optimizer-asm-outline1-output.js
+++ b/tools/test-js-optimizer-asm-outline1-output.js
@@ -321,6 +321,48 @@ function chain() {
helper$0 = HEAP32[sp + 8 >> 2] | 0;
STACKTOP = sp;
}
+function switchh() {
+ var helper$0 = 0, helper$1 = 0, sp = 0;
+ sp = STACKTOP;
+ STACKTOP = STACKTOP + 296 | 0;
+ helper$0 = 1;
+ helper$1 = x;
+ if (helper$0) {
+ helper$0 = 0;
+ switch (helper$1 | 0) {
+ case 0:
+ {
+ f(0);
+ g();
+ break;
+ }
+ default:
+ {
+ helper$0 = 1;
+ }
+ }
+ }
+ HEAP32[sp + 8 >> 2] = helper$0;
+ HEAP32[sp + 16 >> 2] = helper$1;
+ HEAP32[sp + 40 >> 2] = 0;
+ HEAP32[sp + 44 >> 2] = 0;
+ switchh$2(sp);
+ helper$0 = HEAP32[sp + 8 >> 2] | 0;
+ HEAP32[sp + 8 >> 2] = helper$0;
+ HEAP32[sp + 16 >> 2] = helper$1;
+ HEAP32[sp + 32 >> 2] = 0;
+ HEAP32[sp + 36 >> 2] = 0;
+ switchh$1(sp);
+ helper$0 = HEAP32[sp + 8 >> 2] | 0;
+ if (helper$0) {
+ helper$0 = 0;
+ HEAP32[sp + 16 >> 2] = helper$1;
+ HEAP32[sp + 24 >> 2] = 0;
+ HEAP32[sp + 28 >> 2] = 0;
+ switchh$0(sp);
+ }
+ STACKTOP = sp;
+}
function lin$0(sp) {
sp = sp | 0;
c(14);
@@ -645,4 +687,98 @@ function chain$4(sp) {
}
HEAP32[sp + 8 >> 2] = helper$0;
}
+function switchh$0(sp) {
+ sp = sp | 0;
+ var helper$1 = 0;
+ helper$1 = HEAP32[sp + 16 >> 2] | 0;
+ switch (helper$1 | 0) {
+ case 4:
+ {
+ f(4);
+ g();
+ }
+ case 5:
+ {
+ f(5);
+ g();
+ }
+ case 6:
+ {
+ f(6);
+ g();
+ }
+ default:
+ {
+ print(9);
+ }
+ }
+}
+function switchh$1(sp) {
+ sp = sp | 0;
+ var helper$0 = 0, helper$1 = 0;
+ helper$0 = HEAP32[sp + 8 >> 2] | 0;
+ helper$1 = HEAP32[sp + 16 >> 2] | 0;
+ if (helper$0) {
+ helper$0 = 0;
+ switch (helper$1 | 0) {
+ case 21:
+ case 22:
+ case 23:
+ case 24:
+ case 25:
+ case 26:
+ case 27:
+ case 28:
+ case 29:
+ case 3:
+ {
+ f(3);
+ g();
+ break;
+ }
+ default:
+ {
+ helper$0 = 1;
+ }
+ }
+ }
+ HEAP32[sp + 8 >> 2] = helper$0;
+}
+function switchh$2(sp) {
+ sp = sp | 0;
+ var helper$0 = 0, helper$1 = 0;
+ helper$0 = HEAP32[sp + 8 >> 2] | 0;
+ helper$1 = HEAP32[sp + 16 >> 2] | 0;
+ if (helper$0) {
+ helper$0 = 0;
+ switch (helper$1 | 0) {
+ case 1:
+ {
+ f(1);
+ g();
+ break;
+ }
+ default:
+ {
+ helper$0 = 1;
+ }
+ }
+ }
+ if (helper$0) {
+ helper$0 = 0;
+ switch (helper$1 | 0) {
+ case 2:
+ {
+ f(2);
+ g();
+ break;
+ }
+ default:
+ {
+ helper$0 = 1;
+ }
+ }
+ }
+ HEAP32[sp + 8 >> 2] = helper$0;
+}
diff --git a/tools/test-js-optimizer-asm-outline1.js b/tools/test-js-optimizer-asm-outline1.js
index 311cb206..3c454182 100644
--- a/tools/test-js-optimizer-asm-outline1.js
+++ b/tools/test-js-optimizer-asm-outline1.js
@@ -259,5 +259,53 @@ function chain() {
print(99);
}
}
+function switchh() {
+ switch (x) {
+ case 0: {
+ f(0);
+ g();
+ break;
+ }
+ case 1: {
+ f(1);
+ g();
+ break;
+ }
+ case 2: {
+ f(2);
+ g();
+ break;
+ }
+ case 21: // gotta keem em unseparated
+ case 22:
+ case 23:
+ case 24:
+ case 25:
+ case 26:
+ case 27:
+ case 28:
+ case 29:
+ case 3: { // these too
+ f(3);
+ g();
+ break;
+ }
+ case 4: {
+ f(4);
+ g();
+ }
+ case 5: {
+ f(5);
+ g();
+ }
+ case 6: {
+ f(6);
+ g();
+ }
+ default: {
+ print(9);
+ }
+ }
+}
// EMSCRIPTEN_GENERATED_FUNCTIONS
// EXTRA_INFO: { "sizeToOutline": 30, "allowCostlyOutlines": 1 }