Skip to content

Commit 9be8c51

Browse files
committed
WIP. fix bugs about returning a pointer
1 parent 818481b commit 9be8c51

1 file changed

Lines changed: 63 additions & 16 deletions

File tree

ci/generate_checked_functions.py

Lines changed: 63 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,42 @@
11
from pycparser import c_parser, c_ast, parse_file
22
import os
3+
from pprint import pprint
34

45

56
# Updated generate_checked_function to dynamically update Result definition for new return types
67

78

8-
def generate_checked_function(func):
9+
def collect_typedefs(ast):
10+
typedefs = {}
11+
for node in ast.ext:
12+
if isinstance(node, c_ast.Typedef):
13+
typedefs[node.name] = node.type
14+
return typedefs
15+
16+
def resolve_typedef(typedefs, type_name):
17+
resolved_type = typedefs.get(type_name)
18+
19+
# Return the original type name if not a typedef
20+
if not resolved_type:
21+
return type_name
22+
23+
print(f"Resolving typedef for {type_name}: {resolved_type}\n")
24+
25+
if isinstance(resolved_type, c_ast.TypeDecl):
26+
# Base case: Return the type name
27+
return " ".join(resolved_type.declname)
28+
elif isinstance(resolved_type, c_ast.PtrDecl):
29+
# Handle pointer typedefs
30+
resolved_type.show()
31+
base_type = " ".join(resolved_type.type.type.name)
32+
return f"{base_type} *"
33+
elif isinstance(resolved_type, c_ast.ArrayDecl):
34+
# Handle array typedefs
35+
base_type = resolve_typedef(resolved_type.type.declname, typedefs)
36+
return f"{base_type} *"
37+
38+
39+
def generate_checked_function(func, typedefs):
940
func_name = func.name # Access the name directly from Decl
1041
new_func_name = f"{func_name}_checked"
1142

@@ -16,6 +47,8 @@ def generate_checked_function(func):
1647
return_type = "void" # Default to void if no return type is specified
1748
if isinstance(func.type.type, c_ast.TypeDecl):
1849
return_type = " ".join(func.type.type.type.names)
50+
resolved_type = resolve_typedef(typedefs, return_type)
51+
return_type = resolved_type
1952

2053
# Start building the new function
2154
new_func = [f"static inline Result {new_func_name}("]
@@ -55,32 +88,41 @@ def generate_checked_function(func):
5588
# Call the original function
5689
if return_type == "void":
5790
new_func.append(f" {func_name}({', '.join(param_list)});")
58-
new_func.append(f" Result res = {{ .error_code = 0 }};")
5991
elif has_variadic:
6092
new_func.append(" va_start(args, " + param_list[-2] + ");")
6193
new_func.append(
6294
f" {return_type} original_result = {func_name}({', '.join(param_list[:-1])}, args);"
6395
)
6496
new_func.append(" va_end(args);")
65-
new_func.append(f" Result res;")
66-
new_func.append(f" if (original_result == 0) {{")
67-
new_func.append(f" res.error_code = 0;")
68-
new_func.append(f" res.value.{return_type}_value = original_result;")
69-
new_func.append(f" }} else {{")
70-
new_func.append(f" res.error_code = -2;")
71-
new_func.append(f" }}")
7297
else:
7398
new_func.append(
7499
f" {return_type} original_result = {func_name}({', '.join(param_list)});"
75100
)
76-
new_func.append(f" Result res;")
77-
new_func.append(f" if (original_result == 0) {{")
78-
new_func.append(f" res.error_code = 0;")
79101

80-
new_func.append(f" res.value.{return_type}_value = original_result;")
102+
# Handle result return from the original function
103+
new_func.append(f" Result res;")
104+
# if it is bool type
105+
if return_type == "_Bool":
106+
new_func.append(f" if (original_result == 1) {{")
107+
new_func.append(f" res.error_code = 0;")
108+
new_func.append(f" res.value._Bool_value = original_result;")
81109
new_func.append(f" }} else {{")
82-
new_func.append(f" res.error_code = -2;")
110+
new_func.append(f" res.error_code = -1;")
83111
new_func.append(f" }}")
112+
# if it is void type
113+
elif return_type == "void":
114+
new_func.append(f" res.error_code = 0;")
115+
else:
116+
if isinstance(func.type.type, c_ast.PtrDecl):
117+
new_func.append(f" if (original_result != NULL) {{")
118+
new_func.append(f" res.error_code = 0;")
119+
new_func.append(f" res.value.{return_type}_value = original_result;")
120+
new_func.append(f" }} else {{")
121+
new_func.append(f" res.error_code = -1;")
122+
new_func.append(f" }}")
123+
else:
124+
new_func.append(f" res.error_code = 0;")
125+
new_func.append(f" res.value.{return_type}_value = original_result;")
84126

85127
new_func.append(f" return res;")
86128
new_func.append("}")
@@ -130,6 +172,10 @@ def process_header():
130172
],
131173
)
132174

175+
# Collect typedefs
176+
typedefs = collect_typedefs(ast)
177+
# pprint(typedefs)
178+
133179
# Collect all function declarations
134180
functions = [
135181
node
@@ -142,7 +188,8 @@ def process_header():
142188
for func in functions:
143189
if isinstance(func.type.type, c_ast.TypeDecl):
144190
return_type = " ".join(func.type.type.type.names)
145-
return_types.add(return_type)
191+
resolved_type = resolve_typedef(typedefs, return_type)
192+
return_types.add(resolved_type)
146193

147194
# Update the Result struct with all return types
148195
for return_type in return_types:
@@ -171,7 +218,7 @@ def process_header():
171218
f.write(RESULT_STRUCT + "\n")
172219

173220
for func in functions:
174-
new_func = generate_checked_function(func)
221+
new_func = generate_checked_function(func, typedefs)
175222
f.write(new_func + "\n\n")
176223

177224
f.write("#endif // WASM_EXPORT_CHECKED_H\n")

0 commit comments

Comments
 (0)