Beispiel #1
0
        protected void ScanForMessageReference(Dictionary<string, ASClass> messageClasses, ASClass asClass, ASMethod method, int traitIndex, int messageRefCount = 0)
        {
            ABCFile abc = asClass.ABC;
            ASClass messageClass = null;
            using (var outCode = new FlashReader(method.Body.Bytecode))
            {
                while (outCode.IsDataAvailable)
                {
                    OPCode op = outCode.ReadOP();
                    object[] values = outCode.ReadValues(op);
                    switch (op)
                    {
                        case OPCode.NewFunction:
                        {
                            var newFuncIndex = (int)values[0];
                            ASMethod newFuncMethod = abc.Methods[newFuncIndex];
                            ScanForMessageReference(messageClasses, asClass, newFuncMethod, traitIndex, messageRefCount);
                            break;
                        }
                        case OPCode.ConstructProp:
                        {
                            var constructPropIndex = (int)values[0];
                            if (messageClass != null)
                            {
                                ASMultiname constructPropType =
                                    abc.Constants.Multinames[constructPropIndex];

                                if (constructPropType.ObjName == messageClass.Instance.Type.ObjName)
                                {
                                    if (!_messageReferencesCache.ContainsKey(messageClass))
                                        _messageReferencesCache[messageClass] = new List<Tuple<ASMethod, int>>();

                                    _messageReferencesCache[messageClass].Add(
                                        new Tuple<ASMethod, int>(method, (traitIndex + (++messageRefCount))));
                                }
                                messageClass = null;
                            }
                            break;
                        }
                        case OPCode.FindPropStrict:
                        {
                            var findPropStrictIndex = (int)values[0];
                            string findPropStrictObjName = abc.Constants
                                .Multinames[findPropStrictIndex].ObjName;

                            if (messageClasses.ContainsKey(findPropStrictObjName))
                            {
                                messageClass = messageClasses[findPropStrictObjName];

                                // Incoming messages currently not supported.
                                if (IncomingTypes.ContainsValue(messageClass))
                                    messageClass = null;
                            }
                            break;
                        }
                    }
                }
            }
        }
Beispiel #2
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;
            }
        }
Beispiel #3
0
        protected virtual void WriteMethodHashData(BinaryWriter hashInput, ASMethod asMethod, bool writeInstructions)
        {
            WriteTraitsHashData(hashInput, asMethod.Body);
            hashInput.Write(asMethod.Body.Exceptions.Count);
            hashInput.Write(asMethod.Body.MaxStack);
            hashInput.Write(asMethod.Body.LocalCount);
            hashInput.Write(asMethod.Body.MaxScopeDepth);
            hashInput.Write(asMethod.Body.InitialScopeDepth);

            hashInput.Write(asMethod.Parameters.Count);
            foreach (ASParameter parameter in asMethod.Parameters)
            {
                if (parameter.IsOptional)
                {
                    hashInput.Write(parameter.IsOptional);
                    WriteValueSlotHashData(hashInput, parameter);
                }

                if (parameter.Type != null)
                    WriteMultinameHashData(hashInput, parameter.Type);
            }

            if (writeInstructions)
            {
                using (var codeOutput =
                    new FlashReader(asMethod.Body.Bytecode))
                {
                    while (codeOutput.IsDataAvailable)
                    {
                        OPCode op = codeOutput.ReadOP();
                        object[] values = codeOutput.ReadValues(op);
                        hashInput.Write((byte)op);
                    }
                }
            }
        }