/// <summary> /// Add the given field to its declaring class. /// </summary> protected override void AddFieldToDeclaringClass(ClassDefinition declaringClass, DexLib.FieldDefinition dfield, DexTargetPackage targetPackage) { var generatedCodeClass = targetPackage.GetOrCreateGeneratedCodeClass(); UpdateName(dfield, generatedCodeClass); dfield.Owner = generatedCodeClass; generatedCodeClass.Fields.Add(dfield); }
/// <summary> /// Add the given method to its declaring class. /// </summary> protected virtual void SetAccessFlags(DexLib.MethodDefinition dmethod, MethodDefinition method) { if (method.IsPrivate) { if (method.DeclaringType.HasNestedTypes) dmethod.IsProtected = true; else dmethod.IsPrivate = true; } else if (method.IsFamily) dmethod.IsProtected = true; else dmethod.IsPublic = true; if (method.DeclaringType.IsInterface) { dmethod.IsAbstract = true; //dmethod. } else { if (method.IsConstructor) dmethod.IsConstructor = true; else if (method.IsAbstract) dmethod.IsAbstract = true; else if (method.IsVirtual) dmethod.IsVirtual = true; else if (method.IsStatic) dmethod.IsStatic = true; else dmethod.IsFinal = true; //if (method.IsInitOnly) dmethod.IsFinal = true; } }
/// <summary> /// Add the given method to its declaring class. /// </summary> protected override void SetAccessFlags(DexLib.MethodDefinition dmethod, MethodDefinition method) { dmethod.IsStatic = true; dmethod.IsPublic = true; if (method.IsAbstract || method.IsVirtual) { // generate a warning, since these methods will never be called // as virtual. Do not generate a warning if we know the compiler // will handle the call. if (method.DeclaringType.FullName == "System.Array") { // all array methods should be redirected by the compiler. return; } var intfMethod = method.GetBaseInterfaceMethod(); if (intfMethod != null && intfMethod.DeclaringType.FullName == "System.IFormattable") { // this is handled by the compiler. return; } DLog.Warning(DContext.CompilerCodeGenerator, "Abstract or virtual .NET method '{0}' in DexImport class '{1}'. Unless specially handled by the compiler, this will never be called virtually.", method.Name, method.DeclaringType.FullName); } }
/// <summary> /// Add the given method to its declaring class. /// </summary> protected override void AddMethodToDeclaringClass(ClassDefinition declaringClass, DexLib.MethodDefinition dmethod, DexTargetPackage targetPackage) { var generatedCodeClass = targetPackage.GetOrCreateGeneratedCodeClass(); UpdateName(dmethod, generatedCodeClass); dmethod.Owner = generatedCodeClass; generatedCodeClass.Methods.Add(dmethod); }
/// <summary> /// Set the access flags of the created field. /// </summary> protected virtual void SetAccessFlags(DexLib.FieldDefinition dfield, FieldDefinition field) { if (field.IsPrivate) dfield.IsPrivate = true; if (field.IsProtected) dfield.IsProtected = true; if (field.IsPublic) dfield.IsPublic = true; if (field.IsFinal) dfield.IsFinal = true; if (field.IsStatic) dfield.IsStatic = true; if (field.IsTransient) dfield.IsTransient = true; if (field.IsVolatile) dfield.IsVolatile = true; if (field.IsSynthetic) dfield.IsSynthetic = true; if (field.IsEnum) dfield.IsEnum = true; }
/// <summary> /// Ensure that the name of the field is unique. /// </summary> private static void UpdateName(DexLib.FieldDefinition field, ClassDefinition declaringClass) { var baseName = field.Name; var name = field.Name; var postfix = 0; while (true) { if (declaringClass.Fields.All(x => x.Name != name)) { field.Name = name; return; } name = baseName + ++postfix; } }
/// <summary> /// Set the access flags of the created field. /// </summary> protected virtual void SetAccessFlags(DexLib.FieldDefinition dfield, FieldDefinition field) { if (field.IsPrivate) { if (field.DeclaringType.HasNestedTypes) dfield.IsProtected = true; else dfield.IsPrivate = true; } else if (field.IsFamily) dfield.IsProtected = true; else dfield.IsPublic = true; if (field.IsInitOnly) dfield.IsFinal = true; if (field.IsStatic) dfield.IsStatic = true; }
/// <summary> /// Ensure that the name of the field is unique. /// </summary> private static void UpdateName(DexLib.MethodDefinition method, ClassDefinition declaringClass) { var baseName = method.Name; if (baseName == "<init>") baseName = "NetCtor"; var name = baseName; var postfix = 0; while (true) { if (declaringClass.Methods.All(x => x.Name != name)) { method.Name = name; return; } name = baseName + ++postfix; } }
/// <summary> /// Add the given method to its declaring class. /// </summary> protected virtual void SetAccessFlags(DexLib.MethodDefinition dmethod, MethodDefinition method) { if (method.IsPrivate) dmethod.IsPrivate = true; if (method.IsProtected) dmethod.IsProtected = true; if (method.IsPublic) dmethod.IsPublic = true; if (method.DeclaringClass.IsInterface) { dmethod.IsAbstract = true; } else { if (method.IsConstructor) dmethod.IsConstructor = true; if (method.IsAbstract) dmethod.IsAbstract = true; if (method.IsStatic) dmethod.IsStatic = true; if (!method.IsStatic && !method.IsFinal && !method.IsConstructor && !method.IsPrivate) dmethod.IsVirtual = true; if (method.IsFinal || method.IsPrivate) dmethod.IsFinal = true; } }
/// <summary> /// Create a method body for the given method. /// </summary> internal static MethodBody TranslateToRL(AssemblyCompiler compiler, DexTargetPackage targetPackage, MethodSource source, DexLib.MethodDefinition dmethod, 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); // Generate RL code var rlBody = new MethodBody(source); var rlGenerator = new AstCompilerVisitor(compiler, source, targetPackage, dmethod, rlBody); optimizedAst.Accept(rlGenerator, null); // Should we add return_void? if (source.ReturnsVoid) { var instructions = rlBody.Instructions; if ((instructions.Count == 0) || (instructions.Last().Code != RCode.Return_void)) { 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); } }
/// <summary> /// Set the value of the given dex field. /// </summary> protected virtual void SetFieldValue(DexLib.FieldDefinition dfield, FieldDefinition field) { var constant = field.Constant; if (constant != null) { var fieldType = field.FieldType; if (fieldType.IsByte()) { constant = XConvert.ToByte(constant); } else if (fieldType.IsUInt16()) { constant = XConvert.ToShort(constant); } else if (fieldType.IsUInt32()) { constant = XConvert.ToInt(constant); } else if (fieldType.IsUInt64()) { constant = XConvert.ToLong(constant); } } dfield.Value = constant; }
/// <summary> /// Generate method code /// </summary> public override void GenerateCode(DexLib.ClassDefinition declaringClass, DexTargetPackage targetPackage) { // Do nothing }
/// <summary> /// Add the given method to its declaring class. /// </summary> protected override void SetAccessFlags(DexLib.MethodDefinition dmethod, MethodDefinition method) { base.SetAccessFlags(dmethod, method); dmethod.IsNative = true; }
/// <summary> /// Set relation to dex class. /// </summary> internal void SetDexClass(DexLib.ClassDefinition @class, DexTargetPackage targetPackage) { if (@class == null) throw new ArgumentNullException("@class"); if (dexType != null) throw new InvalidOperationException("Cannot set dex class twice"); dexType = @class; }
/// <summary> /// Set the value of the given dex field. /// </summary> protected virtual void SetFieldValue(DexLib.FieldDefinition dfield, FieldDefinition field) { dfield.Value = field.ConstantValue; }
/// <summary> /// Create a dex field definition from this field. /// </summary> public DexLib.FieldDefinition GetDexField(DexLib.ClassDefinition owner, DexTargetPackage targetPackage) { if (dexField == null) { var fdef = new DexLib.FieldDefinition(owner, name, fieldType.GetReference(targetPackage)); if (IsStatic) fdef.IsStatic = true; if (IsPrivate) fdef.IsPrivate = true; else if (IsProtected) fdef.IsProtected = true; else fdef.IsPublic = true; if (IsReadOnly) fdef.IsFinal = true; dexField = fdef; targetPackage.NameConverter.Record(this, dexField); } return dexField; }
/// <summary> /// Gets the type of the value in the given register. /// </summary> public RType GetType(DexLib.Instructions.Register register) { return dRegisterTypes[register]; }
/// <summary> /// Set the value of the given dex field. /// </summary> protected override void SetFieldValue(DexLib.FieldDefinition dfield, FieldDefinition field) { // Do nothing }
/// <summary> /// Add the given method to its declaring class. /// </summary> protected virtual void SetAccessFlags(DexLib.MethodDefinition dmethod, MethodDefinition method) { // subclass accesses have already been fixed on an actual use basis. if (method.IsPrivate) dmethod.IsPrivate = true; else if (method.IsFamily || method.IsFamilyOrAssembly) dmethod.IsProtected = true; else dmethod.IsPublic = true; if (method.DeclaringType.IsInterface) { dmethod.IsAbstract = true; //dmethod. } else { if (method.IsConstructor) { dmethod.IsConstructor = true; dmethod.IsStatic = method.IsStatic; if (method.IsStatic) { // reset access modifiers for static constructors. dmethod.IsPrivate = false; dmethod.IsProtected = false; } } else if (method.IsAbstract) dmethod.IsAbstract = true; else if (method.IsVirtual) dmethod.IsVirtual = true; else if (method.IsStatic) dmethod.IsStatic = true; else dmethod.IsFinal = true; //if (method.IsInitOnly) dmethod.IsFinal = true; } if (method.IsCompilerGenerated()) dmethod.IsSynthetic = true; }
/// <summary> /// Record the given field mapping /// </summary> internal void Record(XFieldDefinition xField, DexLib.FieldDefinition dField) { xFieldMap.Add(xField, dField); }
/// <summary> /// Add the given method to its declaring class. /// </summary> protected override void SetAccessFlags(DexLib.MethodDefinition dmethod, MethodDefinition method) { dmethod.IsStatic = true; dmethod.IsPublic = true; }
/// <summary> /// Set the field type of the given dex field. /// </summary> protected virtual void SetFieldType(DexLib.FieldDefinition dfield, FieldDefinition field, DexTargetPackage targetPackage) { dfield.Type = field.FieldType.GetReference(targetPackage, compiler.Module); }
/// <summary> /// Set the access flags of the created field. /// </summary> protected virtual void SetAccessFlags(DexLib.FieldDefinition dfield, FieldDefinition field) { // subclass accesses have already been fixed on an actual use basis. if (field.IsPrivate) dfield.IsPrivate = true; else if (field.IsFamily || field.IsFamilyOrAssembly) dfield.IsProtected = true; else dfield.IsPublic = true; if (field.IsInitOnly) dfield.IsFinal = true; if (field.IsStatic) dfield.IsStatic = true; if (field.IsCompilerGenerated()) dfield.IsSynthetic = true; dfield.IsVolatile = field.IsUsedInInterlocked || IsVolatile(field); ; }
/// <summary> /// Add the given method to its declaring class. /// </summary> protected virtual void AddFieldToDeclaringClass(ClassDefinition declaringClass, DexLib.FieldDefinition dmethod, DexTargetPackage targetPackage) { dmethod.Owner = declaringClass; declaringClass.Fields.Add(dmethod); }
/// <summary> /// Set the access flags of the created field. /// </summary> protected override void SetAccessFlags(DexLib.FieldDefinition dfield, FieldDefinition field) { base.SetAccessFlags(dfield, field); dfield.IsFinal = true; }
/// <summary> /// Set the field type of the given dex field. /// </summary> protected override void SetFieldType(DexLib.FieldDefinition dfield, FieldDefinition field, DexTargetPackage targetPackage) { dfield.Type = dfield.Owner; }
/// <summary> /// Record the given method mapping /// </summary> internal void Record(XMethodDefinition xMethod, DexLib.MethodDefinition dMethod) { xMethodMap.Add(xMethod, dMethod); }
public static MethodEntry RecordMapping(TypeEntry typeEntry, XMethodDefinition xMethod, MethodDefinition method, DexLib.MethodDefinition dmethod, CompiledMethod compiledMethod) { var scopeId = xMethod.ScopeId; StringBuilder netSignature = new StringBuilder(); method.MethodSignatureFullName(netSignature); var entry = new MethodEntry(method.OriginalName, netSignature.ToString(), dmethod.Name, dmethod.Prototype.ToSignature(), dmethod.MapFileId, scopeId); typeEntry.Methods.Add(entry); if (compiledMethod != null) { compiledMethod.RecordMapping(entry); } return entry; }