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