Reviewers: Rico,

Description:
Fix issues with using defineProperty on the global proxy object.

Please review this at http://codereview.chromium.org/6452004/

SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge

Affected files:
  M src/runtime.cc
  M test/cctest/test-api.cc
  A test/mjsunit/regress/regress-1112.js


Index: src/runtime.cc
diff --git a/src/runtime.cc b/src/runtime.cc
index 3e38d388d8c9607a6cb9f4b066129c5ea2f247fb..61944ac004eb1004e3165278f20511add9b12eb3 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -887,7 +887,7 @@ static MaybeObject* Runtime_PreventExtensions(Arguments args) {
 static MaybeObject* Runtime_IsExtensible(Arguments args) {
   ASSERT(args.length() == 1);
   CONVERT_CHECKED(JSObject, obj, args[0]);
-  return obj->map()->is_extensible() ?  Heap::true_value()
+  return obj->map()->is_extensible() ? Heap::true_value()
                                      : Heap::false_value();
 }

@@ -3668,14 +3668,20 @@ static MaybeObject* Runtime_DefineOrRedefineDataProperty(Arguments args) {
   if (((unchecked & (DONT_DELETE | DONT_ENUM | READ_ONLY)) != 0) &&
       is_element) {
     // Normalize the elements to enable attributes on the property.
-    if (!js_object->IsJSGlobalProxy()) {
-      NormalizeElements(js_object);
-    }
+    if (js_object->IsJSGlobalProxy()) {
+      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());
     // Make sure that we never go back to fast case.
     dictionary->set_requires_slow_elements();
     PropertyDetails details = PropertyDetails(attr, NORMAL);
     NumberDictionarySet(dictionary, index, obj_value, details);
+    return *obj_value;
   }

   LookupResult result;
@@ -3690,9 +3696,12 @@ static MaybeObject* Runtime_DefineOrRedefineDataProperty(Arguments args) {
   if (result.IsProperty() &&
       (attr != result.GetAttributes() || result.type() == CALLBACKS)) {
     // New attributes - normalize to avoid writing to instance descriptor
-    if (!js_object->IsJSGlobalProxy()) {
-      NormalizeProperties(js_object, CLEAR_INOBJECT_PROPERTIES, 0);
+    if (js_object->IsJSGlobalProxy()) {
+      // 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
     // overridden and SetProperty does not allow this.
     return js_object->SetLocalPropertyIgnoreAttributes(*name,
Index: test/cctest/test-api.cc
diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc
index f88ba384d785aa57517739b7a09ef3635855ce09..681d6f84366740605ee3962150d3bc18da5a6abe 100644
--- a/test/cctest/test-api.cc
+++ b/test/cctest/test-api.cc
@@ -12549,3 +12549,19 @@ TEST(NamedEnumeratorAndForIn) {
   CHECK_EQ(1, result->Length());
   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, defineProperty: true, value: 3 });"
+                 "})").As<Function>();
+  context->DetachGlobal();
+  define_property->Call(proxy, 0, NULL);
+}
Index: test/mjsunit/regress/regress-1112.js
diff --git a/test/mjsunit/regress/regress-1112.js b/test/mjsunit/regress/regress-1112.js
new file mode 100644
index 0000000000000000000000000000000000000000..36057247f74b4bc25b475378dea812229bebd233
--- /dev/null
+++ b/test/mjsunit/regress/regress-1112.js
@@ -0,0 +1,33 @@
+// 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, defineProperty: true, value: 3});
+
+


--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to