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 |