Skip to content

Commit 5827570

Browse files
committed
Fix detection of main wrapper function
Note that the expectations for test_metadce_mem grew because we were previously mis-detecting mem.c as not read params, when in fact it does. Fixes: #17720
1 parent 44fd8b1 commit 5827570

12 files changed

+80
-28
lines changed

test/core/test_main_reads_args.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
extern int real_main(int, char**);
2+
3+
int main(int argc, char** argv) {
4+
return real_main(argc, argv);
5+
}

test/core/test_main_reads_args.out

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
argc: 1
2+
argv[0]: test_main_reads_args.js

test/core/test_main_reads_args_real.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#include <stdio.h>
2+
#include <string.h>
3+
4+
int real_main(int argc, char** argv) {
5+
printf("argc: %d\n", argc);
6+
const char* arg0 = strrchr(argv[0], '/');
7+
if (!arg0)
8+
arg0 = strrchr(argv[0], '\\');
9+
printf("argv[0]: %s\n", arg0 + 1);
10+
return 0;
11+
}

test/other/metadce/test_metadce_mem_O3.exports

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ b
22
c
33
d
44
e
5+
f
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
$__wasm_call_ctors
22
$main
33
$sbrk
4+
$stackAlloc
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
5935
1+
5957

test/other/metadce/test_metadce_mem_O3_grow.exports

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ b
22
c
33
d
44
e
5+
f
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
$__wasm_call_ctors
22
$main
33
$sbrk
4+
$stackAlloc
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
5936
1+
5958

test/test_core.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9489,6 +9489,10 @@ def test_js_library_i64_params(self):
94899489
self.emcc_args += ['--js-library=' + test_file('core/js_library_i64_params.js')]
94909490
self.do_core_test('js_library_i64_params.c')
94919491

9492+
def test_main_reads_args(self):
9493+
self.run_process([EMCC, '-c', test_file('core/test_main_reads_args_real.c'), '-o', 'real.o'] + self.get_emcc_args(ldflags=False))
9494+
self.do_core_test('test_main_reads_args.c', emcc_args=['real.o', '-sEXIT_RUNTIME'])
9495+
94929496

94939497
# Generate tests for everything
94949498
def make_run(name, emcc_args, settings=None, env=None, node_args=None, require_v8=False, v8_args=None):

tools/extract_metadata.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,24 +18,29 @@ def skip_function_header(module):
1818

1919

2020
def is_orig_main_wrapper(module, function):
21+
module.get_types()
22+
module.get_function_types()
2123
module.seek(function.offset)
2224
skip_function_header(module)
2325
end = function.offset + function.size
2426
while module.tell() != end:
2527
opcode = module.read_byte()
2628
try:
2729
opcode = OpCode(opcode)
28-
except ValueError as e:
29-
print(e)
30+
except ValueError:
3031
return False
3132
if opcode == OpCode.CALL:
32-
module.read_uleb() # callee
33+
callee = module.read_uleb()
34+
callee_type = module.get_function_type(callee)
35+
if len(callee_type.params) != 0:
36+
return False
3337
elif opcode in (OpCode.LOCAL_GET, OpCode.LOCAL_SET):
3438
module.read_uleb() # local index
3539
elif opcode in (OpCode.END, OpCode.RETURN):
3640
pass
3741
else:
3842
# Any other opcodes and we assume this not a simple wrapper
43+
print("Uknown opcode: %s" % opcode)
3944
return False
4045

4146
assert opcode == OpCode.END

tools/webassembly.py

Lines changed: 44 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,7 @@ def sections(self):
272272
yield Section(section_type, section_size, section_offset, name)
273273
offset = section_offset + section_size
274274

275+
@memoize
275276
def get_types(self):
276277
type_section = self.get_section(SecType.TYPE)
277278
if not type_section:
@@ -280,17 +281,21 @@ def get_types(self):
280281
num_types = self.read_uleb()
281282
types = []
282283
for _ in range(num_types):
283-
params = []
284-
returns = []
285284
type_form = self.read_byte()
286285
assert type_form == 0x60
286+
287+
params = []
287288
num_params = self.read_uleb()
288289
for _ in range(num_params):
289290
params.append(self.read_type())
291+
292+
returns = []
290293
num_returns = self.read_uleb()
291294
for _ in range(num_returns):
292295
returns.append(self.read_type())
296+
293297
types.append(FuncType(params, returns))
298+
294299
return types
295300

296301
def parse_features_section(self):
@@ -503,39 +508,55 @@ def get_tables(self):
503508

504509
return tables
505510

511+
@memoize
512+
def get_function_types(self):
513+
function_section = self.get_section(SecType.FUNCTION)
514+
if not function_section:
515+
return []
516+
517+
self.seek(function_section.offset)
518+
num_types = self.read_uleb()
519+
func_types = []
520+
for _ in range(num_types):
521+
func_types.append(self.read_uleb())
522+
return func_types
523+
506524
def has_name_section(self):
507525
return self.get_custom_section('name') is not None
508526

509527
@once
510528
def _calc_indexes(self):
511-
self.num_imported_funcs = 0
512-
self.num_imported_globals = 0
513-
self.num_imported_memories = 0
514-
self.num_imported_tables = 0
515-
self.num_imported_tags = 0
529+
self.imports_by_kind = {}
516530
for i in self.get_imports():
517-
if i.kind == ExternType.FUNC:
518-
self.num_imported_funcs += 1
519-
elif i.kind == ExternType.GLOBAL:
520-
self.num_imported_globals += 1
521-
elif i.kind == ExternType.MEMORY:
522-
self.num_imported_memories += 1
523-
elif i.kind == ExternType.TABLE:
524-
self.num_imported_tables += 1
525-
elif i.kind == ExternType.TAG:
526-
self.num_imported_tags += 1
527-
else:
528-
assert False, 'unhandled export type: %s' % i.kind
531+
self.imports_by_kind.setdefault(i.kind, [])
532+
self.imports_by_kind[i.kind].append(i)
533+
534+
def num_imported_funcs(self):
535+
self._calc_indexes()
536+
return len(self.imports_by_kind.get(ExternType.FUNC, []))
537+
538+
def num_imported_globals(self):
539+
self._calc_indexes()
540+
return len(self.imports_by_kind.get(ExternType.GLOBAL, []))
529541

530542
def get_function(self, idx):
531543
self._calc_indexes()
532-
assert idx >= self.num_imported_funcs
533-
return self.get_functions()[idx - self.num_imported_funcs]
544+
assert idx >= self.num_imported_funcs()
545+
return self.get_functions()[idx - self.num_imported_funcs()]
534546

535547
def get_global(self, idx):
536548
self._calc_indexes()
537-
assert idx >= self.num_imported_globals
538-
return self.get_globals()[idx - self.num_imported_globals]
549+
assert idx >= self.num_imported_globals()
550+
return self.get_globals()[idx - self.num_imported_globals()]
551+
552+
def get_function_type(self, idx):
553+
self._calc_indexes()
554+
if idx < self.num_imported_funcs():
555+
imp = self.imports_by_kind[ExternType.FUNC][idx]
556+
func_type = imp.type
557+
else:
558+
func_type = self.get_function_types()[idx - self.num_imported_funcs()]
559+
return self.get_types()[func_type]
539560

540561

541562
def parse_dylink_section(wasm_file):

0 commit comments

Comments
 (0)