@@ -13,7 +13,8 @@ use syntax::{ast, attr};
13
13
14
14
use error:: { EvalError , EvalResult } ;
15
15
use memory:: Pointer ;
16
- use super :: { EvalContext , IntegerExt , StackPopCleanup } ;
16
+ use primval:: PrimVal ;
17
+ use super :: { EvalContext , IntegerExt , StackPopCleanup , Value } ;
17
18
18
19
mod intrinsics;
19
20
@@ -154,7 +155,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
154
155
substs : & ' tcx Substs < ' tcx > ,
155
156
fn_ty : & ' tcx BareFnTy ,
156
157
destination : Option < ( Pointer , mir:: BasicBlock ) > ,
157
- args : & [ mir:: Operand < ' tcx > ] ,
158
+ arg_operands : & [ mir:: Operand < ' tcx > ] ,
158
159
span : Span ,
159
160
) -> EvalResult < ' tcx , ( ) > {
160
161
use syntax:: abi:: Abi ;
@@ -163,7 +164,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
163
164
let ty = fn_ty. sig . 0 . output ;
164
165
let layout = self . type_layout ( ty) ;
165
166
let ( ret, target) = destination. unwrap ( ) ;
166
- self . call_intrinsic ( def_id, substs, args , ret, layout) ?;
167
+ self . call_intrinsic ( def_id, substs, arg_operands , ret, layout) ?;
167
168
self . goto_block ( target) ;
168
169
Ok ( ( ) )
169
170
}
@@ -172,23 +173,23 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
172
173
let ty = fn_ty. sig . 0 . output ;
173
174
let size = self . type_size ( ty) ;
174
175
let ( ret, target) = destination. unwrap ( ) ;
175
- self . call_c_abi ( def_id, args , ret, size) ?;
176
+ self . call_c_abi ( def_id, arg_operands , ret, size) ?;
176
177
self . goto_block ( target) ;
177
178
Ok ( ( ) )
178
179
}
179
180
180
181
Abi :: Rust | Abi :: RustCall => {
181
- let mut arg_srcs = Vec :: new ( ) ;
182
- for arg in args {
183
- let src = self . eval_operand_to_ptr ( arg) ?;
184
- let src_ty = self . operand_ty ( arg) ;
185
- arg_srcs . push ( ( src , src_ty ) ) ;
182
+ let mut args = Vec :: new ( ) ;
183
+ for arg in arg_operands {
184
+ let arg_val = self . eval_operand ( arg) ?;
185
+ let arg_ty = self . operand_ty ( arg) ;
186
+ args . push ( ( arg_val , arg_ty ) ) ;
186
187
}
187
188
188
189
// Only trait methods can have a Self parameter.
189
190
let ( resolved_def_id, resolved_substs) =
190
191
if let Some ( trait_id) = self . tcx . trait_of_item ( def_id) {
191
- self . trait_method ( trait_id, def_id, substs, & mut arg_srcs ) ?
192
+ self . trait_method ( trait_id, def_id, substs, & mut args ) ?
192
193
} else {
193
194
( def_id, substs)
194
195
} ;
@@ -200,9 +201,9 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
200
201
} ;
201
202
self . push_stack_frame ( resolved_def_id, span, mir, resolved_substs, return_ptr, return_to_block) ?;
202
203
203
- for ( i, ( src , src_ty ) ) in arg_srcs . into_iter ( ) . enumerate ( ) {
204
+ for ( i, ( arg_val , arg_ty ) ) in args . into_iter ( ) . enumerate ( ) {
204
205
let dest = self . frame ( ) . locals [ i] ;
205
- self . move_ ( src , dest, src_ty ) ?;
206
+ self . write_value ( arg_val , dest, arg_ty ) ?;
206
207
}
207
208
208
209
Ok ( ( ) )
@@ -344,7 +345,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
344
345
} )
345
346
}
346
347
347
- fn unpack_fn_args ( & self , args : & mut Vec < ( Pointer , Ty < ' tcx > ) > ) {
348
+ fn unpack_fn_args ( & self , args : & mut Vec < ( Value , Ty < ' tcx > ) > ) {
348
349
if let Some ( ( last, last_ty) ) = args. pop ( ) {
349
350
let last_layout = self . type_layout ( last_ty) ;
350
351
match ( & last_ty. sty , last_layout) {
@@ -353,9 +354,13 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
353
354
let offsets = iter:: once ( 0 )
354
355
. chain ( variant. offset_after_field . iter ( )
355
356
. map ( |s| s. bytes ( ) ) ) ;
357
+ let last_ptr = match last {
358
+ Value :: ByRef ( ptr) => ptr,
359
+ _ => bug ! ( "rust-call ABI tuple argument wasn't Value::ByRef" ) ,
360
+ } ;
356
361
for ( offset, ty) in offsets. zip ( fields) {
357
- let src = last . offset ( offset as isize ) ;
358
- args. push ( ( src , ty) ) ;
362
+ let arg = Value :: ByRef ( last_ptr . offset ( offset as isize ) ) ;
363
+ args. push ( ( arg , ty) ) ;
359
364
}
360
365
}
361
366
ty => bug ! ( "expected tuple as last argument in function with 'rust-call' ABI, got {:?}" , ty) ,
@@ -369,7 +374,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
369
374
trait_id : DefId ,
370
375
def_id : DefId ,
371
376
substs : & ' tcx Substs < ' tcx > ,
372
- args : & mut Vec < ( Pointer , Ty < ' tcx > ) > ,
377
+ args : & mut Vec < ( Value , Ty < ' tcx > ) > ,
373
378
) -> EvalResult < ' tcx , ( DefId , & ' tcx Substs < ' tcx > ) > {
374
379
let trait_ref = ty:: TraitRef :: from_method ( self . tcx , trait_id, substs) ;
375
380
let trait_ref = self . tcx . normalize_associated_type ( & ty:: Binder ( trait_ref) ) ;
@@ -398,6 +403,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
398
403
( ty:: ClosureKind :: FnMut , ty:: ClosureKind :: FnMut ) |
399
404
( ty:: ClosureKind :: FnOnce , ty:: ClosureKind :: FnOnce ) |
400
405
( ty:: ClosureKind :: Fn , ty:: ClosureKind :: FnMut ) => { } // No adapter needed.
406
+
401
407
( ty:: ClosureKind :: Fn , ty:: ClosureKind :: FnOnce ) |
402
408
( ty:: ClosureKind :: FnMut , ty:: ClosureKind :: FnOnce ) => {
403
409
// The closure fn is a `fn(&self, ...)` or `fn(&mut self, ...)`.
@@ -409,13 +415,15 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
409
415
//
410
416
// These are both the same at trans time.
411
417
412
- // interpreter magic: insert an intermediate pointer, so we can skip the intermediate function call
413
- // FIXME: this is a memory leak, should probably add the pointer to the current stack
414
- let ptr_size = self . memory . pointer_size ( ) ;
415
- let first = self . memory . allocate ( ptr_size, ptr_size) ?;
416
- self . memory . copy ( args[ 0 ] . 0 , first, ptr_size, ptr_size) ?;
417
- self . memory . write_ptr ( args[ 0 ] . 0 , first) ?;
418
+ // Interpreter magic: insert an intermediate pointer, so we can skip the
419
+ // intermediate function call.
420
+ // FIXME: this is a memory leak, should probably add the pointer to the
421
+ // current stack.
422
+ let first = self . value_to_ptr ( args[ 0 ] . 0 , args[ 0 ] . 1 ) ?;
423
+ args[ 0 ] . 0 = Value :: ByVal ( PrimVal :: Ptr ( first) ) ;
424
+ args[ 0 ] . 1 = self . tcx . mk_mut_ptr ( args[ 0 ] . 1 ) ;
418
425
}
426
+
419
427
_ => bug ! ( "cannot convert {:?} to {:?}" , closure_kind, trait_closure_kind) ,
420
428
}
421
429
Ok ( ( vtable_closure. closure_def_id , vtable_closure. substs . func_substs ) )
@@ -433,8 +441,11 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
433
441
434
442
traits:: VtableObject ( ref data) => {
435
443
let idx = self . tcx . get_vtable_index_of_object_method ( data, def_id) ;
436
- if let Some ( & mut ( first_arg, ref mut first_ty) ) = args. get_mut ( 0 ) {
437
- let ( _, vtable) = self . get_fat_ptr ( first_arg) ;
444
+ if let Some ( & mut ( ref mut first_arg, ref mut first_ty) ) = args. get_mut ( 0 ) {
445
+ // FIXME(solson): Remove this allocating hack.
446
+ let ptr = self . value_to_ptr ( * first_arg, * first_ty) ?;
447
+ * first_arg = Value :: ByRef ( ptr) ;
448
+ let ( _, vtable) = self . get_fat_ptr ( ptr) ;
438
449
let vtable = self . memory . read_ptr ( vtable) ?;
439
450
let idx = idx + 3 ;
440
451
let offset = idx * self . memory . pointer_size ( ) ;
0 commit comments