Skip to content

Commit cb711ae

Browse files
committed
Remove downward lookup when searching in prototype chain in for...in
1 parent bc52eb0 commit cb711ae

2 files changed

Lines changed: 6 additions & 35 deletions

File tree

lib/Runtime/Library/ForInObjectEnumerator.cpp

Lines changed: 5 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,11 @@ namespace Js
1111
ForInObjectEnumerator::ShadowData::ShadowData(
1212
RecyclableObject * initObject,
1313
RecyclableObject * firstPrototype,
14-
RecyclableObject * firstPrototypeWithEnumerableProperties,
1514
Recycler * recycler)
1615
: currentObject(initObject),
1716
firstPrototype(firstPrototype),
18-
firstPrototypeWithEnumerableProperties(firstPrototypeWithEnumerableProperties),
1917
propertyIds(recycler)
2018
{
21-
2219
}
2320

2421
ForInObjectEnumerator::ForInObjectEnumerator(RecyclableObject* object, ScriptContext * scriptContext, bool enumSymbols)
@@ -53,9 +50,10 @@ namespace Js
5350
if (firstPrototypeWithEnumerableProperties != nullptr)
5451
{
5552
Recycler *recycler = requestContext->GetRecycler();
56-
this->shadowData = RecyclerNew(recycler, ShadowData, initObject, firstPrototype, firstPrototypeWithEnumerableProperties, recycler);
53+
this->shadowData = RecyclerNew(recycler, ShadowData, initObject, firstPrototype, recycler);
5754
flags = EnumeratorFlags::UseCache | EnumeratorFlags::SnapShotSemantics | EnumeratorFlags::EnumNonEnumerable | (enumSymbols ? EnumeratorFlags::EnumSymbols : EnumeratorFlags::None);
5855
}
56+
// no enumerable properties in the prototype chain, no need to search it
5957
else
6058
{
6159
this->shadowData = nullptr;
@@ -203,36 +201,10 @@ namespace Js
203201
}
204202
}
205203

206-
//check for shadowed property
207204
if (TestAndSetEnumerated(propertyId) //checks if the property is already enumerated or not
208205
&& (attributes & PropertyEnumerable))
209206
{
210-
bool propertyShadowed = false;
211-
212-
if (this->enumeratingPrototype)
213-
{
214-
// prototype checking begins from the first prototype object with enumerable properties,
215-
// but the property could be shadowed by a desendant prototype which has the same property but not enumerable.
216-
// Need to check that because that is ignored from the begining.
217-
RecyclableObject * prototypeObject = this->shadowData->firstPrototype;
218-
219-
while (prototypeObject != nullptr && prototypeObject != this->shadowData->currentObject)
220-
{
221-
if (prototypeObject->HasProperty(propertyId))
222-
{
223-
propertyShadowed = true;
224-
break;
225-
}
226-
prototypeObject = prototypeObject->GetPrototype();
227-
228-
Assert(prototypeObject != nullptr);
229-
}
230-
}
231-
232-
if (!propertyShadowed)
233-
{
234-
return currentIndex;
235-
}
207+
return currentIndex;
236208
}
237209
}
238210
else
@@ -244,10 +216,10 @@ namespace Js
244216
}
245217

246218
RecyclableObject * object;
247-
if (!enumeratingPrototype)
219+
if (!this->enumeratingPrototype)
248220
{
249221
this->enumeratingPrototype = true;
250-
object = this->shadowData->firstPrototypeWithEnumerableProperties;
222+
object = this->shadowData->firstPrototype;
251223
this->shadowData->currentObject = object;
252224
}
253225
else

lib/Runtime/Library/ForInObjectEnumerator.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,9 @@ namespace Js
1212
JavascriptStaticEnumerator enumerator;
1313
struct ShadowData
1414
{
15-
ShadowData(RecyclableObject * initObject, RecyclableObject * firstPrototype, RecyclableObject * firstPrototypeWithEnumerableProperties, Recycler * recycler);
15+
ShadowData(RecyclableObject * initObject, RecyclableObject * firstPrototype, Recycler * recycler);
1616
RecyclableObject * currentObject;
1717
RecyclableObject * firstPrototype;
18-
RecyclableObject * firstPrototypeWithEnumerableProperties;
1918
BVSparse<Recycler> propertyIds;
2019
SListBase<Js::PropertyRecord const *> newPropertyStrings;
2120
} *shadowData;

0 commit comments

Comments
 (0)