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 |