aboutsummaryrefslogtreecommitdiff
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 = {