aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AUTHORS1
-rw-r--r--cmake/Platform/Emscripten.cmake4
-rwxr-xr-xemcc31
-rw-r--r--emlink.py29
-rwxr-xr-xemscripten.py28
-rw-r--r--src/compiler.js14
-rw-r--r--src/intertyper.js3
-rw-r--r--src/jsifier.js44
-rw-r--r--src/library.js95
-rw-r--r--src/library_egl.js76
-rw-r--r--src/library_gl.js197
-rw-r--r--src/library_sdl.js234
-rw-r--r--src/modules.js50
-rw-r--r--src/parseTools.js108
-rw-r--r--src/preamble.js44
-rw-r--r--src/relooper/Relooper.cpp10
-rw-r--r--src/runtime.js4
-rw-r--r--src/settings.js23
-rw-r--r--src/struct_info.json21
-rw-r--r--src/utility.js9
-rw-r--r--system/include/emscripten/emscripten.h9
-rw-r--r--system/lib/libc/musl/src/regex/regcomp.c3352
-rw-r--r--system/lib/libc/musl/src/regex/regerror.c35
-rw-r--r--system/lib/libc/musl/src/regex/regexec.c1011
-rw-r--r--system/lib/libc/musl/src/regex/tre-mem.c158
-rw-r--r--system/lib/libc/musl/src/regex/tre.h231
-rw-r--r--system/lib/libcextra.symbols7
-rw-r--r--tests/cases/storebigfloat.ll17
-rw-r--r--tests/emscripten_get_now.cpp6
-rw-r--r--tests/gles2_conformance.cpp76
-rw-r--r--tests/gles2_uniform_arrays.cpp9
-rw-r--r--tests/lua/Makefile3
-rw-r--r--tests/lua/src/Makefile3
-rwxr-xr-xtests/runner.py20
-rw-r--r--tests/sdl_joystick.c124
-rw-r--r--tests/sockets/test_getaddrinfo.c60
-rw-r--r--tests/test_benchmark.py28
-rw-r--r--tests/test_browser.py85
-rw-r--r--tests/test_core.py127
-rw-r--r--tests/test_egl.c73
-rw-r--r--tests/test_other.py78
-rw-r--r--tests/zlib/CMakeLists.txt190
-rw-r--r--tests/zlib/zconf.h.cmakein (renamed from tests/zlib/zconf.h)4
-rw-r--r--tools/eliminator/eliminator-test-output.js3
-rw-r--r--tools/eliminator/eliminator-test.js10
-rw-r--r--tools/js-optimizer.js142
-rw-r--r--tools/response_file.py6
-rw-r--r--tools/shared.py55
48 files changed, 6553 insertions, 394 deletions
diff --git a/AUTHORS b/AUTHORS
index 0b8fdf33..6a28c205 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -107,3 +107,4 @@ a license to everyone to use it as detailed in LICENSE.)
* Michael Tirado <icetooth333@gmail.com>
* Ben Noordhuis <info@bnoordhuis.nl>
* Bob Roberts <bobroberts177@gmail.com>
+* John Vilk <jvilk@cs.umass.edu>
diff --git a/cmake/Platform/Emscripten.cmake b/cmake/Platform/Emscripten.cmake
index 7c8e83fa..e1e54ccf 100644
--- a/cmake/Platform/Emscripten.cmake
+++ b/cmake/Platform/Emscripten.cmake
@@ -146,6 +146,10 @@ set(link_js_counter 1)
# Internal function: Do not call from user CMakeLists.txt files. Use one of em_link_js_library()/em_link_pre_js()/em_link_post_js() instead.
function(em_add_tracked_link_flag target flagname)
get_target_property(props ${target} LINK_FLAGS)
+ if(NOT props)
+ set(props "")
+ endif()
+
# User can input list of JS files either as a single list, or as variable arguments to this function, so iterate over varargs, and treat each
# item in varargs as a list itself, to support both syntax forms.
foreach(jsFileList ${ARGN})
diff --git a/emcc b/emcc
index 8f8ad4aa..c3f9d862 100755
--- a/emcc
+++ b/emcc
@@ -1133,10 +1133,11 @@ try:
heap = 4096
while heap < shared.Settings.TOTAL_MEMORY:
- if heap <= 16*1024*1024:
- heap *= 2
- else:
- heap += 16*1024*1024
+ heap *= 2
+ #if heap <= 16*1024*1024:
+ # heap *= 2
+ #else:
+ # heap += 16*1024*1024
if heap != shared.Settings.TOTAL_MEMORY:
logging.warning('increasing TOTAL_MEMORY to %d to be more reasonable for asm.js' % heap)
shared.Settings.TOTAL_MEMORY = heap
@@ -1429,6 +1430,12 @@ try:
'wctob.c',
'wctomb.c',
]],
+ ['regex', [
+ 'regcomp.c',
+ 'regerror.c',
+ 'regexec.c',
+ 'tre-mem.c',
+ ]],
['stdio', [
'fwprintf.c',
'swprintf.c',
@@ -1631,18 +1638,26 @@ try:
else:
# At minimum remove dead functions etc., this potentially saves a lot in the size of the generated code (and the time to compile it)
link_opts += shared.Building.get_safe_internalize() + ['-globaldce']
- shared.Building.llvm_opt(in_temp(target_basename + '.bc'), link_opts)
- if DEBUG: save_intermediate('linktime', 'bc')
+ if not save_bc:
+ # let llvm opt directly emit ll, to skip writing and reading all the bitcode
+ link_opts += ['-S']
+ shared.Building.llvm_opt(final, link_opts, final + '.link.ll')
+ final = final + '.link.ll'
+ if DEBUG: save_intermediate('linktime', 'll')
+ else:
+ shared.Building.llvm_opt(final, link_opts)
+ if DEBUG: save_intermediate('linktime', 'bc')
if save_bc:
shutil.copyfile(final, save_bc)
# Prepare .ll for Emscripten
if not LEAVE_INPUTS_RAW:
- final = shared.Building.llvm_dis(final, final + '.ll')
+ if save_bc:
+ final = shared.Building.llvm_dis(final, final + '.ll')
else:
assert len(input_files) == 1
- if DEBUG: save_intermediate('ll', 'll')
+ if DEBUG and save_bc: save_intermediate('ll', 'll')
if AUTODEBUG:
logging.debug('autodebug')
diff --git a/emlink.py b/emlink.py
index 7311f84a..f767ce58 100644
--- a/emlink.py
+++ b/emlink.py
@@ -10,21 +10,24 @@ import sys
from tools import shared
from tools.asm_module import AsmModule
-try:
- me, main, side, out = sys.argv[:4]
-except:
- print >> sys.stderr, 'usage: emlink.py [main module] [side module] [output name]'
- sys.exit(1)
+def run():
+ try:
+ me, main, side, out = sys.argv[:4]
+ except:
+ print >> sys.stderr, 'usage: emlink.py [main module] [side module] [output name]'
+ sys.exit(1)
-print 'Main module:', main
-print 'Side module:', side
-print 'Output:', out
+ print 'Main module:', main
+ print 'Side module:', side
+ print 'Output:', out
-shared.try_delete(out)
+ shared.try_delete(out)
-main = AsmModule(main)
-side = AsmModule(side)
+ main = AsmModule(main)
+ side = AsmModule(side)
-side.relocate_into(main)
-main.write(out)
+ side.relocate_into(main)
+ main.write(out)
+if __name__ == '__main__':
+ run()
diff --git a/emscripten.py b/emscripten.py
index 5576baba..75e6711a 100755
--- a/emscripten.py
+++ b/emscripten.py
@@ -11,6 +11,7 @@ headers, for the libc implementation in JS).
import os, sys, json, optparse, subprocess, re, time, multiprocessing, string, logging
+from tools import shared
from tools import jsrun, cache as cache_module, tempfiles
from tools.response_file import read_response_file
@@ -25,7 +26,6 @@ def get_configuration():
if hasattr(get_configuration, 'configuration'):
return get_configuration.configuration
- from tools import shared
configuration = shared.Configuration(environ=os.environ)
get_configuration.configuration = configuration
return configuration
@@ -117,7 +117,7 @@ def emscript(infile, settings, outfile, libraries=[], compiler_engine=None,
last = func_start
func_start = ll.find('\ndefine ', func_start)
if func_start > last:
- pre.append(ll[last:min(func_start+1, meta_start)] + '\n')
+ pre.append(ll[last:min(func_start+1, meta_start) if meta_start > 0 else func_start+1] + '\n')
if func_start < 0:
pre.append(ll[last:meta_start] + '\n')
break
@@ -425,8 +425,8 @@ def emscript(infile, settings, outfile, libraries=[], compiler_engine=None,
Counter.i += 1
bad = 'b' + str(i)
params = ','.join(['p%d' % p for p in range(len(sig)-1)])
- coercions = ';'.join(['p%d = %sp%d%s' % (p, '+' if sig[p+1] != 'i' else '', p, '' if sig[p+1] != 'i' else '|0') for p in range(len(sig)-1)]) + ';'
- ret = '' if sig[0] == 'v' else ('return %s0' % ('+' if sig[0] != 'i' else ''))
+ coercions = ';'.join(['p%d = %s' % (p, shared.JS.make_coercion('p%d' % p, sig[p+1], settings)) for p in range(len(sig)-1)]) + ';'
+ ret = '' if sig[0] == 'v' else ('return %s' % shared.JS.make_initializer(sig[0], settings))
start = raw.index('[')
end = raw.rindex(']')
body = raw[start+1:end].split(',')
@@ -451,7 +451,7 @@ def emscript(infile, settings, outfile, libraries=[], compiler_engine=None,
math_envs = ['Math.min'] # TODO: move min to maths
asm_setup += '\n'.join(['var %s = %s;' % (f.replace('.', '_'), f) for f in math_envs])
- if settings['TO_FLOAT32']: maths += ['Math.toFloat32']
+ if settings['PRECISE_F32']: maths += ['Math.fround']
basic_funcs = ['abort', 'assert', 'asmPrintInt', 'asmPrintFloat'] + [m.replace('.', '_') for m in math_envs]
if settings['RESERVED_FUNCTION_POINTERS'] > 0: basic_funcs.append('jsCall')
@@ -476,18 +476,14 @@ def emscript(infile, settings, outfile, libraries=[], compiler_engine=None,
asm_runtime_funcs = ['stackAlloc', 'stackSave', 'stackRestore', 'setThrew'] + ['setTempRet%d' % i for i in range(10)]
# function tables
- def asm_coerce(value, sig):
- if sig == 'v': return value
- return ('+' if sig != 'i' else '') + value + ('|0' if sig == 'i' else '')
-
function_tables = ['dynCall_' + table for table in last_forwarded_json['Functions']['tables']]
function_tables_impls = []
for sig in last_forwarded_json['Functions']['tables'].iterkeys():
args = ','.join(['a' + str(i) for i in range(1, len(sig))])
- arg_coercions = ' '.join(['a' + str(i) + '=' + asm_coerce('a' + str(i), sig[i]) + ';' for i in range(1, len(sig))])
- coerced_args = ','.join([asm_coerce('a' + str(i), sig[i]) for i in range(1, len(sig))])
- ret = ('return ' if sig[0] != 'v' else '') + asm_coerce('FUNCTION_TABLE_%s[index&{{{ FTM_%s }}}](%s)' % (sig, sig, coerced_args), sig[0])
+ arg_coercions = ' '.join(['a' + str(i) + '=' + shared.JS.make_coercion('a' + str(i), sig[i], settings) + ';' for i in range(1, len(sig))])
+ coerced_args = ','.join([shared.JS.make_coercion('a' + str(i), sig[i], settings) for i in range(1, len(sig))])
+ ret = ('return ' if sig[0] != 'v' else '') + shared.JS.make_coercion('FUNCTION_TABLE_%s[index&{{{ FTM_%s }}}](%s)' % (sig, sig, coerced_args), sig[0], settings)
function_tables_impls.append('''
function dynCall_%s(index%s%s) {
index = index|0;
@@ -497,7 +493,7 @@ def emscript(infile, settings, outfile, libraries=[], compiler_engine=None,
''' % (sig, ',' if len(sig) > 1 else '', args, arg_coercions, ret))
for i in range(settings['RESERVED_FUNCTION_POINTERS']):
- jsret = ('return ' if sig[0] != 'v' else '') + asm_coerce('jsCall(%d%s%s)' % (i, ',' if coerced_args else '', coerced_args), sig[0])
+ jsret = ('return ' if sig[0] != 'v' else '') + shared.JS.make_coercion('jsCall(%d%s%s)' % (i, ',' if coerced_args else '', coerced_args), sig[0], settings)
function_tables_impls.append('''
function jsCall_%s_%s(%s) {
%s
@@ -505,7 +501,6 @@ def emscript(infile, settings, outfile, libraries=[], compiler_engine=None,
}
''' % (sig, i, args, arg_coercions, jsret))
- from tools import shared
shared.Settings.copy(settings)
asm_setup += '\n' + shared.JS.make_invoke(sig) + '\n'
basic_funcs.append('invoke_%s' % sig)
@@ -585,7 +580,7 @@ var asm = (function(global, env, buffer) {
var undef = 0;
var tempInt = 0, tempBigInt = 0, tempBigIntP = 0, tempBigIntS = 0, tempBigIntR = 0.0, tempBigIntI = 0, tempBigIntD = 0, tempValue = 0, tempDouble = 0.0;
''' + ''.join(['''
- var tempRet%d = 0;''' % i for i in range(10)]) + '\n' + asm_global_funcs + '''
+ var tempRet%d = 0;''' % i for i in range(10)]) + '\n' + asm_global_funcs] + [' var tempFloat = %s;\n' % ('Math_fround(0)' if settings.get('PRECISE_F32') else '0.0')] + ['''
// EMSCRIPTEN_START_FUNCS
function stackAlloc(size) {
size = size|0;
@@ -727,14 +722,12 @@ def main(args, compiler_engine, cache, jcache, relooper, temp_files, DEBUG, DEBU
relooper = cache.get_path('relooper.js')
settings.setdefault('RELOOPER', relooper)
if not os.path.exists(relooper):
- from tools import shared
shared.Building.ensure_relooper(relooper)
settings.setdefault('STRUCT_INFO', cache.get_path('struct_info.compiled.json'))
struct_info = settings.get('STRUCT_INFO')
if not os.path.exists(struct_info):
- from tools import shared
shared.Building.ensure_struct_info(struct_info)
emscript(args.infile, settings, args.outfile, libraries, compiler_engine=compiler_engine,
@@ -833,7 +826,6 @@ WARNING: You should normally never use this! Use emcc instead.
temp_files = tempfiles.TempFiles(temp_dir)
if keywords.compiler is None:
- from tools import shared
keywords.compiler = shared.COMPILER_ENGINE
if keywords.verbose is None:
diff --git a/src/compiler.js b/src/compiler.js
index e9197a5d..aa3c7b92 100644
--- a/src/compiler.js
+++ b/src/compiler.js
@@ -311,12 +311,16 @@ function compile(raw) {
B = new Benchmarker();
-if (ll_file) {
- if (ll_file.indexOf(String.fromCharCode(10)) == -1) {
- compile(read(ll_file));
- } else {
- compile(ll_file); // we are given raw .ll
+try {
+ if (ll_file) {
+ if (ll_file.indexOf(String.fromCharCode(10)) == -1) {
+ compile(read(ll_file));
+ } else {
+ compile(ll_file); // we are given raw .ll
+ }
}
+} catch(err) {
+ printErr('aborting from js compiler due to exception: ' + err);
}
//var M = keys(tokenCacheMisses).map(function(m) { return [m, misses[m]] }).sort(function(a, b) { return a[1] - b[1] });
diff --git a/src/intertyper.js b/src/intertyper.js
index fceeb38d..fa53c652 100644
--- a/src/intertyper.js
+++ b/src/intertyper.js
@@ -680,6 +680,9 @@ function intertyper(lines, sidePass, baseLineNums) {
args.push(ident);
});
}
+ item.ident = expandLLVMString(item.ident).replace(/(#[^\n]*)/g, function(m) {
+ return '/* ' + m.substr(1) + ' */'; // fix asm comments to js comments
+ });
if (item.assignTo) item.ident = 'return ' + item.ident;
item.ident = '(function(' + params + ') { ' + item.ident + ' })(' + args + ');';
return { ret: item, item: item };
diff --git a/src/jsifier.js b/src/jsifier.js
index 0da48a8c..acfb6365 100644
--- a/src/jsifier.js
+++ b/src/jsifier.js
@@ -490,10 +490,19 @@ function JSify(data, functionsOnly, givenFunctions) {
} else {
// If this is not linkable, anything not in the library is definitely missing
var cancel = false;
+ if (item.ident in DEAD_FUNCTIONS) {
+ if (LibraryManager.library[shortident + '__asm']) {
+ warn('cannot kill asm library function ' + item.ident);
+ } else {
+ LibraryManager.library[shortident] = new Function("Module['printErr']('dead function: " + shortident + "'); abort(-1);");
+ delete LibraryManager.library[shortident + '__inline'];
+ delete LibraryManager.library[shortident + '__deps'];
+ }
+ }
if (!LINKABLE && !LibraryManager.library.hasOwnProperty(shortident) && !LibraryManager.library.hasOwnProperty(shortident + '__inline')) {
if (ERROR_ON_UNDEFINED_SYMBOLS) error('unresolved symbol: ' + shortident);
- if (VERBOSE || WARN_ON_UNDEFINED_SYMBOLS) printErr('warning: unresolved symbol: ' + shortident);
- if (ASM_JS || item.ident in DEAD_FUNCTIONS) {
+ else if (VERBOSE || WARN_ON_UNDEFINED_SYMBOLS) warn('unresolved symbol: ' + shortident);
+ if (ASM_JS) {
// emit a stub that will fail during runtime. this allows asm validation to succeed.
LibraryManager.library[shortident] = new Function("Module['printErr']('missing function: " + shortident + "'); abort(-1);");
} else {
@@ -756,14 +765,7 @@ function JSify(data, functionsOnly, givenFunctions) {
if (func.setjmpTable && !ASM_JS) {
ret += ' } catch(e) { if (!e.longjmp || !(e.id in mySetjmpIds)) throw(e); setjmpTable[setjmpLabels[e.id]](e.value) }';
}
- if (ASM_JS && func.returnType !== 'void') {
- // Add a return
- if (func.returnType in Runtime.FLOAT_TYPES) {
- ret += ' return +0;\n';
- } else {
- ret += ' return 0;\n';
- }
- }
+ if (ASM_JS && func.returnType !== 'void') ret += ' return ' + asmInitializer(func.returnType) + ';\n'; // Add a return
} else {
ret += (SHOW_LABELS ? indent + '/* ' + block.entries[0] + ' */' : '') + '\n' + getLabelLines(block.labels[0]);
}
@@ -833,11 +835,7 @@ function JSify(data, functionsOnly, givenFunctions) {
var lastReturn = func.JS.lastIndexOf('return ');
if ((lastCurly < 0 && lastReturn < 0) || // no control flow, no return
(lastCurly >= 0 && lastReturn < lastCurly)) { // control flow, no return past last join
- if (func.returnType in Runtime.FLOAT_TYPES) {
- func.JS += ' return +0;\n';
- } else {
- func.JS += ' return 0;\n';
- }
+ func.JS += ' return ' + asmInitializer(func.returnType) + ';\n';
}
}
func.JS += '}\n';
@@ -1337,7 +1335,7 @@ function JSify(data, functionsOnly, givenFunctions) {
if (isNumber(item.ident)) {
// Direct read from a memory address; this may be an intentional segfault, if not, it is a bug in the source
if (ASM_JS) {
- return asmCoercion('abort(' + item.ident + ')', item.type);
+ return asmFFICoercion('abort(' + item.ident + ')', item.type);
} else {
item.assignTo = null;
return 'throw "fault on read from ' + item.ident + '";';
@@ -1514,8 +1512,10 @@ function JSify(data, functionsOnly, givenFunctions) {
args = args.map(function(arg, i) { return indexizeFunctions(arg, argsTypes[i]) });
if (ASM_JS) {
- if (shortident in Functions.libraryFunctions || simpleIdent in Functions.libraryFunctions || byPointerForced || invoke || extCall || funcData.setjmpTable) {
- args = args.map(function(arg, i) { return asmCoercion(arg, argsTypes[i]) });
+ var ffiCall = (shortident in Functions.libraryFunctions || simpleIdent in Functions.libraryFunctions || byPointerForced || invoke || extCall || funcData.setjmpTable) &&
+ !(simpleIdent in JS_MATH_BUILTINS);
+ if (ffiCall) {
+ args = args.map(function(arg, i) { return asmCoercion(arg, ensureValidFFIType(argsTypes[i])) });
} else {
args = args.map(function(arg, i) { return asmEnsureFloat(arg, argsTypes[i]) });
}
@@ -1592,7 +1592,7 @@ function JSify(data, functionsOnly, givenFunctions) {
returnType = getReturnType(type);
if (callIdent in Functions.implementedFunctions) {
// LLVM sometimes bitcasts for no reason. We must call using the exact same type as the actual function is generated as
- var trueType = Functions.getSignatureReturnType(Functions.implementedFunctions[callIdent]);
+ var trueType = Functions.getSignatureType(Functions.implementedFunctions[callIdent][0]);
if (trueType !== returnType && !isIdenticallyImplemented(trueType, returnType)) {
if (VERBOSE) warnOnce('Fixing function call based on return type from signature, on ' + [callIdent, returnType, trueType]);
returnType = trueType;
@@ -1628,7 +1628,11 @@ function JSify(data, functionsOnly, givenFunctions) {
var ret = callIdent + '(' + args.join(',') + ')';
if (ASM_JS) { // TODO: do only when needed (library functions and Math.*?) XXX && simpleIdent in Functions.libraryFunctions) {
- ret = asmCoercion(ret, returnType);
+ if (ffiCall) {
+ ret = asmFFICoercion(ret, returnType);
+ } else {
+ ret = asmCoercion(ret, returnType);
+ }
if (simpleIdent == 'abort' && funcData.returnType != 'void') {
ret += '; return ' + asmCoercion('0', funcData.returnType); // special case: abort() can happen without return, breaking the return type of asm functions. ensure a return
}
diff --git a/src/library.js b/src/library.js
index 31f531e9..48acf6ac 100644
--- a/src/library.js
+++ b/src/library.js
@@ -847,10 +847,7 @@ LibraryManager.library = {
___setErrNo(ERRNO_CODES.ERANGE);
return 0;
} else {
- for (var i = 0; i < cwd.length; i++) {
- {{{ makeSetValue('buf', 'i', 'cwd.charCodeAt(i)', 'i8') }}}
- }
- {{{ makeSetValue('buf', 'i', '0', 'i8') }}}
+ writeAsciiToMemory(cwd, buf);
return buf;
}
},
@@ -1193,7 +1190,6 @@ LibraryManager.library = {
_exit: function(status) {
// void _exit(int status);
// http://pubs.opengroup.org/onlinepubs/000095399/functions/exit.html
- Module.print('exit(' + status + ') called');
Module['exit'](status);
},
fork__deps: ['__setErrNo', '$ERRNO_CODES'],
@@ -1293,10 +1289,7 @@ LibraryManager.library = {
if (namesize < ret.length + 1) {
return ___setErrNo(ERRNO_CODES.ERANGE);
} else {
- for (var i = 0; i < ret.length; i++) {
- {{{ makeSetValue('name', 'i', 'ret.charCodeAt(i)', 'i8') }}}
- }
- {{{ makeSetValue('name', 'i', '0', 'i8') }}}
+ writeAsciiToMemory(ret, name);
return 0;
}
},
@@ -2699,10 +2692,7 @@ LibraryManager.library = {
var result = dir + '/' + name;
if (!_tmpnam.buffer) _tmpnam.buffer = _malloc(256);
if (!s) s = _tmpnam.buffer;
- for (var i = 0; i < result.length; i++) {
- {{{ makeSetValue('s', 'i', 'result.charCodeAt(i)', 'i8') }}};
- }
- {{{ makeSetValue('s', 'i', '0', 'i8') }}};
+ writeAsciiToMemory(result, s);
return s;
},
tempnam__deps: ['tmpnam'],
@@ -3343,10 +3333,7 @@ LibraryManager.library = {
var ptrSize = {{{ Runtime.getNativeTypeSize('i8*') }}};
for (var i = 0; i < strings.length; i++) {
var line = strings[i];
- for (var j = 0; j < line.length; j++) {
- {{{ makeSetValue('poolPtr', 'j', 'line.charCodeAt(j)', 'i8') }}};
- }
- {{{ makeSetValue('poolPtr', 'j', '0', 'i8') }}};
+ writeAsciiToMemory(line, poolPtr);
{{{ makeSetValue('envPtr', 'i * ptrSize', 'poolPtr', 'i8*') }}};
poolPtr += line.length + 1;
}
@@ -3976,10 +3963,7 @@ LibraryManager.library = {
return ___setErrNo(ERRNO_CODES.ERANGE);
} else {
var msg = ERRNO_MESSAGES[errnum];
- for (var i = 0; i < msg.length; i++) {
- {{{ makeSetValue('strerrbuf', 'i', 'msg.charCodeAt(i)', 'i8') }}}
- }
- {{{ makeSetValue('strerrbuf', 'i', 0, 'i8') }}}
+ writeAsciiToMemory(msg, strerrbuf);
return 0;
}
} else {
@@ -5067,10 +5051,7 @@ LibraryManager.library = {
var layout = {{{ JSON.stringify(C_STRUCTS.utsname) }}};
function copyString(element, value) {
var offset = layout[element];
- for (var i = 0; i < value.length; i++) {
- {{{ makeSetValue('name', 'offset + i', 'value.charCodeAt(i)', 'i8') }}}
- }
- {{{ makeSetValue('name', 'offset + i', '0', 'i8') }}}
+ writeAsciiToMemory(value, name + offset);
}
if (name === 0) {
return -1;
@@ -6131,8 +6112,10 @@ LibraryManager.library = {
// int nanosleep(const struct timespec *rqtp, struct timespec *rmtp);
var seconds = {{{ makeGetValue('rqtp', C_STRUCTS.timespec.tv_sec, 'i32') }}};
var nanoseconds = {{{ makeGetValue('rqtp', C_STRUCTS.timespec.tv_nsec, 'i32') }}};
- {{{ makeSetValue('rmtp', C_STRUCTS.timespec.tv_sec, '0', 'i32') }}}
- {{{ makeSetValue('rmtp', C_STRUCTS.timespec.tv_nsec, '0', 'i32') }}}
+ if (rmtp !== 0) {
+ {{{ makeSetValue('rmtp', C_STRUCTS.timespec.tv_sec, '0', 'i32') }}}
+ {{{ makeSetValue('rmtp', C_STRUCTS.timespec.tv_nsec, '0', 'i32') }}}
+ }
return _usleep((seconds * 1e6) + (nanoseconds / 1000));
},
// TODO: Implement these for real.
@@ -6572,10 +6555,7 @@ LibraryManager.library = {
var me = _nl_langinfo;
if (!me.ret) me.ret = _malloc(32);
- for (var i = 0; i < result.length; i++) {
- {{{ makeSetValue('me.ret', 'i', 'result.charCodeAt(i)', 'i8') }}}
- }
- {{{ makeSetValue('me.ret', 'i', '0', 'i8') }}}
+ writeAsciiToMemory(result, me.ret);
return me.ret;
},
@@ -7433,6 +7413,9 @@ LibraryManager.library = {
getaddrinfo__deps: ['$Sockets', '$DNS', '_inet_pton4_raw', '_inet_ntop4_raw', '_inet_pton6_raw', '_inet_ntop6_raw', '_write_sockaddr', 'htonl'],
getaddrinfo: function(node, service, hint, out) {
+ // Note getaddrinfo currently only returns a single addrinfo with ai_next defaulting to NULL. When NULL
+ // hints are specified or ai_family set to AF_UNSPEC or ai_socktype or ai_protocol set to 0 then we
+ // really should provide a linked list of suitable addrinfo values.
var addrs = [];
var canon = null;
var addr = 0;
@@ -7487,6 +7470,15 @@ LibraryManager.library = {
type = proto === {{{ cDefine('IPPROTO_UDP') }}} ? {{{ cDefine('SOCK_DGRAM') }}} : {{{ cDefine('SOCK_STREAM') }}};
}
+ // If type or proto are set to zero in hints we should really be returning multiple addrinfo values, but for
+ // now default to a TCP STREAM socket so we can at least return a sensible addrinfo given NULL hints.
+ if (proto === 0) {
+ proto = {{{ cDefine('IPPROTO_TCP') }}};
+ }
+ if (type === 0) {
+ type = {{{ cDefine('SOCK_STREAM') }}};
+ }
+
if (!node && !service) {
return {{{ cDefine('EAI_NONAME') }}};
}
@@ -7494,14 +7486,14 @@ LibraryManager.library = {
{{{ cDefine('AI_NUMERICSERV') }}}|{{{ cDefine('AI_V4MAPPED') }}}|{{{ cDefine('AI_ALL') }}}|{{{ cDefine('AI_ADDRCONFIG') }}})) {
return {{{ cDefine('EAI_BADFLAGS') }}};
}
- if (({{{ makeGetValue('hint', C_STRUCTS.addrinfo.ai_flags, 'i32') }}} & {{{ cDefine('AI_CANONNAME') }}}) && !node) {
+ if (hint !== 0 && ({{{ makeGetValue('hint', C_STRUCTS.addrinfo.ai_flags, 'i32') }}} & {{{ cDefine('AI_CANONNAME') }}}) && !node) {
return {{{ cDefine('EAI_BADFLAGS') }}};
}
if (flags & {{{ cDefine('AI_ADDRCONFIG') }}}) {
// TODO
return {{{ cDefine('EAI_NONAME') }}};
}
- if (type !== {{{ cDefine('SOCK_STREAM') }}} && type !== {{{ cDefine('SOCK_DGRAM') }}}) {
+ if (type !== 0 &