示例#1
0
        private static void CallBaseTypeFinalizer(MethodDefinition finalizer, CppCodeWriter writer, IRuntimeMetadataAccess metadataAccess)
        {
            MethodReference method = null;
            TypeDefinition  definition;

            Unity.IL2CPP.ILPreProcessor.TypeResolver resolver;
            for (TypeReference reference2 = finalizer.DeclaringType.BaseType; reference2 != null; reference2 = resolver.Resolve(definition.BaseType))
            {
                definition = reference2.Resolve();
                resolver   = Unity.IL2CPP.ILPreProcessor.TypeResolver.For(reference2);
                foreach (MethodDefinition definition2 in definition.Methods)
                {
                    if (definition2.IsFinalizerMethod())
                    {
                        method = resolver.Resolve(definition2);
                        break;
                    }
                }
            }
            if (method != null)
            {
                List <string> argumentArray = new List <string>(2)
                {
                    Naming.ThisParameterName
                };
                if (MethodSignatureWriter.NeedsHiddenMethodInfo(method, MethodCallType.Normal, false))
                {
                    argumentArray.Add(metadataAccess.HiddenMethodInfo(method));
                }
                Unity.IL2CPP.ILPreProcessor.TypeResolver typeResolverForMethodToCall = Unity.IL2CPP.ILPreProcessor.TypeResolver.For(finalizer.DeclaringType);
                string block = MethodBodyWriter.GetMethodCallExpression(finalizer, typeResolverForMethodToCall.Resolve(method), method, typeResolverForMethodToCall, MethodCallType.Normal, metadataAccess, new VTableBuilder(), argumentArray, false, null);
                writer.WriteStatement(block);
            }
        }
示例#2
0
        private static byte[] SerializeInstructions(CilBody body)
        {
            var writer = new MethodBodyWriter(new TokenProvider(), body);

            writer.Write();
            int codeSize = (int)(uint)codeSizeField.GetValue(writer);

            byte[] newCode = new byte[codeSize];
            Array.Copy(writer.Code, writer.Code.Length - codeSize, newCode, 0, codeSize);
            return(newCode);
        }
示例#3
0
        protected string GetMethodCallExpression(IRuntimeMetadataAccess metadataAccess, string thisArgument, IEnumerable <string> localVariableNames)
        {
            List <string> argumentArray = new List <string> {
                thisArgument
            };

            argumentArray.AddRange(localVariableNames);
            if (MethodSignatureWriter.NeedsHiddenMethodInfo(this._managedMethod, MethodCallType.Normal, false))
            {
                argumentArray.Add(metadataAccess.HiddenMethodInfo(this._managedMethod));
            }
            return("::" + MethodBodyWriter.GetMethodCallExpression(this._managedMethod, this._managedMethod, this._managedMethod, base._typeResolver, MethodCallType.Normal, metadataAccess, new VTableBuilder(), argumentArray, false, null));
        }
示例#4
0
        private void WriteMainInvocation(CppCodeWriter writer, IRuntimeMetadataAccess metadataAccess)
        {
            if (this.ValidateMainMethod(writer))
            {
                writer.AddIncludeForMethodDeclarations(_entryPoint.DeclaringType);
                List <string> argumentArray = new List <string> {
                    Naming.Null
                };
                if (_entryPoint.Parameters.Count > 0)
                {
                    ArrayType parameterType = (ArrayType)_entryPoint.Parameters[0].ParameterType;
                    writer.AddIncludeForTypeDefinition(parameterType);
                    object[] args = new object[] { Naming.ForVariable(parameterType), Emit.NewSZArray(parameterType, "argc - 1", metadataAccess) };
                    writer.WriteLine("{0} args = {1};", args);
                    writer.WriteLine();
                    writer.WriteLine("for (int i = 1; i < argc; i++)");
                    using (new BlockWriter(writer, false))
                    {
                        writer.WriteLine("DECLARE_NATIVE_C_STRING_AS_STRING_VIEW_OF_IL2CPP_CHARS(argumentUtf16, argv[i]);");
                        object[] objArray2 = new object[] { Naming.ForVariable(TypeProvider.SystemString) };
                        writer.WriteLine("{0} argument = il2cpp_codegen_string_new_utf16(argumentUtf16);", objArray2);
                        writer.WriteStatement(Emit.StoreArrayElement("args", "i - 1", "argument", false));
                    }
                    writer.WriteLine();
                    argumentArray.Add("args");
                }
                if (MethodSignatureWriter.NeedsHiddenMethodInfo(_entryPoint, MethodCallType.Normal, false))
                {
                    argumentArray.Add(metadataAccess.HiddenMethodInfo(_entryPoint));
                }
                if ((_entryPoint.DeclaringType.Attributes & (TypeAttributes.AnsiClass | TypeAttributes.BeforeFieldInit)) == TypeAttributes.AnsiClass)
                {
                    object[] objArray3 = new object[] { metadataAccess.TypeInfoFor(_entryPoint.DeclaringType) };
                    writer.WriteLine("IL2CPP_RUNTIME_CLASS_INIT({0});", objArray3);
                }
                Unity.IL2CPP.ILPreProcessor.TypeResolver typeResolverForMethodToCall = Unity.IL2CPP.ILPreProcessor.TypeResolver.For(_entryPoint.DeclaringType, _entryPoint);
                string block = MethodBodyWriter.GetMethodCallExpression(null, _entryPoint, _entryPoint, typeResolverForMethodToCall, MethodCallType.Normal, metadataAccess, new VTableBuilder(), argumentArray, false, null);
                switch (_entryPoint.ReturnType.MetadataType)
                {
                case MetadataType.Void:
                    writer.WriteStatement(block);
                    writer.WriteLine("return 0;");
                    break;

                case MetadataType.Int32:
                {
                    object[] objArray4 = new object[] { block };
                    writer.WriteLine("return {0};", objArray4);
                    break;
                }

                case MetadataType.UInt32:
                {
                    object[] objArray5 = new object[] { block };
                    writer.WriteLine("uint32_t exitCode = {0};", objArray5);
                    writer.WriteLine("return static_cast<int>(exitCode);");
                    break;
                }
                }
            }
        }
示例#5
0
        internal FunctionEmitter(IR.Function function, MethodFactory methodFactory, FunctionLookup functionLookup)
        {
            Contract.Requires(function != null);
            Contract.Requires(methodFactory != null);
            Contract.Requires(functionLookup != null);

            this.declaration    = function;
            this.functionLookup = functionLookup;
            var signature = new FunctionSignature(function.Inputs.Select(i => i.StaticRepr), function.Outputs.Select(o => o.StaticRepr));

            // Determine the method signature
            var parameterDescriptors = new List <ParameterDescriptor>();

            foreach (var input in function.Inputs)
            {
                locals.Add(input, VariableLocation.Parameter(parameterDescriptors.Count));
                parameterDescriptors.Add(new ParameterDescriptor(input.StaticCliType, ParameterAttributes.None, input.Name));
            }

            Type returnType = typeof(void);

            if (function.Outputs.Length == 1)
            {
                returnType = function.Outputs[0].StaticCliType;                 // 1 output, use return value
            }
            else if (function.Outputs.Length >= 2)
            {
                // 2 or more outputs, use 'out' parameters
                foreach (var output in function.Outputs)
                {
                    string name = output.Name;
                    if (locals.ContainsKey(output))
                    {
                        // inout parameter, rename not to clash with input
                        name += "$out";
                    }
                    else
                    {
                        locals.Add(output, VariableLocation.Parameter(parameterDescriptors.Count));
                    }

                    var parameterType = output.StaticCliType.MakeByRefType();
                    parameterDescriptors.Add(new ParameterDescriptor(parameterType, ParameterAttributes.Out, name));
                }
            }

            // Create the method and get its IL generator
            ILGenerator ilGenerator;
            var         methodInfo = methodFactory(function.Name, parameterDescriptors, returnType, out ilGenerator);

            this.method = new FunctionMethod(methodInfo, signature);

            cil = new ILGeneratorMethodBodyWriter(ilGenerator);
            cil = new MethodBodyVerifier(new MethodBodyVerificationContext
            {
                Method         = methodInfo,
                ParameterTypes = parameterDescriptors.Select(p => p.Type).ToArray(),
                ReturnType     = returnType,
                HasInitLocals  = true,
                MaxStackSize   = ushort.MaxValue
            }, cil);

            temporaryPool = new TemporaryLocalPool(cil, "$temp");

            if (function.Outputs.Length == 1)
            {
                // Declare a local variable for the return value
                var output     = function.Outputs[0];
                var localIndex = cil.DeclareLocal(output.StaticCliType, output.Name);
                if (!function.Inputs.Contains(output))
                {
                    locals.Add(output, VariableLocation.Local(localIndex));
                }
            }
        }