Skip to content

Commit 1920599

Browse files
committed
Merge branch 'incoming' of https://github.com/kripken/emscripten into 1.37.1-unity
2 parents 769087b + 62dfd0f commit 1920599

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

78 files changed

+23228
-13834
lines changed

AUTHORS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,3 +269,6 @@ a license to everyone to use it as detailed in LICENSE.)
269269
* Vilibald Wanča <[email protected]>
270270
* Alex Hixon <[email protected]>
271271
* Vladimir Davidovich <[email protected]>
272+
* Christophe Gragnic <[email protected]>
273+
* Murphy McCauley <[email protected]>
274+
* Anatoly Trosinenko <[email protected]>

emcc.py

Lines changed: 61 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
LIB_PREFIXES = ('', 'lib')
5757

5858
JS_CONTAINING_SUFFIXES = ('js', 'html')
59+
EXECUTABLE_SUFFIXES = JS_CONTAINING_SUFFIXES + ('wasm',)
5960

6061
DEFERRED_REPONSE_FILES = ('EMTERPRETIFY_BLACKLIST', 'EMTERPRETIFY_WHITELIST')
6162

@@ -354,10 +355,6 @@ def uniquename(name):
354355
sys.argv = sys.argv[:i] + sys.argv[i+2:]
355356
break
356357

357-
if target and target.endswith(WASM_ENDINGS):
358-
logging.warning('output file "%s" has a wasm suffix, but we cannot emit wasm by itself. specify an output file with suffix .js or .html, and a wasm file will be created on the side' % target)
359-
sys.exit(1)
360-
361358
specified_target = target
362359
target = specified_target if specified_target is not None else 'a.out.js' # specified_target is the user-specified one, target is what we will generate
363360
target_basename = unsuffixed_basename(target)
@@ -440,8 +437,9 @@ def log_time(name):
440437
default_cxx_std = '-std=c++03' # Enforce a consistent C++ standard when compiling .cpp files, if user does not specify one on the cmdline.
441438
use_closure_compiler = None
442439
js_transform = None
443-
pre_js = ''
444-
post_js = ''
440+
pre_js = '' # before all js
441+
post_module = '' # in js, after Module exists
442+
post_js = '' # after all js
445443
preload_files = []
446444
embed_files = []
447445
exclude_files = []
@@ -1098,7 +1096,7 @@ def check(input_file):
10981096
shared.Settings.INCLUDE_FULL_LIBRARY = 1
10991097
elif shared.Settings.SIDE_MODULE:
11001098
assert not shared.Settings.MAIN_MODULE
1101-
memory_init_file = False # memory init file is not supported with side modules, must be executable synchronously (for dlopen)
1099+
memory_init_file = False # memory init file is not supported with asm.js side modules, must be executable synchronously (for dlopen)
11021100

11031101
if shared.Settings.MAIN_MODULE or shared.Settings.SIDE_MODULE:
11041102
assert shared.Settings.ASM_JS, 'module linking requires asm.js output (-s ASM_JS=1)'
@@ -1138,6 +1136,21 @@ def check(input_file):
11381136
# stb_image 2.x need to have STB_IMAGE_IMPLEMENTATION defined to include the implementation when compiling
11391137
newargs.append('-DSTB_IMAGE_IMPLEMENTATION')
11401138

1139+
if shared.Settings.ASMFS and final_suffix in JS_CONTAINING_SUFFIXES:
1140+
input_files.append((next_arg_index, shared.path_from_root('system', 'lib', 'fetch', 'asmfs.cpp')))
1141+
newargs.append('-D__EMSCRIPTEN_ASMFS__=1')
1142+
next_arg_index += 1
1143+
shared.Settings.NO_FILESYSTEM = 1
1144+
shared.Settings.FETCH = 1
1145+
if not shared.Settings.USE_PTHREADS:
1146+
logging.error('-s ASMFS=1 requires either -s USE_PTHREADS=1 or -s USE_PTHREADS=2 to be set!')
1147+
sys.exit(1)
1148+
1149+
if shared.Settings.FETCH and final_suffix in JS_CONTAINING_SUFFIXES:
1150+
input_files.append((next_arg_index, shared.path_from_root('system', 'lib', 'fetch', 'emscripten_fetch.cpp')))
1151+
next_arg_index += 1
1152+
js_libraries.append(shared.path_from_root('src', 'library_fetch.js'))
1153+
11411154
forced_stdlibs = []
11421155
if shared.Settings.DEMANGLE_SUPPORT:
11431156
shared.Settings.EXPORTED_FUNCTIONS += ['___cxa_demangle']
@@ -1226,11 +1239,6 @@ def check(input_file):
12261239
js_opts = True
12271240
force_js_opts = True
12281241

1229-
if shared.Settings.EVAL_CTORS:
1230-
# this option is not a js optimizer pass, but does run the js optimizer internally, so
1231-
# we need to generate proper code for that
1232-
shared.Settings.RUNNING_JS_OPTS = 1
1233-
12341242
if shared.Settings.WASM:
12351243
shared.Settings.BINARYEN = 1 # these are synonyms
12361244

@@ -1251,7 +1259,7 @@ def check(input_file):
12511259
debug_level = max(1, debug_level) # keep whitespace readable, for asm.js parser simplicity
12521260
shared.Settings.GLOBAL_BASE = 1024 # leave some room for mapping global vars
12531261
assert not shared.Settings.SPLIT_MEMORY, 'WebAssembly does not support split memory'
1254-
assert not shared.Settings.INCLUDE_FULL_LIBRARY, 'The WebAssembly libc overlaps with JS libs, so INCLUDE_FULL_LIBRARY does not just work (FIXME)'
1262+
assert not shared.Settings.USE_PTHREADS, 'WebAssembly does not support pthreads'
12551263
# if root was not specified in -s, it might be fixed in ~/.emscripten, copy from there
12561264
if not shared.Settings.BINARYEN_ROOT:
12571265
try:
@@ -1271,6 +1279,20 @@ def check(input_file):
12711279
# * if we also supported js mem inits we'd have 4 modes
12721280
# * and js mem inits are useful for avoiding a side file, but the wasm module avoids that anyhow
12731281
memory_init_file = True
1282+
if shared.Building.is_wasm_only() and shared.Settings.EVAL_CTORS:
1283+
logging.debug('disabling EVAL_CTORS, as in wasm-only mode it hurts more than it helps. TODO: a wasm version of it')
1284+
shared.Settings.EVAL_CTORS = 0
1285+
1286+
# wasm outputs are only possible with a side wasm
1287+
if target.endswith(WASM_ENDINGS):
1288+
if not (shared.Settings.BINARYEN and shared.Settings.SIDE_MODULE):
1289+
logging.warning('output file "%s" has a wasm suffix, but we cannot emit wasm by itself, except as a dynamic library (see SIDE_MODULE option). specify an output file with suffix .js or .html, and a wasm file will be created on the side' % target)
1290+
sys.exit(1)
1291+
1292+
if shared.Settings.EVAL_CTORS:
1293+
# this option is not a js optimizer pass, but does run the js optimizer internally, so
1294+
# we need to generate proper code for that
1295+
shared.Settings.RUNNING_JS_OPTS = 1
12741296

12751297
if shared.Settings.ALLOW_MEMORY_GROWTH and shared.Settings.ASM_JS == 1:
12761298
# this is an issue in asm.js, but not wasm
@@ -1437,7 +1459,7 @@ def compile_source_file(i, input_file):
14371459
linker_inputs = [val for _, val in sorted(temp_files + link_flags)]
14381460

14391461
# If we were just asked to generate bitcode, stop there
1440-
if final_suffix not in JS_CONTAINING_SUFFIXES:
1462+
if final_suffix not in EXECUTABLE_SUFFIXES:
14411463
if not specified_target:
14421464
assert len(temp_files) == len(input_files)
14431465
for i in range(len(input_files)):
@@ -1674,12 +1696,15 @@ def save_intermediate(name=None, suffix='js'):
16741696
else:
16751697
wasm_js_glue = wasm_js_glue.replace('{{{ wasmJSMethod }}}', 'null')
16761698
wasm_js_glue = wasm_js_glue.replace('{{{ WASM_BACKEND }}}', str(shared.Settings.WASM_BACKEND)) # if wasm backend, wasm contains memory segments
1677-
pre_js = wasm_js_glue + '\n' + pre_js
1699+
wasm_js_glue += '\nintegrateWasmJS(Module);\n' # add a call
1700+
post_module += str(wasm_js_glue) # we can set up the glue once we have the module
16781701

16791702
# Apply pre and postjs files
1680-
if pre_js or post_js:
1703+
if pre_js or post_module or post_js:
16811704
logging.debug('applying pre/postjses')
16821705
src = open(final).read()
1706+
if post_module:
1707+
src = src.replace('// {{PREAMBLE_ADDITIONS}}', post_module + '\n// {{PREAMBLE_ADDITIONS}}')
16831708
final += '.pp.js'
16841709
if WINDOWS: # Avoid duplicating \r\n to \r\r\n when writing out.
16851710
if pre_js: pre_js = pre_js.replace('\r\n', '\n')
@@ -1754,12 +1779,9 @@ def repl(m):
17541779
if shared.Settings.USE_PTHREADS:
17551780
shutil.copyfile(shared.path_from_root('src', 'pthread-main.js'), os.path.join(os.path.dirname(os.path.abspath(target)), 'pthread-main.js'))
17561781

1757-
if shared.Settings.BINARYEN:
1758-
# Insert a call to integrate with wasm.js
1759-
js = open(final).read()
1760-
js = js.replace('// {{PREAMBLE_ADDITIONS}}', 'integrateWasmJS(Module);\n// {{PREAMBLE_ADDITIONS}}')
1761-
final += '.binaryen.js'
1762-
open(final, 'w').write(js)
1782+
# Generate the fetch-worker.js script for multithreaded emscripten_fetch() support if targeting pthreads.
1783+
if shared.Settings.FETCH and shared.Settings.USE_PTHREADS:
1784+
shared.make_fetch_worker(final, os.path.join(os.path.dirname(os.path.abspath(target)), 'fetch-worker.js'))
17631785

17641786
# exit block 'memory initializer'
17651787
log_time('memory initializer')
@@ -2090,18 +2112,23 @@ def do_minify(): # minifies the code. this is also when we do certain optimizati
20902112
cmd += ['--mem-init=' + memfile]
20912113
if not shared.Settings.RELOCATABLE:
20922114
cmd += ['--mem-base=' + str(shared.Settings.GLOBAL_BASE)]
2093-
if shared.Settings.BINARYEN_MEM_MAX >= 0:
2115+
# various options imply that the imported table may not be the exact size as the wasm module's own table segments
2116+
if shared.Settings.RELOCATABLE or shared.Settings.RESERVED_FUNCTION_POINTERS > 0 or shared.Settings.EMULATED_FUNCTION_POINTERS:
2117+
cmd += ['--table-max=-1']
2118+
if shared.Settings.SIDE_MODULE:
2119+
cmd += ['--mem-max=-1']
2120+
elif shared.Settings.BINARYEN_MEM_MAX >= 0:
20942121
cmd += ['--mem-max=' + str(shared.Settings.BINARYEN_MEM_MAX)]
20952122
if shared.Building.is_wasm_only():
20962123
cmd += ['--wasm-only'] # this asm.js is code not intended to run as asm.js, it is only ever going to be wasm, an can contain special fastcomp-wasm support
20972124
logging.debug('asm2wasm (asm.js => WebAssembly): ' + ' '.join(cmd))
20982125
TimeLogger.update()
20992126
subprocess.check_call(cmd, stdout=open(wasm_text_target, 'w'))
2100-
log_time('asm2wasm')
21012127
if import_mem_init:
21022128
# remove and forget about the mem init file in later processing; it does not need to be prefetched in the html, etc.
21032129
os.unlink(memfile)
21042130
memory_init_file = False
2131+
log_time('asm2wasm')
21052132
if shared.Settings.BINARYEN_PASSES:
21062133
shutil.move(wasm_text_target, wasm_text_target + '.pre')
21072134
cmd = [os.path.join(binaryen_bin, 'wasm-opt'), wasm_text_target + '.pre', '-o', wasm_text_target] + map(lambda p: '--' + p, shared.Settings.BINARYEN_PASSES.split(','))
@@ -2126,6 +2153,16 @@ def do_minify(): # minifies the code. this is also when we do certain optimizati
21262153
for script in shared.Settings.BINARYEN_SCRIPTS.split(','):
21272154
logging.debug('running binaryen script: ' + script)
21282155
subprocess.check_call([shared.PYTHON, os.path.join(binaryen_scripts, script), js_target, wasm_text_target], env=script_env)
2156+
# after generating the wasm, do some final operations
2157+
if not shared.Settings.WASM_BACKEND:
2158+
if shared.Settings.SIDE_MODULE:
2159+
wso = shared.WebAssembly.make_shared_library(js_target, wasm_binary_target)
2160+
# replace the wasm binary output with the dynamic library. TODO: use a specific suffix for such files?
2161+
shutil.move(wso, wasm_binary_target)
2162+
if not DEBUG:
2163+
os.unlink(js_target) # we don't need the js, it can just confuse
2164+
os.unlink(asm_target) # we don't need the asm.js, it can just confuse
2165+
sys.exit(0) # and we are done.
21292166

21302167
# If we were asked to also generate HTML, do that
21312168
if final_suffix == 'html':

emscripten-version.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
"1.37.0"
1+
"1.37.1"

0 commit comments

Comments
 (0)