put_by_val_direct need to check the property is index or not for using putDirect / putDirectIndex
https://bugs.webkit.org/show_bug.cgi?id=140426
Reviewed by Darin Adler.
In the put_by_val_direct operation, we use JSObject::putDirect.
However, it only accepts non-index property. For index property, we need to use JSObject::putDirectIndex.
This patch checks toString-ed Identifier is index or not to choose putDirect / putDirectIndex.
* dfg/DFGOperations.cpp:
(JSC::DFG::putByVal):
(JSC::DFG::operationPutByValInternal):
* jit/JITOperations.cpp:
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::LLINT_SLOW_PATH_DECL):
* runtime/Identifier.h:
(JSC::isIndex):
(JSC::parseIndex):
* tests/stress/dfg-put-by-val-direct-with-edge-numbers.js: Added.
(lookupWithKey):
(toStringThrowsError.toString):
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@182452 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/JavaScriptCore/dfg/DFGOperations.cpp b/Source/JavaScriptCore/dfg/DFGOperations.cpp
index a0726c1..ff16903 100644
--- a/Source/JavaScriptCore/dfg/DFGOperations.cpp
+++ b/Source/JavaScriptCore/dfg/DFGOperations.cpp
@@ -69,6 +69,7 @@
{
VM& vm = exec->vm();
NativeCallFrameTracer tracer(&vm, exec);
+ ASSERT(isIndex(index));
if (direct) {
RELEASE_ASSERT(baseValue.isObject());
asObject(baseValue)->putDirectIndex(exec, index, value, 0, strict ? PutDirectIndexShouldThrow : PutDirectIndexShouldNotThrow);
@@ -99,6 +100,8 @@
JSValue value = JSValue::decode(encodedValue);
if (LIKELY(property.isUInt32())) {
+ // Despite its name, JSValue::isUInt32 will return true only for positive boxed int32_t; all those values are valid array indices.
+ ASSERT(isIndex(property.asUInt32()));
putByVal<strict, direct>(exec, baseValue, property.asUInt32(), value);
return;
}
@@ -106,7 +109,7 @@
if (property.isDouble()) {
double propertyAsDouble = property.asDouble();
uint32_t propertyAsUInt32 = static_cast<uint32_t>(propertyAsDouble);
- if (propertyAsDouble == propertyAsUInt32) {
+ if (propertyAsDouble == propertyAsUInt32 && isIndex(propertyAsUInt32)) {
putByVal<strict, direct>(exec, baseValue, propertyAsUInt32, value);
return;
}
@@ -114,14 +117,18 @@
// Don't put to an object if toString throws an exception.
auto propertyName = property.toPropertyKey(exec);
- if (!vm->exception()) {
- PutPropertySlot slot(baseValue, strict);
- if (direct) {
- RELEASE_ASSERT(baseValue.isObject());
+ if (vm->exception())
+ return;
+
+ PutPropertySlot slot(baseValue, strict);
+ if (direct) {
+ RELEASE_ASSERT(baseValue.isObject());
+ if (Optional<uint32_t> index = parseIndex(propertyName))
+ asObject(baseValue)->putDirectIndex(exec, index.value(), value, 0, strict ? PutDirectIndexShouldThrow : PutDirectIndexShouldNotThrow);
+ else
asObject(baseValue)->putDirect(*vm, propertyName, value, slot);
- } else
- baseValue.put(exec, propertyName, value, slot);
- }
+ } else
+ baseValue.put(exec, propertyName, value, slot);
}
template<typename ViewClass>
@@ -285,7 +292,7 @@
} else if (property.isDouble()) {
double propertyAsDouble = property.asDouble();
uint32_t propertyAsUInt32 = static_cast<uint32_t>(propertyAsDouble);
- if (propertyAsUInt32 == propertyAsDouble)
+ if (propertyAsUInt32 == propertyAsDouble && isIndex(propertyAsUInt32))
return getByVal(exec, base, propertyAsUInt32);
} else if (property.isString()) {
Structure& structure = *base->structure(vm);