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); } }
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); }
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)); }
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; } } } }
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)); } } }