#define TYPE_CHECKER(type, instancetype) \
- bool Object::Is##type() { \
+ bool Object::Is##type() const { \
return Object::IsHeapObject() && \
HeapObject::cast(this)->map()->instance_type() == instancetype; \
}
-// TODO(svenpanne) We use const_cast here and at a few other places to break our
-// dependency cycle between the cast methods and the predicates. This can be
-// removed when the predicates are const-correct, too.
#define CAST_ACCESSOR(type) \
type* type::cast(Object* object) { \
SLOW_ASSERT(object->Is##type()); \
return reinterpret_cast<type*>(object); \
} \
const type* type::cast(const Object* object) { \
- SLOW_ASSERT(const_cast<Object*>(object)->Is##type()); \
+ SLOW_ASSERT(object->Is##type()); \
return reinterpret_cast<const type*>(object); \
}
}
-bool Object::IsFixedArrayBase() {
+bool Object::IsFixedArrayBase() const {
return IsFixedArray() || IsFixedDoubleArray() || IsConstantPoolArray() ||
IsFixedTypedArrayBase() || IsExternalArray();
}
// External objects are not extensible, so the map check is enough.
-bool Object::IsExternal() {
+bool Object::IsExternal() const {
return Object::IsHeapObject() &&
HeapObject::cast(this)->map() ==
HeapObject::cast(this)->GetHeap()->external_map();
}
-bool Object::IsAccessorInfo() {
+bool Object::IsAccessorInfo() const {
return IsExecutableAccessorInfo() || IsDeclaredAccessorInfo();
}
-bool Object::IsSmi() {
+bool Object::IsSmi() const {
return HAS_SMI_TAG(this);
}
-bool Object::IsHeapObject() {
+bool Object::IsHeapObject() const {
return Internals::HasHeapObjectTag(this);
}
TYPE_CHECKER(Symbol, SYMBOL_TYPE)
-bool Object::IsString() {
+bool Object::IsString() const {
return Object::IsHeapObject()
&& HeapObject::cast(this)->map()->instance_type() < FIRST_NONSTRING_TYPE;
}
-bool Object::IsName() {
+bool Object::IsName() const {
return IsString() || IsSymbol();
}
-bool Object::IsUniqueName() {
+bool Object::IsUniqueName() const {
return IsInternalizedString() || IsSymbol();
}
-bool Object::IsSpecObject() {
+bool Object::IsSpecObject() const {
return Object::IsHeapObject()
&& HeapObject::cast(this)->map()->instance_type() >= FIRST_SPEC_OBJECT_TYPE;
}
-bool Object::IsSpecFunction() {
+bool Object::IsSpecFunction() const {
if (!Object::IsHeapObject()) return false;
InstanceType type = HeapObject::cast(this)->map()->instance_type();
return type == JS_FUNCTION_TYPE || type == JS_FUNCTION_PROXY_TYPE;
}
-bool Object::IsTemplateInfo() {
+bool Object::IsTemplateInfo() const {
return IsObjectTemplateInfo() || IsFunctionTemplateInfo();
}
-bool Object::IsInternalizedString() {
+bool Object::IsInternalizedString() const {
if (!this->IsHeapObject()) return false;
uint32_t type = HeapObject::cast(this)->map()->instance_type();
STATIC_ASSERT(kNotInternalizedTag != 0);
}
-bool Object::IsConsString() {
+bool Object::IsConsString() const {
if (!IsString()) return false;
return StringShape(String::cast(this)).IsCons();
}
-bool Object::IsSlicedString() {
+bool Object::IsSlicedString() const {
if (!IsString()) return false;
return StringShape(String::cast(this)).IsSliced();
}
-bool Object::IsSeqString() {
+bool Object::IsSeqString() const {
if (!IsString()) return false;
return StringShape(String::cast(this)).IsSequential();
}
-bool Object::IsSeqOneByteString() {
+bool Object::IsSeqOneByteString() const {
if (!IsString()) return false;
return StringShape(String::cast(this)).IsSequential() &&
String::cast(this)->IsOneByteRepresentation();
}
-bool Object::IsSeqTwoByteString() {
+bool Object::IsSeqTwoByteString() const {
if (!IsString()) return false;
return StringShape(String::cast(this)).IsSequential() &&
String::cast(this)->IsTwoByteRepresentation();
}
-bool Object::IsExternalString() {
+bool Object::IsExternalString() const {
if (!IsString()) return false;
return StringShape(String::cast(this)).IsExternal();
}
-bool Object::IsExternalAsciiString() {
+bool Object::IsExternalAsciiString() const {
if (!IsString()) return false;
return StringShape(String::cast(this)).IsExternal() &&
String::cast(this)->IsOneByteRepresentation();
}
-bool Object::IsExternalTwoByteString() {
+bool Object::IsExternalTwoByteString() const {
if (!IsString()) return false;
return StringShape(String::cast(this)).IsExternal() &&
String::cast(this)->IsTwoByteRepresentation();
}
-StringShape::StringShape(String* str)
+StringShape::StringShape(const String* str)
: type_(str->map()->instance_type()) {
set_valid();
ASSERT((type_ & kIsNotStringMask) == kStringTag);
}
-bool String::IsOneByteRepresentation() {
+bool String::IsOneByteRepresentation() const {
uint32_t type = map()->instance_type();
return (type & kStringEncodingMask) == kOneByteStringTag;
}
-bool String::IsTwoByteRepresentation() {
+bool String::IsTwoByteRepresentation() const {
uint32_t type = map()->instance_type();
return (type & kStringEncodingMask) == kTwoByteStringTag;
}
};
-bool Object::IsNumber() {
+bool Object::IsNumber() const {
return IsSmi() || IsHeapNumber();
}
TYPE_CHECKER(FreeSpace, FREE_SPACE_TYPE)
-bool Object::IsFiller() {
+bool Object::IsFiller() const {
if (!Object::IsHeapObject()) return false;
InstanceType instance_type = HeapObject::cast(this)->map()->instance_type();
return instance_type == FREE_SPACE_TYPE || instance_type == FILLER_TYPE;
}
-bool Object::IsExternalArray() {
+bool Object::IsExternalArray() const {
if (!Object::IsHeapObject())
return false;
InstanceType instance_type =
#undef TYPED_ARRAY_TYPE_CHECKER
-bool Object::IsFixedTypedArrayBase() {
+bool Object::IsFixedTypedArrayBase() const {
if (!Object::IsHeapObject()) return false;
InstanceType instance_type =
}
-bool Object::IsJSReceiver() {
+bool Object::IsJSReceiver() const {
STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
return IsHeapObject() &&
HeapObject::cast(this)->map()->instance_type() >= FIRST_JS_RECEIVER_TYPE;
}
-bool Object::IsJSObject() {
+bool Object::IsJSObject() const {
STATIC_ASSERT(LAST_JS_OBJECT_TYPE == LAST_TYPE);
return IsHeapObject() &&
HeapObject::cast(this)->map()->instance_type() >= FIRST_JS_OBJECT_TYPE;
}
-bool Object::IsJSProxy() {
+bool Object::IsJSProxy() const {
if (!Object::IsHeapObject()) return false;
return HeapObject::cast(this)->map()->IsJSProxyMap();
}
TYPE_CHECKER(ConstantPoolArray, CONSTANT_POOL_ARRAY_TYPE)
-bool Object::IsJSWeakCollection() {
+bool Object::IsJSWeakCollection() const {
return IsJSWeakMap() || IsJSWeakSet();
}
-bool Object::IsDescriptorArray() {
+bool Object::IsDescriptorArray() const {
return IsFixedArray();
}
-bool Object::IsTransitionArray() {
+bool Object::IsTransitionArray() const {
return IsFixedArray();
}
-bool Object::IsDeoptimizationInputData() {
+bool Object::IsDeoptimizationInputData() const {
// Must be a fixed array.
if (!IsFixedArray()) return false;
}
-bool Object::IsDeoptimizationOutputData() {
+bool Object::IsDeoptimizationOutputData() const {
if (!IsFixedArray()) return false;
// There's actually no way to see the difference between a fixed array and
// a deoptimization data array. Since this is used for asserts we can check
}
-bool Object::IsDependentCode() {
+bool Object::IsDependentCode() const {
if (!IsFixedArray()) return false;
// There's actually no way to see the difference between a fixed array and
// a dependent codes array.
}
-bool Object::IsContext() {
+bool Object::IsContext() const {
if (!Object::IsHeapObject()) return false;
Map* map = HeapObject::cast(this)->map();
Heap* heap = map->GetHeap();
}
-bool Object::IsNativeContext() {
+bool Object::IsNativeContext() const {
return Object::IsHeapObject() &&
HeapObject::cast(this)->map() ==
HeapObject::cast(this)->GetHeap()->native_context_map();
}
-bool Object::IsScopeInfo() {
+bool Object::IsScopeInfo() const {
return Object::IsHeapObject() &&
HeapObject::cast(this)->map() ==
HeapObject::cast(this)->GetHeap()->scope_info_map();
TYPE_CHECKER(JSMessageObject, JS_MESSAGE_OBJECT_TYPE)
-bool Object::IsStringWrapper() {
+bool Object::IsStringWrapper() const {
return IsJSValue() && JSValue::cast(this)->value()->IsString();
}
TYPE_CHECKER(Foreign, FOREIGN_TYPE)
-bool Object::IsBoolean() {
+bool Object::IsBoolean() const {
return IsOddball() &&
((Oddball::cast(this)->kind() & Oddball::kNotBooleanMask) == 0);
}
TYPE_CHECKER(JSDataView, JS_DATA_VIEW_TYPE)
-bool Object::IsJSArrayBufferView() {
+bool Object::IsJSArrayBufferView() const {
return IsJSDataView() || IsJSTypedArray();
}
}
-bool Object::IsHashTable() {
+bool Object::IsHashTable() const {
return Object::IsHeapObject() &&
HeapObject::cast(this)->map() ==
HeapObject::cast(this)->GetHeap()->hash_table_map();
}
-bool Object::IsWeakHashTable() {
+bool Object::IsWeakHashTable() const {
return IsHashTable();
}
-bool Object::IsDictionary() {
+bool Object::IsDictionary() const {
return IsHashTable() &&
this != HeapObject::cast(this)->GetHeap()->string_table();
}
-bool Object::IsNameDictionary() {
+bool Object::IsNameDictionary() const {
return IsDictionary();
}
-bool Object::IsSeededNumberDictionary() {
+bool Object::IsSeededNumberDictionary() const {
return IsDictionary();
}
-bool Object::IsUnseededNumberDictionary() {
+bool Object::IsUnseededNumberDictionary() const {
return IsDictionary();
}
-bool Object::IsStringTable() {
+bool Object::IsStringTable() const {
return IsHashTable();
}
-bool Object::IsJSFunctionResultCache() {
+bool Object::IsJSFunctionResultCache() const {
if (!IsFixedArray()) return false;
- FixedArray* self = FixedArray::cast(this);
+ const FixedArray* self = FixedArray::cast(this);
int length = self->length();
if (length < JSFunctionResultCache::kEntriesIndex) return false;
if ((length - JSFunctionResultCache::kEntriesIndex)
}
#ifdef VERIFY_HEAP
if (FLAG_verify_heap) {
- reinterpret_cast<JSFunctionResultCache*>(this)->
+ // TODO(svenpanne) We use const_cast here and below to break our dependency
+ // cycle between the predicates and the verifiers. This can be removed when
+ // the verifiers are const-correct, too.
+ reinterpret_cast<JSFunctionResultCache*>(const_cast<Object*>(this))->
JSFunctionResultCacheVerify();
}
#endif
}
-bool Object::IsNormalizedMapCache() {
+bool Object::IsNormalizedMapCache() const {
return NormalizedMapCache::IsNormalizedMapCache(this);
}
}
-bool NormalizedMapCache::IsNormalizedMapCache(Object* obj) {
+bool NormalizedMapCache::IsNormalizedMapCache(const Object* obj) {
if (!obj->IsFixedArray()) return false;
if (FixedArray::cast(obj)->length() != NormalizedMapCache::kEntries) {
return false;
}
#ifdef VERIFY_HEAP
if (FLAG_verify_heap) {
- reinterpret_cast<NormalizedMapCache*>(obj)->NormalizedMapCacheVerify();
+ reinterpret_cast<NormalizedMapCache*>(const_cast<Object*>(obj))->
+ NormalizedMapCacheVerify();
}
#endif
return true;
}
-bool Object::IsCompilationCacheTable() {
+bool Object::IsCompilationCacheTable() const {
return IsHashTable();
}
-bool Object::IsCodeCacheHashTable() {
+bool Object::IsCodeCacheHashTable() const {
return IsHashTable();
}
-bool Object::IsPolymorphicCodeCacheHashTable() {
+bool Object::IsPolymorphicCodeCacheHashTable() const {
return IsHashTable();
}
-bool Object::IsMapCache() {
+bool Object::IsMapCache() const {
return IsHashTable();
}
-bool Object::IsObjectHashTable() {
+bool Object::IsObjectHashTable() const {
return IsHashTable();
}
-bool Object::IsOrderedHashTable() {
+bool Object::IsOrderedHashTable() const {
return IsHeapObject() &&
HeapObject::cast(this)->map() ==
HeapObject::cast(this)->GetHeap()->ordered_hash_table_map();
}
-bool Object::IsOrderedHashSet() {
+bool Object::IsOrderedHashSet() const {
return IsOrderedHashTable();
}
-bool Object::IsOrderedHashMap() {
+bool Object::IsOrderedHashMap() const {
return IsOrderedHashTable();
}
-bool Object::IsPrimitive() {
+bool Object::IsPrimitive() const {
return IsOddball() || IsNumber() || IsString();
}
-bool Object::IsJSGlobalProxy() {
+bool Object::IsJSGlobalProxy() const {
bool result = IsHeapObject() &&
(HeapObject::cast(this)->map()->instance_type() ==
JS_GLOBAL_PROXY_TYPE);
}
-bool Object::IsGlobalObject() {
+bool Object::IsGlobalObject() const {
if (!IsHeapObject()) return false;
InstanceType type = HeapObject::cast(this)->map()->instance_type();
TYPE_CHECKER(JSBuiltinsObject, JS_BUILTINS_OBJECT_TYPE)
-bool Object::IsUndetectableObject() {
+bool Object::IsUndetectableObject() const {
return IsHeapObject()
&& HeapObject::cast(this)->map()->is_undetectable();
}
-bool Object::IsAccessCheckNeeded() {
+bool Object::IsAccessCheckNeeded() const {
if (!IsHeapObject()) return false;
if (IsJSGlobalProxy()) {
- JSGlobalProxy* proxy = JSGlobalProxy::cast(this);
- GlobalObject* global =
- proxy->GetIsolate()->context()->global_object();
+ const JSGlobalProxy* proxy = JSGlobalProxy::cast(this);
+ GlobalObject* global = proxy->GetIsolate()->context()->global_object();
return proxy->IsDetachedFrom(global);
}
return HeapObject::cast(this)->map()->is_access_check_needed();
}
-bool Object::IsStruct() {
+bool Object::IsStruct() const {
if (!IsHeapObject()) return false;
switch (HeapObject::cast(this)->map()->instance_type()) {
#define MAKE_STRUCT_CASE(NAME, Name, name) case NAME##_TYPE: return true;
}
-#define MAKE_STRUCT_PREDICATE(NAME, Name, name) \
- bool Object::Is##Name() { \
- return Object::IsHeapObject() \
+#define MAKE_STRUCT_PREDICATE(NAME, Name, name) \
+ bool Object::Is##Name() const { \
+ return Object::IsHeapObject() \
&& HeapObject::cast(this)->map()->instance_type() == NAME##_TYPE; \
}
STRUCT_LIST(MAKE_STRUCT_PREDICATE)
#undef MAKE_STRUCT_PREDICATE
-bool Object::IsUndefined() {
+bool Object::IsUndefined() const {
return IsOddball() && Oddball::cast(this)->kind() == Oddball::kUndefined;
}
-bool Object::IsNull() {
+bool Object::IsNull() const {
return IsOddball() && Oddball::cast(this)->kind() == Oddball::kNull;
}
-bool Object::IsTheHole() {
+bool Object::IsTheHole() const {
return IsOddball() && Oddball::cast(this)->kind() == Oddball::kTheHole;
}
-bool Object::IsException() {
+bool Object::IsException() const {
return IsOddball() && Oddball::cast(this)->kind() == Oddball::kException;
}
-bool Object::IsUninitialized() {
+bool Object::IsUninitialized() const {
return IsOddball() && Oddball::cast(this)->kind() == Oddball::kUninitialized;
}
-bool Object::IsTrue() {
+bool Object::IsTrue() const {
return IsOddball() && Oddball::cast(this)->kind() == Oddball::kTrue;
}
-bool Object::IsFalse() {
+bool Object::IsFalse() const {
return IsOddball() && Oddball::cast(this)->kind() == Oddball::kFalse;
}
-bool Object::IsArgumentsMarker() {
+bool Object::IsArgumentsMarker() const {
return IsOddball() && Oddball::cast(this)->kind() == Oddball::kArgumentMarker;
}
}
-bool Object::IsNaN() {
+bool Object::IsNaN() const {
return this->IsHeapNumber() && std::isnan(HeapNumber::cast(this)->value());
}
}
-Isolate* HeapObject::GetIsolate() {
+Isolate* HeapObject::GetIsolate() const {
return GetHeap()->isolate();
}
}
-double HeapNumber::value() {
+double HeapNumber::value() const {
return READ_DOUBLE_FIELD(this, kValueOffset);
}
ACCESSORS(Oddball, to_number, Object, kToNumberOffset)
-byte Oddball::kind() {
+byte Oddball::kind() const {
return Smi::cast(READ_FIELD(this, kKindOffset))->value();
}
template <class Traits>
const FixedTypedArray<Traits>*
FixedTypedArray<Traits>::cast(const Object* object) {
- SLOW_ASSERT(const_cast<Object*>(object)->IsHeapObject() &&
+ SLOW_ASSERT(object->IsHeapObject() &&
HeapObject::cast(object)->map()->instance_type() ==
Traits::kInstanceType);
return reinterpret_cast<FixedTypedArray<Traits>*>(object);
template <typename Derived, typename Shape, typename Key>
const HashTable<Derived, Shape, Key>*
HashTable<Derived, Shape, Key>::cast(const Object* obj) {
- SLOW_ASSERT(const_cast<Object*>(obj)->IsHashTable());
+ SLOW_ASSERT(obj->IsHashTable());
return reinterpret_cast<const HashTable*>(obj);
}
}
-Object* JSReceiver::GetPrototype() {
+Object* JSReceiver::GetPrototype() const {
return map()->prototype();
}
}
-bool JSGlobalProxy::IsDetachedFrom(GlobalObject* global) {
+bool JSGlobalProxy::IsDetachedFrom(GlobalObject* global) const {
return GetPrototype() != global;
}
class Object {
public:
// Type testing.
- bool IsObject() { return true; }
+ bool IsObject() const { return true; }
-#define IS_TYPE_FUNCTION_DECL(type_) inline bool Is##type_();
+#define IS_TYPE_FUNCTION_DECL(type_) INLINE(bool Is##type_() const);
OBJECT_TYPE_LIST(IS_TYPE_FUNCTION_DECL)
HEAP_OBJECT_TYPE_LIST(IS_TYPE_FUNCTION_DECL)
#undef IS_TYPE_FUNCTION_DECL
- inline bool IsFixedArrayBase();
- inline bool IsExternal();
- inline bool IsAccessorInfo();
+ INLINE(bool IsFixedArrayBase() const);
+ INLINE(bool IsExternal() const);
+ INLINE(bool IsAccessorInfo() const);
- inline bool IsStruct();
-#define DECLARE_STRUCT_PREDICATE(NAME, Name, name) inline bool Is##Name();
+ INLINE(bool IsStruct() const);
+#define DECLARE_STRUCT_PREDICATE(NAME, Name, name) \
+ INLINE(bool Is##Name() const);
STRUCT_LIST(DECLARE_STRUCT_PREDICATE)
#undef DECLARE_STRUCT_PREDICATE
- INLINE(bool IsSpecObject());
- INLINE(bool IsSpecFunction());
- INLINE(bool IsTemplateInfo());
- INLINE(bool IsNameDictionary());
- INLINE(bool IsSeededNumberDictionary());
- INLINE(bool IsUnseededNumberDictionary());
- INLINE(bool IsOrderedHashSet());
- INLINE(bool IsOrderedHashMap());
- bool IsCallable();
+ INLINE(bool IsSpecObject()) const;
+ INLINE(bool IsSpecFunction()) const;
+ INLINE(bool IsTemplateInfo()) const;
+ INLINE(bool IsNameDictionary() const);
+ INLINE(bool IsSeededNumberDictionary() const);
+ INLINE(bool IsUnseededNumberDictionary() const);
+ INLINE(bool IsOrderedHashSet() const);
+ INLINE(bool IsOrderedHashMap() const);
+ bool IsCallable() const;
// Oddball testing.
- INLINE(bool IsUndefined());
- INLINE(bool IsNull());
- INLINE(bool IsTheHole());
- INLINE(bool IsException());
- INLINE(bool IsUninitialized());
- INLINE(bool IsTrue());
- INLINE(bool IsFalse());
- inline bool IsArgumentsMarker();
+ INLINE(bool IsUndefined() const);
+ INLINE(bool IsNull() const);
+ INLINE(bool IsTheHole() const);
+ INLINE(bool IsException() const);
+ INLINE(bool IsUninitialized() const);
+ INLINE(bool IsTrue() const);
+ INLINE(bool IsFalse() const);
+ INLINE(bool IsArgumentsMarker() const);
// Filler objects (fillers and free space objects).
- inline bool IsFiller();
+ INLINE(bool IsFiller() const);
// Extract the number.
inline double Number();
- inline bool IsNaN();
+ INLINE(bool IsNaN() const);
bool ToInt32(int32_t* value);
bool ToUint32(uint32_t* value);
inline Heap* GetHeap() const;
// Convenience method to get current isolate.
- inline Isolate* GetIsolate();
+ inline Isolate* GetIsolate() const;
// Converts an address to a HeapObject pointer.
static inline HeapObject* FromAddress(Address address);
class HeapNumber: public HeapObject {
public:
// [value]: number value.
- inline double value();
+ inline double value() const;
inline void set_value(double value);
DECLARE_CAST(HeapNumber)
uint32_t index);
// Return the object's prototype (might be Heap::null_value()).
- inline Object* GetPrototype();
+ inline Object* GetPrototype() const;
// Return the constructor function (may be Heap::null_value()).
inline Object* GetConstructor();
DECLARE_CAST(NormalizedMapCache)
- static inline bool IsNormalizedMapCache(Object* obj);
+ static inline bool IsNormalizedMapCache(const Object* obj);
DECLARE_VERIFIER(NormalizedMapCache)
private:
DECLARE_CAST(JSGlobalProxy)
- inline bool IsDetachedFrom(GlobalObject* global);
+ inline bool IsDetachedFrom(GlobalObject* global) const;
// Dispatched behavior.
DECLARE_PRINTER(JSGlobalProxy)
// concrete performance benefit at that particular point in the code.
class StringShape BASE_EMBEDDED {
public:
- inline explicit StringShape(String* s);
+ inline explicit StringShape(const String* s);
inline explicit StringShape(Map* s);
inline explicit StringShape(InstanceType t);
inline bool IsSequential();
// be ASCII encoded. This might be the case even if the string is
// two-byte. Such strings may appear when the embedder prefers
// two-byte external representations even for ASCII data.
- inline bool IsOneByteRepresentation();
- inline bool IsTwoByteRepresentation();
+ inline bool IsOneByteRepresentation() const;
+ inline bool IsTwoByteRepresentation() const;
// Cons and slices have an encoding flag that may not represent the actual
// encoding of the underlying string. This is taken into account here.
// [to_number]: Cached to_number computed at startup.
DECL_ACCESSORS(to_number, Object)
- inline byte kind();
+ inline byte kind() const;
inline void set_kind(byte kind);
DECLARE_CAST(Oddball)