| 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 | 
|---|