Skip to content

Commit

Permalink
[JSC] PropertyCondition::isValidValueForAttributes should handle cust…
Browse files Browse the repository at this point in the history
…om accessor and custom value

https://bugs.webkit.org/show_bug.cgi?id=266695
rdar://119854137

Reviewed by Mark Lam.

PropertyCondition::isValidValueForAttributes only handled accessors and values. And it
didn't handle custom accessor / custom values. This patch changes it so that we can
check custom accessor / custom value cases correctly.

* JSTests/stress/attribute-custom-accessor.js: Added.
(async asyncSleep):
(setHasBeenDictionary):
(watchToJSONForReplacements):
(async watchLastMatchForReplacements.getLastMatch):
(async watchLastMatchForReplacements):
(const.target.toJSON):
(opt):
(async main):
* Source/JavaScriptCore/bytecode/PropertyCondition.cpp:
(JSC::PropertyCondition::isValidValueForAttributes):

Originally-landed-as: 272448.6@safari-7618-branch (24d1c08). rdar://124557469
Canonical link: https://commits.webkit.org/276183@main
  • Loading branch information
Constellation authored and robert-jenner committed Mar 15, 2024
1 parent 1863491 commit f6f7015
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 3 deletions.
87 changes: 87 additions & 0 deletions JSTests/stress/attribute-custom-accessor.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
async function asyncSleep(ms) {
return new Promise(resolve => {
setTimeout(() => {
resolve();
}, ms);
});
}

function reifyAllStaticProperties(object) {
Object.assign({}, object);
}

function setHasBeenDictionary(object) {
for (let i = 0; i < 100; i++) {
object.b = 1;
delete object.b;
}

for (const x in Object.create(object)) {

}
}

function watchToJSONForReplacements(object) {
JSON.stringify(Object.create(object));
}

async function watchLastMatchForReplacements(object) {
const tmp = Object.create(object);
function getLastMatch() {
return tmp.lastMatch;
}

for (let i = 0; i < 2000; i++) {
try {
getLastMatch();
} catch {

}
}

await asyncSleep(500);
}

const target = {
toJSON: (() => {
const object = {};
for (let i = 0; i < 10; i++) {
object['a' + i] = 1;
}

object.lastMatch = 0x8888;

return object;
})()
};

function opt() {
return target.toJSON.lastMatch;
}

async function main() {
setHasBeenDictionary(target);

reifyAllStaticProperties(RegExp);
await watchLastMatchForReplacements(RegExp);

for (let i = 0; i < 2000; i++) {
opt();
}

await asyncSleep(200);

target.toJSON = RegExp;
target.b = 1;

watchToJSONForReplacements(target);

await asyncSleep(1000);

const custom_getter_setter = opt();
describe(custom_getter_setter);

custom_getter_setter.x = 1;
}

main();
8 changes: 5 additions & 3 deletions Source/JavaScriptCore/bytecode/PropertyCondition.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -495,9 +495,11 @@ bool PropertyCondition::isValidValueForAttributes(JSValue value, unsigned attrib
{
if (!value)
return false;
bool attributesClaimAccessor = !!(attributes & PropertyAttribute::Accessor);
bool valueClaimsAccessor = !!jsDynamicCast<GetterSetter*>(value);
return attributesClaimAccessor == valueClaimsAccessor;
if (value.inherits<GetterSetter>())
return attributes & PropertyAttribute::Accessor;
if (value.inherits<CustomGetterSetter>())
return attributes & PropertyAttribute::CustomAccessorOrValue;
return !(attributes & PropertyAttribute::AccessorOrCustomAccessorOrValue);
}

bool PropertyCondition::isValidValueForPresence(JSValue value) const
Expand Down

0 comments on commit f6f7015

Please sign in to comment.