Changeset 244312 in webkit
- Timestamp:
- Apr 15, 2019 5:02:32 PM (5 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 15 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r244304 r244312 1 2019-04-15 Devin Rousso <drousso@apple.com> 2 3 Web Inspector: fake value descriptors for promises add a catch handler, preventing "rejectionhandled" events from being fired 4 https://bugs.webkit.org/show_bug.cgi?id=196484 5 <rdar://problem/49114725> 6 7 Reviewed by Joseph Pecoraro. 8 9 * inspector/runtime/promise-native-getter.html: Added. 10 * inspector/runtime/promise-native-getter-expected.txt: Added. 11 1 12 2019-04-15 Shawn Roberts <sroberts@apple.com> 2 13 -
trunk/Source/JavaScriptCore/ChangeLog
r244309 r244312 1 2019-04-15 Devin Rousso <drousso@apple.com> 2 3 Web Inspector: fake value descriptors for promises add a catch handler, preventing "rejectionhandled" events from being fired 4 https://bugs.webkit.org/show_bug.cgi?id=196484 5 <rdar://problem/49114725> 6 7 Reviewed by Joseph Pecoraro. 8 9 Only add a catch handler when the promise is reachable via a native getter and is known to 10 have rejected. A non-rejected promise doesn't need a catch handler, and any promise that 11 isn't reachable via a getter won't actually be reached, as `InjectedScript` doesn't call any 12 functions, instead only getting the function object itself. 13 14 * inspector/InjectedScriptSource.js: 15 (InjectedScript.prototype._propertyDescriptors.createFakeValueDescriptor): 16 17 * inspector/JSInjectedScriptHost.h: 18 * inspector/JSInjectedScriptHost.cpp: 19 (Inspector::JSInjectedScriptHost::isPromiseRejectedWithNativeGetterTypeError): Added. 20 * inspector/JSInjectedScriptHostPrototype.cpp: 21 (Inspector::JSInjectedScriptHostPrototype::finishCreation): 22 (Inspector::jsInjectedScriptHostPrototypeFunctionIsPromiseRejectedWithNativeGetterTypeError): Added. 23 24 * runtime/ErrorInstance.h: 25 (JSC::ErrorInstance::setNativeGetterTypeError): Added. 26 (JSC::ErrorInstance::isNativeGetterTypeError const): Added. 27 28 * runtime/Error.h: 29 (JSC::throwVMGetterTypeError): Added. 30 * runtime/Error.cpp: 31 (JSC::createGetterTypeError): Added. 32 (JSC::throwGetterTypeError): Added. 33 (JSC::throwDOMAttributeGetterTypeError): 34 1 35 2019-04-15 Robin Morisset <rmorisset@apple.com> 2 36 -
trunk/Source/JavaScriptCore/inspector/InjectedScriptSource.js
r243161 r244312 654 654 fakeDescriptor.symbol = symbol; 655 655 // Silence any possible unhandledrejection exceptions created from accessing a native accessor with a wrong this object. 656 if (fakeDescriptor.value instanceof Promise )656 if (fakeDescriptor.value instanceof Promise && InjectedScriptHost.isPromiseRejectedWithNativeGetterTypeError(fakeDescriptor.value)) 657 657 fakeDescriptor.value.catch(function(){}); 658 658 return fakeDescriptor; -
trunk/Source/JavaScriptCore/inspector/JSInjectedScriptHost.cpp
r239583 r244312 143 143 } 144 144 145 JSValue JSInjectedScriptHost::isPromiseRejectedWithNativeGetterTypeError(ExecState* exec) 146 { 147 VM& vm = exec->vm(); 148 auto scope = DECLARE_THROW_SCOPE(vm); 149 150 auto* promise = jsDynamicCast<JSPromise*>(vm, exec->argument(0)); 151 if (!promise || promise->status(vm) != JSPromise::Status::Rejected) 152 return throwTypeError(exec, scope, "InjectedScriptHost.isPromiseRejectedWithNativeGetterTypeError first argument must be a rejected Promise."_s); 153 154 bool result = false; 155 if (auto* errorInstance = jsDynamicCast<ErrorInstance*>(vm, promise->result(vm))) 156 result = errorInstance->isNativeGetterTypeError(); 157 return jsBoolean(result); 158 } 159 145 160 JSValue JSInjectedScriptHost::subtype(ExecState* exec) 146 161 { -
trunk/Source/JavaScriptCore/inspector/JSInjectedScriptHost.h
r239583 r244312 63 63 JSC::JSValue internalConstructorName(JSC::ExecState*); 64 64 JSC::JSValue isHTMLAllCollection(JSC::ExecState*); 65 JSC::JSValue isPromiseRejectedWithNativeGetterTypeError(JSC::ExecState*); 65 66 JSC::JSValue subtype(JSC::ExecState*); 66 67 JSC::JSValue functionDetails(JSC::ExecState*); -
trunk/Source/JavaScriptCore/inspector/JSInjectedScriptHostPrototype.cpp
r242650 r244312 44 44 static EncodedJSValue JSC_HOST_CALL jsInjectedScriptHostPrototypeFunctionInternalConstructorName(ExecState*); 45 45 static EncodedJSValue JSC_HOST_CALL jsInjectedScriptHostPrototypeFunctionIsHTMLAllCollection(ExecState*); 46 static EncodedJSValue JSC_HOST_CALL jsInjectedScriptHostPrototypeFunctionIsPromiseRejectedWithNativeGetterTypeError(ExecState*); 46 47 static EncodedJSValue JSC_HOST_CALL jsInjectedScriptHostPrototypeFunctionProxyTargetValue(ExecState*); 47 48 static EncodedJSValue JSC_HOST_CALL jsInjectedScriptHostPrototypeFunctionWeakMapSize(ExecState*); … … 68 69 JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION("internalConstructorName", jsInjectedScriptHostPrototypeFunctionInternalConstructorName, static_cast<unsigned>(PropertyAttribute::DontEnum), 1); 69 70 JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION("isHTMLAllCollection", jsInjectedScriptHostPrototypeFunctionIsHTMLAllCollection, static_cast<unsigned>(PropertyAttribute::DontEnum), 1); 71 JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION("isPromiseRejectedWithNativeGetterTypeError", jsInjectedScriptHostPrototypeFunctionIsPromiseRejectedWithNativeGetterTypeError, static_cast<unsigned>(PropertyAttribute::DontEnum), 1); 70 72 JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION("proxyTargetValue", jsInjectedScriptHostPrototypeFunctionProxyTargetValue, static_cast<unsigned>(PropertyAttribute::DontEnum), 1); 71 73 JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION("weakMapSize", jsInjectedScriptHostPrototypeFunctionWeakMapSize, static_cast<unsigned>(PropertyAttribute::DontEnum), 1); … … 119 121 } 120 122 123 EncodedJSValue JSC_HOST_CALL jsInjectedScriptHostPrototypeFunctionIsPromiseRejectedWithNativeGetterTypeError(ExecState* exec) 124 { 125 VM& vm = exec->vm(); 126 auto scope = DECLARE_THROW_SCOPE(vm); 127 128 JSValue thisValue = exec->thisValue(); 129 JSInjectedScriptHost* castedThis = jsDynamicCast<JSInjectedScriptHost*>(vm, thisValue); 130 if (!castedThis) 131 return throwVMTypeError(exec, scope); 132 133 return JSValue::encode(castedThis->isPromiseRejectedWithNativeGetterTypeError(exec)); 134 } 135 121 136 EncodedJSValue JSC_HOST_CALL jsInjectedScriptHostPrototypeFunctionProxyTargetValue(ExecState* exec) 122 137 { -
trunk/Source/JavaScriptCore/runtime/Error.cpp
r242596 r244312 124 124 } 125 125 126 JSObject* createGetterTypeError(ExecState* exec, const String& message) 127 { 128 ASSERT(!message.isEmpty()); 129 JSGlobalObject* globalObject = exec->lexicalGlobalObject(); 130 auto* error = ErrorInstance::create(exec, globalObject->vm(), globalObject->errorStructure(ErrorType::TypeError), message); 131 error->setNativeGetterTypeError(); 132 return error; 133 } 134 126 135 class FindFirstCallerFrameWithCodeblockFunctor { 127 136 public: … … 291 300 } 292 301 302 Exception* throwGetterTypeError(ExecState* exec, ThrowScope& scope, const String& message) 303 { 304 return throwException(exec, scope, createGetterTypeError(exec, message)); 305 } 306 293 307 JSValue throwDOMAttributeGetterTypeError(ExecState* exec, ThrowScope& scope, const ClassInfo* classInfo, PropertyName propertyName) 294 308 { 295 return throw TypeError(exec, scope, makeString("The ", classInfo->className, '.', String(propertyName.uid()), " getter can only be used on instances of ", classInfo->className));309 return throwGetterTypeError(exec, scope, makeString("The ", classInfo->className, '.', String(propertyName.uid()), " getter can only be used on instances of ", classInfo->className)); 296 310 } 297 311 -
trunk/Source/JavaScriptCore/runtime/Error.h
r242596 r244312 68 68 JS_EXPORT_PRIVATE JSObject* createError(ExecState*, ErrorType, const String&); 69 69 70 JSObject* createGetterTypeError(ExecState*, const String&); 71 70 72 std::unique_ptr<Vector<StackFrame>> getStackTrace(ExecState*, VM&, JSObject*, bool useCurrentFrame); 71 73 void getBytecodeOffset(ExecState*, VM&, Vector<StackFrame>*, CallFrame*&, unsigned& bytecodeOffset); … … 85 87 JS_EXPORT_PRIVATE Exception* throwSyntaxError(ExecState*, ThrowScope&, const String& errorMessage); 86 88 inline Exception* throwRangeError(ExecState* state, ThrowScope& scope, const String& errorMessage) { return throwException(state, scope, createRangeError(state, errorMessage)); } 89 90 JS_EXPORT_PRIVATE Exception* throwGetterTypeError(ExecState*, ThrowScope&, const String& errorMessage); 87 91 JS_EXPORT_PRIVATE JSValue throwDOMAttributeGetterTypeError(ExecState*, ThrowScope&, const ClassInfo*, PropertyName); 88 92 … … 95 99 inline EncodedJSValue throwVMTypeError(ExecState* exec, ThrowScope& scope, const String& errorMessage) { return JSValue::encode(throwTypeError(exec, scope, errorMessage)); } 96 100 inline EncodedJSValue throwVMRangeError(ExecState* state, ThrowScope& scope, const String& errorMessage) { return JSValue::encode(throwRangeError(state, scope, errorMessage)); } 101 inline EncodedJSValue throwVMGetterTypeError(ExecState* exec, ThrowScope& scope, const String& errorMessage) { return JSValue::encode(throwGetterTypeError(exec, scope, errorMessage)); } 97 102 inline EncodedJSValue throwVMDOMAttributeGetterTypeError(ExecState* state, ThrowScope& scope, const ClassInfo* classInfo, PropertyName propertyName) { return JSValue::encode(throwDOMAttributeGetterTypeError(state, scope, classInfo, propertyName)); } 98 103 -
trunk/Source/JavaScriptCore/runtime/ErrorInstance.h
r240965 r244312 66 66 bool isOutOfMemoryError() const { return m_outOfMemoryError; } 67 67 68 void setNativeGetterTypeError() { m_nativeGetterTypeError = true; } 69 bool isNativeGetterTypeError() const { return m_nativeGetterTypeError; } 70 68 71 JS_EXPORT_PRIVATE String sanitizedToString(ExecState*); 69 72 … … 106 109 bool m_outOfMemoryError { false }; 107 110 bool m_errorInfoMaterialized { false }; 111 bool m_nativeGetterTypeError { false }; 108 112 }; 109 113 -
trunk/Source/WebCore/ChangeLog
r244307 r244312 1 2019-04-15 Devin Rousso <drousso@apple.com> 2 3 Web Inspector: fake value descriptors for promises add a catch handler, preventing "rejectionhandled" events from being fired 4 https://bugs.webkit.org/show_bug.cgi?id=196484 5 <rdar://problem/49114725> 6 7 Reviewed by Joseph Pecoraro. 8 9 Test: inspector/runtime/promise-native-getter.html 10 11 Mark errors created from getters as being `isNativeGetterTypeError`. 12 13 * bindings/js/JSDOMExceptionHandling.cpp: 14 (WebCore::throwGetterTypeError): 15 (WebCore::rejectPromiseWithGetterTypeError): 16 (WebCore::rejectPromiseWithThisTypeError): 17 18 * bindings/js/JSDOMGlobalObject.cpp: 19 (WebCore::makeGetterTypeErrorForBuiltins): 20 21 * bindings/js/JSDOMPromiseDeferred.h: 22 * bindings/js/JSDOMPromiseDeferred.cpp: 23 (WebCore::createRejectedPromiseWithTypeError): 24 25 * Modules/streams/WritableStream.js: 26 (getter.closed): 27 (getter.ready): 28 1 29 2019-04-15 Jer Noble <jer.noble@apple.com> 2 30 -
trunk/Source/WebCore/Modules/streams/WritableStream.js
r242365 r244312 155 155 156 156 if (!@isWritableStream(this)) 157 return @Promise.@reject(@make TypeError("The WritableStream.closed getter can only be used on instances of WritableStream"));157 return @Promise.@reject(@makeGetterTypeError("WritableStream", "closed")); 158 158 159 159 return @getByIdDirectPrivate(this, "closedPromiseCapability").@promise; … … 166 166 167 167 if (!@isWritableStream(this)) 168 return @Promise.@reject(@make TypeError("The WritableStream.ready getter can only be used on instances of WritableStream"));168 return @Promise.@reject(@makeGetterTypeError("WritableStream", "ready")); 169 169 170 170 return @getByIdDirectPrivate(this, "readyPromiseCapability").@promise; -
trunk/Source/WebCore/bindings/js/JSDOMExceptionHandling.cpp
r233122 r244312 271 271 JSC::EncodedJSValue throwGetterTypeError(JSC::ExecState& state, JSC::ThrowScope& scope, const char* interfaceName, const char* attributeName) 272 272 { 273 return throwVM TypeError(&state, scope, makeGetterTypeErrorMessage(interfaceName, attributeName));273 return throwVMGetterTypeError(&state, scope, makeGetterTypeErrorMessage(interfaceName, attributeName)); 274 274 } 275 275 276 276 JSC::EncodedJSValue rejectPromiseWithGetterTypeError(JSC::ExecState& state, const char* interfaceName, const char* attributeName) 277 277 { 278 return createRejectedPromiseWithTypeError(state, makeGetterTypeErrorMessage(interfaceName, attributeName) );278 return createRejectedPromiseWithTypeError(state, makeGetterTypeErrorMessage(interfaceName, attributeName), RejectedPromiseWithTypeErrorCause::NativeGetter); 279 279 } 280 280 … … 303 303 JSC::EncodedJSValue rejectPromiseWithThisTypeError(JSC::ExecState& state, const char* interfaceName, const char* methodName) 304 304 { 305 return createRejectedPromiseWithTypeError(state, makeThisTypeErrorMessage(interfaceName, methodName) );305 return createRejectedPromiseWithTypeError(state, makeThisTypeErrorMessage(interfaceName, methodName), RejectedPromiseWithTypeErrorCause::InvalidThis); 306 306 } 307 307 -
trunk/Source/WebCore/bindings/js/JSDOMGlobalObject.cpp
r242636 r244312 101 101 auto attributeName = execState->uncheckedArgument(1).getString(execState); 102 102 scope.assertNoException(); 103 return JSValue::encode(createTypeError(execState, makeGetterTypeErrorMessage(interfaceName.utf8().data(), attributeName.utf8().data()))); 103 104 auto error = static_cast<ErrorInstance*>(createTypeError(execState, makeGetterTypeErrorMessage(interfaceName.utf8().data(), attributeName.utf8().data()))); 105 error->setNativeGetterTypeError(); 106 return JSValue::encode(error); 104 107 } 105 108 -
trunk/Source/WebCore/bindings/js/JSDOMPromiseDeferred.cpp
r239256 r244312 198 198 } 199 199 200 JSC::EncodedJSValue createRejectedPromiseWithTypeError(JSC::ExecState& state, const String& errorMessage )200 JSC::EncodedJSValue createRejectedPromiseWithTypeError(JSC::ExecState& state, const String& errorMessage, RejectedPromiseWithTypeErrorCause cause) 201 201 { 202 202 ASSERT(state.lexicalGlobalObject()); … … 205 205 auto promiseConstructor = globalObject.promiseConstructor(); 206 206 auto rejectFunction = promiseConstructor->get(&state, state.vm().propertyNames->builtinNames().rejectPrivateName()); 207 auto rejectionValue = createTypeError(&state, errorMessage); 207 auto* rejectionValue = static_cast<ErrorInstance*>(createTypeError(&state, errorMessage)); 208 if (cause == RejectedPromiseWithTypeErrorCause::NativeGetter) 209 rejectionValue->setNativeGetterTypeError(); 208 210 209 211 CallData callData; -
trunk/Source/WebCore/bindings/js/JSDOMPromiseDeferred.h
r239256 r244312 258 258 void fulfillPromiseWithArrayBuffer(Ref<DeferredPromise>&&, const void*, size_t); 259 259 WEBCORE_EXPORT void rejectPromiseWithExceptionIfAny(JSC::ExecState&, JSDOMGlobalObject&, JSC::JSPromiseDeferred&); 260 JSC::EncodedJSValue createRejectedPromiseWithTypeError(JSC::ExecState&, const String&); 260 261 enum class RejectedPromiseWithTypeErrorCause { NativeGetter, InvalidThis }; 262 JSC::EncodedJSValue createRejectedPromiseWithTypeError(JSC::ExecState&, const String&, RejectedPromiseWithTypeErrorCause); 261 263 262 264 using PromiseFunction = void(JSC::ExecState&, Ref<DeferredPromise>&&);
Note: See TracChangeset
for help on using the changeset viewer.