@@ -53,55 +53,52 @@ enum GlobalString<'a> {
53
53
}
54
54
55
55
fn encode_global_strings < ' a > ( module : & mut Module < ' a > ) -> Vec < GlobalString < ' a > > {
56
- let mut global_strings = Vec :: new ( ) ;
57
56
let cx = module. get_context ( ) ;
58
57
59
- for global in module. get_globals ( ) {
60
- // ignore external globals
61
- if matches ! ( global. get_linkage( ) , Linkage :: External ) {
62
- continue ;
63
- }
64
-
65
- match global. get_initializer ( ) {
58
+ module
59
+ . get_globals ( )
60
+ . filter ( |global| !matches ! ( global. get_linkage( ) , Linkage :: External ) )
61
+ . filter_map ( |global| match global. get_initializer ( ) ? {
66
62
// C-like strings
67
- Some ( BasicValueEnum :: ArrayValue ( arr) ) if arr. is_const_string ( ) => {
68
- let encoded_str = match arr. get_string_constant ( ) {
69
- Some ( s) => s
70
- . to_bytes_with_nul ( )
71
- . iter ( )
72
- . map ( |c| * c + 1 )
73
- . collect :: < Vec < _ > > ( ) ,
74
- None => continue ,
75
- } ;
76
- let new_const = cx. const_string ( & encoded_str, false ) ;
77
- global. set_initializer ( & new_const) ;
78
- global. set_constant ( false ) ;
79
- global_strings. push ( GlobalString :: Array ( global, encoded_str. len ( ) as u32 ) ) ;
80
- }
63
+ BasicValueEnum :: ArrayValue ( arr) => Some ( ( global, None , arr) ) ,
81
64
// Rust-like strings
82
- Some ( BasicValueEnum :: StructValue ( stru) ) if stru. count_fields ( ) <= 1 => {
83
- let arr = match stru. get_field_at_index ( 0 ) {
84
- Some ( BasicValueEnum :: ArrayValue ( arr) ) if arr. is_const_string ( ) => arr,
85
- _ => continue ,
86
- } ;
87
- let encoded_str = match arr. get_string_constant ( ) {
88
- Some ( s) => s
89
- . to_bytes_with_nul ( )
90
- . iter ( )
91
- . map ( |c| * c + 1 )
92
- . collect :: < Vec < _ > > ( ) ,
93
- None => continue ,
94
- } ;
65
+ BasicValueEnum :: StructValue ( stru) if stru. count_fields ( ) <= 1 => {
66
+ match stru. get_field_at_index ( 0 ) ? {
67
+ BasicValueEnum :: ArrayValue ( arr) => Some ( ( global, Some ( stru) , arr) ) ,
68
+ _ => None ,
69
+ }
70
+ }
71
+ _ => None ,
72
+ } )
73
+ . filter ( |( _, _, arr) | {
74
+ // needs to be called before `get_string_constant`, otherwise it may crash
75
+ arr. is_const_string ( )
76
+ } )
77
+ . filter_map ( |( global, stru, arr) | {
78
+ // we ignore non-UTF8 strings, since they are probably not human-readable
79
+ let s = arr. get_string_constant ( ) . and_then ( |s| s. to_str ( ) . ok ( ) ) ?;
80
+ let encoded_str = s. bytes ( ) . map ( |c| c + 1 ) . collect :: < Vec < _ > > ( ) ;
81
+ Some ( ( global, stru, encoded_str) )
82
+ } )
83
+ . map ( |( global, stru, encoded_str) | {
84
+ if let Some ( stru) = stru {
85
+ // Rust-like strings
95
86
let new_const = cx. const_string ( & encoded_str, false ) ;
96
87
stru. set_field_at_index ( 0 , new_const) ;
88
+ global. set_initializer ( & stru) ;
97
89
global. set_constant ( false ) ;
98
- global_strings. push ( GlobalString :: Struct ( global, 0 , encoded_str. len ( ) as u32 ) ) ;
99
- }
100
- _ => ( ) ,
101
- }
102
- }
103
90
104
- global_strings
91
+ GlobalString :: Struct ( global, 0 , encoded_str. len ( ) as u32 )
92
+ } else {
93
+ // C-like strings
94
+ let new_const = cx. const_string ( & encoded_str, false ) ;
95
+ global. set_initializer ( & new_const) ;
96
+ global. set_constant ( false ) ;
97
+
98
+ GlobalString :: Array ( global, encoded_str. len ( ) as u32 )
99
+ }
100
+ } )
101
+ . collect ( )
105
102
}
106
103
107
104
fn create_decode_fn < ' a > ( module : & mut Module < ' a > ) -> FunctionValue < ' a > {
0 commit comments