From beac9608ead3504d7a1a2b70eba4fa8ded7edb97 Mon Sep 17 00:00:00 2001 From: John Alanbrook Date: Mon, 2 Feb 2026 18:54:15 -0600 Subject: [PATCH] chase --- source/qjs_wota.c | 9 +++--- source/quickjs.c | 78 +++++++++++++++++++++++++++++++++++++++++------ source/quickjs.h | 56 ++++++++-------------------------- 3 files changed, 86 insertions(+), 57 deletions(-) diff --git a/source/qjs_wota.c b/source/qjs_wota.c index b6236168..4ef576ae 100644 --- a/source/qjs_wota.c +++ b/source/qjs_wota.c @@ -19,14 +19,14 @@ typedef struct WotaEncodeContext { static void wota_stack_push(WotaEncodeContext *enc, JSValueConst val) { - if (!JS_IsObject(val)) return; +/* if (!JS_IsObject(val)) return; ObjectRef *ref = malloc(sizeof(ObjectRef)); if (!ref) return; ref->ptr = JS_VALUE_GET_PTR(val); ref->next = enc->visited_stack; - enc->visited_stack = ref; + enc->visited_stack = ref;*/ } static void wota_stack_pop(WotaEncodeContext *enc) @@ -40,7 +40,7 @@ static void wota_stack_pop(WotaEncodeContext *enc) static int wota_stack_has(WotaEncodeContext *enc, JSValueConst val) { - if (!JS_IsObject(val)) return 0; +/* if (!JS_IsObject(val)) return 0; void *ptr = JS_VALUE_GET_PTR(val); ObjectRef *current = enc->visited_stack; @@ -49,9 +49,10 @@ static int wota_stack_has(WotaEncodeContext *enc, JSValueConst val) if (current->ptr == ptr) return 1; current = current->next; } - return 0; + return 0;*/ } + static void wota_stack_free(WotaEncodeContext *enc) { while (enc->visited_stack) { diff --git a/source/quickjs.c b/source/quickjs.c index e05136a4..b16dc12a 100644 --- a/source/quickjs.c +++ b/source/quickjs.c @@ -58,12 +58,6 @@ #define DIRECT_DISPATCH 1 #endif -#if defined(__APPLE__) -#define MALLOC_OVERHEAD 0 -#else -#define MALLOC_OVERHEAD 8 -#endif - #if !defined(_WIN32) /* define it if printf uses the RNDN rounding mode instead of RNDNA */ #define CONFIG_PRINTF_RNDN @@ -112,6 +106,23 @@ typedef struct JSFrame JSFrame; typedef struct JSCode JSCode; typedef struct JSVarRef JSVarRef; +#define OBJHDR_CAP_SHIFT 8u +#define OBJHDR_CAP_MASK (((objhdr_t)1ull << 56) - 1ull) + +#define JS_MKPTR(ptr) (((JSValue)(uintptr_t)(ptr)) | JS_TAG_PTR) +#define JS_MKFWD(ptr) ((JSValue)JS_TAG_FORWARD | ((JSValue)((uintptr_t)(ptr) >> 3) << 5)) +#define JS_VALUE_GET_FWD_PTR(v) ((void*)(uintptr_t)(((uintptr_t)(v) >> 5) << 3)) + +/* For OBJ_FORWARD type: bits 3-63 contain a 61-bit pointer */ +#define OBJHDR_FWD_PTR_SHIFT 3u +#define OBJHDR_FWD_PTR_MASK (((objhdr_t)1ull << 61) - 1ull) +#define objhdr_fwd_ptr(h) ((void*)(uintptr_t)(((h) >> OBJHDR_FWD_PTR_SHIFT) & OBJHDR_FWD_PTR_MASK)) +#define objhdr_make_fwd(ptr) (((objhdr_t)(uintptr_t)(ptr) << OBJHDR_FWD_PTR_SHIFT) | OBJ_FORWARD) + + +/* Extract pointer (clear low bits) */ +#define JS_VALUE_GET_PTR(v) ((void *)((v) & ~((JSValue)(JSW - 1)))) + /* JSVarRef - variable reference for closures */ struct JSVarRef { uint8_t is_detached; /* TRUE if pvalue points to value field */ @@ -435,6 +446,7 @@ typedef struct { int is_tail_call; } VMCallInfo; + static inline objhdr_t objhdr_set_s (objhdr_t h, bool s) { return s ? (h | OBJHDR_S_MASK) : (h & ~OBJHDR_S_MASK); } @@ -453,6 +465,51 @@ static inline objhdr_t objhdr_make (uint64_t cap56, uint8_t type, bool r, bool a return h; } +static inline objhdr_t *chase(JSValue v) { + objhdr_t *oh = JS_VALUE_GET_PTR(v); + if (objhdr_type(*oh) != OBJ_FORWARD) return oh; + do { + oh = (objhdr_t*)objhdr_fwd_ptr(*oh); + } while (objhdr_type(*oh) == OBJ_FORWARD); + return oh; +} + +JS_BOOL JS_IsStone(JSValue v) { + return !JS_IsObject(v) || objhdr_s(*chase(v)); +} + +JS_BOOL JS_IsArray(JSValue v) { + return JS_IsObject(v) && objhdr_type(*chase(v)) == OBJ_ARRAY; +} + +JS_BOOL JS_IsRecord (JSValue v) { + return JS_IsObject(v) && objhdr_type(*chase(v)) == OBJ_RECORD; +} + +JS_BOOL JS_IsFunction (JSValue v) { + return JS_IsObject(v) && objhdr_type(*chase(v)) == OBJ_FUNCTION; +} + +JS_BOOL JS_IsCode (JSValue v) { + return JS_IsObject(v) && objhdr_type(*chase(v)) == OBJ_CODE; +} + +JS_BOOL JS_IsForwarded (JSValue v) { + return JS_IsObject(v) && objhdr_type(*chase(v)) == OBJ_FORWARD; +} + +JS_BOOL JS_IsFrame (JSValue v) { + return JS_IsObject(v) && objhdr_type(*chase(v)) == OBJ_FRAME; +} + +JS_BOOL JS_IsBlob (JSValue v) { + return JS_IsObject(v) && objhdr_type(*chase(v)) == OBJ_BLOB; +} + +JS_BOOL JS_IsText(JSValue v) { + return MIST_IsImmediateASCII(v) || (JS_IsObject(v) && objhdr_type(*chase(v)) == OBJ_TEXT); +} + /* Intrinsic array type - tagged as JS_TAG_PTR with mist_hdr type OBJ_ARRAY */ typedef struct JSArray { objhdr_t mist_hdr; /* mist header at offset 8 */ @@ -611,10 +668,11 @@ static inline uint64_t fash64_hash_words (const uint64_t *words, } static inline uint64_t fash64_hash_one (uint64_t word) { - fash64_state s; - fash64_begin (&s); - fash64_word (&s, word); - return fash64_end (&s); + uint64_t high, low; + uint64_t mixed = (uint64_t)FASH64_PRIME_8 ^ word; + fash64_mul_hi_lo (mixed, (uint64_t)FASH64_PRIME_11, &high, &low); + uint64_t sum = (uint64_t)FASH64_PRIME_3 + high; + return low ^ sum; } static inline word_t JSText_len (const JSText *text) { diff --git a/source/quickjs.h b/source/quickjs.h index 5afae884..fb095f9e 100644 --- a/source/quickjs.h +++ b/source/quickjs.h @@ -55,14 +55,13 @@ enum mist_obj_type { OBJ_FORWARD = 7 }; -#define OBJHDR_CAP_SHIFT 8u -#define OBJHDR_CAP_MASK (((objhdr_t)1ull << 56) - 1ull) #define OBJHDR_S_BIT 3u #define OBJHDR_P_BIT 4u #define OBJHDR_A_BIT 5u #define OBJHDR_R_BIT 7u + #define OBJHDR_FLAG(bit) ((objhdr_t)1ull << (bit)) #define OBJHDR_S_MASK OBJHDR_FLAG (OBJHDR_S_BIT) #define OBJHDR_P_MASK OBJHDR_FLAG (OBJHDR_P_BIT) @@ -178,6 +177,8 @@ void JS_DeleteGCRef(JSContext *ctx, JSGCRef *ref); Value Extraction ============================================================ */ +#define JS_VALUE_GET_INT(v) ((int)(v) >> 1) + /* Get primary tag (low 2-3 bits) */ static inline int JS_VALUE_GET_TAG (JSValue v) { @@ -201,9 +202,6 @@ JS_VALUE_GET_TAG (JSValue v) { /* Extract bool value from special tag */ #define JS_VALUE_GET_BOOL(v) ((int)((v) >> 5) & 1) -/* Extract pointer (clear low bits) */ -#define JS_VALUE_GET_PTR(v) ((void *)((v) & ~((JSValue)(JSW - 1)))) - /* Extract special tag payload (bits 5+) */ #define JS_VALUE_GET_SPECIAL_PAYLOAD(v) ((int32_t)((v) >> 5)) @@ -212,9 +210,6 @@ JS_VALUE_GET_TAG (JSValue v) { ============================================================ */ #define JS_MKVAL(tag, val) _JS_MkVal (tag, val) -#define JS_MKPTR(ptr) (((JSValue)(uintptr_t)(ptr)) | JS_TAG_PTR) -#define JS_MKFWD(ptr) (((JSValue)(uintptr_t)(ptr)) | JS_TAG_FORWARD) - static inline JSValue _JS_MkVal (int tag, int32_t val) { if (tag == JS_TAG_INT) { return ((JSValue)(uint32_t)val << 1); } /* Special tags encode payload in upper bits */ @@ -306,10 +301,7 @@ static inline JS_BOOL JS_IsInt (JSValue v) { return (v & 1) == 0; } static inline JS_BOOL JS_IsPtr (JSValue v) { return (v & 3) == JS_TAG_PTR; } static inline JS_BOOL JS_IsSpecial (JSValue v) { return (v & 3) == JS_TAG_SPECIAL; } -static inline JS_BOOL JS_IsStone(JSValue v) { - if (!JS_IsPtr(v)) return 1; - return objhdr_s(*(objhdr_t *)JS_VALUE_GET_PTR(v)); -} + #ifdef JS_PTR64 static inline JS_BOOL @@ -586,37 +578,15 @@ static inline JS_BOOL JS_IsObject (JSValue v) { return JS_IsPtr (v); } -static inline JS_BOOL JS_IsArray(JSValue v) { - return JS_IsObject(v) && objhdr_type(*(objhdr_t *)JS_VALUE_GET_PTR(v)) == OBJ_ARRAY; -} - -static inline JS_BOOL JS_IsRecord (JSValue v) { - return JS_IsObject(v) && objhdr_type(*(objhdr_t *)JS_VALUE_GET_PTR(v)) == OBJ_RECORD; -} - -static inline JS_BOOL JS_IsFunction (JSValue v) { - return JS_IsObject(v) && objhdr_type(*(objhdr_t *)JS_VALUE_GET_PTR(v)) == OBJ_FUNCTION; -} - -static inline JS_BOOL JS_IsCode (JSValue v) { - return JS_IsObject(v) && objhdr_type(*(objhdr_t *)JS_VALUE_GET_PTR(v)) == OBJ_CODE; -} - -static inline JS_BOOL JS_IsForwarded (JSValue v) { - return JS_IsObject(v) && objhdr_type(*(objhdr_t *)JS_VALUE_GET_PTR(v)) == OBJ_FORWARD; -} - -static inline JS_BOOL JS_IsFrame (JSValue v) { - return JS_IsObject(v) && objhdr_type(*(objhdr_t *)JS_VALUE_GET_PTR(v)) == OBJ_FRAME; -} - -static inline JS_BOOL JS_IsBlob (JSValue v) { - return JS_IsObject(v) && objhdr_type(*(objhdr_t *)JS_VALUE_GET_PTR(v)) == OBJ_BLOB; -} - -static inline JS_BOOL JS_IsText(JSValue v) { - return MIST_IsImmediateASCII(v) || (JS_IsObject(v) && objhdr_type(*(objhdr_t *)JS_VALUE_GET_PTR(v)) == OBJ_TEXT); -} +JS_BOOL JS_IsArray(JSValue v); +JS_BOOL JS_IsRecord(JSValue v); +JS_BOOL JS_IsFunction(JSValue v); +JS_BOOL JS_IsCode(JSValue v); +JS_BOOL JS_IsForwarded(JSValue v); +JS_BOOL JS_IsFrame(JSValue v); +JS_BOOL JS_IsBlob(JSValue v); +JS_BOOL JS_IsText(JSValue v); +static JS_BOOL JS_IsStone(JSValue v); // Fundamental int JS_GetLength (JSContext *ctx, JSValue obj, int64_t *pres);