ilcclib.Converter.CIL.CILConverter.FunctionCallExpression C# (CSharp) Method

FunctionCallExpression() private method

private FunctionCallExpression ( CParser FunctionCallExpression ) : void
FunctionCallExpression CParser
return void
        public void FunctionCallExpression(CParser.FunctionCallExpression FunctionCallExpression)
        {
            var Function = FunctionCallExpression.Function;
            if (Function is CParser.IdentifierExpression)
            {
                var IdentifierExpression = Function as CParser.IdentifierExpression;
                var FunctionName = IdentifierExpression.Identifier;
                var ParametersExpressions = FunctionCallExpression.Parameters.Expressions;

                // Special functions.
                switch (FunctionName)
                {
                    // Alloca Special Function.
                    case "alloca":
                        {
            #if true
                            // alloca requires the stack to be empty after calling it?
                            var Stack = SafeILGenerator.StackSave();
                            var AllocaAddressLocal = SafeILGenerator.DeclareLocal(typeof(void*));
                            {
                                Traverse(ParametersExpressions);
                                SafeILGenerator.StackAlloc();
                            }
                            SafeILGenerator.StoreLocal(AllocaAddressLocal);
                            SafeILGenerator.StackRestore(Stack);
                            SafeILGenerator.LoadLocal(AllocaAddressLocal);
            #else
                            var AllocaLocal = SafeILGenerator.DeclareLocal(typeof(void*), "AllocaLocal");
                            Traverse(FunctionCallExpression.Parameters.Expressions);
                            //SafeILGenerator.ConvertTo(typeof(void*));
                            SafeILGenerator.StackAlloc();
                            SafeILGenerator.ConvertTo(typeof(void*));
                            SafeILGenerator.StoreLocal(AllocaLocal);
                            SafeILGenerator.LoadLocal(AllocaLocal);
                            //throw(new NotImplementedException("Currently this does not work!"));
            #endif
                        }
                        break;

                    // Normal plain function.
                    default:
                        {
                            var VariableReference = VariableScope.Find(IdentifierExpression.Identifier);
                            var FunctionReference = FunctionScope.Find(IdentifierExpression.Identifier);

                            if (VariableReference != null)
                            {
                                var CFunctionType = VariableReference.CType.GetSpecifiedCType<CFunctionType>();
                                var ReturnType = ConvertCTypeToType(CFunctionType.Return);
                                var ParameterTypes = CFunctionType.Parameters.Select(Item => ConvertCTypeToType(Item.CType)).ToArray();

                                Traverse(ParametersExpressions);
                                Traverse(IdentifierExpression);
                                SafeILGenerator.CallManagedFunction(CallingConventions.Standard, ReturnType, ParameterTypes, null);
                            }
                            else if (FunctionReference != null)
                            {
                                Type[] ParameterTypes;

                                if (FunctionReference.SafeMethodTypeInfo == null)
                                {
                                    if (FunctionReference.MethodInfo.CallingConvention == CallingConventions.VarArgs)
                                    {
                                        ParameterTypes = FunctionCallExpression.Parameters.Expressions.Select(Expression => ConvertCTypeToType(Expression.GetCachedCType(this))).ToArray();
                                    }
                                    else
                                    {
                                        ParameterTypes = FunctionReference.MethodInfo.GetParameters().Select(Parameter => Parameter.ParameterType).ToArray();
                                    }
                                }
                                else
                                {
                                    ParameterTypes = FunctionReference.SafeMethodTypeInfo.Parameters;
                                }

                                if (ParameterTypes.Length != ParametersExpressions.Length)
                                {
                                    throw (new Exception(String.Format(
                                        "Function parameter count mismatch {0} != {1} calling function '{2}'",
                                        ParameterTypes.Length, ParametersExpressions.Length, FunctionName
                                    )));
                                }

                                ParameterTypes = ParameterTypes.Select(Item => GetRealType(Item)).ToArray();

                                for (int n = 0; n < ParametersExpressions.Length; n++)
                                {
                                    var Expression = ParametersExpressions[n];
                                    var ExpressionCType = Expression.GetCachedCType(this);
                                    var ExpressionType = ConvertCTypeToType(ExpressionCType);
                                    var ParameterType = GetRealType(ParameterTypes[n]);
                                    Traverse(Expression);

                                    // Expected a string. Convert it!
                                    if (ParameterType == typeof(string))
                                    {
                                        if (ExpressionType == typeof(sbyte*))
                                        {
                                            SafeILGenerator.ConvertTo(typeof(sbyte*));
                                            SafeILGenerator.Call((CLibUtils.PointerToStringDelegate)CLibUtils.GetStringFromPointer);
                                        }
                                        else
                                        {
                                            throw (new NotImplementedException(String.Format("Invalid string expression {0}", ExpressionType)));
                                        }
                                    }
                                    else
                                    {
                                        SafeILGenerator.ConvertTo(ParameterType);
                                    }
                                }

                                if (FunctionReference.SafeMethodTypeInfo == null && FunctionReference.MethodInfo.CallingConvention == CallingConventions.VarArgs)
                                {
                                    //SafeILGenerator.LoadFunctionPointer(FunctionReference.MethodInfo, IsVirtual: false);
                                    //SafeILGenerator.CallManagedFunction(CallingConventions.VarArgs, FunctionReference.MethodInfo.ReturnType, ParameterTypes, null);
                                    SafeILGenerator.Call(FunctionReference.MethodInfo, FunctionReference.SafeMethodTypeInfo, ParameterTypes);
                                }
                                else
                                {
                                    SafeILGenerator.Call(FunctionReference.MethodInfo, FunctionReference.SafeMethodTypeInfo);
                                }
                            }
                            else
                            {
                                throw (new Exception(String.Format("Unknown function '{0}'", IdentifierExpression.Identifier)));
                            }

                            //SafeILGenerator.__ILGenerator.Emit(OpCodes.Call
                            //throw (new NotImplementedException("Function: " + IdentifierExpression.Value));
                        }
                        break;
                }

            }
            else
            {
                throw (new NotImplementedException());
            }
        }