diff --git a/IL2C.Core/AssemblyPreparer.cs b/IL2C.Core/AssemblyPreparer.cs index 12389a6e..389d00f8 100644 --- a/IL2C.Core/AssemblyPreparer.cs +++ b/IL2C.Core/AssemblyPreparer.cs @@ -321,8 +321,8 @@ public static PreparedInformations Prepare(TranslateContext translateContext) translateContext, // All types type => true, - // The methods except type initializer. - method => !(method.IsConstructor && method.IsStatic)); + // All methods + method => true); } } } diff --git a/IL2C.Core/ILConveters/ArithmeticalConverters.cs b/IL2C.Core/ILConveters/ArithmeticalConverters.cs index 6010bd4e..35d77529 100644 --- a/IL2C.Core/ILConveters/ArithmeticalConverters.cs +++ b/IL2C.Core/ILConveters/ArithmeticalConverters.cs @@ -22,6 +22,7 @@ using Mono.Cecil.Cil; using IL2C.Translators; +using IL2C.Metadata; namespace IL2C.ILConverters { @@ -78,7 +79,7 @@ public static ExpressionEmitter Prepare(BinaryOperators binaryOperator, DecodeCo extractContext.GetSymbolName(si1)) }; } - // Double = (Float) % (Float) + // Double = (Float) op (Float) if (si0.TargetType.IsFloatStackFriendlyType && si1.TargetType.IsFloatStackFriendlyType && (binaryOperator == BinaryOperators.Rem)) { @@ -105,7 +106,7 @@ public static ExpressionEmitter Prepare(BinaryOperators binaryOperator, DecodeCo } // ByRef = (Int32) + (ByRef) - if (si0.TargetType.IsInt32StackFriendlyType && si1.TargetType.IsByReference && + if (si0.TargetType.IsInt32StackFriendlyType && (si1.TargetType.IsByReference) && (binaryOperator == BinaryOperators.Add)) { var result = decodeContext.PushStack(si1.TargetType); @@ -118,7 +119,7 @@ public static ExpressionEmitter Prepare(BinaryOperators binaryOperator, DecodeCo } // ByRef = (IntPtr) + (ByRef) - if (si0.TargetType.IsIntPtrStackFriendlyType && si1.TargetType.IsByReference && + if (si0.TargetType.IsIntPtrStackFriendlyType && (si1.TargetType.IsByReference) && (binaryOperator == BinaryOperators.Add)) { var result = decodeContext.PushStack(si1.TargetType); @@ -131,7 +132,7 @@ public static ExpressionEmitter Prepare(BinaryOperators binaryOperator, DecodeCo } // ByRef = (ByRef) +/- (Int32|IntPtr) - if (si0.TargetType.IsByReference && + if ((si0.TargetType.IsByReference || si0.TargetType.IsArray) && (si1.TargetType.IsInt32StackFriendlyType || si1.TargetType.IsIntPtrStackFriendlyType) && ((binaryOperator == BinaryOperators.Add) || (binaryOperator == BinaryOperators.Sub))) { @@ -234,4 +235,142 @@ public override ExpressionEmitter Prepare(DecodeContext decodeContext) ArithmeticalConverterUtilities.BinaryOperators.Rem, decodeContext); } } + + internal sealed class NotConverter : InlineNoneConverter + { + public override OpCode OpCode => OpCodes.Not; + + public override ExpressionEmitter Prepare(DecodeContext decodeContext) + { + var si0 = decodeContext.PopStack(); + + if (!(si0.TargetType.IsIntegerPrimitive && !si0.TargetType.IsCharType)) + throw new InvalidProgramSequenceException( + "Invalid arithmetical NOT operation: Location={0}, Type0={1}", + decodeContext.CurrentCode.RawLocation, + si0.TargetType.FriendlyName); + + var result = decodeContext.PushStack(si0.TargetType); + + return (extractContext, _) => new[] { string.Format( + "{0} = ~{1}", + extractContext.GetSymbolName(result), + extractContext.GetSymbolName(si0)) }; + } + } + + internal enum ShiftDirection + { + Left, Right + } + + internal abstract class ShiftConverter : InlineNoneConverter + { + public abstract ShiftDirection Direction { get; } + + public ExpressionEmitter Prepare(DecodeContext decodeContext, Func cast) + { + var si1 = decodeContext.PopStack(); + var si0 = decodeContext.PopStack(); + + if (si0.TargetType.IsFloatStackFriendlyType || si0.TargetType.IsByReference || !si1.TargetType.IsInt32Type) + throw new InvalidProgramSequenceException( + "Invalid arithmetical NOT operation: Location={0}, Type0={1}", + decodeContext.CurrentCode.RawLocation, + si0.TargetType.FriendlyName); + + var result = decodeContext.PushStack(si0.TargetType); + + if (cast == null) + { + return (extractContext, _) => new[] { string.Format( + "{0} = {1} {2} {3}", + extractContext.GetSymbolName(result), + extractContext.GetSymbolName(si0), + Direction == ShiftDirection.Left ? "<<" : ">>", + extractContext.GetSymbolName(si1)) }; + } + else + { + return (extractContext, _) => new[] { string.Format( + "{0} = ({4}){1} {2} {3}", + extractContext.GetSymbolName(result), + extractContext.GetSymbolName(si0), + Direction == ShiftDirection.Left ? "<<" : ">>", + extractContext.GetSymbolName(si1), + cast(si0)) }; + } + } + } + + internal sealed class ShiftRightConverter : ShiftConverter + { + public override OpCode OpCode => OpCodes.Shr; + + public override ShiftDirection Direction => ShiftDirection.Right; + + public override ExpressionEmitter Prepare(DecodeContext decodeContext) + { + return Prepare(decodeContext, si => si.TargetType.IsInt32StackFriendlyType ? "int32_t" : "int64_t"); + } + } + + internal sealed class ShiftLeftConverter : ShiftConverter + { + public override OpCode OpCode => OpCodes.Shl; + + public override ShiftDirection Direction => ShiftDirection.Left; + + public override ExpressionEmitter Prepare(DecodeContext decodeContext) + { + return Prepare(decodeContext, null); + } + } + + internal sealed class ShiftRightUnConverter : ShiftConverter + { + public override OpCode OpCode => OpCodes.Shr_Un; + + public override ShiftDirection Direction => ShiftDirection.Right; + + public override ExpressionEmitter Prepare(DecodeContext decodeContext) + { + return Prepare(decodeContext, si => si.TargetType.IsInt32StackFriendlyType ? "uint32_t" : "uint64_t"); + } + } + + internal sealed class NegConverter : InlineNoneConverter + { + public override OpCode OpCode => OpCodes.Neg; + + public override ExpressionEmitter Prepare(DecodeContext decodeContext) + { + var si0 = decodeContext.PopStack(); + Metadata.ILocalVariableInformation result; + + if (si0.TargetType.IsByReference) + throw new InvalidProgramSequenceException( + "Invalid arithmetical NEG operation: Location={0}, Type0={1}", + decodeContext.CurrentCode.RawLocation, + si0.TargetType.FriendlyName); + + if (si0.TargetType.IsInt32StackFriendlyType) + { + result = decodeContext.PushStack(decodeContext.PrepareContext.MetadataContext.Int32Type); + } + else if (si0.TargetType.IsInt64StackFriendlyType) + { // Int64 = -(Int64) + result = decodeContext.PushStack(decodeContext.PrepareContext.MetadataContext.Int64Type); + } + else + { // double = -(double) + result = decodeContext.PushStack(decodeContext.PrepareContext.MetadataContext.DoubleType); + } + + return (extractContext, _) => new[] { string.Format( + "{0} = -{1}", + extractContext.GetSymbolName(result), + extractContext.GetSymbolName(si0)) }; + } + } } diff --git a/IL2C.Core/ILConveters/BranchConverters.cs b/IL2C.Core/ILConveters/BranchConverters.cs index cb36384b..a57170cb 100644 --- a/IL2C.Core/ILConveters/BranchConverters.cs +++ b/IL2C.Core/ILConveters/BranchConverters.cs @@ -241,6 +241,28 @@ public override ExpressionEmitter Prepare( } } + internal sealed class Bgt_UnConverter : ShortInlineBrTargetConverter + { + public override OpCode OpCode => OpCodes.Bgt_Un; + + public override ExpressionEmitter Prepare( + ICodeInformation operand, DecodeContext decodeContext) + { + return BranchExpressionUtilities.ApplyBinary(operand, ">", decodeContext); + } + } + + internal sealed class Bgt_Un_sConverter : ShortInlineBrTargetConverter + { + public override OpCode OpCode => OpCodes.Bgt_Un_S; + + public override ExpressionEmitter Prepare( + ICodeInformation operand, DecodeContext decodeContext) + { + return BranchExpressionUtilities.ApplyBinary(operand, ">", decodeContext); + } + } + internal sealed class BleConverter : ShortInlineBrTargetConverter { public override OpCode OpCode => OpCodes.Ble; diff --git a/IL2C.Core/ILConveters/ConditionalConverters.cs b/IL2C.Core/ILConveters/ConditionalConverters.cs index bdbe2abe..3fc81f83 100644 --- a/IL2C.Core/ILConveters/ConditionalConverters.cs +++ b/IL2C.Core/ILConveters/ConditionalConverters.cs @@ -77,6 +77,18 @@ public static ExpressionEmitter Prepare( extractContext.GetSymbolName(si1)) }; } + if (si0.TargetType.IsFloatStackFriendlyType && + si1.TargetType.IsFloatStackFriendlyType) + { + var result = decodeContext.PushStack(decodeContext.PrepareContext.MetadataContext.Int32Type); + return (extractContext, _) => new[] { string.Format( + "{0} = (double){1} {2} (double){3}", + extractContext.GetSymbolName(result), + extractContext.GetSymbolName(si0), + oper, + extractContext.GetSymbolName(si1)) }; + } + if ((si0.TargetType.IsIntPtrStackFriendlyType || !si0.TargetType.IsValueType || si0.TargetType.IsByReference || si0.TargetType.IsUntypedReferenceType) && (si1.TargetType.IsIntPtrStackFriendlyType || !si1.TargetType.IsValueType || si1.TargetType.IsByReference || si0.TargetType.IsUntypedReferenceType)) { diff --git a/IL2C.Core/ILConveters/LdindConverters.cs b/IL2C.Core/ILConveters/LdindConverters.cs index 3a9a5d59..f00684ba 100644 --- a/IL2C.Core/ILConveters/LdindConverters.cs +++ b/IL2C.Core/ILConveters/LdindConverters.cs @@ -31,8 +31,8 @@ public static ExpressionEmitter Prepare(DecodeContext decodeContext) { var siFrom = decodeContext.PopStack(); - // Requre only managed refs - if (!siFrom.TargetType.IsByReference) + // Require only managed refs + if (!(siFrom.TargetType.IsByReference || siFrom.TargetType.IsArray)) { throw new InvalidProgramSequenceException( "Invalid managed reference: Location={0}, StackType={1}", @@ -43,10 +43,22 @@ public static ExpressionEmitter Prepare(DecodeContext decodeContext) var targetType = siFrom.TargetType.ElementType; var symbol = decodeContext.PushStack(targetType); - return (extractContext, _) => new[] { string.Format( - "{0} = *{1}", - extractContext.GetSymbolName(symbol), - extractContext.GetSymbolName(siFrom)) }; + if (siFrom.TargetType.IsArray) + { + return (extractContext, _) => new[] { string.Format( + "{0} = *(({2}*){1})", + extractContext.GetSymbolName(symbol), + extractContext.GetSymbolName(siFrom), + targetType.CLanguageTypeName + ) }; + } + else + { + return (extractContext, _) => new[] { string.Format( + "{0} = *{1}", + extractContext.GetSymbolName(symbol), + extractContext.GetSymbolName(siFrom)) }; + } } } @@ -159,4 +171,16 @@ public override ExpressionEmitter Prepare(DecodeContext decodeContext) return LdindConverterUtilities.Prepare(decodeContext); } } + + // It is just a generalized Ldind. C compiler handles struct copy + internal sealed class LdobjConverter : InlineTypeConverter + { + public override OpCode OpCode => OpCodes.Ldobj; + + public override ExpressionEmitter Prepare(Metadata.ITypeInformation operand, DecodeContext decodeContext) + { + // Note: note really need the operand in this case, since IL2C knows the type already + return LdindConverterUtilities.Prepare(decodeContext); + } + } } diff --git a/IL2C.Core/ILConveters/LdtokenConverters.cs b/IL2C.Core/ILConveters/LdtokenConverters.cs index 03e2fbe4..d1761749 100644 --- a/IL2C.Core/ILConveters/LdtokenConverters.cs +++ b/IL2C.Core/ILConveters/LdtokenConverters.cs @@ -33,7 +33,7 @@ internal sealed class LdtokenConverters : InlineMemberConverter public override ExpressionEmitter Prepare( IMemberInformation member, DecodeContext decodeContext) { - // ECMA-335 III.4.17 ldtoken - load the runt ime representat ion of a metadata + // ECMA-335 III.4.17 ldtoken - load the runtime representation of a metadata var field = member as IFieldInformation; if (field != null) diff --git a/IL2C.Core/ILConveters/StargConverters .cs b/IL2C.Core/ILConveters/StargConverters .cs new file mode 100644 index 00000000..a279242b --- /dev/null +++ b/IL2C.Core/ILConveters/StargConverters .cs @@ -0,0 +1,65 @@ +///////////////////////////////////////////////////////////////////////////////////////////////// +// +// IL2C - A translator for ECMA-335 CIL/MSIL to C language. +// Copyright (c) 2016-2019 Kouji Matsui (@kozy_kekyo, @kekyo2) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +///////////////////////////////////////////////////////////////////////////////////////////////// + +using System; + +using Mono.Cecil.Cil; + +using IL2C.Translators; +using IL2C.Metadata; + +namespace IL2C.ILConverters +{ + internal static class StargConverterUtilities + { + public static ExpressionEmitter Prepare( + int parameterIndex, DecodeContext decodeContext) + { + var si = decodeContext.PopStack(); + var parameter = decodeContext.Method.Parameters[parameterIndex]; + + // TODO: check target and source type + + return (extractContext, _) => new[] { string.Format( + "{0} = {1}", + parameter.ParameterName, + extractContext.GetSymbolName(si)) }; + } + } + + internal sealed class StargSConverter : ShortInlineParamConverter + { + public override OpCode OpCode => OpCodes.Starg_S; + + public override ExpressionEmitter Prepare(VariableInformation operand, DecodeContext decodeContext) + { + return StargConverterUtilities.Prepare(operand.Index, decodeContext); + } + } + + internal sealed class StargConverter : InlineParamConverter + { + public override OpCode OpCode => OpCodes.Starg; + + public override ExpressionEmitter Prepare(VariableInformation operand, DecodeContext decodeContext) + { + return StargConverterUtilities.Prepare(operand.Index, decodeContext); + } + } +} diff --git a/IL2C.Core/ILConveters/StindConverters.cs b/IL2C.Core/ILConveters/StindConverters.cs index 6ebba82e..491f5673 100644 --- a/IL2C.Core/ILConveters/StindConverters.cs +++ b/IL2C.Core/ILConveters/StindConverters.cs @@ -81,6 +81,28 @@ public static ExpressionEmitter Prepare( } } + internal sealed class Stind_i1Converter : InlineNoneConverter + { + public override OpCode OpCode => OpCodes.Stind_I1; + + public override ExpressionEmitter Prepare( + DecodeContext decodeContext) + { + return StindConverter_Utilities.Prepare(decodeContext); + } + } + + internal sealed class Stind_i2Converter : InlineNoneConverter + { + public override OpCode OpCode => OpCodes.Stind_I2; + + public override ExpressionEmitter Prepare( + DecodeContext decodeContext) + { + return StindConverter_Utilities.Prepare(decodeContext); + } + } + internal sealed class Stind_i4Converter : InlineNoneConverter { public override OpCode OpCode => OpCodes.Stind_I4; @@ -92,6 +114,39 @@ public override ExpressionEmitter Prepare( } } + internal sealed class Stind_i8Converter : InlineNoneConverter + { + public override OpCode OpCode => OpCodes.Stind_I8; + + public override ExpressionEmitter Prepare( + DecodeContext decodeContext) + { + return StindConverter_Utilities.Prepare(decodeContext); + } + } + + internal sealed class Stind_r4Converter : InlineNoneConverter + { + public override OpCode OpCode => OpCodes.Stind_R4; + + public override ExpressionEmitter Prepare( + DecodeContext decodeContext) + { + return StindConverter_Utilities.Prepare(decodeContext); + } + } + + internal sealed class Stind_r8Converter : InlineNoneConverter + { + public override OpCode OpCode => OpCodes.Stind_R8; + + public override ExpressionEmitter Prepare( + DecodeContext decodeContext) + { + return StindConverter_Utilities.Prepare(decodeContext); + } + } + internal sealed class Stind_RefConverter : InlineNoneConverter { public override OpCode OpCode => OpCodes.Stind_Ref; @@ -102,4 +157,16 @@ public override ExpressionEmitter Prepare( return StindConverter_Utilities.Prepare(decodeContext); } } + + // It is just a generalized Stind. C compiler handles struct copy + internal sealed class StobjConverter : InlineTypeConverter + { + public override OpCode OpCode => OpCodes.Stobj; + + public override ExpressionEmitter Prepare(Metadata.ITypeInformation operand, DecodeContext decodeContext) + { + // Note: note really need the operand in this case, since IL2C knows the type already + return StindConverter_Utilities.Prepare(decodeContext); + } + } } diff --git a/IL2C.Core/ILConveters/SwitchConverter.cs b/IL2C.Core/ILConveters/SwitchConverter.cs new file mode 100644 index 00000000..a26bf598 --- /dev/null +++ b/IL2C.Core/ILConveters/SwitchConverter.cs @@ -0,0 +1,48 @@ +using IL2C.ILConverters; +using IL2C.Metadata; +using IL2C.Translators; +using Mono.Cecil.Cil; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace IL2C.ILConveters +{ + internal sealed class SwitchConverter : ILConverter + { + public override OpCode OpCode => OpCodes.Switch; + + public override ExpressionEmitter Prepare(Instruction[] operands, DecodeContext decodeContext) + { + var si = decodeContext.PopStack(); + if (!si.TargetType.IsInt32Type) + throw new InvalidProgramSequenceException( + "Invalid type at stack for switch: Location={0}, StackType={1}", + decodeContext.CurrentCode.RawLocation, + si.TargetType.FriendlyName); + + var labels = new string[operands.Length]; + int i; + + for (i = 0; i < operands.Length; i++) + { + labels[i] = decodeContext.EnqueueNewPath(operands[i].Offset); + } + + return (extractContext, _) => + { + var result = new string[labels.Length + 1]; + result[0] = $"switch ({extractContext.GetSymbolName(si)}) {{\n "; + for (int q = 0; q < labels.Length; q++) + { + var caseStr = $"case {q}: goto {labels[q]}"; + if (q == 0) result[q] += caseStr; else result[q] = caseStr; + } + result[result.Length - 1] = "default: ;}"; + return result; + }; + } + } +} diff --git a/IL2C.Core/Metadata/MetadataContext.cs b/IL2C.Core/Metadata/MetadataContext.cs index b9416e97..cc99f585 100644 --- a/IL2C.Core/Metadata/MetadataContext.cs +++ b/IL2C.Core/Metadata/MetadataContext.cs @@ -112,9 +112,12 @@ internal MetadataContext(string assemblyPath, bool readSymbols) this.MainAssembly = mainAssemblyInformation; assemblies.Add(mainAssembly, mainAssemblyInformation); - assemblies.Add(resolvedCoreAssembly, resolvedCoreAssemblyInformation); - modules.Add(resolvedCoreModule, resolvedCoreModuleInformation); - assemblyByModule.Add(resolvedCoreModule, resolvedCoreAssembly); + if (!assemblies.ContainsKey(resolvedCoreAssembly)) + { + assemblies.Add(resolvedCoreAssembly, resolvedCoreAssemblyInformation); + modules.Add(resolvedCoreModule, resolvedCoreModuleInformation); + assemblyByModule.Add(resolvedCoreModule, resolvedCoreAssembly); + } this.VoidType = this.GetOrAddType(resolvedCoreModule.TypeSystem.Void); this.ObjectType = this.GetOrAddType(resolvedCoreModule.TypeSystem.Object); diff --git a/IL2C.Core/Metadata/MetadataUtilities.cs b/IL2C.Core/Metadata/MetadataUtilities.cs index 611dea31..014ac45c 100644 --- a/IL2C.Core/Metadata/MetadataUtilities.cs +++ b/IL2C.Core/Metadata/MetadataUtilities.cs @@ -270,6 +270,16 @@ public MethodSignatureTypeComparerImpl() public int Compare(ITypeInformation x, ITypeInformation y) { + if (x == null) + { + if (y == null) return 0; + else return 1; + } + else + { + if (y == null) return -1; + } + if (x.Equals(y)) { return 0; @@ -385,9 +395,6 @@ public int Compare(IParameterInformation x, IParameterInformation y) var xt = x.TargetType; var yt = y.TargetType; - var xr = xt.IsAssignableFrom(yt); - var yr = yt.IsAssignableFrom(xt); - return MethodSignatureTypeComparer.Compare(xt, yt); } @@ -424,10 +431,27 @@ public MethodSignatureComparerImpl(bool isVirtual) public int Compare(IMethodInformation x, IMethodInformation y) { - var rn = x.Name.CompareTo(y.Name); + var xname = x.Name; + var yname = y.Name; + + var rn = xname.CompareTo(yname); if (rn != 0) { - return rn; + // If it is an explicit interface implementation, we need to compare with it's full name + if (x.DeclaringType.IsInterface) + { + xname = $"{x.DeclaringType.FriendlyName}.{xname}"; + } + if (y.DeclaringType.IsInterface) + { + yname = $"{y.DeclaringType.FriendlyName}.{yname}"; + } + + rn = xname.CompareTo(yname); + if (rn != 0) + { + return rn; + } } var xps = x.Parameters; @@ -449,9 +473,25 @@ public int Compare(IMethodInformation x, IMethodInformation y) public bool Equals(IMethodInformation x, IMethodInformation y) { - if (x.Name != y.Name) + var xname = x.Name; + var yname = y.Name; + + if (xname != yname) { - return false; + // If it is an explicit interface implementation, we need to compare with it's full name + if (x.DeclaringType.IsInterface) + { + xname = $"{x.DeclaringType.FriendlyName}.{xname}"; + } + if (y.DeclaringType.IsInterface) + { + yname = $"{y.DeclaringType.FriendlyName}.{yname}"; + } + + if (xname != yname) + { + return false; + } } var xps = x.Parameters; diff --git a/IL2C.Core/Metadata/TypeInformation.cs b/IL2C.Core/Metadata/TypeInformation.cs index 53ec4e1e..b90c8d77 100644 --- a/IL2C.Core/Metadata/TypeInformation.cs +++ b/IL2C.Core/Metadata/TypeInformation.cs @@ -363,7 +363,7 @@ public bool IsReferenceType public bool IsRequiredTraverse => (this.Member.IsValueType && !this.Member.IsPrimitive && !this.Member.IsPointer && !this.IsByReference && !this.IsEnum && - this.Fields.Any(f => f.FieldType.IsRequiredTraverse)) || + this.Fields.Where(f => f.FieldType.FriendlyName != this.Member.FullName).Any(f => f.FieldType.IsRequiredTraverse)) || this.IsReferenceType; private static int InternalGetStaticSizeOfValue(ITypeInformation type) => diff --git a/IL2C.Core/TranslateContext.cs b/IL2C.Core/TranslateContext.cs index 46579c27..aa16aa0e 100644 --- a/IL2C.Core/TranslateContext.cs +++ b/IL2C.Core/TranslateContext.cs @@ -282,6 +282,17 @@ private string GetRightExpression( rhsExpression); } } + else if (rhsType.IsEnum) + { + // intValue = (int)enumValue + if (lhsType.IsNumericPrimitive) + { + return string.Format( + "({0}){1}", + lhsType.CLanguageTypeName, + rhsExpression); + } + } else if (rhsType.IsBooleanType) { // intValue = boolValue (implicitly conversion) diff --git a/IL2C.Core/Writers/HeaderWriter.cs b/IL2C.Core/Writers/HeaderWriter.cs index 3d06d29b..cca7ca60 100644 --- a/IL2C.Core/Writers/HeaderWriter.cs +++ b/IL2C.Core/Writers/HeaderWriter.cs @@ -118,7 +118,7 @@ private static void InternalWriteVTableTypePreDefinitions( } // If virtual method collection doesn't contain newslot method at this declared type: - if (!type.DeclaredNewslotMethods.Any(method => method.DeclaringType.Equals(type))) + if (!type.DeclaredNewslotMethods.Any(method => method.DeclaringType.Equals(type)) && type.BaseType != null) { twHeader.WriteLine( "typedef {0}_VTABLE_DECL__ {1}_VTABLE_DECL__;", diff --git a/IL2C.Core/Writers/TypeHelperWriter.cs b/IL2C.Core/Writers/TypeHelperWriter.cs index f9a407b5..b20d818e 100644 --- a/IL2C.Core/Writers/TypeHelperWriter.cs +++ b/IL2C.Core/Writers/TypeHelperWriter.cs @@ -342,7 +342,7 @@ public static void InternalConvertTypeHelper( declaredType.IsReferenceType ? "IL2C_TYPE_REFERENCE" : "IL2C_TYPE_VALUE", declaredType.CLanguageStaticSizeOfExpression, - declaredType.BaseType.MangledUniqueName, + declaredType.BaseType == null ? "NULL" : declaredType.BaseType.MangledUniqueName, declaredType.IsDelegate ? "System_Delegate_MarkHandler__" : markTargetFields.Length.ToString(), interfaceTypes.Length); } diff --git a/IL2C.Core/Writers/TypeWriter.cs b/IL2C.Core/Writers/TypeWriter.cs index 74e5f8cd..89c7428a 100644 --- a/IL2C.Core/Writers/TypeWriter.cs +++ b/IL2C.Core/Writers/TypeWriter.cs @@ -98,7 +98,7 @@ public static void WriteTypeDefinitions( tw.WriteLine( "// [1-2-3] {0} VTable layout (Derived from {1})", declaredType.MemberTypeName, - declaredType.BaseType.FriendlyName); + declaredType.BaseType?.FriendlyName); } tw.WriteLine( @@ -276,7 +276,7 @@ public static void WriteTypeDefinitions( { tw.WriteLine( "// [1-5-1] VTable (Same as {0})", - declaredType.BaseType.FriendlyName); + declaredType.BaseType?.FriendlyName); tw.WriteLine( "#define {0}_VTABLE__ {1}_VTABLE__", declaredType.MangledUniqueName, @@ -287,7 +287,7 @@ public static void WriteTypeDefinitions( { tw.WriteLine( "// [1-5-2] VTable (Derived from {0})", - declaredType.BaseType.FriendlyName); + declaredType.BaseType?.FriendlyName); tw.WriteLine( "extern {0}_VTABLE_DECL__ {0}_VTABLE__;", declaredType.MangledUniqueName); diff --git a/docs/supported-opcodes.md b/docs/supported-opcodes.md index a425067a..3e8747f5 100644 --- a/docs/supported-opcodes.md +++ b/docs/supported-opcodes.md @@ -18,8 +18,8 @@ OpCode | Binary | Implement | Test | ILConverter | [bge.un.s](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.bge_un_s) | 0x34 | | | | | [bgt](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.bgt) | 0x3d | Implemented | | IL2C.ILConverters.BgtConverter | | [bgt.s](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.bgt_s) | 0x30 | Implemented | | IL2C.ILConverters.Bgt_sConverter | -| [bgt.un](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.bgt_un) | 0x42 | | | | -| [bgt.un.s](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.bgt_un_s) | 0x35 | | | | +| [bgt.un](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.bgt_un) | 0x42 | Implemented | | IL2C.ILConverters.Bgt_UnConverter | +| [bgt.un.s](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.bgt_un_s) | 0x35 | Implemented | | IL2C.ILConverters.Bgt_Un_sConverter | | [ble](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.ble) | 0x3e | Implemented | | IL2C.ILConverters.BleConverter | | [ble.s](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.ble_s) | 0x31 | Implemented | | IL2C.ILConverters.Ble_sConverter | | [ble.un](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.ble_un) | 0x43 | | | | @@ -153,7 +153,7 @@ OpCode | Binary | Implement | Test | ILConverter | [ldloca](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.ldloca) | 0xfe0d | | | | | [ldloca.s](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.ldloca_s) | 0x12 | Implemented | [Test [17]](../tests/IL2C.Core.Test.ILConverters/Ldloca_s) | IL2C.ILConverters.Ldloca_sConverter | | [ldnull](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.ldnull) | 0x14 | Implemented | [Test [3]](../tests/IL2C.Core.Test.ILConverters/Ldnull) | IL2C.ILConverters.LdnullConverter | -| [ldobj](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.ldobj) | 0x71 | | | | +| [ldobj](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.ldobj) | 0x71 | Implemented | [Test [26]](../tests/IL2C.Core.Test.ILConverters/Ldobj) | IL2C.ILConverters.LdobjConverter | | [ldsfld](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.ldsfld) | 0x7e | Implemented | [Test [16]](../tests/IL2C.Core.Test.ILConverters/Ldsfld) | IL2C.ILConverters.LdsfldConverter | | [ldsflda](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.ldsflda) | 0x7f | Implemented | [Test [16]](../tests/IL2C.Core.Test.ILConverters/Ldsflda) | IL2C.ILConverters.LdsfldaConverter | | [ldstr](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.ldstr) | 0x72 | Implemented | [Test [1]](../tests/IL2C.Core.Test.ILConverters/Ldstr) | IL2C.ILConverters.LdstrConverter | @@ -166,12 +166,12 @@ OpCode | Binary | Implement | Test | ILConverter | [mul](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.mul) | 0x5a | Implemented | [Test [9]](../tests/IL2C.Core.Test.ILConverters/Mul) | IL2C.ILConverters.MulConverter | | [mul.ovf](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.mul_ovf) | 0xd8 | | | | | [mul.ovf.un](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.mul_ovf_un) | 0xd9 | | | | -| [neg](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.neg) | 0x65 | | | | +| [neg](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.neg) | 0x65 | Implemented | | IL2C.ILConverters.NegConverter | | [newarr](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.newarr) | 0x8d | Implemented | | IL2C.ILConverters.NewarrConverter | | [newobj](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.newobj) | 0x73 | Implemented | | IL2C.ILConverters.NewobjConverter | | no | 0xfe19 | | | | | [nop](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.nop) | 0x0 | Implemented | [Test [1]](../tests/IL2C.Core.Test.ILConverters/Nop) | IL2C.ILConverters.NopConverter | -| [not](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.not) | 0x66 | | | | +| [not](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.not) | 0x66 | Implemented | | IL2C.ILConverters.NotConverter | | [or](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.or) | 0x60 | Implemented | [Test [5]](../tests/IL2C.Core.Test.ILConverters/Or) | IL2C.ILConverters.OrConverter | | [pop](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.pop) | 0x26 | Implemented | | IL2C.ILConverters.PopConverter | | [readonly](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.readonly) | 0xfe1e | | | | @@ -181,12 +181,12 @@ OpCode | Binary | Implement | Test | ILConverter | [rem.un](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.rem_un) | 0x5e | | | | | [ret](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.ret) | 0x2a | Implemented | [Test [6]](../tests/IL2C.Core.Test.ILConverters/Ret) | IL2C.ILConverters.RetConverter | | [rethrow](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.rethrow) | 0xfe1a | Implemented | | IL2C.ILConverters.RethrowConverter | -| [shl](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.shl) | 0x62 | | | | -| [shr](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.shr) | 0x63 | | | | -| [shr.un](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.shr_un) | 0x64 | | | | +| [shl](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.shl) | 0x62 | Implemented | | IL2C.ILConverters.ShiftLeftConverter | +| [shr](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.shr) | 0x63 | Implemented | [Test [40]](../tests/IL2C.Core.Test.ILConverters/Shr) | IL2C.ILConverters.ShiftRightConverter | +| [shr.un](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.shr_un) | 0x64 | Implemented | [Test [40]](../tests/IL2C.Core.Test.ILConverters/Shr_un) | IL2C.ILConverters.ShiftRightUnConverter | | [sizeof](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.sizeof) | 0xfe1c | Implemented | | IL2C.ILConverters.SizeofConverter | -| [starg](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.starg) | 0xfe0b | | | | -| [starg.s](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.starg_s) | 0x10 | | | | +| [starg](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.starg) | 0xfe0b | Implemented | | IL2C.ILConverters.StargConverter | +| [starg.s](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.starg_s) | 0x10 | Implemented | | IL2C.ILConverters.StargSConverter | | [stelem.any](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.stelem) | 0xa4 | Implemented | [Test [42]](../tests/IL2C.Core.Test.ILConverters/Stelem) | IL2C.ILConverters.Stelem_anyConvertersConverter | | [stelem.i](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.stelem_i) | 0x9b | | | | | [stelem.i1](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.stelem_i1) | 0x9c | Implemented | [Test [6]](../tests/IL2C.Core.Test.ILConverters/Stelem_i1) | IL2C.ILConverters.Stelem_i1ConvertersConverter | @@ -198,12 +198,12 @@ OpCode | Binary | Implement | Test | ILConverter | [stelem.ref](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.stelem_ref) | 0xa2 | Implemented | [Test [6]](../tests/IL2C.Core.Test.ILConverters/Stelem_ref) | IL2C.ILConverters.Stelem_refConvertersConverter | | [stfld](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.stfld) | 0x7d | Implemented | | IL2C.ILConverters.StfldConverter | | [stind.i](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.stind_i) | 0xdf | | | | -| [stind.i1](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.stind_i1) | 0x52 | | | | -| [stind.i2](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.stind_i2) | 0x53 | | | | +| [stind.i1](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.stind_i1) | 0x52 | Implemented | | IL2C.ILConverters.Stind_i1Converter | +| [stind.i2](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.stind_i2) | 0x53 | Implemented | | IL2C.ILConverters.Stind_i2Converter | | [stind.i4](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.stind_i4) | 0x54 | Implemented | | IL2C.ILConverters.Stind_i4Converter | -| [stind.i8](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.stind_i8) | 0x55 | | | | -| [stind.r4](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.stind_r4) | 0x56 | | | | -| [stind.r8](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.stind_r8) | 0x57 | | | | +| [stind.i8](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.stind_i8) | 0x55 | Implemented | | IL2C.ILConverters.Stind_i8Converter | +| [stind.r4](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.stind_r4) | 0x56 | Implemented | | IL2C.ILConverters.Stind_r4Converter | +| [stind.r8](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.stind_r8) | 0x57 | Implemented | | IL2C.ILConverters.Stind_r8Converter | | [stind.ref](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.stind_ref) | 0x51 | Implemented | | IL2C.ILConverters.Stind_RefConverter | | [stloc](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.stloc) | 0xfe0e | | | | | [stloc.0](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.stloc_0) | 0xa | Implemented | [Test [16]](../tests/IL2C.Core.Test.ILConverters/Stloc_0) | IL2C.ILConverters.Stloc_0Converter | @@ -211,12 +211,12 @@ OpCode | Binary | Implement | Test | ILConverter | [stloc.2](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.stloc_2) | 0xc | Implemented | [Test [16]](../tests/IL2C.Core.Test.ILConverters/Stloc_2) | IL2C.ILConverters.Stloc_2Converter | | [stloc.3](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.stloc_3) | 0xd | Implemented | [Test [16]](../tests/IL2C.Core.Test.ILConverters/Stloc_3) | IL2C.ILConverters.Stloc_3Converter | | [stloc.s](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.stloc_s) | 0x13 | Implemented | [Test [17]](../tests/IL2C.Core.Test.ILConverters/Stloc_s) | IL2C.ILConverters.Stloc_SConverter | -| [stobj](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.stobj) | 0x81 | | | | +| [stobj](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.stobj) | 0x81 | Implemented | [Test [26]](../tests/IL2C.Core.Test.ILConverters/Stobj) | IL2C.ILConverters.StobjConverter | | [stsfld](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.stsfld) | 0x80 | Implemented | [Test [16]](../tests/IL2C.Core.Test.ILConverters/Stsfld) | IL2C.ILConverters.StsfldConverter | | [sub](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.sub) | 0x59 | Implemented | [Test [11]](../tests/IL2C.Core.Test.ILConverters/Sub) | IL2C.ILConverters.SubConverter | | [sub.ovf](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.sub_ovf) | 0xda | | | | | [sub.ovf.un](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.sub_ovf_un) | 0xdb | | | | -| [switch](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.switch) | 0x45 | | | | +| [switch](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.switch) | 0x45 | Implemented | [Test [8]](../tests/IL2C.Core.Test.ILConverters/Switch) | IL2C.ILConveters.SwitchConverter | | [tail](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.tailcall) | 0xfe14 | | | | | [throw](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.throw) | 0x7a | Implemented | | IL2C.ILConverters.ThrowConverter | | [unaligned](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.unaligned) | 0xfe12 | | | | diff --git a/docs/supported-runtime-system-features.md b/docs/supported-runtime-system-features.md index ddfb72a1..fd4156de 100644 --- a/docs/supported-runtime-system-features.md +++ b/docs/supported-runtime-system-features.md @@ -12,5 +12,9 @@ Feature | Test | Descrition | Interoperability | [Test [5]](../tests/IL2C.Core.Test.RuntimeSystems/Interoperability) | These tests are verified the IL2C manages interoperability with the P/Invoke adn IL2C/Invoke method and internalcall method. | | Threading | [Test [11]](../tests/IL2C.Core.Test.RuntimeSystems/Threading) | These tests are verified the IL2C can handle threading features. | | TypeInitializer | [Test [15]](../tests/IL2C.Core.Test.RuntimeSystems/TypeInitializer) | These tests are verified the IL2C can handle the type initializer special translation cases. | +| TypeInitializer_Defaults | [Test [16]](../tests/IL2C.Core.Test.RuntimeSystems/TypeInitializer_Defaults) | These tests are verified the IL2C can handle the type initializer special translation cases. | +| TypeInitializer_Non_Static_Class | [Test [15]](../tests/IL2C.Core.Test.RuntimeSystems/TypeInitializer_Non_Static_Class) | These tests are verified the IL2C can handle the type initializer special translation cases. | +| TypeInitializer_Singleton | [Test [2]](../tests/IL2C.Core.Test.RuntimeSystems/TypeInitializer_Singleton) | | +| TypeInitializer_Struct | [Test [15]](../tests/IL2C.Core.Test.RuntimeSystems/TypeInitializer_Struct) | These tests are verified the IL2C can handle the type initializer special translation cases. | | TypeRelations | [Test [95]](../tests/IL2C.Core.Test.RuntimeSystems/TypeRelations) | CLR type system contains single-inheritance class types and multiple-implementation interface types. These tests are verified the IL2C can handle the member methods both simple instance methods and complex overriden virtual methods. | | ValueTypes | [Test [18]](../tests/IL2C.Core.Test.RuntimeSystems/ValueTypes) | Value types are specialized types at the .NET type system. Because the type inherited from the System.ValueType (objref type), all method has the managed pointer at the arg0 and these instances will box and apply the pseudo vptrs. These tests are verified the IL2C can handle value types. | diff --git a/tests/IL2C.Core.Test.Fixture/TestFramework.cs b/tests/IL2C.Core.Test.Fixture/TestFramework.cs index 4f060220..8f244d2e 100644 --- a/tests/IL2C.Core.Test.Fixture/TestFramework.cs +++ b/tests/IL2C.Core.Test.Fixture/TestFramework.cs @@ -407,7 +407,7 @@ await TestUtilities.CopyResourceToStreamAsync( CultureInfo.CurrentCulture = CultureInfo.InvariantCulture; CultureInfo.CurrentUICulture = CultureInfo.InvariantCulture; rawResult = caseInfo.Method.Invoke(null, caseInfo.Arguments); - Assert.AreEqual(caseInfo.Expected, rawResult); + Assert.AreEqual(caseInfo.Expected, rawResult, "Bad MSIL, or test case!"); break; } @@ -439,7 +439,7 @@ await TestUtilities.CopyResourceToStreamAsync( /////////////////////////////////////////////// // Step 4: Verify result. - Assert.AreEqual("Success", sanitized); + Assert.AreEqual("Success", sanitized, "Compiled C code failed!"); } } } diff --git a/tests/IL2C.Core.Test.ILConverters/Ldobj/Ldobj.cs b/tests/IL2C.Core.Test.ILConverters/Ldobj/Ldobj.cs new file mode 100644 index 00000000..1c17baf5 --- /dev/null +++ b/tests/IL2C.Core.Test.ILConverters/Ldobj/Ldobj.cs @@ -0,0 +1,100 @@ +///////////////////////////////////////////////////////////////////////////////////////////////// +// +// IL2C - A translator for ECMA-335 CIL/MSIL to C language. +// Copyright (c) 2016-2019 Kouji Matsui (@kozy_kekyo, @kekyo2) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +///////////////////////////////////////////////////////////////////////////////////////////////// + +using System; +using System.Runtime.CompilerServices; + +namespace IL2C.ILConverters +{ + public struct Point + { + public int X, Y; + public int R, G, B; + + public override string ToString() + { + return $"{X}:{Y} C({R},{G},{B})"; + } + } + [TestCase(byte.MinValue, "Ldobj_test_uint8", byte.MinValue)] + [TestCase(byte.MaxValue, "Ldobj_test_uint8", byte.MaxValue)] + + [TestCase(ushort.MinValue, "Ldobj_test_uint16", ushort.MinValue)] + [TestCase(ushort.MaxValue, "Ldobj_test_uint16", ushort.MaxValue)] + + [TestCase(4, "Ldobj_test_int32", 4)] + [TestCase(1, "Ldobj_test_int32", 1)] + [TestCase(0, "Ldobj_test_int32", 0)] + [TestCase(int.MinValue, "Ldobj_test_int32", int.MinValue)] + [TestCase(int.MaxValue, "Ldobj_test_int32", int.MaxValue)] + + [TestCase(4L, "Ldobj_test_int64", 4L)] + [TestCase(1L, "Ldobj_test_int64", 1L)] + [TestCase(0L, "Ldobj_test_int64", 0L)] + [TestCase(long.MinValue, "Ldobj_test_int64", long.MinValue)] + [TestCase(long.MaxValue, "Ldobj_test_int64", long.MaxValue)] + + [TestCase(ulong.MinValue, "Ldobj_test_uint64", ulong.MinValue)] + [TestCase(ulong.MaxValue, "Ldobj_test_uint64", ulong.MaxValue)] + + [TestCase(0.0F, "Ldobj_test_float", 0.0F)] + [TestCase(-0.001F, "Ldobj_test_float", -0.001F)] + [TestCase(float.MinValue, "Ldobj_test_float", float.MinValue)] + [TestCase(float.MaxValue, "Ldobj_test_float", float.MaxValue)] + + [TestCase(0.0, "Ldobj_test_double", 0.0)] + [TestCase(-0.001, "Ldobj_test_double", -0.001)] + [TestCase(double.MinValue, "Ldobj_test_double", double.MinValue)] + [TestCase(double.MaxValue, "Ldobj_test_double", double.MaxValue)] + + [TestCase("1:2 C(3,4,5)", "Ldobj_test_PointSer", 1, 2, 3, 4, 5, IncludeTypes = new[] { typeof(Ldobj), typeof(Point), typeof(Int32), typeof(Char), typeof(String) })] + [TestCase("20:20 C(255,255,255)", "Ldobj_test_PointSer", 20, 20, 255, 255, 255, IncludeTypes = new[] { typeof(Ldobj), typeof(Point), typeof(Int32), typeof(Char), typeof(String) })] + public sealed class Ldobj + { + [MethodImpl(MethodImplOptions.ForwardRef)] + public static extern byte Ldobj_test_uint8(byte v); + + [MethodImpl(MethodImplOptions.ForwardRef)] + public static extern ushort Ldobj_test_uint16(ushort v); + + [MethodImpl(MethodImplOptions.ForwardRef)] + public static extern int Ldobj_test_int32(int v); + + [MethodImpl(MethodImplOptions.ForwardRef)] + public static extern long Ldobj_test_int64(long v); + + [MethodImpl(MethodImplOptions.ForwardRef)] + public static extern ulong Ldobj_test_uint64(ulong v); + + [MethodImpl(MethodImplOptions.ForwardRef)] + public static extern float Ldobj_test_float(float v); + + [MethodImpl(MethodImplOptions.ForwardRef)] + public static extern double Ldobj_test_double(double v); + + [MethodImpl(MethodImplOptions.ForwardRef)] + public static extern Point Ldobj_test_Point(Point v); + + public static string Ldobj_test_PointSer(int x, int y, int r, int g, int b) + { + var v = new Point() { X = x, Y = y, R = r, G = g, B = b }; + return Ldobj_test_Point(v).ToString(); + } + } +} diff --git a/tests/IL2C.Core.Test.ILConverters/Ldobj/Ldobj.il b/tests/IL2C.Core.Test.ILConverters/Ldobj/Ldobj.il new file mode 100644 index 00000000..a2c7f7c5 --- /dev/null +++ b/tests/IL2C.Core.Test.ILConverters/Ldobj/Ldobj.il @@ -0,0 +1,66 @@ +.class public IL2C.ILConverters.Ldobj +{ + .method public static uint8 Ldobj_test_uint8(uint8 v) cil managed + { + .maxstack 1 + ldarga.s 0 + ldobj [mscorlib]System.Byte + ret + } + .method public static uint16 Ldobj_test_uint16(uint16 v) cil managed + { + .maxstack 1 + ldarga.s 0 + ldobj [mscorlib]System.UInt16 + ret + } + + .method public static int32 Ldobj_test_int32(int32 v) cil managed + { + .maxstack 1 + ldarga.s 0 + ldobj [mscorlib]System.Int32 + ret + } + + .method public static int64 Ldobj_test_int64(int64 v) cil managed + { + .maxstack 1 + ldarga.s 0 + ldobj [mscorlib]System.Int64 + ret + } + + .method public static uint64 Ldobj_test_uint64(uint64 v) cil managed + { + .maxstack 1 + ldarga.s 0 + ldobj [mscorlib]System.UInt64 + ret + } + + .method public static float32 Ldobj_test_float(float32 v) cil managed + { + .maxstack 1 + ldarga.s 0 + ldobj [mscorlib]System.Single + ret + } + + .method public static float64 Ldobj_test_double(float64 v) cil managed + { + .maxstack 1 + ldarga.s 0 + ldobj [mscorlib]System.Double + ret + } + + .method public static valuetype IL2C.ILConverters.Point Ldobj_test_Point(valuetype IL2C.ILConverters.Point v) cil managed + { + .maxstack 1 + ldarga.s 0 + ldobj valuetype IL2C.ILConverters.Point + ret + } + +} diff --git a/tests/IL2C.Core.Test.ILConverters/Not/Not.cs b/tests/IL2C.Core.Test.ILConverters/Not/Not.cs new file mode 100644 index 00000000..11341003 --- /dev/null +++ b/tests/IL2C.Core.Test.ILConverters/Not/Not.cs @@ -0,0 +1,55 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.CompilerServices; +using System.Text; +using System.Threading.Tasks; + +namespace IL2C.ILConverters +{ + // Breaks unit testing framework??? + //[TestCase(~(sbyte)0x12, "Not_int8", (sbyte)0x12)] + //[TestCase(~(byte)0x12, "Not_uint8", (byte)0x12)] + //[TestCase(~(short)0x1234, "Not_int16", (short)0x1234)] + //[TestCase(~(ushort)0x1234, "Not_uint16", (ushort)0x1234)] + [TestCase(~(int)0x12345678, "Not_int32", (int)0x12345678)] + [TestCase(~(uint)0x12345678, "Not_uint32", (uint)0x12345678)] + [TestCase(~(long)0x12345678, "Not_int64", (long)0x12345678)] + [TestCase(~(ulong)0x12345678, "Not_uint64", (ulong)0x12345678)] + // If I implement in IL, whole testing system goes down. + // C# compiler says: CS0023: Operator '~' cannot be applied to operand of type 'IntPtr' + //[TestCase(~IntPtr.Zero, "not_intptr", 0)] + //[TestCase(-1, "not_uintptr", (uint)0)] + public sealed class Not + { + [MethodImpl(MethodImplOptions.ForwardRef)] + public static extern sbyte Not_int8(sbyte v); + + [MethodImpl(MethodImplOptions.ForwardRef)] + public static extern byte Not_uint8(byte v); + + [MethodImpl(MethodImplOptions.ForwardRef)] + public static extern short Not_int16(short v); + + [MethodImpl(MethodImplOptions.ForwardRef)] + public static extern ushort Not_uint16(short v); + + [MethodImpl(MethodImplOptions.ForwardRef)] + public static extern int Not_int32(int v); + + [MethodImpl(MethodImplOptions.ForwardRef)] + public static extern uint Not_uint32(uint v); + + [MethodImpl(MethodImplOptions.ForwardRef)] + public static extern long Not_int64(long v); + + [MethodImpl(MethodImplOptions.ForwardRef)] + public static extern ulong Not_uint64(ulong v); + + //[MethodImpl(MethodImplOptions.ForwardRef)] + //public static extern IntPtr Not_IntPtr(int v); + + //[MethodImpl(MethodImplOptions.ForwardRef)] + //public static extern UIntPtr Not_UIntPtr(uint v); + } +} diff --git a/tests/IL2C.Core.Test.ILConverters/Not/Not.il b/tests/IL2C.Core.Test.ILConverters/Not/Not.il new file mode 100644 index 00000000..3ae7f271 --- /dev/null +++ b/tests/IL2C.Core.Test.ILConverters/Not/Not.il @@ -0,0 +1,34 @@ +.class public IL2C.ILConverters.Not +{ + .method public static int32 Not_int32(int32 v) cil managed + { + .maxstack 1 + ldarg.0 + not + ret + } + + .method public static uint32 Not_uint32(uint32 v) cil managed + { + .maxstack 1 + ldarg.0 + not + ret + } + + .method public static int64 Not_int64(int64 v) cil managed + { + .maxstack 1 + ldarg.0 + not + ret + } + + .method public static uint64 Not_uint64(uint64 v) cil managed + { + .maxstack 1 + ldarg.0 + not + ret + } +} diff --git a/tests/IL2C.Core.Test.ILConverters/Shr/Shr.cs b/tests/IL2C.Core.Test.ILConverters/Shr/Shr.cs new file mode 100644 index 00000000..89d8a907 --- /dev/null +++ b/tests/IL2C.Core.Test.ILConverters/Shr/Shr.cs @@ -0,0 +1,100 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.CompilerServices; +using System.Text; +using System.Threading.Tasks; + +namespace IL2C.ILConverters +{ + // Arithmetic Shift right (with sign) + // Warning!!! MSIL always operates for bit storage on Int32, or Int64 + // and as it seems, smaller unsigned values (uint8 & uint16) will never + // be able to set the int32 highest bit => they will operate as logical shift right. + // On the other hand: uint32 and uint64 are still operated as arithmetic shift. + [TestCase((byte)123, "ShrByte", (byte)123, 0)] + [TestCase((byte)0, "ShrByte", (byte)1, 1)] + [TestCase((byte)(Byte.MaxValue - 1) / 2, "ShrByte", (byte)Byte.MaxValue, 1)] + [TestCase((byte)(Byte.MaxValue - 1) / 4, "ShrByte", (byte)Byte.MaxValue, 2)] + + [TestCase((sbyte)123, "ShrSByte", (sbyte)123, 0)] + [TestCase((sbyte)0, "ShrSByte", (sbyte)1, 1)] + [TestCase((sbyte)-1, "ShrSByte", (sbyte)-1, 1)] + [TestCase((sbyte)-1, "ShrSByte", (sbyte)-5, 10)] + [TestCase((sbyte)(SByte.MaxValue - 1) / 2, "ShrSByte", (sbyte)SByte.MaxValue, 1)] + [TestCase((sbyte)(SByte.MaxValue - 1) / 4, "ShrSByte", (sbyte)SByte.MaxValue, 2)] + + [TestCase((short)123, "ShrShort", (short)123, 0)] + [TestCase((short)0, "ShrShort", (short)1, 1)] + [TestCase((short)-1, "ShrShort", (short)-1, 1)] + [TestCase((short)-1, "ShrShort", (short)-5, 10)] + [TestCase((short)(Int16.MaxValue - 1) / 2, "ShrShort", (short)Int16.MaxValue, 1)] + [TestCase((short)(Int16.MaxValue - 1) / 4, "ShrShort", (short)Int16.MaxValue, 2)] + + [TestCase((ushort)123, "ShrUshort", (ushort)123, 0)] + [TestCase((ushort)0, "ShrUshort", (ushort)1, 1)] + [TestCase((ushort)(UInt16.MaxValue - 1) / 2, "ShrUshort", (ushort)UInt16.MaxValue, 1)] + [TestCase((ushort)(UInt16.MaxValue - 1) / 4, "ShrUshort", (ushort)UInt16.MaxValue, 2)] + + [TestCase((int)123, "ShrInt", (int)123, 0)] + [TestCase((int)0, "ShrInt", (int)1, 1)] + [TestCase((int)-1, "ShrInt", (int)-1, 1)] + [TestCase((int)-1, "ShrInt", (int)-5, 10)] + [TestCase((int)(Int32.MaxValue - 1) / 2, "ShrInt", (int)Int32.MaxValue, 1)] + [TestCase((int)(Int32.MaxValue - 1) / 4, "ShrInt", (int)Int32.MaxValue, 2)] + + [TestCase((uint)123, "ShrUInt", (uint)123, 0)] + [TestCase((uint)0, "ShrUInt", (uint)1, 1)] + [TestCase((uint)UInt32.MaxValue, "ShrUInt", (uint)UInt32.MaxValue, 1)] + [TestCase((uint)UInt32.MaxValue, "ShrUInt", (uint)UInt32.MaxValue, 2)] + + [TestCase((long)123, "ShrLong", (long)123, 0)] + [TestCase((long)0, "ShrLong", (long)1, 1)] + [TestCase((long)-1, "ShrLong", (long)-1, 1)] + [TestCase((long)-1, "ShrLong", (long)-5, 10)] + [TestCase((long)(Int64.MaxValue - 1) / 2, "ShrLong", (long)Int64.MaxValue, 1)] + [TestCase((long)(Int64.MaxValue - 1) / 4, "ShrLong", (long)Int64.MaxValue, 2)] + + [TestCase((ulong)123, "ShrUlong", (ulong)123, 0)] + [TestCase((ulong)0, "ShrUlong", (ulong)1, 1)] + [TestCase((ulong)UInt64.MaxValue, "ShrUlong", (ulong)UInt64.MaxValue, 1)] + [TestCase((ulong)UInt64.MaxValue, "ShrUlong", (ulong)UInt64.MaxValue, 2)] + + //[TestCase((int)(Int32.MaxValue - 1) / 2, "ShrIntByIntptr", (int)Int32.MaxValue, 1)] + //[TestCase((int)(Int32.MaxValue - 1) / 4, "ShrIntByIntptr", (int)Int32.MaxValue, 2)] + + //[TestCase((long)(Int64.MaxValue - 1) / 2, "ShrUlongByUIntptr", (long)Int64.MaxValue, 1)] + //[TestCase((long)(Int64.MaxValue - 1) / 4, "ShrUlongByUIntptr", (long)Int64.MaxValue, 2)] + public sealed class Shr + { + [MethodImpl(MethodImplOptions.ForwardRef)] + public static extern byte ShrByte(byte v, int num); + + [MethodImpl(MethodImplOptions.ForwardRef)] + public static extern sbyte ShrSByte(sbyte v, int num); + + [MethodImpl(MethodImplOptions.ForwardRef)] + public static extern short ShrShort(short v, int num); + + [MethodImpl(MethodImplOptions.ForwardRef)] + public static extern ushort ShrUshort(ushort v, int num); + + [MethodImpl(MethodImplOptions.ForwardRef)] + public static extern int ShrInt(int v, int num); + + [MethodImpl(MethodImplOptions.ForwardRef)] + public static extern uint ShrUInt(uint v, int num); + + [MethodImpl(MethodImplOptions.ForwardRef)] + public static extern long ShrLong(long v, int num); + + [MethodImpl(MethodImplOptions.ForwardRef)] + public static extern ulong ShrUlong(ulong v, int num); + + //[MethodImpl(MethodImplOptions.ForwardRef)] + //public static extern int ShrIntByIntptr(int v, IntPtr num); + + //[MethodImpl(MethodImplOptions.ForwardRef)] + //public static extern ulong ShrUlongByUIntptr(ulong v, UIntPtr num); + } +} diff --git a/tests/IL2C.Core.Test.ILConverters/Shr/Shr.il b/tests/IL2C.Core.Test.ILConverters/Shr/Shr.il new file mode 100644 index 00000000..71bf892d --- /dev/null +++ b/tests/IL2C.Core.Test.ILConverters/Shr/Shr.il @@ -0,0 +1,93 @@ +.class public IL2C.ILConverters.Shr +{ + .method public static uint8 ShrByte(uint8 v, int32 num) cil managed + { + .maxstack 2 + ldarg.0 + ldarg.1 + shr + ret + } + + .method public static int8 ShrSByte(int8 v, int32 num) cil managed + { + .maxstack 2 + ldarg.0 + ldarg.1 + shr + ret + } + + .method public static int16 ShrShort(int16 v, int32 num) cil managed + { + .maxstack 2 + ldarg.0 + ldarg.1 + shr + ret + } + + .method public static uint16 ShrUshort(uint16 v, int32 num) cil managed + { + .maxstack 2 + ldarg.0 + ldarg.1 + shr + ret + } + + .method public static int32 ShrInt(int32 v, int32 num) cil managed + { + .maxstack 2 + ldarg.0 + ldarg.1 + shr + ret + } + + .method public static uint32 ShrUInt(uint32 v, int32 num) cil managed + { + .maxstack 2 + ldarg.0 + ldarg.1 + shr + ret + } + + .method public static int64 ShrLong(int64 v, int32 num) cil managed + { + .maxstack 2 + ldarg.0 + ldarg.1 + shr + ret + } + + .method public static uint64 ShrUlong(uint64 v, int32 num) cil managed + { + .maxstack 2 + ldarg.0 + ldarg.1 + shr + ret + } + /* + .method public static int32 ShrIntByIntptr(int32 v, native int num) cil managed + { + .maxstack 2 + ldarg.0 + ldarg.1 + shr + ret + } + + .method public static uint64 ShrUlongByUIntptr(uint64 v, native uint num) cil managed + { + .maxstack 2 + ldarg.0 + ldarg.1 + shr + ret + } + */ +} diff --git a/tests/IL2C.Core.Test.ILConverters/Shr_un/Shr_un.cs b/tests/IL2C.Core.Test.ILConverters/Shr_un/Shr_un.cs new file mode 100644 index 00000000..ae5f8eb4 --- /dev/null +++ b/tests/IL2C.Core.Test.ILConverters/Shr_un/Shr_un.cs @@ -0,0 +1,84 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.CompilerServices; +using System.Text; +using System.Threading.Tasks; + +namespace IL2C.ILConverters +{ + // Logical Shift right (without sign) + [TestCase((byte)123, "ShrByte", (byte)123, 0)] + [TestCase((byte)0, "ShrByte", (byte)1, 1)] + [TestCase((byte)(Byte.MaxValue - 1) / 2, "ShrByte", (byte)Byte.MaxValue, 1)] + [TestCase((byte)(Byte.MaxValue - 1) / 4, "ShrByte", (byte)Byte.MaxValue, 2)] + + [TestCase((sbyte)123, "ShrSByte", (sbyte)123, 0)] + [TestCase((sbyte)0, "ShrSByte", (sbyte)1, 1)] + [TestCase((sbyte)-1, "ShrSByte", (sbyte)-1, 1)] + [TestCase((sbyte)-1, "ShrSByte", (sbyte)-5, 10)] + [TestCase((sbyte)(SByte.MaxValue - 1) / 2, "ShrSByte", (sbyte)SByte.MaxValue, 1)] + [TestCase((sbyte)(SByte.MaxValue - 1) / 4, "ShrSByte", (sbyte)SByte.MaxValue, 2)] + + [TestCase((short)123, "ShrShort", (short)123, 0)] + [TestCase((short)0, "ShrShort", (short)1, 1)] + [TestCase((short)-1, "ShrShort", (short)-1, 1)] + [TestCase((short)-1, "ShrShort", (short)-5, 10)] + [TestCase((short)(Int16.MaxValue - 1) / 2, "ShrShort", (short)Int16.MaxValue, 1)] + [TestCase((short)(Int16.MaxValue - 1) / 4, "ShrShort", (short)Int16.MaxValue, 2)] + + [TestCase((ushort)123, "ShrUshort", (ushort)123, 0)] + [TestCase((ushort)0, "ShrUshort", (ushort)1, 1)] + [TestCase((ushort)(UInt16.MaxValue - 1) / 2, "ShrUshort", (ushort)UInt16.MaxValue, 1)] + [TestCase((ushort)(UInt16.MaxValue - 1) / 4, "ShrUshort", (ushort)UInt16.MaxValue, 2)] + + [TestCase((int)123, "ShrInt", (int)123, 0)] + [TestCase((int)0, "ShrInt", (int)1, 1)] + [TestCase((int)0x7FFFFFFF, "ShrInt", (int)-1, 1)] + [TestCase((int)0x003FFFFF, "ShrInt", (int)-5, 10)] + [TestCase((int)(Int32.MaxValue - 1) / 2, "ShrInt", (int)Int32.MaxValue, 1)] + [TestCase((int)(Int32.MaxValue - 1) / 4, "ShrInt", (int)Int32.MaxValue, 2)] + + [TestCase((uint)123, "ShrUInt", (uint)123, 0)] + [TestCase((uint)0, "ShrUInt", (uint)1, 1)] + [TestCase((uint)0x7FFFFFFF, "ShrUInt", (uint)UInt32.MaxValue, 1)] + [TestCase((uint)0x3FFFFFFF, "ShrUInt", (uint)UInt32.MaxValue, 2)] + + [TestCase((long)123, "ShrLong", (long)123, 0)] + [TestCase((long)0, "ShrLong", (long)1, 1)] + [TestCase((long)0x7FFFFFFFFFFFFFFF, "ShrLong", (long)-1, 1)] + [TestCase((long)0x003FFFFFFFFFFFFF, "ShrLong", (long)-5, 10)] + [TestCase((long)(Int64.MaxValue - 1) / 2, "ShrLong", (long)Int64.MaxValue, 1)] + [TestCase((long)(Int64.MaxValue - 1) / 4, "ShrLong", (long)Int64.MaxValue, 2)] + + [TestCase((ulong)123, "ShrUlong", (ulong)123, 0)] + [TestCase((ulong)0, "ShrUlong", (ulong)1, 1)] + [TestCase((ulong)0x7FFFFFFFFFFFFFFF, "ShrUlong", (ulong)UInt64.MaxValue, 1)] + [TestCase((ulong)0x3FFFFFFFFFFFFFFF, "ShrUlong", (ulong)UInt64.MaxValue, 2)] + public sealed class Shr_un + { + [MethodImpl(MethodImplOptions.ForwardRef)] + public static extern byte ShrByte(byte v, int num); + + [MethodImpl(MethodImplOptions.ForwardRef)] + public static extern sbyte ShrSByte(sbyte v, int num); + + [MethodImpl(MethodImplOptions.ForwardRef)] + public static extern short ShrShort(short v, int num); + + [MethodImpl(MethodImplOptions.ForwardRef)] + public static extern ushort ShrUshort(ushort v, int num); + + [MethodImpl(MethodImplOptions.ForwardRef)] + public static extern int ShrInt(int v, int num); + + [MethodImpl(MethodImplOptions.ForwardRef)] + public static extern uint ShrUInt(uint v, int num); + + [MethodImpl(MethodImplOptions.ForwardRef)] + public static extern long ShrLong(long v, int num); + + [MethodImpl(MethodImplOptions.ForwardRef)] + public static extern ulong ShrUlong(ulong v, int num); + } +} diff --git a/tests/IL2C.Core.Test.ILConverters/Shr_un/Shr_un.il b/tests/IL2C.Core.Test.ILConverters/Shr_un/Shr_un.il new file mode 100644 index 00000000..bc362534 --- /dev/null +++ b/tests/IL2C.Core.Test.ILConverters/Shr_un/Shr_un.il @@ -0,0 +1,74 @@ +.class public IL2C.ILConverters.Shr_un +{ + .method public static uint8 ShrByte(uint8 v, int32 num) cil managed + { + .maxstack 2 + ldarg.0 + ldarg.1 + shr.un + ret + } + + .method public static int8 ShrSByte(int8 v, int32 num) cil managed + { + .maxstack 2 + ldarg.0 + ldarg.1 + shr.un + ret + } + + .method public static int16 ShrShort(int16 v, int32 num) cil managed + { + .maxstack 2 + ldarg.0 + ldarg.1 + shr.un + ret + } + + .method public static uint16 ShrUshort(uint16 v, int32 num) cil managed + { + .maxstack 2 + ldarg.0 + ldarg.1 + shr.un + ret + } + + .method public static int32 ShrInt(int32 v, int32 num) cil managed + { + .maxstack 2 + ldarg.0 + ldarg.1 + shr.un + ret + } + + .method public static uint32 ShrUInt(uint32 v, int32 num) cil managed + { + .maxstack 2 + ldarg.0 + ldarg.1 + shr.un + ret + } + + .method public static int64 ShrLong(int64 v, int32 num) cil managed + { + .maxstack 2 + ldarg.0 + ldarg.1 + shr.un + ret + } + + .method public static uint64 ShrUlong(uint64 v, int32 num) cil managed + { + .maxstack 2 + ldarg.0 + ldarg.1 + shr.un + ret + } +} diff --git a/tests/IL2C.Core.Test.ILConverters/Stobj/Stobj.cs b/tests/IL2C.Core.Test.ILConverters/Stobj/Stobj.cs new file mode 100644 index 00000000..f528c86d --- /dev/null +++ b/tests/IL2C.Core.Test.ILConverters/Stobj/Stobj.cs @@ -0,0 +1,134 @@ +///////////////////////////////////////////////////////////////////////////////////////////////// +// +// IL2C - A translator for ECMA-335 CIL/MSIL to C language. +// Copyright (c) 2016-2019 Kouji Matsui (@kozy_kekyo, @kekyo2) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +///////////////////////////////////////////////////////////////////////////////////////////////// + +using System; +using System.Runtime.CompilerServices; + +namespace IL2C.ILConverters +{ + [TestCase(byte.MinValue, "Stobj_test_uint8Tst", byte.MinValue, IncludeTypes = new[] { typeof(Stobj), typeof(Point) })] + [TestCase(byte.MaxValue, "Stobj_test_uint8Tst", byte.MaxValue, IncludeTypes = new[] { typeof(Stobj), typeof(Point) })] + + [TestCase(ushort.MinValue, "Stobj_test_uint16Tst", ushort.MinValue, IncludeTypes = new[] { typeof(Stobj), typeof(Point) })] + [TestCase(ushort.MaxValue, "Stobj_test_uint16Tst", ushort.MaxValue, IncludeTypes = new[] { typeof(Stobj), typeof(Point) })] + + [TestCase(4, "Stobj_test_int32Tst", 4, IncludeTypes = new[] { typeof(Stobj), typeof(Point) })] + [TestCase(1, "Stobj_test_int32Tst", 1, IncludeTypes = new[] { typeof(Stobj), typeof(Point) })] + [TestCase(0, "Stobj_test_int32Tst", 0, IncludeTypes = new[] { typeof(Stobj), typeof(Point) })] + [TestCase(int.MinValue, "Stobj_test_int32Tst", int.MinValue, IncludeTypes = new[] { typeof(Stobj), typeof(Point) })] + [TestCase(int.MaxValue, "Stobj_test_int32Tst", int.MaxValue, IncludeTypes = new[] { typeof(Stobj), typeof(Point) })] + + [TestCase(4L, "Stobj_test_int64Tst", 4L, IncludeTypes = new[] { typeof(Stobj), typeof(Point) })] + [TestCase(1L, "Stobj_test_int64Tst", 1L, IncludeTypes = new[] { typeof(Stobj), typeof(Point) })] + [TestCase(0L, "Stobj_test_int64Tst", 0L, IncludeTypes = new[] { typeof(Stobj), typeof(Point) })] + [TestCase(long.MinValue, "Stobj_test_int64Tst", long.MinValue, IncludeTypes = new[] { typeof(Stobj), typeof(Point) })] + [TestCase(long.MaxValue, "Stobj_test_int64Tst", long.MaxValue, IncludeTypes = new[] { typeof(Stobj), typeof(Point) })] + + [TestCase(ulong.MinValue, "Stobj_test_uint64Tst", ulong.MinValue, IncludeTypes = new[] { typeof(Stobj), typeof(Point) })] + [TestCase(ulong.MaxValue, "Stobj_test_uint64Tst", ulong.MaxValue, IncludeTypes = new[] { typeof(Stobj), typeof(Point) })] + + [TestCase(0.0F, "Stobj_test_floatTst", 0.0F, IncludeTypes = new[] { typeof(Stobj), typeof(Point) })] + [TestCase(-0.001F, "Stobj_test_floatTst", -0.001F, IncludeTypes = new[] { typeof(Stobj), typeof(Point) })] + [TestCase(float.MinValue, "Stobj_test_floatTst", float.MinValue, IncludeTypes = new[] { typeof(Stobj), typeof(Point) })] + [TestCase(float.MaxValue, "Stobj_test_floatTst", float.MaxValue, IncludeTypes = new[] { typeof(Stobj), typeof(Point) })] + + [TestCase(0.0, "Stobj_test_doubleTst", 0.0, IncludeTypes = new[] { typeof(Stobj), typeof(Point) })] + [TestCase(-0.001, "Stobj_test_doubleTst", -0.001, IncludeTypes = new[] { typeof(Stobj), typeof(Point) })] + [TestCase(double.MinValue, "Stobj_test_doubleTst", double.MinValue, IncludeTypes = new[] { typeof(Stobj), typeof(Point) })] + [TestCase(double.MaxValue, "Stobj_test_doubleTst", double.MaxValue, IncludeTypes = new[] { typeof(Stobj), typeof(Point) })] + + [TestCase("1:2 C(3,4,5)", "Stobj_test_PointSer", 1, 2, 3, 4, 5, IncludeTypes = new[] { typeof(Stobj), typeof(Point), typeof(Int32), typeof(Char), typeof(String) })] + [TestCase("20:20 C(255,255,255)", "Stobj_test_PointSer", 20, 20, 255, 255, 255, IncludeTypes = new[] { typeof(Stobj), typeof(Point), typeof(Int32), typeof(Char), typeof(String) })] + public sealed class Stobj + { + [MethodImpl(MethodImplOptions.ForwardRef)] + public static extern void Stobj_test_uint8(byte v, out byte result); + + public static byte Stobj_test_uint8Tst(byte v) + { + Stobj_test_uint8(v, out byte result); + return result; + } + + [MethodImpl(MethodImplOptions.ForwardRef)] + public static extern void Stobj_test_uint16(ushort v, out ushort result); + + public static ushort Stobj_test_uint16Tst(ushort v) + { + Stobj_test_uint16(v, out ushort result); + return result; + } + + [MethodImpl(MethodImplOptions.ForwardRef)] + public static extern void Stobj_test_int32(int v, out int result); + + public static int Stobj_test_int32Tst(int v) + { + Stobj_test_int32(v, out int result); + return result; + } + + [MethodImpl(MethodImplOptions.ForwardRef)] + public static extern void Stobj_test_int64(long v, out long result); + + public static long Stobj_test_int64Tst(long v) + { + Stobj_test_int64(v, out long result); + return result; + } + + [MethodImpl(MethodImplOptions.ForwardRef)] + public static extern void Stobj_test_uint64(ulong v, out ulong result); + + public static ulong Stobj_test_uint64Tst(ulong v) + { + Stobj_test_uint64(v, out ulong result); + return result; + } + + [MethodImpl(MethodImplOptions.ForwardRef)] + public static extern void Stobj_test_float(float v, out float result); + + public static float Stobj_test_floatTst(float v) + { + Stobj_test_float(v, out float result); + return result; + } + + [MethodImpl(MethodImplOptions.ForwardRef)] + public static extern void Stobj_test_double(double v, out double result); + + public static double Stobj_test_doubleTst(double v) + { + Stobj_test_double(v, out double result); + return result; + } + + [MethodImpl(MethodImplOptions.ForwardRef)] + public static extern void Stobj_test_Point(Point v, out Point result); + + public static string Stobj_test_PointSer(int x, int y, int r, int g, int b) + { + var v = new Point() { X = x, Y = y, R = r, G = g, B = b }; + Stobj_test_Point(v, out Point result); + return result.ToString(); + } + + } +} diff --git a/tests/IL2C.Core.Test.ILConverters/Stobj/Stobj.il b/tests/IL2C.Core.Test.ILConverters/Stobj/Stobj.il new file mode 100644 index 00000000..f4facd70 --- /dev/null +++ b/tests/IL2C.Core.Test.ILConverters/Stobj/Stobj.il @@ -0,0 +1,74 @@ +.class public IL2C.ILConverters.Stobj +{ + .method public static void Stobj_test_uint8(uint8 v, [out] uint8& result) cil managed + { + .maxstack 2 + ldarg.s 1 + ldarg.s 0 + stobj [mscorlib]System.Byte + ret + } + + .method public static void Stobj_test_uint16(uint16 v, [out] uint16& result) cil managed + { + .maxstack 2 + ldarg.s 1 + ldarg.s 0 + stobj [mscorlib]System.UInt16 + ret + } + + .method public static void Stobj_test_int32(int32 v, [out] int32& result) cil managed + { + .maxstack 2 + ldarg.s 1 + ldarg.s 0 + stobj [mscorlib]System.Int32 + ret + } + + .method public static void Stobj_test_int64(int64 v, [out] int64& result) cil managed + { + .maxstack 2 + ldarg.s 1 + ldarg.s 0 + stobj [mscorlib]System.Int64 + ret + } + + .method public static void Stobj_test_uint64(uint64 v, [out] uint64& result) cil managed + { + .maxstack 2 + ldarg.s 1 + ldarg.s 0 + stobj [mscorlib]System.UInt64 + ret + } + + .method public static void Stobj_test_float(float32 v, [out] float32& result) cil managed + { + .maxstack 2 + ldarg.s 1 + ldarg.s 0 + stobj [mscorlib]System.Single + ret + } + + .method public static void Stobj_test_double(float64 v, [out] float64& result) cil managed + { + .maxstack 2 + ldarg.s 1 + ldarg.s 0 + stobj [mscorlib]System.Double + ret + } + + .method public static void Stobj_test_Point(valuetype IL2C.ILConverters.Point v, [out] valuetype IL2C.ILConverters.Point& result) cil managed + { + .maxstack 2 + ldarg.s 1 + ldarg.s 0 + stobj IL2C.ILConverters.Point + ret + } +} diff --git a/tests/IL2C.Core.Test.ILConverters/Switch/Switch.cs b/tests/IL2C.Core.Test.ILConverters/Switch/Switch.cs new file mode 100644 index 00000000..98fdccfa --- /dev/null +++ b/tests/IL2C.Core.Test.ILConverters/Switch/Switch.cs @@ -0,0 +1,38 @@ +///////////////////////////////////////////////////////////////////////////////////////////////// +// +// IL2C - A translator for ECMA-335 CIL/MSIL to C language. +// Copyright (c) 2016-2019 Kouji Matsui (@kozy_kekyo, @kekyo2) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +///////////////////////////////////////////////////////////////////////////////////////////////// + +using System; +using System.Runtime.CompilerServices; + +namespace IL2C.ILConverters +{ + [TestCase((string)"0", "TestSwitch", (int)0)] + [TestCase((string)"1", "TestSwitch", (int)1)] + [TestCase((string)"2", "TestSwitch", (int)2)] + [TestCase((string)"3", "TestSwitch", (int)3)] + [TestCase((string)"Out of range", "TestSwitch", (int)-1)] + [TestCase((string)"Out of range", "TestSwitch", (int)4)] + [TestCase((string)"Out of range", "TestSwitch", (int)int.MinValue)] + [TestCase((string)"Out of range", "TestSwitch", (int)int.MaxValue)] + public sealed class Switch + { + [MethodImpl(MethodImplOptions.ForwardRef)] + public static extern string TestSwitch(int v); + } +} diff --git a/tests/IL2C.Core.Test.ILConverters/Switch/Switch.il b/tests/IL2C.Core.Test.ILConverters/Switch/Switch.il new file mode 100644 index 00000000..88fb042e --- /dev/null +++ b/tests/IL2C.Core.Test.ILConverters/Switch/Switch.il @@ -0,0 +1,23 @@ +.class public IL2C.ILConverters.Switch +{ + .method public static string TestSwitch(int32 v) cil managed + { + .maxstack 1 + ldarg.0 + switch (label0, label1, label2, label3) + ldstr "Out of range" + ret +label0: + ldstr "0" + ret +label1: + ldstr "1" + ret +label2: + ldstr "2" + ret +label3: + ldstr "3" + ret + } +} diff --git a/tests/IL2C.Core.Test.RuntimeSystems/TypeInitializer/TypeInitializer_DefaultValues.cs b/tests/IL2C.Core.Test.RuntimeSystems/TypeInitializer/TypeInitializer_DefaultValues.cs new file mode 100644 index 00000000..fd1150f4 --- /dev/null +++ b/tests/IL2C.Core.Test.RuntimeSystems/TypeInitializer/TypeInitializer_DefaultValues.cs @@ -0,0 +1,136 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace IL2C.RuntimeSystems +{ + public static class TypeInitializer_DefaultValues_Field + { + public static bool BooleanValue = true; + public static readonly byte ByteValue = 10; + public static short Int16Value = 10; + public static readonly int Int32Value = 10; + public static readonly long Int64Value = 10; + public static readonly sbyte SByteValue = 10; + public static readonly ushort UInt16Value = 10; + public static uint UInt32Value = 10; + public static readonly ulong UInt64Value = 10; + public static readonly IntPtr IntPtrValue = (IntPtr)10; + public static UIntPtr UIntPtrValue = (UIntPtr)10; + public static readonly float SingleValue = 10.0f; + public static readonly double DoubleValue = 10.0; + public static readonly char CharValue = 'X'; + public static string StringValue = "StringValue"; + public static int[] Array = new[] { 1, 2, 3 }; + } + + [TestId("TypeInitializer_Defaults")] + [Description("These tests are verified the IL2C can handle the type initializer special translation cases.")] + [TestCase(true, "Bool", IncludeTypes = new[] { typeof(TypeInitializer_DefaultValues_Field) })] + [TestCase((byte)10, "Byte", IncludeTypes = new[] { typeof(TypeInitializer_DefaultValues_Field) })] + [TestCase((short)10, "Int16", IncludeTypes = new[] { typeof(TypeInitializer_DefaultValues_Field) })] + [TestCase((int)10, "Int32", IncludeTypes = new[] { typeof(TypeInitializer_DefaultValues_Field) })] + [TestCase((long)10, "Int64", IncludeTypes = new[] { typeof(TypeInitializer_DefaultValues_Field) })] + [TestCase((sbyte)10, "SByte", IncludeTypes = new[] { typeof(TypeInitializer_DefaultValues_Field) })] + [TestCase((ushort)10, "UInt16", IncludeTypes = new[] { typeof(TypeInitializer_DefaultValues_Field) })] + [TestCase((uint)10, "UInt32", IncludeTypes = new[] { typeof(TypeInitializer_DefaultValues_Field) })] + [TestCase((ulong)10, "UInt64", IncludeTypes = new[] { typeof(TypeInitializer_DefaultValues_Field) })] + [TestCase((int)10, "IntPtr", IncludeTypes = new[] { typeof(TypeInitializer_DefaultValues_Field) })] + [TestCase((uint)10, "UIntPtr", IncludeTypes = new[] { typeof(TypeInitializer_DefaultValues_Field) })] + [TestCase((float)10f, "Single", IncludeTypes = new[] { typeof(TypeInitializer_DefaultValues_Field) })] + [TestCase((double)10f, "Double", IncludeTypes = new[] { typeof(TypeInitializer_DefaultValues_Field) })] + [TestCase((char)'X', "Char", IncludeTypes = new[] { typeof(TypeInitializer_DefaultValues_Field) })] + [TestCase("StringValue", "String", IncludeTypes = new[] { typeof(TypeInitializer_DefaultValues_Field) })] + [TestCase(true, "Array", IncludeTypes = new[] { typeof(TypeInitializer_DefaultValues_Field) })] + public sealed class TypeInitializer_DefaultValues + { + public static bool Bool() + { + return TypeInitializer_DefaultValues_Field.BooleanValue; + } + + public static byte Byte() + { + return TypeInitializer_DefaultValues_Field.ByteValue; + } + + public static short Int16() + { + return TypeInitializer_DefaultValues_Field.Int16Value; + } + + public static int Int32() + { + return TypeInitializer_DefaultValues_Field.Int32Value; + } + + public static long Int64() + { + return TypeInitializer_DefaultValues_Field.Int64Value; + } + + public static sbyte SByte() + { + return TypeInitializer_DefaultValues_Field.SByteValue; + } + + public static ushort UInt16() + { + return TypeInitializer_DefaultValues_Field.UInt16Value; + } + + public static uint UInt32() + { + return TypeInitializer_DefaultValues_Field.UInt32Value; + } + + public static ulong UInt64() + { + return TypeInitializer_DefaultValues_Field.UInt64Value; + } + + public static IntPtr IntPtr() + { + return TypeInitializer_DefaultValues_Field.IntPtrValue; + } + + public static UIntPtr UIntPtr() + { + return TypeInitializer_DefaultValues_Field.UIntPtrValue; + } + + public static float Single() + { + return TypeInitializer_DefaultValues_Field.SingleValue; + } + + public static double Double() + { + return TypeInitializer_DefaultValues_Field.DoubleValue; + } + + public static char Char() + { + return TypeInitializer_DefaultValues_Field.CharValue; + } + + public static string String() + { + return TypeInitializer_DefaultValues_Field.StringValue; + } + + public static bool Array() + { + var array = TypeInitializer_DefaultValues_Field.Array; + if (array == null) return false; + if (array.Length != 3) return false; + if (array[0] != 1) return false; + if (array[1] != 2) return false; + if (array[2] != 3) return false; + return true; + } + } +} diff --git a/tests/IL2C.Core.Test.RuntimeSystems/TypeInitializer/TypeInitializer_NonStaticClass.cs b/tests/IL2C.Core.Test.RuntimeSystems/TypeInitializer/TypeInitializer_NonStaticClass.cs new file mode 100644 index 00000000..f246a2b5 --- /dev/null +++ b/tests/IL2C.Core.Test.RuntimeSystems/TypeInitializer/TypeInitializer_NonStaticClass.cs @@ -0,0 +1,149 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace IL2C.RuntimeSystems +{ + public class TypeInitializer_NonStaticClass_Fields + { + public static bool BooleanValue; + public static readonly byte ByteValue; + public static readonly short Int16Value; + public static readonly int Int32Value; + public static readonly long Int64Value; + public static readonly sbyte SByteValue; + public static ushort UInt16Value; + public static readonly uint UInt32Value; + public static readonly ulong UInt64Value; + public static readonly IntPtr IntPtrValue; + public static readonly UIntPtr UIntPtrValue; + public static float SingleValue; + public static readonly double DoubleValue; + public static readonly char CharValue; + public static readonly string StringValue; + + static TypeInitializer_NonStaticClass_Fields() + { + BooleanValue = !BooleanValue; + ByteValue = (byte)(ByteValue + 1); + Int16Value = (short)(Int16Value + 1); + Int32Value = (int)(Int32Value + 1); + Int64Value = (long)(Int64Value + 1); + SByteValue = (sbyte)(SByteValue + 1); + UInt16Value = (ushort)(UInt16Value + 1); + UInt32Value = (uint)(UInt32Value + 1); + UInt64Value = (ulong)(UInt64Value + 1); + IntPtrValue = (IntPtr)(IntPtrValue + 1); + UIntPtrValue = (UIntPtr)(UIntPtrValue + 1); + SingleValue = (float)(SingleValue + 1); + DoubleValue = (double)(DoubleValue + 1); + CharValue = (char)(CharValue + 1); + StringValue = StringValue + "ABC"; + + DoRefInt32(ref Int32Value); + } + + private static void DoRefInt32(ref int value) + { + value += 2; + } + } + + [TestId("TypeInitializer_Non_Static_Class")] + [Description("These tests are verified the IL2C can handle the type initializer special translation cases.")] + [TestCase(true, "Bool", IncludeTypes = new[] { typeof(TypeInitializer_NonStaticClass_Fields) })] + [TestCase((byte)1, "Byte", IncludeTypes = new[] { typeof(TypeInitializer_NonStaticClass_Fields) })] + [TestCase((short)1, "Int16", IncludeTypes = new[] { typeof(TypeInitializer_NonStaticClass_Fields) })] + [TestCase((int)3, "Int32", IncludeTypes = new[] { typeof(TypeInitializer_NonStaticClass_Fields) })] + [TestCase((long)1, "Int64", IncludeTypes = new[] { typeof(TypeInitializer_NonStaticClass_Fields) })] + [TestCase((sbyte)1, "SByte", IncludeTypes = new[] { typeof(TypeInitializer_NonStaticClass_Fields) })] + [TestCase((ushort)1, "UInt16", IncludeTypes = new[] { typeof(TypeInitializer_NonStaticClass_Fields) })] + [TestCase((uint)1, "UInt32", IncludeTypes = new[] { typeof(TypeInitializer_NonStaticClass_Fields) })] + [TestCase((ulong)1, "UInt64", IncludeTypes = new[] { typeof(TypeInitializer_NonStaticClass_Fields) })] + [TestCase((int)1, "IntPtr", IncludeTypes = new[] { typeof(TypeInitializer_NonStaticClass_Fields) })] + [TestCase((uint)1, "UIntPtr", IncludeTypes = new[] { typeof(TypeInitializer_NonStaticClass_Fields) })] + [TestCase((float)1, "Single", IncludeTypes = new[] { typeof(TypeInitializer_NonStaticClass_Fields) })] + [TestCase((double)1, "Double", IncludeTypes = new[] { typeof(TypeInitializer_NonStaticClass_Fields) })] + [TestCase((char)1, "Char", IncludeTypes = new[] { typeof(TypeInitializer_NonStaticClass_Fields) })] + [TestCase("ABC", "String", IncludeTypes = new[] { typeof(TypeInitializer_NonStaticClass_Fields) })] + public sealed class TypeInitializer_NonStaticClass + { + public static bool Bool() + { + return TypeInitializer_NonStaticClass_Fields.BooleanValue; + } + + public static byte Byte() + { + return TypeInitializer_NonStaticClass_Fields.ByteValue; + } + + public static short Int16() + { + return TypeInitializer_NonStaticClass_Fields.Int16Value; + } + + public static int Int32() + { + return TypeInitializer_NonStaticClass_Fields.Int32Value; + } + + public static long Int64() + { + return TypeInitializer_NonStaticClass_Fields.Int64Value; + } + + public static sbyte SByte() + { + return TypeInitializer_NonStaticClass_Fields.SByteValue; + } + + public static ushort UInt16() + { + return TypeInitializer_NonStaticClass_Fields.UInt16Value; + } + + public static uint UInt32() + { + return TypeInitializer_NonStaticClass_Fields.UInt32Value; + } + + public static ulong UInt64() + { + return TypeInitializer_NonStaticClass_Fields.UInt64Value; + } + + public static IntPtr IntPtr() + { + return TypeInitializer_NonStaticClass_Fields.IntPtrValue; + } + + public static UIntPtr UIntPtr() + { + return TypeInitializer_NonStaticClass_Fields.UIntPtrValue; + } + + public static float Single() + { + return TypeInitializer_NonStaticClass_Fields.SingleValue; + } + + public static double Double() + { + return TypeInitializer_NonStaticClass_Fields.DoubleValue; + } + + public static char Char() + { + return TypeInitializer_NonStaticClass_Fields.CharValue; + } + + public static string String() + { + return TypeInitializer_NonStaticClass_Fields.StringValue; + } + } +} diff --git a/tests/IL2C.Core.Test.RuntimeSystems/TypeInitializer/TypeInitializer_Singleton.cs b/tests/IL2C.Core.Test.RuntimeSystems/TypeInitializer/TypeInitializer_Singleton.cs new file mode 100644 index 00000000..225d694b --- /dev/null +++ b/tests/IL2C.Core.Test.RuntimeSystems/TypeInitializer/TypeInitializer_Singleton.cs @@ -0,0 +1,49 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace IL2C.RuntimeSystems +{ + public class TypeInitializer_Singleton_Class + { + public int Value; + + public static TypeInitializer_Singleton_Class Default; + + static TypeInitializer_Singleton_Class() + { + Default = new TypeInitializer_Singleton_Class(); + Default.Value = 20; + } + } + + public struct TypeInitializer_Singleton_Struct + { + public int Value; + + public static TypeInitializer_Singleton_Struct Default; + + static TypeInitializer_Singleton_Struct() + { + Default = new TypeInitializer_Singleton_Struct(); + Default.Value = 10; + } + } + + [TestCase((int)20, "Default_Class_Value", IncludeTypes = new[] { typeof(TypeInitializer_Singleton_Class) })] + [TestCase((int)10, "Default_Struct_Value", IncludeTypes = new[] { typeof(TypeInitializer_Singleton_Struct) })] + public sealed class TypeInitializer_Singleton + { + public static int Default_Class_Value() + { + return TypeInitializer_Singleton_Class.Default.Value; + } + + public static int Default_Struct_Value() + { + return TypeInitializer_Singleton_Struct.Default.Value; + } + } +} diff --git a/tests/IL2C.Core.Test.RuntimeSystems/TypeInitializer/TypeInitializer_Struct.cs b/tests/IL2C.Core.Test.RuntimeSystems/TypeInitializer/TypeInitializer_Struct.cs new file mode 100644 index 00000000..2f6119b9 --- /dev/null +++ b/tests/IL2C.Core.Test.RuntimeSystems/TypeInitializer/TypeInitializer_Struct.cs @@ -0,0 +1,164 @@ +///////////////////////////////////////////////////////////////////////////////////////////////// +// +// IL2C - A translator for ECMA-335 CIL/MSIL to C language. +// Copyright (c) 2016-2019 Kouji Matsui (@kozy_kekyo, @kekyo2) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +///////////////////////////////////////////////////////////////////////////////////////////////// + +using System; +using System.ComponentModel; + +namespace IL2C.RuntimeSystems +{ + public struct TypeInitializer_Struct_Field + { + public static readonly bool BooleanValue; + public static readonly byte ByteValue; + public static readonly short Int16Value; + public static readonly int Int32Value; + public static readonly long Int64Value; + public static readonly sbyte SByteValue; + public static ushort UInt16Value; + public static readonly uint UInt32Value; + public static readonly ulong UInt64Value; + public static IntPtr IntPtrValue; + public static readonly UIntPtr UIntPtrValue; + public static readonly float SingleValue; + public static double DoubleValue; + public static readonly char CharValue; + public static readonly string StringValue; + + static TypeInitializer_Struct_Field() + { + BooleanValue = !BooleanValue; + ByteValue = (byte)(ByteValue + 1); + Int16Value = (short)(Int16Value + 1); + Int32Value = (int)(Int32Value + 1); + Int64Value = (long)(Int64Value + 1); + SByteValue = (sbyte)(SByteValue + 1); + UInt16Value = (ushort)(UInt16Value + 1); + UInt32Value = (uint)(UInt32Value + 1); + UInt64Value = (ulong)(UInt64Value + 1); + IntPtrValue = (IntPtr)(IntPtrValue + 1); + UIntPtrValue = (UIntPtr)(UIntPtrValue + 1); + SingleValue = (float)(SingleValue + 1); + DoubleValue = (double)(DoubleValue + 1); + CharValue = (char)(CharValue + 1); + StringValue = StringValue + "ABC"; + + DoRefInt32(ref Int32Value); + } + + private static void DoRefInt32(ref int value) + { + value += 2; + } + } + + [TestId("TypeInitializer_Struct")] + [Description("These tests are verified the IL2C can handle the type initializer special translation cases.")] + [TestCase(true, "Bool", IncludeTypes = new[] { typeof(TypeInitializer_Struct_Field) })] + [TestCase((byte)1, "Byte", IncludeTypes = new[] { typeof(TypeInitializer_Struct_Field) })] + [TestCase((short)1, "Int16", IncludeTypes = new[] { typeof(TypeInitializer_Struct_Field) })] + [TestCase((int)3, "Int32", IncludeTypes = new[] { typeof(TypeInitializer_Struct_Field) })] + [TestCase((long)1, "Int64", IncludeTypes = new[] { typeof(TypeInitializer_Struct_Field) })] + [TestCase((sbyte)1, "SByte", IncludeTypes = new[] { typeof(TypeInitializer_Struct_Field) })] + [TestCase((ushort)1, "UInt16", IncludeTypes = new[] { typeof(TypeInitializer_Struct_Field) })] + [TestCase((uint)1, "UInt32", IncludeTypes = new[] { typeof(TypeInitializer_Struct_Field) })] + [TestCase((ulong)1, "UInt64", IncludeTypes = new[] { typeof(TypeInitializer_Struct_Field) })] + [TestCase((int)1, "IntPtr", IncludeTypes = new[] { typeof(TypeInitializer_Struct_Field) })] + [TestCase((uint)1, "UIntPtr", IncludeTypes = new[] { typeof(TypeInitializer_Struct_Field) })] + [TestCase((float)1, "Single", IncludeTypes = new[] { typeof(TypeInitializer_Struct_Field) })] + [TestCase((double)1, "Double", IncludeTypes = new[] { typeof(TypeInitializer_Struct_Field) })] + [TestCase((char)1, "Char", IncludeTypes = new[] { typeof(TypeInitializer_Struct_Field) })] + [TestCase("ABC", "String", IncludeTypes = new[] { typeof(TypeInitializer_Struct_Field) })] + public sealed class TypeInitializer_Struct + { + public static bool Bool() + { + return TypeInitializer_Struct_Field.BooleanValue; + } + + public static byte Byte() + { + return TypeInitializer_Struct_Field.ByteValue; + } + + public static short Int16() + { + return TypeInitializer_Struct_Field.Int16Value; + } + + public static int Int32() + { + return TypeInitializer_Struct_Field.Int32Value; + } + + public static long Int64() + { + return TypeInitializer_Struct_Field.Int64Value; + } + + public static sbyte SByte() + { + return TypeInitializer_Struct_Field.SByteValue; + } + + public static ushort UInt16() + { + return TypeInitializer_Struct_Field.UInt16Value; + } + + public static uint UInt32() + { + return TypeInitializer_Struct_Field.UInt32Value; + } + + public static ulong UInt64() + { + return TypeInitializer_Struct_Field.UInt64Value; + } + + public static IntPtr IntPtr() + { + return TypeInitializer_Struct_Field.IntPtrValue; + } + + public static UIntPtr UIntPtr() + { + return TypeInitializer_Struct_Field.UIntPtrValue; + } + + public static float Single() + { + return TypeInitializer_Struct_Field.SingleValue; + } + + public static double Double() + { + return TypeInitializer_Struct_Field.DoubleValue; + } + + public static char Char() + { + return TypeInitializer_Struct_Field.CharValue; + } + + public static string String() + { + return TypeInitializer_Struct_Field.StringValue; + } + } +}