private unsafe void Scan(MemorySpan mem, int offset, TypeInfo type) { if (type is StructTypeInfo structType) { foreach (var f in structType.Fields) { Scan(mem, offset + f.FieldOffset, f.FieldType); } } else if (type is DynamicArrayTypeInfo dynamicArrayType) { // grab pointer to array and then scan it using (var handle = mem.Pin(offset)) { uint ptr = *((uint *)handle.Ptr); ScanArray(ptr, dynamicArrayType); } } else if (type is ReferenceTypeInfo referenceType) { // grab pointer and then scan it using (var handle = mem.Pin(offset)) { uint ptr = *((uint *)handle.Ptr); Scan(ptr); } } else if (type is StringTypeInfo stringType) { // grab pointer and then scan it using (var handle = mem.Pin(offset)) { uint ptr = *((uint *)handle.Ptr); if (ptr != 0) { Get(ptr).Mark = true; } } } else if (type is StaticArrayTypeInfo staticArrayType) { int elemOffset = 0; for (int i = 0; i < staticArrayType.ArraySize; i++) { Scan(mem, offset + elemOffset, staticArrayType.ElementType); elemOffset += staticArrayType.ElementType.SizeOf(); } } }
public unsafe string AsString(int offset, int length) { if (Type.Kind != TypeKind.String) { throw new System.InvalidCastException(); } using (var handle = Memory.Pin(0)) { char *cptr = (char *)handle.Ptr; return(new string(cptr, offset, length)); } }
public unsafe T Pop <T>() where T : unmanaged { unsafe { _ptr -= sizeof(T); using (var handle = _mem.Pin(_ptr)) { T *tptr = (T *)handle.Ptr; return(*tptr); } } }