diff --git a/source/quickjs.c b/source/quickjs.c index 280563d3..cc61b55e 100644 --- a/source/quickjs.c +++ b/source/quickjs.c @@ -26319,9 +26319,6 @@ JSValue JS_ReadObject(JSContext *ctx, const uint8_t *buf, size_t buf_len, /*******************************************************************/ /* runtime functions & objects */ -static JSValue js_string_constructor(JSContext *ctx, JSValueConst this_val, - int argc, JSValueConst *argv); - static int check_function(JSContext *ctx, JSValueConst obj) { if (likely(JS_IsFunction(ctx, obj))) @@ -26822,56 +26819,6 @@ static JSValue js_object_keys(JSContext *ctx, JSValueConst this_val, JS_GPN_ENUM_ONLY | JS_GPN_STRING_MASK, kind); } -static JSValue js_object_toString(JSContext *ctx, JSValueConst this_val, - int argc, JSValueConst *argv) -{ - JSValue obj, tag; - int is_array; - JSAtom atom; - JSObject *p; - - if (JS_IsNull(this_val)) { - tag = js_new_string8(ctx, "Null"); - } else { - obj = JS_ToObject(ctx, this_val); - if (JS_IsException(obj)) - return obj; - is_array = JS_IsArray(ctx, obj); - if (is_array < 0) { - JS_FreeValue(ctx, obj); - return JS_EXCEPTION; - } - if (is_array) { - atom = JS_ATOM_Array; - } else if (JS_IsFunction(ctx, obj)) { - atom = JS_ATOM_Function; - } else { - p = JS_VALUE_GET_OBJ(obj); - switch(p->class_id) { - case JS_CLASS_STRING: - case JS_CLASS_ERROR: - case JS_CLASS_BOOLEAN: - case JS_CLASS_NUMBER: - case JS_CLASS_REGEXP: - atom = ctx->rt->class_array[p->class_id].class_name; - break; - default: - atom = JS_ATOM_Object; - break; - } - } - tag = JS_GetProperty(ctx, obj, JS_ATOM_Symbol_toStringTag); - JS_FreeValue(ctx, obj); - if (JS_IsException(tag)) - return JS_EXCEPTION; - if (!JS_IsString(tag)) { - JS_FreeValue(ctx, tag); - tag = JS_AtomToString(ctx, atom); - } - } - return JS_ConcatString3(ctx, "[object ", tag, "]"); -} - static JSValue js_object_seal(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int freeze_flag) { @@ -26952,10 +26899,6 @@ static JSValue JS_SpeciesConstructor(JSContext *ctx, JSValueConst obj, return species; } -static const JSCFunctionListEntry js_object_proto_funcs[] = { -// JS_CFUNC_DEF("toString", 0, js_object_toString ), -}; - /* Function class */ static JSValue js_function_proto(JSContext *ctx, JSValueConst this_val, @@ -27208,7 +27151,6 @@ static JSValue js_error_toString(JSContext *ctx, JSValueConst this_val, } static const JSCFunctionListEntry js_error_proto_funcs[] = { -// JS_CFUNC_DEF("toString", 0, js_error_toString ), JS_PROP_STRING_DEF("name", "Error", JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE ), JS_PROP_STRING_DEF("message", "", JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE ), }; @@ -27383,29 +27325,6 @@ static JSValue js_array_includes(JSContext *ctx, JSValueConst this_val, return JS_EXCEPTION; } -static JSValue js_array_toString(JSContext *ctx, JSValueConst this_val, - int argc, JSValueConst *argv) -{ - JSValue obj, method, ret; - - obj = JS_ToObject(ctx, this_val); - if (JS_IsException(obj)) - return JS_EXCEPTION; - method = JS_GetProperty(ctx, obj, JS_ATOM_join); - if (JS_IsException(method)) { - ret = JS_EXCEPTION; - } else - if (!JS_IsFunction(ctx, method)) { - /* Use intrinsic Object.prototype.toString */ - JS_FreeValue(ctx, method); - ret = js_object_toString(ctx, obj, 0, NULL); - } else { - ret = JS_CallFree(ctx, method, obj, 0, NULL); - } - JS_FreeValue(ctx, obj); - return ret; -} - static JSValue js_array_pop(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int shift) { @@ -27683,7 +27602,6 @@ static JSValue js_create_array(JSContext *ctx, int len, JSValueConst *tab) } static const JSCFunctionListEntry js_array_proto_funcs[] = { -// JS_CFUNC_DEF("toString", 0, js_array_toString ), JS_CFUNC_MAGIC_DEF("pop", 0, js_array_pop, 0 ), JS_CFUNC_MAGIC_DEF("push", 1, js_array_push, 0 ), JS_CFUNC_MAGIC_DEF("shift", 0, js_array_pop, 1 ), @@ -27782,54 +27700,6 @@ static const JSClassExoticMethods js_string_exotic_methods = { .delete_property = js_string_delete_property, }; -static JSValue js_string_constructor(JSContext *ctx, JSValueConst new_target, - int argc, JSValueConst *argv) -{ - JSValue val, obj; - if (argc == 0) { - val = JS_AtomToString(ctx, JS_ATOM_empty_string); - } else { - if (JS_IsNull(new_target) && JS_IsSymbol(argv[0])) { - JSAtomStruct *p = JS_VALUE_GET_PTR(argv[0]); - val = JS_ConcatString3(ctx, "Symbol(", JS_AtomToString(ctx, js_get_atom_index(ctx->rt, p)), ")"); - } else { - val = JS_ToString(ctx, argv[0]); - } - if (JS_IsException(val)) - return val; - } - if (!JS_IsNull(new_target)) { - JSString *p1 = JS_VALUE_GET_STRING(val); - - obj = js_create_from_ctor(ctx, new_target, JS_CLASS_STRING); - if (JS_IsException(obj)) { - JS_FreeValue(ctx, val); - } else { - JS_SetObjectData(ctx, obj, val); - JS_DefinePropertyValue(ctx, obj, JS_ATOM_length, JS_NewInt32(ctx, p1->len), 0); - } - return obj; - } else { - return val; - } -} - -static JSValue js_thisStringValue(JSContext *ctx, JSValueConst this_val) -{ - if (JS_VALUE_GET_TAG(this_val) == JS_TAG_STRING || - JS_VALUE_GET_TAG(this_val) == JS_TAG_STRING_ROPE) - return JS_DupValue(ctx, this_val); - - if (JS_VALUE_GET_TAG(this_val) == JS_TAG_OBJECT) { - JSObject *p = JS_VALUE_GET_OBJ(this_val); - if (p->class_id == JS_CLASS_STRING) { - if (JS_VALUE_GET_TAG(p->u.object_data) == JS_TAG_STRING) - return JS_DupValue(ctx, p->u.object_data); - } - } - return JS_ThrowTypeError(ctx, "not a string"); -} - static int string_cmp(JSString *p1, JSString *p2, int x1, int x2, int len) { int i, c1, c2; @@ -27840,54 +27710,6 @@ static int string_cmp(JSString *p1, JSString *p2, int x1, int x2, int len) return 0; } -static int string_indexof_char(JSString *p, int c, int from) -{ - /* assuming 0 <= from <= p->len */ - int i, len = p->len; - if (p->is_wide_char) { - for (i = from; i < len; i++) { - if (p->u.str16[i] == c) - return i; - } - } else { - if ((c & ~0xff) == 0) { - for (i = from; i < len; i++) { - if (p->u.str8[i] == (uint8_t)c) - return i; - } - } - } - return -1; -} - -static int string_indexof(JSString *p1, JSString *p2, int from) -{ - /* assuming 0 <= from <= p1->len */ - int c, i, j, len1 = p1->len, len2 = p2->len; - if (len2 == 0) - return from; - for (i = from, c = string_get(p2, 0); i + len2 <= len1; i = j + 1) { - j = string_indexof_char(p1, c, i); - if (j < 0 || j + len2 > len1) - break; - if (!string_cmp(p1, p2, j + 1, 1, len2 - 1)) - return j; - } - return -1; -} - -static int64_t string_advance_index(JSString *p, int64_t index, BOOL unicode) -{ - if (!unicode || index >= p->len || !p->is_wide_char) { - index++; - } else { - int index32 = (int)index; - string_getc(p, &index32); - index = index32; - } - return index; -} - /* return the position of the first invalid character in the string or -1 if none */ static int js_string_find_invalid_codepoint(JSString *p) @@ -27912,145 +27734,6 @@ static int js_string_find_invalid_codepoint(JSString *p) /* return < 0 if exception or TRUE/FALSE */ static int js_is_regexp(JSContext *ctx, JSValueConst obj); -static JSValue js_string___GetSubstitution(JSContext *ctx, JSValueConst this_val, - int argc, JSValueConst *argv) -{ - // GetSubstitution(matched, str, position, captures, namedCaptures, rep) - JSValueConst matched, str, captures, namedCaptures, rep; - JSValue capture, name, s; - uint32_t position, len, matched_len, captures_len; - int i, j, j0, k, k1; - int c, c1; - StringBuffer b_s, *b = &b_s; - JSString *sp, *rp; - - matched = argv[0]; - str = argv[1]; - captures = argv[3]; - namedCaptures = argv[4]; - rep = argv[5]; - - if (!JS_IsString(rep) || !JS_IsString(str)) - return JS_ThrowTypeError(ctx, "not a string"); - - sp = JS_VALUE_GET_STRING(str); - rp = JS_VALUE_GET_STRING(rep); - - string_buffer_init(ctx, b, 0); - - captures_len = 0; - if (!JS_IsNull(captures)) { - if (js_get_length32(ctx, &captures_len, captures)) - goto exception; - } - if (js_get_length32(ctx, &matched_len, matched)) - goto exception; - if (JS_ToUint32(ctx, &position, argv[2]) < 0) - goto exception; - - len = rp->len; - i = 0; - for(;;) { - j = string_indexof_char(rp, '$', i); - if (j < 0 || j + 1 >= len) - break; - string_buffer_concat(b, rp, i, j); - j0 = j++; - c = string_get(rp, j++); - if (c == '$') { - string_buffer_putc8(b, '$'); - } else if (c == '&') { - if (string_buffer_concat_value(b, matched)) - goto exception; - } else if (c == '`') { - string_buffer_concat(b, sp, 0, position); - } else if (c == '\'') { - string_buffer_concat(b, sp, position + matched_len, sp->len); - } else if (c >= '0' && c <= '9') { - k = c - '0'; - if (j < len) { - c1 = string_get(rp, j); - if (c1 >= '0' && c1 <= '9') { - /* This behavior is specified in ES6 and refined in ECMA 2019 */ - /* ECMA 2019 does not have the extra test, but - Test262 S15.5.4.11_A3_T1..3 require this behavior */ - k1 = k * 10 + c1 - '0'; - if (k1 >= 1 && k1 < captures_len) { - k = k1; - j++; - } - } - } - if (k >= 1 && k < captures_len) { - s = JS_GetPropertyInt64(ctx, captures, k); - if (JS_IsException(s)) - goto exception; - if (!JS_IsNull(s)) { - if (string_buffer_concat_value_free(b, s)) - goto exception; - } - } else { - goto norep; - } - } else if (c == '<' && !JS_IsNull(namedCaptures)) { - k = string_indexof_char(rp, '>', j); - if (k < 0) - goto norep; - name = js_sub_string(ctx, rp, j, k); - if (JS_IsException(name)) - goto exception; - capture = JS_GetPropertyValue(ctx, namedCaptures, name); - if (JS_IsException(capture)) - goto exception; - if (!JS_IsNull(capture)) { - if (string_buffer_concat_value_free(b, capture)) - goto exception; - } - j = k + 1; - } else { - norep: - string_buffer_concat(b, rp, j0, j); - } - i = j; - } - string_buffer_concat(b, rp, i, rp->len); - return string_buffer_end(b); -exception: - string_buffer_free(b); - return JS_EXCEPTION; -} - -/* also used for String.prototype.valueOf */ -static JSValue js_string_toString(JSContext *ctx, JSValueConst this_val, - int argc, JSValueConst *argv) -{ - return js_thisStringValue(ctx, this_val); -} - -static JSValue js_string_concat(JSContext *ctx, JSValueConst this_val, - int argc, JSValueConst *argv) -{ - JSValue r; - int i; - - /* XXX: Use more efficient method */ - /* XXX: This method is OK if r has a single refcount */ - /* XXX: should use string_buffer? */ - r = JS_ToStringCheckObject(ctx, this_val); - for (i = 0; i < argc; i++) { - if (JS_IsException(r)) - break; - r = JS_ConcatString(ctx, r, JS_DupValue(ctx, argv[i])); - } - return r; -} - -static const JSCFunctionListEntry js_string_proto_funcs[] = { - JS_CFUNC_DEF("concat", 1, js_string_concat), -// JS_CFUNC_DEF("toString", 0, js_string_toString ), - JS_CFUNC_DEF("valueOf", 0, js_string_toString ), -}; - /* RegExp */ static void js_regexp_finalizer(JSRuntime *rt, JSValue val) @@ -29559,88 +29242,6 @@ void JS_AddIntrinsicJSON(JSContext *ctx) JS_SetPropertyFunctionList(ctx, ctx->global_obj, js_json_obj, countof(js_json_obj)); } -/* Symbol */ - -static JSValue js_symbol_constructor(JSContext *ctx, JSValueConst new_target, - int argc, JSValueConst *argv) -{ - JSValue str; - JSString *p; - - if (!JS_IsNull(new_target)) - return JS_ThrowTypeError(ctx, "not a constructor"); - if (argc == 0 || JS_IsNull(argv[0])) { - p = NULL; - } else { - str = JS_ToString(ctx, argv[0]); - if (JS_IsException(str)) - return JS_EXCEPTION; - p = JS_VALUE_GET_STRING(str); - } - return JS_NewSymbol(ctx, p, JS_ATOM_TYPE_SYMBOL); -} - -static JSValue js_thisSymbolValue(JSContext *ctx, JSValueConst this_val) -{ - if (JS_VALUE_GET_TAG(this_val) == JS_TAG_SYMBOL) - return JS_DupValue(ctx, this_val); - - if (JS_VALUE_GET_TAG(this_val) == JS_TAG_OBJECT) { - JSObject *p = JS_VALUE_GET_OBJ(this_val); - if (p->class_id == JS_CLASS_SYMBOL) { - if (JS_VALUE_GET_TAG(p->u.object_data) == JS_TAG_SYMBOL) - return JS_DupValue(ctx, p->u.object_data); - } - } - return JS_ThrowTypeError(ctx, "not a symbol"); -} - -static JSValue js_symbol_toString(JSContext *ctx, JSValueConst this_val, - int argc, JSValueConst *argv) -{ - JSValue val, ret; - val = js_thisSymbolValue(ctx, this_val); - if (JS_IsException(val)) - return val; - /* XXX: use JS_ToStringInternal() with a flags */ - ret = js_string_constructor(ctx, JS_NULL, 1, (JSValueConst *)&val); - JS_FreeValue(ctx, val); - return ret; -} - -static JSValue js_symbol_valueOf(JSContext *ctx, JSValueConst this_val, - int argc, JSValueConst *argv) -{ - return js_thisSymbolValue(ctx, this_val); -} - -static JSValue js_symbol_get_description(JSContext *ctx, JSValueConst this_val) -{ - JSValue val, ret; - JSAtomStruct *p; - - val = js_thisSymbolValue(ctx, this_val); - if (JS_IsException(val)) - return val; - p = JS_VALUE_GET_PTR(val); - if (p->len == 0 && p->is_wide_char != 0) { - ret = JS_NULL; - } else { - ret = JS_AtomToString(ctx, js_get_atom_index(ctx->rt, p)); - } - JS_FreeValue(ctx, val); - return ret; -} - -static const JSCFunctionListEntry js_symbol_proto_funcs[] = { -// JS_CFUNC_DEF("toString", 0, js_symbol_toString ), - JS_CFUNC_DEF("valueOf", 0, js_symbol_valueOf ), - // XXX: should have writable: false - JS_CFUNC_DEF("[Symbol.toPrimitive]", 1, js_symbol_valueOf ), - JS_PROP_STRING_DEF("[Symbol.toStringTag]", "Symbol", JS_PROP_CONFIGURABLE ), - JS_CGETSET_DEF("description", js_symbol_get_description, NULL ), -}; - /* global object */ /* ============================================================================ @@ -33773,10 +33374,6 @@ void JS_AddIntrinsicBaseObjects(JSContext *ctx) ctx->global_obj = JS_NewObject(ctx); ctx->global_var_obj = JS_NewObjectProto(ctx, JS_NULL); - /* Object - no constructor, just prototype functions */ - JS_SetPropertyFunctionList(ctx, ctx->class_proto[JS_CLASS_OBJECT], - js_object_proto_funcs, countof(js_object_proto_funcs)); - /* Function - no constructor needed */ ctx->function_ctor = JS_NULL;