WebKit Bugzilla
New
Browse
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
RESOLVED FIXED
214924
CodeGeneratorJS should release the throwScope before doing a void call at end of a function.
https://bugs.webkit.org/show_bug.cgi?id=214924
Summary
CodeGeneratorJS should release the throwScope before doing a void call at end...
Mark Lam
Reported
2020-07-29 10:18:36 PDT
<
rdar://problem/66272080
>
Attachments
proposed patch.
(112.16 KB, patch)
2020-07-29 10:26 PDT
,
Mark Lam
cdumez
: review+
Details
Formatted Diff
Diff
View All
Add attachment
proposed patch, testcase, etc.
Mark Lam
Comment 1
2020-07-29 10:26:04 PDT
Created
attachment 405472
[details]
proposed patch.
Chris Dumez
Comment 2
2020-07-29 10:33:40 PDT
Comment on
attachment 405472
[details]
proposed patch. View in context:
https://bugs.webkit.org/attachment.cgi?id=405472&action=review
> Source/WebCore/ChangeLog:3 > + CodeGeneratorJS should release the throwScope before doing a void call at end of a function.
Could you explain in the ChangeLog why?
Mark Lam
Comment 3
2020-07-29 10:39:49 PDT
(In reply to Chris Dumez from
comment #2
)
> Comment on
attachment 405472
[details]
> proposed patch. > > View in context: >
https://bugs.webkit.org/attachment.cgi?id=405472&action=review
> > > Source/WebCore/ChangeLog:3 > > + CodeGeneratorJS should release the throwScope before doing a void call at end of a function. > > Could you explain in the ChangeLog why?
Thanks for the review. I'll add a comment in the ChangeLog.
Mark Lam
Comment 4
2020-07-29 10:46:14 PDT
Landed in
r265046
: <
http://trac.webkit.org/r265046
>.
Sam Weinig
Comment 5
2020-07-29 10:52:10 PDT
(In reply to Mark Lam from
comment #3
)
> (In reply to Chris Dumez from
comment #2
) > > Comment on
attachment 405472
[details]
> > proposed patch. > > > > View in context: > >
https://bugs.webkit.org/attachment.cgi?id=405472&action=review
> > > > > Source/WebCore/ChangeLog:3 > > > + CodeGeneratorJS should release the throwScope before doing a void call at end of a function. > > > > Could you explain in the ChangeLog why? > > Thanks for the review. I'll add a comment in the ChangeLog.
Hey Mark, I don't understand the explanation in the ChangeLog. Can you give an example of a void function throwing that necessitated this? If there was a bug this was fixing, can it have a test case? I could see this easily being regressed given how non-intuitive this change is.
Mark Lam
Comment 6
2020-07-29 11:27:17 PDT
(In reply to Sam Weinig from
comment #5
)
> (In reply to Mark Lam from
comment #3
) > > (In reply to Chris Dumez from
comment #2
) > > > Comment on
attachment 405472
[details]
> > > proposed patch. > > > > > > View in context: > > >
https://bugs.webkit.org/attachment.cgi?id=405472&action=review
> > > > > > > Source/WebCore/ChangeLog:3 > > > > + CodeGeneratorJS should release the throwScope before doing a void call at end of a function. > > > > > > Could you explain in the ChangeLog why? > > > > Thanks for the review. I'll add a comment in the ChangeLog. > > Hey Mark, I don't understand the explanation in the ChangeLog. Can you give > an example of a void function throwing that necessitated this? If there was > a bug this was fixing, can it have a test case? I could see this easily > being regressed given how non-intuitive this change is.
As indicated in the ChangeLog, this change is "covered by existing tests". Specifically, this test: LayoutTests/webrtc/missing-exception-checks-RTCPeerConnection-generateCertificate.html. In this case, the potential exception comes from here: static inline JSC::EncodedJSValue jsRTCPeerConnectionConstructorFunctionGenerateCertificateBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, Ref<DeferredPromise>&& promise) { auto& vm = JSC::getVM(lexicalGlobalObject); auto throwScope = DECLARE_THROW_SCOPE(vm); UNUSED_PARAM(throwScope); UNUSED_PARAM(callFrame); if (UNLIKELY(callFrame->argumentCount() < 1)) return throwVMError(lexicalGlobalObject, throwScope, createNotEnoughArgumentsError(lexicalGlobalObject)); EnsureStillAliveScope argument0 = callFrame->uncheckedArgument(0); auto keygenAlgorithm = convert<IDLUnion<IDLObject, IDLDOMString>>(*lexicalGlobalObject, argument0.value()); RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); throwScope.release(); // <======= This was added by this patch. RTCPeerConnection::generateCertificate(*jsCast<JSDOMGlobalObject*>(lexicalGlobalObject), WTFMove(keygenAlgorithm), WTFMove(promise)); // <== A simulated throw was detected coming from below this call. return JSValue::encode(jsUndefined()); }
Sam Weinig
Comment 7
2020-07-29 11:48:52 PDT
(In reply to Mark Lam from
comment #6
)
> (In reply to Sam Weinig from
comment #5
) > > (In reply to Mark Lam from
comment #3
) > > > (In reply to Chris Dumez from
comment #2
) > > > > Comment on
attachment 405472
[details]
> > > > proposed patch. > > > > > > > > View in context: > > > >
https://bugs.webkit.org/attachment.cgi?id=405472&action=review
> > > > > > > > > Source/WebCore/ChangeLog:3 > > > > > + CodeGeneratorJS should release the throwScope before doing a void call at end of a function. > > > > > > > > Could you explain in the ChangeLog why? > > > > > > Thanks for the review. I'll add a comment in the ChangeLog. > > > > Hey Mark, I don't understand the explanation in the ChangeLog. Can you give > > an example of a void function throwing that necessitated this? If there was > > a bug this was fixing, can it have a test case? I could see this easily > > being regressed given how non-intuitive this change is. > > As indicated in the ChangeLog, this change is "covered by existing tests". > Specifically, this test: > LayoutTests/webrtc/missing-exception-checks-RTCPeerConnection- > generateCertificate.html.
Sorry for all the questions, but was that test failing before this change and now it is passing?
> > In this case, the potential exception comes from here: > > static inline JSC::EncodedJSValue > jsRTCPeerConnectionConstructorFunctionGenerateCertificateBody(JSC:: > JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, > Ref<DeferredPromise>&& promise) > { > auto& vm = JSC::getVM(lexicalGlobalObject); > auto throwScope = DECLARE_THROW_SCOPE(vm); > UNUSED_PARAM(throwScope); > UNUSED_PARAM(callFrame); > if (UNLIKELY(callFrame->argumentCount() < 1)) > return throwVMError(lexicalGlobalObject, throwScope, > createNotEnoughArgumentsError(lexicalGlobalObject)); > EnsureStillAliveScope argument0 = callFrame->uncheckedArgument(0); > auto keygenAlgorithm = convert<IDLUnion<IDLObject, > IDLDOMString>>(*lexicalGlobalObject, argument0.value()); > RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); > throwScope.release(); // <======= This was added by this patch. > > RTCPeerConnection:: > generateCertificate(*jsCast<JSDOMGlobalObject*>(lexicalGlobalObject), > WTFMove(keygenAlgorithm), WTFMove(promise)); // <== A simulated throw was > detected coming from below this call. > return JSValue::encode(jsUndefined()); > }
In that case, might we want to limit this to cases where we pass some js context information (in that case the global object, but I could imagine a case where we pass the CallFrame as well) to the function?
Mark Lam
Comment 8
2020-07-29 11:59:39 PDT
(In reply to Sam Weinig from
comment #7
)
> (In reply to Mark Lam from
comment #6
) > > (In reply to Sam Weinig from
comment #5
) > > > (In reply to Mark Lam from
comment #3
) > > > > (In reply to Chris Dumez from
comment #2
) > > > > > Comment on
attachment 405472
[details]
> > > > > proposed patch. > > > > > > > > > > View in context: > > > > >
https://bugs.webkit.org/attachment.cgi?id=405472&action=review
> > > > > > > > > > > Source/WebCore/ChangeLog:3 > > > > > > + CodeGeneratorJS should release the throwScope before doing a void call at end of a function. > > > > > > > > > > Could you explain in the ChangeLog why? > > > > > > > > Thanks for the review. I'll add a comment in the ChangeLog. > > > > > > Hey Mark, I don't understand the explanation in the ChangeLog. Can you give > > > an example of a void function throwing that necessitated this? If there was > > > a bug this was fixing, can it have a test case? I could see this easily > > > being regressed given how non-intuitive this change is. > > > > As indicated in the ChangeLog, this change is "covered by existing tests". > > Specifically, this test: > > LayoutTests/webrtc/missing-exception-checks-RTCPeerConnection- > > generateCertificate.html. > > Sorry for all the questions, but was that test failing before this change > and now it is passing?
Yes, An Apple engineer told me that this test regressed and I investigated, leading to this fix.
> > In this case, the potential exception comes from here: > > > > static inline JSC::EncodedJSValue > > jsRTCPeerConnectionConstructorFunctionGenerateCertificateBody(JSC:: > > JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, > > Ref<DeferredPromise>&& promise) > > { > > auto& vm = JSC::getVM(lexicalGlobalObject); > > auto throwScope = DECLARE_THROW_SCOPE(vm); > > UNUSED_PARAM(throwScope); > > UNUSED_PARAM(callFrame); > > if (UNLIKELY(callFrame->argumentCount() < 1)) > > return throwVMError(lexicalGlobalObject, throwScope, > > createNotEnoughArgumentsError(lexicalGlobalObject)); > > EnsureStillAliveScope argument0 = callFrame->uncheckedArgument(0); > > auto keygenAlgorithm = convert<IDLUnion<IDLObject, > > IDLDOMString>>(*lexicalGlobalObject, argument0.value()); > > RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); > > throwScope.release(); // <======= This was added by this patch. > > > > RTCPeerConnection:: > > generateCertificate(*jsCast<JSDOMGlobalObject*>(lexicalGlobalObject), > > WTFMove(keygenAlgorithm), WTFMove(promise)); // <== A simulated throw was > > detected coming from below this call. > > return JSValue::encode(jsUndefined()); > > } > > In that case, might we want to limit this to cases where we pass some js > context information (in that case the global object, but I could imagine a > case where we pass the CallFrame as well) to the function?
As a convention, we don't pass CallFrame anymore. Instead, we pass the globalObject, which is what you see being passed here. There might be cases where the last called function couldn't actually throw anything. Releasing the ThrowScope before such a call at the end is still valid to do though perhaps unnecessary. We can certainly add more smarts into CodeGeneratorJS to detect all these special cases, but then, one would have to modify CodeGeneratorJS to do that ... which is not a cheap price to pay (and I already did quite a bit of this recently for handling ThrowScopes with some degree of smarts). I'm not sure the tradeoff is worth it to more at this time. My vote is to replace CodeGeneeratorJS.pm with something more sane that will allow us to generate better code ... but that's a big project to be explored in the future.
Ryan Haddad
Comment 9
2020-07-29 12:11:54 PDT
***
Bug 214927
has been marked as a duplicate of this bug. ***
Sam Weinig
Comment 10
2020-07-29 12:52:56 PDT
(In reply to Mark Lam from
comment #8
)
> (In reply to Sam Weinig from
comment #7
) > > (In reply to Mark Lam from
comment #6
) > > > (In reply to Sam Weinig from
comment #5
) > > > > (In reply to Mark Lam from
comment #3
) > > > > > (In reply to Chris Dumez from
comment #2
) > > > > > > Comment on
attachment 405472
[details]
> > > > > > proposed patch. > > > > > > > > > > > > View in context: > > > > > >
https://bugs.webkit.org/attachment.cgi?id=405472&action=review
> > > > > > > > > > > > > Source/WebCore/ChangeLog:3 > > > > > > > + CodeGeneratorJS should release the throwScope before doing a void call at end of a function. > > > > > > > > > > > > Could you explain in the ChangeLog why? > > > > > > > > > > Thanks for the review. I'll add a comment in the ChangeLog. > > > > > > > > Hey Mark, I don't understand the explanation in the ChangeLog. Can you give > > > > an example of a void function throwing that necessitated this? If there was > > > > a bug this was fixing, can it have a test case? I could see this easily > > > > being regressed given how non-intuitive this change is. > > > > > > As indicated in the ChangeLog, this change is "covered by existing tests". > > > Specifically, this test: > > > LayoutTests/webrtc/missing-exception-checks-RTCPeerConnection- > > > generateCertificate.html. > > > > Sorry for all the questions, but was that test failing before this change > > and now it is passing? > > Yes, An Apple engineer told me that this test regressed and I investigated, > leading to this fix. > > > > In this case, the potential exception comes from here: > > > > > > static inline JSC::EncodedJSValue > > > jsRTCPeerConnectionConstructorFunctionGenerateCertificateBody(JSC:: > > > JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, > > > Ref<DeferredPromise>&& promise) > > > { > > > auto& vm = JSC::getVM(lexicalGlobalObject); > > > auto throwScope = DECLARE_THROW_SCOPE(vm); > > > UNUSED_PARAM(throwScope); > > > UNUSED_PARAM(callFrame); > > > if (UNLIKELY(callFrame->argumentCount() < 1)) > > > return throwVMError(lexicalGlobalObject, throwScope, > > > createNotEnoughArgumentsError(lexicalGlobalObject)); > > > EnsureStillAliveScope argument0 = callFrame->uncheckedArgument(0); > > > auto keygenAlgorithm = convert<IDLUnion<IDLObject, > > > IDLDOMString>>(*lexicalGlobalObject, argument0.value()); > > > RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); > > > throwScope.release(); // <======= This was added by this patch. > > > > > > RTCPeerConnection:: > > > generateCertificate(*jsCast<JSDOMGlobalObject*>(lexicalGlobalObject), > > > WTFMove(keygenAlgorithm), WTFMove(promise)); // <== A simulated throw was > > > detected coming from below this call. > > > return JSValue::encode(jsUndefined()); > > > } > > > > In that case, might we want to limit this to cases where we pass some js > > context information (in that case the global object, but I could imagine a > > case where we pass the CallFrame as well) to the function? > > As a convention, we don't pass CallFrame anymore. Instead, we pass the > globalObject, which is what you see being passed here. > > There might be cases where the last called function couldn't actually throw > anything. Releasing the ThrowScope before such a call at the end is still > valid to do though perhaps unnecessary. We can certainly add more smarts > into CodeGeneratorJS to detect all these special cases, but then, one would > have to modify CodeGeneratorJS to do that ... which is not a cheap price to > pay (and I already did quite a bit of this recently for handling ThrowScopes > with some degree of smarts). I'm not sure the tradeoff is worth it to more > at this time. > > My vote is to replace CodeGeneeratorJS.pm with something more sane that will > allow us to generate better code ... but that's a big project to be explored > in the future.
Thanks for the details. In the future, if you could include information, like which test was failing and that this fixes it (and, what caused the regression if it is known), in the bug and changelog, that would be very helpful.
Note
You need to
log in
before you can comment on or make changes to this bug.
Top of Page
Format For Printing
XML
Clone This Bug