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; } } }
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()); } }