WebKit Bugzilla
New
Browse
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
RESOLVED FIXED
177389
WeakPtrFactory should allow downcasting
https://bugs.webkit.org/show_bug.cgi?id=177389
Summary
WeakPtrFactory should allow downcasting
Jiewen Tan
Reported
2017-09-22 15:07:18 PDT
WeakPtrFactory should allow downcasting, i.e. creating a weak pointer of the current class' derived classes.
Attachments
Patch
(3.55 KB, patch)
2017-09-25 15:26 PDT
,
zalan
no flags
Details
Formatted Diff
Diff
Patch
(10.88 KB, patch)
2017-09-26 23:54 PDT
,
Jiewen Tan
no flags
Details
Formatted Diff
Diff
Second Solution
(10.54 KB, patch)
2017-09-27 11:18 PDT
,
Jiewen Tan
no flags
Details
Formatted Diff
Diff
First Solution
(6.97 KB, patch)
2017-09-27 12:00 PDT
,
Jiewen Tan
no flags
Details
Formatted Diff
Diff
Show Obsolete
(2)
View All
Add attachment
proposed patch, testcase, etc.
Radar WebKit Bug Importer
Comment 1
2017-09-22 15:09:48 PDT
<
rdar://problem/34604174
>
Jiewen Tan
Comment 2
2017-09-22 15:15:47 PDT
Geoff's proposal: The Problem we have currently: WeakPtr<Element> ptr = parent.createWeakPtr(); // fails: returns WeakPtr<Node> WeakPtr<Element> ptr = parent.createWeakPtr<Element>(); // succeeds: returns WeakPtr<Element> Solution is something like this: template<typename U> WeakPtr<U> createWeakPtr() const { return WeakPtr<U>(static_reference_cast<U>(m_ref); }
zalan
Comment 3
2017-09-25 15:26:44 PDT
Created
attachment 321758
[details]
Patch
Jiewen Tan
Comment 4
2017-09-25 17:22:23 PDT
Comment on
attachment 321758
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=321758&action=review
Thank you for making this patch. Have one question listed below. Could you explain it to me?
> Source/WTF/wtf/WeakPtr.h:108 > + return WeakPtr<U>(Ref<WeakReference<U>>(static_cast<WeakReference<U>&>(*m_ref)));
No sure why static_cast works here. Could you elaborate it a little bit?
Geoffrey Garen
Comment 5
2017-09-25 17:27:28 PDT
> > Source/WTF/wtf/WeakPtr.h:108 > > + return WeakPtr<U>(Ref<WeakReference<U>>(static_cast<WeakReference<U>&>(*m_ref))); > > No sure why static_cast works here. Could you elaborate it a little bit?
Yeah, I didn't write it quite right here. I think Zalan has a working copy of this function now.
Geoffrey Garen
Comment 6
2017-09-25 17:43:14 PDT
> > Source/WTF/wtf/WeakPtr.h:108 > > + return WeakPtr<U>(Ref<WeakReference<U>>(static_cast<WeakReference<U>&>(*m_ref))); > > No sure why static_cast works here. Could you elaborate it a little bit?
Yeah, actually, this is wrong. It only worked in this patch because T and U are equal across all invocations. But when T and U are not equal, static casting WeakReference<T>& to WeakReference<U>& is an error. So, we need a better version of this function.
zalan
Comment 7
2017-09-25 17:45:37 PDT
(In reply to Geoffrey Garen from
comment #6
)
> > > Source/WTF/wtf/WeakPtr.h:108 > > > + return WeakPtr<U>(Ref<WeakReference<U>>(static_cast<WeakReference<U>&>(*m_ref))); > > > > No sure why static_cast works here. Could you elaborate it a little bit? > > Yeah, actually, this is wrong. It only worked in this patch because T and U > are equal across all invocations. But when T and U are not equal, static > casting WeakReference<T>& to WeakReference<U>& is an error. > > So, we need a better version of this function.
Yea, and I was going to work on that. This was more of the first iteration, hence not landed yet.
Geoffrey Garen
Comment 8
2017-09-25 17:50:53 PDT
I guess there are two ways to fix this: We could add a reinterpret_cast that static_asserts the conversion between T* and U* is OK. Or we could add a template parameter to WeakPtr, and say that WeakPtr points to WeakReference<T>, and casts to U* when you get its contents. The second option is probably more in line with idiomatic C++, so if it doesn't make WeakPtr construction too annoying, it might be preferred.
Jiewen Tan
Comment 9
2017-09-26 23:54:54 PDT
Created
attachment 321940
[details]
Patch
Build Bot
Comment 10
2017-09-26 23:55:59 PDT
Attachment 321940
[details]
did not pass style-queue: ERROR: Source/WTF/wtf/WeakPtr.h:68: Should be indented on a separate line, with the colon or comma first on that line. [whitespace/indent] [4] ERROR: Source/WTF/wtf/WeakPtr.h:69: Should be indented on a separate line, with the colon or comma first on that line. [whitespace/indent] [4] Total errors found: 2 in 5 files If any of these errors are false positives, please file a bug against check-webkit-style.
Jiewen Tan
Comment 11
2017-09-27 00:00:10 PDT
Comment on
attachment 321940
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=321940&action=review
> Tools/TestWebKitAPI/Tests/WTF/WeakPtr.cpp:215 > + WeakPtr<Derived, Base> derivedWeakPtr;
Ryosuke and I are kind of worrying this format will be annoying to use. However, I don't know how it could be prevented, i.e. using WeakPtr<Derived> instead of WeakPtr<Derived, Base>. If anyone has any ideas, please tell me. Appreciate it.
Geoffrey Garen
Comment 12
2017-09-27 08:13:01 PDT
Comment on
attachment 321940
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=321940&action=review
> Source/WTF/wtf/WeakPtr.h:88 > + static_assert((!std::is_class<U>::value && !std::is_class<T>::value) || std::is_base_of<U, T>::value, "U should be a base class of T");
There's no need for this assertion because it's built into the static_cast. The value of the double template parameter solution is that you don't need any assertions: The language guarantees correctness.
Geoffrey Garen
Comment 13
2017-09-27 08:26:06 PDT
Comment on
attachment 321940
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=321940&action=review
>> Source/WTF/wtf/WeakPtr.h:88 >> + static_assert((!std::is_class<U>::value && !std::is_class<T>::value) || std::is_base_of<U, T>::value, "U should be a base class of T"); > > There's no need for this assertion because it's built into the static_cast. The value of the double template parameter solution is that you don't need any assertions: The language guarantees correctness.
...built into the static_cast in the getter.
>> Tools/TestWebKitAPI/Tests/WTF/WeakPtr.cpp:215 >> + WeakPtr<Derived, Base> derivedWeakPtr; > > Ryosuke and I are kind of worrying this format will be annoying to use. However, I don't know how it could be prevented, i.e. using WeakPtr<Derived> instead of WeakPtr<Derived, Base>. If anyone has any ideas, please tell me. Appreciate it.
If this is too annoying, we can use the reinterpret_cast solution: template<typename T, typename U> WeakReference<T>& static_weak_reference_cast(WeakReference<U>& weakReference) { static_assert(std::is_convertible<T*, U*>::value, "U* must be convertible to T*"); return reinterpret_cast<WeakReference <T>&>(weakReference); } Then createWeakPtr would static_weak_reference_cast m_ref when creating a WeakPtr.
Jiewen Tan
Comment 14
2017-09-27 11:14:43 PDT
Comment on
attachment 321940
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=321940&action=review
Thanks Geoff for reviewing the patch. I will upload a patch addressing comments in this patch and then upload another that uses the first solution. Then we can decide which one to go.
>>> Source/WTF/wtf/WeakPtr.h:88 >>> + static_assert((!std::is_class<U>::value && !std::is_class<T>::value) || std::is_base_of<U, T>::value, "U should be a base class of T"); >> >> There's no need for this assertion because it's built into the static_cast. The value of the double template parameter solution is that you don't need any assertions: The language guarantees correctness. > > ...built into the static_cast in the getter.
Removed.
>>> Tools/TestWebKitAPI/Tests/WTF/WeakPtr.cpp:215 >>> + WeakPtr<Derived, Base> derivedWeakPtr; >> >> Ryosuke and I are kind of worrying this format will be annoying to use. However, I don't know how it could be prevented, i.e. using WeakPtr<Derived> instead of WeakPtr<Derived, Base>. If anyone has any ideas, please tell me. Appreciate it. > > If this is too annoying, we can use the reinterpret_cast solution: > > template<typename T, typename U> > WeakReference<T>& static_weak_reference_cast(WeakReference<U>& weakReference) > { > static_assert(std::is_convertible<T*, U*>::value, "U* must be convertible to T*"); > return reinterpret_cast<WeakReference <T>&>(weakReference); > } > > Then createWeakPtr would static_weak_reference_cast m_ref when creating a WeakPtr.
Sure. The first solution will definitely resolve this issue for us. I was trying to upload two patches, one for each, yesterday, but was not able to accomplish that. Building for WTF is too costly, I am wondering if it is possible to just build WTF and corresponding API tests.
Jiewen Tan
Comment 15
2017-09-27 11:18:57 PDT
Created
attachment 321978
[details]
Second Solution
Build Bot
Comment 16
2017-09-27 11:21:39 PDT
Attachment 321978
[details]
did not pass style-queue: ERROR: Source/WTF/wtf/WeakPtr.h:66: Should be indented on a separate line, with the colon or comma first on that line. [whitespace/indent] [4] ERROR: Source/WTF/wtf/WeakPtr.h:67: Should be indented on a separate line, with the colon or comma first on that line. [whitespace/indent] [4] ERROR: Source/WTF/wtf/WeakPtr.h:83: Should be indented on a separate line, with the colon or comma first on that line. [whitespace/indent] [4] Total errors found: 3 in 5 files If any of these errors are false positives, please file a bug against check-webkit-style.
Jiewen Tan
Comment 17
2017-09-27 11:27:28 PDT
(In reply to Jiewen Tan from
comment #14
)
> Comment on
attachment 321940
[details]
> Patch > > View in context: >
https://bugs.webkit.org/attachment.cgi?id=321940&action=review
> > Thanks Geoff for reviewing the patch. I will upload a patch addressing > comments in this patch and then upload another that uses the first solution. > Then we can decide which one to go. > > >>> Source/WTF/wtf/WeakPtr.h:88 > >>> + static_assert((!std::is_class<U>::value && !std::is_class<T>::value) || std::is_base_of<U, T>::value, "U should be a base class of T"); > >> > >> There's no need for this assertion because it's built into the static_cast. The value of the double template parameter solution is that you don't need any assertions: The language guarantees correctness. > > > > ...built into the static_cast in the getter. > > Removed. > > >>> Tools/TestWebKitAPI/Tests/WTF/WeakPtr.cpp:215 > >>> + WeakPtr<Derived, Base> derivedWeakPtr; > >> > >> Ryosuke and I are kind of worrying this format will be annoying to use. However, I don't know how it could be prevented, i.e. using WeakPtr<Derived> instead of WeakPtr<Derived, Base>. If anyone has any ideas, please tell me. Appreciate it. > > > > If this is too annoying, we can use the reinterpret_cast solution: > > > > template<typename T, typename U> > > WeakReference<T>& static_weak_reference_cast(WeakReference<U>& weakReference) > > { > > static_assert(std::is_convertible<T*, U*>::value, "U* must be convertible to T*"); > > return reinterpret_cast<WeakReference <T>&>(weakReference); > > } > > > > Then createWeakPtr would static_weak_reference_cast m_ref when creating a WeakPtr. > > Sure. The first solution will definitely resolve this issue for us. I was > trying to upload two patches, one for each, yesterday, but was not able to > accomplish that. Building for WTF is too costly, I am wondering if it is > possible to just build WTF and corresponding API tests.
Hmm, I could build WTF and TestWebKitAPI separately.
Jiewen Tan
Comment 18
2017-09-27 12:00:27 PDT
Created
attachment 321989
[details]
First Solution
Build Bot
Comment 19
2017-09-27 12:03:33 PDT
Attachment 321989
[details]
did not pass style-queue: ERROR: Source/WTF/wtf/WeakPtr.h:71: Should be indented on a separate line, with the colon or comma first on that line. [whitespace/indent] [4] Total errors found: 1 in 5 files If any of these errors are false positives, please file a bug against check-webkit-style.
Jiewen Tan
Comment 20
2017-09-27 16:58:27 PDT
Comment on
attachment 321989
[details]
First Solution View in context:
https://bugs.webkit.org/attachment.cgi?id=321989&action=review
> Tools/TestWebKitAPI/Tests/WTF/WeakPtr.cpp:228 > + EXPECT_EQ(derivedWeakPtr->foo(), dummy1);
It should be derivedPtr.
Jiewen Tan
Comment 21
2017-09-27 16:59:24 PDT
Comment on
attachment 321978
[details]
Second Solution View in context:
https://bugs.webkit.org/attachment.cgi?id=321978&action=review
> Tools/TestWebKitAPI/Tests/WTF/WeakPtr.cpp:228 > + EXPECT_EQ(derivedWeakPtr->foo(), dummy1);
It should be derivedPtr.
Ryosuke Niwa
Comment 22
2017-09-27 18:45:05 PDT
Comment on
attachment 321989
[details]
First Solution View in context:
https://bugs.webkit.org/attachment.cgi?id=321989&action=review
> Tools/TestWebKitAPI/Tests/WTF/WeakPtr.cpp:215 > + WeakPtr<Base> baseWeakPtr; > + WeakPtr<Derived> derivedWeakPtr;
This looks much better to me.
zalan
Comment 23
2017-09-27 18:46:35 PDT
(In reply to Ryosuke Niwa from
comment #22
)
> Comment on
attachment 321989
[details]
> First Solution > > View in context: >
https://bugs.webkit.org/attachment.cgi?id=321989&action=review
> > > Tools/TestWebKitAPI/Tests/WTF/WeakPtr.cpp:215 > > + WeakPtr<Base> baseWeakPtr; > > + WeakPtr<Derived> derivedWeakPtr; > > This looks much better to me.
So much better.
Daniel Bates
Comment 24
2017-09-27 19:54:31 PDT
Comment on
attachment 321989
[details]
First Solution View in context:
https://bugs.webkit.org/attachment.cgi?id=321989&action=review
>>> Tools/TestWebKitAPI/Tests/WTF/WeakPtr.cpp:215 >>> + WeakPtr<Derived> derivedWeakPtr; >> >> This looks much better to me. > > So much better.
Better :)
Geoffrey Garen
Comment 25
2017-09-28 14:04:10 PDT
Comment on
attachment 321989
[details]
First Solution r=me
WebKit Commit Bot
Comment 26
2017-09-28 14:31:43 PDT
Comment on
attachment 321989
[details]
First Solution Clearing flags on attachment: 321989 Committed
r222633
: <
http://trac.webkit.org/changeset/222633
>
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