Skip to content

Commit f08926e

Browse files
committed
v2: minor fixes
1 parent 7b6cdd2 commit f08926e

1 file changed

Lines changed: 23 additions & 9 deletions

File tree

‎vlib/v2/builder/builder.v‎

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,11 @@ fn sanitize_staged_c_source(c_source string) string {
6969
// Pointer dereference for pass-by-pointer array params:
7070
source = source.replace('(_idx_s < ((a)).len)', '(_idx_s < (*(a)).len)')
7171
source = source.replace('&((string*)((a)).data)', '&((string*)(*(a)).data)')
72-
// Result struct declarations that the backend may omit:
73-
source = ensure_result_struct_decl(source, '_result_int', 'int')
74-
source = ensure_result_struct_decl(source, '_result_rune', 'rune')
72+
// Result struct declarations that the backend may omit
73+
// (e.g. due to ARM64 chained-access map bugs in self-hosted binaries):
74+
source = ensure_result_type(source, '_result_string', 'string')
75+
source = ensure_result_type(source, '_result_int', 'int')
76+
source = ensure_result_type(source, '_result_rune', 'rune')
7577
// Builtin function body replacements (V source doesn't lower correctly yet):
7678
source = replace_generated_c_fn(source, 'string u64_to_hex(u64 nn, u8 len)', sanitized_u64_to_hex_fn())
7779
source = replace_generated_c_fn(source, 'string u64_to_hex_no_leading_zeros(u64 nn, u8 len)',
@@ -114,14 +116,26 @@ fn sanitize_staged_c_source(c_source string) string {
114116
return source
115117
}
116118

117-
fn ensure_result_struct_decl(source string, struct_name string, elem_c_type string) string {
118-
if source.contains('struct ${struct_name} {') {
119+
// ensure_result_type ensures that a _result_* type has both typedef and struct definition
120+
// in the generated C source. This is a safety net for when the cleanc backend's alias
121+
// registration fails (e.g. due to ARM64 chained-access map bugs in self-hosted binaries).
122+
fn ensure_result_type(source string, type_name string, val_type string) string {
123+
if source.contains('struct ${type_name} {') {
119124
return source
120125
}
121-
anchor := 'struct _result_string { bool is_error; IError err; u8 data[sizeof(string) > 1 ? sizeof(string) : 1]; };'
122-
replacement := anchor +
123-
'\nstruct ${struct_name} { bool is_error; IError err; u8 data[sizeof(${elem_c_type}) > 1 ? sizeof(${elem_c_type}) : 1]; };'
124-
return source.replace(anchor, replacement)
126+
// Find insertion point: after the _result base struct, or after typedef section
127+
decl := 'typedef struct ${type_name} ${type_name};\n' +
128+
'struct ${type_name} { bool is_error; IError err; u8 data[sizeof(${val_type}) > 1 ? sizeof(${val_type}) : 1]; };\n'
129+
// Try to insert after the base _result struct definition
130+
anchor := 'struct _result { bool is_error; IError err; };\n'
131+
if source.contains(anchor) {
132+
return source.replace(anchor, anchor + decl)
133+
}
134+
// Fallback: insert before the first function forward declaration
135+
fwd_marker := source.index('\nvoid __v_live_init') or {
136+
source.index('\nint main(') or { return source }
137+
}
138+
return source[..fwd_marker] + '\n' + decl + source[fwd_marker..]
125139
}
126140

127141
fn ensure_string_eq_impl(source string) string {

0 commit comments

Comments
 (0)