From: ager@chromium.org Date: Wed, 14 Jan 2009 12:13:26 +0000 (+0000) Subject: Fix issue 186: X-Git-Tag: upstream/4.7.83~24803 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=d4dae20a124f646e4417ac60d28fe6e76c6c7a32;p=platform%2Fupstream%2Fv8.git Fix issue 186: http://code.google.com/p/v8/issues/detail?id=186 Create a new instance type for context extension objects. Use it to not use the __proto__ accessor for context extension objects. Review URL: http://codereview.chromium.org/18044 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@1072 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- diff --git a/src/bootstrapper.cc b/src/bootstrapper.cc index ce25d00e4..8d5418782 100644 --- a/src/bootstrapper.cc +++ b/src/bootstrapper.cc @@ -794,8 +794,11 @@ void Genesis::CreateRoots(v8::Handle global_template, // Create a function for the context extension objects. Handle code = Handle(Builtins::builtin(Builtins::Illegal)); Handle context_extension_fun = - Factory::NewFunction(Factory::empty_symbol(), JS_OBJECT_TYPE, - JSObject::kHeaderSize, code, true); + Factory::NewFunction(Factory::empty_symbol(), + JS_CONTEXT_EXTENSION_OBJECT_TYPE, + JSObject::kHeaderSize, + code, + true); Handle name = Factory::LookupAsciiSymbol("context_extension"); context_extension_fun->shared()->set_instance_class_name(*name); diff --git a/src/objects-debug.cc b/src/objects-debug.cc index 1c1ffed81..6b58f255a 100644 --- a/src/objects-debug.cc +++ b/src/objects-debug.cc @@ -117,6 +117,7 @@ void HeapObject::HeapObjectPrint() { PrintF("filler"); break; case JS_OBJECT_TYPE: // fall through + case JS_CONTEXT_EXTENSION_OBJECT_TYPE: case JS_ARRAY_TYPE: case JS_REGEXP_TYPE: JSObject::cast(this)->JSObjectPrint(); @@ -193,6 +194,7 @@ void HeapObject::HeapObjectVerify() { Oddball::cast(this)->OddballVerify(); break; case JS_OBJECT_TYPE: + case JS_CONTEXT_EXTENSION_OBJECT_TYPE: JSObject::cast(this)->JSObjectVerify(); break; case JS_VALUE_TYPE: @@ -382,6 +384,7 @@ static const char* TypeToString(InstanceType type) { case BYTE_ARRAY_TYPE: return "BYTE_ARRAY"; case FILLER_TYPE: return "FILLER"; case JS_OBJECT_TYPE: return "JS_OBJECT"; + case JS_CONTEXT_EXTENSION_OBJECT_TYPE: return "JS_CONTEXT_EXTENSION_OBJECT"; case ODDBALL_TYPE: return "ODDBALL"; case SHARED_FUNCTION_INFO_TYPE: return "SHARED_FUNCTION_INFO"; case JS_FUNCTION_TYPE: return "JS_FUNCTION"; diff --git a/src/objects-inl.h b/src/objects-inl.h index 0bad5a160..01d897d33 100644 --- a/src/objects-inl.h +++ b/src/objects-inl.h @@ -328,6 +328,13 @@ bool Object::IsJSObject() { } +bool Object::IsJSContextExtensionObject() { + return IsHeapObject() + && (HeapObject::cast(this)->map()->instance_type() == + JS_CONTEXT_EXTENSION_OBJECT_TYPE); +} + + bool Object::IsMap() { return Object::IsHeapObject() && HeapObject::cast(this)->map()->instance_type() == MAP_TYPE; @@ -1018,6 +1025,7 @@ int JSObject::GetHeaderSize() { case JS_REGEXP_TYPE: return JSValue::kSize; case JS_OBJECT_TYPE: + case JS_CONTEXT_EXTENSION_OBJECT_TYPE: return JSObject::kHeaderSize; default: UNREACHABLE(); diff --git a/src/objects.cc b/src/objects.cc index 9981e4cf5..0dc988799 100644 --- a/src/objects.cc +++ b/src/objects.cc @@ -940,6 +940,7 @@ void HeapObject::IterateBody(InstanceType type, int object_size, reinterpret_cast(this)->FixedArrayIterateBody(v); break; case JS_OBJECT_TYPE: + case JS_CONTEXT_EXTENSION_OBJECT_TYPE: case JS_VALUE_TYPE: case JS_ARRAY_TYPE: case JS_REGEXP_TYPE: @@ -2360,7 +2361,7 @@ void JSObject::LocalLookup(String* name, LookupResult* result) { } // Check __proto__ before interceptor. - if (name->Equals(Heap::Proto_symbol())) { + if (name->Equals(Heap::Proto_symbol()) && !IsJSContextExtensionObject()) { result->ConstantResult(this); return; } diff --git a/src/objects.h b/src/objects.h index f251a59cd..60e6d753e 100644 --- a/src/objects.h +++ b/src/objects.h @@ -278,6 +278,7 @@ enum PropertyNormalizationMode { \ V(JS_VALUE_TYPE) \ V(JS_OBJECT_TYPE) \ + V(JS_CONTEXT_EXTENSION_OBJECT_TYPE) \ V(JS_GLOBAL_OBJECT_TYPE) \ V(JS_BUILTINS_OBJECT_TYPE) \ V(JS_GLOBAL_PROXY_TYPE) \ @@ -535,6 +536,7 @@ enum InstanceType { JS_VALUE_TYPE, JS_OBJECT_TYPE, + JS_CONTEXT_EXTENSION_OBJECT_TYPE, JS_GLOBAL_OBJECT_TYPE, JS_BUILTINS_OBJECT_TYPE, JS_GLOBAL_PROXY_TYPE, @@ -622,6 +624,7 @@ class Object BASE_EMBEDDED { inline bool IsOutOfMemoryFailure(); inline bool IsException(); inline bool IsJSObject(); + inline bool IsJSContextExtensionObject(); inline bool IsMap(); inline bool IsFixedArray(); inline bool IsDescriptorArray(); diff --git a/test/mjsunit/bugs/bug-186.js b/test/mjsunit/bugs/bug-186.js deleted file mode 100644 index bde52127d..000000000 --- a/test/mjsunit/bugs/bug-186.js +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright 2009 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. - -// Make sure that eval can introduce a local variable called __proto__. -// See http://code.google.com/p/v8/issues/detail?id=186 - -var setterCalled = false; - -var o = {}; -o.__defineSetter__("x", function() { setterCalled = true; }); - -function testLocal() { - // Add property called __proto__ to the extension object. - eval("var __proto__ = o"); - // Check that the extension object's prototype did not change. - eval("var x = 27"); - assertFalse(setterCalled, "prototype of extension object changed"); -} - -function testGlobal() { - // Assign to the global __proto__ property. - eval("__proto__ = o"); - // Check that the prototype of the global object changed. - eval("x = 27"); - assertTrue(setterCalled, "prototype of global object did not change"); - setterCalled = false; -} - -testLocal(); -testGlobal(); - diff --git a/test/mjsunit/regress/regress-186.js b/test/mjsunit/regress/regress-186.js new file mode 100644 index 000000000..335869d6b --- /dev/null +++ b/test/mjsunit/regress/regress-186.js @@ -0,0 +1,72 @@ +// Copyright 2009 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. + +// Make sure that eval can introduce a local variable called __proto__. +// See http://code.google.com/p/v8/issues/detail?id=186 + +var setterCalled = false; + +var o = {}; +o.__defineSetter__("x", function() { setterCalled = true; }); + +function runTest(test) { + setterCalled = false; + test(); +} + +function testLocal() { + // Add property called __proto__ to the extension object. + eval("var __proto__ = o"); + // Check that the extension object's prototype did not change. + eval("var x = 27"); + assertFalse(setterCalled, "prototype of extension object changed"); + assertEquals(o, eval("__proto__")); +} + +function testConstLocal() { + // Add const property called __proto__ to the extension object. + eval("const __proto__ = o"); + // Check that the extension object's prototype did not change. + eval("var x = 27"); + assertFalse(setterCalled, "prototype of extension object changed"); + assertEquals(o, eval("__proto__")); +} + +function testGlobal() { + // Assign to the global __proto__ property. + eval("__proto__ = o"); + // Check that the prototype of the global object changed. + eval("x = 27"); + assertTrue(setterCalled, "prototype of global object did not change"); + setterCalled = false; + assertEquals(o, eval("__proto__")); +} + +runTest(testLocal); +runTest(testConstLocal); +runTest(testGlobal); +