protected virtual ReadDataInvoker CreateReadDataMethod(Type type, AMFReader reader, object instance) { #if !(MONO) && !(NET_2_0) && !(NET_3_5) && !(SILVERLIGHT) bool canSkipChecks = _ps.IsSubsetOf(AppDomain.CurrentDomain.PermissionSet); #else bool canSkipChecks = SecurityManager.IsGranted(new ReflectionPermission(ReflectionPermissionFlag.MemberAccess)); #endif DynamicMethod method = new DynamicMethod(string.Empty, typeof(object), new Type[] { typeof(AMFReader), typeof(ClassDefinition) }, this.GetType(), canSkipChecks); ILGenerator il = method.GetILGenerator(); LocalBuilder instanceLocal = il.DeclareLocal(type);//[0] instance LocalBuilder typeCodeLocal = il.DeclareLocal(typeof(byte));//[1] uint8 typeCode LocalBuilder keyLocal = il.DeclareLocal(typeof(string));//[2] string key LocalBuilder objTmp = il.DeclareLocal(typeof(object));//[3] temp object store LocalBuilder intTmp1 = il.DeclareLocal(typeof(int));//[4] temp int store, length LocalBuilder intTmp2 = il.DeclareLocal(typeof(int));//[5] temp int store, index LocalBuilder objTmp2 = il.DeclareLocal(typeof(object));//[6] temp object store LocalBuilder typeTmp = il.DeclareLocal(typeof(Type));//[7] temp Type store EmitHelper emit = new EmitHelper(il); ConstructorInfo typeConstructor = type.GetConstructor(EmitHelper.AnyVisibilityInstance, null, CallingConventions.HasThis, System.Type.EmptyTypes, null); MethodInfo miAddReference = typeof(AMFReader).GetMethod("AddAMF3ObjectReference"); MethodInfo miReadByte = typeof(AMFReader).GetMethod("ReadByte"); emit //object instance = new object(); .newobj(typeConstructor) //Create the new instance and push the object reference onto the evaluation stack .stloc_0 //Pop from the top of the evaluation stack and store it in a the local variable list at index 0 //reader.AddReference(instance); .ldarg_0 //Push the argument indexed at 1 onto the evaluation stack 'reader' .ldloc_0 //Loads the local variable at index 0 onto the evaluation stack 'instance' .callvirt(miAddReference) //Arguments are popped from the stack, the method call is performed, return value is pushed onto the stack //typeCode = 0; .ldc_i4_0 //Push the integer value of 0 onto the evaluation stack as an int32 .stloc_1 //Pop and store it in a the local variable list at index 1 //string key = null; .ldnull //Push a null reference onto the evaluation stack .stloc_2 //Pop and store it in a the local variable list at index 2 'key' .end() ; for (int i = 0; i < _classDefinition.MemberCount; i++) { string key = _classDefinition.Members[i].Name; byte typeCode = reader.ReadByte(); object value = reader.ReadAMF3Data(typeCode); reader.SetMember(instance, key, value); emit //.ldarg_1 //.callvirt(typeof(ClassDefinition).GetMethod("get_Members")) //.ldc_i4(i) //.conv_ovf_i //.ldelem_ref //.stloc_2 .ldarg_0 .callvirt(miReadByte) .stloc_1 .end() ; MemberInfo[] memberInfos = type.GetMember(key); if (memberInfos != null && memberInfos.Length > 0) GeneratePropertySet(emit, typeCode, memberInfos[0]); else { //Log this error (do not throw exception), otherwise our current AMF stream becomes unreliable log.Warn(__Res.GetString(__Res.Optimizer_Warning)); string msg = __Res.GetString(__Res.Reflection_MemberNotFound, string.Format("{0}.{1}", type.FullName, key)); log.Warn(msg); //reader.ReadAMF3Data(typeCode); emit .ldarg_0 //Push 'reader' .ldloc_1 //Push 'typeCode' .callvirt(typeof(AMFReader).GetMethod("ReadAMF3Data", new Type[] { typeof(byte) })) .pop .end() ; } } Label labelExit = emit.DefineLabel(); emit .MarkLabel(labelExit) //return instance; .ldloc_0 //Load the local variable at index 0 onto the evaluation stack .ret() //Return ; return (ReadDataInvoker)method.CreateDelegate(typeof(ReadDataInvoker)); }