diff options
-rw-r--r-- | src/library.js | 14 | ||||
-rw-r--r-- | src/library_browser.js | 4 | ||||
-rw-r--r-- | system/include/libc/sys/dirent.h | 1 | ||||
-rw-r--r-- | tests/dirent/test_readdir.c | 132 | ||||
-rw-r--r-- | tests/fcntl-misc/src.c | 2 | ||||
-rw-r--r-- | tests/fcntl-open/output.txt | 10 | ||||
-rw-r--r-- | tests/fcntl-open/src.c | 64 | ||||
-rwxr-xr-x | tests/runner.py | 171 | ||||
-rw-r--r-- | tests/utime/test_utime.c | 53 | ||||
-rw-r--r-- | tools/js-optimizer.js | 6 | ||||
-rw-r--r-- | tools/test-js-optimizer-asm-pre-output.js | 3 | ||||
-rw-r--r-- | tools/test-js-optimizer-asm-pre.js | 3 |
12 files changed, 269 insertions, 194 deletions
diff --git a/src/library.js b/src/library.js index eddeb89b..20a163c6 100644 --- a/src/library.js +++ b/src/library.js @@ -737,7 +737,8 @@ LibraryManager.library = { // int closedir(DIR *dirp); // http://pubs.opengroup.org/onlinepubs/007908799/xsh/closedir.html if (!FS.streams[dirp] || !FS.streams[dirp].object.isFolder) { - return ___setErrNo(ERRNO_CODES.EBADF); + ___setErrNo(ERRNO_CODES.EBADF); + return -1; } else { _free(FS.streams[dirp].currentEntry); FS.streams[dirp] = null; @@ -749,7 +750,8 @@ LibraryManager.library = { // long int telldir(DIR *dirp); // http://pubs.opengroup.org/onlinepubs/007908799/xsh/telldir.html if (!FS.streams[dirp] || !FS.streams[dirp].object.isFolder) { - return ___setErrNo(ERRNO_CODES.EBADF); + ___setErrNo(ERRNO_CODES.EBADF); + return -1; } else { return FS.streams[dirp].position; } @@ -865,10 +867,6 @@ LibraryManager.library = { } var file = FS.findObject(Pointer_stringify(path)); if (file === null) return -1; - if (!file.write) { - ___setErrNo(ERRNO_CODES.EPERM); - return -1; - } file.timestamp = time; return 0; }, @@ -1213,7 +1211,7 @@ LibraryManager.library = { ___setErrNo(ERRNO_CODES.EEXIST); return -1; } - if ((isWrite || isCreate || isTruncate) && target.isFolder) { + if ((isWrite || isTruncate) && target.isFolder) { ___setErrNo(ERRNO_CODES.EISDIR); return -1; } @@ -1381,7 +1379,7 @@ LibraryManager.library = { posix_fallocate: function(fd, offset, len) { // int posix_fallocate(int fd, off_t offset, off_t len); // http://pubs.opengroup.org/onlinepubs/009695399/functions/posix_fallocate.html - if (!FS.streams[fd] || FS.streams[fd].link || + if (!FS.streams[fd] || !FS.streams[fd].isWrite || FS.streams[fd].link || FS.streams[fd].isFolder || FS.streams[fd].isDevice) { ___setErrNo(ERRNO_CODES.EBADF); return -1; diff --git a/src/library_browser.js b/src/library_browser.js index 822e99d6..7f79b2bd 100644 --- a/src/library_browser.js +++ b/src/library_browser.js @@ -91,6 +91,10 @@ mergeInto(LibraryManager.library, { if (Browser.hasBlobConstructor) { try { b = new Blob([byteArray], { type: getMimetype(name) }); + if (b.size !== byteArray.length) { // Safari bug #118630 + // Safari's Blob can only take an ArrayBuffer + b = new Blob([(new Uint8Array(byteArray)).buffer], { type: getMimetype(name) }); + } } catch(e) { Runtime.warnOnce('Blob constructor present but fails: ' + e + '; falling back to blob builder'); } diff --git a/system/include/libc/sys/dirent.h b/system/include/libc/sys/dirent.h index 0d8b02b5..e6ce831e 100644 --- a/system/include/libc/sys/dirent.h +++ b/system/include/libc/sys/dirent.h @@ -24,6 +24,7 @@ DIR *opendir(const char *); void seekdir(DIR *, long); long telldir(DIR *); DIR *readdir(DIR *); +int readdir_r(DIR *, struct dirent *, struct dirent **); int closedir(DIR *dirp); void rewinddir(DIR *dirp); int scandir(const char *dirp, diff --git a/tests/dirent/test_readdir.c b/tests/dirent/test_readdir.c new file mode 100644 index 00000000..9f7b12e8 --- /dev/null +++ b/tests/dirent/test_readdir.c @@ -0,0 +1,132 @@ +#include <assert.h> +#include <dirent.h> +#include <errno.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <sys/stat.h> + +static void create_file(const char *path, const char *buffer, int mode) { + int fd = open(path, O_WRONLY | O_CREAT | O_EXCL, mode); + assert(fd >= 0); + + int err = write(fd, buffer, sizeof(char) * strlen(buffer)); + assert(err == (sizeof(char) * strlen(buffer))); + + close(fd); +} + +void setup() { + mkdir("nocanread", 0111); + mkdir("foobar", 0777); + create_file("foobar/file.txt", "ride into the danger zone", 0666); +} + +void cleanup() { + rmdir("nocanread"); + unlink("foobar/file.txt"); + rmdir("foobar"); +} + +void test() { + int err; + int loc; + DIR *dir; + struct dirent *ent; + struct dirent ent_r; + struct dirent *result; + + // check bad opendir input + dir = opendir("noexist"); + assert(!dir); + assert(errno == ENOENT); + dir = opendir("nocanread"); + assert(!dir); + assert(errno == EACCES); + dir = opendir("foobar/file.txt"); + assert(!dir); + assert(errno == ENOTDIR); + + // check bad readdir input + dir = opendir("foobar"); + closedir(dir); + ent = readdir(dir); + assert(!ent); + assert(errno == EBADF); + + // check bad readdir_r input + dir = opendir("foobar"); + closedir(dir); + err = readdir_r(dir, NULL, &result); + assert(err == EBADF); + + // + // do a normal read with readdir + // + dir = opendir("foobar"); + assert(dir); + ent = readdir(dir); + assert(!strcmp(ent->d_name, ".")); + assert(ent->d_type & DT_DIR); + ent = readdir(dir); + assert(!strcmp(ent->d_name, "..")); + assert(ent->d_type & DT_DIR); + ent = readdir(dir); + assert(!strcmp(ent->d_name, "file.txt")); + assert(ent->d_type & DT_REG); + ent = readdir(dir); + assert(!ent); + + // test rewinddir + rewinddir(dir); + ent = readdir(dir); + assert(!strcmp(ent->d_name, ".")); + + // test seek / tell + rewinddir(dir); + ent = readdir(dir); + assert(!strcmp(ent->d_name, ".")); + loc = telldir(dir); + ent = readdir(dir); + assert(!strcmp(ent->d_name, "..")); + ent = readdir(dir); + assert(!strcmp(ent->d_name, "file.txt")); + seekdir(dir, loc); + ent = readdir(dir); + assert(!strcmp(ent->d_name, "..")); + + // + // do a normal read with readdir_r + // + rewinddir(dir); + err = readdir_r(dir, &ent_r, &result); + assert(!err); + assert(&ent_r == result); + assert(!strcmp(ent_r.d_name, ".")); + err = readdir_r(dir, &ent_r, &result); + assert(!err); + assert(&ent_r == result); + assert(!strcmp(ent_r.d_name, "..")); + err = readdir_r(dir, &ent_r, &result); + assert(!err); + assert(&ent_r == result); + assert(!strcmp(ent_r.d_name, "file.txt")); + err = readdir_r(dir, &ent_r, &result); + assert(!err); + assert(!result); + + err = closedir(dir); + assert(!err); + + puts("success"); +} + +int main() { + atexit(cleanup); + signal(SIGABRT, cleanup); + setup(); + test(); + return EXIT_SUCCESS; +}
\ No newline at end of file diff --git a/tests/fcntl-misc/src.c b/tests/fcntl-misc/src.c index 73734969..7cdbbcd6 100644 --- a/tests/fcntl-misc/src.c +++ b/tests/fcntl-misc/src.c @@ -6,7 +6,7 @@ int main() { struct stat s; - int f = open("/test", O_RDONLY, 0777); + int f = open("/test", O_RDWR, 0777); printf("posix_fadvise: %d\n", posix_fadvise(f, 3, 2, POSIX_FADV_DONTNEED)); printf("errno: %d\n", errno); diff --git a/tests/fcntl-open/output.txt b/tests/fcntl-open/output.txt index 314ae880..07b106ac 100644 --- a/tests/fcntl-open/output.txt +++ b/tests/fcntl-open/output.txt @@ -19,8 +19,8 @@ errno: 0 st_mode: 0100000 EXISTING FOLDER 0,1 -success: 0 -errno: 21 +success: 1 +errno: 0 st_mode: 040000 NON-EXISTING 0,1 @@ -139,8 +139,8 @@ errno: 0 st_mode: 0100000 EXISTING FOLDER 0,9 -success: 0 -errno: 21 +success: 1 +errno: 0 st_mode: 040000 NON-EXISTING 0,9 @@ -720,4 +720,4 @@ st_mode: 0100000 CREAT success: 1 -errno: 0 +errno: 0
\ No newline at end of file diff --git a/tests/fcntl-open/src.c b/tests/fcntl-open/src.c index 52d2e7e4..bd52dd3f 100644 --- a/tests/fcntl-open/src.c +++ b/tests/fcntl-open/src.c @@ -1,13 +1,45 @@ -#include <stdio.h> +#include <assert.h> #include <errno.h> -#include <sys/stat.h> #include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> #include <string.h> +#include <unistd.h> +#include <sys/stat.h> -int main() { +char nonexistent_name[] = "noexist-##"; + +void create_file(const char *path, const char *buffer, int mode) { + int fd = open(path, O_WRONLY | O_CREAT | O_EXCL, mode); + assert(fd >= 0); + + int err = write(fd, buffer, sizeof(char) * strlen(buffer)); + assert(err == (sizeof(char) * strlen(buffer))); + + close(fd); +} + +void setup() { + create_file("test-file", "abcdef", 0777); + mkdir("test-folder", 0777); +} + +void cleanup() { + unlink("test-file"); + rmdir("test-folder"); + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 16; j++) { + nonexistent_name[8] = 'a' + i; + nonexistent_name[9] = 'a' + j; + unlink(nonexistent_name); + } + } + unlink("creat-me"); +} + +void test() { struct stat s; int modes[] = {O_RDONLY, O_WRONLY, O_RDWR}; - char nonexistent_name[] = "/noexist-##"; for (int i = 0; i < 3; i++) { for (int j = 0; j < 16; j++) { @@ -18,25 +50,25 @@ int main() { if (j & 0x8) flags |= O_APPEND; printf("EXISTING FILE %d,%d\n", i, j); - printf("success: %d\n", open("/test-file", flags, 0777) != -1); + printf("success: %d\n", open("test-file", flags, 0777) != -1); printf("errno: %d\n", errno); - stat("/test-file", &s); + stat("test-file", &s); printf("st_mode: 0%o\n", s.st_mode & 037777777000); memset(&s, 0, sizeof s); printf("\n"); errno = 0; printf("EXISTING FOLDER %d,%d\n", i, j); - printf("success: %d\n", open("/test-folder", flags, 0777) != -1); + printf("success: %d\n", open("test-folder", flags, 0777) != -1); printf("errno: %d\n", errno); - stat("/test-folder", &s); + stat("test-folder", &s); printf("st_mode: 0%o\n", s.st_mode & 037777777000); memset(&s, 0, sizeof s); printf("\n"); errno = 0; - nonexistent_name[9] = 'a' + i; - nonexistent_name[10] = 'a' + j; + nonexistent_name[8] = 'a' + i; + nonexistent_name[9] = 'a' + j; printf("NON-EXISTING %d,%d\n", i, j); printf("success: %d\n", open(nonexistent_name, flags, 0777) != -1); printf("errno: %d\n", errno); @@ -49,8 +81,14 @@ int main() { } printf("CREAT\n"); - printf("success: %d\n", creat("/creat-me", 0777) != -1); + printf("success: %d\n", creat("creat-me", 0777) != -1); printf("errno: %d\n", errno); - - return 0; } + +int main() { + atexit(cleanup); + signal(SIGABRT, cleanup); + setup(); + test(); + return EXIT_SUCCESS; +}
\ No newline at end of file diff --git a/tests/runner.py b/tests/runner.py index 69006184..ea702689 100755 --- a/tests/runner.py +++ b/tests/runner.py @@ -6794,84 +6794,9 @@ def process(filename): self.emcc_args += ['--embed-file', 'three_numbers.txt'] self.do_run(src, 'match = 3\nx = -1.0, y = 0.1, z = -0.1\n') - def test_folders(self): - add_pre_run = ''' -def process(filename): - src = open(filename, 'r').read().replace( - '// {{PRE_RUN_ADDITIONS}}', - \'\'\' - FS.createFolder('/', 'test', true, false); - FS.createPath('/', 'test/hello/world/', true, false); - FS.createPath('/test', 'goodbye/world/', true, false); - FS.createPath('/test/goodbye', 'noentry', false, false); - FS.createDataFile('/test', 'freeforall.ext', 'abc', true, true); - FS.createDataFile('/test', 'restricted.ext', 'def', false, false); - \'\'\' - ) - open(filename, 'w').write(src) -''' - src = r''' - #include <stdio.h> - #include <dirent.h> - #include <errno.h> - - int main() { - struct dirent *e; - - // Basic correct behaviour. - DIR* d = opendir("/test"); - printf("--E: %d\n", errno); - while ((e = readdir(d))) puts(e->d_name); - printf("--E: %d\n", errno); - - // Empty folder; tell/seek. - puts("****"); - d = opendir("/test/hello/world/"); - e = readdir(d); - puts(e->d_name); - int pos = telldir(d); - e = readdir(d); - puts(e->d_name); - seekdir(d, pos); - e = readdir(d); - puts(e->d_name); - - // Errors. - puts("****"); - printf("--E: %d\n", errno); - d = opendir("/test/goodbye/noentry"); - printf("--E: %d, D: %d\n", errno, d); - d = opendir("/i/dont/exist"); - printf("--E: %d, D: %d\n", errno, d); - d = opendir("/test/freeforall.ext"); - printf("--E: %d, D: %d\n", errno, d); - while ((e = readdir(d))) puts(e->d_name); - printf("--E: %d\n", errno); - - return 0; - } - ''' - expected = ''' - --E: 0 - . - .. - hello - goodbye - freeforall.ext - restricted.ext - --E: 0 - **** - . - .. - .. - **** - --E: 0 - --E: 13, D: 0 - --E: 2, D: 0 - --E: 20, D: 0 - --E: 9 - ''' - self.do_run(src, re.sub('(^|\n)\s+', '\\1', expected), post_build=add_pre_run) + def test_readdir(self): + src = open(path_from_root('tests', 'dirent', 'test_readdir.c'), 'r').read() + self.do_run(src, 'success', force_c=True) def test_stat(self): add_pre_run = ''' @@ -6906,20 +6831,9 @@ def process(filename): self.do_run(src, expected, post_build=add_pre_run, extra_emscripten_args=['-H', 'libc/fcntl.h']) def test_fcntl_open(self): - add_pre_run = ''' -def process(filename): - src = open(filename, 'r').read().replace( - '// {{PRE_RUN_ADDITIONS}}', - \'\'\' - FS.createDataFile('/', 'test-file', 'abcdef', true, true); - FS.createFolder('/', 'test-folder', true, true); - \'\'\' - ) - open(filename, 'w').write(src) -''' src = open(path_from_root('tests', 'fcntl-open', 'src.c'), 'r').read() expected = open(path_from_root('tests', 'fcntl-open', 'output.txt'), 'r').read() - self.do_run(src, expected, post_build=add_pre_run, extra_emscripten_args=['-H', 'libc/fcntl.h']) + self.do_run(src, expected, force_c=True, extra_emscripten_args=['-H', 'libc/fcntl.h']) def test_fcntl_misc(self): add_pre_run = ''' @@ -7087,49 +7001,8 @@ def process(filename): self.do_run(src, re.sub('(^|\n)\s+', '\\1', expected)) def test_utime(self): - add_pre_run_and_checks = ''' -def process(filename): - src = open(filename, 'r').read().replace( - '// {{PRE_RUN_ADDITIONS}}', - \'\'\' - var TEST_F1 = FS.createFolder('/', 'writeable', true, true); - var TEST_F2 = FS.createFolder('/', 'unwriteable', true, false); - \'\'\' - ).replace( - '// {{POST_RUN_ADDITIONS}}', - \'\'\' - Module.print('first changed: ' + (TEST_F1.timestamp == 1200000000000)); - Module.print('second changed: ' + (TEST_F2.timestamp == 1200000000000)); - \'\'\' - ) - open(filename, 'w').write(src) -''' - src = r''' - #include <stdio.h> - #include <errno.h> - #include <utime.h> - - int main() { - struct utimbuf t = {1000000000, 1200000000}; - char* writeable = "/writeable"; - char* unwriteable = "/unwriteable"; - - utime(writeable, &t); - printf("writeable errno: %d\n", errno); - - utime(unwriteable, &t); - printf("unwriteable errno: %d\n", errno); - - return 0; - } - ''' - expected = ''' - writeable errno: 0 - unwriteable errno: 1 - first changed: true - second changed: false - ''' - self.do_run(src, re.sub('(^|\n)\s+', '\\1', expected), post_build=add_pre_run_and_checks) + src = open(path_from_root('tests', 'utime', 'test_utime.c'), 'r').read() + self.do_run(src, 'success', force_c=True) def test_utf(self): self.banned_js_engines = [SPIDERMONKEY_ENGINE] # only node handles utf well @@ -7221,38 +7094,6 @@ def process(filename): Settings.LINKABLE = linkable # regression check for issue #273 self.do_run(src, "1 2 3") - def test_readdir(self): - add_pre_run = ''' -def process(filename): - src = open(filename, 'r').read().replace( - '// {{PRE_RUN_ADDITIONS}}', - "FS.createFolder('', 'test', true, true);\\nFS.createLazyFile( 'test', 'some_file', 'http://localhost/some_file', true, false);\\nFS.createFolder('test', 'some_directory', true, true);" - ) - open(filename, 'w').write(src) -''' - - src = ''' - #include <dirent.h> - #include <stdio.h> - - int main() - { - DIR * dir; - dirent * entity; - - dir = opendir( "test" ); - - while( ( entity = readdir( dir ) ) ) - { - printf( "%s is a %s\\n", entity->d_name, entity->d_type & DT_DIR ? "directory" : "file" ); - } - - return 0; - } - - ''' - self.do_run(src, ". is a directory\n.. is a directory\nsome_file is a file\nsome_directory is a directory", post_build=add_pre_run) - def test_fs_base(self): Settings.INCLUDE_FULL_LIBRARY = 1 try: diff --git a/tests/utime/test_utime.c b/tests/utime/test_utime.c new file mode 100644 index 00000000..1793f4a5 --- /dev/null +++ b/tests/utime/test_utime.c @@ -0,0 +1,53 @@ +#include <assert.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <utime.h> +#include <sys/stat.h> + +void setup() { + mkdir("writeable", 0777); + mkdir("unwriteable", 0111); +} + +void cleanup() { + rmdir("writeable"); + rmdir("unwriteable"); +} + +void test() { + struct stat s; + // currently, the most recent timestamp is shared for atime, + // ctime and mtime. using unique values for each in the test + // will fail + struct utimbuf t = {1000000000, 1000000000}; + + utime("writeable", &t); + assert(!errno); + memset(&s, 0, sizeof s); + stat("writeable", &s); + assert(s.st_atime == t.actime); + assert(s.st_mtime == t.modtime); + + // write permissions aren't checked when setting node + // attributes unless the user uid isn't the owner (so + // therefor, this should work fine) + utime("unwriteable", &t); + assert(!errno); + memset(&s, 0, sizeof s); + stat("unwriteable", &s); + assert(s.st_atime == t.actime); + assert(s.st_mtime == t.modtime); + + puts("success"); +} + +int main() { + atexit(cleanup); + signal(SIGABRT, cleanup); + setup(); + test(); + return EXIT_SUCCESS; +}
\ No newline at end of file diff --git a/tools/js-optimizer.js b/tools/js-optimizer.js index 6987511c..71a59921 100644 --- a/tools/js-optimizer.js +++ b/tools/js-optimizer.js @@ -562,7 +562,8 @@ function simplifyExpressionsPre(ast) { } else if (type === 'binary' && node[1] === '^') { // LLVM represents bitwise not as xor with -1. Translate it back to an actual bitwise not. if (node[3][0] === 'unary-prefix' && node[3][1] === '-' && node[3][2][0] === 'num' && - node[3][2][1] === 1) { + node[3][2][1] === 1 && + !(node[2][0] == 'unary-prefix' && node[2][1] == '~')) { // avoid creating ~~~ which is confusing for asm given the role of ~~ return ['unary-prefix', '~', node[2]]; } } else if (type === 'binary' && node[1] === '>>' && node[3][0] === 'num' && @@ -636,7 +637,8 @@ function simplifyExpressionsPre(ast) { if (node[0] === 'seq' && node[1][0] === 'assign' && node[1][2][0] === 'sub' && node[1][2][1][0] === 'name' && (node[1][2][1][1] === 'HEAP32' || node[1][2][1][1] === 'HEAPF32') && node[1][2][2][0] === 'binary' && node[1][2][2][2][0] === 'name' && node[1][2][2][2][1] === 'tempDoublePtr' && - node[1][3][0] === 'sub' && node[1][3][1][0] === 'name' && (node[1][3][1][1] === 'HEAP32' || node[1][3][1][1] === 'HEAPF32')) { + node[1][3][0] === 'sub' && node[1][3][1][0] === 'name' && (node[1][3][1][1] === 'HEAP32' || node[1][3][1][1] === 'HEAPF32') && + node[2][0] !== 'seq') { // avoid (x, y, z) which can be used for tempDoublePtr on doubles for alignment fixes if (node[1][2][1][1] === 'HEAP32') { node[1][3][1][1] = 'HEAPF32'; return ['unary-prefix', '+', node[1][3]]; diff --git a/tools/test-js-optimizer-asm-pre-output.js b/tools/test-js-optimizer-asm-pre-output.js index b7afab26..8a5803d6 100644 --- a/tools/test-js-optimizer-asm-pre-output.js +++ b/tools/test-js-optimizer-asm-pre-output.js @@ -66,6 +66,7 @@ function b($this, $__n) { HEAP32[$4] = ~HEAP32[$5]; HEAP32[$4] = ~HEAP32[$5]; HEAP32[$4] = ~HEAP32[$5]; + h(~~g ^ -1); return; } function rett() { @@ -156,6 +157,8 @@ function tempDoublePtr($45, $14, $28, $42) { unelim2 = 127 + $14 | 0; func(); HEAP32[4] = unelim2; + barrier(); + $f163 = (HEAP32[tempDoublePtr >> 2] = HEAP32[$f165 >> 2], HEAP32[tempDoublePtr + 4 >> 2] = HEAP32[$f165 + 4 >> 2], +HEAPF64[tempDoublePtr >> 3]); } function boxx($this, $aabb, $xf, $childIndex) { $this = $this | 0; diff --git a/tools/test-js-optimizer-asm-pre.js b/tools/test-js-optimizer-asm-pre.js index b762a60e..5c004342 100644 --- a/tools/test-js-optimizer-asm-pre.js +++ b/tools/test-js-optimizer-asm-pre.js @@ -70,6 +70,7 @@ function b($this, $__n) { HEAP32[$4] = HEAP32[$5]^-1; // Rewrite to ~ and eliminate the |0. HEAP32[$4] = ((HEAP32[$5]|0)^-1)|0; + h((~~g) ^ -1); // do NOT convert this, as it would lead to ~~~ which is confusing in asm, given the role of ~~ return; } function rett() { @@ -166,6 +167,8 @@ function tempDoublePtr($45, $14, $28, $42) { unelim2 = (HEAP32[tempDoublePtr >> 2] = 127 + $14, +HEAPF32[tempDoublePtr >> 2]); func(); HEAPF32[4] = unelim2; + barrier(); + $f163 = (HEAP32[tempDoublePtr >> 2] = HEAP32[$f165 >> 2], HEAP32[tempDoublePtr + 4 >> 2] = HEAP32[$f165 + 4 >> 2], +HEAPF64[tempDoublePtr >> 3]); } function boxx($this, $aabb, $xf, $childIndex) { $this = $this | 0; |