예제 #1
0
        unsafe void InitToken(ref OpCode code, object token, Dictionary <Mono.Cecil.Cil.Instruction, int> addr)
        {
            switch (code.Code)
            {
            case OpCodeEnum.Leave:
            case OpCodeEnum.Leave_S:
            case OpCodeEnum.Br:
            case OpCodeEnum.Br_S:
            case OpCodeEnum.Brtrue:
            case OpCodeEnum.Brtrue_S:
            case OpCodeEnum.Brfalse:
            case OpCodeEnum.Brfalse_S:
            //比较流程控制
            case OpCodeEnum.Beq:
            case OpCodeEnum.Beq_S:
            case OpCodeEnum.Bne_Un:
            case OpCodeEnum.Bne_Un_S:
            case OpCodeEnum.Bge:
            case OpCodeEnum.Bge_S:
            case OpCodeEnum.Bge_Un:
            case OpCodeEnum.Bge_Un_S:
            case OpCodeEnum.Bgt:
            case OpCodeEnum.Bgt_S:
            case OpCodeEnum.Bgt_Un:
            case OpCodeEnum.Bgt_Un_S:
            case OpCodeEnum.Ble:
            case OpCodeEnum.Ble_S:
            case OpCodeEnum.Ble_Un:
            case OpCodeEnum.Ble_Un_S:
            case OpCodeEnum.Blt:
            case OpCodeEnum.Blt_S:
            case OpCodeEnum.Blt_Un:
            case OpCodeEnum.Blt_Un_S:
                code.TokenInteger = addr[(Mono.Cecil.Cil.Instruction)token];
                break;

            case OpCodeEnum.Ldc_I4:
                code.TokenInteger = (int)token;
                break;

            case OpCodeEnum.Ldc_I4_S:
                code.TokenInteger = (sbyte)token;
                break;

            case OpCodeEnum.Ldc_I8:
                code.TokenLong = (long)token;
                break;

            case OpCodeEnum.Ldc_R4:
            {
                float val = (float)token;
                code.TokenInteger = *(int *)&val;
            }
            break;

            case OpCodeEnum.Ldc_R8:
            {
                double val = (double)token;
                code.TokenLong = *(long *)&val;
            }
            break;

            case OpCodeEnum.Stloc:
            case OpCodeEnum.Stloc_S:
            case OpCodeEnum.Ldloc:
            case OpCodeEnum.Ldloc_S:
            case OpCodeEnum.Ldloca:
            case OpCodeEnum.Ldloca_S:
            {
                Mono.Cecil.Cil.VariableDefinition vd = (Mono.Cecil.Cil.VariableDefinition)token;
                code.TokenInteger = vd.Index;
            }
            break;

            case OpCodeEnum.Ldarg_S:
            case OpCodeEnum.Ldarg:
            case OpCodeEnum.Ldarga:
            case OpCodeEnum.Ldarga_S:
            case OpCodeEnum.Starg:
            case OpCodeEnum.Starg_S:
            {
                Mono.Cecil.ParameterDefinition vd = (Mono.Cecil.ParameterDefinition)token;
                code.TokenInteger = vd.Index;
                if (HasThis)
                {
                    code.TokenInteger++;
                }
            }
            break;

            case OpCodeEnum.Call:
            case OpCodeEnum.Newobj:
            case OpCodeEnum.Ldftn:
            case OpCodeEnum.Ldvirtftn:
            case OpCodeEnum.Callvirt:
            {
                bool invalidToken;
                var  m = appdomain.GetMethod(token, declaringType, this, out invalidToken);
                if (m != null)
                {
                    if (invalidToken)
                    {
                        code.TokenInteger = m.GetHashCode();
                    }
                    else
                    {
                        code.TokenInteger = token.GetHashCode();
                    }
                }
                else
                {
                    //Cannot find method or the method is dummy
                    MethodReference _ref     = (MethodReference)token;
                    int             paramCnt = _ref.HasParameters ? _ref.Parameters.Count : 0;
                    if (_ref.HasThis)
                    {
                        paramCnt++;
                    }
                    code.TokenLong = paramCnt;
                }
            }
            break;

            case OpCodeEnum.Constrained:
            case OpCodeEnum.Box:
            case OpCodeEnum.Unbox_Any:
            case OpCodeEnum.Unbox:
            case OpCodeEnum.Initobj:
            case OpCodeEnum.Isinst:
            case OpCodeEnum.Newarr:
            case OpCodeEnum.Stobj:
            case OpCodeEnum.Ldobj:
            {
                code.TokenInteger = GetTypeTokenHashCode(token);
            }
            break;

            case OpCodeEnum.Stfld:
            case OpCodeEnum.Ldfld:
            case OpCodeEnum.Ldflda:
            {
                code.TokenLong = appdomain.GetStaticFieldIndex(token, declaringType, this);
            }
            break;

            case OpCodeEnum.Stsfld:
            case OpCodeEnum.Ldsfld:
            case OpCodeEnum.Ldsflda:
            {
                code.TokenLong = appdomain.GetStaticFieldIndex(token, declaringType, this);
            }
            break;

            case OpCodeEnum.Ldstr:
            {
                long hashCode = appdomain.CacheString(token);
                code.TokenLong = hashCode;
            }
            break;

            case OpCodeEnum.Ldtoken:
            {
                if (token is FieldReference)
                {
                    code.TokenInteger = 0;
                    code.TokenLong    = appdomain.GetStaticFieldIndex(token, declaringType, this);
                }
                else if (token is TypeReference)
                {
                    code.TokenInteger = 1;
                    code.TokenLong    = GetTypeTokenHashCode(token);
                }
                else
                {
                    throw new NotImplementedException();
                }
            }
            break;

            case OpCodeEnum.Switch:
            {
                PrepareJumpTable(token, addr);
                code.TokenInteger = token.GetHashCode();
            }
            break;
            }
        }