Skip to content

Commit 65ef52e

Browse files
authored
Delay loading of embedded file data until static constructors are run (#17209)
This code was relying on static data relocations being applied during module instantiation, but a recent change to llvm reverts to the previous behaviour of applying relocation during `__wasm_call_ctors`: https://reviews.llvm.org/D127333 This change delays the loading of embedded files until static ctor time after the relocations have been applied. As a followup I think we can look into completely removing the pre-js in this case.
1 parent 84249c1 commit 65ef52e

File tree

3 files changed

+52
-31
lines changed

3 files changed

+52
-31
lines changed

src/library.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3625,6 +3625,33 @@ mergeInto(LibraryManager.library, {
36253625
__c_longjmp_import: true,
36263626
#endif
36273627
#endif
3628+
3629+
_emscripten_fs_load_embedded_files__deps: ['$FS'],
3630+
_emscripten_fs_load_embedded_files__sig: 'vp',
3631+
_emscripten_fs_load_embedded_files: function(ptr) {
3632+
#if MEMORY64
3633+
var start64 = ptr >> 3;
3634+
do {
3635+
var name_addr = Number(HEAPU64[start64++]);
3636+
var len = HEAPU32[start64 << 1];
3637+
start64++;
3638+
var content = Number(HEAPU64[start64++]);
3639+
var name = UTF8ToString(name_addr)
3640+
// canOwn this data in the filesystem, it is a slice of wasm memory that will never change
3641+
FS.createDataFile(name, null, HEAP8.subarray(content, content + len), true, true, true);
3642+
} while (HEAPU64[start64]);
3643+
#else
3644+
var start32 = ptr >> 2;
3645+
do {
3646+
var name_addr = HEAPU32[start32++];
3647+
var len = HEAPU32[start32++];
3648+
var content = HEAPU32[start32++];
3649+
var name = UTF8ToString(name_addr)
3650+
// canOwn this data in the filesystem, it is a slice of wasm memory that will never change
3651+
FS.createDataFile(name, null, HEAP8.subarray(content, content + len), true, true, true);
3652+
} while (HEAPU32[start32]);
3653+
#endif
3654+
},
36283655
});
36293656

36303657
function autoAddDeps(object, name) {

system/lib/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ These current set of static constructors in system libraries and their prioritie
1919
- 1: `emscripten_stack_init` (stack_limits.S)
2020
- 47: `initialize_emmalloc_heap` (emmalloc.c)
2121
- 48: `__emscripten_init_main_thread` (pthread/library_pthread.c)
22+
- 49: `init_file_data` (generated by file_packager.py)
2223
- 50: asan init (??)
2324
- 100: `WasmFS wasmFS` (wasmfs/wasmfs.cpp)
2425

tools/file_packager.py

Lines changed: 24 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -290,18 +290,36 @@ def generate_object_file(data_files):
290290

291291
if options.wasm64:
292292
align = 3
293+
ptr_type = 'i64'
294+
bits = 64
293295
else:
294296
align = 2
295-
out.write(dedent('''
297+
ptr_type = 'i32'
298+
bits = 32
299+
out.write(dedent(f'''
300+
.functype _emscripten_fs_load_embedded_files ({ptr_type}) -> ()
301+
.section .text,"",@
302+
init_file_data:
303+
.functype init_file_data () -> ()
304+
global.get __emscripten_embedded_file_data@GOT
305+
call _emscripten_fs_load_embedded_files
306+
end_function
307+
308+
# Run init_file_data on startup.
309+
# See system/lib/README.md for ordering of system constructors.
310+
.section .init_array.49,"",@
311+
.p2align {align}
312+
.int{bits} init_file_data
313+
296314
# A list of triples of:
297315
# (file_name_ptr, file_data_size, file_data_ptr)
298316
# The list in null terminate with a single 0
299317
.globl __emscripten_embedded_file_data
300318
.export_name __emscripten_embedded_file_data, __emscripten_embedded_file_data
301319
.section .rodata.__emscripten_embedded_file_data,"",@
302320
__emscripten_embedded_file_data:
303-
.p2align %s
304-
''' % align))
321+
.p2align {align}
322+
'''))
305323

306324
for f in embed_files:
307325
# The `.dc.a` directive gives us a pointer (address) sized entry.
@@ -654,35 +672,10 @@ def generate_js(data_target, data_files, metadata):
654672
new DataRequest(files[i]['start'], files[i]['end'], files[i]['audio'] || 0).open('GET', files[i]['filename']);
655673
}\n''' % (create_preloaded if options.use_preload_plugins else create_data)
656674

657-
if options.has_embedded:
658-
if options.obj_output:
659-
if options.wasm64:
660-
code += '''\
661-
var start64 = Module['___emscripten_embedded_file_data'] >> 3;
662-
do {
663-
var name_addr = Number(HEAPU64[start64++]);
664-
var len = HEAPU32[start64 << 1];
665-
start64++;
666-
var content = Number(HEAPU64[start64++]);
667-
var name = UTF8ToString(name_addr)
668-
// canOwn this data in the filesystem, it is a slice of wasm memory that will never change
669-
Module['FS_createDataFile'](name, null, HEAP8.subarray(content, content + len), true, true, true);
670-
} while (HEAPU64[start64]);'''
671-
else:
672-
code += '''\
673-
var start32 = Module['___emscripten_embedded_file_data'] >> 2;
674-
do {
675-
var name_addr = HEAPU32[start32++];
676-
var len = HEAPU32[start32++];
677-
var content = HEAPU32[start32++];
678-
var name = UTF8ToString(name_addr)
679-
// canOwn this data in the filesystem, it is a slice of wasm memory that will never change
680-
Module['FS_createDataFile'](name, null, HEAP8.subarray(content, content + len), true, true, true);
681-
} while (HEAPU32[start32]);'''
682-
else:
683-
err('--obj-output is recommended when using --embed. This outputs an object file for linking directly into your application is more effecient than JS encoding')
675+
if options.has_embedded and not options.obj_output:
676+
err('--obj-output is recommended when using --embed. This outputs an object file for linking directly into your application is more effecient than JS encoding')
684677

685-
for (counter, file_) in enumerate(data_files):
678+
for counter, file_ in enumerate(data_files):
686679
filename = file_.dstpath
687680
dirname = os.path.dirname(filename)
688681
basename = os.path.basename(filename)

0 commit comments

Comments
 (0)