public void BuildTypeMatchingTable(TypeDescriptionTable table, ClosureEntities closure, StringBuilder featureBuilder) { var sb = new StringBuilder(); sb.AppendLine("System_Void buildTypesTable() {"); if (TypesToCast.Count > 0) { AddAllTypes(sb, table, closure); } sb.AppendLine("}"); sb.AppendLine(@" bool IsInstanceOf(int typeSource, int typeImplementation); System_Void buildTypesTable(); std::map<int, std::vector<int> > GlobalMappingType; bool IsInstanceOf(int typeSource, int typeImplementation) { auto typeVector = GlobalMappingType[typeSource]; auto begin = typeVector.begin(); auto end = typeVector.end(); return std::find(begin, end, typeImplementation)!= end; } "); featureBuilder.AppendLine(sb.ToString()); }
private static void WriteClosureBodies(List <MethodInterpreter> closure, StringBuilder sb, TypeDescriptionTable typeTable, CrRuntimeLibrary crRuntime) { sb.AppendLine("///--- PInvoke code --- "); foreach (var interpreter in closure) { if (interpreter.Kind != MethodKind.PlatformInvoke) { continue; } sb.AppendLine(MethodInterpreterCodeWriter.WritePInvokeMethodCode(interpreter)); } sb.AppendLine("///---Begin closure code --- "); foreach (var interpreter in closure) { if (interpreter.Kind != MethodKind.Default) { continue; } if (interpreter.Method.IsAbstract) { continue; } sb.AppendLine(MethodInterpreterCodeWriter.WriteMethodCode(interpreter, typeTable, crRuntime)); } sb.AppendLine("///---End closure code --- "); }
private static void HandleNewObject(LocalOperation operation, StringBuilder bodySb, MidRepresentationVariables vars, TypeDescriptionTable typeTable, MethodInterpreter interpreter) { var value = (Assignment)operation.Value; var rightValue = (NewConstructedObject)value.Right; var localValue = rightValue.Info; var declaringType = localValue.DeclaringType; var cppName = declaringType.ToDeclaredVariableType(true, EscapingMode.Stack); var assignedData = interpreter.AnalyzeProperties.GetVariableData(value.AssignedTo); var isStack = assignedData == EscapingMode.Stack; if (isStack) { bodySb .AppendFormat("{1} {0};", value.AssignedTo.Name, cppName); } else { bodySb.AppendFormat("{0} = std::make_shared<{1}>();", value.AssignedTo.Name, cppName); } bodySb.AppendLine(); typeTable.SetIdOfInstance(bodySb, value.AssignedTo, declaringType, isStack); }
public ProgramClosure(MethodInfo entryMethod, CrRuntimeLibrary crRuntime) { var optimizationsTable = BuildProgramWideOptimizationsTable(); Runtime = crRuntime; Runtime.Closure = this; EntryInterpreter = entryMethod.Register(); ResultingInFunctionOptimizationPass.Runtime = Runtime; ResultingGlobalOptimizationPass.Runtime = Runtime; BuildMethodClosure(); MetaLinkerOptimizer.ApplyOptimizations(MethodClosure.Values.ToList()); if (optimizationsTable.Optimize(this)) { MetaLinkerOptimizer.ApplyOptimizations(MethodClosure.Values.ToList()); } //BuildMethodClosure(); AddAlwaysUsedType(typeof(object)); TypesClosureLinker.SortTypeClosure(UsedTypes, crRuntime); var typeTable = new TypeDescriptionTable(UsedTypes); _typeDictionary = typeTable.ExtractInformation(); BuildVirtualMethodTable(typeTable, MethodClosure); }
private static void HandleAssign(StringBuilder sb, LocalOperation operation, MidRepresentationVariables vars, TypeDescriptionTable typeTable, MethodInterpreter interpreter) { var assignment = (Assignment)operation.Value; if (assignment.Right is NewConstructedObject) { HandleNewObject(operation, sb, vars, typeTable, interpreter); return; } var assignedTo = assignment.AssignedTo; var localVariable = assignment.Right as LocalVariable; if (localVariable != null) { var leftVarType = assignment.AssignedTo.ComputedType(); var rightVarType = assignment.Right.ComputedType(); if (leftVarType != rightVarType) { if (rightVarType.ClrType.IsPointer) { sb.AppendFormat("{0} = *{1};", assignedTo, localVariable.Name); return; } } var assignedToData = interpreter.AnalyzeProperties.GetVariableData(assignedTo); var localVariableData = interpreter.AnalyzeProperties.GetVariableData(localVariable); var rightVar = localVariable; var description = assignedTo.ComputedType(); if (description.ClrTypeCode != TypeCode.Object || assignedToData == localVariableData) { sb.AppendFormat("{0} = {1};", assignedTo.Name, rightVar.Name); return; } switch (assignedToData) { case EscapingMode.Pointer: switch (localVariableData) { case EscapingMode.Stack: sb.AppendFormat("{0} = &{1};", assignedTo.Name, rightVar.Name); return; case EscapingMode.Smart: sb.AppendFormat("{0} = ({1}).get();", assignedTo.Name, rightVar.Name); return; } break; case EscapingMode.Smart: throw new InvalidDataException("Case not possible!"); } throw new InvalidDataException("Case not handled"); } else { sb.AppendFormat("{0} = {1};", assignedTo.Name, assignment.Right.ComputedValue()); } }
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"); }
private void AddAllTypes(StringBuilder sb, TypeDescriptionTable table, ClosureEntities closure) { foreach (var type in TypesToCast) { sb.AppendFormat("// Type of {0}", type.FullName) .AppendLine(); var typeIdBase = table.GetTypeId(type); sb.AppendFormat("std::vector<int> typeTable{0};", typeIdBase) .AppendLine(); var implementingTypes = type.ImplementorsOfT(closure); foreach (var implementingType in implementingTypes) { sb.AppendFormat("//Implementor {0}", implementingType.FullName) .AppendLine(); var typeIdImpl = table.GetTypeId(implementingType); sb .AppendFormat("typeTable{0}.push_back({1});", typeIdBase, typeIdImpl) .AppendLine(); } sb.AppendFormat("GlobalMappingType[{0}] = typeTable{0};", typeIdBase) .AppendLine(); } }
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); }
public StringBuilder BuildFullSourceCode() { var entryInterpreter = ResolveMethod(EntryPoint); List <Type> usedTypes = MappedTypes.Values.ToList(); var typeTable = new TypeDescriptionTable(usedTypes, this); return(CppCodeGenerator.GenerateSourceStringBuilder(entryInterpreter, typeTable, MethodImplementations.Values.ToList(), this)); }
private static void HandleBox(Boxing boxing, StringBuilder bodySb, TypeDescriptionTable typeTable, ClosureEntities closureEntities) { TypeDescription typeDescription = boxing.Right.ComputedType(); bodySb .AppendFormat("{0} = box_value<{2}>({1}, {3});", boxing.AssignedTo.Name, boxing.Right.Name, typeDescription.GetClrType(closureEntities).ToDeclaredVariableType(EscapingMode.Stack), typeTable.GetTypeId(typeDescription.GetClrType(closureEntities))); }
private void BuildVirtualMethodTable(TypeDescriptionTable typeTable, Dictionary <MethodInterpreterKey, MethodInterpreter> methodClosure) { _virtualMethodTable = new VirtualMethodTable(typeTable); foreach (var type in _typeDictionary.Keys) { var methods = type.GetMethods(); foreach (var method in methods) { _virtualMethodTable.RegisterMethod(method, methodClosure); } } }
public CodeOutput GenerateSourceCodeOutput( MethodInterpreter interpreter, TypeDescriptionTable table, List <MethodInterpreter> closure, ClosureEntities closureEntities) { var headerSb = _createCodeOutput(); headerSb.Append("#include \"sloth.h\"") .BlankLine(); if (!string.IsNullOrEmpty(TypeNamerUtils.SmartPtrHeader)) { headerSb .AppendFormat("#include {0}", TypeNamerUtils.SmartPtrHeader) .BlankLine(); } var initializersCodeOutput = _createCodeOutput(); TypeBodiesCodeGenerator.WriteClosureStructBodies(initializersCodeOutput, closureEntities); WriteClosureDelegateBodies(closure, initializersCodeOutput); WriteClosureHeaders(closure, initializersCodeOutput, closureEntities); initializersCodeOutput.BlankLine(); initializersCodeOutput.Append("#include \"runtime_base.hpp\""); initializersCodeOutput.BlankLine(); var bodySb = _createCodeOutput(); bodySb.Append(VirtualMethodTableCodeWriter.GenerateTypeTableCode(table, closureEntities)); // We need to use this type table to generate missing jumps for subclasses that dont override a base method WriteCppMethods(closure, bodySb, closureEntities); WriteClosureMethods(closure, bodySb, table, closureEntities); WriteMainBody(interpreter, bodySb, closureEntities); bodySb.Append(PlatformInvokeCodeWriter.LoadDllMethods()); bodySb.Append(ConstByteArrayList.BuildConstantTable()); LinkingData.Instance.IsInstTable.BuildTypeMatchingTable(table, closureEntities, initializersCodeOutput.StringBuilderOutput); bodySb.Append(LinkingData.Instance.Strings.BuildStringTable()); return(headerSb .Append(initializersCodeOutput.ToString()) .Append(bodySb.ToString())); }
public void GenerateInstructionCode(IsInstance isInstance, CodeOutput sb, ClosureEntities crRuntime) { AddToRuntime(crRuntime); //Needs improvement, how do i get the correct typeid at this point ? we cant just use zero :P //This is a stupid hack as usedtypes can probably change as closure is computed crRuntime.AddType(isInstance.CastTo); var usedTypes = crRuntime.MappedTypes.Values.ToList(); var typeTable = new TypeDescriptionTable(usedTypes, crRuntime); TypesToCast.Add(isInstance.CastTo); sb .AppendFormat("{0} = IsInstanceOf({1}, {2});", isInstance.AssignedTo.Name, typeTable.GetTypeId(isInstance.CastTo), isInstance.Right.Name + "->_typeId" ); }
public static string WriteCode(MethodInterpreter interpreter, TypeDescriptionTable typeTable, CrRuntimeLibrary crRuntime) { var operations = interpreter.MidRepresentation.LocalOperations; var headerSb = new StringBuilder(); var sb = CppWriteSignature.WriteSignature(interpreter, crRuntime); headerSb.AppendLine(sb.ToString()); headerSb.Append("{"); var bodySb = ComputeBodySb(operations, interpreter.MidRepresentation.Vars, typeTable, interpreter, crRuntime); var variablesSb = ComputeVariableSb(interpreter.MidRepresentation, interpreter); var finalSb = new StringBuilder(); finalSb.AppendLine(headerSb.ToString()); finalSb.AppendLine(variablesSb.ToString()); finalSb.AppendLine(bodySb.ToString()); return(finalSb.ToString()); }
private static void WriteStructWithFields(StringBuilder sb, 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 // sb.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):""); sb.AppendFormat("struct {0} : public {1} {{", type.ToCppMangling(), type.BaseType.ToCppMangling()); } else if (!type.IsValueType && type.IsInterface) { sb.AppendFormat("struct {0} : public {1} {{", type.ToCppMangling(), typeof(object).ToCppMangling()); } else { sb.AppendFormat("struct {0} {{", type.ToCppMangling()); } sb.AppendLine(); if (type == typeof(object)) { sb.AppendLine("int _typeId;"); } //String Support if (type == typeof(string)) { crRuntime.AddType(typeof(string)); List <Type> usedTypes = crRuntime.MappedTypes.Values.ToList(); var typeTable = new TypeDescriptionTable(usedTypes, crRuntime); sb.AppendLine(String.Format("System_String() {{_typeId = {0}; }}", typeTable.GetTypeId(typeof(string)))); } WriteClassFieldsBody(sb, mappedType, crRuntime); sb.AppendFormat("}};").AppendLine(); var typedesc = UsedTypeList.Set(type, crRuntime); typedesc.WriteStaticFieldInitialization(sb); }
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); }
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()); }
static void HandleNewObject(LocalOperation operation, CodeOutput bodySb, TypeDescriptionTable typeTable, MethodInterpreter interpreter, ClosureEntities crRuntime) { var value = (NewConstructedObject)operation; var rightValue = value; var localValue = rightValue.Info; var declaringType = localValue.DeclaringType; var targetType = declaringType.GetMappedType(crRuntime); var cppName = declaringType.ToDeclaredVariableType(EscapingMode.Stack); var assignedData = interpreter.AnalyzeProperties.GetVariableData(value.AssignedTo); var isStack = assignedData == EscapingMode.Stack; if (isStack) { bodySb .AppendFormat("{1} {0};", value.AssignedTo.Name, cppName); } else { bodySb.AppendFormat("{0} = std::make_shared<{1}>();", value.AssignedTo.Name, cppName); } typeTable.SetIdOfInstance(bodySb, value.AssignedTo, targetType, isStack); }
public static string WriteMethodCode(MethodInterpreter interpreter, TypeDescriptionTable typeTable, CrRuntimeLibrary crRuntime) { return(CppMethodCodeWriter.WriteCode(interpreter, typeTable, crRuntime)); }
private static void WriteClosureMethods(List <MethodInterpreter> closure, StringBuilder sb, TypeDescriptionTable typeTable, ClosureEntities closureEntities) { WriteClosureBodies(closure, sb, typeTable, closureEntities); }
public static StringBuilder GenerateSourceStringBuilder(MethodInterpreter interpreter, TypeDescriptionTable table, List <MethodInterpreter> closure, ClosureEntities closureEntities) { var headerSb = new StringBuilder(); headerSb.AppendLine("#include \"sloth.h\""); headerSb.AppendLine("#include <functional>"); var initializersSb = new StringBuilder(); TypeBodiesCodeGenerator.WriteClosureStructBodies(initializersSb, closureEntities); WriteClosureDelegateBodies(closure, initializersSb); WriteClosureHeaders(closure, initializersSb, closureEntities); initializersSb.AppendLine("#include \"runtime_base.hpp\""); var bodySb = new StringBuilder(); bodySb.AppendLine(VirtualMethodTableCodeWriter.GenerateTypeTableCode(table, closureEntities)); // We need to use this type table to generate missing jumps for subclasses that dont override a base method WriteCppMethods(closure, bodySb, closureEntities); WriteClosureMethods(closure, bodySb, table, closureEntities); WriteMainBody(interpreter, bodySb, closureEntities); bodySb.AppendLine(PlatformInvokeCodeWriter.LoadDllMethods()); bodySb.AppendLine(ConstByteArrayList.BuildConstantTable()); LinkingData.Instance.IsInstTable.BuildTypeMatchingTable(table, closureEntities); bodySb.AppendLine(LinkingData.Instance.Strings.BuildStringTable()); //Add Logic to Automatically include std class features that are needed ... if (closureEntities.Features.Count > 0) { foreach (var runtimeFeature in closureEntities.Features) { if (runtimeFeature.IsUsed) { if (runtimeFeature.Headers.Count > 0) { headerSb.AppendLine("//Headers For Feature: " + runtimeFeature.Name + "\n" + runtimeFeature.Headers.Select(g => "#include<" + g + ">").Aggregate((a, b) => a + "\n" + b) + "\n//End Of Headers For Feature: " + runtimeFeature.Name + "\n"); } if (runtimeFeature.Declarations.Count > 0) { initializersSb.AppendLine("//Initializers For: " + runtimeFeature.Name + "\n" + runtimeFeature.Declarations.Aggregate((a, b) => a + "\n" + b) + "\n//End OF Initializers For: " + runtimeFeature.Name + "\n"); } if (!String.IsNullOrEmpty(runtimeFeature.Functions)) { bodySb.AppendLine("//Functions For Feature: " + runtimeFeature.Name + "\n" + runtimeFeature.Functions + "\n//End Of Functions For Feature: " + runtimeFeature.Name + "\n"); } } } } return(headerSb.Append(initializersSb).Append(bodySb)); }
private static StringBuilder ComputeBodySb(List <LocalOperation> operations, MidRepresentationVariables vars, TypeDescriptionTable typeTable, MethodInterpreter interpreter, ClosureEntities crRuntime) { var bodySb = new StringBuilder(); foreach (var operation in operations) { if (CppHandleOperators.HandleAssignmentOperations(bodySb, operation, operation.Kind, typeTable, interpreter, crRuntime)) { bodySb.AppendLine(); 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.Call: CppHandleCalls.HandleCall(operation, bodySb, vars, interpreter, crRuntime); break; case OperationKind.CallInterface: CppHandleCalls.HandleCallInterface(operation, bodySb, vars, interpreter, crRuntime); break; case OperationKind.CallVirtual: CppHandleCalls.HandleCallVirtual(operation, bodySb, interpreter, crRuntime); break; case OperationKind.CallRuntime: CppHandleCalls.HandleCallRuntime(operation, bodySb, crRuntime); 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; case OperationKind.Box: var boxing = crRuntime.FindFeature("Boxing"); if (!boxing.IsUsed) { boxing.IsUsed = true; boxing.Declarations.Add(@"template<class T> struct BoxedT : public System_Object { T Data; }; template<class T> std::shared_ptr<System_Object> box_value(T value, int typeId){ auto result = std::make_shared<BoxedT< T > >(); result->_typeId = typeId; result->Data = value; return result; } template<class T> T unbox_value(std::shared_ptr<System_Object> value){ auto resultObject = value.get(); auto castedUnboxing = (BoxedT<T>*)resultObject; return castedUnboxing->Data; }"); } 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: HandleIsInstance((IsInstance)operation, bodySb, crRuntime); break; default: throw new InvalidOperationException( string.Format( "Invalid operation '{0}' is introduced in intermediary representation\nValue: {1}", operation.Kind, operation)); } bodySb.AppendLine(); } bodySb.AppendLine("}"); return(bodySb); }
public static string GenerateTypeTableCode(TypeDescriptionTable table, ClosureEntities crRuntime) { var sb = new StringBuilder(); sb.AppendLine("// --- Begin definition of virtual implementingMethod tables ---"); sb.AppendLine("System_Void setupTypeTable();") .AppendLine(); var vcalls = crRuntime.AbstractMethods; WriteForwardVcalls(crRuntime, vcalls, sb); foreach (var virtualMethod in vcalls) { var methodName = virtualMethod.ClangMethodSignature(crRuntime); var parametersString = GetParametersString(virtualMethod, crRuntime); sb.Append(virtualMethod.ReturnType.ToCppName(EscapingMode.Smart)); sb.Append(" "); sb.Append(methodName); sb.Append("_vcall("); sb.AppendFormat(parametersString); sb.AppendLine(") {"); sb.AppendLine("switch (_this->_typeId)").AppendLine("{"); var declaringType = virtualMethod.DeclaringType; var implementingTypes = declaringType.ImplementorsOfT(crRuntime);//.MappedTypes.Values); foreach (var implementingType in implementingTypes) { if (implementingType.GetReversedMappedType(crRuntime) != implementingType) { continue; } var implementingMethod = AddVirtualMethodImplementations.GetImplementingMethod(implementingType, virtualMethod); // if (implementingMethod == null) //We should call the next implementingMethod in line ... not ignore this object // continue; if (implementingMethod != null) { if (implementingMethod.GetMethodBody() == null) { continue; } var declaringTypeImplementation = implementingMethod.DeclaringType.GetReversedMappedType(crRuntime); var typeId = table.GetTypeId(declaringTypeImplementation); sb.AppendFormat("case {0}:", typeId).AppendLine(); var isVoid = virtualMethod.ReturnType == typeof(void); if (!isVoid) { sb.Append("return "); } var methodImpl = implementingMethod.ClangMethodSignature(crRuntime); var parametersCallString = GetCall(virtualMethod, implementingMethod, crRuntime); sb .AppendFormat("{0}(", methodImpl) .AppendFormat("{0});", parametersCallString) .AppendLine(); if (isVoid) { sb.Append("return;").AppendLine(); } } else { var typeId = table.GetTypeId(implementingType.GetReversedMappedType(crRuntime)); sb.AppendFormat("case {0}:", typeId).AppendLine(); var isVoid = virtualMethod.ReturnType == typeof(void); if (!isVoid) { sb.Append("return "); } var method = implementingType.GetMethod(virtualMethod.Name, virtualMethod.GetParameters().Select(j => j.ParameterType).ToArray()); var methodImpl = method.ClangMethodSignature(crRuntime); var parametersCallString = GetCall(virtualMethod, method, crRuntime); sb .AppendFormat("{0}(", methodImpl) .AppendFormat("{0});", parametersCallString) .AppendLine(); if (isVoid) { sb.Append("return;").AppendLine(); } } } sb.AppendLine("} //switch"); sb.AppendLine("}"); } return(sb.ToString()); }
public static string WriteMethodCode(CilMethodInterpreter interpreter, TypeDescriptionTable typeTable, ClosureEntities closureEntities) { return(CppMethodCodeWriter.WriteCode(interpreter, typeTable, closureEntities)); }
private static void WriteClosureMethods(List <MethodInterpreter> closure, StringBuilder sb, TypeDescriptionTable typeTable, CrRuntimeLibrary crRuntime) { WriteClosureBodies(closure, sb, typeTable, crRuntime); }
static void WriteClosureMethods(List <MethodInterpreter> closure, CodeOutput sb, TypeDescriptionTable typeTable, ClosureEntities closureEntities) { WriteClosureBodies(closure, sb, typeTable, closureEntities); }
public static bool HandleAssignmentOperations(StringBuilder bodySb, LocalOperation operation, OperationKind kind, TypeDescriptionTable typeTable, MethodInterpreter interpreter, ClosureEntities crRuntime) { switch (kind) { case OperationKind.Assignment: HandleAssign(bodySb, operation, interpreter, crRuntime); break; case OperationKind.BinaryOperator: HandleOperator(operation, bodySb, crRuntime); break; case OperationKind.UnaryOperator: HandleUnaryOperator((UnaryOperator)operation, bodySb); break; case OperationKind.SetField: HandleSetField(operation, bodySb, crRuntime); break; case OperationKind.GetField: HandleGetField(operation, bodySb, interpreter); break; case OperationKind.SetStaticField: HandleSetStaticField(operation, bodySb); break; case OperationKind.GetStaticField: HandleLoadStaticField(operation, bodySb, crRuntime); break; case OperationKind.GetArrayItem: HandleReadArrayItem(operation, bodySb, interpreter, crRuntime); break; case OperationKind.SetArrayItem: HandleSetArrayValue(operation, bodySb, interpreter); break; case OperationKind.NewObject: HandleNewObject(operation, bodySb, typeTable, interpreter, crRuntime); break; case OperationKind.NewArray: HandleNewArray(operation, bodySb, interpreter); break; case OperationKind.AddressOfArrayItem: HandleGetAddressOfArrayItem(operation, bodySb); break; case OperationKind.RefAssignment: HandleRefAssignment(operation, bodySb); break; case OperationKind.DerefAssignment: HandleDerefAssignment(operation, bodySb); break; case OperationKind.FieldRefAssignment: HandleFieldRefAssignment(operation, bodySb); break; case OperationKind.LoadFunction: HandleLoadFunction(operation, bodySb, crRuntime); break; case OperationKind.SizeOf: HandleSizeOf(operation, bodySb); break; default: return(false); } return(true); }
private static StringBuilder ComputeBodySb(List <LocalOperation> operations, MidRepresentationVariables vars, TypeDescriptionTable typeTable, MethodInterpreter interpreter, CrRuntimeLibrary crRuntime) { var bodySb = new StringBuilder(); foreach (var operation in operations) { if (CppHandleOperators.HandleAssignmentOperations(vars, bodySb, operation, operation.Kind, typeTable, interpreter)) { bodySb.AppendLine(); continue; } switch (operation.Kind) { case OperationKind.Label: WriteLabel(bodySb, (int)operation.Value); break; case OperationKind.AlwaysBranch: HandleAlwaysBranchOperator(operation, bodySb); break; case OperationKind.BranchOperator: CppHandleBranches.HandleBranchOperator(operation, bodySb); break; case OperationKind.Call: CppHandleCalls.HandleCall(operation, bodySb, vars, interpreter, crRuntime); break; case OperationKind.CallInterface: CppHandleCalls.HandleCallInterface(operation, bodySb, vars, interpreter, crRuntime); break; case OperationKind.CallVirtual: CppHandleCalls.HandleCallVirtual(operation, bodySb, vars, interpreter, crRuntime); break; case OperationKind.CallRuntime: CppHandleCalls.HandleCallRuntime(operation, bodySb); break; case OperationKind.Return: CppHandleCalls.HandleReturn(operation, bodySb); break; case OperationKind.CopyArrayInitializer: HandleCopyArrayInitializer(operation, bodySb); break; case OperationKind.Switch: HandleSwitch(operation, bodySb); break; case OperationKind.Comment: HandleComment(operation.Value.ToString(), bodySb); break; default: throw new InvalidOperationException( string.Format( "Invalid operation '{0}' is introduced in intermediary representation\nValue: {1}", operation.Kind, operation.Value)); } bodySb.AppendLine(); } bodySb.AppendLine("}"); return(bodySb); }
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); }