track total size of static array and Unit/Class/Func
[hiphop-php.git] / hphp / runtime / base / type-object.h
blob456d77779c435c007d11ed6f9cf68930219474c7
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-present Facebook, Inc. (http://www.facebook.com) |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
17 #ifndef incl_HPHP_OBJECT_H_
18 #define incl_HPHP_OBJECT_H_
20 #include "hphp/runtime/base/object-data.h"
21 #include "hphp/runtime/base/req-ptr.h"
22 #include "hphp/runtime/base/typed-value.h"
24 #include <algorithm>
26 namespace HPHP {
27 ///////////////////////////////////////////////////////////////////////////////
29 // Forward declare to avoid including tv-conversions.h and creating a cycle.
30 ObjectData* tvCastToObjectData(TypedValue tv);
32 /**
33 * Object type wrapping around ObjectData to implement reference count.
35 struct Object {
36 private:
37 req::ptr<ObjectData> m_obj;
39 using NoIncRef = req::ptr<ObjectData>::NoIncRef;
41 public:
42 Object() {}
44 ObjectData* get() const { return m_obj.get(); }
45 void reset(ObjectData* obj = nullptr) { m_obj.reset(obj); }
47 ObjectData* operator->() const {
48 return m_obj.get();
51 /**
52 * Constructors
54 explicit Object(ObjectData *data) : m_obj(data) {
55 // The object must have at least two refs here. One pre-existing ref, and
56 // one caused by placing it under m_obj's control.
57 assertx(!data || data->hasMultipleRefs());
59 /* implicit */ Object(const Object& src) : m_obj(src.m_obj) {
60 assertx(!m_obj || m_obj->hasMultipleRefs());
63 template <typename T>
64 explicit Object(const req::ptr<T> &ptr) : m_obj(ptr) {
65 assertx(!m_obj || m_obj->hasMultipleRefs());
68 template <typename T>
69 explicit Object(req::ptr<T>&& ptr) : m_obj(std::move(ptr)) {
70 assertx(!m_obj || m_obj->checkCount());
73 explicit Object(Class* cls)
74 : m_obj(ObjectData::newInstance(cls), NoIncRef{}) {
75 // References to the object can escape inside newInstance, so we only know
76 // that the ref-count is at least 1 here.
77 assertx(!m_obj || m_obj->checkCount());
80 explicit Object(Class* cls, ArrayData* reifiedTypes)
81 : m_obj(ObjectData::newInstanceReified(cls, reifiedTypes), NoIncRef{}) {
82 // References to the object can escape inside newInstance, so we only know
83 // that the ref-count is at least 1 here.
84 assertx(!m_obj || m_obj->checkCount());
87 // Move ctor
88 Object(Object&& src) noexcept : m_obj(std::move(src.m_obj)) {
89 assertx(!m_obj || m_obj->checkCount());
92 // Regular assign
93 Object& operator=(const Object& src) {
94 m_obj = src.m_obj;
95 assertx(!m_obj || m_obj->hasMultipleRefs());
96 return *this;
99 template <typename T>
100 Object& operator=(const req::ptr<T>& src) {
101 m_obj = src;
102 assertx(!m_obj || m_obj->hasMultipleRefs());
103 return *this;
106 // Move assign
107 Object& operator=(Object&& src) {
108 m_obj = std::move(src.m_obj);
109 assertx(!m_obj || m_obj->checkCount());
110 return *this;
113 template <typename T>
114 Object& operator=(req::ptr<T>&& src) {
115 m_obj = std::move(src);
116 assertx(!m_obj || m_obj->checkCount());
117 return *this;
121 * Informational
123 explicit operator bool() const { return (bool)m_obj; }
125 bool isNull() const { return !m_obj; }
126 bool instanceof(const String& s) const {
127 return m_obj && m_obj->instanceof(s);
129 bool instanceof(const Class* cls) const {
130 return m_obj && m_obj->instanceof(cls);
134 * Type conversions
136 bool toBoolean() const { return m_obj ? m_obj->toBoolean() : false; }
137 char toByte () const { return toInt64(); }
138 int16_t toInt16 () const { return toInt64(); }
139 int32_t toInt32 () const { return toInt64(); }
140 int64_t toInt64 () const { return m_obj ? m_obj->toInt64() : 0; }
141 double toDouble () const { return m_obj ? m_obj->toDouble() : 0; }
142 String toString () const;
143 Array toArray () const;
145 // Transfer ownership of our reference to this object.
146 ObjectData *detach() { return m_obj.detach(); }
148 // Take ownership of a reference without touching the ref count
149 static Object attach(ObjectData *object) {
150 assertx(!object || object->checkCount());
151 return Object{req::ptr<ObjectData>::attach(object)};
154 private:
155 template <typename T>
156 friend typename std::enable_if<
157 std::is_base_of<ObjectData,T>::value,
158 ObjectData*
159 >::type deref(const Object& o) { return o.get(); }
161 template <typename T>
162 friend typename std::enable_if<
163 std::is_base_of<ObjectData,T>::value,
164 ObjectData*
165 >::type detach(Object&& o) { return o.detach(); }
167 static void compileTimeAssertions();
169 const char* classname_cstr() const;
172 extern const Object null_object;
174 ///////////////////////////////////////////////////////////////////////////////
175 // ObjNR
177 struct ObjNR {
178 explicit ObjNR(ObjectData* data) {
179 m_px = data;
182 Object& asObject() {
183 return *reinterpret_cast<Object*>(this); // XXX
186 const Object& asObject() const {
187 return const_cast<ObjNR*>(this)->asObject();
190 private:
191 ObjectData* m_px;
193 static void compileTimeAssertions();
196 ///////////////////////////////////////////////////////////////////////////////
198 ALWAYS_INLINE const Object& asCObjRef(tv_rval tv) {
199 assertx(tvIsObject(tv));
200 return reinterpret_cast<const Object&>(val(tv).pobj);
203 ALWAYS_INLINE Object toObject(tv_rval tv) {
204 if (tvIsObject(tv)) return Object{assert_not_null(val(tv).pobj)};
205 return Object::attach(tvCastToObjectData(*tv));
210 #endif // incl_HPHP_OBJECT_H_