]> granicus.if.org Git - php/commitdiff
Improved performance of unserialize(), original patch by galaxy dot mipt at gmail...
authorKalle Sommer Nielsen <kalle@php.net>
Sat, 18 Sep 2010 16:09:28 +0000 (16:09 +0000)
committerKalle Sommer Nielsen <kalle@php.net>
Sat, 18 Sep 2010 16:09:28 +0000 (16:09 +0000)
NEWS
ext/standard/php_var.h
ext/standard/var_unserializer.c
ext/standard/var_unserializer.re

diff --git a/NEWS b/NEWS
index 08a40e0882f535eec61753c45e5b42a94e4ff96c..0b8f620ec76ae4888bc4ff564fe106de9a225dd2 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -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)
index 91026f804b34885e63cbda6c9fcb2295d2a57497..a3a9875e00db94db6cf4d0a6e0585fbff5800519 100644 (file)
@@ -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;
index 8af61755871c2bd65966bcba842508d0c6139bed..aa6c2020d5fb55a64d35746c3e6d6a5d300f2f5b 100644 (file)
@@ -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;
index b1b5d34efe1d83cf5d3ccc70c89d12f8fc5fe001..6ccf8a3b63724e53fbdf6c1b4c86e260d6693d8d 100644 (file)
@@ -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);