зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1356546: Part 4 - Use StructuredCloneHolder as transport for proxied method return values. r=aswan
MozReview-Commit-ID: LZ3XkamgkeF --HG-- extra : rebase_source : 7887bde7e424b35de18ad069161a984c556cc659
This commit is contained in:
Родитель
825b6cd689
Коммит
bc26955f41
|
@ -48,9 +48,9 @@ const {
|
|||
const {
|
||||
LocalAPIImplementation,
|
||||
LocaleData,
|
||||
NoCloneSpreadArgs,
|
||||
SchemaAPIInterface,
|
||||
SingletonEventManager,
|
||||
SpreadArgs,
|
||||
} = ExtensionCommon;
|
||||
|
||||
const isContentProcess = Services.appinfo.processType == Services.appinfo.PROCESS_TYPE_CONTENT;
|
||||
|
@ -773,7 +773,9 @@ class ChildAPIManager {
|
|||
if ("error" in data) {
|
||||
deferred.reject(data.error);
|
||||
} else {
|
||||
deferred.resolve(new SpreadArgs(data.result));
|
||||
let result = data.result.deserialize(this.context.cloneScope);
|
||||
|
||||
deferred.resolve(new NoCloneSpreadArgs(result));
|
||||
}
|
||||
this.callPromises.delete(data.callId);
|
||||
break;
|
||||
|
|
|
@ -53,6 +53,11 @@ XPCOMUtils.defineLazyGetter(this, "console", getConsole);
|
|||
|
||||
var ExtensionCommon;
|
||||
|
||||
/**
|
||||
* A sentinel class to indicate that an array of values should be
|
||||
* treated as an array when used as a promise resolution value, but as a
|
||||
* spread expression (...args) when passed to a callback.
|
||||
*/
|
||||
class SpreadArgs extends Array {
|
||||
constructor(args) {
|
||||
super();
|
||||
|
@ -60,6 +65,25 @@ class SpreadArgs extends Array {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Like SpreadArgs, but also indicates that the array values already
|
||||
* belong to the target compartment, and should not be cloned before
|
||||
* being passed.
|
||||
*
|
||||
* The `unwrappedValues` property contains an Array object which belongs
|
||||
* to the target compartment, and contains the same unwrapped values
|
||||
* passed the NoCloneSpreadArgs constructor.
|
||||
*/
|
||||
class NoCloneSpreadArgs {
|
||||
constructor(args) {
|
||||
this.unwrappedValues = args;
|
||||
}
|
||||
|
||||
[Symbol.iterator]() {
|
||||
return this.unwrappedValues[Symbol.iterator]();
|
||||
}
|
||||
}
|
||||
|
||||
class BaseContext {
|
||||
constructor(envType, extension) {
|
||||
this.envType = envType;
|
||||
|
@ -323,6 +347,8 @@ class BaseContext {
|
|||
dump(`Promise resolved after context unloaded\n`);
|
||||
} else if (!this.active) {
|
||||
dump(`Promise resolved while context is inactive\n`);
|
||||
} else if (args instanceof NoCloneSpreadArgs) {
|
||||
this.runSafeWithoutClone(callback, ...args.unwrappedValues);
|
||||
} else if (args instanceof SpreadArgs) {
|
||||
runSafe(callback, ...args);
|
||||
} else {
|
||||
|
@ -348,6 +374,9 @@ class BaseContext {
|
|||
dump(`Promise resolved after context unloaded\n`);
|
||||
} else if (!this.active) {
|
||||
dump(`Promise resolved while context is inactive\n`);
|
||||
} else if (value instanceof NoCloneSpreadArgs) {
|
||||
let values = value.unwrappedValues;
|
||||
this.runSafeWithoutClone(resolve, values.length == 1 ? values[0] : values);
|
||||
} else if (value instanceof SpreadArgs) {
|
||||
runSafe(resolve, value.length == 1 ? value[0] : value);
|
||||
} else {
|
||||
|
@ -1488,6 +1517,7 @@ ExtensionCommon = {
|
|||
CanOfAPIs,
|
||||
LocalAPIImplementation,
|
||||
LocaleData,
|
||||
NoCloneSpreadArgs,
|
||||
SchemaAPIInterface,
|
||||
SchemaAPIManager,
|
||||
SingletonEventManager,
|
||||
|
|
|
@ -624,7 +624,9 @@ ParentAPIManager = {
|
|||
result.then(result => {
|
||||
result = result instanceof SpreadArgs ? [...result] : [result];
|
||||
|
||||
reply({result});
|
||||
let holder = new StructuredCloneHolder(result);
|
||||
|
||||
reply({result: holder});
|
||||
}, error => {
|
||||
error = context.normalizeError(error);
|
||||
reply({error: {message: error.message, fileName: error.fileName}});
|
||||
|
|
Загрузка…
Ссылка в новой задаче