Diff
Modified: trunk/JSTests/ChangeLog (250877 => 250878)
--- trunk/JSTests/ChangeLog 2019-10-08 23:38:12 UTC (rev 250877)
+++ trunk/JSTests/ChangeLog 2019-10-09 00:25:25 UTC (rev 250878)
@@ -1,3 +1,16 @@
+2019-10-08 Yusuke Suzuki <ysuz...@apple.com>
+
+ [JSC] GetterSetter should be JSCell, not JSObject
+ https://bugs.webkit.org/show_bug.cgi?id=202656
+
+ Reviewed by Tadeu Zagallo and Saam Barati.
+
+ * stress/getter-setter-should-be-cell.js: Added.
+ (foo.with.):
+ (foo.with.get for):
+ (foo.with.bar):
+ (foo):
+
2019-10-08 Alexey Shvayka <shvaikal...@gmail.com>
JSON.parse incorrectly handles array proxies
Added: trunk/JSTests/stress/getter-setter-should-be-cell.js (0 => 250878)
--- trunk/JSTests/stress/getter-setter-should-be-cell.js (rev 0)
+++ trunk/JSTests/stress/getter-setter-should-be-cell.js 2019-10-09 00:25:25 UTC (rev 250878)
@@ -0,0 +1,26 @@
+//@ runDefault("--validateAbstractInterpreterState=1", "--forceEagerCompilation=1")
+String.__proto__ = createGlobalObject();
+const that = {};
+that.__proto__ = String;
+
+function foo() {
+ with (that) {
+ function bar(a0, a1) {
+ const v0 = '';
+ const v1 = undefined;
+ const v2 = undefined;
+ const v3 = undefined;
+ const p = { get: ()=>{} };
+ for (let j = 0; j < 1; j++) {
+ function f0() {}
+ const v4 = Object.defineProperty(''.__proto__, '__proto__', p);
+ }
+ const v5 = undefined;
+ }
+ for (let i = 0; i < 100; i++) {
+ new Promise(bar);
+ }
+ }
+}
+
+foo();
Modified: trunk/Source/_javascript_Core/ChangeLog (250877 => 250878)
--- trunk/Source/_javascript_Core/ChangeLog 2019-10-08 23:38:12 UTC (rev 250877)
+++ trunk/Source/_javascript_Core/ChangeLog 2019-10-09 00:25:25 UTC (rev 250878)
@@ -1,3 +1,45 @@
+2019-10-08 Yusuke Suzuki <ysuz...@apple.com>
+
+ [JSC] GetterSetter should be JSCell, not JSObject
+ https://bugs.webkit.org/show_bug.cgi?id=202656
+
+ Reviewed by Tadeu Zagallo and Saam Barati.
+
+ Essentially, GetterSetter is not a JSObject. It is like a JSCell. But we made GetterSetter JSObject
+ to leverage existing strict-eq implementations for JSObject: pointer-comparison. But given the following
+ conditions,
+
+ 1. GetterSetter strict-eq comparison only happens in builtin code when using @tryGetById.
+ 2. RHS of that comparison is always folded into constant in DFG.
+ 3. We already use pointer-comparison for cells that are neither JSString nor JSBigInt.
+ 4. DFG strength reduction already has a rule which makes `CompareStrictEq(Cell-not-JSString/JSBigInt, Constant)` `ComparePtrEq`.
+
+ So we already support non-JSString/JSBigInt cell comparison in JSC JS code. We should use it instead of making GetterSetter JSObject.
+ This patch makes GetterSetter JSCell, and makes getterSetterStructure per-VM structure.
+
+ The attached test reported AI validation failure. AI assumed that GetterSetter's realm should be the same to the base object. But
+ this is incorrect in our runtime code: we are creating GetterSetter with lexical realm (JSGlobalObject). But the fundamental problem
+ is that GetterSetter is JSObject and tied to JSGlobalObject while it is not necessary.
+
+ * dfg/DFGAbstractInterpreterInlines.h:
+ (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+ * dfg/DFGFixupPhase.cpp:
+ * runtime/GetterSetter.cpp:
+ * runtime/GetterSetter.h:
+ * runtime/JSGlobalObject.cpp:
+ (JSC::getGetterById):
+ (JSC::JSGlobalObject::init):
+ (JSC::JSGlobalObject::visitChildren):
+ * runtime/JSGlobalObject.h:
+ (JSC::JSGlobalObject::regExpProtoGlobalGetter const):
+ (JSC::JSGlobalObject::regExpProtoUnicodeGetter const):
+ (JSC::JSGlobalObject::customGetterSetterFunctionStructure const):
+ (JSC::JSGlobalObject::getterSetterStructure const): Deleted.
+ * runtime/JSType.h:
+ * runtime/VM.cpp:
+ (JSC::VM::VM):
+ * runtime/VM.h:
+
2019-10-08 Devin Rousso <drou...@apple.com>
Web Inspector: Canvas: modifications to shader modules can be shared between vertex/fragment shaders
Modified: trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h (250877 => 250878)
--- trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h 2019-10-08 23:38:12 UTC (rev 250877)
+++ trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h 2019-10-09 00:25:25 UTC (rev 250878)
@@ -3466,12 +3466,7 @@
break;
}
- if (base.value() && base.value().isObject()) {
- setForNode(node, asObject(base.value())->globalObject()->getterSetterStructure());
- break;
- }
-
- setTypeForNode(node, SpecObjectOther);
+ setForNode(node, m_vm.getterSetterStructure.get());
break;
}
Modified: trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp (250877 => 250878)
--- trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp 2019-10-08 23:38:12 UTC (rev 250877)
+++ trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp 2019-10-09 00:25:25 UTC (rev 250878)
@@ -34,6 +34,7 @@
#include "DFGPhase.h"
#include "DFGPredictionPropagationPhase.h"
#include "DFGVariableAccessDataDump.h"
+#include "GetterSetter.h"
#include "JSCInlines.h"
#include "TypeLocation.h"
Modified: trunk/Source/_javascript_Core/runtime/GetterSetter.cpp (250877 => 250878)
--- trunk/Source/_javascript_Core/runtime/GetterSetter.cpp 2019-10-08 23:38:12 UTC (rev 250877)
+++ trunk/Source/_javascript_Core/runtime/GetterSetter.cpp 2019-10-09 00:25:25 UTC (rev 250878)
@@ -33,7 +33,7 @@
STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(GetterSetter);
-const ClassInfo GetterSetter::s_info = { "GetterSetter", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(GetterSetter) };
+const ClassInfo GetterSetter::s_info = { "GetterSetter", nullptr, nullptr, nullptr, CREATE_METHOD_TABLE(GetterSetter) };
void GetterSetter::visitChildren(JSCell* cell, SlotVisitor& visitor)
{
Modified: trunk/Source/_javascript_Core/runtime/GetterSetter.h (250877 => 250878)
--- trunk/Source/_javascript_Core/runtime/GetterSetter.h 2019-10-08 23:38:12 UTC (rev 250877)
+++ trunk/Source/_javascript_Core/runtime/GetterSetter.h 2019-10-09 00:25:25 UTC (rev 250878)
@@ -40,12 +40,12 @@
// that if a property holding a GetterSetter reference is constant-inferred and
// that constant is observed to have a non-null setter (or getter) then we can
// constant fold that setter (or getter).
-class GetterSetter final : public JSNonFinalObject {
+class GetterSetter final : public JSCell {
friend class JIT;
- typedef JSNonFinalObject Base;
+ using Base = JSCell;
private:
GetterSetter(VM& vm, JSGlobalObject* globalObject, JSObject* getter, JSObject* setter)
- : Base(vm, globalObject->getterSetterStructure())
+ : Base(vm, vm.getterSetterStructure.get())
{
WTF::storeStoreFence();
m_getter.set(vm, this, getter ? getter : globalObject->nullGetterFunction());
Modified: trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp (250877 => 250878)
--- trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp 2019-10-08 23:38:12 UTC (rev 250877)
+++ trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp 2019-10-09 00:25:25 UTC (rev 250878)
@@ -450,12 +450,12 @@
m_globalThis.set(vm, this, globalThis);
}
-static JSObject* getGetterById(ExecState* exec, JSObject* base, const Identifier& ident)
+static GetterSetter* getGetterById(ExecState* exec, JSObject* base, const Identifier& ident)
{
JSValue baseValue = JSValue(base);
PropertySlot slot(baseValue, PropertySlot::InternalMethodType::VMInquiry);
baseValue.getPropertySlot(exec, ident, slot);
- return slot.getPureResult().toObject(exec);
+ return jsCast<GetterSetter*>(slot.getPureResult());
}
template<ErrorType errorType>
@@ -514,7 +514,6 @@
[] (const Initializer<Structure>& init) {
init.set(JSBoundFunction::createStructure(init.vm, init.owner, init.owner->m_functionPrototype.get()));
});
- m_getterSetterStructure.set(vm, this, GetterSetter::createStructure(vm, this, jsNull()));
m_nativeStdFunctionStructure.initLater(
[] (const Initializer<Structure>& init) {
init.set(JSNativeStdFunction::createStructure(init.vm, init.owner, init.owner->m_functionPrototype.get()));
@@ -939,22 +938,22 @@
JSFunction* privateFuncSetBucketNext = JSFunction::create(vm, this, 0, String(), setPrivateFuncSetBucketNext, JSSetBucketNextIntrinsic);
JSFunction* privateFuncSetBucketKey = JSFunction::create(vm, this, 0, String(), setPrivateFuncSetBucketKey, JSSetBucketKeyIntrinsic);
- JSObject* regExpProtoFlagsGetterObject = getGetterById(exec, m_regExpPrototype.get(), vm.propertyNames->flags);
+ GetterSetter* regExpProtoFlagsGetter = getGetterById(exec, m_regExpPrototype.get(), vm.propertyNames->flags);
catchScope.assertNoException();
- JSObject* regExpProtoGlobalGetterObject = getGetterById(exec, m_regExpPrototype.get(), vm.propertyNames->global);
+ GetterSetter* regExpProtoGlobalGetter = getGetterById(exec, m_regExpPrototype.get(), vm.propertyNames->global);
catchScope.assertNoException();
- m_regExpProtoGlobalGetter.set(vm, this, regExpProtoGlobalGetterObject);
- JSObject* regExpProtoIgnoreCaseGetterObject = getGetterById(exec, m_regExpPrototype.get(), vm.propertyNames->ignoreCase);
+ m_regExpProtoGlobalGetter.set(vm, this, regExpProtoGlobalGetter);
+ GetterSetter* regExpProtoIgnoreCaseGetter = getGetterById(exec, m_regExpPrototype.get(), vm.propertyNames->ignoreCase);
catchScope.assertNoException();
- JSObject* regExpProtoMultilineGetterObject = getGetterById(exec, m_regExpPrototype.get(), vm.propertyNames->multiline);
+ GetterSetter* regExpProtoMultilineGetter = getGetterById(exec, m_regExpPrototype.get(), vm.propertyNames->multiline);
catchScope.assertNoException();
- JSObject* regExpProtoSourceGetterObject = getGetterById(exec, m_regExpPrototype.get(), vm.propertyNames->source);
+ GetterSetter* regExpProtoSourceGetter = getGetterById(exec, m_regExpPrototype.get(), vm.propertyNames->source);
catchScope.assertNoException();
- JSObject* regExpProtoStickyGetterObject = getGetterById(exec, m_regExpPrototype.get(), vm.propertyNames->sticky);
+ GetterSetter* regExpProtoStickyGetter = getGetterById(exec, m_regExpPrototype.get(), vm.propertyNames->sticky);
catchScope.assertNoException();
- JSObject* regExpProtoUnicodeGetterObject = getGetterById(exec, m_regExpPrototype.get(), vm.propertyNames->unicode);
+ GetterSetter* regExpProtoUnicodeGetter = getGetterById(exec, m_regExpPrototype.get(), vm.propertyNames->unicode);
catchScope.assertNoException();
- m_regExpProtoUnicodeGetter.set(vm, this, regExpProtoUnicodeGetterObject);
+ m_regExpProtoUnicodeGetter.set(vm, this, regExpProtoUnicodeGetter);
JSObject* builtinRegExpExec = asObject(m_regExpPrototype->getDirect(vm, vm.propertyNames->exec).asCell());
m_regExpProtoExec.set(vm, this, builtinRegExpExec);
JSObject* regExpSymbolReplace = asObject(m_regExpPrototype->getDirect(vm, vm.propertyNames->replaceSymbol).asCell());
@@ -1024,13 +1023,13 @@
GlobalPropertyInfo(vm.propertyNames->builtinNames().isConstructorPrivateName(), JSFunction::create(vm, this, 1, String(), esSpecIsConstructor, NoIntrinsic), PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
- GlobalPropertyInfo(vm.propertyNames->builtinNames().regExpProtoFlagsGetterPrivateName(), regExpProtoFlagsGetterObject, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
- GlobalPropertyInfo(vm.propertyNames->builtinNames().regExpProtoGlobalGetterPrivateName(), regExpProtoGlobalGetterObject, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
- GlobalPropertyInfo(vm.propertyNames->builtinNames().regExpProtoIgnoreCaseGetterPrivateName(), regExpProtoIgnoreCaseGetterObject, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
- GlobalPropertyInfo(vm.propertyNames->builtinNames().regExpProtoMultilineGetterPrivateName(), regExpProtoMultilineGetterObject, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
- GlobalPropertyInfo(vm.propertyNames->builtinNames().regExpProtoSourceGetterPrivateName(), regExpProtoSourceGetterObject, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
- GlobalPropertyInfo(vm.propertyNames->builtinNames().regExpProtoStickyGetterPrivateName(), regExpProtoStickyGetterObject, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
- GlobalPropertyInfo(vm.propertyNames->builtinNames().regExpProtoUnicodeGetterPrivateName(), regExpProtoUnicodeGetterObject, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
+ GlobalPropertyInfo(vm.propertyNames->builtinNames().regExpProtoFlagsGetterPrivateName(), regExpProtoFlagsGetter, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
+ GlobalPropertyInfo(vm.propertyNames->builtinNames().regExpProtoGlobalGetterPrivateName(), regExpProtoGlobalGetter, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
+ GlobalPropertyInfo(vm.propertyNames->builtinNames().regExpProtoIgnoreCaseGetterPrivateName(), regExpProtoIgnoreCaseGetter, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
+ GlobalPropertyInfo(vm.propertyNames->builtinNames().regExpProtoMultilineGetterPrivateName(), regExpProtoMultilineGetter, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
+ GlobalPropertyInfo(vm.propertyNames->builtinNames().regExpProtoSourceGetterPrivateName(), regExpProtoSourceGetter, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
+ GlobalPropertyInfo(vm.propertyNames->builtinNames().regExpProtoStickyGetterPrivateName(), regExpProtoStickyGetter, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
+ GlobalPropertyInfo(vm.propertyNames->builtinNames().regExpProtoUnicodeGetterPrivateName(), regExpProtoUnicodeGetter, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
// RegExp.prototype helpers.
GlobalPropertyInfo(vm.propertyNames->builtinNames().regExpBuiltinExecPrivateName(), builtinRegExpExec, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
@@ -1760,7 +1759,6 @@
thisObject->m_customGetterSetterFunctionStructure.visit(visitor);
thisObject->m_boundFunctionStructure.visit(visitor);
- visitor.append(thisObject->m_getterSetterStructure);
thisObject->m_nativeStdFunctionStructure.visit(visitor);
visitor.append(thisObject->m_regExpStructure);
visitor.append(thisObject->m_generatorFunctionStructure);
Modified: trunk/Source/_javascript_Core/runtime/JSGlobalObject.h (250877 => 250878)
--- trunk/Source/_javascript_Core/runtime/JSGlobalObject.h 2019-10-08 23:38:12 UTC (rev 250877)
+++ trunk/Source/_javascript_Core/runtime/JSGlobalObject.h 2019-10-09 00:25:25 UTC (rev 250878)
@@ -306,8 +306,8 @@
LazyProperty<JSGlobalObject, GetterSetter> m_throwTypeErrorGetterSetter;
WriteBarrier<JSObject> m_regExpProtoExec;
WriteBarrier<JSObject> m_regExpProtoSymbolReplace;
- WriteBarrier<JSObject> m_regExpProtoGlobalGetter;
- WriteBarrier<JSObject> m_regExpProtoUnicodeGetter;
+ WriteBarrier<GetterSetter> m_regExpProtoGlobalGetter;
+ WriteBarrier<GetterSetter> m_regExpProtoUnicodeGetter;
WriteBarrier<GetterSetter> m_throwTypeErrorArgumentsCalleeAndCallerGetterSetter;
LazyProperty<JSGlobalObject, JSModuleLoader> m_moduleLoader;
@@ -365,7 +365,6 @@
LazyProperty<JSGlobalObject, Structure> m_boundFunctionStructure;
LazyProperty<JSGlobalObject, Structure> m_customGetterSetterFunctionStructure;
- WriteBarrier<Structure> m_getterSetterStructure;
LazyProperty<JSGlobalObject, Structure> m_nativeStdFunctionStructure;
PropertyOffset m_functionNameOffset;
WriteBarrier<Structure> m_regExpStructure;
@@ -622,8 +621,8 @@
JSFunction* functionProtoHasInstanceSymbolFunction() const { return m_functionProtoHasInstanceSymbolFunction.get(); }
JSObject* regExpProtoExecFunction() const { return m_regExpProtoExec.get(); }
JSObject* regExpProtoSymbolReplaceFunction() const { return m_regExpProtoSymbolReplace.get(); }
- JSObject* regExpProtoGlobalGetter() const { return m_regExpProtoGlobalGetter.get(); }
- JSObject* regExpProtoUnicodeGetter() const { return m_regExpProtoUnicodeGetter.get(); }
+ GetterSetter* regExpProtoGlobalGetter() const { return m_regExpProtoGlobalGetter.get(); }
+ GetterSetter* regExpProtoUnicodeGetter() const { return m_regExpProtoUnicodeGetter.get(); }
GetterSetter* throwTypeErrorArgumentsCalleeAndCallerGetterSetter()
{
return m_throwTypeErrorArgumentsCalleeAndCallerGetterSetter.get();
@@ -748,7 +747,6 @@
Structure* boundFunctionStructure() const { return m_boundFunctionStructure.get(this); }
Structure* customGetterSetterFunctionStructure() const { return m_customGetterSetterFunctionStructure.get(this); }
- Structure* getterSetterStructure() const { return m_getterSetterStructure.get(); }
Structure* nativeStdFunctionStructure() const { return m_nativeStdFunctionStructure.get(this); }
PropertyOffset functionNameOffset() const { return m_functionNameOffset; }
Structure* numberObjectStructure() const { return m_numberObjectStructure.get(this); }
Modified: trunk/Source/_javascript_Core/runtime/JSType.h (250877 => 250878)
--- trunk/Source/_javascript_Core/runtime/JSType.h 2019-10-08 23:38:12 UTC (rev 250877)
+++ trunk/Source/_javascript_Core/runtime/JSType.h 2019-10-09 00:25:25 UTC (rev 250878)
@@ -29,6 +29,7 @@
SymbolType,
BigIntType,
+ GetterSetterType,
CustomGetterSetterType,
APIValueWrapperType,
@@ -88,8 +89,6 @@
DataViewType,
// End JSArrayBufferView types.
- GetterSetterType,
-
// JSScope <- JSWithScope
// <- StrictEvalActivation
// <- JSSymbolTableObject <- JSLexicalEnvironment <- JSModuleEnvironment
Modified: trunk/Source/_javascript_Core/runtime/VM.cpp (250877 => 250878)
--- trunk/Source/_javascript_Core/runtime/VM.cpp 2019-10-08 23:38:12 UTC (rev 250877)
+++ trunk/Source/_javascript_Core/runtime/VM.cpp 2019-10-09 00:25:25 UTC (rev 250878)
@@ -342,6 +342,7 @@
propertyNames = new CommonIdentifiers(*this);
terminatedExecutionErrorStructure.set(*this, TerminatedExecutionError::createStructure(*this, 0, jsNull()));
propertyNameEnumeratorStructure.set(*this, JSPropertyNameEnumerator::createStructure(*this, 0, jsNull()));
+ getterSetterStructure.set(*this, GetterSetter::createStructure(*this, 0, jsNull()));
customGetterSetterStructure.set(*this, CustomGetterSetter::createStructure(*this, 0, jsNull()));
domAttributeGetterSetterStructure.set(*this, DOMAttributeGetterSetter::createStructure(*this, 0, jsNull()));
scopedArgumentsTableStructure.set(*this, ScopedArgumentsTable::createStructure(*this, 0, jsNull()));
Modified: trunk/Source/_javascript_Core/runtime/VM.h (250877 => 250878)
--- trunk/Source/_javascript_Core/runtime/VM.h 2019-10-08 23:38:12 UTC (rev 250877)
+++ trunk/Source/_javascript_Core/runtime/VM.h 2019-10-09 00:25:25 UTC (rev 250878)
@@ -504,6 +504,7 @@
Strong<Structure> terminatedExecutionErrorStructure;
Strong<Structure> stringStructure;
Strong<Structure> propertyNameEnumeratorStructure;
+ Strong<Structure> getterSetterStructure;
Strong<Structure> customGetterSetterStructure;
Strong<Structure> domAttributeGetterSetterStructure;
Strong<Structure> scopedArgumentsTableStructure;