Top Related Projects
Public repository of the QuickJS Javascript Engine.
Safely execute untrusted Javascript in your Javascript, and execute synchronous code that uses async functions
A tiny JavaScript runtime
Rust bindings for the V8 JavaScript engine
Ultra-lightweight JavaScript engine for the Internet of Things.
Embedded JavaScript engine for C/C++
Quick Overview
QuickJS is a small and embeddable JavaScript engine. It supports the latest ECMAScript standard (ES2020) and provides a simple C API for embedding it into applications. The project is developed by Fabrice Bellard, the creator of QEMU and FFmpeg.
Pros
- Small Footprint: QuickJS has a small memory footprint, making it suitable for embedded systems and resource-constrained environments.
- Fast Execution: The engine is designed for fast execution of JavaScript code, with a focus on performance.
- Modern JavaScript Support: QuickJS supports the latest ECMAScript standard (ES2020), including features like async/await, modules, and more.
- Simple C API: The project provides a straightforward C API for embedding the JavaScript engine into applications.
Cons
- Limited Ecosystem: As a relatively new and niche project, QuickJS has a smaller ecosystem compared to more established JavaScript engines like V8 or SpiderMonkey.
- Lack of Widespread Adoption: QuickJS is not as widely adopted as other JavaScript engines, which may limit its use in larger projects or enterprise-level applications.
- Incomplete Documentation: The project's documentation, while improving, could be more comprehensive and user-friendly for newcomers.
- Ongoing Development: As an active project, QuickJS may undergo frequent changes and updates, which could impact stability and compatibility for some users.
Code Examples
Here are a few examples of using QuickJS in C:
- Executing a Simple JavaScript Script:
#include "quickjs.h"
int main() {
JSRuntime *rt = JS_NewRuntime();
JSContext *ctx = JS_NewContext(rt);
JS_Eval(ctx, "console.log('Hello, QuickJS!');", -1, "<input>", 0);
JS_FreeContext(ctx);
JS_FreeRuntime(rt);
return 0;
}
- Calling a JavaScript Function from C:
#include "quickjs.h"
int main() {
JSRuntime *rt = JS_NewRuntime();
JSContext *ctx = JS_NewContext(rt);
// Evaluate a JavaScript function
JS_Eval(ctx, "function add(a, b) { return a + b; }", -1, "<input>", 0);
// Call the JavaScript function from C
JSValue result = JS_Call(ctx, JS_GetGlobalObject(ctx), JS_NewString(ctx, "add"), 2, (JSValue[]){JS_NewInt32(ctx, 2), JS_NewInt32(ctx, 3)});
int sum = JS_GetInt32(ctx, result);
printf("The sum is: %d\n", sum);
JS_FreeValue(ctx, result);
JS_FreeContext(ctx);
JS_FreeRuntime(rt);
return 0;
}
- Handling Errors in QuickJS:
#include "quickjs.h"
int main() {
JSRuntime *rt = JS_NewRuntime();
JSContext *ctx = JS_NewContext(rt);
// Evaluate a JavaScript script that will throw an error
JSValue result = JS_Eval(ctx, "throw new Error('Something went wrong');", -1, "<input>", 0);
// Check if an error occurred
if (JS_IsException(result)) {
JSValue exception = JS_GetException(ctx);
const char *error_message = JS_ToCString(ctx, exception);
printf("Error: %s\n", error_message);
JS_FreeValue(ctx, exception);
}
JS_FreeValue(ctx, result);
JS_FreeContext(ctx);
JS_FreeRuntime(rt);
return 0;
}
Getting Started
To get started with QuickJS, follow these steps:
- Clone the QuickJS repository:
git clone https://github.com/quickjs-zh/QuickJS.git
- Build the QuickJS library:
cd QuickJS
Competitor Comparisons
Public repository of the QuickJS Javascript Engine.
Pros of QuickJS
- Original implementation by Fabrice Bellard, ensuring high-quality and efficient codebase
- More frequent updates and maintenance
- Wider community support and adoption
Cons of QuickJS
- Fewer additional features compared to QuickJS-zh
- Less focus on performance optimizations
- Smaller set of language extensions
Code Comparison
QuickJS:
JSValue js_eval_binary(JSContext *ctx, const uint8_t *buf, size_t buf_len,
const char *filename, int flags)
{
JSParseState s1, *s = &s1;
int err;
JSValue ret;
QuickJS-zh:
JSValue js_eval_binary(JSContext *ctx, const uint8_t *buf, size_t buf_len,
const char *filename, int flags)
{
JSParseState s1, *s = &s1;
int err;
JSValue ret;
uint32_t tag;
The code comparison shows that QuickJS-zh includes an additional uint32_t tag
variable, potentially indicating extended functionality or optimizations in the parsing process.
Safely execute untrusted Javascript in your Javascript, and execute synchronous code that uses async functions
Pros of quickjs-emscripten
- Enables running QuickJS in web browsers and Node.js environments
- Provides TypeScript typings for improved developer experience
- Offers a more streamlined API for JavaScript/TypeScript developers
Cons of quickjs-emscripten
- May have performance overhead due to Emscripten compilation
- Limited to features supported by Emscripten and WebAssembly
- Potentially larger bundle size compared to native QuickJS
Code Comparison
QuickJS:
JSRuntime *rt = JS_NewRuntime();
JSContext *ctx = JS_NewContext(rt);
const char *str = "console.log('Hello, QuickJS!');";
JS_Eval(ctx, str, strlen(str), "<input>", JS_EVAL_TYPE_GLOBAL);
JS_FreeContext(ctx);
JS_FreeRuntime(rt);
quickjs-emscripten:
import { getQuickJS } from 'quickjs-emscripten';
const QuickJS = await getQuickJS();
const vm = QuickJS.newContext();
vm.evalCode(`console.log('Hello, QuickJS!');`);
vm.dispose();
The quickjs-emscripten version provides a more JavaScript-friendly API, with async/await support and simplified memory management. However, it requires additional setup for Emscripten and may have slightly different performance characteristics compared to the native C implementation of QuickJS.
A tiny JavaScript runtime
Pros of txiki.js
- Built-in asynchronous I/O and networking capabilities
- Includes a standard library with common utilities and modules
- Designed for embedding in larger applications and systems
Cons of txiki.js
- Larger footprint due to additional features and dependencies
- May have a steeper learning curve for developers new to the ecosystem
- Potentially slower execution for simple scripts compared to QuickJS
Code Comparison
QuickJS:
#include "quickjs.h"
JSRuntime *rt = JS_NewRuntime();
JSContext *ctx = JS_NewContext(rt);
const char *script = "console.log('Hello, QuickJS!');";
JS_Eval(ctx, script, strlen(script), "<input>", JS_EVAL_TYPE_GLOBAL);
JS_FreeContext(ctx);
JS_FreeRuntime(rt);
txiki.js:
#include "tjs.h"
tjs_init();
tjs_run_script("console.log('Hello, txiki.js!');");
tjs_cleanup();
The code comparison shows that txiki.js has a simpler API for basic script execution, while QuickJS requires more explicit runtime and context management. However, this simplicity in txiki.js comes at the cost of less fine-grained control over the JavaScript environment.
Rust bindings for the V8 JavaScript engine
Pros of rusty_v8
- Higher performance due to V8's advanced optimizations
- Better compatibility with modern JavaScript features
- Stronger ecosystem support and regular updates from the V8 team
Cons of rusty_v8
- Larger binary size and memory footprint
- More complex build process and dependencies
- Steeper learning curve for developers unfamiliar with V8
Code comparison
QuickJS:
#include "quickjs.h"
JSRuntime *rt = JS_NewRuntime();
JSContext *ctx = JS_NewContext(rt);
const char *code = "console.log('Hello, QuickJS!');";
JS_Eval(ctx, code, strlen(code), "<input>", JS_EVAL_TYPE_GLOBAL);
JS_FreeContext(ctx);
JS_FreeRuntime(rt);
rusty_v8:
use v8;
let platform = v8::new_default_platform(0, false).make_shared();
v8::V8::initialize_platform(platform);
v8::V8::initialize();
let isolate = &mut v8::Isolate::new(Default::default());
let handle_scope = &mut v8::HandleScope::new(isolate);
let context = v8::Context::new(handle_scope);
let scope = &mut v8::ContextScope::new(handle_scope, context);
let code = v8::String::new(scope, "console.log('Hello, rusty_v8!');").unwrap();
let script = v8::Script::compile(scope, code, None).unwrap();
script.run(scope).unwrap();
Ultra-lightweight JavaScript engine for the Internet of Things.
Pros of JerryScript
- Designed for resource-constrained devices, making it suitable for IoT and embedded systems
- Smaller memory footprint and faster startup time
- Supports a wider range of platforms, including microcontrollers
Cons of JerryScript
- Limited ES6+ feature support compared to QuickJS
- Slower execution speed for complex JavaScript code
- Less active development and community support
Code Comparison
JerryScript:
jerry_init(JERRY_INIT_EMPTY);
jerry_value_t result = jerry_eval((jerry_char_t *) "1 + 2", 5, true);
int num = jerry_get_number_value(result);
jerry_release_value(result);
jerry_cleanup();
QuickJS:
JSRuntime *rt = JS_NewRuntime();
JSContext *ctx = JS_NewContext(rt);
JSValue result = JS_Eval(ctx, "1 + 2", 5, "<input>", JS_EVAL_TYPE_GLOBAL);
int num = JS_ToInt32(ctx, &num, result);
JS_FreeValue(ctx, result);
JS_FreeContext(ctx);
JS_FreeRuntime(rt);
Both examples demonstrate basic script evaluation and value retrieval. JerryScript's API is more compact, while QuickJS offers a more structured approach with separate runtime and context management.
Embedded JavaScript engine for C/C++
Pros of v7
- Smaller footprint and lower memory usage, suitable for embedded systems
- Faster execution speed for certain operations
- Simpler codebase, easier to integrate and modify
Cons of v7
- Less feature-rich compared to QuickJS
- Limited ECMAScript compatibility (ES5 with some ES6 features)
- Smaller community and fewer resources available
Code Comparison
QuickJS:
JSValue js_eval_buf(JSContext *ctx, const void *buf, int buf_len,
const char *filename, int eval_flags)
{
JSValue val;
int ret;
ret = JS_Eval(ctx, buf, buf_len, filename, eval_flags);
if (JS_IsException(ret))
val = JS_GetException(ctx);
else
val = ret;
return val;
}
v7:
enum v7_err v7_exec(struct v7 *v7, const char *js_code, v7_val_t *result) {
enum v7_err rcode = V7_OK;
v7_val_t res;
rcode = v7_exec_with(v7, js_code, &res, V7_UNDEFINED, V7_UNDEFINED);
if (result != NULL) *result = res;
return rcode;
}
Both QuickJS and v7 are JavaScript engines, but they target different use cases. QuickJS aims to be a more complete implementation of ECMAScript, while v7 focuses on being lightweight and suitable for embedded systems. The code comparison shows their different approaches to executing JavaScript code, with QuickJS offering more options and v7 providing a simpler interface.
Convert
designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
QuickJS Javascriptå¼æ
ç®å½
- QuickJS Javascriptå¼æ
1 ç®ä»
QuickJSæ¯ä¸ä¸ªå°å并ä¸å¯åµå ¥çJavascriptå¼æï¼å®æ¯æES2020è§èï¼å æ¬æ¨¡åï¼å¼æ¥çæå¨å代çå¨ã
å®å¯éæ¯ææ°å¦æ©å±ï¼ä¾å¦å¤§æ´æ° (BigInt)ï¼å¤§æµ®ç¹æ° (BigFloat) 以åè¿ç®ç¬¦éè½½ã
å®æ¹ç«ç¹ï¼https://bellard.org/quickjs/
ä¸æç«ç¹ï¼https://github.com/quickjs-zh/
QuickJS QQ群1ï¼598609506ã
ä¸æWikiï¼https://github.com/quickjs-zh/QuickJS/wiki
1.1 主è¦åè½
- è½»éèä¸æäºåµå ¥ï¼åªéå 个Cæ件ï¼æ²¡æå¤é¨ä¾èµï¼ä¸ä¸ªx86ä¸çç®åçâhello worldâç¨åºåªè¦180 KiBã
- å ·ææä½å¯å¨æ¶é´çå¿«é解éå¨ï¼ å¨ä¸å°åæ ¸çå°å¼PCä¸ï¼å¤§çº¦å¨100ç§å è¿è¡ECMAScript æµè¯å¥ä»¶1 56000次ãè¿è¡æ¶å®ä¾çå®æ´çå½å¨æå¨ä¸å°300å¾®ç§çæ¶é´å å®æã
- å ä¹å®æ´å®ç°ES2019æ¯æï¼å æ¬ï¼ 模åï¼å¼æ¥çæå¨ååå®æ´Annex Bæ¯æ (ä¼ ç»çWebå ¼å®¹æ§)ã许å¤ES2020ä¸å¸¦æ¥çç¹æ§ä¹ä¾ç¶ä¼è¢«æ¯æã
- éè¿100ï¼ çECMAScript Test Suiteæµè¯ã
- å¯ä»¥å°Javascriptæºç¼è¯ä¸ºæ²¡æå¤é¨ä¾èµçå¯æ§è¡æ件ã
- 使ç¨å¼ç¨è®¡æ°ï¼ä»¥åå°å å使ç¨å¹¶å ·æç¡®å®æ§è¡ä¸ºï¼çåå¾æ¶éä¸å¾ªç¯å é¤ã
- æ°å¦æ©å±ï¼BigInt, BigFloat, è¿ç®ç¬¦éè½½, bigint模å¼, math模å¼.
- å¨Javascriptä¸å®ç°çå ·æä¸ä¸æçè²åå®æçå½ä»¤è¡è§£éå¨ã
- éç¨Cå è£ åºæ建çå ç½®æ ååºã
1.2 åºåæµè¯
ç¹å»æ¥çQuickJSåºåæµè¯å ·ä½å 容
2 ç¨æ³
2.1 å®è£
æä¾Makefileå¯ä»¥å¨Linuxæè MacOS/Xä¸ç¼è¯ãéè¿ä½¿ç¨MinGWå·¥å ·å¨Linux主æºä¸è¿è¡äº¤åç¼è¯ï¼å¯ä»¥è·å¾åæ¥çWindowsæ¯æã
å¦æè¦éæ©ç¹å®é项ï¼è¯·ç¼è¾Makefile
顶é¨ï¼ç¶åè¿è¡make
ã
使ç¨root身份æ§è¡ make install
å¯ä»¥å°ç¼è¯çäºè¿å¶æ件åæ¯ææ件å®è£
å° /usr/local
(è¿ä¸æ¯ä½¿ç¨QuickJSæå¿
éç).
**注**ï¼å¯ä»¥åèQuickJSä¸æå ³äºWindowsä¸ç¼è¯å®è£ åLinuxä¸ç¼è¯å®è£ ç¸å ³ææ¡£ã
2.2 å¿«éå ¥é¨
qjs
æ¯å½ä»¤è¡è§£æå¨ (Read-Eval-Print Loop). æ¨å¯ä»¥å°Javascriptæ件å/æ表达å¼ä½ä¸ºåæ°ä¼ é以æ§è¡å®ä»¬ï¼
./qjs examples/hello.js
qjsc
æ¯å½ä»¤è¡ç¼è¯å¨:
./qjsc -o hello examples/hello.js
./hello
çæä¸ä¸ªæ²¡æå¤é¨ä¾èµç hello
å¯æ§è¡æ件ã
qjsbn
å qjscbn
æ¯å
·ææ°å¦æ©å±çç¸åºè§£éå¨åç¼è¯å¨ï¼
./qjsbn examples/pi.js 1000
æ¾ç¤ºPIç1000ä½æ°å
./qjsbnc -o pi examples/pi.js
./pi 1000
ç¼è¯å¹¶æ§è¡PIç¨åºã
2.3 å½ä»¤è¡é项
2.3.1 qjs
解éå¨
ç¨æ³: qjs [options] [files]
é项:
-h
--help
é项å表ã
-e `EXPR`
--eval `EXPR`
æ§è¡EXPR.
-i
--interactive
转å°äº¤äºæ¨¡å¼ (å¨å½ä»¤è¡ä¸æä¾æ件æ¶ï¼å®ä¸æ¯é»è®¤æ¨¡å¼).
-m
--module
å 载为ES6模åï¼é»è®¤ä¸º.mjsæ件æ©å±åï¼ã
é«çº§é项å æ¬ï¼
-d
--dump
转åå å使ç¨æ åµç»è®¡ä¿¡æ¯ã
-q
--quit
åªæ¯å®ä¾å解éå¨å¹¶éåºã
2.3.2 qjsc
ç¼è¯å¨
ç¨æ³: qjsc [options] [files]
é项:
-c
ä» è¾åºCæ件ä¸çåèç ï¼é»è®¤æ¯è¾åºå¯æ§è¡æ件ã
-e
main()
Cæ件ä¸çè¾åºååèç ï¼é»è®¤æ¯è¾åºå¯æ§è¡æ件ã
-o output
设置è¾åºæ件åï¼é»è®¤= out.cæa.outï¼ã
-N cname
设置çææ°æ®çCå称ã
-m
ç¼è¯ä¸ºJavascript模åï¼é»è®¤ä¸º.mjsæ©å±åï¼ã
-M module_name[,cname]
æ·»å å¤é¨C模åçåå§å代ç ãæ¥çc_module
示ä¾ã
-x
åè交æ¢è¾åºï¼ä» ç¨äºäº¤åç¼è¯ï¼ã
-flto
使ç¨é¾æ¥æ¶é´ä¼åãç¼è¯é度è¾æ
¢ï¼ä½å¯æ§è¡æ件æ´å°æ´å¿«ã使ç¨é项æ¶ä¼èªå¨è®¾ç½®æ¤é项-fno-x
ã
-fno-[eval|string-normalize|regexp|json|proxy|map|typedarray|promise]
ç¦ç¨æéè¯è¨åè½ä»¥çæè¾å°çå¯æ§è¡æ件ã
2.4 qjscalc
åºç¨ç¨åº
该qjscalc
åºç¨ç¨åºæ¯qjsbn
å½ä»¤è¡è§£éå¨çè¶
éï¼å®å®ç°äºä¸ä¸ªå
·æä»»æ大æ´æ°åæµ®ç¹æ°ï¼åæ°ï¼å¤æ°ï¼å¤é¡¹å¼åç©éµçJavascript计ç®å¨ãæºä»£ç å¨qjscalc.jsä¸ãhttp://numcalc.comä¸æä¾äºæ´å¤ææ¡£åWebçæ¬ã
2.5 å ç½®æµè¯
è¿è¡make test
以è¿è¡QuickJSåæ¡£ä¸å
å«çä¸äºå
ç½®æµè¯ã
2.6 Test262 (ECMAScript æµè¯å¥ä»¶))
QuickJSåæ¡£ä¸å å«test262è¿è¡ç¨åºã
ä½ä¸ºåèï¼å®æ´çtest262æµè¯å¨æ¡£æ¡qjs-tests-yyyy-mm-dd.tar.xzä¸æä¾ãæ¨åªéå°å ¶è§£å缩å°QuickJSæºä»£ç ç®å½ä¸å³å¯ã
æè ï¼test262æµè¯å¯ä»¥å®è£ ï¼
git clone https://github.com/tc39/test262.git test262
cd test262
git checkout 94b1e80ab3440413df916cd56d29c5a2fa2ac451
patch -p1 < ../tests/test262.patch
cd ..
è¡¥ä¸æ·»å äºç¹å®äºå®ç°çharness
å½æ°ï¼å¹¶ä¼åäºä½æçRegExpå符类åUnicodeå±æ§è½¬ä¹æµè¯ï¼æµè¯æ¬èº«ä¸ä¼è¢«ä¿®æ¹ï¼åªææ
¢éå符串åå§åå½æ°è¢«ä¼åï¼ã
æµè¯å¯ä»¥è¿è¡
make test2
æå
³æ´å¤ä¿¡æ¯ï¼è¯·è¿è¡./run-test262
以æ¥çtest262 runnerçé项ãé
ç½®æ件test262.conf
并test262bn.conf
å
å«è¿è¡åç§æµè¯çé项ã
3 ææ¯è§è
3.1 è¯è¨æ¯æ
3.1.1 ES2019æ¯æ
å å«Annex B (éçWebå ¼å®¹)åUnicodeç¸å ³åè½çES2019è§è 2 å·²ç»åºæ¬æ¯æã ç®åå°æªæ¯æ以ä¸åè½:
- Realms (尽管C APIæ¯æä¸åçè¿è¡æ¶åä¸ä¸æ)
- Tail calls3
3.1.2 JSON
JSON解æå¨ç®åæ¯è§èæ¯æèå´æ´å®½.
3.1.3 ECMA402
ECMA402 (å½é åAPI)å°æªæ¯æ.
3.1.4 æ©å±
- æ令
"use strip"
ä¸ä¿çè°è¯ä¿¡æ¯ (å æ¬å½æ°æºä»£ç ) 以èçå åã"use strict"
æ令å¯ä»¥åºç¨å ¨å±èæ¬ï¼æè ç¹å®å½æ°ã - èæ¬å¼å¤´ç¬¬ä¸è¡
#!
ä¼è¢«å¿½ç¥ã
3.1.5 æ°å¦æ©å±
æ°å¦æ©å±å¨qjsbn
çæ¬ä¸å¯ç¨ï¼å¹¶ä¸å®å
¨ååå
¼å®¹æ åJavascript. æ¥çjsbignum.pdf
è·åæ´å¤ä¿¡æ¯ã
BigInt
(大æ´æ°) TC39å·²ç»æ¯æãBigFloat
æ¯æ: åºæ°2ä¸ä»»æ大浮ç¹æ°ã- è¿ç®ç¬¦éè½½ã
- æ令
"use bigint"
å¯ç¨bigint模å¼ï¼BigInt
é»è®¤æ åµä¸ä¸ºæ´æ°ã - æ令
"use math"
å¯ç¨æ°å¦æ¨¡å¼ï¼å ¶ä¸æ´æ°ä¸çé¤æ³åå¹è¿ç®ç¬¦äº§çåæ°ãBigFloaté»è®¤æ åµä¸ï¼æµ®ç¹æåæ¯é»è®¤å¼ï¼æ´æ°æ¯BigInté»è®¤å¼ã
3.2 模å
ES6模åå®å ¨æ¯æãé»è®¤å称解æè§åå¦ä¸ï¼
- 模åå称带æå导
.
æ..
æ¯ç¸å¯¹äºå½å模åçè·¯å¾ã - 模åå称没æå导
.
æ..
æ¯ç³»ç»æ¨¡åï¼ä¾å¦std
æos
ã - 模åå称以
.so
ç»å°¾ï¼æ¯ä½¿ç¨QuickJS C APIçåç模åã
3.3 æ ååº
é»è®¤æ
åµä¸ï¼æ ååºå
å«å¨å½ä»¤è¡è§£éå¨ä¸ã å®å
å«ä¸¤ä¸ªæ¨¡åstd
åos
以åä¸äºå
¨å±å¯¹è±¡.
3.3.1 å ¨å±å¯¹è±¡
scriptArgs
æä¾å½ä»¤è¡åæ°ã第ä¸ä¸ªåæ°æ¯èæ¬å称ã
print(...args)
æå°ç±ç©ºæ ¼åå°¾éæ¢è¡ç¬¦åéçåæ°ã
console.log(...args)
ä¸print()ç¸åã
3.3.2 std
模å
该std
模å为libcæä¾å
è£
å¨stdlib.håstdio.håå
¶ä»ä¸äºå®ç¨ç¨åºã
å¯ç¨åºå£ï¼
exit(n)
éåºè¿ç¨ã
evalScript(str)
å°å符串str
以èæ¬æ¹å¼è¿è¡ï¼å
¨å±evalï¼ã
loadScript(filename)
å°æ件filename
以èæ¬æ¹å¼è¿è¡ï¼å
¨å±evalï¼ã
Error(errno)
std.Error
æé å½æ°ã é误å®ä¾å
å«å段errno
ï¼é误代ç ï¼åmessage
ï¼std.Error.strerror(errno)
çç»æï¼ã
æé å½æ°å å«ä»¥ä¸å段ï¼
EINVAL
EIO
EACCES
EEXIST
ENOSPC
ENOSYS
EBUSY
ENOENT
EPERM
EPIPE
常è§é误çæ´æ°å¼ ï¼å¯ä»¥å®ä¹éå é误代ç ï¼ã
strerror(errno)
è¿åæè¿°é误çå符串errno
.
open(filename, flags)
æå¼ä¸ä¸ªæ件ï¼libcçå
è£
å¨fopen()
ï¼ãå¨I/Oé误æ¶æåº std.Error
tmpfile()
æå¼ä¸ä¸ªä¸´æ¶æ件ãå¨I/Oé误æ¶æåºstd.Error
ã
puts(str)
ç¸å½äºstd.out.puts(str)
.
printf(fmt, ...args)
ç¸å½äºstd.out.printf(fmt, ...args)
sprintf(fmt, ...args)
ç¸å½äºlibcçsprintf().
in
out
err
å
è£
libcæ件çstdin
, stdout
, stderr
.
SEEK_SET
SEEK_CUR
SEEK_END
seek()ç常é
global
å¼ç¨å ¨å±å¯¹è±¡ã
gc()
æå¨è°ç¨å¾ªç¯å é¤ç®æ³ã循ç¯ç§»é¤ç®æ³å¨éè¦æ¶èªå¨å¯å¨ï¼å æ¤è¯¥åè½å¨ç¹å®å åéå¶ææµè¯æ¶é常æç¨ã
getenv(name)
è¿åç¯å¢åéçå¼ name
ï¼ææªå®ä¹æ¶è¿å undefined
.
FILE ååï¼
close()
å ³éæ件ã
puts(str)
使ç¨UTF-8ç¼ç è¾åºå符串ã
printf(fmt, ...args)
æ ¼å¼åprintfï¼ä¸libc printfæ ¼å¼ç¸åã
flush()
å·æ°ç¼å²çæ件ã
seek(offset, whence)
寻æ¾ç¹å®æ件ä½ç½® (ä»åªéstd.SEEK_*
)ãå¨I/Oé误æ¶æåº std.Error
ã
tell()
è¿åå½åæ件ä½ç½®ã
eof()
å¦ææ件ç»æï¼åè¿åtrueã
fileno()
è¿åå ³èçOSå¥æã
read(buffer, position, length)
ä»æ件ä¸ä»¥åèä½ç½®position
ï¼è¯»ålength
åèå°ArrayBufferbuffer
ï¼libcçå
è£
å¨fread
ï¼ã
write(buffer, position, length)
å°ArrayBufferbuffer
ä¸ä»¥åèä½ç½®position
å¼å§çlength
åèåå
¥æ件 (libcçå
è£
å¨fread
).
getline()
è¿åæ件ä¸çä¸ä¸è¡ï¼å设为UTF-8ç¼ç ï¼ä¸å æ¬å°¾éæ¢è¡ç¬¦ã
getByte()
è¿åæ件ä¸çä¸ä¸ä¸ªåèã
putByte(c)
å°ä¸ä¸ªåèåå ¥æ件ã
3.3.3 os
模å
os
模åæä¾æä½ç³»ç»ç¹å®åè½ï¼
- åºå±æ件访é®
- ä¿¡å·
- 计æ¶å¨
- å¼æ¥ I/O
å¦ææ¯OKï¼OSå½æ°é常è¿å0ï¼æè OSè¿åç¹å®çé误代ç ã
å¯ç¨å¯¼åºå½æ°ï¼
open(filename, flags, mode = 0o666)
æå¼ä¸ä¸ªæ件ãå¦æé误ï¼è¿åå¥ææ<0ã
O_RDONLY
O_WRONLY
O_RDWR
O_APPEND
O_CREAT
O_EXCL
O_TRUNC
POSIXæå¼æ å¿ã
O_TEXT
(Windowsç¹å®)ã以ææ¬æ¨¡å¼æå¼æ件ãé»è®¤ä¸ºäºè¿å¶æ¨¡å¼ã
close(fd)
å
³éæ件å¥æfd
.
seek(fd, offset, whence)
寻æ¾æ件ãä½¿ç¨ std.SEEK_*
æ whence
.
read(fd, buffer, offset, length)
ä»æ件å¥æfd
ä¸ä»¥åèä½ç½®offset
å¼å§ï¼è¯»ålength
åèå°ArrayBufferbuffer
ãè¿å读åçåèæ°ï¼è¥åºç°é误åè¿åå°äº0çå¼ã
write(fd, buffer, offset, length)
å°ArrayBufferbuffer
ä¸ä»¥åèä½ç½®offset
å¼å§çlength
åèåå
¥æ件å¥æfd
ãè¿ååå
¥çåèæ°ï¼è¥åºç°é误åè¿åå°äº0çå¼ã
isatty(fd)
fd
æ¯ä¸ä¸ªTTY (ç»ç«¯)å¥æè¿å true
ã
ttyGetWinSize(fd)
è¿åTTYå¤§å° [width, height]
æè
å¦æä¸å¯ç¨è¿å null
ã
ttySetRaw(fd)
å¨åå§æ¨¡å¼ä¸è®¾ç½®TTYã
remove(filename)
å é¤æ件ãå¦ææ£å¸¸åè¿å0ï¼å¦æé误åè¿å<0
rename(oldname, newname)
éå½åæ件ãå¦ææ£å¸¸åè¿å0ï¼å¦æé误åè¿å<0
setReadHandler(fd, func)
å°è¯»å¤çç¨åºæ·»å å°æ件å¥æfd
ã fd
æ¯æ¬¡ææ°æ®å¾
å¢å å¤çæ¶è°ç¨func
ãæ¯ææ¯ä¸ªæ件å¥æçå个读å¤çç¨åºãä½¿ç¨ func = null
æ¥å é¤å¥æã
setWriteHandler(fd, func)
å°åå¤çç¨åºæ·»å å°æ件å¥æfd
ã fd
æ¯æ¬¡ææ°æ®å¾
åå
¥å¤çæ¶è°ç¨func
. æ¯ææ¯ä¸ªæ件å¥æä¸ä¸ªåå¤çç¨åºãä½¿ç¨ `func = nullæ¥å é¤å¥æã
signal(signal, func)
å½ä¿¡å· signal
åçæ¶è°ç¨ func
ã æ¯ä¸ªä¿¡å·ç¼å·åªæ¯æä¸ä¸ªå¤çç¨åºãä½¿ç¨ null
设å®çé»è®¤å¤çæ undefined
忽ç¥çä¿¡å·ã
SIGINT
SIGABRT
SIGFPE
SIGILL
SIGSEGV
SIGTERM
POSIX ä¿¡å·ç¼å·ã
setTimeout(func, delay)
å¨ delay
毫ç§ä¹åè°ç¨å½æ° func
ãè¿å计æ¶å¨çå¥æã
clearTimer(handle)
åæ¶è®¡æ¶å¨ã
platform
è¿å表示该平å°çåç¬¦ä¸²ï¼ "linux"
, "darwin"
, "win32"
or "js"
.
3.4 QuickJS C API
C APIç设计ç®åèææãC APIå¨quickjs.h
æ 头ä¸å®ä¹ã
3.4.1 è¿è¡æ¶åä¸ä¸æ
JSRuntime
表示ä¸å¯¹è±¡å 对åºçJavaScriptè¿è¡æ¶ãå¯ä»¥åæ¶åå¨å¤ä¸ªè¿è¡æ¶ï¼ä½å®ä»¬ä¸è½äº¤æ¢å¯¹è±¡ãå¨ç»å®çè¿è¡æ¶å
ï¼ä¸æ¯æå¤çº¿ç¨ã
JSContext
表示JavaScriptä¸ä¸æï¼æé¢åï¼ãæ¯ä¸ªJSContexté½æèªå·±çå
¨å±å¯¹è±¡åç³»ç»å¯¹è±¡ãå¨JSRuntimeä¸å¯ä»¥æå¤ä¸ªJSContextï¼å¹¶ä¸å®ä»¬å¯ä»¥å
±äº«å¯¹è±¡ï¼ç±»ä¼¼äºåä¸æºçæ¡æ¶å¨Webæµè§å¨ä¸å
±äº«JavaScript对象ã
3.4.2 JSValue
JSValue
表示ä¸ä¸ªJavaScriptå¼ï¼å¯ä»¥æ¯åå§ç±»åæ对象ã使ç¨å¼ç¨è®¡æ°ï¼å æ¤éè¦çæ¯æç¡®å¤å¶ï¼JS_DupValue()
ï¼å¢å å¼ç¨è®¡æ°ï¼æéæ¾ï¼JS_FreeValue()
ï¼åå°å¼ç¨è®¡æ°ï¼JSValuesã
3.4.3 Cå½æ°
使ç¨JS_NewCFunction()
å¯ä»¥å建Cå½æ°ãJS_SetPropertyFunctionList()
æ¯ä¸ç§ç®ä¾¿çæ¹æ³ï¼å¯å°å½æ°ã设置å¨åè·åå¨å±æ§è½»æ¾æ·»å å°ç»å®å¯¹è±¡ä¸ã
ä¸å
¶ä»åµå
¥å¼JavaScriptå¼æä¸åï¼QuickJS没æéå¼å æ ï¼å æ¤Cå½æ°å°å
¶åæ°ä½ä¸ºæ®éçCåæ°ä¼ éãä¸è¬è§åæ¯ï¼Cå½æ°å°JSValue
ä½ä¸ºåæ°ï¼å æ¤å®ä»¬ä¸éè¦éæ¾ï¼ï¼å¹¶è¿åä¸ä¸ªæ°åé
çï¼æ´»å¨çï¼JSValue
ã
3.4.4 é误å¼å¸¸
å¼å¸¸ï¼å¤§å¤æ°Cå½æ°å¯ä»¥è¿åä¸ä¸ªJavascriptå¼å¸¸ãå¿
é¡»éè¿C代ç æç¡®æµè¯åå¤çå®ãç¹å®çJSValue
ï¼å³JS_EXCEPTION
ï¼è¡¨ç¤ºåçäºå¼å¸¸ãå®é
çå¼å¸¸å¯¹è±¡åå¨å¨JSContext
ä¸ï¼å¯ä»¥ä½¿ç¨JS_GetException()
æ£ç´¢å°ã
3.4.5 Script代ç æ§è¡
使ç¨JS_Eval()
æ¥è¯ä¼°èæ¬æ模åæºä»£ç ã
å¦æèæ¬æ模åå·²ç»ä½¿ç¨qjsc
ç¼è¯æåèç ï¼é£ä¹ä½¿ç¨JS_EvalBinary()
å¯ä»¥å®ç°ç¸åçç»æãä¼ç¹æ¯ä¸éè¦ç¼è¯ï¼å æ¤é度æ´å¿«ãä½ç§¯æ´å°ï¼å 为å¦æä¸éè¦eval
ï¼ç¼è¯å¨å¯ä»¥ä»å¯æ§è¡æ件ä¸å é¤ã
注æï¼åèç æ ¼å¼ä¸ç¹å®çQuickJSçæ¬ç¸å
³èãæ¤å¤ï¼å¨æ§è¡ä¹å没æè¿è¡å®å
¨æ£æ¥ãå æ¤ï¼åèç ä¸åºä»ä¸åä¿¡ä»»çæ¥æºå è½½ãè¿å°±æ¯ä¸ºä»ä¹qjsc
ä¸æ²¡æå°åèç è¾åºå°äºè¿å¶æ件çé项ã
3.4.6 JSç±»
å¯ä»¥å°Cçä¸éææ°æ®éå å°JavaScript对象ä¸ãCä¸éææ°æ®çç±»åç±å¯¹è±¡çç±»IDï¼JSClassID
ï¼ç¡®å®ãå æ¤ï¼ç¬¬ä¸æ¥æ¯æ³¨åä¸ä¸ªæ°çç±»IDåJSç±»ï¼JS_NewClassID()
ãJS_NewClass()
ï¼ãç¶åï¼å¯ä»¥ä½¿ç¨JS_NewObjectClass()
å建该类ç对象ï¼å¹¶ä½¿ç¨JS_GetOpaque()
/JS_SetOpaque()
è·åæ设置Cçä¸éææéã
å¨å®ä¹æ°çJSç±»æ¶ï¼å¯ä»¥å£°æä¸ä¸ªææå½æ°ï¼å¨å¯¹è±¡éæ¯æ¶è°ç¨è¯¥å½æ°ãå¯ä»¥æä¾ä¸ä¸ªgc_mark
æ¹æ³ï¼ä»¥ä¾¿å¾ªç¯ç§»é¤ç®æ³å¯ä»¥æ¾å°è¢«è¯¥å¯¹è±¡å¼ç¨çå
¶ä»å¯¹è±¡ãè¿æå
¶ä»æ¹æ³å¯ç¨äºå®ä¹å¼ç±»å¯¹è±¡è¡ä¸ºã
ç±»IDå¨å
¨å±èå´å
åé
ï¼å³éç¨äºææè¿è¡æ¶ï¼ãJSClasså¨æ¯ä¸ªJSRuntime
ä¸åé
ãJS_SetClassProto()
ç¨äºå¨ç»å®JSContext
ä¸ä¸ºç»å®ç±»å®ä¹ååãJS_NewObjectClass()
å¨å建ç对象ä¸è®¾ç½®æ¤ååã
å¨js_libc.cä¸æä¾äºç¤ºä¾ã
3.4.7 C模å
æ¯æå¨ææè éæé¾æ¥çåçES6模åãæ¥çtest_bjsonåbjson.so示ä¾ãæ ååºjs_libc.cä¹æ¯åç模åå¾å¥½çä¸ä¸ªä¾åã
3.4.8 å åå¤ç
ä½¿ç¨ JS_SetMemoryLimit()
为ç»å®çJSRuntime设置å
¨å±å
ååé
éå¶ã
JS_NewRuntime2()
å¯ä»¥æä¾èªå®ä¹å
ååé
åè½ã
JS_SetMaxStackSize()
å¯ä»¥ä½¿ç¨è®¾ç½®æ大系ç»å æ 大å°
3.4.9 æ§è¡è¶ æ¶åä¸æ
使ç¨JS_SetInterruptHandler()
æ¥è®¾ç½®ä¸ä¸ªåè°å½æ°ï¼å½å¼ææ§è¡ä»£ç æ¶ï¼å®ä¼å®æè°ç¨è¯¥åè°å½æ°ã该åè°å½æ°å¯ä»¥ç¨äºå®ç°æ§è¡è¶
æ¶ã
å½ä»¤è¡è§£éå¨ä½¿ç¨å®æ¥å®ç° Ctrl-C
å¤çç¨åºã
4 å é¨å®ç°
4.1 Bytecode
ç¼è¯å¨ç´æ¥çæåèç ï¼æ²¡æä¸é´è¡¨ç¤ºï¼å¦è§£ææ ï¼ï¼å æ¤é常快éãå¨çæçåèç ä¸è¿è¡äºå¤ä¸ªä¼åæ¥éª¤ã
éæ©äºåºäºå æ çåèç ï¼å 为å®ç®åä¸çæç代ç ç´§åã
对äºæ¯ä¸ªå½æ°ï¼ç¼è¯æ¶è®¡ç®æ大å æ 大å°ï¼å æ¤ä¸éè¦è¿è¡æ¶å æ 溢åºæµè¯ã
为è°è¯ä¿¡æ¯ç»´æ¤äºä¸ä¸ªåç¬çå缩è¡å·è¡¨ã
对éå åéç访é®è¿è¡äºä¼åï¼å¹¶ä¸å ä¹ä¸å±é¨åéä¸æ ·å¿«ã
å¯¹ä¸¥æ ¼æ¨¡å¼ä¸çç´æ¥eval
è¿è¡äºä¼åã
4.2 Executable generation
4.2.1 qjsc
ç¼è¯å¨
qjsc
ç¼è¯å¨ä»Javascriptæ件çæCæºä»£ç ãé»è®¤æ
åµä¸ï¼Cæºä»£ç 使ç¨ç³»ç»ç¼è¯å¨ï¼gcc
æclang
ï¼è¿è¡ç¼è¯ã
çæçCæºä»£ç å
å«å·²ç¼è¯å½æ°æ模åçåèç ãå¦æéè¦å®æ´çå¯æ§è¡æ件ï¼å®è¿å
å«ä¸ä¸ªmain()
å½æ°ï¼å
¶ä¸å
å«å¿
è¦çC代ç æ¥åå§åJavascriptå¼æï¼å¹¶å è½½åæ§è¡å·²ç¼è¯çå½æ°å模åã
å¯ä»¥å°Javascript代ç ä¸C模åæ··å使ç¨ã
为äºçææ´å°çå¯æ§è¡æ件ï¼å¯ä»¥ç¦ç¨ç¹å®çJavascriptåè½ï¼ç¹å«æ¯eval
ææ£å表达å¼ã代ç å é¤ä¾èµäºç³»ç»ç¼è¯å¨çé¾æ¥æ¶ä¼åã
4.2.2 äºè¿å¶ JSON
qjsc
éè¿ç¼è¯èæ¬æ模åï¼ç¶åå°å®ä»¬åºåå为äºè¿å¶æ ¼å¼æ¥å·¥ä½ãè¯¥æ ¼å¼çä¸ä¸ªåéï¼ä¸å
æ¬å½æ°æ模åï¼å¯ä»¥ç¨ä½äºè¿å¶JSONã示ä¾test_bjson.js
å±ç¤ºäºå¦ä½ä½¿ç¨å®ã
è¦åï¼äºè¿å¶JSONæ ¼å¼å¯è½ä¼å¨ä¸ç»éç¥çæ
åµä¸æ´æ¹ï¼å æ¤ä¸åºå°å
¶ç¨äºåå¨æä¹
æ°æ®ãtest_bjson.js
示ä¾ä»
ç¨äºæµè¯äºè¿å¶å¯¹è±¡æ ¼å¼çå½æ°ã
4.3 è¿è¡æ¶
4.3.1 Strings
å符串åå¨ä¸º8ä½æ16ä½å符æ°ç»ãå æ¤ï¼éæºè®¿é®å符æ»æ¯å¾å¿«ã
C APIæä¾å°Javascriptå符串转æ¢ä¸ºC UTF-8ç¼ç å符串çå½æ°ãæ常è§æ åµæ¯ Javascriptåç¬¦ä¸²ä» å å«ASCII å符串ä¸æ¶åå¤å¶ã
4.3.2 Objects
对象形ç¶ï¼å¯¹è±¡ååãå±æ§å称åæ å¿ï¼å¨å¯¹è±¡ä¹é´å ±äº«ï¼ä»¥èçå åã
ä¼åäºæ²¡ææ´ï¼é¤äºæ°ç»æ«å°¾ï¼çæ°ç»ã
TypedArray访é®å·²ä¼åã
4.3.3 Atoms
对象å±æ§å称åä¸äºå符串被åå¨ä¸ºååï¼å¯ä¸å符串ï¼ï¼ä»¥èçå å并å 许快éæ¯è¾ãåå表示为32ä½æ´æ°ãååèå´çä¸åä¿çç»ä» 0 å° 2^{31}-1 çç«å³æ´æ°åé¢å¼ã
4.3.4 Numbers
æ°åå¯ä»¥è¡¨ç¤ºä¸º32ä½æ符å·æ´æ°æ64ä½IEEE-754æµ®ç¹æ°å¼ã大å¤æ°æä½é½é对32ä½æ´æ°æ åµæå¿«éè·¯å¾ã
4.3.5 åå¾åæ¶
å¼ç¨è®¡æ°ç¨äºèªå¨ååç¡®å°éæ¾å¯¹è±¡ãå½åé çå ååå¾è¿å¤§æ¶ï¼ä¼è¿è¡åç¬ç循ç¯ç§»é¤æä½ã循ç¯ç§»é¤ç®æ³ä» 使ç¨å¼ç¨è®¡æ°å对象å 容ï¼å æ¤å¨C代ç ä¸ä¸éè¦æ¾å¼æä½åå¾æ¶éæ ¹ã
4.3.6 JSValue
JSValueæ¯ä¸ä¸ªJavascriptå¼ï¼å¯ä»¥æ¯åå§ç±»åï¼ä¾å¦NumberãStringçï¼æ对象ãå¨32ä½çæ¬ä¸ï¼ä½¿ç¨NaNè£ ç®±æ¥åå¨64ä½æµ®ç¹æ°ã表示形å¼ç»è¿ä¼åï¼å¯ä»¥é«æå°æµè¯32ä½æ´æ°åå¼ç¨è®¡æ°å¼ã
å¨64ä½ä»£ç ä¸ï¼JSValueç大å°ä¸º128ä½ï¼å¹¶ä¸ä¸ä½¿ç¨NaNè£ ç®±ãåå æ¯å¨64ä½ä»£ç ä¸ï¼å å使ç¨ä¸é£ä¹å ³é®ã
å¨ä¸¤ç§æ åµä¸ï¼32ä½æ64ä½ï¼ï¼JSValueæ°å¥½éåºä¸¤ä¸ªCPUå¯åå¨ï¼å æ¤å¯ä»¥éè¿Cå½æ°é«æå°è¿åã
4.3.7 å½æ°è°ç¨
å¼æå·²ç»è¿ä¼åï¼å æ¤å½æ°è°ç¨å¾å¿«ãç³»ç»å æ å å«Javascriptåæ°åå±é¨åéã
4.4 RegExp
å¼åäºä¸ä¸ªç¹å®çæ£å表达å¼å¼æãå®æ¢å°åé«æï¼å¹¶æ¯æææES2019åè½ï¼å æ¬Unicodeå±æ§ãä½ä¸ºJavascriptç¼è¯å¨ï¼å®ç´æ¥çæ没æ解ææ çåèç ã
使ç¨æ¾å¼å æ çå溯使å¾ç³»ç»å æ ä¸æ²¡æéå½ãç®åçéåå¨ç»è¿ä¸é¨ä¼åï¼ä»¥é¿å éå½ã
æ¥èªå ·æ空项çéåå¨çæ ééå½è¢«é¿å ã
å®æ´çæ£å表达å¼æ件åºçæé约为15 KiBï¼x86代ç ï¼ï¼ä¸å æ¬Unicodeåºã
4.5 Unicode
å¼åäºä¸ä¸ªç¹å®çUnicodeåºï¼å æ¤ä¸ä¾èµäºå¤é¨å¤§åUnicodeåºï¼ä¾å¦ICUãå缩ææUnicode表ï¼åæ¶ä¿æåçç访é®é度ã
该åºæ¯æ大å°å转æ¢ï¼Unicodeè§èåï¼Unicodeèæ¬æ¥è¯¢ï¼Unicode常è§ç±»å«æ¥è¯¢åææUnicodeäºè¿å¶å±æ§ã
å®æ´çUnicodeåºå¤§çº¦éé为45 KiBï¼x86代ç ï¼ã
4.6 BigInt å BigFloat
BigInt å BigFloat æ¯ç¨libbf
åº libbf
åºå®ç°ç4ã å®å¤§æ¦æ60 KiB (x86 代ç ) 并æä¾ä»»æ精度çIEEE 754 æµ®ç¹è¿ç®åå
·æ精确èå
¥çè¶
è¶å½æ°ã
5 许å¯åè®®
QuickJS å¨MITåè®®ä¸åå¸ã
é¤éå¦æ说æï¼å¦åQuickJSæ¥æºççæå½Fabrice BellardåCharlie Gordonææã
è注
(1)
https://github.com/tc39/test262
(2)
https://tc39.github.io/ecma262/
(3)
æ们认为ç®åçå°¾é¨è°ç¨è§èè¿äºå¤æï¼å¹¶ä¸å®é å©çæéã
(4)
6 ç¸å ³é¡¹ç®
-
QuickJS-iOS iOSä¸çQuickJSåº
-
QuickJS-Android Androidä¸çQuickJSåº
-
quickjs-rs RustçQuickJSåº
-
quickjspp C++çQuickJSåº
-
go-quickjs GoçQuickJSåº
-
txiki.js The tiny JavaScript runtime built with QuickJS, libuv and â¤ï¸
-
QuickJS-Pascal Quickjs FreePascal / Delphi Bindings
Top Related Projects
Public repository of the QuickJS Javascript Engine.
Safely execute untrusted Javascript in your Javascript, and execute synchronous code that uses async functions
A tiny JavaScript runtime
Rust bindings for the V8 JavaScript engine
Ultra-lightweight JavaScript engine for the Internet of Things.
Embedded JavaScript engine for C/C++
Convert
designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot