以Python为例讨论高级编程语言程序的wire format与校验
2010-09-22 11:26:23 来源:WEB开发网核心提示: 如果字节码只是在解释器内部使用,那么JavaScript的执行过程可以粗略看成: 源码->(解析并校验,以Python为例讨论高级编程语言程序的wire format与校验(5),生成字节码)->字节码->(执行) 从wire format到执行之间至少有一次校验,能杜
如果字节码只是在解释器内部使用,那么JavaScript的执行过程可以粗略看成:
源码->(解析并校验,生成字节码)->字节码->(执行)
从wire format到执行之间至少有一次校验,能杜绝许多错误了。编译器自己当然不会乱生成代码,因而后续执行步骤都是可信任的。
封装中间代码为wire format
设计思路的差异使各语言所采用的中间代码的形式也大相径庭,有的与其源语言非常接近,保留源语言中的对象系统、名字空间等多种特性;有的与常见的实际硬件非常接近,数据类型扁平化,控制流的限制也有所放松;有了两个极端,自然也有介乎两者中间的设计。
这些中间代码一般以地址(偏移量)为标签,单就代码表达力而言至少可以实现函数作用域内的任意跳转,有活脱脱的goto的能力。如不加以限制则可能带来隐患。为此,许多中间代码都有附加规定的约束(constraints);执行环境可以在执行中间代码前先检查约束是否满足。例如,JVM规范中就有对JVM字节码的约束的规定。
现有多数高级语言的中间语言都会选择区分代码区与数据区,只有代码区的数据是可执行的;如此一来阻止了自我引用/自我修改代码,二来避免代码夹杂数据而造成代码发现问题。
代码区一般以函数(方法)为单位来划分,可以明确定位到每个函数(方法)代码的起始位置。
出于安全性的考虑,也为了中间代码能被更高效的执行,主流的高级语言的中间代码一般不允许间接跳转,跳转地址写死在指令里;跳转目标一般也限定在函数(方法)的内部,不然只能是函数(方法)的调用或返回;对填充数据也有严格的规定。
这样,虽然许多中间代码采用可变长度的设计,但从明确的起始位置出发,经过固定地址的局部跳转或易于分析的调用/返回跳转,代码发现就不成问题了。
更多精彩
赞助商链接