diff options
-rw-r--r-- | AUTHORS | 1 | ||||
-rwxr-xr-x | emcc | 5 | ||||
-rwxr-xr-x | emscripten.py | 5 | ||||
-rwxr-xr-x | scons-tools/emscripten.py | 17 | ||||
-rwxr-xr-x | scons-tools/llvm.py | 7 | ||||
-rw-r--r-- | src/intertyper.js | 6 | ||||
-rw-r--r-- | src/library.js | 326 | ||||
-rw-r--r-- | src/library_egl.js | 9 | ||||
-rw-r--r-- | src/library_glut.js | 2 | ||||
-rw-r--r-- | src/library_openal.js | 14 | ||||
-rw-r--r-- | src/library_path.js | 14 | ||||
-rw-r--r-- | src/library_sdl.js | 4 | ||||
-rw-r--r-- | src/preamble.js | 9 | ||||
-rw-r--r-- | src/settings.js | 16 | ||||
-rw-r--r-- | src/shell.js | 53 | ||||
-rw-r--r-- | system/include/libc/sys/signal.h | 4 | ||||
-rw-r--r-- | system/include/net/if.h | 21 | ||||
-rw-r--r-- | system/include/net/netinet/in.h | 67 | ||||
-rw-r--r-- | system/include/netdb.h | 36 | ||||
-rw-r--r-- | system/include/sys/ioctl.h | 58 | ||||
-rw-r--r-- | system/include/sys/select.h | 2 | ||||
-rw-r--r-- | system/include/sys/socket.h | 211 | ||||
-rw-r--r-- | system/lib/libc/musl/src/stdlib/ecvt.c | 19 | ||||
-rw-r--r-- | system/lib/libc/musl/src/stdlib/fcvt.c | 25 | ||||
-rw-r--r-- | system/lib/libc/musl/src/stdlib/gcvt.c | 8 | ||||
-rw-r--r-- | system/lib/libcextra.symbols | 3 | ||||
-rwxr-xr-x | tests/runner.py | 92 | ||||
-rw-r--r-- | tools/asm_module.py | 2 | ||||
-rw-r--r-- | tools/shared.py | 16 |
29 files changed, 770 insertions, 282 deletions
@@ -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.) @@ -1297,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 f48220bb..a6a38cfe 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 @@ -909,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, @@ -935,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); @@ -953,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); @@ -980,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); @@ -1062,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); @@ -1080,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); @@ -1100,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) { @@ -1108,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) { @@ -1116,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 }); @@ -1135,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 }); @@ -1161,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); } @@ -1200,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); @@ -1210,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') }}})) { @@ -1281,7 +1281,7 @@ LibraryManager.library = { } return stream; }, - close: function (stream) { + close: function(stream) { try { if (stream.stream_ops.close) { stream.stream_ops.close(stream); @@ -1292,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); } @@ -1328,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); } @@ -1356,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); } @@ -1371,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); @@ -1385,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); @@ -1414,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; @@ -1442,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; } @@ -1455,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; @@ -1480,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); } @@ -1503,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 = ['.', '..'] @@ -1516,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 @@ -1531,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++) { @@ -1540,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; @@ -1556,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); } @@ -1602,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; @@ -1619,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(); @@ -1636,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); } @@ -1666,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); } @@ -1686,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) { @@ -1715,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 = []; @@ -1725,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 = []; @@ -1820,7 +1820,7 @@ LibraryManager.library = { } if (stream.position < 0 || stream.position >= entries.length) { {{{ makeSetValue('result', '0', '0', 'i8*') }}} - return; + return 0; } var id; var type; @@ -2102,7 +2102,7 @@ LibraryManager.library = { } }, lchmod__deps: ['chmod'], - lchmod: function (path, mode) { + lchmod: function(path, mode) { path = Pointer_stringify(path); try { VFS.lchmod(path, mode); @@ -2701,6 +2701,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); @@ -2723,6 +2728,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); @@ -2824,6 +2834,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); @@ -2841,11 +2856,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); @@ -2977,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') }}})) { @@ -5139,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 @@ -5152,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; @@ -5704,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') }}}; @@ -6366,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; @@ -6398,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; @@ -8942,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({ @@ -9087,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; @@ -9108,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; @@ -9164,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; @@ -9216,6 +9226,7 @@ LibraryManager.library = { return ret; }, + shutdown__deps: ['$FS'], shutdown: function(fd, how) { var stream = FS.getStream(fd); if (!stream) return -1; @@ -9223,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; @@ -9240,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, @@ -9254,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 @@ -9308,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) { @@ -9581,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; @@ -9588,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 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 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 c1924552..23ec07b9 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 ''' @@ -355,6 +355,9 @@ process(sys.argv[1]) 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): print >> sys.stderr, '<load %s from cache> ' % 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> @@ -11041,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> @@ -11646,6 +11679,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/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) |