diff --git a/JSTests/stress/put-by-id-no-crash-interpreter.js b/JSTests/stress/put-by-id-no-crash-interpreter.js new file mode 100644 index 0000000000000..6e578b230f872 --- /dev/null +++ b/JSTests/stress/put-by-id-no-crash-interpreter.js @@ -0,0 +1,30 @@ +//@ runDefault("--useJIT=0") +const propName = "myProp"; +var d; + +function shouldBe(actual, expected) +{ + if (actual !== expected) + throw new Error("Failure, expected: " + expected + ", got: " + actual); +} + +function createDictionary() +{ + var object = $vm.createObjectDoingSideEffectPutWithoutCorrectSlotStatus(); + object[propName] = 42; + return object; +} + +function putWithSideEffects(o) +{ + o.dummy = { + toString() { + delete d[propName]; + return "foo"; + } + }; +} + +d = createDictionary(); +putWithSideEffects(d); +shouldBe(propName in d, false); diff --git a/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp b/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp index d31f9cde5de29..35264425fbce6 100644 --- a/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp +++ b/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp @@ -992,25 +992,22 @@ LLINT_SLOW_PATH_DECL(slow_path_put_by_id) if (newStructure->propertyAccessesAreCacheable() && baseCell == slot.base()) { if (slot.type() == PutPropertySlot::NewProperty) { GCSafeConcurrentJSLocker locker(codeBlock->m_lock, vm); - if (!newStructure->isDictionary() && newStructure->previousID()->outOfLineCapacity() == newStructure->outOfLineCapacity()) { - ASSERT(oldStructure == newStructure->previousID()); - if (oldStructure == newStructure->previousID()) { - ASSERT(oldStructure->transitionWatchpointSetHasBeenInvalidated()); - - bool sawPolyProto = false; - auto result = normalizePrototypeChain(globalObject, baseCell, sawPolyProto); - if (result != InvalidPrototypeChain && !sawPolyProto) { - ASSERT(oldStructure->isObject()); - metadata.m_oldStructureID = oldStructure->id(); - metadata.m_offset = slot.cachedOffset(); - metadata.m_newStructureID = newStructure->id(); - if (!(bytecode.m_flags.isDirect())) { - StructureChain* chain = newStructure->prototypeChain(vm, globalObject, asObject(baseCell)); - ASSERT(chain); - metadata.m_structureChain.set(vm, codeBlock, chain); - } - vm.writeBarrier(codeBlock); + if (!newStructure->isDictionary() && newStructure->previousID()->outOfLineCapacity() == newStructure->outOfLineCapacity() && newStructure->previousID() == oldStructure) { + ASSERT(oldStructure->transitionWatchpointSetHasBeenInvalidated()); + + bool sawPolyProto = false; + auto result = normalizePrototypeChain(globalObject, baseCell, sawPolyProto); + if (result != InvalidPrototypeChain && !sawPolyProto) { + ASSERT(oldStructure->isObject()); + metadata.m_oldStructureID = oldStructure->id(); + metadata.m_offset = slot.cachedOffset(); + metadata.m_newStructureID = newStructure->id(); + if (!(bytecode.m_flags.isDirect())) { + StructureChain* chain = newStructure->prototypeChain(vm, globalObject, asObject(baseCell)); + ASSERT(chain); + metadata.m_structureChain.set(vm, codeBlock, chain); } + vm.writeBarrier(codeBlock); } } } else {