aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/hello_world.js92
-rw-r--r--src/jsifier.js4
-rw-r--r--src/library.js95
-rw-r--r--src/modules.js7
-rw-r--r--src/simd.js7
-rw-r--r--src/utility.js8
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(',') + '}';
}
}