private static void InternalConvertFromPInvokeFunction( CodeTextWriter tw, IMethodInformation method, PInvokeInfo pinvokeInfo) { tw.WriteLine("///////////////////////////////////////"); tw.WriteLine("// [6] P/Invoke: {0}", method.FriendlyName); tw.SplitLine(); tw.WriteLine(method.CLanguageFunctionPrototype); tw.WriteLine("{"); using (var _ = tw.Shift()) { var arguments = string.Join( ", ", method.Parameters. Select(parameter => parameter.GetMarshaledInExpression())); if (method.ReturnType.IsVoidType) { tw.WriteLine("{0}({1});", pinvokeInfo.EntryPoint, arguments); } else { tw.WriteLine("return {0}({1});", pinvokeInfo.EntryPoint, arguments); } } tw.WriteLine("}"); tw.SplitLine(); }
public void WriteCodeComment(CodeTextWriter tw) { switch (mode) { case DebugInformationOptions.CommentOnly: if (canWriteSequencePoint && (debug != null)) { // Write debugging information (opcode and line information) tw.WriteLine( "/* {0,-40} : {1}({2}) */", ci, Path.GetFileName(debug.Path), debug.Line); canWriteSequencePoint = false; } else { // Write debugging information (only opcode information) tw.WriteLine( "/* {0} */", ci); } break; case DebugInformationOptions.Full: // (Full debug information write at the WriteInformationBeforeCode.) tw.WriteLine( "/* {0} */", ci); break; } }
private static void InternalConvertFromAbstractFunction( CodeTextWriter tw, IMethodInformation method) { tw.WriteLine("///////////////////////////////////////"); tw.WriteLine("// [5] Abstract: {0}", method.FriendlyName); tw.SplitLine(); tw.WriteLine(method.CLanguageFunctionPrototype); tw.WriteLine("{"); using (var _ = tw.Shift()) { tw.WriteLine( "// WARNING: Pure virtual function called."); tw.WriteLine( "// TODO: throw : assert(0);"); if (method.ReturnType.IsVoidType == false) { tw.WriteLine( "return ({0}){1};", method.ReturnType.CLanguageTypeName, method.ReturnType.IsNumericPrimitive ? "0" : "NULL"); } } tw.WriteLine("}"); tw.SplitLine(); }
public static void WriteBoxedValueType(CodeTextWriter Writer, TypeDefinition Type) { if (!Type.IsValueType) { return; } var solved = Type.InterfacesSolved(); string Interfaces = string.Join(',', solved.Select(a => $"public {a.InterfaceType.CXXTypeName()}")); // [H2004] Boxed ValueType if (Type.HasGenericParameters) { Writer.WriteLine($"template<{Type.CXXTemplateParam()}>"); } string classDef = $"struct {Type.CXXShortTypeName()}_V : public RTCLI::System::ValueType{(solved.Count == 0 ? "" : "," + Interfaces)}"; using (var classScope = new CXXScopeDisposer(Writer, classDef, true, $"// [H2004] Boxed ValueType {Type.CXXTypeName()}_V ", $"// [H2004] Exit Boxed ValueType {Type.CXXTypeName()}_V")) { Writer.unindent().WriteLine("public:").indent(); Writer.WriteLine($"using ValueType = {Type.CXXShortTypeName()};"); //Writer.WriteLine($"using ValueType = struct {type.CXXShortTypeName()};"); Writer.WriteLine($"{Type.CXXShortTypeName()} value;"); WriteMethodSignatures(Writer, Type, false); } }
private static void InternalConvertFromInternalCallFunction( CodeTextWriter tw, IMethodInformation method) { Debug.Assert(method.IsExtern); tw.WriteLine("///////////////////////////////////////"); tw.WriteLine( "// [6] {0}: {1}", (method.PInvokeInformation != null) ? "P/Invoke" : "IL2C/Invoke", method.FriendlyName); tw.SplitLine(); // P/Invoke linkage doesn't verify the C header declarations. // It will lookp up by the library symbol name. if (method.PInvokeInformation != null) { tw.WriteLine( "extern {0};", method.CLanguagePInvokePrototype); tw.SplitLine(); } if (method.IsPrivate) { tw.WriteLine("static inline {0}", method.CLanguageFunctionPrototype); } else { tw.WriteLine(method.CLanguageFunctionPrototype); } tw.WriteLine("{"); using (var _ = tw.Shift()) { var arguments = string.Join( ", ", method.Parameters.Select(GetMarshaledInExpression)); if (method.ReturnType.IsVoidType) { tw.WriteLine( "{0}({1});", method.CLanguageInteropName, arguments); } else { tw.WriteLine( "return {0}({1});", method.CLanguageInteropName, arguments); } } tw.WriteLine("}"); tw.SplitLine(); }
public static void WriteTypePreDefinitions( CodeTextWriter twHeader, ITypeInformation targetType, IReadOnlyDictionary <ITypeInformation, ITypeInformation[]> typesByDeclaring) { InternalWriteTypePreDefinitions(twHeader, targetType, typesByDeclaring); InternalWriteVTableTypePreDefinitions(twHeader, targetType, typesByDeclaring); }
public CXXScopeDisposer(CodeTextWriter parent, string Scope, bool bEndWithSemicolon = false) { this.parent = parent; this.EndWithSemicolon = bEndWithSemicolon; parent.WriteLine(Scope); parent.WriteLine("{"); parent.indent(); }
private static void InternalConvertSetupExecutionFrame( CodeTextWriter tw, IExtractContextHost extractContext, PreparedMethodInformation preparedMethod, ILocalVariableInformation[] objRefEntries, ILocalVariableInformation[] valueEntries, DebugInformationWriteController debugInformationController) { tw.WriteLine("//-------------------"); tw.WriteLine("// [3-5] Setup execution frame:"); tw.SplitLine(); // Important NULL assigner (p = NULL): // Because these variables are pointer (of object reference 'O' type). // So GC will traverse these variables just setup the stack frame. debugInformationController.WriteInformationBeforeCode(tw); tw.WriteLine( "{0}_EXECUTION_FRAME__ frame__ =", preparedMethod.Method.CLanguageFunctionName); using (var __ = tw.Shift()) { if (valueEntries.Length >= 1) { tw.WriteLine( "{{ NULL, {0}, {1}, {2} }};", objRefEntries.Length, valueEntries.Length, string.Join( ", ", objRefEntries.Select(___ => "NULL"). Concat(valueEntries. Select(valueEntry => string.Format( "il2c_typeof({0}), NULL", valueEntry.TargetType.MangledUniqueName))))); } else { // Make short initializer expression if value type not included, // maybe C compiler makes better code. tw.WriteLine( "{{ NULL, {0} }};", objRefEntries.Length); } } foreach (var valueEntry in valueEntries) { debugInformationController.WriteInformationBeforeCode(tw); tw.WriteLine( "frame__.{0}_value_ptr__ = &{0};", extractContext.GetSymbolName(valueEntry)); } debugInformationController.WriteInformationBeforeCode(tw); tw.WriteLine("il2c_link_execution_frame(&frame__);"); tw.SplitLine(); }
public static void IncludeUberHeaders(CodeTextWriter Writer, TypeDefinition Type) { Writer.WriteLine("// [S1000] Include Uber Headers."); Writer.WriteLine($"#include <{Type.CXXUberHeaderPath()}>"); foreach (var assemblyReference in Type.Module.AssemblyReferences) { Writer.WriteLine($"#include <{assemblyReference.CXXUberHeaderPath()}>"); } }
private static void EndMain(CodeTextWriter writer, TestRunnerGeneratorOptions options) { if (!String.IsNullOrEmpty(options.EndMarker)) { writer.WriteLine("Console.WriteLine(\"{0}\");", options.EndMarker); } EndMethod(writer); }
public void Dispose() { if (parent != null) { parent.unindent(); parent.WriteLine("}" + (EndWithSemicolon?";":"")); parent = null; } }
private static void InternalConvertExecutionFrame( CodeTextWriter tw, IExtractContextHost extractContext, PreparedMethodInformation preparedMethod, ILocalVariableInformation[] objRefEntries, ILocalVariableInformation[] valueEntries) { tw.WriteLine("//-------------------"); tw.WriteLine("// [3-7] Declare execution frame:"); tw.SplitLine(); tw.WriteLine( "typedef struct {0}_EXECUTION_FRAME_DECL", preparedMethod.Method.CLanguageFunctionName); tw.WriteLine("{"); using (var _ = tw.Shift()) { tw.WriteLine("const IL2C_EXECUTION_FRAME* pNext__;"); tw.WriteLine("const uint16_t objRefCount__;"); tw.WriteLine("const uint16_t valueCount__;"); if (objRefEntries.Length >= 1) { tw.WriteLine("//-------------------- objref"); foreach (var objRefEntry in objRefEntries) { tw.WriteLine( "{0} {1};", objRefEntry.TargetType.CLanguageTypeName, extractContext.GetSymbolName(objRefEntry)); } } if (valueEntries.Length >= 1) { tw.WriteLine("//-------------------- value type"); foreach (var valueEntry in valueEntries) { var name = extractContext.GetSymbolName(valueEntry); tw.WriteLine( "const IL2C_RUNTIME_TYPE {0}_type__;", name); tw.WriteLine( "const {0}* {1}_value_ptr__;", valueEntry.TargetType.CLanguageTypeName, name); } } } tw.WriteLine( "}} {0}_EXECUTION_FRAME__;", preparedMethod.Method.CLanguageFunctionName); tw.SplitLine(); }
public CXXTypeScope(CodeTextWriter parent, TypeDefinition type) : base(parent, type.IsValueType ? CXXHeaderRules.StructDeclaration(type) : // [C0001] type.IsInterface ? CXXHeaderRules.InterfaceDeclaration(type) : // [C0002] CXXHeaderRules.ClassDeclaration(type), //[C0003] true, $"// [H2000] TypeScope {type.CXXTypeName()} ", $"// [H2000] Exit TypeScope {type.CXXTypeName()}") { }
public static void WriteMethodSignatures(CodeTextWriter Writer, TypeDefinition Type, bool ValueType) { if (Type.Methods != null & Type.Methods.Count != 0) { Writer.WriteLine("// [H2001] Method Signatures"); List <MethodDefinition> overrided = new List <MethodDefinition>(); foreach (var method in Type.Methods) { if (!ValueType && method.HasOverrides && method.IsVirtual) { foreach (var od in method.Overrides) { var odd = od.Resolve(); overrided.Add(odd); Writer.WriteLine($"{odd.CXXMethodSignature()} override{CondStr(method.IsAbstract, "= 0")}{CondStr(method.IsFinal, " final")};"); } } else if (!ValueType && method.IsVirtual) { if (method.IsNewSlot) { Writer.WriteLine($"virtual {method.CXXMethodSignature()}{CondStr(method.IsAbstract, " = 0")}{CondStr(method.IsFinal, " final")};"); } #if ENABLE_EXPLICT_OVERIDE if (!Type.IsInterface && !method.IsAbstract) { Writer.WriteLine($"{method.CXXRetType()} {method.CXXRowName()}_Impl{method.CXXParamSequence(true)};"); foreach (var i in Type.Interfaces) { var itype = i.InterfaceType.Resolve(); foreach (var mtdd in itype.Methods) { if (mtdd.Name == method.Name && !overrided.Contains(mtdd)) { Writer.WriteLine($"virtual {mtdd.CXXMethodSignature()}{CondStr(method.IsAbstract, " = 0")}{CondStr(method.IsFinal, " final")};"); } } } } #endif } else { if (method.HasGenericParameters) { Writer.WriteLine($"template<{method.CXXTemplateParam()}>"); } Writer.WriteLine($"{method.CXXMethodSignature()};"); } } Writer.WriteLine(); } }
public void WriteInformationBeforeCode(CodeTextWriter tw) { if ((mode == DebugInformationOptions.Full) && (debug != null)) { tw.WriteLineIgnoreIndent( "#line {0} \"{1}\"", debug.Line, debug.Path.Replace("\\", "\\\\")); } canWriteSequencePoint = true; }
public static void WriteStaticFieldImplementation(CodeTextWriter Writer, TypeDefinition Type) { Writer.WriteLine("// [S2001] Static Field Implementation"); foreach (var Field in Type.Fields) { if (Field.IsStatic) { Writer.WriteLine($"{Field.FieldType.CXXTypeName()} " + $"{Type.CXXTypeName()}::{Utilities.GetCXXValidTokenString(Field.Name)};"); } } }
public static void WriteFieldDeclaration(CodeTextWriter Writer, TypeDefinition Type) { if (Type.Fields != null & Type.Fields.Count != 0) { Writer.WriteLine("// [H2005] Field Declarations"); foreach (var field in Type.Fields) { Writer.WriteLine(field.CXXFieldDeclaration()); } Writer.WriteLine(); } }
public ScopeNoUnusedWarning(CodeTextWriter writer) { Writer = writer; Writer.WriteLine(""); Writer.WriteLine("// [S0001] Close Unused-Label Warnings."); Writer.WriteLine($"#if defined(RTCLI_COMPILER_CLANG)"); Writer.WriteLine($"#pragma clang diagnostic push"); Writer.WriteLine($"#pragma clang diagnostic ignored \"-Wunused-label\""); Writer.WriteLine($"#elif defined(RTCLI_COMPILER_MSVC)"); Writer.WriteLine($"#pragma warning(push)"); Writer.WriteLine($"#pragma warning(disable: 4102)"); Writer.WriteLine($"#endif"); }
public void WriteResult(CodeTextStorage storage) { var assemblyInformation = translateContext.MetadataContext.Assemblies[translateContext.FocusedAssembly]; CodeTextWriter writer = storage.Wirter( assemblyInformation.IdentName + ".json" ); writer.WriteLine( JsonConvert.SerializeObject( translateContext.MetadataContext.Assemblies[translateContext.FocusedAssembly], Formatting.Indented) ); }
public CXXScopeDisposer(CodeTextWriter parent, string Scope, bool bEndWithSemicolon = false, string onEnter = null, string onExit = null) { this.parent = parent; this.EndWithSemicolon = bEndWithSemicolon; this.onExit = onExit; if (onEnter != null) { parent.WriteLine(onEnter); } parent.WriteLine(Scope); parent.WriteLine("{"); parent.indent(); }
public static void IncludeWeakReferences(CodeTextWriter Writer, TypeDefinition Type) { Writer.WriteLine("// [S1001] Include Uber Headers."); Writer.WriteLine($"#include <{Type.CXXHeaderPath()}>"); var rs = Type.WeakReferences(); foreach (var r in rs) { if (!r.IsImplementedByVM()) { Writer.WriteLine($"#include <{r.CXXHeaderPath()}>"); } } }
private static void BeginProgram(CodeTextWriter writer, IType testSuite) { writer.WriteLine("using System;"); //writer.WriteLine("using NUnit.Framework;"); if (!String.IsNullOrEmpty(testSuite.Namespace)) { writer.WriteLine("using {0};", testSuite.Namespace); } writer.WriteLine(); writer.WriteLine("class Program"); writer.WriteLine("{"); writer.Indent(); }
private static void InternalWriteVTableTypePreDefinitions( CodeTextWriter twHeader, ITypeInformation targetType, IReadOnlyDictionary <ITypeInformation, ITypeInformation[]> typesByDeclaring) { if (typesByDeclaring.TryGetValue(targetType, out var types)) { if (types.Length >= 1) { twHeader.WriteLine("////////////////////////////////////////////////////////////"); twHeader.WriteLine("// [2-1-2] VTable types:"); twHeader.SplitLine(); foreach (var type in types) { // The nested types have to declare before outer types. if (!type.Equals(targetType)) { InternalWriteVTableTypePreDefinitions( twHeader, type, typesByDeclaring); } // If virtual method collection doesn't contain newslot method at this declared type: if (!type.NewSlotMethods.Any(method => method.DeclaringType.Equals(type))) { twHeader.WriteLine( "typedef {0}_VTABLE_DECL__ {1}_VTABLE_DECL__;", type.BaseType.MangledUniqueName, type.MangledUniqueName); } // Require new vtable layout. else { // Important: The vtable structure definition marked for "const", // because these vtables place into the ".rdata" section or same location. // Many small system have very tiny space for RAM (writable memory), // IL2C has to efficient memory space, vtable can place into ROM location. twHeader.WriteLine( "typedef const struct {0}_VTABLE_DECL___ {0}_VTABLE_DECL__;", type.MangledUniqueName); } } twHeader.SplitLine(); } } }
public static void IncludeStrongReferences(CodeTextWriter Writer, TypeDefinition Type) { var StrongRefernces = Type.StrongRefernces(); if (StrongRefernces.Count != 0) { Writer.WriteLine("// [H1001] Strong Referenced Types Headers"); foreach (var R in StrongRefernces) { if (!R.IsImplementedByVM()) { Writer.WriteLine($"#include <{R.CXXHeaderPath()}>"); } } } }
private static void InternalWriteAssemblyReferences( CodeTextWriter tw, TranslateContext translateContext, IExtractContext extractContext, ITypeInformation declaringType) { foreach (var assembly in extractContext.EnumerateRegisteredTypesByDeclaringType(declaringType). Distinct(). OrderByDependant(declaringType.DeclaringModule.DeclaringAssembly). Select(type => type.DeclaringModule.DeclaringAssembly). Where(assembly => !assembly.Equals(translateContext.Assembly)). Distinct(). OrderBy(assembly => assembly.Name)) { tw.WriteLine("#include <{0}.h>", assembly.Name); } tw.SplitLine(); }
public static void WriteForwardDeclaration(CodeTextWriter Writer, TypeDefinition Type) { Writer.WriteLine("// [H0001] Forward Declaration"); var rs = Type.WeakReferences(); foreach (var r in rs) { if (r.HasGenericParameters || r.IsGenericInstance) { } else if (!r.IsImplementedByVM()) { Writer.WriteLine( $"namespace {r.CXXNamespace()} " + "{ " + $"struct {r.CXXShortTypeName()}; " + "}"); } } }
private static void InternalWriteHeader( CodeTextWriter twHeader, PreparedInformations prepared, ITypeInformation targetType, MemberScopes memberScope, IReadOnlyDictionary <ITypeInformation, ITypeInformation[]> typesByDeclaring) { if (typesByDeclaring.TryGetValue(targetType, out var types)) { foreach (var type in types) { // The nested types have to declare before outer types. if (!type.Equals(targetType)) { InternalWriteHeader( twHeader, prepared, type, memberScope, typesByDeclaring); } // Write value type and object reference type. TypeWriter.WriteTypeDefinitions( twHeader, type); // Write type members. TypeWriter.WriteMemberDefinitions( twHeader, type, field => true, method => // Except type initializer !(method.IsConstructor && method.IsStatic) && prepared.Functions.ContainsKey(method)); // TODO: The internal or private members can separate into the internal headers. //field => field.CLanguageMemberScope == memberScope, //method => (method.CLanguageMemberScope == memberScope) && prepared.Functions.ContainsKey(method)); } } }
private static void WriteRunnerCode(this IMethod test, CodeTextWriter writer, TestRunnerGeneratorOptions options) { if (options == null) { options = new TestRunnerGeneratorOptions { Protect = true } } ; var testSuite = test.DeclaringType; BeginProgram(writer, testSuite); BeginMain(writer); RunTest(writer, options, test); EndMain(writer, options); EndProgram(writer); }
private void WriteTypeRecursively(CodeTextWriter codeWriter, TypeDefinition type) { if (type.IsEnum) { CXXHeaderRules.WriteEnumType(codeWriter, type); return; } // [C0004] generic if (type.HasGenericParameters) { codeWriter.WriteLine(CXXHeaderRules.GenericDeclaration(type)); } // [H2000] Type Scope using (var typeScope = new CXXTypeScope(codeWriter, type)) { codeWriter.unindent().WriteLine("public:").indent(); foreach (var nested in type.NestedTypes) { // [H2002] Inner Types codeWriter.WriteLine($"// [H2002] Inner Types {nested.CXXShortTypeName()}"); WriteTypeRecursively(codeWriter, nested); } // [H2001] Method Signatures CXXHeaderRules.WriteMethodSignatures(codeWriter, type, type.IsValueType); // [H2005] Field Declaration CXXHeaderRules.WriteFieldDeclaration(codeWriter, type); } // [H2004] Boxed ValueType if (!type.IsValueType) { return; } CXXHeaderRules.WriteBoxedValueType(codeWriter, type); }
public static void WriteEnumType(CodeTextWriter Writer, TypeDefinition Type) { if (!Type.IsEnum) { return; } Writer.WriteLine($"using {Type.CXXShortTypeName()} = {Type.Fields.First().FieldType.CXXTypeName()};"); string classDef = $"struct {Type.CXXShortTypeName()}_V : public RTCLI::System::Enum"; using (var classScope = new CXXScopeDisposer(Writer, classDef, true, $"// [H2004] Boxed ValueType {Type.CXXTypeName()}_V ", $"// [H2004] Exit Boxed ValueType {Type.CXXTypeName()}_V")) { Writer.unindent().WriteLine("public:").indent(); Writer.WriteLine($"using ValueType = {Type.CXXShortTypeName()};"); //Writer.WriteLine($"using ValueType = struct {type.CXXShortTypeName()};"); Writer.WriteLine($"{Type.CXXShortTypeName()} value;"); foreach (var Field in Type.Fields.Skip(1)) { Writer.WriteLine($"static constexpr {Type.CXXShortTypeName()} {Field.Name} = {Field.Constant};"); } } }