UNPKG

@awayfl/avm2

Version:

Virtual machine for executing AS3 code

153 lines (152 loc) 5.46 kB
import { jsGlobal } from '@awayfl/swf-loader'; import { Errors } from '../errors'; import { wrapJSGlobalFunction } from './wrapJSGlobalFunction'; import { checkValue } from '../run/checkValue'; import { release, assertUnreachable, notImplemented } from '@awayfl/swf-loader'; import { isNullOrUndefined } from '@awayjs/graphics'; import { axCoerceString } from '../run/axCoerceString'; import { getCurrentABC } from '../run/getCurrentABC'; import { Multiname } from '../abc/lazy/Multiname'; import { describeType as describeTypeIntern } from '../natives/describeType'; var getQualifiedClassName = function (_, value) { release || checkValue(value); var valueType = typeof value; switch (valueType) { case 'undefined': return 'void'; case 'object': if (value === null) { return 'null'; } return value.classInfo.instanceInfo.multiname.toFQNString(true); case 'number': return (value | 0) === value ? 'int' : 'Number'; case 'string': return 'String'; case 'boolean': return 'Boolean'; } release || assertUnreachable('invalid value type ' + valueType); }; /** * Other natives can live in this module */ export var Natives = { print: function (sec, expression, arg1, arg2, arg3, arg4) { var message; var objects = []; if (arguments.length == 2) { message = arguments[1] ? arguments[1].toString() : arguments[1]; if (['string', 'boolean', 'number', 'null', 'undefined'].indexOf(typeof arguments[1]) === -1) objects.push(arguments[1]); } else { message = ''; for (var i = 1; i < arguments.length; i++) { message += arguments[i] ? arguments[i].toString() : arguments[i]; if (['string', 'boolean', 'number', 'null', 'undefined'].indexOf(typeof arguments[i]) === -1) objects.push(arguments[i]); if (i != arguments.length - 1) message += ' '; } } console.log('%c Trace from SWF:', 'color: DodgerBlue', message, objects.length == 0 ? '' : objects); if (message == 'debugger') { debugger; } }, debugBreak: function (v) { /* tslint:disable */ debugger; /* tslint:enable */ }, bugzilla: function (_, n) { switch (n) { case 574600: // AS3 Vector::map Bug return true; } return false; }, decodeURI: function (sec, encodedURI) { try { return jsGlobal.decodeURI(encodedURI); } catch (e) { sec.throwError('URIError', Errors.InvalidURIError, 'decodeURI'); } }, decodeURIComponent: function (sec, encodedURI) { try { return jsGlobal.decodeURIComponent(encodedURI); } catch (e) { sec.throwError('URIError', Errors.InvalidURIError, 'decodeURIComponent'); } }, encodeURI: function (sec, uri) { try { return jsGlobal.encodeURI(uri); } catch (e) { sec.throwError('URIError', Errors.InvalidURIError, 'encodeURI'); } }, encodeURIComponent: function (sec, uri) { try { return jsGlobal.encodeURIComponent(uri); } catch (e) { sec.throwError('URIError', Errors.InvalidURIError, 'encodeURIComponent'); } }, isNaN: wrapJSGlobalFunction(jsGlobal.isNaN), isFinite: wrapJSGlobalFunction(jsGlobal.isFinite), parseInt: wrapJSGlobalFunction(jsGlobal.parseInt), parseFloat: wrapJSGlobalFunction(jsGlobal.parseFloat), escape: wrapJSGlobalFunction(jsGlobal.escape), unescape: wrapJSGlobalFunction(jsGlobal.unescape), isXMLName: function () { return false; // "FIX ME"; }, notImplemented: wrapJSGlobalFunction(notImplemented), /** * Returns the fully qualified class name of an object. */ getQualifiedClassName: function (_, value) { return getQualifiedClassName(_, value); }, /** * Returns the fully qualified class name of the base class of the object specified by the * |value| parameter. */ getQualifiedSuperclassName: function (sec, value) { if (isNullOrUndefined(value)) { return 'null'; } value = sec.box(value); // The value might be from another domain, so don't use passed-in the current // AXSecurityDomain. var axClass = value.sec.AXClass.axIsType(value) ? value.superClass : value.axClass.superClass; return getQualifiedClassName(sec, axClass); }, /** * Returns the class with the specified name, or |null| if no such class exists. */ getDefinitionByName: function (sec, name) { name = axCoerceString(name).replace('::', '.'); var mn = Multiname.FromFQNString(name, 0 /* NamespaceType.Public */); return getCurrentABC().env.app.getClass(mn); }, describeType: function (sec, value, flags) { return describeTypeIntern(sec, value, flags); }, describeTypeJSON: function (sec, value, flags) { console.log('describeTypeJSON not implemented'); return null; //describeTypeJSON(sec, value, flags); }, getArgv: function () { return null; } };