@@ -89,7 +89,7 @@ unsafe fn extract_file_and_line(execute_data: &zend_execute_data) -> (Option<Thi
89
89
mod detail {
90
90
use super :: * ;
91
91
use crate :: string_set:: StringSet ;
92
- use datadog_thin_str:: ThinStr ;
92
+ use datadog_thin_str:: { ThinHeader , ThinStr } ;
93
93
use log:: { debug, trace} ;
94
94
use std:: cell:: RefCell ;
95
95
use std:: ops:: Deref ;
@@ -103,34 +103,37 @@ mod detail {
103
103
string_set : & ' a mut StringSet ,
104
104
}
105
105
106
+ #[ repr( usize ) ]
107
+ enum CacheSlot {
108
+ Function = 0 ,
109
+ Filename = 1 ,
110
+ }
111
+
106
112
impl < ' a > StringCache < ' a > {
107
113
/// Makes a copy of the string in the cache slot. If there isn't a
108
114
/// string in the slot currently, then create one by calling the
109
115
/// provided function, store it in the string cache and cache slot,
110
116
/// and return it.
111
- fn get_or_insert < F > ( & mut self , slot : usize , f : F ) -> Option < ThinString >
117
+ fn get_or_insert < F > ( & mut self , slot : CacheSlot , f : F ) -> Option < ThinString >
112
118
where
113
119
F : FnOnce ( ) -> Option < ThinString > ,
114
120
{
115
- debug_assert ! ( slot < self . cache_slots . len ( ) ) ;
116
- let cached = unsafe { self . cache_slots . get_unchecked_mut ( slot) } ;
121
+ // SAFETY: the slot is in-bounds from CacheSlot -> usize conv.
122
+ let cached = unsafe { self . cache_slots . get_unchecked_mut ( slot as usize ) } ;
117
123
118
- let ptr = * cached as * mut u8 ;
124
+ let ptr = * cached as * mut ThinHeader ;
119
125
match NonNull :: new ( ptr) {
120
126
Some ( non_null) => {
121
- // SAFETY: transmuting ThinStr from its repr.
122
- let thin_str: ThinStr = unsafe { core:: mem:: transmute ( non_null) } ;
123
127
// SAFETY: the string set is only reset between requests,
124
- // so this ThinStr points into the same string set that
125
- // created it.
126
- let str = unsafe { self . string_set . get_thin_str ( thin_str ) } ;
127
- Some ( ThinString :: from_str_in ( str , Global ) )
128
+ // so this ThinStr points into the same string set arena
129
+ // that created it.
130
+ let thin_str : ThinStr = unsafe { ThinStr :: from_raw ( non_null ) } ;
131
+ Some ( ThinString :: from_str_in ( thin_str . deref ( ) , Global ) )
128
132
}
129
133
None => {
130
134
let string = f ( ) ?;
131
135
let thin_str = self . string_set . insert ( & string) ;
132
- // SAFETY: transmuting ThinStr into its repr.
133
- let non_null: NonNull < u8 > = unsafe { core:: mem:: transmute ( thin_str) } ;
136
+ let non_null = thin_str. header_ptr ( ) ;
134
137
* cached = non_null. as_ptr ( ) as usize ;
135
138
Some ( string)
136
139
}
@@ -321,15 +324,16 @@ mod detail {
321
324
func : & zend_function ,
322
325
string_cache : & mut StringCache ,
323
326
) -> Option < ThinString > {
324
- let fname = string_cache. get_or_insert ( 0 , || extract_function_name ( func) ) ?;
327
+ let fname =
328
+ string_cache. get_or_insert ( CacheSlot :: Function , || extract_function_name ( func) ) ?;
325
329
Some ( ThinString :: from_str_in ( & fname, Global ) )
326
330
}
327
331
328
332
unsafe fn handle_file_cache_slot (
329
333
execute_data : & zend_execute_data ,
330
334
string_cache : & mut StringCache ,
331
335
) -> ( Option < ThinString > , u32 ) {
332
- let option = string_cache. get_or_insert ( 1 , || -> Option < ThinString > {
336
+ let option = string_cache. get_or_insert ( CacheSlot :: Filename , || -> Option < ThinString > {
333
337
unsafe {
334
338
// Safety: if we have cache slots, we definitely have a func.
335
339
let func = & * execute_data. func ;
0 commit comments