WebKit Bugzilla
New
Browse
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
RESOLVED FIXED
158114
WebRTC: Update RTCPeerConnection overloaded legacy operations to return a Promise
https://bugs.webkit.org/show_bug.cgi?id=158114
Summary
WebRTC: Update RTCPeerConnection overloaded legacy operations to return a Pro...
Adam Bergkvist
Reported
2016-05-26 03:20:56 PDT
The WebRTC 1.0 specification has been updated so that the overloaded legacy operations [1] (using callbacks) return a Promise. I.e. no errors will be throw. [2] links to the WG discussion and [3] is the specific change. [1]
https://w3c.github.io/webrtc-pc/archives/20160513/webrtc.html#legacy-interface-extensions
[2]
https://github.com/w3c/webrtc-pc/issues/615
[3]
https://github.com/w3c/webrtc-pc/pull/618
Attachments
Proposed patch
(64.35 KB, patch)
2016-05-26 04:52 PDT
,
Adam Bergkvist
eric.carlson
: review+
buildbot
: commit-queue-
Details
Formatted Diff
Diff
Archive of layout-test-results from ews103 for mac-yosemite
(828.23 KB, application/zip)
2016-05-26 05:35 PDT
,
Build Bot
no flags
Details
Updated patch
(72.01 KB, patch)
2016-05-27 04:44 PDT
,
Adam Bergkvist
no flags
Details
Formatted Diff
Diff
Show Obsolete
(1)
View All
Add attachment
proposed patch, testcase, etc.
Adam Bergkvist
Comment 1
2016-05-26 04:52:58 PDT
Created
attachment 279879
[details]
Proposed patch
Build Bot
Comment 2
2016-05-26 05:35:23 PDT
Comment on
attachment 279879
[details]
Proposed patch
Attachment 279879
[details]
did not pass mac-ews (mac): Output:
http://webkit-queues.webkit.org/results/1385627
New failing tests: ietestcenter/css3/grid/grid-items-005.htm
Build Bot
Comment 3
2016-05-26 05:35:26 PDT
Created
attachment 279880
[details]
Archive of layout-test-results from ews103 for mac-yosemite The attached test failures were seen while running run-webkit-tests on the mac-ews. Bot: ews103 Port: mac-yosemite Platform: Mac OS X 10.10.5
Eric Carlson
Comment 4
2016-05-26 07:02:46 PDT
Comment on
attachment 279879
[details]
Proposed patch View in context:
https://bugs.webkit.org/attachment.cgi?id=279879&action=review
> LayoutTests/fast/mediastream/resources/promise-utils.js:18 > +function promiseShouldResolve(expr) {
This function is unused. Did you mean to use it, or is it for future use?
> Source/WebCore/Modules/mediastream/RTCPeerConnectionInternals.js:98 > +function objectAndCallbacksOverload(args, functionName, objectConstructor, objectOptions, promiseMode, legacyMode) > { > "use strict"; > > - var options = {}; > + let argsCount = Math.min(3, args.length); > + let objectArg = args[0]; > + let objectArgOk = false; > + > + if (argsCount == 0 && objectOptions.optionalAndNullable) { > + objectArg = null; > + objectArgOk = true; > + argsCount = 1; > + } else { > + const hasMatchingType = objectArg instanceof objectConstructor; > + objectArgOk = objectOptions.optionalAndNullable ? (objectArg === null || typeof objectArg === "undefined" || hasMatchingType) : hasMatchingType; > + } > > - if (args.length <= 1) { > - // Promise mode > - if (args.length && @isDictionary(args[0])) > - options = args[0] > + if (argsCount == 1 && objectArgOk) > + return promiseMode(objectArg); > > - return @enqueueOperation(peerConnection, function () { > - return targetFunction.@call(peerConnection, options); > - }); > - } > + const successCallback = args[1]; > + const errorCallback = args[2]; > + if (argsCount == 3 && objectArgOk > + && (successCallback == null || typeof successCallback === "function") > + && (errorCallback == null || typeof errorCallback === "function")) { > + if (typeof successCallback !== "function") > + return @Promise.@reject(new @TypeError(`Argument 2 ('successCallback') to RTCPeerConnection.${functionName} must be a function`)); > + > + if (typeof errorCallback !== "function") > + return @Promise.@reject(new @TypeError(`Argument 3 ('errorCallback') to RTCPeerConnection.${functionName} must be a function`)); > > - // Legacy callbacks mode (2 or 3 arguments) > - var successCallback = @extractCallbackArg(args, 0, "successCallback", functionName); > - var errorCallback = @extractCallbackArg(args, 1, "errorCallback", functionName); > + return legacyMode(objectArg, successCallback, errorCallback); > + } > > - if (args.length > 2 && @isDictionary(args[2])) > - options = args[2]; > + if (argsCount < 1) > + return @Promise.@reject(new @TypeError("Not enough arguments")); > > - @enqueueOperation(peerConnection, function () { > - return targetFunction.@call(peerConnection, options).then(successCallback, errorCallback); > - }); > + return @Promise.@reject(new @TypeError("Type error")); > }
I had a hard time figuring out this logic. I think it will be clearer if you restructure it to return early as soon as you know the arguments are valid or illegal. For example (untested so this may not be exactly correct): function objectAndCallbacksOverload(args, functionName, objectConstructor, objectOptions, promiseMode, legacyMode) { "use strict"; let argsCount = Math.min(3, args.length); let objectArg = args[0]; let objectArgOk = false; if (!argsCount && objectOptions.optionalAndNullable) { objectArg = null; objectArgOk = true; argsCount = 1; } else { const hasMatchingType = objectArg instanceof objectConstructor; objectArgOk = objectOptions.optionalAndNullable ? (objectArg === null || typeof objectArg === "undefined" || hasMatchingType) : hasMatchingType; } if (argsCount < 1) return @Promise.@reject(new @TypeError("Not enough arguments")); if (argsCount == 1 && objectArgOk) return promiseMode(objectArg); if (argsCount != 3 || !objectArgOk) return @Promise.@reject(new @TypeError("Type error")); const successCallback = args[1]; if (successCallback != null && typeof errorCallback !== "function") return @Promise.@reject(new @TypeError(`Argument 2 ('successCallback') to RTCPeerConnection.${functionName} must be a function`)); const errorCallback = args[2]; if (errorCallback != null && typeof errorCallback !== "function")) return @Promise.@reject(new @TypeError(`Argument 3 ('errorCallback') to RTCPeerConnection.${functionName} must be a function`)); return legacyMode(objectArg, successCallback, errorCallback); }
> Source/WebCore/Modules/mediastream/RTCPeerConnectionInternals.js:123 > + const argsCount = Math.min(3, args.length); > > - // Legacy callbacks mode (3 arguments) > - if (args.length < 3) > - throw new @TypeError("Not enough arguments"); > + if (argsCount == 0 || argsCount == 1) > + return promiseMode(args[0]); > > - var successCallback = @extractCallbackArg(args, 1, "successCallback", functionName); > - var errorCallback = @extractCallbackArg(args, 2, "errorCallback", functionName); > - > - @enqueueOperation(peerConnection, function () { > - return targetFunction.@call(peerConnection, description).then(successCallback, errorCallback); > - }); > -} > + const successCallback = args[0]; > + const errorCallback = args[1]; > + if ((argsCount == 2 || argsCount == 3) > + && (successCallback == null || typeof successCallback === "function") > + && (errorCallback == null || typeof errorCallback === "function")) { > + if (typeof successCallback !== "function") > + return @Promise.@reject(new @TypeError(`Argument 1 ('successCallback') to RTCPeerConnection.${functionName} must be a function`)); > > -function extractCallbackArg(args, index, name, parentFunctionName) > -{ > - "use strict"; > + if (typeof errorCallback !== "function") > + return @Promise.@reject(new @TypeError(`Argument 2 ('errorCallback') to RTCPeerConnection.${functionName} must be a function`)); > > - var callback = args[index]; > - if (typeof callback !== "function") > - throw new @TypeError("Argument " + (index + 1) + " ('" + name + "') to RTCPeerConnection." + parentFunctionName + " must be a Function"); > + return legacyMode(successCallback, errorCallback, args[2]); > + } > > - return callback; > + return @Promise.@reject(new @TypeError("Type error"));
I think this would be slightly clearer if you reject for an unexpected number of arguments immediately after getting the argument count.
Adam Bergkvist
Comment 5
2016-05-27 04:44:37 PDT
Created
attachment 279953
[details]
Updated patch Addressed review comments
Adam Bergkvist
Comment 6
2016-05-27 05:39:00 PDT
(In reply to
comment #4
)
> Comment on
attachment 279879
[details]
> Proposed patch > > View in context: >
https://bugs.webkit.org/attachment.cgi?id=279879&action=review
> > > LayoutTests/fast/mediastream/resources/promise-utils.js:18 > > +function promiseShouldResolve(expr) { > > This function is unused. Did you mean to use it, or is it for future use?
It's used by other tests not yet upstreamed. I'll remove it and add it when it's needed. [...]
> > I had a hard time figuring out this logic. I think it will be clearer if you > restructure it to return early as soon as you know the arguments are valid > or illegal. For example (untested so this may not be exactly correct): > > > function objectAndCallbacksOverload(args, functionName, objectConstructor, > objectOptions, promiseMode, legacyMode) > { > "use strict"; > > let argsCount = Math.min(3, args.length); > let objectArg = args[0]; > let objectArgOk = false; > > if (!argsCount && objectOptions.optionalAndNullable) { > objectArg = null; > objectArgOk = true; > argsCount = 1; > } else { > const hasMatchingType = objectArg instanceof objectConstructor; > objectArgOk = objectOptions.optionalAndNullable ? (objectArg === > null || typeof objectArg === "undefined" || hasMatchingType) : > hasMatchingType; > } > > if (argsCount < 1) > return @Promise.@reject(new @TypeError("Not enough arguments")); > > if (argsCount == 1 && objectArgOk) > return promiseMode(objectArg); > > if (argsCount != 3 || !objectArgOk) > return @Promise.@reject(new @TypeError("Type error")); > > const successCallback = args[1]; > if (successCallback != null && typeof errorCallback !== "function") > return @Promise.@reject(new @TypeError(`Argument 2 > ('successCallback') to RTCPeerConnection.${functionName} must be a > function`)); > > const errorCallback = args[2]; > if (errorCallback != null && typeof errorCallback !== "function")) > return @Promise.@reject(new @TypeError(`Argument 3 ('errorCallback') > to RTCPeerConnection.${functionName} must be a function`)); > > return legacyMode(objectArg, successCallback, errorCallback); > }
I've imitated the structure of generated bindings and I agree with you that it's not the most obvious code flow for readability. :) I've restructured the bindings in the updated patch, as you proposed. The new version is also more specific on error messages (no generic "Type error" messages). [...]
> > I think this would be slightly clearer if you reject for an unexpected > number of arguments immediately after getting the argument count.
Se previous comment.
Adam Bergkvist
Comment 7
2016-05-27 11:23:45 PDT
Comment on
attachment 279953
[details]
Updated patch Thanks for reviewing
WebKit Commit Bot
Comment 8
2016-05-27 11:34:38 PDT
Comment on
attachment 279953
[details]
Updated patch Clearing flags on attachment: 279953 Committed
r201455
: <
http://trac.webkit.org/changeset/201455
>
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