Commit 8c6c2732 authored by ager@chromium.org's avatar ager@chromium.org

Fix issues with using defineProperty on the global proxy object.

Review URL: http://codereview.chromium.org/6452004

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@6683 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 27ed4d3a
...@@ -3685,14 +3685,20 @@ static MaybeObject* Runtime_DefineOrRedefineDataProperty(Arguments args) { ...@@ -3685,14 +3685,20 @@ static MaybeObject* Runtime_DefineOrRedefineDataProperty(Arguments args) {
if (((unchecked & (DONT_DELETE | DONT_ENUM | READ_ONLY)) != 0) && if (((unchecked & (DONT_DELETE | DONT_ENUM | READ_ONLY)) != 0) &&
is_element) { is_element) {
// Normalize the elements to enable attributes on the property. // Normalize the elements to enable attributes on the property.
if (!js_object->IsJSGlobalProxy()) { if (js_object->IsJSGlobalProxy()) {
NormalizeElements(js_object); Handle<Object> proto(js_object->GetPrototype());
} // If proxy is detached, ignore the assignment. Alternatively,
// we could throw an exception.
if (proto->IsNull()) return *obj_value;
js_object = Handle<JSObject>::cast(proto);
}
NormalizeElements(js_object);
Handle<NumberDictionary> dictionary(js_object->element_dictionary()); Handle<NumberDictionary> dictionary(js_object->element_dictionary());
// Make sure that we never go back to fast case. // Make sure that we never go back to fast case.
dictionary->set_requires_slow_elements(); dictionary->set_requires_slow_elements();
PropertyDetails details = PropertyDetails(attr, NORMAL); PropertyDetails details = PropertyDetails(attr, NORMAL);
NumberDictionarySet(dictionary, index, obj_value, details); NumberDictionarySet(dictionary, index, obj_value, details);
return *obj_value;
} }
LookupResult result; LookupResult result;
...@@ -3707,9 +3713,12 @@ static MaybeObject* Runtime_DefineOrRedefineDataProperty(Arguments args) { ...@@ -3707,9 +3713,12 @@ static MaybeObject* Runtime_DefineOrRedefineDataProperty(Arguments args) {
if (result.IsProperty() && if (result.IsProperty() &&
(attr != result.GetAttributes() || result.type() == CALLBACKS)) { (attr != result.GetAttributes() || result.type() == CALLBACKS)) {
// New attributes - normalize to avoid writing to instance descriptor // New attributes - normalize to avoid writing to instance descriptor
if (!js_object->IsJSGlobalProxy()) { if (js_object->IsJSGlobalProxy()) {
NormalizeProperties(js_object, CLEAR_INOBJECT_PROPERTIES, 0); // Since the result is a property, the prototype will exist so
// we don't have to check for null.
js_object = Handle<JSObject>(JSObject::cast(js_object->GetPrototype()));
} }
NormalizeProperties(js_object, CLEAR_INOBJECT_PROPERTIES, 0);
// Use IgnoreAttributes version since a readonly property may be // Use IgnoreAttributes version since a readonly property may be
// overridden and SetProperty does not allow this. // overridden and SetProperty does not allow this.
return js_object->SetLocalPropertyIgnoreAttributes(*name, return js_object->SetLocalPropertyIgnoreAttributes(*name,
......
...@@ -12549,3 +12549,19 @@ TEST(NamedEnumeratorAndForIn) { ...@@ -12549,3 +12549,19 @@ TEST(NamedEnumeratorAndForIn) {
CHECK_EQ(1, result->Length()); CHECK_EQ(1, result->Length());
CHECK_EQ(v8_str("universalAnswer"), result->Get(0)); CHECK_EQ(v8_str("universalAnswer"), result->Get(0));
} }
TEST(DefinePropertyPostDetach) {
v8::HandleScope scope;
LocalContext context;
v8::Handle<v8::Object> proxy = context->Global();
v8::Handle<v8::Function> define_property =
CompileRun("(function() {"
" Object.defineProperty("
" this,"
" 1,"
" { configurable: true, enumerable: true, value: 3 });"
"})").As<Function>();
context->DetachGlobal();
define_property->Call(proxy, 0, NULL);
}
// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Regression test making sure that defineProperty on the global proxy
// defines the property on the global object.
Object.defineProperty(this,
1,
{ configurable: true, enumerable: true, value: 3 });
assertEquals(3, this[1]);
assertTrue(this.hasOwnProperty("1"));
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment