@@ -12,13 +12,26 @@ fn retain_count(obj: &Object) -> usize {
12
12
fn create_data ( bytes : & [ u8 ] ) -> Id < Object , Shared > {
13
13
let bytes_ptr = bytes. as_ptr ( ) as * const c_void ;
14
14
unsafe {
15
- // All code between the `msg_send!` and the `retain_autoreleased` must
16
- // be able to be optimized away for this to work.
15
+ // let obj: *mut Object = msg_send![
16
+ // class!(NSMutableData),
17
+ // dataWithBytes: bytes_ptr,
18
+ // length: bytes.len(),
19
+ // ];
20
+ //
21
+ // On x86 (and perhaps others), dataWithBytes does not tail call
22
+ // `autorelease` and hence the return address points into that instead
23
+ // of our code, making the fast autorelease scheme fail.
24
+ //
25
+ // So instead, we call `autorelease` manually here.
26
+ let obj: * mut Object = msg_send ! [ class!( NSMutableData ) , alloc] ;
17
27
let obj: * mut Object = msg_send ! [
18
- class! ( NSData ) ,
19
- dataWithBytes : bytes_ptr,
28
+ obj ,
29
+ initWithBytes : bytes_ptr,
20
30
length: bytes. len( ) ,
21
31
] ;
32
+ let obj: * mut Object = msg_send ! [ obj, autorelease] ;
33
+ // All code between the `msg_send!` and the `retain_autoreleased` must
34
+ // be able to be optimized away for this to work.
22
35
Id :: retain_autoreleased ( obj) . unwrap ( )
23
36
}
24
37
}
0 commit comments