Skip to content

Commit f227d45

Browse files
committed
Remove fastcomp-only BINARYEN_TRAP_MODE. See #11860
1 parent bd98714 commit f227d45

File tree

8 files changed

+2
-161
lines changed

8 files changed

+2
-161
lines changed

emcc.py

Lines changed: 0 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -482,9 +482,6 @@ def standardize_setting_change(key, value):
482482
exit_with_error('setting `%s` expects `%s` but got `%s`' % (user_key, type(existing), type(value)))
483483
setattr(shared.Settings, user_key, value)
484484

485-
if shared.Settings.WASM_BACKEND and key == 'BINARYEN_TRAP_MODE':
486-
exit_with_error('BINARYEN_TRAP_MODE is not supported by the LLVM wasm backend')
487-
488485
if key == 'EXPORTED_FUNCTIONS':
489486
# used for warnings in emscripten.py
490487
shared.Settings.USER_EXPORTED_FUNCTIONS = shared.Settings.EXPORTED_FUNCTIONS[:]
@@ -3150,76 +3147,6 @@ def do_binaryen(target, asm_target, options, memfile, wasm_binary_target,
31503147
# whether we need to emit -g in the intermediate binaryen invocations (but not necessarily at the very end).
31513148
# this is necessary for emitting a symbol map at the end.
31523149
intermediate_debug_info = bool(debug_info or options.emit_symbol_map or shared.Settings.ASYNCIFY_ONLY or shared.Settings.ASYNCIFY_REMOVE or shared.Settings.ASYNCIFY_ADD)
3153-
# finish compiling to WebAssembly, using asm2wasm, if we didn't already emit WebAssembly directly using the wasm backend.
3154-
if not shared.Settings.WASM_BACKEND:
3155-
if DEBUG:
3156-
# save the asm.js input
3157-
building.save_intermediate(asm_target, 'asmjs.js')
3158-
cmd = [os.path.join(binaryen_bin, 'asm2wasm'), asm_target, '--total-memory=' + str(shared.Settings.INITIAL_MEMORY)]
3159-
if shared.Settings.BINARYEN_TRAP_MODE not in ('js', 'clamp', 'allow'):
3160-
exit_with_error('invalid BINARYEN_TRAP_MODE value: ' + shared.Settings.BINARYEN_TRAP_MODE + ' (should be js/clamp/allow)')
3161-
cmd += ['--trap-mode=' + shared.Settings.BINARYEN_TRAP_MODE]
3162-
if shared.Settings.BINARYEN_IGNORE_IMPLICIT_TRAPS:
3163-
cmd += ['--ignore-implicit-traps']
3164-
# pass optimization level to asm2wasm (if not optimizing, or which passes we should run was overridden, do not optimize)
3165-
if shared.Settings.OPT_LEVEL > 0:
3166-
cmd.append(building.opt_level_to_str(shared.Settings.OPT_LEVEL, shared.Settings.SHRINK_LEVEL))
3167-
# import mem init file if it exists, and if we will not be using asm.js as a binaryen method (as it needs the mem init file, of course)
3168-
mem_file_exists = options.memory_init_file and os.path.exists(memfile)
3169-
import_mem_init = mem_file_exists and shared.Settings.MEM_INIT_IN_WASM
3170-
if import_mem_init:
3171-
cmd += ['--mem-init=' + memfile]
3172-
if not shared.Settings.RELOCATABLE:
3173-
cmd += ['--mem-base=' + str(shared.Settings.GLOBAL_BASE)]
3174-
# various options imply that the imported table may not be the exact size as
3175-
# the wasm module's own table segments
3176-
if shared.Settings.RELOCATABLE or shared.Settings.RESERVED_FUNCTION_POINTERS > 0:
3177-
cmd += ['--table-max=-1']
3178-
if shared.Settings.SIDE_MODULE:
3179-
cmd += ['--mem-max=-1']
3180-
elif not shared.Settings.ALLOW_MEMORY_GROWTH:
3181-
cmd += ['--mem-max=' + str(shared.Settings.INITIAL_MEMORY)]
3182-
elif shared.Settings.MAXIMUM_MEMORY >= 0:
3183-
cmd += ['--mem-max=' + str(shared.Settings.MAXIMUM_MEMORY)]
3184-
if shared.Settings.LEGALIZE_JS_FFI != 1:
3185-
cmd += ['--no-legalize-javascript-ffi']
3186-
if building.is_wasm_only():
3187-
cmd += ['--wasm-only'] # this asm.js is code not intended to run as asm.js, it is only ever going to be wasm, and can contain special fastcomp-wasm support
3188-
if shared.Settings.USE_PTHREADS:
3189-
cmd += ['--enable-threads']
3190-
if intermediate_debug_info:
3191-
cmd += ['-g']
3192-
if options.emit_symbol_map:
3193-
cmd += ['--symbolmap=' + shared.replace_or_append_suffix(target, '.symbols')]
3194-
# we prefer to emit a binary, as it is more efficient. however, when we
3195-
# want full debug info support (not just function names), then we must
3196-
# emit text (at least until wasm gains support for debug info in binaries)
3197-
target_binary = shared.Settings.DEBUG_LEVEL < 3
3198-
if target_binary:
3199-
cmd += ['-o', wasm_binary_target]
3200-
else:
3201-
cmd += ['-o', wasm_text_target, '-S']
3202-
cmd += building.get_binaryen_feature_flags()
3203-
logger.debug('asm2wasm (asm.js => WebAssembly): ' + ' '.join(cmd))
3204-
TimeLogger.update()
3205-
shared.check_call(cmd)
3206-
3207-
if not target_binary:
3208-
cmd = [os.path.join(binaryen_bin, 'wasm-as'), wasm_text_target, '-o', wasm_binary_target, '--all-features', '--disable-bulk-memory']
3209-
if intermediate_debug_info:
3210-
cmd += ['-g']
3211-
if use_source_map(options):
3212-
cmd += ['--source-map=' + wasm_source_map_target]
3213-
cmd += ['--source-map-url=' + options.source_map_base + os.path.basename(wasm_binary_target) + '.map']
3214-
logger.debug('wasm-as (text => binary): ' + ' '.join(cmd))
3215-
shared.check_call(cmd)
3216-
if import_mem_init:
3217-
# remove the mem init file in later processing; it does not need to be prefetched in the html, etc.
3218-
if DEBUG:
3219-
safe_move(memfile, os.path.join(shared.get_emscripten_temp_dir(), os.path.basename(memfile)))
3220-
else:
3221-
os.unlink(memfile)
3222-
log_time('asm2wasm')
32233150

32243151
if options.binaryen_passes:
32253152
if '--post-emscripten' in options.binaryen_passes and not shared.Settings.SIDE_MODULE:

site/source/docs/compiling/Deploying-Pages.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ This way the page will be future compatible once support for the particular feat
118118

119119
2. Exceptions caused by Emscripten runtime calling the ``abort()`` function. These correspond to a fatal error that execution of the compiled code cannot recover from. For example, this can occur when calling an invalid function pointer.
120120

121-
3. Traps caused by compiled WebAssembly code. These correspond to fatal errors coming from the WebAssembly VM. This can occur for example when performing an integer division by zero, or when converting a large floating point number to an integer when the float is out of range of the numbers representable by that integer type. See the linker flag ``-s BINARYEN_TRAP_MODE`` for more details.
121+
3. Traps caused by compiled WebAssembly code. These correspond to fatal errors coming from the WebAssembly VM. This can occur for example when performing an integer division by zero, or when converting a large floating point number to an integer when the float is out of range of the numbers representable by that integer type.
122122

123123
- Implement a final "catch all" error handler on the page by implementing a ``window.onerror`` script. This will be called as a last resort if no other source handled an exception that was raised on the page. See `window.onerror <https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers/onerror#window.onerror>`_ documentaton on MDN.
124124

site/source/docs/compiling/WebAssembly.rst

Lines changed: 1 addition & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -94,32 +94,11 @@ upgrade from fastcomp to upstream:
9494

9595
* Also see the `blocker bugs on the wasm backend <https://github.com/emscripten-core/emscripten/projects/1>`_, and the `wasm backend tagged issues <https://github.com/emscripten-core/emscripten/issues?utf8=✓&q=is%3Aissue+is%3Aopen+label%3A"LLVM+wasm+backend">`_.
9696

97-
Binaryen codegen options
98-
========================
99-
10097
Trapping
101-
--------
98+
========
10299

103100
WebAssembly can trap - throw an exception - on things like division by zero, rounding a very large float to an int, and so forth. In asm.js such things were silently ignored, as in JavaScript they do not throw, so this is a difference between JavaScript and WebAssembly that you may notice, with the browser reporting an error like ``float unrepresentable in integer range``, ``integer result unrepresentable``, ``integer overflow``, or ``Out of bounds Trunc operation``.
104101

105-
106-
Fastcomp/asm2wasm
107-
~~~~~~~~~~~~~~~~~
108-
109-
In fastcomp/asm2wasm, emscripten will emit code that is optimized for size and speed, which means it emits code that may trap on the things mentioned before. That mode is called ``allow``. The other modes are ``clamp``, which will avoid traps by clamping values to a reasonable range, and ``js``, which ensures the exact same behavior as JavaScript does (which also does clamping, but makes sure to clamp exactly like JavaScript does, and also do other things JavaScript would).
110-
111-
In general, using ``clamp`` is safest, as whether such a trap occurs depends on how the LLVM optimizer optimizes code. In other words, there is no guarantee that this will not be an issue, and updating LLVM can make a problem appear or vanish (the wasm spec process has recognized this problem and intends to standardize `new operations that avoid it <https://github.com/WebAssembly/design/issues/1143>`_). Also, there is not a big downside to using ``clamp``: it is only slightly larger and slower than the default ``allow``, in most cases. To do so, build with
112-
113-
::
114-
115-
-s "BINARYEN_TRAP_MODE='clamp'"
116-
117-
118-
However, if the default (to allow traps) works in your codebase, then it may be worth keeping it that way, for the (small) benefits. Note that ``js``, which preserves the exact same behavior as JavaScript does, adds a large amount of overhead, so unless you really need that, use ``clamp`` (``js`` is often useful for debugging, though).
119-
120-
LLVM wasm backend
121-
~~~~~~~~~~~~~~~~~
122-
123102
The LLVM wasm backend avoids traps by adding more code around each possible trap (basically clamping the value if it would trap). This can increase code size and decrease speed, if you don't need that extra code. The proper solution for this is to use newer wasm instructions that do not trap, by calling emcc or clang with ``-mnontrapping-fptoint``. That code may not run in older VMs, though.
124103

125104
Compiler output

src/jsifier.js

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,6 @@ var proxiedFunctionTable = ["null" /* Reserve index 0 for an undefined function*
4141
// map: pair(sig, syncOrAsync) -> function body
4242
var proxiedFunctionInvokers = {};
4343

44-
// We include asm2wasm imports if the trap mode is 'js' (to call out to JS to do some math stuff).
45-
// However, we always need some of them (like the frem import because % is in asm.js but not in wasm).
46-
// But we can avoid emitting all the others in many cases.
47-
var NEED_ALL_ASM2WASM_IMPORTS = BINARYEN_TRAP_MODE == 'js';
48-
4944
// Used internally. set when there is a main() function.
5045
// Also set when in a linkable module, as the main() function might
5146
// arrive from a dynamically-linked library, and not necessarily

src/settings.js

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1203,17 +1203,6 @@ var BINARYEN_SCRIPTS = "";
12031203
// codebase it may help reduce code size a little bit.
12041204
var BINARYEN_IGNORE_IMPLICIT_TRAPS = 0;
12051205

1206-
// How we handle wasm operations that may trap, which includes integer
1207-
// div/rem of 0 and float-to-int of values too large to fit in an int.
1208-
// js: do exactly what js does. this can be slower.
1209-
// clamp: avoid traps by clamping to a reasonable value. this can be
1210-
// faster than "js".
1211-
// allow: allow creating operations that can trap. this is the most
1212-
// compact, as we just emit a single wasm operation, with no
1213-
// guards to trapping values, and also often the fastest.
1214-
// [fastcomp-only]
1215-
var BINARYEN_TRAP_MODE = "allow";
1216-
12171206
// A comma-separated list of extra passes to run in the binaryen optimizer,
12181207
// Setting this does not override/replace the default passes. It is appended at
12191208
// the end of the list of passes.

src/support.js

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -46,24 +46,6 @@ var asm2wasmImports = { // special asm2wasm imports
4646
debugger;
4747
#endif
4848
}
49-
#if NEED_ALL_ASM2WASM_IMPORTS
50-
,
51-
"f64-to-int": function(x) {
52-
return x | 0;
53-
},
54-
"i32s-div": function(x, y) {
55-
return ((x | 0) / (y | 0)) | 0;
56-
},
57-
"i32u-div": function(x, y) {
58-
return ((x >>> 0) / (y >>> 0)) >>> 0;
59-
},
60-
"i32s-rem": function(x, y) {
61-
return ((x | 0) % (y | 0)) | 0;
62-
},
63-
"i32u-rem": function(x, y) {
64-
return ((x >>> 0) % (y >>> 0)) >>> 0;
65-
}
66-
#endif // NEED_ALL_ASM2WASM_IMPORTS
6749
};
6850
#endif
6951

tests/fuzz/csmith_driver.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,6 @@ def try_js(args=[]):
117117
shared.try_delete(filename + '.js')
118118
js_args = [shared.EMCC, fullname, '-o', filename + '.js'] + [opts] + llvm_opts + CSMITH_CFLAGS + args + ['-w']
119119
if TEST_BINARYEN:
120-
js_args += ['-s', 'BINARYEN=1', '-s', 'BINARYEN_TRAP_MODE="js"']
121120
if random.random() < 0.5:
122121
js_args += ['-g']
123122
if random.random() < 0.1:

tests/test_core.py

Lines changed: 0 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -344,8 +344,6 @@ def test_sintvars(self):
344344

345345
def test_int53(self):
346346
self.emcc_args += ['-s', 'DEFAULT_LIBRARY_FUNCS_TO_INCLUDE=[$convertI32PairToI53,$convertU32PairToI53,$readI53FromU64,$readI53FromI64,$writeI53ToI64,$writeI53ToI64Clamped,$writeI53ToU64Clamped,$writeI53ToI64Signaling,$writeI53ToU64Signaling]']
347-
if not self.is_wasm_backend():
348-
self.emcc_args += ['-s', 'BINARYEN_TRAP_MODE=js']
349347
self.do_run_in_out_file_test('tests', 'core', 'test_int53')
350348

351349
def test_i64(self):
@@ -8203,34 +8201,6 @@ def test_stack_overflow_check(self):
82038201
self.emcc_args = args + ['-s', 'ASSERTIONS=1']
82048202
self.do_run(open(path_from_root('tests', 'stack_overflow.cpp')).read(), 'Stack overflow! Attempted to allocate', assert_returncode=NON_ZERO)
82058203

8206-
@no_wasm_backend('uses BINARYEN_TRAP_MODE (the wasm backend only supports non-trapping)')
8207-
def test_binaryen_trap_mode(self):
8208-
if not self.is_wasm():
8209-
self.skipTest('wasm test')
8210-
TRAP_OUTPUTS = ('trap', 'RuntimeError')
8211-
default = 'allow'
8212-
print('default is', default)
8213-
for mode in ['js', 'clamp', 'allow', '']:
8214-
if mode == 'js' and self.is_wasm_backend():
8215-
# wasm backend does not use asm2wasm imports, which js trap mode requires
8216-
continue
8217-
print('mode:', mode)
8218-
self.set_setting('BINARYEN_TRAP_MODE', mode or default)
8219-
if not mode:
8220-
mode = default
8221-
print(' idiv')
8222-
self.do_run(open(path_from_root('tests', 'wasm', 'trap-idiv.cpp')).read(), {
8223-
'js': '|0|',
8224-
'clamp': '|0|',
8225-
'allow': TRAP_OUTPUTS
8226-
}[mode], assert_returncode=NON_ZERO if mode == 'allow' else 0)
8227-
print(' f2i')
8228-
self.do_run(open(path_from_root('tests', 'wasm', 'trap-f2i.cpp')).read(), {
8229-
'js': '|1337|\n|4294967295|', # JS did an fmod 2^32 | normal
8230-
'clamp': '|-2147483648|\n|4294967295|',
8231-
'allow': TRAP_OUTPUTS
8232-
}[mode], assert_returncode=NON_ZERO if mode == 'allow' else 0)
8233-
82348204
@node_pthreads
82358205
def test_binaryen_2170_emscripten_atomic_cas_u8(self):
82368206
self.emcc_args += ['-s', 'USE_PTHREADS=1']

0 commit comments

Comments
 (0)