@awayfl/avm2
Version:
Virtual machine for executing AS3 code
372 lines (371 loc) • 13.8 kB
JavaScript
import { __extends } from "tslib";
import { Multiname } from './../abc/lazy/Multiname';
import { getExtClassField, extClasses, LONG_NAMES } from '../ext/external';
var LexImportsGenerator = /** @class */ (function () {
function LexImportsGenerator() {
this.imports = [];
this._lexMode = false;
}
LexImportsGenerator.prototype.test = function (_mn, _isLexCall) {
return false;
};
LexImportsGenerator.prototype._genEntry = function (def) {
var args = [];
for (var _i = 1; _i < arguments.length; _i++) {
args[_i - 1] = arguments[_i];
}
return '//' + def.name;
};
LexImportsGenerator.prototype._genAlias = function (mn, _options) {
return mn.namespace.uri.replace(/\./g, '_') + '__' + mn.name;
};
LexImportsGenerator.prototype.findAliases = function (mn, findProp) {
return this.imports.filter(function (e) {
return e.name === mn && (findProp ? findProp === e.options.findProp : true);
});
};
LexImportsGenerator.prototype.getLexAlias = function (mn, options) {
this._lexMode = true;
var res = this.getPropStrictAlias(mn, Object.assign({ findProp: true, mnIndex: -1 }, options || {}));
this._lexMode = false;
return res;
};
LexImportsGenerator.prototype.getPropStrictAlias = function (mn, options) {
var _a;
if (options === void 0) { options = { findProp: false, mnIndex: -1 }; }
if (!this.test(mn, this._lexMode)) {
throw "Can't generate static alias for ".concat(mn.name, " of ").concat((_a = mn.namespace) === null || _a === void 0 ? void 0 : _a.uri);
}
var def = this.imports.find(function (e) {
return e.name === mn && options.findProp === e.options.findProp;
});
if (def) {
return def.alias;
}
var alias = this._genAlias(mn, options);
if (!this.imports.find(function (e) { return e.alias === alias; })) {
this.imports.push({
name: mn,
alias: alias,
options: options
});
}
return alias;
};
LexImportsGenerator.prototype.genHeader = function (ident) {
if (ident === void 0) { ident = ''; }
var args = [];
for (var _i = 1; _i < arguments.length; _i++) {
args[_i - 1] = arguments[_i];
}
if (!this.imports.length) {
return '';
}
var header = ["\n".concat(ident, " /* ").concat(this.constructor.name, " */")];
for (var _a = 0, _b = this.imports; _a < _b.length; _a++) {
var def = _b[_a];
header.push(ident + ' ' + this._genEntry(def));
}
header.push('\n');
return header.join('\n');
};
LexImportsGenerator.prototype.genBody = function (_ident) {
if (_ident === void 0) { _ident = ''; }
var _args = [];
for (var _i = 1; _i < arguments.length; _i++) {
_args[_i - 1] = arguments[_i];
}
return '';
};
LexImportsGenerator.prototype.genPost = function (input) {
return input;
};
LexImportsGenerator.prototype.reset = function () {
this.imports.length = 0;
};
return LexImportsGenerator;
}());
export { LexImportsGenerator };
/**
* Generate imports for all lex generators
*/
var ComplexGenerator = /** @class */ (function () {
function ComplexGenerator(generators) {
this.generators = generators;
/**
* Allowed collsion for alias of generator, return first alias;
*/
this.allowColissions = false;
if (!generators) {
throw 'Generators array can\'t be null';
}
}
/**
* Return generator that will used for lex generation
*/
ComplexGenerator.prototype.getGenerator = function (mn, isLexCall) {
for (var _i = 0, _a = this.generators; _i < _a.length; _i++) {
var g = _a[_i];
if (g.test(mn, isLexCall)) {
return g;
}
}
return null;
};
ComplexGenerator.prototype.test = function (mn, isLexCall) {
if (!this.generators.length) {
return false;
}
return !!this.getGenerator(mn, isLexCall);
};
ComplexGenerator.prototype.findAliases = function (mn, findProp) {
var res = [];
for (var _i = 0, _a = this.generators; _i < _a.length; _i++) {
var g = _a[_i];
res = res.concat(g.findAliases(mn, findProp));
}
return res;
};
/**
* Return generator that will used for propstrict generation
*/
ComplexGenerator.prototype.getLexAlias = function (mn, options) {
var _a;
var gen = this.getGenerator(mn, true);
if (!gen) {
throw "Can't generate static alias for ".concat(mn.name, " of ").concat((_a = mn.namespace) === null || _a === void 0 ? void 0 : _a.uri);
}
return gen.getLexAlias(mn, options);
};
ComplexGenerator.prototype.getPropStrictAlias = function (mn, options) {
var _a;
var gen = this.getGenerator(mn, false);
if (!gen) {
throw "Can't generate static alias for ".concat(mn.name, " of ").concat((_a = mn.namespace) === null || _a === void 0 ? void 0 : _a.uri);
}
return gen.getPropStrictAlias(mn, options);
};
ComplexGenerator.prototype.genHeader = function (ident) {
var header = '';
for (var _i = 0, _a = this.generators; _i < _a.length; _i++) {
var g = _a[_i];
header += g.genHeader(ident);
}
return header;
};
ComplexGenerator.prototype.genBody = function (ident) {
var body = '';
for (var _i = 0, _a = this.generators; _i < _a.length; _i++) {
var g = _a[_i];
body += g.genBody(ident);
}
return body;
};
ComplexGenerator.prototype.genPost = function (arr) {
for (var _i = 0, _a = this.generators; _i < _a.length; _i++) {
var g = _a[_i];
arr = g.genPost(arr);
}
return arr;
};
ComplexGenerator.prototype.reset = function () {
this.generators.forEach(function (e) { return e.reset(); });
};
return ComplexGenerator;
}());
export { ComplexGenerator };
/* -------------------- GENERATORS ------------------- */
/**
* Import generator for Box2D and Nape external libs
*/
var PhysicsLex = /** @class */ (function (_super) {
__extends(PhysicsLex, _super);
function PhysicsLex(allows) {
if (allows === void 0) { allows = null; }
var _this = _super.call(this) || this;
_this.allows = allows;
_this.allows = Object.assign({ box2D: true, nape: true }, allows);
return _this;
}
PhysicsLex.prototype._genEntry = function (def) {
var uri = def.name.namespace.uri;
var name = def.name.name;
return "const ".concat(def.alias, " = context.getStaticImportExt('").concat(uri, "', '").concat(name, "');");
};
PhysicsLex.prototype._genAlias = function (mn, _options) {
return mn.namespace.uri.replace(/\./g, '_') + '__' + mn.name;
};
PhysicsLex.prototype.test = function (mn) {
var _a, _b;
var uri = (_a = mn.namespace) === null || _a === void 0 ? void 0 : _a.uri;
if (!uri || !extClasses.lib) {
return false;
}
// generate static for box2D
if (uri.startsWith('Box2D') && !this.allows.box2D) {
return false;
}
if (uri.startsWith('nape.') && !this.allows.nape) {
return false;
}
if (mn.name.includes('Debug')) {
return false;
}
var ns = (_b = mn.namespace) === null || _b === void 0 ? void 0 : _b.uri;
var isLong = ns && LONG_NAMES.test(ns);
return !!getExtClassField(mn.name, isLong ? ns : undefined);
};
return PhysicsLex;
}(LexImportsGenerator));
export { PhysicsLex };
var ALLOWED_TOP_LEVEL_NAMES = [
'flash.geom',
'flash.utils',
'Math',
'trace',
'parseInt',
'RegExp'
];
var NOT_ALLOWED = [
'getDefinitionByName',
'SetIntervalTimer',
'setTimeout',
':trace'
];
/**
* @description Generete single constant reference on top level API props: trace, pareseInt etc
*/
var TopLevelLex = /** @class */ (function (_super) {
__extends(TopLevelLex, _super);
function TopLevelLex() {
return _super !== null && _super.apply(this, arguments) || this;
}
TopLevelLex.prototype.test = function (mn) {
var _a;
var uri = ((_a = mn.namespace) === null || _a === void 0 ? void 0 : _a.uri) || '';
var name = mn.name;
if (typeof uri === 'undefined') {
return false;
}
if (NOT_ALLOWED.indexOf(name) > -1 ||
NOT_ALLOWED.indexOf(uri) > -1) {
return false;
}
if ((ALLOWED_TOP_LEVEL_NAMES.indexOf(name) > -1 && !uri) || // trace, Math
ALLOWED_TOP_LEVEL_NAMES.indexOf(uri) > -1) {
return true;
}
return false;
};
TopLevelLex.prototype._genEntry = function (def) {
var uri = def.name.namespace.uri;
var name = def.name.name;
var _a = def.options || {}, mnIndex = _a.mnIndex, findProp = _a.findProp;
if (typeof mnIndex !== 'number' || mnIndex < 0) {
throw 'Name alias required for generatin Toplevel exports!';
}
var id = mnIndex;
var mnname = "['".concat(Multiname.getPublicMangledName(name), "']");
return "const ".concat(def.alias, " = context.getTopLevel(").concat(id, ")").concat(findProp ? mnname : '', "; // ").concat(uri, ":").concat(name);
};
TopLevelLex.prototype._genAlias = function (mn, options) {
var uri = mn.namespace.uri.split(/[.:]/g);
if (typeof options.mnIndex !== 'number' || options.mnIndex < 0) {
throw 'Name alias required for generatin Toplevel exports!';
}
return "".concat(uri.join('_'), "__").concat(mn.name).concat(options.findProp ? '' : '_def');
};
return TopLevelLex;
}(LexImportsGenerator));
export { TopLevelLex };
/**
* @description Generate single reference on class namespace/class with static field
*/
var StaticHoistLex = /** @class */ (function (_super) {
__extends(StaticHoistLex, _super);
function StaticHoistLex() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this._mn = new Set();
_this._loc = {};
return _this;
}
StaticHoistLex.prototype.markScope = function (name, pos) {
if (pos === void 0) { pos = 0; }
if (!pos) {
throw 'Scope location should be marked!';
}
this._loc[name] = pos;
};
StaticHoistLex.prototype.test = function (mn, isLexCall) {
if (!isLexCall) {
return false;
}
// when there are not URI and no public - skip
if (!mn.uri || mn.namespace.type !== 0 /* NamespaceType.Public */) {
return false;
}
if (!this._mn.has(mn)) {
this._mn.add(mn);
return false;
}
return true;
};
StaticHoistLex.prototype._genAlias = function (mn, options) {
var uri = mn.namespace.uri.split(/[.|:]/g);
var opt = options;
if (!opt.nameAlias) {
throw 'Name alias required for generatin FirstUsageScopeLex exports!';
}
if (!opt.scope) {
throw 'Scope alias required for generatin FirstUsageScopeLex exports!';
}
return "".concat(uri.join('_'), "__").concat(mn.name);
};
StaticHoistLex.prototype.findAliases = function () {
return [];
};
StaticHoistLex.prototype.genHeader = function () {
return '';
};
StaticHoistLex.prototype.genBody = function (idnt) {
if (!this.imports.length) {
return '';
}
var body = ["".concat(idnt, " // ").concat(this.constructor.name, " ")];
for (var _i = 0, _a = this.imports; _i < _a.length; _i++) {
var imp = _a[_i];
body.push("".concat(idnt, " let ").concat(imp.alias, "; // ").concat(imp.name));
}
return body.join('\n');
};
StaticHoistLex.prototype.genPost = function (arr) {
for (var _i = 0, _a = this.imports; _i < _a.length; _i++) {
var def = _a[_i];
var opt = def.options;
var loc = this._loc[opt.scope];
if (!loc) {
throw 'Unknow import for scope:' + opt.scope;
}
//@ts-ignore
var idnt = arr[loc].length - arr[loc].trimLeft().length - 1;
arr.splice(loc + 1, 0, this._genEntry(def, ' '.repeat(idnt)));
}
return arr;
};
StaticHoistLex.prototype._genEntry = function (def, idnt) {
if (idnt === void 0) { idnt = ' '; }
var js = [];
var mn = def.name;
var opt = def.options;
js.push("".concat(idnt, " // "));
js.push("".concat(idnt, " // ").concat(mn));
js.push("".concat(idnt, " temp = ").concat(opt.scope, ".findScopeProperty(").concat(opt.nameAlias, ", true, false);"));
js.push("".concat(idnt, " ").concat(def.alias, " = temp['$Bg").concat(mn.name, "'];"));
js.push("".concat(idnt, " if (").concat(def.alias, " === undefined || typeof ").concat(def.alias, " === 'function') {"));
js.push("".concat(idnt, " ").concat(def.alias, " = temp.axGetProperty(").concat(opt.nameAlias, ");"));
js.push("".concat(idnt, " }"));
return js.join('\n');
};
return StaticHoistLex;
}(LexImportsGenerator));
export { StaticHoistLex };