aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AUTHORS4
-rwxr-xr-xemcc12
-rw-r--r--src/determinstic.js8
-rw-r--r--src/intertyper.js15
-rw-r--r--src/jsifier.js14
-rw-r--r--src/library.js53
-rw-r--r--src/library_browser.js5
-rw-r--r--src/library_gl.js1492
-rw-r--r--src/library_sdl.js5
-rw-r--r--src/parseTools.js10
-rw-r--r--src/preamble.js1
-rw-r--r--src/relooper/Relooper.cpp127
-rw-r--r--src/relooper/Relooper.h7
-rw-r--r--src/relooper/fuzzer.py4
-rw-r--r--src/relooper/test.cpp41
-rw-r--r--src/relooper/test.txt27
-rw-r--r--src/relooper/test4.txt1
-rw-r--r--src/relooper/test_debug.txt76
-rw-r--r--src/relooper/test_fuzz1.txt11
-rw-r--r--src/relooper/test_fuzz5.txt24
-rw-r--r--src/relooper/test_fuzz6.txt1
-rwxr-xr-xsrc/relooper/testit.sh2
-rwxr-xr-xsrc/relooper/updateit.sh2
-rw-r--r--src/settings.js4
-rw-r--r--src/shell.js1
-rw-r--r--system/include/emscripten/emscripten.h13
-rw-r--r--system/include/libcxx/exception4
-rw-r--r--system/lib/libcxx/symbols1
-rw-r--r--tests/aniso.c16
-rw-r--r--tests/cases/emptystruct.ll2
-rw-r--r--tests/cases/fp80_ta2.ll (renamed from tests/cases/fp80.ll)0
-rw-r--r--tests/cases/muli33_ta2.ll114
-rw-r--r--tests/cases/muli33_ta2.txt1
-rw-r--r--tests/cases/philoop_ta2.ll305
-rw-r--r--tests/cases/philoop_ta2.txt1
-rw-r--r--tests/files.cpp3
-rw-r--r--tests/full_es2_sdlproc.c727
-rw-r--r--tests/gl_ps.c40
-rw-r--r--tests/gl_ps_workaround.c230
-rw-r--r--tests/gl_ps_workaround2.c230
-rw-r--r--tests/glbegin_points.c44
-rw-r--r--tests/linpack.c1153
-rwxr-xr-xtests/runner.py553
-rw-r--r--tests/s3tc.c16
-rw-r--r--tests/s3tc_crunch.c16
-rw-r--r--tests/sdl_fog_density.c48
-rw-r--r--tests/sdl_fog_exp2.c48
-rw-r--r--tests/sdl_fog_linear.c48
-rw-r--r--tests/sdl_fog_negative.c48
-rw-r--r--tests/sdl_fog_simple.c51
-rw-r--r--tests/sdl_ogl.c48
-rw-r--r--tests/sdl_ogl_defaultMatrixMode.c46
-rw-r--r--tests/sdl_ogl_p.c44
-rw-r--r--third_party/lzma.js/lzip/Makefile18
-rw-r--r--tools/eliminator/asm-eliminator-test-output.js4605
-rw-r--r--tools/eliminator/asm-eliminator-test.js6087
-rw-r--r--tools/file_packager.py91
-rw-r--r--tools/js-optimizer.js120
-rw-r--r--tools/shared.py10
-rw-r--r--tools/test-js-optimizer-asm-pre-output.js20
-rw-r--r--tools/test-js-optimizer-asm-pre.js14
-rw-r--r--tools/test-js-optimizer-asm-regs-output.js81
-rw-r--r--tools/test-js-optimizer-asm-regs.js84
63 files changed, 15706 insertions, 1221 deletions
diff --git a/AUTHORS b/AUTHORS
index 4cacefeb..f7a2225a 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -76,4 +76,8 @@ a license to everyone to use it as detailed in LICENSE.)
* John Allwine <jallwine86@gmail.com>
* Martin Gerhardy <martin.gerhardy@gmail.com>
* James Gregory <jgregory@zynga.com> (copyright owned by Zynga, Inc)
+* Dan Gohman <sunfish@google.com> (copyright owned by Google, Inc.)
+* Jeff Gilbert <jgilbert@mozilla.com> (copyright owned by Mozilla Foundation)
+* Frits Talbot <frits@metapathy.com>
+
diff --git a/emcc b/emcc
index acb59143..9feba1b1 100755
--- a/emcc
+++ b/emcc
@@ -110,7 +110,7 @@ while response_file:
sys.argv[index:index+1] = extra_args
break
-if len(sys.argv) == 1 or sys.argv[1] == '--help':
+if len(sys.argv) == 1 or '--help' in sys.argv:
this = os.path.basename('em++' if os.environ.get('EMMAKEN_CXX') else 'emcc')
print '''%s [options] file...
@@ -601,7 +601,7 @@ if EMMAKEN_CFLAGS: CC_ADDITIONAL_ARGS += shlex.split(EMMAKEN_CFLAGS)
# ---------------- Utilities ---------------
-SOURCE_SUFFIXES = ('.c', '.cpp', '.cxx', '.cc')
+SOURCE_SUFFIXES = ('.c', '.cpp', '.cxx', '.cc', '.m', '.mm')
BITCODE_SUFFIXES = ('.bc', '.o', '.obj')
DYNAMICLIB_SUFFIXES = ('.dylib', '.so', '.dll')
STATICLIB_SUFFIXES = ('.a',)
@@ -629,7 +629,7 @@ header = False # pre-compiled headers. We fake that by just copying the file
for i in range(1, len(sys.argv)):
arg = sys.argv[i]
if not arg.startswith('-'):
- if arg.endswith('.c'):
+ if arg.endswith(('.c','.m')):
use_cxx = False
if arg.endswith('.h') and sys.argv[i-1] != '-include':
header = True
@@ -994,7 +994,8 @@ try:
for change in settings_changes:
key, value = change.split('=')
if value[0] == '@':
- value = '"' + value + '"'
+ value = '"@' + os.path.abspath(value[1:]) + '"'
+ value = value.replace('\\\\', '/').replace('\\', '/') # Convert backslash paths to forward slashes on Windows as well, since the JS compiler otherwise needs the backslashes escaped (alternative is to escape all input paths passing to JS, which feels clumsier to read)
exec('shared.Settings.' + key + ' = ' + value)
# Apply effects from settings
@@ -1002,8 +1003,7 @@ try:
assert opt_level >= 1, 'asm.js requires -O1 or above'
if bind:
- shared.Settings.ASM_JS = 0
- logging.warning('disabling asm.js because it is not compatible with embind yet')
+ shared.Settings.RESERVED_FUNCTION_POINTERS = max(shared.Settings.RESERVED_FUNCTION_POINTERS, 10)
if shared.Settings.CORRECT_SIGNS != 1:
logging.warning('setting CORRECT_SIGNS to 1 for asm.js code generation')
shared.Settings.CORRECT_SIGNS = 1
diff --git a/src/determinstic.js b/src/determinstic.js
index 91f98ed9..1ec0bbfe 100644
--- a/src/determinstic.js
+++ b/src/determinstic.js
@@ -10,3 +10,11 @@ Date.now = function() {
};
performance.now = Date.now;
+function hashMemory(id) {
+ var ret = 0;
+ for (var i = 0; i < HEAPU8.length; i++) {
+ ret = (ret*17 + HEAPU8[i])|0;
+ }
+ print(id + ':' + ret);
+}
+
diff --git a/src/intertyper.js b/src/intertyper.js
index 445c37f4..6da30ae8 100644
--- a/src/intertyper.js
+++ b/src/intertyper.js
@@ -537,12 +537,17 @@ function intertyper(data, sidePass, baseLineNums) {
});
}
} else if (!external) {
- if (item.tokens[3].text == 'c')
- item.tokens.splice(3, 1);
- if (item.tokens[3].text in PARSABLE_LLVM_FUNCTIONS) {
- ret.value = parseLLVMFunctionCall(item.tokens.slice(2));
+ if (item.tokens[3] && item.tokens[3].text != ';') {
+ if (item.tokens[3].text == 'c') {
+ item.tokens.splice(3, 1);
+ }
+ if (item.tokens[3].text in PARSABLE_LLVM_FUNCTIONS) {
+ ret.value = parseLLVMFunctionCall(item.tokens.slice(2));
+ } else {
+ ret.value = scanConst(item.tokens[3], ret.type);
+ }
} else {
- ret.value = scanConst(item.tokens[3], ret.type);
+ ret.value = { intertype: 'value', ident: '0', value: '0', type: ret.type };
}
}
return [ret];
diff --git a/src/jsifier.js b/src/jsifier.js
index 2c83d036..156fd65d 100644
--- a/src/jsifier.js
+++ b/src/jsifier.js
@@ -12,6 +12,8 @@ var RELOOP_IGNORED_LASTS = set('return', 'unreachable', 'resume');
var addedLibraryItems = {};
var asmLibraryFunctions = [];
+var SETJMP_LABEL = -1;
+
// JSifier
function JSify(data, functionsOnly, givenFunctions) {
var mainPass = !functionsOnly;
@@ -458,6 +460,7 @@ function JSify(data, functionsOnly, givenFunctions) {
} else {
ident = '_' + ident;
}
+ if (VERBOSE) printErr('adding ' + ident + ' and deps ' + deps);
var depsText = (deps ? '\n' + deps.map(addFromLibrary).filter(function(x) { return x != '' }).join('\n') : '');
var contentText = isFunction ? snippet : ('var ' + ident + '=' + snippet + ';');
if (ASM_JS) {
@@ -730,7 +733,7 @@ function JSify(data, functionsOnly, givenFunctions) {
}).join('\n') + '\n';
if (func.setjmpTable && ASM_JS) {
// emit a label in which we write to the proper local variable, before jumping to the actual label
- ret += ' case -1111: ';
+ ret += ' case ' + SETJMP_LABEL + ': ';
ret += func.setjmpTable.map(function(triple) { // original label, label we created for right after the setjmp, variable setjmp result goes into
return 'if ((setjmpLabel|0) == ' + getLabelId(triple.oldLabel) + ') { ' + triple.assignTo + ' = threwValue; label = ' + triple.newLabel + ' }\n';
}).join(' else ');
@@ -1030,13 +1033,13 @@ function JSify(data, functionsOnly, givenFunctions) {
}
for (var i = 0; i < idents.length; i++) {
if (keys(deps[idents[i]]).length == 0) {
- pre = 'var ' + idents[i] + ' = ' + valueJSes[idents[i]] + ';' + pre;
+ post = 'var ' + idents[i] + ' = ' + valueJSes[idents[i]] + ';' + post;
remove(idents[i]);
continue mainLoop;
}
}
// If we got here, we have circular dependencies, and must break at least one.
- pre = 'var ' + idents[0] + '$phi = ' + valueJSes[idents[0]] + ';' + pre;
+ pre += 'var ' + idents[0] + '$phi = ' + valueJSes[idents[0]] + ';';
post += 'var ' + idents[0] + ' = ' + idents[0] + '$phi;';
remove(idents[0]);
}
@@ -1160,6 +1163,7 @@ function JSify(data, functionsOnly, givenFunctions) {
return ret + ';';
});
makeFuncLineActor('resume', function(item) {
+ if (DISABLE_EXCEPTION_CATCHING) return 'abort()';
if (item.ident == 0) {
// No exception to resume, so we can just bail.
// This is related to issue #917 and http://llvm.org/PR15518
@@ -1488,9 +1492,9 @@ function JSify(data, functionsOnly, givenFunctions) {
}
if (ASM_JS && funcData.setjmpTable) {
- // check if a longjmp was done. If a setjmp happened, check if ours. If ours, go to -111 to handle it.
+ // check if a longjmp was done. If a setjmp happened, check if ours. If ours, go to a special label to handle it.
// otherwise, just return - the call to us must also have been an invoke, so the setjmp propagates that way
- ret += '; if (((__THREW__|0) != 0) & ((threwValue|0) != 0)) { setjmpLabel = ' + asmCoercion('_testSetjmp(' + makeGetValue('__THREW__', 0, 'i32') + ', setjmpTable)', 'i32') + '; if ((setjmpLabel|0) > 0) { label = -1111; break } else return ' + (funcData.returnType != 'void' ? asmCoercion('0', funcData.returnType) : '') + ' } __THREW__ = threwValue = 0;\n';
+ ret += '; if (((__THREW__|0) != 0) & ((threwValue|0) != 0)) { setjmpLabel = ' + asmCoercion('_testSetjmp(' + makeGetValue('__THREW__', 0, 'i32') + ', setjmpTable)', 'i32') + '; if ((setjmpLabel|0) > 0) { label = ' + SETJMP_LABEL + '; break } else return ' + (funcData.returnType != 'void' ? asmCoercion('0', funcData.returnType) : '') + ' } __THREW__ = threwValue = 0;\n';
}
return ret;
diff --git a/src/library.js b/src/library.js
index 6f85669e..1b4fd1d6 100644
--- a/src/library.js
+++ b/src/library.js
@@ -561,6 +561,7 @@ LibraryManager.library = {
var stdout = FS.createDevice(devFolder, 'stdout', null, output);
var stderr = FS.createDevice(devFolder, 'stderr', null, error);
FS.createDevice(devFolder, 'tty', input, output);
+ FS.createDevice(devFolder, 'null', function(){}, function(){});
// Create default streams.
FS.streams[1] = {
@@ -3798,14 +3799,14 @@ LibraryManager.library = {
* implementation (replaced by dlmalloc normally) so
* not an issue.
*/
-#if ASSERTIONS
+#if ASSERTIONS == 2
Runtime.warnOnce('using stub malloc (reference it from C to have the real one included)');
#endif
var ptr = Runtime.dynamicAlloc(bytes + 8);
return (ptr+8) & 0xFFFFFFF8;
},
free: function() {
-#if ASSERTIONS
+#if ASSERTIONS == 2
Runtime.warnOnce('using stub free (reference it from C to have the real one included)');
#endif
},
@@ -3919,7 +3920,14 @@ LibraryManager.library = {
str++;
}
}
- }
+ } else if (finalBase==16) {
+ if ({{{ makeGetValue('str', 0, 'i8') }}} == {{{ charCode('0') }}}) {
+ if ({{{ makeGetValue('str+1', 0, 'i8') }}} == {{{ charCode('x') }}} ||
+ {{{ makeGetValue('str+1', 0, 'i8') }}} == {{{ charCode('X') }}}) {
+ str += 2;
+ }
+ }
+ }
if (!finalBase) finalBase = 10;
// Get digits.
@@ -3970,13 +3978,14 @@ LibraryManager.library = {
#if USE_TYPED_ARRAYS == 2
_parseInt64__deps: ['isspace', '__setErrNo', '$ERRNO_CODES', function() { Types.preciseI64MathUsed = 1 }],
_parseInt64: function(str, endptr, base, min, max, unsign) {
- var start = str;
+ var isNegative = false;
// Skip space.
while (_isspace({{{ makeGetValue('str', 0, 'i8') }}})) str++;
-
+
// Check for a plus/minus sign.
if ({{{ makeGetValue('str', 0, 'i8') }}} == {{{ charCode('-') }}}) {
str++;
+ isNegative = true;
} else if ({{{ makeGetValue('str', 0, 'i8') }}} == {{{ charCode('+') }}}) {
str++;
}
@@ -3992,12 +4001,19 @@ LibraryManager.library = {
str += 2;
} else {
finalBase = 8;
- str++;
ok = true; // we saw an initial zero, perhaps the entire thing is just "0"
}
}
- }
+ } else if (finalBase==16) {
+ if ({{{ makeGetValue('str', 0, 'i8') }}} == {{{ charCode('0') }}}) {
+ if ({{{ makeGetValue('str+1', 0, 'i8') }}} == {{{ charCode('x') }}} ||
+ {{{ makeGetValue('str+1', 0, 'i8') }}} == {{{ charCode('X') }}}) {
+ str += 2;
+ }
+ }
+ }
if (!finalBase) finalBase = 10;
+ start = str;
// Get digits.
var chr;
@@ -4010,6 +4026,7 @@ LibraryManager.library = {
ok = true;
}
}
+
if (!ok) {
___setErrNo(ERRNO_CODES.EINVAL);
{{{ makeStructuralReturn(['0', '0']) }}};
@@ -4021,7 +4038,8 @@ LibraryManager.library = {
}
try {
- i64Math.fromString(Pointer_stringify(start, str - start), finalBase, min, max, unsign);
+ var numberString = isNegative ? '-'+Pointer_stringify(start, str - start) : Pointer_stringify(start, str - start);
+ i64Math.fromString(numberString, finalBase, min, max, unsign);
} catch(e) {
___setErrNo(ERRNO_CODES.ERANGE); // not quite correct
}
@@ -5089,7 +5107,13 @@ LibraryManager.library = {
return _malloc(size);
},
__cxa_free_exception: function(ptr) {
- return _free(ptr);
+ try {
+ return _free(ptr);
+ } catch(e) { // XXX FIXME
+#if ASSERTIONS
+ Module.printErr('exception during cxa_free_exception: ' + e);
+#endif
+ }
},
__cxa_throw__sig: 'viii',
__cxa_throw__deps: ['llvm_eh_exception', '_ZSt18uncaught_exceptionv', '__cxa_find_matching_catch'],
@@ -5577,10 +5601,15 @@ LibraryManager.library = {
frexp: function(x, exp_addr) {
var sig = 0, exp_ = 0;
if (x !== 0) {
+ var sign = 1;
+ if (x < 0) {
+ x = -x;
+ sign = -1;
+ }
var raw_exp = Math.log(x)/Math.log(2);
exp_ = Math.ceil(raw_exp);
if (exp_ === raw_exp) exp_ += 1;
- sig = x/Math.pow(2, exp_);
+ sig = sign*x/Math.pow(2, exp_);
}
{{{ makeSetValue('exp_addr', 0, 'exp_', 'i32') }}}
return sig;
@@ -6814,7 +6843,7 @@ LibraryManager.library = {
},
__errno_state: 0,
__setErrNo__deps: ['__errno_state'],
- __setErrNo__postset: '___errno_state = Runtime.staticAlloc(4);',
+ __setErrNo__postset: '___errno_state = Runtime.staticAlloc(4); {{{ makeSetValue("___errno_state", 0, 0, "i32") }}};',
__setErrNo: function(value) {
// For convenient setting and returning of errno.
{{{ makeSetValue('___errno_state', '0', 'value', 'i32') }}}
@@ -7953,7 +7982,7 @@ LibraryManager.library = {
},
emscripten_run_script_int: function(ptr) {
- return eval(Pointer_stringify(ptr));
+ return eval(Pointer_stringify(ptr))|0;
},
emscripten_run_script_string: function(ptr) {
diff --git a/src/library_browser.js b/src/library_browser.js
index 894484bc..a690286b 100644
--- a/src/library_browser.js
+++ b/src/library_browser.js
@@ -763,6 +763,11 @@ mergeInto(LibraryManager.library, {
}
},
+ emscripten_exit_with_live_runtime: function() {
+ Module['noExitRuntime'] = true;
+ throw 'SimulateInfiniteLoop';
+ },
+
emscripten_hide_mouse: function() {
var styleSheet = document.styleSheets[0];
var rules = styleSheet.cssRules;
diff --git a/src/library_gl.js b/src/library_gl.js
index ba99eaa8..1fa0cc9c 100644
--- a/src/library_gl.js
+++ b/src/library_gl.js
@@ -373,7 +373,7 @@ var LibraryGL = {
glGetIntegerv__sig: 'vii',
glGetIntegerv: function(name_, p) {
- switch(name_) { // Handle a few trivial GLES values
+ switch(name_) { // Handle a few trivial GLES values
case 0x8DFA: // GL_SHADER_COMPILER
{{{ makeSetValue('p', '0', '1', 'i32') }}};
return;
@@ -507,7 +507,7 @@ var LibraryGL = {
glGenTextures__sig: 'vii',
glGenTextures: function(n, textures) {
for (var i = 0; i < n; i++) {
- var id = GL.getNewId(GL.textures);
+ var id = GL.getNewId(GL.textures);
GL.textures[id] = Module.ctx.createTexture();
{{{ makeSetValue('textures', 'i*4', 'id', 'i32') }}};
}
@@ -726,7 +726,7 @@ var LibraryGL = {
var ptable = GL.uniformTable[program];
if (!ptable) ptable = GL.uniformTable[program] = {};
var id = ptable[name];
- if (id) return id;
+ if (id) return id;
var loc = Module.ctx.getUniformLocation(GL.programs[program], name);
if (!loc) return -1;
id = GL.getNewId(GL.uniforms);
@@ -989,13 +989,15 @@ var LibraryGL = {
glBindBuffer__sig: 'vii',
glBindBuffer: function(target, buffer) {
+ var bufferObj = buffer ? GL.buffers[buffer] : null;
+
if (target == Module.ctx.ARRAY_BUFFER) {
GL.currArrayBuffer = buffer;
} else if (target == Module.ctx.ELEMENT_ARRAY_BUFFER) {
GL.currElementArrayBuffer = buffer;
}
- Module.ctx.bindBuffer(target, buffer ? GL.buffers[buffer] : null);
+ Module.ctx.bindBuffer(target, bufferObj);
},
glVertexAttrib1fv__sig: 'vii',
@@ -1275,7 +1277,22 @@ var LibraryGL = {
currentVao: null,
enabledVertexAttribArrays: {}, // helps with vao cleanups
+ hasRunInit: false,
+
init: function() {
+ // Do not activate immediate/emulation code (e.g. replace glDrawElements) when in FULL_ES2 mode.
+ // We do not need full emulation, we instead emulate client-side arrays etc. in FULL_ES2 code in
+ // a straightforward manner, and avoid not having a bound buffer be ambiguous between es2 emulation
+ // code and legacy gl emulation code.
+#if FULL_ES2
+ return;
+#endif
+
+ if (GLEmulation.hasRunInit) {
+ return;
+ }
+ GLEmulation.hasRunInit = true;
+
GLEmulation.fogColor = new Float32Array(4);
// Add some emulation workarounds
@@ -1297,6 +1314,7 @@ var LibraryGL = {
0x80A0: 1 // GL_SAMPLE_COVERAGE
};
+ var glEnable = _glEnable;
_glEnable = function(cap) {
// Clean up the renderer on any change to the rendering state. The optimization of
// skipping renderer setup is aimed at the case of multiple glDraw* right after each other
@@ -1307,13 +1325,18 @@ var LibraryGL = {
} else if (cap == 0x0de1 /* GL_TEXTURE_2D */) {
// XXX not according to spec, and not in desktop GL, but works in some GLES1.x apparently, so support
// it by forwarding to glEnableClientState
+ /* Actually, let's not, for now. (This sounds exceedingly broken)
+ * This is in gl_ps_workaround2.c.
_glEnableClientState(cap);
+ */
return;
} else if (!(cap in validCapabilities)) {
return;
}
- Module.ctx.enable(cap);
+ glEnable(cap);
};
+
+ var glDisable = _glDisable;
_glDisable = function(cap) {
if (GL.immediate.lastRenderer) GL.immediate.lastRenderer.cleanup();
if (cap == 0x0B60 /* GL_FOG */) {
@@ -1322,12 +1345,15 @@ var LibraryGL = {
} else if (cap == 0x0de1 /* GL_TEXTURE_2D */) {
// XXX not according to spec, and not in desktop GL, but works in some GLES1.x apparently, so support
// it by forwarding to glDisableClientState
+ /* Actually, let's not, for now. (This sounds exceedingly broken)
+ * This is in gl_ps_workaround2.c.
_glDisableClientState(cap);
+ */
return;
} else if (!(cap in validCapabilities)) {
return;
}
- Module.ctx.disable(cap);
+ glDisable(cap);
};
_glIsEnabled = function(cap) {
if (cap == 0x0B60 /* GL_FOG */) {
@@ -1453,6 +1479,7 @@ var LibraryGL = {
_glShaderSource = function(shader, count, string, length) {
var source = GL.getSource(shader, count, string, length);
#if GL_DEBUG
+ console.log("glShaderSource: Input: \n" + source);
GL.shaderOriginalSources[shader] = source;
#endif
// XXX We add attributes and uniforms to shaders. The program can ask for the # of them, and see the
@@ -1510,9 +1537,7 @@ var LibraryGL = {
}
if (source.indexOf('gl_Color') >= 0) {
source = 'attribute vec4 a_color; \n' +
- 'uniform vec4 u_color; \n' +
- 'uniform int u_hasColorAttrib; \n' +
-