-
Notifications
You must be signed in to change notification settings - Fork 20
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
node源码粗读(5):通过调试./lib库的js代码来看javascript在node中运行环境的变化 #14
Comments
再次编译的时候看起来需要把 |
@AsceticBoy 不需要删文件,node的编译是增量的 |
@AsceticBoy 你仔细看下报错,loop多了个o |
@xtx1130 谢谢🙏 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
前言
相信对node源码感兴趣的同学一定知道,./lib库中的js通过node.gyp自动转换成了node_javascript.cc中的ASCII码,如果读过我之前写的一篇文章,应该也是对此有点了解的,而./lib库中的bootstrap_node.js又是js的入口文件,所有./lib下的文件几乎都需要它来挂载。那么这部分代码又该如何调试修改呢?
./lib中的js如何编译
由于./lib库中的js都是存储在node_javascript.cc中,所以我们如果想要调试./lib中的js需要多一个编译的步骤,也就是把你修改的代码编译到node_javascript.cc中。如果大家读过node.gyp以及makefile,那么整个编译流程就会很清晰,在这篇文章中不做过多解读,如果有兴趣了解的话请移步这里。我们在修改完代码后需要执行一下make来进行编译。make会根据lib库中的js重新生成node_javascript.cc文件。这样就可以保证./lib库中的代码在调用的时候都是最新的了。
调试
相信大家都了解,node的入口文件是bootstrap_node.js,那么我们就从这个文件入手,聊一聊该如何调试。二话不说,先写一个console.log然后make一下看看更新了么。
然后我们make一下(手动滑稽.jpg):
![issue14-1](https://github.com/xtx1130/blog/raw/master/images/issue14/issue14-1.png)
![issue14-2](https://github.com/xtx1130/blog/raw/master/images/issue14/issue14-2.png)
![issue14-3](https://github.com/xtx1130/blog/raw/master/images/issue14/issue14-3.png)
nice,没有报错,release和debug都完美生成了。接下来,我们开始跑了:
What?!代码没更新?console没出来?还没报错?这是什么情况?(黑人问号脸.jpg)
吓得我赶紧去翻一下node_javascript.cc,然后看到了:
上面的红框表示是文件internal/bootstrap_node.js,下面的红框如果大家有兴趣可以查一下ASCII,表示的是
console.log(1111)
。这里可以说明,编译是绝对没问题的,那么问题出在哪里呢?js node运行环境的变化
顺着bootstrap_node.js往下看会看到一段代码:
之后的调用栈就不深扒了,通过命名可以看出来,这是装载全局console的代码。哦,原来是在这里装载的,那我在这之后打个console试试?
![issue14-4](https://github.com/xtx1130/blog/raw/master/images/issue14/issue14-4.png)
居然打出来了?!那么另外一个问题就来了,为什么之前那个console没打出来亦没有报错呢?
然后我们可以做一个小测试,分别在这两个地方设置断点,然后在前面的断点记录下来console.log,在后面的断点对比两者是否相等,代码如下
接下来我们跑一遍验证一下,在跑之前记得修改一下调用参数哦:
![issue14-5](https://github.com/xtx1130/blog/raw/master/images/issue14/issue14-5.png)
![issue14-6](https://github.com/xtx1130/blog/raw/master/images/issue14/issue14-6.png)
![issue14-7](https://github.com/xtx1130/blog/raw/master/images/issue14/issue14-7.png)
这个地方应该都没有疑问吧,肯定是true,接下来我们看下面的debugger:
通过这个结果,能清晰的看出来node已然把console重做了。那么为什么要重做呢?
于是乎,在这里引出来一个概念:v8是js的翻译(编译)器,而node在c++中会为js全局添加global而且会把process作为bootstrap_node.js的参数传入;而在bootstrap_node.js中,则会添加和重写一部分方法,使之符合node的相关需求。
我们还是用console这个例子说明一下。在node中,console的输出是针对于ttys的,所以node在处理console的时候,其实是引入了process.stdout.write的概念来实现的console,具体代码可以参考这里,对于这部分代码不在本次主要的说明范围内,所以不做过多解释,有兴趣的可以结合上下文看一下。这就是一个非常典型的
node runtime interface
。node runtime interface
如果大家看过./lib下面的js文件,那么会发现一个非常有意思的文件: ./lib/repl.js,这个文件可以让你的代码获得runtime interface。
总结
by 小菜
The text was updated successfully, but these errors were encountered: