From af6dd56712f96e14f13cacc6a53bef9433214248 Mon Sep 17 00:00:00 2001 From: ayende Date: Wed, 16 Apr 2008 18:29:04 +0000 Subject: [PATCH] Fixing an issue with output parameters that are of type IntPtr git-svn-id: https://svn.castleproject.org/svn/castle/trunk@5003 73e77b4c-caa6-f847-a29a-24ab75ae54b6 --- .../BugsReportedTestCase.cs | 1 + .../RhinoMocksTestCase.cs | 39 +++ .../Generators/Emitters/OpCodeUtil.cs | 348 ++++++++++----------- 3 files changed, 214 insertions(+), 174 deletions(-) rewrite Tools/Castle.DynamicProxy2/Castle.DynamicProxy/Generators/Emitters/OpCodeUtil.cs (84%) diff --git a/Tools/Castle.DynamicProxy2/Castle.DynamicProxy.Tests/BugsReportedTestCase.cs b/Tools/Castle.DynamicProxy2/Castle.DynamicProxy.Tests/BugsReportedTestCase.cs index f23bf6356..03f736475 100644 --- a/Tools/Castle.DynamicProxy2/Castle.DynamicProxy.Tests/BugsReportedTestCase.cs +++ b/Tools/Castle.DynamicProxy2/Castle.DynamicProxy.Tests/BugsReportedTestCase.cs @@ -105,6 +105,7 @@ namespace Castle.DynamicProxy.Tests { public void Intercept(IInvocation invocation) { + } } diff --git a/Tools/Castle.DynamicProxy2/Castle.DynamicProxy.Tests/RhinoMocksTestCase.cs b/Tools/Castle.DynamicProxy2/Castle.DynamicProxy.Tests/RhinoMocksTestCase.cs index 188479f14..9bf840bf5 100644 --- a/Tools/Castle.DynamicProxy2/Castle.DynamicProxy.Tests/RhinoMocksTestCase.cs +++ b/Tools/Castle.DynamicProxy2/Castle.DynamicProxy.Tests/RhinoMocksTestCase.cs @@ -188,6 +188,27 @@ namespace Castle.DynamicProxy.Tests Assert.AreEqual(2, logging.Invocations.Count); } + [Test] + public void CanProxyMethodWithOutIntPtrParamter() + { + IFooWithOutIntPtr o = + (IFooWithOutIntPtr)generator.CreateInterfaceProxyWithoutTarget(typeof(IFooWithOutIntPtr), + new Type[0], new SkipCallingMethodInterceptorWithOutputParams()); + Assert.IsNotNull(o); + IntPtr i; + o.Bar(out i); + } + + + public class SkipCallingMethodInterceptorWithOutputParams : IInterceptor + { + public void Intercept(IInvocation invocation) + { + invocation.Arguments[0] = IntPtr.Zero; + invocation.ReturnValue = 5; + } + } + public interface IWithEvents { event EventHandler Foo; @@ -319,5 +340,23 @@ namespace Castle.DynamicProxy.Tests } } + public interface IFooWithOutIntPtr + { + int Bar(out IntPtr i); + } + + public class Foo : IFooWithOutIntPtr + { + public int Bar(out IntPtr i) + { + i = (IntPtr)Test(); + return 5; + } + + private object Test() + { + return new IntPtr(3); + } + } #endif } \ No newline at end of file diff --git a/Tools/Castle.DynamicProxy2/Castle.DynamicProxy/Generators/Emitters/OpCodeUtil.cs b/Tools/Castle.DynamicProxy2/Castle.DynamicProxy/Generators/Emitters/OpCodeUtil.cs dissimilarity index 84% index eaf02e976..64810e460 100644 --- a/Tools/Castle.DynamicProxy2/Castle.DynamicProxy/Generators/Emitters/OpCodeUtil.cs +++ b/Tools/Castle.DynamicProxy2/Castle.DynamicProxy/Generators/Emitters/OpCodeUtil.cs @@ -1,174 +1,174 @@ -// Copyright 2004-2008 Castle Project - http://www.castleproject.org/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -namespace Castle.DynamicProxy.Generators.Emitters -{ - using System; - using System.Reflection.Emit; - - internal abstract class OpCodeUtil - { - /// - /// Emits a load opcode of the appropriate kind for a constant string or - /// primitive value. - /// - /// - /// - public static void EmitLoadOpCodeForConstantValue(ILGenerator gen, object value) - { - if (value is String) - { - gen.Emit(OpCodes.Ldstr, value.ToString()); - } - else if (value is Int32) - { - OpCode code = LdcOpCodesDictionary.Instance[value.GetType()]; - gen.Emit(code, (int) value); - } - else if (value is bool) - { - OpCode code = LdcOpCodesDictionary.Instance[value.GetType()]; - gen.Emit(code, Convert.ToInt32(value)); - } - else - { - throw new NotSupportedException(); - } - } - - /// - /// Emits a load opcode of the appropriate kind for the constant default value of a - /// type, such as 0 for value types and null for reference types. - /// - public static void EmitLoadOpCodeForDefaultValueOfType(ILGenerator gen, Type type) - { - if (type.IsPrimitive) - { - gen.Emit(LdcOpCodesDictionary.Instance[type], 0); - } - else - { - gen.Emit(OpCodes.Ldnull); - } - } - - /// - /// Emits a load indirect opcode of the appropriate type for a value or object reference. - /// Pops a pointer off the evaluation stack, dereferences it and loads - /// a value of the specified type. - /// - /// - /// - public static void EmitLoadIndirectOpCodeForType(ILGenerator gen, Type type) - { - if (type.IsEnum) - { - EmitLoadIndirectOpCodeForType(gen, GetUnderlyingTypeOfEnum(type)); - return; - } - - if (type.IsByRef) - { - throw new NotSupportedException("Cannot load ByRef values"); - } - else if (type.IsPrimitive) - { - OpCode opCode = LdindOpCodesDictionary.Instance[type]; - - if (opCode == LdindOpCodesDictionary.EmptyOpCode) - { - throw new ArgumentException("Type " + type + " could not be converted to a OpCode"); - } - - gen.Emit(opCode); - } - else if (type.IsValueType) - { - gen.Emit(OpCodes.Ldobj, type); - } - else - { - gen.Emit(OpCodes.Ldind_Ref); - } - } - - /// - /// Emits a store indirectopcode of the appropriate type for a value or object reference. - /// Pops a value of the specified type and a pointer off the evaluation stack, and - /// stores the value. - /// - /// - /// - public static void EmitStoreIndirectOpCodeForType(ILGenerator gen, Type type) - { - if (type.IsEnum) - { - EmitStoreIndirectOpCodeForType(gen, GetUnderlyingTypeOfEnum(type)); - return; - } - - if (type.IsByRef) - { - throw new NotSupportedException("Cannot store ByRef values"); - } - else if (type.IsPrimitive) - { - OpCode opCode = StindOpCodesDictionary.Instance[type]; - - if (ReferenceEquals(opCode, StindOpCodesDictionary.EmptyOpCode)) - { - throw new ArgumentException("Type " + type + " could not be converted to a OpCode"); - } - - gen.Emit(opCode); - } - else if (type.IsValueType) - { - gen.Emit(OpCodes.Stobj, type); - } - else - { - gen.Emit(OpCodes.Stind_Ref); - } - } - - private static Type GetUnderlyingTypeOfEnum(Type enumType) - { - Enum baseType = (Enum) Activator.CreateInstance(enumType); - TypeCode code = baseType.GetTypeCode(); - - switch(code) - { - case TypeCode.SByte: - return typeof(SByte); - case TypeCode.Byte: - return typeof(Byte); - case TypeCode.Int16: - return typeof(Int16); - case TypeCode.Int32: - return typeof(Int32); - case TypeCode.Int64: - return typeof(Int64); - case TypeCode.UInt16: - return typeof(UInt16); - case TypeCode.UInt32: - return typeof(UInt32); - case TypeCode.UInt64: - return typeof(UInt64); - default: - throw new NotSupportedException(); - } - } - } -} \ No newline at end of file +// Copyright 2004-2008 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Generators.Emitters +{ + using System; + using System.Reflection.Emit; + + internal abstract class OpCodeUtil + { + /// + /// Emits a load opcode of the appropriate kind for a constant string or + /// primitive value. + /// + /// + /// + public static void EmitLoadOpCodeForConstantValue(ILGenerator gen, object value) + { + if (value is String) + { + gen.Emit(OpCodes.Ldstr, value.ToString()); + } + else if (value is Int32) + { + OpCode code = LdcOpCodesDictionary.Instance[value.GetType()]; + gen.Emit(code, (int)value); + } + else if (value is bool) + { + OpCode code = LdcOpCodesDictionary.Instance[value.GetType()]; + gen.Emit(code, Convert.ToInt32(value)); + } + else + { + throw new NotSupportedException(); + } + } + + /// + /// Emits a load opcode of the appropriate kind for the constant default value of a + /// type, such as 0 for value types and null for reference types. + /// + public static void EmitLoadOpCodeForDefaultValueOfType(ILGenerator gen, Type type) + { + if (type.IsPrimitive) + { + gen.Emit(LdcOpCodesDictionary.Instance[type], 0); + } + else + { + gen.Emit(OpCodes.Ldnull); + } + } + + /// + /// Emits a load indirect opcode of the appropriate type for a value or object reference. + /// Pops a pointer off the evaluation stack, dereferences it and loads + /// a value of the specified type. + /// + /// + /// + public static void EmitLoadIndirectOpCodeForType(ILGenerator gen, Type type) + { + if (type.IsEnum) + { + EmitLoadIndirectOpCodeForType(gen, GetUnderlyingTypeOfEnum(type)); + return; + } + + if (type.IsByRef) + { + throw new NotSupportedException("Cannot load ByRef values"); + } + else if (type.IsPrimitive && type != typeof(IntPtr)) + { + OpCode opCode = LdindOpCodesDictionary.Instance[type]; + + if (opCode == LdindOpCodesDictionary.EmptyOpCode) + { + throw new ArgumentException("Type " + type + " could not be converted to a OpCode"); + } + + gen.Emit(opCode); + } + else if (type.IsValueType) + { + gen.Emit(OpCodes.Ldobj, type); + } + else + { + gen.Emit(OpCodes.Ldind_Ref); + } + } + + /// + /// Emits a store indirectopcode of the appropriate type for a value or object reference. + /// Pops a value of the specified type and a pointer off the evaluation stack, and + /// stores the value. + /// + /// + /// + public static void EmitStoreIndirectOpCodeForType(ILGenerator gen, Type type) + { + if (type.IsEnum) + { + EmitStoreIndirectOpCodeForType(gen, GetUnderlyingTypeOfEnum(type)); + return; + } + + if (type.IsByRef) + { + throw new NotSupportedException("Cannot store ByRef values"); + } + else if (type.IsPrimitive && type != typeof(IntPtr)) + { + OpCode opCode = StindOpCodesDictionary.Instance[type]; + + if (Equals(opCode, StindOpCodesDictionary.EmptyOpCode)) + { + throw new ArgumentException("Type " + type + " could not be converted to a OpCode"); + } + + gen.Emit(opCode); + } + else if (type.IsValueType) + { + gen.Emit(OpCodes.Stobj, type); + } + else + { + gen.Emit(OpCodes.Stind_Ref); + } + } + + private static Type GetUnderlyingTypeOfEnum(Type enumType) + { + Enum baseType = (Enum)Activator.CreateInstance(enumType); + TypeCode code = baseType.GetTypeCode(); + + switch (code) + { + case TypeCode.SByte: + return typeof(SByte); + case TypeCode.Byte: + return typeof(Byte); + case TypeCode.Int16: + return typeof(Int16); + case TypeCode.Int32: + return typeof(Int32); + case TypeCode.Int64: + return typeof(Int64); + case TypeCode.UInt16: + return typeof(UInt16); + case TypeCode.UInt32: + return typeof(UInt32); + case TypeCode.UInt64: + return typeof(UInt64); + default: + throw new NotSupportedException(); + } + } + } +} \ No newline at end of file -- 2.11.4.GIT