diff --git a/src/Castle.Core/DynamicProxy/Generators/Emitters/CodeBuilder.cs b/src/Castle.Core/DynamicProxy/Generators/Emitters/CodeBuilder.cs index 606e97543..4fdfd646c 100644 --- a/src/Castle.Core/DynamicProxy/Generators/Emitters/CodeBuilder.cs +++ b/src/Castle.Core/DynamicProxy/Generators/Emitters/CodeBuilder.cs @@ -1,4 +1,4 @@ -// Copyright 2004-2021 Castle Project - http://www.castleproject.org/ +// Copyright 2004-2025 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. @@ -22,14 +22,12 @@ namespace Castle.DynamicProxy.Generators.Emitters internal sealed class CodeBuilder { - private readonly List locals; private readonly List statements; private bool isEmpty; public CodeBuilder() { statements = new List(); - locals = new List(); isEmpty = true; } @@ -47,18 +45,11 @@ public CodeBuilder AddStatement(IStatement statement) public LocalReference DeclareLocal(Type type) { - var local = new LocalReference(type); - locals.Add(local); - return local; + return new LocalReference(type); } internal void Generate(ILGenerator il) { - foreach (var local in locals) - { - local.Generate(il); - } - foreach (var statement in statements) { statement.Emit(il); diff --git a/src/Castle.Core/DynamicProxy/Generators/Emitters/SimpleAST/AsTypeExpression.cs b/src/Castle.Core/DynamicProxy/Generators/Emitters/SimpleAST/AsTypeExpression.cs index 003e83d65..f4984690e 100644 --- a/src/Castle.Core/DynamicProxy/Generators/Emitters/SimpleAST/AsTypeExpression.cs +++ b/src/Castle.Core/DynamicProxy/Generators/Emitters/SimpleAST/AsTypeExpression.cs @@ -20,21 +20,21 @@ namespace Castle.DynamicProxy.Generators.Emitters.SimpleAST using System.Diagnostics; using System.Reflection.Emit; - [DebuggerDisplay("{reference} as {type}")] + [DebuggerDisplay("{expression} as {type}")] internal class AsTypeExpression : IExpression { - private readonly Reference reference; + private readonly IExpression expression; private readonly Type type; - public AsTypeExpression(Reference reference, Type type) + public AsTypeExpression(IExpression expression, Type type) { - this.reference = reference; + this.expression = expression; this.type = type; } public void Emit(ILGenerator gen) { - reference.Emit(gen); + expression.Emit(gen); gen.Emit(OpCodes.Isinst, type); } } diff --git a/src/Castle.Core/DynamicProxy/Generators/Emitters/SimpleAST/AssignArgumentStatement.cs b/src/Castle.Core/DynamicProxy/Generators/Emitters/SimpleAST/AssignArgumentStatement.cs deleted file mode 100644 index 296782103..000000000 --- a/src/Castle.Core/DynamicProxy/Generators/Emitters/SimpleAST/AssignArgumentStatement.cs +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright 2004-2025 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. - -#nullable enable - -namespace Castle.DynamicProxy.Generators.Emitters.SimpleAST -{ - using System.Reflection.Emit; - - internal class AssignArgumentStatement : IStatement - { - private readonly ArgumentReference argument; - private readonly IExpression expression; - - public AssignArgumentStatement(ArgumentReference argument, IExpression expression) - { - this.argument = argument; - this.expression = expression; - } - - public void Emit(ILGenerator gen) - { - argument.Emit(gen); - expression.Emit(gen); - } - } -} \ No newline at end of file diff --git a/src/Castle.Core/DynamicProxy/Generators/Emitters/SimpleAST/DefaultValueExpression.cs b/src/Castle.Core/DynamicProxy/Generators/Emitters/SimpleAST/DefaultValueExpression.cs index c4668cf20..177c73148 100644 --- a/src/Castle.Core/DynamicProxy/Generators/Emitters/SimpleAST/DefaultValueExpression.cs +++ b/src/Castle.Core/DynamicProxy/Generators/Emitters/SimpleAST/DefaultValueExpression.cs @@ -1,4 +1,4 @@ -// Copyright 2004-2021 Castle Project - http://www.castleproject.org/ +// Copyright 2004-2025 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. @@ -42,34 +42,12 @@ public void Emit(ILGenerator gen) gen.Emit(OpCodes.Initobj, type); gen.Emit(OpCodes.Ldloc, local); } - else if (type.IsByRef) - { - EmitByRef(gen); - } else { throw new NotImplementedException("Can't emit default value for type " + type); } } - private void EmitByRef(ILGenerator gen) - { - var elementType = type.GetElementType(); - if (IsPrimitiveOrClass(elementType)) - { - OpCodeUtil.EmitLoadOpCodeForDefaultValueOfType(gen, elementType); - OpCodeUtil.EmitStoreIndirectOpCodeForType(gen, elementType); - } - else if (elementType.IsGenericParameter || elementType.IsValueType) - { - gen.Emit(OpCodes.Initobj, elementType); - } - else - { - throw new NotImplementedException("Can't emit default value for reference of type " + elementType); - } - } - private bool IsPrimitiveOrClass(Type type) { if (type.IsPrimitive && type != typeof(IntPtr) && type != typeof(UIntPtr)) diff --git a/src/Castle.Core/DynamicProxy/Generators/Emitters/SimpleAST/FieldReference.cs b/src/Castle.Core/DynamicProxy/Generators/Emitters/SimpleAST/FieldReference.cs index 3ba3d8a90..476ac9c39 100644 --- a/src/Castle.Core/DynamicProxy/Generators/Emitters/SimpleAST/FieldReference.cs +++ b/src/Castle.Core/DynamicProxy/Generators/Emitters/SimpleAST/FieldReference.cs @@ -20,7 +20,7 @@ namespace Castle.DynamicProxy.Generators.Emitters.SimpleAST using System.Reflection; using System.Reflection.Emit; - [DebuggerDisplay("{fieldBuilder.Name} ({fieldBuilder.FieldType})")] + [DebuggerDisplay("{field.Name} ({field.FieldType})")] internal class FieldReference : Reference { private readonly FieldInfo field; diff --git a/src/Castle.Core/DynamicProxy/Generators/Emitters/SimpleAST/IfNullExpression.cs b/src/Castle.Core/DynamicProxy/Generators/Emitters/SimpleAST/IfNullExpression.cs index 470ea9af7..cb2ad00de 100644 --- a/src/Castle.Core/DynamicProxy/Generators/Emitters/SimpleAST/IfNullExpression.cs +++ b/src/Castle.Core/DynamicProxy/Generators/Emitters/SimpleAST/IfNullExpression.cs @@ -23,15 +23,7 @@ internal class IfNullExpression : IExpression, IStatement { private readonly IExpressionOrStatement ifNotNull; private readonly IExpressionOrStatement ifNull; - private readonly Reference? reference; - private readonly IExpression? expression; - - public IfNullExpression(Reference reference, IExpressionOrStatement ifNull, IExpressionOrStatement ifNotNull = null) - { - this.reference = reference ?? throw new ArgumentNullException(nameof(reference)); - this.ifNull = ifNull; - this.ifNotNull = ifNotNull; - } + private readonly IExpression expression; public IfNullExpression(IExpression expression, IExpressionOrStatement ifNull, IExpressionOrStatement ifNotNull = null) { @@ -42,15 +34,7 @@ public IfNullExpression(IExpression expression, IExpressionOrStatement ifNull, I public void Emit(ILGenerator gen) { - if (reference != null) - { - reference.Emit(gen); - } - else if (expression != null) - { - expression.Emit(gen); - } - + expression.Emit(gen); var notNull = gen.DefineLabel(); gen.Emit(OpCodes.Brtrue_S, notNull); ifNull.Emit(gen); diff --git a/src/Castle.Core/DynamicProxy/Generators/Emitters/SimpleAST/IndirectReference.cs b/src/Castle.Core/DynamicProxy/Generators/Emitters/SimpleAST/IndirectReference.cs index 8865d9970..3cc727401 100644 --- a/src/Castle.Core/DynamicProxy/Generators/Emitters/SimpleAST/IndirectReference.cs +++ b/src/Castle.Core/DynamicProxy/Generators/Emitters/SimpleAST/IndirectReference.cs @@ -22,10 +22,11 @@ namespace Castle.DynamicProxy.Generators.Emitters.SimpleAST using System.Reflection.Emit; /// - /// Wraps a reference that is passed - /// ByRef and provides indirect load/store support. + /// Represents the storage location X referenced by a + /// holding a managed pointer ("by-ref") &X to it. + /// It essentially has the same function as the pointer indirection / dereferencing operator *. /// - [DebuggerDisplay("&{OwnerReference}")] + [DebuggerDisplay("*{byRefReference}")] internal class IndirectReference : Reference { private readonly Reference byRefReference; diff --git a/src/Castle.Core/DynamicProxy/Generators/Emitters/SimpleAST/LocalReference.cs b/src/Castle.Core/DynamicProxy/Generators/Emitters/SimpleAST/LocalReference.cs index 450a69c57..1c848d015 100644 --- a/src/Castle.Core/DynamicProxy/Generators/Emitters/SimpleAST/LocalReference.cs +++ b/src/Castle.Core/DynamicProxy/Generators/Emitters/SimpleAST/LocalReference.cs @@ -23,32 +23,32 @@ namespace Castle.DynamicProxy.Generators.Emitters.SimpleAST [DebuggerDisplay("local {Type}")] internal class LocalReference : Reference { - private LocalBuilder? localBuilder; + private LocalBuilder? local; public LocalReference(Type type) : base(type) { } - public override void Generate(ILGenerator gen) - { - localBuilder = gen.DeclareLocal(base.Type); - } - public override void EmitAddress(ILGenerator gen) { - gen.Emit(OpCodes.Ldloca, localBuilder!); + gen.Emit(OpCodes.Ldloca, GetInitializedLocal(gen)); } public override void Emit(ILGenerator gen) { - gen.Emit(OpCodes.Ldloc, localBuilder!); + gen.Emit(OpCodes.Ldloc, GetInitializedLocal(gen)); } public override void EmitStore(IExpression value, ILGenerator gen) { value.Emit(gen); - gen.Emit(OpCodes.Stloc, localBuilder!); + gen.Emit(OpCodes.Stloc, GetInitializedLocal(gen)); + } + + private LocalBuilder GetInitializedLocal(ILGenerator gen) + { + return local ??= gen.DeclareLocal(Type); } } } \ No newline at end of file diff --git a/src/Castle.Core/DynamicProxy/Generators/Emitters/SimpleAST/NewArrayExpression.cs b/src/Castle.Core/DynamicProxy/Generators/Emitters/SimpleAST/NewArrayExpression.cs index e6a2524c9..e4f35a282 100644 --- a/src/Castle.Core/DynamicProxy/Generators/Emitters/SimpleAST/NewArrayExpression.cs +++ b/src/Castle.Core/DynamicProxy/Generators/Emitters/SimpleAST/NewArrayExpression.cs @@ -1,4 +1,4 @@ -// Copyright 2004-2021 Castle Project - http://www.castleproject.org/ +// Copyright 2004-2025 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. @@ -19,19 +19,19 @@ namespace Castle.DynamicProxy.Generators.Emitters.SimpleAST internal class NewArrayExpression : IExpression { - private readonly Type arrayType; + private readonly Type elementType; private readonly int size; - public NewArrayExpression(int size, Type arrayType) + public NewArrayExpression(int size, Type elementType) { this.size = size; - this.arrayType = arrayType; + this.elementType = elementType; } public void Emit(ILGenerator gen) { gen.Emit(OpCodes.Ldc_I4, size); - gen.Emit(OpCodes.Newarr, arrayType); + gen.Emit(OpCodes.Newarr, elementType); } } } \ No newline at end of file diff --git a/src/Castle.Core/DynamicProxy/Generators/Emitters/SimpleAST/Reference.cs b/src/Castle.Core/DynamicProxy/Generators/Emitters/SimpleAST/Reference.cs index 168f60357..ead676452 100644 --- a/src/Castle.Core/DynamicProxy/Generators/Emitters/SimpleAST/Reference.cs +++ b/src/Castle.Core/DynamicProxy/Generators/Emitters/SimpleAST/Reference.cs @@ -38,9 +38,5 @@ public Type Type public abstract void Emit(ILGenerator gen); public abstract void EmitStore(IExpression value, ILGenerator gen); - - public virtual void Generate(ILGenerator gen) - { - } } } \ No newline at end of file diff --git a/src/Castle.Core/DynamicProxy/Generators/Emitters/SimpleAST/ReturnStatement.cs b/src/Castle.Core/DynamicProxy/Generators/Emitters/SimpleAST/ReturnStatement.cs index c913945d1..cd2bb40b1 100644 --- a/src/Castle.Core/DynamicProxy/Generators/Emitters/SimpleAST/ReturnStatement.cs +++ b/src/Castle.Core/DynamicProxy/Generators/Emitters/SimpleAST/ReturnStatement.cs @@ -21,17 +21,11 @@ namespace Castle.DynamicProxy.Generators.Emitters.SimpleAST internal class ReturnStatement : IStatement { private readonly IExpression? expression; - private readonly Reference? reference; public ReturnStatement() { } - public ReturnStatement(Reference reference) - { - this.reference = reference; - } - public ReturnStatement(IExpression expression) { this.expression = expression; @@ -39,15 +33,7 @@ public ReturnStatement(IExpression expression) public void Emit(ILGenerator gen) { - if (reference != null) - { - reference.Emit(gen); - } - else if (expression != null) - { - expression.Emit(gen); - } - + expression?.Emit(gen); gen.Emit(OpCodes.Ret); } } diff --git a/src/Castle.Core/DynamicProxy/Generators/MinimalisticMethodGenerator.cs b/src/Castle.Core/DynamicProxy/Generators/MinimalisticMethodGenerator.cs index 965ea8e78..3b70fb86c 100644 --- a/src/Castle.Core/DynamicProxy/Generators/MinimalisticMethodGenerator.cs +++ b/src/Castle.Core/DynamicProxy/Generators/MinimalisticMethodGenerator.cs @@ -1,4 +1,4 @@ -// Copyright 2004-2021 Castle Project - http://www.castleproject.org/ +// Copyright 2004-2025 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. @@ -52,8 +52,10 @@ private void InitOutParameters(MethodEmitter emitter, ParameterInfo[] parameters if (parameter.IsOut) { emitter.CodeBuilder.AddStatement( - new AssignArgumentStatement(new ArgumentReference(parameter.ParameterType, index + 1), - new DefaultValueExpression(parameter.ParameterType))); + new AssignStatement( + new IndirectReference( + new ArgumentReference(parameter.ParameterType, index + 1)), + new DefaultValueExpression(parameter.ParameterType.GetElementType()))); } } } diff --git a/src/Castle.Core/DynamicProxy/Generators/OptionallyForwardingMethodGenerator.cs b/src/Castle.Core/DynamicProxy/Generators/OptionallyForwardingMethodGenerator.cs index 9ae81f7d2..86359be05 100644 --- a/src/Castle.Core/DynamicProxy/Generators/OptionallyForwardingMethodGenerator.cs +++ b/src/Castle.Core/DynamicProxy/Generators/OptionallyForwardingMethodGenerator.cs @@ -84,8 +84,10 @@ private void InitOutParameters(BlockStatement statements, ParameterInfo[] parame if (parameter.IsOut) { statements.AddStatement( - new AssignArgumentStatement(new ArgumentReference(parameter.ParameterType, index + 1), - new DefaultValueExpression(parameter.ParameterType))); + new AssignStatement( + new IndirectReference( + new ArgumentReference(parameter.ParameterType, index + 1)), + new DefaultValueExpression(parameter.ParameterType.GetElementType()))); } } }