c语言中double deno是什么意思,Deno原理详解,让我们一起从源码分析开始

Node之父ry:在“Node中的设计错误”演讲中表示:

不允许将任意本地函数绑定至 V8 当中。

所有系统调用都将通过消息传递完成(protobuf 序列化)。

两项原生函数:send 与 recv。

这既简化了设计流程,又使得系统更易于审计。

这几点很大程度上体现出了node和deno在设计本质上的区别,同时这几点体现了deno的安全性(利用 JavaScript 本身即为安全沙箱这一事实)

V8worker2是Go和V8连接的桥梁

允许从GO程序执行JavaScript

只允许GO和V8之间的消息传递(传统:暴露C++函数作为函数在JavaScript。)

维护一个安全的JS沙箱

JS中只允许绑定3个函数:send(), recv(), print()

0cc8ac53a6cef7869dc9cea6c8c24828.png

从图中可以清晰的看出,V8worker2是v8和Go之间实现调用的核心组件

8ca12aa25858f44808ed1b187f7cb800.png

可以看出V8worker2 是通过binding C++ 模块进行绑定V8,bingding暴露了基础操作方法:v8_init() 、worker_load()、worker_send_bytes()、worker_dispose()...提供给GO 进行调用

//binding.h

const char* worker_version();

void worker_set_flags(int* argc, char** argv);

void v8_init();

worker* worker_new(int table_index);

int worker_load(worker* w, char* name_s, char* source_s);

const char* worker_last_exception(worker* w);

int worker_send_bytes(worker* w, void* data, size_t len);

void worker_dispose(worker* w);

void worker_terminate_execution(worker* w);

复制代码

通过Golang的GC提供的CGO模块调用C语言暴露的方法,就可以实现GO和V8之间的通信了:

创建一个实例:v8worker2.New(ReceiveMessageCallback)

加载执行JS: worker.Load(scriptName,codeString)

// worker.go

package v8worker2

import "C"

...

func recvCb(buf unsafe.Pointer, buflen C.int, index workerTableIndex) C.buf {

...

}

func New(cb ReceiveMessageCallback) *Worker {

...

initV8Once.Do(func() {

C.v8_init()

})

}

func (w *Worker) Load(scriptName string, code string) error {

...

r := C.worker_load(w.worker.cWorker, scriptName_s, code_s)

...

}

func (w *Worker) SendBytes(msg []byte) error {

...

r := C.worker_send_bytes(w.worker.cWorker, msg_p, C.size_t(len(msg)))

}

复制代码

案例演示

实现Js中的console.log() 方法

Js发送数据给Go

Go发送数据给Js

// hello.go

package main

import (

"fmt"

"github.com/ry/v8worker2"

)

func main() {

worker := v8worker2.New(recv)

// 实现JS的console.log 方法

err := worker.Load("hello.js", `

this["console"] = {

log(...args) {

V8Worker2.print(args)

}

};

console.log("Hello World");

`)

if err != nil {

fmt.Println(err)

}

// 发送数据给GO

err = worker.Load("sendData.js", `

V8Worker2.send(new ArrayBuffer(5))

`)

if err != nil {

fmt.Println(err)

}

// 发送数据给JS

err = worker.Load("recvData.js", `

V8Worker2.recv(function(msg) {

const len =msg.byteLength;

console.log("recv data from go,length: "+len);

});

`)

if err != nil {

fmt.Println(err)

}

err = worker.SendBytes([]byte("abcd"))

}

func recv(buf []byte) []byte {

fmt.Println("recv data from js,length:", len(buf))

return nil

}

复制代码

在控制台运行: go run hello.goe5051ca0cc775f802a401e86f58eca20.png

需要运行测试代码,可以直接访问我的github :deno 案例源码

参考资料

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值