diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/hello_world.js | 92 | ||||
-rw-r--r-- | src/jsifier.js | 4 | ||||
-rw-r--r-- | src/library.js | 95 | ||||
-rw-r--r-- | src/modules.js | 7 | ||||
-rw-r--r-- | src/simd.js | 7 | ||||
-rw-r--r-- | src/utility.js | 8 |
6 files changed, 203 insertions, 10 deletions
diff --git a/src/hello_world.js b/src/hello_world.js new file mode 100644 index 00000000..01082eb4 --- /dev/null +++ b/src/hello_world.js @@ -0,0 +1,92 @@ +// *** Environment setup code *** +var arguments_ = []; + +var ENVIRONMENT_IS_NODE = typeof process === 'object'; +var ENVIRONMENT_IS_WEB = typeof window === 'object'; +var ENVIRONMENT_IS_WORKER = typeof importScripts === 'function'; +var ENVIRONMENT_IS_SHELL = !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_NODE && !ENVIRONMENT_IS_WORKER; + +if (ENVIRONMENT_IS_NODE) { + // Expose functionality in the same simple way that the shells work + // Note that we pollute the global namespace here, otherwise we break in node + print = function(x) { + process['stdout'].write(x + '\n'); + }; + printErr = function(x) { + process['stderr'].write(x + '\n'); + }; + + var nodeFS = require('fs'); + + read = function(filename) { + var ret = nodeFS['readFileSync'](filename).toString(); + if (!ret && filename[0] != '/') { + filename = __dirname.split('/').slice(0, -1).join('/') + '/src/' + filename; + ret = nodeFS['readFileSync'](filename).toString(); + } + return ret; + }; + + load = function(f) { + globalEval(read(f)); + }; + + arguments_ = process['argv'].slice(2); + +} else if (ENVIRONMENT_IS_SHELL) { + // Polyfill over SpiderMonkey/V8 differences + if (!this['read']) { + this['read'] = function(f) { snarf(f) }; + } + + if (typeof scriptArgs != 'undefined') { + arguments_ = scriptArgs; + } else if (typeof arguments != 'undefined') { + arguments_ = arguments; + } + +} else if (ENVIRONMENT_IS_WEB) { + this['print'] = printErr = function(x) { + console.log(x); + }; + + this['read'] = function(url) { + var xhr = new XMLHttpRequest(); + xhr.open('GET', url, false); + xhr.send(null); + return xhr.responseText; + }; + + if (this['arguments']) { + arguments_ = arguments; + } +} else if (ENVIRONMENT_IS_WORKER) { + // We can do very little here... + + this['load'] = importScripts; + +} else { + throw 'Unknown runtime environment. Where are we?'; +} + +function globalEval(x) { + eval.call(null, x); +} + +if (typeof load == 'undefined' && typeof read != 'undefined') { + this['load'] = function(f) { + globalEval(read(f)); + }; +} + +if (typeof printErr === 'undefined') { + this['printErr'] = function(){}; +} + +if (typeof print === 'undefined') { + this['print'] = printErr; +} +// *** Environment setup code *** + +print('hello, world!'); + diff --git a/src/jsifier.js b/src/jsifier.js index 907855e7..b5502741 100644 --- a/src/jsifier.js +++ b/src/jsifier.js @@ -1859,10 +1859,10 @@ function JSify(data, functionsOnly, givenFunctions) { // first row are utilities called from generated code, second are needed from fastLong ['i64Add', 'i64Subtract', 'bitshift64Shl', 'bitshift64Lshr', 'bitshift64Ashr', 'llvm_ctlz_i32', 'llvm_cttz_i32'].forEach(function(func) { - if (!Functions.libraryFunctions[func]) { + if (!Functions.libraryFunctions[func] || (phase == 'glue' && func[0] === 'l')) { // TODO: one-by-one in fastcomp glue mode print(processLibraryFunction(LibraryManager.library[func], func)); // must be first to be close to generated code Functions.implementedFunctions['_' + func] = LibraryManager.library[func + '__sig']; - Functions.libraryFunctions[func] = 1; + Functions.libraryFunctions[func] = phase == 'glue' ? 2 : 1; // XXX // limited dependency handling var deps = LibraryManager.library[func + '__deps']; if (deps) { diff --git a/src/library.js b/src/library.js index 26d766e9..bdc0a39e 100644 --- a/src/library.js +++ b/src/library.js @@ -1868,14 +1868,13 @@ LibraryManager.library = { #endif #if USE_TYPED_ARRAYS == 2 } else if (type == 'i64') { - -#if TARGET_LE32 +#if TARGET_LE32 == 1 ret = [{{{ makeGetValue('varargs', 'argIndex', 'i32', undefined, undefined, true) }}}, {{{ makeGetValue('varargs', 'argIndex+8', 'i32', undefined, undefined, true) }}}]; argIndex += {{{ STACK_ALIGN }}}; // each 32-bit chunk is in a 64-bit block #else - ret = [{{{ makeGetValue('varargs', 'argIndex', 'i32', undefined, undefined, true) }}}, - {{{ makeGetValue('varargs', 'argIndex+4', 'i32', undefined, undefined, true) }}}]; + ret = [{{{ makeGetValue('varargs', 'argIndex', 'i32', undefined, undefined, true, 4) }}}, + {{{ makeGetValue('varargs', 'argIndex+4', 'i32', undefined, undefined, true, 4) }}}]; #endif #else @@ -7702,6 +7701,94 @@ LibraryManager.library = { return _gai_strerror.buffer; }, + // Implement netdb.h protocol entry (getprotoent, getprotobyname, getprotobynumber, setprotoent, endprotoent) + // http://pubs.opengroup.org/onlinepubs/9699919799/functions/getprotobyname.html + // The Protocols object holds our 'fake' protocols 'database'. + $Protocols: { + list: [], + map: {} + }, + setprotoent__deps: ['$Protocols'], + setprotoent: function(stayopen) { + // void setprotoent(int stayopen); + + // Allocate and populate a protoent structure given a name, protocol number and array of aliases + function allocprotoent(name, proto, aliases) { + // write name into buffer + var nameBuf = _malloc(name.length + 1); + writeAsciiToMemory(name, nameBuf); + + // write aliases into buffer + var j = 0; + var length = aliases.length; + var aliasListBuf = _malloc((length + 1) * 4); // Use length + 1 so we have space for the terminating NULL ptr. + + for (var i = 0; i < length; i++, j += 4) { + var alias = aliases[i]; + var aliasBuf = _malloc(alias.length + 1); + writeAsciiToMemory(alias, aliasBuf); + {{{ makeSetValue('aliasListBuf', 'j', 'aliasBuf', 'i8*') }}}; + } + {{{ makeSetValue('aliasListBuf', 'j', '0', 'i8*') }}}; // Terminating NULL pointer. + + // generate protoent + var pe = _malloc({{{ C_STRUCTS.protoent.__size__ }}}); + {{{ makeSetValue('pe', C_STRUCTS.protoent.p_name, 'nameBuf', 'i8*') }}}; + {{{ makeSetValue('pe', C_STRUCTS.protoent.p_aliases, 'aliasListBuf', 'i8**') }}}; + {{{ makeSetValue('pe', C_STRUCTS.protoent.p_proto, 'proto', 'i32') }}}; + return pe; + }; + + // Populate the protocol 'database'. The entries are limited to tcp and udp, though it is fairly trivial + // to add extra entries from /etc/protocols if desired - though not sure if that'd actually be useful. + var list = Protocols.list; + var map = Protocols.map; + if (list.length === 0) { + var entry = allocprotoent('tcp', 6, ['TCP']); + list.push(entry); + map['tcp'] = map['6'] = entry; + entry = allocprotoent('udp', 17, ['UDP']); + list.push(entry); + map['udp'] = map['17'] = entry; + } + + _setprotoent.index = 0; + }, + + endprotoent: function() { + // void endprotoent(void); + // We're not using a real protocol database so we don't do a real close. + }, + + getprotoent__deps: ['setprotoent', '$Protocols'], + getprotoent: function(number) { + // struct protoent *getprotoent(void); + // reads the next entry from the protocols 'database' or return NULL if 'eof' + if (_setprotoent.index === Protocols.list.length) { + return 0; + } else { + var result = Protocols.list[_setprotoent.index++]; + return result; + } + }, + + getprotobyname__deps: ['setprotoent', '$Protocols'], + getprotobyname: function(name) { + // struct protoent *getprotobyname(const char *); + name = Pointer_stringify(name); + _setprotoent(true); + var result = Protocols.map[name]; + return result; + }, + + getprotobynumber__deps: ['setprotoent', '$Protocols'], + getprotobynumber: function(number) { + // struct protoent *getprotobynumber(int proto); + _setprotoent(true); + var result = Protocols.map[number]; + return result; + }, + // ========================================================================== // sockets. Note that the implementation assumes all sockets are always // nonblocking diff --git a/src/modules.js b/src/modules.js index e80115c4..b9b8ab5e 100644 --- a/src/modules.js +++ b/src/modules.js @@ -282,7 +282,12 @@ var Functions = { sig += Functions.getSignatureLetter(type); } else { var chunks = getNumIntChunks(type); - for (var j = 0; j < chunks; j++) sig += 'i'; + if (chunks > 0) { + for (var j = 0; j < chunks; j++) sig += 'i'; + } else { + // some special type like a SIMD vector + sig += Functions.getSignatureLetter(type); + } } } if (hasVarArgs) sig += 'i'; diff --git a/src/simd.js b/src/simd.js index c7f5ff48..6e3e3675 100644 --- a/src/simd.js +++ b/src/simd.js @@ -848,8 +848,11 @@ var SIMD = (function () { * @return {float32x4} a bit-wise copy of t as a float32x4. */ bitsToFloat32x4: function(t) { - var alias = new Float32Array(t.storage_.buffer); - return new float32x4(alias[0], alias[1], alias[2], alias[3]); + var temp_storage = new Int32Array([t.storage_[0], t.storage_[1], t.storage_[2], t.storage_[3]]); + var alias = new Float32Array(temp_storage.buffer); + var fx4 = float32x4.zero(); + fx4.storage_ = alias; + return fx4; }, /** * @param {int32x4} t An instance of int32x4. diff --git a/src/utility.js b/src/utility.js index cd27b209..178c596b 100644 --- a/src/utility.js +++ b/src/utility.js @@ -346,13 +346,19 @@ function sortedJsonCompare(x, y) { return true; } +function escapeJSONKey(x) { + if (/^[\d\w_]+$/.exec(x) || x[0] === '"' || x[0] === "'") return x; + assert(x.indexOf("'") < 0, 'cannot have internal single quotes in keys: ' + x); + return "'" + x + "'"; +} + function stringifyWithFunctions(obj) { if (typeof obj === 'function') return obj.toString(); if (obj === null || typeof obj !== 'object') return JSON.stringify(obj); if (isArray(obj)) { return '[' + obj.map(stringifyWithFunctions).join(',') + ']'; } else { - return '{' + keys(obj).map(function(key) { return key + ':' + stringifyWithFunctions(obj[key]) }).join(',') + '}'; + return '{' + keys(obj).map(function(key) { return escapeJSONKey(key) + ':' + stringifyWithFunctions(obj[key]) }).join(',') + '}'; } } |