JavaScript执行栈的实际V8实现

3

我很好奇。JavaScript引擎如何内部实现EMCAScript执行堆栈指令。

如果你看下面的代码,EMCAScript会要求我们创建一个全局执行上下文(Global execution context),其中包含fun1、res和c变量的环境记录(Environmental Record)。 当fun1被调用时,我们将创建一个新的函数执行上下文(Function execution context),它将有一个环境记录(Environmental Record),其中包含a和b变量及其关联值。

在V8团队的这篇博客文章中Blazingly fast parsing, part 2: lazy parsing,清楚地表明他们在内部使用内存堆栈来控制函数调用,除非变量受到闭包的影响。

我想知道下面代码中的res和c变量是否也会被放在堆栈上? 对于像示例中这样简单的代码,全局和函数执行上下文的环境记录实际上是否会被创建。

任何答案都将不胜感激,充分理解在此情况下答案并不重要,只要使用JS即可。

let fun1 = function(a){
let b = 2;
return a+b;
}
let res = fun1(4);
let c = ”done";

1个回答

1

(我是一名V8开发者。)

JavaScript引擎内部的实现方式是怎样的?

每个引擎的答案都不同,而且随着时间的推移会有所改变。即使你专注于一个版本的一个引擎,答案也可能是“取决于情况”。

我很好奇下面代码中的resc变量是否也会被放置在堆栈上?

全局变量是全局对象上的属性。这些变量的值在存储为全局对象属性之前可能会短暂地存储在堆栈上,也可能不会。

像示例中那样简单的代码,全局和函数执行上下文的环境记录是否真的会被创建?

是的——无论如何都会有。拥有全局对象并在其上存储属性是为全局上下文创建“环境记录”的一种方式。

这种抽象是一个关键的洞见。不要期望有一个类EnvironmentalRecord或类似的东西。它是一个抽象概念,描述引擎必须有一种方法来存储函数的变量。这可以是堆栈帧中的插槽,或者是“上下文”对象,或者(在优化编译器中)某个寄存器的“活动范围”,或任何其他内部实现选择。值得注意的是,在编译时进行作用域解析和在运行时进行实际值存储之间存在区别:对于前者,引擎可能需要保留更多元数据,并使用不同的内部实现,而对于后者则不同。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接