1.9. v8 api

808 阅读2分钟

js的表现能力取决于宿主环境的api支持。所以同样是js语法,我们在chrome、node、hybrid app、electron桌面应用的场景不一样。 image.png

v8是什么

v8提供了可供外部调用的一系列的API:

  • Isolate:提供了一个v8虚拟机的实例
  • Context:提供了一个沙箱,也就是独立的上下文可以运行Isolate;Context中包了JavaScript内建函数、对象等;

v8对象的访问都是通过handle完成,handle持有对象的指针

  • Local<>是最常用的变量分配方式,一般是内部函数的对象。
  • v8通过HandleScope栈式管理内存,管理所有handle和Local,HandleScope被销毁,它们在下gc被收回
  • persistent 持久化handle或全局handle。

  • v8的数据类型基类是Data,所有js对象的基类是Value。

    • Primitive 基本类型
    • Object 引用类型
    • external:将c++对象包裹成js的变量,External::New返回一个handle<External>对象;
  • template :用js对象包裹c++函数和数据结构,就可以通过js访问c++函数和数据结构; function template。这是创建一个独立函数的模板。创建一个javascript的template实例,需要通过template的GetFunction方法。你也可以给这个function template关联一个回调函数。当javascript函数实例调用时,这个回调会被访问。

object template。每个function template都会有一个关联的object template。这是为关联创建该对象的函数。你可以为object template关联两个类型的回调:

-  accessor callbacks : 当脚本访问特定对象的属性时调用;
-  interceptor callbacks 当脚本访问任意对象属性时调用

node中使用v8点击

chrome官网中例子 使用v8

读入file.js文件并执行,注入一个全局变量value

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "include/libplatform/libplatform.h"
#include "include/v8.h"

using namespace std;
using namespace v8;

const std::string fileName = "file.js";
static int gValue = 10; // 初始化全局变量10

void GlobalValueGetter( Local<String> property, const PropertyCallbackInfo<Value>& info ) {
    info.GetReturnValue().Set( gValue );
}

void GlobalValueSetter( Local<String> property, Local<Value> value, const PropertyCallbackInfo<void>& info ) {
    gValue = value->Int32Value( info.GetIsolate()->GetCurrentContext() ).ToChecked();
}

// 读入一个js文件
MaybeLocal<String> ReadFile( Isolate* isolate, const string& name ) {
    FILE* file = fopen( name.c_str(), "rb" );
    if ( file == NULL ) return MaybeLocal<String>();

    fseek( file, 0, SEEK_END );
    size_t size = ftell( file );
    rewind( file );

    std::unique_ptr<char> chars( new char[size + 1] );
    chars.get()[size] = '\0';
    for ( size_t i = 0; i < size;) {
        i += fread( &chars.get()[i], 1, size - i, file );
        if ( ferror( file ) ) {
            fclose( file );
            return MaybeLocal<String>();
        }
    }
    fclose( file );
    MaybeLocal<String> result = String::NewFromUtf8(
        isolate, chars.get(), NewStringType::kNormal, static_cast<int>(size) );
    return result;
}

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();

    printf( "before gValue = %d\n", gValue );

    // 创建一个虚拟机并进入
    v8::Isolate::CreateParams create_params;
    create_params.array_buffer_allocator =
        v8::ArrayBuffer::Allocator::NewDefaultAllocator();
    v8::Isolate* isolate = v8::Isolate::New( create_params );
    {
        v8::Isolate::Scope isolate_scope( isolate );

        // 创建栈分配句柄
        v8::HandleScope handle_scope( isolate );
        // 创建全局变量
        v8::Local<v8::ObjectTemplate> global = v8::ObjectTemplate::New( isolate );
        global->SetAccessor( v8::String::NewFromUtf8( isolate, "value" ).ToLocalChecked()
            , GlobalValueGetter
            , GlobalValueSetter );

        // 创建执行环境
        v8::Local<v8::Context> context = v8::Context::New( isolate, nullptr, global );

        // 进入执行环境里面
        v8::Context::Scope context_scope( context );

        {
            //ReadFile读取js文件的代码
            v8::Local<v8::String> source;
            if ( !ReadFile( isolate, fileName ).ToLocal( &source ) ) {
                fprintf( stderr, "Error reading '%s'.\n", fileName.c_str() );
                return -1;
            }

            // 编译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 );
            printf( "after gValue = %d\n", gValue );
        }
    }

    // 关闭虚拟机和 V8.
    isolate->Dispose();
    v8::V8::Dispose();
    v8::V8::ShutdownPlatform();
    delete create_params.array_buffer_allocator;
    return 0;
}

//file.js

function add() {
    value += 1;
}

add();

参考: v8docs.nodesource.com/node-0.8/df…blog.csdn.net/lusing/arti…

欢迎关注我的前端自检清单,我和你一起成长