日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

深入出不来nodejs源码-V8引擎初探

發布時間:2025/3/14 编程问答 18 豆豆
生活随笔 收集整理的這篇文章主要介紹了 深入出不来nodejs源码-V8引擎初探 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

  原本打算是把node源碼看得差不多了再去深入V8的,但是這兩者基本上沒辦法分開講。

  與express是基于node的封裝不同,node是基于V8的一個應用,源碼內容已經滲透到V8層面,因此這章簡述一下我目前理解的V8引擎吧。

  首先需要理解的是V8是一個JS代碼運行平臺,可以將JS代碼編譯執行。

  本節就非常淺顯的講一下V8內部一些常見類,以及一個運行JS代碼的簡單demo。

  (由于研究V8引擎原理的人非常多,本人學識淺薄,可以去參考別人的博客)

參考資料:

  1、很多大佬的博客

  2、V8引擎API文檔:https://v8docs.nodesource.com/

  3、github:https://github.com/v8/v8

  

  本節先列舉一些核心類,示例代碼大部分來源于node中的源碼。

Isolate

  該類代表一個V8引擎實例,有自己獨立的狀態,用法如下。

1、不能使用new關鍵字來生成一個實例,只能通過類方法Isolate::New(params)來創建。

Isolate* const isolate = Isolate::New(params);

2、該類的方法都是設置V8引擎的一些處理細節。

// 添加error的信息監聽器 isolate->AddMessageListener(OnMessage); // 從名字能看出來 設置未捕捉中斷異常的回調函數 isolate->SetAbortOnUncaughtExceptionCallback(ShouldAbortOnUncaughtException); // 設置Microtask的執行方式(有三種) isolate->SetMicrotasksPolicy(v8::MicrotasksPolicy::kExplicit); // 設置致命錯誤的回調函數 isolate->SetFatalErrorHandler(OnFatalError); // WebAssembly代碼生成回調函數 isolate->SetAllowWasmCodeGenerationCallback(AllowWasmCodeGenerationCallback);

3、作為一個參數傳入其余的V8工具類中。

// 單線程運行V8的Isolate Locker locker(isolate); Isolate::Scope isolate_scope(isolate);

?

Local/Persistent - Handle

  這個地方我之前一直比較混亂,因為有文章指出:Handle類定義在v8.h中,它是一個模板類,而且有兩個派生類Local和Persistent。

  出處:https://blog.csdn.net/sunbxonline/article/details/20310897

  但是從源碼來看,無論是Local<T>還是MaybeLocal<T>,均不繼承于任何類(在V8中確實存在一個Handle的類,但是跟這兩個沒有繼承關系)。

  這是因為V8版本不一致,所以我這里只講當前版本的情況,源碼注釋如下:

#if !defined(V8_IMMINENT_DEPRECATION_WARNINGS) // Handle is an alias for Local for historical reasons. template <class T> using Handle = Local<T>; #endif

  這兩個類從作用上講都是handle,但實際上并不繼承于同一個父類。

1、Local/Persistent是V8的兩個類,指向底層的原始數據。

2、所有對象的引用都需要被V8的垃圾回收管理,在管理中可能出現移動對象的情況(參考網上大量關于V8垃圾回收的博客),這會導致對象指針產生錯誤,所以不能直接使用原始的數據類型,諸如String,而需要使用Local<String>,Local被V8引擎管理,會在對象移動時更新指針指向,并在合適的時候進行回收。

3、Persistent屬于全局對象(可參考Global),獨立于HanldeScope,可使用Reset方法清空。

?

Value

  所以JS數據類型映射到C++的根類,繼承關系如下:

  具體的內部實現后面做分析。?

?

HandleScope

?  一個管理handle的容器,在當前作用域開頭聲明一個HanldeScope,在域結束時會自動清理所有的handle。

HandleScope handle_scope(isolate);

  嵌套使用時,作用域會自動進行切換。

?

Context

  執行上下文,有自己獨立的函數與對象。與Isolate相似,通過類方法New來生成。

auto context = Context::New(isolate, nullptr, object_template);

  可通過內部Scope類來進行上下文的切換。

Context::Scope context_scope(context);

?

Script

  該類主要負責對JS代碼字符串進行編譯和執行,核心方法為Compile、Run。

  Script::Compile可以編譯JS代碼字符串,返回一個Local<Script>對象

  Script::Run可以執行編譯后的JS代碼,返回一個Handle<Value>對象

?

  另外,還有FunctionTemplate/ObjectTemplate可以封裝C++的對象、函數提供給JS代碼調用,示例代碼如下:

// 將C++的GetBinding函數包裝提供給JS代碼調用 // NewFunctionTemplate是v8::FunctionTemplate::New()方法的包裝 v8::Local<v8::Function> get_binding_fn = env->NewFunctionTemplate(GetBinding)->GetFunction(env->context()) .ToLocalChecked();

?

  基本上大部分用到的東西就是上面所列舉的,GC暫時不討論,以一個非常簡單的網上案例把上面的東西串起來:

// 創建一個Isolate實例 Isolate::CreateParams params; Isolate* const isolate = Isolate::New(params); // 創建一個HandleScope管理handle HandleScope handle_scope(isolate); // 創建一個上下文執行環境 Local<Context> context = Context::New(isolate); // 切換到當前上下文 Context::Scope context_scope(context); // 新建一個Local // 類型可以類比JS的源字符串 Local<String> source = v8::String::NewFromOneByte(isolate , "12345"); // 編譯該JS字符串 MaybeLocal<v8::Script> script = v8::Script::Compile(context , source); // 執行上面返回的編譯對象 Local<Value> result = script.ToLocalChecked()->Run(context).ToLocalChecked(); // 這個result就是對JS源字符串編譯執行后的C++代碼 Local<String> str = result->ToString(context ).ToLocalChecked();

  這樣,對V8引擎就有了一個基本的認識,可以幫助我們更好的學習nodejs源碼。

轉載于:https://www.cnblogs.com/QH-Jimmy/p/9212923.html

總結

以上是生活随笔為你收集整理的深入出不来nodejs源码-V8引擎初探的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。