Skip to content

Commit

Permalink
Cherry-pick 265870.535@safari-7616-branch (049d074). https://bugs.web…
Browse files Browse the repository at this point in the history
…kit.org/show_bug.cgi?id=261287

    JSObject::anyObjectInChainMayInterceptIndexedAccesses and JSObject::didBecomePrototype need to account for JSGlobalProxy
    https://bugs.webkit.org/show_bug.cgi?id=261287
    rdar://114860483

    Reviewed by Yusuke Suzuki.

    Since JSObject::anyObjectInChainMayInterceptIndexedAccesses() walks up the [[Prototype]] chain,
    whenever an indexed property is defined on a JSGlobalObject, we should add MayHaveIndexedAccessors
    flag to JSGlobalProxy instead.

    Currently, mayInterceptIndexedAccesses() is never queried on JSGlobalObject instances.

    This change also fixes mayBePrototype() to be queried from JSGlobalProxy rather than JSGlobalObject,
    which is correct given setPrototypeDirect() used to call didBecomePrototype() only on the proxy.
    However, for extra robustness, this we propagate didBecomePrototype() to the global object as well.

    * JSTests/stress/regress-114860483.js: Added.
    * Source/JavaScriptCore/runtime/JSObjectInlines.h:
    (JSC::JSObject::didBecomePrototype):
    * Source/JavaScriptCore/runtime/JSObject.cpp:
    (JSC::JSObject::notifyPresenceOfIndexedAccessors):

    Canonical link: https://commits.webkit.org/265870.535@safari-7616-branch
  • Loading branch information
Alexey Shvayka authored and aperezdc committed Oct 20, 2023
1 parent e0e6399 commit 62bc9d1
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 0 deletions.
40 changes: 40 additions & 0 deletions JSTests/stress/regress-114860483.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
function assertArgumentsContent() {
const str = [...arguments].join();
if (str !== `,1.1,1.1,1.1,1.1,1.1`)
throw new Error("Bad assertion!");
}

function createClonedArguments() {
return arguments.callee.arguments;
}

function main() {
gc();

const global_proxy = this;
Reflect.defineProperty(global_proxy, 0, {
get() {
for (let i = 100; i < 200; i++)
cloned_arguments[i] = 1.1;

for (let i = 0; i < 100; i++)
cloned_arguments[i] = 1.1;

gc();

// Creating invalid date objects.
for (let i = 0; i < 100; i++) {
new Date('a');
}
}
});

const cloned_arguments = createClonedArguments(null, new Date(), new Date(), new Date(), new Date(), new Date());
delete cloned_arguments[0];

Reflect.setPrototypeOf(cloned_arguments, global_proxy);

assertArgumentsContent.apply(null, cloned_arguments);
}

main();
5 changes: 5 additions & 0 deletions Source/JavaScriptCore/runtime/JSObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1162,6 +1162,11 @@ void JSObject::enterDictionaryIndexingMode(VM& vm)

void JSObject::notifyPresenceOfIndexedAccessors(VM& vm)
{
if (UNLIKELY(isGlobalObject())) {
jsCast<JSGlobalObject*>(this)->globalThis()->notifyPresenceOfIndexedAccessors(vm);
return;
}

if (mayInterceptIndexedAccesses())
return;

Expand Down
3 changes: 3 additions & 0 deletions Source/JavaScriptCore/runtime/JSObjectInlines.h
Original file line number Diff line number Diff line change
Expand Up @@ -508,6 +508,9 @@ inline void JSObject::didBecomePrototype(VM& vm)
DeferredStructureTransitionWatchpointFire deferred(vm, oldStructure);
setStructure(vm, Structure::becomePrototypeTransition(vm, oldStructure, &deferred));
}

if (UNLIKELY(type() == GlobalProxyType))
jsCast<JSGlobalProxy*>(this)->target()->didBecomePrototype(vm);
}

inline bool JSObject::canGetIndexQuicklyForTypedArray(unsigned i) const
Expand Down

0 comments on commit 62bc9d1

Please sign in to comment.