[ES6] Module namespace object should not allow unset IC
authorutatane.tea@gmail.com <utatane.tea@gmail.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 8 Aug 2016 02:48:56 +0000 (02:48 +0000)
committerutatane.tea@gmail.com <utatane.tea@gmail.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 8 Aug 2016 02:48:56 +0000 (02:48 +0000)
https://bugs.webkit.org/show_bug.cgi?id=160553

Reviewed by Saam Barati.

JSTests:

* modules/namespace-object-get-property.js: Added.
(import.as.ns.from.string_appeared_here.shouldThrow):
* modules/namespace-object-has-property.js: Added.
* modules/namespace-object-inline-caching.js: Added.
(import.as.A.from.string_appeared_here.import.as.B.from.string_appeared_here.lookup):
(shouldBe.lookup.lookup):
(shouldBe.lookup):
* modules/namespace-object-inline-caching/a.js: Added.
* modules/namespace-object-inline-caching/b.js: Added.
* modules/namespace-object-try-get.js: Added.
(import.as.ns.from.string_appeared_here.tryGetByIdText):
(tryGetByIdTextStrict):
* modules/namespace-object-typed-array-fast-path.js: Added.
* test262.yaml:

Source/JavaScriptCore:

Previously, module namespace object accidentally allow "unset IC". But this "unsetness" does not rely on
the structure. We should disable inline caching onto the namespace object. Once it is needed, we should
create the special caching for namespace object like the following: it should be similar to monomorphic IC,
but it caches the object itself instead of the structure. It checks the object itself (And in DFG, it should be
CheckCell) and loads the value from the target module environment directly[1].

And this patch also set setIsTaintedByProxy for the module namespace object to notify to the caller that
this object has impure ::getOwnPropertySlot. Then this function is now renamed to setIsTaintedByOpaqueObject.

We drop the hack in JSModuleNamespaceObject::getOwnPropertySlot since we already introduced InternalMethodType
for ProxyObject. Previously we cannot distinguish ::HasProperty and ::GetOwnProperty. So not to throw any
errors for ::HasProperty case, we used slot.setCustom to delay the observable operation.
But, this hack lacks the support for hasOwnProperty: hasOwnProperty uses [[GetOwnProperty]], so it should throw an error.
However the previous implementation does not throw an error since the delayed observable part (custom function part) is
skipped in hasOwnProperty implementation. We now remove this custom property hack and fix the corresponding failure
in test262.

[1]: https://bugs.webkit.org/show_bug.cgi?id=160590

* jit/JITOperations.cpp:
* runtime/ArrayPrototype.cpp:
(JSC::getProperty):
* runtime/JSGenericTypedArrayViewConstructorInlines.h:
(JSC::constructGenericTypedArrayViewWithArguments):
* runtime/JSModuleNamespaceObject.cpp:
(JSC::JSModuleNamespaceObject::getOwnPropertySlot):
(JSC::callbackGetter): Deleted.
* runtime/JSModuleNamespaceObject.h:
* runtime/PropertySlot.cpp:
(JSC::PropertySlot::getPureResult):
* runtime/PropertySlot.h:
(JSC::PropertySlot::PropertySlot):
(JSC::PropertySlot::setIsTaintedByOpaqueObject):
(JSC::PropertySlot::isTaintedByOpaqueObject):
(JSC::PropertySlot::setIsTaintedByProxy): Deleted.
(JSC::PropertySlot::isTaintedByProxy): Deleted.
* runtime/ProxyObject.cpp:
(JSC::ProxyObject::getOwnPropertySlotCommon):

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

18 files changed:
JSTests/ChangeLog
JSTests/modules/namespace-object-get-property.js [new file with mode: 0644]
JSTests/modules/namespace-object-has-property.js [new file with mode: 0644]
JSTests/modules/namespace-object-inline-caching.js [new file with mode: 0644]
JSTests/modules/namespace-object-inline-caching/a.js [new file with mode: 0644]
JSTests/modules/namespace-object-inline-caching/b.js [new file with mode: 0644]
JSTests/modules/namespace-object-try-get.js [new file with mode: 0644]
JSTests/modules/namespace-object-typed-array-fast-path.js [new file with mode: 0644]
JSTests/test262.yaml
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/jit/JITOperations.cpp
Source/JavaScriptCore/runtime/ArrayPrototype.cpp
Source/JavaScriptCore/runtime/JSGenericTypedArrayViewConstructorInlines.h
Source/JavaScriptCore/runtime/JSModuleNamespaceObject.cpp
Source/JavaScriptCore/runtime/JSModuleNamespaceObject.h
Source/JavaScriptCore/runtime/PropertySlot.cpp
Source/JavaScriptCore/runtime/PropertySlot.h
Source/JavaScriptCore/runtime/ProxyObject.cpp

index 58eca85..9f6d8d3 100644 (file)
@@ -1,3 +1,25 @@
+2016-08-07  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        [ES6] Module namespace object should not allow unset IC
+        https://bugs.webkit.org/show_bug.cgi?id=160553
+
+        Reviewed by Saam Barati.
+
+        * modules/namespace-object-get-property.js: Added.
+        (import.as.ns.from.string_appeared_here.shouldThrow):
+        * modules/namespace-object-has-property.js: Added.
+        * modules/namespace-object-inline-caching.js: Added.
+        (import.as.A.from.string_appeared_here.import.as.B.from.string_appeared_here.lookup):
+        (shouldBe.lookup.lookup):
+        (shouldBe.lookup):
+        * modules/namespace-object-inline-caching/a.js: Added.
+        * modules/namespace-object-inline-caching/b.js: Added.
+        * modules/namespace-object-try-get.js: Added.
+        (import.as.ns.from.string_appeared_here.tryGetByIdText):
+        (tryGetByIdTextStrict):
+        * modules/namespace-object-typed-array-fast-path.js: Added.
+        * test262.yaml:
+
 2016-08-05  Saam Barati  <sbarati@apple.com>
 
         various math operations don't properly check for an exception after calling toNumber() on the lhs
diff --git a/JSTests/modules/namespace-object-get-property.js b/JSTests/modules/namespace-object-get-property.js
new file mode 100644 (file)
index 0000000..2692012
--- /dev/null
@@ -0,0 +1,9 @@
+import { shouldThrow, shouldBe } from "./resources/assert.js";
+import * as ns from "./namespace-object-get-property.js"
+
+shouldThrow(() => {
+    Reflect.get(ns, 'empty');
+}, `ReferenceError: Cannot access uninitialized variable.`);
+shouldBe(Reflect.get(ns, 'undefined'), undefined);
+
+export let empty;
diff --git a/JSTests/modules/namespace-object-has-property.js b/JSTests/modules/namespace-object-has-property.js
new file mode 100644 (file)
index 0000000..686885a
--- /dev/null
@@ -0,0 +1,7 @@
+import { shouldBe } from "./resources/assert.js";
+import * as ns from "./namespace-object-has-property.js"
+
+shouldBe(Reflect.has(ns, 'empty'), true);
+shouldBe(Reflect.has(ns, 'undefined'), false);
+
+export let empty;
diff --git a/JSTests/modules/namespace-object-inline-caching.js b/JSTests/modules/namespace-object-inline-caching.js
new file mode 100644 (file)
index 0000000..5cef5ac
--- /dev/null
@@ -0,0 +1,37 @@
+import { shouldBe } from "./resources/assert.js";
+import * as A from "./namespace-object-inline-caching/a.js"
+import * as B from "./namespace-object-inline-caching/b.js"
+
+// unset caching should be disabled for namespace object.
+{
+    function lookup(ns)
+    {
+        return ns.hello;
+    }
+    noInline(lookup);
+
+    shouldBe(A.hello, undefined);
+    shouldBe(B.hello, 42);
+
+    for (let i = 0; i < 1e4; ++i)
+        shouldBe(lookup(A), undefined);
+
+    shouldBe(lookup(B), 42);
+}
+
+// usual caching should be disabled for namespace object.
+{
+    function lookup(ns)
+    {
+        return ns.goodbye;
+    }
+    noInline(lookup);
+
+    shouldBe(A.goodbye, 0);
+    shouldBe(B.goodbye, undefined);
+
+    for (let i = 0; i < 1e4; ++i)
+        shouldBe(lookup(A), 0);
+
+    shouldBe(lookup(B), undefined);
+}
diff --git a/JSTests/modules/namespace-object-inline-caching/a.js b/JSTests/modules/namespace-object-inline-caching/a.js
new file mode 100644 (file)
index 0000000..731873a
--- /dev/null
@@ -0,0 +1 @@
+export let goodbye = 0;
diff --git a/JSTests/modules/namespace-object-inline-caching/b.js b/JSTests/modules/namespace-object-inline-caching/b.js
new file mode 100644 (file)
index 0000000..5b7d90f
--- /dev/null
@@ -0,0 +1 @@
+export let hello = 42;
diff --git a/JSTests/modules/namespace-object-try-get.js b/JSTests/modules/namespace-object-try-get.js
new file mode 100644 (file)
index 0000000..8b7ce69
--- /dev/null
@@ -0,0 +1,23 @@
+import { shouldBe } from "./resources/assert.js";
+import * as ns from "./namespace-object-try-get.js"
+
+function tryGetByIdText(propertyName) { return `(function (base) { return @tryGetById(base, '${propertyName}'); })`; }
+
+function tryGetByIdTextStrict(propertyName) { return `(function (base) { "use strict"; return @tryGetById(base, '${propertyName}'); })`; }
+
+{
+    let get = createBuiltin(tryGetByIdText("empty"));
+    noInline(get);
+
+    // Do not throw.
+    shouldBe(get(ns), null);
+
+    let getStrict = createBuiltin(tryGetByIdTextStrict("empty"));
+    noInline(getStrict);
+
+    // Do not throw.
+    shouldBe(getStrict(ns), null);
+
+}
+
+export let empty;
diff --git a/JSTests/modules/namespace-object-typed-array-fast-path.js b/JSTests/modules/namespace-object-typed-array-fast-path.js
new file mode 100644 (file)
index 0000000..2aea786
--- /dev/null
@@ -0,0 +1,7 @@
+import { shouldBe } from "./resources/assert.js";
+import * as ns from "./namespace-object-typed-array-fast-path.js"
+export let length = 42;
+export let hello = 44;
+
+let array = new Uint8Array(ns);
+shouldBe(array.length, 2);
index 983652d..6de59e3 100644 (file)
 - path: test262/test/language/module-code/namespace/internals/get-own-property-str-found-init.js
   cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], [:module]
 - path: test262/test/language/module-code/namespace/internals/get-own-property-str-found-uninit.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], [:module]
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], [:module]
 - path: test262/test/language/module-code/namespace/internals/get-own-property-str-not-found.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], [:module]
 - path: test262/test/language/module-code/namespace/internals/get-own-property-sym.js
index 251a8ea..2c68c92 100644 (file)
@@ -1,3 +1,49 @@
+2016-08-07  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        [ES6] Module namespace object should not allow unset IC
+        https://bugs.webkit.org/show_bug.cgi?id=160553
+
+        Reviewed by Saam Barati.
+
+        Previously, module namespace object accidentally allow "unset IC". But this "unsetness" does not rely on
+        the structure. We should disable inline caching onto the namespace object. Once it is needed, we should
+        create the special caching for namespace object like the following: it should be similar to monomorphic IC,
+        but it caches the object itself instead of the structure. It checks the object itself (And in DFG, it should be
+        CheckCell) and loads the value from the target module environment directly[1].
+
+        And this patch also set setIsTaintedByProxy for the module namespace object to notify to the caller that
+        this object has impure ::getOwnPropertySlot. Then this function is now renamed to setIsTaintedByOpaqueObject.
+
+        We drop the hack in JSModuleNamespaceObject::getOwnPropertySlot since we already introduced InternalMethodType
+        for ProxyObject. Previously we cannot distinguish ::HasProperty and ::GetOwnProperty. So not to throw any
+        errors for ::HasProperty case, we used slot.setCustom to delay the observable operation.
+        But, this hack lacks the support for hasOwnProperty: hasOwnProperty uses [[GetOwnProperty]], so it should throw an error.
+        However the previous implementation does not throw an error since the delayed observable part (custom function part) is
+        skipped in hasOwnProperty implementation. We now remove this custom property hack and fix the corresponding failure
+        in test262.
+
+        [1]: https://bugs.webkit.org/show_bug.cgi?id=160590
+
+        * jit/JITOperations.cpp:
+        * runtime/ArrayPrototype.cpp:
+        (JSC::getProperty):
+        * runtime/JSGenericTypedArrayViewConstructorInlines.h:
+        (JSC::constructGenericTypedArrayViewWithArguments):
+        * runtime/JSModuleNamespaceObject.cpp:
+        (JSC::JSModuleNamespaceObject::getOwnPropertySlot):
+        (JSC::callbackGetter): Deleted.
+        * runtime/JSModuleNamespaceObject.h:
+        * runtime/PropertySlot.cpp:
+        (JSC::PropertySlot::getPureResult):
+        * runtime/PropertySlot.h:
+        (JSC::PropertySlot::PropertySlot):
+        (JSC::PropertySlot::setIsTaintedByOpaqueObject):
+        (JSC::PropertySlot::isTaintedByOpaqueObject):
+        (JSC::PropertySlot::setIsTaintedByProxy): Deleted.
+        (JSC::PropertySlot::isTaintedByProxy): Deleted.
+        * runtime/ProxyObject.cpp:
+        (JSC::ProxyObject::getOwnPropertySlotCommon):
+
 2016-08-05  Keith Miller  <keith_miller@apple.com>
 
         Add LEBDecoder and tests
index d21d868..a4cea5b 100644 (file)
@@ -194,7 +194,7 @@ EncodedJSValue JIT_OPERATION operationTryGetByIdOptimize(ExecState* exec, Struct
     PropertySlot slot(baseValue, PropertySlot::InternalMethodType::VMInquiry);
 
     baseValue.getPropertySlot(exec, ident, slot);
-    if (stubInfo->considerCaching(baseValue.structureOrNull()) && !slot.isTaintedByProxy() && (slot.isCacheableValue() || slot.isCacheableGetter() || slot.isUnset()))
+    if (stubInfo->considerCaching(baseValue.structureOrNull()) && !slot.isTaintedByOpaqueObject() && (slot.isCacheableValue() || slot.isCacheableGetter() || slot.isUnset()))
         repatchGetByID(exec, baseValue, ident, slot, *stubInfo, GetByIDKind::Pure);
 
     return JSValue::encode(slot.getPureResult());
index 3661dba..f1ec57c 100644 (file)
@@ -154,12 +154,12 @@ static ALWAYS_INLINE JSValue getProperty(ExecState* exec, JSObject* object, unsi
         return result;
     // We want to perform get and has in the same operation.
     // We can only do so when this behavior is not observable. The
-    // only time it is observable is when we encounter a ProxyObject
+    // only time it is observable is when we encounter an opaque objects (ProxyObject and JSModuleNamespaceObject)
     // somewhere in the prototype chain.
     PropertySlot slot(object, PropertySlot::InternalMethodType::HasProperty);
     if (!object->getPropertySlot(exec, index, slot))
         return JSValue();
-    if (UNLIKELY(slot.isTaintedByProxy()))
+    if (UNLIKELY(slot.isTaintedByOpaqueObject()))
         return object->get(exec, index);
     return slot.getValue(exec, index);
 }
index 902b06b..15ab401 100644 (file)
@@ -152,7 +152,7 @@ inline JSObject* constructGenericTypedArrayViewWithArguments(ExecState* exec, St
             length = jsCast<JSArrayBufferView*>(object)->length();
         else {
             // This getPropertySlot operation should not be observed by the Proxy.
-            // So we use VMInquiry. And purge the proxy case by isTaintedByProxy() guard.
+            // So we use VMInquiry. And purge the opaque object cases (proxy and namespace object) by isTaintedByOpaqueObject() guard.
             PropertySlot lengthSlot(object, PropertySlot::InternalMethodType::VMInquiry);
             object->getPropertySlot(exec, vm.propertyNames->length, lengthSlot);
 
@@ -168,7 +168,7 @@ inline JSObject* constructGenericTypedArrayViewWithArguments(ExecState* exec, St
 
             if (!iteratorFunc.isUndefined()
                 && (iteratorFunc != object->globalObject()->arrayProtoValuesFunction()
-                    || lengthSlot.isAccessor() || lengthSlot.isCustom() || lengthSlot.isTaintedByProxy()
+                    || lengthSlot.isAccessor() || lengthSlot.isCustom() || lengthSlot.isTaintedByOpaqueObject()
                     || hasAnyArrayStorage(object->indexingType()))) {
 
                     CallData callData;
index 872a40c..d610586 100644 (file)
@@ -98,31 +98,6 @@ void JSModuleNamespaceObject::visitChildren(JSCell* cell, SlotVisitor& visitor)
     visitor.append(&thisObject->m_moduleRecord);
 }
 
-static EncodedJSValue callbackGetter(ExecState* exec, EncodedJSValue thisValue, PropertyName propertyName)
-{
-    JSModuleNamespaceObject* thisObject = jsCast<JSModuleNamespaceObject*>(JSValue::decode(thisValue));
-    JSModuleRecord* moduleRecord = thisObject->moduleRecord();
-
-    JSModuleRecord::Resolution resolution = moduleRecord->resolveExport(exec, Identifier::fromUid(exec, propertyName.uid()));
-    ASSERT(resolution.type != JSModuleRecord::Resolution::Type::NotFound && resolution.type != JSModuleRecord::Resolution::Type::Ambiguous);
-
-    JSModuleRecord* targetModule = resolution.moduleRecord;
-    JSModuleEnvironment* targetEnvironment = targetModule->moduleEnvironment();
-
-    PropertySlot trampolineSlot(targetEnvironment, PropertySlot::InternalMethodType::Get);
-    if (!targetEnvironment->methodTable(exec->vm())->getOwnPropertySlot(targetEnvironment, exec, resolution.localName, trampolineSlot))
-        return JSValue::encode(jsUndefined());
-
-    JSValue value = trampolineSlot.getValue(exec, propertyName);
-    if (exec->hadException())
-        return JSValue::encode(jsUndefined());
-
-    // If the value is filled with TDZ value, throw a reference error.
-    if (!value)
-        return throwVMError(exec, createTDZError(exec));
-    return JSValue::encode(value);
-}
-
 bool JSModuleNamespaceObject::getOwnPropertySlot(JSObject* cell, ExecState* exec, PropertyName propertyName, PropertySlot& slot)
 {
     // http://www.ecma-international.org/ecma-262/6.0/#sec-module-namespace-exotic-objects-getownproperty-p
@@ -135,21 +110,54 @@ bool JSModuleNamespaceObject::getOwnPropertySlot(JSObject* cell, ExecState* exec
     if (propertyName.isSymbol())
         return JSObject::getOwnPropertySlot(thisObject, exec, propertyName, slot);
 
+    // FIXME: Add IC for module namespace object.
+    // https://bugs.webkit.org/show_bug.cgi?id=160590
+    slot.disableCaching();
+    slot.setIsTaintedByOpaqueObject();
     if (!thisObject->m_exports.contains(propertyName.uid()))
         return false;
 
-    // https://esdiscuss.org/topic/march-24-meeting-notes
-    // http://www.ecma-international.org/ecma-262/6.0/#sec-module-namespace-exotic-objects-getownproperty-p
-    // section 9.4.6.5, step 6.
-    // This property will be seen as writable: true, enumerable:true, configurable: false.
-    // But this does not mean that this property is writable by users.
-    //
-    // In JSC, getOwnPropertySlot is not designed to throw any errors. But looking up the value from the module
-    // environment may throw error if the loaded variable is the TDZ value. To workaround, we set the custom
-    // getter function. When it is called, it looks up the variable and throws an error if the variable is not
-    // initialized.
-    slot.setCustom(thisObject, DontDelete, callbackGetter);
-    return true;
+    switch (slot.internalMethodType()) {
+    case PropertySlot::InternalMethodType::Get:
+    case PropertySlot::InternalMethodType::GetOwnProperty: {
+        JSModuleRecord* moduleRecord = thisObject->moduleRecord();
+
+        JSModuleRecord::Resolution resolution = moduleRecord->resolveExport(exec, Identifier::fromUid(exec, propertyName.uid()));
+        ASSERT(resolution.type != JSModuleRecord::Resolution::Type::NotFound && resolution.type != JSModuleRecord::Resolution::Type::Ambiguous);
+
+        JSModuleRecord* targetModule = resolution.moduleRecord;
+        JSModuleEnvironment* targetEnvironment = targetModule->moduleEnvironment();
+
+        PropertySlot trampolineSlot(targetEnvironment, PropertySlot::InternalMethodType::Get);
+        bool found = targetEnvironment->methodTable(exec->vm())->getOwnPropertySlot(targetEnvironment, exec, resolution.localName, trampolineSlot);
+        ASSERT_UNUSED(found, found);
+
+        JSValue value = trampolineSlot.getValue(exec, propertyName);
+        ASSERT(!exec->hadException());
+
+        // If the value is filled with TDZ value, throw a reference error.
+        if (!value) {
+            throwVMError(exec, createTDZError(exec));
+            return false;
+        }
+
+        slot.setValue(thisObject, DontDelete, value);
+        return true;
+    }
+    case PropertySlot::InternalMethodType::HasProperty: {
+        // Do not perform [[Get]] for [[HasProperty]].
+        // [[Get]] / [[GetOwnProperty]] onto namespace object could throw an error while [[HasProperty]] just returns true here.
+        // https://tc39.github.io/ecma262/#sec-module-namespace-exotic-objects-hasproperty-p
+        slot.setValue(thisObject, DontDelete, jsUndefined());
+        return true;
+    }
+
+    case PropertySlot::InternalMethodType::VMInquiry:
+        return false;
+    }
+
+    RELEASE_ASSERT_NOT_REACHED();
+    return false;
 }
 
 bool JSModuleNamespaceObject::put(JSCell*, ExecState* exec, PropertyName, JSValue, PutPropertySlot& slot)
index 8cfecfd..2ec18e8 100644 (file)
@@ -36,7 +36,7 @@ class JSModuleRecord;
 class JSModuleNamespaceObject : public JSDestructibleObject {
 public:
     typedef JSDestructibleObject Base;
-    static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot | OverridesGetPropertyNames;
+    static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot | InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | OverridesGetPropertyNames | GetOwnPropertySlotIsImpureForPropertyAbsence;
 
     static JSModuleNamespaceObject* create(ExecState* exec, JSGlobalObject* globalObject, Structure* structure, JSModuleRecord* moduleRecord, const IdentifierSet& exports)
     {
index 496d0ac..19d9a09 100644 (file)
@@ -44,7 +44,7 @@ JSValue PropertySlot::customGetter(ExecState* exec, PropertyName propertyName) c
 JSValue PropertySlot::getPureResult() const
 {
     JSValue result;
-    if (isTaintedByProxy())
+    if (isTaintedByOpaqueObject())
         result = jsNull();
     else if (isCacheableValue())
         result = JSValue::decode(m_data.value);
index d7d76c7..503d086 100644 (file)
@@ -90,7 +90,7 @@ public:
         , m_cacheability(CachingAllowed)
         , m_propertyType(TypeUnset)
         , m_internalMethodType(internalMethodType)
-        , m_isTaintedByProxy(false)
+        , m_isTaintedByOpaqueObject(false)
     {
     }
 
@@ -110,8 +110,8 @@ public:
     bool isCacheableValue() const { return isCacheable() && isValue(); }
     bool isCacheableGetter() const { return isCacheable() && isAccessor(); }
     bool isCacheableCustom() const { return isCacheable() && isCustom(); }
-    void setIsTaintedByProxy() { m_isTaintedByProxy = true; }
-    bool isTaintedByProxy() const { return m_isTaintedByProxy; }
+    void setIsTaintedByOpaqueObject() { m_isTaintedByOpaqueObject = true; }
+    bool isTaintedByOpaqueObject() const { return m_isTaintedByOpaqueObject; }
 
     InternalMethodType internalMethodType() const { return m_internalMethodType; }
 
@@ -293,7 +293,7 @@ private:
     CacheabilityType m_cacheability;
     PropertyType m_propertyType;
     InternalMethodType m_internalMethodType;
-    bool m_isTaintedByProxy;
+    bool m_isTaintedByOpaqueObject;
 };
 
 ALWAYS_INLINE JSValue PropertySlot::getValue(ExecState* exec, PropertyName propertyName) const
index 6ee486c..48a709d 100644 (file)
@@ -344,7 +344,7 @@ bool ProxyObject::getOwnPropertySlotCommon(ExecState* exec, PropertyName propert
         return false;
     }
     slot.disableCaching();
-    slot.setIsTaintedByProxy();
+    slot.setIsTaintedByOpaqueObject();
     switch (slot.internalMethodType()) {
     case PropertySlot::InternalMethodType::Get:
         return performGet(exec, propertyName, slot);