Skip to content

Commit 83e3000

Browse files
authored
Remove fastcomp-only ALIASING_FUNCTION_POINTERS setting (#11882)
Also removes the code block around it in emscripten.py. That's an obvious easy win as it's a fastcomp-only function, and it's faster to remove such a thing (when it's easily identifiable like here) rather than let future PRs remove it line by line. Also removes the call chain to that function, also of fastcomp- only functions (also easy wins, and necessary due to flake8). See #11860
1 parent 9990463 commit 83e3000

File tree

7 files changed

+4
-182
lines changed

7 files changed

+4
-182
lines changed

emcc.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1444,9 +1444,6 @@ def check(input_file):
14441444
not shared.Settings.USE_PTHREADS:
14451445
shared.Settings.EXPORT_READY_PROMISE = 0
14461446

1447-
if shared.Settings.EMULATE_FUNCTION_POINTER_CASTS:
1448-
shared.Settings.ALIASING_FUNCTION_POINTERS = 0
1449-
14501447
if shared.Settings.LEGACY_VM_SUPPORT:
14511448
if not shared.Settings.WASM or shared.Settings.WASM2JS:
14521449
shared.Settings.POLYFILL_OLD_MATH_FUNCTIONS = 1

emscripten.py

Lines changed: 1 addition & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -53,70 +53,6 @@ def access_quote(prop):
5353
return '.' + prop
5454

5555

56-
def emscript_fastcomp(infile, outfile, memfile, temp_files, DEBUG):
57-
"""Runs the emscripten LLVM-to-JS compiler.
58-
59-
Args:
60-
infile: The path to the input LLVM assembly file.
61-
outfile: An open file object where the output is written.
62-
"""
63-
64-
assert shared.Settings.ASM_JS, 'fastcomp is asm.js-only (mode 1 or 2)'
65-
66-
success = False
67-
68-
try:
69-
70-
# Overview:
71-
# * Run LLVM backend to emit JS. JS includes function bodies, memory initializer,
72-
# and various metadata
73-
# * Run compiler.js on the metadata to emit the shell js code, pre/post-ambles,
74-
# JS library dependencies, etc.
75-
76-
# metadata is modified by reference in some of the below
77-
# these functions are split up to force variables to go out of scope and allow
78-
# memory to be reclaimed
79-
80-
with ToolchainProfiler.profile_block('get_and_parse_backend'):
81-
backend_output = compile_js(infile, temp_files, DEBUG)
82-
funcs, metadata, mem_init = parse_fastcomp_output(backend_output, DEBUG)
83-
fixup_metadata_tables(metadata)
84-
funcs = fixup_functions(funcs, metadata)
85-
with ToolchainProfiler.profile_block('compiler_glue'):
86-
glue, forwarded_data = compiler_glue(metadata, temp_files, DEBUG)
87-
88-
with ToolchainProfiler.profile_block('function_tables_and_exports'):
89-
(post, function_table_data, bundled_args) = (
90-
function_tables_and_exports(funcs, metadata, mem_init, glue, forwarded_data, outfile, DEBUG))
91-
with ToolchainProfiler.profile_block('write_output_file'):
92-
finalize_output(outfile, post, function_table_data, bundled_args, metadata, DEBUG)
93-
success = True
94-
95-
finally:
96-
outfile.close()
97-
if not success:
98-
shared.try_delete(outfile.name) # remove partial output
99-
100-
101-
def compile_js(infile, temp_files, DEBUG):
102-
"""Compile infile with asm.js backend, return the contents of the compiled js"""
103-
with temp_files.get_file('.4.js') as temp_js:
104-
backend_cmd = create_backend_cmd(infile, temp_js)
105-
106-
if DEBUG:
107-
logger.debug('emscript: llvm backend: ' + ' '.join(backend_cmd))
108-
t = time.time()
109-
shared.print_compiler_stage(backend_cmd)
110-
with ToolchainProfiler.profile_block('emscript_llvm_backend'):
111-
shared.check_call(backend_cmd)
112-
if DEBUG:
113-
logger.debug(' emscript: llvm backend took %s seconds' % (time.time() - t))
114-
115-
# Split up output
116-
backend_output = open(temp_js).read()
117-
return backend_output
118-
119-
12056
def parse_fastcomp_output(backend_output, DEBUG):
12157
start_funcs_marker = '// EMSCRIPTEN_START_FUNCTIONS'
12258
end_funcs_marker = '// EMSCRIPTEN_END_FUNCTIONS'
@@ -543,49 +479,6 @@ def write_output_file(outfile, post, module):
543479
outfile.write(post)
544480

545481

546-
def create_backend_cmd(infile, temp_js):
547-
"""Create asm.js backend command from settings dict"""
548-
args = [
549-
shared.LLVM_COMPILER, infile, '-march=js', '-filetype=asm', '-o', temp_js,
550-
'-emscripten-stack-size=%d' % shared.Settings.TOTAL_STACK,
551-
'-O%s' % shared.Settings.OPT_LEVEL,
552-
]
553-
if shared.Settings.USE_PTHREADS:
554-
args += ['-emscripten-enable-pthreads']
555-
if shared.Settings.WARN_UNALIGNED:
556-
args += ['-emscripten-warn-unaligned']
557-
if shared.Settings.RESERVED_FUNCTION_POINTERS > 0:
558-
args += ['-emscripten-reserved-function-pointers=%d' % shared.Settings.RESERVED_FUNCTION_POINTERS]
559-
if shared.Settings.ASSERTIONS > 0:
560-
args += ['-emscripten-assertions=%d' % shared.Settings.ASSERTIONS]
561-
if shared.Settings.ALIASING_FUNCTION_POINTERS == 0:
562-
args += ['-emscripten-no-aliasing-function-pointers']
563-
if shared.Settings.EMULATE_FUNCTION_POINTER_CASTS:
564-
args += ['-emscripten-emulate-function-pointer-casts']
565-
if shared.Settings.RELOCATABLE:
566-
args += ['-emscripten-relocatable']
567-
args += ['-emscripten-global-base=0']
568-
elif shared.Settings.GLOBAL_BASE >= 0:
569-
args += ['-emscripten-global-base=%d' % shared.Settings.GLOBAL_BASE]
570-
if shared.Settings.SIDE_MODULE:
571-
args += ['-emscripten-side-module']
572-
if shared.Settings.LEGALIZE_JS_FFI != 1:
573-
args += ['-emscripten-legalize-javascript-ffi=0']
574-
if shared.Settings.DISABLE_EXCEPTION_CATCHING != 1:
575-
args += ['-enable-emscripten-cpp-exceptions']
576-
if shared.Settings.DISABLE_EXCEPTION_CATCHING == 2:
577-
args += ['-emscripten-cpp-exceptions-whitelist=' + ','.join(shared.Settings.EXCEPTION_CATCHING_ALLOWED or ['fake'])]
578-
if not shared.Settings.EXIT_RUNTIME:
579-
args += ['-emscripten-no-exit-runtime']
580-
if shared.Settings.WORKAROUND_IOS_9_RIGHT_SHIFT_BUG:
581-
args += ['-emscripten-asmjs-work-around-ios-9-right-shift-bug']
582-
if shared.Settings.WASM:
583-
args += ['-emscripten-wasm']
584-
if building.is_wasm_only():
585-
args += ['-emscripten-only-wasm']
586-
return args
587-
588-
589482
def optimize_syscalls(declares, DEBUG):
590483
"""Disables filesystem if only a limited subset of syscalls is used.
591484
@@ -2444,7 +2337,7 @@ def run(infile, outfile, memfile):
24442337

24452338
outfile_obj = open(outfile, 'w')
24462339

2447-
emscripter = emscript_wasm_backend if shared.Settings.WASM_BACKEND else emscript_fastcomp
2340+
emscripter = emscript_wasm_backend
24482341
return temp_files.run_and_clean(lambda: emscripter(
24492342
infile, outfile_obj, memfile, temp_files, shared.DEBUG)
24502343
)

site/source/docs/porting/Debugging.rst

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -251,14 +251,11 @@ In order to debug these sorts of issues:
251251
- Compile with ``-Werror``. This turns warnings into errors, which can be useful as some cases of undefined behavior would otherwise show warnings.
252252
- Use ``-s ASSERTIONS=2`` to get some useful information about the function pointer being called, and its type.
253253
- Look at the browser stack trace to see where the error occurs and which function should have been called.
254-
- Build with :ref:`SAFE_HEAP=1 <debugging-SAFE-HEAP>` and function pointer aliasing disabled (``ALIASING_FUNCTION_POINTERS=0``). This should make it impossible for a function pointer to be called with the wrong type without raising an error: ``-s SAFE_HEAP=1 -s ALIASING_FUNCTION_POINTERS=0``
255-
254+
- Build with :ref:`SAFE_HEAP=1 <debugging-SAFE-HEAP>`.
255+
- :ref:`Sanitizers` can help here, in particular UBSan.
256256

257257
Another function pointer issue is when the wrong function is called. :ref:`SAFE_HEAP=1 <debugging-SAFE-HEAP>` can help with this as it detects some possible errors with function table accesses.
258258

259-
``ALIASING_FUNCTION_POINTERS=0`` is also useful because it ensures that calls to function pointer addresses in the wrong table result in clear errors. Without this setting such calls just execute whatever function is at the address, which can be much harder to debug.
260-
261-
262259

263260
Infinite loops
264261
--------------

src/settings.js

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -290,12 +290,6 @@ var SAFE_HEAP_LOG = 0;
290290
// [fastcomp-only]
291291
var RESERVED_FUNCTION_POINTERS = 0;
292292

293-
// Whether to allow function pointers to alias if they have a different type.
294-
// This can greatly decrease table sizes in asm.js, but can break code that
295-
// compares function pointers across different types.
296-
// [fastcomp-only]
297-
var ALIASING_FUNCTION_POINTERS = 0;
298-
299293
// Allows function pointers to be cast, wraps each call of an incorrect type
300294
// with a runtime correction. This adds overhead and should not be used
301295
// normally. It also forces ALIASING_FUNCTION_POINTERS to 0. Aside from making
@@ -1745,4 +1739,5 @@ var LEGACY_SETTINGS = [
17451739
['FAST_UNROLLED_MEMCPY_AND_MEMSET', [0, 1], 'The wasm backend implements memcpy/memset in C'],
17461740
['DOUBLE_MODE', [0, 1], 'The wasm backend always implements doubles normally'],
17471741
['PRECISE_F32', [0, 1, 2], 'The wasm backend always implements floats normally'],
1742+
['ALIASING_FUNCTION_POINTERS', [0, 1], 'The wasm backend always uses a single index space for function pointers, in a single Table'],
17481743
];

tests/test_core.py

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6085,10 +6085,6 @@ def test_lua(self):
60856085
@needs_make('configure script')
60866086
@is_slow_test
60876087
def test_freetype(self):
6088-
if self.run_name == 'asm2g':
6089-
# flip for some more coverage here
6090-
self.set_setting('ALIASING_FUNCTION_POINTERS', 1 - self.get_setting('ALIASING_FUNCTION_POINTERS'))
6091-
60926088
self.add_pre_run("FS.createDataFile('/', 'font.ttf', %s, true, false, false);" % str(
60936089
list(bytearray(open(path_from_root('tests', 'freetype', 'LiberationSansBold.ttf'), 'rb').read()))
60946090
))
@@ -6898,11 +6894,6 @@ def test_add_function(self):
68986894
self.emcc_args = old
68996895
print(old)
69006896

6901-
print('with ALIASING_FUNCTION_POINTERS')
6902-
self.set_setting('ALIASING_FUNCTION_POINTERS', 1)
6903-
self.do_run_in_out_file_test('tests', 'interop', 'test_add_function')
6904-
self.clear_setting('ALIASING_FUNCTION_POINTERS')
6905-
69066897
print('with RESERVED_FUNCTION_POINTERS=0')
69076898
self.set_setting('RESERVED_FUNCTION_POINTERS', 0)
69086899

tests/test_other.py

Lines changed: 0 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -3929,56 +3929,6 @@ def test_bad_function_pointer_cast(self):
39293929
# non-informative error
39303930
self.assertContained(('abort(', 'exception'), output)
39313931

3932-
@no_wasm_backend('asm.js function table feature')
3933-
def test_aliased_func_pointers(self):
3934-
create_test_file('src.cpp', r'''
3935-
#include <stdio.h>
3936-
3937-
int impl1(int foo) { return foo; }
3938-
float impla(float foo) { return foo; }
3939-
int impl2(int foo) { return foo+1; }
3940-
float implb(float foo) { return foo+1; }
3941-
int impl3(int foo) { return foo+2; }
3942-
float implc(float foo) { return foo+2; }
3943-
3944-
int main(int argc, char **argv) {
3945-
volatile void *f = (void*)impl1;
3946-
if (argc == 50) f = (void*)impla;
3947-
if (argc == 51) f = (void*)impl2;
3948-
if (argc == 52) f = (void*)implb;
3949-
if (argc == 53) f = (void*)impl3;
3950-
if (argc == 54) f = (void*)implc;
3951-
return (int)f;
3952-
}
3953-
''')
3954-
3955-
print('aliasing')
3956-
3957-
sizes_ii = {}
3958-
sizes_dd = {}
3959-
3960-
for alias in [None, 0, 1]:
3961-
cmd = [EMCC, 'src.cpp', '-O1', '-s', 'WASM=0']
3962-
if alias is not None:
3963-
cmd += ['-s', 'ALIASING_FUNCTION_POINTERS=' + str(alias)]
3964-
else:
3965-
alias = -1
3966-
print(cmd)
3967-
self.run_process(cmd)
3968-
src = open('a.out.js').read().split('\n')
3969-
for line in src:
3970-
if line.strip().startswith('var FUNCTION_TABLE_ii = '):
3971-
sizes_ii[alias] = line.count(',')
3972-
if line.strip().startswith('var FUNCTION_TABLE_dd = '):
3973-
sizes_dd[alias] = line.count(',')
3974-
3975-
print('ii', sizes_ii)
3976-
print('dd', sizes_dd)
3977-
3978-
for sizes in [sizes_ii, sizes_dd]:
3979-
self.assertEqual(sizes[-1], sizes[1]) # default is to alias
3980-
self.assertLess(sizes[1], sizes[0]) # without aliasing, we have more unique values and fat tables
3981-
39823932
def test_bad_export(self):
39833933
for m in ['', ' ']:
39843934
self.clear()

tools/shared.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1001,7 +1001,6 @@ def apply_opt_level(cls, opt_level, shrink_level=0, noisy=False):
10011001
if opt_level >= 1:
10021002
cls.attrs['ASM_JS'] = 1
10031003
cls.attrs['ASSERTIONS'] = 0
1004-
cls.attrs['ALIASING_FUNCTION_POINTERS'] = 1
10051004
if shrink_level >= 2:
10061005
cls.attrs['EVAL_CTORS'] = 1
10071006

0 commit comments

Comments
 (0)