summaryrefslogtreecommitdiff
path: root/ext/json/json_encoder.c
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@zend.com>2017-06-19 10:07:11 +0300
committerDmitry Stogov <dmitry@zend.com>2017-06-19 10:07:11 +0300
commit6fe75aad6da55e7ce473109e219fdc80bf3b7a51 (patch)
treea293a35500ca626f5f0c4dc3ef75e138f6d3c4ff /ext/json/json_encoder.c
parente0403eb65270c39ec664b1ff7e41c69856d51f94 (diff)
downloadphp-git-6fe75aad6da55e7ce473109e219fdc80bf3b7a51.tar.gz
Optimization for fast path.
Diffstat (limited to 'ext/json/json_encoder.c')
-rw-r--r--ext/json/json_encoder.c163
1 files changed, 83 insertions, 80 deletions
diff --git a/ext/json/json_encoder.c b/ext/json/json_encoder.c
index f0d02bfbd0..9d480bcc90 100644
--- a/ext/json/json_encoder.c
+++ b/ext/json/json_encoder.c
@@ -329,90 +329,93 @@ static int php_json_escape_string(
smart_str_appendc(buf, digits[(us & 0xf0) >> 4]);
smart_str_appendc(buf, digits[(us & 0xf)]);
} else {
- pos++;
-
- switch (us) {
- case '"':
- if (options & PHP_JSON_HEX_QUOT) {
- smart_str_appendl(buf, "\\u0022", 6);
- } else {
- smart_str_appendl(buf, "\\\"", 2);
- }
- break;
-
- case '\\':
- smart_str_appendl(buf, "\\\\", 2);
- break;
-
- case '/':
- if (options & PHP_JSON_UNESCAPED_SLASHES) {
- smart_str_appendc(buf, '/');
- } else {
- smart_str_appendl(buf, "\\/", 2);
- }
- break;
-
- case '\b':
- smart_str_appendl(buf, "\\b", 2);
- break;
-
- case '\f':
- smart_str_appendl(buf, "\\f", 2);
- break;
-
- case '\n':
- smart_str_appendl(buf, "\\n", 2);
- break;
-
- case '\r':
- smart_str_appendl(buf, "\\r", 2);
- break;
-
- case '\t':
- smart_str_appendl(buf, "\\t", 2);
- break;
-
- case '<':
- if (options & PHP_JSON_HEX_TAG) {
- smart_str_appendl(buf, "\\u003C", 6);
- } else {
- smart_str_appendc(buf, '<');
- }
- break;
-
- case '>':
- if (options & PHP_JSON_HEX_TAG) {
- smart_str_appendl(buf, "\\u003E", 6);
- } else {
- smart_str_appendc(buf, '>');
- }
- break;
+ static const uint32_t charmap[4] = {
+ 0xffffffff, 0x500080c4, 0x10000000, 0x00000000};
- case '&':
- if (options & PHP_JSON_HEX_AMP) {
- smart_str_appendl(buf, "\\u0026", 6);
- } else {
- smart_str_appendc(buf, '&');
- }
- break;
-
- case '\'':
- if (options & PHP_JSON_HEX_APOS) {
- smart_str_appendl(buf, "\\u0027", 6);
- } else {
- smart_str_appendc(buf, '\'');
- }
- break;
-
- default:
- if (us >= ' ') {
- smart_str_appendc(buf, (unsigned char) us);
- } else {
+ pos++;
+ if (EXPECTED(!(charmap[us >> 5] & (1 << (us & 0x1f))))) {
+ smart_str_appendc(buf, (unsigned char) us);
+ } else {
+ switch (us) {
+ case '"':
+ if (options & PHP_JSON_HEX_QUOT) {
+ smart_str_appendl(buf, "\\u0022", 6);
+ } else {
+ smart_str_appendl(buf, "\\\"", 2);
+ }
+ break;
+
+ case '\\':
+ smart_str_appendl(buf, "\\\\", 2);
+ break;
+
+ case '/':
+ if (options & PHP_JSON_UNESCAPED_SLASHES) {
+ smart_str_appendc(buf, '/');
+ } else {
+ smart_str_appendl(buf, "\\/", 2);
+ }
+ break;
+
+ case '\b':
+ smart_str_appendl(buf, "\\b", 2);
+ break;
+
+ case '\f':
+ smart_str_appendl(buf, "\\f", 2);
+ break;
+
+ case '\n':
+ smart_str_appendl(buf, "\\n", 2);
+ break;
+
+ case '\r':
+ smart_str_appendl(buf, "\\r", 2);
+ break;
+
+ case '\t':
+ smart_str_appendl(buf, "\\t", 2);
+ break;
+
+ case '<':
+ if (options & PHP_JSON_HEX_TAG) {
+ smart_str_appendl(buf, "\\u003C", 6);
+ } else {
+ smart_str_appendc(buf, '<');
+ }
+ break;
+
+ case '>':
+ if (options & PHP_JSON_HEX_TAG) {
+ smart_str_appendl(buf, "\\u003E", 6);
+ } else {
+ smart_str_appendc(buf, '>');
+ }
+ break;
+
+ case '&':
+ if (options & PHP_JSON_HEX_AMP) {
+ smart_str_appendl(buf, "\\u0026", 6);
+ } else {
+ smart_str_appendc(buf, '&');
+ }
+ break;
+
+ case '\'':
+ if (options & PHP_JSON_HEX_APOS) {
+ smart_str_appendl(buf, "\\u0027", 6);
+ } else {
+ smart_str_appendc(buf, '\'');
+ }
+ break;
+
+ default:
+ ZEND_ASSERT(us < ' ');
smart_str_appendl(buf, "\\u00", sizeof("\\u00")-1);
smart_str_appendc(buf, digits[(us & 0xf0) >> 4]);
smart_str_appendc(buf, digits[(us & 0xf)]);
- }
- break;
+ break;
+ }
}
}
} while (pos < len);