public override void OutputIL(NitroIL into) { // Ensure our conditions output type is computed: OutputType(); Label End = into.DefineLabel(); Label Else = into.DefineLabel(); Conditions[0].OutputIL(into); into.Emit(OpCodes.Brfalse, Else); AllRoutesReturn = IfTrue.CompileBody(Method); into.Emit(OpCodes.Br, End); into.MarkLabel(Else); if (IfFalse != null) { bool returns = IfFalse.CompileBody(Method); AllRoutesReturn = (AllRoutesReturn && returns); } else { AllRoutesReturn = false; } into.MarkLabel(End); }
public void OutputSet(NitroIL into, Type setting) { if (Field != null) { if (IsStatic) { into.Emit(OpCodes.Stsfld, Field); } else { into.Emit(OpCodes.Stfld, Field); } } else if (Property != null) { bool useVirtual = !IsStatic && !Property.PropertyType.IsValueType; MethodInfo setMethod = Property.GetSetMethod(); if (setMethod == null) { Error(Name + " is a readonly property."); } into.Emit(useVirtual?OpCodes.Callvirt:OpCodes.Call, setMethod); } else { Error(Name + " is a function! Unable to set it's value."); } }
public override void OutputIL(NitroIL into) { into.Emit(OpCodes.Ldtoken, TypeObject); MethodInfo methodToCall = typeof(System.Type).GetMethod("GetTypeFromHandle"); into.Emit(OpCodes.Call, methodToCall); }
public override void OutputIL(NitroIL into){ Type methodType=Method.ReturnType(); if(Input0!=null){ Type type=Input0.OutputType(out Input0); if(type==null){ if(methodType.IsValueType){ // We're returning null and the method returns a value type - this isn't allowed. Error("Can't return null here as the output type of the method is a value type."); } }else if(!methodType.IsAssignableFrom(type)){ if(Types.IsVoid(methodType)){ Error("This method cannot return anything (it's got no return type)"); }else{ Error("Must return something of type "+methodType+" (the methods return type)"); } } Input0.OutputIL(into); }else if(!Types.IsVoid(methodType)){ Error("Must return a value of type "+methodType); } if(Method.ReturnBay!=null){ into.Emit(OpCodes.Stloc,Method.ReturnBay); } into.Emit(OpCodes.Br,Method.EndOfMethod); }
/// <summary>Outputs this variable into IL.</summary> /// <param name="into">The IL stream to output it into.</param> /// <param name="accessingMember">True if we are accessing a field/method of this variable.</param> public override void OutputIL(NitroIL into,bool accessingMember){ if(accessingMember&&ParameterType.IsValueType){ // Must load by reference. It's a value type and we want some property of it. into.Emit(OpCodes.Ldarga,Builder.Position); }else{ into.Emit(OpCodes.Ldarg,Builder.Position); } }
public override void OutputIL(NitroIL into){ Input0.OutputIL(into); Input1.OutputIL(into); into.Emit(OpCodes.Ceq); // Flip by comparing with 0: into.Emit(OpCodes.Ldc_I4_0); into.Emit(OpCodes.Ceq); }
public override void OutputIL(NitroIL into) { Input0.OutputIL(into); Input1.OutputIL(into); into.Emit(OpCodes.Clt); // Flip by comparing with 0: into.Emit(OpCodes.Ldc_I4_0); into.Emit(OpCodes.Ceq); }
public override void OutputIL(NitroIL into){ if(Input0==null){ Input1.OutputIL(into); into.Emit(OpCodes.Neg); }else{ Input0.OutputIL(into); Input1.OutputIL(into); into.Emit(OpCodes.Sub); } }
public void OutputSet(NitroIL into, Type setting) { if (ElementType.IsValueType) { into.Emit(OpCodes.Stelem, ElementType); } else { into.Emit(OpCodes.Stelem_Ref); } }
public override void OutputIL(NitroIL into) { OutputTarget(into); if (ElementType.IsValueType) { into.Emit(OpCodes.Ldelem, ElementType); } else { into.Emit(OpCodes.Ldelem_Ref); } }
public override void OutputIL(NitroIL into) { GetMethodInfo(); // First, the instance this method is on: bool useVirtual = (CalledOn != null); if (useVirtual) { Type type = CalledOn.OutputType(out CalledOn); CalledOn.OutputIL(into); if (type.IsValueType) { if (!CalledOn.EmitsAddress) { // Value must be set into a temporary local and reloaded (but as an address). // Future optimization may be to pool these. LocalBuilder builder = into.DeclareLocal(type); into.Emit(OpCodes.Stloc, builder); into.Emit(OpCodes.Ldloca, builder); } useVirtual = false; } } // Next, its arguments: if (Types.IsDynamic(MethodToCall)) { if (Arguments != null) { for (int i = 0; i < Arguments.Length; i++) { Arguments[i].OutputIL(into); } } } else { Types.OutputParameters(Arguments, Method, into, MethodToCall.GetParameters()); } // And emit the call: if (useVirtual) { into.Emit(OpCodes.Callvirt, MethodToCall); } else { into.Emit(OpCodes.Call, MethodToCall); } }
public override void OutputIL(NitroIL into) { // Two args for the create call: // - Note that the first is the scope/ variable set into.Emit(OpCodes.Ldnull); into.Emit(OpCodes.Ldftn, ToDelegate); // Get the constructor: ConstructorInfo ctr = DelegateType.GetConstructors()[0]; // Create the delegate: into.Emit(OpCodes.Newobj, ctr); }
public override void OutputIL(NitroIL into) { if (Input0 == null) { Input1.OutputIL(into); into.Emit(OpCodes.Neg); } else { Input0.OutputIL(into); Input1.OutputIL(into); into.Emit(OpCodes.Sub); } }
public void OutputSet(NitroIL into, Type setting) { if (Field != null) { if (IsStatic) { into.Emit(OpCodes.Stsfld, Field); } else { into.Emit(OpCodes.Stfld, Field); } } else if (Property != null) { bool useVirtual = !IsStatic && !Property.PropertyType.IsValueType; MethodInfo setMethod = Property.GetSetMethod(); if (setMethod == null) { Error(Name + " is a readonly property."); } into.Emit(useVirtual?OpCodes.Callvirt:OpCodes.Call, setMethod); } else if (Methods != null) { // Extension property (hopefully!). Look for a set method lookalike. // Get types: Type[] argTypes = new Type[] { OfType(), setting }; // Get the overload: MethodInfo setMethod = Types.GetOverload(Methods, argTypes); if (setMethod == null) { Error(Name + " is a 'readonly' extension property."); } // Call the set method: into.Emit(OpCodes.Call, setMethod); } else { Error(Name + " is a function! Unable to set it's value."); } }
public override void OutputIL(NitroIL into){ if(FromType==null){ FromType=ToBox.OutputType(out ToBox); } ToBox.OutputIL(into); into.Emit(OpCodes.Box,FromType); }
public override void OutputIL(NitroIL into){ if(Size!=null){ Size.OutputIL(into); }else{ into.Emit(OpCodes.Ldc_I4,DirectSize); } Type ElementType=ArrayType.GetElementType(); into.Emit(OpCodes.Newarr,ElementType); if(DefaultValues==null || DefaultValues.Length==0){ return; } LocalBuilder temp=into.DeclareLocal(ArrayType); into.Emit(OpCodes.Stloc,temp); // Emit a series of SET's into the array. for(int i=0;i<DefaultValues.Length;i++){ into.Emit(OpCodes.Ldloc,temp); into.Emit(OpCodes.Ldc_I4,i); DefaultValues[i].OutputIL(into); if(ElementType.IsValueType){ into.Emit(OpCodes.Stelem,ElementType); }else{ into.Emit(OpCodes.Stelem_Ref); } } into.Emit(OpCodes.Ldloc,temp); }
public override void OutputSet(NitroIL into, Type setting) { if (VariableType == null) { VariableType = setting; } else if (setting != VariableType && setting != null) { // Overwriting the variable with something of a different type. Create a new one. VariableType = setting; Builder = null; } if (VariableType == null) { VariableType = typeof(object); } if (Builder == null) { Builder = into.DeclareLocal(VariableType); } into.Emit(OpCodes.Stloc, Builder); }
public override void OutputSet(NitroIL into,Type setting){ if(VariableType==null){ VariableType=setting; }else if(setting!=VariableType){ // Overwriting the variable with something of a different type. Create a new one. VariableType=setting; Builder=null; } if(VariableType==null){ VariableType=typeof(object); } if(Builder==null){ Builder=into.DeclareLocal(VariableType); } into.Emit(OpCodes.Stloc,Builder); }
/// <summary>Outputs this variable into IL.</summary> /// <param name="into">The IL stream to output it into.</param> /// <param name="accessingMember">True if we are accessing a field/method of this variable.</param> public override void OutputIL(NitroIL into,bool accessingMember){ if(Builder==null){ // This variable hasn't been written to yet, so this is always like reading a null or zero. return; } if(accessingMember&&VariableType.IsValueType){ // Must load by reference. It's a value type and we want some property of it. into.Emit(OpCodes.Ldloca,Builder); }else{ into.Emit(OpCodes.Ldloc,Builder); } }
public override void OutputIL(NitroIL into) { // Get the input type: Type casting = ToCast.OutputType(out ToCast); // Special case - if the thing being casted is an object and // the thing we're casting to is a value type, we must unbox instead. if (ToType.IsValueType && casting == typeof(object)) { ToCast.OutputIL(into); into.Emit(OpCodes.Unbox_Any, ToType); return; } ToCast.OutputIL(into); into.Emit(OpCodes.Castclass, ToType); }
/// <summary>Outputs this variable into IL.</summary> /// <param name="into">The IL stream to output it into.</param> /// <param name="accessingMember">True if we are accessing a field/method of this variable.</param> public override void OutputIL(NitroIL into, bool accessingMember) { if (Builder == null) { // This variable hasn't been written to yet, so this is always like reading a null or zero. return; } if (accessingMember && VariableType.IsValueType) { // Must load by reference. It's a value type and we want some property of it. into.Emit(OpCodes.Ldloca, Builder); } else { into.Emit(OpCodes.Ldloc, Builder); } }
public override void OutputIL(NitroIL into) { if (FromType == null) { FromType = ToBox.OutputType(out ToBox); } ToBox.OutputIL(into); into.Emit(OpCodes.Box, FromType); }
/// <summary>Generates the IL of this operation into the given stream.</summary> /// <param name="into">The IL stream to output the IL into</param> public virtual void OutputIL(NitroIL into) { if (Value == null) { into.Emit(OpCodes.Ldnull); return; } // Output the variable that represents the result. Note: used by operations which are variables too. EmitValue(Value.GetType(), into); }
public override void OutputIL(NitroIL into) { // Get Input0 onto the stack: if (Input0 == null) { into.Emit(OpCodes.Ldnull, typeof(object)); } else { Input0.OutputIL(into); } // Run GetObjectType() method: #if NETFX_CORE MethodInfo getType = typeof(TypeofOperation).GetTypeInfo().GetMethod("GetObjectType"); #else MethodInfo getType = typeof(TypeofOperation).GetMethod("GetObjectType"); #endif // Call it: into.Emit(OpCodes.Call, getType); }
public override void OutputIL(NitroIL into){ // Ensure our conditions output type is computed: OutputType(); Label End=into.DefineLabel(); Label Else=into.DefineLabel(); Conditions[0].OutputIL(into); into.Emit(OpCodes.Brfalse,Else); AllRoutesReturn=IfTrue.CompileBody(Method); into.Emit(OpCodes.Br,End); into.MarkLabel(Else); if(IfFalse!=null){ bool returns=IfFalse.CompileBody(Method); AllRoutesReturn=(AllRoutesReturn&&returns); }else{ AllRoutesReturn=false; } into.MarkLabel(End); }
public override void OutputIL(NitroIL into){ if(Types.IsDynamic(Constructor)){ if(Parameters!=null){ for(int i=0;i<Parameters.Length;i++){ Parameters[i].OutputIL(into); } } }else{ Types.OutputParameters(Parameters,Method,into,Constructor.GetParameters()); } into.Emit(OpCodes.Newobj,Constructor); }
public override void OutputIL(NitroIL into) { Type methodType = Method.ReturnType(); if (Input0 != null) { Type type = Input0.OutputType(out Input0); if (type == null) { if (methodType.IsValueType) { // We're returning null and the method returns a value type - this isn't allowed. Error("Can't return null here as the output type of the method is a value type."); } } else if (!methodType.IsAssignableFrom(type)) { if (Types.IsVoid(methodType)) { Error("This method cannot return anything (it's got no return type)"); } else { Error("Must return something of type " + methodType + " (the methods return type)"); } } Input0.OutputIL(into); } else if (!Types.IsVoid(methodType)) { Error("Must return a value of type " + methodType); } if (Method.ReturnBay != null) { into.Emit(OpCodes.Stloc, Method.ReturnBay); } into.Emit(OpCodes.Br, Method.EndOfMethod); }
public override void OutputIL(NitroIL into) { if (Types.IsDynamic(Constructor)) { if (Parameters != null) { for (int i = 0; i < Parameters.Length; i++) { Parameters[i].OutputIL(into); } } } else { Types.OutputParameters(Parameters, Method, into, Constructor.GetParameters()); } into.Emit(OpCodes.Newobj, Constructor); }
public override void OutputIL(NitroIL into){ // Get Input0 onto the stack: if(Input0==null){ into.Emit(OpCodes.Ldnull,typeof(object)); }else{ Input0.OutputIL(into); } // Run GetObjectType() method: #if NETFX_CORE MethodInfo getType=typeof(TypeofOperation).GetTypeInfo().GetMethod("GetObjectType"); #else MethodInfo getType=typeof(TypeofOperation).GetMethod("GetObjectType"); #endif // Call it: into.Emit(OpCodes.Call,getType); }
public override void OutputIL(NitroIL into) { if (Size != null) { Size.OutputIL(into); } else { into.Emit(OpCodes.Ldc_I4, DirectSize); } Type ElementType = ArrayType.GetElementType(); into.Emit(OpCodes.Newarr, ElementType); if (DefaultValues == null || DefaultValues.Length == 0) { return; } LocalBuilder temp = into.DeclareLocal(ArrayType); into.Emit(OpCodes.Stloc, temp); // Emit a series of SET's into the array. for (int i = 0; i < DefaultValues.Length; i++) { into.Emit(OpCodes.Ldloc, temp); into.Emit(OpCodes.Ldc_I4, i); DefaultValues[i].OutputIL(into); if (ElementType.IsValueType) { into.Emit(OpCodes.Stelem, ElementType); } else { into.Emit(OpCodes.Stelem_Ref); } } into.Emit(OpCodes.Ldloc, temp); }
public override void OutputIL(NitroIL into){ Input0.OutputIL(into); Input1.OutputIL(into); into.Emit(OpCodes.Cgt); }
/// <summary>Emits a continue - a jump to the start of the loop.</summary> /// <param name="into">The IL code to emit the instruction into.</param> public void Continue(NitroIL into){ into.Emit(OpCodes.Br,ContinuePoint); }
public void OutputSet(NitroIL into,Type setting){ if(Field!=null){ if(IsStatic){ into.Emit(OpCodes.Stsfld,Field); }else{ into.Emit(OpCodes.Stfld,Field); } }else if(Property!=null){ bool useVirtual=!IsStatic && !Property.PropertyType.IsValueType; MethodInfo setMethod=Property.GetSetMethod(); if(setMethod==null){ Error(Name+" is a readonly property."); } into.Emit(useVirtual?OpCodes.Callvirt:OpCodes.Call,setMethod); }else{ Error(Name+" is a function! Unable to set it's value."); } }
public override void OutputIL(NitroIL into) { Input0.OutputIL(into); Input1.OutputIL(into); into.Emit(OpCodes.Rem); }
/// <summary>Emits a break - a jump to the end of the loop.</summary> /// <param name="into">The IL code to emit the instruction into.</param> public void Break(NitroIL into) { into.Emit(OpCodes.Br, End); }
public override void OutputIL(NitroIL into) { into.Emit(OpCodes.Ldarg_0); }
public void OutputSet(NitroIL into,Type setting){ if(ElementType.IsValueType){ into.Emit(OpCodes.Stelem,ElementType); }else{ into.Emit(OpCodes.Stelem_Ref); } }
/// <summary>Emits the Value held by this compiled fragment if possible.</summary> /// <param name="type">The type of the value (or one of the base types of the value).</param> /// <param name="into">The IL stream to output the IL into.</param> public void EmitValue(Type type,NitroIL into){ if(type==typeof(string)){ into.Emit(OpCodes.Ldstr,(string)Value); }else if(type==typeof(int)){ into.Emit(OpCodes.Ldc_I4,(int)Value); }else if(type==typeof(uint)){ into.Emit(OpCodes.Ldc_I4,(uint)Value); }else if(type==typeof(long)){ into.Emit(OpCodes.Ldc_I8,(long)Value); }else if(type==typeof(ulong)){ into.Emit(OpCodes.Ldc_I8,(ulong)Value); }else if(type==typeof(float)){ into.Emit(OpCodes.Ldc_R4,(float)Value); }else if(type==typeof(double)){ into.Emit(OpCodes.Ldc_R8,(double)Value); }else if(type==typeof(OpCode)){ into.Emit((OpCode)Value); }else if(type==typeof(bool)){ into.Emit(OpCodes.Ldc_I4,((bool)Value)?1:0); }else if(type==typeof(short)){ into.Emit(OpCodes.Ldc_I4,(short)Value); }else if(type==typeof(ushort)){ into.Emit(OpCodes.Ldc_I4,(ushort)Value); }else if(type==typeof(byte)){ into.Emit(OpCodes.Ldc_I4,(byte)Value); }else if(type==typeof(sbyte)){ into.Emit(OpCodes.Ldc_I4,(sbyte)Value); }else if(Types.IsSubclass(Value,typeof(Variable))){ // Is parent a type of methodoperation or propertyoperation? // If it is, IsMemberAccessor is true. ((Variable)Value).OutputIL(into, (ParentFragment!=null && ParentFragment.IsMemberAccessor()) ); }else{ Error("Didn't know how to output value "+Value+" (type is "+type+")"); } }
/// <summary>Generates the IL of this operation into the given stream.</summary> /// <param name="into">The IL stream to output the IL into</param> public virtual void OutputIL(NitroIL into){ if(Value==null){ into.Emit(OpCodes.Ldnull); return; } // Output the variable that represents the result. Note: used by operations which are variables too. EmitValue(Value.GetType(),into); }
public override void OutputIL(NitroIL into){ GetMethodInfo(); // First, the instance this method is on: bool useVirtual=(CalledOn!=null); if(useVirtual){ Type type=CalledOn.OutputType(out CalledOn); CalledOn.OutputIL(into); if(type.IsValueType){ if(!CalledOn.EmitsAddress){ // Value must be set into a temporary local and reloaded (but as an address). // Future optimization may be to pool these. LocalBuilder builder=into.DeclareLocal(type); into.Emit(OpCodes.Stloc,builder); into.Emit(OpCodes.Ldloca,builder); } useVirtual=false; } } // Next, its arguments: if(Types.IsDynamic(MethodToCall)){ if(Arguments!=null){ for(int i=0;i<Arguments.Length;i++){ Arguments[i].OutputIL(into); } } }else{ Types.OutputParameters(Arguments,Method,into,MethodToCall.GetParameters()); } // And emit the call: if(useVirtual){ into.Emit(OpCodes.Callvirt,MethodToCall); }else{ into.Emit(OpCodes.Call,MethodToCall); } }
public override void OutputIL(NitroIL into){ into.Emit(OpCodes.Ldarg_0); }
public override void OutputIL(NitroIL into) { if (!OutputTarget(into)) { return; } if (Field != null) { if (Field.IsLiteral) { // Special case - this field isn't actually a field at all! // Load it's literal value: object literalFieldValue = Field.GetValue(null); // Get ready to write out the literal value: CompiledFragment literalValue = new CompiledFragment(literalFieldValue); // It might even be from an enum - let's check: if (Field.FieldType.IsEnum) { // Ok great it's from an enum. What type is it? Type literalValueType = Enum.GetUnderlyingType(Field.FieldType); // Use that type to emit the value: literalValue.EmitValue(literalValueType, into); } else { literalValue.OutputIL(into); } } else if (ParentFragment != null && ParentFragment.IsMemberAccessor() && Field.FieldType.IsValueType) { // Are we followed by another PropertyOperation? // A following operation in this sitation ends up being the parent. // If we are, and we output a valuetype, Ldflda must be used. if (IsStatic) { into.Emit(OpCodes.Ldsflda, Field); } else { into.Emit(OpCodes.Ldflda, Field); } } else if (IsStatic) { into.Emit(OpCodes.Ldsfld, Field); } else { into.Emit(OpCodes.Ldfld, Field); } } else if (Property != null) { bool useVirtual = !IsStatic && !Property.PropertyType.IsValueType; into.Emit(useVirtual?OpCodes.Callvirt:OpCodes.Call, Property.GetGetMethod()); } else if (Methods != null) { // Extension property (hopefully!). Look for a get method lookalike. // Get types: Type[] argTypes = new Type[] { OfType() }; // Get the overload: MethodInfo getMethod = Types.GetOverload(Methods, argTypes); if (getMethod == null) { Error(Name + " is a 'write only' extension property."); } // Call the set method: into.Emit(OpCodes.Call, getMethod); } else { DynamicMethodCompiler.Compile(Method, Name, MethodReturnType, Of).OutputIL(into); } }
public override void OutputIL(NitroIL into) { // Emit any set operations before the block itself (e.g. i=0): for (int i = 0; i < Parameters.Length; i++) { CompiledFragment parameter = Parameters[i]; if (Types.IsTypeOf(parameter, typeof(SetOperation))) { // Make sure it isn't a self set - e.g. i++, i=i+10. SetOperation set = (SetOperation)parameter; if (!set.SelfReferencing()) { set.OutputIL(into); Parameters[i] = null; } else { set.Output = false; } } else { // Compute it's output type: // Note that this must NOT be done for the SET ops as it makes them think // We want to use their output, which isn't true! parameter.OutputType(out parameter); Parameters[i] = parameter; } } Label continuePoint = into.DefineLabel(); Label start = into.DefineLabel(); Label end = into.DefineLabel(); Method.AddBreakPoint(new BreakPoint(continuePoint, end)); into.MarkLabel(start); // Logical operations (e.g. i<10): for (int i = 0; i < Parameters.Length; i++) { CompiledFragment parameter = Parameters[i]; if (parameter == null) { continue; } if (Types.IsTypeOf(parameter, typeof(SetOperation))) { // Just checking for a logical operation will make an incremental (i++) operation think // It's being daisy chained. That's because its output type is checked for boolean in IsLogical. continue; } if (parameter.IsLogical()) { parameter.OutputIL(into); into.Emit(OpCodes.Brfalse, end); Parameters[i] = null; } } Body.CompileBody(Method); into.MarkLabel(continuePoint); // Increment/decrement ops (e.g. i++): for (int i = 0; i < Parameters.Length; i++) { CompiledFragment cfrag = Parameters[i]; if (cfrag == null) { continue; } cfrag.OutputIL(into); } into.Emit(OpCodes.Br, start); into.MarkLabel(end); Method.PopBreakPoint(); }
/// <summary>Emits the Value held by this compiled fragment if possible.</summary> /// <param name="type">The type of the value (or one of the base types of the value).</param> /// <param name="into">The IL stream to output the IL into.</param> public void EmitValue(Type type, NitroIL into) { if (type == typeof(string)) { into.Emit(OpCodes.Ldstr, (string)Value); } else if (type == typeof(int)) { into.Emit(OpCodes.Ldc_I4, (int)Value); } else if (type == typeof(uint)) { into.Emit(OpCodes.Ldc_I4, (uint)Value); } else if (type == typeof(long)) { into.Emit(OpCodes.Ldc_I8, (long)Value); } else if (type == typeof(ulong)) { into.Emit(OpCodes.Ldc_I8, (ulong)Value); } else if (type == typeof(float)) { into.Emit(OpCodes.Ldc_R4, (float)Value); } else if (type == typeof(double)) { into.Emit(OpCodes.Ldc_R8, (double)Value); } else if (type == typeof(OpCode)) { into.Emit((OpCode)Value); } else if (type == typeof(bool)) { into.Emit(OpCodes.Ldc_I4, ((bool)Value)?1:0); } else if (type == typeof(short)) { into.Emit(OpCodes.Ldc_I4, (short)Value); } else if (type == typeof(ushort)) { into.Emit(OpCodes.Ldc_I4, (ushort)Value); } else if (type == typeof(byte)) { into.Emit(OpCodes.Ldc_I4, (byte)Value); } else if (type == typeof(sbyte)) { into.Emit(OpCodes.Ldc_I4, (sbyte)Value); } else if (Types.IsSubclass(Value, typeof(Variable))) { // Is parent a type of methodoperation or propertyoperation? // If it is, IsMemberAccessor is true. ((Variable)Value).OutputIL(into, (ParentFragment != null && ParentFragment.IsMemberAccessor())); } else { Error("Didn't know how to output value " + Value + " (type is " + type + ")"); } }
public override void OutputIL(NitroIL into){ OutputTarget(into); if(ElementType.IsValueType){ into.Emit(OpCodes.Ldelem,ElementType); }else{ into.Emit(OpCodes.Ldelem_Ref); } }
/// <summary>Emits a break - a jump to the end of the loop.</summary> /// <param name="into">The IL code to emit the instruction into.</param> public void Break(NitroIL into){ into.Emit(OpCodes.Br,End); }
public override void OutputIL(NitroIL into){ OutputTarget(into); if(Field!=null){ if(Field.IsLiteral){ // Special case - this field isn't actually a field at all! // Load it's literal value: object literalFieldValue=Field.GetValue(null); // Get ready to write out the literal value: CompiledFragment literalValue=new CompiledFragment(literalFieldValue); // It might even be from an enum - let's check: if(Field.FieldType.IsEnum){ // Ok great it's from an enum. What type is it? Type literalValueType=Enum.GetUnderlyingType(Field.FieldType); // Use that type to emit the value: literalValue.EmitValue(literalValueType,into); }else{ literalValue.OutputIL(into); } }else if(ParentFragment!=null && ParentFragment.IsMemberAccessor() && Field.FieldType.IsValueType){ // Are we followed by another PropertyOperation? // A following operation in this sitation ends up being the parent. // If we are, and we output a valuetype, Ldflda must be used. if(IsStatic){ into.Emit(OpCodes.Ldsflda,Field); }else{ into.Emit(OpCodes.Ldflda,Field); } }else if(IsStatic){ into.Emit(OpCodes.Ldsfld,Field); }else{ into.Emit(OpCodes.Ldfld,Field); } }else if(Property!=null){ bool useVirtual=!IsStatic && !Property.PropertyType.IsValueType; into.Emit(useVirtual?OpCodes.Callvirt:OpCodes.Call,Property.GetGetMethod()); }else{ DynamicMethodCompiler.Compile(Method,Name,MethodReturnType,Of).OutputIL(into); } }
/// <summary>Emits a continue - a jump to the start of the loop.</summary> /// <param name="into">The IL code to emit the instruction into.</param> public void Continue(NitroIL into) { into.Emit(OpCodes.Br, ContinuePoint); }
public override void OutputIL(NitroIL into){ into.Emit(OpCodes.Ldtoken,TypeObject); MethodInfo methodToCall=typeof(System.Type).GetMethod("GetTypeFromHandle"); into.Emit(OpCodes.Call,methodToCall); }
public override void OutputIL(NitroIL into){ // Emit any set operations before the block itself (e.g. i=0): for(int i=0;i<Parameters.Length;i++){ CompiledFragment parameter=Parameters[i]; if(Types.IsTypeOf(parameter,typeof(SetOperation))){ // Make sure it isn't a self set - e.g. i++, i=i+10. SetOperation set=(SetOperation)parameter; if(!set.SelfReferencing()){ set.OutputIL(into); Parameters[i]=null; }else{ set.Output=false; } }else{ // Compute it's output type: // Note that this must NOT be done for the SET ops as it makes them think // We want to use their output, which isn't true! parameter.OutputType(out parameter); Parameters[i]=parameter; } } Label continuePoint=into.DefineLabel(); Label start=into.DefineLabel(); Label end=into.DefineLabel(); Method.AddBreakPoint(new BreakPoint(continuePoint,end)); into.MarkLabel(start); // Logical operations (e.g. i<10): for(int i=0;i<Parameters.Length;i++){ CompiledFragment parameter=Parameters[i]; if(parameter==null){ continue; } if(Types.IsTypeOf(parameter,typeof(SetOperation))){ // Just checking for a logical operation will make an incremental (i++) operation think // It's being daisy chained. That's because its output type is checked for boolean in IsLogical. continue; } if(parameter.IsLogical()){ parameter.OutputIL(into); into.Emit(OpCodes.Brfalse,end); Parameters[i]=null; } } Body.CompileBody(Method); into.MarkLabel(continuePoint); // Increment/decrement ops (e.g. i++): for(int i=0;i<Parameters.Length;i++){ CompiledFragment cfrag=Parameters[i]; if(cfrag==null){ continue; } cfrag.OutputIL(into); } into.Emit(OpCodes.Br,start); into.MarkLabel(end); Method.PopBreakPoint(); }
public override void OutputSet(NitroIL into,Type setting){ into.Emit(OpCodes.Starg,Builder.Position); }