This reverts commit 3b9a7fc3fc
.
This commit is contained in:
Родитель
9eb948aa36
Коммит
f760ef3415
|
@ -9,7 +9,6 @@ using ILCompiler.Compiler.CppCodeGen;
|
|||
using Internal.TypeSystem;
|
||||
using LLVMSharp;
|
||||
using ILCompiler.CodeGen;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Internal.IL
|
||||
{
|
||||
|
@ -87,7 +86,7 @@ namespace Internal.IL
|
|||
/// <param name="pos">Position where to insert <paramref name="v"/></param>
|
||||
public void InsertAt(T v, int pos)
|
||||
{
|
||||
Debug.Assert(pos <= _top, "Invalid insertion point");
|
||||
Debug.Assert(pos < _top, "Invalid insertion point");
|
||||
|
||||
if (_top >= _stack.Length)
|
||||
{
|
||||
|
@ -167,20 +166,6 @@ namespace Internal.IL
|
|||
}
|
||||
}
|
||||
|
||||
class LLVMTypeRefEqualityComparer : IEqualityComparer<LLVMTypeRef>
|
||||
{
|
||||
public static LLVMTypeRefEqualityComparer Instance = new LLVMTypeRefEqualityComparer();
|
||||
public bool Equals(LLVMTypeRef x, LLVMTypeRef y)
|
||||
{
|
||||
return x.Pointer.Equals(y.Pointer);
|
||||
}
|
||||
|
||||
public int GetHashCode(LLVMTypeRef obj)
|
||||
{
|
||||
return obj.Pointer.GetHashCode();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Abstract representation of a stack entry
|
||||
/// </summary>
|
||||
|
@ -196,53 +181,18 @@ namespace Internal.IL
|
|||
/// </summary>
|
||||
public TypeDesc Type { get; }
|
||||
|
||||
Dictionary<LLVMTypeRef, LLVMValueRef> _castValues = new Dictionary<LLVMTypeRef, LLVMValueRef>(LLVMTypeRefEqualityComparer.Instance);
|
||||
|
||||
public LLVMValueRef ValueAsType(LLVMTypeRef type, LLVMBuilderRef builder)
|
||||
{
|
||||
return ValueAsTypeInternal(type, builder, false);
|
||||
}
|
||||
|
||||
public LLVMValueRef ValueAsType(TypeDesc type, LLVMBuilderRef builder)
|
||||
{
|
||||
return ValueAsType(ILImporter.GetLLVMTypeForTypeDesc(type), builder);
|
||||
}
|
||||
|
||||
public LLVMValueRef ValueForStackKind(StackValueKind kind, LLVMBuilderRef builder, bool signExtend)
|
||||
{
|
||||
if (kind == StackValueKind.Int32)
|
||||
return ValueAsInt32(builder, signExtend);
|
||||
else if (kind == StackValueKind.Int64)
|
||||
return ValueAsInt64(builder, signExtend);
|
||||
else if (kind == StackValueKind.Float)
|
||||
return ValueAsType(LLVM.FloatType(), builder);
|
||||
else if (kind == StackValueKind.NativeInt || kind == StackValueKind.ByRef || kind == StackValueKind.ObjRef)
|
||||
return ValueAsInt32(builder, false);
|
||||
else
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public LLVMValueRef ValueAsInt32(LLVMBuilderRef builder, bool signExtend)
|
||||
{
|
||||
return ValueAsTypeInternal(LLVM.Int32Type(), builder, signExtend);
|
||||
}
|
||||
|
||||
public LLVMValueRef ValueAsInt64(LLVMBuilderRef builder, bool signExtend)
|
||||
{
|
||||
return ValueAsTypeInternal(LLVM.Int32Type(), builder, signExtend);
|
||||
}
|
||||
|
||||
protected abstract LLVMValueRef ValueAsTypeInternal(LLVMTypeRef type, LLVMBuilderRef builder, bool signExtend);
|
||||
public LLVMValueRef LLVMValue { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of StackEntry.
|
||||
/// </summary>
|
||||
/// <param name="kind">Kind of entry.</param>
|
||||
/// <param name="type">Type if any of entry.</param>
|
||||
protected StackEntry(StackValueKind kind, TypeDesc type = null)
|
||||
protected StackEntry(StackValueKind kind, LLVMValueRef llvmValue, TypeDesc type = null)
|
||||
{
|
||||
Kind = kind;
|
||||
Type = type;
|
||||
LLVMValue = llvmValue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -256,6 +206,45 @@ namespace Internal.IL
|
|||
/// </summary>
|
||||
/// <returns>A new instance of the same type as the current entry.</returns>
|
||||
public abstract StackEntry Duplicate();
|
||||
|
||||
/// <summary>
|
||||
/// Overridden and sealed to force descendants to override <see cref="BuildRepresentation"/>.
|
||||
/// </summary>
|
||||
/// <returns>String representation of current entry</returns>
|
||||
public override sealed string ToString()
|
||||
{
|
||||
StringBuilder s = new StringBuilder();
|
||||
BuildRepresentation(s);
|
||||
return s.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Build a representation of current entry in <paramref name="s"/>.
|
||||
/// </summary>
|
||||
/// <param name="s">StringBuilder where representation will be saved.</param>
|
||||
protected virtual void BuildRepresentation(StringBuilder s)
|
||||
{
|
||||
Debug.Assert(s != null, "StringBuilder is null.");
|
||||
if (Type != null)
|
||||
{
|
||||
s.Append(Type);
|
||||
if (Kind != StackValueKind.Unknown)
|
||||
{
|
||||
s.Append('(');
|
||||
s.Append(Kind);
|
||||
s.Append(')');
|
||||
}
|
||||
}
|
||||
else if (Kind != StackValueKind.Unknown)
|
||||
{
|
||||
if (Kind != StackValueKind.Unknown)
|
||||
{
|
||||
s.Append('(');
|
||||
s.Append(Kind);
|
||||
s.Append(')');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -263,7 +252,7 @@ namespace Internal.IL
|
|||
/// </summary>
|
||||
internal abstract class ConstantEntry : StackEntry
|
||||
{
|
||||
protected ConstantEntry(StackValueKind kind, TypeDesc type = null) : base(kind, type)
|
||||
protected ConstantEntry(StackValueKind kind, LLVMValueRef llvmValue, TypeDesc type = null) : base(kind, llvmValue, type)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -282,38 +271,28 @@ namespace Internal.IL
|
|||
{
|
||||
public T Value { get; }
|
||||
|
||||
protected ConstantEntry(StackValueKind kind, T value, TypeDesc type = null) : base(kind, type)
|
||||
protected ConstantEntry(StackValueKind kind, T value, LLVMValueRef llvmValue, TypeDesc type = null) : base(kind, llvmValue, type)
|
||||
{
|
||||
Value = value;
|
||||
}
|
||||
|
||||
protected override void BuildRepresentation(StringBuilder s)
|
||||
{
|
||||
base.BuildRepresentation(s);
|
||||
if (s.Length > 0)
|
||||
{
|
||||
s.Append(' ');
|
||||
}
|
||||
s.Append(Value);
|
||||
}
|
||||
}
|
||||
|
||||
internal class Int32ConstantEntry : ConstantEntry<int>
|
||||
{
|
||||
public Int32ConstantEntry(int value, TypeDesc type = null) : base(StackValueKind.Int32, value, type)
|
||||
public Int32ConstantEntry(int value, TypeDesc type = null) : base(StackValueKind.Int32, value, LLVM.ConstInt(LLVM.Int32Type(), (ulong)value, LLVMMisc.False), type)
|
||||
{
|
||||
}
|
||||
|
||||
protected override LLVMValueRef ValueAsTypeInternal(LLVMTypeRef type, LLVMBuilderRef builder, bool signExtend)
|
||||
{
|
||||
if (type.TypeKind == LLVMTypeKind.LLVMPointerTypeKind && Value == 0)
|
||||
{
|
||||
return LLVM.ConstPointerNull(type);
|
||||
}
|
||||
else if (type.TypeKind == LLVMTypeKind.LLVMPointerTypeKind && Value != 0)
|
||||
{
|
||||
return LLVM.ConstIntToPtr(LLVM.ConstInt(LLVM.Int32Type(), (ulong)Value, LLVMMisc.False), type);
|
||||
}
|
||||
else if (type.TypeKind != LLVMTypeKind.LLVMIntegerTypeKind)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
else
|
||||
{
|
||||
return LLVM.ConstInt(type, (ulong)Value, LLVMMisc.False);
|
||||
}
|
||||
}
|
||||
|
||||
public override StackEntry Duplicate()
|
||||
{
|
||||
return new Int32ConstantEntry(Value, Type);
|
||||
|
@ -345,7 +324,7 @@ namespace Internal.IL
|
|||
|
||||
internal class Int64ConstantEntry : ConstantEntry<long>
|
||||
{
|
||||
public Int64ConstantEntry(long value, TypeDesc type = null) : base(StackValueKind.Int64, value, type)
|
||||
public Int64ConstantEntry(long value, TypeDesc type = null) : base(StackValueKind.Int64, value, LLVM.ConstInt(LLVM.Int64Type(), (ulong)value, LLVMMisc.False), type)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -354,26 +333,6 @@ namespace Internal.IL
|
|||
return new Int64ConstantEntry(Value, Type);
|
||||
}
|
||||
|
||||
protected override LLVMValueRef ValueAsTypeInternal(LLVMTypeRef type, LLVMBuilderRef builder, bool signExtend)
|
||||
{
|
||||
if (type.TypeKind == LLVMTypeKind.LLVMPointerTypeKind && Value == 0)
|
||||
{
|
||||
return LLVM.ConstPointerNull(type);
|
||||
}
|
||||
else if (type.TypeKind == LLVMTypeKind.LLVMPointerTypeKind && Value != 0)
|
||||
{
|
||||
return LLVM.ConstIntToPtr(LLVM.ConstInt(LLVM.Int64Type(), (ulong)Value, LLVMMisc.False), type);
|
||||
}
|
||||
else if (type.TypeKind != LLVMTypeKind.LLVMIntegerTypeKind)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
else
|
||||
{
|
||||
return LLVM.ConstInt(type, (ulong)Value, LLVMMisc.False);
|
||||
}
|
||||
}
|
||||
|
||||
public override bool IsCastNecessary(TypeDesc destType)
|
||||
{
|
||||
switch (destType.UnderlyingType.Category)
|
||||
|
@ -404,15 +363,10 @@ namespace Internal.IL
|
|||
|
||||
internal class FloatConstantEntry : ConstantEntry<double>
|
||||
{
|
||||
public FloatConstantEntry(double value, TypeDesc type = null) : base(StackValueKind.Float, value, type)
|
||||
public FloatConstantEntry(double value, TypeDesc type = null) : base(StackValueKind.Float, value, LLVM.ConstReal(LLVM.FloatType(), value), type)
|
||||
{
|
||||
}
|
||||
|
||||
protected override LLVMValueRef ValueAsTypeInternal(LLVMTypeRef type, LLVMBuilderRef builder, bool signExtend)
|
||||
{
|
||||
return LLVM.ConstReal(type, Value);
|
||||
}
|
||||
|
||||
public override StackEntry Duplicate()
|
||||
{
|
||||
return new FloatConstantEntry(Value, Type);
|
||||
|
@ -428,74 +382,31 @@ namespace Internal.IL
|
|||
/// String representation of current expression
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
public LLVMValueRef RawLLVMValue { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes new instance of ExpressionEntry
|
||||
/// </summary>
|
||||
/// <param name="kind">Kind of entry</param>
|
||||
/// <param name="name">String representation of entry</param>
|
||||
/// <param name="type">Type if any of entry</param>
|
||||
public ExpressionEntry(StackValueKind kind, string name, LLVMValueRef llvmValue, TypeDesc type = null) : base(kind, type)
|
||||
public ExpressionEntry(StackValueKind kind, string name, LLVMValueRef llvmValue, TypeDesc type = null) : base(kind, llvmValue, type)
|
||||
{
|
||||
Name = name;
|
||||
RawLLVMValue = llvmValue;
|
||||
}
|
||||
|
||||
public override StackEntry Duplicate()
|
||||
{
|
||||
return new ExpressionEntry(Kind, Name, RawLLVMValue, Type);
|
||||
return new ExpressionEntry(Kind, Name, LLVMValue, Type);
|
||||
}
|
||||
|
||||
protected override LLVMValueRef ValueAsTypeInternal(LLVMTypeRef type, LLVMBuilderRef builder, bool signExtend)
|
||||
protected override void BuildRepresentation(StringBuilder s)
|
||||
{
|
||||
//TODO: deal with sign extension here
|
||||
return ILImporter.CastIfNecessary(builder, RawLLVMValue, type);
|
||||
base.BuildRepresentation(s);
|
||||
if (s.Length > 0)
|
||||
{
|
||||
s.Append(' ');
|
||||
}
|
||||
}
|
||||
|
||||
internal class LoadExpressionEntry : ExpressionEntry
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes new instance of ExpressionEntry
|
||||
/// </summary>
|
||||
/// <param name="kind">Kind of entry</param>
|
||||
/// <param name="name">String representation of entry</param>
|
||||
/// <param name="type">Type if any of entry</param>
|
||||
public LoadExpressionEntry(StackValueKind kind, string name, LLVMValueRef llvmValue, TypeDesc type = null) : base(kind, name, llvmValue, type)
|
||||
{
|
||||
}
|
||||
|
||||
public override StackEntry Duplicate()
|
||||
{
|
||||
return new LoadExpressionEntry(Kind, Name, RawLLVMValue, Type);
|
||||
}
|
||||
|
||||
protected override LLVMValueRef ValueAsTypeInternal(LLVMTypeRef type, LLVMBuilderRef builder, bool signExtend)
|
||||
{
|
||||
return ILImporter.LoadValue(builder, RawLLVMValue, Type, type, signExtend);
|
||||
}
|
||||
}
|
||||
|
||||
internal class AddressExpressionEntry : ExpressionEntry
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes new instance of ExpressionEntry
|
||||
/// </summary>
|
||||
/// <param name="kind">Kind of entry</param>
|
||||
/// <param name="name">String representation of entry</param>
|
||||
/// <param name="type">Type if any of entry</param>
|
||||
public AddressExpressionEntry(StackValueKind kind, string name, LLVMValueRef llvmValue, TypeDesc type = null) : base(kind, name, llvmValue, type)
|
||||
{
|
||||
}
|
||||
|
||||
public override StackEntry Duplicate()
|
||||
{
|
||||
return new LoadExpressionEntry(Kind, Name, RawLLVMValue, Type);
|
||||
}
|
||||
|
||||
protected override LLVMValueRef ValueAsTypeInternal(LLVMTypeRef type, LLVMBuilderRef builder, bool signExtend)
|
||||
{
|
||||
return ILImporter.CastIfNecessary(builder, RawLLVMValue, type);
|
||||
s.Append(Name);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -506,19 +417,21 @@ namespace Internal.IL
|
|||
{
|
||||
public T LdToken { get; }
|
||||
|
||||
public LdTokenEntry(StackValueKind kind, string name, T token, TypeDesc type = null) : base(kind, name, default(LLVMValueRef), type)
|
||||
public LdTokenEntry(StackValueKind kind, string name, T token, LLVMValueRef value, TypeDesc type = null) : base(kind, name, value, type)
|
||||
{
|
||||
LdToken = token;
|
||||
}
|
||||
|
||||
public override StackEntry Duplicate()
|
||||
{
|
||||
return new LdTokenEntry<T>(Kind, Name, LdToken, Type);
|
||||
return new LdTokenEntry<T>(Kind, Name, LdToken, LLVMValue, Type);
|
||||
}
|
||||
|
||||
protected override LLVMValueRef ValueAsTypeInternal(LLVMTypeRef type, LLVMBuilderRef builder, bool signExtend)
|
||||
protected override void BuildRepresentation(StringBuilder s)
|
||||
{
|
||||
return ILImporter.CastIfNecessary(builder, RawLLVMValue, type);
|
||||
base.BuildRepresentation(s);
|
||||
s.Append(' ');
|
||||
s.Append(LdToken);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -529,7 +442,7 @@ namespace Internal.IL
|
|||
/// </summary>
|
||||
public static InvalidEntry Entry = new InvalidEntry();
|
||||
|
||||
protected InvalidEntry() : base(StackValueKind.Unknown, null)
|
||||
protected InvalidEntry() : base(StackValueKind.Unknown, default(LLVMValueRef), null)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -538,33 +451,9 @@ namespace Internal.IL
|
|||
return this;
|
||||
}
|
||||
|
||||
protected override LLVMValueRef ValueAsTypeInternal(LLVMTypeRef type, LLVMBuilderRef builder, bool signExtend)
|
||||
protected override void BuildRepresentation(StringBuilder s)
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Entry representing a writable sharable stack entry that can survive from one basic block to another
|
||||
/// </summary>
|
||||
internal class SpilledExpressionEntry : ExpressionEntry
|
||||
{
|
||||
public int LocalIndex;
|
||||
private ILImporter _importer;
|
||||
public SpilledExpressionEntry(StackValueKind kind, string name, TypeDesc type, int localIndex, ILImporter importer) : base(kind, name, new LLVMValueRef(IntPtr.Zero), type)
|
||||
{
|
||||
LocalIndex = localIndex;
|
||||
_importer = importer;
|
||||
}
|
||||
|
||||
protected override LLVMValueRef ValueAsTypeInternal(LLVMTypeRef type, LLVMBuilderRef builder, bool signExtend)
|
||||
{
|
||||
return _importer.LoadTemp(LocalIndex, type);
|
||||
}
|
||||
|
||||
public override StackEntry Duplicate()
|
||||
{
|
||||
return new SpilledExpressionEntry(Kind, Name, Type, LocalIndex, _importer);
|
||||
s.Append("Invalid Entry");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -101,6 +101,7 @@ namespace Internal.IL
|
|||
|
||||
static LLVMValueRef TrapFunction = default(LLVMValueRef);
|
||||
static LLVMValueRef DoNothingFunction = default(LLVMValueRef);
|
||||
|
||||
private static IEnumerable<string> GetParameterNamesForMethod(MethodDesc method)
|
||||
{
|
||||
// TODO: The uses of this method need revision. The right way to get to this info is from
|
||||
|
|
|
@ -188,17 +188,6 @@ namespace ILCompiler.DependencyAnalysis
|
|||
//throw new NotImplementedException(); // This function isn't complete
|
||||
}
|
||||
|
||||
public static LLVMValueRef GetConstZeroArray(int length)
|
||||
{
|
||||
var int8Type = LLVM.Int8Type();
|
||||
var result = new LLVMValueRef[length];
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
result[i] = LLVM.ConstInt(int8Type, 0, LLVMMisc.False);
|
||||
}
|
||||
return LLVM.ConstArray(int8Type, result);
|
||||
}
|
||||
|
||||
public static LLVMValueRef EmitGlobal(LLVMModuleRef module, FieldDesc field, NameMangler nameMangler)
|
||||
{
|
||||
if (field.IsThreadStatic)
|
||||
|
@ -214,7 +203,7 @@ namespace ILCompiler.DependencyAnalysis
|
|||
var valueType = LLVM.ArrayType(LLVM.Int8Type(), (uint)field.FieldType.GetElementSize().AsInt);
|
||||
var llvmValue = LLVM.AddGlobal(module, valueType, nameMangler.GetMangledFieldName(field).ToString());
|
||||
LLVM.SetLinkage(llvmValue, LLVMLinkage.LLVMInternalLinkage);
|
||||
LLVM.SetInitializer(llvmValue, GetConstZeroArray(field.FieldType.GetElementSize().AsInt));
|
||||
LLVM.SetInitializer(llvmValue, LLVM.ConstPointerNull(valueType));
|
||||
s_staticFieldMapping.Add(field, llvmValue);
|
||||
return llvmValue;
|
||||
}
|
||||
|
@ -273,7 +262,7 @@ namespace ILCompiler.DependencyAnalysis
|
|||
{
|
||||
LLVMValueRef valRef = IsFunction ? LLVM.GetNamedFunction(module, SymbolName) : LLVM.GetNamedGlobal(module, SymbolName);
|
||||
|
||||
if (Offset != 0 && valRef.Pointer != IntPtr.Zero)
|
||||
if (Offset != 0)
|
||||
{
|
||||
var pointerType = LLVM.PointerType(LLVM.Int8Type(), 0);
|
||||
var bitCast = LLVM.ConstBitCast(valRef, pointerType);
|
||||
|
@ -324,18 +313,10 @@ namespace ILCompiler.DependencyAnalysis
|
|||
if (ObjectSymbolRefs.TryGetValue(curOffset, out symbolRef))
|
||||
{
|
||||
LLVMValueRef pointedAtValue = symbolRef.ToLLVMValueRef(module);
|
||||
//TODO: why did this come back null
|
||||
if (pointedAtValue.Pointer != IntPtr.Zero)
|
||||
{
|
||||
var ptrValue = LLVM.ConstBitCast(pointedAtValue, intPtrType);
|
||||
entries.Add(ptrValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
entries.Add(LLVM.ConstPointerNull(intPtrType));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int value = BitConverter.ToInt32(currentObjectData, curOffset);
|
||||
var nullptr = LLVM.ConstPointerNull(int8PtrType);
|
||||
|
@ -377,6 +358,7 @@ namespace ILCompiler.DependencyAnalysis
|
|||
|
||||
_dataToFill.Add(new ObjectNodeDataEmission(arrayglobal, _currentObjectData.ToArray(), _currentObjectSymbolRefs));
|
||||
|
||||
|
||||
foreach (var symbolIdInfo in _symbolDefs)
|
||||
{
|
||||
EmitSymbolDef(arrayglobal, symbolIdInfo.Key, symbolIdInfo.Value);
|
||||
|
|
|
@ -32,8 +32,8 @@ namespace ILCompiler.DependencyAnalysis
|
|||
|
||||
protected override IMethodNode CreateUnboxingStubNode(MethodDesc method)
|
||||
{
|
||||
// TODO: this is wrong: this returns an unstubbed node
|
||||
return new WebAssemblyMethodCodeNode(method);
|
||||
// TODO: this is wrong: this returns an assembly stub node
|
||||
return new UnboxingStubNode(method, Target);
|
||||
}
|
||||
|
||||
protected override ISymbolNode CreateReadyToRunHelperNode(ReadyToRunHelperKey helperCall)
|
||||
|
|
|
@ -11,12 +11,10 @@ internal static class Program
|
|||
private static unsafe void Main(string[] args)
|
||||
{
|
||||
Add(1, 2);
|
||||
var tempObj = new TestClass(1337);
|
||||
|
||||
int tempInt = 0;
|
||||
(*(&tempInt)) = 9;
|
||||
|
||||
tempObj.TestMethod("Hello");
|
||||
|
||||
if(tempInt == 9)
|
||||
{
|
||||
PrintLine("Hello from C#!");
|
||||
|
@ -24,8 +22,6 @@ internal static class Program
|
|||
|
||||
TwoByteStr str = new TwoByteStr() { first = 1, second = 2 };
|
||||
TwoByteStr str2 = new TwoByteStr() { first = 3, second = 4 };
|
||||
*(&str) = str2;
|
||||
str2 = *(&str);
|
||||
|
||||
if (str2.second == 4)
|
||||
{
|
||||
|
@ -61,7 +57,6 @@ internal static class Program
|
|||
{
|
||||
PrintLine("shiftRight test: Ok.");
|
||||
}
|
||||
|
||||
var unsignedShift = UnsignedShift(0xFFFFFFFFu, 4) == 0x0FFFFFFFu;
|
||||
if (unsignedShift)
|
||||
{
|
||||
|
@ -164,21 +159,3 @@ public struct TwoByteStr
|
|||
public byte second;
|
||||
}
|
||||
|
||||
public class TestClass
|
||||
{
|
||||
public string TestString {get; set;}
|
||||
|
||||
public TestClass(int number)
|
||||
{
|
||||
if(number != 1337)
|
||||
throw new Exception();
|
||||
}
|
||||
|
||||
public void TestMethod(string str)
|
||||
{
|
||||
TestString = str;
|
||||
if(TestString != str)
|
||||
throw new Exception();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче