rm dependence on tostring

This commit is contained in:
2026-01-20 10:08:35 -06:00
parent 823183c510
commit 2b60e3a242
2 changed files with 31 additions and 100 deletions

View File

@@ -179,15 +179,12 @@ JS_SetClassProto(js, js_##TYPE##_id, TYPE##_proto); \
#define QJSCLASSPREP_FUNCS_CTOR(TYPE, CTOR_ARGC) \ #define QJSCLASSPREP_FUNCS_CTOR(TYPE, CTOR_ARGC) \
({ \ ({ \
QJSCLASSPREP_FUNCS(TYPE); \ QJSCLASSPREP_FUNCS(TYPE); \
JSValue TYPE##_ctor = JS_NewCFunction2(js, js_##TYPE##_constructor, #TYPE, CTOR_ARGC, JS_CFUNC_constructor, 0); \ JSValue TYPE##_ctor = JS_NewCFunction2(js, js_##TYPE##_constructor, #TYPE, CTOR_ARGC, JS_CFUNC_generic, 0); \
JS_SetConstructor(js, TYPE##_ctor, TYPE##_proto); \
TYPE##_ctor; \ TYPE##_ctor; \
}) })
#define countof(x) (sizeof(x)/sizeof((x)[0])) #define countof(x) (sizeof(x)/sizeof((x)[0]))
// Common macros for property access // Common macros for property access
#define JS_GETPROP(JS, TARGET, VALUE, PROP, TYPE) {\ #define JS_GETPROP(JS, TARGET, VALUE, PROP, TYPE) {\
JSValue __##PROP##__v = JS_GetPropertyStr(JS,VALUE,#PROP); \ JSValue __##PROP##__v = JS_GetPropertyStr(JS,VALUE,#PROP); \

View File

@@ -155,6 +155,18 @@ typedef struct JSProfileState {
#endif /* DUMP_PROFILE */ #endif /* DUMP_PROFILE */
static inline JS_BOOL JS_VALUE_IS_TEXT(JSValue v)
{
int tag = JS_VALUE_GET_TAG(v);
return tag == JS_TAG_STRING || tag == JS_TAG_STRING_ROPE;
}
static inline JS_BOOL JS_VALUE_IS_NUMBER(JSValue v)
{
int tag = JS_VALUE_GET_TAG(v);
return tag == JS_TAG_INT || tag == JS_TAG_FLOAT64;
}
enum { enum {
/* classid tag */ /* union usage | properties */ /* classid tag */ /* union usage | properties */
JS_CLASS_OBJECT = 1, /* must be first */ JS_CLASS_OBJECT = 1, /* must be first */
@@ -31272,47 +31284,6 @@ static JSValue js_cell_neg(JSContext *ctx, JSValueConst this_val,
return JS_NewFloat64(ctx, -num); return JS_NewFloat64(ctx, -num);
} }
/* normalize(text) - Unicode normalize to NFC form */
static JSValue js_cell_normalize(JSContext *ctx, JSValueConst this_val,
int argc, JSValueConst *argv)
{
if (argc < 1)
return JS_NewString(ctx, "");
JSValue str_val = JS_ToString(ctx, argv[0]);
if (JS_IsException(str_val))
return JS_EXCEPTION;
/* Get the string as UTF-32 for normalization */
uint32_t *codepoints = NULL;
size_t len;
// codepoints = JS_ToUTF32String(ctx, &len, str_val);
JS_FreeValue(ctx, str_val);
if (!codepoints)
return JS_EXCEPTION;
if (len == 0) {
js_free(ctx, codepoints);
return JS_NewString(ctx, "");
}
/* Normalize to NFC */
uint32_t *normalized = NULL;
int norm_len = unicode_normalize(&normalized, codepoints, len, UNICODE_NFC,
ctx->rt, js_realloc_rt);
js_free(ctx, codepoints);
if (norm_len < 0 || !normalized)
return JS_EXCEPTION;
/* Convert back to JSValue string */
// JSValue result = JS_NewUTF32String(ctx, normalized, norm_len);
js_free_rt(ctx->rt, normalized);
return JS_NULL;
}
/* character(value) - get character from text or codepoint */ /* character(value) - get character from text or codepoint */
static JSValue js_cell_character(JSContext *ctx, JSValueConst this_val, static JSValue js_cell_character(JSContext *ctx, JSValueConst this_val,
int argc, JSValueConst *argv) int argc, JSValueConst *argv)
@@ -31562,8 +31533,7 @@ static JSValue js_cell_text(JSContext *ctx, JSValueConst this_val,
} }
} }
/* Default: convert to string */ return js_cell_number_to_radix_string(ctx, num, 10);
return JS_ToString(ctx, arg);
} }
/* Handle array */ /* Handle array */
@@ -31654,8 +31624,7 @@ static JSValue js_cell_text(JSContext *ctx, JSValueConst this_val,
if (JS_IsNull(arg)) if (JS_IsNull(arg))
return JS_NULL; return JS_NULL;
/* Default: convert to string */ return JS_ThrowInternalError(ctx, "Could not convert to text.");
return JS_ToString(ctx, arg);
} }
/* text.lower(str) - convert to lowercase */ /* text.lower(str) - convert to lowercase */
@@ -31663,14 +31632,10 @@ static JSValue js_cell_text_lower(JSContext *ctx, JSValueConst this_val,
int argc, JSValueConst *argv) int argc, JSValueConst *argv)
{ {
if (argc < 1) return JS_NULL; if (argc < 1) return JS_NULL;
int tag = JS_VALUE_GET_TAG(argv[0]); if (!JS_VALUE_IS_TEXT(argv[0]))
if (tag != JS_TAG_STRING && tag != JS_TAG_STRING_ROPE)
return JS_NULL; return JS_NULL;
JSValue str = JS_ToString(ctx, argv[0]); JSString *p = JS_VALUE_GET_STRING(argv[0]);
if (JS_IsException(str)) return str;
JSString *p = JS_VALUE_GET_STRING(str);
StringBuffer b_s, *b = &b_s; StringBuffer b_s, *b = &b_s;
string_buffer_init(ctx, b, p->len); string_buffer_init(ctx, b, p->len);
@@ -31680,12 +31645,10 @@ static JSValue js_cell_text_lower(JSContext *ctx, JSValueConst this_val,
c = c - 'A' + 'a'; c = c - 'A' + 'a';
if (string_buffer_putc(b, c)) { if (string_buffer_putc(b, c)) {
string_buffer_free(b); string_buffer_free(b);
JS_FreeValue(ctx, str);
return JS_EXCEPTION; return JS_EXCEPTION;
} }
} }
JS_FreeValue(ctx, str);
return string_buffer_end(b); return string_buffer_end(b);
} }
@@ -31694,14 +31657,10 @@ static JSValue js_cell_text_upper(JSContext *ctx, JSValueConst this_val,
int argc, JSValueConst *argv) int argc, JSValueConst *argv)
{ {
if (argc < 1) return JS_NULL; if (argc < 1) return JS_NULL;
int tag = JS_VALUE_GET_TAG(argv[0]); if (!JS_VALUE_IS_TEXT(argv[0]))
if (tag != JS_TAG_STRING && tag != JS_TAG_STRING_ROPE)
return JS_NULL; return JS_NULL;
JSValue str = JS_ToString(ctx, argv[0]); JSString *p = JS_VALUE_GET_STRING(argv[0]);
if (JS_IsException(str)) return str;
JSString *p = JS_VALUE_GET_STRING(str);
StringBuffer b_s, *b = &b_s; StringBuffer b_s, *b = &b_s;
string_buffer_init(ctx, b, p->len); string_buffer_init(ctx, b, p->len);
@@ -31711,12 +31670,10 @@ static JSValue js_cell_text_upper(JSContext *ctx, JSValueConst this_val,
c = c - 'a' + 'A'; c = c - 'a' + 'A';
if (string_buffer_putc(b, c)) { if (string_buffer_putc(b, c)) {
string_buffer_free(b); string_buffer_free(b);
JS_FreeValue(ctx, str);
return JS_EXCEPTION; return JS_EXCEPTION;
} }
} }
JS_FreeValue(ctx, str);
return string_buffer_end(b); return string_buffer_end(b);
} }
@@ -31892,16 +31849,15 @@ static JSValue js_cell_text_replace(JSContext *ctx, JSValueConst this_val, int a
} }
} }
JSValue str = JS_ToString(ctx, argv[0]); if (!JS_VALUE_IS_TEXT(argv[0]))
if (JS_IsException(str)) return str; return JS_ThrowInternalError(ctx, "Replace must have text in arg0.");
JSString *sp = JS_VALUE_GET_STRING(str); JSString *sp = JS_VALUE_GET_STRING(argv[0]);
int len = (int)sp->len; int len = (int)sp->len;
int32_t limit = -1; int32_t limit = -1;
if (argc > 3 && !JS_IsNull(argv[3])) { if (argc > 3 && !JS_IsNull(argv[3])) {
if (JS_ToInt32(ctx, &limit, argv[3])) { if (JS_ToInt32(ctx, &limit, argv[3])) {
JS_FreeValue(ctx, str);
return JS_NULL; return JS_NULL;
} }
if (limit < 0) limit = -1; if (limit < 0) limit = -1;
@@ -31911,13 +31867,10 @@ static JSValue js_cell_text_replace(JSContext *ctx, JSValueConst this_val, int a
string_buffer_init(ctx, b, len); string_buffer_init(ctx, b, len);
if (!target_is_regex) { if (!target_is_regex) {
JSValue target = JS_ToString(ctx, argv[1]); if (!JS_VALUE_IS_TEXT(argv[1]))
if (JS_IsException(target)) { return JS_ThrowInternalError(ctx, "Second arg of replace must be pattern or text.");
JS_FreeValue(ctx, str);
return target;
}
JSString *tp = JS_VALUE_GET_STRING(target); JSString *tp = JS_VALUE_GET_STRING(argv[1]);
int t_len = (int)tp->len; int t_len = (int)tp->len;
if (t_len == 0) { if (t_len == 0) {
@@ -31947,8 +31900,6 @@ static JSValue js_cell_text_replace(JSContext *ctx, JSValueConst this_val, int a
} }
} }
JS_FreeValue(ctx, str);
JS_FreeValue(ctx, target);
return string_buffer_end(b); return string_buffer_end(b);
} }
@@ -31995,14 +31946,10 @@ static JSValue js_cell_text_replace(JSContext *ctx, JSValueConst this_val, int a
if (string_buffer_concat_value_free(b, sub)) goto fail_str_target; if (string_buffer_concat_value_free(b, sub)) goto fail_str_target;
} }
JS_FreeValue(ctx, str);
JS_FreeValue(ctx, target);
return string_buffer_end(b); return string_buffer_end(b);
fail_str_target: fail_str_target:
string_buffer_free(b); string_buffer_free(b);
JS_FreeValue(ctx, str);
JS_FreeValue(ctx, target);
return JS_EXCEPTION; return JS_EXCEPTION;
} }
@@ -32097,7 +32044,6 @@ static JSValue js_cell_text_replace(JSContext *ctx, JSValueConst this_val, int a
if (have_orig_last_index) JS_SetPropertyStr(ctx, rx, "lastIndex", orig_last_index); if (have_orig_last_index) JS_SetPropertyStr(ctx, rx, "lastIndex", orig_last_index);
JS_FreeValue(ctx, str);
return string_buffer_end(b); return string_buffer_end(b);
fail_rx: fail_rx:
@@ -32107,7 +32053,6 @@ fail_rx:
} else { } else {
JS_FreeValue(ctx, orig_last_index); JS_FreeValue(ctx, orig_last_index);
} }
JS_FreeValue(ctx, str);
return JS_EXCEPTION; return JS_EXCEPTION;
} }
@@ -32584,11 +32529,8 @@ static JSValue js_cell_array(JSContext *ctx, JSValueConst this_val,
/* array(text) - split into characters */ /* array(text) - split into characters */
/* array(text, separator) - split by separator */ /* array(text, separator) - split by separator */
/* array(text, length) - dice into chunks */ /* array(text, length) - dice into chunks */
if (tag == JS_TAG_STRING || tag == JS_TAG_STRING_ROPE) { if (JS_VALUE_IS_TEXT(arg)) {
JSValue str = JS_ToString(ctx, arg); JSString *p = JS_VALUE_GET_STRING(arg);
if (JS_IsException(str)) return str;
JSString *p = JS_VALUE_GET_STRING(str);
int len = p->len; int len = p->len;
if (argc < 2 || JS_IsNull(argv[1])) { if (argc < 2 || JS_IsNull(argv[1])) {
@@ -32601,19 +32543,17 @@ static JSValue js_cell_array(JSContext *ctx, JSValueConst this_val,
for (int i = 0; i < len; i++) { for (int i = 0; i < len; i++) {
JSValue ch = js_sub_string(ctx, p, i, i + 1); JSValue ch = js_sub_string(ctx, p, i, i + 1);
if (JS_IsException(ch)) { if (JS_IsException(ch)) {
JS_FreeValue(ctx, str);
JS_FreeValue(ctx, result); JS_FreeValue(ctx, result);
return JS_EXCEPTION; return JS_EXCEPTION;
} }
JS_SetPropertyInt64(ctx, result, i, ch); JS_SetPropertyInt64(ctx, result, i, ch);
} }
JS_FreeValue(ctx, str);
return result; return result;
} }
int tag2 = JS_VALUE_GET_TAG(argv[1]); int tag2 = JS_VALUE_GET_TAG(argv[1]);
if (tag2 == JS_TAG_STRING || tag2 == JS_TAG_STRING_ROPE) { if (JS_VALUE_IS_TEXT(argv[1])) {
/* Split by separator */ /* Split by separator */
const char *cstr = JS_ToCString(ctx, str); const char *cstr = JS_ToCString(ctx, str);
const char *sep = JS_ToCString(ctx, argv[1]); const char *sep = JS_ToCString(ctx, argv[1]);
@@ -32783,7 +32723,7 @@ static JSValue js_cell_array(JSContext *ctx, JSValueConst this_val,
return JS_EXCEPTION; return JS_EXCEPTION;
} }
if (tag2 == JS_TAG_INT || tag2 == JS_TAG_FLOAT64) { if (JS_VALUE_IS_NUMBER(argv[1])) {
/* Dice into chunks */ /* Dice into chunks */
int chunk_len; int chunk_len;
if (JS_ToInt32(ctx, &chunk_len, argv[1])) { if (JS_ToInt32(ctx, &chunk_len, argv[1])) {
@@ -34518,7 +34458,7 @@ static JSValue js_cell_length(JSContext *ctx, JSValueConst this_val,
JS_FreeValue(ctx, len); JS_FreeValue(ctx, len);
return result; return result;
} }
if (JS_VALUE_GET_TAG(len) == JS_TAG_INT || JS_VALUE_GET_TAG(len) == JS_TAG_FLOAT64) if (JS_VALUE_IS_NUMBER(len))
return len; return len;
JS_FreeValue(ctx, len); JS_FreeValue(ctx, len);
} else if (JS_IsException(len)) { } else if (JS_IsException(len)) {
@@ -35097,12 +35037,6 @@ void JS_AddIntrinsicBaseObjects(JSContext *ctx)
JS_NewCFunction(ctx, js_cell_not, "not", 1), JS_NewCFunction(ctx, js_cell_not, "not", 1),
JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE); JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE);
/* normalize(text) - Unicode normalize */
JS_DefinePropertyValueStr(ctx, ctx->global_obj, "normalize",
JS_NewCFunction(ctx, js_cell_normalize, "normalize", 1),
JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE);
/* reverse() - reverse an array */ /* reverse() - reverse an array */
JS_DefinePropertyValueStr(ctx, ctx->global_obj, "reverse", JS_DefinePropertyValueStr(ctx, ctx->global_obj, "reverse",
JS_NewCFunction(ctx, js_cell_reverse, "reverse", 1), JS_NewCFunction(ctx, js_cell_reverse, "reverse", 1),