summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xemcc5
-rwxr-xr-xemscripten.py7
-rw-r--r--src/analyzer.js16
-rw-r--r--src/compiler.js5
-rw-r--r--src/headless.js2
-rw-r--r--src/intertyper.js11
-rw-r--r--src/jsifier.js65
-rw-r--r--src/library.js12
-rw-r--r--src/library_browser.js18
-rw-r--r--src/library_egl.js5
-rw-r--r--src/library_fs.js49
-rw-r--r--src/library_gl.js281
-rw-r--r--src/library_glut.js26
-rw-r--r--src/library_memfs.js66
-rw-r--r--src/library_sdl.js55
-rw-r--r--src/modules.js18
-rw-r--r--src/parseTools.js30
-rw-r--r--src/postamble.js9
-rw-r--r--src/settings.js8
-rw-r--r--src/shell.js7
-rw-r--r--system/include/compat/math.h14
-rw-r--r--system/include/compat/stdlib.h16
-rw-r--r--system/include/compat/string.h17
-rw-r--r--system/include/compat/sys/stat.h20
-rw-r--r--system/include/compat/sys/timeb.h (renamed from system/include/libc/sys/timeb.h)0
-rw-r--r--system/include/compat/unistd.h16
-rw-r--r--system/include/compat/xlocale.h21
-rw-r--r--system/include/emscripten/emscripten.h13
-rw-r--r--system/include/libc/stdlib.h2
-rw-r--r--system/include/libc/string.h2
-rw-r--r--system/include/libc/sys/unistd.h1
-rw-r--r--system/include/xlocale.h7
-rw-r--r--tests/aniso.c10
-rw-r--r--tests/cases/phi24_ta2.ll1
-rw-r--r--tests/glut_touchevents.c64
-rwxr-xr-xtests/runner.py123
-rw-r--r--tests/sdl_ogl_proc_alias.c180
-rw-r--r--tests/sockets/test_sockets_echo_server.c8
-rw-r--r--tests/sockets/test_sockets_partial_server.c24
-rw-r--r--tests/sockets/webrtc_host.c89
-rw-r--r--tests/sockets/webrtc_peer.c81
-rw-r--r--tests/test_browser.py126
-rw-r--r--tests/test_core.py92
-rw-r--r--tests/test_other.py2
-rw-r--r--tests/test_sockets.py68
-rw-r--r--tools/find_bigfuncs.py4
-rw-r--r--tools/js-optimizer.js14
-rw-r--r--tools/jsrun.py2
-rw-r--r--tools/response_file.py4
-rw-r--r--tools/shared.py1
-rwxr-xr-xtools/source-maps/sourcemapper.js43
-rw-r--r--tools/test-js-optimizer-asm-outline1-output.js159
-rw-r--r--tools/test-js-optimizer-asm-outline2-output.js790
53 files changed, 1829 insertions, 880 deletions
diff --git a/emcc b/emcc
index b63eada0..df2ef38c 100755
--- a/emcc
+++ b/emcc
@@ -137,7 +137,7 @@ Options that are modified or new in %s include:
opt levels, see apply_opt_level() in
tools/shared.py and also src/settings.js.)
-O2 As -O1, plus the relooper (loop recreation),
- LLVM -O2 optimizations, and
+ LLVM -O3 optimizations, and
-s ALIASING_FUNCTION_POINTERS=1
@@ -1621,9 +1621,6 @@ try:
js_optimizer_queue += [get_eliminate(), 'simplifyExpressions']
- if shared.Settings.RELOOP and not shared.Settings.ASM_JS:
- js_optimizer_queue += ['optimizeShiftsAggressive', get_eliminate()] # aggressive shifts optimization requires loops, it breaks on switches
-
if closure and not shared.Settings.ASM_JS:
flush_js_optimizer_queue()
diff --git a/emscripten.py b/emscripten.py
index 1b1284c7..a156ca73 100755
--- a/emscripten.py
+++ b/emscripten.py
@@ -190,6 +190,11 @@ def emscript(infile, settings, outfile, libraries=[], compiler_engine=None,
open(forwarded_file, 'w').write(forwarded_data)
if DEBUG: print >> sys.stderr, ' emscript: phase 1 took %s seconds' % (time.time() - t)
+ indexed_functions = set()
+ forwarded_json = json.loads(forwarded_data)
+ for key in forwarded_json['Functions']['indexedFunctions'].iterkeys():
+ indexed_functions.add(key)
+
# Phase 2 - func
cores = int(os.environ.get('EMCC_CORES') or multiprocessing.cpu_count())
@@ -203,8 +208,6 @@ def emscript(infile, settings, outfile, libraries=[], compiler_engine=None,
chunk_size = MAX_CHUNK_SIZE # if 1 core, just use the max chunk size
if DEBUG: t = time.time()
- forwarded_json = json.loads(forwarded_data)
- indexed_functions = set()
if settings.get('ASM_JS'):
settings['EXPORTED_FUNCTIONS'] = forwarded_json['EXPORTED_FUNCTIONS']
save_settings()
diff --git a/src/analyzer.js b/src/analyzer.js
index 931ce421..2a7d64f5 100644
--- a/src/analyzer.js
+++ b/src/analyzer.js
@@ -953,9 +953,23 @@ function analyzer(data, sidePass) {
if (type[0] == '{' || type[0] == '<') {
type = nonPointing;
var packed = type[0] == '<';
+ var internal = type;
+ if (packed) {
+ if (internal[internal.length-1] != '>') {
+ warnOnce('ignoring type ' + internal);
+ return; // function pointer or such
+ }
+ internal = internal.substr(1, internal.length-2);
+ }
+ assert(internal[0] == '{', internal);
+ if (internal[internal.length-1] != '}') {
+ warnOnce('ignoring type ' + internal);
+ return; // function pointer or such
+ }
+ internal = internal.substr(2, internal.length-4);
Types.types[type] = {
name_: type,
- fields: splitTokenList(tokenize(type.substr(2 + packed, type.length - 4 - 2*packed)).tokens).map(function(segment) {
+ fields: splitTokenList(tokenize(internal).tokens).map(function(segment) {
return segment[0].text;
}),
packed: packed,
diff --git a/src/compiler.js b/src/compiler.js
index 365ff32f..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
@@ -203,6 +202,8 @@ if (phase == 'pre') {
}
}
+if (VERBOSE) printErr('VERBOSE is on, this generates a lot of output and can slow down compilation');
+
// Load compiler code
load('framework.js');
diff --git a/src/headless.js b/src/headless.js
index 097a42f7..1c7b8945 100644
--- a/src/headless.js
+++ b/src/headless.js
@@ -23,6 +23,7 @@ var window = {
return '%s';
},
search: '?%s',
+ pathname: '%s',
},
fakeNow: 0, // we don't use Date.now()
rafs: [],
@@ -84,6 +85,7 @@ var window = {
},
revokeObjectURL: function(x) {},
},
+ encodeURIComponent: function(x) { return x },
};
var setTimeout = window.setTimeout;
var document = {
diff --git a/src/intertyper.js b/src/intertyper.js
index 3fc840c4..31e97bd0 100644
--- a/src/intertyper.js
+++ b/src/intertyper.js
@@ -365,8 +365,17 @@ function intertyper(data, sidePass, baseLineNums) {
}
if (tokensLength >= 3 && (token0Text == 'call' || token1Text == 'call'))
return 'Call';
- if (token0Text == 'target')
+ if (token0Text == 'target') {
+ if (token1Text == 'triple') {
+ var triple = item.tokens[3].text;
+ triple = triple.substr(1, triple.length-2);
+ var expected = TARGET_LE32 ? 'le32-unknown-nacl' : 'i386-pc-linux-gnu';
+ if (triple !== expected) {
+ warn('using an unexpected LLVM triple: ' + [triple, ' !== ', expected] + ' (are you using emcc for everything and not clang?)');
+ }
+ }
return '/dev/null';
+ }
if (token0Text == ';')
return '/dev/null';
if (tokensLength >= 3 && token0Text == 'invoke')
diff --git a/src/jsifier.js b/src/jsifier.js
index c92526d2..c7742288 100644
--- a/src/jsifier.js
+++ b/src/jsifier.js
@@ -16,6 +16,8 @@ var SETJMP_LABEL = -1;
var INDENTATION = ' ';
+var functionStubSigs = {};
+
// JSifier
function JSify(data, functionsOnly, givenFunctions) {
var mainPass = !functionsOnly;
@@ -278,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)) {
@@ -407,6 +409,11 @@ function JSify(data, functionsOnly, givenFunctions) {
// functionStub
substrate.addActor('FunctionStub', {
processItem: function(item) {
+ // note the signature
+ if (item.returnType && item.params) {
+ functionStubSigs[item.ident] = Functions.getSignature(item.returnType.text, item.params.map(function(arg) { return arg.type }), false);
+ }
+
function addFromLibrary(ident) {
if (ident in addedLibraryItems) return '';
addedLibraryItems[ident] = true;
@@ -1537,7 +1544,7 @@ function JSify(data, functionsOnly, givenFunctions) {
// This is a call through an invoke_*, either a forced one, or a setjmp-required one
// note: no need to update argsTypes at this point
if (byPointerForced) Functions.unimplementedFunctions[callIdent] = sig;
- args.unshift(byPointerForced ? Functions.getIndex(callIdent, undefined, sig) : asmCoercion(callIdent, 'i32'));
+ args.unshift(byPointerForced ? Functions.getIndex(callIdent, sig) : asmCoercion(callIdent, 'i32'));
callIdent = 'invoke_' + sig;
}
} else if (SAFE_DYNCALLS) {
@@ -1628,7 +1635,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
@@ -1672,24 +1679,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');
+ }
}
}
@@ -1724,11 +1733,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');
@@ -1795,7 +1806,7 @@ 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('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 815badc1..9e78db13 100644
--- a/src/library.js
+++ b/src/library.js
@@ -100,7 +100,7 @@ LibraryManager.library = {
}
var entries;
try {
- entries = FS.readdir(stream);
+ entries = FS.readdir(stream.path);
} catch (e) {
return FS.handleFSError(e);
}
@@ -478,8 +478,6 @@ LibraryManager.library = {
open: function(path, oflag, varargs) {
// int open(const char *path, int oflag, ...);
// http://pubs.opengroup.org/onlinepubs/009695399/functions/open.html
- // NOTE: This implementation tries to mimic glibc rather than strictly
- // following the POSIX standard.
var mode = {{{ makeGetValue('varargs', 0, 'i32') }}};
path = Pointer_stringify(path);
try {
@@ -7237,7 +7235,7 @@ LibraryManager.library = {
socket__deps: ['$FS', '$Sockets'],
socket: function(family, type, protocol) {
var INCOMING_QUEUE_LENGTH = 64;
- var stream = FS.createStream({
+ var info = FS.createStream({
addr: null,
port: null,
inQueue: new CircularBuffer(INCOMING_QUEUE_LENGTH),
@@ -7246,7 +7244,7 @@ LibraryManager.library = {
socket: true,
stream_ops: {}
});
- assert(stream.fd < 64); // select() assumes socket fd values are in 0..63
+ assert(info.fd < 64); // select() assumes socket fd values are in 0..63
var stream = type == {{{ cDefine('SOCK_STREAM') }}};
if (protocol) {
assert(stream == (protocol == {{{ cDefine('IPPROTO_TCP') }}})); // if stream, must be tcp
@@ -7359,8 +7357,7 @@ LibraryManager.library = {
}
};
};
-
- return stream.fd;
+ return info.fd;
},
mkport__deps: ['$Sockets'],
@@ -7454,6 +7451,7 @@ LibraryManager.library = {
buffer.set(data, info.header.byteLength);
connection.send('unreliable', buffer.buffer);
+ return ret;
},
recvmsg__deps: ['$FS', '$Sockets', 'bind', '__setErrNo', '$ERRNO_CODES', 'htons'],
diff --git a/src/library_browser.js b/src/library_browser.js
index f65791e4..558c9a59 100644
--- a/src/library_browser.js
+++ b/src/library_browser.js
@@ -6,6 +6,7 @@ mergeInto(LibraryManager.library, {
$Browser__deps: ['$PATH'],
$Browser__postset: 'Module["requestFullScreen"] = function(lockPointer, resizeCanvas) { Browser.requestFullScreen(lockPointer, resizeCanvas) };\n' + // exports
'Module["requestAnimationFrame"] = function(func) { Browser.requestAnimationFrame(func) };\n' +
+ 'Module["setCanvasSize"] = function(width, height, noUpdates) { Browser.setCanvasSize(width, height, noUpdates) };\n' +
'Module["pauseMainLoop"] = function() { Browser.mainLoop.pause() };\n' +
'Module["resumeMainLoop"] = function() { Browser.mainLoop.resume() };\n' +
'Module["getUserMedia"] = function() { Browser.getUserMedia() }',
@@ -451,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
diff --git a/src/library_egl.js b/src/library_egl.js
index 0e96e92f..ff912ed2 100644
--- a/src/library_egl.js
+++ b/src/library_egl.js
@@ -489,6 +489,11 @@ var LibraryEGL = {
eglSwapBuffers: function() {
EGL.setErrorCode(0x3000 /* EGL_SUCCESS */);
},
+
+ eglGetProcAddress__deps: ['emscripten_GetProcAddress'],
+ eglGetProcAddress: function(name_) {
+ return _emscripten_GetProcAddress(Pointer_stringify(name_));
+ },
};
autoAddDeps(LibraryEGL, '$EGL');
diff --git a/src/library_fs.js b/src/library_fs.js
index 9c83fcad..9d1f0cfd 100644
--- a/src/library_fs.js
+++ b/src/library_fs.js
@@ -18,7 +18,7 @@ mergeInto(LibraryManager.library, {
devices: [null],
streams: [null],
nextInode: 1,
- name_table: new Array(4096),
+ name_table: null,
currentPath: '/',
initialized: false,
// Whether we are currently ignoring permissions. Useful when preparing the
@@ -27,16 +27,21 @@ mergeInto(LibraryManager.library, {
// to modify the filesystem freely before run() is called.
ignorePermissions: true,
- ErrnoError: function(errno) {
- this.errno = errno;
- for (var key in ERRNO_CODES) {
- if (ERRNO_CODES[key] === errno) {
- this.code = key;
- break;
+ ErrnoError: (function() {
+ function ErrnoError(errno) {
+ this.errno = errno;
+ for (var key in ERRNO_CODES) {
+ if (ERRNO_CODES[key] === errno) {
+ this.code = key;
+ break;
+ }
}
- }
- this.message = ERRNO_MESSAGES[errno] + ' : ' + new Error().stack;
- },
+ this.message = ERRNO_MESSAGES[errno];
+ };
+ ErrnoError.prototype = new Error();
+ ErrnoError.prototype.constructor = ErrnoError;
+ return ErrnoError;
+ }()),
handleFSError: function(e) {
if (!(e instanceof FS.ErrnoError)) throw e + ' : ' + new Error().stack;
@@ -51,7 +56,7 @@ mergeInto(LibraryManager.library, {
for (var i = 0; i < name.length; i++) {
hash = ((hash << 5) - hash + name.charCodeAt(i)) | 0;
}
- return (parentid + hash) % FS.name_table.length;
+ return ((parentid + hash) >>> 0) % FS.name_table.length;
},
hashAddNode: function(node) {
var hash = FS.hashName(node.parent.id, node.name);
@@ -730,6 +735,9 @@ mergeInto(LibraryManager.library, {
});
// use a custom read function
stream_ops.read = function(stream, buffer, offset, length, position) {
+ if (!FS.forceLoadFile(node)) {
+ throw new FS.ErrnoError(ERRNO_CODES.EIO);
+ }
var contents = stream.node.contents;
var size = Math.min(contents.length - position, length);
if (contents.slice) { // normal array
@@ -860,6 +868,8 @@ mergeInto(LibraryManager.library, {
assert(stderr.fd === 3, 'invalid handle for stderr (' + stderr.fd + ')');
},
staticInit: function() {
+ FS.name_table = new Array(4096);
+
FS.root = FS.createNode(null, '/', {{{ cDefine('S_IFDIR') }}} | 0777, 0);
FS.mount(MEMFS, {}, '/');
@@ -1035,7 +1045,7 @@ mergeInto(LibraryManager.library, {
FS.hashRemoveNode(old_node);
// do the underlying fs rename
try {
- old_node.node_ops.rename(old_node, new_dir, new_name);
+ old_dir.node_ops.rename(old_node, new_dir, new_name);
} catch (e) {
throw e;
} finally {
@@ -1062,6 +1072,14 @@ mergeInto(LibraryManager.library, {
parent.node_ops.rmdir(parent, name);
FS.destroyNode(node);
},
+ readdir: function(path) {
+ var lookup = FS.lookupPath(path, { follow: true });
+ var node = lookup.node;
+ if (!node.node_ops.readdir) {
+ throw new FS.ErrnoError(ERRNO_CODES.ENOTDIR);
+ }
+ return node.node_ops.readdir(node);
+ },
unlink: function(path) {
var lookup = FS.lookupPath(path, { parent: true });
var parent = lookup.node;
@@ -1202,6 +1220,7 @@ mergeInto(LibraryManager.library, {
open: function(path, flags, mode, fd_start, fd_end) {
path = PATH.normalize(path);
flags = typeof flags === 'string' ? FS.modeStringToFlags(flags) : flags;
+ mode = typeof mode === 'undefined' ? 0666 : mode;
if ((flags & {{{ cDefine('O_CREAT') }}})) {
mode = (mode & {{{ cDefine('S_IALLUGO') }}}) | {{{ cDefine('S_IFREG') }}};
} else {
@@ -1280,12 +1299,6 @@ mergeInto(LibraryManager.library, {
}
return stream.stream_ops.llseek(stream, offset, whence);
},
- readdir: function(stream) {
- if (!stream.stream_ops.readdir) {
- throw new FS.ErrnoError(ERRNO_CODES.ENOTDIR);
- }
- return stream.stream_ops.readdir(stream);
- },
read: function(stream, buffer, offset, length, position) {
if (length < 0 || position < 0) {
throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
diff --git a/src/library_gl.js b/src/library_gl.js
index 8c724245..c134ad97 100644
--- a/src/library_gl.js
+++ b/src/library_gl.js
@@ -1285,10 +1285,11 @@ var LibraryGL = {
return Module.ctx.isFramebuffer(fb);
},
-#if DISABLE_GL_EMULATION == 0
+#if LEGACY_GL_EMULATION
// GL emulation: provides misc. functionality not present in OpenGL ES 2.0 or WebGL
+ $GLEmulation__deps: ['$GLImmediateSetup', 'glEnable', 'glDisable', 'glIsEnabled', 'glGetBooleanv', 'glGetIntegerv', 'glGetString', 'glCreateShader', 'glShaderSource', 'glCompileShader', 'glAttachShader', 'glDetachShader', 'glUseProgram', 'glDeleteProgram', 'glBindAttribLocation', 'glLinkProgram', 'glBindBuffer', 'glGetFloatv', 'glHint', 'glEnableVertexAttribArray', 'glDisableVertexAttribArray', 'glVertexAttribPointer', 'glActiveTexture'],
$GLEmulation__postset: 'GLEmulation.init();',
$GLEmulation: {
// Fog support. Partial, we assume shaders are used that implement fog. We just pass them uniforms
@@ -1323,7 +1324,7 @@ var LibraryGL = {
GLEmulation.fogColor = new Float32Array(4);
// Add some emulation workarounds
- Module.printErr('WARNING: using emscripten GL emulation. This is a collection of limited workarounds, do not expect it to work. (If you do not want this, build with -s DISABLE_GL_EMULATION=1)');
+ Module.printErr('WARNING: using emscripten GL emulation. This is a collection of limited workarounds, do not expect it to work.');
#if GL_UNSAFE_OPTS == 0
Module.printErr('WARNING: using emscripten GL emulation unsafe opts. If weirdness happens, try -s GL_UNSAFE_OPTS=0');
#endif
@@ -1618,17 +1619,15 @@ var LibraryGL = {
var glCompileShader = _glCompileShader;
_glCompileShader = function(shader) {
Module.ctx.compileShader(GL.shaders[shader]);
+#if GL_DEBUG
if (!Module.ctx.getShaderParameter(GL.shaders[shader], Module.ctx.COMPILE_STATUS)) {
Module.printErr('Failed to compile shader: ' + Module.ctx.getShaderInfoLog(GL.shaders[shader]));
Module.printErr('Info: ' + JSON.stringify(GL.shaderInfos[shader]));
-#if GL_DEBUG
Module.printErr('Original source: ' + GL.shaderOriginalSources[shader]);
Module.printErr('Source: ' + GL.shaderSources[shader]);
throw 'Shader compilation halt';
-#else
- Module.printErr('Enable GL_DEBUG to see shader source');
-#endif
}
+#endif
};
GL.programShaders = {};
@@ -1775,170 +1774,6 @@ var LibraryGL = {
}
return attrib;
},
-
- getProcAddress: function(name) {
- name = name.replace('EXT', '').replace('ARB', '');
- // Do the translation carefully because of closure
- var ret = 0;
- switch (name) {
- case 'glCreateShaderObject': case 'glCreateShader': ret = {{{ Functions.getIndex('_glCreateShader', true) }}}; break;
- case 'glCreateProgramObject': case 'glCreateProgram': ret = {{{ Functions.getIndex('_glCreateProgram', true) }}}; break;
- case 'glAttachObject': case 'glAttachShader': ret = {{{ Functions.getIndex('_glAttachShader', true) }}}; break;
- case 'glUseProgramObject': case 'glUseProgram': ret = {{{ Functions.getIndex('_glUseProgram', true) }}}; break;
- case 'glDetachObject': case 'glDetachShader': ret = {{{ Functions.getIndex('_glDetachShader', true) }}}; break;
- case 'glDeleteObject': ret = {{{ Functions.getIndex('_glDeleteObject', true) }}}; break;
- case 'glGetObjectParameteriv': ret = {{{ Functions.getIndex('_glGetObjectParameteriv', true) }}}; break;
- case 'glGetInfoLog': ret = {{{ Functions.getIndex('_glGetInfoLog', true) }}}; break;
- case 'glBindProgram': ret = {{{ Functions.getIndex('_glBindProgram', true) }}}; break;
- case 'glDrawRangeElements': ret = {{{ Functions.getIndex('_glDrawRangeElements', true) }}}; break;
- case 'glShaderSource': ret = {{{ Functions.getIndex('_glShaderSource', true) }}}; break;
- case 'glCompileShader': ret = {{{ Functions.getIndex('_glCompileShader', true) }}}; break;
- case 'glLinkProgram': ret = {{{ Functions.getIndex('_glLinkProgram', true) }}}; break;
- case 'glGetUniformLocation': ret = {{{ Functions.getIndex('_glGetUniformLocation', true) }}}; break;
- case 'glUniform1f': ret = {{{ Functions.getIndex('_glUniform1f', true) }}}; break;
- case 'glUniform2f': ret = {{{ Functions.getIndex('_glUniform2f', true) }}}; break;
- case 'glUniform3f': ret = {{{ Functions.getIndex('_glUniform3f', true) }}}; break;
- case 'glUniform4f': ret = {{{ Functions.getIndex('_glUniform4f', true) }}}; break;
- case 'glUniform1fv': ret = {{{ Functions.getIndex('_glUniform1fv', true) }}}; break;
- case 'glUniform2fv': ret = {{{ Functions.getIndex('_glUniform2fv', true) }}}; break;
- case 'glUniform3fv': ret = {{{ Functions.getIndex('_glUniform3fv', true) }}}; break;
- case 'glUniform4fv': ret = {{{ Functions.getIndex('_glUniform4fv', true) }}}; break;
- case 'glUniform1i': ret = {{{ Functions.getIndex('_glUniform1i', true) }}}; break;
- case 'glUniform2i': ret = {{{ Functions.getIndex('_glUniform2i', true) }}}; break;
- case 'glUniform3i': ret = {{{ Functions.getIndex('_glUniform3i', true) }}}; break;
- case 'glUniform4i': ret = {{{ Functions.getIndex('_glUniform4i', true) }}}; break;
- case 'glUniform1iv': ret = {{{ Functions.getIndex('_glUniform1iv', true) }}}; break;
- case 'glUniform2iv': ret = {{{ Functions.getIndex('_glUniform2iv', true) }}}; break;
- case 'glUniform3iv': ret = {{{ Functions.getIndex('_glUniform3iv', true) }}}; break;
- case 'glUniform4iv': ret = {{{ Functions.getIndex('_glUniform4iv', true) }}}; break;
- case 'glBindAttribLocation': ret = {{{ Functions.getIndex('_glBindAttribLocation', true) }}}; break;
- case 'glGetActiveUniform': ret = {{{ Functions.getIndex('_glGetActiveUniform', true) }}}; break;
- case 'glGenBuffers': ret = {{{ Functions.getIndex('_glGenBuffers', true) }}}; break;
- case 'glBindBuffer': ret = {{{ Functions.getIndex('_glBindBuffer', true) }}}; break;
- case 'glBufferData': ret = {{{ Functions.getIndex('_glBufferData', true) }}}; break;
- case 'glBufferSubData': ret = {{{ Functions.getIndex('_glBufferSubData', true) }}}; break;
- case 'glDeleteBuffers': ret = {{{ Functions.getIndex('_glDeleteBuffers', true) }}}; break;
- case 'glActiveTexture': ret = {{{ Functions.getIndex('_glActiveTexture', true) }}}; break;
- case 'glClientActiveTexture': ret = {{{ Functions.getIndex('_glClientActiveTexture', true) }}}; break;
- case 'glGetProgramiv': ret = {{{ Functions.getIndex('_glGetProgramiv', true) }}}; break;
- case 'glEnableVertexAttribArray': ret = {{{ Functions.getIndex('_glEnableVertexAttribArray', true) }}}; break;
- case 'glDisableVertexAttribArray': ret = {{{ Functions.getIndex('_glDisableVertexAttribArray', true) }}}; break;
- case 'glVertexAttribPointer': ret = {{{ Functions.getIndex('_glVertexAttribPointer', true) }}}; break;
- case 'glVertexAttrib1f': ret = {{{ Functions.getIndex('_glVertexAttrib1f', true) }}}; break;
- case 'glVertexAttrib2f': ret = {{{ Functions.getIndex('_glVertexAttrib2f', true) }}}; break;
- case 'glVertexAttrib3f': ret = {{{ Functions.getIndex('_glVertexAttrib3f', true) }}}; break;
- case 'glVertexAttrib4f': ret = {{{ Functions.getIndex('_glVertexAttrib4f', true) }}}; break;
- case 'glVertexAttrib1fv': ret = {{{ Functions.getIndex('_glVertexAttrib1fv', true) }}}; break;
- case 'glVertexAttrib2fv': ret = {{{ Functions.getIndex('_glVertexAttrib2fv', true) }}}; break;
- case 'glVertexAttrib3fv': ret = {{{ Functions.getIndex('_glVertexAttrib3fv', true) }}}; break;
- case 'glVertexAttrib4fv': ret = {{{ Functions.getIndex('_glVertexAttrib4fv', true) }}}; break;
- case 'glGetVertexAttribfv': ret = {{{ Functions.getIndex('_glGetVertexAttribfv', true) }}}; break;
- case 'glGetVertexAttribiv': ret = {{{ Functions.getIndex('_glGetVertexAttribiv', true) }}}; break;
- case 'glGetVertexAttribPointerv': ret = {{{ Functions.getIndex('_glGetVertexAttribPointerv', true) }}}; break;
- case 'glGetAttribLocation': ret = {{{ Functions.getIndex('_glGetAttribLocation', true) }}}; break;
- case 'glGetActiveAttrib': ret = {{{ Functions.getIndex('_glGetActiveAttrib', true) }}}; break;
- case 'glBindRenderbuffer': ret = {{{ Functions.getIndex('_glBindRenderbuffer', true) }}}; break;
- case 'glDeleteRenderbuffers': ret = {{{ Functions.getIndex('_glDeleteRenderbuffers', true) }}}; break;
- case 'glGenRenderbuffers': ret = {{{ Functions.getIndex('_glGenRenderbuffers', true) }}}; break;
- case 'glCompressedTexImage2D': ret = {{{ Functions.getIndex('_glCompressedTexImage2D', true) }}}; break;
- case 'glCompressedTexSubImage2D': ret = {{{ Functions.getIndex('_glCompressedTexSubImage2D', true) }}}; break;
- case 'glBindFramebuffer': ret = {{{ Functions.getIndex('_glBindFramebuffer', true) }}}; break;
- case 'glGenFramebuffers': ret = {{{ Functions.getIndex('_glGenFramebuffers', true) }}}; break;
- case 'glDeleteFramebuffers': ret = {{{ Functions.getIndex('_glDeleteFramebuffers', true) }}}; break;
- case 'glFramebufferRenderbuffer': ret = {{{ Functions.getIndex('_glFramebufferRenderbuffer', true) }}}; break;
- case 'glFramebufferTexture2D': ret = {{{ Functions.getIndex('_glFramebufferTexture2D', true) }}}; break;
- case 'glGetFramebufferAttachmentParameteriv': ret = {{{ Functions.getIndex('_glGetFramebufferAttachmentParameteriv', true) }}}; break;
- case 'glIsFramebuffer': ret = {{{ Functions.getIndex('_glIsFramebuffer', true) }}}; break;
- case 'glCheckFramebufferStatus': ret = {{{ Functions.getIndex('_glCheckFramebufferStatus', true) }}}; break;
- case 'glRenderbufferStorage': ret = {{{ Functions.getIndex('_glRenderbufferStorage', true) }}}; break;
- case 'glGenVertexArrays': ret = {{{ Functions.getIndex('_glGenVertexArrays', true) }}}; break;
- case 'glDeleteVertexArrays': ret = {{{ Functions.getIndex('_glDeleteVertexArrays', true) }}}; break;
- case 'glBindVertexArray': ret = {{{ Functions.getIndex('_glBindVertexArray', true) }}}; break;
- case 'glGetString': ret = {{{ Functions.getIndex('_glGetString', true) }}}; break;
- case 'glBindTexture': ret = {{{ Functions.getIndex('_glBindTexture', true) }}}; break;
- case 'glGetBufferParameteriv': ret = {{{ Functions.getIndex('_glGetBufferParameteriv', true) }}}; break;
- case 'glIsBuffer': ret = {{{ Functions.getIndex('_glIsBuffer', true) }}}; break;
- case 'glDeleteShader': ret = {{{ Functions.getIndex('_glDeleteShader', true) }}}; break;
- case 'glUniformMatrix2fv': ret = {{{ Functions.getIndex('_glUniformMatrix2fv', true) }}}; break;
- case 'glUniformMatrix3fv': ret = {{{ Functions.getIndex('_glUniformMatrix3fv', true) }}}; break;
- case 'glUniformMatrix4fv': ret = {{{ Functions.getIndex('_glUniformMatrix4fv', true) }}}; break;
- case 'glIsRenderbuffer': ret = {{{ Functions.getIndex('_glIsRenderbuffer', true) }}}; break;
- case 'glBlendEquation': ret = {{{ Functions.getIndex('_glBlendEquation', true) }}}; break;
- case 'glBlendFunc': ret = {{{ Functions.getIndex('_glBlendFunc', true) }}}; break;
- case 'glBlendFuncSeparate': ret = {{{ Functions.getIndex('_glBlendFuncSeparate', true) }}}; break;
- case 'glBlendEquationSeparate': ret = {{{ Functions.getIndex('_glBlendEquationSeparate', true) }}}; break;
- case 'glDepthRangef': ret = {{{ Functions.getIndex('_glDepthRangef', true) }}}; break;
- case 'glClear': ret = {{{ Functions.getIndex('_glClear', true) }}}; break;
- case 'glGenerateMipmap': ret = {{{ Functions.getIndex('_glGenerateMipmap', true) }}}; break;
- case 'glBlendColor': ret = {{{ Functions.getIndex('_glBlendColor', true) }}}; break;
- case 'glClearDepthf': ret = {{{ Functions.getIndex('_glClearDepthf', true) }}}; break;
- case 'glDeleteProgram': ret = {{{ Functions.getIndex('_glDeleteProgram', true) }}}; break;
- case 'glUniformMatrix3fv': ret = {{{ Functions.getIndex('_glUniformMatrix3fv', true) }}}; break;
- case 'glClearColor': ret = {{{ Functions.getIndex('_glClearColor', true) }}}; break;
- case 'glGetRenderbufferParameteriv': ret = {{{ Functions.getIndex('_glGetRenderbufferParameteriv', true) }}}; break;
- case 'glGetShaderInfoLog': ret = {{{ Functions.getIndex('_glGetShaderInfoLog', true) }}}; break;
- case 'glUniformMatrix4fv': ret = {{{ Functions.getIndex('_glUniformMatrix4fv', true) }}}; break;
- case 'glClearStencil': ret = {{{ Functions.getIndex('_glClearStencil', true) }}}; break;
- case 'glGetProgramInfoLog': ret = {{{ Functions.getIndex('_glGetProgramInfoLog', true) }}}; break;
- case 'glGetUniformfv': ret = {{{ Functions.getIndex('_glGetUniformfv', true) }}}; break;
- case 'glStencilFuncSeparate': ret = {{{ Functions.getIndex('_glStencilFuncSeparate', true) }}}; break;
- case 'glSampleCoverage': ret = {{{ Functions.getIndex('_glSampleCoverage', true) }}}; break;
- case 'glColorMask': ret = {{{ Functions.getIndex('_glColorMask', true) }}}; break;
- case 'glGetShaderiv': ret = {{{ Functions.getIndex('_glGetShaderiv', true) }}}; break;
- case 'glGetUniformiv': ret = {{{ Functions.getIndex('_glGetUniformiv', true) }}}; break;
- case 'glCopyTexSubImage2D': ret = {{{ Functions.getIndex('_glCopyTexSubImage2D', true) }}}; break;
- case 'glDetachShader': ret = {{{ Functions.getIndex('_glDetachShader', true) }}}; break;
- case 'glGetShaderSource': ret = {{{ Functions.getIndex('_glGetShaderSource', true) }}}; break;
- case 'glDeleteTextures': ret = {{{ Functions.getIndex('_glDeleteTextures', true) }}}; break;
- case 'glGetAttachedShaders': ret = {{{ Functions.getIndex('_glGetAttachedShaders', true) }}}; break;
- case 'glValidateProgram': ret = {{{ Functions.getIndex('_glValidateProgram', true) }}}; break;
- case 'glDepthFunc': ret = {{{ Functions.getIndex('_glDepthFunc', true) }}}; break;
- case 'glIsShader': ret = {{{ Functions.getIndex('_glIsShader', true) }}}; break;
- case 'glDepthMask': ret = {{{ Functions.getIndex('_glDepthMask', true) }}}; break;
- case 'glStencilMaskSeparate': ret = {{{ Functions.getIndex('_glStencilMaskSeparate', true) }}}; break;
- case 'glIsProgram': ret = {{{ Functions.getIndex('_glIsProgram', true) }}}; break;
- case 'glDisable': ret = {{{ Functions.getIndex('_glDisable', true) }}}; break;
- case 'glStencilOpSeparate': ret = {{{ Functions.getIndex('_glStencilOpSeparate', true) }}}; break;
- case 'glDrawArrays': ret = {{{ Functions.getIndex('_glDrawArrays', true) }}}; break;
- case 'glDrawElements': ret = {{{ Functions.getIndex('_glDrawElements', true) }}}; break;
- case 'glEnable': ret = {{{ Functions.getIndex('_glEnable', true) }}}; break;
- case 'glFinish': ret = {{{ Functions.getIndex('_glFinish', true) }}}; break;
- case 'glFlush': ret = {{{ Functions.getIndex('_glFlush', true) }}}; break;
- case 'glFrontFace': ret = {{{ Functions.getIndex('_glFrontFace', true) }}}; break;
- case 'glCullFace': ret = {{{ Functions.getIndex('_glCullFace', true) }}}; break;
- case 'glGenTextures': ret = {{{ Functions.getIndex('_glGenTextures', true) }}}; break;
- case 'glGetError': ret = {{{ Functions.getIndex('_glGetError', true) }}}; break;
- case 'glGetIntegerv': ret = {{{ Functions.getIndex('_glGetIntegerv', true) }}}; break;
- case 'glGetBooleanv': ret = {{{ Functions.getIndex('_glGetBooleanv', true) }}}; break;
- case 'glGetFloatv': ret = {{{ Functions.getIndex('_glGetFloatv', true) }}}; break;
- case 'glHint': ret = {{{ Functions.getIndex('_glHint', true) }}}; break;
- case 'glIsTexture': ret = {{{ Functions.getIndex('_glIsTexture', true) }}}; break;
- case 'glPixelStorei': ret = {{{ Functions.getIndex('_glPixelStorei', true) }}}; break;
- case 'glReadPixels': ret = {{{ Functions.getIndex('_glReadPixels', true) }}}; break;
- case 'glScissor': ret = {{{ Functions.getIndex('_glScissor', true) }}}; break;
- case 'glStencilFunc': ret = {{{ Functions.getIndex('_glStencilFunc', true) }}}; break;
- case 'glStencilMask': ret = {{{ Functions.getIndex('_glStencilMask', true) }}}; break;
- case 'glStencilOp': ret = {{{ Functions.getIndex('_glStencilOp', true) }}}; break;
- case 'glTexImage2D': ret = {{{ Functions.getIndex('_glTexImage2D', true) }}}; break;
- case 'glTexParameterf': ret = {{{ Functions.getIndex('_glTexParameterf', true) }}}; break;
- case 'glTexParameterfv': ret = {{{ Functions.getIndex('_glTexParameterfv', true) }}}; break;
- case 'glTexParameteri': ret = {{{ Functions.getIndex('_glTexParameteri', true) }}}; break;
- case 'glTexParameteriv': ret = {{{ Functions.getIndex('_glTexParameteriv', true) }}}; break;
- case 'glGetTexParameterfv': ret = {{{ Functions.getIndex('_glGetTexParameterfv', true) }}}; break;
- case 'glGetTexParameteriv': ret = {{{ Functions.getIndex('_glGetTexParameteriv', true) }}}; break;
- case 'glTexSubImage2D': ret = {{{ Functions.getIndex('_glTexSubImage2D', true) }}}; break;
- case 'glCopyTexImage2D': ret = {{{ Functions.getIndex('_glCopyTexImage2D', true) }}}; break;
- case 'glViewport': ret = {{{ Functions.getIndex('_glViewport', true) }}}; break;
- case 'glIsEnabled': ret = {{{ Functions.getIndex('_glIsEnabled', true) }}}; break;
- case 'glLineWidth': ret = {{{ Functions.getIndex('_glLineWidth', true) }}}; break;
- case 'glPolygonOffset': ret = {{{ Functions.getIndex('_glPolygonOffset', true) }}}; break;
- case 'glReleaseShaderCompiler': ret = {{{ Functions.getIndex('_glReleaseShaderCompiler', true) }}}; break;
- case 'glGetShaderPrecisionFormat': ret = {{{ Functions.getIndex('_glGetShaderPrecisionFormat', true) }}}; break;
- case 'glShaderBinary': ret = {{{ Functions.getIndex('_glShaderBinary', true) }}}; break;
- }
- if (!ret) Module.printErr('WARNING: getProcAddress failed for ' + name);
- return ret;
- }
},
glGetShaderPrecisionFormat__sig: 'v',
@@ -4202,7 +4037,43 @@ var LibraryGL = {
glBindVertexArrayOES: 'glBindVertexArray',
glFramebufferTexture2DOES: 'glFramebufferTexture2D',
-#endif // DISABLE_GL_EMULATION == 0
+#else // LEGACY_GL_EMULATION
+
+ // Warn if code tries to use various emulation stuff, when emulation is disabled
+ // (do not warn if INCLUDE_FULL_LIBRARY is one, because then likely the gl code will
+ // not be called anyhow, leave only the runtime aborts)
+ glVertexPointer__deps: [function() {
+#if INCLUDE_FULL_LIBRARY == 0
+ warn('Legacy GL function (glVertexPointer) called. You need to compile with -s LEGACY_GL_EMULATION=1 to enable legacy GL emulation.');
+#endif
+ }],
+ glVertexPointer: function(){ throw 'Legacy GL function (glVertexPointer) called. You need to compile with -s LEGACY_GL_EMULATION=1 to enable legacy GL emulation.'; },
+ glGenVertexArrays__deps: [function() {
+#if INCLUDE_FULL_LIBRARY == 0
+ warn('Legacy GL function (glGenVertexArrays) called. You need to compile with -s LEGACY_GL_EMULATION=1 to enable legacy GL emulation.');
+#endif
+ }],
+ glGenVertexArrays: function(){ throw 'Legacy GL function (glGenVertexArrays) called. You need to compile with -s LEGACY_GL_EMULATION=1 to enable legacy GL emulation.'; },
+ glMatrixMode__deps: [function() {
+#if INCLUDE_FULL_LIBRARY == 0
+ warn('Legacy GL function (glMatrixMode) called. You need to compile with -s LEGACY_GL_EMULATION=1 to enable legacy GL emulation.');
+#endif
+ }],
+ glMatrixMode: function(){ throw 'Legacy GL function (glMatrixMode) called. You need to compile with -s LEGACY_GL_EMULATION=1 to enable legacy GL emulation.'; },
+ glBegin__deps: [function() {
+#if INCLUDE_FULL_LIBRARY == 0
+ warn('Legacy GL function (glBegin) called. You need to compile with -s LEGACY_GL_EMULATION=1 to enable legacy GL emulation.');
+#endif
+ }],
+ glBegin: function(){ throw 'Legacy GL function (glBegin) called. You need to compile with -s LEGACY_GL_EMULATION=1 to enable legacy GL emulation.'; },
+ glLoadIdentity__deps: [function() {
+#if INCLUDE_FULL_LIBRARY == 0
+ warn('Legacy GL function (glLoadIdentity) called. You need to compile with -s LEGACY_GL_EMULATION=1 to enable legacy GL emulation.');
+#endif
+ }],
+ glLoadIdentity: function(){ throw 'Legacy GL function (glLoadIdentity) called. You need to compile with -s LEGACY_GL_EMULATION=1 to enable legacy GL emulation.'; },
+
+#endif // LEGACY_GL_EMULATION
// GLU
@@ -4438,28 +4309,60 @@ var LibraryGL = {
autoAddDeps(LibraryGL, '$GL');
-if (!DISABLE_GL_EMULATION) {
- // Emulation requires everything else, potentially
- LibraryGL.$GLEmulation__deps = LibraryGL.$GLEmulation__deps.slice(0); // the __deps object is shared
- var glFuncs = [];
- for (var item in LibraryGL) {
- if (item != '$GLEmulation' && item.substr(-6) != '__deps' && item.substr(-9) != '__postset' && item.substr(-5) != '__sig' && item.substr(0, 2) == 'gl') {
- glFuncs.push(item);
+// Legacy GL emulation
+if (LEGACY_GL_EMULATION) {
+ DEFAULT_LIBRARY_FUNCS_TO_INCLUDE.push('$GLEmulation');
+}
+
+// GL proc address retrieval
+LibraryGL.emscripten_GetProcAddress__deps = [function() {
+ // ProcAddress is used, so include everything in GL. This runs before we go to the $ProcAddressTable object,
+ // and we fill its deps just in time, and create the lookup table
+ var table = {};
+ LibraryManager.library.emscripten_procAddressTable__deps = keys(LibraryGL).map(function(x) {
+ if (x.substr(-6) == '__deps' || x.substr(-9) == '__postset' || x.substr(-5) == '__sig' || x.substr(-5) == '__asm' || x.substr(0, 2) != 'gl') return null;
+ var original = x;
+ if (('_' + x) in Functions.implementedFunctions) {
+ // a user-implemented function aliases this one, but we still want it to be accessible by name, so rename it
+ var y = x + '__procTable';
+ LibraryManager.library[y] = LibraryManager.library[x];
+ LibraryManager.library[y + '__deps'] = LibraryManager.library[x + '__deps'];
+ LibraryManager.library[y + '__postset'] = LibraryManager.library[x + '__postset'];
+ LibraryManager.library[y + '__sig'] = LibraryManager.library[x + '__sig'];//|| Functions.implementedFunctions['_' + x];
+ LibraryManager.library[y + '__asm'] = LibraryManager.library[x + '__asm'];
+ x = y;
+ assert(!(y in Functions.implementedFunctions) && !Functions.unimplementedFunctions['_' + y]);
}
- }
- LibraryGL.$GLEmulation__deps = LibraryGL.$GLEmulation__deps.concat(glFuncs);
- LibraryGL.$GLEmulation__deps.push(function() {
- for (var func in Functions.getIndex.tentative) {
- Functions.getIndex(func);
- Functions.unimplementedFunctions[func] = LibraryGL[func.substr(1) + '__sig'];
+ var longX = '_' + x;
+ var sig = LibraryManager.library[x + '__sig'] || functionStubSigs[longX];
+ if (sig) {
+ table[original] = Functions.getIndex(longX, sig);
+ if (!(longX in Functions.implementedFunctions)) Functions.unimplementedFunctions[longX] = sig;
}
- });
-
- if (FORCE_GL_EMULATION) {
- LibraryGL.glDrawElements__deps = LibraryGL.glDrawElements__deps.concat('$GLEmulation');
- LibraryGL.glDrawArrays__deps = LibraryGL.glDrawArrays__deps.concat('$GLEmulation');
+ return x;
+ }).filter(function(x) { return x !== null });
+ // convert table into function with switch, to not confuse closure compiler
+ var tableImpl = 'switch(name) {\n';
+ for (var x in table) tableImpl += 'case "' + x + '": return ' + table[x] + '; break;\n';
+ tableImpl += '}\nreturn 0;';
+ LibraryManager.library.emscripten_procAddressTable = new Function('name', tableImpl);
+}, 'emscripten_procAddressTable'];
+LibraryGL.emscripten_GetProcAddress = function(name) {
+ name = name.replace('EXT', '').replace('ARB', '');
+ switch(name) { // misc renamings
+ case 'glCreateProgramObject': name = 'glCreateProgram'; break;
+ case 'glUseProgramObject': name = 'glUseProgram'; break;
+ case 'glCreateShaderObject': name = 'glCreateShader'; break;
+ case 'glAttachObject': name = 'glAttachShader'; break;
+ case 'glDetachObject': name = 'glDetachShader'; break;
}
+ var ret = _emscripten_procAddressTable(name);
+ if (!ret) Module.printErr('WARNING: getProcAddress failed for ' + name);
+ return ret;
}
+// Final merge
mergeInto(LibraryManager.library, LibraryGL);
+assert(!(FULL_ES2 && LEGACY_GL_EMULATION), 'cannot emulate both ES2 and legacy GL');
+
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 a044e0c6..0fa6cdfb 100644
--- a/src/library_memfs.js
+++ b/src/library_memfs.js
@@ -10,16 +10,48 @@ mergeInto(LibraryManager.library, {
throw new FS.ErrnoError(ERRNO_CODES.EPERM);
}
var node = FS.createNode(parent, name, mode, dev);
- node.node_ops = MEMFS.node_ops;
if (FS.isDir(node.mode)) {
- node.stream_ops = MEMFS.stream_ops;
+ node.node_ops = {
+ getattr: MEMFS.node_ops.getattr,
+ setattr: MEMFS.node_ops.setattr,
+ lookup: MEMFS.node_ops.lookup,
+ mknod: MEMFS.node_ops.mknod,
+ mknod: MEMFS.node_ops.mknod,
+ rename: MEMFS.node_ops.rename,
+ unlink: MEMFS.node_ops.unlink,
+ rmdir: MEMFS.node_ops.rmdir,
+ readdir: MEMFS.node_ops.readdir,
+ symlink: MEMFS.node_ops.symlink
+ };
+ node.stream_ops = {
+ llseek: MEMFS.stream_ops.llseek
+ };
node.contents = {};
} else if (FS.isFile(node.mode)) {
- node.stream_ops = MEMFS.stream_ops;
+ node.node_ops = {
+ getattr: MEMFS.node_ops.getattr,
+ setattr: MEMFS.node_ops.setattr
+ };
+ node.stream_ops = {
+ llseek: MEMFS.stream_ops.llseek,
+ read: MEMFS.stream_ops.read,
+ write: MEMFS.stream_ops.write,
+ allocate: MEMFS.stream_ops.allocate,
+ mmap: MEMFS.stream_ops.mmap
+ };
node.contents = [];
} else if (FS.isLink(node.mode)) {
- node.stream_ops = MEMFS.stream_ops;
+ node.node_ops = {
+ getattr: MEMFS.node_ops.getattr,
+ setattr: MEMFS.node_ops.setattr,
+ readlink: MEMFS.node_ops.readlink
+ };
+ node.stream_ops = {};
} else if (FS.isChrdev(node.mode)) {
+ node.node_ops = {
+ getattr: MEMFS.node_ops.getattr,
+ setattr: MEMFS.node_ops.setattr
+ };
node.stream_ops = FS.chrdev_stream_ops;
}
node.timestamp = Date.now();
@@ -106,6 +138,16 @@ mergeInto(LibraryManager.library, {
}
delete parent.contents[name];
},
+ readdir: function(node) {
+ var entries = ['.', '..']
+ for (var key in node.contents) {
+ if (!node.contents.hasOwnProperty(key)) {
+ continue;
+ }
+ entries.push(key);
+ }
+ return entries;
+ },
symlink: function(parent, newname, oldpath) {
var node = MEMFS.create_node(parent, newname, 0777 | {{{ cDefine('S_IFLNK') }}}, 0);
node.link = oldpath;
@@ -119,19 +161,6 @@ mergeInto(LibraryManager.library, {
},
},
stream_ops: {
- open: function(stream) {
- if (FS.isDir(stream.node.mode)) {
- // cache off the directory entries when open'd
- var entries = ['.', '..']
- for (var key in stream.node.contents) {
- if (!stream.node.contents.hasOwnProperty(key)) {
- continue;
- }
- entries.push(key);
- }
- stream.entries = entries;
- }
- },
read: function(stream, buffer, offset, length, position) {
var contents = stream.node.contents;
var size = Math.min(contents.length - position, length);
@@ -172,9 +201,6 @@ mergeInto(LibraryManager.library, {
stream.position = position;
return position;
},
- readdir: function(stream) {
- return stream.entries;
- },
allocate: function(stream, offset, length) {
var contents = stream.node.contents;
var limit = offset + length;
diff --git a/src/library_sdl.js b/src/library_sdl.js
index 92cfc7e5..5b2f8379 100644
--- a/src/library_sdl.js
+++ b/src/library_sdl.js
@@ -258,7 +258,7 @@ var LibrarySDL = {
makeSurface: function(width, height, flags, usePageCanvas, source, rmask, gmask, bmask, amask) {
flags = flags || 0;
- var surf = _malloc(14*Runtime.QUANTUM_SIZE); // SDL_Surface has 14 fields of quantum size
+ var surf = _malloc(15*Runtime.QUANTUM_SIZE); // SDL_Surface has 15 fields of quantum size
var buffer = _malloc(width*height*4); // TODO: only allocate when locked the first time
var pixelFormat = _malloc(18*Runtime.QUANTUM_SIZE);
flags |= 1; // SDL_HWSURFACE - this tells SDL_MUSTLOCK that this needs to be locked
@@ -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;
},
@@ -590,8 +611,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;
}
@@ -755,6 +777,11 @@ var LibrarySDL = {
return depth; // all modes are ok.
},
+ SDL_AudioDriverName__deps: ['SDL_VideoDriverName'],
+ SDL_AudioDriverName: function(buf, max_size) {
+ return _SDL_VideoDriverName(buf, max_size);
+ },
+
SDL_VideoDriverName: function(buf, max_size) {
if (SDL.startTime === null) {
return 0; //return NULL
@@ -2062,9 +2089,9 @@ var LibrarySDL = {
console.log('TODO: SDL_GL_SetAttribute');
},
- SDL_GL_GetProcAddress__deps: ['$GLEmulation'],
+ SDL_GL_GetProcAddress__deps: ['emscripten_GetProcAddress'],
SDL_GL_GetProcAddress: function(name_) {
- return GLEmulation.getProcAddress(Pointer_stringify(name_));
+ return _emscripten_GetProcAddress(Pointer_stringify(name_));
},
SDL_GL_SwapBuffers: function() {},
diff --git a/src/modules.js b/src/modules.js
index 13561777..fa6c0983 100644
--- a/src/modules.js
+++ b/src/modules.js
@@ -275,20 +275,15 @@ var Functions = {
},
// Mark a function as needing indexing. Python will coordinate them all
- getIndex: function(ident, doNotCreate, sig) {
- if (doNotCreate && !(ident in this.indexedFunctions)) {
- if (!Functions.getIndex.tentative) Functions.getIndex.tentative = {}; // only used by GL emulation; TODO: generalize when needed
- Functions.getIndex.tentative[ident] = 0;
- }
+ getIndex: function(ident, sig) {
var ret;
if (phase != 'post' && singlePhase) {
- if (!doNotCreate) this.indexedFunctions[ident] = 0; // tell python we need this indexized
ret = "'{{ FI_" + toNiceIdent(ident) + " }}'"; // something python will replace later
+ this.indexedFunctions[ident] = 0;
} else {
if (!singlePhase) return 'NO_INDEX'; // Should not index functions in post
ret = this.indexedFunctions[ident];
if (!ret) {
- if (doNotCreate) return '0';
ret = this.nextIndex;
this.nextIndex += 2; // Need to have indexes be even numbers, see |polymorph| test
this.indexedFunctions[ident] = ret;
@@ -326,7 +321,7 @@ var Functions = {
tables[sig][index] = ident;
}
var generated = false;
- var wrapped = {};
+ var wrapped = {}; // whether we wrapped a lib func
var maxTable = 0;
for (var t in tables) {
if (t == 'pre') continue;
@@ -349,10 +344,11 @@ var Functions = {
if (ASM_JS) {
var curr = table[i];
if (curr && curr != '0' && !Functions.implementedFunctions[curr]) {
- curr = toNiceIdent(curr); // fix Math.* to Math_*
+ var short = toNiceIdent(curr); // fix Math.* to Math_*
+ curr = t + '_' + short; // libfuncs can alias with different sigs, wrap each separately
// This is a library function, we can't just put it in the function table, need a wrapper
if (!wrapped[curr]) {
- var args = '', arg_coercions = '', call = curr + '(', retPre = '', retPost = '';
+ var args = '', arg_coercions = '', call = short + '(', retPre = '', retPost = '';
if (t[0] != 'v') {
if (t[0] == 'i') {
retPre = 'return ';
@@ -367,7 +363,7 @@ var Functions = {
call += (j > 1 ? ',' : '') + asmCoercion('a' + j, t[j] != 'i' ? 'float' : 'i32');
}
call += ')';
- if (curr == '_setjmp') printErr('WARNING: setjmp used via a function pointer. If this is for libc setjmp (not something of your own with the same name), it will break things');
+ if (short == '_setjmp') printErr('WARNING: setjmp used via a function pointer. If this is for libc setjmp (not something of your own with the same name), it will break things');
tables.pre += 'function ' + curr + '__wrapper(' + args + ') { ' + arg_coercions + ' ; ' + retPre + call + retPost + ' }\n';
wrapped[curr] = 1;
}
diff --git a/src/parseTools.js b/src/parseTools.js
index f11c867a..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) {
@@ -1244,7 +1266,7 @@ function indexizeFunctions(value, type) {
if (!sig) {
sig = Functions.unimplementedFunctions[value] = Functions.getSignature(out.returnType, out.segments ? out.segments.map(function(segment) { return segment[0].text }) : [], isVarArgsFunctionType(type));
}
- return Functions.getIndex(value, undefined, sig);
+ return Functions.getIndex(value, sig);
}
return value;
}
diff --git a/src/postamble.js b/src/postamble.js
index c4ca3aae..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;
@@ -127,6 +135,7 @@ Module['exit'] = Module.exit = exit;
function abort(text) {
if (text) {
Module.print(text);
+ Module.printErr(text);
}
ABORT = true;
diff --git a/src/settings.js b/src/settings.js
index 3ecac040..cb64bfd9 100644
--- a/src/settings.js
+++ b/src/settings.js
@@ -191,9 +191,8 @@ var GL_TESTING = 0; // When enabled, sets preserveDrawingBuffer in the context,
var GL_MAX_TEMP_BUFFER_SIZE = 2097152; // How large GL emulation temp buffers are
var GL_UNSAFE_OPTS = 1; // Enables some potentially-unsafe optimizations in GL emulation code
var FULL_ES2 = 0; // Forces support for all GLES2 features, not just the WebGL-friendly subset.
-var FORCE_GL_EMULATION = 0; // Forces inclusion of full GL emulation code.
-var DISABLE_GL_EMULATION = 0; // Disable inclusion of full GL emulation code. Useful when you don't want emulation
- // but do need INCLUDE_FULL_LIBRARY or MAIN_MODULE.
+var LEGACY_GL_EMULATION = 0; // Includes code to emulate various desktop GL features. Incomplete but useful
+ // in some cases, see https://github.com/kripken/emscripten/wiki/OpenGL-support
var STB_IMAGE = 0; // Enables building of stb-image, a tiny public-domain library for decoding images, allowing
// decoding of images without using the browser's built-in decoders. The benefit is that this
@@ -316,11 +315,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.
diff --git a/src/shell.js b/src/shell.js
index bac4eaa3..f91aa96a 100644
--- a/src/shell.js
+++ b/src/shell.js
@@ -74,7 +74,12 @@ else if (ENVIRONMENT_IS_SHELL) {
Module['print'] = print;
if (typeof printErr != 'undefined') Module['printErr'] = printErr; // not present in v8 or older sm
- Module['read'] = read;
+ if (typeof read != 'undefined') {
+ Module['read'] = read;
+ } else {
+ Module['read'] = function() { throw 'no read() available (jsc?)' };
+ }
+
Module['readBinary'] = function(f) {
return read(f, 'binary');
};
diff --git a/system/include/compat/math.h b/system/include/compat/math.h
new file mode 100644
index 00000000..089cf66b
--- /dev/null
+++ b/system/include/compat/math.h
@@ -0,0 +1,14 @@
+#ifndef _COMPAT_MATH_H_
+#define _COMPAT_MATH_H_
+
+#ifndef isinff
+ #define isinff isinf
+#endif
+
+#ifndef isnanf
+ #define isnanf isnan
+#endif
+
+#include_next <math.h>
+
+#endif /* _COMPAT_MATH_H_ */
diff --git a/system/include/compat/stdlib.h b/system/include/compat/stdlib.h
new file mode 100644
index 00000000..dc01947d
--- /dev/null
+++ b/system/include/compat/stdlib.h
@@ -0,0 +1,16 @@
+#ifndef _COMPAT_STDLIB_H
+#define _COMPAT_STDLIB_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int getloadavg(double loadavg[], int nelem);
+
+#ifdef __cplusplus
+}
+#endif
+
+#include_next <stdlib.h>
+
+#endif
diff --git a/system/include/compat/string.h b/system/include/compat/string.h
new file mode 100644
index 00000000..880089cc
--- /dev/null
+++ b/system/include/compat/string.h
@@ -0,0 +1,17 @@
+#ifndef _COMPAT_STRING_H
+#define _COMPAT_STRING_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern char* strlwr(char *);
+extern char* strupr(char *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#include_next <string.h>
+
+#endif
diff --git a/system/include/compat/sys/stat.h b/system/include/compat/sys/stat.h
new file mode 100644
index 00000000..731502ea
--- /dev/null
+++ b/system/include/compat/sys/stat.h
@@ -0,0 +1,20 @@
+#ifndef _COMPAT_STAT_H
+#define _COMPAT_STAT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include_next <sys/stat.h>
+
+#define S_IRWXUGO (S_IRWXU|S_IRWXG|S_IRWXO)
+#define S_IALLUGO (S_ISUID|S_ISGID|S_ISVTX|S_IRWXUGO)
+#define S_IRUGO (S_IRUSR|S_IRGRP|S_IROTH)
+#define S_IWUGO (S_IWUSR|S_IWGRP|S_IWOTH)
+#define S_IXUGO (S_IXUSR|S_IXGRP|S_IXOTH)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/system/include/libc/sys/timeb.h b/system/include/compat/sys/timeb.h
index 0a2c3de8..0a2c3de8 100644
--- a/system/include/libc/sys/timeb.h
+++ b/system/include/compat/sys/timeb.h
diff --git a/system/include/compat/unistd.h b/system/include/compat/unistd.h
new file mode 100644
index 00000000..07c3afde
--- /dev/null
+++ b/system/include/compat/unistd.h
@@ -0,0 +1,16 @@
+#ifndef _COMPAT_UNISTD_H
+#define _COMPAT_UNISTD_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+char * getwd(char *__buf );
+
+#ifdef __cplusplus
+}
+#endif
+
+#include_next <unistd.h>
+
+#endif
diff --git a/system/include/compat/xlocale.h b/system/include/compat/xlocale.h
new file mode 100644
index 00000000..4bafa27d
--- /dev/null
+++ b/system/include/compat/xlocale.h
@@ -0,0 +1,21 @@
+#ifndef _COMPAT_XLOCALE_H_
+#define _COMPAT_XLOCALE_H_
+
+#include <locale.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+long long strtoll_l(const char *start, char **end, int base, locale_t loc);
+unsigned long long strtoull_l(const char *start, char **end, int base, locale_t loc);
+double strtold_l(const char *start, char **end, locale_t loc);
+
+#ifdef __cplusplus
+}
+#endif
+
+#include_next <xlocale.h>
+
+#endif /* _COMPAT_XLOCALE_H_ */
+
diff --git a/system/include/emscripten/emscripten.h b/system/include/emscripten/emscripten.h
index 28e6063c..f0df8dca 100644
--- a/system/include/emscripten/emscripten.h
+++ b/system/include/emscripten/emscripten.h
@@ -20,14 +20,13 @@ extern "C" {
/*
* Forces LLVM to not dead-code-eliminate a function. Note that
- * closure may still eliminate it at the JS level, for which you
- * should use EXPORTED_FUNCTIONS (see settings.js).
- *
- * **DEPRECATED**: Use EXPORTED_FUNCTIONS instead, which will work
- * with closure, asm.js, etc. For example
- * -s EXPORTED_FUNCTIONS=["_main", "myfunc"]
+ * you still need to use EXPORTED_FUNCTIONS so it stays alive
+ * in JS, e.g.
+ * emcc -s EXPORTED_FUNCTIONS=["_main", "_myfunc"]
+ * and in the source file
+ * void EMSCRIPTEN_KEEPALIVE myfunc() {..}
*/
-/* #define EMSCRIPTEN_KEEPALIVE __attribute__((used)) */
+#define EMSCRIPTEN_KEEPALIVE __attribute__((used))
/*
* Interface to the underlying JS engine. This function will
diff --git a/system/include/libc/stdlib.h b/system/include/libc/stdlib.h
index 888b6041..6fdef40b 100644
--- a/system/include/libc/stdlib.h
+++ b/system/include/libc/stdlib.h
@@ -223,8 +223,6 @@ extern long double strtold (const char *, char **);
extern long double wcstold (const wchar_t *, wchar_t **);
#endif /* _LDBL_EQ_DBL */
-int getloadavg(double loadavg[], int nelem); /* XXX Emscripten */
-
_END_STD_C
#endif /* _STDLIB_H_ */
diff --git a/system/include/libc/string.h b/system/include/libc/string.h
index 515c71a7..8fd9ea43 100644
--- a/system/include/libc/string.h
+++ b/system/include/libc/string.h
@@ -72,8 +72,6 @@ size_t _EXFUN(strlcpy,(char *, const char *, size_t));
int _EXFUN(strncasecmp,(const char *, const char *, size_t));
size_t _EXFUN(strnlen,(const char *, size_t));
char *_EXFUN(strsep,(char **, const char *));
-char *_EXFUN(strlwr,(char *));
-char *_EXFUN(strupr,(char *));
#if defined(__CYGWIN__) || defined(EMSCRIPTEN)
#ifndef DEFS_H /* Kludge to work around problem compiling in gdb */
char *_EXFUN(strsignal, (int __signo));
diff --git a/system/include/libc/sys/unistd.h b/system/include/libc/sys/unistd.h
index 1a414b3c..a4219d4d 100644
--- a/system/include/libc/sys/unistd.h
+++ b/system/include/libc/sys/unistd.h
@@ -102,7 +102,6 @@ uid_t _EXFUN(getuid, (void ));
#endif
#if defined(EMSCRIPTEN) || defined(__CYGWIN__)
char * _EXFUN(getusershell, (void));
-char * _EXFUN(getwd, (char *__buf ));
int _EXFUN(iruserok, (unsigned long raddr, int superuser, const char *ruser, const char *luser));
#endif
int _EXFUN(isatty, (int __fildes ));
diff --git a/system/include/xlocale.h b/system/include/xlocale.h
index bb3b50e5..6867d25f 100644
--- a/system/include/xlocale.h
+++ b/system/include/xlocale.h
@@ -1,4 +1,3 @@
-
#ifndef _XLOCALE_H_
#define _XLOCALE_H_
@@ -9,10 +8,6 @@
extern "C" {
#endif
-long long strtoll_l(const char *start, char **end, int base, locale_t loc);
-unsigned long long strtoull_l(const char *start, char **end, int base, locale_t loc);
-double strtold_l(const char *start, char **end, locale_t loc);
-
int strcoll_l(const char *s1, const char *s2, locale_t locale);
int wcscoll_l(const wchar_t *ws1, const wchar_t *ws2, locale_t locale);
@@ -43,5 +38,5 @@ size_t strftime_l(char *s, size_t maxsize, const char *format, const struct tm *
}
#endif
-#endif /* _LOCALE_H_ */
+#endif /* _XLOCALE_H_ */
diff --git a/tests/aniso.c b/tests/aniso.c
index 1126265e..f210e5a5 100644
--- a/tests/aniso.c
+++ b/tests/aniso.c
@@ -161,7 +161,7 @@ int main(int argc, char *argv[])
for (int x = 0; x < n; x++) {
int start = x*w*2;
glBegin( GL_TRIANGLES );
- glTexCoord2i( 1, 0 ); glVertex3f( start , 0, 0 );
+ glTexCoord2i( 1, 0 ); glVertex2i( start , 0 );
glTexCoord2i( 0, 0 ); glVertex3f( start+w, 300, 0 );
glTexCoord2i( 1, 1 ); glVertex3f( start-w, 300, 0 );
glEnd();
@@ -209,5 +209,11 @@ int main(int argc, char *argv[])
SDL_Quit();
- return 0;
+ // check for asm compilation bug with aliased functions with different sigs
+ void (*f)(int, int) = glVertex2i;
+ if ((int)f % 16 == 4) f(5, 7);
+ void (*g)(int, int) = glVertex3f;
+ if ((int)g % 16 == 4) g(5, 7);
+ return (int)f + (int)g;
}
+
diff --git a/tests/cases/phi24_ta2.ll b/tests/cases/phi24_ta2.ll
index 4894d5e6..2d9b6646 100644
--- a/tests/cases/phi24_ta2.ll
+++ b/tests/cases/phi24_ta2.ll
@@ -252,6 +252,7 @@ target triple = "i386-pc-linux-gnu"
@g_287 = internal constant i32 -1, align 4
define i32 @main(i32 %argc, i8** nocapture %argv) nounwind {
+ %msgdummy = alloca { i8*, { i64, i8* } (i8*)* } ; test for parsing of this kind of stuff, compilation-only test
%p_6.i.i = alloca %union.U3, align 8
%1 = icmp eq i32 %argc, 2
br i1 %1, label %2, label %7
diff --git a/tests/glut_touchevents.c b/tests/glut_touchevents.c
new file mode 100644
index 00000000..1f097895
--- /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);
+ 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/runner.py b/tests/runner.py
index 41fd5b90..bbbc23e5 100755
--- a/tests/runner.py
+++ b/tests/runner.py
@@ -48,6 +48,9 @@ class RunnerCore(unittest.TestCase):
env = {}
+ def skipme(self): # used by tests we ask on the commandline to be skipped, see right before call to unittest.main
+ return self.skip('requested to be skipped')
+
def setUp(self):
Settings.reset()
self.banned_js_engines = []
@@ -272,6 +275,18 @@ process(sys.argv[1])
print "Output: " + output[0]
return output[0]
+ # Tests that the given two paths are identical, modulo path delimiters. E.g. "C:/foo" is equal to "C:\foo".
+ def assertPathsIdentical(self, path1, path2):
+ path1 = path1.replace('\\', '/')
+ path2 = path2.replace('\\', '/')
+ return self.assertIdentical(path1, path2)
+
+ # Tests that the given two multiline text content are identical, modulo line ending differences (\r\n on Windows, \n on Unix).
+ def assertTextDataIdentical(self, text1, text2):
+ text1 = text1.replace('\r\n', '\n')
+ text2 = text2.replace('\r\n', '\n')
+ return self.assertIdentical(text1, text2)
+
def assertIdentical(self, values, y):
if type(values) not in [list, tuple]: values = [values]
for x in values:
@@ -477,7 +492,7 @@ def server_func(dir, q):
if 'report_' in s.path:
q.put(s.path)
else:
- filename = s.path[1:]
+ filename = s.path.split('?')[0][1:]
if os.path.exists(filename):
s.send_response(200)
s.send_header("Content-type", "text/html")
@@ -646,6 +661,7 @@ class BrowserCore(RunnerCore):
self.reftest(path_from_root('tests', reference))
args = args + ['--pre-js', 'reftest.js', '-s', 'GL_TESTING=1']
Popen([PYTHON, EMCC, temp_filepath, '-o', outfile] + args).communicate()
+ assert os.path.exists(outfile)
if type(expected) is str: expected = [expected]
self.run_browser(outfile, message, ['/report_result?' + e for e in expected])
@@ -660,9 +676,55 @@ if __name__ == '__main__':
elif len(JS_ENGINES) < total_engines:
print 'WARNING: Not all the JS engines in JS_ENGINES appears to work, ignoring those.'
+ # Create a list of modules to load tests from
+ modules = []
+ for filename in glob.glob(os.path.join(os.path.dirname(__file__), 'test*.py')):
+ module_dir, module_file = os.path.split(filename)
+ module_name, module_ext = os.path.splitext(module_file)
+ __import__(module_name)
+ modules.append(sys.modules[module_name])
+
+ # Extract the JS engine override from the arguments (used by benchmarks)
+ for i in range(1, len(sys.argv)):
+ arg = sys.argv[i]
+ if arg.isupper():
+ print 'Interpreting all capital argument "%s" as JS_ENGINE override' % arg
+ Building.JS_ENGINE_OVERRIDE = eval(arg)
+ sys.argv[i] = None
+ sys.argv = filter(lambda arg: arg is not None, sys.argv)
+
# If an argument comes in as test_*, treat it as a test of the default suite
sys.argv = map(lambda arg: arg if not arg.startswith('test_') else 'default.' + arg, sys.argv)
+ # If a test (e.g. test_html) is specified as ALL.test_html, add an entry for each test_mode
+ if len(sys.argv) == 2 and sys.argv[1].startswith('ALL.'):
+ ignore, test = sys.argv[1].split('.')
+ print 'Running all test modes on test "%s"' % test
+ sys.argv = [sys.argv[0]] + map(lambda mode: mode+'.'+test, test_modes)
+
+ # Skip requested tests
+ for i in range(len(sys.argv)):
+ arg = sys.argv[i]
+ if arg.startswith('skip:'):
+ which = arg.split('skip:')[1]
+ if which.startswith('ALL.'):
+ ignore, test = which.split('.')
+ which = map(lambda mode: mode+'.'+test, test_modes)
+ else:
+ which = [which]
+
+ print >> sys.stderr, ','.join(which)
+ for test in which:
+ print >> sys.stderr, 'will skip "%s"' % test
+ for m in modules:
+ try:
+ exec('m.' + test + ' = RunnerCore("skipme")')
+ break
+ except:
+ pass
+ sys.argv[i] = None
+ sys.argv = filter(lambda arg: arg is not None, sys.argv)
+
# If no tests were specified, run the core suite
if len(sys.argv) == 1:
sys.argv = [sys.argv[0]] + map(lambda mode: mode, test_modes)
@@ -670,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
@@ -706,55 +769,6 @@ an individual test with
'''
time.sleep(2)
- # If a test (e.g. test_html) is specified as ALL.test_html, add an entry for each test_mode
- if len(sys.argv) == 2 and sys.argv[1].startswith('ALL.'):
- ignore, test = sys.argv[1].split('.')
- print 'Running all test modes on test "%s"' % test
- sys.argv = [sys.argv[0]] + map(lambda mode: mode+'.'+test, test_modes)
-
- # Extract the JS engine override from the arguments (used by benchmarks)
- for i in range(1, len(sys.argv)):
- arg = sys.argv[i]
- if arg.isupper():
- print 'Interpreting all capital argument "%s" as JS_ENGINE override' % arg
- Building.JS_ENGINE_OVERRIDE = eval(arg)
- sys.argv[i] = None
- sys.argv = filter(lambda arg: arg is not None, sys.argv)
-
- # Create a list of modules to load tests from
- modules = []
- for filename in glob.glob(os.path.join(os.path.dirname(__file__), 'test*.py')):
- module_dir, module_file = os.path.split(filename)
- module_name, module_ext = os.path.splitext(module_file)
- __import__(module_name)
- modules.append(sys.modules[module_name])
-
- # Skip requested tests
- def skipme(self):
- return self.skip('requested to be skipped')
-
- for i in range(len(sys.argv)):
- arg = sys.argv[i]
- if arg.startswith('skip:'):
- which = arg.split('skip:')[1]
- if which.startswith('ALL.'):
- ignore, test = which.split('.')
- which = map(lambda mode: mode+'.'+test, test_modes)
- else:
- which = [which]
-
- print >> sys.stderr, ','.join(which)
- for test in which:
- print >> sys.stderr, 'will skip "%s"' % test
- for m in modules:
- try:
- exec('m.' + test + ' = skipme')
- break
- except:
- pass
- sys.argv[i] = None
- sys.argv = filter(lambda arg: arg is not None, sys.argv)
-
# Filter and load tests from the discovered modules
loader = unittest.TestLoader()
names = sys.argv[1:]
@@ -765,10 +779,17 @@ an individual test with
except:
pass
+ numFailures = 0 # Keep count of the total number of failing tests.
+
# Run the discovered tests
if not len(suites):
print >> sys.stderr, 'No tests found for %s' % str(sys.argv[1:])
+ numFailures = 1
else:
testRunner = unittest.TextTestRunner(verbosity=2)
for suite in suites:
- testRunner.run(suite)
+ results = testRunner.run(suite)
+ numFailures += len(results.errors) + len(results.failures)
+
+ # Return the number of failures as the process exit code for automating success/failure reporting.
+ exit(numFailures)
diff --git a/tests/sdl_ogl_proc_alias.c b/tests/sdl_ogl_proc_alias.c
new file mode 100644
index 00000000..c96da81b
--- /dev/null
+++ b/tests/sdl_ogl_proc_alias.c
@@ -0,0 +1,180 @@
+/*******************************************************************
+ * *
+ * Using SDL With OpenGL *
+ * *
+ * Tutorial by Kyle Foley (sdw) *
+ * *
+ * http://gpwiki.org/index.php/SDL:Tutorials:Using_SDL_with_OpenGL *
+ * *
+ *******************************************************************/
+
+/*
+THIS WORK, INCLUDING THE SOURCE CODE, DOCUMENTATION
+AND RELATED MEDIA AND DATA, IS PLACED INTO THE PUBLIC DOMAIN.
+
+THE ORIGINAL AUTHOR IS KYLE FOLEY.
+
+THIS SOFTWARE IS PROVIDED AS-IS WITHOUT WARRANTY
+OF ANY KIND, NOT EVEN THE IMPLIED WARRANTY OF
+MERCHANTABILITY. THE AUTHOR OF THIS SOFTWARE,
+ASSUMES _NO_ RESPONSIBILITY FOR ANY CONSEQUENCE
+RESULTING FROM THE USE, MODIFICATION, OR
+REDISTRIBUTION OF THIS SOFTWARE.
+*/
+
+#include "SDL/SDL.h"
+#include "SDL/SDL_image.h"
+#include "SDL/SDL_opengl.h"
+
+#include <stdio.h>
+#include <string.h>
+
+void (*true_glGenTextures)(GLsizei, GLuint*) = NULL;
+
+void glGenTextures(GLsizei n, GLuint *textures) {
+ printf("num? %d\n", n);
+ true_glGenTextures(n + 1, textures); // correct the error, ensures we are gone through
+}
+
+int main(int argc, char *argv[])
+{
+ SDL_Surface *screen;
+
+ // Slightly different SDL initialization
+ if ( SDL_Init(SDL_INIT_VIDEO) != 0 ) {
+ printf("Unable to initialize SDL: %s\n", SDL_GetError());
+ return 1;
+ }
+
+ SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); // *new*
+
+ screen = SDL_SetVideoMode( 640, 480, 16, SDL_OPENGL ); // *changed*
+ if ( !screen ) {
+ printf("Unable to set video mode: %s\n", SDL_GetError());
+ return 1;
+ }
+
+ // Set the OpenGL state after creating the context with SDL_SetVideoMode
+
+ glClearColor( 0, 0, 0, 0 );
+
+ glEnable( GL_TEXTURE_2D ); // Needed when we're using the fixed-function pipeline.
+
+ glViewport( 0, 0, 640, 480 );
+
+ glMatrixMode( GL_PROJECTION );
+ glPushMatrix(); // just for testing
+ glLoadIdentity();
+
+ glOrtho( 0, 640, 480, 0, -1, 1 );
+
+ glMatrixMode( GL_MODELVIEW );
+ glLoadIdentity();
+
+ // Load the OpenGL texture
+
+ GLuint texture; // Texture object handle
+ SDL_Surface *surface; // Gives us the information to make the texture
+
+ if ( (surface = IMG_Load("screenshot.png")) ) {
+
+ // Check that the image's width is a power of 2
+ if ( (surface->w & (surface->w - 1)) != 0 ) {
+ printf("warning: image.bmp's width is not a power of 2\n");
+ }
+
+ // Also check if the height is a power of 2
+ if ( (surface->h & (surface->h - 1)) != 0 ) {
+ printf("warning: image.bmp's height is not a power of 2\n");
+ }
+
+ true_glGenTextures = SDL_GL_GetProcAddress("glGenTextures");
+
+ // Have OpenGL generate a texture object handle for us
+ glGenTextures( 0, &texture );
+
+ // Bind the texture object
+ glBindTexture( GL_TEXTURE_2D, texture );
+
+ // Set the texture's stretching properties
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
+
+ //SDL_LockSurface(surface);
+
+ // Add some greyness
+ memset(surface->pixels, 0x66, surface->w*surface->h);
+
+ // Edit the texture object's image data using the information SDL_Surface gives us
+ glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, surface->w, surface->h, 0,
+ GL_RGBA, GL_UNSIGNED_BYTE, surface->pixels );
+
+ //SDL_UnlockSurface(surface);
+ }
+ else {
+ printf("SDL could not load image.bmp: %s\n", SDL_GetError());
+ SDL_Quit();
+ return 1;
+ }
+
+ // Free the SDL_Surface only if it was successfully created
+ if ( surface ) {
+ SDL_FreeSurface( surface );
+ }
+
+ // Clear the screen before drawing
+ glClear( GL_COLOR_BUFFER_BIT );
+
+ // Bind the texture to which subsequent calls refer to
+ glBindTexture( GL_TEXTURE_2D, texture );
+
+ glBegin( GL_QUADS );
+ glTexCoord2i( 0, 0 ); glVertex3f( 10, 10, 0 );
+ glTexCoord2i( 1, 0 ); glVertex3f( 300, 10, 0 );
+ glTexCoord2i( 1, 1 ); glVertex3f( 300, 128, 0 );
+ glTexCoord2i( 0, 1 ); glVertex3f( 10, 128, 0 );
+
+ glTexCoord2f( 0, 0.5 ); glVertex3f( 410, 10, 0 );
+ glTexCoord2f( 1, 0.5 ); glVertex3f( 600, 10, 0 );
+ glTexCoord2f( 1, 1 ); glVertex3f( 630, 200, 0 );
+ glTexCoord2f( 0.5, 1 ); glVertex3f( 310, 250, 0 );
+ glEnd();
+
+ glBegin( GL_TRIANGLE_STRIP );
+ glTexCoord2i( 0, 0 ); glVertex3f( 100, 300, 0 );
+ glTexCoord2i( 1, 0 ); glVertex3f( 300, 300, 0 );
+ glTexCoord2i( 1, 1 ); glVertex3f( 300, 400, 0 );
+ glTexCoord2i( 0, 1 ); glVertex3f( 500, 410, 0 );
+ glEnd();
+
+ glDisable(GL_TEXTURE_2D);
+
+ glColor3ub(90, 255, 255);
+ glBegin( GL_QUADS );
+ glVertex3f( 10, 410, 0 );
+ glVertex3f( 300, 410, 0 );
+ glVertex3f( 300, 480, 0 );
+ glVertex3f( 10, 470, 0 );
+ glEnd();
+
+ glBegin( GL_QUADS );
+ glColor3f(1.0, 0, 1.0); glVertex3f( 410, 410, 0 );
+ glColor3f(0, 1.0, 0); glVertex3f( 600, 410, 0 );
+ glColor3f(0, 0, 1.0); glVertex3f( 600, 480, 0 );
+ glColor3f(1.0, 1.0, 1.0); glVertex3f( 410, 470, 0 );
+ glEnd();
+
+ SDL_GL_SwapBuffers();
+
+#if !EMSCRIPTEN
+ // Wait for 3 seconds to give us a chance to see the image
+ SDL_Delay(3000);
+#endif
+
+ // Now we can delete the OpenGL texture and close down SDL
+ glDeleteTextures( 1, &texture );
+
+ SDL_Quit();
+
+ return 0;
+}
diff --git a/tests/sockets/test_sockets_echo_server.c b/tests/sockets/test_sockets_echo_server.c
index 8a48b878..f01004c3 100644
--- a/tests/sockets/test_sockets_echo_server.c
+++ b/tests/sockets/test_sockets_echo_server.c
@@ -37,6 +37,11 @@ typedef struct {
server_t server;
client_t client;
+void cleanup() {
+ if (server.fd) close(server.fd);
+ if (client.fd) close(client.fd);
+}
+
void main_loop(void *arg) {
int res;
fd_set fdr;
@@ -105,6 +110,9 @@ int main() {
struct sockaddr_in addr;
int res;
+ atexit(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 57fae84b..21096552 100644
--- a/tests/sockets/test_sockets_partial_server.c
+++ b/tests/sockets/test_sockets_partial_server.c
@@ -14,18 +14,13 @@
#include <emscripten.h>
#endif
-int serverfd = -1;
-int clientfd = -1;
-
-// csock.send("\x09\x01\x02\x03\x04\x05\x06\x07\x08\x09")
-// csock.send("\x08\x01\x02\x03\x04\x05\x06\x07\x08")
-// csock.send("\x07\x01\x02\x03\x04\x05\x06\x07")
-// csock.send("\x06\x01\x02\x03\x04\x05\x06")
-// csock.send("\x05\x01\x02\x03\x04\x05")
-// csock.send("\x04\x01\x02\x03\x04")
-// csock.send("\x03\x01\x02\x03")
-// csock.send("\x02\x01\x02")
-// csock.send("\x01\x01")
+int serverfd = 0;
+int clientfd = 0;
+
+void cleanup() {
+ if (serverfd) close(serverfd);
+ if (clientfd) close(clientfd);
+}
void do_send(int sockfd) {
static char* buffers[] = {
@@ -69,7 +64,7 @@ void iter(void *arg) {
FD_ZERO(&fdr);
FD_ZERO(&fdw);
FD_SET(serverfd, &fdr);
- if (clientfd != -1) FD_SET(clientfd, &fdw);
+ if (clientfd) FD_SET(clientfd, &fdw);
res = select(64, &fdr, &fdw, NULL, NULL);
if (res == -1) {
perror("select failed");
@@ -91,6 +86,9 @@ int main() {
struct sockaddr_in addr;
int res;
+ atexit(cleanup);
+ //signal(SIGTERM, cleanup);
+
// create the socket
serverfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
if (serverfd == -1) {
diff --git a/tests/sockets/webrtc_host.c b/tests/sockets/webrtc_host.c
new file mode 100644
index 00000000..770e59e0
--- /dev/null
+++ b/tests/sockets/webrtc_host.c
@@ -0,0 +1,89 @@
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <assert.h>
+#if EMSCRIPTEN
+#include <emscripten.h>
+#endif
+
+#define EXPECTED_BYTES 5
+#define BUFLEN 16
+
+int result = 0;
+int sock;
+char buf[BUFLEN];
+char expected[] = "emscripten";
+struct sockaddr_in si_host,
+ si_peer;
+struct iovec iov[1];
+struct msghdr hdr;
+int done = 0;
+
+void iter(void* arg) {
+ int n;
+ n = recvmsg(sock, &hdr, 0);
+
+ if(0 < n) {
+ done = 1;
+ fprintf(stderr, "received %d bytes: %s", n, (char*)hdr.msg_iov[0].iov_base);
+
+ shutdown(sock, SHUT_RDWR);
+ close(sock);
+
+#if EMSCRIPTEN
+ int result = 1;
+ REPORT_RESULT();
+ exit(EXIT_SUCCESS);
+ emscripten_cancel_main_loop();
+#endif
+ } else if(EWOULDBLOCK != errno) {
+ perror("recvmsg failed");
+ exit(EXIT_FAILURE);
+ emscripten_cancel_main_loop();
+ }
+}
+
+int main(void)
+{
+ memset(&si_host, 0, sizeof(struct sockaddr_in));
+ memset(&si_peer, 0, sizeof(struct sockaddr_in));
+
+ si_host.sin_family = AF_INET;
+ si_host.sin_port = htons(8991);
+ si_host.sin_addr.s_addr = htonl(INADDR_ANY);
+
+ if(-1 == (sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP))) {
+ perror("cannot create host socket");
+ exit(EXIT_FAILURE);
+ }
+
+ if(-1 == bind(sock, (struct sockaddr*)&si_host, sizeof(struct sockaddr))) {
+ perror("cannot bind host socket");
+ exit(EXIT_FAILURE);
+ }
+
+ iov[0].iov_base = buf;
+ iov[0].iov_len = sizeof(buf);
+
+ memset (&hdr, 0, sizeof (struct msghdr));
+
+ hdr.msg_name = &si_peer;
+ hdr.msg_namelen = sizeof(struct sockaddr_in);
+ hdr.msg_iov = iov;
+ hdr.msg_iovlen = 1;
+
+#if EMSCRIPTEN
+ emscripten_set_main_loop(iter, 0, 0);
+#else
+ while (!done) iter(NULL);
+#endif
+
+ return EXIT_SUCCESS;
+} \ No newline at end of file
diff --git a/tests/sockets/webrtc_peer.c b/tests/sockets/webrtc_peer.c
new file mode 100644
index 00000000..d24979e7
--- /dev/null
+++ b/tests/sockets/webrtc_peer.c
@@ -0,0 +1,81 @@
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <assert.h>
+#if EMSCRIPTEN
+#include <emscripten.h>
+#endif
+
+#define EXPECTED_BYTES 5
+#define BUFLEN 16
+#define HOST_ADDR "10.0.0.1"
+
+int result = 0;
+int sock;
+char buf[16] = "emscripten";
+struct sockaddr_in si_host;
+struct iovec iov[1];
+struct msghdr hdr;
+int done = 0;
+
+void iter(void* arg) {
+ int n;
+ n = sendmsg(sock, &hdr, 0);
+
+ if(0 < n) {
+ done = 1;
+ fprintf(stderr, "sent %d bytes: %s", n, (char*)hdr.msg_iov[0].iov_base);
+
+ shutdown(sock, SHUT_RDWR);
+ close(sock);
+
+ exit(EXIT_SUCCESS);
+ emscripten_cancel_main_loop();
+ } else if(EWOULDBLOCK != errno) {
+ perror("sendmsg failed");
+ exit(EXIT_FAILURE);
+ emscripten_cancel_main_loop();
+ }
+}
+
+int main(void)
+{
+ memset(&si_host, 0, sizeof(struct sockaddr_in));
+
+ si_host.sin_family = AF_INET;
+ si_host.sin_port = htons(8991);
+ if(0 == inet_pton(AF_INET, HOST_ADDR, &si_host.sin_addr)) {
+ perror("inet_aton failed");
+ exit(EXIT_FAILURE);
+ }
+
+ if(-1 == (sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP))) {
+ perror("cannot create socket");
+ exit(EXIT_FAILURE);
+ }
+
+ iov[0].iov_base = buf;
+ iov[0].iov_len = sizeof(buf);
+
+ memset (&hdr, 0, sizeof (struct msghdr));
+
+ hdr.msg_name = &si_host;
+ hdr.msg_namelen = sizeof(struct sockaddr_in);
+ hdr.msg_iov = iov;
+ hdr.msg_iovlen = 1;
+
+#if EMSCRIPTEN
+ emscripten_set_main_loop(iter, 0, 0);
+#else
+ while (!done) iter(NULL);
+#endif
+
+ return EXIT_SUCCESS;
+} \ No newline at end of file
diff --git a/tests/test_browser.py b/tests/test_browser.py
index 60c030aa..7c387071 100644
--- a/tests/test_browser.py
+++ b/tests/test_browser.py
@@ -620,7 +620,7 @@ Press any key to continue.'''
def test_sdl_canvas(self):
open(os.path.join(self.get_dir(), 'sdl_canvas.c'), 'w').write(self.with_report_result(open(path_from_root('tests', 'sdl_canvas.c')).read()))
- Popen([PYTHON, EMCC, os.path.join(self.get_dir(), 'sdl_canvas.c'), '-o', 'page.html']).communicate()
+ Popen([PYTHON, EMCC, os.path.join(self.get_dir(), 'sdl_canvas.c'), '-o', 'page.html', '-s', 'LEGACY_GL_EMULATION=1']).communicate()
self.run_browser('page.html', '', '/report_result?1')
def test_sdl_key(self):
@@ -787,6 +787,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('''
@@ -843,50 +846,55 @@ Press any key to continue.'''
def test_sdl_ogl(self):
shutil.copyfile(path_from_root('tests', 'screenshot.png'), os.path.join(self.get_dir(), 'screenshot.png'))
self.btest('sdl_ogl.c', reference='screenshot-gray-purple.png', reference_slack=1,
- args=['-O2', '--minify', '0', '--preload-file', 'screenshot.png'],
+ args=['-O2', '--minify', '0', '--preload-file', 'screenshot.png', '-s', 'LEGACY_GL_EMULATION=1'],
message='You should see an image with gray at the top.')
def test_sdl_ogl_defaultmatrixmode(self):
shutil.copyfile(path_from_root('tests', 'screenshot.png'), os.path.join(self.get_dir(), 'screenshot.png'))
self.btest('sdl_ogl_defaultMatrixMode.c', reference='screenshot-gray-purple.png', reference_slack=1,
- args=['--minify', '0', '--preload-file', 'screenshot.png'],
+ args=['--minify', '0', '--preload-file', 'screenshot.png', '-s', 'LEGACY_GL_EMULATION=1'],
message='You should see an image with gray at the top.')
def test_sdl_ogl_p(self):
# Immediate mode with pointers
shutil.copyfile(path_from_root('tests', 'screenshot.png'), os.path.join(self.get_dir(), 'screenshot.png'))
self.btest('sdl_ogl_p.c', reference='screenshot-gray.png', reference_slack=1,
- args=['--preload-file', 'screenshot.png'],
+ args=['--preload-file', 'screenshot.png', '-s', 'LEGACY_GL_EMULATION=1'],
message='You should see an image with gray at the top.')
+ def test_sdl_ogl_proc_alias(self):
+ shutil.copyfile(path_from_root('tests', 'screenshot.png'), os.path.join(self.get_dir(), 'screenshot.png'))
+ self.btest('sdl_ogl_proc_alias.c', reference='screenshot-gray-purple.png', reference_slack=1,
+ args=['-O2', '-g2', '-s', 'INLINING_LIMIT=1', '--preload-file', 'screenshot.png', '-s', 'LEGACY_GL_EMULATION=1', '-s', 'VERBOSE=1'])
+
def test_sdl_fog_simple(self):
shutil.copyfile(path_from_root('tests', 'screenshot.png'), os.path.join(self.get_dir(), 'screenshot.png'))
self.btest('sdl_fog_simple.c', reference='screenshot-fog-simple.png',
- args=['-O2', '--minify', '0', '--preload-file', 'screenshot.png'],
+ args=['-O2', '--minify', '0', '--preload-file', 'screenshot.png', '-s', 'LEGACY_GL_EMULATION=1'],
message='You should see an image with fog.')
def test_sdl_fog_negative(self):
shutil.copyfile(path_from_root('tests', 'screenshot.png'), os.path.join(self.get_dir(), 'screenshot.png'))
self.btest('sdl_fog_negative.c', reference='screenshot-fog-negative.png',
- args=['--preload-file', 'screenshot.png'],
+ args=['--preload-file', 'screenshot.png', '-s', 'LEGACY_GL_EMULATION=1'],
message='You should see an image with fog.')
def test_sdl_fog_density(self):
shutil.copyfile(path_from_root('tests', 'screenshot.png'), os.path.join(self.get_dir(), 'screenshot.png'))
self.btest('sdl_fog_density.c', reference='screenshot-fog-density.png',
- args=['--preload-file', 'screenshot.png'],
+ args=['--preload-file', 'screenshot.png', '-s', 'LEGACY_GL_EMULATION=1'],
message='You should see an image with fog.')
def test_sdl_fog_exp2(self):
shutil.copyfile(path_from_root('tests', 'screenshot.png'), os.path.join(self.get_dir(), 'screenshot.png'))
self.btest('sdl_fog_exp2.c', reference='screenshot-fog-exp2.png',
- args=['--preload-file', 'screenshot.png'],
+ args=['--preload-file', 'screenshot.png', '-s', 'LEGACY_GL_EMULATION=1'],
message='You should see an image with fog.')
def test_sdl_fog_linear(self):
shutil.copyfile(path_from_root('tests', 'screenshot.png'), os.path.join(self.get_dir(), 'screenshot.png'))
self.btest('sdl_fog_linear.c', reference='screenshot-fog-linear.png', reference_slack=1,
- args=['--preload-file', 'screenshot.png'],
+ args=['--preload-file', 'screenshot.png', '-s', 'LEGACY_GL_EMULATION=1'],
message='You should see an image with fog.')
def test_openal_playback(self):
@@ -903,7 +911,7 @@ Press any key to continue.'''
def test_glfw(self):
open(os.path.join(self.get_dir(), 'glfw.c'), 'w').write(self.with_report_result(open(path_from_root('tests', 'glfw.c')).read()))
- Popen([PYTHON, EMCC, '-O2', os.path.join(self.get_dir(), 'glfw.c'), '-o', 'page.html']).communicate()
+ Popen([PYTHON, EMCC, '-O2', os.path.join(self.get_dir(), 'glfw.c'), '-o', 'page.html', '-s', 'LEGACY_GL_EMULATION=1']).communicate()
self.run_browser('page.html', '', '/report_result?1')
def test_egl_width_height(self):
@@ -1056,30 +1064,26 @@ Press any key to continue.'''
server.terminate()
def test_glgears(self):
- self.btest('hello_world_gles.c', reference='gears.png',
+ self.btest('hello_world_gles.c', reference='gears.png', reference_slack=1,
args=['-DHAVE_BUILTIN_SINCOS'], outfile='something.html',
message='You should see animating gears.')
def test_glgears_animation(self):
es2_suffix = ['', '_full', '_full_944']
for full_es2 in [0, 1, 2]:
- for emulation in [0, 1]:
- if full_es2 and emulation: continue
- print full_es2, emulation
- Popen([PYTHON, EMCC, path_from_root('tests', 'hello_world_gles%s.c' % es2_suffix[full_es2]), '-o', 'something.html',
- '-DHAVE_BUILTIN_SINCOS', '-s', 'GL_TESTING=1',
- '--shell-file', path_from_root('tests', 'hello_world_gles_shell.html')] +
- (['-s', 'FORCE_GL_EMULATION=1'] if emulation else []) +
- (['-s', 'FULL_ES2=1'] if full_es2 else []),
- ).communicate()
- self.run_browser('something.html', 'You should see animating gears.', '/report_gl_result?true')
- assert ('var GLEmulation' in open(self.in_dir('something.html')).read()) == emulation, "emulation code should be added when asked for"
+ print full_es2
+ Popen([PYTHON, EMCC, path_from_root('tests', 'hello_world_gles%s.c' % es2_suffix[full_es2]), '-o', 'something.html',
+ '-DHAVE_BUILTIN_SINCOS', '-s', 'GL_TESTING=1',
+ '--shell-file', path_from_root('tests', 'hello_world_gles_shell.html')] +
+ (['-s', 'FULL_ES2=1'] if full_es2 else []),
+ ).communicate()
+ self.run_browser('something.html', 'You should see animating gears.', '/report_gl_result?true')
def test_fulles2_sdlproc(self):
self.btest('full_es2_sdlproc.c', '1', args=['-s', 'GL_TESTING=1', '-DHAVE_BUILTIN_SINCOS', '-s', 'FULL_ES2=1'])
def test_glgears_deriv(self):
- self.btest('hello_world_gles_deriv.c', reference='gears.png',
+ self.btest('hello_world_gles_deriv.c', reference='gears.png', reference_slack=1,
args=['-DHAVE_BUILTIN_SINCOS'], outfile='something.html',
message='You should see animating gears.')
with open('something.html') as f:
@@ -1163,90 +1167,90 @@ Press any key to continue.'''
self.btest('glgetattachedshaders.c', '1')
def test_sdlglshader(self):
- self.btest('sdlglshader.c', reference='sdlglshader.png', args=['-O2', '--closure', '1'])
+ self.btest('sdlglshader.c', reference='sdlglshader.png', args=['-O2', '--closure', '1', '-s', 'LEGACY_GL_EMULATION=1'])
def test_gl_ps(self):
# pointers and a shader
shutil.copyfile(path_from_root('tests', 'screenshot.png'), os.path.join(self.get_dir(), 'screenshot.png'))
- self.btest('gl_ps.c', reference='gl_ps.png', args=['--preload-file', 'screenshot.png'], reference_slack=1)
+ self.btest('gl_ps.c', reference='gl_ps.png', args=['--preload-file', 'screenshot.png', '-s', 'LEGACY_GL_EMULATION=1'], reference_slack=1)
def test_gl_ps_packed(self):
# packed data that needs to be strided
shutil.copyfile(path_from_root('tests', 'screenshot.png'), os.path.join(self.get_dir(), 'screenshot.png'))
- self.btest('gl_ps_packed.c', reference='gl_ps.png', args=['--preload-file', 'screenshot.png'], reference_slack=1)
+ self.btest('gl_ps_packed.c', reference='gl_ps.png', args=['--preload-file', 'screenshot.png', '-s', 'LEGACY_GL_EMULATION=1'], reference_slack=1)
def test_gl_ps_strides(self):
shutil.copyfile(path_from_root('tests', 'screenshot.png'), os.path.join(self.get_dir(), 'screenshot.png'))
- self.btest('gl_ps_strides.c', reference='gl_ps_strides.png', args=['--preload-file', 'screenshot.png'])
+ self.btest('gl_ps_strides.c', reference='gl_ps_strides.png', args=['--preload-file', 'screenshot.png', '-s', 'LEGACY_GL_EMULATION=1'])
def test_gl_renderers(self):
- self.btest('gl_renderers.c', reference='gl_renderers.png', args=['-s', 'GL_UNSAFE_OPTS=0'])
+ self.btest('gl_renderers.c', reference='gl_renderers.png', args=['-s', 'GL_UNSAFE_OPTS=0', '-s', 'LEGACY_GL_EMULATION=1'])
def test_gl_stride(self):
- self.btest('gl_stride.c', reference='gl_stride.png', args=['-s', 'GL_UNSAFE_OPTS=0'])
+ self.btest('gl_stride.c', reference='gl_stride.png', args=['-s', 'GL_UNSAFE_OPTS=0', '-s', 'LEGACY_GL_EMULATION=1'])
def test_matrix_identity(self):
- self.btest('gl_matrix_identity.c', expected=['-1882984448', '460451840'])
+ self.btest('gl_matrix_identity.c', expected=['-1882984448', '460451840'], args=['-s', 'LEGACY_GL_EMULATION=1'])
def test_cubegeom_pre(self):
- self.btest('cubegeom_pre.c', reference='cubegeom_pre.png')
+ self.btest('cubegeom_pre.c', reference='cubegeom_pre.png', args=['-s', 'LEGACY_GL_EMULATION=1'])
def test_cubegeom_pre2(self):
- self.btest('cubegeom_pre2.c', reference='cubegeom_pre2.png', args=['-s', 'GL_DEBUG=1']) # some coverage for GL_DEBUG not breaking the build
+ self.btest('cubegeom_pre2.c', reference='cubegeom_pre2.png', args=['-s', 'GL_DEBUG=1', '-s', 'LEGACY_GL_EMULATION=1']) # some coverage for GL_DEBUG not breaking the build
def test_cubegeom_pre3(self):
- self.btest('cubegeom_pre3.c', reference='cubegeom_pre2.png')
+ self.btest('cubegeom_pre3.c', reference='cubegeom_pre2.png', args=['-s', 'LEGACY_GL_EMULATION=1'])
def test_cubegeom(self):
- self.btest('cubegeom.c', args=['-O2', '-g'], reference='cubegeom.png')
+ self.btest('cubegeom.c', reference='cubegeom.png', args=['-O2', '-g', '-s', 'LEGACY_GL_EMULATION=1'])
def test_cubegeom_glew(self):
- self.btest('cubegeom_glew.c', args=['-O2', '--closure', '1'], reference='cubegeom.png')
+ self.btest('cubegeom_glew.c', reference='cubegeom.png', args=['-O2', '--closure', '1', '-s', 'LEGACY_GL_EMULATION=1'])
def test_cubegeom_color(self):
- self.btest('cubegeom_color.c', reference='cubegeom_color.png')
+ self.btest('cubegeom_color.c', reference='cubegeom_color.png', args=['-s', 'LEGACY_GL_EMULATION=1'])
def test_cubegeom_normal(self):
- self.btest('cubegeom_normal.c', reference='cubegeom_normal.png')
+ self.btest('cubegeom_normal.c', reference='cubegeom_normal.png', args=['-s', 'LEGACY_GL_EMULATION=1'])
def test_cubegeom_normal_dap(self): # draw is given a direct pointer to clientside memory, no element array buffer
- self.btest('cubegeom_normal_dap.c', reference='cubegeom_normal.png')
+ self.btest('cubegeom_normal_dap.c', reference='cubegeom_normal.png', args=['-s', 'LEGACY_GL_EMULATION=1'])
def test_cubegeom_normal_dap_far(self): # indices do nto start from 0
- self.btest('cubegeom_normal_dap_far.c', reference='cubegeom_normal.png')
+ self.btest('cubegeom_normal_dap_far.c', reference='cubegeom_normal.png', args=['-s', 'LEGACY_GL_EMULATION=1'])
def test_cubegeom_normal_dap_far_range(self): # glDrawRangeElements
- self.btest('cubegeom_normal_dap_far_range.c', reference='cubegeom_normal.png')
+ self.btest('cubegeom_normal_dap_far_range.c', reference='cubegeom_normal.png', args=['-s', 'LEGACY_GL_EMULATION=1'])
def test_cubegeom_normal_dap_far_glda(self): # use glDrawArrays
- self.btest('cubegeom_normal_dap_far_glda.c', reference='cubegeom_normal_dap_far_glda.png')
+ self.btest('cubegeom_normal_dap_far_glda.c', reference='cubegeom_normal_dap_far_glda.png', args=['-s', 'LEGACY_GL_EMULATION=1'])
def test_cubegeom_normal_dap_far_glda_quad(self): # with quad
- self.btest('cubegeom_normal_dap_far_glda_quad.c', reference='cubegeom_normal_dap_far_glda_quad.png')
+ self.btest('cubegeom_normal_dap_far_glda_quad.c', reference='cubegeom_normal_dap_far_glda_quad.png', args=['-s', 'LEGACY_GL_EMULATION=1'])
def test_cubegeom_mt(self):
- self.btest('cubegeom_mt.c', reference='cubegeom_mt.png') # multitexture
+ self.btest('cubegeom_mt.c', reference='cubegeom_mt.png', args=['-s', 'LEGACY_GL_EMULATION=1']) # multitexture
def test_cubegeom_color2(self):
- self.btest('cubegeom_color2.c', reference='cubegeom_color2.png')
+ self.btest('cubegeom_color2.c', reference='cubegeom_color2.png', args=['-s', 'LEGACY_GL_EMULATION=1'])
def test_cubegeom_texturematrix(self):
- self.btest('cubegeom_texturematrix.c', reference='cubegeom_texturematrix.png')
+ self.btest('cubegeom_texturematrix.c', reference='cubegeom_texturematrix.png', args=['-s', 'LEGACY_GL_EMULATION=1'])
def test_cubegeom_fog(self):
- self.btest('cubegeom_fog.c', reference='cubegeom_fog.png')
+ self.btest('cubegeom_fog.c', reference='cubegeom_fog.png', args=['-s', 'LEGACY_GL_EMULATION=1'])
def test_cubegeom_pre_vao(self):
- self.btest('cubegeom_pre_vao.c', reference='cubegeom_pre_vao.png')
+ self.btest('cubegeom_pre_vao.c', reference='cubegeom_pre_vao.png', args=['-s', 'LEGACY_GL_EMULATION=1'])
def test_cubegeom_pre2_vao(self):
- self.btest('cubegeom_pre2_vao.c', reference='cubegeom_pre_vao.png')
+ self.btest('cubegeom_pre2_vao.c', reference='cubegeom_pre_vao.png', args=['-s', 'LEGACY_GL_EMULATION=1'])
def test_cubegeom_pre2_vao2(self):
- self.btest('cubegeom_pre2_vao2.c', reference='cubegeom_pre2_vao2.png')
+ self.btest('cubegeom_pre2_vao2.c', reference='cubegeom_pre2_vao2.png', args=['-s', 'LEGACY_GL_EMULATION=1'])
def test_cube_explosion(self):
- self.btest('cube_explosion.c', reference='cube_explosion.png')
+ self.btest('cube_explosion.c', reference='cube_explosion.png', args=['-s', 'LEGACY_GL_EMULATION=1'])
def test_sdl_canvas_blank(self):
self.btest('sdl_canvas_blank.c', reference='sdl_canvas_blank.png')
@@ -1298,11 +1302,11 @@ Press any key to continue.'''
def test_glbegin_points(self):
shutil.copyfile(path_from_root('tests', 'screenshot.png'), os.path.join(self.get_dir(), 'screenshot.png'))
- self.btest('glbegin_points.c', reference='glbegin_points.png', args=['--preload-file', 'screenshot.png'])
+ self.btest('glbegin_points.c', reference='glbegin_points.png', args=['--preload-file', 'screenshot.png', '-s', 'LEGACY_GL_EMULATION=1'])
def test_s3tc(self):
shutil.copyfile(path_from_root('tests', 'screenshot.dds'), os.path.join(self.get_dir(), 'screenshot.dds'))
- self.btest('s3tc.c', reference='s3tc.png', args=['--preload-file', 'screenshot.dds'])
+ self.btest('s3tc.c', reference='s3tc.png', args=['--preload-file', 'screenshot.dds', '-s', 'LEGACY_GL_EMULATION=1'])
def test_s3tc_crunch(self):
shutil.copyfile(path_from_root('tests', 'ship.dds'), 'ship.dds')
@@ -1313,7 +1317,7 @@ Press any key to continue.'''
shutil.move('ship.dds', 'ship.donotfindme.dds') # make sure we load from the compressed
shutil.move('bloom.dds', 'bloom.donotfindme.dds') # make sure we load from the compressed
shutil.move('water.dds', 'water.donotfindme.dds') # make sure we load from the compressed
- self.btest('s3tc_crunch.c', reference='s3tc_crunch.png', reference_slack=11, args=['--pre-js', 'pre.js'])
+ self.btest('s3tc_crunch.c', reference='s3tc_crunch.png', reference_slack=11, args=['--pre-js', 'pre.js', '-s', 'LEGACY_GL_EMULATION=1'])
def test_s3tc_crunch_split(self): # load several datafiles/outputs of file packager
shutil.copyfile(path_from_root('tests', 'ship.dds'), 'ship.dds')
@@ -1324,14 +1328,20 @@ Press any key to continue.'''
shutil.move('ship.dds', 'ship.donotfindme.dds') # make sure we load from the compressed
shutil.move('bloom.dds', 'bloom.donotfindme.dds') # make sure we load from the compressed
shutil.move('water.dds', 'water.donotfindme.dds') # make sure we load from the compressed
- self.btest('s3tc_crunch.c', reference='s3tc_crunch.png', reference_slack=11, args=['--pre-js', 'asset_a.js', '--pre-js', 'asset_b.js'])
+ self.btest('s3tc_crunch.c', reference='s3tc_crunch.png', reference_slack=11, args=['--pre-js', 'asset_a.js', '--pre-js', 'asset_b.js', '-s', 'LEGACY_GL_EMULATION=1'])
def test_aniso(self):
+ if SPIDERMONKEY_ENGINE in JS_ENGINES:
+ # asm.js-ification check
+ Popen([PYTHON, EMCC, path_from_root('tests', 'aniso.c'), '-O2', '-g2', '-s', 'LEGACY_GL_EMULATION=1']).communicate()
+ Settings.ASM_JS = 1
+ self.run_generated_code(SPIDERMONKEY_ENGINE, 'a.out.js')
+
shutil.copyfile(path_from_root('tests', 'water.dds'), 'water.dds')
- self.btest('aniso.c', reference='aniso.png', reference_slack=2, args=['--preload-file', 'water.dds'])
+ self.btest('aniso.c', reference='aniso.png', reference_slack=2, args=['--preload-file', 'water.dds', '-s', 'LEGACY_GL_EMULATION=1'])
def test_tex_nonbyte(self):
- self.btest('tex_nonbyte.c', reference='tex_nonbyte.png')
+ self.btest('tex_nonbyte.c', reference='tex_nonbyte.png', args=['-s', 'LEGACY_GL_EMULATION=1'])
def test_float_tex(self):
self.btest('float_tex.cpp', reference='float_tex.png')
@@ -1340,10 +1350,10 @@ Press any key to continue.'''
self.btest('gl_subdata.cpp', reference='float_tex.png')
def test_perspective(self):
- self.btest('perspective.c', reference='perspective.png')
+ 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 31db6ca5..f3ddc4f4 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>
@@ -5451,7 +5525,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,7 +5544,6 @@ 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
@@ -5525,7 +5598,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 +5694,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 +5798,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 +5855,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
@@ -9582,15 +9651,15 @@ def process(filename):
self.assertIdentical(clean(no_maps_file), clean(out_file))
map_filename = out_filename + '.map'
data = json.load(open(map_filename, 'r'))
- self.assertIdentical(out_filename, data['file'])
- self.assertIdentical(src_filename, data['sources'][0])
- self.assertIdentical(src, data['sourcesContent'][0])
+ self.assertPathsIdentical(out_filename, data['file'])
+ self.assertPathsIdentical(src_filename, data['sources'][0])
+ self.assertTextDataIdentical(src, data['sourcesContent'][0])
mappings = json.loads(jsrun.run_js(
path_from_root('tools', 'source-maps', 'sourcemap2json.js'),
tools.shared.NODE_JS, [map_filename]))
seen_lines = set()
for m in mappings:
- self.assertIdentical(src_filename, m['source'])
+ self.assertPathsIdentical(src_filename, m['source'])
seen_lines.add(m['originalLine'])
# ensure that all the 'meaningful' lines in the original code get mapped
assert seen_lines.issuperset([6, 7, 11, 12])
@@ -10071,4 +10140,5 @@ 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..3b3887d6 100644
--- a/tests/test_other.py
+++ b/tests/test_other.py
@@ -1033,7 +1033,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')
diff --git a/tests/test_sockets.py b/tests/test_sockets.py
index 03593674..4f6ee2a9 100644
--- a/tests/test_sockets.py
+++ b/tests/test_sockets.py
@@ -198,3 +198,71 @@ class sockets(BrowserCore):
# ]:
# with harness:
# self.btest(os.path.join('sockets', 'test_enet_client.c'), expected='0', args=['-DSOCKK=9011'] + enet)
+
+ def test_webrtc(self):
+ host_src = 'webrtc_host.c'
+ peer_src = 'webrtc_peer.c'
+
+ host_outfile = 'host.html'
+ peer_outfile = 'peer.html'
+
+ host_filepath = path_from_root('tests', 'sockets', host_src)
+ temp_host_filepath = os.path.join(self.get_dir(), os.path.basename(host_src))
+ with open(host_filepath) as f: host_src = f.read()
+ with open(temp_host_filepath, 'w') as f: f.write(self.with_report_result(host_src))
+
+ peer_filepath = path_from_root('tests', 'sockets', peer_src)
+ temp_peer_filepath = os.path.join(self.get_dir(), os.path.basename(peer_src))
+ with open(peer_filepath) as f: peer_src = f.read()
+ with open(temp_peer_filepath, 'w') as f: f.write(self.with_report_result(peer_src))
+
+ open(os.path.join(self.get_dir(), 'host_pre.js'), 'w').write('''
+ var Module = {
+ webrtc: {
+ broker: 'https://mdsw.ch:8080',
+ session: undefined,
+ onpeer: function(peer, route) {
+ window.open('http://localhost:8888/peer.html?' + route);
+ // iframe = document.createElement("IFRAME");
+ // iframe.setAttribute("src", "http://localhost:8888/peer.html?" + route);
+ // iframe.style.display = "none";
+ // document.body.appendChild(iframe);
+ peer.listen();
+ },
+ onconnect: function(peer) {
+ },
+ ondisconnect: function(peer) {
+ },
+ onerror: function(error) {
+ console.error(error);
+ }
+ },
+ };
+ ''')
+
+ open(os.path.join(self.get_dir(), 'peer_pre.js'), 'w').write('''
+ var Module = {
+ webrtc: {
+ broker: 'https://mdsw.ch:8080',
+ session: window.location.toString().split('?')[1],
+ onpeer: function(peer, route) {
+ peer.connect(Module['webrtc']['session']);
+ },
+ onconnect: function(peer) {
+ },
+ ondisconnect: function(peer) {
+ // Calling window.close() from this handler hangs my browser, so run it in the next turn
+ setTimeout(window.close, 0);
+ },
+ onerror: function(error) {
+ console.error(error);
+ }
+ }
+ };
+ ''')
+
+ Popen([PYTHON, EMCC, temp_host_filepath, '-o', host_outfile] + ['-s', 'GL_TESTING=1', '--pre-js', 'host_pre.js', '-s', 'SOCKET_WEBRTC=1', '-s', 'SOCKET_DEBUG=1']).communicate()
+ Popen([PYTHON, EMCC, temp_peer_filepath, '-o', peer_outfile] + ['-s', 'GL_TESTING=1', '--pre-js', 'peer_pre.js', '-s', 'SOCKET_WEBRTC=1', '-s', 'SOCKET_DEBUG=1']).communicate()
+
+ expected = '1'
+ self.run_browser(host_outfile, '.', ['/report_result?' + e for e in expected]) \ No newline at end of file
diff --git a/tools/find_bigfuncs.py b/tools/find_bigfuncs.py
index 6fdec3a9..79136343 100644
--- a/tools/find_bigfuncs.py
+++ b/tools/find_bigfuncs.py
@@ -1,5 +1,5 @@
'''
-Simple tool to find big functions in an .ll file.
+Simple tool to find big functions in a js or ll file
'''
import os, sys, re
@@ -11,7 +11,7 @@ curr = None
data = []
for line in open(filename):
i += 1
- if line.startswith('function '):
+ if line.startswith(('function ', 'define ')):
start = i
curr = line
elif line.startswith('}') and curr:
diff --git a/tools/js-optimizer.js b/tools/js-optimizer.js
index ff6aee67..e61317af 100644
--- a/tools/js-optimizer.js
+++ b/tools/js-optimizer.js
@@ -801,7 +801,10 @@ function simplifyExpressions(ast) {
// HEAP[x >> 2]
// very often. We can in some cases do the shift on the variable itself when it is set,
// to greatly reduce the number of shift operations.
-// TODO: when shifting a variable, if there are other uses, keep an unshifted version too, to prevent slowdowns?
+// XXX this optimization is deprecated and currently invalid: does not handle overflows
+// or non-aligned (round numbers, x >> 2 is a multiple of 4). Both are ok to assume
+// for pointers (undefined behavior otherwise), but invalid in general, and we do
+// no sufficiently-well distinguish the cases.
function optimizeShiftsInternal(ast, conservative) {
var MAX_SHIFTS = 3;
traverseGeneratedFunctions(ast, function(fun) {
@@ -3001,7 +3004,7 @@ function outline(ast) {
// Try to flatten out code as much as possible, to make outlining more feasible.
function flatten(func, asmData) {
- var minSize = sizeToOutline;
+ var minSize = extraInfo.sizeToOutline/4;
var helperId = 0;
function getHelper() {
while (1) {
@@ -3475,6 +3478,9 @@ function outline(ast) {
}
}
}
+ function done() {
+ return asmData.splitCounter >= asmData.maxOutlinings || measureSize(func) <= extraInfo.sizeToOutline;
+ }
while (1) {
i--;
calcMinIndex(); // TODO: optimize
@@ -3530,7 +3536,7 @@ function outline(ast) {
if (ret.length > pre) {
// we outlined recursively, reset our state here
//printErr('successful outline in recursion ' + func[1] + ' due to recursive in level ' + level);
- if (measureSize(func) <= extraInfo.sizeToOutline) break;
+ if (done()) break;
end = i-1;
sizeSeen = 0;
canRestart = true;
@@ -3570,7 +3576,7 @@ function outline(ast) {
if (newFuncs.length) {
ret.push.apply(ret, newFuncs);
}
- if (measureSize(func) <= extraInfo.sizeToOutline) break;
+ if (done()) break;
sizeSeen = 0;
end = i-1;
canRestart = true;
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/response_file.py b/tools/response_file.py
index 312cda73..f19cf8af 100644
--- a/tools/response_file.py
+++ b/tools/response_file.py
@@ -6,8 +6,8 @@ def create_response_file(args, directory):
(response_fd, response_filename) = tempfile.mkstemp(prefix='emscripten_', suffix='.rsp', dir=directory, text=True)
response_fd = os.fdopen(response_fd, "w")
#print >> sys.stderr, "Creating response file '%s'" % response_filename
- args = map(lambda p: p.replace(' ', '').replace('\\', '\\\\').replace('"', '\\"'), args)
- response_fd.write(' '.join(args))
+ args = map(lambda p: p.replace('\\', '\\\\').replace('"', '\\"'), args)
+ response_fd.write('"' + '" "'.join(args) + '"')
response_fd.close()
return response_filename
diff --git a/tools/shared.py b/tools/shared.py
index 917f548e..0d0f20d4 100644
--- a/tools/shared.py
+++ b/tools/shared.py
@@ -550,6 +550,7 @@ if USE_EMSDK:
# allows projects to override them)
EMSDK_OPTS = ['-nostdinc', '-Xclang', '-nobuiltininc', '-Xclang', '-nostdsysteminc',
'-Xclang', '-isystem' + path_from_root('system', 'local', 'include'),
+ '-Xclang', '-isystem' + path_from_root('system', 'include', 'compat'),
'-Xclang', '-isystem' + path_from_root('system', 'include', 'libcxx'),
'-Xclang', '-isystem' + path_from_root('system', 'include'),
'-Xclang', '-isystem' + path_from_root('system', 'include', 'emscripten'),
diff --git a/tools/source-maps/sourcemapper.js b/tools/source-maps/sourcemapper.js
index fa908900..06c9a227 100755
--- a/tools/source-maps/sourcemapper.js
+++ b/tools/source-maps/sourcemapper.js
@@ -16,6 +16,38 @@ function countLines(s) {
return count;
}
+// For a minor optimization, only do win32->unix normalization if we are actually on Windows,
+// which avoids redundantly scanning files if not needed.
+var isWindows = (process.platform === 'win32');
+
+var unixPathRe = new RegExp('\\\\', 'g');
+// Returns the given (possibly Windows) path p normalized to unix path separators '/'.
+function toUnixPath(p) {
+ if (isWindows) {
+ return p.replace(unixPathRe, '/');
+ } else {
+ return p;
+ }
+}
+
+var unixLineEndRe = new RegExp('\r\n', 'g');
+// Returns the given (possibly Windows) text data t normalized to unix line endings '\n'.
+function toUnixLineEnding(t) {
+ if (isWindows) {
+ return t.replace(unixLineEndRe, '\n');
+ } else {
+ return t;
+ }
+}
+
+// If path "p2" is a relative path, joins paths p1 and p2 to form "p1/p2". If p2 is an absolute path, "p2" is returned.
+function joinPath(p1, p2) {
+ if (p2[0] == '/' || (p2.length >= 3 && p2[1] == ':' && (p2[2] == '/' || p2[2] == '\\'))) // Is p2 an absolute path?
+ return p2;
+ else
+ return toUnixPath(path.join(p1, p2));
+}
+
/*
* Extracts the line (not block) comments from the generated function code and
* invokes commentHandler with (comment content, line number of comment). This
@@ -105,8 +137,7 @@ function generateMap(mappings, sourceRoot, mapFileBaseName, generatedLineOffset)
// avoid doing it unnecessarily
if (!(originalFileName in seenFiles)) {
seenFiles[originalFileName] = true;
- var rootedPath = originalFileName[0] === path.sep ?
- originalFileName : path.join(sourceRoot, originalFileName);
+ var rootedPath = joinPath(sourceRoot, originalFileName);
try {
generator.setSourceContent(originalFileName, fs.readFileSync(rootedPath, 'utf-8'));
} catch (e) {
@@ -144,15 +175,15 @@ if (require.main === module) {
} else {
var opts = parseArgs(process.argv.slice(2));
var fileName = opts._[0];
- var sourceRoot = opts.sourceRoot ? opts.sourceRoot : ".";
- var mapFileBaseName = opts.mapFileBaseName ? opts.mapFileBaseName : fileName;
+ var sourceRoot = opts.sourceRoot ? toUnixPath(opts.sourceRoot) : ".";
+ var mapFileBaseName = toUnixPath(opts.mapFileBaseName ? opts.mapFileBaseName : fileName);
var generatedLineOffset = opts.offset ? parseInt(opts.offset, 10) : 0;
- var generatedSource = fs.readFileSync(fileName, 'utf-8');
+ var generatedSource = toUnixLineEnding(fs.readFileSync(fileName, 'utf-8'));
var source = generatedSource;
var mappings = getMappings(generatedSource);
for (var i = 1, l = opts._.length; i < l; i ++) {
- var optimizedSource = fs.readFileSync(opts._[i], 'utf-8')
+ var optimizedSource = toUnixLineEnding(fs.readFileSync(opts._[i], 'utf-8'))
var optimizedMappings = getMappings(optimizedSource);
var newMappings = {};
// uglify processes the code between EMSCRIPTEN_START_FUNCS and
diff --git a/tools/test-js-optimizer-asm-outline1-output.js b/tools/test-js-optimizer-asm-outline1-output.js
index 904e56cf..d8ea9446 100644
--- a/tools/test-js-optimizer-asm-outline1-output.js
+++ b/tools/test-js-optimizer-asm-outline1-output.js
@@ -276,8 +276,29 @@ function vars_w_stack(x, y) {
function chain() {
var helper$0 = 0, sp = 0;
sp = STACKTOP;
- STACKTOP = STACKTOP + 240 | 0;
+ STACKTOP = STACKTOP + 464 | 0;
helper$0 = 1;
+ if (helper$0) {
+ helper$0 = 0;
+ if (x == 1) {
+ print(1);
+ } else {
+ helper$0 = 1;
+ }
+ }
+ if (helper$0) {
+ helper$0 = 0;
+ if (x == 2) {
+ print(2);
+ } else {
+ helper$0 = 1;
+ }
+ }
+ HEAP32[sp + 8 >> 2] = helper$0;
+ HEAP32[sp + 48 >> 2] = 0;
+ HEAP32[sp + 52 >> 2] = 0;
+ chain$4(sp);
+ helper$0 = HEAP32[sp + 8 >> 2] | 0;
HEAP32[sp + 8 >> 2] = helper$0;
HEAP32[sp + 40 >> 2] = 0;
HEAP32[sp + 44 >> 2] = 0;
@@ -288,6 +309,16 @@ function chain() {
HEAP32[sp + 36 >> 2] = 0;
chain$2(sp);
helper$0 = HEAP32[sp + 8 >> 2] | 0;
+ HEAP32[sp + 8 >> 2] = helper$0;
+ HEAP32[sp + 24 >> 2] = 0;
+ HEAP32[sp + 28 >> 2] = 0;
+ chain$1(sp);
+ helper$0 = HEAP32[sp + 8 >> 2] | 0;
+ HEAP32[sp + 8 >> 2] = helper$0;
+ HEAP32[sp + 16 >> 2] = 0;
+ HEAP32[sp + 20 >> 2] = 0;
+ chain$0(sp);
+ helper$0 = HEAP32[sp + 8 >> 2] | 0;
STACKTOP = sp;
}
function lin$0(sp) {
@@ -500,22 +531,21 @@ function chain$0(sp) {
sp = sp | 0;
var helper$0 = 0;
helper$0 = HEAP32[sp + 8 >> 2] | 0;
- if (x == 7) {
- print(7);
- } else if (x == 8) {
- print(8);
- } else if (x == 9) {
- print(9);
- } else if (x == 10) {
- print(10);
- } else if (x == 11) {
- print(11);
- } else if (x == 12) {
- print(12);
- } else if (1) {
- print(99);
- } else {
- helper$0 = 1;
+ if (helper$0) {
+ helper$0 = 0;
+ if (x == 12) {
+ print(12);
+ } else {
+ helper$0 = 1;
+ }
+ }
+ if (helper$0) {
+ helper$0 = 0;
+ if (1) {
+ print(99);
+ } else {
+ helper$0 = 1;
+ }
}
HEAP32[sp + 8 >> 2] = helper$0;
}
@@ -523,20 +553,21 @@ function chain$1(sp) {
sp = sp | 0;
var helper$0 = 0;
helper$0 = HEAP32[sp + 8 >> 2] | 0;
- if (x == 1) {
- print(1);
- } else if (x == 2) {
- print(2);
- } else if (x == 3) {
- print(3);
- } else if (x == 4) {
- print(4);
- } else if (x == 5) {
- print(5);
- } else if (x == 6) {
- print(6);
- } else {
- helper$0 = 1;
+ if (helper$0) {
+ helper$0 = 0;
+ if (x == 10) {
+ print(10);
+ } else {
+ helper$0 = 1;
+ }
+ }
+ if (helper$0) {
+ helper$0 = 0;
+ if (x == 11) {
+ print(11);
+ } else {
+ helper$0 = 1;
+ }
}
HEAP32[sp + 8 >> 2] = helper$0;
}
@@ -546,11 +577,19 @@ function chain$2(sp) {
helper$0 = HEAP32[sp + 8 >> 2] | 0;
if (helper$0) {
helper$0 = 0;
- HEAP32[sp + 8 >> 2] = helper$0;
- HEAP32[sp + 16 >> 2] = 0;
- HEAP32[sp + 20 >> 2] = 0;
- chain$0(sp);
- helper$0 = HEAP32[sp + 8 >> 2] | 0;
+ if (x == 8) {
+ print(8);
+ } else {
+ helper$0 = 1;
+ }
+ }
+ if (helper$0) {
+ helper$0 = 0;
+ if (x == 9) {
+ print(9);
+ } else {
+ helper$0 = 1;
+ }
}
HEAP32[sp + 8 >> 2] = helper$0;
}
@@ -560,11 +599,49 @@ function chain$3(sp) {
helper$0 = HEAP32[sp + 8 >> 2] | 0;
if (helper$0) {
helper$0 = 0;
- HEAP32[sp + 8 >> 2] = helper$0;
- HEAP32[sp + 24 >> 2] = 0;
- HEAP32[sp + 28 >> 2] = 0;
- chain$1(sp);
- helper$0 = HEAP32[sp + 8 >> 2] | 0;
+ if (x == 6) {
+ print(6);
+ } else {
+ helper$0 = 1;
+ }
+ }
+ if (helper$0) {
+ helper$0 = 0;
+ if (x == 7) {
+ print(7);
+ } else {
+ helper$0 = 1;
+ }
+ }
+ HEAP32[sp + 8 >> 2] = helper$0;
+}
+function chain$4(sp) {
+ sp = sp | 0;
+ var helper$0 = 0;
+ helper$0 = HEAP32[sp + 8 >> 2] | 0;
+ if (helper$0) {
+ helper$0 = 0;
+ if (x == 3) {
+ print(3);
+ } else {
+ helper$0 = 1;
+ }
+ }
+ if (helper$0) {
+ helper$0 = 0;
+ if (x == 4) {
+ print(4);
+ } else {
+ helper$0 = 1;
+ }
+ }
+ if (helper$0) {
+ helper$0 = 0;
+ if (x == 5) {
+ print(5);
+ } else {
+ helper$0 = 1;
+ }
}
HEAP32[sp + 8 >> 2] = helper$0;
}
diff --git a/tools/test-js-optimizer-asm-outline2-output.js b/tools/test-js-optimizer-asm-outline2-output.js
index 28feb6cb..2658fda0 100644
--- a/tools/test-js-optimizer-asm-outline2-output.js
+++ b/tools/test-js-optimizer-asm-outline2-output.js
@@ -23,7 +23,7 @@ function linear() {
}
function _free($mem) {
$mem = $mem | 0;
- var $5 = 0, $10 = 0, $16 = 0, $21 = 0, $25 = 0, $26 = 0, $psize_0 = 0, $p_0 = 0, $189 = 0, $194 = 0, sp = 0;
+ var $5 = 0, $10 = 0, $16 = 0, $21 = 0, $25 = 0, $26 = 0, $psize_0 = 0, $p_0 = 0, $189 = 0, $194 = 0, sp = 0, helper$0 = 0;
sp = STACKTOP;
if (($mem | 0) == 0) {
STACKTOP = sp;
@@ -39,59 +39,71 @@ function _free($mem) {
}
$16 = $mem + (($10 & -8) - 8) | 0;
L621 : do {
- if (($10 & 1 | 0) == 0) {
- $21 = HEAP32[($mem - 8 | 0) >> 2] | 0;
- if (($10 & 3 | 0) == 0) {
- return;
- }
- $25 = $mem + (-8 - $21 | 0) | 0;
- $26 = $21 + ($10 & -8) | 0;
- if (($mem + (-8 - $21 | 0) | 0) >>> 0 < $5 >>> 0) {
- _abort();
- }
- if (($25 | 0) == (HEAP32[25] | 0)) {
- if ((HEAP32[($mem + (($10 & -8) - 4) | 0) >> 2] & 3 | 0) != 3) {
- $p_0 = $25;
- $psize_0 = $26;
+ helper$0 = 1;
+ if (helper$0) {
+ helper$0 = 0;
+ if (($10 & 1 | 0) == 0) {
+ $21 = HEAP32[($mem - 8 | 0) >> 2] | 0;
+ if (($10 & 3 | 0) == 0) {
+ return;
+ }
+ $25 = $mem + (-8 - $21 | 0) | 0;
+ $26 = $21 + ($10 & -8) | 0;
+ if (($mem + (-8 - $21 | 0) | 0) >>> 0 < $5 >>> 0) {
+ _abort();
+ }
+ if (($25 | 0) == (HEAP32[25] | 0)) {
+ if ((HEAP32[($mem + (($10 & -8) - 4) | 0) >> 2] & 3 | 0) != 3) {
+ $p_0 = $25;
+ $psize_0 = $26;
+ break;
+ }
+ HEAP32[22] = $26;
+ HEAP32[($mem + (($10 & -8) - 4) | 0) >> 2] = HEAP32[($mem + (($10 & -8) - 4) | 0) >> 2] & -2;
+ HEAP32[$mem + ((-8 - $21 | 0) + 4) >> 2] = $26 | 1;
+ HEAP32[($mem + (($10 & -8) - 8) | 0) >> 2] = $26;
+ return;
+ }
+ HEAP32[sp + 8 >> 2] = $mem;
+ HEAP32[sp + 16 >> 2] = $5;
+ HEAP32[sp + 40 >> 2] = $21;
+ HEAP32[sp + 48 >> 2] = $25;
+ HEAP32[sp + 56 >> 2] = $26;
+ HEAP32[sp + 216 >> 2] = $psize_0;
+ HEAP32[sp + 224 >> 2] = $p_0;
+ HEAP32[sp + 696 >> 2] = 0;
+ HEAP32[sp + 700 >> 2] = 0;
+ _free$1(sp);
+ $psize_0 = HEAP32[sp + 216 >> 2] | 0;
+ $p_0 = HEAP32[sp + 224 >> 2] | 0;
+ tempValue = HEAP32[sp + 696 >> 2] | 0;
+ tempInt = HEAP32[sp + 700 >> 2] | 0;
+ tempDouble = +HEAPF32[sp + 700 >> 2];
+ HEAP32[sp + 696 >> 2] = 0;
+ HEAP32[sp + 700 >> 2] = 0;
+ if ((tempValue | 0) == 1) {
break;
}
- HEAP32[22] = $26;
- HEAP32[($mem + (($10 & -8) - 4) | 0) >> 2] = HEAP32[($mem + (($10 & -8) - 4) | 0) >> 2] & -2;
- HEAP32[$mem + ((-8 - $21 | 0) + 4) >> 2] = $26 | 1;
- HEAP32[($mem + (($10 & -8) - 8) | 0) >> 2] = $26;
- return;
- }
- HEAP32[sp + 8 >> 2] = $mem;
- HEAP32[sp + 16 >> 2] = $5;
- HEAP32[sp + 40 >> 2] = $21;
- HEAP32[sp + 48 >> 2] = $25;
- HEAP32[sp + 56 >> 2] = $26;
- HEAP32[sp + 216 >> 2] = $psize_0;
- HEAP32[sp + 224 >> 2] = $p_0;
- HEAP32[sp + 648 >> 2] = 0;
- HEAP32[sp + 652 >> 2] = 0;
- _free$1(sp);
- $psize_0 = HEAP32[sp + 216 >> 2] | 0;
- $p_0 = HEAP32[sp + 224 >> 2] | 0;
- tempValue = HEAP32[sp + 648 >> 2] | 0;
- tempInt = HEAP32[sp + 652 >> 2] | 0;
- tempDouble = +HEAPF32[sp + 652 >> 2];
- HEAP32[sp + 648 >> 2] = 0;
- HEAP32[sp + 652 >> 2] = 0;
- if ((tempValue | 0) == 1) {
- break;
- }
- if ((tempValue | 0) == 2) {
- switch (tempInt | 0) {
- case 2:
- {
- break L621;
+ if ((tempValue | 0) == 2) {
+ switch (tempInt | 0) {
+ case 2:
+ {
+ break L621;
+ }
}
}
+ } else {
+ helper$0 = 1;
+ }
+ }
+ if (helper$0) {
+ helper$0 = 0;
+ if (1) {
+ $p_0 = $mem - 8 | 0;
+ $psize_0 = $10 & -8;
+ } else {
+ helper$0 = 1;
}
- } else {
- $p_0 = $mem - 8 | 0;
- $psize_0 = $10 & -8;
}
} while (0);
$189 = $p_0;
@@ -109,14 +121,14 @@ function _free($mem) {
HEAP32[sp + 224 >> 2] = $p_0;
HEAP32[sp + 232 >> 2] = $189;
HEAP32[sp + 240 >> 2] = $194;
- HEAP32[sp + 656 >> 2] = 0;
- HEAP32[sp + 660 >> 2] = 0;
+ HEAP32[sp + 704 >> 2] = 0;
+ HEAP32[sp + 708 >> 2] = 0;
_free$2(sp);
- tempValue = HEAP32[sp + 656 >> 2] | 0;
- tempInt = HEAP32[sp + 660 >> 2] | 0;
- tempDouble = +HEAPF32[sp + 660 >> 2];
- HEAP32[sp + 656 >> 2] = 0;
- HEAP32[sp + 660 >> 2] = 0;
+ tempValue = HEAP32[sp + 704 >> 2] | 0;
+ tempInt = HEAP32[sp + 708 >> 2] | 0;
+ tempDouble = +HEAPF32[sp + 708 >> 2];
+ HEAP32[sp + 704 >> 2] = 0;
+ HEAP32[sp + 708 >> 2] = 0;
if ((tempValue | 0) == 5) {
return;
}
@@ -153,175 +165,200 @@ function linear$1(sp) {
}
function _free$0(sp) {
sp = sp | 0;
- var $194 = 0, $233 = 0, $mem = 0, $10 = 0, $236 = 0, $16 = 0, $_pre_phi305 = 0, $267 = 0, $270 = 0, $273 = 0, $294 = 0, $299 = 0, $R7_1 = 0, $R7_0 = 0, $RP9_0 = 0, $301 = 0, $302 = 0, $305 = 0, $306 = 0, $278 = 0, $320 = 0, $351 = 0, $364 = 0;
+ var helper$3 = 0, $194 = 0, $233 = 0, $mem = 0, $10 = 0, $236 = 0, $16 = 0, $_pre_phi305 = 0, $267 = 0, $270 = 0, $273 = 0, helper$4 = 0, $294 = 0, $299 = 0, $R7_1 = 0, $R7_0 = 0, $RP9_0 = 0, $301 = 0, $302 = 0, $305 = 0, $306 = 0, $278 = 0, $320 = 0, $351 = 0, $364 = 0;
$mem = HEAP32[sp + 8 >> 2] | 0;
$10 = HEAP32[sp + 24 >> 2] | 0;
$16 = HEAP32[sp + 32 >> 2] | 0;
$194 = HEAP32[sp + 240 >> 2] | 0;
+ helper$3 = HEAP32[sp + 664 >> 2] | 0;
OL : do {
- if ($194 >>> 0 < 256) {
- $233 = HEAP32[$mem + ($10 & -8) >> 2] | 0;
- $236 = HEAP32[$mem + ($10 & -8 | 4) >> 2] | 0;
- do {
- if (($233 | 0) != (120 + ($194 >>> 3 << 1 << 2) | 0 | 0)) {
- if ($233 >>> 0 < (HEAP32[24] | 0) >>> 0) {
+ if (helper$3) {
+ helper$3 = 0;
+ if ($194 >>> 0 < 256) {
+ $233 = HEAP32[$mem + ($10 & -8) >> 2] | 0;
+ $236 = HEAP32[$mem + ($10 & -8 | 4) >> 2] | 0;
+ do {
+ if (($233 | 0) != (120 + ($194 >>> 3 << 1 << 2) | 0 | 0)) {
+ if ($233 >>> 0 < (HEAP32[24] | 0) >>> 0) {
+ _abort();
+ }
+ if ((HEAP32[$233 + 12 >> 2] | 0) == ($16 | 0)) {
+ break;
+ }
_abort();
}
- if ((HEAP32[$233 + 12 >> 2] | 0) == ($16 | 0)) {
- break;
- }
- _abort();
+ } while (0);
+ if (($236 | 0) == ($233 | 0)) {
+ HEAP32[20] = HEAP32[20] & (1 << ($194 >>> 3) ^ -1);
+ HEAP32[sp + 688 >> 2] = 1;
+ break OL;
}
- } while (0);
- if (($236 | 0) == ($233 | 0)) {
- HEAP32[20] = HEAP32[20] & (1 << ($194 >>> 3) ^ -1);
- HEAP32[sp + 640 >> 2] = 1;
- break OL;
- }
- do {
- if (($236 | 0) == (120 + ($194 >>> 3 << 1 << 2) | 0 | 0)) {
- $_pre_phi305 = $236 + 8 | 0;
- } else {
- if ($236 >>> 0 < (HEAP32[24] | 0) >>> 0) {
- _abort();
- }
- if ((HEAP32[($236 + 8 | 0) >> 2] | 0) == ($16 | 0)) {
+ do {
+ if (($236 | 0) == (120 + ($194 >>> 3 << 1 << 2) | 0 | 0)) {
$_pre_phi305 = $236 + 8 | 0;
- break;
- }
- _abort();
- }
- } while (0);
- HEAP32[$233 + 12 >> 2] = $236;
- HEAP32[$_pre_phi305 >> 2] = $233;
- } else {
- $267 = $mem + (($10 & -8) - 8) | 0;
- $270 = HEAP32[$mem + (($10 & -8) + 16) >> 2] | 0;
- $273 = HEAP32[$mem + ($10 & -8 | 4) >> 2] | 0;
- do {
- if (($273 | 0) == ($267 | 0)) {
- $294 = HEAP32[($mem + (($10 & -8) + 12) | 0) >> 2] | 0;
- if (($294 | 0) == 0) {
- $299 = HEAP32[($mem + (($10 & -8) + 8) | 0) >> 2] | 0;
- if (($299 | 0) == 0) {
- $R7_1 = 0;
- break;
- } else {
- $R7_0 = $299;
- $RP9_0 = $mem + (($10 & -8) + 8) | 0;
- }
} else {
- $R7_0 = $294;
- $RP9_0 = $mem + (($10 & -8) + 12) | 0;
- }
- while (1) {
- $301 = $R7_0 + 20 | 0;
- $302 = HEAP32[$301 >> 2] | 0;
- if (($302 | 0) != 0) {
- $R7_0 = $302;
- $RP9_0 = $301;
- continue;
+ if ($236 >>> 0 < (HEAP32[24] | 0) >>> 0) {
+ _abort();
}
- $305 = $R7_0 + 16 | 0;
- $306 = HEAP32[$305 >> 2] | 0;
- if (($306 | 0) == 0) {
+ if ((HEAP32[($236 + 8 | 0) >> 2] | 0) == ($16 | 0)) {
+ $_pre_phi305 = $236 + 8 | 0;
break;
- } else {
- $R7_0 = $306;
- $RP9_0 = $305;
}
- }
- if ($RP9_0 >>> 0 < (HEAP32[24] | 0) >>> 0) {
_abort();
- } else {
- HEAP32[$RP9_0 >> 2] = 0;
- $R7_1 = $R7_0;
- break;
}
- } else {
- $278 = HEAP32[$mem + ($10 & -8) >> 2] | 0;
- if ($278 >>> 0 < (HEAP32[24] | 0) >>> 0) {
- _abort();
+ } while (0);
+ HEAP32[$233 + 12 >> 2] = $236;
+ HEAP32[$_pre_phi305 >> 2] = $233;
+ } else {
+ helper$3 = 1;
+ }
+ }
+ if (helper$3) {
+ helper$3 = 0;
+ if (1) {
+ $267 = $mem + (($10 & -8) - 8) | 0;
+ $270 = HEAP32[$mem + (($10 & -8) + 16) >> 2] | 0;
+ $273 = HEAP32[$mem + ($10 & -8 | 4) >> 2] | 0;
+ do {
+ helper$4 = 1;
+ if (helper$4) {
+ helper$4 = 0;
+ if (($273 | 0) == ($267 | 0)) {
+ $294 = HEAP32[($mem + (($10 & -8) + 12) | 0) >> 2] | 0;
+ if (($294 | 0) == 0) {
+ $299 = HEAP32[($mem + (($10 & -8) + 8) | 0) >> 2] | 0;
+ if (($299 | 0) == 0) {
+ $R7_1 = 0;
+ break;
+ } else {
+ $R7_0 = $299;
+ $RP9_0 = $mem + (($10 & -8) + 8) | 0;
+ }
+ } else {
+ $R7_0 = $294;
+ $RP9_0 = $mem + (($10 & -8) + 12) | 0;
+ }
+ while (1) {
+ $301 = $R7_0 + 20 | 0;
+ $302 = HEAP32[$301 >> 2] | 0;
+ if (($302 | 0) != 0) {
+ $R7_0 = $302;
+ $RP9_0 = $301;
+ continue;
+ }
+ $305 = $R7_0 + 16 | 0;
+ $306 = HEAP32[$305 >> 2] | 0;
+ if (($306 | 0) == 0) {
+ break;
+ } else {
+ $R7_0 = $306;
+ $RP9_0 = $305;
+ }
+ }
+ if ($RP9_0 >>> 0 < (HEAP32[24] | 0) >>> 0) {
+ _abort();
+ } else {
+ HEAP32[$RP9_0 >> 2] = 0;
+ $R7_1 = $R7_0;
+ break;
+ }
+ } else {
+ helper$4 = 1;
+ }
}
- if ((HEAP32[($278 + 12 | 0) >> 2] | 0) != ($267 | 0)) {
- _abort();
+ if (helper$4) {
+ helper$4 = 0;
+ if (1) {
+ $278 = HEAP32[$mem + ($10 & -8) >> 2] | 0;
+ if ($278 >>> 0 < (HEAP32[24] | 0) >>> 0) {
+ _abort();
+ }
+ if ((HEAP32[($278 + 12 | 0) >> 2] | 0) != ($267 | 0)) {
+ _abort();
+ }
+ if ((HEAP32[($273 + 8 | 0) >> 2] | 0) == ($267 | 0)) {
+ HEAP32[($278 + 12 | 0) >> 2] = $273;
+ HEAP32[($273 + 8 | 0) >> 2] = $278;
+ $R7_1 = $273;
+ break;
+ } else {
+ _abort();
+ }
+ } else {
+ helper$4 = 1;
+ }
}
- if ((HEAP32[($273 + 8 | 0) >> 2] | 0) == ($267 | 0)) {
- HEAP32[($278 + 12 | 0) >> 2] = $273;
- HEAP32[($273 + 8 | 0) >> 2] = $278;
- $R7_1 = $273;
- break;
+ } while (0);
+ if (($270 | 0) == 0) {
+ HEAP32[sp + 688 >> 2] = 1;
+ break OL;
+ }
+ $320 = 384 + (HEAP32[($mem + (($10 & -8) + 20) | 0) >> 2] << 2) | 0;
+ do {
+ if (($267 | 0) == (HEAP32[$320 >> 2] | 0)) {
+ HEAP32[$320 >> 2] = $R7_1;
+ if (($R7_1 | 0) != 0) {
+ break;
+ }
+ HEAP32[21] = HEAP32[21] & (1 << HEAP32[($mem + (($10 & -8) + 20) | 0) >> 2] ^ -1);
+ HEAP32[sp + 688 >> 2] = 2;
+ HEAP32[sp + 692 >> 2] = 2;
+ break OL;
} else {
- _abort();
+ if ($270 >>> 0 < (HEAP32[24] | 0) >>> 0) {
+ _abort();
+ }
+ if ((HEAP32[($270 + 16 | 0) >> 2] | 0) == ($267 | 0)) {
+ HEAP32[($270 + 16 | 0) >> 2] = $R7_1;
+ } else {
+ HEAP32[$270 + 20 >> 2] = $R7_1;
+ }
+ if (($R7_1 | 0) == 0) {
+ HEAP32[sp + 688 >> 2] = 2;
+ HEAP32[sp + 692 >> 2] = 2;
+ break OL;
+ }
}
+ } while (0);
+ if ($R7_1 >>> 0 < (HEAP32[24] | 0) >>> 0) {
+ _abort();
}
- } while (0);
- if (($270 | 0) == 0) {
- HEAP32[sp + 640 >> 2] = 1;
- break OL;
- }
- $320 = 384 + (HEAP32[($mem + (($10 & -8) + 20) | 0) >> 2] << 2) | 0;
- do {
- if (($267 | 0) == (HEAP32[$320 >> 2] | 0)) {
- HEAP32[$320 >> 2] = $R7_1;
- if (($R7_1 | 0) != 0) {
- break;
+ HEAP32[$R7_1 + 24 >> 2] = $270;
+ $351 = HEAP32[$mem + (($10 & -8) + 8) >> 2] | 0;
+ do {
+ if (($351 | 0) != 0) {
+ if ($351 >>> 0 < (HEAP32[24] | 0) >>> 0) {
+ _abort();
+ } else {
+ HEAP32[$R7_1 + 16 >> 2] = $351;
+ HEAP32[$351 + 24 >> 2] = $R7_1;
+ break;
+ }
}
- HEAP32[21] = HEAP32[21] & (1 << HEAP32[($mem + (($10 & -8) + 20) | 0) >> 2] ^ -1);
- HEAP32[sp + 640 >> 2] = 2;
- HEAP32[sp + 644 >> 2] = 2;
+ } while (0);
+ $364 = HEAP32[$mem + (($10 & -8) + 12) >> 2] | 0;
+ if (($364 | 0) == 0) {
+ HEAP32[sp + 688 >> 2] = 1;
break OL;
- } else {
- if ($270 >>> 0 < (HEAP32[24] | 0) >>> 0) {
- _abort();
- }
- if ((HEAP32[($270 + 16 | 0) >> 2] | 0) == ($267 | 0)) {
- HEAP32[($270 + 16 | 0) >> 2] = $R7_1;
- } else {
- HEAP32[$270 + 20 >> 2] = $R7_1;
- }
- if (($R7_1 | 0) == 0) {
- HEAP32[sp + 640 >> 2] = 2;
- HEAP32[sp + 644 >> 2] = 2;
- break OL;
- }
}
- } while (0);
- if ($R7_1 >>> 0 < (HEAP32[24] | 0) >>> 0) {
- _abort();
- }
- HEAP32[$R7_1 + 24 >> 2] = $270;
- $351 = HEAP32[$mem + (($10 & -8) + 8) >> 2] | 0;
- do {
- if (($351 | 0) != 0) {
- if ($351 >>> 0 < (HEAP32[24] | 0) >>> 0) {
- _abort();
- } else {
- HEAP32[$R7_1 + 16 >> 2] = $351;
- HEAP32[$351 + 24 >> 2] = $R7_1;
- break;
- }
+ if ($364 >>> 0 < (HEAP32[24] | 0) >>> 0) {
+ _abort();
+ } else {
+ HEAP32[$R7_1 + 20 >> 2] = $364;
+ HEAP32[$364 + 24 >> 2] = $R7_1;
+ HEAP32[sp + 688 >> 2] = 1;
+ break OL;
}
- } while (0);
- $364 = HEAP32[$mem + (($10 & -8) + 12) >> 2] | 0;
- if (($364 | 0) == 0) {
- HEAP32[sp + 640 >> 2] = 1;
- break OL;
- }
- if ($364 >>> 0 < (HEAP32[24] | 0) >>> 0) {
- _abort();
} else {
- HEAP32[$R7_1 + 20 >> 2] = $364;
- HEAP32[$364 + 24 >> 2] = $R7_1;
- HEAP32[sp + 640 >> 2] = 1;
- break OL;
+ helper$3 = 1;
}
}
} while (0);
+ HEAP32[sp + 664 >> 2] = helper$3;
}
function _free$1(sp) {
sp = sp | 0;
- var $21 = 0, $37 = 0, $mem = 0, $40 = 0, $5 = 0, $25 = 0, $26 = 0, $_pre_phi307 = 0, $69 = 0, $72 = 0, $75 = 0, $95 = 0, $100 = 0, $R_1 = 0, $R_0 = 0, $RP_0 = 0, $102 = 0, $103 = 0, $106 = 0, $107 = 0, $80 = 0, $120 = 0, $151 = 0, $164 = 0, $p_0 = 0, $psize_0 = 0;
+ var $21 = 0, $37 = 0, $mem = 0, $40 = 0, $5 = 0, $25 = 0, $26 = 0, $_pre_phi307 = 0, $69 = 0, $72 = 0, $75 = 0, helper$1 = 0, $95 = 0, $100 = 0, $R_1 = 0, $R_0 = 0, $RP_0 = 0, $102 = 0, $103 = 0, $106 = 0, $107 = 0, $80 = 0, $120 = 0, $151 = 0, $164 = 0, $p_0 = 0, $psize_0 = 0;
$mem = HEAP32[sp + 8 >> 2] | 0;
$5 = HEAP32[sp + 16 >> 2] | 0;
$21 = HEAP32[sp + 40 >> 2] | 0;
@@ -348,7 +385,7 @@ function _free$1(sp) {
HEAP32[20] = HEAP32[20] & (1 << ($21 >>> 3) ^ -1);
$p_0 = $25;
$psize_0 = $26;
- HEAP32[sp + 648 >> 2] = 1;
+ HEAP32[sp + 696 >> 2] = 1;
break OL;
}
do {
@@ -369,74 +406,86 @@ function _free$1(sp) {
HEAP32[$_pre_phi307 >> 2] = $37;
$p_0 = $25;
$psize_0 = $26;
- HEAP32[sp + 648 >> 2] = 1;
+ HEAP32[sp + 696 >> 2] = 1;
break OL;
}
$69 = $mem + (-8 - $21 | 0) | 0;
$72 = HEAP32[$mem + ((-8 - $21 | 0) + 24) >> 2] | 0;
$75 = HEAP32[$mem + ((-8 - $21 | 0) + 12) >> 2] | 0;
do {
- if (($75 | 0) == ($69 | 0)) {
- $95 = HEAP32[($mem + ((-8 - $21 | 0) + 20) | 0) >> 2] | 0;
- if (($95 | 0) == 0) {
- $100 = HEAP32[($mem + ((-8 - $21 | 0) + 16) | 0) >> 2] | 0;
- if (($100 | 0) == 0) {
- $R_1 = 0;
- break;
+ helper$1 = 1;
+ if (helper$1) {
+ helper$1 = 0;
+ if (($75 | 0) == ($69 | 0)) {
+ $95 = HEAP32[($mem + ((-8 - $21 | 0) + 20) | 0) >> 2] | 0;
+ if (($95 | 0) == 0) {
+ $100 = HEAP32[($mem + ((-8 - $21 | 0) + 16) | 0) >> 2] | 0;
+ if (($100 | 0) == 0) {
+ $R_1 = 0;
+ break;
+ } else {
+ $R_0 = $100;
+ $RP_0 = $mem + ((-8 - $21 | 0) + 16) | 0;
+ }
+ } else {
+ $R_0 = $95;
+ $RP_0 = $mem + ((-8 - $21 | 0) + 20) | 0;
+ }
+ while (1) {
+ $102 = $R_0 + 20 | 0;
+ $103 = HEAP32[$102 >> 2] | 0;
+ if (($103 | 0) != 0) {
+ $R_0 = $103;
+ $RP_0 = $102;
+ continue;
+ }
+ $106 = $R_0 + 16 | 0;
+ $107 = HEAP32[$106 >> 2] | 0;
+ if (($107 | 0) == 0) {
+ break;
+ } else {
+ $R_0 = $107;
+ $RP_0 = $106;
+ }
+ }
+ if ($RP_0 >>> 0 < $5 >>> 0) {
+ _abort();
} else {
- $R_0 = $100;
- $RP_0 = $mem + ((-8 - $21 | 0) + 16) | 0;
+ HEAP32[$RP_0 >> 2] = 0;
+ $R_1 = $R_0;
+ break;
}
} else {
- $R_0 = $95;
- $RP_0 = $mem + ((-8 - $21 | 0) + 20) | 0;
+ helper$1 = 1;
}
- while (1) {
- $102 = $R_0 + 20 | 0;
- $103 = HEAP32[$102 >> 2] | 0;
- if (($103 | 0) != 0) {
- $R_0 = $103;
- $RP_0 = $102;
- continue;
+ }
+ if (helper$1) {
+ helper$1 = 0;
+ if (1) {
+ $80 = HEAP32[$mem + ((-8 - $21 | 0) + 8) >> 2] | 0;
+ if ($80 >>> 0 < $5 >>> 0) {
+ _abort();
+ }
+ if ((HEAP32[($80 + 12 | 0) >> 2] | 0) != ($69 | 0)) {
+ _abort();
}
- $106 = $R_0 + 16 | 0;
- $107 = HEAP32[$106 >> 2] | 0;
- if (($107 | 0) == 0) {
+ if ((HEAP32[($75 + 8 | 0) >> 2] | 0) == ($69 | 0)) {
+ HEAP32[($80 + 12 | 0) >> 2] = $75;
+ HEAP32[($75 + 8 | 0) >> 2] = $80;
+ $R_1 = $75;
break;
} else {
- $R_0 = $107;
- $RP_0 = $106;
+ _abort();
}
- }
- if ($RP_0 >>> 0 < $5 >>> 0) {
- _abort();
} else {
- HEAP32[$RP_0 >> 2] = 0;
- $R_1 = $R_0;
- break;
- }
- } else {
- $80 = HEAP32[$mem + ((-8 - $21 | 0) + 8) >> 2] | 0;
- if ($80 >>> 0 < $5 >>> 0) {
- _abort();
- }
- if ((HEAP32[($80 + 12 | 0) >> 2] | 0) != ($69 | 0)) {
- _abort();
- }
- if ((HEAP32[($75 + 8 | 0) >> 2] | 0) == ($69 | 0)) {
- HEAP32[($80 + 12 | 0) >> 2] = $75;
- HEAP32[($75 + 8 | 0) >> 2] = $80;
- $R_1 = $75;
- break;
- } else {
- _abort();
+ helper$1 = 1;
}
}
} while (0);
if (($72 | 0) == 0) {
$p_0 = $25;
$psize_0 = $26;
- HEAP32[sp + 648 >> 2] = 1;
+ HEAP32[sp + 696 >> 2] = 1;
break OL;
}
$120 = 384 + (HEAP32[($mem + ((-8 - $21 | 0) + 28) | 0) >> 2] << 2) | 0;
@@ -449,8 +498,8 @@ function _free$1(sp) {
HEAP32[21] = HEAP32[21] & (1 << HEAP32[($mem + ((-8 - $21 | 0) + 28) | 0) >> 2] ^ -1);
$p_0 = $25;
$psize_0 = $26;
- HEAP32[sp + 648 >> 2] = 2;
- HEAP32[sp + 652 >> 2] = 2;
+ HEAP32[sp + 696 >> 2] = 2;
+ HEAP32[sp + 700 >> 2] = 2;
break OL;
} else {
if ($72 >>> 0 < (HEAP32[24] | 0) >>> 0) {
@@ -464,8 +513,8 @@ function _free$1(sp) {
if (($R_1 | 0) == 0) {
$p_0 = $25;
$psize_0 = $26;
- HEAP32[sp + 648 >> 2] = 2;
- HEAP32[sp + 652 >> 2] = 2;
+ HEAP32[sp + 696 >> 2] = 2;
+ HEAP32[sp + 700 >> 2] = 2;
break OL;
}
}
@@ -490,7 +539,7 @@ function _free$1(sp) {
if (($164 | 0) == 0) {
$p_0 = $25;
$psize_0 = $26;
- HEAP32[sp + 648 >> 2] = 1;
+ HEAP32[sp + 696 >> 2] = 1;
break OL;
}
if ($164 >>> 0 < (HEAP32[24] | 0) >>> 0) {
@@ -500,7 +549,7 @@ function _free$1(sp) {
HEAP32[$164 + 24 >> 2] = $R_1;
$p_0 = $25;
$psize_0 = $26;
- HEAP32[sp + 648 >> 2] = 1;
+ HEAP32[sp + 696 >> 2] = 1;
break OL;
}
} while (0);
@@ -509,7 +558,7 @@ function _free$1(sp) {
}
function _free$2(sp) {
sp = sp | 0;
- var $194 = 0, $16 = 0, $204 = 0, $psize_0 = 0, $p_0 = 0, $220 = 0, $189 = 0, $227 = 0, $mem = 0, $10 = 0, $psize_1 = 0, $390 = 0, $396 = 0, $F16_0 = 0, $_pre_phi = 0, $404 = 0, $414 = 0, $415 = 0, $I18_0 = 0, $428 = 0, $436 = 0, $443 = 0, $447 = 0, $448 = 0, $463 = 0, $K19_0 = 0, $T_0 = 0, $472 = 0, $473 = 0, label = 0, $486 = 0, $487 = 0, $489 = 0, $501 = 0, $sp_0_in_i = 0, $sp_0_i = 0;
+ var helper$2 = 0, $194 = 0, $16 = 0, $204 = 0, $psize_0 = 0, $p_0 = 0, $220 = 0, $189 = 0, $227 = 0, helper$3 = 0, $mem = 0, $10 = 0, $psize_1 = 0, $390 = 0, $396 = 0, $F16_0 = 0, $_pre_phi = 0, $404 = 0, $414 = 0, $415 = 0, $I18_0 = 0, $428 = 0, $436 = 0, $443 = 0, $447 = 0, $448 = 0, helper$5 = 0, $463 = 0, $K19_0 = 0, $T_0 = 0, $472 = 0, $473 = 0, label = 0, $486 = 0, $487 = 0, $489 = 0, $501 = 0, $sp_0_in_i = 0, $sp_0_i = 0;
$mem = HEAP32[sp + 8 >> 2] | 0;
$10 = HEAP32[sp + 24 >> 2] | 0;
$16 = HEAP32[sp + 32 >> 2] | 0;
@@ -519,73 +568,88 @@ function _free$2(sp) {
$194 = HEAP32[sp + 240 >> 2] | 0;
OL : do {
do {
- if (($194 & 2 | 0) == 0) {
- if (($16 | 0) == (HEAP32[26] | 0)) {
- $204 = (HEAP32[23] | 0) + $psize_0 | 0;
- HEAP32[23] = $204;
- HEAP32[26] = $p_0;
- HEAP32[$p_0 + 4 >> 2] = $204 | 1;
- if (($p_0 | 0) == (HEAP32[25] | 0)) {
- HEAP32[25] = 0;
- HEAP32[22] = 0;
- }
- if ($204 >>> 0 <= (HEAP32[27] | 0) >>> 0) {
- HEAP32[sp + 656 >> 2] = 5;
+ helper$2 = 1;
+ if (helper$2) {
+ helper$2 = 0;
+ if (($194 & 2 | 0) == 0) {
+ if (($16 | 0) == (HEAP32[26] | 0)) {
+ $204 = (HEAP32[23] | 0) + $psize_0 | 0;
+ HEAP32[23] = $204;
+ HEAP32[26] = $p_0;
+ HEAP32[$p_0 + 4 >> 2] = $204 | 1;
+ if (($p_0 | 0) == (HEAP32[25] | 0)) {
+ HEAP32[25] = 0;
+ HEAP32[22] = 0;
+ }
+ if ($204 >>> 0 <= (HEAP32[27] | 0) >>> 0) {
+ HEAP32[sp + 704 >> 2] = 5;
+ break OL;
+ }
+ _sys_trim(0) | 0;
+ HEAP32[sp + 704 >> 2] = 5;
break OL;
}
- _sys_trim(0) | 0;
- HEAP32[sp + 656 >> 2] = 5;
- break OL;
- }
- if (($16 | 0) == (HEAP32[25] | 0)) {
- $220 = (HEAP32[22] | 0) + $psize_0 | 0;
- HEAP32[22] = $220;
- HEAP32[25] = $p_0;
- HEAP32[$p_0 + 4 >> 2] = $220 | 1;
- HEAP32[$189 + $220 >> 2] = $220;
- HEAP32[sp + 656 >> 2] = 5;
- break OL;
- }
- $227 = ($194 & -8) + $psize_0 | 0;
- L726 : do {
- HEAP32[sp + 8 >> 2] = $mem;
- HEAP32[sp + 24 >> 2] = $10;
- HEAP32[sp + 32 >> 2] = $16;
- HEAP32[sp + 240 >> 2] = $194;
- HEAP32[sp + 640 >> 2] = 0;
- HEAP32[sp + 644 >> 2] = 0;
- _free$0(sp);
- tempValue = HEAP32[sp + 640 >> 2] | 0;
- tempInt = HEAP32[sp + 644 >> 2] | 0;
- tempDouble = +HEAPF32[sp + 644 >> 2];
- HEAP32[sp + 640 >> 2] = 0;
- HEAP32[sp + 644 >> 2] = 0;
- if ((tempValue | 0) == 1) {
- break;
+ if (($16 | 0) == (HEAP32[25] | 0)) {
+ $220 = (HEAP32[22] | 0) + $psize_0 | 0;
+ HEAP32[22] = $220;
+ HEAP32[25] = $p_0;
+ HEAP32[$p_0 + 4 >> 2] = $220 | 1;
+ HEAP32[$189 + $220 >> 2] = $220;
+ HEAP32[sp + 704 >> 2] = 5;
+ break OL;
}
- if ((tempValue | 0) == 2) {
- switch (tempInt | 0) {
- case 2:
- {
- break L726;
+ $227 = ($194 & -8) + $psize_0 | 0;
+ L726 : do {
+ helper$3 = 1;
+ HEAP32[sp + 8 >> 2] = $mem;
+ HEAP32[sp + 24 >> 2] = $10;
+ HEAP32[sp + 32 >> 2] = $16;
+ HEAP32[sp + 240 >> 2] = $194;
+ HEAP32[sp + 664 >> 2] = helper$3;
+ HEAP32[sp + 688 >> 2] = 0;
+ HEAP32[sp + 692 >> 2] = 0;
+ _free$0(sp);
+ helper$3 = HEAP32[sp + 664 >> 2] | 0;
+ tempValue = HEAP32[sp + 688 >> 2] | 0;
+ tempInt = HEAP32[sp + 692 >> 2] | 0;
+ tempDouble = +HEAPF32[sp + 692 >> 2];
+ HEAP32[sp + 688 >> 2] = 0;
+ HEAP32[sp + 692 >> 2] = 0;
+ if ((tempValue | 0) == 1) {
+ break;
+ }
+ if ((tempValue | 0) == 2) {
+ switch (tempInt | 0) {
+ case 2:
+ {
+ break L726;
+ }
}
}
+ } while (0);
+ HEAP32[$p_0 + 4 >> 2] = $227 | 1;
+ HEAP32[$189 + $227 >> 2] = $227;
+ if (($p_0 | 0) != (HEAP32[25] | 0)) {
+ $psize_1 = $227;
+ break;
}
- } while (0);
- HEAP32[$p_0 + 4 >> 2] = $227 | 1;
- HEAP32[$189 + $227 >> 2] = $227;
- if (($p_0 | 0) != (HEAP32[25] | 0)) {
- $psize_1 = $227;
- break;
+ HEAP32[22] = $227;
+ HEAP32[sp + 704 >> 2] = 5;
+ break OL;
+ } else {
+ helper$2 = 1;
+ }
+ }
+ if (helper$2) {
+ helper$2 = 0;
+ if (1) {
+ HEAP32[($mem + (($10 & -8) - 4) | 0) >> 2] = $194 & -2;
+ HEAP32[$p_0 + 4 >> 2] = $psize_0 | 1;
+ HEAP32[$189 + $psize_0 >> 2] = $psize_0;
+ $psize_1 = $psize_0;
+ } else {
+ helper$2 = 1;
}
- HEAP32[22] = $227;
- HEAP32[sp + 656 >> 2] = 5;
- break OL;
- } else {
- HEAP32[($mem + (($10 & -8) - 4) | 0) >> 2] = $194 & -2;
- HEAP32[$p_0 + 4 >> 2] = $psize_0 | 1;
- HEAP32[$189 + $psize_0 >> 2] = $psize_0;
- $psize_1 = $psize_0;
}
} while (0);
$390 = $psize_1 >>> 3;
@@ -610,7 +674,7 @@ function _free$2(sp) {
HEAP32[$F16_0 + 12 >> 2] = $p_0;
HEAP32[$p_0 + 8 >> 2] = $F16_0;
HEAP32[$p_0 + 12 >> 2] = 120 + ($390 << 1 << 2) | 0;
- HEAP32[sp + 656 >> 2] = 5;
+ HEAP32[sp + 704 >> 2] = 5;
break OL;
}
$414 = $p_0;
@@ -635,60 +699,72 @@ function _free$2(sp) {
$447 = HEAP32[21] | 0;
$448 = 1 << $I18_0;
do {
- if (($447 & $448 | 0) == 0) {
- HEAP32[21] = $447 | $448;
- HEAP32[$443 >> 2] = $414;
- HEAP32[$p_0 + 24 >> 2] = $443;
- HEAP32[$p_0 + 12 >> 2] = $p_0;
- HEAP32[$p_0 + 8 >> 2] = $p_0;
- } else {
- if (($I18_0 | 0) == 31) {
- $463 = 0;
+ helper$5 = 1;
+ if (helper$5) {
+ helper$5 = 0;
+ if (($447 & $448 | 0) == 0) {
+ HEAP32[21] = $447 | $448;
+ HEAP32[$443 >> 2] = $414;
+ HEAP32[$p_0 + 24 >> 2] = $443;
+ HEAP32[$p_0 + 12 >> 2] = $p_0;
+ HEAP32[$p_0 + 8 >> 2] = $p_0;
} else {
- $463 = 25 - ($I18_0 >>> 1) | 0;
+ helper$5 = 1;
}
- $K19_0 = $psize_1 << $463;
- $T_0 = HEAP32[$443 >> 2] | 0;
- while (1) {
- if ((HEAP32[$T_0 + 4 >> 2] & -8 | 0) == ($psize_1 | 0)) {
- break;
- }
- $472 = $T_0 + 16 + ($K19_0 >>> 31 << 2) | 0;
- $473 = HEAP32[$472 >> 2] | 0;
- if (($473 | 0) == 0) {
- label = 569;
- break;
+ }
+ if (helper$5) {
+ helper$5 = 0;
+ if (1) {
+ if (($I18_0 | 0) == 31) {
+ $463 = 0;
} else {
- $K19_0 = $K19_0 << 1;
- $T_0 = $473;
+ $463 = 25 - ($I18_0 >>> 1) | 0;
}
- }
- if ((label | 0) == 569) {
- if ($472 >>> 0 < (HEAP32[24] | 0) >>> 0) {
+ $K19_0 = $psize_1 << $463;
+ $T_0 = HEAP32[$443 >> 2] | 0;
+ while (1) {
+ if ((HEAP32[$T_0 + 4 >> 2] & -8 | 0) == ($psize_1 | 0)) {
+ break;
+ }
+ $472 = $T_0 + 16 + ($K19_0 >>> 31 << 2) | 0;
+ $473 = HEAP32[$472 >> 2] | 0;
+ if (($473 | 0) == 0) {
+ label = 569;
+ break;
+ } else {
+ $K19_0 = $K19_0 << 1;
+ $T_0 = $473;
+ }
+ }
+ if ((label | 0) == 569) {
+ if ($472 >>> 0 < (HEAP32[24] | 0) >>> 0) {
+ _abort();
+ } else {
+ HEAP32[$472 >> 2] = $414;
+ HEAP32[$p_0 + 24 >> 2] = $T_0;
+ HEAP32[$p_0 + 12 >> 2] = $p_0;
+ HEAP32[$p_0 + 8 >> 2] = $p_0;
+ break;
+ }
+ }
+ $486 = $T_0 + 8 | 0;
+ $487 = HEAP32[$486 >> 2] | 0;
+ $489 = HEAP32[24] | 0;
+ if ($T_0 >>> 0 < $489 >>> 0) {
+ _abort();
+ }
+ if ($487 >>> 0 < $489 >>> 0) {
_abort();
} else {
- HEAP32[$472 >> 2] = $414;
- HEAP32[$p_0 + 24 >> 2] = $T_0;
- HEAP32[$p_0 + 12 >> 2] = $p_0;
- HEAP32[$p_0 + 8 >> 2] = $p_0;
+ HEAP32[$487 + 12 >> 2] = $414;
+ HEAP32[$486 >> 2] = $414;
+ HEAP32[$p_0 + 8 >> 2] = $487;
+ HEAP32[$p_0 + 12 >> 2] = $T_0;
+ HEAP32[$p_0 + 24 >> 2] = 0;
break;
}
- }
- $486 = $T_0 + 8 | 0;
- $487 = HEAP32[$486 >> 2] | 0;
- $489 = HEAP32[24] | 0;
- if ($T_0 >>> 0 < $489 >>> 0) {
- _abort();
- }
- if ($487 >>> 0 < $489 >>> 0) {
- _abort();
} else {
- HEAP32[$487 + 12 >> 2] = $414;
- HEAP32[$486 >> 2] = $414;
- HEAP32[$p_0 + 8 >> 2] = $487;
- HEAP32[$p_0 + 12 >> 2] = $T_0;
- HEAP32[$p_0 + 24 >> 2] = 0;
- break;
+ helper$5 = 1;
}
}
} while (0);
@@ -697,7 +773,7 @@ function _free$2(sp) {
if (($501 | 0) == 0) {
$sp_0_in_i = 536;
} else {
- HEAP32[sp + 656 >> 2] = 5;
+ HEAP32[sp + 704 >> 2] = 5;
break OL;
}
while (1) {
@@ -710,7 +786,7 @@ function _free$2(sp) {
}
HEAP32[28] = -1;
STACKTOP = sp;
- HEAP32[sp + 656 >> 2] = 5;
+ HEAP32[sp + 704 >> 2] = 5;
break OL;
} while (0);
}