/// <summary> /// Read in the method bytecode bodies /// </summary> private void ReadMethodBodies() { uint bodyCount = this.abcdtr.ReadU30(); #if DEBUG if (this.ReadLog != null) { this.ReadLog.AppendLine("Body count: " + bodyCount); } #endif while (bodyCount-- > 0) { Method m = this.code.GetMethod((int)this.abcdtr.ReadU30()); m.MaxStack = this.abcdtr.ReadU30(); m.LocalCount = this.abcdtr.ReadU30(); m.InitScopeDepth = this.abcdtr.ReadU30(); m.MaxScopeDepth = this.abcdtr.ReadU30(); m.Bytes = this.abcdtr.ReadByteBlock((int)this.abcdtr.ReadU30()); #if DEBUG if (this.ReadLog != null) { this.ReadLog.AppendLine("Method: " + m); this.ReadLog.AppendLine(" max stack: " + m.MaxStack); this.ReadLog.AppendLine(" locals: " + m.LocalCount); this.ReadLog.AppendLine(" init scope depth: " + m.InitScopeDepth); this.ReadLog.AppendLine(" max scope depth: " + m.MaxScopeDepth); } #endif /* Read exception handlers, but ignore for now */ uint exceptionCount = this.abcdtr.ReadU30(); while (exceptionCount-- > 0) { ExceptionHandler eh = new ExceptionHandler(); eh.From = (int)this.abcdtr.ReadU30(); eh.To = (int)this.abcdtr.ReadU30(); eh.Target = (int)this.abcdtr.ReadU30(); eh.CatchType = this.code.GetMultiname((int)this.abcdtr.ReadU30()); eh.VarName = this.code.GetMultiname((int)this.abcdtr.ReadU30()); m.AddExceptionHandler(eh); } uint traitCount = this.abcdtr.ReadU30(); while (traitCount-- > 0) { m.AddTrait(this.ReadTrait()); } } }
/// <summary> /// Generates a script that binds a class to a clip. /// </summary> /// <param name="spr">The sprite to create the class for.</param> public void GenerateClipClassBindingScript(Sprite spr) { Namespace nsEmptyPackage = this.CreateNamespace(Namespace.NamespaceKind.Package, string.Empty); Namespace nsFlashEvents = this.CreateNamespace(Namespace.NamespaceKind.Package, "flash.events"); Namespace nsFlashDisplay = this.CreateNamespace(Namespace.NamespaceKind.Package, "flash.display"); Multiname mnObject = this.CreateMultiname(Multiname.MultinameKind.QName, "Object", nsEmptyPackage, null); Multiname mnEventDispatcher = this.CreateMultiname(Multiname.MultinameKind.QName, "EventDispatcher", nsFlashEvents, null); Multiname mnDisplayObject = this.CreateMultiname(Multiname.MultinameKind.QName, "DisplayObject", nsFlashDisplay, null); Multiname mnInteractiveObject = this.CreateMultiname(Multiname.MultinameKind.QName, "InteractiveObject", nsFlashDisplay, null); Multiname mnDisplayObjectContainer = this.CreateMultiname(Multiname.MultinameKind.QName, "DisplayObjectContainer", nsFlashDisplay, null); Multiname mnSprite = this.CreateMultiname(Multiname.MultinameKind.QName, "Sprite", nsFlashDisplay, null); Multiname mnMovieClip = this.CreateMultiname(Multiname.MultinameKind.QName, "MovieClip", nsFlashDisplay, null); Multiname sprQName = null; Multiname sprMultiname = null; if (spr.Class.Name.Kind == Multiname.MultinameKind.Multiname) { sprMultiname = spr.Class.Name; /* ISSUE 5: Convert a multiname to a QName of the form: * mn QName "MyClassName"; ns Package "com.mypackage"; set * */ throw new SWFModellerException( SWFModellerError.UnimplementedFeature, "Unsupported sprite class name kind in class binding script generation: " + spr.Class.Name.Kind.ToString()); } else if (spr.Class.Name.Kind == Multiname.MultinameKind.QName) { sprQName = spr.Class.Name; /* Convert to form: * mn Multiname "MyClassName"; ns *; set {ns Package "com.mypackage"} */ sprMultiname = this.CreateMultiname( Multiname.MultinameKind.Multiname, sprQName.Name, nsEmptyPackage, this.CreateNamespaceSet(new Namespace[] { sprQName.NS })); } else { /* ISSUE 73 */ throw new SWFModellerException( SWFModellerError.UnimplementedFeature, "Unsupported sprite class name kind in class binding script generation: " + spr.Class.Name.Kind.ToString()); } Method bindingMethod = this.CreateMethod(spr.Class.Name.Name + "BindingScript.abc", 2, 1, 1, 9, /* The above magic numbers come from the numbers generated by IDE versions of this function. * I have no real ideal about how I'd work them out for myself, which would obviously be * more ideal. */ /* Line */ /* 1 */ this.Op(Opcode.Mnemonics.GetLocal0), /* 2 */ this.Op(Opcode.Mnemonics.PushScope), /* 3 */ this.Op(Opcode.Mnemonics.FindPropStrict, sprMultiname), /* 4 */ this.Op(Opcode.Mnemonics.GetLex, mnObject), /* 5 */ this.Op(Opcode.Mnemonics.PushScope), /* 6 */ this.Op(Opcode.Mnemonics.GetLex, mnEventDispatcher), /* 7 */ this.Op(Opcode.Mnemonics.PushScope), /* 8 */ this.Op(Opcode.Mnemonics.GetLex, mnDisplayObject), /* 9 */ this.Op(Opcode.Mnemonics.PushScope), /* 10 */ this.Op(Opcode.Mnemonics.GetLex, mnInteractiveObject), /* 11 */ this.Op(Opcode.Mnemonics.PushScope), /* 12 */ this.Op(Opcode.Mnemonics.GetLex, mnDisplayObjectContainer), /* 13 */ this.Op(Opcode.Mnemonics.PushScope), /* 14 */ this.Op(Opcode.Mnemonics.GetLex, mnSprite), /* 15 */ this.Op(Opcode.Mnemonics.PushScope), /* 16 */ this.Op(Opcode.Mnemonics.GetLex, mnMovieClip), /* 17 */ this.Op(Opcode.Mnemonics.PushScope), /* 18 */ this.Op(Opcode.Mnemonics.GetLex, mnMovieClip), /* 19 */ this.Op(Opcode.Mnemonics.NewClass, spr.Class), /* 20 */ this.Op(Opcode.Mnemonics.PopScope), /* 21 */ this.Op(Opcode.Mnemonics.PopScope), /* 22 */ this.Op(Opcode.Mnemonics.PopScope), /* 23 */ this.Op(Opcode.Mnemonics.PopScope), /* 24 */ this.Op(Opcode.Mnemonics.PopScope), /* 25 */ this.Op(Opcode.Mnemonics.PopScope), /* 26 */ this.Op(Opcode.Mnemonics.PopScope), /* 27 */ this.Op(Opcode.Mnemonics.InitProperty, sprQName), /* 28 */ this.Op(Opcode.Mnemonics.ReturnVoid)); Trait classTrait = new ClassTrait() { As3class = (AS3ClassDef)spr.Class, Kind = TraitKind.Class, Name = sprQName }; bindingMethod.AddTrait(classTrait); Script bindScript = new Script() { Method = bindingMethod, }; bindScript.AddTrait(classTrait); this.scripts.Insert(0, bindScript); /* Insert at the start to make sure any timeline script is last. */ }