summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xemcc58
-rwxr-xr-xemscripten.py2
-rw-r--r--src/library.js286
-rw-r--r--src/library_sdl.js40
-rw-r--r--src/parseTools.js25
-rw-r--r--src/preamble.js9
-rw-r--r--tests/test_benchmark.py2
-rw-r--r--tests/test_core.py7
-rw-r--r--tests/test_other.py69
-rw-r--r--tools/js-optimizer.js27
-rw-r--r--tools/shared.py71
11 files changed, 373 insertions, 223 deletions
diff --git a/emcc b/emcc
index c295a76e..7333b832 100755
--- a/emcc
+++ b/emcc
@@ -781,6 +781,14 @@ def filename_type_ending(filename):
suffix = filename_type_suffix(filename)
return '' if not suffix else ('.' + suffix)
+# Log out times for emcc stages
+log_time_last = time.time()
+def log_time(name):
+ global log_time_last
+ now = time.time()
+ logging.debug('emcc step "%s" took %.2f seconds' % (name, now - log_time_last))
+ log_time_last = now
+
try:
call = CXX if use_cxx else CC
@@ -1297,6 +1305,8 @@ try:
temp_files = []
+ log_time('parse arguments and setup')
+
# First, generate LLVM bitcode. For each input file, we get base.o with bitcode
for input_file in input_files:
file_ending = filename_type_ending(input_file)
@@ -1336,6 +1346,8 @@ try:
logging.error(input_file + ': Unknown file suffix when compiling to LLVM bitcode!')
sys.exit(1)
+ log_time('bitcodeize inputs')
+
if not LEAVE_INPUTS_RAW:
assert len(temp_files) == len(input_files)
@@ -1382,6 +1394,8 @@ try:
shared.Building.link(temp_files, specified_target)
exit(0)
+ log_time('bitcodeize inputs')
+
## Continue on to create JavaScript
logging.debug('will generate JavaScript')
@@ -1755,15 +1769,14 @@ try:
libfile = shared.Cache.get(name, create)
extra_files_to_link.append(libfile)
+ log_time('calculate system libraries')
+
# First, combine the bitcode files if there are several. We must also link if we have a singleton .a
if len(input_files) + len(extra_files_to_link) > 1 or \
(not LEAVE_INPUTS_RAW and not (suffix(temp_files[0]) in BITCODE_ENDINGS or suffix(temp_files[0]) in DYNAMICLIB_ENDINGS) and shared.Building.is_ar(temp_files[0])):
linker_inputs = temp_files + extra_files_to_link
logging.debug('linking: ' + str(linker_inputs))
- t0 = time.time()
shared.Building.link(linker_inputs, in_temp(target_basename + '.bc'), force_archive_contents = len(filter(lambda temp: not temp.endswith(STATICLIB_ENDINGS), temp_files)) == 0)
- t1 = time.time()
- logging.debug(' linking took %.2f seconds' % (t1 - t0))
final = in_temp(target_basename + '.bc')
else:
if not LEAVE_INPUTS_RAW:
@@ -1773,19 +1786,16 @@ try:
final = in_temp(input_files[0])
shutil.copyfile(input_files[0], final)
+ log_time('link')
+
if DEBUG:
logging.debug('saving intermediate processing steps to %s' % shared.EMSCRIPTEN_TEMP_DIR)
intermediate_counter = 0
- intermediate_time = None
def save_intermediate(name=None, suffix='js'):
- global intermediate_counter, intermediate_time
+ global intermediate_counter
shutil.copyfile(final, os.path.join(shared.EMSCRIPTEN_TEMP_DIR, 'emcc-%d%s.%s' % (intermediate_counter, '' if name is None else '-' + name, suffix)))
intermediate_counter += 1
- now = time.time()
- if intermediate_time:
- logging.debug(' step took %.2f seconds' % (now - intermediate_time))
- intermediate_time = now
if not LEAVE_INPUTS_RAW: save_intermediate('basebc', 'bc')
@@ -1846,6 +1856,8 @@ try:
final += '.adsimp.bc'
if DEBUG: save_intermediate('adsimp', 'bc')
+ log_time('post-link')
+
# Emscripten
logging.debug('LLVM => JS')
extra_args = [] if not js_libraries else ['--libraries', ','.join(map(os.path.abspath, js_libraries))]
@@ -1853,6 +1865,8 @@ try:
final = shared.Building.emscripten(final, append_ext=False, extra_args=extra_args)
if DEBUG: save_intermediate('original')
+ log_time('emscript (llvm=>js)')
+
# Embed and preload files
if len(preload_files) + len(embed_files) > 0:
logging.debug('setting up files')
@@ -1913,9 +1927,7 @@ try:
shared.try_delete(memfile)
def repl(m):
# handle chunking of the memory initializer
- s = re.sub('[\[\]\n\(\)\. ]', '', m.groups(0)[0])
- s = s.replace('concat', ',')
- if s[-1] == ',': s = s[:-1]
+ s = m.groups(0)[0]
open(memfile, 'wb').write(''.join(map(lambda x: chr(int(x or '0')), s.split(','))))
if DEBUG:
# Copy into temp dir as well, so can be run there too
@@ -1926,6 +1938,7 @@ try:
src = re.sub(shared.JS.memory_initializer_pattern, repl, open(final).read(), count=1)
open(final + '.mem.js', 'w').write(src)
final += '.mem.js'
+ src = None
js_transform_tempfiles[-1] = final # simple text substitution preserves comment line number mappings
if DEBUG:
if os.path.exists(memfile):
@@ -1933,6 +1946,17 @@ try:
logging.debug('wrote memory initialization to %s' % memfile)
else:
logging.debug('did not see memory initialization')
+ elif shared.Settings.USE_TYPED_ARRAYS == 2 and not shared.Settings.MAIN_MODULE and not shared.Settings.SIDE_MODULE:
+ # not writing a binary init, but we can at least optimize them by splitting them up
+ src = open(final).read()
+ src = shared.JS.optimize_initializer(src)
+ if src is not None:
+ logging.debug('optimizing memory initialization')
+ open(final + '.mem.js', 'w').write(src)
+ final += '.mem.js'
+ src = None
+
+ log_time('source transforms')
# It is useful to run several js optimizer passes together, to save on unneeded unparsing/reparsing
js_optimizer_queue = []
@@ -2014,10 +2038,12 @@ try:
flush_js_optimizer_queue()
+ log_time('js opts')
+
# Remove some trivial whitespace # TODO: do not run when compress has already been done on all parts of the code
- src = open(final).read()
- src = re.sub(r'\n+[ \n]*\n+', '\n', src)
- open(final, 'w').write(src)
+ #src = open(final).read()
+ #src = re.sub(r'\n+[ \n]*\n+', '\n', src)
+ #open(final, 'w').write(src)
def generate_source_map(map_file_base_name, offset=0):
jsrun.run_js(shared.path_from_root('tools', 'source-maps', 'sourcemapper.js'),
@@ -2120,6 +2146,8 @@ try:
# copy final JS to output
shutil.move(final, target)
+ log_time('final emitting')
+
if DEBUG: logging.debug('total time: %.2f seconds' % (time.time() - start_time))
finally:
diff --git a/emscripten.py b/emscripten.py
index aeace63d..725f573f 100755
--- a/emscripten.py
+++ b/emscripten.py
@@ -725,7 +725,7 @@ def emscript_fast(infile, settings, outfile, libraries=[], compiler_engine=None,
outfile: The file where the output is written.
"""
- assert(settings['ASM_JS']) # TODO: apply ASM_JS even in -O0 for fastcomp
+ assert(settings['ASM_JS'])
# Overview:
# * Run LLVM backend to emit JS. JS includes function bodies, memory initializer,
diff --git a/src/library.js b/src/library.js
index 82aa5362..d2adbf24 100644
--- a/src/library.js
+++ b/src/library.js
@@ -100,7 +100,7 @@ LibraryManager.library = {
return FS.handleFSError(e);
}
if (stream.position < 0 || stream.position >= entries.length) {
- {{{ makeSetValue('result', '0', '0', 'i8*') }}}
+ {{{ makeSetValue('result', '0', '0', 'i8*') }}};
return 0;
}
var id;
@@ -118,15 +118,15 @@ LibraryManager.library = {
FS.isLink(child.mode) ? 10 : // DT_LNK, symbolic link.
8; // DT_REG, regular file.
}
- {{{ makeSetValue('entry', C_STRUCTS.dirent.d_ino, 'id', 'i32') }}}
- {{{ makeSetValue('entry', C_STRUCTS.dirent.d_off, 'offset', 'i32') }}}
- {{{ makeSetValue('entry', C_STRUCTS.dirent.d_reclen, 'name.length + 1', 'i32') }}}
+ {{{ makeSetValue('entry', C_STRUCTS.dirent.d_ino, 'id', 'i32') }}};
+ {{{ makeSetValue('entry', C_STRUCTS.dirent.d_off, 'offset', 'i32') }}};
+ {{{ makeSetValue('entry', C_STRUCTS.dirent.d_reclen, 'name.length + 1', 'i32') }}};
for (var i = 0; i < name.length; i++) {
- {{{ makeSetValue('entry + ' + C_STRUCTS.dirent.d_name, 'i', 'name.charCodeAt(i)', 'i8') }}}
+ {{{ makeSetValue('entry + ' + C_STRUCTS.dirent.d_name, 'i', 'name.charCodeAt(i)', 'i8') }}};
}
- {{{ makeSetValue('entry + ' + C_STRUCTS.dirent.d_name, 'i', '0', 'i8') }}}
- {{{ makeSetValue('entry', C_STRUCTS.dirent.d_type, 'type', 'i8') }}}
- {{{ makeSetValue('result', '0', 'entry', 'i8*') }}}
+ {{{ makeSetValue('entry + ' + C_STRUCTS.dirent.d_name, 'i', '0', 'i8') }}};
+ {{{ makeSetValue('entry', C_STRUCTS.dirent.d_type, 'type', 'i8') }}};
+ {{{ makeSetValue('result', '0', 'entry', 'i8*') }}};
stream.position++;
return 0;
},
@@ -205,13 +205,13 @@ LibraryManager.library = {
var length = i;
if (allSlashes) {
// All slashes result in a single slash.
- {{{ makeSetValue('path', '1', '0', 'i8') }}}
+ {{{ makeSetValue('path', '1', '0', 'i8') }}};
return [path, -1];
} else {
// Strip trailing slashes.
while (slashPositions.length &&
slashPositions[slashPositions.length - 1] == length - 1) {
- {{{ makeSetValue('path', 'slashPositions.pop(i)', '0', 'i8') }}}
+ {{{ makeSetValue('path', 'slashPositions.pop(i)', '0', 'i8') }}};
length--;
}
return [path, slashPositions.pop()];
@@ -232,9 +232,9 @@ LibraryManager.library = {
// http://pubs.opengroup.org/onlinepubs/007908799/xsh/dirname.html
var result = ___libgenSplitName(path);
if (result[1] == 0) {
- {{{ makeSetValue('result[0]', 1, '0', 'i8') }}}
+ {{{ makeSetValue('result[0]', 1, '0', 'i8') }}};
} else if (result[1] !== -1) {
- {{{ makeSetValue('result[0]', 'result[1]', '0', 'i8') }}}
+ {{{ makeSetValue('result[0]', 'result[1]', '0', 'i8') }}};
}
return result[0];
},
@@ -255,22 +255,22 @@ LibraryManager.library = {
{{{ makeSetValue('buf', C_STRUCTS.stat.st_dev, 'stat.dev', 'i32') }}};
{{{ makeSetValue('buf', C_STRUCTS.stat.__st_dev_padding, '0', 'i32') }}};
{{{ makeSetValue('buf', C_STRUCTS.stat.__st_ino_truncated, 'stat.ino', 'i32') }}};
- {{{ makeSetValue('buf', C_STRUCTS.stat.st_mode, 'stat.mode', 'i32') }}}
- {{{ makeSetValue('buf', C_STRUCTS.stat.st_nlink, 'stat.nlink', 'i32') }}}
- {{{ makeSetValue('buf', C_STRUCTS.stat.st_uid, 'stat.uid', 'i32') }}}
- {{{ makeSetValue('buf', C_STRUCTS.stat.st_gid, 'stat.gid', 'i32') }}}
- {{{ makeSetValue('buf', C_STRUCTS.stat.st_rdev, 'stat.rdev', 'i32') }}}
+ {{{ makeSetValue('buf', C_STRUCTS.stat.st_mode, 'stat.mode', 'i32') }}};
+ {{{ makeSetValue('buf', C_STRUCTS.stat.st_nlink, 'stat.nlink', 'i32') }}};
+ {{{ makeSetValue('buf', C_STRUCTS.stat.st_uid, 'stat.uid', 'i32') }}};
+ {{{ makeSetValue('buf', C_STRUCTS.stat.st_gid, 'stat.gid', 'i32') }}};
+ {{{ makeSetValue('buf', C_STRUCTS.stat.st_rdev, 'stat.rdev', 'i32') }}};
{{{ makeSetValue('buf', C_STRUCTS.stat.__st_rdev_padding, '0', 'i32') }}};
- {{{ makeSetValue('buf', C_STRUCTS.stat.st_size, 'stat.size', 'i32') }}}
- {{{ makeSetValue('buf', C_STRUCTS.stat.st_blksize, '4096', 'i32') }}}
- {{{ makeSetValue('buf', C_STRUCTS.stat.st_blocks, 'stat.blocks', 'i32') }}}
- {{{ makeSetValue('buf', C_STRUCTS.stat.st_atim.tv_sec, 'Math.floor(stat.atime.getTime() / 1000)', 'i32') }}}
- {{{ makeSetValue('buf', C_STRUCTS.stat.st_atim.tv_nsec, '0', 'i32') }}}
- {{{ makeSetValue('buf', C_STRUCTS.stat.st_mtim.tv_sec, 'Math.floor(stat.mtime.getTime() / 1000)', 'i32') }}}
- {{{ makeSetValue('buf', C_STRUCTS.stat.st_mtim.tv_nsec, '0', 'i32') }}}
- {{{ makeSetValue('buf', C_STRUCTS.stat.st_ctim.tv_sec, 'Math.floor(stat.ctime.getTime() / 1000)', 'i32') }}}
- {{{ makeSetValue('buf', C_STRUCTS.stat.st_ctim.tv_nsec, '0', 'i32') }}}
- {{{ makeSetValue('buf', C_STRUCTS.stat.st_ino, 'stat.ino', 'i32') }}}
+ {{{ makeSetValue('buf', C_STRUCTS.stat.st_size, 'stat.size', 'i32') }}};
+ {{{ makeSetValue('buf', C_STRUCTS.stat.st_blksize, '4096', 'i32') }}};
+ {{{ makeSetValue('buf', C_STRUCTS.stat.st_blocks, 'stat.blocks', 'i32') }}};
+ {{{ makeSetValue('buf', C_STRUCTS.stat.st_atim.tv_sec, 'Math.floor(stat.atime.getTime() / 1000)', 'i32') }}};
+ {{{ makeSetValue('buf', C_STRUCTS.stat.st_atim.tv_nsec, '0', 'i32') }}};
+ {{{ makeSetValue('buf', C_STRUCTS.stat.st_mtim.tv_sec, 'Math.floor(stat.mtime.getTime() / 1000)', 'i32') }}};
+ {{{ makeSetValue('buf', C_STRUCTS.stat.st_mtim.tv_nsec, '0', 'i32') }}};
+ {{{ makeSetValue('buf', C_STRUCTS.stat.st_ctim.tv_sec, 'Math.floor(stat.ctime.getTime() / 1000)', 'i32') }}};
+ {{{ makeSetValue('buf', C_STRUCTS.stat.st_ctim.tv_nsec, '0', 'i32') }}};
+ {{{ makeSetValue('buf', C_STRUCTS.stat.st_ino, 'stat.ino', 'i32') }}};
return 0;
} catch (e) {
FS.handleFSError(e);
@@ -407,17 +407,17 @@ LibraryManager.library = {
// int statvfs(const char *restrict path, struct statvfs *restrict buf);
// NOTE: None of the constants here are true. We're just returning safe and
// sane values.
- {{{ makeSetValue('buf', C_STRUCTS.statvfs.f_bsize, '4096', 'i32') }}}
- {{{ makeSetValue('buf', C_STRUCTS.statvfs.f_frsize, '4096', 'i32') }}}
- {{{ makeSetValue('buf', C_STRUCTS.statvfs.f_blocks, '1000000', 'i32') }}}
- {{{ makeSetValue('buf', C_STRUCTS.statvfs.f_bfree, '500000', 'i32') }}}
- {{{ makeSetValue('buf', C_STRUCTS.statvfs.f_bavail, '500000', 'i32') }}}
- {{{ makeSetValue('buf', C_STRUCTS.statvfs.f_files, 'FS.nextInode', 'i32') }}}
- {{{ makeSetValue('buf', C_STRUCTS.statvfs.f_ffree, '1000000', 'i32') }}}
- {{{ makeSetValue('buf', C_STRUCTS.statvfs.f_favail, '1000000', 'i32') }}}
- {{{ makeSetValue('buf', C_STRUCTS.statvfs.f_fsid, '42', 'i32') }}}
- {{{ makeSetValue('buf', C_STRUCTS.statvfs.f_flag, '2', 'i32') }}} // ST_NOSUID
- {{{ makeSetValue('buf', C_STRUCTS.statvfs.f_namemax, '255', 'i32') }}}
+ {{{ makeSetValue('buf', C_STRUCTS.statvfs.f_bsize, '4096', 'i32') }}};
+ {{{ makeSetValue('buf', C_STRUCTS.statvfs.f_frsize, '4096', 'i32') }}};
+ {{{ makeSetValue('buf', C_STRUCTS.statvfs.f_blocks, '1000000', 'i32') }}};
+ {{{ makeSetValue('buf', C_STRUCTS.statvfs.f_bfree, '500000', 'i32') }}};
+ {{{ makeSetValue('buf', C_STRUCTS.statvfs.f_bavail, '500000', 'i32') }}};
+ {{{ makeSetValue('buf', C_STRUCTS.statvfs.f_files, 'FS.nextInode', 'i32') }}};
+ {{{ makeSetValue('buf', C_STRUCTS.statvfs.f_ffree, '1000000', 'i32') }}};
+ {{{ makeSetValue('buf', C_STRUCTS.statvfs.f_favail, '1000000', 'i32') }}};
+ {{{ makeSetValue('buf', C_STRUCTS.statvfs.f_fsid, '42', 'i32') }}};
+ {{{ makeSetValue('buf', C_STRUCTS.statvfs.f_flag, '2', 'i32') }}}; // ST_NOSUID
+ {{{ makeSetValue('buf', C_STRUCTS.statvfs.f_namemax, '255', 'i32') }}};
return 0;
},
fstatvfs__deps: ['statvfs'],
@@ -506,7 +506,7 @@ LibraryManager.library = {
var arg = {{{ makeGetValue('varargs', 0, 'i32') }}};
var offset = {{{ C_STRUCTS.flock.l_type }}};
// We're always unlocked.
- {{{ makeSetValue('arg', 'offset', cDefine('F_UNLCK'), 'i16') }}}
+ {{{ makeSetValue('arg', 'offset', cDefine('F_UNLCK'), 'i16') }}};
return 0;
case {{{ cDefine('F_SETLK') }}}:
case {{{ cDefine('F_SETLKW') }}}:
@@ -585,7 +585,7 @@ LibraryManager.library = {
}
mask &= events | {{{ cDefine('POLLERR') }}} | {{{ cDefine('POLLHUP') }}};
if (mask) nonzero++;
- {{{ makeSetValue('pollfd', C_STRUCTS.pollfd.revents, 'mask', 'i16') }}}
+ {{{ makeSetValue('pollfd', C_STRUCTS.pollfd.revents, 'mask', 'i16') }}};
}
return nonzero;
},
@@ -1165,7 +1165,7 @@ LibraryManager.library = {
} else {
var length = Math.min(len, value.length);
for (var i = 0; i < length; i++) {
- {{{ makeSetValue('buf', 'i', 'value.charCodeAt(i)', 'i8') }}}
+ {{{ makeSetValue('buf', 'i', 'value.charCodeAt(i)', 'i8') }}};
}
if (len > length) {{{ makeSetValue('buf', 'i++', '0', 'i8') }}}
return i;
@@ -1214,9 +1214,9 @@ LibraryManager.library = {
// int getresuid(uid_t *ruid, uid_t *euid, uid_t *suid);
// http://linux.die.net/man/2/getresuid
// We have just one process/group/user, all with ID 0.
- {{{ makeSetValue('ruid', '0', '0', 'i32') }}}
- {{{ makeSetValue('euid', '0', '0', 'i32') }}}
- {{{ makeSetValue('suid', '0', '0', 'i32') }}}
+ {{{ makeSetValue('ruid', '0', '0', 'i32') }}};
+ {{{ makeSetValue('euid', '0', '0', 'i32') }}};
+ {{{ makeSetValue('suid', '0', '0', 'i32') }}};
return 0;
},
getresgid: 'getresuid',
@@ -1228,7 +1228,7 @@ LibraryManager.library = {
___setErrNo(ERRNO_CODES.EINVAL);
return -1;
} else {
- {{{ makeSetValue('grouplist', '0', '0', 'i32') }}}
+ {{{ makeSetValue('grouplist', '0', '0', 'i32') }}};
return 1;
}
},
@@ -1261,10 +1261,10 @@ LibraryManager.library = {
}
var length = Math.min(namelen, host.length);
for (var i = 0; i < length; i++) {
- {{{ makeSetValue('name', 'i', 'host.charCodeAt(i)', 'i8') }}}
+ {{{ makeSetValue('name', 'i', 'host.charCodeAt(i)', 'i8') }}};
}
if (namelen > length) {
- {{{ makeSetValue('name', 'i', '0', 'i8') }}}
+ {{{ makeSetValue('name', 'i', '0', 'i8') }}};
return 0;
} else {
___setErrNo(ERRNO_CODES.ENAMETOOLONG);
@@ -1381,8 +1381,8 @@ LibraryManager.library = {
for (var i = 0; i < nbytes; i += 2) {
var first = {{{ makeGetValue('src', 'i', 'i8') }}};
var second = {{{ makeGetValue('src', 'i + 1', 'i8') }}};
- {{{ makeSetValue('dest', 'i', 'second', 'i8') }}}
- {{{ makeSetValue('dest', 'i + 1', 'first', 'i8') }}}
+ {{{ makeSetValue('dest', 'i', 'second', 'i8') }}};
+ {{{ makeSetValue('dest', 'i + 1', 'first', 'i8') }}};
}
},
tcgetpgrp: function(fildes) {
@@ -1790,7 +1790,7 @@ LibraryManager.library = {
break;
case 'X':
case 'x':
- {{{ makeSetValue('argPtr', 0, 'parseInt(text, 16)', 'i32') }}}
+ {{{ makeSetValue('argPtr', 0, 'parseInt(text, 16)', 'i32') }}};
break;
case 'F':
case 'f':
@@ -1801,15 +1801,15 @@ LibraryManager.library = {
case 'E':
// fallthrough intended
if (long_) {
- {{{ makeSetValue('argPtr', 0, 'parseFloat(text)', 'double') }}}
+ {{{ makeSetValue('argPtr', 0, 'parseFloat(text)', 'double') }}};
} else {
- {{{ makeSetValue('argPtr', 0, 'parseFloat(text)', 'float') }}}
+ {{{ makeSetValue('argPtr', 0, 'parseFloat(text)', 'float') }}};
}
break;
case 's':
var array = intArrayFromString(text);
for (var j = 0; j < array.length; j++) {
- {{{ makeSetValue('argPtr', 'j', 'array[j]', 'i8') }}}
+ {{{ makeSetValue('argPtr', 'j', 'array[j]', 'i8') }}};
}
break;
}
@@ -2245,7 +2245,7 @@ LibraryManager.library = {
case 'n': {
// Write the length written so far to the next parameter.
var ptr = getNextArg('i32*');
- {{{ makeSetValue('ptr', '0', 'ret.length', 'i32') }}}
+ {{{ makeSetValue('ptr', '0', 'ret.length', 'i32') }}};
break;
}
case '%': {
@@ -2372,9 +2372,9 @@ LibraryManager.library = {
___setErrNo(ERRNO_CODES.ESPIPE);
return -1;
}
- {{{ makeSetValue('pos', '0', 'stream.position', 'i32') }}}
+ {{{ makeSetValue('pos', '0', 'stream.position', 'i32') }}};
var state = (stream.eof ? 1 : 0) + (stream.error ? 2 : 0);
- {{{ makeSetValue('pos', Runtime.getNativeTypeSize('i32'), 'state', 'i32') }}}
+ {{{ makeSetValue('pos', Runtime.getNativeTypeSize('i32'), 'state', 'i32') }}};
return 0;
},
fgets__deps: ['fgetc'],
@@ -2391,9 +2391,9 @@ LibraryManager.library = {
if (streamObj.error || (streamObj.eof && i == 0)) return 0;
else if (streamObj.eof) break;
}
- {{{ makeSetValue('s', 'i', 'byte_', 'i8') }}}
+ {{{ makeSetValue('s', 'i', 'byte_', 'i8') }}};
}
- {{{ makeSetValue('s', 'i', '0', 'i8') }}}
+ {{{ makeSetValue('s', 'i', '0', 'i8') }}};
return s;
},
gets__deps: ['fgets'],
@@ -2457,7 +2457,7 @@ LibraryManager.library = {
// int fputc(int c, FILE *stream);
// http://pubs.opengroup.org/onlinepubs/000095399/functions/fputc.html
var chr = unSign(c & 0xFF);
- {{{ makeSetValue('_fputc.ret', '0', 'chr', 'i8') }}}
+ {{{ makeSetValue('_fputc.ret', '0', 'chr', 'i8') }}};
var ret = _write(stream, _fputc.ret, 1);
if (ret == -1) {
var streamObj = FS.getStream(stream);
@@ -2511,7 +2511,7 @@ LibraryManager.library = {
return 0;
}
while (streamObj.ungotten.length && bytesToRead > 0) {
- {{{ makeSetValue('ptr++', '0', 'streamObj.ungotten.pop()', 'i8') }}}
+ {{{ makeSetValue('ptr++', '0', 'streamObj.ungotten.pop()', 'i8') }}};
bytesToRead--;
bytesRead++;
}
@@ -3127,7 +3127,7 @@ LibraryManager.library = {
// Set end pointer.
if (endptr) {
- {{{ makeSetValue('endptr', 0, 'str', '*') }}}
+ {{{ makeSetValue('endptr', 0, 'str', '*') }}};
}
// Unsign if needed.
@@ -3213,7 +3213,7 @@ LibraryManager.library = {
// Set end pointer.
if (endptr) {
- {{{ makeSetValue('endptr', 0, 'str', '*') }}}
+ {{{ makeSetValue('endptr', 0, 'str', '*') }}};
}
try {
@@ -3307,7 +3307,7 @@ LibraryManager.library = {
poolPtr = allocate(TOTAL_ENV_SIZE, 'i8', ALLOC_STATIC);
envPtr = allocate(MAX_ENV_VALUES * {{{ Runtime.QUANTUM_SIZE }}},
'i8*', ALLOC_STATIC);
- {{{ makeSetValue('envPtr', '0', 'poolPtr', 'i8*') }}}
+ {{{ makeSetValue('envPtr', '0', 'poolPtr', 'i8*') }}};
{{{ makeSetValue(makeGlobalUse('_environ'), 0, 'envPtr', 'i8*') }}};
} else {
envPtr = {{{ makeGetValue(makeGlobalUse('_environ'), '0', 'i8**') }}};
@@ -3431,7 +3431,7 @@ LibraryManager.library = {
var limit = Math.min(nelem, 3);
var doubleSize = {{{ Runtime.getNativeTypeSize('double') }}};
for (var i = 0; i < limit; i++) {
- {{{ makeSetValue('loadavg', 'i * doubleSize', '0.1', 'double') }}}
+ {{{ makeSetValue('loadavg', 'i * doubleSize', '0.1', 'double') }}};
}
return limit;
},
@@ -3460,9 +3460,9 @@ LibraryManager.library = {
} else {
var size = Math.min(4095, absolute.path.length); // PATH_MAX - 1.
for (var i = 0; i < size; i++) {
- {{{ makeSetValue('resolved_name', 'i', 'absolute.path.charCodeAt(i)', 'i8') }}}
+ {{{ makeSetValue('resolved_name', 'i', 'absolute.path.charCodeAt(i)', 'i8') }}};
}
- {{{ makeSetValue('resolved_name', 'size', '0', 'i8') }}}
+ {{{ makeSetValue('resolved_name', 'size', '0', 'i8') }}};
return resolved_name;
}
},
@@ -3670,7 +3670,7 @@ LibraryManager.library = {
var padding = 0, curr = 0, i = 0;
while ((i|0) < (num|0)) {
curr = padding ? 0 : {{{ makeGetValueAsm('psrc', 'i', 'i8') }}};
- {{{ makeSetValue('pdest', 'i', 'curr', 'i8') }}}
+ {{{ makeSetValue('pdest', 'i', 'curr', 'i8') }}};
padding = padding ? 1 : ({{{ makeGetValueAsm('psrc', 'i', 'i8') }}} == 0);
i = (i+1)|0;
}
@@ -3723,7 +3723,7 @@ LibraryManager.library = {
if ({{{ makeGetValue('pdest', 'len+i', 'i8') }}} == 0) break;
i ++;
if (i == num) {
- {{{ makeSetValue('pdest', 'len+i', 0, 'i8') }}}
+ {{{ makeSetValue('pdest', 'len+i', 0, 'i8') }}};
break;
}
}
@@ -4091,7 +4091,7 @@ LibraryManager.library = {
var i16size = {{{ Runtime.getNativeTypeSize('i16') }}};
var arr = _malloc(values.length * i16size);
for (var i = 0; i < values.length; i++) {
- {{{ makeSetValue('arr', 'i * i16size', 'values[i]', 'i16') }}}
+ {{{ makeSetValue('arr', 'i * i16size', 'values[i]', 'i16') }}};
}
me.ret = allocate([arr + 128 * i16size], 'i16*', ALLOC_NORMAL);
}
@@ -4119,7 +4119,7 @@ LibraryManager.library = {
var i32size = {{{ Runtime.getNativeTypeSize('i32') }}};
var arr = _malloc(values.length * i32size);
for (var i = 0; i < values.length; i++) {
- {{{ makeSetValue('arr', 'i * i32size', 'values[i]', 'i32') }}}
+ {{{ makeSetValue('arr', 'i * i32size', 'values[i]', 'i32') }}};
}
me.ret = allocate([arr + 128 * i32size], 'i32*', ALLOC_NORMAL);
}
@@ -4146,7 +4146,7 @@ LibraryManager.library = {
var i32size = {{{ Runtime.getNativeTypeSize('i32') }}};
var arr = _malloc(values.length * i32size);
for (var i = 0; i < values.length; i++) {
- {{{ makeSetValue('arr', 'i * i32size', 'values[i]', 'i32') }}}
+ {{{ makeSetValue('arr', 'i * i32size', 'values[i]', 'i32') }}};
}
me.ret = allocate([arr + 128 * i32size], 'i32*', ALLOC_NORMAL);
}
@@ -4348,9 +4348,9 @@ LibraryManager.library = {
#if EXCEPTION_DEBUG
Module.printErr('Compiled code throwing an exception, ' + [ptr,type,destructor] + ', at ' + stackTrace());
#endif
- {{{ makeSetValue('_llvm_eh_exception.buf', '0', 'ptr', 'void*') }}}
- {{{ makeSetValue('_llvm_eh_exception.buf', QUANTUM_SIZE, 'type', 'void*') }}}
- {{{ makeSetValue('_llvm_eh_exception.buf', 2 * QUANTUM_SIZE, 'destructor', 'void*') }}}
+ {{{ makeSetValue('_llvm_eh_exception.buf', '0', 'ptr', 'void*') }}};
+ {{{ makeSetValue('_llvm_eh_exception.buf', QUANTUM_SIZE, 'type', 'void*') }}};
+ {{{ makeSetValue('_llvm_eh_exception.buf', 2 * QUANTUM_SIZE, 'destructor', 'void*') }}};
if (!("uncaught_exception" in __ZSt18uncaught_exceptionv)) {
__ZSt18uncaught_exceptionv.uncaught_exception = 1;
} else {
@@ -4396,18 +4396,18 @@ LibraryManager.library = {
__THREW__ = 0;
#endif
// Clear type.
- {{{ makeSetValue('_llvm_eh_exception.buf', QUANTUM_SIZE, '0', 'void*') }}}
+ {{{ makeSetValue('_llvm_eh_exception.buf', QUANTUM_SIZE, '0', 'void*') }}};
// Call destructor if one is registered then clear it.
var ptr = {{{ makeGetValue('_llvm_eh_exception.buf', '0', 'void*') }}};
var destructor = {{{ makeGetValue('_llvm_eh_exception.buf', 2 * QUANTUM_SIZE, 'void*') }}};
if (destructor) {
Runtime.dynCall('vi', destructor, [ptr]);
- {{{ makeSetValue('_llvm_eh_exception.buf', 2 * QUANTUM_SIZE, '0', 'i32') }}}
+ {{{ makeSetValue('_llvm_eh_exception.buf', 2 * QUANTUM_SIZE, '0', 'i32') }}};
}
// Free ptr if it isn't null.
if (ptr) {
___cxa_free_exception(ptr);
- {{{ makeSetValue('_llvm_eh_exception.buf', '0', '0', 'void*') }}}
+ {{{ makeSetValue('_llvm_eh_exception.buf', '0', '0', 'void*') }}};
}
},
__cxa_get_exception_ptr__deps: ['llvm_eh_exception'],
@@ -4818,11 +4818,11 @@ LibraryManager.library = {
cbrtl: 'cbrt',
modf: function(x, intpart) {
- {{{ makeSetValue('intpart', 0, 'Math.floor(x)', 'double') }}}
+ {{{ makeSetValue('intpart', 0, 'Math.floor(x)', 'double') }}};
return x - {{{ makeGetValue('intpart', 0, 'double') }}};
},
modff: function(x, intpart) {
- {{{ makeSetValue('intpart', 0, 'Math.floor(x)', 'float') }}}
+ {{{ makeSetValue('intpart', 0, 'Math.floor(x)', 'float') }}};
return x - {{{ makeGetValue('intpart', 0, 'float') }}};
},
frexp: function(x, exp_addr) {
@@ -4838,7 +4838,7 @@ LibraryManager.library = {
if (exp_ === raw_exp) exp_ += 1;
sig = sign*x/Math.pow(2, exp_);
}
- {{{ makeSetValue('exp_addr', 0, 'exp_', 'i32') }}}
+ {{{ makeSetValue('exp_addr', 0, 'exp_', 'i32') }}};
return sig;
},
frexpf: 'frexp',
@@ -5346,7 +5346,7 @@ LibraryManager.library = {
time: function(ptr) {
var ret = Math.floor(Date.now()/1000);
if (ptr) {
- {{{ makeSetValue('ptr', 0, 'ret', 'i32') }}}
+ {{{ makeSetValue('ptr', 0, 'ret', 'i32') }}};
}
return ret;
},
@@ -5373,9 +5373,9 @@ LibraryManager.library = {
{{{ makeGetValue('tmPtr', C_STRUCTS.tm.tm_min, 'i32') }}},
{{{ makeGetValue('tmPtr', C_STRUCTS.tm.tm_sec, 'i32') }}},
0).getTime() / 1000;
- {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_wday, 'new Date(timestamp).getDay()', 'i32') }}}
+ {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_wday, 'new Date(timestamp).getDay()', 'i32') }}};
var yday = Math.round((timestamp - (new Date(year, 0, 1)).getTime()) / (1000 * 60 * 60 * 24));
- {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_yday, 'yday', 'i32') }}}
+ {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_yday, 'yday', 'i32') }}};
return timestamp;
},
timelocal: 'mktime',
@@ -5388,15 +5388,15 @@ LibraryManager.library = {
gmtime_r__deps: ['__tm_timezone'],
gmtime_r: function(time, tmPtr) {
var date = new Date({{{ makeGetValue('time', 0, 'i32') }}}*1000);
- {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_sec, 'date.getUTCSeconds()', 'i32') }}}
- {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_min, 'date.getUTCMinutes()', 'i32') }}}
- {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_hour, 'date.getUTCHours()', 'i32') }}}
- {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_mday, 'date.getUTCDate()', 'i32') }}}
- {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_mon, 'date.getUTCMonth()', 'i32') }}}
- {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_year, 'date.getUTCFullYear()-1900', 'i32') }}}
- {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_wday, 'date.getUTCDay()', 'i32') }}}
- {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_gmtoff, '0', 'i32') }}}
- {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_isdst, '0', 'i32') }}}
+ {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_sec, 'date.getUTCSeconds()', 'i32') }}};
+ {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_min, 'date.getUTCMinutes()', 'i32') }}};
+ {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_hour, 'date.getUTCHours()', 'i32') }}};
+ {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_mday, 'date.getUTCDate()', 'i32') }}};
+ {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_mon, 'date.getUTCMonth()', 'i32') }}};
+ {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_year, 'date.getUTCFullYear()-1900', 'i32') }}};
+ {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_wday, 'date.getUTCDay()', 'i32') }}};
+ {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_gmtoff, '0', 'i32') }}};
+ {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_isdst, '0', 'i32') }}};
var start = new Date(date); // define date using UTC, start from Jan 01 00:00:00 UTC
start.setUTCDate(1);
start.setUTCMonth(0);
@@ -5405,8 +5405,8 @@ LibraryManager.library = {
start.setUTCSeconds(0);
start.setUTCMilliseconds(0);
var yday = Math.floor((date.getTime() - start.getTime()) / (1000 * 60 * 60 * 24));
- {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_yday, 'yday', 'i32') }}}
- {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_zone, '___tm_timezone', 'i32') }}}
+ {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_yday, 'yday', 'i32') }}};
+ {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_zone, '___tm_timezone', 'i32') }}};
return tmPtr;
},
@@ -5429,23 +5429,23 @@ LibraryManager.library = {
localtime_r: function(time, tmPtr) {
_tzset();
var date = new Date({{{ makeGetValue('time', 0, 'i32') }}}*1000);
- {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_sec, 'date.getSeconds()', 'i32') }}}
- {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_min, 'date.getMinutes()', 'i32') }}}
- {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_hour, 'date.getHours()', 'i32') }}}
- {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_mday, 'date.getDate()', 'i32') }}}
- {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_mon, 'date.getMonth()', 'i32') }}}
- {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_year, 'date.getFullYear()-1900', 'i32') }}}
- {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_wday, 'date.getDay()', 'i32') }}}
+ {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_sec, 'date.getSeconds()', 'i32') }}};
+ {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_min, 'date.getMinutes()', 'i32') }}};
+ {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_hour, 'date.getHours()', 'i32') }}};
+ {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_mday, 'date.getDate()', 'i32') }}};
+ {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_mon, 'date.getMonth()', 'i32') }}};
+ {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_year, 'date.getFullYear()-1900', 'i32') }}};
+ {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_wday, 'date.getDay()', 'i32') }}};
var start = new Date(date.getFullYear(), 0, 1);
var yday = Math.floor((date.getTime() - start.getTime()) / (1000 * 60 * 60 * 24));
- {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_yday, 'yday', 'i32') }}}
- {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_gmtoff, 'start.getTimezoneOffset() * 60', 'i32') }}}
+ {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_yday, 'yday', 'i32') }}};
+ {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_gmtoff, 'start.getTimezoneOffset() * 60', 'i32') }}};
var dst = Number(start.getTimezoneOffset() != date.getTimezoneOffset());
- {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_isdst, 'dst', 'i32') }}}
+ {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_isdst, 'dst', 'i32') }}};
- {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_zone, '___tm_timezone', 'i32') }}}
+ {{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_zone, '___tm_timezone', 'i32') }}};
return tmPtr;
},
@@ -5463,9 +5463,9 @@ LibraryManager.library = {
var timePart = formatted.match(/\d{2}:\d{2}:\d{2}/)[0];
formatted = datePart + timePart + ' ' + date.getFullYear() + '\n';
formatted.split('').forEach(function(chr, index) {
- {{{ makeSetValue('buf', 'index', 'chr.charCodeAt(0)', 'i8') }}}
+ {{{ makeSetValue('buf', 'index', 'chr.charCodeAt(0)', 'i8') }}};
});
- {{{ makeSetValue('buf', '25', '0', 'i8') }}}
+ {{{ makeSetValue('buf', '25', '0', 'i8') }}};
return buf;
},
@@ -5495,18 +5495,18 @@ LibraryManager.library = {
if (_tzset.called) return;
_tzset.called = true;
- {{{ makeSetValue(makeGlobalUse('_timezone'), '0', '-(new Date()).getTimezoneOffset() * 60', 'i32') }}}
+ {{{ makeSetValue(makeGlobalUse('_timezone'), '0', '-(new Date()).getTimezoneOffset() * 60', 'i32') }}};
var winter = new Date(2000, 0, 1);
var summer = new Date(2000, 6, 1);
- {{{ makeSetValue(makeGlobalUse('_daylight'), '0', 'Number(winter.getTimezoneOffset() != summer.getTimezoneOffset())', 'i32') }}}
+ {{{ makeSetValue(makeGlobalUse('_daylight'), '0', 'Number(winter.getTimezoneOffset() != summer.getTimezoneOffset())', 'i32') }}};
var winterName = 'GMT'; // XXX do not rely on browser timezone info, it is very unpredictable | winter.toString().match(/\(([A-Z]+)\)/)[1];
var summerName = 'GMT'; // XXX do not rely on browser timezone info, it is very unpredictable | summer.toString().match(/\(([A-Z]+)\)/)[1];
var winterNamePtr = allocate(intArrayFromString(winterName), 'i8', ALLOC_NORMAL);
var summerNamePtr = allocate(intArrayFromString(summerName), 'i8', ALLOC_NORMAL);
- {{{ makeSetValue(makeGlobalUse('_tzname'), '0', 'winterNamePtr', 'i32') }}}
- {{{ makeSetValue(makeGlobalUse('_tzname'), Runtime.QUANTUM_SIZE, 'summerNamePtr', 'i32') }}}
+ {{{ makeSetValue(makeGlobalUse('_tzname'), '0', 'winterNamePtr', 'i32') }}};
+ {{{ makeSetValue(makeGlobalUse('_tzname'), Runtime.QUANTUM_SIZE, 'summerNamePtr', 'i32') }}};
},
stime__deps: ['$ERRNO_CODES', '__setErrNo'],
@@ -6076,15 +6076,15 @@ LibraryManager.library = {
*/
var fullDate = new Date(date.year, date.month, date.day, date.hour, date.min, date.sec, 0);
- {{{ makeSetValue('tm', C_STRUCTS.tm.tm_sec, 'fullDate.getSeconds()', 'i32') }}}
- {{{ makeSetValue('tm', C_STRUCTS.tm.tm_min, 'fullDate.getMinutes()', 'i32') }}}
- {{{ makeSetValue('tm', C_STRUCTS.tm.tm_hour, 'fullDate.getHours()', 'i32') }}}
- {{{ makeSetValue('tm', C_STRUCTS.tm.tm_mday, 'fullDate.getDate()', 'i32') }}}
- {{{ makeSetValue('tm', C_STRUCTS.tm.tm_mon, 'fullDate.getMonth()', 'i32') }}}
- {{{ makeSetValue('tm', C_STRUCTS.tm.tm_year, 'fullDate.getFullYear()-1900', 'i32') }}}
- {{{ makeSetValue('tm', C_STRUCTS.tm.tm_wday, 'fullDate.getDay()', 'i32') }}}
- {{{ makeSetValue('tm', C_STRUCTS.tm.tm_yday, '__arraySum(__isLeapYear(fullDate.getFullYear()) ? __MONTH_DAYS_LEAP : __MONTH_DAYS_REGULAR, fullDate.getMonth()-1)+fullDate.getDate()-1', 'i32') }}}
- {{{ makeSetValue('tm', C_STRUCTS.tm.tm_isdst, '0', 'i32') }}}
+ {{{ makeSetValue('tm', C_STRUCTS.tm.tm_sec, 'fullDate.getSeconds()', 'i32') }}};
+ {{{ makeSetValue('tm', C_STRUCTS.tm.tm_min, 'fullDate.getMinutes()', 'i32') }}};
+ {{{ makeSetValue('tm', C_STRUCTS.tm.tm_hour, 'fullDate.getHours()', 'i32') }}};
+ {{{ makeSetValue('tm', C_STRUCTS.tm.tm_mday, 'fullDate.getDate()', 'i32') }}};
+ {{{ makeSetValue('tm', C_STRUCTS.tm.tm_mon, 'fullDate.getMonth()', 'i32') }}};
+ {{{ makeSetValue('tm', C_STRUCTS.tm.tm_year, 'fullDate.getFullYear()-1900', 'i32') }}};
+ {{{ makeSetValue('tm', C_STRUCTS.tm.tm_wday, 'fullDate.getDay()', 'i32') }}};
+ {{{ makeSetValue('tm', C_STRUCTS.tm.tm_yday, '__arraySum(__isLeapYear(fullDate.getFullYear()) ? __MONTH_DAYS_LEAP : __MONTH_DAYS_REGULAR, fullDate.getMonth()-1)+fullDate.getDate()-1', 'i32') }}};
+ {{{ makeSetValue('tm', C_STRUCTS.tm.tm_isdst, '0', 'i32') }}};
// we need to convert the matched sequence into an integer array to take care of UTF-8 characters > 0x7F
// TODO: not sure that intArrayFromString handles all unicode characters correctly
@@ -6115,8 +6115,8 @@ LibraryManager.library = {
var seconds = {{{ makeGetValue('rqtp', C_STRUCTS.timespec.tv_sec, 'i32') }}};
var nanoseconds = {{{ makeGetValue('rqtp', C_STRUCTS.timespec.tv_nsec, 'i32') }}};
if (rmtp !== 0) {
- {{{ makeSetValue('rmtp', C_STRUCTS.timespec.tv_sec, '0', 'i32') }}}
- {{{ makeSetValue('rmtp', C_STRUCTS.timespec.tv_nsec, '0', 'i32') }}}
+ {{{ makeSetValue('rmtp', C_STRUCTS.timespec.tv_sec, '0', 'i32') }}};
+ {{{ makeSetValue('rmtp', C_STRUCTS.timespec.tv_nsec, '0', 'i32') }}};
}
return _usleep((seconds * 1e6) + (nanoseconds / 1000));
},
@@ -6147,7 +6147,7 @@ LibraryManager.library = {
} else {
nsec = _emscripten_get_now_res();
}
- {{{ makeSetValue('res', C_STRUCTS.timespec.tv_sec, '1', 'i32') }}}
+ {{{ makeSetValue('res', C_STRUCTS.timespec.tv_sec, '1', 'i32') }}};
{{{ makeSetValue('res', C_STRUCTS.timespec.tv_nsec, 'nsec', 'i32') }}} // resolution is milliseconds
return 0;
},
@@ -6828,7 +6828,7 @@ LibraryManager.library = {
__setErrNo__postset: '___errno_state = Runtime.staticAlloc(4); {{{ makeSetValue("___errno_state", 0, 0, "i32") }}};',
__setErrNo: function(value) {
// For convenient setting and returning of errno.
- {{{ makeSetValue('___errno_state', '0', 'value', 'i32') }}}
+ {{{ makeSetValue('___errno_state', '0', 'value', 'i32') }}};
return value;
},
__errno_location__deps: ['__setErrNo'],
@@ -6856,10 +6856,10 @@ LibraryManager.library = {
// TODO: Implement for real. We just do time used, and no useful data
getrusage: function(resource, rlp) {
// int getrusage(int resource, struct rusage *rlp);
- {{{ makeSetValue('rlp', C_STRUCTS.rusage.ru_utime.tv_sec, '1', 'i32') }}}
- {{{ makeSetValue('rlp', C_STRUCTS.rusage.ru_utime.tv_usec, '2', 'i32') }}}
- {{{ makeSetValue('rlp', C_STRUCTS.rusage.ru_stime.tv_sec, '3', 'i32') }}}
- {{{ makeSetValue('rlp', C_STRUCTS.rusage.ru_stime.tv_usec, '4', 'i32') }}}
+ {{{ makeSetValue('rlp', C_STRUCTS.rusage.ru_utime.tv_sec, '1', 'i32') }}};
+ {{{ makeSetValue('rlp', C_STRUCTS.rusage.ru_utime.tv_usec, '2', 'i32') }}};
+ {{{ makeSetValue('rlp', C_STRUCTS.rusage.ru_stime.tv_sec, '3', 'i32') }}};
+ {{{ makeSetValue('rlp', C_STRUCTS.rusage.ru_stime.tv_usec, '4', 'i32') }}};
return 0;
},
@@ -6923,8 +6923,8 @@ LibraryManager.library = {
void **restrict stackaddr, size_t *restrict stacksize); */
/*FIXME: assumes that there is only one thread, and that attr is the
current thread*/
- {{{ makeSetValue('stackaddr', '0', 'STACK_BASE', 'i8*') }}}
- {{{ makeSetValue('stacksize', '0', 'TOTAL_STACK', 'i32') }}}
+ {{{ makeSetValue('stackaddr', '0', 'STACK_BASE', 'i8*') }}};
+ {{{ makeSetValue('stacksize', '0', 'TOTAL_STACK', 'i32') }}};
return 0;
},
@@ -6942,7 +6942,7 @@ LibraryManager.library = {
if (key == 0) {
return ERRNO_CODES.EINVAL;
}
- {{{ makeSetValue('key', '0', 'PTHREAD_SPECIFIC_NEXT_KEY', 'i32*') }}}
+ {{{ makeSetValue('key', '0', 'PTHREAD_SPECIFIC_NEXT_KEY', 'i32*') }}};
// values start at 0
PTHREAD_SPECIFIC[PTHREAD_SPECIFIC_NEXT_KEY] = 0;
PTHREAD_SPECIFIC_NEXT_KEY++;
@@ -7000,7 +7000,7 @@ LibraryManager.library = {
posix_memalign__deps: ['memalign'],
posix_memalign: function(memptr, alignment, size) {
var ptr = _memalign(alignment, size);
- {{{ makeSetValue('memptr', '0', 'ptr', 'i8*') }}}
+ {{{ makeSetValue('memptr', '0', 'ptr', 'i8*') }}};
return 0;
},
@@ -7042,7 +7042,7 @@ LibraryManager.library = {
if (addr === null) {
return 0;
}
- {{{ makeSetValue('inp', '0', 'addr', 'i32') }}}
+ {{{ makeSetValue('inp', '0', 'addr', 'i32') }}};
return 1;
},
@@ -7201,7 +7201,7 @@ LibraryManager.library = {
if (ret === null) {
return 0;
}
- {{{ makeSetValue('dst', '0', 'ret', 'i32') }}}
+ {{{ makeSetValue('dst', '0', 'ret', 'i32') }}};
return 1;
},
_inet_pton6_raw__deps: ['htons'],
@@ -7406,18 +7406,18 @@ LibraryManager.library = {
var ret = _malloc({{{ C_STRUCTS.hostent.__size__ }}}); // XXX possibly leaked, as are others here
var nameBuf = _malloc(name.length+1);
writeStringToMemory(name, nameBuf);
- {{{ makeSetValue('ret', C_STRUCTS.hostent.h_name, 'nameBuf', 'i8*') }}}
+ {{{ makeSetValue('ret', C_STRUCTS.hostent.h_name, 'nameBuf', 'i8*') }}};
var aliasesBuf = _malloc(4);
- {{{ makeSetValue('aliasesBuf', '0', '0', 'i8*') }}}
- {{{ makeSetValue('ret', C_STRUCTS.hostent.h_aliases, 'aliasesBuf', 'i8**') }}}
+ {{{ makeSetValue('aliasesBuf', '0', '0', 'i8*') }}};
+ {{{ makeSetValue('ret', C_STRUCTS.hostent.h_aliases, 'aliasesBuf', 'i8**') }}};
var afinet = {{{ cDefine('AF_INET') }}};
- {{{ makeSetValue('ret', C_STRUCTS.hostent.h_addrtype, 'afinet', 'i32') }}}
- {{{ makeSetValue('ret', C_STRUCTS.hostent.h_length, '4', 'i32') }}}
+ {{{ makeSetValue('ret', C_STRUCTS.hostent.h_addrtype, 'afinet', 'i32') }}};
+ {{{ makeSetValue('ret', C_STRUCTS.hostent.h_length, '4', 'i32') }}};
var addrListBuf = _malloc(12);
- {{{ makeSetValue('addrListBuf', '0', 'addrListBuf+8', 'i32*') }}}
- {{{ makeSetValue('addrListBuf', '4', '0', 'i32*') }}}
- {{{ makeSetValue('addrListBuf', '8', '__inet_pton4_raw(DNS.lookup_name(name))', 'i32') }}}
- {{{ makeSetValue('ret', C_STRUCTS.hostent.h_addr_list, 'addrListBuf', 'i8**') }}}
+ {{{ makeSetValue('addrListBuf', '0', 'addrListBuf+8', 'i32*') }}};
+ {{{ makeSetValue('addrListBuf', '4', '0', 'i32*') }}};
+ {{{ makeSetValue('addrListBuf', '8', '__inet_pton4_raw(DNS.lookup_name(name))', 'i32') }}};
+ {{{ makeSetValue('ret', C_STRUCTS.hostent.h_addr_list, 'addrListBuf', 'i8**') }}};
return ret;
},
diff --git a/src/library_sdl.js b/src/library_sdl.js
index fc38dd1c..5a111289 100644
--- a/src/library_sdl.js
+++ b/src/library_sdl.js
@@ -232,17 +232,17 @@ var LibrarySDL = {
{{{ makeSetValue('surf', C_STRUCTS.SDL_Surface.pixels, 'buffer', 'void*') }}} // SDL_Surface.pixels
{{{ makeSetValue('surf', C_STRUCTS.SDL_Surface.clip_rect, '0', 'i32*') }}} // SDL_Surface.offset
- {{{ makeSetValue('surf', C_STRUCTS.SDL_Surface.refcount, '1', 'i32') }}}
+ {{{ makeSetValue('surf', C_STRUCTS.SDL_Surface.refcount, '1', 'i32') }}};
{{{ makeSetValue('pixelFormat', C_STRUCTS.SDL_PixelFormat.format, cDefine('SDL_PIXELFORMAT_RGBA8888'), 'i32') }}} // SDL_PIXELFORMAT_RGBA8888
{{{ makeSetValue('pixelFormat', C_STRUCTS.SDL_PixelFormat.palette, '0', 'i32') }}} // TODO
- {{{ makeSetValue('pixelFormat', C_STRUCTS.SDL_PixelFormat.BitsPerPixel, 'bpp * 8', 'i8') }}}
- {{{ makeSetValue('pixelFormat', C_STRUCTS.SDL_PixelFormat.BytesPerPixel, 'bpp', 'i8') }}}
+ {{{ makeSetValue('pixelFormat', C_STRUCTS.SDL_PixelFormat.BitsPerPixel, 'bpp * 8', 'i8') }}};
+ {{{ makeSetValue('pixelFormat', C_STRUCTS.SDL_PixelFormat.BytesPerPixel, 'bpp', 'i8') }}};
- {{{ makeSetValue('pixelFormat', C_STRUCTS.SDL_PixelFormat.Rmask, 'rmask || 0x000000ff', 'i32') }}}
- {{{ makeSetValue('pixelFormat', C_STRUCTS.SDL_PixelFormat.Gmask, 'gmask || 0x0000ff00', 'i32') }}}
- {{{ makeSetValue('pixelFormat', C_STRUCTS.SDL_PixelFormat.Bmask, 'bmask || 0x00ff0000', 'i32') }}}
- {{{ makeSetValue('pixelFormat', C_STRUCTS.SDL_PixelFormat.Amask, 'amask || 0xff000000', 'i32') }}}
+ {{{ makeSetValue('pixelFormat', C_STRUCTS.SDL_PixelFormat.Rmask, 'rmask || 0x000000ff', 'i32') }}};
+ {{{ makeSetValue('pixelFormat', C_STRUCTS.SDL_PixelFormat.Gmask, 'gmask || 0x0000ff00', 'i32') }}};
+ {{{ makeSetValue('pixelFormat', C_STRUCTS.SDL_PixelFormat.Bmask, 'bmask || 0x00ff0000', 'i32') }}};
+ {{{ makeSetValue('pixelFormat', C_STRUCTS.SDL_PixelFormat.Amask, 'amask || 0xff000000', 'i32') }}};
// Decide if we want to use WebGL or not
var useWebGL = (flags & 0x04000000) != 0; // SDL_OPENGL
@@ -592,19 +592,19 @@ var LibrarySDL = {
scan = SDL.scanCodes[key] || key;
}
- {{{ makeSetValue('ptr', C_STRUCTS.SDL_KeyboardEvent.type, 'SDL.DOMEventToSDLEvent[event.type]', 'i32') }}}
- {{{ makeSetValue('ptr', C_STRUCTS.SDL_KeyboardEvent.state, 'down ? 1 : 0', 'i8') }}}
+ {{{ makeSetValue('ptr', C_STRUCTS.SDL_KeyboardEvent.type, 'SDL.DOMEventToSDLEvent[event.type]', 'i32') }}};
+ {{{ makeSetValue('ptr', C_STRUCTS.SDL_KeyboardEvent.state, 'down ? 1 : 0', 'i8') }}};
{{{ makeSetValue('ptr', C_STRUCTS.SDL_KeyboardEvent.repeat, '0', 'i8') }}} // TODO
- {{{ makeSetValue('ptr', C_STRUCTS.SDL_KeyboardEvent.keysym + C_STRUCTS.SDL_Keysym.scancode, 'scan', 'i32') }}}
- {{{ makeSetValue('ptr', C_STRUCTS.SDL_KeyboardEvent.keysym + C_STRUCTS.SDL_Keysym.sym, 'key', 'i32') }}}
- {{{ makeSetValue('ptr', C_STRUCTS.SDL_KeyboardEvent.keysym + C_STRUCTS.SDL_Keysym.mod, 'SDL.modState', 'i16') }}}
+ {{{ makeSetValue('ptr', C_STRUCTS.SDL_KeyboardEvent.keysym + C_STRUCTS.SDL_Keysym.scancode, 'scan', 'i32') }}};
+ {{{ makeSetValue('ptr', C_STRUCTS.SDL_KeyboardEvent.keysym + C_STRUCTS.SDL_Keysym.sym, 'key', 'i32') }}};
+ {{{ makeSetValue('ptr', C_STRUCTS.SDL_KeyboardEvent.keysym + C_STRUCTS.SDL_Keysym.mod, 'SDL.modState', 'i16') }}};
// some non-character keys (e.g. backspace and tab) won't have keypressCharCode set, fill in with the keyCode.
- {{{ makeSetValue('ptr', C_STRUCTS.SDL_KeyboardEvent.keysym + C_STRUCTS.SDL_Keysym.unicode, 'event.keypressCharCode || key', 'i32') }}}
+ {{{ makeSetValue('ptr', C_STRUCTS.SDL_KeyboardEvent.keysym + C_STRUCTS.SDL_Keysym.unicode, 'event.keypressCharCode || key', 'i32') }}};
break;
}
case 'keypress': {
- {{{ makeSetValue('ptr', C_STRUCTS.SDL_TextInputEvent.type, 'SDL.DOMEventToSDLEvent[event.type]', 'i32') }}}
+ {{{ makeSetValue('ptr', C_STRUCTS.SDL_TextInputEvent.type, 'SDL.DOMEventToSDLEvent[event.type]', 'i32') }}};
// Not filling in windowID for now
var cStr = intArrayFromString(String.fromCharCode(event.charCode));
for (var i = 0; i < cStr.length; ++i) {
@@ -819,9 +819,9 @@ var LibrarySDL = {
SDL_Linked_Version: function() {
if (SDL.version === null) {
SDL.version = _malloc({{{ C_STRUCTS.SDL_version.__size__ }}});
- {{{ makeSetValue('SDL.version + ' + C_STRUCTS.SDL_version.major, '0', '1', 'i8') }}}
- {{{ makeSetValue('SDL.version + ' + C_STRUCTS.SDL_version.minor, '0', '3', 'i8') }}}
- {{{ makeSetValue('SDL.version + ' + C_STRUCTS.SDL_version.patch, '0', '0', 'i8') }}}
+ {{{ makeSetValue('SDL.version + ' + C_STRUCTS.SDL_version.major, '0', '1', 'i8') }}};
+ {{{ makeSetValue('SDL.version + ' + C_STRUCTS.SDL_version.minor, '0', '3', 'i8') }}};
+ {{{ makeSetValue('SDL.version + ' + C_STRUCTS.SDL_version.patch, '0', '0', 'i8') }}};
}
return SDL.version;
},
@@ -881,9 +881,9 @@ var LibrarySDL = {
var ret = _malloc(5*Runtime.QUANTUM_SIZE);
{{{ makeSetValue('ret+Runtime.QUANTUM_SIZE*0', '0', '0', 'i32') }}} // TODO
{{{ makeSetValue('ret+Runtime.QUANTUM_SIZE*1', '0', '0', 'i32') }}} // TODO
- {{{ makeSetValue('ret+Runtime.QUANTUM_SIZE*2', '0', '0', 'void*') }}}
- {{{ makeSetValue('ret+Runtime.QUANTUM_SIZE*3', '0', 'Module["canvas"].width', 'i32') }}}
- {{{ makeSetValue('ret+Runtime.QUANTUM_SIZE*4', '0', 'Module["canvas"].height', 'i32') }}}
+ {{{ makeSetValue('ret+Runtime.QUANTUM_SIZE*2', '0', '0', 'void*') }}};
+ {{{ makeSetValue('ret+Runtime.QUANTUM_SIZE*3', '0', 'Module["canvas"].width', 'i32') }}};
+ {{{ makeSetValue('ret+Runtime.QUANTUM_SIZE*4', '0', 'Module["canvas"].height', 'i32') }}};
return ret;
},
diff --git a/src/parseTools.js b/src/parseTools.js
index 036ccfc1..1c70a018 100644
--- a/src/parseTools.js
+++ b/src/parseTools.js
@@ -1328,7 +1328,7 @@ function makeGetValue(ptr, pos, type, noNeedFirst, unsigned, ignore, align, noSa
if (printType !== 'null' && printType[0] !== '#') printType = '"' + safeQuote(printType) + '"';
if (printType[0] === '#') printType = printType.substr(1);
if (ASM_JS) {
- if (!ignore) return asmCoercion('SAFE_HEAP_LOAD(' + asmCoercion(offset, 'i32') + ', ' + Runtime.getNativeTypeSize(type) + ', ' + ((type in Runtime.FLOAT_TYPES)|0) + ')', type);
+ if (!ignore) return asmCoercion('SAFE_HEAP_LOAD(' + asmCoercion(offset, 'i32') + ', ' + Runtime.getNativeTypeSize(type) + ', ' + ((type in Runtime.FLOAT_TYPES)|0) + ', ' + (!!unsigned+0) + ')', type);
// else fall through
} else {
return asmCoercion('SAFE_HEAP_LOAD(' + offset + ', ' + (ASM_JS ? 0 : printType) + ', ' + (!!unsigned+0) + ', ' + ((!checkSafeHeap() || ignore)|0) + ')', type);
@@ -1789,31 +1789,12 @@ function makePointer(slab, pos, allocator, type, ptr, finalMemoryInitialization)
types = 'i8';
}
- // JS engines sometimes say array initializers are too large. Work around that by chunking and calling concat to combine at runtime
- var chunkSize = JS_CHUNK_SIZE;
- function chunkify(array) {
- // break very large slabs into parts
- var ret = '';
- var index = 0;
- while (index < array.length) {
- ret = (ret ? ret + '.concat(' : '') + '[' + array.slice(index, index + chunkSize).map(JSON.stringify) + ']' + (ret ? ')\n' : '');
- index += chunkSize;
- }
- return ret;
- }
- if (typeof slab == 'object' && slab.length > chunkSize) {
- slab = chunkify(slab);
- }
if (typeof types == 'object') {
while (types.length < slab.length) types.push(0);
}
- if (typeof types != 'string' && types.length > chunkSize) {
- types = chunkify(types);
- } else {
- types = JSON.stringify(types);
- }
+ types = JSON.stringify(types);
if (typeof slab == 'object') slab = '[' + slab.join(',') + ']';
- return 'allocate(' + slab + ', ' + types + (allocator ? ', ' + allocator : '') + (allocator == 'ALLOC_NONE' ? ', ' + ptr : '') + ')';
+ return 'allocate(' + slab + ', ' + types + (allocator ? ', ' + allocator : '') + (allocator == 'ALLOC_NONE' ? ', ' + ptr : '') + ');';
}
function makeGetSlabs(ptr, type, allowMultiple, unsigned) {
diff --git a/src/preamble.js b/src/preamble.js
index d70ef4b1..d415b87e 100644
--- a/src/preamble.js
+++ b/src/preamble.js
@@ -189,13 +189,16 @@ function SAFE_HEAP_STORE(dest, value, bytes, isFloat) {
setValue(dest, value, getSafeHeapType(bytes, isFloat), 1);
}
-function SAFE_HEAP_LOAD(dest, bytes, isFloat) {
+function SAFE_HEAP_LOAD(dest, bytes, isFloat, unsigned) {
#if SAFE_HEAP_LOG
- Module.print('SAFE_HEAP load: ' + [dest, bytes, isFloat]);
+ Module.print('SAFE_HEAP load: ' + [dest, bytes, isFloat, unsigned]);
#endif
assert(dest > 0, 'segmentation fault');
assert(dest % bytes === 0);
- return getValue(dest, getSafeHeapType(bytes, isFloat), 1);
+ var type = getSafeHeapType(bytes, isFloat);
+ var ret = getValue(dest, type, 1);
+ if (unsigned) ret = unSign(ret, parseInt(type.substr(1)), 1);
+ return ret;
}
#endif
diff --git a/tests/test_benchmark.py b/tests/test_benchmark.py
index 21a47178..729512f3 100644
--- a/tests/test_benchmark.py
+++ b/tests/test_benchmark.py
@@ -472,7 +472,7 @@ class benchmark(RunnerCore):
def lua(self, benchmark, expected, output_parser=None, args_processor=None):
shutil.copyfile(path_from_root('tests', 'lua', benchmark + '.lua'), benchmark + '.lua')
def lib_builder(name, native, env_init):
- ret = self.get_library('lua', [os.path.join('src', 'lua'), os.path.join('src', 'liblua.a')], make=['make', 'generic'], configure=None, native=native, cache_name_extra=name, env_init=env_init)
+ ret = self.get_library('lua_native' if native else 'lua', [os.path.join('src', 'lua'), os.path.join('src', 'liblua.a')], make=['make', 'generic'], configure=None, native=native, cache_name_extra=name, env_init=env_init)
if native: return ret
shutil.copyfile(ret[0], ret[0] + '.bc')
ret[0] += '.bc'
diff --git a/tests/test_core.py b/tests/test_core.py
index 5aab48f5..f5d18e45 100644
--- a/tests/test_core.py
+++ b/tests/test_core.py
@@ -3706,6 +3706,7 @@ ok
self.do_run_from_file(src, output)
def test_fnmatch(self):
+ if self.emcc_args is None: return self.skip('requires linking in libc++')
test_path = path_from_root('tests', 'core', 'fnmatch')
src, output = (test_path + s for s in ('.c', '.out'))
self.do_run_from_file(src, output)
@@ -4627,6 +4628,7 @@ return malloc(size);
assert 'asm1' in test_modes
if self.run_name == 'asm1':
generated = open('src.cpp.o.js').read()
+ generated = re.sub(r'\n+[ \n]*\n+', '\n', generated)
main = generated[generated.find('function runPostSets'):]
main = main[:main.find('\n}')]
assert main.count('\n') == 7, 'must not emit too many postSets: %d' % main.count('\n')
@@ -5008,7 +5010,9 @@ def process(filename):
def clean(text):
text = text.replace('\n\n', '\n').replace('\n\n', '\n').replace('\n\n', '\n').replace('\n\n', '\n').replace('\n\n', '\n').replace('{\n}', '{}')
return '\n'.join(sorted(text.split('\n')))
- self.assertIdentical(clean(open('release.js').read()), clean(open('debug%d.js' % debug).read())) # EMCC_DEBUG=1 mode must not generate different code!
+ sizes = len(open('release.js').read()), len(open('debug%d.js' % debug).read())
+ print >> sys.stderr, debug, 'sizes', sizes
+ assert abs(sizes[0] - sizes[1]) < 0.0001*sizes[0] # we can't check on identical output, compilation is not 100% deterministic (order of switch elements, etc.), but size should be ~identical
print >> sys.stderr, 'debug check %d passed too' % debug
try:
@@ -6055,6 +6059,7 @@ def process(filename):
# optimizer can deal with both types.
out_file = re.sub(' *//@.*$', '', out_file, flags=re.MULTILINE)
def clean(code):
+ code = re.sub(r'\n+[ \n]*\n+', '\n', code)
code = code.replace('{\n}', '{}')
return '\n'.join(sorted(code.split('\n')))
self.assertIdentical(clean(no_maps_file), clean(out_file))
diff --git a/tests/test_other.py b/tests/test_other.py
index b2fc4cf6..f69eced2 100644
--- a/tests/test_other.py
+++ b/tests/test_other.py
@@ -284,9 +284,33 @@ f.close()
if WINDOWS:
generators = ['MinGW Makefiles', 'NMake Makefiles']
else:
- generators = ['Unix Makefiles']
-
- make_commands = { 'MinGW Makefiles': ['mingw32-make'], 'NMake Makefiles': ['nmake', '/NOLOGO'], 'Unix Makefiles': ['make'] }
+ generators = ['Unix Makefiles', 'Ninja', 'Eclipse CDT4 - Ninja']
+
+ def nmake_detect_error(configuration):
+ if Building.which(configuration['build'][0]):
+ return None
+ else:
+ return 'Skipping NMake test for CMake support, since nmake was not found in PATH. Run this test in Visual Studio command prompt to easily access nmake.'
+
+ def check_makefile(configuration, dirname):
+ assert os.path.exists(dirname + '/Makefile'), 'CMake call did not produce a Makefile!'
+
+ configurations = { 'MinGW Makefiles' : { 'prebuild': check_makefile,
+ 'build' : ['mingw32-make'],
+
+ },
+ 'NMake Makefiles' : { 'detect' : nmake_detect_error,
+ 'prebuild': check_makefile,
+ 'build' : ['nmake', '/NOLOGO'],
+ },
+ 'Unix Makefiles' : { 'prebuild': check_makefile,
+ 'build' : ['make'],
+ },
+ 'Ninja' : { 'build' : ['ninja'],
+ },
+ 'Eclipse CDT4 - Ninja': { 'build' : ['ninja'],
+ }
+ }
if os.name == 'nt':
emconfigure = path_from_root('emconfigure.bat')
@@ -294,11 +318,37 @@ f.close()
emconfigure = path_from_root('emconfigure')
for generator in generators:
- if generator == 'NMake Makefiles' and not Building.which('nmake'):
- print >> sys.stderr, 'Skipping NMake test for CMake support, since nmake was not found in PATH. Run this test in Visual Studio command prompt to easily access nmake.'
+ conf = configurations[generator]
+
+ make = conf['build']
+
+ try:
+ detector = conf['detect']
+ except KeyError:
+ detector = None
+
+ if detector:
+ error = detector(conf)
+ elif len(make) == 1 and not Building.which(make[0]):
+ # Use simple test if applicable
+ error = 'Skipping %s test for CMake support, since it could not be detected.' % generator
+ else:
+ error = None
+
+ if error:
+ logging.warning(error)
continue
- make = make_commands[generator]
+ try:
+ prebuild = conf['prebuild']
+ except KeyError:
+ prebuild = None
+
+ try:
+ postbuild = conf['postbuild']
+ except KeyError:
+ postbuild = None
+
cmake_cases = ['target_js', 'target_html']
cmake_outputs = ['test_cmake.js', 'hello_world_gles.html']
for i in range(0, 2):
@@ -331,7 +381,9 @@ f.close()
logging.error('Failed command: ' + ' '.join(cmd))
logging.error('Result:\n' + ret[1])
raise Exception('cmake call failed!')
- assert os.path.exists(tempdirname + '/Makefile'), 'CMake call did not produce a Makefile!'
+
+ if prebuild:
+ prebuild(configuration, tempdirname)
# Build
cmd = make + (['VERBOSE=1'] if verbose_level >= 3 else [])
@@ -344,6 +396,9 @@ f.close()
raise Exception('make failed!')
assert os.path.exists(tempdirname + '/' + cmake_outputs[i]), 'Building a cmake-generated Makefile failed to produce an output file %s!' % tempdirname + '/' + cmake_outputs[i]
+ if postbuild:
+ postbuild(configuration, tempdirname)
+
# Run through node, if CMake produced a .js file.
if cmake_outputs[i].endswith('.js'):
ret = Popen(listify(NODE_JS) + [tempdirname + '/' + cmake_outputs[i]], stdout=PIPE).communicate()[0]
diff --git a/tools/js-optimizer.js b/tools/js-optimizer.js
index fa59dbec..6d65f3e7 100644
--- a/tools/js-optimizer.js
+++ b/tools/js-optimizer.js
@@ -3951,7 +3951,7 @@ function safeHeap(ast) {
return ['call', ['name', 'SAFE_HEAP_STORE'], [ptr, makeAsmCoercion(value, ASM_INT), ['num', 4], ['num', '0']]];
}
case 'HEAPF32': {
- return ['call', ['name', 'SAFE_HEAP_STORE'], [ptr, makeAsmCoercion(value, ASM_FLOAT), ['num', 4], ['num', '1']]];
+ return ['call', ['name', 'SAFE_HEAP_STORE'], [ptr, makeAsmCoercion(value, ASM_DOUBLE), ['num', 4], ['num', '1']]];
}
case 'HEAPF64': {
return ['call', ['name', 'SAFE_HEAP_STORE'], [ptr, makeAsmCoercion(value, ASM_DOUBLE), ['num', 8], ['num', '1']]];
@@ -3965,20 +3965,29 @@ function safeHeap(ast) {
var ptr = fixPtr(node[2], heap);
// SAFE_HEAP_LOAD(ptr, bytes, isFloat)
switch (heap) {
- case 'HEAP8': case 'HEAPU8': {
- return makeAsmCoercion(['call', ['name', 'SAFE_HEAP_LOAD'], [ptr, ['num', 1], ['num', '0']]], ASM_INT);
+ case 'HEAP8': {
+ return makeAsmCoercion(['call', ['name', 'SAFE_HEAP_LOAD'], [ptr, ['num', 1], ['num', '0'], ['num', '0']]], ASM_INT);
}
- case 'HEAP16': case 'HEAPU16': {
- return makeAsmCoercion(['call', ['name', 'SAFE_HEAP_LOAD'], [ptr, ['num', 2], ['num', '0']]], ASM_INT);
+ case 'HEAPU8': {
+ return makeAsmCoercion(['call', ['name', 'SAFE_HEAP_LOAD'], [ptr, ['num', 1], ['num', '0'], ['num', '1']]], ASM_INT);
}
- case 'HEAP32': case 'HEAPU32': {
- return makeAsmCoercion(['call', ['name', 'SAFE_HEAP_LOAD'], [ptr, ['num', 4], ['num', '0']]], ASM_INT);
+ case 'HEAP16': {
+ return makeAsmCoercion(['call', ['name', 'SAFE_HEAP_LOAD'], [ptr, ['num', 2], ['num', '0'], ['num', '0']]], ASM_INT);
+ }
+ case 'HEAPU16': {
+ return makeAsmCoercion(['call', ['name', 'SAFE_HEAP_LOAD'], [ptr, ['num', 2], ['num', '0'], ['num', '1']]], ASM_INT);
+ }
+ case 'HEAP32': {
+ return makeAsmCoercion(['call', ['name', 'SAFE_HEAP_LOAD'], [ptr, ['num', 4], ['num', '0'], ['num', '0']]], ASM_INT);
+ }
+ case 'HEAPU32': {
+ return makeAsmCoercion(['call', ['name', 'SAFE_HEAP_LOAD'], [ptr, ['num', 4], ['num', '0'], ['num', '1']]], ASM_INT);
}
case 'HEAPF32': {
- return makeAsmCoercion(['call', ['name', 'SAFE_HEAP_LOAD'], [ptr, ['num', 4], ['num', '1']]], ASM_FLOAT);
+ return makeAsmCoercion(['call', ['name', 'SAFE_HEAP_LOAD'], [ptr, ['num', 4], ['num', '1'], ['num', '0']]], ASM_DOUBLE);
}
case 'HEAPF64': {
- return makeAsmCoercion(['call', ['name', 'SAFE_HEAP_LOAD'], [ptr, ['num', 8], ['num', '1']]], ASM_DOUBLE);
+ return makeAsmCoercion(['call', ['name', 'SAFE_HEAP_LOAD'], [ptr, ['num', 8], ['num', '1'], ['num', '0']]], ASM_DOUBLE);
}
default: throw 'bad heap ' + heap;
}
diff --git a/tools/shared.py b/tools/shared.py
index bb50350d..e05a5f7a 100644
--- a/tools/shared.py
+++ b/tools/shared.py
@@ -1568,7 +1568,7 @@ JCache = cache.JCache(Cache)
chunkify = cache.chunkify
class JS:
- memory_initializer_pattern = '/\* memory initializer \*/ allocate\(([\d,\.concat\(\)\[\]\\n ]+)"i8", ALLOC_NONE, ([\dRuntime\.GLOBAL_BASEH+]+)\)'
+ memory_initializer_pattern = '/\* memory initializer \*/ allocate\(\[([\d, ]+)\], "i8", ALLOC_NONE, ([\d+Runtime\.GLOBAL_BASEH]+)\);'
no_memory_initializer_pattern = '/\* no memory initializer \*/'
memory_staticbump_pattern = 'STATICTOP = STATIC_BASE \+ (\d+);'
@@ -1652,6 +1652,75 @@ class JS:
while x % by != 0: x += 1
return x
+ INITIALIZER_CHUNK_SIZE = 10240
+
+ @staticmethod
+ def collect_initializers(src):
+ ret = []
+ max_offset = -1
+ for init in re.finditer(JS.memory_initializer_pattern, src):
+ contents = init.group(1).split(',')
+ offset = sum([int(x) if x[0] != 'R' else 0 for x in init.group(2).split('+')])
+ ret.append((offset, contents))
+ assert offset > max_offset
+ max_offset = offset
+ return ret
+
+ @staticmethod
+ def split_initializer(contents):
+ # given a memory initializer (see memory_initializer_pattern), split it up into multiple initializers to avoid long runs of zeros or a single overly-large allocator
+ ret = []
+ l = len(contents)
+ maxx = JS.INITIALIZER_CHUNK_SIZE
+ i = 0
+ start = 0
+ while 1:
+ if i - start >= maxx or (i > start and i == l):
+ #print >> sys.stderr, 'new', start, i-start
+ ret.append((start, contents[start:i]))
+ start = i
+ if i == l: break
+ if contents[i] != '0':
+ i += 1
+ else:
+ # look for a sequence of zeros
+ j = i + 1
+ while j < l and contents[j] == '0': j += 1
+ if j-i > maxx/10 or j-start >= maxx:
+ #print >> sys.stderr, 'skip', start, i-start, j-start
+ ret.append((start, contents[start:i])) # skip over the zeros starting at i and ending at j
+ start = j
+ i = j
+ return ret
+
+ @staticmethod
+ def replace_initializers(src, inits):
+ class State:
+ first = True
+ def rep(m):
+ if not State.first: return ''
+ # write out all the new initializers in place of the first old one
+ State.first = False
+ def gen_init(init):
+ offset, contents = init
+ return '/* memory initializer */ allocate([%s], "i8", ALLOC_NONE, Runtime.GLOBAL_BASE%s);' % (
+ ','.join(contents),
+ '' if offset == 0 else ('+%d' % offset)
+ )
+ return '\n'.join(map(gen_init, inits))
+ return re.sub(JS.memory_initializer_pattern, rep, src)
+
+ @staticmethod
+ def optimize_initializer(src):
+ inits = JS.collect_initializers(src)
+ if len(inits) == 0: return None
+ assert len(inits) == 1
+ init = inits[0]
+ offset, contents = init
+ assert offset == 0 # offset 0, singleton
+ if len(contents) <= JS.INITIALIZER_CHUNK_SIZE: return None
+ return JS.replace_initializers(src, JS.split_initializer(contents))
+
# Compression of code and data for smaller downloads
class Compression:
on = False