@@ -22,6 +22,10 @@ struct C {
22
22
return_pointer_area_align : usize ,
23
23
names : Ns ,
24
24
needs_string : bool ,
25
+ needs_union_int32_float : bool ,
26
+ needs_union_float_int32 : bool ,
27
+ needs_union_int64_double : bool ,
28
+ needs_union_double_int64 : bool ,
25
29
prim_names : HashSet < String > ,
26
30
world : String ,
27
31
sizes : SizeAlign ,
@@ -331,7 +335,7 @@ impl WorldGenerator for C {
331
335
self . src. h_helpers,
332
336
"
333
337
// Transfers ownership of `s` into the string `ret`
334
- void {snake}_string_set({snake}_string_t *ret, {c_string_ty} *s);
338
+ void {snake}_string_set({snake}_string_t *ret, const {c_string_ty} *s);
335
339
336
340
// Creates a copy of the input nul-terminate string `s` and
337
341
// stores it into the component model string `ret`.
@@ -345,14 +349,14 @@ impl WorldGenerator for C {
345
349
uwrite ! (
346
350
self . src. c_helpers,
347
351
"
348
- void {snake}_string_set({snake}_string_t *ret, {c_string_ty} *s) {{
352
+ void {snake}_string_set({snake}_string_t *ret, const {c_string_ty} *s) {{
349
353
ret->ptr = ({ty}*) s;
350
354
ret->len = {strlen};
351
355
}}
352
356
353
357
void {snake}_string_dup({snake}_string_t *ret, const {c_string_ty} *s) {{
354
358
ret->len = {strlen};
355
- ret->ptr = cabi_realloc(NULL, 0, {size}, ret->len * {size});
359
+ ret->ptr = ({ty}*) cabi_realloc(NULL, 0, {size}, ret->len * {size});
356
360
memcpy(ret->ptr, s, ret->len * {size});
357
361
}}
358
362
@@ -366,6 +370,30 @@ impl WorldGenerator for C {
366
370
" ,
367
371
) ;
368
372
}
373
+ if self . needs_union_int32_float {
374
+ uwriteln ! (
375
+ self . src. c_helpers,
376
+ "\n union int32_float {{ int32_t a; float b; }};"
377
+ ) ;
378
+ }
379
+ if self . needs_union_float_int32 {
380
+ uwriteln ! (
381
+ self . src. c_helpers,
382
+ "\n union float_int32 {{ float a; int32_t b; }};"
383
+ ) ;
384
+ }
385
+ if self . needs_union_int64_double {
386
+ uwriteln ! (
387
+ self . src. c_helpers,
388
+ "\n union int64_double {{ int64_t a; double b; }};"
389
+ ) ;
390
+ }
391
+ if self . needs_union_double_int64 {
392
+ uwriteln ! (
393
+ self . src. c_helpers,
394
+ "\n union double_int64 {{ double a; int64_t b; }};"
395
+ ) ;
396
+ }
369
397
let version = env ! ( "CARGO_PKG_VERSION" ) ;
370
398
let mut h_str = wit_bindgen_core:: Source :: default ( ) ;
371
399
@@ -570,6 +598,51 @@ impl C {
570
598
self . type_names . retain ( |k, _| live_import_types. contains ( k) ) ;
571
599
self . resources . retain ( |k, _| live_import_types. contains ( k) ) ;
572
600
}
601
+
602
+ fn perform_cast ( & mut self , op : & str , cast : & Bitcast ) -> String {
603
+ match cast {
604
+ Bitcast :: I32ToF32 | Bitcast :: I64ToF32 => {
605
+ self . needs_union_int32_float = true ;
606
+ format ! ( "((union int32_float){{ (int32_t) {} }}).b" , op)
607
+ }
608
+ Bitcast :: F32ToI32 | Bitcast :: F32ToI64 => {
609
+ self . needs_union_float_int32 = true ;
610
+ format ! ( "((union float_int32){{ {} }}).b" , op)
611
+ }
612
+ Bitcast :: I64ToF64 => {
613
+ self . needs_union_int64_double = true ;
614
+ format ! ( "((union int64_double){{ (int64_t) {} }}).b" , op)
615
+ }
616
+ Bitcast :: F64ToI64 => {
617
+ self . needs_union_double_int64 = true ;
618
+ format ! ( "((union double_int64){{ {} }}).b" , op)
619
+ }
620
+ Bitcast :: I32ToI64 | Bitcast :: LToI64 | Bitcast :: PToP64 => {
621
+ format ! ( "(int64_t) {}" , op)
622
+ }
623
+ Bitcast :: I64ToI32 | Bitcast :: I64ToL => {
624
+ format ! ( "(int32_t) {}" , op)
625
+ }
626
+ // P64 is currently represented as int64_t, so no conversion is needed.
627
+ Bitcast :: I64ToP64 | Bitcast :: P64ToI64 => {
628
+ format ! ( "{}" , op)
629
+ }
630
+ Bitcast :: P64ToP | Bitcast :: I32ToP | Bitcast :: LToP => {
631
+ format ! ( "(uint8_t *) {}" , op)
632
+ }
633
+
634
+ // Cast to uintptr_t to avoid implicit pointer-to-int conversions.
635
+ Bitcast :: PToI32 | Bitcast :: PToL => format ! ( "(uintptr_t) {}" , op) ,
636
+
637
+ Bitcast :: I32ToL | Bitcast :: LToI32 | Bitcast :: None => op. to_string ( ) ,
638
+
639
+ Bitcast :: Sequence ( sequence) => {
640
+ let [ first, second] = & * * sequence;
641
+ let inner = self . perform_cast ( op, first) ;
642
+ self . perform_cast ( & inner, second)
643
+ }
644
+ }
645
+ }
573
646
}
574
647
575
648
pub fn imported_types_used_by_exported_interfaces (
@@ -2068,7 +2141,7 @@ impl<'a, 'b> FunctionBindgen<'a, 'b> {
2068
2141
fn load_ext ( & mut self , ty : & str , offset : i32 , operands : & [ String ] , results : & mut Vec < String > ) {
2069
2142
self . load ( ty, offset, operands, results) ;
2070
2143
let result = results. pop ( ) . unwrap ( ) ;
2071
- results. push ( format ! ( "(int32_t) ({}) " , result) ) ;
2144
+ results. push ( format ! ( "(int32_t) {} " , result) ) ;
2072
2145
}
2073
2146
2074
2147
fn store ( & mut self , ty : & str , offset : i32 , operands : & [ String ] ) {
@@ -2208,7 +2281,7 @@ impl Bindgen for FunctionBindgen<'_, '_> {
2208
2281
2209
2282
Instruction :: Bitcasts { casts } => {
2210
2283
for ( cast, op) in casts. iter ( ) . zip ( operands) {
2211
- let op = perform_cast ( op, cast) ;
2284
+ let op = self . gen . gen . perform_cast ( op, cast) ;
2212
2285
results. push ( op) ;
2213
2286
}
2214
2287
}
@@ -2223,11 +2296,12 @@ impl Bindgen for FunctionBindgen<'_, '_> {
2223
2296
results. push ( format ! ( "({}).{}" , op, to_c_ident( & f. name) ) ) ;
2224
2297
}
2225
2298
}
2226
- Instruction :: RecordLift { ty, .. } => {
2299
+ Instruction :: RecordLift { ty, record , .. } => {
2227
2300
let name = self . gen . gen . type_name ( & Type :: Id ( * ty) ) ;
2228
2301
let mut result = format ! ( "({}) {{\n " , name) ;
2229
- for op in operands {
2230
- uwriteln ! ( result, "{}," , op) ;
2302
+ for ( field, op) in record. fields . iter ( ) . zip ( operands. iter ( ) ) {
2303
+ let field_ty = self . gen . gen . type_name ( & field. ty ) ;
2304
+ uwriteln ! ( result, "({}) {}," , field_ty, op) ;
2231
2305
}
2232
2306
result. push_str ( "}" ) ;
2233
2307
results. push ( result) ;
@@ -2239,11 +2313,12 @@ impl Bindgen for FunctionBindgen<'_, '_> {
2239
2313
results. push ( format ! ( "({}).f{}" , op, i) ) ;
2240
2314
}
2241
2315
}
2242
- Instruction :: TupleLift { ty, .. } => {
2316
+ Instruction :: TupleLift { ty, tuple , .. } => {
2243
2317
let name = self . gen . gen . type_name ( & Type :: Id ( * ty) ) ;
2244
2318
let mut result = format ! ( "({}) {{\n " , name) ;
2245
- for op in operands {
2246
- uwriteln ! ( result, "{}," , op) ;
2319
+ for ( ty, op) in tuple. types . iter ( ) . zip ( operands. iter ( ) ) {
2320
+ let ty = self . gen . gen . type_name ( & ty) ;
2321
+ uwriteln ! ( result, "({}) {}," , ty, op) ;
2247
2322
}
2248
2323
result. push_str ( "}" ) ;
2249
2324
results. push ( result) ;
@@ -2943,46 +3018,6 @@ impl Bindgen for FunctionBindgen<'_, '_> {
2943
3018
}
2944
3019
}
2945
3020
2946
- fn perform_cast ( op : & str , cast : & Bitcast ) -> String {
2947
- match cast {
2948
- Bitcast :: I32ToF32 | Bitcast :: I64ToF32 => {
2949
- format ! ( "((union {{ int32_t a; float b; }}){{ {} }}).b" , op)
2950
- }
2951
- Bitcast :: F32ToI32 | Bitcast :: F32ToI64 => {
2952
- format ! ( "((union {{ float a; int32_t b; }}){{ {} }}).b" , op)
2953
- }
2954
- Bitcast :: I64ToF64 => {
2955
- format ! ( "((union {{ int64_t a; double b; }}){{ {} }}).b" , op)
2956
- }
2957
- Bitcast :: F64ToI64 => {
2958
- format ! ( "((union {{ double a; int64_t b; }}){{ {} }}).b" , op)
2959
- }
2960
- Bitcast :: I32ToI64 | Bitcast :: LToI64 | Bitcast :: PToP64 => {
2961
- format ! ( "(int64_t) {}" , op)
2962
- }
2963
- Bitcast :: I64ToI32 | Bitcast :: I64ToL => {
2964
- format ! ( "(int32_t) {}" , op)
2965
- }
2966
- // P64 is currently represented as int64_t, so no conversion is needed.
2967
- Bitcast :: I64ToP64 | Bitcast :: P64ToI64 => {
2968
- format ! ( "{}" , op)
2969
- }
2970
- Bitcast :: P64ToP | Bitcast :: I32ToP | Bitcast :: LToP => {
2971
- format ! ( "(uint8_t *) {}" , op)
2972
- }
2973
-
2974
- // Cast to uintptr_t to avoid implicit pointer-to-int conversions.
2975
- Bitcast :: PToI32 | Bitcast :: PToL => format ! ( "(uintptr_t) {}" , op) ,
2976
-
2977
- Bitcast :: I32ToL | Bitcast :: LToI32 | Bitcast :: None => op. to_string ( ) ,
2978
-
2979
- Bitcast :: Sequence ( sequence) => {
2980
- let [ first, second] = & * * sequence;
2981
- perform_cast ( & perform_cast ( op, first) , second)
2982
- }
2983
- }
2984
- }
2985
-
2986
3021
#[ derive( Default , Clone , Copy ) ]
2987
3022
enum SourceType {
2988
3023
#[ default]
0 commit comments