| 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 859 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 870 } else if (state != MEGAMORPHIC) { | 870 } else if (state != MEGAMORPHIC) { |
| 871 ASSERT(state != GENERIC); | 871 ASSERT(state != GENERIC); |
| 872 stub = megamorphic_stub(); | 872 stub = megamorphic_stub(); |
| 873 } | 873 } |
| 874 if (!stub.is_null()) { | 874 if (!stub.is_null()) { |
| 875 set_target(*stub); | 875 set_target(*stub); |
| 876 #ifdef DEBUG | 876 #ifdef DEBUG |
| 877 if (FLAG_trace_ic) PrintF("[LoadIC : +#prototype /function]\n"); | 877 if (FLAG_trace_ic) PrintF("[LoadIC : +#prototype /function]\n"); |
| 878 #endif | 878 #endif |
| 879 } | 879 } |
| 880 return Accessors::FunctionGetPrototype(*object, 0); | 880 return *Accessors::FunctionGetPrototype(object); |
| 881 } | 881 } |
| 882 } | 882 } |
| 883 | 883 |
| 884 // Check if the name is trivially convertible to an index and get | 884 // Check if the name is trivially convertible to an index and get |
| 885 // the element or char if so. | 885 // the element or char if so. |
| 886 uint32_t index; | 886 uint32_t index; |
| 887 if (kind() == Code::KEYED_LOAD_IC && name->AsArrayIndex(&index)) { | 887 if (kind() == Code::KEYED_LOAD_IC && name->AsArrayIndex(&index)) { |
| 888 // Rewrite to the generic keyed load stub. | 888 // Rewrite to the generic keyed load stub. |
| 889 if (FLAG_use_ic) set_target(*generic_stub()); | 889 if (FLAG_use_ic) set_target(*generic_stub()); |
| 890 return Runtime::GetElementOrCharAt(isolate(), object, index); | 890 return Runtime::GetElementOrCharAtOrFail(isolate(), object, index); |
| 891 } | 891 } |
| 892 | 892 |
| 893 // Named lookup in the object. | 893 // Named lookup in the object. |
| 894 LookupResult lookup(isolate()); | 894 LookupResult lookup(isolate()); |
| 895 LookupForRead(object, name, &lookup); | 895 LookupForRead(object, name, &lookup); |
| 896 | 896 |
| 897 // If we did not find a property, check if we need to throw an exception. | 897 // If we did not find a property, check if we need to throw an exception. |
| 898 if (!lookup.IsFound()) { | 898 if (!lookup.IsFound()) { |
| 899 if (IsUndeclaredGlobal(object)) { | 899 if (IsUndeclaredGlobal(object)) { |
| 900 return ReferenceError("not_defined", name); | 900 return ReferenceError("not_defined", name); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 915 RETURN_IF_EMPTY_HANDLE(isolate(), result); | 915 RETURN_IF_EMPTY_HANDLE(isolate(), result); |
| 916 // If the property is not present, check if we need to throw an | 916 // If the property is not present, check if we need to throw an |
| 917 // exception. | 917 // exception. |
| 918 if (attr == ABSENT && IsUndeclaredGlobal(object)) { | 918 if (attr == ABSENT && IsUndeclaredGlobal(object)) { |
| 919 return ReferenceError("not_defined", name); | 919 return ReferenceError("not_defined", name); |
| 920 } | 920 } |
| 921 return *result; | 921 return *result; |
| 922 } | 922 } |
| 923 | 923 |
| 924 // Get the property. | 924 // Get the property. |
| 925 return object->GetProperty(*object, &lookup, *name, &attr); | 925 return Object::GetPropertyOrFail(object, object, &lookup, name, &attr); |
| 926 } | 926 } |
| 927 | 927 |
| 928 | 928 |
| 929 static bool AddOneReceiverMapIfMissing(MapHandleList* receiver_maps, | 929 static bool AddOneReceiverMapIfMissing(MapHandleList* receiver_maps, |
| 930 Handle<Map> new_receiver_map) { | 930 Handle<Map> new_receiver_map) { |
| 931 ASSERT(!new_receiver_map.is_null()); | 931 ASSERT(!new_receiver_map.is_null()); |
| 932 for (int current = 0; current < receiver_maps->length(); ++current) { | 932 for (int current = 0; current < receiver_maps->length(); ++current) { |
| 933 if (!receiver_maps->at(current).is_null() && | 933 if (!receiver_maps->at(current).is_null() && |
| 934 receiver_maps->at(current).is_identical_to(new_receiver_map)) { | 934 receiver_maps->at(current).is_identical_to(new_receiver_map)) { |
| 935 return false; | 935 return false; |
| (...skipping 533 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1469 | 1469 |
| 1470 | 1470 |
| 1471 MaybeObject* StoreIC::Store(State state, | 1471 MaybeObject* StoreIC::Store(State state, |
| 1472 StrictModeFlag strict_mode, | 1472 StrictModeFlag strict_mode, |
| 1473 Handle<Object> object, | 1473 Handle<Object> object, |
| 1474 Handle<String> name, | 1474 Handle<String> name, |
| 1475 Handle<Object> value, | 1475 Handle<Object> value, |
| 1476 JSReceiver::StoreFromKeyed store_mode) { | 1476 JSReceiver::StoreFromKeyed store_mode) { |
| 1477 // Handle proxies. | 1477 // Handle proxies. |
| 1478 if (object->IsJSProxy()) { | 1478 if (object->IsJSProxy()) { |
| 1479 return JSProxy::cast(*object)-> | 1479 return JSReceiver::SetPropertyOrFail( |
| 1480 SetProperty(*name, *value, NONE, strict_mode); | 1480 Handle<JSReceiver>::cast(object), name, value, NONE, strict_mode); |
| 1481 } | 1481 } |
| 1482 | 1482 |
| 1483 // If the object is undefined or null it's illegal to try to set any | 1483 // If the object is undefined or null it's illegal to try to set any |
| 1484 // properties on it; throw a TypeError in that case. | 1484 // properties on it; throw a TypeError in that case. |
| 1485 if (object->IsUndefined() || object->IsNull()) { | 1485 if (object->IsUndefined() || object->IsNull()) { |
| 1486 return TypeError("non_object_property_store", object, name); | 1486 return TypeError("non_object_property_store", object, name); |
| 1487 } | 1487 } |
| 1488 | 1488 |
| 1489 // The length property of string values is read-only. Throw in strict mode. | 1489 // The length property of string values is read-only. Throw in strict mode. |
| 1490 if (strict_mode == kStrictMode && object->IsString() && | 1490 if (strict_mode == kStrictMode && object->IsString() && |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1502 uint32_t index; | 1502 uint32_t index; |
| 1503 if (name->AsArrayIndex(&index)) { | 1503 if (name->AsArrayIndex(&index)) { |
| 1504 Handle<Object> result = | 1504 Handle<Object> result = |
| 1505 JSObject::SetElement(receiver, index, value, NONE, strict_mode); | 1505 JSObject::SetElement(receiver, index, value, NONE, strict_mode); |
| 1506 RETURN_IF_EMPTY_HANDLE(isolate(), result); | 1506 RETURN_IF_EMPTY_HANDLE(isolate(), result); |
| 1507 return *value; | 1507 return *value; |
| 1508 } | 1508 } |
| 1509 | 1509 |
| 1510 // Observed objects are always modified through the runtime. | 1510 // Observed objects are always modified through the runtime. |
| 1511 if (FLAG_harmony_observation && receiver->map()->is_observed()) { | 1511 if (FLAG_harmony_observation && receiver->map()->is_observed()) { |
| 1512 return receiver->SetProperty(*name, *value, NONE, strict_mode, store_mode); | 1512 return JSReceiver::SetPropertyOrFail( |
| 1513 receiver, name, value, NONE, strict_mode, store_mode); |
| 1513 } | 1514 } |
| 1514 | 1515 |
| 1515 // Use specialized code for setting the length of arrays with fast | 1516 // Use specialized code for setting the length of arrays with fast |
| 1516 // properties. Slow properties might indicate redefinition of the length | 1517 // properties. Slow properties might indicate redefinition of the length |
| 1517 // property. | 1518 // property. |
| 1518 if (FLAG_use_ic && | 1519 if (FLAG_use_ic && |
| 1519 receiver->IsJSArray() && | 1520 receiver->IsJSArray() && |
| 1520 name->Equals(isolate()->heap()->length_string()) && | 1521 name->Equals(isolate()->heap()->length_string()) && |
| 1521 Handle<JSArray>::cast(receiver)->AllowsSetElementsLength() && | 1522 Handle<JSArray>::cast(receiver)->AllowsSetElementsLength() && |
| 1522 receiver->HasFastProperties()) { | 1523 receiver->HasFastProperties()) { |
| 1523 Handle<Code> stub = | 1524 Handle<Code> stub = |
| 1524 StoreArrayLengthStub(kind(), strict_mode).GetCode(isolate()); | 1525 StoreArrayLengthStub(kind(), strict_mode).GetCode(isolate()); |
| 1525 set_target(*stub); | 1526 set_target(*stub); |
| 1526 TRACE_IC("StoreIC", name, state, *stub); | 1527 TRACE_IC("StoreIC", name, state, *stub); |
| 1527 return receiver->SetProperty(*name, *value, NONE, strict_mode, store_mode); | 1528 return JSReceiver::SetPropertyOrFail( |
| 1529 receiver, name, value, NONE, strict_mode, store_mode); |
| 1528 } | 1530 } |
| 1529 | 1531 |
| 1530 if (receiver->IsJSGlobalProxy()) { | 1532 if (receiver->IsJSGlobalProxy()) { |
| 1531 if (FLAG_use_ic && kind() != Code::KEYED_STORE_IC) { | 1533 if (FLAG_use_ic && kind() != Code::KEYED_STORE_IC) { |
| 1532 // Generate a generic stub that goes to the runtime when we see a global | 1534 // Generate a generic stub that goes to the runtime when we see a global |
| 1533 // proxy as receiver. | 1535 // proxy as receiver. |
| 1534 Handle<Code> stub = (strict_mode == kStrictMode) | 1536 Handle<Code> stub = (strict_mode == kStrictMode) |
| 1535 ? global_proxy_stub_strict() | 1537 ? global_proxy_stub_strict() |
| 1536 : global_proxy_stub(); | 1538 : global_proxy_stub(); |
| 1537 set_target(*stub); | 1539 set_target(*stub); |
| 1538 TRACE_IC("StoreIC", name, state, *stub); | 1540 TRACE_IC("StoreIC", name, state, *stub); |
| 1539 } | 1541 } |
| 1540 return receiver->SetProperty(*name, *value, NONE, strict_mode, store_mode); | 1542 return JSReceiver::SetPropertyOrFail( |
| 1543 receiver, name, value, NONE, strict_mode, store_mode); |
| 1541 } | 1544 } |
| 1542 | 1545 |
| 1543 LookupResult lookup(isolate()); | 1546 LookupResult lookup(isolate()); |
| 1544 if (LookupForWrite(receiver, name, &lookup)) { | 1547 if (LookupForWrite(receiver, name, &lookup)) { |
| 1545 if (FLAG_use_ic) { | 1548 if (FLAG_use_ic) { |
| 1546 UpdateCaches(&lookup, state, strict_mode, receiver, name, value); | 1549 UpdateCaches(&lookup, state, strict_mode, receiver, name, value); |
| 1547 } | 1550 } |
| 1548 } else if (strict_mode == kStrictMode && | 1551 } else if (strict_mode == kStrictMode && |
| 1549 !(lookup.IsProperty() && lookup.IsReadOnly()) && | 1552 !(lookup.IsProperty() && lookup.IsReadOnly()) && |
| 1550 IsUndeclaredGlobal(object)) { | 1553 IsUndeclaredGlobal(object)) { |
| 1551 // Strict mode doesn't allow setting non-existent global property. | 1554 // Strict mode doesn't allow setting non-existent global property. |
| 1552 return ReferenceError("not_defined", name); | 1555 return ReferenceError("not_defined", name); |
| 1553 } | 1556 } |
| 1554 | 1557 |
| 1555 // Set the property. | 1558 // Set the property. |
| 1556 return receiver->SetProperty(*name, *value, NONE, strict_mode, store_mode); | 1559 return JSReceiver::SetPropertyOrFail( |
| 1560 receiver, name, value, NONE, strict_mode, store_mode); |
| 1557 } | 1561 } |
| 1558 | 1562 |
| 1559 | 1563 |
| 1560 void StoreIC::UpdateCaches(LookupResult* lookup, | 1564 void StoreIC::UpdateCaches(LookupResult* lookup, |
| 1561 State state, | 1565 State state, |
| 1562 StrictModeFlag strict_mode, | 1566 StrictModeFlag strict_mode, |
| 1563 Handle<JSObject> receiver, | 1567 Handle<JSObject> receiver, |
| 1564 Handle<String> name, | 1568 Handle<String> name, |
| 1565 Handle<Object> value) { | 1569 Handle<Object> value) { |
| 1566 ASSERT(!receiver->IsJSGlobalProxy()); | 1570 ASSERT(!receiver->IsJSGlobalProxy()); |
| (...skipping 1238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2805 #undef ADDR | 2809 #undef ADDR |
| 2806 }; | 2810 }; |
| 2807 | 2811 |
| 2808 | 2812 |
| 2809 Address IC::AddressFromUtilityId(IC::UtilityId id) { | 2813 Address IC::AddressFromUtilityId(IC::UtilityId id) { |
| 2810 return IC_utilities[id]; | 2814 return IC_utilities[id]; |
| 2811 } | 2815 } |
| 2812 | 2816 |
| 2813 | 2817 |
| 2814 } } // namespace v8::internal | 2818 } } // namespace v8::internal |
| OLD | NEW |