| OLD | NEW |
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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/objects.h" | 5 #include "src/objects.h" |
| 6 | 6 |
| 7 #include <cmath> | 7 #include <cmath> |
| 8 #include <iomanip> | 8 #include <iomanip> |
| 9 #include <sstream> | 9 #include <sstream> |
| 10 | 10 |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 108 } | 108 } |
| 109 constructor = handle( | 109 constructor = handle( |
| 110 JSFunction::cast(native_context->get(constructor_function_index)), | 110 JSFunction::cast(native_context->get(constructor_function_index)), |
| 111 isolate); | 111 isolate); |
| 112 } | 112 } |
| 113 Handle<JSObject> result = isolate->factory()->NewJSObject(constructor); | 113 Handle<JSObject> result = isolate->factory()->NewJSObject(constructor); |
| 114 Handle<JSValue>::cast(result)->set_value(*object); | 114 Handle<JSValue>::cast(result)->set_value(*object); |
| 115 return result; | 115 return result; |
| 116 } | 116 } |
| 117 | 117 |
| 118 // ES6 section 9.2.1.2, OrdinaryCallBindThis for sloppy callee. |
| 119 // static |
| 120 MaybeHandle<JSReceiver> Object::ConvertReceiver(Isolate* isolate, |
| 121 Handle<Object> object) { |
| 122 if (object->IsJSReceiver()) return Handle<JSReceiver>::cast(object); |
| 123 if (*object == isolate->heap()->null_value() || |
| 124 *object == isolate->heap()->undefined_value()) { |
| 125 return handle(isolate->global_proxy(), isolate); |
| 126 } |
| 127 return Object::ToObject(isolate, object); |
| 128 } |
| 118 | 129 |
| 119 // static | 130 // static |
| 120 MaybeHandle<Object> Object::ToNumber(Handle<Object> input) { | 131 MaybeHandle<Object> Object::ToNumber(Handle<Object> input) { |
| 121 while (true) { | 132 while (true) { |
| 122 if (input->IsNumber()) { | 133 if (input->IsNumber()) { |
| 123 return input; | 134 return input; |
| 124 } | 135 } |
| 125 if (input->IsString()) { | 136 if (input->IsString()) { |
| 126 return String::ToNumber(Handle<String>::cast(input)); | 137 return String::ToNumber(Handle<String>::cast(input)); |
| 127 } | 138 } |
| (...skipping 925 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1053 THROW_NEW_ERROR(isolate, | 1064 THROW_NEW_ERROR(isolate, |
| 1054 NewTypeError(MessageTemplate::kIncompatibleMethodReceiver, | 1065 NewTypeError(MessageTemplate::kIncompatibleMethodReceiver, |
| 1055 name, receiver), | 1066 name, receiver), |
| 1056 Object); | 1067 Object); |
| 1057 } | 1068 } |
| 1058 | 1069 |
| 1059 v8::AccessorNameGetterCallback call_fun = | 1070 v8::AccessorNameGetterCallback call_fun = |
| 1060 v8::ToCData<v8::AccessorNameGetterCallback>(info->getter()); | 1071 v8::ToCData<v8::AccessorNameGetterCallback>(info->getter()); |
| 1061 if (call_fun == nullptr) return isolate->factory()->undefined_value(); | 1072 if (call_fun == nullptr) return isolate->factory()->undefined_value(); |
| 1062 | 1073 |
| 1074 if (info->is_sloppy() && !receiver->IsJSReceiver()) { |
| 1075 ASSIGN_RETURN_ON_EXCEPTION(isolate, receiver, |
| 1076 Object::ConvertReceiver(isolate, receiver), |
| 1077 Object); |
| 1078 } |
| 1079 |
| 1063 PropertyCallbackArguments args(isolate, info->data(), *receiver, *holder, | 1080 PropertyCallbackArguments args(isolate, info->data(), *receiver, *holder, |
| 1064 Object::DONT_THROW); | 1081 Object::DONT_THROW); |
| 1065 Handle<Object> result = args.Call(call_fun, name); | 1082 Handle<Object> result = args.Call(call_fun, name); |
| 1066 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); | 1083 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); |
| 1067 if (result.is_null()) return ReadAbsentProperty(isolate, receiver, name); | 1084 if (result.is_null()) return ReadAbsentProperty(isolate, receiver, name); |
| 1068 // Rebox handle before return. | 1085 // Rebox handle before return. |
| 1069 return handle(*result, isolate); | 1086 return handle(*result, isolate); |
| 1070 } | 1087 } |
| 1071 | 1088 |
| 1072 // Regular accessor. | 1089 // Regular accessor. |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1123 return Nothing<bool>(); | 1140 return Nothing<bool>(); |
| 1124 } | 1141 } |
| 1125 | 1142 |
| 1126 v8::AccessorNameSetterCallback call_fun = | 1143 v8::AccessorNameSetterCallback call_fun = |
| 1127 v8::ToCData<v8::AccessorNameSetterCallback>(info->setter()); | 1144 v8::ToCData<v8::AccessorNameSetterCallback>(info->setter()); |
| 1128 // TODO(verwaest): We should not get here anymore once all AccessorInfos are | 1145 // TODO(verwaest): We should not get here anymore once all AccessorInfos are |
| 1129 // marked as special_data_property. They cannot both be writable and not | 1146 // marked as special_data_property. They cannot both be writable and not |
| 1130 // have a setter. | 1147 // have a setter. |
| 1131 if (call_fun == nullptr) return Just(true); | 1148 if (call_fun == nullptr) return Just(true); |
| 1132 | 1149 |
| 1150 if (info->is_sloppy() && !receiver->IsJSReceiver()) { |
| 1151 ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
| 1152 isolate, receiver, Object::ConvertReceiver(isolate, receiver), |
| 1153 Nothing<bool>()); |
| 1154 } |
| 1155 |
| 1133 PropertyCallbackArguments args(isolate, info->data(), *receiver, *holder, | 1156 PropertyCallbackArguments args(isolate, info->data(), *receiver, *holder, |
| 1134 should_throw); | 1157 should_throw); |
| 1135 args.Call(call_fun, name, value); | 1158 args.Call(call_fun, name, value); |
| 1136 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>()); | 1159 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>()); |
| 1137 return Just(true); | 1160 return Just(true); |
| 1138 } | 1161 } |
| 1139 | 1162 |
| 1140 // Regular accessor. | 1163 // Regular accessor. |
| 1141 Handle<Object> setter(AccessorPair::cast(*structure)->setter(), isolate); | 1164 Handle<Object> setter(AccessorPair::cast(*structure)->setter(), isolate); |
| 1142 if (setter->IsFunctionTemplateInfo()) { | 1165 if (setter->IsFunctionTemplateInfo()) { |
| (...skipping 2934 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4077 // Make sure that the top context does not change when doing callbacks or | 4100 // Make sure that the top context does not change when doing callbacks or |
| 4078 // interceptor calls. | 4101 // interceptor calls. |
| 4079 AssertNoContextChange ncc(isolate); | 4102 AssertNoContextChange ncc(isolate); |
| 4080 | 4103 |
| 4081 DCHECK_EQ(LookupIterator::INTERCEPTOR, it->state()); | 4104 DCHECK_EQ(LookupIterator::INTERCEPTOR, it->state()); |
| 4082 Handle<InterceptorInfo> interceptor(it->GetInterceptor()); | 4105 Handle<InterceptorInfo> interceptor(it->GetInterceptor()); |
| 4083 if (interceptor->setter()->IsUndefined()) return Just(false); | 4106 if (interceptor->setter()->IsUndefined()) return Just(false); |
| 4084 | 4107 |
| 4085 Handle<JSObject> holder = it->GetHolder<JSObject>(); | 4108 Handle<JSObject> holder = it->GetHolder<JSObject>(); |
| 4086 bool result; | 4109 bool result; |
| 4087 PropertyCallbackArguments args(isolate, interceptor->data(), | 4110 Handle<Object> receiver = it->GetReceiver(); |
| 4088 *it->GetReceiver(), *holder, should_throw); | 4111 if (!receiver->IsJSReceiver()) { |
| 4112 ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, receiver, |
| 4113 Object::ConvertReceiver(isolate, receiver), |
| 4114 Nothing<bool>()); |
| 4115 } |
| 4116 PropertyCallbackArguments args(isolate, interceptor->data(), *receiver, |
| 4117 *holder, should_throw); |
| 4089 | 4118 |
| 4090 if (it->IsElement()) { | 4119 if (it->IsElement()) { |
| 4091 uint32_t index = it->index(); | 4120 uint32_t index = it->index(); |
| 4092 v8::IndexedPropertySetterCallback setter = | 4121 v8::IndexedPropertySetterCallback setter = |
| 4093 v8::ToCData<v8::IndexedPropertySetterCallback>(interceptor->setter()); | 4122 v8::ToCData<v8::IndexedPropertySetterCallback>(interceptor->setter()); |
| 4094 // TODO(neis): In the future, we may want to actually return the | 4123 // TODO(neis): In the future, we may want to actually return the |
| 4095 // interceptor's result, which then should be a boolean. | 4124 // interceptor's result, which then should be a boolean. |
| 4096 result = !args.Call(setter, index, value).is_null(); | 4125 result = !args.Call(setter, index, value).is_null(); |
| 4097 } else { | 4126 } else { |
| 4098 Handle<Name> name = it->name(); | 4127 Handle<Name> name = it->name(); |
| (...skipping 1310 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5409 // callbacks or interceptor calls. | 5438 // callbacks or interceptor calls. |
| 5410 AssertNoContextChange ncc(isolate); | 5439 AssertNoContextChange ncc(isolate); |
| 5411 HandleScope scope(isolate); | 5440 HandleScope scope(isolate); |
| 5412 | 5441 |
| 5413 Handle<JSObject> holder = it->GetHolder<JSObject>(); | 5442 Handle<JSObject> holder = it->GetHolder<JSObject>(); |
| 5414 Handle<InterceptorInfo> interceptor(it->GetInterceptor()); | 5443 Handle<InterceptorInfo> interceptor(it->GetInterceptor()); |
| 5415 if (!it->IsElement() && it->name()->IsSymbol() && | 5444 if (!it->IsElement() && it->name()->IsSymbol() && |
| 5416 !interceptor->can_intercept_symbols()) { | 5445 !interceptor->can_intercept_symbols()) { |
| 5417 return Just(ABSENT); | 5446 return Just(ABSENT); |
| 5418 } | 5447 } |
| 5419 PropertyCallbackArguments args(isolate, interceptor->data(), | 5448 Handle<Object> receiver = it->GetReceiver(); |
| 5420 *it->GetReceiver(), *holder, | 5449 if (!receiver->IsJSReceiver()) { |
| 5421 Object::DONT_THROW); | 5450 ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, receiver, |
| 5451 Object::ConvertReceiver(isolate, receiver), |
| 5452 Nothing<PropertyAttributes>()); |
| 5453 } |
| 5454 PropertyCallbackArguments args(isolate, interceptor->data(), *receiver, |
| 5455 *holder, Object::DONT_THROW); |
| 5422 if (!interceptor->query()->IsUndefined()) { | 5456 if (!interceptor->query()->IsUndefined()) { |
| 5423 Handle<Object> result; | 5457 Handle<Object> result; |
| 5424 if (it->IsElement()) { | 5458 if (it->IsElement()) { |
| 5425 uint32_t index = it->index(); | 5459 uint32_t index = it->index(); |
| 5426 v8::IndexedPropertyQueryCallback query = | 5460 v8::IndexedPropertyQueryCallback query = |
| 5427 v8::ToCData<v8::IndexedPropertyQueryCallback>(interceptor->query()); | 5461 v8::ToCData<v8::IndexedPropertyQueryCallback>(interceptor->query()); |
| 5428 result = args.Call(query, index); | 5462 result = args.Call(query, index); |
| 5429 } else { | 5463 } else { |
| 5430 Handle<Name> name = it->name(); | 5464 Handle<Name> name = it->name(); |
| 5431 DCHECK(!name->IsPrivate()); | 5465 DCHECK(!name->IsPrivate()); |
| (...skipping 579 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6011 Isolate* isolate = it->isolate(); | 6045 Isolate* isolate = it->isolate(); |
| 6012 // Make sure that the top context does not change when doing callbacks or | 6046 // Make sure that the top context does not change when doing callbacks or |
| 6013 // interceptor calls. | 6047 // interceptor calls. |
| 6014 AssertNoContextChange ncc(isolate); | 6048 AssertNoContextChange ncc(isolate); |
| 6015 | 6049 |
| 6016 DCHECK_EQ(LookupIterator::INTERCEPTOR, it->state()); | 6050 DCHECK_EQ(LookupIterator::INTERCEPTOR, it->state()); |
| 6017 Handle<InterceptorInfo> interceptor(it->GetInterceptor()); | 6051 Handle<InterceptorInfo> interceptor(it->GetInterceptor()); |
| 6018 if (interceptor->deleter()->IsUndefined()) return Nothing<bool>(); | 6052 if (interceptor->deleter()->IsUndefined()) return Nothing<bool>(); |
| 6019 | 6053 |
| 6020 Handle<JSObject> holder = it->GetHolder<JSObject>(); | 6054 Handle<JSObject> holder = it->GetHolder<JSObject>(); |
| 6055 Handle<Object> receiver = it->GetReceiver(); |
| 6056 if (!receiver->IsJSReceiver()) { |
| 6057 ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, receiver, |
| 6058 Object::ConvertReceiver(isolate, receiver), |
| 6059 Nothing<bool>()); |
| 6060 } |
| 6021 | 6061 |
| 6022 PropertyCallbackArguments args(isolate, interceptor->data(), | 6062 PropertyCallbackArguments args(isolate, interceptor->data(), *receiver, |
| 6023 *it->GetReceiver(), *holder, should_throw); | 6063 *holder, should_throw); |
| 6024 Handle<Object> result; | 6064 Handle<Object> result; |
| 6025 if (it->IsElement()) { | 6065 if (it->IsElement()) { |
| 6026 uint32_t index = it->index(); | 6066 uint32_t index = it->index(); |
| 6027 v8::IndexedPropertyDeleterCallback deleter = | 6067 v8::IndexedPropertyDeleterCallback deleter = |
| 6028 v8::ToCData<v8::IndexedPropertyDeleterCallback>(interceptor->deleter()); | 6068 v8::ToCData<v8::IndexedPropertyDeleterCallback>(interceptor->deleter()); |
| 6029 result = args.Call(deleter, index); | 6069 result = args.Call(deleter, index); |
| 6030 } else if (it->name()->IsSymbol() && !interceptor->can_intercept_symbols()) { | 6070 } else if (it->name()->IsSymbol() && !interceptor->can_intercept_symbols()) { |
| 6031 return Nothing<bool>(); | 6071 return Nothing<bool>(); |
| 6032 } else { | 6072 } else { |
| 6033 Handle<Name> name = it->name(); | 6073 Handle<Name> name = it->name(); |
| (...skipping 10244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 16278 AssertNoContextChange ncc(isolate); | 16318 AssertNoContextChange ncc(isolate); |
| 16279 | 16319 |
| 16280 DCHECK_EQ(LookupIterator::INTERCEPTOR, it->state()); | 16320 DCHECK_EQ(LookupIterator::INTERCEPTOR, it->state()); |
| 16281 Handle<InterceptorInfo> interceptor = it->GetInterceptor(); | 16321 Handle<InterceptorInfo> interceptor = it->GetInterceptor(); |
| 16282 if (interceptor->getter()->IsUndefined()) { | 16322 if (interceptor->getter()->IsUndefined()) { |
| 16283 return isolate->factory()->undefined_value(); | 16323 return isolate->factory()->undefined_value(); |
| 16284 } | 16324 } |
| 16285 | 16325 |
| 16286 Handle<JSObject> holder = it->GetHolder<JSObject>(); | 16326 Handle<JSObject> holder = it->GetHolder<JSObject>(); |
| 16287 Handle<Object> result; | 16327 Handle<Object> result; |
| 16288 PropertyCallbackArguments args(isolate, interceptor->data(), | 16328 Handle<Object> receiver = it->GetReceiver(); |
| 16289 *it->GetReceiver(), *holder, | 16329 if (!receiver->IsJSReceiver()) { |
| 16290 Object::DONT_THROW); | 16330 ASSIGN_RETURN_ON_EXCEPTION( |
| 16331 isolate, receiver, Object::ConvertReceiver(isolate, receiver), Object); |
| 16332 } |
| 16333 PropertyCallbackArguments args(isolate, interceptor->data(), *receiver, |
| 16334 *holder, Object::DONT_THROW); |
| 16291 | 16335 |
| 16292 if (it->IsElement()) { | 16336 if (it->IsElement()) { |
| 16293 uint32_t index = it->index(); | 16337 uint32_t index = it->index(); |
| 16294 v8::IndexedPropertyGetterCallback getter = | 16338 v8::IndexedPropertyGetterCallback getter = |
| 16295 v8::ToCData<v8::IndexedPropertyGetterCallback>(interceptor->getter()); | 16339 v8::ToCData<v8::IndexedPropertyGetterCallback>(interceptor->getter()); |
| 16296 result = args.Call(getter, index); | 16340 result = args.Call(getter, index); |
| 16297 } else { | 16341 } else { |
| 16298 Handle<Name> name = it->name(); | 16342 Handle<Name> name = it->name(); |
| 16299 DCHECK(!name->IsPrivate()); | 16343 DCHECK(!name->IsPrivate()); |
| 16300 | 16344 |
| (...skipping 3485 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 19786 if (cell->value() != *new_value) { | 19830 if (cell->value() != *new_value) { |
| 19787 cell->set_value(*new_value); | 19831 cell->set_value(*new_value); |
| 19788 Isolate* isolate = cell->GetIsolate(); | 19832 Isolate* isolate = cell->GetIsolate(); |
| 19789 cell->dependent_code()->DeoptimizeDependentCodeGroup( | 19833 cell->dependent_code()->DeoptimizeDependentCodeGroup( |
| 19790 isolate, DependentCode::kPropertyCellChangedGroup); | 19834 isolate, DependentCode::kPropertyCellChangedGroup); |
| 19791 } | 19835 } |
| 19792 } | 19836 } |
| 19793 | 19837 |
| 19794 } // namespace internal | 19838 } // namespace internal |
| 19795 } // namespace v8 | 19839 } // namespace v8 |
| OLD | NEW |