首页 > 解决方案 > JS执行栈的实际V8实现

问题描述

我只是好奇。JavaScript 引擎究竟是如何在内部实现 EMCAScript 执行堆栈指令的。

如果您查看下面的代码,ECMAScript 将期望我们创建一个全局执行上下文,其中包含一个包含 fun1、res 和 c 变量的环境记录。当 fun1 被调用时,我们将创建一个新的函数执行上下文,该上下文将具有一个包含 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";

标签: v8executioncontext

解决方案


(这里是 V8 开发人员。)

究竟如何

确切的细节很复杂。如果您真的关心这些,请阅读源代码。

JavaScript 引擎是否在内部实现

每个引擎的答案都会有所不同。它也会随着时间而改变。即使您放大一个引擎的一个版本,答案也可能是“视情况而定”。

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

全局变量是全局对象的属性。这些变量的值可能会或可能不会在存储为全局对象属性之前暂时存储在堆栈中。

是否会为示例中的简单代码创建全局和函数执行上下文的环境记录。

是的——一种或另一种方式。拥有一个全局对象并在其上存储属性是为全局上下文创建“环境记录”的一种方式。

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


推荐阅读