日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當前位置:首頁 > 科技  > 軟件

跨端輕量JavaScript引擎的實現與探索

來源: 責編: 時間:2024-03-18 09:42:06 259觀看
導讀一、JavaScript1.JavaScript語言JavaScript是ECMAScript的實現,由ECMA 39(歐洲計算機制造商協會39號技術委員會)負責制定ECMAScript標準。ECMAScript發展史:時間版本說明1997年7月ES1.0 發布當年7月,ECMA262 標準出臺1

一、JavaScript

1.JavaScript語言

JavaScript是ECMAScript的實現,由ECMA 39(歐洲計算機制造商協會39號技術委員會)負責制定ECMAScript標準。Kx128資訊網——每日最新資訊28at.com

ECMAScript發展史:Kx128資訊網——每日最新資訊28at.com

時間Kx128資訊網——每日最新資訊28at.com

版本Kx128資訊網——每日最新資訊28at.com

說明Kx128資訊網——每日最新資訊28at.com

1997年7月Kx128資訊網——每日最新資訊28at.com

ES1.0 發布Kx128資訊網——每日最新資訊28at.com

當年7月,ECMA262 標準出臺Kx128資訊網——每日最新資訊28at.com

1998年6月Kx128資訊網——每日最新資訊28at.com

ES2.0 發布Kx128資訊網——每日最新資訊28at.com

該版本修改完全符合ISO/IEC 16262國際標準。Kx128資訊網——每日最新資訊28at.com

1999年12月Kx128資訊網——每日最新資訊28at.com

ES3.0 發布Kx128資訊網——每日最新資訊28at.com

成為 JavaScript 的通行標準,得到了廣泛支持Kx128資訊網——每日最新資訊28at.com

2007年10月Kx128資訊網——每日最新資訊28at.com

ES4.0草案發布Kx128資訊網——每日最新資訊28at.com

各大廠商意見分歧,該方案未通過Kx128資訊網——每日最新資訊28at.com

2008年7月Kx128資訊網——每日最新資訊28at.com

發布ES3.1,并改名為ECMAScript 5Kx128資訊網——每日最新資訊28at.com

廢除ECMAScript 4.0,所以4.0版本不存在Kx128資訊網——每日最新資訊28at.com

2009年12月Kx128資訊網——每日最新資訊28at.com

ESt 5.0 正式發布Kx128資訊網——每日最新資訊28at.com


Kx128資訊網——每日最新資訊28at.com

2011年6月Kx128資訊網——每日最新資訊28at.com

ES5.1 發布Kx128資訊網——每日最新資訊28at.com

該版本成為了 ISO 國際標準(ISO/IEC 16262:2011)Kx128資訊網——每日最新資訊28at.com

2013年12月Kx128資訊網——每日最新資訊28at.com

ES6 草案發布Kx128資訊網——每日最新資訊28at.com


Kx128資訊網——每日最新資訊28at.com

2015年6月Kx128資訊網——每日最新資訊28at.com

ES6 正式發布,并且更名為“ECMAScript 2015”Kx128資訊網——每日最新資訊28at.com

TC39委員會決定每年發布一個ECMAScript 的版本Kx128資訊網——每日最新資訊28at.com

2.JavaScript引擎

JavaScript引擎是指用于處理以及執行JavaScript腳本的虛擬機。Kx128資訊網——每日最新資訊28at.com

常見的JavaScript引擎:Kx128資訊網——每日最新資訊28at.com

Kx128資訊網——每日最新資訊28at.com

引擎Kx128資訊網——每日最新資訊28at.com

所屬機構/個人Kx128資訊網——每日最新資訊28at.com

瀏覽器Kx128資訊網——每日最新資訊28at.com

說明Kx128資訊網——每日最新資訊28at.com

SpiderMonkeyKx128資訊網——每日最新資訊28at.com

MozillaKx128資訊網——每日最新資訊28at.com

FirefoxKx128資訊網——每日最新資訊28at.com

第一款JavaScript引擎,早期用于 Netscape Navigator,現時用于 Mozilla Firefox。是用C語言實現的,還有一個Java版本叫Rhino;Rhino引擎由Mozilla基金會管理,開放源代碼,完全以Java編寫,用于 HTMLUnit;而后TraceMonkey引擎是基于實時編譯的引擎,用于Mozilla Firefox 3.5~3.6版本;JaegerMonkey:結合追蹤和組合碼技術大幅提高性能,用于Mozilla Firefox 4.0以上版本Kx128資訊網——每日最新資訊28at.com

JavaScriptCoreKx128資訊網——每日最新資訊28at.com

AppleKx128資訊網——每日最新資訊28at.com

SafariKx128資訊網——每日最新資訊28at.com

簡稱JSC,開源,用于webkit內核瀏覽器,如 Safari ,2008 年實現了編譯器和字節碼解釋器,升級為了SquirrelFish。蘋果內部代號為Nitro的 JavaScript 引擎也是基于 JSC引擎的。至于具體時間,JSC是WebKit默認內嵌的JS引擎,而WebKit誕生于1998年,Nitro是為Safari 4編寫,Safari 4是2009年6月發布。Kx128資訊網——每日最新資訊28at.com

V8Kx128資訊網——每日最新資訊28at.com

GoogleKx128資訊網——每日最新資訊28at.com

ChromeKx128資訊網——每日最新資訊28at.com

2008年9月,Google的V8引擎第一個版本隨著Chrome的第一個版本發布。V8引擎用 C++編寫,由 Google 丹麥開發,開源。除了Chrome,還被運用于Node.js以及運用于Android操作系統等Kx128資訊網——每日最新資訊28at.com

ChakraKx128資訊網——每日最新資訊28at.com

MicrosoftKx128資訊網——每日最新資訊28at.com

Edge、IEKx128資訊網——每日最新資訊28at.com

譯名查克拉,用于IE9、10、11和Microsoft Edge,IE9發布時間2011年3月Kx128資訊網——每日最新資訊28at.com

JerryScriptKx128資訊網——每日最新資訊28at.com

三星Kx128資訊網——每日最新資訊28at.com


Kx128資訊網——每日最新資訊28at.com

三星推出的適用于嵌入式設備的小型 JavaScript 引擎,2015年開源Kx128資訊網——每日最新資訊28at.com

NashornKx128資訊網——每日最新資訊28at.com

OracaleKx128資訊網——每日最新資訊28at.com


Kx128資訊網——每日最新資訊28at.com

從 JDK 1.8 開始,Nashorn取代Rhino(JDK 1.6, JDK1.7) 成為 Java 的嵌入式 JavaScript 引擎,JDK1.8發布于2014年Kx128資訊網——每日最新資訊28at.com

QuickJSKx128資訊網——每日最新資訊28at.com

Fabrice BellardKx128資訊網——每日最新資訊28at.com


Kx128資訊網——每日最新資訊28at.com

QuickJS 是一個小型的嵌入式 Javascript 引擎。 它支持 ES2023 規范,包括模塊、異步生成器、代理和 BigInt。 它可以選擇支持數學擴展,例如大十進制浮點數 (BigDecimal)、大二進制浮點數 (BigFloat) 和運算符重載。Kx128資訊網——每日最新資訊28at.com

HermesKx128資訊網——每日最新資訊28at.com

FacebookKx128資訊網——每日最新資訊28at.com


Kx128資訊網——每日最新資訊28at.com

引擎,Facebook在Chain React 2019 大會上發布的一個嶄新JavaScript引擎,用于移動端React Native應用的集成,開源Kx128資訊網——每日最新資訊28at.com

3.JavaScript引擎工作原理

a.V8引擎工作原理

Kx128資訊網——每日最新資訊28at.com

b.Turbofan技術實例說明

function sum(a, b) {    return a + b;}

這里a和b可以是任意類型數據,當執行sum函數時,Ignition解釋器會檢查a和b的數據類型,并相應地執行加法或者連接字符串的操作。Kx128資訊網——每日最新資訊28at.com

如果 sum函數被調用多次,每次執行時都要檢查參數的數據類型是很浪費時間的。此時TurboFan就出場了。它會分析函數的執行信息,如果以前每次調用sum函數時傳遞的參數類型都是數字,那么TurboFan就預設sum的參數類型是數字類型,然后將其編譯為機器碼。Kx128資訊網——每日最新資訊28at.com

但是如果某一次的調用傳入的參數不再是數字時,表示TurboFan的假設是錯誤的,此時優化編譯生成的機器代碼就不能再使用了,于是就需要進行回退到字節碼的操作。Kx128資訊網——每日最新資訊28at.com

三、QuickJS

1.QuickJS作者簡介

法布里斯·貝拉 (Fabrice Bellard)Kx128資訊網——每日最新資訊28at.com

Kx128資訊網——每日最新資訊28at.com

Kx128資訊網——每日最新資訊28at.com

2.QuickJS簡介

QuickJS 是一個小型的嵌入式 Javascript 引擎。 它支持 ES2023 規范,包括模塊、異步生成器、代理和 BigInt。Kx128資訊網——每日最新資訊28at.com

它可以選擇支持數學擴展,例如大十進制浮點數 (BigDecimal)、大二進制浮點數 (BigFloat) 和運算符重載。Kx128資訊網——每日最新資訊28at.com

?小且易于嵌入:只需幾個 C 文件,無外部依賴項,一個簡單的 hello world 程序的 210 KiB x86 代碼。Kx128資訊網——每日最新資訊28at.com

?啟動時間極短的快速解釋器:在臺式 PC 的單核上運行 ECMAScript 測試套件的 76000 次測試只需不到 2 分鐘。 運行時實例的完整生命周期在不到 300 微秒的時間內完成。Kx128資訊網——每日最新資訊28at.com

?幾乎完整的 ES2023 支持,包括模塊、異步生成器和完整的附錄 B 支持(舊版 Web 兼容性)。Kx128資訊網——每日最新資訊28at.com

?通過了近 100% 的 ECMAScript 測試套件測試: Test262 Report(https://test262.fyi/#)。Kx128資訊網——每日最新資訊28at.com

?可以將 Javascript 源代碼編譯為可執行文件,無需外部依賴。Kx128資訊網——每日最新資訊28at.com

?使用引用計數(以減少內存使用并具有確定性行為)和循環刪除的垃圾收集。Kx128資訊網——每日最新資訊28at.com

?數學擴展:BigDecimal、BigFloat、運算符重載、bigint 模式、數學模式。Kx128資訊網——每日最新資訊28at.com

?用 Javascript 實現的帶有上下文著色的命令行解釋器。Kx128資訊網——每日最新資訊28at.com

?帶有 C 庫包裝器的小型內置標準庫。Kx128資訊網——每日最新資訊28at.com

3.QuickJS工程簡介

5.94MB quickjs├── 17.6kB      cutils.c                /// 輔助函數├── 7.58kB      cutils.h                /// 輔助函數├── 241kB       libbf.c                 /// BigFloat相關├── 17.9kB      libbf.h                 /// BigFloat相關├── 2.25kB      libregexp-opcode.h      /// 正則表達式操作符├── 82.3kB      libregexp.c             /// 正則表達式相關├── 3.26kB      libregexp.h             /// 正則表達式相關├── 3.09kB      list.h                  /// 鏈表實現├── 16.7kB      qjs.c                   /// QuickJS stand alone interpreter├── 22kB        qjsc.c                  /// QuickJS command line compiler├── 73.1kB      qjscalc.js              /// 數學計算器├── 7.97kB      quickjs-atom.h          /// 定義了javascript中的關鍵字├── 114kB       quickjs-libc.c├── 2.57kB      quickjs-libc.h          /// C API├── 15.9kB      quickjs-opcode.h        /// 字節碼操作符定義├── 1.81MB      quickjs.c               ├── 41.9kB      quickjs.h               /// QuickJS Engine├── 49.8kB      repl.js                 /// REPL├── 218kB       libunicode-table.h      /// unicode相關├── 53kB        libunicode.c            /// unicode相關├── 3.86kB      libunicode.h            /// unicode相關├── 86.4kB      unicode_gen.c           /// unicode相關└── 6.99kB      unicode_gen_def.h       /// unicode相關

4.QuickJS工作原理

QuickJS的解釋器是基于棧的。Kx128資訊網——每日最新資訊28at.com

Kx128資訊網——每日最新資訊28at.com

QuickJS的對byte-code會優化兩次,通過一個簡單例子看看QuickJS的字節碼與優化器的輸出,以及執行過程。Kx128資訊網——每日最新資訊28at.com

function sum(a, b) {    return a + b;}

?第一階段(未經過優化的字節碼)Kx128資訊網——每日最新資訊28at.com

;; function sum(a, b) {        enter_scope 1    ;;     return a + b;        line_num 2        scope_get_var a,1    ///通用的獲取變量的指令        scope_get_var b,1            add        return;; }

?第二階段Kx128資訊網——每日最新資訊28at.com

;; function sum(a, b) {;;     return a + b;        line_num 2        get_arg 0: a        /// 獲取參數列表中的變量        get_arg 1: b        add        return;; }

?第三階段Kx128資訊網——每日最新資訊28at.com

;; function sum(a, b) {;;     return a + b;        get_arg0 0: a        /// 精簡成獲取參數列表中第0個參數        get_arg1 1: b        add        return;; }
sum(1,2);

通過上述簡單的函數調用,觀察sum函數調用過程中棧幀的變化,通過計算可知sum函數最棧幀大小為兩個字節Kx128資訊網——每日最新資訊28at.com

get_arg0Kx128資訊網——每日最新資訊28at.com

get_arg1Kx128資訊網——每日最新資訊28at.com

addKx128資訊網——每日最新資訊28at.com

returnKx128資訊網——每日最新資訊28at.com

1Kx128資訊網——每日最新資訊28at.com

2Kx128資訊網——每日最新資訊28at.com

3Kx128資訊網——每日最新資訊28at.com

將棧頂的數據3返回Kx128資訊網——每日最新資訊28at.com


Kx128資訊網——每日最新資訊28at.com

1Kx128資訊網——每日最新資訊28at.com


Kx128資訊網——每日最新資訊28at.com


Kx128資訊網——每日最新資訊28at.com

5.內存管理

QuickJS通過引用計算來管理內存,在使用C API時需要根據不同API的說明手動增加或者減少引用計數器。Kx128資訊網——每日最新資訊28at.com

對于循環引用的對象,QuickJS通過臨時減引用保存到臨時數組中的方法來判斷相互引用的對象是否可以回收。Kx128資訊網——每日最新資訊28at.com

6.QuickJS簡單使用

從github上clone完最新的源碼后,通過執行(macos 環境)以下代碼即可在本地安裝好qjs、qjsc、qjscalc幾個命令行程序Kx128資訊網——每日最新資訊28at.com

sudo makesudo make install

?qjs: JavaScript代碼解釋器Kx128資訊網——每日最新資訊28at.com

?qjsc: JavaScript代碼編譯器Kx128資訊網——每日最新資訊28at.com

?qjscalc: 基于QuickJS的REPL計算器程序Kx128資訊網——每日最新資訊28at.com

通過使用qjs可以直接運行一個JavaScript源碼,通過qsjc的如下命令,則可以輸出一個帶有byte-code源碼的可直接運行的C源文件:Kx128資訊網——每日最新資訊28at.com

qjsc -e  -o add.c examples/add.js
#include "quickjs-libc.h"const uint32_t qjsc_add_size = 135;const uint8_t qjsc_add[135] = { 0x02, 0x06, 0x06, 0x73, 0x75, 0x6d, 0x0e, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x06, 0x6c, 0x6f, 0x67, 0x1e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x2f, 0x61, 0x64, 0x64, 0x2e, 0x6a, 0x73, 0x02, 0x61, 0x02, 0x62, 0x0e, 0x00, 0x06, 0x00, 0xa2, 0x01, 0x00, 0x01, 0x00, 0x05, 0x00, 0x01, 0x25, 0x01, 0xa4, 0x01, 0x00, 0x00, 0x00, 0x3f, 0xe3, 0x00, 0x00, 0x00, 0x40, 0xc2, 0x00, 0x40, 0xe3, 0x00, 0x00, 0x00, 0x00, 0x38, 0xe4, 0x00, 0x00, 0x00, 0x42, 0xe5, 0x00, 0x00, 0x00, 0x38, 0xe3, 0x00, 0x00, 0x00, 0xb8, 0xb9, 0xf2, 0x24, 0x01, 0x00, 0xcf, 0x28, 0xcc, 0x03, 0x01, 0x04, 0x1f, 0x00, 0x08, 0x0a, 0x0e, 0x43, 0x06, 0x00, 0xc6, 0x03, 0x02, 0x00, 0x02, 0x02, 0x00, 0x00, 0x04, 0x02, 0xce, 0x03, 0x00, 0x01, 0x00, 0xd0, 0x03, 0x00, 0x01, 0x00, 0xd3, 0xd4, 0x9e, 0x28, 0xcc, 0x03, 0x01, 0x01, 0x03,};static JSContext *JS_NewCustomContext(JSRuntime *rt){  JSContext *ctx = JS_NewContextRaw(rt);  if (!ctx)    return NULL;  JS_AddIntrinsicBaseObjects(ctx);  JS_AddIntrinsicDate(ctx);  JS_AddIntrinsicEval(ctx);  JS_AddIntrinsicStringNormalize(ctx);  JS_AddIntrinsicRegExp(ctx);  JS_AddIntrinsicJSON(ctx);  JS_AddIntrinsicProxy(ctx);  JS_AddIntrinsicMapSet(ctx);  JS_AddIntrinsicTypedArrays(ctx);  JS_AddIntrinsicPromise(ctx);  JS_AddIntrinsicBigInt(ctx);  return ctx;}int main(int argc, char **argv){  JSRuntime *rt;  JSContext *ctx;  rt = JS_NewRuntime();  js_std_set_worker_new_context_func(JS_NewCustomContext);  js_std_init_handlers(rt);  JS_SetModuleLoaderFunc(rt, NULL, js_module_loader, NULL);  ctx = JS_NewCustomContext(rt);  js_std_add_helpers(ctx, argc, argv);  js_std_eval_binary(ctx, qjsc_add, qjsc_add_size, 0);  js_std_loop(ctx);  js_std_free_handlers(rt);  JS_FreeContext(ctx);  JS_FreeRuntime(rt);  return 0;}

上面的這個C源文件,通過如下命令即可編譯成可執行文件:Kx128資訊網——每日最新資訊28at.com

gcc add.c -o add_exec -I/usr/local/include quickjs-libc.c quickjs.c cutils.c libbf.c libregexp.c libunicode.c  -DCONFIG_BIGNUM

也可以直接使用如下命令,將JavaScript文件直接編譯成可執行文件:Kx128資訊網——每日最新資訊28at.com

qjsc -o add_exec examples/add.js

7.給qjsc添加擴展

QuickJS只實現了最基本的JavaScript能力,同時QuickJS也可以實現能力的擴展,比如給QuickJS添加打開文件并讀取文件內容的內容,這樣在JavaScript代碼中即可通過js代碼打開并讀取到文件內容了。Kx128資訊網——每日最新資訊28at.com

通過一個例子來看看添加擴展都需要做哪些操作:Kx128資訊網——每日最新資訊28at.com

?編寫一個C語言的擴展模塊Kx128資訊網——每日最新資訊28at.com

#include "quickjs.h"#include "cutils.h"http:/// js中對應plus函數的C語言函數static JSValue plusNumbers(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {    int a, b;    if (JS_ToInt32(ctx, &a, argv[0]))        return JS_EXCEPTION;    if (JS_ToInt32(ctx, &b, argv[1]))        return JS_EXCEPTION;    return JS_NewInt32(ctx, a + b);}/// 模塊需要導致的列表static const JSCFunctionListEntry js_my_module_funcs[] = {    JS_CFUNC_DEF("plus", 2, plusNumbers),};/// 模塊初始化函數,并將plus導出static int js_my_module_init(JSContext *ctx, JSModuleDef *m) {    return JS_SetModuleExportList(ctx, m, js_my_module_funcs, countof(js_my_module_funcs));}JSModuleDef *js_init_module_my_module(JSContext *ctx, const char *module_name) {    JSModuleDef *m;    m = JS_NewCModule(ctx, module_name, js_my_module_init);    if (!m)        return NULL;    JS_AddModuleExportList(ctx, m, js_my_module_funcs, countof(js_my_module_funcs));    return m;}

?Makefile文件中添加my_module.c模塊的編譯Kx128資訊網——每日最新資訊28at.com

QJS_LIB_OBJS= ... $(OBJDIR)/my_module.o

?在qjsc.c文件中注冊模塊Kx128資訊網——每日最新資訊28at.com

namelist_add(&cmodule_list,“my_module”,“my_module”,0);

?編寫一個my_module.js測試文件Kx128資訊網——每日最新資訊28at.com

import * as mm from 'my_module';const value = mm.plus(1, 2);console.log(`my_module.plus: ${value}`);

?重新編譯Kx128資訊網——每日最新資訊28at.com

sudo make && sudo make installqjsc -m -o my_module examples/my_module.js /// 這里需要指定my_module模塊

最終生成的my_module可執行文件,通過執行my_module輸出:Kx128資訊網——每日最新資訊28at.com

my_module.plus: 3

8.使用C API

在第5個步驟時,生成了add.c文件中實際上已經給出了一個簡單的使用C API最基本的代碼。當編寫一下如下的js源碼時,會發現當前的qjsc編譯后的可執行文件或者qjs執行這段js代碼與我們的預期不符:Kx128資訊網——每日最新資訊28at.com

function getName() {    return new Promise((resolve, reject) => {        setTimeout(() => {            resolve("張三峰");        }, 2000);    });}console.log(`開始執行`);getName().then(name => console.log(`promise name: ${name}`));

Kx128資訊網——每日最新資訊28at.com

上面的代碼并不會按預期的效果輸出結果,因為js環境下的loop只執行了一次,任務隊列還沒有來得急執行程序就結束了,稍微改動一下讓程序可以正常輸出,如下:Kx128資訊網——每日最新資訊28at.com

#include <stdio.h>#include <pthread.h>#include <stdlib.h>#include <uv.h>/* File generated automatically by the QuickJS compiler. */#include "quickjs-libc.h"#include <string.h>static JSContext *JS_NewCustomContext(JSRuntime *rt) {  JSContext *ctx = JS_NewContextRaw(rt);  if (!ctx)    return NULL;  JS_AddIntrinsicBaseObjects(ctx);  JS_AddIntrinsicDate(ctx);  JS_AddIntrinsicEval(ctx);  JS_AddIntrinsicStringNormalize(ctx);  JS_AddIntrinsicRegExp(ctx);  JS_AddIntrinsicJSON(ctx);  JS_AddIntrinsicProxy(ctx);  JS_AddIntrinsicMapSet(ctx);  JS_AddIntrinsicTypedArrays(ctx);  JS_AddIntrinsicPromise(ctx);  JS_AddIntrinsicBigInt(ctx);  return ctx;}JSRuntime *rt = NULL;JSContext *ctx = NULL;void *run(void *args) {    const char *file_path = "/Volumes/Work/分享/quickjs/code/quickjs/examples/promise.js";    size_t pbuf_len = 0;            js_std_set_worker_new_context_func(JS_NewCustomContext);    js_std_init_handlers(rt);    JS_SetModuleLoaderFunc(rt, NULL, js_module_loader, NULL);    ctx = JS_NewCustomContext(rt);            js_std_add_helpers(ctx, 0, NULL);    js_init_module_os(ctx, "test");    const uint8_t *code = js_load_file(ctx, &pbuf_len, file_path);    JSValue js_ret_val = JS_Eval(ctx, (char *)code, pbuf_len, "add", JS_EVAL_TYPE_MODULE);    if(JS_IsError(ctx, js_ret_val) || JS_IsException(js_ret_val)) {        js_std_dump_error(ctx);    }    return NULL;}pthread_t quickjs_t;int main(int argc, char **argv) {    rt = JS_NewRuntime();    pthread_create(&quickjs_t, NULL, run, NULL);    while (1) {        if(ctx) js_std_loop(ctx);    }    js_std_free_handlers(rt);    JS_FreeContext(ctx);    JS_FreeRuntime(rt);    return 0;}

這樣的操作只適合用于測試一下功能,實際生產中使用需要一個即可以在必要的時候調用loop又可以做到不搶占過多的CPU或者只搶占較少的CPU時間片。Kx128資訊網——每日最新資訊28at.com

四、libuv

1.libuv簡價

libuv 是一個使用C語言編寫的多平臺支持庫,專注于異步 I/O。 它主要是為 Node.js 使用而開發的,但 Luvit、Julia、uvloop 等也使用它。Kx128資訊網——每日最新資訊28at.com

功能亮點Kx128資訊網——每日最新資訊28at.com

?由 epoll、kqueue、IOCP、事件端口支持的全功能事件循環。Kx128資訊網——每日最新資訊28at.com

?異步 TCP 和 UDP 套接字Kx128資訊網——每日最新資訊28at.com

?異步 DNS 解析Kx128資訊網——每日最新資訊28at.com

?異步文件和文件系統操作Kx128資訊網——每日最新資訊28at.com

?文件系統事件Kx128資訊網——每日最新資訊28at.com

?ANSI 轉義碼控制的 TTYKx128資訊網——每日最新資訊28at.com

?具有套接字共享的 IPC,使用 Unix 域套接字或命名管道 (Windows)Kx128資訊網——每日最新資訊28at.com

?子進程Kx128資訊網——每日最新資訊28at.com

?線程池Kx128資訊網——每日最新資訊28at.com

?信號處理Kx128資訊網——每日最新資訊28at.com

?高分辨率時鐘Kx128資訊網——每日最新資訊28at.com

?線程和同步原語Kx128資訊網——每日最新資訊28at.com

2.libuv運行原理

Kx128資訊網——每日最新資訊28at.com

int uv_run(uv_loop_t* loop, uv_run_mode mode) {  ...  r = uv__loop_alive(loop);  if (!r)    uv__update_time(loop);  while (r != 0 && loop->stop_flag == 0) {    uv__update_time(loop);    uv__run_timers(loop);    ran_pending = uv__run_pending(loop);    uv__run_idle(loop);    uv__run_prepare(loop);    ...    uv__io_poll(loop, timeout);    uv__run_check(loop);    uv__run_closing_handles(loop);    ...  }}

3.簡單使用

static void timer_cb(uv_timer_t *handler) {    printf("timer_cb exec./r/n");}int main(int argc, const char * argv[]) {   uv_loop_t *loop = uv_default_loop();   uv_timer_t *timer = (uv_timer_t*)malloc(sizeof(uv_timer_t));   uv_timer_init(loop, timer);   uv_timer_start(timer, timer_cb, 2000, 0);   uv_run(loop, UV_RUN_DEFAULT);}

五、QuickJS + libuv

console.log(`開始執行`);function getName() {    return new Promise((resolve, reject) => {        setTimeout(() => {            resolve("張三峰");        }, 2000);    });}getName().then(name => console.log(`promise name: ${name}`));

Kx128資訊網——每日最新資訊28at.com

#include <stdio.h>#include <pthread.h>#include <stdlib.h>#include <uv.h>/* File generated automatically by the QuickJS compiler. */#include "quickjs-libc.h"#include <string.h>typedef struct once_timer_data {    JSValue func;    JSValue this_val;    JSContext *ctx;} once_timer_data;void once_timer_cb(uv_timer_t *once_timer) {    once_timer_data *data = (once_timer_data *)once_timer->data;    JSContext *ctx = data->ctx;    JSValue js_ret_val = JS_Call(data->ctx, data->func, data->this_val, 0, NULL);    if(JS_IsError(ctx, js_ret_val) || JS_IsException(js_ret_val)) {        js_std_dump_error(ctx);    }    JS_FreeValue(data->ctx, js_ret_val);    JS_FreeValue(data->ctx, data->func);    JS_FreeValue(data->ctx, data->this_val);    free(data);    uv_timer_stop(once_timer);    free(once_timer);}void check_cb(uv_check_t *check) {    JSContext *ctx = (JSContext *)check->data;    js_std_loop(ctx);}void idle_cb(uv_idle_t *idle) {    }JSValue set_timeout(JSContext *ctx, JSValue this_val, int argc, JSValue *argv) {     if(argc != 2) return JS_NULL;    JSValue func_val = argv[0];    JSValue delay_val = argv[1];    int64_t delay = 0;    int ret = JS_ToInt64(ctx, &delay, delay_val);    if(ret < 0) js_std_dump_error(ctx);    uv_timer_t *once_timer = (uv_timer_t *)malloc(sizeof(uv_timer_t));    once_timer_data *data = (once_timer_data *)malloc(sizeof(once_timer_data));    data->func = JS_DupValue(ctx, func_val);    data->this_val = JS_DupValue(ctx, this_val);    data->ctx = ctx;    once_timer->data = data;    uv_timer_init(uv_default_loop(), once_timer);    uv_timer_start(once_timer, once_timer_cb, delay, 0);    JSValue js_timer = JS_NewInt64(ctx, (uint64_t)once_timer);    return js_timer;}static JSContext *JS_NewCustomContext(JSRuntime *rt) {  JSContext *ctx = JS_NewContextRaw(rt);  if (!ctx)    return NULL;  JS_AddIntrinsicBaseObjects(ctx);  JS_AddIntrinsicDate(ctx);  JS_AddIntrinsicEval(ctx);  JS_AddIntrinsicStringNormalize(ctx);  JS_AddIntrinsicRegExp(ctx);  JS_AddIntrinsicJSON(ctx);  JS_AddIntrinsicProxy(ctx);  JS_AddIntrinsicMapSet(ctx);  JS_AddIntrinsicTypedArrays(ctx);  JS_AddIntrinsicPromise(ctx);  JS_AddIntrinsicBigInt(ctx);  return ctx;}void js_job(uv_timer_t *timer) {    JSRuntime *rt = timer->data;    const char *file_path = "/Volumes/Work/分享/quickjs/code/quickjs/examples/promise.js";    size_t pbuf_len = 0;        JSContext *ctx;    js_std_set_worker_new_context_func(JS_NewCustomContext);    js_std_init_handlers(rt);    JS_SetModuleLoaderFunc(rt, NULL, js_module_loader, NULL);    ctx = JS_NewCustomContext(rt);        uv_check_t *check = (uv_check_t *)malloc(sizeof(uv_check_t));    uv_check_init(uv_default_loop(), check);    check->data = ctx;    uv_check_start(check, check_cb);        JSValue global = JS_GetGlobalObject(ctx);    JSValue func_val = JS_NewCFunction(ctx, set_timeout, "setTimeout", 1);    JS_SetPropertyStr(ctx, global, "setTimeout", func_val);    JS_FreeValue(ctx, global);            js_std_add_helpers(ctx, 0, NULL);    js_init_module_os(ctx, "test");    const uint8_t *code = js_load_file(ctx, &pbuf_len, file_path);    JSValue js_ret_val = JS_Eval(ctx, (char *)code, pbuf_len, "add", JS_EVAL_TYPE_MODULE);    if(JS_IsError(ctx, js_ret_val) || JS_IsException(js_ret_val)) {        js_std_dump_error(ctx);    }    js_std_free_handlers(rt);    JS_FreeContext(ctx);  }int main(int argc, char **argv) {    JSRuntime *rt = JS_NewRuntime();    uv_loop_t *loop = uv_default_loop();        uv_timer_t *timer = (uv_timer_t*)malloc(sizeof(uv_timer_t));    timer->data = rt;    uv_timer_init(loop, timer);    uv_timer_start(timer, js_job, 0, 0);        uv_idle_t *idle = (uv_idle_t *)malloc(sizeof(uv_idle_t));    uv_idle_init(loop, idle);    uv_idle_start(idle, idle_cb);    uv_run(loop, UV_RUN_DEFAULT);    JS_FreeRuntime(rt);    return 0;}

本文鏈接:http://m.www897cc.com/showinfo-26-76532-0.html跨端輕量JavaScript引擎的實現與探索

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: ?2024年保護微服務的前十種技術

下一篇: .NET Core 上傳文件到本地服務器技術詳解

標簽:
  • 熱門焦點
  • 影音體驗是真的強 簡單聊聊iQOO Pad

    大公司的好處就是產品線豐富,非常細分化的東西也能給你做出來,例如早先我們看到了新的vivo Pad2,之后我們又在iQOO Neo8 Pro的發布會上看到了iQOO的首款平板產品iQOO Pad。雖
  • 6月iOS設備好評榜:第一蟬聯榜首近一年

    作為安兔兔各種榜單里變化最小的那個,2023年6月的iOS好評榜和上個月相比沒有任何排名上的變化,僅僅是部分設備好評率的下降,長年累月的用戶評價和逐漸退出市場的老款機器讓這
  • 6月安卓手機性能榜:vivo/iQOO霸占旗艦排行榜前三

    2023年上半年已經正式過去了,我們也迎來了安兔兔V10版本,在新的驍龍8Gen3和天璣9300發布之前,性能榜的榜單大體會以驍龍8Gen2和天璣9200+為主,至于那顆3.36GHz的驍龍8Gen2領先
  • 服務存儲設計模式:Cache-Aside模式

    Cache-Aside模式一種常用的緩存方式,通常是把數據從主存儲加載到KV緩存中,加速后續的訪問。在存在重復度的場景,Cache-Aside可以提升服務性能,降低底層存儲的壓力,缺點是緩存和底
  • 每天一道面試題-CPU偽共享

    前言:了不起:又到了每天一到面試題的時候了!學弟,最近學習的怎么樣啊 了不起學弟:最近學習的還不錯,每天都在學習,每天都在進步! 了不起:那你最近學習的什么呢? 了不起學弟:最近在學習C
  • 2天漲粉255萬,又一賽道在抖音爆火

    來源:運營研究社作者 | 張知白編輯 | 楊佩汶設計 | 晏談夢潔這個暑期,旅游賽道徹底火了:有的「地方」火了&mdash;&mdash;貴州村超旅游收入 1 個月超過 12 億;有的「博主」火了&m
  • “又被陳思誠騙了”

    作者|張思齊 出品|眾面(ID:ZhongMian_ZM)如今的國產懸疑電影,成了陳思誠的天下。最近大爆電影《消失的她》票房突破30億斷層奪魁暑期檔,陳思誠再度風頭無兩。你可以說陳思誠的
  • 超級標準版旗艦!iQOO 11S全球首發iQOO超算獨顯芯片

    上半年已接近尾聲,截至目前各大品牌旗下的頂級旗艦都已悉數亮相,而下半年即將推出的頂級旗艦已經成為了數碼圈爆料的主流,其中就包括全新的iQOO 11S系
  • 親歷馬斯克血洗Twitter,硅谷的苦日子在后頭

    文/劉哲銘  編輯/李薇  馬斯克再次揮下裁員大刀。  美國時間11月14日,Twitter約4400名外包員工遭解雇,此次被解雇的員工的主要工作為內容審核等。此前,T
Top 日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不
麻豆精品精华液| 亚洲裸体在线观看| 欧美日韩国产欧| 欧美精品久久久久久久久老牛影院| 欧美一站二站| 久久精品女人| 蜜桃av噜噜一区| 欧美另类视频在线| 欧美四级在线| 国产精品亚洲аv天堂网| 国产精品性做久久久久久| 国产欧美一区二区三区国产幕精品| 国产日韩精品一区观看| 国产精品午夜久久| 99riav久久精品riav| 一区二区三区蜜桃网| 欧美在线亚洲在线| 欧美国产先锋| 国产农村妇女毛片精品久久麻豆| 激情六月综合| 一二三四社区欧美黄| 久久福利毛片| 欧美日韩国产成人精品| 国产欧美精品va在线观看| 91久久夜色精品国产九色| 午夜精品视频在线| 欧美韩日一区| 国产在线欧美| 亚洲视频网站在线观看| 美女尤物久久精品| 国产精品亚洲综合天堂夜夜| 亚洲黄色一区| 欧美在线一二三| 欧美日韩免费一区二区三区视频| 国模叶桐国产精品一区| 亚洲午夜国产成人av电影男同| 久久婷婷综合激情| 国产精品伦一区| 亚洲人成在线观看一区二区| 久久狠狠婷婷| 国产精品wwwwww| 亚洲人成欧美中文字幕| 久久久久久久久久久久久女国产乱| 欧美视频在线一区| 亚洲欧洲日本一区二区三区| 久久九九精品99国产精品| 欧美亚州一区二区三区| 亚洲人成人99网站| 久久久久一区二区三区| 国产农村妇女精品一区二区| 在线亚洲成人| 欧美成人日本| 久久女同精品一区二区| 欧美色视频在线| 亚洲欧洲精品一区| 久久全球大尺度高清视频| 国产精品午夜电影| 一区二区三区精品视频| 欧美不卡视频| 一区在线视频| 久久精品国产在热久久| 国产欧美日韩伦理| 亚洲综合三区| 欧美性色综合| 亚洲久久一区| 欧美电影电视剧在线观看| 一区二区三区在线视频免费观看| 午夜视黄欧洲亚洲| 欧美午夜电影完整版| 夜夜爽夜夜爽精品视频| 欧美久久一级| 亚洲精品一区二区在线观看| 免费观看日韩| 亚洲国产精品成人| 男女精品网站| 亚洲黄色成人网| 欧美成人有码| 亚洲精品影视在线观看| 欧美精品一区二区三区蜜桃| 亚洲人成网站在线播| 欧美大胆a视频| 在线精品观看| 欧美91视频| 亚洲精品色婷婷福利天堂| 欧美不卡一区| 亚洲精品视频免费| 欧美美女日韩| 一区二区精品在线观看| 欧美午夜电影完整版| 亚洲无亚洲人成网站77777| 国产精品草草| 亚洲欧美制服另类日韩| 国产欧美精品久久| 久久久成人网| 亚洲国产成人av| 亚洲成在线观看| 亚洲精品在线视频| 欧美精品在线视频| 日韩视频免费观看| 欧美视频一二三区| 亚洲欧美一区在线| 国产日产精品一区二区三区四区的观看方式 | 亚洲视频久久| 国产精品欧美久久久久无广告| 亚洲欧美日韩一区二区在线| 国产一区二区电影在线观看| 99国产精品99久久久久久| 欧美日韩三级| 亚洲影视在线播放| 国产午夜精品理论片a级探花 | 久久精品人人| 亚洲国产精品123| 欧美视频一区二区三区…| 亚洲欧美中日韩| 红桃视频成人| 欧美久久久久久久久久| 亚洲欧美国产高清| 国模叶桐国产精品一区| 欧美激情一级片一区二区| 在线亚洲免费视频| 国产午夜精品全部视频在线播放| 久久综合伊人77777| 日韩视频―中文字幕| 国产精品剧情在线亚洲| 久久午夜激情| 一本色道88久久加勒比精品| 国产区二精品视| 欧美福利小视频| 亚洲欧美综合国产精品一区| 亚洲电影中文字幕| 国产精品高清在线| 久久久久国色av免费看影院| 亚洲久色影视| 国内精品伊人久久久久av一坑| 欧美高清视频一区| 午夜精品久久久| 亚洲国产另类精品专区| 国产精品视频导航| 欧美va亚洲va日韩∨a综合色| 亚洲一区久久久| 亚洲成人在线网| 国产精品区免费视频| 久热re这里精品视频在线6| 亚洲午夜国产一区99re久久| 经典三级久久| 国产精品久久久久9999吃药| 美女精品网站| 亚洲欧美成人| 亚洲人永久免费| 国产欧美日韩亚洲精品| 欧美人与禽性xxxxx杂性| 久久成年人视频| 在线综合亚洲| 亚洲激情综合| 国产在线精品二区| 欧美视频在线观看 亚洲欧| 久久午夜影视| 亚洲欧美日韩一区二区在线| 亚洲人成亚洲人成在线观看| 国产欧美精品一区aⅴ影院| 欧美激情亚洲精品| 久久精品一区二区三区不卡| 宅男噜噜噜66一区二区 | 亚洲一区二区三区在线观看视频| 亚洲第一黄网| 国产一区二区三区免费在线观看| 欧美色视频一区| 欧美多人爱爱视频网站| 欧美一区二区视频在线观看| 夜夜躁日日躁狠狠久久88av| 亚洲高清激情| 韩国精品在线观看| 国产精品自拍在线| 欧美系列精品| 欧美精品福利在线| 欧美大片va欧美在线播放| 久久久久久网| 韩国自拍一区| 国产精品免费aⅴ片在线观看| 欧美理论在线播放| 欧美xxx成人| 久久青草福利网站| 欧美在线一二三四区| 亚洲欧美精品在线观看| 亚洲午夜在线观看| 一片黄亚洲嫩模| 亚洲理论在线观看| 亚洲精品国精品久久99热一| 亚洲国产一区二区a毛片| 影音先锋成人资源站| 海角社区69精品视频| 国产最新精品精品你懂的| 国产亚洲一区二区三区在线观看 | **欧美日韩vr在线| 激情一区二区| 激情丁香综合| 伊人久久av导航| 一区二区三区在线免费视频| 在线观看精品| 亚洲国内欧美| 亚洲精品九九| 99re热这里只有精品视频| 亚洲美女中文字幕| 一本大道av伊人久久综合|