源映射
作为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
分开 ;
.这些元素中的每一个都对应于一条指令,即不能使用字节偏移量,但必须使用指令偏移量(推送指令比单个字节长)。田野 s
, l
和 f
如上。 j
要么可以 i
, o
或 -
表示跳转指令是否进入函数、从函数返回或是作为循环的一部分的常规跳转。最后一个领域, 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 如果使用内置,则源映射将无效:内置将被视为单条指令,而不是潜在的多条指令。