- Revision
- 148142
- Author
- mhahnenb...@apple.com
- Date
- 2013-04-10 15:25:36 -0700 (Wed, 10 Apr 2013)
Log Message
JSObject::getOwnNonIndexPropertyNames calculates numCacheableSlots incorrectly
https://bugs.webkit.org/show_bug.cgi?id=114235
Reviewed by Filip Pizlo.
If the object doesn't have any properties but the prototype does, we'll assume those prototype properties are
accessible in the base object's backing store, which is bad.
Source/_javascript_Core:
* runtime/JSObject.cpp:
(JSC::JSObject::getPropertyNames):
(JSC::JSObject::getOwnNonIndexPropertyNames):
* runtime/PropertyNameArray.h:
(JSC::PropertyNameArray::PropertyNameArray):
(JSC::PropertyNameArray::setNumCacheableSlotsForObject):
(JSC::PropertyNameArray::setBaseObject):
(PropertyNameArray):
LayoutTests:
* fast/js/get-by-pname-only-prototype-properties-expected.txt: Added.
* fast/js/get-by-pname-only-prototype-properties.html: Added.
* fast/js/script-tests/get-by-pname-only-prototype-properties.js: Added.
(foo):
Modified Paths
Added Paths
Diff
Modified: trunk/LayoutTests/ChangeLog (148141 => 148142)
--- trunk/LayoutTests/ChangeLog 2013-04-10 22:18:49 UTC (rev 148141)
+++ trunk/LayoutTests/ChangeLog 2013-04-10 22:25:36 UTC (rev 148142)
@@ -1,3 +1,18 @@
+2013-04-10 Mark Hahnenberg <mhahnenb...@apple.com>
+
+ JSObject::getOwnNonIndexPropertyNames calculates numCacheableSlots incorrectly
+ https://bugs.webkit.org/show_bug.cgi?id=114235
+
+ Reviewed by Filip Pizlo.
+
+ If the object doesn't have any properties but the prototype does, we'll assume those prototype properties are
+ accessible in the base object's backing store, which is bad.
+
+ * fast/js/get-by-pname-only-prototype-properties-expected.txt: Added.
+ * fast/js/get-by-pname-only-prototype-properties.html: Added.
+ * fast/js/script-tests/get-by-pname-only-prototype-properties.js: Added.
+ (foo):
+
2013-04-10 Hans Muller <hmul...@adobe.com>
[CSS Exclusions] Zoom causes shape-inside to fail when shape-padding is specified
Added: trunk/LayoutTests/fast/js/get-by-pname-only-prototype-properties-expected.txt (0 => 148142)
--- trunk/LayoutTests/fast/js/get-by-pname-only-prototype-properties-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/js/get-by-pname-only-prototype-properties-expected.txt 2013-04-10 22:25:36 UTC (rev 148142)
@@ -0,0 +1,9 @@
+This tests that get_by_pname doesn't incorrectly think that an empty object can cache its prototype's properties.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/fast/js/get-by-pname-only-prototype-properties.html (0 => 148142)
--- trunk/LayoutTests/fast/js/get-by-pname-only-prototype-properties.html (rev 0)
+++ trunk/LayoutTests/fast/js/get-by-pname-only-prototype-properties.html 2013-04-10 22:25:36 UTC (rev 148142)
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<script src=""
+<script src=""
+</body>
+</html>
Added: trunk/LayoutTests/fast/js/script-tests/get-by-pname-only-prototype-properties.js (0 => 148142)
--- trunk/LayoutTests/fast/js/script-tests/get-by-pname-only-prototype-properties.js (rev 0)
+++ trunk/LayoutTests/fast/js/script-tests/get-by-pname-only-prototype-properties.js 2013-04-10 22:25:36 UTC (rev 148142)
@@ -0,0 +1,54 @@
+description(
+"This tests that get_by_pname doesn't incorrectly think that an empty object can cache its prototype's properties."
+);
+
+var foo = function (C, A) {
+ for(var B in (A||{})) {
+ C[B]=A[B];
+ }
+ return C;
+}
+
+var protos = [];
+for (var i = 0; i < 256; i++) {
+ var proto = Object.create(null);
+ protos.push(proto);
+ proto.aa = 1;
+ proto.ab = 1;
+ proto.ac = 1;
+ proto.ad = 1;
+ proto.ae = 1;
+ proto.af = 1;
+ proto.ag = 1;
+ proto.ah = 1;
+ proto.ai = 1;
+ proto.aj = 1;
+ proto.ak = 1;
+ proto.al = 1;
+ proto.am = 1;
+ proto.an = 1;
+ proto.ao = 1;
+ proto.ap = 1;
+ proto.aq = 1;
+ proto.ar = 1;
+ proto.as = 1;
+ proto.at = 1;
+ proto.au = 1;
+ proto.av = 1;
+ proto.aw = 1;
+ proto.ax = 1;
+ proto.ay = 1;
+ proto.az = 1;
+ proto.ba = 1;
+ proto.bb = 1;
+ proto.bc = 1;
+ proto.bd = 1;
+ proto.be = 1;
+ proto.bf = 1;
+ var weirdObject = Object.create(proto);
+ var result = foo({}, weirdObject);
+ for (var p in result) {
+ if (result[p] !== result["" + p])
+ shouldBe("result[p]", "result[\"\" + p]");
+ }
+}
Modified: trunk/Source/_javascript_Core/ChangeLog (148141 => 148142)
--- trunk/Source/_javascript_Core/ChangeLog 2013-04-10 22:18:49 UTC (rev 148141)
+++ trunk/Source/_javascript_Core/ChangeLog 2013-04-10 22:25:36 UTC (rev 148142)
@@ -1,3 +1,22 @@
+2013-04-10 Mark Hahnenberg <mhahnenb...@apple.com>
+
+ JSObject::getOwnNonIndexPropertyNames calculates numCacheableSlots incorrectly
+ https://bugs.webkit.org/show_bug.cgi?id=114235
+
+ Reviewed by Filip Pizlo.
+
+ If the object doesn't have any properties but the prototype does, we'll assume those prototype properties are
+ accessible in the base object's backing store, which is bad.
+
+ * runtime/JSObject.cpp:
+ (JSC::JSObject::getPropertyNames):
+ (JSC::JSObject::getOwnNonIndexPropertyNames):
+ * runtime/PropertyNameArray.h:
+ (JSC::PropertyNameArray::PropertyNameArray):
+ (JSC::PropertyNameArray::setNumCacheableSlotsForObject):
+ (JSC::PropertyNameArray::setBaseObject):
+ (PropertyNameArray):
+
2013-04-10 Patrick Gansterer <par...@webkit.org>
Remove code duplicates from MacroAssemblerARM
Modified: trunk/Source/_javascript_Core/runtime/JSObject.cpp (148141 => 148142)
--- trunk/Source/_javascript_Core/runtime/JSObject.cpp 2013-04-10 22:18:49 UTC (rev 148141)
+++ trunk/Source/_javascript_Core/runtime/JSObject.cpp 2013-04-10 22:25:36 UTC (rev 148142)
@@ -1442,6 +1442,7 @@
void JSObject::getPropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
{
+ propertyNames.setBaseObject(object);
object->methodTable()->getOwnPropertyNames(object, exec, propertyNames, mode);
if (object->prototype().isNull())
@@ -1537,7 +1538,7 @@
object->structure()->getPropertyNamesFromStructure(exec->globalData(), propertyNames, mode);
if (canCachePropertiesFromStructure)
- propertyNames.setNumCacheableSlots(propertyNames.size());
+ propertyNames.setNumCacheableSlotsForObject(object, propertyNames.size());
}
double JSObject::toNumber(ExecState* exec) const
Modified: trunk/Source/_javascript_Core/runtime/PropertyNameArray.h (148141 => 148142)
--- trunk/Source/_javascript_Core/runtime/PropertyNameArray.h 2013-04-10 22:18:49 UTC (rev 148141)
+++ trunk/Source/_javascript_Core/runtime/PropertyNameArray.h 2013-04-10 22:25:36 UTC (rev 148142)
@@ -56,6 +56,7 @@
: m_data(PropertyNameArrayData::create())
, m_globalData(globalData)
, m_numCacheableSlots(0)
+ , m_baseObject(0)
{
}
@@ -63,6 +64,7 @@
: m_data(PropertyNameArrayData::create())
, m_globalData(&exec->globalData())
, m_numCacheableSlots(0)
+ , m_baseObject(0)
{
}
@@ -86,7 +88,18 @@
const_iterator end() const { return m_data->propertyNameVector().end(); }
size_t numCacheableSlots() const { return m_numCacheableSlots; }
- void setNumCacheableSlots(size_t numCacheableSlots) { m_numCacheableSlots = numCacheableSlots; }
+ void setNumCacheableSlotsForObject(JSObject* object, size_t numCacheableSlots)
+ {
+ if (object != m_baseObject)
+ return;
+ m_numCacheableSlots = numCacheableSlots;
+ }
+ void setBaseObject(JSObject* object)
+ {
+ if (m_baseObject)
+ return;
+ m_baseObject = object;
+ }
private:
typedef HashSet<StringImpl*, PtrHash<StringImpl*> > IdentifierSet;
@@ -95,6 +108,7 @@
IdentifierSet m_set;
JSGlobalData* m_globalData;
size_t m_numCacheableSlots;
+ JSObject* m_baseObject;
};
} // namespace JSC