public Emit <Func <int> > EmitByteCode(CompilerContext context, Emit <Func <int> > emiter) { if (Operator == BinaryOperator.CONCAT) { return(EmitConcat(context, emiter)); } emiter = Left.EmitByteCode(context, emiter); emiter = Right.EmitByteCode(context, emiter); switch (Operator) { case BinaryOperator.ADD: { emiter = emiter.Add(); break; } case BinaryOperator.SUB: { emiter = emiter.Subtract(); break; } case BinaryOperator.MULTIPLY: { emiter = emiter.Multiply(); break; } case BinaryOperator.DIVIDE: { emiter = emiter.Divide(); break; } case BinaryOperator.EQUALS: { emiter = emiter.CompareEqual(); break; } case BinaryOperator.DIFFERENT: { emiter = emiter.CompareEqual(); emiter = emiter.Not(); break; } case BinaryOperator.OR: { emiter = emiter.Or(); break; } case BinaryOperator.AND: { emiter = emiter.And(); break; } case BinaryOperator.LESSER: { emiter = emiter.CompareLessThan(); break; } case BinaryOperator.GREATER: { emiter = emiter.CompareGreaterThan(); break; } } return(emiter); }
public void EmitDeserialize(Emit emiter, Local value) { var elementType = value.LocalType.GetElementType(); var emptyArray = emiter.DefineLabel(nameof(ArrayWithScalarSerializer) + "EmptyArray" + Guid.NewGuid()); var end = emiter.DefineLabel(nameof(ArrayWithScalarSerializer) + "End" + Guid.NewGuid()); using (var length = emiter.DeclareLocal <short>("length")) { emiter.CallDeserializerForType(length.LocalType, length); // if(length < 1) { // value = Array.Empty<>() // return // } emiter.LoadLocal(length); emiter.LoadConstant(1); emiter.BranchIfLess(emptyArray); // value = new [length] emiter.LoadLocal(length); emiter.NewArray(elementType); emiter.StoreLocal(value); var loop = emiter.DefineLabel(nameof(ArrayWithScalarSerializer) + "Loop" + Guid.NewGuid()); var loopCheck = emiter.DefineLabel(nameof(ArrayWithScalarSerializer) + "LoopCheck" + Guid.NewGuid()); // Little optimization for byte arrays if (elementType == typeof(byte)) { // value = reader.ReadBytes(length); emiter.LoadArgument(1); emiter.LoadLocal(length); emiter.CallVirtual(typeof(BinaryReader).GetMethod(nameof(BinaryReader.ReadBytes))); emiter.StoreLocal(value); emiter.Branch(end); } else { using (var element = emiter.DeclareLocal(elementType, "element")) using (var i = emiter.DeclareLocal <int>("i")) { emiter.MarkLabel(loop); emiter.CallDeserializerForType(elementType, element); // value[i] = element emiter.LoadLocal(value); emiter.LoadLocal(i); emiter.LoadLocal(element); emiter.StoreElement(elementType); // ++i emiter.LoadLocal(i); emiter.LoadConstant(1); emiter.Add(); emiter.StoreLocal(i); // i < length emiter.MarkLabel(loopCheck); emiter.LoadLocal(i); emiter.LoadLocal(length); emiter.BranchIfLess(loop); } } emiter.Branch(end); } // value = Array.Empty<>() emiter.MarkLabel(emptyArray); emiter.Call(typeof(Array) .GetMethod(nameof(Array.Empty)) .GetGenericMethodDefinition() .MakeGenericMethod(elementType)); emiter.StoreLocal(value); emiter.MarkLabel(end); }
public void EmitSerialize(Emit emiter, Local value) { using (var length = emiter.DeclareLocal <int>("length")) { // length = value.Length emiter.LoadLocal(value); emiter.Call(value.LocalType.GetProperty(nameof(Array.Length)).GetMethod); emiter.StoreLocal(length); var elementType = value.LocalType.GetElementType(); var loop = emiter.DefineLabel(); var loopCheck = emiter.DefineLabel(); var loopFill = emiter.DefineLabel(); var loopFillCheck = emiter.DefineLabel(); using (var element = emiter.DeclareLocal(elementType, "element")) using (var i = emiter.DeclareLocal <int>("i")) { emiter.Branch(loopCheck); emiter.MarkLabel(loop); // element = value[i] emiter.LoadLocal(value); emiter.LoadLocal(i); emiter.LoadElement(elementType); emiter.StoreLocal(element); emiter.CallSerializerForType(elementType, element); // ++i emiter.LoadLocal(i); emiter.LoadConstant(1); emiter.Add(); emiter.StoreLocal(i); // i < length emiter.MarkLabel(loopCheck); emiter.LoadLocal(i); emiter.LoadLocal(length); emiter.BranchIfLess(loop); emiter.Branch(loopFillCheck); emiter.MarkLabel(loopFill); // element = 0 emiter.LoadConstant(0); emiter.StoreLocal(element); emiter.CallSerializerForType(elementType, element); // ++i emiter.LoadLocal(i); emiter.LoadConstant(1); emiter.Add(); emiter.StoreLocal(i); emiter.MarkLabel(loopFillCheck); emiter.LoadLocal(i); emiter.LoadConstant(_size); emiter.BranchIfLess(loopFill); } } }
private static void SerializeValueArray(PropertyInfo propInfo, Emit <Action <T, StringBuilder, StringBuilder> > serializationEmitter) { var loopBodyLabel = serializationEmitter.DefineLabel(); var loopConditionLabel = serializationEmitter.DefineLabel(); var elementType = propInfo.PropertyType.GetElementType(); var isString = elementType == typeof(string); using (var stringLocal = serializationEmitter.DeclareLocal <string>()) using (var iterationLocal = serializationEmitter.DeclareLocal <int>()) { serializationEmitter.LoadConstant(0); serializationEmitter.StoreLocal(iterationLocal); serializationEmitter.Branch(loopConditionLabel); serializationEmitter.MarkLabel(loopBodyLabel); serializationEmitter.LoadConstant(isString ? @"'{0}', " : "{0}, "); serializationEmitter.LoadArgument(0); // instance serializationEmitter.CallVirtual(propInfo.GetGetMethod()); serializationEmitter.LoadLocal(iterationLocal); serializationEmitter.LoadElement(elementType); if (isString) { serializationEmitter.Call(stringEscape); serializationEmitter.LoadConstant(Environment.NewLine); serializationEmitter.LoadConstant(@"\n"); serializationEmitter.CallVirtual(stringReplace); } else { serializationEmitter.Box(elementType); } serializationEmitter.Call(stringFormat); serializationEmitter.StoreLocal(stringLocal); // Append to hotfix builder serializationEmitter.LoadArgument(1); // hotfixBuilder serializationEmitter.LoadLocal(stringLocal); serializationEmitter.Call(stringBuilderAppend); serializationEmitter.Pop(); if (isString) { // Append to locale builder if (localeBuilder != null) var localeBuilderMarker = serializationEmitter.DefineLabel(); serializationEmitter.LoadArgument(2); // instanceBuilder serializationEmitter.LoadNull(); serializationEmitter.CompareEqual(); serializationEmitter.BranchIfTrue(localeBuilderMarker); serializationEmitter.LoadArgument(2); // instanceBuilder serializationEmitter.LoadLocal(stringLocal); serializationEmitter.Call(stringBuilderAppend); serializationEmitter.Pop(); serializationEmitter.MarkLabel(localeBuilderMarker); } serializationEmitter.LoadLocal(iterationLocal); serializationEmitter.LoadConstant(1); serializationEmitter.Add(); serializationEmitter.StoreLocal(iterationLocal); serializationEmitter.MarkLabel(loopConditionLabel); serializationEmitter.LoadLocal(iterationLocal); serializationEmitter.LoadArgument(0); // instance serializationEmitter.CallVirtual(propInfo.GetGetMethod()); serializationEmitter.LoadLength(elementType); serializationEmitter.Convert <int>(); serializationEmitter.CompareLessThan(); serializationEmitter.BranchIfTrue(loopBodyLabel); } }
public static Emit <TDelegate> Increment <TDelegate>(this Emit <TDelegate> emiter, Type valueType) { emiter.LoadConstantOne(valueType); emiter.Add(); return(emiter); }
public void EmitDeserialize(Emit emiter, Local value) { var elementType = value.LocalType.GetElementType(); var emptyArray = emiter.DefineLabel(); var end = emiter.DefineLabel(); using (var length = emiter.DeclareLocal <T>("length")) { emiter.CallDeserializerForType(length.LocalType, length); // if(length < 1) { // value = Array.Empty<>() // return // } emiter.LoadLocal(length); emiter.LoadConstant(1); emiter.BranchIfLess(emptyArray); // value = new [length] emiter.LoadLocal(length); emiter.NewArray(elementType); emiter.StoreLocal(value); var loop = emiter.DefineLabel(); var loopCheck = emiter.DefineLabel(); using (var element = emiter.DeclareLocal(elementType, "element")) using (var i = emiter.DeclareLocal <T>("i")) { emiter.MarkLabel(loop); if (_compiler != null) { _compiler.EmitDeserialize(emiter, element); } else if (_serializer != null) { emiter.CallDeserializer(_serializer, element); } else { emiter.CallDeserializerForType(elementType, element); } // value[i] = element emiter.LoadLocal(value); emiter.LoadLocal(i); emiter.LoadLocal(element); emiter.StoreElement(elementType); // ++i emiter.LoadLocal(i); emiter.LoadConstant(1); emiter.Add(); emiter.StoreLocal(i); // i < length emiter.MarkLabel(loopCheck); emiter.LoadLocal(i); emiter.LoadLocal(length); emiter.BranchIfLess(loop); } emiter.Branch(end); } // value = Array.Empty<>() emiter.MarkLabel(emptyArray); emiter.Call(typeof(Array) .GetMethod(nameof(Array.Empty)) .GetGenericMethodDefinition() .MakeGenericMethod(elementType)); emiter.StoreLocal(value); emiter.MarkLabel(end); }
public void EmitDeserialize(Emit emiter, Local value) { var elementType = value.LocalType.GetElementType(); var emptyArray = emiter.DefineLabel(); var end = emiter.DefineLabel(); using (var length = emiter.DeclareLocal <int>("length")) { // length = ProudNetBinaryReaderExtensions.ReadScalar(reader) emiter.LoadArgument(1); emiter.Call(ReflectionHelper.GetMethod((BinaryReader x) => x.ReadScalar())); emiter.StoreLocal(length); // if(length < 1) { // value = Array.Empty<>() // return // } emiter.LoadLocal(length); emiter.LoadConstant(1); emiter.BranchIfLess(emptyArray); // value = new [length] emiter.LoadLocal(length); emiter.NewArray(elementType); emiter.StoreLocal(value); // Little optimization for byte arrays if (elementType == typeof(byte)) { // value = reader.ReadBytes(length); emiter.LoadArgument(1); emiter.LoadLocal(length); emiter.Call(ReflectionHelper.GetMethod((BinaryReader x) => x.ReadBytes(default(int)))); emiter.StoreLocal(value); } else { var loop = emiter.DefineLabel(); var loopCheck = emiter.DefineLabel(); using (var element = emiter.DeclareLocal(elementType, "element")) using (var i = emiter.DeclareLocal <int>("i")) { emiter.MarkLabel(loop); emiter.CallDeserializerForType(elementType, element); // value[i] = element emiter.LoadLocal(value); emiter.LoadLocal(i); emiter.LoadLocal(element); emiter.StoreElement(elementType); // ++i emiter.LoadLocal(i); emiter.LoadConstant(1); emiter.Add(); emiter.StoreLocal(i); // i < length emiter.MarkLabel(loopCheck); emiter.LoadLocal(i); emiter.LoadLocal(length); emiter.BranchIfLess(loop); } } emiter.Branch(end); } // value = Array.Empty<>() emiter.MarkLabel(emptyArray); emiter.Call(typeof(Array) .GetMethod(nameof(Array.Empty)) .GetGenericMethodDefinition() .MakeGenericMethod(elementType)); emiter.StoreLocal(value); emiter.MarkLabel(end); }
[Fact] public void TestAdd() => TestRoundTrip("x += 3", Emit.Add(Emit.Name("x"), Emit.Const(3)), ScriptParser.Expression);
[Fact] public void OrderTest06() => TestRoundTrip( "x.y += 10", Emit.Add( Emit.Member(Emit.Name("x"), Emit.Name("y")), Emit.Const(10) ), ScriptParser.Expression);