Bug 197631

Summary: [JSC] Strict, Sloppy and Arrow functions should have different classInfo
Product: WebKit Reporter: Robin Morisset <rmorisset>
Component: JavaScriptCoreAssignee: Yusuke Suzuki <ysuzuki>
Status: RESOLVED FIXED    
Severity: Normal CC: ews-watchlist, fpizlo, keith_miller, mark.lam, msaboff, saam, tzagallo, webkit-bug-importer, ysuzuki
Priority: P2 Keywords: InRadar
Version: WebKit Nightly Build   
Hardware: Unspecified   
OS: Unspecified   
Attachments:
Description Flags
Patch
none
Patch
none
Patch saam: review+

Description Robin Morisset 2019-05-06 15:15:37 PDT
'arguments' behave differently in sloppy and strict mode. So if we cache HasOwnProperty('arguments') in strict mode, then try to call it again in sloppy mode (or vice-versa) the result will be wrong.
The simplest solution is just not to ever cache HasOwnProperty('arguments').
Adding a bit for sloppy/strict in the keys would also work, but it would complicate things for the common case, and I don't expect HasOwnProperty('arguments') to be super common.
Comment 1 Robin Morisset 2019-05-06 15:15:59 PDT
rdar://problem/50202206
Comment 2 Robin Morisset 2019-05-06 15:21:36 PDT
Created attachment 369178 [details]
Patch
Comment 3 Saam Barati 2019-05-06 15:28:44 PDT
(In reply to Robin Morisset from comment #0)
> 'arguments' behave differently in sloppy and strict mode. So if we cache
> HasOwnProperty('arguments') in strict mode, then try to call it again in
> sloppy mode (or vice-versa) the result will be wrong.
> The simplest solution is just not to ever cache HasOwnProperty('arguments').
> Adding a bit for sloppy/strict in the keys would also work, but it would
> complicate things for the common case, and I don't expect
> HasOwnProperty('arguments') to be super common.

Why don't these have different structures?
Comment 4 Saam Barati 2019-05-06 15:30:57 PDT
Comment on attachment 369178 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=369178&action=review

> JSTests/stress/has-own-property-arguments.js:3
> +class A extends Function {}
> +new A("'use strict';").hasOwnProperty('arguments');
> +new A().hasOwnProperty('arguments');

I'm super confused what this is doing. This is just calling the constructor with a string as the first argument.

Also, classes are always in strict mode. Can you explain what's going on? Can this also test what it expects the results to be?

> Source/JavaScriptCore/runtime/HasOwnPropertyCache.h:95
> +        // We don't cache accesses to arguments, because it depends on whether we are in strict or sloppy mode.
> +        if (propName == "arguments")
> +            return;

This seems wrong. We should be reflecting this in Structure. It's unlikely the bug is just here and not also in Get
Comment 5 Filip Pizlo 2019-06-04 10:49:41 PDT
(In reply to Robin Morisset from comment #0)
> 'arguments' behave differently in sloppy and strict mode. So if we cache
> HasOwnProperty('arguments') in strict mode, then try to call it again in
> sloppy mode (or vice-versa) the result will be wrong.
> The simplest solution is just not to ever cache HasOwnProperty('arguments').
> Adding a bit for sloppy/strict in the keys would also work, but it would
> complicate things for the common case, and I don't expect
> HasOwnProperty('arguments') to be super common.

Why wouldn't the sloppy-strict change be caught by the cache?

A function can't change its mind about whether it is strict or sloppy.  Is the issue that function objects for strict functions have the same structure as function objects for sloppy functions?
Comment 6 Yusuke Suzuki 2019-06-21 20:03:23 PDT
Function constructor should pick a correct structure, I think this is the issue.
Comment 7 Yusuke Suzuki 2019-06-21 20:04:25 PDT
(In reply to Yusuke Suzuki from comment #6)
> Function constructor should pick a correct structure, I think this is the
> issue.

Ah, no. Investigating
Comment 8 Yusuke Suzuki 2019-06-21 20:08:31 PDT
(In reply to Yusuke Suzuki from comment #7)
> (In reply to Yusuke Suzuki from comment #6)
> > Function constructor should pick a correct structure, I think this is the
> > issue.
> 
> Ah, no. Investigating

The issue is that InternalFunction::createSubclassStructureSlow caches the structure, and when using the previous structure, we are assuming that "If classInfo is the same, we should reuse the cached one". This is wrong for this case.
Comment 9 Yusuke Suzuki 2019-06-21 21:58:40 PDT
Created attachment 372671 [details]
Patch
Comment 10 Yusuke Suzuki 2019-06-21 22:00:49 PDT
Created attachment 372672 [details]
Patch
Comment 11 Saam Barati 2019-06-21 22:38:48 PDT
Comment on attachment 372672 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=372672&action=review

r=me

> JSTests/stress/has-own-property-arguments.js:8
> +shouldBe(new A().hasOwnProperty('arguments'), true);

Can you also add tests that would break get by id inline caching?
Comment 12 Yusuke Suzuki 2019-06-22 00:12:50 PDT
Comment on attachment 372672 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=372672&action=review

Thanks!

>> JSTests/stress/has-own-property-arguments.js:8
>> +shouldBe(new A().hasOwnProperty('arguments'), true);
> 
> Can you also add tests that would break get by id inline caching?

Sure! Added.
Comment 13 Yusuke Suzuki 2019-06-22 00:48:12 PDT
Committed r246709: <https://trac.webkit.org/changeset/246709>