原本打算是把node源码看得差不多了再去深入V8的,但是这两者基本上没办法分开讲。

  与express是基于node的封装不同,node是基于V8的一个应用,源码内容已经渗透到V8层面,因此这章简述一下我目前理解的V8引擎吧。

  首先需要理解的是V8是一个JS代码运行平台,可以将JS代码编译执行。

  本节就非常浅显的讲一下V8内部一些常见类,以及一个运行JS代码的简单demo。

  (由于研究V8引擎原理的人非常多,本人学识浅薄,可以去参考别人的博客)

参考资料:

  1、很多大佬的博客

  2、V8引擎API文档:https://v8docs.nodesource.com/

  3、github:https://github.com/v8/v8

  

  本节先列举一些核心类,示例代码大部分来源于node中的源码。

Isolate

  该类代表一个V8引擎实例,有自己独立的状态,用法如下。

1、不能使用new关键字来生成一个实例,只能通过类方法Isolate::New(params)来创建。

Isolate* const isolate = Isolate::New(params);

2、该类的方法都是设置V8引擎的一些处理细节。

// 添加error的信息监听器
isolate->AddMessageListener(OnMessage);
// 从名字能看出来 设置未捕捉中断异常的回调函数
isolate->SetAbortOnUncaughtExceptionCallback(ShouldAbortOnUncaughtException);
// 设置Microtask的执行方式(有三种)
isolate->SetMicrotasksPolicy(v8::MicrotasksPolicy::kExplicit);
// 设置致命错误的回调函数
isolate->SetFatalErrorHandler(OnFatalError);
// WebAssembly代码生成回调函数
isolate->SetAllowWasmCodeGenerationCallback(AllowWasmCodeGenerationCallback);

3、作为一个参数传入其余的V8工具类中。

// 单线程运行V8的Isolate
Locker locker(isolate);
Isolate::Scope isolate_scope(isolate);

Local/Persistent - Handle

  这个地方我之前一直比较混乱,因为有文章指出:Handle类定义在v8.h中,它是一个模板类,而且有两个派生类Local和Persistent。

  出处:https://blog.csdn.net/sunbxonline/article/details/20310897

  但是从源码来看,无论是Local<T>还是MaybeLocal<T>,均不继承于任何类(在V8中确实存在一个Handle的类,但是跟这两个没有继承关系)。

  这是因为V8版本不一致,所以我这里只讲当前版本的情况,源码注释如下:

#if !defined(V8_IMMINENT_DEPRECATION_WARNINGS)
// Handle is an alias for Local for historical reasons.
template <class T>
using Handle = Local<T>;
#endif

  这两个类从作用上讲都是handle,但实际上并不继承于同一个父类。

1、Local/Persistent是V8的两个类,指向底层的原始数据。

2、所有对象的引用都需要被V8的垃圾回收管理,在管理中可能出现移动对象的情况(参考网上大量关于V8垃圾回收的博客),这会导致对象指针产生错误,所以不能直接使用原始的数据类型,诸如String,而需要使用Local<String>,Local被V8引擎管理,会在对象移动时更新指针指向,并在合适的时候进行回收。

3、Persistent属于全局对象(可参考Global),独立于HanldeScope,可使用Reset方法清空。

Value

  所以JS数据类型映射到C++的根类,继承关系如下:

  具体的内部实现后面做分析。

HandleScope

  一个管理handle的容器,在当前作用域开头声明一个HanldeScope,在域结束时会自动清理所有的handle。

HandleScope handle_scope(isolate);

  嵌套使用时,作用域会自动进行切换。

Context

  执行上下文,有自己独立的函数与对象。与Isolate相似,通过类方法New来生成。

auto context = Context::New(isolate, nullptr, object_template);

  可通过内部Scope类来进行上下文的切换。

Context::Scope context_scope(context);

Script

  该类主要负责对JS代码字符串进行编译和执行,核心方法为Compile、Run。

  Script::Compile可以编译JS代码字符串,返回一个Local<Script>对象

  Script::Run可以执行编译后的JS代码,返回一个Handle<Value>对象

  另外,还有FunctionTemplate/ObjectTemplate可以封装C++的对象、函数提供给JS代码调用,示例代码如下:

// 将C++的GetBinding函数包装提供给JS代码调用
// NewFunctionTemplate是v8::FunctionTemplate::New()方法的包装
v8::Local<v8::Function> get_binding_fn =
env->NewFunctionTemplate(GetBinding)->GetFunction(env->context())
.ToLocalChecked();

  基本上大部分用到的东西就是上面所列举的,GC暂时不讨论,以一个非常简单的网上案例把上面的东西串起来:

// 创建一个Isolate实例
Isolate::CreateParams params;
Isolate* const isolate = Isolate::New(params);
// 创建一个HandleScope管理handle
HandleScope handle_scope(isolate);
// 创建一个上下文执行环境
Local<Context> context = Context::New(isolate);
// 切换到当前上下文
Context::Scope context_scope(context);
// 新建一个Local
// 类型可以类比JS的源字符串
Local<String> source = v8::String::NewFromOneByte(isolate , "12345");
// 编译该JS字符串
MaybeLocal<v8::Script> script = v8::Script::Compile(context , source);
// 执行上面返回的编译对象
Local<Value> result = script.ToLocalChecked()->Run(context).ToLocalChecked();
// 这个result就是对JS源字符串编译执行后的C++代码
Local<String> str = result->ToString(context ).ToLocalChecked();

  这样,对V8引擎就有了一个基本的认识,可以帮助我们更好的学习nodejs源码。

转载于:https://www.cnblogs.com/QH-Jimmy/p/9212923.html

深入出不来nodejs源码-V8引擎初探相关推荐

  1. 深入出不来nodejs源码-内置模块引入初探

    重新审视了一下上一篇的内容,配合源码发现有些地方说的不太对,或者不太严谨. 主要是关于内置模块引入的问题,当时我是这样描述的: 需要关注的只要那个RegisterBuiltinModules方法,从名 ...

  2. 深入出不来nodejs源码-编译启动

    整整弄了两天,踩了无数的坑,各种奇怪的error,最后终于编译成功了. 网上的教程基本上都过时了,或者是版本不对,都会报一些奇怪的错误,这里总结一下目前可行的流程. node版本:v10.1.0. 首 ...

  3. 从os.cpus()来分析nodejs源码结构

    这几天和小伙伴在研究怎么用nodejs来监控机器的硬件信息,其中有项是要计算CPU的剩余idle信息,第一时间想到用top命令, 可以直接获取当前机器的硬件信息.本着好奇查了下top命令计算CPU i ...

  4. nodejs源码_格物致知记一次nodejs源码分析的经历

    昨天分析http模块相关的代码时,遇到了一个晦涩的逻辑,看了想,想了看还是没看懂.百度.谷歌了很多帖子也没看到合适的答案.突然看到一个题目有点相识的搜索结果,点进去是Stack Overflow上的帖 ...

  5. 格物致知-记一次nodejs源码分析的经历

    昨天分析http模块相关的代码时,遇到了一个晦涩的逻辑,看了想,想了看还是没看懂.百度.谷歌了很多帖子也没看到合适的答案.突然看到一个题目有点相识的搜索结果,点进去是Stack Overflow上的帖 ...

  6. php项目素材,PHP素材资源解析平台源码V8.0(thinkPHP框架内核)

    PHP素材资源解析平台源码V8.0 第三方平台下载千图网千库网等素材网站下载站 V8版本.十月一日最 新更新,全新的解析架构. 小白问题一:为什么我不能解析? 答:解析是需要开通目标站VIP的. 小白 ...

  7. 百度SEO站群素材资源解析平台系统源码V8.0

    素材资源解析平台系统源码V8.0 第三方平台下载站程序千图网千库网等素材网站下载网站 下载地址: http://www.bytepan.com/SkCylUCcHaR 小白问题一:为什么我不能解析? ...

  8. 最新亲测云赏在线视频打赏源码V8.5修复完整版

    正文: 云赏在线视频打赏源码+V8.1版本+V8.5终结版+V8.5修复完结版+已购和包天包周包月功能+码支付+qq乐支付+大产付+安装教程(文字+视频) V8.1版本:带已购.包天功能,对接好全新极 ...

  9. 最新西门子224/226PLC源码/V8.9西门子PLC源码 C v8.9运行源代码,本人已修改好剩余的bug

    最新西门子224/226PLC源码/V8.9西门子PLC源码 C v8.9运行源代码,本人已修改好剩余的bug /* 20190723A 通过宏定义,快速切换224XP/226 (50586) 201 ...

最新文章

  1. CSS之布局(盒子模型--外边距)
  2. python3 判断ip有效性 是否是内网ip
  3. tomcat 启动项目 页面文字乱码_eclipse启动tomcat项目乱码而终端启动tomcat正常的解决办法...
  4. Day2-springmvc初解
  5. 复制公钥到多个服务器脚本
  6. [Qt教程] 第40篇 网络(十)WebKit初识
  7. Eclipse输入Java和XML代码自动提示功能最简单的方法
  8. intellij中导入外部的依赖包+在当前的工程中使用
  9. 文献学习(part6)--Clustering ensemble based on sample’s stability
  10. JavaScript回顾与学习——条件语句
  11. 对于高并发的理解及实践方案
  12. 改善深层神经网络:超参数调整、正则化以及优化 —— 3.1调试处理
  13. 英特尔 AI 芯片业务的现状与未来
  14. sqlite3 判断数据库和表的状态
  15. python26个保留字,Python保留字(关键字)一览表
  16. 基于特征子空间的波束形成算法原理介绍及MATLAB实现
  17. 促双碳|智慧能源管理解决方案
  18. 计算机的usn插口无法读取,USB3.0还缺谁 解决主板插槽不健全方案
  19. 芯片设计中的latch_Flip-Flop和Latch
  20. QQ,群,空间等API接口代码分享

热门文章

  1. 【译】An Opinionated Introduction to AutoML and Neural Architecture Search
  2. Reversing Ethereum Smart Contracts: Part 2
  3. Android中取消系统标题栏的几种方式
  4. AndroidStudio gradle配置
  5. .net core 生成html,ASP.NET Core 中如何将 .cshtml 视图文件生成为 .cs 文件
  6. JZOJ 5938. 【NOIP2018模拟10.30】分离计划
  7. 电子信息科学与技术计算机科学与技术会计学,我是本三学生 学的电子信息科学与技术专业 今年大三 从没接触过会计 想考注册会计师 可以么 ?...
  8. 笔记本暗屏维修多少钱_电视机维修|维修电视机多少钱?电视机黑屏
  9. 【五校联考3day2】A
  10. JZOJ__Day 4:【普及模拟】游戏