diff options
author | Alon Zakai <azakai@mozilla.com> | 2011-01-08 14:01:10 -0800 |
---|---|---|
committer | Alon Zakai <azakai@mozilla.com> | 2011-01-08 14:01:10 -0800 |
commit | 9143905d9833518c56625ad11e0d3c4cac78dd59 (patch) | |
tree | 78fd43b95fc964f51fc4b4f673723f0f000784cf /src/library.js | |
parent | 1a2f55979d66202814c61a4c4ed934b770606947 (diff) |
refactor preamble functions into library
Diffstat (limited to 'src/library.js')
-rw-r--r-- | src/library.js | 158 |
1 files changed, 157 insertions, 1 deletions
diff --git a/src/library.js b/src/library.js index a00bce91..001861b0 100644 --- a/src/library.js +++ b/src/library.js @@ -15,17 +15,127 @@ var Library = { // stdio.h + _formatString: function() { + function isFloatArg(type) { + return String.fromCharCode(type) in Runtime.set('f', 'e', 'g'); + } + var cStyle = false; + var textIndex = arguments[0]; + var argIndex = 1; + if (textIndex < 0) { + cStyle = true; + textIndex = -textIndex; + slab = null; + argIndex = arguments[1]; + } else { + var _arguments = arguments; + } + function getNextArg(type) { + var ret; + if (!cStyle) { + ret = _arguments[argIndex]; + argIndex++; + } else { + if (isFloatArg(type)) { + ret = {{{ makeGetValue(0, 'argIndex', 'double') }}}; + } else { + ret = {{{ makeGetValue(0, 'argIndex', 'i32') }}}; + } + argIndex += type === 'l'.charCodeAt(0) ? 8 : 4; // XXX hardcoded native sizes + } + return ret; + } + + var ret = []; + var curr, next, currArg; + while(1) { + curr = {{{ makeGetValue(0, 'textIndex', 'i8') }}}; + if (curr === 0) break; + next = {{{ makeGetValue(0, 'textIndex+1', 'i8') }}}; + if (curr == '%'.charCodeAt(0)) { + // Handle very very simply formatting, namely only %.X[f|d|u|etc.] + var precision = -1; + if (next == '.'.charCodeAt(0)) { + textIndex++; + precision = 0; + while(1) { + var precisionChr = {{{ makeGetValue(0, 'textIndex+1', 'i8') }}}; + if (!(precisionChr >= '0'.charCodeAt(0) && precisionChr <= '9'.charCodeAt(0))) break; + precision *= 10; + precision += precisionChr - '0'.charCodeAt(0); + textIndex++; + } + next = {{{ makeGetValue(0, 'textIndex+1', 'i8') }}}; + } + if (next == 'l'.charCodeAt(0)) { + textIndex++; + next = {{{ makeGetValue(0, 'textIndex+1', 'i8') }}}; + } + if (isFloatArg(next)) { + next = 'f'.charCodeAt(0); // no support for 'e' + } + if (['d', 'i', 'u', 'p', 'f'].indexOf(String.fromCharCode(next)) != -1) { + var currArg; + var argText; + currArg = getNextArg(next); + argText = String(+currArg); // +: boolean=>int + if (next == 'u'.charCodeAt(0)) { + argText = String(unSign(currArg, 32)); + } else if (next == 'p'.charCodeAt(0)) { + argText = '0x' + currArg.toString(16); + } else { + argText = String(+currArg); // +: boolean=>int + } + if (precision >= 0) { + if (isFloatArg(next)) { + var dotIndex = argText.indexOf('.'); + if (dotIndex == -1 && next == 'f'.charCodeAt(0)) { + dotIndex = argText.length; + argText += '.'; + } + argText += '00000000000'; // padding + argText = argText.substr(0, dotIndex+1+precision); + } else { + while (argText.length < precision) { + argText = '0' + argText; + } + } + } + argText.split('').forEach(function(chr) { + ret.push(chr.charCodeAt(0)); + }); + textIndex += 2; + } else if (next == 's'.charCodeAt(0)) { + ret = ret.concat(String_copy(getNextArg(next))); + textIndex += 2; + } else if (next == 'c'.charCodeAt(0)) { + ret = ret.concat(getNextArg(next)); + textIndex += 2; + } else { + ret.push(next); + textIndex += 2; // not sure what to do with this %, so print it + } + } else { + ret.push(curr); + textIndex += 1; + } + } + return Pointer_make(ret.concat(0), 0, ALLOC_STACK); // NB: Stored on the stack + }, + + printf__deps: ['_formatString'], printf: function() { __print__(Pointer_stringify(__formatString.apply(null, arguments))); }, + fprintf__deps: ['_formatString'], fprintf: function() { var file = arguments[0]; // TODO: something clever with this var args = Array.prototype.slice.call(arguments, 1); __print__(Pointer_stringify(__formatString.apply(null, args))); }, - sprintf__deps: ['strcpy'], + sprintf__deps: ['strcpy', '_formatString'], sprintf: function() { var str = arguments[0]; var args = Array.prototype.slice.call(arguments, 1); @@ -89,6 +199,7 @@ var Library = { __print__('\n'); }, + vsnprintf__deps: ['_formatString'], vsnprintf: function(dst, num, src, ptr) { var text = __formatString(-src, ptr); // |-|src tells formatstring to use C-style params (typically they are from varargs) var i; @@ -119,6 +230,10 @@ var Library = { abs: 'Math.abs', + atoi: function(s) { + return Math.floor(Number(Pointer_stringify(s))); + }, + atexit: function(func) { __ATEXIT__.push(func); }, @@ -129,6 +244,7 @@ var Library = { throw 'ABORT: ' + code + ', at ' + (new Error().stack); }, + realloc__deps: ['memcpy'], realloc: function(ptr, size) { // Very simple, inefficient implementation - if you use a real malloc, best to use // a real realloc with it @@ -177,6 +293,7 @@ var Library = { return ret; }, + qsort__deps: ['memcpy'], qsort: function(base, num, size, comparator) { // forward calls to the JavaScript sort method // first, sort the items logically @@ -198,6 +315,45 @@ var Library = { // string.h + memcpy: function (dest, src, num, idunno) { + var curr; + for (var i = 0; i < num; i++) { + // TODO: optimize for the typed arrays case + // || 0, since memcpy sometimes copies uninitialized areas XXX: Investigate why initializing alloc'ed memory does not fix that too + {{{ makeCopyValue('dest', 'i', 'src', 'i', 'null', ' || 0') }}}; + } + }, + llvm_memcpy_i32: 'memcpy', + llvm_memcpy_i64: 'memcpy', + llvm_memcpy_p0i8_p0i8_i32: 'memcpy', + llvm_memcpy_p0i8_p0i8_i64: 'memcpy', + + memmove: function(dest, src, num, idunno) { + // not optimized! + if (num === 0) return; // will confuse malloc if 0 + var tmp = _malloc(num); + _memcpy(tmp, src, num); + _memcpy(dest, tmp, num); + _free(tmp); + }, + llvm_memmove_i32: 'memmove', + llvm_memmove_i64: 'memmove', + llvm_memmove_p0i8_p0i8_i32: 'memmove', + llvm_memmove_p0i8_p0i8_i64: 'memmove', + + memset: function(ptr, value, num) { + for (var i = 0; i < num; i++) { + {{{ makeSetValue('ptr', 'i', 'value', 'null') }}} + } + }, + llvm_memset_i32: 'memset', + llvm_memset_p0i8_i32: 'memset', + llvm_memset_p0i8_i64: 'memset', + + strlen: function(ptr) { + return String_len(ptr); + }, + strspn: function(pstr, pset) { var str = String_copy(pstr, true); var set = String_copy(pset); |