Skip to content

Commit 1e42813

Browse files
author
marco trivellato
committed
Merge tag '1.37.2' of https://github.com/kripken/emscripten into 1.37.2-unity
2 parents 1920599 + 4517555 commit 1e42813

34 files changed

+1091
-591
lines changed

AUTHORS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,3 +272,5 @@ a license to everyone to use it as detailed in LICENSE.)
272272
* Christophe Gragnic <[email protected]>
273273
* Murphy McCauley <[email protected]>
274274
* Anatoly Trosinenko <[email protected]>
275+
* Brad Grantham <[email protected]>
276+

emcc.py

Lines changed: 37 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1255,6 +1255,11 @@ def check(input_file):
12551255
os.environ['EMCC_WASM_BACKEND_BINARYEN'] = '1'
12561256

12571257
if shared.Settings.BINARYEN:
1258+
# set file locations, so that JS glue can find what it needs
1259+
shared.Settings.WASM_TEXT_FILE = os.path.basename(wasm_text_target)
1260+
shared.Settings.WASM_BINARY_FILE = os.path.basename(wasm_binary_target)
1261+
shared.Settings.ASMJS_CODE_FILE = os.path.basename(asm_target)
1262+
12581263
shared.Settings.ASM_JS = 2 # when targeting wasm, we use a wasm Memory, but that is not compatible with asm.js opts
12591264
debug_level = max(1, debug_level) # keep whitespace readable, for asm.js parser simplicity
12601265
shared.Settings.GLOBAL_BASE = 1024 # leave some room for mapping global vars
@@ -1282,6 +1287,20 @@ def check(input_file):
12821287
if shared.Building.is_wasm_only() and shared.Settings.EVAL_CTORS:
12831288
logging.debug('disabling EVAL_CTORS, as in wasm-only mode it hurts more than it helps. TODO: a wasm version of it')
12841289
shared.Settings.EVAL_CTORS = 0
1290+
# enable async compilation if optimizing and not turned off manually
1291+
if opt_level > 0:
1292+
if 'BINARYEN_ASYNC_COMPILATION=0' not in settings_changes:
1293+
shared.Settings.BINARYEN_ASYNC_COMPILATION = 1
1294+
if shared.Settings.BINARYEN_ASYNC_COMPILATION == 1:
1295+
if shared.Building.is_wasm_only():
1296+
# async compilation requires a swappable module - we swap it in when it's ready
1297+
shared.Settings.SWAPPABLE_ASM_MODULE = 1
1298+
else:
1299+
# if not wasm-only, we can't do async compilation as the build can run in other
1300+
# modes than wasm (like asm.js) which may not support an async step
1301+
shared.Settings.BINARYEN_ASYNC_COMPILATION = 0
1302+
if 'BINARYEN_ASYNC_COMPILATION=1' in settings_changes:
1303+
logging.warning('BINARYEN_ASYNC_COMPILATION requested, but disabled since not in wasm-only mode')
12851304

12861305
# wasm outputs are only possible with a side wasm
12871306
if target.endswith(WASM_ENDINGS):
@@ -1643,9 +1662,11 @@ def save_intermediate(name=None, suffix='js'):
16431662
if DEBUG: save_intermediate('original')
16441663

16451664
if shared.Settings.WASM_BACKEND:
1646-
# we also received wasm at this stage
1647-
wasm_temp = final[:-3] + '.wast'
1648-
shutil.move(wasm_temp, wasm_text_target)
1665+
# we also received wast and wasm at this stage
1666+
temp_basename = final[:-3]
1667+
wast_temp = temp_basename + '.wast'
1668+
shutil.move(wast_temp, wasm_text_target)
1669+
shutil.move(temp_basename + '.wasm', wasm_binary_target)
16491670
open(wasm_text_target + '.mappedGlobals', 'w').write('{}') # no need for mapped globals for now, but perhaps some day
16501671

16511672
if shared.Settings.CYBERDWARF:
@@ -1685,20 +1706,6 @@ def save_intermediate(name=None, suffix='js'):
16851706
file_code = execute([shared.PYTHON, shared.FILE_PACKAGER, unsuffixed(target) + '.data'] + file_args, stdout=PIPE)[0]
16861707
pre_js = file_code + pre_js
16871708

1688-
if shared.Settings.BINARYEN:
1689-
# add in the glue integration code as a pre-js, so it is optimized together with everything else
1690-
wasm_js_glue = open(os.path.join(shared.Settings.BINARYEN_ROOT, 'src', 'js', 'wasm.js-post.js')).read()
1691-
wasm_js_glue = wasm_js_glue.replace('{{{ asmjsCodeFile }}}', '"' + os.path.basename(asm_target) + '"')
1692-
wasm_js_glue = wasm_js_glue.replace('{{{ wasmTextFile }}}', '"' + os.path.basename(wasm_text_target) + '"')
1693-
wasm_js_glue = wasm_js_glue.replace('{{{ wasmBinaryFile }}}', '"' + os.path.basename(wasm_binary_target) + '"')
1694-
if shared.Settings.BINARYEN_METHOD:
1695-
wasm_js_glue = wasm_js_glue.replace('{{{ wasmJSMethod }}}', '(Module[\'wasmJSMethod\'] || "' + shared.Settings.BINARYEN_METHOD + '")')
1696-
else:
1697-
wasm_js_glue = wasm_js_glue.replace('{{{ wasmJSMethod }}}', 'null')
1698-
wasm_js_glue = wasm_js_glue.replace('{{{ WASM_BACKEND }}}', str(shared.Settings.WASM_BACKEND)) # if wasm backend, wasm contains memory segments
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
1701-
17021709
# Apply pre and postjs files
17031710
if pre_js or post_module or post_js:
17041711
logging.debug('applying pre/postjses')
@@ -2060,10 +2067,8 @@ def do_minify(): # minifies the code. this is also when we do certain optimizati
20602067
# Separate out the asm.js code, if asked. Or, if necessary for another option
20612068
if (separate_asm or shared.Settings.BINARYEN) and not shared.Settings.WASM_BACKEND:
20622069
logging.debug('separating asm')
2063-
with misc_temp_files.get_file(suffix='.js') as temp_target:
2064-
subprocess.check_call([shared.PYTHON, shared.path_from_root('tools', 'separate_asm.py'), js_target, asm_target, temp_target])
2065-
generated_text_files_with_native_eols += [asm_target]
2066-
shutil.move(temp_target, js_target)
2070+
subprocess.check_call([shared.PYTHON, shared.path_from_root('tools', 'separate_asm.py'), js_target, asm_target, js_target])
2071+
generated_text_files_with_native_eols += [asm_target]
20672072

20682073
# extra only-my-code logic
20692074
if shared.Settings.ONLY_MY_CODE:
@@ -2121,26 +2126,27 @@ def do_minify(): # minifies the code. this is also when we do certain optimizati
21212126
cmd += ['--mem-max=' + str(shared.Settings.BINARYEN_MEM_MAX)]
21222127
if shared.Building.is_wasm_only():
21232128
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
2129+
if debug_level >= 2 or profiling_funcs:
2130+
cmd += ['-g']
2131+
if emit_symbol_map or shared.Settings.CYBERDWARF:
2132+
cmd += ['--symbolmap=' + target + '.symbols']
2133+
cmd += ['-o', wasm_binary_target]
21242134
logging.debug('asm2wasm (asm.js => WebAssembly): ' + ' '.join(cmd))
21252135
TimeLogger.update()
2126-
subprocess.check_call(cmd, stdout=open(wasm_text_target, 'w'))
2136+
subprocess.check_call(cmd)
21272137
if import_mem_init:
21282138
# remove and forget about the mem init file in later processing; it does not need to be prefetched in the html, etc.
21292139
os.unlink(memfile)
21302140
memory_init_file = False
21312141
log_time('asm2wasm')
21322142
if shared.Settings.BINARYEN_PASSES:
2133-
shutil.move(wasm_text_target, wasm_text_target + '.pre')
2134-
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(','))
2143+
shutil.move(wasm_binary_target, wasm_binary_target + '.pre')
2144+
cmd = [os.path.join(binaryen_bin, 'wasm-opt'), wasm_binary_target + '.pre', '-o', wasm_binary_target] + map(lambda p: '--' + p, shared.Settings.BINARYEN_PASSES.split(','))
21352145
logging.debug('wasm-opt on BINARYEN_PASSES: ' + ' '.join(cmd))
21362146
subprocess.check_call(cmd)
2137-
if 'native-wasm' in shared.Settings.BINARYEN_METHOD or 'interpret-binary' in shared.Settings.BINARYEN_METHOD:
2138-
cmd = [os.path.join(binaryen_bin, 'wasm-as'), wasm_text_target, '-o', wasm_binary_target]
2139-
if debug_level >= 2 or profiling_funcs:
2140-
cmd += ['-g']
2141-
if emit_symbol_map or shared.Settings.CYBERDWARF:
2142-
cmd += ['--symbolmap=' + target + '.symbols']
2143-
logging.debug('wasm-as (text => binary): ' + ' '.join(cmd))
2147+
if 'interpret-s-expr' in shared.Settings.BINARYEN_METHOD:
2148+
cmd = [os.path.join(binaryen_bin, 'wasm-dis'), wasm_binary_target, '-o', wasm_text_target]
2149+
logging.debug('wasm-dis (binary => text): ' + ' '.join(cmd))
21442150
subprocess.check_call(cmd)
21452151
if shared.Settings.BINARYEN_SCRIPTS:
21462152
binaryen_scripts = os.path.join(shared.Settings.BINARYEN_ROOT, 'scripts')

emscripten-version.txt

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

emscripten.py

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1405,7 +1405,8 @@ def emscript_wasm_backend(infile, settings, outfile, libraries=None, compiler_en
14051405
shutil.copyfile(temp_s, os.path.join(shared.CANONICAL_TEMP_DIR, 'emcc-llvm-backend-output.s'))
14061406

14071407
assert shared.Settings.BINARYEN_ROOT, 'need BINARYEN_ROOT config set so we can use Binaryen s2wasm on the backend output'
1408-
wasm = outfile.name[:-3] + '.wast'
1408+
basename = outfile.name[:-3]
1409+
wast = basename + '.wast'
14091410
s2wasm_args = [os.path.join(shared.Settings.BINARYEN_ROOT, 'bin', 's2wasm'), temp_s]
14101411
s2wasm_args += ['--emscripten-glue']
14111412
s2wasm_args += ['--global-base=%d' % shared.Settings.GLOBAL_BASE]
@@ -1418,21 +1419,26 @@ def compiler_rt_fail(): raise Exception('Expected wasm_compiler_rt.a to already
14181419
logging.debug('emscript: binaryen s2wasm: ' + ' '.join(s2wasm_args))
14191420
t = time.time()
14201421
#s2wasm_args += ['--debug']
1421-
shared.check_call(s2wasm_args, stdout=open(wasm, 'w'))
1422+
shared.check_call(s2wasm_args, stdout=open(wast, 'w'))
1423+
# Also convert wasm text to binary
1424+
wasm_as_args = [os.path.join(shared.Settings.BINARYEN_ROOT, 'bin', 'wasm-as'),
1425+
wast, '-o', basename + '.wasm']
1426+
logging.debug(' emscript: binaryen wasm-as: ' + ' '.join(wasm_as_args))
1427+
shared.check_call(wasm_as_args)
14221428

14231429
if DEBUG:
14241430
logging.debug(' emscript: binaryen s2wasm took %s seconds' % (time.time() - t))
14251431
t = time.time()
14261432
import shutil
1427-
shutil.copyfile(wasm, os.path.join(shared.CANONICAL_TEMP_DIR, 'emcc-s2wasm-output.wast'))
1433+
shutil.copyfile(wast, os.path.join(shared.CANONICAL_TEMP_DIR, 'emcc-s2wasm-output.wast'))
14281434

14291435
# js compiler
14301436

14311437
if DEBUG: logging.debug('emscript: js compiler glue')
14321438

14331439
# Integrate info from backend
14341440

1435-
output = open(wasm).read()
1441+
output = open(wast).read()
14361442
parts = output.split('\n;; METADATA:')
14371443
assert len(parts) == 2
14381444
metadata_raw = parts[1]
@@ -1468,7 +1474,7 @@ def asmjs_mangle(name):
14681474
metadata['initializers'] = [asmjs_mangle(i) for i in metadata['initializers']]
14691475

14701476
# TODO: emit it from s2wasm; for now, we parse it right here
1471-
for line in open(wasm).readlines():
1477+
for line in open(wast).readlines():
14721478
if line.startswith(' (import '):
14731479
parts = line.split()
14741480
# Don't include Invoke wrapper names (for asm.js-style exception handling)
@@ -1635,7 +1641,7 @@ def math_fix(g):
16351641

16361642
# Asm.js-style exception handling: invoke wrapper generation
16371643
invoke_wrappers = ''
1638-
with open(wasm) as f:
1644+
with open(wast) as f:
16391645
for line in f:
16401646
if line.startswith(' (import '):
16411647
parts = line.split()

site/source/docs/porting/multimedia_and_graphics/OpenGL-support.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ In this mode (``-s LEGACY_GL_EMULATION=1``), there are a few extra flags that ca
6363
What if my codebase depends on an desktop OpenGL feature that is currently unsupported?
6464
---------------------------------------------------------------------------------------
6565

66-
You can consider building the codebase against the `Regal <https://github.com/p3/regal>`_ Desktop OpenGL emulation library. That project offers a more complete set of emulated Desktop OpenGL features on top of OpenGL ES 2.0. If the built-in Desktop OpenGL emulation works but is too slow, it may also be possible to get better performance by using Regal.
66+
You can consider building the codebase against the `Regal <https://github.com/p3/regal>`_ Desktop OpenGL emulation library, which aims to support Desktop OpenGL features on top of OpenGL ES 2.0. This may work better or worse than Emscripten's GL emulation depending on the project.
6767

6868
OpenGL ES extensions
6969
====================
@@ -86,4 +86,4 @@ The Emscripten :ref:`bug tracker <bug-reports>` has labels specific to OpenGL an
8686

8787
**Footnotes:**
8888

89-
.. [#f1] Client-side arrays are missing from WebGL because they are less efficient than properly using GPU-side data.
89+
.. [#f1] Client-side arrays are missing from WebGL because they are less efficient than properly using GPU-side data.

src/Fetch.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -478,7 +478,7 @@ function emscripten_start_fetch(fetch, successcb, errorcb, progresscb) {
478478
#if FETCH_DEBUG
479479
console.log('fetch: operation success. e: ' + e);
480480
#endif
481-
if (onsuccess && Runtime.dynCall) Runtime.dynCall('vi', onsuccess, [fetch]);
481+
if (onsuccess && Runtime.dynCall) Module['dynCall_vi'](onsuccess, fetch);
482482
else if (successcb) successcb(fetch);
483483
};
484484

@@ -497,20 +497,20 @@ function emscripten_start_fetch(fetch, successcb, errorcb, progresscb) {
497497
#endif
498498
};
499499
__emscripten_fetch_cache_data(Fetch.dbInstance, fetch, xhr.response, storeSuccess, storeError);
500-
if (onsuccess && Runtime.dynCall) Runtime.dynCall('vi', onsuccess, [fetch]);
500+
if (onsuccess && Runtime.dynCall) Module['dynCall_vi'](onsuccess, fetch);
501501
else if (successcb) successcb(fetch);
502502
};
503503

504504
var reportProgress = function(fetch, xhr, e) {
505-
if (onprogress && Runtime.dynCall) Runtime.dynCall('vi', onprogress, [fetch]);
505+
if (onprogress && Runtime.dynCall) Module['dynCall_vi'](onprogress, fetch);
506506
else if (progresscb) progresscb(fetch);
507507
};
508508

509509
var reportError = function(fetch, xhr, e) {
510510
#if FETCH_DEBUG
511511
console.error('fetch: operation failed: ' + e);
512512
#endif
513-
if (onerror && Runtime.dynCall) Runtime.dynCall('vi', onerror, [fetch]);
513+
if (onerror && Runtime.dynCall) Module['dynCall_vi'](onerror, fetch);
514514
else if (errorcb) errorcb(fetch);
515515
};
516516

src/deps_info.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
"realloc": ["malloc", "free"],
1111
"getlogin": ["malloc"],
1212
"tmpnam": ["malloc"],
13-
"mmap": ["malloc"],
13+
"mmap": ["memalign"],
1414
"realpath": ["malloc"],
1515
"strerror": ["malloc"],
1616
"__ctype_b_loc": ["malloc"],

src/library.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -951,15 +951,15 @@ LibraryManager.library = {
951951
llvm_ctlz_i8: function(x, isZeroUndef) {
952952
x = x | 0;
953953
isZeroUndef = isZeroUndef | 0;
954-
return (Math_clz32(x) | 0) - 24 | 0;
954+
return (Math_clz32(x & 0xff) | 0) - 24 | 0;
955955
},
956956

957957
llvm_ctlz_i16__asm: true,
958958
llvm_ctlz_i16__sig: 'ii',
959959
llvm_ctlz_i16: function(x, isZeroUndef) {
960960
x = x | 0;
961961
isZeroUndef = isZeroUndef | 0;
962-
return (Math_clz32(x) | 0) - 16 | 0
962+
return (Math_clz32(x & 0xffff) | 0) - 16 | 0
963963
},
964964

965965
llvm_ctlz_i64__asm: true,
@@ -1092,10 +1092,10 @@ LibraryManager.library = {
10921092
if (info.refcount === 0 && !info.rethrown) {
10931093
if (info.destructor) {
10941094
#if WASM_BACKEND == 0
1095-
Runtime.dynCall('vi', info.destructor, [ptr]);
1095+
Module['dynCall_vi'](info.destructor, ptr);
10961096
#else
10971097
// In Wasm, destructors return 'this' as in ARM
1098-
Runtime.dynCall('ii', info.destructor, [ptr]);
1098+
Module['dynCall_ii'](info.destructor, ptr);
10991099
#endif
11001100
}
11011101
delete EXCEPTIONS.infos[ptr];
@@ -4192,7 +4192,7 @@ LibraryManager.library = {
41924192
var trace = _emscripten_get_callstack_js();
41934193
var parts = trace.split('\n');
41944194
for (var i = 0; i < parts.length; i++) {
4195-
var ret = Runtime.dynCall('iii', [0, arg]);
4195+
var ret = Module['dynCall_iii'](func, 0, arg);
41964196
if (ret !== 0) return;
41974197
}
41984198
},

src/library_async.js

Lines changed: 78 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,31 @@ mergeInto(LibraryManager.library, {
189189
emscripten_yield__asm: true,
190190
emscripten_yield: function() {
191191
___async = 1;
192-
}
192+
},
193+
194+
emscripten_wget__deps: ['emscripten_async_resume', '$PATH', '$Browser'],
195+
emscripten_wget: function(url, file) {
196+
var _url = Pointer_stringify(url);
197+
var _file = Pointer_stringify(file);
198+
_file = PATH.resolve(FS.cwd(), _file);
199+
asm.setAsync();
200+
Module['noExitRuntime'] = true;
201+
var destinationDirectory = PATH.dirname(_file);
202+
FS.createPreloadedFile(
203+
destinationDirectory,
204+
PATH.basename(_file),
205+
_url, true, true,
206+
_emscripten_async_resume,
207+
_emscripten_async_resume,
208+
undefined, // dontCreateFile
209+
undefined, // canOwn
210+
function() { // preFinish
211+
// if the destination directory does not yet exist, create it
212+
FS.mkdirTree(destinationDirectory);
213+
}
214+
);
215+
},
216+
193217
#else // ASYNCIFY
194218

195219
#if EMTERPRETIFY_ASYNC
@@ -344,12 +368,53 @@ mergeInto(LibraryManager.library, {
344368
}, true);
345369
},
346370

347-
#else
371+
emscripten_wget__deps: ['$EmterpreterAsync', '$PATH', '$FS', '$Browser'],
372+
emscripten_wget: function(url, file) {
373+
EmterpreterAsync.handle(function(resume) {
374+
var _url = Pointer_stringify(url);
375+
var _file = Pointer_stringify(file);
376+
_file = PATH.resolve(FS.cwd(), _file);
377+
var destinationDirectory = PATH.dirname(_file);
378+
FS.createPreloadedFile(
379+
destinationDirectory,
380+
PATH.basename(_file),
381+
_url, true, true,
382+
resume,
383+
resume,
384+
undefined, // dontCreateFile
385+
undefined, // canOwn
386+
function() { // preFinish
387+
// if the destination directory does not yet exist, create it
388+
FS.mkdirTree(destinationDirectory);
389+
}
390+
);
391+
});
392+
},
393+
394+
emscripten_wget_data__deps: ['$EmterpreterAsync', '$Browser'],
395+
emscripten_wget_data: function(url, pbuffer, pnum, perror) {
396+
EmterpreterAsync.handle(function(resume) {
397+
Browser.asyncLoad(Pointer_stringify(url), function(byteArray) {
398+
resume(function() {
399+
// can only allocate the buffer after the resume, not during an asyncing
400+
var buffer = _malloc(byteArray.length); // must be freed by caller!
401+
HEAPU8.set(byteArray, buffer);
402+
{{{ makeSetValueAsm('pbuffer', 0, 'buffer', 'i32') }}};
403+
{{{ makeSetValueAsm('pnum', 0, 'byteArray.length', 'i32') }}};
404+
{{{ makeSetValueAsm('perror', 0, '0', 'i32') }}};
405+
});
406+
}, function() {
407+
{{{ makeSetValueAsm('perror', 0, '1', 'i32') }}};
408+
resume();
409+
}, true /* no need for run dependency, this is async but will not do any prepare etc. step */ );
410+
});
411+
},
412+
413+
#else // EMTERPRETIFY_ASYNC
414+
348415
emscripten_sleep: function() {
349416
throw 'Please compile your program with async support in order to use asynchronous operations like emscripten_sleep';
350417
},
351-
#endif
352-
353418
emscripten_coroutine_create: function() {
354419
throw 'Please compile your program with async support in order to use asynchronous operations like emscripten_coroutine_create';
355420
},
@@ -358,7 +423,14 @@ mergeInto(LibraryManager.library, {
358423
},
359424
emscripten_yield: function() {
360425
throw 'Please compile your program with async support in order to use asynchronous operations like emscripten_yield';
361-
}
362-
#endif
426+
},
427+
emscripten_wget: function(url, file) {
428+
throw 'Please compile your program with async support in order to use asynchronous operations like emscripten_wget';
429+
},
430+
emscripten_wget_data: function(url, file) {
431+
throw 'Please compile your program with async support in order to use asynchronous operations like emscripten_wget_data';
432+
},
433+
#endif // EMTERPRETIFY_ASYNC
434+
#endif // ASYNCIFY
363435
});
364436

0 commit comments

Comments
 (0)