前端: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.mzph.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…