aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xemscripten.py19
-rw-r--r--src/hello_world.js (renamed from tests/hello_world.js)0
-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
-rw-r--r--tests/sockets/test_getprotobyname.c87
-rw-r--r--tests/test_other.py14
-rw-r--r--tests/test_sockets.py3
-rw-r--r--tools/shared.py4
11 files changed, 226 insertions, 22 deletions
diff --git a/emscripten.py b/emscripten.py
index 907e88ce..ae46ca07 100755
--- a/emscripten.py
+++ b/emscripten.py
@@ -804,6 +804,13 @@ def emscript_fast(infile, settings, outfile, libraries=[], compiler_engine=None,
if DEBUG: logging.debug('emscript: js compiler glue')
+ # Settings changes
+ assert settings['TARGET_LE32'] == 1
+ settings['TARGET_LE32'] = 2
+ if 'i64Add' in metadata['declares']: # TODO: others, once we split them up
+ settings['PRECISE_I64_MATH'] = 2
+ metadata['declares'] = filter(lambda i64_func: i64_func not in ['getHigh32', 'setHigh32', '__muldi3', '__divdi3', '__remdi3', '__udivdi3', '__uremdi3'], metadata['declares']) # FIXME: do these one by one as normal js lib funcs
+
# Integrate info from backend
settings['DEFAULT_LIBRARY_FUNCS_TO_INCLUDE'] = list(
set(settings['DEFAULT_LIBRARY_FUNCS_TO_INCLUDE'] + map(shared.JS.to_nice_ident, metadata['declares'])).difference(
@@ -811,10 +818,6 @@ def emscript_fast(infile, settings, outfile, libraries=[], compiler_engine=None,
)
) + map(lambda x: x[1:], metadata['externs'])
- # Settings changes
- assert settings['TARGET_LE32'] == 1
- settings['TARGET_LE32'] = 2
-
# Save settings to a file to work around v8 issue 1579
settings_file = temp_files.get('.txt').name
def save_settings():
@@ -885,18 +888,14 @@ def emscript_fast(infile, settings, outfile, libraries=[], compiler_engine=None,
#if DEBUG: outfile.write('// funcs\n')
if settings.get('ASM_JS'):
- #print >> sys.stderr, '<<<<<<', post, '>>>>>>'
- post_funcs = '' #, post_rest = post.split('// EMSCRIPTEN_END_FUNCS\n')
- #post = post_rest
-
# Move preAsms to their right place
def move_preasm(m):
contents = m.groups(0)[0]
outfile.write(contents + '\n')
return ''
- post_funcs = re.sub(r'/\* PRE_ASM \*/(.*)\n', lambda m: move_preasm(m), post_funcs)
+ funcs_js[1] = re.sub(r'/\* PRE_ASM \*/(.*)\n', lambda m: move_preasm(m), funcs_js[1])
- funcs_js += ['\n' + post_funcs + '// EMSCRIPTEN_END_FUNCS\n']
+ funcs_js += ['\n// EMSCRIPTEN_END_FUNCS\n']
simple = os.environ.get('EMCC_SIMPLE_ASM')
class Counter:
diff --git a/tests/hello_world.js b/src/hello_world.js
index 01082eb4..01082eb4 100644
--- a/tests/hello_world.js
+++ b/src/hello_world.js
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(',') + '}';
}
}
diff --git a/tests/sockets/test_getprotobyname.c b/tests/sockets/test_getprotobyname.c
new file mode 100644
index 00000000..571a287e
--- /dev/null
+++ b/tests/sockets/test_getprotobyname.c
@@ -0,0 +1,87 @@
+#include <assert.h>
+#include <errno.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+void checkEntryByValue(char* name, int port, char** aliasArray) {
+ struct protoent* entry;
+ char** aliases;
+
+ // Perform a protocol look up by name
+ entry = getprotobyname(name);
+ assert(entry != NULL);
+
+ // Check results
+ assert(strcmp(name, entry->p_name) == 0);
+ assert(port == entry->p_proto);
+
+ aliases = entry->p_aliases;
+ for (int i = 0; aliases[i] != NULL; i++) {
+ assert(strcmp(aliases[i], aliasArray[i]) == 0);
+ }
+
+ // Perform a protocol look up by number
+ entry = getprotobynumber(port);
+ assert(entry != NULL);
+
+ // Check results
+ assert(strcmp(name, entry->p_name) == 0);
+ assert(port == entry->p_proto);
+
+ aliases = entry->p_aliases;
+ for (int i = 0; aliases[i] != NULL; i++) {
+ assert(strcmp(aliases[i], aliasArray[i]) == 0);
+ }
+}
+
+void checkEntryDatabase() {
+ struct protoent* entry;
+
+ // Don't call setprotoent() initially as getprotoent() should open the "database" if necessary.
+ entry = getprotoent();
+ assert(entry != NULL);
+ assert(strcmp("tcp", entry->p_name) == 0);
+
+ entry = getprotoent();
+ assert(entry != NULL);
+ assert(strcmp("udp", entry->p_name) == 0);
+
+ // Check that setprotoent() correctly sets the next entry to the first entry
+ setprotoent(1);
+
+ entry = getprotoent();
+ assert(entry != NULL);
+ assert(strcmp("tcp", entry->p_name) == 0);
+
+ entry = getprotoent();
+ assert(entry != NULL);
+ assert(strcmp("udp", entry->p_name) == 0);
+
+ // If we do a getprotoent() that goes past the end of the 'database' check that it returns NULL.
+ entry = getprotoent();
+ assert(entry == NULL);
+}
+
+int main() {
+ // First check getprotobyname() and getprotobynumber()
+ char* aliases[] = {"TCP"};
+ checkEntryByValue("tcp", 6, aliases);
+
+ aliases[0] = "UDP";
+ checkEntryByValue("udp", 17, aliases);
+
+ // Check that the doomsday protocol hasn't been implemented :-) ......
+ assert(getprotobyname("doomsday") == NULL);
+
+ // Now check setprotoent() and getprotoent()
+ checkEntryDatabase();
+
+ endprotoent();
+
+ puts("success");
+
+ return EXIT_SUCCESS;
+}
+
diff --git a/tests/test_other.py b/tests/test_other.py
index 5100db72..b10ae13b 100644
--- a/tests/test_other.py
+++ b/tests/test_other.py
@@ -2136,3 +2136,17 @@ int main()
assert 'test.o' in head, 'Invalid dependency target'
assert 'test.cpp' in tail and 'test.hpp' in tail, 'Invalid dependencies generated'
+ def test_quoted_js_lib_key(self):
+ open('lib.js', 'w').write(r'''
+mergeInto(LibraryManager.library, {
+ __internal_data:{
+ '<' : 0,
+ 'white space' : 1
+ },
+ printf__deps: ['__internal_data', 'fprintf']
+});
+''')
+
+ Popen([PYTHON, EMCC, path_from_root('tests', 'hello_world.cpp'), '--js-library', 'lib.js']).communicate()
+ self.assertContained('hello, world!', run_js(os.path.join(self.get_dir(), 'a.out.js')))
+
diff --git a/tests/test_sockets.py b/tests/test_sockets.py
index 1229aa70..f9dcbc68 100644
--- a/tests/test_sockets.py
+++ b/tests/test_sockets.py
@@ -228,6 +228,9 @@ class sockets(BrowserCore):
def test_gethostbyname(self):
self.do_run(open(path_from_root('tests', 'sockets', 'test_gethostbyname.c')).read(), 'success')
+ def test_getprotobyname(self):
+ self.do_run(open(path_from_root('tests', 'sockets', 'test_getprotobyname.c')).read(), 'success')
+
def test_sockets_echo(self):
sockets_include = '-I'+path_from_root('tests', 'sockets')
diff --git a/tools/shared.py b/tools/shared.py
index 3eb72a1e..3456ab18 100644
--- a/tools/shared.py
+++ b/tools/shared.py
@@ -316,7 +316,7 @@ def check_sanity(force=False):
try:
reason = None
if not CONFIG_FILE:
- if not force: return # config stored directly in EM_CONFIG => skip sanity checks
+ return # config stored directly in EM_CONFIG => skip sanity checks
else:
settings_mtime = os.stat(CONFIG_FILE).st_mtime
sanity_file = CONFIG_FILE + '_sanity'
@@ -637,7 +637,7 @@ def check_engine(engine):
try:
if not CONFIG_FILE:
return True # config stored directly in EM_CONFIG => skip engine check
- return 'hello, world!' in run_js(path_from_root('tests', 'hello_world.js'), engine)
+ return 'hello, world!' in run_js(path_from_root('src', 'hello_world.js'), engine)
except Exception, e:
print 'Checking JS engine %s failed. Check %s. Details: %s' % (str(engine), EM_CONFIG, str(e))
return False