代码{}在JavaScript中是完全合法的,因为它表示Block

但是,我注意到在Chrome *中嵌套了很多块({{...}})会引起很多问题:



为什么在这里发生堆栈溢出?

这是一个codepen说明问题(jsfiddle崩溃)。

在JSRoom中询问时,Zirak发现在chrome上,魔数是 3913 块,在Firefox上是 2555

什么被压入堆栈?为什么?

(*)我已经检查过了,它也出现在IE和Firefox中

更新:我已经检查过,IE无法可靠地避免堆栈溢出异常。它已经抛出了两次,但没有第三次。如果有任何读者使用IE,并且也愿意测试它的旧版本(例如IE8和9),请告诉我发生了什么,我将非常感谢。

最佳答案

首先,ghord是完全正确的。它是由解析器的递归性质引起的,因此请给他投票爱。但是需要证明,OP希望我将其作为单独的答案发布。

火狐浏览器

那么,在哪里可以找到如何完成的呢?问一些从事发动机制造的人。所以我转到#jsapi上的irc://irc.mozilla.org channel ,问他们:



这几乎就是答案。转到mozilla中央存储库并进行挖掘,我们有以下怀疑:

  • Parser<ParseHandler>::blockStatement
  • Parser<ParseHandler>::statements

  • 因此,我们拥有的是:
  • statements调用blockStatement,后者解析该块,以查找另一个块,然后调用
  • statements调用blockStatement,后者解析该块,以查找另一个块,然后调用
  • statements调用blockStatement,后者解析该块,以查找另一个块,然后调用
  • ...

  • 直到堆栈崩溃,我猜是here

    因此,我们有Firefox的源代码。

    Chrome / Chromium /其他基于v8的版本

    从Firefox上学习了教训,我进入了v8项目并寻找了一个名为parser的文件。果然在那里。

    接下来的事情是寻找何时解析一个块,所以我天真地搜索了statements,到达了有希望的ParseStatement

    这是我们的幸运日,一个巨大的switch!我们关心的是the first case,它是另一个有希望的名字ParseBlock的调用!

    实际上,是inside ParseBlock , we find a callParseStatement。因此,很明显,我们有两个功能:
  • Parser::ParseBlock
  • Parser::Parser::ParseStatement

  • 他们像在Firefox中看到的那样互相打电话:
  • ParseStatement调用ParseBlock,后者解析该块,以查找另一个块,然后调用
  • ParseStatement调用ParseBlock,后者解析该块,以查找另一个块,然后调用
  • ParseStatement调用ParseBlock,后者解析该块,以查找另一个块,然后调用
  • ...

  • 直到kaboom进入堆栈。

    苹果浏览器

    (很抱歉在上次编辑中将其称为“封闭源”!)Safari的js引擎是JavaScriptCore,它位于WebKit项目中。查找功能与在Chrome中查找功能几乎相同,因此让我们跳到有趣的部分:
  • Parser<LexerType>::parseSourceElements
  • Parser<LexerType>::parseStatement
  • Parser<LexerType>::parseBlockStatement

  • 我们在中间有一个额外的功能,但是原理是一样的:
  • parseSourceElements调用parseStatement调用parseBlockStatement,后者解析该块,以查找另一个块,然后调用
  • parseSourceElements调用parseStatement调用parseBlockStatement,后者解析该块,以查找另一个块,然后调用
  • parseSourceElements调用parseStatement调用parseBlockStatement,后者解析该块,以查找另一个块,然后调用
  • ...

  • 繁荣

    IE(以及其他所有开源软件,例如Opera)

    ……除非他们突然感到急切地要求公开消息,或者有进取心的员工与我们分享内部信息,否则这仍然是个谜。上面的两个出色的引擎以相同的方式进行操作,因此我们可以假定其他浏览器也以类似的方式进行操作。

    如果浏览器没有崩溃,那将是一个有趣的问题,但是这个答案不能指望有人咳嗽。

    09-19 03:40