OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/api.h" | 5 #include "src/api.h" |
6 | 6 |
7 #include <string.h> // For memcpy, strlen. | 7 #include <string.h> // For memcpy, strlen. |
8 #ifdef V8_USE_ADDRESS_SANITIZER | 8 #ifdef V8_USE_ADDRESS_SANITIZER |
9 #include <sanitizer/asan_interface.h> | 9 #include <sanitizer/asan_interface.h> |
10 #endif // V8_USE_ADDRESS_SANITIZER | 10 #endif // V8_USE_ADDRESS_SANITIZER |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
89 | 89 |
90 #define EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, value) \ | 90 #define EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, value) \ |
91 EXCEPTION_BAILOUT_CHECK_GENERIC( \ | 91 EXCEPTION_BAILOUT_CHECK_GENERIC( \ |
92 isolate, value, isolate->FireCallCompletedCallback();) | 92 isolate, value, isolate->FireCallCompletedCallback();) |
93 | 93 |
94 | 94 |
95 #define EXCEPTION_BAILOUT_CHECK(isolate, value) \ | 95 #define EXCEPTION_BAILOUT_CHECK(isolate, value) \ |
96 EXCEPTION_BAILOUT_CHECK_GENERIC(isolate, value, ;) | 96 EXCEPTION_BAILOUT_CHECK_GENERIC(isolate, value, ;) |
97 | 97 |
98 | 98 |
| 99 #define PREPARE_FOR_EXECUTION_GENERIC(context, function_name, bailout_value, \ |
| 100 HandleScopeClass) \ |
| 101 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate()); \ |
| 102 if (IsExecutionTerminatingCheck(isolate)) { \ |
| 103 return bailout_value; \ |
| 104 } \ |
| 105 HandleScopeClass handle_scope(isolate); \ |
| 106 CallDepthScope call_depth_scope(isolate); \ |
| 107 v8::Context::Scope context_scope(context); \ |
| 108 LOG_API(isolate, function_name); \ |
| 109 ENTER_V8(isolate); \ |
| 110 bool has_pending_exception = false |
| 111 |
| 112 |
| 113 #define PREPARE_FOR_EXECUTION(context, function_name, T) \ |
| 114 PREPARE_FOR_EXECUTION_GENERIC(context, function_name, MaybeLocal<T>(), \ |
| 115 InternalEscapableScope) |
| 116 |
| 117 |
| 118 #define PREPARE_FOR_EXECUTION_PRIMITIVE(context, function_name, T) \ |
| 119 PREPARE_FOR_EXECUTION_GENERIC(context, function_name, Nothing<T>(), \ |
| 120 i::HandleScope) |
| 121 |
| 122 |
| 123 #define EXCEPTION_BAILOUT_CHECK_SCOPED(isolate, value, do_callback) \ |
| 124 do { \ |
| 125 if (has_pending_exception) { \ |
| 126 bool call_depth_is_zero = call_depth_scope.Escape(); \ |
| 127 (isolate)->OptionalRescheduleException(call_depth_is_zero); \ |
| 128 do_callback return value; \ |
| 129 } \ |
| 130 do_callback \ |
| 131 } while (false) |
| 132 |
| 133 |
| 134 #define RETURN_ON_FAILED_EXECUTION(T) \ |
| 135 EXCEPTION_BAILOUT_CHECK_SCOPED(isolate, MaybeLocal<T>(), ;) |
| 136 |
| 137 |
| 138 #define RETURN_ON_FAILED_EXECUTION_PRIMITIVE(T) \ |
| 139 EXCEPTION_BAILOUT_CHECK_SCOPED(isolate, Nothing<T>(), ;) |
| 140 |
| 141 |
| 142 #define RETURN_TO_LOCAL_UNCHECKED(maybe_local, T) \ |
| 143 return maybe_local.FromMaybe(Local<T>()); |
| 144 |
| 145 |
| 146 #define RETURN_ESCAPED(value) return handle_scope.Escape(value); |
| 147 |
| 148 |
| 149 namespace { |
| 150 |
| 151 Local<Context> ContextFromHeapObject(i::Handle<i::Object> obj) { |
| 152 return reinterpret_cast<v8::Isolate*>(i::HeapObject::cast(*obj)->GetIsolate()) |
| 153 ->GetCurrentContext(); |
| 154 } |
| 155 |
| 156 class InternalEscapableScope : public v8::EscapableHandleScope { |
| 157 public: |
| 158 explicit inline InternalEscapableScope(i::Isolate* isolate) |
| 159 : v8::EscapableHandleScope(reinterpret_cast<v8::Isolate*>(isolate)) {} |
| 160 }; |
| 161 |
| 162 |
| 163 class CallDepthScope { |
| 164 public: |
| 165 explicit CallDepthScope(i::Isolate* isolate) |
| 166 : isolate_(isolate), escaped_(false) { |
| 167 DCHECK(!isolate_->external_caught_exception()); |
| 168 isolate_->handle_scope_implementer()->IncrementCallDepth(); |
| 169 } |
| 170 ~CallDepthScope() { |
| 171 if (!escaped_) Escape(); |
| 172 } |
| 173 |
| 174 bool Escape() { |
| 175 DCHECK(!escaped_); |
| 176 escaped_ = true; |
| 177 auto handle_scope_implementer = isolate_->handle_scope_implementer(); |
| 178 handle_scope_implementer->DecrementCallDepth(); |
| 179 return handle_scope_implementer->CallDepthIsZero(); |
| 180 } |
| 181 |
| 182 private: |
| 183 i::Isolate* const isolate_; |
| 184 bool escaped_; |
| 185 }; |
| 186 |
| 187 } // namespace |
| 188 |
| 189 |
99 // --- E x c e p t i o n B e h a v i o r --- | 190 // --- E x c e p t i o n B e h a v i o r --- |
100 | 191 |
101 | 192 |
102 void i::FatalProcessOutOfMemory(const char* location) { | 193 void i::FatalProcessOutOfMemory(const char* location) { |
103 i::V8::FatalProcessOutOfMemory(location, false); | 194 i::V8::FatalProcessOutOfMemory(location, false); |
104 } | 195 } |
105 | 196 |
106 | 197 |
107 // When V8 cannot allocated memory FatalProcessOutOfMemory is called. | 198 // When V8 cannot allocated memory FatalProcessOutOfMemory is called. |
108 // The default fatal error handler is called and execution is stopped. | 199 // The default fatal error handler is called and execution is stopped. |
(...skipping 2516 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2625 bool Value::IsMapIterator() const { | 2716 bool Value::IsMapIterator() const { |
2626 return Utils::OpenHandle(this)->IsJSMapIterator(); | 2717 return Utils::OpenHandle(this)->IsJSMapIterator(); |
2627 } | 2718 } |
2628 | 2719 |
2629 | 2720 |
2630 bool Value::IsSetIterator() const { | 2721 bool Value::IsSetIterator() const { |
2631 return Utils::OpenHandle(this)->IsJSSetIterator(); | 2722 return Utils::OpenHandle(this)->IsJSSetIterator(); |
2632 } | 2723 } |
2633 | 2724 |
2634 | 2725 |
2635 #define CONTEXT_SCOPE_GET_ISOLATE(context, function_name) \ | |
2636 v8::Context::Scope context_scope(context); \ | |
2637 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate()); \ | |
2638 LOG_API(isolate, function_name); \ | |
2639 ENTER_V8(isolate); | |
2640 | |
2641 | |
2642 #define RETURN_TO_LOCAL_UNCHECKED(maybe_local, T) \ | |
2643 do { \ | |
2644 Local<T> result; \ | |
2645 bool ignored = maybe_local.ToLocal(&result); \ | |
2646 USE(ignored); \ | |
2647 return result; \ | |
2648 } while (false); | |
2649 | |
2650 | |
2651 static Local<Context> ContextFromHeapObject(i::Handle<i::Object> obj) { | |
2652 return reinterpret_cast<v8::Isolate*>(i::HeapObject::cast(*obj)->GetIsolate()) | |
2653 ->GetCurrentContext(); | |
2654 } | |
2655 | |
2656 | |
2657 MaybeLocal<String> Value::ToString(Local<Context> context) const { | 2726 MaybeLocal<String> Value::ToString(Local<Context> context) const { |
2658 auto obj = Utils::OpenHandle(this); | 2727 auto obj = Utils::OpenHandle(this); |
2659 if (obj->IsString()) return ToApiHandle<String>(obj); | 2728 if (obj->IsString()) return ToApiHandle<String>(obj); |
2660 CONTEXT_SCOPE_GET_ISOLATE(context, "ToString"); | 2729 PREPARE_FOR_EXECUTION(context, "ToString", String); |
2661 EXCEPTION_PREAMBLE(isolate); | |
2662 Local<String> result; | 2730 Local<String> result; |
2663 has_pending_exception = | 2731 has_pending_exception = |
2664 !ToLocal<String>(i::Execution::ToString(isolate, obj), &result); | 2732 !ToLocal<String>(i::Execution::ToString(isolate, obj), &result); |
2665 EXCEPTION_BAILOUT_CHECK(isolate, result); | 2733 RETURN_ON_FAILED_EXECUTION(String); |
2666 return result; | 2734 RETURN_ESCAPED(result); |
2667 } | 2735 } |
2668 | 2736 |
2669 | 2737 |
2670 Local<String> Value::ToString(Isolate* isolate) const { | 2738 Local<String> Value::ToString(Isolate* isolate) const { |
2671 RETURN_TO_LOCAL_UNCHECKED(ToString(isolate->GetCurrentContext()), String); | 2739 RETURN_TO_LOCAL_UNCHECKED(ToString(isolate->GetCurrentContext()), String); |
2672 } | 2740 } |
2673 | 2741 |
2674 | 2742 |
2675 MaybeLocal<String> Value::ToDetailString(Local<Context> context) const { | 2743 MaybeLocal<String> Value::ToDetailString(Local<Context> context) const { |
2676 auto obj = Utils::OpenHandle(this); | 2744 auto obj = Utils::OpenHandle(this); |
2677 if (obj->IsString()) return ToApiHandle<String>(obj); | 2745 if (obj->IsString()) return ToApiHandle<String>(obj); |
2678 CONTEXT_SCOPE_GET_ISOLATE(context, "ToDetailString"); | 2746 PREPARE_FOR_EXECUTION(context, "ToDetailString", String); |
2679 EXCEPTION_PREAMBLE(isolate); | |
2680 Local<String> result; | 2747 Local<String> result; |
2681 has_pending_exception = | 2748 has_pending_exception = |
2682 !ToLocal<String>(i::Execution::ToDetailString(isolate, obj), &result); | 2749 !ToLocal<String>(i::Execution::ToDetailString(isolate, obj), &result); |
2683 EXCEPTION_BAILOUT_CHECK(isolate, result); | 2750 RETURN_ON_FAILED_EXECUTION(String); |
2684 return result; | 2751 RETURN_ESCAPED(result); |
2685 } | 2752 } |
2686 | 2753 |
2687 | 2754 |
2688 Local<String> Value::ToDetailString(Isolate* isolate) const { | 2755 Local<String> Value::ToDetailString(Isolate* isolate) const { |
2689 RETURN_TO_LOCAL_UNCHECKED(ToDetailString(isolate->GetCurrentContext()), | 2756 RETURN_TO_LOCAL_UNCHECKED(ToDetailString(isolate->GetCurrentContext()), |
2690 String); | 2757 String); |
2691 } | 2758 } |
2692 | 2759 |
2693 | 2760 |
2694 MaybeLocal<Object> Value::ToObject(Local<Context> context) const { | 2761 MaybeLocal<Object> Value::ToObject(Local<Context> context) const { |
2695 auto obj = Utils::OpenHandle(this); | 2762 auto obj = Utils::OpenHandle(this); |
2696 if (obj->IsJSObject()) return ToApiHandle<Object>(obj); | 2763 if (obj->IsJSObject()) return ToApiHandle<Object>(obj); |
2697 CONTEXT_SCOPE_GET_ISOLATE(context, "ToObject"); | 2764 PREPARE_FOR_EXECUTION(context, "ToObject", Object); |
2698 EXCEPTION_PREAMBLE(isolate); | |
2699 Local<Object> result; | 2765 Local<Object> result; |
2700 has_pending_exception = | 2766 has_pending_exception = |
2701 !ToLocal<Object>(i::Execution::ToObject(isolate, obj), &result); | 2767 !ToLocal<Object>(i::Execution::ToObject(isolate, obj), &result); |
2702 EXCEPTION_BAILOUT_CHECK(isolate, result); | 2768 RETURN_ON_FAILED_EXECUTION(Object); |
2703 return result; | 2769 RETURN_ESCAPED(result); |
2704 } | 2770 } |
2705 | 2771 |
2706 | 2772 |
2707 Local<v8::Object> Value::ToObject(Isolate* isolate) const { | 2773 Local<v8::Object> Value::ToObject(Isolate* isolate) const { |
2708 RETURN_TO_LOCAL_UNCHECKED(ToObject(isolate->GetCurrentContext()), Object); | 2774 RETURN_TO_LOCAL_UNCHECKED(ToObject(isolate->GetCurrentContext()), Object); |
2709 } | 2775 } |
2710 | 2776 |
2711 | 2777 |
2712 MaybeLocal<Boolean> Value::ToBoolean(Local<Context> context) const { | 2778 MaybeLocal<Boolean> Value::ToBoolean(Local<Context> context) const { |
2713 auto obj = Utils::OpenHandle(this); | 2779 auto obj = Utils::OpenHandle(this); |
2714 if (obj->IsBoolean()) return ToApiHandle<Boolean>(obj); | 2780 if (obj->IsBoolean()) return ToApiHandle<Boolean>(obj); |
2715 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate()); | 2781 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate()); |
2716 auto val = isolate->factory()->ToBoolean(obj->BooleanValue()); | 2782 auto val = isolate->factory()->ToBoolean(obj->BooleanValue()); |
2717 return ToApiHandle<Boolean>(val); | 2783 return ToApiHandle<Boolean>(val); |
2718 } | 2784 } |
2719 | 2785 |
2720 | 2786 |
2721 Local<Boolean> Value::ToBoolean(Isolate* v8_isolate) const { | 2787 Local<Boolean> Value::ToBoolean(Isolate* v8_isolate) const { |
2722 return ToBoolean(v8_isolate->GetCurrentContext()).ToLocalChecked(); | 2788 return ToBoolean(v8_isolate->GetCurrentContext()).ToLocalChecked(); |
2723 } | 2789 } |
2724 | 2790 |
2725 | 2791 |
2726 MaybeLocal<Number> Value::ToNumber(Local<Context> context) const { | 2792 MaybeLocal<Number> Value::ToNumber(Local<Context> context) const { |
2727 auto obj = Utils::OpenHandle(this); | 2793 auto obj = Utils::OpenHandle(this); |
2728 if (obj->IsNumber()) return ToApiHandle<Number>(obj); | 2794 if (obj->IsNumber()) return ToApiHandle<Number>(obj); |
2729 CONTEXT_SCOPE_GET_ISOLATE(context, "ToNumber"); | 2795 PREPARE_FOR_EXECUTION(context, "ToNumber", Number); |
2730 EXCEPTION_PREAMBLE(isolate); | |
2731 Local<Number> result; | 2796 Local<Number> result; |
2732 has_pending_exception = | 2797 has_pending_exception = |
2733 !ToLocal<Number>(i::Execution::ToNumber(isolate, obj), &result); | 2798 !ToLocal<Number>(i::Execution::ToNumber(isolate, obj), &result); |
2734 EXCEPTION_BAILOUT_CHECK(isolate, result); | 2799 RETURN_ON_FAILED_EXECUTION(Number); |
2735 return result; | 2800 RETURN_ESCAPED(result); |
2736 } | 2801 } |
2737 | 2802 |
2738 | 2803 |
2739 Local<Number> Value::ToNumber(Isolate* isolate) const { | 2804 Local<Number> Value::ToNumber(Isolate* isolate) const { |
2740 RETURN_TO_LOCAL_UNCHECKED(ToNumber(isolate->GetCurrentContext()), Number); | 2805 RETURN_TO_LOCAL_UNCHECKED(ToNumber(isolate->GetCurrentContext()), Number); |
2741 } | 2806 } |
2742 | 2807 |
2743 | 2808 |
2744 MaybeLocal<Integer> Value::ToInteger(Local<Context> context) const { | 2809 MaybeLocal<Integer> Value::ToInteger(Local<Context> context) const { |
2745 auto obj = Utils::OpenHandle(this); | 2810 auto obj = Utils::OpenHandle(this); |
2746 if (obj->IsSmi()) return ToApiHandle<Integer>(obj); | 2811 if (obj->IsSmi()) return ToApiHandle<Integer>(obj); |
2747 CONTEXT_SCOPE_GET_ISOLATE(context, "ToInteger"); | 2812 PREPARE_FOR_EXECUTION(context, "ToInteger", Integer); |
2748 EXCEPTION_PREAMBLE(isolate); | |
2749 Local<Integer> result; | 2813 Local<Integer> result; |
2750 has_pending_exception = | 2814 has_pending_exception = |
2751 !ToLocal<Integer>(i::Execution::ToInteger(isolate, obj), &result); | 2815 !ToLocal<Integer>(i::Execution::ToInteger(isolate, obj), &result); |
2752 EXCEPTION_BAILOUT_CHECK(isolate, result); | 2816 RETURN_ON_FAILED_EXECUTION(Integer); |
2753 return result; | 2817 RETURN_ESCAPED(result); |
2754 } | 2818 } |
2755 | 2819 |
2756 | 2820 |
2757 Local<Integer> Value::ToInteger(Isolate* isolate) const { | 2821 Local<Integer> Value::ToInteger(Isolate* isolate) const { |
2758 RETURN_TO_LOCAL_UNCHECKED(ToInteger(isolate->GetCurrentContext()), Integer); | 2822 RETURN_TO_LOCAL_UNCHECKED(ToInteger(isolate->GetCurrentContext()), Integer); |
2759 } | 2823 } |
2760 | 2824 |
2761 | 2825 |
2762 MaybeLocal<Int32> Value::ToInt32(Local<Context> context) const { | 2826 MaybeLocal<Int32> Value::ToInt32(Local<Context> context) const { |
2763 auto obj = Utils::OpenHandle(this); | 2827 auto obj = Utils::OpenHandle(this); |
2764 if (obj->IsSmi()) return ToApiHandle<Int32>(obj); | 2828 if (obj->IsSmi()) return ToApiHandle<Int32>(obj); |
2765 CONTEXT_SCOPE_GET_ISOLATE(context, "ToInt32"); | |
2766 EXCEPTION_PREAMBLE(isolate); | |
2767 Local<Int32> result; | 2829 Local<Int32> result; |
| 2830 PREPARE_FOR_EXECUTION(context, "ToInt32", Int32); |
2768 has_pending_exception = | 2831 has_pending_exception = |
2769 !ToLocal<Int32>(i::Execution::ToInt32(isolate, obj), &result); | 2832 !ToLocal<Int32>(i::Execution::ToInt32(isolate, obj), &result); |
2770 EXCEPTION_BAILOUT_CHECK(isolate, result); | 2833 RETURN_ON_FAILED_EXECUTION(Int32); |
2771 return result; | 2834 RETURN_ESCAPED(result); |
2772 } | 2835 } |
2773 | 2836 |
2774 | 2837 |
2775 Local<Int32> Value::ToInt32(Isolate* isolate) const { | 2838 Local<Int32> Value::ToInt32(Isolate* isolate) const { |
2776 RETURN_TO_LOCAL_UNCHECKED(ToInt32(isolate->GetCurrentContext()), Int32); | 2839 RETURN_TO_LOCAL_UNCHECKED(ToInt32(isolate->GetCurrentContext()), Int32); |
2777 } | 2840 } |
2778 | 2841 |
2779 | 2842 |
2780 MaybeLocal<Uint32> Value::ToUint32(Local<Context> context) const { | 2843 MaybeLocal<Uint32> Value::ToUint32(Local<Context> context) const { |
2781 auto obj = Utils::OpenHandle(this); | 2844 auto obj = Utils::OpenHandle(this); |
2782 if (obj->IsSmi()) return ToApiHandle<Uint32>(obj); | 2845 if (obj->IsSmi()) return ToApiHandle<Uint32>(obj); |
2783 CONTEXT_SCOPE_GET_ISOLATE(context, "ToUInt32"); | |
2784 EXCEPTION_PREAMBLE(isolate); | |
2785 Local<Uint32> result; | 2846 Local<Uint32> result; |
| 2847 PREPARE_FOR_EXECUTION(context, "ToUInt32", Uint32); |
2786 has_pending_exception = | 2848 has_pending_exception = |
2787 !ToLocal<Uint32>(i::Execution::ToUint32(isolate, obj), &result); | 2849 !ToLocal<Uint32>(i::Execution::ToUint32(isolate, obj), &result); |
2788 EXCEPTION_BAILOUT_CHECK(isolate, result); | 2850 RETURN_ON_FAILED_EXECUTION(Uint32); |
2789 return result; | 2851 RETURN_ESCAPED(result); |
2790 } | 2852 } |
2791 | 2853 |
2792 | 2854 |
2793 Local<Uint32> Value::ToUint32(Isolate* isolate) const { | 2855 Local<Uint32> Value::ToUint32(Isolate* isolate) const { |
2794 RETURN_TO_LOCAL_UNCHECKED(ToUint32(isolate->GetCurrentContext()), Uint32); | 2856 RETURN_TO_LOCAL_UNCHECKED(ToUint32(isolate->GetCurrentContext()), Uint32); |
2795 } | 2857 } |
2796 | 2858 |
2797 | 2859 |
2798 void i::Internals::CheckInitializedImpl(v8::Isolate* external_isolate) { | 2860 void i::Internals::CheckInitializedImpl(v8::Isolate* external_isolate) { |
2799 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(external_isolate); | 2861 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(external_isolate); |
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3006 | 3068 |
3007 | 3069 |
3008 bool Value::BooleanValue() const { | 3070 bool Value::BooleanValue() const { |
3009 return Utils::OpenHandle(this)->BooleanValue(); | 3071 return Utils::OpenHandle(this)->BooleanValue(); |
3010 } | 3072 } |
3011 | 3073 |
3012 | 3074 |
3013 Maybe<double> Value::NumberValue(Local<Context> context) const { | 3075 Maybe<double> Value::NumberValue(Local<Context> context) const { |
3014 auto obj = Utils::OpenHandle(this); | 3076 auto obj = Utils::OpenHandle(this); |
3015 if (obj->IsNumber()) return Just(obj->Number()); | 3077 if (obj->IsNumber()) return Just(obj->Number()); |
3016 CONTEXT_SCOPE_GET_ISOLATE(context, "NumberValue"); | 3078 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "NumberValue", double); |
3017 EXCEPTION_PREAMBLE(isolate); | |
3018 i::Handle<i::Object> num; | 3079 i::Handle<i::Object> num; |
3019 has_pending_exception = !i::Execution::ToNumber(isolate, obj).ToHandle(&num); | 3080 has_pending_exception = !i::Execution::ToNumber(isolate, obj).ToHandle(&num); |
3020 EXCEPTION_BAILOUT_CHECK(isolate, Nothing<double>()); | 3081 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(double); |
3021 return Just(num->Number()); | 3082 return Just(num->Number()); |
3022 } | 3083 } |
3023 | 3084 |
3024 | 3085 |
3025 double Value::NumberValue() const { | 3086 double Value::NumberValue() const { |
3026 auto obj = Utils::OpenHandle(this); | 3087 auto obj = Utils::OpenHandle(this); |
3027 if (obj->IsNumber()) return obj->Number(); | 3088 if (obj->IsNumber()) return obj->Number(); |
3028 return NumberValue(ContextFromHeapObject(obj)) | 3089 return NumberValue(ContextFromHeapObject(obj)) |
3029 .FromMaybe(std::numeric_limits<double>::quiet_NaN()); | 3090 .FromMaybe(std::numeric_limits<double>::quiet_NaN()); |
3030 } | 3091 } |
3031 | 3092 |
3032 | 3093 |
3033 Maybe<int64_t> Value::IntegerValue(Local<Context> context) const { | 3094 Maybe<int64_t> Value::IntegerValue(Local<Context> context) const { |
3034 auto obj = Utils::OpenHandle(this); | 3095 auto obj = Utils::OpenHandle(this); |
3035 i::Handle<i::Object> num; | 3096 i::Handle<i::Object> num; |
3036 if (obj->IsNumber()) { | 3097 if (obj->IsNumber()) { |
3037 num = obj; | 3098 num = obj; |
3038 } else { | 3099 } else { |
3039 CONTEXT_SCOPE_GET_ISOLATE(context, "IntegerValue"); | 3100 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "IntegerValue", int64_t); |
3040 EXCEPTION_PREAMBLE(isolate); | |
3041 has_pending_exception = | 3101 has_pending_exception = |
3042 !i::Execution::ToInteger(isolate, obj).ToHandle(&num); | 3102 !i::Execution::ToInteger(isolate, obj).ToHandle(&num); |
3043 EXCEPTION_BAILOUT_CHECK(isolate, Nothing<int64_t>()); | 3103 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(int64_t); |
3044 } | 3104 } |
3045 return Just(num->IsSmi() ? static_cast<int64_t>(i::Smi::cast(*num)->value()) | 3105 return Just(num->IsSmi() ? static_cast<int64_t>(i::Smi::cast(*num)->value()) |
3046 : static_cast<int64_t>(num->Number())); | 3106 : static_cast<int64_t>(num->Number())); |
3047 } | 3107 } |
3048 | 3108 |
3049 | 3109 |
3050 int64_t Value::IntegerValue() const { | 3110 int64_t Value::IntegerValue() const { |
3051 auto obj = Utils::OpenHandle(this); | 3111 auto obj = Utils::OpenHandle(this); |
3052 if (obj->IsNumber()) { | 3112 if (obj->IsNumber()) { |
3053 if (obj->IsSmi()) { | 3113 if (obj->IsSmi()) { |
3054 return i::Smi::cast(*obj)->value(); | 3114 return i::Smi::cast(*obj)->value(); |
3055 } else { | 3115 } else { |
3056 return static_cast<int64_t>(obj->Number()); | 3116 return static_cast<int64_t>(obj->Number()); |
3057 } | 3117 } |
3058 } | 3118 } |
3059 return IntegerValue(ContextFromHeapObject(obj)).FromMaybe(0); | 3119 return IntegerValue(ContextFromHeapObject(obj)).FromMaybe(0); |
3060 } | 3120 } |
3061 | 3121 |
3062 | 3122 |
3063 Maybe<int32_t> Value::Int32Value(Local<Context> context) const { | 3123 Maybe<int32_t> Value::Int32Value(Local<Context> context) const { |
3064 auto obj = Utils::OpenHandle(this); | 3124 auto obj = Utils::OpenHandle(this); |
3065 if (obj->IsNumber()) return Just(NumberToInt32(*obj)); | 3125 if (obj->IsNumber()) return Just(NumberToInt32(*obj)); |
3066 CONTEXT_SCOPE_GET_ISOLATE(context, "Int32Value"); | 3126 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "Int32Value", int32_t); |
3067 EXCEPTION_PREAMBLE(isolate); | |
3068 i::Handle<i::Object> num; | 3127 i::Handle<i::Object> num; |
3069 has_pending_exception = !i::Execution::ToInt32(isolate, obj).ToHandle(&num); | 3128 has_pending_exception = !i::Execution::ToInt32(isolate, obj).ToHandle(&num); |
3070 EXCEPTION_BAILOUT_CHECK(isolate, Nothing<int32_t>()); | 3129 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(int32_t); |
3071 return Just(num->IsSmi() ? i::Smi::cast(*num)->value() | 3130 return Just(num->IsSmi() ? i::Smi::cast(*num)->value() |
3072 : static_cast<int32_t>(num->Number())); | 3131 : static_cast<int32_t>(num->Number())); |
3073 } | 3132 } |
3074 | 3133 |
3075 | 3134 |
3076 int32_t Value::Int32Value() const { | 3135 int32_t Value::Int32Value() const { |
3077 auto obj = Utils::OpenHandle(this); | 3136 auto obj = Utils::OpenHandle(this); |
3078 if (obj->IsNumber()) return NumberToInt32(*obj); | 3137 if (obj->IsNumber()) return NumberToInt32(*obj); |
3079 return Int32Value(ContextFromHeapObject(obj)).FromMaybe(0); | 3138 return Int32Value(ContextFromHeapObject(obj)).FromMaybe(0); |
3080 } | 3139 } |
3081 | 3140 |
3082 | 3141 |
3083 Maybe<uint32_t> Value::Uint32Value(Local<Context> context) const { | 3142 Maybe<uint32_t> Value::Uint32Value(Local<Context> context) const { |
3084 auto obj = Utils::OpenHandle(this); | 3143 auto obj = Utils::OpenHandle(this); |
3085 if (obj->IsNumber()) return Just(NumberToUint32(*obj)); | 3144 if (obj->IsNumber()) return Just(NumberToUint32(*obj)); |
3086 CONTEXT_SCOPE_GET_ISOLATE(context, "Uint32Value"); | 3145 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "Uint32Value", uint32_t); |
3087 EXCEPTION_PREAMBLE(isolate); | |
3088 i::Handle<i::Object> num; | 3146 i::Handle<i::Object> num; |
3089 has_pending_exception = !i::Execution::ToUint32(isolate, obj).ToHandle(&num); | 3147 has_pending_exception = !i::Execution::ToUint32(isolate, obj).ToHandle(&num); |
3090 EXCEPTION_BAILOUT_CHECK(isolate, Nothing<uint32_t>()); | 3148 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(uint32_t); |
3091 return Just(num->IsSmi() ? static_cast<uint32_t>(i::Smi::cast(*num)->value()) | 3149 return Just(num->IsSmi() ? static_cast<uint32_t>(i::Smi::cast(*num)->value()) |
3092 : static_cast<uint32_t>(num->Number())); | 3150 : static_cast<uint32_t>(num->Number())); |
3093 } | 3151 } |
3094 | 3152 |
3095 | 3153 |
3096 uint32_t Value::Uint32Value() const { | 3154 uint32_t Value::Uint32Value() const { |
3097 auto obj = Utils::OpenHandle(this); | 3155 auto obj = Utils::OpenHandle(this); |
3098 if (obj->IsNumber()) return NumberToUint32(*obj); | 3156 if (obj->IsNumber()) return NumberToUint32(*obj); |
3099 return Uint32Value(ContextFromHeapObject(obj)).FromMaybe(0); | 3157 return Uint32Value(ContextFromHeapObject(obj)).FromMaybe(0); |
3100 } | 3158 } |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3202 if (!Utils::ApiCheck(!obj.is_null() && !that.IsEmpty(), | 3260 if (!Utils::ApiCheck(!obj.is_null() && !that.IsEmpty(), |
3203 "v8::Value::SameValue()", | 3261 "v8::Value::SameValue()", |
3204 "Reading from empty handle")) { | 3262 "Reading from empty handle")) { |
3205 return false; | 3263 return false; |
3206 } | 3264 } |
3207 i::Handle<i::Object> other = Utils::OpenHandle(*that); | 3265 i::Handle<i::Object> other = Utils::OpenHandle(*that); |
3208 return obj->SameValue(*other); | 3266 return obj->SameValue(*other); |
3209 } | 3267 } |
3210 | 3268 |
3211 | 3269 |
| 3270 Maybe<bool> v8::Object::Set(v8::Local<v8::Context> context, |
| 3271 v8::Local<Value> key, v8::Local<Value> value) { |
| 3272 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Object::Set()", bool); |
| 3273 auto self = Utils::OpenHandle(this); |
| 3274 auto key_obj = Utils::OpenHandle(*key); |
| 3275 auto value_obj = Utils::OpenHandle(*value); |
| 3276 has_pending_exception = |
| 3277 i::Runtime::SetObjectProperty(isolate, self, key_obj, value_obj, |
| 3278 i::SLOPPY).is_null(); |
| 3279 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool); |
| 3280 return Just(true); |
| 3281 } |
| 3282 |
| 3283 |
3212 bool v8::Object::Set(v8::Handle<Value> key, v8::Handle<Value> value) { | 3284 bool v8::Object::Set(v8::Handle<Value> key, v8::Handle<Value> value) { |
3213 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); | 3285 auto context = ContextFromHeapObject(Utils::OpenHandle(this)); |
3214 ON_BAILOUT(isolate, "v8::Object::Set()", return false); | 3286 return Set(context, key, value).FromMaybe(false); |
3215 ENTER_V8(isolate); | 3287 } |
3216 i::HandleScope scope(isolate); | 3288 |
3217 i::Handle<i::Object> self = Utils::OpenHandle(this); | 3289 |
3218 i::Handle<i::Object> key_obj = Utils::OpenHandle(*key); | 3290 Maybe<bool> v8::Object::Set(v8::Local<v8::Context> context, uint32_t index, |
3219 i::Handle<i::Object> value_obj = Utils::OpenHandle(*value); | 3291 v8::Local<Value> value) { |
3220 EXCEPTION_PREAMBLE(isolate); | 3292 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Object::Set()", bool); |
3221 has_pending_exception = | 3293 auto self = Utils::OpenHandle(this); |
3222 i::Runtime::SetObjectProperty(isolate, self, key_obj, value_obj, | 3294 auto value_obj = Utils::OpenHandle(*value); |
3223 i::SLOPPY).is_null(); | 3295 has_pending_exception = i::JSObject::SetElement( |
3224 EXCEPTION_BAILOUT_CHECK(isolate, false); | 3296 self, index, value_obj, NONE, i::SLOPPY).is_null(); |
3225 return true; | 3297 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool); |
| 3298 return Just(true); |
3226 } | 3299 } |
3227 | 3300 |
3228 | 3301 |
3229 bool v8::Object::Set(uint32_t index, v8::Handle<Value> value) { | 3302 bool v8::Object::Set(uint32_t index, v8::Handle<Value> value) { |
3230 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); | 3303 auto context = ContextFromHeapObject(Utils::OpenHandle(this)); |
3231 ON_BAILOUT(isolate, "v8::Object::Set()", return false); | 3304 return Set(context, index, value).FromMaybe(false); |
3232 ENTER_V8(isolate); | |
3233 i::HandleScope scope(isolate); | |
3234 i::Handle<i::JSObject> self = Utils::OpenHandle(this); | |
3235 i::Handle<i::Object> value_obj = Utils::OpenHandle(*value); | |
3236 EXCEPTION_PREAMBLE(isolate); | |
3237 has_pending_exception = i::JSObject::SetElement( | |
3238 self, index, value_obj, NONE, i::SLOPPY).is_null(); | |
3239 EXCEPTION_BAILOUT_CHECK(isolate, false); | |
3240 return true; | |
3241 } | 3305 } |
3242 | 3306 |
3243 | 3307 |
3244 bool v8::Object::ForceSet(v8::Handle<Value> key, | 3308 Maybe<bool> v8::Object::ForceSet(v8::Local<v8::Context> context, |
3245 v8::Handle<Value> value, | 3309 v8::Local<Value> key, v8::Local<Value> value, |
3246 v8::PropertyAttribute attribs) { | 3310 v8::PropertyAttribute attribs) { |
3247 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); | 3311 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Object::Set()", bool); |
3248 ON_BAILOUT(isolate, "v8::Object::ForceSet()", return false); | 3312 auto self = Utils::OpenHandle(this); |
3249 ENTER_V8(isolate); | 3313 auto key_obj = Utils::OpenHandle(*key); |
3250 i::HandleScope scope(isolate); | 3314 auto value_obj = Utils::OpenHandle(*value); |
3251 i::Handle<i::JSObject> self = Utils::OpenHandle(this); | |
3252 i::Handle<i::Object> key_obj = Utils::OpenHandle(*key); | |
3253 i::Handle<i::Object> value_obj = Utils::OpenHandle(*value); | |
3254 EXCEPTION_PREAMBLE(isolate); | |
3255 has_pending_exception = i::Runtime::DefineObjectProperty( | 3315 has_pending_exception = i::Runtime::DefineObjectProperty( |
3256 self, | 3316 self, |
3257 key_obj, | 3317 key_obj, |
3258 value_obj, | 3318 value_obj, |
3259 static_cast<PropertyAttributes>(attribs)).is_null(); | 3319 static_cast<PropertyAttributes>(attribs)).is_null(); |
3260 EXCEPTION_BAILOUT_CHECK(isolate, false); | 3320 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool); |
3261 return true; | 3321 return Just(true); |
3262 } | 3322 } |
3263 | 3323 |
3264 | 3324 |
| 3325 bool v8::Object::ForceSet(v8::Handle<Value> key, v8::Handle<Value> value, |
| 3326 v8::PropertyAttribute attribs) { |
| 3327 auto context = ContextFromHeapObject(Utils::OpenHandle(this)); |
| 3328 return ForceSet(context, key, value, attribs).FromMaybe(false); |
| 3329 } |
| 3330 |
| 3331 |
3265 bool v8::Object::SetPrivate(v8::Handle<Private> key, v8::Handle<Value> value) { | 3332 bool v8::Object::SetPrivate(v8::Handle<Private> key, v8::Handle<Value> value) { |
3266 return ForceSet(v8::Handle<Value>(reinterpret_cast<Value*>(*key)), | 3333 return ForceSet(v8::Handle<Value>(reinterpret_cast<Value*>(*key)), |
3267 value, DontEnum); | 3334 value, DontEnum); |
3268 } | 3335 } |
3269 | 3336 |
3270 | 3337 |
| 3338 namespace { |
| 3339 |
3271 i::MaybeHandle<i::Object> DeleteObjectProperty( | 3340 i::MaybeHandle<i::Object> DeleteObjectProperty( |
3272 i::Isolate* isolate, i::Handle<i::JSReceiver> receiver, | 3341 i::Isolate* isolate, i::Handle<i::JSReceiver> receiver, |
3273 i::Handle<i::Object> key, i::LanguageMode language_mode) { | 3342 i::Handle<i::Object> key, i::LanguageMode language_mode) { |
3274 // Check if the given key is an array index. | 3343 // Check if the given key is an array index. |
3275 uint32_t index; | 3344 uint32_t index; |
3276 if (key->ToArrayIndex(&index)) { | 3345 if (key->ToArrayIndex(&index)) { |
3277 // In Firefox/SpiderMonkey, Safari and Opera you can access the | 3346 // In Firefox/SpiderMonkey, Safari and Opera you can access the |
3278 // characters of a string using [] notation. In the case of a | 3347 // characters of a string using [] notation. In the case of a |
3279 // String object we just need to redirect the deletion to the | 3348 // String object we just need to redirect the deletion to the |
3280 // underlying string if the index is in range. Since the | 3349 // underlying string if the index is in range. Since the |
(...skipping 17 matching lines...) Expand all Loading... |
3298 } | 3367 } |
3299 name = i::Handle<i::String>::cast(converted); | 3368 name = i::Handle<i::String>::cast(converted); |
3300 } | 3369 } |
3301 | 3370 |
3302 if (name->IsString()) { | 3371 if (name->IsString()) { |
3303 name = i::String::Flatten(i::Handle<i::String>::cast(name)); | 3372 name = i::String::Flatten(i::Handle<i::String>::cast(name)); |
3304 } | 3373 } |
3305 return i::JSReceiver::DeleteProperty(receiver, name, language_mode); | 3374 return i::JSReceiver::DeleteProperty(receiver, name, language_mode); |
3306 } | 3375 } |
3307 | 3376 |
| 3377 } // namespace |
| 3378 |
| 3379 |
| 3380 MaybeLocal<Value> v8::Object::Get(Local<v8::Context> context, |
| 3381 Local<Value> key) { |
| 3382 PREPARE_FOR_EXECUTION(context, "v8::Object::Get()", Value); |
| 3383 auto self = Utils::OpenHandle(this); |
| 3384 auto key_obj = Utils::OpenHandle(*key); |
| 3385 i::Handle<i::Object> result; |
| 3386 has_pending_exception = |
| 3387 !i::Runtime::GetObjectProperty(isolate, self, key_obj).ToHandle(&result); |
| 3388 RETURN_ON_FAILED_EXECUTION(Value); |
| 3389 RETURN_ESCAPED(Utils::ToLocal(result)); |
| 3390 } |
| 3391 |
3308 | 3392 |
3309 Local<Value> v8::Object::Get(v8::Handle<Value> key) { | 3393 Local<Value> v8::Object::Get(v8::Handle<Value> key) { |
3310 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); | 3394 auto context = ContextFromHeapObject(Utils::OpenHandle(this)); |
3311 ON_BAILOUT(isolate, "v8::Object::Get()", return Local<v8::Value>()); | 3395 RETURN_TO_LOCAL_UNCHECKED(Get(context, key), Value); |
3312 ENTER_V8(isolate); | 3396 } |
3313 i::Handle<i::Object> self = Utils::OpenHandle(this); | 3397 |
3314 i::Handle<i::Object> key_obj = Utils::OpenHandle(*key); | 3398 |
3315 EXCEPTION_PREAMBLE(isolate); | 3399 MaybeLocal<Value> v8::Object::Get(Local<Context> context, uint32_t index) { |
| 3400 PREPARE_FOR_EXECUTION(context, "v8::Object::Get()", Value); |
| 3401 auto self = Utils::OpenHandle(this); |
3316 i::Handle<i::Object> result; | 3402 i::Handle<i::Object> result; |
3317 has_pending_exception = | 3403 has_pending_exception = |
3318 !i::Runtime::GetObjectProperty(isolate, self, key_obj).ToHandle(&result); | 3404 !i::Object::GetElement(isolate, self, index).ToHandle(&result); |
3319 EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>()); | 3405 RETURN_ON_FAILED_EXECUTION(Value); |
3320 return Utils::ToLocal(result); | 3406 RETURN_ESCAPED(Utils::ToLocal(result)); |
3321 } | 3407 } |
3322 | 3408 |
3323 | 3409 |
3324 Local<Value> v8::Object::Get(uint32_t index) { | 3410 Local<Value> v8::Object::Get(uint32_t index) { |
3325 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); | 3411 auto context = ContextFromHeapObject(Utils::OpenHandle(this)); |
3326 ON_BAILOUT(isolate, "v8::Object::Get()", return Local<v8::Value>()); | 3412 RETURN_TO_LOCAL_UNCHECKED(Get(context, index), Value); |
3327 ENTER_V8(isolate); | |
3328 i::Handle<i::JSObject> self = Utils::OpenHandle(this); | |
3329 EXCEPTION_PREAMBLE(isolate); | |
3330 i::Handle<i::Object> result; | |
3331 has_pending_exception = | |
3332 !i::Object::GetElement(isolate, self, index).ToHandle(&result); | |
3333 EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>()); | |
3334 return Utils::ToLocal(result); | |
3335 } | 3413 } |
3336 | 3414 |
3337 | 3415 |
3338 Local<Value> v8::Object::GetPrivate(v8::Handle<Private> key) { | 3416 Local<Value> v8::Object::GetPrivate(v8::Handle<Private> key) { |
3339 return Get(v8::Handle<Value>(reinterpret_cast<Value*>(*key))); | 3417 return Get(v8::Handle<Value>(reinterpret_cast<Value*>(*key))); |
3340 } | 3418 } |
3341 | 3419 |
3342 | 3420 |
| 3421 Maybe<PropertyAttribute> v8::Object::GetPropertyAttributes( |
| 3422 Local<Context> context, Local<Value> key) { |
| 3423 PREPARE_FOR_EXECUTION_PRIMITIVE( |
| 3424 context, "v8::Object::GetPropertyAttributes()", PropertyAttribute); |
| 3425 auto self = Utils::OpenHandle(this); |
| 3426 auto key_obj = Utils::OpenHandle(*key); |
| 3427 if (!key_obj->IsName()) { |
| 3428 has_pending_exception = !i::Execution::ToString( |
| 3429 isolate, key_obj).ToHandle(&key_obj); |
| 3430 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(PropertyAttribute); |
| 3431 } |
| 3432 auto key_name = i::Handle<i::Name>::cast(key_obj); |
| 3433 auto result = i::JSReceiver::GetPropertyAttributes(self, key_name); |
| 3434 has_pending_exception = !result.has_value; |
| 3435 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(PropertyAttribute); |
| 3436 if (result.value == ABSENT) { |
| 3437 return Just(static_cast<PropertyAttribute>(NONE)); |
| 3438 } |
| 3439 return Just(static_cast<PropertyAttribute>(result.value)); |
| 3440 } |
| 3441 |
| 3442 |
3343 PropertyAttribute v8::Object::GetPropertyAttributes(v8::Handle<Value> key) { | 3443 PropertyAttribute v8::Object::GetPropertyAttributes(v8::Handle<Value> key) { |
3344 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); | 3444 auto context = ContextFromHeapObject(Utils::OpenHandle(this)); |
3345 ON_BAILOUT(isolate, "v8::Object::GetPropertyAttributes()", | 3445 return GetPropertyAttributes(context, key) |
3346 return static_cast<PropertyAttribute>(NONE)); | 3446 .FromMaybe(static_cast<PropertyAttribute>(NONE)); |
3347 ENTER_V8(isolate); | |
3348 i::HandleScope scope(isolate); | |
3349 i::Handle<i::JSObject> self = Utils::OpenHandle(this); | |
3350 i::Handle<i::Object> key_obj = Utils::OpenHandle(*key); | |
3351 if (!key_obj->IsName()) { | |
3352 EXCEPTION_PREAMBLE(isolate); | |
3353 has_pending_exception = !i::Execution::ToString( | |
3354 isolate, key_obj).ToHandle(&key_obj); | |
3355 EXCEPTION_BAILOUT_CHECK(isolate, static_cast<PropertyAttribute>(NONE)); | |
3356 } | |
3357 i::Handle<i::Name> key_name = i::Handle<i::Name>::cast(key_obj); | |
3358 EXCEPTION_PREAMBLE(isolate); | |
3359 Maybe<PropertyAttributes> result = | |
3360 i::JSReceiver::GetPropertyAttributes(self, key_name); | |
3361 has_pending_exception = !result.has_value; | |
3362 EXCEPTION_BAILOUT_CHECK(isolate, static_cast<PropertyAttribute>(NONE)); | |
3363 if (result.value == ABSENT) return static_cast<PropertyAttribute>(NONE); | |
3364 return static_cast<PropertyAttribute>(result.value); | |
3365 } | 3447 } |
3366 | 3448 |
3367 | 3449 |
3368 Local<Value> v8::Object::GetOwnPropertyDescriptor(Local<String> key) { | 3450 MaybeLocal<Value> v8::Object::GetOwnPropertyDescriptor(Local<Context> context, |
3369 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); | 3451 Local<String> key) { |
3370 ON_BAILOUT(isolate, "v8::Object::GetOwnPropertyDescriptor()", | 3452 PREPARE_FOR_EXECUTION(context, "v8::Object::GetOwnPropertyDescriptor()", |
3371 return Local<Value>()); | 3453 Value); |
3372 ENTER_V8(isolate); | 3454 auto obj = Utils::OpenHandle(this); |
3373 i::Handle<i::JSObject> obj = Utils::OpenHandle(this); | 3455 auto key_name = Utils::OpenHandle(*key); |
3374 i::Handle<i::Name> key_name = Utils::OpenHandle(*key); | |
3375 i::Handle<i::Object> args[] = { obj, key_name }; | 3456 i::Handle<i::Object> args[] = { obj, key_name }; |
3376 EXCEPTION_PREAMBLE(isolate); | |
3377 i::Handle<i::Object> result; | 3457 i::Handle<i::Object> result; |
3378 has_pending_exception = | 3458 has_pending_exception = |
3379 !CallV8HeapFunction(isolate, "ObjectGetOwnPropertyDescriptor", | 3459 !CallV8HeapFunction(isolate, "ObjectGetOwnPropertyDescriptor", |
3380 isolate->factory()->undefined_value(), | 3460 isolate->factory()->undefined_value(), |
3381 arraysize(args), args).ToHandle(&result); | 3461 arraysize(args), args).ToHandle(&result); |
3382 EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>()); | 3462 RETURN_ON_FAILED_EXECUTION(Value); |
3383 return Utils::ToLocal(result); | 3463 RETURN_ESCAPED(Utils::ToLocal(result)); |
3384 } | 3464 } |
3385 | 3465 |
3386 | 3466 |
| 3467 Local<Value> v8::Object::GetOwnPropertyDescriptor(Local<String> key) { |
| 3468 auto context = ContextFromHeapObject(Utils::OpenHandle(this)); |
| 3469 RETURN_TO_LOCAL_UNCHECKED(GetOwnPropertyDescriptor(context, key), Value); |
| 3470 } |
| 3471 |
| 3472 |
3387 Local<Value> v8::Object::GetPrototype() { | 3473 Local<Value> v8::Object::GetPrototype() { |
3388 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); | 3474 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); |
3389 ON_BAILOUT(isolate, "v8::Object::GetPrototype()", return Local<v8::Value>()); | 3475 ON_BAILOUT(isolate, "v8::Object::GetPrototype()", return Local<v8::Value>()); |
3390 ENTER_V8(isolate); | 3476 ENTER_V8(isolate); |
3391 i::Handle<i::Object> self = Utils::OpenHandle(this); | 3477 i::Handle<i::Object> self = Utils::OpenHandle(this); |
3392 i::PrototypeIterator iter(isolate, self); | 3478 i::PrototypeIterator iter(isolate, self); |
3393 return Utils::ToLocal(i::PrototypeIterator::GetCurrent(iter)); | 3479 return Utils::ToLocal(i::PrototypeIterator::GetCurrent(iter)); |
3394 } | 3480 } |
3395 | 3481 |
3396 | 3482 |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3540 // Copy the buffer into a heap-allocated string and return it. | 3626 // Copy the buffer into a heap-allocated string and return it. |
3541 Local<String> result = v8::String::NewFromUtf8( | 3627 Local<String> result = v8::String::NewFromUtf8( |
3542 isolate, buf.start(), String::kNormalString, buf_len); | 3628 isolate, buf.start(), String::kNormalString, buf_len); |
3543 return result; | 3629 return result; |
3544 } | 3630 } |
3545 } | 3631 } |
3546 } | 3632 } |
3547 | 3633 |
3548 | 3634 |
3549 Local<String> v8::Object::GetConstructorName() { | 3635 Local<String> v8::Object::GetConstructorName() { |
3550 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); | 3636 auto self = Utils::OpenHandle(this); |
3551 ON_BAILOUT(isolate, "v8::Object::GetConstructorName()", | |
3552 return Local<v8::String>()); | |
3553 ENTER_V8(isolate); | |
3554 i::Handle<i::JSObject> self = Utils::OpenHandle(this); | |
3555 i::Handle<i::String> name(self->constructor_name()); | 3637 i::Handle<i::String> name(self->constructor_name()); |
3556 return Utils::ToLocal(name); | 3638 return Utils::ToLocal(name); |
3557 } | 3639 } |
3558 | 3640 |
3559 | 3641 |
3560 bool v8::Object::Delete(v8::Handle<Value> key) { | 3642 Maybe<bool> v8::Object::Delete(Local<Context> context, Local<Value> key) { |
3561 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); | 3643 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Object::Delete()", bool); |
3562 ON_BAILOUT(isolate, "v8::Object::Delete()", return false); | 3644 auto self = Utils::OpenHandle(this); |
3563 ENTER_V8(isolate); | 3645 auto key_obj = Utils::OpenHandle(*key); |
3564 i::HandleScope scope(isolate); | |
3565 i::Handle<i::JSObject> self = Utils::OpenHandle(this); | |
3566 i::Handle<i::Object> key_obj = Utils::OpenHandle(*key); | |
3567 EXCEPTION_PREAMBLE(isolate); | |
3568 i::Handle<i::Object> obj; | 3646 i::Handle<i::Object> obj; |
3569 has_pending_exception = | 3647 has_pending_exception = |
3570 !DeleteObjectProperty(isolate, self, key_obj, i::SLOPPY).ToHandle(&obj); | 3648 !DeleteObjectProperty(isolate, self, key_obj, i::SLOPPY).ToHandle(&obj); |
3571 EXCEPTION_BAILOUT_CHECK(isolate, false); | 3649 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool); |
3572 return obj->IsTrue(); | 3650 return Just(obj->IsTrue()); |
3573 } | 3651 } |
3574 | 3652 |
3575 | 3653 |
| 3654 bool v8::Object::Delete(v8::Handle<Value> key) { |
| 3655 auto context = ContextFromHeapObject(Utils::OpenHandle(this)); |
| 3656 return Delete(context, key).FromMaybe(false); |
| 3657 } |
| 3658 |
| 3659 |
3576 bool v8::Object::DeletePrivate(v8::Handle<Private> key) { | 3660 bool v8::Object::DeletePrivate(v8::Handle<Private> key) { |
3577 return Delete(v8::Handle<Value>(reinterpret_cast<Value*>(*key))); | 3661 return Delete(v8::Handle<Value>(reinterpret_cast<Value*>(*key))); |
3578 } | 3662 } |
3579 | 3663 |
3580 | 3664 |
3581 bool v8::Object::Has(v8::Handle<Value> key) { | 3665 Maybe<bool> v8::Object::Has(Local<Context> context, Local<Value> key) { |
3582 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); | 3666 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Object::Get()", bool); |
3583 ON_BAILOUT(isolate, "v8::Object::Has()", return false); | 3667 auto self = Utils::OpenHandle(this); |
3584 ENTER_V8(isolate); | 3668 auto key_obj = Utils::OpenHandle(*key); |
3585 i::Handle<i::JSReceiver> self = Utils::OpenHandle(this); | |
3586 i::Handle<i::Object> key_obj = Utils::OpenHandle(*key); | |
3587 EXCEPTION_PREAMBLE(isolate); | |
3588 Maybe<bool> maybe = Nothing<bool>(); | 3669 Maybe<bool> maybe = Nothing<bool>(); |
3589 // Check if the given key is an array index. | 3670 // Check if the given key is an array index. |
3590 uint32_t index; | 3671 uint32_t index; |
3591 if (key_obj->ToArrayIndex(&index)) { | 3672 if (key_obj->ToArrayIndex(&index)) { |
3592 maybe = i::JSReceiver::HasElement(self, index); | 3673 maybe = i::JSReceiver::HasElement(self, index); |
3593 } else { | 3674 } else { |
3594 // Convert the key to a name - possibly by calling back into JavaScript. | 3675 // Convert the key to a name - possibly by calling back into JavaScript. |
3595 i::Handle<i::Name> name; | 3676 i::Handle<i::Name> name; |
3596 if (i::Runtime::ToName(isolate, key_obj).ToHandle(&name)) { | 3677 if (i::Runtime::ToName(isolate, key_obj).ToHandle(&name)) { |
3597 maybe = i::JSReceiver::HasProperty(self, name); | 3678 maybe = i::JSReceiver::HasProperty(self, name); |
3598 } | 3679 } |
3599 } | 3680 } |
3600 if (!maybe.has_value) has_pending_exception = true; | 3681 has_pending_exception = !maybe.has_value; |
3601 EXCEPTION_BAILOUT_CHECK(isolate, false); | 3682 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool); |
3602 DCHECK(maybe.has_value); | 3683 return maybe; |
3603 return maybe.value; | |
3604 } | 3684 } |
3605 | 3685 |
3606 | 3686 |
| 3687 bool v8::Object::Has(v8::Handle<Value> key) { |
| 3688 auto context = ContextFromHeapObject(Utils::OpenHandle(this)); |
| 3689 return Has(context, key).FromMaybe(false); |
| 3690 } |
| 3691 |
| 3692 |
3607 bool v8::Object::HasPrivate(v8::Handle<Private> key) { | 3693 bool v8::Object::HasPrivate(v8::Handle<Private> key) { |
3608 // TODO(rossberg): this should use HasOwnProperty, but we'd need to | 3694 // TODO(rossberg): this should use HasOwnProperty, but we'd need to |
3609 // generalise that to a (noy yet existant) Name argument first. | 3695 // generalise that to a (noy yet existant) Name argument first. |
3610 return Has(v8::Handle<Value>(reinterpret_cast<Value*>(*key))); | 3696 return Has(v8::Handle<Value>(reinterpret_cast<Value*>(*key))); |
3611 } | 3697 } |
3612 | 3698 |
3613 | 3699 |
| 3700 Maybe<bool> v8::Object::Delete(Local<Context> context, uint32_t index) { |
| 3701 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Object::DeleteProperty()", |
| 3702 bool); |
| 3703 auto self = Utils::OpenHandle(this); |
| 3704 i::Handle<i::Object> obj; |
| 3705 has_pending_exception = |
| 3706 !i::JSReceiver::DeleteElement(self, index).ToHandle(&obj); |
| 3707 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool); |
| 3708 return Just(obj->IsTrue()); |
| 3709 } |
| 3710 |
| 3711 |
3614 bool v8::Object::Delete(uint32_t index) { | 3712 bool v8::Object::Delete(uint32_t index) { |
3615 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); | 3713 auto context = ContextFromHeapObject(Utils::OpenHandle(this)); |
3616 ON_BAILOUT(isolate, "v8::Object::DeleteProperty()", | 3714 return Delete(context, index).FromMaybe(false); |
3617 return false); | 3715 } |
3618 ENTER_V8(isolate); | |
3619 HandleScope scope(reinterpret_cast<Isolate*>(isolate)); | |
3620 i::Handle<i::JSObject> self = Utils::OpenHandle(this); | |
3621 | 3716 |
3622 EXCEPTION_PREAMBLE(isolate); | 3717 |
3623 i::Handle<i::Object> obj; | 3718 Maybe<bool> v8::Object::Has(Local<Context> context, uint32_t index) { |
3624 has_pending_exception = | 3719 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Object::Get()", bool); |
3625 !i::JSReceiver::DeleteElement(self, index).ToHandle(&obj); | 3720 auto self = Utils::OpenHandle(this); |
3626 EXCEPTION_BAILOUT_CHECK(isolate, false); | 3721 auto maybe = i::JSReceiver::HasElement(self, index); |
3627 return obj->IsTrue(); | 3722 has_pending_exception = !maybe.has_value; |
| 3723 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool); |
| 3724 return maybe; |
3628 } | 3725 } |
3629 | 3726 |
3630 | 3727 |
3631 bool v8::Object::Has(uint32_t index) { | 3728 bool v8::Object::Has(uint32_t index) { |
3632 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); | 3729 auto context = ContextFromHeapObject(Utils::OpenHandle(this)); |
3633 ON_BAILOUT(isolate, "v8::Object::HasProperty()", return false); | 3730 return Has(context, index).FromMaybe(false); |
3634 i::Handle<i::JSObject> self = Utils::OpenHandle(this); | |
3635 EXCEPTION_PREAMBLE(isolate); | |
3636 Maybe<bool> maybe = i::JSReceiver::HasElement(self, index); | |
3637 has_pending_exception = !maybe.has_value; | |
3638 EXCEPTION_BAILOUT_CHECK(isolate, false); | |
3639 return maybe.value; | |
3640 } | 3731 } |
3641 | 3732 |
3642 | 3733 |
3643 template<typename Getter, typename Setter, typename Data> | 3734 template <typename Getter, typename Setter, typename Data> |
3644 static inline bool ObjectSetAccessor(Object* obj, | 3735 static Maybe<bool> ObjectSetAccessor(Local<Context> context, Object* obj, |
3645 Handle<Name> name, | 3736 Local<Name> name, Getter getter, |
3646 Getter getter, | 3737 Setter setter, Data data, |
3647 Setter setter, | |
3648 Data data, | |
3649 AccessControl settings, | 3738 AccessControl settings, |
3650 PropertyAttribute attributes) { | 3739 PropertyAttribute attributes) { |
3651 i::Isolate* isolate = Utils::OpenHandle(obj)->GetIsolate(); | 3740 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Object::SetAccessor()", bool); |
3652 ON_BAILOUT(isolate, "v8::Object::SetAccessor()", return false); | |
3653 ENTER_V8(isolate); | |
3654 i::HandleScope scope(isolate); | |
3655 v8::Handle<AccessorSignature> signature; | 3741 v8::Handle<AccessorSignature> signature; |
3656 i::Handle<i::AccessorInfo> info = MakeAccessorInfo( | 3742 auto info = MakeAccessorInfo(name, getter, setter, data, settings, attributes, |
3657 name, getter, setter, data, settings, attributes, signature); | 3743 signature); |
3658 if (info.is_null()) return false; | 3744 if (info.is_null()) return Nothing<bool>(); |
3659 bool fast = Utils::OpenHandle(obj)->HasFastProperties(); | 3745 bool fast = Utils::OpenHandle(obj)->HasFastProperties(); |
3660 i::Handle<i::Object> result; | 3746 i::Handle<i::Object> result; |
3661 ASSIGN_RETURN_ON_EXCEPTION_VALUE( | 3747 has_pending_exception = |
3662 isolate, result, | 3748 !i::JSObject::SetAccessor(Utils::OpenHandle(obj), info).ToHandle(&result); |
3663 i::JSObject::SetAccessor(Utils::OpenHandle(obj), info), | 3749 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool); |
3664 false); | 3750 if (result->IsUndefined()) return Nothing<bool>(); |
3665 if (result->IsUndefined()) return false; | |
3666 if (fast) { | 3751 if (fast) { |
3667 i::JSObject::MigrateSlowToFast(Utils::OpenHandle(obj), 0, "APISetAccessor"); | 3752 i::JSObject::MigrateSlowToFast(Utils::OpenHandle(obj), 0, "APISetAccessor"); |
3668 } | 3753 } |
3669 return true; | 3754 return Just(true); |
3670 } | 3755 } |
3671 | 3756 |
3672 | 3757 |
| 3758 Maybe<bool> Object::SetAccessor(Local<Context> context, Local<Name> name, |
| 3759 AccessorNameGetterCallback getter, |
| 3760 AccessorNameSetterCallback setter, |
| 3761 MaybeLocal<Value> data, AccessControl settings, |
| 3762 PropertyAttribute attribute) { |
| 3763 return ObjectSetAccessor(context, this, name, getter, setter, |
| 3764 data.FromMaybe(Local<Value>()), settings, attribute); |
| 3765 } |
| 3766 |
| 3767 |
3673 bool Object::SetAccessor(Handle<String> name, | 3768 bool Object::SetAccessor(Handle<String> name, |
3674 AccessorGetterCallback getter, | 3769 AccessorGetterCallback getter, |
3675 AccessorSetterCallback setter, | 3770 AccessorSetterCallback setter, |
3676 v8::Handle<Value> data, | 3771 v8::Handle<Value> data, |
3677 AccessControl settings, | 3772 AccessControl settings, |
3678 PropertyAttribute attributes) { | 3773 PropertyAttribute attributes) { |
3679 return ObjectSetAccessor( | 3774 auto context = ContextFromHeapObject(Utils::OpenHandle(this)); |
3680 this, name, getter, setter, data, settings, attributes); | 3775 return ObjectSetAccessor(context, this, name, getter, setter, data, settings, |
| 3776 attributes).FromMaybe(false); |
3681 } | 3777 } |
3682 | 3778 |
3683 | 3779 |
3684 bool Object::SetAccessor(Handle<Name> name, | 3780 bool Object::SetAccessor(Handle<Name> name, |
3685 AccessorNameGetterCallback getter, | 3781 AccessorNameGetterCallback getter, |
3686 AccessorNameSetterCallback setter, | 3782 AccessorNameSetterCallback setter, |
3687 v8::Handle<Value> data, | 3783 v8::Handle<Value> data, |
3688 AccessControl settings, | 3784 AccessControl settings, |
3689 PropertyAttribute attributes) { | 3785 PropertyAttribute attributes) { |
3690 return ObjectSetAccessor( | 3786 auto context = ContextFromHeapObject(Utils::OpenHandle(this)); |
3691 this, name, getter, setter, data, settings, attributes); | 3787 return ObjectSetAccessor(context, this, name, getter, setter, data, settings, |
| 3788 attributes).FromMaybe(false); |
3692 } | 3789 } |
3693 | 3790 |
3694 | 3791 |
3695 void Object::SetAccessorProperty(Local<Name> name, | 3792 void Object::SetAccessorProperty(Local<Name> name, |
3696 Local<Function> getter, | 3793 Local<Function> getter, |
3697 Handle<Function> setter, | 3794 Handle<Function> setter, |
3698 PropertyAttribute attribute, | 3795 PropertyAttribute attribute, |
3699 AccessControl settings) { | 3796 AccessControl settings) { |
3700 // TODO(verwaest): Remove |settings|. | 3797 // TODO(verwaest): Remove |settings|. |
3701 DCHECK_EQ(v8::DEFAULT, settings); | 3798 DCHECK_EQ(v8::DEFAULT, settings); |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3792 EXCEPTION_BAILOUT_CHECK(it->isolate(), Local<Value>()); | 3889 EXCEPTION_BAILOUT_CHECK(it->isolate(), Local<Value>()); |
3793 | 3890 |
3794 if (it->IsFound()) return Utils::ToLocal(result); | 3891 if (it->IsFound()) return Utils::ToLocal(result); |
3795 return Local<Value>(); | 3892 return Local<Value>(); |
3796 } | 3893 } |
3797 | 3894 |
3798 | 3895 |
3799 static Maybe<PropertyAttribute> GetPropertyAttributesByLookup( | 3896 static Maybe<PropertyAttribute> GetPropertyAttributesByLookup( |
3800 i::LookupIterator* it) { | 3897 i::LookupIterator* it) { |
3801 Maybe<PropertyAttributes> attr = i::JSReceiver::GetPropertyAttributes(it); | 3898 Maybe<PropertyAttributes> attr = i::JSReceiver::GetPropertyAttributes(it); |
3802 return it->IsFound() ? Just<PropertyAttribute>( | 3899 if (!it->IsFound()) return Nothing<PropertyAttribute>(); |
3803 static_cast<PropertyAttribute>(attr.value)) | 3900 return Just(static_cast<PropertyAttribute>(attr.value)); |
3804 : Nothing<PropertyAttribute>(); | |
3805 } | 3901 } |
3806 | 3902 |
3807 | 3903 |
3808 Local<Value> v8::Object::GetRealNamedPropertyInPrototypeChain( | 3904 Local<Value> v8::Object::GetRealNamedPropertyInPrototypeChain( |
3809 Handle<String> key) { | 3905 Handle<String> key) { |
3810 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); | 3906 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); |
3811 ON_BAILOUT(isolate, | 3907 ON_BAILOUT(isolate, |
3812 "v8::Object::GetRealNamedPropertyInPrototypeChain()", | 3908 "v8::Object::GetRealNamedPropertyInPrototypeChain()", |
3813 return Local<Value>()); | 3909 return Local<Value>()); |
3814 ENTER_V8(isolate); | 3910 ENTER_V8(isolate); |
(...skipping 4054 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7869 Isolate* isolate = reinterpret_cast<Isolate*>(info.GetIsolate()); | 7965 Isolate* isolate = reinterpret_cast<Isolate*>(info.GetIsolate()); |
7870 Address callback_address = | 7966 Address callback_address = |
7871 reinterpret_cast<Address>(reinterpret_cast<intptr_t>(callback)); | 7967 reinterpret_cast<Address>(reinterpret_cast<intptr_t>(callback)); |
7872 VMState<EXTERNAL> state(isolate); | 7968 VMState<EXTERNAL> state(isolate); |
7873 ExternalCallbackScope call_scope(isolate, callback_address); | 7969 ExternalCallbackScope call_scope(isolate, callback_address); |
7874 callback(info); | 7970 callback(info); |
7875 } | 7971 } |
7876 | 7972 |
7877 | 7973 |
7878 } } // namespace v8::internal | 7974 } } // namespace v8::internal |
OLD | NEW |