コード例 #1
0
        public LayoutControlItem CreateGridListViewItem(ClassDesc subclass)
        {
            LayoutControlItem item            = new LayoutControlItem();
            BaseViewControl   baseViewControl = new BaseViewControl();

            baseViewControl.BindData(new DynamicObjectHelper(subclass));
            baseViewControl.HideFilter();
            baseViewControl.SimpleEditor();
            item.Control             = baseViewControl;
            item.TextVisible         = false;
            item.SizeConstraintsType = SizeConstraintsType.Custom;
            item.ControlMinSize      = new Size(0, 800);

            subclassviewList.Add(baseViewControl);

            return(item);
        }
コード例 #2
0
        public static string GetClass(string _assembly, string _namespace, string name, bool il2cpp)
        {
            GetAssembly(_assembly, il2cpp);
            var desc = new ClassDesc()
            {
                Assembly = _assembly, Namespace = _namespace, Name = name
            };

            if (il2cpp)
            {
                I2ClassSet.Add(desc);
            }
            else
            {
                MonoClassSet.Add(desc);
            }
            return(GetClassDefine(desc, il2cpp));
        }
コード例 #3
0
ファイル: Program.cs プロジェクト: z77ma/runtime
        static void EmitClass(TextWriter tw, ClassDesc clz)
        {
            string genericParamString = "";

            if (clz.GenericParams != null)
            {
                genericParamString = $"<{clz.GenericParams}>";
            }
            tw.WriteLine($".class {clz.ClassFlags} {clz.Name}{genericParamString}");
            if (clz.BaseType != null)
            {
                tw.WriteLine($"       extends {clz.BaseType}");
            }

            if (clz.InterfacesImplemented != null)
            {
                bool first = true;
                foreach (string iface in clz.InterfacesImplemented)
                {
                    if (first)
                    {
                        first = false;
                        tw.Write("       implements ");
                    }
                    else
                    {
                        tw.Write("," + Environment.NewLine + "                  ");
                    }
                    tw.Write(iface);
                }

                if (first == true)
                {
                    throw new Exception();
                }
                tw.WriteLine("");
            }
            tw.WriteLine("{");
        }
コード例 #4
0
        private LayoutControlGroup CreateLayoutGroup(List <TableColumnDesc> column_list, List <TableColumnDisplay> display_list, List <TableColumnReference> reference_list, List <TableColumnRegular> rule_list)
        {
            string group_text     = String.Empty;
            string sub_group_text = String.Empty;

            TableColumnDisplay display = display_list.Find(obj => obj.Id == column_list[0].Id);

            if (display != null)
            {
                group_text     = display.Column_display_name;
                sub_group_text = display.Sub_group_display_name;
            }
            LayoutControlGroup grp = this.CreateLayoutGroup(sub_group_text == String.Empty?group_text:sub_group_text);

            foreach (TableColumnDesc col in column_list)
            {
                TableColumnDisplay   column_display   = display_list.Find(obj => obj.Id == col.Id);
                TableColumnReference column_reference = reference_list.Find(obj => obj.Id == col.Id);
                TableColumnRegular   column_rule      = rule_list.Find(obj => obj.Id == col.Id);

                string column_text      = column_display != null?column_display.Column_display_name:col.Column_name;
                string column_ref_value = GlobeData.tableColumnDescList.Find(obj => obj.Column_idx == column_reference.Reference_value_column_id).Column_name;
                string column_ref_text  = GlobeData.tableColumnDescList.Find(obj => obj.Column_idx == column_reference.Reference_text_column_id).Column_name;
                var    ref_data         = new object();

                LayoutControlItem itm = new LayoutControlItem();

                if (column_reference != null)
                {
                    ClassDesc tmp = GlobeData.classDescList.Find(obj => obj.Id == column_reference.Reference_id);

                    if (tmp != null)
                    {
                        object ref_class = GlobeData.assembly.CreateInstance(tmp.Class_name);
                        ref_data = ref_class.GetType().InvokeMember("GetDataList", BindingFlags.Default | BindingFlags.InvokeMethod, null, ref_class, null);
                    }
                }


                switch (col.Column_edit_type)
                {
                case ObjectEnum.ColumnEditType.Calc:
                    itm = this.CreateCalcItem(column_text, col.Column_name, 10, 8, col.Is_readonly); break;

                case ObjectEnum.ColumnEditType.Check:
                    itm = this.CreateCheckItem(column_text, col.Column_name, col.Is_readonly); break;

                case ObjectEnum.ColumnEditType.CheckedCombo:
                    itm = this.CreateCheckedComboItem(column_text, col.Column_name, column_rule != null ? column_rule.ItemList.Split(',').ToList(): new List <String>(), "(Select All)", ',', col.Is_readonly); break;

                case ObjectEnum.ColumnEditType.Combo:
                    itm = this.CreateComboItem(column_text, col.Column_name, ref_data, column_ref_text,
                                               column_ref_value,
                                               col.Is_readonly); break;

                case ObjectEnum.ColumnEditType.Date:
                    itm = this.CreateDateItem(column_text, col.Column_name, col.Is_readonly); break;

                case ObjectEnum.ColumnEditType.Grid: break;

                case ObjectEnum.ColumnEditType.LookUp:
                    itm = this.CreateSearchFindItem(column_text, col.Column_name,
                                                    ref_data,
                                                    column_ref_text,
                                                    column_ref_value,
                                                    col.Is_readonly); break;

                case ObjectEnum.ColumnEditType.Memo:
                    itm = this.CreateMemoItem(column_text, col.Column_name, column_rule != null ? column_rule.Max_length : 65535, col.Is_readonly); break;

                case ObjectEnum.ColumnEditType.Spin:
                    itm = this.CreateSpinItem(column_text, col.Column_name,
                                              column_rule != null ? column_rule.Max_value : int.MaxValue,
                                              column_rule != null ? column_rule.Min_value : int.MinValue,
                                              1, false, col.Is_readonly); break;

                case ObjectEnum.ColumnEditType.Text:
                    itm = this.CreateTextItem(column_text, col.Column_name, column_rule != null ? column_rule.Max_length : 65535,
                                              column_rule != null?column_rule.Mask_type:MaskType.None,
                                              column_rule != null?column_rule.Mask:String.Empty,
                                              col.Is_readonly); break;

                case ObjectEnum.ColumnEditType.Time:
                    itm = this.CreateTimeItem(column_text, col.Column_name, col.Is_readonly); break;

                case ObjectEnum.ColumnEditType.Toggle:
                    itm = this.CreateToggleSwitchItem(column_text, col.Column_name,
                                                      column_rule != null ? column_rule.Toggle_off_value : false,
                                                      column_rule != null ? column_rule.Toggle_on_value : true,
                                                      column_rule != null ? column_rule.Toggle_off_text : "Off",
                                                      column_rule != null ? column_rule.Toggle_on_text : "ON",
                                                      col.Is_readonly); break;
                }

                grp.AddItem(itm);
            }

            return(grp);
        }
コード例 #5
0
        public void CreateLayoutEditor(DynamicObjectHelper dynamicObject)
        {
            if (dynamicObject.classDesc == null)
            {
                return;
            }

            this.dynamicObject       = dynamicObject;
            bindingSource.DataSource = dynamicObject.objclass;

            int group_idx = 1;

            while (true)
            {
                List <TableColumnDesc> list = dynamicObject.ColumnList.FindAll(obj => obj.Group_idx == group_idx);

                if (list.Count > 0)
                {
                    string group_text = String.Empty;

                    TableColumnDisplay display = dynamicObject.ColumnLanguageDisplayList.Find(obj => obj.Id == list[0].Id);
                    if (display != null)
                    {
                        group_text = display.Column_display_name;
                    }
                    LayoutControlGroup grp = this.CreateLayoutGroup(group_text);

                    #region 子Group
                    (int min, int max)tuple = (list.Min(obj => obj.Sub_group_idx), list.Min(obj => obj.Sub_group_idx));

                    if (tuple.min > 0)
                    {
                        for (int k = tuple.min; k <= tuple.max; k++)
                        {
                            List <TableColumnDesc> sub_list = list.FindAll(obj => obj.Sub_group_idx == k);

                            grp.Add(this.CreateLayoutGroup(sub_list, dynamicObject.ColumnLanguageDisplayList, dynamicObject.ColumnReferenceList, dynamicObject.ColumnRegularList));
                        }
                    }
                    #endregion

                    #region 单个Group
                    else
                    {
                        grp = this.CreateLayoutGroup(list, dynamicObject.ColumnLanguageDisplayList, dynamicObject.ColumnReferenceList, dynamicObject.ColumnRegularList);
                    }
                    #endregion

                    this.layoutEdit.AddGroup(grp);
                }
                else
                {
                    break;
                }

                group_idx++;
            }

            List <ClassRelated> sub_class = GlobeData.classRelatedList.FindAll(obj => obj.Main_class_id == dynamicObject.classDesc.Id);
            foreach (ClassRelated sub in sub_class)
            {
                ClassDesc subclass = GlobeData.classDescList.Find(obj => obj.Id == sub.Sub_class_id);

                LayoutControlGroup grp1 = this.CreateLayoutGroup(subclass.Class_name);
                LayoutControlItem  item = this.CreateGridListViewItem(subclass);
                grp1.AddItem(item);
                layoutEdit.AddGroup(grp1);
            }
        }
コード例 #6
0
ファイル: Program.cs プロジェクト: z77ma/runtime
        static void Main(string[] args)
        {
            using StreamWriter twOutputCommon = new StreamWriter(Path.Combine(args[0], @$ "{CommonAndImplAssemblyName}.il"));
            using StreamWriter twOutputTest   = new StreamWriter(Path.Combine(args[0], @$ "{TestAssemblyName}.il"));

            StringWriter swMainMethodBody   = new StringWriter();
            StringWriter swTestClassMethods = new StringWriter();

            EmitTestGlobalHeader(twOutputCommon);
            EmitAssemblyRecord(twOutputCommon, CommonAndImplAssemblyName);
            EmitCodeForCommonLibrary(twOutputCommon);
            GenerateImplementations(twOutputCommon);

            EmitTestGlobalHeader(twOutputTest);
            EmitAssemblyExternRecord(twOutputTest, CommonAndImplAssemblyName);
            EmitAssemblyRecord(twOutputTest, TestAssemblyName);

            foreach (var scenario in TestScenario.GetScenarios())
            {
                string scenarioName = scenario.ToString();

                string constrainedType = AppendSuffixToConstrainedType(scenario, GetConstrainedTypeName(scenario.ConstrainedTypeDefinition), out bool skipScenario);
                if (skipScenario)
                {
                    continue;
                }

                string interfaceTypeSansImplPrefix;
                string interfaceMethod;

                string constrainedTypePrefix;
                if (constrainedType.Contains("Valuetype"))
                {
                    constrainedTypePrefix = $"valuetype ";
                }
                else
                {
                    constrainedTypePrefix = $"class ";
                }

                switch (scenario.InterfaceType)
                {
                case InterfaceType.NonGeneric:
                    interfaceTypeSansImplPrefix = "IFaceNonGeneric";
                    break;

                case InterfaceType.GenericOverString:
                    if (scenario.CallerScenario == CallerMethodScenario.GenericOverConstrainedType)
                    {
                        interfaceTypeSansImplPrefix = "IFaceGeneric`1<!!1>";
                    }
                    else
                    {
                        interfaceTypeSansImplPrefix = "IFaceGeneric`1<string>";
                    }
                    break;

                case InterfaceType.GenericOverObject:
                    if (scenario.CallerScenario == CallerMethodScenario.GenericOverConstrainedType)
                    {
                        interfaceTypeSansImplPrefix = "IFaceGeneric`1<!!1>";
                    }
                    else
                    {
                        interfaceTypeSansImplPrefix = "IFaceGeneric`1<object>";
                    }
                    break;

                case InterfaceType.CuriouslyRecurringGeneric:
                    interfaceTypeSansImplPrefix = $"IFaceCuriouslyRecurringGeneric`1<{constrainedTypePrefix}{constrainedType}>";
                    break;

                default:
                    throw new Exception("Unexpected value");
                }

                string interfaceMethodRoot;
                string interfaceMethodInstantiation = "";

                switch (scenario.MethodType)
                {
                case MethodType.NormalMethod:
                    interfaceMethodRoot = "NormalMethod";
                    break;

                case MethodType.GenericMethodOverInt:
                    interfaceMethodRoot          = "GenericMethod";
                    interfaceMethodInstantiation = "<int32>";
                    break;

                case MethodType.GenericMethodOverString:
                    interfaceMethodRoot          = "GenericMethod";
                    interfaceMethodInstantiation = "<string>";
                    break;

                case MethodType.GenericMethodOverTypeParameter:
                    interfaceMethodRoot = "GenericMethod";
                    if (scenario.CallerScenario == CallerMethodScenario.NonGeneric)
                    {
                        continue;
                    }
                    interfaceMethodInstantiation = "<!!0>";
                    break;

                default:
                    throw new Exception("Unexpected");
                }

                interfaceMethod = interfaceMethodRoot + interfaceMethodInstantiation;

                TextWriter twIL;

                MethodDesc mdIndividualTestMethod = new MethodDesc();
                string     basicTestMethodName    = $"Test_{scenarioName}";
                mdIndividualTestMethod.Name        = basicTestMethodName;
                mdIndividualTestMethod.HasBody     = true;
                mdIndividualTestMethod.MethodFlags = "public static";
                mdIndividualTestMethod.MethodImpls = null;
                mdIndividualTestMethod.ReturnType  = "void";
                mdIndividualTestMethod.Arguments   = "";


                string expectedString = constrainedTypePrefix + AppendSuffixToConstrainedType(scenario, GetConstrainedTypeName(scenario.ConstrainedTypeDefinition, withImplPrefix: false), out _) + "'" + interfaceTypeSansImplPrefix + "." + interfaceMethodRoot + "'" + interfaceMethodInstantiation;
                expectedString = expectedString.Replace(ImplPrefix, "");

                if (scenario.CallerScenario == CallerMethodScenario.NonGeneric)
                {
                    EmitTestMethod();
                    CallTestEntrypoint($"        call void TestEntrypoint::{mdIndividualTestMethod.Name}()");
                }
                else
                {
                    string methodInstantiation;
                    switch (scenario.CallerScenario)
                    {
                    case CallerMethodScenario.GenericOverInt32:
                    case CallerMethodScenario.GenericOverString:

                        mdIndividualTestMethod.Name = mdIndividualTestMethod.Name + "<T>";
                        methodInstantiation         = "string";
                        if (scenario.CallerScenario == CallerMethodScenario.GenericOverInt32)
                        {
                            methodInstantiation = "int32";
                        }

                        expectedString = expectedString.Replace("!!0", $"{methodInstantiation}");
                        expectedString = expectedString.Replace(ImplPrefix, "");
                        EmitTestMethod();

                        CallTestEntrypoint($"        call void TestEntrypoint::{basicTestMethodName}<{methodInstantiation}>()");
                        break;

                    case CallerMethodScenario.GenericOverConstrainedType:
                        mdIndividualTestMethod.Name = $"{mdIndividualTestMethod.Name}<({(interfaceTypeSansImplPrefix.Contains("`") ? "class " : "")}{CommonPrefix}{interfaceTypeSansImplPrefix}) T,U>";

                        expectedString = expectedString.Replace("!!0", $"{constrainedTypePrefix}{constrainedType}");
                        expectedString = expectedString.Replace(ImplPrefix, "");

                        EmitTestMethod();

                        string callCommand = GetSetBangBang1IfNeeded("string") + $"    call void TestEntrypoint::{basicTestMethodName}<{constrainedTypePrefix}{constrainedType},string>()";
                        if (scenario.InterfaceType == InterfaceType.GenericOverObject)
                        {
                            callCommand = callCommand + Environment.NewLine + GetSetBangBang1IfNeeded("object") + $"        call void TestEntrypoint::{basicTestMethodName}<{constrainedTypePrefix}{constrainedType},object>()";
                        }
                        CallTestEntrypoint(callCommand);

                        string GetSetBangBang1IfNeeded(string bangBang1Expected)
                        {
                            if (expectedString.Contains("!!1"))
                            {
                                return($"    ldstr \"{bangBang1Expected}\"" + Environment.NewLine + "    stsfld string [GenericContextCommonCs]Statics::BangBang1Param" + Environment.NewLine);
                            }
                            else
                            {
                                return("");
                            }
                        }

                        break;

                    default:
                        throw new Exception("AACLL");
                    }
                }

                void CallTestEntrypoint(string callCommand)
                {
                    swMainMethodBody.WriteLine("    .try {");
                    swMainMethodBody.WriteLine(callCommand);
                    swMainMethodBody.WriteLine($"        leave.s {scenarioName}Done");
                    swMainMethodBody.WriteLine("    } catch [System.Runtime]System.Exception {");
                    swMainMethodBody.WriteLine($"        stloc.0");
                    swMainMethodBody.WriteLine($"        ldstr \"{scenarioName}\"");
                    swMainMethodBody.WriteLine($"        ldstr \"{expectedString}\"");
                    swMainMethodBody.WriteLine($"        ldloc.0");
                    swMainMethodBody.WriteLine($"        callvirt   instance string [System.Runtime]System.Object::ToString()");
                    swMainMethodBody.WriteLine($"        call void [GenericContextCommonCs]Statics::CheckForFailure(string,string,string)");
                    swMainMethodBody.WriteLine($"        leave.s {scenarioName}Done");
                    swMainMethodBody.WriteLine("    }");
                    swMainMethodBody.WriteLine($"{scenarioName}Done: nop");
                }

                // If test scenario requires generic class caller, Create Caller class and make a global method method which calls it
                // If test scenario requires generic method caller, create global generic method as required and non-generic test method
                // If test scenario requires non-generic method caller, just make global method as caller
                //   Call callee
                //
                // Create Callee class
                //   With callee method that implements scenario
                //   fill expected value static with string computed based on scenario + exact type of calle class/generic args of callee method
                // compute expected result string

                void EmitTestMethod()
                {
                    EmitMethod(swTestClassMethods, mdIndividualTestMethod);
                    EmitILToCallActualMethod(swTestClassMethods);
                    swTestClassMethods.WriteLine($"    ldstr \"{scenario.ToString()}\"");
                    swTestClassMethods.WriteLine($"    ldstr \"{expectedString}\"");
                    if (expectedString.Contains("!!1"))
                    {
                        swTestClassMethods.WriteLine("    ldstr \"!!1\"");
                        swTestClassMethods.WriteLine("    ldsfld string [GenericContextCommonCs]Statics::BangBang1Param");
                        swTestClassMethods.WriteLine("    call instance string [System.Runtime]System.String::Replace(string, string)");
                    }
                    swTestClassMethods.WriteLine($"    call void {CommonCsPrefix}Statics::CheckForFailure(string,string)");
                    swTestClassMethods.WriteLine($"    ret");
                    twIL = swTestClassMethods;
                    EmitEndMethod(swTestClassMethods, mdIndividualTestMethod);
                }

                void EmitILToCallActualMethod(TextWriter twActualIL)
                {
                    // Emit the IL to call the actual method
                    switch (scenario.Operation)
                    {
                    case OperationTested.Call:
                        EmitConstrainedPrefix();
                        twActualIL.WriteLine($"    call void class {ImplPrefix}{interfaceTypeSansImplPrefix}::{interfaceMethod}()");
                        break;

                    case OperationTested.Ldftn:
                        EmitConstrainedPrefix();
                        twActualIL.WriteLine($"    ldftn void class {ImplPrefix}{interfaceTypeSansImplPrefix}::{interfaceMethod}()");
                        twActualIL.WriteLine($"    volatile.");
                        twActualIL.WriteLine($"    stsfld     native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) {CommonCsPrefix}Statics::FtnHolder");
                        twActualIL.WriteLine($"    volatile.");
                        twActualIL.WriteLine($"    ldsfld     native int modreq([System.Runtime]System.Runtime.CompilerServices.IsVolatile) {CommonCsPrefix}Statics::FtnHolder");
                        twActualIL.WriteLine($"    calli      void()");
                        break;

                    case OperationTested.CreateDelegate:
                        twActualIL.WriteLine("    ldnull");
                        EmitConstrainedPrefix();
                        twActualIL.WriteLine($"    ldftn void class {ImplPrefix}{interfaceTypeSansImplPrefix}::{interfaceMethod}()");
                        twActualIL.WriteLine($"    newobj instance void [System.Runtime]System.Action::.ctor(object,");
                        twActualIL.WriteLine($"                                                              native int)");
                        twActualIL.WriteLine($"    volatile.");
                        twActualIL.WriteLine($"    stsfld     class [System.Runtime] System.Action modreq([System.Runtime] System.Runtime.CompilerServices.IsVolatile) {CommonCsPrefix}Statics::ActionHolder");
                        twActualIL.WriteLine($"    volatile.");
                        twActualIL.WriteLine($"    ldsfld class [System.Runtime] System.Action modreq([System.Runtime] System.Runtime.CompilerServices.IsVolatile) {CommonCsPrefix}Statics::ActionHolder");
                        twActualIL.WriteLine($"    callvirt instance void[System.Runtime] System.Action::Invoke()");
                        break;

                    default:
                        throw new Exception();
                    }

                    void EmitConstrainedPrefix()
                    {
                        if (scenario.CallerScenario == CallerMethodScenario.GenericOverConstrainedType)
                        {
                            twActualIL.WriteLine($"    constrained. !!0");
                        }
                        else
                        {
                            twActualIL.WriteLine($"    constrained. {constrainedTypePrefix}{constrainedType}");
                        }
                    }
                }
            }

            ClassDesc mainClass = new ClassDesc();

            mainClass.BaseType   = "[System.Runtime]System.Object";
            mainClass.ClassFlags = "public auto ansi";
            mainClass.Name       = "TestEntrypoint";

            EmitClass(twOutputTest, mainClass);

            twOutputTest.Write(swTestClassMethods.ToString());

            MethodDesc mainMethod = new MethodDesc();

            mainMethod.Name        = "Main";
            mainMethod.Arguments   = "";
            mainMethod.ReturnType  = "int32";
            mainMethod.MethodImpls = null;
            mainMethod.HasBody     = true;
            mainMethod.MethodFlags = "public static";

            EmitMethod(twOutputTest, mainMethod);
            twOutputTest.WriteLine("    .entrypoint");
            twOutputTest.WriteLine("    .locals init (class [System.Runtime]System.Exception V_0)");
            twOutputTest.Write(swMainMethodBody.ToString());
            twOutputTest.WriteLine($"    call int32 { CommonCsPrefix}Statics::ReportResults()");
            twOutputTest.WriteLine("    ret");

            EmitEndMethod(twOutputTest, mainMethod);
            EmitEndClass(twOutputTest, mainClass);
        }
コード例 #7
0
ファイル: Program.cs プロジェクト: z77ma/runtime
        static void GenerateImplementations(TextWriter tw)
        {
            foreach (var constrainedTypeDefinition in (ConstrainedTypeDefinition[])typeof(ConstrainedTypeDefinition).GetEnumValues())
            {
                string baseType = constrainedTypeDefinition.ToString().Contains("Valuetype") ? "[System.Runtime]System.ValueType" : "[System.Runtime]System.Object";

                ClassDesc implClass = new ClassDesc();
                implClass.BaseType = baseType;

                implClass.Name       = GetConstrainedTypeName(constrainedTypeDefinition, false);
                implClass.ClassFlags = "public auto ansi";
                string implTypePrefix = "class";
                if (constrainedTypeDefinition.ToString().Contains("Valuetype"))
                {
                    implTypePrefix       = "valuetype";
                    implClass.ClassFlags = implClass.ClassFlags + " sealed";
                }

                if (constrainedTypeDefinition.ToString().StartsWith("Generic"))
                {
                    implClass.GenericParams = "T";
                }

                List <string> interfacesImplemented = new List <string>();
                StringWriter  implsGenerated        = new StringWriter();
                implClass.InterfacesImplemented = interfacesImplemented;

                if (constrainedTypeDefinition.ToString().StartsWith("Generic"))
                {
                    GenerateImpl(implClass.Name + "<!0>", "IFaceNonGeneric", "", false);
                    GenerateImpl(implClass.Name + "<!0>", "IFaceGeneric`1", "<string>", true);
                    GenerateImpl(implClass.Name + "<!0>", "IFaceGeneric`1", "<object>", true);
                    GenerateImpl(implClass.Name + "<!0>", $"IFaceCuriouslyRecurringGeneric`1", $"<{implTypePrefix} {implClass.Name}<!0>>", true);
                }
                else
                {
                    GenerateImpl(implClass.Name, "IFaceNonGeneric", "", false);
                    GenerateImpl(implClass.Name, "IFaceGeneric`1", "<string>", true);
                    GenerateImpl(implClass.Name, "IFaceGeneric`1", "<object>", true);
                    GenerateImpl(implClass.Name, $"IFaceCuriouslyRecurringGeneric`1", $"<{implTypePrefix} {implClass.Name}>", true);
                }

                EmitClass(tw, implClass);
                if (!constrainedTypeDefinition.ToString().Contains("Valuetype"))
                {
                    tw.WriteLine($"  .method public hidebysig specialname rtspecialname ");
                    tw.WriteLine($"          instance void  .ctor() cil managed");
                    tw.WriteLine($"  {{");
                    tw.WriteLine($"    .maxstack  8");
                    tw.WriteLine($"    IL_0000:  ldarg.0");
                    tw.WriteLine($"    IL_0001:  call       instance void {implClass.BaseType}::.ctor()");
                    tw.WriteLine($"    IL_0006:  ret");
                    tw.WriteLine($"  }}");
                }
                tw.WriteLine(implsGenerated.ToString());
                EmitEndClass(tw, implClass);

                void GenerateImpl(string implType, string iface, string ifaceGenericArguments, bool isGeneric)
                {
                    interfacesImplemented.Add(ToILDasmTypeName(iface, ifaceGenericArguments));

                    MethodDesc implMethodDesc = new MethodDesc();

                    implMethodDesc.Name        = $"'{iface}{ifaceGenericArguments}.NormalMethod'";
                    implMethodDesc.MethodFlags = "public static";
                    implMethodDesc.ReturnType  = "void";
                    implMethodDesc.HasBody     = true;
                    implMethodDesc.MethodImpls = new string[] { $"method void {ToILDasmTypeName(ImplPrefix+iface, ifaceGenericArguments)}::NormalMethod()" };

                    EmitMethod(implsGenerated, implMethodDesc);
                    GenerateMethodBody(false);
                    EmitEndMethod(implsGenerated, implMethodDesc);

                    implMethodDesc.Name        = $"'{iface}{ifaceGenericArguments}.GenericMethod'<U>";
                    implMethodDesc.MethodImpls = new string[] { $"method void {ToILDasmTypeName(ImplPrefix + iface, ifaceGenericArguments)}::GenericMethod<[1]>()" };
                    EmitMethod(implsGenerated, implMethodDesc);
                    GenerateMethodBody(true);
                    EmitEndMethod(implsGenerated, implMethodDesc);

                    void GenerateMethodBody(bool genericMethod)
                    {
                        implsGenerated.WriteLine($"    ldtoken {implTypePrefix} {implType}");
                        implsGenerated.WriteLine($"    call string {CommonCsPrefix}Statics::MakeName(valuetype [System.Runtime]System.RuntimeTypeHandle)");

                        string methodNameToEmit = implMethodDesc.Name;

                        if (methodNameToEmit.EndsWith("<U>"))
                        {
                            methodNameToEmit = methodNameToEmit.Substring(0, methodNameToEmit.Length - 3);
                        }
                        implsGenerated.WriteLine($"    ldstr \"{methodNameToEmit}\"");
                        if (methodNameToEmit.Contains("!!0"))
                        {
                            implsGenerated.WriteLine($"    ldstr \"!!0\"");
                            implsGenerated.WriteLine($"    ldtoken !!0");
                            implsGenerated.WriteLine($"    call string {CommonCsPrefix}Statics::MakeName(valuetype[System.Runtime]System.RuntimeTypeHandle)");
                            implsGenerated.WriteLine($"    call instance string [System.Runtime]System.String::Replace(string, string)");
                        }
                        if (methodNameToEmit.Contains("!!1"))
                        {
                            implsGenerated.WriteLine($"    ldstr \"!!1\"");
                            implsGenerated.WriteLine($"    ldtoken !!1");
                            implsGenerated.WriteLine($"    call string {CommonCsPrefix}Statics::MakeName(valuetype[System.Runtime]System.RuntimeTypeHandle)");
                            implsGenerated.WriteLine($"    call instance string [System.Runtime]System.String::Replace(string, string)");
                        }
                        if (methodNameToEmit.Contains("!0"))
                        {
                            implsGenerated.WriteLine($"    ldstr \"!0\"");
                            implsGenerated.WriteLine($"    ldtoken !0");
                            implsGenerated.WriteLine($"    call string {CommonCsPrefix}Statics::MakeName(valuetype[System.Runtime]System.RuntimeTypeHandle)");
                            implsGenerated.WriteLine($"    call instance string [System.Runtime]System.String::Replace(string, string)");
                        }
                        if (genericMethod)
                        {
                            implsGenerated.WriteLine($"    ldstr \"<\"");
                            implsGenerated.WriteLine($"    ldtoken !!0");
                            implsGenerated.WriteLine($"    call string {CommonCsPrefix}Statics::MakeName(valuetype[System.Runtime]System.RuntimeTypeHandle)");
                            implsGenerated.WriteLine($"    ldstr \">\"");
                            implsGenerated.WriteLine($"    call string[System.Runtime] System.String::Concat(string, string, string,string)");
                        }
                        implsGenerated.WriteLine($"    call string[System.Runtime] System.String::Concat(string, string)");
                        implsGenerated.WriteLine($"    stsfld string {CommonCsPrefix}Statics::String");
                        implsGenerated.WriteLine($"    ret");
                    }
                }
            }
        }
コード例 #8
0
ファイル: Program.cs プロジェクト: z77ma/runtime
 static void EmitEndClass(TextWriter tw, ClassDesc clz)
 {
     tw.WriteLine($"}} // end of class {clz.Name}");
 }
コード例 #9
0
        private static string GetClassDefine(ClassDesc klass, bool il2cpp)
        {
            var perfix = il2cpp ? "il2cpp" : "mono";

            return($"{perfix}_get_class_{klass.Namespace}_{klass.Name}()".Replace(".", "_"));
        }
コード例 #10
0
        public void Resolve(string assemblyName, string dllName)
        {
            // create assembly and module
            AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(
                new AssemblyName(assemblyName),
                AssemblyBuilderAccess.Save
                );
            ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule(assemblyName, dllName);

            // create Inanity.Object type
            TypeBuilder inanityObjectTypeBuilder = moduleBuilder.DefineType(
                "Inanity.Object",
                TypeAttributes.Public | TypeAttributes.Abstract,
                null,                 // parent
                new Type[] {
                typeof(IDisposable)
            }
                );

            inanityObjectTypeBuilder.DefineField(
                "ptr",
                typeof(UIntPtr),
                FieldAttributes.Family
                );
            ConstructorBuilder inanityObjectConstructorBuilder = inanityObjectTypeBuilder.DefineDefaultConstructor(MethodAttributes.Family);

            {
                MethodBuilder disposeMethod = inanityObjectTypeBuilder.DefineMethod(
                    "Dispose",
                    MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.Final | MethodAttributes.HideBySig,
                    typeof(void),
                    new Type[] { }
                    );
                disposeMethod.SetImplementationFlags(MethodImplAttributes.InternalCall);
            }
            inanityObjectTypeBuilder.CreateType();

            // create type bulders for all classes
            foreach (string fullClassName in classes.Keys)
            {
                classes[fullClassName].typeBuilder = moduleBuilder.DefineType(
                    fullClassName,
                    TypeAttributes.Public | (classes[fullClassName].constructor == null ? TypeAttributes.Abstract : 0)
                    );
            }

            // lambda for resolving types
            Func <string, Type> resolveType = delegate(string typeName)
            {
                switch (typeName)
                {
                case "void":
                    return(typeof(void));

                case "bool":
                    return(typeof(bool));

                case "int32":
                    return(typeof(Int32));

                case "uint32":
                    return(typeof(UInt32));

                case "int64":
                    return(typeof(Int64));

                case "uint64":
                    return(typeof(UInt64));

                case "float":
                    return(typeof(float));

                case "double":
                    return(typeof(double));

                case "string":
                    return(typeof(string));

                case "object":
                    return(typeof(object));

                default:
                {
                    ClassDesc classDesc;
                    if (!classes.TryGetValue(typeName, out classDesc))
                    {
                        throw new Exception("Cannot resolve type " + typeName);
                    }
                    return(classDesc.typeBuilder);
                }
                }
            };

            // set parents, create constructors and methods
            foreach (string className in classes.Keys)
            {
                ClassDesc   classDesc   = classes[className];
                TypeBuilder typeBuilder = classDesc.typeBuilder;
                // set parent
                {
                    TypeBuilder parentTypeBuilder;
                    if (classDesc.parentClassName != null)
                    {
                        if (!classes.TryGetValue(classDesc.parentClassName, out classDesc.parentClassDesc))
                        {
                            throw new Exception("Parent class " + classDesc.parentClassName + " is not registered");
                        }
                        parentTypeBuilder = classDesc.parentClassDesc.typeBuilder;
                    }
                    else
                    {
                        parentTypeBuilder = inanityObjectTypeBuilder;
                    }
                    typeBuilder.SetParent(parentTypeBuilder);
                }
                // set constructor
                {
                    ConstructorDesc constructorDesc = classDesc.constructor;
                    if (constructorDesc != null)
                    {
                        Type[] argumentTypes = constructorDesc.argumentTypes.Select(resolveType).ToArray();

                        // define extern thunk method
                        MethodBuilder methodBuilder = typeBuilder.DefineMethod(
                            "__c",
                            MethodAttributes.Private,
                            CallingConventions.HasThis,
                            typeof(void),
                            argumentTypes
                            );
                        methodBuilder.SetImplementationFlags(MethodImplAttributes.InternalCall);
                        classDesc.constructorThunkMethodBuilder = methodBuilder;

                        // define constructor
                        ConstructorBuilder constructorBuilder = typeBuilder.DefineConstructor(
                            MethodAttributes.Public,
                            CallingConventions.HasThis,
                            argumentTypes
                            );
                        classDesc.constructorBuilder = constructorBuilder;
                    }
                    else
                    {
                        classDesc.constructorBuilder = typeBuilder.DefineDefaultConstructor(MethodAttributes.Family);
                    }
                }
                // add methods
                foreach (string methodName in classDesc.methods.Keys)
                {
                    MethodDesc    methodDesc    = classDesc.methods[methodName];
                    MethodBuilder methodBuilder = typeBuilder.DefineMethod(
                        methodName,
                        MethodAttributes.Public | MethodAttributes.Final,
                        CallingConventions.HasThis,
                        resolveType(methodDesc.returnType),
                        methodDesc.argumentTypes.Select(resolveType).ToArray()
                        );
                    methodBuilder.SetImplementationFlags(MethodImplAttributes.InternalCall);
                }
                // add static methods
                foreach (string staticMethodName in classDesc.staticMethods.Keys)
                {
                    FunctionDesc  functionDesc  = classDesc.staticMethods[staticMethodName];
                    MethodBuilder methodBuilder = typeBuilder.DefineMethod(
                        staticMethodName,
                        MethodAttributes.Public | MethodAttributes.Final | MethodAttributes.Static,
                        CallingConventions.Standard,
                        resolveType(functionDesc.returnType),
                        functionDesc.argumentTypes.Select(resolveType).ToArray()
                        );
                    methodBuilder.SetImplementationFlags(MethodImplAttributes.InternalCall);
                }
            }

            // emit code for constructors
            foreach (ClassDesc classDesc in classes.Values)
            {
                ConstructorDesc constructorDesc = classDesc.constructor;
                if (constructorDesc == null)
                {
                    continue;
                }

                Type[] argumentTypes = constructorDesc.argumentTypes.Select(resolveType).ToArray();

                ILGenerator ilGenerator = classDesc.constructorBuilder.GetILGenerator();
                ilGenerator.Emit(OpCodes.Ldarg_0);
                ilGenerator.Emit(OpCodes.Call,
                                 classDesc.parentClassDesc != null
                                        ? classDesc.parentClassDesc.constructorBuilder
                                        : inanityObjectConstructorBuilder
                                 );
                ilGenerator.Emit(OpCodes.Ldarg_0);
                for (int i = 0; i < argumentTypes.Length; ++i)
                {
                    ilGenerator.Emit(OpCodes.Ldarg, i + 1);
                }
                ilGenerator.Emit(OpCodes.Call, classDesc.constructorThunkMethodBuilder);
                ilGenerator.Emit(OpCodes.Ret);
            }

            // create types
            foreach (ClassDesc classDesc in classes.Values)
            {
                classDesc.typeBuilder.CreateType();
            }

            // save assembly
            assemblyBuilder.Save(dllName);
        }
コード例 #11
0
ファイル: Program.cs プロジェクト: mikem8361/runtime
        static void Main(string[] args)
        {
            int    maxCases       = Int32.MaxValue;
            string rootPath       = Path.GetDirectoryName(typeof(Program).Assembly.Location);
            string scenarioSuffix = "";

            if (args.Length > 0)
            {
                rootPath = args[0];
            }
            if (args.Length > 2)
            {
                maxCases       = Int32.Parse(args[1]);
                scenarioSuffix = args[2];
            }
            using StreamWriter twOutputTest = new StreamWriter(Path.Combine(rootPath, @$ "{TestAssemblyName}{scenarioSuffix}.il"));

            StringWriter swMainMethodBody   = new StringWriter();
            StringWriter swTestClassMethods = new StringWriter();

            EmitTestGlobalHeader(twOutputTest);
            EmitAssemblyRecord(twOutputTest, TestAssemblyName);

            int currentCase = 0;

            foreach (var scenario in TestScenario.GetScenarios())
            {
                if ((++currentCase) > maxCases)
                {
                    break;
                }
                string scenarioName = scenario.ToString();

                // Emit interface
                ClassDesc iface = new ClassDesc();
                iface.ClassFlags    = "interface public abstract auto ansi";
                iface.GenericParams = scenario.InterfaceTypeGenericParams;
                iface.Name          = "Interface" + scenarioName + GenericTypeSuffix(scenario.InterfaceTypeGenericParams);;

                EmitClass(twOutputTest, iface);
                MethodDesc ifaceMethod = new MethodDesc();
                ifaceMethod.HasBody     = false;
                ifaceMethod.MethodFlags = "public newslot virtual abstract static";
                ifaceMethod.ReturnType  = scenario.InterfaceReturnType;
                ifaceMethod.Name        = "Method";

                EmitMethod(twOutputTest, ifaceMethod);
                EmitEndMethod(twOutputTest, ifaceMethod);
                EmitEndClass(twOutputTest, iface);

                // Emit base class which implements static method to implement interface. Mark it abstract if we don't put the methodimpl there
                ClassDesc baseType = new ClassDesc();
                baseType.BaseType = "[System.Runtime]System.Object";
                switch (scenario.InterfaceImplementationApproach)
                {
                case InterfaceImplementationApproach.OnBaseType:
                case InterfaceImplementationApproach.OnBothBaseAndDerived:
                    baseType.ClassFlags = "public auto ansi";
                    break;

                case InterfaceImplementationApproach.OnBothBaseAndDerivedBaseIsAbstract:
                    baseType.ClassFlags = "public abstract auto ansi";
                    break;

                default:
                    throw new Exception("Unknown interface approach");
                }
                baseType.GenericParams = scenario.BaseTypeGenericParams;
                baseType.Name          = "Base" + scenarioName + GenericTypeSuffix(scenario.BaseTypeGenericParams);
                if (scenario.InterfaceImplementationApproach.ToString().Contains("Base"))
                {
                    baseType.InterfacesImplemented = new string[] { ToILDasmTypeName(iface.Name, scenario.InterfaceTypeInstantiationOnBaseType) };
                }
                EmitClass(twOutputTest, baseType);
                switch (scenario.InterfaceImplementationApproach)
                {
                case InterfaceImplementationApproach.OnBaseType:
                case InterfaceImplementationApproach.OnBothBaseAndDerived:
                    MethodDesc ifaceImplMethod = new MethodDesc();
                    ifaceImplMethod.HasBody     = true;
                    ifaceImplMethod.MethodFlags = "public static";
                    ifaceImplMethod.ReturnType  = scenario.BaseTypeReturnType;
                    ifaceImplMethod.Name        = "Method";
                    EmitMethod(twOutputTest, ifaceImplMethod);
                    twOutputTest.WriteLine($"    .override method {scenario.InterfaceReturnType} {ToILDasmTypeName(iface.Name, scenario.InterfaceTypeInstantiationOnBaseType)}::Method()");
                    twOutputTest.WriteLine($"    .locals init ({scenario.BaseTypeReturnType} V_O)");
                    twOutputTest.WriteLine($"    ldloca.s 0");
                    twOutputTest.WriteLine($"    initobj {scenario.BaseTypeReturnType}");
                    twOutputTest.WriteLine($"    ldloc.0");
                    twOutputTest.WriteLine($"    ret");
                    EmitEndMethod(twOutputTest, ifaceImplMethod);
                    break;

                case InterfaceImplementationApproach.OnBothBaseAndDerivedBaseIsAbstract:
                    break;

                default:
                    throw new Exception("Unknown interface approach");
                }
                EmitEndClass(twOutputTest, baseType);

                // Emit derived class.
                ClassDesc derivedType = new ClassDesc();
                derivedType.BaseType = ToILDasmTypeName(baseType.Name, scenario.BaseTypeInstantiationOnDerivedType);
                switch (scenario.InterfaceImplementationApproach)
                {
                case InterfaceImplementationApproach.OnBaseType:
                case InterfaceImplementationApproach.OnBothBaseAndDerived:
                case InterfaceImplementationApproach.OnBothBaseAndDerivedBaseIsAbstract:
                    derivedType.ClassFlags = "public auto ansi";
                    break;

                default:
                    throw new Exception("Unknown interface approach");
                }
                derivedType.Name          = "Derived" + scenarioName + GenericTypeSuffix(scenario.DerivedTypeGenericParams);
                derivedType.GenericParams = scenario.DerivedTypeGenericParams;
                if (scenario.InterfaceImplementationApproach.ToString().Contains("Derived"))
                {
                    derivedType.InterfacesImplemented = new string[] { ToILDasmTypeName(iface.Name, scenario.InterfaceTypeInstantiationOnDerivedType) };
                }

                EmitClass(twOutputTest, derivedType);
                switch (scenario.InterfaceImplementationApproach)
                {
                case InterfaceImplementationApproach.OnBaseType:
                case InterfaceImplementationApproach.OnBothBaseAndDerived:
                    break;

                case InterfaceImplementationApproach.OnBothBaseAndDerivedBaseIsAbstract:
                    MethodDesc ifaceImplMethod = new MethodDesc();
                    ifaceImplMethod.HasBody     = true;
                    ifaceImplMethod.MethodFlags = "public static";
                    ifaceImplMethod.ReturnType  = scenario.DerivedTypeReturnType;
                    ifaceImplMethod.Name        = "MethodImplOnDerived";
                    EmitMethod(twOutputTest, ifaceImplMethod);
                    twOutputTest.WriteLine($"    .override method {scenario.InterfaceReturnType} {ToILDasmTypeName(iface.Name, scenario.InterfaceTypeInstantiationOnDerivedType)}::Method()");
                    twOutputTest.WriteLine($"    .locals init ({scenario.DerivedTypeReturnType} V_O)");
                    twOutputTest.WriteLine($"    ldloca.s 0");
                    twOutputTest.WriteLine($"    initobj {scenario.DerivedTypeReturnType}");
                    twOutputTest.WriteLine($"    ldloc.0");
                    twOutputTest.WriteLine($"    ret");
                    EmitEndMethod(twOutputTest, ifaceImplMethod);
                    break;

                default:
                    throw new Exception("Unknown interface approach");
                }
                EmitEndClass(twOutputTest, derivedType);

                // Emit test method which performs constrained call to hit the method
                MethodDesc mdIndividualTestMethod = new MethodDesc();
                string     basicTestMethodName    = $"Test_{scenarioName}";
                mdIndividualTestMethod.Name        = basicTestMethodName;
                mdIndividualTestMethod.HasBody     = true;
                mdIndividualTestMethod.MethodFlags = "public static";
                mdIndividualTestMethod.MethodImpls = null;
                mdIndividualTestMethod.ReturnType  = "void";
                mdIndividualTestMethod.Arguments   = "";

                EmitMethod(swTestClassMethods, mdIndividualTestMethod);
                swTestClassMethods.WriteLine($"    constrained. {ToILDasmTypeName(derivedType.Name, scenario.DerivedTypeInstantiation)}");
                swTestClassMethods.WriteLine($"    call {scenario.CallReturnType} {ToILDasmTypeName(iface.Name, scenario.CallInterfaceTypeInstantiation)}::Method()");
                if (scenario.CallReturnType != "void")
                {
                    // TODO: should we rather convert the value to string and stsfld Statics.String?
                    swTestClassMethods.WriteLine($"    pop");
                }
                swTestClassMethods.WriteLine($"    ldstr \"{scenarioName}\"");
                swTestClassMethods.WriteLine($"    ldnull");
                swTestClassMethods.WriteLine($"    call void {CommonCsPrefix}Statics::CheckForFailure(string,string)");
                swTestClassMethods.WriteLine($"    ret");
                EmitEndMethod(swTestClassMethods, mdIndividualTestMethod);
                // Call test method from main method
                swMainMethodBody.WriteLine("    .try {");
                swMainMethodBody.WriteLine($"        call void TestEntrypoint::{mdIndividualTestMethod.Name}()");
                swMainMethodBody.WriteLine($"        leave.s {scenarioName}Done");
                swMainMethodBody.WriteLine("    } catch [System.Runtime]System.Exception {");
                swMainMethodBody.WriteLine($"        stloc.0");
                swMainMethodBody.WriteLine($"        ldstr \"{scenarioName}\"");
                swMainMethodBody.WriteLine($"        ldnull");
                swMainMethodBody.WriteLine($"        ldloc.0");
                swMainMethodBody.WriteLine($"        callvirt   instance string [System.Runtime]System.Object::ToString()");
                swMainMethodBody.WriteLine($"        call void [TypeHierarchyCommonCs]Statics::CheckForFailure(string,string,string)");
                swMainMethodBody.WriteLine($"        leave.s {scenarioName}Done");
                swMainMethodBody.WriteLine("    }");
                swMainMethodBody.WriteLine($"{scenarioName}Done: nop");

                string GenericTypeSuffix(string genericParams)
                {
                    if (String.IsNullOrEmpty(genericParams))
                    {
                        return("");
                    }

                    return($"`{genericParams.Split(',').Length}");
                }
            }

            ClassDesc mainClass = new ClassDesc();

            mainClass.BaseType   = "[System.Runtime]System.Object";
            mainClass.ClassFlags = "public auto ansi";
            mainClass.Name       = "TestEntrypoint";

            EmitClass(twOutputTest, mainClass);

            twOutputTest.Write(swTestClassMethods.ToString());

            MethodDesc mainMethod = new MethodDesc();

            mainMethod.Name        = "Main";
            mainMethod.Arguments   = "";
            mainMethod.ReturnType  = "int32";
            mainMethod.MethodImpls = null;
            mainMethod.HasBody     = true;
            mainMethod.MethodFlags = "public static";

            EmitMethod(twOutputTest, mainMethod);
            twOutputTest.WriteLine("    .entrypoint");
            twOutputTest.WriteLine("    .locals init (class [System.Runtime]System.Exception V_0)");
            twOutputTest.Write(swMainMethodBody.ToString());
            twOutputTest.WriteLine($"    call int32 { CommonCsPrefix}Statics::ReportResults()");
            twOutputTest.WriteLine("    ret");

            EmitEndMethod(twOutputTest, mainMethod);
            EmitEndClass(twOutputTest, mainClass);
        }
コード例 #12
0
ファイル: ValueConverter.cs プロジェクト: s0s0s0/unity-orm
 public ArrayValueConverter(ClassDesc desc)
 {
     this.desc = desc;
 }
コード例 #13
0
ファイル: ValueConverter.cs プロジェクト: s0s0s0/unity-orm
 public ClassValueConverter(ClassDesc desc)
 {
     this.desc = desc;
 }