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 608 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
619 // Otherwise, it will fail in the lookup step. | 619 // Otherwise, it will fail in the lookup step. |
620 } | 620 } |
621 | 621 |
622 // Lookup the property in the object. | 622 // Lookup the property in the object. |
623 LookupResult lookup(isolate()); | 623 LookupResult lookup(isolate()); |
624 LookupForRead(object, name, &lookup); | 624 LookupForRead(object, name, &lookup); |
625 | 625 |
626 if (!lookup.IsFound()) { | 626 if (!lookup.IsFound()) { |
627 // If the object does not have the requested property, check which | 627 // If the object does not have the requested property, check which |
628 // exception we need to throw. | 628 // exception we need to throw. |
629 return IsUndeclaredGlobal(object) | 629 return object->IsGlobalObject() |
630 ? ReferenceError("not_defined", name) | 630 ? ReferenceError("not_defined", name) |
631 : TypeError("undefined_method", object, name); | 631 : TypeError("undefined_method", object, name); |
632 } | 632 } |
633 | 633 |
634 // Lookup is valid: Update inline cache and stub cache. | 634 // Lookup is valid: Update inline cache and stub cache. |
635 if (use_ic) UpdateCaches(&lookup, object, name); | 635 if (use_ic) UpdateCaches(&lookup, object, name); |
636 | 636 |
637 // Get the property. | 637 // Get the property. |
638 PropertyAttributes attr; | 638 PropertyAttributes attr; |
639 Handle<Object> result = | 639 Handle<Object> result = |
640 Object::GetProperty(object, object, &lookup, name, &attr); | 640 Object::GetProperty(object, object, &lookup, name, &attr); |
641 RETURN_IF_EMPTY_HANDLE(isolate(), result); | 641 RETURN_IF_EMPTY_HANDLE(isolate(), result); |
642 | 642 |
643 if (lookup.IsInterceptor() && attr == ABSENT) { | 643 if (lookup.IsInterceptor() && attr == ABSENT) { |
644 // If the object does not have the requested property, check which | 644 // If the object does not have the requested property, check which |
645 // exception we need to throw. | 645 // exception we need to throw. |
646 return IsUndeclaredGlobal(object) | 646 return object->IsGlobalObject() |
647 ? ReferenceError("not_defined", name) | 647 ? ReferenceError("not_defined", name) |
648 : TypeError("undefined_method", object, name); | 648 : TypeError("undefined_method", object, name); |
649 } | 649 } |
650 | 650 |
651 ASSERT(!result->IsTheHole()); | 651 ASSERT(!result->IsTheHole()); |
652 | 652 |
653 // Make receiver an object if the callee requires it. Strict mode or builtin | 653 // Make receiver an object if the callee requires it. Strict mode or builtin |
654 // functions do not wrap the receiver, non-strict functions and objects | 654 // functions do not wrap the receiver, non-strict functions and objects |
655 // called as functions do. | 655 // called as functions do. |
656 ReceiverToObjectIfRequired(result, object); | 656 ReceiverToObjectIfRequired(result, object); |
(...skipping 438 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1095 break; | 1095 break; |
1096 case GENERIC: | 1096 case GENERIC: |
1097 UNREACHABLE(); | 1097 UNREACHABLE(); |
1098 break; | 1098 break; |
1099 } | 1099 } |
1100 } | 1100 } |
1101 | 1101 |
1102 | 1102 |
1103 Handle<Code> LoadIC::initialize_stub(Isolate* isolate, ContextualMode mode) { | 1103 Handle<Code> LoadIC::initialize_stub(Isolate* isolate, ContextualMode mode) { |
1104 Handle<Code> ic = isolate->stub_cache()->ComputeLoad( | 1104 Handle<Code> ic = isolate->stub_cache()->ComputeLoad( |
1105 UNINITIALIZED, IC::ComputeExtraICState(mode)); | 1105 UNINITIALIZED, ComputeExtraICState(mode)); |
1106 return ic; | 1106 return ic; |
1107 } | 1107 } |
1108 | 1108 |
1109 | 1109 |
1110 Handle<Code> LoadIC::pre_monomorphic_stub(Isolate* isolate, | 1110 Handle<Code> LoadIC::pre_monomorphic_stub(Isolate* isolate, |
1111 ContextualMode mode) { | 1111 ContextualMode mode) { |
1112 return isolate->stub_cache()->ComputeLoad( | 1112 return isolate->stub_cache()->ComputeLoad( |
1113 PREMONOMORPHIC, IC::ComputeExtraICState(mode)); | 1113 PREMONOMORPHIC, ComputeExtraICState(mode)); |
1114 } | 1114 } |
1115 | 1115 |
1116 | 1116 |
1117 Handle<Code> LoadIC::megamorphic_stub() { | 1117 Handle<Code> LoadIC::megamorphic_stub() { |
1118 return isolate()->stub_cache()->ComputeLoad( | 1118 return isolate()->stub_cache()->ComputeLoad( |
1119 MEGAMORPHIC, extra_ic_state()); | 1119 MEGAMORPHIC, extra_ic_state()); |
1120 } | 1120 } |
1121 | 1121 |
1122 | 1122 |
1123 Handle<Code> LoadIC::SimpleFieldLoad(int offset, | 1123 Handle<Code> LoadIC::SimpleFieldLoad(int offset, |
(...skipping 439 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1563 receiver, name, value, NONE, strict_mode(), store_mode); | 1563 receiver, name, value, NONE, strict_mode(), store_mode); |
1564 RETURN_IF_EMPTY_HANDLE(isolate(), result); | 1564 RETURN_IF_EMPTY_HANDLE(isolate(), result); |
1565 return *result; | 1565 return *result; |
1566 } | 1566 } |
1567 | 1567 |
1568 LookupResult lookup(isolate()); | 1568 LookupResult lookup(isolate()); |
1569 bool can_store = LookupForWrite(receiver, name, value, &lookup, this); | 1569 bool can_store = LookupForWrite(receiver, name, value, &lookup, this); |
1570 if (!can_store && | 1570 if (!can_store && |
1571 strict_mode() == kStrictMode && | 1571 strict_mode() == kStrictMode && |
1572 !(lookup.IsProperty() && lookup.IsReadOnly()) && | 1572 !(lookup.IsProperty() && lookup.IsReadOnly()) && |
1573 IsUndeclaredGlobal(object)) { | 1573 object->IsGlobalObject()) { |
1574 // Strict mode doesn't allow setting non-existent global property. | 1574 // Strict mode doesn't allow setting non-existent global property. |
1575 return ReferenceError("not_defined", name); | 1575 return ReferenceError("not_defined", name); |
1576 } | 1576 } |
1577 if (FLAG_use_ic) { | 1577 if (FLAG_use_ic) { |
1578 if (state() == UNINITIALIZED) { | 1578 if (state() == UNINITIALIZED) { |
1579 Handle<Code> stub = pre_monomorphic_stub(); | 1579 Handle<Code> stub = pre_monomorphic_stub(); |
1580 set_target(*stub); | 1580 set_target(*stub); |
1581 TRACE_IC("StoreIC", name); | 1581 TRACE_IC("StoreIC", name); |
1582 } else if (can_store) { | 1582 } else if (can_store) { |
1583 UpdateCaches(&lookup, receiver, name, value); | 1583 UpdateCaches(&lookup, receiver, name, value); |
1584 } else if (!name->IsCacheable(isolate()) || | 1584 } else if (!name->IsCacheable(isolate()) || |
1585 lookup.IsNormal() || | 1585 lookup.IsNormal() || |
1586 (lookup.IsField() && lookup.CanHoldValue(value))) { | 1586 (lookup.IsField() && lookup.CanHoldValue(value))) { |
1587 Handle<Code> stub = generic_stub(); | 1587 Handle<Code> stub = generic_stub(); |
1588 set_target(*stub); | 1588 set_target(*stub); |
1589 } | 1589 } |
1590 } | 1590 } |
1591 | 1591 |
1592 // Set the property. | 1592 // Set the property. |
1593 Handle<Object> result = JSReceiver::SetProperty( | 1593 Handle<Object> result = JSReceiver::SetProperty( |
1594 receiver, name, value, NONE, strict_mode(), store_mode); | 1594 receiver, name, value, NONE, strict_mode(), store_mode); |
1595 RETURN_IF_EMPTY_HANDLE(isolate(), result); | 1595 RETURN_IF_EMPTY_HANDLE(isolate(), result); |
1596 return *result; | 1596 return *result; |
1597 } | 1597 } |
1598 | 1598 |
1599 | 1599 |
1600 Handle<Code> StoreIC::initialize_stub(Isolate* isolate, | 1600 Handle<Code> StoreIC::initialize_stub(Isolate* isolate, |
1601 StrictModeFlag strict_mode, | 1601 StrictModeFlag strict_mode) { |
1602 ContextualMode mode) { | 1602 ExtraICState extra_state = ComputeExtraICState(strict_mode); |
1603 ExtraICState extra_state = ComputeExtraICState(strict_mode, mode); | |
1604 Handle<Code> ic = isolate->stub_cache()->ComputeStore( | 1603 Handle<Code> ic = isolate->stub_cache()->ComputeStore( |
1605 UNINITIALIZED, extra_state); | 1604 UNINITIALIZED, extra_state); |
1606 return ic; | 1605 return ic; |
1607 } | 1606 } |
1608 | 1607 |
1609 | 1608 |
1610 Handle<Code> StoreIC::megamorphic_stub() { | 1609 Handle<Code> StoreIC::megamorphic_stub() { |
1611 return isolate()->stub_cache()->ComputeStore(MEGAMORPHIC, extra_ic_state()); | 1610 return isolate()->stub_cache()->ComputeStore(MEGAMORPHIC, extra_ic_state()); |
1612 } | 1611 } |
1613 | 1612 |
1614 | 1613 |
1615 Handle<Code> StoreIC::generic_stub() const { | 1614 Handle<Code> StoreIC::generic_stub() const { |
1616 return isolate()->stub_cache()->ComputeStore(GENERIC, extra_ic_state()); | 1615 return isolate()->stub_cache()->ComputeStore(GENERIC, extra_ic_state()); |
1617 } | 1616 } |
1618 | 1617 |
1619 | 1618 |
1620 Handle<Code> StoreIC::pre_monomorphic_stub(Isolate* isolate, | 1619 Handle<Code> StoreIC::pre_monomorphic_stub(Isolate* isolate, |
1621 StrictModeFlag strict_mode, | 1620 StrictModeFlag strict_mode) { |
1622 ContextualMode contextual_mode) { | 1621 ExtraICState state = ComputeExtraICState(strict_mode); |
1623 ExtraICState state = StoreIC::ComputeExtraICState(strict_mode, | |
1624 contextual_mode); | |
1625 return isolate->stub_cache()->ComputeStore(PREMONOMORPHIC, state); | 1622 return isolate->stub_cache()->ComputeStore(PREMONOMORPHIC, state); |
1626 } | 1623 } |
1627 | 1624 |
1628 | 1625 |
1629 void StoreIC::UpdateCaches(LookupResult* lookup, | 1626 void StoreIC::UpdateCaches(LookupResult* lookup, |
1630 Handle<JSObject> receiver, | 1627 Handle<JSObject> receiver, |
1631 Handle<String> name, | 1628 Handle<String> name, |
1632 Handle<Object> value) { | 1629 Handle<Object> value) { |
1633 ASSERT(lookup->IsFound()); | 1630 ASSERT(lookup->IsFound()); |
1634 | 1631 |
(...skipping 1585 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3220 #undef ADDR | 3217 #undef ADDR |
3221 }; | 3218 }; |
3222 | 3219 |
3223 | 3220 |
3224 Address IC::AddressFromUtilityId(IC::UtilityId id) { | 3221 Address IC::AddressFromUtilityId(IC::UtilityId id) { |
3225 return IC_utilities[id]; | 3222 return IC_utilities[id]; |
3226 } | 3223 } |
3227 | 3224 |
3228 | 3225 |
3229 } } // namespace v8::internal | 3226 } } // namespace v8::internal |
OLD | NEW |