| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 1198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1209 DATA_VIEW_GETTER(Int8, int8_t, NumberFromInt32) | 1209 DATA_VIEW_GETTER(Int8, int8_t, NumberFromInt32) |
| 1210 DATA_VIEW_GETTER(Uint16, uint16_t, NumberFromUint32) | 1210 DATA_VIEW_GETTER(Uint16, uint16_t, NumberFromUint32) |
| 1211 DATA_VIEW_GETTER(Int16, int16_t, NumberFromInt32) | 1211 DATA_VIEW_GETTER(Int16, int16_t, NumberFromInt32) |
| 1212 DATA_VIEW_GETTER(Uint32, uint32_t, NumberFromUint32) | 1212 DATA_VIEW_GETTER(Uint32, uint32_t, NumberFromUint32) |
| 1213 DATA_VIEW_GETTER(Int32, int32_t, NumberFromInt32) | 1213 DATA_VIEW_GETTER(Int32, int32_t, NumberFromInt32) |
| 1214 DATA_VIEW_GETTER(Float32, float, NumberFromDouble) | 1214 DATA_VIEW_GETTER(Float32, float, NumberFromDouble) |
| 1215 DATA_VIEW_GETTER(Float64, double, NumberFromDouble) | 1215 DATA_VIEW_GETTER(Float64, double, NumberFromDouble) |
| 1216 | 1216 |
| 1217 #undef DATA_VIEW_GETTER | 1217 #undef DATA_VIEW_GETTER |
| 1218 | 1218 |
| 1219 |
| 1220 template <typename T> |
| 1221 static T DataViewConvertValue(double value); |
| 1222 |
| 1223 |
| 1224 template <> |
| 1225 int8_t DataViewConvertValue<int8_t>(double value) { |
| 1226 return static_cast<int8_t>(DoubleToInt32(value)); |
| 1227 } |
| 1228 |
| 1229 |
| 1230 template <> |
| 1231 int16_t DataViewConvertValue<int16_t>(double value) { |
| 1232 return static_cast<int16_t>(DoubleToInt32(value)); |
| 1233 } |
| 1234 |
| 1235 |
| 1236 template <> |
| 1237 int32_t DataViewConvertValue<int32_t>(double value) { |
| 1238 return DoubleToInt32(value); |
| 1239 } |
| 1240 |
| 1241 |
| 1242 template <> |
| 1243 uint8_t DataViewConvertValue<uint8_t>(double value) { |
| 1244 return static_cast<uint8_t>(DoubleToUint32(value)); |
| 1245 } |
| 1246 |
| 1247 |
| 1248 template <> |
| 1249 uint16_t DataViewConvertValue<uint16_t>(double value) { |
| 1250 return static_cast<uint16_t>(DoubleToUint32(value)); |
| 1251 } |
| 1252 |
| 1253 |
| 1254 template <> |
| 1255 uint32_t DataViewConvertValue<uint32_t>(double value) { |
| 1256 return DoubleToUint32(value); |
| 1257 } |
| 1258 |
| 1259 |
| 1260 template <> |
| 1261 float DataViewConvertValue<float>(double value) { |
| 1262 return static_cast<float>(value); |
| 1263 } |
| 1264 |
| 1265 |
| 1266 template <> |
| 1267 double DataViewConvertValue<double>(double value) { |
| 1268 return value; |
| 1269 } |
| 1270 |
| 1271 |
| 1219 #define DATA_VIEW_SETTER(TypeName, Type) \ | 1272 #define DATA_VIEW_SETTER(TypeName, Type) \ |
| 1220 RUNTIME_FUNCTION(MaybeObject*, Runtime_DataViewSet##TypeName) { \ | 1273 RUNTIME_FUNCTION(MaybeObject*, Runtime_DataViewSet##TypeName) { \ |
| 1221 HandleScope scope(isolate); \ | 1274 HandleScope scope(isolate); \ |
| 1222 ASSERT(args.length() == 4); \ | 1275 ASSERT(args.length() == 4); \ |
| 1223 CONVERT_ARG_HANDLE_CHECKED(JSDataView, holder, 0); \ | 1276 CONVERT_ARG_HANDLE_CHECKED(JSDataView, holder, 0); \ |
| 1224 CONVERT_ARG_HANDLE_CHECKED(Object, offset, 1); \ | 1277 CONVERT_ARG_HANDLE_CHECKED(Object, offset, 1); \ |
| 1225 CONVERT_ARG_HANDLE_CHECKED(Object, value, 2); \ | 1278 CONVERT_ARG_HANDLE_CHECKED(Object, value, 2); \ |
| 1226 CONVERT_BOOLEAN_ARG_CHECKED(is_little_endian, 3); \ | 1279 CONVERT_BOOLEAN_ARG_CHECKED(is_little_endian, 3); \ |
| 1227 Type v = static_cast<Type>(value->Number()); \ | 1280 Type v = DataViewConvertValue<Type>(value->Number()); \ |
| 1228 if (DataViewSetValue( \ | 1281 if (DataViewSetValue( \ |
| 1229 isolate, holder, offset, is_little_endian, v)) { \ | 1282 isolate, holder, offset, is_little_endian, v)) { \ |
| 1230 return isolate->heap()->undefined_value(); \ | 1283 return isolate->heap()->undefined_value(); \ |
| 1231 } else { \ | 1284 } else { \ |
| 1232 return isolate->Throw(*isolate->factory()->NewRangeError( \ | 1285 return isolate->Throw(*isolate->factory()->NewRangeError( \ |
| 1233 "invalid_data_view_accessor_offset", \ | 1286 "invalid_data_view_accessor_offset", \ |
| 1234 HandleVector<Object>(NULL, 0))); \ | 1287 HandleVector<Object>(NULL, 0))); \ |
| 1235 } \ | 1288 } \ |
| 1236 } | 1289 } |
| 1237 | 1290 |
| (...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1449 ASSERT(args.length() == 1); | 1502 ASSERT(args.length() == 1); |
| 1450 CONVERT_ARG_CHECKED(Object, obj, 0); | 1503 CONVERT_ARG_CHECKED(Object, obj, 0); |
| 1451 // We don't expect access checks to be needed on JSProxy objects. | 1504 // We don't expect access checks to be needed on JSProxy objects. |
| 1452 ASSERT(!obj->IsAccessCheckNeeded() || obj->IsJSObject()); | 1505 ASSERT(!obj->IsAccessCheckNeeded() || obj->IsJSObject()); |
| 1453 do { | 1506 do { |
| 1454 if (obj->IsAccessCheckNeeded() && | 1507 if (obj->IsAccessCheckNeeded() && |
| 1455 !isolate->MayNamedAccess(JSObject::cast(obj), | 1508 !isolate->MayNamedAccess(JSObject::cast(obj), |
| 1456 isolate->heap()->proto_string(), | 1509 isolate->heap()->proto_string(), |
| 1457 v8::ACCESS_GET)) { | 1510 v8::ACCESS_GET)) { |
| 1458 isolate->ReportFailedAccessCheck(JSObject::cast(obj), v8::ACCESS_GET); | 1511 isolate->ReportFailedAccessCheck(JSObject::cast(obj), v8::ACCESS_GET); |
| 1512 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
| 1459 return isolate->heap()->undefined_value(); | 1513 return isolate->heap()->undefined_value(); |
| 1460 } | 1514 } |
| 1461 obj = obj->GetPrototype(isolate); | 1515 obj = obj->GetPrototype(isolate); |
| 1462 } while (obj->IsJSObject() && | 1516 } while (obj->IsJSObject() && |
| 1463 JSObject::cast(obj)->map()->is_hidden_prototype()); | 1517 JSObject::cast(obj)->map()->is_hidden_prototype()); |
| 1464 return obj; | 1518 return obj; |
| 1465 } | 1519 } |
| 1466 | 1520 |
| 1467 | 1521 |
| 1468 static inline Object* GetPrototypeSkipHiddenPrototypes(Isolate* isolate, | 1522 static inline Object* GetPrototypeSkipHiddenPrototypes(Isolate* isolate, |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1553 } | 1607 } |
| 1554 | 1608 |
| 1555 | 1609 |
| 1556 enum AccessCheckResult { | 1610 enum AccessCheckResult { |
| 1557 ACCESS_FORBIDDEN, | 1611 ACCESS_FORBIDDEN, |
| 1558 ACCESS_ALLOWED, | 1612 ACCESS_ALLOWED, |
| 1559 ACCESS_ABSENT | 1613 ACCESS_ABSENT |
| 1560 }; | 1614 }; |
| 1561 | 1615 |
| 1562 | 1616 |
| 1563 static AccessCheckResult CheckElementAccess( | |
| 1564 JSObject* obj, | |
| 1565 uint32_t index, | |
| 1566 v8::AccessType access_type) { | |
| 1567 // TODO(1095): we should traverse hidden prototype hierachy as well. | |
| 1568 if (CheckGenericAccess( | |
| 1569 obj, obj, index, access_type, &Isolate::MayIndexedAccess)) { | |
| 1570 return ACCESS_ALLOWED; | |
| 1571 } | |
| 1572 | |
| 1573 obj->GetIsolate()->ReportFailedAccessCheck(obj, access_type); | |
| 1574 return ACCESS_FORBIDDEN; | |
| 1575 } | |
| 1576 | |
| 1577 | |
| 1578 static AccessCheckResult CheckPropertyAccess( | 1617 static AccessCheckResult CheckPropertyAccess( |
| 1579 JSObject* obj, | 1618 JSObject* obj, |
| 1580 Name* name, | 1619 Name* name, |
| 1581 v8::AccessType access_type) { | 1620 v8::AccessType access_type) { |
| 1582 uint32_t index; | 1621 uint32_t index; |
| 1583 if (name->AsArrayIndex(&index)) { | 1622 if (name->AsArrayIndex(&index)) { |
| 1584 return CheckElementAccess(obj, index, access_type); | 1623 // TODO(1095): we should traverse hidden prototype hierachy as well. |
| 1624 if (CheckGenericAccess( |
| 1625 obj, obj, index, access_type, &Isolate::MayIndexedAccess)) { |
| 1626 return ACCESS_ALLOWED; |
| 1627 } |
| 1628 |
| 1629 obj->GetIsolate()->ReportFailedAccessCheck(obj, access_type); |
| 1630 return ACCESS_FORBIDDEN; |
| 1585 } | 1631 } |
| 1586 | 1632 |
| 1587 LookupResult lookup(obj->GetIsolate()); | 1633 LookupResult lookup(obj->GetIsolate()); |
| 1588 obj->LocalLookup(name, &lookup, true); | 1634 obj->LocalLookup(name, &lookup, true); |
| 1589 | 1635 |
| 1590 if (!lookup.IsProperty()) return ACCESS_ABSENT; | 1636 if (!lookup.IsProperty()) return ACCESS_ABSENT; |
| 1591 if (CheckGenericAccess<Object*>( | 1637 if (CheckGenericAccess<Object*>( |
| 1592 obj, lookup.holder(), name, access_type, &Isolate::MayNamedAccess)) { | 1638 obj, lookup.holder(), name, access_type, &Isolate::MayNamedAccess)) { |
| 1593 return ACCESS_ALLOWED; | 1639 return ACCESS_ALLOWED; |
| 1594 } | 1640 } |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1634 DESCRIPTOR_SIZE | 1680 DESCRIPTOR_SIZE |
| 1635 }; | 1681 }; |
| 1636 | 1682 |
| 1637 | 1683 |
| 1638 static MaybeObject* GetOwnProperty(Isolate* isolate, | 1684 static MaybeObject* GetOwnProperty(Isolate* isolate, |
| 1639 Handle<JSObject> obj, | 1685 Handle<JSObject> obj, |
| 1640 Handle<Name> name) { | 1686 Handle<Name> name) { |
| 1641 Heap* heap = isolate->heap(); | 1687 Heap* heap = isolate->heap(); |
| 1642 // Due to some WebKit tests, we want to make sure that we do not log | 1688 // Due to some WebKit tests, we want to make sure that we do not log |
| 1643 // more than one access failure here. | 1689 // more than one access failure here. |
| 1644 switch (CheckPropertyAccess(*obj, *name, v8::ACCESS_HAS)) { | 1690 AccessCheckResult access_check_result = |
| 1691 CheckPropertyAccess(*obj, *name, v8::ACCESS_HAS); |
| 1692 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
| 1693 switch (access_check_result) { |
| 1645 case ACCESS_FORBIDDEN: return heap->false_value(); | 1694 case ACCESS_FORBIDDEN: return heap->false_value(); |
| 1646 case ACCESS_ALLOWED: break; | 1695 case ACCESS_ALLOWED: break; |
| 1647 case ACCESS_ABSENT: return heap->undefined_value(); | 1696 case ACCESS_ABSENT: return heap->undefined_value(); |
| 1648 } | 1697 } |
| 1649 | 1698 |
| 1650 PropertyAttributes attrs = obj->GetLocalPropertyAttribute(*name); | 1699 PropertyAttributes attrs = obj->GetLocalPropertyAttribute(*name); |
| 1651 if (attrs == ABSENT) return heap->undefined_value(); | 1700 if (attrs == ABSENT) { |
| 1701 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
| 1702 return heap->undefined_value(); |
| 1703 } |
| 1704 ASSERT(!isolate->has_scheduled_exception()); |
| 1652 AccessorPair* raw_accessors = obj->GetLocalPropertyAccessorPair(*name); | 1705 AccessorPair* raw_accessors = obj->GetLocalPropertyAccessorPair(*name); |
| 1653 Handle<AccessorPair> accessors(raw_accessors, isolate); | 1706 Handle<AccessorPair> accessors(raw_accessors, isolate); |
| 1654 | 1707 |
| 1655 Handle<FixedArray> elms = isolate->factory()->NewFixedArray(DESCRIPTOR_SIZE); | 1708 Handle<FixedArray> elms = isolate->factory()->NewFixedArray(DESCRIPTOR_SIZE); |
| 1656 elms->set(ENUMERABLE_INDEX, heap->ToBoolean((attrs & DONT_ENUM) == 0)); | 1709 elms->set(ENUMERABLE_INDEX, heap->ToBoolean((attrs & DONT_ENUM) == 0)); |
| 1657 elms->set(CONFIGURABLE_INDEX, heap->ToBoolean((attrs & DONT_DELETE) == 0)); | 1710 elms->set(CONFIGURABLE_INDEX, heap->ToBoolean((attrs & DONT_DELETE) == 0)); |
| 1658 elms->set(IS_ACCESSOR_INDEX, heap->ToBoolean(raw_accessors != NULL)); | 1711 elms->set(IS_ACCESSOR_INDEX, heap->ToBoolean(raw_accessors != NULL)); |
| 1659 | 1712 |
| 1660 if (raw_accessors == NULL) { | 1713 if (raw_accessors == NULL) { |
| 1661 elms->set(WRITABLE_INDEX, heap->ToBoolean((attrs & READ_ONLY) == 0)); | 1714 elms->set(WRITABLE_INDEX, heap->ToBoolean((attrs & READ_ONLY) == 0)); |
| 1662 // GetProperty does access check. | 1715 // GetProperty does access check. |
| 1663 Handle<Object> value = GetProperty(isolate, obj, name); | 1716 Handle<Object> value = GetProperty(isolate, obj, name); |
| 1664 RETURN_IF_EMPTY_HANDLE(isolate, value); | 1717 RETURN_IF_EMPTY_HANDLE(isolate, value); |
| 1665 elms->set(VALUE_INDEX, *value); | 1718 elms->set(VALUE_INDEX, *value); |
| 1666 } else { | 1719 } else { |
| 1667 // Access checks are performed for both accessors separately. | 1720 // Access checks are performed for both accessors separately. |
| 1668 // When they fail, the respective field is not set in the descriptor. | 1721 // When they fail, the respective field is not set in the descriptor. |
| 1669 Object* getter = accessors->GetComponent(ACCESSOR_GETTER); | 1722 Object* getter = accessors->GetComponent(ACCESSOR_GETTER); |
| 1670 Object* setter = accessors->GetComponent(ACCESSOR_SETTER); | 1723 Object* setter = accessors->GetComponent(ACCESSOR_SETTER); |
| 1671 if (!getter->IsMap() && CheckPropertyAccess(*obj, *name, v8::ACCESS_GET)) { | 1724 if (!getter->IsMap() && CheckPropertyAccess(*obj, *name, v8::ACCESS_GET)) { |
| 1725 ASSERT(!isolate->has_scheduled_exception()); |
| 1672 elms->set(GETTER_INDEX, getter); | 1726 elms->set(GETTER_INDEX, getter); |
| 1727 } else { |
| 1728 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
| 1673 } | 1729 } |
| 1674 if (!setter->IsMap() && CheckPropertyAccess(*obj, *name, v8::ACCESS_SET)) { | 1730 if (!setter->IsMap() && CheckPropertyAccess(*obj, *name, v8::ACCESS_SET)) { |
| 1731 ASSERT(!isolate->has_scheduled_exception()); |
| 1675 elms->set(SETTER_INDEX, setter); | 1732 elms->set(SETTER_INDEX, setter); |
| 1733 } else { |
| 1734 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
| 1676 } | 1735 } |
| 1677 } | 1736 } |
| 1678 | 1737 |
| 1679 return *isolate->factory()->NewJSArrayWithElements(elms); | 1738 return *isolate->factory()->NewJSArrayWithElements(elms); |
| 1680 } | 1739 } |
| 1681 | 1740 |
| 1682 | 1741 |
| 1683 // Returns an array with the property description: | 1742 // Returns an array with the property description: |
| 1684 // if args[1] is not a property on args[0] | 1743 // if args[1] is not a property on args[0] |
| 1685 // returns undefined | 1744 // returns undefined |
| (...skipping 1104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2790 return isolate->heap()->undefined_value(); | 2849 return isolate->heap()->undefined_value(); |
| 2791 } | 2850 } |
| 2792 | 2851 |
| 2793 | 2852 |
| 2794 RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateJSGeneratorObject) { | 2853 RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateJSGeneratorObject) { |
| 2795 SealHandleScope shs(isolate); | 2854 SealHandleScope shs(isolate); |
| 2796 ASSERT(args.length() == 0); | 2855 ASSERT(args.length() == 0); |
| 2797 | 2856 |
| 2798 JavaScriptFrameIterator it(isolate); | 2857 JavaScriptFrameIterator it(isolate); |
| 2799 JavaScriptFrame* frame = it.frame(); | 2858 JavaScriptFrame* frame = it.frame(); |
| 2800 JSFunction* function = JSFunction::cast(frame->function()); | 2859 JSFunction* function = frame->function(); |
| 2801 RUNTIME_ASSERT(function->shared()->is_generator()); | 2860 RUNTIME_ASSERT(function->shared()->is_generator()); |
| 2802 | 2861 |
| 2803 JSGeneratorObject* generator; | 2862 JSGeneratorObject* generator; |
| 2804 if (frame->IsConstructor()) { | 2863 if (frame->IsConstructor()) { |
| 2805 generator = JSGeneratorObject::cast(frame->receiver()); | 2864 generator = JSGeneratorObject::cast(frame->receiver()); |
| 2806 } else { | 2865 } else { |
| 2807 MaybeObject* maybe_generator = | 2866 MaybeObject* maybe_generator = |
| 2808 isolate->heap()->AllocateJSGeneratorObject(function); | 2867 isolate->heap()->AllocateJSGeneratorObject(function); |
| 2809 if (!maybe_generator->To(&generator)) return maybe_generator; | 2868 if (!maybe_generator->To(&generator)) return maybe_generator; |
| 2810 } | 2869 } |
| 2811 generator->set_function(function); | 2870 generator->set_function(function); |
| 2812 generator->set_context(Context::cast(frame->context())); | 2871 generator->set_context(Context::cast(frame->context())); |
| 2813 generator->set_receiver(frame->receiver()); | 2872 generator->set_receiver(frame->receiver()); |
| 2814 generator->set_continuation(0); | 2873 generator->set_continuation(0); |
| 2815 generator->set_operand_stack(isolate->heap()->empty_fixed_array()); | 2874 generator->set_operand_stack(isolate->heap()->empty_fixed_array()); |
| 2816 generator->set_stack_handler_index(-1); | 2875 generator->set_stack_handler_index(-1); |
| 2817 | 2876 |
| 2818 return generator; | 2877 return generator; |
| 2819 } | 2878 } |
| 2820 | 2879 |
| 2821 | 2880 |
| 2822 RUNTIME_FUNCTION(MaybeObject*, Runtime_SuspendJSGeneratorObject) { | 2881 RUNTIME_FUNCTION(MaybeObject*, Runtime_SuspendJSGeneratorObject) { |
| 2823 SealHandleScope shs(isolate); | 2882 SealHandleScope shs(isolate); |
| 2824 ASSERT(args.length() == 1); | 2883 ASSERT(args.length() == 1); |
| 2825 CONVERT_ARG_CHECKED(JSGeneratorObject, generator_object, 0); | 2884 CONVERT_ARG_CHECKED(JSGeneratorObject, generator_object, 0); |
| 2826 | 2885 |
| 2827 JavaScriptFrameIterator stack_iterator(isolate); | 2886 JavaScriptFrameIterator stack_iterator(isolate); |
| 2828 JavaScriptFrame* frame = stack_iterator.frame(); | 2887 JavaScriptFrame* frame = stack_iterator.frame(); |
| 2829 RUNTIME_ASSERT(JSFunction::cast(frame->function())->shared()->is_generator()); | 2888 RUNTIME_ASSERT(frame->function()->shared()->is_generator()); |
| 2830 ASSERT_EQ(JSFunction::cast(frame->function()), generator_object->function()); | 2889 ASSERT_EQ(frame->function(), generator_object->function()); |
| 2831 | 2890 |
| 2832 // The caller should have saved the context and continuation already. | 2891 // The caller should have saved the context and continuation already. |
| 2833 ASSERT_EQ(generator_object->context(), Context::cast(frame->context())); | 2892 ASSERT_EQ(generator_object->context(), Context::cast(frame->context())); |
| 2834 ASSERT_LT(0, generator_object->continuation()); | 2893 ASSERT_LT(0, generator_object->continuation()); |
| 2835 | 2894 |
| 2836 // We expect there to be at least two values on the operand stack: the return | 2895 // We expect there to be at least two values on the operand stack: the return |
| 2837 // value of the yield expression, and the argument to this runtime call. | 2896 // value of the yield expression, and the argument to this runtime call. |
| 2838 // Neither of those should be saved. | 2897 // Neither of those should be saved. |
| 2839 int operands_count = frame->ComputeOperandsCount(); | 2898 int operands_count = frame->ComputeOperandsCount(); |
| 2840 ASSERT_GE(operands_count, 2); | 2899 ASSERT_GE(operands_count, 2); |
| (...skipping 1965 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4806 CONVERT_ARG_HANDLE_CHECKED(Object, getter, 2); | 4865 CONVERT_ARG_HANDLE_CHECKED(Object, getter, 2); |
| 4807 RUNTIME_ASSERT(IsValidAccessor(getter)); | 4866 RUNTIME_ASSERT(IsValidAccessor(getter)); |
| 4808 CONVERT_ARG_HANDLE_CHECKED(Object, setter, 3); | 4867 CONVERT_ARG_HANDLE_CHECKED(Object, setter, 3); |
| 4809 RUNTIME_ASSERT(IsValidAccessor(setter)); | 4868 RUNTIME_ASSERT(IsValidAccessor(setter)); |
| 4810 CONVERT_SMI_ARG_CHECKED(unchecked, 4); | 4869 CONVERT_SMI_ARG_CHECKED(unchecked, 4); |
| 4811 RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); | 4870 RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); |
| 4812 PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked); | 4871 PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked); |
| 4813 | 4872 |
| 4814 bool fast = obj->HasFastProperties(); | 4873 bool fast = obj->HasFastProperties(); |
| 4815 JSObject::DefineAccessor(obj, name, getter, setter, attr); | 4874 JSObject::DefineAccessor(obj, name, getter, setter, attr); |
| 4875 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
| 4816 if (fast) JSObject::TransformToFastProperties(obj, 0); | 4876 if (fast) JSObject::TransformToFastProperties(obj, 0); |
| 4817 return isolate->heap()->undefined_value(); | 4877 return isolate->heap()->undefined_value(); |
| 4818 } | 4878 } |
| 4819 | 4879 |
| 4820 | 4880 |
| 4821 // Implements part of 8.12.9 DefineOwnProperty. | 4881 // Implements part of 8.12.9 DefineOwnProperty. |
| 4822 // There are 3 cases that lead here: | 4882 // There are 3 cases that lead here: |
| 4823 // Step 4a - define a new data property. | 4883 // Step 4a - define a new data property. |
| 4824 // Steps 9b & 12 - replace an existing accessor property with a data property. | 4884 // Steps 9b & 12 - replace an existing accessor property with a data property. |
| 4825 // Step 12 - update an existing data property with a data or generic | 4885 // Step 12 - update an existing data property with a data or generic |
| (...skipping 506 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5332 | 5392 |
| 5333 CONVERT_ARG_CHECKED(JSReceiver, object, 0); | 5393 CONVERT_ARG_CHECKED(JSReceiver, object, 0); |
| 5334 CONVERT_ARG_CHECKED(Name, key, 1); | 5394 CONVERT_ARG_CHECKED(Name, key, 1); |
| 5335 CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode, 2); | 5395 CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode, 2); |
| 5336 return object->DeleteProperty(key, (strict_mode == kStrictMode) | 5396 return object->DeleteProperty(key, (strict_mode == kStrictMode) |
| 5337 ? JSReceiver::STRICT_DELETION | 5397 ? JSReceiver::STRICT_DELETION |
| 5338 : JSReceiver::NORMAL_DELETION); | 5398 : JSReceiver::NORMAL_DELETION); |
| 5339 } | 5399 } |
| 5340 | 5400 |
| 5341 | 5401 |
| 5342 static Object* HasLocalPropertyImplementation(Isolate* isolate, | 5402 static MaybeObject* HasLocalPropertyImplementation(Isolate* isolate, |
| 5343 Handle<JSObject> object, | 5403 Handle<JSObject> object, |
| 5344 Handle<Name> key) { | 5404 Handle<Name> key) { |
| 5345 if (object->HasLocalProperty(*key)) return isolate->heap()->true_value(); | 5405 if (object->HasLocalProperty(*key)) return isolate->heap()->true_value(); |
| 5346 // Handle hidden prototypes. If there's a hidden prototype above this thing | 5406 // Handle hidden prototypes. If there's a hidden prototype above this thing |
| 5347 // then we have to check it for properties, because they are supposed to | 5407 // then we have to check it for properties, because they are supposed to |
| 5348 // look like they are on this object. | 5408 // look like they are on this object. |
| 5349 Handle<Object> proto(object->GetPrototype(), isolate); | 5409 Handle<Object> proto(object->GetPrototype(), isolate); |
| 5350 if (proto->IsJSObject() && | 5410 if (proto->IsJSObject() && |
| 5351 Handle<JSObject>::cast(proto)->map()->is_hidden_prototype()) { | 5411 Handle<JSObject>::cast(proto)->map()->is_hidden_prototype()) { |
| 5352 return HasLocalPropertyImplementation(isolate, | 5412 return HasLocalPropertyImplementation(isolate, |
| 5353 Handle<JSObject>::cast(proto), | 5413 Handle<JSObject>::cast(proto), |
| 5354 key); | 5414 key); |
| 5355 } | 5415 } |
| 5416 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
| 5356 return isolate->heap()->false_value(); | 5417 return isolate->heap()->false_value(); |
| 5357 } | 5418 } |
| 5358 | 5419 |
| 5359 | 5420 |
| 5360 RUNTIME_FUNCTION(MaybeObject*, Runtime_HasLocalProperty) { | 5421 RUNTIME_FUNCTION(MaybeObject*, Runtime_HasLocalProperty) { |
| 5361 SealHandleScope shs(isolate); | 5422 SealHandleScope shs(isolate); |
| 5362 ASSERT(args.length() == 2); | 5423 ASSERT(args.length() == 2); |
| 5363 CONVERT_ARG_CHECKED(Name, key, 1); | 5424 CONVERT_ARG_CHECKED(Name, key, 1); |
| 5364 | 5425 |
| 5365 uint32_t index; | 5426 uint32_t index; |
| 5366 const bool key_is_array_index = key->AsArrayIndex(&index); | 5427 const bool key_is_array_index = key->AsArrayIndex(&index); |
| 5367 | 5428 |
| 5368 Object* obj = args[0]; | 5429 Object* obj = args[0]; |
| 5369 // Only JS objects can have properties. | 5430 // Only JS objects can have properties. |
| 5370 if (obj->IsJSObject()) { | 5431 if (obj->IsJSObject()) { |
| 5371 JSObject* object = JSObject::cast(obj); | 5432 JSObject* object = JSObject::cast(obj); |
| 5372 // Fast case: either the key is a real named property or it is not | 5433 // Fast case: either the key is a real named property or it is not |
| 5373 // an array index and there are no interceptors or hidden | 5434 // an array index and there are no interceptors or hidden |
| 5374 // prototypes. | 5435 // prototypes. |
| 5375 if (object->HasRealNamedProperty(isolate, key)) | 5436 if (object->HasRealNamedProperty(isolate, key)) { |
| 5437 ASSERT(!isolate->has_scheduled_exception()); |
| 5376 return isolate->heap()->true_value(); | 5438 return isolate->heap()->true_value(); |
| 5439 } else { |
| 5440 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
| 5441 } |
| 5377 Map* map = object->map(); | 5442 Map* map = object->map(); |
| 5378 if (!key_is_array_index && | 5443 if (!key_is_array_index && |
| 5379 !map->has_named_interceptor() && | 5444 !map->has_named_interceptor() && |
| 5380 !HeapObject::cast(map->prototype())->map()->is_hidden_prototype()) { | 5445 !HeapObject::cast(map->prototype())->map()->is_hidden_prototype()) { |
| 5381 return isolate->heap()->false_value(); | 5446 return isolate->heap()->false_value(); |
| 5382 } | 5447 } |
| 5383 // Slow case. | 5448 // Slow case. |
| 5384 HandleScope scope(isolate); | 5449 HandleScope scope(isolate); |
| 5385 return HasLocalPropertyImplementation(isolate, | 5450 return HasLocalPropertyImplementation(isolate, |
| 5386 Handle<JSObject>(object), | 5451 Handle<JSObject>(object), |
| 5387 Handle<Name>(key)); | 5452 Handle<Name>(key)); |
| 5388 } else if (obj->IsString() && key_is_array_index) { | 5453 } else if (obj->IsString() && key_is_array_index) { |
| 5389 // Well, there is one exception: Handle [] on strings. | 5454 // Well, there is one exception: Handle [] on strings. |
| 5390 String* string = String::cast(obj); | 5455 String* string = String::cast(obj); |
| 5391 if (index < static_cast<uint32_t>(string->length())) { | 5456 if (index < static_cast<uint32_t>(string->length())) { |
| 5392 return isolate->heap()->true_value(); | 5457 return isolate->heap()->true_value(); |
| 5393 } | 5458 } |
| 5394 } | 5459 } |
| 5395 return isolate->heap()->false_value(); | 5460 return isolate->heap()->false_value(); |
| 5396 } | 5461 } |
| 5397 | 5462 |
| 5398 | 5463 |
| 5399 RUNTIME_FUNCTION(MaybeObject*, Runtime_HasProperty) { | 5464 RUNTIME_FUNCTION(MaybeObject*, Runtime_HasProperty) { |
| 5400 SealHandleScope shs(isolate); | 5465 SealHandleScope shs(isolate); |
| 5401 ASSERT(args.length() == 2); | 5466 ASSERT(args.length() == 2); |
| 5402 CONVERT_ARG_CHECKED(JSReceiver, receiver, 0); | 5467 CONVERT_ARG_CHECKED(JSReceiver, receiver, 0); |
| 5403 CONVERT_ARG_CHECKED(Name, key, 1); | 5468 CONVERT_ARG_CHECKED(Name, key, 1); |
| 5404 | 5469 |
| 5405 bool result = receiver->HasProperty(key); | 5470 bool result = receiver->HasProperty(key); |
| 5471 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
| 5406 if (isolate->has_pending_exception()) return Failure::Exception(); | 5472 if (isolate->has_pending_exception()) return Failure::Exception(); |
| 5407 return isolate->heap()->ToBoolean(result); | 5473 return isolate->heap()->ToBoolean(result); |
| 5408 } | 5474 } |
| 5409 | 5475 |
| 5410 | 5476 |
| 5411 RUNTIME_FUNCTION(MaybeObject*, Runtime_HasElement) { | 5477 RUNTIME_FUNCTION(MaybeObject*, Runtime_HasElement) { |
| 5412 SealHandleScope shs(isolate); | 5478 SealHandleScope shs(isolate); |
| 5413 ASSERT(args.length() == 2); | 5479 ASSERT(args.length() == 2); |
| 5414 CONVERT_ARG_CHECKED(JSReceiver, receiver, 0); | 5480 CONVERT_ARG_CHECKED(JSReceiver, receiver, 0); |
| 5415 CONVERT_SMI_ARG_CHECKED(index, 1); | 5481 CONVERT_SMI_ARG_CHECKED(index, 1); |
| 5416 | 5482 |
| 5417 bool result = receiver->HasElement(index); | 5483 bool result = receiver->HasElement(index); |
| 5484 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
| 5418 if (isolate->has_pending_exception()) return Failure::Exception(); | 5485 if (isolate->has_pending_exception()) return Failure::Exception(); |
| 5419 return isolate->heap()->ToBoolean(result); | 5486 return isolate->heap()->ToBoolean(result); |
| 5420 } | 5487 } |
| 5421 | 5488 |
| 5422 | 5489 |
| 5423 RUNTIME_FUNCTION(MaybeObject*, Runtime_IsPropertyEnumerable) { | 5490 RUNTIME_FUNCTION(MaybeObject*, Runtime_IsPropertyEnumerable) { |
| 5424 SealHandleScope shs(isolate); | 5491 SealHandleScope shs(isolate); |
| 5425 ASSERT(args.length() == 2); | 5492 ASSERT(args.length() == 2); |
| 5426 | 5493 |
| 5427 CONVERT_ARG_CHECKED(JSObject, object, 0); | 5494 CONVERT_ARG_CHECKED(JSObject, object, 0); |
| 5428 CONVERT_ARG_CHECKED(Name, key, 1); | 5495 CONVERT_ARG_CHECKED(Name, key, 1); |
| 5429 | 5496 |
| 5430 PropertyAttributes att = object->GetLocalPropertyAttribute(key); | 5497 PropertyAttributes att = object->GetLocalPropertyAttribute(key); |
| 5431 return isolate->heap()->ToBoolean(att != ABSENT && (att & DONT_ENUM) == 0); | 5498 if (att == ABSENT || (att & DONT_ENUM) != 0) { |
| 5499 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
| 5500 return isolate->heap()->false_value(); |
| 5501 } |
| 5502 ASSERT(!isolate->has_scheduled_exception()); |
| 5503 return isolate->heap()->true_value(); |
| 5432 } | 5504 } |
| 5433 | 5505 |
| 5434 | 5506 |
| 5435 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetPropertyNames) { | 5507 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetPropertyNames) { |
| 5436 HandleScope scope(isolate); | 5508 HandleScope scope(isolate); |
| 5437 ASSERT(args.length() == 1); | 5509 ASSERT(args.length() == 1); |
| 5438 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0); | 5510 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0); |
| 5439 bool threw = false; | 5511 bool threw = false; |
| 5440 Handle<JSArray> result = GetKeysFor(object, &threw); | 5512 Handle<JSArray> result = GetKeysFor(object, &threw); |
| 5441 if (threw) return Failure::Exception(); | 5513 if (threw) return Failure::Exception(); |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5499 | 5571 |
| 5500 // Skip the global proxy as it has no properties and always delegates to the | 5572 // Skip the global proxy as it has no properties and always delegates to the |
| 5501 // real global object. | 5573 // real global object. |
| 5502 if (obj->IsJSGlobalProxy()) { | 5574 if (obj->IsJSGlobalProxy()) { |
| 5503 // Only collect names if access is permitted. | 5575 // Only collect names if access is permitted. |
| 5504 if (obj->IsAccessCheckNeeded() && | 5576 if (obj->IsAccessCheckNeeded() && |
| 5505 !isolate->MayNamedAccess(*obj, | 5577 !isolate->MayNamedAccess(*obj, |
| 5506 isolate->heap()->undefined_value(), | 5578 isolate->heap()->undefined_value(), |
| 5507 v8::ACCESS_KEYS)) { | 5579 v8::ACCESS_KEYS)) { |
| 5508 isolate->ReportFailedAccessCheck(*obj, v8::ACCESS_KEYS); | 5580 isolate->ReportFailedAccessCheck(*obj, v8::ACCESS_KEYS); |
| 5581 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
| 5509 return *isolate->factory()->NewJSArray(0); | 5582 return *isolate->factory()->NewJSArray(0); |
| 5510 } | 5583 } |
| 5511 obj = Handle<JSObject>(JSObject::cast(obj->GetPrototype())); | 5584 obj = Handle<JSObject>(JSObject::cast(obj->GetPrototype())); |
| 5512 } | 5585 } |
| 5513 | 5586 |
| 5514 // Find the number of objects making up this. | 5587 // Find the number of objects making up this. |
| 5515 int length = LocalPrototypeChainLength(*obj); | 5588 int length = LocalPrototypeChainLength(*obj); |
| 5516 | 5589 |
| 5517 // Find the number of local properties for each of the objects. | 5590 // Find the number of local properties for each of the objects. |
| 5518 ScopedVector<int> local_property_count(length); | 5591 ScopedVector<int> local_property_count(length); |
| 5519 int total_property_count = 0; | 5592 int total_property_count = 0; |
| 5520 Handle<JSObject> jsproto = obj; | 5593 Handle<JSObject> jsproto = obj; |
| 5521 for (int i = 0; i < length; i++) { | 5594 for (int i = 0; i < length; i++) { |
| 5522 // Only collect names if access is permitted. | 5595 // Only collect names if access is permitted. |
| 5523 if (jsproto->IsAccessCheckNeeded() && | 5596 if (jsproto->IsAccessCheckNeeded() && |
| 5524 !isolate->MayNamedAccess(*jsproto, | 5597 !isolate->MayNamedAccess(*jsproto, |
| 5525 isolate->heap()->undefined_value(), | 5598 isolate->heap()->undefined_value(), |
| 5526 v8::ACCESS_KEYS)) { | 5599 v8::ACCESS_KEYS)) { |
| 5527 isolate->ReportFailedAccessCheck(*jsproto, v8::ACCESS_KEYS); | 5600 isolate->ReportFailedAccessCheck(*jsproto, v8::ACCESS_KEYS); |
| 5601 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
| 5528 return *isolate->factory()->NewJSArray(0); | 5602 return *isolate->factory()->NewJSArray(0); |
| 5529 } | 5603 } |
| 5530 int n; | 5604 int n; |
| 5531 n = jsproto->NumberOfLocalProperties(filter); | 5605 n = jsproto->NumberOfLocalProperties(filter); |
| 5532 local_property_count[i] = n; | 5606 local_property_count[i] = n; |
| 5533 total_property_count += n; | 5607 total_property_count += n; |
| 5534 if (i < length - 1) { | 5608 if (i < length - 1) { |
| 5535 jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype())); | 5609 jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype())); |
| 5536 } | 5610 } |
| 5537 } | 5611 } |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5644 ASSERT_EQ(args.length(), 1); | 5718 ASSERT_EQ(args.length(), 1); |
| 5645 CONVERT_ARG_CHECKED(JSObject, raw_object, 0); | 5719 CONVERT_ARG_CHECKED(JSObject, raw_object, 0); |
| 5646 Handle<JSObject> object(raw_object); | 5720 Handle<JSObject> object(raw_object); |
| 5647 | 5721 |
| 5648 if (object->IsJSGlobalProxy()) { | 5722 if (object->IsJSGlobalProxy()) { |
| 5649 // Do access checks before going to the global object. | 5723 // Do access checks before going to the global object. |
| 5650 if (object->IsAccessCheckNeeded() && | 5724 if (object->IsAccessCheckNeeded() && |
| 5651 !isolate->MayNamedAccess(*object, isolate->heap()->undefined_value(), | 5725 !isolate->MayNamedAccess(*object, isolate->heap()->undefined_value(), |
| 5652 v8::ACCESS_KEYS)) { | 5726 v8::ACCESS_KEYS)) { |
| 5653 isolate->ReportFailedAccessCheck(*object, v8::ACCESS_KEYS); | 5727 isolate->ReportFailedAccessCheck(*object, v8::ACCESS_KEYS); |
| 5728 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
| 5654 return *isolate->factory()->NewJSArray(0); | 5729 return *isolate->factory()->NewJSArray(0); |
| 5655 } | 5730 } |
| 5656 | 5731 |
| 5657 Handle<Object> proto(object->GetPrototype(), isolate); | 5732 Handle<Object> proto(object->GetPrototype(), isolate); |
| 5658 // If proxy is detached we simply return an empty array. | 5733 // If proxy is detached we simply return an empty array. |
| 5659 if (proto->IsNull()) return *isolate->factory()->NewJSArray(0); | 5734 if (proto->IsNull()) return *isolate->factory()->NewJSArray(0); |
| 5660 object = Handle<JSObject>::cast(proto); | 5735 object = Handle<JSObject>::cast(proto); |
| 5661 } | 5736 } |
| 5662 | 5737 |
| 5663 bool threw = false; | 5738 bool threw = false; |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5725 if (index < n) { | 5800 if (index < n) { |
| 5726 return frame->GetParameter(index); | 5801 return frame->GetParameter(index); |
| 5727 } else { | 5802 } else { |
| 5728 return isolate->initial_object_prototype()->GetElement(index); | 5803 return isolate->initial_object_prototype()->GetElement(index); |
| 5729 } | 5804 } |
| 5730 } | 5805 } |
| 5731 | 5806 |
| 5732 // Handle special arguments properties. | 5807 // Handle special arguments properties. |
| 5733 if (key->Equals(isolate->heap()->length_string())) return Smi::FromInt(n); | 5808 if (key->Equals(isolate->heap()->length_string())) return Smi::FromInt(n); |
| 5734 if (key->Equals(isolate->heap()->callee_string())) { | 5809 if (key->Equals(isolate->heap()->callee_string())) { |
| 5735 Object* function = frame->function(); | 5810 JSFunction* function = frame->function(); |
| 5736 if (function->IsJSFunction() && | 5811 if (!function->shared()->is_classic_mode()) { |
| 5737 !JSFunction::cast(function)->shared()->is_classic_mode()) { | |
| 5738 return isolate->Throw(*isolate->factory()->NewTypeError( | 5812 return isolate->Throw(*isolate->factory()->NewTypeError( |
| 5739 "strict_arguments_callee", HandleVector<Object>(NULL, 0))); | 5813 "strict_arguments_callee", HandleVector<Object>(NULL, 0))); |
| 5740 } | 5814 } |
| 5741 return function; | 5815 return function; |
| 5742 } | 5816 } |
| 5743 | 5817 |
| 5744 // Lookup in the initial Object.prototype object. | 5818 // Lookup in the initial Object.prototype object. |
| 5745 return isolate->initial_object_prototype()->GetProperty(*key); | 5819 return isolate->initial_object_prototype()->GetProperty(*key); |
| 5746 } | 5820 } |
| 5747 | 5821 |
| (...skipping 2466 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8214 | 8288 |
| 8215 ASSERT(deoptimizer->compiled_code_kind() == Code::OPTIMIZED_FUNCTION); | 8289 ASSERT(deoptimizer->compiled_code_kind() == Code::OPTIMIZED_FUNCTION); |
| 8216 | 8290 |
| 8217 // Make sure to materialize objects before causing any allocation. | 8291 // Make sure to materialize objects before causing any allocation. |
| 8218 JavaScriptFrameIterator it(isolate); | 8292 JavaScriptFrameIterator it(isolate); |
| 8219 deoptimizer->MaterializeHeapObjects(&it); | 8293 deoptimizer->MaterializeHeapObjects(&it); |
| 8220 delete deoptimizer; | 8294 delete deoptimizer; |
| 8221 | 8295 |
| 8222 JavaScriptFrame* frame = it.frame(); | 8296 JavaScriptFrame* frame = it.frame(); |
| 8223 RUNTIME_ASSERT(frame->function()->IsJSFunction()); | 8297 RUNTIME_ASSERT(frame->function()->IsJSFunction()); |
| 8224 Handle<JSFunction> function(JSFunction::cast(frame->function()), isolate); | 8298 Handle<JSFunction> function(frame->function(), isolate); |
| 8225 Handle<Code> optimized_code(function->code()); | 8299 Handle<Code> optimized_code(function->code()); |
| 8226 RUNTIME_ASSERT((type != Deoptimizer::EAGER && | 8300 RUNTIME_ASSERT((type != Deoptimizer::EAGER && |
| 8227 type != Deoptimizer::SOFT) || function->IsOptimized()); | 8301 type != Deoptimizer::SOFT) || function->IsOptimized()); |
| 8228 | 8302 |
| 8229 // Avoid doing too much work when running with --always-opt and keep | 8303 // Avoid doing too much work when running with --always-opt and keep |
| 8230 // the optimized code around. | 8304 // the optimized code around. |
| 8231 if (FLAG_always_opt || type == Deoptimizer::LAZY) { | 8305 if (FLAG_always_opt || type == Deoptimizer::LAZY) { |
| 8232 return isolate->heap()->undefined_value(); | 8306 return isolate->heap()->undefined_value(); |
| 8233 } | 8307 } |
| 8234 | 8308 |
| 8235 // Find other optimized activations of the function or functions that | 8309 // Find other optimized activations of the function or functions that |
| 8236 // share the same optimized code. | 8310 // share the same optimized code. |
| 8237 bool has_other_activations = false; | 8311 bool has_other_activations = false; |
| 8238 while (!it.done()) { | 8312 while (!it.done()) { |
| 8239 JavaScriptFrame* frame = it.frame(); | 8313 JavaScriptFrame* frame = it.frame(); |
| 8240 JSFunction* other_function = JSFunction::cast(frame->function()); | 8314 JSFunction* other_function = frame->function(); |
| 8241 if (frame->is_optimized() && other_function->code() == function->code()) { | 8315 if (frame->is_optimized() && other_function->code() == function->code()) { |
| 8242 has_other_activations = true; | 8316 has_other_activations = true; |
| 8243 break; | 8317 break; |
| 8244 } | 8318 } |
| 8245 it.Advance(); | 8319 it.Advance(); |
| 8246 } | 8320 } |
| 8247 | 8321 |
| 8248 if (!has_other_activations) { | 8322 if (!has_other_activations) { |
| 8249 ActivationsFinder activations_finder(*function); | 8323 ActivationsFinder activations_finder(*function); |
| 8250 isolate->thread_manager()->IterateArchivedThreads(&activations_finder); | 8324 isolate->thread_manager()->IterateArchivedThreads(&activations_finder); |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8339 } | 8413 } |
| 8340 } else if (type->IsOneByteEqualTo(STATIC_ASCII_VECTOR("parallel"))) { | 8414 } else if (type->IsOneByteEqualTo(STATIC_ASCII_VECTOR("parallel"))) { |
| 8341 function->MarkForParallelRecompilation(); | 8415 function->MarkForParallelRecompilation(); |
| 8342 } | 8416 } |
| 8343 } | 8417 } |
| 8344 | 8418 |
| 8345 return isolate->heap()->undefined_value(); | 8419 return isolate->heap()->undefined_value(); |
| 8346 } | 8420 } |
| 8347 | 8421 |
| 8348 | 8422 |
| 8423 RUNTIME_FUNCTION(MaybeObject*, Runtime_NeverOptimize) { |
| 8424 HandleScope scope(isolate); |
| 8425 |
| 8426 if (args.length() == 0) { |
| 8427 // Disable optimization for the calling function. |
| 8428 JavaScriptFrameIterator it(isolate); |
| 8429 if (!it.done()) { |
| 8430 it.frame()->function()->shared()->set_optimization_disabled(true); |
| 8431 } |
| 8432 return isolate->heap()->undefined_value(); |
| 8433 } |
| 8434 |
| 8435 // Disable optimization for the functions passed. |
| 8436 for (int i = 0; i < args.length(); i++) { |
| 8437 CONVERT_ARG_CHECKED(JSFunction, function, i); |
| 8438 function->shared()->set_optimization_disabled(true); |
| 8439 } |
| 8440 return isolate->heap()->undefined_value(); |
| 8441 } |
| 8442 |
| 8443 |
| 8349 RUNTIME_FUNCTION(MaybeObject*, Runtime_CompleteOptimization) { | 8444 RUNTIME_FUNCTION(MaybeObject*, Runtime_CompleteOptimization) { |
| 8350 HandleScope scope(isolate); | 8445 HandleScope scope(isolate); |
| 8351 ASSERT(args.length() == 1); | 8446 ASSERT(args.length() == 1); |
| 8352 CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); | 8447 CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); |
| 8353 if (FLAG_parallel_recompilation && V8::UseCrankshaft()) { | 8448 if (FLAG_parallel_recompilation && V8::UseCrankshaft()) { |
| 8354 // While function is in optimization pipeline, it is marked accordingly. | 8449 // While function is in optimization pipeline, it is marked accordingly. |
| 8355 // Note that if the debugger is activated during parallel recompilation, | 8450 // Note that if the debugger is activated during parallel recompilation, |
| 8356 // the function will be marked with the lazy-recompile builtin, which is | 8451 // the function will be marked with the lazy-recompile builtin, which is |
| 8357 // not related to parallel recompilation. | 8452 // not related to parallel recompilation. |
| 8358 while (function->IsMarkedForParallelRecompilation() || | 8453 while (function->IsMarkedForParallelRecompilation() || |
| 8359 function->IsInRecompileQueue() || | 8454 function->IsInRecompileQueue() || |
| 8360 function->IsMarkedForInstallingRecompiledCode()) { | 8455 function->IsMarkedForInstallingRecompiledCode()) { |
| 8361 isolate->optimizing_compiler_thread()->InstallOptimizedFunctions(); | 8456 isolate->optimizing_compiler_thread()->InstallOptimizedFunctions(); |
| 8362 OS::Sleep(50); | 8457 OS::Sleep(50); |
| 8363 } | 8458 } |
| 8364 } | 8459 } |
| 8365 return isolate->heap()->undefined_value(); | 8460 return isolate->heap()->undefined_value(); |
| 8366 } | 8461 } |
| 8367 | 8462 |
| 8368 | 8463 |
| 8369 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetOptimizationStatus) { | 8464 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetOptimizationStatus) { |
| 8370 HandleScope scope(isolate); | 8465 HandleScope scope(isolate); |
| 8371 ASSERT(args.length() == 1); | 8466 ASSERT(args.length() == 1); |
| 8372 // The least significant bit (after untagging) indicates whether the | |
| 8373 // function is currently optimized, regardless of reason. | |
| 8374 if (!V8::UseCrankshaft()) { | 8467 if (!V8::UseCrankshaft()) { |
| 8375 return Smi::FromInt(4); // 4 == "never". | 8468 return Smi::FromInt(4); // 4 == "never". |
| 8376 } | 8469 } |
| 8377 CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); | 8470 CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); |
| 8378 if (FLAG_parallel_recompilation) { | 8471 if (FLAG_parallel_recompilation) { |
| 8379 if (function->IsMarkedForLazyRecompilation()) { | 8472 if (function->IsMarkedForLazyRecompilation()) { |
| 8380 return Smi::FromInt(5); | 8473 return Smi::FromInt(5); // 5 == "parallel recompilation". |
| 8381 } | 8474 } |
| 8382 } | 8475 } |
| 8383 if (FLAG_always_opt) { | 8476 if (FLAG_always_opt) { |
| 8384 // We may have always opt, but that is more best-effort than a real | 8477 // We may have always opt, but that is more best-effort than a real |
| 8385 // promise, so we still say "no" if it is not optimized. | 8478 // promise, so we still say "no" if it is not optimized. |
| 8386 return function->IsOptimized() ? Smi::FromInt(3) // 3 == "always". | 8479 return function->IsOptimized() ? Smi::FromInt(3) // 3 == "always". |
| 8387 : Smi::FromInt(2); // 2 == "no". | 8480 : Smi::FromInt(2); // 2 == "no". |
| 8388 } | 8481 } |
| 8482 if (FLAG_deopt_every_n_times) { |
| 8483 return Smi::FromInt(6); // 6 == "maybe deopted". |
| 8484 } |
| 8389 return function->IsOptimized() ? Smi::FromInt(1) // 1 == "yes". | 8485 return function->IsOptimized() ? Smi::FromInt(1) // 1 == "yes". |
| 8390 : Smi::FromInt(2); // 2 == "no". | 8486 : Smi::FromInt(2); // 2 == "no". |
| 8391 } | 8487 } |
| 8392 | 8488 |
| 8393 | 8489 |
| 8394 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetOptimizationCount) { | 8490 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetOptimizationCount) { |
| 8395 HandleScope scope(isolate); | 8491 HandleScope scope(isolate); |
| 8396 ASSERT(args.length() == 1); | 8492 ASSERT(args.length() == 1); |
| 8397 CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); | 8493 CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); |
| 8398 return Smi::FromInt(function->shared()->opt_count()); | 8494 return Smi::FromInt(function->shared()->opt_count()); |
| (...skipping 2807 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11206 static bool SetLocalVariableValue(Isolate* isolate, | 11302 static bool SetLocalVariableValue(Isolate* isolate, |
| 11207 JavaScriptFrame* frame, | 11303 JavaScriptFrame* frame, |
| 11208 int inlined_jsframe_index, | 11304 int inlined_jsframe_index, |
| 11209 Handle<String> variable_name, | 11305 Handle<String> variable_name, |
| 11210 Handle<Object> new_value) { | 11306 Handle<Object> new_value) { |
| 11211 if (inlined_jsframe_index != 0 || frame->is_optimized()) { | 11307 if (inlined_jsframe_index != 0 || frame->is_optimized()) { |
| 11212 // Optimized frames are not supported. | 11308 // Optimized frames are not supported. |
| 11213 return false; | 11309 return false; |
| 11214 } | 11310 } |
| 11215 | 11311 |
| 11216 Handle<JSFunction> function(JSFunction::cast(frame->function())); | 11312 Handle<JSFunction> function(frame->function()); |
| 11217 Handle<SharedFunctionInfo> shared(function->shared()); | 11313 Handle<SharedFunctionInfo> shared(function->shared()); |
| 11218 Handle<ScopeInfo> scope_info(shared->scope_info()); | 11314 Handle<ScopeInfo> scope_info(shared->scope_info()); |
| 11219 | 11315 |
| 11220 bool default_result = false; | 11316 bool default_result = false; |
| 11221 | 11317 |
| 11222 // Parameters. | 11318 // Parameters. |
| 11223 for (int i = 0; i < scope_info->ParameterCount(); ++i) { | 11319 for (int i = 0; i < scope_info->ParameterCount(); ++i) { |
| 11224 if (scope_info->ParameterName(i)->Equals(*variable_name)) { | 11320 if (scope_info->ParameterName(i)->Equals(*variable_name)) { |
| 11225 frame->SetParameterValue(i, *new_value); | 11321 frame->SetParameterValue(i, *new_value); |
| 11226 // Argument might be shadowed in heap context, don't stop here. | 11322 // Argument might be shadowed in heap context, don't stop here. |
| (...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11453 ScopeTypeBlock, | 11549 ScopeTypeBlock, |
| 11454 ScopeTypeModule | 11550 ScopeTypeModule |
| 11455 }; | 11551 }; |
| 11456 | 11552 |
| 11457 ScopeIterator(Isolate* isolate, | 11553 ScopeIterator(Isolate* isolate, |
| 11458 JavaScriptFrame* frame, | 11554 JavaScriptFrame* frame, |
| 11459 int inlined_jsframe_index) | 11555 int inlined_jsframe_index) |
| 11460 : isolate_(isolate), | 11556 : isolate_(isolate), |
| 11461 frame_(frame), | 11557 frame_(frame), |
| 11462 inlined_jsframe_index_(inlined_jsframe_index), | 11558 inlined_jsframe_index_(inlined_jsframe_index), |
| 11463 function_(JSFunction::cast(frame->function())), | 11559 function_(frame->function()), |
| 11464 context_(Context::cast(frame->context())), | 11560 context_(Context::cast(frame->context())), |
| 11465 nested_scope_chain_(4), | 11561 nested_scope_chain_(4), |
| 11466 failed_(false) { | 11562 failed_(false) { |
| 11467 | 11563 |
| 11468 // Catch the case when the debugger stops in an internal function. | 11564 // Catch the case when the debugger stops in an internal function. |
| 11469 Handle<SharedFunctionInfo> shared_info(function_->shared()); | 11565 Handle<SharedFunctionInfo> shared_info(function_->shared()); |
| 11470 Handle<ScopeInfo> scope_info(shared_info->scope_info()); | 11566 Handle<ScopeInfo> scope_info(shared_info->scope_info()); |
| 11471 if (shared_info->script() == isolate->heap()->undefined_value()) { | 11567 if (shared_info->script() == isolate->heap()->undefined_value()) { |
| 11472 while (context_->closure() == *function_) { | 11568 while (context_->closure() == *function_) { |
| 11473 context_ = Handle<Context>(context_->previous(), isolate_); | 11569 context_ = Handle<Context>(context_->previous(), isolate_); |
| (...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11834 if (!maybe_check->ToObject(&check)) return maybe_check; | 11930 if (!maybe_check->ToObject(&check)) return maybe_check; |
| 11835 } | 11931 } |
| 11836 CONVERT_SMI_ARG_CHECKED(wrapped_id, 1); | 11932 CONVERT_SMI_ARG_CHECKED(wrapped_id, 1); |
| 11837 | 11933 |
| 11838 // Get the frame where the debugging is performed. | 11934 // Get the frame where the debugging is performed. |
| 11839 StackFrame::Id id = UnwrapFrameId(wrapped_id); | 11935 StackFrame::Id id = UnwrapFrameId(wrapped_id); |
| 11840 JavaScriptFrameIterator frame_it(isolate, id); | 11936 JavaScriptFrameIterator frame_it(isolate, id); |
| 11841 JavaScriptFrame* frame = frame_it.frame(); | 11937 JavaScriptFrame* frame = frame_it.frame(); |
| 11842 | 11938 |
| 11843 Handle<SharedFunctionInfo> shared = | 11939 Handle<SharedFunctionInfo> shared = |
| 11844 Handle<SharedFunctionInfo>(JSFunction::cast(frame->function())->shared()); | 11940 Handle<SharedFunctionInfo>(frame->function()->shared()); |
| 11845 Handle<DebugInfo> debug_info = Debug::GetDebugInfo(shared); | 11941 Handle<DebugInfo> debug_info = Debug::GetDebugInfo(shared); |
| 11846 | 11942 |
| 11847 int len = 0; | 11943 int len = 0; |
| 11848 Handle<JSArray> array(isolate->factory()->NewJSArray(10)); | 11944 Handle<JSArray> array(isolate->factory()->NewJSArray(10)); |
| 11849 // Find the break point where execution has stopped. | 11945 // Find the break point where execution has stopped. |
| 11850 BreakLocationIterator break_location_iterator(debug_info, | 11946 BreakLocationIterator break_location_iterator(debug_info, |
| 11851 ALL_BREAK_LOCATIONS); | 11947 ALL_BREAK_LOCATIONS); |
| 11852 | 11948 |
| 11853 break_location_iterator.FindBreakLocationFromAddress(frame->pc()); | 11949 break_location_iterator.FindBreakLocationFromAddress(frame->pc()); |
| 11854 int current_statement_pos = break_location_iterator.statement_position(); | 11950 int current_statement_pos = break_location_iterator.statement_position(); |
| (...skipping 1882 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13737 if (proto->IsNull()) return isolate->heap()->false_value(); | 13833 if (proto->IsNull()) return isolate->heap()->false_value(); |
| 13738 ASSERT(proto->IsJSGlobalObject()); | 13834 ASSERT(proto->IsJSGlobalObject()); |
| 13739 obj = JSReceiver::cast(proto); | 13835 obj = JSReceiver::cast(proto); |
| 13740 } | 13836 } |
| 13741 return isolate->heap()->ToBoolean(obj->map()->is_observed()); | 13837 return isolate->heap()->ToBoolean(obj->map()->is_observed()); |
| 13742 } | 13838 } |
| 13743 | 13839 |
| 13744 | 13840 |
| 13745 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetIsObserved) { | 13841 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetIsObserved) { |
| 13746 SealHandleScope shs(isolate); | 13842 SealHandleScope shs(isolate); |
| 13747 ASSERT(args.length() == 2); | 13843 ASSERT(args.length() == 1); |
| 13748 CONVERT_ARG_CHECKED(JSReceiver, obj, 0); | 13844 CONVERT_ARG_CHECKED(JSReceiver, obj, 0); |
| 13749 CONVERT_BOOLEAN_ARG_CHECKED(is_observed, 1); | |
| 13750 if (obj->IsJSGlobalProxy()) { | 13845 if (obj->IsJSGlobalProxy()) { |
| 13751 Object* proto = obj->GetPrototype(); | 13846 Object* proto = obj->GetPrototype(); |
| 13752 if (proto->IsNull()) return isolate->heap()->undefined_value(); | 13847 if (proto->IsNull()) return isolate->heap()->undefined_value(); |
| 13753 ASSERT(proto->IsJSGlobalObject()); | 13848 ASSERT(proto->IsJSGlobalObject()); |
| 13754 obj = JSReceiver::cast(proto); | 13849 obj = JSReceiver::cast(proto); |
| 13755 } | 13850 } |
| 13756 ASSERT(!(obj->map()->is_observed() && obj->IsJSObject() && | 13851 ASSERT(!(obj->map()->is_observed() && obj->IsJSObject() && |
| 13757 JSObject::cast(obj)->HasFastElements())); | 13852 JSObject::cast(obj)->HasFastElements())); |
| 13758 if (obj->map()->is_observed() != is_observed) { | 13853 ASSERT(obj->IsJSObject()); |
| 13759 if (is_observed && obj->IsJSObject() && | 13854 return JSObject::cast(obj)->SetObserved(isolate); |
| 13760 !JSObject::cast(obj)->HasExternalArrayElements()) { | |
| 13761 // Go to dictionary mode, so that we don't skip map checks. | |
| 13762 MaybeObject* maybe = JSObject::cast(obj)->NormalizeElements(); | |
| 13763 if (maybe->IsFailure()) return maybe; | |
| 13764 ASSERT(!JSObject::cast(obj)->HasFastElements()); | |
| 13765 } | |
| 13766 MaybeObject* maybe = obj->map()->Copy(); | |
| 13767 Map* map; | |
| 13768 if (!maybe->To(&map)) return maybe; | |
| 13769 map->set_is_observed(is_observed); | |
| 13770 obj->set_map(map); | |
| 13771 } | |
| 13772 return isolate->heap()->undefined_value(); | |
| 13773 } | 13855 } |
| 13774 | 13856 |
| 13775 | 13857 |
| 13776 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetObserverDeliveryPending) { | 13858 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetObserverDeliveryPending) { |
| 13777 SealHandleScope shs(isolate); | 13859 SealHandleScope shs(isolate); |
| 13778 ASSERT(args.length() == 0); | 13860 ASSERT(args.length() == 0); |
| 13779 isolate->set_observer_delivery_pending(true); | 13861 isolate->set_observer_delivery_pending(true); |
| 13780 return isolate->heap()->undefined_value(); | 13862 return isolate->heap()->undefined_value(); |
| 13781 } | 13863 } |
| 13782 | 13864 |
| (...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13996 // Handle last resort GC and make sure to allow future allocations | 14078 // Handle last resort GC and make sure to allow future allocations |
| 13997 // to grow the heap without causing GCs (if possible). | 14079 // to grow the heap without causing GCs (if possible). |
| 13998 isolate->counters()->gc_last_resort_from_js()->Increment(); | 14080 isolate->counters()->gc_last_resort_from_js()->Increment(); |
| 13999 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, | 14081 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, |
| 14000 "Runtime::PerformGC"); | 14082 "Runtime::PerformGC"); |
| 14001 } | 14083 } |
| 14002 } | 14084 } |
| 14003 | 14085 |
| 14004 | 14086 |
| 14005 } } // namespace v8::internal | 14087 } } // namespace v8::internal |
| OLD | NEW |