示例#1
0
        internal AbcMethod DefineMethod(Sig sig, AbcCoder coder)
        {
            var method = new AbcMethod
            {
                ReturnType = sig.ReturnType != null
                                                         ? DefineTypeNameSafe(sig.ReturnType)
                                                         : null
            };

            if (sig.Args != null)
            {
                AddParameters(method.Parameters, sig.Args);
            }

            var body = new AbcMethodBody(method);

            AddMethod(method);

            if (coder != null)
            {
                var code = new AbcCode(this);
                coder(code);
                body.Finish(code);
            }

            return(method);
        }
示例#2
0
        public static AbcTrait CreateMethod(AbcMethod method, AbcMultiname name)
        {
            var t = CreateMethod(method);

            t.Name = name;
            return(t);
        }
示例#3
0
        public void Read(SwfReader reader)
        {
            _method      = reader.ReadAbcMethod();
            _method.Body = this;

            MaxStackDepth = (int)reader.ReadUIntEncoded();
            LocalCount    = (int)reader.ReadUIntEncoded();
            MinScopeDepth = (int)reader.ReadUIntEncoded();
            MaxScopeDepth = (int)reader.ReadUIntEncoded();

            int len  = (int)reader.ReadUIntEncoded();
            var code = reader.ReadUInt8(len);

            _exceptions.Read(reader);
            _traits.Read(reader);

            _il = new ILStream();

            if (len > 0)
            {
                var codeReader = new SwfReader(code)
                {
                    ABC = reader.ABC
                };
                _il.Read(this, codeReader);
            }
        }
示例#4
0
        private AbcMultiname BuildReturnType(object returnType, AbcMethod method)
        {
            if (returnType == null)
            {
                return(Abc.DefineTypeName(AvmTypeCode.Void));
            }

            var generator = Abc.Generator;

            var source = returnType as IMethod;

            if (source != null)
            {
                return(generator.MethodBuilder.BuildReturnType(method, source));
            }

            var type = returnType as IType;

            if (type != null)
            {
                return(generator.TypeBuilder.BuildReturnType(type));
            }

            return(Abc.DefineTypeNameSafe(returnType));
        }
示例#5
0
        //Used to define static initializer for interfaces
        public AbcMethod DefineEmptyAbstractMethod()
        {
            var method = new AbcMethod();

            Methods.Add(method);
            return(method);
        }
示例#6
0
 public void CopyFrom(AbcMethod method)
 {
     if (method == null)
     {
         throw new ArgumentNullException("method");
     }
     CopyFrom(method.Parameters);
 }
示例#7
0
        /// <summary>
        /// Determines whether the given <see cref="AbcMethod"/> is defined in this ABC file.
        /// </summary>
        /// <param name="method">method to check</param>
        /// <returns></returns>
        public bool IsDefined(AbcMethod method)
        {
            int index = method.Index;

            if (index < 0 || index >= Methods.Count)
            {
                return(false);
            }
            return(ReferenceEquals(Methods[index], method));
        }
示例#8
0
 private void ImportTraits(IAbcTraitProvider from, IAbcTraitProvider to, ref AbcMethod importMethod)
 {
     foreach (var trait in from.Traits)
     {
         var t2 = ImportTrait(trait);
         if (trait.Method == importMethod)
         {
             importMethod = t2.Method;
         }
         to.Traits.Add(t2);
     }
 }
示例#9
0
 private void ImportParams(AbcMethod from, AbcMethod to)
 {
     foreach (var p in from.Parameters)
     {
         var p2 = new AbcParameter
         {
             IsOptional = p.IsOptional,
             Name       = ImportConst(p.Name),
             Type       = ImportType(p.Type),
             Value      = ImportValue(p.Value)
         };
         to.Parameters.Add(p2);
     }
 }
示例#10
0
        public void AddMethod(AbcMethod method)
        {
            if (method == null)
            {
                throw new ArgumentNullException("method");
            }
            Methods.Add(method);
            var body = method.Body;

            if (body != null)
            {
                MethodBodies.Add(body);
            }
        }
示例#11
0
        private AbcMethod ImportMethod(AbcMethod method)
        {
            if (IsDefined(method))
            {
                return(method);
            }

            if (method.ImportedMethod != null)
            {
                return(method.ImportedMethod);
            }

            var m = new AbcMethod
            {
                Name           = ImportConst(method.Name),
                Flags          = method.Flags,
                IsInitializer  = method.IsInitializer,
                OriginalMethod = method,
                Method         = method.Method,
                ReturnType     = ImportType(method.ReturnType)
            };

            method.ImportedMethod = m;
            method.IsImported     = true;

            if (m.Method != null)
            {
                SetData(m.Method, m);
            }

            ImportParams(method, m);

            Methods.Add(m);

            var body = method.Body;

            if (body != null)
            {
                m.Body = ImportMethodBody(body, m);
            }

            return(m);
        }
示例#12
0
 private static void DumpAccessor(TextWriter writer, AbcMethod m, string tab)
 {
     if (m != null)
     {
         if (AbcDumpService.DumpCode && !m.IsAbstract)
         {
             writer.WriteLine(tab + "get");
             writer.WriteLine(tab + "{");
             if (m.Body != null)
             {
                 m.Body.IL.Dump(writer, tab + "\t");
             }
             writer.WriteLine(tab + "}");
         }
         else
         {
             writer.WriteLine(tab + "get;");
         }
     }
 }
示例#13
0
        public static Sig @from(AbcMethod prototype)
        {
            if (prototype == null)
            {
                throw new ArgumentNullException("prototype");
            }

            var t = prototype.Trait;

            if (t == null)
            {
                throw new InvalidOperationException();
            }

            return(new Sig(t.Name, prototype.ReturnType, prototype)
            {
                Kind = t.Kind,
                Semantics = t.MethodSemantics,
            });
        }
示例#14
0
        private AbcMethodBody ImportMethodBody(AbcMethodBody from, AbcMethod method)
        {
            if (from.ImportedBody != null)
            {
                return(from.ImportedBody);
            }

            var body = new AbcMethodBody(method);

            from.ImportedBody  = body;
            body.MaxStackDepth = from.MaxStackDepth;
            body.LocalCount    = from.LocalCount;
            body.MinScopeDepth = from.MinScopeDepth;
            body.MaxScopeDepth = from.MaxScopeDepth;
            MethodBodies.Add(body);

            ImportTraits(from, body);
            ImportExceptions(body, from);
            ImportIL(body, from);
            body.TranslateIndices();
            body.ResolveExceptionOffsets(this);

            return(body);
        }
示例#15
0
        private AbcInstance ImportInstanceCore(AbcInstance source, ref AbcMethod importMethod)
        {
            var instance = new AbcInstance
            {
                Name         = ImportConst(source.Name),
                IsMixin      = source.IsMixin,
                IsStyleMixin = source.IsStyleMixin,
                ImportedFrom = source
            };

            source.ImportedInstance = instance;

            var klass = new AbcClass(instance);

            AddInstance(instance);

            AbcInstance superType;

            instance.BaseTypeName       = ImportType(source.BaseTypeName, out superType);
            instance.BaseInstance       = superType;
            instance.Flags              = source.Flags;
            instance.ProtectedNamespace = ImportConst(source.ProtectedNamespace);
            instance.Type = source.Type;

            if (instance.Type != null)
            {
                SetData(instance.Type, instance);
            }

            foreach (var iname in source.Interfaces)
            {
                AbcInstance ifaceInstance;
                var         mn = ImportType(iname, out ifaceInstance);
                if (mn == null)
                {
                    throw new InvalidOperationException();
                }
                //NOTE: Flex Compiler Bug!!!
                //I found that within SWC files interface names must be always declared as multinames (with namespace set)
                //This is true for flex 3.
                if (IsSwcScript)
                {
                    mn = ToMultiname(mn);
                }
                instance.Interfaces.Add(mn);
                if (ifaceInstance != null)
                {
                    ifaceInstance.Implementations.Add(instance);
                    instance.Implements.Add(ifaceInstance);
                }
            }

            instance.Initializer = ImportMethod(source.Initializer);
            klass.Initializer    = ImportMethod(source.Class.Initializer);

            if (importMethod == source.Initializer)
            {
                importMethod = instance.Initializer;
            }

            if (importMethod == source.Class.Initializer)
            {
                importMethod = klass.Initializer;
            }

            ImportTraits(source, instance, ref importMethod);
            ImportTraits(source.Class, klass, ref importMethod);

            return(instance);
        }
示例#16
0
        public AbcInstance ImportInstance(AbcInstance instance, ref AbcMethod importMethod)
        {
            if (instance == null)
            {
                return(null);
            }

            if (instance.IsNative)
            {
                return(instance);
            }

            if (instance.UseExternalLinking)
            {
                if (instance.IsLinkedExternally)
                {
                    return(instance);
                }

                if (AllowExternalLinking)
                {
                    instance.IsLinkedExternally = true;
                    if (instance.InSwc)
                    {
                        var abc = instance.Abc;
                        if (!abc._importing)
                        {
                            Debug.Assert(abc != this);
                            Import(abc);
                        }
                    }
                    else
                    {
                        ImportAssets(instance);
                    }
                    return(instance);
                }
            }

            if (IsDefined(instance))
            {
                return(instance);
            }

            if (instance.ImportedInstance != null)
            {
                return(instance.ImportedInstance);
            }

            if (instance.InSwc)
            {
                var abc = instance.Abc;
                if (!abc._importing)
                {
                    Debug.Assert(abc != this);
                    Import(abc);
                }
            }

            if (instance.ImportedInstance != null)
            {
                return(instance.ImportedInstance);
            }

            if (!IsImportTypeExternally)
            {
                var superType = instance.BaseInstance;
                if (superType != null)
                {
                    ImportInstance(superType);
                }
            }

            if (instance.ImportedInstance != null)
            {
                return(instance.ImportedInstance);
            }

            ImportAbcFiles(instance);

            if (instance.ImportedInstance != null)
            {
                return(instance.ImportedInstance);
            }

            var result = ImportInstanceCore(instance, ref importMethod);

            //ImportAbcFiles(instance);

            return(result);
        }
示例#17
0
        /// <summary>
        /// Imports given instance
        /// </summary>
        /// <param name="instance"></param>
        /// <returns></returns>
        public AbcInstance ImportInstance(AbcInstance instance)
        {
            AbcMethod importMethod = null;

            return(ImportInstance(instance, ref importMethod));
        }
示例#18
0
 public AbcMethodBody(AbcMethod method) : this()
 {
     Method = method;
 }
示例#19
0
 public void Read(SwfReader reader)
 {
     SlotId = (int)reader.ReadUIntEncoded(); //slot_id
     Method = reader.ReadAbcMethod();        //function
 }
示例#20
0
 public void Read(SwfReader reader)
 {
     SlotId = (int)reader.ReadUIntEncoded(); //disp_id
     Method = reader.ReadAbcMethod();        //method
 }
示例#21
0
 public AbcTrait(AbcTraitKind kind, AbcMethod method)
 {
     Kind   = kind;
     Method = method;
 }
示例#22
0
 public static AbcTrait CreateMethod(AbcMethod method)
 {
     return(new AbcTrait(AbcTraitKind.Method, method));
 }
示例#23
0
        internal AbcMethod DefineMethod(Sig sig, AbcCoder coder, Action <AbcMethod> complete)
        {
            if (sig == null)
            {
                throw new ArgumentNullException("sig");
            }

            if (!sig.IsInitilizer && sig.Name == null)
            {
                throw new InvalidOperationException();
            }

            var klass = Class;

            if (klass == null)
            {
                throw new InvalidOperationException(string.Format("Class is not defined yet for Instance {0}", FullName));
            }

            AbcMultiname traitName = null;
            AbcTrait     trait;

            bool isStatic = (sig.Semantics & MethodSemantics.Static) != 0;
            var  traits   = isStatic ? klass.Traits : Traits;

            if (sig.IsInitilizer)
            {
                if (Initializer != null)
                {
                    throw new InvalidOperationException();
                }
            }
            else
            {
                traitName = Abc.DefineName(sig.Name);
                trait     = traits.Find(traitName, sig.Kind);
                if (trait != null)
                {
                    return(trait.Method);
                }
            }

            var method = new AbcMethod
            {
                Method = sig.Source
            };

            var generator = Abc.Generator;

            if (sig.Source != null)
            {
                generator.SetData(sig.Source, method);
            }

            AbcMethodBody body = null;

            if (sig.IsAbstract)
            {
                if (coder != null)
                {
                    throw new InvalidOperationException();
                }
            }
            else
            {
                body = new AbcMethodBody(method);
            }

            Abc.AddMethod(method);

            if (sig.IsInitilizer)
            {
                Initializer = method;
            }
            else
            {
                //for non initializer method we must define trait and return type
                method.ReturnType = BuildReturnType(sig.ReturnType, method);

                trait      = AbcTrait.CreateMethod(method, traitName);
                trait.Kind = sig.Kind;

                if (!isStatic)
                {
                    trait.IsVirtual  = (sig.Semantics & MethodSemantics.Virtual) != 0;
                    trait.IsOverride = (sig.Semantics & MethodSemantics.Override) != 0;
                }

                traits.Add(trait);
            }

            if (sig.Args != null)
            {
                if (sig.Args.Length == 1 && sig.Args[0] is IMethod)
                {
                    var m = (IMethod)sig.Args[0];
                    if (generator == null)
                    {
                        throw new InvalidOperationException();
                    }
                    generator.MethodBuilder.BuildParameters(method, m);
                }
                else
                {
                    Abc.AddParameters(method.Parameters, sig.Args);
                }
            }

            if (body != null && coder != null)
            {
                var code = new AbcCode(Abc);
                coder(code);
                body.Finish(code);
            }

            if (complete != null)
            {
                complete(method);
            }

            return(method);
        }