- Revision
- 91224
- Author
- [email protected]
- Date
- 2011-07-18 17:25:49 -0700 (Mon, 18 Jul 2011)
Log Message
https://bugs.webkit.org/show_bug.cgi?id=64678
Fix bugs in Object.prototype this handling.
Reviewed by Oliver Hunt.
Source/_javascript_Core:
undefined/null this values should throw TypeErrors, not convert to the global object,
also, to toLocaleString should be calling the ToObject & invoking the object's toString
function, even for values that are already strings.
* runtime/ObjectPrototype.cpp:
(JSC::objectProtoFuncValueOf):
(JSC::objectProtoFuncHasOwnProperty):
(JSC::objectProtoFuncIsPrototypeOf):
(JSC::objectProtoFuncPropertyIsEnumerable):
(JSC::objectProtoFuncToLocaleString):
(JSC::objectProtoFuncToString):
LayoutTests:
* fast/js/resources/js-test-pre.js:
- Updated harness to not call Object.prototype.toString on undefined.
* fast/js/eval-var-decl-expected.txt:
* fast/js/object-prototype-properties-expected.txt: Added.
* fast/js/object-prototype-properties.html: Added.
* fast/js/object-prototype-toLocaleString-expected.txt
* fast/js/script-tests/eval-var-decl.js:
- Fix test case, calling hasProperty with undefined as the this value should throw.
* fast/js/script-tests/object-prototype-properties.js: Added.
- Place for test cases for Object.prototype properties; to being with, check that calling these methods on undefined throws!
* fast/js/script-tests/object-prototype-toLocaleString.js:
- Added test cases for correct behaviour when this is a string primitive.
* sputnik/Conformance/11_Expressions/11.1_Primary_Expressions/11.1.1_The_this_Keyword/S11.1.1_A2-expected.txt:
* sputnik/Conformance/15_Native_Objects/15.5_String/15.5.4/15.5.4.10_String.prototype.match/S15.5.4.10_A1_T3-expected.txt:
* sputnik/Conformance/15_Native_Objects/15.5_String/15.5.4/15.5.4.11_String.prototype.replace/S15.5.4.11_A1_T3-expected.txt:
* sputnik/Conformance/15_Native_Objects/15.5_String/15.5.4/15.5.4.12_String.prototype.search/S15.5.4.12_A1_T3-expected.txt:
* sputnik/Conformance/15_Native_Objects/15.5_String/15.5.4/15.5.4.13_String.prototype.slice/S15.5.4.13_A1_T3-expected.txt:
* sputnik/Conformance/15_Native_Objects/15.5_String/15.5.4/15.5.4.14_String.prototype.split/S15.5.4.14_A1_T3-expected.txt:
* sputnik/Conformance/15_Native_Objects/15.5_String/15.5.4/15.5.4.15_String.prototype.substring/S15.5.4.15_A1_T3-expected.txt:
* sputnik/Conformance/15_Native_Objects/15.5_String/15.5.4/15.5.4.4_String.prototype.charAt/S15.5.4.4_A1_T3-expected.txt:
* sputnik/Conformance/15_Native_Objects/15.5_String/15.5.4/15.5.4.5_String.prototype.charCodeAt/S15.5.4.5_A1_T3-expected.txt:
* sputnik/Conformance/15_Native_Objects/15.5_String/15.5.4/15.5.4.6_String.prototype.concat/S15.5.4.6_A1_T3-expected.txt:
* sputnik/Conformance/15_Native_Objects/15.5_String/15.5.4/15.5.4.7_String.prototype.indexOf/S15.5.4.7_A1_T3-expected.txt:
* sputnik/Conformance/15_Native_Objects/15.5_String/15.5.4/15.5.4.8_String.prototype.lastIndexOf/S15.5.4.8_A1_T3-expected.txt:
- These test cases are all incorrect. (See https://bugs.ecmascript.org/show_bug.cgi?id=117).
We were incorrectly passing 15.5.4.11_String.prototype.replace, this should fail, as the others do.
All the other 15.5.4 tests were failing & are still failing, but now have a better error message.
S11.1.1_A2 is also invalid, calling toString() passing undefined as this should throw.
Modified Paths
Added Paths
Diff
Modified: trunk/LayoutTests/ChangeLog (91223 => 91224)
--- trunk/LayoutTests/ChangeLog 2011-07-19 00:20:42 UTC (rev 91223)
+++ trunk/LayoutTests/ChangeLog 2011-07-19 00:25:49 UTC (rev 91224)
@@ -1,3 +1,39 @@
+2011-07-18 Gavin Barraclough <[email protected]>
+
+ https://bugs.webkit.org/show_bug.cgi?id=64678
+ Fix bugs in Object.prototype this handling.
+
+ Reviewed by Oliver Hunt.
+
+ * fast/js/resources/js-test-pre.js:
+ - Updated harness to not call Object.prototype.toString on undefined.
+ * fast/js/eval-var-decl-expected.txt:
+ * fast/js/object-prototype-properties-expected.txt: Added.
+ * fast/js/object-prototype-properties.html: Added.
+ * fast/js/object-prototype-toLocaleString-expected.txt
+ * fast/js/script-tests/eval-var-decl.js:
+ - Fix test case, calling hasProperty with undefined as the this value should throw.
+ * fast/js/script-tests/object-prototype-properties.js: Added.
+ - Place for test cases for Object.prototype properties; to being with, check that calling these methods on undefined throws!
+ * fast/js/script-tests/object-prototype-toLocaleString.js:
+ - Added test cases for correct behaviour when this is a string primitive.
+ * sputnik/Conformance/11_Expressions/11.1_Primary_Expressions/11.1.1_The_this_Keyword/S11.1.1_A2-expected.txt:
+ * sputnik/Conformance/15_Native_Objects/15.5_String/15.5.4/15.5.4.10_String.prototype.match/S15.5.4.10_A1_T3-expected.txt:
+ * sputnik/Conformance/15_Native_Objects/15.5_String/15.5.4/15.5.4.11_String.prototype.replace/S15.5.4.11_A1_T3-expected.txt:
+ * sputnik/Conformance/15_Native_Objects/15.5_String/15.5.4/15.5.4.12_String.prototype.search/S15.5.4.12_A1_T3-expected.txt:
+ * sputnik/Conformance/15_Native_Objects/15.5_String/15.5.4/15.5.4.13_String.prototype.slice/S15.5.4.13_A1_T3-expected.txt:
+ * sputnik/Conformance/15_Native_Objects/15.5_String/15.5.4/15.5.4.14_String.prototype.split/S15.5.4.14_A1_T3-expected.txt:
+ * sputnik/Conformance/15_Native_Objects/15.5_String/15.5.4/15.5.4.15_String.prototype.substring/S15.5.4.15_A1_T3-expected.txt:
+ * sputnik/Conformance/15_Native_Objects/15.5_String/15.5.4/15.5.4.4_String.prototype.charAt/S15.5.4.4_A1_T3-expected.txt:
+ * sputnik/Conformance/15_Native_Objects/15.5_String/15.5.4/15.5.4.5_String.prototype.charCodeAt/S15.5.4.5_A1_T3-expected.txt:
+ * sputnik/Conformance/15_Native_Objects/15.5_String/15.5.4/15.5.4.6_String.prototype.concat/S15.5.4.6_A1_T3-expected.txt:
+ * sputnik/Conformance/15_Native_Objects/15.5_String/15.5.4/15.5.4.7_String.prototype.indexOf/S15.5.4.7_A1_T3-expected.txt:
+ * sputnik/Conformance/15_Native_Objects/15.5_String/15.5.4/15.5.4.8_String.prototype.lastIndexOf/S15.5.4.8_A1_T3-expected.txt:
+ - These test cases are all incorrect. (See https://bugs.ecmascript.org/show_bug.cgi?id=117).
+ We were incorrectly passing 15.5.4.11_String.prototype.replace, this should fail, as the others do.
+ All the other 15.5.4 tests were failing & are still failing, but now have a better error message.
+ S11.1.1_A2 is also invalid, calling toString() passing undefined as this should throw.
+
2011-07-18 Ryosuke Niwa <[email protected]>
Fix a typo.
Modified: trunk/LayoutTests/fast/js/eval-var-decl-expected.txt (91223 => 91224)
--- trunk/LayoutTests/fast/js/eval-var-decl-expected.txt 2011-07-19 00:20:42 UTC (rev 91223)
+++ trunk/LayoutTests/fast/js/eval-var-decl-expected.txt 2011-07-19 00:25:49 UTC (rev 91224)
@@ -3,8 +3,8 @@
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-PASS hasOwnProperty("foo") is true
-PASS hasOwnProperty("bar") is true
+PASS this.hasOwnProperty("foo") is true
+PASS this.hasOwnProperty("bar") is true
PASS firstEvalResult is true
PASS secondEvalResult is false
PASS thirdEvalResult is true
Added: trunk/LayoutTests/fast/js/object-prototype-properties-expected.txt (0 => 91224)
--- trunk/LayoutTests/fast/js/object-prototype-properties-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/js/object-prototype-properties-expected.txt 2011-07-19 00:25:49 UTC (rev 91224)
@@ -0,0 +1,15 @@
+This is a test case for bug 64678.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS toString() threw exception TypeError: 'undefined' is not an object (evaluating 'toString()').
+PASS toLocaleString() threw exception TypeError: 'undefined' is not an object (evaluating 'toLocaleString()').
+PASS valueOf() threw exception TypeError: 'undefined' is not an object (evaluating 'valueOf()').
+PASS hasProperty('hasProperty') threw exception ReferenceError: Can't find variable: hasProperty.
+PASS propertyIsEnumerable('hasProperty') threw exception TypeError: 'undefined' is not an object (evaluating 'propertyIsEnumerable('hasProperty')').
+PASS isPrototypeOf(this) threw exception TypeError: 'undefined' is not an object (evaluating 'isPrototypeOf(this)').
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/fast/js/object-prototype-properties.html (0 => 91224)
--- trunk/LayoutTests/fast/js/object-prototype-properties.html (rev 0)
+++ trunk/LayoutTests/fast/js/object-prototype-properties.html 2011-07-19 00:25:49 UTC (rev 91224)
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<link rel="stylesheet" href=""
+<script src=""
+</head>
+<body>
+<p id="description"></p>
+<div id="console"></div>
+<script src=""
+<script src=""
+</body>
+</html>
Modified: trunk/LayoutTests/fast/js/object-prototype-toLocaleString-expected.txt (91223 => 91224)
--- trunk/LayoutTests/fast/js/object-prototype-toLocaleString-expected.txt 2011-07-19 00:20:42 UTC (rev 91223)
+++ trunk/LayoutTests/fast/js/object-prototype-toLocaleString-expected.txt 2011-07-19 00:25:49 UTC (rev 91224)
@@ -5,6 +5,8 @@
PASS o.toLocaleString() is o.toString()
PASS o.toLocaleString() is "Dynamic toLocaleString()"
+PASS Object.prototype.toLocaleString.call('Hello, world!') is "Hello, world!"
+PASS Object.prototype.toLocaleString.call('Hello, world!') is "stringPrototypeToString"
PASS successfullyParsed is true
TEST COMPLETE
Modified: trunk/LayoutTests/fast/js/resources/js-test-pre.js (91223 => 91224)
--- trunk/LayoutTests/fast/js/resources/js-test-pre.js 2011-07-19 00:20:42 UTC (rev 91223)
+++ trunk/LayoutTests/fast/js/resources/js-test-pre.js 2011-07-19 00:25:49 UTC (rev 91224)
@@ -65,7 +65,7 @@
return true;
if (typeof(_expected) == "number" && isNaN(_expected))
return typeof(_actual) == "number" && isNaN(_actual);
- if (Object.prototype.toString.call(_expected) == Object.prototype.toString.call([]))
+ if (_expected && (Object.prototype.toString.call(_expected) == Object.prototype.toString.call([])))
return areArraysEqual(_actual, _expected);
return false;
}
Modified: trunk/LayoutTests/fast/js/script-tests/eval-var-decl.js (91223 => 91224)
--- trunk/LayoutTests/fast/js/script-tests/eval-var-decl.js 2011-07-19 00:20:42 UTC (rev 91223)
+++ trunk/LayoutTests/fast/js/script-tests/eval-var-decl.js 2011-07-19 00:25:49 UTC (rev 91224)
@@ -2,17 +2,17 @@
"This test case checks whether variables cause properties to be defined even before reaching the declaration statement in various cases."
);
-shouldBeTrue('hasOwnProperty("foo")');
+shouldBeTrue('this.hasOwnProperty("foo")');
var foo = 3;
delete bar;
-shouldBeTrue('hasOwnProperty("bar")');
+shouldBeTrue('this.hasOwnProperty("bar")');
var bar = 3;
-var firstEvalResult = eval('var result = hasOwnProperty("y"); var y = 3; result');
+var firstEvalResult = eval('var result = this.hasOwnProperty("y"); var y = 3; result');
shouldBeTrue("firstEvalResult");
-var secondEvalResult = eval('delete x; var result = hasOwnProperty("x"); var x = 3; result');
+var secondEvalResult = eval('delete x; var result = this.hasOwnProperty("x"); var x = 3; result');
shouldBeFalse("secondEvalResult");
var thirdEvalResult = false;
Added: trunk/LayoutTests/fast/js/script-tests/object-prototype-properties.js (0 => 91224)
--- trunk/LayoutTests/fast/js/script-tests/object-prototype-properties.js (rev 0)
+++ trunk/LayoutTests/fast/js/script-tests/object-prototype-properties.js 2011-07-19 00:25:49 UTC (rev 91224)
@@ -0,0 +1,13 @@
+description(
+'This is a test case for <a https://bugs.webkit.org/show_bug.cgi?id=64678">bug 64678</a>.'
+);
+
+// These call pass undefined as this value, and as such should show in toObject.
+shouldThrow("toString()");
+shouldThrow("toLocaleString()");
+shouldThrow("valueOf()");
+shouldThrow("hasProperty('hasProperty')");
+shouldThrow("propertyIsEnumerable('hasProperty')");
+shouldThrow("isPrototypeOf(this)");
+
+var successfullyParsed = true;
Modified: trunk/LayoutTests/fast/js/script-tests/object-prototype-toLocaleString.js (91223 => 91224)
--- trunk/LayoutTests/fast/js/script-tests/object-prototype-toLocaleString.js 2011-07-19 00:20:42 UTC (rev 91223)
+++ trunk/LayoutTests/fast/js/script-tests/object-prototype-toLocaleString.js 2011-07-19 00:25:49 UTC (rev 91224)
@@ -7,4 +7,11 @@
o.toLocaleString = function () { return "Dynamic toLocaleString()"; }
shouldBe("o.toLocaleString()", '"Dynamic toLocaleString()"');
+shouldBe("Object.prototype.toLocaleString.call('Hello, world!')", '"Hello, world!"');
+
+var stringPrototypeToString = String.prototype.toString;
+String.prototype.toString = (function(){ return "stringPrototypeToString"; });
+shouldBe("Object.prototype.toLocaleString.call('Hello, world!')", '"stringPrototypeToString"');
+String.prototype.toString = stringPrototypeToString;
+
var successfullyParsed = true;
Modified: trunk/Source/_javascript_Core/ChangeLog (91223 => 91224)
--- trunk/Source/_javascript_Core/ChangeLog 2011-07-19 00:20:42 UTC (rev 91223)
+++ trunk/Source/_javascript_Core/ChangeLog 2011-07-19 00:25:49 UTC (rev 91224)
@@ -1,3 +1,22 @@
+2011-07-18 Gavin Barraclough <[email protected]>
+
+ https://bugs.webkit.org/show_bug.cgi?id=64678
+ Fix bugs in Object.prototype this handling.
+
+ Reviewed by Oliver Hunt.
+
+ undefined/null this values should throw TypeErrors, not convert to the global object,
+ also, to toLocaleString should be calling the ToObject & invoking the object's toString
+ function, even for values that are already strings.
+
+ * runtime/ObjectPrototype.cpp:
+ (JSC::objectProtoFuncValueOf):
+ (JSC::objectProtoFuncHasOwnProperty):
+ (JSC::objectProtoFuncIsPrototypeOf):
+ (JSC::objectProtoFuncPropertyIsEnumerable):
+ (JSC::objectProtoFuncToLocaleString):
+ (JSC::objectProtoFuncToString):
+
2011-07-18 Filip Pizlo <[email protected]>
JSC GC lazy sweep does not inline the common cases of cell destruction.
Modified: trunk/Source/_javascript_Core/runtime/ObjectPrototype.cpp (91223 => 91224)
--- trunk/Source/_javascript_Core/runtime/ObjectPrototype.cpp 2011-07-19 00:20:42 UTC (rev 91223)
+++ trunk/Source/_javascript_Core/runtime/ObjectPrototype.cpp 2011-07-19 00:25:49 UTC (rev 91224)
@@ -104,19 +104,19 @@
EncodedJSValue JSC_HOST_CALL objectProtoFuncValueOf(ExecState* exec)
{
JSValue thisValue = exec->hostThisValue();
- return JSValue::encode(thisValue.toThisObject(exec));
+ return JSValue::encode(thisValue.toObject(exec));
}
EncodedJSValue JSC_HOST_CALL objectProtoFuncHasOwnProperty(ExecState* exec)
{
JSValue thisValue = exec->hostThisValue();
- return JSValue::encode(jsBoolean(thisValue.toThisObject(exec)->hasOwnProperty(exec, Identifier(exec, exec->argument(0).toString(exec)))));
+ return JSValue::encode(jsBoolean(thisValue.toObject(exec)->hasOwnProperty(exec, Identifier(exec, exec->argument(0).toString(exec)))));
}
EncodedJSValue JSC_HOST_CALL objectProtoFuncIsPrototypeOf(ExecState* exec)
{
JSValue thisValue = exec->hostThisValue();
- JSObject* thisObj = thisValue.toThisObject(exec);
+ JSObject* thisObj = thisValue.toObject(exec);
if (!exec->argument(0).isObject())
return JSValue::encode(jsBoolean(false));
@@ -167,19 +167,34 @@
EncodedJSValue JSC_HOST_CALL objectProtoFuncPropertyIsEnumerable(ExecState* exec)
{
JSValue thisValue = exec->hostThisValue();
- return JSValue::encode(jsBoolean(thisValue.toThisObject(exec)->propertyIsEnumerable(exec, Identifier(exec, exec->argument(0).toString(exec)))));
+ return JSValue::encode(jsBoolean(thisValue.toObject(exec)->propertyIsEnumerable(exec, Identifier(exec, exec->argument(0).toString(exec)))));
}
+// 15.2.4.3 Object.prototype.toLocaleString()
EncodedJSValue JSC_HOST_CALL objectProtoFuncToLocaleString(ExecState* exec)
{
- JSValue thisValue = exec->hostThisValue();
- return JSValue::encode(thisValue.toThisJSString(exec));
+ // 1. Let O be the result of calling ToObject passing the this value as the argument.
+ JSObject* object = exec->hostThisValue().toObject(exec);
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
+
+ // 2. Let toString be the result of calling the [[Get]] internal method of O passing "toString" as the argument.
+ JSValue toString = object->get(exec, exec->propertyNames().toString);
+
+ // 3. If IsCallable(toString) is false, throw a TypeError exception.
+ CallData callData;
+ CallType callType = getCallData(toString, callData);
+ if (callType == CallTypeNone)
+ return JSValue::encode(jsUndefined());
+
+ // 4. Return the result of calling the [[Call]] internal method of toString passing O as the this value and no arguments.
+ return JSValue::encode(call(exec, toString, callType, callData, object, exec->emptyList()));
}
EncodedJSValue JSC_HOST_CALL objectProtoFuncToString(ExecState* exec)
{
JSValue thisValue = exec->hostThisValue();
- return JSValue::encode(jsMakeNontrivialString(exec, "[object ", thisValue.toThisObject(exec)->className(), "]"));
+ return JSValue::encode(jsMakeNontrivialString(exec, "[object ", thisValue.toObject(exec)->className(), "]"));
}
} // namespace JSC