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 static Local<Context> ContextFromHeapObject(i::Handle<i::Object> obj) { |
| 2647 return reinterpret_cast<v8::Isolate*>(i::HeapObject::cast(*obj)->GetIsolate()) |
| 2648 ->GetCurrentContext(); |
| 2649 } |
| 2650 |
| 2651 |
2646 MaybeLocal<String> Value::ToString(Local<Context> context) const { | 2652 MaybeLocal<String> Value::ToString(Local<Context> context) const { |
2647 auto obj = Utils::OpenHandle(this); | 2653 auto obj = Utils::OpenHandle(this); |
2648 if (obj->IsString()) return ToApiHandle<String>(obj); | 2654 if (obj->IsString()) return ToApiHandle<String>(obj); |
2649 CONTEXT_SCOPE_GET_ISOLATE(context, "ToString"); | 2655 CONTEXT_SCOPE_GET_ISOLATE(context, "ToString"); |
2650 EXCEPTION_PREAMBLE(isolate); | 2656 EXCEPTION_PREAMBLE(isolate); |
2651 Local<String> result; | 2657 Local<String> result; |
2652 has_pending_exception = | 2658 has_pending_exception = |
2653 !ToLocal<String>(i::Execution::ToString(isolate, obj), &result); | 2659 !ToLocal<String>(i::Execution::ToString(isolate, obj), &result); |
2654 EXCEPTION_BAILOUT_CHECK(isolate, result); | 2660 EXCEPTION_BAILOUT_CHECK(isolate, result); |
2655 return result; | 2661 return result; |
(...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2982 | 2988 |
2983 | 2989 |
2984 void v8::RegExp::CheckCast(v8::Value* that) { | 2990 void v8::RegExp::CheckCast(v8::Value* that) { |
2985 i::Handle<i::Object> obj = Utils::OpenHandle(that); | 2991 i::Handle<i::Object> obj = Utils::OpenHandle(that); |
2986 Utils::ApiCheck(obj->IsJSRegExp(), | 2992 Utils::ApiCheck(obj->IsJSRegExp(), |
2987 "v8::RegExp::Cast()", | 2993 "v8::RegExp::Cast()", |
2988 "Could not convert to regular expression"); | 2994 "Could not convert to regular expression"); |
2989 } | 2995 } |
2990 | 2996 |
2991 | 2997 |
| 2998 Maybe<bool> Value::BooleanValue(Local<Context> context) const { |
| 2999 return maybe(Utils::OpenHandle(this)->BooleanValue()); |
| 3000 } |
| 3001 |
| 3002 |
2992 bool Value::BooleanValue() const { | 3003 bool Value::BooleanValue() const { |
2993 return Utils::OpenHandle(this)->BooleanValue(); | 3004 return Utils::OpenHandle(this)->BooleanValue(); |
2994 } | 3005 } |
2995 | 3006 |
2996 | 3007 |
| 3008 Maybe<double> Value::NumberValue(Local<Context> context) const { |
| 3009 auto obj = Utils::OpenHandle(this); |
| 3010 if (obj->IsNumber()) return maybe(obj->Number()); |
| 3011 CONTEXT_SCOPE_GET_ISOLATE(context, "NumberValue"); |
| 3012 EXCEPTION_PREAMBLE(isolate); |
| 3013 i::Handle<i::Object> num; |
| 3014 has_pending_exception = !i::Execution::ToNumber(isolate, obj).ToHandle(&num); |
| 3015 EXCEPTION_BAILOUT_CHECK(isolate, Maybe<double>()); |
| 3016 return maybe(num->Number()); |
| 3017 } |
| 3018 |
| 3019 |
2997 double Value::NumberValue() const { | 3020 double Value::NumberValue() const { |
2998 i::Handle<i::Object> obj = Utils::OpenHandle(this); | 3021 auto obj = Utils::OpenHandle(this); |
| 3022 if (obj->IsNumber()) return obj->Number(); |
| 3023 return NumberValue(ContextFromHeapObject(obj)) |
| 3024 .From(std::numeric_limits<double>::quiet_NaN()); |
| 3025 } |
| 3026 |
| 3027 |
| 3028 Maybe<int64_t> Value::IntegerValue(Local<Context> context) const { |
| 3029 auto obj = Utils::OpenHandle(this); |
2999 i::Handle<i::Object> num; | 3030 i::Handle<i::Object> num; |
3000 if (obj->IsNumber()) { | 3031 if (obj->IsNumber()) { |
3001 num = obj; | 3032 num = obj; |
3002 } else { | 3033 } else { |
3003 i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate(); | 3034 CONTEXT_SCOPE_GET_ISOLATE(context, "IntegerValue"); |
3004 LOG_API(isolate, "NumberValue"); | |
3005 ENTER_V8(isolate); | |
3006 EXCEPTION_PREAMBLE(isolate); | 3035 EXCEPTION_PREAMBLE(isolate); |
3007 has_pending_exception = !i::Execution::ToNumber( | 3036 has_pending_exception = |
3008 isolate, obj).ToHandle(&num); | 3037 !i::Execution::ToInteger(isolate, obj).ToHandle(&num); |
3009 EXCEPTION_BAILOUT_CHECK(isolate, std::numeric_limits<double>::quiet_NaN()); | 3038 EXCEPTION_BAILOUT_CHECK(isolate, Maybe<int64_t>()); |
3010 } | 3039 } |
3011 return num->Number(); | 3040 if (num->IsSmi()) { |
| 3041 return maybe(static_cast<int64_t>(i::Smi::cast(*num)->value())); |
| 3042 } else { |
| 3043 return maybe(static_cast<int64_t>(num->Number())); |
| 3044 } |
3012 } | 3045 } |
3013 | 3046 |
3014 | 3047 |
3015 int64_t Value::IntegerValue() const { | 3048 int64_t Value::IntegerValue() const { |
3016 i::Handle<i::Object> obj = Utils::OpenHandle(this); | 3049 auto obj = Utils::OpenHandle(this); |
| 3050 if (obj->IsNumber()) { |
| 3051 if (obj->IsSmi()) { |
| 3052 return i::Smi::cast(*obj)->value(); |
| 3053 } else { |
| 3054 return static_cast<int64_t>(obj->Number()); |
| 3055 } |
| 3056 } |
| 3057 return IntegerValue(ContextFromHeapObject(obj)).From(0); |
| 3058 } |
| 3059 |
| 3060 |
| 3061 Maybe<int32_t> Value::Int32Value(Local<Context> context) const { |
| 3062 auto obj = Utils::OpenHandle(this); |
| 3063 if (obj->IsNumber()) return maybe(NumberToInt32(*obj)); |
| 3064 CONTEXT_SCOPE_GET_ISOLATE(context, "Int32Value"); |
| 3065 EXCEPTION_PREAMBLE(isolate); |
3017 i::Handle<i::Object> num; | 3066 i::Handle<i::Object> num; |
3018 if (obj->IsNumber()) { | 3067 has_pending_exception = !i::Execution::ToInt32(isolate, obj).ToHandle(&num); |
3019 num = obj; | 3068 EXCEPTION_BAILOUT_CHECK(isolate, Maybe<int32_t>()); |
| 3069 if (num->IsSmi()) { |
| 3070 return maybe(i::Smi::cast(*num)->value()); |
3020 } else { | 3071 } else { |
3021 i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate(); | 3072 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 } | 3073 } |
| 3074 } |
| 3075 |
| 3076 |
| 3077 int32_t Value::Int32Value() const { |
| 3078 auto obj = Utils::OpenHandle(this); |
| 3079 if (obj->IsNumber()) return NumberToInt32(*obj); |
| 3080 return Int32Value(ContextFromHeapObject(obj)).From(0); |
| 3081 } |
| 3082 |
| 3083 |
| 3084 Maybe<uint32_t> Value::Uint32Value(Local<Context> context) const { |
| 3085 auto obj = Utils::OpenHandle(this); |
| 3086 if (obj->IsNumber()) return maybe(NumberToUint32(*obj)); |
| 3087 CONTEXT_SCOPE_GET_ISOLATE(context, "Uint32Value"); |
| 3088 EXCEPTION_PREAMBLE(isolate); |
| 3089 i::Handle<i::Object> num; |
| 3090 has_pending_exception = !i::Execution::ToUint32(isolate, obj).ToHandle(&num); |
| 3091 EXCEPTION_BAILOUT_CHECK(isolate, Maybe<uint32_t>()); |
3029 if (num->IsSmi()) { | 3092 if (num->IsSmi()) { |
3030 return i::Smi::cast(*num)->value(); | 3093 return maybe(static_cast<uint32_t>(i::Smi::cast(*num)->value())); |
3031 } else { | 3094 } else { |
3032 return static_cast<int64_t>(num->Number()); | 3095 return maybe(static_cast<uint32_t>(num->Number())); |
3033 } | 3096 } |
3034 } | 3097 } |
3035 | 3098 |
3036 | 3099 |
| 3100 uint32_t Value::Uint32Value() const { |
| 3101 auto obj = Utils::OpenHandle(this); |
| 3102 if (obj->IsNumber()) return NumberToUint32(*obj); |
| 3103 return Uint32Value(ContextFromHeapObject(obj)).From(0); |
| 3104 } |
| 3105 |
| 3106 |
3037 Local<Uint32> Value::ToArrayIndex() const { | 3107 Local<Uint32> Value::ToArrayIndex() const { |
3038 i::Handle<i::Object> obj = Utils::OpenHandle(this); | 3108 i::Handle<i::Object> obj = Utils::OpenHandle(this); |
3039 if (obj->IsSmi()) { | 3109 if (obj->IsSmi()) { |
3040 if (i::Smi::cast(*obj)->value() >= 0) return Utils::Uint32ToLocal(obj); | 3110 if (i::Smi::cast(*obj)->value() >= 0) return Utils::Uint32ToLocal(obj); |
3041 return Local<Uint32>(); | 3111 return Local<Uint32>(); |
3042 } | 3112 } |
3043 i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate(); | 3113 i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate(); |
3044 LOG_API(isolate, "ToArrayIndex"); | 3114 LOG_API(isolate, "ToArrayIndex"); |
3045 ENTER_V8(isolate); | 3115 ENTER_V8(isolate); |
3046 EXCEPTION_PREAMBLE(isolate); | 3116 EXCEPTION_PREAMBLE(isolate); |
3047 i::Handle<i::Object> string_obj; | 3117 i::Handle<i::Object> string_obj; |
3048 has_pending_exception = !i::Execution::ToString( | 3118 has_pending_exception = !i::Execution::ToString( |
3049 isolate, obj).ToHandle(&string_obj); | 3119 isolate, obj).ToHandle(&string_obj); |
3050 EXCEPTION_BAILOUT_CHECK(isolate, Local<Uint32>()); | 3120 EXCEPTION_BAILOUT_CHECK(isolate, Local<Uint32>()); |
3051 i::Handle<i::String> str = i::Handle<i::String>::cast(string_obj); | 3121 i::Handle<i::String> str = i::Handle<i::String>::cast(string_obj); |
3052 uint32_t index; | 3122 uint32_t index; |
3053 if (str->AsArrayIndex(&index)) { | 3123 if (str->AsArrayIndex(&index)) { |
3054 i::Handle<i::Object> value; | 3124 i::Handle<i::Object> value; |
3055 if (index <= static_cast<uint32_t>(i::Smi::kMaxValue)) { | 3125 if (index <= static_cast<uint32_t>(i::Smi::kMaxValue)) { |
3056 value = i::Handle<i::Object>(i::Smi::FromInt(index), isolate); | 3126 value = i::Handle<i::Object>(i::Smi::FromInt(index), isolate); |
3057 } else { | 3127 } else { |
3058 value = isolate->factory()->NewNumber(index); | 3128 value = isolate->factory()->NewNumber(index); |
3059 } | 3129 } |
3060 return Utils::Uint32ToLocal(value); | 3130 return Utils::Uint32ToLocal(value); |
3061 } | 3131 } |
3062 return Local<Uint32>(); | 3132 return Local<Uint32>(); |
3063 } | 3133 } |
3064 | 3134 |
3065 | 3135 |
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 { | 3136 bool Value::Equals(Handle<Value> that) const { |
3088 i::Handle<i::Object> obj = Utils::OpenHandle(this, true); | 3137 i::Handle<i::Object> obj = Utils::OpenHandle(this, true); |
3089 i::Handle<i::Object> other = Utils::OpenHandle(*that); | 3138 i::Handle<i::Object> other = Utils::OpenHandle(*that); |
3090 if (obj->IsSmi() && other->IsSmi()) { | 3139 if (obj->IsSmi() && other->IsSmi()) { |
3091 return obj->Number() == other->Number(); | 3140 return obj->Number() == other->Number(); |
3092 } | 3141 } |
3093 i::Object* ho = obj->IsSmi() ? *other : *obj; | 3142 i::Object* ho = obj->IsSmi() ? *other : *obj; |
3094 i::Isolate* isolate = i::HeapObject::cast(ho)->GetIsolate(); | 3143 i::Isolate* isolate = i::HeapObject::cast(ho)->GetIsolate(); |
3095 if (!Utils::ApiCheck(!obj.is_null() && !that.IsEmpty(), | 3144 if (!Utils::ApiCheck(!obj.is_null() && !that.IsEmpty(), |
3096 "v8::Value::Equals()", | 3145 "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(), | 3206 if (!Utils::ApiCheck(!obj.is_null() && !that.IsEmpty(), |
3158 "v8::Value::SameValue()", | 3207 "v8::Value::SameValue()", |
3159 "Reading from empty handle")) { | 3208 "Reading from empty handle")) { |
3160 return false; | 3209 return false; |
3161 } | 3210 } |
3162 i::Handle<i::Object> other = Utils::OpenHandle(*that); | 3211 i::Handle<i::Object> other = Utils::OpenHandle(*that); |
3163 return obj->SameValue(*other); | 3212 return obj->SameValue(*other); |
3164 } | 3213 } |
3165 | 3214 |
3166 | 3215 |
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) { | 3216 bool v8::Object::Set(v8::Handle<Value> key, v8::Handle<Value> value) { |
3190 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); | 3217 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); |
3191 ON_BAILOUT(isolate, "v8::Object::Set()", return false); | 3218 ON_BAILOUT(isolate, "v8::Object::Set()", return false); |
3192 ENTER_V8(isolate); | 3219 ENTER_V8(isolate); |
3193 i::HandleScope scope(isolate); | 3220 i::HandleScope scope(isolate); |
3194 i::Handle<i::Object> self = Utils::OpenHandle(this); | 3221 i::Handle<i::Object> self = Utils::OpenHandle(this); |
3195 i::Handle<i::Object> key_obj = Utils::OpenHandle(*key); | 3222 i::Handle<i::Object> key_obj = Utils::OpenHandle(*key); |
3196 i::Handle<i::Object> value_obj = Utils::OpenHandle(*value); | 3223 i::Handle<i::Object> value_obj = Utils::OpenHandle(*value); |
3197 EXCEPTION_PREAMBLE(isolate); | 3224 EXCEPTION_PREAMBLE(isolate); |
3198 has_pending_exception = | 3225 has_pending_exception = |
(...skipping 4646 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7845 Isolate* isolate = reinterpret_cast<Isolate*>(info.GetIsolate()); | 7872 Isolate* isolate = reinterpret_cast<Isolate*>(info.GetIsolate()); |
7846 Address callback_address = | 7873 Address callback_address = |
7847 reinterpret_cast<Address>(reinterpret_cast<intptr_t>(callback)); | 7874 reinterpret_cast<Address>(reinterpret_cast<intptr_t>(callback)); |
7848 VMState<EXTERNAL> state(isolate); | 7875 VMState<EXTERNAL> state(isolate); |
7849 ExternalCallbackScope call_scope(isolate, callback_address); | 7876 ExternalCallbackScope call_scope(isolate, callback_address); |
7850 callback(info); | 7877 callback(info); |
7851 } | 7878 } |
7852 | 7879 |
7853 | 7880 |
7854 } } // namespace v8::internal | 7881 } } // namespace v8::internal |
OLD | NEW |