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 2002 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
17522 for (int i = 0; i < length; i++) { | 17564 for (int i = 0; i < length; i++) { |
17523 int index = Smi::cast(storage->get(i))->value(); | 17565 int index = Smi::cast(storage->get(i))->value(); |
17524 storage->set(i, this->KeyAt(index)); | 17566 storage->set(i, this->KeyAt(index)); |
17525 } | 17567 } |
17526 } | 17568 } |
17527 | 17569 |
17528 template <typename Derived, typename Shape, typename Key> | 17570 template <typename Derived, typename Shape, typename Key> |
17529 void Dictionary<Derived, Shape, Key>::CollectKeysTo( | 17571 void Dictionary<Derived, Shape, Key>::CollectKeysTo( |
17530 Handle<Dictionary<Derived, Shape, Key> > dictionary, KeyAccumulator* keys, | 17572 Handle<Dictionary<Derived, Shape, Key> > dictionary, KeyAccumulator* keys, |
17531 PropertyFilter filter) { | 17573 PropertyFilter filter) { |
| 17574 DCHECK(!(filter & USE_ACCESS_CHECK_INTERCEPTOR)); |
| 17575 |
17532 Isolate* isolate = keys->isolate(); | 17576 Isolate* isolate = keys->isolate(); |
17533 int capacity = dictionary->Capacity(); | 17577 int capacity = dictionary->Capacity(); |
17534 Handle<FixedArray> array = | 17578 Handle<FixedArray> array = |
17535 isolate->factory()->NewFixedArray(dictionary->NumberOfElements()); | 17579 isolate->factory()->NewFixedArray(dictionary->NumberOfElements()); |
17536 int array_size = 0; | 17580 int array_size = 0; |
17537 | 17581 |
17538 { | 17582 { |
17539 DisallowHeapAllocation no_gc; | 17583 DisallowHeapAllocation no_gc; |
17540 Dictionary<Derived, Shape, Key>* raw_dict = *dictionary; | 17584 Dictionary<Derived, Shape, Key>* raw_dict = *dictionary; |
17541 for (int i = 0; i < capacity; i++) { | 17585 for (int i = 0; i < capacity; i++) { |
(...skipping 1314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
18856 void PropertyCell::SetValueWithInvalidation(Handle<PropertyCell> cell, | 18900 void PropertyCell::SetValueWithInvalidation(Handle<PropertyCell> cell, |
18857 Handle<Object> new_value) { | 18901 Handle<Object> new_value) { |
18858 if (cell->value() != *new_value) { | 18902 if (cell->value() != *new_value) { |
18859 cell->set_value(*new_value); | 18903 cell->set_value(*new_value); |
18860 Isolate* isolate = cell->GetIsolate(); | 18904 Isolate* isolate = cell->GetIsolate(); |
18861 cell->dependent_code()->DeoptimizeDependentCodeGroup( | 18905 cell->dependent_code()->DeoptimizeDependentCodeGroup( |
18862 isolate, DependentCode::kPropertyCellChangedGroup); | 18906 isolate, DependentCode::kPropertyCellChangedGroup); |
18863 } | 18907 } |
18864 } | 18908 } |
18865 | 18909 |
| 18910 // static |
| 18911 AccessCheckInfo* AccessCheckInfo::Get(Isolate* isolate, |
| 18912 Handle<JSObject> receiver) { |
| 18913 DisallowHeapAllocation no_gc; |
| 18914 DCHECK(receiver->map()->is_access_check_needed()); |
| 18915 Object* maybe_constructor = receiver->map()->GetConstructor(); |
| 18916 // Might happen for a detached context. |
| 18917 if (!maybe_constructor->IsJSFunction()) return nullptr; |
| 18918 JSFunction* constructor = JSFunction::cast(maybe_constructor); |
| 18919 // Might happen for the debug context. |
| 18920 if (!constructor->shared()->IsApiFunction()) return nullptr; |
| 18921 |
| 18922 Object* data_obj = |
| 18923 constructor->shared()->get_api_func_data()->access_check_info(); |
| 18924 if (data_obj->IsUndefined(isolate)) return nullptr; |
| 18925 |
| 18926 return AccessCheckInfo::cast(data_obj); |
| 18927 } |
| 18928 |
18866 } // namespace internal | 18929 } // namespace internal |
18867 } // namespace v8 | 18930 } // namespace v8 |
OLD | NEW |