OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 1861 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1872 }; | 1872 }; |
1873 | 1873 |
1874 | 1874 |
1875 /** | 1875 /** |
1876 * A JavaScript number value (ECMA-262, 4.3.20) | 1876 * A JavaScript number value (ECMA-262, 4.3.20) |
1877 */ | 1877 */ |
1878 class V8EXPORT Number : public Primitive { | 1878 class V8EXPORT Number : public Primitive { |
1879 public: | 1879 public: |
1880 double Value() const; | 1880 double Value() const; |
1881 static Local<Number> New(double value); | 1881 static Local<Number> New(double value); |
| 1882 static Local<Number> New(Isolate* isolate, double value); |
1882 V8_INLINE(static Number* Cast(v8::Value* obj)); | 1883 V8_INLINE(static Number* Cast(v8::Value* obj)); |
1883 private: | 1884 private: |
1884 Number(); | 1885 Number(); |
1885 static void CheckCast(v8::Value* obj); | 1886 static void CheckCast(v8::Value* obj); |
1886 }; | 1887 }; |
1887 | 1888 |
1888 | 1889 |
1889 /** | 1890 /** |
1890 * A JavaScript value representing a signed integer. | 1891 * A JavaScript value representing a signed integer. |
1891 */ | 1892 */ |
(...skipping 841 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2733 }; | 2734 }; |
2734 | 2735 |
2735 | 2736 |
2736 template<typename T> | 2737 template<typename T> |
2737 class V8EXPORT ReturnValue { | 2738 class V8EXPORT ReturnValue { |
2738 public: | 2739 public: |
2739 V8_INLINE(explicit ReturnValue(internal::Object** slot)); | 2740 V8_INLINE(explicit ReturnValue(internal::Object** slot)); |
2740 // Handle setters | 2741 // Handle setters |
2741 V8_INLINE(void Set(const Persistent<T>& handle)); | 2742 V8_INLINE(void Set(const Persistent<T>& handle)); |
2742 V8_INLINE(void Set(const Handle<T> handle)); | 2743 V8_INLINE(void Set(const Handle<T> handle)); |
2743 // TODO(dcarney): implement | |
2744 // Fast primitive setters | 2744 // Fast primitive setters |
2745 // V8_INLINE(void Set(Isolate* isolate, bool)); | 2745 V8_INLINE(void Set(Isolate* isolate, bool value)); |
2746 // V8_INLINE(void Set(Isolate* isolate, float i)); | 2746 V8_INLINE(void Set(Isolate* isolate, double i)); |
2747 // V8_INLINE(void Set(Isolate* isolate, double i)); | 2747 V8_INLINE(void Set(Isolate* isolate, int32_t i)); |
2748 // V8_INLINE(void Set(Isolate* isolate, int32_t i)); | 2748 V8_INLINE(void Set(Isolate* isolate, uint32_t i)); |
2749 // V8_INLINE(void Set(Isolate* isolate, uint32_t i)); | |
2750 // Fast JS primitive setters | 2749 // Fast JS primitive setters |
2751 // V8_INLINE(void SetNull(Isolate* isolate)); | 2750 V8_INLINE(void SetNull(Isolate* isolate)); |
2752 // V8_INLINE(void SetUndefined(Isolate* isolate)); | 2751 V8_INLINE(void SetUndefined(Isolate* isolate)); |
2753 private: | 2752 private: |
2754 internal::Object** value_; | 2753 internal::Object** value_; |
2755 }; | 2754 }; |
2756 | 2755 |
2757 | 2756 |
2758 /** | 2757 /** |
2759 * The argument information given to function call callbacks. This | 2758 * The argument information given to function call callbacks. This |
2760 * class provides access to information about the context of the call, | 2759 * class provides access to information about the context of the call, |
2761 * including the receiver, the number and values of arguments, and | 2760 * including the receiver, the number and values of arguments, and |
2762 * the holder of the function. | 2761 * the holder of the function. |
(...skipping 2371 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5134 const int kHeapObjectTagSize = 2; | 5133 const int kHeapObjectTagSize = 2; |
5135 const intptr_t kHeapObjectTagMask = (1 << kHeapObjectTagSize) - 1; | 5134 const intptr_t kHeapObjectTagMask = (1 << kHeapObjectTagSize) - 1; |
5136 | 5135 |
5137 // Tag information for Smi. | 5136 // Tag information for Smi. |
5138 const int kSmiTag = 0; | 5137 const int kSmiTag = 0; |
5139 const int kSmiTagSize = 1; | 5138 const int kSmiTagSize = 1; |
5140 const intptr_t kSmiTagMask = (1 << kSmiTagSize) - 1; | 5139 const intptr_t kSmiTagMask = (1 << kSmiTagSize) - 1; |
5141 | 5140 |
5142 template <size_t ptr_size> struct SmiTagging; | 5141 template <size_t ptr_size> struct SmiTagging; |
5143 | 5142 |
| 5143 template<int kSmiShiftSize> |
| 5144 V8_INLINE(internal::Object* IntToSmi(int value)) { |
| 5145 int smi_shift_bits = kSmiTagSize + kSmiShiftSize; |
| 5146 intptr_t tagged_value = |
| 5147 (static_cast<intptr_t>(value) << smi_shift_bits) | kSmiTag; |
| 5148 return reinterpret_cast<internal::Object*>(tagged_value); |
| 5149 } |
| 5150 |
5144 // Smi constants for 32-bit systems. | 5151 // Smi constants for 32-bit systems. |
5145 template <> struct SmiTagging<4> { | 5152 template <> struct SmiTagging<4> { |
5146 static const int kSmiShiftSize = 0; | 5153 static const int kSmiShiftSize = 0; |
5147 static const int kSmiValueSize = 31; | 5154 static const int kSmiValueSize = 31; |
5148 V8_INLINE(static int SmiToInt(internal::Object* value)) { | 5155 V8_INLINE(static int SmiToInt(internal::Object* value)) { |
5149 int shift_bits = kSmiTagSize + kSmiShiftSize; | 5156 int shift_bits = kSmiTagSize + kSmiShiftSize; |
5150 // Throw away top 32 bits and shift down (requires >> to be sign extending). | 5157 // Throw away top 32 bits and shift down (requires >> to be sign extending). |
5151 return static_cast<int>(reinterpret_cast<intptr_t>(value)) >> shift_bits; | 5158 return static_cast<int>(reinterpret_cast<intptr_t>(value)) >> shift_bits; |
5152 } | 5159 } |
| 5160 V8_INLINE(static internal::Object* IntToSmi(int value)) { |
| 5161 return internal::IntToSmi<kSmiShiftSize>(value); |
| 5162 } |
| 5163 V8_INLINE(static bool IsValidSmi(intptr_t value)) { |
| 5164 // To be representable as an tagged small integer, the two |
| 5165 // most-significant bits of 'value' must be either 00 or 11 due to |
| 5166 // sign-extension. To check this we add 01 to the two |
| 5167 // most-significant bits, and check if the most-significant bit is 0 |
| 5168 // |
| 5169 // CAUTION: The original code below: |
| 5170 // bool result = ((value + 0x40000000) & 0x80000000) == 0; |
| 5171 // may lead to incorrect results according to the C language spec, and |
| 5172 // in fact doesn't work correctly with gcc4.1.1 in some cases: The |
| 5173 // compiler may produce undefined results in case of signed integer |
| 5174 // overflow. The computation must be done w/ unsigned ints. |
| 5175 return static_cast<uintptr_t>(value + 0x40000000U) < 0x80000000U; |
| 5176 } |
5153 }; | 5177 }; |
5154 | 5178 |
5155 // Smi constants for 64-bit systems. | 5179 // Smi constants for 64-bit systems. |
5156 template <> struct SmiTagging<8> { | 5180 template <> struct SmiTagging<8> { |
5157 static const int kSmiShiftSize = 31; | 5181 static const int kSmiShiftSize = 31; |
5158 static const int kSmiValueSize = 32; | 5182 static const int kSmiValueSize = 32; |
5159 V8_INLINE(static int SmiToInt(internal::Object* value)) { | 5183 V8_INLINE(static int SmiToInt(internal::Object* value)) { |
5160 int shift_bits = kSmiTagSize + kSmiShiftSize; | 5184 int shift_bits = kSmiTagSize + kSmiShiftSize; |
5161 // Shift down and throw away top 32 bits. | 5185 // Shift down and throw away top 32 bits. |
5162 return static_cast<int>(reinterpret_cast<intptr_t>(value) >> shift_bits); | 5186 return static_cast<int>(reinterpret_cast<intptr_t>(value) >> shift_bits); |
5163 } | 5187 } |
| 5188 V8_INLINE(static internal::Object* IntToSmi(int value)) { |
| 5189 return internal::IntToSmi<kSmiShiftSize>(value); |
| 5190 } |
| 5191 V8_INLINE(static bool IsValidSmi(intptr_t value)) { |
| 5192 // To be representable as a long smi, the value must be a 32-bit integer. |
| 5193 return (value == static_cast<int32_t>(value)); |
| 5194 } |
5164 }; | 5195 }; |
5165 | 5196 |
5166 typedef SmiTagging<kApiPointerSize> PlatformSmiTagging; | 5197 typedef SmiTagging<kApiPointerSize> PlatformSmiTagging; |
5167 const int kSmiShiftSize = PlatformSmiTagging::kSmiShiftSize; | 5198 const int kSmiShiftSize = PlatformSmiTagging::kSmiShiftSize; |
5168 const int kSmiValueSize = PlatformSmiTagging::kSmiValueSize; | 5199 const int kSmiValueSize = PlatformSmiTagging::kSmiValueSize; |
5169 | 5200 |
5170 /** | 5201 /** |
5171 * This class exports constants and functionality from within v8 that | 5202 * This class exports constants and functionality from within v8 that |
5172 * is necessary to implement inline functions in the v8 api. Don't | 5203 * is necessary to implement inline functions in the v8 api. Don't |
5173 * depend on functions and constants defined here. | 5204 * depend on functions and constants defined here. |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5218 | 5249 |
5219 V8_INLINE(static bool HasHeapObjectTag(internal::Object* value)) { | 5250 V8_INLINE(static bool HasHeapObjectTag(internal::Object* value)) { |
5220 return ((reinterpret_cast<intptr_t>(value) & kHeapObjectTagMask) == | 5251 return ((reinterpret_cast<intptr_t>(value) & kHeapObjectTagMask) == |
5221 kHeapObjectTag); | 5252 kHeapObjectTag); |
5222 } | 5253 } |
5223 | 5254 |
5224 V8_INLINE(static int SmiValue(internal::Object* value)) { | 5255 V8_INLINE(static int SmiValue(internal::Object* value)) { |
5225 return PlatformSmiTagging::SmiToInt(value); | 5256 return PlatformSmiTagging::SmiToInt(value); |
5226 } | 5257 } |
5227 | 5258 |
| 5259 V8_INLINE(static internal::Object* IntToSmi(int value)) { |
| 5260 return PlatformSmiTagging::IntToSmi(value); |
| 5261 } |
| 5262 |
| 5263 V8_INLINE(static bool IsValidSmi(intptr_t value)) { |
| 5264 return PlatformSmiTagging::IsValidSmi(value); |
| 5265 } |
| 5266 |
5228 V8_INLINE(static int GetInstanceType(internal::Object* obj)) { | 5267 V8_INLINE(static int GetInstanceType(internal::Object* obj)) { |
5229 typedef internal::Object O; | 5268 typedef internal::Object O; |
5230 O* map = ReadField<O*>(obj, kHeapObjectMapOffset); | 5269 O* map = ReadField<O*>(obj, kHeapObjectMapOffset); |
5231 return ReadField<uint8_t>(map, kMapInstanceTypeOffset); | 5270 return ReadField<uint8_t>(map, kMapInstanceTypeOffset); |
5232 } | 5271 } |
5233 | 5272 |
5234 V8_INLINE(static int GetOddballKind(internal::Object* obj)) { | 5273 V8_INLINE(static int GetOddballKind(internal::Object* obj)) { |
5235 typedef internal::Object O; | 5274 typedef internal::Object O; |
5236 return SmiValue(ReadField<O*>(obj, kOddballKindOffset)); | 5275 return SmiValue(ReadField<O*>(obj, kOddballKindOffset)); |
5237 } | 5276 } |
(...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5593 template <class T> | 5632 template <class T> |
5594 uint16_t Persistent<T>::WrapperClassId(Isolate* isolate) const { | 5633 uint16_t Persistent<T>::WrapperClassId(Isolate* isolate) const { |
5595 typedef internal::Internals I; | 5634 typedef internal::Internals I; |
5596 if (this->IsEmpty()) return 0; | 5635 if (this->IsEmpty()) return 0; |
5597 if (!I::IsInitialized(isolate)) return 0; | 5636 if (!I::IsInitialized(isolate)) return 0; |
5598 internal::Object** obj = reinterpret_cast<internal::Object**>(this->val_); | 5637 internal::Object** obj = reinterpret_cast<internal::Object**>(this->val_); |
5599 uint8_t* addr = reinterpret_cast<uint8_t*>(obj) + I::kNodeClassIdOffset; | 5638 uint8_t* addr = reinterpret_cast<uint8_t*>(obj) + I::kNodeClassIdOffset; |
5600 return *reinterpret_cast<uint16_t*>(addr); | 5639 return *reinterpret_cast<uint16_t*>(addr); |
5601 } | 5640 } |
5602 | 5641 |
| 5642 |
5603 template<typename T> | 5643 template<typename T> |
5604 ReturnValue<T>::ReturnValue(internal::Object** slot) : value_(slot) {} | 5644 ReturnValue<T>::ReturnValue(internal::Object** slot) : value_(slot) {} |
5605 | 5645 |
5606 template<typename T> | 5646 template<typename T> |
5607 void ReturnValue<T>::Set(const Persistent<T>& handle) { | 5647 void ReturnValue<T>::Set(const Persistent<T>& handle) { |
5608 *value_ = *reinterpret_cast<internal::Object**>(*handle); | 5648 *value_ = *reinterpret_cast<internal::Object**>(*handle); |
5609 } | 5649 } |
5610 | 5650 |
5611 template<typename T> | 5651 template<typename T> |
5612 void ReturnValue<T>::Set(const Handle<T> handle) { | 5652 void ReturnValue<T>::Set(const Handle<T> handle) { |
5613 *value_ = *reinterpret_cast<internal::Object**>(*handle); | 5653 *value_ = *reinterpret_cast<internal::Object**>(*handle); |
5614 } | 5654 } |
5615 | 5655 |
5616 template<typename T> | 5656 template<typename T> |
| 5657 void ReturnValue<T>::Set(Isolate* isolate, double i) { |
| 5658 Set(Number::New(isolate, i)); |
| 5659 } |
| 5660 |
| 5661 template<typename T> |
| 5662 void ReturnValue<T>::Set(Isolate* isolate, int32_t i) { |
| 5663 typedef internal::Internals I; |
| 5664 if (V8_LIKELY(I::IsValidSmi(i))) { |
| 5665 *value_ = I::IntToSmi(i); |
| 5666 return; |
| 5667 } |
| 5668 Set(Integer::New(i, isolate)); |
| 5669 } |
| 5670 |
| 5671 template<typename T> |
| 5672 void ReturnValue<T>::Set(Isolate* isolate, uint32_t i) { |
| 5673 typedef internal::Internals I; |
| 5674 if (V8_LIKELY(I::IsValidSmi(i))) { |
| 5675 *value_ = I::IntToSmi(i); |
| 5676 return; |
| 5677 } |
| 5678 Set(Integer::NewFromUnsigned(i, isolate)); |
| 5679 } |
| 5680 |
| 5681 template<typename T> |
| 5682 void ReturnValue<T>::Set(Isolate* isolate, bool value) { |
| 5683 typedef internal::Internals I; |
| 5684 *value_ = *I::GetRoot( |
| 5685 isolate, value ? I::kTrueValueRootIndex : I::kFalseValueRootIndex); |
| 5686 } |
| 5687 |
| 5688 template<typename T> |
| 5689 void ReturnValue<T>::SetNull(Isolate* isolate) { |
| 5690 typedef internal::Internals I; |
| 5691 *value_ = *I::GetRoot(isolate, I::kNullValueRootIndex); |
| 5692 } |
| 5693 |
| 5694 template<typename T> |
| 5695 void ReturnValue<T>::SetUndefined(Isolate* isolate) { |
| 5696 typedef internal::Internals I; |
| 5697 *value_ = *I::GetRoot(isolate, I::kUndefinedValueRootIndex); |
| 5698 } |
| 5699 |
| 5700 |
| 5701 template<typename T> |
5617 FunctionCallbackInfo<T>::FunctionCallbackInfo(internal::Object** implicit_args, | 5702 FunctionCallbackInfo<T>::FunctionCallbackInfo(internal::Object** implicit_args, |
5618 internal::Object** values, | 5703 internal::Object** values, |
5619 int length, | 5704 int length, |
5620 bool is_construct_call) | 5705 bool is_construct_call) |
5621 : implicit_args_(implicit_args), | 5706 : implicit_args_(implicit_args), |
5622 values_(values), | 5707 values_(values), |
5623 length_(length), | 5708 length_(length), |
5624 is_construct_call_(is_construct_call) { } | 5709 is_construct_call_(is_construct_call) { } |
5625 | 5710 |
5626 | 5711 |
(...skipping 558 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6185 | 6270 |
6186 | 6271 |
6187 } // namespace v8 | 6272 } // namespace v8 |
6188 | 6273 |
6189 | 6274 |
6190 #undef V8EXPORT | 6275 #undef V8EXPORT |
6191 #undef TYPE_CHECK | 6276 #undef TYPE_CHECK |
6192 | 6277 |
6193 | 6278 |
6194 #endif // V8_H_ | 6279 #endif // V8_H_ |
OLD | NEW |