Title: [277224] trunk/Source/_javascript_Core
Revision
277224
Author
[email protected]
Date
2021-05-08 00:32:45 -0700 (Sat, 08 May 2021)

Log Message

Introduce JSObject::getIfPropertyExists helper
https://bugs.webkit.org/show_bug.cgi?id=225553

Reviewed by Alexey Shvayka.

Suggested by Alexey during review of r277221.
ArrayPrototype also has a "Has-guarded Get", so it's helpful for JSObject to house this functionality.

* runtime/ArrayPrototype.cpp:
(JSC::getProperty):
* runtime/ErrorInstance.cpp:
(JSC::ErrorInstance::finishCreation):
* runtime/JSObject.h:
* runtime/JSObjectInlines.h:
(JSC::JSObject::getIfPropertyExists):

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (277223 => 277224)


--- trunk/Source/_javascript_Core/ChangeLog	2021-05-08 04:32:51 UTC (rev 277223)
+++ trunk/Source/_javascript_Core/ChangeLog	2021-05-08 07:32:45 UTC (rev 277224)
@@ -1,3 +1,21 @@
+2021-05-08  Ross Kirsling  <[email protected]>
+
+        Introduce JSObject::getIfPropertyExists helper
+        https://bugs.webkit.org/show_bug.cgi?id=225553
+
+        Reviewed by Alexey Shvayka.
+
+        Suggested by Alexey during review of r277221.
+        ArrayPrototype also has a "Has-guarded Get", so it's helpful for JSObject to house this functionality.
+
+        * runtime/ArrayPrototype.cpp:
+        (JSC::getProperty):
+        * runtime/ErrorInstance.cpp:
+        (JSC::ErrorInstance::finishCreation):
+        * runtime/JSObject.h:
+        * runtime/JSObjectInlines.h:
+        (JSC::JSObject::getIfPropertyExists):
+
 2021-05-07  Ross Kirsling  <[email protected]>
 
         [JSC] Error#cause must recognize explicit undefined

Modified: trunk/Source/_javascript_Core/runtime/ArrayPrototype.cpp (277223 => 277224)


--- trunk/Source/_javascript_Core/runtime/ArrayPrototype.cpp	2021-05-08 04:32:51 UTC (rev 277223)
+++ trunk/Source/_javascript_Core/runtime/ArrayPrototype.cpp	2021-05-08 07:32:45 UTC (rev 277224)
@@ -147,22 +147,14 @@
 {
     VM& vm = globalObject->vm();
     auto scope = DECLARE_THROW_SCOPE(vm);
-    
+
     if (JSValue result = object->tryGetIndexQuickly(index))
         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 an opaque objects (ProxyObject and JSModuleNamespaceObject)
-    // somewhere in the prototype chain.
-    PropertySlot slot(object, PropertySlot::InternalMethodType::HasProperty);
-    bool hasProperty = object->getPropertySlot(globalObject, index, slot);
-    EXCEPTION_ASSERT(!scope.exception() || !hasProperty);
-    if (!hasProperty)
-        return { };
-    if (UNLIKELY(slot.isTaintedByOpaqueObject()))
-        RELEASE_AND_RETURN(scope, object->get(globalObject, index));
 
-    RELEASE_AND_RETURN(scope, slot.getValue(globalObject, index));
+    // Don't return undefined if the property is not found.
+    auto property = object->getIfPropertyExists(globalObject, Identifier::from(vm, index));
+    RETURN_IF_EXCEPTION(scope, { });
+    return property.valueOr(JSValue());
 }
 
 static ALWAYS_INLINE void setLength(JSGlobalObject* globalObject, VM& vm, JSObject* obj, uint64_t value)

Modified: trunk/Source/_javascript_Core/runtime/ErrorInstance.cpp (277223 => 277224)


--- trunk/Source/_javascript_Core/runtime/ErrorInstance.cpp	2021-05-08 04:32:51 UTC (rev 277223)
+++ trunk/Source/_javascript_Core/runtime/ErrorInstance.cpp	2021-05-08 07:32:45 UTC (rev 277224)
@@ -135,22 +135,12 @@
     if (!messageWithSource.isNull())
         putDirect(vm, vm.propertyNames->message, jsString(vm, messageWithSource), static_cast<unsigned>(PropertyAttribute::DontEnum));
 
-    // Since `throw undefined;` is valid, the spec specially recognizes the case where `cause` is an explicit undefined.
     if (options.isObject()) {
-        auto object = asObject(options);
-
-        PropertySlot slot(object, PropertySlot::InternalMethodType::HasProperty);
-        bool hasProperty = object->getPropertySlot(globalObject, vm.propertyNames->cause, slot);
+        // Since `throw undefined;` is valid, we need to distinguish the case where `cause` is an explicit undefined.
+        auto cause = asObject(options)->getIfPropertyExists(globalObject, vm.propertyNames->cause);
         RETURN_IF_EXCEPTION(scope, void());
-
-        if (hasProperty) {
-            JSValue cause = UNLIKELY(slot.isTaintedByOpaqueObject())
-                ? object->get(globalObject, vm.propertyNames->cause)
-                : slot.getValue(globalObject, vm.propertyNames->cause);
-            RETURN_IF_EXCEPTION(scope, void());
-
-            putDirect(vm, vm.propertyNames->cause, cause, static_cast<unsigned>(PropertyAttribute::DontEnum));
-        }
+        if (cause)
+            putDirect(vm, vm.propertyNames->cause, cause.value(), static_cast<unsigned>(PropertyAttribute::DontEnum));
     }
 }
 

Modified: trunk/Source/_javascript_Core/runtime/JSObject.h (277223 => 277224)


--- trunk/Source/_javascript_Core/runtime/JSObject.h	2021-05-08 04:32:51 UTC (rev 277223)
+++ trunk/Source/_javascript_Core/runtime/JSObject.h	2021-05-08 07:32:45 UTC (rev 277224)
@@ -162,6 +162,8 @@
     template<typename CallbackWhenNoException> typename std::result_of<CallbackWhenNoException(bool, PropertySlot&)>::type getPropertySlot(JSGlobalObject*, PropertyName, CallbackWhenNoException) const;
     template<typename CallbackWhenNoException> typename std::result_of<CallbackWhenNoException(bool, PropertySlot&)>::type getPropertySlot(JSGlobalObject*, PropertyName, PropertySlot&, CallbackWhenNoException) const;
 
+    Optional<JSValue> getIfPropertyExists(JSGlobalObject*, PropertyName);
+
 private:
     static bool getOwnPropertySlotImpl(JSObject*, JSGlobalObject*, PropertyName, PropertySlot&);
 public:

Modified: trunk/Source/_javascript_Core/runtime/JSObjectInlines.h (277223 => 277224)


--- trunk/Source/_javascript_Core/runtime/JSObjectInlines.h	2021-05-08 04:32:51 UTC (rev 277223)
+++ trunk/Source/_javascript_Core/runtime/JSObjectInlines.h	2021-05-08 07:32:45 UTC (rev 277224)
@@ -191,6 +191,23 @@
     return JSObject::getOwnPropertySlot(this, globalObject, propertyName, slot);
 }
 
+inline Optional<JSValue> JSObject::getIfPropertyExists(JSGlobalObject* globalObject, PropertyName propertyName)
+{
+    VM& vm = globalObject->vm();
+    auto scope = DECLARE_THROW_SCOPE(vm);
+
+    PropertySlot slot(this, PropertySlot::InternalMethodType::HasProperty);
+    bool hasProperty = getPropertySlot(globalObject, propertyName, slot);
+    EXCEPTION_ASSERT_UNUSED(scope, !scope.exception() || !hasProperty);
+
+    if (!hasProperty)
+        return WTF::nullopt;
+
+    return UNLIKELY(slot.isTaintedByOpaqueObject())
+        ? get(globalObject, propertyName)
+        : slot.getValue(globalObject, propertyName);
+}
+
 inline bool JSObject::mayInterceptIndexedAccesses(VM& vm)
 {
     return structure(vm)->mayInterceptIndexedAccesses();
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to