Example #1
0
        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);
        }
Example #2
0
        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);
        }
Example #3
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)
        {
            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}");
        }
Example #4
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}");
            }
        }