/// <summary> /// Increases <c>index</c> by 8 /// </summary> public void IncreaseIndexBy8() { LoadIndexByRef(); // stack: [ref index] LoadIndex(); // stack: [ref index, index] Il.Ldc_I4(8); // stack: [ref index, index, 8] Il.Add(); // stack: [ref index, index + 8] Il.Stind(typeof(int)); // index = index + 8 }
public void SkipValue() { LoadIndexByRef(); // stack: [ref index] LoadIndex(); // stack: [ref index, index] // todo: сделать switch Il.Ldloc(TypeCode); // stack: [ref index, index, TypeCode] Il.Ldc_I4((int)GroBufTypeCode.DateTimeOld); // stack: [ref index, index, TypeCode, GroBufTypeCode.DateTimeOld] var notDateTimeLabel = Il.DefineLabel("notDateTime"); Il.Bne_Un(notDateTimeLabel); // if(TypeCode != GroBufTypeCode.DateTimeOld) goto notDateTime; stack: [ref index, index] Il.Ldc_I4(8); // stack: [ref index, index, 8] AssertLength(); GoToCurrentLocation(); // stack: [ref index, index, &data[index]] Il.Ldc_I4(4); Il.Add(); Il.Ldind(typeof(int)); // stack: [ref index, index, (int)(&data[index])] Il.Ldc_I4(31); // stack: [ref index, index, (int)&data[index], 31] Il.Shr(true); // stack: [ref index, index, (int)&data[index] >> 31] Il.Ldc_I4(8); // stack: [ref index, index, (int)&data[index] >> 31, 8] Il.Add(); // stack: [ref index, index, (int)&data[index] >> 31 + 8] var increaseLabel = Il.DefineLabel("increase"); Il.Br(increaseLabel); Il.MarkLabel(notDateTimeLabel); LoadField(Context.Lengths); Il.Ldloc(TypeCode); // stack: [ref index, index, lengths, typeCode] Il.Ldelem(typeof(int)); // stack: [ref index, index, lengths[typeCode]] Il.Dup(); // stack: [ref index, index, lengths[typeCode], lengths[typeCode]] Il.Ldc_I4(-1); // stack: [ref index, index, lengths[typeCode], lengths[typeCode], -1] Il.Bne_Un(increaseLabel); // if(lengths[typeCode] != -1) goto increase; Il.Ldc_I4(4); AssertLength(); Il.Pop(); // stack: [ref index, index] Il.Dup(); // stack: [ref index, index, index] LoadData(); // stack: [ref index, index, index, pinnedData] Il.Add(); // stack: [ref index, index, index + pinnedData] Il.Ldind(typeof(uint)); // stack: [ref index, index, *(uint*)(pinnedData + index)] Il.Ldc_I4(4); // stack: [ref index, index, *(uint*)(pinnedData + index), 4] Il.Add(); // stack: [ref index, *(uint*)(pinnedData + index) + 4] Il.MarkLabel(increaseLabel); Il.Dup(); // stack: [ref index, length, length] AssertLength(); // stack: [ref index, length] Il.Add(); // stack: [ref index, index + length] Il.Stind(typeof(int)); // index = index + length }
/// <summary> /// Asserts that the specified number of bytes can be read from <c>data</c> starting at <c>index</c> /// <para></para> /// The number of bytes must be pushed onto the evaluation stack /// </summary> public void AssertLength() { LoadIndex(); // stack: [length, index] Il.Add(); // stack: [length + index] LoadDataLength(); // stack: [length + index, dataLength] var bigEnoughLabel = Il.DefineLabel("bigEnough"); Il.Ble(bigEnoughLabel, true); Il.Ldstr("Unexpected end of data"); var constructor = typeof(DataCorruptedException).GetConstructor(new[] { typeof(string) }); if (constructor == null) { throw new MissingConstructorException(typeof(DataCorruptedException), typeof(string)); } Il.Newobj(constructor); Il.Throw(); Il.MarkLabel(bigEnoughLabel); }
/// <summary> /// Asserts that the specified number of bytes can be written to <c>result</c> starting at <c>index</c> /// <para></para> /// The number of bytes must be pushed onto the evaluation stack /// </summary> public void AssertLength() { LoadIndex(); // stack: [length, index] Il.Add(); // stack: [length + index] LoadResultLength(); // stack: [length + index, resultLength] var bigEnoughLabel = Il.DefineLabel("bigEnough"); Il.Ble(bigEnoughLabel, true); Il.Ldstr("Seems like the object being serialized has been changed during serialization"); var constructor = typeof(InvalidOperationException).GetConstructor(new[] { typeof(string) }); if (constructor == null) { throw new MissingConstructorException(typeof(InvalidOperationException), typeof(string)); } Il.Newobj(constructor); Il.Throw(); Il.MarkLabel(bigEnoughLabel); }
/// <summary> /// Loads &<c>data</c>[<c>index</c>] onto the evaluation stack /// </summary> public void GoToCurrentLocation() { LoadData(); // stack: [pinnedData] LoadIndex(); // stack: [pinnedData, index] Il.Add(); // stack: [pinnedData + index] }
/// <summary> /// Loads &<c>result</c>[<c>index</c>] onto the evaluation stack /// </summary> public void GoToCurrentLocation() { LoadResult(); // stack: [result] LoadIndex(); // stack: [result, index] Il.Add(); // stack: [result + index] }