| Summary: | operationHasEnumerableIndexedProperty in DFGSpeculativeJIT::compileEnumeratorNextUpdateIndexAndMode may destroy IndexGPR | ||
|---|---|---|---|
| Product: | WebKit | Reporter: | ChristineWillice <ChristineWillice> |
| Component: | JavaScriptCore | Assignee: | Nobody <webkit-unassigned> |
| Status: | NEW --- | ||
| Severity: | Normal | CC: | keith_miller, mark.lam, webkit-bug-importer, ysuzuki |
| Priority: | P2 | Keywords: | InRadar |
| Version: | WebKit Nightly Build | ||
| Hardware: | PC | ||
| OS: | Linux | ||
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.