rm jsstring and string_buffer

This commit is contained in:
2026-02-01 11:35:40 -06:00
parent bb83327a52
commit 6c3c492446
3 changed files with 404 additions and 1080 deletions

View File

@@ -55,12 +55,21 @@ Objects are heap allocated, referenced by a pointer value. They are all preceded
### 64 bit build
56 bits capacity
1 bit memory reclamation flag: note that this obj has already been moved
3 bit reserved (per object)
2 bit reserved (per object)
1 bit stone: note that this obj is immutable
3 bit type: note the type of the object
1 bit: fwd: note that this obj is a forward linkage
Type 7: Forward
The forward type indicates that the object (an array, blob, pretext, or record) has grown beyond its capacity and is now residing at a new address. The remaining 61 bits contain the address of the enlarged object. Forward linkages are cleaned up by the memory reclaimer.
Last bit ..1:
The forward type indicates that the object (an array, blob, pretext, or record) has grown beyond its capacity and is now residing at a new address. The remaining 63 bits contain the address of the enlarged object. Forward linkages are cleaned up by the memory reclaimer.
Type 7: C light C object
Header
Pointer
Capacity is an ID of a registered C type.
Pointer is a pointer to the opaque C object.
Type 0: Array
Header

File diff suppressed because it is too large Load Diff

View File

@@ -44,8 +44,39 @@ extern "C" {
// #define BINARY64 // 64 bit word type (double)
// #define DEC64 // 64 bit word type (dec)
enum mist_obj_type {
OBJ_ARRAY = 0,
OBJ_BLOB = 1,
OBJ_TEXT = 2,
OBJ_RECORD = 3, // js style objects
OBJ_FUNCTION = 4,
OBJ_CODE = 5,
OBJ_FRAME = 6,
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)
#define OBJHDR_A_MASK OBJHDR_FLAG (OBJHDR_A_BIT)
#define OBJHDR_R_MASK OBJHDR_FLAG (OBJHDR_R_BIT)
typedef uint64_t word_t; // one actor-memory word
typedef uint64_t objhdr_t; // header word
typedef uint64_t objref_t; // 56-bit word address (0 = null)
static inline uint8_t objhdr_type (objhdr_t h) { return (uint8_t)(h & 7u); }
static inline int objhdr_s (objhdr_t h) { return (h & OBJHDR_S_MASK) != 0; }
/*
NaN boxing is used, always. A value is the length of the word.
Half: 10 bits
Float: 23 bits
Double: 52 bits
@@ -64,21 +95,8 @@ typedef struct JSContext JSContext; // Each actor - has its own GC
typedef struct JSClass JSClass;
typedef uint32_t JSClassID;
typedef struct JSGCRef {
JSValue val;
struct JSGCRef *prev;
} JSGCRef;
/* stack of 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)
/* list of JSGCRef (they can be removed in any order, slower) */
JSValue *JS_AddGCRef(JSContext *ctx, JSGCRef *ref);
void JS_DeleteGCRef(JSContext *ctx, JSGCRef *ref);
/* Forward declaration - JSGCRef moved after JSValue definition */
struct JSGCRef;
/* ============================================================
Mist Value Encoding (LSB-based type discrimination)
@@ -130,23 +148,29 @@ enum {
JS_TAG_UNINITIALIZED = 0x17, /* 10111 */
JS_TAG_STRING_IMM = 0x1B, /* 11011 - immediate ASCII (up to 7 chars) */
JS_TAG_CATCH_OFFSET = 0x1F, /* 11111 */
/* Object subtypes (stored in object header, not value) */
JS_TAG_STRING = -8, /* mist_text pointer */
JS_TAG_ARRAY = -6, /* JSArray pointer */
JS_TAG_FUNCTION = -5, /* JSFunction pointer */
JS_TAG_FUNCTION_BYTECODE = -2,
JS_TAG_OBJECT = -1, /* JSRecord/JSObject pointer */
/* Legacy - for gradual migration (to be removed) */
JS_TAG_FIRST = -10,
JS_TAG_FLOAT64 = 8, /* unused in new encoding */
};
typedef struct JSRefCountHeader {
int ref_count;
} JSRefCountHeader;
/* JSGCRef - for rooting values during GC */
typedef struct JSGCRef {
JSValue val;
struct JSGCRef *prev;
} JSGCRef;
/* stack of 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)
/* list of JSGCRef (they can be removed in any order, slower) */
JSValue *JS_AddGCRef(JSContext *ctx, JSGCRef *ref);
void JS_DeleteGCRef(JSContext *ctx, JSGCRef *ref);
/* ============================================================
Value Extraction
============================================================ */
@@ -185,10 +209,10 @@ JS_VALUE_GET_TAG (JSValue v) {
============================================================ */
#define JS_MKVAL(tag, val) _JS_MkVal (tag, val)
#define JS_MKPTR(tag, ptr) (((JSValue)(uintptr_t)(ptr)) | JS_TAG_PTR)
#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) {
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 */
return ((JSValue)tag) | ((JSValue)(uint32_t)val << 5);
@@ -239,8 +263,7 @@ __JS_NewFloat64 (JSContext *ctx, double d) {
| JS_TAG_SHORT_FLOAT;
}
static inline double
JS_VALUE_GET_FLOAT64 (JSValue v) {
static inline double JS_VALUE_GET_FLOAT64 (JSValue v) {
if ((v & 7) != JS_TAG_SHORT_FLOAT) return 0.0;
uint64_t sign = v >> 63;
@@ -258,11 +281,6 @@ JS_VALUE_GET_FLOAT64 (JSValue v) {
return u.d;
}
static inline JS_BOOL
JS_VALUE_IS_NAN (JSValue v) {
return 0; /* NaN becomes NULL in Mist encoding */
}
#define JS_TAG_IS_FLOAT64(tag) ((tag) == JS_TAG_SHORT_FLOAT)
#define JS_NAN JS_MKVAL (JS_TAG_NULL, 0)
@@ -272,11 +290,6 @@ static inline JSValue __JS_NewFloat64 (JSContext *ctx,
double d); /* forward decl */
static inline double JS_VALUE_GET_FLOAT64 (JSValue v);
static inline JS_BOOL
JS_VALUE_IS_NAN (JSValue v) {
return 0;
}
#define JS_TAG_IS_FLOAT64(tag) (0)
#define JS_NAN JS_MKVAL (JS_TAG_NULL, 0)
@@ -286,18 +299,15 @@ JS_VALUE_IS_NAN (JSValue v) {
Type Checks
============================================================ */
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_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
JS_IsShortFloat (JSValue v) {
@@ -309,9 +319,6 @@ JS_IsShortFloat (JSValue v) {
#define JS_VALUE_IS_BOTH_FLOAT(v1, v2) \
(JS_IsShortFloat (v1) && JS_IsShortFloat (v2))
/* Pointer values have ref counts */
#define JS_VALUE_HAS_REF_COUNT(v) JS_IsPtr (v)
/* ============================================================
Special Constants
============================================================ */
@@ -371,7 +378,6 @@ typedef struct JSMallocFunctions {
typedef struct JSGCObjectHeader JSGCObjectHeader;
JSValue JS_Stone (JSContext *ctx, JSValue this_val);
int JS_IsStone (JSContext *ctx, JSValue val);
JSRuntime *JS_NewRuntime (void);
/* info lifetime must exceed that of rt */
@@ -405,29 +411,6 @@ 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_AddIntrinsicEval (JSContext *ctx);
void JS_AddIntrinsicRegExpCompiler (JSContext *ctx);
void JS_AddIntrinsicRegExp (JSContext *ctx);
void JS_AddIntrinsicJSON (JSContext *ctx);
JSValue js_string_codePointRange (JSContext *ctx, JSValue this_val,
int argc, JSValue *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;
@@ -530,29 +513,24 @@ JS_NewFloat64 (JSContext *ctx, double d) {
return __JS_NewFloat64 (ctx, d);
}
static inline JS_BOOL
JS_IsNumber (JSValue v) {
static inline JS_BOOL JS_IsNumber (JSValue v) {
int tag = JS_VALUE_GET_TAG (v);
return tag == JS_TAG_INT || JS_TAG_IS_FLOAT64 (tag);
}
static inline JS_BOOL
JS_IsBool (JSValue v) {
static inline JS_BOOL JS_IsBool (JSValue v) {
return JS_VALUE_GET_TAG (v) == JS_TAG_BOOL;
}
static inline JS_BOOL
JS_IsNull (JSValue v) {
static inline JS_BOOL JS_IsNull (JSValue v) {
return JS_VALUE_GET_TAG (v) == JS_TAG_NULL;
}
static inline JS_BOOL
JS_IsException (JSValue v) {
static inline JS_BOOL JS_IsException (JSValue v) {
return (JS_VALUE_GET_TAG (v) == JS_TAG_EXCEPTION);
}
static inline JS_BOOL
JS_IsUninitialized (JSValue v) {
static inline JS_BOOL JS_IsUninitialized (JSValue v) {
return (JS_VALUE_GET_TAG (v) == JS_TAG_UNINITIALIZED);
}
@@ -586,24 +564,45 @@ MIST_TryNewImmediateASCII (const char *str, size_t len) {
return v;
}
JS_BOOL JS_IsString (JSValue v);
JS_BOOL JS_IsText (JSValue v);
/* Symbols removed in Mist encoding */
/* JS_IsFunction - check if value is a callable function.
With new tagging, must check gc_obj_type in JSGCObjectHeader. */
JS_BOOL JS_IsFunction (JSValue v);
static inline JS_BOOL
JS_IsInteger (JSValue v) {
static inline JS_BOOL JS_IsInteger (JSValue v) {
return JS_VALUE_GET_TAG (v) == JS_TAG_INT;
}
/* JS_IsObject - check if value is a settable object (record or array).
With new tagging, must check gc_obj_type in JSGCObjectHeader. */
JS_BOOL JS_IsObject (JSValue v);
int JS_IsArray (JSContext *ctx, JSValue val);
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 JS_IsObject(v) && objhdr_type(*(objhdr_t *)JS_VALUE_GET_PTR(v)) == OBJ_TEXT;
}
// Fundamental
int JS_GetLength (JSContext *ctx, JSValue obj, int64_t *pres);
@@ -626,49 +625,12 @@ JSValue __js_printf_like (2, 3)
JS_ThrowInternalError (JSContext *ctx, const char *fmt, ...);
JSValue JS_ThrowOutOfMemory (JSContext *ctx);
void __JS_FreeValue (JSContext *ctx, JSValue v);
static inline void
JS_FreeValue (JSContext *ctx, JSValue v) {
if (JS_VALUE_HAS_REF_COUNT (v)) {
JSRefCountHeader *p = (JSRefCountHeader *)JS_VALUE_GET_PTR (v);
if (--p->ref_count <= 0) { __JS_FreeValue (ctx, v); }
}
}
void __JS_FreeValueRT (JSRuntime *rt, JSValue v);
static inline void
JS_FreeValueRT (JSRuntime *rt, JSValue v) {
if (JS_VALUE_HAS_REF_COUNT (v)) {
JSRefCountHeader *p = (JSRefCountHeader *)JS_VALUE_GET_PTR (v);
if (--p->ref_count <= 0) { __JS_FreeValueRT (rt, v); }
}
}
static inline JSValue
JS_DupValue (JSContext *ctx, JSValue v) {
if (JS_VALUE_HAS_REF_COUNT (v)) {
JSRefCountHeader *p = (JSRefCountHeader *)JS_VALUE_GET_PTR (v);
p->ref_count++;
}
return (JSValue)v;
}
static inline JSValue
JS_DupValueRT (JSRuntime *rt, JSValue v) {
if (JS_VALUE_HAS_REF_COUNT (v)) {
JSRefCountHeader *p = (JSRefCountHeader *)JS_VALUE_GET_PTR (v);
p->ref_count++;
}
return (JSValue)v;
}
JS_BOOL JS_StrictEq (JSContext *ctx, JSValue op1, JSValue op2);
JS_BOOL JS_SameValue (JSContext *ctx, JSValue op1, JSValue op2);
int JS_ToBool (JSContext *ctx,
JSValue val); /* return -1 for JS_EXCEPTION */
int JS_ToBool (JSContext *ctx, JSValue val); /* return -1 for JS_EXCEPTION */
int JS_ToInt32 (JSContext *ctx, int32_t *pres, JSValue val);
static inline int
JS_ToUint32 (JSContext *ctx, uint32_t *pres, JSValue val) {
static inline int JS_ToUint32 (JSContext *ctx, uint32_t *pres, JSValue val) {
return JS_ToInt32 (ctx, (int32_t *)pres, val);
}
int JS_ToInt64 (JSContext *ctx, int64_t *pres, JSValue val);
@@ -676,26 +638,21 @@ int JS_ToFloat64 (JSContext *ctx, double *pres, JSValue val);
/* return an exception if 'val' is a Number */
JSValue JS_NewStringLen (JSContext *ctx, const char *str1, size_t len1);
static inline JSValue
JS_NewString (JSContext *ctx, const char *str) {
static inline JSValue JS_NewString (JSContext *ctx, const char *str) {
return JS_NewStringLen (ctx, str, strlen (str));
}
JSValue JS_ToString (JSContext *ctx, JSValue val);
JSValue JS_ToPropertyKey (JSContext *ctx, JSValue val);
const char *JS_ToCStringLen2 (JSContext *ctx, size_t *plen, JSValue val1,
JS_BOOL cesu8);
static inline const char *
JS_ToCStringLen (JSContext *ctx, size_t *plen, JSValue val1) {
const char *JS_ToCStringLen2 (JSContext *ctx, size_t *plen, JSValue val1, JS_BOOL cesu8);
static inline const char * JS_ToCStringLen (JSContext *ctx, size_t *plen, JSValue val1) {
return JS_ToCStringLen2 (ctx, plen, val1, 0);
}
static inline const char *
JS_ToCString (JSContext *ctx, JSValue val1) {
static inline const char * JS_ToCString (JSContext *ctx, JSValue val1) {
return JS_ToCStringLen2 (ctx, NULL, val1, 0);
}
void JS_FreeCString (JSContext *ctx, const char *ptr);
JSValue JS_NewObjectProtoClass (JSContext *ctx, JSValue proto,
JSClassID class_id);
JSValue JS_NewObjectProtoClass (JSContext *ctx, JSValue proto, JSClassID class_id);
JSValue JS_NewObjectClass (JSContext *ctx, int class_id);
JSValue JS_NewObjectProto (JSContext *ctx, JSValue proto);
JSValue JS_NewObject (JSContext *ctx);
@@ -825,42 +782,33 @@ typedef union JSCFunctionType {
JSValue JS_NewCFunction2 (JSContext *ctx, JSCFunction *func, const char *name,
int length, JSCFunctionEnum cproto, int magic);
static inline JSValue
JS_NewCFunction (JSContext *ctx, JSCFunction *func, const char *name,
int length) {
static inline JSValue JS_NewCFunction (JSContext *ctx, JSCFunction *func, const char *name, int length) {
return JS_NewCFunction2 (ctx, func, name, length, JS_CFUNC_generic, 0);
}
static inline JSValue
JS_NewCFunctionMagic (JSContext *ctx, JSCFunctionMagic *func, const char *name,
int length, JSCFunctionEnum cproto, int magic) {
static inline JSValue JS_NewCFunctionMagic (JSContext *ctx, JSCFunctionMagic *func, const char *name, int length, JSCFunctionEnum cproto, int magic) {
return JS_NewCFunction2 (ctx, (JSCFunction *)func, name, length, cproto,
magic);
}
/* Fixed-arity fast path constructors */
static inline JSValue
JS_NewCFuncFixed0 (JSContext *ctx, JSCFunction0 *func, const char *name) {
static inline JSValue JS_NewCFuncFixed0 (JSContext *ctx, JSCFunction0 *func, const char *name) {
return JS_NewCFunction2 (ctx, (JSCFunction *)func, name, 0, JS_CFUNC_0, 0);
}
static inline JSValue
JS_NewCFuncFixed1 (JSContext *ctx, JSCFunction1 *func, const char *name) {
static inline JSValue JS_NewCFuncFixed1 (JSContext *ctx, JSCFunction1 *func, const char *name) {
return JS_NewCFunction2 (ctx, (JSCFunction *)func, name, 1, JS_CFUNC_1, 0);
}
static inline JSValue
JS_NewCFuncFixed2 (JSContext *ctx, JSCFunction2 *func, const char *name) {
static inline JSValue JS_NewCFuncFixed2 (JSContext *ctx, JSCFunction2 *func, const char *name) {
return JS_NewCFunction2 (ctx, (JSCFunction *)func, name, 2, JS_CFUNC_2, 0);
}
static inline JSValue
JS_NewCFuncFixed3 (JSContext *ctx, JSCFunction3 *func, const char *name) {
static inline JSValue JS_NewCFuncFixed3 (JSContext *ctx, JSCFunction3 *func, const char *name) {
return JS_NewCFunction2 (ctx, (JSCFunction *)func, name, 3, JS_CFUNC_3, 0);
}
static inline JSValue
JS_NewCFuncFixed4 (JSContext *ctx, JSCFunction4 *func, const char *name) {
static inline JSValue JS_NewCFuncFixed4 (JSContext *ctx, JSCFunction4 *func, const char *name) {
return JS_NewCFunction2 (ctx, (JSCFunction *)func, name, 4, JS_CFUNC_4, 0);
}