public void WriteCodeToOutput(CodeOutput bodySb, MethodInterpreter interpreter) { bodySb.Append("\n"); if (Returning == null) { bodySb.Append("return;"); } else { //Need to expand this for more cases if (Returning is ConstValue) { var retType = interpreter.Method.GetReturnType(); if (retType == typeof(string)) { bodySb.AppendFormat("return {0};", Returning.ComputedValue()); } else { bodySb.AppendFormat("return {0};", Returning.Name); } } else { bodySb.AppendFormat("return {0};", Returning.Name); } } }
public static string WritePlatformInvokeMethod(this PlatformInvokeMethod platformInvoke, ClosureEntities crRuntime) { var methodId = Import(platformInvoke.LibraryName, platformInvoke.MethodName, platformInvoke.CallingConvention, platformInvoke.EntryPoint); var codeOutput = new CodeOutput(); codeOutput.AppendFormat(platformInvoke.WritePInvokeDefinition(methodId)); codeOutput.BlankLine(); codeOutput.Append(platformInvoke.Method.WriteHeaderMethod(crRuntime, false)); // write PInvoke implementation codeOutput.BracketOpen(); var argumentsCall = platformInvoke.Method.GetParameters() .Select(CallMarshallerFactory.CreateMarshaller) .Each(marshaller => { codeOutput.Append(marshaller.GetTransformationCode()); }) .Once(marshallers => { codeOutput.BlankLine(); }) .Select(p => p.GetParameterString()) .Join(", "); if (!platformInvoke.Method.GetReturnType().IsVoid()) { codeOutput.Append("return "); } codeOutput.AppendFormat("{0}({1});", methodId, argumentsCall); codeOutput.BracketClose(); return(codeOutput.ToString()); }
static void WriteClosureBodies(List <MethodInterpreter> closure, CodeOutput sb, TypeDescriptionTable typeTable, ClosureEntities closureEntities) { sb.Append("///--- PInvoke code ---\n"); foreach (var interpreter in closure) { if (interpreter.Kind != MethodKind.PlatformInvoke) { continue; } sb.Append(MethodInterpreterCodeWriter.WritePInvokeMethodCode((PlatformInvokeMethod)interpreter, closureEntities)); } sb.Append("///---Begin closure code ---\n"); foreach (var interpreter in closure) { if (interpreter.Kind != MethodKind.CilInstructions) { continue; } if (interpreter.Method.IsAbstract) { continue; } sb.Append(MethodInterpreterCodeWriter.WriteMethodCode((CilMethodInterpreter)interpreter, typeTable, closureEntities)); } sb.Append("///---End closure code ---\n"); }
static void WriteStructWithFields(CodeOutput codeOutput, ClosureEntities crRuntime, Type type) { if (DelegateManager.IsTypeDelegate(type)) return; var mappedType = type.GetMappedType(crRuntime); type = mappedType.GetReversedMappedType(crRuntime); if (!type.IsValueType && type.BaseType != null) { //Not Necessary // codeOutput.AppendFormat("struct {0} : public {1} {2} {{", type.ToCppMangling(), type.BaseType.ToCppMangling(),type.GetInterfaces().Any()? " ,"+type.GetInterfaces().Select(j=>j.ToCppMangling()).Aggregate((a,b)=>a + " , " + b):""); codeOutput.AppendFormat( "struct {0} : public {1}", type.ToCppMangling(), type.BaseType.ToCppMangling()) .BracketOpen(); } else if (!type.IsValueType && type.IsInterface) { codeOutput.AppendFormat("struct {0} : public {1}", type.ToCppMangling(), typeof(object).ToCppMangling()) .BracketOpen(); } else { codeOutput.AppendFormat("struct {0}", type.ToCppMangling()) .BracketOpen(); } if (type == typeof(object)) { codeOutput.Append("int _typeId;\n"); } //String Support if (type == typeof(string)) { crRuntime.AddType(typeof(string)); var usedTypes = crRuntime.MappedTypes.Values.ToList(); var typeTable = new TypeDescriptionTable(usedTypes, crRuntime); codeOutput.Append("System_String()") .BracketOpen() .AppendFormat("_typeId = {0};\n", typeTable.GetTypeId(typeof(string))) .BracketClose() .BlankLine(); } WriteClassFieldsBody(codeOutput, mappedType, crRuntime); codeOutput.BracketClose(true) .Append(";\n") .BlankLine(); var typedesc = UsedTypeList.Set(type, crRuntime); typedesc.WriteStaticFieldInitialization(codeOutput); }
static void WriteClosureDelegateBodies(List <MethodInterpreter> closure, CodeOutput codeOutput) { foreach (var interpreter in closure) { if (interpreter.Kind != MethodKind.Delegate) { continue; } codeOutput.Append(MethodInterpreterCodeWriter.WriteDelegateCallCode(interpreter)); } codeOutput.Append(DelegateManager.Instance.BuildDelegateContent()); }
public static string LoadDllMethods() { var sb = new CodeOutput(); sb.BlankLine() .Append("System_Void mapLibs()") .BracketOpen(); var pos = 0; foreach (var library in LinkingData.Libraries) { sb.Append("//---------------------------------------------------------\n") .AppendFormat("// {0} methods\n", library.DllName) .Append("//---------------------------------------------------------\n") .AppendFormat("auto lib_{0} = LoadNativeLibrary(L\"{1}\");\n", pos, library.DllName) .BlankLine(); foreach (var method in library.Methods.Values) { sb.AppendFormat("{0} = ({0}_type)LoadNativeMethod(lib_{2}, \"{1}\");\n", method.FormattedName(), method.EntryPoint, pos); } pos++; } return(sb.BracketClose() .BlankLine() .ToString()); }
public static void WriteHeaderMethodWithEscaping(this MethodInterpreter interpreter, CodeOutput codeOutput, ClosureEntities closureEntities, bool writeEndColon = true) { var methodBase = interpreter.Method; codeOutput.Append(methodBase.GetReturnType().ToCppName()) .Append(" ") .Append(interpreter.ClangMethodSignature(closureEntities)); var arguments = interpreter.GetArgumentsAsTextWithEscaping(closureEntities); codeOutput.AppendFormat("({0})", arguments); if (writeEndColon) { codeOutput.Append(";"); } }
static void WriteClosureHeaders(IEnumerable <MethodInterpreter> closure, CodeOutput codeOutput, ClosureEntities closureEntities) { closure.Where(interpreter => !interpreter.Method.IsAbstract) .Each(interpreter => { MethodInterpreterCodeWriter.WriteMethodSignature(codeOutput, interpreter, closureEntities); codeOutput.Append("\n"); }); }
public static bool HandleCastRelatedOperations(TypeDescriptionTable typeTable, ClosureEntities crRuntime, LocalOperation operation, CodeOutput bodySb, OperationKind opKind) { switch (opKind) { case OperationKind.Box: if (!Boxing.IsUsed) { Boxing.IsUsed = true; bodySb.Append(BoxingTemplate); } HandleBox((Boxing)operation, bodySb, typeTable, crRuntime); break; case OperationKind.CastClass: HandleCastClass((ClassCasting)operation, bodySb, crRuntime); break; case OperationKind.Unbox: HandleUnbox((Unboxing)operation, bodySb, crRuntime); break; case OperationKind.IsInstance: { var declarations = new List <string> { "bool IsInstanceOf(int typeSource, int typeImplementation);", "System_Void buildTypesTable();", "std::map<int, std::vector<int> > GlobalMappingType;" }; bodySb.Append(Join(Environment.NewLine, declarations)); HandleIsInstance((IsInstance)operation, bodySb, crRuntime); } break; default: return(false); } return(true); }
static void WriteMainBody(MethodInterpreter interpreter, CodeOutput sb, ClosureEntities crRuntime) { sb.Append("System_Void initializeRuntime();\n"); sb.Append("int main(int argc, char**argv)").BracketOpen(); sb.Append("auto argsAsList = System_getArgumentsAsList(argc, argv);\n"); sb.Append("initializeRuntime();\n"); var entryPoint = interpreter.Method as MethodInfo; if (entryPoint.ReturnType != typeof(void)) { sb.Append("return "); } var parameterInfos = entryPoint.GetParameters(); var args = string.Empty; if (parameterInfos.Length != 0) { args = "argsAsList"; } sb.AppendFormat("{0}({1});\n", entryPoint.ClangMethodSignature(crRuntime), args); sb.BlankLine(); sb.Append("return 0;"); sb.BracketClose(); }
public void WriteLayout(CodeOutput codeOutput) { BaseType?.WriteLayout(codeOutput); var noOffsetFields = new List <FieldDescription>(); var dictionary = new SortedDictionary <int, List <FieldDescription> >(); BuildUnionLayouts(noOffsetFields, dictionary); foreach (var fieldList in dictionary.Values) { codeOutput.Append("union") .BracketOpen(); WriteFieldListToLayout(codeOutput, fieldList); codeOutput.BracketClose(); } WriteFieldListToLayout(codeOutput, noOffsetFields); }
public static void HandleCallInterface(LocalOperation operation, CodeOutput sbCode, MidRepresentationVariables vars, MethodInterpreter interpreter, ClosureEntities crRuntime) { var operationData = (CallMethodStatic)operation; var sb = new StringBuilder(); var methodInfo = operationData.Info.GetReversedMethod(crRuntime); var isVoidMethod = methodInfo.GetReturnType().IsVoid(); if (!isVoidMethod && operationData.Result != null) { sb.AppendFormat("{0} = ", operationData.Result.Name); } sb.AppendFormat("{0}_icall", methodInfo.ClangMethodSignature(crRuntime)); WriteParametersToSb(operationData, sb, interpreter); sbCode.Append(sb.ToString()); }
public static string WriteCode(CilMethodInterpreter interpreter, TypeDescriptionTable typeTable, ClosureEntities crRuntime) { var operations = interpreter.MidRepresentation.LocalOperations; var headerSb = new CodeOutput(); CppWriteSignature.WriteSignature(headerSb, interpreter, crRuntime); var bodySb = ComputeBodySb(operations, interpreter.MidRepresentation.Vars, typeTable, interpreter, crRuntime); var variablesSb = ComputeVariableSb(interpreter.MidRepresentation, interpreter, crRuntime); var finalSb = new CodeOutput(); finalSb.Append(headerSb.ToString()) .BracketOpen() .Append(variablesSb.ToString()) .Append(bodySb.ToString()) .BracketClose(); return(finalSb.ToString()); }
public string BuildStringTable() { var sb = new CodeOutput(); sb.BlankLine() .Append("System_Void buildStringTable()") .BracketOpen(); var stringDataBuilder = new List <string>(); var jump = 0; foreach (var strItem in _table) { sb.AppendFormat("_AddJumpAndLength({0}, {1});\n", jump, strItem.Length); var itemTextData = TextData(strItem); AddTextToStringTable(stringDataBuilder, itemTextData, strItem); jump += strItem.Length + 1; } sb.BracketClose(true) .Append(" // buildStringTable\n"); var stringTableContent = string.Join(", " + Environment.NewLine, stringDataBuilder); var length = jump == 0 ? 1 : jump; sb.BlankLine() .AppendFormat("const System_Char _stringTable[{0}] =", length) .BracketOpen(); sb.Append(jump == 0 ? "0" : stringTableContent); sb.BracketClose(true) .Append("; // _stringTable\n"); return(sb.ToString()); }
static CodeOutput ComputeBodySb(List <LocalOperation> operations, MidRepresentationVariables vars, TypeDescriptionTable typeTable, MethodInterpreter interpreter, ClosureEntities crRuntime) { var bodySb = new CodeOutput(); foreach (var operation in operations) { bodySb.Append("\n"); if (CppHandleOperators.HandleAssignmentOperations(bodySb, operation, operation.Kind, typeTable, interpreter, crRuntime)) { continue; } if (CppCastRelatedOperations.HandleCastRelatedOperations(typeTable, crRuntime, operation, bodySb, operation.Kind)) { continue; } if (HandleCallOperations(vars, interpreter, crRuntime, operation, bodySb)) { continue; } switch (operation.Kind) { case OperationKind.Label: WriteLabel(bodySb, ((Label)operation).JumpTo); break; case OperationKind.AlwaysBranch: HandleAlwaysBranchOperator(operation, bodySb); break; case OperationKind.BranchOperator: CppHandleBranches.HandleBranchOperator(operation, bodySb); break; case OperationKind.Return: CppHandleCalls.HandleReturn(operation, bodySb, interpreter); break; case OperationKind.CopyArrayInitializer: HandleCopyArrayInitializer(operation, bodySb); break; case OperationKind.Switch: HandleSwitch(operation, bodySb); break; case OperationKind.Comment: HandleComment(operation.ToString(), bodySb); break; default: throw new InvalidOperationException( $"Invalid operation '{operation.Kind}' is introduced in intermediary representation\nValue: {operation}"); } } return(bodySb); }
public static void HandleCallVirtual(LocalOperation operation, CodeOutput sbCode, MethodInterpreter interpreter, ClosureEntities crRuntime) { var operationData = (CallMethodStatic)operation; var sb = new StringBuilder(); var methodInfo = operationData.Info.GetReversedMethod(crRuntime); var isVoidMethod = methodInfo.GetReturnType().IsVoid(); if (!isVoidMethod && operationData.Result != null) { sb.AppendFormat("{0} = ", operationData.Result.Name); } var mappedType = methodInfo.DeclaringType.GetReversedMappedType(crRuntime); while ((mappedType.BaseType != typeof(object))) // Match top level virtual dispatch { if (mappedType.BaseType == null) { break; } mappedType = mappedType.BaseType; } sb.AppendFormat("{0}_vcall", methodInfo.ClangMethodSignature(crRuntime, mappedType)); //TODO: the intermediate representation should remove the testinf of final methods and such //the virtual call is always a virtual call //Added DevirtualizeFinalMethods //Virtual Method Dispatch Table is on base class only //Also we need to take care of the call if this is not a virtual call // C# compiler seems to use virtual calls when derived class uses new operator on non-virtual base class method //Added special case for interface calls /* * if (methodInfo.IsVirtual) * { * var @params = operationData.Parameters.Select(h => h.FixedType.ClrType).Skip(1).ToArray(); // Skip first parameter for virtual dispatch * * if ((methodInfo.DeclaringType.GetMethod(methodInfo.Name, @params) != null && methodInfo.DeclaringType.GetMethod(methodInfo.Name, @params).DeclaringType == methodInfo.DeclaringType)) * { * * sb.AppendFormat("{0}_vcall", methodInfo.ClangMethodSignature(crRuntime, isvirtualmethod: true)); * * } * else * { * sb.AppendFormat("{0}", methodInfo.DeclaringType.BaseType.GetMethod(methodInfo.Name, operationData.Parameters.Select(h => h.FixedType.ClrType).ToArray()).ClangMethodSignature(crRuntime, isvirtualmethod: false)); * } * } * else * { * sb.AppendFormat("{0}", methodInfo.ClangMethodSignature(crRuntime, isvirtualmethod: false)); * } */ WriteParametersToSb(operationData, sb, interpreter); sbCode.Append(sb.ToString()); }