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))); } }
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()); } }