RESOLVED FIXED 122561
Objective-C API: blocks aren't callable via 'new'
https://bugs.webkit.org/show_bug.cgi?id=122561
Summary Objective-C API: blocks aren't callable via 'new'
Mark Hahnenberg
Reported 2013-10-09 10:54:23 PDT
Currently the only way for clients to vend new native objects to JavaScript code is via factory methods in the form of exported class methods or blocks. Blocks can be called like normal functions from JavaScript code, but they cannot be invoked with 'new'. This would give a simple way for clients to expose constructor-like behavior to their JavaScript code.
Attachments
Patch (17.64 KB, patch)
2013-10-09 11:02 PDT, Mark Hahnenberg
no flags
Patch (18.03 KB, patch)
2013-10-09 15:44 PDT, Mark Hahnenberg
no flags
Patch (17.86 KB, patch)
2013-10-09 16:07 PDT, Mark Hahnenberg
no flags
Mark Hahnenberg
Comment 1 2013-10-09 11:02:49 PDT
Mark Hahnenberg
Comment 2 2013-10-09 11:03:06 PDT
Geoffrey Garen
Comment 3 2013-10-09 12:17:11 PDT
Comment on attachment 213795 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=213795&action=review r=me > Source/JavaScriptCore/API/ObjCCallbackFunction.mm:496 > + JSGlobalContextRef contextRef = [context JSGlobalContextRef]; > + if (*exception) { > + ::JSValue *bogusObject = [::JSValue valueWithNewObjectInContext:context]; > + return JSValueToObject(contextRef, [bogusObject JSValueRef], NULL); > + } > + > + if (!JSValueIsObject(contextRef, result)) { > + *exception = toRef(JSC::createTypeError(toJS(contextRef), "Objective-C blocks called as constructors must return an object.")); > + ::JSValue *bogusObject = [::JSValue valueWithNewObjectInContext:context]; > + return JSValueToObject(contextRef, [bogusObject JSValueRef], NULL); > + } Can we get away with just returning NULL here? In general, the C API allows a client to return NULL when throwing an exception. I think that would be nicer than making a bogus object. > Source/JavaScriptCore/API/ObjCCallbackFunction.mm:497 > + return JSValueToObject(contextRef, result, exception); This can just be a cast, since you've checked JSValueIsObject.
Mark Hahnenberg
Comment 4 2013-10-09 13:38:54 PDT
(In reply to comment #3) > (From update of attachment 213795 [details]) > View in context: https://bugs.webkit.org/attachment.cgi?id=213795&action=review > > r=me > > > Source/JavaScriptCore/API/ObjCCallbackFunction.mm:496 > > + JSGlobalContextRef contextRef = [context JSGlobalContextRef]; > > + if (*exception) { > > + ::JSValue *bogusObject = [::JSValue valueWithNewObjectInContext:context]; > > + return JSValueToObject(contextRef, [bogusObject JSValueRef], NULL); > > + } > > + > > + if (!JSValueIsObject(contextRef, result)) { > > + *exception = toRef(JSC::createTypeError(toJS(contextRef), "Objective-C blocks called as constructors must return an object.")); > > + ::JSValue *bogusObject = [::JSValue valueWithNewObjectInContext:context]; > > + return JSValueToObject(contextRef, [bogusObject JSValueRef], NULL); > > + } > > Can we get away with just returning NULL here? In general, the C API allows a client to return NULL when throwing an exception. I think that would be nicer than making a bogus object. I ran into an issue where if I returned NULL, the caller (APICallbackFunction::construct) would see the null and throw a *different* TypeError than the one I wanted to throw. Maybe we could just change APICallbackFunction::construct to allow NULL? > > > Source/JavaScriptCore/API/ObjCCallbackFunction.mm:497 > > + return JSValueToObject(contextRef, result, exception); > > This can just be a cast, since you've checked JSValueIsObject. Okiedokie.
Mark Hahnenberg
Comment 5 2013-10-09 15:44:02 PDT
Mark Hahnenberg
Comment 6 2013-10-09 15:45:22 PDT
(In reply to comment #5) > Created an attachment (id=213826) [details] > Patch I uploaded another patch for review because I changed the part where we create the block automatically add a new, empty object as the .prototype property of the block and to set the .constructor property on that prototype object properly rather than forcing the client to do it themselves.
Mark Hahnenberg
Comment 7 2013-10-09 15:49:24 PDT
(In reply to comment #6) > (In reply to comment #5) > > Created an attachment (id=213826) [details] [details] > > Patch > > I uploaded another patch for review because I changed the part where we create the block automatically add a new, empty object as the .prototype property of the block and to set the .constructor property on that prototype object properly rather than forcing the client to do all of that themselves. ...I changed the part where we create the block automatically TO add a new, empty...
Geoffrey Garen
Comment 8 2013-10-09 15:57:48 PDT
> > Can we get away with just returning NULL here? In general, the C API allows a client to return NULL when throwing an exception. I think that would be nicer than making a bogus object. > > I ran into an issue where if I returned NULL, the caller (APICallbackFunction::construct) would see the null and throw a *different* TypeError than the one I wanted to throw. Maybe we could just change APICallbackFunction::construct to allow NULL? I think it's appropriate for APICallbackFunction::construct to allow NULL if and only if an exception has been thrown. So, you just have to change the "if (exception)" block to return explicitly, to avoid throwing a new exception.
Geoffrey Garen
Comment 9 2013-10-09 16:00:51 PDT
> I think it's appropriate for APICallbackFunction::construct to allow NULL if and only if an exception has been thrown. So, you just have to change the "if (exception)" block to return explicitly, to avoid throwing a new exception. ... which is a good thing to do anyway, since returning an exception is supposed to mean "don't use the value I returned -- it's bogus". We want to return some value other than result, since result is bogus. Looks like we return the exception object when we throw a type error, so we should probably return the exception object in this case as well.
Mark Hahnenberg
Comment 10 2013-10-09 16:07:04 PDT
WebKit Commit Bot
Comment 11 2013-10-10 11:18:43 PDT
Comment on attachment 213828 [details] Patch Clearing flags on attachment: 213828 Committed r157234: <http://trac.webkit.org/changeset/157234>
WebKit Commit Bot
Comment 12 2013-10-10 11:18:45 PDT
All reviewed patches have been landed. Closing bug.
Note You need to log in before you can comment on or make changes to this bug.