summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AUTHORS1
-rwxr-xr-xemcc5
-rw-r--r--src/intertyper.js6
-rw-r--r--src/library.js418
-rw-r--r--src/library_egl.js9
-rw-r--r--src/library_glut.js2
-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/settings.js16
-rw-r--r--src/shell.js53
-rw-r--r--system/include/libc/sys/signal.h4
-rw-r--r--system/include/net/if.h21
-rw-r--r--system/include/net/netinet/in.h67
-rw-r--r--system/include/netdb.h36
-rw-r--r--system/include/sys/ioctl.h58
-rw-r--r--system/include/sys/select.h2
-rw-r--r--system/include/sys/socket.h211
-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.py142
-rw-r--r--tools/asm_module.py2
-rw-r--r--tools/js-optimizer.js9
-rw-r--r--tools/shared.py5
27 files changed, 819 insertions, 347 deletions
diff --git a/AUTHORS b/AUTHORS
index d3cdd156..5161f7ad 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -92,4 +92,5 @@ a license to everyone to use it as detailed in LICENSE.)
* Michael Lelli <toadking@toadking.com>
* Yu Kobayashi <yukoba@accelart.jp>
* Pin Zhang <zhangpin04@gmail.com>
+* Nick Bray <ncbray@chromium.org> (copyright owned by Google, Inc.)
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/intertyper.js b/src/intertyper.js
index abfbdacb..dd6e5522 100644
--- a/src/intertyper.js
+++ b/src/intertyper.js
@@ -700,6 +700,12 @@ function intertyper(data, sidePass, baseLineNums) {
item.intertype = 'value';
if (tokensLeft[0].text == 'sideeffect') tokensLeft.splice(0, 1);
item.ident = tokensLeft[0].text.substr(1, tokensLeft[0].text.length-2) || ';'; // use ; for empty inline assembly
+ var i = 0;
+ splitTokenList(tokensLeft[3].item.tokens).map(function(element) {
+ var ident = toNiceIdent(element[1].text);
+ var type = element[0].text;
+ item.ident = item.ident.replace(new RegExp('\\$' + i++, 'g'), ident);
+ });
return { forward: null, ret: [item], item: item };
}
if (item.ident.substr(-2) == '()') {
diff --git a/src/library.js b/src/library.js
index e8333b32..a6a38cfe 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
@@ -869,10 +872,9 @@ LibraryManager.library = {
// You can also call this with a typed array instead of a url. It will then
// do preloading for the Image/Audio part, as if the typed array were the
// result of an XHR that you did manually.
- createPreloadedFile__deps: ['$PATH'],
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) {
@@ -907,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,
@@ -933,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);
@@ -951,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);
@@ -978,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);
@@ -1060,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);
@@ -1078,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);
@@ -1098,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) {
@@ -1106,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) {
@@ -1114,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 });
@@ -1133,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 });
@@ -1159,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);
}
@@ -1198,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);
@@ -1208,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') }}})) {
@@ -1279,7 +1281,7 @@ LibraryManager.library = {
}
return stream;
},
- close: function (stream) {
+ close: function(stream) {
try {
if (stream.stream_ops.close) {
stream.stream_ops.close(stream);
@@ -1290,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);
}
@@ -1326,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);
}
@@ -1354,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);
}
@@ -1369,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);
@@ -1383,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);
@@ -1412,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;
@@ -1440,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;
}
@@ -1453,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;
@@ -1478,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);
}
@@ -1501,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 = ['.', '..']
@@ -1514,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
@@ -1529,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++) {
@@ -1538,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;
@@ -1554,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);
}
@@ -1600,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;
@@ -1617,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();
@@ -1634,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);
}
@@ -1664,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);
}
@@ -1684,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) {
@@ -1713,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 = [];
@@ -1723,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 = [];
@@ -1762,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)) {
@@ -1814,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;
@@ -1894,7 +1896,7 @@ LibraryManager.library = {
VFS.utime(path, time, time);
return 0;
} catch (e) {
- ___setErrNo(e.errno);
+ FS.handleFSError(e);
return -1;
}
},
@@ -2007,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;
}
},
@@ -2044,7 +2046,7 @@ LibraryManager.library = {
VFS.mknod(path, mode, dev);
return 0;
} catch (e) {
- ___setErrNo(e.errno);
+ FS.handleFSError(e);
return -1;
}
},
@@ -2057,7 +2059,7 @@ LibraryManager.library = {
VFS.mkdir(path, mode, 0);
return 0;
} catch (e) {
- ___setErrNo(e.errno);
+ FS.handleFSError(e);
return -1;
}
},
@@ -2083,7 +2085,7 @@ LibraryManager.library = {
VFS.chmod(path, mode);
return 0;
} catch (e) {
- ___setErrNo(e.errno);
+ FS.handleFSError(e);
return -1;
}
},
@@ -2095,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;
}
},
@@ -2198,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;
}
},
@@ -2237,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;
@@ -2295,7 +2297,7 @@ LibraryManager.library = {
VFS.allocate(stream, offset, len);
return 0;
} catch (e) {
- ___setErrNo(e.errno);
+ FS.handleFSError(e);
return -1;
}
},
@@ -2362,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 = '';
@@ -2385,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)) {
@@ -2413,7 +2415,7 @@ LibraryManager.library = {
VFS.chown(path, owner, group);
return 0;
} catch (e) {
- ___setErrNo(e.errno);
+ FS.handleFSError(e);
return -1;
}
},
@@ -2437,7 +2439,7 @@ LibraryManager.library = {
VFS.close(stream);
return 0;
} catch (e) {
- ___setErrNo(e.errno);;
+ FS.handleFSError(e);;
return -1;
}
},
@@ -2463,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;
}
}
@@ -2476,7 +2478,7 @@ LibraryManager.library = {
VFS.fchown(fildes, owner, group);
return 0;
} catch (e) {
- ___setErrNo(e.errno);
+ FS.handleFSError(e);
return -1;
}
},
@@ -2579,7 +2581,7 @@ LibraryManager.library = {
VFS.truncate(path, length);
return 0;
} catch (e) {
- ___setErrNo(e.errno);
+ FS.handleFSError(e);
return -1;
}
},
@@ -2591,7 +2593,7 @@ LibraryManager.library = {
VFS.ftruncate(fildes, length);
return 0;
} catch (e) {
- ___setErrNo(e.errno);
+ FS.handleFSError(e);
return -1;
}
},
@@ -2675,7 +2677,7 @@ LibraryManager.library = {
try {
return VFS.llseek(stream, offset, whence);
} catch (e) {
- ___setErrNo(e.errno);
+ FS.handleFSError(e);
return -1;
}
},
@@ -2699,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;
}
},
@@ -2721,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;
}
},
@@ -2741,7 +2753,7 @@ LibraryManager.library = {
VFS.rmdir(path);
return 0;
} catch (e) {
- ___setErrNo(e.errno);
+ FS.handleFSError(e);
return -1;
}
},
@@ -2754,7 +2766,7 @@ LibraryManager.library = {
VFS.unlink(path);
return 0;
} catch (e) {
- ___setErrNo(e.errno);
+ FS.handleFSError(e);
return -1;
}
},
@@ -2791,7 +2803,7 @@ LibraryManager.library = {
VFS.symlink(path1, path2);
return 0;
} catch (e) {
- ___setErrNo(e.errno);
+ FS.handleFSError(e);
return -1;
}
},
@@ -2804,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));
@@ -2822,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;
}
},
@@ -2839,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;
}
},
@@ -2975,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') }}})) {
@@ -4316,7 +4338,7 @@ LibraryManager.library = {
VFS.rename(old_path, new_path);
return 0;
} catch (e) {
- ___setErrNo(e.errno);
+ FS.handleFSError(e);
return -1;
}
},
@@ -4581,7 +4603,7 @@ LibraryManager.library = {
ptr = res.ptr;
allocated = res.allocated;
} catch (e) {
- ___setErrNo(e.errno);
+ FS.handleFSError(e);
return -1;
}
}
@@ -5137,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
@@ -5150,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;
@@ -5702,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') }}};
@@ -6364,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;
@@ -6396,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;
@@ -8940,7 +8952,7 @@ LibraryManager.library = {
* Module['webrtc']['ondisconnect']: function(peer), invoked when an existing connection is closed
* Module['webrtc']['onerror']: function(error), invoked when an error occurs
*/
- socket__deps: ['$Sockets'],
+ socket__deps: ['$FS', '$Sockets'],
socket: function(family, type, protocol) {
var INCOMING_QUEUE_LENGTH = 64;
var stream = FS.createStream({
@@ -9085,7 +9097,7 @@ LibraryManager.library = {
// Stub: connection-oriented sockets are not supported yet.
},
- bind__deps: ['$Sockets', '_inet_ntoa_raw', 'ntohs', 'mkport'],
+ bind__deps: ['$FS', '$Sockets', '_inet_ntoa_raw', 'ntohs', 'mkport'],
bind: function(fd, addr, addrlen) {
var info = FS.getStream(fd);
if (!info) return -1;
@@ -9106,7 +9118,7 @@ LibraryManager.library = {
info.bound = true;
},
- sendmsg__deps: ['$Sockets', 'bind', '_inet_ntoa_raw', 'ntohs'],
+ sendmsg__deps: ['$FS', '$Sockets', 'bind', '_inet_ntoa_raw', 'ntohs'],
sendmsg: function(fd, msg, flags) {
var info = FS.getStream(fd);
if (!info) return -1;
@@ -9162,7 +9174,7 @@ LibraryManager.library = {
connection.send('unreliable', buffer.buffer);
},
- recvmsg__deps: ['$Sockets', 'bind', '__setErrNo', '$ERRNO_CODES', 'htons'],
+ recvmsg__deps: ['$FS', '$Sockets', 'bind', '__setErrNo', '$ERRNO_CODES', 'htons'],
recvmsg: function(fd, msg, flags) {
var info = FS.getStream(fd);
if (!info) return -1;
@@ -9214,6 +9226,7 @@ LibraryManager.library = {
return ret;
},
+ shutdown__deps: ['$FS'],
shutdown: function(fd, how) {
var stream = FS.getStream(fd);
if (!stream) return -1;
@@ -9221,6 +9234,7 @@ LibraryManager.library = {
FS.closeStream(stream);
},
+ ioctl__deps: ['$FS'],
ioctl: function(fd, request, varargs) {
var info = FS.getStream(fd);
if (!info) return -1;
@@ -9238,6 +9252,7 @@ LibraryManager.library = {
return 0;
},
+ accept__deps: ['$FS'],
accept: function(fd, addr, addrlen) {
// TODO: webrtc queued incoming connections, etc.
// For now, the model is that bind does a connect, and we "accept" that one connection,
@@ -9252,6 +9267,7 @@ LibraryManager.library = {
return fd;
},
+ select__deps: ['$FS'],
select: function(nfds, readfds, writefds, exceptfds, timeout) {
// readfds are supported,
// writefds checks socket open status
@@ -9306,7 +9322,7 @@ LibraryManager.library = {
}
},
#else
- socket__deps: ['$Sockets'],
+ socket__deps: ['$FS', '$Sockets'],
socket: function(family, type, protocol) {
var stream = type == {{{ cDefine('SOCK_STREAM') }}};
if (protocol) {
@@ -9579,6 +9595,7 @@ LibraryManager.library = {
return _recv(fd, buf, len, flags);
},
+ shutdown__deps: ['$FS'],
shutdown: function(fd, how) {
var stream = FS.getStream(fd);
if (!stream) return -1;
@@ -9586,6 +9603,7 @@ LibraryManager.library = {
FS.closeStream(stream);
},
+ ioctl__deps: ['$FS'],
ioctl: function(fd, request, varargs) {
var info = FS.getStream(fd);
if (!info) return -1;
diff --git a/src/library_egl.js b/src/library_egl.js
index 0ccb13e6..0e96e92f 100644
--- a/src/library_egl.js
+++ b/src/library_egl.js
@@ -260,8 +260,13 @@ var LibraryEGL = {
}
EGL.windowID = _glutCreateWindow();
- EGL.setErrorCode(0x3000 /* EGL_SUCCESS */);
- return 62004; // Magic ID for Emscripten EGLContext
+ if (EGL.windowID != 0) {
+ EGL.setErrorCode(0x3000 /* EGL_SUCCESS */);
+ return 62004; // Magic ID for Emscripten EGLContext
+ } else {
+ EGL.setErrorCode(0x3009 /* EGL_BAD_MATCH */); // By the EGL 1.4 spec, an implementation that does not support GLES2 (WebGL in this case), this error code is set.
+ return 0; /* EGL_NO_CONTEXT */
+ }
},
eglDestroyContext__deps: ['glutDestroyWindow', '$GL'],
diff --git a/src/library_glut.js b/src/library_glut.js
index 36d47787..29957e6f 100644
--- a/src/library_glut.js
+++ b/src/library_glut.js
@@ -385,7 +385,7 @@ var LibraryGLUT = {
glutCreateWindow__deps: ['$Browser'],
glutCreateWindow: function(name) {
Module.ctx = Browser.createContext(Module['canvas'], true, true);
- return 1;
+ return Module.ctx ? 1 /* a new GLUT window ID for the created context */ : 0 /* failure */;
},
glutDestroyWindow__deps: ['$Browser'],
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/settings.js b/src/settings.js
index 19108f3b..f620edf7 100644
--- a/src/settings.js
+++ b/src/settings.js
@@ -444,7 +444,7 @@ var C_DEFINES = {
'ABMON_9': '41',
'ACCESSPERMS': '0000400',
'AF_INET': '2',
- 'AF_INET6': '6',
+ 'AF_INET6': '10',
'ALLPERMS': '0004000',
'ALT_DIGITS': '49',
'AM_STR': '5',
@@ -620,8 +620,8 @@ var C_DEFINES = {
'HAVE__ULTOA': '1',
'HUGE_VAL': 'inf',
'INT_MAX': '2147483647',
- 'IPPROTO_TCP': '1',
- 'IPPROTO_UDP': '2',
+ 'IPPROTO_TCP': '6',
+ 'IPPROTO_UDP': '17',
'ITIMER_PROF': '2',
'ITIMER_REAL': '0',
'ITIMER_VIRTUAL': '1',
@@ -676,7 +676,7 @@ var C_DEFINES = {
'NOSTR': '55',
'NO_ARG': '0',
'no_argument': '0',
- 'NSIG': '32',
+ 'NSIG': '64',
'NULL': '0',
'OPTIONAL_ARG': '2',
'optional_argument': '2',
@@ -830,8 +830,8 @@ var C_DEFINES = {
'SIGPROF': '27',
'SIGPWR': '19',
'SIGQUIT': '3',
- 'SIGRTMAX': '31',
- 'SIGRTMIN': '27',
+ 'SIGRTMAX': '64',
+ 'SIGRTMIN': '32',
'SIGSEGV': '11',
'SIGSTOP': '17',
'SIGSYS': '12',
@@ -857,8 +857,8 @@ var C_DEFINES = {
'SI_QUEUE': '2',
'SI_TIMER': '3',
'SI_USER': '1',
- 'SOCK_DGRAM': '20',
- 'SOCK_STREAM': '200',
+ 'SOCK_DGRAM': '2',
+ 'SOCK_STREAM': '1',
'STDC_HEADERS': '1',
'STDERR_FILENO': '2',
'STDIN_FILENO': '0',
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/include/libc/sys/signal.h b/system/include/libc/sys/signal.h
index 49a94d80..fc9b67d5 100644
--- a/system/include/libc/sys/signal.h
+++ b/system/include/libc/sys/signal.h
@@ -298,7 +298,9 @@ int _EXFUN(sigqueue, (pid_t pid, int signo, const union sigval value));
#define SIGLOST 29 /* resource lost (eg, record-lock lost) */
#define SIGUSR1 30 /* user defined signal 1 */
#define SIGUSR2 31 /* user defined signal 2 */
-#define NSIG 32 /* signal 0 implied */
+#define NSIG 64 /* signal 0 implied */
+#define SIGRTMIN 32
+#define SIGRTMAX NSIG
#endif
#endif
diff --git a/system/include/net/if.h b/system/include/net/if.h
index dd7884aa..0ef18520 100644
--- a/system/include/net/if.h
+++ b/system/include/net/if.h
@@ -77,7 +77,26 @@ char *if_indextoname(unsigned int a, char *b);
struct if_nameindex *if_nameindex();
void if_freenameindex(struct if_nameindex *a);
-
+#define IFF_UP 0x1
+#define IFF_BROADCAST 0x2
+#define IFF_DEBUG 0x4
+#define IFF_LOOPBACK 0x8
+#define IFF_POINTOPOINT 0x10
+#define IFF_NOTRAILERS 0x20
+#define IFF_RUNNING 0x40
+#define IFF_NOARP 0x80
+#define IFF_PROMISC 0x100
+#define IFF_ALLMULTI 0x200
+#define IFF_MASTER 0x400
+#define IFF_SLAVE 0x800
+#define IFF_MULTICAST 0x1000
+#define IFF_PORTSEL 0x2000
+#define IFF_AUTOMEDIA 0x4000
+#define IFF_DYNAMIC 0x8000
+#define IFF_LOWER_UP 0x10000
+#define IFF_DORMANT 0x20000
+#define IFF_ECHO 0x40000
+#define IFF_VOLATILE (IFF_LOOPBACK|IFF_POINTOPOINT|IFF_BROADCAST|IFF_ECHO|IFF_MASTER|IFF_SLAVE|IFF_RUNNING|IFF_LOWER_UP|IFF_DORMANT)
#ifdef __cplusplus
}
diff --git a/system/include/net/netinet/in.h b/system/include/net/netinet/in.h
index fba1a7b3..1d3952f5 100644
--- a/system/include/net/netinet/in.h
+++ b/system/include/net/netinet/in.h
@@ -11,11 +11,63 @@ extern "C" {
enum {
IPPROTO_IP = 0,
-#define IPPROTO_IP IPPROTO_IP
- IPPROTO_TCP = 1,
-#define IPPROTO_TCP IPPROTO_TCP
- IPPROTO_UDP = 2,
-#define IPPROTO_UDP IPPROTO_UDP
+#define IPPROTO_IP IPPROTO_IP
+ IPPROTO_HOPOPTS = 0,
+#define IPPROTO_HOPOPTS IPPROTO_HOPOPTS
+ IPPROTO_ICMP = 1,
+#define IPPROTO_ICMP IPPROTO_ICMP
+ IPPROTO_IGMP = 2,
+#define IPPROTO_IGMP IPPROTO_IGMP
+ IPPROTO_IPIP = 4,
+#define IPPROTO_IPIP IPPROTO_IPIP
+ IPPROTO_TCP = 6,
+#define IPPROTO_TCP IPPROTO_TCP
+ IPPROTO_EGP = 8,
+#define IPPROTO_EGP IPPROTO_EGP
+ IPPROTO_PUP = 12,
+#define IPPROTO_PUP IPPROTO_PUP
+ IPPROTO_UDP = 17,
+#define IPPROTO_UDP IPPROTO_UDP
+ IPPROTO_IDP = 22,
+#define IPPROTO_IDP IPPROTO_IDP
+ IPPROTO_TP = 29,
+#define IPPROTO_TP IPPROTO_TP
+ IPPROTO_DCCP = 33,
+#define IPPROTO_DCCP IPPROTO_DCCP
+ IPPROTO_IPV6 = 41,
+#define IPPROTO_IPV6 IPPROTO_IPV6
+ IPPROTO_ROUTING = 43,
+#define IPPROTO_ROUTING IPPROTO_ROUTING
+ IPPROTO_FRAGMENT = 44,
+#define IPPROTO_FRAGMENT IPPROTO_FRAGMENT
+ IPPROTO_RSVP = 46,
+#define IPPROTO_RSVP IPPROTO_RSVP
+ IPPROTO_GRE = 47,
+#define IPPROTO_GRE IPPROTO_GRE
+ IPPROTO_ESP = 50,
+#define IPPROTO_ESP IPPROTO_ESP
+ IPPROTO_AH = 51,
+#define IPPROTO_AH IPPROTO_AH
+ IPPROTO_ICMPV6 = 58,
+#define IPPROTO_ICMPV6 IPPROTO_ICMPV6
+ IPPROTO_NONE = 59,
+#define IPPROTO_NONE IPPROTO_NONE
+ IPPROTO_DSTOPTS = 60,
+#define IPPROTO_DSTOPTS IPPROTO_DSTOPTS
+ IPPROTO_MTP = 92,
+#define IPPROTO_MTP IPPROTO_MTP
+ IPPROTO_ENCAP = 98,
+#define IPPROTO_ENCAP IPPROTO_ENCAP
+ IPPROTO_PIM = 103,
+#define IPPROTO_PIM IPPROTO_PIM
+ IPPROTO_COMP = 108,
+#define IPPROTO_COMP IPPROTO_COMP
+ IPPROTO_SCTP = 132,
+#define IPPROTO_SCTP IPPROTO_SCTP
+ IPPROTO_UDPLITE = 136,
+#define IPPROTO_UDPLITE IPPROTO_UDPLITE
+ IPPROTO_RAW = 255,
+#define IPPROTO_RAW IPPROTO_RAW
IPPROTO_MAX
};
@@ -75,6 +127,11 @@ struct ip_mreq {
struct in_addr imr_interface;
};
+#define IP_PMTUDISC_DONT 0
+#define IP_PMTUDISC_WANT 1
+#define IP_PMTUDISC_DO 2
+#define IP_PMTUDISC_PROBE 3
+
#define IP_MULTICAST_IF 32
#define IP_MULTICAST_TTL 33
#define IP_MULTICAST_LOOP 34
diff --git a/system/include/netdb.h b/system/include/netdb.h
index 48acdcc4..df74a117 100644
--- a/system/include/netdb.h
+++ b/system/include/netdb.h
@@ -11,6 +11,20 @@ extern "C" {
#define NO_DATA 4
#define NO_ADDRESS 5
+#define AI_PASSIVE 0x0001
+#define AI_CANONNAME 0x0002
+#define AI_NUMERICHOST 0x0004
+#define AI_V4MAPPED 0x0008
+#define AI_ALL 0x0010
+#define AI_ADDRCONFIG 0x0020
+#ifdef __USE_GNU
+# define AI_IDN 0x0040
+# define AI_CANONIDN 0x0080
+# define AI_IDN_ALLOW_UNASSIGNED 0x0100
+# define AI_IDN_USE_STD3_ASCII_RULES 0x0200
+#endif
+#define AI_NUMERICSERV 0x0400
+
#define EAI_ADDRFAMILY 1
#define EAI_AGAIN 2
#define EAI_BADFLAGS 3
@@ -47,6 +61,15 @@ extern "C" {
#define IP_PASSSEC 18
#define IP_TRANSPARENT 19
+#define NI_MAXHOST 1025
+#define NI_MAXSERV 32
+
+#define NI_NOFQDN 0x00000001
+#define NI_NUMERICHOST 0x00000002
+#define NI_NAMEREQD 0x00000004
+#define NI_NUMERICSERV 0x00000008
+#define NI_DGRAM 0x00000010
+
typedef int socklen_t;
struct addrinfo
@@ -85,6 +108,19 @@ const char* hstrerror(int err);
extern int h_errno;
+struct servent {
+ char *s_name;
+ char **s_aliases;
+ int s_port;
+ char *s_proto;
+};
+
+struct servent *getservent(void);
+struct servent *getservbyname(const char *name, const char *proto);
+struct servent *getservbyport(int port, const char *proto);
+void setservent(int stayopen);
+void endservent(void);
+
#include <netinet/in.h>
#ifdef __cplusplus
diff --git a/system/include/sys/ioctl.h b/system/include/sys/ioctl.h
index c54d4ccc..047329cb 100644
--- a/system/include/sys/ioctl.h
+++ b/system/include/sys/ioctl.h
@@ -5,9 +5,6 @@
extern "C" {
#endif
-#define SIOCGIFCONF 1 // bogus value
-#define SIOCGIFNETMASK 2 // bogus value
-
#define TIOCGSIZE 80 // bogus
#define TIOCGWINSZ 80 // bogus
@@ -19,6 +16,61 @@ int ioctl(int d, int request, ...);
#define SO_RCVTIMEO 1000
#define SO_SNDTIMEO 2000
+#define SIOCADDRT 0x890B
+#define SIOCDELRT 0x890C
+#define SIOCRTMSG 0x890D
+#define SIOCGIFNAME 0x8910
+#define SIOCSIFLINK 0x8911
+#define SIOCGIFCONF 0x8912
+#define SIOCGIFFLAGS 0x8913
+#define SIOCSIFFLAGS 0x8914
+#define SIOCGIFADDR 0x8915
+#define SIOCSIFADDR 0x8916
+#define SIOCGIFDSTADDR 0x8917
+#define SIOCSIFDSTADDR 0x8918
+#define SIOCGIFBRDADDR 0x8919
+#define SIOCSIFBRDADDR 0x891a
+#define SIOCGIFNETMASK 0x891b
+#define SIOCSIFNETMASK 0x891c
+#define SIOCGIFMETRIC 0x891d
+#define SIOCSIFMETRIC 0x891e
+#define SIOCGIFMEM 0x891f
+#define SIOCSIFMEM 0x8920
+#define SIOCGIFMTU 0x8921
+#define SIOCSIFMTU 0x8922
+#define SIOCSIFNAME 0x8923
+#define SIOCSIFHWADDR 0x8924
+#define SIOCGIFENCAP 0x8925
+#define SIOCSIFENCAP 0x8926
+#define SIOCGIFHWADDR 0x8927
+#define SIOCGIFSLAVE 0x8929
+#define SIOCSIFSLAVE 0x8930
+#define SIOCADDMULTI 0x8931
+#define SIOCDELMULTI 0x8932
+#define SIOCGIFINDEX 0x8933
+#define SIOGIFINDEX SIOCGIFINDEX
+#define SIOCSIFPFLAGS 0x8934
+#define SIOCGIFPFLAGS 0x8935
+#define SIOCDIFADDR 0x8936
+#define SIOCSIFHWBROADCAST 0x8937
+#define SIOCGIFCOUNT 0x8938
+#define SIOCGIFBR 0x8940
+#define SIOCSIFBR 0x8941
+#define SIOCGIFTXQLEN 0x8942
+#define SIOCSIFTXQLEN 0x8943
+#define SIOCDARP 0x8953
+#define SIOCGARP 0x8954
+#define SIOCSARP 0x8955
+#define SIOCDRARP 0x8960
+#define SIOCGRARP 0x8961
+#define SIOCSRARP 0x8962
+#define SIOCGIFMAP 0x8970
+#define SIOCSIFMAP 0x8971
+#define SIOCADDDLCI 0x8980
+#define SIOCDELDLCI 0x8981
+#define SIOCDEVPRIVATE 0x89F0
+#define SIOCPROTOPRIVATE 0x89E0
+
#ifdef __cplusplus
}
#endif
diff --git a/system/include/sys/select.h b/system/include/sys/select.h
index a5c73147..d6957fea 100644
--- a/system/include/sys/select.h
+++ b/system/include/sys/select.h
@@ -1,6 +1,8 @@
#ifndef _SELECT_H
#define _SELECT_H
+#include <unistd.h>
+
#ifdef __cplusplus
extern "C" {
#endif
diff --git a/system/include/sys/socket.h b/system/include/sys/socket.h
index 9650bb9a..abc0aa62 100644
--- a/system/include/sys/socket.h
+++ b/system/include/sys/socket.h
@@ -4,44 +4,196 @@
#include <netdb.h>
#include <sys/select.h>
#include <sys/uio.h>
+#include <unistd.h>
#ifdef __cplusplus
extern "C" {
#endif
-// Note that the values of these constants are mostly arbitrary numbers.
+#define SOCK_STREAM 1
+#define SOCK_DGRAM 2
+#define SOCK_RAW 3
+#define SOCK_RDM 4
+#define SOCK_SEQPACKET 5
+#define SOCK_DCCP 6
+#define SOCK_PACKET 10
+#define SOCK_CLOEXEC 02000000
+#define SOCK_NONBLOCK 04000
+
+#define PF_UNSPEC 0
+#define PF_LOCAL 1
+#define PF_UNIX PF_LOCAL
+#define PF_FILE PF_LOCAL
+#define PF_INET 2
+#define PF_AX25 3
+#define PF_IPX 4
+#define PF_APPLETALK 5
+#define PF_NETROM 6
+#define PF_BRIDGE 7
+#define PF_ATMPVC 8
+#define PF_X25 9
+#define PF_INET6 10
+#define PF_ROSE 11
+#define PF_DECnet 12
+#define PF_NETBEUI 13
+#define PF_SECURITY 14
+#define PF_KEY 15
+#define PF_NETLINK 16
+#define PF_ROUTE PF_NETLINK
+#define PF_PACKET 17
+#define PF_ASH 18
+#define PF_ECONET 19
+#define PF_ATMSVC 20
+#define PF_RDS 21
+#define PF_SNA 22
+#define PF_IRDA 23
+#define PF_PPPOX 24
+#define PF_WANPIPE 25
+#define PF_LLC 26
+#define PF_CAN 29
+#define PF_TIPC 30
+#define PF_BLUETOOTH 31
+#define PF_IUCV 32
+#define PF_RXRPC 33
+#define PF_ISDN 34
+#define PF_PHONET 35
+#define PF_IEEE802154 36
+#define PF_CAIF 37
+#define PF_ALG 38
+#define PF_NFC 39
+#define PF_MAX 40
+
+#define AF_UNSPEC PF_UNSPEC
+#define AF_LOCAL PF_LOCAL
+#define AF_UNIX PF_UNIX
+#define AF_FILE PF_FILE
+#define AF_INET PF_INET
+#define AF_AX25 PF_AX25
+#define AF_IPX PF_IPX
+#define AF_APPLETALK PF_APPLETALK
+#define AF_NETROM PF_NETROM
+#define AF_BRIDGE PF_BRIDGE
+#define AF_ATMPVC PF_ATMPVC
+#define AF_X25 PF_X25
+#define AF_INET6 PF_INET6
+#define AF_ROSE PF_ROSE
+#define AF_DECnet PF_DECnet
+#define AF_NETBEUI PF_NETBEUI
+#define AF_SECURITY PF_SECURITY
+#define AF_KEY PF_KEY
+#define AF_NETLINK PF_NETLINK
+#define AF_ROUTE PF_ROUTE
+#define AF_PACKET PF_PACKET
+#define AF_ASH PF_ASH
+#define AF_ECONET PF_ECONET
+#define AF_ATMSVC PF_ATMSVC
+#define AF_RDS PF_RDS
+#define AF_SNA PF_SNA
+#define AF_IRDA PF_IRDA
+#define AF_PPPOX PF_PPPOX
+#define AF_WANPIPE PF_WANPIPE
+#define AF_LLC PF_LLC
+#define AF_CAN PF_CAN
+#define AF_TIPC PF_TIPC
+#define AF_BLUETOOTH PF_BLUETOOTH
+#define AF_IUCV PF_IUCV
+#define AF_RXRPC PF_RXRPC
+#define AF_ISDN PF_ISDN
+#define AF_PHONET PF_PHONET
+#define AF_IEEE802154 PF_IEEE802154
+#define AF_CAIF PF_CAIF
+#define AF_ALG PF_ALG
+#define AF_NFC PF_NFC
+#define AF_MAX PF_MAX
+
#define SOMAXCONN 128
-#define PF_LOCAL 1
-#define PF_UNIX PF_LOCAL
-#define PF_INET 2
-#define SO_BROADCAST 6
-#define AF_UNIX PF_UNIX
-
-#define AF_UNSPEC 0
-#define SOCK_STREAM 200
-#define SOL_SOCKET 50
-#define SO_ERROR 10
-#define SOCK_DGRAM 20
-#define SO_REUSEADDR 30
-#define SO_SNDBUF 40
-#define SO_RCVBUF 60
-#define SO_LINGER 70
-#define SO_NOSIGPIPE 80
-#define SO_KEEPALIVE 90
-#define SO_OOBINLINE 100
-#define SO_NO_CHECK 110
-#define SO_PRIORITY 120
-#define SO_LINGER 130
-#define SO_BSDCOMPAT 140
+
+#define SOL_SOCKET 1
+
+#define SO_DEBUG 1
+#define SO_REUSEADDR 2
+#define SO_TYPE 3
+#define SO_ERROR 4
+#define SO_DONTROUTE 5
+#define SO_BROADCAST 6
+#define SO_SNDBUF 7
+#define SO_RCVBUF 8
+#define SO_SNDBUFFORCE 32
+#define SO_RCVBUFFORCE 33
+#define SO_KEEPALIVE 9
+#define SO_OOBINLINE 10
+#define SO_NO_CHECK 11
+#define SO_PRIORITY 12
+#define SO_LINGER 13
+#define SO_BSDCOMPAT 14
+#ifndef SO_PASSCRED
+#define SO_PASSCRED 16
+#define SO_PEERCRED 17
+#define SO_RCVLOWAT 18
+#define SO_SNDLOWAT 19
+#define SO_RCVTIMEO 20
+#define SO_SNDTIMEO 21
+#endif
+#define SO_SECURITY_AUTHENTICATION 22
+#define SO_SECURITY_ENCRYPTION_TRANSPORT 23
+#define SO_SECURITY_ENCRYPTION_NETWORK 24
+#define SO_BINDTODEVICE 25
+#define SO_ATTACH_FILTER 26
+#define SO_DETACH_FILTER 27
+#define SO_PEERNAME 28
+#define SO_TIMESTAMP 29
+#define SCM_TIMESTAMP SO_TIMESTAMP
+#define SO_ACCEPTCONN 30
+#define SO_PEERSEC 31
+#define SO_PASSSEC 34
+#define SO_TIMESTAMPNS 35
+#define SCM_TIMESTAMPNS SO_TIMESTAMPNS
+#define SO_MARK 36
+#define SO_TIMESTAMPING 37
+#define SCM_TIMESTAMPING SO_TIMESTAMPING
+#define SO_PROTOCOL 38
+#define SO_DOMAIN 39
+#define SO_RXQ_OVFL 40
+
+#if __BSD_VISIBLE
+#define SO_NOSIGPIPE 0x0800
+#endif
+
+#define MSG_OOB 0x01
+#define MSG_PEEK 0x02
+#define MSG_DONTROUTE 0x04
+#ifdef __USE_GNU
+# define MSG_TRYHARD MSG_DONTROUTE
+#endif
+#define MSG_CTRUNC 0x08
+#define MSG_PROXY 0x10
+#define MSG_TRUNC 0x20
+#define MSG_DONTWAIT 0x40
+#define MSG_EOR 0x80
+#define MSG_WAITALL 0x100
+#define MSG_FIN 0x200
+#define MSG_SYN 0x400
+#define MSG_CONFIRM 0x800
+#define MSG_RST 0x1000
+#define MSG_ERRQUEUE 0x2000
+#define MSG_NOSIGNAL 0x4000
+#define MSG_MORE 0x8000
+#define MSG_WAITFORONE 0x10000
+#define MSG_CMSG_CLOEXEC 0x40000000
#define SHUT_RD 0
#define SHUT_WR 1
#define SHUT_RDWR 2
+#define FIOSETOWN 0x8901
+#define SIOCSPGRP 0x8902
+#define FIOGETOWN 0x8903
+#define SIOCGPGRP 0x8904
+#define SIOCATMARK 0x8905
+#define SIOCGSTAMP 0x8906
+#define SIOCGSTAMPNS 0x8907
+
typedef unsigned int sa_family_t;
-#define AF_INET PF_INET
-#define AF_INET6 6
-#define PF_INET6 AF_INET6
struct sockaddr {
sa_family_t sa_family;
@@ -87,13 +239,6 @@ struct linger {
int l_linger;
};
-#define SIOCATMARK 0x8905
-
-#define SOCK_RAW 111
-#define SOCK_SEQPACKET 555
-
-#define PF_APPLETALK 5
-
#ifdef __cplusplus
}
#endif
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..75b1f348 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'''
@@ -4062,17 +4083,11 @@ def process(filename):
self.do_run(src, 'Inline JS is very cool\n3.64')
- def zzztest_inlinejs2(self):
+ def test_inlinejs2(self):
if Settings.ASM_JS: return self.skip('asm does not support random code, TODO: something that works in asm')
src = r'''
#include <stdio.h>
- double get() {
- double ret = 0;
- __asm __volatile__("Math.abs(-12/3.3)":"=r"(ret)); // write to a variable
- return ret;
- }
-
int mix(int x, int y) {
int ret;
asm("Math.pow(2, %0+%1+1)" : "=r"(ret) : "r"(x), "r"(y)); // read and write
@@ -4085,15 +4100,13 @@ def process(filename):
}
int main(int argc, char **argv) {
- asm("Module.print('Inline JS is very cool')");
- printf("%.2f\n", get());
printf("%d\n", mix(argc, argc/2));
mult();
return 0;
}
'''
- self.do_run(src, 'Inline JS is very cool\n3.64\nwaka\nzakai\n')
+ self.do_run(src, '4\n200\n')
def test_memorygrowth(self):
if Settings.USE_TYPED_ARRAYS == 0: return self.skip('memory growth is only supported with typed arrays')
@@ -7089,7 +7102,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 +7134,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 +7777,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 +9176,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 +11056,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 +11223,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 +11263,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':
@@ -11652,6 +11677,39 @@ int main(int argc, char const *argv[])
self.assertContained('a\nb\n', run_js(os.path.join(self.get_dir(), 'a.out.js')))
+ def test_export_in_a(self):
+ export_name = 'this_is_an_entry_point'
+
+ open('export.c', 'w').write(r'''
+ #include <stdio.h>
+ void %s(void) {
+ printf("Hello, world!\n");
+ }
+ ''' % export_name)
+ Popen([PYTHON, EMCC, 'export.c', '-c', '-o', 'export.o']).communicate()
+ Popen([PYTHON, EMAR, 'rc', 'libexport.a', 'export.o']).communicate()
+
+ open('main.c', 'w').write(r'''
+ int main() {
+ return 0;
+ }
+ ''')
+
+ definition = 'function _%s(' % export_name
+
+ # Sanity check: the symbol should not be linked in if not requested.
+ Popen([PYTHON, EMCC, 'main.c', '-L.', '-lexport']).communicate()
+ self.assertNotContained(definition, open(os.path.join(self.get_dir(), 'a.out.js')).read())
+
+ # Sanity check: exporting without a definition does not cause it to appear.
+ # Note: exporting main prevents emcc from warning that it generated no code.
+ Popen([PYTHON, EMCC, 'main.c', '-s', '''EXPORTED_FUNCTIONS=['_main', '_%s']''' % export_name]).communicate()
+ self.assertNotContained(definition, open(os.path.join(self.get_dir(), 'a.out.js')).read())
+
+ # Actual test: defining symbol in library and exporting it causes it to appear in the output.
+ Popen([PYTHON, EMCC, 'main.c', '-L.', '-lexport', '-s', '''EXPORTED_FUNCTIONS=['_%s']''' % export_name]).communicate()
+ self.assertContained(definition, open(os.path.join(self.get_dir(), 'a.out.js')).read())
+
def test_embed_file(self):
open(os.path.join(self.get_dir(), 'somefile.txt'), 'w').write('''hello from a file with lots of data and stuff in it thank you very much''')
open(os.path.join(self.get_dir(), 'main.cpp'), 'w').write(r'''
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;
diff --git a/tools/shared.py b/tools/shared.py
index c3b2da87..f6d0ff4f 100644
--- a/tools/shared.py
+++ b/tools/shared.py
@@ -883,7 +883,10 @@ set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)''' % { 'winfix': '' if not WINDOWS e
@staticmethod
def link(files, target, force_archive_contents=False):
actual_files = []
- unresolved_symbols = set(['main']) # tracking unresolveds is necessary for .a linking, see below. (and main is always a necessary symbol)
+ # Tracking unresolveds is necessary for .a linking, see below.
+ # Specify all possible entry points to seed the linking process.
+ # For a simple application, this would just be "main".
+ unresolved_symbols = set([func[1:] for func in Settings.EXPORTED_FUNCTIONS])
resolved_symbols = set()
temp_dirs = []
files = map(os.path.abspath, files)