mirror of
https://github.com/Smaug123/WoofWare.PawPrint
synced 2025-10-18 03:48:40 +00:00
WIP
This commit is contained in:
@@ -70,8 +70,8 @@ public class TestInitobj
|
|||||||
if (s.DoubleField != 3.14) return 4;
|
if (s.DoubleField != 3.14) return 4;
|
||||||
if (s.ByteField != 255) return 5;
|
if (s.ByteField != 255) return 5;
|
||||||
|
|
||||||
// Use initobj to reset the struct
|
// Use default to reset the struct (generates initobj)
|
||||||
Unsafe.InitBlockUnaligned(ref Unsafe.As<SimpleStruct, byte>(ref s), 0, (uint)Unsafe.SizeOf<SimpleStruct>());
|
s = default(SimpleStruct);
|
||||||
|
|
||||||
// Verify all fields are zeroed
|
// Verify all fields are zeroed
|
||||||
if (s.IntField != 0) return 6;
|
if (s.IntField != 0) return 6;
|
||||||
@@ -181,11 +181,11 @@ public class TestInitobj
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test 5: Initialize struct in array element
|
// Test 5: Initialize struct in array element using ref
|
||||||
public static int Test5()
|
public static int Test5()
|
||||||
{
|
{
|
||||||
SimpleStruct[] array = new SimpleStruct[3];
|
SimpleStruct[] array = new SimpleStruct[3];
|
||||||
|
|
||||||
// Set values in first element
|
// Set values in first element
|
||||||
array[0].IntField = 111;
|
array[0].IntField = 111;
|
||||||
array[0].BoolField = true;
|
array[0].BoolField = true;
|
||||||
@@ -195,14 +195,20 @@ public class TestInitobj
|
|||||||
if (array[0].BoolField != true) return 51;
|
if (array[0].BoolField != true) return 51;
|
||||||
if (array[0].CharField != 'Z') return 52;
|
if (array[0].CharField != 'Z') return 52;
|
||||||
|
|
||||||
// Reset first element using ref and Unsafe
|
// Reset first element using default assignment
|
||||||
ref SimpleStruct firstElement = ref array[0];
|
array[0] = default(SimpleStruct);
|
||||||
Unsafe.InitBlockUnaligned(ref Unsafe.As<SimpleStruct, byte>(ref firstElement), 0, (uint)Unsafe.SizeOf<SimpleStruct>());
|
|
||||||
|
|
||||||
if (array[0].IntField != 0) return 53;
|
if (array[0].IntField != 0) return 53;
|
||||||
if (array[0].BoolField != false) return 54;
|
if (array[0].BoolField != false) return 54;
|
||||||
if (array[0].CharField != '\0') return 55;
|
if (array[0].CharField != '\0') return 55;
|
||||||
|
|
||||||
|
// Also test with ref local
|
||||||
|
array[1].IntField = 222;
|
||||||
|
ref SimpleStruct secondElement = ref array[1];
|
||||||
|
secondElement = default(SimpleStruct);
|
||||||
|
|
||||||
|
if (array[1].IntField != 0) return 56;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -286,10 +292,10 @@ public class TestInitobj
|
|||||||
// Verify initial values
|
// Verify initial values
|
||||||
if (arg.IntField != 333) return 85;
|
if (arg.IntField != 333) return 85;
|
||||||
if (arg.BoolField != true) return 86;
|
if (arg.BoolField != true) return 86;
|
||||||
|
|
||||||
// Reset using default - this should use initobj on the argument
|
// Reset using default - this should use initobj on the argument
|
||||||
arg = default(SimpleStruct);
|
arg = default(SimpleStruct);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -376,7 +382,7 @@ public class TestInitobj
|
|||||||
|
|
||||||
// Get a pointer to the struct
|
// Get a pointer to the struct
|
||||||
SimpleStruct* ptr = &s;
|
SimpleStruct* ptr = &s;
|
||||||
|
|
||||||
// Initialize through pointer
|
// Initialize through pointer
|
||||||
*ptr = default(SimpleStruct);
|
*ptr = default(SimpleStruct);
|
||||||
|
|
||||||
@@ -390,6 +396,63 @@ public class TestInitobj
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Test 12: Initialize struct through Unsafe.AsRef
|
||||||
|
public static int Test12()
|
||||||
|
{
|
||||||
|
SimpleStruct s = new SimpleStruct
|
||||||
|
{
|
||||||
|
IntField = 999,
|
||||||
|
BoolField = true,
|
||||||
|
CharField = 'U',
|
||||||
|
DoubleField = 12.34,
|
||||||
|
ByteField = 200
|
||||||
|
};
|
||||||
|
|
||||||
|
// Use Unsafe to get a ref and initialize it
|
||||||
|
ref SimpleStruct sRef = ref s;
|
||||||
|
sRef = default(SimpleStruct);
|
||||||
|
|
||||||
|
// Verify all fields are zeroed
|
||||||
|
if (s.IntField != 0) return 120;
|
||||||
|
if (s.BoolField != false) return 121;
|
||||||
|
if (s.CharField != '\0') return 122;
|
||||||
|
if (s.DoubleField != 0.0) return 123;
|
||||||
|
if (s.ByteField != 0) return 124;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test 13: Initialize readonly struct
|
||||||
|
public static int Test13()
|
||||||
|
{
|
||||||
|
ReadonlyStruct ros = new ReadonlyStruct(100, true);
|
||||||
|
|
||||||
|
// Verify initial values through properties
|
||||||
|
if (ros.IntValue != 100) return 130;
|
||||||
|
if (ros.BoolValue != true) return 131;
|
||||||
|
|
||||||
|
// Reset using default
|
||||||
|
ros = default(ReadonlyStruct);
|
||||||
|
|
||||||
|
// Verify zeroed
|
||||||
|
if (ros.IntValue != 0) return 132;
|
||||||
|
if (ros.BoolValue != false) return 133;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly struct ReadonlyStruct
|
||||||
|
{
|
||||||
|
public readonly int IntValue;
|
||||||
|
public readonly bool BoolValue;
|
||||||
|
|
||||||
|
public ReadonlyStruct(int i, bool b)
|
||||||
|
{
|
||||||
|
IntValue = i;
|
||||||
|
BoolValue = b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static int Main(string[] argv)
|
public static int Main(string[] argv)
|
||||||
{
|
{
|
||||||
var result = Test1();
|
var result = Test1();
|
||||||
@@ -425,7 +488,13 @@ public class TestInitobj
|
|||||||
result = Test11();
|
result = Test11();
|
||||||
if (result != 0) return result;
|
if (result != 0) return result;
|
||||||
|
|
||||||
|
result = Test12();
|
||||||
|
if (result != 0) return result;
|
||||||
|
|
||||||
|
result = Test13();
|
||||||
|
if (result != 0) return result;
|
||||||
|
|
||||||
// All tests passed
|
// All tests passed
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -43,6 +43,8 @@ module Intrinsics =
|
|||||||
None
|
None
|
||||||
else
|
else
|
||||||
|
|
||||||
|
// In general, some implementations are in:
|
||||||
|
// https://github.com/dotnet/runtime/blob/108fa7856efcfd39bc991c2d849eabbf7ba5989c/src/coreclr/tools/Common/TypeSystem/IL/Stubs/UnsafeIntrinsics.cs#L192
|
||||||
match methodToCall.DeclaringType.Assembly.Name, methodToCall.DeclaringType.Name, methodToCall.Name with
|
match methodToCall.DeclaringType.Assembly.Name, methodToCall.DeclaringType.Name, methodToCall.Name with
|
||||||
| "System.Private.CoreLib", "Type", "get_TypeHandle" ->
|
| "System.Private.CoreLib", "Type", "get_TypeHandle" ->
|
||||||
// TODO: check return type is RuntimeTypeHandle
|
// TODO: check return type is RuntimeTypeHandle
|
||||||
@@ -321,6 +323,7 @@ module Intrinsics =
|
|||||||
| [ from ; to_ ] -> from, to_
|
| [ from ; to_ ] -> from, to_
|
||||||
| _ -> failwith "bad generics"
|
| _ -> failwith "bad generics"
|
||||||
|
|
||||||
|
failwith "TODO: transmute fields etc"
|
||||||
let state = state |> IlMachineState.advanceProgramCounter currentThread
|
let state = state |> IlMachineState.advanceProgramCounter currentThread
|
||||||
|
|
||||||
Some state
|
Some state
|
||||||
@@ -343,5 +346,8 @@ module Intrinsics =
|
|||||||
|> IlMachineState.pushToEvalStack (CliType.Numeric (CliNumericType.Int32 size)) currentThread
|
|> IlMachineState.pushToEvalStack (CliType.Numeric (CliNumericType.Int32 size)) currentThread
|
||||||
|> IlMachineState.advanceProgramCounter currentThread
|
|> IlMachineState.advanceProgramCounter currentThread
|
||||||
|> Some
|
|> Some
|
||||||
|
| "System.Private.CoreLib", "ReadOnlySpan`1", "get_Length" ->
|
||||||
|
// https://github.com/dotnet/runtime/blob/108fa7856efcfd39bc991c2d849eabbf7ba5989c/src/libraries/System.Private.CoreLib/src/System/ReadOnlySpan.cs#L161
|
||||||
|
None
|
||||||
| a, b, c -> failwith $"TODO: implement JIT intrinsic {a}.{b}.{c}"
|
| a, b, c -> failwith $"TODO: implement JIT intrinsic {a}.{b}.{c}"
|
||||||
|> Option.map (fun s -> s.WithThreadSwitchedToAssembly callerAssy currentThread |> fst)
|
|> Option.map (fun s -> s.WithThreadSwitchedToAssembly callerAssy currentThread |> fst)
|
||||||
|
Reference in New Issue
Block a user