From 8079b9e9a5689a33ff9838607855fd57886fc4bc Mon Sep 17 00:00:00 2001 From: Dominique Schuppli Date: Mon, 1 Mar 2021 02:16:42 +0100 Subject: [PATCH 1/2] Replace `ConstReference` which isn't a "reference" at all, but simply emits constants. There is already a `LiteralIntExpression` for integer constants; add new similar node types for string and Boolean constants. --- .../ClassProxySerializableContributor.cs | 8 +-- .../InterfaceProxySerializableContributor.cs | 8 +-- .../Contributors/SerializableContributor.cs | 22 ++++---- .../Emitters/SimpleAST/ConstReference.cs | 54 ------------------- .../SimpleAST/LiteralBoolExpression.cs | 33 ++++++++++++ .../SimpleAST/LiteralStringExpression.cs | 33 ++++++++++++ .../LoadRefArrayElementExpression.cs | 11 ++-- .../Emitters/SimpleAST/ThrowStatement.cs | 4 +- 8 files changed, 90 insertions(+), 83 deletions(-) delete mode 100644 src/Castle.Core/DynamicProxy/Generators/Emitters/SimpleAST/ConstReference.cs create mode 100644 src/Castle.Core/DynamicProxy/Generators/Emitters/SimpleAST/LiteralBoolExpression.cs create mode 100644 src/Castle.Core/DynamicProxy/Generators/Emitters/SimpleAST/LiteralStringExpression.cs diff --git a/src/Castle.Core/DynamicProxy/Contributors/ClassProxySerializableContributor.cs b/src/Castle.Core/DynamicProxy/Contributors/ClassProxySerializableContributor.cs index c5c58f3931..44d04a4a8c 100644 --- a/src/Castle.Core/DynamicProxy/Contributors/ClassProxySerializableContributor.cs +++ b/src/Castle.Core/DynamicProxy/Contributors/ClassProxySerializableContributor.cs @@ -96,8 +96,8 @@ protected override void CustomizeGetObjectData(CodeBuilder codebuilder, Argument new MethodInvocationExpression( serializationInfo, SerializationInfoMethods.AddValue_Bool, - new ConstReference("__delegateToBase"), - new ConstReference(delegateToBaseGetObjectData))); + new LiteralStringExpression("__delegateToBase"), + new LiteralBoolExpression(delegateToBaseGetObjectData))); if (delegateToBaseGetObjectData == false) { @@ -136,7 +136,7 @@ private void EmitCustomGetObjectData(CodeBuilder codebuilder, ArgumentReference var addValue = new MethodInvocationExpression( serializationInfo, SerializationInfoMethods.AddValue_Object, - new ConstReference("__data"), + new LiteralStringExpression("__data"), data); codebuilder.AddStatement(addValue); } @@ -179,7 +179,7 @@ private void GenerateSerializationConstructor(ClassEmitter emitter) { var getValue = new MethodInvocationExpression(serializationInfo, SerializationInfoMethods.GetValue, - new ConstReference(field.Reference.Name), + new LiteralStringExpression(field.Reference.Name), new TypeTokenExpression(field.Reference.FieldType)); ctor.CodeBuilder.AddStatement(new AssignStatement( field, diff --git a/src/Castle.Core/DynamicProxy/Contributors/InterfaceProxySerializableContributor.cs b/src/Castle.Core/DynamicProxy/Contributors/InterfaceProxySerializableContributor.cs index c0427da77f..2d30dbc656 100644 --- a/src/Castle.Core/DynamicProxy/Contributors/InterfaceProxySerializableContributor.cs +++ b/src/Castle.Core/DynamicProxy/Contributors/InterfaceProxySerializableContributor.cs @@ -38,15 +38,15 @@ protected override void CustomizeGetObjectData(CodeBuilder codebuilder, Argument new MethodInvocationExpression( serializationInfo, SerializationInfoMethods.AddValue_Object, - new ConstReference("__targetFieldType"), - new ConstReference(targetField.Reference.FieldType.AssemblyQualifiedName))); + new LiteralStringExpression("__targetFieldType"), + new LiteralStringExpression(targetField.Reference.FieldType.AssemblyQualifiedName))); codebuilder.AddStatement( new MethodInvocationExpression( serializationInfo, SerializationInfoMethods.AddValue_Object, - new ConstReference("__theInterface"), - new ConstReference(targetType.AssemblyQualifiedName))); + new LiteralStringExpression("__theInterface"), + new LiteralStringExpression(targetType.AssemblyQualifiedName))); } } } diff --git a/src/Castle.Core/DynamicProxy/Contributors/SerializableContributor.cs b/src/Castle.Core/DynamicProxy/Contributors/SerializableContributor.cs index fc6be52924..c4ff33945c 100644 --- a/src/Castle.Core/DynamicProxy/Contributors/SerializableContributor.cs +++ b/src/Castle.Core/DynamicProxy/Contributors/SerializableContributor.cs @@ -57,9 +57,9 @@ protected void ImplementGetObjectData(ClassEmitter emitter) new MethodInvocationExpression( null, TypeMethods.StaticGetType, - new ConstReference(typeof(ProxyObjectReference).AssemblyQualifiedName), - new ConstReference(1), - new ConstReference(0)))); + new LiteralStringExpression(typeof(ProxyObjectReference).AssemblyQualifiedName), + new LiteralBoolExpression(true), + new LiteralBoolExpression(false)))); getObjectData.CodeBuilder.AddStatement( new MethodInvocationExpression( @@ -93,36 +93,36 @@ protected void ImplementGetObjectData(ClassEmitter emitter) new AssignArrayStatement( interfacesLocal, i, - new ConstReference(interfaces[i].AssemblyQualifiedName))); + new LiteralStringExpression(interfaces[i].AssemblyQualifiedName))); } getObjectData.CodeBuilder.AddStatement( new MethodInvocationExpression( info, SerializationInfoMethods.AddValue_Object, - new ConstReference("__interfaces"), + new LiteralStringExpression("__interfaces"), interfacesLocal)); getObjectData.CodeBuilder.AddStatement( new MethodInvocationExpression( info, SerializationInfoMethods.AddValue_Object, - new ConstReference("__baseType"), - new ConstReference(emitter.BaseType.AssemblyQualifiedName))); + new LiteralStringExpression("__baseType"), + new LiteralStringExpression(emitter.BaseType.AssemblyQualifiedName))); getObjectData.CodeBuilder.AddStatement( new MethodInvocationExpression( info, SerializationInfoMethods.AddValue_Object, - new ConstReference("__proxyGenerationOptions"), + new LiteralStringExpression("__proxyGenerationOptions"), emitter.GetField("proxyGenerationOptions"))); getObjectData.CodeBuilder.AddStatement( new MethodInvocationExpression( info, SerializationInfoMethods.AddValue_Object, - new ConstReference("__proxyTypeId"), - new ConstReference(proxyTypeId))); + new LiteralStringExpression("__proxyTypeId"), + new LiteralStringExpression(proxyTypeId))); CustomizeGetObjectData(getObjectData.CodeBuilder, info, getObjectData.Arguments[1], emitter); @@ -136,7 +136,7 @@ protected virtual void AddAddValueInvocation(ArgumentReference serializationInfo new MethodInvocationExpression( serializationInfo, SerializationInfoMethods.AddValue_Object, - new ConstReference(field.Reference.Name), + new LiteralStringExpression(field.Reference.Name), field)); return; } diff --git a/src/Castle.Core/DynamicProxy/Generators/Emitters/SimpleAST/ConstReference.cs b/src/Castle.Core/DynamicProxy/Generators/Emitters/SimpleAST/ConstReference.cs deleted file mode 100644 index 4357d0aac1..0000000000 --- a/src/Castle.Core/DynamicProxy/Generators/Emitters/SimpleAST/ConstReference.cs +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright 2004-2021 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.SimpleAST -{ - using System; - using System.Diagnostics; - using System.Reflection; - using System.Reflection.Emit; - - [DebuggerDisplay("{value}")] - internal class ConstReference : TypeReference - { - private readonly object value; - - public ConstReference(object value) - : base(value.GetType()) - { - Debug.Assert(value.GetType().IsPrimitive || value is string, "Invalid type to ConstReference"); - - this.value = value; - } - - public override void Generate(ILGenerator gen) - { - } - - public override void LoadAddressOfReference(ILGenerator gen) - { - throw new NotSupportedException(); - } - - public override void LoadReference(ILGenerator gen) - { - OpCodeUtil.EmitLoadOpCodeForConstantValue(gen, value); - } - - public override void StoreReference(ILGenerator gen) - { - throw new NotImplementedException("ConstReference.StoreReference"); - } - } -} \ No newline at end of file diff --git a/src/Castle.Core/DynamicProxy/Generators/Emitters/SimpleAST/LiteralBoolExpression.cs b/src/Castle.Core/DynamicProxy/Generators/Emitters/SimpleAST/LiteralBoolExpression.cs new file mode 100644 index 0000000000..2fb5050115 --- /dev/null +++ b/src/Castle.Core/DynamicProxy/Generators/Emitters/SimpleAST/LiteralBoolExpression.cs @@ -0,0 +1,33 @@ +// Copyright 2004-2021 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.SimpleAST +{ + using System.Reflection.Emit; + + internal class LiteralBoolExpression : IExpression + { + private readonly bool value; + + public LiteralBoolExpression(bool value) + { + this.value = value; + } + + public void Emit(ILGenerator gen) + { + gen.Emit(value ? OpCodes.Ldc_I4_1 : OpCodes.Ldc_I4_0); + } + } +} diff --git a/src/Castle.Core/DynamicProxy/Generators/Emitters/SimpleAST/LiteralStringExpression.cs b/src/Castle.Core/DynamicProxy/Generators/Emitters/SimpleAST/LiteralStringExpression.cs new file mode 100644 index 0000000000..f8a842d1a6 --- /dev/null +++ b/src/Castle.Core/DynamicProxy/Generators/Emitters/SimpleAST/LiteralStringExpression.cs @@ -0,0 +1,33 @@ +// Copyright 2004-2021 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.SimpleAST +{ + using System.Reflection.Emit; + + internal class LiteralStringExpression : IExpression + { + private readonly string value; + + public LiteralStringExpression(string value) + { + this.value = value; + } + + public void Emit(ILGenerator gen) + { + gen.Emit(OpCodes.Ldstr, value); + } + } +} diff --git a/src/Castle.Core/DynamicProxy/Generators/Emitters/SimpleAST/LoadRefArrayElementExpression.cs b/src/Castle.Core/DynamicProxy/Generators/Emitters/SimpleAST/LoadRefArrayElementExpression.cs index 7e9f6b619b..311a46c432 100644 --- a/src/Castle.Core/DynamicProxy/Generators/Emitters/SimpleAST/LoadRefArrayElementExpression.cs +++ b/src/Castle.Core/DynamicProxy/Generators/Emitters/SimpleAST/LoadRefArrayElementExpression.cs @@ -19,23 +19,18 @@ namespace Castle.DynamicProxy.Generators.Emitters.SimpleAST internal class LoadRefArrayElementExpression : IExpression { private readonly Reference arrayReference; - private readonly ConstReference index; + private readonly LiteralIntExpression index; public LoadRefArrayElementExpression(int index, Reference arrayReference) - : this(new ConstReference(index), arrayReference) { - } - - public LoadRefArrayElementExpression(ConstReference index, Reference arrayReference) - { - this.index = index; + this.index = new LiteralIntExpression(index); this.arrayReference = arrayReference; } public void Emit(ILGenerator gen) { ArgumentsUtil.EmitLoadOwnerAndReference(arrayReference, gen); - ArgumentsUtil.EmitLoadOwnerAndReference(index, gen); + index.Emit(gen); gen.Emit(OpCodes.Ldelem_Ref); } } diff --git a/src/Castle.Core/DynamicProxy/Generators/Emitters/SimpleAST/ThrowStatement.cs b/src/Castle.Core/DynamicProxy/Generators/Emitters/SimpleAST/ThrowStatement.cs index a4c5a9e7a2..f34a3c563d 100644 --- a/src/Castle.Core/DynamicProxy/Generators/Emitters/SimpleAST/ThrowStatement.cs +++ b/src/Castle.Core/DynamicProxy/Generators/Emitters/SimpleAST/ThrowStatement.cs @@ -32,9 +32,9 @@ public ThrowStatement(Type exceptionType, string errorMessage) public void Emit(ILGenerator gen) { var ci = exceptionType.GetConstructor(new[] { typeof(string) }); - var constRef = new ConstReference(errorMessage); + var message = new LiteralStringExpression(errorMessage); - var creationStmt = new NewInstanceExpression(ci, constRef); + var creationStmt = new NewInstanceExpression(ci, message); creationStmt.Emit(gen); From 2778d339ab5e62c9c4b8b38be360a2180ecaf2b4 Mon Sep 17 00:00:00 2001 From: Dominique Schuppli Date: Mon, 1 Mar 2021 02:19:47 +0100 Subject: [PATCH 2/2] `EmitLoadOpCodeForConstantValue` is now obsolete --- .../Generators/Emitters/OpCodeUtil.cs | 26 ------------------- 1 file changed, 26 deletions(-) diff --git a/src/Castle.Core/DynamicProxy/Generators/Emitters/OpCodeUtil.cs b/src/Castle.Core/DynamicProxy/Generators/Emitters/OpCodeUtil.cs index d95272ca10..4b1ac75ed3 100644 --- a/src/Castle.Core/DynamicProxy/Generators/Emitters/OpCodeUtil.cs +++ b/src/Castle.Core/DynamicProxy/Generators/Emitters/OpCodeUtil.cs @@ -62,32 +62,6 @@ public static void EmitLoadIndirectOpCodeForType(ILGenerator gen, Type type) } } - /// - /// 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) - { - var code = LdcOpCodesDictionary.Instance[value.GetType()]; - gen.Emit(code, (int)value); - } - else if (value is bool) - { - var 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.