about summary refs log tree commit diff
path: root/src/vtable.rs
diff options
context:
space:
mode:
authorbjorn3 <17426603+bjorn3@users.noreply.github.com>2022-10-23 16:22:55 +0200
committerbjorn3 <17426603+bjorn3@users.noreply.github.com>2022-10-23 16:22:55 +0200
commit9950bd1dc5bd249af274a14c7da30a2992c33295 (patch)
tree5d0461ac726e5c836ea3be27912bb3a17597ba60 /src/vtable.rs
parent54ee5ac0734a5c715558190fda9c61be2446d93a (diff)
Merge commit '266e96785ab71834b917bf474f130a6d8fdecd4b' into sync_cg_clif-2022-10-23
Diffstat (limited to 'src/vtable.rs')
-rw-r--r--src/vtable.rs26
1 files changed, 20 insertions, 6 deletions
diff --git a/src/vtable.rs b/src/vtable.rs
index 36b3725ef42..f04fb82de8c 100644
--- a/src/vtable.rs
+++ b/src/vtable.rs
@@ -45,12 +45,26 @@ pub(crate) fn get_ptr_and_method_ref<'tcx>(
     fx: &mut FunctionCx<'_, '_, 'tcx>,
     arg: CValue<'tcx>,
     idx: usize,
-) -> (Value, Value) {
-    let (ptr, vtable) = if let Abi::ScalarPair(_, _) = arg.layout().abi {
-        arg.load_scalar_pair(fx)
-    } else {
-        let (ptr, vtable) = arg.try_to_ptr().unwrap();
-        (ptr.get_addr(fx), vtable.unwrap())
+) -> (Pointer, Value) {
+    let (ptr, vtable) = 'block: {
+        if let ty::Ref(_, ty, _) = arg.layout().ty.kind() {
+            if ty.is_dyn_star() {
+                let inner_layout = fx.layout_of(arg.layout().ty.builtin_deref(true).unwrap().ty);
+                let dyn_star = CPlace::for_ptr(Pointer::new(arg.load_scalar(fx)), inner_layout);
+                let ptr = dyn_star.place_field(fx, mir::Field::new(0)).to_ptr();
+                let vtable =
+                    dyn_star.place_field(fx, mir::Field::new(1)).to_cvalue(fx).load_scalar(fx);
+                break 'block (ptr, vtable);
+            }
+        }
+
+        if let Abi::ScalarPair(_, _) = arg.layout().abi {
+            let (ptr, vtable) = arg.load_scalar_pair(fx);
+            (Pointer::new(ptr), vtable)
+        } else {
+            let (ptr, vtable) = arg.try_to_ptr().unwrap();
+            (ptr, vtable.unwrap())
+        }
     };
 
     let usize_size = fx.layout_of(fx.tcx.types.usize).size.bytes();