@awayfl/avm2
Version:
Virtual machine for executing AS3 code
118 lines (117 loc) • 4.85 kB
JavaScript
import { ScriptInfo } from '../abc/lazy/ScriptInfo';
import { Errors } from '../errors';
import { assert } from '@awayjs/graphics';
import { runtimeWriter } from './writers';
import { interpret } from '../int';
import { release } from '@awayfl/swf-loader';
import { Traits } from '../abc/lazy/Traits';
/**
* All code lives within an application domain.
*/
var AXApplicationDomain = /** @class */ (function () {
function AXApplicationDomain(sec, parent) {
this.sec = sec;
this.parent = parent;
this.system = parent ? parent.system : this;
this._abcs = [];
this._binarySymbols = {};
}
AXApplicationDomain.prototype.addBinarySymbol = function (symbol) {
this._binarySymbols[symbol.className] = symbol;
};
AXApplicationDomain.prototype.getBinarySymbol = function (className) {
return this._binarySymbols[className];
};
AXApplicationDomain.prototype.loadABC = function (abc) {
assert(this._abcs.indexOf(abc) < 0);
this._abcs.push(abc);
};
AXApplicationDomain.prototype.loadAndExecuteABC = function (abc) {
this.loadABC(abc);
this.executeABC(abc);
};
AXApplicationDomain.prototype.executeABC = function (abc) {
var lastScript = abc.scripts[abc.scripts.length - 1];
this.executeScript(lastScript);
};
AXApplicationDomain.prototype.findClassInfoDeep = function (name) {
var info = this.findClassInfo(name);
if (info)
return info;
if (this.parent) {
info = this.parent.findClassInfo(name);
if (info)
return info;
}
return null;
};
AXApplicationDomain.prototype.findClassInfo = function (name) {
var argName = typeof name === 'string' ? name : name.name;
var uri = typeof name === 'string' ? '' : name.namespaces[0].uri;
for (var i = 0; i < this._abcs.length; i++) {
var abc = this._abcs[i];
for (var j = 0; j < abc.instances.length; j++) {
var c = abc.classes[j];
var mn = c.instanceInfo.multiname;
if (mn.name === argName && mn.namespaces[0].uri == uri) {
return c;
}
}
}
return null;
};
AXApplicationDomain.prototype.executeScript = function (scriptInfo) {
assert(scriptInfo.state === 0 /* ScriptInfoState.None */);
runtimeWriter && runtimeWriter.writeLn('Running Script: ' + scriptInfo);
var global = this.sec.createAXGlobal(this, scriptInfo);
scriptInfo.global = global;
scriptInfo.state = 1 /* ScriptInfoState.Executing */;
interpret(scriptInfo.methodInfo, global.scope, null).apply(global, []);
scriptInfo.state = 2 /* ScriptInfoState.Executed */;
};
AXApplicationDomain.prototype.findProperty = function (mn, _strict, execute) {
var _a;
if (mn.globalInfo)
return mn.globalInfo.global;
var globalInfo = ((_a = Traits.getGlobalTrait(mn)) === null || _a === void 0 ? void 0 : _a.holder)
|| this.findDefiningGlobal(mn, execute);
if (!globalInfo)
return;
if (!mn.mutable)
mn.globalInfo = globalInfo;
if (execute && globalInfo instanceof ScriptInfo && globalInfo.state === 0 /* ScriptInfoState.None */) {
this.executeScript(globalInfo);
}
return globalInfo.global || (globalInfo.global = this.sec.createAXGlobal(this, globalInfo));
};
AXApplicationDomain.prototype.getClass = function (mn) {
var classObject = this.getProperty(mn, true, true);
if (classObject && !classObject.axApplicationDomain) {
classObject.axApplicationDomain = this;
}
return classObject;
};
AXApplicationDomain.prototype.getProperty = function (mn, strict, execute) {
var global = this.findProperty(mn, strict, execute);
if (global)
return global.axGetProperty(mn);
if (mn.name != 'void')
this.sec.throwError('ReferenceError', Errors.DefinitionNotFoundError, mn.name);
};
AXApplicationDomain.prototype.findDefiningGlobal = function (mn, execute) {
var _a;
// Look in parent domain first.
var globalInfo;
// Still no luck, so let's ask the security domain to load additional ABCs and try again.
var abc = this.system.sec.findDefiningABC(mn);
if (abc) {
this.loadABC(abc);
globalInfo = (_a = Traits.getGlobalTrait(mn)) === null || _a === void 0 ? void 0 : _a.holder;
release || assert(globalInfo, 'Shall find class in loaded ABC');
return globalInfo;
}
return null;
};
return AXApplicationDomain;
}());
export { AXApplicationDomain };