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 |