#ifndef MQUICKJS_H
#define MQUICKJS_H
#include <inttypes.h>
#include <stddef.h>
#if defined(__GNUC__) || defined(__clang__)
#define __js_printf_like(f, a) __attribute__((format(printf, f, a)))
#else
#define __js_printf_like(a, b)
#endif
#if INTPTR_MAX >= INT64_MAX
#define JS_PTR64
#endif
typedef struct JSContext JSContext;
#ifdef JS_PTR64
typedef uint64_t JSWord;
typedef uint64_t JSValue;
#define JSW 8
#define JSValue_PRI PRIo64
#define JS_USE_SHORT_FLOAT
#else
typedef uint32_t JSWord;
typedef uint32_t JSValue;
#define JSW 4
#define JSValue_PRI PRIo32
#endif
#define JS_BOOL int
enum {
JS_TAG_INT = 0,
JS_TAG_PTR = 1,
JS_TAG_SPECIAL = 3,
JS_TAG_BOOL = JS_TAG_SPECIAL | (0 << 2),
JS_TAG_NULL = JS_TAG_SPECIAL | (1 << 2),
JS_TAG_UNDEFINED = JS_TAG_SPECIAL | (2 << 2),
JS_TAG_EXCEPTION = JS_TAG_SPECIAL | (3 << 2),
JS_TAG_SHORT_FUNC = JS_TAG_SPECIAL | (4 << 2),
JS_TAG_UNINITIALIZED = JS_TAG_SPECIAL | (5 << 2),
JS_TAG_STRING_CHAR = JS_TAG_SPECIAL | (6 << 2),
JS_TAG_CATCH_OFFSET = JS_TAG_SPECIAL | (7 << 2),
#ifdef JS_USE_SHORT_FLOAT
JS_TAG_SHORT_FLOAT = 5,
#endif
};
#define JS_TAG_SPECIAL_BITS 5
#define JS_VALUE_GET_INT(v) ((int)(v) >> 1)
#define JS_VALUE_GET_SPECIAL_VALUE(v) ((int)(v) >> JS_TAG_SPECIAL_BITS)
#define JS_VALUE_GET_SPECIAL_TAG(v) ((v) & ((1 << JS_TAG_SPECIAL_BITS) - 1))
#define JS_VALUE_MAKE_SPECIAL(tag, v) ((tag) | ((v) << JS_TAG_SPECIAL_BITS))
#define JS_NULL JS_VALUE_MAKE_SPECIAL(JS_TAG_NULL, 0)
#define JS_UNDEFINED JS_VALUE_MAKE_SPECIAL(JS_TAG_UNDEFINED, 0)
#define JS_UNINITIALIZED JS_VALUE_MAKE_SPECIAL(JS_TAG_UNINITIALIZED, 0)
#define JS_FALSE JS_VALUE_MAKE_SPECIAL(JS_TAG_BOOL, 0)
#define JS_TRUE JS_VALUE_MAKE_SPECIAL(JS_TAG_BOOL, 1)
#define JS_EX_NORMAL 0
#define JS_EX_CALL 1
#define JS_EXCEPTION JS_VALUE_MAKE_SPECIAL(JS_TAG_EXCEPTION, JS_EX_NORMAL)
typedef enum {
JS_CLASS_OBJECT,
JS_CLASS_ARRAY,
JS_CLASS_C_FUNCTION,
JS_CLASS_CLOSURE,
JS_CLASS_NUMBER,
JS_CLASS_BOOLEAN,
JS_CLASS_STRING,
JS_CLASS_DATE,
JS_CLASS_REGEXP,
JS_CLASS_ERROR,
JS_CLASS_EVAL_ERROR,
JS_CLASS_RANGE_ERROR,
JS_CLASS_REFERENCE_ERROR,
JS_CLASS_SYNTAX_ERROR,
JS_CLASS_TYPE_ERROR,
JS_CLASS_URI_ERROR,
JS_CLASS_INTERNAL_ERROR,
JS_CLASS_ARRAY_BUFFER,
JS_CLASS_TYPED_ARRAY,
JS_CLASS_UINT8C_ARRAY,
JS_CLASS_INT8_ARRAY,
JS_CLASS_UINT8_ARRAY,
JS_CLASS_INT16_ARRAY,
JS_CLASS_UINT16_ARRAY,
JS_CLASS_INT32_ARRAY,
JS_CLASS_UINT32_ARRAY,
JS_CLASS_FLOAT32_ARRAY,
JS_CLASS_FLOAT64_ARRAY,
JS_CLASS_USER,
} JSObjectClassEnum;
typedef enum {
JS_CFUNCTION_bound,
JS_CFUNCTION_USER,
} JSCFunctionEnum;
typedef struct {
uint8_t buf[5];
} JSCStringBuf;
typedef struct JSGCRef {
JSValue val;
struct JSGCRef *prev;
} JSGCRef;
JSValue *JS_PushGCRef(JSContext *ctx, JSGCRef *ref);
JSValue JS_PopGCRef(JSContext *ctx, JSGCRef *ref);
#define JS_PUSH_VALUE(ctx, v) do { JS_PushGCRef(ctx, &v ## _ref); v ## _ref.val = v; } while (0)
#define JS_POP_VALUE(ctx, v) v = JS_PopGCRef(ctx, &v ## _ref)
JSValue *JS_AddGCRef(JSContext *ctx, JSGCRef *ref);
void JS_DeleteGCRef(JSContext *ctx, JSGCRef *ref);
JSValue JS_NewFloat64(JSContext *ctx, double d);
JSValue JS_NewInt32(JSContext *ctx, int32_t val);
JSValue JS_NewUint32(JSContext *ctx, uint32_t val);
JSValue JS_NewInt64(JSContext *ctx, int64_t val);
static inline JS_BOOL JS_IsInt(JSValue v)
{
return (v & 1) == JS_TAG_INT;
}
static inline JS_BOOL JS_IsPtr(JSValue v)
{
return (v & (JSW - 1)) == JS_TAG_PTR;
}
#ifdef JS_USE_SHORT_FLOAT
static inline JS_BOOL JS_IsShortFloat(JSValue v)
{
return (v & (JSW - 1)) == JS_TAG_SHORT_FLOAT;
}
#endif
static inline JS_BOOL JS_IsBool(JSValue v)
{
return JS_VALUE_GET_SPECIAL_TAG(v) == JS_TAG_BOOL;
}
static inline JS_BOOL JS_IsNull(JSValue v)
{
return v == JS_NULL;
}
static inline JS_BOOL JS_IsUndefined(JSValue v)
{
return v == JS_UNDEFINED;
}
static inline JS_BOOL JS_IsUninitialized(JSValue v)
{
return v == JS_UNINITIALIZED;
}
static inline JS_BOOL JS_IsException(JSValue v)
{
return v == JS_EXCEPTION;
}
static inline JSValue JS_NewBool(int val)
{
return JS_VALUE_MAKE_SPECIAL(JS_TAG_BOOL, (val != 0));
}
JS_BOOL JS_IsNumber(JSContext *ctx, JSValue val);
JS_BOOL JS_IsString(JSContext *ctx, JSValue val);
JS_BOOL JS_IsError(JSContext *ctx, JSValue val);
JS_BOOL JS_IsFunction(JSContext *ctx, JSValue val);
int JS_GetClassID(JSContext *ctx, JSValue val);
void JS_SetOpaque(JSContext *ctx, JSValue val, void *opaque);
void *JS_GetOpaque(JSContext *ctx, JSValue val);
typedef JSValue JSCFunction(JSContext *ctx, JSValue *this_val, int argc, JSValue *argv);
typedef void (*JSCFinalizer)(JSContext *ctx, void *opaque);
typedef enum JSCFunctionDefEnum {
JS_CFUNC_generic,
JS_CFUNC_generic_magic,
JS_CFUNC_constructor,
JS_CFUNC_constructor_magic,
JS_CFUNC_generic_params,
JS_CFUNC_f_f,
} JSCFunctionDefEnum;
typedef union JSCFunctionType {
JSCFunction *generic;
JSValue (*generic_magic)(JSContext *ctx, JSValue *this_val, int argc, JSValue *argv, int magic);
JSCFunction *constructor;
JSValue (*constructor_magic)(JSContext *ctx, JSValue *this_val, int argc, JSValue *argv, int magic);
JSValue (*generic_params)(JSContext *ctx, JSValue *this_val, int argc, JSValue *argv, JSValue params);
double (*f_f)(double f);
} JSCFunctionType;
typedef struct JSCFunctionDef {
JSCFunctionType func;
JSValue name;
uint8_t def_type;
uint8_t arg_count;
int16_t magic;
} JSCFunctionDef;
typedef struct {
const JSWord *stdlib_table;
const JSCFunctionDef *c_function_table;
const JSCFinalizer *c_finalizer_table;
uint32_t stdlib_table_len;
uint32_t stdlib_table_align;
uint32_t sorted_atoms_offset;
uint32_t global_object_offset;
uint32_t class_count;
} JSSTDLibraryDef;
typedef void JSWriteFunc(void *opaque, const void *buf, size_t buf_len);
typedef int JSInterruptHandler(JSContext *ctx, void *opaque);
JSContext *JS_NewContext(void *mem_start, size_t mem_size, const JSSTDLibraryDef *stdlib_def);
JSContext *JS_NewContext2(void *mem_start, size_t mem_size, const JSSTDLibraryDef *stdlib_def, JS_BOOL prepare_compilation);
void JS_FreeContext(JSContext *ctx);
void JS_SetContextOpaque(JSContext *ctx, void *opaque);
void JS_SetInterruptHandler(JSContext *ctx, JSInterruptHandler *interrupt_handler);
void JS_SetRandomSeed(JSContext *ctx, uint64_t seed);
JSValue JS_GetGlobalObject(JSContext *ctx);
JSValue JS_Throw(JSContext *ctx, JSValue obj);
JSValue __js_printf_like(3, 4) JS_ThrowError(JSContext *ctx, JSObjectClassEnum error_num,
const char *fmt, ...);
#define JS_ThrowTypeError(ctx, fmt, ...) JS_ThrowError(ctx, JS_CLASS_TYPE_ERROR, fmt, ##__VA_ARGS__)
#define JS_ThrowReferenceError(ctx, fmt, ...) JS_ThrowError(ctx, JS_CLASS_REFERENCE_ERROR, fmt, ##__VA_ARGS__)
#define JS_ThrowInternalError(ctx, fmt, ...) JS_ThrowError(ctx, JS_CLASS_INTERNAL_ERROR, fmt, ##__VA_ARGS__)
#define JS_ThrowRangeError(ctx, fmt, ...) JS_ThrowError(ctx, JS_CLASS_RANGE_ERROR, fmt, ##__VA_ARGS__)
#define JS_ThrowSyntaxError(ctx, fmt, ...) JS_ThrowError(ctx, JS_CLASS_SYNTAX_ERROR, fmt, ##__VA_ARGS__)
JSValue JS_ThrowOutOfMemory(JSContext *ctx);
JSValue JS_GetPropertyStr(JSContext *ctx, JSValue this_obj, const char *str);
JSValue JS_GetPropertyUint32(JSContext *ctx, JSValue obj, uint32_t idx);
JSValue JS_SetPropertyStr(JSContext *ctx, JSValue this_obj,
const char *str, JSValue val);
JSValue JS_SetPropertyUint32(JSContext *ctx, JSValue this_obj,
uint32_t idx, JSValue val);
JSValue JS_NewObjectClassUser(JSContext *ctx, int class_id);
JSValue JS_NewObject(JSContext *ctx);
JSValue JS_NewArray(JSContext *ctx, int initial_len);
JSValue JS_NewCFunctionParams(JSContext *ctx, int func_idx, JSValue params);
#define JS_EVAL_RETVAL (1 << 0)
#define JS_EVAL_REPL (1 << 1)
#define JS_EVAL_STRIP_COL (1 << 2)
#define JS_EVAL_JSON (1 << 3)
#define JS_EVAL_REGEXP (1 << 4)
#define JS_EVAL_REGEXP_FLAGS_SHIFT 8
JSValue JS_Parse(JSContext *ctx, const char *input, size_t input_len,
const char *filename, int eval_flags);
JSValue JS_Run(JSContext *ctx, JSValue val);
JSValue JS_Eval(JSContext *ctx, const char *input, size_t input_len,
const char *filename, int eval_flags);
void JS_GC(JSContext *ctx);
JSValue JS_NewStringLen(JSContext *ctx, const char *buf, size_t buf_len);
JSValue JS_NewString(JSContext *ctx, const char *buf);
const char *JS_ToCStringLen(JSContext *ctx, size_t *plen, JSValue val, JSCStringBuf *buf);
const char *JS_ToCString(JSContext *ctx, JSValue val, JSCStringBuf *buf);
JSValue JS_ToString(JSContext *ctx, JSValue val);
int JS_ToInt32(JSContext *ctx, int *pres, JSValue val);
int JS_ToUint32(JSContext *ctx, uint32_t *pres, JSValue val);
int JS_ToInt32Sat(JSContext *ctx, int *pres, JSValue val);
int JS_ToNumber(JSContext *ctx, double *pres, JSValue val);
JSValue JS_GetException(JSContext *ctx);
int JS_StackCheck(JSContext *ctx, uint32_t len);
void JS_PushArg(JSContext *ctx, JSValue val);
#define FRAME_CF_CTOR (1 << 16)
JSValue JS_Call(JSContext *ctx, int call_flags);
#define JS_BYTECODE_MAGIC 0xacfb
typedef struct {
uint16_t magic;
uint16_t version;
uintptr_t base_addr;
JSValue unique_strings;
JSValue main_func;
} JSBytecodeHeader;
void JS_PrepareBytecode(JSContext *ctx,
JSBytecodeHeader *hdr,
const uint8_t **pdata_buf, uint32_t *pdata_len,
JSValue eval_code);
int JS_RelocateBytecode2(JSContext *ctx, JSBytecodeHeader *hdr,
uint8_t *buf, uint32_t buf_len,
uintptr_t new_base_addr, JS_BOOL update_atoms);
#if JSW == 8
typedef struct {
uint16_t magic;
uint16_t version;
uint32_t base_addr;
uint32_t unique_strings;
uint32_t main_func;
} JSBytecodeHeader32;
int JS_PrepareBytecode64to32(JSContext *ctx,
JSBytecodeHeader32 *hdr,
const uint8_t **pdata_buf, uint32_t *pdata_len,
JSValue eval_code);
#endif
JS_BOOL JS_IsBytecode(const uint8_t *buf, size_t buf_len);
int JS_RelocateBytecode(JSContext *ctx,
uint8_t *buf, uint32_t buf_len);
JSValue JS_LoadBytecode(JSContext *ctx, const uint8_t *buf);
void JS_SetLogFunc(JSContext *ctx, JSWriteFunc *write_func);
void JS_PrintValue(JSContext *ctx, JSValue val);
#define JS_DUMP_LONG (1 << 0)
#define JS_DUMP_NOQUOTE (1 << 1)
#define JS_DUMP_RAW (1 << 2)
void JS_PrintValueF(JSContext *ctx, JSValue val, int flags);
void JS_DumpValueF(JSContext *ctx, const char *str,
JSValue val, int flags);
void JS_DumpValue(JSContext *ctx, const char *str,
JSValue val);
void JS_DumpMemory(JSContext *ctx, JS_BOOL is_long);
#endif