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 2625 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2636 | 2636 |
2637 #define RETURN_TO_LOCAL_UNCHECKED(maybe_local, T) \ | 2637 #define RETURN_TO_LOCAL_UNCHECKED(maybe_local, T) \ |
2638 do { \ | 2638 do { \ |
2639 Local<T> result; \ | 2639 Local<T> result; \ |
2640 bool ignored = maybe_local.ToLocal(&result); \ | 2640 bool ignored = maybe_local.ToLocal(&result); \ |
2641 USE(ignored); \ | 2641 USE(ignored); \ |
2642 return result; \ | 2642 return result; \ |
2643 } while (false); | 2643 } while (false); |
2644 | 2644 |
2645 | 2645 |
2646 #define RETURN_MAYBE_DEFAULT(maybe_value, default_value, T) \ | |
Sven Panne
2015/02/27 12:18:03
I think this should actually be a member function
| |
2647 do { \ | |
2648 T result; \ | |
2649 if (!maybe_value.ToValue(&result)) return default_value; \ | |
2650 return result; \ | |
2651 } while (false); | |
2652 | |
2653 | |
2654 static Local<Context> ContextFromHeapObject(i::Handle<i::Object> obj) { | |
2655 return reinterpret_cast<v8::Isolate*>(i::HeapObject::cast(*obj)->GetIsolate()) | |
2656 ->GetCurrentContext(); | |
2657 } | |
2658 | |
2659 | |
2646 MaybeLocal<String> Value::ToString(Local<Context> context) const { | 2660 MaybeLocal<String> Value::ToString(Local<Context> context) const { |
2647 auto obj = Utils::OpenHandle(this); | 2661 auto obj = Utils::OpenHandle(this); |
2648 if (obj->IsString()) return ToApiHandle<String>(obj); | 2662 if (obj->IsString()) return ToApiHandle<String>(obj); |
2649 CONTEXT_SCOPE_GET_ISOLATE(context, "ToString"); | 2663 CONTEXT_SCOPE_GET_ISOLATE(context, "ToString"); |
2650 EXCEPTION_PREAMBLE(isolate); | 2664 EXCEPTION_PREAMBLE(isolate); |
2651 Local<String> result; | 2665 Local<String> result; |
2652 has_pending_exception = | 2666 has_pending_exception = |
2653 !ToLocal<String>(i::Execution::ToString(isolate, obj), &result); | 2667 !ToLocal<String>(i::Execution::ToString(isolate, obj), &result); |
2654 EXCEPTION_BAILOUT_CHECK(isolate, result); | 2668 EXCEPTION_BAILOUT_CHECK(isolate, result); |
2655 return result; | 2669 return result; |
(...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2982 | 2996 |
2983 | 2997 |
2984 void v8::RegExp::CheckCast(v8::Value* that) { | 2998 void v8::RegExp::CheckCast(v8::Value* that) { |
2985 i::Handle<i::Object> obj = Utils::OpenHandle(that); | 2999 i::Handle<i::Object> obj = Utils::OpenHandle(that); |
2986 Utils::ApiCheck(obj->IsJSRegExp(), | 3000 Utils::ApiCheck(obj->IsJSRegExp(), |
2987 "v8::RegExp::Cast()", | 3001 "v8::RegExp::Cast()", |
2988 "Could not convert to regular expression"); | 3002 "Could not convert to regular expression"); |
2989 } | 3003 } |
2990 | 3004 |
2991 | 3005 |
3006 Maybe<bool> Value::BooleanValue(Local<Context> context) const { | |
3007 return maybe(Utils::OpenHandle(this)->BooleanValue()); | |
3008 } | |
3009 | |
3010 | |
2992 bool Value::BooleanValue() const { | 3011 bool Value::BooleanValue() const { |
2993 return Utils::OpenHandle(this)->BooleanValue(); | 3012 return Utils::OpenHandle(this)->BooleanValue(); |
2994 } | 3013 } |
2995 | 3014 |
2996 | 3015 |
3016 Maybe<double> Value::NumberValue(Local<Context> context) const { | |
3017 auto obj = Utils::OpenHandle(this); | |
3018 if (obj->IsNumber()) return maybe(obj->Number()); | |
3019 CONTEXT_SCOPE_GET_ISOLATE(context, "NumberValue"); | |
3020 EXCEPTION_PREAMBLE(isolate); | |
3021 i::Handle<i::Object> num; | |
3022 has_pending_exception = !i::Execution::ToNumber(isolate, obj).ToHandle(&num); | |
3023 EXCEPTION_BAILOUT_CHECK(isolate, Maybe<double>()); | |
3024 return maybe(num->Number()); | |
3025 } | |
3026 | |
3027 | |
2997 double Value::NumberValue() const { | 3028 double Value::NumberValue() const { |
2998 i::Handle<i::Object> obj = Utils::OpenHandle(this); | 3029 auto obj = Utils::OpenHandle(this); |
3030 if (obj->IsNumber()) return obj->Number(); | |
3031 RETURN_MAYBE_DEFAULT(NumberValue(ContextFromHeapObject(obj)), | |
3032 std::numeric_limits<double>::quiet_NaN(), double); | |
3033 } | |
3034 | |
3035 | |
3036 Maybe<int64_t> Value::IntegerValue(Local<Context> context) const { | |
3037 auto obj = Utils::OpenHandle(this); | |
2999 i::Handle<i::Object> num; | 3038 i::Handle<i::Object> num; |
3000 if (obj->IsNumber()) { | 3039 if (obj->IsNumber()) { |
3001 num = obj; | 3040 num = obj; |
3002 } else { | 3041 } else { |
3003 i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate(); | 3042 CONTEXT_SCOPE_GET_ISOLATE(context, "IntegerValue"); |
3004 LOG_API(isolate, "NumberValue"); | |
3005 ENTER_V8(isolate); | |
3006 EXCEPTION_PREAMBLE(isolate); | 3043 EXCEPTION_PREAMBLE(isolate); |
3007 has_pending_exception = !i::Execution::ToNumber( | 3044 has_pending_exception = |
3008 isolate, obj).ToHandle(&num); | 3045 !i::Execution::ToInteger(isolate, obj).ToHandle(&num); |
3009 EXCEPTION_BAILOUT_CHECK(isolate, std::numeric_limits<double>::quiet_NaN()); | 3046 EXCEPTION_BAILOUT_CHECK(isolate, Maybe<int64_t>()); |
3010 } | 3047 } |
3011 return num->Number(); | 3048 if (num->IsSmi()) { |
3049 return maybe(static_cast<int64_t>(i::Smi::cast(*num)->value())); | |
3050 } else { | |
3051 return maybe(static_cast<int64_t>(num->Number())); | |
3052 } | |
3012 } | 3053 } |
3013 | 3054 |
3014 | 3055 |
3015 int64_t Value::IntegerValue() const { | 3056 int64_t Value::IntegerValue() const { |
3016 i::Handle<i::Object> obj = Utils::OpenHandle(this); | 3057 auto obj = Utils::OpenHandle(this); |
3058 if (obj->IsNumber()) { | |
3059 if (obj->IsSmi()) { | |
3060 return i::Smi::cast(*obj)->value(); | |
3061 } else { | |
3062 return static_cast<int64_t>(obj->Number()); | |
3063 } | |
3064 } | |
3065 RETURN_MAYBE_DEFAULT(IntegerValue(ContextFromHeapObject(obj)), 0, int64_t); | |
3066 } | |
3067 | |
3068 | |
3069 Maybe<int32_t> Value::Int32Value(Local<Context> context) const { | |
3070 auto obj = Utils::OpenHandle(this); | |
3071 if (obj->IsNumber()) return maybe(NumberToInt32(*obj)); | |
3072 CONTEXT_SCOPE_GET_ISOLATE(context, "Int32Value"); | |
3073 EXCEPTION_PREAMBLE(isolate); | |
3017 i::Handle<i::Object> num; | 3074 i::Handle<i::Object> num; |
3018 if (obj->IsNumber()) { | 3075 has_pending_exception = !i::Execution::ToInt32(isolate, obj).ToHandle(&num); |
3019 num = obj; | 3076 EXCEPTION_BAILOUT_CHECK(isolate, Maybe<int32_t>()); |
3077 if (num->IsSmi()) { | |
3078 return maybe(i::Smi::cast(*num)->value()); | |
3020 } else { | 3079 } else { |
3021 i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate(); | 3080 return maybe(static_cast<int32_t>(num->Number())); |
3022 LOG_API(isolate, "IntegerValue"); | |
3023 ENTER_V8(isolate); | |
3024 EXCEPTION_PREAMBLE(isolate); | |
3025 has_pending_exception = !i::Execution::ToInteger( | |
3026 isolate, obj).ToHandle(&num); | |
3027 EXCEPTION_BAILOUT_CHECK(isolate, 0); | |
3028 } | 3081 } |
3082 } | |
3083 | |
3084 | |
3085 int32_t Value::Int32Value() const { | |
3086 auto obj = Utils::OpenHandle(this); | |
3087 if (obj->IsNumber()) return NumberToInt32(*obj); | |
3088 RETURN_MAYBE_DEFAULT(Int32Value(ContextFromHeapObject(obj)), 0, int32_t); | |
3089 } | |
3090 | |
3091 | |
3092 Maybe<uint32_t> Value::Uint32Value(Local<Context> context) const { | |
3093 auto obj = Utils::OpenHandle(this); | |
3094 if (obj->IsNumber()) return maybe(NumberToUint32(*obj)); | |
3095 CONTEXT_SCOPE_GET_ISOLATE(context, "Uint32Value"); | |
3096 EXCEPTION_PREAMBLE(isolate); | |
3097 i::Handle<i::Object> num; | |
3098 has_pending_exception = !i::Execution::ToUint32(isolate, obj).ToHandle(&num); | |
3099 EXCEPTION_BAILOUT_CHECK(isolate, Maybe<uint32_t>()); | |
3029 if (num->IsSmi()) { | 3100 if (num->IsSmi()) { |
3030 return i::Smi::cast(*num)->value(); | 3101 return maybe(static_cast<uint32_t>(i::Smi::cast(*num)->value())); |
3031 } else { | 3102 } else { |
3032 return static_cast<int64_t>(num->Number()); | 3103 return maybe(static_cast<uint32_t>(num->Number())); |
3033 } | 3104 } |
3034 } | 3105 } |
3035 | 3106 |
3036 | 3107 |
3108 uint32_t Value::Uint32Value() const { | |
3109 auto obj = Utils::OpenHandle(this); | |
3110 if (obj->IsNumber()) return NumberToUint32(*obj); | |
3111 RETURN_MAYBE_DEFAULT(Uint32Value(ContextFromHeapObject(obj)), 0, uint32_t); | |
3112 } | |
3113 | |
3114 | |
3037 Local<Uint32> Value::ToArrayIndex() const { | 3115 Local<Uint32> Value::ToArrayIndex() const { |
3038 i::Handle<i::Object> obj = Utils::OpenHandle(this); | 3116 i::Handle<i::Object> obj = Utils::OpenHandle(this); |
3039 if (obj->IsSmi()) { | 3117 if (obj->IsSmi()) { |
3040 if (i::Smi::cast(*obj)->value() >= 0) return Utils::Uint32ToLocal(obj); | 3118 if (i::Smi::cast(*obj)->value() >= 0) return Utils::Uint32ToLocal(obj); |
3041 return Local<Uint32>(); | 3119 return Local<Uint32>(); |
3042 } | 3120 } |
3043 i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate(); | 3121 i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate(); |
3044 LOG_API(isolate, "ToArrayIndex"); | 3122 LOG_API(isolate, "ToArrayIndex"); |
3045 ENTER_V8(isolate); | 3123 ENTER_V8(isolate); |
3046 EXCEPTION_PREAMBLE(isolate); | 3124 EXCEPTION_PREAMBLE(isolate); |
3047 i::Handle<i::Object> string_obj; | 3125 i::Handle<i::Object> string_obj; |
3048 has_pending_exception = !i::Execution::ToString( | 3126 has_pending_exception = !i::Execution::ToString( |
3049 isolate, obj).ToHandle(&string_obj); | 3127 isolate, obj).ToHandle(&string_obj); |
3050 EXCEPTION_BAILOUT_CHECK(isolate, Local<Uint32>()); | 3128 EXCEPTION_BAILOUT_CHECK(isolate, Local<Uint32>()); |
3051 i::Handle<i::String> str = i::Handle<i::String>::cast(string_obj); | 3129 i::Handle<i::String> str = i::Handle<i::String>::cast(string_obj); |
3052 uint32_t index; | 3130 uint32_t index; |
3053 if (str->AsArrayIndex(&index)) { | 3131 if (str->AsArrayIndex(&index)) { |
3054 i::Handle<i::Object> value; | 3132 i::Handle<i::Object> value; |
3055 if (index <= static_cast<uint32_t>(i::Smi::kMaxValue)) { | 3133 if (index <= static_cast<uint32_t>(i::Smi::kMaxValue)) { |
3056 value = i::Handle<i::Object>(i::Smi::FromInt(index), isolate); | 3134 value = i::Handle<i::Object>(i::Smi::FromInt(index), isolate); |
3057 } else { | 3135 } else { |
3058 value = isolate->factory()->NewNumber(index); | 3136 value = isolate->factory()->NewNumber(index); |
3059 } | 3137 } |
3060 return Utils::Uint32ToLocal(value); | 3138 return Utils::Uint32ToLocal(value); |
3061 } | 3139 } |
3062 return Local<Uint32>(); | 3140 return Local<Uint32>(); |
3063 } | 3141 } |
3064 | 3142 |
3065 | 3143 |
3066 int32_t Value::Int32Value() const { | |
3067 i::Handle<i::Object> obj = Utils::OpenHandle(this); | |
3068 if (obj->IsNumber()) { | |
3069 return NumberToInt32(*obj); | |
3070 } else { | |
3071 i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate(); | |
3072 LOG_API(isolate, "Int32Value (slow)"); | |
3073 ENTER_V8(isolate); | |
3074 EXCEPTION_PREAMBLE(isolate); | |
3075 i::Handle<i::Object> num; | |
3076 has_pending_exception = !i::Execution::ToInt32(isolate, obj).ToHandle(&num); | |
3077 EXCEPTION_BAILOUT_CHECK(isolate, 0); | |
3078 if (num->IsSmi()) { | |
3079 return i::Smi::cast(*num)->value(); | |
3080 } else { | |
3081 return static_cast<int32_t>(num->Number()); | |
3082 } | |
3083 } | |
3084 } | |
3085 | |
3086 | |
3087 bool Value::Equals(Handle<Value> that) const { | 3144 bool Value::Equals(Handle<Value> that) const { |
3088 i::Handle<i::Object> obj = Utils::OpenHandle(this, true); | 3145 i::Handle<i::Object> obj = Utils::OpenHandle(this, true); |
3089 i::Handle<i::Object> other = Utils::OpenHandle(*that); | 3146 i::Handle<i::Object> other = Utils::OpenHandle(*that); |
3090 if (obj->IsSmi() && other->IsSmi()) { | 3147 if (obj->IsSmi() && other->IsSmi()) { |
3091 return obj->Number() == other->Number(); | 3148 return obj->Number() == other->Number(); |
3092 } | 3149 } |
3093 i::Object* ho = obj->IsSmi() ? *other : *obj; | 3150 i::Object* ho = obj->IsSmi() ? *other : *obj; |
3094 i::Isolate* isolate = i::HeapObject::cast(ho)->GetIsolate(); | 3151 i::Isolate* isolate = i::HeapObject::cast(ho)->GetIsolate(); |
3095 if (!Utils::ApiCheck(!obj.is_null() && !that.IsEmpty(), | 3152 if (!Utils::ApiCheck(!obj.is_null() && !that.IsEmpty(), |
3096 "v8::Value::Equals()", | 3153 "v8::Value::Equals()", |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3157 if (!Utils::ApiCheck(!obj.is_null() && !that.IsEmpty(), | 3214 if (!Utils::ApiCheck(!obj.is_null() && !that.IsEmpty(), |
3158 "v8::Value::SameValue()", | 3215 "v8::Value::SameValue()", |
3159 "Reading from empty handle")) { | 3216 "Reading from empty handle")) { |
3160 return false; | 3217 return false; |
3161 } | 3218 } |
3162 i::Handle<i::Object> other = Utils::OpenHandle(*that); | 3219 i::Handle<i::Object> other = Utils::OpenHandle(*that); |
3163 return obj->SameValue(*other); | 3220 return obj->SameValue(*other); |
3164 } | 3221 } |
3165 | 3222 |
3166 | 3223 |
3167 uint32_t Value::Uint32Value() const { | |
3168 i::Handle<i::Object> obj = Utils::OpenHandle(this); | |
3169 if (obj->IsNumber()) { | |
3170 return NumberToUint32(*obj); | |
3171 } else { | |
3172 i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate(); | |
3173 LOG_API(isolate, "Uint32Value"); | |
3174 ENTER_V8(isolate); | |
3175 EXCEPTION_PREAMBLE(isolate); | |
3176 i::Handle<i::Object> num; | |
3177 has_pending_exception = !i::Execution::ToUint32( | |
3178 isolate, obj).ToHandle(&num); | |
3179 EXCEPTION_BAILOUT_CHECK(isolate, 0); | |
3180 if (num->IsSmi()) { | |
3181 return i::Smi::cast(*num)->value(); | |
3182 } else { | |
3183 return static_cast<uint32_t>(num->Number()); | |
3184 } | |
3185 } | |
3186 } | |
3187 | |
3188 | |
3189 bool v8::Object::Set(v8::Handle<Value> key, v8::Handle<Value> value) { | 3224 bool v8::Object::Set(v8::Handle<Value> key, v8::Handle<Value> value) { |
3190 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); | 3225 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); |
3191 ON_BAILOUT(isolate, "v8::Object::Set()", return false); | 3226 ON_BAILOUT(isolate, "v8::Object::Set()", return false); |
3192 ENTER_V8(isolate); | 3227 ENTER_V8(isolate); |
3193 i::HandleScope scope(isolate); | 3228 i::HandleScope scope(isolate); |
3194 i::Handle<i::Object> self = Utils::OpenHandle(this); | 3229 i::Handle<i::Object> self = Utils::OpenHandle(this); |
3195 i::Handle<i::Object> key_obj = Utils::OpenHandle(*key); | 3230 i::Handle<i::Object> key_obj = Utils::OpenHandle(*key); |
3196 i::Handle<i::Object> value_obj = Utils::OpenHandle(*value); | 3231 i::Handle<i::Object> value_obj = Utils::OpenHandle(*value); |
3197 EXCEPTION_PREAMBLE(isolate); | 3232 EXCEPTION_PREAMBLE(isolate); |
3198 has_pending_exception = | 3233 has_pending_exception = |
(...skipping 4646 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7845 Isolate* isolate = reinterpret_cast<Isolate*>(info.GetIsolate()); | 7880 Isolate* isolate = reinterpret_cast<Isolate*>(info.GetIsolate()); |
7846 Address callback_address = | 7881 Address callback_address = |
7847 reinterpret_cast<Address>(reinterpret_cast<intptr_t>(callback)); | 7882 reinterpret_cast<Address>(reinterpret_cast<intptr_t>(callback)); |
7848 VMState<EXTERNAL> state(isolate); | 7883 VMState<EXTERNAL> state(isolate); |
7849 ExternalCallbackScope call_scope(isolate, callback_address); | 7884 ExternalCallbackScope call_scope(isolate, callback_address); |
7850 callback(info); | 7885 callback(info); |
7851 } | 7886 } |
7852 | 7887 |
7853 | 7888 |
7854 } } // namespace v8::internal | 7889 } } // namespace v8::internal |
OLD | NEW |