Title: [277221] trunk
Revision
277221
Author
ross.kirsl...@sony.com
Date
2021-05-07 18:26:31 -0700 (Fri, 07 May 2021)

Log Message

[JSC] Error#cause must recognize explicit undefined
https://bugs.webkit.org/show_bug.cgi?id=225535

Reviewed by Alexey Shvayka.

JSTests:

* test262/config.yaml:
Re-enable tests for this feature; they were all failing due to this quirk.

Source/_javascript_Core:

Error#cause is specified such that `new Error(message, {})` and `new Error(message, { cause: undefined })`
are not the same -- namely, the latter should create a property descriptor with an undefined `value`.

This would seem absurd, but the reason is because the `cause` field is meant to store a thrown object,
and `throw undefined;` is valid code.

In aligning our implementation with the spec, this patch also consolidates the relevant logic in one place
(ErrorInstance::finishCreation) to minimize confusion.

* runtime/AggregateError.cpp:
(JSC::createAggregateError):
* runtime/ErrorInstance.cpp:
(JSC::ErrorInstance::create):
(JSC::ErrorInstance::finishCreation):
* runtime/ErrorInstance.h:
(JSC::ErrorInstance::create):

Modified Paths

Diff

Modified: trunk/JSTests/ChangeLog (277220 => 277221)


--- trunk/JSTests/ChangeLog	2021-05-08 01:08:08 UTC (rev 277220)
+++ trunk/JSTests/ChangeLog	2021-05-08 01:26:31 UTC (rev 277221)
@@ -1,5 +1,15 @@
 2021-05-07  Ross Kirsling  <ross.kirsl...@sony.com>
 
+        [JSC] Error#cause must recognize explicit undefined
+        https://bugs.webkit.org/show_bug.cgi?id=225535
+
+        Reviewed by Alexey Shvayka.
+
+        * test262/config.yaml:
+        Re-enable tests for this feature; they were all failing due to this quirk.
+
+2021-05-07  Ross Kirsling  <ross.kirsl...@sony.com>
+
         Update test262 (2021.05.07)
         https://bugs.webkit.org/show_bug.cgi?id=225536
 

Modified: trunk/JSTests/test262/config.yaml (277220 => 277221)


--- trunk/JSTests/test262/config.yaml	2021-05-08 01:08:08 UTC (rev 277220)
+++ trunk/JSTests/test262/config.yaml	2021-05-08 01:26:31 UTC (rev 277221)
@@ -8,6 +8,7 @@
   class-static-fields-public: usePublicStaticClassFields
   class-static-fields-private: usePrivateStaticClassFields
   class-static-methods-private: usePrivateMethods
+  error-cause: useErrorCause
   Intl.DateTimeFormat-dayPeriod: useIntlDateTimeFormatDayPeriod
   SharedArrayBuffer: useSharedArrayBuffer
   Atomics: useSharedArrayBuffer
@@ -24,8 +25,6 @@
     - cleanupSome
     # https://bugs.webkit.org/show_bug.cgi?id=221093
     - class-fields-private-in
-    # https://bugs.webkit.org/show_bug.cgi?id=225535
-    - error-cause
   paths:
   files:
     # Slightly different formatting. We should update test262 side.

Modified: trunk/Source/_javascript_Core/ChangeLog (277220 => 277221)


--- trunk/Source/_javascript_Core/ChangeLog	2021-05-08 01:08:08 UTC (rev 277220)
+++ trunk/Source/_javascript_Core/ChangeLog	2021-05-08 01:26:31 UTC (rev 277221)
@@ -1,3 +1,27 @@
+2021-05-07  Ross Kirsling  <ross.kirsl...@sony.com>
+
+        [JSC] Error#cause must recognize explicit undefined
+        https://bugs.webkit.org/show_bug.cgi?id=225535
+
+        Reviewed by Alexey Shvayka.
+
+        Error#cause is specified such that `new Error(message, {})` and `new Error(message, { cause: undefined })`
+        are not the same -- namely, the latter should create a property descriptor with an undefined `value`.
+
+        This would seem absurd, but the reason is because the `cause` field is meant to store a thrown object,
+        and `throw undefined;` is valid code.
+
+        In aligning our implementation with the spec, this patch also consolidates the relevant logic in one place
+        (ErrorInstance::finishCreation) to minimize confusion.
+
+        * runtime/AggregateError.cpp:
+        (JSC::createAggregateError):
+        * runtime/ErrorInstance.cpp:
+        (JSC::ErrorInstance::create):
+        (JSC::ErrorInstance::finishCreation):
+        * runtime/ErrorInstance.h:
+        (JSC::ErrorInstance::create):
+
 2021-05-06  Chris Dumez  <cdu...@apple.com>
 
         Port Filesystem::fileMetadata() & Filesystem::getFileModificationTime() to std::filesystem

Modified: trunk/Source/_javascript_Core/runtime/AggregateError.cpp (277220 => 277221)


--- trunk/Source/_javascript_Core/runtime/AggregateError.cpp	2021-05-08 01:08:08 UTC (rev 277220)
+++ trunk/Source/_javascript_Core/runtime/AggregateError.cpp	2021-05-08 01:26:31 UTC (rev 277221)
@@ -37,12 +37,6 @@
 {
     auto scope = DECLARE_THROW_SCOPE(vm);
 
-    String messageString = message.isUndefined() ? String() : message.toWTFString(globalObject);
-    RETURN_IF_EXCEPTION(scope, nullptr);
-
-    JSValue cause = !options.isObject() ? jsUndefined() : options.get(globalObject, vm.propertyNames->cause);
-    RETURN_IF_EXCEPTION(scope, nullptr);
-
     MarkedArgumentBuffer errorsList;
     forEachInIterable(globalObject, errors, [&] (VM&, JSGlobalObject*, JSValue nextValue) {
         errorsList.append(nextValue);
@@ -54,7 +48,7 @@
     auto* array = constructArray(globalObject, static_cast<ArrayAllocationProfile*>(nullptr), errorsList);
     RETURN_IF_EXCEPTION(scope, nullptr);
 
-    auto* error = ErrorInstance::create(globalObject, vm, structure, messageString, cause, appender, type, ErrorType::AggregateError, useCurrentFrame);
+    auto* error = ErrorInstance::create(globalObject, structure, message, options, appender, type, ErrorType::AggregateError, useCurrentFrame);
     error->putDirect(vm, vm.propertyNames->errors, array, static_cast<unsigned>(PropertyAttribute::DontEnum));
     return error;
 }

Modified: trunk/Source/_javascript_Core/runtime/ErrorInstance.cpp (277220 => 277221)


--- trunk/Source/_javascript_Core/runtime/ErrorInstance.cpp	2021-05-08 01:08:08 UTC (rev 277220)
+++ trunk/Source/_javascript_Core/runtime/ErrorInstance.cpp	2021-05-08 01:26:31 UTC (rev 277221)
@@ -52,10 +52,7 @@
     String messageString = message.isUndefined() ? String() : message.toWTFString(globalObject);
     RETURN_IF_EXCEPTION(scope, nullptr);
 
-    JSValue cause = !options.isObject() ? jsUndefined() : options.get(globalObject, vm.propertyNames->cause);
-    RETURN_IF_EXCEPTION(scope, nullptr);
-
-    return create(globalObject, vm, structure, messageString, cause, appender, type, errorType, useCurrentFrame);
+    return create(globalObject, vm, structure, messageString, options, appender, type, errorType, useCurrentFrame);
 }
 
 static String appendSourceToErrorMessage(CallFrame* callFrame, ErrorInstance* exception, BytecodeIndex bytecodeIndex, const String& message)
@@ -110,10 +107,11 @@
     return appender(message, codeBlock->source().provider()->getRange(start, stop).toString(), type, ErrorInstance::FoundApproximateSource);
 }
 
-void ErrorInstance::finishCreation(VM& vm, JSGlobalObject* globalObject, const String& message, JSValue cause, SourceAppender appender, RuntimeType type, bool useCurrentFrame)
+void ErrorInstance::finishCreation(VM& vm, JSGlobalObject* globalObject, const String& message, JSValue options, SourceAppender appender, RuntimeType type, bool useCurrentFrame)
 {
     Base::finishCreation(vm);
     ASSERT(inherits(vm, info()));
+    auto scope = DECLARE_THROW_SCOPE(vm);
 
     m_sourceAppender = appender;
     m_runtimeTypeForCause = type;
@@ -137,8 +135,23 @@
     if (!messageWithSource.isNull())
         putDirect(vm, vm.propertyNames->message, jsString(vm, messageWithSource), static_cast<unsigned>(PropertyAttribute::DontEnum));
 
-    if (!cause.isUndefined())
-        putDirect(vm, vm.propertyNames->cause, cause, 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);
+        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));
+        }
+    }
 }
 
 // Based on ErrorPrototype's errorProtoFuncToString(), but is modified to

Modified: trunk/Source/_javascript_Core/runtime/ErrorInstance.h (277220 => 277221)


--- trunk/Source/_javascript_Core/runtime/ErrorInstance.h	2021-05-08 01:08:08 UTC (rev 277220)
+++ trunk/Source/_javascript_Core/runtime/ErrorInstance.h	2021-05-08 01:26:31 UTC (rev 277221)
@@ -54,10 +54,10 @@
         return Structure::create(vm, globalObject, prototype, TypeInfo(ErrorInstanceType, StructureFlags), info());
     }
 
-    static ErrorInstance* create(JSGlobalObject* globalObject, VM& vm, Structure* structure, const String& message, JSValue cause, SourceAppender appender = nullptr, RuntimeType type = TypeNothing, ErrorType errorType = ErrorType::Error, bool useCurrentFrame = true)
+    static ErrorInstance* create(JSGlobalObject* globalObject, VM& vm, Structure* structure, const String& message, JSValue options, SourceAppender appender = nullptr, RuntimeType type = TypeNothing, ErrorType errorType = ErrorType::Error, bool useCurrentFrame = true)
     {
         ErrorInstance* instance = new (NotNull, allocateCell<ErrorInstance>(vm.heap)) ErrorInstance(vm, structure, errorType);
-        instance->finishCreation(vm, globalObject, message, cause, appender, type, useCurrentFrame);
+        instance->finishCreation(vm, globalObject, message, options, appender, type, useCurrentFrame);
         return instance;
     }
 
@@ -94,7 +94,7 @@
 protected:
     explicit ErrorInstance(VM&, Structure*, ErrorType);
 
-    void finishCreation(VM&, JSGlobalObject*, const String& message, JSValue cause, SourceAppender = nullptr, RuntimeType = TypeNothing, bool useCurrentFrame = true);
+    void finishCreation(VM&, JSGlobalObject*, const String& message, JSValue options, SourceAppender = nullptr, RuntimeType = TypeNothing, bool useCurrentFrame = true);
 
     static bool getOwnPropertySlot(JSObject*, JSGlobalObject*, PropertyName, PropertySlot&);
     static void getOwnSpecialPropertyNames(JSObject*, JSGlobalObject*, PropertyNameArray&, DontEnumPropertiesMode);
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to