109 lines
2.7 KiB
JavaScript
109 lines
2.7 KiB
JavaScript
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
"use strict";
|
|
|
|
const { Actor } = require("resource://devtools/shared/protocol.js");
|
|
const { symbolSpec } = require("resource://devtools/shared/specs/symbol.js");
|
|
loader.lazyRequireGetter(
|
|
this,
|
|
"createValueGrip",
|
|
"resource://devtools/server/actors/object/utils.js",
|
|
true
|
|
);
|
|
|
|
/**
|
|
* Creates an actor for the specified symbol.
|
|
*
|
|
* @param {DevToolsServerConnection} conn: The connection to the client.
|
|
* @param {Symbol} symbol: The symbol we want to create an actor for.
|
|
*/
|
|
class SymbolActor extends Actor {
|
|
constructor(conn, symbol) {
|
|
super(conn, symbolSpec);
|
|
this.symbol = symbol;
|
|
}
|
|
|
|
rawValue() {
|
|
return this.symbol;
|
|
}
|
|
|
|
destroy() {
|
|
// Because symbolActors is not a weak map, we won't automatically leave
|
|
// it so we need to manually leave on destroy so that we don't leak
|
|
// memory.
|
|
this._releaseActor();
|
|
super.destroy();
|
|
}
|
|
|
|
/**
|
|
* Returns a grip for this actor for returning in a protocol message.
|
|
*/
|
|
form() {
|
|
const form = {
|
|
type: this.typeName,
|
|
actor: this.actorID,
|
|
};
|
|
const name = getSymbolName(this.symbol);
|
|
if (name !== undefined) {
|
|
// Create a grip for the name because it might be a longString.
|
|
form.name = createValueGrip(name, this.getParent());
|
|
}
|
|
return form;
|
|
}
|
|
|
|
/**
|
|
* Handle a request to release this SymbolActor instance.
|
|
*/
|
|
release() {
|
|
// TODO: also check if this.getParent() === threadActor.threadLifetimePool
|
|
// when the web console moves away from manually releasing pause-scoped
|
|
// actors.
|
|
this._releaseActor();
|
|
this.destroy();
|
|
return {};
|
|
}
|
|
|
|
_releaseActor() {
|
|
const parent = this.getParent();
|
|
if (parent && parent.symbolActors) {
|
|
delete parent.symbolActors[this.symbol];
|
|
}
|
|
}
|
|
}
|
|
|
|
const symbolProtoToString = Symbol.prototype.toString;
|
|
|
|
function getSymbolName(symbol) {
|
|
const name = symbolProtoToString.call(symbol).slice("Symbol(".length, -1);
|
|
return name || undefined;
|
|
}
|
|
|
|
/**
|
|
* Create a grip for the given symbol.
|
|
*
|
|
* @param sym Symbol
|
|
* The symbol we are creating a grip for.
|
|
* @param pool Pool
|
|
* The actor pool where the new actor will be added.
|
|
*/
|
|
function symbolGrip(sym, pool) {
|
|
if (!pool.symbolActors) {
|
|
pool.symbolActors = Object.create(null);
|
|
}
|
|
|
|
if (sym in pool.symbolActors) {
|
|
return pool.symbolActors[sym].form();
|
|
}
|
|
|
|
const actor = new SymbolActor(pool.conn, sym);
|
|
pool.manage(actor);
|
|
pool.symbolActors[sym] = actor;
|
|
return actor.form();
|
|
}
|
|
|
|
module.exports = {
|
|
SymbolActor,
|
|
symbolGrip,
|
|
};
|