Skip to content

Commit b21196e

Browse files
authored
Use a python class in tools/extract_metadata.py. NFC (emscripten-core#18007)
1 parent 4f28b7a commit b21196e

3 files changed

Lines changed: 65 additions & 48 deletions

File tree

emcc.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -724,7 +724,7 @@ def process_dynamic_libs(dylibs, lib_dirs):
724724
imports = [i.field for i in imports if i.kind in (webassembly.ExternType.FUNC, webassembly.ExternType.GLOBAL, webassembly.ExternType.TAG)]
725725
# For now we ignore `invoke_` functions imported by side modules and rely
726726
# on the dynamic linker to create them on the fly.
727-
# TODO(sbc): Integrate with metadata['invokeFuncs'] that comes from the
727+
# TODO(sbc): Integrate with metadata.invokeFuncs that comes from the
728728
# main module to avoid creating new invoke functions at runtime.
729729
imports = set(i for i in imports if not i.startswith('invoke_'))
730730
weak_imports = imports.intersection(exports)

emscripten.py

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -120,27 +120,27 @@ def get_weak_imports(main_wasm):
120120

121121

122122
def update_settings_glue(wasm_file, metadata):
123-
optimize_syscalls(metadata['declares'])
123+
optimize_syscalls(metadata.imports)
124124

125125
# Integrate info from backend
126126
if settings.SIDE_MODULE:
127127
# we don't need any JS library contents in side modules
128128
settings.DEFAULT_LIBRARY_FUNCS_TO_INCLUDE = []
129129
else:
130-
syms = settings.DEFAULT_LIBRARY_FUNCS_TO_INCLUDE + [to_nice_ident(d) for d in metadata['declares']]
131-
syms = set(syms).difference(metadata['exports'])
132-
syms.update(metadata['globalImports'])
130+
syms = settings.DEFAULT_LIBRARY_FUNCS_TO_INCLUDE + [to_nice_ident(d) for d in metadata.imports]
131+
syms = set(syms).difference(metadata.exports)
132+
syms.update(metadata.globalImports)
133133
settings.DEFAULT_LIBRARY_FUNCS_TO_INCLUDE = sorted(syms)
134134
if settings.MAIN_MODULE:
135135
get_weak_imports(wasm_file)
136136

137-
settings.WASM_EXPORTS = metadata['exports'] + list(metadata['namedGlobals'].keys())
137+
settings.WASM_EXPORTS = metadata.exports + list(metadata.namedGlobals.keys())
138138
# Store function exports so that Closure and metadce can track these even in
139139
# -sDECLARE_ASM_MODULE_EXPORTS=0 builds.
140-
settings.WASM_FUNCTION_EXPORTS = metadata['exports']
140+
settings.WASM_FUNCTION_EXPORTS = metadata.exports
141141

142142
# start with the MVP features, and add any detected features.
143-
settings.BINARYEN_FEATURES = ['--mvp-features'] + metadata['features']
143+
settings.BINARYEN_FEATURES = ['--mvp-features'] + metadata.features
144144
if settings.ASYNCIFY == 2:
145145
settings.BINARYEN_FEATURES += ['--enable-reference-types']
146146

@@ -156,15 +156,15 @@ def update_settings_glue(wasm_file, metadata):
156156

157157
# When using dynamic linking the main function might be in a side module.
158158
# To be safe assume they do take input parametes.
159-
settings.MAIN_READS_PARAMS = metadata['mainReadsParams'] or bool(settings.MAIN_MODULE)
159+
settings.MAIN_READS_PARAMS = metadata.mainReadsParams or bool(settings.MAIN_MODULE)
160160
if settings.MAIN_READS_PARAMS and not settings.STANDALONE_WASM:
161161
# callMain depends on this library function
162162
settings.DEFAULT_LIBRARY_FUNCS_TO_INCLUDE += ['$allocateUTF8OnStack']
163163

164164
if settings.STACK_OVERFLOW_CHECK and not settings.SIDE_MODULE:
165165
# writeStackCookie and checkStackCookie both rely on emscripten_stack_get_end being
166166
# exported. In theory it should always be present since its defined in compiler-rt.
167-
assert 'emscripten_stack_get_end' in metadata['exports']
167+
assert 'emscripten_stack_get_end' in metadata.exports
168168

169169

170170
def apply_static_code_hooks(forwarded_json, code):
@@ -279,7 +279,7 @@ def trim_asm_const_body(body):
279279

280280
def create_named_globals(metadata):
281281
named_globals = []
282-
for k, v in metadata['namedGlobals'].items():
282+
for k, v in metadata.namedGlobals.items():
283283
v = int(v)
284284
if settings.RELOCATABLE:
285285
v += settings.GLOBAL_BASE
@@ -308,19 +308,19 @@ def emscript(in_wasm, out_wasm, outfile_js, memfile):
308308
metadata = finalize_wasm(in_wasm, out_wasm, memfile)
309309

310310
if settings.RELOCATABLE and settings.MEMORY64 == 2:
311-
metadata['globalImports'] += ['__memory_base32']
311+
metadata.globalImports += ['__memory_base32']
312312

313313
update_settings_glue(out_wasm, metadata)
314314

315-
if not settings.WASM_BIGINT and metadata['emJsFuncs']:
315+
if not settings.WASM_BIGINT and metadata.emJsFuncs:
316316
import_map = {}
317317

318318
with webassembly.Module(in_wasm) as module:
319319
types = module.get_types()
320320
for imp in module.get_imports():
321321
import_map[imp.field] = imp
322322

323-
for em_js_func, raw in metadata.get('emJsFuncs', {}).items():
323+
for em_js_func, raw in metadata.emJsFuncs.items():
324324
c_sig = raw.split('<::>')[0].strip('()')
325325
if not c_sig or c_sig == 'void':
326326
c_sig = []
@@ -334,9 +334,9 @@ def emscript(in_wasm, out_wasm, outfile_js, memfile):
334334
diagnostics.warning('em-js-i64', 'using 64-bit arguments in EM_JS function without WASM_BIGINT is not yet fully supported: `%s` (%s, %s)', em_js_func, c_sig, signature.params)
335335

336336
if settings.SIDE_MODULE:
337-
if metadata['asmConsts']:
337+
if metadata.asmConsts:
338338
exit_with_error('EM_ASM is not supported in side modules')
339-
if metadata['emJsFuncs']:
339+
if metadata.emJsFuncs:
340340
exit_with_error('EM_JS is not supported in side modules')
341341
logger.debug('emscript: skipping remaining js glue generation')
342342
return
@@ -360,9 +360,9 @@ def emscript(in_wasm, out_wasm, outfile_js, memfile):
360360
settings.INITIAL_TABLE = dylink_sec.table_size + 1
361361

362362
if settings.ASYNCIFY:
363-
metadata['globalImports'] += ['__asyncify_state', '__asyncify_data']
363+
metadata.globalImports += ['__asyncify_state', '__asyncify_data']
364364

365-
invoke_funcs = metadata['invokeFuncs']
365+
invoke_funcs = metadata.invokeFuncs
366366
if invoke_funcs:
367367
settings.DEFAULT_LIBRARY_FUNCS_TO_INCLUDE += ['$getWasmTableEntry']
368368

@@ -385,7 +385,7 @@ def emscript(in_wasm, out_wasm, outfile_js, memfile):
385385
pre += f" ignoredModuleProp('{sym}');\n"
386386
pre += "}\n"
387387

388-
exports = metadata['exports']
388+
exports = metadata.exports
389389

390390
if settings.ASYNCIFY:
391391
exports += ['asyncify_start_unwind', 'asyncify_stop_unwind', 'asyncify_start_rewind', 'asyncify_stop_rewind']
@@ -452,7 +452,7 @@ def get_metadata(infile, outfile, modify_wasm, args):
452452
# re-read parts of the metadata post-finalize
453453
extract_metadata.update_metadata(outfile, metadata)
454454
if DEBUG:
455-
logger.debug("Metadata: " + pprint.pformat(metadata))
455+
logger.debug("Metadata: " + pprint.pformat(metadata.__dict__))
456456
return metadata
457457

458458

@@ -542,7 +542,7 @@ def finalize_wasm(infile, outfile, memfile):
542542
# Calculate the subset of exports that were explicitly marked with llvm.used.
543543
# These are any exports that were not requested on the command line and are
544544
# not known auto-generated system functions.
545-
unexpected_exports = [e for e in metadata['exports'] if treat_as_user_function(e)]
545+
unexpected_exports = [e for e in metadata.exports if treat_as_user_function(e)]
546546
unexpected_exports = [asmjs_mangle(e) for e in unexpected_exports]
547547
unexpected_exports = [e for e in unexpected_exports if e not in expected_exports]
548548
building.user_requested_exports.update(unexpected_exports)
@@ -553,7 +553,7 @@ def finalize_wasm(infile, outfile, memfile):
553553

554554
def create_asm_consts(metadata):
555555
asm_consts = {}
556-
for addr, const in metadata['asmConsts'].items():
556+
for addr, const in metadata.asmConsts.items():
557557
body = trim_asm_const_body(const)
558558
args = []
559559
max_arity = 16
@@ -595,7 +595,7 @@ def func_type_to_sig(type):
595595
def create_em_js(metadata):
596596
em_js_funcs = []
597597
separator = '<::>'
598-
for name, raw in metadata.get('emJsFuncs', {}).items():
598+
for name, raw in metadata.emJsFuncs.items():
599599
assert separator in raw
600600
args, body = raw.split(separator, 1)
601601
args = args[1:-1]
@@ -606,8 +606,8 @@ def create_em_js(metadata):
606606
arg_names = [arg.split()[-1].replace("*", "") for arg in args if arg]
607607
args = ','.join(arg_names)
608608
func = f'function {name}({args}) {body}'
609-
if settings.ASYNCIFY == 2 and name in metadata['emJsFuncTypes']:
610-
sig = func_type_to_sig(metadata['emJsFuncTypes'][name])
609+
if settings.ASYNCIFY == 2 and name in metadata.emJsFuncTypes:
610+
sig = func_type_to_sig(metadata.emJsFuncTypes[name])
611611
func = func + f'\n{name}.sig = \'{sig}\';'
612612
em_js_funcs.append(func)
613613

@@ -677,13 +677,13 @@ def add_send_items(name, mangled_name, ignore_dups=False):
677677
assert name not in send_items_map, 'duplicate symbol in exports: %s' % name
678678
send_items_map[name] = mangled_name
679679

680-
for name in metadata['emJsFuncs']:
680+
for name in metadata.emJsFuncs:
681681
add_send_items(name, name)
682682
for name in invoke_funcs:
683683
add_send_items(name, name)
684-
for name in metadata['declares']:
684+
for name in metadata.imports:
685685
add_send_items(name, asmjs_mangle(name))
686-
for name in metadata['globalImports']:
686+
for name in metadata.globalImports:
687687
# globalImports can currently overlap with declares, in the case of dynamic linking
688688
add_send_items(name, asmjs_mangle(name), ignore_dups=settings.RELOCATABLE)
689689

@@ -848,7 +848,7 @@ def create_wasm64_wrappers(metadata):
848848

849849
sigs_seen = set()
850850
wrap_functions = []
851-
for exp in metadata['exports']:
851+
for exp in metadata.exports:
852852
sig = mapping.get(exp)
853853
if sig:
854854
if sig not in sigs_seen:

tools/extract_metadata.py

Lines changed: 36 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -235,21 +235,21 @@ def get_named_globals(module, exports):
235235

236236

237237
def update_metadata(filename, metadata):
238-
declares = []
238+
imports = []
239239
invoke_funcs = []
240-
em_js_funcs = set(metadata['emJsFuncs'])
240+
em_js_funcs = set(metadata.emJsFuncs)
241241
with webassembly.Module(filename) as module:
242242
for i in module.get_imports():
243243
if i.kind == webassembly.ExternType.FUNC:
244244
if i.field.startswith('invoke_'):
245245
invoke_funcs.append(i.field)
246246
elif i.field not in em_js_funcs:
247-
declares.append(i.field)
247+
imports.append(i.field)
248248

249249
exports = [e.name for e in module.get_exports() if e.kind in [webassembly.ExternType.FUNC, webassembly.ExternType.TAG]]
250-
metadata['declares'] = declares
251-
metadata['exports'] = exports
252-
metadata['invokeFuncs'] = invoke_funcs
250+
metadata.imports = imports
251+
metadata.exports = exports
252+
metadata.invokeFuncs = invoke_funcs
253253

254254

255255
def get_string_at(module, address):
@@ -259,9 +259,25 @@ def get_string_at(module, address):
259259
return data_to_string(data[offset:str_end])
260260

261261

262+
class Metadata:
263+
imports: []
264+
export: []
265+
asmConsts: []
266+
emJsFuncs: {}
267+
emJsFuncTypes: []
268+
features: []
269+
globalImports: []
270+
invokeFuncs: []
271+
mainReadsParams: bool
272+
namedGlobals: []
273+
274+
def __init__(self):
275+
pass
276+
277+
262278
def extract_metadata(filename):
263279
export_names = []
264-
declares = []
280+
import_names = []
265281
invoke_funcs = []
266282
global_imports = []
267283
em_js_funcs = {}
@@ -291,7 +307,7 @@ def extract_metadata(filename):
291307
types = module.get_types()
292308
em_js_func_types[i.field] = types[i.type]
293309
else:
294-
declares.append(i.field)
310+
import_names.append(i.field)
295311

296312
export_names = [e.name for e in exports if e.kind in [webassembly.ExternType.FUNC, webassembly.ExternType.TAG]]
297313

@@ -303,16 +319,17 @@ def extract_metadata(filename):
303319

304320
# If main does not read its parameters, it will just be a stub that
305321
# calls __original_main (which has no parameters).
306-
metadata = {}
307-
metadata['asmConsts'] = get_asm_strings(module, export_map)
308-
metadata['declares'] = declares
309-
metadata['emJsFuncs'] = em_js_funcs
310-
metadata['emJsFuncTypes'] = em_js_func_types
311-
metadata['exports'] = export_names
312-
metadata['features'] = features
313-
metadata['globalImports'] = global_imports
314-
metadata['invokeFuncs'] = invoke_funcs
315-
metadata['mainReadsParams'] = get_main_reads_params(module, export_map)
316-
metadata['namedGlobals'] = get_named_globals(module, exports)
322+
metadata = Metadata()
323+
metadata.imports = import_names
324+
metadata.exports = export_names
325+
metadata.asmConsts = get_asm_strings(module, export_map)
326+
metadata.emJsFuncs = em_js_funcs
327+
metadata.emJsFuncTypes = em_js_func_types
328+
metadata.features = features
329+
metadata.globalImports = global_imports
330+
metadata.invokeFuncs = invoke_funcs
331+
metadata.mainReadsParams = get_main_reads_params(module, export_map)
332+
metadata.namedGlobals = get_named_globals(module, exports)
333+
317334
# print("Metadata parsed: " + pprint.pformat(metadata))
318335
return metadata

0 commit comments

Comments
 (0)