tbaeder created this revision.
tbaeder added reviewers: aaron.ballman, erichkeane, tahonermann, shafik.
Herald added a project: All.
tbaeder requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

  The InterpFrame was only created so early so we could use getThis().
  However, we need to know the Function when creating the InterpFrame and
  in the case of virtual functions, we need to determine what function to
  call at interpretation time.
  
  Get the This pointer ourselves and just create the InterpFrame later.

This is of course in preparation for virtual function calls.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D142617

Files:
  clang/lib/AST/Interp/Interp.h
  clang/lib/AST/Interp/InterpStack.h


Index: clang/lib/AST/Interp/InterpStack.h
===================================================================
--- clang/lib/AST/Interp/InterpStack.h
+++ clang/lib/AST/Interp/InterpStack.h
@@ -67,6 +67,10 @@
     return *reinterpret_cast<T *>(peek(aligned_size<T>()));
   }
 
+  template <typename T> T &peek(size_t Offset) const {
+    return *reinterpret_cast<T *>(peek(Offset));
+  }
+
   /// Returns a pointer to the top object.
   void *top() const { return Chunk ? peek(0) : nullptr; }
 
Index: clang/lib/AST/Interp/Interp.h
===================================================================
--- clang/lib/AST/Interp/Interp.h
+++ clang/lib/AST/Interp/Interp.h
@@ -1499,10 +1499,11 @@
 }
 
 inline bool Call(InterpState &S, CodePtr &PC, const Function *Func) {
-  auto NewFrame = std::make_unique<InterpFrame>(S, Func, PC);
-  Pointer ThisPtr;
   if (Func->hasThisPointer()) {
-    ThisPtr = NewFrame->getThis();
+    size_t ThisOffset =
+        Func->getArgSize() + (Func->hasRVO() ? primSize(PT_Ptr) : 0);
+    const Pointer &ThisPtr = S.Stk.peek<Pointer>(ThisOffset);
+
     if (!CheckInvoke(S, PC, ThisPtr))
       return false;
 
@@ -1513,6 +1514,7 @@
   if (!CheckCallable(S, PC, Func))
     return false;
 
+  auto NewFrame = std::make_unique<InterpFrame>(S, Func, PC);
   InterpFrame *FrameBefore = S.Current;
   S.Current = NewFrame.get();
 


Index: clang/lib/AST/Interp/InterpStack.h
===================================================================
--- clang/lib/AST/Interp/InterpStack.h
+++ clang/lib/AST/Interp/InterpStack.h
@@ -67,6 +67,10 @@
     return *reinterpret_cast<T *>(peek(aligned_size<T>()));
   }
 
+  template <typename T> T &peek(size_t Offset) const {
+    return *reinterpret_cast<T *>(peek(Offset));
+  }
+
   /// Returns a pointer to the top object.
   void *top() const { return Chunk ? peek(0) : nullptr; }
 
Index: clang/lib/AST/Interp/Interp.h
===================================================================
--- clang/lib/AST/Interp/Interp.h
+++ clang/lib/AST/Interp/Interp.h
@@ -1499,10 +1499,11 @@
 }
 
 inline bool Call(InterpState &S, CodePtr &PC, const Function *Func) {
-  auto NewFrame = std::make_unique<InterpFrame>(S, Func, PC);
-  Pointer ThisPtr;
   if (Func->hasThisPointer()) {
-    ThisPtr = NewFrame->getThis();
+    size_t ThisOffset =
+        Func->getArgSize() + (Func->hasRVO() ? primSize(PT_Ptr) : 0);
+    const Pointer &ThisPtr = S.Stk.peek<Pointer>(ThisOffset);
+
     if (!CheckInvoke(S, PC, ThisPtr))
       return false;
 
@@ -1513,6 +1514,7 @@
   if (!CheckCallable(S, PC, Func))
     return false;
 
+  auto NewFrame = std::make_unique<InterpFrame>(S, Func, PC);
   InterpFrame *FrameBefore = S.Current;
   S.Current = NewFrame.get();
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
  • [PATCH] D142617: [clang][Inter... Timm Bäder via Phabricator via cfe-commits

Reply via email to