原本打算是把 node 源码看得差不多了再去深入 V8 的, 但是这两者基本上没办法分开讲.
与 express 是基于 node 的封装不同, node 是基于 V8 的一个应用, 源码内容已经渗透到 V8 层面, 因此这章简述一下我目前理解的 V8 引擎吧.
首先需要理解的是 V8 是一个 JS 代码运行平台, 可以将 JS 代码编译执行. 本节就非常浅显的讲一下 V8 运行 JS 代码的过程.
(由于研究 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/Hanlde
这个地方我之前一直比较混乱, 因为有文章指出: Handle 类定义在 v8.h 中, 它是一个模板类, 而且有两个派生类 Local 和 Persistent.
- #if !defined(V8_IMMINENT_DEPRECATION_WARNINGS)
- // Handle is an alias for Local for historical reasons.
- template <class T>
- using Handle = Local<T>;
- #endif
- Context::Scope context_scope(context);
- Script
- // 将 C++ 的 GetBinding 函数包装提供给 JS 代码调用
- // NewFunctionTemplate 是 v8::FunctionTemplate::New() 方法的包装
- v8::Local<v8::Function> get_binding_fn =
- env->NewFunctionTemplate(GetBinding)->GetFunction(env->context())
- .ToLocalChecked();
- // 创建一个 Isolate 实例
- Isolate::CreateParams params;
- Isolate* const isolate = Isolate::New(params);
- // 创建一个 HandleScope 管理 handle
- HandleScope handle_scope(isolate);
- // 创建一个上下文执行环境
- Local<Context> context = NewContext(isolate);
- // 切换到当前上下文
- Context::Scope context_scope(context);
- // 新建一个 Local
- // 类型可以类比 JS 的源字符串
- Local<String> source = String::New("'Hello' + ', World!'");
- // 编译该 JS 字符串
- Local<Script> script = Script::Compile(source);
- // 执行上面返回的编译对象
- Local<Value> result = script->Run();
- // 这个 result 就是对 JS 源字符串编译执行后的 C++ 代码
来源: https://www.cnblogs.com/QH-Jimmy/p/9212923.html