Skip to content

Commit a77873d

Browse files
authored
Optimize String.fromCharCode and String.fromCodePoint (#391)
- test for common case: single integer argument and create string directly
1 parent 83726bb commit a77873d

File tree

1 file changed

+34
-3
lines changed

1 file changed

+34
-3
lines changed

quickjs.c

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39335,6 +39335,17 @@ static JSValue js_string_fromCharCode(JSContext *ctx, JSValue this_val,
3933539335
int i;
3933639336
StringBuffer b_s, *b = &b_s;
3933739337

39338+
// shortcut for single argument common case
39339+
if (argc == 1 && JS_VALUE_GET_TAG(argv[0]) == JS_TAG_INT) {
39340+
uint16_t c16 = JS_VALUE_GET_INT(argv[0]);
39341+
if (c16 < 128) {
39342+
uint8_t c8 = c16;
39343+
return js_new_string8(ctx, &c8, 1);
39344+
} else {
39345+
return js_new_string16(ctx, &c16, 1);
39346+
}
39347+
}
39348+
3933839349
string_buffer_init(ctx, b, argc);
3933939350

3934039351
for(i = 0; i < argc; i++) {
@@ -39352,10 +39363,30 @@ static JSValue js_string_fromCodePoint(JSContext *ctx, JSValue this_val,
3935239363
{
3935339364
double d;
3935439365
int i, c;
39355-
StringBuffer b_s, *b = &b_s;
39366+
StringBuffer b_s, *b = NULL;
3935639367

39357-
/* XXX: could pre-compute string length if all arguments are JS_TAG_INT */
39368+
// shortcut for single argument common case
39369+
if (argc == 1 && JS_VALUE_GET_TAG(argv[0]) == JS_TAG_INT) {
39370+
c = JS_VALUE_GET_INT(argv[0]);
39371+
if (c < 0 || c > 0x10ffff)
39372+
goto range_error;
39373+
if (c < 128) {
39374+
uint8_t c8 = c;
39375+
return js_new_string8(ctx, &c8, 1);
39376+
}
39377+
if (c < 0x10000) {
39378+
uint16_t c16 = c;
39379+
return js_new_string16(ctx, &c16, 1);
39380+
} else {
39381+
uint16_t c16[2];
39382+
c16[0] = get_hi_surrogate(c);
39383+
c16[1] = get_lo_surrogate(c);
39384+
return js_new_string16(ctx, c16, 2);
39385+
}
39386+
}
3935839387

39388+
/* XXX: could pre-compute string length if all arguments are JS_TAG_INT */
39389+
b = &b_s;
3935939390
if (string_buffer_init(ctx, b, argc))
3936039391
goto fail;
3936139392
for(i = 0; i < argc; i++) {
@@ -39377,7 +39408,7 @@ static JSValue js_string_fromCodePoint(JSContext *ctx, JSValue this_val,
3937739408
range_error:
3937839409
JS_ThrowRangeError(ctx, "invalid code point");
3937939410
fail:
39380-
string_buffer_free(b);
39411+
if (b) string_buffer_free(b);
3938139412
return JS_EXCEPTION;
3938239413
}
3938339414

0 commit comments

Comments
 (0)