Changeset 258664 in webkit
- Timestamp:
- Mar 18, 2020 3:27:22 PM (4 years ago)
- Location:
- trunk
- Files:
-
- 1 added
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JSTests/ChangeLog
r258531 r258664 1 2020-03-18 Yusuke Suzuki <ysuzuki@apple.com> 2 3 Add a way to mark a rejected promise as handled 4 https://bugs.webkit.org/show_bug.cgi?id=209241 5 6 Reviewed by Michael Saboff. 7 8 * stress/reject-as-handled.js: Added. 9 (shouldBe): 10 (set new): 11 1 12 2020-03-16 Keith Miller <keith_miller@apple.com> 2 13 -
trunk/Source/JavaScriptCore/ChangeLog
r258603 r258664 1 2020-03-18 Yusuke Suzuki <ysuzuki@apple.com> 2 3 Add a way to mark a rejected promise as handled 4 https://bugs.webkit.org/show_bug.cgi?id=209241 5 6 Reviewed by Michael Saboff. 7 8 Some of WebCore promise implementations (WebAnimation etc.) want to reject promise 9 as handled state to suppress UnhandledPromiseRejection tracking. For example, a 10 lot of WebCore implementations expose Promise DOM attributes which will be rejected 11 at some conditions. But we do not want to force users setting a handler for each such an 12 attribute. 13 14 This patch adds `JSPromise::rejectAsHandled` C++ function. This simply sets isHandledFlag 15 before executing `JSPromise::reject` if we are not calling a reject function yet. 16 17 * runtime/JSPromise.cpp: 18 (JSC::JSPromise::rejectAsHandled): 19 * runtime/JSPromise.h: 20 * tools/JSDollarVM.cpp: 21 (JSC::functionRejectPromiseAsHandled): 22 (JSC::JSDollarVM::finishCreation): 23 1 24 2020-03-17 Yusuke Suzuki <ysuzuki@apple.com> 2 25 -
trunk/Source/JavaScriptCore/runtime/JSPromise.cpp
r251691 r258664 183 183 } 184 184 185 void JSPromise::rejectAsHandled(JSGlobalObject* lexicalGlobalObject, JSValue value) 186 { 187 // Setting isHandledFlag before calling reject since this removes round-trip between JSC and PromiseRejectionTracker, and it does not show an user-observable behavior. 188 VM& vm = lexicalGlobalObject->vm(); 189 uint32_t flags = this->flags(); 190 if (!(flags & isFirstResolvingFunctionCalledFlag)) 191 internalField(static_cast<unsigned>(Field::Flags)).set(vm, this, jsNumber(flags | isHandledFlag)); 192 reject(lexicalGlobalObject, value); 193 } 194 185 195 void JSPromise::reject(JSGlobalObject* lexicalGlobalObject, Exception* reason) 186 196 { … … 188 198 } 189 199 200 void JSPromise::rejectAsHandled(JSGlobalObject* lexicalGlobalObject, Exception* reason) 201 { 202 rejectAsHandled(lexicalGlobalObject, reason->value()); 203 } 204 190 205 } // namespace JSC -
trunk/Source/JavaScriptCore/runtime/JSPromise.h
r253007 r258664 69 69 JS_EXPORT_PRIVATE void resolve(JSGlobalObject*, JSValue); 70 70 JS_EXPORT_PRIVATE void reject(JSGlobalObject*, JSValue); 71 JS_EXPORT_PRIVATE void rejectAsHandled(JSGlobalObject*, JSValue); 71 72 JS_EXPORT_PRIVATE void reject(JSGlobalObject*, Exception*); 73 JS_EXPORT_PRIVATE void rejectAsHandled(JSGlobalObject*, Exception*); 72 74 73 75 struct DeferredData { -
trunk/Source/JavaScriptCore/tools/JSDollarVM.cpp
r258059 r258664 2930 2930 } 2931 2931 2932 static EncodedJSValue JSC_HOST_CALL functionRejectPromiseAsHandled(JSGlobalObject* globalObject, CallFrame* callFrame) 2933 { 2934 JSPromise* promise = jsCast<JSPromise*>(callFrame->uncheckedArgument(0)); 2935 JSValue reason = callFrame->uncheckedArgument(1); 2936 promise->rejectAsHandled(globalObject, reason); 2937 return JSValue::encode(jsUndefined()); 2938 } 2939 2932 2940 void JSDollarVM::finishCreation(VM& vm) 2933 2941 { … … 3064 3072 3065 3073 addFunction(vm, "hasOwnLengthProperty", functionHasOwnLengthProperty, 1); 3074 addFunction(vm, "rejectPromiseAsHandled", functionRejectPromiseAsHandled, 1); 3066 3075 3067 3076 m_objectDoingSideEffectPutWithoutCorrectSlotStatusStructure.set(vm, this, ObjectDoingSideEffectPutWithoutCorrectSlotStatus::createStructure(vm, globalObject, jsNull())); -
trunk/Source/WebCore/ChangeLog
r258663 r258664 1 2020-03-18 Yusuke Suzuki <ysuzuki@apple.com> 2 3 Add a way to mark a rejected promise as handled 4 https://bugs.webkit.org/show_bug.cgi?id=209241 5 6 Reviewed by Michael Saboff. 7 8 This adds an interface using JSPromise::rejectAsHandled to DOMPromise classes. 9 10 * bindings/js/DOMPromiseProxy.h: 11 (WebCore::DOMPromiseProxy<IDLType>::reject): 12 (WebCore::DOMPromiseProxy<IDLVoid>::reject): 13 (WebCore::DOMPromiseProxyWithResolveCallback<IDLType>::reject): 14 * bindings/js/JSDOMPromiseDeferred.cpp: 15 (WebCore::DeferredPromise::callFunction): 16 (WebCore::DeferredPromise::reject): 17 * bindings/js/JSDOMPromiseDeferred.h: 18 (WebCore::DeferredPromise::reject): 19 (WebCore::DeferredPromise::rejectWithCallback): 20 (WebCore::DOMPromiseDeferredBase::reject): 21 (WebCore::DOMPromiseDeferredBase::rejectType): 22 1 23 2020-03-18 youenn fablet <youenn@apple.com> 2 24 -
trunk/Source/WebCore/bindings/js/DOMPromiseProxy.h
r251425 r258664 52 52 void resolve(typename IDLType::ParameterType); 53 53 void resolveWithNewlyCreated(typename IDLType::ParameterType); 54 void reject(Exception );54 void reject(Exception, RejectAsHandled = RejectAsHandled::No); 55 55 56 56 private: … … 73 73 74 74 void resolve(); 75 void reject(Exception );75 void reject(Exception, RejectAsHandled = RejectAsHandled::No); 76 76 77 77 private: … … 103 103 void resolve(typename IDLType::ParameterType); 104 104 void resolveWithNewlyCreated(typename IDLType::ParameterType); 105 void reject(Exception );105 void reject(Exception, RejectAsHandled = RejectAsHandled::No); 106 106 107 107 private: … … 174 174 175 175 template<typename IDLType> 176 inline void DOMPromiseProxy<IDLType>::reject(Exception exception )176 inline void DOMPromiseProxy<IDLType>::reject(Exception exception, RejectAsHandled rejectAsHandled) 177 177 { 178 178 ASSERT(!m_valueOrException); … … 180 180 m_valueOrException = ExceptionOr<Value> { WTFMove(exception) }; 181 181 for (auto& deferredPromise : m_deferredPromises) 182 deferredPromise->reject(m_valueOrException->exception() );182 deferredPromise->reject(m_valueOrException->exception(), rejectAsHandled); 183 183 } 184 184 … … 230 230 } 231 231 232 inline void DOMPromiseProxy<IDLVoid>::reject(Exception exception )232 inline void DOMPromiseProxy<IDLVoid>::reject(Exception exception, RejectAsHandled rejectAsHandled) 233 233 { 234 234 ASSERT(!m_valueOrException); 235 235 m_valueOrException = ExceptionOr<void> { WTFMove(exception) }; 236 236 for (auto& deferredPromise : m_deferredPromises) 237 deferredPromise->reject(m_valueOrException->exception() );237 deferredPromise->reject(m_valueOrException->exception(), rejectAsHandled); 238 238 } 239 239 … … 313 313 314 314 template<typename IDLType> 315 inline void DOMPromiseProxyWithResolveCallback<IDLType>::reject(Exception exception )315 inline void DOMPromiseProxyWithResolveCallback<IDLType>::reject(Exception exception, RejectAsHandled rejectAsHandled) 316 316 { 317 317 ASSERT(!m_valueOrException); … … 319 319 m_valueOrException = ExceptionOr<void> { WTFMove(exception) }; 320 320 for (auto& deferredPromise : m_deferredPromises) 321 deferredPromise->reject(m_valueOrException->exception() );322 } 323 324 } 321 deferredPromise->reject(m_valueOrException->exception(), rejectAsHandled); 322 } 323 324 } -
trunk/Source/WebCore/bindings/js/JSDOMPromiseDeferred.cpp
r252607 r258664 72 72 deferred()->reject(&lexicalGlobalObject, resolution); 73 73 break; 74 case ResolveMode::RejectAsHandled: 75 deferred()->rejectAsHandled(&lexicalGlobalObject, resolution); 76 break; 74 77 } 75 78 … … 93 96 } 94 97 95 void DeferredPromise::reject( )96 { 97 if (shouldIgnoreRequestToFulfill()) 98 return; 99 100 ASSERT(deferred()); 101 ASSERT(m_globalObject); 102 auto& lexicalGlobalObject = *m_globalObject; 103 JSC::JSLockHolder locker(&lexicalGlobalObject); 104 reject(lexicalGlobalObject, JSC::jsUndefined() );105 } 106 107 void DeferredPromise::reject(std::nullptr_t )108 { 109 if (shouldIgnoreRequestToFulfill()) 110 return; 111 112 ASSERT(deferred()); 113 ASSERT(m_globalObject); 114 auto& lexicalGlobalObject = *m_globalObject; 115 JSC::JSLockHolder locker(&lexicalGlobalObject); 116 reject(lexicalGlobalObject, JSC::jsNull() );117 } 118 119 void DeferredPromise::reject(Exception exception )98 void DeferredPromise::reject(RejectAsHandled rejectAsHandled) 99 { 100 if (shouldIgnoreRequestToFulfill()) 101 return; 102 103 ASSERT(deferred()); 104 ASSERT(m_globalObject); 105 auto& lexicalGlobalObject = *m_globalObject; 106 JSC::JSLockHolder locker(&lexicalGlobalObject); 107 reject(lexicalGlobalObject, JSC::jsUndefined(), rejectAsHandled); 108 } 109 110 void DeferredPromise::reject(std::nullptr_t, RejectAsHandled rejectAsHandled) 111 { 112 if (shouldIgnoreRequestToFulfill()) 113 return; 114 115 ASSERT(deferred()); 116 ASSERT(m_globalObject); 117 auto& lexicalGlobalObject = *m_globalObject; 118 JSC::JSLockHolder locker(&lexicalGlobalObject); 119 reject(lexicalGlobalObject, JSC::jsNull(), rejectAsHandled); 120 } 121 122 void DeferredPromise::reject(Exception exception, RejectAsHandled rejectAsHandled) 120 123 { 121 124 if (shouldIgnoreRequestToFulfill()) … … 135 138 scope.clearException(); 136 139 137 reject<IDLAny>(error );140 reject<IDLAny>(error, rejectAsHandled); 138 141 return; 139 142 } … … 146 149 } 147 150 148 reject(lexicalGlobalObject, error );149 } 150 151 void DeferredPromise::reject(ExceptionCode ec, const String& message )151 reject(lexicalGlobalObject, error, rejectAsHandled); 152 } 153 154 void DeferredPromise::reject(ExceptionCode ec, const String& message, RejectAsHandled rejectAsHandled) 152 155 { 153 156 if (shouldIgnoreRequestToFulfill()) … … 167 170 scope.clearException(); 168 171 169 reject<IDLAny>(error );172 reject<IDLAny>(error, rejectAsHandled); 170 173 return; 171 174 } … … 179 182 180 183 181 reject(lexicalGlobalObject, error );182 } 183 184 void DeferredPromise::reject(const JSC::PrivateName& privateName )184 reject(lexicalGlobalObject, error, rejectAsHandled); 185 } 186 187 void DeferredPromise::reject(const JSC::PrivateName& privateName, RejectAsHandled rejectAsHandled) 185 188 { 186 189 if (shouldIgnoreRequestToFulfill()) … … 191 194 JSC::JSGlobalObject* lexicalGlobalObject = m_globalObject.get(); 192 195 JSC::JSLockHolder locker(lexicalGlobalObject); 193 reject(*lexicalGlobalObject, JSC::Symbol::create(lexicalGlobalObject->vm(), privateName.uid()) );196 reject(*lexicalGlobalObject, JSC::Symbol::create(lexicalGlobalObject->vm(), privateName.uid()), rejectAsHandled); 194 197 } 195 198 -
trunk/Source/WebCore/bindings/js/JSDOMPromiseDeferred.h
r252646 r258664 37 37 38 38 class JSDOMWindow; 39 enum class RejectAsHandled : uint8_t { No, Yes }; 39 40 40 41 class DeferredPromise : public DOMGuarded<JSC::JSPromise> { … … 110 111 111 112 template<class IDLType> 112 void reject(typename IDLType::ParameterType value )113 { 114 if (shouldIgnoreRequestToFulfill()) 115 return; 116 117 ASSERT(deferred()); 118 ASSERT(globalObject()); 119 JSC::JSGlobalObject* lexicalGlobalObject = globalObject(); 120 JSC::JSLockHolder locker(lexicalGlobalObject); 121 reject(*lexicalGlobalObject, toJS<IDLType>(*lexicalGlobalObject, *globalObject(), std::forward<typename IDLType::ParameterType>(value)) );122 } 123 124 void reject( );125 void reject(std::nullptr_t );126 void reject(Exception );127 WEBCORE_EXPORT void reject(ExceptionCode, const String& = { } );128 void reject(const JSC::PrivateName& );113 void reject(typename IDLType::ParameterType value, RejectAsHandled rejectAsHandled = RejectAsHandled::No) 114 { 115 if (shouldIgnoreRequestToFulfill()) 116 return; 117 118 ASSERT(deferred()); 119 ASSERT(globalObject()); 120 JSC::JSGlobalObject* lexicalGlobalObject = globalObject(); 121 JSC::JSLockHolder locker(lexicalGlobalObject); 122 reject(*lexicalGlobalObject, toJS<IDLType>(*lexicalGlobalObject, *globalObject(), std::forward<typename IDLType::ParameterType>(value)), rejectAsHandled); 123 } 124 125 void reject(RejectAsHandled = RejectAsHandled::No); 126 void reject(std::nullptr_t, RejectAsHandled = RejectAsHandled::No); 127 void reject(Exception, RejectAsHandled = RejectAsHandled::No); 128 WEBCORE_EXPORT void reject(ExceptionCode, const String& = { }, RejectAsHandled = RejectAsHandled::No); 129 void reject(const JSC::PrivateName&, RejectAsHandled = RejectAsHandled::No); 129 130 130 131 template<typename Callback> … … 142 143 143 144 template<typename Callback> 144 void rejectWithCallback(Callback callback )145 { 146 if (shouldIgnoreRequestToFulfill()) 147 return; 148 149 ASSERT(deferred()); 150 ASSERT(globalObject()); 151 JSC::JSGlobalObject* lexicalGlobalObject = globalObject(); 152 JSC::JSLockHolder locker(lexicalGlobalObject); 153 reject(*lexicalGlobalObject, callback(*globalObject()) );145 void rejectWithCallback(Callback callback, RejectAsHandled rejectAsHandled = RejectAsHandled::No) 146 { 147 if (shouldIgnoreRequestToFulfill()) 148 return; 149 150 ASSERT(deferred()); 151 ASSERT(globalObject()); 152 JSC::JSGlobalObject* lexicalGlobalObject = globalObject(); 153 JSC::JSLockHolder locker(lexicalGlobalObject); 154 reject(*lexicalGlobalObject, callback(*globalObject()), rejectAsHandled); 154 155 } 155 156 … … 169 170 JSC::JSPromise* deferred() const { return guarded(); } 170 171 171 enum class ResolveMode { Resolve, Reject };172 enum class ResolveMode { Resolve, Reject, RejectAsHandled }; 172 173 WEBCORE_EXPORT void callFunction(JSC::JSGlobalObject&, ResolveMode, JSC::JSValue resolution); 173 174 174 175 void resolve(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue resolution) { callFunction(lexicalGlobalObject, ResolveMode::Resolve, resolution); } 175 void reject(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue resolution) { callFunction(lexicalGlobalObject, ResolveMode::Reject, resolution); } 176 void reject(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue resolution, RejectAsHandled rejectAsHandled) 177 { 178 callFunction(lexicalGlobalObject, rejectAsHandled == RejectAsHandled::Yes ? ResolveMode::RejectAsHandled : ResolveMode::Reject, resolution); 179 } 176 180 177 181 Mode m_mode; … … 208 212 } 209 213 210 void reject( )211 { 212 m_promise->reject( );214 void reject(RejectAsHandled rejectAsHandled = RejectAsHandled::No) 215 { 216 m_promise->reject(rejectAsHandled); 213 217 } 214 218 … … 220 224 221 225 template<typename IDLType> 222 void rejectType(typename IDLType::ParameterType value )223 { 224 m_promise->reject<IDLType>(std::forward<typename IDLType::ParameterType>(value) );226 void rejectType(typename IDLType::ParameterType value, RejectAsHandled rejectAsHandled = RejectAsHandled::No) 227 { 228 m_promise->reject<IDLType>(std::forward<typename IDLType::ParameterType>(value), rejectAsHandled); 225 229 } 226 230
Note: See TracChangeset
for help on using the changeset viewer.