语言引擎 VS。运行时 VS。进程虚拟机

Teo*_*ite 7 interpreter runtime compilation javascript-engine vm-implementation

由于 JavaScript 的日益流行,我发现听到(甚至在同一个演讲中)关于 JavaScript引擎、JavaScript虚拟机或 JavaScript解释器,在相同的上下文中并指同一个事物很有趣。

因此,我试图做一些研究,为什么所有这些流行语会同时共存(必须有一个原因),以及它们之间是否存在一些真正的(尽管细微的)差异。

我试图从许多不同的来源(我在以下几行中引用)总结到目前为止我学到的东西。如果我错了/误导了某些东西,请随时纠正我。

虽然我发现它们的运行时职责基本相同,但我也发现了一些主要区别:

  1. 进程虚拟机

  2. 运行时

    • 不会从本机代码中抽象出来
    • 使用编译技术(即时提前
    • 缺少 VM 进程/沙盒应用程序
    • 与底层操作系统紧密耦合/依赖
    • 示例:公共语言运行时、Android 运行时
  3. 语言引擎

问题:

  • 上面的列表是否准确,或者它只是基于使用相同名称的大多数常见运行时系统之间完全巧合的相似性的副产品?

  • 还有其他值得注意的差异吗?

Car*_*edy 0

长话短说:

虚拟机是一个概念,它代表了如何将 CPU 用于执行程序的实际指令与人类可读的源代码解耦。作为程序员,您能够编写更少的代码来完成更多的事情。

更长的答案

我很确定您正在寻找比您在问题中概述的分类简单得多的答案。通常,虚拟机仅代表插入在您编写的源代码与物理硬件如何接收这些指令之间的抽象。

与处理器对话所需的所有细节都由“虚拟机”处理,虚拟机本身会自动执行许多重复命令,这些命令可能需要执行非常简单的操作,例如操作字符串 UTF-8编码字符并将其打印到命令行。Python 使用一种,Java 使用一种,而您上面概述的“语言引擎”类只是虚拟机同一概念的一个更奇特的名称。任何虚拟机都可以像虚拟机程序员设计的那样快速和轻量级,这将提高为其开发的应用程序的可用性和可靠性。

与使用 Java 和 Python 的情况一样,您可以使用冗长的语言编写程序,这些语言与物理处理器执行命令所需的“语言”几乎没有共同之处。值得庆幸的是,比我聪明得多的人已经使用特定于处理器的语言(称为“汇编器”或“汇编”语言)创建了程序,这些语言在指令集架构(例如 RISC-V、x8/x86-64、ARMv8)之间有所不同。 )。这些程序可以按程序将您编写的内容翻译成特定于处理器的语言,本质上充当翻译层。

您最终可能会得到的是您(开发人员)和您尝试利用的硬件之间的更简单的界面。首先,为了在不同的操作系统环境中运行程序,您唯一需要的就是用物理主机处理器使用的任何汇编语言来实现虚拟机。

注意:我说可以是因为对任何给定语言语法的欣赏都是非常主观的。

举一个高级示例,我们可以使用 Python“解释器”来执​​行预先编写的脚本并在命令行应用程序中进行交互,它依赖于一个编译器,该编译器根据您的代码创建 Python 字节码,然后将其输入进入所谓的Python虚拟机进行处理器执行。

此外,虚拟机“语言引擎”之间没有真正的区别。JavaScript 语言引擎(例如 Google 的 V8)只是这种虚拟机概念的实现,它允许开发人员在开发基于 Web 的动态应用程序时依赖平台不可知论和可移植性,而不必担心破坏程序的可用性。

如果您有兴趣,请研究一下 Python 的各种实现(Jython、IronPython 等)。它们使用由其他语言/框架(例如 Java 和 .NET)实现的概念虚拟机来创建使用相同语法的 Python 实现,但交叉编译为 Java 字节码或通用中间语言字节码指令以实现相同的结果。几乎普遍提到的“python解释器”是由Python软件基金会官方维护的C语言实现的解释器,通俗地称为“CPython”。

为了真正让大家理解,这里有一个用 Python、C++ 使用 C 库和 x86 ASM(x86 汇编语言)编写的质数检查算法(由 xmdi 在 youtube 上提供),您将能够看到 Python VM 如何启用这种算法语法允许人们轻松地进入编程,而不会失去理智尝试使用汇编语言处理寄存器操作:

Python:

def isPrime(n):
    for i in range(2,n//2+1):
        if (not (n%i)):
            return 0
        return 1

numPrimes = 0

for i in range(2,250001):
    numPrimes+=isPrime(i)

print(str(numPrimes))
Run Code Online (Sandbox Code Playgroud)

C++:

#include <stdio.h>

int isPrime(int n){
    for (int i = 2; i <= n/2; i++){
        if (!(n%2)){
            return 0;
        }
    }
    return 1;
}

int main(){
    int numPrimes = 0;
    
    for (int i = 2; i <= 250001; i++){
        numPrimes += isPrime(i);
    }

    printf("%d\n", numPrimes);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

x86 ASM:

.section .data
    f: .string "%d/n"
.section .text
    .globl main
    main:
        movl $2, %eax
        xor %r8d,%r8d
    loop:
        cmpl $250000,%eax
        jg end_loop
        movl $2, %r10d
        movl %eax,%r11d
        shr $1,%r11d
    prime_loop:
        cmpl %r11d,%r10d
        jg prime
        push %rax
        xor %edx,%edx
        div %r10d
        test %edx,%edx
        pop %rax
        je not_prime
        inc %r10d
        jmp prime_loop
    prime:
        inc%r8d
    not_prime:
        inc %eax
        jmp loop

    end_loop:
        lea f(%rip),%rdi
        mov %r8d,%esi
        xor %eax,%eax
        call printf
Run Code Online (Sandbox Code Playgroud)