예제 #1
0
        /*public static ProtoCallback BuildCallback(IProtoTypeSerializer head)
         * {
         *  Type type = head.ExpectedType;
         *  CompilerContext ctx = new CompilerContext(type, true, true);
         *  using (Local typedVal = new Local(ctx, type))
         *  {
         *      ctx.LoadValue(Local.InputValue);
         *      ctx.CastFromObject(type);
         *      ctx.StoreValue(typedVal);
         *      CodeLabel[] jumpTable = new CodeLabel[4];
         *      for(int i = 0 ; i < jumpTable.Length ; i++) {
         *          jumpTable[i] = ctx.DefineLabel();
         *      }
         *      ctx.LoadReaderWriter();
         *      ctx.Switch(jumpTable);
         *      ctx.Return();
         *      for(int i = 0 ; i < jumpTable.Length ; i++) {
         *          ctx.MarkLabel(jumpTable[i]);
         *          if (head.HasCallbacks((TypeModel.CallbackType)i))
         *          {
         *              head.EmitCallback(ctx, typedVal, (TypeModel.CallbackType)i);
         *          }
         *          ctx.Return();
         *      }
         *  }
         *
         *  ctx.Emit(OpCodes.Ret);
         *  return (ProtoCallback)ctx.method.CreateDelegate(
         *      typeof(ProtoCallback));
         * }*/
        public static ProtoDeserializer BuildDeserializer(IProtoSerializer head, TypeModel model)
        {
            Type            type = head.ExpectedType;
            CompilerContext ctx  = new CompilerContext(type, false, true, model);

            using (Local typedVal = new Local(ctx, type))
            {
                if (!type.IsValueType)
                {
                    ctx.LoadValue(Local.InputValue);
                    ctx.CastFromObject(type);
                    ctx.StoreValue(typedVal);
                }
                else
                {
                    ctx.LoadValue(Local.InputValue);
                    CodeLabel notNull = ctx.DefineLabel(), endNull = ctx.DefineLabel();
                    ctx.BranchIfTrue(notNull, true);

                    ctx.LoadAddress(typedVal, type);
                    ctx.EmitCtor(type);
                    ctx.Branch(endNull, true);

                    ctx.MarkLabel(notNull);
                    ctx.LoadValue(Local.InputValue);
                    ctx.CastFromObject(type);
                    ctx.StoreValue(typedVal);

                    ctx.MarkLabel(endNull);
                }
                head.EmitRead(ctx, typedVal);

                if (head.ReturnsValue)
                {
                    ctx.StoreValue(typedVal);
                }

                ctx.LoadValue(typedVal);
                ctx.CastToObject(type);
            }
            ctx.Emit(OpCodes.Ret);
            return((ProtoDeserializer)ctx.method.CreateDelegate(
                       typeof(ProtoDeserializer)));
        }
예제 #2
0
        public static ProtoDeserializer BuildDeserializer(IProtoSerializer head, TypeModel model)
        {
            Type            expectedType    = head.ExpectedType;
            CompilerContext compilerContext = new CompilerContext(expectedType, false, true, model, typeof(object));

            using (Local local = new Local(compilerContext, expectedType))
            {
                if (expectedType.IsValueType)
                {
                    compilerContext.LoadValue(compilerContext.InputValue);
                    CodeLabel codeLabel  = compilerContext.DefineLabel();
                    CodeLabel codeLabel1 = compilerContext.DefineLabel();
                    compilerContext.BranchIfTrue(codeLabel, true);
                    compilerContext.LoadAddress(local, expectedType);
                    compilerContext.EmitCtor(expectedType);
                    compilerContext.Branch(codeLabel1, true);
                    compilerContext.MarkLabel(codeLabel);
                    compilerContext.LoadValue(compilerContext.InputValue);
                    compilerContext.CastFromObject(expectedType);
                    compilerContext.StoreValue(local);
                    compilerContext.MarkLabel(codeLabel1);
                }
                else
                {
                    compilerContext.LoadValue(compilerContext.InputValue);
                    compilerContext.CastFromObject(expectedType);
                    compilerContext.StoreValue(local);
                }
                head.EmitRead(compilerContext, local);
                if (head.ReturnsValue)
                {
                    compilerContext.StoreValue(local);
                }
                compilerContext.LoadValue(local);
                compilerContext.CastToObject(expectedType);
            }
            compilerContext.Emit(OpCodes.Ret);
            return((ProtoDeserializer)compilerContext.method.CreateDelegate(typeof(ProtoDeserializer)));
        }
예제 #3
0
        /*public static ProtoCallback BuildCallback(IProtoTypeSerializer head)
        {
            Type type = head.ExpectedType;
            CompilerContext ctx = new CompilerContext(type, true, true);
            using (Local typedVal = new Local(ctx, type))
            {
                ctx.LoadValue(Local.InputValue);
                ctx.CastFromObject(type);
                ctx.StoreValue(typedVal);
                CodeLabel[] jumpTable = new CodeLabel[4];
                for(int i = 0 ; i < jumpTable.Length ; i++) {
                    jumpTable[i] = ctx.DefineLabel();
                }
                ctx.LoadReaderWriter();
                ctx.Switch(jumpTable);
                ctx.Return();
                for(int i = 0 ; i < jumpTable.Length ; i++) {
                    ctx.MarkLabel(jumpTable[i]);
                    if (head.HasCallbacks((TypeModel.CallbackType)i))
                    {
                        head.EmitCallback(ctx, typedVal, (TypeModel.CallbackType)i);
                    }
                    ctx.Return();
                }
            }

            ctx.Emit(OpCodes.Ret);
            return (ProtoCallback)ctx.method.CreateDelegate(
                typeof(ProtoCallback));
        }*/
        public static ProtoDeserializer BuildDeserializer(IProtoSerializer head, TypeModel model)
        {
            Type type = head.ExpectedType;
            CompilerContext ctx = new CompilerContext(type, false, true, model, typeof(object));

            using (Local typedVal = new Local(ctx, type))
            {
                if (!type.IsValueType)
                {
                    ctx.LoadValue(ctx.InputValue);
                    ctx.CastFromObject(type);
                    ctx.StoreValue(typedVal);
                }
                else
                {
                    ctx.LoadValue(ctx.InputValue);
                    CodeLabel notNull = ctx.DefineLabel(), endNull = ctx.DefineLabel();
                    ctx.BranchIfTrue(notNull, true);

                    ctx.LoadAddress(typedVal, type);
                    ctx.EmitCtor(type);
                    ctx.Branch(endNull, true);

                    ctx.MarkLabel(notNull);
                    ctx.LoadValue(ctx.InputValue);
                    ctx.CastFromObject(type);
                    ctx.StoreValue(typedVal);

                    ctx.MarkLabel(endNull);
                }
                head.EmitRead(ctx, typedVal);

                if (head.ReturnsValue) {
                    ctx.StoreValue(typedVal);
                }

                ctx.LoadValue(typedVal);
                ctx.CastToObject(type);
            }
            ctx.Emit(OpCodes.Ret);
            return (ProtoDeserializer)ctx.method.CreateDelegate(
                typeof(ProtoDeserializer));
        }