aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorngld <ngld@tproxy.de>2013-09-16 23:49:19 +0200
committerngld <ngld@tproxy.de>2013-09-16 23:49:19 +0200
commit1600df2e360d0bbfd9195b3523dd3d0b440fe62a (patch)
tree8b6dc4e1f9b79520154025f5adbddc166eb069f7
parente0cd2c4078c5dbaecda881c9258f01d5069a1d02 (diff)
Integrate the new tool into emscripten
Automatically compile struct_info.json and save the compiled version in the emscripten cache.
-rwxr-xr-xemscripten.py9
-rw-r--r--src/compiler.js6
-rw-r--r--src/library.js593
-rw-r--r--src/parseTools.js3
-rw-r--r--src/struct_info.json822
-rw-r--r--tools/gen_struct_info.py335
-rw-r--r--tools/shared.py12
7 files changed, 1298 insertions, 482 deletions
diff --git a/emscripten.py b/emscripten.py
index 4d744fdd..e6a6e124 100755
--- a/emscripten.py
+++ b/emscripten.py
@@ -709,7 +709,14 @@ def main(args, compiler_engine, cache, jcache, relooper, temp_files, DEBUG, DEBU
if not os.path.exists(relooper):
from tools import shared
shared.Building.ensure_relooper(relooper)
-
+
+ settings.setdefault('STRUCT_INFO', cache.get_path('struct_info.compiled.json'))
+ struct_info = settings.get('STRUCT_INFO')
+
+ if not os.path.exists(struct_info):
+ from tools import shared
+ shared.Building.ensure_struct_info(struct_info)
+
emscript(args.infile, settings, args.outfile, libraries, compiler_engine=compiler_engine,
jcache=jcache, temp_files=temp_files, DEBUG=DEBUG, DEBUG_CACHE=DEBUG_CACHE)
diff --git a/src/compiler.js b/src/compiler.js
index f2b0dcbd..69824035 100644
--- a/src/compiler.js
+++ b/src/compiler.js
@@ -204,6 +204,12 @@ if (phase == 'pre') {
if (VERBOSE) printErr('VERBOSE is on, this generates a lot of output and can slow down compilation');
+// Load struct and define information.
+var temp = JSON.parse(read(STRUCT_INFO));
+C_STRUCTS = temp.structs;
+// NOTE: This overwrites C_DEFINES from settings.js, should this be fixed or will C_DEFINES in settings.js be deprecated?
+C_DEFINES = temp.defines;
+
// Load compiler code
load('framework.js');
diff --git a/src/library.js b/src/library.js
index aac5a9da..b45dd8f5 100644
--- a/src/library.js
+++ b/src/library.js
@@ -28,13 +28,7 @@ LibraryManager.library = {
// dirent.h
// ==========================================================================
- __dirent_struct_layout: Runtime.generateStructInfo([
- ['i32', 'd_ino'],
- ['i32', 'd_off'],
- ['i16', 'd_reclen'],
- ['i8', 'd_type'],
- ['b256', 'd_name']]),
- opendir__deps: ['$FS', '__setErrNo', '$ERRNO_CODES', '__dirent_struct_layout', 'open'],
+ opendir__deps: ['$FS', '__setErrNo', '$ERRNO_CODES', 'open'],
opendir: function(dirname) {
// DIR *opendir(const char *dirname);
// http://pubs.opengroup.org/onlinepubs/007908799/xsh/opendir.html
@@ -90,7 +84,7 @@ LibraryManager.library = {
// http://pubs.opengroup.org/onlinepubs/007908799/xsh/rewinddir.html
_seekdir(dirp, 0);
},
- readdir_r__deps: ['$FS', '__setErrNo', '$ERRNO_CODES', '__dirent_struct_layout'],
+ readdir_r__deps: ['$FS', '__setErrNo', '$ERRNO_CODES'],
readdir_r: function(dirp, entry, result) {
// int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result);
// http://pubs.opengroup.org/onlinepubs/007908799/xsh/readdir_r.html
@@ -123,14 +117,14 @@ LibraryManager.library = {
FS.isLink(child.mode) ? 10 : // DT_LNK, symbolic link.
8; // DT_REG, regular file.
}
- {{{ makeSetValue('entry', '___dirent_struct_layout.d_ino', 'id', 'i32') }}}
- {{{ makeSetValue('entry', '___dirent_struct_layout.d_off', 'offset', 'i32') }}}
- {{{ makeSetValue('entry', '___dirent_struct_layout.d_reclen', 'name.length + 1', 'i32') }}}
+ {{{ makeSetValue('entry', C_STRUCTS.dirent.d_ino, 'id', 'i32') }}}
+ {{{ makeSetValue('entry', C_STRUCTS.dirent.d_off, 'offset', 'i32') }}}
+ {{{ makeSetValue('entry', C_STRUCTS.dirent.d_reclen, 'name.length + 1', 'i32') }}}
for (var i = 0; i < name.length; i++) {
- {{{ makeSetValue('entry + ___dirent_struct_layout.d_name', 'i', 'name.charCodeAt(i)', 'i8') }}}
+ {{{ makeSetValue('entry + ' + C_STRUCTS.dirent.d_name, 'i', 'name.charCodeAt(i)', 'i8') }}}
}
- {{{ makeSetValue('entry + ___dirent_struct_layout.d_name', 'i', '0', 'i8') }}}
- {{{ makeSetValue('entry', '___dirent_struct_layout.d_type', 'type', 'i8') }}}
+ {{{ makeSetValue('entry + ' + C_STRUCTS.dirent.d_name, 'i', '0', 'i8') }}}
+ {{{ makeSetValue('entry', C_STRUCTS.dirent.d_type, 'type', 'i8') }}}
{{{ makeSetValue('result', '0', 'entry', 'i8*') }}}
stream.position++;
return 0;
@@ -145,7 +139,7 @@ LibraryManager.library = {
return 0;
}
// TODO Is it supposed to be safe to execute multiple readdirs?
- if (!_readdir.entry) _readdir.entry = _malloc(___dirent_struct_layout.__size__);
+ if (!_readdir.entry) _readdir.entry = _malloc({{{ C_STRUCTS.dirent.__size__ }}});
if (!_readdir.result) _readdir.result = _malloc(4);
var err = _readdir_r(dirp, _readdir.entry, _readdir.result);
if (err) {
@@ -161,17 +155,14 @@ LibraryManager.library = {
// utime.h
// ==========================================================================
- __utimbuf_struct_layout: Runtime.generateStructInfo([
- ['i32', 'actime'],
- ['i32', 'modtime']]),
- utime__deps: ['$FS', '__setErrNo', '$ERRNO_CODES', '__utimbuf_struct_layout'],
+ utime__deps: ['$FS', '__setErrNo', '$ERRNO_CODES'],
utime: function(path, times) {
// int utime(const char *path, const struct utimbuf *times);
// http://pubs.opengroup.org/onlinepubs/009695399/basedefs/utime.h.html
var time;
if (times) {
// NOTE: We don't keep track of access timestamps.
- var offset = ___utimbuf_struct_layout.modtime;
+ var offset = {{{ C_STRUCTS.utimbuf.modtime }}};
time = {{{ makeGetValue('times', 'offset', 'i32') }}}
time *= 1000;
} else {
@@ -253,27 +244,7 @@ LibraryManager.library = {
// sys/stat.h
// ==========================================================================
- __stat_struct_layout: Runtime.generateStructInfo([
- ['i32', 'st_dev'],
- ['i32', '__st_dev_padding'],
- ['i32', '__st_ino_truncated'],
- ['i32', 'st_mode'],
- ['i32', 'st_nlink'],
- ['i32', 'st_uid'],
- ['i32', 'st_gid'],
- ['i32', 'st_rdev'],
- ['i32', '__st_rdev_padding'],
- ['i32', 'st_size'],
- ['i32', 'st_blksize'],
- ['i32', 'st_blocks'],
- ['i32', 'st_atim_secs'],
- ['i32', 'st_atim_nsecs'],
- ['i32', 'st_mtim_secs'],
- ['i32', 'st_mtim_nsecs'],
- ['i32', 'st_ctim_secs'],
- ['i32', 'st_ctim_nsecs'],
- ['i32', 'st_ino']]),
- stat__deps: ['$FS', '__stat_struct_layout'],
+ stat__deps: ['$FS'],
stat: function(path, buf, dontResolveLastLink) {
// http://pubs.opengroup.org/onlinepubs/7908799/xsh/stat.html
// int stat(const char *path, struct stat *buf);
@@ -282,25 +253,25 @@ LibraryManager.library = {
path = typeof path !== 'string' ? Pointer_stringify(path) : path;
try {
var stat = dontResolveLastLink ? FS.lstat(path) : FS.stat(path);
- {{{ makeSetValue('buf', '___stat_struct_layout.st_dev', 'stat.dev', 'i32') }}};
- {{{ makeSetValue('buf', '___stat_struct_layout.__st_dev_padding', '0', 'i32') }}};
- {{{ makeSetValue('buf', '___stat_struct_layout.__st_ino_truncated', 'stat.ino', 'i32') }}};
- {{{ makeSetValue('buf', '___stat_struct_layout.st_mode', 'stat.mode', 'i32') }}}
- {{{ makeSetValue('buf', '___stat_struct_layout.st_nlink', 'stat.nlink', 'i32') }}}
- {{{ makeSetValue('buf', '___stat_struct_layout.st_uid', 'stat.uid', 'i32') }}}
- {{{ makeSetValue('buf', '___stat_struct_layout.st_gid', 'stat.gid', 'i32') }}}
- {{{ makeSetValue('buf', '___stat_struct_layout.st_rdev', 'stat.rdev', 'i32') }}}
- {{{ makeSetValue('buf', '___stat_struct_layout.__st_rdev_padding', '0', 'i32') }}};
- {{{ makeSetValue('buf', '___stat_struct_layout.st_size', 'stat.size', 'i32') }}}
- {{{ makeSetValue('buf', '___stat_struct_layout.st_blksize', '4096', 'i32') }}}
- {{{ makeSetValue('buf', '___stat_struct_layout.st_blocks', 'stat.blocks', 'i32') }}}
- {{{ makeSetValue('buf', '___stat_struct_layout.st_atim_secs', 'Math.floor(stat.atime.getTime() / 1000)', 'i32') }}}
- {{{ makeSetValue('buf', '___stat_struct_layout.st_atim_nsecs', '0', 'i32') }}}
- {{{ makeSetValue('buf', '___stat_struct_layout.st_mtim_secs', 'Math.floor(stat.mtime.getTime() / 1000)', 'i32') }}}
- {{{ makeSetValue('buf', '___stat_struct_layout.st_mtim_nsecs', '0', 'i32') }}}
- {{{ makeSetValue('buf', '___stat_struct_layout.st_ctim_secs', 'Math.floor(stat.ctime.getTime() / 1000)', 'i32') }}}
- {{{ makeSetValue('buf', '___stat_struct_layout.st_ctim_nsecs', '0', 'i32') }}}
- {{{ makeSetValue('buf', '___stat_struct_layout.st_ino', 'stat.ino', 'i32') }}}
+ {{{ makeSetValue('buf', C_STRUCTS.stat.st_dev, 'stat.dev', 'i32') }}};
+ {{{ makeSetValue('buf', C_STRUCTS.stat.__st_dev_padding, '0', 'i32') }}};
+ {{{ makeSetValue('buf', C_STRUCTS.stat.__st_ino_truncated, 'stat.ino', 'i32') }}};
+ {{{ makeSetValue('buf', C_STRUCTS.stat.st_mode, 'stat.mode', 'i32') }}}
+ {{{ makeSetValue('buf', C_STRUCTS.stat.st_nlink, 'stat.nlink', 'i32') }}}
+ {{{ makeSetValue('buf', C_STRUCTS.stat.st_uid, 'stat.uid', 'i32') }}}
+ {{{ makeSetValue('buf', C_STRUCTS.stat.st_gid, 'stat.gid', 'i32') }}}
+ {{{ makeSetValue('buf', C_STRUCTS.stat.st_rdev, 'stat.rdev', 'i32') }}}
+ {{{ makeSetValue('buf', C_STRUCTS.stat.__st_rdev_padding, '0', 'i32') }}};
+ {{{ makeSetValue('buf', C_STRUCTS.stat.st_size, 'stat.size', 'i32') }}}
+ {{{ makeSetValue('buf', C_STRUCTS.stat.st_blksize, '4096', 'i32') }}}
+ {{{ makeSetValue('buf', C_STRUCTS.stat.st_blocks, 'stat.blocks', 'i32') }}}
+ {{{ makeSetValue('buf', C_STRUCTS.stat.st_atim.tv_sec, 'Math.floor(stat.atime.getTime() / 1000)', 'i32') }}}
+ {{{ makeSetValue('buf', C_STRUCTS.stat.st_atim.tv_nsec, '0', 'i32') }}}
+ {{{ makeSetValue('buf', C_STRUCTS.stat.st_mtim.tv_sec, 'Math.floor(stat.mtime.getTime() / 1000)', 'i32') }}}
+ {{{ makeSetValue('buf', C_STRUCTS.stat.st_mtim.tv_nsec, '0', 'i32') }}}
+ {{{ makeSetValue('buf', C_STRUCTS.stat.st_ctim.tv_sec, 'Math.floor(stat.ctime.getTime() / 1000)', 'i32') }}}
+ {{{ makeSetValue('buf', C_STRUCTS.stat.st_ctim.tv_nsec, '0', 'i32') }}}
+ {{{ makeSetValue('buf', C_STRUCTS.stat.st_ino, 'stat.ino', 'i32') }}}
return 0;
} catch (e) {
FS.handleFSError(e);
@@ -436,43 +407,23 @@ LibraryManager.library = {
// sys/statvfs.h
// ==========================================================================
- __statvfs_struct_layout: Runtime.generateStructInfo([
- ['i32', 'f_bsize'],
- ['i32', 'f_frsize'],
- ['i32', 'f_blocks'],
- ['i32', 'f_bfree'],
- ['i32', 'f_bavail'],
- ['i32', 'f_files'],
- ['i32', 'f_ffree'],
- ['i32', 'f_favail'],
- ['i32', 'f_fsid'],
- ['i32', '__padding'],
- ['i32', 'f_flag'],
- ['i32', 'f_namemax'],
- ['i32', '__reserved_1'],
- ['i32', '__reserved_2'],
- ['i32', '__reserved_3'],
- ['i32', '__reserved_4'],
- ['i32', '__reserved_5'],
- ['i32', '__reserved_6']]),
- statvfs__deps: ['$FS', '__statvfs_struct_layout'],
+ statvfs__deps: ['$FS'],
statvfs: function(path, buf) {
// http://pubs.opengroup.org/onlinepubs/009695399/functions/statvfs.html
// int statvfs(const char *restrict path, struct statvfs *restrict buf);
- var offsets = ___statvfs_struct_layout;
// NOTE: None of the constants here are true. We're just returning safe and
// sane values.
- {{{ makeSetValue('buf', 'offsets.f_bsize', '4096', 'i32') }}}
- {{{ makeSetValue('buf', 'offsets.f_frsize', '4096', 'i32') }}}
- {{{ makeSetValue('buf', 'offsets.f_blocks', '1000000', 'i32') }}}
- {{{ makeSetValue('buf', 'offsets.f_bfree', '500000', 'i32') }}}
- {{{ makeSetValue('buf', 'offsets.f_bavail', '500000', 'i32') }}}
- {{{ makeSetValue('buf', 'offsets.f_files', 'FS.nextInode', 'i32') }}}
- {{{ makeSetValue('buf', 'offsets.f_ffree', '1000000', 'i32') }}}
- {{{ makeSetValue('buf', 'offsets.f_favail', '1000000', 'i32') }}}
- {{{ makeSetValue('buf', 'offsets.f_fsid', '42', 'i32') }}}
- {{{ makeSetValue('buf', 'offsets.f_flag', '2', 'i32') }}} // ST_NOSUID
- {{{ makeSetValue('buf', 'offsets.f_namemax', '255', 'i32') }}}
+ {{{ makeSetValue('buf', C_STRUCTS.statvfs.f_bsize, '4096', 'i32') }}}
+ {{{ makeSetValue('buf', C_STRUCTS.statvfs.f_frsize, '4096', 'i32') }}}
+ {{{ makeSetValue('buf', C_STRUCTS.statvfs.f_blocks, '1000000', 'i32') }}}
+ {{{ makeSetValue('buf', C_STRUCTS.statvfs.f_bfree, '500000', 'i32') }}}
+ {{{ makeSetValue('buf', C_STRUCTS.statvfs.f_bavail, '500000', 'i32') }}}
+ {{{ makeSetValue('buf', C_STRUCTS.statvfs.f_files, 'FS.nextInode', 'i32') }}}
+ {{{ makeSetValue('buf', C_STRUCTS.statvfs.f_ffree, '1000000', 'i32') }}}
+ {{{ makeSetValue('buf', C_STRUCTS.statvfs.f_favail, '1000000', 'i32') }}}
+ {{{ makeSetValue('buf', C_STRUCTS.statvfs.f_fsid, '42', 'i32') }}}
+ {{{ makeSetValue('buf', C_STRUCTS.statvfs.f_flag, '2', 'i32') }}} // ST_NOSUID
+ {{{ makeSetValue('buf', C_STRUCTS.statvfs.f_namemax, '255', 'i32') }}}
return 0;
},
fstatvfs__deps: ['statvfs'],
@@ -488,13 +439,7 @@ LibraryManager.library = {
// fcntl.h
// ==========================================================================
- __flock_struct_layout: Runtime.generateStructInfo([
- ['i16', 'l_type'],
- ['i16', 'l_whence'],
- ['i32', 'l_start'],
- ['i32', 'l_len'],
- ['i16', 'l_pid']]),
- open__deps: ['$FS', '__setErrNo', '$ERRNO_CODES', '__dirent_struct_layout'],
+ open__deps: ['$FS', '__setErrNo', '$ERRNO_CODES'],
open: function(path, oflag, varargs) {
// int open(const char *path, int oflag, ...);
// http://pubs.opengroup.org/onlinepubs/009695399/functions/open.html
@@ -523,7 +468,7 @@ LibraryManager.library = {
writeArrayToMemory(intArrayFromString(c), template + Pointer_stringify(template).indexOf(rep));
return _creat(template, 0600);
},
- fcntl__deps: ['$FS', '__setErrNo', '$ERRNO_CODES', '__flock_struct_layout'],
+ fcntl__deps: ['$FS', '__setErrNo', '$ERRNO_CODES'],
fcntl: function(fildes, cmd, varargs, dup2) {
// int fcntl(int fildes, int cmd, ...);
// http://pubs.opengroup.org/onlinepubs/009695399/functions/fcntl.html
@@ -559,7 +504,7 @@ LibraryManager.library = {
case {{{ cDefine('F_GETLK') }}}:
case {{{ cDefine('F_GETLK64') }}}:
var arg = {{{ makeGetValue('varargs', 0, 'i32') }}};
- var offset = ___flock_struct_layout.l_type;
+ var offset = {{{ C_STRUCTS.flock.l_type }}};
// We're always unlocked.
{{{ makeSetValue('arg', 'offset', cDefine('F_UNLCK'), 'i16') }}}
return 0;
@@ -621,20 +566,15 @@ LibraryManager.library = {
// ==========================================================================
__DEFAULT_POLLMASK: {{{ cDefine('POLLIN') }}} | {{{ cDefine('POLLOUT') }}},
- __pollfd_struct_layout: Runtime.generateStructInfo([
- ['i32', 'fd'],
- ['i16', 'events'],
- ['i16', 'revents']]),
- poll__deps: ['$FS', '__DEFAULT_POLLMASK', '__pollfd_struct_layout'],
+ poll__deps: ['$FS', '__DEFAULT_POLLMASK'],
poll: function(fds, nfds, timeout) {
// int poll(struct pollfd fds[], nfds_t nfds, int timeout);
// http://pubs.opengroup.org/onlinepubs/009695399/functions/poll.html
- var offsets = ___pollfd_struct_layout;
var nonzero = 0;
for (var i = 0; i < nfds; i++) {
- var pollfd = fds + ___pollfd_struct_layout.__size__ * i;
- var fd = {{{ makeGetValue('pollfd', 'offsets.fd', 'i32') }}};
- var events = {{{ makeGetValue('pollfd', 'offsets.events', 'i16') }}};
+ var pollfd = fds + {{{ C_STRUCTS.pollfd.__size__ }}} * i;
+ var fd = {{{ makeGetValue('pollfd', C_STRUCTS.pollfd.fd, 'i32') }}};
+ var events = {{{ makeGetValue('pollfd', C_STRUCTS.pollfd.events, 'i16') }}};
var mask = {{{ cDefine('POLLNVAL') }}};
var stream = FS.getStream(fd);
if (stream) {
@@ -645,7 +585,7 @@ LibraryManager.library = {
}
mask &= events | {{{ cDefine('POLLERR') }}} | {{{ cDefine('POLLHUP') }}};
if (mask) nonzero++;
- {{{ makeSetValue('pollfd', 'offsets.revents', 'mask', 'i16') }}}
+ {{{ makeSetValue('pollfd', C_STRUCTS.pollfd.revents, 'mask', 'i16') }}}
}
return nonzero;
},
@@ -5010,17 +4950,11 @@ LibraryManager.library = {
{{{ makeSetValue('cosine', '0', 'cosineVal', 'float') }}};
},
- __div_t_struct_layout: Runtime.generateStructInfo([
- ['i32', 'quot'],
- ['i32', 'rem'],
- ]),
- div__deps: ['__div_t_struct_layout'],
div: function(divt, numer, denom) {
var quot = Math.floor(numer / denom);
var rem = numer - quot * denom;
- var offset = ___div_t_struct_layout.rem;
- {{{ makeSetValue('divt', '0', 'quot', 'i32') }}};
- {{{ makeSetValue('divt', 'offset', 'rem', 'i32') }}};
+ {{{ makeSetValue('divt', C_STRUCTS.div_t.quot, 'quot', 'i32') }}};
+ {{{ makeSetValue('divt', C_STRUCTS.div_t.rem, 'rem', 'i32') }}};
return divt;
},
@@ -5039,19 +4973,12 @@ LibraryManager.library = {
// sys/utsname.h
// ==========================================================================
- __utsname_struct_layout: Runtime.generateStructInfo([
- ['b65', 'sysname'],
- ['b65', 'nodename'],
- ['b65', 'release'],
- ['b65', 'version'],
- ['b65', 'machine'],
- ['b65', 'domainname']]),
- uname__deps: ['__utsname_struct_layout'],
uname: function(name) {
// int uname(struct utsname *name);
// http://pubs.opengroup.org/onlinepubs/009695399/functions/uname.html
+ var layout = {{{ JSON.stringify(C_STRUCTS.utsname) }}};
function copyString(element, value) {
- var offset = ___utsname_struct_layout[element];
+ var offset = layout[element];
for (var i = 0; i < value.length; i++) {
{{{ makeSetValue('name', 'offset + i', 'value.charCodeAt(i)', 'i8') }}}
}
@@ -5347,62 +5274,48 @@ LibraryManager.library = {
return time1 - time0;
},
- __tm_struct_layout: Runtime.generateStructInfo([
- ['i32', 'tm_sec'],
- ['i32', 'tm_min'],
- ['i32', 'tm_hour'],
- ['i32', 'tm_mday'],
- ['i32', 'tm_mon'],
- ['i32', 'tm_year'],
- ['i32', 'tm_wday'],
- ['i32', 'tm_yday'],
- ['i32', 'tm_isdst'],
- ['i32', 'tm_gmtoff'],
- ['i8*', 'tm_zone']]),
- // Statically allocated time struct.
+ // Statically allocated time struct. (TODO: Shouldn't C_STRUCTS.tm.__size__ be used here?)
__tm_current: 'allocate({{{ Runtime.QUANTUM_SIZE }}}*26, "i8", ALLOC_STATIC)',
// Statically allocated timezone string. We only use GMT as a timezone.
__tm_timezone: 'allocate(intArrayFromString("GMT"), "i8", ALLOC_STATIC)',
// Statically allocated time strings.
__tm_formatted: 'allocate({{{ Runtime.QUANTUM_SIZE }}}*26, "i8", ALLOC_STATIC)',
- mktime__deps: ['__tm_struct_layout', 'tzset'],
+ mktime__deps: ['tzset'],
mktime: function(tmPtr) {
_tzset();
- var offsets = ___tm_struct_layout;
- var year = {{{ makeGetValue('tmPtr', 'offsets.tm_year', 'i32') }}};
+ var year = {{{ makeGetValue('tmPtr', C_STRUCTS.tm.tm_year, 'i32') }}};
var timestamp = new Date(year >= 1900 ? year : year + 1900,
- {{{ makeGetValue('tmPtr', 'offsets.tm_mon', 'i32') }}},
- {{{ makeGetValue('tmPtr', 'offsets.tm_mday', 'i32') }}},
- {{{ makeGetValue('tmPtr', 'offsets.tm_hour', 'i32') }}},
- {{{ makeGetValue('tmPtr', 'offsets.tm_min', 'i32') }}},
- {{{ makeGetValue('tmPtr', 'offsets.tm_sec', 'i32') }}},
+ {{{ makeGetValue('tmPtr', C_STRUCTS.tm.tm_mon, 'i32') }}},
+ {{{ makeGetValue('tmPtr', C_STRUCTS.tm.tm_mday, 'i32') }}},
+ {{{ makeGetValue('tmPtr', C_STRUCTS.tm.tm_hour, 'i32') }}},
+ {{{ makeGetValue('tmPtr', C_STRUCTS.tm.tm_min, 'i32') }}},
+ {{{ makeGetValue('tmPtr', C_STRUCTS.tm.tm_sec, 'i32') }}},
0).getTime() / 1000;
- {{{ makeSetValue('tmPtr', 'offsets.tm_wday', 'new Date(timestamp).getDay()', 'i32') }}}
+ {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_wday, 'new Date(timestamp).getDay()', 'i32') }}}
var yday = Math.round((timestamp - (new Date(year, 0, 1)).getTime()) / (1000 * 60 * 60 * 24));
- {{{ makeSetValue('tmPtr', 'offsets.tm_yday', 'yday', 'i32') }}}
+ {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_yday, 'yday', 'i32') }}}
return timestamp;
},
timelocal: 'mktime',
- gmtime__deps: ['malloc', '__tm_struct_layout', '__tm_current', 'gmtime_r'],
+ gmtime__deps: ['malloc', '__tm_current', 'gmtime_r'],
gmtime: function(time) {
return _gmtime_r(time, ___tm_current);
},
- gmtime_r__deps: ['__tm_struct_layout', '__tm_timezone'],
+ gmtime_r__deps: ['__tm_timezone'],
gmtime_r: function(time, tmPtr) {
var date = new Date({{{ makeGetValue('time', 0, 'i32') }}}*1000);
- var offsets = ___tm_struct_layout;
- {{{ makeSetValue('tmPtr', 'offsets.tm_sec', 'date.getUTCSeconds()', 'i32') }}}
- {{{ makeSetValue('tmPtr', 'offsets.tm_min', 'date.getUTCMinutes()', 'i32') }}}
- {{{ makeSetValue('tmPtr', 'offsets.tm_hour', 'date.getUTCHours()', 'i32') }}}
- {{{ makeSetValue('tmPtr', 'offsets.tm_mday', 'date.getUTCDate()', 'i32') }}}
- {{{ makeSetValue('tmPtr', 'offsets.tm_mon', 'date.getUTCMonth()', 'i32') }}}
- {{{ makeSetValue('tmPtr', 'offsets.tm_year', 'date.getUTCFullYear()-1900', 'i32') }}}
- {{{ makeSetValue('tmPtr', 'offsets.tm_wday', 'date.getUTCDay()', 'i32') }}}
- {{{ makeSetValue('tmPtr', 'offsets.tm_gmtoff', '0', 'i32') }}}
- {{{ makeSetValue('tmPtr', 'offsets.tm_isdst', '0', 'i32') }}}
+ {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_sec, 'date.getUTCSeconds()', 'i32') }}}
+ {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_min, 'date.getUTCMinutes()', 'i32') }}}
+ {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_hour, 'date.getUTCHours()', 'i32') }}}
+ {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_mday, 'date.getUTCDate()', 'i32') }}}
+ {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_mon, 'date.getUTCMonth()', 'i32') }}}
+ {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_year, 'date.getUTCFullYear()-1900', 'i32') }}}
+ {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_wday, 'date.getUTCDay()', 'i32') }}}
+ {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_gmtoff, '0', 'i32') }}}
+ {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_isdst, '0', 'i32') }}}
var start = new Date(date); // define date using UTC, start from Jan 01 00:00:00 UTC
start.setUTCDate(1);
start.setUTCMonth(0);
@@ -5411,8 +5324,8 @@ LibraryManager.library = {
start.setUTCSeconds(0);
start.setUTCMilliseconds(0);
var yday = Math.floor((date.getTime() - start.getTime()) / (1000 * 60 * 60 * 24));
- {{{ makeSetValue('tmPtr', 'offsets.tm_yday', 'yday', 'i32') }}}
- {{{ makeSetValue('tmPtr', 'offsets.tm_zone', '___tm_timezone', 'i32') }}}
+ {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_yday, 'yday', 'i32') }}}
+ {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_zone, '___tm_timezone', 'i32') }}}
return tmPtr;
},
@@ -5426,33 +5339,32 @@ LibraryManager.library = {
return ret;
},
- localtime__deps: ['malloc', '__tm_struct_layout', '__tm_current', 'localtime_r'],
+ localtime__deps: ['malloc', '__tm_current', 'localtime_r'],
localtime: function(time) {
return _localtime_r(time, ___tm_current);
},
- localtime_r__deps: ['__tm_struct_layout', '__tm_timezone', 'tzset'],
+ localtime_r__deps: ['__tm_timezone', 'tzset'],
localtime_r: function(time, tmPtr) {
_tzset();
- var offsets = ___tm_struct_layout;
var date = new Date({{{ makeGetValue('time', 0, 'i32') }}}*1000);
- {{{ makeSetValue('tmPtr', 'offsets.tm_sec', 'date.getSeconds()', 'i32') }}}
- {{{ makeSetValue('tmPtr', 'offsets.tm_min', 'date.getMinutes()', 'i32') }}}
- {{{ makeSetValue('tmPtr', 'offsets.tm_hour', 'date.getHours()', 'i32') }}}
- {{{ makeSetValue('tmPtr', 'offsets.tm_mday', 'date.getDate()', 'i32') }}}
- {{{ makeSetValue('tmPtr', 'offsets.tm_mon', 'date.getMonth()', 'i32') }}}
- {{{ makeSetValue('tmPtr', 'offsets.tm_year', 'date.getFullYear()-1900', 'i32') }}}
- {{{ makeSetValue('tmPtr', 'offsets.tm_wday', 'date.getDay()', 'i32') }}}
+ {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_sec, 'date.getSeconds()', 'i32') }}}
+ {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_min, 'date.getMinutes()', 'i32') }}}
+ {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_hour, 'date.getHours()', 'i32') }}}
+ {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_mday, 'date.getDate()', 'i32') }}}
+ {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_mon, 'date.getMonth()', 'i32') }}}
+ {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_year, 'date.getFullYear()-1900', 'i32') }}}
+ {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_wday, 'date.getDay()', 'i32') }}}
var start = new Date(date.getFullYear(), 0, 1);
var yday = Math.floor((date.getTime() - start.getTime()) / (1000 * 60 * 60 * 24));
- {{{ makeSetValue('tmPtr', 'offsets.tm_yday', 'yday', 'i32') }}}
- {{{ makeSetValue('tmPtr', 'offsets.tm_gmtoff', 'start.getTimezoneOffset() * 60', 'i32') }}}
+ {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_yday, 'yday', 'i32') }}}
+ {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_gmtoff, 'start.getTimezoneOffset() * 60', 'i32') }}}
var dst = Number(start.getTimezoneOffset() != date.getTimezoneOffset());
- {{{ makeSetValue('tmPtr', 'offsets.tm_isdst', 'dst', 'i32') }}}
+ {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_isdst, 'dst', 'i32') }}}
- {{{ makeSetValue('tmPtr', 'offsets.tm_zone', '___tm_timezone', 'i32') }}}
+ {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_zone, '___tm_timezone', 'i32') }}}
return tmPtr;
},
@@ -5563,21 +5475,21 @@ LibraryManager.library = {
return newDate;
},
- strftime__deps: ['__tm_struct_layout', '_isLeapYear', '_arraySum', '_addDays', '_MONTH_DAYS_REGULAR', '_MONTH_DAYS_LEAP'],
+ strftime__deps: ['_isLeapYear', '_arraySum', '_addDays', '_MONTH_DAYS_REGULAR', '_MONTH_DAYS_LEAP'],
strftime: function(s, maxsize, format, tm) {
// size_t strftime(char *restrict s, size_t maxsize, const char *restrict format, const struct tm *restrict timeptr);
// http://pubs.opengroup.org/onlinepubs/009695399/functions/strftime.html
var date = {
- tm_sec: {{{ makeGetValue('tm', '___tm_struct_layout.tm_sec', 'i32') }}},
- tm_min: {{{ makeGetValue('tm', '___tm_struct_layout.tm_min', 'i32') }}},
- tm_hour: {{{ makeGetValue('tm', '___tm_struct_layout.tm_hour', 'i32') }}},
- tm_mday: {{{ makeGetValue('tm', '___tm_struct_layout.tm_mday', 'i32') }}},
- tm_mon: {{{ makeGetValue('tm', '___tm_struct_layout.tm_mon', 'i32') }}},
- tm_year: {{{ makeGetValue('tm', '___tm_struct_layout.tm_year', 'i32') }}},
- tm_wday: {{{ makeGetValue('tm', '___tm_struct_layout.tm_wday', 'i32') }}},
- tm_yday: {{{ makeGetValue('tm', '___tm_struct_layout.tm_yday', 'i32') }}},
- tm_isdst: {{{ makeGetValue('tm', '___tm_struct_layout.tm_isdst', 'i32') }}}
+ tm_sec: {{{ makeGetValue('tm', C_STRUCTS.tm.tm_sec, 'i32') }}},
+ tm_min: {{{ makeGetValue('tm', C_STRUCTS.tm.tm_min, 'i32') }}},
+ tm_hour: {{{ makeGetValue('tm', C_STRUCTS.tm.tm_hour, 'i32') }}},
+ tm_mday: {{{ makeGetValue('tm', C_STRUCTS.tm.tm_mday, 'i32') }}},
+ tm_mon: {{{ makeGetValue('tm', C_STRUCTS.tm.tm_mon, 'i32') }}},
+ tm_year: {{{ makeGetValue('tm', C_STRUCTS.tm.tm_year, 'i32') }}},
+ tm_wday: {{{ makeGetValue('tm', C_STRUCTS.tm.tm_wday, 'i32') }}},
+ tm_yday: {{{ makeGetValue('tm', C_STRUCTS.tm.tm_yday, 'i32') }}},
+ tm_isdst: {{{ makeGetValue('tm', C_STRUCTS.tm.tm_isdst, 'i32') }}}
};
var pattern = Pointer_stringify(format);
@@ -5860,7 +5772,7 @@ LibraryManager.library = {
},
strftime_l: 'strftime', // no locale support yet
- strptime__deps: ['__tm_struct_layout', '_isLeapYear', '_arraySum', '_addDays', '_MONTH_DAYS_REGULAR', '_MONTH_DAYS_LEAP'],
+ strptime__deps: ['_isLeapYear', '_arraySum', '_addDays', '_MONTH_DAYS_REGULAR', '_MONTH_DAYS_LEAP'],
strptime: function(buf, format, tm) {
// char *strptime(const char *restrict buf, const char *restrict format, struct tm *restrict tm);
// http://pubs.opengroup.org/onlinepubs/009695399/functions/strptime.html
@@ -5938,12 +5850,12 @@ LibraryManager.library = {
return (typeof value !== 'number' || isNaN(value)) ? min : (value>=min ? (value<=max ? value: max): min);
};
return {
- year: fixup({{{ makeGetValue('tm', '___tm_struct_layout.tm_year', 'i32', 0, 0, 1) }}} + 1900 , 1970, 9999),
- month: fixup({{{ makeGetValue('tm', '___tm_struct_layout.tm_mon', 'i32', 0, 0, 1) }}}, 0, 11),
- day: fixup({{{ makeGetValue('tm', '___tm_struct_layout.tm_mday', 'i32', 0, 0, 1) }}}, 1, 31),
- hour: fixup({{{ makeGetValue('tm', '___tm_struct_layout.tm_hour', 'i32', 0, 0, 1) }}}, 0, 23),
- min: fixup({{{ makeGetValue('tm', '___tm_struct_layout.tm_min', 'i32', 0, 0, 1) }}}, 0, 59),
- sec: fixup({{{ makeGetValue('tm', '___tm_struct_layout.tm_sec', 'i32', 0, 0, 1) }}}, 0, 59)
+ year: fixup({{{ makeGetValue('tm', C_STRUCTS.tm.tm_year, 'i32', 0, 0, 1) }}} + 1900 , 1970, 9999),
+ month: fixup({{{ makeGetValue('tm', C_STRUCTS.tm.tm_mon, 'i32', 0, 0, 1) }}}, 0, 11),
+ day: fixup({{{ makeGetValue('tm', C_STRUCTS.tm.tm_mday, 'i32', 0, 0, 1) }}}, 1, 31),
+ hour: fixup({{{ makeGetValue('tm', C_STRUCTS.tm.tm_hour, 'i32', 0, 0, 1) }}}, 0, 23),
+ min: fixup({{{ makeGetValue('tm', C_STRUCTS.tm.tm_min, 'i32', 0, 0, 1) }}}, 0, 59),
+ sec: fixup({{{ makeGetValue('tm', C_STRUCTS.tm.tm_sec, 'i32', 0, 0, 1) }}}, 0, 59)
};
};
@@ -6083,15 +5995,15 @@ LibraryManager.library = {
*/
var fullDate = new Date(date.year, date.month, date.day, date.hour, date.min, date.sec, 0);
- {{{ makeSetValue('tm', '___tm_struct_layout.tm_sec', 'fullDate.getSeconds()', 'i32') }}}
- {{{ makeSetValue('tm', '___tm_struct_layout.tm_min', 'fullDate.getMinutes()', 'i32') }}}
- {{{ makeSetValue('tm', '___tm_struct_layout.tm_hour', 'fullDate.getHours()', 'i32') }}}
- {{{ makeSetValue('tm', '___tm_struct_layout.tm_mday', 'fullDate.getDate()', 'i32') }}}
- {{{ makeSetValue('tm', '___tm_struct_layout.tm_mon', 'fullDate.getMonth()', 'i32') }}}
- {{{ makeSetValue('tm', '___tm_struct_layout.tm_year', 'fullDate.getFullYear()-1900', 'i32') }}}
- {{{ makeSetValue('tm', '___tm_struct_layout.tm_wday', 'fullDate.getDay()', 'i32') }}}
- {{{ makeSetValue('tm', '___tm_struct_layout.tm_yday', '__arraySum(__isLeapYear(fullDate.getFullYear()) ? __MONTH_DAYS_LEAP : __MONTH_DAYS_REGULAR, fullDate.getMonth()-1)+fullDate.getDate()-1', 'i32') }}}
- {{{ makeSetValue('tm', '___tm_struct_layout.tm_isdst', '0', 'i32') }}}
+ {{{ makeSetValue('tm', C_STRUCTS.tm.tm_sec, 'fullDate.getSeconds()', 'i32') }}}
+ {{{ makeSetValue('tm', C_STRUCTS.tm.tm_min, 'fullDate.getMinutes()', 'i32') }}}
+ {{{ makeSetValue('tm', C_STRUCTS.tm.tm_hour, 'fullDate.getHours()', 'i32') }}}
+ {{{ makeSetValue('tm', C_STRUCTS.tm.tm_mday, 'fullDate.getDate()', 'i32') }}}
+ {{{ makeSetValue('tm', C_STRUCTS.tm.tm_mon, 'fullDate.getMonth()', 'i32') }}}
+ {{{ makeSetValue('tm', C_STRUCTS.tm.tm_year, 'fullDate.getFullYear()-1900', 'i32') }}}
+ {{{ makeSetValue('tm', C_STRUCTS.tm.tm_wday, 'fullDate.getDay()', 'i32') }}}
+ {{{ makeSetValue('tm', C_STRUCTS.tm.tm_yday, '__arraySum(__isLeapYear(fullDate.getFullYear()) ? __MONTH_DAYS_LEAP : __MONTH_DAYS_REGULAR, fullDate.getMonth()-1)+fullDate.getDate()-1', 'i32') }}}
+ {{{ makeSetValue('tm', C_STRUCTS.tm.tm_isdst, '0', 'i32') }}}
// we need to convert the matched sequence into an integer array to take care of UTF-8 characters > 0x7F
// TODO: not sure that intArrayFromString handles all unicode characters correctly
@@ -6116,25 +6028,21 @@ LibraryManager.library = {
// sys/time.h
// ==========================================================================
- __timespec_struct_layout: Runtime.generateStructInfo([
- ['i32', 'tv_sec'],
- ['i32', 'tv_nsec']]),
- nanosleep__deps: ['usleep', '__timespec_struct_layout'],
+ nanosleep__deps: ['usleep'],
nanosleep: function(rqtp, rmtp) {
// int nanosleep(const struct timespec *rqtp, struct timespec *rmtp);
- var seconds = {{{ makeGetValue('rqtp', '___timespec_struct_layout.tv_sec', 'i32') }}};
- var nanoseconds = {{{ makeGetValue('rqtp', '___timespec_struct_layout.tv_nsec', 'i32') }}};
- {{{ makeSetValue('rmtp', '___timespec_struct_layout.tv_sec', '0', 'i32') }}}
- {{{ makeSetValue('rmtp', '___timespec_struct_layout.tv_nsec', '0', 'i32') }}}
+ var seconds = {{{ makeGetValue('rqtp', C_STRUCTS.timespec.tv_sec, 'i32') }}};
+ var nanoseconds = {{{ makeGetValue('rqtp', C_STRUCTS.timespec.tv_nsec, 'i32') }}};
+ {{{ makeSetValue('rmtp', C_STRUCTS.timespec.tv_sec, '0', 'i32') }}}
+ {{{ makeSetValue('rmtp', C_STRUCTS.timespec.tv_nsec, '0', 'i32') }}}
return _usleep((seconds * 1e6) + (nanoseconds / 1000));
},
// TODO: Implement these for real.
- clock_gettime__deps: ['__timespec_struct_layout'],
clock_gettime: function(clk_id, tp) {
// int clock_gettime(clockid_t clk_id, struct timespec *tp);
var now = Date.now();
- {{{ makeSetValue('tp', '___timespec_struct_layout.tv_sec', 'Math.floor(now/1000)', 'i32') }}}; // seconds
- {{{ makeSetValue('tp', '___timespec_struct_layout.tv_nsec', '(now % 1000) * 1000 * 1000', 'i32') }}}; // nanoseconds (really milliseconds)
+ {{{ makeSetValue('tp', C_STRUCTS.timespec.tv_sec, 'Math.floor(now/1000)', 'i32') }}}; // seconds
+ {{{ makeSetValue('tp', C_STRUCTS.timespec.tv_nsec, '(now % 1000) * 1000 * 1000', 'i32') }}}; // nanoseconds (really milliseconds)
return 0;
},
clock_settime: function(clk_id, tp) {
@@ -6142,28 +6050,26 @@ LibraryManager.library = {
// Nothing.
return 0;
},
- clock_getres__deps: ['__timespec_struct_layout'],
clock_getres: function(clk_id, res) {
// int clock_getres(clockid_t clk_id, struct timespec *res);
- {{{ makeSetValue('res', '___timespec_struct_layout.tv_sec', '1', 'i32') }}}
- {{{ makeSetValue('res', '___timespec_struct_layout.tv_nsec', '1000 * 1000', 'i32') }}} // resolution is milliseconds
+ {{{ makeSetValue('res', C_STRUCTS.timespec.tv_sec, '1', 'i32') }}}
+ {{{ makeSetValue('res', C_STRUCTS.timespec.tv_nsec, '1000 * 1000', 'i32') }}} // resolution is milliseconds
return 0;
},
// http://pubs.opengroup.org/onlinepubs/000095399/basedefs/sys/time.h.html
gettimeofday: function(ptr) {
- // %struct.timeval = type { i32, i32 }
- {{{ (LibraryManager.structs.gettimeofday = Runtime.calculateStructAlignment({ fields: ['i32', 'i32'] }), null) }}}
var now = Date.now();
- {{{ makeSetValue('ptr', LibraryManager.structs.gettimeofday[0], 'Math.floor(now/1000)', 'i32') }}}; // seconds
- {{{ makeSetValue('ptr', LibraryManager.structs.gettimeofday[1], 'Math.floor((now-1000*Math.floor(now/1000))*1000)', 'i32') }}}; // microseconds
+ {{{ makeSetValue('ptr', C_STRUCTS.timeval.tv_sec, 'Math.floor(now/1000)', 'i32') }}}; // seconds
+ {{{ makeSetValue('ptr', C_STRUCTS.timeval.tv_usec, 'Math.floor((now-1000*Math.floor(now/1000))*1000)', 'i32') }}}; // microseconds
return 0;
},
// ==========================================================================
// sys/timeb.h
// ==========================================================================
-
+
+ // TODO: Where did this header go?
__timeb_struct_layout: Runtime.generateStructInfo([
['i32', 'time'],
['i16', 'millitm'],
@@ -6184,18 +6090,13 @@ LibraryManager.library = {
// sys/times.h
// ==========================================================================
- __tms_struct_layout: Runtime.generateStructInfo([
- ['i32', 'tms_utime'],
- ['i32', 'tms_stime'],
- ['i32', 'tms_cutime'],
- ['i32', 'tms_cstime']]),
- times__deps: ['__tms_struct_layout', 'memset'],
+ times__deps: ['memset'],
times: function(buffer) {
// clock_t times(struct tms *buffer);
// http://pubs.opengroup.org/onlinepubs/009695399/functions/times.html
// NOTE: This is fake, since we can't calculate real CPU time usage in JS.
if (buffer !== 0) {
- _memset(buffer, 0, ___tms_struct_layout.__size__);
+ _memset(buffer, 0, {{{ C_STRUCTS.tms.__size__ }}});
}
return 0;
},
@@ -6853,14 +6754,10 @@ LibraryManager.library = {
// ==========================================================================
// TODO: Implement for real.
- __rlimit_struct_layout: Runtime.generateStructInfo([
- ['i32', 'rlim_cur'],
- ['i32', 'rlim_max']]),
- getrlimit__deps: ['__rlimit_struct_layout'],
getrlimit: function(resource, rlp) {
// int getrlimit(int resource, struct rlimit *rlp);
- {{{ makeSetValue('rlp', '___rlimit_struct_layout.rlim_cur', '-1', 'i32') }}} // RLIM_INFINITY
- {{{ makeSetValue('rlp', '___rlimit_struct_layout.rlim_max', '-1', 'i32') }}} // RLIM_INFINITY
+ {{{ makeSetValue('rlp', C_STRUCTS.rlimit.rlim_cur, '-1', 'i32') }}} // RLIM_INFINITY
+ {{{ makeSetValue('rlp', C_STRUCTS.rlimit.rlim_max, '-1', 'i32') }}} // RLIM_INFINITY
return 0;
},
setrlimit: function(resource, rlp) {
@@ -6870,33 +6767,12 @@ LibraryManager.library = {
__01getrlimit64_: 'getrlimit',
// TODO: Implement for real. We just do time used, and no useful data
- __rusage_struct_layout: Runtime.generateStructInfo([
- ['i64', 'ru_utime'],
- ['i64', 'ru_stime'],
- ['i32', 'ru_maxrss'],
- ['i32', 'ru_ixrss'],
- ['i32', 'ru_idrss'],
- ['i32', 'ru_isrss'],
- ['i32', 'ru_minflt'],
- ['i32', 'ru_majflt'],
- ['i32', 'ru_nswap'],
- ['i32', 'ru_inblock'],
- ['i32', 'ru_oublock'],
- ['i32', 'ru_msgsnd'],
- ['i32', 'ru_msgrcv'],
- ['i32', 'ru_nsignals'],
- ['i32', 'ru_nvcsw'],
- ['i32', 'ru_nivcsw']]),
- getrusage__deps: ['__rusage_struct_layout'],
getrusage: function(resource, rlp) {
- // %struct.timeval = type { i32, i32 }
- var timeval = Runtime.calculateStructAlignment({ fields: ['i32', 'i32'] });
-
// int getrusage(int resource, struct rusage *rlp);
- {{{ makeSetValue('rlp', '___rusage_struct_layout.ru_utime+timeval[0]', '1', 'i32') }}}
- {{{ makeSetValue('rlp', '___rusage_struct_layout.ru_utime+timeval[1]', '2', 'i32') }}}
- {{{ makeSetValue('rlp', '___rusage_struct_layout.ru_stime+timeval[0]', '3', 'i32') }}}
- {{{ makeSetValue('rlp', '___rusage_struct_layout.ru_stime+timeval[1]', '4', 'i32') }}}
+ {{{ makeSetValue('rlp', C_STRUCTS.rusage.ru_utime.tv_sec, '1', 'i32') }}}
+ {{{ makeSetValue('rlp', C_STRUCTS.rusage.ru_utime.tv_usec, '2', 'i32') }}}
+ {{{ makeSetValue('rlp', C_STRUCTS.rusage.ru_stime.tv_sec, '3', 'i32') }}}
+ {{{ makeSetValue('rlp', C_STRUCTS.rusage.ru_stime.tv_usec, '4', 'i32') }}}
return 0;
},
@@ -7404,25 +7280,6 @@ LibraryManager.library = {
},
// note: lots of leaking here!
- __hostent_struct_layout: Runtime.generateStructInfo([
- ['i8*', 'h_name'],
- ['i8**', 'h_aliases'],
- ['i32', 'h_addrtype'],
- ['i32', 'h_length'],
- ['i8**', 'h_addr_list'],
- ]),
-
- _addrinfo_layout: Runtime.generateStructInfo([
- ['i32', 'ai_flags'],
- ['i32', 'ai_family'],
- ['i32', 'ai_socktype'],
- ['i32', 'ai_protocol'],
- ['i32', 'ai_addrlen'],
- ['*', 'ai_addr'],
- ['*', 'ai_canonname'],
- ['*', 'ai_next']
- ]),
-
gethostbyaddr__deps: ['$DNS', 'gethostbyname', '_inet_ntop4_raw'],
gethostbyaddr: function (addr, addrlen, type) {
if (type !== {{{ cDefine('AF_INET') }}}) {
@@ -7439,40 +7296,40 @@ LibraryManager.library = {
return _gethostbyname(hostp);
},
- gethostbyname__deps: ['$DNS', '__hostent_struct_layout', '_inet_pton4_raw'],
+ gethostbyname__deps: ['$DNS', '_inet_pton4_raw'],
gethostbyname: function(name) {
name = Pointer_stringify(name);
// generate hostent
- var ret = _malloc(___hostent_struct_layout.__size__); // XXX possibly leaked, as are others here
+ var ret = _malloc({{{ C_STRUCTS.hostent.__size__ }}}); // XXX possibly leaked, as are others here
var nameBuf = _malloc(name.length+1);
writeStringToMemory(name, nameBuf);
- {{{ makeSetValue('ret', '___hostent_struct_layout.h_name', 'nameBuf', 'i8*') }}}
+ {{{ makeSetValue('ret', C_STRUCTS.hostent.h_name, 'nameBuf', 'i8*') }}}
var aliasesBuf = _malloc(4);
{{{ makeSetValue('aliasesBuf', '0', '0', 'i8*') }}}
- {{{ makeSetValue('ret', '___hostent_struct_layout.h_aliases', 'aliasesBuf', 'i8**') }}}
+ {{{ makeSetValue('ret', C_STRUCTS.hostent.h_aliases, 'aliasesBuf', 'i8**') }}}
var afinet = {{{ cDefine('AF_INET') }}};
- {{{ makeSetValue('ret', '___hostent_struct_layout.h_addrtype', 'afinet', 'i32') }}}
- {{{ makeSetValue('ret', '___hostent_struct_layout.h_length', '4', 'i32') }}}
+ {{{ makeSetValue('ret', C_STRUCTS.hostent.h_addrtype, 'afinet', 'i32') }}}
+ {{{ makeSetValue('ret', C_STRUCTS.hostent.h_length, '4', 'i32') }}}
var addrListBuf = _malloc(12);
{{{ makeSetValue('addrListBuf', '0', 'addrListBuf+8', 'i32*') }}}
{{{ makeSetValue('addrListBuf', '4', '0', 'i32*') }}}
{{{ makeSetValue('addrListBuf', '8', '__inet_pton4_raw(DNS.lookup_name(name))', 'i32') }}}
- {{{ makeSetValue('ret', '___hostent_struct_layout.h_addr_list', 'addrListBuf', 'i8**') }}}
+ {{{ makeSetValue('ret', C_STRUCTS.hostent.h_addr_list, 'addrListBuf', 'i8**') }}}
return ret;
},
gethostbyname_r__deps: ['gethostbyname'],
gethostbyname_r: function(name, ret, buf, buflen, out, err) {
var data = _gethostbyname(name);
- _memcpy(ret, data, ___hostent_struct_layout.__size__);
+ _memcpy(ret, data, {{{ C_STRUCTS.hostent.__size__ }}});
_free(data);
{{{ makeSetValue('err', '0', '0', 'i32') }}};
{{{ makeSetValue('out', '0', 'ret', '*') }}};
return 0;
},
- getaddrinfo__deps: ['$Sockets', '$DNS', '_addrinfo_layout', '_inet_pton4_raw', '_inet_ntop4_raw', '_inet_pton6_raw', '_inet_ntop6_raw', '_write_sockaddr', 'htonl'],
+ getaddrinfo__deps: ['$Sockets', '$DNS', '_inet_pton4_raw', '_inet_ntop4_raw', '_inet_pton6_raw', '_inet_ntop6_raw', '_write_sockaddr', 'htonl'],
getaddrinfo: function(node, service, hint, out) {
var addrs = [];
var canon = null;
@@ -7489,8 +7346,8 @@ LibraryManager.library = {
var res;
salen = family === {{{ cDefine('AF_INET6') }}} ?
- Sockets.sockaddr_in6_layout.__size__ :
- Sockets.sockaddr_in_layout.__size__;
+ {{{ C_STRUCTS.sockaddr_in6.__size__ }}} :
+ {{{ C_STRUCTS.sockaddr_in.__size__ }}};
addr = family === {{{ cDefine('AF_INET6') }}} ?
__inet_ntop6_raw(addr) :
__inet_ntop4_raw(addr);
@@ -7498,28 +7355,28 @@ LibraryManager.library = {
res = __write_sockaddr(sa, family, addr, port);
assert(!res.errno);
- ai = _malloc(__addrinfo_layout.__size__);
- {{{ makeSetValue('ai', '__addrinfo_layout.ai_family', 'family', 'i32') }}};
- {{{ makeSetValue('ai', '__addrinfo_layout.ai_socktype', 'type', 'i32') }}};
- {{{ makeSetValue('ai', '__addrinfo_layout.ai_protocol', 'proto', 'i32') }}};
+ ai = _malloc({{{ C_STRUCTS.addrinfo.__size__ }}});
+ {{{ makeSetValue('ai', C_STRUCTS.addrinfo.ai_family, 'family', 'i32') }}};
+ {{{ makeSetValue('ai', C_STRUCTS.addrinfo.ai_socktype, 'type', 'i32') }}};
+ {{{ makeSetValue('ai', C_STRUCTS.addrinfo.ai_protocol, 'proto', 'i32') }}};
if (canon) {
- {{{ makeSetValue('ai', '__addrinfo_layout.ai_canonname', 'canon', 'i32') }}};
+ {{{ makeSetValue('ai', C_STRUCTS.addrinfo.ai_canonname, 'canon', 'i32') }}};
}
- {{{ makeSetValue('ai', '__addrinfo_layout.ai_addr', 'sa', '*') }}};
+ {{{ makeSetValue('ai', C_STRUCTS.addrinfo.ai_addr, 'sa', '*') }}};
if (family === {{{ cDefine('AF_INET6') }}}) {
- {{{ makeSetValue('ai', '__addrinfo_layout.ai_addrlen', 'Sockets.sockaddr_in6_layout.__size__', 'i32') }}};
+ {{{ makeSetValue('ai', C_STRUCTS.addrinfo.ai_addrlen, C_STRUCTS.sockaddr_in6.__size__, 'i32') }}};
} else {
- {{{ makeSetValue('ai', '__addrinfo_layout.ai_addrlen', 'Sockets.sockaddr_in_layout.__size__', 'i32') }}};
+ {{{ makeSetValue('ai', C_STRUCTS.addrinfo.ai_addrlen, C_STRUCTS.sockaddr_in.__size__, 'i32') }}};
}
return ai;
}
if (hint) {
- flags = {{{ makeGetValue('hint', '__addrinfo_layout.ai_flags', 'i32') }}};
- family = {{{ makeGetValue('hint', '__addrinfo_layout.ai_family', 'i32') }}};
- type = {{{ makeGetValue('hint', '__addrinfo_layout.ai_socktype', 'i32') }}};
- proto = {{{ makeGetValue('hint', '__addrinfo_layout.ai_protocol', 'i32') }}};
+ flags = {{{ makeGetValue('hint', C_STRUCTS.addrinfo.ai_flags, 'i32') }}};
+ family = {{{ makeGetValue('hint', C_STRUCTS.addrinfo.ai_family, 'i32') }}};
+ type = {{{ makeGetValue('hint', C_STRUCTS.addrinfo.ai_socktype, 'i32') }}};
+ proto = {{{ makeGetValue('hint', C_STRUCTS.addrinfo.ai_protocol, 'i32') }}};
}
if (type && !proto) {
proto = type === {{{ cDefine('SOCK_DGRAM') }}} ? {{{ cDefine('IPPROTO_UDP') }}} : {{{ cDefine('IPPROTO_TCP') }}};
@@ -7535,7 +7392,7 @@ LibraryManager.library = {
{{{ cDefine('AI_NUMERICSERV') }}}|{{{ cDefine('AI_V4MAPPED') }}}|{{{ cDefine('AI_ALL') }}}|{{{ cDefine('AI_ADDRCONFIG') }}})) {
return {{{ cDefine('EAI_BADFLAGS') }}};
}
- if (({{{ makeGetValue('hint', '__addrinfo_layout.ai_flags', 'i32') }}} & {{{ cDefine('AI_CANONNAME') }}}) && !node) {
+ if (({{{ makeGetValue('hint', C_STRUCTS.addrinfo.ai_flags, 'i32') }}} & {{{ cDefine('AI_CANONNAME') }}}) && !node) {
return {{{ cDefine('EAI_BADFLAGS') }}};
}
if (flags & {{{ cDefine('AI_ADDRCONFIG') }}}) {
@@ -7631,14 +7488,14 @@ LibraryManager.library = {
return 0;
},
- freeaddrinfo__deps: ['$Sockets', '_addrinfo_layout'],
+ freeaddrinfo__deps: ['$Sockets'],
freeaddrinfo: function(ai) {
- var sa = {{{ makeGetValue('ai', '__addrinfo_layout.ai_addr', '*') }}};
+ var sa = {{{ makeGetValue('ai', C_STRUCTS.addrinfo.ai_addr, '*') }}};
_free(sa);
_free(ai);
},
- getnameinfo__deps: ['$Sockets', '$DNS', '__hostent_struct_layout', '_read_sockaddr'],
+ getnameinfo__deps: ['$Sockets', '$DNS', '_read_sockaddr'],
getnameinfo: function (sa, salen, node, nodelen, serv, servlen, flags) {
var info = __read_sockaddr(sa, salen);
if (info.errno) {
@@ -7705,33 +7562,7 @@ LibraryManager.library = {
localAddr: 0xfe00000a, // Local address is always 10.0.0.254
addrPool: [ 0x0200000a, 0x0300000a, 0x0400000a, 0x0500000a,
0x0600000a, 0x0700000a, 0x0800000a, 0x0900000a, 0x0a00000a,
- 0x0b00000a, 0x0c00000a, 0x0d00000a, 0x0e00000a], /* 0x0100000a is reserved */
- sockaddr_in_layout: Runtime.generateStructInfo([
- ['i16', 'sin_family'],
- ['i16', 'sin_port'],
- ['i32', 'sin_addr'],
- ['b8', 'sin_zero'],
- ]),
- sockaddr_in6_layout: Runtime.generateStructInfo([
- ['i16', 'sin6_family'],
- ['i16', 'sin6_port'],
- ['i32', 'sin6_flowinfo'],
- ['b16', 'sin6_addr'],
- ['i32', 'sin6_scope_id']
- ]),
- msghdr_layout: Runtime.generateStructInfo([
- ['*', 'msg_name'],
- ['i32', 'msg_namelen'],
- ['*', 'msg_iov'],
- ['i32', 'msg_iovlen'],
- ['*', 'msg_control'],
- ['i32', 'msg_controllen'],
- ['i32', 'msg_flags'],
- ]),
- iovec_layout: Runtime.generateStructInfo([
- ['i8*', 'iov_base'],
- ['i32', 'iov_len']
- ])
+ 0x0b00000a, 0x0c00000a, 0x0d00000a, 0x0e00000a] /* 0x0100000a is reserved */
},
#if SOCKET_WEBRTC
@@ -7895,8 +7726,8 @@ LibraryManager.library = {
var info = FS.getStream(fd);
if (!info) return -1;
if (addr) {
- info.port = _ntohs(getValue(addr + Sockets.sockaddr_in_layout.sin_port, 'i16'));
- // info.addr = getValue(addr + Sockets.sockaddr_in_layout.sin_addr, 'i32');
+ info.port = _ntohs(getValue(addr + {{{ C_STRUCTS.sockaddr_in.sin_port }}}, 'i16'));
+ // info.addr = getValue(addr + {{{ C_STRUCTS.sockaddr_in.sin_addr.s_addr }}}, 'i32');
}
if (!info.port) {
info.port = _mkport();
@@ -7920,10 +7751,10 @@ LibraryManager.library = {
_bind(fd);
}
- var name = {{{ makeGetValue('msg', 'Sockets.msghdr_layout.msg_name', '*') }}};
+ var name = {{{ makeGetValue('msg', C_STRUCTS.msghdr.msg_name, '*') }}};
assert(name, 'sendmsg on non-connected socket, and no name/address in the message');
- var port = _ntohs(getValue(name + Sockets.sockaddr_in_layout.sin_port, 'i16'));
- var addr = getValue(name + Sockets.sockaddr_in_layout.sin_addr, 'i32');
+ var port = _ntohs(getValue(name + {{{ C_STRUCTS.sockaddr_in.sin_port }}}, 'i16'));
+ var addr = getValue(name + {{{ C_STRUCTS.sockaddr_in.sin_addr.s_addr }}}, 'i32');
var connection = Sockets.connections[addr];
// var host = __inet_ntop4_raw(addr);
@@ -7932,8 +7763,8 @@ LibraryManager.library = {
return -1;
}
- var iov = {{{ makeGetValue('msg', 'Sockets.msghdr_layout.msg_iov', 'i8*') }}};
- var num = {{{ makeGetValue('msg', 'Sockets.msghdr_layout.msg_iovlen', 'i32') }}};
+ var iov = {{{ makeGetValue('msg', C_STRUCTS.msghdr.msg_iov, 'i8*') }}};
+ var num = {{{ makeGetValue('msg', C_STRUCTS.msghdr.msg_iovlen, 'i32') }}};
#if SOCKET_DEBUG
Module.print('sendmsg vecs: ' + num);
#endif
@@ -7994,13 +7825,13 @@ LibraryManager.library = {
Module.print('recvmsg bytes: ' + bytes + ' | ' + Array.prototype.slice.call(buffer));
#endif
// write source
- var name = {{{ makeGetValue('msg', 'Sockets.msghdr_layout.msg_name', '*') }}};
- {{{ makeSetValue('name', 'Sockets.sockaddr_in_layout.sin_addr', 'addr', 'i32') }}};
- {{{ makeSetValue('name', 'Sockets.sockaddr_in_layout.sin_port', '_htons(header[0])', 'i16') }}};
+ var name = {{{ makeGetValue('msg', C_STRUCTS.msghdr.msg_name, '*') }}};
+ {{{ makeSetValue('name', C_STRUCTS.sockaddr_in.sin_addr.s_addr, 'addr', 'i32') }}};
+ {{{ makeSetValue('name', C_STRUCTS.sockaddr_in.sin_port, '_htons(header[0])', 'i16') }}};
// write data
var ret = bytes;
- var iov = {{{ makeGetValue('msg', 'Sockets.msghdr_layout.msg_iov', 'i8*') }}};
- var num = {{{ makeGetValue('msg', 'Sockets.msghdr_layout.msg_iovlen', 'i32') }}};
+ var iov = {{{ makeGetValue('msg', C_STRUCTS.msghdr.msg_iov, 'i8*') }}};
+ var num = {{{ makeGetValue('msg', C_STRUCTS.msghdr.msg_iovlen, 'i32') }}};
var bufferPos = 0;
for (var i = 0; i < num && bytes > 0; i++) {
var currNum = {{{ makeGetValue('iov', '8*i + 4', 'i32') }}};
@@ -8054,9 +7885,9 @@ LibraryManager.library = {
var info = FS.getStream(fd);
if (!info) return -1;
if (addr) {
- setValue(addr + Sockets.sockaddr_in_layout.sin_addr, info.addr, 'i32');
- setValue(addr + Sockets.sockaddr_in_layout.sin_port, info.port, 'i32');
- setValue(addrlen, Sockets.sockaddr_in_layout.__size__, 'i32');
+ setValue(addr + {{{ C_STRUCTS.sockaddr_in.sin_addr.s_addr }}}, info.addr, 'i32');
+ setValue(addr + {{{ C_STRUCTS.sockaddr_in.sin_port }}}, info.port, 'i32');
+ setValue(addrlen, {{{ C_STRUCTS.sockaddr_in.__size__ }}}, 'i32');
}
return fd;
},
@@ -8122,27 +7953,27 @@ LibraryManager.library = {
_read_sockaddr__deps: ['$Sockets', '_inet_ntop4_raw', '_inet_ntop6_raw'],
_read_sockaddr: function (sa, salen) {
// family / port offsets are common to both sockaddr_in and sockaddr_in6
- var family = {{{ makeGetValue('sa', 'Sockets.sockaddr_in_layout.sin_family', 'i16') }}};
- var port = _ntohs({{{ makeGetValue('sa', 'Sockets.sockaddr_in_layout.sin_port', 'i16') }}});
+ var family = {{{ makeGetValue('sa', C_STRUCTS.sockaddr_in.sin_family, 'i16') }}};
+ var port = _ntohs({{{ makeGetValue('sa', C_STRUCTS.sockaddr_in.sin_port, 'i16') }}});
var addr;
switch (family) {
case {{{ cDefine('AF_INET') }}}:
- if (salen !== Sockets.sockaddr_in_layout.__size__) {
+ if (salen !== {{{ C_STRUCTS.sockaddr_in.__size__ }}}) {
return { errno: ERRNO_CODES.EINVAL };
}
- addr = {{{ makeGetValue('sa', 'Sockets.sockaddr_in_layout.sin_addr', 'i32') }}};
+ addr = {{{ makeGetValue('sa', C_STRUCTS.sockaddr_in.sin_addr.s_addr, 'i32') }}};
addr = __inet_ntop4_raw(addr);
break;
case {{{ cDefine('AF_INET6') }}}:
- if (salen !== Sockets.sockaddr_in6_layout.__size__) {
+ if (salen !== {{{ C_STRUCTS.sockaddr_in6.__size__ }}}) {
return { errno: ERRNO_CODES.EINVAL };
}
addr = [
- {{{ makeGetValue('sa', 'Sockets.sockaddr_in6_layout.sin6_addr+0', 'i32') }}},
- {{{ makeGetValue('sa', 'Sockets.sockaddr_in6_layout.sin6_addr+4', 'i32') }}},
- {{{ makeGetValue('sa', 'Sockets.sockaddr_in6_layout.sin6_addr+8', 'i32') }}},
- {{{ makeGetValue('sa', 'Sockets.sockaddr_in6_layout.sin6_addr+12', 'i32') }}}
+ {{{ makeGetValue('sa', C_STRUCTS.sockaddr_in6.sin6_addr.__in6_union.__s6_addr+0, 'i32') }}},
+ {{{ makeGetValue('sa', C_STRUCTS.sockaddr_in6.sin6_addr.__in6_union.__s6_addr+4, 'i32') }}},
+ {{{ makeGetValue('sa', C_STRUCTS.sockaddr_in6.sin6_addr.__in6_union.__s6_addr+8, 'i32') }}},
+ {{{ makeGetValue('sa', C_STRUCTS.sockaddr_in6.sin6_addr.__in6_union.__s6_addr+12, 'i32') }}}
];
addr = __inet_ntop6_raw(addr);
break;
@@ -8157,18 +7988,18 @@ LibraryManager.library = {
switch (family) {
case {{{ cDefine('AF_INET') }}}:
addr = __inet_pton4_raw(addr);
- {{{ makeSetValue('sa', 'Sockets.sockaddr_in_layout.sin_family', 'family', 'i16') }}};
- {{{ makeSetValue('sa', 'Sockets.sockaddr_in_layout.sin_addr', 'addr', 'i32') }}};
- {{{ makeSetValue('sa', 'Sockets.sockaddr_in_layout.sin_port', '_htons(port)', 'i16') }}};
+ {{{ makeSetValue('sa', C_STRUCTS.sockaddr_in.sin_family, 'family', 'i16') }}};
+ {{{ makeSetValue('sa', C_STRUCTS.sockaddr_in.sin_addr.s_addr, 'addr', 'i32') }}};
+ {{{ makeSetValue('sa', C_STRUCTS.sockaddr_in.sin_port, '_htons(port)', 'i16') }}};
break;
case {{{ cDefine('AF_INET6') }}}:
addr = __inet_pton6_raw(addr);
- {{{ makeSetValue('sa', 'Sockets.sockaddr_in6_layout.sin6_family', 'family', 'i32') }}};
- {{{ makeSetValue('sa', 'Sockets.sockaddr_in6_layout.sin6_addr+0', 'addr[0]', 'i32') }}};
- {{{ makeSetValue('sa', 'Sockets.sockaddr_in6_layout.sin6_addr+4', 'addr[1]', 'i32') }}};
- {{{ makeSetValue('sa', 'Sockets.sockaddr_in6_layout.sin6_addr+8', 'addr[2]', 'i32') }}};
- {{{ makeSetValue('sa', 'Sockets.sockaddr_in6_layout.sin6_addr+12', 'addr[3]', 'i32') }}};
- {{{ makeSetValue('sa', 'Sockets.sockaddr_in6_layout.sin6_port', '_htons(port)', 'i16') }}};
+ {{{ makeSetValue('sa', C_STRUCTS.sockaddr_in6.sin6_family, 'family', 'i32') }}};
+ {{{ makeSetValue('sa', C_STRUCTS.sockaddr_in6.sin6_addr.__in6_union.__s6_addr+0, 'addr[0]', 'i32') }}};
+ {{{ makeSetValue('sa', C_STRUCTS.sockaddr_in6.sin6_addr.__in6_union.__s6_addr+4, 'addr[1]', 'i32') }}};
+ {{{ makeSetValue('sa', C_STRUCTS.sockaddr_in6.sin6_addr.__in6_union.__s6_addr+8, 'addr[2]', 'i32') }}};
+ {{{ makeSetValue('sa', C_STRUCTS.sockaddr_in6.sin6_addr.__in6_union.__s6_addr+12, 'addr[3]', 'i32') }}};
+ {{{ makeSetValue('sa', C_STRUCTS.sockaddr_in6.sin6_port, '_htons(port)', 'i16') }}};
break;
default:
return { errno: ERRNO_CODES.EAFNOSUPPORT };
@@ -8414,14 +8245,14 @@ LibraryManager.library = {
return -1;
}
- var iov = {{{ makeGetValue('message', 'Sockets.msghdr_layout.msg_iov', '*') }}};
- var num = {{{ makeGetValue('message', 'Sockets.msghdr_layout.msg_iovlen', 'i32') }}};
+ var iov = {{{ makeGetValue('message', C_STRUCTS.msghdr.msg_iov, '*') }}};
+ var num = {{{ makeGetValue('message', C_STRUCTS.msghdr.msg_iovlen, 'i32') }}};
// read the address and port to send to
var addr;
var port;
- var name = {{{ makeGetValue('message', 'Sockets.msghdr_layout.msg_name', '*') }}};
- var namelen = {{{ makeGetValue('message', 'Sockets.msghdr_layout.msg_namelen', 'i32') }}};
+ var name = {{{ makeGetValue('message', C_STRUCTS.msghdr.msg_name, '*') }}};
+ var namelen = {{{ makeGetValue('message', C_STRUCTS.msghdr.msg_namelen, 'i32') }}};
if (name) {
var info = __read_sockaddr(name, namelen);
if (info.errno) {
@@ -8435,13 +8266,13 @@ LibraryManager.library = {
// concatenate scatter-gather arrays into one message buffer
var total = 0;
for (var i = 0; i < num; i++) {
- total += {{{ makeGetValue('iov', '(Sockets.iovec_layout.__size__ * i) + Sockets.iovec_layout.iov_len', 'i32') }}};
+ total += {{{ makeGetValue('iov', '(' + C_STRUCTS.iovec.__size__ + ' * i) + ' + C_STRUCTS.iovec.iov_len, 'i32') }}};
}
var view = new Uint8Array(total);
var offset = 0;
for (var i = 0; i < num; i++) {
- var iovbase = {{{ makeGetValue('iov', '(Sockets.iovec_layout.__size__ * i) + Sockets.iovec_layout.iov_base', 'i8*') }}};
- var iovlen = {{{ makeGetValue('iov', '(Sockets.iovec_layout.__size__ * i) + Sockets.iovec_layout.iov_len', 'i32') }}};
+ var iovbase = {{{ makeGetValue('iov', '(' + C_STRUCTS.iovec.__size__ + ' * i) + ' + C_STRUCTS.iovec.iov_base, 'i8*') }}};
+ var iovlen = {{{ makeGetValue('iov', '(' + C_STRUCTS.iovec.__size__ + ' * i) + ' + C_STRUCTS.iovec.iov_len, 'i32') }}};
for (var j = 0; j < iovlen; j++) {
view[offset++] = {{{ makeGetValue('iovbase', 'j', 'i8') }}};
}
@@ -8464,13 +8295,13 @@ LibraryManager.library = {
return -1;
}
- var iov = {{{ makeGetValue('message', 'Sockets.msghdr_layout.msg_iov', 'i8*') }}};
- var num = {{{ makeGetValue('message', 'Sockets.msghdr_layout.msg_iovlen', 'i32') }}};
+ var iov = {{{ makeGetValue('message', C_STRUCTS.msghdr.msg_iov, 'i8*') }}};
+ var num = {{{ makeGetValue('message', C_STRUCTS.msghdr.msg_iovlen, 'i32') }}};
// get the total amount of data we can read across all arrays
var total = 0;
for (var i = 0; i < num; i++) {
- total += {{{ makeGetValue('iov', '(Sockets.iovec_layout.__size__ * i) + Sockets.iovec_layout.iov_len', 'i32') }}};
+ total += {{{ makeGetValue('iov', '(' + C_STRUCTS.iovec.__size__ + ' * i) + ' + C_STRUCTS.iovec.iov_len, 'i32') }}};
}
// try to read total data
@@ -8496,7 +8327,7 @@ LibraryManager.library = {
// Requests that the function block until the full amount of data requested can be returned. The function may return a smaller amount of data if a signal is caught, if the connection is terminated, if MSG_PEEK was specified, or if an error is pending for the socket.
// write the source address out
- var name = {{{ makeGetValue('message', 'Sockets.msghdr_layout.msg_name', '*') }}};
+ var name = {{{ makeGetValue('message', C_STRUCTS.msghdr.msg_name, '*') }}};
if (name) {
var res = __write_sockaddr(name, sock.family, DNS.lookup_name(msg.addr), msg.port);
assert(!res.errno);
@@ -8506,8 +8337,8 @@ LibraryManager.library = {
var bytesRemaining = msg.buffer.byteLength;
for (var i = 0; bytesRemaining > 0 && i < num; i++) {
- var iovbase = {{{ makeGetValue('iov', '(Sockets.iovec_layout.__size__ * i) + Sockets.iovec_layout.iov_base', 'i8*') }}};
- var iovlen = {{{ makeGetValue('iov', '(Sockets.iovec_layout.__size__ * i) + Sockets.iovec_layout.iov_len', 'i32') }}};
+ var iovbase = {{{ makeGetValue('iov', '(' + C_STRUCTS.iovec.__size__ + ' * i) + ' + C_STRUCTS.iovec.iov_base, 'i8*') }}};
+ var iovlen = {{{ makeGetValue('iov', '(' + C_STRUCTS.iovec.__size__ + ' * i) + ' + C_STRUCTS.iovec.iov_len, 'i32') }}};
if (!iovlen) {
continue;
}
diff --git a/src/parseTools.js b/src/parseTools.js
index 90c5acab..2ccf0179 100644
--- a/src/parseTools.js
+++ b/src/parseTools.js
@@ -5,11 +5,12 @@
// Does simple 'macro' substitution, using Django-like syntax,
// {{{ code }}} will be replaced with |eval(code)|.
+// NOTE: Be careful with that ret check. If ret is |0|, |ret ? ret.toString() : ''| would result in ''!
function processMacros(text) {
return text.replace(/{{{([^}]|}(?!}))+}}}/g, function(str) {
str = str.substr(3, str.length-6);
var ret = eval(str);
- return ret ? ret.toString() : '';
+ return ret !== null ? ret.toString() : '';
});
}
diff --git a/src/struct_info.json b/src/struct_info.json
new file mode 100644
index 00000000..5b969603
--- /dev/null
+++ b/src/struct_info.json
@@ -0,0 +1,822 @@
+[
+ {
+ "file": "libc/dirent.h",
+ "defines": [],
+ "structs": {
+ "dirent": [
+ "d_ino",
+ "d_off",
+ "d_reclen",
+ "d_type",
+ "d_name"
+ ]
+ }
+ },
+ {
+ "file": "libc/utime.h",
+ "defines": [],
+ "structs": {
+ "utimbuf": [
+ "actime",
+ "modtime"
+ ]
+ }
+ },
+ {
+ "file": "libc/sys/stat.h",
+ "defines": [
+ "S_IFDIR",
+ "S_IFREG",
+ "S_IFMT",
+ "S_IFIFO",
+ "S_IFSOCK",
+ "S_IFBLK",
+ "S_IFLNK",
+ "S_IFCHR"
+ ],
+ "structs": {
+ "stat": [
+ "st_dev",
+ "__st_dev_padding",
+ "__st_ino_truncated",
+ "st_mode",
+ "st_nlink",
+ "st_uid",
+ "st_gid",
+ "st_rdev",
+ "__st_rdev_padding",
+ "st_size",
+ "st_blksize",
+ "st_blocks",
+ {
+ "st_atim": [
+ "tv_sec",
+ "tv_nsec"
+ ]
+ },
+ {
+ "st_mtim": [
+ "tv_sec",
+ "tv_nsec"
+ ]
+ },
+ {
+ "st_ctim": [
+ "tv_sec",
+ "tv_nsec"
+ ]
+ },
+ "st_ino"
+ ]
+ }
+ },
+ {
+ "file": "libc/sys/statvfs.h",
+ "defines": [],
+ "structs": {
+ "statvfs": [
+ "f_bsize",
+ "f_frsize",
+ "f_blocks",
+ "f_bfree",
+ "f_bavail",
+ "f_files",
+ "f_ffree",
+ "f_favail",
+ "f_fsid",
+ "f_flag",
+ "f_namemax"
+ ]
+ }
+ },
+ {
+ "file": "libc/fcntl.h",
+ "defines": [
+ "F_UNLCK",
+ "O_RDWR",
+ "S_IRWXO",
+ "F_GETLK64",
+ "F_SETLKW64",
+ "F_SETLKW",
+ "F_SETLK64",
+ "F_GETLK",
+ "S_ISVTX",
+ "O_RDONLY",
+ "O_ACCMODE",
+ "F_DUPFD",
+ "F_SETLK",
+ "O_WRONLY"
+ ],
+ "structs": {
+ "flock": [
+ "l_type",
+ "l_whence",
+ "l_start",
+ "l_len",
+ "l_pid"
+ ]
+ }
+ },
+ {
+ "file": "libc/poll.h",
+ "defines": [
+ "POLLHUP",
+ "POLLERR",
+ "POLLRDNORM",
+ "POLLPRI",
+ "POLLIN",
+ "POLLOUT",
+ "POLLNVAL"
+ ],
+ "structs": {
+ "pollfd": [
+ "fd",
+ "events",
+ "revents"
+ ]
+ }
+ },
+ {
+ "file": "libc/stdlib.h",
+ "defines": [],
+ "structs": {
+ // NOTE: The hash sign at the end of this name is a hint to the processor that it mustn't prefix "struct " to the name to reference this struct.
+ // It will be stripped away when writing the compiled JSON file. You can just refer to it as C_STRUCTS.div_t when using it in the JS code.
+ // For more information see gen_inspect_code() in tools/gen_struct_info.py .
+ "div_t#": [
+ "quot",
+ "rem"
+ ]
+ }
+ },
+ {
+ "file": "libc/sys/utsname.h",
+ "defines": [],
+ "structs": {
+ "utsname": [
+ "sysname",
+ "nodename",
+ "release",
+ "version",
+ "machine",
+ "domainname"
+ ]
+ }
+ },
+ {
+ "file": "libc/time.h",
+ "defines": [
+ ["li", "CLOCKS_PER_SEC"]
+ ],
+ "structs": {
+ "timezone": [
+ "tz_minuteswest",
+ "tz_dsttime"
+ ],
+ "tm": [
+ "tm_sec",
+ "tm_min",
+ "tm_hour",
+ "tm_mday",
+ "tm_mon",
+ "tm_year",
+ "tm_wday",
+ "tm_yday",
+ "tm_isdst",
+ "tm_gmtoff",
+ "tm_zone"
+ ],
+ "itimerspec": [
+ {
+ "it_interval": [
+ "tv_sec",
+ "tv_nsec"
+ ]
+ },
+ {
+ "it_value": [
+ "tv_sec",
+ "tv_nsec"
+ ]
+ }
+ ],
+ "timespec": [
+ "tv_sec",
+ "tv_nsec"
+ ],
+ "timeval": [
+ "tv_sec",
+ "tv_usec"
+ ]
+ }
+ },
+ {
+ "file": "libc/sys/times.h",
+ "defines": [],
+ "structs": {
+ "tms": [
+ "tms_utime",
+ "tms_stime",
+ "tms_cutime",
+ "tms_cstime"
+ ]
+ }
+ },
+ {
+ "file": "libc/sys/resource.h",
+ "defines": [],
+ "structs": {
+ "rlimit": [
+ "rlim_cur",
+ "rlim_max"
+ ],
+ "rusage": [
+ {
+ "ru_utime": [
+ "tv_sec",
+ "tv_usec"
+ ]
+ },
+ {
+ "ru_stime": [
+ "tv_sec",
+ "tv_usec"
+ ]
+ },
+ "ru_maxrss",
+ "ru_ixrss",
+ "ru_idrss",
+ "ru_isrss",
+ "ru_minflt",
+ "ru_majflt",
+ "ru_nswap",
+ "ru_inblock",
+ "ru_oublock",
+ "ru_msgsnd",
+ "ru_msgrcv",
+ "ru_nsignals",
+ "ru_nvcsw",
+ "ru_nivcsw"
+ ]
+ }
+ },
+ {
+ "file": "libc/netdb.h",
+ "defines": [
+ "AI_V4MAPPED",
+ "EAI_SERVICE",
+ "EAI_FAMILY",
+ "AI_ALL",
+ "AI_ADDRCONFIG",
+ "AI_NUMERICSERV",
+ "NI_NUMERICHOST",
+ "EAI_OVERFLOW",
+ "AI_NUMERICHOST",
+ "AI_CANONNAME",
+ "AI_PASSIVE",
+ "NI_NAMEREQD",
+ "EAI_NONAME",
+ "EAI_SOCKTYPE",
+ "EAI_BADFLAGS"
+ ],
+ "structs": {
+ "sockaddr": [
+ "sa_family",
+ "sa_data"
+ ],
+ "hostent": [
+ "h_name",
+ "h_aliases",
+ "h_addrtype",
+ "h_length",
+ "h_addr_list"
+ ],
+ "addrinfo": [
+ "ai_flags",
+ "ai_family",
+ "ai_socktype",
+ "ai_protocol",
+ "ai_addrlen",
+ "ai_addr",
+ "ai_canonname",
+ "ai_next"
+ ],
+ "in_addr": [
+ "s_addr"
+ ],
+ "linger": [
+ "l_onoff",
+ "l_linger"
+ ],
+ "protoent": [
+ "p_name",
+ "p_aliases",
+ "p_proto"
+ ],
+ "sockaddr_in": [
+ "sin_family",
+ "sin_port",
+ {
+ "sin_addr": [
+ "s_addr"
+ ]
+ },
+ "sin_zero"
+ ],
+ "iovec": [
+ "iov_base",
+ "iov_len"
+ ],
+ "cmsghdr": [
+ "cmsg_len",
+ "cmsg_level",
+ "cmsg_type"
+ ],
+ "sockaddr_in6": [
+ "sin6_family",
+ "sin6_port",
+ "sin6_flowinfo",
+ {
+ "sin6_addr": [
+ {
+ "__in6_union": [
+ "__s6_addr",
+ "__s6_addr16",
+ "__s6_addr32"
+ ]
+ }
+ ]
+ },
+ "sin6_scope_id"
+ ],
+ "msghdr": [
+ "msg_name",
+ "msg_namelen",
+ "msg_iov",
+ "msg_iovlen",
+ "msg_control",
+ "msg_controllen",
+ "msg_flags"
+ ],
+ "in6_addr": [
+ {
+ "__in6_union": [
+ "__s6_addr",
+ "__s6_addr16",
+ "__s6_addr32"
+ ]
+ }
+ ],
+ "netent": [
+ "n_name",
+ "n_aliases",
+ "n_addrtype",
+ "n_net"
+ ]
+ }
+ },
+ {
+ "file": "libc/netinet/in.h",
+ "defines": [
+ "IPPROTO_UDP",
+ "IPPROTO_TCP",
+ "INADDR_LOOPBACK"
+ ],
+ "structs": {}
+ },
+ {
+ "file": "libc/math.h",
+ "defines": [
+ "FP_ZERO",
+ "FP_NAN",
+ "FP_INFINITE",
+ "FP_NORMAL"
+ ],
+ "structs": {}
+ },
+ {
+ "file": "libc/bits/fcntl.h",
+ "defines": [
+ "O_CREAT",
+ "O_SYNC",
+ "F_GETFD",
+ "F_SETFL",
+ "O_NOFOLLOW",
+ "O_APPEND",
+ "F_SETOWN",
+ "O_TRUNC",
+ "F_GETOWN",
+ "F_SETFD",
+ "O_EXCL",
+ "F_GETFL"
+ ],
+ "structs": {}
+ },
+ {
+ "file": "libc/sys/socket.h",
+ "defines": [
+ "SOCK_DGRAM",
+ "SOCK_STREAM",
+ "AF_INET",
+ "AF_UNSPEC",
+ "AF_INET6"
+ ],
+ "structs": {}
+ },
+ {
+ "file": "libc/bits/ioctl.h",
+ "defines": [
+ "FIONREAD"
+ ],
+ "structs": {}
+ },
+ {
+ "file": "libc/unistd.h",
+ "defines": [
+ "_SC_XOPEN_LEGACY",
+ "_SC_XOPEN_VERSION",
+ "_SC_BC_DIM_MAX",
+ "_CS_POSIX_V6_LP64_OFF64_LIBS",
+ "_PC_REC_MIN_XFER_SIZE",
+ "_SC_V6_ILP32_OFFBIG",
+ "_SC_MEMLOCK",
+ "_SC_THREADS",
+ "_PC_SOCK_MAXBUF",
+ "_SC_THREAD_KEYS_MAX",
+ "_SC_2_PBS",
+ "_SC_TRACE_INHERIT",
+ "_SC_REGEXP",
+ "_CS_POSIX_V6_LP64_OFF64_CFLAGS",
+ "_SC_VERSION",
+ "_PC_CHOWN_RESTRICTED",
+ "_SC_MQ_PRIO_MAX",
+ "_SC_PAGE_SIZE",
+ "_SC_BARRIERS",
+ "_SC_2_LOCALEDEF",
+ "_SC_STREAM_MAX",
+ "_SC_TIMERS",
+ "_PC_PATH_MAX",
+ "_SC_SPORADIC_SERVER",
+ "_SC_NPROCESSORS_ONLN",
+ "_CS_POSIX_V6_LPBIG_OFFBIG_LIBS",
+ "_PC_MAX_INPUT",
+ "_SC_CLK_TCK",
+ "_SC_AIO_MAX",
+ "_SC_THREAD_PRIO_INHERIT",
+ "_PC_2_SYMLINKS",
+ "_SC_SPAWN",
+ "_CS_POSIX_V6_ILP32_OFF32_LDFLAGS",
+ "_CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS",
+ "_SC_TRACE_SYS_MAX",
+ "_CS_POSIX_V6_WIDTH_RESTRICTED_ENVS",
+ "_SC_AIO_PRIO_DELTA_MAX",
+ "_SC_MONOTONIC_CLOCK",
+ "_SC_XOPEN_ENH_I18N",
+ "_SC_SPIN_LOCKS",
+ "_SC_XOPEN_SHM",
+ "_PC_LINK_MAX",
+ "_SC_FSYNC",
+ "_SC_GETGR_R_SIZE_MAX",
+ "_SC_TRACE_NAME_MAX",
+ "_SC_BC_BASE_MAX",
+ "_SC_XOPEN_STREAMS",
+ "_SC_GETPW_R_SIZE_MAX",
+ "_SC_CPUTIME",
+ "_SC_XBS5_ILP32_OFFBIG",
+ "_SC_TRACE_EVENT_FILTER",
+ "_SC_OPEN_MAX",
+ "_SC_2_FORT_RUN",
+ "_SC_RE_DUP_MAX",
+ "_SC_THREAD_PRIO_PROTECT",
+ "_SC_2_PBS_CHECKPOINT",
+ "_SC_XBS5_LPBIG_OFFBIG",
+ "_SC_SHARED_MEMORY_OBJECTS",
+ "_PC_ALLOC_SIZE_MIN",
+ "_SC_READER_WRITER_LOCKS",
+ "_SC_MEMLOCK_RANGE",
+ "_SC_PRIORITY_SCHEDULING",
+ "_PC_VDISABLE",
+ "_SC_MESSAGE_PASSING",
+ "_SC_THREAD_ATTR_STACKADDR",
+ "_SC_THREAD_THREADS_MAX",
+ "_SC_LOGIN_NAME_MAX",
+ "_SC_2_C_BIND",
+ "_PC_NO_TRUNC",
+ "_SC_SHELL",
+ "_SC_V6_LP64_OFF64",
+ "_CS_GNU_LIBC_VERSION",
+ "_SC_SEM_VALUE_MAX",
+ "_SC_MQ_OPEN_MAX",
+ "_SC_HOST_NAME_MAX",
+ "_SC_THREAD_STACK_MIN",
+ "_SC_TIMEOUTS",
+ "_SC_CHILD_MAX",
+ "_SC_2_PBS_MESSAGE",
+ "_SC_2_C_DEV",
+ "_SC_TIMER_MAX",
+ "_SC_SYMLOOP_MAX",
+ "_PC_REC_XFER_ALIGN",
+ "_SC_REALTIME_SIGNALS",
+ "_PC_ASYNC_IO",
+ "_SC_MAPPED_FILES",
+ "_SC_NGROUPS_MAX",
+ "_SC_SEMAPHORES",
+ "_SC_TRACE_LOG",
+ "_CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS",
+ "_CS_POSIX_V6_LP64_OFF64_LDFLAGS",
+ "_SC_THREAD_DESTRUCTOR_ITERATIONS",
+ "_SC_TRACE_EVENT_NAME_MAX",
+ "_SC_BC_STRING_MAX",
+ "_SC_2_SW_DEV",
+ "_SC_ARG_MAX",
+ "_SC_THREAD_PRIORITY_SCHEDULING",
+ "_SC_THREAD_CPUTIME",
+ "_CS_POSIX_V6_ILP32_OFF32_LIBS",
+ "_SC_SYNCHRONIZED_IO",
+ "_CS_POSIX_V6_ILP32_OFF32_CFLAGS",
+ "_SC_MEMORY_PROTECTION",
+ "_PC_PRIO_IO",
+ "_SC_V6_LPBIG_OFFBIG",
+ "_SC_EXPR_NEST_MAX",
+ "_CS_POSIX_V6_ILP32_OFFBIG_CFLAGS",
+ "_PC_REC_MAX_XFER_SIZE",
+ "_SC_DELAYTIMER_MAX",
+ "W_OK",
+ "R_OK",
+ "_SC_XOPEN_CRYPT",
+ "_SC_XBS5_LP64_OFF64",
+ "_SC_SIGQUEUE_MAX",
+ "_SC_TZNAME_MAX",
+ "_CS_PATH",
+ "_PC_MAX_CANON",
+ "_SC_THREAD_SAFE_FUNCTIONS",
+ "_PC_NAME_MAX",
+ "_SC_TRACE_USER_EVENT_MAX",
+ "_SC_RAW_SOCKETS",
+ "_SC_RTSIG_MAX",
+ "_SC_PRIORITIZED_IO",
+ "_SC_XOPEN_UNIX",
+ "_PC_REC_INCR_XFER_SIZE",
+ "_PC_FILESIZEBITS",
+ "_SC_XBS5_ILP32_OFF32",
+ "_CS_GNU_LIBPTHREAD_VERSION",
+ "_SC_2_PBS_LOCATE",
+ "_SC_V6_ILP32_OFF32",
+ "_PC_SYNC_IO",
+ "_SC_2_UPE",
+ "_SC_SEM_NSEMS_MAX",
+ "_SC_IOV_MAX",
+ "_SC_TRACE",
+ "_CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS",
+ "_SC_LINE_MAX",
+ "_CS_POSIX_V6_ILP32_OFFBIG_LIBS",
+ "_SC_2_FORT_DEV",
+ "_SC_ATEXIT_MAX",
+ "_SC_SAVED_IDS",
+ "_SC_2_PBS_TRACK",
+ "_SC_THREAD_PROCESS_SHARED",
+ "_SC_JOB_CONTROL",
+ "_SC_IPV6",
+ "_SC_ADVISORY_INFO",
+ "_SC_XOPEN_REALTIME_THREADS",
+ "_PC_SYMLINK_MAX",
+ "X_OK",
+ "_SC_COLL_WEIGHTS_MAX",
+ "_SC_CLOCK_SELECTION",
+ "_SC_XOPEN_REALTIME",
+ "_PC_PIPE_BUF",
+ "_SC_2_PBS_ACCOUNTING",
+ "_SC_THREAD_SPORADIC_SERVER",
+ "_SC_THREAD_ATTR_STACKSIZE",
+ "_SC_2_VERSION",
+ "_SC_TYPED_MEMORY_OBJECTS",
+ "_SC_ASYNCHRONOUS_IO",
+ "_SC_2_CHAR_TERM",
+ "_SC_AIO_LISTIO_MAX",
+ "_SC_BC_SCALE_MAX",
+ "_SC_TTY_NAME_MAX"
+ ],
+ "structs": {}
+ },
+ {
+ "file": "libc/bits/errno.h",
+ "defines": [
+ "ETXTBSY",
+ "ETOOMANYREFS",
+ "ENAMETOOLONG",
+ "ENOPKG",
+ "EL3HLT",
+ "EINPROGRESS",
+ "ENOTSOCK",
+ "ENOTSUP",
+ "EFBIG",
+ "ENOLINK",
+ "EL3RST",
+ "ENOTUNIQ",
+ "ELNRNG",
+ "ENOANO",
+ "ENOPROTOOPT",
+ "E2BIG",
+ "EHOSTDOWN",
+ "EBFONT",
+ "ENOTEMPTY",
+ "EBUSY",
+ "EADDRINUSE",
+ "ELIBACC",
+ "EDQUOT",
+ "ENOENT",
+ "ECOMM",
+ "EXFULL",
+ "ENOTDIR",
+ "ENETRESET",
+ "EAFNOSUPPORT",
+ "EINVAL",
+ "ENODEV",
+ "ENOCSI",
+ "EPROTONOSUPPORT",
+ "ETIME",
+ "ENOTTY",
+ "EAGAIN",
+ "EMSGSIZE",
+ "ELIBEXEC",
+ "EMLINK",
+ "ECANCELED",
+ "EDESTADDRREQ",
+ "EADDRNOTAVAIL",
+ "EPERM",
+ "EPROTOTYPE",
+ "ENOMEDIUM",
+ "ELOOP",
+ "EREMOTE",
+ "ELIBMAX",
+ "EMULTIHOP",
+ "ECONNABORTED",
+ "EFAULT",
+ "EBADMSG",
+ "EDOM",
+ "EILSEQ",
+ "EPFNOSUPPORT",
+ "ENONET",
+ "ECHRNG",
+ "ESRCH",
+ "EHOSTUNREACH",
+ "EL2HLT",
+ "EL2NSYNC",
+ "ENOMSG",
+ "EISDIR",
+ "EDEADLOCK",
+ "ECONNRESET",
+ "ESTRPIPE",
+ "ESHUTDOWN",
+ "EDEADLK",
+ "EBADRQC",
+ "EUNATCH",
+ "ECHILD",
+ "ETIMEDOUT",
+ "EALREADY",
+ "ENXIO",
+ "EMFILE",
+ "ENFILE",
+ "EREMCHG",
+ "ENOMEM",
+ "ENOSR",
+ "EOWNERDEAD",
+ "ELIBSCN",
+ "EPIPE",
+ "EBADSLT",
+ "ENOSTR",
+ "EIO",
+ "EWOULDBLOCK",
+ "EBADE",
+ "ENODATA",
+ "ESOCKTNOSUPPORT",
+ "ENOLCK",
+ "EPROTO",
+ "ESRMNT",
+ "EXDEV",
+ "ENOSPC",
+ "ELIBBAD",
+ "ERANGE",
+ "ESTALE",
+ "ENOTRECOVERABLE",
+ "ENOBUFS",
+ "EIDRM",
+ "EINTR",
+ "EADV",
+ "ENOSYS",
+ "EUSERS",
+ "EOPNOTSUPP",
+ "ENOTCONN",
+ "ENETUNREACH",
+ "ESPIPE",
+ "EROFS",
+ "ECONNREFUSED",
+ "ENETDOWN",
+ "ENOEXEC",
+ "EBADF",
+ "EDOTDOT",
+ "EBADFD",
+ "EBADR",
+ "EISCONN",
+ "ENOTBLK",
+ "EOVERFLOW"
+ ],
+ "structs": {}
+ },
+ {
+ "file": "libc/langinfo.h",
+ "defines": [
+ "ABDAY_7",
+ "ABDAY_6",
+ "ABDAY_5",
+ "ABDAY_4",
+ "ABDAY_3",
+ "ABDAY_2",
+ "ABDAY_1",
+ "ABMON_1",
+ "RADIXCHAR",
+ "ABMON_3",
+ "AM_STR",
+ "ALT_DIGITS",
+ "PM_STR",
+ "ABMON_9",
+ "YESEXPR",
+ "ABMON_2",
+ "ABMON_7",
+ "ABMON_6",
+ "ABMON_5",
+ "ABMON_4",
+ "ABMON_8",
+ "ERA",
+ "MON_2",
+ "MON_3",
+ "MON_1",
+ "MON_6",
+ "MON_7",
+ "MON_4",
+ "MON_5",
+ "MON_8",
+ "MON_9",
+ "NOEXPR",
+ "T_FMT_AMPM",
+ "MON_10",
+ "MON_11",
+ "MON_12",
+ "T_FMT",
+ "THOUSEP",
+ "ERA_T_FMT",
+ "ERA_D_T_FMT",
+ "D_FMT",
+ "DAY_2",
+ "DAY_3",
+ "DAY_1",
+ "DAY_6",
+ "DAY_7",
+ "DAY_4",
+ "DAY_5",
+ "ERA_D_FMT",
+ "CODESET",
+ "D_T_FMT",
+ "CRNCYSTR",
+ "ABMON_12",
+ "ABMON_11",
+ "ABMON_10"
+ ],
+ "structs": {}
+ },
+ {
+ "file": "libc/stdio.h",
+ "defines": [
+ "EOF",
+ "SEEK_END",
+ "SEEK_SET"
+ ],
+ "structs": {}
+ },
+ {
+ "file": "libc/arpa/tftp.h",
+ "defines": [
+ "EACCES",
+ "EEXIST"
+ ],
+ "structs": {}
+ },
+ {
+ "file": "compat/sys/stat.h",
+ "defines": [
+ "S_IALLUGO",
+ "S_IWUGO",
+ "S_IRUGO",
+ "S_IRWXUGO",
+ "S_IXUGO"
+ ],
+ "structs": {}
+ },
+ {
+ "file": "libc/bits/mman.h",
+ "defines": [
+ "MAP_PRIVATE"
+ ],
+ "structs": {}
+ }
+]
diff --git a/tools/gen_struct_info.py b/tools/gen_struct_info.py
index 563b4fa1..203a18ec 100644
--- a/tools/gen_struct_info.py
+++ b/tools/gen_struct_info.py
@@ -75,29 +75,38 @@ The JSON output format is based on the return value of Runtime.generateStructInf
'''
-import sys
-import os
-import json
-import argparse
-import tempfile
-import subprocess
+import sys, os, re, json, argparse, tempfile, subprocess
import shared
+QUIET = (__name__ != '__main__')
+
+def show(msg):
+ global QUIET
+ if not QUIET:
+ sys.stderr.write(msg + '\n')
# Try to load pycparser.
try:
import pycparser
except ImportError:
# The import failed, warn the user.
- sys.stderr.write('WARN: pycparser isn\'t available. I won\'t be able to parse C files, only .json files.\n')
+ show('WARN: pycparser isn\'t available. I won\'t be able to parse C files, only .json files.')
def parse_header(path, cpp_opts):
# Tell the user how to get pycparser, if he tries to parse a C file.
sys.stderr.write('ERR: I need pycparser to process C files. \n')
- sys.stderr.write(' Use "pip install pycparser" or go to "https://github.com/eliben/pycparser" to install it.\n')
+ sys.stderr.write(' Use "pip install pycparser" to install or download it from "https://github.com/eliben/pycparser".\n')
sys.exit(1)
else:
# We successfully imported pycparser, the script will be completely functional.
+ class DelayedRef(object):
+ def __init__(self, dest):
+ self.dest = dest
+
+ def __str__(self):
+ return self.dest
+
+ # For a list of node types and their fields, look here: https://github.com/eliben/pycparser/blob/master/pycparser/_c_ast.cfg
class FieldVisitor(pycparser.c_ast.NodeVisitor):
def __init__(self):
self._name = None
@@ -106,21 +115,30 @@ else:
def visit_Struct(self, node):
if node.decls == None:
- # Skip empty struct declarations.
+ self.named_structs[self._name] = DelayedRef(node.name)
return
+
fields = []
for decl in node.decls:
- # Look for nested structs.
- subwalk = FieldVisitor()
- subwalk.visit(decl)
+ if decl.name == None:
+ # Well, this field doesn't have a name.
+ continue
- if subwalk.named_structs:
- # Store the nested fields.
- fields.append(subwalk.named_structs)
- else:
- # Just store the field name.
+ if decl.type != None and isinstance(decl.type, pycparser.c_ast.PtrDecl):
+ # This field is a pointer, there's no point in looking for nested structs.
fields.append(decl.name)
+ else:
+ # Look for nested structs.
+ subwalk = FieldVisitor()
+ subwalk.visit(decl)
+
+ if subwalk.named_structs:
+ # Store the nested fields.
+ fields.append(subwalk.named_structs)
+ else:
+ # Just store the field name.
+ fields.append(decl.name)
if node.name != None:
self.structs[node.name] = fields
@@ -136,9 +154,68 @@ else:
self._name = node.declname
self.generic_visit(node)
self._name = old_name
-
+
+ # The first parameter is a structure, the second is a path (a list containing all the keys, needed to reach the destination).
+ # The last parameter is an item to look for. This function will try to follow the path into the given object and then look there for this key.
+ # As long as the nested object doesn't have the given key, it will descent into the next higher object till it finds the given key.
+ #
+ # Example:
+ #
+ # res = look_through({
+ # 'la1': {
+ # 'lb1': {
+ # 'lc1': 99,
+ # 'lc2': { 'ld1': 11 }
+ # 'lc2': 200
+ # },
+ # 'nice': 100
+ # },
+ # 'nice': 300
+ # }, ['la1', 'lb1', 'lc2'], 'nice')
+ #
+ # print(res) # Prints 100 .
+ #
+ # In this case the function looked inside obj['la1']['lb1']['lc2']['nice'], then obj['la1']['lb1']['nice'] and found the value
+ # in obj['la1']['nice']. As soon as it finds a value it returns it and stops looking.
+ def look_through(obj, path, name):
+ cur_level = obj
+ path = path[:]
+ for i, p in enumerate(path):
+ cur_level = cur_level[p]
+ path[i] = cur_level
+
+ path = [ obj ] + path
+
+ while len(path) > 0:
+ if name in path[-1]:
+ return path[-1][name]
+ else:
+ path.pop()
+
+ return None
+
+ # Use the above function to resolve all DelayedRef() inside a list or dict recursively.
+ def resolve_delayed(item, root=None, path=[]):
+ if root == None:
+ root = item
+
+ if isinstance(item, DelayedRef):
+ if item.dest in path:
+ show('WARN: Circular reference found! Field "' + path[-1] + '" references "' + item.dest + '"! (Path = ' + '/'.join([str(part) for part in path]) + ')')
+ return { '__ref__': item.dest }
+ else:
+ return look_through(root, path[:-1], item.dest)
+ elif isinstance(item, dict):
+ for name, val in item.items():
+ item[name] = resolve_delayed(val, root, path + [ name ])
+ elif isinstance(item, list):
+ for i, val in enumerate(item):
+ item[i] = resolve_delayed(val, root, path + [ i ])
+
+ return item
+
def parse_header(path, cpp_opts):
- sys.stderr.write('Parsing header "' + path + '"...\n')
+ show('Parsing header "' + path + '"...')
# Use clang -E as the preprocessor for pycparser.
ast = pycparser.parse_file(path, True, cpp_path=shared.CLANG_CC, cpp_args=['-E'] + cpp_opts)
@@ -146,10 +223,37 @@ else:
# Walk the parsed AST and filter out all the declared structs and their fields.
walker = FieldVisitor()
walker.visit(ast)
- return walker.structs
+
+ walker.structs = resolve_delayed(walker.structs)
+ with open(path, 'r') as stream:
+ defines = re.findall(r'(?:^|\n)#define\s+([A-Z|_]+)\s.*', stream.read())
+
+ return {
+ 'file': path,
+ 'defines': defines,
+ 'structs': walker.structs
+ }
# The following three functions generate C code. The output of the compiled code will be
# parsed later on and then put back together into a dict structure by parse_c_output().
+#
+# Example:
+# c_descent('test1', code)
+# c_set('item', 'i%i', '111', code)
+# c_set('item2', 'i%i', '9', code)
+# c_set('item3', 's%s', '"Hello"', code)
+# c_ascent(code)
+# c_set('outer', 'f%f', '0.999', code)
+#
+# Will result in:
+# {
+# 'test1': {
+# 'item': 111,
+# 'item2': 9,
+# 'item3': 'Hello',
+# },
+# 'outer': 0.999
+# }
def c_set(name, type_, value, code):
code.append('printf("K' + name + '\\n");')
code.append('printf("V' + type_ + '\\n", ' + value + ');')
@@ -173,7 +277,14 @@ def parse_c_output(lines):
key = arg
elif line[0] == 'V':
# A value
- cur_level[key] = int(arg)
+ if arg[0] == 'i':
+ arg = int(arg[1:])
+ elif arg[0] == 'f':
+ arg = float(arg[1:])
+ elif arg[0] == 's':
+ arg = arg[1:]
+
+ cur_level[key] = arg
elif line[0] == 'D':
# Remember the current level as the last parent.
parent.append(cur_level)
@@ -188,11 +299,19 @@ def parse_c_output(lines):
return result
def gen_inspect_code(path, struct, code):
+ if path[0][-1] == '#':
+ path[0] = path[0][:-1]
+ prefix = ''
+ else:
+ prefix = 'struct '
+
c_descent(path[-1], code)
+
if len(path) == 1:
- c_set('__size__', '%lu', 'sizeof (struct ' + path[0] + ')', code)
+ c_set('__size__', 'i%u', 'sizeof (' + prefix + path[0] + ')', code)
else:
- c_set('__size__', '%lu', 'sizeof ((struct ' + path[0] + ' *)0)->' + '.'.join(path[1:]), code)
+ c_set('__size__', 'i%u', 'sizeof ((' + prefix + path[0] + ' *)0)->' + '.'.join(path[1:]), code)
+ #c_set('__offset__', 'i%u', 'offsetof(' + prefix + path[0] + ', ' + '.'.join(path[1:]) + ')', code)
for field in struct:
if isinstance(field, dict):
@@ -200,12 +319,12 @@ def gen_inspect_code(path, struct, code):
fname = field.keys()[0]
gen_inspect_code(path + [fname], field[fname], code)
else:
- c_set(field, '%u', 'offsetof(struct ' + path[0] + ', ' + '.'.join(path[1:] + [field]) + ')', code)
+ c_set(field, 'i%u', 'offsetof(' + prefix + path[0] + ', ' + '.'.join(path[1:] + [field]) + ')', code)
c_ascent(code)
def inspect_code(headers, cpp_opts, structs, defines):
- sys.stderr.write('Generating C code...\n')
+ show('Generating C code...')
code = ['#include <stdio.h>', '#include <stddef.h>']
# Include all the needed headers.
@@ -219,19 +338,27 @@ def inspect_code(headers, cpp_opts, structs, defines):
c_ascent(code)
c_descent('defines', code)
- for name in defines:
- if isinstance(name, list):
- type_, name = name
- else:
- type_ = 'i'
- c_set(name, '%' + type_, name, code)
+ for name, type_ in defines.items():
+ # Add the necessary python type, if missing.
+ if '%' not in type_:
+ if type_[-1] in ('d', 'i', 'u'):
+ # integer
+ type_ = 'i%' + type_
+ elif type_[-1] in ('f', 'F', 'e', 'E', 'g', 'G'):
+ # float
+ type_ = 'f%' + type_
+ elif type_[-1] in ('x', 'X', 'a', 'A', 'c', 's'):
+ # hexadecimal or string
+ type_ = 's%' + type_
+
+ c_set(name, type_, name, code)
code.append('return 0;')
code.append('}')
# Write the source code to a temporary file.
src_file = tempfile.mkstemp('.c')
- bin_file = tempfile.mkstemp()
+ bin_file = tempfile.mkstemp('.ll')
os.write(src_file[0], '\n'.join(code))
@@ -239,15 +366,18 @@ def inspect_code(headers, cpp_opts, structs, defines):
os.close(src_file[0])
os.close(bin_file[0])
+ # NOTE: We can't generate an executable in the next step because it won't run on the current system without changing the target.
+ # If we change the target, some type sizes will change resulting in wrong data. As a workaround, we will be generating bitcode and
+ # run that with the LLVM interpreter. That way we can use the default target and still run the code.
info = []
try:
# Compile the program.
- sys.stderr.write('Compiling generated code...\n')
- subprocess.check_call([shared.CLANG_CC] + cpp_opts + ['-o', bin_file[1], src_file[1]])
+ show('Compiling generated code...')
+ subprocess.check_call([shared.CLANG_CC, '-emit-llvm', '-S'] + cpp_opts + ['-o', bin_file[1], src_file[1]])
# Run the compiled program.
- sys.stderr.write('Calling generated program...\n')
- info = subprocess.check_output([bin_file[1]]).splitlines()
+ show('Calling generated program...')
+ info = subprocess.check_output([shared.LLVM_INTERPRETER, bin_file[1]]).splitlines()
except subprocess.CalledProcessError:
if os.path.isfile(bin_file[1]):
sys.stderr.write('FAIL: Running the generated program failed!\n')
@@ -263,47 +393,75 @@ def inspect_code(headers, cpp_opts, structs, defines):
os.unlink(bin_file[1])
# Parse the output of the program into a dict.
- data = parse_c_output(info)
+ return parse_c_output(info)
+
+def parse_json(path, header_files, structs, defines):
+ with open(path, 'r') as stream:
+ # Remove comments before loading the JSON.
+ data = json.loads(re.sub(r'//.*\n', '', stream.read()))
- # Convert all the define's values into the appropriate python types (based on the type passed to printf).
- for name in defines:
- if isinstance(name, list):
- type_, name = name
- else:
- type_ = 'i'
+ if not isinstance(data, list):
+ data = [ data ]
+
+ for item in data:
+ header_files.append(item['file'])
+ for name, data in item['structs'].items():
+ if name in structs:
+ show('WARN: Description of struct "' + name + '" in file "' + item['file'] + '" replaces an existing description!')
+
+ structs[name] = data
- if type_[-1] in ('d', 'i', 'u'):
- # Integer
- data['defines'][name] = int(data['defines'][name])
- elif type_[-1] in ('x', 'X', 'a', 'A'):
- # Hexadecimal
- data['defines'][name] = float.fromhex(data['defines'][name])
- elif type_[-1] in ('f', 'F', 'e', 'E', 'g', 'G'):
- # Float
- data['defines'][name] = float(data['defines'][name])
- # Leave everything else untouched.
-
- return data
+ for part in item['defines']:
+ if not isinstance(part, list):
+ # If no type is specified, assume integer.
+ part = ['i', part]
+
+ if part[1] in defines:
+ show('WARN: Description of define "' + part[1] + '" in file "' + item['file'] + '" replaces an existing description!')
+
+ defines[part[1]] = part[0]
+
+def output_json(obj, compressed=True, stream=None):
+ if stream == None:
+ stream = sys.stdout
+ elif isinstance(stream, str):
+ stream = open(stream, 'w')
+
+ if compressed:
+ json.dump(obj, stream, separators=(',', ':'))
+ else:
+ json.dump(obj, stream, indent=4, sort_keys=True)
+
+ stream.close()
+
+def filter_opts(opts):
+ # Only apply compiler options regarding syntax, includes and defines.
+ # We have to compile for the current system, we aren't compiling to bitcode after all.
+ out = []
+ for flag in opts:
+ if flag[:2] in ('-f', '-I', '-i', '-D', '-U'):
+ out.append(flag)
+
+ return out
-def main():
+def main(args):
+ global QUIET
+
parser = argparse.ArgumentParser(description='Generate JSON infos for structs.')
parser.add_argument('headers', nargs='+', help='A header (.h) file or a JSON file with a list of structs and their fields')
- parser.add_argument('-f', dest='list_fields', action='store_true', default=False, help='Output a list of structs and fields for the first header.')
+ parser.add_argument('-q', dest='quiet', action='store_true', default=False, help='Don\'t output anything besides error messages.')
+ parser.add_argument('-f', dest='list_fields', action='store_true', default=False, help='Output a list of structs and fields for the given headers.')
parser.add_argument('-p', dest='pretty_print', action='store_true', default=False, help='Pretty print the outputted JSON.')
parser.add_argument('-o', dest='output', metavar='path', default=None, help='Path to the JSON file that will be written. If omitted, the generated data will be printed to stdout.')
parser.add_argument('-I', dest='includes', metavar='dir', action='append', default=[], help='Add directory to include search path')
parser.add_argument('-D', dest='defines', metavar='define', action='append', default=[], help='Pass a define to the preprocessor')
parser.add_argument('-U', dest='undefines', metavar='undefine', action='append', default=[], help='Pass an undefine to the preprocessor')
- args = parser.parse_args()
+ args = parser.parse_args(args)
- # Avoid parsing problems due to gcc specifc syntax.
- cpp_opts = ['-U__GNUC__']
+ QUIET = args.quiet
- # Only apply compiler options regarding syntax, includes and defines.
- # We have to compile for the current system, we aren't compiling to bitcode after all.
- for flag in shared.COMPILER_OPTS:
- if flag[:2] in ('-f', '-I', '-i', '-D', '-U'):
- cpp_opts.append(flag)
+ # Avoid parsing problems due to gcc specifc syntax.
+ cpp_opts = ['-U__GNUC__', '-D_GNU_SOURCE'] + shared.COMPILER_OPTS
# Add the user options to the list as well.
for path in args.includes:
@@ -316,20 +474,15 @@ def main():
cpp_opts.append('-U' + arg)
if args.list_fields:
- # Just parse the first header and output the result.
- structs = parse_header(args.headers[0], cpp_opts)
- data = {
- 'file': args.headers[0],
- 'structs': structs,
- 'defines': []
- }
-
- if args.output == None:
- sys.stdout.write(json.dumps(data, indent=4 if args.pretty_print else None))
- else:
- with open(args.output, 'w') as stream:
- json.dump(data, stream, indent=4 if args.pretty_print else None)
+ # Just parse the given headers and output the result.
+ data = []
+ for path in args.headers:
+ if path[-5:] == '.json':
+ show('WARN: Skipping "' + path + '" because it\'s already a JSON file!')
+ else:
+ data.append(parse_header(path, cpp_opts))
+ output_json(data, not args.pretty_print, args.output)
sys.exit(0)
# Look for structs in all passed headers.
@@ -339,30 +492,18 @@ def main():
for header in args.headers:
if header[-5:] == '.json':
- # This is a JSON file, simply load it.
- with open(header, 'r') as stream:
- data = json.load(stream)
-
- if not isinstance(data, list):
- data = [ data ]
-
- for item in data:
- header_files.append(item['file'])
- structs.update(item['structs'])
- defines.update(item['defines'])
+ # This is a JSON file, parse it.
+ parse_json(header, header_files, structs, defines)
else:
# If the passed file isn't a JSON file, assume it's a header.
header_files.append(header)
- structs.update(parse_header(header, cpp_opts))
+ data = parse_header(header, cpp_opts)
+ structs.update(data['structs'])
+ defines.extend(data['defines'])
# Inspect all collected structs.
struct_info = inspect_code(header_files, cpp_opts, structs, defines)
-
- if args.output == None:
- sys.stdout.write(json.dumps(struct_info, indent=4 if args.pretty_print else None))
- else:
- with open(args.output, 'w') as stream:
- json.dump(struct_info, stream, indent=4 if args.pretty_print else None)
+ output_json(struct_info, not args.pretty_print, args.output)
if __name__ == '__main__':
- main() \ No newline at end of file
+ main(sys.argv[1:]) \ No newline at end of file
diff --git a/tools/shared.py b/tools/shared.py
index a07bdeaf..76802eaa 100644
--- a/tools/shared.py
+++ b/tools/shared.py
@@ -354,7 +354,7 @@ def check_sanity(force=False):
logging.critical('Node.js (%s) does not seem to work, check the paths in %s' % (NODE_JS, EM_CONFIG))
sys.exit(1)
- for cmd in [CLANG, LINK_CMD[0], LLVM_AR, LLVM_OPT, LLVM_AS, LLVM_DIS, LLVM_NM]:
+ for cmd in [CLANG, LINK_CMD[0], LLVM_AR, LLVM_OPT, LLVM_AS, LLVM_DIS, LLVM_NM, LLVM_INTERPRETER]:
if not os.path.exists(cmd) and not os.path.exists(cmd + '.exe'): # .exe extension required for Windows
logging.critical('Cannot find %s, check the paths in %s' % (cmd, EM_CONFIG))
sys.exit(1)
@@ -1445,7 +1445,15 @@ class Building:
if not ok:
logging.error('bootstrapping relooper failed. You may need to manually create relooper.js by compiling it, see src/relooper/emscripten')
1/0
-
+
+ @staticmethod
+ def ensure_struct_info(info_path):
+ if os.path.exists(info_path): return
+ Cache.ensure()
+
+ import gen_struct_info
+ gen_struct_info.main(['-o', info_path, path_from_root('src/struct_info.json')])
+
@staticmethod
def preprocess(infile, outfile):
'''