quickjs.h 46 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180
  1. /*
  2. * QuickJS Javascript Engine
  3. *
  4. * Copyright (c) 2017-2021 Fabrice Bellard
  5. * Copyright (c) 2017-2021 Charlie Gordon
  6. *
  7. * Permission is hereby granted, free of charge, to any person obtaining a copy
  8. * of this software and associated documentation files (the "Software"), to deal
  9. * in the Software without restriction, including without limitation the rights
  10. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  11. * copies of the Software, and to permit persons to whom the Software is
  12. * furnished to do so, subject to the following conditions:
  13. *
  14. * The above copyright notice and this permission notice shall be included in
  15. * all copies or substantial portions of the Software.
  16. *
  17. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  20. * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  22. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  23. * THE SOFTWARE.
  24. */
  25. #ifndef QUICKJS_H
  26. #define QUICKJS_H
  27. #include <stdio.h>
  28. #include <stdint.h>
  29. #include <string.h>
  30. #ifdef __cplusplus
  31. extern "C" {
  32. #endif
  33. #if defined(__GNUC__) || defined(__clang__)
  34. #define js_likely(x) __builtin_expect(!!(x), 1)
  35. #define js_unlikely(x) __builtin_expect(!!(x), 0)
  36. #define js_force_inline inline __attribute__((always_inline))
  37. #define __js_printf_like(f, a) __attribute__((format(printf, f, a)))
  38. #else
  39. #define js_likely(x) (x)
  40. #define js_unlikely(x) (x)
  41. #define js_force_inline inline
  42. #define __js_printf_like(a, b)
  43. #endif
  44. #define JS_BOOL int
  45. typedef struct JSRuntime JSRuntime;
  46. typedef struct JSContext JSContext;
  47. typedef struct JSClass JSClass;
  48. typedef uint32_t JSClassID;
  49. typedef uint32_t JSAtom;
  50. #if INTPTR_MAX >= INT64_MAX
  51. #define JS_PTR64
  52. #define JS_PTR64_DEF(a) a
  53. #else
  54. #define JS_PTR64_DEF(a)
  55. #endif
  56. #ifndef JS_PTR64
  57. #define JS_NAN_BOXING
  58. #endif
  59. #if defined(__SIZEOF_INT128__) && (INTPTR_MAX >= INT64_MAX)
  60. #define JS_LIMB_BITS 64
  61. #else
  62. #define JS_LIMB_BITS 32
  63. #endif
  64. #define JS_SHORT_BIG_INT_BITS JS_LIMB_BITS
  65. enum {
  66. /* all tags with a reference count are negative */
  67. JS_TAG_FIRST = -9, /* first negative tag */
  68. JS_TAG_BIG_INT = -9,
  69. JS_TAG_SYMBOL = -8,
  70. JS_TAG_STRING = -7,
  71. JS_TAG_STRING_ROPE = -6,
  72. JS_TAG_MODULE = -3, /* used internally */
  73. JS_TAG_FUNCTION_BYTECODE = -2, /* used internally */
  74. JS_TAG_OBJECT = -1,
  75. JS_TAG_INT = 0,
  76. JS_TAG_BOOL = 1,
  77. JS_TAG_NULL = 2,
  78. JS_TAG_UNDEFINED = 3,
  79. JS_TAG_UNINITIALIZED = 4,
  80. JS_TAG_CATCH_OFFSET = 5,
  81. JS_TAG_EXCEPTION = 6,
  82. JS_TAG_SHORT_BIG_INT = 7,
  83. JS_TAG_FLOAT64 = 8,
  84. /* any larger tag is FLOAT64 if JS_NAN_BOXING */
  85. };
  86. /* must match the layout of 'JSMallocBlockHeader' */
  87. typedef struct JSRefCountHeader {
  88. int ref_count;
  89. } JSRefCountHeader;
  90. #define JS_FLOAT64_NAN NAN
  91. #ifdef CONFIG_CHECK_JSVALUE
  92. /* JSValue consistency : it is not possible to run the code in this
  93. mode, but it is useful to detect simple reference counting
  94. errors. It would be interesting to modify a static C analyzer to
  95. handle specific annotations (clang has such annotations but only
  96. for objective C) */
  97. typedef struct __JSValue *JSValue;
  98. typedef const struct __JSValue *JSValueConst;
  99. #define JS_VALUE_GET_TAG(v) (int)((uintptr_t)(v) & 0xf)
  100. /* same as JS_VALUE_GET_TAG, but return JS_TAG_FLOAT64 with NaN boxing */
  101. #define JS_VALUE_GET_NORM_TAG(v) JS_VALUE_GET_TAG(v)
  102. #define JS_VALUE_GET_INT(v) (int)((intptr_t)(v) >> 4)
  103. #define JS_VALUE_GET_BOOL(v) JS_VALUE_GET_INT(v)
  104. #define JS_VALUE_GET_FLOAT64(v) (double)JS_VALUE_GET_INT(v)
  105. #define JS_VALUE_GET_SHORT_BIG_INT(v) JS_VALUE_GET_INT(v)
  106. #define JS_VALUE_GET_PTR(v) (void *)((intptr_t)(v) & ~0xf)
  107. #define JS_MKVAL(tag, val) (JSValue)(intptr_t)(((val) << 4) | (tag))
  108. #define JS_MKPTR(tag, p) (JSValue)((intptr_t)(p) | (tag))
  109. #define JS_TAG_IS_FLOAT64(tag) ((unsigned)(tag) == JS_TAG_FLOAT64)
  110. #define JS_NAN JS_MKVAL(JS_TAG_FLOAT64, 1)
  111. static inline JSValue __JS_NewFloat64(JSContext *ctx, double d)
  112. {
  113. return JS_MKVAL(JS_TAG_FLOAT64, (int)d);
  114. }
  115. static inline JS_BOOL JS_VALUE_IS_NAN(JSValue v)
  116. {
  117. return 0;
  118. }
  119. static inline JSValue __JS_NewShortBigInt(JSContext *ctx, int32_t d)
  120. {
  121. return JS_MKVAL(JS_TAG_SHORT_BIG_INT, d);
  122. }
  123. #elif defined(JS_NAN_BOXING)
  124. typedef uint64_t JSValue;
  125. #define JSValueConst JSValue
  126. #define JS_VALUE_GET_TAG(v) (int)((v) >> 32)
  127. #define JS_VALUE_GET_INT(v) (int)(v)
  128. #define JS_VALUE_GET_BOOL(v) (int)(v)
  129. #define JS_VALUE_GET_SHORT_BIG_INT(v) (int)(v)
  130. #define JS_VALUE_GET_PTR(v) (void *)(intptr_t)(v)
  131. #define JS_MKVAL(tag, val) (((uint64_t)(tag) << 32) | (uint32_t)(val))
  132. #define JS_MKPTR(tag, ptr) (((uint64_t)(tag) << 32) | (uintptr_t)(ptr))
  133. #define JS_FLOAT64_TAG_ADDEND (0x7ff80000 - JS_TAG_FIRST + 1) /* quiet NaN encoding */
  134. static inline double JS_VALUE_GET_FLOAT64(JSValue v)
  135. {
  136. union {
  137. JSValue v;
  138. double d;
  139. } u;
  140. u.v = v;
  141. u.v += (uint64_t)JS_FLOAT64_TAG_ADDEND << 32;
  142. return u.d;
  143. }
  144. #define JS_NAN (0x7ff8000000000000 - ((uint64_t)JS_FLOAT64_TAG_ADDEND << 32))
  145. static inline JSValue __JS_NewFloat64(JSContext *ctx, double d)
  146. {
  147. union {
  148. double d;
  149. uint64_t u64;
  150. } u;
  151. JSValue v;
  152. u.d = d;
  153. /* normalize NaN */
  154. if (js_unlikely((u.u64 & 0x7fffffffffffffff) > 0x7ff0000000000000))
  155. v = JS_NAN;
  156. else
  157. v = u.u64 - ((uint64_t)JS_FLOAT64_TAG_ADDEND << 32);
  158. return v;
  159. }
  160. #define JS_TAG_IS_FLOAT64(tag) ((unsigned)((tag) - JS_TAG_FIRST) >= (JS_TAG_FLOAT64 - JS_TAG_FIRST))
  161. /* same as JS_VALUE_GET_TAG, but return JS_TAG_FLOAT64 with NaN boxing */
  162. static inline int JS_VALUE_GET_NORM_TAG(JSValue v)
  163. {
  164. uint32_t tag;
  165. tag = JS_VALUE_GET_TAG(v);
  166. if (JS_TAG_IS_FLOAT64(tag))
  167. return JS_TAG_FLOAT64;
  168. else
  169. return tag;
  170. }
  171. static inline JS_BOOL JS_VALUE_IS_NAN(JSValue v)
  172. {
  173. uint32_t tag;
  174. tag = JS_VALUE_GET_TAG(v);
  175. return tag == (JS_NAN >> 32);
  176. }
  177. static inline JSValue __JS_NewShortBigInt(JSContext *ctx, int32_t d)
  178. {
  179. return JS_MKVAL(JS_TAG_SHORT_BIG_INT, d);
  180. }
  181. #else /* !JS_NAN_BOXING */
  182. typedef union JSValueUnion {
  183. uint64_t uint64;
  184. double float64;
  185. void *ptr;
  186. #if JS_SHORT_BIG_INT_BITS == 32
  187. int32_t short_big_int;
  188. #else
  189. int64_t short_big_int;
  190. #endif
  191. } JSValueUnion;
  192. typedef struct JSValue {
  193. JSValueUnion u;
  194. int64_t tag;
  195. } JSValue;
  196. #define JSValueConst JSValue
  197. #define JS_VALUE_GET_TAG(v) ((int32_t)(v).tag)
  198. /* same as JS_VALUE_GET_TAG, but return JS_TAG_FLOAT64 with NaN boxing */
  199. #define JS_VALUE_GET_NORM_TAG(v) JS_VALUE_GET_TAG(v)
  200. #define JS_VALUE_GET_INT(v) ((int)(v).u.uint64)
  201. #define JS_VALUE_GET_BOOL(v) ((int)(v).u.uint64)
  202. #define JS_VALUE_GET_FLOAT64(v) ((v).u.float64)
  203. #define JS_VALUE_GET_SHORT_BIG_INT(v) ((v).u.short_big_int)
  204. #define JS_VALUE_GET_PTR(v) ((v).u.ptr)
  205. /* avoid uninitialized data by using a 64 bit field even if only 32
  206. bits are needed because some compilers generate slower code */
  207. #define JS_MKVAL(tag, val) (JSValue){ (JSValueUnion){ .uint64 = (uint32_t)(val) }, tag }
  208. #define JS_MKPTR(tag, p) (JSValue){ (JSValueUnion){ .ptr = p }, tag }
  209. #define JS_TAG_IS_FLOAT64(tag) ((unsigned)(tag) == JS_TAG_FLOAT64)
  210. #define JS_NAN (JSValue){ .u.float64 = JS_FLOAT64_NAN, JS_TAG_FLOAT64 }
  211. static inline JSValue __JS_NewFloat64(JSContext *ctx, double d)
  212. {
  213. JSValue v;
  214. v.tag = JS_TAG_FLOAT64;
  215. v.u.float64 = d;
  216. return v;
  217. }
  218. static inline JS_BOOL JS_VALUE_IS_NAN(JSValue v)
  219. {
  220. union {
  221. double d;
  222. uint64_t u64;
  223. } u;
  224. if (v.tag != JS_TAG_FLOAT64)
  225. return 0;
  226. u.d = v.u.float64;
  227. return (u.u64 & 0x7fffffffffffffff) > 0x7ff0000000000000;
  228. }
  229. static inline JSValue __JS_NewShortBigInt(JSContext *ctx, int64_t d)
  230. {
  231. JSValue v;
  232. v.tag = JS_TAG_SHORT_BIG_INT;
  233. v.u.short_big_int = d;
  234. return v;
  235. }
  236. #endif /* !JS_NAN_BOXING */
  237. #define JS_VALUE_IS_BOTH_INT(v1, v2) ((JS_VALUE_GET_TAG(v1) | JS_VALUE_GET_TAG(v2)) == 0)
  238. #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)))
  239. #define JS_VALUE_HAS_REF_COUNT(v) ((unsigned)JS_VALUE_GET_TAG(v) >= (unsigned)JS_TAG_FIRST)
  240. /* special values */
  241. #define JS_NULL JS_MKVAL(JS_TAG_NULL, 0)
  242. #define JS_UNDEFINED JS_MKVAL(JS_TAG_UNDEFINED, 0)
  243. #define JS_FALSE JS_MKVAL(JS_TAG_BOOL, 0)
  244. #define JS_TRUE JS_MKVAL(JS_TAG_BOOL, 1)
  245. #define JS_EXCEPTION JS_MKVAL(JS_TAG_EXCEPTION, 0)
  246. #define JS_UNINITIALIZED JS_MKVAL(JS_TAG_UNINITIALIZED, 0)
  247. /* flags for object properties */
  248. #define JS_PROP_CONFIGURABLE (1 << 0)
  249. #define JS_PROP_WRITABLE (1 << 1)
  250. #define JS_PROP_ENUMERABLE (1 << 2)
  251. #define JS_PROP_C_W_E (JS_PROP_CONFIGURABLE | JS_PROP_WRITABLE | JS_PROP_ENUMERABLE)
  252. #define JS_PROP_LENGTH (1 << 3) /* used internally in Arrays */
  253. #define JS_PROP_TMASK (3 << 4) /* mask for NORMAL, GETSET, VARREF, AUTOINIT */
  254. #define JS_PROP_NORMAL (0 << 4)
  255. #define JS_PROP_GETSET (1 << 4)
  256. #define JS_PROP_VARREF (2 << 4) /* used internally */
  257. #define JS_PROP_AUTOINIT (3 << 4) /* used internally */
  258. /* flags for JS_DefineProperty */
  259. #define JS_PROP_HAS_SHIFT 8
  260. #define JS_PROP_HAS_CONFIGURABLE (1 << 8)
  261. #define JS_PROP_HAS_WRITABLE (1 << 9)
  262. #define JS_PROP_HAS_ENUMERABLE (1 << 10)
  263. #define JS_PROP_HAS_GET (1 << 11)
  264. #define JS_PROP_HAS_SET (1 << 12)
  265. #define JS_PROP_HAS_VALUE (1 << 13)
  266. /* throw an exception if false would be returned
  267. (JS_DefineProperty/JS_SetProperty) */
  268. #define JS_PROP_THROW (1 << 14)
  269. /* throw an exception if false would be returned in strict mode
  270. (JS_SetProperty) */
  271. #define JS_PROP_THROW_STRICT (1 << 15)
  272. #define JS_PROP_NO_EXOTIC (1 << 16) /* internal use */
  273. #ifndef JS_DEFAULT_STACK_SIZE
  274. #define JS_DEFAULT_STACK_SIZE (1024 * 1024)
  275. #endif
  276. /* JS_Eval() flags */
  277. #define JS_EVAL_TYPE_GLOBAL (0 << 0) /* global code (default) */
  278. #define JS_EVAL_TYPE_MODULE (1 << 0) /* module code */
  279. #define JS_EVAL_TYPE_DIRECT (2 << 0) /* direct call (internal use) */
  280. #define JS_EVAL_TYPE_INDIRECT (3 << 0) /* indirect call (internal use) */
  281. #define JS_EVAL_TYPE_MASK (3 << 0)
  282. #define JS_EVAL_FLAG_STRICT (1 << 3) /* force 'strict' mode */
  283. /* compile but do not run. The result is an object with a
  284. JS_TAG_FUNCTION_BYTECODE or JS_TAG_MODULE tag. It can be executed
  285. with JS_EvalFunction(). */
  286. #define JS_EVAL_FLAG_COMPILE_ONLY (1 << 5)
  287. /* don't include the stack frames before this eval in the Error() backtraces */
  288. #define JS_EVAL_FLAG_BACKTRACE_BARRIER (1 << 6)
  289. /* allow top-level await in normal script. JS_Eval() returns a
  290. promise. Only allowed with JS_EVAL_TYPE_GLOBAL */
  291. #define JS_EVAL_FLAG_ASYNC (1 << 7)
  292. typedef JSValue JSCFunction(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv);
  293. typedef JSValue JSCFunctionMagic(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic);
  294. typedef JSValue JSCFunctionData(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic, JSValue *func_data);
  295. typedef struct JSMallocState {
  296. size_t malloc_count;
  297. size_t malloc_size;
  298. size_t malloc_limit;
  299. void *opaque; /* user opaque */
  300. } JSMallocState;
  301. typedef struct JSMallocFunctions {
  302. void *(*js_malloc)(JSMallocState *s, size_t size);
  303. void (*js_free)(JSMallocState *s, void *ptr);
  304. void *(*js_realloc)(JSMallocState *s, void *ptr, size_t size);
  305. size_t (*js_malloc_usable_size)(const void *ptr);
  306. } JSMallocFunctions;
  307. typedef struct JSGCObjectHeader JSGCObjectHeader;
  308. JSRuntime *JS_NewRuntime(void);
  309. /* info lifetime must exceed that of rt */
  310. void JS_SetRuntimeInfo(JSRuntime *rt, const char *info);
  311. void JS_SetMemoryLimit(JSRuntime *rt, size_t limit);
  312. void JS_SetGCThreshold(JSRuntime *rt, size_t gc_threshold);
  313. /* use 0 to disable maximum stack size check */
  314. void JS_SetMaxStackSize(JSRuntime *rt, size_t stack_size);
  315. /* should be called when changing thread to update the stack top value
  316. used to check stack overflow. */
  317. void JS_UpdateStackTop(JSRuntime *rt);
  318. JSRuntime *JS_NewRuntime2(const JSMallocFunctions *mf, void *opaque);
  319. void JS_FreeRuntime(JSRuntime *rt);
  320. void *JS_GetRuntimeOpaque(JSRuntime *rt);
  321. void JS_SetRuntimeOpaque(JSRuntime *rt, void *opaque);
  322. typedef void JS_MarkFunc(JSRuntime *rt, JSGCObjectHeader *gp);
  323. void JS_MarkValue(JSRuntime *rt, JSValueConst val, JS_MarkFunc *mark_func);
  324. void JS_RunGC(JSRuntime *rt);
  325. JS_BOOL JS_IsLiveObject(JSRuntime *rt, JSValueConst obj);
  326. JSContext *JS_NewContext(JSRuntime *rt);
  327. void JS_FreeContext(JSContext *s);
  328. JSContext *JS_DupContext(JSContext *ctx);
  329. void *JS_GetContextOpaque(JSContext *ctx);
  330. void JS_SetContextOpaque(JSContext *ctx, void *opaque);
  331. JSRuntime *JS_GetRuntime(JSContext *ctx);
  332. void JS_SetClassProto(JSContext *ctx, JSClassID class_id, JSValue obj);
  333. JSValue JS_GetClassProto(JSContext *ctx, JSClassID class_id);
  334. /* the following functions are used to select the intrinsic object to
  335. save memory */
  336. JSContext *JS_NewContextRaw(JSRuntime *rt);
  337. int JS_AddIntrinsicBaseObjects(JSContext *ctx);
  338. int JS_AddIntrinsicDate(JSContext *ctx);
  339. int JS_AddIntrinsicEval(JSContext *ctx);
  340. int JS_AddIntrinsicStringNormalize(JSContext *ctx);
  341. void JS_AddIntrinsicRegExpCompiler(JSContext *ctx);
  342. int JS_AddIntrinsicRegExp(JSContext *ctx);
  343. int JS_AddIntrinsicJSON(JSContext *ctx);
  344. int JS_AddIntrinsicProxy(JSContext *ctx);
  345. int JS_AddIntrinsicMapSet(JSContext *ctx);
  346. int JS_AddIntrinsicTypedArrays(JSContext *ctx);
  347. int JS_AddIntrinsicPromise(JSContext *ctx);
  348. int JS_AddIntrinsicWeakRef(JSContext *ctx);
  349. JSValue js_string_codePointRange(JSContext *ctx, JSValueConst this_val,
  350. int argc, JSValueConst *argv);
  351. void *js_malloc_rt(JSRuntime *rt, size_t size);
  352. void js_free_rt(JSRuntime *rt, void *ptr);
  353. void *js_realloc_rt(JSRuntime *rt, void *ptr, size_t size);
  354. size_t js_malloc_usable_size_rt(JSRuntime *rt, const void *ptr);
  355. void *js_mallocz_rt(JSRuntime *rt, size_t size);
  356. void *js_malloc(JSContext *ctx, size_t size);
  357. void js_free(JSContext *ctx, void *ptr);
  358. void *js_realloc(JSContext *ctx, void *ptr, size_t size);
  359. size_t js_malloc_usable_size(JSContext *ctx, const void *ptr);
  360. void *js_realloc2(JSContext *ctx, void *ptr, size_t size, size_t *pslack);
  361. void *js_mallocz(JSContext *ctx, size_t size);
  362. char *js_strdup(JSContext *ctx, const char *str);
  363. char *js_strndup(JSContext *ctx, const char *s, size_t n);
  364. typedef struct JSMemoryUsage {
  365. int64_t malloc_size, malloc_limit, memory_used_size;
  366. int64_t malloc_count;
  367. int64_t memory_used_count;
  368. int64_t atom_count, atom_size;
  369. int64_t str_count, str_size;
  370. int64_t obj_count, obj_size;
  371. int64_t prop_count, prop_size;
  372. int64_t shape_count, shape_size;
  373. int64_t js_func_count, js_func_size, js_func_code_size;
  374. int64_t js_func_pc2line_count, js_func_pc2line_size;
  375. int64_t c_func_count, array_count;
  376. int64_t fast_array_count, fast_array_elements;
  377. int64_t binary_object_count, binary_object_size;
  378. } JSMemoryUsage;
  379. void JS_ComputeMemoryUsage(JSRuntime *rt, JSMemoryUsage *s);
  380. void JS_DumpMemoryUsage(FILE *fp, const JSMemoryUsage *s, JSRuntime *rt);
  381. /* atom support */
  382. #define JS_ATOM_NULL 0
  383. JSAtom JS_NewAtomLen(JSContext *ctx, const char *str, size_t len);
  384. JSAtom JS_NewAtom(JSContext *ctx, const char *str);
  385. JSAtom JS_NewAtomUInt32(JSContext *ctx, uint32_t n);
  386. JSAtom JS_DupAtom(JSContext *ctx, JSAtom v);
  387. void JS_FreeAtom(JSContext *ctx, JSAtom v);
  388. void JS_FreeAtomRT(JSRuntime *rt, JSAtom v);
  389. JSValue JS_AtomToValue(JSContext *ctx, JSAtom atom);
  390. JSValue JS_AtomToString(JSContext *ctx, JSAtom atom);
  391. const char *JS_AtomToCStringLen(JSContext *ctx, size_t *plen, JSAtom atom);
  392. static inline const char *JS_AtomToCString(JSContext *ctx, JSAtom atom)
  393. {
  394. return JS_AtomToCStringLen(ctx, NULL, atom);
  395. }
  396. JSAtom JS_ValueToAtom(JSContext *ctx, JSValueConst val);
  397. /* object class support */
  398. typedef struct JSPropertyEnum {
  399. JS_BOOL is_enumerable;
  400. JSAtom atom;
  401. } JSPropertyEnum;
  402. typedef struct JSPropertyDescriptor {
  403. int flags;
  404. JSValue value;
  405. JSValue getter;
  406. JSValue setter;
  407. } JSPropertyDescriptor;
  408. typedef struct JSClassExoticMethods {
  409. /* Return -1 if exception (can only happen in case of Proxy object),
  410. FALSE if the property does not exists, TRUE if it exists. If 1 is
  411. returned, the property descriptor 'desc' is filled if != NULL. */
  412. int (*get_own_property)(JSContext *ctx, JSPropertyDescriptor *desc,
  413. JSValueConst obj, JSAtom prop);
  414. /* '*ptab' should hold the '*plen' property keys. Return 0 if OK,
  415. -1 if exception. The 'is_enumerable' field is ignored.
  416. */
  417. int (*get_own_property_names)(JSContext *ctx, JSPropertyEnum **ptab,
  418. uint32_t *plen,
  419. JSValueConst obj);
  420. /* return < 0 if exception, or TRUE/FALSE */
  421. int (*delete_property)(JSContext *ctx, JSValueConst obj, JSAtom prop);
  422. /* return < 0 if exception or TRUE/FALSE */
  423. int (*define_own_property)(JSContext *ctx, JSValueConst this_obj,
  424. JSAtom prop, JSValueConst val,
  425. JSValueConst getter, JSValueConst setter,
  426. int flags);
  427. /* The following methods can be emulated with the previous ones,
  428. so they are usually not needed */
  429. /* return < 0 if exception or TRUE/FALSE */
  430. int (*has_property)(JSContext *ctx, JSValueConst obj, JSAtom atom);
  431. JSValue (*get_property)(JSContext *ctx, JSValueConst obj, JSAtom atom,
  432. JSValueConst receiver);
  433. /* return < 0 if exception or TRUE/FALSE */
  434. int (*set_property)(JSContext *ctx, JSValueConst obj, JSAtom atom,
  435. JSValueConst value, JSValueConst receiver, int flags);
  436. /* To get a consistent object behavior when get_prototype != NULL,
  437. get_property, set_property and set_prototype must be != NULL
  438. and the object must be created with a JS_NULL prototype. */
  439. JSValue (*get_prototype)(JSContext *ctx, JSValueConst obj);
  440. /* return < 0 if exception or TRUE/FALSE */
  441. int (*set_prototype)(JSContext *ctx, JSValueConst obj, JSValueConst proto_val);
  442. /* return < 0 if exception or TRUE/FALSE */
  443. int (*is_extensible)(JSContext *ctx, JSValueConst obj);
  444. /* return < 0 if exception or TRUE/FALSE */
  445. int (*prevent_extensions)(JSContext *ctx, JSValueConst obj);
  446. } JSClassExoticMethods;
  447. typedef void JSClassFinalizer(JSRuntime *rt, JSValue val);
  448. typedef void JSClassGCMark(JSRuntime *rt, JSValueConst val,
  449. JS_MarkFunc *mark_func);
  450. #define JS_CALL_FLAG_CONSTRUCTOR (1 << 0)
  451. typedef JSValue JSClassCall(JSContext *ctx, JSValueConst func_obj,
  452. JSValueConst this_val, int argc, JSValueConst *argv,
  453. int flags);
  454. typedef struct JSClassDef {
  455. const char *class_name;
  456. JSClassFinalizer *finalizer;
  457. JSClassGCMark *gc_mark;
  458. /* if call != NULL, the object is a function. If (flags &
  459. JS_CALL_FLAG_CONSTRUCTOR) != 0, the function is called as a
  460. constructor. In this case, 'this_val' is new.target. A
  461. constructor call only happens if the object constructor bit is
  462. set (see JS_SetConstructorBit()). */
  463. JSClassCall *call;
  464. /* XXX: suppress this indirection ? It is here only to save memory
  465. because only a few classes need these methods */
  466. JSClassExoticMethods *exotic;
  467. } JSClassDef;
  468. #define JS_INVALID_CLASS_ID 0
  469. JSClassID JS_NewClassID(JSClassID *pclass_id);
  470. /* Returns the class ID if `v` is an object, otherwise returns JS_INVALID_CLASS_ID. */
  471. JSClassID JS_GetClassID(JSValue v);
  472. int JS_NewClass(JSRuntime *rt, JSClassID class_id, const JSClassDef *class_def);
  473. int JS_IsRegisteredClass(JSRuntime *rt, JSClassID class_id);
  474. /* value handling */
  475. static js_force_inline JSValue JS_NewBool(JSContext *ctx, JS_BOOL val)
  476. {
  477. return JS_MKVAL(JS_TAG_BOOL, (val != 0));
  478. }
  479. static js_force_inline JSValue JS_NewInt32(JSContext *ctx, int32_t val)
  480. {
  481. return JS_MKVAL(JS_TAG_INT, val);
  482. }
  483. static js_force_inline JSValue JS_NewCatchOffset(JSContext *ctx, int32_t val)
  484. {
  485. return JS_MKVAL(JS_TAG_CATCH_OFFSET, val);
  486. }
  487. static js_force_inline JSValue JS_NewInt64(JSContext *ctx, int64_t val)
  488. {
  489. JSValue v;
  490. if (val == (int32_t)val) {
  491. v = JS_NewInt32(ctx, val);
  492. } else {
  493. v = __JS_NewFloat64(ctx, val);
  494. }
  495. return v;
  496. }
  497. static js_force_inline JSValue JS_NewUint32(JSContext *ctx, uint32_t val)
  498. {
  499. JSValue v;
  500. if (val <= 0x7fffffff) {
  501. v = JS_NewInt32(ctx, val);
  502. } else {
  503. v = __JS_NewFloat64(ctx, val);
  504. }
  505. return v;
  506. }
  507. JSValue JS_NewBigInt64(JSContext *ctx, int64_t v);
  508. JSValue JS_NewBigUint64(JSContext *ctx, uint64_t v);
  509. static js_force_inline JSValue JS_NewFloat64(JSContext *ctx, double d)
  510. {
  511. int32_t val;
  512. union {
  513. double d;
  514. uint64_t u;
  515. } u, t;
  516. if (d >= INT32_MIN && d <= INT32_MAX) {
  517. u.d = d;
  518. val = (int32_t)d;
  519. t.d = val;
  520. /* -0 cannot be represented as integer, so we compare the bit
  521. representation */
  522. if (u.u == t.u)
  523. return JS_MKVAL(JS_TAG_INT, val);
  524. }
  525. return __JS_NewFloat64(ctx, d);
  526. }
  527. static inline JS_BOOL JS_IsNumber(JSValueConst v)
  528. {
  529. int tag = JS_VALUE_GET_TAG(v);
  530. return tag == JS_TAG_INT || JS_TAG_IS_FLOAT64(tag);
  531. }
  532. static inline JS_BOOL JS_IsBigInt(JSContext *ctx, JSValueConst v)
  533. {
  534. int tag = JS_VALUE_GET_TAG(v);
  535. return tag == JS_TAG_BIG_INT || tag == JS_TAG_SHORT_BIG_INT;
  536. }
  537. static inline JS_BOOL JS_IsBool(JSValueConst v)
  538. {
  539. return JS_VALUE_GET_TAG(v) == JS_TAG_BOOL;
  540. }
  541. static inline JS_BOOL JS_IsNull(JSValueConst v)
  542. {
  543. return JS_VALUE_GET_TAG(v) == JS_TAG_NULL;
  544. }
  545. static inline JS_BOOL JS_IsUndefined(JSValueConst v)
  546. {
  547. return JS_VALUE_GET_TAG(v) == JS_TAG_UNDEFINED;
  548. }
  549. static inline JS_BOOL JS_IsException(JSValueConst v)
  550. {
  551. return js_unlikely(JS_VALUE_GET_TAG(v) == JS_TAG_EXCEPTION);
  552. }
  553. static inline JS_BOOL JS_IsUninitialized(JSValueConst v)
  554. {
  555. return js_unlikely(JS_VALUE_GET_TAG(v) == JS_TAG_UNINITIALIZED);
  556. }
  557. static inline JS_BOOL JS_IsString(JSValueConst v)
  558. {
  559. return JS_VALUE_GET_TAG(v) == JS_TAG_STRING ||
  560. JS_VALUE_GET_TAG(v) == JS_TAG_STRING_ROPE;
  561. }
  562. static inline JS_BOOL JS_IsSymbol(JSValueConst v)
  563. {
  564. return JS_VALUE_GET_TAG(v) == JS_TAG_SYMBOL;
  565. }
  566. static inline JS_BOOL JS_IsObject(JSValueConst v)
  567. {
  568. return JS_VALUE_GET_TAG(v) == JS_TAG_OBJECT;
  569. }
  570. JSValue JS_Throw(JSContext *ctx, JSValue obj);
  571. void JS_SetUncatchableException(JSContext *ctx, JS_BOOL flag);
  572. JSValue JS_GetException(JSContext *ctx);
  573. JS_BOOL JS_HasException(JSContext *ctx);
  574. JS_BOOL JS_IsError(JSContext *ctx, JSValueConst val);
  575. JSValue JS_NewError(JSContext *ctx);
  576. JSValue __js_printf_like(2, 3) JS_ThrowSyntaxError(JSContext *ctx, const char *fmt, ...);
  577. JSValue __js_printf_like(2, 3) JS_ThrowTypeError(JSContext *ctx, const char *fmt, ...);
  578. JSValue __js_printf_like(2, 3) JS_ThrowReferenceError(JSContext *ctx, const char *fmt, ...);
  579. JSValue __js_printf_like(2, 3) JS_ThrowRangeError(JSContext *ctx, const char *fmt, ...);
  580. JSValue __js_printf_like(2, 3) JS_ThrowInternalError(JSContext *ctx, const char *fmt, ...);
  581. JSValue JS_ThrowOutOfMemory(JSContext *ctx);
  582. void __JS_FreeValue(JSContext *ctx, JSValue v);
  583. static inline JSRefCountHeader *__js_rc(void *ptr)
  584. {
  585. return (JSRefCountHeader *)((uint32_t *)ptr - 1);
  586. }
  587. static inline void JS_FreeValue(JSContext *ctx, JSValue v)
  588. {
  589. if (JS_VALUE_HAS_REF_COUNT(v)) {
  590. JSRefCountHeader *p = __js_rc(JS_VALUE_GET_PTR(v));
  591. if (--p->ref_count <= 0) {
  592. __JS_FreeValue(ctx, v);
  593. }
  594. }
  595. }
  596. void __JS_FreeValueRT(JSRuntime *rt, JSValue v);
  597. static inline void JS_FreeValueRT(JSRuntime *rt, JSValue v)
  598. {
  599. if (JS_VALUE_HAS_REF_COUNT(v)) {
  600. JSRefCountHeader *p = __js_rc(JS_VALUE_GET_PTR(v));
  601. if (--p->ref_count <= 0) {
  602. __JS_FreeValueRT(rt, v);
  603. }
  604. }
  605. }
  606. static inline JSValue JS_DupValue(JSContext *ctx, JSValueConst v)
  607. {
  608. if (JS_VALUE_HAS_REF_COUNT(v)) {
  609. JSRefCountHeader *p = __js_rc(JS_VALUE_GET_PTR(v));
  610. p->ref_count++;
  611. }
  612. return (JSValue)v;
  613. }
  614. static inline JSValue JS_DupValueRT(JSRuntime *rt, JSValueConst v)
  615. {
  616. if (JS_VALUE_HAS_REF_COUNT(v)) {
  617. JSRefCountHeader *p = __js_rc(JS_VALUE_GET_PTR(v));
  618. p->ref_count++;
  619. }
  620. return (JSValue)v;
  621. }
  622. JS_BOOL JS_StrictEq(JSContext *ctx, JSValueConst op1, JSValueConst op2);
  623. JS_BOOL JS_SameValue(JSContext *ctx, JSValueConst op1, JSValueConst op2);
  624. JS_BOOL JS_SameValueZero(JSContext *ctx, JSValueConst op1, JSValueConst op2);
  625. int JS_ToBool(JSContext *ctx, JSValueConst val); /* return -1 for JS_EXCEPTION */
  626. int JS_ToInt32(JSContext *ctx, int32_t *pres, JSValueConst val);
  627. static inline int JS_ToUint32(JSContext *ctx, uint32_t *pres, JSValueConst val)
  628. {
  629. return JS_ToInt32(ctx, (int32_t*)pres, val);
  630. }
  631. int JS_ToInt64(JSContext *ctx, int64_t *pres, JSValueConst val);
  632. int JS_ToIndex(JSContext *ctx, uint64_t *plen, JSValueConst val);
  633. int JS_ToFloat64(JSContext *ctx, double *pres, JSValueConst val);
  634. /* return an exception if 'val' is a Number */
  635. int JS_ToBigInt64(JSContext *ctx, int64_t *pres, JSValueConst val);
  636. /* same as JS_ToInt64() but allow BigInt */
  637. int JS_ToInt64Ext(JSContext *ctx, int64_t *pres, JSValueConst val);
  638. JSValue JS_NewStringLen(JSContext *ctx, const char *str1, size_t len1);
  639. static inline JSValue JS_NewString(JSContext *ctx, const char *str)
  640. {
  641. return JS_NewStringLen(ctx, str, strlen(str));
  642. }
  643. JSValue JS_NewAtomString(JSContext *ctx, const char *str);
  644. JSValue JS_ToString(JSContext *ctx, JSValueConst val);
  645. JSValue JS_ToPropertyKey(JSContext *ctx, JSValueConst val);
  646. const char *JS_ToCStringLen2(JSContext *ctx, size_t *plen, JSValueConst val1, JS_BOOL cesu8);
  647. static inline const char *JS_ToCStringLen(JSContext *ctx, size_t *plen, JSValueConst val1)
  648. {
  649. return JS_ToCStringLen2(ctx, plen, val1, 0);
  650. }
  651. static inline const char *JS_ToCString(JSContext *ctx, JSValueConst val1)
  652. {
  653. return JS_ToCStringLen2(ctx, NULL, val1, 0);
  654. }
  655. void JS_FreeCString(JSContext *ctx, const char *ptr);
  656. JSValue JS_NewObjectProtoClass(JSContext *ctx, JSValueConst proto, JSClassID class_id);
  657. JSValue JS_NewObjectClass(JSContext *ctx, int class_id);
  658. JSValue JS_NewObjectProto(JSContext *ctx, JSValueConst proto);
  659. JSValue JS_NewObject(JSContext *ctx);
  660. JS_BOOL JS_IsFunction(JSContext* ctx, JSValueConst val);
  661. JS_BOOL JS_IsConstructor(JSContext* ctx, JSValueConst val);
  662. JS_BOOL JS_SetConstructorBit(JSContext *ctx, JSValueConst func_obj, JS_BOOL val);
  663. JSValue JS_NewArray(JSContext *ctx);
  664. int JS_IsArray(JSContext *ctx, JSValueConst val);
  665. JSValue JS_NewDate(JSContext *ctx, double epoch_ms);
  666. JSValue JS_GetPropertyInternal(JSContext *ctx, JSValueConst obj,
  667. JSAtom prop, JSValueConst receiver,
  668. JS_BOOL throw_ref_error);
  669. static js_force_inline JSValue JS_GetProperty(JSContext *ctx, JSValueConst this_obj,
  670. JSAtom prop)
  671. {
  672. return JS_GetPropertyInternal(ctx, this_obj, prop, this_obj, 0);
  673. }
  674. JSValue JS_GetPropertyStr(JSContext *ctx, JSValueConst this_obj,
  675. const char *prop);
  676. JSValue JS_GetPropertyUint32(JSContext *ctx, JSValueConst this_obj,
  677. uint32_t idx);
  678. int JS_SetPropertyInternal(JSContext *ctx, JSValueConst obj,
  679. JSAtom prop, JSValue val, JSValueConst this_obj,
  680. int flags);
  681. static inline int JS_SetProperty(JSContext *ctx, JSValueConst this_obj,
  682. JSAtom prop, JSValue val)
  683. {
  684. return JS_SetPropertyInternal(ctx, this_obj, prop, val, this_obj, JS_PROP_THROW);
  685. }
  686. int JS_SetPropertyUint32(JSContext *ctx, JSValueConst this_obj,
  687. uint32_t idx, JSValue val);
  688. int JS_SetPropertyInt64(JSContext *ctx, JSValueConst this_obj,
  689. int64_t idx, JSValue val);
  690. int JS_SetPropertyStr(JSContext *ctx, JSValueConst this_obj,
  691. const char *prop, JSValue val);
  692. int JS_HasProperty(JSContext *ctx, JSValueConst this_obj, JSAtom prop);
  693. int JS_IsExtensible(JSContext *ctx, JSValueConst obj);
  694. int JS_PreventExtensions(JSContext *ctx, JSValueConst obj);
  695. int JS_DeleteProperty(JSContext *ctx, JSValueConst obj, JSAtom prop, int flags);
  696. int JS_SetPrototype(JSContext *ctx, JSValueConst obj, JSValueConst proto_val);
  697. JSValue JS_GetPrototype(JSContext *ctx, JSValueConst val);
  698. #define JS_GPN_STRING_MASK (1 << 0)
  699. #define JS_GPN_SYMBOL_MASK (1 << 1)
  700. #define JS_GPN_PRIVATE_MASK (1 << 2)
  701. /* only include the enumerable properties */
  702. #define JS_GPN_ENUM_ONLY (1 << 4)
  703. /* set theJSPropertyEnum.is_enumerable field */
  704. #define JS_GPN_SET_ENUM (1 << 5)
  705. int JS_GetOwnPropertyNames(JSContext *ctx, JSPropertyEnum **ptab,
  706. uint32_t *plen, JSValueConst obj, int flags);
  707. void JS_FreePropertyEnum(JSContext *ctx, JSPropertyEnum *tab,
  708. uint32_t len);
  709. int JS_GetOwnProperty(JSContext *ctx, JSPropertyDescriptor *desc,
  710. JSValueConst obj, JSAtom prop);
  711. JSValue JS_Call(JSContext *ctx, JSValueConst func_obj, JSValueConst this_obj,
  712. int argc, JSValueConst *argv);
  713. JSValue JS_Invoke(JSContext *ctx, JSValueConst this_val, JSAtom atom,
  714. int argc, JSValueConst *argv);
  715. JSValue JS_CallConstructor(JSContext *ctx, JSValueConst func_obj,
  716. int argc, JSValueConst *argv);
  717. JSValue JS_CallConstructor2(JSContext *ctx, JSValueConst func_obj,
  718. JSValueConst new_target,
  719. int argc, JSValueConst *argv);
  720. JS_BOOL JS_DetectModule(const char *input, size_t input_len);
  721. /* 'input' must be zero terminated i.e. input[input_len] = '\0'. */
  722. JSValue JS_Eval(JSContext *ctx, const char *input, size_t input_len,
  723. const char *filename, int eval_flags);
  724. /* same as JS_Eval() but with an explicit 'this_obj' parameter */
  725. JSValue JS_EvalThis(JSContext *ctx, JSValueConst this_obj,
  726. const char *input, size_t input_len,
  727. const char *filename, int eval_flags);
  728. JSValue JS_GetGlobalObject(JSContext *ctx);
  729. int JS_IsInstanceOf(JSContext *ctx, JSValueConst val, JSValueConst obj);
  730. int JS_DefineProperty(JSContext *ctx, JSValueConst this_obj,
  731. JSAtom prop, JSValueConst val,
  732. JSValueConst getter, JSValueConst setter, int flags);
  733. int JS_DefinePropertyValue(JSContext *ctx, JSValueConst this_obj,
  734. JSAtom prop, JSValue val, int flags);
  735. int JS_DefinePropertyValueUint32(JSContext *ctx, JSValueConst this_obj,
  736. uint32_t idx, JSValue val, int flags);
  737. int JS_DefinePropertyValueStr(JSContext *ctx, JSValueConst this_obj,
  738. const char *prop, JSValue val, int flags);
  739. int JS_DefinePropertyGetSet(JSContext *ctx, JSValueConst this_obj,
  740. JSAtom prop, JSValue getter, JSValue setter,
  741. int flags);
  742. void JS_SetOpaque(JSValue obj, void *opaque);
  743. void *JS_GetOpaque(JSValueConst obj, JSClassID class_id);
  744. void *JS_GetOpaque2(JSContext *ctx, JSValueConst obj, JSClassID class_id);
  745. void *JS_GetAnyOpaque(JSValueConst obj, JSClassID *class_id);
  746. /* 'buf' must be zero terminated i.e. buf[buf_len] = '\0'. */
  747. JSValue JS_ParseJSON(JSContext *ctx, const char *buf, size_t buf_len,
  748. const char *filename);
  749. #define JS_PARSE_JSON_EXT (1 << 0) /* allow extended JSON */
  750. JSValue JS_ParseJSON2(JSContext *ctx, const char *buf, size_t buf_len,
  751. const char *filename, int flags);
  752. JSValue JS_JSONStringify(JSContext *ctx, JSValueConst obj,
  753. JSValueConst replacer, JSValueConst space0);
  754. typedef void JSFreeArrayBufferDataFunc(JSRuntime *rt, void *opaque, void *ptr);
  755. JSValue JS_NewArrayBuffer(JSContext *ctx, uint8_t *buf, size_t len,
  756. JSFreeArrayBufferDataFunc *free_func, void *opaque,
  757. JS_BOOL is_shared);
  758. JSValue JS_NewArrayBufferCopy(JSContext *ctx, const uint8_t *buf, size_t len);
  759. void JS_DetachArrayBuffer(JSContext *ctx, JSValueConst obj);
  760. uint8_t *JS_GetArrayBuffer(JSContext *ctx, size_t *psize, JSValueConst obj);
  761. typedef enum JSTypedArrayEnum {
  762. JS_TYPED_ARRAY_UINT8C = 0,
  763. JS_TYPED_ARRAY_INT8,
  764. JS_TYPED_ARRAY_UINT8,
  765. JS_TYPED_ARRAY_INT16,
  766. JS_TYPED_ARRAY_UINT16,
  767. JS_TYPED_ARRAY_INT32,
  768. JS_TYPED_ARRAY_UINT32,
  769. JS_TYPED_ARRAY_BIG_INT64,
  770. JS_TYPED_ARRAY_BIG_UINT64,
  771. JS_TYPED_ARRAY_FLOAT16,
  772. JS_TYPED_ARRAY_FLOAT32,
  773. JS_TYPED_ARRAY_FLOAT64,
  774. } JSTypedArrayEnum;
  775. JSValue JS_NewTypedArray(JSContext *ctx, int argc, JSValueConst *argv,
  776. JSTypedArrayEnum array_type);
  777. JSValue JS_GetTypedArrayBuffer(JSContext *ctx, JSValueConst obj,
  778. size_t *pbyte_offset,
  779. size_t *pbyte_length,
  780. size_t *pbytes_per_element);
  781. typedef struct {
  782. void *(*sab_alloc)(void *opaque, size_t size);
  783. void (*sab_free)(void *opaque, void *ptr);
  784. void (*sab_dup)(void *opaque, void *ptr);
  785. void *sab_opaque;
  786. } JSSharedArrayBufferFunctions;
  787. void JS_SetSharedArrayBufferFunctions(JSRuntime *rt,
  788. const JSSharedArrayBufferFunctions *sf);
  789. typedef enum JSPromiseStateEnum {
  790. JS_PROMISE_PENDING,
  791. JS_PROMISE_FULFILLED,
  792. JS_PROMISE_REJECTED,
  793. } JSPromiseStateEnum;
  794. JSValue JS_NewPromiseCapability(JSContext *ctx, JSValue *resolving_funcs);
  795. JSPromiseStateEnum JS_PromiseState(JSContext *ctx, JSValue promise);
  796. JSValue JS_PromiseResult(JSContext *ctx, JSValue promise);
  797. /* is_handled = TRUE means that the rejection is handled */
  798. typedef void JSHostPromiseRejectionTracker(JSContext *ctx, JSValueConst promise,
  799. JSValueConst reason,
  800. JS_BOOL is_handled, void *opaque);
  801. void JS_SetHostPromiseRejectionTracker(JSRuntime *rt, JSHostPromiseRejectionTracker *cb, void *opaque);
  802. /* return != 0 if the JS code needs to be interrupted */
  803. typedef int JSInterruptHandler(JSRuntime *rt, void *opaque);
  804. void JS_SetInterruptHandler(JSRuntime *rt, JSInterruptHandler *cb, void *opaque);
  805. /* if can_block is TRUE, Atomics.wait() can be used */
  806. void JS_SetCanBlock(JSRuntime *rt, JS_BOOL can_block);
  807. /* select which debug info is stripped from the compiled code */
  808. #define JS_STRIP_SOURCE (1 << 0) /* strip source code */
  809. #define JS_STRIP_DEBUG (1 << 1) /* strip all debug info including source code */
  810. void JS_SetStripInfo(JSRuntime *rt, int flags);
  811. int JS_GetStripInfo(JSRuntime *rt);
  812. /* set the [IsHTMLDDA] internal slot */
  813. void JS_SetIsHTMLDDA(JSContext *ctx, JSValueConst obj);
  814. typedef struct JSModuleDef JSModuleDef;
  815. /* return the module specifier (allocated with js_malloc()) or NULL if
  816. exception */
  817. typedef char *JSModuleNormalizeFunc(JSContext *ctx,
  818. const char *module_base_name,
  819. const char *module_name, void *opaque);
  820. typedef JSModuleDef *JSModuleLoaderFunc(JSContext *ctx,
  821. const char *module_name, void *opaque);
  822. typedef JSModuleDef *JSModuleLoaderFunc2(JSContext *ctx,
  823. const char *module_name, void *opaque,
  824. JSValueConst attributes);
  825. /* return -1 if exception, 0 if OK */
  826. typedef int JSModuleCheckSupportedImportAttributes(JSContext *ctx, void *opaque,
  827. JSValueConst attributes);
  828. /* module_normalize = NULL is allowed and invokes the default module
  829. filename normalizer */
  830. void JS_SetModuleLoaderFunc(JSRuntime *rt,
  831. JSModuleNormalizeFunc *module_normalize,
  832. JSModuleLoaderFunc *module_loader, void *opaque);
  833. /* same as JS_SetModuleLoaderFunc but with attributes. if
  834. module_check_attrs = NULL, no attribute checking is done. */
  835. void JS_SetModuleLoaderFunc2(JSRuntime *rt,
  836. JSModuleNormalizeFunc *module_normalize,
  837. JSModuleLoaderFunc2 *module_loader,
  838. JSModuleCheckSupportedImportAttributes *module_check_attrs,
  839. void *opaque);
  840. /* return the import.meta object of a module */
  841. JSValue JS_GetImportMeta(JSContext *ctx, JSModuleDef *m);
  842. JSAtom JS_GetModuleName(JSContext *ctx, JSModuleDef *m);
  843. JSValue JS_GetModuleNamespace(JSContext *ctx, JSModuleDef *m);
  844. /* JS Job support */
  845. typedef JSValue JSJobFunc(JSContext *ctx, int argc, JSValueConst *argv);
  846. int JS_EnqueueJob(JSContext *ctx, JSJobFunc *job_func, int argc, JSValueConst *argv);
  847. JS_BOOL JS_IsJobPending(JSRuntime *rt);
  848. int JS_ExecutePendingJob(JSRuntime *rt, JSContext **pctx);
  849. /* Object Writer/Reader (currently only used to handle precompiled code) */
  850. #define JS_WRITE_OBJ_BYTECODE (1 << 0) /* allow function/module */
  851. #define JS_WRITE_OBJ_BSWAP (1 << 1) /* byte swapped output */
  852. #define JS_WRITE_OBJ_SAB (1 << 2) /* allow SharedArrayBuffer */
  853. #define JS_WRITE_OBJ_REFERENCE (1 << 3) /* allow object references to
  854. encode arbitrary object
  855. graph */
  856. uint8_t *JS_WriteObject(JSContext *ctx, size_t *psize, JSValueConst obj,
  857. int flags);
  858. uint8_t *JS_WriteObject2(JSContext *ctx, size_t *psize, JSValueConst obj,
  859. int flags, uint8_t ***psab_tab, size_t *psab_tab_len);
  860. #define JS_READ_OBJ_BYTECODE (1 << 0) /* allow function/module */
  861. #define JS_READ_OBJ_ROM_DATA (1 << 1) /* avoid duplicating 'buf' data */
  862. #define JS_READ_OBJ_SAB (1 << 2) /* allow SharedArrayBuffer */
  863. #define JS_READ_OBJ_REFERENCE (1 << 3) /* allow object references */
  864. JSValue JS_ReadObject(JSContext *ctx, const uint8_t *buf, size_t buf_len,
  865. int flags);
  866. /* instantiate and evaluate a bytecode function. Only used when
  867. reading a script or module with JS_ReadObject() */
  868. JSValue JS_EvalFunction(JSContext *ctx, JSValue fun_obj);
  869. /* load the dependencies of the module 'obj'. Useful when JS_ReadObject()
  870. returns a module. */
  871. int JS_ResolveModule(JSContext *ctx, JSValueConst obj);
  872. /* only exported for os.Worker() */
  873. JSAtom JS_GetScriptOrModuleName(JSContext *ctx, int n_stack_levels);
  874. /* only exported for os.Worker() */
  875. JSValue JS_LoadModule(JSContext *ctx, const char *basename,
  876. const char *filename);
  877. /* C function definition */
  878. typedef enum JSCFunctionEnum { /* XXX: should rename for namespace isolation */
  879. JS_CFUNC_generic,
  880. JS_CFUNC_generic_magic,
  881. JS_CFUNC_constructor,
  882. JS_CFUNC_constructor_magic,
  883. JS_CFUNC_constructor_or_func,
  884. JS_CFUNC_constructor_or_func_magic,
  885. JS_CFUNC_f_f,
  886. JS_CFUNC_f_f_f,
  887. JS_CFUNC_getter,
  888. JS_CFUNC_setter,
  889. JS_CFUNC_getter_magic,
  890. JS_CFUNC_setter_magic,
  891. JS_CFUNC_iterator_next,
  892. } JSCFunctionEnum;
  893. typedef union JSCFunctionType {
  894. JSCFunction *generic;
  895. JSValue (*generic_magic)(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic);
  896. JSCFunction *constructor;
  897. JSValue (*constructor_magic)(JSContext *ctx, JSValueConst new_target, int argc, JSValueConst *argv, int magic);
  898. JSCFunction *constructor_or_func;
  899. double (*f_f)(double);
  900. double (*f_f_f)(double, double);
  901. JSValue (*getter)(JSContext *ctx, JSValueConst this_val);
  902. JSValue (*setter)(JSContext *ctx, JSValueConst this_val, JSValueConst val);
  903. JSValue (*getter_magic)(JSContext *ctx, JSValueConst this_val, int magic);
  904. JSValue (*setter_magic)(JSContext *ctx, JSValueConst this_val, JSValueConst val, int magic);
  905. JSValue (*iterator_next)(JSContext *ctx, JSValueConst this_val,
  906. int argc, JSValueConst *argv, int *pdone, int magic);
  907. } JSCFunctionType;
  908. JSValue JS_NewCFunction2(JSContext *ctx, JSCFunction *func,
  909. const char *name,
  910. int length, JSCFunctionEnum cproto, int magic);
  911. JSValue JS_NewCFunctionData(JSContext *ctx, JSCFunctionData *func,
  912. int length, int magic, int data_len,
  913. JSValueConst *data);
  914. static inline JSValue JS_NewCFunction(JSContext *ctx, JSCFunction *func, const char *name,
  915. int length)
  916. {
  917. return JS_NewCFunction2(ctx, func, name, length, JS_CFUNC_generic, 0);
  918. }
  919. static inline JSValue JS_NewCFunctionMagic(JSContext *ctx, JSCFunctionMagic *func,
  920. const char *name,
  921. int length, JSCFunctionEnum cproto, int magic)
  922. {
  923. /* Used to squelch a -Wcast-function-type warning. */
  924. JSCFunctionType ft = { .generic_magic = func };
  925. return JS_NewCFunction2(ctx, ft.generic, name, length, cproto, magic);
  926. }
  927. int JS_SetConstructor(JSContext *ctx, JSValueConst func_obj,
  928. JSValueConst proto);
  929. /* C property definition */
  930. typedef struct JSCFunctionListEntry {
  931. const char *name;
  932. uint8_t prop_flags;
  933. uint8_t def_type;
  934. int16_t magic;
  935. union {
  936. struct {
  937. uint8_t length; /* XXX: should move outside union */
  938. uint8_t cproto; /* XXX: should move outside union */
  939. JSCFunctionType cfunc;
  940. } func;
  941. struct {
  942. JSCFunctionType get;
  943. JSCFunctionType set;
  944. } getset;
  945. struct {
  946. const char *name;
  947. int base;
  948. } alias;
  949. struct {
  950. const struct JSCFunctionListEntry *tab;
  951. int len;
  952. } prop_list;
  953. const char *str;
  954. int32_t i32;
  955. int64_t i64;
  956. double f64;
  957. } u;
  958. } JSCFunctionListEntry;
  959. #define JS_DEF_CFUNC 0
  960. #define JS_DEF_CGETSET 1
  961. #define JS_DEF_CGETSET_MAGIC 2
  962. #define JS_DEF_PROP_STRING 3
  963. #define JS_DEF_PROP_INT32 4
  964. #define JS_DEF_PROP_INT64 5
  965. #define JS_DEF_PROP_DOUBLE 6
  966. #define JS_DEF_PROP_UNDEFINED 7
  967. #define JS_DEF_OBJECT 8
  968. #define JS_DEF_ALIAS 9
  969. #define JS_DEF_PROP_ATOM 10
  970. #define JS_DEF_PROP_BOOL 11
  971. /* Note: c++ does not like nested designators */
  972. #define JS_CFUNC_DEF(name, length, func1) { name, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE, JS_DEF_CFUNC, 0, .u = { .func = { length, JS_CFUNC_generic, { .generic = func1 } } } }
  973. #define JS_CFUNC_MAGIC_DEF(name, length, func1, magic) { name, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE, JS_DEF_CFUNC, magic, .u = { .func = { length, JS_CFUNC_generic_magic, { .generic_magic = func1 } } } }
  974. #define JS_CFUNC_SPECIAL_DEF(name, length, cproto, func1) { name, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE, JS_DEF_CFUNC, 0, .u = { .func = { length, JS_CFUNC_ ## cproto, { .cproto = func1 } } } }
  975. #define JS_ITERATOR_NEXT_DEF(name, length, func1, magic) { name, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE, JS_DEF_CFUNC, magic, .u = { .func = { length, JS_CFUNC_iterator_next, { .iterator_next = func1 } } } }
  976. #define JS_CGETSET_DEF(name, fgetter, fsetter) { name, JS_PROP_CONFIGURABLE, JS_DEF_CGETSET, 0, .u = { .getset = { .get = { .getter = fgetter }, .set = { .setter = fsetter } } } }
  977. #define JS_CGETSET_MAGIC_DEF(name, fgetter, fsetter, magic) { name, JS_PROP_CONFIGURABLE, JS_DEF_CGETSET_MAGIC, magic, .u = { .getset = { .get = { .getter_magic = fgetter }, .set = { .setter_magic = fsetter } } } }
  978. #define JS_PROP_STRING_DEF(name, cstr, prop_flags) { name, prop_flags, JS_DEF_PROP_STRING, 0, .u = { .str = cstr } }
  979. #define JS_PROP_INT32_DEF(name, val, prop_flags) { name, prop_flags, JS_DEF_PROP_INT32, 0, .u = { .i32 = val } }
  980. #define JS_PROP_INT64_DEF(name, val, prop_flags) { name, prop_flags, JS_DEF_PROP_INT64, 0, .u = { .i64 = val } }
  981. #define JS_PROP_DOUBLE_DEF(name, val, prop_flags) { name, prop_flags, JS_DEF_PROP_DOUBLE, 0, .u = { .f64 = val } }
  982. #define JS_PROP_UNDEFINED_DEF(name, prop_flags) { name, prop_flags, JS_DEF_PROP_UNDEFINED, 0, .u = { .i32 = 0 } }
  983. #define JS_PROP_ATOM_DEF(name, val, prop_flags) { name, prop_flags, JS_DEF_PROP_ATOM, 0, .u = { .i32 = val } }
  984. #define JS_PROP_BOOL_DEF(name, val, prop_flags) { name, prop_flags, JS_DEF_PROP_BOOL, 0, .u = { .i32 = val } }
  985. #define JS_OBJECT_DEF(name, tab, len, prop_flags) { name, prop_flags, JS_DEF_OBJECT, 0, .u = { .prop_list = { tab, len } } }
  986. #define JS_ALIAS_DEF(name, from) { name, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE, JS_DEF_ALIAS, 0, .u = { .alias = { from, -1 } } }
  987. #define JS_ALIAS_BASE_DEF(name, from, base) { name, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE, JS_DEF_ALIAS, 0, .u = { .alias = { from, base } } }
  988. int JS_SetPropertyFunctionList(JSContext *ctx, JSValueConst obj,
  989. const JSCFunctionListEntry *tab,
  990. int len);
  991. /* C module definition */
  992. typedef int JSModuleInitFunc(JSContext *ctx, JSModuleDef *m);
  993. JSModuleDef *JS_NewCModule(JSContext *ctx, const char *name_str,
  994. JSModuleInitFunc *func);
  995. /* can only be called before the module is instantiated */
  996. int JS_AddModuleExport(JSContext *ctx, JSModuleDef *m, const char *name_str);
  997. int JS_AddModuleExportList(JSContext *ctx, JSModuleDef *m,
  998. const JSCFunctionListEntry *tab, int len);
  999. /* can only be called after the module is instantiated */
  1000. int JS_SetModuleExport(JSContext *ctx, JSModuleDef *m, const char *export_name,
  1001. JSValue val);
  1002. int JS_SetModuleExportList(JSContext *ctx, JSModuleDef *m,
  1003. const JSCFunctionListEntry *tab, int len);
  1004. /* associate a JSValue to a C module */
  1005. int JS_SetModulePrivateValue(JSContext *ctx, JSModuleDef *m, JSValue val);
  1006. JSValue JS_GetModulePrivateValue(JSContext *ctx, JSModuleDef *m);
  1007. /* debug value output */
  1008. typedef struct {
  1009. JS_BOOL show_hidden : 8; /* only show enumerable properties */
  1010. JS_BOOL raw_dump : 8; /* avoid doing autoinit and avoid any malloc() call (for internal use) */
  1011. uint32_t max_depth; /* recurse up to this depth, 0 = no limit */
  1012. uint32_t max_string_length; /* print no more than this length for
  1013. strings, 0 = no limit */
  1014. uint32_t max_item_count; /* print no more than this count for
  1015. arrays or objects, 0 = no limit */
  1016. } JSPrintValueOptions;
  1017. typedef void JSPrintValueWrite(void *opaque, const char *buf, size_t len);
  1018. void JS_PrintValueSetDefaultOptions(JSPrintValueOptions *options);
  1019. void JS_PrintValueRT(JSRuntime *rt, JSPrintValueWrite *write_func, void *write_opaque,
  1020. JSValueConst val, const JSPrintValueOptions *options);
  1021. void JS_PrintValue(JSContext *ctx, JSPrintValueWrite *write_func, void *write_opaque,
  1022. JSValueConst val, const JSPrintValueOptions *options);
  1023. #undef js_unlikely
  1024. #undef js_force_inline
  1025. #ifdef __cplusplus
  1026. } /* extern "C" { */
  1027. #endif
  1028. #endif /* QUICKJS_H */