资讯专栏INFORMATION COLUMN

从源码一步步学习,Ryan Dahl的Deno实现原理

goji / 1173人阅读

摘要:之父在中的设计错误演讲中表示不允许将任意本地函数绑定至当中。所有系统调用都将通过消息传递完成序列化。两项原生函数与。这既简化了设计流程,又使得系统更易于审计。

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


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

可以看出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.go

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

参考资料

Ryan Dahl 对 v8worker 的演讲PPT

justjavac: Deno 并不是下一代 Node.js

v8worker2 github

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/107953.html

相关文章

  • Deno 并不是下代 Node.js

    摘要:长文预警字,图。开发并不是因为,也不是为了取代。不知道从官方介绍来看,可以认为它是下一代是如何脑补出来的。只是一个原型或实验性产品。所以,不是要取代,也不是下一代,也不是要放弃重建生态。的目前是要拥抱浏览器生态。 这几天前端圈最火的事件莫过于 ry(Ryan Dahl) 的新项目 deno 了,很多 IT 新闻和媒体都用了标题:下一代 Node.js。这周末读了一遍 deno 的源码,...

    mmy123456 评论0 收藏0
  • 前端每周清单第 29 期:Web 现状分析与优化策略、Vue 单元测试、Headless Chrom

    摘要:前端每周清单第期现状分析与优化策略单元测试爬虫作者王下邀月熊编辑徐川前端每周清单专注前端领域内容,以对外文资料的搜集为主,帮助开发者了解一周前端热点分为新闻热点开发教程工程实践深度阅读开源项目巅峰人生等栏目。 showImg(https://segmentfault.com/img/remote/1460000011008022); 前端每周清单第 29 期:Web 现状分析与优化策略...

    HackerShell 评论0 收藏0
  • 快速学习nodejs系列:二、nodejs诞生

    摘要:简介的诞生学习一门技术之前,有必要了解该技术是如何诞生的是之父于年发布的。其在纽约罗切斯特大学数学系读博,研究一些分型分类的研究。年月,把项目定义为同年月,向外界宣布这个项目年底,在柏林的大会上进行的演讲,之后开始流行 nodejs简介 1.nodejs的诞生 学习一门技术之前,有必要了解该技术是如何诞生的? nodejs是ryan dahl(nodejs 之父)于2009年发布的。 ...

    tangr206 评论0 收藏0
  • 什么是Node.js

    Node.js从2009年诞生至今,已经发展了两年有余,其成长的速度有目共睹。从在github的访问量超过Rails,到去年底Node.jsS创始人Ryan Dalh加盟Joyent获得企业资助,再到今年发布Windows移植版本,Node.js的前景获得了技术社区的肯定。InfoQ一直在关注Node.js的发展,在今年的两次Qcon大会(北京站和杭州站)都有专门的讲座。为了更好地促进Node.j...

    CrazyCodes 评论0 收藏0
  • Node.js 是什么?我为什么选择它?

    摘要:单线程使用单线程来运行,而不是向之类的其它服务器,每个请求将生产一个线程,这种方法避免了上下文切换和内存中的大量执行堆栈,这也是和其它服务器为解决上一个年,著名的并发连接问题而采用的方法。 showImg(https://segmentfault.com/img/remote/1460000019968794?w=1080&h=675);当我们学习一项新的事物的时候,我们首先要知道它来...

    Joyven 评论0 收藏0

发表评论

0条评论

goji

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<