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 9550 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9561 PropertyDetails details = dictionary->DetailsAt(entry); | 9561 PropertyDetails details = dictionary->DetailsAt(entry); |
9562 if (details.type() == CALLBACKS && set_mode == SET_PROPERTY) { | 9562 if (details.type() == CALLBACKS && set_mode == SET_PROPERTY) { |
9563 return SetElementWithCallback(element, index, value, this, strict_mode); | 9563 return SetElementWithCallback(element, index, value, this, strict_mode); |
9564 } else { | 9564 } else { |
9565 dictionary->UpdateMaxNumberKey(index); | 9565 dictionary->UpdateMaxNumberKey(index); |
9566 // If a value has not been initialized we allow writing to it even if it | 9566 // If a value has not been initialized we allow writing to it even if it |
9567 // is read-only (a declared const that has not been initialized). If a | 9567 // is read-only (a declared const that has not been initialized). If a |
9568 // value is being defined we skip attribute checks completely. | 9568 // value is being defined we skip attribute checks completely. |
9569 if (set_mode == DEFINE_PROPERTY) { | 9569 if (set_mode == DEFINE_PROPERTY) { |
9570 details = PropertyDetails(attributes, NORMAL, details.index()); | 9570 details = PropertyDetails(attributes, NORMAL, details.index()); |
9571 dictionary->ValueAtPut(entry, value); | |
9572 dictionary->DetailsAtPut(entry, details); | 9571 dictionary->DetailsAtPut(entry, details); |
9573 } else if (!details.IsReadOnly() || element->IsTheHole()) { | 9572 } else if (details.IsReadOnly() && !element->IsTheHole()) { |
9574 dictionary->ValueAtPut(entry, value); | 9573 if (strict_mode == kNonStrictMode) { |
9575 } else if (strict_mode == kStrictMode) { | 9574 return isolate->heap()->undefined_value(); |
9576 Handle<Object> holder(this); | 9575 } else { |
9577 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); | 9576 Handle<Object> holder(this); |
9578 Handle<Object> args[2] = { number, holder }; | 9577 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); |
9579 Handle<Object> error = | 9578 Handle<Object> args[2] = { number, holder }; |
9580 isolate->factory()->NewTypeError("strict_read_only_property", | 9579 Handle<Object> error = |
9581 HandleVector(args, 2)); | 9580 isolate->factory()->NewTypeError("strict_read_only_property", |
9582 return isolate->Throw(*error); | 9581 HandleVector(args, 2)); |
| 9582 return isolate->Throw(*error); |
| 9583 } |
9583 } | 9584 } |
| 9585 // Elements of the arguments object in slow mode might be slow aliases. |
| 9586 if (is_arguments && element->IsAliasedArgumentsEntry()) { |
| 9587 AliasedArgumentsEntry* entry = AliasedArgumentsEntry::cast(element); |
| 9588 Context* context = Context::cast(elements->get(0)); |
| 9589 int context_index = entry->aliased_context_slot(); |
| 9590 ASSERT(!context->get(context_index)->IsTheHole()); |
| 9591 context->set(context_index, value); |
| 9592 // For elements that are still writable we keep slow aliasing. |
| 9593 if (!details.IsReadOnly()) value = element; |
| 9594 } |
| 9595 dictionary->ValueAtPut(entry, value); |
9584 } | 9596 } |
9585 } else { | 9597 } else { |
9586 // Index not already used. Look for an accessor in the prototype chain. | 9598 // Index not already used. Look for an accessor in the prototype chain. |
9587 if (check_prototype) { | 9599 if (check_prototype) { |
9588 bool found; | 9600 bool found; |
9589 MaybeObject* result = | 9601 MaybeObject* result = |
9590 SetElementWithCallbackSetterInPrototypes( | 9602 SetElementWithCallbackSetterInPrototypes( |
9591 index, value, &found, strict_mode); | 9603 index, value, &found, strict_mode); |
9592 if (found) return result; | 9604 if (found) return result; |
9593 } | 9605 } |
(...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9929 case NON_STRICT_ARGUMENTS_ELEMENTS: { | 9941 case NON_STRICT_ARGUMENTS_ELEMENTS: { |
9930 FixedArray* parameter_map = FixedArray::cast(elements()); | 9942 FixedArray* parameter_map = FixedArray::cast(elements()); |
9931 uint32_t length = parameter_map->length(); | 9943 uint32_t length = parameter_map->length(); |
9932 Object* probe = | 9944 Object* probe = |
9933 (index < length - 2) ? parameter_map->get(index + 2) : NULL; | 9945 (index < length - 2) ? parameter_map->get(index + 2) : NULL; |
9934 if (probe != NULL && !probe->IsTheHole()) { | 9946 if (probe != NULL && !probe->IsTheHole()) { |
9935 Context* context = Context::cast(parameter_map->get(0)); | 9947 Context* context = Context::cast(parameter_map->get(0)); |
9936 int context_index = Smi::cast(probe)->value(); | 9948 int context_index = Smi::cast(probe)->value(); |
9937 ASSERT(!context->get(context_index)->IsTheHole()); | 9949 ASSERT(!context->get(context_index)->IsTheHole()); |
9938 context->set(context_index, value); | 9950 context->set(context_index, value); |
9939 return value; | 9951 // Redefining attributes of an aliased element destroys fast aliasing. |
| 9952 if (set_mode == SET_PROPERTY || attr == NONE) return value; |
| 9953 parameter_map->set_the_hole(index + 2); |
| 9954 // For elements that are still writable we re-establish slow aliasing. |
| 9955 if ((attr & READ_ONLY) == 0) { |
| 9956 MaybeObject* maybe_entry = |
| 9957 isolate->heap()->AllocateAliasedArgumentsEntry(context_index); |
| 9958 if (!maybe_entry->ToObject(&value)) return maybe_entry; |
| 9959 } |
| 9960 } |
| 9961 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); |
| 9962 if (arguments->IsDictionary()) { |
| 9963 return SetDictionaryElement(index, value, attr, strict_mode, |
| 9964 check_prototype, set_mode); |
9940 } else { | 9965 } else { |
9941 // Object is not mapped, defer to the arguments. | 9966 return SetFastElement(index, value, strict_mode, check_prototype); |
9942 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); | |
9943 if (arguments->IsDictionary()) { | |
9944 return SetDictionaryElement(index, value, attr, strict_mode, | |
9945 check_prototype, set_mode); | |
9946 } else { | |
9947 return SetFastElement(index, value, strict_mode, check_prototype); | |
9948 } | |
9949 } | 9967 } |
9950 } | 9968 } |
9951 } | 9969 } |
9952 // All possible cases have been handled above. Add a return to avoid the | 9970 // All possible cases have been handled above. Add a return to avoid the |
9953 // complaints from the compiler. | 9971 // complaints from the compiler. |
9954 UNREACHABLE(); | 9972 UNREACHABLE(); |
9955 return isolate->heap()->null_value(); | 9973 return isolate->heap()->null_value(); |
9956 } | 9974 } |
9957 | 9975 |
9958 | 9976 |
(...skipping 3184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13143 if (break_point_objects()->IsUndefined()) return 0; | 13161 if (break_point_objects()->IsUndefined()) return 0; |
13144 // Single break point. | 13162 // Single break point. |
13145 if (!break_point_objects()->IsFixedArray()) return 1; | 13163 if (!break_point_objects()->IsFixedArray()) return 1; |
13146 // Multiple break points. | 13164 // Multiple break points. |
13147 return FixedArray::cast(break_point_objects())->length(); | 13165 return FixedArray::cast(break_point_objects())->length(); |
13148 } | 13166 } |
13149 #endif // ENABLE_DEBUGGER_SUPPORT | 13167 #endif // ENABLE_DEBUGGER_SUPPORT |
13150 | 13168 |
13151 | 13169 |
13152 } } // namespace v8::internal | 13170 } } // namespace v8::internal |
OLD | NEW |