我正试图将我的Android应用程序与用Free Pascal编译的JAR链接起来。我得到以下构建错误:
[2012-09-14 16:08:38 - MyApp] Dx
EXCEPTION FROM SIMULATION:
[2012-09-14 16:08:38 - MyApp] Dx local 0009: invalid
[2012-09-14 16:08:38 - Yarxi] Dx ...at bytecode offset 00015f2c
locals[0000]: Lcom/mypackage/$Core$$_fpc_nestedvars$70;
locals[0001]: I
locals[0002]: I
locals[0003]: I
locals[0004]: I
locals[0005]: I
locals[0006]: I
locals[0007]: I
locals[0008]: I
locals[0009]: <invalid>
locals[000a]: <invalid>
(..more locals... much more)
locals[06db]: <invalid>
stack[0003]: I
stack[0002]: I
stack[0001]: [I
stack[top0]: int{0x00000000 / 0}
...while working on block 5f23
...while working on method $MyMethod$944$FPR1:(Lcom/mypackage/$Core$$_fpc_nestedvars$70;)V
...while processing $MyMethod$944$FPR1 (Lcom/mypackage/$Core$$_fpc_nestedvars$70;)V
...while processing com/mypackage/Core.class
[2012-09-14 16:08:40 - MyApp] Dx 1 error; aborting
[2012-09-14 16:08:40 - MyApp] Conversion to Dalvik format failed with error 1
错误似乎是在某个时刻,代码试图读取未初始化的本地0009。
现在,Pascal不强制初始化局部变量。很可能,初始化一开始就被省略了。我保留了Free Pascal为我生成的JVM汇编文件。这些文件与Jasmin一起汇编成类文件。这个文件太大了,我不会把它粘贴在这里。
有人能帮我把错误点追溯到源头吗?错误位于字节码偏移00015f2c处。有没有办法把它转换回汇编文件的行号?
已解决。00015f2c(十进制89900)实际上是一个方法中的字节码偏移量。我做了以下事情。
首先,我直接调用Jasmin,传递生成的.j文件和-g选项(生成行号):
java -jar %JASM% -g Core.j
Free Pascal本身不会发出-g。这给了我一个可选的Core.class文件,其中有行号,行号是相对于FPC生成的.j文件的。然后我使用javap
将类反汇编回另一个.j文件:
"%JDKROOT%javap" -l -c Core.class >Core_WithLines.j
但这个新的.j文件包含了每个单独命令的行号和偏移量。然后,我在有问题的方法中搜索偏移量89900(注意:偏移量,由javap
生成,在65536处换行)。然后,我查看了该方法主体下方的LineNumberTable(偏移量和行号都换行),在源Core.j文件中找到了与该偏移量对应的行号。回顾一下Core.j,有一条注释包含Pascal源代码的行号。
确实,有一个函数调用传递了一个未初始化的变量,但作为var
参数。
这个问题有点像Pascal/JVM的边界问题。变量未初始化,但ref将其传递到一个函数中,该函数将从后者返回。编译器应该以某种方式抽象掉它,IMHO,但FPC没有。