|
| 1 | +# QuickJS |
| 2 | + |
| 3 | +QuickJS is a small and embeddable Javascript engine written in C89. Binary file is only about 1Mb. |
| 4 | +It was created by Charlie Gordon and Fabrice Bellard creator of FFMPEG and QEMU. |
| 5 | +It supports the ES2020 specification including modules, asynchronous generators, proxies and BigInt. |
| 6 | +It optionally supports mathematical extensions such as big decimal floating point numbers (BigDecimal), big binary floating point numbers (BigFloat) and operator overloading. |
| 7 | + |
| 8 | +Official site: https://bellard.org/quickjs/ |
| 9 | + |
| 10 | +The main documentation is in doc/quickjs.pdf or doc/quickjs.html. |
| 11 | + |
| 12 | +### Main Features: |
| 13 | + |
| 14 | +- Small and easily embeddable: just a few C files, no external dependency, 210 KiB of x86 code for a simple hello world program. |
| 15 | +- Fast interpreter with very low startup time: runs the 75000 tests of the ECMAScript Test Suite in about 100 seconds on a single core of a desktop PC. The complete life cycle of a runtime instance completes in less than 300 microseconds. |
| 16 | +- Almost complete ES2020 support including modules, asynchronous generators and full Annex B support (legacy web compatibility). |
| 17 | +- Passes nearly 100% of the ECMAScript Test Suite tests when selecting the ES2020 features. A summary is available at Test262 Report. |
| 18 | +- Can compile Javascript sources to executables with no external dependency. |
| 19 | +- Garbage collection using reference counting (to reduce memory usage and have deterministic behavior) with cycle removal. |
| 20 | +- Mathematical extensions: BigDecimal, BigFloat, operator overloading, bigint mode, math mode. |
| 21 | +- Command line interpreter with contextual colorization implemented in Javascript. |
| 22 | +- Small built-in standard library with C library wrappers. |
| 23 | + |
| 24 | + |
| 25 | +----------- |
| 26 | + |
| 27 | +### How Build: |
| 28 | + |
| 29 | +##### 1. Download and install MSYS2 in C:\msys64 |
| 30 | +"msys2-x86_64-20220128.exe" |
| 31 | +https://www.msys2.org/ |
| 32 | + |
| 33 | +##### 2. Run msys2.exe |
| 34 | + |
| 35 | +##### 3. Install mingw |
| 36 | +Execute in msys: |
| 37 | +```sh |
| 38 | +pacman -Syu |
| 39 | +pacman -Su |
| 40 | +pacman -S --needed base-devel mingw-w64-x86_64-toolchain |
| 41 | +pacman -S mingw-w64-x86_64-gcc mingw-w64-x86_64-make mingw-w64-x86_64-dlfcn |
| 42 | +echo "#! /bin/sh" > /mingw64/bin/make |
| 43 | +echo "\"mingw32-make\" \"\$@\"" >> /mingw64/bin/make |
| 44 | +``` |
| 45 | + |
| 46 | +##### 4. Add to variable PATH |
| 47 | +```sh |
| 48 | +C:\msys64\mingw64\bin |
| 49 | +C:\msys64\usr\bin |
| 50 | +``` |
| 51 | + |
| 52 | +##### 5. Clone this repository |
| 53 | +```sh |
| 54 | +git clone https://github.com/Gurigraphics/quickjs.git |
| 55 | +``` |
| 56 | + |
| 57 | +##### 6. Build: Run in CMD |
| 58 | +```sh |
| 59 | +cd quickjs |
| 60 | +make LDEXPORT="-static -s" |
| 61 | +``` |
| 62 | +Files: qjs.exe | qjsc.exe | run-test262.exe |
| 63 | + |
| 64 | + ----------- |
| 65 | + |
| 66 | +### Hello World Binary File |
| 67 | + |
| 68 | +Create file: **hello.js** |
| 69 | +```js |
| 70 | +console.log( "Hello world" ) |
| 71 | +``` |
| 72 | + |
| 73 | +Compile file: **hello.js** to: **hello.c** |
| 74 | +```sh |
| 75 | +qjsc -e -o hello.c hello.js |
| 76 | +``` |
| 77 | + |
| 78 | +Compile file: **hello.c** to **hello.exe** |
| 79 | +```sh |
| 80 | +gcc -D_GNU_SOURCE -I./ -o hello hello.c -static -s -L./ -lquickjs -lm -ldl -lpthread |
| 81 | +``` |
| 82 | + |
| 83 | +### How Run a Module File |
| 84 | + |
| 85 | +Create file: **data.js** |
| 86 | +```js |
| 87 | +export const hello = "Hello World"; |
| 88 | +``` |
| 89 | + |
| 90 | +Create file: **example.js** |
| 91 | +```js |
| 92 | +import { hello } from "data.js" |
| 93 | +console.log( hello ) |
| 94 | +``` |
| 95 | + |
| 96 | +Execute |
| 97 | +```sh |
| 98 | +qjs -m example.js |
| 99 | +``` |
| 100 | + |
| 101 | + ----------- |
| 102 | + |
| 103 | +### Outher Examples |
| 104 | + |
| 105 | +Edit file: **example.js** |
| 106 | +```js |
| 107 | +import * as std from "std"; |
| 108 | +import * as os from "os"; |
| 109 | + |
| 110 | +var func = (value) => { |
| 111 | + std.printf(os.platform) // win32 |
| 112 | +} |
| 113 | +func("name") |
| 114 | +``` |
| 115 | +Execute |
| 116 | +```sh |
| 117 | +qjs -m example.js |
| 118 | +``` |
| 119 | + |
| 120 | +----------- |
| 121 | + |
| 122 | +### Create a C Module Example |
| 123 | +Create file: **my_module.js** |
| 124 | +```js |
| 125 | +import * as myModule from 'my_module' |
| 126 | + |
| 127 | +const value = myModule.plus(1, 2) |
| 128 | +console.log("Result:", value) |
| 129 | + |
| 130 | +// Output => Result: 3 |
| 131 | +``` |
| 132 | + |
| 133 | +Create file: **my_module.c** |
| 134 | +```c |
| 135 | +#include "quickjs.h" |
| 136 | +#include "cutils.h" |
| 137 | + |
| 138 | +static JSValue plusNumbers(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) |
| 139 | +{ |
| 140 | + int a, b; |
| 141 | + |
| 142 | + if (JS_ToInt32(ctx, &a, argv[0])) |
| 143 | + return JS_EXCEPTION; |
| 144 | + |
| 145 | + if (JS_ToInt32(ctx, &b, argv[1])) |
| 146 | + return JS_EXCEPTION; |
| 147 | + |
| 148 | + return JS_NewInt32(ctx, a + b); |
| 149 | +} |
| 150 | + |
| 151 | +static const JSCFunctionListEntry js_my_module_funcs[] = { |
| 152 | + JS_CFUNC_DEF("plus", 2, plusNumbers), |
| 153 | +}; |
| 154 | + |
| 155 | +static int js_my_module_init(JSContext *ctx, JSModuleDef *m) |
| 156 | +{ |
| 157 | + return JS_SetModuleExportList(ctx, m, js_my_module_funcs, countof(js_my_module_funcs)); |
| 158 | +} |
| 159 | + |
| 160 | +JSModuleDef *js_init_module_my_module(JSContext *ctx, const char *module_name) |
| 161 | +{ |
| 162 | + JSModuleDef *m; |
| 163 | + m = JS_NewCModule(ctx, module_name, js_my_module_init); |
| 164 | + |
| 165 | + if (!m) |
| 166 | + return NULL; |
| 167 | + |
| 168 | + JS_AddModuleExportList(ctx, m, js_my_module_funcs, countof(js_my_module_funcs)); |
| 169 | + return m; |
| 170 | +} |
| 171 | +``` |
| 172 | +
|
| 173 | +Generate file: **my_module.o** |
| 174 | +```sh |
| 175 | +gcc -c my_module.c |
| 176 | +``` |
| 177 | + |
| 178 | +Add to "lib objects list" in Makefile |
| 179 | +```sh |
| 180 | +QJS_LIB_OBJS= ... $(OBJDIR)/my_module.o |
| 181 | +``` |
| 182 | + |
| 183 | +Add **my_module** to file **qjsc.c**. After "std" and "os" modules |
| 184 | +```sh |
| 185 | +/* add system modules */ |
| 186 | +namelist_add(&cmodule_list, "std", "std", 0); |
| 187 | +namelist_add(&cmodule_list, "os", "os", 0); |
| 188 | +// our module |
| 189 | +namelist_add(&cmodule_list, "my_module", "my_module", 0); |
| 190 | +``` |
| 191 | + |
| 192 | +Generate a new compiler **qjsc.exe** |
| 193 | +```sh |
| 194 | +make qjsc LDEXPORT="-static -s" |
| 195 | +``` |
| 196 | + |
| 197 | +Generate file: **my_module_js.c** |
| 198 | +```sh |
| 199 | +qjsc -e -m -o my_module_js.c my_module.js |
| 200 | +``` |
| 201 | + |
| 202 | +Generate file: **my_module.exe** |
| 203 | +```sh |
| 204 | +gcc -D_GNU_SOURCE -I./ -o my_module my_module_js.c -static -s -L./ -lquickjs -lm -ldl -lpthread |
| 205 | +``` |
| 206 | + |
| 207 | + |
| 208 | + |
| 209 | +### References |
| 210 | +| File | Repository | |
| 211 | +| ------ | ------ | |
| 212 | +| Makefile - Windows 64bits | https://github.com/mengmo/QuickJS-Windows-Build | |
| 213 | +| Writing native modules in C for QuickJS engine | https://calbertts.medium.com/writing-native-modules-in-c-for-quickjs-engine-49043587f2e2 | |
| 214 | + |
| 215 | + |
| 216 | +----------- |
| 217 | + |
| 218 | +## License |
| 219 | +MIT |
| 220 | + |
| 221 | + |
| 222 | + |
0 commit comments