Skip to content

Commit 124396a

Browse files
committed
potential solution
1 parent 65f3b7e commit 124396a

File tree

1 file changed

+15
-7
lines changed

1 file changed

+15
-7
lines changed

ext/json/json_encoder.c

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -504,14 +504,11 @@ zend_result php_json_escape_string(
504504
//}
505505
//printf("\n");
506506

507-
// TODO: problem if the first UTF-8 char comes before the first escape char
508-
// and getting this right+performant is hard, so for now we just don't shift.
507+
int max_shift = 16;
508+
509509
int input_range_mask = _mm_movemask_epi8(input_range);
510510
if (input_range_mask != 0) {
511-
//int shift = __builtin_ctz(input_range_mask);
512-
//pos += shift;
513-
//len -= shift;
514-
break;
511+
max_shift = __builtin_ctz(input_range_mask);
515512
}
516513

517514
#if 0
@@ -537,7 +534,13 @@ zend_result php_json_escape_string(
537534
int mask = _mm_cvtsi128_si32(result_individual_bytes);
538535
#endif
539536
if (mask != 0) {
540-
int shift = __builtin_clz(mask) - 16;
537+
if (max_shift < 16) {
538+
int shift = __builtin_ctz(mask); /* first offending character */
539+
pos += MIN(max_shift, shift);
540+
len -= MIN(max_shift, shift);
541+
break;
542+
}
543+
int shift = __builtin_clz(mask) - 16; /* skips over everything */
541544
do {
542545
/* Note that we shift the input forward, so we have to shift the mask as well,
543546
* beyond the to-be-escaped character */
@@ -557,6 +560,11 @@ zend_result php_json_escape_string(
557560

558561
pos += shift;
559562
} else {
563+
if (max_shift < 16) {
564+
pos += max_shift;
565+
len -= max_shift;
566+
break;
567+
}
560568
pos += sizeof(__m128i);
561569
}
562570

0 commit comments

Comments
 (0)