到目前为止,我正在开发一种语言,它可以编译成字节码,然后由虚拟机运行。我的问题是,当发生运行时错误时,VM如何知道源代码的哪一行导致错误,因为在编译过程中删除了所有空白。我想到的一件事是存储一个单独的整数数组,该数组与字节码和其中的行号相关,但这听起来非常节省内存,特别是当有很多指令时。
某些形式的字节码包含行号、方法名等信息,这些信息是为了提供更好的调试信息。例如,在JVM中,方法字节码包含一个表,该表将字节码地址的范围映射到源行号。这是一种比用行号标记每个字节码操作更有效的存储方式,因为每行通常有多个操作。它确实占用了额外的空间,但我不会把它归类为效率极低。
如果没有这个信息,解释器真的没有办法报告关于原始程序的任何信息,因为正如你已经注意到的那样,所有的信息都将被丢弃。
这类似于编译后的可执行文件处理调试信息的方式。有了调试符号,程序就有了将代码地址映射到函数名和行号的表。去掉符号后,你得到的只是原始指令和数据,没有办法引用原始代码。