| OLD | NEW |
| 1 // Copyright 2007-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2007-2009 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 1260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1271 * the backing store is preserved while V8 has a reference. | 1271 * the backing store is preserved while V8 has a reference. |
| 1272 */ | 1272 */ |
| 1273 void SetIndexedPropertiesToPixelData(uint8_t* data, int length); | 1273 void SetIndexedPropertiesToPixelData(uint8_t* data, int length); |
| 1274 | 1274 |
| 1275 static Local<Object> New(); | 1275 static Local<Object> New(); |
| 1276 static inline Object* Cast(Value* obj); | 1276 static inline Object* Cast(Value* obj); |
| 1277 private: | 1277 private: |
| 1278 Object(); | 1278 Object(); |
| 1279 static void CheckCast(Value* obj); | 1279 static void CheckCast(Value* obj); |
| 1280 Local<Value> CheckedGetInternalField(int index); | 1280 Local<Value> CheckedGetInternalField(int index); |
| 1281 void* SlowGetPointerFromInternalField(int index); |
| 1281 | 1282 |
| 1282 /** | 1283 /** |
| 1283 * If quick access to the internal field is possible this method | 1284 * If quick access to the internal field is possible this method |
| 1284 * returns the value. Otherwise an empty handle is returned. | 1285 * returns the value. Otherwise an empty handle is returned. |
| 1285 */ | 1286 */ |
| 1286 inline Local<Value> UncheckedGetInternalField(int index); | 1287 inline Local<Value> UncheckedGetInternalField(int index); |
| 1287 }; | 1288 }; |
| 1288 | 1289 |
| 1289 | 1290 |
| 1290 /** | 1291 /** |
| (...skipping 1455 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2746 | 2747 |
| 2747 // These values match non-compiler-dependent values defined within | 2748 // These values match non-compiler-dependent values defined within |
| 2748 // the implementation of v8. | 2749 // the implementation of v8. |
| 2749 static const int kHeapObjectMapOffset = 0; | 2750 static const int kHeapObjectMapOffset = 0; |
| 2750 static const int kMapInstanceTypeOffset = sizeof(void*) + sizeof(int); | 2751 static const int kMapInstanceTypeOffset = sizeof(void*) + sizeof(int); |
| 2751 static const int kStringResourceOffset = 2 * sizeof(void*); | 2752 static const int kStringResourceOffset = 2 * sizeof(void*); |
| 2752 static const int kProxyProxyOffset = sizeof(void*); | 2753 static const int kProxyProxyOffset = sizeof(void*); |
| 2753 static const int kJSObjectHeaderSize = 3 * sizeof(void*); | 2754 static const int kJSObjectHeaderSize = 3 * sizeof(void*); |
| 2754 static const int kFullStringRepresentationMask = 0x07; | 2755 static const int kFullStringRepresentationMask = 0x07; |
| 2755 static const int kExternalTwoByteRepresentationTag = 0x03; | 2756 static const int kExternalTwoByteRepresentationTag = 0x03; |
| 2756 static const int kAlignedPointerShift = 2; | |
| 2757 | 2757 |
| 2758 // These constants are compiler dependent so their values must be | 2758 // These constants are compiler dependent so their values must be |
| 2759 // defined within the implementation. | 2759 // defined within the implementation. |
| 2760 V8EXPORT static int kJSObjectType; | 2760 V8EXPORT static int kJSObjectType; |
| 2761 V8EXPORT static int kFirstNonstringType; | 2761 V8EXPORT static int kFirstNonstringType; |
| 2762 V8EXPORT static int kProxyType; | 2762 V8EXPORT static int kProxyType; |
| 2763 | 2763 |
| 2764 static inline bool HasHeapObjectTag(internal::Object* value) { | 2764 static inline bool HasHeapObjectTag(internal::Object* value) { |
| 2765 return ((reinterpret_cast<intptr_t>(value) & kHeapObjectTagMask) == | 2765 return ((reinterpret_cast<intptr_t>(value) & kHeapObjectTagMask) == |
| 2766 kHeapObjectTag); | 2766 kHeapObjectTag); |
| 2767 } | 2767 } |
| 2768 | 2768 |
| 2769 static inline bool HasSmiTag(internal::Object* value) { | 2769 static inline bool HasSmiTag(internal::Object* value) { |
| 2770 return ((reinterpret_cast<intptr_t>(value) & kSmiTagMask) == kSmiTag); | 2770 return ((reinterpret_cast<intptr_t>(value) & kSmiTagMask) == kSmiTag); |
| 2771 } | 2771 } |
| 2772 | 2772 |
| 2773 static inline int SmiValue(internal::Object* value) { | 2773 static inline int SmiValue(internal::Object* value) { |
| 2774 #ifdef V8_TARGET_ARCH_X64 | 2774 #ifdef V8_TARGET_ARCH_X64 |
| 2775 int shift_bits = kSmiTagSize + kSmiShiftSize; | 2775 int shift_bits = kSmiTagSize + kSmiShiftSize; |
| 2776 // Shift down and throw away top 32 bits. | 2776 // Shift down and throw away top 32 bits. |
| 2777 return static_cast<int>(reinterpret_cast<intptr_t>(value) >> shift_bits); | 2777 return static_cast<int>(reinterpret_cast<intptr_t>(value) >> shift_bits); |
| 2778 #else | 2778 #else |
| 2779 int shift_bits = kSmiTagSize + kSmiShiftSize; | 2779 int shift_bits = kSmiTagSize + kSmiShiftSize; |
| 2780 // Throw away top 32 bits and shift down (requires >> to be sign extending). | 2780 // Throw away top 32 bits and shift down (requires >> to be sign extending). |
| 2781 return static_cast<int>(reinterpret_cast<intptr_t>(value)) >> shift_bits; | 2781 return static_cast<int>(reinterpret_cast<intptr_t>(value)) >> shift_bits; |
| 2782 #endif | 2782 #endif |
| 2783 } | 2783 } |
| 2784 | 2784 |
| 2785 static inline int GetInstanceType(internal::Object* obj) { |
| 2786 typedef internal::Object O; |
| 2787 O* map = ReadField<O*>(obj, kHeapObjectMapOffset); |
| 2788 return ReadField<uint8_t>(map, kMapInstanceTypeOffset); |
| 2789 } |
| 2790 |
| 2791 static inline void* GetExternalPointer(internal::Object* obj) { |
| 2792 if (HasSmiTag(obj)) { |
| 2793 return obj; |
| 2794 } else if (GetInstanceType(obj) == kProxyType) { |
| 2795 return ReadField<void*>(obj, kProxyProxyOffset); |
| 2796 } else { |
| 2797 return NULL; |
| 2798 } |
| 2799 } |
| 2800 |
| 2785 static inline bool IsExternalTwoByteString(int instance_type) { | 2801 static inline bool IsExternalTwoByteString(int instance_type) { |
| 2786 int representation = (instance_type & kFullStringRepresentationMask); | 2802 int representation = (instance_type & kFullStringRepresentationMask); |
| 2787 return representation == kExternalTwoByteRepresentationTag; | 2803 return representation == kExternalTwoByteRepresentationTag; |
| 2788 } | 2804 } |
| 2789 | 2805 |
| 2790 template <typename T> | 2806 template <typename T> |
| 2791 static inline T ReadField(Object* ptr, int offset) { | 2807 static inline T ReadField(Object* ptr, int offset) { |
| 2792 uint8_t* addr = reinterpret_cast<uint8_t*>(ptr) + offset - kHeapObjectTag; | 2808 uint8_t* addr = reinterpret_cast<uint8_t*>(ptr) + offset - kHeapObjectTag; |
| 2793 return *reinterpret_cast<T*>(addr); | 2809 return *reinterpret_cast<T*>(addr); |
| 2794 } | 2810 } |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2932 if (!quick_result.IsEmpty()) return quick_result; | 2948 if (!quick_result.IsEmpty()) return quick_result; |
| 2933 #endif | 2949 #endif |
| 2934 return CheckedGetInternalField(index); | 2950 return CheckedGetInternalField(index); |
| 2935 } | 2951 } |
| 2936 | 2952 |
| 2937 | 2953 |
| 2938 Local<Value> Object::UncheckedGetInternalField(int index) { | 2954 Local<Value> Object::UncheckedGetInternalField(int index) { |
| 2939 typedef internal::Object O; | 2955 typedef internal::Object O; |
| 2940 typedef internal::Internals I; | 2956 typedef internal::Internals I; |
| 2941 O* obj = *reinterpret_cast<O**>(this); | 2957 O* obj = *reinterpret_cast<O**>(this); |
| 2942 O* map = I::ReadField<O*>(obj, I::kHeapObjectMapOffset); | 2958 if (I::GetInstanceType(obj) == I::kJSObjectType) { |
| 2943 int instance_type = I::ReadField<uint8_t>(map, I::kMapInstanceTypeOffset); | |
| 2944 if (instance_type == I::kJSObjectType) { | |
| 2945 // If the object is a plain JSObject, which is the common case, | 2959 // If the object is a plain JSObject, which is the common case, |
| 2946 // we know where to find the internal fields and can return the | 2960 // we know where to find the internal fields and can return the |
| 2947 // value directly. | 2961 // value directly. |
| 2948 int offset = I::kJSObjectHeaderSize + (sizeof(void*) * index); | 2962 int offset = I::kJSObjectHeaderSize + (sizeof(void*) * index); |
| 2949 O* value = I::ReadField<O*>(obj, offset); | 2963 O* value = I::ReadField<O*>(obj, offset); |
| 2950 O** result = HandleScope::CreateHandle(value); | 2964 O** result = HandleScope::CreateHandle(value); |
| 2951 return Local<Value>(reinterpret_cast<Value*>(result)); | 2965 return Local<Value>(reinterpret_cast<Value*>(result)); |
| 2952 } else { | 2966 } else { |
| 2953 return Local<Value>(); | 2967 return Local<Value>(); |
| 2954 } | 2968 } |
| 2955 } | 2969 } |
| 2956 | 2970 |
| 2957 | 2971 |
| 2958 void* External::Unwrap(Handle<v8::Value> obj) { | 2972 void* External::Unwrap(Handle<v8::Value> obj) { |
| 2959 #ifdef V8_ENABLE_CHECKS | 2973 #ifdef V8_ENABLE_CHECKS |
| 2960 return FullUnwrap(obj); | 2974 return FullUnwrap(obj); |
| 2961 #else | 2975 #else |
| 2962 return QuickUnwrap(obj); | 2976 return QuickUnwrap(obj); |
| 2963 #endif | 2977 #endif |
| 2964 } | 2978 } |
| 2965 | 2979 |
| 2966 | 2980 |
| 2967 void* External::QuickUnwrap(Handle<v8::Value> wrapper) { | 2981 void* External::QuickUnwrap(Handle<v8::Value> wrapper) { |
| 2968 typedef internal::Object O; | 2982 typedef internal::Object O; |
| 2969 typedef internal::Internals I; | |
| 2970 O* obj = *reinterpret_cast<O**>(const_cast<v8::Value*>(*wrapper)); | 2983 O* obj = *reinterpret_cast<O**>(const_cast<v8::Value*>(*wrapper)); |
| 2971 if (I::HasSmiTag(obj)) { | 2984 return internal::Internals::GetExternalPointer(obj); |
| 2972 int value = I::SmiValue(obj) << I::kAlignedPointerShift; | |
| 2973 return reinterpret_cast<void*>(value); | |
| 2974 } else { | |
| 2975 O* map = I::ReadField<O*>(obj, I::kHeapObjectMapOffset); | |
| 2976 int instance_type = I::ReadField<uint8_t>(map, I::kMapInstanceTypeOffset); | |
| 2977 if (instance_type == I::kProxyType) { | |
| 2978 return I::ReadField<void*>(obj, I::kProxyProxyOffset); | |
| 2979 } else { | |
| 2980 return NULL; | |
| 2981 } | |
| 2982 } | |
| 2983 } | 2985 } |
| 2984 | 2986 |
| 2985 | 2987 |
| 2986 void* Object::GetPointerFromInternalField(int index) { | 2988 void* Object::GetPointerFromInternalField(int index) { |
| 2987 return External::Unwrap(GetInternalField(index)); | 2989 typedef internal::Object O; |
| 2990 typedef internal::Internals I; |
| 2991 |
| 2992 O* obj = *reinterpret_cast<O**>(this); |
| 2993 |
| 2994 if (I::GetInstanceType(obj) == I::kJSObjectType) { |
| 2995 // If the object is a plain JSObject, which is the common case, |
| 2996 // we know where to find the internal fields and can return the |
| 2997 // value directly. |
| 2998 int offset = I::kJSObjectHeaderSize + (sizeof(void*) * index); |
| 2999 O* value = I::ReadField<O*>(obj, offset); |
| 3000 return I::GetExternalPointer(value); |
| 3001 } |
| 3002 |
| 3003 return SlowGetPointerFromInternalField(index); |
| 2988 } | 3004 } |
| 2989 | 3005 |
| 2990 | 3006 |
| 2991 String* String::Cast(v8::Value* value) { | 3007 String* String::Cast(v8::Value* value) { |
| 2992 #ifdef V8_ENABLE_CHECKS | 3008 #ifdef V8_ENABLE_CHECKS |
| 2993 CheckCast(value); | 3009 CheckCast(value); |
| 2994 #endif | 3010 #endif |
| 2995 return static_cast<String*>(value); | 3011 return static_cast<String*>(value); |
| 2996 } | 3012 } |
| 2997 | 3013 |
| 2998 | 3014 |
| 2999 String::ExternalStringResource* String::GetExternalStringResource() const { | 3015 String::ExternalStringResource* String::GetExternalStringResource() const { |
| 3000 typedef internal::Object O; | 3016 typedef internal::Object O; |
| 3001 typedef internal::Internals I; | 3017 typedef internal::Internals I; |
| 3002 O* obj = *reinterpret_cast<O**>(const_cast<String*>(this)); | 3018 O* obj = *reinterpret_cast<O**>(const_cast<String*>(this)); |
| 3003 O* map = I::ReadField<O*>(obj, I::kHeapObjectMapOffset); | |
| 3004 int instance_type = I::ReadField<uint8_t>(map, I::kMapInstanceTypeOffset); | |
| 3005 String::ExternalStringResource* result; | 3019 String::ExternalStringResource* result; |
| 3006 if (I::IsExternalTwoByteString(instance_type)) { | 3020 if (I::IsExternalTwoByteString(I::GetInstanceType(obj))) { |
| 3007 void* value = I::ReadField<void*>(obj, I::kStringResourceOffset); | 3021 void* value = I::ReadField<void*>(obj, I::kStringResourceOffset); |
| 3008 result = reinterpret_cast<String::ExternalStringResource*>(value); | 3022 result = reinterpret_cast<String::ExternalStringResource*>(value); |
| 3009 } else { | 3023 } else { |
| 3010 result = NULL; | 3024 result = NULL; |
| 3011 } | 3025 } |
| 3012 #ifdef V8_ENABLE_CHECKS | 3026 #ifdef V8_ENABLE_CHECKS |
| 3013 VerifyExternalStringResource(result); | 3027 VerifyExternalStringResource(result); |
| 3014 #endif | 3028 #endif |
| 3015 return result; | 3029 return result; |
| 3016 } | 3030 } |
| 3017 | 3031 |
| 3018 | 3032 |
| 3019 bool Value::IsString() const { | 3033 bool Value::IsString() const { |
| 3020 #ifdef V8_ENABLE_CHECKS | 3034 #ifdef V8_ENABLE_CHECKS |
| 3021 return FullIsString(); | 3035 return FullIsString(); |
| 3022 #else | 3036 #else |
| 3023 return QuickIsString(); | 3037 return QuickIsString(); |
| 3024 #endif | 3038 #endif |
| 3025 } | 3039 } |
| 3026 | 3040 |
| 3027 bool Value::QuickIsString() const { | 3041 bool Value::QuickIsString() const { |
| 3028 typedef internal::Object O; | 3042 typedef internal::Object O; |
| 3029 typedef internal::Internals I; | 3043 typedef internal::Internals I; |
| 3030 O* obj = *reinterpret_cast<O**>(const_cast<Value*>(this)); | 3044 O* obj = *reinterpret_cast<O**>(const_cast<Value*>(this)); |
| 3031 if (!I::HasHeapObjectTag(obj)) return false; | 3045 if (!I::HasHeapObjectTag(obj)) return false; |
| 3032 O* map = I::ReadField<O*>(obj, I::kHeapObjectMapOffset); | 3046 return (I::GetInstanceType(obj) < I::kFirstNonstringType); |
| 3033 int instance_type = I::ReadField<uint8_t>(map, I::kMapInstanceTypeOffset); | |
| 3034 return (instance_type < I::kFirstNonstringType); | |
| 3035 } | 3047 } |
| 3036 | 3048 |
| 3037 | 3049 |
| 3038 Number* Number::Cast(v8::Value* value) { | 3050 Number* Number::Cast(v8::Value* value) { |
| 3039 #ifdef V8_ENABLE_CHECKS | 3051 #ifdef V8_ENABLE_CHECKS |
| 3040 CheckCast(value); | 3052 CheckCast(value); |
| 3041 #endif | 3053 #endif |
| 3042 return static_cast<Number*>(value); | 3054 return static_cast<Number*>(value); |
| 3043 } | 3055 } |
| 3044 | 3056 |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3129 | 3141 |
| 3130 } // namespace v8 | 3142 } // namespace v8 |
| 3131 | 3143 |
| 3132 | 3144 |
| 3133 #undef V8EXPORT | 3145 #undef V8EXPORT |
| 3134 #undef V8EXPORT_INLINE | 3146 #undef V8EXPORT_INLINE |
| 3135 #undef TYPE_CHECK | 3147 #undef TYPE_CHECK |
| 3136 | 3148 |
| 3137 | 3149 |
| 3138 #endif // V8_H_ | 3150 #endif // V8_H_ |
| OLD | NEW |