Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Xamarin.Android.Tools.Bytecode] Ignore synthetic ctor params (#1091)
Fixes: #1090 Attempting to parse [TensorFlow 1.13.1][0] with a Debug build of `class-parse` results in an assertion failure: % curl -o tensorflow-android-1.13.1.aar https://repo1.maven.org/maven2/org/tensorflow/tensorflow-android/1.13.1/tensorflow-android-1.13.1.aar % unzip tensorflow-android-1.13.1.aar classes.jar % dotnet bin/Debug-net7.0/class-parse.dll classes.jar Unexpected number of method parameters; expected 0, got 1 at Xamarin.Android.Tools.Bytecode.MethodInfo.UpdateParametersFromMethodParametersAttribute(ParameterInfo[] parameters) at Xamarin.Android.Tools.Bytecode.MethodInfo.GetParameters() at Xamarin.Android.Tools.Bytecode.XmlClassDeclarationBuilder.GetMethodParameters(MethodInfo method)+MoveNext() at System.Xml.Linq.XContainer.AddContentSkipNotify(Object content) at System.Xml.Linq.XContainer.AddContentSkipNotify(Object content) at Xamarin.Android.Tools.Bytecode.XmlClassDeclarationBuilder.GetMethod(String element, String name, MethodInfo method, String returns) at Xamarin.Android.Tools.Bytecode.XmlClassDeclarationBuilder.<GetConstructors>b__23_2(MethodInfo c) Note: this will only happen for Debug builds of `class-parse`, which we do not ship. Thus, this will only happen if you are using a local build of xamarin/Java.Interop. The assertion occurs when processing the constructor for `org/tensorflow/Session$Runner$Reference.class`, which is a non-static inner class: % unzip classes.jar 'org/tensorflow/Session$Runner$Reference.class' % dotnet bin/Debug-net7.0/class-parse.dll --dump 'org/tensorflow/Session$Runner$Reference.class' … Methods Count: 2 0: <init> (Lorg/tensorflow/Session$Runner;)V Public Code(60, Unknown[LineNumberTable](30), LocalVariableTableAttribute(LocalVariableTableEntry(Name='this', Descriptor='Lorg/tensorflow/Session$Runner$Reference;', StartPC=0, Index=0)), Xamarin.Android.Tools.Bytecode.StackMapTableAttribute) MethodParametersAttribute(MethodParameterInfo(Name='this$1', AccessFlags=Final, Synthetic)) Note the `MethodParameterInfo.AccessFlags` value for the parameter: `AccessFlags=Final, Synthetic`. This differs from the `Final, Mandated` value that is checked for by `MethodInfo.UpdateParametersFromMethodParametersAttribute()`: var OuterThis = MethodParameterAccessFlags.Final | MethodParameterAccessFlags.Mandated; // … while (startIndex < pinfo.Count && (pinfo [startIndex].AccessFlags & OuterThis) == OuterThis) { startIndex++; } Because the parameter is `Final, Synthetic` and not `Final, Mandated`, the parameter is *not* skipped, which results in the assertion message `expected 0, got 1`. @jonpryor does not know how or why `Final, Synthetic` is being used by `Session$Runner$Reference.class`, and is unable to reproduce this particular Java bytecode output with the JDK 1.8 and JDK 11 compilers. Update `MethodInfo.UpdateParametersFromMethodParametersAttribute()` to also skip `Final, Synthetic` parameters. This allows `Session$Runner$Reference.class` to be processed without assertions: % dotnet bin/Debug-net7.0/class-parse.dll classes.jar # no errors Additionally, update the assertion message so that it includes the declaring class name, method name, and method descriptor. [0]: https://mvnrepository.com/artifact/org.tensorflow/tensorflow-android/1.13.1
- Loading branch information