Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(321)

Side by Side Diff: src/objects.cc

Issue 9460004: Fix redefining of attributes on aliased arguments. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed comments by Andreas Rossberg. Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/objects.h ('k') | src/objects-debug.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/objects-debug.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698