Bug 258518 - operationHasEnumerableIndexedProperty in DFGSpeculativeJIT::compileEnumeratorNextUpdateIndexAndMode may destroy IndexGPR
Summary: operationHasEnumerableIndexedProperty in DFGSpeculativeJIT::compileEnumerator...
Status: NEW
Alias: None
Product: WebKit
Classification: Unclassified
Component: JavaScriptCore (show other bugs)
Version: WebKit Nightly Build
Hardware: PC Linux
: P2 Normal
Assignee: Nobody
URL:
Keywords: InRadar
Depends on:
Blocks:
 
Reported: 2023-06-26 06:03 PDT by ChristineWillice
Modified: 2023-06-26 12:57 PDT (History)
4 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description ChristineWillice 2023-06-26 06:03:46 PDT
Hello, I found a bug in JavaScriptCore(commitid: 269f0e8b5e51910decd0f6d55a87bac7f5ec4eb8) on Linux.

`````````test.js``````````
for (let v0 = 0; v0 < 98; v0++) {
  const v2 = new WeakSet();
  function f3() {
    v2;
  }
  function f6(a7, a8) {
    return a7;
  }
  const v4 = [v0];
  for (const v5 in v4) {
    print(v0)
    try {
      f6(v5, ...v4);
    } catch (e19) {}
    let v59 = 1;
    const v60 = v59.toLocaleString();
    Math.__proto__ = [1000.0];
    v59 &&= Math;
    const v62 = [v60, 1000];
    v62.join(",");
    const v12 = new Proxy(v4, {});
    v4.__proto__ = v12;
    [,v64] = "test";
    v64
  }
}

``````````````````````````

Run args: ./jsc -f test.js --useConcurrentJIT=0 --jitPolicyScale=0.01 --useFTLJIT=0

In latest version, JSC does not crash. The correct output should print 0-97, but JSC only prints 0-1. In old version, JSC may crash.

I have analyzed this bug preliminarily and found some strange behaviors. This bug is related to for-in. In DFG, EnumeratorNextUpdateIndexAndMode and EnumeratorNextUpdatePropertyName is two nodes from for-in. When compiling EnumeratorNextUpdateIndexAndMode in DFGSpeculativeJIT.cpp, `index` is recorded in `newIndexGPR` which is $r8 when running in my machine. When run the JITTed code, EnumeratorNextUpdateIndexAndMode will invoke slowPath  operationHasEnumerableIndexProperty and enter JSObject::hasEnumerableProperty. JSObject::hasEnumerableProperty will invoke JSObject::getPropertySlot. In JSObject::getPropertySlot, JSC will invoke DECLARE_THROW_SCOPE(vm), this operation will directly modify $r8. In my machine, $r8 is modified into 0x72.
In EnumberatorNextUpdatePropertyName, index has already become 0x72, which is bigger than length (1), so the iteration is terminated early and does not print v0 any more. I feel strange about this behavior. Should newIndexGPR be saved before modification?

I have minimize test.js in my best, but test.js is still long.
Comment 1 Radar WebKit Bug Importer 2023-06-26 12:57:04 PDT
<rdar://problem/111344221>