summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xemcc5
-rw-r--r--src/library.js401
-rw-r--r--src/library_openal.js14
-rw-r--r--src/library_path.js17
-rw-r--r--src/library_sdl.js4
-rw-r--r--src/preamble.js9
-rw-r--r--src/shell.js53
-rw-r--r--system/lib/libc/musl/src/stdlib/ecvt.c19
-rw-r--r--system/lib/libc/musl/src/stdlib/fcvt.c25
-rw-r--r--system/lib/libc/musl/src/stdlib/gcvt.c8
-rw-r--r--system/lib/libcextra.symbols3
-rwxr-xr-xtests/runner.py97
-rw-r--r--tools/asm_module.py2
-rw-r--r--tools/js-optimizer.js9
14 files changed, 390 insertions, 276 deletions
diff --git a/emcc b/emcc
index 8f71883d..a5b30b97 100755
--- a/emcc
+++ b/emcc
@@ -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;