Skip to content

Commit

Permalink
Remove fastcomp-only --separate-asm option. See #11860 (#11869)
Browse files Browse the repository at this point in the history
SEPARATE_ASM was always just an asm.js feature, and never
worked in upstream.
  • Loading branch information
kripken authored Aug 12, 2020
1 parent 574f381 commit c6212ef
Show file tree
Hide file tree
Showing 8 changed files with 8 additions and 202 deletions.
73 changes: 3 additions & 70 deletions emcc.py
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,6 @@ def __init__(self):
self.proxy_to_worker = False
self.default_object_extension = '.o'
self.valid_abspaths = []
self.separate_asm = False
self.cfi = False
# Specifies the line ending format to use for all generated text files.
# Defaults to using the native EOL on each platform (\r\n on Windows, \n on
Expand Down Expand Up @@ -1223,9 +1222,6 @@ def get_last_setting_change(setting):

final_suffix = get_file_suffix(target)

if options.separate_asm and final_suffix != '.html':
diagnostics.warning('separate-asm', "--separate-asm works best when compiling to HTML. Otherwise, you must yourself load the '.asm.js' file that is emitted separately, and must do so before loading the main '.js' file.")

if has_dash_c or has_dash_S or has_dash_E:
if has_dash_c:
if '-emit-llvm' in newargs:
Expand Down Expand Up @@ -1256,9 +1252,6 @@ def get_last_setting_change(setting):
wasm_binary_target = asm_target.replace('.asm.js', '.wasm') # ditto, might not be used
wasm_source_map_target = shared.replace_or_append_suffix(wasm_binary_target, '.map')

if options.separate_asm:
shared.Settings.SEPARATE_ASM = shared.JS.get_subresource_location(asm_target)

# Apply user -jsD settings
for s in user_js_defines:
shared.Settings.attrs[s[0]] = s[1]
Expand Down Expand Up @@ -1745,9 +1738,8 @@ def include_and_export(name):
shared.Settings.MINIFY_ASMJS_IMPORT_NAMES = 1

if shared.Settings.WASM:
if not building.need_asm_js_file():
asm_target = asm_target.replace('.asm.js', '.temp.asm.js')
misc_temp_files.note(asm_target)
asm_target = asm_target.replace('.asm.js', '.temp.asm.js')
misc_temp_files.note(asm_target)

if shared.Settings.WASM:
if shared.Settings.INITIAL_MEMORY % 65536 != 0:
Expand Down Expand Up @@ -1803,23 +1795,6 @@ def include_and_export(name):
if shared.Settings.WASM_BACKEND:
shared.Settings.MINIFY_WASM_IMPORTED_MODULES = 1

# In MINIMAL_RUNTIME when modularizing, by default output asm.js module under the same name as
# the JS module. This allows code to share same loading function for both JS and asm.js modules,
# to save code size. The intent is that loader code captures the function variable from global
# scope to XHR loader local scope when it finishes loading, to avoid polluting global JS scope
# with variables. This provides safety via encapsulation. See src/shell_minimal_runtime.html for
# an example.
if shared.Settings.MINIMAL_RUNTIME and not shared.Settings.SEPARATE_ASM_MODULE_NAME and not shared.Settings.WASM and shared.Settings.MODULARIZE:
shared.Settings.SEPARATE_ASM_MODULE_NAME = 'var ' + shared.Settings.EXPORT_NAME

if shared.Settings.MODULARIZE and shared.Settings.SEPARATE_ASM and not shared.Settings.WASM and not shared.Settings.SEPARATE_ASM_MODULE_NAME:
exit_with_error('Targeting asm.js with --separate-asm and -s MODULARIZE=1 requires specifying the target variable name to which the asm.js module is loaded into. See https://github.com/emscripten-core/emscripten/pull/7949 for details')
# Apply default option if no custom name is provided
if not shared.Settings.SEPARATE_ASM_MODULE_NAME:
shared.Settings.SEPARATE_ASM_MODULE_NAME = 'Module["asm"]'
elif shared.Settings.WASM:
exit_with_error('-s SEPARATE_ASM_MODULE_NAME option only applies to when targeting asm.js, not with WebAssembly!')

if shared.Settings.MINIMAL_RUNTIME:
# Minimal runtime uses a different default shell file
if options.shell_path == shared.path_from_root('src', 'shell.html'):
Expand Down Expand Up @@ -1896,9 +1871,6 @@ def include_and_export(name):
if shared.Settings.SIDE_MODULE and target.endswith('.js'):
diagnostics.warning('emcc', 'output suffix .js requested, but wasm side modules are just wasm files; emitting only a .wasm, no .js')

if options.separate_asm:
exit_with_error('cannot --separate-asm when emitting wasm, since not emitting asm.js')

sanitize = set()

for arg in newargs:
Expand Down Expand Up @@ -2735,11 +2707,6 @@ def get_eliminate():
# track files that will need native eols
generated_text_files_with_native_eols = []

if (options.separate_asm or shared.Settings.WASM) and not shared.Settings.WASM_BACKEND:
separate_asm_js(final, asm_target)
if not shared.Settings.SINGLE_FILE:
generated_text_files_with_native_eols += [asm_target]

if shared.Settings.WASM:
do_binaryen(target, asm_target, options, memfile, wasm_binary_target,
wasm_text_target, wasm_source_map_target, misc_temp_files,
Expand All @@ -2760,9 +2727,6 @@ def get_eliminate():
# here, so that it will not confuse the hacky script.
shared.JS.handle_license(final)
shared.run_process([shared.PYTHON, shared.path_from_root('tools', 'hacky_postprocess_around_closure_limitations.py'), final])
# Process .asm.js file
if not shared.Settings.WASM and shared.Settings.SEPARATE_ASM:
shared.run_process([shared.PYTHON, shared.path_from_root('tools', 'hacky_postprocess_around_closure_limitations.py'), asm_target])

# Apply pre and postjs files
if options.extern_pre_js or options.extern_post_js:
Expand Down Expand Up @@ -3015,8 +2979,7 @@ def consume_arg():
newargs[i] = ''
newargs[i + 1] = ''
elif newargs[i] == '--separate-asm':
options.separate_asm = True
newargs[i] = ''
exit_with_error('cannot --separate-asm with the wasm backend, since not emitting asm.js')
elif newargs[i].startswith(('-I', '-L')):
path_name = newargs[i][2:]
if os.path.isabs(path_name) and not is_valid_abspath(options, path_name):
Expand Down Expand Up @@ -3129,12 +3092,6 @@ def emit_js_source_maps(target, js_transform_tempfiles):
'--offset', '0'])


def separate_asm_js(final, asm_target):
"""Separate out the asm.js code, if asked. Or, if necessary for another option"""
logger.debug('separating asm')
shared.check_call([shared.PYTHON, shared.path_from_root('tools', 'separate_asm.py'), final, asm_target, final, shared.Settings.SEPARATE_ASM_MODULE_NAME])


def do_binaryen(target, asm_target, options, memfile, wasm_binary_target,
wasm_text_target, wasm_source_map_target, misc_temp_files,
optimizer):
Expand Down Expand Up @@ -3524,30 +3481,6 @@ def generate_traditional_runtime_html(target, options, js_target, target_basenam
meminitXHR.send(null);
''' % shared.JS.get_subresource_location(memfile)) + script.inline

# Download .asm.js if --separate-asm was passed in an asm.js build, or if 'asmjs' is one
# of the wasm run methods.
if not options.separate_asm or shared.Settings.WASM:
pass
else:
script.un_src()
# just load the asm, then load the rest
script.inline = '''
var filename = '%s';
var fileBytes = tryParseAsDataURI(filename);
var script = document.createElement('script');
if (fileBytes) {
script.innerHTML = intArrayToString(fileBytes);
} else {
script.src = filename;
}
script.onload = function() {
setTimeout(function() {
%s
}, 1); // delaying even 1ms is enough to allow compilation memory to be reclaimed
};
document.body.appendChild(script);
''' % (shared.JS.get_subresource_location(asm_target), script.inline)

if shared.Settings.WASM and not shared.Settings.WASM_ASYNC_COMPILATION:
# We need to load the wasm file before anything else, it has to be synchronously ready TODO: optimize
script.un_src()
Expand Down
4 changes: 0 additions & 4 deletions src/preamble_minimal.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@
* SPDX-License-Identifier: MIT
*/

#if SEPARATE_ASM && ASSERTIONS && WASM == 0 && MODULARIZE
if (!({{{ASM_MODULE_NAME}}})) throw 'Must load asm.js Module in to variable {{{ASM_MODULE_NAME}}} before adding compiled output .js script to the DOM';
#endif

#include "runtime_safe_heap.js"

#if ASSERTIONS
Expand Down
16 changes: 2 additions & 14 deletions src/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -1040,16 +1040,6 @@ var DETERMINISTIC = 0;
// code, allowing better dead code elimination and minification.
var MODULARIZE = 0;

// If we separate out asm.js with the --separate-asm option,
// this is the name of the variable where the generated asm.js
// Module is assigned to. This name can either be a property
// of Module, or a freestanding variable name, like "var asmJs".
// If you are XHRing in multiple asm.js built files, use this option to
// assign the generated asm.js modules to different variable names
// so that they do not conflict. Default name is 'Module["asm"]' if a custom
// name is not passed in.
var SEPARATE_ASM_MODULE_NAME = '';

// Export using an ES6 Module export rather than a UMD export. MODULARIZE must
// be enabled for ES6 exports.
var EXPORT_ES6 = 0;
Expand All @@ -1074,10 +1064,6 @@ var ASM_JS = 1;
// [fastcomp-only]
var FINALIZE_ASM_JS = 1;

// see emcc --separate-asm
// [fastcomp-only]
var SEPARATE_ASM = 0;

// JS library functions on this list are not converted to JS, and calls to them
// are turned into abort()s. This is potentially useful for reducing code size.
// If a dead function is actually called, you will get a runtime error.
Expand Down Expand Up @@ -1766,6 +1752,8 @@ var LEGACY_SETTINGS = [
['ASYNCIFY_WHITELIST', 'ASYNCIFY_ONLY'],
['ASYNCIFY_BLACKLIST', 'ASYNCIFY_REMOVE'],
['EXCEPTION_CATCHING_WHITELIST', 'EXCEPTION_CATCHING_ALLOWED'],
['SEPARATE_ASM', [0], 'Separate asm.js only made sense for fastcomp with asm.js output'],
['SEPARATE_ASM_MODULE_NAME', [''], 'Separate asm.js only made sense for fastcomp with asm.js output'],
['FAST_UNROLLED_MEMCPY_AND_MEMSET', [0, 1], 'The wasm backend implements memcpy/memset in C'],
['DOUBLE_MODE', [0, 1], 'The wasm backend always implements doubles normally'],
['PRECISE_F32', [0, 1, 2], 'The wasm backend always implements floats normally'],
Expand Down
6 changes: 0 additions & 6 deletions src/shell_minimal.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,6 @@ if (ENVIRONMENT_IS_NODE) {
#endif
#endif
#else
#if SEPARATE_ASM
eval(fs.readFileSync(__dirname + '/{{{ TARGET_BASENAME }}}.asm.js')+'');
#endif
#endif
#if MEM_INIT_METHOD == 1 && !MEM_INIT_IN_WASM
Module['mem'] = fs.readFileSync(__dirname + '/{{{ TARGET_BASENAME }}}.mem');
Expand Down Expand Up @@ -105,9 +102,6 @@ if (ENVIRONMENT_IS_SHELL) {
#if ENVIRONMENT_MAY_BE_NODE
if (ENVIRONMENT_IS_NODE) {
var fs = require('fs');
#if SEPARATE_ASM
eval(fs.readFileSync(__dirname + '/{{{ TARGET_BASENAME }}}.asm.js')+'');
#endif
#if MEM_INIT_METHOD == 1 && !MEM_INIT_IN_WASM
Module['mem'] = fs.readFileSync(__dirname + '/{{{ TARGET_BASENAME }}}.mem');
#endif
Expand Down
12 changes: 0 additions & 12 deletions src/worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -113,18 +113,6 @@ this.onmessage = function(e) {
#else // asm.js:
{{{ makeAsmImportsAccessInPthread('buffer') }}} = e.data.buffer;

#if SEPARATE_ASM
// load the separated-out asm.js
e.data.asmJsUrlOrBlob = e.data.asmJsUrlOrBlob || '{{{ SEPARATE_ASM }}}';
if (typeof e.data.asmJsUrlOrBlob === 'string') {
importScripts(e.data.asmJsUrlOrBlob);
} else {
var objectUrl = URL.createObjectURL(e.data.asmJsUrlOrBlob);
importScripts(objectUrl);
URL.revokeObjectURL(objectUrl);
}
#endif

#endif // WASM

#if !MINIMAL_RUNTIME || MODULARIZE
Expand Down
88 changes: 3 additions & 85 deletions tests/test_browser.py
Original file line number Diff line number Diff line change
Expand Up @@ -3836,13 +3836,6 @@ def test_pthread_supported(self):
for args in [[], ['-s', 'USE_PTHREADS=1', '-s', 'PTHREAD_POOL_SIZE=8']]:
self.btest(path_from_root('tests', 'pthread', 'test_pthread_supported.cpp'), expected='0', args=['-O3'] + args)

# Test that --separate-asm works with -s USE_PTHREADS=1.
@no_wasm_backend('asm.js')
@requires_threads
def test_pthread_separate_asm_pthreads(self):
for modularize in [[], ['-s', 'MODULARIZE=1', '-s', 'EXPORT_NAME=MyModule', '--shell-file', path_from_root('tests', 'shell_that_launches_modularize.html')]]:
self.btest(path_from_root('tests', 'pthread', 'test_pthread_atomics.cpp'), expected='0', args=['-s', 'INITIAL_MEMORY=64MB', '-O3', '-s', 'USE_PTHREADS=1', '-s', 'PTHREAD_POOL_SIZE=8', '--separate-asm', '--profiling'] + modularize)

# Test the operation of Module.pthreadMainPrefixURL variable
@no_wasm_backend('uses js')
@requires_threads
Expand Down Expand Up @@ -3898,7 +3891,7 @@ def test_pthread_sbrk(self):
print('aborting malloc=' + str(aborting_malloc))
# With aborting malloc = 1, test allocating memory in threads
# With aborting malloc = 0, allocate so much memory in threads that some of the allocations fail.
self.btest(path_from_root('tests', 'pthread', 'test_pthread_sbrk.cpp'), expected='0', args=['-O3', '-s', 'USE_PTHREADS=1', '-s', 'PTHREAD_POOL_SIZE=8', '--separate-asm', '-s', 'ABORTING_MALLOC=' + str(aborting_malloc), '-DABORTING_MALLOC=' + str(aborting_malloc), '-s', 'INITIAL_MEMORY=128MB'])
self.btest(path_from_root('tests', 'pthread', 'test_pthread_sbrk.cpp'), expected='0', args=['-O3', '-s', 'USE_PTHREADS=1', '-s', 'PTHREAD_POOL_SIZE=8', '-s', 'ABORTING_MALLOC=' + str(aborting_malloc), '-DABORTING_MALLOC=' + str(aborting_malloc), '-s', 'INITIAL_MEMORY=128MB'])

# Test that -s ABORTING_MALLOC=0 works in both pthreads and non-pthreads builds. (sbrk fails gracefully)
@requires_threads
Expand Down Expand Up @@ -4090,48 +4083,6 @@ def test_canvas_size_proxy(self):
def test_custom_messages_proxy(self):
self.btest(path_from_root('tests', 'custom_messages_proxy.c'), expected='1', args=['--proxy-to-worker', '--shell-file', path_from_root('tests', 'custom_messages_proxy_shell.html'), '--post-js', path_from_root('tests', 'custom_messages_proxy_postjs.js')])

# Tests that when building with -s MINIMAL_RUNTIME=1, the build can use -s WASM=0 --separate-asm as well.
@no_wasm_backend('asm.js')
def test_minimal_runtime_separate_asm(self):
for opts in [['-s', 'MINIMAL_RUNTIME=1']]:
print(opts)
create_test_file('src.cpp', self.with_report_result(open(path_from_root('tests', 'browser_test_hello_world.c')).read()))
self.compile_btest(['src.cpp', '-o', 'test.html', '-s', 'WASM=0', '--separate-asm'] + opts)
self.run_browser('test.html', None, '/report_result?0')

@no_wasm_backend('asm.js')
def test_separate_asm(self):
for opts in [['-O0'], ['-O1'], ['-O2'], ['-O2', '--closure', '1']]:
print(opts)
create_test_file('src.cpp', self.with_report_result(open(path_from_root('tests', 'browser_test_hello_world.c')).read()))
self.compile_btest(['src.cpp', '-o', 'test.html', '-s', 'WASM=0'] + opts)
self.run_browser('test.html', None, '/report_result?0')

print('run one')
create_test_file('one.html', '<script src="test.js"></script>')
self.run_browser('one.html', None, '/report_result?0')

print('run two')
self.run_process([PYTHON, path_from_root('tools', 'separate_asm.py'), 'test.js', 'asm.js', 'rest.js'])
create_test_file('two.html', '''
<script>
var Module = {};
</script>
<script src="asm.js"></script>
<script src="rest.js"></script>
''')
self.run_browser('two.html', None, '/report_result?0')

print('run hello world')
self.clear()
assert not os.path.exists('tests.asm.js')
self.btest('browser_test_hello_world.c', expected='0', args=opts + ['-s', 'WASM=0', '--separate-asm'])
self.assertExists('test.asm.js')
os.unlink('test.asm.js')

print('see a fail')
self.run_browser('test.html', None, '[no http server activity]', timeout=5) # fail without the asm

def test_vanilla_html_when_proxying(self):
for opts in [0, 1, 2]:
print(opts)
Expand Down Expand Up @@ -4561,7 +4512,7 @@ def test_emscripten_get_device_pixel_ratio(self):
@requires_threads
def test_pthread_run_script(self):
for args in [[], ['-s', 'USE_PTHREADS=1', '-s', 'PROXY_TO_PTHREAD=1']]:
self.btest(path_from_root('tests', 'pthread', 'test_pthread_run_script.cpp'), expected='1', args=['-O3', '--separate-asm'] + args)
self.btest(path_from_root('tests', 'pthread', 'test_pthread_run_script.cpp'), expected='1', args=['-O3'] + args)

# Tests emscripten_set_canvas_element_size() and OffscreenCanvas functionality in different build configurations.
@requires_threads
Expand All @@ -4575,7 +4526,7 @@ def test_emscripten_animate_canvas_element_size(self):
['-DTEST_EXPLICIT_CONTEXT_SWAP=1', '-s', 'PROXY_TO_PTHREAD=1', '-s', 'USE_PTHREADS=1', '-s', 'OFFSCREEN_FRAMEBUFFER=1', '-DTEST_MANUALLY_SET_ELEMENT_CSS_SIZE=1'],
['-DTEST_EMSCRIPTEN_SET_MAIN_LOOP=1', '-s', 'OFFSCREENCANVAS_SUPPORT'],
]:
cmd = ['-lGL', '-O3', '-g2', '--shell-file', path_from_root('tests', 'canvas_animate_resize_shell.html'), '--separate-asm', '-s', 'GL_DEBUG=1', '--threadprofiler'] + args
cmd = ['-lGL', '-O3', '-g2', '--shell-file', path_from_root('tests', 'canvas_animate_resize_shell.html'), '-s', 'GL_DEBUG=1', '--threadprofiler'] + args
print(' '.join(cmd))
self.btest('canvas_animate_resize.cpp', expected='1', args=cmd)

Expand Down Expand Up @@ -4899,39 +4850,6 @@ def test_closure_in_web_only_target_environment_console_log(self):
def test_closure_in_web_only_target_environment_webgl(self):
self.btest('webgl_draw_triangle.c', '0', args=['-lGL', '-s', 'ENVIRONMENT=web', '-O3', '--closure', '1'])

# Tests that it is possible to load two asm.js compiled programs to one page when both --separate-asm and MODULARIZE=1 is used, by assigning
# the pages different asm module names to ensure they do not conflict when being XHRed in.
@no_wasm_backend('this tests asm.js support')
def test_two_separate_asm_files_on_same_page(self):
html_file = open('main.html', 'w')
html_file.write(open(path_from_root('tests', 'two_separate_asm_files.html')).read().replace('localhost:8888', 'localhost:%s' % self.port))
html_file.close()

cmd = [EMCC, path_from_root('tests', 'modularize_separate_asm.c'), '-o', 'page1.js', '-s', 'WASM=0', '--separate-asm', '-s', 'MODULARIZE=1', '-s', 'EXPORT_NAME=Module1', '-s', 'SEPARATE_ASM_MODULE_NAME=ModuleForPage1["asm"]']
print(cmd)
subprocess.check_call(cmd)

cmd = [EMCC, path_from_root('tests', 'modularize_separate_asm.c'), '-o', 'page2.js', '-s', 'WASM=0', '--separate-asm', '-s', 'MODULARIZE=1', '-s', 'EXPORT_NAME=Module2', '-s', 'SEPARATE_ASM_MODULE_NAME=ModuleForPage2["asm"]']
print(cmd)
subprocess.check_call(cmd)

self.run_browser('main.html', None, '/report_result?1')

# Tests that it is possible to encapsulate asm.js compiled programs by using --separate-asm + MODULARIZE=1. See
# encapsulated_asmjs_page_load.html for the example.
@no_wasm_backend('this tests asm.js support')
def test_encapsulated_asmjs_page_load(self):
html_file = open('main.html', 'w')
html_file.write(open(path_from_root('tests', 'encapsulated_asmjs_page_load.html')).read().replace('localhost:8888', 'localhost:%s' % self.port))
html_file.close()

cmd = [EMCC, path_from_root('tests', 'modularize_separate_asm.c'), '-o', 'a.js', '-s', 'WASM=0', '--separate-asm', '-s', 'MODULARIZE=1', '-s', 'EXPORT_NAME=EmscriptenCode', '-s', 'SEPARATE_ASM_MODULE_NAME="var EmscriptenCode"']
print(cmd)
subprocess.check_call(cmd)

self.run_browser('main.html', None, '/report_result?1')

@no_wasm_backend('MINIMAL_RUNTIME not yet available in Wasm backend')
def test_no_declare_asm_module_exports_asmjs(self):
for minimal_runtime in [[], ['-s', 'MINIMAL_RUNTIME=1']]:
self.btest(path_from_root('tests', 'declare_asm_module_exports.cpp'), '1', args=['-s', 'DECLARE_ASM_MODULE_EXPORTS=0', '-s', 'ENVIRONMENT=web', '-O3', '--closure', '1', '-s', 'WASM=0'] + minimal_runtime)
Expand Down
7 changes: 0 additions & 7 deletions tools/building.py
Original file line number Diff line number Diff line change
Expand Up @@ -870,13 +870,6 @@ def can_inline():
return Settings.INLINING_LIMIT == 0


def need_asm_js_file():
# Explicitly separate asm.js requires it
if Settings.SEPARATE_ASM:
return True
return False


def is_wasm_only():
# not even wasm, much less wasm-only
if not Settings.WASM:
Expand Down
4 changes: 0 additions & 4 deletions tools/minimal_runtime_shell.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,6 @@ def generate_minimal_runtime_load_statement(target_basename):
then_statements += ["Module.mem = r[%d];" % len(files_to_load)]
files_to_load += ["binary('%s')" % (target_basename + '.mem')]

# Download separate .asm.fs file when building with --separate-asm
if shared.Settings.SEPARATE_ASM:
files_to_load += ["script('%s')" % (target_basename + '.asm.js')]

# Download .wasm file
if shared.Settings.WASM == 1 or not download_wasm:
if shared.Settings.MODULARIZE:
Expand Down

0 comments on commit c6212ef

Please sign in to comment.