| 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 1339 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1350 } else if (it->state() == LookupIterator::INTERCEPTOR) { | 1350 } else if (it->state() == LookupIterator::INTERCEPTOR) { |
| 1351 if (it->GetInterceptor()->all_can_read()) return true; | 1351 if (it->GetInterceptor()->all_can_read()) return true; |
| 1352 } else if (it->state() == LookupIterator::JSPROXY) { | 1352 } else if (it->state() == LookupIterator::JSPROXY) { |
| 1353 // Stop lookupiterating. And no, AllCanNotRead. | 1353 // Stop lookupiterating. And no, AllCanNotRead. |
| 1354 return false; | 1354 return false; |
| 1355 } | 1355 } |
| 1356 } | 1356 } |
| 1357 return false; | 1357 return false; |
| 1358 } | 1358 } |
| 1359 | 1359 |
| 1360 namespace { |
| 1361 |
| 1362 MaybeHandle<Object> GetPropertyWithInterceptorInternal( |
| 1363 LookupIterator* it, Handle<InterceptorInfo> interceptor, bool* done) { |
| 1364 *done = false; |
| 1365 Isolate* isolate = it->isolate(); |
| 1366 // Make sure that the top context does not change when doing callbacks or |
| 1367 // interceptor calls. |
| 1368 AssertNoContextChange ncc(isolate); |
| 1369 |
| 1370 if (interceptor->getter()->IsUndefined(isolate)) { |
| 1371 return isolate->factory()->undefined_value(); |
| 1372 } |
| 1373 |
| 1374 Handle<JSObject> holder = it->GetHolder<JSObject>(); |
| 1375 Handle<Object> result; |
| 1376 Handle<Object> receiver = it->GetReceiver(); |
| 1377 if (!receiver->IsJSReceiver()) { |
| 1378 ASSIGN_RETURN_ON_EXCEPTION( |
| 1379 isolate, receiver, Object::ConvertReceiver(isolate, receiver), Object); |
| 1380 } |
| 1381 PropertyCallbackArguments args(isolate, interceptor->data(), *receiver, |
| 1382 *holder, Object::DONT_THROW); |
| 1383 |
| 1384 if (it->IsElement()) { |
| 1385 uint32_t index = it->index(); |
| 1386 v8::IndexedPropertyGetterCallback getter = |
| 1387 v8::ToCData<v8::IndexedPropertyGetterCallback>(interceptor->getter()); |
| 1388 result = args.Call(getter, index); |
| 1389 } else { |
| 1390 Handle<Name> name = it->name(); |
| 1391 DCHECK(!name->IsPrivate()); |
| 1392 |
| 1393 if (name->IsSymbol() && !interceptor->can_intercept_symbols()) { |
| 1394 return isolate->factory()->undefined_value(); |
| 1395 } |
| 1396 |
| 1397 v8::GenericNamedPropertyGetterCallback getter = |
| 1398 v8::ToCData<v8::GenericNamedPropertyGetterCallback>( |
| 1399 interceptor->getter()); |
| 1400 result = args.Call(getter, name); |
| 1401 } |
| 1402 |
| 1403 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); |
| 1404 if (result.is_null()) return isolate->factory()->undefined_value(); |
| 1405 *done = true; |
| 1406 // Rebox handle before return |
| 1407 return handle(*result, isolate); |
| 1408 } |
| 1409 |
| 1410 Maybe<PropertyAttributes> GetPropertyAttributesWithInterceptorInternal( |
| 1411 LookupIterator* it, Handle<InterceptorInfo> interceptor) { |
| 1412 Isolate* isolate = it->isolate(); |
| 1413 // Make sure that the top context does not change when doing |
| 1414 // callbacks or interceptor calls. |
| 1415 AssertNoContextChange ncc(isolate); |
| 1416 HandleScope scope(isolate); |
| 1417 |
| 1418 Handle<JSObject> holder = it->GetHolder<JSObject>(); |
| 1419 if (!it->IsElement() && it->name()->IsSymbol() && |
| 1420 !interceptor->can_intercept_symbols()) { |
| 1421 return Just(ABSENT); |
| 1422 } |
| 1423 Handle<Object> receiver = it->GetReceiver(); |
| 1424 if (!receiver->IsJSReceiver()) { |
| 1425 ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, receiver, |
| 1426 Object::ConvertReceiver(isolate, receiver), |
| 1427 Nothing<PropertyAttributes>()); |
| 1428 } |
| 1429 PropertyCallbackArguments args(isolate, interceptor->data(), *receiver, |
| 1430 *holder, Object::DONT_THROW); |
| 1431 if (!interceptor->query()->IsUndefined(isolate)) { |
| 1432 Handle<Object> result; |
| 1433 if (it->IsElement()) { |
| 1434 uint32_t index = it->index(); |
| 1435 v8::IndexedPropertyQueryCallback query = |
| 1436 v8::ToCData<v8::IndexedPropertyQueryCallback>(interceptor->query()); |
| 1437 result = args.Call(query, index); |
| 1438 } else { |
| 1439 Handle<Name> name = it->name(); |
| 1440 DCHECK(!name->IsPrivate()); |
| 1441 v8::GenericNamedPropertyQueryCallback query = |
| 1442 v8::ToCData<v8::GenericNamedPropertyQueryCallback>( |
| 1443 interceptor->query()); |
| 1444 result = args.Call(query, name); |
| 1445 } |
| 1446 if (!result.is_null()) { |
| 1447 int32_t value; |
| 1448 CHECK(result->ToInt32(&value)); |
| 1449 return Just(static_cast<PropertyAttributes>(value)); |
| 1450 } |
| 1451 } else if (!interceptor->getter()->IsUndefined(isolate)) { |
| 1452 // TODO(verwaest): Use GetPropertyWithInterceptor? |
| 1453 Handle<Object> result; |
| 1454 if (it->IsElement()) { |
| 1455 uint32_t index = it->index(); |
| 1456 v8::IndexedPropertyGetterCallback getter = |
| 1457 v8::ToCData<v8::IndexedPropertyGetterCallback>(interceptor->getter()); |
| 1458 result = args.Call(getter, index); |
| 1459 } else { |
| 1460 Handle<Name> name = it->name(); |
| 1461 DCHECK(!name->IsPrivate()); |
| 1462 v8::GenericNamedPropertyGetterCallback getter = |
| 1463 v8::ToCData<v8::GenericNamedPropertyGetterCallback>( |
| 1464 interceptor->getter()); |
| 1465 result = args.Call(getter, name); |
| 1466 } |
| 1467 if (!result.is_null()) return Just(DONT_ENUM); |
| 1468 } |
| 1469 |
| 1470 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<PropertyAttributes>()); |
| 1471 return Just(ABSENT); |
| 1472 } |
| 1473 |
| 1474 Maybe<bool> SetPropertyWithInterceptorInternal( |
| 1475 LookupIterator* it, Handle<InterceptorInfo> interceptor, |
| 1476 Object::ShouldThrow should_throw, Handle<Object> value) { |
| 1477 Isolate* isolate = it->isolate(); |
| 1478 // Make sure that the top context does not change when doing callbacks or |
| 1479 // interceptor calls. |
| 1480 AssertNoContextChange ncc(isolate); |
| 1481 |
| 1482 if (interceptor->setter()->IsUndefined(isolate)) return Just(false); |
| 1483 |
| 1484 Handle<JSObject> holder = it->GetHolder<JSObject>(); |
| 1485 bool result; |
| 1486 Handle<Object> receiver = it->GetReceiver(); |
| 1487 if (!receiver->IsJSReceiver()) { |
| 1488 ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, receiver, |
| 1489 Object::ConvertReceiver(isolate, receiver), |
| 1490 Nothing<bool>()); |
| 1491 } |
| 1492 PropertyCallbackArguments args(isolate, interceptor->data(), *receiver, |
| 1493 *holder, should_throw); |
| 1494 |
| 1495 if (it->IsElement()) { |
| 1496 uint32_t index = it->index(); |
| 1497 v8::IndexedPropertySetterCallback setter = |
| 1498 v8::ToCData<v8::IndexedPropertySetterCallback>(interceptor->setter()); |
| 1499 // TODO(neis): In the future, we may want to actually return the |
| 1500 // interceptor's result, which then should be a boolean. |
| 1501 result = !args.Call(setter, index, value).is_null(); |
| 1502 } else { |
| 1503 Handle<Name> name = it->name(); |
| 1504 DCHECK(!name->IsPrivate()); |
| 1505 |
| 1506 if (name->IsSymbol() && !interceptor->can_intercept_symbols()) { |
| 1507 return Just(false); |
| 1508 } |
| 1509 |
| 1510 v8::GenericNamedPropertySetterCallback setter = |
| 1511 v8::ToCData<v8::GenericNamedPropertySetterCallback>( |
| 1512 interceptor->setter()); |
| 1513 result = !args.Call(setter, name, value).is_null(); |
| 1514 } |
| 1515 |
| 1516 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(it->isolate(), Nothing<bool>()); |
| 1517 return Just(result); |
| 1518 } |
| 1519 |
| 1520 } // namespace |
| 1360 | 1521 |
| 1361 MaybeHandle<Object> JSObject::GetPropertyWithFailedAccessCheck( | 1522 MaybeHandle<Object> JSObject::GetPropertyWithFailedAccessCheck( |
| 1362 LookupIterator* it) { | 1523 LookupIterator* it) { |
| 1524 Isolate* isolate = it->isolate(); |
| 1363 Handle<JSObject> checked = it->GetHolder<JSObject>(); | 1525 Handle<JSObject> checked = it->GetHolder<JSObject>(); |
| 1364 while (AllCanRead(it)) { | 1526 Handle<InterceptorInfo> interceptor = |
| 1365 if (it->state() == LookupIterator::ACCESSOR) { | 1527 it->GetInterceptorForFailedAccessCheck(); |
| 1366 return GetPropertyWithAccessor(it); | 1528 if (interceptor.is_null()) { |
| 1529 while (AllCanRead(it)) { |
| 1530 if (it->state() == LookupIterator::ACCESSOR) { |
| 1531 return GetPropertyWithAccessor(it); |
| 1532 } |
| 1533 DCHECK_EQ(LookupIterator::INTERCEPTOR, it->state()); |
| 1534 bool done; |
| 1535 Handle<Object> result; |
| 1536 ASSIGN_RETURN_ON_EXCEPTION(isolate, result, |
| 1537 GetPropertyWithInterceptor(it, &done), Object); |
| 1538 if (done) return result; |
| 1367 } | 1539 } |
| 1368 DCHECK_EQ(LookupIterator::INTERCEPTOR, it->state()); | 1540 } else { |
| 1541 MaybeHandle<Object> result; |
| 1369 bool done; | 1542 bool done; |
| 1370 Handle<Object> result; | 1543 result = GetPropertyWithInterceptorInternal(it, interceptor, &done); |
| 1371 ASSIGN_RETURN_ON_EXCEPTION(it->isolate(), result, | 1544 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); |
| 1372 GetPropertyWithInterceptor(it, &done), Object); | |
| 1373 if (done) return result; | 1545 if (done) return result; |
| 1374 } | 1546 } |
| 1375 | 1547 |
| 1376 // Cross-Origin [[Get]] of Well-Known Symbols does not throw, and returns | 1548 // Cross-Origin [[Get]] of Well-Known Symbols does not throw, and returns |
| 1377 // undefined. | 1549 // undefined. |
| 1378 Handle<Name> name = it->GetName(); | 1550 Handle<Name> name = it->GetName(); |
| 1379 if (name->IsSymbol() && Symbol::cast(*name)->is_well_known_symbol()) { | 1551 if (name->IsSymbol() && Symbol::cast(*name)->is_well_known_symbol()) { |
| 1380 return it->factory()->undefined_value(); | 1552 return it->factory()->undefined_value(); |
| 1381 } | 1553 } |
| 1382 | 1554 |
| 1383 it->isolate()->ReportFailedAccessCheck(checked); | 1555 isolate->ReportFailedAccessCheck(checked); |
| 1384 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(it->isolate(), Object); | 1556 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); |
| 1385 return it->factory()->undefined_value(); | 1557 return it->factory()->undefined_value(); |
| 1386 } | 1558 } |
| 1387 | 1559 |
| 1388 | 1560 |
| 1389 Maybe<PropertyAttributes> JSObject::GetPropertyAttributesWithFailedAccessCheck( | 1561 Maybe<PropertyAttributes> JSObject::GetPropertyAttributesWithFailedAccessCheck( |
| 1390 LookupIterator* it) { | 1562 LookupIterator* it) { |
| 1563 Isolate* isolate = it->isolate(); |
| 1391 Handle<JSObject> checked = it->GetHolder<JSObject>(); | 1564 Handle<JSObject> checked = it->GetHolder<JSObject>(); |
| 1392 while (AllCanRead(it)) { | 1565 Handle<InterceptorInfo> interceptor = |
| 1393 if (it->state() == LookupIterator::ACCESSOR) { | 1566 it->GetInterceptorForFailedAccessCheck(); |
| 1394 return Just(it->property_attributes()); | 1567 if (interceptor.is_null()) { |
| 1568 while (AllCanRead(it)) { |
| 1569 if (it->state() == LookupIterator::ACCESSOR) { |
| 1570 return Just(it->property_attributes()); |
| 1571 } |
| 1572 DCHECK_EQ(LookupIterator::INTERCEPTOR, it->state()); |
| 1573 auto result = GetPropertyAttributesWithInterceptor(it); |
| 1574 if (isolate->has_scheduled_exception()) break; |
| 1575 if (result.IsJust() && result.FromJust() != ABSENT) return result; |
| 1395 } | 1576 } |
| 1396 DCHECK_EQ(LookupIterator::INTERCEPTOR, it->state()); | 1577 } else { |
| 1397 auto result = GetPropertyAttributesWithInterceptor(it); | 1578 Maybe<PropertyAttributes> result = |
| 1398 if (it->isolate()->has_scheduled_exception()) break; | 1579 GetPropertyAttributesWithInterceptorInternal(it, interceptor); |
| 1399 if (result.IsJust() && result.FromJust() != ABSENT) return result; | 1580 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<PropertyAttributes>()); |
| 1581 if (result.FromMaybe(ABSENT) != ABSENT) return result; |
| 1400 } | 1582 } |
| 1401 it->isolate()->ReportFailedAccessCheck(checked); | 1583 isolate->ReportFailedAccessCheck(checked); |
| 1402 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(it->isolate(), | 1584 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<PropertyAttributes>()); |
| 1403 Nothing<PropertyAttributes>()); | |
| 1404 return Just(ABSENT); | 1585 return Just(ABSENT); |
| 1405 } | 1586 } |
| 1406 | 1587 |
| 1407 | 1588 |
| 1408 // static | 1589 // static |
| 1409 bool JSObject::AllCanWrite(LookupIterator* it) { | 1590 bool JSObject::AllCanWrite(LookupIterator* it) { |
| 1410 for (; it->IsFound() && it->state() != LookupIterator::JSPROXY; it->Next()) { | 1591 for (; it->IsFound() && it->state() != LookupIterator::JSPROXY; it->Next()) { |
| 1411 if (it->state() == LookupIterator::ACCESSOR) { | 1592 if (it->state() == LookupIterator::ACCESSOR) { |
| 1412 Handle<Object> accessors = it->GetAccessors(); | 1593 Handle<Object> accessors = it->GetAccessors(); |
| 1413 if (accessors->IsAccessorInfo()) { | 1594 if (accessors->IsAccessorInfo()) { |
| 1414 if (AccessorInfo::cast(*accessors)->all_can_write()) return true; | 1595 if (AccessorInfo::cast(*accessors)->all_can_write()) return true; |
| 1415 } | 1596 } |
| 1416 } | 1597 } |
| 1417 } | 1598 } |
| 1418 return false; | 1599 return false; |
| 1419 } | 1600 } |
| 1420 | 1601 |
| 1421 | 1602 |
| 1422 Maybe<bool> JSObject::SetPropertyWithFailedAccessCheck( | 1603 Maybe<bool> JSObject::SetPropertyWithFailedAccessCheck( |
| 1423 LookupIterator* it, Handle<Object> value, ShouldThrow should_throw) { | 1604 LookupIterator* it, Handle<Object> value, ShouldThrow should_throw) { |
| 1605 Isolate* isolate = it->isolate(); |
| 1424 Handle<JSObject> checked = it->GetHolder<JSObject>(); | 1606 Handle<JSObject> checked = it->GetHolder<JSObject>(); |
| 1425 if (AllCanWrite(it)) { | 1607 Handle<InterceptorInfo> interceptor = |
| 1426 return SetPropertyWithAccessor(it, value, should_throw); | 1608 it->GetInterceptorForFailedAccessCheck(); |
| 1609 if (interceptor.is_null()) { |
| 1610 if (AllCanWrite(it)) { |
| 1611 return SetPropertyWithAccessor(it, value, should_throw); |
| 1612 } |
| 1613 } else { |
| 1614 Maybe<bool> result = SetPropertyWithInterceptorInternal( |
| 1615 it, interceptor, should_throw, value); |
| 1616 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>()); |
| 1617 if (result.IsJust()) return result; |
| 1427 } | 1618 } |
| 1428 | 1619 |
| 1429 it->isolate()->ReportFailedAccessCheck(checked); | 1620 isolate->ReportFailedAccessCheck(checked); |
| 1430 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(it->isolate(), Nothing<bool>()); | 1621 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>()); |
| 1431 return Just(true); | 1622 return Just(true); |
| 1432 } | 1623 } |
| 1433 | 1624 |
| 1434 | 1625 |
| 1435 void JSObject::SetNormalizedProperty(Handle<JSObject> object, | 1626 void JSObject::SetNormalizedProperty(Handle<JSObject> object, |
| 1436 Handle<Name> name, | 1627 Handle<Name> name, |
| 1437 Handle<Object> value, | 1628 Handle<Object> value, |
| 1438 PropertyDetails details) { | 1629 PropertyDetails details) { |
| 1439 DCHECK(!object->HasFastProperties()); | 1630 DCHECK(!object->HasFastProperties()); |
| 1440 if (!name->IsUniqueName()) { | 1631 if (!name->IsUniqueName()) { |
| (...skipping 2769 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4210 | 4401 |
| 4211 | 4402 |
| 4212 // static | 4403 // static |
| 4213 Handle<Map> Map::Update(Handle<Map> map) { | 4404 Handle<Map> Map::Update(Handle<Map> map) { |
| 4214 if (!map->is_deprecated()) return map; | 4405 if (!map->is_deprecated()) return map; |
| 4215 return ReconfigureProperty(map, -1, kData, NONE, Representation::None(), | 4406 return ReconfigureProperty(map, -1, kData, NONE, Representation::None(), |
| 4216 FieldType::None(map->GetIsolate()), | 4407 FieldType::None(map->GetIsolate()), |
| 4217 ALLOW_IN_DESCRIPTOR); | 4408 ALLOW_IN_DESCRIPTOR); |
| 4218 } | 4409 } |
| 4219 | 4410 |
| 4220 | |
| 4221 Maybe<bool> JSObject::SetPropertyWithInterceptor(LookupIterator* it, | 4411 Maybe<bool> JSObject::SetPropertyWithInterceptor(LookupIterator* it, |
| 4222 ShouldThrow should_throw, | 4412 ShouldThrow should_throw, |
| 4223 Handle<Object> value) { | 4413 Handle<Object> value) { |
| 4224 Isolate* isolate = it->isolate(); | |
| 4225 // Make sure that the top context does not change when doing callbacks or | |
| 4226 // interceptor calls. | |
| 4227 AssertNoContextChange ncc(isolate); | |
| 4228 | |
| 4229 DCHECK_EQ(LookupIterator::INTERCEPTOR, it->state()); | 4414 DCHECK_EQ(LookupIterator::INTERCEPTOR, it->state()); |
| 4230 Handle<InterceptorInfo> interceptor(it->GetInterceptor()); | 4415 return SetPropertyWithInterceptorInternal(it, it->GetInterceptor(), |
| 4231 if (interceptor->setter()->IsUndefined(isolate)) return Just(false); | 4416 should_throw, value); |
| 4232 | |
| 4233 Handle<JSObject> holder = it->GetHolder<JSObject>(); | |
| 4234 bool result; | |
| 4235 Handle<Object> receiver = it->GetReceiver(); | |
| 4236 if (!receiver->IsJSReceiver()) { | |
| 4237 ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, receiver, | |
| 4238 Object::ConvertReceiver(isolate, receiver), | |
| 4239 Nothing<bool>()); | |
| 4240 } | |
| 4241 PropertyCallbackArguments args(isolate, interceptor->data(), *receiver, | |
| 4242 *holder, should_throw); | |
| 4243 | |
| 4244 if (it->IsElement()) { | |
| 4245 uint32_t index = it->index(); | |
| 4246 v8::IndexedPropertySetterCallback setter = | |
| 4247 v8::ToCData<v8::IndexedPropertySetterCallback>(interceptor->setter()); | |
| 4248 // TODO(neis): In the future, we may want to actually return the | |
| 4249 // interceptor's result, which then should be a boolean. | |
| 4250 result = !args.Call(setter, index, value).is_null(); | |
| 4251 } else { | |
| 4252 Handle<Name> name = it->name(); | |
| 4253 DCHECK(!name->IsPrivate()); | |
| 4254 | |
| 4255 if (name->IsSymbol() && !interceptor->can_intercept_symbols()) { | |
| 4256 return Just(false); | |
| 4257 } | |
| 4258 | |
| 4259 v8::GenericNamedPropertySetterCallback setter = | |
| 4260 v8::ToCData<v8::GenericNamedPropertySetterCallback>( | |
| 4261 interceptor->setter()); | |
| 4262 result = !args.Call(setter, name, value).is_null(); | |
| 4263 } | |
| 4264 | |
| 4265 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(it->isolate(), Nothing<bool>()); | |
| 4266 return Just(result); | |
| 4267 } | 4417 } |
| 4268 | 4418 |
| 4269 | |
| 4270 MaybeHandle<Object> Object::SetProperty(Handle<Object> object, | 4419 MaybeHandle<Object> Object::SetProperty(Handle<Object> object, |
| 4271 Handle<Name> name, Handle<Object> value, | 4420 Handle<Name> name, Handle<Object> value, |
| 4272 LanguageMode language_mode, | 4421 LanguageMode language_mode, |
| 4273 StoreFromKeyed store_mode) { | 4422 StoreFromKeyed store_mode) { |
| 4274 LookupIterator it(object, name); | 4423 LookupIterator it(object, name); |
| 4275 MAYBE_RETURN_NULL(SetProperty(&it, value, language_mode, store_mode)); | 4424 MAYBE_RETURN_NULL(SetProperty(&it, value, language_mode, store_mode)); |
| 4276 return value; | 4425 return value; |
| 4277 } | 4426 } |
| 4278 | 4427 |
| 4279 | 4428 |
| (...skipping 1238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5518 | 5667 |
| 5519 MaybeHandle<Object> JSObject::DefinePropertyOrElementIgnoreAttributes( | 5668 MaybeHandle<Object> JSObject::DefinePropertyOrElementIgnoreAttributes( |
| 5520 Handle<JSObject> object, Handle<Name> name, Handle<Object> value, | 5669 Handle<JSObject> object, Handle<Name> name, Handle<Object> value, |
| 5521 PropertyAttributes attributes) { | 5670 PropertyAttributes attributes) { |
| 5522 Isolate* isolate = object->GetIsolate(); | 5671 Isolate* isolate = object->GetIsolate(); |
| 5523 LookupIterator it = LookupIterator::PropertyOrElement( | 5672 LookupIterator it = LookupIterator::PropertyOrElement( |
| 5524 isolate, object, name, object, LookupIterator::OWN); | 5673 isolate, object, name, object, LookupIterator::OWN); |
| 5525 return DefineOwnPropertyIgnoreAttributes(&it, value, attributes); | 5674 return DefineOwnPropertyIgnoreAttributes(&it, value, attributes); |
| 5526 } | 5675 } |
| 5527 | 5676 |
| 5528 | |
| 5529 Maybe<PropertyAttributes> JSObject::GetPropertyAttributesWithInterceptor( | 5677 Maybe<PropertyAttributes> JSObject::GetPropertyAttributesWithInterceptor( |
| 5530 LookupIterator* it) { | 5678 LookupIterator* it) { |
| 5531 Isolate* isolate = it->isolate(); | 5679 return GetPropertyAttributesWithInterceptorInternal(it, it->GetInterceptor()); |
| 5532 // Make sure that the top context does not change when doing | |
| 5533 // callbacks or interceptor calls. | |
| 5534 AssertNoContextChange ncc(isolate); | |
| 5535 HandleScope scope(isolate); | |
| 5536 | |
| 5537 Handle<JSObject> holder = it->GetHolder<JSObject>(); | |
| 5538 Handle<InterceptorInfo> interceptor(it->GetInterceptor()); | |
| 5539 if (!it->IsElement() && it->name()->IsSymbol() && | |
| 5540 !interceptor->can_intercept_symbols()) { | |
| 5541 return Just(ABSENT); | |
| 5542 } | |
| 5543 Handle<Object> receiver = it->GetReceiver(); | |
| 5544 if (!receiver->IsJSReceiver()) { | |
| 5545 ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, receiver, | |
| 5546 Object::ConvertReceiver(isolate, receiver), | |
| 5547 Nothing<PropertyAttributes>()); | |
| 5548 } | |
| 5549 PropertyCallbackArguments args(isolate, interceptor->data(), *receiver, | |
| 5550 *holder, Object::DONT_THROW); | |
| 5551 if (!interceptor->query()->IsUndefined(isolate)) { | |
| 5552 Handle<Object> result; | |
| 5553 if (it->IsElement()) { | |
| 5554 uint32_t index = it->index(); | |
| 5555 v8::IndexedPropertyQueryCallback query = | |
| 5556 v8::ToCData<v8::IndexedPropertyQueryCallback>(interceptor->query()); | |
| 5557 result = args.Call(query, index); | |
| 5558 } else { | |
| 5559 Handle<Name> name = it->name(); | |
| 5560 DCHECK(!name->IsPrivate()); | |
| 5561 v8::GenericNamedPropertyQueryCallback query = | |
| 5562 v8::ToCData<v8::GenericNamedPropertyQueryCallback>( | |
| 5563 interceptor->query()); | |
| 5564 result = args.Call(query, name); | |
| 5565 } | |
| 5566 if (!result.is_null()) { | |
| 5567 int32_t value; | |
| 5568 CHECK(result->ToInt32(&value)); | |
| 5569 return Just(static_cast<PropertyAttributes>(value)); | |
| 5570 } | |
| 5571 } else if (!interceptor->getter()->IsUndefined(isolate)) { | |
| 5572 // TODO(verwaest): Use GetPropertyWithInterceptor? | |
| 5573 Handle<Object> result; | |
| 5574 if (it->IsElement()) { | |
| 5575 uint32_t index = it->index(); | |
| 5576 v8::IndexedPropertyGetterCallback getter = | |
| 5577 v8::ToCData<v8::IndexedPropertyGetterCallback>(interceptor->getter()); | |
| 5578 result = args.Call(getter, index); | |
| 5579 } else { | |
| 5580 Handle<Name> name = it->name(); | |
| 5581 DCHECK(!name->IsPrivate()); | |
| 5582 v8::GenericNamedPropertyGetterCallback getter = | |
| 5583 v8::ToCData<v8::GenericNamedPropertyGetterCallback>( | |
| 5584 interceptor->getter()); | |
| 5585 result = args.Call(getter, name); | |
| 5586 } | |
| 5587 if (!result.is_null()) return Just(DONT_ENUM); | |
| 5588 } | |
| 5589 | |
| 5590 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<PropertyAttributes>()); | |
| 5591 return Just(ABSENT); | |
| 5592 } | 5680 } |
| 5593 | 5681 |
| 5594 | |
| 5595 Maybe<PropertyAttributes> JSReceiver::GetPropertyAttributes( | 5682 Maybe<PropertyAttributes> JSReceiver::GetPropertyAttributes( |
| 5596 LookupIterator* it) { | 5683 LookupIterator* it) { |
| 5597 for (; it->IsFound(); it->Next()) { | 5684 for (; it->IsFound(); it->Next()) { |
| 5598 switch (it->state()) { | 5685 switch (it->state()) { |
| 5599 case LookupIterator::NOT_FOUND: | 5686 case LookupIterator::NOT_FOUND: |
| 5600 case LookupIterator::TRANSITION: | 5687 case LookupIterator::TRANSITION: |
| 5601 UNREACHABLE(); | 5688 UNREACHABLE(); |
| 5602 case LookupIterator::JSPROXY: | 5689 case LookupIterator::JSPROXY: |
| 5603 return JSProxy::GetPropertyAttributes(it); | 5690 return JSProxy::GetPropertyAttributes(it); |
| 5604 case LookupIterator::INTERCEPTOR: { | 5691 case LookupIterator::INTERCEPTOR: { |
| (...skipping 9846 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 15451 if (this->IsKey(isolate, k)) { | 15538 if (this->IsKey(isolate, k)) { |
| 15452 elements->set(pos++, this->ValueAt(i), mode); | 15539 elements->set(pos++, this->ValueAt(i), mode); |
| 15453 } | 15540 } |
| 15454 } | 15541 } |
| 15455 DCHECK(pos == elements->length()); | 15542 DCHECK(pos == elements->length()); |
| 15456 } | 15543 } |
| 15457 | 15544 |
| 15458 | 15545 |
| 15459 MaybeHandle<Object> JSObject::GetPropertyWithInterceptor(LookupIterator* it, | 15546 MaybeHandle<Object> JSObject::GetPropertyWithInterceptor(LookupIterator* it, |
| 15460 bool* done) { | 15547 bool* done) { |
| 15461 *done = false; | |
| 15462 Isolate* isolate = it->isolate(); | |
| 15463 // Make sure that the top context does not change when doing callbacks or | |
| 15464 // interceptor calls. | |
| 15465 AssertNoContextChange ncc(isolate); | |
| 15466 | |
| 15467 DCHECK_EQ(LookupIterator::INTERCEPTOR, it->state()); | 15548 DCHECK_EQ(LookupIterator::INTERCEPTOR, it->state()); |
| 15468 Handle<InterceptorInfo> interceptor = it->GetInterceptor(); | 15549 return GetPropertyWithInterceptorInternal(it, it->GetInterceptor(), done); |
| 15469 if (interceptor->getter()->IsUndefined(isolate)) { | |
| 15470 return isolate->factory()->undefined_value(); | |
| 15471 } | |
| 15472 | |
| 15473 Handle<JSObject> holder = it->GetHolder<JSObject>(); | |
| 15474 Handle<Object> result; | |
| 15475 Handle<Object> receiver = it->GetReceiver(); | |
| 15476 if (!receiver->IsJSReceiver()) { | |
| 15477 ASSIGN_RETURN_ON_EXCEPTION( | |
| 15478 isolate, receiver, Object::ConvertReceiver(isolate, receiver), Object); | |
| 15479 } | |
| 15480 PropertyCallbackArguments args(isolate, interceptor->data(), *receiver, | |
| 15481 *holder, Object::DONT_THROW); | |
| 15482 | |
| 15483 if (it->IsElement()) { | |
| 15484 uint32_t index = it->index(); | |
| 15485 v8::IndexedPropertyGetterCallback getter = | |
| 15486 v8::ToCData<v8::IndexedPropertyGetterCallback>(interceptor->getter()); | |
| 15487 result = args.Call(getter, index); | |
| 15488 } else { | |
| 15489 Handle<Name> name = it->name(); | |
| 15490 DCHECK(!name->IsPrivate()); | |
| 15491 | |
| 15492 if (name->IsSymbol() && !interceptor->can_intercept_symbols()) { | |
| 15493 return isolate->factory()->undefined_value(); | |
| 15494 } | |
| 15495 | |
| 15496 v8::GenericNamedPropertyGetterCallback getter = | |
| 15497 v8::ToCData<v8::GenericNamedPropertyGetterCallback>( | |
| 15498 interceptor->getter()); | |
| 15499 result = args.Call(getter, name); | |
| 15500 } | |
| 15501 | |
| 15502 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); | |
| 15503 if (result.is_null()) return isolate->factory()->undefined_value(); | |
| 15504 *done = true; | |
| 15505 // Rebox handle before return | |
| 15506 return handle(*result, isolate); | |
| 15507 } | 15550 } |
| 15508 | 15551 |
| 15509 | |
| 15510 Maybe<bool> JSObject::HasRealNamedProperty(Handle<JSObject> object, | 15552 Maybe<bool> JSObject::HasRealNamedProperty(Handle<JSObject> object, |
| 15511 Handle<Name> name) { | 15553 Handle<Name> name) { |
| 15512 LookupIterator it = LookupIterator::PropertyOrElement( | 15554 LookupIterator it = LookupIterator::PropertyOrElement( |
| 15513 name->GetIsolate(), object, name, LookupIterator::OWN_SKIP_INTERCEPTOR); | 15555 name->GetIsolate(), object, name, LookupIterator::OWN_SKIP_INTERCEPTOR); |
| 15514 return HasProperty(&it); | 15556 return HasProperty(&it); |
| 15515 } | 15557 } |
| 15516 | 15558 |
| 15517 | 15559 |
| 15518 Maybe<bool> JSObject::HasRealElementProperty(Handle<JSObject> object, | 15560 Maybe<bool> JSObject::HasRealElementProperty(Handle<JSObject> object, |
| 15519 uint32_t index) { | 15561 uint32_t index) { |
| (...skipping 3336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 18856 void PropertyCell::SetValueWithInvalidation(Handle<PropertyCell> cell, | 18898 void PropertyCell::SetValueWithInvalidation(Handle<PropertyCell> cell, |
| 18857 Handle<Object> new_value) { | 18899 Handle<Object> new_value) { |
| 18858 if (cell->value() != *new_value) { | 18900 if (cell->value() != *new_value) { |
| 18859 cell->set_value(*new_value); | 18901 cell->set_value(*new_value); |
| 18860 Isolate* isolate = cell->GetIsolate(); | 18902 Isolate* isolate = cell->GetIsolate(); |
| 18861 cell->dependent_code()->DeoptimizeDependentCodeGroup( | 18903 cell->dependent_code()->DeoptimizeDependentCodeGroup( |
| 18862 isolate, DependentCode::kPropertyCellChangedGroup); | 18904 isolate, DependentCode::kPropertyCellChangedGroup); |
| 18863 } | 18905 } |
| 18864 } | 18906 } |
| 18865 | 18907 |
| 18908 // static |
| 18909 AccessCheckInfo* AccessCheckInfo::Get(Isolate* isolate, |
| 18910 Handle<JSObject> receiver) { |
| 18911 DisallowHeapAllocation no_gc; |
| 18912 DCHECK(receiver->map()->is_access_check_needed()); |
| 18913 Object* maybe_constructor = receiver->map()->GetConstructor(); |
| 18914 // Might happen for a detached context. |
| 18915 if (!maybe_constructor->IsJSFunction()) return nullptr; |
| 18916 JSFunction* constructor = JSFunction::cast(maybe_constructor); |
| 18917 // Might happen for the debug context. |
| 18918 if (!constructor->shared()->IsApiFunction()) return nullptr; |
| 18919 |
| 18920 Object* data_obj = |
| 18921 constructor->shared()->get_api_func_data()->access_check_info(); |
| 18922 if (data_obj->IsUndefined(isolate)) return nullptr; |
| 18923 |
| 18924 return AccessCheckInfo::cast(data_obj); |
| 18925 } |
| 18926 |
| 18866 } // namespace internal | 18927 } // namespace internal |
| 18867 } // namespace v8 | 18928 } // namespace v8 |
| OLD | NEW |