https://bugs.webkit.org/show_bug.cgi?id=78434
authorbarraclough@apple.com <barraclough@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 13 Feb 2012 09:28:44 +0000 (09:28 +0000)
committerbarraclough@apple.com <barraclough@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 13 Feb 2012 09:28:44 +0000 (09:28 +0000)
Unreviewed - temporarily reverting r107498 will I fix a couple of testcases.

Source/JavaScriptCore:

* parser/Parser.cpp:
(JSC::::parseFunctionInfo):
* runtime/ClassInfo.h:
(MethodTable):
(JSC):
* runtime/JSCell.cpp:
(JSC):
* runtime/JSCell.h:
(JSCell):
* runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::reset):
* runtime/JSGlobalObjectFunctions.cpp:
(JSC):
* runtime/JSGlobalObjectFunctions.h:
(JSC):
* runtime/JSObject.cpp:
(JSC::JSObject::put):
(JSC):
(JSC::JSObject::putDirectAccessor):
(JSC::JSObject::defineOwnProperty):
* runtime/JSObject.h:
(JSC::JSObject::inlineGetOwnPropertySlot):
(JSC::JSValue::get):
* runtime/JSString.cpp:
(JSC::JSString::getOwnPropertySlot):
* runtime/JSValue.h:
(JSValue):
* runtime/ObjectConstructor.cpp:
(JSC::objectConstructorGetPrototypeOf):
* runtime/Structure.cpp:
(JSC::Structure::Structure):
* runtime/Structure.h:
(JSC::Structure::setHasGetterSetterProperties):
(Structure):

Source/WebCore:

* bindings/js/JSDOMWindowBase.cpp:
(WebCore):
* bindings/js/JSDOMWindowBase.h:
(JSDOMWindowBase):

LayoutTests:

* fast/js/Object-getOwnPropertyNames-expected.txt:
* fast/js/cyclic-prototypes-expected.txt:
* fast/js/parser-syntax-check-expected.txt:
* fast/js/preventExtensions-expected.txt:
* fast/js/prototypes-expected.txt:
* fast/js/script-tests/Object-getOwnPropertyNames.js:
* fast/js/script-tests/cyclic-prototypes.js:
* fast/js/script-tests/parser-syntax-check.js:
* fast/js/script-tests/preventExtensions.js:
* fast/js/script-tests/prototypes.js:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@107544 268f45cc-cd09-0410-ab3c-d52691b4dbfc

29 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/js/Object-getOwnPropertyNames-expected.txt
LayoutTests/fast/js/cyclic-prototypes-expected.txt
LayoutTests/fast/js/parser-syntax-check-expected.txt
LayoutTests/fast/js/preventExtensions-expected.txt
LayoutTests/fast/js/prototypes-expected.txt
LayoutTests/fast/js/script-tests/Object-getOwnPropertyNames.js
LayoutTests/fast/js/script-tests/cyclic-prototypes.js
LayoutTests/fast/js/script-tests/parser-syntax-check.js
LayoutTests/fast/js/script-tests/preventExtensions.js
LayoutTests/fast/js/script-tests/prototypes.js
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/parser/Parser.cpp
Source/JavaScriptCore/runtime/ClassInfo.h
Source/JavaScriptCore/runtime/JSCell.cpp
Source/JavaScriptCore/runtime/JSCell.h
Source/JavaScriptCore/runtime/JSGlobalObject.cpp
Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp
Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.h
Source/JavaScriptCore/runtime/JSObject.cpp
Source/JavaScriptCore/runtime/JSObject.h
Source/JavaScriptCore/runtime/JSString.cpp
Source/JavaScriptCore/runtime/JSValue.h
Source/JavaScriptCore/runtime/ObjectConstructor.cpp
Source/JavaScriptCore/runtime/Structure.cpp
Source/JavaScriptCore/runtime/Structure.h
Source/WebCore/ChangeLog
Source/WebCore/bindings/js/JSDOMWindowBase.cpp
Source/WebCore/bindings/js/JSDOMWindowBase.h

index 8923692..5651179 100644 (file)
@@ -1,3 +1,19 @@
+2012-02-13  Gavin Barraclough  <barraclough@apple.com>
+
+        https://bugs.webkit.org/show_bug.cgi?id=78434
+        Unreviewed - temporarily reverting r107498 will I fix a couple of testcases.
+
+        * fast/js/Object-getOwnPropertyNames-expected.txt:
+        * fast/js/cyclic-prototypes-expected.txt:
+        * fast/js/parser-syntax-check-expected.txt:
+        * fast/js/preventExtensions-expected.txt:
+        * fast/js/prototypes-expected.txt:
+        * fast/js/script-tests/Object-getOwnPropertyNames.js:
+        * fast/js/script-tests/cyclic-prototypes.js:
+        * fast/js/script-tests/parser-syntax-check.js:
+        * fast/js/script-tests/preventExtensions.js:
+        * fast/js/script-tests/prototypes.js:
+
 2012-02-13  Pavel Podivilov  <podivilov@chromium.org>
 
         Unreviewed, remove missing test from expectations.
index 892062b..a124e2e 100644 (file)
@@ -41,7 +41,7 @@ PASS getSortedOwnPropertyNames(decodeURIComponent) is ['length', 'name']
 PASS getSortedOwnPropertyNames(encodeURI) is ['length', 'name']
 PASS getSortedOwnPropertyNames(encodeURIComponent) is ['length', 'name']
 PASS getSortedOwnPropertyNames(Object) is ['create', 'defineProperties', 'defineProperty', 'freeze', 'getOwnPropertyDescriptor', 'getOwnPropertyNames', 'getPrototypeOf', 'isExtensible', 'isFrozen', 'isSealed', 'keys', 'length', 'name', 'preventExtensions', 'prototype', 'seal']
-PASS getSortedOwnPropertyNames(Object.prototype) is ['__defineGetter__', '__defineSetter__', '__lookupGetter__', '__lookupSetter__', '__proto__', 'constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', 'toLocaleString', 'toString', 'valueOf']
+PASS getSortedOwnPropertyNames(Object.prototype) is ['__defineGetter__', '__defineSetter__', '__lookupGetter__', '__lookupSetter__', 'constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', 'toLocaleString', 'toString', 'valueOf']
 PASS getSortedOwnPropertyNames(Function) is ['length', 'name', 'prototype']
 PASS getSortedOwnPropertyNames(Function.prototype) is ['apply', 'bind', 'call', 'constructor', 'length', 'name', 'toString']
 PASS getSortedOwnPropertyNames(Array) is ['isArray', 'length', 'name', 'prototype']
index 7953362..d1f9ac9 100644 (file)
@@ -3,10 +3,7 @@ This test makes sure we don't hang when setting cyclic prototype values: http://
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
 
-PASS o1.__proto__ = o3; threw exception Error: cyclic __proto__ value.
-PASS ({}).hasOwnProperty.call(o1, '__proto__') is false
-PASS ({}).hasOwnProperty.call(o1, '__proto__') is true
-PASS Object.getPrototypeOf(o1) is null
+PASS o1.__proto__ = o3 threw exception Error: cyclic __proto__ value.
 PASS successfullyParsed is true
 
 TEST COMPLETE
index ac7472f..2dd7626 100644 (file)
@@ -541,14 +541,14 @@ PASS Invalid: "for(var a,b 'this shouldn't be allowed' false ; ) ;"
 PASS Invalid: "function f() { for(var a,b 'this shouldn't be allowed' false ; ) ; }"
 PASS Invalid: "for(var a,b '"
 PASS Invalid: "function f() { for(var a,b ' }"
-PASS Valid:   "function __proto__(){}"
-PASS Valid:   "function f() { function __proto__(){} }"
-PASS Valid:   "(function __proto__(){})"
-PASS Valid:   "function f() { (function __proto__(){}) }"
-PASS Valid:   "'use strict'; function __proto__(){}"
-PASS Valid:   "function f() { 'use strict'; function __proto__(){} }"
-PASS Valid:   "'use strict'; (function __proto__(){})"
-PASS Valid:   "function f() { 'use strict'; (function __proto__(){}) }"
+PASS Invalid: "function __proto__(){}"
+PASS Invalid: "function f() { function __proto__(){} }"
+PASS Invalid: "(function __proto__(){})"
+PASS Invalid: "function f() { (function __proto__(){}) }"
+PASS Invalid: "'use strict'; function __proto__(){}"
+PASS Invalid: "function f() { 'use strict'; function __proto__(){} }"
+PASS Invalid: "'use strict'; (function __proto__(){})"
+PASS Invalid: "function f() { 'use strict'; (function __proto__(){}) }"
 PASS Valid:   "if (0) $foo; "
 PASS Valid:   "function f() { if (0) $foo;  }"
 PASS Valid:   "if (0) _foo; "
index fd7b6b6..fe43cb3 100644 (file)
@@ -12,7 +12,7 @@ PASS test(seal(obj())) is "(a:1)(b:4)S"
 PASS test(freeze(obj())) is "(a:1)(b:2)SF"
 PASS Object.preventExtensions(Math.sin) is Math.sin
 PASS var o = {}; Object.preventExtensions(o); o.__proto__ = { newProp: "Should not see this" }; o.newProp; is undefined.
-PASS "use strict"; var o = {}; Object.preventExtensions(o); o.__proto__ = { newProp: "Should not see this" }; o.newProp; is undefined.
+PASS "use strict"; var o = {}; Object.preventExtensions(o); o.__proto__ = { newProp: "Should not see this" }; threw exception TypeError: Attempted to assign to readonly property..
 PASS Object.preventExtensions(Math); Math.sqrt(4) is 2
 PASS successfullyParsed is true
 
index 0f1e440..781b0be 100644 (file)
@@ -53,14 +53,10 @@ PASS Object.__proto__.isPrototypeOf(Array) is true
 PASS Object.__proto__.isPrototypeOf(Date) is true
 PASS Object.__proto__.isPrototypeOf(Number) is true
 PASS Object.__proto__.isPrototypeOf(String) is true
-PASS var wasSet = false; var o = { }; o.__defineGetter__("__proto__", function() { wasSet = true }); o.__proto__; wasSet; is true
-PASS var wasSet = false; var o = { }; o.__defineSetter__("__proto__", function() { wasSet = true }); o.__proto__ = {}; wasSet; is true
-PASS var wasSet = false; var o = { }; Object.defineProperty(o, "__proto__", { "get": function() { wasSet = true } }); o.__proto__; wasSet; is true
+PASS var wasSet = false; var o = { }; o.__defineGetter__("__proto__", function() { wasSet = true }); o.__proto__; wasSet; is false
+PASS var wasSet = false; var o = { }; o.__defineSetter__("__proto__", function() { wasSet = true }); o.__proto__ = {}; wasSet; is false
+PASS var wasSet = false; var o = { }; Object.defineProperty(o, "__proto__", { "get": function() { wasSet = true } }); o.__proto__; wasSet; is false
 PASS var wasSet = false; var o = { }; Object.defineProperty(o, "__proto__", { "__proto__": function(x) { wasSet = true } }); o.__proto__ = {}; wasSet; is false
-PASS var o = {}; o.__proto__ = { x:true }; o.x is true
-PASS var o = {}; o.__proto__ = { x:true }; o.hasOwnProperty('__proto__') is false
-PASS var o = {}; o.__proto__ = { x:true }; o.x is undefined.
-PASS var o = {}; o.__proto__ = { x:true }; o.hasOwnProperty('__proto__') is true
 PASS successfullyParsed is true
 
 TEST COMPLETE
index daea97c..3ec75cb 100644 (file)
@@ -49,7 +49,7 @@ var expectedPropertyNamesSet = {
     "encodeURIComponent": "['length', 'name']",
 // Built-in ECMA objects
     "Object": "['create', 'defineProperties', 'defineProperty', 'freeze', 'getOwnPropertyDescriptor', 'getOwnPropertyNames', 'getPrototypeOf', 'isExtensible', 'isFrozen', 'isSealed', 'keys', 'length', 'name', 'preventExtensions', 'prototype', 'seal']",
-    "Object.prototype": "['__defineGetter__', '__defineSetter__', '__lookupGetter__', '__lookupSetter__', '__proto__', 'constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', 'toLocaleString', 'toString', 'valueOf']",
+    "Object.prototype": "['__defineGetter__', '__defineSetter__', '__lookupGetter__', '__lookupSetter__', 'constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', 'toLocaleString', 'toString', 'valueOf']",
     "Function": "['length', 'name', 'prototype']",
     "Function.prototype": "['apply', 'bind', 'call', 'constructor', 'length', 'name', 'toString']",
     "Array": "['isArray', 'length', 'name', 'prototype']",
index 041356e..a80e69e 100644 (file)
@@ -6,13 +6,6 @@ o2.__proto__ = o1;
 var o3 = { p3: 3 };
 o3.__proto__ = o2;
 
-// Try to create a cyclical prototype chain.
-shouldThrow("o1.__proto__ = o3;");
+o1.__proto__ = null;  // just for sanity's sake
 
-// This changes behaviour, since __proto__ is an accessor on Object.prototype.
-o1.__proto__ = null;
-
-shouldBeFalse("({}).hasOwnProperty.call(o1, '__proto__')");
-o1.__proto__ = o3;
-shouldBeTrue("({}).hasOwnProperty.call(o1, '__proto__')");
-shouldBe("Object.getPrototypeOf(o1)", "null");
+shouldThrow("o1.__proto__ = o3");
index e225baa..5fd6937 100644 (file)
@@ -347,10 +347,10 @@ invalid("L: L1: L2: L3: L4: L: ;");
 invalid("for(var a,b 'this shouldn\'t be allowed' false ; ) ;");
 invalid("for(var a,b '");
 
-valid("function __proto__(){}")
-valid("(function __proto__(){})")
-valid("'use strict'; function __proto__(){}")
-valid("'use strict'; (function __proto__(){})")
+invalid("function __proto__(){}")
+invalid("(function __proto__(){})")
+invalid("'use strict'; function __proto__(){}")
+invalid("'use strict'; (function __proto__(){})")
 
 valid("if (0) $foo; ")
 valid("if (0) _foo; ")
index 139b50d..65562e0 100644 (file)
@@ -69,7 +69,7 @@ shouldBe('test(freeze(obj()))', '"(a:1)(b:2)SF"'); // sealed and frozen, CANNOT
 shouldBe('Object.preventExtensions(Math.sin)', 'Math.sin');
 
 shouldBeUndefined('var o = {}; Object.preventExtensions(o); o.__proto__ = { newProp: "Should not see this" }; o.newProp;');
-shouldBeUndefined('"use strict"; var o = {}; Object.preventExtensions(o); o.__proto__ = { newProp: "Should not see this" }; o.newProp;');
+shouldThrow('"use strict"; var o = {}; Object.preventExtensions(o); o.__proto__ = { newProp: "Should not see this" };');
 
 // check that we can still access static properties on an object after calling preventExtensions.
 shouldBe('Object.preventExtensions(Math); Math.sqrt(4)', '2');
index 4be3fa6..7bbe1ad 100644 (file)
@@ -55,14 +55,7 @@ shouldBeTrue("Object.__proto__.isPrototypeOf(Date)");
 shouldBeTrue("Object.__proto__.isPrototypeOf(Number)");
 shouldBeTrue("Object.__proto__.isPrototypeOf(String)");
 
-shouldBeTrue("var wasSet = false; var o = { }; o.__defineGetter__(\"__proto__\", function() { wasSet = true }); o.__proto__; wasSet;");
-shouldBeTrue("var wasSet = false; var o = { }; o.__defineSetter__(\"__proto__\", function() { wasSet = true }); o.__proto__ = {}; wasSet;");
-shouldBeTrue("var wasSet = false; var o = { }; Object.defineProperty(o, \"__proto__\", { \"get\": function() { wasSet = true } }); o.__proto__; wasSet;");
+shouldBeFalse("var wasSet = false; var o = { }; o.__defineGetter__(\"__proto__\", function() { wasSet = true }); o.__proto__; wasSet;");
+shouldBeFalse("var wasSet = false; var o = { }; o.__defineSetter__(\"__proto__\", function() { wasSet = true }); o.__proto__ = {}; wasSet;");
+shouldBeFalse("var wasSet = false; var o = { }; Object.defineProperty(o, \"__proto__\", { \"get\": function() { wasSet = true } }); o.__proto__; wasSet;");
 shouldBeFalse("var wasSet = false; var o = { }; Object.defineProperty(o, \"__proto__\", { \"__proto__\": function(x) { wasSet = true } }); o.__proto__ = {}; wasSet;");
-
-// Deleting Object.prototype.__proto__ removes the ability to set the object's prototype.
-shouldBeTrue("var o = {}; o.__proto__ = { x:true }; o.x");
-shouldBeFalse("var o = {}; o.__proto__ = { x:true }; o.hasOwnProperty('__proto__')");
-delete Object.prototype.__proto__;
-shouldBeUndefined("var o = {}; o.__proto__ = { x:true }; o.x");
-shouldBeTrue("var o = {}; o.__proto__ = { x:true }; o.hasOwnProperty('__proto__')");
index e3ee08c..cac8c92 100644 (file)
@@ -1,3 +1,43 @@
+2012-02-13  Gavin Barraclough  <barraclough@apple.com>
+
+        https://bugs.webkit.org/show_bug.cgi?id=78434
+        Unreviewed - temporarily reverting r107498 will I fix a couple of testcases.
+
+        * parser/Parser.cpp:
+        (JSC::::parseFunctionInfo):
+        * runtime/ClassInfo.h:
+        (MethodTable):
+        (JSC):
+        * runtime/JSCell.cpp:
+        (JSC):
+        * runtime/JSCell.h:
+        (JSCell):
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::reset):
+        * runtime/JSGlobalObjectFunctions.cpp:
+        (JSC):
+        * runtime/JSGlobalObjectFunctions.h:
+        (JSC):
+        * runtime/JSObject.cpp:
+        (JSC::JSObject::put):
+        (JSC):
+        (JSC::JSObject::putDirectAccessor):
+        (JSC::JSObject::defineOwnProperty):
+        * runtime/JSObject.h:
+        (JSC::JSObject::inlineGetOwnPropertySlot):
+        (JSC::JSValue::get):
+        * runtime/JSString.cpp:
+        (JSC::JSString::getOwnPropertySlot):
+        * runtime/JSValue.h:
+        (JSValue):
+        * runtime/ObjectConstructor.cpp:
+        (JSC::objectConstructorGetPrototypeOf):
+        * runtime/Structure.cpp:
+        (JSC::Structure::Structure):
+        * runtime/Structure.h:
+        (JSC::Structure::setHasGetterSetterProperties):
+        (Structure):
+
 2012-02-12  Ashod Nakashian  <ashodnakashian@yahoo.com>
 
         KeywordLookupGenerator.py script fails in some cases
index 939d269..58e9e19 100644 (file)
@@ -774,6 +774,7 @@ template <FunctionRequirements requirements, bool nameIsInContainingScope, class
     functionScope->setIsFunction();
     if (match(IDENT)) {
         name = m_token.m_data.ident;
+        failIfTrueWithMessage(*name == m_globalData->propertyNames->underscoreProto, "Cannot name a function __proto__");
         next();
         if (!nameIsInContainingScope)
             failIfFalseIfStrict(functionScope->declareVariable(name));
index 0d33ae3..9ebb33a 100644 (file)
@@ -89,9 +89,6 @@ namespace JSC {
 
         typedef bool (*GetOwnPropertyDescriptorFunctionPtr)(JSObject*, ExecState*, const Identifier&, PropertyDescriptor&);
         GetOwnPropertyDescriptorFunctionPtr getOwnPropertyDescriptor;
-
-        typedef bool (*AllowsAccessFromFunctionPtr)(JSObject*, ExecState*);
-        AllowsAccessFromFunctionPtr allowsAccessFrom;
     };
 
 #define CREATE_MEMBER_CHECKER(member) \
@@ -133,7 +130,6 @@ struct MemberCheck##member { \
         &ClassName::putDirectVirtual, \
         &ClassName::defineOwnProperty, \
         &ClassName::getOwnPropertyDescriptor, \
-        &ClassName::allowsAccessFrom, \
     }, \
     sizeof(ClassName), \
     ClassName::TypedArrayStorageType
index f49a430..4703b68 100644 (file)
@@ -191,12 +191,6 @@ void JSCell::putDirectVirtual(JSObject*, ExecState*, const Identifier&, JSValue,
     ASSERT_NOT_REACHED();
 }
 
-bool JSCell::allowsAccessFrom(JSObject*, ExecState*)
-{
-    ASSERT_NOT_REACHED();
-    return false;
-}
-
 bool JSCell::defineOwnProperty(JSObject*, ExecState*, const Identifier&, PropertyDescriptor&, bool)
 {
     ASSERT_NOT_REACHED();
index 4b8688f..baaa9ef 100644 (file)
@@ -161,7 +161,6 @@ namespace JSC {
         static NO_RETURN_DUE_TO_ASSERT void putDirectVirtual(JSObject*, ExecState*, const Identifier& propertyName, JSValue, unsigned attributes);
         static bool defineOwnProperty(JSObject*, ExecState*, const Identifier& propertyName, PropertyDescriptor&, bool shouldThrow);
         static bool getOwnPropertyDescriptor(JSObject*, ExecState*, const Identifier&, PropertyDescriptor&);
-        static bool allowsAccessFrom(JSObject*, ExecState*);
 
     private:
         const ClassInfo* m_classInfo;
index 72c20d7..e648fbe 100644 (file)
@@ -205,10 +205,6 @@ void JSGlobalObject::reset(JSValue prototype)
     m_callFunction.set(exec->globalData(), this, callFunction);
     m_applyFunction.set(exec->globalData(), this, applyFunction);
     m_objectPrototype.set(exec->globalData(), this, ObjectPrototype::create(exec, this, ObjectPrototype::createStructure(exec->globalData(), this, jsNull())));
-    GetterSetter* protoAccessor = GetterSetter::create(exec);
-    protoAccessor->setGetter(exec->globalData(), JSFunction::create(exec, this, 0, Identifier(), globalFuncProtoGetter));
-    protoAccessor->setSetter(exec->globalData(), JSFunction::create(exec, this, 0, Identifier(), globalFuncProtoSetter));
-    m_objectPrototype->putDirectAccessor(exec->globalData(), exec->propertyNames().underscoreProto, protoAccessor, Accessor | DontEnum);
     m_functionPrototype->structure()->setPrototypeWithoutTransition(exec->globalData(), m_objectPrototype.get());
 
     m_emptyObjectStructure.set(exec->globalData(), this, m_objectPrototype->inheritorID(exec->globalData()));
index 748990f..b82ab62 100644 (file)
@@ -714,41 +714,4 @@ EncodedJSValue JSC_HOST_CALL globalFuncThrowTypeError(ExecState* exec)
     return throwVMTypeError(exec);
 }
 
-EncodedJSValue JSC_HOST_CALL globalFuncProtoGetter(ExecState* exec)
-{
-    if (!exec->thisValue().isObject())
-        return JSValue::encode(exec->thisValue().synthesizePrototype(exec));
-
-    JSObject* thisObject = asObject(exec->thisValue());
-    if (!thisObject->methodTable()->allowsAccessFrom(thisObject, exec))
-        return JSValue::encode(jsUndefined());
-
-    return JSValue::encode(thisObject->prototype());
-}
-
-EncodedJSValue JSC_HOST_CALL globalFuncProtoSetter(ExecState* exec)
-{
-    JSValue value = exec->argument(0);
-
-    // Setting __proto__ of a primitive should have no effect.
-    if (!exec->thisValue().isObject())
-        return JSValue::encode(jsUndefined());
-
-    JSObject* thisObject = asObject(exec->thisValue());
-    if (!thisObject->methodTable()->allowsAccessFrom(thisObject, exec))
-        return JSValue::encode(jsUndefined());
-
-    // Setting __proto__ to a non-object, non-null value is silently ignored to match Mozilla.
-    if (!value.isObject() && !value.isNull())
-        return JSValue::encode(jsUndefined());
-
-    if (!thisObject->isExtensible())
-        return JSValue::encode(jsUndefined());
-
-    if (!thisObject->setPrototypeWithCycleCheck(exec->globalData(), value))
-        throwError(exec, createError(exec, "cyclic __proto__ value"));
-
-    return JSValue::encode(jsUndefined());
-}
-
 } // namespace JSC
index 8833bf6..1183dfa 100644 (file)
@@ -48,8 +48,6 @@ namespace JSC {
     EncodedJSValue JSC_HOST_CALL globalFuncEscape(ExecState*);
     EncodedJSValue JSC_HOST_CALL globalFuncUnescape(ExecState*);
     EncodedJSValue JSC_HOST_CALL globalFuncThrowTypeError(ExecState*);
-    EncodedJSValue JSC_HOST_CALL globalFuncProtoGetter(ExecState*);
-    EncodedJSValue JSC_HOST_CALL globalFuncProtoSetter(ExecState*);
 
     static const double mantissaOverflowLowerBound = 9007199254740992.0;
     double parseIntOverflow(const LChar*, int length, int radix);
index ee91b78..4d90f5a 100644 (file)
@@ -132,19 +132,33 @@ void JSObject::put(JSCell* cell, ExecState* exec, const Identifier& propertyName
     ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(thisObject));
     JSGlobalData& globalData = exec->globalData();
 
+    if (propertyName == exec->propertyNames().underscoreProto) {
+        // Setting __proto__ to a non-object, non-null value is silently ignored to match Mozilla.
+        if (!value.isObject() && !value.isNull())
+            return;
+
+        if (!thisObject->isExtensible()) {
+            if (slot.isStrictMode())
+                throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
+            return;
+        }
+            
+        if (!thisObject->setPrototypeWithCycleCheck(globalData, value))
+            throwError(exec, createError(exec, "cyclic __proto__ value"));
+        return;
+    }
+
     // Check if there are any setters or getters in the prototype chain
     JSValue prototype;
-    if (propertyName != exec->propertyNames().underscoreProto) {
-        for (JSObject* obj = thisObject; !obj->structure()->hasGetterSetterPropertiesExcludingProto(); obj = asObject(prototype)) {
-            prototype = obj->prototype();
-            if (prototype.isNull()) {
-                if (!thisObject->putDirectInternal<PutModePut>(globalData, propertyName, value, 0, slot, getJSFunction(value)) && slot.isStrictMode())
-                    throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
-                return;
-            }
+    for (JSObject* obj = thisObject; !obj->structure()->hasGetterSetterProperties(); obj = asObject(prototype)) {
+        prototype = obj->prototype();
+        if (prototype.isNull()) {
+            if (!thisObject->putDirectInternal<PutModePut>(globalData, propertyName, value, 0, slot, getJSFunction(value)) && slot.isStrictMode())
+                throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
+            return;
         }
     }
-
+    
     unsigned attributes;
     JSCell* specificValue;
     if ((thisObject->structure()->get(globalData, propertyName, attributes, specificValue) != WTF::notFound) && attributes & ReadOnly) {
@@ -201,14 +215,10 @@ void JSObject::putDirectVirtual(JSObject* object, ExecState* exec, const Identif
     object->putDirectInternal<PutModeDefineOwnProperty>(exec->globalData(), propertyName, value, attributes, slot, getJSFunction(value));
 }
 
-bool JSObject::allowsAccessFrom(JSObject*, ExecState*)
-{
-    return true;
-}
-
 void JSObject::putDirectAccessor(JSGlobalData& globalData, const Identifier& propertyName, JSValue value, unsigned attributes)
 {
     ASSERT(value.isGetterSetter() && (attributes & Accessor));
+    ASSERT(propertyName != globalData.propertyNames->underscoreProto);
 
     PutPropertySlot slot;
     putDirectInternal<PutModeDefineOwnProperty>(globalData, propertyName, value, attributes, slot, getJSFunction(value));
@@ -219,7 +229,7 @@ void JSObject::putDirectAccessor(JSGlobalData& globalData, const Identifier& pro
     if (slot.type() != PutPropertySlot::NewProperty)
         setStructure(globalData, Structure::attributeChangeTransition(globalData, structure(), propertyName, attributes));
 
-    structure()->setHasGetterSetterProperties(propertyName == globalData.propertyNames->underscoreProto);
+    structure()->setHasGetterSetterProperties(true);
 }
 
 bool JSObject::hasProperty(ExecState* exec, const Identifier& propertyName) const
@@ -619,6 +629,11 @@ static bool putDescriptor(ExecState* exec, JSObject* target, const Identifier& p
 
 bool JSObject::defineOwnProperty(JSObject* object, ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor, bool throwException)
 {
+    // __proto__ is magic; we don't currently support setting it as a regular property.
+    // Silent filter out calls to set __proto__ at an early stage; pretend all is okay.
+    if (propertyName == exec->propertyNames().underscoreProto)
+        return true;
+
     // If we have a new property we can just put it on normally
     PropertyDescriptor current;
     if (!object->methodTable()->getOwnPropertyDescriptor(object, exec, propertyName, current)) {
index 037cc59..9b5516c 100644 (file)
@@ -104,7 +104,6 @@ namespace JSC {
         static bool getOwnPropertySlot(JSCell*, ExecState*, const Identifier& propertyName, PropertySlot&);
         JS_EXPORT_PRIVATE static bool getOwnPropertySlotByIndex(JSCell*, ExecState*, unsigned propertyName, PropertySlot&);
         JS_EXPORT_PRIVATE static bool getOwnPropertyDescriptor(JSObject*, ExecState*, const Identifier&, PropertyDescriptor&);
-        JS_EXPORT_PRIVATE static bool allowsAccessFrom(JSObject*, ExecState*);
 
         JS_EXPORT_PRIVATE static void put(JSCell*, ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&);
         JS_EXPORT_PRIVATE static void putByIndex(JSCell*, ExecState*, unsigned propertyName, JSValue);
@@ -551,6 +550,12 @@ ALWAYS_INLINE bool JSObject::inlineGetOwnPropertySlot(ExecState* exec, const Ide
         return true;
     }
 
+    // non-standard Netscape extension
+    if (propertyName == exec->propertyNames().underscoreProto) {
+        slot.setValue(prototype());
+        return true;
+    }
+
     return false;
 }
 
@@ -798,6 +803,8 @@ inline JSValue JSValue::get(ExecState* exec, const Identifier& propertyName, Pro
 {
     if (UNLIKELY(!isCell())) {
         JSObject* prototype = synthesizePrototype(exec);
+        if (propertyName == exec->propertyNames().underscoreProto)
+            return prototype;
         if (!prototype->getPropertySlot(exec, propertyName, slot))
             return jsUndefined();
         return slot.getValue(exec, propertyName);
index 3fa2901..4e98f9d 100644 (file)
@@ -253,6 +253,10 @@ bool JSString::getOwnPropertySlot(JSCell* cell, ExecState* exec, const Identifie
     // This function should only be called by JSValue::get.
     if (thisObject->getStringPropertySlot(exec, propertyName, slot))
         return true;
+    if (propertyName == exec->propertyNames().underscoreProto) {
+        slot.setValue(exec->lexicalGlobalObject()->stringPrototype());
+        return true;
+    }
     slot.setBase(thisObject);
     JSObject* object;
     for (JSValue prototype = exec->lexicalGlobalObject()->stringPrototype(); !prototype.isNull(); prototype = object->prototype()) {
index 80acbb1..b18c181 100644 (file)
@@ -234,8 +234,6 @@ namespace JSC {
 
         char* description();
 
-        JS_EXPORT_PRIVATE JSObject* synthesizePrototype(ExecState*) const;
-
     private:
         template <class T> JSValue(WriteBarrierBase<T>);
 
@@ -248,6 +246,7 @@ namespace JSC {
         JS_EXPORT_PRIVATE JSObject* toObjectSlowCase(ExecState*, JSGlobalObject*) const;
         JS_EXPORT_PRIVATE JSObject* toThisObjectSlowCase(ExecState*) const;
 
+        JS_EXPORT_PRIVATE JSObject* synthesizePrototype(ExecState*) const;
         JSObject* synthesizeObject(ExecState*) const;
 
 #if USE(JSVALUE32_64)
index b6c74d4..d96c1de 100644 (file)
@@ -138,12 +138,11 @@ EncodedJSValue JSC_HOST_CALL objectConstructorGetPrototypeOf(ExecState* exec)
 {
     if (!exec->argument(0).isObject())
         return throwVMError(exec, createTypeError(exec, "Requested prototype of a value that is not an object."));
-    JSObject* object = asObject(exec->argument(0));
-
-    if (!object->methodTable()->allowsAccessFrom(object, exec))
-        return JSValue::encode(jsUndefined());
-
-    return JSValue::encode(object->prototype());
+        
+    // This uses JSValue::get() instead of directly accessing the prototype from the object
+    // (using JSObject::prototype()) in order to allow objects to override the behavior, such
+    // as returning jsUndefined() for cross-origin access.
+    return JSValue::encode(exec->argument(0).get(exec, exec->propertyNames().underscoreProto));
 }
 
 EncodedJSValue JSC_HOST_CALL objectConstructorGetOwnPropertyDescriptor(ExecState* exec)
index 4ce9f4e..978e3d3 100644 (file)
@@ -167,7 +167,6 @@ Structure::Structure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSV
     , m_dictionaryKind(NoneDictionaryKind)
     , m_isPinnedPropertyTable(false)
     , m_hasGetterSetterProperties(false)
-    , m_hasGetterSetterPropertiesExcludingProto(false)
     , m_hasNonEnumerableProperties(false)
     , m_attributesInPrevious(0)
     , m_specificFunctionThrashCount(0)
@@ -189,7 +188,6 @@ Structure::Structure(JSGlobalData& globalData)
     , m_dictionaryKind(NoneDictionaryKind)
     , m_isPinnedPropertyTable(false)
     , m_hasGetterSetterProperties(false)
-    , m_hasGetterSetterPropertiesExcludingProto(false)
     , m_hasNonEnumerableProperties(false)
     , m_attributesInPrevious(0)
     , m_specificFunctionThrashCount(0)
@@ -209,7 +207,6 @@ Structure::Structure(JSGlobalData& globalData, const Structure* previous)
     , m_dictionaryKind(previous->m_dictionaryKind)
     , m_isPinnedPropertyTable(false)
     , m_hasGetterSetterProperties(previous->m_hasGetterSetterProperties)
-    , m_hasGetterSetterPropertiesExcludingProto(previous->m_hasGetterSetterPropertiesExcludingProto)
     , m_hasNonEnumerableProperties(previous->m_hasNonEnumerableProperties)
     , m_attributesInPrevious(0)
     , m_specificFunctionThrashCount(previous->m_specificFunctionThrashCount)
index aec2c8a..ced2968 100644 (file)
@@ -145,13 +145,7 @@ namespace JSC {
         }
 
         bool hasGetterSetterProperties() const { return m_hasGetterSetterProperties; }
-        bool hasGetterSetterPropertiesExcludingProto() const { return m_hasGetterSetterPropertiesExcludingProto; }
-        void setHasGetterSetterProperties(bool isProto)
-        {
-            m_hasGetterSetterProperties = true;
-            if (!isProto)
-                m_hasGetterSetterPropertiesExcludingProto = true;
-        }
+        void setHasGetterSetterProperties(bool hasGetterSetterProperties) { m_hasGetterSetterProperties = hasGetterSetterProperties; }
 
         bool hasNonEnumerableProperties() const { return m_hasNonEnumerableProperties; }
         
@@ -288,7 +282,6 @@ namespace JSC {
         unsigned m_dictionaryKind : 2;
         bool m_isPinnedPropertyTable : 1;
         bool m_hasGetterSetterProperties : 1;
-        bool m_hasGetterSetterPropertiesExcludingProto : 1;
         bool m_hasNonEnumerableProperties : 1;
         unsigned m_attributesInPrevious : 7;
         unsigned m_specificFunctionThrashCount : 2;
index 7f1e921..99bb7d9 100644 (file)
@@ -1,3 +1,13 @@
+2012-02-13  Gavin Barraclough  <barraclough@apple.com>
+
+        https://bugs.webkit.org/show_bug.cgi?id=78434
+        Unreviewed - temporarily reverting r107498 will I fix a couple of testcases.
+
+        * bindings/js/JSDOMWindowBase.cpp:
+        (WebCore):
+        * bindings/js/JSDOMWindowBase.h:
+        (JSDOMWindowBase):
+
 2012-02-13  Ilya Tikhonovsky  <loislo@chromium.org>
 
         Web Inspector: get rid of cycles in containment view of an object.
index 0bdaf59..8de432e 100644 (file)
@@ -92,11 +92,6 @@ void JSDOMWindowBase::printErrorMessage(const String& message) const
     printErrorMessageForFrame(impl()->frame(), message);
 }
 
-bool JSDOMWindowBase::allowsAccessFrom(JSObject* thisObject, ExecState* exec)
-{
-    return static_cast<JSDOMWindowBase*>(thisObject)->allowsAccessFrom(exec);
-}
-
 bool JSDOMWindowBase::supportsProfiling(const JSGlobalObject* object)
 {
 #if !ENABLE(JAVASCRIPT_DEBUGGER) || !ENABLE(INSPECTOR)
index 13d7d36..84c1862 100644 (file)
@@ -63,8 +63,7 @@ namespace WebCore {
         static bool supportsProfiling(const JSC::JSGlobalObject*);
         static bool supportsRichSourceInfo(const JSC::JSGlobalObject*);
         static bool shouldInterruptScript(const JSC::JSGlobalObject*);
-        static bool allowsAccessFrom(JSC::JSObject*, JSC::ExecState*);
-        
+
         bool allowsAccessFrom(JSC::ExecState*) const;
         bool allowsAccessFromNoErrorMessage(JSC::ExecState*) const;
         bool allowsAccessFrom(JSC::ExecState*, String& message) const;