Optimize String.fromCharCode
and String.fromCodePoint
(#391)
- test for common case: single integer argument and create string directly
This commit is contained in:
parent
83726bb00c
commit
a77873d657
1 changed files with 34 additions and 3 deletions
37
quickjs.c
37
quickjs.c
|
@ -39335,6 +39335,17 @@ static JSValue js_string_fromCharCode(JSContext *ctx, JSValue this_val,
|
||||||
int i;
|
int i;
|
||||||
StringBuffer b_s, *b = &b_s;
|
StringBuffer b_s, *b = &b_s;
|
||||||
|
|
||||||
|
// shortcut for single argument common case
|
||||||
|
if (argc == 1 && JS_VALUE_GET_TAG(argv[0]) == JS_TAG_INT) {
|
||||||
|
uint16_t c16 = JS_VALUE_GET_INT(argv[0]);
|
||||||
|
if (c16 < 128) {
|
||||||
|
uint8_t c8 = c16;
|
||||||
|
return js_new_string8(ctx, &c8, 1);
|
||||||
|
} else {
|
||||||
|
return js_new_string16(ctx, &c16, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
string_buffer_init(ctx, b, argc);
|
string_buffer_init(ctx, b, argc);
|
||||||
|
|
||||||
for(i = 0; i < argc; i++) {
|
for(i = 0; i < argc; i++) {
|
||||||
|
@ -39352,10 +39363,30 @@ static JSValue js_string_fromCodePoint(JSContext *ctx, JSValue this_val,
|
||||||
{
|
{
|
||||||
double d;
|
double d;
|
||||||
int i, c;
|
int i, c;
|
||||||
StringBuffer b_s, *b = &b_s;
|
StringBuffer b_s, *b = NULL;
|
||||||
|
|
||||||
|
// shortcut for single argument common case
|
||||||
|
if (argc == 1 && JS_VALUE_GET_TAG(argv[0]) == JS_TAG_INT) {
|
||||||
|
c = JS_VALUE_GET_INT(argv[0]);
|
||||||
|
if (c < 0 || c > 0x10ffff)
|
||||||
|
goto range_error;
|
||||||
|
if (c < 128) {
|
||||||
|
uint8_t c8 = c;
|
||||||
|
return js_new_string8(ctx, &c8, 1);
|
||||||
|
}
|
||||||
|
if (c < 0x10000) {
|
||||||
|
uint16_t c16 = c;
|
||||||
|
return js_new_string16(ctx, &c16, 1);
|
||||||
|
} else {
|
||||||
|
uint16_t c16[2];
|
||||||
|
c16[0] = get_hi_surrogate(c);
|
||||||
|
c16[1] = get_lo_surrogate(c);
|
||||||
|
return js_new_string16(ctx, c16, 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* XXX: could pre-compute string length if all arguments are JS_TAG_INT */
|
/* XXX: could pre-compute string length if all arguments are JS_TAG_INT */
|
||||||
|
b = &b_s;
|
||||||
if (string_buffer_init(ctx, b, argc))
|
if (string_buffer_init(ctx, b, argc))
|
||||||
goto fail;
|
goto fail;
|
||||||
for(i = 0; i < argc; i++) {
|
for(i = 0; i < argc; i++) {
|
||||||
|
@ -39377,7 +39408,7 @@ static JSValue js_string_fromCodePoint(JSContext *ctx, JSValue this_val,
|
||||||
range_error:
|
range_error:
|
||||||
JS_ThrowRangeError(ctx, "invalid code point");
|
JS_ThrowRangeError(ctx, "invalid code point");
|
||||||
fail:
|
fail:
|
||||||
string_buffer_free(b);
|
if (b) string_buffer_free(b);
|
||||||
return JS_EXCEPTION;
|
return JS_EXCEPTION;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue