@react-native-quickjs/quickjs 1.0.0-alpha.1 → 1.0.0-alpha.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +173 -15
- package/README.md +17 -0
- package/ReactNativeQuickJS.podspec +13 -1
- package/android/CMakeLists.txt +6 -0
- package/android/build.gradle +33 -6
- package/bin/qjsc/darwin-arm64/qjsc +0 -0
- package/bin/qjsc/darwin-x64/qjsc +0 -0
- package/bin/qjsc/linux-arm64/qjsc +0 -0
- package/bin/qjsc/linux-x64/qjsc +0 -0
- package/bin/qjsc/win32-x64/qjsc.exe +0 -0
- package/cmake/quickjs.cmake +9 -0
- package/engine/quickjs-rel/MANIFEST.json +118 -13
- package/engine/quickjs-rel/builtin-array-fromasync.h +100 -92
- package/engine/quickjs-rel/builtin-iterator-zip-keyed.h +288 -273
- package/engine/quickjs-rel/builtin-iterator-zip.h +293 -276
- package/engine/quickjs-rel/libregexp-backtrack.c.inc +583 -0
- package/engine/quickjs-rel/libregexp.c +1021 -573
- package/engine/quickjs-rel/libregexp.h +54 -2
- package/engine/quickjs-rel/libunicode-table.h +71 -84
- package/engine/quickjs-rel/libunicode.c +5 -0
- package/engine/quickjs-rel/quickjs-opcode.h +15 -6
- package/engine/quickjs-rel/quickjs.c +6581 -734
- package/engine/quickjs-rel/quickjs.h +43 -9
- package/package.json +15 -3
- package/src/runtime/QuickJSRuntime.cpp +18 -5
|
@@ -184,6 +184,7 @@ enum {
|
|
|
184
184
|
JS_TAG_SYMBOL = -8,
|
|
185
185
|
JS_TAG_STRING = -7,
|
|
186
186
|
JS_TAG_STRING_ROPE = -6,
|
|
187
|
+
JS_TAG_LAZY_JSON = -4, /* internal, immediate lazy JSON tape-node index */
|
|
187
188
|
JS_TAG_MODULE = -3, /* used internally */
|
|
188
189
|
JS_TAG_FUNCTION_BYTECODE = -2, /* used internally */
|
|
189
190
|
JS_TAG_OBJECT = -1,
|
|
@@ -396,7 +397,9 @@ static inline bool JS_VALUE_IS_NAN(JSValue v)
|
|
|
396
397
|
#define JS_VALUE_IS_BOTH_INT(v1, v2) ((JS_VALUE_GET_TAG(v1) | JS_VALUE_GET_TAG(v2)) == 0)
|
|
397
398
|
#define JS_VALUE_IS_BOTH_FLOAT(v1, v2) (JS_TAG_IS_FLOAT64(JS_VALUE_GET_TAG(v1)) && JS_TAG_IS_FLOAT64(JS_VALUE_GET_TAG(v2)))
|
|
398
399
|
|
|
399
|
-
#define JS_VALUE_HAS_REF_COUNT(v)
|
|
400
|
+
#define JS_VALUE_HAS_REF_COUNT(v) \
|
|
401
|
+
(JS_VALUE_GET_TAG(v) != JS_TAG_LAZY_JSON && \
|
|
402
|
+
(unsigned)JS_VALUE_GET_TAG(v) >= (unsigned)JS_TAG_FIRST)
|
|
400
403
|
|
|
401
404
|
/* special values */
|
|
402
405
|
#define JS_NULL JS_MKVAL(JS_TAG_NULL, 0)
|
|
@@ -509,6 +512,8 @@ typedef struct JSGCObjectHeader JSGCObjectHeader;
|
|
|
509
512
|
JS_EXTERN JSRuntime *JS_NewRuntime(void);
|
|
510
513
|
/* info lifetime must exceed that of rt */
|
|
511
514
|
JS_EXTERN void JS_SetRuntimeInfo(JSRuntime *rt, const char *info);
|
|
515
|
+
/* QJS_JSON_LAZY=0/1 remains available as a process-level test override. */
|
|
516
|
+
JS_EXTERN void JS_SetJSONLazyEnabled(JSRuntime *rt, bool enabled);
|
|
512
517
|
/* use 0 to disable memory limit */
|
|
513
518
|
JS_EXTERN void JS_SetMemoryLimit(JSRuntime *rt, size_t limit);
|
|
514
519
|
JS_EXTERN void JS_SetDumpFlags(JSRuntime *rt, uint64_t flags);
|
|
@@ -710,7 +715,6 @@ JS_EXTERN void *js_malloc(JSContext *ctx, size_t size);
|
|
|
710
715
|
JS_EXTERN void js_free(JSContext *ctx, void *ptr);
|
|
711
716
|
JS_EXTERN void *js_realloc(JSContext *ctx, void *ptr, size_t size);
|
|
712
717
|
JS_EXTERN size_t js_malloc_usable_size(JSContext *ctx, const void *ptr);
|
|
713
|
-
JS_EXTERN void *js_realloc2(JSContext *ctx, void *ptr, size_t size, size_t *pslack);
|
|
714
718
|
JS_EXTERN void *js_mallocz(JSContext *ctx, size_t size);
|
|
715
719
|
JS_EXTERN char *js_strdup(JSContext *ctx, const char *str);
|
|
716
720
|
JS_EXTERN char *js_strndup(JSContext *ctx, const char *s, size_t n);
|
|
@@ -1196,10 +1200,24 @@ JS_EXTERN JSValue JS_ParseJSON(JSContext *ctx, const char *buf, size_t buf_len,
|
|
|
1196
1200
|
JS_EXTERN JSValue JS_JSONStringify(JSContext *ctx, JSValueConst obj,
|
|
1197
1201
|
JSValueConst replacer, JSValueConst space0);
|
|
1198
1202
|
|
|
1199
|
-
|
|
1203
|
+
/* Manages the backing memory of an externally created ArrayBuffer.
|
|
1204
|
+
When 'size' is zero, 'ptr' must be freed and NULL returned. Otherwise the
|
|
1205
|
+
block must be resized to 'size' bytes and the new pointer returned, or NULL
|
|
1206
|
+
if that is not possible, indicating a memory error, in which case 'ptr' must
|
|
1207
|
+
stay valid and the ArrayBuffer keeps its current size. */
|
|
1208
|
+
typedef void *JSReallocArrayBufferDataFunc(JSRuntime *rt, void *opaque,
|
|
1209
|
+
void *ptr, size_t size);
|
|
1210
|
+
/* Creates an ArrayBuffer backed by 'buf'. Pass a zero 'max_len' for a regular,
|
|
1211
|
+
fixed length ArrayBuffer; a non-zero 'max_len' makes it resizable and is its
|
|
1212
|
+
maxByteLength. 'realloc_func' may be NULL if the memory must not be managed
|
|
1213
|
+
by quickjs at all; such an ArrayBuffer can neither be resized nor
|
|
1214
|
+
transferred to a different length. It is required for resizable
|
|
1215
|
+
ArrayBuffers, except for SharedArrayBuffers: those commit their maximum size
|
|
1216
|
+
upfront and therefore need 'buf' to be at least 'max_len' bytes big. */
|
|
1200
1217
|
JS_EXTERN JSValue JS_NewArrayBuffer(JSContext *ctx, uint8_t *buf, size_t len,
|
|
1201
|
-
|
|
1202
|
-
|
|
1218
|
+
size_t max_len,
|
|
1219
|
+
JSReallocArrayBufferDataFunc *realloc_func,
|
|
1220
|
+
void *opaque, bool is_shared);
|
|
1203
1221
|
JS_EXTERN JSValue JS_NewArrayBufferCopy(JSContext *ctx, const uint8_t *buf, size_t len);
|
|
1204
1222
|
JS_EXTERN void JS_DetachArrayBuffer(JSContext *ctx, JSValueConst obj);
|
|
1205
1223
|
JS_EXTERN uint8_t *JS_GetArrayBuffer(JSContext *ctx, size_t *psize, JSValueConst obj);
|
|
@@ -1232,8 +1250,8 @@ JS_EXTERN JSValue JS_GetTypedArrayBuffer(JSContext *ctx, JSValueConst obj,
|
|
|
1232
1250
|
size_t *pbyte_length,
|
|
1233
1251
|
size_t *pbytes_per_element);
|
|
1234
1252
|
JS_EXTERN JSValue JS_NewUint8Array(JSContext *ctx, uint8_t *buf, size_t len,
|
|
1235
|
-
|
|
1236
|
-
bool is_shared);
|
|
1253
|
+
JSReallocArrayBufferDataFunc *realloc_func,
|
|
1254
|
+
void *opaque, bool is_shared);
|
|
1237
1255
|
/* returns -1 if not a typed array otherwise return a JSTypedArrayEnum value */
|
|
1238
1256
|
JS_EXTERN int JS_GetTypedArrayType(JSValueConst obj);
|
|
1239
1257
|
JS_EXTERN JSValue JS_NewUint8ArrayCopy(JSContext *ctx, const uint8_t *buf, size_t len);
|
|
@@ -1254,10 +1272,14 @@ typedef enum JSPromiseStateEnum {
|
|
|
1254
1272
|
} JSPromiseStateEnum;
|
|
1255
1273
|
|
|
1256
1274
|
JS_EXTERN JSValue JS_NewPromiseCapability(JSContext *ctx, JSValue *resolving_funcs);
|
|
1275
|
+
JS_EXTERN JSValue JS_PromiseThen(JSContext *ctx, JSValueConst promise,
|
|
1276
|
+
JSValueConst on_fulfilled,
|
|
1277
|
+
JSValueConst on_rejected);
|
|
1257
1278
|
JS_EXTERN JSPromiseStateEnum JS_PromiseState(JSContext *ctx,
|
|
1258
1279
|
JSValueConst promise);
|
|
1259
1280
|
JS_EXTERN JSValue JS_PromiseResult(JSContext *ctx, JSValueConst promise);
|
|
1260
1281
|
JS_EXTERN bool JS_IsPromise(JSValueConst val);
|
|
1282
|
+
JS_EXTERN void JS_PromiseMarkAsHandled(JSContext *ctx, JSValueConst promise);
|
|
1261
1283
|
JS_EXTERN JSValue JS_NewSettledPromise(JSContext *ctx, bool is_reject, JSValueConst value);
|
|
1262
1284
|
|
|
1263
1285
|
JS_EXTERN JSValue JS_NewSymbol(JSContext *ctx, const char *description, bool is_global);
|
|
@@ -1384,6 +1406,18 @@ JS_EXTERN uint8_t *JS_WriteObject2(JSContext *ctx, size_t *psize, JSValueConst o
|
|
|
1384
1406
|
writer in the same process (e.g. another Worker on the same runtime). */
|
|
1385
1407
|
#define JS_READ_OBJ_SAB (1 << 2) /* allow SharedArrayBuffer */
|
|
1386
1408
|
#define JS_READ_OBJ_REFERENCE (1 << 3) /* allow object references */
|
|
1409
|
+
/* Defer function-body deserialization, including local definitions, constant
|
|
1410
|
+
pools, bytecode, object-literal metadata and debug data, until first use.
|
|
1411
|
+
The atom table is also populated on demand. This moves work from startup to
|
|
1412
|
+
the first call of each deferred function. The payload is copied internally,
|
|
1413
|
+
so `buf` need not outlive the call. Requires JS_READ_OBJ_BYTECODE and is
|
|
1414
|
+
incompatible with JS_READ_OBJ_REFERENCE and JS_READ_OBJ_SAB. */
|
|
1415
|
+
#define JS_READ_OBJ_LAZY (1 << 4)
|
|
1416
|
+
/* With JS_READ_OBJ_LAZY, point at the caller's buffer instead of copying it.
|
|
1417
|
+
The caller owns the bytes and must keep them alive and unmodified until every
|
|
1418
|
+
value and runtime created from the payload has been freed. Requires
|
|
1419
|
+
JS_READ_OBJ_LAZY; invalid combinations are rejected. */
|
|
1420
|
+
#define JS_READ_OBJ_BORROW (1 << 5)
|
|
1387
1421
|
JS_EXTERN JSValue JS_ReadObject(JSContext *ctx, const uint8_t *buf, size_t buf_len, int flags);
|
|
1388
1422
|
JS_EXTERN JSValue JS_ReadObject2(JSContext *ctx, const uint8_t *buf, size_t buf_len,
|
|
1389
1423
|
int flags, JSSABTab *psab_tab);
|
|
@@ -1561,8 +1595,8 @@ JS_EXTERN int JS_SetModuleExportList(JSContext *ctx, JSModuleDef *m,
|
|
|
1561
1595
|
/* Version */
|
|
1562
1596
|
|
|
1563
1597
|
#define QJS_VERSION_MAJOR 0
|
|
1564
|
-
#define QJS_VERSION_MINOR
|
|
1565
|
-
#define QJS_VERSION_PATCH
|
|
1598
|
+
#define QJS_VERSION_MINOR 16
|
|
1599
|
+
#define QJS_VERSION_PATCH 2
|
|
1566
1600
|
#define QJS_VERSION_SUFFIX ""
|
|
1567
1601
|
|
|
1568
1602
|
JS_EXTERN const char* JS_GetVersion(void);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@react-native-quickjs/quickjs",
|
|
3
|
-
"version": "1.0.0-alpha.
|
|
3
|
+
"version": "1.0.0-alpha.3",
|
|
4
4
|
"description": "QuickJS JSI runtime for React Native, built from source",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react-native",
|
|
@@ -60,9 +60,21 @@
|
|
|
60
60
|
"configure": "cmake -B build -DCMAKE_BUILD_TYPE=Debug",
|
|
61
61
|
"build": "cmake --build build -j8",
|
|
62
62
|
"test": "npm run configure && npm run build && ctest --test-dir build --output-on-failure -j4",
|
|
63
|
-
"bench": "cmake -B build-release -DCMAKE_BUILD_TYPE=Release && cmake --build build-release -j8
|
|
63
|
+
"bench": "cmake -B build-release -DCMAKE_BUILD_TYPE=Release && cmake --build build-release -j8 --target qjs-bench native-call-bench && node tools/benchmark/bench.mjs",
|
|
64
|
+
"bench:build": "cmake -B build-release -DCMAKE_BUILD_TYPE=Release && cmake --build build-release -j8 --target qjs-bench native-call-bench",
|
|
65
|
+
"bench:octane": "node tools/benchmark/bench.mjs octane",
|
|
66
|
+
"bench:workloads": "node tools/benchmark/bench.mjs react minireact rn primitives data strings surface suspense modern arrayholes jsonparse",
|
|
67
|
+
"bench:kernels": "node tools/benchmark/bench.mjs compiler jit",
|
|
68
|
+
"bench:calls": "node tools/benchmark/bench.mjs calls",
|
|
69
|
+
"bench:startup": "node tools/benchmark/bench.mjs startup",
|
|
70
|
+
"bench:record": "node tools/benchmark/bench.mjs --save",
|
|
71
|
+
"bench:gate": "node tools/benchmark/bench.mjs --against",
|
|
72
|
+
"bench:list": "node tools/benchmark/bench.mjs --list",
|
|
73
|
+
"bench:device": "node tools/benchmark/bench.mjs --device",
|
|
64
74
|
"bytecode": "./build/qjsc-ng",
|
|
65
75
|
"clean": "rm -rf build build-release",
|
|
76
|
+
"format": "clang-format -i $(git ls-files '*.c' '*.h' '*.cpp' '*.mm' | grep -Ev '^(engine/|tests/third_party/|modules/napi/)' | grep -v '^android/src/main/jni/JJSRuntimeFactory.h$')",
|
|
77
|
+
"format:check": "clang-format --dry-run --Werror $(git ls-files '*.c' '*.h' '*.cpp' '*.mm' | grep -Ev '^(engine/|tests/third_party/|modules/napi/)' | grep -v '^android/src/main/jni/JJSRuntimeFactory.h$')",
|
|
66
78
|
"prepack": "node scripts/check-submodule.js && node scripts/apply-patches.js --check && node scripts/sync-quickjs-rel.js --check",
|
|
67
79
|
"postinstall": "node scripts/postinstall.js",
|
|
68
80
|
"example": "npm run --workspace @react-native-quickjs/example",
|
|
@@ -102,6 +114,6 @@
|
|
|
102
114
|
}
|
|
103
115
|
},
|
|
104
116
|
"dependencies": {
|
|
105
|
-
"@react-native-quickjs/text-encoding": "1.0.
|
|
117
|
+
"@react-native-quickjs/text-encoding": "1.0.1"
|
|
106
118
|
}
|
|
107
119
|
}
|
|
@@ -297,8 +297,14 @@ struct ArrayBufferProxy {
|
|
|
297
297
|
std::shared_ptr<jsi::MutableBuffer> buffer;
|
|
298
298
|
};
|
|
299
299
|
|
|
300
|
-
void
|
|
301
|
-
|
|
300
|
+
void *reallocArrayBufferProxy(
|
|
301
|
+
JSRuntime * /*rt*/, void *opaque, void * /*ptr*/, size_t size) {
|
|
302
|
+
ArrayBufferProxy *proxy = static_cast<ArrayBufferProxy *>(opaque);
|
|
303
|
+
if (size == 0) {
|
|
304
|
+
delete proxy;
|
|
305
|
+
return nullptr;
|
|
306
|
+
}
|
|
307
|
+
return nullptr;
|
|
302
308
|
}
|
|
303
309
|
|
|
304
310
|
const char *kEnumeratePropertyNamesSource =
|
|
@@ -1047,8 +1053,14 @@ jsi::Value QuickJSRuntime::evaluateSource(
|
|
|
1047
1053
|
|
|
1048
1054
|
jsi::Value QuickJSRuntime::evaluateBytecode(
|
|
1049
1055
|
const uint8_t *payload, size_t size) {
|
|
1050
|
-
|
|
1051
|
-
|
|
1056
|
+
#ifndef RNQJS_BYTECODE_LAZY
|
|
1057
|
+
#define RNQJS_BYTECODE_LAZY 1
|
|
1058
|
+
#endif
|
|
1059
|
+
int readFlags = JS_READ_OBJ_BYTECODE;
|
|
1060
|
+
#if RNQJS_BYTECODE_LAZY
|
|
1061
|
+
readFlags |= JS_READ_OBJ_LAZY;
|
|
1062
|
+
#endif
|
|
1063
|
+
JSValue function = JS_ReadObject(context_, payload, size, readFlags);
|
|
1052
1064
|
if (JS_IsException(function)) {
|
|
1053
1065
|
// Almost always an engine mismatch. quickjs bytecode loads only in the
|
|
1054
1066
|
// build that wrote it, and "bytecode function expected" does not say so.
|
|
@@ -1737,7 +1749,8 @@ jsi::ArrayBuffer QuickJSRuntime::createArrayBuffer(
|
|
|
1737
1749
|
auto *proxy = new ArrayBufferProxy{std::move(buffer)};
|
|
1738
1750
|
|
|
1739
1751
|
JSValue arrayBuffer = JS_NewArrayBuffer(
|
|
1740
|
-
context_, data, size,
|
|
1752
|
+
context_, data, size, /*max_len*/ 0, reallocArrayBufferProxy, proxy,
|
|
1753
|
+
false);
|
|
1741
1754
|
if (JS_IsException(arrayBuffer)) {
|
|
1742
1755
|
delete proxy;
|
|
1743
1756
|
throwPendingError();
|