V8 Embedding - Hello World 讲解
发表于 2018-08-03
作者: 灼灼团队
本文字数: 2328
阅读时长 ≈ 7.8 分钟

通过一个 Hello World 示例来介绍 V8 的几个重要概念。

这个示例代码是基于 V8 (7.1) 的,要编译这个示例请查看 {% post_link v8/compile-v8 Javascript Engine V8 Embedding - 编译 %}

# 示例代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "include/libplatform/libplatform.h"
#include "include/v8.h"
int main(int argc, char* argv[]) {
  // 初始化 V8
  v8::V8::InitializeICUDefaultLocation(argv[0]);
  v8::V8::InitializeExternalStartupData(argv[0]);
  std::unique_ptr<v8::Platform> platform = v8::platform::NewDefaultPlatform();
  v8::V8::InitializePlatform(platform.get());
  v8::V8::Initialize();

  // 创建一个 Isolate 实例, 它代表一个 JS VM 实例
  v8::Isolate::CreateParams create_params;
  create_params.array_buffer_allocator =
      v8::ArrayBuffer::Allocator::NewDefaultAllocator();

  v8::Isolate* isolate = v8::Isolate::New(create_params);

  {
    // 使用 isolate
    v8::Isolate::Scope isolate_scope(isolate);

    // 创建一个 HandleScope,用于管理 Handle 的生命周期
    v8::HandleScope handle_scope(isolate);

    // 创建 Context,它是 javascript 代码执行的环境上下文对象
    v8::Local<v8::Context> context = v8::Context::New(isolate);

    // 进入 or 使用 context
    v8::Context::Scope context_scope(context);
    {
      // 定义 JS 代码字符串
      v8::Local<v8::String> source =
          v8::String::NewFromUtf8(isolate, "'Hello' + ', World!'",
                                  v8::NewStringType::kNormal).ToLocalChecked();
      // 编译 JS 代码
      v8::Local<v8::Script> script =
          v8::Script::Compile(context, source).ToLocalChecked();

      // 运行 JS 代码,并获取结果
      v8::Local<v8::Value> result = script->Run(context).ToLocalChecked();

      // 将运行结果转换为 UTF8 字符串,并打印
      v8::String::Utf8Value utf8(isolate, result);
      printf("%s\n", *utf8);
    }
  }

  // 释放 V8 相关资源
  isolate->Dispose();
  v8::V8::Dispose();
  v8::V8::ShutdownPlatform();
  delete create_params.array_buffer_allocator;
  return 0;
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58

# V8 重要概念

# Isolate

一个 Isolate 就是一个 VM 实例,它有自己独立的 Heap。

# Handle

一个 Handle 就是对一个 V8 object 的引用, V8 objects 都是分配在 Heap 中的,所有 V8 objects 都需要通过一个Handle 引用来访问,才能保证 V8 garbage collector 能工作。

Handle 又分 Local(局部) 和 Persistent(全局)两种。

Local Handle 的生命周期 使用 HandleScope 来管理,而 Persistent 是全局的 Handle, 需要通过 Persistent::New()Persistent::Release() 来创建和释放。

# Handle Scope

一个 Handle Scope 可以理解为用来批量管理 Handle 的容器,这样我们就不用一个个的去释放 Handle,只要把它们的 Handle Scope 释放掉就可以了。

Handle Scope 相当于提供了 Handle Stack 机制来管理 Handles,当一个 Handle Scope 本身被释放的时候,会从 Handle Stack 上弹出所有基于它的 Local Handles

注意:这个 Handle Stack 并不是 C++ 调用栈Handle Scope 是在 C++ 调用栈 中的分配的,Handle Scope 必须创建在栈上,不能用 new 创建!

{% img https://v8.dev/_img/docs/embed/local-persist-handles-review.png %}

# Context

Context 是 javascript 代码的执行环境;

想像一下,你有多个不相关的 js 代码要运行,这些代码运行的过程中可能会修改 V8 全局的一些状态,就需要给他们指定不同的 context 才能相互独立的隔离运行。

另外,我们可以为一个 context 设置预定义的全局属性,这个属性可以是 C++ 写的对象或方法,这样在 js 环境中,就能够调用 C++ 对象了,相当于扩充了 js 的能力。

比如,Node.js 中的 process 对象,就是一个预定义到 context 的对象,所以在 Node.js 中可以直接使用。同样的,浏览器中的 window document 等全局对象,也是预定义到 context 上的。

# 参考链接

Getting started with embedding V8: https://v8.dev/docs/embed#advanced-guide

联系我们
联系电话:17681177133
联系邮箱:admin@zhuo-zhuo.com
公司地址:合肥市高新区习友路2666号 (习友路和石莲南路交叉口西北角)二期304室
官网
博客
皖ICP备20009670号-2
合肥灼灼信息技术有限公司 | Copyright © 2020-present zhuo-zhuo.com