Skip to content

Commit 00eda2b

Browse files
authored
More minimal runtime code building (#10337)
* More tests working with MINIMAL_RUNTIME in Wasm backend. ASan support to MINIMAL_RUNTIME. * LSan works too * Enable more of the core test suite to build on MINIMAL_RUNTIME. * More core test suite working in MINIMAL_RUNTIME. * Add missing printf deps in MINIMAL_RUNTIME * Stack functions are not a JS library function in Wasm backend. * Cleanup * cleanup * assert() behind ASSERTIONS. * Fix Closure + Wasm2JS build. * Flake and fix dladdr * Revise fflush() behavior in MINIMAL_RUNTIME * Drop memcpy and memset by default * Fix deletion of DEFAULT_LIBRARY_FUNCS_TO_INCLUDE exports * Fix location of MINIMAL_RUNTIME reading * Clear DEFAULT_LIBRARY_FUNCS_TO_INCLUDE for MINIMAL_RUNTIME * Rename _get_executable_name to _getExecutableName.
1 parent 993586f commit 00eda2b

20 files changed

+205
-92
lines changed

emcc.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1103,6 +1103,10 @@ def get_last_setting_change(setting):
11031103
if 'WARN_ON_UNDEFINED_SYMBOLS=0' in settings_changes:
11041104
shared.Settings.ERROR_ON_UNDEFINED_SYMBOLS = 0
11051105

1106+
if shared.Settings.MINIMAL_RUNTIME or 'MINIMAL_RUNTIME=1' in settings_changes or 'MINIMAL_RUNTIME=2' in settings_changes:
1107+
# Remove the default exported functions 'malloc', 'free', etc. those should only be linked in if used
1108+
shared.Settings.DEFAULT_LIBRARY_FUNCS_TO_INCLUDE = []
1109+
11061110
# Set ASM_JS default here so that we can override it from the command line.
11071111
shared.Settings.ASM_JS = 1 if options.opt_level > 0 else 2
11081112

@@ -1249,10 +1253,6 @@ def is_supported_link_flag(f):
12491253

12501254
link_flags = [f for f in link_flags if is_supported_link_flag(f[1])]
12511255

1252-
if shared.Settings.MINIMAL_RUNTIME:
1253-
# Remove the default exported functions 'memcpy', 'memset', 'malloc', 'free', etc. - those should only be linked in if used
1254-
shared.Settings.DEFAULT_LIBRARY_FUNCS_TO_INCLUDE = []
1255-
12561256
if shared.Settings.STACK_OVERFLOW_CHECK:
12571257
if shared.Settings.MINIMAL_RUNTIME:
12581258
shared.Settings.DEFAULT_LIBRARY_FUNCS_TO_INCLUDE += ['$abortStackOverflow']

src/Fetch.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,9 @@ function __emscripten_fetch_xhr(fetch, onsuccess, onerror, onprogress, onreadyst
325325
xhr.open(requestMethod, url_, !fetchAttrSynchronous, userNameStr, passwordStr);
326326
if (!fetchAttrSynchronous) xhr.timeout = timeoutMsecs; // XHR timeout field is only accessible in async XHRs, and must be set after .open() but before .send().
327327
xhr.url_ = url_; // Save the url for debugging purposes (and for comparing to the responseURL that server side advertised)
328+
#if ASSERTIONS
328329
assert(!fetchAttrStreamData, 'streaming uses moz-chunked-arraybuffer which is no longer supported; TODO: rewrite using fetch()');
330+
#endif
329331
xhr.responseType = 'arraybuffer';
330332

331333
if (overriddenMimeType) {

src/deps_info.json

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -80,13 +80,13 @@
8080
"sleep": ["usleep"],
8181
"recv": ["htons"],
8282
"send": ["htons"],
83-
"ctime": ["_get_tzname", "_get_daylight", "_get_timezone"],
84-
"ctime_r": ["_get_tzname", "_get_daylight", "_get_timezone"],
85-
"localtime": ["_get_tzname", "_get_daylight", "_get_timezone"],
86-
"localtime_r": ["_get_tzname", "_get_daylight", "_get_timezone"],
87-
"mktime": ["_get_tzname", "_get_daylight", "_get_timezone"],
88-
"timegm": ["_get_tzname", "_get_daylight", "_get_timezone"],
89-
"tzset": ["_get_tzname", "_get_daylight", "_get_timezone"],
83+
"ctime": ["_get_tzname", "_get_daylight", "_get_timezone", "malloc"],
84+
"ctime_r": ["_get_tzname", "_get_daylight", "_get_timezone", "malloc"],
85+
"localtime": ["_get_tzname", "_get_daylight", "_get_timezone", "malloc"],
86+
"localtime_r": ["_get_tzname", "_get_daylight", "_get_timezone", "malloc"],
87+
"mktime": ["_get_tzname", "_get_daylight", "_get_timezone", "malloc"],
88+
"timegm": ["_get_tzname", "_get_daylight", "_get_timezone", "malloc"],
89+
"tzset": ["_get_tzname", "_get_daylight", "_get_timezone", "malloc"],
9090
"emscripten_set_canvas_element_size_calling_thread": ["emscripten_async_queue_on_thread_"],
9191
"emscripten_webgl_destroy_context": ["emscripten_webgl_make_context_current", "emscripten_webgl_get_current_context"],
9292
"emscripten_webgl_create_context": ["malloc", "free"],

src/library.js

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -467,7 +467,7 @@ LibraryManager.library = {
467467
},
468468

469469
emscripten_get_heap_size: function() {
470-
return HEAP8.length;
470+
return HEAPU8.length;
471471
},
472472

473473
emscripten_get_sbrk_ptr__asm: true,
@@ -703,7 +703,7 @@ LibraryManager.library = {
703703
_exit(-1234);
704704
},
705705

706-
#if MINIMAL_RUNTIME
706+
#if MINIMAL_RUNTIME && !EXIT_RUNTIME
707707
atexit: function(){},
708708
__cxa_atexit: function(){},
709709
__cxa_thread_atexit: function(){},
@@ -746,7 +746,7 @@ LibraryManager.library = {
746746
// to limitations in the system libraries (we can't easily add a global
747747
// ctor to create the environment without it always being linked in with
748748
// libc).
749-
__buildEnvironment__deps: ['$ENV'],
749+
__buildEnvironment__deps: ['$ENV', '_getExecutableName'],
750750
__buildEnvironment: function(environ) {
751751
// WARNING: Arbitrary limit!
752752
var MAX_ENV_VALUES = 64;
@@ -765,7 +765,7 @@ LibraryManager.library = {
765765
ENV['HOME'] = '/home/web_user';
766766
// Browser language detection #8751
767767
ENV['LANG'] = ((typeof navigator === 'object' && navigator.languages && navigator.languages[0]) || 'C').replace('-', '_') + '.UTF-8';
768-
ENV['_'] = thisProgram;
768+
ENV['_'] = __getExecutableName();
769769
// Allocate memory.
770770
#if !MINIMAL_RUNTIME // TODO: environment support in MINIMAL_RUNTIME
771771
poolPtr = getMemory(TOTAL_ENV_SIZE);
@@ -1844,12 +1844,12 @@ LibraryManager.library = {
18441844
}
18451845
},
18461846

1847-
dladdr__deps: ['$stringToNewUTF8'],
1847+
dladdr__deps: ['$stringToNewUTF8', '_getExecutableName'],
18481848
dladdr__proxy: 'sync',
18491849
dladdr__sig: 'iii',
18501850
dladdr: function(addr, info) {
18511851
// report all function pointers as coming from this program itself XXX not really correct in any way
1852-
var fname = stringToNewUTF8(thisProgram || './this.program'); // XXX leak
1852+
var fname = stringToNewUTF8(__getExecutableName()); // XXX leak
18531853
{{{ makeSetValue('info', 0, 'fname', 'i32') }}};
18541854
{{{ makeSetValue('info', Runtime.QUANTUM_SIZE, '0', 'i32') }}};
18551855
{{{ makeSetValue('info', Runtime.QUANTUM_SIZE*2, '0', 'i32') }}};
@@ -2068,6 +2068,9 @@ LibraryManager.library = {
20682068
// Note: glibc has one fewer underscore for all of these. Also used in other related functions (timegm)
20692069
tzset__proxy: 'sync',
20702070
tzset__sig: 'v',
2071+
#if MINIMAL_RUNTIME
2072+
tzset__deps: ['$allocateUTF8'],
2073+
#endif
20712074
tzset: function() {
20722075
// TODO: Use (malleable) environment variables instead of system settings.
20732076
if (_tzset.called) return;
@@ -2091,8 +2094,8 @@ LibraryManager.library = {
20912094
};
20922095
var winterName = extractZone(winter);
20932096
var summerName = extractZone(summer);
2094-
var winterNamePtr = allocate(intArrayFromString(winterName), 'i8', ALLOC_NORMAL);
2095-
var summerNamePtr = allocate(intArrayFromString(summerName), 'i8', ALLOC_NORMAL);
2097+
var winterNamePtr = allocateUTF8(winterName);
2098+
var summerNamePtr = allocateUTF8(summerName);
20962099
if (summer.getTimezoneOffset() < winter.getTimezoneOffset()) {
20972100
// Northern hemisphere
20982101
{{{ makeSetValue('__get_tzname()', '0', 'winterNamePtr', 'i32') }}};
@@ -2158,7 +2161,11 @@ LibraryManager.library = {
21582161

21592162
// Note: this is not used in STANDALONE_WASM mode, because it is more
21602163
// compact to do it in JS.
2161-
strftime__deps: ['_isLeapYear', '_arraySum', '_addDays', '_MONTH_DAYS_REGULAR', '_MONTH_DAYS_LEAP'],
2164+
strftime__deps: ['_isLeapYear', '_arraySum', '_addDays', '_MONTH_DAYS_REGULAR', '_MONTH_DAYS_LEAP'
2165+
#if MINIMAL_RUNTIME
2166+
, '$intArrayFromString', '$writeArrayToMemory'
2167+
#endif
2168+
],
21622169
strftime: function(s, maxsize, format, tm) {
21632170
// size_t strftime(char *restrict s, size_t maxsize, const char *restrict format, const struct tm *restrict timeptr);
21642171
// http://pubs.opengroup.org/onlinepubs/009695399/functions/strftime.html
@@ -2481,7 +2488,11 @@ LibraryManager.library = {
24812488
return _strftime(s, maxsize, format, tm); // no locale support yet
24822489
},
24832490

2484-
strptime__deps: ['_isLeapYear', '_arraySum', '_addDays', '_MONTH_DAYS_REGULAR', '_MONTH_DAYS_LEAP'],
2491+
strptime__deps: ['_isLeapYear', '_arraySum', '_addDays', '_MONTH_DAYS_REGULAR', '_MONTH_DAYS_LEAP'
2492+
#if MINIMAL_RUNTIME
2493+
, '$intArrayFromString'
2494+
#endif
2495+
],
24852496
strptime: function(buf, format, tm) {
24862497
// char *strptime(const char *restrict buf, const char *restrict format, struct tm *restrict tm);
24872498
// http://pubs.opengroup.org/onlinepubs/009695399/functions/strptime.html
@@ -5149,6 +5160,19 @@ LibraryManager.library = {
51495160
__handle_stack_overflow: function() {
51505161
abort('stack overflow')
51515162
},
5163+
5164+
_getExecutableName: function() {
5165+
#if MINIMAL_RUNTIME // MINIMAL_RUNTIME does not have a global runtime variable thisProgram
5166+
#if ENVIRONMENT_MAY_BE_NODE
5167+
if (ENVIRONMENT_IS_NODE && process['argv'].length > 1) {
5168+
return process['argv'][1].replace(/\\/g, '/');
5169+
}
5170+
#endif
5171+
return "./this.program";
5172+
#else
5173+
return thisProgram || './this.program';
5174+
#endif
5175+
},
51525176
};
51535177

51545178
function autoAddDeps(object, name) {

src/library_formatString.js

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@ mergeInto(LibraryManager.library, {
1010
// Returns the resulting string string as a character array.
1111
_formatString__deps: ['_reallyNegative'],
1212
_formatString: function(format, varargs) {
13+
#if ASSERTIONS
1314
assert((varargs & 3) === 0);
15+
#endif
1416
var textIndex = format;
1517
var argIndex = varargs;
1618
// This must be called before reading a double or i64 vararg. It will bump the pointer properly.
@@ -19,11 +21,15 @@ mergeInto(LibraryManager.library, {
1921
if (type === 'double' || type === 'i64') {
2022
// move so the load is aligned
2123
if (ptr & 7) {
24+
#if ASSERTIONS
2225
assert((ptr & 7) === 4);
26+
#endif
2327
ptr += 4;
2428
}
2529
} else {
30+
#if ASSERTIONS
2631
assert((ptr & 3) === 0);
32+
#endif
2733
}
2834
return ptr;
2935
}
@@ -40,7 +46,9 @@ mergeInto(LibraryManager.library, {
4046
{{{ makeGetValue('argIndex', 4, 'i32', undefined, undefined, true, 4) }}}];
4147
argIndex += 8;
4248
} else {
49+
#if ASSERTIONS
4350
assert((argIndex & 3) === 0);
51+
#endif
4452
type = 'i32'; // varargs are always i32, i64, or double
4553
ret = {{{ makeGetValue('argIndex', 0, 'i32', undefined, undefined, true) }}};
4654
argIndex += 4;
@@ -418,7 +426,11 @@ mergeInto(LibraryManager.library, {
418426
},
419427

420428
// printf/puts implementations for when musl is not pulled in - very partial. useful for tests, and when bootstrapping structInfo
421-
printf__deps: ['_formatString'],
429+
printf__deps: ['_formatString'
430+
#if MINIMAL_RUNTIME
431+
, '$intArrayToString'
432+
#endif
433+
],
422434
printf: function(format, varargs) {
423435
// int printf(const char *restrict format, ...);
424436
// http://pubs.opengroup.org/onlinepubs/000095399/functions/printf.html

src/library_html5.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ var LibraryJSEvents = {
4141
#endif
4242
},
4343

44-
#if !MINIMAL_RUNTIME // In minimal runtime, there is no concept of the page running vs being closed, and hence __ATEXIT__ is not present
44+
#if !MINIMAL_RUNTIME || EXIT_RUNTIME // In minimal runtime, there is no concept of the page running vs being closed, and hence __ATEXIT__ is not present
4545
registerRemoveEventListeners: function() {
4646
if (!JSEvents.removeEventListenersRegistered) {
4747
__ATEXIT__.push(JSEvents.removeAllEventListeners);
@@ -175,7 +175,7 @@ var LibraryJSEvents = {
175175
},
176176

177177
#if USE_PTHREADS
178-
#if MINIMAL_RUNTIME
178+
#if MINIMAL_RUNTIME && !WASM_BACKEND
179179
queueEventHandlerOnThread_iiii__deps: ['$stackSave', '$stackAlloc', '$stackRestore'],
180180
#endif
181181
queueEventHandlerOnThread_iiii: function(targetThread, eventHandlerFunc, eventTypeId, eventData, userData) {
@@ -2824,7 +2824,7 @@ var LibraryJSEvents = {
28242824
},
28252825

28262826
emscripten_set_offscreencanvas_size_on_target_thread_js__deps: ['$stringToNewUTF8'
2827-
#if MINIMAL_RUNTIME
2827+
#if MINIMAL_RUNTIME && !WASM_BACKEND
28282828
, '$stackSave', '$stackAlloc', '$stackRestore'
28292829
#endif
28302830
],
@@ -2887,7 +2887,7 @@ var LibraryJSEvents = {
28872887
#endif
28882888

28892889
_set_canvas_element_size__deps: ['emscripten_set_canvas_element_size'
2890-
#if MINIMAL_RUNTIME
2890+
#if MINIMAL_RUNTIME && !WASM_BACKEND
28912891
, '$stackSave', '$stackAlloc', '$stackRestore'
28922892
#endif
28932893
],
@@ -2964,7 +2964,7 @@ var LibraryJSEvents = {
29642964

29652965
// JavaScript-friendly API, returns pair [width, height]
29662966
_get_canvas_element_size__deps: ['emscripten_get_canvas_element_size'
2967-
#if MINIMAL_RUNTIME
2967+
#if MINIMAL_RUNTIME && !WASM_BACKEND
29682968
, '$stackSave', '$stackAlloc', '$stackRestore'
29692969
#endif
29702970
],

src/library_nodefs.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,15 @@ mergeInto(LibraryManager.library, {
3434
},
3535
convertNodeCode: function(e) {
3636
var code = e.code;
37+
#if ASSERTIONS
3738
assert(code in ERRNO_CODES);
39+
#endif
3840
return ERRNO_CODES[code];
3941
},
4042
mount: function (mount) {
43+
#if ASSERTIONS
4144
assert(ENVIRONMENT_IS_NODE);
45+
#endif
4246
return NODEFS.createNode(null, '/', NODEFS.getMode(mount.opts.root), 0);
4347
},
4448
createNode: function (parent, name, mode, dev) {

src/library_pthread_stub.js

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -163,23 +163,15 @@ var LibraryPThreadStub = {
163163
emscripten_main_browser_thread_id: function() { return _pthread_self(); },
164164

165165
// When pthreads is not enabled, we can't use the Atomics futex api to do proper sleeps, so simulate a busy spin wait loop instead.
166+
usleep__deps: ['emscripten_get_now'],
166167
usleep: function(useconds) {
167168
// int usleep(useconds_t useconds);
168169
// http://pubs.opengroup.org/onlinepubs/000095399/functions/usleep.html
169170
// We're single-threaded, so use a busy loop. Super-ugly.
170-
var msec = useconds / 1000;
171-
if ((ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) && self['performance'] && self['performance']['now']) {
172-
var start = self['performance']['now']();
173-
while (self['performance']['now']() - start < msec) {
174-
// Do nothing.
175-
}
176-
} else {
177-
var start = Date.now();
178-
while (Date.now() - start < msec) {
179-
// Do nothing.
180-
}
171+
var start = _emscripten_get_now();
172+
while (_emscripten_get_now() - start < useconds / 1000) {
173+
// Do nothing.
181174
}
182-
return 0;
183175
},
184176

185177
nanosleep__deps: ['usleep', '__setErrNo'],

src/library_stack_trace.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
var LibraryStackTrace = {
22

33
$demangle__deps: [
4-
#if MINIMAL_RUNTIME
4+
#if MINIMAL_RUNTIME && !WASM_BACKEND
55
'$stackSave', '$stackAlloc', '$stackRestore'
66
#if ASSERTIONS
77
, '$warnOnce'

src/library_strings.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#if MINIMAL_RUNTIME
22

33
#include "runtime_strings_extra.js"
4+
#include "arrayUtils.js"
45

56
mergeInto(LibraryManager.library, {
67
$AsciiToString: AsciiToString,
@@ -15,7 +16,9 @@ mergeInto(LibraryManager.library, {
1516
$allocateUTF8OnStack: allocateUTF8OnStack,
1617
$writeStringToMemory: writeStringToMemory,
1718
$writeArrayToMemory: writeArrayToMemory,
18-
$writeAsciiToMemory: writeAsciiToMemory
19+
$writeAsciiToMemory: writeAsciiToMemory,
20+
$intArrayFromString: intArrayFromString,
21+
$intArrayToString: intArrayToString
1922
});
2023

2124
#endif

0 commit comments

Comments
 (0)