| OLD | NEW |
| 1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2009 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 501 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 512 } | 512 } |
| 513 return TypeError("undefined_method", object, name); | 513 return TypeError("undefined_method", object, name); |
| 514 } | 514 } |
| 515 | 515 |
| 516 // Lookup is valid: Update inline cache and stub cache. | 516 // Lookup is valid: Update inline cache and stub cache. |
| 517 if (FLAG_use_ic) { | 517 if (FLAG_use_ic) { |
| 518 UpdateCaches(&lookup, state, object, name); | 518 UpdateCaches(&lookup, state, object, name); |
| 519 } | 519 } |
| 520 | 520 |
| 521 // Get the property. | 521 // Get the property. |
| 522 Object* result; |
| 523 { TryAllocation t = object->GetProperty(*object, &lookup, *name, &attr); |
| 524 if (!t->ToObject(&result)) return t; |
| 525 } |
| 522 PropertyAttributes attr; | 526 PropertyAttributes attr; |
| 523 Object* result = object->GetProperty(*object, &lookup, *name, &attr); | |
| 524 if (result->IsFailure()) return result; | |
| 525 if (lookup.type() == INTERCEPTOR) { | 527 if (lookup.type() == INTERCEPTOR) { |
| 526 // If the object does not have the requested property, check which | 528 // If the object does not have the requested property, check which |
| 527 // exception we need to throw. | 529 // exception we need to throw. |
| 528 if (attr == ABSENT) { | 530 if (attr == ABSENT) { |
| 529 if (IsContextual(object)) { | 531 if (IsContextual(object)) { |
| 530 return ReferenceError("not_defined", name); | 532 return ReferenceError("not_defined", name); |
| 531 } | 533 } |
| 532 return TypeError("undefined_method", object, name); | 534 return TypeError("undefined_method", object, name); |
| 533 } | 535 } |
| 534 } | 536 } |
| (...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 860 } | 862 } |
| 861 } | 863 } |
| 862 | 864 |
| 863 // Update inline cache and stub cache. | 865 // Update inline cache and stub cache. |
| 864 if (FLAG_use_ic) { | 866 if (FLAG_use_ic) { |
| 865 UpdateCaches(&lookup, state, object, name); | 867 UpdateCaches(&lookup, state, object, name); |
| 866 } | 868 } |
| 867 | 869 |
| 868 PropertyAttributes attr; | 870 PropertyAttributes attr; |
| 869 if (lookup.IsProperty() && lookup.type() == INTERCEPTOR) { | 871 if (lookup.IsProperty() && lookup.type() == INTERCEPTOR) { |
| 872 Object* result; |
| 873 { TryAllocation t = object->GetProperty(*object, &lookup, *name, &attr); |
| 874 if (!t->ToObject(&result)) return t; |
| 875 } |
| 870 // Get the property. | 876 // Get the property. |
| 871 Object* result = object->GetProperty(*object, &lookup, *name, &attr); | |
| 872 if (result->IsFailure()) return result; | |
| 873 // If the property is not present, check if we need to throw an | 877 // If the property is not present, check if we need to throw an |
| 874 // exception. | 878 // exception. |
| 875 if (attr == ABSENT && IsContextual(object)) { | 879 if (attr == ABSENT && IsContextual(object)) { |
| 876 return ReferenceError("not_defined", name); | 880 return ReferenceError("not_defined", name); |
| 877 } | 881 } |
| 878 return result; | 882 return result; |
| 879 } | 883 } |
| 880 | 884 |
| 881 // Get the property. | 885 // Get the property. |
| 882 return object->GetProperty(*object, &lookup, *name, &attr); | 886 return object->GetProperty(*object, &lookup, *name, &attr); |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 996 // If the object is undefined or null it's illegal to try to get any | 1000 // If the object is undefined or null it's illegal to try to get any |
| 997 // of its properties; throw a TypeError in that case. | 1001 // of its properties; throw a TypeError in that case. |
| 998 if (object->IsUndefined() || object->IsNull()) { | 1002 if (object->IsUndefined() || object->IsNull()) { |
| 999 return TypeError("non_object_property_load", object, name); | 1003 return TypeError("non_object_property_load", object, name); |
| 1000 } | 1004 } |
| 1001 | 1005 |
| 1002 if (FLAG_use_ic) { | 1006 if (FLAG_use_ic) { |
| 1003 // Use specialized code for getting the length of strings. | 1007 // Use specialized code for getting the length of strings. |
| 1004 if (object->IsString() && name->Equals(Heap::length_symbol())) { | 1008 if (object->IsString() && name->Equals(Heap::length_symbol())) { |
| 1005 Handle<String> string = Handle<String>::cast(object); | 1009 Handle<String> string = Handle<String>::cast(object); |
| 1010 { TryAllocation t = |
| 1011 StubCache::ComputeKeyedLoadStringLength(*name, *string); |
| 1012 if (!t->ToObject(&code)) return t; |
| 1013 } |
| 1006 Object* code = NULL; | 1014 Object* code = NULL; |
| 1007 code = StubCache::ComputeKeyedLoadStringLength(*name, *string); | |
| 1008 if (code->IsFailure()) return code; | |
| 1009 set_target(Code::cast(code)); | 1015 set_target(Code::cast(code)); |
| 1010 #ifdef DEBUG | 1016 #ifdef DEBUG |
| 1011 TraceIC("KeyedLoadIC", name, state, target()); | 1017 TraceIC("KeyedLoadIC", name, state, target()); |
| 1012 #endif // DEBUG | 1018 #endif // DEBUG |
| 1013 return Smi::FromInt(string->length()); | 1019 return Smi::FromInt(string->length()); |
| 1014 } | 1020 } |
| 1015 | 1021 |
| 1016 // Use specialized code for getting the length of arrays. | 1022 // Use specialized code for getting the length of arrays. |
| 1017 if (object->IsJSArray() && name->Equals(Heap::length_symbol())) { | 1023 if (object->IsJSArray() && name->Equals(Heap::length_symbol())) { |
| 1024 Object* code; |
| 1025 { TryAllocation t = |
| 1026 StubCache::ComputeKeyedLoadArrayLength(*name, *array); |
| 1027 if (!t->ToObject(&code)) return t; |
| 1028 } |
| 1018 Handle<JSArray> array = Handle<JSArray>::cast(object); | 1029 Handle<JSArray> array = Handle<JSArray>::cast(object); |
| 1019 Object* code = StubCache::ComputeKeyedLoadArrayLength(*name, *array); | |
| 1020 if (code->IsFailure()) return code; | |
| 1021 set_target(Code::cast(code)); | 1030 set_target(Code::cast(code)); |
| 1022 #ifdef DEBUG | 1031 #ifdef DEBUG |
| 1023 TraceIC("KeyedLoadIC", name, state, target()); | 1032 TraceIC("KeyedLoadIC", name, state, target()); |
| 1024 #endif // DEBUG | 1033 #endif // DEBUG |
| 1025 return JSArray::cast(*object)->length(); | 1034 return JSArray::cast(*object)->length(); |
| 1026 } | 1035 } |
| 1027 | 1036 |
| 1028 // Use specialized code for getting prototype of functions. | 1037 // Use specialized code for getting prototype of functions. |
| 1029 if (object->IsJSFunction() && name->Equals(Heap::prototype_symbol()) && | 1038 if (object->IsJSFunction() && name->Equals(Heap::prototype_symbol()) && |
| 1030 JSFunction::cast(*object)->should_have_prototype()) { | 1039 JSFunction::cast(*object)->should_have_prototype()) { |
| 1031 Handle<JSFunction> function = Handle<JSFunction>::cast(object); | 1040 Handle<JSFunction> function = Handle<JSFunction>::cast(object); |
| 1032 Object* code = | 1041 Object* code; |
| 1033 StubCache::ComputeKeyedLoadFunctionPrototype(*name, *function); | 1042 { TryAllocation t = |
| 1034 if (code->IsFailure()) return code; | 1043 StubCache::ComputeKeyedLoadFunctionPrototype(*name, *function); |
| 1044 if (!t->ToObject(&code)) return t; |
| 1045 } |
| 1035 set_target(Code::cast(code)); | 1046 set_target(Code::cast(code)); |
| 1036 #ifdef DEBUG | 1047 #ifdef DEBUG |
| 1037 TraceIC("KeyedLoadIC", name, state, target()); | 1048 TraceIC("KeyedLoadIC", name, state, target()); |
| 1038 #endif // DEBUG | 1049 #endif // DEBUG |
| 1039 return Accessors::FunctionGetPrototype(*object, 0); | 1050 return Accessors::FunctionGetPrototype(*object, 0); |
| 1040 } | 1051 } |
| 1041 } | 1052 } |
| 1042 | 1053 |
| 1043 // Check if the name is trivially convertible to an index and get | 1054 // Check if the name is trivially convertible to an index and get |
| 1044 // the element or char if so. | 1055 // the element or char if so. |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1060 return ReferenceError("not_defined", name); | 1071 return ReferenceError("not_defined", name); |
| 1061 } | 1072 } |
| 1062 } | 1073 } |
| 1063 | 1074 |
| 1064 if (FLAG_use_ic) { | 1075 if (FLAG_use_ic) { |
| 1065 UpdateCaches(&lookup, state, object, name); | 1076 UpdateCaches(&lookup, state, object, name); |
| 1066 } | 1077 } |
| 1067 | 1078 |
| 1068 PropertyAttributes attr; | 1079 PropertyAttributes attr; |
| 1069 if (lookup.IsProperty() && lookup.type() == INTERCEPTOR) { | 1080 if (lookup.IsProperty() && lookup.type() == INTERCEPTOR) { |
| 1081 Object* result; |
| 1082 { TryAllocation t = object->GetProperty(*object, &lookup, *name, &attr); |
| 1083 if (!t->ToObject(&result)) return t; |
| 1084 } |
| 1070 // Get the property. | 1085 // Get the property. |
| 1071 Object* result = object->GetProperty(*object, &lookup, *name, &attr); | |
| 1072 if (result->IsFailure()) return result; | |
| 1073 // If the property is not present, check if we need to throw an | 1086 // If the property is not present, check if we need to throw an |
| 1074 // exception. | 1087 // exception. |
| 1075 if (attr == ABSENT && IsContextual(object)) { | 1088 if (attr == ABSENT && IsContextual(object)) { |
| 1076 return ReferenceError("not_defined", name); | 1089 return ReferenceError("not_defined", name); |
| 1077 } | 1090 } |
| 1078 return result; | 1091 return result; |
| 1079 } | 1092 } |
| 1080 | 1093 |
| 1081 return object->GetProperty(*object, &lookup, *name, &attr); | 1094 return object->GetProperty(*object, &lookup, *name, &attr); |
| 1082 } | 1095 } |
| (...skipping 541 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1624 args.at<Object>(2)); | 1637 args.at<Object>(2)); |
| 1625 } | 1638 } |
| 1626 | 1639 |
| 1627 | 1640 |
| 1628 Object* StoreIC_ArrayLength(Arguments args) { | 1641 Object* StoreIC_ArrayLength(Arguments args) { |
| 1629 NoHandleAllocation nha; | 1642 NoHandleAllocation nha; |
| 1630 | 1643 |
| 1631 ASSERT(args.length() == 2); | 1644 ASSERT(args.length() == 2); |
| 1632 JSObject* receiver = JSObject::cast(args[0]); | 1645 JSObject* receiver = JSObject::cast(args[0]); |
| 1633 Object* len = args[1]; | 1646 Object* len = args[1]; |
| 1647 Object* result; |
| 1648 { TryAllocation t = receiver->SetElementsLength(len); |
| 1649 if (!t->ToObject(&result)) return t; |
| 1650 } |
| 1634 | 1651 |
| 1635 Object* result = receiver->SetElementsLength(len); | |
| 1636 if (result->IsFailure()) return result; | |
| 1637 return len; | 1652 return len; |
| 1638 } | 1653 } |
| 1639 | 1654 |
| 1640 | 1655 |
| 1641 // Extend storage is called in a store inline cache when | 1656 // Extend storage is called in a store inline cache when |
| 1642 // it is necessary to extend the properties array of a | 1657 // it is necessary to extend the properties array of a |
| 1643 // JSObject. | 1658 // JSObject. |
| 1644 Object* SharedStoreIC_ExtendStorage(Arguments args) { | 1659 Object* SharedStoreIC_ExtendStorage(Arguments args) { |
| 1645 NoHandleAllocation na; | 1660 NoHandleAllocation na; |
| 1646 ASSERT(args.length() == 3); | 1661 ASSERT(args.length() == 3); |
| 1647 | 1662 |
| 1648 // Convert the parameters | 1663 // Convert the parameters |
| 1649 JSObject* object = JSObject::cast(args[0]); | 1664 JSObject* object = JSObject::cast(args[0]); |
| 1650 Map* transition = Map::cast(args[1]); | 1665 Map* transition = Map::cast(args[1]); |
| 1651 Object* value = args[2]; | 1666 Object* value = args[2]; |
| 1652 | 1667 |
| 1653 // Check the object has run out out property space. | 1668 // Check the object has run out out property space. |
| 1654 ASSERT(object->HasFastProperties()); | 1669 ASSERT(object->HasFastProperties()); |
| 1655 ASSERT(object->map()->unused_property_fields() == 0); | 1670 ASSERT(object->map()->unused_property_fields() == 0); |
| 1656 | 1671 |
| 1657 // Expand the properties array. | 1672 // Expand the properties array. |
| 1658 FixedArray* old_storage = object->properties(); | 1673 FixedArray* old_storage = object->properties(); |
| 1659 int new_unused = transition->unused_property_fields(); | 1674 int new_unused = transition->unused_property_fields(); |
| 1675 Object* result; |
| 1676 { TryAllocation t = old_storage->CopySize(new_size); |
| 1677 if (!t->ToObject(&result)) return t; |
| 1678 } |
| 1660 int new_size = old_storage->length() + new_unused + 1; | 1679 int new_size = old_storage->length() + new_unused + 1; |
| 1661 Object* result = old_storage->CopySize(new_size); | |
| 1662 if (result->IsFailure()) return result; | |
| 1663 FixedArray* new_storage = FixedArray::cast(result); | 1680 FixedArray* new_storage = FixedArray::cast(result); |
| 1664 new_storage->set(old_storage->length(), value); | 1681 new_storage->set(old_storage->length(), value); |
| 1665 | 1682 |
| 1666 // Set the new property value and do the map transition. | 1683 // Set the new property value and do the map transition. |
| 1667 object->set_properties(new_storage); | 1684 object->set_properties(new_storage); |
| 1668 object->set_map(transition); | 1685 object->set_map(transition); |
| 1669 | 1686 |
| 1670 // Return the stored value. | 1687 // Return the stored value. |
| 1671 return value; | 1688 return value; |
| 1672 } | 1689 } |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1832 #undef ADDR | 1849 #undef ADDR |
| 1833 }; | 1850 }; |
| 1834 | 1851 |
| 1835 | 1852 |
| 1836 Address IC::AddressFromUtilityId(IC::UtilityId id) { | 1853 Address IC::AddressFromUtilityId(IC::UtilityId id) { |
| 1837 return IC_utilities[id]; | 1854 return IC_utilities[id]; |
| 1838 } | 1855 } |
| 1839 | 1856 |
| 1840 | 1857 |
| 1841 } } // namespace v8::internal | 1858 } } // namespace v8::internal |
| OLD | NEW |