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. Setting it to 1 without --memory-init-file will cause an error. 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.
This commit is contained in:
Родитель
92094e41a6
Коммит
8f44c9f77a
20
emcc
20
emcc
|
@ -1289,6 +1289,10 @@ try:
|
|||
# Emscripten
|
||||
logging.debug('LLVM => JS')
|
||||
extra_args = [] if not js_libraries else ['--libraries', ','.join(map(os.path.abspath, js_libraries))]
|
||||
if memory_init_file:
|
||||
shared.Settings.MEM_INIT_METHOD = 1
|
||||
elif shared.Settings.MEM_INIT_METHOD == 1:
|
||||
shared.Settings.MEM_INIT_METHOD = 0
|
||||
final = shared.Building.emscripten(final, append_ext=False, extra_args=extra_args)
|
||||
if DEBUG: save_intermediate('original')
|
||||
|
||||
|
@ -1340,14 +1344,26 @@ try:
|
|||
|
||||
js_transform_tempfiles = [final]
|
||||
|
||||
if memory_init_file:
|
||||
if memory_init_file or shared.Settings.MEM_INIT_METHOD == 2:
|
||||
memfile = target + '.mem'
|
||||
shared.try_delete(memfile)
|
||||
def repl(m):
|
||||
# handle chunking of the memory initializer
|
||||
s = m.groups(0)[0]
|
||||
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
|
||||
open(memfile, 'wb').write(''.join(map(lambda x: chr(int(x or '0')), s.split(','))))
|
||||
membytes = [int(x or '0') for x in s.split(',')]
|
||||
if not shared.Settings.EMTERPRETIFY:
|
||||
while membytes and membytes[-1] == 0:
|
||||
membytes.pop()
|
||||
if not membytes:
|
||||
return '';
|
||||
membytes = ''.join(map(chr, membytes))
|
||||
if not memory_init_file:
|
||||
s = repr(membytes)
|
||||
hex_to_octal = lambda x: '\\%o' % int(x.group(1), 16)
|
||||
s = re.sub(r'\\x([0-1][0-9A-Fa-f])(?:(?=[^0-9])|$)', hex_to_octal, s)
|
||||
return 'var memoryInitializer = %s;' % s
|
||||
open(memfile, 'wb').write(membytes)
|
||||
if DEBUG:
|
||||
# Copy into temp dir as well, so can be run there too
|
||||
shared.safe_copy(memfile, os.path.join(shared.get_emscripten_temp_dir(), os.path.basename(memfile)))
|
||||
|
|
|
@ -1,6 +1,16 @@
|
|||
|
||||
// === Auto-generated postamble setup entry stuff ===
|
||||
|
||||
#if MEM_INIT_METHOD == 2
|
||||
#if USE_PTHREADS
|
||||
if (memoryInitializer && !ENVIRONMENT_IS_PTHREAD) (function(s) {
|
||||
#else
|
||||
if (memoryInitializer) (function(s) {
|
||||
#endif
|
||||
for (var i = 0; i < s.length; ++i) HEAPU8[STATIC_BASE + i] = s.charCodeAt(i);
|
||||
})(memoryInitializer);
|
||||
#else
|
||||
#if MEM_INIT_METHOD == 1
|
||||
#if USE_PTHREADS
|
||||
if (memoryInitializer && !ENVIRONMENT_IS_PTHREAD) {
|
||||
#else
|
||||
|
@ -52,6 +62,8 @@ if (memoryInitializer) {
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
function ExitStatus(status) {
|
||||
this.name = "ExitStatus";
|
||||
|
|
|
@ -35,6 +35,11 @@ var INVOKE_RUN = 1; // Whether we will run the main() function. Disable if you e
|
|||
// can do with Module.callMain(), with an optional parameter of commandline args).
|
||||
var NO_EXIT_RUNTIME = 0; // If set, the runtime is not quit when main() completes (allowing code to
|
||||
// run afterwards, for example from the browser main event loop).
|
||||
var MEM_INIT_METHOD = 0; // How to represent the initial memory content.
|
||||
// 0: keep array literal representing the initial memory data
|
||||
// 1: create a *.mem file containing the binary data of the initial memory;
|
||||
// use the --memory-init-file command line switch to select this method
|
||||
// 2: embed a string literal representing that initial memory data
|
||||
var TOTAL_STACK = 5*1024*1024; // The total stack size. There is no way to enlarge the stack, so this
|
||||
// value must be large enough for the program's requirements. If
|
||||
// assertions are on, we will assert on not exceeding this, otherwise,
|
||||
|
|
|
@ -62,6 +62,14 @@ class RunnerCore(unittest.TestCase):
|
|||
def is_emterpreter(self):
|
||||
return False
|
||||
|
||||
def uses_memory_init_file(self):
|
||||
if self.emcc_args is None:
|
||||
return None
|
||||
elif '--memory-init-file' in self.emcc_args:
|
||||
return int(self.emcc_args[self.emcc_args.index('--memory-init-file')+1])
|
||||
else:
|
||||
return ('-O2' in self.emcc_args or '-O3' in self.emcc_args or '-Oz' in self.emcc_args) and not Settings.SIDE_MODULE
|
||||
|
||||
def setUp(self):
|
||||
Settings.reset()
|
||||
self.banned_js_engines = []
|
||||
|
@ -252,16 +260,10 @@ class RunnerCore(unittest.TestCase):
|
|||
output_processor(open(filename + '.o.js').read())
|
||||
|
||||
if self.emcc_args is not None:
|
||||
if '--memory-init-file' in self.emcc_args:
|
||||
memory_init_file = int(self.emcc_args[self.emcc_args.index('--memory-init-file')+1])
|
||||
else:
|
||||
memory_init_file = ('-O2' in self.emcc_args or '-O3' in self.emcc_args or '-Oz' in self.emcc_args) and not Settings.SIDE_MODULE
|
||||
src = open(filename + '.o.js').read()
|
||||
if memory_init_file:
|
||||
if self.uses_memory_init_file():
|
||||
# side memory init file, or an empty one in the js
|
||||
assert ('/* memory initializer */' not in src) or ('/* memory initializer */ allocate([]' in src)
|
||||
else:
|
||||
assert 'memory initializer */' in src or '/*' not in src # memory initializer comment, or cleaned-up source with no comments
|
||||
|
||||
def validate_asmjs(self, err):
|
||||
if 'uccessfully compiled asm.js code' in err and 'asm.js link error' not in err:
|
||||
|
|
|
@ -4549,7 +4549,7 @@ def process(filename):
|
|||
try_delete(mem_file)
|
||||
self.do_run(src, ('size: 7\ndata: 100,-56,50,25,10,77,123\nloop: 100 -56 50 25 10 77 123 \ninput:hi there!\ntexto\n$\n5 : 10,30,20,11,88\nother=some data.\nseeked=me da.\nseeked=ata.\nseeked=ta.\nfscanfed: 10 - hello\n5 bytes to dev/null: 5\nok.\n \ntexte\n', 'size: 7\ndata: 100,-56,50,25,10,77,123\nloop: 100 -56 50 25 10 77 123 \ninput:hi there!\ntexto\ntexte\n$\n5 : 10,30,20,11,88\nother=some data.\nseeked=me da.\nseeked=ata.\nseeked=ta.\nfscanfed: 10 - hello\n5 bytes to dev/null: 5\nok.\n'),
|
||||
post_build=post, extra_emscripten_args=['-H', 'libc/fcntl.h'])
|
||||
if '-O2' in self.emcc_args:
|
||||
if self.uses_memory_init_file():
|
||||
assert os.path.exists(mem_file)
|
||||
|
||||
def test_files_m(self):
|
||||
|
@ -7387,6 +7387,7 @@ asm2f = make_run("asm2f", compiler=CLANG, emcc_args=["-Oz", "-s", "PRECISE_F32=1
|
|||
asm2g = make_run("asm2g", compiler=CLANG, emcc_args=["-O2", "-g", "-s", "ASSERTIONS=1", "-s", "SAFE_HEAP=1"])
|
||||
asm1i = make_run("asm1i", compiler=CLANG, emcc_args=["-O1", '-s', 'EMTERPRETIFY=1'])
|
||||
asm3i = make_run("asm3i", compiler=CLANG, emcc_args=["-O3", '-s', 'EMTERPRETIFY=1'])
|
||||
asm2m = make_run("asm2m", compiler=CLANG, emcc_args=["-O2", "--memory-init-file", "0", "-s", "MEM_INIT_METHOD=2"])
|
||||
|
||||
# Legacy test modes -
|
||||
asm2nn = make_run("asm2nn", compiler=CLANG, emcc_args=["-O2"], env={"EMCC_NATIVE_OPTIMIZER": "0"})
|
||||
|
|
Загрузка…
Ссылка в новой задаче