aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xemcc95
-rwxr-xr-xemscripten.py20
-rw-r--r--src/fastLong.js18
-rw-r--r--src/jsifier.js37
-rw-r--r--src/library.js2
-rw-r--r--src/modules.js3
-rw-r--r--src/parseTools.js10
-rw-r--r--src/relooper/Relooper.cpp10
-rw-r--r--src/relooper/test.txt108
-rw-r--r--src/relooper/test2.txt12
-rw-r--r--src/relooper/test3.txt34
-rw-r--r--src/relooper/test4.txt24
-rw-r--r--src/relooper/test5.txt46
-rw-r--r--src/relooper/test6.txt12
-rw-r--r--src/relooper/test_debug.txt12
-rw-r--r--src/relooper/test_fuzz1.txt40
-rw-r--r--src/relooper/test_fuzz2.txt10
-rw-r--r--src/relooper/test_fuzz3.txt2
-rw-r--r--src/relooper/test_fuzz4.txt16
-rw-r--r--src/relooper/test_fuzz5.txt82
-rw-r--r--src/relooper/test_fuzz6.txt186
-rw-r--r--src/relooper/test_inf.txt698
-rw-r--r--src/runtime.js6
-rw-r--r--tests/lua/binarytrees.lua17
-rw-r--r--tests/lua/scimark.lua50
-rwxr-xr-xtests/runner.py56
-rw-r--r--tools/eliminator/asm-eliminator-test-output.js10071
-rw-r--r--tools/eliminator/asm-eliminator-test.js13531
-rw-r--r--tools/eliminator/eliminator-test-output.js11798
-rw-r--r--tools/eliminator/eliminator-test.js17258
-rw-r--r--tools/eliminator/safe-eliminator-test-output.js164
-rw-r--r--tools/eliminator/safe-eliminator-test.js198
-rw-r--r--tools/js-optimizer.js193
-rw-r--r--tools/js_optimizer.py26
-rw-r--r--tools/shared.py2
-rw-r--r--tools/test-js-optimizer-asm-last-output.js82
-rw-r--r--tools/test-js-optimizer-asm-last.js94
-rw-r--r--tools/test-js-optimizer-asm-pre-output.js640
-rw-r--r--tools/test-js-optimizer-asm-pre.js651
-rw-r--r--tools/test-js-optimizer-asm-regs-min-output.js50
-rw-r--r--tools/test-js-optimizer-asm-regs-min.js50
-rw-r--r--tools/test-js-optimizer-asm-regs-output.js180
-rw-r--r--tools/test-js-optimizer-asm-regs.js186
-rw-r--r--tools/test-js-optimizer-output.js482
-rw-r--r--tools/test-js-optimizer-regs-output.js426
-rw-r--r--tools/test-js-optimizer-regs.js436
-rw-r--r--tools/test-js-optimizer-t2-output.js176
-rw-r--r--tools/test-js-optimizer-t2.js176
-rw-r--r--tools/test-js-optimizer-t2c-output.js28
-rw-r--r--tools/test-js-optimizer-t2c.js30
-rw-r--r--tools/test-js-optimizer-t3-output.js90
-rw-r--r--tools/test-js-optimizer-t3.js90
-rw-r--r--tools/test-js-optimizer.js666
53 files changed, 30107 insertions, 29273 deletions
diff --git a/emcc b/emcc
index 33dbbb03..053076a3 100755
--- a/emcc
+++ b/emcc
@@ -182,16 +182,31 @@ Options that are modified or new in %s include:
). Note that the path must be absolute, not
relative.
- -g or -g1 Use debug info. Note that you need this during
- the last compilation phase from bitcode to
- JavaScript, or else we will remove it by
- default in -O1 and above.
- In -O0, line numbers wil be shown in the
- generated code. In -O1 and above, the optimizer
- removes those comments. This flag does however
- have the effect of disabling anything that
- causes name mangling or minification (closure
- or the registerize pass).
+ -g Use debug info. When compiling to bitcode,
+ this is the same as in clang and gcc, it
+ adds debug info to the object files. When
+ compiling from source to JS or bitcode to JS,
+ it is equivalent to -g3 (keep code as debuggable
+ as possible, except for discarding LLVM
+ debug info, so no C/C++ line numbers; use
+ -g4 to get line number debugging info in JS).
+
+ -g<level> When compiling from bitcode to JS, we can
+ keep the code debuggable to different
+ degrees. Each of these levels builds on the
+ previous:
+
+ -g0 Make no effort to keep code debuggable.
+ Will discard LLVM debug info. (default
+ in -O1+)
+ -g1 Preserve (do not minify) whitespace
+ -g2 Preserve function names
+ -g3 Preserve variable names
+ -g4 Preserve LLVM debug info (if -g was
+ used when compiling the C/C++ sources)
+ and show line number debug comments.
+ This is the highest level of debuggability.
+ (default in -O0)
-g2 Like -g1, but we generate source maps as well,
and we preserve comments even with -O1 and above.
@@ -308,12 +323,7 @@ Options that are modified or new in %s include:
archive, which is given the same name as the
output HTML but with suffix .data.compress
- --minify <on> 0: Do not minify the generated JavaScript's
- whitespace (default in -O0, -O1, or if
- -g is used)
- 1: Minify the generated JavaScript's
- whitespace (default in -O2+, assuming
- -g is not used)
+ --minify 0 Identical to -g1
--split <size> Splits the resulting javascript file into pieces
to ease debugging. This option only works if
@@ -701,7 +711,6 @@ try:
js_transform = None
pre_js = ''
post_js = ''
- minify_whitespace = None
split_js_file = None
preload_files = []
embed_files = []
@@ -777,7 +786,7 @@ try:
newargs[i+1] = ''
elif newargs[i].startswith('--minify'):
check_bad_eq(newargs[i])
- minify_whitespace = int(newargs[i+1])
+ debug_level = max(1, debug_level)
newargs[i] = ''
newargs[i+1] = ''
elif newargs[i].startswith('--split'):
@@ -786,10 +795,9 @@ try:
newargs[i] = ''
newargs[i+1] = ''
elif newargs[i].startswith('-g'):
- requested_level = newargs[i][2:] or '1'
- debug_level = validate_arg_level(requested_level, 2)
- if debug_level > 0:
- newargs[i] = '-g' # we'll need this to get LLVM debug info
+ requested_level = newargs[i][2:] or '3'
+ debug_level = validate_arg_level(requested_level, 4)
+ newargs[i] = '-g' # we'll need this to get LLVM debug info
elif newargs[i] == '--bind':
bind = True
newargs[i] = ''
@@ -878,13 +886,13 @@ try:
if llvm_opts is None: llvm_opts = LLVM_OPT_LEVEL[opt_level]
if llvm_lto is None: llvm_lto = opt_level >= 3
- if opt_level <= 0: debug_level = max(debug_level, 1) # always keep debug in -O0
+ if opt_level == 0: debug_level = 4
if closure is None and opt_level == 3: closure = True
# TODO: support source maps with js_transform
- if js_transform and debug_level >= 2:
+ if js_transform and debug_level >= 4:
logging.warning('disabling source maps because a js transform is being done')
- debug_level = 1
+ debug_level = 3
if DEBUG: start_time = time.time() # done after parsing arguments, which might affect debug state
@@ -1032,13 +1040,13 @@ try:
if shared.Settings.ASSERTIONS and shared.Settings.ALIASING_FUNCTION_POINTERS:
logging.warning('ALIASING_FUNCTION_POINTERS is on, function pointer comparisons may be invalid across types')
- if debug_level >= 1 and closure:
+ if shared.Settings.CORRECT_SIGNS >= 2 or shared.Settings.CORRECT_OVERFLOWS >= 2 or shared.Settings.CORRECT_ROUNDINGS >= 2:
+ debug_level = 4 # must keep debug info to do line-by-line operations
+
+ if debug_level > 0 and closure:
logging.warning('disabling closure because debug info was requested')
closure = False
- if minify_whitespace is None:
- minify_whitespace = opt_level >= 2 and debug_level == 0
-
assert shared.LLVM_TARGET in shared.COMPILER_OPTS
if shared.LLVM_TARGET == 'i386-pc-linux-gnu':
shared.Settings.TARGET_X86 = 1
@@ -1143,6 +1151,8 @@ try:
libcxx_symbols = read_symbols(shared.path_from_root('system', 'lib', 'libcxx', 'symbols'), exclude=libc_symbols)
libcxxabi_symbols = read_symbols(shared.path_from_root('system', 'lib', 'libcxxabi', 'symbols'), exclude=libc_symbols)
+ # XXX we should disable EMCC_DEBUG (and EMCC_OPTIMIZE_NORMALLY?) when building libs, just like in the relooper
+
def build_libc(lib_filename, files):
o_s = []
prev_cxx = os.environ.get('EMMAKEN_CXX')
@@ -1363,7 +1373,7 @@ try:
for haz in has: # remove symbols that are supplied by another of the inputs
if haz in need:
need.remove(haz)
- logging.debug('considering %s: we need %s and have %s' % (name, str(need), str(has)))
+ if shared.Settings.VERBOSE: logging.debug('considering %s: we need %s and have %s' % (name, str(need), str(has)))
if (force or len(need) > 0) and apply_(need):
# We need to build and link the library in
logging.debug('including %s' % name)
@@ -1407,12 +1417,7 @@ try:
# Optimize, if asked to
if not LEAVE_INPUTS_RAW:
-
- if opt_level == 0 or debug_level >= 2 or shared.Settings.CORRECT_SIGNS >= 2 or \
- shared.Settings.CORRECT_OVERFLOWS >= 2 or shared.Settings.CORRECT_ROUNDINGS >= 2:
- link_opts = []
- else:
- link_opts = ['-strip-debug'] # remove LLVM debug info in -O1+, since the optimizer removes it anyhow
+ link_opts = [] if debug_level >= 4 else ['-strip-debug'] # remove LLVM debug if we are not asked for it
if llvm_opts > 0:
if not os.environ.get('EMCC_OPTIMIZE_NORMALLY'):
@@ -1515,7 +1520,7 @@ try:
if shared.Settings.ASM_JS:
js_optimizer_queue = ['asm'] + js_optimizer_queue
logging.debug('applying js optimization passes: %s', js_optimizer_queue)
- final = shared.Building.js_optimizer(final, js_optimizer_queue, jcache, debug_level >= 2)
+ final = shared.Building.js_optimizer(final, js_optimizer_queue, jcache, debug_level >= 4)
js_transform_tempfiles.append(final)
if DEBUG: save_intermediate('js_opts')
else:
@@ -1524,7 +1529,7 @@ try:
if shared.Settings.ASM_JS:
passes = ['asm'] + passes
logging.debug('applying js optimization pass: %s', passes)
- final = shared.Building.js_optimizer(final, passes, jcache, debug_level >= 2)
+ final = shared.Building.js_optimizer(final, passes, jcache, debug_level >= 4)
js_transform_tempfiles.append(final)
save_intermediate(name)
js_optimizer_queue = []
@@ -1534,7 +1539,7 @@ try:
if DEBUG == '2':
# Clean up the syntax a bit
- final = shared.Building.js_optimizer(final, [], jcache, debug_level >= 2)
+ final = shared.Building.js_optimizer(final, [], jcache, debug_level >= 4)
js_transform_tempfiles.append(final)
if DEBUG: save_intermediate('pretty')
@@ -1562,12 +1567,12 @@ try:
logging.debug('running post-closure post-opts')
js_optimizer_queue += ['simplifyExpressionsPost']
- if (not closure or shared.Settings.ASM_JS) and shared.Settings.RELOOP and debug_level == 0:
- # do this if closure is not enabled (it gives similar speedups), and we do not need to keep debug info around
+ if (not closure or shared.Settings.ASM_JS) and shared.Settings.RELOOP and debug_level < 3:
js_optimizer_queue += ['registerize']
- if minify_whitespace:
- js_optimizer_queue += ['compress']
+ if opt_level > 0:
+ if debug_level < 2 and shared.Settings.ASM_JS and shared.Settings.RELOOP: js_optimizer_queue += ['minifyGlobals']
+ if debug_level == 0: js_optimizer_queue += ['minifyWhitespace']
if closure and shared.Settings.ASM_JS:
js_optimizer_queue += ['closure']
@@ -1623,7 +1628,7 @@ try:
shell = open(shell_path).read()
html = open(target, 'w')
if not Compression.on:
- if debug_level >= 2:
+ if debug_level >= 4:
match = re.match('.*?<script[^>]*>{{{ SCRIPT_CODE }}}</script>', shell,
re.DOTALL)
if match is None:
@@ -1699,7 +1704,7 @@ try:
from tools.split import split_javascript_file
split_javascript_file(final, unsuffixed(target), split_js_file)
else:
- if debug_level >= 2: generate_source_map(target)
+ if debug_level >= 4: generate_source_map(target)
# copy final JS to output
shutil.move(final, target)
diff --git a/emscripten.py b/emscripten.py
index c9a5eb59..56f59273 100755
--- a/emscripten.py
+++ b/emscripten.py
@@ -407,7 +407,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])
- basic_funcs = ['abort', 'assert', 'asmPrintInt', 'asmPrintFloat', 'copyTempDouble', 'copyTempFloat'] + [m.replace('.', '_') for m in math_envs]
+ basic_funcs = ['abort', 'assert', 'asmPrintInt', 'asmPrintFloat'] + [m.replace('.', '_') for m in math_envs]
if settings['RESERVED_FUNCTION_POINTERS'] > 0: basic_funcs.append('jsCall')
if settings['SAFE_HEAP']: basic_funcs += ['SAFE_HEAP_LOAD', 'SAFE_HEAP_STORE', 'SAFE_HEAP_CLEAR']
if settings['CHECK_HEAP_ALIGN']: basic_funcs += ['CHECK_ALIGN_2', 'CHECK_ALIGN_4', 'CHECK_ALIGN_8']
@@ -555,6 +555,24 @@ var asm = (function(global, env, buffer) {
threwValue = value;
}
}
+ function copyTempFloat(ptr) {
+ ptr = ptr|0;
+ HEAP8[tempDoublePtr] = HEAP8[ptr];
+ HEAP8[tempDoublePtr+1|0] = HEAP8[ptr+1|0];
+ HEAP8[tempDoublePtr+2|0] = HEAP8[ptr+2|0];
+ HEAP8[tempDoublePtr+3|0] = HEAP8[ptr+3|0];
+ }
+ function copyTempDouble(ptr) {
+ ptr = ptr|0;
+ HEAP8[tempDoublePtr] = HEAP8[ptr];
+ HEAP8[tempDoublePtr+1|0] = HEAP8[ptr+1|0];
+ HEAP8[tempDoublePtr+2|0] = HEAP8[ptr+2|0];
+ HEAP8[tempDoublePtr+3|0] = HEAP8[ptr+3|0];
+ HEAP8[tempDoublePtr+4|0] = HEAP8[ptr+4|0];
+ HEAP8[tempDoublePtr+5|0] = HEAP8[ptr+5|0];
+ HEAP8[tempDoublePtr+6|0] = HEAP8[ptr+6|0];
+ HEAP8[tempDoublePtr+7|0] = HEAP8[ptr+7|0];
+ }
''' + ''.join(['''
function setTempRet%d(value) {
value = value|0;
diff --git a/src/fastLong.js b/src/fastLong.js
index d1ce5d39..4f6efd9f 100644
--- a/src/fastLong.js
+++ b/src/fastLong.js
@@ -5,12 +5,12 @@ function ___muldsi3($a, $b) {
var $1 = 0, $2 = 0, $3 = 0, $6 = 0, $8 = 0, $11 = 0, $12 = 0;
$1 = $a & 65535;
$2 = $b & 65535;
- $3 = Math.imul($2, $1);
+ $3 = Math.imul($2, $1) | 0;
$6 = $a >>> 16;
- $8 = ($3 >>> 16) + Math.imul($2, $6) | 0;
+ $8 = ($3 >>> 16) + (Math.imul($2, $6) | 0) | 0;
$11 = $b >>> 16;
- $12 = Math.imul($11, $1);
- return (tempRet0 = (($8 >>> 16) + Math.imul($11, $6) | 0) + ((($8 & 65535) + $12 | 0) >>> 16) | 0, 0 | ($8 + $12 << 16 | $3 & 65535)) | 0;
+ $12 = Math.imul($11, $1) | 0;
+ return (tempRet0 = (($8 >>> 16) + (Math.imul($11, $6) | 0) | 0) + ((($8 & 65535) + $12 | 0) >>> 16) | 0, 0 | ($8 + $12 << 16 | $3 & 65535)) | 0;
}
function ___divdi3($a$0, $a$1, $b$0, $b$1) {
$a$0 = $a$0 | 0;
@@ -47,7 +47,7 @@ function ___remdi3($a$0, $a$1, $b$0, $b$1) {
$4$0 = _i64Subtract($1$0 ^ $a$0, $1$1 ^ $a$1, $1$0, $1$1) | 0;
$4$1 = tempRet0;
$6$0 = _i64Subtract($2$0 ^ $b$0, $2$1 ^ $b$1, $2$0, $2$1) | 0;
- ___udivmoddi4($4$0, $4$1, $6$0, tempRet0, $rem);
+ ___udivmoddi4($4$0, $4$1, $6$0, tempRet0, $rem) | 0;
$10$0 = _i64Subtract(HEAP32[$rem >> 2] ^ $1$0, HEAP32[$rem + 4 >> 2] ^ $1$1, $1$0, $1$1) | 0;
$10$1 = tempRet0;
STACKTOP = __stackBase__;
@@ -63,8 +63,8 @@ function ___muldi3($a$0, $a$1, $b$0, $b$1) {
$y_sroa_0_0_extract_trunc = $b$0;
$1$0 = ___muldsi3($x_sroa_0_0_extract_trunc, $y_sroa_0_0_extract_trunc) | 0;
$1$1 = tempRet0;
- $2 = Math.imul($a$1, $y_sroa_0_0_extract_trunc);
- return (tempRet0 = (Math.imul($b$1, $x_sroa_0_0_extract_trunc) + $2 | 0) + $1$1 | $1$1 & 0, 0 | $1$0 & -1) | 0;
+ $2 = Math.imul($a$1, $y_sroa_0_0_extract_trunc) | 0;
+ return (tempRet0 = ((Math.imul($b$1, $x_sroa_0_0_extract_trunc) | 0) + $2 | 0) + $1$1 | $1$1 & 0, 0 | $1$0 & -1) | 0;
}
function ___udivdi3($a$0, $a$1, $b$0, $b$1) {
$a$0 = $a$0 | 0;
@@ -84,7 +84,7 @@ function ___uremdi3($a$0, $a$1, $b$0, $b$1) {
__stackBase__ = STACKTOP;
STACKTOP = STACKTOP + 8 | 0;
$rem = __stackBase__ | 0;
- ___udivmoddi4($a$0, $a$1, $b$0, $b$1, $rem);
+ ___udivmoddi4($a$0, $a$1, $b$0, $b$1, $rem) | 0;
STACKTOP = __stackBase__;
return (tempRet0 = HEAP32[$rem + 4 >> 2] | 0, HEAP32[$rem >> 2] | 0) | 0;
}
@@ -258,7 +258,7 @@ function ___udivmoddi4($a$0, $a$1, $b$0, $b$1, $rem) {
$149 = $carry_0203 | $q_sroa_0_1199 << 1;
$r_sroa_0_0_insert_insert42$0 = 0 | ($r_sroa_0_1201 << 1 | $q_sroa_1_1198 >>> 31);
$r_sroa_0_0_insert_insert42$1 = $r_sroa_0_1201 >>> 31 | $r_sroa_1_1200 << 1 | 0;
- _i64Subtract($137$0, $137$1, $r_sroa_0_0_insert_insert42$0, $r_sroa_0_0_insert_insert42$1);
+ _i64Subtract($137$0, $137$1, $r_sroa_0_0_insert_insert42$0, $r_sroa_0_0_insert_insert42$1) | 0;
$150$1 = tempRet0;
$151$0 = $150$1 >> 31 | (($150$1 | 0) < 0 ? -1 : 0) << 1;
$152 = $151$0 & 1;
diff --git a/src/jsifier.js b/src/jsifier.js
index 7264b0e9..a432b3e0 100644
--- a/src/jsifier.js
+++ b/src/jsifier.js
@@ -14,6 +14,8 @@ var asmLibraryFunctions = [];
var SETJMP_LABEL = -1;
+var INDENTATION = ' ';
+
// JSifier
function JSify(data, functionsOnly, givenFunctions) {
var mainPass = !functionsOnly;
@@ -591,13 +593,13 @@ function JSify(data, functionsOnly, givenFunctions) {
func.JS += 'function ' + func.ident + '(' + paramIdents.join(', ') + ') {\n';
if (PGO) {
- func.JS += ' PGOMonitor.called["' + func.ident + '"] = 1;\n';
+ func.JS += INDENTATION + 'PGOMonitor.called["' + func.ident + '"] = 1;\n';
}
if (ASM_JS) {
// spell out argument types
func.params.forEach(function(param) {
- func.JS += ' ' + param.ident + ' = ' + asmCoercion(param.ident, param.type) + ';\n';
+ func.JS += INDENTATION + param.ident + ' = ' + asmCoercion(param.ident, param.type) + ';\n';
});
// spell out local variables
@@ -611,7 +613,7 @@ function JSify(data, functionsOnly, givenFunctions) {
i += chunkSize;
}
for (i = 0; i < chunks.length; i++) {
- func.JS += ' var ' + chunks[i].map(function(v) {
+ func.JS += INDENTATION + 'var ' + chunks[i].map(function(v) {
var type = getImplementationType(v);
if (!isIllegalType(type) || v.ident.indexOf('$', 1) > 0) { // not illegal, or a broken up illegal
return v.ident + ' = ' + asmInitializer(type); //, func.variables[v.ident].impl);
@@ -627,7 +629,7 @@ function JSify(data, functionsOnly, givenFunctions) {
if (true) { // TODO: optimize away when not needed
if (CLOSURE_ANNOTATIONS) func.JS += '/** @type {number} */';
- func.JS += ' var label = 0;\n';
+ func.JS += INDENTATION + 'var label = 0;\n';
}
if (ASM_JS) {
@@ -636,12 +638,12 @@ function JSify(data, functionsOnly, givenFunctions) {
hasByVal = hasByVal || param.byVal;
});
if (hasByVal) {
- func.JS += ' var tempParam = 0;\n';
+ func.JS += INDENTATION + 'var tempParam = 0;\n';
}
}
// Prepare the stack, if we need one. If we have other stack allocations, force the stack to be set up.
- func.JS += ' ' + RuntimeGenerator.stackEnter(func.initialStack, func.otherStackAllocations) + ';\n';
+ func.JS += INDENTATION + RuntimeGenerator.stackEnter(func.initialStack, func.otherStackAllocations) + ';\n';
// Make copies of by-value params
// XXX It is not clear we actually need this. While without this we fail, it does look like
@@ -654,7 +656,7 @@ function JSify(data, functionsOnly, givenFunctions) {
if (param.byVal) {
var type = removePointing(param.type);
var typeInfo = Types.types[type];
- func.JS += ' ' + (ASM_JS ? '' : 'var ') + 'tempParam = ' + param.ident + '; ' + param.ident + ' = ' + RuntimeGenerator.stackAlloc(typeInfo.flatSize) + ';' +
+ func.JS += INDENTATION + (ASM_JS ? '' : 'var ') + 'tempParam = ' + param.ident + '; ' + param.ident + ' = ' + RuntimeGenerator.stackAlloc(typeInfo.flatSize) + ';' +
makeCopyValues(param.ident, 'tempParam', typeInfo.flatSize, 'null', null, param.byVal) + ';\n';
}
});
@@ -730,12 +732,12 @@ function JSify(data, functionsOnly, givenFunctions) {
}
ret += 'switch(' + asmCoercion('label', 'i32') + ') {\n';
ret += block.labels.map(function(label) {
- return indent + ' case ' + getLabelId(label.ident) + ': ' + (SHOW_LABELS ? '// ' + getOriginalLabelId(label.ident) : '') + '\n'
- + getLabelLines(label, indent + ' ');
+ return indent + INDENTATION + 'case ' + getLabelId(label.ident) + ': ' + (SHOW_LABELS ? '// ' + getOriginalLabelId(label.ident) : '') + '\n'
+ + getLabelLines(label, indent + INDENTATION + INDENTATION);
}).join('\n') + '\n';
if (func.setjmpTable && ASM_JS) {
// emit a label in which we write to the proper local variable, before jumping to the actual label
- ret += ' case ' + SETJMP_LABEL + ': ';
+ ret += INDENTATION + 'case ' + SETJMP_LABEL + ': ';
ret += func.setjmpTable.map(function(triple) { // original label, label we created for right after the setjmp, variable setjmp result goes into
return 'if ((setjmpLabel|0) == ' + getLabelId(triple.oldLabel) + ') { ' + triple.assignTo + ' = threwValue; label = ' + triple.newLabel + ' }\n';
}).join(' else ');
@@ -743,7 +745,7 @@ function JSify(data, functionsOnly, givenFunctions) {
ret += '__THREW__ = threwValue = 0;\n';
ret += 'break;\n';
}
- if (ASSERTIONS) ret += indent + ' default: assert(0' + (ASM_JS ? '' : ', "bad label: " + label') + ');\n';
+ if (ASSERTIONS) ret += indent + INDENTATION + 'default: assert(0' + (ASM_JS ? '' : ', "bad label: " + label') + ');\n';
ret += indent + '}\n';
if (func.setjmpTable && !ASM_JS) {
ret += ' } catch(e) { if (!e.longjmp || !(e.id in mySetjmpIds)) throw(e); setjmpTable[setjmpLabels[e.id]](e.value) }';
@@ -799,13 +801,13 @@ function JSify(data, functionsOnly, givenFunctions) {
}
return ret;
}
- func.JS += walkBlock(func.block, ' ');
+ func.JS += walkBlock(func.block, INDENTATION);
// Finalize function
if (LABEL_DEBUG && functionNameFilterTest(func.ident)) func.JS += " INDENT = INDENT.substr(0, INDENT.length-2);\n";
// Ensure a return in a function with a type that returns, even if it lacks a return (e.g., if it aborts())
if (RELOOP && func.lines.length > 0 && func.returnType != 'void') {
var returns = func.labels.filter(function(label) { return label.lines[label.lines.length-1].intertype == 'return' }).length;
- if (returns == 0) func.JS += ' return ' + asmCoercion('0', func.returnType);
+ if (returns == 0) func.JS += INDENTATION + 'return ' + asmCoercion('0', func.returnType);
}
func.JS += '}\n';
@@ -1123,7 +1125,7 @@ function JSify(data, functionsOnly, givenFunctions) {
ret += value + '{\n';
}
var phiSet = getPhiSetsForLabel(phiSets, targetLabel);
- ret += ' ' + phiSet + makeBranch(targetLabel, item.currLabelId || null) + '\n';
+ ret += INDENTATION + '' + phiSet + makeBranch(targetLabel, item.currLabelId || null) + '\n';
ret += '}\n';
if (RELOOP) {
item.groupedLabels.push({
@@ -1187,8 +1189,13 @@ function JSify(data, functionsOnly, givenFunctions) {
if (disabled) {
ret = call_ + ';';
} else if (ASM_JS) {
+ if (item.type != 'void') call_ = asmCoercion(call_, item.type); // ensure coercion to ffi in comma operator
call_ = call_.replace('; return', ''); // we auto-add returns when aborting, but do not need them here
- ret = '(__THREW__ = 0,' + call_ + ');';
+ if (item.type == 'void') {
+ ret = '__THREW__ = 0;' + call_ + ';';
+ } else {
+ ret = '(__THREW__ = 0,' + call_ + ');';
+ }
} else {
ret = '(function() { try { __THREW__ = 0; return '
+ call_ + ' '
diff --git a/src/library.js b/src/library.js
index 33dcbd5f..01a67804 100644
--- a/src/library.js
+++ b/src/library.js
@@ -4399,7 +4399,7 @@ LibraryManager.library = {
{{{ makeSetValueAsm('dest', 0, makeGetValueAsm('src', 0, 'i8'), 'i8') }}};
}
} else {
- _memcpy(dest, src, num);
+ _memcpy(dest, src, num) | 0;
}
},
llvm_memmove_i32: 'memmove',
diff --git a/src/modules.js b/src/modules.js
index b13ab3c5..d26acbd5 100644
--- a/src/modules.js
+++ b/src/modul