private static string GetMarshaledInExpression(IParameterInformation parameter) { // TODO: UTF8 conversion // TODO: Apply MarshalAsAttribute if (parameter.TargetType.IsStringType) { return(string.Format("{0}->string_body__", parameter.ParameterName)); } return(parameter.ParameterName); }
public static string GetMarshaledInExpression(this IParameterInformation parameter) { if (parameter.TargetType.IsStringType) { return(string.Format("{0}->string_body__", parameter.ParameterName)); } if (parameter.TargetType.IsEnum) { return(string.Format( "({0}){1}", parameter.TargetType.Name, // Simple enum type name for use P/Invoke. parameter.ParameterName)); } return(parameter.ParameterName); }
private static (ITypeInformation type, ILocalVariableInformation variable, string format) GetArg0ParameterInformation( DecodeContext decodeContext, ref IMethodInformation method, IParameterInformation parameter0, ILocalVariableInformation arg0, ref ITypeInformation arg0ValueType, ref ILocalVariableInformation requiredBoxingAtArg0PointerVariable, ref ILocalVariableInformation requiredCastingAtArg0PointerVariable, ref bool isVirtualCall) { Debug.Assert(method.IsStatic || parameter0.TargetType.Equals(method.DeclaringType) || (parameter0.TargetType.IsByReference && parameter0.TargetType.ElementType.Equals(method.DeclaringType))); // Required boxing at the arg0 if (arg0ValueType != null) { if (!arg0.TargetType.IsByReference) { throw new InvalidProgramSequenceException( "Cannot apply constrained prefix, arg0 isn't byref: Location={0}, Arg0Type={1}", decodeContext.CurrentCode.RawLocation, arg0.TargetType.FriendlyName); } // VERY DIRTY: The arg0 (managed pointer) uses below. requiredBoxingAtArg0PointerVariable = arg0; // VERY DIRTY: Make the boxing expression below, // it's reserving for the boxed value symbol at the evaluation stack. var arg0BoxedSymbol = decodeContext.PushStack( new BoxedValueTypeInformation(arg0ValueType)); decodeContext.PopStack(); return(parameter0.TargetType, arg0BoxedSymbol, "{0}"); } // If it's virtual method else if (isVirtualCall) { // Invoke interface method with the inline boxed-type instance. // ex: ((IFoo)foo).Bar(...) // If not inlined (ex: bound to local variable), arg0 doesn't box type. Next to the else block. if (method.DeclaringType.IsInterface && arg0.TargetType.IsBoxedType) { // VERY DIRTY: The arg0 (boxed value) uses below. requiredCastingAtArg0PointerVariable = arg0; arg0ValueType = arg0.TargetType; // VERY DIRTY: Make the implicitly cast expression below, // it's reserving for the casted value symbol at the evaluation stack. var arg0CastedSymbol = decodeContext.PushStack(method.DeclaringType); decodeContext.PopStack(); return(parameter0.TargetType, arg0CastedSymbol, "il2c_adjusted_reference({0})"); } // Invoke interface method with the class-type instance and // IL2C detected here for can cast statically. else if (method.DeclaringType.IsInterface && arg0.TargetType.IsClass && method.DeclaringType.IsAssignableFrom(arg0.TargetType)) { // All declared methods from derived to base types. var allDeclaredMethods = arg0.TargetType.AllInheritedDeclaredMethods; var m = method; var implementationMethod = allDeclaredMethods.First( dm => MetadataUtilities.VirtualMethodSignatureComparer.Equals(dm, m)); Debug.Assert(implementationMethod.DeclaringType.IsAssignableFrom(arg0.TargetType)); // Drop virtual call and turn to the direct call (devirtualize) isVirtualCall = false; method = implementationMethod; return(arg0.TargetType, arg0, "il2c_adjusted_reference({0})"); } else if (!(parameter0.TargetType.IsClass && arg0.TargetType.IsClass && parameter0.TargetType.IsAssignableFrom(arg0.TargetType))) { // Include adjust offset expression return(parameter0.TargetType, arg0, "il2c_adjusted_reference({0})"); } } return(parameter0.TargetType, arg0, "{0}"); }
private static (ITypeInformation type, ILocalVariableInformation variable, string format) GetArg0ParameterInformation( DecodeContext decodeContext, ref IMethodInformation method, IParameterInformation parameter0, ILocalVariableInformation arg0, ref ITypeInformation arg0ValueType, ref ILocalVariableInformation requiredBoxingAtArg0PointerVariable, ref ILocalVariableInformation requiredCastingAtArg0PointerVariable, ref bool isVirtualCall) { // Required boxing at the arg0 if (arg0ValueType != null) { if (!arg0.TargetType.IsByReference) { throw new InvalidProgramSequenceException( "Cannot apply constrained prefix, arg0 isn't byref: Location={0}, Arg0Type={1}", decodeContext.CurrentCode.RawLocation, arg0.TargetType.FriendlyName); } // VERY DIRTY: The arg0 (managed pointer) uses below. requiredBoxingAtArg0PointerVariable = arg0; // VERY DIRTY: Make the boxing expression below, // it's reserving for the boxed value symbol at the evaluation stack. var arg0BoxedSymbol = decodeContext.PushStack( new BoxedValueTypeInformation(arg0ValueType)); decodeContext.PopStack(); return(parameter0.TargetType, arg0BoxedSymbol, "{0}"); } // If it's virtual method else if (isVirtualCall) { // Invoke interface method with the inline boxed-type instance. // ex: ((IFoo)foo).Bar(...) // If not inlined (ex: bound to local variable), arg0 doesn't box type. Next to the else block. if (method.DeclaringType.IsInterface && arg0.TargetType.IsBoxedType) { // VERY DIRTY: The arg0 (boxed value) uses below. requiredCastingAtArg0PointerVariable = arg0; arg0ValueType = arg0.TargetType; // VERY DIRTY: Make the implicitly cast expression below, // it's reserving for the casted value symbol at the evaluation stack. var arg0CastedSymbol = decodeContext.PushStack(method.DeclaringType); decodeContext.PopStack(); return(parameter0.TargetType, arg0CastedSymbol, "il2c_adjusted_reference({0})"); } else { // Include adjust offset expression return(parameter0.TargetType, arg0, "il2c_adjusted_reference({0})"); } } else { return(parameter0.TargetType, arg0, "{0}"); } }