前端:QuickJS到底能干什么

640?wx_fmt=png


QuickJS 是一個輕量且可嵌入的 JavaScript 引擎,它支持 ES2019 規范,包括 ES module、異步生成器以及 proxies。除此之外,還支持可選的數學擴展,例如大整數(BigInt)、大浮點數(BigFloat)和運算符重載。


主要特點:

  • 輕量而且易于嵌入:只需幾個C文件,沒有外部依賴,一個x86下的簡單的“hello world”程序只要180 KiB。

  • 具有極低啟動時間的快速解釋器:在一臺單核的臺式PC上,大約在100秒內運行ECMAScript 測試套件1 56000次。運行時實例的完整生命周期在不到300微秒的時間內完成。

  • 幾乎完整實現ES2019支持,包括:模塊,異步生成器和和完整Annex B支持 (傳統的Web兼容性)。

  • 通過100%的ECMAScript Test Suite測試。

  • 可以將Javascript源編譯為沒有外部依賴的可執行文件。

  • 使用引用計數(以減少內存使用并具有確定性行為)的垃圾收集與循環刪除。

  • 數學擴展:BigInt, BigFloat, 運算符重載, bigint模式, math模式.

  • 在Javascript中實現的具有上下文著色和完成的命令行解釋器。

  • 采用C包裝庫構建的內置標準庫。

用途:后端服務、嵌入式應用、命令工具等等。

示例:

QuickJS/bjson.c:一個可讀取可寫入JSON文件的插件

#include "quickjs-libc.h"
#include "cutils.h"

static JSValue js_bjson_read(JSContext *ctx, JSValueConst this_val,
int argc, JSValueConst *argv)
{
uint8_t *buf;
uint64_t pos, len;
JSValue obj;
size_t size;

if (JS_ToIndex(ctx, &pos, argv[1]))
return JS_EXCEPTION;
if (JS_ToIndex(ctx, &len, argv[2]))
return JS_EXCEPTION;
buf = JS_GetArrayBuffer(ctx, &size, argv[0]);
if (!buf)
return JS_EXCEPTION;
if (pos + len > size)
return JS_ThrowRangeError(ctx, "array buffer overflow");
obj = JS_ReadObject(ctx, buf + pos, len, 0);
return obj;
}

static JSValue js_bjson_write(JSContext *ctx, JSValueConst this_val,
int argc, JSValueConst *argv)
{
size_t len;
uint8_t *buf;
JSValue array;

buf = JS_WriteObject(ctx, &len, argv[0], 0);
if (!buf)
return JS_EXCEPTION;
array = JS_NewArrayBufferCopy(ctx, buf, len);
js_free(ctx, buf);
return array;
}

static const JSCFunctionListEntry js_bjson_funcs[] = {
JS_CFUNC_DEF("read", 3, js_bjson_read ),
JS_CFUNC_DEF("write", 1, js_bjson_write ),
};

static int js_bjson_init(JSContext *ctx, JSModuleDef *m)
{
return JS_SetModuleExportList(ctx, m, js_bjson_funcs,
countof(js_bjson_funcs));
}

#ifdef JS_SHARED_LIBRARY
#define JS_INIT_MODULE js_init_module
#else
#define JS_INIT_MODULE js_init_module_bjson
#endif

JSModuleDef *JS_INIT_MODULE(JSContext *ctx, const char *module_name)
{
JSModuleDef *m;
m = JS_NewCModule(ctx, module_name, js_bjson_init);
if (!m)
return NULL;
JS_AddModuleExportList(ctx, m, js_bjson_funcs, countof(js_bjson_funcs));
return m;
}


QuickJS/tests/test_bjson.js:測試代碼

import * as bjson from "../bjson.so";

function assert(b, str)
{
if (b) {
return;
} else {
throw Error("assertion failed: " + str);
}
}

function toHex(a)
{
var i, s = "", tab, v;
tab = new Uint8Array(a);
for(i = 0; i < tab.length; i++) {
v = tab[i].toString(16);
if (v.length < 2)
v = "0" + v;
if (i !== 0)
s += " ";
s += v;
}
return s;
}

function toStr(a)
{
var s, i, props, prop;

switch(typeof(a)) {
case "object":
if (a === null)
return "null";
if (Array.isArray(a)) {
s = "[";
for(i = 0; i < a.length; i++) {
if (i != 0)
s += ",";
s += toStr(a[i]);
}
s += "]";
} else {
props = Object.keys(a);
s = "{";
for(i = 0; i < props.length; i++) {
if (i != 0)
s += ",";
prop = props[i];
s += prop + ":" + toStr(a[prop]);
}
s += "}";
}
return s;
case "undefined":
return "undefined";
case "string":
return a.__quote();
case "number":
case "bigfloat":
if (a == 0 && 1 / a < 0)
return "-0";
else
return a.toString();
break;
default:
return a.toString();
}
}

function bjson_test(a)
{
var buf, r, a_str, r_str;
a_str = toStr(a);
buf = bjson.write(a);
if (0) {
print(a_str, "->", toHex(buf));
}
r = bjson.read(buf, 0, buf.byteLength);
r_str = toStr(r);
if (a_str != r_str) {
print(a_str);
print(r_str);
assert(false);
}
}

function bjson_test_all()
{
var obj;

bjson_test({x:1, y:2, if:3});
bjson_test([1, 2, 3]);
bjson_test([1.0, "aa", true, false, undefined, null, NaN, -Infinity, -0.0]);
if (typeof BigInt !== "undefined") {
bjson_test([BigInt("1"), -BigInt("0x123456789"),
BigInt("0x123456789abcdef123456789abcdef")]);
}
if (typeof BigFloat !== "undefined") {
BigFloatEnv.setPrec(function () {
bjson_test([BigFloat("0.1"), BigFloat("-1e30"), BigFloat("0"),
BigFloat("-0"), BigFloat("Infinity"), BigFloat("-Infinity"),
0.0 / BigFloat("0"), BigFloat.MAX_VALUE,
BigFloat.MIN_VALUE]);
}, 113, 15);
}

/* tested with a circular reference */
obj = {};
obj.x = obj;
try {
bjson.write(obj);
assert(false);
} catch(e) {
assert(e instanceof TypeError);
}
}

bjson_test_all();


本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/271959.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/271959.shtml
英文地址,請注明出處:http://en.pswp.cn/news/271959.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

隨機存取是什么意思_手機小白必看!12GB+256GB,同樣是GB,它們到底有什么不同?...

導語本文適合對電子產品有深度興趣的小白&#xff0c;詳細介紹了信息世界的數據計量單位&#xff0c;以及RAM與ROM的&#xff0c;文末給出了購機建議&#xff0c;建議不了解手機或者說半懂的同學觀看。看完如果您覺得還可以的話&#xff0c;點贊關注&#xff0c;給小編一個鼓勵…

ES6 解構賦值的用法筆記

1、概念&#xff1a;解構賦值可以理解為對賦值運算符的一種擴展。它主要針對數組或者對象進行模式匹配&#xff0c;然后對模式中的變量進行賦值。2、特性&#xff1a;采用ES6解構賦值的方式可以代碼的可讀性更高、代碼書寫更加簡潔、清晰。3、解構模型&#xff1a;分為解構源、…

一.高階函數

一.函數式編程中函數的特點 可以創建匿名函數 def聲明帶名函數&#xff0c;val聲明匿名函數scala scala> def triple(x:Int):Int {3*x} scala> triple(2) res1: Int 6scala scala> val triple (x:Int) > 3*x scala> triple(2) res0: Int 6函數和數字一樣&am…

線程和進程的區別?

進程是操作系統分配資源的最小單元&#xff0c;線程是操作系統調度的最小單元。 一個程序至少有一個進程,一個進程至少有一個線程。

收集12個經典的程序員段子

1bug 跟蚊子的相似之處&#xff1a;1、不知道藏在哪里。2、不知道有多少。3、總是在你即將睡覺休息的時候出現。2A&#xff1a;最近在看《一拳超人》&#xff0c;覺得咱們程序猿跟埼玉老師有點像啊&#xff01;B&#xff1a;哪里像了&#xff1f;A&#xff1a;越禿越強&#xf…

2020mysql安裝教程_2020MySQL安裝圖文教程

MySQL安裝圖文教程(Windows10)1、MySQL下載可以去MySQL官網下載&#xff0c;或者在我提供的百度云鏈接下載。官網下載網速較慢&#xff0c;我從官網下載了將近四個小時&#xff0c;然后把下載好的放在了百度網盤&#xff0c;需要的而已自取。MySQL官網地址&#xff1a;MySQL官網…

說一下 runnable 和 callable 有什么區別?

主要區別 Runnable 接口 run 方法無返回值&#xff1b;Callable 接口 call 方法有返回值&#xff0c;支持泛型Runnable 接口 run 方法只能拋出運行時異常&#xff0c;且無法捕獲處理&#xff1b;Callable 接口 call 方法允許拋出異常&#xff0c;可以獲取異常信息 Runnable Ca…

幾種常見的光纖接頭(ST,SC,LC,FC)以及PC、APC和UPC的區別

一、幾種常見的光纖接頭(ST,SC,LC,FC)FC型光纖連接器&#xff1a;外部加強方式是采用金屬套&#xff0c;緊固方式為螺絲扣。 一般在ODF側采用(配線架上用的最多)SC型光纖連接器&#xff1a;連接GBIC光模塊或普通光纖收發器的連接器&#xff0c;它的外殼呈矩形&#xff0c;緊固方…

nginx配置ssl

1.使用pfx證書配置ssl &#xff08;http://www.heartlifes.com/archives/12/&#xff09; 。上傳證書 。生成證書crt及key文件 openssl pkcs12 -in /usr/local/nginx/ssl/xxx.pfx -clcerts -nokeys -out /usr/local/nginx/ssl/xxx.crt openssl pkcs12 -in /usr/local/nginx/ssl…

python開發客戶端_python用700行代碼實現http客戶端

本文用python在TCP的基礎上實現一個HTTP客戶端, 該客戶端能夠復用TCP連接, 使用HTTP1.1協議.一. 創建HTTP請求HTTP是基于TCP連接的, 它的請求報文格式如下:因此, 我們只需要創建一個到服務器的TCP連接, 然后按照上面的格式寫好報文并發給服務器, 就實現了一個HTTP請求.1. HTTPC…

家里網線的接法和順序

對于網線&#xff0c;大伙都熟悉吧&#xff0c;它是電腦連接時必不可少的一種設備。但是許多網友卻和小編一樣&#xff0c;不知道如何連接網線&#xff0c;導致電腦無法上網&#xff0c;下面我們就來詳細介紹一下&#xff1a;如何接網線以及家里網線的接法和順序&#xff1f;希…

String str=Hello 與 String str=new String(“Hello”)一樣嗎?

為什么會輸出上邊的結果呢&#xff0c;String x "Hello" 的方式&#xff0c;Java 虛擬機會將其分配到常量池中&#xff0c;而常量池中沒有重復的元素&#xff0c;比如當執行“Hello”時&#xff0c;java虛擬機會先在常量池中檢索是否已經有“Hello”,如果有那么就將…

盤點程序員最喜歡的15個網站

程序員作為一個經常和互聯網打交道的人群&#xff0c;他們喜歡瀏覽哪些網站呢&#xff1f;不愛敲代碼的程序猿整理了以下網站供大家參考&#xff0c;排名不分先后&#xff1a; 0. Google https://google.com 這個不用多說了吧。 1.GitHub 開發者最最最重要的網站&#xff1a;h…

簡單的反射 把datatable 轉換成list對象

/// <summary>/// 把datatable 轉換成list對象/// </summary>/// <typeparam name"T"></typeparam>/// <param name"dt"></param>/// <returns></returns>public List<T> SelectsAll<T>(Data…

mysql 取 映射數據庫中_JAVA與數據庫MySQL相連接

JDBC(Java數據庫連接體系結構)&#xff1a;是Java實現數據庫訪問的應用程序編程接口&#xff0c;主要功能是管理存放在數據庫中的數據。通過接口對象&#xff0c;應用程序可以完成與數據庫的連接&#xff0c;執行SQL語句&#xff0c;從數據庫中獲取結果&#xff0c;獲取狀態以及…

抽象類必須要有抽象方法嗎?

答案是&#xff1a;不必須。 這個題目主要是考察對抽象類的理解。 說一下我個人的理解吧。 1.如果一個類使用了abstract關鍵字修飾&#xff0c;那么這個類就是一個抽象類。 2.抽象類可以沒有抽象方法 3.一個類如果包含抽象方法&#xff0c;那么這個類必須是抽象類&#xf…

python序列化和反序列化_Python 中 json 數據序列化和反序列化

1.Json 定義定義&#xff1a;JSON(JavaScript Object Notation, JS 對象簡譜) 是一種輕量級的數據交換格式。JSON 的數據格式其實就是 python 里面的字典格式&#xff0c;里面可以包含方括號括起來的數組&#xff0c;也就是python里面的列表。特點&#xff1a;簡潔和清晰的層次…

重寫navigationController的push方法后,出現卡頓現象

在使用navigation的pushViewController進行push的時候&#xff0c;兩個頁面間的動畫會出現卡頓一下再推出的效果&#xff0c;是因為iOS7 viewController背景顏色的問題&#xff0c;看到大神的博客上說&#xff1a;其實不是卡頓&#xff0c;是由于透明色顏色重疊后視覺上的問題&…

硬件:RS232基礎知識筆記

個人計算機上的通訊接口之一&#xff0c;由電子工業協會&#xff08;ElectronicIndustriesAssociation&#xff0c;EIA&#xff09;所制定的異步傳輸標準接口。通常RS-232接口以9個引腳&#xff08;DB-9&#xff09;或是25個引腳&#xff08;DB-25&#xff09;的型態出現&#…

普通類和抽象類有哪些區別?

抽象類不能被實例化抽象類可以有抽象方法&#xff0c;抽象方法只需申明&#xff0c;無需實現含有抽象方法的類必須申明為抽象類抽象類的子類必須實現抽象類中所有抽象方法&#xff0c;否則這個子類也是抽象類抽象方法不能被聲明為靜態static抽象方法不能用 private 修飾&#x…