diff --git a/include/v8.h b/include/v8.h index ec2f48d796..430f410a6e 100644 --- a/include/v8.h +++ b/include/v8.h @@ -863,13 +863,13 @@ class Value : public Data { * Returns true if this value is the undefined value. See ECMA-262 * 4.3.10. */ - V8EXPORT bool IsUndefined() const; + inline bool IsUndefined() const; /** * Returns true if this value is the null value. See ECMA-262 * 4.3.11. */ - V8EXPORT bool IsNull() const; + inline bool IsNull() const; /** * Returns true if this value is true. @@ -983,7 +983,11 @@ class Value : public Data { V8EXPORT bool StrictEquals(Handle that) const; private: + inline bool QuickIsUndefined() const; + inline bool QuickIsNull() const; inline bool QuickIsString() const; + V8EXPORT bool FullIsUndefined() const; + V8EXPORT bool FullIsNull() const; V8EXPORT bool FullIsString() const; }; @@ -3894,6 +3898,7 @@ class Internals { static const int kStringResourceOffset = InternalConstants::kStringResourceOffset; + static const int kOddballKindOffset = 3 * kApiPointerSize; static const int kForeignAddressOffset = kApiPointerSize; static const int kJSObjectHeaderSize = 3 * kApiPointerSize; static const int kFullStringRepresentationMask = 0x07; @@ -3901,8 +3906,12 @@ class Internals { static const int kJSObjectType = 0xaa; static const int kFirstNonstringType = 0x80; + static const int kOddballType = 0x82; static const int kForeignType = 0x85; + static const int kUndefinedOddballKind = 5; + static const int kNullOddballKind = 3; + static inline bool HasHeapObjectTag(internal::Object* value) { return ((reinterpret_cast(value) & kHeapObjectTagMask) == kHeapObjectTag); @@ -3922,6 +3931,11 @@ class Internals { return ReadField(map, kMapInstanceTypeOffset); } + static inline int GetOddballKind(internal::Object* obj) { + typedef internal::Object O; + return SmiValue(ReadField(obj, kOddballKindOffset)); + } + static inline void* GetExternalPointerFromSmi(internal::Object* value) { const uintptr_t address = reinterpret_cast(value); return reinterpret_cast(address >> kPointerToSmiShift); @@ -4203,6 +4217,42 @@ String::ExternalStringResource* String::GetExternalStringResource() const { } +bool Value::IsUndefined() const { +#ifdef V8_ENABLE_CHECKS + return FullIsUndefined(); +#else + return QuickIsUndefined(); +#endif +} + +bool Value::QuickIsUndefined() const { + typedef internal::Object O; + typedef internal::Internals I; + O* obj = *reinterpret_cast(const_cast(this)); + if (!I::HasHeapObjectTag(obj)) return false; + if (I::GetInstanceType(obj) != I::kOddballType) return false; + return (I::GetOddballKind(obj) == I::kUndefinedOddballKind); +} + + +bool Value::IsNull() const { +#ifdef V8_ENABLE_CHECKS + return FullIsNull(); +#else + return QuickIsNull(); +#endif +} + +bool Value::QuickIsNull() const { + typedef internal::Object O; + typedef internal::Internals I; + O* obj = *reinterpret_cast(const_cast(this)); + if (!I::HasHeapObjectTag(obj)) return false; + if (I::GetInstanceType(obj) != I::kOddballType) return false; + return (I::GetOddballKind(obj) == I::kNullOddballKind); +} + + bool Value::IsString() const { #ifdef V8_ENABLE_CHECKS return FullIsString(); diff --git a/src/api.cc b/src/api.cc index c7252ba3ff..3826a1c97b 100644 --- a/src/api.cc +++ b/src/api.cc @@ -2101,17 +2101,21 @@ bool StackFrame::IsConstructor() const { // --- D a t a --- -bool Value::IsUndefined() const { +bool Value::FullIsUndefined() const { if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsUndefined()")) { return false; } - return Utils::OpenHandle(this)->IsUndefined(); + bool result = Utils::OpenHandle(this)->IsUndefined(); + ASSERT_EQ(result, QuickIsUndefined()); + return result; } -bool Value::IsNull() const { +bool Value::FullIsNull() const { if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsNull()")) return false; - return Utils::OpenHandle(this)->IsNull(); + bool result = Utils::OpenHandle(this)->IsNull(); + ASSERT_EQ(result, QuickIsNull()); + return result; } diff --git a/src/objects.h b/src/objects.h index d682cde0f8..80d1fd47d0 100644 --- a/src/objects.h +++ b/src/objects.h @@ -680,6 +680,7 @@ const int kExternalArrayTypeCount = STATIC_CHECK(JS_OBJECT_TYPE == Internals::kJSObjectType); STATIC_CHECK(FIRST_NONSTRING_TYPE == Internals::kFirstNonstringType); +STATIC_CHECK(ODDBALL_TYPE == Internals::kOddballType); STATIC_CHECK(FOREIGN_TYPE == Internals::kForeignType); @@ -7636,6 +7637,10 @@ class Oddball: public HeapObject { kToNumberOffset + kPointerSize, kSize> BodyDescriptor; + STATIC_CHECK(kKindOffset == Internals::kOddballKindOffset); + STATIC_CHECK(kNull == Internals::kNullOddballKind); + STATIC_CHECK(kUndefined == Internals::kUndefinedOddballKind); + private: DISALLOW_IMPLICIT_CONSTRUCTORS(Oddball); };