Skip to content

Commit cff1009

Browse files
committed
Store memory initialization in string literal if requested
With “--memory-init-file 0 -s MEM_INIT_METHOD=2” on the command line, the generated JavaScript file will contain a string literal representing the initial content of the memory buffer. The MEM_INIT_METHOD defaults to 0 but gets set to 1 if --memory-init-file is being used. Conversely, setting it to 1 without --memory-init-file will cause it to revert to 0. That way, we can use the setting in the postamble, without too many changes in other places. Since memory is initialized to all zero, trailing zeros can be omitted. This change affects the file-based initialization as well, but not when using emterpretify.
1 parent 55de8d6 commit cff1009

File tree

3 files changed

+31
-2
lines changed

3 files changed

+31
-2
lines changed

emcc

+18-2
Original file line numberDiff line numberDiff line change
@@ -1267,6 +1267,10 @@ try:
12671267
# Emscripten
12681268
logging.debug('LLVM => JS')
12691269
extra_args = [] if not js_libraries else ['--libraries', ','.join(map(os.path.abspath, js_libraries))]
1270+
if memory_init_file:
1271+
shared.Settings.MEM_INIT_METHOD = 1
1272+
elif shared.Settings.MEM_INIT_METHOD == 1:
1273+
shared.Settings.MEM_INIT_METHOD = 0
12701274
final = shared.Building.emscripten(final, append_ext=False, extra_args=extra_args)
12711275
if DEBUG: save_intermediate('original')
12721276

@@ -1318,14 +1322,26 @@ try:
13181322

13191323
js_transform_tempfiles = [final]
13201324

1321-
if memory_init_file:
1325+
if memory_init_file or shared.Settings.MEM_INIT_METHOD == 2:
13221326
memfile = target + '.mem'
13231327
shared.try_delete(memfile)
13241328
def repl(m):
13251329
# handle chunking of the memory initializer
13261330
s = m.groups(0)[0]
13271331
if len(s) == 0 and not shared.Settings.EMTERPRETIFY: return m.group(0) # emterpreter must have a mem init file; otherwise, don't emit 0-size ones
1328-
open(memfile, 'wb').write(''.join(map(lambda x: chr(int(x or '0')), s.split(','))))
1332+
membytes = [int(x or '0') for x in s.split(',')]
1333+
if not shared.Settings.EMTERPRETIFY:
1334+
while membytes and membytes[-1] == 0:
1335+
membytes.pop()
1336+
if not membytes:
1337+
return '';
1338+
membytes = ''.join(map(chr, membytes))
1339+
if not memory_init_file:
1340+
s = repr(membytes)
1341+
hex_to_octal = lambda x: '\\%o' % int(x.group(1), 16)
1342+
s = re.sub(r'\\x([0-1][0-9A-Fa-f])(?:(?=[^0-9])|$)', hex_to_octal, s)
1343+
return 'var memoryInitializer = %s;' % s
1344+
open(memfile, 'wb').write(membytes)
13291345
if DEBUG:
13301346
# Copy into temp dir as well, so can be run there too
13311347
shared.safe_copy(memfile, os.path.join(shared.get_emscripten_temp_dir(), os.path.basename(memfile)))

src/postamble.js

+8
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11

22
// === Auto-generated postamble setup entry stuff ===
33

4+
#if MEM_INIT_METHOD == 2
5+
if (memoryInitializer) (function(s) {
6+
for (var i = 0; i < s.length; ++i) HEAPU8[i] = s.charCodeAt(i);
7+
})(memoryInitializer);
8+
#else
9+
#if MEM_INIT_METHOD == 1
410
if (memoryInitializer) {
511
if (typeof Module['locateFile'] === 'function') {
612
memoryInitializer = Module['locateFile'](memoryInitializer);
@@ -48,6 +54,8 @@ if (memoryInitializer) {
4854
}
4955
}
5056
}
57+
#endif
58+
#endif
5159

5260
function ExitStatus(status) {
5361
this.name = "ExitStatus";

src/settings.js

+5
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,11 @@ var INVOKE_RUN = 1; // Whether we will run the main() function. Disable if you e
3535
// can do with Module.callMain(), with an optional parameter of commandline args).
3636
var NO_EXIT_RUNTIME = 0; // If set, the runtime is not quit when main() completes (allowing code to
3737
// run afterwards, for example from the browser main event loop).
38+
var MEM_INIT_METHOD = 0; // How to represent the initial memory content.
39+
// 0: keep array literal representing the initial memory data
40+
// 1: create a *.mem file containing the binary data of the initial memory;
41+
// use the --memory-init-file command line switch to select this method
42+
// 2: embed a string literal representing that initial memory data
3843
var TOTAL_STACK = 5*1024*1024; // The total stack size. There is no way to enlarge the stack, so this
3944
// value must be large enough for the program's requirements. If
4045
// assertions are on, we will assert on not exceeding this, otherwise,

0 commit comments

Comments
 (0)