博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
V8 JavaScript引擎研究(四)在应用程序中使用V8
阅读量:4935 次
发布时间:2019-06-11

本文共 4221 字,大约阅读时间需要 14 分钟。

V8引擎在C++程序中使用简介

V8引擎可以被嵌入在任何C++程序中使用。

V8的APIs提供了对JavaScript代码的编译和执行功能、与C++函数互掉、访问数据结构、错误处理、及安全检查等功能。在应用程序中可将V8当做一个C++库来使用,访问V8的APIs需要包含V8的头文件v8.h。

使用V8非常简单,首先看一个简单示例程序:

#include 
#include
#include
#include "include/libplatform/libplatform.h"#include "include/v8.h"using namespace v8;class ArrayBufferAllocator : public v8::ArrayBuffer::Allocator { public: virtual void* Allocate(size_t length) { void* data = AllocateUninitialized(length); return data == NULL ? data : memset(data, 0, length); } virtual void* AllocateUninitialized(size_t length) { return malloc(length); } virtual void Free(void* data, size_t) { free(data); }};int main(int argc, char* argv[]) { // 初始化V8 V8::InitializeICU(); V8::InitializeExternalStartupData(argv[0]); Platform* platform = platform::CreateDefaultPlatform(); V8::InitializePlatform(platform); V8::Initialize(); // 创建一个新的Isolate ArrayBufferAllocator allocator; Isolate::CreateParams create_params; create_params.array_buffer_allocator = &allocator; Isolate* isolate = Isolate::New(create_params); { Isolate::Scope isolate_scope(isolate); // 创建一个分配在栈上的handle scope. HandleScope handle_scope(isolate); // 创建一个context. Local
context = Context::New(isolate); // 关联context Context::Scope context_scope(context); // 创建一个包含JavaScript代码的字符串 Local
source = String::NewFromUtf8(isolate, "'Hello' + ', World!'", NewStringType::kNormal).ToLocalChecked(); // 编译JavaScript代码 Local
  • 一个isolate代表一个堆上的虚拟机实例。
  • 一个handle是指向一个对象的指针,所有的V8对象都通过handle来访问,这是为了便于垃圾回收器工作。
  • 一个handle scope可以想象成是一系列handle的容器,当结束使用handle后,无需依次删除每个handle,可直接简单的删除scope即可。
  • 一个context代表一个执行环境上下文,允许单独的、无关的JavaScript代码运行在一个V8实例中。可以指定JavaScript代码运行在任何context中。

Handles简介

一个handle提供了一个对堆上对象地址的引用,V8垃圾回收器通过对释放不再使用的对象来达到回收内存的作用。在垃圾回收周期期间,对象的位置可能发生移动,当一个对象发生移动后,所有指向它的handle都会被更新。

Handle的分类

分配在栈上的局部handle

生命周期由其所在的handle scope决定,当handle scope被删除后,垃圾回收器将会回收其中的所有handle。这类handle典型使用在一个函数中。

可以像这样声明一个局部对象类:Local<Class>。

*注意:一个handle的栈不是C++调用栈的一部分,但handle scope是嵌入在C++调用栈中的。Handle scope只能通过栈内存来分配,不能使用new操作来分配。

分配在堆上的持久handle

当需要不仅是在局部保持对一个对象的引用时,使用堆handle。如在Chrome浏览器中,DOM节点都是使用堆handle。

可以像这样声明持久对象:Persistent<Class>。

Contexts简介

一个context代表一个执行环境上下文,允许单独的、无关的JavaScript代码运行在一个V8实例中。可以指定JavaScript代码运行在任何context中。

context机制的引入是非常必要的,JavaScript提供了非常多的内建函数和对象,由于这些函数和对象可以在JavaScript代码执行时被改变,因此如果不提供一个单独的执行环境context,将会产生许多问题。如两个完全不相关的函数都修改了同一个内建的对象。

每次创建一个context都需要创建一系列的内建对象,这将产生很大的消耗。V8使用了缓存机制来解决这一问题,当创建完第一个context后,后续再需创建context时,代价非常小。V8同时使用了snapshot机制(可通过命令 snapshot=yes开启,默认开启)来高度优化第一次创建context所带来的消耗。

当一个context被创建后,可以多次进出此context。例如,当在context A中时,进入了context B,此时当前的context更新为B,当退出B时,当前的context又被转回A,见下图所示:

 

在V8中使用context的绝佳实例是,每个浏览器中的每个iframe都使用一个单独的context。

Templates简介

Template被用来封装C++函数和对象来给JavaScript对象使用。例如,Chrome封装了C++中的DOM节点作为JavaScript对象。

Template分为函数template和对象template。

可以像下面这样的方式来使用template:

Local
global = ObjectTemplate::New(isolate);global->Set(String::NewFromUtf8(isolate, "log"), FunctionTemplate::New(isolate, LogCallback));

 

V8引擎的扩展和绑定

当JavaScript引擎所提供的能力不能满足业务需求时,如引擎本身对HTML5的支持程度不够,这时应用程序可以扩展V8引擎的能力。V8提供两种方式来扩展引擎:动态的扩展机制以及静态的绑定机制。

V8扩展

V8通过提供一个基类Extension和一个全局注册函数,来扩展JavaScript借口。

示例代码:

class MyExtension : public v8::Extension{  public:  virtual v8::Handle
GetNativeFunction(v8::Handle
name)  {    // 可根据name来返回不同的函数    return v8::FunctionTemplate::New(MyExtension::MyFunc);  }  static v8::Handle
MyFunc(const v8::Arguments& args)  {    // 自定义处理    return v8::Undefined();  }};MyExtension extension;RegisterExtension(&extension);

 

首先创建基于Extension基类的子类,然后实现GetNativeFunction。接着将子类的实例注册到V8引擎中,这样,当JavaScript代码中调用MyFunc时,就能执行自定义的MyFunc函数。

整个过程非常简单。

V8绑定

绑定的原理非常简单,即使用IDL文件或接口文件来生成绑定文件,然后将这些文件与V8引擎一起编译。

一个简单的IDL文件如下:

module mymodule {  interface [    InterfaceName=MyObject  ] MyObj {    readonly attribute long myAttr;    DOMString myMethod(DOMString myArg);  }}

 

完成好IDL文件后,可以使用WebKit的工具来通过将IDL文件转换成V8的绑定文件。V8的绑定文件即是标准的C++文件,包含了在IDL文件中定义的函数和对象。当绑定文件连同V8一起编译后,即可在JavaScript代码中直接使用自定义的函数和对象。

转载于:https://www.cnblogs.com/wolfx/p/5920141.html

你可能感兴趣的文章
4.27随笔
查看>>
CSS实例:图片导航块
查看>>
poj1860 Currency Exchange(spfa判断正环)
查看>>
SQL CHECK 约束&Case when 的使用方法
查看>>
[整理]HTTPS和SSL证书
查看>>
[转载] Android 异步加载图片,使用LruCache和SD卡或手机缓存,效果非常的流畅
查看>>
水晶苍蝇拍:聊聊估值那些事儿——“指标”背后的故事 (2011-11-01 14:58:32)
查看>>
3.每周总结
查看>>
应用提交 App Store 上架被拒绝
查看>>
Android实现异步处理 -- HTTP请求
查看>>
数据清空js清空div里的数据问题
查看>>
Fortran中的指针使用
查看>>
移动终端app测试点总结
查看>>
14-6-27&28自学内容小结
查看>>
JSP
查看>>
---
查看>>
(第一组_GNS3)自反ACl
查看>>
hdu--1258--Sum It Up(Map水过)
查看>>
Spring @DeclareParents 的扩展应用实例
查看>>
VS2012更新Update1后帮助查看器无法打开
查看>>