internal static SubPatternStruct <TPattern> Interpret(Type structType) { if (_interpretedStruct.TryGetValue(structType, out SubPatternStruct <TPattern> interpretedStruct)) { return(interpretedStruct); } if (!IsSequentialLayout(structType)) { throw new Exception("Struct may be sequential struct layout"); } FieldInfo[] fields = structType.GetFields(); int[] mappedOffset = new int[_patternFields.Length]; int * fieldOffsets = stackalloc int[fields.Length]; int totalSize = 0; for (int i = 0; i < fields.Length; i++) { fieldOffsets[i] = totalSize; totalSize += SizeOfHelper.SizeOf(fields[i].FieldType); } int index; for (int i = 0; i < _patternFields.Length; i++) { index = Array.FindIndex(fields, (item) => IsEqualFieldInfo(item, _patternFields[i])); mappedOffset[i] = index >= 0 ? fieldOffsets[index] : -1; } interpretedStruct = new SubPatternStruct <TPattern>(mappedOffset, totalSize); _interpretedStruct.Add(structType, interpretedStruct); return(interpretedStruct); }
internal override void EmulateVCall(EmuContext ctx) { Type type = (Type)ctx.Header.References[ctx.Stack.Pop().U4]; ctx.Stack.Push(new VMSlot() { U4 = (uint)SizeOfHelper.SizeOf(type) }); //Fixed :) }
public void Load(DarksVMContext ctx, out ExecutionState state) { uint sp = ctx.Registers[DarksVMConstants.REG_SP].U4; uint bp = ctx.Registers[DarksVMConstants.REG_BP].U4; var type = (Type) ctx.Instance.Data.LookupReference(ctx.Stack[sp].U4); ctx.Stack[sp] = new DarksVMSlot { U4 = (uint) SizeOfHelper.SizeOf(type) }; state = ExecutionState.Next; }
static StructInterpreter() { Type type = typeof(TPattern); if (!type.IsValueType) { throw new Exception($"{type.FullName} isn't a struct"); } _patternFields = type.GetFields(); PatternFieldOffsets = new int[_patternFields.Length]; PatternFieldSizes = new int[_patternFields.Length]; int totalSize = 0; for (int i = 0; i < PatternFieldOffsets.Length; i++) { PatternFieldOffsets[i] = totalSize; totalSize += PatternFieldSizes[i] = SizeOfHelper.SizeOf(_patternFields[i].FieldType); } }