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:
Kris Maglione 2017-06-04 20:39:28 -07:00
Родитель 825b6cd689
Коммит bc26955f41
3 изменённых файлов: 37 добавлений и 3 удалений

Просмотреть файл

@ -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}});