UNPKG

@awayfl/avm2

Version:

Virtual machine for executing AS3 code

70 lines (56 loc) 2.1 kB
import { AXObject } from '../run/AXObject'; import { ASFunction } from './ASFunction'; import { defineNonEnumerableProperty } from '@awayfl/swf-loader'; import { AXCallable } from '../run/AXCallable'; import { Errors } from '../errors'; import { sliceArguments } from '../run/writers'; export class ASMethodClosure extends ASFunction { static classInitializer() { const proto: any = this.dPrototype; const asProto: any = ASMethodClosure.prototype; defineNonEnumerableProperty(proto, '$Bgcall', asProto.call); defineNonEnumerableProperty(proto, '$Bgapply', asProto.apply); } static Create(receiver: AXObject, method: AXCallable) { // hack, create a real closure and change prototype onto AXMethodClosure // now we can invoke closure as regular function // fix for click heroes const closure = function () { // eslint-disable-next-line prefer-rest-params return (<any> closure.value).apply(closure.receiver, arguments); }; Object.setPrototypeOf(closure,this.sec.AXMethodClosure.tPrototype); closure.__isClosure = true; closure.receiver = <any>receiver; closure.value = method; closure.methodInfo = method.methodInfo; closure.axCall = closure.call; closure.axApply = closure.apply; return closure; } get prototype(): AXObject { return null; } set prototype(prototype: AXObject) { this.sec.throwError('ReferenceError', Errors.ConstWriteError, 'prototype', 'MethodClosure'); } axCall(ignoredThisArg: any): any { return this.value.apply(this.receiver, sliceArguments(arguments, 1)); } axApply(ignoredThisArg: any, argArray?: any[]): any { return this.value.apply(this.receiver, argArray); } call(ignoredThisArg: any) { const args = arguments; const len = args.length; if (len <= 6) { return this.value.call(this.receiver, args[1], args[2], args[3], args[4], args[5]); } else { return this.value.apply(this.receiver, sliceArguments(arguments, 1)); } } apply(ignoredThisArg: any, argArray?: any): any { return this.value.apply(this.receiver, (argArray && argArray.value) ? argArray.value : argArray); } }