diff options
author | Alon Zakai <azakai@mozilla.com> | 2011-01-16 13:52:25 -0800 |
---|---|---|
committer | Alon Zakai <azakai@mozilla.com> | 2011-01-16 13:52:25 -0800 |
commit | 6a6e842688afe7e15f6a957d4179da982c0f940b (patch) | |
tree | 9f31de60b019df0c8c6b0ca23d0ba963e2b1ed76 /src | |
parent | 9d209878f9819ffd1aa92c7306123392609db845 (diff) |
initial emulation for stdio file reading, and other preparations for poppler
Diffstat (limited to 'src')
-rw-r--r-- | src/jsifier.js | 77 | ||||
-rw-r--r-- | src/library.js | 164 | ||||
-rw-r--r-- | src/parseTools.js | 2 | ||||
-rw-r--r-- | src/preamble.js | 2 |
4 files changed, 194 insertions, 51 deletions
diff --git a/src/jsifier.js b/src/jsifier.js index a88429a0..847b198d 100644 --- a/src/jsifier.js +++ b/src/jsifier.js @@ -278,56 +278,83 @@ function JSify(data, functionsOnly, givenTypes, givenFunctions, givenGlobalVaria return ret; } else { item.JS = 'var ' + item.ident + ';'; - var constant = item.external ? - makePointer(JSON.stringify(makeEmptyStruct(item.type)) + ' /* external value? */', null, 'ALLOC_STATIC') - : - parseConst(item.value, item.type, item.ident); - if (typeof constant === 'object') { - // This is a flattened object. We need to find its idents, so they can be assigned to later - constant.forEach(function(value, i) { - if (value[0] in set('_', '(') || value.substr(0, 14) === 'CHECK_OVERFLOW') { // ident, or expression containing an ident - ret.push({ - intertype: 'GlobalVariablePostSet', - JS: 'IHEAP[' + item.ident + '+' + i + '] = ' + value + ';', - }); - constant[i] = '0'; - } + var constant = null; + if (item.external) { + return ret; + } else { + constant = parseConst(item.value, item.type, item.ident); + if (typeof constant === 'object') { + // This is a flattened object. We need to find its idents, so they can be assigned to later + constant.forEach(function(value, i) { + if (value[0] in set('_', '(') || value.substr(0, 14) === 'CHECK_OVERFLOW') { // ident, or expression containing an ident + ret.push({ + intertype: 'GlobalVariablePostSet', + JS: 'IHEAP[' + item.ident + '+' + i + '] = ' + value + ';' + }); + constant[i] = '0'; + } + }); + constant = '[' + constant.join(', ') + ']'; + } + constant = makePointer(constant, null, 'ALLOC_STATIC', item.type); + + return ret.concat({ + intertype: 'GlobalVariable', + JS: item.ident + ' = ' + constant + ';', }); - constant = '[' + constant.join(', ') + ']'; } - constant = makePointer(constant, null, 'ALLOC_STATIC', item.type); - return ret.concat({ - intertype: 'GlobalVariable', - JS: item.ident + ' = ' + constant + ';', - }); } } }); + var addedLibraryItems = {}; + // functionStub substrate.addActor('FunctionStub', { processItem: function(item) { + var ret = [item]; var shortident = item.ident.substr(1); if (shortident in Library) { function addFromLibrary(ident) { var me = arguments.callee; - if (!me.added) me.added = {}; - if (ident in me.added) return ''; - me.added[ident] = true; + if (ident in addedLibraryItems) return ''; + addedLibraryItems[ident] = true; var snippet = Library[ident]; if (typeof snippet === 'string') { if (Library[snippet]) { snippet = Library[snippet]; // redirection for aliases } + } else if (typeof snippet === 'object') { + // JSON.stringify removes functions, so we need to make sure they are added + var funcs = []; + for (var x in snippet) { + if (typeof snippet[x] === 'function') { + funcs.push(x + ': ' + snippet[x].toString()); + } + } + snippet = JSON.stringify(snippet).replace(/}$/, ', ' + funcs.join(', ') + ' }'); + } else if (typeof snippet === 'function') { + snippet = snippet.toString(); + } + + var postsetId = ident + '__postset'; + var postset = Library[postsetId]; + if (postset && !addedLibraryItems[postsetId]) { + addedLibraryItems[postsetId] = true; + ret.push({ + intertype: 'GlobalVariablePostSet', + JS: postset + }); } + var deps = Library[ident + '__deps']; - return '_' + ident + ' = ' + snippet.toString() + (deps ? '\n' + deps.map(addFromLibrary).join('\n') : ''); + return '_' + ident + ' = ' + snippet + (deps ? '\n' + deps.map(addFromLibrary).join('\n') : ''); } item.JS = addFromLibrary(shortident); } else { item.JS = '// stub for ' + item.ident; } - return [item]; + return ret; } }); diff --git a/src/library.js b/src/library.js index 495229c3..8bc35ac0 100644 --- a/src/library.js +++ b/src/library.js @@ -6,7 +6,8 @@ // entry in the Library is a function, we insert it. If it is a string, we // do another lookup in the library (a simple way to write a function once, // if it can be called by different names). We also allow dependencies, -// using __deps. +// using __deps. Initialization code to be run after allocating all +// global constants can be defined by __postset. // // Note that the full function name will be '_' + the name in the Library // object. For convenience, the short name appears here. Note that if you add a @@ -15,6 +16,7 @@ var Library = { // stdio.h + _formatString__deps: ['STDIO'], _formatString: function() { function isFloatArg(type) { return String.fromCharCode(type) in Runtime.set('f', 'e', 'g'); @@ -142,6 +144,14 @@ var Library = { _strcpy(str, __formatString.apply(null, args)); // not terribly efficient }, + snprintf__deps: ['strncpy', '_formatString'], + snprintf: function() { + var str = arguments[0]; + var num = arguments[1]; + var args = Array.prototype.slice.call(arguments, 2); + _strncpy(str, __formatString.apply(null, args), num); // not terribly efficient + }, + fflush: function(file) { __print__(null); }, @@ -163,11 +173,6 @@ var Library = { }, _ZNSo3putEc: 'putchar', - fopen: function(filename, mode) { - return 1; // TODO - }, - __01fopen64_: 'fopen', - getc: function(file) { return -1; // EOF }, @@ -178,23 +183,6 @@ var Library = { return chr; }, - feof: function(stream) { - return 1; - }, - - ferror: function(stream) { - return 0; - }, - - fwrite: function(ptr, size, count, stream) { - __print__(intArrayToString(Array_copy(ptr, count))); - return count; - }, - - fclose: function(stream) { - return 0; - }, - _ZNSo5flushEv: function() { __print__('\n'); }, @@ -226,6 +214,115 @@ var Library = { funlockfile: function(file) { }, + // stdio.h - file functions + + STDIO__postset: 'this._STDIO.init()', + STDIO: { + streams: {}, + filenames: {}, + counter: 1, + SEEK_SET: 0, /* Beginning of file. */ + SEEK_CUR: 1, /* Current position. */ + SEEK_END: 2, /* End of file. */ + init: function() { + _stdin = Pointer_make([0], null, ALLOC_STATIC); + IHEAP[_stdin] = this.prepare('<<stdin>>'); + _stdout = Pointer_make([0], null, ALLOC_STATIC); + IHEAP[_stdout] = this.prepare('<<stdout>>'); + _stderr = Pointer_make([0], null, ALLOC_STATIC); + IHEAP[_stderr] = this.prepare('<<stderr>>'); + }, + prepare: function(filename, data) { + var stream = this.counter++; + this.streams[stream] = { + filename: filename, + data: data, + position: 0, + eof: 0, + error: 0, + print: 1 // true for stdout and stderr - we print when receiving data for them + }; + this.filenames[filename] = stream; + return stream; + } + }, + + fopen__deps: ['STDIO'], + fopen: function(filename, mode) { + var str = Pointer_stringify(filename); + //assert(str in this._STDIO.filenames, 'No information for file: ' + str); + return this._STDIO.filenames[str]; + }, + __01fopen64_: 'fopen', + + rewind__deps: ['STDIO'], + rewind: function(stream) { + var info = this._STDIO.streams[stream]; + info.position = 0; + info.error = 0; + }, + + fseek__deps: ['STDIO'], + fseek: function(stream, offset, whence) { + var info = this._STDIO.streams[stream]; + if (whence === this._STDIO.SEEK_CUR) { + offset += info.position; + } else if (whence === this._STDIO.SEEK_END) { + offset += info.data.length; + } + info.position = offset; + info.eof = 0; + return 0; + }, + __01fseeko64_: 'fseek', + + ftell__deps: ['STDIO'], + ftell: function(stream) { + return this._STDIO.streams[stream].position; + }, + __01ftello64_: 'ftell', + + fread__deps: ['STDIO'], + fread: function(ptr, size, count, stream) { + var info = this._STDIO.streams[stream]; + for (var i = 0; i < count; i++) { + if (info.position + size > info.data.length) { + info.eof = 1; + return i; + } + for (var j = 0; j < size; j++) { + {{{ makeSetValue('ptr', '0', 'info.data[info.position]', 'null') }}} + info.position++; + ptr++; + } + } + return count; + }, + + fwrite__deps: ['STDIO'], + fwrite: function(ptr, size, count, stream) { + var info = this._STDIO.streams[stream]; + if (info.print) { + __print__(intArrayToString(Array_copy(ptr, count*size))); + } // XXX + return count; + }, + + fclose__deps: ['STDIO'], + fclose: function(stream) { + return 0; + }, + + feof__deps: ['STDIO'], + feof: function(stream) { + return this._STDIO.streams[stream].eof; + }, + + ferror__deps: ['STDIO'], + ferror: function(stream) { + return this._STDIO.streams[stream].error; + }, + // stdlib.h abs: 'Math.abs', @@ -796,6 +893,14 @@ var Library = { return -1; }, + getuid: function() { + return 100; + }, + + getpwuid: function(uid) { + return 0; // NULL + }, + // time.h time: function(ptr) { @@ -882,6 +987,19 @@ var Library = { me.ret = Pointer_make([0], 0, ALLOC_STATIC); } return me.ret; + }, + + // pthread.h (stubs for mutexes only - no thread support yet!) + + pthread_mutex_init: function() {}, + pthread_mutex_destroy: function() {}, + pthread_mutex_lock: function() {}, + pthread_mutex_unlock: function() {}, + + // dirent.h + + opendir: function(pname) { + return 0; } }; diff --git a/src/parseTools.js b/src/parseTools.js index 12b531ea..52afcfe7 100644 --- a/src/parseTools.js +++ b/src/parseTools.js @@ -57,7 +57,7 @@ function toNiceIdent(ident) { assert(ident); if (parseFloat(ident) == ident) return ident; if (ident == 'null') return '0'; // see parseNumerical - return ident.replace('%', '$').replace(/["\\ \.@:<>,\*\[\]-]/g, '_'); + return ident.replace('%', '$').replace(/["&\\ \.@:<>,\*\[\]-]/g, '_'); } // Kind of a hack. In some cases we have strings that we do not want diff --git a/src/preamble.js b/src/preamble.js index ad7ea12a..e375b90a 100644 --- a/src/preamble.js +++ b/src/preamble.js @@ -268,8 +268,6 @@ function __shutdownRuntime__() { } } -// stdio.h - // Copies a list of num items on the HEAP into a // a normal JavaScript array of numbers |