Skip to content

Commit f2bc4a2

Browse files
committed
Add missing ArrayElementReference
1 parent 81f1b9b commit f2bc4a2

File tree

7 files changed

+75
-92
lines changed

7 files changed

+75
-92
lines changed

src/Castle.Core/DynamicProxy/Contributors/SerializableContributor.cs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright 2004-2021 Castle Project - http://www.castleproject.org/
1+
// Copyright 2004-2025 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.
@@ -90,9 +90,8 @@ protected void ImplementGetObjectData(ClassEmitter emitter)
9090
for (var i = 0; i < interfaces.Length; i++)
9191
{
9292
getObjectData.CodeBuilder.AddStatement(
93-
new AssignArrayStatement(
94-
interfacesLocal,
95-
i,
93+
new AssignStatement(
94+
new ArrayElementReference(interfacesLocal, i),
9695
new LiteralStringExpression(interfaces[i].AssemblyQualifiedName)));
9796
}
9897

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright 2004-2021 Castle Project - http://www.castleproject.org/
1+
// Copyright 2004-2025 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.
@@ -331,7 +331,9 @@ protected void GenerateParameterlessConstructor(ClassEmitter emitter, Type baseC
331331
constructor.CodeBuilder.AddStatement(new AssignStatement(interceptorField,
332332
new NewArrayExpression(1, typeof(IInterceptor))));
333333
constructor.CodeBuilder.AddStatement(
334-
new AssignArrayStatement(interceptorField, 0, new NewInstanceExpression(typeof(StandardInterceptor))));
334+
new AssignStatement(
335+
new ArrayElementReference(interceptorField, 0),
336+
new NewInstanceExpression(typeof(StandardInterceptor))));
335337

336338
// Invoke base constructor
337339

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
// Copyright 2004-2025 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+
#nullable enable
16+
17+
namespace Castle.DynamicProxy.Generators.Emitters.SimpleAST
18+
{
19+
using System.Diagnostics;
20+
using System.Reflection.Emit;
21+
22+
internal sealed class ArrayElementReference : Reference
23+
{
24+
private readonly Reference array;
25+
private readonly int index;
26+
27+
public ArrayElementReference(Reference array, int index)
28+
: base(array.Type.GetElementType()!)
29+
{
30+
Debug.Assert(array.Type.IsArray);
31+
32+
// The below methods have the `ldelem.ref` and `stelem.ref` opcodes hardcoded,
33+
// which is only correct for reference types. Once we start using this class
34+
// for arrays of primitive types, enums, value types, or generic parameters,
35+
// we will need to revisit this.
36+
Debug.Assert(array.Type.GetElementType()!.IsClass || array.Type.GetElementType()!.IsInterface);
37+
38+
this.array = array;
39+
this.index = index;
40+
}
41+
42+
public override void Emit(ILGenerator gen)
43+
{
44+
array.Emit(gen);
45+
gen.Emit(OpCodes.Ldc_I4, index);
46+
gen.Emit(OpCodes.Ldelem_Ref);
47+
}
48+
49+
public override void EmitAddress(ILGenerator gen)
50+
{
51+
array.Emit(gen);
52+
gen.Emit(OpCodes.Ldc_I4, index);
53+
gen.Emit(OpCodes.Ldelema);
54+
}
55+
56+
public override void EmitStore(IExpression value, ILGenerator gen)
57+
{
58+
array.Emit(gen);
59+
gen.Emit(OpCodes.Ldc_I4, index);
60+
value.Emit(gen);
61+
gen.Emit(OpCodes.Stelem_Ref);
62+
}
63+
}
64+
}

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

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

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

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

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ bool IsReadOnly(ParameterInfo parameter)
133133

134134
private static ConvertExpression Argument(int i, LocalReference invocationArgs, Reference[] arguments)
135135
{
136-
return new ConvertExpression(arguments[i].Type, new LoadRefArrayElementExpression(i, invocationArgs));
136+
return new ConvertExpression(arguments[i].Type, new ArrayElementReference(invocationArgs, i));
137137
}
138138

139139
private static AssignStatement AssignArgument(Reference[] dereferencedArguments, int i,

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,9 @@ private void EmitLoadGenericMethodArguments(MethodEmitter methodEmitter, MethodI
222222
for (var i = 0; i < genericParameters.Length; ++i)
223223
{
224224
methodEmitter.CodeBuilder.AddStatement(
225-
new AssignArrayStatement(genericParamsArrayLocal, i, new TypeTokenExpression(genericParameters[i])));
225+
new AssignStatement(
226+
new ArrayElementReference(genericParamsArrayLocal, i),
227+
new TypeTokenExpression(genericParameters[i])));
226228
}
227229
methodEmitter.CodeBuilder.AddStatement(
228230
new MethodInvocationExpression(invocationLocal,

0 commit comments

Comments
 (0)