aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AUTHORS1
-rw-r--r--cmake/Platform/Emscripten.cmake10
-rwxr-xr-xemcc1
-rw-r--r--src/library.js71
-rw-r--r--src/library_browser.js21
-rw-r--r--src/library_fs.js8
-rw-r--r--src/library_gl.js111
-rw-r--r--src/library_html5.js179
-rw-r--r--src/library_memfs.js5
-rw-r--r--src/library_sockfs.js2
-rw-r--r--src/postamble.js12
-rw-r--r--src/preamble.js250
-rw-r--r--system/include/emscripten/emscripten.h4
-rw-r--r--system/lib/gl.c4
-rw-r--r--tests/cases/atomicrmw_dec.ll21
-rw-r--r--tests/cases/atomicrmw_dec.txt1
-rw-r--r--tests/cases/dollar.ll22
-rw-r--r--tests/cases/ptrtoint_blockaddr.ll14
-rw-r--r--tests/emscripten_api_browser.cpp16
-rw-r--r--tests/fuzz/18.cpp1125
-rw-r--r--tests/fuzz/18.cpp.txt1
-rwxr-xr-xtests/fuzz/creduce_tester.py2
-rwxr-xr-xtests/fuzz/csmith_driver.py4
-rwxr-xr-xtests/fuzz/test.sh3
-rwxr-xr-xtests/fuzz/testpp.sh51
-rw-r--r--tests/printf/output.txt1
-rw-r--r--tests/printf/test.c1
-rw-r--r--tests/test_browser.py2
-rw-r--r--tests/test_core.py21
-rw-r--r--tests/test_locale.c24
-rw-r--r--tests/test_locale.out12
-rw-r--r--tests/test_sanity.py12
-rw-r--r--tools/make_minigzip.py2
33 files changed, 1709 insertions, 305 deletions
diff --git a/AUTHORS b/AUTHORS
index 39f41407..6c6b3f27 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -125,3 +125,4 @@ a license to everyone to use it as detailed in LICENSE.)
* Sami Vaarala <sami.vaarala@iki.fi>
* Jack A. Arrington <jack@epicpineapple.com>
* Richard Janicek <r@janicek.co>
+* Joel Croteau <jcroteau@gmail.com>
diff --git a/cmake/Platform/Emscripten.cmake b/cmake/Platform/Emscripten.cmake
index 4f434d14..7d86c467 100644
--- a/cmake/Platform/Emscripten.cmake
+++ b/cmake/Platform/Emscripten.cmake
@@ -125,20 +125,20 @@ set(CMAKE_C_SIZEOF_DATA_PTR 4)
set(CMAKE_CXX_SIZEOF_DATA_PTR 4)
set(CMAKE_C_FLAGS_RELEASE "-DNDEBUG -O2" CACHE STRING "Emscripten-overridden CMAKE_C_FLAGS_RELEASE")
-set(CMAKE_C_FLAGS_MINSIZEREL "-DNDEBUG -O2" CACHE STRING "Emscripten-overridden CMAKE_C_FLAGS_MINSIZEREL")
+set(CMAKE_C_FLAGS_MINSIZEREL "-DNDEBUG -Os" CACHE STRING "Emscripten-overridden CMAKE_C_FLAGS_MINSIZEREL")
set(CMAKE_C_FLAGS_RELWITHDEBINFO "-O2" CACHE STRING "Emscripten-overridden CMAKE_C_FLAGS_RELWITHDEBINFO")
set(CMAKE_CXX_FLAGS_RELEASE "-DNDEBUG -O2" CACHE STRING "Emscripten-overridden CMAKE_CXX_FLAGS_RELEASE")
-set(CMAKE_CXX_FLAGS_MINSIZEREL "-DNDEBUG -O2" CACHE STRING "Emscripten-overridden CMAKE_CXX_FLAGS_MINSIZEREL")
+set(CMAKE_CXX_FLAGS_MINSIZEREL "-DNDEBUG -Os" CACHE STRING "Emscripten-overridden CMAKE_CXX_FLAGS_MINSIZEREL")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2" CACHE STRING "Emscripten-overridden CMAKE_CXX_FLAGS_RELWITHDEBINFO")
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "-O2" CACHE STRING "Emscripten-overridden CMAKE_EXE_LINKER_FLAGS_RELEASE")
-set(CMAKE_EXE_LINKER_FLAGS_MINSIZEREL "-O2" CACHE STRING "Emscripten-overridden CMAKE_EXE_LINKER_FLAGS_MINSIZEREL")
+set(CMAKE_EXE_LINKER_FLAGS_MINSIZEREL "-Os" CACHE STRING "Emscripten-overridden CMAKE_EXE_LINKER_FLAGS_MINSIZEREL")
set(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "-O2 -g" CACHE STRING "Emscripten-overridden CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO")
set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "-O2" CACHE STRING "Emscripten-overridden CMAKE_SHARED_LINKER_FLAGS_RELEASE")
-set(CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL "-O2" CACHE STRING "Emscripten-overridden CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL")
+set(CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL "-Os" CACHE STRING "Emscripten-overridden CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL")
set(CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO "-O2 -g" CACHE STRING "Emscripten-overridden CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO")
set(CMAKE_MODULE_LINKER_FLAGS_RELEASE "-O2" CACHE STRING "Emscripten-overridden CMAKE_MODULE_LINKER_FLAGS_RELEASE")
-set(CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL "-O2" CACHE STRING "Emscripten-overridden CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL")
+set(CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL "-Os" CACHE STRING "Emscripten-overridden CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL")
set(CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO "-O2 -g" CACHE STRING "Emscripten-overridden CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO")
function(em_validate_asmjs_after_build target)
diff --git a/emcc b/emcc
index 491e8dff..2c3033aa 100755
--- a/emcc
+++ b/emcc
@@ -1217,6 +1217,7 @@ try:
assert not split_js_file, '--split-js is deprecated and not supported in fastcomp'
assert not bind, 'embind not supported in fastcomp yet'
assert shared.Settings.MAX_SETJMPS == 20, 'changing MAX_SETJMPS is not supported in fastcomp yet'
+ assert shared.Settings.INIT_HEAP == 0, 'HEAP_INIT is not supported in fastcomp (and should never be needed except for debugging)'
if jcache:
logging.warning('jcache is not supported in fastcomp (you should not need it anyhow), disabling')
jcache = False
diff --git a/src/library.js b/src/library.js
index c1eb2219..91d5f925 100644
--- a/src/library.js
+++ b/src/library.js
@@ -131,7 +131,7 @@ LibraryManager.library = {
stream.position++;
return 0;
},
- readdir__deps: ['readdir_r', '__setErrNo', '$ERRNO_CODES'],
+ readdir__deps: ['readdir_r', '__setErrNo', '$ERRNO_CODES', 'malloc'],
readdir: function(dirp) {
// struct dirent *readdir(DIR *dirp);
// http://pubs.opengroup.org/onlinepubs/007908799/xsh/readdir_r.html
@@ -1021,7 +1021,7 @@ LibraryManager.library = {
return -1;
}
},
- ttyname__deps: ['ttyname_r'],
+ ttyname__deps: ['ttyname_r', 'malloc'],
ttyname: function(fildes) {
// char *ttyname(int fildes);
// http://pubs.opengroup.org/onlinepubs/000095399/functions/ttyname.html
@@ -1287,7 +1287,7 @@ LibraryManager.library = {
return -1;
}
},
- getlogin__deps: ['getlogin_r'],
+ getlogin__deps: ['getlogin_r', 'malloc'],
getlogin: function() {
// char *getlogin(void);
// http://pubs.opengroup.org/onlinepubs/000095399/functions/getlogin.html
@@ -1970,7 +1970,7 @@ LibraryManager.library = {
}
next = {{{ makeGetValue(0, 'textIndex+1', 'i8') }}};
}
- if (precision === -1) {
+ if (precision < 0) {
precision = 6; // Standard default.
precisionSet = false;
}
@@ -2695,7 +2695,7 @@ LibraryManager.library = {
if (buf) _setvbuf(stream, buf, 0, 8192); // _IOFBF, BUFSIZ.
else _setvbuf(stream, buf, 2, 8192); // _IONBF, BUFSIZ.
},
- tmpnam__deps: ['$FS'],
+ tmpnam__deps: ['$FS', 'malloc'],
tmpnam: function(s, dir, prefix) {
// char *tmpnam(char *s);
// http://pubs.opengroup.org/onlinepubs/000095399/functions/tmpnam.html
@@ -2792,7 +2792,7 @@ LibraryManager.library = {
function unget() { index--; };
return __scanString(format, get, unget, varargs);
},
- snprintf__deps: ['_formatString'],
+ snprintf__deps: ['_formatString', 'malloc'],
snprintf: function(s, n, format, varargs) {
// int snprintf(char *restrict s, size_t n, const char *restrict format, ...);
// http://pubs.opengroup.org/onlinepubs/000095399/functions/printf.html
@@ -2903,7 +2903,7 @@ LibraryManager.library = {
// sys/mman.h
// ==========================================================================
- mmap__deps: ['$FS'],
+ mmap__deps: ['$FS', 'malloc', 'memset'],
mmap: function(start, num, prot, flags, fd, offset) {
/* FIXME: Since mmap is normally implemented at the kernel level,
* this implementation simply uses malloc underneath the call to
@@ -3061,7 +3061,7 @@ LibraryManager.library = {
return 0;
},
- realloc__deps: ['memcpy'],
+ realloc__deps: ['malloc', 'memcpy', 'free'],
realloc: function(ptr, size) {
// Very simple, inefficient implementation - if you use a real malloc, best to use
// a real realloc with it
@@ -3275,7 +3275,7 @@ LibraryManager.library = {
return _strtoll(ptr, null, 10);
},
- qsort__deps: ['memcpy'],
+ qsort__deps: ['malloc', 'memcpy', 'free'],
qsort: function(base, num, size, cmp) {
if (num == 0 || size == 0) return;
// forward calls to the JavaScript sort method
@@ -3825,7 +3825,7 @@ LibraryManager.library = {
},
rindex: 'strrchr',
- strdup__deps: ['strlen'],
+ strdup__deps: ['strlen', 'malloc'],
strdup: function(ptr) {
var len = _strlen(ptr);
var newStr = _malloc(len + 1);
@@ -3834,7 +3834,7 @@ LibraryManager.library = {
return newStr;
},
- strndup__deps: ['strdup', 'strlen'],
+ strndup__deps: ['strdup', 'strlen', 'malloc'],
strndup: function(ptr, size) {
var len = _strlen(ptr);
@@ -3942,7 +3942,7 @@ LibraryManager.library = {
return ___setErrNo(ERRNO_CODES.EINVAL);
}
},
- strerror__deps: ['strerror_r'],
+ strerror__deps: ['strerror_r', 'malloc'],
strerror: function(errnum) {
if (!_strerror.buffer) _strerror.buffer = _malloc(256);
_strerror_r(errnum, _strerror.buffer, 256);
@@ -4080,6 +4080,7 @@ LibraryManager.library = {
return _isgraph(chr); // no locale support yet
},
// Lookup tables for glibc ctype implementation.
+ __ctype_b_loc__deps: ['malloc'],
__ctype_b_loc: function() {
// http://refspecs.freestandards.org/LSB_3.0.0/LSB-Core-generic/LSB-Core-generic/baselib---ctype-b-loc.html
var me = ___ctype_b_loc;
@@ -4105,6 +4106,7 @@ LibraryManager.library = {
}
return me.ret;
},
+ __ctype_tolower_loc__deps: ['malloc'],
__ctype_tolower_loc: function() {
// http://refspecs.freestandards.org/LSB_3.1.1/LSB-Core-generic/LSB-Core-generic/libutil---ctype-tolower-loc.html
var me = ___ctype_tolower_loc;
@@ -4133,6 +4135,7 @@ LibraryManager.library = {
}
return me.ret;
},
+ __ctype_toupper_loc__deps: ['malloc'],
__ctype_toupper_loc: function() {
// http://refspecs.freestandards.org/LSB_3.1.1/LSB-Core-generic/LSB-Core-generic/libutil---ctype-toupper-loc.html
var me = ___ctype_toupper_loc;
@@ -4338,12 +4341,12 @@ LibraryManager.library = {
__cxa_caught_exceptions: [],
// Exceptions
- __cxa_allocate_exception__deps: ['__cxa_exception_header_size'],
+ __cxa_allocate_exception__deps: ['__cxa_exception_header_size', 'malloc'],
__cxa_allocate_exception: function(size) {
var ptr = _malloc(size + ___cxa_exception_header_size);
return ptr + ___cxa_exception_header_size;
},
- __cxa_free_exception__deps: ['__cxa_exception_header_size'],
+ __cxa_free_exception__deps: ['__cxa_exception_header_size', 'free'],
__cxa_free_exception: function(ptr) {
try {
return _free(ptr - ___cxa_exception_header_size);
@@ -4414,7 +4417,7 @@ LibraryManager.library = {
// we don't actually get the value that we allocated, but something else. Easiest
// to remember that the last exception thrown is going to be the first to be caught,
// so just use that value instead as it is what we're really looking for.
- __cxa_begin_catch__deps: ['_ZSt18uncaught_exceptionv', '__cxa_caught_exceptions'],
+ __cxa_begin_catch__deps: ['_ZSt18uncaught_exceptionv', '__cxa_caught_exceptions', '__cxa_last_thrown_exception'],
__cxa_begin_catch: function(ptr) {
__ZSt18uncaught_exceptionv.uncaught_exception--;
___cxa_caught_exceptions.push(___cxa_last_thrown_exception);
@@ -4449,14 +4452,13 @@ LibraryManager.library = {
___cxa_last_thrown_exception = 0;
}
},
- __cxa_get_exception_ptr__deps: ['___cxa_last_thrown_exception'],
__cxa_get_exception_ptr: function(ptr) {
return ptr;
},
_ZSt18uncaught_exceptionv: function() { // std::uncaught_exception()
return !!__ZSt18uncaught_exceptionv.uncaught_exception;
},
- __cxa_uncaught_exception__deps: ['_Zst18uncaught_exceptionv'],
+ __cxa_uncaught_exception__deps: ['_ZSt18uncaught_exceptionv'],
__cxa_uncaught_exception: function() {
return !!__ZSt18uncaught_exceptionv.uncaught_exception;
},
@@ -4532,7 +4534,7 @@ LibraryManager.library = {
{{{ makeStructuralReturn(['thrown', 'throwntype']) }}};
},
- __resumeException__deps: [function() { Functions.libraryFunctions['__resumeException'] = 1 }], // will be called directly from compiled code
+ __resumeException__deps: [function() { Functions.libraryFunctions['__resumeException'] = 1 }, '__cxa_last_thrown_exception'], // will be called directly from compiled code
__resumeException: function(ptr) {
#if EXCEPTION_DEBUG
Module.print("Resuming exception");
@@ -4585,7 +4587,7 @@ LibraryManager.library = {
_ZNSt9exceptionD1Ev: function() {},
_ZNSt9exceptionD2Ev: function() {},
- _ZNKSt9exception4whatEv__deps: ['_malloc'],
+ _ZNKSt9exception4whatEv__deps: ['malloc'],
_ZNKSt9exception4whatEv: function() {
if (!__ZNKSt9exception4whatEv.buffer) {
var name = "std::exception";
@@ -6443,7 +6445,19 @@ LibraryManager.library = {
// var indexes = Runtime.calculateStructAlignment({ fields: ['i32', 'i32'] });
var me = _localeconv;
if (!me.ret) {
- me.ret = allocate([allocate(intArrayFromString('.'), 'i8', ALLOC_NORMAL)], 'i8*', ALLOC_NORMAL); // just decimal point, for now
+ // These are defaults from the "C" locale
+ me.ret = allocate([
+ allocate(intArrayFromString('.'), 'i8', ALLOC_NORMAL),0,0,0, // decimal_point
+ allocate(intArrayFromString(''), 'i8', ALLOC_NORMAL),0,0,0, // thousands_sep
+ allocate(intArrayFromString(''), 'i8', ALLOC_NORMAL),0,0,0, // grouping
+ allocate(intArrayFromString(''), 'i8', ALLOC_NORMAL),0,0,0, // int_curr_symbol
+ allocate(intArrayFromString(''), 'i8', ALLOC_NORMAL),0,0,0, // currency_symbol
+ allocate(intArrayFromString(''), 'i8', ALLOC_NORMAL),0,0,0, // mon_decimal_point
+ allocate(intArrayFromString(''), 'i8', ALLOC_NORMAL),0,0,0, // mon_thousands_sep
+ allocate(intArrayFromString(''), 'i8', ALLOC_NORMAL),0,0,0, // mon_grouping
+ allocate(intArrayFromString(''), 'i8', ALLOC_NORMAL),0,0,0, // positive_sign
+ allocate(intArrayFromString(''), 'i8', ALLOC_NORMAL),0,0,0 // negative_sign
+ ], 'i8*', ALLOC_NORMAL); // Allocate strings in lconv, still don't allocate chars
}
return me.ret;
},
@@ -6454,6 +6468,7 @@ LibraryManager.library = {
// langinfo.h
// ==========================================================================
+ nl_langinfo__deps: ['malloc'],
nl_langinfo: function(item) {
// char *nl_langinfo(nl_item item);
// http://pubs.opengroup.org/onlinepubs/000095399/functions/nl_langinfo.html
@@ -7080,7 +7095,7 @@ LibraryManager.library = {
}
return addr;
},
- inet_ntoa__deps: ['_inet_ntop4_raw'],
+ inet_ntoa__deps: ['_inet_ntop4_raw', 'malloc'],
inet_ntoa: function(in_addr) {
if (!_inet_ntoa.buffer) {
_inet_ntoa.buffer = _malloc(1024);
@@ -7442,7 +7457,7 @@ LibraryManager.library = {
return _gethostbyname(hostp);
},
- gethostbyname__deps: ['$DNS', '_inet_pton4_raw'],
+ gethostbyname__deps: ['$DNS', '_inet_pton4_raw', 'malloc'],
gethostbyname: function(name) {
name = Pointer_stringify(name);
@@ -7475,7 +7490,7 @@ LibraryManager.library = {
return 0;
},
- getaddrinfo__deps: ['$Sockets', '$DNS', '_inet_pton4_raw', '_inet_ntop4_raw', '_inet_pton6_raw', '_inet_ntop6_raw', '_write_sockaddr', 'htonl'],
+ getaddrinfo__deps: ['$Sockets', '$DNS', '_inet_pton4_raw', '_inet_ntop4_raw', '_inet_pton6_raw', '_inet_ntop6_raw', '_write_sockaddr', 'htonl', 'malloc'],
getaddrinfo: function(node, service, hint, out) {
// Note getaddrinfo currently only returns a single addrinfo with ai_next defaulting to NULL. When NULL
// hints are specified or ai_family set to AF_UNSPEC or ai_socktype or ai_protocol set to 0 then we
@@ -7692,7 +7707,7 @@ LibraryManager.library = {
// are actually negative numbers and you can't have expressions as keys in JavaScript literals.
$GAI_ERRNO_MESSAGES: {},
- gai_strerror__deps: ['$GAI_ERRNO_MESSAGES'],
+ gai_strerror__deps: ['$GAI_ERRNO_MESSAGES', 'malloc'],
gai_strerror: function(val) {
var buflen = 256;
@@ -7734,7 +7749,7 @@ LibraryManager.library = {
list: [],
map: {}
},
- setprotoent__deps: ['$Protocols'],
+ setprotoent__deps: ['$Protocols', 'malloc'],
setprotoent: function(stayopen) {
// void setprotoent(int stayopen);
@@ -8397,7 +8412,7 @@ LibraryManager.library = {
}
},
- getsockname__deps: ['$FS', '$SOCKFS', '$DNS', '$ERRNO_CODES', '__setErrNo', '_write_sockaddr', '_inet_pton_raw'],
+ getsockname__deps: ['$FS', '$SOCKFS', '$DNS', '$ERRNO_CODES', '__setErrNo', '_write_sockaddr'],
getsockname: function (fd, addr, addrlen) {
var sock = SOCKFS.getSocket(fd);
if (!sock) {
@@ -8415,7 +8430,7 @@ LibraryManager.library = {
}
},
- getpeername__deps: ['$FS', '$SOCKFS', '$DNS', '$ERRNO_CODES', '__setErrNo', '_write_sockaddr', '_inet_pton_raw'],
+ getpeername__deps: ['$FS', '$SOCKFS', '$DNS', '$ERRNO_CODES', '__setErrNo', '_write_sockaddr'],
getpeername: function (fd, addr, addrlen) {
var sock = SOCKFS.getSocket(fd);
if (!sock) {
@@ -8565,7 +8580,7 @@ LibraryManager.library = {
}
},
- recvmsg__deps: ['$FS', '$SOCKFS', '$DNS', '$ERRNO_CODES', '__setErrNo', '_inet_pton_raw', '_write_sockaddr'],
+ recvmsg__deps: ['$FS', '$SOCKFS', '$DNS', '$ERRNO_CODES', '__setErrNo', '_write_sockaddr'],
recvmsg: function(fd, message, flags) {
var sock = SOCKFS.getSocket(fd);
if (!sock) {
diff --git a/src/library_browser.js b/src/library_browser.js
index 50a8fc6f..b800292c 100644
--- a/src/library_browser.js
+++ b/src/library_browser.js
@@ -234,6 +234,10 @@ mergeInto(LibraryManager.library, {
}
#endif
var ctx;
+ var errorInfo = '?';
+ function onContextCreationError(event) {
+ errorInfo = event.statusMessage || errorInfo;
+ }
try {
if (useWebGL) {
var contextAttributes = {
@@ -251,10 +255,6 @@ mergeInto(LibraryManager.library, {
contextAttributes.preserveDrawingBuffer = true;
#endif
- var errorInfo = '?';
- function onContextCreationError(event) {
- errorInfo = event.statusMessage || errorInfo;
- }
canvas.addEventListener('webglcontextcreationerror', onContextCreationError, false);
try {
['experimental-webgl', 'webgl'].some(function(webglId) {
@@ -752,7 +752,7 @@ mergeInto(LibraryManager.library, {
document.body.appendChild(script);
},
- emscripten_set_main_loop: function(func, fps, simulateInfiniteLoop) {
+ emscripten_set_main_loop: function(func, fps, simulateInfiniteLoop, arg) {
Module['noExitRuntime'] = true;
Browser.mainLoop.runner = function Browser_mainLoop_runner() {
@@ -803,7 +803,11 @@ mergeInto(LibraryManager.library, {
}
try {
- Runtime.dynCall('v', func);
+ if (typeof arg !== 'undefined') {
+ Runtime.dynCall('vi', func, [arg]);
+ } else {
+ Runtime.dynCall('v', func);
+ }
} catch (e) {
if (e instanceof ExitStatus) {
return;
@@ -843,6 +847,11 @@ mergeInto(LibraryManager.library, {
}
},
+ emscripten_set_main_loop_arg__deps: ['emscripten_set_main_loop'],
+ emscripten_set_main_loop_arg: function(func, arg, fps, simulateInfiniteLoop) {
+ _emscripten_set_main_loop(func, fps, simulateInfiniteLoop, arg);
+ },
+
emscripten_cancel_main_loop: function() {
Browser.mainLoop.scheduler = null;
Browser.mainLoop.shouldPause = true;
diff --git a/src/library_fs.js b/src/library_fs.js
index e97ba588..1428f041 100644
--- a/src/library_fs.js
+++ b/src/library_fs.js
@@ -616,13 +616,13 @@ mergeInto(LibraryManager.library, {
},
// helpers to create specific types of nodes
create: function(path, mode) {
- mode = mode !== undefined ? mode : 0666;
+ mode = mode !== undefined ? mode : 438 /* 0666 */;
mode &= {{{ cDefine('S_IALLUGO') }}};
mode |= {{{ cDefine('S_IFREG') }}};
return FS.mknod(path, mode, 0);
},
mkdir: function(path, mode) {
- mode = mode !== undefined ? mode : 0777;
+ mode = mode !== undefined ? mode : 511 /* 0777 */;
mode &= {{{ cDefine('S_IRWXUGO') }}} | {{{ cDefine('S_ISVTX') }}};
mode |= {{{ cDefine('S_IFDIR') }}};
return FS.mknod(path, mode, 0);
@@ -630,7 +630,7 @@ mergeInto(LibraryManager.library, {
mkdev: function(path, mode, dev) {
if (typeof(dev) === 'undefined') {
dev = mode;
- mode = 0666;
+ mode = 438 /* 0666 */;
}
mode |= {{{ cDefine('S_IFCHR') }}};
return FS.mknod(path, mode, dev);
@@ -895,7 +895,7 @@ mergeInto(LibraryManager.library, {
},
open: function(path, flags, mode, fd_start, fd_end) {
flags = typeof flags === 'string' ? FS.modeStringToFlags(flags) : flags;
- mode = typeof mode === 'undefined' ? 0666 : mode;
+ mode = typeof mode === 'undefined' ? 438 /* 0666 */ : mode;
if ((flags & {{{ cDefine('O_CREAT') }}})) {
mode = (mode & {{{ cDefine('S_IALLUGO') }}}) | {{{ cDefine('S_IFREG') }}};
} else {
diff --git a/src/library_gl.js b/src/library_gl.js
index e3442a8a..7e4c5a97 100644
--- a/src/library_gl.js
+++ b/src/library_gl.js
@@ -19,6 +19,7 @@ var LibraryGL = {
textures: [],
uniforms: [],
shaders: [],
+ vaos: [],
#if FULL_ES2
clientBuffers: [],
@@ -633,6 +634,9 @@ var LibraryGL = {
// Extension available from Firefox 26 and Google Chrome 30
GL.instancedArraysExt = GLctx.getExtension('ANGLE_instanced_arrays');
+
+ // Extension available from Firefox 25 and WebKit
+ GL.vaoExt = Module.ctx.getExtension('OES_vertex_array_object');
// These are the 'safe' feature-enabling extensions that don't add any performance impact related to e.g. debugging, and
// should be enabled by default so that client GLES2/GL code will not need to go through extra hoops to get its stuff working.
@@ -1797,6 +1801,81 @@ var LibraryGL = {
},
#if LEGACY_GL_EMULATION
+ glGenVertexArrays__deps: ['emulGlGenVertexArrays'],
+#endif
+ glGenVertexArrays__sig: 'vii',
+ glGenVertexArrays: function (n, arrays) {
+#if LEGACY_GL_EMULATION
+ _emulGlGenVertexArrays(n, arrays);
+#else
+#if GL_ASSERTIONS
+ assert(GL.vaoExt, 'Must have OES_vertex_array_object to use vao');
+#endif
+
+ for(var i = 0; i < n; i++) {
+ var id = GL.getNewId(GL.vaos);
+ var vao = GL.vaoExt.createVertexArrayOES();
+ vao.name = id;
+ GL.vaos[id] = vao;
+ {{{ makeSetValue('arrays', 'i*4', 'id', 'i32') }}};
+ }
+#endif
+ },
+
+#if LEGACY_GL_EMULATION
+ glDeleteVertexArrays__deps: ['emulGlDeleteVertexArrays'],
+#endif
+ glDeleteVertexArrays__sig: 'vii',
+ glDeleteVertexArrays: function(n, vaos) {
+#if LEGACY_GL_EMULATION
+ _emulGlDeleteVertexArrays(n, vaos);
+#else
+#if GL_ASSERTIONS
+ assert(GL.vaoExt, 'Must have OES_vertex_array_object to use vao');
+#endif
+ for(var i = 0; i < n; i++) {
+ var id = {{{ makeGetValue('vaos', 'i*4', 'i32') }}};
+ GL.vaoExt.deleteVertexArrayOES(GL.vaos[id]);
+ GL.vaos[id] = null;
+ }
+#endif
+ },
+
+#if LEGACY_GL_EMULATION
+ glBindVertexArray__deps: ['emulGlBindVertexArray'],
+#endif
+ glBindVertexArray__sig: 'vi',
+ glBindVertexArray: function(vao) {
+#if LEGACY_GL_EMULATION
+ _emulGlBindVertexArray(vao);
+#else
+#if GL_ASSERTIONS
+ assert(GL.vaoExt, 'Must have OES_vertex_array_object to use vao');
+#endif
+
+ GL.vaoExt.bindVertexArrayOES(GL.vaos[vao]);
+#endif
+ },
+
+#if LEGACY_GL_EMULATION
+ glIsVertexArray__deps: ['emulGlIsVertexArray'],
+#endif
+ glIsVertexArray__sig: 'ii',
+ glIsVertexArray: function(array) {
+#if LEGACY_GL_EMULATION
+ return _emulGlIsVertexArray(array);
+#else
+#if GL_ASSERTIONS
+ assert(GL.vaoExt, 'Must have OES_vertex_array_object to use vao');
+#endif
+
+ var vao = GL.vaos[array];
+ if (!vao) return 0;
+ return GL.vaoExt.isVertexArrayOES(vao);
+#endif
+ },
+
+#if LEGACY_GL_EMULATION
// GL emulation: provides misc. functionality not present in OpenGL ES 2.0 or WebGL
@@ -4809,9 +4888,9 @@ var LibraryGL = {
},
// Vertex array object (VAO) support. TODO: when the WebGL extension is popular, use that and remove this code and GL.vaos
- glGenVertexArrays__deps: ['$GLEmulation'],
- glGenVertexArrays__sig: 'vii',
- glGenVertexArrays: function(n, vaos) {
+ emulGlGenVertexArrays__deps: ['$GLEmulation'],
+ emulGlGenVertexArrays__sig: 'vii',
+ emulGlGenVertexArrays: function(n, vaos) {
for (var i = 0; i < n; i++) {
var id = GL.getNewId(GLEmulation.vaos);
GLEmulation.vaos[id] = {
@@ -4825,17 +4904,23 @@ var LibraryGL = {
{{{ makeSetValue('vaos', 'i*4', 'id', 'i32') }}};
}
},
- glDeleteVertexArrays__sig: 'vii',
- glDeleteVertexArrays: function(n, vaos) {
+ emulGlDeleteVertexArrays__sig: 'vii',
+ emulGlDeleteVertexArrays: function(n, vaos) {
for (var i = 0; i < n; i++) {
var id = {{{ makeGetValue('vaos', 'i*4', 'i32') }}};
GLEmulation.vaos[id] = null;
if (GLEmulation.currentVao && GLEmulation.currentVao.id == id) GLEmulation.currentVao = null;
}
},
- glBindVertexArray__deps: ['glBindBuffer', 'glEnableVertexAttribArray', 'glVertexAttribPointer', 'glEnableClientState'],
- glBindVertexArray__sig: 'vi',
- glBindVertexArray: function(vao) {
+ emulGlIsVertexArray__sig: 'vi',
+ emulGlIsVertexArray: function(array) {
+ var vao = GLEmulation.vaos[array];
+ if (!vao) return 0;
+ return 1;
+ },
+ emulGlBindVertexArray__deps: ['glBindBuffer', 'glEnableVertexAttribArray', 'glVertexAttribPointer', 'glEnableClientState'],
+ emulGlBindVertexArray__sig: 'vi',
+ emulGlBindVertexArray: function(vao) {
// undo vao-related things, wipe the slate clean, both for vao of 0 or an actual vao
GLEmulation.currentVao = null; // make sure the commands we run here are not recorded
if (GLImmediate.lastRenderer) GLImmediate.lastRenderer.cleanup();
@@ -5034,21 +5119,23 @@ var LibraryGL = {
glCheckFramebufferStatusOES : 'glCheckFramebufferStatus',
glDeleteFramebuffersOES : 'glDeleteFramebuffers',
glDeleteRenderbuffersOES : 'glDeleteRenderbuffers',
- glGenVertexArraysOES: 'glGenVertexArrays',
- glDeleteVertexArraysOES: 'glDeleteVertexArrays',
- glBindVertexArrayOES: 'glBindVertexArray',
glFramebufferTexture2DOES: 'glFramebufferTexture2D',
#else // LEGACY_GL_EMULATION
glVertexPointer: function(){ throw 'Legacy GL function (glVertexPointer) called. If you want legacy GL emulation, you need to compile with -s LEGACY_GL_EMULATION=1 to enable legacy GL emulation.'; },
- glGenVertexArrays: function(){ throw 'Legacy GL function (glGenVertexArrays) called. If you want legacy GL emulation, you need to compile with -s LEGACY_GL_EMULATION=1 to enable legacy GL emulation.'; },
glMatrixMode: function(){ throw 'Legacy GL function (glMatrixMode) called. If you want legacy GL emulation, you need to compile with -s LEGACY_GL_EMULATION=1 to enable legacy GL emulation.'; },
glBegin: function(){ throw 'Legacy GL function (glBegin) called. If you want legacy GL emulation, you need to compile with -s LEGACY_GL_EMULATION=1 to enable legacy GL emulation.'; },
glLoadIdentity: function(){ throw 'Legacy GL function (glLoadIdentity) called. If you want legacy GL emulation, you need to compile with -s LEGACY_GL_EMULATION=1 to enable legacy GL emulation.'; },
#endif // LEGACY_GL_EMULATION
+ // Open GLES1.1 vao compatibility (Could work w/o -s LEGACY_GL_EMULATION=1)
+
+ glGenVertexArraysOES: 'glGenVertexArrays',
+ glDeleteVertexArraysOES: 'glDeleteVertexArrays',
+ glBindVertexArrayOES: 'glBindVertexArray',
+
// GLU
gluPerspective: function(fov, aspect, near, far) {
diff --git a/src/library_html5.js b/src/library_html5.js
index a38c2390..a28bcb85 100644
--- a/src/library_html5.js
+++ b/src/library_html5.js
@@ -156,17 +156,17 @@ var LibraryJSEvents = {
var e = event || window.event;
writeStringToMemory(e.key ? e.key : "", JSEvents.keyEvent + {{{ C_STRUCTS.EmscriptenKeyboardEvent.key }}} );
writeStringToMemory(e.code ? e.code : "", JSEvents.keyEvent + {{{ C_STRUCTS.EmscriptenKeyboardEvent.code }}} );
- {{{ makeSetValue('JSEvents.keyEvent', C_STRUCTS.EmscriptenKeyboardEvent.location, 'e.location', 'i32') }}}
- {{{ makeSetValue('JSEvents.keyEvent', C_STRUCTS.EmscriptenKeyboardEvent.ctrlKey, 'e.ctrlKey', 'i32') }}}
- {{{ makeSetValue('JSEvents.keyEvent', C_STRUCTS.EmscriptenKeyboardEvent.shiftKey, 'e.shiftKey', 'i32') }}}
- {{{ makeSetValue('JSEvents.keyEvent', C_STRUCTS.EmscriptenKeyboardEvent.altKey, 'e.altKey', 'i32') }}}
- {{{ makeSetValue('JSEvents.keyEvent', C_STRUCTS.EmscriptenKeyboardEvent.metaKey, 'e.metaKey', 'i32') }}}
- {{{ makeSetValue('JSEvents.keyEvent', C_STRUCTS.EmscriptenKeyboardEvent.repeat, 'e.repeat', 'i32') }}}
+ {{{ makeSetValue('JSEvents.keyEvent', C_STRUCTS.EmscriptenKeyboardEvent.location, 'e.location', 'i32') }}};
+ {{{ makeSetValue('JSEvents.keyEvent', C_STRUCTS.EmscriptenKeyboardEvent.ctrlKey, 'e.ctrlKey', 'i32') }}};
+ {{{ makeSetValue('JSEvents.keyEvent', C_STRUCTS.EmscriptenKeyboardEvent.shiftKey, 'e.shiftKey', 'i32') }}};
+ {{{ makeSetValue('JSEvents.keyEvent', C_STRUCTS.EmscriptenKeyboardEvent.altKey, 'e.altKey', 'i32') }}};
+ {{{ makeSetValue('JSEvents.keyEvent', C_STRUCTS.EmscriptenKeyboardEvent.metaKey, 'e.metaKey', 'i32') }}};
+ {{{ makeSetValue('JSEvents.keyEvent', C_STRUCTS.EmscriptenKeyboardEvent.repeat, 'e.repeat', 'i32') }}};
writeStringToMemory(e.locale ? e.locale : "", JSEvents.keyEvent + {{{ C_STRUCTS.EmscriptenKeyboardEvent.locale }}} );
writeStringToMemory(e.char ? e.char : "", JSEvents.keyEvent + {{{ C_STRUCTS.EmscriptenKeyboardEvent.charValue }}} );
- {{{ makeSetValue('JSEvents.keyEvent', C_STRUCTS.EmscriptenKeyboardEvent.charCode, 'e.charCode', 'i32') }}}
- {{{ makeSetValue('JSEvents.keyEvent', C_STRUCTS.EmscriptenKeyboardEvent.keyCode, 'e.keyCode', 'i32') }}}
- {{{ makeSetValue('JSEvents.keyEvent', C_STRUCTS.EmscriptenKeyboardEvent.which, 'e.which', 'i32') }}}
+ {{{ makeSetValue('JSEvents.keyEvent', C_STRUCTS.EmscriptenKeyboardEvent.charCode, 'e.charCode', 'i32') }}};
+ {{{ makeSetValue('JSEvents.keyEvent', C_STRUCTS.EmscriptenKeyboardEvent.keyCode, 'e.keyCode', 'i32') }}};
+ {{{ makeSetValue('JSEvents.keyEvent', C_STRUCTS.EmscriptenKeyboardEvent.which, 'e.which', 'i32') }}};
var shouldCancel = Runtime.dynCall('iiii', callbackfunc, [eventTypeId, JSEvents.keyEvent, userData]);
if (shouldCancel) {