コード例 #1
0
        void UpdateRegistrationSwitch(MethodDefinition method, MethodReference[] switchMethods)
        {
            var instructions       = method.Body.Instructions;
            var module             = method.DeclaringType.Module;
            var switchInstructions = new Instruction [switchMethods.Length];

            instructions.Clear();

            var typeNullable            = _context.GetType("mscorlib", "System.Nullable`1");
            var methodGetValueOrDefault = Extensions.GetMethod(typeNullable, "GetValueOrDefault");
            var genericTypeNullable     = new GenericInstanceType(typeNullable);

            genericTypeNullable.GenericArguments.Add(_context.GetType("mscorlib", "System.Int32"));

            var typeIdxVariable = new VariableDefinition(module.ImportReference(genericTypeNullable));

            method.Body.Variables.Clear();
            method.Body.Variables.Add(typeIdxVariable);

            instructions.Add(Instruction.Create(OpCodes.Ldarg_1));
            instructions.Add(Instruction.Create(OpCodes.Stloc_0));
            instructions.Add(Instruction.Create(OpCodes.Ldloca_S, typeIdxVariable));

            var genericMethodGetValueOrDefault = CreateGenericMethodReference(methodGetValueOrDefault, genericTypeNullable);

            instructions.Add(Instruction.Create(OpCodes.Call, module.ImportReference(genericMethodGetValueOrDefault)));

            for (var i = 0; i < switchMethods.Length; i++)
            {
                switchInstructions [i] = Instruction.Create(OpCodes.Ldtoken, switchMethods [i].DeclaringType);
            }

            var typeType = _context.GetType("mscorlib", "System.Type");
            var methodGetTypeFromHandle = _context.GetMethod("mscorlib", "System.Type", "GetTypeFromHandle", new string[] { "System.RuntimeTypeHandle" });
            var callDelegateStart       = Instruction.Create(OpCodes.Call, module.ImportReference(methodGetTypeFromHandle));

            instructions.Add(Instruction.Create(OpCodes.Switch, switchInstructions));

            for (var i = 0; i < switchMethods.Length; i++)
            {
                instructions.Add(switchInstructions [i]);
                instructions.Add(Instruction.Create(OpCodes.Br, callDelegateStart));
            }

            instructions.Add(Instruction.Create(OpCodes.Ldc_I4_0));
            instructions.Add(Instruction.Create(OpCodes.Ret));

            var actionType = _context.GetType("mscorlib", "System.Action`1");

            var genericActionType = new GenericInstanceType(actionType);
            var argsType          = _context.GetType("Java.Interop", "Java.Interop.JniNativeMethodRegistrationArguments");

            genericActionType.GenericArguments.Add(argsType);

            MarkType(genericActionType);

            var actionInvoke         = Extensions.GetMethod(actionType, "Invoke", new string[] { "T" });
            var methodGetMethod      = _context.GetMethod("mscorlib", "System.Type", "GetMethod", new string[] { "System.String" });
            var typeMethodInfo       = _context.GetType("mscorlib", "System.Reflection.MethodInfo");
            var methodCreateDelegate = _context.GetMethod("mscorlib", "System.Reflection.MethodInfo", "CreateDelegate", new string[] { "System.Type" });

            instructions.Add(callDelegateStart);

            instructions.Add(Instruction.Create(OpCodes.Ldstr, "__RegisterNativeMembers"));
            instructions.Add(Instruction.Create(OpCodes.Call, module.ImportReference(methodGetMethod)));

            instructions.Add(Instruction.Create(OpCodes.Ldtoken, module.ImportReference(genericActionType)));
            instructions.Add(Instruction.Create(OpCodes.Call, module.ImportReference(methodGetTypeFromHandle)));

            instructions.Add(Instruction.Create(OpCodes.Callvirt, module.ImportReference(methodCreateDelegate)));

            instructions.Add(Instruction.Create(OpCodes.Castclass, module.ImportReference(genericActionType)));

            var genericActionInvoke = CreateGenericMethodReference(actionInvoke, genericActionType);

            instructions.Add(Instruction.Create(OpCodes.Ldarg_0));
            instructions.Add(Instruction.Create(OpCodes.Callvirt, module.ImportReference(genericActionInvoke)));

            instructions.Add(Instruction.Create(OpCodes.Ldc_I4_1));
            instructions.Add(Instruction.Create(OpCodes.Ret));
        }