/// <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) { 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); } }