| Index: include/v8.h
|
| diff --git a/include/v8.h b/include/v8.h
|
| index 28bea2e3e4435b39a4b50a140513560b80b3fd85..cf9275d918ccadc9dda2735069f1182a206cd874 100644
|
| --- a/include/v8.h
|
| +++ b/include/v8.h
|
| @@ -76,17 +76,6 @@
|
|
|
| #endif // _WIN32
|
|
|
| -// TODO(svenpanne) Remove this when the Chrome's v8 bindings have been adapted.
|
| -#define V8_DISABLE_DEPRECATIONS 1
|
| -
|
| -#if defined(__GNUC__) && !defined(V8_DISABLE_DEPRECATIONS)
|
| -#define V8_DEPRECATED(func) func __attribute__ ((deprecated))
|
| -#elif defined(_MSC_VER) && !defined(V8_DISABLE_DEPRECATIONS)
|
| -#define V8_DEPRECATED(func) __declspec(deprecated) func
|
| -#else
|
| -#define V8_DEPRECATED(func) func
|
| -#endif
|
| -
|
| /**
|
| * The v8 JavaScript engine.
|
| */
|
| @@ -1612,41 +1601,16 @@ class Object : public Value {
|
|
|
| /** Gets the number of internal fields for this Object. */
|
| V8EXPORT int InternalFieldCount();
|
| -
|
| - /** Gets the value from an internal field. */
|
| + /** Gets the value in an internal field. */
|
| inline Local<Value> GetInternalField(int index);
|
| -
|
| /** Sets the value in an internal field. */
|
| V8EXPORT void SetInternalField(int index, Handle<Value> value);
|
|
|
| - /**
|
| - * Gets a native pointer from an internal field. Deprecated. If the pointer is
|
| - * always 2-byte-aligned, use GetAlignedPointerFromInternalField instead,
|
| - * otherwise use a combination of GetInternalField, External::Cast and
|
| - * External::Value.
|
| - */
|
| - V8EXPORT V8_DEPRECATED(void* GetPointerFromInternalField(int index));
|
| -
|
| - /**
|
| - * Sets a native pointer in an internal field. Deprecated. If the pointer is
|
| - * always 2-byte aligned, use SetAlignedPointerInInternalField instead,
|
| - * otherwise use a combination of External::New and SetInternalField.
|
| - */
|
| - inline V8_DEPRECATED(void SetPointerInInternalField(int index, void* value));
|
| + /** Gets a native pointer from an internal field. */
|
| + inline void* GetPointerFromInternalField(int index);
|
|
|
| - /**
|
| - * Gets a 2-byte-aligned native pointer from an internal field. This field
|
| - * must have been set by SetAlignedPointerInInternalField, everything else
|
| - * leads to undefined behavior.
|
| - */
|
| - inline void* GetAlignedPointerFromInternalField(int index);
|
| -
|
| - /**
|
| - * Sets a 2-byte-aligned native pointer in an internal field. To retrieve such
|
| - * a field, GetAlignedPointerFromInternalField must be used, everything else
|
| - * leads to undefined behavior.
|
| - */
|
| - V8EXPORT void SetAlignedPointerInInternalField(int index, void* value);
|
| + /** Sets a native pointer in an internal field. */
|
| + V8EXPORT void SetPointerInInternalField(int index, void* value);
|
|
|
| // Testers for local properties.
|
| V8EXPORT bool HasOwnProperty(Handle<String> key);
|
| @@ -1777,8 +1741,14 @@ class Object : public Value {
|
| private:
|
| V8EXPORT Object();
|
| V8EXPORT static void CheckCast(Value* obj);
|
| - V8EXPORT Local<Value> SlowGetInternalField(int index);
|
| - V8EXPORT void* SlowGetAlignedPointerFromInternalField(int index);
|
| + V8EXPORT Local<Value> CheckedGetInternalField(int index);
|
| + V8EXPORT void* SlowGetPointerFromInternalField(int index);
|
| +
|
| + /**
|
| + * If quick access to the internal field is possible this method
|
| + * returns the value. Otherwise an empty handle is returned.
|
| + */
|
| + inline Local<Value> UncheckedGetInternalField(int index);
|
| };
|
|
|
|
|
| @@ -1989,22 +1959,29 @@ class RegExp : public Object {
|
|
|
|
|
| /**
|
| - * A JavaScript value that wraps a C++ void*. This type of value is mainly used
|
| - * to associate C++ data structures with JavaScript objects.
|
| + * A JavaScript value that wraps a C++ void*. This type of value is
|
| + * mainly used to associate C++ data structures with JavaScript
|
| + * objects.
|
| + *
|
| + * The Wrap function V8 will return the most optimal Value object wrapping the
|
| + * C++ void*. The type of the value is not guaranteed to be an External object
|
| + * and no assumptions about its type should be made. To access the wrapped
|
| + * value Unwrap should be used, all other operations on that object will lead
|
| + * to unpredictable results.
|
| */
|
| class External : public Value {
|
| public:
|
| - /** Deprecated, use New instead. */
|
| - V8_DEPRECATED(static inline Local<Value> Wrap(void* value));
|
| -
|
| - /** Deprecated, use a combination of Cast and Value instead. */
|
| - V8_DEPRECATED(static inline void* Unwrap(Handle<Value> obj));
|
| + V8EXPORT static Local<Value> Wrap(void* data);
|
| + static inline void* Unwrap(Handle<Value> obj);
|
|
|
| V8EXPORT static Local<External> New(void* value);
|
| static inline External* Cast(Value* obj);
|
| V8EXPORT void* Value() const;
|
| private:
|
| + V8EXPORT External();
|
| V8EXPORT static void CheckCast(v8::Value* obj);
|
| + static inline void* QuickUnwrap(Handle<v8::Value> obj);
|
| + V8EXPORT static void* FullUnwrap(Handle<v8::Value> obj);
|
| };
|
|
|
|
|
| @@ -3793,45 +3770,12 @@ class V8EXPORT Context {
|
| static bool InContext();
|
|
|
| /**
|
| - * Gets embedder data with index 0. Deprecated, use GetEmbedderData with index
|
| - * 0 instead.
|
| - */
|
| - V8_DEPRECATED(inline Local<Value> GetData());
|
| -
|
| - /**
|
| - * Sets embedder data with index 0. Deprecated, use SetEmbedderData with index
|
| - * 0 instead.
|
| + * Associate an additional data object with the context. This is mainly used
|
| + * with the debugger to provide additional information on the context through
|
| + * the debugger API.
|
| */
|
| - V8_DEPRECATED(inline void SetData(Handle<Value> value));
|
| -
|
| - /**
|
| - * Gets the embedder data with the given index, which must have been set by a
|
| - * previous call to SetEmbedderData with the same index. Note that index 0
|
| - * currently has a special meaning for Chrome's debugger.
|
| - */
|
| - inline Local<Value> GetEmbedderData(int index);
|
| -
|
| - /**
|
| - * Sets the embedder data with the given index, growing the data as
|
| - * needed. Note that index 0 currently has a special meaning for Chrome's
|
| - * debugger.
|
| - */
|
| - void SetEmbedderData(int index, Handle<Value> value);
|
| -
|
| - /**
|
| - * Gets a 2-byte-aligned native pointer from the embedder data with the given
|
| - * index, which must have bees set by a previous call to
|
| - * SetAlignedPointerInEmbedderData with the same index. Note that index 0
|
| - * currently has a special meaning for Chrome's debugger.
|
| - */
|
| - inline void* GetAlignedPointerFromEmbedderData(int index);
|
| -
|
| - /**
|
| - * Sets a 2-byte-aligned native pointer in the embedder data with the given
|
| - * index, growing the data as needed. Note that index 0 currently has a
|
| - * special meaning for Chrome's debugger.
|
| - */
|
| - void SetAlignedPointerInEmbedderData(int index, void* value);
|
| + void SetData(Handle<Value> data);
|
| + Local<Value> GetData();
|
|
|
| /**
|
| * Control whether code generation from strings is allowed. Calling
|
| @@ -3880,9 +3824,6 @@ class V8EXPORT Context {
|
| friend class Script;
|
| friend class Object;
|
| friend class Function;
|
| -
|
| - Local<Value> SlowGetEmbedderData(int index);
|
| - void* SlowGetAlignedPointerFromEmbedderData(int index);
|
| };
|
|
|
|
|
| @@ -4116,6 +4057,11 @@ template <> struct SmiTagging<4> {
|
| // Throw away top 32 bits and shift down (requires >> to be sign extending).
|
| return static_cast<int>(reinterpret_cast<intptr_t>(value)) >> shift_bits;
|
| }
|
| +
|
| + // For 32-bit systems any 2 bytes aligned pointer can be encoded as smi
|
| + // with a plain reinterpret_cast.
|
| + static const uintptr_t kEncodablePointerMask = 0x1;
|
| + static const int kPointerToSmiShift = 0;
|
| };
|
|
|
| // Smi constants for 64-bit systems.
|
| @@ -4127,11 +4073,26 @@ template <> struct SmiTagging<8> {
|
| // Shift down and throw away top 32 bits.
|
| return static_cast<int>(reinterpret_cast<intptr_t>(value) >> shift_bits);
|
| }
|
| +
|
| + // To maximize the range of pointers that can be encoded
|
| + // in the available 32 bits, we require them to be 8 bytes aligned.
|
| + // This gives 2 ^ (32 + 3) = 32G address space covered.
|
| + // It might be not enough to cover stack allocated objects on some platforms.
|
| + static const int kPointerAlignment = 3;
|
| +
|
| + static const uintptr_t kEncodablePointerMask =
|
| + ~(uintptr_t(0xffffffff) << kPointerAlignment);
|
| +
|
| + static const int kPointerToSmiShift =
|
| + kSmiTagSize + kSmiShiftSize - kPointerAlignment;
|
| };
|
|
|
| typedef SmiTagging<kApiPointerSize> PlatformSmiTagging;
|
| const int kSmiShiftSize = PlatformSmiTagging::kSmiShiftSize;
|
| const int kSmiValueSize = PlatformSmiTagging::kSmiValueSize;
|
| +const uintptr_t kEncodablePointerMask =
|
| + PlatformSmiTagging::kEncodablePointerMask;
|
| +const int kPointerToSmiShift = PlatformSmiTagging::kPointerToSmiShift;
|
|
|
| /**
|
| * This class exports constants and functionality from within v8 that
|
| @@ -4149,9 +4110,6 @@ class Internals {
|
| static const int kOddballKindOffset = 3 * kApiPointerSize;
|
| static const int kForeignAddressOffset = kApiPointerSize;
|
| static const int kJSObjectHeaderSize = 3 * kApiPointerSize;
|
| - static const int kFixedArrayHeaderSize = 2 * kApiPointerSize;
|
| - static const int kContextHeaderSize = 2 * kApiPointerSize;
|
| - static const int kContextEmbedderDataIndex = 54;
|
| static const int kFullStringRepresentationMask = 0x07;
|
| static const int kStringEncodingMask = 0x4;
|
| static const int kExternalTwoByteRepresentationTag = 0x02;
|
| @@ -4164,7 +4122,7 @@ class Internals {
|
| static const int kNullValueRootIndex = 7;
|
| static const int kTrueValueRootIndex = 8;
|
| static const int kFalseValueRootIndex = 9;
|
| - static const int kEmptySymbolRootIndex = 119;
|
| + static const int kEmptySymbolRootIndex = 118;
|
|
|
| static const int kJSObjectType = 0xaa;
|
| static const int kFirstNonstringType = 0x80;
|
| @@ -4179,6 +4137,10 @@ class Internals {
|
| kHeapObjectTag);
|
| }
|
|
|
| + static inline bool HasSmiTag(internal::Object* value) {
|
| + return ((reinterpret_cast<intptr_t>(value) & kSmiTagMask) == kSmiTag);
|
| + }
|
| +
|
| static inline int SmiValue(internal::Object* value) {
|
| return PlatformSmiTagging::SmiToInt(value);
|
| }
|
| @@ -4194,6 +4156,21 @@ class Internals {
|
| return SmiValue(ReadField<O*>(obj, kOddballKindOffset));
|
| }
|
|
|
| + static inline void* GetExternalPointerFromSmi(internal::Object* value) {
|
| + const uintptr_t address = reinterpret_cast<uintptr_t>(value);
|
| + return reinterpret_cast<void*>(address >> kPointerToSmiShift);
|
| + }
|
| +
|
| + static inline void* GetExternalPointer(internal::Object* obj) {
|
| + if (HasSmiTag(obj)) {
|
| + return GetExternalPointerFromSmi(obj);
|
| + } else if (GetInstanceType(obj) == kForeignType) {
|
| + return ReadField<void*>(obj, kForeignAddressOffset);
|
| + } else {
|
| + return NULL;
|
| + }
|
| + }
|
| +
|
| static inline bool IsExternalTwoByteString(int instance_type) {
|
| int representation = (instance_type & kFullStringRepresentationMask);
|
| return representation == kExternalTwoByteRepresentationTag;
|
| @@ -4227,19 +4204,6 @@ class Internals {
|
| return *reinterpret_cast<T*>(addr);
|
| }
|
|
|
| - template <typename T>
|
| - static inline T ReadEmbedderData(Context* context, int index) {
|
| - typedef internal::Object O;
|
| - typedef internal::Internals I;
|
| - O* ctx = *reinterpret_cast<O**>(context);
|
| - int embedder_data_offset = I::kContextHeaderSize +
|
| - (internal::kApiPointerSize * I::kContextEmbedderDataIndex);
|
| - O* embedder_data = I::ReadField<O*>(ctx, embedder_data_offset);
|
| - int value_offset =
|
| - I::kFixedArrayHeaderSize + (internal::kApiPointerSize * index);
|
| - return I::ReadField<T>(embedder_data, value_offset);
|
| - }
|
| -
|
| static inline bool CanCastToHeapObject(void* o) { return false; }
|
| static inline bool CanCastToHeapObject(Context* o) { return true; }
|
| static inline bool CanCastToHeapObject(String* o) { return true; }
|
| @@ -4454,40 +4418,63 @@ void Template::Set(const char* name, v8::Handle<Data> value) {
|
|
|
| Local<Value> Object::GetInternalField(int index) {
|
| #ifndef V8_ENABLE_CHECKS
|
| + Local<Value> quick_result = UncheckedGetInternalField(index);
|
| + if (!quick_result.IsEmpty()) return quick_result;
|
| +#endif
|
| + return CheckedGetInternalField(index);
|
| +}
|
| +
|
| +
|
| +Local<Value> Object::UncheckedGetInternalField(int index) {
|
| typedef internal::Object O;
|
| typedef internal::Internals I;
|
| O* obj = *reinterpret_cast<O**>(this);
|
| - // Fast path: 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.
|
| 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 + (internal::kApiPointerSize * index);
|
| O* value = I::ReadField<O*>(obj, offset);
|
| O** result = HandleScope::CreateHandle(value);
|
| return Local<Value>(reinterpret_cast<Value*>(result));
|
| + } else {
|
| + return Local<Value>();
|
| }
|
| +}
|
| +
|
| +
|
| +void* External::Unwrap(Handle<v8::Value> obj) {
|
| +#ifdef V8_ENABLE_CHECKS
|
| + return FullUnwrap(obj);
|
| +#else
|
| + return QuickUnwrap(obj);
|
| #endif
|
| - return SlowGetInternalField(index);
|
| }
|
|
|
|
|
| -void Object::SetPointerInInternalField(int index, void* value) {
|
| - SetInternalField(index, External::New(value));
|
| +void* External::QuickUnwrap(Handle<v8::Value> wrapper) {
|
| + typedef internal::Object O;
|
| + O* obj = *reinterpret_cast<O**>(const_cast<v8::Value*>(*wrapper));
|
| + return internal::Internals::GetExternalPointer(obj);
|
| }
|
|
|
|
|
| -void* Object::GetAlignedPointerFromInternalField(int index) {
|
| -#ifndef V8_ENABLE_CHECKS
|
| +void* Object::GetPointerFromInternalField(int index) {
|
| typedef internal::Object O;
|
| typedef internal::Internals I;
|
| +
|
| O* obj = *reinterpret_cast<O**>(this);
|
| - // Fast path: 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.
|
| +
|
| 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 + (internal::kApiPointerSize * index);
|
| - return I::ReadField<void*>(obj, offset);
|
| + O* value = I::ReadField<O*>(obj, offset);
|
| + return I::GetExternalPointer(value);
|
| }
|
| -#endif
|
| - return SlowGetAlignedPointerFromInternalField(index);
|
| +
|
| + return SlowGetPointerFromInternalField(index);
|
| }
|
|
|
|
|
| @@ -4679,16 +4666,6 @@ Function* Function::Cast(v8::Value* value) {
|
| }
|
|
|
|
|
| -Local<Value> External::Wrap(void* value) {
|
| - return External::New(value);
|
| -}
|
| -
|
| -
|
| -void* External::Unwrap(Handle<v8::Value> obj) {
|
| - return External::Cast(*obj)->Value();
|
| -}
|
| -
|
| -
|
| External* External::Cast(v8::Value* value) {
|
| #ifdef V8_ENABLE_CHECKS
|
| CheckCast(value);
|
| @@ -4765,37 +4742,6 @@ void* Isolate::GetData() {
|
| }
|
|
|
|
|
| -Local<Value> Context::GetData() {
|
| - return GetEmbedderData(0);
|
| -}
|
| -
|
| -void Context::SetData(Handle<Value> data) {
|
| - SetEmbedderData(0, data);
|
| -}
|
| -
|
| -
|
| -Local<Value> Context::GetEmbedderData(int index) {
|
| -#ifndef V8_ENABLE_CHECKS
|
| - typedef internal::Object O;
|
| - typedef internal::Internals I;
|
| - O** result = HandleScope::CreateHandle(I::ReadEmbedderData<O*>(this, index));
|
| - return Local<Value>(reinterpret_cast<Value*>(result));
|
| -#else
|
| - return SlowGetEmbedderData(index);
|
| -#endif
|
| -}
|
| -
|
| -
|
| -void* Context::GetAlignedPointerFromEmbedderData(int index) {
|
| -#ifndef V8_ENABLE_CHECKS
|
| - typedef internal::Internals I;
|
| - return I::ReadEmbedderData<void*>(this, index);
|
| -#else
|
| - return SlowGetAlignedPointerFromEmbedderData(index);
|
| -#endif
|
| -}
|
| -
|
| -
|
| /**
|
| * \example shell.cc
|
| * A simple shell that takes a list of expressions on the
|
|
|