public void LoadValue(Local local) { if (local == null) /* nothing to do; top of stack */ } {
protected override void EmitWrite(ProtoBuf.Compiler.CompilerContext ctx, ProtoBuf.Compiler.Local valueFrom) { if (arrayType.GetArrayRank() > 1) { return; } // int i and T[] arr using (Compiler.Local arr = ctx.GetLocalWithValue(arrayType, valueFrom)) using (Compiler.Local len = new Compiler.Local(ctx, typeof(int))) using (Compiler.Local i = new ProtoBuf.Compiler.Local(ctx, typeof(int))) using (Compiler.Local writeObject = new Compiler.Local(ctx, typeof(bool))) { // int len = arr.Count; ctx.LoadValue(arr); ctx.LoadValue(arrayType.GetProperty("Length")); ctx.StoreValue(len); // writeObject = true; ctx.LoadValue(true); ctx.StoreValue(writeObject); bool writePacked = (options & OPTIONS_WritePacked) != 0; using (Compiler.Local token = writePacked ? new Compiler.Local(ctx, typeof(SubItemToken)) : null) { if (writePacked) { ctx.LoadValue(fieldNumber); ctx.LoadValue((int)WireType.String); ctx.LoadReaderWriter(); ctx.EmitCall(typeof(ProtoWriter).GetMethod("WriteFieldHeader")); ctx.LoadValue(arr); ctx.LoadReaderWriter(); ctx.EmitCall(typeof(ProtoWriter).GetMethod("StartSubItem")); ctx.StoreValue(token); ctx.LoadValue(fieldNumber); ctx.LoadReaderWriter(); ctx.EmitCall(typeof(ProtoWriter).GetMethod("SetPackedField")); } else { ctx.LoadValue(fieldNumber); ctx.LoadValue((int)WireType.Variant); ctx.LoadReaderWriter(); ctx.EmitCall(typeof(ProtoWriter).GetMethod("WriteFieldHeader")); if (AsReference) { using (Compiler.Local existing = new Compiler.Local(ctx, typeof(bool))) using (Compiler.Local objectKey = new Compiler.Local(ctx, typeof(int))) { //int objectKey = dest.NetCache.AddObjectKey(value, out existing); ctx.LoadReaderWriter(); ctx.LoadValue(typeof(ProtoWriter).GetProperty("NetCache")); //dest.NetCache ctx.LoadValue(arr); ctx.LoadAddress(existing, typeof(bool)); ctx.EmitCall(typeof(NetObjectCache).GetMethod("AddObjectKey", new Type[] { typeof(object), typeof(bool).MakeByRefType() })); ctx.StoreValue(objectKey); //writeObject = !existing; ctx.LoadValue(existing); Compiler.CodeLabel @writeBoolean = ctx.DefineLabel(); Compiler.CodeLabel @trueCase = ctx.DefineLabel(); ctx.BranchIfTrue(@trueCase, true); ctx.LoadValue(true); ctx.Branch(@writeBoolean, true); ctx.MarkLabel(@trueCase); ctx.LoadValue(false); ctx.MarkLabel(@writeBoolean); ctx.StoreValue(writeObject); //ProtoWriter.WriteUInt32(existing ? (uint)objectKey : 0, dest); using (Compiler.Local valueToWrite = new Compiler.Local(ctx, typeof(uint))) { ctx.LoadValue(0); ctx.StoreValue(valueToWrite); Compiler.CodeLabel @endValueWrite = ctx.DefineLabel(); ctx.LoadValue(existing); ctx.BranchIfFalse(@endValueWrite, true); ctx.LoadValue(objectKey); ctx.CastToObject(typeof(uint)); ctx.StoreValue(valueToWrite); ctx.MarkLabel(@endValueWrite); ctx.LoadValue(valueToWrite); ctx.LoadReaderWriter(); ctx.EmitCall(typeof(ProtoWriter).GetMethod("WriteUInt32")); } } } else { // bool isEmpty = len == 0; // ProtoWriter.WriteBoolean(isEmpty, dest); ctx.LoadValue(len); ctx.LoadValue(0); ctx.TestEqual(); ctx.LoadReaderWriter(); ctx.EmitCall(typeof(ProtoWriter).GetMethod("WriteBoolean")); } } Compiler.CodeLabel @endWrite = ctx.DefineLabel(); ctx.LoadValue(writeObject); ctx.BranchIfFalse(@endWrite, false); EmitWriteArrayLoop(ctx, i, arr); ctx.MarkLabel(@endWrite); if (writePacked) { ctx.LoadValue(token); ctx.LoadReaderWriter(); ctx.EmitCall(typeof(ProtoWriter).GetMethod("EndSubItem")); } } } }
internal void LoadArrayValue(Local arr, Local i) { Type type = arr.Type; type = type.GetElementType(); this.LoadValue(arr); this.LoadValue(i); switch (Helpers.GetTypeCode(type)) { case ProtoTypeCode.SByte: { this.Emit(OpCodes.Ldelem_I1); return; } case ProtoTypeCode.Byte: { this.Emit(OpCodes.Ldelem_U1); return; } case ProtoTypeCode.Int16: { this.Emit(OpCodes.Ldelem_I2); return; } case ProtoTypeCode.UInt16: { this.Emit(OpCodes.Ldelem_U2); return; } case ProtoTypeCode.Int32: { this.Emit(OpCodes.Ldelem_I4); return; } case ProtoTypeCode.UInt32: { this.Emit(OpCodes.Ldelem_U4); return; } case ProtoTypeCode.Int64: { this.Emit(OpCodes.Ldelem_I8); return; } case ProtoTypeCode.UInt64: { this.Emit(OpCodes.Ldelem_I8); return; } case ProtoTypeCode.Single: { this.Emit(OpCodes.Ldelem_R4); return; } case ProtoTypeCode.Double: { this.Emit(OpCodes.Ldelem_R8); return; } } if (!type.IsValueType) { this.Emit(OpCodes.Ldelem_Ref); return; } this.il.Emit(OpCodes.Ldelema, type); this.il.Emit(OpCodes.Ldobj, type); }
internal void CreateArray(Type elementType, Local length) { this.LoadValue(length); this.il.Emit(OpCodes.Newarr, elementType); }
public IDisposable Using(Local local) { return(new CompilerContext.UsingBlock(this, local)); }
private bool UseShortForm(Local local) { return(local.Value.LocalIndex < 256); }
public void Switch(CodeLabel[] jumpTable) { if ((int)jumpTable.Length <= 128) { Label[] value = new Label[(int)jumpTable.Length]; for (int i = 0; i < (int)value.Length; i++) { value[i] = jumpTable[i].Value; } this.il.Emit(OpCodes.Switch, value); return; } using (Local localWithValue = this.GetLocalWithValue(this.MapType(typeof(int)), null)) { int length = (int)jumpTable.Length; int num = 0; int num1 = length / 128; if (length % 128 != 0) { num1++; } Label[] labelArray = new Label[num1]; for (int j = 0; j < num1; j++) { labelArray[j] = this.il.DefineLabel(); } CodeLabel codeLabel = this.DefineLabel(); this.LoadValue(localWithValue); this.LoadValue(128); this.Emit(OpCodes.Div); this.il.Emit(OpCodes.Switch, labelArray); this.Branch(codeLabel, false); Label[] value1 = new Label[128]; for (int k = 0; k < num1; k++) { this.il.MarkLabel(labelArray[k]); int num2 = Math.Min(128, length); length -= num2; if ((int)value1.Length != num2) { value1 = new Label[num2]; } int num3 = num; for (int l = 0; l < num2; l++) { int num4 = num; num = num4 + 1; value1[l] = jumpTable[num4].Value; } this.LoadValue(localWithValue); if (num3 != 0) { this.LoadValue(num3); this.Emit(OpCodes.Sub); } this.il.Emit(OpCodes.Switch, value1); if (length != 0) { this.Branch(codeLabel, false); } } this.MarkLabel(codeLabel); } }