Skip to content

Commit fe67c23

Browse files
authored
Remove fastcomp-only BINARYEN_TRAP_MODE. See emscripten-core#11860 (emscripten-core#11870)
1 parent a529fde commit fe67c23

8 files changed

Lines changed: 6 additions & 161 deletions

File tree

emcc.py

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

484-
if shared.Settings.WASM_BACKEND and key == 'BINARYEN_TRAP_MODE':
485-
exit_with_error('BINARYEN_TRAP_MODE is not supported by the LLVM wasm backend')
486-
487484
if key == 'EXPORTED_FUNCTIONS':
488485
# used for warnings in emscripten.py
489486
shared.Settings.USER_EXPORTED_FUNCTIONS = shared.Settings.EXPORTED_FUNCTIONS[:]
@@ -3105,76 +3102,6 @@ def do_binaryen(target, asm_target, options, memfile, wasm_binary_target,
31053102
# whether we need to emit -g in the intermediate binaryen invocations (but not necessarily at the very end).
31063103
# this is necessary for emitting a symbol map at the end.
31073104
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)
3108-
# finish compiling to WebAssembly, using asm2wasm, if we didn't already emit WebAssembly directly using the wasm backend.
3109-
if not shared.Settings.WASM_BACKEND:
3110-
if DEBUG:
3111-
# save the asm.js input
3112-
building.save_intermediate(asm_target, 'asmjs.js')
3113-
cmd = [os.path.join(binaryen_bin, 'asm2wasm'), asm_target, '--total-memory=' + str(shared.Settings.INITIAL_MEMORY)]
3114-
if shared.Settings.BINARYEN_TRAP_MODE not in ('js', 'clamp', 'allow'):
3115-
exit_with_error('invalid BINARYEN_TRAP_MODE value: ' + shared.Settings.BINARYEN_TRAP_MODE + ' (should be js/clamp/allow)')
3116-
cmd += ['--trap-mode=' + shared.Settings.BINARYEN_TRAP_MODE]
3117-
if shared.Settings.BINARYEN_IGNORE_IMPLICIT_TRAPS:
3118-
cmd += ['--ignore-implicit-traps']
3119-
# pass optimization level to asm2wasm (if not optimizing, or which passes we should run was overridden, do not optimize)
3120-
if shared.Settings.OPT_LEVEL > 0:
3121-
cmd.append(building.opt_level_to_str(shared.Settings.OPT_LEVEL, shared.Settings.SHRINK_LEVEL))
3122-
# 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)
3123-
mem_file_exists = options.memory_init_file and os.path.exists(memfile)
3124-
import_mem_init = mem_file_exists and shared.Settings.MEM_INIT_IN_WASM
3125-
if import_mem_init:
3126-
cmd += ['--mem-init=' + memfile]
3127-
if not shared.Settings.RELOCATABLE:
3128-
cmd += ['--mem-base=' + str(shared.Settings.GLOBAL_BASE)]
3129-
# various options imply that the imported table may not be the exact size as
3130-
# the wasm module's own table segments
3131-
if shared.Settings.RELOCATABLE or shared.Settings.RESERVED_FUNCTION_POINTERS > 0:
3132-
cmd += ['--table-max=-1']
3133-
if shared.Settings.SIDE_MODULE:
3134-
cmd += ['--mem-max=-1']
3135-
elif not shared.Settings.ALLOW_MEMORY_GROWTH:
3136-
cmd += ['--mem-max=' + str(shared.Settings.INITIAL_MEMORY)]
3137-
elif shared.Settings.MAXIMUM_MEMORY >= 0:
3138-
cmd += ['--mem-max=' + str(shared.Settings.MAXIMUM_MEMORY)]
3139-
if shared.Settings.LEGALIZE_JS_FFI != 1:
3140-
cmd += ['--no-legalize-javascript-ffi']
3141-
if building.is_wasm_only():
3142-
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
3143-
if shared.Settings.USE_PTHREADS:
3144-
cmd += ['--enable-threads']
3145-
if intermediate_debug_info:
3146-
cmd += ['-g']
3147-
if options.emit_symbol_map:
3148-
cmd += ['--symbolmap=' + shared.replace_or_append_suffix(target, '.symbols')]
3149-
# we prefer to emit a binary, as it is more efficient. however, when we
3150-
# want full debug info support (not just function names), then we must
3151-
# emit text (at least until wasm gains support for debug info in binaries)
3152-
target_binary = shared.Settings.DEBUG_LEVEL < 3
3153-
if target_binary:
3154-
cmd += ['-o', wasm_binary_target]
3155-
else:
3156-
cmd += ['-o', wasm_text_target, '-S']
3157-
cmd += building.get_binaryen_feature_flags()
3158-
logger.debug('asm2wasm (asm.js => WebAssembly): ' + ' '.join(cmd))
3159-
TimeLogger.update()
3160-
shared.check_call(cmd)
3161-
3162-
if not target_binary:
3163-
cmd = [os.path.join(binaryen_bin, 'wasm-as'), wasm_text_target, '-o', wasm_binary_target, '--all-features', '--disable-bulk-memory']
3164-
if intermediate_debug_info:
3165-
cmd += ['-g']
3166-
if use_source_map(options):
3167-
cmd += ['--source-map=' + wasm_source_map_target]
3168-
cmd += ['--source-map-url=' + options.source_map_base + os.path.basename(wasm_binary_target) + '.map']
3169-
logger.debug('wasm-as (text => binary): ' + ' '.join(cmd))
3170-
shared.check_call(cmd)
3171-
if import_mem_init:
3172-
# remove the mem init file in later processing; it does not need to be prefetched in the html, etc.
3173-
if DEBUG:
3174-
safe_move(memfile, os.path.join(shared.get_emscripten_temp_dir(), os.path.basename(memfile)))
3175-
else:
3176-
os.unlink(memfile)
3177-
log_time('asm2wasm')
31783105

31793106
if options.binaryen_passes:
31803107
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: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1189,17 +1189,6 @@ var BINARYEN_SCRIPTS = "";
11891189
// codebase it may help reduce code size a little bit.
11901190
var BINARYEN_IGNORE_IMPLICIT_TRAPS = 0;
11911191

1192-
// How we handle wasm operations that may trap, which includes integer
1193-
// div/rem of 0 and float-to-int of values too large to fit in an int.
1194-
// js: do exactly what js does. this can be slower.
1195-
// clamp: avoid traps by clamping to a reasonable value. this can be
1196-
// faster than "js".
1197-
// allow: allow creating operations that can trap. this is the most
1198-
// compact, as we just emit a single wasm operation, with no
1199-
// guards to trapping values, and also often the fastest.
1200-
// [fastcomp-only]
1201-
var BINARYEN_TRAP_MODE = "allow";
1202-
12031192
// A comma-separated list of extra passes to run in the binaryen optimizer,
12041193
// Setting this does not override/replace the default passes. It is appended at
12051194
// the end of the list of passes.
@@ -1720,6 +1709,9 @@ var ASM_PRIMITIVE_VARS = ['__THREW__', 'threwValue', 'setjmpId', 'tempInt', 'tem
17201709
// First element in the list is the canonical/fixed value going forward.
17211710
// This allows existing build systems to keep specifying one of the supported
17221711
// settings, for backwards compatibility.
1712+
// When a setting has been removed, and we want to error on all values of it,
1713+
// we can set POSSIBLE_VALUES to an impossible value (like "disallowed" for a
1714+
// numeric setting, or -1 for a string setting).
17231715
var LEGACY_SETTINGS = [
17241716
['BINARYEN', 'WASM'],
17251717
['BINARYEN_ASYNC_COMPILATION', 'WASM_ASYNC_COMPILATION'],
@@ -1732,6 +1724,7 @@ var LEGACY_SETTINGS = [
17321724
['SAFE_SPLIT_MEMORY', [0], 'Starting from Emscripten 1.38.19, SAFE_SPLIT_MEMORY codegen is no longer available (https://github.com/emscripten-core/emscripten/pull/7465)'],
17331725
['SPLIT_MEMORY', [0], 'Starting from Emscripten 1.38.19, SPLIT_MEMORY codegen is no longer available (https://github.com/emscripten-core/emscripten/pull/7465)'],
17341726
['BINARYEN_METHOD', ['native-wasm'], 'Starting from Emscripten 1.38.23, Emscripten now always builds either to Wasm (-s WASM=1 - default), or to asm.js (-s WASM=0), other methods are not supported (https://github.com/emscripten-core/emscripten/pull/7836)'],
1727+
['BINARYEN_TRAP_MODE', [-1], 'The wasm backend does not support a trap mode (it always clamps, in effect)'],
17351728
['PRECISE_I64_MATH', [1, 2], 'Starting from Emscripten 1.38.26, PRECISE_I64_MATH is always enabled (https://github.com/emscripten-core/emscripten/pull/7935)'],
17361729
['MEMFS_APPEND_TO_TYPED_ARRAYS', [1], 'Starting from Emscripten 1.38.26, MEMFS_APPEND_TO_TYPED_ARRAYS=0 is no longer supported. MEMFS no longer supports using JS arrays for file data (https://github.com/emscripten-core/emscripten/pull/7918)'],
17371730
['ERROR_ON_MISSING_LIBRARIES', [1], 'missing libraries are always an error now'],

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
@@ -332,8 +332,6 @@ def test_sintvars(self):
332332

333333
def test_int53(self):
334334
self.emcc_args += ['-s', 'DEFAULT_LIBRARY_FUNCS_TO_INCLUDE=[$convertI32PairToI53,$convertU32PairToI53,$readI53FromU64,$readI53FromI64,$writeI53ToI64,$writeI53ToI64Clamped,$writeI53ToU64Clamped,$writeI53ToI64Signaling,$writeI53ToU64Signaling]']
335-
if not self.is_wasm_backend():
336-
self.emcc_args += ['-s', 'BINARYEN_TRAP_MODE=js']
337335
self.do_run_in_out_file_test('tests', 'core', 'test_int53')
338336

339337
def test_i64(self):
@@ -8163,34 +8161,6 @@ def test_stack_overflow_check(self):
81638161
self.emcc_args = args + ['-s', 'ASSERTIONS=1']
81648162
self.do_run(open(path_from_root('tests', 'stack_overflow.cpp')).read(), 'Stack overflow! Attempted to allocate', assert_returncode=NON_ZERO)
81658163

8166-
@no_wasm_backend('uses BINARYEN_TRAP_MODE (the wasm backend only supports non-trapping)')
8167-
def test_binaryen_trap_mode(self):
8168-
if not self.is_wasm():
8169-
self.skipTest('wasm test')
8170-
TRAP_OUTPUTS = ('trap', 'RuntimeError')
8171-
default = 'allow'
8172-
print('default is', default)
8173-
for mode in ['js', 'clamp', 'allow', '']:
8174-
if mode == 'js' and self.is_wasm_backend():
8175-
# wasm backend does not use asm2wasm imports, which js trap mode requires
8176-
continue
8177-
print('mode:', mode)
8178-
self.set_setting('BINARYEN_TRAP_MODE', mode or default)
8179-
if not mode:
8180-
mode = default
8181-
print(' idiv')
8182-
self.do_run(open(path_from_root('tests', 'wasm', 'trap-idiv.cpp')).read(), {
8183-
'js': '|0|',
8184-
'clamp': '|0|',
8185-
'allow': TRAP_OUTPUTS
8186-
}[mode], assert_returncode=NON_ZERO if mode == 'allow' else 0)
8187-
print(' f2i')
8188-
self.do_run(open(path_from_root('tests', 'wasm', 'trap-f2i.cpp')).read(), {
8189-
'js': '|1337|\n|4294967295|', # JS did an fmod 2^32 | normal
8190-
'clamp': '|-2147483648|\n|4294967295|',
8191-
'allow': TRAP_OUTPUTS
8192-
}[mode], assert_returncode=NON_ZERO if mode == 'allow' else 0)
8193-
81948164
@node_pthreads
81958165
def test_binaryen_2170_emscripten_atomic_cas_u8(self):
81968166
self.emcc_args += ['-s', 'USE_PTHREADS=1']

0 commit comments

Comments
 (0)