📄 objects-inl.h.svn-base
字号:
// Copyright 2006-2008 the V8 project authors. All rights reserved.// Redistribution and use in source and binary forms, with or without// modification, are permitted provided that the following conditions are// met://// * Redistributions of source code must retain the above copyright// notice, this list of conditions and the following disclaimer.// * Redistributions in binary form must reproduce the above// copyright notice, this list of conditions and the following// disclaimer in the documentation and/or other materials provided// with the distribution.// * Neither the name of Google Inc. nor the names of its// contributors may be used to endorse or promote products derived// from this software without specific prior written permission.//// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.//// Review notes://// - The use of macros in these inline fuctions may seem superfluous// but it is absolutely needed to make sure gcc generates optimal// code. gcc is not happy when attempting to inline too deep.//#ifndef V8_OBJECTS_INL_H_#define V8_OBJECTS_INL_H_#include "objects.h"#include "contexts.h"#include "conversions-inl.h"#include "property.h"namespace v8 { namespace internal {PropertyDetails::PropertyDetails(Smi* smi) { value_ = smi->value();}Smi* PropertyDetails::AsSmi() { return Smi::FromInt(value_);}#define CAST_ACCESSOR(type) \ type* type::cast(Object* object) { \ ASSERT(object->Is##type()); \ return reinterpret_cast<type*>(object); \ }#define INT_ACCESSORS(holder, name, offset) \ int holder::name() { return READ_INT_FIELD(this, offset); } \ void holder::set_##name(int value) { WRITE_INT_FIELD(this, offset, value); }#define ACCESSORS(holder, name, type, offset) \ type* holder::name() { return type::cast(READ_FIELD(this, offset)); } \ void holder::set_##name(type* value) { \ WRITE_FIELD(this, offset, value); \ WRITE_BARRIER(this, offset); \ }#define SMI_ACCESSORS(holder, name, offset) \ int holder::name() { \ Object* value = READ_FIELD(this, offset); \ return Smi::cast(value)->value(); \ } \ void holder::set_##name(int value) { \ WRITE_FIELD(this, offset, Smi::FromInt(value)); \ }#define BOOL_ACCESSORS(holder, field, name, offset) \ bool holder::name() { \ return BooleanBit::get(field(), offset); \ } \ void holder::set_##name(bool value) { \ set_##field(BooleanBit::set(field(), offset, value)); \ }bool Object::IsSmi() { return HAS_SMI_TAG(this);}bool Object::IsHeapObject() { return HAS_HEAP_OBJECT_TAG(this);}bool Object::IsHeapNumber() { return Object::IsHeapObject() && HeapObject::cast(this)->map()->instance_type() == HEAP_NUMBER_TYPE;}bool Object::IsString() { return Object::IsHeapObject() && HeapObject::cast(this)->map()->instance_type() < FIRST_NONSTRING_TYPE;}bool Object::IsSeqString() { return IsString() && (String::cast(this)->representation_tag() == kSeqStringTag);}bool Object::IsAsciiString() { return IsString() && (String::cast(this)->is_ascii());}bool Object::IsTwoByteString() { return IsString() && (!String::cast(this)->is_ascii());}bool Object::IsConsString() { return IsString() && (String::cast(this)->representation_tag() == kConsStringTag);}bool Object::IsSlicedString() { return IsString() && (String::cast(this)->representation_tag() == kSlicedStringTag);}bool Object::IsExternalString() { return IsString() && (String::cast(this)->representation_tag() == kExternalStringTag);}bool Object::IsExternalAsciiString() { return IsExternalString() && (String::cast(this)->is_ascii());}bool Object::IsExternalTwoByteString() { return IsExternalString() && (!String::cast(this)->is_ascii());}bool Object::IsShortString() { return IsString() && (String::cast(this)->size_tag() == kShortStringTag);}bool Object::IsMediumString() { return IsString() && (String::cast(this)->size_tag() == kMediumStringTag);}bool Object::IsLongString() { return IsString() && (String::cast(this)->size_tag() == kLongStringTag);}bool Object::IsSymbol() { return IsString() && (String::cast(this)->is_symbol());}bool Object::IsNumber() { return IsSmi() || IsHeapNumber();}bool Object::IsByteArray() { return Object::IsHeapObject() && HeapObject::cast(this)->map()->instance_type() == BYTE_ARRAY_TYPE;}bool Object::IsFailure() { return HAS_FAILURE_TAG(this);}bool Object::IsRetryAfterGC() { return HAS_FAILURE_TAG(this) && Failure::cast(this)->type() == Failure::RETRY_AFTER_GC;}bool Object::IsException() { return this == Failure::Exception();}bool Object::IsJSObject() { return IsHeapObject() && HeapObject::cast(this)->map()->instance_type() >= FIRST_JS_OBJECT_TYPE;}bool Object::IsMap() { return Object::IsHeapObject() && HeapObject::cast(this)->map()->instance_type() == MAP_TYPE;}bool Object::IsFixedArray() { return Object::IsHeapObject() && HeapObject::cast(this)->map()->instance_type() == FIXED_ARRAY_TYPE;}bool Object::IsDescriptorArray() { return IsFixedArray();}bool Object::IsContext() { return Object::IsHeapObject() && (HeapObject::cast(this)->map() == Heap::context_map() || HeapObject::cast(this)->map() == Heap::global_context_map());}bool Object::IsGlobalContext() { return Object::IsHeapObject() && HeapObject::cast(this)->map() == Heap::global_context_map();}bool Object::IsJSFunction() { return Object::IsHeapObject() && HeapObject::cast(this)->map()->instance_type() == JS_FUNCTION_TYPE;}template <> inline bool Is<JSFunction>(Object* obj) { return obj->IsJSFunction();}bool Object::IsCode() { return Object::IsHeapObject() && HeapObject::cast(this)->map()->instance_type() == CODE_TYPE;}bool Object::IsOddball() { return Object::IsHeapObject() && HeapObject::cast(this)->map()->instance_type() == ODDBALL_TYPE;}bool Object::IsSharedFunctionInfo() { return Object::IsHeapObject() && (HeapObject::cast(this)->map()->instance_type() == SHARED_FUNCTION_INFO_TYPE);}bool Object::IsJSValue() { return Object::IsHeapObject() && HeapObject::cast(this)->map()->instance_type() == JS_VALUE_TYPE;}bool Object::IsProxy() { return Object::IsHeapObject() && HeapObject::cast(this)->map()->instance_type() == PROXY_TYPE;}bool Object::IsBoolean() { return IsTrue() || IsFalse();}bool Object::IsJSArray() { return Object::IsHeapObject() && HeapObject::cast(this)->map()->instance_type() == JS_ARRAY_TYPE;}bool Object::IsJSRegExp() { return Object::IsHeapObject() && HeapObject::cast(this)->map()->instance_type() == JS_REGEXP_TYPE;}template <> inline bool Is<JSArray>(Object* obj) { return obj->IsJSArray();}bool Object::IsHashTable() { return Object::IsHeapObject() && HeapObject::cast(this)->map() == Heap::hash_table_map();}bool Object::IsDictionary() { return IsHashTable() && this != Heap::symbol_table();}bool Object::IsSymbolTable() { return IsHashTable() && this == Heap::symbol_table();}bool Object::IsCompilationCacheTable() { return IsHashTable();}bool Object::IsMapCache() { return IsHashTable();}bool Object::IsPrimitive() { return IsOddball() || IsNumber() || IsString();}bool Object::IsGlobalObject() { return IsHeapObject() && ((HeapObject::cast(this)->map()->instance_type() == JS_GLOBAL_OBJECT_TYPE) || (HeapObject::cast(this)->map()->instance_type() == JS_BUILTINS_OBJECT_TYPE));}bool Object::IsJSGlobalObject() {#ifdef DEBUG if (IsHeapObject() && (HeapObject::cast(this)->map()->instance_type() == JS_GLOBAL_OBJECT_TYPE)) { ASSERT(IsAccessCheckNeeded()); }#endif return IsHeapObject() && (HeapObject::cast(this)->map()->instance_type() == JS_GLOBAL_OBJECT_TYPE);}bool Object::IsJSBuiltinsObject() { return IsHeapObject() && (HeapObject::cast(this)->map()->instance_type() == JS_BUILTINS_OBJECT_TYPE);}bool Object::IsUndetectableObject() { return IsHeapObject() && HeapObject::cast(this)->map()->is_undetectable();}bool Object::IsAccessCheckNeeded() { return IsHeapObject() && HeapObject::cast(this)->map()->needs_access_check();}bool Object::IsStruct() { if (!IsHeapObject()) return false; switch (HeapObject::cast(this)->map()->instance_type()) {#define MAKE_STRUCT_CASE(NAME, Name, name) case NAME##_TYPE: return true; STRUCT_LIST(MAKE_STRUCT_CASE)#undef MAKE_STRUCT_CASE default: return false; }}#define MAKE_STRUCT_PREDICATE(NAME, Name, name) \ bool Object::Is##Name() { \ return Object::IsHeapObject() \ && HeapObject::cast(this)->map()->instance_type() == NAME##_TYPE; \ } STRUCT_LIST(MAKE_STRUCT_PREDICATE)#undef MAKE_STRUCT_PREDICATEbool Object::IsUndefined() { return this == Heap::undefined_value();}bool Object::IsTheHole() { return this == Heap::the_hole_value();}bool Object::IsNull() { return this == Heap::null_value();}bool Object::IsTrue() { return this == Heap::true_value();}bool Object::IsFalse() { return this == Heap::false_value();}double Object::Number() { ASSERT(IsNumber()); return IsSmi() ? static_cast<double>(reinterpret_cast<Smi*>(this)->value()) : reinterpret_cast<HeapNumber*>(this)->value();}Object* Object::ToSmi() { if (IsSmi()) return this; if (IsHeapNumber()) { double value = HeapNumber::cast(this)->value(); int int_value = FastD2I(value); if (value == FastI2D(int_value) && Smi::IsValid(int_value)) { return Smi::FromInt(int_value); } } return Failure::Exception();}Object* Object::GetElement(uint32_t index) { return GetElementWithReceiver(this, index);}Object* Object::GetProperty(String* key) { PropertyAttributes attributes; return GetPropertyWithReceiver(this, key, &attributes);}Object* Object::GetProperty(String* key, PropertyAttributes* attributes) { return GetPropertyWithReceiver(this, key, attributes);}#define FIELD_ADDR(p, offset) \ (reinterpret_cast<byte*>(p) + offset - kHeapObjectTag)#define READ_FIELD(p, offset) \ (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)))#define WRITE_FIELD(p, offset, value) \ (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)) = value)#define WRITE_BARRIER(object, offset) \ Heap::RecordWrite(object->address(), offset);#define READ_DOUBLE_FIELD(p, offset) \ (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)))#define WRITE_DOUBLE_FIELD(p, offset, value) \ (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)) = value)#define READ_INT_FIELD(p, offset) \ (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)))#define WRITE_INT_FIELD(p, offset, value) \ (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)) = value)#define READ_SHORT_FIELD(p, offset) \ (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)))#define WRITE_SHORT_FIELD(p, offset, value) \ (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)) = value)#define READ_BYTE_FIELD(p, offset) \ (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)))#define WRITE_BYTE_FIELD(p, offset, value) \ (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)) = value)Object* HeapObject::GetHeapObjectField(HeapObject* obj, int index) { return READ_FIELD(obj, HeapObject::kHeaderSize + kPointerSize * index);}int Smi::value() { return reinterpret_cast<int>(this) >> kSmiTagSize;}Smi* Smi::FromInt(int value) { ASSERT(Smi::IsValid(value)); return reinterpret_cast<Smi*>((value << kSmiTagSize) | kSmiTag);}Failure::Type Failure::type() const { return static_cast<Type>(value() & kFailureTypeTagMask);}bool Failure::IsInternalError() const { return type() == INTERNAL_ERROR;}bool Failure::IsOutOfMemoryException() const { return type() == OUT_OF_MEMORY_EXCEPTION;}int Failure::requested() const { const int kShiftBits = kFailureTypeTagSize + kSpaceTagSize - kObjectAlignmentBits; STATIC_ASSERT(kShiftBits >= 0); ASSERT(type() == RETRY_AFTER_GC); return value() >> kShiftBits;}AllocationSpace Failure::allocation_space() const { ASSERT_EQ(RETRY_AFTER_GC, type()); return static_cast<AllocationSpace>((value() >> kFailureTypeTagSize) & kSpaceTagMask);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -