源映射

作为AST输出的一部分,编译器提供由AST中的各个节点表示的源代码范围。这可以用于各种用途,从基于AST报告错误的静态分析工具,到突出显示局部变量及其用途的调试工具。

此外,编译器还可以生成从字节码到生成指令的源代码范围的映射。这对于在字节码级别上操作的静态分析工具,对于在调试器中显示源代码中的当前位置或对于断点处理来说,这一点同样重要。此映射还包含其他信息,如跳跃类型和修改器深度(见下文)。

这两种源映射都使用整数标识符来引用源文件。源文件的标识符存储在 output['sources'][sourceName]['id'] 在哪里? output 标准json编译器接口的输出被解析为json。对于某些实用程序例程,编译器生成“内部”源文件,这些文件不是原始输入的一部分,而是从源映射引用的。这些源文件及其标识符可以通过 output['contracts'][sourceName][contractName]['evm']['bytecode']['generatedSources'] .

注解

对于不与任何特定源文件关联的指令,源映射将分配一个整数标识符 -1 .对于源自编译器生成的内联汇编语句的字节码部分,可能会发生这种情况。

AST内的源映射使用以下表示法:

s:l:f

哪里 s 是源文件中范围开始的字节偏移量, l 是源范围的长度(以字节为单位), f 是上面提到的源索引。

字节码源映射中的编码更加复杂:它是 s:l:f:j:m 分开 ; .这些元素中的每一个都对应于一条指令,即不能使用字节偏移量,但必须使用指令偏移量(推送指令比单个字节长)。田野 slf 如上。 j 要么可以 io- 表示跳转指令是否进入函数、从函数返回或是作为循环的一部分的常规跳转。最后一个领域, m ,是表示“修改器深度”的整数。每当占位符语句 (_ )在修饰符中输入并在再次离开时减少。这使得调试器能够跟踪棘手的情况,比如同一个修饰符被使用了两次,或者在一个修饰符中使用了多个占位符语句。

为了压缩这些源映射,尤其是字节码映射,使用以下规则:

  • 如果字段为空,则使用前面元素的值。

  • 如果A : 缺少,以下所有字段都视为空。

这意味着以下源映射表示相同的信息:

1:2:1;1:9:1;2:1:2;2:1:2;2:1:2

1:2:1;:9;2:1:2;;

需要注意的是,当 verbatim 如果使用内置,则源映射将无效:内置将被视为单条指令,而不是潜在的多条指令。