Modified: releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/ChangeLog (210207 => 210208)
--- releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/ChangeLog 2016-12-30 09:02:51 UTC (rev 210207)
+++ releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/ChangeLog 2016-12-30 09:39:26 UTC (rev 210208)
@@ -1,3 +1,45 @@
+2016-10-27 Mark Lam <[email protected]>
+
+ JSFunction::put() should not allow caching of lazily reified properties.
+ https://bugs.webkit.org/show_bug.cgi?id=164081
+
+ Reviewed by Geoffrey Garen.
+
+ It is incorrect for JSFunction::put() to return PutPropertySlots that indicates
+ that its lazily reified properties (e.g. .caller, and .arguments) are cacheable.
+ The reason for this is:
+
+ 1. Currently, a cacheable put may only consist of the following types of put
+ operations:
+ a. putting a new property at an offset in the object storage.
+ b. changing the value of an existing property at an offset in the object storage.
+ c. invoking the setter for a property at an offset in the object storage.
+
+ Returning a PutPropertySlot that indicates the property is cacheable means that
+ the property put must be one of the above operations.
+
+ For lazily reified properties, JSFunction::put() implements complex conditional
+ behavior that is different than the set of cacheable put operations above.
+ Hence, it should not claim that the property put is cacheable.
+
+ 2. Cacheable puts are cached on the original structure of the object before the
+ put operation.
+
+ Reifying a lazy property will trigger a structure transition. Even though
+ subsequent puts to such a property may be cacheable after the structure
+ transition, it is incorrect to indicate that the property put is cacheable
+ because the caching is on the original structure, not the new transitioned
+ structure.
+
+ Also fixed some missing exception checks.
+
+ * jit/JITOperations.cpp:
+ * runtime/JSFunction.cpp:
+ (JSC::JSFunction::put):
+ (JSC::JSFunction::reifyLazyPropertyIfNeeded):
+ (JSC::JSFunction::reifyBoundNameIfNeeded):
+ * runtime/JSFunction.h:
+
2016-10-12 Joseph Pecoraro <[email protected]>
Web Inspector: Improve support for logging Proxy objects in console
Modified: releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/jit/JITOperations.cpp (210207 => 210208)
--- releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/jit/JITOperations.cpp 2016-12-30 09:02:51 UTC (rev 210207)
+++ releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/jit/JITOperations.cpp 2016-12-30 09:39:26 UTC (rev 210208)
@@ -201,6 +201,9 @@
PropertySlot slot(baseValue, PropertySlot::InternalMethodType::VMInquiry);
baseValue.getPropertySlot(exec, ident, slot);
+ if (UNLIKELY(vm->exception()))
+ return encodedJSValue();
+
if (stubInfo->considerCaching(baseValue.structureOrNull()) && !slot.isTaintedByOpaqueObject() && (slot.isCacheableValue() || slot.isCacheableGetter() || slot.isUnset()))
repatchGetByID(exec, baseValue, ident, slot, *stubInfo, GetByIDKind::Pure);
@@ -398,7 +401,9 @@
Structure* structure = baseValue.isCell() ? baseValue.asCell()->structure(*vm) : nullptr;
baseValue.putInline(exec, ident, value, slot);
-
+ if (UNLIKELY(vm->exception()))
+ return;
+
if (accessType != static_cast<AccessType>(stubInfo->accessType))
return;
@@ -423,7 +428,9 @@
Structure* structure = baseValue.isCell() ? baseValue.asCell()->structure(*vm) : nullptr;
baseValue.putInline(exec, ident, value, slot);
-
+ if (UNLIKELY(vm->exception()))
+ return;
+
if (accessType != static_cast<AccessType>(stubInfo->accessType))
return;
Modified: releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/runtime/JSFunction.cpp (210207 => 210208)
--- releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/runtime/JSFunction.cpp 2016-12-30 09:02:51 UTC (rev 210207)
+++ releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/runtime/JSFunction.cpp 2016-12-30 09:39:26 UTC (rev 210208)
@@ -437,23 +437,26 @@
return ordinarySetSlow(exec, thisObject, propertyName, value, slot.thisValue(), slot.isStrictMode());
if (thisObject->isHostOrBuiltinFunction()) {
- thisObject->reifyBoundNameIfNeeded(vm, exec, propertyName);
+ LazyPropertyType propType = thisObject->reifyBoundNameIfNeeded(vm, exec, propertyName);
+ if (propType == LazyPropertyType::IsLazyProperty)
+ slot.disableCaching();
return Base::put(thisObject, exec, propertyName, value, slot);
}
if (propertyName == vm.propertyNames->prototype) {
+ slot.disableCaching();
// Make sure prototype has been reified, such that it can only be overwritten
// following the rules set out in ECMA-262 8.12.9.
- PropertySlot slot(thisObject, PropertySlot::InternalMethodType::VMInquiry);
- thisObject->methodTable(vm)->getOwnPropertySlot(thisObject, exec, propertyName, slot);
+ PropertySlot getSlot(thisObject, PropertySlot::InternalMethodType::VMInquiry);
+ thisObject->methodTable(vm)->getOwnPropertySlot(thisObject, exec, propertyName, getSlot);
if (thisObject->m_rareData)
thisObject->m_rareData->clear("Store to prototype property of a function");
- // Don't allow this to be cached, since a [[Put]] must clear m_rareData.
- PutPropertySlot dontCache(thisObject);
scope.release();
- return Base::put(thisObject, exec, propertyName, value, dontCache);
+ return Base::put(thisObject, exec, propertyName, value, slot);
}
+
if (thisObject->jsExecutable()->isStrictMode() && (propertyName == vm.propertyNames->arguments || propertyName == vm.propertyNames->caller)) {
+ slot.disableCaching();
// This will trigger the property to be reified, if this is not already the case!
bool okay = thisObject->hasProperty(exec, propertyName);
ASSERT_UNUSED(okay, okay);
@@ -461,11 +464,14 @@
return Base::put(thisObject, exec, propertyName, value, slot);
}
if (propertyName == vm.propertyNames->arguments || propertyName == vm.propertyNames->caller) {
+ slot.disableCaching();
if (slot.isStrictMode())
throwTypeError(exec, scope, StrictModeReadonlyPropertyWriteError);
return false;
}
- thisObject->reifyLazyPropertyIfNeeded(vm, exec, propertyName);
+ LazyPropertyType propType = thisObject->reifyLazyPropertyIfNeeded(vm, exec, propertyName);
+ if (propType == LazyPropertyType::IsLazyProperty)
+ slot.disableCaching();
scope.release();
return Base::put(thisObject, exec, propertyName, value, slot);
}
@@ -671,25 +677,28 @@
rareData->setHasReifiedName();
}
-void JSFunction::reifyLazyPropertyIfNeeded(VM& vm, ExecState* exec, PropertyName propertyName)
+JSFunction::LazyPropertyType JSFunction::reifyLazyPropertyIfNeeded(VM& vm, ExecState* exec, PropertyName propertyName)
{
if (propertyName == vm.propertyNames->length) {
if (!hasReifiedLength())
reifyLength(vm);
+ return LazyPropertyType::IsLazyProperty;
} else if (propertyName == vm.propertyNames->name) {
if (!hasReifiedName())
reifyName(vm, exec);
+ return LazyPropertyType::IsLazyProperty;
}
+ return LazyPropertyType::NotLazyProperty;
}
-void JSFunction::reifyBoundNameIfNeeded(VM& vm, ExecState* exec, PropertyName propertyName)
+JSFunction::LazyPropertyType JSFunction::reifyBoundNameIfNeeded(VM& vm, ExecState* exec, PropertyName propertyName)
{
const Identifier& nameIdent = vm.propertyNames->name;
if (propertyName != nameIdent)
- return;
+ return LazyPropertyType::NotLazyProperty;
if (hasReifiedName())
- return;
+ return LazyPropertyType::IsLazyProperty;
if (this->inherits(JSBoundFunction::info())) {
FunctionRareData* rareData = this->rareData(vm);
@@ -698,6 +707,7 @@
putDirect(vm, nameIdent, jsString(exec, name), initialAttributes);
rareData->setHasReifiedName();
}
+ return LazyPropertyType::IsLazyProperty;
}
} // namespace JSC
Modified: releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/runtime/JSFunction.h (210207 => 210208)
--- releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/runtime/JSFunction.h 2016-12-30 09:02:51 UTC (rev 210207)
+++ releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/runtime/JSFunction.h 2016-12-30 09:39:26 UTC (rev 210208)
@@ -191,10 +191,12 @@
bool hasReifiedName() const;
void reifyLength(VM&);
void reifyName(VM&, ExecState*);
- void reifyBoundNameIfNeeded(VM&, ExecState*, PropertyName);
void reifyName(VM&, ExecState*, String name);
- void reifyLazyPropertyIfNeeded(VM&, ExecState*, PropertyName propertyName);
+ enum class LazyPropertyType { NotLazyProperty, IsLazyProperty };
+ LazyPropertyType reifyLazyPropertyIfNeeded(VM&, ExecState*, PropertyName);
+ LazyPropertyType reifyBoundNameIfNeeded(VM&, ExecState*, PropertyName);
+
friend class LLIntOffsetsExtractor;
static EncodedJSValue argumentsGetter(ExecState*, EncodedJSValue, PropertyName);