Chromium Code Reviews| 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 |