@awayfl/avm2
Version:
Virtual machine for executing AS3 code
101 lines (100 loc) • 3.55 kB
JavaScript
/**
* @description Generate a simple call instruction (witout runtime checks) on lexed alliases
*/
var FastCall = /** @class */ (function () {
function FastCall(lexer, scope) {
if (scope === void 0) { scope = null; }
this.lexer = lexer;
this.scope = scope;
this.safeIntrDistance = 20;
this._active = {};
this._imports = [];
}
FastCall.prototype.checkNameToCall = function (mn, propname, lex) {
if (lex === void 0) { lex = false; }
if (!this.scope) {
return false;
}
var obj = this.scope.findScopeProperty(mn, true, false);
if (!lex) {
return obj && typeof obj[propname] === 'function';
}
return obj && obj[mn.getMangledName()] && typeof obj[mn.getMangledName()][propname] === 'function';
};
FastCall.prototype.mark = function (alias, index, isMangled, name, fromLex) {
if (name === void 0) { name = null; }
if (fromLex === void 0) { fromLex = false; }
this._active[alias] = { alias: alias, index: index, name: name, isMangled: isMangled, fromLex: fromLex };
};
FastCall.prototype.sureThatFast = function (stackAlias, method) {
var d = this._active[stackAlias];
if (!d || (method && !d.name)) {
return null;
}
if (method && this.checkNameToCall(d.name, method, d.fromLex)) {
d.isFunc = true;
}
return d;
};
FastCall.prototype.getMethodAlias = function (stackAlias, method) {
var d = this._active[stackAlias];
if (!d || !d.isFunc || !d.name) {
return null;
}
var lexedImportD = this.lexer.findAliases(d.name, false)[0];
if (!lexedImportD) {
return null;
}
var lexedImport = lexedImportD.alias;
var methodALias = lexedImport + '_' + method;
var declare = this._imports.find(function (e) { return e.methodAlias === methodALias; });
if (declare) {
return declare.methodAlias;
}
else {
d.methodAlias = methodALias;
d.methodImport = lexedImport + '.' + method;
this._imports.push(d);
}
return methodALias;
};
FastCall.prototype.kill = function (stackAlias) {
delete this._active[stackAlias];
};
FastCall.prototype.killFar = function (index) {
var keys = Object.keys(this._active);
for (var _i = 0, keys_1 = keys; _i < keys_1.length; _i++) {
var k = keys_1[_i];
if (index - this._active[k].index >= this.safeIntrDistance) {
delete this._active[k];
}
}
};
FastCall.prototype.genHeader = function (ident) {
var header = ["".concat(ident, " /* ").concat(this.constructor.name, " */")];
for (var _i = 0, _a = this._imports; _i < _a.length; _i++) {
var d = _a[_i];
header.push("".concat(ident, " const ").concat(d.methodAlias, " = ").concat(d.methodImport, ";"));
}
header.push('\n');
return header.join('\n');
};
FastCall.prototype.genBody = function () {
return '';
};
/**
* Drop fastCall cache
*/
FastCall.prototype.drop = function () {
this._active = {};
};
FastCall.prototype.genPost = function (arr) {
return arr;
};
FastCall.prototype.reset = function () {
this._active = {};
this._imports = [];
};
return FastCall;
}());
export { FastCall };