/// <summary> /// Writes the Cil _header. /// </summary> /// <param name="compiler">The assembly compiler.</param> /// <param name="linker">The linker.</param> private void WriteCilHeader(AssemblyCompiler compiler, IAssemblyLinker linker) { using (Stream stream = linker.Allocate(CLI_HEADER.SymbolName, SectionKind.Text, CLI_HEADER.Length, 4)) using (BinaryWriter bw = new BinaryWriter(stream, Encoding.ASCII)) { _cliHeader.Write(bw); } }
static void Main(string[] args) { string text = @"namespace HelloWorld { public class Test { public Test(){ Name=""111""; } public string Name; public int Age{get;set;} } }"; //根据脚本创建动态类 AssemblyCompiler oop = new AssemblyCompiler("test"); oop.Add(text); Type type = oop.GetType("Test"); Console.WriteLine(type.Name); var action = NDelegate.Random().Action(""); var a = action.Method; Console.WriteLine(action.Method.Module.Assembly); Console.ReadKey(); }
/// <summary> /// Convert node with code Cast. /// </summary> private static void ConvertCastclass(AssemblyCompiler compiler, AstExpression node, XTypeSystem typeSystem) { var type = (XTypeReference)node.Operand; if (type.IsSystemArray()) { // Call cast method var arrayHelper = compiler.GetDot42InternalType(InternalConstants.CompilerHelperName).Resolve(); var castToArray = arrayHelper.Methods.First(x => x.Name == "CastToArray"); var castToArrayExpr = new AstExpression(node.SourceLocation, AstCode.Call, castToArray, node.Arguments).SetType(type); node.CopyFrom(castToArrayExpr); return; } string castMethod = null; if (type.IsSystemCollectionsIEnumerable()) { castMethod = "CastToEnumerable"; } else if (type.IsSystemCollectionsICollection()) { castMethod = "CastToCollection"; } else if (type.IsSystemCollectionsIList()) { castMethod = "CastToList"; } else if (type.IsSystemIFormattable()) { castMethod = "CastToFormattable"; } if (castMethod != null) { // Call cast method var arrayHelper = compiler.GetDot42InternalType(InternalConstants.CompilerHelperName).Resolve(); var castToArray = arrayHelper.Methods.First(x => x.Name == castMethod); // Call "(x instanceof T) ? (T)x : asMethod(x)" // "instanceof x" var instanceofExpr = new AstExpression(node.SourceLocation, AstCode.SimpleInstanceOf, type, node.Arguments[0]).SetType(typeSystem.Bool); // CastX(x) var castXExpr = new AstExpression(node.SourceLocation, AstCode.Call, castToArray, node.Arguments[0]).SetType(typeSystem.Object); // T(x) var txExpr = new AstExpression(node.SourceLocation, AstCode.SimpleCastclass, type, node.Arguments[0]).SetType(type); // Combine var conditional = new AstExpression(node.SourceLocation, AstCode.Conditional, type, instanceofExpr, txExpr, castXExpr).SetType(type); node.CopyFrom(conditional); return; } // Normal castclass node.Code = AstCode.SimpleCastclass; }
/// <summary> /// Optimize expressions /// </summary> public static void Convert(AstNode ast, AssemblyCompiler compiler) { // Convert IntPtr.Zero foreach (var node in ast.GetExpressions(AstCode.Ldsfld)) { var field = (XFieldReference)node.Operand; if (field.DeclaringType.IsIntPtr() && (field.Name == "Zero")) { node.Code = AstCode.Ldnull; node.Operand = null; node.Arguments.Clear(); node.SetType(compiler.Module.TypeSystem.Object); } } // Convert box(IntPtr) foreach (var node in ast.GetExpressions(AstCode.Box)) { var type = (XTypeReference)node.Operand; if (type.IsIntPtr()) { node.CopyFrom(node.Arguments[0]); } } }
/// <summary> /// Default ctor /// </summary> internal ReachableContext(AssemblyCompiler compiler, IEnumerable <AssemblyNameDefinition> assemblyNames, IEnumerable <string> rootClassNames) { this.compiler = compiler; this.rootClassNames = new HashSet <string>(rootClassNames.Select(x => x.ToLowerInvariant())); this.assemblyClassLoader = compiler.ClassLoader; this.assemblyNames = assemblyNames.ToList(); }
public void ApplicationAssemblyInclusion_DependsOnAttribute() { string compiledAssemblyPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "NonApplicationMarkedAssembly.dll"); try { AppDomainRunner.Run( delegate(object[] args) { var path = (string)args[0]; ApplicationAssemblyLoaderFilter filter = ApplicationAssemblyLoaderFilter.Instance; Assert.That(filter.ShouldIncludeAssembly(typeof(AttributeAssemblyLoaderFilterTest).Assembly), Is.True); Assert.That(filter.ShouldIncludeAssembly(typeof(TestFixtureAttribute).Assembly), Is.True); Assert.That(filter.ShouldIncludeAssembly(typeof(ApplicationAssemblyLoaderFilter).Assembly), Is.True); Assert.That(filter.ShouldIncludeAssembly(typeof(object).Assembly), Is.True); Assert.That(filter.ShouldIncludeAssembly(typeof(Uri).Assembly), Is.True); var assemblyCompiler = new AssemblyCompiler(@"Reflection\TypeDiscovery\TestAssemblies\NonApplicationMarkedAssembly", path, typeof(NonApplicationAssemblyAttribute).Assembly.Location); assemblyCompiler.Compile(); Assert.That(filter.ShouldIncludeAssembly(assemblyCompiler.CompiledAssembly), Is.False); }, compiledAssemblyPath); } finally { if (File.Exists(compiledAssemblyPath)) { FileUtility.DeleteAndWaitForCompletion(compiledAssemblyPath); } } }
/// <summary> /// Create an annotation for the given attribute /// </summary> private static void CreateAttributeAnnotation(AssemblyCompiler compiler, CustomAttribute attribute, TypeDefinition attributeType, List <Annotation> annotationList, DexTargetPackage targetPackage) { // Gets the mapping for the type of attribute var mapping = compiler.GetAttributeAnnotationMapping(attributeType); MethodDefinition factoryMethod; // Note: not multithreading capable. see my comments elsewhere. if (mapping.FactoryMethodMap.ContainsKey(attribute)) { factoryMethod = mapping.FactoryMethodMap[attribute]; } else { // create the factory method. factoryMethod = CreateFactoryMethod(compiler, targetPackage, attribute, mapping); mapping.FactoryMethodMap[attribute] = factoryMethod; } // Create attribute annotation var attrAnnotation = new Annotation { Visibility = AnnotationVisibility.Runtime }; attrAnnotation.Type = compiler.GetDot42InternalType("IAttribute").GetClassReference(targetPackage); attrAnnotation.Arguments.Add(new AnnotationArgument("AttributeType", attributeType.GetReference(targetPackage, compiler.Module))); attrAnnotation.Arguments.Add(new AnnotationArgument("FactoryMethod", factoryMethod.Name)); // Add annotation annotationList.Add(attrAnnotation); }
/// <summary> /// Optimize expressions /// </summary> public static void Convert(AstNode ast, AssemblyCompiler compiler) { // Optimize enum2int(ldsfld(enum-const)) foreach (var node in ast.GetExpressions()) { switch (node.Code) { case AstCode.Enum_to_int: case AstCode.Enum_to_long: { var arg = node.Arguments[0]; XFieldReference fieldRef; if (arg.Match(AstCode.Ldsfld, out fieldRef)) { XFieldDefinition field; object value; if (fieldRef.TryResolve(out field) && field.IsStatic && field.DeclaringType.IsEnum && field.TryGetEnumValue(out value)) { // Replace with ldc_ix var wide = (node.Code == AstCode.Enum_to_long); node.SetCode(wide ? AstCode.Ldc_I8 : AstCode.Ldc_I4); node.Operand = wide ? (object)XConvert.ToLong(value) : XConvert.ToInt(value); node.Arguments.Clear(); } } } break; } } }
private static void CommonCode(string input) { AssemblyCompiler compiler = new AssemblyCompiler(input, true); compiler.Compile(true); compiler.RunAssembly(); }
public static void Main(string[] args) { if (args.Length == 0) { Console.WriteLine("You should pass at least one parameter!"); return; } string sourceModelPath = args[0]; List <string> passedRefsPaths = args.Skip(1).ToList(); if (!passedRefsPaths.Any()) { passedRefsPaths = Compiler.AssemblyCompiler.DefaultRefs.ToList(); } try { FileInfo modelFile; List <FileInfo> libraries; modelFile = GetFile(sourceModelPath); libraries = new List <FileInfo>(); foreach (var passedRef in passedRefsPaths) { libraries.Add(GetFile(passedRef)); } AssemblyCompiler compiler = new AssemblyCompiler(modelFile, libraries); compiler.Compile(false); } catch (ArgumentException e) { Console.WriteLine(e.Message); } }
/// <summary> /// Create annotations for all included attributes /// </summary> public static void Create(AssemblyCompiler compiler, ICustomAttributeProvider attributeProvider, IAnnotationProvider annotationProvider, DexTargetPackage targetPackage, bool customAttributesOnly = false) { if (!attributeProvider.HasCustomAttributes) return; var annotations = new List<Annotation>(); foreach (var attr in attributeProvider.CustomAttributes) { var attributeType = attr.AttributeType.Resolve(); if (!attributeType.HasIgnoreAttribute()) { Create(compiler, attr, attributeType, annotations, targetPackage); } } if (annotations.Count > 0) { // Create 1 IAttributes annotation var attrsAnnotation = new Annotation { Visibility = AnnotationVisibility.Runtime }; attrsAnnotation.Type = compiler.GetDot42InternalType("IAttributes").GetClassReference(targetPackage); attrsAnnotation.Arguments.Add(new AnnotationArgument("Attributes", annotations.ToArray())); annotationProvider.Annotations.Add(attrsAnnotation); } if (!customAttributesOnly) { // Add annotations specified using AnnotationAttribute foreach (var attr in attributeProvider.CustomAttributes.Where(IsAnnotationAttribute)) { var annotationType = (TypeReference) attr.ConstructorArguments[0].Value; var annotationClass = annotationType.GetClassReference(targetPackage, compiler.Module); annotationProvider.Annotations.Add(new Annotation(annotationClass, AnnotationVisibility.Runtime)); } } }
/// <summary> /// Create a type builder for the given type. /// </summary> internal static IClassBuilder[] Create(ReachableContext context, AssemblyCompiler compiler, TypeDefinition typeDef) { if (typeDef.FullName == "<Module>") return new IClassBuilder[] { new SkipClassBuilder() }; if (typeDef.IsDelegate()) return new IClassBuilder[] {new DelegateClassBuilder(context, compiler, typeDef) }; if (typeDef.IsAttribute()) return new IClassBuilder[] {new AttributeClassBuilder(context, compiler, typeDef) }; if (typeDef.IsAnnotation()) return new IClassBuilder[] {new AnnotationClassBuilder(context, compiler, typeDef) }; if (typeDef.HasDexImportAttribute()) return new IClassBuilder[] {new DexImportClassBuilder(context, compiler, typeDef) }; if (typeDef.HasJavaImportAttribute()) return new IClassBuilder[] {CreateJavaImportBuilder(context, compiler, typeDef)}; if (typeDef.IsEnum) { if (typeDef.UsedInNullableT) { var nullableBaseClassBuilder = new NullableEnumBaseClassBuilder(context, compiler, typeDef); IClassBuilder builder = new EnumClassBuilder(context, compiler, typeDef, nullableBaseClassBuilder); return new[] { builder, nullableBaseClassBuilder }; } return new IClassBuilder[] { new EnumClassBuilder(context, compiler, typeDef, null) }; } else { IClassBuilder builder = new StandardClassBuilder(context, compiler, typeDef); if (typeDef.UsedInNullableT) return new[] { builder, new NullableBaseClassBuilder(context, compiler, typeDef) }; return new[] { builder }; } }
/// <summary> /// Performs stage specific processing on the compiler context. /// </summary> /// <param name="compiler">The compiler context to perform processing in.</param> public virtual void Run(AssemblyCompiler compiler) { long address; // Check if we have unresolved requests and try to link them List <string> members = new List <string> (_linkRequests.Keys); foreach (string member in members) { // Is the runtime member resolved? if (IsResolved(member, out address)) { // Yes, patch up the method List <LinkRequest> link = _linkRequests[member]; PatchRequests(address, link); _linkRequests.Remove(member); } } Debug.Assert(0 == _linkRequests.Count, "AssemblyLinker has found unresolved _symbols."); if (0 != _linkRequests.Count) { throw new LinkerException("Unresolved _symbols."); } }
public void Setup(AssemblyCompiler compiler) { if (this.implementation != null) { this.implementation.Setup(compiler); } }
private Assembly Generate() { var assemblyPath = Path.GetDirectoryName(this.assembly.Location); var trees = new ConcurrentBag<SyntaxTree>(); var allowUnsafe = false; Parallel.ForEach(assembly.GetExportedTypes() .Where(_ => string.IsNullOrWhiteSpace(_.Validate(this.options.Serialization, new AssemblyNameGenerator(_))) && !typeof(Array).IsAssignableFrom(_) && !typeof(Enum).IsAssignableFrom(_) && !typeof(ValueType).IsAssignableFrom(_) && !typeof(Delegate).IsAssignableFrom(_)), _ => { var builder = new AssemblyBuilder(_, new ReadOnlyDictionary<int, ReadOnlyCollection<HandlerInformation>>( new Dictionary<int, ReadOnlyCollection<HandlerInformation>>()), new SortedSet<string>(), this.options); builder.Build(); trees.Add(builder.Tree); allowUnsafe |= builder.IsUnsafe; }); var referencedAssemblies = this.assembly.GetReferencedAssemblies().Select(_ => Assembly.Load(_)).ToList(); referencedAssemblies.Add(this.assembly); var compiler = new AssemblyCompiler(trees, this.options.Optimization, new AssemblyNameGenerator(this.assembly).AssemblyName, referencedAssemblies.AsReadOnly(), currentDirectory, allowUnsafe, this.options.AllowWarnings); compiler.Compile(); return compiler.Result; }
/// <summary> /// Convert ret or store field node. /// /// converts to IEnumerable, ICollection or IList if required. /// </summary> private static void ConvertRetOrStfldOrStsfld(AssemblyCompiler compiler, XTypeReference targetType, AstExpression node, XTypeSystem typeSystem) { var argument = node.Arguments.LastOrDefault(); if (argument == null) { return; } if (argument.InferredType == null || !argument.InferredType.IsArray) { return; } var methodName = GetCollectionConvertMethodName(targetType); if (methodName == null) { return; } // Call "ret asMethod(x)" var arrayHelper = compiler.GetDot42InternalType(InternalConstants.CompilerHelperName).Resolve(); var asArray = arrayHelper.Methods.First(x => x.Name == "As" + methodName); // AsX(x) var asXExpr = new AstExpression(node.SourceLocation, AstCode.Call, asArray, argument).SetType(typeSystem.Object); // replace argument. node.Arguments[node.Arguments.Count - 1] = asXExpr; }
/// <summary> /// Operands refering to types, methods or fields need to be fixed, as they might have /// gotten another name in the target package. he same applies for catch references. /// </summary> private void FixReferences(MethodBody body, AssemblyCompiler compiler, DexTargetPackage targetPackage) { // fix operands foreach (var ins in body.Instructions) { var fieldRef = ins.Operand as FieldReference; var methodRef = ins.Operand as MethodReference; var classRef = ins.Operand as ClassReference; if (classRef != null) { ins.Operand = ConvertClassReference(classRef, compiler, targetPackage); } else if (fieldRef != null) { ins.Operand = ConvertFieldReference(fieldRef, compiler, targetPackage); } else if (methodRef != null) { ins.Operand = ConvertMethodReference(methodRef, compiler, targetPackage); } } // fix catch clauses foreach (var @catch in body.Exceptions.SelectMany(e => e.Catches)) { if (@catch.Type != null) { @catch.Type = ConvertTypeReference(@catch.Type, compiler, targetPackage); } } }
public void Test() { var primaryAssembly = AssemblyCompiler.Compile(primaryAssemblyCode); var assemblyName = primaryAssembly.GetName().Name; CopyAssemblyToTestDirectory(primaryAssembly); CopyAssemblyToTestDirectory(typeof(IContainer).Assembly); CopyAssemblyToTestDirectory(Assembly.GetExecutingAssembly()); CopyAssemblyToTestDirectory(typeof(Assert).Assembly); GetInvoker().DoCallBack(assemblyName, delegate(string s) { var f = new ContainerFactory() .WithAssembliesFilter(x => x.Name.StartsWith("tmp_")) .WithTypesFromDefaultBinDirectory(false); var type = Type.GetType("A1.ISomeInterface, " + s); Assert.That(type, Is.Not.Null); using (var c = f.Build()) { var exception = Assert.Throws <SimpleContainerException>(() => c.Get(type)); var assemblies = new[] { "SimpleContainer", s }.OrderBy(x => x).Select(x => "\t" + x).JoinStrings("\r\n"); const string expectedMessage = "no instances for [ISomeInterface]\r\n\r\n!" + "ISomeInterface - has no implementations\r\n" + "scanned assemblies\r\n"; Assert.That(exception.Message, Is.EqualTo(expectedMessage + assemblies)); } }); }
/// <summary> /// Link time code generator used to compile dynamically created methods during link time. /// </summary> /// <param name="compiler">The assembly compiler used to compile this method.</param> /// <param name="methodName">The name of the created method.</param> /// <param name="instructionSet">The instruction set.</param> /// <returns></returns> /// <exception cref="System.ArgumentNullException"><paramref name="compiler"/>, <paramref name="methodName"/> or <paramref name="instructionSet"/> is null.</exception> /// <exception cref="System.ArgumentException"><paramref name="methodName"/> is invalid.</exception> public static CompilerGeneratedMethod Compile(AssemblyCompiler compiler, string methodName, InstructionSet instructionSet) { if (compiler == null) { throw new ArgumentNullException(@"compiler"); } if (methodName == null) { throw new ArgumentNullException(@"methodName"); } if (methodName.Length == 0) { throw new ArgumentException(@"Invalid method name."); } // Create the type if we need to. CompilerGeneratedType type = compilerGeneratedType; if (type == null) { type = compilerGeneratedType = new CompilerGeneratedType(compiler.Assembly, @"Mosa.Tools.Compiler", @"LinkerGenerated"); } // Create the method // HACK: <$> prevents the method from being called from CIL CompilerGeneratedMethod method = new CompilerGeneratedMethod(compiler.Assembly, "<$>" + methodName, type); type.Methods.Add(method); LinkerMethodCompiler methodCompiler = new LinkerMethodCompiler(compiler, method, instructionSet); methodCompiler.Compile(); return(method); }
void IAssemblyCompilerStage.Setup(AssemblyCompiler compiler) { base.Setup(compiler); CheckImplementation(); ((IAssemblyCompilerStage)this.implementation).Setup(compiler); }
/// <summary> /// Default ctor /// </summary> public static IEnumerable <FieldBuilder> Create(AssemblyCompiler compiler, FieldDefinition field) { if (field.IsAndroidExtension()) { return new[] { new DexImportFieldBuilder(compiler, field) } } ; if (field.DeclaringType.IsEnum) { if (!field.IsStatic) { throw new ArgumentException("value field should not be implemented this way"); } return(new[] { new EnumFieldBuilder(compiler, field) }); } var fieldBuilder = new FieldBuilder(compiler, field); if (!field.IsUsedInInterlocked) { return new[] { fieldBuilder } } ; return(new[] { fieldBuilder, new FieldInterlockedBuilder(compiler, field, fieldBuilder) }); }
/// <summary> /// Performs stage specific processing on the compiler context. /// </summary> /// <param name="compiler">The compiler context to perform processing in.</param> public void Run(AssemblyCompiler compiler) { if (this.implementation != null) { implementation.Run(compiler); } }
/// <summary> /// Writes the multiboot _header. /// </summary> /// <param name="compiler">The assembly compiler.</param> /// <param name="linker">The linker.</param> /// <param name="entryPoint">The virtualAddress of the multiboot compliant entry point.</param> private void WriteMultibootHeader(AssemblyCompiler compiler, IAssemblyLinker linker, IntPtr entryPoint) { // HACK: According to the multiboot specification this _header must be within the first 8K of the // kernel binary. Since the text section is always first, this should take care of the problem. using (Stream stream = linker.Allocate(MultibootHeaderSymbolName, SectionKind.Text, 64, 4)) using (BinaryWriter bw = new BinaryWriter(stream, Encoding.ASCII)) { // flags - multiboot flags uint flags = /*HEADER_MB_FLAG_VIDEO_MODES_REQUIRED | */ HEADER_MB_FLAG_MEMORY_INFO_REQUIRED | HEADER_MB_FLAG_MODULES_PAGE_ALIGNED; // The multiboot _header checksum uint csum = 0; // header_addr is the load virtualAddress of the multiboot _header uint header_addr = 0; // load_addr is the base virtualAddress of the binary in memory uint load_addr = 0; // load_end_addr holds the virtualAddress past the last byte to load From the image uint load_end_addr = 0; // bss_end_addr is the virtualAddress of the last byte to be zeroed out uint bss_end_addr = 0; // entry_point the load virtualAddress of the entry point to invoke uint entry_point = (uint)entryPoint.ToInt32(); // Are we linking an ELF binary? if (!(linker is Elf32Linker || linker is Elf64Linker)) { // Check the linker layout settings if (linker.LoadSectionAlignment != linker.VirtualSectionAlignment) { throw new LinkerException(@"Load and virtual section alignment must be identical if you are booting non-ELF binaries with a multiboot bootloader."); } // No, special multiboot treatment required flags |= HEADER_MB_FLAG_NON_ELF_BINARY; header_addr = (uint)(linker.GetSection(SectionKind.Text).VirtualAddress.ToInt64() + linker.GetSymbol(MultibootHeaderSymbolName).SectionAddress); load_addr = (uint)linker.BaseAddress; load_end_addr = 0; bss_end_addr = 0; } // Calculate the checksum csum = unchecked (0U - HEADER_MB_MAGIC - flags); bw.Write(HEADER_MB_MAGIC); bw.Write(flags); bw.Write(csum); bw.Write(header_addr); bw.Write(load_addr); bw.Write(load_end_addr); bw.Write(bss_end_addr); // HACK: Symbol has been hacked. What's the correct way to do this? linker.Link(LinkType.AbsoluteAddress | LinkType.I4, MultibootHeaderSymbolName, (int)stream.Position, 0, @"Mosa.Tools.Compiler.LinkerGenerated.<$>MultibootInit()", IntPtr.Zero); bw.Write(videoMode); bw.Write(videoWidth); bw.Write(videoHeight); bw.Write(videoDepth); } }
/// <summary> /// Convert the given method into optimized Ast format. /// </summary> internal protected static AstNode CreateOptimizedAst(AssemblyCompiler compiler, MethodSource source, bool generateSetNextInstructionCode, StopAstConversion debugStop = StopAstConversion.None, AstOptimizationStep debugStopOptimizing = AstOptimizationStep.None ) { // Build AST DecompilerContext context; AstBlock ast; if (source.IsDotNet) { context = new DecompilerContext(source.Method); var astBuilder = new IL2Ast.AstBuilder(source.ILMethod, true, context); var children = astBuilder.Build(); ast = new AstBlock(children.Select(x => x.SourceLocation).FirstOrDefault(), children); if ((source.ILMethod.IsConstructor) && (source.Method.DeclaringType.Fields.Any(x => x.FieldType.IsEnum() || x.Name.EndsWith(NameConstants.Atomic.FieldUpdaterPostfix)))) { // Ensure all fields are initialized AddFieldInitializationCode(compiler, source, ast); } if (source.Method.NeedsGenericInstanceTypeParameter && (source.Name == ".ctor")) { // Add code to save the generic instance type parameter into the generic instance field. AddGenericInstanceFieldInitializationCode(source, ast, compiler.Module.TypeSystem); } } else if (source.IsJava) { var astBuilder = new Java2Ast.AstBuilder(compiler.Module, source.JavaMethod, source.Method.DeclaringType, true); context = new DecompilerContext(source.Method); ast = astBuilder.Build(); } else if (source.IsAst) { context = new DecompilerContext(source.Method); ast = source.Ast; } else { throw new NotSupportedException("Unknown source"); } if (debugStop == StopAstConversion.AfterILConversion) return ast; // Optimize AST var astOptimizer = new AstOptimizer(context, ast); astOptimizer.Optimize(debugStopOptimizing); if (debugStop == StopAstConversion.AfterOptimizing) return ast; // Optimize AST towards the target TargetConverters.Convert(context, ast, source, compiler, debugStop); if(generateSetNextInstructionCode) SetNextInstructionGenerator.Convert(ast, source, compiler); // Return return return ast; }
private static void CommonCode(string input) { AssemblyCompiler compiler = new AssemblyCompiler(input, true); compiler.Compile(true); Console.WriteLine(GenerationUtils.PrintCodeObject(compiler.CompileUnit)); }
public static void CreateAssemblyTypes(AssemblyCompiler compiler, DexTargetPackage targetPackage, IEnumerable <TypeDefinition> reachableTypes) { var xAssemblyTypes = compiler.GetDot42InternalType("AssemblyTypes"); var assemblyTypes = (ClassDefinition)xAssemblyTypes.GetClassReference(targetPackage); var entryAssembly = assemblyTypes.Fields.First(f => f.Name == "EntryAssembly"); var iAssemblyTypes = compiler.GetDot42InternalType("IAssemblyTypes").GetClassReference(targetPackage); entryAssembly.Value = compiler.Assemblies.First().Name.Name; List <object> values = new List <object>(); string prevAssemblyName = null; foreach (var type in reachableTypes.OrderBy(t => t.Module.Assembly.Name.Name) .ThenBy(t => t.Namespace) .ThenBy(t => t.Name)) { var assemblyName = type.module.Assembly.Name.Name; if (assemblyName == "dot42") { // group all android types into virtual "android" assembly, // so that MvvmCross can find all view-types. // -- is this a hack? if (type.Namespace.StartsWith("Android")) { assemblyName = "android"; } else // ignore other types, these will get the "default" assembly. { continue; } } if (prevAssemblyName != assemblyName) { values.Add("!" + assemblyName); // we need some identification of assemblies. prevAssemblyName = assemblyName; } // TODO: With compilationmode=all reachable types contains <Module> // this should be excluded earlier. if (type.FullName == "<Module>") { continue; } var tRef = type.GetReference(targetPackage, compiler.Module) as ClassReference; if (tRef != null) { values.Add(tRef.Fullname); } } var anno = new Annotation(iAssemblyTypes, AnnotationVisibility.Runtime, new AnnotationArgument("AssemblyTypeList", values.ToArray())); ((IAnnotationProvider)assemblyTypes).Annotations.Add(anno); }
/// <summary> /// Convert node with code Cast. /// </summary> private static void ConvertCastclass(AssemblyCompiler compiler, AstExpression node, XTypeSystem typeSystem) { var type = (XTypeReference) node.Operand; if (type.IsSystemArray()) { // Call cast method var arrayHelper = compiler.GetDot42InternalType(InternalConstants.CompilerHelperName).Resolve(); var castToArray = arrayHelper.Methods.First(x => x.Name == "CastToArray"); var castToArrayExpr = new AstExpression(node.SourceLocation, AstCode.Call, castToArray, node.Arguments).SetType(type); node.CopyFrom(castToArrayExpr); return; } string castMethod = null; if (type.IsSystemCollectionsIEnumerable()) { castMethod = "CastToEnumerable"; } else if (type.IsSystemCollectionsICollection()) { castMethod = "CastToCollection"; } else if (type.IsSystemCollectionsIList()) { castMethod = "CastToList"; } else if (type.IsSystemIFormattable()) { castMethod = "CastToFormattable"; } if (castMethod != null) { // Call cast method var arrayHelper = compiler.GetDot42InternalType(InternalConstants.CompilerHelperName).Resolve(); var castToArray = arrayHelper.Methods.First(x => x.Name == castMethod); // Call "(x instanceof T) ? (T)x : asMethod(x)" // "instanceof x" var instanceofExpr = new AstExpression(node.SourceLocation, AstCode.SimpleInstanceOf, type, node.Arguments[0]).SetType(typeSystem.Bool); // CastX(x) var castXExpr = new AstExpression(node.SourceLocation, AstCode.Call, castToArray, node.Arguments[0]).SetType(typeSystem.Object); // T(x) var txExpr = new AstExpression(node.SourceLocation, AstCode.SimpleCastclass, type, node.Arguments[0]).SetType(type); // Combine var conditional = new AstExpression(node.SourceLocation, AstCode.Conditional, type, instanceofExpr, txExpr, castXExpr).SetType(type); node.CopyFrom(conditional); return; } // Normal castclass node.Code = AstCode.SimpleCastclass; }
public static void Run(string input) { AssemblyCompiler compiler = new AssemblyCompiler(input, true); //Set this to false to generate exe in default folder compiler.Compile(true); compiler.RunAssembly(); }
/// <summary> /// Create a IGnericDefinition annotation and attaches it to the given provider. /// TODO: this might better belong somewhere else. /// </summary> public static void AddGenericDefinitionAnnotationIfGeneric(this IAnnotationProvider provider, XTypeReference xtype, AssemblyCompiler compiler, DexTargetPackage targetPackage, bool forceTypeDefinition=false) { if (!xtype.IsGenericInstance && !xtype.IsGenericParameter) return; Annotation annotation = GetGenericDefinitionAnnotationForType(xtype, forceTypeDefinition, compiler, targetPackage); if(annotation != null) provider.Annotations.Add(annotation); }
private static void CommonCode(string input) { input = Defaults.DefUsing + input; AssemblyCompiler compiler = new AssemblyCompiler(input, true); compiler.Compile(true); compiler.RunAssembly(); }
/// <summary> /// Gets a unbox method for the given primitive type. /// </summary> internal static MethodReference GetUnboxValueMethod(XTypeReference type, AssemblyCompiler compiler, DexTargetPackage targetPackage, out RCode convertAfterCode) { var info = Get(type); convertAfterCode = info.convertAfterCode; var boxingClass = compiler.GetDot42InternalType("Boxing").GetClassReference(targetPackage); return(new MethodReference(boxingClass, info.unboxMethodName, new Prototype(info.primitiveType, new Parameter(FrameworkReferences.Object, "value")))); }
/// <summary> /// Initializes a mapping. /// </summary> public static AttributeAnnotationMapping CreateMapping( ISourceLocation sequencePoint, AssemblyCompiler compiler, DexTargetPackage targetPackage, TypeDefinition attributeType, ClassDefinition attributeClass) { return(new AttributeAnnotationMapping(attributeType, attributeClass)); }
/// <summary> /// Initializes a mapping. /// </summary> public static AttributeAnnotationMapping CreateMapping( ISourceLocation sequencePoint, AssemblyCompiler compiler, DexTargetPackage targetPackage, TypeDefinition attributeType, ClassDefinition attributeClass) { return new AttributeAnnotationMapping(attributeType, attributeClass); }
void IAssemblyCompilerStage.Setup(AssemblyCompiler compiler) { base.Setup(compiler); scheduler = compiler.Pipeline.FindFirst<ICompilationSchedulerStage>(); if (scheduler == null) throw new InvalidOperationException(@"No compilation scheduler found in the assembly compiler pipeline."); }
/// <summary> /// Default ctor /// </summary> public DelegateType(AssemblyCompiler compiler, XTypeDefinition delegateType, ClassDefinition interfaceClass, Dex target, NameConverter nsConverter) { this.compiler = compiler; this.delegateType = delegateType; this.interfaceClass = interfaceClass; // Build invoke prototype invokeMethod = delegateType.Methods.First(x => x.EqualsName("Invoke")); }
/// <summary> /// Performs stage specific processing on the compiler context. /// </summary> /// <param name="compiler">The compiler context to perform processing in.</param> public void Run(AssemblyCompiler compiler) { _ctx.AppendInstruction(IR.Instruction.CallInstruction); _ctx.InvokeTarget = compiler.Assembly.EntryPoint; _ctx.AppendInstruction(IR.Instruction.EpilogueInstruction); _ctx.Other = 0; _method = LinkTimeCodeGenerator.Compile(compiler, @"AssemblyInit", InstructionSet); }
public static void Convert(AstNode ast, MethodSource currentMethod, AssemblyCompiler compiler) { foreach (var block in ast.GetSelfAndChildrenRecursive<AstBlock>()) { for (int i = 0; i < block.Body.Count; ++i) { var expr = block.Body[i] as AstExpression; if(expr == null) continue; var interlockedPairs = expr.GetExpressionPairs(p => p.Code == AstCode.Call && ((XMethodReference) p.Operand).DeclaringType.FullName == "System.Threading.Interlocked") .ToList(); if(interlockedPairs.Count == 0) continue; if (interlockedPairs.Count > 1) throw new CompilerException("The Interlocked converter can not handle more than one interlocked call per statement. Try splittig the statement up."); var interlockedCall = interlockedPairs.First().Expression; // first parameter should be a reference to a field, // (but be lenient if we don't find what we expect) var targetExpr = interlockedCall.Arguments[0]; XFieldReference field = null; if (targetExpr.InferredType.IsByReference) { field = targetExpr.Operand as XFieldReference; if (field != null) { // check if we have an atomic updater var updater = field.DeclaringType.Resolve().Fields .FirstOrDefault(f => f.Name == field.Name + NameConstants.Atomic.FieldUpdaterPostfix); if (updater != null) { var method = (XMethodReference) interlockedCall.Operand; var methodName = method.Name.Split('$')[0]; // retrieve original name. if (InterlockedUsingUpdater(interlockedCall, methodName, field, updater, targetExpr, interlockedPairs.First().Parent, compiler)) continue; } } } FailsafeInterlockedUsingLocking(field, expr, targetExpr, block, i, compiler, currentMethod); } } }
/// <summary> /// Create an annotation for the given attribute /// </summary> private static void Create(AssemblyCompiler compiler, CustomAttribute attribute, TypeDefinition attributeType, List <Annotation> annotationList, DexTargetPackage targetPackage) { // Gets the mapping for the type of attribute var mapping = compiler.GetAttributeAnnotationType(attributeType); var ctorMap = mapping.CtorMap[attribute.Constructor.Resolve()]; // Create annotation var annotation = new Annotation { Visibility = AnnotationVisibility.Runtime }; annotation.Type = mapping.AnnotationInterfaceClass; // Add ctor arguments var argIndex = 0; foreach (var arg in attribute.ConstructorArguments) { var name = ctorMap.ArgumentGetters[argIndex].Name; annotation.Arguments.Add(CreateAnnotationArgument(name, arg.Type, arg.Value, targetPackage, compiler.Module)); argIndex++; } // Add field values foreach (var arg in attribute.Fields) { var entry = mapping.FieldToGetMethodMap.First(x => x.Key.Name == arg.Name); var name = entry.Value.Name; annotation.Arguments.Add(CreateAnnotationArgument(name, arg.Argument.Type, arg.Argument.Value, targetPackage, compiler.Module)); } // Add property values foreach (var arg in attribute.Properties) { if (mapping.PropertyToGetMethodMap.Keys.Any(x => x.Name == arg.Name)) { var entry = mapping.PropertyToGetMethodMap.First(x => x.Key.Name == arg.Name); var name = entry.Value.Name; annotation.Arguments.Add(CreateAnnotationArgument(name, arg.Argument.Type, arg.Argument.Value, targetPackage, compiler.Module)); } } // Create attribute annotation var attrAnnotation = new Annotation { Visibility = AnnotationVisibility.Runtime }; attrAnnotation.Type = compiler.GetDot42InternalType("IAttribute").GetClassReference(targetPackage); attrAnnotation.Arguments.Add(new AnnotationArgument("AttributeBuilder", ctorMap.Builder)); attrAnnotation.Arguments.Add(new AnnotationArgument("AttributeType", attributeType.GetReference(targetPackage, compiler.Module))); attrAnnotation.Arguments.Add(new AnnotationArgument("Annotation", annotation)); // Add annotation annotationList.Add(attrAnnotation); }
/// <summary> /// Create a type builder for the given type with JavaImport attribute. /// </summary> internal static IClassBuilder CreateJavaImportBuilder(ReachableContext context, AssemblyCompiler compiler, TypeDefinition typeDef) { var javaImportAttr = typeDef.GetJavaImportAttribute(true); var className = (string)javaImportAttr.ConstructorArguments[0].Value; ClassFile classFile; if (!compiler.ClassLoader.TryLoadClass(className, out classFile)) throw new ClassNotFoundException(className); context.RecordReachableType(classFile); return new SkipClassBuilder(); }
public SimpleJitMethodCompiler(AssemblyCompiler compiler, ICompilationSchedulerStage compilationScheduler, RuntimeType type, RuntimeMethod method, Stream codeStream, ITypeSystem typeSystem) : base(compiler.Pipeline.FindFirst <IAssemblyLinker>(), compiler.Architecture, compilationScheduler, type, method, typeSystem, compiler.Pipeline.FindFirst <ITypeLayout>()) { if (codeStream == null) { throw new ArgumentNullException(@"codeStream"); } this.codeStream = codeStream; }
/// <summary> /// Default ctor /// </summary> public static FieldBuilder Create(AssemblyCompiler compiler, FieldDefinition field) { if (field.IsAndroidExtension()) return new DexImportFieldBuilder(compiler, field); if (field.DeclaringType.IsEnum) { if (!field.IsStatic) throw new ArgumentException("value field should not be implemented this way"); return new EnumFieldBuilder(compiler, field); } return new FieldBuilder(compiler, field); }
public static void Convert(AstNode ast, MethodSource currentMethod, AssemblyCompiler compiler) { // only work on MoveNext of IAsyncStateMachine implementations. if (currentMethod.Name != "MoveNext" && currentMethod.Name != "IAsyncStateMachine_MoveNext") return; var declaringType = currentMethod.Method.DeclaringType.Resolve(); if (declaringType.Interfaces.All(i => i.FullName != "System.Runtime.CompilerServices.IAsyncStateMachine")) return; foreach(var block in ast.GetSelfAndChildrenRecursive<AstBlock>()) FixBlock(block); }
/// <summary> /// Create a prototype for the given methods signature /// </summary> internal static Prototype BuildPrototype(AssemblyCompiler compiler, DexTargetPackage targetPackage, ClassDefinition declaringClass, MethodDefinition method) { var result = new Prototype(); var module = compiler.Module; result.ReturnType = method.ReturnType.GetReference(XTypeUsageFlags.ReturnType, targetPackage, module); var paramIndex = 0; foreach (var p in method.Parameters) { var dparameter = new Parameter(p.GetReference(XTypeUsageFlags.ParameterType, targetPackage, module), "p" + paramIndex++); result.Parameters.Add(dparameter); } return result; }
/// <summary> /// Default ctor /// </summary> public static MethodBuilder Create(AssemblyCompiler compiler, MethodDefinition method) { string dllName; if (method.IsAndroidExtension()) { return new DexImportMethodBuilder(compiler, method); } if (method.TryGetDllImportName(out dllName)) { return new DllImportMethodBuilder(compiler, method, dllName); } return new MethodBuilder(compiler, method); }
/// <summary> /// Create an annotation for the given attribute /// </summary> private static void Create(AssemblyCompiler compiler, CustomAttribute attribute, TypeDefinition attributeType, List<Annotation> annotationList, DexTargetPackage targetPackage) { // Gets the mapping for the type of attribute var mapping = compiler.GetAttributeAnnotationType(attributeType); var ctorMap = mapping.CtorMap[attribute.Constructor.Resolve()]; // Create annotation var annotation = new Annotation {Visibility = AnnotationVisibility.Runtime}; annotation.Type = mapping.AnnotationInterfaceClass; // Add ctor arguments var argIndex = 0; foreach (var arg in attribute.ConstructorArguments) { var name = ctorMap.ArgumentGetters[argIndex].Name; annotation.Arguments.Add(CreateAnnotationArgument(name, arg.Type, arg.Value, targetPackage, compiler.Module)); argIndex++; } // Add field values foreach (var arg in attribute.Fields) { var entry = mapping.FieldToGetMethodMap.First(x => x.Key.Name == arg.Name); var name = entry.Value.Name; annotation.Arguments.Add(CreateAnnotationArgument(name, arg.Argument.Type, arg.Argument.Value, targetPackage, compiler.Module)); } // Add property values foreach (var arg in attribute.Properties) { if (mapping.PropertyToGetMethodMap.Keys.Any(x => x.Name == arg.Name)) { var entry = mapping.PropertyToGetMethodMap.First(x => x.Key.Name == arg.Name); var name = entry.Value.Name; annotation.Arguments.Add(CreateAnnotationArgument(name, arg.Argument.Type, arg.Argument.Value, targetPackage, compiler.Module)); } } // Create attribute annotation var attrAnnotation = new Annotation { Visibility = AnnotationVisibility.Runtime }; attrAnnotation.Type = compiler.GetDot42InternalType("IAttribute").GetClassReference(targetPackage); attrAnnotation.Arguments.Add(new AnnotationArgument("AttributeBuilder", ctorMap.Builder)); attrAnnotation.Arguments.Add(new AnnotationArgument("AttributeType", attributeType.GetReference(targetPackage, compiler.Module))); attrAnnotation.Arguments.Add(new AnnotationArgument("Annotation", annotation)); // Add annotation annotationList.Add(attrAnnotation); }
public static void CreateAssemblyTypes(AssemblyCompiler compiler, DexTargetPackage targetPackage, IEnumerable<TypeDefinition> reachableTypes) { var xAssemblyTypes = compiler.GetDot42InternalType("AssemblyTypes"); var assemblyTypes = (ClassDefinition)xAssemblyTypes.GetClassReference(targetPackage); var entryAssembly = assemblyTypes.Fields.First(f => f.Name == "EntryAssembly"); var iAssemblyTypes = compiler.GetDot42InternalType("IAssemblyTypes").GetClassReference(targetPackage); entryAssembly.Value = compiler.Assemblies.First().Name.Name; List<object> values = new List<object>(); string prevAssemblyName = null; foreach (var type in reachableTypes.OrderBy(t => t.Module.Assembly.Name.Name) .ThenBy(t => t.Namespace) .ThenBy(t => t.Name)) { var assemblyName = type.module.Assembly.Name.Name; if (assemblyName == "dot42") { // group all android types into virtual "android" assembly, // so that MvvmCross can find all view-types. // -- is this a hack? if (type.Namespace.StartsWith("Android")) assemblyName = "android"; else // ignore other types, these will get the "default" assembly. continue; } if (prevAssemblyName != assemblyName) { values.Add("!" + assemblyName); // we need some identification of assemblies. prevAssemblyName = assemblyName; } // TODO: With compilationmode=all reachable types contains <Module> // this should be excluded earlier. if (type.FullName == "<Module>") continue; var tRef = type.GetReference(targetPackage, compiler.Module) as ClassReference; if(tRef != null) values.Add(tRef.Fullname); } var anno = new Annotation(iAssemblyTypes, AnnotationVisibility.Runtime, new AnnotationArgument("AssemblyTypeList", values.ToArray())); ((IAnnotationProvider)assemblyTypes).Annotations.Add(anno); }
/// <summary> /// Convert the given method into optimized Ast format. /// </summary> protected static AstNode CreateOptimizedAst(AssemblyCompiler compiler, MethodSource source) { // Build AST DecompilerContext context; AstBlock ast; if (source.IsDotNet) { context = new DecompilerContext(source.Method); var astBuilder = new IL2Ast.AstBuilder(source.ILMethod, true, context); var children = astBuilder.Build(); ast = new AstBlock(children.Select(x => x.SourceLocation).FirstOrDefault(), children); if ((source.ILMethod.IsConstructor) && (source.Method.DeclaringType.Fields.Any(x => x.FieldType.IsEnum()))) { // Ensure all fields are initialized AddFieldInitializationCode(source, ast); } if (source.Method.NeedsGenericInstanceTypeParameter && (source.Name == ".ctor")) { // Add code to safe the generic instance type parameter into the generic instance field. AddGenericInstanceFieldInitializationCode(ast); } } else if (source.IsJava) { var astBuilder = new Java2Ast.AstBuilder(compiler.Module, source.JavaMethod, source.Method.DeclaringType, true); context = new DecompilerContext(source.Method); ast = astBuilder.Build(); } else if (source.IsAst) { context = new DecompilerContext(source.Method); ast = source.Ast; } else { throw new NotSupportedException("Unknown source"); } // Optimize AST var astOptimizer = new AstOptimizer(context, ast); astOptimizer.Optimize(); // Optimize AST towards the target TargetConverters.Convert(context, ast, source, compiler); // Return return return ast; }
/// <summary> /// Create the current type as class definition. /// </summary> internal DelegateInstanceTypeBuilder( ISourceLocation sequencePoint, AssemblyCompiler compiler, DexTargetPackage targetPackage, ClassDefinition delegateClass, XMethodDefinition invokeMethod, Prototype invokePrototype, XMethodDefinition calledMethod) { this.sequencePoint = sequencePoint; this.compiler = compiler; this.targetPackage = targetPackage; this.delegateClass = delegateClass; this.invokeMethod = invokeMethod; this.invokePrototype = invokePrototype; this.calledMethod = calledMethod; this.multicastDelegateClass = compiler.GetDot42InternalType("System", "MulticastDelegate").GetClassReference(targetPackage); }
/// <summary> /// Default ctor /// </summary> public static IEnumerable<FieldBuilder> Create(AssemblyCompiler compiler, FieldDefinition field) { if (field.IsAndroidExtension()) return new[] {new DexImportFieldBuilder(compiler, field)}; if (field.DeclaringType.IsEnum) { if (!field.IsStatic) throw new ArgumentException("value field should not be implemented this way"); return new[] {new EnumFieldBuilder(compiler, field)}; } var fieldBuilder = new FieldBuilder(compiler, field); if (!field.IsUsedInInterlocked) return new[] { fieldBuilder }; return new[] { fieldBuilder, new FieldInterlockedBuilder(compiler, field, fieldBuilder) }; }
/// <summary> /// Optimize expressions /// </summary> public static void Convert(AstNode ast, AssemblyCompiler compiler) { foreach (var node in ast.GetExpressions()) { AstExpression arg1; XMethodReference method; if (node.Match(AstCode.Call, out method, out arg1) && arg1.Match(AstCode.Ldtoken)) { if ((method.Name == "GetTypeFromHandle") && method.DeclaringType.IsSystemType()) { node.Code = AstCode.TypeOf; node.Operand = arg1.Operand; node.Arguments.Clear(); node.SetType(compiler.Module.TypeSystem.Type); } } } }
/// <summary> /// Default ctor /// </summary> public DelegateType(AssemblyCompiler compiler, XTypeDefinition delegateType, ClassDefinition interfaceClass, Dex target, NameConverter nsConverter) { this.compiler = compiler; this.delegateType = delegateType; this.interfaceClass = interfaceClass; // Build invoke prototype invokeMethod = delegateType.Methods.First(x => x.EqualsName("Invoke")); XTypeDefinition baseType = delegateType; while ((null != baseType) && !baseType.Methods.Any(x => x.EqualsName("Equals"))) { baseType = baseType.BaseType as XTypeDefinition; } if (null != baseType) { equalsMethod = baseType.Methods.First(x => x.EqualsName("Equals")); } }
/// <summary> /// Perform all dot42 related Ast conversions. /// </summary> public static void Convert(DecompilerContext context, AstBlock ast, MethodSource currentMethod, AssemblyCompiler compiler) { if (ast.IsOptimizedForTarget) return; #if DEBUG //Debugger.Launch(); if ((currentMethod.Method != null) && (currentMethod.Method.Name.Equals("runTest", StringComparison.OrdinalIgnoreCase))) { //Debugger.Launch(); } #endif IntPtrConverter.Convert(ast, compiler); TypeOfConverter.Convert(ast, compiler); BranchOptimizer.Convert(ast); CompoundAssignmentConverter.Convert(ast); ByReferenceParamConverter.Convert(context, ast, compiler); CompareUnorderedConverter.Convert(ast); EnumConverter.Convert(ast, compiler); EnumOptimizer.Convert(ast, compiler); // Keep this order NullableConverter.Convert(ast, compiler); PrimitiveAddressOfConverter.Convert(ast, currentMethod, compiler); StructCallConverter.Convert(ast, compiler); // end InitializeStructVariablesConverter.Convert(ast); DelegateConverter.Convert(ast); LdcWideConverter.Convert(ast); LdLocWithConversionConverter.Convert(ast); ConvertAfterLoadConversionConverter.Convert(ast); ConvertBeforeStoreConversionConverter.Convert(ast); CleanupConverter.Convert(ast); GenericsConverter.Convert(ast); // Expand cast expressions CastConverter.Convert(ast, currentMethod, compiler); // Expand generic instance information GenericInstanceConverter.Convert(ast, currentMethod, compiler); }
/// <summary> /// Create a method body for the given method. /// </summary> internal static MethodBody TranslateToRL(AssemblyCompiler compiler, DexTargetPackage targetPackage, MethodSource source, MethodDefinition dmethod, bool generateSetNextInstructionCode, out CompiledMethod compiledMethod) { try { #if DEBUG //Debugger.Launch(); if ((source.Method != null) && (source.Method.Name == "test6")) { //Debugger.Launch(); } #endif // Create Ast var optimizedAst = CreateOptimizedAst(compiler, source, generateSetNextInstructionCode); // Generate RL code var rlBody = new MethodBody(source); var rlGenerator = new AstCompilerVisitor(compiler, source, targetPackage, dmethod, rlBody); optimizedAst.Accept(rlGenerator, null); rlGenerator.Complete(); // Should we add return_void? if (source.ReturnsVoid) { var instructions = rlBody.Instructions; if ((instructions.Count == 0) || (instructions.Last().Code != RCode.Return_void && instructions.Last().Code != RCode.Throw)) { instructions.Add(new RL.Instruction(RCode.Return_void) { SequencePoint = source.GetLastSourceLine() }); } } // Record results compiledMethod = targetPackage.Record(source, rlBody, rlGenerator.Frame); return rlBody; } catch (Exception ex) { // Forward exception with more information var msg = string.Format("Error while compiling {0} in {1}: {2}", source.FullName, source.DeclaringTypeFullName, ex.Message); throw new CompilerException(msg, ex); } }
public static Annotation CreateAnnotation(XTypeReference xtype, bool forceTypeDefinition, AssemblyCompiler compiler, DexTargetPackage targetPackage) { var genericsDefAnnotationClass = compiler.GetDot42InternalType(InternalConstants.GenericDefinitionAnnotation) .GetClassReference(targetPackage); var annotation = new Annotation { Type = genericsDefAnnotationClass, Visibility = AnnotationVisibility.Runtime }; string s = GetDefinition(xtype, forceTypeDefinition, compiler, targetPackage); if (string.IsNullOrEmpty(s)) return null; annotation.Arguments.Add(new AnnotationArgument("Definition", s)); return annotation; }
/// <summary> /// Add generic parameters to the prototype based on the given XMethodDefinition /// </summary> public static void AddGenericParameters(AssemblyCompiler compiler, DexTargetPackage targetPackage, XMethodDefinition method, Prototype result) { if (method.NeedsGenericInstanceTypeParameter) { var annType = compiler.GetDot42InternalType(InternalConstants.GenericTypeParameterAnnotation).GetClassReference(targetPackage); int numParameters = method.DeclaringType.GenericParameters.Count; var buildAsArray = numParameters > InternalConstants.GenericTypeParametersAsArrayThreshold; var parameterArray = result.GenericInstanceTypeParameters; AddGenericParameterArguments(result, buildAsArray, numParameters, "__$$git", annType, parameterArray); } if (method.NeedsGenericInstanceMethodParameter) { // Add GenericInstance parameter var annType = compiler.GetDot42InternalType(InternalConstants.GenericMethodParameterAnnotation).GetClassReference(targetPackage); int numParameters = method.GenericParameters.Count; var buildAsArray = numParameters > InternalConstants.GenericMethodParametersAsArrayThreshold; var parameterArray = result.GenericInstanceMethodParameters; AddGenericParameterArguments(result, buildAsArray, numParameters, "__$$gim", annType, parameterArray); } }
/// <summary> /// Optimize expressions /// </summary> public static void Convert(AstNode ast, MethodSource currentMethod, AssemblyCompiler compiler) { var typeSystem = compiler.Module.TypeSystem; // Expand instanceof foreach (var node in ast.GetSelfAndChildrenRecursive<AstExpression>(x => x.Code == AstCode.InstanceOf)) { ConvertInstanceOf(compiler, node, typeSystem); } // Expand isinst foreach (var node in ast.GetSelfAndChildrenRecursive<AstExpression>(x => x.Code == AstCode.Isinst)) { ConvertIsInst(compiler, node, typeSystem); } // Expand Castclass foreach (var node in ast.GetSelfAndChildrenRecursive<AstExpression>(x => x.Code == AstCode.Castclass)) { ConvertCastclass(compiler, node, typeSystem); } }
/// <summary> /// Optimize expressions /// </summary> public static void Convert(AstNode ast, MethodSource currentMethod, AssemblyCompiler compiler) { foreach (var node in ast.GetExpressions(x => (x.Code == AstCode.Call) || (x.Code == AstCode.Calli) || (x.Code == AstCode.Callvirt))) { var method = (XMethodReference)node.Operand; XMethodDefinition methodDef; if (method.TryResolve(out methodDef) && methodDef.IsConstructor && methodDef.DeclaringType.IsPrimitive && (node.Arguments.Count == 2)) { // primitive.ctor(addressof_primitive, value) -> primitive.cast(value) var locVar = node.Arguments[0].Operand; node.Arguments.RemoveAt(0); node.SetCode(AstCode.Stloc).SetType(node.Arguments[0].GetResultType()).Operand = locVar; } else { for (var i = 0; i < node.Arguments.Count; i++) { ProcessArgument(node, method, i, currentMethod, compiler.Module); } } } }