RESOLVED FIXED 107778
Objective-C API: JSContext exception property causes reference cycle
https://bugs.webkit.org/show_bug.cgi?id=107778
Summary Objective-C API: JSContext exception property causes reference cycle
Mark Hahnenberg
Reported 2013-01-23 20:08:26 PST
JSContext has a (retain) JSValue * exception property which, when non-null, creates a reference cycle (since the JSValue * holds a strong reference back to the JSContext *).
Attachments
Patch (1.84 KB, patch)
2013-01-30 14:55 PST, Mark Hahnenberg
no flags
Patch (2.04 KB, patch)
2013-01-30 17:49 PST, Mark Hahnenberg
no flags
Patch (2.59 KB, patch)
2013-01-31 11:21 PST, Mark Hahnenberg
darin: review+
Radar WebKit Bug Importer
Comment 1 2013-01-24 11:46:32 PST
Mark Hahnenberg
Comment 2 2013-01-30 14:55:57 PST
Geoffrey Garen
Comment 3 2013-01-30 15:14:25 PST
Comment on attachment 185587 [details] Patch Do we need to to something to keep the exception value from being garbage collected?
Gavin Barraclough
Comment 4 2013-01-30 17:38:11 PST
(In reply to comment #3) > (From update of attachment 185587 [details]) > Do we need to to something to keep the exception value from being garbage collected? Oh, I think you're right.
Gavin Barraclough
Comment 5 2013-01-30 17:41:03 PST
Comment on attachment 185587 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=185587&action=review r- for protect issue Geoff identified. > Source/JavaScriptCore/API/JSContext.mm:93 > + m_exception = nil; I think we only use nil for Objective-C pointer types; this should probably by 0.
Mark Hahnenberg
Comment 6 2013-01-30 17:49:39 PST
Oliver Hunt
Comment 7 2013-01-31 10:44:37 PST
Comment on attachment 185638 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=185638&action=review > Source/JavaScriptCore/API/JSContext.mm:45 > + JSValueRef m_exception; Make this Strong<> or ProtectedPtr<> > Source/JavaScriptCore/API/JSContext.mm:100 > + if (m_exception) > + JSValueUnprotect(m_context, m_exception); > + > + if (value) { > + m_exception = valueInternalValue(value); > + JSValueProtect(m_context, m_exception); > + } else > + m_exception = 0; This becomes much simpler if m_exception is simply a Strong or ProtectedPtr -- I assume we'd prefer Strong<> these days but maybe i'm wrong? > Source/JavaScriptCore/API/JSContext.mm:107 > + if (m_exception) > + return [JSValue valueWithValue:m_exception inContext:self]; > + return nil; Formatting horror!
Geoffrey Garen
Comment 8 2013-01-31 11:02:40 PST
Strong is a bit more efficient than ProtectedPtr.
Mark Hahnenberg
Comment 9 2013-01-31 11:03:24 PST
> > Source/JavaScriptCore/API/JSContext.mm:107 > > + if (m_exception) > > + return [JSValue valueWithValue:m_exception inContext:self]; > > + return nil; > > Formatting horror! Oh my.
Mark Hahnenberg
Comment 10 2013-01-31 11:21:34 PST
Mark Hahnenberg
Comment 11 2013-01-31 11:23:19 PST
In JSContext.h, the exception property is marked with the "retain" attribute. I'm not sure whether this is correct or not, since we do "retain" the internal JavaScript value, but we don't retain that particular JSValue that is passed into setException.
Darin Adler
Comment 12 2013-01-31 13:01:15 PST
Comment on attachment 185827 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=185827&action=review > Source/JavaScriptCore/API/JSContext.mm:99 > + if (m_exception) > + return [JSValue valueWithValue:toRef(m_exception.get()) inContext:self]; > + return nil; Normally WebKit style is to use early return for the exceptional cases, so the return nil would come first. Is the special case for nil needed? Does valueWithValue:inContext: handle null properly? Do we need to optimize the null case?
Mark Hahnenberg
Comment 13 2013-01-31 13:13:49 PST
(In reply to comment #12) > (From update of attachment 185827 [details]) > View in context: https://bugs.webkit.org/attachment.cgi?id=185827&action=review > > > Source/JavaScriptCore/API/JSContext.mm:99 > > + if (m_exception) > > + return [JSValue valueWithValue:toRef(m_exception.get()) inContext:self]; > > + return nil; > > Normally WebKit style is to use early return for the exceptional cases, so the return nil would come first. > > Is the special case for nil needed? Does valueWithValue:inContext: handle null properly? Do we need to optimize the null case? valueWithValue:inContext: calls initWithValue:inContext: which has an ASSERT(value), so it doesn't do the right thing here.
Mark Hahnenberg
Comment 14 2013-01-31 14:41:21 PST
Note You need to log in before you can comment on or make changes to this bug.