Skip to content

Commit 6e4f61e

Browse files
committed
[MERGE #5299 @pleath] OS#17729736: Don't cache missing properties for objects with DictionaryTypeHandler's
Merge pull request #5299 from pleath:17729736 This may leave stale isMissing elements in the TypePropertyCache after the property has been added to the prototype chain.
2 parents 058c1cd + 09b7eaf commit 6e4f61e

File tree

2 files changed

+35
-4
lines changed

2 files changed

+35
-4
lines changed

lib/Runtime/Language/JavascriptOperators.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1806,10 +1806,12 @@ using namespace Js;
18061806

18071807
DynamicTypeHandler* handler = DynamicObject::UnsafeFromVar(instance)->GetDynamicType()->GetTypeHandler();
18081808

1809-
// Only cache missing property lookups for non-root field loads on objects that have PathTypeHandlers and DictionaryTypeHandlers, because only these types have the right behavior
1810-
// when the missing property is later added: path types guarantee a type change, and DictionaryTypeHandlerBase::AddProperty explicitly invalidates all prototype caches for the
1811-
// property. (We don't support other types only because we haven't needed to yet; we do not anticipate any difficulties in adding the cache-invalidation logic there if that changes.)
1812-
if (!handler->IsPathTypeHandler() && !handler->IsDictionaryTypeHandler())
1809+
// Only cache missing property lookups for non-root field loads on objects that have PathTypeHandlers, because only these types have the right behavior
1810+
// when the missing property is later added. DictionaryTypeHandler's introduce the possibility that a stale TypePropertyCache entry with isMissing==true can
1811+
// be left in the cache after the property has been installed in the object's prototype chain. Other changes to optimize accesses to objects that don't
1812+
// override special symbols make it unnecessary to introduce an invalidation scheme to deal with DictionaryTypeHandler's.
1813+
1814+
if (!handler->IsPathTypeHandler())
18131815
{
18141816
return;
18151817
}

test/es6/ES6Proto.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,35 @@ var tests = [
9999
assert.areEqual(p, Object.getPrototypeOf(o), "[[Prototype]] slot of o was changed to p");
100100
}
101101
},
102+
{
103+
name: "__proto__ plus missing property",
104+
body: function () {
105+
function main() {
106+
var l0 = {
107+
a: -1,
108+
b: 0x414141,
109+
};
110+
l0.a = (l0.a) + (l0.a);
111+
112+
l0.y = {};
113+
l0.__defineGetter__('z', function () {
114+
delete l0.a;
115+
return 5;
116+
});
117+
l0.a = (l0.a) - (l0.z);
118+
119+
l0.__proto__ = l0.y;
120+
l0.z = (l0.z) / (l0.a);
121+
var o = {};
122+
o.a = 42;
123+
l0.y.__proto__ = o;
124+
return l0.a;
125+
}
126+
for (var i = 0; i < 20; i++) {
127+
assert.areEqual(42, main(), "Missing property on local instance should be found in prototype chain");
128+
}
129+
}
130+
},
102131
];
103132

104133
testRunner.runTests(tests, { verbose: WScript.Arguments[0] != "summary" });

0 commit comments

Comments
 (0)