先规定一台抽象机器
这里的虚拟机主要指运行程序的抽象机器,不是连同操作系统一起模拟的整台计算机。规范可以规定数值类型、指令、调用和异常等规则,而把底层实现留给开发者。只要实现遵守这些约定,同一目标表示便有机会被不同硬件与系统上的运行环境理解。
执行需要保存哪些状态
以Java虚拟机为例,一次方法调用使用帧保存局部变量、操作数栈和相关信息;对象等数据则涉及堆。抽象机器的状态会随着指令执行而改变。WebAssembly也用栈式计算模型描述许多操作,但两者的指令、类型与存储规则并不相同,不能因都叫虚拟机就混用规范。
规范与执行策略分开
JVM规范明确允许实现自行选择内部优化,例如把虚拟机指令翻译成机器码。因而虚拟机既可能解释指令,也可能结合即时编译;“虚拟”并不等于每步都做软件模拟。语言到中间代码的翻译,与运行环境怎样执行中间代码,是可以分别设计和改进的两层工作。
参考:[1]
可移植性仍有运行边界
可移植的指令格式只是条件之一。程序还可能依赖库、宿主接口、外部文件和资源限制;虚拟机并不会自动统一这些环境。Limbo的Dis与Guile的运行系统也采用各自执行基础。理解它们时,应区分源语言、虚拟指令约定和实际宿主服务,才能知道移植工作究竟落在哪一层。