예제 #1
0
        /// <summary>
        /// Convert a nullable .GetValueOrDefault()
        /// </summary>
        private static void ConvertPrimitiveGetValueOrDefault(AstExpression node, XMethodReference ilMethod, XTypeReference type, AstExpression target, XModule data)
        {
            // Clear node
            var originalArgs = node.Arguments.ToList();
            var getValueRef = new XMethodReference.Simple("GetValue", false, ilMethod.ReturnType, ilMethod.DeclaringType, new[] { data.TypeSystem.Object, data.TypeSystem.Bool }, null);
            node.Operand = getValueRef;
            node.Arguments.Clear();
            node.InferredType = type;
            node.ExpectedType = type;

            AddLoadArgument(node, target, originalArgs[0]);
            node.Arguments.Add(new AstExpression(node.SourceLocation, AstCode.Ldc_I4, 1) { InferredType = data.TypeSystem.Bool });
        }
예제 #2
0
 /// <summary>
 /// Make a .NET method reference for the MonitorEnter/Exit instruction.
 /// </summary>
 private XMethodReference MonitorMethodReference(string methodName)
 {
     var declaringType = new XTypeReference.SimpleXTypeReference(module, "System.Threading", "Monitor", null, false, null);
     var methodRef = new XMethodReference.Simple(methodName, false, module.TypeSystem.Void, declaringType, new[] { module.TypeSystem.Object }, null);
     return methodRef;
 }
예제 #3
0
        /// <summary>
        /// Create the body of the valueOf(string) method.
        /// </summary>
        private AstBlock CreateValueOfBody(XSyntheticMethodDefinition method, XFieldDefinition enumInfoField, XTypeSystem typeSystem)
        {
            var internalEnumType = Compiler.GetDot42InternalType("Enum");
            var internalEnumInfoType = Compiler.GetDot42InternalType("EnumInfo");
            var parseMethod = new XMethodReference.Simple("Parse", true, internalEnumType, internalEnumInfoType,
                                                    XParameter.Create("value", typeSystem.String),
                                                    XParameter.Create("ignoreCase", typeSystem.Bool),
                                                    XParameter.Create("throwIfNotFound", typeSystem.Bool));

            var ast = AstBlock.CreateOptimizedForTarget(
               new AstExpression(AstNode.NoSource, AstCode.Ret, null,
                   new AstExpression(AstNode.NoSource, AstCode.SimpleCastclass, XType,
                            new AstExpression(AstNode.NoSource, AstCode.Call, parseMethod,
                               new AstExpression(AstNode.NoSource, AstCode.Ldsfld, enumInfoField),
                               new AstExpression(AstNode.NoSource, AstCode.Ldloc, method.AstParameters[0]),
                               new AstExpression(AstNode.NoSource, AstCode.Ldc_I4, 0),
                               new AstExpression(AstNode.NoSource, AstCode.Ldc_I4, 1)))));
            return ast;
        }
예제 #4
0
        /// <summary>
        /// Create the body of the class ctor.
        /// </summary>
        private AstBlock CreateClassCtorBody(bool isWide, XFieldDefinition enumInfoField, XFieldDefinition defaultField, XMethodReference enumInfoCtor, XTypeReference valueType, XTypeSystem typeSystem)
        {
            var internalEnumType = Compiler.GetDot42InternalType("Enum");
            var internalEnumInfoType = Compiler.GetDot42InternalType("EnumInfo");
            var valueToFieldMap = new Dictionary<object, XFieldDefinition>();
            var ldc = isWide ? AstCode.Ldc_I8 : AstCode.Ldc_I4;

            var ast = AstBlock.CreateOptimizedForTarget(
                // Instantiate enum info field
                new AstExpression(AstNode.NoSource, AstCode.Stsfld, enumInfoField,
                    new AstExpression(AstNode.NoSource, AstCode.Newobj, enumInfoCtor)));

            // Instantiate values for each field
            var ordinal = 0;
            foreach (var field in XType.Fields.Where(x => x.IsStatic && !(x is XSyntheticFieldDefinition)))
            {
                // Find dex field
                object value;
                if (!field.TryGetEnumValue(out value))
                    throw new CompilerException(string.Format("Cannot get enum value from field {0}", field.FullName));
                value = isWide ? (object)XConvert.ToLong(value) : (object)XConvert.ToInt(value);
                XFieldDefinition existingField;
                AstExpression valueExpr;
                if (valueToFieldMap.TryGetValue(value, out existingField))
                {
                    // Re-use instance of existing field
                    valueExpr = new AstExpression(AstNode.NoSource, AstCode.Ldsfld, existingField);
                }
                else
                {
                    // Record
                    valueToFieldMap[value] = field;

                    // Call ctor
                    valueExpr = new AstExpression(AstNode.NoSource, AstCode.Newobj, ctor,
                        new AstExpression(AstNode.NoSource, AstCode.Ldstr, field.Name),
                        new AstExpression(AstNode.NoSource, AstCode.Ldc_I4, ordinal),
                        new AstExpression(AstNode.NoSource, ldc, value));
                }

                // Initialize static field
                ast.Body.Add(new AstExpression(AstNode.NoSource, AstCode.Stsfld, field, valueExpr));

                // Add to info
                var addMethod = new XMethodReference.Simple("Add", true, typeSystem.Void, internalEnumInfoType,
                    XParameter.Create("value", valueType),
                    XParameter.Create("instance", internalEnumType));
                ast.Body.Add(new AstExpression(AstNode.NoSource, AstCode.Call, addMethod,
                    new AstExpression(AstNode.NoSource, AstCode.Ldsfld, enumInfoField),
                    new AstExpression(AstNode.NoSource, ldc, value),
                    new AstExpression(AstNode.NoSource, AstCode.Ldsfld, field)));

                // Increment ordinal
                ordinal++;
            }

            // Initialize default field
            var getValueMethod = new XMethodReference.Simple("GetValue", true, internalEnumType, internalEnumInfoType,
                XParameter.Create("value", valueType));
            ast.Body.Add(new AstExpression(AstNode.NoSource, AstCode.Stsfld, defaultField,
                new AstExpression(AstNode.NoSource, AstCode.SimpleCastclass, XType,
                    new AstExpression(AstNode.NoSource, AstCode.Call, getValueMethod,
                        new AstExpression(AstNode.NoSource, AstCode.Ldsfld, enumInfoField),
                        new AstExpression(AstNode.NoSource, ldc, 0)))));

            // Return
            ast.Body.Add(new AstExpression(AstNode.NoSource, AstCode.Ret, null));
            return ast;
        }
예제 #5
0
        /// <summary>
        /// Create the body of the values() method.
        /// </summary>
        private AstBlock CreateValuesBody(XFieldDefinition enumInfoField, XTypeSystem typeSystem)
        {
            
            var internalEnumInfoType = Compiler.GetDot42InternalType("EnumInfo");
            var valuesMethod = new XMethodReference.Simple("Values", true, typeSystem.Object, internalEnumInfoType);

            var ast = AstBlock.CreateOptimizedForTarget(
                new AstExpression(AstNode.NoSource, AstCode.Ret, null,
                    new AstExpression(AstNode.NoSource, AstCode.SimpleCastclass, new XArrayType(XType),
                        new AstExpression(AstNode.NoSource, AstCode.Call, valuesMethod,
                            new AstExpression(AstNode.NoSource, AstCode.Ldsfld, enumInfoField)))));
            return ast;
        }