Skip to content

Commit 02cce94

Browse files
authored
Merge pull request #731 from stakx/arguments-marshaller
Introduce `ArgumentsMarshaller` helpers for `MethodWithInvocation- Generator` and `InvocationTypeGenerator`
2 parents f011b2c + 1de62ba commit 02cce94

7 files changed

Lines changed: 427 additions & 384 deletions

File tree

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
// Copyright 2004-2026 Castle Project - http://www.castleproject.org/
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
namespace Castle.DynamicProxy.Generators.Emitters.SimpleAST
16+
{
17+
using System;
18+
using System.Diagnostics;
19+
using System.Reflection.Emit;
20+
21+
internal class ConvertArgumentFromObjectExpression : IExpression
22+
{
23+
private readonly IExpression obj;
24+
private Type dereferencedArgumentType;
25+
26+
public ConvertArgumentFromObjectExpression(IExpression obj, Type dereferencedArgumentType)
27+
{
28+
Debug.Assert(dereferencedArgumentType.IsByRef == false);
29+
30+
this.obj = obj;
31+
this.dereferencedArgumentType = dereferencedArgumentType;
32+
}
33+
34+
public void Emit(ILGenerator gen)
35+
{
36+
obj.Emit(gen);
37+
38+
if (dereferencedArgumentType == typeof(object))
39+
{
40+
return;
41+
}
42+
43+
if (dereferencedArgumentType.IsValueType)
44+
{
45+
// Unbox conversion
46+
// Assumes fromType is a boxed value
47+
// if we can, we emit a box and ldind, otherwise, we will use unbox.any
48+
if (LdindOpCodesDictionary.Instance[dereferencedArgumentType] != LdindOpCodesDictionary.EmptyOpCode)
49+
{
50+
gen.Emit(OpCodes.Unbox, dereferencedArgumentType);
51+
OpCodeUtil.EmitLoadIndirectOpCodeForType(gen, dereferencedArgumentType);
52+
}
53+
else
54+
{
55+
gen.Emit(OpCodes.Unbox_Any, dereferencedArgumentType);
56+
}
57+
}
58+
else
59+
{
60+
// Possible down-cast
61+
if (dereferencedArgumentType.IsGenericParameter)
62+
{
63+
gen.Emit(OpCodes.Unbox_Any, dereferencedArgumentType);
64+
}
65+
else if (dereferencedArgumentType.IsGenericType)
66+
{
67+
gen.Emit(OpCodes.Castclass, dereferencedArgumentType);
68+
}
69+
else if (dereferencedArgumentType.IsSubclassOf(typeof(object)))
70+
{
71+
gen.Emit(OpCodes.Castclass, dereferencedArgumentType);
72+
}
73+
}
74+
}
75+
}
76+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// Copyright 2004-2026 Castle Project - http://www.castleproject.org/
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
namespace Castle.DynamicProxy.Generators.Emitters.SimpleAST
16+
{
17+
using System.Diagnostics;
18+
using System.Reflection.Emit;
19+
20+
internal class ConvertArgumentToObjectExpression : IExpression
21+
{
22+
private readonly Reference dereferencedArgument;
23+
24+
public ConvertArgumentToObjectExpression(Reference dereferencedArgument)
25+
{
26+
Debug.Assert(dereferencedArgument.Type.IsByRef == false);
27+
28+
this.dereferencedArgument = dereferencedArgument;
29+
}
30+
31+
public void Emit(ILGenerator gen)
32+
{
33+
dereferencedArgument.Emit(gen);
34+
35+
var dereferencedArgumentType = dereferencedArgument.Type;
36+
if (dereferencedArgumentType.IsValueType || dereferencedArgumentType.IsGenericParameter)
37+
{
38+
gen.Emit(OpCodes.Box, dereferencedArgumentType);
39+
}
40+
}
41+
}
42+
}

src/Castle.Core/DynamicProxy/Generators/Emitters/SimpleAST/IndirectReference.cs

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright 2004-2025 Castle Project - http://www.castleproject.org/
1+
// Copyright 2004-2026 Castle Project - http://www.castleproject.org/
22
//
33
// Licensed under the Apache License, Version 2.0 (the "License");
44
// you may not use this file except in compliance with the License.
@@ -59,23 +59,5 @@ public override void EmitStore(IExpression value, ILGenerator gen)
5959
value.Emit(gen);
6060
OpCodeUtil.EmitStoreIndirectOpCodeForType(gen, Type);
6161
}
62-
63-
public static Reference WrapIfByRef(Reference reference)
64-
{
65-
return reference.Type.IsByRef ? new IndirectReference(reference) : reference;
66-
}
67-
68-
// TODO: Better name
69-
public static Reference[] WrapIfByRef(Reference[] references)
70-
{
71-
var result = new Reference[references.Length];
72-
73-
for (var i = 0; i < references.Length; i++)
74-
{
75-
result[i] = WrapIfByRef(references[i]);
76-
}
77-
78-
return result;
79-
}
8062
}
8163
}

src/Castle.Core/DynamicProxy/Generators/Emitters/SimpleAST/ReferencesToObjectArrayExpression.cs

Lines changed: 0 additions & 85 deletions
This file was deleted.

src/Castle.Core/DynamicProxy/Generators/GeneratorUtil.cs

Lines changed: 0 additions & 96 deletions
This file was deleted.

0 commit comments

Comments
 (0)