Beispiel #1
0
        /// <summary>
        /// Gets the converted name of the given field.
        /// </summary>
        public static string GetConvertedName(XMethodReference method)
        {
            var name = method.Name;

            // Handle special names
            switch (name)
            {
            case ".ctor":
                return("<init>");

            case ".cctor":
                return("<clinit>");
            }

            // Handle properties in custom views.
            var methodDef = method.Resolve();

            if (methodDef.DeclaringType.HasCustomViewAttribute())
            {
                if (methodDef.IsSetter && name.StartsWith("set_"))
                {
                    name = "set" + name.Substring(4);
                }
                else if (methodDef.IsGetter && name.StartsWith("get_"))
                {
                    name = "get" + name.Substring(4);
                }
            }

            // Avoid special characters
            var originalName = name;

            name = name.Replace('<', '_');
            name = name.Replace('>', '_');
            name = name.Replace('.', '_');

            if (name != originalName)
            {
                // Add hash to ensure unique
                name = name + '_' + GetHashPostfix(originalName);
            }

            return(name);
        }
        void ProcessArgument(AstExpression callNode, XMethodReference methodRef, int argumentIndex, MethodSource currentMethod, XModule assembly)
        {
            var node = callNode.Arguments[argumentIndex];

            // Should we do something?
            switch (node.Code)
            {
            case AstCode.Ldloca:     // Parameter
            case AstCode.AddressOf:  // Local variable
            case AstCode.Ldflda:     // Instance field
            case AstCode.Ldsflda:    // Static field
            case AstCode.Ldelema:    // Array
                break;

            case AstCode.Ldloc:
                if (!node.MatchThis() || !currentMethod.IsDotNet)
                {
                    return;
                }
                break;

            default:
                return;
            }

            // Process argument
            var method         = methodRef.Resolve();
            var argIsThis      = !method.IsStatic && (argumentIndex == 0);
            var parameterIndex = method.IsStatic ? argumentIndex : argumentIndex - 1;
            var parameter      = argIsThis ? null : method.Parameters[parameterIndex];
            var argType        = argIsThis ? method.DeclaringType : parameter.ParameterType;
            //var argAttrs = argIsThis ? ParameterAttributes.None : parameter.Attributes;
            var argIsByRef         = argType.IsByReference;
            var argIsOut           = argIsThis ? false : argIsByRef && (parameter.Kind == XParameterKind.Output); // argIsByRef && argAttrs.HasFlag(ParameterAttributes.Out);
            var argIsGenByRefParam = argIsByRef && argType.ElementType.IsGenericParameter;

            switch (node.Code)
            {
            case AstCode.Ldloca:     // Parameter
            {
                var variable = ((AstVariable)node.Operand);
                if (variable.Type.IsPrimitive || argIsByRef)
                {
                    // Box first
                    var ldloc = new AstExpression(node.SourceLocation, AstCode.Ldloc, node.Operand)
                    {
                        InferredType = variable.Type
                    };
                    if (argIsByRef)
                    {
                        var stloc = new AstExpression(node.SourceLocation, AstCode.Stloc, node.Operand)
                        {
                            InferredType = variable.Type
                        };
                        stloc.Arguments.Add(GetValueOutOfByRefArray(node, variable.Type, argIsGenByRefParam, assembly));
                        ConvertToByRefArray(node, variable.Type, ldloc, stloc, argIsOut, argIsGenByRefParam, argType.ElementType, assembly);
                    }
                    else
                    {
                        ConvertToBox(node, variable.Type, ldloc);
                    }
                }
                else if (variable.Type.IsGenericParameter)
                {
                    // Convert to ldarg
                    var ldloc = new AstExpression(node.SourceLocation, AstCode.Ldloc, node.Operand)
                    {
                        InferredType = variable.Type
                    };
                    callNode.Arguments[argumentIndex] = ldloc;
                }
            }
            break;

            case AstCode.Ldloc:     // this
            {
                var variable = ((AstVariable)node.Operand);
                if (argIsThis && (variable.Type.IsByReference))
                {
                    node.SetType(variable.Type.ElementType);
                }
                else if (argIsByRef)
                {
                    var ldclone     = new AstExpression(node);
                    var stExpr      = new AstExpression(node.SourceLocation, AstCode.Nop, null);
                    var elementType = variable.Type;
                    if (elementType.IsByReference)
                    {
                        elementType = elementType.ElementType;
                    }
                    ConvertToByRefArray(node, elementType, ldclone, stExpr, argIsOut, argIsGenByRefParam, argType.ElementType, assembly);
                }
            }
            break;

            case AstCode.AddressOf:     // Local variable
            {
                var arg     = node.Arguments[0];
                var type    = arg.GetResultType();
                var typeDef = type.Resolve();
                if (typeDef.IsPrimitive)
                {
                    if (argIsByRef)
                    {
                        throw new CompilerException("Unsupported use of AddressOf by byref argument");
                    }
                    else
                    {
                        ConvertToBox(node, type, arg);
                    }
                }
            }
            break;

            case AstCode.Ldflda:     // Instance field
            case AstCode.Ldsflda:    // Static field
            {
                var fieldRef = (XFieldReference)node.Operand;
                var field    = fieldRef.Resolve();
                if (field.FieldType.IsPrimitive || argIsByRef)
                {
                    // Box first
                    var ldfldCode = (node.Code == AstCode.Ldflda) ? AstCode.Ldfld : AstCode.Ldsfld;
                    var ldfld     = new AstExpression(node.SourceLocation, ldfldCode, node.Operand)
                    {
                        InferredType = field.FieldType
                    };
                    ldfld.Arguments.AddRange(node.Arguments);
                    if (argIsByRef)
                    {
                        var stfldCode = (node.Code == AstCode.Ldflda) ? AstCode.Stfld : AstCode.Stsfld;
                        var stfld     = new AstExpression(node.SourceLocation, stfldCode, node.Operand)
                        {
                            InferredType = field.FieldType
                        };
                        stfld.Arguments.AddRange(node.Arguments);                                                          // instance
                        stfld.Arguments.Add(GetValueOutOfByRefArray(node, field.FieldType, argIsGenByRefParam, assembly)); // value
                        ConvertToByRefArray(node, field.FieldType, ldfld, stfld, argIsOut, argIsGenByRefParam, argType.ElementType, assembly);
                    }
                    else
                    {
                        ConvertToBox(node, field.FieldType, ldfld);
                    }
                }
            }
            break;

            case AstCode.Ldelema:     // Array element
            {
                var array     = node.Arguments[0];
                var arrayType = array.GetResultType();
                var type      = arrayType.ElementType;
                if (type.IsPrimitive || argIsByRef)
                {
                    // Box first
                    var ldElemCode = type.GetLdElemCode();
                    var ldelem     = new AstExpression(node.SourceLocation, ldElemCode, node.Operand)
                    {
                        InferredType = type
                    };
                    ldelem.Arguments.AddRange(node.Arguments);
                    if (argIsByRef)
                    {
                        var stelemCode = type.GetStElemCode();
                        var stelem     = new AstExpression(node.SourceLocation, stelemCode, node.Operand)
                        {
                            InferredType = type
                        };
                        stelem.Arguments.AddRange(node.Arguments);
                        stelem.Arguments.Add(GetValueOutOfByRefArray(node, type, argIsGenByRefParam, assembly));
                        ConvertToByRefArray(node, type, ldelem, stelem, argIsOut, argIsGenByRefParam, argType.ElementType, assembly);
                    }
                    else
                    {
                        ConvertToBox(node, type, ldelem);
                    }
                }
            }
            break;
            }
        }