Exemplo n.º 1
0
        protected virtual void ImplementCacheInvocationCache()
        {
            MethodInfo get_ItemMethod = typeof(HybridDictionary).GetMethod("get_Item", new Type[] { typeof(object) });
            MethodInfo set_ItemMethod = typeof(HybridDictionary).GetMethod("Add", new Type[] { typeof(object), typeof(object) });

            Type[] args = new Type[] { typeof(ICallable), typeof(MethodInfo) };
            Type[] invocation_const_args = new Type[] { typeof(ICallable), typeof(object), typeof(MethodInfo), typeof(object) };

            ArgumentReference arg1 = new ArgumentReference(typeof(ICallable));
            ArgumentReference arg2 = new ArgumentReference(typeof(MethodInfo));
            ArgumentReference arg3 = new ArgumentReference(typeof(object));

            _method2Invocation = MainTypeBuilder.CreateMethod("_Method2Invocation",
                                                              new ReturnReferenceExpression(Context.Invocation),
                                                              MethodAttributes.Family | MethodAttributes.HideBySig, arg1, arg2,
                                                              arg3);

            LocalReference invocation_local =
                _method2Invocation.CodeBuilder.DeclareLocal(Context.Invocation);

            LockBlockExpression block = new LockBlockExpression(SelfReference.Self);

            block.AddStatement(new AssignStatement(invocation_local,
                                                   new ConvertExpression(Context.Invocation,
                                                                         new VirtualMethodInvocationExpression(CacheField,
                                                                                                               get_ItemMethod,
                                                                                                               arg2.ToExpression()))));

            ConditionExpression cond1 = new ConditionExpression(OpCodes.Brfalse_S,
                                                                invocation_local.ToExpression());

            cond1.AddTrueStatement(new AssignStatement(
                                       invocation_local,
                                       new NewInstanceExpression(InvocationType.GetConstructor(invocation_const_args),
                                                                 arg1.ToExpression(), SelfReference.Self.ToExpression(),
                                                                 arg2.ToExpression(), arg3.ToExpression())));

            cond1.AddTrueStatement(new ExpressionStatement(
                                       new VirtualMethodInvocationExpression(CacheField,
                                                                             set_ItemMethod, arg2.ToExpression(),
                                                                             invocation_local.ToExpression())));

            block.AddStatement(new ExpressionStatement(cond1));

            _method2Invocation.CodeBuilder.AddStatement(new ExpressionStatement(block));
            _method2Invocation.CodeBuilder.AddStatement(new ReturnStatement(invocation_local));
        }
        public void DeclareLocal()
        {
            var            method = ClassEmitter.CreateMethod("Statement", MethodAttributes.Public, typeof(int), new Type[0]);
            LocalReference local  = method.DeclareLocal(typeof(int));

            method.ImplementByReturning(local.ToExpression());

            Assert.That(BuildInstanceAndInvokeMethod(method), Is.EqualTo(0));
        }
Exemplo n.º 3
0
        /// <summary>
        /// Writes the method implementation. This
        /// method generates the IL code for property get/set method and
        /// ordinary methods.
        /// </summary>
        /// <param name="method">The method to implement.</param>
        /// <param name="builder"><see cref="EasyMethod"/> being constructed.</param>
        protected virtual void WriteInterceptorInvocationMethod(MethodInfo method, EasyMethod builder)
        {
            ArgumentReference[] arguments             = builder.Arguments;
            TypeReference[]     dereferencedArguments = IndirectReference.WrapIfByRef(builder.Arguments);

            LocalReference local_inv = builder.CodeBuilder.DeclareLocal(Context.Invocation);

            EasyCallable   callable      = _method2Delegate[method] as EasyCallable;
            FieldReference fieldDelegate = ObtainCallableFieldBuilderDelegate(callable);

            builder.CodeBuilder.AddStatement(
                new AssignStatement(local_inv,
                                    new MethodInvocationExpression(_method2Invocation,
                                                                   fieldDelegate.ToExpression(),
                                                                   new MethodTokenExpression(GetCorrectMethod(method)),
                                                                   GetPseudoInvocationTarget(method))));

            LocalReference ret_local  = builder.CodeBuilder.DeclareLocal(typeof(object));
            LocalReference args_local = builder.CodeBuilder.DeclareLocal(typeof(object[]));

            // Store arguments into an object array.
            builder.CodeBuilder.AddStatement(
                new AssignStatement(args_local,
                                    new ReferencesToObjectArrayExpression(dereferencedArguments)));

            // Invoke the interceptor.
            builder.CodeBuilder.AddStatement(
                new AssignStatement(ret_local,
                                    new VirtualMethodInvocationExpression(InterceptorField,
                                                                          Context.Interceptor.GetMethod("Intercept"),
                                                                          local_inv.ToExpression(),
                                                                          args_local.ToExpression())));

            // Load possibly modified ByRef arguments from the array.
            for (int i = 0; i < arguments.Length; i++)
            {
                if (arguments[i].Type.IsByRef)
                {
                    builder.CodeBuilder.AddStatement(
                        new AssignStatement(dereferencedArguments[i],
                                            new ConvertExpression(dereferencedArguments[i].Type,
                                                                  new LoadRefArrayElementExpression(i, args_local))));
                }
            }

            if (builder.ReturnType == typeof(void))
            {
                builder.CodeBuilder.AddStatement(new ReturnStatement());
            }
            else
            {
                builder.CodeBuilder.AddStatement(new ReturnStatement(
                                                     new ConvertExpression(builder.ReturnType, ret_local.ToExpression())));
            }
        }
Exemplo n.º 4
0
        protected override void CustomizeGetObjectData(AbstractCodeBuilder codebuilder,
                                                       ArgumentReference arg1, ArgumentReference arg2)
        {
            Type[]     key_and_object     = new Type[] { typeof(String), typeof(Object) };
            Type[]     key_and_bool       = new Type[] { typeof(String), typeof(bool) };
            MethodInfo addValueMethod     = typeof(SerializationInfo).GetMethod("AddValue", key_and_object);
            MethodInfo addValueBoolMethod = typeof(SerializationInfo).GetMethod("AddValue", key_and_bool);

            codebuilder.AddStatement(new ExpressionStatement(
                                         new VirtualMethodInvocationExpression(arg1, addValueBoolMethod,
                                                                               new FixedReference("__delegateToBase").ToExpression(),
                                                                               new FixedReference(_delegateToBaseGetObjectData ? 1 : 0).ToExpression())));

            if (_delegateToBaseGetObjectData)
            {
                MethodInfo baseGetObjectData = _baseType.GetMethod("GetObjectData",
                                                                   new Type[] { typeof(SerializationInfo), typeof(StreamingContext) });

                codebuilder.AddStatement(new ExpressionStatement(
                                             new MethodInvocationExpression(baseGetObjectData,
                                                                            arg1.ToExpression(), arg2.ToExpression())));
            }
            else
            {
                LocalReference members_ref = codebuilder.DeclareLocal(typeof(MemberInfo[]));
                LocalReference data_ref    = codebuilder.DeclareLocal(typeof(object[]));

                MethodInfo getSerMembers = typeof(FormatterServices).GetMethod("GetSerializableMembers",
                                                                               new Type[] { typeof(Type) });
                MethodInfo getObjData = typeof(FormatterServices).GetMethod("GetObjectData",
                                                                            new Type[] { typeof(object), typeof(MemberInfo[]) });

                codebuilder.AddStatement(new AssignStatement(members_ref,
                                                             new MethodInvocationExpression(null, getSerMembers,
                                                                                            new TypeTokenExpression(_baseType))));

                codebuilder.AddStatement(new AssignStatement(data_ref,
                                                             new MethodInvocationExpression(null, getObjData,
                                                                                            SelfReference.Self.ToExpression(), members_ref.ToExpression())));

                codebuilder.AddStatement(new ExpressionStatement(
                                             new VirtualMethodInvocationExpression(arg1, addValueMethod,
                                                                                   new FixedReference("__data").ToExpression(),
                                                                                   data_ref.ToExpression())));
            }
        }
Exemplo n.º 5
0
        private void GenerateCall()
        {
            ArgumentReference arrayReference = new ArgumentReference(typeof(object[]));

            this._callmethod = base.CreateMethod("Call", new ReturnReferenceExpression(typeof(object)), new ArgumentReference[] { arrayReference });
            TypeReference[]  referenceArray  = IndirectReference.WrapIfByRef(this._args);
            LocalReference[] referenceArray2 = new LocalReference[this._args.Length];
            Expression[]     args            = new Expression[this._args.Length];
            for (int i = 0; i < this._args.Length; i++)
            {
                if (this._args[i].Type.IsByRef)
                {
                    referenceArray2[i] = this._callmethod.CodeBuilder.DeclareLocal(referenceArray[i].Type);
                    this._callmethod.CodeBuilder.AddStatement(new AssignStatement(referenceArray2[i], new ConvertExpression(referenceArray[i].Type, new LoadRefArrayElementExpression(i, arrayReference))));
                    args[i] = referenceArray2[i].ToAddressOfExpression();
                }
                else
                {
                    args[i] = new ConvertExpression(referenceArray[i].Type, new LoadRefArrayElementExpression(i, arrayReference));
                }
            }
            MethodInvocationExpression expression = new MethodInvocationExpression(this._invokeMethod, args);
            Expression instance = null;

            if (this._returnType.Type == typeof(void))
            {
                this._callmethod.CodeBuilder.AddStatement(new ExpressionStatement(expression));
                instance = NullExpression.Instance;
            }
            else
            {
                LocalReference target = this._callmethod.CodeBuilder.DeclareLocal(typeof(object));
                this._callmethod.CodeBuilder.AddStatement(new AssignStatement(target, new ConvertExpression(typeof(object), this._returnType.Type, expression)));
                instance = target.ToExpression();
            }
            for (int j = 0; j < this._args.Length; j++)
            {
                if (this._args[j].Type.IsByRef)
                {
                    this._callmethod.CodeBuilder.AddStatement(new AssignArrayStatement(arrayReference, j, new ConvertExpression(typeof(object), referenceArray[j].Type, referenceArray2[j].ToExpression())));
                }
            }
            this._callmethod.CodeBuilder.AddStatement(new ReturnStatement(instance));
        }
Exemplo n.º 6
0
        protected override void CustomizeGetObjectData(AbstractCodeBuilder codebuilder, ArgumentReference serializationInfo, ArgumentReference streamingContext, ClassEmitter emitter)
        {
            codebuilder.AddStatement(new ExpressionStatement(
                                         new MethodInvocationExpression(serializationInfo, SerializationInfoMethods.AddValue_Bool,
                                                                        new ConstReference("__delegateToBase").ToExpression(),
                                                                        new ConstReference(delegateToBaseGetObjectData ? 1 : 0).
                                                                        ToExpression())));

            if (delegateToBaseGetObjectData)
            {
                MethodInfo baseGetObjectData = targetType.GetMethod("GetObjectData",
                                                                    new[] { typeof(SerializationInfo), typeof(StreamingContext) });

                codebuilder.AddStatement(new ExpressionStatement(
                                             new MethodInvocationExpression(baseGetObjectData,
                                                                            serializationInfo.ToExpression(),
                                                                            streamingContext.ToExpression())));
            }
            else
            {
                LocalReference members_ref = codebuilder.DeclareLocal(typeof(MemberInfo[]));
                LocalReference data_ref    = codebuilder.DeclareLocal(typeof(object[]));

                codebuilder.AddStatement(new AssignStatement(members_ref,
                                                             new MethodInvocationExpression(null,
                                                                                            FormatterServicesMethods.
                                                                                            GetSerializableMembers,
                                                                                            new TypeTokenExpression(targetType))));

                codebuilder.AddStatement(new AssignStatement(data_ref,
                                                             new MethodInvocationExpression(null,
                                                                                            FormatterServicesMethods.GetObjectData,
                                                                                            SelfReference.Self.ToExpression(),
                                                                                            members_ref.ToExpression())));

                codebuilder.AddStatement(new ExpressionStatement(
                                             new MethodInvocationExpression(serializationInfo, SerializationInfoMethods.AddValue_Object,
                                                                            new ConstReference("__data").ToExpression(),
                                                                            data_ref.ToExpression())));
            }
        }
        protected virtual void ImplementInvokeMethodOnTarget(AbstractTypeEmitter invocation, MethodInfo method,
                                                             MethodEmitter invokeMethodOnTarget,
                                                             Reference targetField)
        {
            var callbackMethod = GetCallbackMethod(invocation, method);

            if (callbackMethod == null)
            {
                EmitCallThrowOnNoTarget(invokeMethodOnTarget);
                return;
            }

            if (canChangeTarget)
            {
                EmitCallEnsureValidTarget(invokeMethodOnTarget);
            }

            var parameters = method.GetParameters();
            var args       = new Expression[parameters.Length];

            // Idea: instead of grab parameters one by one
            // we should grab an array
            var byRefArguments = new Dictionary <int, LocalReference>();

            for (var i = 0; i < parameters.Length; i++)
            {
                var param = parameters[i];

                var paramType = invocation.GetClosedParameterType(param.ParameterType);
                if (paramType.IsByRef)
                {
                    var localReference = invokeMethodOnTarget.CodeBuilder.DeclareLocal(paramType.GetElementType());
                    invokeMethodOnTarget.CodeBuilder
                    .AddStatement(
                        new AssignStatement(localReference,
                                            new ConvertExpression(paramType.GetElementType(),
                                                                  new MethodInvocationExpression(SelfReference.Self,
                                                                                                 InvocationMethods.GetArgumentValue,
                                                                                                 new LiteralIntExpression(i)))));
                    var byRefReference = new ByRefReference(localReference);
                    args[i]           = new ReferenceExpression(byRefReference);
                    byRefArguments[i] = localReference;
                }
                else
                {
                    args[i] =
                        new ConvertExpression(paramType,
                                              new MethodInvocationExpression(SelfReference.Self,
                                                                             InvocationMethods.GetArgumentValue,
                                                                             new LiteralIntExpression(i)));
                }
            }

            if (byRefArguments.Count > 0)
            {
                invokeMethodOnTarget.CodeBuilder.AddStatement(new TryStatement());
            }

            var methodOnTargetInvocationExpression = GetCallbackMethodInvocation(invocation, args, callbackMethod, targetField, invokeMethodOnTarget);

            LocalReference returnValue = null;

            if (callbackMethod.ReturnType != typeof(void))
            {
                var returnType = invocation.GetClosedParameterType(callbackMethod.ReturnType);
                returnValue = invokeMethodOnTarget.CodeBuilder.DeclareLocal(returnType);
                invokeMethodOnTarget.CodeBuilder.AddStatement(new AssignStatement(returnValue, methodOnTargetInvocationExpression));
            }
            else
            {
                invokeMethodOnTarget.CodeBuilder.AddStatement(new ExpressionStatement(methodOnTargetInvocationExpression));
            }

            AssignBackByRefArguments(invokeMethodOnTarget, byRefArguments);

            if (callbackMethod.ReturnType != typeof(void))
            {
                var setRetVal =
                    new MethodInvocationExpression(SelfReference.Self,
                                                   InvocationMethods.SetReturnValue,
                                                   new ConvertExpression(typeof(object), returnValue.Type, returnValue.ToExpression()));

                invokeMethodOnTarget.CodeBuilder.AddStatement(new ExpressionStatement(setRetVal));
            }

            invokeMethodOnTarget.CodeBuilder.AddStatement(new ReturnStatement());
        }
Exemplo n.º 8
0
        protected void ImplementGetObjectData(ClassEmitter emitter)
        {
            var           serializationInfo = new ArgumentReference(typeof(SerializationInfo));
            var           streamingContext  = new ArgumentReference(typeof(StreamingContext));
            MethodEmitter getObjectData     = emitter.CreateMethod("GetObjectData", serializationInfo, streamingContext);

            LocalReference typeLocal = getObjectData.CodeBuilder.DeclareLocal(typeof(Type));

            getObjectData.CodeBuilder.AddStatement(
                new AssignStatement(
                    typeLocal,
                    new MethodInvocationExpression(
                        null,
                        TypeMethods.StaticGetType,
                        new ConstReference(typeof(ProxyObjectReference).AssemblyQualifiedName).ToExpression(),
                        new ConstReference(1).ToExpression(),
                        new ConstReference(0).ToExpression())));

            getObjectData.CodeBuilder.AddStatement(
                new ExpressionStatement(
                    new MethodInvocationExpression(
                        serializationInfo,
                        SerializationInfoMethods.SetType,
                        typeLocal.ToExpression())));

            foreach (var field in emitter.GetAllFields())
            {
                if (field.Reference.IsStatic)
                {
                    continue;
                }
                if (field.Reference.IsNotSerialized)
                {
                    continue;
                }
                AddAddValueInvocation(serializationInfo, getObjectData, field);
            }

            LocalReference interfacesLocal = getObjectData.CodeBuilder.DeclareLocal(typeof(string[]));

            getObjectData.CodeBuilder.AddStatement(
                new AssignStatement(
                    interfacesLocal,
                    new NewArrayExpression(interfaces.Length, typeof(string))));

            for (int i = 0; i < interfaces.Length; i++)
            {
                getObjectData.CodeBuilder.AddStatement(
                    new AssignArrayStatement(
                        interfacesLocal,
                        i,
                        new ConstReference(interfaces[i].AssemblyQualifiedName).ToExpression()));
            }

            getObjectData.CodeBuilder.AddStatement(
                new ExpressionStatement(
                    new MethodInvocationExpression(
                        serializationInfo,
                        SerializationInfoMethods.AddValue_Object,
                        new ConstReference("__interfaces").ToExpression(),
                        interfacesLocal.ToExpression())));

            getObjectData.CodeBuilder.AddStatement(
                new ExpressionStatement(
                    new MethodInvocationExpression(
                        serializationInfo,
                        SerializationInfoMethods.AddValue_Object,
                        new ConstReference("__baseType").ToExpression(),
                        new ConstReference(emitter.BaseType.AssemblyQualifiedName).ToExpression())));

            getObjectData.CodeBuilder.AddStatement(
                new ExpressionStatement(
                    new MethodInvocationExpression(
                        serializationInfo,
                        SerializationInfoMethods.AddValue_Object,
                        new ConstReference("__proxyGenerationOptions").ToExpression(),
                        emitter.GetField("proxyGenerationOptions").ToExpression())));



            getObjectData.CodeBuilder.AddStatement(
                new ExpressionStatement(
                    new MethodInvocationExpression(serializationInfo,
                                                   SerializationInfoMethods.AddValue_Object,
                                                   new ConstReference("__proxyTypeId").ToExpression(),
                                                   new ConstReference(proxyTypeId).ToExpression())));

            CustomizeGetObjectData(getObjectData.CodeBuilder, serializationInfo, streamingContext, emitter);

            getObjectData.CodeBuilder.AddStatement(new ReturnStatement());
        }
Exemplo n.º 9
0
        protected virtual void ImplementGetObjectData(Type[] interfaces)
        {
            // To prevent re-implementation of this interface.
            _generated.Add(typeof(ISerializable));

            Type[]     get_type_args  = new Type[] { typeof(String), typeof(bool), typeof(bool) };
            Type[]     key_and_object = new Type[] { typeof(String), typeof(Object) };
            MethodInfo addValueMethod = typeof(SerializationInfo).GetMethod("AddValue", key_and_object);

            ArgumentReference arg1          = new ArgumentReference(typeof(SerializationInfo));
            ArgumentReference arg2          = new ArgumentReference(typeof(StreamingContext));
            EasyMethod        getObjectData = MainTypeBuilder.CreateMethod("GetObjectData",
                                                                           new ReturnReferenceExpression(typeof(void)), arg1, arg2);

            LocalReference typeLocal = getObjectData.CodeBuilder.DeclareLocal(typeof(Type));

            getObjectData.CodeBuilder.AddStatement(new AssignStatement(
                                                       typeLocal,
                                                       new MethodInvocationExpression(null,
                                                                                      typeof(Type).GetMethod("GetType",
                                                                                                             get_type_args),
                                                                                      new FixedReference(
                                                                                          Context.ProxyObjectReference.
                                                                                          AssemblyQualifiedName).ToExpression(),
                                                                                      new FixedReference(1).ToExpression(),
                                                                                      new FixedReference(0).ToExpression())));

            getObjectData.CodeBuilder.AddStatement(new ExpressionStatement(
                                                       new VirtualMethodInvocationExpression(
                                                           arg1, typeof(SerializationInfo).GetMethod("SetType"),
                                                           typeLocal.ToExpression())));

            getObjectData.CodeBuilder.AddStatement(new ExpressionStatement(
                                                       new VirtualMethodInvocationExpression(arg1, addValueMethod,
                                                                                             new FixedReference("__interceptor").
                                                                                             ToExpression(),
                                                                                             InterceptorField.ToExpression())));

            getObjectData.CodeBuilder.AddStatement(new ExpressionStatement(
                                                       new VirtualMethodInvocationExpression(arg1, addValueMethod,
                                                                                             new FixedReference("__mixins").
                                                                                             ToExpression(),
                                                                                             MixinField.ToExpression())));

            LocalReference interfacesLocal =
                getObjectData.CodeBuilder.DeclareLocal(typeof(String[]));

            getObjectData.CodeBuilder.AddStatement(
                new AssignStatement(interfacesLocal,
                                    new NewArrayExpression(interfaces.Length, typeof(String))));

            for (int i = 0; i < interfaces.Length; i++)
            {
                getObjectData.CodeBuilder.AddStatement(new AssignArrayStatement(
                                                           interfacesLocal, i,
                                                           new FixedReference(interfaces[i].AssemblyQualifiedName).ToExpression()));
            }

            getObjectData.CodeBuilder.AddStatement(new ExpressionStatement(
                                                       new VirtualMethodInvocationExpression(arg1, addValueMethod,
                                                                                             new FixedReference("__interfaces").
                                                                                             ToExpression(),
                                                                                             interfacesLocal.ToExpression())));

            getObjectData.CodeBuilder.AddStatement(new ExpressionStatement(
                                                       new VirtualMethodInvocationExpression(arg1, addValueMethod,
                                                                                             new FixedReference("__baseType").
                                                                                             ToExpression(),
                                                                                             new TypeTokenExpression(_baseType))));

            CustomizeGetObjectData(getObjectData.CodeBuilder, arg1, arg2);

            getObjectData.CodeBuilder.AddStatement(new ReturnStatement());
        }
Exemplo n.º 10
0
        private void GenerateCall()
        {
            ArgumentReference arg = new ArgumentReference(typeof(object[]));

            _callmethod = CreateMethod("Call",
                                       new ReturnReferenceExpression(typeof(object)), arg);

            // LocalReference localRef = method.CodeBuilder.DeclareLocal( typeof(object) );

            TypeReference[]  dereferencedArguments = IndirectReference.WrapIfByRef(_args);
            LocalReference[] localCopies           = new LocalReference[_args.Length];
            Expression[]     invocationArguments   = new Expression[_args.Length];

            // Load arguments from the object array.
            for (int i = 0; i < _args.Length; i++)
            {
                if (_args[i].Type.IsByRef)
                {
                    localCopies[i] = _callmethod.CodeBuilder.DeclareLocal(dereferencedArguments[i].Type);

                    _callmethod.CodeBuilder.AddStatement(new AssignStatement(localCopies[i],
                                                                             new ConvertExpression(dereferencedArguments[i].Type,
                                                                                                   new LoadRefArrayElementExpression(i, arg))));

                    invocationArguments[i] = localCopies[i].ToAddressOfExpression();
                }
                else
                {
                    invocationArguments[i] = new ConvertExpression(dereferencedArguments[i].Type,
                                                                   new LoadRefArrayElementExpression(i, arg));
                }
            }

            // Invoke the method.
            MethodInvocationExpression methodInv = new MethodInvocationExpression(
                _invokeMethod,
                invocationArguments);

            Expression result = null;

            if (_returnType.Type == typeof(void))
            {
                _callmethod.CodeBuilder.AddStatement(new ExpressionStatement(methodInv));
                result = NullExpression.Instance;
            }
            else
            {
                LocalReference resultLocal = _callmethod.CodeBuilder.DeclareLocal(typeof(object));

                _callmethod.CodeBuilder.AddStatement(new AssignStatement(resultLocal,
                                                                         new ConvertExpression(typeof(object), _returnType.Type, methodInv)));

                result = resultLocal.ToExpression();
            }

            // Save ByRef arguments into the object array.
            for (int i = 0; i < _args.Length; i++)
            {
                if (_args[i].Type.IsByRef)
                {
                    _callmethod.CodeBuilder.AddStatement(new AssignArrayStatement(arg, i,
                                                                                  new ConvertExpression(typeof(object), dereferencedArguments[i].Type,
                                                                                                        localCopies[i].ToExpression())));
                }
            }

            // Return.
            _callmethod.CodeBuilder.AddStatement(new ReturnStatement(result));
        }
        protected override void CustomizeGetObjectData(AbstractCodeBuilder codebuilder, ArgumentReference arg1, ArgumentReference arg2)
        {
            Type[]     types      = new Type[] { typeof(string), typeof(object) };
            Type[]     typeArray2 = new Type[] { typeof(string), typeof(bool) };
            MethodInfo method     = typeof(SerializationInfo).GetMethod("AddValue", types);
            MethodInfo info2      = typeof(SerializationInfo).GetMethod("AddValue", typeArray2);

            codebuilder.AddStatement(new ExpressionStatement(new VirtualMethodInvocationExpression(arg1, info2, new Expression[] { new FixedReference("__delegateToBase").ToExpression(), new FixedReference(this._delegateToBaseGetObjectData ? 1 : 0).ToExpression() })));
            if (this._delegateToBaseGetObjectData)
            {
                MethodInfo info3 = base._baseType.GetMethod("GetObjectData", new Type[] { typeof(SerializationInfo), typeof(StreamingContext) });
                codebuilder.AddStatement(new ExpressionStatement(new MethodInvocationExpression(info3, new Expression[] { arg1.ToExpression(), arg2.ToExpression() })));
            }
            else
            {
                LocalReference target     = codebuilder.DeclareLocal(typeof(MemberInfo[]));
                LocalReference reference2 = codebuilder.DeclareLocal(typeof(object[]));
                MethodInfo     info4      = typeof(FormatterServices).GetMethod("GetSerializableMembers", new Type[] { typeof(Type) });
                MethodInfo     info5      = typeof(FormatterServices).GetMethod("GetObjectData", new Type[] { typeof(object), typeof(MemberInfo[]) });
                codebuilder.AddStatement(new AssignStatement(target, new MethodInvocationExpression(null, info4, new Expression[] { new TypeTokenExpression(base._baseType) })));
                codebuilder.AddStatement(new AssignStatement(reference2, new MethodInvocationExpression(null, info5, new Expression[] { SelfReference.Self.ToExpression(), target.ToExpression() })));
                codebuilder.AddStatement(new ExpressionStatement(new VirtualMethodInvocationExpression(arg1, method, new Expression[] { new FixedReference("__data").ToExpression(), reference2.ToExpression() })));
            }
        }
        private void AddOverrider(MethodInfo method, Reference invocationHandler)
        {
            var overrider = _emitter.CreateMethod(method.Name, MethodAttributes.Public | MethodAttributes.Virtual, method);

            overrider.AddCustomAttribute(new CustomAttributeBuilder(s_attributeConstructor, new object[0]));

            Reference      targetReference       = GetTargetReference();
            Expression     overriddenMethodToken = new MethodTokenExpression(method);
            LocalReference argsLocal             = CopyArgumentsToLocalVariable(overrider);
            Expression     baseMethodInvoker     = GetBaseInvokerExpression(method);

            TypeReference handlerReference = new TypeReferenceWrapper(invocationHandler, typeof(MethodInvocationHandler));

            Expression[] handlerArgs = new Expression[] { targetReference.ToExpression(), overriddenMethodToken, argsLocal.ToExpression(), baseMethodInvoker };

            Expression handlerInvocation = new VirtualMethodInvocationExpression(handlerReference, s_handlerInvokeMethod, handlerArgs);

            if (method.ReturnType != typeof(void))
            {
                overrider.ImplementByReturning(new ConvertExpression(method.ReturnType, typeof(object), handlerInvocation));
            }
            else
            {
                overrider.AddStatement(new ExpressionStatement(handlerInvocation));
                overrider.AddStatement(new PopStatement());
                overrider.ImplementByReturningVoid();
            }
        }
        protected virtual void ImplementInvokeMethodOnTarget(AbstractTypeEmitter @class, ParameterInfo[] parameters, MethodEmitter invokeMethodOnTarget, MethodInfo callbackMethod, Reference targetField)
        {
            if (canChangeTarget)
            {
                invokeMethodOnTarget.CodeBuilder.AddStatement(
                    new ExpressionStatement(new MethodInvocationExpression(SelfReference.Self, InvocationMethods.EnsureValidTarget)));
            }


            Expression[] args = new Expression[parameters.Length];

            // Idea: instead of grab parameters one by one
            // we should grab an array
            Dictionary <int, LocalReference> byRefArguments = new Dictionary <int, LocalReference>();

            for (int i = 0; i < parameters.Length; i++)
            {
                ParameterInfo param = parameters[i];

                Type paramType = TypeUtil.GetClosedParameterType(@class, param.ParameterType);
                if (paramType.IsByRef)
                {
                    LocalReference localReference = invokeMethodOnTarget.CodeBuilder.DeclareLocal(paramType.GetElementType());
                    invokeMethodOnTarget.CodeBuilder.AddStatement(
                        new AssignStatement(localReference,
                                            new ConvertExpression(paramType.GetElementType(),
                                                                  new MethodInvocationExpression(SelfReference.Self,
                                                                                                 InvocationMethods.GetArgumentValue,
                                                                                                 new LiteralIntExpression(i)))));
                    ByRefReference byRefReference = new ByRefReference(localReference);
                    args[i]           = new ReferenceExpression(byRefReference);
                    byRefArguments[i] = localReference;
                }
                else
                {
                    args[i] =
                        new ConvertExpression(paramType,
                                              new MethodInvocationExpression(SelfReference.Self,
                                                                             InvocationMethods.GetArgumentValue,
                                                                             new LiteralIntExpression(i)));
                }
            }

            if (callbackMethod.IsGenericMethod)
            {
                callbackMethod = callbackMethod.MakeGenericMethod(@class.GetGenericArgumentsFor(callbackMethod));
            }

            var methodOnTargetInvocationExpression = new MethodInvocationExpression(
                new AsTypeReference(targetField, callbackMethod.DeclaringType),
                callbackMethod,
                args)
            {
                VirtualCall = true
            };

            LocalReference returnValue = null;

            if (callbackMethod.ReturnType != typeof(void))
            {
                Type returnType = TypeUtil.GetClosedParameterType(@class, callbackMethod.ReturnType);
                returnValue = invokeMethodOnTarget.CodeBuilder.DeclareLocal(returnType);
                invokeMethodOnTarget.CodeBuilder.AddStatement(new AssignStatement(returnValue, methodOnTargetInvocationExpression));
            }
            else
            {
                invokeMethodOnTarget.CodeBuilder.AddStatement(new ExpressionStatement(methodOnTargetInvocationExpression));
            }

            foreach (KeyValuePair <int, LocalReference> byRefArgument in byRefArguments)
            {
                int            index          = byRefArgument.Key;
                LocalReference localReference = byRefArgument.Value;
                invokeMethodOnTarget.CodeBuilder.AddStatement(
                    new ExpressionStatement(
                        new MethodInvocationExpression(SelfReference.Self,
                                                       InvocationMethods.SetArgumentValue,
                                                       new LiteralIntExpression(index),
                                                       new ConvertExpression(typeof(object), localReference.Type,
                                                                             new ReferenceExpression(localReference)))
                        ));
            }

            if (callbackMethod.ReturnType != typeof(void))
            {
                var setRetVal =
                    new MethodInvocationExpression(SelfReference.Self,
                                                   InvocationMethods.SetReturnValue,
                                                   new ConvertExpression(typeof(object), returnValue.Type, returnValue.ToExpression()));

                invokeMethodOnTarget.CodeBuilder.AddStatement(new ExpressionStatement(setRetVal));
            }

            invokeMethodOnTarget.CodeBuilder.AddStatement(new ReturnStatement());
        }
        protected virtual void WriteInterceptorInvocationMethod(MethodInfo method, EasyMethod builder)
        {
            ArgumentReference[] arguments  = builder.Arguments;
            TypeReference[]     args       = IndirectReference.WrapIfByRef(builder.Arguments);
            LocalReference      target     = builder.CodeBuilder.DeclareLocal(this.Context.Invocation);
            EasyCallable        callable   = this._method2Delegate[method] as EasyCallable;
            FieldReference      reference2 = this.ObtainCallableFieldBuilderDelegate(callable);

            builder.CodeBuilder.AddStatement(new AssignStatement(target, new MethodInvocationExpression(this._method2Invocation, new Expression[] { reference2.ToExpression(), new MethodTokenExpression(this.GetCorrectMethod(method)), this.GetPseudoInvocationTarget(method) })));
            LocalReference reference3 = builder.CodeBuilder.DeclareLocal(typeof(object));
            LocalReference reference4 = builder.CodeBuilder.DeclareLocal(typeof(object[]));

            builder.CodeBuilder.AddStatement(new AssignStatement(reference4, new ReferencesToObjectArrayExpression(args)));
            builder.CodeBuilder.AddStatement(new AssignStatement(reference3, new VirtualMethodInvocationExpression(this.InterceptorField, this.Context.Interceptor.GetMethod("Intercept"), new Expression[] { target.ToExpression(), reference4.ToExpression() })));
            for (int i = 0; i < arguments.Length; i++)
            {
                if (arguments[i].Type.IsByRef)
                {
                    builder.CodeBuilder.AddStatement(new AssignStatement(args[i], new ConvertExpression(args[i].Type, new LoadRefArrayElementExpression(i, reference4))));
                }
            }
            if (builder.ReturnType == typeof(void))
            {
                builder.CodeBuilder.AddStatement(new ReturnStatement());
            }
            else
            {
                builder.CodeBuilder.AddStatement(new ReturnStatement(new ConvertExpression(builder.ReturnType, reference3.ToExpression())));
            }
        }
        protected virtual void ImplementGetObjectData(Type[] interfaces)
        {
            this._generated.Add(typeof(ISerializable));
            Type[]            types      = new Type[] { typeof(string), typeof(bool), typeof(bool) };
            Type[]            typeArray2 = new Type[] { typeof(string), typeof(object) };
            MethodInfo        info       = typeof(SerializationInfo).GetMethod("AddValue", typeArray2);
            ArgumentReference owner      = new ArgumentReference(typeof(SerializationInfo));
            ArgumentReference reference2 = new ArgumentReference(typeof(StreamingContext));
            EasyMethod        method     = this.MainTypeBuilder.CreateMethod("GetObjectData", new ReturnReferenceExpression(typeof(void)), new ArgumentReference[] { owner, reference2 });
            LocalReference    target     = method.CodeBuilder.DeclareLocal(typeof(Type));

            method.CodeBuilder.AddStatement(new AssignStatement(target, new MethodInvocationExpression(null, typeof(Type).GetMethod("GetType", types), new Expression[] { new FixedReference(this.Context.ProxyObjectReference.AssemblyQualifiedName).ToExpression(), new FixedReference(1).ToExpression(), new FixedReference(0).ToExpression() })));
            method.CodeBuilder.AddStatement(new ExpressionStatement(new VirtualMethodInvocationExpression(owner, typeof(SerializationInfo).GetMethod("SetType"), new Expression[] { target.ToExpression() })));
            method.CodeBuilder.AddStatement(new ExpressionStatement(new VirtualMethodInvocationExpression(owner, info, new Expression[] { new FixedReference("__interceptor").ToExpression(), this.InterceptorField.ToExpression() })));
            method.CodeBuilder.AddStatement(new ExpressionStatement(new VirtualMethodInvocationExpression(owner, info, new Expression[] { new FixedReference("__mixins").ToExpression(), this.MixinField.ToExpression() })));
            LocalReference reference4 = method.CodeBuilder.DeclareLocal(typeof(string[]));

            method.CodeBuilder.AddStatement(new AssignStatement(reference4, new NewArrayExpression(interfaces.Length, typeof(string))));
            for (int i = 0; i < interfaces.Length; i++)
            {
                method.CodeBuilder.AddStatement(new AssignArrayStatement(reference4, i, new FixedReference(interfaces[i].AssemblyQualifiedName).ToExpression()));
            }
            method.CodeBuilder.AddStatement(new ExpressionStatement(new VirtualMethodInvocationExpression(owner, info, new Expression[] { new FixedReference("__interfaces").ToExpression(), reference4.ToExpression() })));
            method.CodeBuilder.AddStatement(new ExpressionStatement(new VirtualMethodInvocationExpression(owner, info, new Expression[] { new FixedReference("__baseType").ToExpression(), new TypeTokenExpression(this._baseType) })));
            this.CustomizeGetObjectData(method.CodeBuilder, owner, reference2);
            method.CodeBuilder.AddStatement(new ReturnStatement());
        }
        protected virtual void ImplementCacheInvocationCache()
        {
            MethodInfo method = typeof(HybridDictionary).GetMethod("get_Item", new Type[] { typeof(object) });
            MethodInfo info2  = typeof(HybridDictionary).GetMethod("Add", new Type[] { typeof(object), typeof(object) });

            Type[]            types      = new Type[] { typeof(ICallable), typeof(object), typeof(MethodInfo), typeof(object) };
            ArgumentReference reference  = new ArgumentReference(typeof(ICallable));
            ArgumentReference reference2 = new ArgumentReference(typeof(MethodInfo));
            ArgumentReference reference3 = new ArgumentReference(typeof(object));

            this._method2Invocation = this.MainTypeBuilder.CreateMethod("_Method2Invocation", new ReturnReferenceExpression(this.Context.Invocation), MethodAttributes.HideBySig | MethodAttributes.Family, new ArgumentReference[] { reference, reference2, reference3 });
            LocalReference      target     = this._method2Invocation.CodeBuilder.DeclareLocal(this.Context.Invocation);
            LockBlockExpression expression = new LockBlockExpression(SelfReference.Self);

            expression.AddStatement(new AssignStatement(target, new ConvertExpression(this.Context.Invocation, new VirtualMethodInvocationExpression(this.CacheField, method, new Expression[] { reference2.ToExpression() }))));
            ConditionExpression expression2 = new ConditionExpression(OpCodes.Brfalse_S, target.ToExpression());

            expression2.AddTrueStatement(new AssignStatement(target, new NewInstanceExpression(this.InvocationType.GetConstructor(types), new Expression[] { reference.ToExpression(), SelfReference.Self.ToExpression(), reference2.ToExpression(), reference3.ToExpression() })));
            expression2.AddTrueStatement(new ExpressionStatement(new VirtualMethodInvocationExpression(this.CacheField, info2, new Expression[] { reference2.ToExpression(), target.ToExpression() })));
            expression.AddStatement(new ExpressionStatement(expression2));
            this._method2Invocation.CodeBuilder.AddStatement(new ExpressionStatement(expression));
            this._method2Invocation.CodeBuilder.AddStatement(new ReturnStatement(target));
        }