Skip to content

Commit

Permalink
BlobReader: inlined a bunch of methods
Browse files Browse the repository at this point in the history
  • Loading branch information
azuisleet committed Oct 30, 2012
1 parent 5742ee7 commit b3cc1c3
Show file tree
Hide file tree
Showing 10 changed files with 202 additions and 29 deletions.
4 changes: 0 additions & 4 deletions SteamKit2/SteamKit2/Blob/BlobReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -151,10 +151,6 @@ private void UnpackBlobIfNeeded()

source.ReadInt16(); // skip zlib header

if (sourceStack == null)
sourceStack = new Stack<Stream>(1);

sourceStack.Push(source);
source = new BufferedStream(new DeflateStream(source, CompressionMode.Decompress, true), 0x10000);

ReadBlobHeader();
Expand Down
207 changes: 188 additions & 19 deletions SteamKit2/SteamKit2/Blob/JIT/JITContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,11 @@ public void PushType(Type t)
StoreLocal(local);
}

public void Pop()
{
ilgen.Emit(OpCodes.Pop);
}

public void PopType(Type t)
{
typePool[t].Return();
Expand Down Expand Up @@ -149,6 +154,11 @@ public LocalBuilder CreateLocal(Type t)
return ilgen.DeclareLocal(t);
}

public void CreateArray(Type t)
{
ilgen.Emit(OpCodes.Newarr, t);
}

public void StoreField(FieldInfo field)
{
ilgen.Emit(OpCodes.Stfld, field);
Expand Down Expand Up @@ -203,6 +213,16 @@ public void Goto(Label label)
ilgen.Emit(OpCodes.Br, label);
}

public void GotoNotEqual(Label label)
{
ilgen.Emit(OpCodes.Bne_Un, label);
}

public void GotoGtOrEqual(Label label)
{
ilgen.Emit(OpCodes.Bge_Un, label);
}

public void GotoWhenFalse(Label label)
{
ilgen.Emit(OpCodes.Brfalse, label);
Expand All @@ -223,17 +243,17 @@ public void LoadBlobReader()
LoadLocal(top);
}

private MethodInfo GetReaderMethod(string methodName)
public MethodInfo GetReaderMethod(string methodName)
{
MethodInfo method = typeof(BlobReader).GetMethod(methodName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
if (method == null) throw new ArgumentException("methodName");

return method;
}

public void BitConvertToInt32()
public void BitConvertTo(String type)
{
MethodInfo convMethod = typeof(BitConverter).GetMethod("ToInt32", BindingFlags.Public | BindingFlags.Static);
MethodInfo convMethod = typeof(BitConverter).GetMethod("To" + type, BindingFlags.Public | BindingFlags.Static);
if (convMethod == null) throw new ArgumentException("methodName");

EmitCall(convMethod);
Expand Down Expand Up @@ -278,6 +298,12 @@ public void CompareGreaterThanZero()
ilgen.Emit(OpCodes.Cgt);
}

public void CompareEqualTo(int value)
{
ilgen.Emit(OpCodes.Ldc_I4, value);
ilgen.Emit(OpCodes.Ceq);
}

public void EmitKeyTest(byte[] key, Label failed)
{
LoadByteKey(key);
Expand All @@ -302,21 +328,43 @@ public void LoadIntConstant(int value)
{
switch (value)
{
case -1: ilgen.Emit(OpCodes.Ldc_I4_M1); break;
case 0: ilgen.Emit(OpCodes.Ldc_I4_0); break;
case 1: ilgen.Emit(OpCodes.Ldc_I4_1); break;
case 2: ilgen.Emit(OpCodes.Ldc_I4_2); break;
case 3: ilgen.Emit(OpCodes.Ldc_I4_3); break;
case 4: ilgen.Emit(OpCodes.Ldc_I4_4); break;
case 5: ilgen.Emit(OpCodes.Ldc_I4_5); break;
case 6: ilgen.Emit(OpCodes.Ldc_I4_6); break;
case 7: ilgen.Emit(OpCodes.Ldc_I4_7); break;
case 8: ilgen.Emit(OpCodes.Ldc_I4_8); break;
default:
ilgen.Emit(OpCodes.Ldc_I4, value);
break;
}
}

public void Add()
{
ilgen.Emit(OpCodes.Add);
}

public void Subtract()
{
ilgen.Emit(OpCodes.Sub);
}

public void Length()
{
ilgen.Emit(OpCodes.Ldlen);
ilgen.Emit(OpCodes.Conv_I4);
}

public void Switch(Label[] table)
{
ilgen.Emit(OpCodes.Switch, table);
}

public void LoadByteKey(byte[] key)
{
int index = ByteKeys.FindIndex(x => x.Length == key.Length && BlobUtil.UnsafeCompare(x, key));
Expand All @@ -339,52 +387,48 @@ public void ReadFieldBlob()

public void ReadFieldStream()
{
LoadBlobReader();
EmitCall(GetReaderMethod("ReadFieldStream"));
}

public void ReadFieldHeader()
{
LoadBlobReader();
EmitCall(GetReaderMethod("ReadFieldHeader"));
LoadBlobField("source");
}


public void CanReadBytes(int count)
{
LoadBlobReader();
ilgen.Emit(OpCodes.Ldc_I4, count);
EmitCall(GetReaderMethod("CanTakeBytes"));
LoadBlobReader();
LoadBlobField("bytesAvailable");
ilgen.Emit(OpCodes.Clt);
}

public void GetFieldDataBytes()
{
LoadBlobReader();
EmitCall(GetReaderMethod("get_FieldDataBytes"));
LoadBlobField("dataBytes");
}

public void GetFieldKeyBytes()
{
LoadBlobReader();
EmitCall(GetReaderMethod("get_FieldKeyBytes"));
LoadBlobField("keyBytes");
}

public void LoadPeekKey()
{
LoadBlobReader();
EmitCall(GetReaderMethod("get_PeekIntKey"));
LoadBlobField("keyInt");
}

public void LoadByteKey()
{
LoadBlobReader();
EmitCall(GetReaderMethod("get_ByteKey"));
LoadBlobField("keyBuffer");
}

public void SkipField()
{
LoadBlobReader();
EmitCall(GetReaderMethod("SkipField"));
LoadBlobField("source");
LoadBlobReader();
LoadBlobField("dataBytes");
EmitStreamCall("ReadAndDiscard");
}

public void SkipSpare()
Expand All @@ -405,6 +449,28 @@ private void Return()
ilgen.Emit(OpCodes.Ret);
}


public void LoadField(Type type, string field)
{
ilgen.Emit(OpCodes.Ldfld, type.GetField(field, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance));
}

public void LoadStaticField(Type type, string field)
{
ilgen.Emit(OpCodes.Ldsfld, type.GetField(field, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static));
}

public void LoadBlobField(string field)
{
LoadField(typeof(BlobReader), field);
}

public void StoreBlobField(string field)
{
ilgen.Emit(OpCodes.Stfld, typeof(BlobReader).GetField(field, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance));
}


public static BlobDeserializer BuildDeserializer(IBlobSerializer source)
{
JITContext ctx = new JITContext(source.ExpectedType);
Expand All @@ -414,5 +480,108 @@ public static BlobDeserializer BuildDeserializer(IBlobSerializer source)

return (BlobDeserializer)ctx.method.CreateDelegate(typeof(BlobDeserializer));
}

public void StreamRead(int length, string type)
{
LoadStaticField(typeof(StreamHelpers), "data");
LoadIntConstant(0);
LoadIntConstant(length);
EmitStreamCall("Read");
Pop();
LoadStaticField(typeof(StreamHelpers), "data");
LoadIntConstant(0);
BitConvertTo(type);
}

public void ReadFieldHeader()
{
var totalBytes = CreateLocal(typeof(Int32));

LoadBlobReader();
LoadBlobReader();
LoadBlobReader();
LoadBlobReader();
LoadBlobReader();
LoadBlobReader();
LoadBlobReader();

LoadBlobField("source");
StreamRead(2, "UInt16");
StoreBlobField("keyBytes");

LoadBlobField("source");
StreamRead(4, "Int32");
StoreBlobField("dataBytes");

LoadBlobField("bytesAvailable");
LoadIntConstant(BlobReader.FieldHeaderLength);
Subtract();
StoreBlobField("bytesAvailable");

var continueRead = CreateLabel();

LoadBlobReader();
LoadBlobField("keyBuffer");
Length();
LoadBlobReader();
LoadBlobField("keyBytes");
GotoGtOrEqual(continueRead);

LoadBlobReader();
LoadBlobReader();
LoadBlobField("keyBytes");
CreateArray(typeof(byte));
StoreBlobField("keyBuffer");

MarkLabel(continueRead);

LoadBlobField("dataBytes");
LoadBlobReader();
LoadBlobField("keyBytes");
Add();
StoreLocal(totalBytes);

LoadBlobReader();
LoadBlobField("source");
LoadBlobReader();
LoadBlobField("keyBuffer");
LoadIntConstant(0);
LoadBlobReader();
LoadBlobField("keyBytes");
EmitStreamCall("Read");
Pop();


var cleanup = CreateLabel();
var neg1 = CreateLabel();

LoadBlobReader();
LoadBlobField("keyBytes");
LoadIntConstant(4);
GotoNotEqual(neg1);

LoadBlobReader();
LoadBlobReader();
LoadBlobField("keyBuffer");
LoadIntConstant(0);
BitConvertTo("Int32");
StoreBlobField("keyInt");

Goto(cleanup);

MarkLabel(neg1);
LoadBlobReader();
LoadIntConstant(-1);
StoreBlobField("keyInt");

MarkLabel(cleanup);

LoadBlobReader();
LoadBlobReader();
LoadBlobField("bytesAvailable");
LoadLocal(totalBytes);
Subtract();
StoreBlobField("bytesAvailable");
}
}
}
1 change: 1 addition & 0 deletions SteamKit2/SteamKit2/Blob/Serializers/BooleanSerializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ public object Read(Object target, BlobReader reader)

public void EmitRead(JITContext context)
{
context.LoadBlobReader();
context.ReadFieldStream();
context.EmitStreamCall("ReadByte");
context.CompareGreaterThanZero();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ public void EmitRead(JITContext context)
case TypeCode.Int32:
context.LoadByteKey();
context.LoadIntConstant(0);
context.BitConvertToInt32();
context.BitConvertTo("Int32");
break;
case TypeCode.String:
context.PushUTF8Encoding();
Expand Down
6 changes: 4 additions & 2 deletions SteamKit2/SteamKit2/Blob/Serializers/Int16Serializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@ public object Read(Object target, BlobReader reader)

public void EmitRead(JITContext context)
{
context.LoadBlobReader();
context.ReadFieldStream();
context.EmitStreamCall("ReadInt16");
context.StreamRead(2, "Int16");
}
}

Expand All @@ -41,8 +42,9 @@ public object Read(Object target, BlobReader reader)

public void EmitRead(JITContext context)
{
context.LoadBlobReader();
context.ReadFieldStream();
context.EmitStreamCall("ReadUInt16");
context.StreamRead(2, "UInt16");
}
}
}
6 changes: 4 additions & 2 deletions SteamKit2/SteamKit2/Blob/Serializers/Int32Serializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@ public object Read(Object target, BlobReader reader)

public void EmitRead(JITContext context)
{
context.LoadBlobReader();
context.ReadFieldStream();
context.EmitStreamCall("ReadInt32");
context.StreamRead(4, "Int32");
}
}

Expand All @@ -41,8 +42,9 @@ public object Read(Object target, BlobReader reader)

public void EmitRead(JITContext context)
{
context.LoadBlobReader();
context.ReadFieldStream();
context.EmitStreamCall("ReadUInt32");
context.StreamRead(4, "UInt32");
}
}
}
Loading

0 comments on commit b3cc1c3

Please sign in to comment.