Add the Interpreter* to the cling::Value. We can afford it, because its actual size is 24 and it anyway gets aligned to 32 (except on a few old washing machines).

This commit is contained in:
Vassil Vassilev 2014-05-16 17:27:37 +02:00 committed by sftnight
parent 7b18586fa9
commit e587158b03
4 changed files with 28 additions and 10 deletions

View File

@ -52,6 +52,12 @@ namespace cling {
/// dependencies.
void* m_Type;
///\brief Interpreter, produced the value.
///
///(Size without this is 24, this member makes it 32)
///
Interpreter* m_Interpreter;
enum EStorageType {
kSignedIntegerOrEnumerationType,
kUnsignedIntegerOrEnumerationType,
@ -119,7 +125,7 @@ namespace cling {
public:
/// \brief Default constructor, creates a value that IsInvalid().
Value(): m_Type(0) {}
Value(): m_Type(0), m_Interpreter(0) {}
/// \brief Copy a value.
Value(const Value& other);
/// \brief Move a value.
@ -127,7 +133,7 @@ namespace cling {
/// \brief Construct a valid but ininitialized Value. After this call the
/// value's storage can be accessed; i.e. calls ManagedAllocate() if
/// needed.
Value(clang::QualType Ty, Interpreter* Interp);
Value(clang::QualType Ty, Interpreter& Interp);
/// \brief Destruct the value; calls ManagedFree() if needed.
~Value();
@ -135,6 +141,9 @@ namespace cling {
Value& operator =(Value&& other);
clang::QualType getType() const;
clang::ASTContext& getASTContext() const;
Interpreter* getInterpreter() { return m_Interpreter; }
const Interpreter* getInterpreter() const { return m_Interpreter; }
/// \brief Whether this type needs managed heap, i.e. the storage provided
/// by the m_Storage member is insufficient, or a non-trivial destructor

View File

@ -9,7 +9,7 @@
#include "cling/Interpreter/Value.h"
#include "llvm/Support/raw_ostream.h"
#include "cling/Interpreter/Interpreter.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/CanonicalType.h"
@ -97,21 +97,23 @@ namespace {
namespace cling {
Value::Value(const Value& other):
m_Storage(other.m_Storage), m_Type(other.m_Type) {
m_Storage(other.m_Storage), m_Type(other.m_Type),
m_Interpreter(other.m_Interpreter) {
if (needsManagedAllocation())
AllocatedValue::getFromPayload(m_Storage.m_Ptr)->Retain();
}
Value::Value(Value&& other):
m_Storage(other.m_Storage), m_Type(other.m_Type) {
m_Storage(other.m_Storage), m_Type(other.m_Type),
m_Interpreter(other.m_Interpreter) {
// Invalidate other so it will not release.
other.m_Type = 0;
}
Value::Value(clang::QualType clangTy, Interpreter* Interp):
m_Type(clangTy.getAsOpaquePtr()) {
Value::Value(clang::QualType clangTy, Interpreter& Interp):
m_Type(clangTy.getAsOpaquePtr()), m_Interpreter(&Interp) {
if (needsManagedAllocation())
ManagedAllocate(Interp);
ManagedAllocate(&Interp);
}
Value& Value::operator =(const Value& other) {
@ -122,6 +124,7 @@ Value& Value::operator =(const Value& other) {
// Retain new one.
m_Type = other.m_Type;
m_Storage = other.m_Storage;
m_Interpreter = other.m_Interpreter;
if (needsManagedAllocation())
AllocatedValue::getFromPayload(m_Storage.m_Ptr)->Retain();
return *this;
@ -135,6 +138,7 @@ Value& Value::operator =(Value&& other) {
// Move new one.
m_Type = other.m_Type;
m_Storage = other.m_Storage;
m_Interpreter = other.m_Interpreter;
// Invalidate other so it will not release.
other.m_Type = 0;
@ -150,6 +154,11 @@ clang::QualType Value::getType() const {
return clang::QualType::getFromOpaquePtr(m_Type);
}
clang::ASTContext& Value::getASTContext() const {
return m_Interpreter->getCI()->getASTContext();
}
bool Value::isValid() const { return !getType().isNull(); }
bool Value::isVoid(const clang::ASTContext& Ctx) const {

View File

@ -380,7 +380,7 @@ namespace {
clang::QualType QT = clang::QualType::getFromOpaquePtr(vpQT);
cling::Value& SVR = *(cling::Value*)vpSVR;
// Here the copy keeps the refcounted value alive.
SVR = cling::Value(QT, i);
SVR = cling::Value(QT, *i);
return SVR;
}
}

View File

@ -324,7 +324,7 @@ namespace cling {
// Build the result
clang::ASTContext& Ctx = m_Interpreter.getCI()->getASTContext();
if (result) {
*result = Value(Ctx.IntTy, 0);
*result = Value(Ctx.IntTy, m_Interpreter);
result->getAs<long long>() = ret;
}