Deno 原理详解,让我们一起从源码分析开始 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
vtexhtllo1
V2EX    Node.js

Deno 原理详解,让我们一起从源码分析开始

  •  
  •   vtexhtllo1 2018-06-05 14:05:19 +08:00 5020 次点击
    这是一个创建于 2760 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

    deno 架构图(Parsa Ghadimi 绘制) 从图中可以清晰的看出,V8worker2 是 v8 和 Go 之间实现调用的核心组件

    v8worker2 架构图

    可以看出 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 之间的通信了:

    1. 创建一个实例:v8worker2.New(ReceiveMessageCallback)
    2. 加载执行 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 案例源码

    参考资料

    2 条回复    2018-06-06 16:58:09 +08:00
    nine99
        1
    nine99  
       2018-06-05 23:53:54 +08:00
    不错的资料
    jziwenchen
        2
    jziwenchen  
       2018-06-06 16:58:09 +08:00
    加了这么多东西 性能不会很差吗 ?
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     1017 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 26ms UTC 18:28 PVG 02:28 LAX 10:28 JFK 13:28
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86