diff options
author | Kalle Sommer Nielsen <kalle@php.net> | 2010-09-18 16:09:28 +0000 |
---|---|---|
committer | Kalle Sommer Nielsen <kalle@php.net> | 2010-09-18 16:09:28 +0000 |
commit | 208aa1025d0316b517383bd1e102d39c919636a3 (patch) | |
tree | 96b326dceca0bbcc957100d87a17cde60618bbfd | |
parent | 1c9e784985a9f9194ac2b5854c48d13c0e75d3a7 (diff) | |
download | php-git-208aa1025d0316b517383bd1e102d39c919636a3.tar.gz |
Improved performance of unserialize(), original patch by galaxy dot mipt at gmail dot com
-rw-r--r-- | NEWS | 2 | ||||
-rw-r--r-- | ext/standard/php_var.h | 2 | ||||
-rw-r--r-- | ext/standard/var_unserializer.c | 941 | ||||
-rw-r--r-- | ext/standard/var_unserializer.re | 36 |
4 files changed, 662 insertions, 319 deletions
@@ -97,6 +97,8 @@ . Don't terminate shell on fatal errors. - Improved ext/zlib: re-implemented non-file related functionality. (Mike) - Improved output layer. See README.NEW-OUTPUT-API for internals. (Mike) +- Improved the performance of unserialize(). (galaxy dot mipt at gmail dot com, + Kalle) - Removed legacy features: . allow_call_time_pass_reference. (Pierrick) diff --git a/ext/standard/php_var.h b/ext/standard/php_var.h index 91026f804b..a3a9875e00 100644 --- a/ext/standard/php_var.h +++ b/ext/standard/php_var.h @@ -42,7 +42,9 @@ typedef HashTable* php_serialize_data_t; struct php_unserialize_data { void *first; + void *last; void *first_dtor; + void *last_dtor; }; typedef struct php_unserialize_data* php_unserialize_data_t; diff --git a/ext/standard/var_unserializer.c b/ext/standard/var_unserializer.c index 8af6175587..aa6c2020d5 100644 --- a/ext/standard/var_unserializer.c +++ b/ext/standard/var_unserializer.c @@ -1,4 +1,4 @@ -/* Generated by re2c 0.13.5 on Fri Aug 6 19:20:07 2010 */ +/* Generated by re2c 0.13.5 on Sat Sep 18 17:59:40 2010 */ #line 1 "ext/standard/var_unserializer.re" /* +----------------------------------------------------------------------+ @@ -35,25 +35,23 @@ typedef struct { static inline void var_push(php_unserialize_data_t *var_hashx, zval **rval) { - var_entries *var_hash = (*var_hashx)->first, *prev = NULL; + var_entries *var_hash = (*var_hashx)->last; #if 0 fprintf(stderr, "var_push(%ld): %d\n", var_hash?var_hash->used_slots:-1L, Z_TYPE_PP(rval)); #endif - - while (var_hash && var_hash->used_slots == VAR_ENTRIES_MAX) { - prev = var_hash; - var_hash = var_hash->next; - } - if (!var_hash) { + if (!var_hash || var_hash->used_slots == VAR_ENTRIES_MAX) { var_hash = emalloc(sizeof(var_entries)); var_hash->used_slots = 0; var_hash->next = 0; - if (!(*var_hashx)->first) + if (!(*var_hashx)->first) { (*var_hashx)->first = var_hash; - else - prev->next = var_hash; + } else { + ((var_entries *) (*var_hashx)->last)->next = var_hash; + } + + (*var_hashx)->last = var_hash; } var_hash->data[var_hash->used_slots++] = *rval; @@ -61,25 +59,23 @@ static inline void var_push(php_unserialize_data_t *var_hashx, zval **rval) PHPAPI void var_push_dtor(php_unserialize_data_t *var_hashx, zval **rval) { - var_entries *var_hash = (*var_hashx)->first_dtor, *prev = NULL; + var_entries *var_hash = (*var_hashx)->last_dtor; #if 0 fprintf(stderr, "var_push_dtor(%ld): %d\n", var_hash?var_hash->used_slots:-1L, Z_TYPE_PP(rval)); #endif - - while (var_hash && var_hash->used_slots == VAR_ENTRIES_MAX) { - prev = var_hash; - var_hash = var_hash->next; - } - if (!var_hash) { + if (!var_hash || var_hash->used_slots == VAR_ENTRIES_MAX) { var_hash = emalloc(sizeof(var_entries)); var_hash->used_slots = 0; var_hash->next = 0; - if (!(*var_hashx)->first_dtor) + if (!(*var_hashx)->first_dtor) { (*var_hashx)->first_dtor = var_hash; - else - prev->next = var_hash; + } else { + ((var_entries *) (*var_hashx)->last_dtor)->next = var_hash; + } + + (*var_hashx)->last_dtor = var_hash; } Z_ADDREF_PP(rval); @@ -205,7 +201,7 @@ static char *unserialize_str(const unsigned char **p, size_t *len, size_t maxlen #define YYMARKER marker -#line 213 "ext/standard/var_unserializer.re" +#line 209 "ext/standard/var_unserializer.re" @@ -411,43 +407,9 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER) -#line 415 "ext/standard/var_unserializer.c" +#line 411 "ext/standard/var_unserializer.c" { YYCTYPE yych; - static const unsigned char yybm[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }; if ((YYLIMIT - YYCURSOR) < 7) YYFILL(7); yych = *YYCURSOR; @@ -469,90 +431,147 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER) } yy2: yych = *(YYMARKER = ++YYCURSOR); - if (yych == ':') goto yy95; + switch (yych) { + case ':': goto yy95; + default: goto yy3; + } yy3: -#line 737 "ext/standard/var_unserializer.re" +#line 733 "ext/standard/var_unserializer.re" { return 0; } -#line 477 "ext/standard/var_unserializer.c" +#line 442 "ext/standard/var_unserializer.c" yy4: yych = *(YYMARKER = ++YYCURSOR); - if (yych == ':') goto yy89; - goto yy3; + switch (yych) { + case ':': goto yy89; + default: goto yy3; + } yy5: yych = *++YYCURSOR; - if (yych == ';') goto yy87; - goto yy3; + switch (yych) { + case ';': goto yy87; + default: goto yy3; + } yy6: yych = *(YYMARKER = ++YYCURSOR); - if (yych == ':') goto yy83; - goto yy3; + switch (yych) { + case ':': goto yy83; + default: goto yy3; + } yy7: yych = *(YYMARKER = ++YYCURSOR); - if (yych == ':') goto yy77; - goto yy3; + switch (yych) { + case ':': goto yy77; + default: goto yy3; + } yy8: yych = *(YYMARKER = ++YYCURSOR); - if (yych == ':') goto yy53; - goto yy3; + switch (yych) { + case ':': goto yy53; + default: goto yy3; + } yy9: yych = *(YYMARKER = ++YYCURSOR); - if (yych == ':') goto yy46; - goto yy3; + switch (yych) { + case ':': goto yy46; + default: goto yy3; + } yy10: yych = *(YYMARKER = ++YYCURSOR); - if (yych == ':') goto yy39; - goto yy3; + switch (yych) { + case ':': goto yy39; + default: goto yy3; + } yy11: yych = *(YYMARKER = ++YYCURSOR); - if (yych == ':') goto yy32; - goto yy3; + switch (yych) { + case ':': goto yy32; + default: goto yy3; + } yy12: yych = *(YYMARKER = ++YYCURSOR); - if (yych == ':') goto yy25; - goto yy3; + switch (yych) { + case ':': goto yy25; + default: goto yy3; + } yy13: yych = *(YYMARKER = ++YYCURSOR); - if (yych == ':') goto yy17; - goto yy3; + switch (yych) { + case ':': goto yy17; + default: goto yy3; + } yy14: ++YYCURSOR; -#line 731 "ext/standard/var_unserializer.re" +#line 727 "ext/standard/var_unserializer.re" { /* this is the case where we have less data than planned */ php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Unexpected end of serialized data"); return 0; /* not sure if it should be 0 or 1 here? */ } -#line 526 "ext/standard/var_unserializer.c" +#line 511 "ext/standard/var_unserializer.c" yy16: yych = *++YYCURSOR; goto yy3; yy17: yych = *++YYCURSOR; - if (yybm[0+yych] & 128) { - goto yy20; + switch (yych) { + case '+': goto yy19; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy20; + default: goto yy18; } - if (yych == '+') goto yy19; yy18: YYCURSOR = YYMARKER; goto yy3; yy19: yych = *++YYCURSOR; - if (yybm[0+yych] & 128) { - goto yy20; + switch (yych) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy20; + default: goto yy18; } - goto yy18; yy20: ++YYCURSOR; if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2); yych = *YYCURSOR; - if (yybm[0+yych] & 128) { - goto yy20; + switch (yych) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy20; + case ':': goto yy22; + default: goto yy18; } - if (yych != ':') goto yy18; +yy22: yych = *++YYCURSOR; - if (yych != '"') goto yy18; + switch (yych) { + case '"': goto yy23; + default: goto yy18; + } +yy23: ++YYCURSOR; -#line 614 "ext/standard/var_unserializer.re" +#line 610 "ext/standard/var_unserializer.re" { size_t len, len2, len3, maxlen; long elements; @@ -669,32 +688,66 @@ yy20: return object_common2(UNSERIALIZE_PASSTHRU, elements); } -#line 673 "ext/standard/var_unserializer.c" +#line 692 "ext/standard/var_unserializer.c" yy25: yych = *++YYCURSOR; - if (yych <= ',') { - if (yych != '+') goto yy18; - } else { - if (yych <= '-') goto yy26; - if (yych <= '/') goto yy18; - if (yych <= '9') goto yy27; - goto yy18; + switch (yych) { + case '+': + case '-': goto yy26; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy27; + default: goto yy18; } yy26: yych = *++YYCURSOR; - if (yych <= '/') goto yy18; - if (yych >= ':') goto yy18; + switch (yych) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy27; + default: goto yy18; + } yy27: ++YYCURSOR; if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2); yych = *YYCURSOR; - if (yych <= '/') goto yy18; - if (yych <= '9') goto yy27; - if (yych >= ';') goto yy18; + switch (yych) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy27; + case ':': goto yy29; + default: goto yy18; + } +yy29: yych = *++YYCURSOR; - if (yych != '"') goto yy18; + switch (yych) { + case '"': goto yy30; + default: goto yy18; + } +yy30: ++YYCURSOR; -#line 606 "ext/standard/var_unserializer.re" +#line 602 "ext/standard/var_unserializer.re" { INIT_PZVAL(*rval); @@ -702,28 +755,65 @@ yy27: return object_common2(UNSERIALIZE_PASSTHRU, object_common1(UNSERIALIZE_PASSTHRU, ZEND_STANDARD_CLASS_DEF_PTR)); } -#line 706 "ext/standard/var_unserializer.c" +#line 759 "ext/standard/var_unserializer.c" yy32: yych = *++YYCURSOR; - if (yych == '+') goto yy33; - if (yych <= '/') goto yy18; - if (yych <= '9') goto yy34; - goto yy18; + switch (yych) { + case '+': goto yy33; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy34; + default: goto yy18; + } yy33: yych = *++YYCURSOR; - if (yych <= '/') goto yy18; - if (yych >= ':') goto yy18; + switch (yych) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy34; + default: goto yy18; + } yy34: ++YYCURSOR; if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2); yych = *YYCURSOR; - if (yych <= '/') goto yy18; - if (yych <= '9') goto yy34; - if (yych >= ';') goto yy18; + switch (yych) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy34; + case ':': goto yy36; + default: goto yy18; + } +yy36: yych = *++YYCURSOR; - if (yych != '{') goto yy18; + switch (yych) { + case '{': goto yy37; + default: goto yy18; + } +yy37: ++YYCURSOR; -#line 586 "ext/standard/var_unserializer.re" +#line 582 "ext/standard/var_unserializer.re" { long elements = parse_iv(start + 2); /* use iv() not uiv() in order to check data range */ @@ -743,28 +833,65 @@ yy34: return finish_nested_data(UNSERIALIZE_PASSTHRU); } -#line 747 "ext/standard/var_unserializer.c" +#line 837 "ext/standard/var_unserializer.c" yy39: yych = *++YYCURSOR; - if (yych == '+') goto yy40; - if (yych <= '/') goto yy18; - if (yych <= '9') goto yy41; - goto yy18; + switch (yych) { + case '+': goto yy40; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy41; + default: goto yy18; + } yy40: yych = *++YYCURSOR; - if (yych <= '/') goto yy18; - if (yych >= ':') goto yy18; + switch (yych) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy41; + default: goto yy18; + } yy41: ++YYCURSOR; if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2); yych = *YYCURSOR; - if (yych <= '/') goto yy18; - if (yych <= '9') goto yy41; - if (yych >= ';') goto yy18; + switch (yych) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy41; + case ':': goto yy43; + default: goto yy18; + } +yy43: yych = *++YYCURSOR; - if (yych != '"') goto yy18; + switch (yych) { + case '"': goto yy44; + default: goto yy18; + } +yy44: ++YYCURSOR; -#line 557 "ext/standard/var_unserializer.re" +#line 553 "ext/standard/var_unserializer.re" { size_t len, maxlen; char *str; @@ -793,28 +920,65 @@ yy41: ZVAL_STRINGL(*rval, str, len, 0); return 1; } -#line 797 "ext/standard/var_unserializer.c" +#line 924 "ext/standard/var_unserializer.c" yy46: yych = *++YYCURSOR; - if (yych == '+') goto yy47; - if (yych <= '/') goto yy18; - if (yych <= '9') goto yy48; - goto yy18; + switch (yych) { + case '+': goto yy47; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy48; + default: goto yy18; + } yy47: yych = *++YYCURSOR; - if (yych <= '/') goto yy18; - if (yych >= ':') goto yy18; + switch (yych) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy48; + default: goto yy18; + } yy48: ++YYCURSOR; if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2); yych = *YYCURSOR; - if (yych <= '/') goto yy18; - if (yych <= '9') goto yy48; - if (yych >= ';') goto yy18; + switch (yych) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy48; + case ':': goto yy50; + default: goto yy18; + } +yy50: yych = *++YYCURSOR; - if (yych != '"') goto yy18; + switch (yych) { + case '"': goto yy51; + default: goto yy18; + } +yy51: ++YYCURSOR; -#line 529 "ext/standard/var_unserializer.re" +#line 525 "ext/standard/var_unserializer.re" { size_t len, maxlen; char *str; @@ -842,95 +1006,131 @@ yy48: ZVAL_STRINGL(*rval, str, len, 1); return 1; } -#line 846 "ext/standard/var_unserializer.c" +#line 1010 "ext/standard/var_unserializer.c" yy53: yych = *++YYCURSOR; - if (yych <= '/') { - if (yych <= ',') { - if (yych == '+') goto yy57; - goto yy18; - } else { - if (yych <= '-') goto yy55; - if (yych <= '.') goto yy60; - goto yy18; - } - } else { - if (yych <= 'I') { - if (yych <= '9') goto yy58; - if (yych <= 'H') goto yy18; - goto yy56; - } else { - if (yych != 'N') goto yy18; - } + switch (yych) { + case '+': goto yy57; + case '-': goto yy55; + case '.': goto yy60; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy58; + case 'I': goto yy56; + case 'N': goto yy54; + default: goto yy18; } +yy54: yych = *++YYCURSOR; - if (yych == 'A') goto yy76; - goto yy18; + switch (yych) { + case 'A': goto yy76; + default: goto yy18; + } yy55: yych = *++YYCURSOR; - if (yych <= '/') { - if (yych == '.') goto yy60; - goto yy18; - } else { - if (yych <= '9') goto yy58; - if (yych != 'I') goto yy18; + switch (yych) { + case '.': goto yy60; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy58; + case 'I': goto yy56; + default: goto yy18; } yy56: yych = *++YYCURSOR; - if (yych == 'N') goto yy72; - goto yy18; + switch (yych) { + case 'N': goto yy72; + default: goto yy18; + } yy57: yych = *++YYCURSOR; - if (yych == '.') goto yy60; - if (yych <= '/') goto yy18; - if (yych >= ':') goto yy18; + switch (yych) { + case '.': goto yy60; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy58; + default: goto yy18; + } yy58: ++YYCURSOR; if ((YYLIMIT - YYCURSOR) < 4) YYFILL(4); yych = *YYCURSOR; - if (yych <= ':') { - if (yych <= '.') { - if (yych <= '-') goto yy18; - goto yy70; - } else { - if (yych <= '/') goto yy18; - if (yych <= '9') goto yy58; - goto yy18; - } - } else { - if (yych <= 'E') { - if (yych <= ';') goto yy63; - if (yych <= 'D') goto yy18; - goto yy65; - } else { - if (yych == 'e') goto yy65; - goto yy18; - } + switch (yych) { + case '.': goto yy70; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy58; + case ';': goto yy63; + case 'E': + case 'e': goto yy65; + default: goto yy18; } yy60: yych = *++YYCURSOR; - if (yych <= '/') goto yy18; - if (yych >= ':') goto yy18; + switch (yych) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy61; + default: goto yy18; + } yy61: ++YYCURSOR; if ((YYLIMIT - YYCURSOR) < 4) YYFILL(4); yych = *YYCURSOR; - if (yych <= ';') { - if (yych <= '/') goto yy18; - if (yych <= '9') goto yy61; - if (yych <= ':') goto yy18; - } else { - if (yych <= 'E') { - if (yych <= 'D') goto yy18; - goto yy65; - } else { - if (yych == 'e') goto yy65; - goto yy18; - } + switch (yych) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy61; + case ';': goto yy63; + case 'E': + case 'e': goto yy65; + default: goto yy18; } yy63: ++YYCURSOR; -#line 519 "ext/standard/var_unserializer.re" +#line 515 "ext/standard/var_unserializer.re" { #if SIZEOF_LONG == 4 use_double: @@ -940,66 +1140,109 @@ use_double: ZVAL_DOUBLE(*rval, zend_strtod((const char *)start + 2, NULL)); return 1; } -#line 944 "ext/standard/var_unserializer.c" +#line 1144 "ext/standard/var_unserializer.c" yy65: yych = *++YYCURSOR; - if (yych <= ',') { - if (yych != '+') goto yy18; - } else { - if (yych <= '-') goto yy66; - if (yych <= '/') goto yy18; - if (yych <= '9') goto yy67; - goto yy18; + switch (yych) { + case '+': + case '-': goto yy66; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy67; + default: goto yy18; } yy66: yych = *++YYCURSOR; - if (yych <= ',') { - if (yych == '+') goto yy69; - goto yy18; - } else { - if (yych <= '-') goto yy69; - if (yych <= '/') goto yy18; - if (yych >= ':') goto yy18; + switch (yych) { + case '+': + case '-': goto yy69; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy67; + default: goto yy18; } yy67: ++YYCURSOR; if (YYLIMIT <= YYCURSOR) YYFILL(1); yych = *YYCURSOR; - if (yych <= '/') goto yy18; - if (yych <= '9') goto yy67; - if (yych == ';') goto yy63; - goto yy18; + switch (yych) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy67; + case ';': goto yy63; + default: goto yy18; + } yy69: yych = *++YYCURSOR; - if (yych <= '/') goto yy18; - if (yych <= '9') goto yy67; - goto yy18; + switch (yych) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy67; + default: goto yy18; + } yy70: ++YYCURSOR; if ((YYLIMIT - YYCURSOR) < 4) YYFILL(4); yych = *YYCURSOR; - if (yych <= ';') { - if (yych <= '/') goto yy18; - if (yych <= '9') goto yy70; - if (yych <= ':') goto yy18; - goto yy63; - } else { - if (yych <= 'E') { - if (yych <= 'D') goto yy18; - goto yy65; - } else { - if (yych == 'e') goto yy65; - goto yy18; - } + switch (yych) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy70; + case ';': goto yy63; + case 'E': + case 'e': goto yy65; + default: goto yy18; } yy72: yych = *++YYCURSOR; - if (yych != 'F') goto yy18; + switch (yych) { + case 'F': goto yy73; + default: goto yy18; + } yy73: yych = *++YYCURSOR; - if (yych != ';') goto yy18; + switch (yych) { + case ';': goto yy74; + default: goto yy18; + } +yy74: ++YYCURSOR; -#line 504 "ext/standard/var_unserializer.re" +#line 500 "ext/standard/var_unserializer.re" { *p = YYCURSOR; INIT_PZVAL(*rval); @@ -1014,34 +1257,66 @@ yy73: return 1; } -#line 1018 "ext/standard/var_unserializer.c" +#line 1261 "ext/standard/var_unserializer.c" yy76: yych = *++YYCURSOR; - if (yych == 'N') goto yy73; - goto yy18; + switch (yych) { + case 'N': goto yy73; + default: goto yy18; + } yy77: yych = *++YYCURSOR; - if (yych <= ',') { - if (yych != '+') goto yy18; - } else { - if (yych <= '-') goto yy78; - if (yych <= '/') goto yy18; - if (yych <= '9') goto yy79; - goto yy18; + switch (yych) { + case '+': + case '-': goto yy78; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy79; + default: goto yy18; } yy78: yych = *++YYCURSOR; - if (yych <= '/') goto yy18; - if (yych >= ':') goto yy18; + switch (yych) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy79; + default: goto yy18; + } yy79: ++YYCURSOR; if (YYLIMIT <= YYCURSOR) YYFILL(1); yych = *YYCURSOR; - if (yych <= '/') goto yy18; - if (yych <= '9') goto yy79; - if (yych != ';') goto yy18; + switch (yych) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy79; + case ';': goto yy81; + default: goto yy18; + } +yy81: ++YYCURSOR; -#line 477 "ext/standard/var_unserializer.re" +#line 473 "ext/standard/var_unserializer.re" { #if SIZEOF_LONG == 4 int digits = YYCURSOR - start - 3; @@ -1068,55 +1343,93 @@ yy79: ZVAL_LONG(*rval, parse_iv(start + 2)); return 1; } -#line 1072 "ext/standard/var_unserializer.c" +#line 1347 "ext/standard/var_unserializer.c" yy83: yych = *++YYCURSOR; - if (yych <= '/') goto yy18; - if (yych >= '2') goto yy18; + switch (yych) { + case '0': + case '1': goto yy84; + default: goto yy18; + } +yy84: yych = *++YYCURSOR; - if (yych != ';') goto yy18; + switch (yych) { + case ';': goto yy85; + default: goto yy18; + } +yy85: ++YYCURSOR; -#line 470 "ext/standard/var_unserializer.re" +#line 466 "ext/standard/var_unserializer.re" { *p = YYCURSOR; INIT_PZVAL(*rval); ZVAL_BOOL(*rval, parse_iv(start + 2)); return 1; } -#line 1087 "ext/standard/var_unserializer.c" +#line 1370 "ext/standard/var_unserializer.c" yy87: ++YYCURSOR; -#line 463 "ext/standard/var_unserializer.re" +#line 459 "ext/standard/var_unserializer.re" { *p = YYCURSOR; INIT_PZVAL(*rval); ZVAL_NULL(*rval); return 1; } -#line 1097 "ext/standard/var_unserializer.c" +#line 1380 "ext/standard/var_unserializer.c" yy89: yych = *++YYCURSOR; - if (yych <= ',') { - if (yych != '+') goto yy18; - } else { - if (yych <= '-') goto yy90; - if (yych <= '/') goto yy18; - if (yych <= '9') goto yy91; - goto yy18; + switch (yych) { + case '+': + case '-': goto yy90; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy91; + default: goto yy18; } yy90: yych = *++YYCURSOR; - if (yych <= '/') goto yy18; - if (yych >= ':') goto yy18; + switch (yych) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy91; + default: goto yy18; + } yy91: ++YYCURSOR; if (YYLIMIT <= YYCURSOR) YYFILL(1); yych = *YYCURSOR; - if (yych <= '/') goto yy18; - if (yych <= '9') goto yy91; - if (yych != ';') goto yy18; + switch (yych) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy91; + case ';': goto yy93; + default: goto yy18; + } +yy93: ++YYCURSOR; -#line 440 "ext/standard/var_unserializer.re" +#line 436 "ext/standard/var_unserializer.re" { long id; @@ -1139,30 +1452,60 @@ yy91: return 1; } -#line 1143 "ext/standard/var_unserializer.c" +#line 1456 "ext/standard/var_unserializer.c" yy95: yych = *++YYCURSOR; - if (yych <= ',') { - if (yych != '+') goto yy18; - } else { - if (yych <= '-') goto yy96; - if (yych <= '/') goto yy18; - if (yych <= '9') goto yy97; - goto yy18; + switch (yych) { + case '+': + case '-': goto yy96; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy97; + default: goto yy18; } yy96: yych = *++YYCURSOR; - if (yych <= '/') goto yy18; - if (yych >= ':') goto yy18; + switch (yych) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy97; + default: goto yy18; + } yy97: ++YYCURSOR; if (YYLIMIT <= YYCURSOR) YYFILL(1); yych = *YYCURSOR; - if (yych <= '/') goto yy18; - if (yych <= '9') goto yy97; - if (yych != ';') goto yy18; + switch (yych) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy97; + case ';': goto yy99; + default: goto yy18; + } +yy99: ++YYCURSOR; -#line 419 "ext/standard/var_unserializer.re" +#line 415 "ext/standard/var_unserializer.re" { long id; @@ -1183,9 +1526,9 @@ yy97: return 1; } -#line 1187 "ext/standard/var_unserializer.c" +#line 1530 "ext/standard/var_unserializer.c" } -#line 739 "ext/standard/var_unserializer.re" +#line 735 "ext/standard/var_unserializer.re" return 0; diff --git a/ext/standard/var_unserializer.re b/ext/standard/var_unserializer.re index b1b5d34efe..6ccf8a3b63 100644 --- a/ext/standard/var_unserializer.re +++ b/ext/standard/var_unserializer.re @@ -33,25 +33,23 @@ typedef struct { static inline void var_push(php_unserialize_data_t *var_hashx, zval **rval) { - var_entries *var_hash = (*var_hashx)->first, *prev = NULL; + var_entries *var_hash = (*var_hashx)->last; #if 0 fprintf(stderr, "var_push(%ld): %d\n", var_hash?var_hash->used_slots:-1L, Z_TYPE_PP(rval)); #endif - - while (var_hash && var_hash->used_slots == VAR_ENTRIES_MAX) { - prev = var_hash; - var_hash = var_hash->next; - } - if (!var_hash) { + if (!var_hash || var_hash->used_slots == VAR_ENTRIES_MAX) { var_hash = emalloc(sizeof(var_entries)); var_hash->used_slots = 0; var_hash->next = 0; - if (!(*var_hashx)->first) + if (!(*var_hashx)->first) { (*var_hashx)->first = var_hash; - else - prev->next = var_hash; + } else { + ((var_entries *) (*var_hashx)->last)->next = var_hash; + } + + (*var_hashx)->last = var_hash; } var_hash->data[var_hash->used_slots++] = *rval; @@ -59,25 +57,23 @@ static inline void var_push(php_unserialize_data_t *var_hashx, zval **rval) PHPAPI void var_push_dtor(php_unserialize_data_t *var_hashx, zval **rval) { - var_entries *var_hash = (*var_hashx)->first_dtor, *prev = NULL; + var_entries *var_hash = (*var_hashx)->last_dtor; #if 0 fprintf(stderr, "var_push_dtor(%ld): %d\n", var_hash?var_hash->used_slots:-1L, Z_TYPE_PP(rval)); #endif - - while (var_hash && var_hash->used_slots == VAR_ENTRIES_MAX) { - prev = var_hash; - var_hash = var_hash->next; - } - if (!var_hash) { + if (!var_hash || var_hash->used_slots == VAR_ENTRIES_MAX) { var_hash = emalloc(sizeof(var_entries)); var_hash->used_slots = 0; var_hash->next = 0; - if (!(*var_hashx)->first_dtor) + if (!(*var_hashx)->first_dtor) { (*var_hashx)->first_dtor = var_hash; - else - prev->next = var_hash; + } else { + ((var_entries *) (*var_hashx)->last_dtor)->next = var_hash; + } + + (*var_hashx)->last_dtor = var_hash; } Z_ADDREF_PP(rval); |