v8.h | v8.h | |||
---|---|---|---|---|
skipping to change at line 905 | skipping to change at line 905 | |||
*/ | */ | |||
static Local<String> New(const char* data, int length = -1); | static Local<String> New(const char* data, int length = -1); | |||
/** Allocates a new string from utf16 data.*/ | /** Allocates a new string from utf16 data.*/ | |||
static Local<String> New(const uint16_t* data, int length = -1); | static Local<String> New(const uint16_t* data, int length = -1); | |||
/** Creates a symbol. Returns one if it exists already.*/ | /** Creates a symbol. Returns one if it exists already.*/ | |||
static Local<String> NewSymbol(const char* data, int length = -1); | static Local<String> NewSymbol(const char* data, int length = -1); | |||
/** | /** | |||
* Creates a new string by concatenating the left and the right strings | ||||
* passed in as parameters. | ||||
*/ | ||||
static Local<String> Concat(Handle<String> left, Handle<String>right); | ||||
/** | ||||
* Creates a new external string using the data defined in the given | * Creates a new external string using the data defined in the given | |||
* resource. The resource is deleted when the external string is no | * resource. The resource is deleted when the external string is no | |||
* longer live on V8's heap. The caller of this function should not | * longer live on V8's heap. The caller of this function should not | |||
* delete or modify the resource. Neither should the underlying buffer be | * delete or modify the resource. Neither should the underlying buffer be | |||
* deallocated or modified except through the destructor of the | * deallocated or modified except through the destructor of the | |||
* external string resource. | * external string resource. | |||
*/ | */ | |||
static Local<String> NewExternal(ExternalStringResource* resource); | static Local<String> NewExternal(ExternalStringResource* resource); | |||
/** | /** | |||
skipping to change at line 1047 | skipping to change at line 1053 | |||
Number(); | Number(); | |||
static void CheckCast(v8::Value* obj); | static void CheckCast(v8::Value* obj); | |||
}; | }; | |||
/** | /** | |||
* A JavaScript value representing a signed integer. | * A JavaScript value representing a signed integer. | |||
*/ | */ | |||
class V8EXPORT Integer : public Number { | class V8EXPORT Integer : public Number { | |||
public: | public: | |||
static Local<Integer> New(int32_t value); | static Local<Integer> New(int32_t value); | |||
static inline Local<Integer> NewFromUnsigned(uint32_t value); | ||||
int64_t Value() const; | int64_t Value() const; | |||
static inline Integer* Cast(v8::Value* obj); | static inline Integer* Cast(v8::Value* obj); | |||
private: | private: | |||
Integer(); | Integer(); | |||
static void CheckCast(v8::Value* obj); | static void CheckCast(v8::Value* obj); | |||
}; | }; | |||
/** | /** | |||
* A JavaScript value representing a 32-bit signed integer. | * A JavaScript value representing a 32-bit signed integer. | |||
*/ | */ | |||
skipping to change at line 1257 | skipping to change at line 1264 | |||
* the backing store is preserved while V8 has a reference. | * the backing store is preserved while V8 has a reference. | |||
*/ | */ | |||
void SetIndexedPropertiesToPixelData(uint8_t* data, int length); | void SetIndexedPropertiesToPixelData(uint8_t* data, int length); | |||
static Local<Object> New(); | static Local<Object> New(); | |||
static inline Object* Cast(Value* obj); | static inline Object* Cast(Value* obj); | |||
private: | private: | |||
Object(); | Object(); | |||
static void CheckCast(Value* obj); | static void CheckCast(Value* obj); | |||
Local<Value> CheckedGetInternalField(int index); | Local<Value> CheckedGetInternalField(int index); | |||
void* SlowGetPointerFromInternalField(int index); | ||||
/** | /** | |||
* If quick access to the internal field is possible this method | * If quick access to the internal field is possible this method | |||
* returns the value. Otherwise an empty handle is returned. | * returns the value. Otherwise an empty handle is returned. | |||
*/ | */ | |||
inline Local<Value> UncheckedGetInternalField(int index); | inline Local<Value> UncheckedGetInternalField(int index); | |||
}; | }; | |||
/** | /** | |||
* An instance of the built-in array constructor (ECMA-262, 15.4.2). | * An instance of the built-in array constructor (ECMA-262, 15.4.2). | |||
skipping to change at line 2652 | skipping to change at line 2660 | |||
// Tag information for HeapObject. | // Tag information for HeapObject. | |||
const int kHeapObjectTag = 1; | const int kHeapObjectTag = 1; | |||
const int kHeapObjectTagSize = 2; | const int kHeapObjectTagSize = 2; | |||
const intptr_t kHeapObjectTagMask = (1 << kHeapObjectTagSize) - 1; | const intptr_t kHeapObjectTagMask = (1 << kHeapObjectTagSize) - 1; | |||
// Tag information for Smi. | // Tag information for Smi. | |||
const int kSmiTag = 0; | const int kSmiTag = 0; | |||
const int kSmiTagSize = 1; | const int kSmiTagSize = 1; | |||
const intptr_t kSmiTagMask = (1 << kSmiTagSize) - 1; | const intptr_t kSmiTagMask = (1 << kSmiTagSize) - 1; | |||
template <size_t ptr_size> struct SmiConstants; | ||||
// Smi constants for 32-bit systems. | ||||
template <> struct SmiConstants<4> { | ||||
static const int kSmiShiftSize = 0; | ||||
static const int kSmiValueSize = 31; | ||||
static inline int SmiToInt(internal::Object* value) { | ||||
int shift_bits = kSmiTagSize + kSmiShiftSize; | ||||
// Throw away top 32 bits and shift down (requires >> to be sign extend | ||||
ing). | ||||
return static_cast<int>(reinterpret_cast<intptr_t>(value)) >> shift_bit | ||||
s; | ||||
} | ||||
}; | ||||
// Smi constants for 64-bit systems. | ||||
template <> struct SmiConstants<8> { | ||||
static const int kSmiShiftSize = 31; | ||||
static const int kSmiValueSize = 32; | ||||
static inline int SmiToInt(internal::Object* value) { | ||||
int shift_bits = kSmiTagSize + kSmiShiftSize; | ||||
// Shift down and throw away top 32 bits. | ||||
return static_cast<int>(reinterpret_cast<intptr_t>(value) >> shift_bits | ||||
); | ||||
} | ||||
}; | ||||
const int kSmiShiftSize = SmiConstants<sizeof(void*)>::kSmiShiftSize; | ||||
const int kSmiValueSize = SmiConstants<sizeof(void*)>::kSmiValueSize; | ||||
/** | /** | |||
* This class exports constants and functionality from within v8 that | * This class exports constants and functionality from within v8 that | |||
* is necessary to implement inline functions in the v8 api. Don't | * is necessary to implement inline functions in the v8 api. Don't | |||
* depend on functions and constants defined here. | * depend on functions and constants defined here. | |||
*/ | */ | |||
class Internals { | class Internals { | |||
public: | public: | |||
// These values match non-compiler-dependent values defined within | // These values match non-compiler-dependent values defined within | |||
// the implementation of v8. | // the implementation of v8. | |||
static const int kHeapObjectMapOffset = 0; | static const int kHeapObjectMapOffset = 0; | |||
static const int kMapInstanceTypeOffset = sizeof(void*) + sizeof(int); | static const int kMapInstanceTypeOffset = sizeof(void*) + sizeof(int); | |||
static const int kStringResourceOffset = 2 * sizeof(void*); | static const int kStringResourceOffset = 2 * sizeof(void*); | |||
static const int kProxyProxyOffset = sizeof(void*); | static const int kProxyProxyOffset = sizeof(void*); | |||
static const int kJSObjectHeaderSize = 3 * sizeof(void*); | static const int kJSObjectHeaderSize = 3 * sizeof(void*); | |||
static const int kFullStringRepresentationMask = 0x07; | static const int kFullStringRepresentationMask = 0x07; | |||
static const int kExternalTwoByteRepresentationTag = 0x03; | static const int kExternalTwoByteRepresentationTag = 0x03; | |||
static const int kAlignedPointerShift = 2; | ||||
// These constants are compiler dependent so their values must be | // These constants are compiler dependent so their values must be | |||
// defined within the implementation. | // defined within the implementation. | |||
V8EXPORT static int kJSObjectType; | V8EXPORT static int kJSObjectType; | |||
V8EXPORT static int kFirstNonstringType; | V8EXPORT static int kFirstNonstringType; | |||
V8EXPORT static int kProxyType; | V8EXPORT static int kProxyType; | |||
static inline bool HasHeapObjectTag(internal::Object* value) { | static inline bool HasHeapObjectTag(internal::Object* value) { | |||
return ((reinterpret_cast<intptr_t>(value) & kHeapObjectTagMask) == | return ((reinterpret_cast<intptr_t>(value) & kHeapObjectTagMask) == | |||
kHeapObjectTag); | kHeapObjectTag); | |||
} | } | |||
static inline bool HasSmiTag(internal::Object* value) { | static inline bool HasSmiTag(internal::Object* value) { | |||
return ((reinterpret_cast<intptr_t>(value) & kSmiTagMask) == kSmiTag); | return ((reinterpret_cast<intptr_t>(value) & kSmiTagMask) == kSmiTag); | |||
} | } | |||
static inline int SmiValue(internal::Object* value) { | static inline int SmiValue(internal::Object* value) { | |||
return static_cast<int>(reinterpret_cast<intptr_t>(value)) >> kSmiTagSi | return SmiConstants<sizeof(void*)>::SmiToInt(value); | |||
ze; | } | |||
static inline int GetInstanceType(internal::Object* obj) { | ||||
typedef internal::Object O; | ||||
O* map = ReadField<O*>(obj, kHeapObjectMapOffset); | ||||
return ReadField<uint8_t>(map, kMapInstanceTypeOffset); | ||||
} | ||||
static inline void* GetExternalPointer(internal::Object* obj) { | ||||
if (HasSmiTag(obj)) { | ||||
return obj; | ||||
} else if (GetInstanceType(obj) == kProxyType) { | ||||
return ReadField<void*>(obj, kProxyProxyOffset); | ||||
} else { | ||||
return NULL; | ||||
} | ||||
} | } | |||
static inline bool IsExternalTwoByteString(int instance_type) { | static inline bool IsExternalTwoByteString(int instance_type) { | |||
int representation = (instance_type & kFullStringRepresentationMask); | int representation = (instance_type & kFullStringRepresentationMask); | |||
return representation == kExternalTwoByteRepresentationTag; | return representation == kExternalTwoByteRepresentationTag; | |||
} | } | |||
template <typename T> | template <typename T> | |||
static inline T ReadField(Object* ptr, int offset) { | static inline T ReadField(Object* ptr, int offset) { | |||
uint8_t* addr = reinterpret_cast<uint8_t*>(ptr) + offset - kHeapObjectT ag; | uint8_t* addr = reinterpret_cast<uint8_t*>(ptr) + offset - kHeapObjectT ag; | |||
skipping to change at line 2826 | skipping to change at line 2876 | |||
Local<Value> quick_result = UncheckedGetInternalField(index); | Local<Value> quick_result = UncheckedGetInternalField(index); | |||
if (!quick_result.IsEmpty()) return quick_result; | if (!quick_result.IsEmpty()) return quick_result; | |||
#endif | #endif | |||
return CheckedGetInternalField(index); | return CheckedGetInternalField(index); | |||
} | } | |||
Local<Value> Object::UncheckedGetInternalField(int index) { | Local<Value> Object::UncheckedGetInternalField(int index) { | |||
typedef internal::Object O; | typedef internal::Object O; | |||
typedef internal::Internals I; | typedef internal::Internals I; | |||
O* obj = *reinterpret_cast<O**>(this); | O* obj = *reinterpret_cast<O**>(this); | |||
O* map = I::ReadField<O*>(obj, I::kHeapObjectMapOffset); | if (I::GetInstanceType(obj) == I::kJSObjectType) { | |||
int instance_type = I::ReadField<uint8_t>(map, I::kMapInstanceTypeOffset) | ||||
; | ||||
if (instance_type == I::kJSObjectType) { | ||||
// If the object is a plain JSObject, which is the common case, | // If the object is a plain JSObject, which is the common case, | |||
// we know where to find the internal fields and can return the | // we know where to find the internal fields and can return the | |||
// value directly. | // value directly. | |||
int offset = I::kJSObjectHeaderSize + (sizeof(void*) * index); | int offset = I::kJSObjectHeaderSize + (sizeof(void*) * index); | |||
O* value = I::ReadField<O*>(obj, offset); | O* value = I::ReadField<O*>(obj, offset); | |||
O** result = HandleScope::CreateHandle(value); | O** result = HandleScope::CreateHandle(value); | |||
return Local<Value>(reinterpret_cast<Value*>(result)); | return Local<Value>(reinterpret_cast<Value*>(result)); | |||
} else { | } else { | |||
return Local<Value>(); | return Local<Value>(); | |||
} | } | |||
skipping to change at line 2851 | skipping to change at line 2899 | |||
void* External::Unwrap(Handle<v8::Value> obj) { | void* External::Unwrap(Handle<v8::Value> obj) { | |||
#ifdef V8_ENABLE_CHECKS | #ifdef V8_ENABLE_CHECKS | |||
return FullUnwrap(obj); | return FullUnwrap(obj); | |||
#else | #else | |||
return QuickUnwrap(obj); | return QuickUnwrap(obj); | |||
#endif | #endif | |||
} | } | |||
void* External::QuickUnwrap(Handle<v8::Value> wrapper) { | void* External::QuickUnwrap(Handle<v8::Value> wrapper) { | |||
typedef internal::Object O; | typedef internal::Object O; | |||
typedef internal::Internals I; | ||||
O* obj = *reinterpret_cast<O**>(const_cast<v8::Value*>(*wrapper)); | O* obj = *reinterpret_cast<O**>(const_cast<v8::Value*>(*wrapper)); | |||
if (I::HasSmiTag(obj)) { | return internal::Internals::GetExternalPointer(obj); | |||
int value = I::SmiValue(obj) << I::kAlignedPointerShift; | ||||
return reinterpret_cast<void*>(value); | ||||
} else { | ||||
O* map = I::ReadField<O*>(obj, I::kHeapObjectMapOffset); | ||||
int instance_type = I::ReadField<uint8_t>(map, I::kMapInstanceTypeOffse | ||||
t); | ||||
if (instance_type == I::kProxyType) { | ||||
return I::ReadField<void*>(obj, I::kProxyProxyOffset); | ||||
} else { | ||||
return NULL; | ||||
} | ||||
} | ||||
} | } | |||
void* Object::GetPointerFromInternalField(int index) { | void* Object::GetPointerFromInternalField(int index) { | |||
return External::Unwrap(GetInternalField(index)); | typedef internal::Object O; | |||
typedef internal::Internals I; | ||||
O* obj = *reinterpret_cast<O**>(this); | ||||
if (I::GetInstanceType(obj) == I::kJSObjectType) { | ||||
// If the object is a plain JSObject, which is the common case, | ||||
// we know where to find the internal fields and can return the | ||||
// value directly. | ||||
int offset = I::kJSObjectHeaderSize + (sizeof(void*) * index); | ||||
O* value = I::ReadField<O*>(obj, offset); | ||||
return I::GetExternalPointer(value); | ||||
} | ||||
return SlowGetPointerFromInternalField(index); | ||||
} | } | |||
String* String::Cast(v8::Value* value) { | String* String::Cast(v8::Value* value) { | |||
#ifdef V8_ENABLE_CHECKS | #ifdef V8_ENABLE_CHECKS | |||
CheckCast(value); | CheckCast(value); | |||
#endif | #endif | |||
return static_cast<String*>(value); | return static_cast<String*>(value); | |||
} | } | |||
String::ExternalStringResource* String::GetExternalStringResource() const { | String::ExternalStringResource* String::GetExternalStringResource() const { | |||
typedef internal::Object O; | typedef internal::Object O; | |||
typedef internal::Internals I; | typedef internal::Internals I; | |||
O* obj = *reinterpret_cast<O**>(const_cast<String*>(this)); | O* obj = *reinterpret_cast<O**>(const_cast<String*>(this)); | |||
O* map = I::ReadField<O*>(obj, I::kHeapObjectMapOffset); | ||||
int instance_type = I::ReadField<uint8_t>(map, I::kMapInstanceTypeOffset) | ||||
; | ||||
String::ExternalStringResource* result; | String::ExternalStringResource* result; | |||
if (I::IsExternalTwoByteString(instance_type)) { | if (I::IsExternalTwoByteString(I::GetInstanceType(obj))) { | |||
void* value = I::ReadField<void*>(obj, I::kStringResourceOffset); | void* value = I::ReadField<void*>(obj, I::kStringResourceOffset); | |||
result = reinterpret_cast<String::ExternalStringResource*>(value); | result = reinterpret_cast<String::ExternalStringResource*>(value); | |||
} else { | } else { | |||
result = NULL; | result = NULL; | |||
} | } | |||
#ifdef V8_ENABLE_CHECKS | #ifdef V8_ENABLE_CHECKS | |||
VerifyExternalStringResource(result); | VerifyExternalStringResource(result); | |||
#endif | #endif | |||
return result; | return result; | |||
} | } | |||
skipping to change at line 2910 | skipping to change at line 2958 | |||
#else | #else | |||
return QuickIsString(); | return QuickIsString(); | |||
#endif | #endif | |||
} | } | |||
bool Value::QuickIsString() const { | bool Value::QuickIsString() const { | |||
typedef internal::Object O; | typedef internal::Object O; | |||
typedef internal::Internals I; | typedef internal::Internals I; | |||
O* obj = *reinterpret_cast<O**>(const_cast<Value*>(this)); | O* obj = *reinterpret_cast<O**>(const_cast<Value*>(this)); | |||
if (!I::HasHeapObjectTag(obj)) return false; | if (!I::HasHeapObjectTag(obj)) return false; | |||
O* map = I::ReadField<O*>(obj, I::kHeapObjectMapOffset); | return (I::GetInstanceType(obj) < I::kFirstNonstringType); | |||
int instance_type = I::ReadField<uint8_t>(map, I::kMapInstanceTypeOffset) | ||||
; | ||||
return (instance_type < I::kFirstNonstringType); | ||||
} | } | |||
Number* Number::Cast(v8::Value* value) { | Number* Number::Cast(v8::Value* value) { | |||
#ifdef V8_ENABLE_CHECKS | #ifdef V8_ENABLE_CHECKS | |||
CheckCast(value); | CheckCast(value); | |||
#endif | #endif | |||
return static_cast<Number*>(value); | return static_cast<Number*>(value); | |||
} | } | |||
Local<Integer> Integer::NewFromUnsigned(uint32_t value) { | ||||
bool fits_into_int32_t = (value & (1 << 31)) == 0; | ||||
if (fits_into_int32_t) { | ||||
return Integer::New(static_cast<int32_t>(value)); | ||||
} | ||||
return Local<Integer>::Cast(Number::New(value)); | ||||
} | ||||
Integer* Integer::Cast(v8::Value* value) { | Integer* Integer::Cast(v8::Value* value) { | |||
#ifdef V8_ENABLE_CHECKS | #ifdef V8_ENABLE_CHECKS | |||
CheckCast(value); | CheckCast(value); | |||
#endif | #endif | |||
return static_cast<Integer*>(value); | return static_cast<Integer*>(value); | |||
} | } | |||
Date* Date::Cast(v8::Value* value) { | Date* Date::Cast(v8::Value* value) { | |||
#ifdef V8_ENABLE_CHECKS | #ifdef V8_ENABLE_CHECKS | |||
CheckCast(value); | CheckCast(value); | |||
End of changes. 14 change blocks. | ||||
30 lines changed or deleted | 82 lines changed or added | |||