diff options
Diffstat (limited to 'src/library.js')
-rw-r--r-- | src/library.js | 87 |
1 files changed, 65 insertions, 22 deletions
diff --git a/src/library.js b/src/library.js index c753422d..faa86c68 100644 --- a/src/library.js +++ b/src/library.js @@ -24,7 +24,7 @@ LibraryManager.library = { _impure_ptr: 0, $FS__deps: ['$ERRNO_CODES', '__setErrNo', 'stdin', 'stdout', 'stderr', '_impure_ptr'], - $FS__postset: 'FS.init();', + $FS__postset: 'FS.init(); __ATEXIT__.push({ func: function() { FS.quit() } });', $FS: { // The path to the current folder. currentPath: '/', @@ -246,8 +246,7 @@ LibraryManager.library = { // Makes sure a file's contents are loaded. Returns whether the file has // been loaded successfully. No-op for files that have been loaded already. forceLoadFile: function(obj) { - if (obj.isDevice || obj.isFolder || obj.link || - 'contents' in obj) return true; + if (obj.isDevice || obj.isFolder || obj.link || obj.contents) return true; var success = true; if (typeof XMLHttpRequest !== 'undefined') { // Browser. @@ -323,19 +322,6 @@ LibraryManager.library = { return input.cache.shift(); }; if (!output) output = function(val) { - if (!output.printer) { - if (typeof print == 'function') { - // Either console or custom print function defined. - output.printer = print; - } else if (console && typeof console.log == 'function') { - // Browser-like environment with a console. - output.printer = console.log; - } else { - // Fallback to a harmless no-op. - output.printer = function() {}; - } - } - if (!output.buffer) output.buffer = []; if (val === null || val === '\n'.charCodeAt(0)) { output.printer(output.buffer.join('')); output.buffer = []; @@ -343,6 +329,8 @@ LibraryManager.library = { output.buffer.push(String.fromCharCode(val)); } }; + if (!output.printer) output.printer = print; + if (!output.buffer) output.buffer = []; if (!error) error = output; // Create the temporary folder. @@ -403,6 +391,12 @@ LibraryManager.library = { // Once initialized, permissions start having effect. FS.ignorePermissions = false; + }, + + quit: function() { + // Flush any partially-printed lines in stdout and stderr + if (FS.streams[2].object.output.buffer.length > 0) FS.streams[2].object.output('\n'.charCodeAt(0)); + if (FS.streams[3].object.output.buffer.length > 0) FS.streams[3].object.output('\n'.charCodeAt(0)); } }, @@ -3353,6 +3347,7 @@ LibraryManager.library = { qsort__deps: ['memcpy'], qsort: function(base, num, size, comparator) { + if (num == 0 || size == 0) return; // forward calls to the JavaScript sort method // first, sort the items logically comparator = FUNCTION_TABLE[comparator]; @@ -3572,13 +3567,21 @@ LibraryManager.library = { // string.h // ========================================================================== + memcpy__inline: function (dest, src, num, idunno) { + var ret = ''; +#if ASSERTIONS + ret += "assert(" + num + " % 1 === 0, 'memcpy given ' + " + num + " + ' bytes to copy. Problem with QUANTUM_SIZE=1 corrections perhaps?');"; +#endif + ret += makeCopyValues(dest, src, num, 'null'); + return ret; + }, memcpy: function (dest, src, num, idunno) { #if ASSERTIONS assert(num % 1 === 0, 'memcpy given ' + num + ' bytes to copy. Problem with QUANTUM_SIZE=1 corrections perhaps?'); #endif - // || 0, since memcpy sometimes copies uninitialized areas XXX: Investigate why initializing alloc'ed memory does not fix that too - {{{ makeCopyValues('dest', 'src', 'num', 'null', ' || 0') }}}; + {{{ makeCopyValues('dest', 'src', 'num', 'null') }}}; }, + llvm_memcpy_i32: 'memcpy', llvm_memcpy_i64: 'memcpy', llvm_memcpy_p0i8_p0i8_i32: 'memcpy', @@ -3598,6 +3601,9 @@ LibraryManager.library = { llvm_memmove_p0i8_p0i8_i32: 'memmove', llvm_memmove_p0i8_p0i8_i64: 'memmove', + memset__inline: function(ptr, value, num) { + return makeSetValues(ptr, 0, value, 'null', num); + }, memset: function(ptr, value, num) { {{{ makeSetValues('ptr', '0', 'value', 'null', 'num') }}} }, @@ -3978,6 +3984,14 @@ LibraryManager.library = { // LLVM specifics // ========================================================================== + llvm_va_start__inline: function(ptr) { + // varargs - we received a pointer to the varargs as a final 'extra' parameter + var data = 'arguments[' + Framework.currItem.funcData.ident + '.length]'; + return makeSetValue(ptr, 0, data, 'void*'); + }, + + llvm_va_end: function() {}, + llvm_va_copy: function(ppdest, ppsrc) { {{{ makeCopyValues('ppdest', 'ppsrc', QUANTUM_SIZE, 'null') }}} /* Alternate implementation that copies the actual DATA; it assumes the va_list is prefixed by its size @@ -4003,6 +4017,15 @@ LibraryManager.library = { } return ret; }, + + llvm_ctlz_i32: function(x) { + for (var i=0; i<32; i++) { + if ( (x & (1 << (31-i))) != 0 ) { + return i; + } + } + return 32; + }, __assert_fail: function(condition, file, line) { ABORT = true; @@ -4158,8 +4181,8 @@ LibraryManager.library = { return ret; }, - llvm_expect_i32: function(x, y) { - return x == y; // TODO: inline this + llvm_expect_i32__inline: function(x, y) { + return '((' + x + ')==(' + y + '))'; }, llvm_lifetime_start: function() {}, @@ -4169,10 +4192,20 @@ LibraryManager.library = { // iostream.h // ========================================================================== - // TODO: Document; compile from real implementation. + // libc++ + + $libcxx__postset: 'try { __ZNSt3__14coutE = 1 } catch(e){}; try { __ZNSt3__14cerrE = 2 } catch(e){};', + $libcxx: {}, + + _ZNSt3__113basic_ostreamIcNS_11char_traitsIcEEElsEPKv__deps: ['fputs', '$libcxx'], + _ZNSt3__113basic_ostreamIcNS_11char_traitsIcEEElsEPKv: function(stream, str) { + _fputs(str, _stdout); // XXX stderr etc. + }, + + // glibc _ZNSt8ios_base4InitC1Ev: function() { - // need valid 'file descriptors' + // need valid 'file descriptors' for glibc //__ZSt4cout = 1; //__ZSt4cerr = 2; }, @@ -4245,6 +4278,11 @@ LibraryManager.library = { scalbnf: 'ldexp', scalbln: 'ldexp', scalblnf: 'ldexp', + cbrt: function(x) { + return Math.pow(x, 1/3); + }, + cbrtf: 'cbrt', + cbrtl: 'cbrt', modf: function(x, intpart) { {{{ makeSetValue('intpart', 0, 'Math.floor(x)', 'double') }}} @@ -5374,6 +5412,11 @@ LibraryManager.library = { _Z21emscripten_run_scriptPKc: function(ptr) { eval(Pointer_stringify(ptr)); + }, + + EMSCRIPTEN_COMMENT__inline: function(param) { + param = stripCorrections(param); + return '// ' + Variables.globals[param].value.text.replace('\\00', '') + ' '; } }; |