diff options
-rwxr-xr-x | emcc | 5 | ||||
-rw-r--r-- | src/library.js | 401 | ||||
-rw-r--r-- | src/library_openal.js | 14 | ||||
-rw-r--r-- | src/library_path.js | 17 | ||||
-rw-r--r-- | src/library_sdl.js | 4 | ||||
-rw-r--r-- | src/preamble.js | 9 | ||||
-rw-r--r-- | src/shell.js | 53 | ||||
-rw-r--r-- | system/lib/libc/musl/src/stdlib/ecvt.c | 19 | ||||
-rw-r--r-- | system/lib/libc/musl/src/stdlib/fcvt.c | 25 | ||||
-rw-r--r-- | system/lib/libc/musl/src/stdlib/gcvt.c | 8 | ||||
-rw-r--r-- | system/lib/libcextra.symbols | 3 | ||||
-rwxr-xr-x | tests/runner.py | 97 | ||||
-rw-r--r-- | tools/asm_module.py | 2 | ||||
-rw-r--r-- | tools/js-optimizer.js | 9 |
14 files changed, 390 insertions, 276 deletions
@@ -1285,6 +1285,11 @@ try: 'wctob.c', 'wctomb.c', ]], + ['stdlib', [ + 'ecvt.c', + 'fcvt.c', + 'gcvt.c', + ]], ['string', [ 'wcpcpy.c', 'wcpncpy.c', diff --git a/src/library.js b/src/library.js index bd376f20..a499ccd0 100644 --- a/src/library.js +++ b/src/library.js @@ -56,38 +56,38 @@ LibraryManager.library = { // to modify the filesystem freely before run() is called. ignorePermissions: true, - ErrnoError: function (errno) { - function ErrnoError(errno) { - this.errno = errno; - for (var key in ERRNO_CODES) { - if (ERRNO_CODES[key] === errno) { - this.code = key; - break; - } + 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]; - }; - ErrnoError.prototype = Object.create(Error.prototype); - ErrnoError.prototype.contructor = ErrnoError; - return new ErrnoError(errno); + } + 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) { + 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) { + 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) { + 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; @@ -102,7 +102,7 @@ LibraryManager.library = { } } }, - lookupNode: function (parent, name) { + lookupNode: function(parent, name) { var err = FS.mayLookup(parent); if (err) { throw new FS.ErrnoError(err); @@ -116,7 +116,7 @@ LibraryManager.library = { // if we failed to find it in the cache, call into the VFS return VFS.lookup(parent, name); }, - createNode: function (parent, name, mode, rdev) { + createNode: function(parent, name, mode, rdev) { var node = { id: FS.nextInode++, name: name, @@ -136,12 +136,12 @@ LibraryManager.library = { var readMode = {{{ cDefine('S_IRUGO') }}} | {{{ cDefine('S_IXUGO') }}}; var writeMode = {{{ cDefine('S_IWUGO') }}}; Object.defineProperty(node, 'read', { - get: function () { return (node.mode & readMode) === readMode; }, - set: function (val) { val ? node.mode |= readMode : node.mode &= ~readMode; } + get: function() { return (node.mode & readMode) === readMode; }, + set: function(val) { val ? node.mode |= readMode : node.mode &= ~readMode; } }); Object.defineProperty(node, 'write', { - get: function () { return (node.mode & writeMode) === writeMode; }, - set: function (val) { val ? node.mode |= writeMode : node.mode &= ~writeMode; } + get: function() { return (node.mode & writeMode) === writeMode; }, + set: function(val) { val ? node.mode |= writeMode : node.mode &= ~writeMode; } }); // TODO add: // isFolder @@ -149,38 +149,41 @@ LibraryManager.library = { FS.hashAddNode(node); return node; }, - destroyNode: function (node) { + destroyNode: function(node) { FS.hashRemoveNode(node); }, - isRoot: function (node) { + isRoot: function(node) { return node === node.parent; }, - isMountpoint: function (node) { + isMountpoint: function(node) { return node.mounted; }, - isFile: function (mode) { + isFile: function(mode) { return (mode & {{{ cDefine('S_IFMT') }}}) === {{{ cDefine('S_IFREG') }}}; }, - isDir: function (mode) { + isDir: function(mode) { return (mode & {{{ cDefine('S_IFMT') }}}) === {{{ cDefine('S_IFDIR') }}}; }, - isLink: function (mode) { + isLink: function(mode) { return (mode & {{{ cDefine('S_IFMT') }}}) === {{{ cDefine('S_IFLNK') }}}; }, - isChrdev: function (mode) { + isChrdev: function(mode) { return (mode & {{{ cDefine('S_IFMT') }}}) === {{{ cDefine('S_IFCHR') }}}; }, - isBlkdev: function (mode) { + isBlkdev: function(mode) { return (mode & {{{ cDefine('S_IFMT') }}}) === {{{ cDefine('S_IFBLK') }}}; }, - isFIFO: function (mode) { + isFIFO: function(mode) { return (mode & {{{ cDefine('S_IFMT') }}}) === {{{ cDefine('S_IFIFO') }}}; }, // // paths // - lookupPath: function (path, opts) { + cwd: function() { + return FS.currentPath; + }, + lookupPath: function(path, opts) { path = PATH.resolve(FS.currentPath, path); opts = opts || { recurse_count: 0 }; @@ -189,7 +192,7 @@ LibraryManager.library = { } // split the path - var parts = PATH.normalizeArray(path.split('/').filter(function (p) { + var parts = PATH.normalizeArray(path.split('/').filter(function(p) { return !!p; }), false); @@ -233,7 +236,7 @@ LibraryManager.library = { return { path: current_path, node: current }; }, - getPath: function (node) { + getPath: function(node) { var path; while (true) { if (FS.isRoot(node)) { @@ -265,7 +268,7 @@ LibraryManager.library = { '"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) { + modeStringToFlags: function(str) { var flags = FS.flagModes[str]; if (typeof flags === 'undefined') { throw new Error('Unknown file open mode: ' + str); @@ -273,7 +276,7 @@ LibraryManager.library = { return flags; }, // convert O_* bitmask to a string for nodePermissions - flagsToPermissionString: function (flag) { + flagsToPermissionString: function(flag) { var accmode = flag & {{{ cDefine('O_ACCMODE') }}}; var perms = ['r', 'w', 'rw'][accmode]; if ((flag & {{{ cDefine('O_TRUNC') }}})) { @@ -281,7 +284,7 @@ LibraryManager.library = { } return perms; }, - nodePermissions: function (node, perms) { + nodePermissions: function(node, perms) { if (FS.ignorePermissions) { return 0; } @@ -295,10 +298,10 @@ LibraryManager.library = { } return 0; }, - mayLookup: function (dir) { + mayLookup: function(dir) { return FS.nodePermissions(dir, 'x'); }, - mayMknod: function (mode) { + mayMknod: function(mode) { switch (mode & {{{ cDefine('S_IFMT') }}}) { case {{{ cDefine('S_IFREG') }}}: case {{{ cDefine('S_IFCHR') }}}: @@ -310,7 +313,7 @@ LibraryManager.library = { return ERRNO_CODES.EINVAL; } }, - mayCreate: function (dir, name) { + mayCreate: function(dir, name) { try { var node = FS.lookupNode(dir, name); return ERRNO_CODES.EEXIST; @@ -318,7 +321,7 @@ LibraryManager.library = { } return FS.nodePermissions(dir, 'wx'); }, - mayDelete: function (dir, name, isdir) { + mayDelete: function(dir, name, isdir) { var node; try { node = FS.lookupNode(dir, name); @@ -343,7 +346,7 @@ LibraryManager.library = { } return 0; }, - mayOpen: function (node, flags) { + mayOpen: function(node, flags) { if (!node) { return ERRNO_CODES.ENOENT; } @@ -368,7 +371,7 @@ LibraryManager.library = { // 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) { + 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; @@ -377,23 +380,23 @@ LibraryManager.library = { stream.stream_ops.open(stream); } }, - llseek: function () { + llseek: function() { throw new FS.ErrnoError(ERRNO_CODES.ESPIPE); } }, - major: function (dev) { + major: function(dev) { return ((dev) >> 8); }, - minor: function (dev) { + minor: function(dev) { return ((dev) & 0xff); }, - makedev: function (ma, mi) { + makedev: function(ma, mi) { return ((ma) << 8 | (mi)); }, - registerDevice: function (dev, ops) { + registerDevice: function(dev, ops) { FS.devices[dev] = { stream_ops: ops }; }, - getDevice: function (dev) { + getDevice: function(dev) { return FS.devices[dev]; }, @@ -401,7 +404,7 @@ LibraryManager.library = { // streams // MAX_OPEN_FDS: 4096, - nextfd: function (fd_start, fd_end) { + 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++) { @@ -411,46 +414,46 @@ LibraryManager.library = { } throw new FS.ErrnoError(ERRNO_CODES.EMFILE); }, - getStream: function (fd) { + getStream: function(fd) { return FS.streams[fd]; }, - createStream: function (stream, fd_start, fd_end) { + createStream: function(stream, fd_start, fd_end) { var fd = FS.nextfd(fd_start, fd_end); stream.fd = fd; // compatibility Object.defineProperty(stream, 'object', { - get: function () { return stream.node; }, - set: function (val) { stream.node = val; } + get: function() { return stream.node; }, + set: function(val) { stream.node = val; } }); Object.defineProperty(stream, 'isRead', { - get: function () { return (stream.flags & {{{ cDefine('O_ACCMODE') }}}) !== {{{ cDefine('O_WRONLY') }}}; } + get: function() { return (stream.flags & {{{ cDefine('O_ACCMODE') }}}) !== {{{ cDefine('O_WRONLY') }}}; } }); Object.defineProperty(stream, 'isWrite', { - get: function () { return (stream.flags & {{{ cDefine('O_ACCMODE') }}}) !== {{{ cDefine('O_RDONLY') }}}; } + get: function() { return (stream.flags & {{{ cDefine('O_ACCMODE') }}}) !== {{{ cDefine('O_RDONLY') }}}; } }); Object.defineProperty(stream, 'isAppend', { - get: function () { return (stream.flags & {{{ cDefine('O_APPEND') }}}); } + get: function() { return (stream.flags & {{{ cDefine('O_APPEND') }}}); } }); FS.streams[fd] = stream; return stream; }, - closeStream: function (fd) { + closeStream: function(fd) { FS.streams[fd] = null; }, // // general // - createDefaultDirectories: function () { + createDefaultDirectories: function() { VFS.mkdir('/tmp', 0777); }, - createDefaultDevices: function () { + 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; } + read: function() { return 0; }, + write: function() { return 0; } }); VFS.mkdev('/dev/null', 0666, FS.makedev(1, 3)); // setup /dev/tty and /dev/tty1 @@ -465,7 +468,7 @@ LibraryManager.library = { VFS.mkdir('/dev/shm', 0777); VFS.mkdir('/dev/shm/tmp', 0777); }, - createStandardStreams: function () { + 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 @@ -503,14 +506,14 @@ LibraryManager.library = { {{{ makeSetValue(makeGlobalUse('_stderr'), 0, 'stderr.fd', 'void*') }}}; assert(stderr.fd === 3, 'invalid handle for stderr (' + stderr.fd + ')'); }, - staticInit: function () { + staticInit: function() { FS.root = FS.createNode(null, '/', {{{ cDefine('S_IFDIR') }}} | 0777, 0); VFS.mount(MEMFS, {}, '/'); FS.createDefaultDirectories(); FS.createDefaultDevices(); }, - init: function (input, output, error) { + 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; @@ -521,7 +524,7 @@ LibraryManager.library = { FS.createStandardStreams(); }, - quit: function () { + quit: function() { FS.init.initialized = false; for (var i = 0; i < FS.streams.length; i++) { var stream = FS.streams[i]; @@ -535,24 +538,24 @@ LibraryManager.library = { // // compatibility // - getMode: function (canRead, canWrite) { + 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) { + 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) { + absolutePath: function(relative, base) { return PATH.resolve(base, relative); }, - standardizePath: function (path) { + standardizePath: function(path) { return PATH.normalize(path); }, - findObject: function (path, dontResolveLastLink) { + findObject: function(path, dontResolveLastLink) { var ret = FS.analyzePath(path, dontResolveLastLink); if (ret.exists) { return ret.object; @@ -561,7 +564,7 @@ LibraryManager.library = { return null; } }, - analyzePath: function (path, dontResolveLastLink) { + analyzePath: function(path, dontResolveLastLink) { // operate from within the context of the symlink's target try { var lookup = FS.lookupPath(path, { follow: !dontResolveLastLink }); @@ -589,12 +592,12 @@ LibraryManager.library = { }; return ret; }, - createFolder: function (parent, name, canRead, canWrite) { + createFolder: function(parent, name, canRead, canWrite) { var path = PATH.join(typeof parent === 'string' ? parent : FS.getPath(parent), name); var mode = FS.getMode(canRead, canWrite); return VFS.mkdir(path, mode); }, - createPath: function (parent, path, canRead, canWrite) { + createPath: function(parent, path, canRead, canWrite) { parent = typeof parent === 'string' ? parent : FS.getPath(parent); var parts = path.split('/').reverse(); while (parts.length) { @@ -610,12 +613,12 @@ LibraryManager.library = { } return current; }, - createFile: function (parent, name, properties, canRead, canWrite) { + createFile: function(parent, name, properties, canRead, canWrite) { var path = PATH.join(typeof parent === 'string' ? parent : FS.getPath(parent), name); var mode = FS.getMode(canRead, canWrite); return VFS.create(path, mode); }, - createDataFile: function (parent, name, data, canRead, canWrite) { + createDataFile: function(parent, name, data, canRead, canWrite) { var path = PATH.join(typeof parent === 'string' ? parent : FS.getPath(parent), name); var mode = FS.getMode(canRead, canWrite); var node = VFS.create(path, mode); @@ -634,7 +637,7 @@ LibraryManager.library = { } return node; }, - createDevice: function (parent, name, input, output) { + createDevice: function(parent, name, input, output) { var path = PATH.join(typeof parent === 'string' ? parent : FS.getPath(parent), name); var mode = input && output ? 0777 : (input ? 0333 : 0555); if (!FS.createDevice.major) FS.createDevice.major = 64; @@ -642,16 +645,16 @@ LibraryManager.library = { // Create a fake device that a set of stream ops to emulate // the old behavior. FS.registerDevice(dev, { - open: function (stream) { + open: function(stream) { stream.seekable = false; }, - close: function (stream) { + close: function(stream) { // flush any pending line data - if (output.buffer && output.buffer.length) { + if (output && output.buffer && output.buffer.length) { output({{{ charCode('\n') }}}); } }, - read: function (stream, buffer, offset, length, pos /* ignored */) { + read: function(stream, buffer, offset, length, pos /* ignored */) { var bytesRead = 0; for (var i = 0; i < length; i++) { var result; @@ -672,7 +675,7 @@ LibraryManager.library = { } return bytesRead; }, - write: function (stream, buffer, offset, length, pos) { + write: function(stream, buffer, offset, length, pos) { for (var i = 0; i < length; i++) { try { output(buffer[offset+i]); @@ -688,7 +691,7 @@ LibraryManager.library = { }); return VFS.mkdev(path, mode, dev); }, - createLink: function (parent, name, target, canRead, canWrite) { + createLink: function(parent, name, target, canRead, canWrite) { var path = PATH.join(typeof parent === 'string' ? parent : FS.getPath(parent), name); return VFS.symlink(target, path); }, @@ -830,9 +833,9 @@ LibraryManager.library = { // override each stream op with one that tries to force load the lazy file first var stream_ops = {}; var keys = Object.keys(node.stream_ops); - keys.forEach(function (key) { + keys.forEach(function(key) { var fn = node.stream_ops[key]; - stream_ops[key] = function () { + stream_ops[key] = function() { if (!FS.forceLoadFile(node)) { throw new FS.ErrnoError(ERRNO_CODES.EIO); } @@ -840,7 +843,7 @@ LibraryManager.library = { }; }); // use a custom read function - stream_ops.read = function (stream, buffer, offset, length, position) { + stream_ops.read = function(stream, buffer, offset, length, position) { var contents = stream.node.contents; var size = Math.min(contents.length - position, length); if (contents.slice) { // normal array @@ -871,7 +874,7 @@ LibraryManager.library = { // result of an XHR that you did manually. createPreloadedFile: function(parent, name, url, canRead, canWrite, onload, onerror, dontCreateFile) { Browser.init(); - var fullname = PATH.join(parent, name).substr(1); + var fullname = FS.joinPath([parent, name], true); function processData(byteArray) { function finish(byteArray) { if (!dontCreateFile) { @@ -906,7 +909,7 @@ LibraryManager.library = { $VFS__deps: ['$FS'], $VFS: { - mount: function (type, opts, mountpoint) { + mount: function(type, opts, mountpoint) { var mount = { type: type, opts: opts, @@ -932,11 +935,11 @@ LibraryManager.library = { } return root; }, - lookup: function (parent, name) { + lookup: function(parent, name) { return parent.node_ops.lookup(parent, name); }, // generic function for all node creation - mknod: function (path, mode, dev) { + mknod: function(path, mode, dev) { var lookup = FS.lookupPath(path, { parent: true }); var parent = lookup.node; var name = PATH.basename(path); @@ -950,21 +953,21 @@ LibraryManager.library = { return parent.node_ops.mknod(parent, name, mode, dev); }, // helpers to create specific types of nodes - create: function (path, mode) { + create: function(path, mode) { mode &= {{{ cDefine('S_IALLUGO') }}}; mode |= {{{ cDefine('S_IFREG') }}}; return VFS.mknod(path, mode, 0); }, - mkdir: function (path, mode) { + mkdir: function(path, mode) { mode &= {{{ cDefine('S_IRWXUGO') }}} | {{{ cDefine('S_ISVTX') }}}; mode |= {{{ cDefine('S_IFDIR') }}}; return VFS.mknod(path, mode, 0); }, - mkdev: function (path, mode, dev) { + mkdev: function(path, mode, dev) { mode |= {{{ cDefine('S_IFCHR') }}}; return VFS.mknod(path, mode, dev); }, - symlink: function (oldpath, newpath) { + symlink: function(oldpath, newpath) { var lookup = FS.lookupPath(newpath, { parent: true }); var parent = lookup.node; var newname = PATH.basename(newpath); @@ -977,7 +980,7 @@ LibraryManager.library = { } return parent.node_ops.symlink(parent, newname, oldpath); }, - rename: function (old_path, new_path) { + rename: function(old_path, new_path) { var old_dirname = PATH.dirname(old_path); var new_dirname = PATH.dirname(new_path); var old_name = PATH.basename(old_path); @@ -1059,7 +1062,7 @@ LibraryManager.library = { FS.hashAddNode(old_node); } }, - rmdir: function (path) { + rmdir: function(path) { var lookup = FS.lookupPath(path, { parent: true }); var parent = lookup.node; var name = PATH.basename(path); @@ -1077,7 +1080,7 @@ LibraryManager.library = { parent.node_ops.rmdir(parent, name); FS.destroyNode(node); }, - unlink: function (path) { + unlink: function(path) { var lookup = FS.lookupPath(path, { parent: true }); var parent = lookup.node; var name = PATH.basename(path); @@ -1097,7 +1100,7 @@ LibraryManager.library = { parent.node_ops.unlink(parent, name); FS.destroyNode(node); }, - readlink: function (path) { + readlink: function(path) { var lookup = FS.lookupPath(path, { follow: false }); var link = lookup.node; if (!link.node_ops.readlink) { @@ -1105,7 +1108,7 @@ LibraryManager.library = { } return link.node_ops.readlink(link); }, - stat: function (path, dontFollow) { + stat: function(path, dontFollow) { var lookup = FS.lookupPath(path, { follow: !dontFollow }); var node = lookup.node; if (!node.node_ops.getattr) { @@ -1113,10 +1116,10 @@ LibraryManager.library = { } return node.node_ops.getattr(node); }, - lstat: function (path) { + lstat: function(path) { return VFS.stat(path, true); }, - chmod: function (path, mode, dontFollow) { + chmod: function(path, mode, dontFollow) { var node; if (typeof path === 'string') { var lookup = FS.lookupPath(path, { follow: !dontFollow }); @@ -1132,17 +1135,17 @@ LibraryManager.library = { timestamp: Date.now() }); }, - lchmod: function (path, mode) { + lchmod: function(path, mode) { VFS.chmod(path, mode, true); }, - fchmod: function (fd, mode) { + fchmod: function(fd, mode) { var stream = FS.getStream(fd); if (!stream) { throw new FS.ErrnoError(ERRNO_CODES.EBADF); } VFS.chmod(stream.node, mode); }, - chown: function (path, uid, gid, dontFollow) { + chown: function(path, uid, gid, dontFollow) { var node; if (typeof path === 'string') { var lookup = FS.lookupPath(path, { follow: !dontFollow }); @@ -1158,17 +1161,17 @@ LibraryManager.library = { // we ignore the uid / gid for now }); }, - lchown: function (path, uid, gid) { + lchown: function(path, uid, gid) { VFS.chown(path, uid, gid, true); }, - fchown: function (fd, uid, gid) { + fchown: function(fd, uid, gid) { var stream = FS.getStream(fd); if (!stream) { throw new FS.ErrnoError(ERRNO_CODES.EBADF); } VFS.chown(stream.node, uid, gid); }, - truncate: function (path, len) { + truncate: function(path, len) { if (len < 0) { throw new FS.ErrnoError(ERRNO_CODES.EINVAL); } @@ -1197,7 +1200,7 @@ LibraryManager.library = { timestamp: Date.now() }); }, - ftruncate: function (fd, len) { + ftruncate: function(fd, len) { var stream = FS.getStream(fd); if (!stream) { throw new FS.ErrnoError(ERRNO_CODES.EBADF); @@ -1207,14 +1210,14 @@ LibraryManager.library = { } VFS.truncate(stream.node, len); }, - utime: function (path, atime, mtime) { + utime: function(path, atime, mtime) { var lookup = FS.lookupPath(path, { follow: true }); var node = lookup.node; node.node_ops.setattr(node, { timestamp: Math.max(atime, mtime) }); }, - open: function (path, flags, mode, fd_start, fd_end) { + open: function(path, flags, mode, fd_start, fd_end) { path = PATH.normalize(path); flags = typeof flags === 'string' ? FS.modeStringToFlags(flags) : flags; if ((flags & {{{ cDefine('O_CREAT') }}})) { @@ -1278,7 +1281,7 @@ LibraryManager.library = { } return stream; }, - close: function (stream) { + close: function(stream) { try { if (stream.stream_ops.close) { stream.stream_ops.close(stream); @@ -1289,19 +1292,19 @@ LibraryManager.library = { FS.closeStream(stream.fd); } }, - llseek: function (stream, offset, whence) { + llseek: function(stream, offset, whence) { if (!stream.seekable || !stream.stream_ops.llseek) { throw new FS.ErrnoError(ERRNO_CODES.ESPIPE); } return stream.stream_ops.llseek(stream, offset, whence); }, - readdir: function (stream) { + 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) { + read: function(stream, buffer, offset, length, position) { if (length < 0 || position < 0) { throw new FS.ErrnoError(ERRNO_CODES.EINVAL); } @@ -1325,7 +1328,7 @@ LibraryManager.library = { if (!seeking) stream.position += bytesRead; return bytesRead; }, - write: function (stream, buffer, offset, length, position) { + write: function(stream, buffer, offset, length, position) { if (length < 0 || position < 0) { throw new FS.ErrnoError(ERRNO_CODES.EINVAL); } @@ -1353,7 +1356,7 @@ LibraryManager.library = { if (!seeking) stream.position += bytesWritten; return bytesWritten; }, - allocate: function (stream, offset, length) { + allocate: function(stream, offset, length) { if (offset < 0 || length <= 0) { throw new FS.ErrnoError(ERRNO_CODES.EINVAL); } @@ -1368,7 +1371,7 @@ LibraryManager.library = { } stream.stream_ops.allocate(stream, offset, length); }, - mmap: function (stream, buffer, offset, length, position, prot, flags) { + mmap: function(stream, buffer, offset, length, position, prot, flags) { // TODO if PROT is PROT_WRITE, make sure we have write acccess if ((stream.flags & {{{ cDefine('O_ACCMODE') }}}) === {{{ cDefine('O_WRONLY')}}}) { throw new FS.ErrnoError(ERRNO_CODES.EACCES); @@ -1382,10 +1385,10 @@ LibraryManager.library = { $MEMFS__deps: ['$FS'], $MEMFS: { - mount: function (mount) { + mount: function(mount) { return MEMFS.create_node(null, '/', {{{ cDefine('S_IFDIR') }}} | 0777, 0); }, - create_node: function (parent, name, mode, dev) { + create_node: function(parent, name, mode, dev) { if (FS.isBlkdev(mode) || FS.isFIFO(mode)) { // no supported throw new FS.ErrnoError(ERRNO_CODES.EPERM); @@ -1411,7 +1414,7 @@ LibraryManager.library = { return node; }, node_ops: { - getattr: function (node) { + getattr: function(node) { var attr = {}; // device numbers reuse inode numbers. attr.dev = FS.isChrdev(node.mode) ? node.id : 1; @@ -1439,7 +1442,7 @@ LibraryManager.library = { attr.blocks = Math.ceil(attr.size / attr.blksize); return attr; }, - setattr: function (node, attr) { + setattr: function(node, attr) { if (attr.mode !== undefined) { node.mode = attr.mode; } @@ -1452,13 +1455,13 @@ LibraryManager.library = { else while (attr.size > contents.length) contents.push(0); } }, - lookup: function (parent, name) { + lookup: function(parent, name) { throw new FS.ErrnoError(ERRNO_CODES.ENOENT); }, - mknod: function (parent, name, mode, dev) { + mknod: function(parent, name, mode, dev) { return MEMFS.create_node(parent, name, mode, dev); }, - rename: function (old_node, new_dir, new_name) { + rename: function(old_node, new_dir, new_name) { // if we're overwriting a directory at new_name, make sure it's empty. if (FS.isDir(old_node.mode)) { var new_node; @@ -1477,22 +1480,22 @@ LibraryManager.library = { old_node.name = new_name; new_dir.contents[new_name] = old_node; }, - unlink: function (parent, name) { + unlink: function(parent, name) { delete parent.contents[name]; }, - rmdir: function (parent, name) { + rmdir: function(parent, name) { var node = FS.lookupNode(parent, name); for (var i in node.contents) { throw new FS.ErrnoError(ERRNO_CODES.ENOTEMPTY); } delete parent.contents[name]; }, - symlink: function (parent, newname, oldpath) { + symlink: function(parent, newname, oldpath) { var node = MEMFS.create_node(parent, newname, 0777 | {{{ cDefine('S_IFLNK') }}}, 0); node.link = oldpath; return node; }, - readlink: function (node) { + readlink: function(node) { if (!FS.isLink(node.mode)) { throw new FS.ErrnoError(ERRNO_CODES.EINVAL); } @@ -1500,7 +1503,7 @@ LibraryManager.library = { }, }, stream_ops: { - open: function (stream) { + open: function(stream) { if (FS.isDir(stream.node.mode)) { // cache off the directory entries when open'd var entries = ['.', '..'] @@ -1513,7 +1516,7 @@ LibraryManager.library = { stream.entries = entries; } }, - read: function (stream, buffer, offset, length, position) { + read: function(stream, buffer, offset, length, position) { var contents = stream.node.contents; var size = Math.min(contents.length - position, length); #if USE_TYPED_ARRAYS == 2 @@ -1528,7 +1531,7 @@ LibraryManager.library = { } return size; }, - write: function (stream, buffer, offset, length, position) { + write: function(stream, buffer, offset, length, position) { var contents = stream.node.contents; while (contents.length < position) contents.push(0); for (var i = 0; i < length; i++) { @@ -1537,7 +1540,7 @@ LibraryManager.library = { stream.node.timestamp = Date.now(); return length; }, - llseek: function (stream, offset, whence) { + llseek: function(stream, offset, whence) { var position = offset; if (whence === 1) { // SEEK_CUR. position += stream.position; @@ -1553,15 +1556,15 @@ LibraryManager.library = { stream.position = position; return position; }, - readdir: function (stream) { + readdir: function(stream) { return stream.entries; }, - allocate: function (stream, offset, length) { + allocate: function(stream, offset, length) { var contents = stream.node.contents; var limit = offset + length; while (limit > contents.length) contents.push(0); }, - mmap: function (stream, buffer, offset, length, position, prot, flags) { + mmap: function(stream, buffer, offset, length, position, prot, flags) { if (!FS.isFile(stream.node.mode)) { throw new FS.ErrnoError(ERRNO_CODES.ENODEV); } @@ -1599,7 +1602,7 @@ LibraryManager.library = { $SOCKFS__postset: '__ATINIT__.push({ func: function() { SOCKFS.root = VFS.mount(SOCKFS, {}, null); } });', $SOCKFS__deps: ['$FS'], $SOCKFS: { - mount: function (mount) { + mount: function(mount) { var node = FS.createNode(null, '/', {{{ cDefine('S_IFDIR') }}} | 0777, 0); node.node_ops = SOCKFS.node_ops; node.stream_ops = SOCKFS.stream_ops; @@ -1616,12 +1619,12 @@ LibraryManager.library = { $TTY__deps: ['$FS'], $TTY: { ttys: [], - register: function (dev, ops) { + register: function(dev, ops) { TTY.ttys[dev] = { input: [], output: [], ops: ops }; FS.registerDevice(dev, TTY.stream_ops); }, stream_ops: { - open: function (stream) { + open: function(stream) { // this wouldn't be required if the library wasn't eval'd at first... if (!TTY.utf8) { TTY.utf8 = new Runtime.UTF8Processor(); @@ -1633,13 +1636,13 @@ LibraryManager.library = { stream.tty = tty; stream.seekable = false; }, - close: function (stream) { + close: function(stream) { // flush any pending line data if (stream.tty.output.length) { stream.tty.ops.put_char(stream.tty, {{{ charCode('\n') }}}); } }, - read: function (stream, buffer, offset, length, pos /* ignored */) { + read: function(stream, buffer, offset, length, pos /* ignored */) { if (!stream.tty || !stream.tty.ops.get_char) { throw new FS.ErrnoError(ERRNO_CODES.ENXIO); } @@ -1663,7 +1666,7 @@ LibraryManager.library = { } return bytesRead; }, - write: function (stream, buffer, offset, length, pos) { + write: function(stream, buffer, offset, length, pos) { if (!stream.tty || !stream.tty.ops.put_char) { throw new FS.ErrnoError(ERRNO_CODES.ENXIO); } @@ -1683,7 +1686,7 @@ LibraryManager.library = { // NOTE: This is weird to support stdout and stderr // overrides in addition to print and printErr orverrides. default_tty_ops: { - get_char: function (tty) { + get_char: function(tty) { if (!tty.input.length) { var result = null; if (ENVIRONMENT_IS_NODE) { @@ -1712,7 +1715,7 @@ LibraryManager.library = { } return tty.input.shift(); }, - put_char: function (tty, val) { + put_char: function(tty, val) { if (val === null || val === {{{ charCode('\n') }}}) { Module['print'](tty.output.join('')); tty.output = []; @@ -1722,7 +1725,7 @@ LibraryManager.library = { } }, default_tty1_ops: { - put_char: function (tty, val) { + put_char: function(tty, val) { if (val === null || val === {{{ charCode('\n') }}}) { Module['printErr'](tty.output.join('')); tty.output = []; @@ -1761,7 +1764,7 @@ LibraryManager.library = { var lookup = FS.lookupPath(path, { follow: true }); node = lookup.node; } catch (e) { - ___setErrNo(e.errno); + FS.handleFSError(e); return 0; } if (!FS.isDir(node.mode)) { @@ -1813,11 +1816,11 @@ LibraryManager.library = { try { entries = VFS.readdir(stream); } catch (e) { - return ___setErrNo(e.errno); + return FS.handleFSError(e); } if (stream.position < 0 || stream.position >= entries.length) { {{{ makeSetValue('result', '0', '0', 'i8*') }}} - return; + return 0; } var id; var type; @@ -1893,7 +1896,7 @@ LibraryManager.library = { VFS.utime(path, time, time); return 0; } catch (e) { - ___setErrNo(e.errno); + FS.handleFSError(e); return -1; } }, @@ -2006,7 +2009,7 @@ LibraryManager.library = { {{{ makeSetValue('buf', '___stat_struct_layout.st_blocks', 'stat.blocks', 'i32') }}} return 0; } catch (e) { - ___setErrNo(e.errno); + FS.handleFSError(e); return -1; } }, @@ -2043,7 +2046,7 @@ LibraryManager.library = { VFS.mknod(path, mode, dev); return 0; } catch (e) { - ___setErrNo(e.errno); + FS.handleFSError(e); return -1; } }, @@ -2056,7 +2059,7 @@ LibraryManager.library = { VFS.mkdir(path, mode, 0); return 0; } catch (e) { - ___setErrNo(e.errno); + FS.handleFSError(e); return -1; } }, @@ -2082,7 +2085,7 @@ LibraryManager.library = { VFS.chmod(path, mode); return 0; } catch (e) { - ___setErrNo(e.errno); + FS.handleFSError(e); return -1; } }, @@ -2094,18 +2097,18 @@ LibraryManager.library = { VFS.fchmod(fildes, mode); return 0; } catch (e) { - ___setErrNo(e.errno); + FS.handleFSError(e); return -1; } }, lchmod__deps: ['chmod'], - lchmod: function (path, mode) { + lchmod: function(path, mode) { path = Pointer_stringify(path); try { VFS.lchmod(path, mode); return 0; } catch (e) { - ___setErrNo(e.errno); + FS.handleFSError(e); return -1; } }, @@ -2197,7 +2200,7 @@ LibraryManager.library = { var stream = VFS.open(path, oflag, mode); return stream.fd; } catch (e) { - ___setErrNo(e.errno); + FS.handleFSError(e); return -1; } }, @@ -2236,7 +2239,7 @@ LibraryManager.library = { try { newStream = VFS.open(stream.path, stream.flags, 0, arg); } catch (e) { - ___setErrNo(e.errno); + FS.handleFSError(e); return -1; } return newStream.fd; @@ -2294,7 +2297,7 @@ LibraryManager.library = { VFS.allocate(stream, offset, len); return 0; } catch (e) { - ___setErrNo(e.errno); + FS.handleFSError(e); return -1; } }, @@ -2361,7 +2364,7 @@ LibraryManager.library = { var lookup = FS.lookupPath(path, { follow: true }); node = lookup.node; } catch (e) { - ___setErrNo(e.errno); + FS.handleFSError(e); return -1; } var perms = ''; @@ -2384,7 +2387,7 @@ LibraryManager.library = { try { lookup = FS.lookupPath(path, { follow: true }); } catch (e) { - ___setErrNo(e.errno); + FS.handleFSError(e); return -1; } if (!FS.isDir(lookup.node.mode)) { @@ -2412,7 +2415,7 @@ LibraryManager.library = { VFS.chown(path, owner, group); return 0; } catch (e) { - ___setErrNo(e.errno); + FS.handleFSError(e); return -1; } }, @@ -2436,7 +2439,7 @@ LibraryManager.library = { VFS.close(stream); return 0; } catch (e) { - ___setErrNo(e.errno);; + FS.handleFSError(e);; return -1; } }, @@ -2462,7 +2465,7 @@ LibraryManager.library = { var stream2 = VFS.open(stream.path, stream.flags, 0, fildes2, fildes2); return stream2.fd; } catch (e) { - ___setErrNo(e.errno); + FS.handleFSError(e); return -1; } } @@ -2475,7 +2478,7 @@ LibraryManager.library = { VFS.fchown(fildes, owner, group); return 0; } catch (e) { - ___setErrNo(e.errno); + FS.handleFSError(e); return -1; } }, @@ -2578,7 +2581,7 @@ LibraryManager.library = { VFS.truncate(path, length); return 0; } catch (e) { - ___setErrNo(e.errno); + FS.handleFSError(e); return -1; } }, @@ -2590,7 +2593,7 @@ LibraryManager.library = { VFS.ftruncate(fildes, length); return 0; } catch (e) { - ___setErrNo(e.errno); + FS.handleFSError(e); return -1; } }, @@ -2674,7 +2677,7 @@ LibraryManager.library = { try { return VFS.llseek(stream, offset, whence); } catch (e) { - ___setErrNo(e.errno); + FS.handleFSError(e); return -1; } }, @@ -2698,9 +2701,14 @@ LibraryManager.library = { } try { var slab = {{{ makeGetSlabs('buf', 'i8', true) }}}; +#if SAFE_HEAP +#if USE_TYPED_ARRAYS == 0 + SAFE_HEAP_FILL_HISTORY(buf, buf+nbyte, 'i8'); // VFS does not use makeSetValues, so we need to do it manually +#endif +#endif return VFS.read(stream, slab, buf, nbyte, offset); } catch (e) { - ___setErrNo(e.errno); + FS.handleFSError(e); return -1; } }, @@ -2720,9 +2728,14 @@ LibraryManager.library = { try { var slab = {{{ makeGetSlabs('buf', 'i8', true) }}}; +#if SAFE_HEAP +#if USE_TYPED_ARRAYS == 0 + SAFE_HEAP_FILL_HISTORY(buf, buf+nbyte, 'i8'); // VFS does not use makeSetValues, so we need to do it manually +#endif +#endif return VFS.read(stream, slab, buf, nbyte); } catch (e) { - ___setErrNo(e.errno); + FS.handleFSError(e); return -1; } }, @@ -2740,7 +2753,7 @@ LibraryManager.library = { VFS.rmdir(path); return 0; } catch (e) { - ___setErrNo(e.errno); + FS.handleFSError(e); return -1; } }, @@ -2753,7 +2766,7 @@ LibraryManager.library = { VFS.unlink(path); return 0; } catch (e) { - ___setErrNo(e.errno); + FS.handleFSError(e); return -1; } }, @@ -2790,7 +2803,7 @@ LibraryManager.library = { VFS.symlink(path1, path2); return 0; } catch (e) { - ___setErrNo(e.errno); + FS.handleFSError(e); return -1; } }, @@ -2803,7 +2816,7 @@ LibraryManager.library = { try { str = VFS.readlink(path); } catch (e) { - ___setErrNo(e.errno); + FS.handleFSError(e); return -1; } str = str.slice(0, Math.max(0, bufsize - 1)); @@ -2821,9 +2834,14 @@ LibraryManager.library = { } try { var slab = {{{ makeGetSlabs('buf', 'i8', true) }}}; +#if SAFE_HEAP +#if USE_TYPED_ARRAYS == 0 + SAFE_HEAP_FILL_HISTORY(buf, buf+nbyte, 'i8'); // VFS does not use makeSetValues, so we need to do it manually +#endif +#endif return VFS.write(stream, slab, buf, nbyte, offset); } catch (e) { - ___setErrNo(e.errno); + FS.handleFSError(e); return -1; } }, @@ -2838,14 +2856,19 @@ LibraryManager.library = { } if (stream && ('socket' in stream)) { - return _send(fildes, buf, nbyte, 0); + return _send(fildes, buf, nbyte, 0); } try { var slab = {{{ makeGetSlabs('buf', 'i8', true) }}}; +#if SAFE_HEAP +#if USE_TYPED_ARRAYS == 0 + SAFE_HEAP_FILL_HISTORY(buf, buf+nbyte, 'i8'); // VFS does not use makeSetValues, so we need to do it manually +#endif +#endif return VFS.write(stream, slab, buf, nbyte); } catch (e) { - ___setErrNo(e.errno); + FS.handleFSError(e); return -1; } }, @@ -2974,7 +2997,7 @@ LibraryManager.library = { }, // TODO: Implement initgroups (grp.h). setgroups__deps: ['__setErrNo', '$ERRNO_CODES', 'sysconf'], - setgroups: function (ngroups, gidset) { + setgroups: function(ngroups, gidset) { // int setgroups(int ngroups, const gid_t *gidset); // https://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man2/setgroups.2.html if (ngroups < 1 || ngroups > _sysconf({{{ cDefine('_SC_NGROUPS_MAX') }}})) { @@ -4315,7 +4338,7 @@ LibraryManager.library = { VFS.rename(old_path, new_path); return 0; } catch (e) { - ___setErrNo(e.errno); + FS.handleFSError(e); return -1; } }, @@ -4580,7 +4603,7 @@ LibraryManager.library = { ptr = res.ptr; allocated = res.allocated; } catch (e) { - ___setErrNo(e.errno); + FS.handleFSError(e); return -1; } } @@ -5136,7 +5159,7 @@ LibraryManager.library = { // FIXME: memcpy, memmove and memset should all return their destination pointers. - memcpy__inline: function (dest, src, num, align) { + memcpy__inline: function(dest, src, num, align) { var ret = ''; #if ASSERTIONS #if ASM_JS == 0 @@ -5149,7 +5172,7 @@ LibraryManager.library = { memcpy__asm: true, memcpy__sig: 'iiii', - memcpy: function (dest, src, num) { + memcpy: function(dest, src, num) { dest = dest|0; src = src|0; num = num|0; var ret = 0; ret = dest|0; @@ -5701,17 +5724,7 @@ LibraryManager.library = { (chr >= {{{ charCode('{') }}} && chr <= {{{ charCode('~') }}}); }, isspace: function(chr) { - switch(chr) { - case 32: - case 9: - case 10: - case 11: - case 12: - case 13: - return true; - default: - return false; - }; + return (chr == 32) || (chr >= 9 && chr <= 13); }, isblank: function(chr) { return chr == {{{ charCode(' ') }}} || chr == {{{ charCode('\t') }}}; @@ -6363,7 +6376,7 @@ LibraryManager.library = { // http://www.digitalmars.com/archives/cplusplus/3634.html // and mruby source code at // https://github.com/mruby/mruby/blob/master/src/math.c - erfc: function (x) { + erfc: function(x) { var MATH_TOLERANCE = 1E-12; var ONE_SQRTPI = 0.564189583547756287; var a = 1; @@ -6395,7 +6408,7 @@ LibraryManager.library = { }, erfcf: 'erfcf', erf__deps: ['erfc'], - erf: function (x) { + erf: function(x) { var MATH_TOLERANCE = 1E-12; var TWO_SQRTPI = 1.128379167095512574; var sum = x; diff --git a/src/library_openal.js b/src/library_openal.js index d2516559..c55415b8 100644 --- a/src/library_openal.js +++ b/src/library_openal.js @@ -85,7 +85,7 @@ var LibraryOpenAL = { err: 0, src: [], buf: [], - interval: setInterval(function () { _updateSources(context); }, AL.QUEUE_INTERVAL) + interval: setInterval(function() { _updateSources(context); }, AL.QUEUE_INTERVAL) }; AL.contexts.push(context); return AL.contexts.length; @@ -95,14 +95,14 @@ var LibraryOpenAL = { }, updateSources__deps: ['updateSource'], - updateSources: function (context) { + updateSources: function(context) { for (var i = 0; i < context.src.length; i++) { _updateSource(context.src[i]); } }, updateSource__deps: ['setSourceState'], - updateSource: function (src) { + updateSource: function(src) { #if OPENAL_DEBUG var idx = AL.currentContext.src.indexOf(src); #endif @@ -154,7 +154,7 @@ var LibraryOpenAL = { }, setSourceState__deps: ['updateSource', 'stopSourceQueue'], - setSourceState: function (src, state) { + setSourceState: function(src, state) { #if OPENAL_DEBUG var idx = AL.currentContext.src.indexOf(src); #endif @@ -208,7 +208,7 @@ var LibraryOpenAL = { } }, - stopSourceQueue: function (src) { + stopSourceQueue: function(src) { for (var i = 0; i < src.queue.length; i++) { var entry = src.queue[i]; if (entry.src) { @@ -906,7 +906,7 @@ var LibraryOpenAL = { return 0; }, - alGetString: function (param) { + alGetString: function(param) { return allocate(intArrayFromString('NA'), 'i8', ALLOC_NORMAL); }, @@ -914,7 +914,7 @@ var LibraryOpenAL = { return 0; }, - alcGetString: function (param) { + alcGetString: function(param) { return allocate(intArrayFromString('NA'), 'i8', ALLOC_NORMAL); }, diff --git a/src/library_path.js b/src/library_path.js index 3df6ca5b..2c2c016a 100644 --- a/src/library_path.js +++ b/src/library_path.js @@ -1,12 +1,13 @@ mergeInto(LibraryManager.library, { + $PATH__deps: ['$FS'], $PATH: { // split a filename into [root, dir, basename, ext], unix version // 'root' is just a slash, or nothing. - splitPath: function (filename) { + splitPath: function(filename) { var splitPathRe = /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/; return splitPathRe.exec(filename).slice(1); }, - normalizeArray: function (parts, allowAboveRoot) { + normalizeArray: function(parts, allowAboveRoot) { // if the path tries to go above the root, `up` ends up > 0 var up = 0; for (var i = parts.length - 1; i >= 0; i--) { @@ -29,7 +30,7 @@ mergeInto(LibraryManager.library, { } return parts; }, - normalize: function (path) { + normalize: function(path) { var isAbsolute = path.charAt(0) === '/', trailingSlash = path.substr(-1) === '/'; // Normalize the path @@ -44,7 +45,7 @@ mergeInto(LibraryManager.library, { } return (isAbsolute ? '/' : '') + path; }, - dirname: function (path) { + dirname: function(path) { var result = PATH.splitPath(path), root = result[0], dir = result[1]; @@ -58,7 +59,7 @@ mergeInto(LibraryManager.library, { } return root + dir; }, - basename: function (path, ext) { + basename: function(path, ext) { // EMSCRIPTEN return '/'' for '/', not an empty string if (path === '/') return '/'; var f = PATH.splitPath(path)[2]; @@ -67,7 +68,7 @@ mergeInto(LibraryManager.library, { } return f; }, - join: function () { + join: function() { var paths = Array.prototype.slice.call(arguments, 0); return PATH.normalize(paths.filter(function(p, index) { if (typeof p !== 'string') { @@ -76,11 +77,11 @@ mergeInto(LibraryManager.library, { return p; }).join('/')); }, - resolve: function () { + resolve: function() { var resolvedPath = '', resolvedAbsolute = false; for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) { - var path = (i >= 0) ? arguments[i] : process.cwd(); + var path = (i >= 0) ? arguments[i] : FS.cwd(); // Skip empty and invalid entries if (typeof path !== 'string') { throw new TypeError('Arguments to path.resolve must be strings'); diff --git a/src/library_sdl.js b/src/library_sdl.js index 80c7ac07..19152646 100644 --- a/src/library_sdl.js +++ b/src/library_sdl.js @@ -318,7 +318,7 @@ var LibrarySDL = { usePageCanvas: usePageCanvas, source: source, - isFlagSet: function (flag) { + isFlagSet: function(flag) { return flags & flag; } }; @@ -2112,7 +2112,7 @@ var LibrarySDL = { return -1; }, - SDL_SetGammaRamp: function (redTable, greenTable, blueTable) { + SDL_SetGammaRamp: function(redTable, greenTable, blueTable) { return -1; }, diff --git a/src/preamble.js b/src/preamble.js index 2955c885..585db832 100644 --- a/src/preamble.js +++ b/src/preamble.js @@ -156,6 +156,15 @@ function SAFE_HEAP_COPY_HISTORY(dest, src) { SAFE_HEAP_ACCESS(dest, HEAP_HISTORY[dest] || null, true, false); } +function SAFE_HEAP_FILL_HISTORY(from, to, type) { +#if SAFE_HEAP_LOG + Module.print('SAFE_HEAP fill: ' + [from, to, type]); +#endif + for (var i = from; i < to; i++) { + HEAP_HISTORY[i] = type; + } +} + //========================================== #endif diff --git a/src/shell.js b/src/shell.js index 2082eeae..bac4eaa3 100644 --- a/src/shell.js +++ b/src/shell.js @@ -70,8 +70,7 @@ if (ENVIRONMENT_IS_NODE) { module.exports = Module; } - -if (ENVIRONMENT_IS_SHELL) { +else if (ENVIRONMENT_IS_SHELL) { Module['print'] = print; if (typeof printErr != 'undefined') Module['printErr'] = printErr; // not present in v8 or older sm @@ -88,20 +87,7 @@ if (ENVIRONMENT_IS_SHELL) { this['{{{ EXPORT_NAME }}}'] = Module; } - -if (ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_WORKER) { - Module['print'] = function(x) { - console.log(x); - }; - - Module['printErr'] = function(x) { - console.log(x); - }; - - this['{{{ EXPORT_NAME }}}'] = Module; -} - -if (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) { +else if (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) { Module['read'] = function(url) { var xhr = new XMLHttpRequest(); xhr.open('GET', url, false); @@ -112,21 +98,30 @@ if (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) { if (typeof arguments != 'undefined') { Module['arguments'] = arguments; } -} -if (ENVIRONMENT_IS_WORKER) { - // We can do very little here... - var TRY_USE_DUMP = false; - Module['print'] = (TRY_USE_DUMP && (typeof(dump) !== "undefined") ? (function(x) { - dump(x); - }) : (function(x) { - // self.postMessage(x); // enable this if you want stdout to be sent as messages - })); - - Module['load'] = importScripts; + if (ENVIRONMENT_IS_WEB) { + Module['print'] = function(x) { + console.log(x); + }; + + Module['printErr'] = function(x) { + console.log(x); + }; + + this['{{{ EXPORT_NAME }}}'] = Module; + } else if (ENVIRONMENT_IS_WORKER) { + // We can do very little here... + var TRY_USE_DUMP = false; + Module['print'] = (TRY_USE_DUMP && (typeof(dump) !== "undefined") ? (function(x) { + dump(x); + }) : (function(x) { + // self.postMessage(x); // enable this if you want stdout to be sent as messages + })); + + Module['load'] = importScripts; + } } - -if (!ENVIRONMENT_IS_WORKER && !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_NODE && !ENVIRONMENT_IS_SHELL) { +else { // Unreachable because SHELL is dependant on the others throw 'Unknown runtime environment. Where are we?'; } diff --git a/system/lib/libc/musl/src/stdlib/ecvt.c b/system/lib/libc/musl/src/stdlib/ecvt.c new file mode 100644 index 00000000..79c3de63 --- /dev/null +++ b/system/lib/libc/musl/src/stdlib/ecvt.c @@ -0,0 +1,19 @@ +#include <stdlib.h> +#include <stdio.h> + +char *ecvt(double x, int n, int *dp, int *sign) +{ + static char buf[16]; + char tmp[32]; + int i, j; + + if (n-1U > 15) n = 15; + sprintf(tmp, "%.*e", n-1, x); + i = *sign = (tmp[0]=='-'); + for (j=0; tmp[i]!='e'; j+=(tmp[i++]!='.')) + buf[j] = tmp[i]; + buf[j] = 0; + *dp = atoi(tmp+i+1)+1; + + return buf; +} diff --git a/system/lib/libc/musl/src/stdlib/fcvt.c b/system/lib/libc/musl/src/stdlib/fcvt.c new file mode 100644 index 00000000..f90928fe --- /dev/null +++ b/system/lib/libc/musl/src/stdlib/fcvt.c @@ -0,0 +1,25 @@ +#define _GNU_SOURCE +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +char *fcvt(double x, int n, int *dp, int *sign) +{ + char tmp[1500]; + int i, lz; + + if (n > 1400U) n = 1400; + sprintf(tmp, "%.*f", n, x); + i = (tmp[0] == '-'); + if (tmp[i] == '0') lz = strspn(tmp+i+2, "0"); + else lz = -(int)strcspn(tmp+i, "."); + + if (n<=lz) { + *sign = i; + *dp = 1; + if (n>14U) n = 14; + return "000000000000000"+14-n; + } + + return ecvt(x, n-lz, dp, sign); +} diff --git a/system/lib/libc/musl/src/stdlib/gcvt.c b/system/lib/libc/musl/src/stdlib/gcvt.c new file mode 100644 index 00000000..6c075e25 --- /dev/null +++ b/system/lib/libc/musl/src/stdlib/gcvt.c @@ -0,0 +1,8 @@ +#include <stdlib.h> +#include <stdio.h> + +char *gcvt(double x, int n, char *b) +{ + sprintf(b, "%.*g", n, x); + return b; +} diff --git a/system/lib/libcextra.symbols b/system/lib/libcextra.symbols index 42e66b51..a365271d 100644 --- a/system/lib/libcextra.symbols +++ b/system/lib/libcextra.symbols @@ -1,4 +1,7 @@ T btowc + T ecvt + T fcvt + T gcvt T iswalnum T iswalpha T iswblank diff --git a/tests/runner.py b/tests/runner.py index 46096213..54a7a340 100755 --- a/tests/runner.py +++ b/tests/runner.py @@ -16,7 +16,7 @@ so you may prefer to use fewer cores here. ''' from subprocess import Popen, PIPE, STDOUT -import os, unittest, tempfile, shutil, time, inspect, sys, math, glob, re, difflib, webbrowser, hashlib, threading, platform, BaseHTTPServer, multiprocessing, functools, stat +import os, unittest, tempfile, shutil, time, inspect, sys, math, glob, re, difflib, webbrowser, hashlib, threading, platform, BaseHTTPServer, multiprocessing, functools, stat, string if len(sys.argv) == 1: print ''' @@ -353,7 +353,10 @@ process(sys.argv[1]) build_dir = self.get_build_dir() output_dir = self.get_dir() - cache_name = name + cache_name_extra + (self.env.get('EMCC_LLVM_TARGET') or '') + cache_name = name + str(Building.COMPILER_TEST_OPTS) + cache_name_extra + (self.env.get('EMCC_LLVM_TARGET') or '') + + valid_chars = "_%s%s" % (string.ascii_letters, string.digits) + cache_name = ''.join([(c if c in valid_chars else '_') for c in cache_name]) if self.library_cache is not None: if cache and self.library_cache.get(cache_name): @@ -1984,6 +1987,24 @@ Succeeded! self.do_run(src, "1.0 2.0 -1.0 -2.0 2.0 3.0 -2.0 -3.0 " "1 2 -1 -2 2 2 -2 -2") + # This example borrowed from MSDN documentation + def test_fcvt(self): + src = ''' + #include <stdlib.h> + #include <stdio.h> + + int main() { + int decimal, sign; + char *buffer; + double source = 3.1415926535; + + buffer = fcvt(source, 7, &decimal, &sign); + printf("source: %2.10f buffer: '%s' decimal: %d sign: %d\\n", + source, buffer, decimal, sign); + } + ''' + self.do_run(src, "source: 3.1415926535 buffer: '31415927' decimal: 1 sign: 0"); + def test_llrint(self): if Settings.USE_TYPED_ARRAYS != 2: return self.skip('requires ta2') src = r''' @@ -7089,7 +7110,7 @@ def process(filename): other.close() src = open(path_from_root('tests', 'files.cpp'), 'r').read() - self.do_run(src, 'size: 7\ndata: 100,-56,50,25,10,77,123\nloop: 100 -56 50 25 10 77 123 \ninput:hi there!\ntexto\n$\n5 : 10,30,20,11,88\nother=some data.\nseeked=me da.\nseeked=ata.\nseeked=ta.\nfscanfed: 10 - hello\nok.\ntexte\n', + self.do_run(src, ('size: 7\ndata: 100,-56,50,25,10,77,123\nloop: 100 -56 50 25 10 77 123 \ninput:hi there!\ntexto\n$\n5 : 10,30,20,11,88\nother=some data.\nseeked=me da.\nseeked=ata.\nseeked=ta.\nfscanfed: 10 - hello\nok.\ntexte\n', 'size: 7\ndata: 100,-56,50,25,10,77,123\nloop: 100 -56 50 25 10 77 123 \ninput:hi there!\ntexto\ntexte\n$\n5 : 10,30,20,11,88\nother=some data.\nseeked=me da.\nseeked=ata.\nseeked=ta.\nfscanfed: 10 - hello\nok.\n'), post_build=post, extra_emscripten_args=['-H', 'libc/fcntl.h']) def test_files_m(self): @@ -7121,7 +7142,7 @@ def process(filename): return 0; } ''' - self.do_run(src, 'got: 35\ngot: 45\ngot: 25\ngot: 15\nisatty? 0,0,1\n', post_build=post) + self.do_run(src, ('got: 35\ngot: 45\ngot: 25\ngot: 15\nisatty? 0,0,1\n', 'isatty? 0,0,1\ngot: 35\ngot: 45\ngot: 25\ngot: 15\n'), post_build=post) def test_fwrite_0(self): src = r''' @@ -7764,6 +7785,8 @@ def process(filename): self.do_run(src, '120.86.52.18\n120.86.52.18\n') def test_inet4(self): + if Settings.USE_TYPED_ARRAYS != 2: return self.skip('requires ta2') + src = r''' #include <stdio.h> #include <arpa/inet.h> @@ -9161,24 +9184,14 @@ def process(filename): } int main(int argc, char **argv) { - // keep them alive - if (argc == 10) return get_int(); - if (argc == 11) return get_float(); - if (argc == 12) return get_string()[0]; - if (argc == 13) print_int(argv[0][0]); - if (argc == 14) print_float(argv[0][0]); - if (argc == 15) print_string(argv[0]); - if (argc == 16) pointer((int*)argv[0]); - if (argc % 17 == 12) return multi(argc, float(argc)/2, argc+1, argv[0]); - // return 0; - exit(0); + return 0; } ''' post = ''' def process(filename): src = \'\'\' - var Module = { noInitialRun: true }; + var Module = { 'noInitialRun': true }; \'\'\' + open(filename, 'r').read() + \'\'\' Module.addOnExit(function () { Module.print('*'); @@ -11051,6 +11064,24 @@ f.close() voidfunc sidey(voidfunc f) { return f; } ''', 'hello from funcptr\n') + # function pointers with 'return' in the name + test('fp2', 'typedef void (*voidfunc)();', r''' + #include <stdio.h> + #include "header.h" + int sidey(voidfunc f); + void areturn0() { printf("hello 0\n"); } + void areturn1() { printf("hello 1\n"); } + void areturn2() { printf("hello 2\n"); } + int main(int argc, char **argv) { + voidfunc table[3] = { areturn0, areturn1, areturn2 }; + table[sidey(NULL)](); + return 0; + } + ''', ''' + #include "header.h" + int sidey(voidfunc f) { if (f) f(); return 1; } + ''', 'hello 1\n') + # Global initializer test('global init', '', r''' #include <stdio.h> @@ -11200,7 +11231,7 @@ f.close() def test_outline(self): - def test(name, src, libs, expected, expected_ranges, args=[], suffix='cpp'): + def test(name, src, libs, expected, expected_ranges, args=[], suffix='cpp', test_sizes=True): print name def measure_funcs(filename): @@ -11240,21 +11271,23 @@ f.close() seen = max(measure_funcs('test.js').values()) high = expected_ranges[outlining_limit][1] print outlining_limit, ' ', low, '<=', seen, '<=', high - assert low <= seen <= high - - test('zlib', path_from_root('tests', 'zlib', 'example.c'), - self.get_library('zlib', os.path.join('libz.a'), make_args=['libz.a']), - open(path_from_root('tests', 'zlib', 'ref.txt'), 'r').read(), - { - 100: (190, 250), - 250: (300, 330), - 500: (250, 310), - 1000: (230, 300), - 2000: (380, 450), - 5000: (800, 1100), - 0: (1500, 1800) - }, - args=['-I' + path_from_root('tests', 'zlib')], suffix='c') + if test_sizes: assert low <= seen <= high + + for test_opts, test_sizes in [([], True), (['-O2'], False)]: + Building.COMPILER_TEST_OPTS = test_opts + test('zlib', path_from_root('tests', 'zlib', 'example.c'), + self.get_library('zlib', os.path.join('libz.a'), make_args=['libz.a']), + open(path_from_root('tests', 'zlib', 'ref.txt'), 'r').read(), + { + 100: (190, 250), + 250: (200, 330), + 500: (250, 310), + 1000: (230, 300), + 2000: (380, 450), + 5000: (800, 1100), + 0: (1500, 1800) + }, + args=['-I' + path_from_root('tests', 'zlib')], suffix='c', test_sizes=test_sizes) def test_symlink(self): if os.name == 'nt': diff --git a/tools/asm_module.py b/tools/asm_module.py index e54cfc21..bf7fa71d 100644 --- a/tools/asm_module.py +++ b/tools/asm_module.py @@ -49,7 +49,7 @@ class AsmModule(): # tables and exports post_js = self.js[self.end_funcs:self.end_asm] - ret = post_js.find('return') + ret = post_js.find('return ') self.tables_js = post_js[:ret] self.exports_js = post_js[ret:] self.tables = self.parse_tables(self.tables_js) diff --git a/tools/js-optimizer.js b/tools/js-optimizer.js index 82942ce2..4192ddd1 100644 --- a/tools/js-optimizer.js +++ b/tools/js-optimizer.js @@ -3227,6 +3227,7 @@ function outline(ast) { if (asmData.splitCounter === asmData.maxOutlinings) return []; if (!extraInfo.allowCostlyOutlines) var originalStats = copy(stats); var code = stats.slice(start, end+1); + var originalCodeSize = measureSize(code); var funcSize = measureSize(func); var outlineIndex = asmData.splitCounter++; var newIdent = func[1] + '$' + outlineIndex; @@ -3239,7 +3240,6 @@ function outline(ast) { owned[v] = 1; } }); - printErr('attempting outline ' + [func[1], newIdent, 'overhead:', setSize(setSub(codeInfo.writes, owned)), setSize(setSub(codeInfo.reads, owned))]); var reps = []; // wipe out control variable reps.push(['stat', makeAssign(makeStackAccess(ASM_INT, asmData.controlStackPos(outlineIndex)), ['num', 0])]); @@ -3417,9 +3417,11 @@ function outline(ast) { stats.splice.apply(stats, [start, end-start+1].concat(reps)); // final evaluation and processing if (!extraInfo.allowCostlyOutlines && (measureSize(func) >= funcSize || measureSize(newFunc) >= funcSize)) { + //printErr('aborted outline attempt ' + [measureSize(func), measureSize(newFunc), ' one of which >= ', funcSize]); // abort, this was pointless stats.length = originalStats.length; for (var i = 0; i < stats.length; i++) stats[i] = originalStats[i]; + asmData.splitCounter--; return []; } for (var v in owned) { @@ -3434,6 +3436,7 @@ function outline(ast) { } } outliningParents[newIdent] = func[1]; + printErr('performed outline ' + [func[1], newIdent, 'code sizes (pre/post):', originalCodeSize, measureSize(code), 'overhead (w/r):', setSize(setSub(codeInfo.writes, owned)), setSize(setSub(codeInfo.reads, owned))]); calculateThreshold(func); return [newFunc]; } @@ -3518,7 +3521,7 @@ function outline(ast) { // If this is big enough to outline, but not too big (if very close to the size of the full function, // outlining is pointless; remove stats from the end to try to achieve the good case), then outline. // Also, try to reduce the size if it is much larger than the hoped-for size - while ((sizeSeen > maxSize || sizeSeen > 2*sizeToOutline) && end > i+1 && stats[end][0] !== 'begin-outline-call' && stats[end][0] !== 'end-outline-call') { + while ((sizeSeen > maxSize || sizeSeen > 2*sizeToOutline) && end > i && stats[end][0] !== 'begin-outline-call' && stats[end][0] !== 'end-outline-call') { sizeSeen -= measureSize(stats[end]); if (sizeSeen >= sizeToOutline) { end--; @@ -3540,12 +3543,12 @@ function outline(ast) { }); assert(sum == 0); // final decision and action + //printErr(' will try done working on sizeSeen due to ' + [(sizeSeen > maxSize || sizeSeen > 2*sizeToOutline), end > i , stats[end][0] !== 'begin-outline-call' , stats[end][0] !== 'end-outline-call'] + ' ... ' + [sizeSeen, sizeToOutline, maxSize, sizeSeen >= sizeToOutline, sizeSeen <= maxSize]); if (sizeSeen >= sizeToOutline && sizeSeen <= maxSize) { assert(i >= minIndex); var newFuncs = doOutline(func, asmData, stats, i, end); // outline [i, .. ,end] inclusive if (newFuncs.length) { ret.push.apply(ret, newFuncs); - printErr('performed outline on ' + func[1] + ' of ' + sizeSeen + ', => ' + newFuncs[0][1]); } sizeSeen = 0; end = i-1; |