Esempio n. 1
0
        public ASClass GetIncomingParser(ASInstance incomingInstance)
        {
            if (_incomingParsersCache.ContainsKey(incomingInstance))
            {
                return(_incomingParsersCache[incomingInstance]);
            }

            ASClass parserClass = null;
            ABCFile abc         = incomingInstance.ABC;

            try
            {
                using (var codeOut = new FlashReader(
                           incomingInstance.Constructor.Body.Bytecode))
                {
                    while (codeOut.IsDataAvailable)
                    {
                        OPCode   op     = codeOut.ReadOP();
                        object[] values = codeOut.ReadValues(op);
                        if (op != OPCode.GetLex)
                        {
                            continue;
                        }

                        var         getLexIndex = (int)values[0];
                        ASMultiname getLexName  = abc.Constants.Multinames[getLexIndex];
                        parserClass = abc.FindClassByName(getLexName.ObjName);
                        if (parserClass != null)
                        {
                            return(parserClass);
                        }
                        break;
                    }
                }

                ASInstance incomingSuperInstance = abc.FindInstanceByName(
                    incomingInstance.SuperType.ObjName);

                ASMultiname parserReturnType = incomingSuperInstance
                                               .FindGetter("parser").Method.ReturnType;

                SlotConstantTrait parserSlot = incomingSuperInstance
                                               .FindSlot("*", parserReturnType.ObjName);

                foreach (ASTrait trait in incomingInstance.Traits)
                {
                    if (trait.TraitType != TraitType.Method)
                    {
                        continue;
                    }

                    var mgsTrait = (MethodGetterSetterTrait)trait.Data;
                    if (mgsTrait.Method.Parameters.Count != 0)
                    {
                        continue;
                    }

                    using (var codeOut = new FlashReader(
                               mgsTrait.Method.Body.Bytecode))
                    {
                        while (codeOut.IsDataAvailable)
                        {
                            OPCode   op     = codeOut.ReadOP();
                            object[] values = codeOut.ReadValues(op);
                            if (op != OPCode.GetLex)
                            {
                                continue;
                            }

                            var         getLexIndex = (int)values[0];
                            ASMultiname getLexType  = abc.Constants.Multinames[getLexIndex];
                            if (getLexType.ObjName != parserSlot.ObjName)
                            {
                                continue;
                            }

                            parserClass = abc.FindClassByName(mgsTrait.Method.ReturnType.ObjName);
                            if (parserClass != null)
                            {
                                return(parserClass);
                            }
                            break;
                        }
                    }
                }
                return(parserClass);
            }
            finally
            {
                if (parserClass != null)
                {
                    _incomingParsersCache[incomingInstance] = parserClass;
                }
            }
        }
Esempio n. 2
0
        public ASTrait(ABCFile abc, FlashReader reader)
            : this(abc)
        {
            TypeIndex = reader.Read7BitEncodedInt();
            byte trueKind = reader.ReadByte();

            var traitType = (TraitType)(trueKind & 0xF);
            Attributes = (TraitAttributes)(trueKind >> 4);
            #region Trait Reading
            switch (traitType)
            {
            case TraitType.Slot:
            case TraitType.Constant:
            {
                Data = new SlotConstantTrait(abc, reader, traitType)
                {
                    ObjName = Type.ObjName
                };
                break;
            }

            case TraitType.Method:
            case TraitType.Getter:
            case TraitType.Setter:
            {
                Data = new MethodGetterSetterTrait(abc, reader, traitType)
                {
                    ObjName = Type.ObjName
                };

                ((MethodGetterSetterTrait)Data).Method.ObjName = ObjName;
                break;
            }

            case TraitType.Class:
            {
                Data = new ClassTrait(abc, reader)
                {
                    ObjName = Type.ObjName
                };
                break;
            }

            case TraitType.Function:
            {
                Data = new FunctionTrait(abc, reader)
                {
                    ObjName = Type.ObjName
                };
                break;
            }

            default:
                throw new Exception($"Invalid {nameof(ASTrait)} type: " + traitType);
            }
            #endregion

            if ((Attributes & TraitAttributes.Metadata) != 0)
            {
                MetadataIndices.Capacity = reader.Read7BitEncodedInt();
            }

            for (int i = 0; i < MetadataIndices.Capacity; i++)
            {
                MetadataIndices.Add(reader.Read7BitEncodedInt());
            }
        }