public VMStack(VMHeap heap, int stackSize) { // stupid hack: to unify pointer logic, we allocate the stack from our VM heap too _heap = heap; _stackAlloc = heap.Get(heap.malloc(null, stackSize)); heap.Pin(_stackAlloc.Handle); _mem = _stackAlloc.Memory; _ptr = 0; }
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 void Free(MemorySpan span) { // don't need to free memory, the .NET GC will handle it }