1095 lines · 41.0 KB · C
RawDownload
/* * QuickJS Javascript Engine * * Copyright (c) 2017-2020 Fabrice Bellard * Copyright (c) 2017-2020 Charlie Gordon * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */#ifndef QUICKJS_H#define QUICKJS_H #include <stdio.h>#include <stdint.h> #ifdef __cplusplusextern "C" {#endif #if defined(__GNUC__) || defined(__clang__)#define js_likely(x)          __builtin_expect(!!(x), 1)#define js_unlikely(x)        __builtin_expect(!!(x), 0)#define js_force_inline       inline __attribute__((always_inline))#define __js_printf_like(f, a)   __attribute__((format(printf, f, a)))#else#define js_likely(x)     (x)#define js_unlikely(x)   (x)#define js_force_inline  inline#define __js_printf_like(a, b)#endif #define JS_BOOL int typedef struct JSRuntime JSRuntime;typedef struct JSContext JSContext;typedef struct JSObject JSObject;typedef struct JSClass JSClass;typedef uint32_t JSClassID;typedef uint32_t JSAtom; #pragma incomplete JSRuntime#pragma incomplete JSContext#pragma incomplete JSObject#pragma incomplete JSClass #ifdef __amd64__#define JS_PTR64#define JS_PTR64_DEF(a) a#else#define JS_PTR64_DEF(a)#endif #ifndef JS_PTR64#define JS_NAN_BOXING#endif enum {    /* all tags with a reference count are negative */    JS_TAG_FIRST       = -11, /* first negative tag */    JS_TAG_BIG_DECIMAL = -11,    JS_TAG_BIG_INT     = -10,    JS_TAG_BIG_FLOAT   = -9,    JS_TAG_SYMBOL      = -8,    JS_TAG_STRING      = -7,    JS_TAG_MODULE      = -3, /* used internally */    JS_TAG_FUNCTION_BYTECODE = -2, /* used internally */    JS_TAG_OBJECT      = -1,     JS_TAG_INT         = 0,    JS_TAG_BOOL        = 1,    JS_TAG_NULL        = 2,    JS_TAG_UNDEFINED   = 3,    JS_TAG_UNINITIALIZED = 4,    JS_TAG_CATCH_OFFSET = 5,    JS_TAG_EXCEPTION   = 6,    JS_TAG_FLOAT64     = 7,    /* any larger tag is FLOAT64 if JS_NAN_BOXING */}; typedef struct JSRefCountHeader {    int ref_count;} JSRefCountHeader; #pragma incomplete JSRefCountHeader #define JS_FLOAT64_NAN NAN #ifdef CONFIG_CHECK_JSVALUE/* JSValue consistency : it is not possible to run the code in this   mode, but it is useful to detect simple reference counting   errors. It would be interesting to modify a static C analyzer to   handle specific annotations (clang has such annotations but only   for objective C) */typedef struct __JSValue *JSValue;typedef const struct __JSValue *JSValueConst; #pragma incomplete JSValue#pragma incomplete JSValueConst #define JS_VALUE_GET_TAG(v) (int)((uintptr_t)(v) & 0xf)/* same as JS_VALUE_GET_TAG, but return JS_TAG_FLOAT64 with NaN boxing */#define JS_VALUE_GET_NORM_TAG(v) JS_VALUE_GET_TAG(v)#define JS_VALUE_GET_INT(v) (int)((intptr_t)(v) >> 4)#define JS_VALUE_GET_BOOL(v) JS_VALUE_GET_INT(v)#define JS_VALUE_GET_FLOAT64(v) (double)JS_VALUE_GET_INT(v)#define JS_VALUE_GET_PTR(v) (void *)((intptr_t)(v) & ~0xf) #define JS_MKVAL(tag, val) (JSValue)(intptr_t)(((val) << 4) | (tag))#define JS_MKPTR(tag, p) (JSValue)((intptr_t)(p) | (tag)) #define JS_TAG_IS_FLOAT64(tag) ((unsigned)(tag) == JS_TAG_FLOAT64) #define JS_NAN JS_MKVAL(JS_TAG_FLOAT64, 1) static inline JSValue __JS_NewFloat64(JSContext *ctx, double d){    return JS_MKVAL(JS_TAG_FLOAT64, (int)d);} static inline JS_BOOL JS_VALUE_IS_NAN(JSValue v){    return 0;}    #elif defined(JS_NAN_BOXING) typedef uint64_t JSValue; #define JSValueConst JSValue #define JS_VALUE_GET_TAG(v) (int)((v) >> 32)#define JS_VALUE_GET_INT(v) (int)(v)#define JS_VALUE_GET_BOOL(v) (int)(v)#define JS_VALUE_GET_PTR(v) (void *)(intptr_t)(v) #define JS_MKVAL(tag, val) (((uint64_t)(tag) << 32) | (uint32_t)(val))#define JS_MKPTR(tag, ptr) (((uint64_t)(tag) << 32) | (uintptr_t)(ptr)) #define JS_FLOAT64_TAG_ADDEND (0x7ff80000 - JS_TAG_FIRST + 1) /* quiet NaN encoding */ static inline double JS_VALUE_GET_FLOAT64(JSValue v){    union {        JSValue v;        double d;    } u;    u.v = v;    u.v += (uint64_t)JS_FLOAT64_TAG_ADDEND << 32;    return u.d;} #define JS_NAN (0x7ff8000000000000 - ((uint64_t)JS_FLOAT64_TAG_ADDEND << 32)) static inline JSValue __JS_NewFloat64(JSContext *ctx, double d){    union {        double d;        uint64_t u64;    } u;    JSValue v;    u.d = d;    /* normalize NaN */    if (js_unlikely((u.u64 & 0x7fffffffffffffff) > 0x7ff0000000000000))        v = JS_NAN;    else        v = u.u64 - ((uint64_t)JS_FLOAT64_TAG_ADDEND << 32);    return v;} #define JS_TAG_IS_FLOAT64(tag) ((unsigned)((tag) - JS_TAG_FIRST) >= (JS_TAG_FLOAT64 - JS_TAG_FIRST)) /* same as JS_VALUE_GET_TAG, but return JS_TAG_FLOAT64 with NaN boxing */static inline int JS_VALUE_GET_NORM_TAG(JSValue v){    uint32_t tag;    tag = JS_VALUE_GET_TAG(v);    if (JS_TAG_IS_FLOAT64(tag))        return JS_TAG_FLOAT64;    else        return tag;} static inline JS_BOOL JS_VALUE_IS_NAN(JSValue v){    uint32_t tag;    tag = JS_VALUE_GET_TAG(v);    return tag == (JS_NAN >> 32);}    #else /* !JS_NAN_BOXING */ typedef union JSValueUnion {    int32_t int32;    double float64;    void *ptr;} JSValueUnion; typedef struct JSValue {    JSValueUnion u;    int64_t tag;} JSValue; #define JSValueConst JSValue #define JS_VALUE_GET_TAG(v) ((int32_t)(v).tag)/* same as JS_VALUE_GET_TAG, but return JS_TAG_FLOAT64 with NaN boxing */#define JS_VALUE_GET_NORM_TAG(v) JS_VALUE_GET_TAG(v)#define JS_VALUE_GET_INT(v) ((v).u.int32)#define JS_VALUE_GET_BOOL(v) ((v).u.int32)#define JS_VALUE_GET_FLOAT64(v) ((v).u.float64)#define JS_VALUE_GET_PTR(v) ((v).u.ptr) static JSValueJS_MKVAL(int64_t tag, int32_t val){	JSValue v = {		.u = {			.int32 = val,		},		.tag = tag,	};	return v;} static JSValueJS_MKPTR(int64_t tag, void *p){	JSValue v = {		.u = {			.ptr = p,		},		.tag = tag,	};	return v;} static JSValue_JS_NAN(void){	JSValue v = {		.u = {			.float64 = JS_FLOAT64_NAN,		},		.tag = JS_TAG_FLOAT64,	};	return v;}#define JS_NAN _JS_NAN() /*#define JS_MKVAL(tag, val) (JSValue){ .u = (JSValueUnion){ .int32 = val }, tag }#define JS_MKPTR(tag, p) (JSValue){ .u = (JSValueUnion){ .ptr = p }, tag }#define JS_NAN (JSValue){ .u.float64 = JS_FLOAT64_NAN, JS_TAG_FLOAT64 }*/ #define JS_TAG_IS_FLOAT64(tag) ((unsigned)(tag) == JS_TAG_FLOAT64) static inline JSValue __JS_NewFloat64(JSContext *ctx, double d){    JSValue v;    v.tag = JS_TAG_FLOAT64;    v.u.float64 = d;    return v;} static inline JS_BOOL JS_VALUE_IS_NAN(JSValue v){    union {        double d;        uint64_t u64;    } u;    if (v.tag != JS_TAG_FLOAT64)        return 0;    u.d = v.u.float64;    return (u.u64 & 0x7fffffffffffffff) > 0x7ff0000000000000;} #endif /* !JS_NAN_BOXING */ #define JS_VALUE_IS_BOTH_INT(v1, v2) ((JS_VALUE_GET_TAG(v1) | JS_VALUE_GET_TAG(v2)) == 0)#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))) #define JS_VALUE_GET_OBJ(v) ((JSObject *)JS_VALUE_GET_PTR(v))#define JS_VALUE_GET_STRING(v) ((JSString *)JS_VALUE_GET_PTR(v))#define JS_VALUE_HAS_REF_COUNT(v) ((unsigned)JS_VALUE_GET_TAG(v) >= (unsigned)JS_TAG_FIRST) /* special values */#define JS_NULL      JS_MKVAL(JS_TAG_NULL, 0)#define JS_UNDEFINED JS_MKVAL(JS_TAG_UNDEFINED, 0)#define JS_FALSE     JS_MKVAL(JS_TAG_BOOL, 0)#define JS_TRUE      JS_MKVAL(JS_TAG_BOOL, 1)#define JS_EXCEPTION JS_MKVAL(JS_TAG_EXCEPTION, 0)#define JS_UNINITIALIZED JS_MKVAL(JS_TAG_UNINITIALIZED, 0) /* flags for object properties */#define JS_PROP_CONFIGURABLE  (1 << 0)#define JS_PROP_WRITABLE      (1 << 1)#define JS_PROP_ENUMERABLE    (1 << 2)#define JS_PROP_C_W_E         (JS_PROP_CONFIGURABLE | JS_PROP_WRITABLE | JS_PROP_ENUMERABLE)#define JS_PROP_LENGTH        (1 << 3) /* used internally in Arrays */#define JS_PROP_TMASK         (3 << 4) /* mask for NORMAL, GETSET, VARREF, AUTOINIT */#define JS_PROP_NORMAL         (0 << 4)#define JS_PROP_GETSET         (1 << 4)#define JS_PROP_VARREF         (2 << 4) /* used internally */#define JS_PROP_AUTOINIT       (3 << 4) /* used internally */ /* flags for JS_DefineProperty */#define JS_PROP_HAS_SHIFT        8#define JS_PROP_HAS_CONFIGURABLE (1 << 8)#define JS_PROP_HAS_WRITABLE     (1 << 9)#define JS_PROP_HAS_ENUMERABLE   (1 << 10)#define JS_PROP_HAS_GET          (1 << 11)#define JS_PROP_HAS_SET          (1 << 12)#define JS_PROP_HAS_VALUE        (1 << 13) /* throw an exception if false would be returned   (JS_DefineProperty/JS_SetProperty) */#define JS_PROP_THROW            (1 << 14)/* throw an exception if false would be returned in strict mode   (JS_SetProperty) */#define JS_PROP_THROW_STRICT     (1 << 15) #define JS_PROP_NO_ADD           (1 << 16) /* internal use */#define JS_PROP_NO_EXOTIC        (1 << 17) /* internal use */ #define JS_DEFAULT_STACK_SIZE (256 * 1024) /* JS_Eval() flags */#define JS_EVAL_TYPE_GLOBAL   (0 << 0) /* global code (default) */#define JS_EVAL_TYPE_MODULE   (1 << 0) /* module code */#define JS_EVAL_TYPE_DIRECT   (2 << 0) /* direct call (internal use) */#define JS_EVAL_TYPE_INDIRECT (3 << 0) /* indirect call (internal use) */#define JS_EVAL_TYPE_MASK     (3 << 0) #define JS_EVAL_FLAG_STRICT   (1 << 3) /* force 'strict' mode */#define JS_EVAL_FLAG_STRIP    (1 << 4) /* force 'strip' mode *//* compile but do not run. The result is an object with a   JS_TAG_FUNCTION_BYTECODE or JS_TAG_MODULE tag. It can be executed   with JS_EvalFunction(). */#define JS_EVAL_FLAG_COMPILE_ONLY (1 << 5)/* don't include the stack frames before this eval in the Error() backtraces */#define JS_EVAL_FLAG_BACKTRACE_BARRIER (1 << 6) typedef JSValue JSCFunction(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv);typedef JSValue JSCFunctionMagic(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic);typedef JSValue JSCFunctionData(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic, JSValue *func_data); typedef struct JSMallocState {    size_t malloc_count;    size_t malloc_size;    size_t malloc_limit;    void *opaque; /* user opaque */} JSMallocState; typedef struct JSMallocFunctions {    void *(*js_malloc)(JSMallocState *s, size_t size);    void (*js_free)(JSMallocState *s, void *ptr);    void *(*js_realloc)(JSMallocState *s, void *ptr, size_t size);    size_t (*js_malloc_usable_size)(const void *ptr);} JSMallocFunctions; typedef struct JSGCObjectHeader JSGCObjectHeader; JSRuntime *JS_NewRuntime(void);/* info lifetime must exceed that of rt */void JS_SetRuntimeInfo(JSRuntime *rt, const char *info);void JS_SetMemoryLimit(JSRuntime *rt, size_t limit);void JS_SetGCThreshold(JSRuntime *rt, size_t gc_threshold);void JS_SetMaxStackSize(JSRuntime *rt, size_t stack_size);JSRuntime *JS_NewRuntime2(const JSMallocFunctions *mf, void *opaque);void JS_FreeRuntime(JSRuntime *rt);void *JS_GetRuntimeOpaque(JSRuntime *rt);void JS_SetRuntimeOpaque(JSRuntime *rt, void *opaque);typedef void JS_MarkFunc(JSRuntime *rt, JSGCObjectHeader *gp);#pragma incomplete JSGCObjectHeadervoid JS_MarkValue(JSRuntime *rt, JSValueConst val, JS_MarkFunc *mark_func);void JS_RunGC(JSRuntime *rt);JS_BOOL JS_IsLiveObject(JSRuntime *rt, JSValueConst obj); JSContext *JS_NewContext(JSRuntime *rt);void JS_FreeContext(JSContext *s);JSContext *JS_DupContext(JSContext *ctx);void *JS_GetContextOpaque(JSContext *ctx);void JS_SetContextOpaque(JSContext *ctx, void *opaque);JSRuntime *JS_GetRuntime(JSContext *ctx);void JS_SetClassProto(JSContext *ctx, JSClassID class_id, JSValue obj);JSValue JS_GetClassProto(JSContext *ctx, JSClassID class_id); /* the following functions are used to select the intrinsic object to   save memory */JSContext *JS_NewContextRaw(JSRuntime *rt);void JS_AddIntrinsicBaseObjects(JSContext *ctx);void JS_AddIntrinsicDate(JSContext *ctx);void JS_AddIntrinsicEval(JSContext *ctx);void JS_AddIntrinsicStringNormalize(JSContext *ctx);void JS_AddIntrinsicRegExpCompiler(JSContext *ctx);void JS_AddIntrinsicRegExp(JSContext *ctx);void JS_AddIntrinsicJSON(JSContext *ctx);void JS_AddIntrinsicProxy(JSContext *ctx);void JS_AddIntrinsicMapSet(JSContext *ctx);void JS_AddIntrinsicTypedArrays(JSContext *ctx);void JS_AddIntrinsicPromise(JSContext *ctx);void JS_AddIntrinsicBigInt(JSContext *ctx);void JS_AddIntrinsicBigFloat(JSContext *ctx);void JS_AddIntrinsicBigDecimal(JSContext *ctx);/* enable operator overloading */void JS_AddIntrinsicOperators(JSContext *ctx);/* enable "use math" */void JS_EnableBignumExt(JSContext *ctx, JS_BOOL enable); JSValue js_string_codePointRange(JSContext *ctx, JSValueConst this_val,                                 int argc, JSValueConst *argv); void *js_malloc_rt(JSRuntime *rt, size_t size);void js_free_rt(JSRuntime *rt, void *ptr);void *js_realloc_rt(JSRuntime *rt, void *ptr, size_t size);size_t js_malloc_usable_size_rt(JSRuntime *rt, const void *ptr);void *js_mallocz_rt(JSRuntime *rt, size_t size); void *js_malloc(JSContext *ctx, size_t size);void js_free(JSContext *ctx, void *ptr);void *js_realloc(JSContext *ctx, void *ptr, size_t size);size_t js_malloc_usable_size(JSContext *ctx, const void *ptr);void *js_realloc2(JSContext *ctx, void *ptr, size_t size, size_t *pslack);void *js_mallocz(JSContext *ctx, size_t size);char *js_strdup(JSContext *ctx, const char *str);char *js_strndup(JSContext *ctx, const char *s, size_t n); typedef struct JSMemoryUsage {    int64_t malloc_size, malloc_limit, memory_used_size;    int64_t malloc_count;    int64_t memory_used_count;    int64_t atom_count, atom_size;    int64_t str_count, str_size;    int64_t obj_count, obj_size;    int64_t prop_count, prop_size;    int64_t shape_count, shape_size;    int64_t js_func_count, js_func_size, js_func_code_size;    int64_t js_func_pc2line_count, js_func_pc2line_size;    int64_t c_func_count, array_count;    int64_t fast_array_count, fast_array_elements;    int64_t binary_object_count, binary_object_size;} JSMemoryUsage; void JS_ComputeMemoryUsage(JSRuntime *rt, JSMemoryUsage *s);void JS_DumpMemoryUsage(FILE *fp, const JSMemoryUsage *s, JSRuntime *rt); /* atom support */#define JS_ATOM_NULL 0 JSAtom JS_NewAtomLen(JSContext *ctx, const char *str, size_t len);JSAtom JS_NewAtom(JSContext *ctx, const char *str);JSAtom JS_NewAtomUInt32(JSContext *ctx, uint32_t n);JSAtom JS_DupAtom(JSContext *ctx, JSAtom v);void JS_FreeAtom(JSContext *ctx, JSAtom v);void JS_FreeAtomRT(JSRuntime *rt, JSAtom v);JSValue JS_AtomToValue(JSContext *ctx, JSAtom atom);JSValue JS_AtomToString(JSContext *ctx, JSAtom atom);const char *JS_AtomToCString(JSContext *ctx, JSAtom atom);JSAtom JS_ValueToAtom(JSContext *ctx, JSValueConst val); /* object class support */ typedef struct JSPropertyEnum {    JS_BOOL is_enumerable;    JSAtom atom;} JSPropertyEnum; typedef struct JSPropertyDescriptor {    int flags;    JSValue value;    JSValue getter;    JSValue setter;} JSPropertyDescriptor; typedef struct JSClassExoticMethods {    /* Return -1 if exception (can only happen in case of Proxy object),       FALSE if the property does not exists, TRUE if it exists. If 1 is       returned, the property descriptor 'desc' is filled if != NULL. */    int (*get_own_property)(JSContext *ctx, JSPropertyDescriptor *desc,                             JSValueConst obj, JSAtom prop);    /* '*ptab' should hold the '*plen' property keys. Return 0 if OK,       -1 if exception. The 'is_enumerable' field is ignored.    */    int (*get_own_property_names)(JSContext *ctx, JSPropertyEnum **ptab,

Lines 1–500 of 1095.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t