protected void InsertEarlyReturnLocal(ASMethod method, byte local) { method.Body.Bytecode[0] = (byte)(local + OPCode.GetLocal_0); method.Body.Bytecode[1] = (byte)OPCode.ReturnValue; }
protected void InsertEarlyReturnTrue(ASMethod method) { method.Body.Bytecode[0] = (byte)OPCode.PushTrue; method.Body.Bytecode[1] = (byte)OPCode.ReturnValue; }
protected void RemoveHostSuffix(ABCFile abc, ASMethod connectMethod) { using (var inCode = new FlashReader(connectMethod.Body.Bytecode)) using (var outCode = new FlashWriter(inCode.Length)) { int ifNeCount = 0; while (inCode.Position != inCode.Length) { OPCode op = inCode.ReadOP(); outCode.WriteOP(op); if (op == OPCode.IfNe && ++ifNeCount == 2) { var iFNeJumpCount = (int)inCode.ReadS24(); outCode.WriteS24(iFNeJumpCount + 6); continue; } else if (op != OPCode.PushInt) continue; int pushIntIndex = inCode.Read7BitEncodedInt(); int integerValue = abc.Constants.Integers[pushIntIndex]; switch (integerValue) { case 65244: case 65185: case 65191: case 65189: case 65188: case 65174: case 65238: case 65184: case 65171: case 65172: { pushIntIndex = abc.Constants.AddInteger(65290); break; } } outCode.Write7BitEncodedInt(pushIntIndex); } connectMethod.Body.Bytecode = outCode.ToArray(); } RemoveDeadFalseConditions(connectMethod.Body); }
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; } } } } }
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); } } } }