Commit e871bc0b authored by oliver@apple.com's avatar oliver@apple.com

getPropertyNames caching is invalid when the prototype chain contains objects...

getPropertyNames caching is invalid when the prototype chain contains objects with custom getPropertyNames
https://bugs.webkit.org/show_bug.cgi?id=29214

Reviewed by Sam Weinig.

Add a flag to TypeInfo to indicate whether a type overrides getPropertyNames.
This flag is used to make sure that caching of the property name data is safe.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@48331 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 2380be8b
......@@ -41,7 +41,7 @@ public:
static PassRefPtr<Structure> createStructure(JSValue proto)
{
return Structure::create(proto, TypeInfo(ObjectType, ImplementsHasInstance | HasStandardGetOwnPropertySlot | HasDefaultMark));
return Structure::create(proto, TypeInfo(ObjectType, ImplementsHasInstance | HasStandardGetOwnPropertySlot | HasDefaultMark | HasDefaultGetPropertyNames));
}
private:
......
2009-09-11 Oliver Hunt <oliver@apple.com>
Reviewed by Sam Weinig.
getPropertyNames caching is invalid when the prototype chain contains objects with custom getPropertyNames
https://bugs.webkit.org/show_bug.cgi?id=29214
Add a flag to TypeInfo to indicate whether a type overrides getPropertyNames.
This flag is used to make sure that caching of the property name data is safe.
* API/JSCallbackConstructor.h:
(JSC::JSCallbackConstructor::createStructure):
* debugger/DebuggerActivation.h:
(JSC::DebuggerActivation::createStructure):
* runtime/BooleanObject.h:
(JSC::BooleanObject::createStructure):
* runtime/DatePrototype.h:
(JSC::DatePrototype::createStructure):
* runtime/FunctionPrototype.h:
(JSC::FunctionPrototype::createStructure):
* runtime/JSONObject.h:
(JSC::JSONObject::createStructure):
* runtime/JSObject.h:
(JSC::JSObject::createStructure):
* runtime/JSTypeInfo.h:
(JSC::TypeInfo::hasDefaultGetPropertyNames):
* runtime/JSVariableObject.h:
(JSC::JSVariableObject::createStructure):
* runtime/JSWrapperObject.h:
(JSC::JSWrapperObject::createStructure):
* runtime/MathObject.h:
(JSC::MathObject::createStructure):
* runtime/NumberConstructor.h:
(JSC::NumberConstructor::createStructure):
* runtime/NumberObject.h:
(JSC::NumberObject::createStructure):
* runtime/RegExpConstructor.h:
(JSC::RegExpConstructor::createStructure):
* runtime/RegExpObject.h:
(JSC::RegExpObject::createStructure):
* runtime/StructureChain.cpp:
(JSC::StructureChain::isCacheable):
2009-09-11 Alexey Proskuryakov <ap@webkit.org>
Reviewed by Geoff Garen.
......
......@@ -51,7 +51,7 @@ namespace JSC {
static PassRefPtr<Structure> createStructure(JSValue prototype)
{
return Structure::create(prototype, TypeInfo(ObjectType));
return Structure::create(prototype, TypeInfo(ObjectType, HasDefaultGetPropertyNames));
}
private:
......
......@@ -34,7 +34,7 @@ namespace JSC {
static PassRefPtr<Structure> createStructure(JSValue prototype)
{
return Structure::create(prototype, TypeInfo(ObjectType, HasStandardGetOwnPropertySlot | HasDefaultMark));
return Structure::create(prototype, TypeInfo(ObjectType, HasStandardGetOwnPropertySlot | HasDefaultMark | HasDefaultGetPropertyNames));
}
};
......
......@@ -39,7 +39,7 @@ namespace JSC {
static PassRefPtr<Structure> createStructure(JSValue prototype)
{
return Structure::create(prototype, TypeInfo(ObjectType));
return Structure::create(prototype, TypeInfo(ObjectType, HasDefaultGetPropertyNames));
}
};
......
......@@ -34,7 +34,7 @@ namespace JSC {
static PassRefPtr<Structure> createStructure(JSValue proto)
{
return Structure::create(proto, TypeInfo(ObjectType, HasStandardGetOwnPropertySlot | HasDefaultMark));
return Structure::create(proto, TypeInfo(ObjectType, HasStandardGetOwnPropertySlot | HasDefaultMark | HasDefaultGetPropertyNames));
}
private:
......
......@@ -41,7 +41,7 @@ namespace JSC {
static PassRefPtr<Structure> createStructure(JSValue prototype)
{
return Structure::create(prototype, TypeInfo(ObjectType, HasDefaultMark));
return Structure::create(prototype, TypeInfo(ObjectType, HasDefaultMark | HasDefaultGetPropertyNames));
}
static void markStringifiers(MarkStack&, Stringifier*);
......
......@@ -205,7 +205,7 @@ namespace JSC {
static PassRefPtr<Structure> createStructure(JSValue prototype)
{
return Structure::create(prototype, TypeInfo(ObjectType, HasStandardGetOwnPropertySlot | HasDefaultMark));
return Structure::create(prototype, TypeInfo(ObjectType, HasStandardGetOwnPropertySlot | HasDefaultMark | HasDefaultGetPropertyNames));
}
private:
......
......@@ -42,6 +42,7 @@ namespace JSC {
static const unsigned NeedsThisConversion = 1 << 4;
static const unsigned HasStandardGetOwnPropertySlot = 1 << 5;
static const unsigned HasDefaultMark = 1 << 6;
static const unsigned HasDefaultGetPropertyNames = 1 << 7;
class TypeInfo {
friend class JIT;
......@@ -64,6 +65,7 @@ namespace JSC {
bool needsThisConversion() const { return m_flags & NeedsThisConversion; }
bool hasStandardGetOwnPropertySlot() const { return m_flags & HasStandardGetOwnPropertySlot; }
bool hasDefaultMark() const { return m_flags & HasDefaultMark; }
bool hasDefaultGetPropertyNames() const { return m_flags & HasDefaultGetPropertyNames; }
unsigned flags() const { return m_flags; }
private:
......
......@@ -58,6 +58,11 @@ namespace JSC {
Register& registerAt(int index) const { return d->registers[index]; }
static PassRefPtr<Structure> createStructure(JSValue prototype)
{
return Structure::create(prototype, TypeInfo(ObjectType, HasStandardGetOwnPropertySlot | HasDefaultMark));
}
protected:
// Subclasses of JSVariableObject can subclass this struct to add data
// without increasing their own size (since there's a hard limit on the
......
......@@ -38,7 +38,7 @@ namespace JSC {
static PassRefPtr<Structure> createStructure(JSValue prototype)
{
return Structure::create(prototype, TypeInfo(ObjectType, HasStandardGetOwnPropertySlot));
return Structure::create(prototype, TypeInfo(ObjectType, HasStandardGetOwnPropertySlot | HasDefaultGetPropertyNames));
}
private:
......
......@@ -37,7 +37,7 @@ namespace JSC {
static PassRefPtr<Structure> createStructure(JSValue prototype)
{
return Structure::create(prototype, TypeInfo(ObjectType, HasDefaultMark));
return Structure::create(prototype, TypeInfo(ObjectType, HasDefaultMark | HasDefaultGetPropertyNames));
}
};
......
......@@ -39,7 +39,7 @@ namespace JSC {
static PassRefPtr<Structure> createStructure(JSValue proto)
{
return Structure::create(proto, TypeInfo(ObjectType, ImplementsHasInstance | HasDefaultMark));
return Structure::create(proto, TypeInfo(ObjectType, ImplementsHasInstance | HasDefaultMark | HasDefaultGetPropertyNames));
}
enum { NaNValue, NegInfinity, PosInfinity, MaxValue, MinValue };
......
......@@ -33,12 +33,12 @@ namespace JSC {
#if USE(JSVALUE32)
static PassRefPtr<Structure> createStructure(JSValue prototype)
{
return Structure::create(prototype, TypeInfo(ObjectType, HasStandardGetOwnPropertySlot));
return Structure::create(prototype, TypeInfo(ObjectType, HasStandardGetOwnPropertySlot | HasDefaultGetPropertyNames));
}
#else
static PassRefPtr<Structure> createStructure(JSValue prototype)
{
return Structure::create(prototype, TypeInfo(ObjectType, HasStandardGetOwnPropertySlot | HasDefaultMark));
return Structure::create(prototype, TypeInfo(ObjectType, HasStandardGetOwnPropertySlot | HasDefaultMark | HasDefaultGetPropertyNames));
}
#endif
private:
......
......@@ -36,7 +36,7 @@ namespace JSC {
static PassRefPtr<Structure> createStructure(JSValue prototype)
{
return Structure::create(prototype, TypeInfo(ObjectType, ImplementsHasInstance | HasDefaultMark));
return Structure::create(prototype, TypeInfo(ObjectType, ImplementsHasInstance | HasDefaultMark | HasDefaultGetPropertyNames));
}
virtual void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&);
......
......@@ -49,7 +49,7 @@ namespace JSC {
static PassRefPtr<Structure> createStructure(JSValue prototype)
{
return Structure::create(prototype, TypeInfo(ObjectType, HasDefaultMark));
return Structure::create(prototype, TypeInfo(ObjectType, HasDefaultMark | HasDefaultGetPropertyNames));
}
private:
......
......@@ -51,7 +51,9 @@ bool StructureChain::isCacheable() const
uint32_t i = 0;
while (m_vector[i]) {
if (m_vector[i++]->isDictionary())
if (m_vector[i]->isDictionary())
return false;
if (!m_vector[i++]->typeInfo().hasDefaultGetPropertyNames())
return false;
}
return true;
......
2009-09-11 Oliver Hunt <oliver@apple.com>
Reviewed by Sam Weinig.
getPropertyNames caching is invalid when the prototype chain contains objects with custom getPropertyNames
https://bugs.webkit.org/show_bug.cgi?id=29214
Add test case for for-in caching.
* fast/js/for-in-cached-expected.txt:
* fast/js/resources/for-in-cached.js:
(forIn4):
2009-09-10 Chris Fleizach <cfleizach@apple.com>
Reviewed by Darin Adler.
......
......@@ -8,6 +8,8 @@ PASS forIn2() is ['x']
PASS forIn3({ __proto__: { y1: 2 } }) is ['x', 'y1']
PASS forIn3({ y2 : 2, __proto__: null }) is ['x', 'y2']
PASS forIn3({ __proto__: { __proto__: { y3 : 2 } } }) is ['x', 'y3']
PASS forIn4(objectWithArrayAsProto) is []
PASS forIn4(objectWithArrayAsProto) is ['0']
PASS successfullyParsed is true
TEST COMPLETE
......
......@@ -43,4 +43,16 @@ forIn3({ __proto__: { __proto__: { y3 : 2 } } });
forIn3({ __proto__: { __proto__: { y3 : 2 } } });
shouldBe("forIn3({ __proto__: { __proto__: { y3 : 2 } } })", "['x', 'y3']");
function forIn4(o) {
var result = [];
for (var p in o)
result.push(p);
return result;
}
var objectWithArrayAsProto = {};
objectWithArrayAsProto.__proto__ = [];
shouldBe("forIn4(objectWithArrayAsProto)", "[]");
objectWithArrayAsProto.__proto__[0]=1;
shouldBe("forIn4(objectWithArrayAsProto)", "['0']");
var successfullyParsed = true;
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment