新聞中心
前言:閱讀Node.js的源碼已經(jīng)有一段時間了,最近也看了一下新的JS運行時Just的一些實現(xiàn),就產(chǎn)生了自己寫一個JS運行時的想法,雖然幾個月前就基于V8寫了一個簡單的JS運行時,但功能比較簡單,這次廢棄了之前的代碼,重新寫了一遍,寫這個JS運行時的目的最主要是為了學(xué)習(xí),事實也證明,寫一個JS運行時的確可以學(xué)到很多東西。本文介紹運行時No.js的一些設(shè)計和實現(xiàn),取名No.js一來是受Node.js的影響,二來是為了說明不僅僅是JS,也就是利用V8拓展了JS的功能,同時,前端開發(fā)者要學(xué)習(xí)的知識也不僅僅是JS了。

1 為什么選io_uring
io_uring是Linux下新一代的高性能異步IO框架,也是No.js的核心。在No.js中,io_uring用于實現(xiàn)事件循環(huán)。為什么不選用epoll呢?因為epoll不支持文件IO,如果選用epoll,還需要自己實現(xiàn)一個線程池,還需要實現(xiàn)線程和主線程的通信,以及線程池任務(wù)和事件循環(huán)的融合,No.js希望把事件變得純粹,簡單。而io_uring是支持異步文件IO的,并且io_uring是真正的異步IO框架,支持的功能也非常豐富,比如在epoll里我們監(jiān)聽一個socket后,需要把socket fd注冊到epoll中,等待有連接時執(zhí)行回調(diào),然后調(diào)用accept獲取新的fd,而io_uring直接就幫我們獲取新的fd,io_uring通知我們的時候,我們就已經(jīng)拿到新的fd了,epoll時代,epoll通知我們可以做什么事情了,然后我們自己去做,io_uring時代,io_uring通知我們什么事情完成了。
2 No.js框架的設(shè)計
No.js目前的實現(xiàn)比較清晰簡單,所有的功能都通過c和c++實現(xiàn),然后通過V8暴露給JS實現(xiàn)。No.cc是初始化的入口,core目錄是所有功能實現(xiàn)的地方,core下面按照模塊功能劃分。下面我們看看整體的框架實現(xiàn)。
- int main(int argc, char* argv[]) {
- // ...
- Isolate* isolate = Isolate::New(create_params);
- {
- Isolate::Scope isolate_scope(isolate);
- HandleScope handle_scope(isolate);
- // 創(chuàng)建全局對象
- Local
global = ObjectTemplate::New(isolate); - // 創(chuàng)建執(zhí)行上下文
- Local
context = Context::New(isolate, nullptr, global); - Environment * env = new Environment(context);
- Context::Scope context_scope(context);
- // 創(chuàng)建No,核心對象
- Local
- // 注冊c、c++模塊
- register_builtins(isolate, No);
- // 獲取全局對象
- Local
- // 設(shè)置全局屬性
- globalInstance->Set(context, String::NewFromUtf8Literal(isolate, "No",
- NewStringType::kNormal), No);
- // 設(shè)置全局屬性global指向全局對象
- globalInstance->Set(context, String::NewFromUtf8Literal(isolate,
- "global",
- NewStringType::kNormal), globalInstance).Check();
- {
- // 打開文件
- int fd = open(argv[1], O_RDONLY);
- struct stat info;
- // 取得文件信息
- fstat(fd, &info);
- // 分配內(nèi)存保存文件內(nèi)容
- char *ptr = (char *)malloc(info.st_size + 1);
- read(fd, (void *)ptr, info.st_size);
- // 要執(zhí)行的js代碼
- Local
source = String::NewFromUtf8(isolate, ptr, - NewStringType::kNormal,
- info.st_size).ToLocalChecked();
- // 編譯
- Local


咨詢
建站咨詢