summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AUTHORS1
-rwxr-xr-xemcc19
-rwxr-xr-xemscripten.py5
-rwxr-xr-xscons-tools/emscripten.py17
-rwxr-xr-xscons-tools/llvm.py7
-rw-r--r--src/intertyper.js6
-rw-r--r--src/library.js326
-rw-r--r--src/library_browser.js6
-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.js14
-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.py146
-rw-r--r--tools/asm_module.py2
-rw-r--r--tools/js-optimizer.js9
-rw-r--r--tools/shared.py16
31 files changed, 819 insertions, 316 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..0eb4499b 100755
--- a/emcc
+++ b/emcc
@@ -462,6 +462,12 @@ Options that are modified or new in %s include:
memory initialization data embedded inside
JavaScript as text. (default is off)
+ -Wno-warn-absolute-paths If not specified, the compiler will warn about any
+ uses of absolute paths in -I and -L command line
+ directives. Pass this flag on the command line
+ to hide these warnings and acknowledge that the
+ explicit use of absolute paths is intentional.
+
The target file, if specified (-o <target>), defines what will
be generated:
@@ -735,6 +741,12 @@ try:
absolute_warning_shown = False
+ # Scan for warning suppression message in advance from other cmdline flags, so that it works even if -I or -L directives are present before this.
+ for i in range(len(newargs)):
+ if newargs[i] == '-Wno-warn-absolute-paths':
+ newargs[i] = ''
+ absolute_warning_shown = True
+
settings_changes = []
def validate_arg_level(level_string, max_level, err_msg):
@@ -879,7 +891,7 @@ try:
elif newargs[i].startswith(('-I', '-L')):
path_name = newargs[i][2:]
if not absolute_warning_shown and os.path.isabs(path_name):
- logging.warning ('-I or -L of an absolute path "' + newargs[i] + '" encountered. If this is to a local system header/library, it may cause problems (local system files make sense for compiling natively on your system, but not necessarily to JavaScript)') # Of course an absolute path to a non-system-specific library or header is fine, and you can ignore this warning. The danger are system headers that are e.g. x86 specific and nonportable. The emscripten bundled headers are modified to be portable, local system ones are generally not
+ logging.warning ('-I or -L of an absolute path "' + newargs[i] + '" encountered. If this is to a local system header/library, it may cause problems (local system files make sense for compiling natively on your system, but not necessarily to JavaScript). Pass \'-Wno-warn-absolute-paths\' to emcc to hide this warning.') # Of course an absolute path to a non-system-specific library or header is fine, and you can ignore this warning. The danger are system headers that are e.g. x86 specific and nonportable. The emscripten bundled headers are modified to be portable, local system ones are generally not
absolute_warning_shown = True
newargs = [ arg for arg in newargs if arg is not '' ]
@@ -1285,6 +1297,11 @@ try:
'wctob.c',
'wctomb.c',
]],
+ ['stdlib', [
+ 'ecvt.c',
+ 'fcvt.c',
+ 'gcvt.c',
+ ]],
['string', [
'wcpcpy.c',
'wcpncpy.c',
diff --git a/emscripten.py b/emscripten.py
index ab68fcaa..aa47e4f1 100755
--- a/emscripten.py
+++ b/emscripten.py
@@ -11,7 +11,6 @@ headers, for the libc implementation in JS).
import os, sys, json, optparse, subprocess, re, time, multiprocessing, string
-from tools import shared
from tools import jsrun, cache as cache_module, tempfiles
from tools.response_file import read_response_file
@@ -26,6 +25,7 @@ def get_configuration():
if hasattr(get_configuration, 'configuration'):
return get_configuration.configuration
+ from tools import shared
configuration = shared.Configuration(environ=os.environ)
get_configuration.configuration = configuration
return configuration
@@ -469,6 +469,7 @@ def emscript(infile, settings, outfile, libraries=[], compiler_engine=None,
}
''' % (sig, i, args, arg_coercions, jsret))
+ from tools import shared
asm_setup += '\n' + shared.JS.make_invoke(sig) + '\n'
basic_funcs.append('invoke_%s' % sig)
@@ -807,7 +808,7 @@ WARNING: You should normally never use this! Use emcc instead.
'''
if len(positional) != 1:
- raise RuntimeError('Must provide exactly one positional argument.')
+ raise RuntimeError('Must provide exactly one positional argument. Got ' + str(len(positional)) + ': "' + '", "'.join(positional) + '"')
keywords.infile = os.path.abspath(positional[0])
if isinstance(keywords.outfile, basestring):
keywords.outfile = open(keywords.outfile, 'w')
diff --git a/scons-tools/emscripten.py b/scons-tools/emscripten.py
index 473c51ad..b4912aaa 100755
--- a/scons-tools/emscripten.py
+++ b/scons-tools/emscripten.py
@@ -24,6 +24,7 @@ def build_version_file(env):
EMSCRIPTEN_DEPENDENCIES = [
env.Glob('${EMSCRIPTEN_HOME}/src/*.js'),
+ env.Glob('${EMSCRIPTEN_HOME}/src/embind/*.js'),
env.Glob('${EMSCRIPTEN_HOME}/tools/*.py'),
'${EMSCRIPTEN_HOME}/emscripten.py',
]
@@ -141,7 +142,7 @@ def emscripten(env, target_js, source_bc):
[global_emscripten_min_js] = env.JSOptimizer(
buildName('global.min.js'),
closure_js,
- JS_OPTIMIZER_PASSES=['simplifyExpressionsPost', 'compress', 'last'])
+ JS_OPTIMIZER_PASSES=['simplifyExpressionsPost', 'minifyWhitespace', 'last'])
[emscripten_iteration_js] = env.WrapInModule(
buildName('iteration.js'),
@@ -155,8 +156,6 @@ def emscripten(env, target_js, source_bc):
buildName('min.js'),
global_emscripten_min_js)
- env.InstallAs(buildName('js'), emscripten_js)
-
return [emscripten_iteration_js, emscripten_js, emscripten_min_js]
LIBC_SOURCES = [
@@ -265,9 +264,9 @@ def generate(env):
)
env.Replace(
- CC='${LLVM_ROOT}/${CLANG}',
- CXX='${LLVM_ROOT}/${CLANGXX}',
- AR='${LLVM_ROOT}/${LLVM_LINK}',
+ CC=os.path.join('${LLVM_ROOT}', '${CLANG}'),
+ CXX=os.path.join('${LLVM_ROOT}', '${CLANGXX}'),
+ AR=os.path.join('${LLVM_ROOT}', '${LLVM_LINK}'),
ARCOM='$AR -o $TARGET $SOURCES',
OBJSUFFIX='.bc',
LIBPREFIX='',
@@ -301,6 +300,12 @@ def generate(env):
'__IEEE_LITTLE_ENDIAN',
])
+ env.Append(
+ CPPPATH=[
+ env.Dir('${EMSCRIPTEN_HOME}/system/include'),
+ ]
+ )
+
env['BUILDERS']['Emscripten'] = Builder(
action='$PYTHON ${EMSCRIPTEN_HOME}/emscripten.py $EMSCRIPTEN_FLAGS $_EMSCRIPTEN_SETTINGS_FLAGS --temp-dir=$EMSCRIPTEN_TEMP_DIR --compiler $JS_ENGINE --relooper=third-party/relooper.js $SOURCE > $TARGET',
target_scanner=EmscriptenScanner)
diff --git a/scons-tools/llvm.py b/scons-tools/llvm.py
index f272bd16..2dc65dd3 100755
--- a/scons-tools/llvm.py
+++ b/scons-tools/llvm.py
@@ -1,5 +1,6 @@
from SCons.Scanner.Prog import scan
from SCons.Builder import Builder
+import os
def exists(env):
return True
@@ -23,11 +24,11 @@ def generate(env):
LLVM_LINK='llvm-link')
env['BUILDERS']['LLVMDis'] = Builder(
- action='${LLVM_ROOT}/$LLVM_DIS -o=$TARGET $SOURCE')
+ action=os.path.join('${LLVM_ROOT}', '$LLVM_DIS') + ' -o=$TARGET $SOURCE')
env['BUILDERS']['LLVMOpt'] = Builder(
- action='${LLVM_ROOT}/$LLVM_OPT $LLVM_OPT_FLAGS $LLVM_OPT_PASSES -o=$TARGET $SOURCE')
+ action=os.path.join('${LLVM_ROOT}', '$LLVM_OPT') + ' $LLVM_OPT_FLAGS $LLVM_OPT_PASSES -o=$TARGET $SOURCE')
env['BUILDERS']['LLVMLink'] = Builder(
- action='${LLVM_ROOT}/$LLVM_LINK -o=$TARGET $SOURCES',
+ action=os.path.join('${LLVM_ROOT}', '$LLVM_LINK') + ' -o=$TARGET $SOURCES',
emitter=add_libraries)
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 a73d4dc9..591d4350 100644
--- a/src/library.js
+++ b/src/library.js
@@ -56,7 +56,7 @@ LibraryManager.library = {
// to modify the filesystem freely before run() is called.
ignorePermissions: true,
- ErrnoError: function (errno) {
+ ErrnoError: function(errno) {
this.errno = errno;
for (var key in ERRNO_CODES) {
if (ERRNO_CODES[key] === errno) {
@@ -75,19 +75,19 @@ LibraryManager.library = {
//
// 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,31 +149,31 @@ 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') }}};
},
@@ -183,7 +183,7 @@ LibraryManager.library = {
cwd: function() {
return FS.currentPath;
},
- lookupPath: function (path, opts) {
+ lookupPath: function(path, opts) {
path = PATH.resolve(FS.currentPath, path);
opts = opts || { recurse_count: 0 };
@@ -192,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);
@@ -236,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)) {
@@ -268,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);
@@ -276,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') }}})) {
@@ -284,7 +284,7 @@ LibraryManager.library = {
}
return perms;
},
- nodePermissions: function (node, perms) {
+ nodePermissions: function(node, perms) {
if (FS.ignorePermissions) {
return 0;
}
@@ -298,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') }}}:
@@ -313,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;
@@ -321,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);
@@ -346,7 +346,7 @@ LibraryManager.library = {
}
return 0;
},
- mayOpen: function (node, flags) {
+ mayOpen: function(node, flags) {
if (!node) {
return ERRNO_CODES.ENOENT;
}
@@ -371,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;
@@ -380,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];
},
@@ -404,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++) {
@@ -414,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
@@ -468,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
@@ -506,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;
@@ -524,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];
@@ -538,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;
@@ -564,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 });
@@ -592,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) {
@@ -613,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);
@@ -637,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;
@@ -645,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;
@@ -675,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]);
@@ -691,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);
},
@@ -833,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);
}
@@ -843,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
@@ -911,7 +911,7 @@ LibraryManager.library = {
$VFS__deps: ['$FS'],
$VFS: {
- mount: function (type, opts, mountpoint) {
+ mount: function(type, opts, mountpoint) {
var mount = {
type: type,
opts: opts,
@@ -937,11 +937,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);
@@ -955,21 +955,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);
@@ -982,7 +982,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);
@@ -1064,7 +1064,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);
@@ -1082,7 +1082,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);
@@ -1102,7 +1102,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) {
@@ -1110,7 +1110,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) {
@@ -1118,10 +1118,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 });
@@ -1137,17 +1137,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 });
@@ -1163,17 +1163,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);
}
@@ -1202,7 +1202,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);
@@ -1212,14 +1212,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') }}})) {
@@ -1283,7 +1283,7 @@ LibraryManager.library = {
}
return stream;
},
- close: function (stream) {
+ close: function(stream) {
try {
if (stream.stream_ops.close) {
stream.stream_ops.close(stream);
@@ -1294,19 +1294,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);
}
@@ -1330,7 +1330,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);
}
@@ -1358,7 +1358,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);
}
@@ -1373,7 +1373,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);
@@ -1387,10 +1387,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);
@@ -1416,7 +1416,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;
@@ -1444,7 +1444,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;
}
@@ -1457,13 +1457,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;
@@ -1482,22 +1482,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);
}
@@ -1505,7 +1505,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 = ['.', '..']
@@ -1518,7 +1518,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
@@ -1533,7 +1533,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++) {
@@ -1542,7 +1542,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;
@@ -1558,15 +1558,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);
}
@@ -1604,7 +1604,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;
@@ -1621,12 +1621,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();
@@ -1638,13 +1638,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);
}
@@ -1668,7 +1668,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);
}
@@ -1688,7 +1688,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) {
@@ -1717,7 +1717,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 = [];
@@ -1727,7 +1727,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 = [];
@@ -1822,7 +1822,7 @@ LibraryManager.library = {
}
if (stream.position < 0 || stream.position >= entries.length) {
{{{ makeSetValue('result', '0', '0', 'i8*') }}}
- return;
+ return 0;
}
var id;
var type;
@@ -2104,7 +2104,7 @@ LibraryManager.library = {
}
},
lchmod__deps: ['chmod'],
- lchmod: function (path, mode) {
+ lchmod: function(path, mode) {
path = Pointer_stringify(path);
try {
VFS.lchmod(path, mode);
@@ -2703,6 +2703,11 @@ 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) {
FS.handleFSError(e);
@@ -2725,6 +2730,11 @@ 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) {
FS.handleFSError(e);
@@ -2826,6 +2836,11 @@ 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) {
FS.handleFSError(e);
@@ -2843,11 +2858,16 @@ 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) {
FS.handleFSError(e);
@@ -2979,7 +2999,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') }}})) {
@@ -5141,7 +5161,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
@@ -5154,7 +5174,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;
@@ -5706,17 +5726,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') }}};
@@ -6368,7 +6378,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;
@@ -6400,7 +6410,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;
@@ -8944,7 +8954,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({
@@ -9089,7 +9099,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;
@@ -9110,7 +9120,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;
@@ -9166,7 +9176,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;
@@ -9218,6 +9228,7 @@ LibraryManager.library = {
return ret;
},
+ shutdown__deps: ['$FS'],
shutdown: function(fd, how) {
var stream = FS.getStream(fd);
if (!stream) return -1;
@@ -9225,6 +9236,7 @@ LibraryManager.library = {
FS.closeStream(stream);
},
+ ioctl__deps: ['$FS'],
ioctl: function(fd, request, varargs) {
var info = FS.getStream(fd);
if (!info) return -1;
@@ -9242,6 +9254,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,
@@ -9256,6 +9269,7 @@ LibraryManager.library = {
return fd;
},
+ select__deps: ['$FS'],
select: function(nfds, readfds, writefds, exceptfds, timeout) {
// readfds are supported,
// writefds checks socket open status
@@ -9310,7 +9324,7 @@ LibraryManager.library = {
}
},
#else
- socket__deps: ['$Sockets'],
+ socket__deps: ['$FS', '$Sockets'],
socket: function(family, type, protocol) {
var stream = type == {{{ cDefine('SOCK_STREAM') }}};
if (protocol) {
@@ -9583,6 +9597,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;
@@ -9590,6 +9605,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_browser.js b/src/library_browser.js
index 4a322a54..f65791e4 100644
--- a/src/library_browser.js
+++ b/src/library_browser.js
@@ -61,7 +61,11 @@ mergeInto(LibraryManager.library, {
console.log("warning: no blob constructor, cannot create blobs with mimetypes");
}
Browser.BlobBuilder = typeof MozBlobBuilder != "undefined" ? MozBlobBuilder : (typeof WebKitBlobBuilder != "undefined" ? WebKitBlobBuilder : (!Browser.hasBlobConstructor ? console.log("warning: no BlobBuilder") : null));
- Browser.URLObject = typeof window != "undefined" ? (window.URL ? window.URL : window.webkitURL) : console.log("warning: cannot create object URLs");
+ Browser.URLObject = typeof window != "undefined" ? (window.URL ? window.URL : window.webkitURL) : undefined;
+ if (!Module.noImageDecoding && typeof Browser.URLObject === 'undefined') {
+ console.log("warning: Browser does not support creating object URLs. Built-in browser image decoding will not be available.");
+ Module.noImageDecoding = true;
+ }
// Support for plugins that can process preloaded files. You can add more of these to
// your app by creating and appending to Module.preloadPlugins.
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 feec1e68..2c2c016a 100644
--- a/src/library_path.js
+++ b/src/library_path.js
@@ -3,11 +3,11 @@ mergeInto(LibraryManager.library, {
$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--) {
@@ -30,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
@@ -45,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];
@@ -59,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];
@@ -68,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') {
@@ -77,7 +77,7 @@ mergeInto(LibraryManager.library, {
return p;
}).join('/'));
},
- resolve: function () {
+ resolve: function() {
var resolvedPath = '',
resolvedAbsolute = false;
for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) {
diff --git a/src/library_sdl.js b/src/library_sdl.js
index e46b41f5..64984628 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;
}
};
@@ -2108,7 +2108,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 83d62946..8196053d 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,26 @@ 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):
+ if self.emcc_args is None: return self.skip('requires emcc')
+
+ 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 +4085,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 +4102,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 +7104,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 +7136,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 +7779,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 +9178,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 +11058,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 +11225,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 +11265,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':
@@ -11424,6 +11451,8 @@ int main(int argc, char const *argv[])
for args, expected in [(['-I/usr/something'], True),
(['-L/usr/something'], True),
+ (['-I/usr/something', '-Wno-warn-absolute-paths'], False),
+ (['-L/usr/something', '-Wno-warn-absolute-paths'], False),
(['-Isubdir/something'], False),
(['-Lsubdir/something'], False),
([], False)]:
@@ -11652,6 +11681,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 c0df227d..f6d0ff4f 100644
--- a/tools/shared.py
+++ b/tools/shared.py
@@ -360,8 +360,15 @@ def check_sanity(force=False):
# Tools/paths
-LLVM_ADD_VERSION = os.getenv('LLVM_ADD_VERSION')
-CLANG_ADD_VERSION = os.getenv('CLANG_ADD_VERSION')
+try:
+ LLVM_ADD_VERSION
+except NameError:
+ LLVM_ADD_VERSION = os.getenv('LLVM_ADD_VERSION')
+
+try:
+ CLANG_ADD_VERSION
+except NameError:
+ CLANG_ADD_VERSION = os.getenv('CLANG_ADD_VERSION')
# Some distributions ship with multiple llvm versions so they add
# the version to the binaries, cope with that
@@ -876,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)