aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorToadKing <toadking@toadking.com>2013-08-12 23:30:49 -0400
committerToadKing <toadking@toadking.com>2013-08-12 23:30:49 -0400
commit7466223864929d50d02407dde1da331133a0bef1 (patch)
tree60403b8061880e6aea503a20d9c45b3e678ec6ad
parentc2b064eb49ea63eec59add5751c8a9c2b80dab92 (diff)
parent3090cdd713609a9d3f749d13002a898e03cbd5e3 (diff)
Merge branch 'incoming' of https://github.com/kripken/emscripten into fixed_openal_buffers
Conflicts: src/library_openal.js
-rwxr-xr-xem++2
-rwxr-xr-xemscripten.py2
-rw-r--r--src/analyzer.js10
-rw-r--r--src/library.js1818
-rw-r--r--src/library_fs.js1368
-rw-r--r--src/library_memfs.js217
-rw-r--r--src/library_openal.js272
-rw-r--r--src/library_sdl.js76
-rw-r--r--src/library_sockfs.js18
-rw-r--r--src/library_tty.js121
-rw-r--r--src/modules.js2
-rw-r--r--src/parseTools.js17
-rw-r--r--src/preamble.js7
-rw-r--r--src/settings.js7
-rw-r--r--tests/cases/phi24_ta2.ll3
-rwxr-xr-xtests/runner.py15231
-rw-r--r--tests/sdl_pumpevents.c54
-rw-r--r--tests/sockets/socket_relay.py (renamed from tests/socket_relay.py)0
-rw-r--r--tests/sockets/test_enet_client.c (renamed from tests/enet_client.c)24
-rw-r--r--tests/sockets/test_enet_server.c (renamed from tests/enet_server.c)15
-rw-r--r--tests/sockets/test_sockets.c143
-rw-r--r--tests/sockets/test_sockets_bi.c138
-rw-r--r--tests/sockets/test_sockets_bi_bigdata.c138
-rw-r--r--tests/sockets/test_sockets_bi_side.c93
-rw-r--r--tests/sockets/test_sockets_bi_side_bigdata.c90
-rw-r--r--tests/sockets/test_sockets_bigdata.h20
-rw-r--r--tests/sockets/test_sockets_echo_client.c148
-rw-r--r--tests/sockets/test_sockets_echo_server.c152
-rw-r--r--tests/sockets/test_sockets_gethostbyname.c131
-rw-r--r--tests/sockets/test_sockets_msg.h78
-rw-r--r--tests/sockets/test_sockets_partial_client.c (renamed from tests/sockets/test_sockets_partial.c)2
-rw-r--r--tests/sockets/test_sockets_partial_server.c130
-rw-r--r--tests/sockets/test_sockets_select_server_closes_connection.c112
-rw-r--r--tests/sockets/test_sockets_select_server_closes_connection_client_rw.c (renamed from tests/sockets/test_sockets_select_server_closes_connection_rw.c)42
-rw-r--r--tests/sockets/test_sockets_select_server_no_accept_client.c (renamed from tests/sockets/test_sockets_select.c)0
-rw-r--r--tests/sockets/test_sockets_select_server_no_accept_server.c86
-rw-r--r--tests/test_benchmark.py507
-rw-r--r--tests/test_browser.py1378
-rw-r--r--tests/test_core.py10074
-rw-r--r--tests/test_other.py1913
-rw-r--r--tests/test_sanity.py522
-rw-r--r--tests/test_sockets.py200
-rw-r--r--tools/find_bigvars.py24
-rw-r--r--tools/js-optimizer.js24
-rw-r--r--tools/shared.py142
-rw-r--r--tools/test-js-optimizer-asm-outline1-output.js315
-rw-r--r--tools/test-js-optimizer-asm-outline2-output.js562
47 files changed, 18108 insertions, 18320 deletions
diff --git a/em++ b/em++
index ba09e1a2..810b7aec 100755
--- a/em++
+++ b/em++
@@ -8,5 +8,7 @@ import os, subprocess, sys
from tools import shared
os.environ['EMMAKEN_CXX'] = '1'
+if not os.path.exists(shared.PYTHON):
+ print >> sys.stderr, 'warning: PYTHON does not seem to be defined properly in ~/.emscripten (%s)' % shared.PYTHON
exit(subprocess.call([shared.PYTHON, shared.EMCC] + sys.argv[1:]))
diff --git a/emscripten.py b/emscripten.py
index 217fd6d5..1b1284c7 100755
--- a/emscripten.py
+++ b/emscripten.py
@@ -423,6 +423,8 @@ def emscript(infile, settings, outfile, libraries=[], compiler_engine=None,
math_envs = ['Math.min'] # TODO: move min to maths
asm_setup += '\n'.join(['var %s = %s;' % (f.replace('.', '_'), f) for f in math_envs])
+ if settings['TO_FLOAT32']: maths += ['Math.toFloat32']
+
basic_funcs = ['abort', 'assert', 'asmPrintInt', 'asmPrintFloat'] + [m.replace('.', '_') for m in math_envs]
if settings['RESERVED_FUNCTION_POINTERS'] > 0: basic_funcs.append('jsCall')
if settings['SAFE_HEAP']: basic_funcs += ['SAFE_HEAP_LOAD', 'SAFE_HEAP_STORE', 'SAFE_HEAP_CLEAR']
diff --git a/src/analyzer.js b/src/analyzer.js
index 1a752305..931ce421 100644
--- a/src/analyzer.js
+++ b/src/analyzer.js
@@ -765,7 +765,15 @@ function analyzer(data, sidePass) {
}
break;
}
- case 'add': case 'sub': case 'sdiv': case 'udiv': case 'mul': case 'urem': case 'srem':
+ case 'add': case 'sub': case 'sdiv': case 'udiv': case 'mul': case 'urem': case 'srem': {
+ if (sourceBits < 32) {
+ // when we add illegal types like i24, we must work on the singleton chunks
+ item.assignTo += '$0';
+ item.params[0].ident += '$0';
+ item.params[1].ident += '$0';
+ }
+ // fall through
+ }
case 'uitofp': case 'sitofp': case 'fptosi': case 'fptoui': {
// We cannot do these in parallel chunks of 32-bit operations. We will handle these in processMathop
i++;
diff --git a/src/library.js b/src/library.js
index f0302aaa..815badc1 100644
--- a/src/library.js
+++ b/src/library.js
@@ -18,1737 +18,12 @@
// Memory allocated during startup, in postsets, should only be ALLOC_STATIC
LibraryManager.library = {
- // ==========================================================================
- // File system base.
- // ==========================================================================
-
// keep this low in memory, because we flatten arrays with them in them
stdin: 'allocate(1, "i32*", ALLOC_STATIC)',
stdout: 'allocate(1, "i32*", ALLOC_STATIC)',
stderr: 'allocate(1, "i32*", ALLOC_STATIC)',
_impure_ptr: 'allocate(1, "i32*", ALLOC_STATIC)',
- $FS__deps: ['$ERRNO_CODES', '$ERRNO_MESSAGES', '__setErrNo', '$VFS', '$PATH', '$TTY', '$MEMFS', 'stdin', 'stdout', 'stderr', 'fflush'],
- $FS__postset: 'FS.staticInit();' +
- '__ATINIT__.unshift({ func: function() { if (!Module["noFSInit"] && !FS.init.initialized) FS.init() } });' +
- '__ATMAIN__.push({ func: function() { FS.ignorePermissions = false } });' +
- '__ATEXIT__.push({ func: function() { FS.quit() } });' +
- // export some names through closure
- 'Module["FS_createFolder"] = FS.createFolder;' +
- 'Module["FS_createPath"] = FS.createPath;' +
- 'Module["FS_createDataFile"] = FS.createDataFile;' +
- 'Module["FS_createPreloadedFile"] = FS.createPreloadedFile;' +
- 'Module["FS_createLazyFile"] = FS.createLazyFile;' +
- 'Module["FS_createLink"] = FS.createLink;' +
- 'Module["FS_createDevice"] = FS.createDevice;',
- $FS: {
- root: null,
- nodes: [null],
- devices: [null],
- streams: [null],
- nextInode: 1,
- name_table: new Array(4096),
- currentPath: '/',
- initialized: false,
- // Whether we are currently ignoring permissions. Useful when preparing the
- // filesystem and creating files inside read-only folders.
- // This is set to false when the runtime is initialized, allowing you
- // 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;
- }
- }
- this.message = ERRNO_MESSAGES[errno];
- },
-
- handleFSError: function(e) {
- if (!(e instanceof FS.ErrnoError)) throw e + ' : ' + new Error().stack;
- return ___setErrNo(e.errno);
- },
-
- //
- // nodes
- //
- hashName: function(parentid, name) {
- var hash = 0;
- for (var i = 0; i < name.length; i++) {
- hash = ((hash << 5) - hash + name.charCodeAt(i)) | 0;
- }
- return (parentid + hash) % FS.name_table.length;
- },
- hashAddNode: function(node) {
- var hash = FS.hashName(node.parent.id, node.name);
- node.name_next = FS.name_table[hash];
- FS.name_table[hash] = node;
- },
- hashRemoveNode: function(node) {
- var hash = FS.hashName(node.parent.id, node.name);
- if (FS.name_table[hash] === node) {
- FS.name_table[hash] = node.name_next;
- } else {
- var current = FS.name_table[hash];
- while (current) {
- if (current.name_next === node) {
- current.name_next = node.name_next;
- break;
- }
- current = current.name_next;
- }
- }
- },
- lookupNode: function(parent, name) {
- var err = FS.mayLookup(parent);
- if (err) {
- throw new FS.ErrnoError(err);
- }
- var hash = FS.hashName(parent.id, name);
- for (var node = FS.name_table[hash]; node; node = node.name_next) {
- if (node.parent.id === parent.id && node.name === name) {
- return node;
- }
- }
- // if we failed to find it in the cache, call into the VFS
- return VFS.lookup(parent, name);
- },
- createNode: function(parent, name, mode, rdev) {
- var node = {
- id: FS.nextInode++,
- name: name,
- mode: mode,
- node_ops: {},
- stream_ops: {},
- rdev: rdev,
- parent: null,
- mount: null
- };
- if (!parent) {
- parent = node; // root node sets parent to itself
- }
- node.parent = parent;
- node.mount = parent.mount;
- // compatibility
- var readMode = {{{ cDefine('S_IRUGO') }}} | {{{ cDefine('S_IXUGO') }}};
- var writeMode = {{{ cDefine('S_IWUGO') }}};
- // NOTE we must use Object.defineProperties instead of individual calls to
- // Object.defineProperty in order to make closure compiler happy
- Object.defineProperties(node, {
- read: {
- get: function() { return (node.mode & readMode) === readMode; },
- set: function(val) { val ? node.mode |= readMode : node.mode &= ~readMode; }
- },
- write: {
- get: function() { return (node.mode & writeMode) === writeMode; },
- set: function(val) { val ? node.mode |= writeMode : node.mode &= ~writeMode; }
- },
- isFolder: {
- get: function() { return FS.isDir(node.mode); },
- },
- isDevice: {
- get: function() { return FS.isChrdev(node.mode); },
- },
- });
- FS.hashAddNode(node);
- return node;
- },
- destroyNode: function(node) {
- FS.hashRemoveNode(node);
- },
- isRoot: function(node) {
- return node === node.parent;
- },
- isMountpoint: function(node) {
- return node.mounted;
- },
- isFile: function(mode) {
- return (mode & {{{ cDefine('S_IFMT') }}}) === {{{ cDefine('S_IFREG') }}};
- },
- isDir: function(mode) {
- return (mode & {{{ cDefine('S_IFMT') }}}) === {{{ cDefine('S_IFDIR') }}};
- },
- isLink: function(mode) {
- return (mode & {{{ cDefine('S_IFMT') }}}) === {{{ cDefine('S_IFLNK') }}};
- },
- isChrdev: function(mode) {
- return (mode & {{{ cDefine('S_IFMT') }}}) === {{{ cDefine('S_IFCHR') }}};
- },
- isBlkdev: function(mode) {
- return (mode & {{{ cDefine('S_IFMT') }}}) === {{{ cDefine('S_IFBLK') }}};
- },
- isFIFO: function(mode) {
- return (mode & {{{ cDefine('S_IFMT') }}}) === {{{ cDefine('S_IFIFO') }}};
- },
-
- //
- // paths
- //
- cwd: function() {
- return FS.currentPath;
- },
- lookupPath: function(path, opts) {
- path = PATH.resolve(FS.currentPath, path);
- opts = opts || { recurse_count: 0 };
-
- if (opts.recurse_count > 8) { // max recursive lookup of 8
- throw new FS.ErrnoError(ERRNO_CODES.ELOOP);
- }
-
- // split the path
- var parts = PATH.normalizeArray(path.split('/').filter(function(p) {
- return !!p;
- }), false);
-
- // start at the root
- var current = FS.root;
- var current_path = '/';
-
- for (var i = 0; i < parts.length; i++) {
- var islast = (i === parts.length-1);
- if (islast && opts.parent) {
- // stop resolving
- break;
- }
-
- current = FS.lookupNode(current, parts[i]);
- current_path = PATH.join(current_path, parts[i]);
-
- // jump to the mount's root node if this is a mountpoint
- if (FS.isMountpoint(current)) {
- current = current.mount.root;
- }
-
- // follow symlinks
- // by default, lookupPath will not follow a symlink if it is the final path component.
- // setting opts.follow = true will override this behavior.
- if (!islast || opts.follow) {
- var count = 0;
- while (FS.isLink(current.mode)) {
- var link = VFS.readlink(current_path);
- current_path = PATH.resolve(PATH.dirname(current_path), link);
-
- var lookup = FS.lookupPath(current_path, { recurse_count: opts.recurse_count });
- current = lookup.node;
-
- if (count++ > 40) { // limit max consecutive symlinks to 40 (SYMLOOP_MAX).
- throw new FS.ErrnoError(ERRNO_CODES.ELOOP);
- }
- }
- }
- }
-
- return { path: current_path, node: current };
- },
- getPath: function(node) {
- var path;
- while (true) {
- if (FS.isRoot(node)) {
- return path ? PATH.join(node.mount.mountpoint, path) : node.mount.mountpoint;
- }
- path = path ? PATH.join(node.name, path) : node.name;
- node = node.parent;
- }
- },
-
- //
- // permissions
- //
- flagModes: {
- '"r"': {{{ cDefine('O_RDONLY') }}},
- '"rs"': {{{ cDefine('O_RDONLY') }}} | {{{ cDefine('O_SYNC') }}},
- '"r+"': {{{ cDefine('O_RDWR') }}},
- '"w"': {{{ cDefine('O_TRUNC') }}} | {{{ cDefine('O_CREAT') }}} | {{{ cDefine('O_WRONLY') }}},
- '"wx"': {{{ cDefine('O_TRUNC') }}} | {{{ cDefine('O_CREAT') }}} | {{{ cDefine('O_WRONLY') }}} | {{{ cDefine('O_EXCL') }}},
- '"xw"': {{{ cDefine('O_TRUNC') }}} | {{{ cDefine('O_CREAT') }}} | {{{ cDefine('O_WRONLY') }}} | {{{ cDefine('O_EXCL') }}},
- '"w+"': {{{ cDefine('O_TRUNC') }}} | {{{ cDefine('O_CREAT') }}} | {{{ cDefine('O_RDWR') }}},
- '"wx+"': {{{ cDefine('O_TRUNC') }}} | {{{ cDefine('O_CREAT') }}} | {{{ cDefine('O_RDWR') }}} | {{{ cDefine('O_EXCL') }}},
- '"xw+"': {{{ cDefine('O_TRUNC') }}} | {{{ cDefine('O_CREAT') }}} | {{{ cDefine('O_RDWR') }}} | {{{ cDefine('O_EXCL') }}},
- '"a"': {{{ cDefine('O_APPEND') }}} | {{{ cDefine('O_CREAT') }}} | {{{ cDefine('O_WRONLY') }}},
- '"ax"': {{{ cDefine('O_APPEND') }}} | {{{ cDefine('O_CREAT') }}} | {{{ cDefine('O_WRONLY') }}} | {{{ cDefine('O_EXCL') }}},
- '"xa"': {{{ cDefine('O_APPEND') }}} | {{{ cDefine('O_CREAT') }}} | {{{ cDefine('O_WRONLY') }}} | {{{ cDefine('O_EXCL') }}},
- '"a+"': {{{ cDefine('O_APPEND') }}} | {{{ cDefine('O_CREAT') }}} | {{{ cDefine('O_RDWR') }}},
- '"ax+"': {{{ cDefine('O_APPEND') }}} | {{{ cDefine('O_CREAT') }}} | {{{ cDefine('O_RDWR') }}} | {{{ cDefine('O_EXCL') }}},
- '"xa+"': {{{ cDefine('O_APPEND') }}} | {{{ cDefine('O_CREAT') }}} | {{{ cDefine('O_RDWR') }}} | {{{ cDefine('O_EXCL') }}}
- },
- // convert the 'r', 'r+', etc. to it's corresponding set of O_* flags
- modeStringToFlags: function(str) {
- var flags = FS.flagModes[str];
- if (typeof flags === 'undefined') {
- throw new Error('Unknown file open mode: ' + str);
- }
- return flags;
- },
- // convert O_* bitmask to a string for nodePermissions
- flagsToPermissionString: function(flag) {
- var accmode = flag & {{{ cDefine('O_ACCMODE') }}};
- var perms = ['r', 'w', 'rw'][accmode];
- if ((flag & {{{ cDefine('O_TRUNC') }}})) {
- perms += 'w';
- }
- return perms;
- },
- nodePermissions: function(node, perms) {
- if (FS.ignorePermissions) {
- return 0;
- }
- // return 0 if any user, group or owner bits are set.
- if (perms.indexOf('r') !== -1 && !(node.mode & {{{ cDefine('S_IRUGO') }}})) {
- return ERRNO_CODES.EACCES;
- } else if (perms.indexOf('w') !== -1 && !(node.mode & {{{ cDefine('S_IWUGO') }}})) {
- return ERRNO_CODES.EACCES;
- } else if (perms.indexOf('x') !== -1 && !(node.mode & {{{ cDefine('S_IXUGO') }}})) {
- return ERRNO_CODES.EACCES;
- }
- return 0;
- },
- mayLookup: function(dir) {
- return FS.nodePermissions(dir, 'x');
- },
- mayMknod: function(mode) {
- switch (mode & {{{ cDefine('S_IFMT') }}}) {
- case {{{ cDefine('S_IFREG') }}}:
- case {{{ cDefine('S_IFCHR') }}}:
- case {{{ cDefine('S_IFBLK') }}}:
- case {{{ cDefine('S_IFIFO') }}}:
- case {{{ cDefine('S_IFSOCK') }}}:
- return 0;
- default:
- return ERRNO_CODES.EINVAL;
- }
- },
- mayCreate: function(dir, name) {
- try {
- var node = FS.lookupNode(dir, name);
- return ERRNO_CODES.EEXIST;
- } catch (e) {
- }
- return FS.nodePermissions(dir, 'wx');
- },
- mayDelete: function(dir, name, isdir) {
- var node;
- try {
- node = FS.lookupNode(dir, name);
- } catch (e) {
- return e.errno;
- }
- var err = FS.nodePermissions(dir, 'wx');
- if (err) {
- return err;
- }
- if (isdir) {
- if (!FS.isDir(node.mode)) {
- return ERRNO_CODES.ENOTDIR;
- }
- if (FS.isRoot(node) || FS.getPath(node) === FS.currentPath) {
- return ERRNO_CODES.EBUSY;
- }
- } else {
- if (FS.isDir(node.mode)) {
- return ERRNO_CODES.EISDIR;
- }
- }
- return 0;
- },
- mayOpen: function(node, flags) {
- if (!node) {
- return ERRNO_CODES.ENOENT;
- }
- if (FS.isLink(node.mode)) {
- return ERRNO_CODES.ELOOP;
- } else if (FS.isDir(node.mode)) {
- if ((flags & {{{ cDefine('O_ACCMODE') }}}) !== {{{ cDefine('O_RDONLY')}}} || // opening for write
- (flags & {{{ cDefine('O_TRUNC') }}})) {
- return ERRNO_CODES.EISDIR;
- }
- }
- return FS.nodePermissions(node, FS.flagsToPermissionString(flags));
- },
-
- //
- // devices
- //
- // each character device consists of a device id + stream operations.
- // when a character device node is created (e.g. /dev/stdin) it is
- // assigned a device id that lets us map back to the actual device.
- // by default, each character device stream (e.g. _stdin) uses chrdev_stream_ops.
- // however, once opened, the stream's operations are overridden with
- // the operations of the device its underlying node maps back to.
- chrdev_stream_ops: {
- open: function(stream) {
- var device = FS.getDevice(stream.node.rdev);
- // override node's stream ops with the device's
- stream.stream_ops = device.stream_ops;
- // forward the open call
- if (stream.stream_ops.open) {
- stream.stream_ops.open(stream);
- }
- },
- llseek: function() {
- throw new FS.ErrnoError(ERRNO_CODES.ESPIPE);
- }
- },
- major: function(dev) {
- return ((dev) >> 8);
- },
- minor: function(dev) {
- return ((dev) & 0xff);
- },
- makedev: function(ma, mi) {
- return ((ma) << 8 | (mi));
- },
- registerDevice: function(dev, ops) {
- FS.devices[dev] = { stream_ops: ops };
- },
- getDevice: function(dev) {
- return FS.devices[dev];
- },
-
- //
- // streams
- //
- MAX_OPEN_FDS: 4096,
- nextfd: function(fd_start, fd_end) {
- fd_start = fd_start || 1;
- fd_end = fd_end || FS.MAX_OPEN_FDS;
- for (var fd = fd_start; fd <= fd_end; fd++) {
- if (!FS.streams[fd]) {
- return fd;
- }
- }
- throw new FS.ErrnoError(ERRNO_CODES.EMFILE);
- },
- getStream: function(fd) {
- return FS.streams[fd];
- },
- createStream: function(stream, fd_start, fd_end) {
- var fd = FS.nextfd(fd_start, fd_end);
- stream.fd = fd;
- // compatibility
- Object.defineProperties(stream, {
- object: {
- get: function() { return stream.node; },
- set: function(val) { stream.node = val; }
- },
- isRead: {
- get: function() { return (stream.flags & {{{ cDefine('O_ACCMODE') }}}) !== {{{ cDefine('O_WRONLY') }}}; }
- },
- isWrite: {
- get: function() { return (stream.flags & {{{ cDefine('O_ACCMODE') }}}) !== {{{ cDefine('O_RDONLY') }}}; }
- },
- isAppend: {
- get: function() { return (stream.flags & {{{ cDefine('O_APPEND') }}}); }
- }
- });
- FS.streams[fd] = stream;
- return stream;
- },
- closeStream: function(fd) {
- FS.streams[fd] = null;
- },
-
- //
- // general
- //
- createDefaultDirectories: function() {
- VFS.mkdir('/tmp', 0777);
- },
- createDefaultDevices: function() {
- // create /dev
- VFS.mkdir('/dev', 0777);
- // setup /dev/null
- FS.registerDevice(FS.makedev(1, 3), {
- read: function() { return 0; },
- write: function() { return 0; }
- });
- VFS.mkdev('/dev/null', 0666, FS.makedev(1, 3));
- // setup /dev/tty and /dev/tty1
- // stderr needs to print output using Module['printErr']
- // so we register a second tty just for it.
- TTY.register(FS.makedev(5, 0), TTY.default_tty_ops);
- TTY.register(FS.makedev(6, 0), TTY.default_tty1_ops);
- VFS.mkdev('/dev/tty', 0666, FS.makedev(5, 0));
- VFS.mkdev('/dev/tty1', 0666, FS.makedev(6, 0));
- // we're not going to emulate the actual shm device,
- // just create the tmp dirs that reside in it commonly
- VFS.mkdir('/dev/shm', 0777);
- VFS.mkdir('/dev/shm/tmp', 0777);
- },
- createStandardStreams: function() {
- // TODO deprecate the old functionality of a single
- // input / output callback and that utilizes FS.createDevice
- // and instead require a unique set of stream ops
-
- // by default, we symlink the standard streams to the
- // default tty devices. however, if the standard streams
- // have been overwritten we create a unique device for
- // them instead.
- if (Module['stdin']) {
- FS.createDevice('/dev', 'stdin', Module['stdin']);
- } else {
- VFS.symlink('/dev/tty', '/dev/stdin');
- }
- if (Module['stdout']) {
- FS.createDevice('/dev', 'stdout', null, Module['stdout']);
- } else {
- VFS.symlink('/dev/tty', '/dev/stdout');
- }
- if (Module['stderr']) {
- FS.createDevice('/dev', 'stderr', null, Module['stderr']);
- } else {
- VFS.symlink('/dev/tty1', '/dev/stderr');
- }
-
- // open default streams for the stdin, stdout and stderr devices
- var stdin = VFS.open('/dev/stdin', 'r');
- {{{ makeSetValue(makeGlobalUse('_stdin'), 0, 'stdin.fd', 'void*') }}};
- assert(stdin.fd === 1, 'invalid handle for stdin (' + stdin.fd + ')');
-
- var stdout = VFS.open('/dev/stdout', 'w');
- {{{ makeSetValue(makeGlobalUse('_stdout'), 0, 'stdout.fd', 'void*') }}};
- assert(stdout.fd === 2, 'invalid handle for stdout (' + stdout.fd + ')');
-
- var stderr = VFS.open('/dev/stderr', 'w');
- {{{ makeSetValue(makeGlobalUse('_stderr'), 0, 'stderr.fd', 'void*') }}};
- assert(stderr.fd === 3, 'invalid handle for stderr (' + stderr.fd + ')');
- },
- staticInit: function() {
- FS.root = FS.createNode(null, '/', {{{ cDefine('S_IFDIR') }}} | 0777, 0);
- VFS.mount(MEMFS, {}, '/');
-
- FS.createDefaultDirectories();
- FS.createDefaultDevices();
- },
- init: function(input, output, error) {
- assert(!FS.init.initialized, 'FS.init was previously called. If you want to initialize later with custom parameters, remove any earlier calls (note that one is automatically added to the generated code)');
- FS.init.initialized = true;
-
- // Allow Module.stdin etc. to provide defaults, if none explicitly passed to us here
- Module['stdin'] = input || Module['stdin'];
- Module['stdout'] = output || Module['stdout'];
- Module['stderr'] = error || Module['stderr'];
-
- FS.createStandardStreams();
- },
- quit: function() {
- FS.init.initialized = false;
- for (var i = 0; i < FS.streams.length; i++) {
- var stream = FS.streams[i];
- if (!stream) {
- continue;
- }
- VFS.close(stream);
- }
- },
-
- //
- // compatibility
- //
- getMode: function(canRead, canWrite) {
- var mode = 0;
- if (canRead) mode |= {{{ cDefine('S_IRUGO') }}} | {{{ cDefine('S_IXUGO') }}};
- if (canWrite) mode |= {{{ cDefine('S_IWUGO') }}};
- return mode;
- },
- joinPath: function(parts, forceRelative) {
- var path = PATH.join.apply(null, parts);
- if (forceRelative && path[0] == '/') path = path.substr(1);
- return path;
- },
- absolutePath: function(relative, base) {
- return PATH.resolve(base, relative);
- },
- standardizePath: function(path) {
- return PATH.normalize(path);
- },
- findObject: function(path, dontResolveLastLink) {
- var ret = FS.analyzePath(path, dontResolveLastLink);
- if (ret.exists) {
- return ret.object;
- } else {
- ___setErrNo(ret.error);
- return null;
- }
- },
- analyzePath: function(path, dontResolveLastLink) {
- // operate from within the context of the symlink's target
- try {
- var lookup = FS.lookupPath(path, { follow: !dontResolveLastLink });
- path = lookup.path;
- } catch (e) {
- }
- var ret = {
- isRoot: false, exists: false, error: 0, name: null, path: null, object: null,
- parentExists: false, parentPath: null, parentObject: null
- };
- try {
- var lookup = FS.lookupPath(path, { parent: true });
- ret.parentExists = true;
- ret.parentPath = lookup.path;
- ret.parentObject = lookup.node;
- ret.name = PATH.basename(path);
- lookup = FS.lookupPath(path, { follow: !dontResolveLastLink });
- ret.exists = true;
- ret.path = lookup.path;
- ret.object = lookup.node;
- ret.name = look