diff --git a/source/cell.h b/source/cell.h index 625c1ef0..d580b540 100644 --- a/source/cell.h +++ b/source/cell.h @@ -179,15 +179,12 @@ JS_SetClassProto(js, js_##TYPE##_id, TYPE##_proto); \ #define QJSCLASSPREP_FUNCS_CTOR(TYPE, CTOR_ARGC) \ ({ \ QJSCLASSPREP_FUNCS(TYPE); \ - JSValue TYPE##_ctor = JS_NewCFunction2(js, js_##TYPE##_constructor, #TYPE, CTOR_ARGC, JS_CFUNC_constructor, 0); \ - JS_SetConstructor(js, TYPE##_ctor, TYPE##_proto); \ + JSValue TYPE##_ctor = JS_NewCFunction2(js, js_##TYPE##_constructor, #TYPE, CTOR_ARGC, JS_CFUNC_generic, 0); \ TYPE##_ctor; \ }) - #define countof(x) (sizeof(x)/sizeof((x)[0])) - // Common macros for property access #define JS_GETPROP(JS, TARGET, VALUE, PROP, TYPE) {\ JSValue __##PROP##__v = JS_GetPropertyStr(JS,VALUE,#PROP); \ diff --git a/source/quickjs.c b/source/quickjs.c index ec60a956..1d66d17f 100644 --- a/source/quickjs.c +++ b/source/quickjs.c @@ -155,6 +155,18 @@ typedef struct JSProfileState { #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 { /* classid tag */ /* union usage | properties */ 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); } -/* 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 */ static JSValue js_cell_character(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) @@ -31562,8 +31533,7 @@ static JSValue js_cell_text(JSContext *ctx, JSValueConst this_val, } } - /* Default: convert to string */ - return JS_ToString(ctx, arg); + return js_cell_number_to_radix_string(ctx, num, 10); } /* Handle array */ @@ -31654,8 +31624,7 @@ static JSValue js_cell_text(JSContext *ctx, JSValueConst this_val, if (JS_IsNull(arg)) return JS_NULL; - /* Default: convert to string */ - return JS_ToString(ctx, arg); + return JS_ThrowInternalError(ctx, "Could not convert to text."); } /* 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) { if (argc < 1) return JS_NULL; - int tag = JS_VALUE_GET_TAG(argv[0]); - if (tag != JS_TAG_STRING && tag != JS_TAG_STRING_ROPE) + if (!JS_VALUE_IS_TEXT(argv[0])) return JS_NULL; - JSValue str = JS_ToString(ctx, argv[0]); - if (JS_IsException(str)) return str; - - JSString *p = JS_VALUE_GET_STRING(str); + JSString *p = JS_VALUE_GET_STRING(argv[0]); StringBuffer b_s, *b = &b_s; 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'; if (string_buffer_putc(b, c)) { string_buffer_free(b); - JS_FreeValue(ctx, str); return JS_EXCEPTION; } } - JS_FreeValue(ctx, str); return string_buffer_end(b); } @@ -31694,14 +31657,10 @@ static JSValue js_cell_text_upper(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { if (argc < 1) return JS_NULL; - int tag = JS_VALUE_GET_TAG(argv[0]); - if (tag != JS_TAG_STRING && tag != JS_TAG_STRING_ROPE) + if (!JS_VALUE_IS_TEXT(argv[0])) return JS_NULL; - JSValue str = JS_ToString(ctx, argv[0]); - if (JS_IsException(str)) return str; - - JSString *p = JS_VALUE_GET_STRING(str); + JSString *p = JS_VALUE_GET_STRING(argv[0]); StringBuffer b_s, *b = &b_s; 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'; if (string_buffer_putc(b, c)) { string_buffer_free(b); - JS_FreeValue(ctx, str); return JS_EXCEPTION; } } - JS_FreeValue(ctx, str); 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_IsException(str)) return str; + if (!JS_VALUE_IS_TEXT(argv[0])) + 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; int32_t limit = -1; if (argc > 3 && !JS_IsNull(argv[3])) { if (JS_ToInt32(ctx, &limit, argv[3])) { - JS_FreeValue(ctx, str); return JS_NULL; } 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); if (!target_is_regex) { - JSValue target = JS_ToString(ctx, argv[1]); - if (JS_IsException(target)) { - JS_FreeValue(ctx, str); - return target; - } + if (!JS_VALUE_IS_TEXT(argv[1])) + return JS_ThrowInternalError(ctx, "Second arg of replace must be pattern or text."); - JSString *tp = JS_VALUE_GET_STRING(target); + JSString *tp = JS_VALUE_GET_STRING(argv[1]); int t_len = (int)tp->len; 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); } @@ -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; } - JS_FreeValue(ctx, str); - JS_FreeValue(ctx, target); return string_buffer_end(b); fail_str_target: string_buffer_free(b); - JS_FreeValue(ctx, str); - JS_FreeValue(ctx, target); 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); - JS_FreeValue(ctx, str); return string_buffer_end(b); fail_rx: @@ -32107,7 +32053,6 @@ fail_rx: } else { JS_FreeValue(ctx, orig_last_index); } - JS_FreeValue(ctx, str); return JS_EXCEPTION; } @@ -32584,11 +32529,8 @@ static JSValue js_cell_array(JSContext *ctx, JSValueConst this_val, /* array(text) - split into characters */ /* array(text, separator) - split by separator */ /* array(text, length) - dice into chunks */ - if (tag == JS_TAG_STRING || tag == JS_TAG_STRING_ROPE) { - JSValue str = JS_ToString(ctx, arg); - if (JS_IsException(str)) return str; - - JSString *p = JS_VALUE_GET_STRING(str); + if (JS_VALUE_IS_TEXT(arg)) { + JSString *p = JS_VALUE_GET_STRING(arg); int len = p->len; 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++) { JSValue ch = js_sub_string(ctx, p, i, i + 1); if (JS_IsException(ch)) { - JS_FreeValue(ctx, str); JS_FreeValue(ctx, result); return JS_EXCEPTION; } JS_SetPropertyInt64(ctx, result, i, ch); } - JS_FreeValue(ctx, str); 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 */ const char *cstr = JS_ToCString(ctx, str); 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; } - if (tag2 == JS_TAG_INT || tag2 == JS_TAG_FLOAT64) { + if (JS_VALUE_IS_NUMBER(argv[1])) { /* Dice into chunks */ int chunk_len; 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); 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; JS_FreeValue(ctx, len); } else if (JS_IsException(len)) { @@ -35097,12 +35037,6 @@ void JS_AddIntrinsicBaseObjects(JSContext *ctx) JS_NewCFunction(ctx, js_cell_not, "not", 1), 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 */ JS_DefinePropertyValueStr(ctx, ctx->global_obj, "reverse", JS_NewCFunction(ctx, js_cell_reverse, "reverse", 1),