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