diff options
Diffstat (limited to 'src/library.js')
-rw-r--r-- | src/library.js | 116 |
1 files changed, 77 insertions, 39 deletions
diff --git a/src/library.js b/src/library.js index 344ec8d6..e65754ba 100644 --- a/src/library.js +++ b/src/library.js @@ -619,7 +619,7 @@ LibraryManager.library = { #endif allocate([ allocate( {{{ Runtime.QUANTUM_SIZE === 4 ? '[0, 0, 0, 0, _stdin, 0, 0, 0, _stdout, 0, 0, 0, _stderr, 0, 0, 0]' : '[0, _stdin, _stdout, _stderr]' }}}, - 'void*', ALLOC_DYNAMIC) ], 'void*', ALLOC_NONE, {{{ makeGlobalUse('__impure_ptr') }}}); + 'void*', ALLOC_NORMAL) ], 'void*', ALLOC_NONE, {{{ makeGlobalUse('__impure_ptr') }}}); }, quit: function() { @@ -3576,14 +3576,14 @@ LibraryManager.library = { return -1; }, fscanf__deps: ['$FS', '__setErrNo', '$ERRNO_CODES', - '_scanString', 'getc', 'ungetc'], + '_scanString', 'fgetc', 'fseek', 'ftell'], fscanf: function(stream, format, varargs) { // int fscanf(FILE *restrict stream, const char *restrict format, ... ); // http://pubs.opengroup.org/onlinepubs/000095399/functions/scanf.html if (FS.streams[stream]) { - var stack = []; - var get = function() { var ret = _fgetc(stream); stack.push(ret); return ret }; - var unget = function(c) { return _ungetc(stack.pop(), stream) }; + var i = _ftell(stream), SEEK_SET = 0; + var get = function () { i++; return _fgetc(stream); }; + var unget = function () { _fseek(stream, --i, SEEK_SET); }; return __scanString(format, get, unget, varargs); } else { return -1; @@ -3726,30 +3726,44 @@ LibraryManager.library = { * this implementation simply uses malloc underneath the call to * mmap. */ + var MAP_PRIVATE = 2; + var allocated = false; + if (!_mmap.mappings) _mmap.mappings = {}; + if (stream == -1) { var ptr = _malloc(num); + if (!ptr) return -1; + _memset(ptr, 0, num); + allocated = true; } else { var info = FS.streams[stream]; if (!info) return -1; var contents = info.object.contents; - contents = Array.prototype.slice.call(contents, offset, offset+num); - ptr = allocate(contents, 'i8', ALLOC_NORMAL); - } - // align to page size - var ret = ptr; - if (ptr % PAGE_SIZE != 0) { - var old = ptr; - ptr = _malloc(num + PAGE_SIZE); - ret = alignMemoryPage(ptr); - _memcpy(ret, old, num); - _free(old); - } - if (stream == -1) { - _memset(ret, 0, num); + // Only make a new copy when MAP_PRIVATE is specified. + if (flags & MAP_PRIVATE == 0) { + // We can't emulate MAP_SHARED when the file is not backed by HEAP. + assert(contents.buffer === HEAPU8.buffer); + ptr = contents.byteOffset; + allocated = false; + } else { + // Try to avoid unnecessary slices. + if (offset > 0 || offset + num < contents.length) { + if (contents.subarray) { + contents = contents.subarray(offset, offset+num); + } else { + contents = Array.prototype.slice.call(contents, offset, offset+num); + } + } + ptr = _malloc(num); + if (!ptr) return -1; + HEAPU8.set(contents, ptr); + allocated = true; + } } - _mmap.mappings[ret] = { malloc: ptr, num: num }; - return ret; + + _mmap.mappings[ptr] = { malloc: ptr, num: num, allocated: allocated }; + return ptr; }, __01mmap64_: 'mmap', @@ -3760,7 +3774,9 @@ LibraryManager.library = { if (!info) return 0; if (num == info.num) { _mmap.mappings[start] = null; - _free(info.malloc); + if (info.allocated) { + _free(info.malloc); + } } return 0; }, @@ -3902,7 +3918,14 @@ LibraryManager.library = { str++; } } - } + } else if (finalBase==16) { + if ({{{ makeGetValue('str', 0, 'i8') }}} == {{{ charCode('0') }}}) { + if ({{{ makeGetValue('str+1', 0, 'i8') }}} == {{{ charCode('x') }}} || + {{{ makeGetValue('str+1', 0, 'i8') }}} == {{{ charCode('X') }}}) { + str += 2; + } + } + } if (!finalBase) finalBase = 10; // Get digits. @@ -3953,13 +3976,14 @@ LibraryManager.library = { #if USE_TYPED_ARRAYS == 2 _parseInt64__deps: ['isspace', '__setErrNo', '$ERRNO_CODES', function() { Types.preciseI64MathUsed = 1 }], _parseInt64: function(str, endptr, base, min, max, unsign) { - var start = str; + var isNegative = false; // Skip space. while (_isspace({{{ makeGetValue('str', 0, 'i8') }}})) str++; - + // Check for a plus/minus sign. if ({{{ makeGetValue('str', 0, 'i8') }}} == {{{ charCode('-') }}}) { str++; + isNegative = true; } else if ({{{ makeGetValue('str', 0, 'i8') }}} == {{{ charCode('+') }}}) { str++; } @@ -3975,12 +3999,19 @@ LibraryManager.library = { str += 2; } else { finalBase = 8; - str++; ok = true; // we saw an initial zero, perhaps the entire thing is just "0" } } - } + } else if (finalBase==16) { + if ({{{ makeGetValue('str', 0, 'i8') }}} == {{{ charCode('0') }}}) { + if ({{{ makeGetValue('str+1', 0, 'i8') }}} == {{{ charCode('x') }}} || + {{{ makeGetValue('str+1', 0, 'i8') }}} == {{{ charCode('X') }}}) { + str += 2; + } + } + } if (!finalBase) finalBase = 10; + start = str; // Get digits. var chr; @@ -3993,6 +4024,7 @@ LibraryManager.library = { ok = true; } } + if (!ok) { ___setErrNo(ERRNO_CODES.EINVAL); {{{ makeStructuralReturn(['0', '0']) }}}; @@ -4004,7 +4036,8 @@ LibraryManager.library = { } try { - i64Math.fromString(Pointer_stringify(start, str - start), finalBase, min, max, unsign); + var numberString = isNegative ? '-'+Pointer_stringify(start, str - start) : Pointer_stringify(start, str - start); + i64Math.fromString(numberString, finalBase, min, max, unsign); } catch(e) { ___setErrNo(ERRNO_CODES.ERANGE); // not quite correct } @@ -5072,7 +5105,13 @@ LibraryManager.library = { return _malloc(size); }, __cxa_free_exception: function(ptr) { - return _free(ptr); + try { + return _free(ptr); + } catch(e) { // XXX FIXME +#if ASSERTIONS + Module.printErr('exception during cxa_free_exception: ' + e); +#endif + } }, __cxa_throw__sig: 'viii', __cxa_throw__deps: ['llvm_eh_exception', '_ZSt18uncaught_exceptionv', '__cxa_find_matching_catch'], @@ -6170,8 +6209,9 @@ LibraryManager.library = { clock_gettime__deps: ['__timespec_struct_layout'], clock_gettime: function(clk_id, tp) { // int clock_gettime(clockid_t clk_id, struct timespec *tp); - {{{ makeSetValue('tp', '___timespec_struct_layout.tv_sec', '0', 'i32') }}} - {{{ makeSetValue('tp', '___timespec_struct_layout.tv_nsec', '0', 'i32') }}} + var now = Date.now(); + {{{ makeSetValue('tp', '___timespec_struct_layout.tv_sec', 'Math.floor(now/1000)', 'i32') }}}; // seconds + {{{ makeSetValue('tp', '___timespec_struct_layout.tv_nsec', '0', 'i32') }}}; // nanoseconds - not supported return 0; }, clock_settime: function(clk_id, tp) { @@ -6794,19 +6834,17 @@ LibraryManager.library = { 26: 'Text file busy', 18: 'Invalid cross-device link' }, + __errno_state: 0, + __setErrNo__deps: ['__errno_state'], + __setErrNo__postset: '___errno_state = Runtime.staticAlloc(4); {{{ makeSetValue("___errno_state", 0, 0, "i32") }}};', __setErrNo: function(value) { // For convenient setting and returning of errno. - if (!___setErrNo.ret) ___setErrNo.ret = allocate([0], 'i32', ALLOC_NORMAL); - {{{ makeSetValue('___setErrNo.ret', '0', 'value', 'i32') }}} + {{{ makeSetValue('___errno_state', '0', 'value', 'i32') }}} return value; }, __errno_location__deps: ['__setErrNo'], __errno_location: function() { - if (!___setErrNo.ret) { - ___setErrNo.ret = allocate([0], 'i32', ALLOC_NORMAL); - {{{ makeSetValue('___setErrNo.ret', '0', '0', 'i32') }}} - } - return ___setErrNo.ret; + return ___errno_state; }, __errno: '__errno_location', @@ -7563,7 +7601,7 @@ LibraryManager.library = { }, emscripten_run_script_int: function(ptr) { - return eval(Pointer_stringify(ptr)); + return eval(Pointer_stringify(ptr))|0; }, emscripten_run_script_string: function(ptr) { |