[JSC] GetterSetter should be JSCell, not JSObject
authorysuzuki@apple.com <ysuzuki@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 9 Oct 2019 00:25:25 +0000 (00:25 +0000)
committerysuzuki@apple.com <ysuzuki@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 9 Oct 2019 00:25:25 +0000 (00:25 +0000)
https://bugs.webkit.org/show_bug.cgi?id=202656

Reviewed by Tadeu Zagallo and Saam Barati.

JSTests:

* stress/getter-setter-should-be-cell.js: Added.
(foo.with.):
(foo.with.get for):
(foo.with.bar):
(foo):

Source/JavaScriptCore:

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:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@250878 268f45cc-cd09-0410-ab3c-d52691b4dbfc

12 files changed:
JSTests/ChangeLog
JSTests/stress/getter-setter-should-be-cell.js [new file with mode: 0644]
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h
Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
Source/JavaScriptCore/runtime/GetterSetter.cpp
Source/JavaScriptCore/runtime/GetterSetter.h
Source/JavaScriptCore/runtime/JSGlobalObject.cpp
Source/JavaScriptCore/runtime/JSGlobalObject.h
Source/JavaScriptCore/runtime/JSType.h
Source/JavaScriptCore/runtime/VM.cpp
Source/JavaScriptCore/runtime/VM.h

index 462ba63..1d84f4e 100644 (file)
@@ -1,3 +1,16 @@
+2019-10-08  Yusuke Suzuki  <ysuzuki@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  <shvaikalesh@gmail.com>
 
         JSON.parse incorrectly handles array proxies
diff --git a/JSTests/stress/getter-setter-should-be-cell.js b/JSTests/stress/getter-setter-should-be-cell.js
new file mode 100644 (file)
index 0000000..d9ce5d2
--- /dev/null
@@ -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();
index bccb200..4583330 100644 (file)
@@ -1,3 +1,45 @@
+2019-10-08  Yusuke Suzuki  <ysuzuki@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  <drousso@apple.com>
 
         Web Inspector: Canvas: modifications to shader modules can be shared between vertex/fragment shaders
index 5a63b42..d41c045 100644 (file)
@@ -3466,12 +3466,7 @@ bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi
             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;
     }
         
index 3f1c891..e1e1678 100644 (file)
@@ -34,6 +34,7 @@
 #include "DFGPhase.h"
 #include "DFGPredictionPropagationPhase.h"
 #include "DFGVariableAccessDataDump.h"
+#include "GetterSetter.h"
 #include "JSCInlines.h"
 #include "TypeLocation.h"
 
index 998d184..c8ea8be 100644 (file)
@@ -33,7 +33,7 @@ namespace JSC {
 
 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)
 {
index f10478b..67f3f63 100644 (file)
@@ -40,12 +40,12 @@ class JSObject;
 // 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());
index d956979..b3fc404 100644 (file)
@@ -450,12 +450,12 @@ void JSGlobalObject::setGlobalThis(VM& vm, JSObject* globalThis)
     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 @@ void JSGlobalObject::init(VM& vm)
         [] (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 @@ capitalName ## Constructor* lowerName ## Constructor = featureFlag ? capitalName
     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 @@ capitalName ## Constructor* lowerName ## Constructor = featureFlag ? capitalName
 
         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 @@ void JSGlobalObject::visitChildren(JSCell* cell, SlotVisitor& visitor)
 
     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);
index be1bd25..22689cf 100644 (file)
@@ -306,8 +306,8 @@ public:
     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 @@ public:
 
     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 @@ public:
     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 @@ public:
 
     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); }
index e930fd3..6e99687 100644 (file)
@@ -29,6 +29,7 @@ enum JSType : uint8_t {
     SymbolType,
     BigIntType,
 
+    GetterSetterType,
     CustomGetterSetterType,
     APIValueWrapperType,
 
@@ -88,8 +89,6 @@ enum JSType : uint8_t {
     DataViewType,
     // End JSArrayBufferView types.
 
-    GetterSetterType,
-
     // JSScope <- JSWithScope
     //         <- StrictEvalActivation
     //         <- JSSymbolTableObject  <- JSLexicalEnvironment      <- JSModuleEnvironment
index adb5a91..cbfdd21 100644 (file)
@@ -342,6 +342,7 @@ VM::VM(VMType vmType, HeapType heapType)
     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()));
index 0700fca..f813a2a 100644 (file)
@@ -504,6 +504,7 @@ public:
     Strong<Structure> terminatedExecutionErrorStructure;
     Strong<Structure> stringStructure;
     Strong<Structure> propertyNameEnumeratorStructure;
+    Strong<Structure> getterSetterStructure;
     Strong<Structure> customGetterSetterStructure;
     Strong<Structure> domAttributeGetterSetterStructure;
     Strong<Structure> scopedArgumentsTableStructure;