1
1
//! Internal details to be used by instance.rs only
2
- #[ cfg( feature = "iterator" ) ]
3
- use std:: collections:: HashMap ;
4
- #[ cfg( feature = "iterator" ) ]
5
- use std:: convert:: TryInto ;
2
+
6
3
use std:: ffi:: c_void;
7
- #[ cfg( not( feature = "iterator" ) ) ]
8
- use std:: marker:: PhantomData ;
9
4
use std:: ptr:: NonNull ;
10
5
11
6
use wasmer_runtime_core:: {
@@ -17,8 +12,6 @@ use wasmer_runtime_core::{
17
12
use crate :: backends:: decrease_gas_left;
18
13
use crate :: errors:: { VmError , VmResult } ;
19
14
use crate :: ffi:: GasInfo ;
20
- #[ cfg( feature = "iterator" ) ]
21
- use crate :: traits:: StorageIterator ;
22
15
use crate :: traits:: { Querier , Storage } ;
23
16
24
17
/** context data **/
@@ -70,17 +63,13 @@ impl GasState {
70
63
}
71
64
}
72
65
73
- struct ContextData < ' a , S : Storage , Q : Querier > {
66
+ struct ContextData < S : Storage , Q : Querier > {
74
67
gas_state : GasState ,
75
68
storage : Option < S > ,
76
69
storage_readonly : bool ,
77
70
querier : Option < Q > ,
78
71
/// A non-owning link to the wasmer instance
79
72
wasmer_instance : Option < NonNull < WasmerInstance > > ,
80
- #[ cfg( feature = "iterator" ) ]
81
- iterators : HashMap < u32 , Box < dyn StorageIterator + ' a > > ,
82
- #[ cfg( not( feature = "iterator" ) ) ]
83
- iterators : PhantomData < & ' a mut ( ) > ,
84
73
}
85
74
86
75
pub fn setup_context < S : Storage , Q : Querier > ( gas_limit : u64 ) -> ( * mut c_void , fn ( * mut c_void ) ) {
@@ -97,10 +86,6 @@ fn create_unmanaged_context_data<S: Storage, Q: Querier>(gas_limit: u64) -> *mut
97
86
storage_readonly : true ,
98
87
querier : None ,
99
88
wasmer_instance : None ,
100
- #[ cfg( feature = "iterator" ) ]
101
- iterators : HashMap :: new ( ) ,
102
- #[ cfg( not( feature = "iterator" ) ) ]
103
- iterators : PhantomData :: default ( ) ,
104
89
} ;
105
90
let heap_data = Box :: new ( data) ; // move from stack to heap
106
91
Box :: into_raw ( heap_data) as * mut c_void // give up ownership
@@ -109,43 +94,22 @@ fn create_unmanaged_context_data<S: Storage, Q: Querier>(gas_limit: u64) -> *mut
109
94
fn destroy_unmanaged_context_data < S : Storage , Q : Querier > ( ptr : * mut c_void ) {
110
95
if !ptr. is_null ( ) {
111
96
// obtain ownership and drop instance of ContextData when box gets out of scope
112
- let mut dying = unsafe { Box :: from_raw ( ptr as * mut ContextData < S , Q > ) } ;
113
- // Ensure all iterators are dropped before the storage
114
- destroy_iterators ( & mut dying) ;
97
+ let _dying = unsafe { Box :: from_raw ( ptr as * mut ContextData < S , Q > ) } ;
115
98
}
116
99
}
117
100
118
101
/// Get a mutable reference to the context's data. Ownership remains in the Context.
119
- // NOTE: This is actually not really implemented safely at the moment. I did this as a
120
- // nicer and less-terrible version of the previous solution to the following issue:
121
- //
122
- // +--->> Go pointer
123
- // |
124
- // Ctx ->> ContextData +-> iterators: Box<dyn Iterator + 'a> --+
125
- // | |
126
- // +-> storage: impl Storage <<------------+
127
- // |
128
- // +-> querier: impl Querier
129
- //
130
- // -> : Ownership
131
- // ->> : Mutable borrow
132
- //
133
- // As you can see, there's a cyclical reference here... changing this function to return the same lifetime as it
134
- // returns (and adjusting a few other functions to only have one lifetime instead of two) triggers an error
135
- // elsewhere where we try to add iterators to the context. That's not legal according to Rust's rules, and it
136
- // complains that we're trying to borrow ctx mutably twice. This needs a better solution because this function
137
- // probably triggers unsoundness.
138
102
fn get_context_data_mut < ' a , ' b , S : Storage , Q : Querier > (
139
103
ctx : & ' a mut Ctx ,
140
- ) -> & ' b mut ContextData < ' b , S , Q > {
104
+ ) -> & ' b mut ContextData < S , Q > {
141
105
unsafe {
142
106
let ptr = ctx. data as * mut ContextData < S , Q > ;
143
107
ptr. as_mut ( )
144
108
. expect ( "The pointer ctx.data was null in get_context_data_mut; this is a bug." )
145
109
}
146
110
}
147
111
148
- fn get_context_data < ' a , ' b , S : Storage , Q : Querier > ( ctx : & ' a Ctx ) -> & ' b ContextData < ' b , S , Q > {
112
+ fn get_context_data < ' a , ' b , S : Storage , Q : Querier > ( ctx : & ' a Ctx ) -> & ' b ContextData < S , Q > {
149
113
unsafe {
150
114
let ptr = ctx. data as * mut ContextData < S , Q > ;
151
115
ptr. as_ref ( )
@@ -164,25 +128,12 @@ pub fn set_wasmer_instance<S: Storage, Q: Querier>(
164
128
}
165
129
}
166
130
167
- #[ cfg( feature = "iterator" ) ]
168
- fn destroy_iterators < S : Storage , Q : Querier > ( context : & mut ContextData < S , Q > ) {
169
- context. iterators . clear ( ) ;
170
- }
171
-
172
- #[ cfg( not( feature = "iterator" ) ) ]
173
- fn destroy_iterators < S : Storage , Q : Querier > ( _context : & mut ContextData < S , Q > ) { }
174
-
175
131
/// Returns the original storage and querier as owned instances, and closes any remaining
176
132
/// iterators. This is meant to be called when recycling the instance.
177
133
pub ( crate ) fn move_out_of_context < S : Storage , Q : Querier > (
178
134
source : & mut Ctx ,
179
135
) -> ( Option < S > , Option < Q > ) {
180
- let mut b = get_context_data_mut :: < S , Q > ( source) ;
181
- // Destroy all existing iterators which are (in contrast to the storage)
182
- // not reused between different instances.
183
- // This is also important because the iterators are pointers to Go memory which should not be stored long term
184
- // Paragraphs 5-7: https://golang.org/cmd/cgo/#hdr-Passing_pointers
185
- destroy_iterators ( & mut b) ;
136
+ let b = get_context_data_mut :: < S , Q > ( source) ;
186
137
( b. storage . take ( ) , b. querier . take ( ) )
187
138
}
188
139
@@ -270,28 +221,6 @@ pub fn set_storage_readonly<S: Storage, Q: Querier>(ctx: &mut Ctx, new_value: bo
270
221
context_data. storage_readonly = new_value;
271
222
}
272
223
273
- /// Add the iterator to the context's data. A new ID is assigned and returned.
274
- /// IDs are guaranteed to be in the range [0, 2**31-1], i.e. fit in the non-negative part if type i32.
275
- #[ cfg( feature = "iterator" ) ]
276
- #[ must_use = "without the returned iterator ID, the iterator cannot be accessed" ]
277
- pub fn add_iterator < ' a , S : Storage , Q : Querier > (
278
- ctx : & mut Ctx ,
279
- iter : Box < dyn StorageIterator + ' a > ,
280
- ) -> u32 {
281
- let b = get_context_data_mut :: < S , Q > ( ctx) ;
282
- let last_id: u32 = b
283
- . iterators
284
- . len ( )
285
- . try_into ( )
286
- . expect ( "Found more iterator IDs than supported" ) ;
287
- let new_id = last_id + 1 ;
288
- if new_id > ( i32:: MAX as u32 ) {
289
- panic ! ( "Iterator ID exceeded i32::MAX. This must not happen." ) ;
290
- }
291
- b. iterators . insert ( new_id, iter) ;
292
- new_id
293
- }
294
-
295
224
pub ( crate ) fn with_func_from_context < S , Q , Args , Rets , Callback , CallbackData > (
296
225
ctx : & mut Ctx ,
297
226
name : & str ,
@@ -346,31 +275,11 @@ where
346
275
}
347
276
}
348
277
349
- #[ cfg( feature = "iterator" ) ]
350
- pub ( crate ) fn with_iterator_from_context < ' a , ' b , S : ' b , Q : ' b , F , T > (
351
- ctx : & ' a mut Ctx ,
352
- iterator_id : u32 ,
353
- func : F ,
354
- ) -> VmResult < T >
355
- where
356
- S : Storage ,
357
- Q : Querier ,
358
- F : FnOnce ( & ' b mut ( dyn StorageIterator + ' b ) ) -> VmResult < T > ,
359
- {
360
- let b = get_context_data_mut :: < S , Q > ( ctx) ;
361
- match b. iterators . get_mut ( & iterator_id) {
362
- Some ( iterator) => func ( iterator) ,
363
- None => Err ( VmError :: iterator_does_not_exist ( iterator_id) ) ,
364
- }
365
- }
366
-
367
278
#[ cfg( test) ]
368
279
mod test {
369
280
use super :: * ;
370
281
use crate :: backends:: { compile, decrease_gas_left, set_gas_left} ;
371
282
use crate :: errors:: VmError ;
372
- #[ cfg( feature = "iterator" ) ]
373
- use crate :: testing:: MockIterator ;
374
283
use crate :: testing:: { MockQuerier , MockStorage } ;
375
284
use crate :: traits:: Storage ;
376
285
use cosmwasm_std:: {
@@ -536,29 +445,6 @@ mod test {
536
445
assert_eq ! ( is_storage_readonly:: <MS , MQ >( ctx) , true ) ;
537
446
}
538
447
539
- #[ test]
540
- #[ cfg( feature = "iterator" ) ]
541
- fn add_iterator_works ( ) {
542
- let mut instance = make_instance ( ) ;
543
- let ctx = instance. context_mut ( ) ;
544
- leave_default_data ( ctx) ;
545
-
546
- assert_eq ! ( get_context_data_mut:: <MS , MQ >( ctx) . iterators. len( ) , 0 ) ;
547
- let id1 = add_iterator :: < MS , MQ > ( ctx, Box :: new ( MockIterator :: empty ( ) ) ) ;
548
- let id2 = add_iterator :: < MS , MQ > ( ctx, Box :: new ( MockIterator :: empty ( ) ) ) ;
549
- let id3 = add_iterator :: < MS , MQ > ( ctx, Box :: new ( MockIterator :: empty ( ) ) ) ;
550
- assert_eq ! ( get_context_data_mut:: <MS , MQ >( ctx) . iterators. len( ) , 3 ) ;
551
- assert ! ( get_context_data_mut:: <MS , MQ >( ctx)
552
- . iterators
553
- . contains_key( & id1) ) ;
554
- assert ! ( get_context_data_mut:: <MS , MQ >( ctx)
555
- . iterators
556
- . contains_key( & id2) ) ;
557
- assert ! ( get_context_data_mut:: <MS , MQ >( ctx)
558
- . iterators
559
- . contains_key( & id3) ) ;
560
- }
561
-
562
448
#[ test]
563
449
fn with_func_from_context_works ( ) {
564
450
let mut instance = make_instance ( ) ;
@@ -690,36 +576,4 @@ mod test {
690
576
} )
691
577
. unwrap ( ) ;
692
578
}
693
-
694
- #[ test]
695
- #[ cfg( feature = "iterator" ) ]
696
- fn with_iterator_from_context_works ( ) {
697
- let mut instance = make_instance ( ) ;
698
- let ctx = instance. context_mut ( ) ;
699
- leave_default_data ( ctx) ;
700
-
701
- let id = add_iterator :: < MS , MQ > ( ctx, Box :: new ( MockIterator :: empty ( ) ) ) ;
702
- with_iterator_from_context :: < MS , MQ , _ , ( ) > ( ctx, id, |iter| {
703
- assert ! ( iter. next( ) . 0 . unwrap( ) . is_none( ) ) ;
704
- Ok ( ( ) )
705
- } )
706
- . expect ( "must not error" ) ;
707
- }
708
-
709
- #[ test]
710
- #[ cfg( feature = "iterator" ) ]
711
- fn with_iterator_from_context_errors_for_non_existent_iterator_id ( ) {
712
- let mut instance = make_instance ( ) ;
713
- let ctx = instance. context_mut ( ) ;
714
- leave_default_data ( ctx) ;
715
-
716
- let missing_id = 42u32 ;
717
- let result = with_iterator_from_context :: < MS , MQ , _ , ( ) > ( ctx, missing_id, |_iter| {
718
- panic ! ( "this should not be called" ) ;
719
- } ) ;
720
- match result. unwrap_err ( ) {
721
- VmError :: IteratorDoesNotExist { id, .. } => assert_eq ! ( id, missing_id) ,
722
- err => panic ! ( "Unexpected error: {:?}" , err) ,
723
- }
724
- }
725
579
}
0 commit comments