Ejemplo n.º 1
0
        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.");
            }
        }
Ejemplo n.º 3
0
        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);
		}
Ejemplo n.º 5
0
		/// <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);
		}
Ejemplo n.º 7
0
 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);
			}
		}
Ejemplo n.º 9
0
 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);
     }
 }
Ejemplo n.º 11
0
        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);
            }
        }
Ejemplo n.º 12
0
        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);
        }
Ejemplo n.º 13
0
 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);
     }
 }
Ejemplo n.º 14
0
        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.");
            }
        }
Ejemplo n.º 15
0
		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);
		}
Ejemplo n.º 17
0
        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);
        }
Ejemplo n.º 21
0
        /// <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);
            }
        }
Ejemplo n.º 22
0
 public override void OutputIL(NitroIL into)
 {
     if (FromType == null)
     {
         FromType = ToBox.OutputType(out ToBox);
     }
     ToBox.OutputIL(into);
     into.Emit(OpCodes.Box, FromType);
 }
Ejemplo n.º 23
0
 /// <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);
 }
Ejemplo n.º 24
0
        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);
        }
Ejemplo n.º 25
0
		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);
		}
Ejemplo n.º 27
0
        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);
        }
Ejemplo n.º 28
0
 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);
		}
Ejemplo n.º 32
0
		/// <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.");
			}
			
		}
Ejemplo n.º 34
0
 public override void OutputIL(NitroIL into)
 {
     Input0.OutputIL(into);
     Input1.OutputIL(into);
     into.Emit(OpCodes.Rem);
 }
Ejemplo n.º 35
0
 /// <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);
		}
Ejemplo n.º 42
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);
            }
        }
Ejemplo n.º 43
0
        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();
        }
Ejemplo n.º 44
0
 /// <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);
			}
		}
Ejemplo n.º 46
0
		/// <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);
			}
		}
Ejemplo n.º 48
0
 /// <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);
		}
Ejemplo n.º 50
0
		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();
		}
Ejemplo n.º 51
0
		public override void OutputSet(NitroIL into,Type setting){
			into.Emit(OpCodes.Starg,Builder.Position);
		}