Skip to content

Commit 19dca5d

Browse files
authored
Merge branch 'incoming' into minnum-maxnum-intrinsics
2 parents 3d67088 + 3d2272e commit 19dca5d

Some content is hidden

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

43 files changed

+2660
-169
lines changed

ChangeLog.markdown

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,14 @@ Not all changes are documented here. In particular, new features, user-oriented
99

1010
Current Trunk
1111
-------------
12+
- Breaking change: Don't export the `ALLOC_*` numeric constants by default. As with previous changes, a warning will be shown in `-O0` and when `ASSERTIONS` are on if they are used.
13+
- Breaking change: Don't export FS methods by default. As with previous changes, a warning will be shown in `-O0` and when `ASSERTIONS` are on, which will suggest either exporting the specific methods you need, or using `FORCE_FILESYSTEM` which will auto export all the main filesystem methods. Aside from using FS methods yourself, you may notice this change when using a file package created standalone, that is, by running the file packager directly and then loading it at run time (as opposed to telling `emcc` to package the files for you, in which case it would be aware of them at compile time); you should build with `FORCE_FILESYSTEM` to ensure filesystem support for that case.
14+
15+
v1.37.27: 12/24/2017
16+
--------------------
1217
- Breaking change: Remove the `Runtime` object, and move all the useful methods from it to simple top-level functions. Any usage of `Runtime.func` should be changed to `func`.
1318

14-
v1.37.26: 12/20/1027
19+
v1.37.26: 12/20/2017
1520
--------------------
1621
- Breaking change: Change `NO_EXIT_RUNTIME` to 1 by default. This means that by default we don't include code to shut down the runtime, flush stdio streams, run atexits, etc., which is better for code size. When `ASSERTIONS` is on, we warn at runtime if there is text buffered in the streams that should be flushed, or atexits are used.
1722
- Meta-DCE for JS+wasm: remove unused code between JS+wasm more aggressively. This should not break valid code, but may break code that depended on unused code being kept around (like using a function from outside the emitted JS without exporting it - only exported things are guaranteed to be kept alive through optimization).

emcc.py

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -909,7 +909,11 @@ def check(input_file):
909909
value = '"' + value + '"'
910910
else:
911911
value = value.replace('\\', '\\\\')
912-
setattr(shared.Settings, key, eval(value))
912+
try:
913+
setattr(shared.Settings, key, eval(value))
914+
except Exception as e:
915+
logging.error('a problem occurred in evaluating content after a "-s", specifically %s . one possible cause of this is missing quotation marks (this depends on the shell you are running in; you may need quotation marks around the entire %s , or on an individual element)' % (change, change))
916+
raise e
913917
if key == 'EXPORTED_FUNCTIONS':
914918
# used for warnings in emscripten.py
915919
shared.Settings.ORIGINAL_EXPORTED_FUNCTIONS = original_exported_response or shared.Settings.EXPORTED_FUNCTIONS[:]
@@ -979,6 +983,10 @@ def check(input_file):
979983
shared.Settings.RELOCATABLE = 1
980984
shared.Settings.PRECISE_I64_MATH = 1 # other might use precise math, we need to be able to print it
981985
assert not options.use_closure_compiler, 'cannot use closure compiler on shared modules'
986+
# getMemory is used during startup of shared modules (to allocate their static memory)
987+
shared.Settings.EXPORTED_RUNTIME_METHODS += [
988+
'getMemory',
989+
]
982990

983991
if shared.Settings.EMULATE_FUNCTION_POINTER_CASTS:
984992
shared.Settings.ALIASING_FUNCTION_POINTERS = 0
@@ -1092,6 +1100,25 @@ def check(input_file):
10921100
else:
10931101
options.js_libraries.append(shared.path_from_root('src', 'library_pthread_stub.js'))
10941102

1103+
if shared.Settings.FORCE_FILESYSTEM:
1104+
# when the filesystem is forced, we export by default methods that filesystem usage
1105+
# may need, including filesystem usage from standalone file packager output (i.e.
1106+
# file packages not built together with emcc, but that are loaded at runtime
1107+
# separately, and they need emcc's output to contain the support they need)
1108+
shared.Settings.EXPORTED_RUNTIME_METHODS += [
1109+
'FS_createFolder',
1110+
'FS_createPath',
1111+
'FS_createDataFile',
1112+
'FS_createPreloadedFile',
1113+
'FS_createLazyFile',
1114+
'FS_createLink',
1115+
'FS_createDevice',
1116+
'FS_unlink',
1117+
'getMemory',
1118+
'addRunDependency',
1119+
'removeRunDependency',
1120+
]
1121+
10951122
if shared.Settings.USE_PTHREADS:
10961123
if shared.Settings.LINKABLE:
10971124
exit_with_error('-s LINKABLE=1 is not supported with -s USE_PTHREADS>0!')

emscripten-version.txt

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

emscripten.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -644,6 +644,13 @@ def get_exported_implemented_functions(all_exported_functions, all_implemented,
644644
funcs += ['setTempRet0', 'getTempRet0']
645645
if not (settings['BINARYEN'] and settings['SIDE_MODULE']):
646646
funcs += ['setThrew']
647+
if settings['EMTERPRETIFY']:
648+
funcs += ['emterpret']
649+
if settings['EMTERPRETIFY_ASYNC']:
650+
funcs += ['setAsyncState', 'emtStackSave', 'emtStackRestore']
651+
if settings['ASYNCIFY']:
652+
funcs += ['setAsync']
653+
647654
return sorted(set(funcs))
648655

649656

@@ -1253,8 +1260,6 @@ def create_basic_vars(exported_implemented_functions, forwarded_json, metadata,
12531260
def create_exports(exported_implemented_functions, in_table, function_table_data, metadata, settings):
12541261
quote = quoter(settings)
12551262
asm_runtime_funcs = create_asm_runtime_funcs(settings)
1256-
if need_asyncify(exported_implemented_functions):
1257-
asm_runtime_funcs.append('setAsync')
12581263
all_exported = exported_implemented_functions + asm_runtime_funcs + function_tables(function_table_data, settings)
12591264
if settings['EMULATED_FUNCTION_POINTERS']:
12601265
all_exported += in_table
@@ -1281,10 +1286,6 @@ def create_asm_runtime_funcs(settings):
12811286
funcs += ['setDynamicTop']
12821287
if settings['ONLY_MY_CODE']:
12831288
funcs = []
1284-
if settings.get('EMTERPRETIFY'):
1285-
funcs += ['emterpret']
1286-
if settings.get('EMTERPRETIFY_ASYNC'):
1287-
funcs += ['setAsyncState', 'emtStackSave', 'emtStackRestore']
12881289
return funcs
12891290

12901291

site/source/docs/api_reference/module.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ Module object
88

99
Developers can provide an implementation of ``Module`` to control the execution of code. For example, to define how notification messages from Emscripten are displayed, developers implement the :js:attr:`Module.print` attribute.
1010

11-
.. note:: ``Module`` is also used to provide access to Emscripten API functions (for example :js:func:`ccall`) in a safe way. Any function or runtime method exported (using ``EXPORTED_FUNCTIONS`` for compiled functions, or ``EXTRA_EXPORTED_RUNTIME_METHODS`` for runtime methods like ``ccall``) will be accessible on the ``Module`` object, without minification changing the name, and the optimizer will make sure to keep the function present (and not remove it as unused).
11+
.. note:: ``Module`` is also used to provide access to Emscripten API functions (for example :js:func:`ccall`) in a safe way. Any function or runtime method exported (using ``EXPORTED_FUNCTIONS`` for compiled functions, or ``EXTRA_EXPORTED_RUNTIME_METHODS`` for runtime methods like ``ccall``) will be accessible on the ``Module`` object, without minification changing the name, and the optimizer will make sure to keep the function present (and not remove it as unused). See the :ref:`relevant FAQ entry<faq-export-stuff>`.
1212

1313
.. contents:: Table of Contents
1414
:local:

site/source/docs/getting_started/FAQ.rst

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -345,15 +345,51 @@ Emscripten by default does *not* give fatal errors on undefined symbols, so you
345345

346346
Aside from just forgetting to link in a necessary object file, one possible cause for this error is inline functions in headers. If you have a header with ``inline int my_func() { .. }`` then *Clang* may not actually inline the function (since inline is just a hint), and also not generate code for it (since it's in a header). The result is that the generated bitcode and JavaScript will not have that function implemented. One solution is to add ``static`` to the function declaration, which forces code to be generated in the object file: ``static inline int my_func() { .. }``.
347347

348+
.. _faq-export-stuff:
349+
348350
Why do I get ``TypeError: Module.someThing is not a function``?
349351
===============================================================
350352

351-
The ``Module`` object will contain exported methods. For something to appear there, you should add it to ``EXPORTED_FUNCTIONS`` for compiled code, or ``EXTRA_EXPORTED_RUNTIME_METHODS`` for a runtime method (like ``getValue``).
353+
The ``Module`` object will contain exported methods. For something to appear there, you should add it to ``EXPORTED_FUNCTIONS`` for compiled code, or ``EXTRA_EXPORTED_RUNTIME_METHODS`` for a runtime method (like ``getValue``). For example,
354+
355+
::
356+
357+
./emcc -s EXPORTED_FUNCTIONS="['_main', '_my_func']" ...
358+
359+
would export a C method ``my_func`` (in addition to ``main``, in this example). And
360+
361+
::
362+
363+
./emcc -s EXTRA_EXPORTED_RUNTIME_METHODS="['ccall']" ...
364+
365+
will export ``ccall``. In both cases you can then access the exported function on the ``Module`` object.
352366

353367
.. note:: You can use runtime methods directly, without exporting them, if the compiler can see them used. For example, you can use ``getValue`` in ``EM_ASM`` code, or a ``--pre-js``, by calling it directly. The optimizer will not remove that JS runtime method because it sees it is used. You only need to use ``Module.getValue`` if you want to call that method from outside the JS code the compiler can see, and then you need to export it.
354368

355369
.. note:: Emscripten used to export many runtime methods by default. This increased code size, and for that reason we've changed that default. If you depend on something that used to be exported, you should see a warning pointing you to the solution, in an unoptimized build, or a build with ``ASSERTIONS`` enabled, which we hope will minimize any annoyance. See ``Changelog.markdown`` for details.
356370

371+
Why do I get a ``NameError`` or ``a problem occurred in evaluating content after a "-s"`` when I use a ``-s`` option?
372+
========================================================
373+
374+
That may occur when running something like
375+
376+
::
377+
378+
# this fails on most Linuxes
379+
./emcc a.c -s EXTRA_EXPORTED_RUNTIME_METHODS=['addOnPostRun']
380+
381+
You may need quotation marks, such as
382+
383+
::
384+
385+
# this works on most Linuxes
386+
./emcc a.c -s "EXTRA_EXPORTED_RUNTIME_METHODS=['addOnPostRun']"
387+
388+
# also this should work
389+
./emcc a.c -s EXTRA_EXPORTED_RUNTIME_METHODS="['addOnPostRun']"
390+
391+
The proper syntax depends on the OS and shell you are in.
392+
357393
Why do I get an odd python error complaining about libcxx.bc or libcxxabi.bc?
358394
=============================================================================
359395

src/emscripten-source-map.min.js

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/headless.js

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -284,11 +284,13 @@ var screen = { // XXX these values may need to be adjusted
284284
availWidth: 2100,
285285
availHeight: 1283,
286286
};
287-
var console = {
288-
log: function(x) {
289-
print(x);
290-
},
291-
};
287+
if (typeof console === "undefined") {
288+
console = {
289+
log: function(x) {
290+
print(x);
291+
}
292+
};
293+
}
292294
var MozBlobBuilder = function() {
293295
this.data = new Uint8Array(0);
294296
this.append = function(buffer) {

src/library_async.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ mergeInto(LibraryManager.library, {
5454

5555
emscripten_sleep__deps: ['emscripten_async_resume', '$Browser'],
5656
emscripten_sleep: function(ms) {
57-
Module['asm'].setAsync(); // tell the scheduler that we have a callback on hold
57+
Module['setAsync'](); // tell the scheduler that we have a callback on hold
5858
Browser.safeSetTimeout(_emscripten_async_resume, ms);
5959
},
6060

@@ -196,7 +196,7 @@ mergeInto(LibraryManager.library, {
196196
var _url = Pointer_stringify(url);
197197
var _file = Pointer_stringify(file);
198198
_file = PATH.resolve(FS.cwd(), _file);
199-
Module['asm'].setAsync();
199+
Module['setAsync']();
200200
Module['noExitRuntime'] = true;
201201
var destinationDirectory = PATH.dirname(_file);
202202
FS.createPreloadedFile(
@@ -255,7 +255,7 @@ mergeInto(LibraryManager.library, {
255255
setState: function(s) {
256256
this.ensureInit();
257257
this.state = s;
258-
Module['asm'].setAsyncState(s);
258+
Module['setAsyncState'](s);
259259
},
260260
handle: function(doAsyncOp, yieldDuring) {
261261
Module['noExitRuntime'] = true;

src/library_fs.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ mergeInto(LibraryManager.library, {
1414
'__ATINIT__.unshift(function() { if (!Module["noFSInit"] && !FS.init.initialized) FS.init() });' +
1515
'__ATMAIN__.push(function() { FS.ignorePermissions = false });' +
1616
'__ATEXIT__.push(function() { FS.quit() });' +
17-
//Get module methods from settings
17+
// Get module methods from settings
1818
'{{{ EXPORTED_RUNTIME_METHODS.filter(function(func) { return func.substr(0, 3) === 'FS_' }).map(function(func){return 'Module["' + func + '"] = FS.' + func.substr(3) + ";"}).reduce(function(str, func){return str + func;}, '') }}}',
1919
$FS: {
2020
root: null,

src/modules.js

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -271,10 +271,38 @@ var EXPORTED_RUNTIME_METHODS_SET = set(EXPORTED_RUNTIME_METHODS.concat(EXTRA_EXP
271271
EXPORTED_RUNTIME_METHODS = unset(EXPORTED_RUNTIME_METHODS_SET);
272272
EXTRA_EXPORTED_RUNTIME_METHODS = [];
273273

274-
function maybeExport(name) {
274+
function isFSPrefixed(name) {
275+
return name.length > 3 && name[0] === 'F' && name[1] === 'S' && name[2] === '_';
276+
}
277+
278+
// forcing the filesystem exports a few things by default
279+
function isExportedByForceFilesystem(name) {
280+
return name === 'FS_createFolder' ||
281+
name === 'FS_createPath' ||
282+
name === 'FS_createDataFile' ||
283+
name === 'FS_createPreloadedFile' ||
284+
name === 'FS_createLazyFile' ||
285+
name === 'FS_createLink' ||
286+
name === 'FS_createDevice' ||
287+
name === 'FS_unlink' ||
288+
name === 'getMemory' ||
289+
name === 'addRunDependency' ||
290+
name === 'removeRunDependency';
291+
}
292+
293+
// optionally export something.
294+
// in ASSERTIONS mode we show a useful error if it is used without
295+
// being exported. how we show the message depends on whether it's
296+
// a function (almost all of them) or a number.
297+
function maybeExport(name, isNumber) {
275298
// if requested to be exported, export it
276299
if (name in EXPORTED_RUNTIME_METHODS_SET) {
277-
return 'Module["' + name + '"] = ' + name + ';';
300+
var exported = name;
301+
if (isFSPrefixed(exported)) {
302+
// this is a filesystem value, FS.x exported as FS_x
303+
exported = 'FS.' + exported.substr(3);
304+
}
305+
return 'Module["' + name + '"] = ' + exported + ';';
278306
}
279307
// do not export it. but if ASSERTIONS, emit a
280308
// stub with an error, so the user gets a message
@@ -283,11 +311,23 @@ function maybeExport(name) {
283311
// check if it already exists, to support EXPORT_ALL and other cases
284312
// (we could optimize this, but in ASSERTIONS mode code size doesn't
285313
// matter anyhow)
286-
return 'if (!Module["' + name + '"]) Module["' + name + '"] = function() { abort("\'' + name + '\' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };';
314+
var extra = '';
315+
if (isExportedByForceFilesystem(name)) {
316+
extra = '. Alternatively, forcing filesystem support (-s FORCE_FILESYSTEM=1) can export this for you';
317+
}
318+
if (!isNumber) {
319+
return 'if (!Module["' + name + '"]) Module["' + name + '"] = function() { abort("\'' + name + '\' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)' + extra + '") };';
320+
} else {
321+
return 'if (!Module["' + name + '"]) Object.defineProperty(Module, "' + name + '", { get: function() { abort("\'' + name + '\' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)' + extra + '") } });';
322+
}
287323
}
288324
return '';
289325
}
290326

327+
function maybeExportNumber(name) {
328+
return maybeExport(name, true);
329+
}
330+
291331
var PassManager = {
292332
serialize: function() {
293333
print('\n//FORWARDED_DATA:' + JSON.stringify({

src/postamble.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,15 @@
44
Module['asm'] = asm;
55

66
{{{ maybeExport('FS') }}}
7+
{{{ maybeExport('FS_createFolder') }}}
8+
{{{ maybeExport('FS_createPath') }}}
9+
{{{ maybeExport('FS_createDataFile') }}}
10+
{{{ maybeExport('FS_createPreloadedFile') }}}
11+
{{{ maybeExport('FS_createLazyFile') }}}
12+
{{{ maybeExport('FS_createLink') }}}
13+
{{{ maybeExport('FS_createDevice') }}}
14+
{{{ maybeExport('FS_unlink') }}}
15+
716
{{{ maybeExport('GL') }}}
817

918
#if MEM_INIT_IN_WASM == 0

src/preamble.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -276,11 +276,11 @@ var ALLOC_STACK = 1; // Lives for the duration of the current function call
276276
var ALLOC_STATIC = 2; // Cannot be freed
277277
var ALLOC_DYNAMIC = 3; // Cannot be freed except through sbrk
278278
var ALLOC_NONE = 4; // Do not allocate
279-
{{{ maybeExport('ALLOC_NORMAL') }}}
280-
{{{ maybeExport('ALLOC_STACK') }}}
281-
{{{ maybeExport('ALLOC_STATIC') }}}
282-
{{{ maybeExport('ALLOC_DYNAMIC') }}}
283-
{{{ maybeExport('ALLOC_NONE') }}}
279+
{{{ maybeExportNumber('ALLOC_NORMAL') }}}
280+
{{{ maybeExportNumber('ALLOC_STACK') }}}
281+
{{{ maybeExportNumber('ALLOC_STATIC') }}}
282+
{{{ maybeExportNumber('ALLOC_DYNAMIC') }}}
283+
{{{ maybeExportNumber('ALLOC_NONE') }}}
284284

285285
// allocate(): This is for internal use. You can use it yourself as well, but the interface
286286
// is a little tricky (see docs right below). The reason is that it is optimized
@@ -933,7 +933,7 @@ function checkStackCookie() {
933933
}
934934

935935
function abortStackOverflow(allocSize) {
936-
abort('Stack overflow! Attempted to allocate ' + allocSize + ' bytes on the stack, but stack has only ' + (STACK_MAX - Module['asm'].stackSave() + allocSize) + ' bytes available!');
936+
abort('Stack overflow! Attempted to allocate ' + allocSize + ' bytes on the stack, but stack has only ' + (STACK_MAX - stackSave() + allocSize) + ' bytes available!');
937937
}
938938
#endif
939939

src/settings.js

Lines changed: 4 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -342,31 +342,16 @@ var ASYNCIFY_WHITELIST = ['qsort', // Functions in this list are never conside
342342
'__fwritex',
343343
'MUSL_vfprintf'];
344344

345-
var EXPORTED_RUNTIME_METHODS = [ // Runtime elements that are exported on Module. By default we export quite a bit, you can reduce this list to lower your code size,
346-
// especially when closure is run (exporting prevents closure from eliminating code)
345+
var EXPORTED_RUNTIME_METHODS = [ // Runtime elements that are exported on Module by default. We used to export quite a lot here,
346+
// but have removed them all, so this option is redundant given that EXTRA_EXPORTED_RUNTIME_METHODS
347+
// exists, and so this option exists only for backwards compatibility. You should use
348+
// EXTRA_EXPORTED_RUNTIME_METHODS for things you want to export from the runtime.
347349
// Note that methods on this list are only exported if they are included (either automatically from linking, or due to being
348350
// in DEFAULT_LIBRARY_FUNCS_TO_INCLUDE)
349351
// Note that the name may be slightly misleading, as this
350352
// is for any JS library element, and not just
351353
// methods. For example, we export the Runtime object
352354
// by having "Runtime" in this list.
353-
'FS_createFolder',
354-
'FS_createPath',
355-
'FS_createDataFile',
356-
'FS_createPreloadedFile',
357-
'FS_createLazyFile',
358-
'FS_createLink',
359-
'FS_createDevice',
360-
'FS_unlink',
361-
'Runtime',
362-
'ALLOC_NORMAL',
363-
'ALLOC_STACK',
364-
'ALLOC_STATIC',
365-
'ALLOC_DYNAMIC',
366-
'ALLOC_NONE',
367-
'getMemory',
368-
'addRunDependency',
369-
'removeRunDependency',
370355
];
371356

372357
var EXTRA_EXPORTED_RUNTIME_METHODS = []; // Additional methods to those in EXPORTED_RUNTIME_METHODS. Adjusting that list

0 commit comments

Comments
 (0)