Beispiel #1
0
        void UpdateMagicPrefill(TypeDefinition magicType)
        {
            var fieldTypesMap = magicType.Fields.FirstOrDefault(f => f.Name == "typesMap");

            if (fieldTypesMap == null)
            {
                return;
            }

            var methodPrefill = Extensions.GetMethod(magicType, "Prefill");

            if (methodPrefill == null)
            {
                return;
            }

            var typeDictionary        = _context.GetType("mscorlib", "System.Collections.Generic.Dictionary`2");
            var ctorDictionary        = Extensions.GetMethod(typeDictionary, ".ctor", new string[] { "System.Int32" });
            var methodSetItem         = Extensions.GetMethod(typeDictionary, "set_Item", new string[] { "TKey", "TValue" });
            var genericTypeDictionary = new GenericInstanceType(typeDictionary);

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

            var genericMethodDictionaryCtor    = CreateGenericMethodReference(ctorDictionary, genericTypeDictionary);
            var genericMethodDictionarySetItem = CreateGenericMethodReference(methodSetItem, genericTypeDictionary);
            var importedMethodSetItem          = magicType.Module.ImportReference(genericMethodDictionarySetItem);

            var instructions = methodPrefill.Body.Instructions;

            instructions.Clear();

            instructions.Add(Extensions.CreateLoadArraySizeOrOffsetInstruction(marshalTypes.Count));
            instructions.Add(Instruction.Create(OpCodes.Newobj, magicType.Module.ImportReference(genericMethodDictionaryCtor)));
            instructions.Add(Instruction.Create(OpCodes.Stsfld, fieldTypesMap));

            int idx = 0;

            foreach (var type in marshalTypes)
            {
                instructions.Add(Instruction.Create(OpCodes.Ldsfld, fieldTypesMap));
                instructions.Add(Instruction.Create(OpCodes.Ldstr, type.FullName.Replace("/__<$>_jni_marshal_methods", "").Replace("/", "+")));
                instructions.Add(Extensions.CreateLoadArraySizeOrOffsetInstruction(idx++));
                instructions.Add(Instruction.Create(OpCodes.Callvirt, importedMethodSetItem));
            }

            instructions.Add(Instruction.Create(OpCodes.Ret));
        }
        MethodDefinition GetKeepAliveMethod()
        {
            var corlibAssembly = GetCorlibAssembly();

            if (corlibAssembly == null)
            {
                return(null);
            }

            var gcType = Extensions.GetType(corlibAssembly, "System.GC");

            if (gcType == null)
            {
                return(null);
            }

            return(Extensions.GetMethod(gcType, "KeepAlive", new string [] { "System.Object" }));
        }
Beispiel #3
0
        void UpdateMagicRegistration()
        {
            TypeDefinition magicType = _context.GetType("Mono.Android", "Android.Runtime.AndroidTypeManager/MagicRegistrationMap");

            if (magicType == null)
            {
                return;
            }

            MethodDefinition magicCall = Extensions.GetMethod(magicType, "CallRegisterMethodByIndex");

            if (magicCall == null)
            {
                return;
            }

            var switchMethods = new MethodReference [marshalTypes.Count];
            var module        = magicType.Module;
            int idx           = 0;

            foreach (var type in marshalTypes)
            {
                var md = Extensions.GetMethod(type, "__RegisterNativeMembers");
                if (md == null)
                {
                    return;
                }

                var resolved = md.Resolve();
                if (resolved == null)
                {
                    return;
                }

                switchMethods [idx++] = module.ImportReference(resolved);
            }

            UpdateMagicPrefill(magicType);
            UpdateRegistrationSwitch(magicCall, switchMethods);
        }
Beispiel #4
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));
        }