Пример #1
0
        public void IdentifierExpression(CParser.IdentifierExpression IdentifierExpression)
        {
            var Variable = VariableScope.Find(IdentifierExpression.Identifier);
            var Function = FunctionScope.Find(IdentifierExpression.Identifier);

            if (Variable != null)
            {
                // For fixed array types, get always the address?
                if (Variable.CType is CArrayType && (Variable.CType as CArrayType).Size != 0)
                {
                    Variable.LoadAddress(SafeILGenerator);
                }
                else if (GenerateAddress)
                {
                    //Console.WriteLine(" Left");
                    Variable.LoadAddress(SafeILGenerator);
                }
                else
                {
                    //Console.WriteLine(" No Left");
                    Variable.Load(SafeILGenerator);
                }
            }
            else if (Function != null)
            {
                //SafeILGenerator.Push(Function.MethodInfo);
                SafeILGenerator.LoadFunctionPointer(Function.MethodInfo, false);
                SafeILGenerator.ConvertTo(typeof(void *));
            }
            else
            {
                throw (new Exception(string.Format("Not variable or function for identifier {0}", IdentifierExpression)));
            }
        }
Пример #2
0
        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());
            }
        }