Bug 1402944: Part 8 - Avoid X-ray overhead when cloning event handler responses. r?mixedpuppy draft
authorKris Maglione <maglione.k@gmail.com>
Sat, 23 Sep 2017 13:30:52 -0700
changeset 670807 b0b60850e4b3e4fd890826815fe3fb5d63fde2d9
parent 670806 9019b2d2e99c9e287968649ef29e611ff005a446
child 670808 35f539a1d56a7009e170882ade7f00d2c9e2c1ae
push id81714
push usermaglione.k@gmail.com
push dateTue, 26 Sep 2017 21:30:45 +0000
reviewersmixedpuppy
bugs1402944
milestone58.0a1
Bug 1402944: Part 8 - Avoid X-ray overhead when cloning event handler responses. r?mixedpuppy MozReview-Commit-ID: 4CHP80WymuA
toolkit/components/extensions/ExtensionChild.jsm
toolkit/components/extensions/ExtensionParent.jsm
--- a/toolkit/components/extensions/ExtensionChild.jsm
+++ b/toolkit/components/extensions/ExtensionChild.jsm
@@ -823,19 +823,26 @@ class ChildAPIManager {
 
     switch (name || messageName) {
       case "API:RunListener":
         let map = this.listeners.get(data.path);
         let listener = map.ids.get(data.listenerId);
 
         if (listener) {
           let args = data.args.deserialize(this.context.cloneScope);
-          let fire = () => this.context.runSafeWithoutClone(listener, ...args);
-          return (data.handlingUserInput) ?
-                 withHandlingUserInput(this.context.contentWindow, fire) : fire();
+          let fire = () => this.context.applySafeWithoutClone(listener, args);
+          return Promise.resolve(
+            data.handlingUserInput ? withHandlingUserInput(this.context.contentWindow, fire)
+                                   : fire())
+            .then(result => {
+              if (result !== undefined) {
+                return new StructuredCloneHolder(result, this.context.cloneScope);
+              }
+              return result;
+            });
         }
         if (!map.removedIds.has(data.listenerId)) {
           Services.console.logStringMessage(
             `Unknown listener at childId=${data.childId} path=${data.path} listenerId=${data.listenerId}\n`);
         }
         break;
 
       case "API:CallResult":
--- a/toolkit/components/extensions/ExtensionParent.jsm
+++ b/toolkit/components/extensions/ExtensionParent.jsm
@@ -64,16 +64,18 @@ let schemaURLs = new Set();
 
 schemaURLs.add("chrome://extensions/content/schemas/experiments.json");
 
 let GlobalManager;
 let ParentAPIManager;
 let ProxyMessenger;
 let StartupCache;
 
+const global = this;
+
 // This object loads the ext-*.js scripts that define the extension API.
 let apiManager = new class extends SchemaAPIManager {
   constructor() {
     super("main");
     this.initialized = null;
 
     this.on("startup", (event, extension) => { // eslint-disable-line mozilla/balanced-listeners
       let promises = [];
@@ -778,16 +780,18 @@ ParentAPIManager = {
           childId,
           handlingUserInput,
           listenerId: data.listenerId,
           path: data.path,
           args: new StructuredCloneHolder(listenerArgs),
         },
         {
           recipient: {childId},
+        }).then(result => {
+          return result && result.deserialize(global);
         });
     }
 
     context.listenerProxies.set(data.listenerId, listener);
 
     let args = data.args;
     let promise = context.apiCan.asyncFindAPIPath(data.path);