aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/library.js158
1 files changed, 54 insertions, 104 deletions
diff --git a/src/library.js b/src/library.js
index e6ca3851..c13e2ba0 100644
--- a/src/library.js
+++ b/src/library.js
@@ -854,12 +854,14 @@ LibraryManager.library = {
__flock_struct_layout: Runtime.generateStructInfo(null, '%struct.flock'),
open__deps: ['$FS', '__setErrNo', '$ERRNO_CODES', '__dirent_struct_layout'],
- open: function(path, oflag, mode) {
+ open: function(path, oflag, varargs) {
// int open(const char *path, int oflag, ...);
// http://pubs.opengroup.org/onlinepubs/009695399/functions/open.html
// NOTE: This implementation tries to mimic glibc rather that strictly
// following the POSIX standard.
+ var mode = {{{ makeGetValue('varargs', 0, 'i32') }}};
+
// Simplify flags.
var accessMode = oflag & 0x3; // O_ACCMODE.
var isWrite = accessMode != 0x0; // O_RDONLY.
@@ -958,10 +960,12 @@ LibraryManager.library = {
creat: function(path, mode) {
// int creat(const char *path, mode_t mode);
// http://pubs.opengroup.org/onlinepubs/009695399/functions/creat.html
- return _open(path, 0x241, mode); // O_WRONLY | O_CREAT | O_TRUNC.
+ var modePtr = allocate([mode, 0, 0, 0], 'i32', ALLOC_STACK);
+ var ret = _open(path, 0x241, modePtr); // O_WRONLY | O_CREAT | O_TRUNC.
+ return ret;
},
fcntl__deps: ['$FS', '__setErrNo', '$ERRNO_CODES', '__flock_struct_layout'],
- fcntl: function(fildes, cmd, arg) {
+ fcntl: function(fildes, cmd, varargs) {
// int fcntl(int fildes, int cmd, ...);
// http://pubs.opengroup.org/onlinepubs/009695399/functions/fcntl.html
if (!(fildes in FS.streams)) {
@@ -971,6 +975,7 @@ LibraryManager.library = {
var stream = FS.streams[fildes];
switch (cmd) {
case 0: // F_DUPFD.
+ var arg = {{{ makeGetValue('varargs', 0, 'i32') }}};
if (arg < 0) {
___setErrNo(ERRNO_CODES.EINVAL);
return -1;
@@ -994,10 +999,12 @@ LibraryManager.library = {
// Synchronization and blocking flags are irrelevant to us.
return flags;
case 4: // F_SETFL.
+ var arg = {{{ makeGetValue('varargs', 0, 'i32') }}};
stream.isAppend = Boolean(arg | 0x400); // O_APPEND.
// Synchronization and blocking flags are irrelevant to us.
return 0;
case 5: // F_GETLK.
+ var arg = {{{ makeGetValue('varargs', 0, 'i32') }}};
var offset = ___flock_struct_layout.l_type;
// We're always unlocked.
{{{ makeSetValue('arg', 'offset', '2', 'i16') }}} // F_UNLCK.
@@ -1147,7 +1154,9 @@ LibraryManager.library = {
dup: function(fildes) {
// int dup(int fildes);
// http://pubs.opengroup.org/onlinepubs/000095399/functions/dup.html
- return _fcntl(fildes, 0, 0); // F_DUPFD.
+ var fildes2Ptr = allocate([0, 0, 0, 0], 'i32', ALLOC_STACK);
+ var ret = _fcntl(fildes, 0, fildes2Ptr); // F_DUPFD.
+ return ret;
},
dup2__deps: ['$FS', '__setErrNo', '$ERRNO_CODES', 'fcntl', 'close'],
dup2: function(fildes, fildes2) {
@@ -1160,7 +1169,9 @@ LibraryManager.library = {
return fildes;
} else {
_close(fildes2);
- return _fcntl(fildes, 0, fildes2); // F_DUPFD.
+ var fildes2Ptr = allocate([fildes2, 0, 0, 0], 'i32', ALLOC_STACK);
+ var ret = _fcntl(fildes, 0, fildes2Ptr); // F_DUPFD.
+ return ret
}
},
fchown__deps: ['$FS', '__setErrNo', '$ERRNO_CODES', 'chown'],
@@ -2121,13 +2132,14 @@ LibraryManager.library = {
// ==========================================================================
// TODO: Document.
- _scanString: function(format, get, unget, args) {
+ _scanString: function(format, get, unget, varargs) {
// Supports %x, %4x, %d.%d, %s.
// TODO: Support all format specifiers.
format = Pointer_stringify(format);
var formatIndex = 0;
var argsi = 0;
var fields = 0;
+ var argIndex = 0;
for (var formatIndex = 0; formatIndex < format.length; formatIndex++) {
var next = get();
if (next <= 0) return fields; // End of input.
@@ -2161,18 +2173,19 @@ LibraryManager.library = {
}
if (buffer.length === 0) return 0; // Failure.
var text = buffer.join('');
+ var argPtr = {{{ makeGetValue('varargs', 'argIndex', 'void*') }}};
+ argIndex += Runtime.getNativeFieldSize('void*');
switch (type) {
case 'd':
- {{{ makeSetValue('args.shift()', '0', 'parseInt(text, 10)', 'i32') }}}
+ {{{ makeSetValue('argPtr', 0, 'parseInt(text, 10)', 'i32') }}}
break;
case 'x':
- {{{ makeSetValue('args.shift()', '0', 'parseInt(text, 16)', 'i32') }}}
+ {{{ makeSetValue('argPtr', 0, 'parseInt(text, 16)', 'i32') }}}
break;
case 's':
var array = intArrayFromString(text);
- var buf = args.shift();
for (var j = 0; j < array.length; j++) {
- {{{ makeSetValue('buf', 'j', 'array[j]', 'i8') }}}
+ {{{ makeSetValue('argPtr', 'j', 'array[j]', 'i8') }}}
}
break;
}
@@ -2188,44 +2201,19 @@ LibraryManager.library = {
return fields;
},
// Performs prtinf-style formatting.
- // isVarArgs: Whether the arguments are passed in varargs style, i.e. the
- // third parameter is an address of the start of the argument list.
// format: A pointer to the format string.
+ // varargs: A pointer to the start of the arguments list.
// Returns the resulting string string as a character array.
- _formatString: function(isVarArgs, format/*, ...*/) {
+ _formatString: function(format, varargs) {
var textIndex = format;
var argIndex = 0;
- var getNextArg;
- if (isVarArgs) {
- var varArgStart = arguments[2];
- getNextArg = function(type) {
- var ret;
- if (type === 'double') {
- ret = {{{ makeGetValue('varArgStart', 'argIndex', 'double') }}};
- } else if (type === 'float') {
- ret = {{{ makeGetValue('varArgStart', 'argIndex', 'float') }}};
- } else if (type === 'i64') {
- ret = {{{ makeGetValue('varArgStart', 'argIndex', 'i64') }}};
- } else if (type === 'i32') {
- ret = {{{ makeGetValue('varArgStart', 'argIndex', 'i32') }}};
- } else if (type === 'i16') {
- ret = {{{ makeGetValue('varArgStart', 'argIndex', 'i16') }}};
- } else if (type === 'i8') {
- ret = {{{ makeGetValue('varArgStart', 'argIndex', 'i8') }}};
- } else if (type[type.length - 1] === '*') {
- ret = {{{ makeGetValue('varArgStart', 'argIndex', 'void*') }}};
- } else {
- throw new Error('Unknown formatString argument type: ' + type);
- }
- argIndex += Runtime.getNativeFieldSize(type);
- return Number(ret);
- };
- } else {
- var args = arguments;
- getNextArg = function() {
- return Number(args[2 + argIndex++]);
- };
- }
+ var getNextArg = function(type) {
+ // NOTE: Explicitly ignoring type safety. Otherwise this fails:
+ // int x = 4; printf("%c\n", (char)x);
+ var ret = {{{ makeGetValue('varargs', 'argIndex', 'null', undefined, undefined, true) }}};
+ argIndex += Runtime.getNativeFieldSize(type);
+ return Number(ret);
+ };
var ret = [];
var curr, next, currArg;
@@ -2748,7 +2736,8 @@ LibraryManager.library = {
___setErrNo(ERRNO_CODES.EINVAL);
return 0;
}
- var ret = _open(filename, flags, 0x1FF); // All creation permissions.
+ var modePtr = allocate([0x1FF, 0, 0, 0], 'i32', ALLOC_STACK) // All creation permissions.
+ var ret = _open(filename, flags, modePtr);
return (ret == -1) ? 0 : ret;
},
fputc__deps: ['$FS', 'write'],
@@ -3035,43 +3024,38 @@ LibraryManager.library = {
},
fscanf__deps: ['$FS', '__setErrNo', '$ERRNO_CODES',
'_scanString', 'getc', 'ungetc'],
- fscanf: function(stream, format/*, ...*/) {
+ fscanf: function(stream, format, varargs) {
// int fscanf(FILE *restrict stream, const char *restrict format, ... );
// http://pubs.opengroup.org/onlinepubs/000095399/functions/scanf.html
if (stream in FS.streams) {
- var args = Array.prototype.slice.call(arguments, 2);
var get = function() { return _fgetc(stream); };
var unget = function(c) { return _ungetc(c, stream); };
- return __scanString(format, get, unget, args);
+ return __scanString(format, get, unget, varargs);
} else {
return -1;
}
},
scanf__deps: ['fscanf'],
- scanf: function(format/*, ...*/) {
+ scanf: function(format, varargs) {
// int scanf(const char *restrict format, ... );
// http://pubs.opengroup.org/onlinepubs/000095399/functions/scanf.html
- var args = Array.prototype.slice.call(arguments, 0);
- args.unshift({{{ makeGetValue('_stdin', '0', 'void*') }}});
- return _fscanf.apply(null, args);
+ var stdin = {{{ makeGetValue('_stdin', '0', 'void*') }}};
+ return _fscanf(stdin, format, varargs);
},
sscanf__deps: ['_scanString'],
- sscanf: function(s, format/*, ...*/) {
+ sscanf: function(s, format, varargs) {
// int sscanf(const char *restrict s, const char *restrict format, ... );
// http://pubs.opengroup.org/onlinepubs/000095399/functions/scanf.html
var index = 0;
var get = function() { return {{{ makeGetValue('s', 'index++', 'i8') }}}; };
var unget = function() { index--; };
- var args = Array.prototype.slice.call(arguments, 2);
- return __scanString(format, get, unget, args);
+ return __scanString(format, get, unget, varargs);
},
snprintf__deps: ['_formatString'],
- snprintf: function(s, n, format/*, ... */) {
+ snprintf: function(s, n, format, varargs) {
// int snprintf(char *restrict s, size_t n, const char *restrict format, ...);
// http://pubs.opengroup.org/onlinepubs/000095399/functions/printf.html
- var args = Array.prototype.slice.call(arguments, 2);
- args.unshift(false);
- var result = __formatString.apply(null, args);
+ var result = __formatString(format, varargs);
var limit = (n === undefined) ? result.length
: Math.min(result.length, n - 1);
for (var i = 0; i < limit; i++) {
@@ -3081,65 +3065,31 @@ LibraryManager.library = {
return result.length;
},
fprintf__deps: ['fwrite', '_formatString'],
- fprintf: function(stream, format/*, ... */) {
+ fprintf: function(stream, format, varargs) {
// int fprintf(FILE *restrict stream, const char *restrict format, ...);
// http://pubs.opengroup.org/onlinepubs/000095399/functions/printf.html
- var args = Array.prototype.slice.call(arguments, 1);
- args.unshift(false);
- var result = __formatString.apply(null, args);
+ var result = __formatString(format, varargs);
var buffer = allocate(result, 'i8', ALLOC_STACK);
var ret = _fwrite(buffer, 1, result.length, stream);
return ret;
},
printf__deps: ['fprintf'],
- printf: function(format/*, ... */) {
+ printf: function(format, varargs) {
// int printf(const char *restrict format, ...);
// http://pubs.opengroup.org/onlinepubs/000095399/functions/printf.html
- var args = Array.prototype.slice.call(arguments, 0);
- args.unshift({{{ makeGetValue('_stdout', '0', 'void*') }}});
- return _fprintf.apply(null, args);
+ var stdout = {{{ makeGetValue('_stdout', '0', 'void*') }}};
+ return _fprintf(stdout, format, varargs);
},
sprintf__deps: ['snprintf'],
- sprintf: function(s, format/*, ... */) {
+ sprintf: function(s, format, varargs) {
// int sprintf(char *restrict s, const char *restrict format, ...);
// http://pubs.opengroup.org/onlinepubs/000095399/functions/printf.html
- var args = [s, undefined].concat(Array.prototype.slice.call(arguments, 1));
- return _snprintf.apply(null, args);
- },
- vfprintf__deps: ['fwrite', '_formatString'],
- vfprintf: function(stream, format, ap) {
- // int vfprintf(FILE *restrict stream, const char *restrict format, va_list ap);
- // http://pubs.opengroup.org/onlinepubs/000095399/functions/vprintf.html
- var result = __formatString(true, format, ap);
- var buffer = allocate(result, 'i8', ALLOC_STACK);
- var ret = _fwrite(buffer, 1, result.length, stream);
- return ret;
- },
- vsnprintf__deps: ['_formatString'],
- vsnprintf: function(s, n, format, ap) {
- // int vsnprintf(char *restrict s, size_t n, const char *restrict format, va_list ap);
- // http://pubs.opengroup.org/onlinepubs/000095399/functions/vprintf.html
- var result = __formatString(true, format, ap);
- var limit = (n === undefined) ? result.length
- : Math.min(result.length, n - 1);
- for (var i = 0; i < limit; i++) {
- {{{ makeSetValue('s', 'i', 'result[i]', 'i8') }}};
- }
- {{{ makeSetValue('s', 'i', '0', 'i8') }}};
- return result.length;
- },
- vprintf__deps: ['vfprintf'],
- vprintf: function(format, ap) {
- // int vprintf(const char *restrict format, va_list ap);
- // http://pubs.opengroup.org/onlinepubs/000095399/functions/vprintf.html
- return _vfprintf({{{ makeGetValue('_stdout', '0', 'void*') }}}, format, ap);
- },
- vsprintf__deps: ['vsnprintf'],
- vsprintf: function(s, format, ap) {
- // int vsprintf(char *restrict s, const char *restrict format, va_list ap);
- // http://pubs.opengroup.org/onlinepubs/000095399/functions/vprintf.html
- return _vsnprintf(s, undefined, format, ap);
+ return _snprintf(s, undefined, format, varargs);
},
+ vfprintf: 'fprintf',
+ vsnprintf: 'snprintf',
+ vprintf: 'printf',
+ vsprintf: 'sprintf',
// TODO: Implement v*scanf().
__01fopen64_: 'fopen',
__01fseeko64_: 'fseek',