public void Load( MethodEmitter method ) { if ( m_Field != null ) { method.LoadArgument( 0 ); method.LoadField( m_Field ); } else if ( m_Value == null ) { method.LoadNull( m_Type ); } else { if ( m_Value is int ) method.Load( (int) m_Value ); else if ( m_Value is long ) method.Load( (long) m_Value ); else if ( m_Value is float ) method.Load( (float) m_Value ); else if ( m_Value is double ) method.Load( (double) m_Value ); else if ( m_Value is char ) method.Load( (char) m_Value ); else if ( m_Value is bool ) method.Load( (bool) m_Value ); else if ( m_Value is string ) method.Load( (string) m_Value ); else if ( m_Value is Enum ) method.Load( (Enum) m_Value ); else throw new InvalidOperationException( "Unrecognized comparison value." ); } }
protected override void ImplementInvokeMethodOnTarget(AbstractTypeEmitter @class, ParameterInfo[] parameters, MethodEmitter invokeMethodOnTarget, MethodInfo callbackMethod, Reference targetField) { invokeMethodOnTarget.CodeBuilder.AddStatement( new ExpressionStatement( new MethodInvocationExpression(SelfReference.Self, InvocationMethods.EnsureValidTarget))); base.ImplementInvokeMethodOnTarget(@class, parameters, invokeMethodOnTarget, callbackMethod, targetField); }
void ICondition.Compile(MethodEmitter emitter) { // The object was safely cast to be the conditionals type // If it's null, then the type cast didn't work... emitter.LoadNull(); emitter.Compare(OpCodes.Ceq); emitter.LogicalNot(); }
private Reference GetDelegate(AbstractTypeEmitter invocation, MethodEmitter invokeMethodOnTarget) { var closedDelegateType = delegateType.MakeGenericType(invocation.GenericTypeParams); var localReference = invokeMethodOnTarget.CodeBuilder.DeclareLocal(closedDelegateType); var closedMethodOnTarget = method.MethodOnTarget.MakeGenericMethod(invocation.GenericTypeParams); var localTarget = new ReferenceExpression(targetReference); invokeMethodOnTarget.CodeBuilder.AddStatement( SetDelegate(localReference, localTarget, closedDelegateType, closedMethodOnTarget)); return(localReference); }
private Reference GetDelegate(AbstractTypeEmitter invocation, MethodEmitter invokeMethodOnTarget) { var genericTypeParameters = invocation.GenericTypeParams.AsTypeArray(); var closedDelegateType = delegateType.MakeGenericType(genericTypeParameters); var localReference = invokeMethodOnTarget.CodeBuilder.DeclareLocal(closedDelegateType); var closedMethodOnTarget = method.MethodOnTarget.MakeGenericMethod(genericTypeParameters); invokeMethodOnTarget.CodeBuilder.AddStatement( SetDelegate(localReference, targetReference, closedDelegateType, closedMethodOnTarget)); return(localReference); }
public MethodInvocationExpression GetCallbackMethodInvocation( AbstractTypeEmitter invocation, IExpression[] args, Reference targetField, MethodEmitter invokeMethodOnTarget ) { var @delegate = GetDelegate(invocation, invokeMethodOnTarget); return(new MethodInvocationExpression(@delegate, GetCallbackMethod(), args)); }
protected void ImplementProxyTargetAccessor(ClassEmitter emitter, FieldReference interceptorsField) { MethodEmitter dynProxyGetTarget = emitter.CreateMethod("DynProxyGetTarget", typeof(object)); dynProxyGetTarget.CodeBuilder.AddStatement( new ReturnStatement(new ConvertExpression(typeof(object), targetType, GetTargetReferenceExpression(emitter)))); MethodEmitter getInterceptors = emitter.CreateMethod("GetInterceptors", typeof(IInterceptor[])); getInterceptors.CodeBuilder.AddStatement( new ReturnStatement(interceptorsField)); }
internal CodeBlock(ClassGenerator clazz, MethodEmitter emitter, params Parameter[] parameters) { this.Clazz = clazz; this._emitter = emitter; this._parent = null; this._continuableBlock = false; LocalVariables.createNew(clazz.Handle(), "this"); foreach (Parameter parameter in parameters) { LocalVariables.createNew(parameter.Type(), parameter.Name()); } }
public MethodInvocationExpression GetCallbackMethodInvocation( AbstractTypeEmitter invocation, IExpression[] args, Reference targetField, MethodEmitter invokeMethodOnTarget ) { var allArgs = GetAllArgs(args, targetField); var @delegate = (Reference)invocation.GetField("delegate"); return(new MethodInvocationExpression(@delegate, GetCallbackMethod(), allArgs)); }
public void StaticMethodArguments() { ClassEmitter emitter = new ClassEmitter(generator.ProxyBuilder.ModuleScope, "Foo", typeof(List <object>), Type.EmptyTypes); MethodEmitter methodEmitter = emitter.CreateMethod("StaticMethod", MethodAttributes.Public | MethodAttributes.Static, typeof(string), typeof(string)); methodEmitter.CodeBuilder.AddStatement(new ReturnStatement(methodEmitter.Arguments[0])); Type t = emitter.BuildType(); Assert.AreEqual("five", t.GetMethod("StaticMethod").Invoke(null, new object[] { "five" })); }
/// <summary> /// Creates a reference to a parameter used in a custom attribute. /// </summary> /// <param name="emitter">The emitter.</param> /// <param name="attribute">The attribute.</param> /// <param name="arg">The argument.</param> public void CreateAttributeParameter(MethodEmitter emitter, CustomAttribute attribute, CustomAttributeArgument arg) { var il = emitter.GetIL(); if (arg.Value == null) { il.Emit(Codes.Null); return; } var type = arg.Type; if (type.IsArray) { var elements = (arg.Value as IEnumerable).Cast <CustomAttributeArgument>().ToArray(); il.Emit(Codes.Int(elements.Length)); il.Emit(Codes.CreateArray(type.GetElementType())); if (elements.Length == 0) { return; } il.Emit(Codes.Duplicate); for (int i = 0, count = elements.Length; i < count; i++) { il.Emit(Codes.Int(i)); if (elements[i].Value == null) { il.Emit(Codes.Null); il.Emit(Codes.StoreArray); } else { il.Emit(Codes.Load(elements[i].Value)); il.Emit(Codes.StoreArray); } if (i + 1 < count) { il.Emit(Codes.Duplicate); } } } else { il.Emit(Codes.Load(arg.Value)); } }
/// <summary> /// Create an attribute variable for a property definition. /// </summary> /// <param name="property">The property.</param> /// <param name="get">The getter method.</param> /// <param name="set">The setter method.</param> /// <param name="attribute">The attribute.</param> /// <param name="field">The optional field reference which was routed.</param> /// <returns></returns> public Variable[] CreateAttribute(PropertyEmitter property, MethodEmitter get, MethodEmitter set, CustomAttribute attribute, MemberReference field) { var method = get ?? set; var sta = method.Target.IsStatic; var options = attribute.GetAttribute(Context.Finder.CompilationOptionsAttribute); var scope = options.GetProperty("Scope", notFound: AttributeScopeSingleton); if (sta) { if (scope == AttributeScopeInstanced) { scope = AttributeScopeSingleton; } else if (scope == AttributeScopeMultiInstanced) { scope = AttributeScopeMultiSingleton; } } var hasGet = attribute.HasInterface(Context.Finder.IPropertyGetInterceptor); var hasSet = attribute.HasInterface(Context.Finder.IPropertySetInterceptor); switch (scope) { case AttributeScopeAdhoc: var adhocGet = hasGet && get != null?CreateAttributeAdhoc(get, attribute, property.Target) : null; var adhocSet = hasSet && set != null?CreateAttributeAdhoc(set, attribute, property.Target) : null; return(new[] { adhocGet, adhocSet }); case AttributeScopeInstanced: var instanced = CreateAttributeInstanced(property.Parent, attribute, field ?? property.Target); return(new[] { hasGet?instanced : null, hasSet ? instanced : null }); case AttributeScopeMultiInstanced: var multi = CreateAttributeMultiInstanced(property.Parent, attribute, field ?? property.Target); return(new[] { hasGet?multi : null, hasSet ? multi : null }); case AttributeScopeSingleton: var singleton = CreateAttributeSingleton(property.Parent, attribute, field ?? property.Target); return(new[] { hasGet?singleton : null, hasSet ? singleton : null }); case AttributeScopeMultiSingleton: var multiSingleton = CreateAttributeMultiSingleton(property.Parent, attribute, field ?? property.Target); return(new[] { hasGet?multiSingleton : null, hasSet ? multiSingleton : null }); default: throw new NotSupportedException($"Cannot create attribute '{attribute.AttributeType.FullName}' with scope '{scope}'"); } }
public void InstanceMethodArguments() { ClassEmitter emitter = new ClassEmitter(generator.ProxyBuilder.ModuleScope, "Foo", typeof(List <object>), Type.EmptyTypes); MethodEmitter methodEmitter = emitter.CreateMethod("InstanceMethod", MethodAttributes.Public, typeof(string), typeof(string)); methodEmitter.CodeBuilder.AddStatement(new ReturnStatement(methodEmitter.Arguments[0])); Type t = emitter.BuildType(); object instance = Activator.CreateInstance(t); Assert.AreEqual("six", t.GetMethod("InstanceMethod").Invoke(instance, new object[] { "six" })); }
private void InitOutParameters(MethodEmitter emitter, ParameterInfo[] parameters) { for (var index = 0; index < parameters.Length; index++) { var parameter = parameters[index]; if (parameter.IsOut) { emitter.CodeBuilder.AddStatement( new AssignArgumentStatement(new ArgumentReference(parameter.ParameterType, index + 1), new DefaultValueExpression(parameter.ParameterType))); } } }
protected override MethodEmitter BuildProxiedMethodBody(MethodEmitter emitter, ClassEmitter @class, INamingScope namingScope) { var targetReference = getTargetReference(@class, MethodToOverride); emitter.CodeBuilder.AddStatement( new IfNullExpression( targetReference, IfNull(emitter.ReturnType), IfNotNull(targetReference))); return(emitter); }
public override void Close() { EndBlock(); if (_parent != null) { _parent._emitter = _emitter; } else { _emitter.done(); } this._emitter = InvalidState.BlockClosed; }
public void Load(MethodEmitter method) { if (m_Field != null) { method.LoadArgument(0); method.LoadField(m_Field); } else if (m_Value == null) { method.LoadNull(m_Type); } else { if (m_Value is int i) { method.Load(i); } else if (m_Value is long lValue) { method.Load(lValue); } else if (m_Value is float fValue) { method.Load(fValue); } else if (m_Value is double dValue) { method.Load(dValue); } else if (m_Value is char cValue) { method.Load(cValue); } else if (m_Value is bool bValue) { method.Load(bValue); } else if (m_Value is string sValue) { method.Load(sValue); } else if (m_Value is Enum eValue) { method.Load(eValue); } else { throw new InvalidOperationException("Unrecognized comparison value."); } } }
public void Load(MethodEmitter method) { if (Field != null) { method.LoadArgument(0); method.LoadField(Field); } else if (Value == null) { method.LoadNull(Type); } else { if (Value is int i) { method.Load(i); } else if (Value is long l) { method.Load(l); } else if (Value is float f) { method.Load(f); } else if (Value is double d) { method.Load(d); } else if (Value is char c) { method.Load(c); } else if (Value is bool b) { method.Load(b); } else if (Value is string s) { method.Load(s); } else if (Value is Enum e) { method.Load(e); } else { throw new InvalidOperationException("Unrecognized comparison value."); } } }
public void Load(MethodEmitter method) { if (m_Field != null) { method.LoadArgument(0); method.LoadField(m_Field); } else if (m_Value == null) { method.LoadNull(m_Type); } else { if (m_Value is int) { method.Load((int)m_Value); } else if (m_Value is long) { method.Load((long)m_Value); } else if (m_Value is float) { method.Load((float)m_Value); } else if (m_Value is double) { method.Load((double)m_Value); } else if (m_Value is char) { method.Load((char)m_Value); } else if (m_Value is bool) { method.Load((bool)m_Value); } else if (m_Value is string) { method.Load((string)m_Value); } else if (m_Value is Enum) { method.Load((Enum)m_Value); } else { throw new InvalidOperationException("Unrecognized comparison value."); } } }
public void TestCanEmit_InstancePropertyInitializer() { var stringType = assemblyEmitter.TypeSystem.String; var voidType = assemblyEmitter.TypeSystem.Void; var initializer = new LiteralNode(stringType, "aaa"); var backingField = new FieldDefinition("testProperty_backingField", FieldAttributes.Private, stringType); var setter = new MethodEmitter(typeEmitter, "set_testProperty", voidType, MethodAttributes.Public); var value = new ParameterDefinition("value", ParameterAttributes.None, stringType); var setterBody = new CodeBlockNode() { Nodes = new List <IParserNode>() { new AssignmentOperatorNode() { LeftOperand = new FieldNode() { ObjectInstance = new ThisNode() { ExpressionReturnType = backingField.DeclaringType }, Field = backingField }, RightOperand = new ParameterNode(value) } } }; setter.AddArgument(value); setter.ParseTree(setterBody); var property = new PropertyDefinition("testProperty", PropertyAttributes.None, stringType); property.SetMethod = (MethodDefinition)setter.Get(); typeEmitter.AddField(backingField); typeEmitter.AddProperty(property, initializer); var loadFieldExpression = new FieldNode() { ObjectInstance = ConstructTypeEmitterInstance(), Field = backingField }; GenerateBodyToOutputExpression(loadFieldExpression); ExpectedOutput = "aaa"; AssertSuccessByExecution(); }
public CustomMethodEmitter(CustomClassEmitter declaringType, string name, MethodAttributes attributes, MethodInfo methodToUseAsATemplate) { ArgumentUtility.CheckNotNull("declaringType", declaringType); ArgumentUtility.CheckNotNullOrEmpty("name", name); ArgumentUtility.CheckNotNull("attributes", attributes); ArgumentUtility.CheckNotNull("methodToUseAsATemplate", methodToUseAsATemplate); MethodEmitter innerEmitter = declaringType.InnerEmitter.CreateMethod(name, attributes, methodToUseAsATemplate); _innerEmitter = innerEmitter; _declaringType = declaringType; _name = name; _parameterTypes = _innerEmitter.Arguments.Select(a => a.Type).ToArray(); }
public void TestCanEmit_FunctionAssignmentToFunctorWithoutArgs() { var voidType = assemblyEmitter.TypeSystem.Void; var targetMethod = new MethodEmitter(typeEmitter, "TargetMethod", voidType); targetMethod.ParseTree(new CodeBlockNode() { Nodes = new List <IParserNode>() { CallConsoleWriteLine(new LiteralNode(assemblyEmitter.TypeSystem.String, "TargetMethod was called")) } }); var functorType = AssemblyRegistry.GetFunctorType(assemblyEmitter, targetMethod.Get()); var field = new FieldDefinition("myFunction", FieldAttributes.Public, functorType); var initializer = new FunctionNode() { Method = targetMethod.Get(), ObjectInstance = new ThisNode() { ExpressionReturnType = typeEmitter.Get(assemblyEmitter) }, ExpressionReturnType = functorType }; typeEmitter.AddField(field); typeEmitter.AddFieldInitializer(field, initializer); BodyCodeBlock = new CodeBlockNode() { Nodes = new List <IParserNode>() { new MethodCallNode() { ExpressionReturnType = voidType, Function = new FieldNode() { Field = field, ObjectInstance = ConstructTypeEmitterInstance() }, Args = new IExpressionNode[0] } } }; ExpectedOutput = "TargetMethod was called"; AssertSuccessByExecution(); }
/// <summary> /// Weaves all types which are candidates for method interception. /// </summary> public void WeaveMethodInterceptors() { var candidates = Context.Candidates.FindTypeByMethodInterceptors(); foreach (var item in candidates) { var weaver = new TypeEmitter(Context.Module, item.Type, Context); foreach (var method in item.Methods) { var inner = new MethodEmitter(weaver, method.Method); WeaveMethodInterceptors(inner, method); } } }
protected override MethodEmitter BuildProxiedMethodBody(MethodEmitter emitter, ClassEmitter @class, ProxyGenerationOptions options, INamingScope namingScope) { var targetReference = getTargetReference(@class, MethodToOverride); var arguments = ArgumentsUtil.ConvertToArgumentReferenceExpression(MethodToOverride.GetParameters()); emitter.CodeBuilder.AddStatement(new ReturnStatement( new MethodInvocationExpression( targetReference, MethodToOverride, arguments) { VirtualCall = true })); return(emitter); }
/// <summary> /// Creates a reference to a property used in a custom attribute. /// </summary> /// <param name="emitter">The emitter.</param> /// <param name="attribute">The attribute.</param> /// <param name="field">The attribute variable.</param> /// <param name="property">The property.</param> public void CreateAttributeProperty(MethodEmitter emitter, CustomAttribute attribute, Variable field, Mono.Cecil.CustomAttributeNamedArgument property) { var il = emitter.GetIL(); var member = field.Type.Resolve().Properties.FirstOrDefault(p => p.Name == property.Name)?.SetMethod; if (member == null) { throw new MissingMemberException($"Cannot resolve property {property.Name} of {attribute.AttributeType.Name} as there is no setter"); } il.Emit(Codes.ThisIf(field)); il.Emit(Codes.Load(field)); CreateAttributeParameter(emitter, attribute, property.Argument); il.Emit(Codes.Invoke(member.Import())); }
protected override MethodEmitter BuildProxiedMethodBody(MethodEmitter emitter, ClassEmitter @class, ProxyGenerationOptions options, INamingScope namingScope) { InitOutParameters(emitter, MethodToOverride.GetParameters()); if (emitter.ReturnType == typeof(void)) { emitter.CodeBuilder.AddStatement(new ReturnStatement()); } else { emitter.CodeBuilder.AddStatement(new ReturnStatement(new DefaultValueExpression(emitter.ReturnType))); } return(emitter); }
public CustomMethodEmitter(CustomClassEmitter declaringType, string name, MethodAttributes attributes, Type returnType, Type[] parameterTypes) { ArgumentUtility.CheckNotNull("declaringType", declaringType); ArgumentUtility.CheckNotNullOrEmpty("name", name); ArgumentUtility.CheckNotNull("attributes", attributes); ArgumentUtility.CheckNotNull("returnType", returnType); ArgumentUtility.CheckNotNull("parameterTypes", parameterTypes); MethodEmitter innerEmitter = declaringType.InnerEmitter.CreateMethod(name, attributes, returnType, parameterTypes); _innerEmitter = innerEmitter; _declaringType = declaringType; _name = name; _parameterTypes = parameterTypes; }
public void TestCanEmit_FunctionAssignmentToDelegate() { var voidType = assemblyEmitter.TypeSystem.Void; var targetMethod = new MethodEmitter(typeEmitter, "TargetMethod", voidType, MethodAttributes.Private | MethodAttributes.Static); targetMethod.ParseTree(new CodeBlockNode() { Nodes = new List <IParserNode>() { CallConsoleWriteLine(new LiteralNode(assemblyEmitter.TypeSystem.String, "Inside target method")) } }); var declaringType = (TypeDefinition)typeEmitter.Get(assemblyEmitter); var delegateType = DelegateEmitter.Create(assemblyEmitter, "MyDelegate", declaringType, voidType, new TypeReference[0]); declaringType.NestedTypes.Add(delegateType); var delegateField = new FieldDefinition("myDelegate", FieldAttributes.Public | FieldAttributes.Static, delegateType); typeEmitter.AddField(delegateField); BodyCodeBlock = new CodeBlockNode() { Nodes = new List <IParserNode>() { new AssignmentOperatorNode() { LeftOperand = new FieldNode(delegateField), RightOperand = new FunctionNode() { ExpressionReturnType = delegateType, Method = targetMethod.Get() } }, new MethodCallNode() { ExpressionReturnType = voidType, Function = new FieldNode(delegateField), Args = new IExpressionNode[0] } } }; ExpectedOutput = "Inside target method"; AssertSuccessByExecution(); }
/// <summary> /// Create an attribute variable for a method definition. /// </summary> /// <param name="method">The method.</param> /// <param name="attribute">The attribute.</param> /// <param name="member">The optional parameter member.</param> /// <returns></returns> public Variable CreateAttribute(MethodEmitter method, CustomAttribute attribute) { var options = attribute.GetAttribute(Context.Finder.CompilationOptionsAttribute); var scope = options != null?options.GetProperty("Scope", notFound : AttributeScopeSingleton) : AttributeScopeSingleton; if (scope == AttributeScopeInstanced && attribute.HasConstructorArguments) { scope = AttributeScopeMultiInstanced; } switch (scope) { case AttributeScopeInstanced: if (method.Target.IsStatic) { scope = AttributeScopeSingleton; } break; case AttributeScopeMultiInstanced: if (method.Target.IsStatic) { scope = AttributeScopeMultiSingleton; } break; } switch (scope) { case AttributeScopeAdhoc: return(CreateAttributeAdhoc(method, attribute, method.Target)); case AttributeScopeInstanced: return(CreateAttributeInstanced(method.Parent, attribute, method.Target)); case AttributeScopeMultiInstanced: return(CreateAttributeMultiInstanced(method.Parent, attribute, method.Target)); case AttributeScopeSingleton: return(CreateAttributeSingleton(method.Parent, attribute, method.Target)); case AttributeScopeMultiSingleton: return(CreateAttributeMultiSingleton(method.Parent, attribute, method.Target)); default: throw new NotSupportedException($"Cannot create attribute '{attribute.AttributeType.FullName}' with scope {scope}"); } }
protected virtual void AddAddValueInvocation( ArgumentReference serializationInfo, MethodEmitter getObjectData, FieldReference field ) { getObjectData.CodeBuilder.AddStatement( new MethodInvocationExpression( serializationInfo, SerializationInfoMethods.AddValue_Object, new LiteralStringExpression(field.Reference.Name), field ) ); return; }
private void ParseHeader(Modifiers mods, IAbstractSyntaxTree lexerNode, string methodName) { Contract.Requires(lexerNode.Type == Lexer.TokenType.Type); var point = Parser.GetSequencePoint(lexerNode); var builder = new TypeNode.TypeBuilder(Parent); int count = lexerNode.Children.Count; var paramz = ParseParams(Parser, lexerNode.Children[count - 1]); for (int i = 0; i < count - 1; i++) { builder.Append(lexerNode.Children[i]); } MethodReturnType = builder.Type; emitter = new MethodEmitter(GetClass().TypeEmitter, methodName, MethodReturnType, AttributesFromModifiers(Parser.GetSequencePoint(lexerNode), mods)); foreach (var p in paramz) { var param = ParseParameter(Parent, p.Type, p.Name); if (param.ParameterType.IsVoid()) { ErrorCode.IllegalMethodParam.ReportAndThrow(point, "Illegal method parameter type void"); } if (symbols.ContainsKey(param.Name)) { ErrorCode.ParamAlreadyDeclared.ReportAndThrow(point, "Parameter with name {0} is already declared", param.Name); } emitter.AddArgument(param); symbols.Add(param.Name, param); } ParamTypes = symbols.Values.Select(p => p.ParameterType); if (mods.HasFlag(Modifiers.Entry)) { if (MethodReturnType != Parser.Int32 && MethodReturnType != Parser.UInt32 && MethodReturnType != Parser.Void) { InvalidEntryReturn(SequencePoint, MethodReturnType); } emitter.SetAsEntryPoint(); if (!ValidParametersForMain(ParamTypes)) { InvalidEntryParams(point, ParamTypes); } } }
/// <summary> /// Defines a new runtime method. /// </summary> /// <param name="returnType">The return type.</param> /// <param name="parameterTypes">All parameter types.</param> /// <param name="methodEmitter">The method emitter.</param> /// <returns>The acquired scoped lock.</returns> public ScopedLock DefineRuntimeMethod( Type returnType, Type[] parameterTypes, out MethodEmitter methodEmitter) { var scopedLock = new ScopedLock(this); methodEmitter = new MethodEmitter( new DynamicMethod( LauncherMethodName, returnType, parameterTypes, moduleBuilder, true)); return(scopedLock); }
/// <summary> /// Gets or creates the <c>add</c> method emitter. /// </summary> /// <returns></returns> public MethodEmitter GetAdd() { if (add != null) { return(add); } var attributes = MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.Final; var method = new MethodDefinition($"add_{Target.Name}", attributes, Parent.Context.Module.TypeSystem.Void); method.Parameters.Add(new ParameterDefinition("value", ParameterAttributes.None, Target.EventType.Import())); Target.AddMethod = method; Parent.Target.Methods.Add(method); Parent.Context.AddCompilerGenerated(method); return(add = new MethodEmitter(Parent, method)); }
public abstract void Compile( MethodEmitter emitter );
public static IComparer Compile(AssemblyEmitter assembly, Type objectType, Property[] props) { TypeBuilder typeBuilder = assembly.DefineType( "__distinct", TypeAttributes.Public, typeof(object)); #region Constructor { ConstructorBuilder ctor = typeBuilder.DefineConstructor( MethodAttributes.Public, CallingConventions.Standard, Type.EmptyTypes); ILGenerator il = ctor.GetILGenerator(); // : base() il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Call, typeof(object).GetConstructor(Type.EmptyTypes)); // return; il.Emit(OpCodes.Ret); } #endregion #region IComparer typeBuilder.AddInterfaceImplementation(typeof(IComparer)); MethodBuilder compareMethod; #region Compare { MethodEmitter emitter = new MethodEmitter(typeBuilder); emitter.Define( /* name */ "Compare", /* attr */ MethodAttributes.Public | MethodAttributes.Virtual, /* return */ typeof(int), /* params */ new Type[] { typeof(object), typeof(object) }); LocalBuilder a = emitter.CreateLocal(objectType); LocalBuilder b = emitter.CreateLocal(objectType); LocalBuilder v = emitter.CreateLocal(typeof(int)); emitter.LoadArgument(1); emitter.CastAs(objectType); emitter.StoreLocal(a); emitter.LoadArgument(2); emitter.CastAs(objectType); emitter.StoreLocal(b); emitter.Load(0); emitter.StoreLocal(v); Label end = emitter.CreateLabel(); for (int i = 0; i < props.Length; ++i) { if (i > 0) { emitter.LoadLocal(v); emitter.BranchIfTrue(end); // if ( v != 0 ) return v; } Property prop = props[i]; emitter.LoadLocal(a); emitter.Chain(prop); bool couldCompare = emitter.CompareTo(1, delegate() { emitter.LoadLocal(b); emitter.Chain(prop); }); if (!couldCompare) throw new InvalidOperationException("Property is not comparable."); emitter.StoreLocal(v); } emitter.MarkLabel(end); emitter.LoadLocal(v); emitter.Return(); typeBuilder.DefineMethodOverride( emitter.Method, typeof(IComparer).GetMethod( "Compare", new Type[] { typeof(object), typeof(object) })); compareMethod = emitter.Method; } #endregion #endregion #region IEqualityComparer typeBuilder.AddInterfaceImplementation(typeof(IEqualityComparer<object>)); #region Equals { MethodEmitter emitter = new MethodEmitter(typeBuilder); emitter.Define( /* name */ "Equals", /* attr */ MethodAttributes.Public | MethodAttributes.Virtual, /* return */ typeof(bool), /* params */ new Type[] { typeof(object), typeof(object) }); emitter.Generator.Emit(OpCodes.Ldarg_0); emitter.Generator.Emit(OpCodes.Ldarg_1); emitter.Generator.Emit(OpCodes.Ldarg_2); emitter.Generator.Emit(OpCodes.Call, compareMethod); emitter.Generator.Emit(OpCodes.Ldc_I4_0); emitter.Generator.Emit(OpCodes.Ceq); emitter.Generator.Emit(OpCodes.Ret); typeBuilder.DefineMethodOverride( emitter.Method, typeof(IEqualityComparer<object>).GetMethod( "Equals", new Type[] { typeof(object), typeof(object) })); } #endregion #region GetHashCode { MethodEmitter emitter = new MethodEmitter(typeBuilder); emitter.Define( /* name */ "GetHashCode", /* attr */ MethodAttributes.Public | MethodAttributes.Virtual, /* return */ typeof(int), /* params */ new Type[] { typeof(object) }); LocalBuilder obj = emitter.CreateLocal(objectType); emitter.LoadArgument(1); emitter.CastAs(objectType); emitter.StoreLocal(obj); for (int i = 0; i < props.Length; ++i) { Property prop = props[i]; emitter.LoadLocal(obj); emitter.Chain(prop); Type active = emitter.Active; MethodInfo getHashCode = active.GetMethod("GetHashCode", Type.EmptyTypes); if (getHashCode == null) getHashCode = typeof(object).GetMethod("GetHashCode", Type.EmptyTypes); if (active != typeof(int)) { if (!active.IsValueType) { LocalBuilder value = emitter.AcquireTemp(active); Label valueNotNull = emitter.CreateLabel(); Label done = emitter.CreateLabel(); emitter.StoreLocal(value); emitter.LoadLocal(value); emitter.BranchIfTrue(valueNotNull); emitter.Load(0); emitter.Pop(typeof(int)); emitter.Branch(done); emitter.MarkLabel(valueNotNull); emitter.LoadLocal(value); emitter.Call(getHashCode); emitter.ReleaseTemp(value); emitter.MarkLabel(done); } else { emitter.Call(getHashCode); } } if (i > 0) emitter.Xor(); } emitter.Return(); typeBuilder.DefineMethodOverride( emitter.Method, typeof(IEqualityComparer<object>).GetMethod( "GetHashCode", new Type[] { typeof(object) })); } #endregion #endregion Type comparerType = typeBuilder.CreateType(); return (IComparer)Activator.CreateInstance(comparerType); }
public override void EmitMethod(MethodInfo methodInfo) { var emitter = new MethodEmitter(TypeBuilder, ImplField); emitter.Emit(methodInfo); }
public static IComparer Compile(AssemblyEmitter assembly, Type objectType, OrderInfo[] orders) { TypeBuilder typeBuilder = assembly.DefineType( "__sort", TypeAttributes.Public, typeof(object)); #region Constructor { ConstructorBuilder ctor = typeBuilder.DefineConstructor( MethodAttributes.Public, CallingConventions.Standard, Type.EmptyTypes); ILGenerator il = ctor.GetILGenerator(); // : base() il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Call, typeof(object).GetConstructor(Type.EmptyTypes)); // return; il.Emit(OpCodes.Ret); } #endregion #region IComparer typeBuilder.AddInterfaceImplementation(typeof(IComparer)); MethodBuilder compareMethod; #region Compare { MethodEmitter emitter = new MethodEmitter(typeBuilder); emitter.Define( /* name */ "Compare", /* attr */ MethodAttributes.Public | MethodAttributes.Virtual, /* return */ typeof(int), /* params */ new Type[] { typeof(object), typeof(object) }); LocalBuilder a = emitter.CreateLocal(objectType); LocalBuilder b = emitter.CreateLocal(objectType); LocalBuilder v = emitter.CreateLocal(typeof(int)); emitter.LoadArgument(1); emitter.CastAs(objectType); emitter.StoreLocal(a); emitter.LoadArgument(2); emitter.CastAs(objectType); emitter.StoreLocal(b); emitter.Load(0); emitter.StoreLocal(v); Label end = emitter.CreateLabel(); for (int i = 0; i < orders.Length; ++i) { if (i > 0) { emitter.LoadLocal(v); emitter.BranchIfTrue(end); // if ( v != 0 ) return v; } OrderInfo orderInfo = orders[i]; Property prop = orderInfo.Property; int sign = orderInfo.Sign; emitter.LoadLocal(a); emitter.Chain(prop); bool couldCompare = emitter.CompareTo(sign, delegate() { emitter.LoadLocal(b); emitter.Chain(prop); }); if (!couldCompare) throw new InvalidOperationException("Property is not comparable."); emitter.StoreLocal(v); } emitter.MarkLabel(end); emitter.LoadLocal(v); emitter.Return(); typeBuilder.DefineMethodOverride( emitter.Method, typeof(IComparer).GetMethod( "Compare", new Type[] { typeof(object), typeof(object) })); compareMethod = emitter.Method; } #endregion #endregion Type comparerType = typeBuilder.CreateType(); return (IComparer)Activator.CreateInstance(comparerType); }
public MethodInvocationExpression(Reference owner, MethodEmitter method, params Expression[] args) : this(owner, method.MethodBuilder, args) { }
public MethodInvocationExpression(MethodEmitter method, params Expression[] args) : this(SelfReference.Self, method.MethodBuilder, args) { }
public override void Compile( MethodEmitter emitter ) { bool inverse = false; string methodName; switch ( m_Operator ) { case StringOperator.Equal: methodName = "Equals"; break; case StringOperator.NotEqual: methodName = "Equals"; inverse = true; break; case StringOperator.Contains: methodName = "Contains"; break; case StringOperator.StartsWith: methodName = "StartsWith"; break; case StringOperator.EndsWith: methodName = "EndsWith"; break; default: throw new InvalidOperationException( "Invalid string comparison operator." ); } if ( m_IgnoreCase || methodName == "Equals" ) { Type type = ( m_IgnoreCase ? typeof( Insensitive ) : typeof( String ) ); emitter.BeginCall( type.GetMethod( methodName, BindingFlags.Public | BindingFlags.Static, null, new Type[] { typeof( string ), typeof( string ) }, null ) ); emitter.Chain( m_Property ); m_Value.Load( emitter ); emitter.FinishCall(); } else { Label notNull = emitter.CreateLabel(); Label moveOn = emitter.CreateLabel(); LocalBuilder temp = emitter.AcquireTemp( m_Property.Type ); emitter.Chain( m_Property ); emitter.StoreLocal( temp ); emitter.LoadLocal( temp ); emitter.BranchIfTrue( notNull ); emitter.Load( false ); emitter.Pop(); emitter.Branch( moveOn ); emitter.MarkLabel( notNull ); emitter.LoadLocal( temp ); emitter.BeginCall( typeof( string ).GetMethod( methodName, BindingFlags.Public | BindingFlags.Instance, null, new Type[] { typeof( string ) }, null ) ); m_Value.Load( emitter ); emitter.FinishCall(); emitter.MarkLabel( moveOn ); } if ( m_Not != inverse ) emitter.LogicalNot(); }
public override void Compile( MethodEmitter emitter ) { emitter.Chain( m_Property ); bool inverse = false; bool couldCompare = emitter.CompareTo( 1, delegate() { m_Value.Load( emitter ); } ); if ( couldCompare ) { emitter.Load( 0 ); switch ( m_Operator ) { case ComparisonOperator.Equal: emitter.Compare( OpCodes.Ceq ); break; case ComparisonOperator.NotEqual: emitter.Compare( OpCodes.Ceq ); inverse = true; break; case ComparisonOperator.Greater: emitter.Compare( OpCodes.Cgt ); break; case ComparisonOperator.GreaterEqual: emitter.Compare( OpCodes.Clt ); inverse = true; break; case ComparisonOperator.Lesser: emitter.Compare( OpCodes.Clt ); break; case ComparisonOperator.LesserEqual: emitter.Compare( OpCodes.Cgt ); inverse = true; break; default: throw new InvalidOperationException( "Invalid comparison operator." ); } } else { // This type is -not- comparable // We can only support == and != operations m_Value.Load( emitter ); switch ( m_Operator ) { case ComparisonOperator.Equal: emitter.Compare( OpCodes.Ceq ); break; case ComparisonOperator.NotEqual: emitter.Compare( OpCodes.Ceq ); inverse = true; break; case ComparisonOperator.Greater: case ComparisonOperator.GreaterEqual: case ComparisonOperator.Lesser: case ComparisonOperator.LesserEqual: throw new InvalidOperationException( "Property does not support relational comparisons." ); default: throw new InvalidOperationException( "Invalid operator." ); } } if ( m_Not != inverse ) emitter.LogicalNot(); }
public static IConditional Compile( AssemblyEmitter assembly, Type objectType, ICondition[] conditions, int index ) { TypeBuilder typeBuilder = assembly.DefineType( "__conditional" + index, TypeAttributes.Public, typeof( object ) ); #region Constructor { ConstructorBuilder ctor = typeBuilder.DefineConstructor( MethodAttributes.Public, CallingConventions.Standard, Type.EmptyTypes ); ILGenerator il = ctor.GetILGenerator(); // : base() il.Emit( OpCodes.Ldarg_0 ); il.Emit( OpCodes.Call, typeof( object ).GetConstructor( Type.EmptyTypes ) ); for ( int i = 0; i < conditions.Length; ++i ) conditions[i].Construct( typeBuilder, il, i ); // return; il.Emit( OpCodes.Ret ); } #endregion #region IComparer typeBuilder.AddInterfaceImplementation( typeof( IConditional ) ); MethodBuilder compareMethod; #region Compare { MethodEmitter emitter = new MethodEmitter( typeBuilder ); emitter.Define( /* name */ "Verify", /* attr */ MethodAttributes.Public | MethodAttributes.Virtual, /* return */ typeof( bool ), /* params */ new Type[] { typeof( object ) } ); LocalBuilder obj = emitter.CreateLocal( objectType ); LocalBuilder eq = emitter.CreateLocal( typeof( bool ) ); emitter.LoadArgument( 1 ); emitter.CastAs( objectType ); emitter.StoreLocal( obj ); Label done = emitter.CreateLabel(); for ( int i = 0; i < conditions.Length; ++i ) { if ( i > 0 ) { emitter.LoadLocal( eq ); emitter.BranchIfFalse( done ); } emitter.LoadLocal( obj ); conditions[i].Compile( emitter ); emitter.StoreLocal( eq ); } emitter.MarkLabel( done ); emitter.LoadLocal( eq ); emitter.Return(); typeBuilder.DefineMethodOverride( emitter.Method, typeof( IConditional ).GetMethod( "Verify", new Type[] { typeof( object ) } ) ); compareMethod = emitter.Method; } #endregion #endregion Type conditionalType = typeBuilder.CreateType(); return (IConditional) Activator.CreateInstance( conditionalType ); }