]> granicus.if.org Git - php/commitdiff
Implemented 'finally' keywords for php
authorXinchen Hui <laruence@php.net>
Mon, 13 Aug 2012 13:48:39 +0000 (21:48 +0800)
committerXinchen Hui <laruence@php.net>
Mon, 13 Aug 2012 13:48:39 +0000 (21:48 +0800)
RFC: https://wiki.php.net/rfc/finally
FR: https://bugs.php.net/bug.php?id=32100
and I have got some improvment ideas(performance), will implemented
later. thanks

25 files changed:
NEWS
UPGRADING
Zend/tests/catch_finally_001.phpt [new file with mode: 0644]
Zend/tests/catch_finally_002.phpt [new file with mode: 0644]
Zend/tests/catch_finally_003.phpt [new file with mode: 0644]
Zend/tests/catch_finally_004.phpt [new file with mode: 0644]
Zend/tests/catch_finally_005.phpt [new file with mode: 0644]
Zend/tests/catch_finally_006.phpt [new file with mode: 0644]
Zend/tests/try_catch_finally_001.phpt [new file with mode: 0644]
Zend/tests/try_catch_finally_002.phpt [new file with mode: 0644]
Zend/tests/try_catch_finally_003.phpt [new file with mode: 0644]
Zend/tests/try_catch_finally_004.phpt [new file with mode: 0644]
Zend/tests/try_finally_001.phpt [new file with mode: 0644]
Zend/tests/try_finally_002.phpt [new file with mode: 0644]
Zend/tests/try_finally_003.phpt [new file with mode: 0644]
Zend/zend_compile.c
Zend/zend_compile.h
Zend/zend_language_parser.y
Zend/zend_language_scanner.c
Zend/zend_language_scanner.l
Zend/zend_language_scanner_defs.h
Zend/zend_vm_def.h
Zend/zend_vm_execute.h
Zend/zend_vm_execute.skl
Zend/zend_vm_opcodes.h

diff --git a/NEWS b/NEWS
index 0c177ddb267e4084e2c950444c8cfffbb1432d99..58eeabd37f2bc71fe595b8153fcdbf2a51966faa 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -3,6 +3,7 @@ PHP                                                                        NEWS
 ?? ??? 201?, PHP 5.5.0
 
 - General improvements:
+  . Implemented 'finally' keyword (https://wiki.php.net/rfc/finally). (Laruence)
   . Drop Windows XP and 2003 support. (Pierre)
   . World domination
   . Improve set_exception_handler while doing reset.(Laruence)
index 4fac7a88f574157fb1644ea8db99815e000c6776..f95ab4962b176fe50dce2af083309b93efcde3d9 100755 (executable)
--- a/UPGRADING
+++ b/UPGRADING
@@ -31,6 +31,8 @@ PHP X.Y UPGRADE NOTES
 2. New Features
 ========================================
 
+- Support finally keyword. (Laruence)
+  (wiki.php.net/rfc/finally)
 - Support constant array/string dereferencing. (Laruence)
   (https://wiki.php.net/rfc/constdereference)
 - Add support for using empty() on the result of function calls and
diff --git a/Zend/tests/catch_finally_001.phpt b/Zend/tests/catch_finally_001.phpt
new file mode 100644 (file)
index 0000000..2b58fa7
--- /dev/null
@@ -0,0 +1,32 @@
+--TEST--
+Try catch finally
+--FILE--
+<?php
+function foo ($throw = FALSE) {
+   try {
+     echo "try\n";
+     if ($throw) {
+        throw new Exception("ex");
+     }
+   } catch (Exception $e) {
+     echo "catch\n"; 
+   } finally {
+     echo "finally\n";
+   }
+
+   echo "end\n";
+}
+
+foo();
+echo "\n";
+foo(true);
+?>
+--EXPECTF--
+try
+finally
+end
+
+try
+catch
+finally
+end
diff --git a/Zend/tests/catch_finally_002.phpt b/Zend/tests/catch_finally_002.phpt
new file mode 100644 (file)
index 0000000..5f36ae2
--- /dev/null
@@ -0,0 +1,21 @@
+--TEST--
+Try catch finally return
+--FILE--
+<?php
+function foo () {
+   try {
+     echo "try\n";
+     return 1;
+   } catch (Exception $e) {
+   } finally {
+     echo "finally\n";
+   }
+   return 2;
+}
+
+var_dump(foo());
+?>
+--EXPECTF--
+try
+finally
+int(1)
diff --git a/Zend/tests/catch_finally_003.phpt b/Zend/tests/catch_finally_003.phpt
new file mode 100644 (file)
index 0000000..a47c6f0
--- /dev/null
@@ -0,0 +1,40 @@
+--TEST--
+Try catch finally multi-return
+--FILE--
+<?php
+function dummy($msg) {
+   var_dump($msg);
+}
+
+function foo ($a) {
+   try {
+       dummy("try");
+       return $a;
+   } catch (Exception $e) {
+       throw $e;
+   } finally {
+       dummy("finally");
+       return "finally";
+   }
+   return "end";
+}
+
+function &bar($a) {
+   try {
+     echo "try\n";
+     throw new Exception("ex");
+   } catch (Exception $e) {
+   } finally {
+     return $a;
+   }
+   return ($c = "end");
+}
+var_dump(foo("para"));
+var_dump(bar("para"));
+?>
+--EXPECTF--
+string(3) "try"
+string(7) "finally"
+string(7) "finally"
+try
+string(4) "para"
diff --git a/Zend/tests/catch_finally_004.phpt b/Zend/tests/catch_finally_004.phpt
new file mode 100644 (file)
index 0000000..be32a43
--- /dev/null
@@ -0,0 +1,41 @@
+--TEST--
+Nesting try catch finally
+--FILE--
+<?php
+
+function throw_exception($msg) {
+    throw new Exception($msg);
+}
+
+function foo (&$ex) {
+   try {
+      echo "1";
+      try {
+        echo "2";
+        throw_exception("try");
+      } catch (Exception $e) {
+        echo "3";
+        throw_exception("catch");
+      } finally {
+        echo "4";
+        throw_exception("finally");
+      } 
+   } catch (Exception $e) {
+      $ex = $e;
+      echo "3";
+   } finally {
+      echo "2";
+   }
+   return 1;
+}
+
+var_dump(foo($ex));
+
+do {
+  var_dump($ex->getMessage());
+} while ($ex = $ex->getPrevious());
+?>
+--EXPECT--
+123432int(1)
+string(7) "finally"
+string(5) "catch"
diff --git a/Zend/tests/catch_finally_005.phpt b/Zend/tests/catch_finally_005.phpt
new file mode 100644 (file)
index 0000000..d8573bd
--- /dev/null
@@ -0,0 +1,21 @@
+--TEST--
+Try catch finally with return
+--FILE--
+<?php
+function foo ($a) {
+   try {
+     throw new Exception("ex");
+   } catch (PdoException $e) {
+     die("error");
+   } catch (Exception $e) {
+     return 2;
+   } finally {
+     return 3;
+   }
+   return 1;
+}
+
+var_dump(foo("para"));
+?>
+--EXPECTF--
+int(3)
diff --git a/Zend/tests/catch_finally_006.phpt b/Zend/tests/catch_finally_006.phpt
new file mode 100644 (file)
index 0000000..48937c4
--- /dev/null
@@ -0,0 +1,28 @@
+--TEST--
+Try catch finally: re-throw exception in catch block
+--FILE--
+<?php
+function foo ($a) {
+   try {
+     throw new Exception("ex");
+   } catch (Exception $e) {
+     var_dump($a);
+     throw $e;
+   } finally {
+     var_dump("finally");
+     return "return";
+   }
+   return 1;
+}
+
+try {
+   var_dump(foo("para"));
+} catch (Exception $e) {
+    "caught exception" . PHP_EOL;
+    var_dump($e->getMessage());
+}
+?>
+--EXPECT--
+string(4) "para"
+string(7) "finally"
+string(2) "ex"
diff --git a/Zend/tests/try_catch_finally_001.phpt b/Zend/tests/try_catch_finally_001.phpt
new file mode 100644 (file)
index 0000000..3d478f4
--- /dev/null
@@ -0,0 +1,36 @@
+--TEST--
+Try catch finally
+--FILE--
+<?php
+
+class AE extends Exception {};
+class BE extends Exception {};
+
+function foo () {
+    try {
+        try {
+            try {
+                throw new Exception("try");
+            } catch (AE $e) {
+                echo "0";
+                die("error");
+            } finally {
+                echo "1";
+            }
+        } finally {
+            echo "2";
+        }
+    } catch (BE $e) {
+      die("error");
+    } catch (Exception $e) {
+        echo "3";
+    } finally {
+        echo "4";
+    }
+   return 1;
+}
+
+var_dump(foo());
+?>
+--EXPECTF--
+1234int(1)
diff --git a/Zend/tests/try_catch_finally_002.phpt b/Zend/tests/try_catch_finally_002.phpt
new file mode 100644 (file)
index 0000000..94143f6
--- /dev/null
@@ -0,0 +1,42 @@
+--TEST--
+Try catch finally
+--FILE--
+<?php
+
+class AE extends Exception {};
+class BE extends Exception {};
+
+function foo () {
+    try {
+        try {
+            try {
+                try {
+                   echo "1";
+                   throw new Exception("try");
+                } catch (AE $e) {
+                   die("error");
+                } finally {
+                   echo "2";
+                }
+            } finally {
+                echo "3";
+            }
+        } catch (BE $e) {
+            die("error");
+        } finally {
+            echo "4";
+        }
+    } catch (Exception $e) {
+        echo "5";
+    } catch (AE $e) {
+        die("error");
+    } finally {
+        echo "6";
+    }
+   return 7;
+}
+
+var_dump(foo());
+?>
+--EXPECTF--
+123456int(7)
diff --git a/Zend/tests/try_catch_finally_003.phpt b/Zend/tests/try_catch_finally_003.phpt
new file mode 100644 (file)
index 0000000..78b37be
--- /dev/null
@@ -0,0 +1,38 @@
+--TEST--
+Try catch finally
+--FILE--
+<?php
+
+class AE extends Exception {};
+class BE extends Exception {};
+
+function foo () {
+    try {
+        try {
+            try {
+                throw new Exception("try");
+            } catch (AE $e) {
+                die("error");
+            } finally {
+               echo "1";
+               return 1;
+            }
+        } finally {
+           echo "2";
+           return 2;
+        }
+    } catch (BE $e) {
+      die("error");
+    } catch (Exception $e) {
+        echo "3";
+    } finally {
+        echo "4";
+        return 4;
+    }
+   return 5;
+}
+
+var_dump(foo());
+?>
+--EXPECTF--
+1234int(4)
diff --git a/Zend/tests/try_catch_finally_004.phpt b/Zend/tests/try_catch_finally_004.phpt
new file mode 100644 (file)
index 0000000..c694601
--- /dev/null
@@ -0,0 +1,30 @@
+--TEST--
+Try catch finally
+--CREDITS--
+adoy
+--FILE--
+<?php
+function dummy($msg) {
+   var_dump($msg);
+}
+try {
+    try {
+        var_dump("try");
+        return;
+    } catch (Exception $e) {
+        dummy("catch");
+        throw $e;
+    } finally {
+        dummy("finally");
+    }
+} catch (Exception $e) {
+  dummy("catch2");
+} finally {
+  dummy("finally2");
+}
+var_dump("end");
+?>
+--EXPECTF--
+string(3) "try"
+string(7) "finally"
+string(8) "finally2"
diff --git a/Zend/tests/try_finally_001.phpt b/Zend/tests/try_finally_001.phpt
new file mode 100644 (file)
index 0000000..1c168da
--- /dev/null
@@ -0,0 +1,23 @@
+--TEST--
+Try finally
+--FILE--
+<?php
+function foo ($a) {
+   try {
+     throw new Exception("ex");
+   } finally {
+     var_dump($a);
+   }
+}
+
+foo("finally");
+?>
+--EXPECTF--
+string(7) "finally"
+
+Fatal error: Uncaught exception 'Exception' with message 'ex' %s
+Stack trace:
+#0 %stry_finally_001.php(%d): foo('finally')
+#1 {main}
+  thrown in %stry_finally_001.php on line %d
+
diff --git a/Zend/tests/try_finally_002.phpt b/Zend/tests/try_finally_002.phpt
new file mode 100644 (file)
index 0000000..4467696
--- /dev/null
@@ -0,0 +1,23 @@
+--TEST--
+Try finally
+--FILE--
+<?php
+function foo () {
+   try {
+     throw new Exception("try");
+   } finally {
+     throw new Exception("finally");
+   }
+}
+
+try {
+  foo();
+} catch (Exception $e) {
+  do {
+    var_dump($e->getMessage());
+  } while ($e = $e->getPrevious());
+}
+?>
+--EXPECT--
+string(7) "finally"
+string(3) "try"
diff --git a/Zend/tests/try_finally_003.phpt b/Zend/tests/try_finally_003.phpt
new file mode 100644 (file)
index 0000000..c5a3809
--- /dev/null
@@ -0,0 +1,27 @@
+--TEST--
+Try finally
+--FILE--
+<?php
+function foo () {
+   try {
+      echo "1";
+      try {
+        echo "2";
+        throw new Exception("ex");
+      } finally {
+        echo "3";
+      }
+   } finally {
+      echo "4";
+   }
+}
+
+foo();
+?>
+--EXPECTF--
+1234
+Fatal error: Uncaught exception 'Exception' with message 'ex' %s
+Stack trace:
+#0 %stry_finally_003.php(%d): foo()
+#1 {main}
+  thrown in %stry_finally_003.php on line %d
index f8b8941e79546ce4cf818aa9dc6b7577093efeb0..1e995b6738a01af1970f792524bfb8f5027dae66 100644 (file)
@@ -2661,6 +2661,7 @@ static int zend_add_try_element(zend_uint try_op TSRMLS_DC) /* {{{ */
 
        CG(active_op_array)->try_catch_array = erealloc(CG(active_op_array)->try_catch_array, sizeof(zend_try_catch_element)*CG(active_op_array)->last_try_catch);
        CG(active_op_array)->try_catch_array[try_catch_offset].try_op = try_op;
+       CG(active_op_array)->try_catch_array[try_catch_offset].finally_op = 0;
        return try_catch_offset;
 }
 /* }}} */
@@ -2677,7 +2678,7 @@ void zend_do_first_catch(znode *open_parentheses TSRMLS_DC) /* {{{ */
 }
 /* }}} */
 
-void zend_initialize_try_catch_element(const znode *try_token TSRMLS_DC) /* {{{ */
+void zend_initialize_try_catch_element(znode *catch_token TSRMLS_DC) /* {{{ */
 {
        int jmp_op_number = get_next_op_number(CG(active_op_array));
        zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
@@ -2694,7 +2695,7 @@ void zend_initialize_try_catch_element(const znode *try_token TSRMLS_DC) /* {{{
        zend_stack_top(&CG(bp_stack), (void **) &jmp_list_ptr);
        zend_llist_add_element(jmp_list_ptr, &jmp_op_number);
 
-       zend_add_catch_element(try_token->u.op.opline_num, get_next_op_number(CG(active_op_array)) TSRMLS_CC);
+    catch_token->EA = get_next_op_number(CG(active_op_array));
 }
 /* }}} */
 
@@ -2720,7 +2721,11 @@ void zend_do_try(znode *try_token TSRMLS_DC) /* {{{ */
 }
 /* }}} */
 
-void zend_do_begin_catch(znode *try_token, znode *class_name, znode *catch_var, znode *first_catch TSRMLS_DC) /* {{{ */
+void zend_do_finally(znode *finally_token TSRMLS_DC) /* {{{ */ {
+    finally_token->u.op.opline_num = get_next_op_number(CG(active_op_array));
+} /* }}} */
+
+void zend_do_begin_catch(znode *catch_token, znode *class_name, znode *catch_var, znode *first_catch TSRMLS_DC) /* {{{ */
 {
        long catch_op_number;
        zend_op *opline;
@@ -2748,11 +2753,11 @@ void zend_do_begin_catch(znode *try_token, znode *class_name, znode *catch_var,
        Z_STRVAL(catch_var->u.constant) = (char*)CG(active_op_array)->vars[opline->op2.var].name;
        opline->result.num = 0; /* 1 means it's the last catch in the block */
 
-       try_token->u.op.opline_num = catch_op_number;
+       catch_token->u.op.opline_num = catch_op_number;
 }
 /* }}} */
 
-void zend_do_end_catch(const znode *try_token TSRMLS_DC) /* {{{ */
+void zend_do_end_catch(znode *catch_token TSRMLS_DC) /* {{{ */
 {
        int jmp_op_number = get_next_op_number(CG(active_op_array));
        zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
@@ -2766,7 +2771,39 @@ void zend_do_end_catch(const znode *try_token TSRMLS_DC) /* {{{ */
        zend_stack_top(&CG(bp_stack), (void **) &jmp_list_ptr);
        zend_llist_add_element(jmp_list_ptr, &jmp_op_number);
 
-       CG(active_op_array)->opcodes[try_token->u.op.opline_num].extended_value = get_next_op_number(CG(active_op_array));
+       CG(active_op_array)->opcodes[catch_token->u.op.opline_num].extended_value = get_next_op_number(CG(active_op_array));
+}
+/* }}} */
+
+void zend_do_bind_catch(znode *try_token, znode *catch_token TSRMLS_DC) /* {{{ */ {
+    if (catch_token->op_type != IS_UNUSED) {
+       zend_add_catch_element(try_token->u.op.opline_num, catch_token->EA TSRMLS_CC);
+    }
+}
+/* }}} */
+
+
+void zend_do_end_finally(znode *try_token, znode* catch_token, znode *finally_token TSRMLS_DC) /* {{{ */
+{
+       zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
+
+    if (catch_token->op_type == IS_UNUSED && finally_token->op_type == IS_UNUSED) {
+        zend_error(E_COMPILE_ERROR, "Cannot use try without catch or finally");
+    } 
+    if (finally_token->op_type != IS_UNUSED) {
+        CG(active_op_array)->try_catch_array[try_token->u.op.opline_num].finally_op = finally_token->u.op.opline_num;
+        //try_token->u.op.opline_num = catch_token->u.op.opline_num;
+
+        opline->opcode = ZEND_LEAVE;
+        SET_UNUSED(opline->op1);
+        SET_UNUSED(opline->op2);
+    } 
+    if (catch_token->op_type == IS_UNUSED) {
+        CG(active_op_array)->try_catch_array[try_token->u.op.opline_num].catch_op = 0;
+    } //else {
+    //    try_token->u.op.opline_num = catch_token->u.op.opline_num;
+    //}
+
 }
 /* }}} */
 
index f164122785b8b61308cd948b6477de721e8ddc1e..f604de4699cf578e6a989aadb268c6ee87d32a6c 100644 (file)
@@ -132,6 +132,7 @@ typedef struct _zend_label {
 typedef struct _zend_try_catch_element {
        zend_uint try_op;
        zend_uint catch_op;  /* ketchup! */
+    zend_uint finally_op;
 } zend_try_catch_element;
 
 #if SIZEOF_LONG == 8
@@ -381,6 +382,7 @@ struct _zend_execute_data {
        zend_class_entry *current_called_scope;
        zval *current_this;
        zval *current_object;
+    zend_bool leaving;
 };
 
 #define EX(element) execute_data.element
@@ -496,7 +498,7 @@ void zend_do_fetch_lexical_variable(znode *varname, zend_bool is_ref TSRMLS_DC);
 
 void zend_do_try(znode *try_token TSRMLS_DC);
 void zend_do_begin_catch(znode *try_token, znode *catch_class, znode *catch_var, znode *first_catch TSRMLS_DC);
-void zend_do_end_catch(const znode *try_token TSRMLS_DC);
+void zend_do_end_catch(znode *catch_token TSRMLS_DC);
 void zend_do_throw(const znode *expr TSRMLS_DC);
 
 ZEND_API int do_bind_function(const zend_op_array *op_array, zend_op *opline, HashTable *function_table, zend_bool compile_time);
@@ -662,7 +664,7 @@ void print_op_array(zend_op_array *op_array, int optimizations);
 ZEND_API int pass_two(zend_op_array *op_array TSRMLS_DC);
 zend_brk_cont_element *get_next_brk_cont_element(zend_op_array *op_array);
 void zend_do_first_catch(znode *open_parentheses TSRMLS_DC);
-void zend_initialize_try_catch_element(const znode *try_token TSRMLS_DC);
+void zend_initialize_try_catch_element(znode *catch_token TSRMLS_DC);
 void zend_do_mark_last_catch(const znode *first_catch, const znode *last_additional_catch TSRMLS_DC);
 ZEND_API zend_bool zend_is_compiling(TSRMLS_D);
 ZEND_API char *zend_make_compiled_string_description(const char *name TSRMLS_DC);
index c88e9a7c004e8dff5b2f8724bf9551bfbd793f84..80760a5a543057563f3f7546421688e924eead04 100644 (file)
@@ -160,6 +160,7 @@ static YYSIZE_T zend_yytnamerr(char*, const char*);
 %token T_RETURN     "return (T_RETURN)"
 %token T_TRY        "try (T_TRY)"
 %token T_CATCH      "catch (T_CATCH)"
+%token T_FINALLY    "finally (T_FINALLY)"
 %token T_THROW      "throw (T_THROW)"
 %token T_USE        "use (T_USE)"
 %token T_INSTEADOF  "insteadof (T_INSTEADOF)"
@@ -314,15 +315,24 @@ unticked_statement:
        |       T_DECLARE { $1.u.op.opline_num = get_next_op_number(CG(active_op_array)); zend_do_declare_begin(TSRMLS_C); } '(' declare_list ')' declare_statement { zend_do_declare_end(&$1 TSRMLS_CC); }
        |       ';'             /* empty statement */
        |       T_TRY { zend_do_try(&$1 TSRMLS_CC); } '{' inner_statement_list '}'
-               T_CATCH '(' { zend_initialize_try_catch_element(&$1 TSRMLS_CC); }
-               fully_qualified_class_name { zend_do_first_catch(&$7 TSRMLS_CC); }
-               T_VARIABLE ')' { zend_do_begin_catch(&$1, &$9, &$11, &$7 TSRMLS_CC); }
-               '{' inner_statement_list '}' { zend_do_end_catch(&$1 TSRMLS_CC); }
-               additional_catches { zend_do_mark_last_catch(&$7, &$18 TSRMLS_CC); }
+        catch_statement { zend_do_bind_catch(&$1, &$6 TSRMLS_CC); }
+        finally_statement { zend_do_end_finally(&$1, &$6, &$8 TSRMLS_CC); }
        |       T_THROW expr ';' { zend_do_throw(&$2 TSRMLS_CC); }
        |       T_GOTO T_STRING ';' { zend_do_goto(&$2 TSRMLS_CC); }
 ;
 
+catch_statement:
+       /* empty */ { $$.op_type = IS_UNUSED; }
+    |   T_CATCH '(' { zend_initialize_try_catch_element(&$1 TSRMLS_CC); } 
+        fully_qualified_class_name { zend_do_first_catch(&$2 TSRMLS_CC); }
+        T_VARIABLE ')' { zend_do_begin_catch(&$1, &$4, &$6, &$2 TSRMLS_CC); }
+               '{' inner_statement_list '}' { zend_do_end_catch(&$1 TSRMLS_CC); }
+               additional_catches { zend_do_mark_last_catch(&$2, &$13 TSRMLS_CC); $$ = $1;}
+
+finally_statement:
+       /* empty */ { $$.op_type = IS_UNUSED; }
+    |  T_FINALLY { zend_do_finally(&$1 TSRMLS_CC); } '{' inner_statement_list '}' { $$ = $1; }
+;
 
 additional_catches:
                non_empty_additional_catches { $$ = $1; }
@@ -334,12 +344,10 @@ non_empty_additional_catches:
        |       non_empty_additional_catches additional_catch { $$ = $2; }
 ;
 
-
 additional_catch:
        T_CATCH '(' fully_qualified_class_name { $$.u.op.opline_num = get_next_op_number(CG(active_op_array)); } T_VARIABLE ')' { zend_do_begin_catch(&$1, &$3, &$5, NULL TSRMLS_CC); } '{' inner_statement_list '}' { zend_do_end_catch(&$1 TSRMLS_CC); }
 ;
 
-
 unset_variables:
                unset_variable
        |       unset_variables ',' unset_variable
index 0bfbac99750e95e2640ef98264eb1f365f8c3d22..f4289c3800026cce695622fb8fbd8f5bc4b4aed2 100644 (file)
@@ -1,4 +1,4 @@
-/* Generated by re2c 0.13.5 on Mon Apr 30 15:56:25 2012 */
+/* Generated by re2c 0.13.5 on Tue Jul 24 17:16:42 2012 */
 #line 1 "Zend/zend_language_scanner.l"
 /*
    +----------------------------------------------------------------------+
@@ -1097,7 +1097,7 @@ yyc_INITIAL:
 yy3:
                YYDEBUG(3, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1791 "Zend/zend_language_scanner.l"
+#line 1795 "Zend/zend_language_scanner.l"
                {
        if (YYCURSOR > YYLIMIT) {
                return 0;
@@ -1175,7 +1175,7 @@ yy5:
 yy6:
                YYDEBUG(6, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1779 "Zend/zend_language_scanner.l"
+#line 1783 "Zend/zend_language_scanner.l"
                {
        if (CG(short_tags)) {
                zendlval->value.str.val = yytext; /* no copying - intentional */
@@ -1194,7 +1194,7 @@ yy7:
                if ((yych = *YYCURSOR) == '=') goto yy43;
                YYDEBUG(8, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1756 "Zend/zend_language_scanner.l"
+#line 1760 "Zend/zend_language_scanner.l"
                {
        if (CG(asp_tags)) {
                zendlval->value.str.val = yytext; /* no copying - intentional */
@@ -1392,7 +1392,7 @@ yy35:
                ++YYCURSOR;
                YYDEBUG(38, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1716 "Zend/zend_language_scanner.l"
+#line 1720 "Zend/zend_language_scanner.l"
                {
        YYCTYPE *bracket = (YYCTYPE*)zend_memrchr(yytext, '<', yyleng - (sizeof("script language=php>") - 1));
 
@@ -1436,7 +1436,7 @@ yy43:
                ++YYCURSOR;
                YYDEBUG(44, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1734 "Zend/zend_language_scanner.l"
+#line 1738 "Zend/zend_language_scanner.l"
                {
        if (CG(asp_tags)) {
                zendlval->value.str.val = yytext; /* no copying - intentional */
@@ -1454,7 +1454,7 @@ yy45:
                ++YYCURSOR;
                YYDEBUG(46, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1747 "Zend/zend_language_scanner.l"
+#line 1751 "Zend/zend_language_scanner.l"
                {
        zendlval->value.str.val = yytext; /* no copying - intentional */
        zendlval->value.str.len = yyleng;
@@ -1489,7 +1489,7 @@ yy50:
 yy51:
                YYDEBUG(51, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1769 "Zend/zend_language_scanner.l"
+#line 1773 "Zend/zend_language_scanner.l"
                {
        zendlval->value.str.val = yytext; /* no copying - intentional */
        zendlval->value.str.len = yyleng;
@@ -1569,7 +1569,7 @@ yyc_ST_BACKQUOTE:
 yy56:
                YYDEBUG(56, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 2242 "Zend/zend_language_scanner.l"
+#line 2246 "Zend/zend_language_scanner.l"
                {
        if (YYCURSOR > YYLIMIT) {
                return 0;
@@ -1621,7 +1621,7 @@ yy58:
                ++YYCURSOR;
                YYDEBUG(59, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 2186 "Zend/zend_language_scanner.l"
+#line 2190 "Zend/zend_language_scanner.l"
                {
        BEGIN(ST_IN_SCRIPTING);
        return '`';
@@ -1636,7 +1636,7 @@ yy61:
                ++YYCURSOR;
                YYDEBUG(62, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 2173 "Zend/zend_language_scanner.l"
+#line 2177 "Zend/zend_language_scanner.l"
                {
        zendlval->value.lval = (long) '{';
        yy_push_state(ST_IN_SCRIPTING TSRMLS_CC);
@@ -1659,7 +1659,7 @@ yy63:
 yy65:
                YYDEBUG(65, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1873 "Zend/zend_language_scanner.l"
+#line 1877 "Zend/zend_language_scanner.l"
                {
        zend_copy_value(zendlval, (yytext+1), (yyleng-1));
        zendlval->type = IS_STRING;
@@ -1671,7 +1671,7 @@ yy66:
                ++YYCURSOR;
                YYDEBUG(67, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1449 "Zend/zend_language_scanner.l"
+#line 1453 "Zend/zend_language_scanner.l"
                {
        yy_push_state(ST_LOOKING_FOR_VARNAME TSRMLS_CC);
        return T_DOLLAR_OPEN_CURLY_BRACES;
@@ -1690,7 +1690,7 @@ yy70:
                ++YYCURSOR;
                YYDEBUG(71, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1865 "Zend/zend_language_scanner.l"
+#line 1869 "Zend/zend_language_scanner.l"
                {
        yyless(yyleng - 1);
        yy_push_state(ST_VAR_OFFSET TSRMLS_CC);
@@ -1716,7 +1716,7 @@ yy73:
                ++YYCURSOR;
                YYDEBUG(74, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1855 "Zend/zend_language_scanner.l"
+#line 1859 "Zend/zend_language_scanner.l"
                {
        yyless(yyleng - 3);
        yy_push_state(ST_LOOKING_FOR_PROPERTY TSRMLS_CC);
@@ -1792,7 +1792,7 @@ yy77:
 yy78:
                YYDEBUG(78, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 2192 "Zend/zend_language_scanner.l"
+#line 2196 "Zend/zend_language_scanner.l"
                {
        if (GET_DOUBLE_QUOTES_SCANNED_LENGTH()) {
                YYCURSOR += GET_DOUBLE_QUOTES_SCANNED_LENGTH() - 1;
@@ -1852,7 +1852,7 @@ yy80:
                ++YYCURSOR;
                YYDEBUG(81, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 2181 "Zend/zend_language_scanner.l"
+#line 2185 "Zend/zend_language_scanner.l"
                {
        BEGIN(ST_IN_SCRIPTING);
        return '"';
@@ -1867,7 +1867,7 @@ yy83:
                ++YYCURSOR;
                YYDEBUG(84, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 2173 "Zend/zend_language_scanner.l"
+#line 2177 "Zend/zend_language_scanner.l"
                {
        zendlval->value.lval = (long) '{';
        yy_push_state(ST_IN_SCRIPTING TSRMLS_CC);
@@ -1890,7 +1890,7 @@ yy85:
 yy87:
                YYDEBUG(87, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1873 "Zend/zend_language_scanner.l"
+#line 1877 "Zend/zend_language_scanner.l"
                {
        zend_copy_value(zendlval, (yytext+1), (yyleng-1));
        zendlval->type = IS_STRING;
@@ -1902,7 +1902,7 @@ yy88:
                ++YYCURSOR;
                YYDEBUG(89, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1449 "Zend/zend_language_scanner.l"
+#line 1453 "Zend/zend_language_scanner.l"
                {
        yy_push_state(ST_LOOKING_FOR_VARNAME TSRMLS_CC);
        return T_DOLLAR_OPEN_CURLY_BRACES;
@@ -1921,7 +1921,7 @@ yy92:
                ++YYCURSOR;
                YYDEBUG(93, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1865 "Zend/zend_language_scanner.l"
+#line 1869 "Zend/zend_language_scanner.l"
                {
        yyless(yyleng - 1);
        yy_push_state(ST_VAR_OFFSET TSRMLS_CC);
@@ -1947,7 +1947,7 @@ yy95:
                ++YYCURSOR;
                YYDEBUG(96, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1855 "Zend/zend_language_scanner.l"
+#line 1859 "Zend/zend_language_scanner.l"
                {
        yyless(yyleng - 3);
        yy_push_state(ST_LOOKING_FOR_PROPERTY TSRMLS_CC);
@@ -1966,7 +1966,7 @@ yyc_ST_END_HEREDOC:
        ++YYCURSOR;
        YYDEBUG(100, *YYCURSOR);
        yyleng = YYCURSOR - SCNG(yy_text);
-#line 2160 "Zend/zend_language_scanner.l"
+#line 2164 "Zend/zend_language_scanner.l"
        {
        YYCURSOR += CG(heredoc_len) - 1;
        yyleng = CG(heredoc_len);
@@ -2040,7 +2040,7 @@ yy103:
 yy104:
                YYDEBUG(104, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 2284 "Zend/zend_language_scanner.l"
+#line 2288 "Zend/zend_language_scanner.l"
                {
        int newline = 0;
 
@@ -2126,7 +2126,7 @@ yy107:
                ++YYCURSOR;
                YYDEBUG(108, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 2173 "Zend/zend_language_scanner.l"
+#line 2177 "Zend/zend_language_scanner.l"
                {
        zendlval->value.lval = (long) '{';
        yy_push_state(ST_IN_SCRIPTING TSRMLS_CC);
@@ -2149,7 +2149,7 @@ yy109:
 yy111:
                YYDEBUG(111, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1873 "Zend/zend_language_scanner.l"
+#line 1877 "Zend/zend_language_scanner.l"
                {
        zend_copy_value(zendlval, (yytext+1), (yyleng-1));
        zendlval->type = IS_STRING;
@@ -2161,7 +2161,7 @@ yy112:
                ++YYCURSOR;
                YYDEBUG(113, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1449 "Zend/zend_language_scanner.l"
+#line 1453 "Zend/zend_language_scanner.l"
                {
        yy_push_state(ST_LOOKING_FOR_VARNAME TSRMLS_CC);
        return T_DOLLAR_OPEN_CURLY_BRACES;
@@ -2180,7 +2180,7 @@ yy116:
                ++YYCURSOR;
                YYDEBUG(117, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1865 "Zend/zend_language_scanner.l"
+#line 1869 "Zend/zend_language_scanner.l"
                {
        yyless(yyleng - 1);
        yy_push_state(ST_VAR_OFFSET TSRMLS_CC);
@@ -2206,7 +2206,7 @@ yy119:
                ++YYCURSOR;
                YYDEBUG(120, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1855 "Zend/zend_language_scanner.l"
+#line 1859 "Zend/zend_language_scanner.l"
                {
        yyless(yyleng - 3);
        yy_push_state(ST_LOOKING_FOR_PROPERTY TSRMLS_CC);
@@ -2379,23 +2379,23 @@ yy123:
                YYDEBUG(-1, yych);
                switch ((yych = *YYCURSOR)) {
                case 'C':
-               case 'c':       goto yy726;
+               case 'c':       goto yy729;
                case 'L':
-               case 'l':       goto yy727;
+               case 'l':       goto yy730;
                case 'M':
-               case 'm':       goto yy728;
+               case 'm':       goto yy731;
                case 'N':
-               case 'n':       goto yy729;
+               case 'n':       goto yy732;
                case 'V':
-               case 'v':       goto yy730;
+               case 'v':       goto yy733;
                case 'X':
-               case 'x':       goto yy731;
+               case 'x':       goto yy734;
                default:        goto yy186;
                }
 yy124:
                YYDEBUG(124, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1896 "Zend/zend_language_scanner.l"
+#line 1900 "Zend/zend_language_scanner.l"
                {
        zend_copy_value(zendlval, yytext, yyleng);
        zendlval->type = IS_STRING;
@@ -2407,20 +2407,20 @@ yy125:
                yych = *++YYCURSOR;
                if (yych <= 'O') {
                        if (yych <= 'H') {
-                               if (yych == 'E') goto yy708;
+                               if (yych == 'E') goto yy711;
                                goto yy186;
                        } else {
-                               if (yych <= 'I') goto yy709;
+                               if (yych <= 'I') goto yy712;
                                if (yych <= 'N') goto yy186;
-                               goto yy710;
+                               goto yy713;
                        }
                } else {
                        if (yych <= 'h') {
-                               if (yych == 'e') goto yy708;
+                               if (yych == 'e') goto yy711;
                                goto yy186;
                        } else {
-                               if (yych <= 'i') goto yy709;
-                               if (yych == 'o') goto yy710;
+                               if (yych <= 'i') goto yy712;
+                               if (yych == 'o') goto yy713;
                                goto yy186;
                        }
                }
@@ -2627,7 +2627,7 @@ yy137:
 yy138:
                YYDEBUG(138, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1438 "Zend/zend_language_scanner.l"
+#line 1442 "Zend/zend_language_scanner.l"
                {
        return yytext[0];
 }
@@ -2640,7 +2640,7 @@ yy139:
 yy140:
                YYDEBUG(140, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1169 "Zend/zend_language_scanner.l"
+#line 1173 "Zend/zend_language_scanner.l"
                {
        zendlval->value.str.val = yytext; /* no copying - intentional */
        zendlval->value.str.len = yyleng;
@@ -2659,7 +2659,7 @@ yy142:
                ++YYCURSOR;
                YYDEBUG(143, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1198 "Zend/zend_language_scanner.l"
+#line 1202 "Zend/zend_language_scanner.l"
                {
        return T_NS_SEPARATOR;
 }
@@ -2891,7 +2891,7 @@ yy167:
                ++YYCURSOR;
                YYDEBUG(168, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1443 "Zend/zend_language_scanner.l"
+#line 1447 "Zend/zend_language_scanner.l"
                {
        yy_push_state(ST_IN_SCRIPTING TSRMLS_CC);
        return '{';
@@ -2902,7 +2902,7 @@ yy169:
                ++YYCURSOR;
                YYDEBUG(170, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1455 "Zend/zend_language_scanner.l"
+#line 1459 "Zend/zend_language_scanner.l"
                {
        RESET_DOC_COMMENT();
        if (!zend_stack_is_empty(&SCNG(state_stack))) {
@@ -2938,7 +2938,7 @@ yy171:
 yy172:
                YYDEBUG(172, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1506 "Zend/zend_language_scanner.l"
+#line 1510 "Zend/zend_language_scanner.l"
                {
        if (yyleng < MAX_LENGTH_OF_LONG - 1) { /* Won't overflow */
                zendlval->value.lval = strtol(yytext, NULL, 0);
@@ -2987,7 +2987,7 @@ yy175:
 yy176:
                YYDEBUG(176, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1903 "Zend/zend_language_scanner.l"
+#line 1907 "Zend/zend_language_scanner.l"
                {
        while (YYCURSOR < YYLIMIT) {
                switch (*YYCURSOR++) {
@@ -3028,7 +3028,7 @@ yy177:
 yy178:
                YYDEBUG(178, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1994 "Zend/zend_language_scanner.l"
+#line 1998 "Zend/zend_language_scanner.l"
                {
        register char *s, *t;
        char *end;
@@ -3103,7 +3103,7 @@ yy179:
 yy180:
                YYDEBUG(180, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 2063 "Zend/zend_language_scanner.l"
+#line 2067 "Zend/zend_language_scanner.l"
                {
        int bprefix = (yytext[0] != '"') ? 1 : 0;
 
@@ -3150,7 +3150,7 @@ yy181:
                ++YYCURSOR;
                YYDEBUG(182, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 2154 "Zend/zend_language_scanner.l"
+#line 2158 "Zend/zend_language_scanner.l"
                {
        BEGIN(ST_BACKQUOTE);
        return '`';
@@ -3161,7 +3161,7 @@ yy183:
                ++YYCURSOR;
                YYDEBUG(184, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 2412 "Zend/zend_language_scanner.l"
+#line 2416 "Zend/zend_language_scanner.l"
                {
        if (YYCURSOR > YYLIMIT) {
                return 0;
@@ -3197,7 +3197,7 @@ yy187:
 yy189:
                YYDEBUG(189, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1571 "Zend/zend_language_scanner.l"
+#line 1575 "Zend/zend_language_scanner.l"
                {
        zendlval->value.dval = zend_strtod(yytext, NULL);
        zendlval->type = IS_DOUBLE;
@@ -3295,7 +3295,7 @@ yy199:
                }
                YYDEBUG(201, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1481 "Zend/zend_language_scanner.l"
+#line 1485 "Zend/zend_language_scanner.l"
                {
        char *bin = yytext + 2; /* Skip "0b" */
        int len = yyleng - 2;
@@ -3332,7 +3332,7 @@ yy202:
                }
                YYDEBUG(204, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1527 "Zend/zend_language_scanner.l"
+#line 1531 "Zend/zend_language_scanner.l"
                {
        char *hex = yytext + 2; /* Skip "0x" */
        int len = yyleng - 2;
@@ -3366,7 +3366,7 @@ yy205:
 yy206:
                YYDEBUG(206, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1971 "Zend/zend_language_scanner.l"
+#line 1975 "Zend/zend_language_scanner.l"
                {
        zendlval->value.str.val = yytext; /* no copying - intentional */
        zendlval->value.str.len = yyleng;
@@ -3408,7 +3408,7 @@ yy209:
 yy211:
                YYDEBUG(211, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1873 "Zend/zend_language_scanner.l"
+#line 1877 "Zend/zend_language_scanner.l"
                {
        zend_copy_value(zendlval, (yytext+1), (yyleng-1));
        zendlval->type = IS_STRING;
@@ -3428,7 +3428,7 @@ yy213:
                }
                YYDEBUG(214, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1426 "Zend/zend_language_scanner.l"
+#line 1430 "Zend/zend_language_scanner.l"
                {
        return T_LOGICAL_XOR;
 }
@@ -3441,7 +3441,7 @@ yy215:
                }
                YYDEBUG(216, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1418 "Zend/zend_language_scanner.l"
+#line 1422 "Zend/zend_language_scanner.l"
                {
        return T_LOGICAL_OR;
 }
@@ -3451,7 +3451,7 @@ yy217:
                ++YYCURSOR;
                YYDEBUG(218, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1406 "Zend/zend_language_scanner.l"
+#line 1410 "Zend/zend_language_scanner.l"
                {
        return T_XOR_EQUAL;
 }
@@ -3461,7 +3461,7 @@ yy219:
                ++YYCURSOR;
                YYDEBUG(220, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1410 "Zend/zend_language_scanner.l"
+#line 1414 "Zend/zend_language_scanner.l"
                {
        return T_BOOLEAN_OR;
 }
@@ -3471,7 +3471,7 @@ yy221:
                ++YYCURSOR;
                YYDEBUG(222, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1402 "Zend/zend_language_scanner.l"
+#line 1406 "Zend/zend_language_scanner.l"
                {
        return T_OR_EQUAL;
 }
@@ -3481,7 +3481,7 @@ yy223:
                ++YYCURSOR;
                YYDEBUG(224, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1414 "Zend/zend_language_scanner.l"
+#line 1418 "Zend/zend_language_scanner.l"
                {
        return T_BOOLEAN_AND;
 }
@@ -3491,7 +3491,7 @@ yy225:
                ++YYCURSOR;
                YYDEBUG(226, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1398 "Zend/zend_language_scanner.l"
+#line 1402 "Zend/zend_language_scanner.l"
                {
        return T_AND_EQUAL;
 }
@@ -3504,7 +3504,7 @@ yy227:
 yy228:
                YYDEBUG(228, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1980 "Zend/zend_language_scanner.l"
+#line 1984 "Zend/zend_language_scanner.l"
                {
        if (CG(asp_tags)) {
                BEGIN(INITIAL);
@@ -3523,7 +3523,7 @@ yy229:
                ++YYCURSOR;
                YYDEBUG(230, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1386 "Zend/zend_language_scanner.l"
+#line 1390 "Zend/zend_language_scanner.l"
                {
        return T_MOD_EQUAL;
 }
@@ -3558,7 +3558,7 @@ yy235:
                ++YYCURSOR;
                YYDEBUG(236, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1382 "Zend/zend_language_scanner.l"
+#line 1386 "Zend/zend_language_scanner.l"
                {
        return T_CONCAT_EQUAL;
 }
@@ -3571,7 +3571,7 @@ yy237:
 yy238:
                YYDEBUG(238, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1937 "Zend/zend_language_scanner.l"
+#line 1941 "Zend/zend_language_scanner.l"
                {
        int doc_com;
 
@@ -3615,7 +3615,7 @@ yy240:
                ++YYCURSOR;
                YYDEBUG(241, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1378 "Zend/zend_language_scanner.l"
+#line 1382 "Zend/zend_language_scanner.l"
                {
        return T_DIV_EQUAL;
 }
@@ -3642,7 +3642,7 @@ yy245:
                ++YYCURSOR;
                YYDEBUG(246, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1374 "Zend/zend_language_scanner.l"
+#line 1378 "Zend/zend_language_scanner.l"
                {
        return T_MUL_EQUAL;
 }
@@ -3653,7 +3653,7 @@ yy247:
                if ((yych = *YYCURSOR) == '=') goto yy251;
                YYDEBUG(248, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1434 "Zend/zend_language_scanner.l"
+#line 1438 "Zend/zend_language_scanner.l"
                {
        return T_SR;
 }
@@ -3663,7 +3663,7 @@ yy249:
                ++YYCURSOR;
                YYDEBUG(250, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1362 "Zend/zend_language_scanner.l"
+#line 1366 "Zend/zend_language_scanner.l"
                {
        return T_IS_GREATER_OR_EQUAL;
 }
@@ -3673,7 +3673,7 @@ yy251:
                ++YYCURSOR;
                YYDEBUG(252, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1394 "Zend/zend_language_scanner.l"
+#line 1398 "Zend/zend_language_scanner.l"
                {
        return T_SR_EQUAL;
 }
@@ -3688,7 +3688,7 @@ yy253:
 yy254:
                YYDEBUG(254, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1430 "Zend/zend_language_scanner.l"
+#line 1434 "Zend/zend_language_scanner.l"
                {
        return T_SL;
 }
@@ -3704,7 +3704,7 @@ yy256:
                ++YYCURSOR;
                YYDEBUG(257, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1358 "Zend/zend_language_scanner.l"
+#line 1362 "Zend/zend_language_scanner.l"
                {
        return T_IS_SMALLER_OR_EQUAL;
 }
@@ -3715,7 +3715,7 @@ yy258:
 yy259:
                YYDEBUG(259, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1354 "Zend/zend_language_scanner.l"
+#line 1358 "Zend/zend_language_scanner.l"
                {
        return T_IS_NOT_EQUAL;
 }
@@ -3770,7 +3770,7 @@ yy267:
                ++YYCURSOR;
                YYDEBUG(268, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1390 "Zend/zend_language_scanner.l"
+#line 1394 "Zend/zend_language_scanner.l"
                {
        return T_SL_EQUAL;
 }
@@ -3879,7 +3879,7 @@ yy278:
 yy279:
                YYDEBUG(279, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 2105 "Zend/zend_language_scanner.l"
+#line 2109 "Zend/zend_language_scanner.l"
                {
        char *s;
        int bprefix = (yytext[0] != '<') ? 1 : 0;
@@ -3967,7 +3967,7 @@ yy283:
                ++YYCURSOR;
                YYDEBUG(285, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1346 "Zend/zend_language_scanner.l"
+#line 1350 "Zend/zend_language_scanner.l"
                {
        return T_IS_NOT_IDENTICAL;
 }
@@ -3977,7 +3977,7 @@ yy286:
                ++YYCURSOR;
                YYDEBUG(287, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1366 "Zend/zend_language_scanner.l"
+#line 1370 "Zend/zend_language_scanner.l"
                {
        return T_PLUS_EQUAL;
 }
@@ -3987,7 +3987,7 @@ yy288:
                ++YYCURSOR;
                YYDEBUG(289, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1334 "Zend/zend_language_scanner.l"
+#line 1338 "Zend/zend_language_scanner.l"
                {
        return T_INC;
 }
@@ -4010,7 +4010,7 @@ yy292:
                }
                YYDEBUG(293, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1322 "Zend/zend_language_scanner.l"
+#line 1326 "Zend/zend_language_scanner.l"
                {
        return T_LIST;
 }
@@ -4021,7 +4021,7 @@ yy294:
                if ((yych = *YYCURSOR) == '=') goto yy298;
                YYDEBUG(295, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1350 "Zend/zend_language_scanner.l"
+#line 1354 "Zend/zend_language_scanner.l"
                {
        return T_IS_EQUAL;
 }
@@ -4031,7 +4031,7 @@ yy296:
                ++YYCURSOR;
                YYDEBUG(297, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1318 "Zend/zend_language_scanner.l"
+#line 1322 "Zend/zend_language_scanner.l"
                {
        return T_DOUBLE_ARROW;
 }
@@ -4041,7 +4041,7 @@ yy298:
                ++YYCURSOR;
                YYDEBUG(299, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1342 "Zend/zend_language_scanner.l"
+#line 1346 "Zend/zend_language_scanner.l"
                {
        return T_IS_IDENTICAL;
 }
@@ -4175,7 +4175,7 @@ yy316:
                }
                YYDEBUG(319, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1706 "Zend/zend_language_scanner.l"
+#line 1710 "Zend/zend_language_scanner.l"
                {
        if (CG(current_namespace)) {
                *zendlval = *CG(current_namespace);
@@ -4205,7 +4205,7 @@ yy321:
                }
                YYDEBUG(324, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1679 "Zend/zend_language_scanner.l"
+#line 1683 "Zend/zend_language_scanner.l"
                {
        char *filename = zend_get_compiled_filename(TSRMLS_C);
        const size_t filename_len = strlen(filename);
@@ -4257,7 +4257,7 @@ yy327:
                }
                YYDEBUG(330, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1661 "Zend/zend_language_scanner.l"
+#line 1665 "Zend/zend_language_scanner.l"
                {
        zendlval->value.lval = CG(zend_lineno);
        zendlval->type = IS_LONG;
@@ -4298,7 +4298,7 @@ yy335:
                }
                YYDEBUG(338, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1640 "Zend/zend_language_scanner.l"
+#line 1644 "Zend/zend_language_scanner.l"
                {
        const char *class_name = CG(active_class_entry) ? CG(active_class_entry)->name : NULL;
        const char *func_name = CG(active_op_array)? CG(active_op_array)->function_name : NULL;
@@ -4370,7 +4370,7 @@ yy346:
                }
                YYDEBUG(349, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1624 "Zend/zend_language_scanner.l"
+#line 1628 "Zend/zend_language_scanner.l"
                {
        const char *func_name = NULL;
 
@@ -4406,7 +4406,7 @@ yy351:
                }
                YYDEBUG(354, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1667 "Zend/zend_language_scanner.l"
+#line 1671 "Zend/zend_language_scanner.l"
                {
        char *filename = zend_get_compiled_filename(TSRMLS_C);
 
@@ -4448,7 +4448,7 @@ yy358:
                }
                YYDEBUG(361, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1604 "Zend/zend_language_scanner.l"
+#line 1608 "Zend/zend_language_scanner.l"
                {
        const char *trait_name = NULL;
        
@@ -4498,7 +4498,7 @@ yy365:
                }
                YYDEBUG(368, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1577 "Zend/zend_language_scanner.l"
+#line 1581 "Zend/zend_language_scanner.l"
                {
        const char *class_name = NULL;
        
@@ -4587,7 +4587,7 @@ yy380:
                }
                YYDEBUG(381, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1286 "Zend/zend_language_scanner.l"
+#line 1290 "Zend/zend_language_scanner.l"
                {
        return T_HALT_COMPILER;
 }
@@ -4611,7 +4611,7 @@ yy384:
                }
                YYDEBUG(385, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1266 "Zend/zend_language_scanner.l"
+#line 1270 "Zend/zend_language_scanner.l"
                {
        return T_USE;
 }
@@ -4634,7 +4634,7 @@ yy388:
                }
                YYDEBUG(389, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1314 "Zend/zend_language_scanner.l"
+#line 1318 "Zend/zend_language_scanner.l"
                {
        return T_UNSET;
 }
@@ -4810,7 +4810,7 @@ yy405:
                ++YYCURSOR;
                YYDEBUG(407, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1214 "Zend/zend_language_scanner.l"
+#line 1218 "Zend/zend_language_scanner.l"
                {
        return T_INT_CAST;
 }
@@ -4858,7 +4858,7 @@ yy413:
                ++YYCURSOR;
                YYDEBUG(416, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1218 "Zend/zend_language_scanner.l"
+#line 1222 "Zend/zend_language_scanner.l"
                {
        return T_DOUBLE_CAST;
 }
@@ -4932,7 +4932,7 @@ yy427:
                ++YYCURSOR;
                YYDEBUG(430, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1222 "Zend/zend_language_scanner.l"
+#line 1226 "Zend/zend_language_scanner.l"
                {
        return T_STRING_CAST;
 }
@@ -4969,7 +4969,7 @@ yy434:
                ++YYCURSOR;
                YYDEBUG(437, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1226 "Zend/zend_language_scanner.l"
+#line 1230 "Zend/zend_language_scanner.l"
                {
        return T_ARRAY_CAST;
 }
@@ -5011,7 +5011,7 @@ yy442:
                ++YYCURSOR;
                YYDEBUG(445, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1230 "Zend/zend_language_scanner.l"
+#line 1234 "Zend/zend_language_scanner.l"
                {
        return T_OBJECT_CAST;
 }
@@ -5056,7 +5056,7 @@ yy451:
                ++YYCURSOR;
                YYDEBUG(453, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1234 "Zend/zend_language_scanner.l"
+#line 1238 "Zend/zend_language_scanner.l"
                {
        return T_BOOL_CAST;
 }
@@ -5120,7 +5120,7 @@ yy462:
                ++YYCURSOR;
                YYDEBUG(465, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1238 "Zend/zend_language_scanner.l"
+#line 1242 "Zend/zend_language_scanner.l"
                {
        return T_UNSET_CAST;
 }
@@ -5138,7 +5138,7 @@ yy467:
                }
                YYDEBUG(468, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1210 "Zend/zend_language_scanner.l"
+#line 1214 "Zend/zend_language_scanner.l"
                {
        return T_VAR;
 }
@@ -5162,7 +5162,7 @@ yy471:
                }
                YYDEBUG(472, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1202 "Zend/zend_language_scanner.l"
+#line 1206 "Zend/zend_language_scanner.l"
                {
        return T_NEW;
 }
@@ -5205,7 +5205,7 @@ yy479:
                }
                YYDEBUG(480, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1262 "Zend/zend_language_scanner.l"
+#line 1266 "Zend/zend_language_scanner.l"
                {
        return T_NAMESPACE;
 }
@@ -5215,7 +5215,7 @@ yy481:
                ++YYCURSOR;
                YYDEBUG(482, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1194 "Zend/zend_language_scanner.l"
+#line 1198 "Zend/zend_language_scanner.l"
                {
        return T_PAAMAYIM_NEKUDOTAYIM;
 }
@@ -5241,7 +5241,7 @@ yy485:
                ++YYCURSOR;
                YYDEBUG(486, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1370 "Zend/zend_language_scanner.l"
+#line 1374 "Zend/zend_language_scanner.l"
                {
        return T_MINUS_EQUAL;
 }
@@ -5251,7 +5251,7 @@ yy487:
                ++YYCURSOR;
                YYDEBUG(488, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1338 "Zend/zend_language_scanner.l"
+#line 1342 "Zend/zend_language_scanner.l"
                {
        return T_DEC;
 }
@@ -5261,7 +5261,7 @@ yy489:
                ++YYCURSOR;
                YYDEBUG(490, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1164 "Zend/zend_language_scanner.l"
+#line 1168 "Zend/zend_language_scanner.l"
                {
        yy_push_state(ST_LOOKING_FOR_PROPERTY TSRMLS_CC);
        return T_OBJECT_OPERATOR;
@@ -5311,7 +5311,7 @@ yy496:
                }
                YYDEBUG(497, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1310 "Zend/zend_language_scanner.l"
+#line 1314 "Zend/zend_language_scanner.l"
                {
        return T_PUBLIC;
 }
@@ -5370,7 +5370,7 @@ yy505:
                }
                YYDEBUG(506, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1306 "Zend/zend_language_scanner.l"
+#line 1310 "Zend/zend_language_scanner.l"
                {
        return T_PROTECTED;
 }
@@ -5404,7 +5404,7 @@ yy511:
                }
                YYDEBUG(512, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1302 "Zend/zend_language_scanner.l"
+#line 1306 "Zend/zend_language_scanner.l"
                {
        return T_PRIVATE;
 }
@@ -5417,7 +5417,7 @@ yy513:
                }
                YYDEBUG(514, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1140 "Zend/zend_language_scanner.l"
+#line 1144 "Zend/zend_language_scanner.l"
                {
        return T_PRINT;
 }
@@ -5446,7 +5446,7 @@ yy518:
                }
                YYDEBUG(519, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1132 "Zend/zend_language_scanner.l"
+#line 1136 "Zend/zend_language_scanner.l"
                {
        return T_GOTO;
 }
@@ -5474,7 +5474,7 @@ yy523:
                }
                YYDEBUG(524, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1274 "Zend/zend_language_scanner.l"
+#line 1278 "Zend/zend_language_scanner.l"
                {
        return T_GLOBAL;
 }
@@ -5515,7 +5515,7 @@ yy531:
                }
                YYDEBUG(532, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1124 "Zend/zend_language_scanner.l"
+#line 1128 "Zend/zend_language_scanner.l"
                {
        return T_BREAK;
 }
@@ -5559,7 +5559,7 @@ yy539:
                }
                YYDEBUG(540, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1108 "Zend/zend_language_scanner.l"
+#line 1112 "Zend/zend_language_scanner.l"
                {
        return T_SWITCH;
 }
@@ -5587,7 +5587,7 @@ yy544:
                }
                YYDEBUG(545, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1290 "Zend/zend_language_scanner.l"
+#line 1294 "Zend/zend_language_scanner.l"
                {
        return T_STATIC;
 }
@@ -5618,7 +5618,7 @@ yy549:
                }
                YYDEBUG(550, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1104 "Zend/zend_language_scanner.l"
+#line 1108 "Zend/zend_language_scanner.l"
                {
        return T_AS;
 }
@@ -5641,7 +5641,7 @@ yy553:
                }
                YYDEBUG(554, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1326 "Zend/zend_language_scanner.l"
+#line 1330 "Zend/zend_language_scanner.l"
                {
        return T_ARRAY;
 }
@@ -5654,7 +5654,7 @@ yy555:
                }
                YYDEBUG(556, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1422 "Zend/zend_language_scanner.l"
+#line 1426 "Zend/zend_language_scanner.l"
                {
        return T_LOGICAL_AND;
 }
@@ -5692,7 +5692,7 @@ yy562:
                }
                YYDEBUG(563, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1294 "Zend/zend_language_scanner.l"
+#line 1298 "Zend/zend_language_scanner.l"
                {
        return T_ABSTRACT;
 }
@@ -5720,7 +5720,7 @@ yy567:
                }
                YYDEBUG(568, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1064 "Zend/zend_language_scanner.l"
+#line 1068 "Zend/zend_language_scanner.l"
                {
        return T_WHILE;
 }
@@ -5733,7 +5733,7 @@ yy569:
                }
                YYDEBUG(570, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1048 "Zend/zend_language_scanner.l"
+#line 1052 "Zend/zend_language_scanner.l"
                {
        return T_IF;
 }
@@ -5789,7 +5789,7 @@ yy576:
                }
                YYDEBUG(577, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1278 "Zend/zend_language_scanner.l"
+#line 1282 "Zend/zend_language_scanner.l"
                {
        return T_ISSET;
 }
@@ -5847,7 +5847,7 @@ yy584:
 yy585:
                YYDEBUG(585, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1246 "Zend/zend_language_scanner.l"
+#line 1250 "Zend/zend_language_scanner.l"
                {
        return T_INCLUDE;
 }
@@ -5880,7 +5880,7 @@ yy590:
                }
                YYDEBUG(591, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1250 "Zend/zend_language_scanner.l"
+#line 1254 "Zend/zend_language_scanner.l"
                {
        return T_INCLUDE_ONCE;
 }
@@ -5918,7 +5918,7 @@ yy597:
                }
                YYDEBUG(598, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1148 "Zend/zend_language_scanner.l"
+#line 1152 "Zend/zend_language_scanner.l"
                {
        return T_INTERFACE;
 }
@@ -5972,7 +5972,7 @@ yy605:
                }
                YYDEBUG(606, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1270 "Zend/zend_language_scanner.l"
+#line 1274 "Zend/zend_language_scanner.l"
                {
         return T_INSTEADOF;
 }
@@ -6005,7 +6005,7 @@ yy611:
                }
                YYDEBUG(612, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1100 "Zend/zend_language_scanner.l"
+#line 1104 "Zend/zend_language_scanner.l"
                {
        return T_INSTANCEOF;
 }
@@ -6053,7 +6053,7 @@ yy620:
                }
                YYDEBUG(621, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1160 "Zend/zend_language_scanner.l"
+#line 1164 "Zend/zend_language_scanner.l"
                {
        return T_IMPLEMENTS;
 }
@@ -6108,7 +6108,7 @@ yy628:
                }
                YYDEBUG(629, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1152 "Zend/zend_language_scanner.l"
+#line 1156 "Zend/zend_language_scanner.l"
                {
        return T_TRAIT;
 }
@@ -6131,7 +6131,7 @@ yy632:
                }
                YYDEBUG(633, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1044 "Zend/zend_language_scanner.l"
+#line 1048 "Zend/zend_language_scanner.l"
                {
        return T_THROW;
 }
@@ -6196,7 +6196,7 @@ yy640:
 yy641:
                YYDEBUG(641, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1254 "Zend/zend_language_scanner.l"
+#line 1258 "Zend/zend_language_scanner.l"
                {
        return T_REQUIRE;
 }
@@ -6229,7 +6229,7 @@ yy646:
                }
                YYDEBUG(647, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1258 "Zend/zend_language_scanner.l"
+#line 1262 "Zend/zend_language_scanner.l"
                {
        return T_REQUIRE_ONCE;
 }
@@ -6346,7 +6346,7 @@ yy661:
                }
                YYDEBUG(662, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1128 "Zend/zend_language_scanner.l"
+#line 1132 "Zend/zend_language_scanner.l"
                {
        return T_CONTINUE;
 }
@@ -6388,7 +6388,7 @@ yy668:
                }
                YYDEBUG(669, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1206 "Zend/zend_language_scanner.l"
+#line 1210 "Zend/zend_language_scanner.l"
                {
        return T_CLONE;
 }
@@ -6406,7 +6406,7 @@ yy671:
                }
                YYDEBUG(672, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1144 "Zend/zend_language_scanner.l"
+#line 1148 "Zend/zend_language_scanner.l"
                {
        return T_CLASS;
 }
@@ -6456,7 +6456,7 @@ yy680:
                }
                YYDEBUG(681, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1330 "Zend/zend_language_scanner.l"
+#line 1334 "Zend/zend_language_scanner.l"
                {
  return T_CALLABLE;
 }
@@ -6469,7 +6469,7 @@ yy682:
                }
                YYDEBUG(683, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1116 "Zend/zend_language_scanner.l"
+#line 1120 "Zend/zend_language_scanner.l"
                {
        return T_CASE;
 }
@@ -6570,7 +6570,7 @@ yy697:
 yy698:
                YYDEBUG(698, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1076 "Zend/zend_language_scanner.l"
+#line 1080 "Zend/zend_language_scanner.l"
                {
        return T_FOR;
 }
@@ -6598,7 +6598,7 @@ yy702:
                }
                YYDEBUG(703, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1084 "Zend/zend_language_scanner.l"
+#line 1088 "Zend/zend_language_scanner.l"
                {
        return T_FOREACH;
 }
@@ -6616,557 +6616,590 @@ yy705:
 yy706:
                YYDEBUG(706, *YYCURSOR);
                ++YYCURSOR;
-               if (yybm[0+(yych = *YYCURSOR)] & 4) {
-                       goto yy185;
+               if ((yych = *YYCURSOR) <= '^') {
+                       if (yych <= '@') {
+                               if (yych <= '/') goto yy707;
+                               if (yych <= '9') goto yy185;
+                       } else {
+                               if (yych == 'L') goto yy708;
+                               if (yych <= 'Z') goto yy185;
+                       }
+               } else {
+                       if (yych <= 'k') {
+                               if (yych != '`') goto yy185;
+                       } else {
+                               if (yych <= 'l') goto yy708;
+                               if (yych <= 'z') goto yy185;
+                               if (yych >= 0x7F) goto yy185;
+                       }
                }
+yy707:
                YYDEBUG(707, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1298 "Zend/zend_language_scanner.l"
+#line 1302 "Zend/zend_language_scanner.l"
                {
        return T_FINAL;
 }
-#line 6629 "Zend/zend_language_scanner.c"
+#line 6644 "Zend/zend_language_scanner.c"
 yy708:
                YYDEBUG(708, *YYCURSOR);
                yych = *++YYCURSOR;
+               if (yych == 'Y') goto yy709;
+               if (yych != 'y') goto yy186;
+yy709:
+               YYDEBUG(709, *YYCURSOR);
+               ++YYCURSOR;
+               if (yybm[0+(yych = *YYCURSOR)] & 4) {
+                       goto yy185;
+               }
+               YYDEBUG(710, *YYCURSOR);
+               yyleng = YYCURSOR - SCNG(yy_text);
+#line 1044 "Zend/zend_language_scanner.l"
+               {
+       return T_FINALLY;
+}
+#line 6662 "Zend/zend_language_scanner.c"
+yy711:
+               YYDEBUG(711, *YYCURSOR);
+               yych = *++YYCURSOR;
                if (yych <= 'F') {
-                       if (yych == 'C') goto yy714;
+                       if (yych == 'C') goto yy717;
                        if (yych <= 'E') goto yy186;
-                       goto yy715;
+                       goto yy718;
                } else {
                        if (yych <= 'c') {
                                if (yych <= 'b') goto yy186;
-                               goto yy714;
+                               goto yy717;
                        } else {
-                               if (yych == 'f') goto yy715;
+                               if (yych == 'f') goto yy718;
                                goto yy186;
                        }
                }
-yy709:
-               YYDEBUG(709, *YYCURSOR);
+yy712:
+               YYDEBUG(712, *YYCURSOR);
                yych = *++YYCURSOR;
-               if (yych == 'E') goto yy712;
-               if (yych == 'e') goto yy712;
+               if (yych == 'E') goto yy715;
+               if (yych == 'e') goto yy715;
                goto yy186;
-yy710:
-               YYDEBUG(710, *YYCURSOR);
+yy713:
+               YYDEBUG(713, *YYCURSOR);
                ++YYCURSOR;
                if (yybm[0+(yych = *YYCURSOR)] & 4) {
                        goto yy185;
                }
-               YYDEBUG(711, *YYCURSOR);
+               YYDEBUG(714, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1072 "Zend/zend_language_scanner.l"
+#line 1076 "Zend/zend_language_scanner.l"
                {
        return T_DO;
 }
-#line 6664 "Zend/zend_language_scanner.c"
-yy712:
-               YYDEBUG(712, *YYCURSOR);
+#line 6697 "Zend/zend_language_scanner.c"
+yy715:
+               YYDEBUG(715, *YYCURSOR);
                ++YYCURSOR;
                if (yybm[0+(yych = *YYCURSOR)] & 4) {
                        goto yy185;
                }
-               YYDEBUG(713, *YYCURSOR);
+               YYDEBUG(716, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
 #line 1020 "Zend/zend_language_scanner.l"
                {
        return T_EXIT;
 }
-#line 6677 "Zend/zend_language_scanner.c"
-yy714:
-               YYDEBUG(714, *YYCURSOR);
+#line 6710 "Zend/zend_language_scanner.c"
+yy717:
+               YYDEBUG(717, *YYCURSOR);
                yych = *++YYCURSOR;
-               if (yych == 'L') goto yy721;
-               if (yych == 'l') goto yy721;
+               if (yych == 'L') goto yy724;
+               if (yych == 'l') goto yy724;
                goto yy186;
-yy715:
-               YYDEBUG(715, *YYCURSOR);
+yy718:
+               YYDEBUG(718, *YYCURSOR);
                yych = *++YYCURSOR;
-               if (yych == 'A') goto yy716;
+               if (yych == 'A') goto yy719;
                if (yych != 'a') goto yy186;
-yy716:
-               YYDEBUG(716, *YYCURSOR);
+yy719:
+               YYDEBUG(719, *YYCURSOR);
                yych = *++YYCURSOR;
-               if (yych == 'U') goto yy717;
+               if (yych == 'U') goto yy720;
                if (yych != 'u') goto yy186;
-yy717:
-               YYDEBUG(717, *YYCURSOR);
+yy720:
+               YYDEBUG(720, *YYCURSOR);
                yych = *++YYCURSOR;
-               if (yych == 'L') goto yy718;
+               if (yych == 'L') goto yy721;
                if (yych != 'l') goto yy186;
-yy718:
-               YYDEBUG(718, *YYCURSOR);
+yy721:
+               YYDEBUG(721, *YYCURSOR);
                yych = *++YYCURSOR;
-               if (yych == 'T') goto yy719;
+               if (yych == 'T') goto yy722;
                if (yych != 't') goto yy186;
-yy719:
-               YYDEBUG(719, *YYCURSOR);
+yy722:
+               YYDEBUG(722, *YYCURSOR);
                ++YYCURSOR;
                if (yybm[0+(yych = *YYCURSOR)] & 4) {
                        goto yy185;
                }
-               YYDEBUG(720, *YYCURSOR);
+               YYDEBUG(723, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1120 "Zend/zend_language_scanner.l"
+#line 1124 "Zend/zend_language_scanner.l"
                {
        return T_DEFAULT;
 }
-#line 6716 "Zend/zend_language_scanner.c"
-yy721:
-               YYDEBUG(721, *YYCURSOR);
+#line 6749 "Zend/zend_language_scanner.c"
+yy724:
+               YYDEBUG(724, *YYCURSOR);
                yych = *++YYCURSOR;
-               if (yych == 'A') goto yy722;
+               if (yych == 'A') goto yy725;
                if (yych != 'a') goto yy186;
-yy722:
-               YYDEBUG(722, *YYCURSOR);
+yy725:
+               YYDEBUG(725, *YYCURSOR);
                yych = *++YYCURSOR;
-               if (yych == 'R') goto yy723;
+               if (yych == 'R') goto yy726;
                if (yych != 'r') goto yy186;
-yy723:
-               YYDEBUG(723, *YYCURSOR);
+yy726:
+               YYDEBUG(726, *YYCURSOR);
                yych = *++YYCURSOR;
-               if (yych == 'E') goto yy724;
+               if (yych == 'E') goto yy727;
                if (yych != 'e') goto yy186;
-yy724:
-               YYDEBUG(724, *YYCURSOR);
+yy727:
+               YYDEBUG(727, *YYCURSOR);
                ++YYCURSOR;
                if (yybm[0+(yych = *YYCURSOR)] & 4) {
                        goto yy185;
                }
-               YYDEBUG(725, *YYCURSOR);
+               YYDEBUG(728, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1092 "Zend/zend_language_scanner.l"
+#line 1096 "Zend/zend_language_scanner.l"
                {
        return T_DECLARE;
 }
-#line 6744 "Zend/zend_language_scanner.c"
-yy726:
-               YYDEBUG(726, *YYCURSOR);
-               yych = *++YYCURSOR;
-               if (yych == 'H') goto yy788;
-               if (yych == 'h') goto yy788;
-               goto yy186;
-yy727:
-               YYDEBUG(727, *YYCURSOR);
-               yych = *++YYCURSOR;
-               if (yych == 'S') goto yy782;
-               if (yych == 's') goto yy782;
-               goto yy186;
-yy728:
-               YYDEBUG(728, *YYCURSOR);
-               yych = *++YYCURSOR;
-               if (yych == 'P') goto yy778;
-               if (yych == 'p') goto yy778;
-               goto yy186;
+#line 6777 "Zend/zend_language_scanner.c"
 yy729:
                YYDEBUG(729, *YYCURSOR);
                yych = *++YYCURSOR;
-               if (yych == 'D') goto yy744;
-               if (yych == 'd') goto yy744;
+               if (yych == 'H') goto yy791;
+               if (yych == 'h') goto yy791;
                goto yy186;
 yy730:
                YYDEBUG(730, *YYCURSOR);
                yych = *++YYCURSOR;
-               if (yych == 'A') goto yy741;
-               if (yych == 'a') goto yy741;
+               if (yych == 'S') goto yy785;
+               if (yych == 's') goto yy785;
                goto yy186;
 yy731:
                YYDEBUG(731, *YYCURSOR);
                yych = *++YYCURSOR;
-               if (yych <= 'T') {
-                       if (yych == 'I') goto yy732;
-                       if (yych <= 'S') goto yy186;
-                       goto yy733;
-               } else {
-                       if (yych <= 'i') {
-                               if (yych <= 'h') goto yy186;
-                       } else {
-                               if (yych == 't') goto yy733;
-                               goto yy186;
-                       }
-               }
+               if (yych == 'P') goto yy781;
+               if (yych == 'p') goto yy781;
+               goto yy186;
 yy732:
                YYDEBUG(732, *YYCURSOR);
                yych = *++YYCURSOR;
-               if (yych == 'T') goto yy739;
-               if (yych == 't') goto yy739;
+               if (yych == 'D') goto yy747;
+               if (yych == 'd') goto yy747;
                goto yy186;
 yy733:
                YYDEBUG(733, *YYCURSOR);
                yych = *++YYCURSOR;
-               if (yych == 'E') goto yy734;
-               if (yych != 'e') goto yy186;
+               if (yych == 'A') goto yy744;
+               if (yych == 'a') goto yy744;
+               goto yy186;
 yy734:
                YYDEBUG(734, *YYCURSOR);
                yych = *++YYCURSOR;
-               if (yych == 'N') goto yy735;
-               if (yych != 'n') goto yy186;
+               if (yych <= 'T') {
+                       if (yych == 'I') goto yy735;
+                       if (yych <= 'S') goto yy186;
+                       goto yy736;
+               } else {
+                       if (yych <= 'i') {
+                               if (yych <= 'h') goto yy186;
+                       } else {
+                               if (yych == 't') goto yy736;
+                               goto yy186;
+                       }
+               }
 yy735:
                YYDEBUG(735, *YYCURSOR);
                yych = *++YYCURSOR;
-               if (yych == 'D') goto yy736;
-               if (yych != 'd') goto yy186;
+               if (yych == 'T') goto yy742;
+               if (yych == 't') goto yy742;
+               goto yy186;
 yy736:
                YYDEBUG(736, *YYCURSOR);
                yych = *++YYCURSOR;
-               if (yych == 'S') goto yy737;
-               if (yych != 's') goto yy186;
+               if (yych == 'E') goto yy737;
+               if (yych != 'e') goto yy186;
 yy737:
                YYDEBUG(737, *YYCURSOR);
+               yych = *++YYCURSOR;
+               if (yych == 'N') goto yy738;
+               if (yych != 'n') goto yy186;
+yy738:
+               YYDEBUG(738, *YYCURSOR);
+               yych = *++YYCURSOR;
+               if (yych == 'D') goto yy739;
+               if (yych != 'd') goto yy186;
+yy739:
+               YYDEBUG(739, *YYCURSOR);
+               yych = *++YYCURSOR;
+               if (yych == 'S') goto yy740;
+               if (yych != 's') goto yy186;
+yy740:
+               YYDEBUG(740, *YYCURSOR);
                ++YYCURSOR;
                if (yybm[0+(yych = *YYCURSOR)] & 4) {
                        goto yy185;
                }
-               YYDEBUG(738, *YYCURSOR);
+               YYDEBUG(741, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1156 "Zend/zend_language_scanner.l"
+#line 1160 "Zend/zend_language_scanner.l"
                {
        return T_EXTENDS;
 }
-#line 6828 "Zend/zend_language_scanner.c"
-yy739:
-               YYDEBUG(739, *YYCURSOR);
+#line 6861 "Zend/zend_language_scanner.c"
+yy742:
+               YYDEBUG(742, *YYCURSOR);
                ++YYCURSOR;
                if (yybm[0+(yych = *YYCURSOR)] & 4) {
                        goto yy185;
                }
-               YYDEBUG(740, *YYCURSOR);
+               YYDEBUG(743, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
 #line 1016 "Zend/zend_language_scanner.l"
                {
        return T_EXIT;
 }
-#line 6841 "Zend/zend_language_scanner.c"
-yy741:
-               YYDEBUG(741, *YYCURSOR);
+#line 6874 "Zend/zend_language_scanner.c"
+yy744:
+               YYDEBUG(744, *YYCURSOR);
                yych = *++YYCURSOR;
-               if (yych == 'L') goto yy742;
+               if (yych == 'L') goto yy745;
                if (yych != 'l') goto yy186;
-yy742:
-               YYDEBUG(742, *YYCURSOR);
+yy745:
+               YYDEBUG(745, *YYCURSOR);
                ++YYCURSOR;
                if (yybm[0+(yych = *YYCURSOR)] & 4) {
                        goto yy185;
                }
-               YYDEBUG(743, *YYCURSOR);
+               YYDEBUG(746, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1242 "Zend/zend_language_scanner.l"
+#line 1246 "Zend/zend_language_scanner.l"
                {
        return T_EVAL;
 }
-#line 6859 "Zend/zend_language_scanner.c"
-yy744:
-               YYDEBUG(744, *YYCURSOR);
+#line 6892 "Zend/zend_language_scanner.c"
+yy747:
+               YYDEBUG(747, *YYCURSOR);
                yych = *++YYCURSOR;
                YYDEBUG(-1, yych);
                switch (yych) {
                case 'D':
-               case 'd':       goto yy745;
+               case 'd':       goto yy748;
                case 'F':
-               case 'f':       goto yy746;
+               case 'f':       goto yy749;
                case 'I':
-               case 'i':       goto yy747;
+               case 'i':       goto yy750;
                case 'S':
-               case 's':       goto yy748;
+               case 's':       goto yy751;
                case 'W':
-               case 'w':       goto yy749;
+               case 'w':       goto yy752;
                default:        goto yy186;
                }
-yy745:
-               YYDEBUG(745, *YYCURSOR);
-               yych = *++YYCURSOR;
-               if (yych == 'E') goto yy771;
-               if (yych == 'e') goto yy771;
-               goto yy186;
-yy746:
-               YYDEBUG(746, *YYCURSOR);
-               yych = *++YYCURSOR;
-               if (yych == 'O') goto yy763;
-               if (yych == 'o') goto yy763;
-               goto yy186;
-yy747:
-               YYDEBUG(747, *YYCURSOR);
-               yych = *++YYCURSOR;
-               if (yych == 'F') goto yy761;
-               if (yych == 'f') goto yy761;
-               goto yy186;
 yy748:
                YYDEBUG(748, *YYCURSOR);
                yych = *++YYCURSOR;
-               if (yych == 'W') goto yy755;
-               if (yych == 'w') goto yy755;
+               if (yych == 'E') goto yy774;
+               if (yych == 'e') goto yy774;
                goto yy186;
 yy749:
                YYDEBUG(749, *YYCURSOR);
                yych = *++YYCURSOR;
-               if (yych == 'H') goto yy750;
-               if (yych != 'h') goto yy186;
+               if (yych == 'O') goto yy766;
+               if (yych == 'o') goto yy766;
+               goto yy186;
 yy750:
                YYDEBUG(750, *YYCURSOR);
                yych = *++YYCURSOR;
-               if (yych == 'I') goto yy751;
-               if (yych != 'i') goto yy186;
+               if (yych == 'F') goto yy764;
+               if (yych == 'f') goto yy764;
+               goto yy186;
 yy751:
                YYDEBUG(751, *YYCURSOR);
                yych = *++YYCURSOR;
-               if (yych == 'L') goto yy752;
-               if (yych != 'l') goto yy186;
+               if (yych == 'W') goto yy758;
+               if (yych == 'w') goto yy758;
+               goto yy186;
 yy752:
                YYDEBUG(752, *YYCURSOR);
                yych = *++YYCURSOR;
-               if (yych == 'E') goto yy753;
-               if (yych != 'e') goto yy186;
+               if (yych == 'H') goto yy753;
+               if (yych != 'h') goto yy186;
 yy753:
                YYDEBUG(753, *YYCURSOR);
+               yych = *++YYCURSOR;
+               if (yych == 'I') goto yy754;
+               if (yych != 'i') goto yy186;
+yy754:
+               YYDEBUG(754, *YYCURSOR);
+               yych = *++YYCURSOR;
+               if (yych == 'L') goto yy755;
+               if (yych != 'l') goto yy186;
+yy755:
+               YYDEBUG(755, *YYCURSOR);
+               yych = *++YYCURSOR;
+               if (yych == 'E') goto yy756;
+               if (yych != 'e') goto yy186;
+yy756:
+               YYDEBUG(756, *YYCURSOR);
                ++YYCURSOR;
                if (yybm[0+(yych = *YYCURSOR)] & 4) {
                        goto yy185;
                }
-               YYDEBUG(754, *YYCURSOR);
+               YYDEBUG(757, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1068 "Zend/zend_language_scanner.l"
+#line 1072 "Zend/zend_language_scanner.l"
                {
        return T_ENDWHILE;
 }
-#line 6933 "Zend/zend_language_scanner.c"
-yy755:
-               YYDEBUG(755, *YYCURSOR);
+#line 6966 "Zend/zend_language_scanner.c"
+yy758:
+               YYDEBUG(758, *YYCURSOR);
                yych = *++YYCURSOR;
-               if (yych == 'I') goto yy756;
+               if (yych == 'I') goto yy759;
                if (yych != 'i') goto yy186;
-yy756:
-               YYDEBUG(756, *YYCURSOR);
+yy759:
+               YYDEBUG(759, *YYCURSOR);
                yych = *++YYCURSOR;
-               if (yych == 'T') goto yy757;
+               if (yych == 'T') goto yy760;
                if (yych != 't') goto yy186;
-yy757:
-               YYDEBUG(757, *YYCURSOR);
+yy760:
+               YYDEBUG(760, *YYCURSOR);
                yych = *++YYCURSOR;
-               if (yych == 'C') goto yy758;
+               if (yych == 'C') goto yy761;
                if (yych != 'c') goto yy186;
-yy758:
-               YYDEBUG(758, *YYCURSOR);
+yy761:
+               YYDEBUG(761, *YYCURSOR);
                yych = *++YYCURSOR;
-               if (yych == 'H') goto yy759;
+               if (yych == 'H') goto yy762;
                if (yych != 'h') goto yy186;
-yy759:
-               YYDEBUG(759, *YYCURSOR);
+yy762:
+               YYDEBUG(762, *YYCURSOR);
                ++YYCURSOR;
                if (yybm[0+(yych = *YYCURSOR)] & 4) {
                        goto yy185;
                }
-               YYDEBUG(760, *YYCURSOR);
+               YYDEBUG(763, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1112 "Zend/zend_language_scanner.l"
+#line 1116 "Zend/zend_language_scanner.l"
                {
        return T_ENDSWITCH;
 }
-#line 6966 "Zend/zend_language_scanner.c"
-yy761:
-               YYDEBUG(761, *YYCURSOR);
+#line 6999 "Zend/zend_language_scanner.c"
+yy764:
+               YYDEBUG(764, *YYCURSOR);
                ++YYCURSOR;
                if (yybm[0+(yych = *YYCURSOR)] & 4) {
                        goto yy185;
                }
-               YYDEBUG(762, *YYCURSOR);
+               YYDEBUG(765, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1056 "Zend/zend_language_scanner.l"
+#line 1060 "Zend/zend_language_scanner.l"
                {
        return T_ENDIF;
 }
-#line 6979 "Zend/zend_language_scanner.c"
-yy763:
-               YYDEBUG(763, *YYCURSOR);
+#line 7012 "Zend/zend_language_scanner.c"
+yy766:
+               YYDEBUG(766, *YYCURSOR);
                yych = *++YYCURSOR;
-               if (yych == 'R') goto yy764;
+               if (yych == 'R') goto yy767;
                if (yych != 'r') goto yy186;
-yy764:
-               YYDEBUG(764, *YYCURSOR);
+yy767:
+               YYDEBUG(767, *YYCURSOR);
                ++YYCURSOR;
                if ((yych = *YYCURSOR) <= '^') {
                        if (yych <= '@') {
-                               if (yych <= '/') goto yy765;
+                               if (yych <= '/') goto yy768;
                                if (yych <= '9') goto yy185;
                        } else {
-                               if (yych == 'E') goto yy766;
+                               if (yych == 'E') goto yy769;
                                if (yych <= 'Z') goto yy185;
                        }
                } else {
                        if (yych <= 'd') {
                                if (yych != '`') goto yy185;
                        } else {
-                               if (yych <= 'e') goto yy766;
+                               if (yych <= 'e') goto yy769;
                                if (yych <= 'z') goto yy185;
                                if (yych >= 0x7F) goto yy185;
                        }
                }
-yy765:
-               YYDEBUG(765, *YYCURSOR);
+yy768:
+               YYDEBUG(768, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1080 "Zend/zend_language_scanner.l"
+#line 1084 "Zend/zend_language_scanner.l"
                {
        return T_ENDFOR;
 }
-#line 7012 "Zend/zend_language_scanner.c"
-yy766:
-               YYDEBUG(766, *YYCURSOR);
+#line 7045 "Zend/zend_language_scanner.c"
+yy769:
+               YYDEBUG(769, *YYCURSOR);
                yych = *++YYCURSOR;
-               if (yych == 'A') goto yy767;
+               if (yych == 'A') goto yy770;
                if (yych != 'a') goto yy186;
-yy767:
-               YYDEBUG(767, *YYCURSOR);
+yy770:
+               YYDEBUG(770, *YYCURSOR);
                yych = *++YYCURSOR;
-               if (yych == 'C') goto yy768;
+               if (yych == 'C') goto yy771;
                if (yych != 'c') goto yy186;
-yy768:
-               YYDEBUG(768, *YYCURSOR);
+yy771:
+               YYDEBUG(771, *YYCURSOR);
                yych = *++YYCURSOR;
-               if (yych == 'H') goto yy769;
+               if (yych == 'H') goto yy772;
                if (yych != 'h') goto yy186;
-yy769:
-               YYDEBUG(769, *YYCURSOR);
+yy772:
+               YYDEBUG(772, *YYCURSOR);
                ++YYCURSOR;
                if (yybm[0+(yych = *YYCURSOR)] & 4) {
                        goto yy185;
                }
-               YYDEBUG(770, *YYCURSOR);
+               YYDEBUG(773, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1088 "Zend/zend_language_scanner.l"
+#line 1092 "Zend/zend_language_scanner.l"
                {
        return T_ENDFOREACH;
 }
-#line 7040 "Zend/zend_language_scanner.c"
-yy771:
-               YYDEBUG(771, *YYCURSOR);
+#line 7073 "Zend/zend_language_scanner.c"
+yy774:
+               YYDEBUG(774, *YYCURSOR);
                yych = *++YYCURSOR;
-               if (yych == 'C') goto yy772;
+               if (yych == 'C') goto yy775;
                if (yych != 'c') goto yy186;
-yy772:
-               YYDEBUG(772, *YYCURSOR);
+yy775:
+               YYDEBUG(775, *YYCURSOR);
                yych = *++YYCURSOR;
-               if (yych == 'L') goto yy773;
+               if (yych == 'L') goto yy776;
                if (yych != 'l') goto yy186;
-yy773:
-               YYDEBUG(773, *YYCURSOR);
+yy776:
+               YYDEBUG(776, *YYCURSOR);
                yych = *++YYCURSOR;
-               if (yych == 'A') goto yy774;
+               if (yych == 'A') goto yy777;
                if (yych != 'a') goto yy186;
-yy774:
-               YYDEBUG(774, *YYCURSOR);
+yy777:
+               YYDEBUG(777, *YYCURSOR);
                yych = *++YYCURSOR;
-               if (yych == 'R') goto yy775;
+               if (yych == 'R') goto yy778;
                if (yych != 'r') goto yy186;
-yy775:
-               YYDEBUG(775, *YYCURSOR);
+yy778:
+               YYDEBUG(778, *YYCURSOR);
                yych = *++YYCURSOR;
-               if (yych == 'E') goto yy776;
+               if (yych == 'E') goto yy779;
                if (yych != 'e') goto yy186;
-yy776:
-               YYDEBUG(776, *YYCURSOR);
+yy779:
+               YYDEBUG(779, *YYCURSOR);
                ++YYCURSOR;
                if (yybm[0+(yych = *YYCURSOR)] & 4) {
                        goto yy185;
                }
-               YYDEBUG(777, *YYCURSOR);
+               YYDEBUG(780, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1096 "Zend/zend_language_scanner.l"
+#line 1100 "Zend/zend_language_scanner.l"
                {
        return T_ENDDECLARE;
 }
-#line 7078 "Zend/zend_language_scanner.c"
-yy778:
-               YYDEBUG(778, *YYCURSOR);
+#line 7111 "Zend/zend_language_scanner.c"
+yy781:
+               YYDEBUG(781, *YYCURSOR);
                yych = *++YYCURSOR;
-               if (yych == 'T') goto yy779;
+               if (yych == 'T') goto yy782;
                if (yych != 't') goto yy186;
-yy779:
-               YYDEBUG(779, *YYCURSOR);
+yy782:
+               YYDEBUG(782, *YYCURSOR);
                yych = *++YYCURSOR;
-               if (yych == 'Y') goto yy780;
+               if (yych == 'Y') goto yy783;
                if (yych != 'y') goto yy186;
-yy780:
-               YYDEBUG(780, *YYCURSOR);
+yy783:
+               YYDEBUG(783, *YYCURSOR);
                ++YYCURSOR;
                if (yybm[0+(yych = *YYCURSOR)] & 4) {
                        goto yy185;
                }
-               YYDEBUG(781, *YYCURSOR);
+               YYDEBUG(784, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1282 "Zend/zend_language_scanner.l"
+#line 1286 "Zend/zend_language_scanner.l"
                {
        return T_EMPTY;
 }
-#line 7101 "Zend/zend_language_scanner.c"
-yy782:
-               YYDEBUG(782, *YYCURSOR);
+#line 7134 "Zend/zend_language_scanner.c"
+yy785:
+               YYDEBUG(785, *YYCURSOR);
                yych = *++YYCURSOR;
-               if (yych == 'E') goto yy783;
+               if (yych == 'E') goto yy786;
                if (yych != 'e') goto yy186;
-yy783:
-               YYDEBUG(783, *YYCURSOR);
+yy786:
+               YYDEBUG(786, *YYCURSOR);
                ++YYCURSOR;
                if ((yych = *YYCURSOR) <= '^') {
                        if (yych <= '@') {
-                               if (yych <= '/') goto yy784;
+                               if (yych <= '/') goto yy787;
                                if (yych <= '9') goto yy185;
                        } else {
-                               if (yych == 'I') goto yy785;
+                               if (yych == 'I') goto yy788;
                                if (yych <= 'Z') goto yy185;
                        }
                } else {
                        if (yych <= 'h') {
                                if (yych != '`') goto yy185;
                        } else {
-                               if (yych <= 'i') goto yy785;
+                               if (yych <= 'i') goto yy788;
                                if (yych <= 'z') goto yy185;
                                if (yych >= 0x7F) goto yy185;
                        }
                }
-yy784:
-               YYDEBUG(784, *YYCURSOR);
+yy787:
+               YYDEBUG(787, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1060 "Zend/zend_language_scanner.l"
+#line 1064 "Zend/zend_language_scanner.l"
                {
        return T_ELSE;
 }
-#line 7134 "Zend/zend_language_scanner.c"
-yy785:
-               YYDEBUG(785, *YYCURSOR);
+#line 7167 "Zend/zend_language_scanner.c"
+yy788:
+               YYDEBUG(788, *YYCURSOR);
                yych = *++YYCURSOR;
-               if (yych == 'F') goto yy786;
+               if (yych == 'F') goto yy789;
                if (yych != 'f') goto yy186;
-yy786:
-               YYDEBUG(786, *YYCURSOR);
+yy789:
+               YYDEBUG(789, *YYCURSOR);
                ++YYCURSOR;
                if (yybm[0+(yych = *YYCURSOR)] & 4) {
                        goto yy185;
                }
-               YYDEBUG(787, *YYCURSOR);
+               YYDEBUG(790, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1052 "Zend/zend_language_scanner.l"
+#line 1056 "Zend/zend_language_scanner.l"
                {
        return T_ELSEIF;
 }
-#line 7152 "Zend/zend_language_scanner.c"
-yy788:
-               YYDEBUG(788, *YYCURSOR);
+#line 7185 "Zend/zend_language_scanner.c"
+yy791:
+               YYDEBUG(791, *YYCURSOR);
                yych = *++YYCURSOR;
-               if (yych == 'O') goto yy789;
+               if (yych == 'O') goto yy792;
                if (yych != 'o') goto yy186;
-yy789:
-               YYDEBUG(789, *YYCURSOR);
+yy792:
+               YYDEBUG(792, *YYCURSOR);
                ++YYCURSOR;
                if (yybm[0+(yych = *YYCURSOR)] & 4) {
                        goto yy185;
                }
-               YYDEBUG(790, *YYCURSOR);
+               YYDEBUG(793, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1136 "Zend/zend_language_scanner.l"
+#line 1140 "Zend/zend_language_scanner.l"
                {
        return T_ECHO;
 }
-#line 7170 "Zend/zend_language_scanner.c"
+#line 7203 "Zend/zend_language_scanner.c"
        }
 /* *********************************** */
 yyc_ST_LOOKING_FOR_PROPERTY:
@@ -7205,41 +7238,41 @@ yyc_ST_LOOKING_FOR_PROPERTY:
                         64,  64,  64,  64,  64,  64,  64,  64, 
                         64,  64,  64,  64,  64,  64,  64,  64, 
                };
-               YYDEBUG(791, *YYCURSOR);
+               YYDEBUG(794, *YYCURSOR);
                YYFILL(2);
                yych = *YYCURSOR;
                if (yych <= '-') {
                        if (yych <= '\r') {
-                               if (yych <= 0x08) goto yy799;
-                               if (yych <= '\n') goto yy793;
-                               if (yych <= '\f') goto yy799;
+                               if (yych <= 0x08) goto yy802;
+                               if (yych <= '\n') goto yy796;
+                               if (yych <= '\f') goto yy802;
                        } else {
-                               if (yych == ' ') goto yy793;
-                               if (yych <= ',') goto yy799;
-                               goto yy795;
+                               if (yych == ' ') goto yy796;
+                               if (yych <= ',') goto yy802;
+                               goto yy798;
                        }
                } else {
                        if (yych <= '_') {
-                               if (yych <= '@') goto yy799;
-                               if (yych <= 'Z') goto yy797;
-                               if (yych <= '^') goto yy799;
-                               goto yy797;
+                               if (yych <= '@') goto yy802;
+                               if (yych <= 'Z') goto yy800;
+                               if (yych <= '^') goto yy802;
+                               goto yy800;
                        } else {
-                               if (yych <= '`') goto yy799;
-                               if (yych <= 'z') goto yy797;
-                               if (yych <= '~') goto yy799;
-                               goto yy797;
+                               if (yych <= '`') goto yy802;
+                               if (yych <= 'z') goto yy800;
+                               if (yych <= '~') goto yy802;
+                               goto yy800;
                        }
                }
-yy793:
-               YYDEBUG(793, *YYCURSOR);
+yy796:
+               YYDEBUG(796, *YYCURSOR);
                ++YYCURSOR;
                yych = *YYCURSOR;
-               goto yy805;
-yy794:
-               YYDEBUG(794, *YYCURSOR);
+               goto yy808;
+yy797:
+               YYDEBUG(797, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1169 "Zend/zend_language_scanner.l"
+#line 1173 "Zend/zend_language_scanner.l"
                {
        zendlval->value.str.val = yytext; /* no copying - intentional */
        zendlval->value.str.len = yyleng;
@@ -7247,73 +7280,73 @@ yy794:
        HANDLE_NEWLINES(yytext, yyleng);
        return T_WHITESPACE;
 }
-#line 7251 "Zend/zend_language_scanner.c"
-yy795:
-               YYDEBUG(795, *YYCURSOR);
+#line 7284 "Zend/zend_language_scanner.c"
+yy798:
+               YYDEBUG(798, *YYCURSOR);
                ++YYCURSOR;
-               if ((yych = *YYCURSOR) == '>') goto yy802;
-yy796:
-               YYDEBUG(796, *YYCURSOR);
+               if ((yych = *YYCURSOR) == '>') goto yy805;
+yy799:
+               YYDEBUG(799, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1188 "Zend/zend_language_scanner.l"
+#line 1192 "Zend/zend_language_scanner.l"
                {
        yyless(0);
        yy_pop_state(TSRMLS_C);
        goto restart;
 }
-#line 7265 "Zend/zend_language_scanner.c"
-yy797:
-               YYDEBUG(797, *YYCURSOR);
+#line 7298 "Zend/zend_language_scanner.c"
+yy800:
+               YYDEBUG(800, *YYCURSOR);
                ++YYCURSOR;
                yych = *YYCURSOR;
-               goto yy801;
-yy798:
-               YYDEBUG(798, *YYCURSOR);
+               goto yy804;
+yy801:
+               YYDEBUG(801, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1181 "Zend/zend_language_scanner.l"
+#line 1185 "Zend/zend_language_scanner.l"
                {
        yy_pop_state(TSRMLS_C);
        zend_copy_value(zendlval, yytext, yyleng);
        zendlval->type = IS_STRING;
        return T_STRING;
 }
-#line 7281 "Zend/zend_language_scanner.c"
-yy799:
-               YYDEBUG(799, *YYCURSOR);
+#line 7314 "Zend/zend_language_scanner.c"
+yy802:
+               YYDEBUG(802, *YYCURSOR);
                yych = *++YYCURSOR;
-               goto yy796;
-yy800:
-               YYDEBUG(800, *YYCURSOR);
+               goto yy799;
+yy803:
+               YYDEBUG(803, *YYCURSOR);
                ++YYCURSOR;
                YYFILL(1);
                yych = *YYCURSOR;
-yy801:
-               YYDEBUG(801, *YYCURSOR);
+yy804:
+               YYDEBUG(804, *YYCURSOR);
                if (yybm[0+yych] & 64) {
-                       goto yy800;
+                       goto yy803;
                }
-               goto yy798;
-yy802:
-               YYDEBUG(802, *YYCURSOR);
+               goto yy801;
+yy805:
+               YYDEBUG(805, *YYCURSOR);
                ++YYCURSOR;
-               YYDEBUG(803, *YYCURSOR);
+               YYDEBUG(806, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1177 "Zend/zend_language_scanner.l"
+#line 1181 "Zend/zend_language_scanner.l"
                {
        return T_OBJECT_OPERATOR;
 }
-#line 7306 "Zend/zend_language_scanner.c"
-yy804:
-               YYDEBUG(804, *YYCURSOR);
+#line 7339 "Zend/zend_language_scanner.c"
+yy807:
+               YYDEBUG(807, *YYCURSOR);
                ++YYCURSOR;
                YYFILL(1);
                yych = *YYCURSOR;
-yy805:
-               YYDEBUG(805, *YYCURSOR);
+yy808:
+               YYDEBUG(808, *YYCURSOR);
                if (yybm[0+yych] & 128) {
-                       goto yy804;
+                       goto yy807;
                }
-               goto yy794;
+               goto yy797;
        }
 /* *********************************** */
 yyc_ST_LOOKING_FOR_VARNAME:
@@ -7352,74 +7385,74 @@ yyc_ST_LOOKING_FOR_VARNAME:
                        128, 128, 128, 128, 128, 128, 128, 128, 
                        128, 128, 128, 128, 128, 128, 128, 128, 
                };
-               YYDEBUG(806, *YYCURSOR);
+               YYDEBUG(809, *YYCURSOR);
                YYFILL(2);
                yych = *YYCURSOR;
                if (yych <= '_') {
-                       if (yych <= '@') goto yy810;
-                       if (yych <= 'Z') goto yy808;
-                       if (yych <= '^') goto yy810;
+                       if (yych <= '@') goto yy813;
+                       if (yych <= 'Z') goto yy811;
+                       if (yych <= '^') goto yy813;
                } else {
-                       if (yych <= '`') goto yy810;
-                       if (yych <= 'z') goto yy808;
-                       if (yych <= '~') goto yy810;
+                       if (yych <= '`') goto yy813;
+                       if (yych <= 'z') goto yy811;
+                       if (yych <= '~') goto yy813;
                }
-yy808:
-               YYDEBUG(808, *YYCURSOR);
+yy811:
+               YYDEBUG(811, *YYCURSOR);
                yyaccept = 0;
                yych = *(YYMARKER = ++YYCURSOR);
                if (yych <= '_') {
                        if (yych <= '@') {
-                               if (yych <= '/') goto yy809;
-                               if (yych <= '9') goto yy812;
+                               if (yych <= '/') goto yy812;
+                               if (yych <= '9') goto yy815;
                        } else {
-                               if (yych <= '[') goto yy812;
-                               if (yych >= '_') goto yy812;
+                               if (yych <= '[') goto yy815;
+                               if (yych >= '_') goto yy815;
                        }
                } else {
                        if (yych <= '|') {
-                               if (yych <= '`') goto yy809;
-                               if (yych <= 'z') goto yy812;
+                               if (yych <= '`') goto yy812;
+                               if (yych <= 'z') goto yy815;
                        } else {
-                               if (yych != '~') goto yy812;
+                               if (yych != '~') goto yy815;
                        }
                }
-yy809:
-               YYDEBUG(809, *YYCURSOR);
+yy812:
+               YYDEBUG(812, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1474 "Zend/zend_language_scanner.l"
+#line 1478 "Zend/zend_language_scanner.l"
                {
        yyless(0);
        yy_pop_state(TSRMLS_C);
        yy_push_state(ST_IN_SCRIPTING TSRMLS_CC);
        goto restart;
 }
-#line 7398 "Zend/zend_language_scanner.c"
-yy810:
-               YYDEBUG(810, *YYCURSOR);
+#line 7431 "Zend/zend_language_scanner.c"
+yy813:
+               YYDEBUG(813, *YYCURSOR);
                yych = *++YYCURSOR;
-               goto yy809;
-yy811:
-               YYDEBUG(811, *YYCURSOR);
+               goto yy812;
+yy814:
+               YYDEBUG(814, *YYCURSOR);
                ++YYCURSOR;
                YYFILL(1);
                yych = *YYCURSOR;
-yy812:
-               YYDEBUG(812, *YYCURSOR);
+yy815:
+               YYDEBUG(815, *YYCURSOR);
                if (yybm[0+yych] & 128) {
-                       goto yy811;
+                       goto yy814;
                }
-               if (yych == '[') goto yy814;
-               if (yych == '}') goto yy814;
-               YYDEBUG(813, *YYCURSOR);
+               if (yych == '[') goto yy817;
+               if (yych == '}') goto yy817;
+               YYDEBUG(816, *YYCURSOR);
                YYCURSOR = YYMARKER;
-               goto yy809;
-yy814:
-               YYDEBUG(814, *YYCURSOR);
+               goto yy812;
+yy817:
+               YYDEBUG(817, *YYCURSOR);
                ++YYCURSOR;
-               YYDEBUG(815, *YYCURSOR);
+               YYDEBUG(818, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1464 "Zend/zend_language_scanner.l"
+#line 1468 "Zend/zend_language_scanner.l"
                {
        yyless(yyleng - 1);
        zend_copy_value(zendlval, yytext, yyleng);
@@ -7428,18 +7461,18 @@ yy814:
        yy_push_state(ST_IN_SCRIPTING TSRMLS_CC);
        return T_STRING_VARNAME;
 }
-#line 7432 "Zend/zend_language_scanner.c"
+#line 7465 "Zend/zend_language_scanner.c"
        }
 /* *********************************** */
 yyc_ST_NOWDOC:
-       YYDEBUG(816, *YYCURSOR);
+       YYDEBUG(819, *YYCURSOR);
        YYFILL(1);
        yych = *YYCURSOR;
-       YYDEBUG(818, *YYCURSOR);
+       YYDEBUG(821, *YYCURSOR);
        ++YYCURSOR;
-       YYDEBUG(819, *YYCURSOR);
+       YYDEBUG(822, *YYCURSOR);
        yyleng = YYCURSOR - SCNG(yy_text);
-#line 2356 "Zend/zend_language_scanner.l"
+#line 2360 "Zend/zend_language_scanner.l"
        {
        int newline = 0;
 
@@ -7494,7 +7527,7 @@ nowdoc_scan_done:
        HANDLE_NEWLINES(yytext, yyleng - newline);
        return T_ENCAPSED_AND_WHITESPACE;
 }
-#line 7498 "Zend/zend_language_scanner.c"
+#line 7531 "Zend/zend_language_scanner.c"
 /* *********************************** */
 yyc_ST_VAR_OFFSET:
        {
@@ -7532,76 +7565,76 @@ yyc_ST_VAR_OFFSET:
                         16,  16,  16,  16,  16,  16,  16,  16, 
                         16,  16,  16,  16,  16,  16,  16,  16, 
                };
-               YYDEBUG(820, *YYCURSOR);
+               YYDEBUG(823, *YYCURSOR);
                YYFILL(3);
                yych = *YYCURSOR;
                if (yych <= '/') {
                        if (yych <= ' ') {
                                if (yych <= '\f') {
-                                       if (yych <= 0x08) goto yy834;
-                                       if (yych <= '\n') goto yy830;
-                                       goto yy834;
+                                       if (yych <= 0x08) goto yy837;
+                                       if (yych <= '\n') goto yy833;
+                                       goto yy837;
                                } else {
-                                       if (yych <= '\r') goto yy830;
-                                       if (yych <= 0x1F) goto yy834;
-                                       goto yy830;
+                                       if (yych <= '\r') goto yy833;
+                                       if (yych <= 0x1F) goto yy837;
+                                       goto yy833;
                                }
                        } else {
                                if (yych <= '$') {
-                                       if (yych <= '"') goto yy829;
-                                       if (yych <= '#') goto yy830;
-                                       goto yy825;
+                                       if (yych <= '"') goto yy832;
+                                       if (yych <= '#') goto yy833;
+                                       goto yy828;
                                } else {
-                                       if (yych == '\'') goto yy830;
-                                       goto yy829;
+                                       if (yych == '\'') goto yy833;
+                                       goto yy832;
                                }
                        }
                } else {
                        if (yych <= '\\') {
                                if (yych <= '@') {
-                                       if (yych <= '0') goto yy822;
-                                       if (yych <= '9') goto yy824;
-                                       goto yy829;
+                                       if (yych <= '0') goto yy825;
+                                       if (yych <= '9') goto yy827;
+                                       goto yy832;
                                } else {
-                                       if (yych <= 'Z') goto yy832;
-                                       if (yych <= '[') goto yy829;
-                                       goto yy830;
+                                       if (yych <= 'Z') goto yy835;
+                                       if (yych <= '[') goto yy832;
+                                       goto yy833;
                                }
                        } else {
                                if (yych <= '_') {
-                                       if (yych <= ']') goto yy827;
-                                       if (yych <= '^') goto yy829;
-                                       goto yy832;
+                                       if (yych <= ']') goto yy830;
+                                       if (yych <= '^') goto yy832;
+                                       goto yy835;
                                } else {
-                                       if (yych <= '`') goto yy829;
-                                       if (yych <= 'z') goto yy832;
-                                       if (yych <= '~') goto yy829;
-                                       goto yy832;
+                                       if (yych <= '`') goto yy832;
+                                       if (yych <= 'z') goto yy835;
+                                       if (yych <= '~') goto yy832;
+                                       goto yy835;
                                }
                        }
                }
-yy822:
-               YYDEBUG(822, *YYCURSOR);
+yy825:
+               YYDEBUG(825, *YYCURSOR);
                yyaccept = 0;
                yych = *(YYMARKER = ++YYCURSOR);
                if (yych <= 'W') {
                        if (yych <= '9') {
-                               if (yych >= '0') goto yy846;
+                               if (yych >= '0') goto yy849;
                        } else {
-                               if (yych == 'B') goto yy843;
+                               if (yych == 'B') goto yy846;
                        }
                } else {
                        if (yych <= 'b') {
-                               if (yych <= 'X') goto yy845;
-                               if (yych >= 'b') goto yy843;
+                               if (yych <= 'X') goto yy848;
+                               if (yych >= 'b') goto yy846;
                        } else {
-                               if (yych == 'x') goto yy845;
+                               if (yych == 'x') goto yy848;
                        }
                }
-yy823:
-               YYDEBUG(823, *YYCURSOR);
+yy826:
+               YYDEBUG(826, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1552 "Zend/zend_language_scanner.l"
+#line 1556 "Zend/zend_language_scanner.l"
                { /* Offset could be treated as a long */
        if (yyleng < MAX_LENGTH_OF_LONG - 1 || (yyleng == MAX_LENGTH_OF_LONG - 1 && strcmp(yytext, long_min_digits) < 0)) {
                zendlval->value.lval = strtol(yytext, NULL, 10);
@@ -7613,81 +7646,81 @@ yy823:
        }
        return T_NUM_STRING;
 }
-#line 7617 "Zend/zend_language_scanner.c"
-yy824:
-               YYDEBUG(824, *YYCURSOR);
+#line 7650 "Zend/zend_language_scanner.c"
+yy827:
+               YYDEBUG(827, *YYCURSOR);
                yych = *++YYCURSOR;
-               goto yy842;
-yy825:
-               YYDEBUG(825, *YYCURSOR);
+               goto yy845;
+yy828:
+               YYDEBUG(828, *YYCURSOR);
                ++YYCURSOR;
                if ((yych = *YYCURSOR) <= '_') {
-                       if (yych <= '@') goto yy826;
-                       if (yych <= 'Z') goto yy838;
-                       if (yych >= '_') goto yy838;
+                       if (yych <= '@') goto yy829;
+                       if (yych <= 'Z') goto yy841;
+                       if (yych >= '_') goto yy841;
                } else {
-                       if (yych <= '`') goto yy826;
-                       if (yych <= 'z') goto yy838;
-                       if (yych >= 0x7F) goto yy838;
+                       if (yych <= '`') goto yy829;
+                       if (yych <= 'z') goto yy841;
+                       if (yych >= 0x7F) goto yy841;
                }
-yy826:
-               YYDEBUG(826, *YYCURSOR);
+yy829:
+               YYDEBUG(829, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1884 "Zend/zend_language_scanner.l"
+#line 1888 "Zend/zend_language_scanner.l"
                {
        /* Only '[' can be valid, but returning other tokens will allow a more explicit parse error */
        return yytext[0];
 }
-#line 7642 "Zend/zend_language_scanner.c"
-yy827:
-               YYDEBUG(827, *YYCURSOR);
+#line 7675 "Zend/zend_language_scanner.c"
+yy830:
+               YYDEBUG(830, *YYCURSOR);
                ++YYCURSOR;
-               YYDEBUG(828, *YYCURSOR);
+               YYDEBUG(831, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1879 "Zend/zend_language_scanner.l"
+#line 1883 "Zend/zend_language_scanner.l"
                {
        yy_pop_state(TSRMLS_C);
        return ']';
 }
-#line 7653 "Zend/zend_language_scanner.c"
-yy829:
-               YYDEBUG(829, *YYCURSOR);
+#line 7686 "Zend/zend_language_scanner.c"
+yy832:
+               YYDEBUG(832, *YYCURSOR);
                yych = *++YYCURSOR;
-               goto yy826;
-yy830:
-               YYDEBUG(830, *YYCURSOR);
+               goto yy829;
+yy833:
+               YYDEBUG(833, *YYCURSOR);
                ++YYCURSOR;
-               YYDEBUG(831, *YYCURSOR);
+               YYDEBUG(834, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1889 "Zend/zend_language_scanner.l"
+#line 1893 "Zend/zend_language_scanner.l"
                {
        /* Invalid rule to return a more explicit parse error with proper line number */
        yyless(0);
        yy_pop_state(TSRMLS_C);
        return T_ENCAPSED_AND_WHITESPACE;
 }
-#line 7670 "Zend/zend_language_scanner.c"
-yy832:
-               YYDEBUG(832, *YYCURSOR);
+#line 7703 "Zend/zend_language_scanner.c"
+yy835:
+               YYDEBUG(835, *YYCURSOR);
                ++YYCURSOR;
                yych = *YYCURSOR;
-               goto yy837;
-yy833:
-               YYDEBUG(833, *YYCURSOR);
+               goto yy840;
+yy836:
+               YYDEBUG(836, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1896 "Zend/zend_language_scanner.l"
+#line 1900 "Zend/zend_language_scanner.l"
                {
        zend_copy_value(zendlval, yytext, yyleng);
        zendlval->type = IS_STRING;
        return T_STRING;
 }
-#line 7685 "Zend/zend_language_scanner.c"
-yy834:
-               YYDEBUG(834, *YYCURSOR);
+#line 7718 "Zend/zend_language_scanner.c"
+yy837:
+               YYDEBUG(837, *YYCURSOR);
                ++YYCURSOR;
-               YYDEBUG(835, *YYCURSOR);
+               YYDEBUG(838, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 2412 "Zend/zend_language_scanner.l"
+#line 2416 "Zend/zend_language_scanner.l"
                {
        if (YYCURSOR > YYLIMIT) {
                return 0;
@@ -7696,118 +7729,118 @@ yy834:
        zend_error(E_COMPILE_WARNING,"Unexpected character in input:  '%c' (ASCII=%d) state=%d", yytext[0], yytext[0], YYSTATE);
        goto restart;
 }
-#line 7700 "Zend/zend_language_scanner.c"
-yy836:
-               YYDEBUG(836, *YYCURSOR);
+#line 7733 "Zend/zend_language_scanner.c"
+yy839:
+               YYDEBUG(839, *YYCURSOR);
                ++YYCURSOR;
                YYFILL(1);
                yych = *YYCURSOR;
-yy837:
-               YYDEBUG(837, *YYCURSOR);
+yy840:
+               YYDEBUG(840, *YYCURSOR);
                if (yybm[0+yych] & 16) {
-                       goto yy836;
+                       goto yy839;
                }
-               goto yy833;
-yy838:
-               YYDEBUG(838, *YYCURSOR);
+               goto yy836;
+yy841:
+               YYDEBUG(841, *YYCURSOR);
                ++YYCURSOR;
                YYFILL(1);
                yych = *YYCURSOR;
-               YYDEBUG(839, *YYCURSOR);
+               YYDEBUG(842, *YYCURSOR);
                if (yych <= '^') {
                        if (yych <= '9') {
-                               if (yych >= '0') goto yy838;
+                               if (yych >= '0') goto yy841;
                        } else {
-                               if (yych <= '@') goto yy840;
-                               if (yych <= 'Z') goto yy838;
+                               if (yych <= '@') goto yy843;
+                               if (yych <= 'Z') goto yy841;
                        }
                } else {
                        if (yych <= '`') {
-                               if (yych <= '_') goto yy838;
+                               if (yych <= '_') goto yy841;
                        } else {
-                               if (yych <= 'z') goto yy838;
-                               if (yych >= 0x7F) goto yy838;
+                               if (yych <= 'z') goto yy841;
+                               if (yych >= 0x7F) goto yy841;
                        }
                }
-yy840:
-               YYDEBUG(840, *YYCURSOR);
+yy843:
+               YYDEBUG(843, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1873 "Zend/zend_language_scanner.l"
+#line 1877 "Zend/zend_language_scanner.l"
                {
        zend_copy_value(zendlval, (yytext+1), (yyleng-1));
        zendlval->type = IS_STRING;
        return T_VARIABLE;
 }
-#line 7742 "Zend/zend_language_scanner.c"
-yy841:
-               YYDEBUG(841, *YYCURSOR);
+#line 7775 "Zend/zend_language_scanner.c"
+yy844:
+               YYDEBUG(844, *YYCURSOR);
                ++YYCURSOR;
                YYFILL(1);
                yych = *YYCURSOR;
-yy842:
-               YYDEBUG(842, *YYCURSOR);
+yy845:
+               YYDEBUG(845, *YYCURSOR);
                if (yybm[0+yych] & 32) {
-                       goto yy841;
+                       goto yy844;
                }
-               goto yy823;
-yy843:
-               YYDEBUG(843, *YYCURSOR);
+               goto yy826;
+yy846:
+               YYDEBUG(846, *YYCURSOR);
                yych = *++YYCURSOR;
                if (yybm[0+yych] & 128) {
-                       goto yy851;
+                       goto yy854;
                }
-yy844:
-               YYDEBUG(844, *YYCURSOR);
+yy847:
+               YYDEBUG(847, *YYCURSOR);
                YYCURSOR = YYMARKER;
-               goto yy823;
-yy845:
-               YYDEBUG(845, *YYCURSOR);
+               goto yy826;
+yy848:
+               YYDEBUG(848, *YYCURSOR);
                yych = *++YYCURSOR;
                if (yybm[0+yych] & 64) {
-                       goto yy849;
+                       goto yy852;
                }
-               goto yy844;
-yy846:
-               YYDEBUG(846, *YYCURSOR);
+               goto yy847;
+yy849:
+               YYDEBUG(849, *YYCURSOR);
                ++YYCURSOR;
                YYFILL(1);
                yych = *YYCURSOR;
-               YYDEBUG(847, *YYCURSOR);
-               if (yych <= '/') goto yy848;
-               if (yych <= '9') goto yy846;
-yy848:
-               YYDEBUG(848, *YYCURSOR);
+               YYDEBUG(850, *YYCURSOR);
+               if (yych <= '/') goto yy851;
+               if (yych <= '9') goto yy849;
+yy851:
+               YYDEBUG(851, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1564 "Zend/zend_language_scanner.l"
+#line 1568 "Zend/zend_language_scanner.l"
                { /* Offset must be treated as a string */
        zendlval->value.str.val = (char *)estrndup(yytext, yyleng);
        zendlval->value.str.len = yyleng;
        zendlval->type = IS_STRING;
        return T_NUM_STRING;
 }
-#line 7789 "Zend/zend_language_scanner.c"
-yy849:
-               YYDEBUG(849, *YYCURSOR);
+#line 7822 "Zend/zend_language_scanner.c"
+yy852:
+               YYDEBUG(852, *YYCURSOR);
                ++YYCURSOR;
                YYFILL(1);
                yych = *YYCURSOR;
-               YYDEBUG(850, *YYCURSOR);
+               YYDEBUG(853, *YYCURSOR);
                if (yybm[0+yych] & 64) {
-                       goto yy849;
+                       goto yy852;
                }
-               goto yy848;
-yy851:
-               YYDEBUG(851, *YYCURSOR);
+               goto yy851;
+yy854:
+               YYDEBUG(854, *YYCURSOR);
                ++YYCURSOR;
                YYFILL(1);
                yych = *YYCURSOR;
-               YYDEBUG(852, *YYCURSOR);
+               YYDEBUG(855, *YYCURSOR);
                if (yybm[0+yych] & 128) {
-                       goto yy851;
+                       goto yy854;
                }
-               goto yy848;
+               goto yy851;
        }
 }
-#line 2421 "Zend/zend_language_scanner.l"
+#line 2425 "Zend/zend_language_scanner.l"
 
 }
index c73f39aedb9fca57d2a7e1423687bda07f9a8ba1..1104c6ac27e5eef8a526d98afb4023b1b2d5af9a 100644 (file)
@@ -1041,6 +1041,10 @@ NEWLINE ("\r"|"\n"|"\r\n")
        return T_CATCH;
 }
 
+<ST_IN_SCRIPTING>"finally" {
+       return T_FINALLY;
+}
+
 <ST_IN_SCRIPTING>"throw" {
        return T_THROW;
 }
index 5ef78a9faf30b2e50538e9ce962f15cd9abba387..519d415e74ac0c87bbc36bfc8b21ffe775e6c908 100644 (file)
@@ -1,4 +1,4 @@
-/* Generated by re2c 0.13.5 on Mon Apr 30 15:56:25 2012 */
+/* Generated by re2c 0.13.5 on Tue Jul 24 17:16:42 2012 */
 #line 3 "Zend/zend_language_scanner_defs.h"
 
 enum YYCONDTYPE {
index 5480698d9f544ad2a0b968d33a5c6879ee5ce6aa..ad9301d975b3f19a145c1916479a244a69b1f96b 100644 (file)
@@ -2133,7 +2133,9 @@ ZEND_VM_HANDLER(109, ZEND_FETCH_CLASS, ANY, CONST|TMP|VAR|UNUSED|CV)
        USE_OPLINE
 
        SAVE_OPLINE();
-       EG(exception) = NULL;
+    if (EG(exception)) {
+        zend_exception_save(TSRMLS_C);
+    }
        if (OP2_TYPE == IS_UNUSED) {
                EX_T(opline->result.var).class_entry = zend_fetch_class(NULL, 0, opline->extended_value TSRMLS_CC);
                CHECK_EXCEPTION();
@@ -2833,7 +2835,7 @@ ZEND_VM_HANDLER(62, ZEND_RETURN, CONST|TMP|VAR|CV, ANY)
        USE_OPLINE
        zval *retval_ptr;
        zend_free_op free_op1;
-
+    
        SAVE_OPLINE();
        retval_ptr = GET_OP1_ZVAL_PTR(BP_VAR_R);
 
@@ -2842,6 +2844,9 @@ ZEND_VM_HANDLER(62, ZEND_RETURN, CONST|TMP|VAR|CV, ANY)
                        FREE_OP1();
                }
        } else if (!IS_OP1_TMP_FREE()) { /* Not a temp var */
+        if (*EG(return_value_ptr_ptr)) {
+            zval_ptr_dtor(EG(return_value_ptr_ptr));
+        }
                if (OP1_TYPE == IS_CONST ||
                    (PZVAL_IS_REF(retval_ptr) && Z_REFCOUNT_P(retval_ptr) > 0)) {
                        zval *ret;
@@ -2863,12 +2868,59 @@ ZEND_VM_HANDLER(62, ZEND_RETURN, CONST|TMP|VAR|CV, ANY)
        } else {
                zval *ret;
 
+        if (*EG(return_value_ptr_ptr)) {
+            zval_ptr_dtor(EG(return_value_ptr_ptr));
+        }
+
                ALLOC_ZVAL(ret);
                INIT_PZVAL_COPY(ret, retval_ptr);
                *EG(return_value_ptr_ptr) = ret;
        }
        FREE_OP1_IF_VAR();
-       ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper);
+
+    if (!(EG(active_op_array)->last_try_catch)) {
+        ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper);
+    } else {
+        zend_uint i, op_num = opline - EX(op_array)->opcodes;
+        zend_uint catch_op_num = 0, finally_op_num = 0;
+        for (i=0; i<EG(active_op_array)->last_try_catch; i++) {
+            if (EG(active_op_array)->try_catch_array[i].try_op > op_num) {
+                break;
+            } 
+            if (op_num < EG(active_op_array)->try_catch_array[i].finally_op) {
+                finally_op_num = EG(active_op_array)->try_catch_array[i].finally_op;
+            }
+            if (EG(prev_exception)) {
+                /* leaving */
+                if (op_num < EG(active_op_array)->try_catch_array[i].catch_op) {
+                    catch_op_num = EG(active_op_array)->try_catch_array[i].catch_op;
+                }
+            }
+        }
+
+        if (catch_op_num && finally_op_num) {
+            if (catch_op_num > finally_op_num) {
+                EX(leaving) = 1;
+                ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
+                ZEND_VM_CONTINUE();
+            } else {
+                EX(leaving) = 0;
+                ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
+                ZEND_VM_CONTINUE();
+            }
+        } else if (catch_op_num) {
+            ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
+            ZEND_VM_CONTINUE();
+        } else if (finally_op_num) {
+            EX(leaving) = 1;
+            ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
+            ZEND_VM_CONTINUE();
+        } else if (EX(leaving)) {
+            ZEND_VM_NEXT_OPCODE();
+        } else {
+            ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper);
+        }
+    }
 }
 
 ZEND_VM_HANDLER(111, ZEND_RETURN_BY_REF, CONST|TMP|VAR|CV, ANY)
@@ -2881,6 +2933,10 @@ ZEND_VM_HANDLER(111, ZEND_RETURN_BY_REF, CONST|TMP|VAR|CV, ANY)
        SAVE_OPLINE();
 
        do {
+        if (EG(return_value_ptr_ptr) && *EG(return_value_ptr_ptr)) {
+            zval_ptr_dtor(EG(return_value_ptr_ptr));
+        }
+
                if (OP1_TYPE == IS_CONST || OP1_TYPE == IS_TMP_VAR) {
                        /* Not supposed to happen, but we'll allow it */
                        zend_error(E_NOTICE, "Only variable references should be returned by reference");
@@ -2936,7 +2992,50 @@ ZEND_VM_HANDLER(111, ZEND_RETURN_BY_REF, CONST|TMP|VAR|CV, ANY)
        } while (0);
 
        FREE_OP1_IF_VAR();
-       ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper);
+
+    if (!(EG(active_op_array)->last_try_catch)) {
+        ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper);
+    } else {
+        zend_uint i, op_num = opline - EX(op_array)->opcodes;
+        zend_uint catch_op_num = 0, finally_op_num = 0;
+        for (i=0; i<EG(active_op_array)->last_try_catch; i++) {
+            if (EG(active_op_array)->try_catch_array[i].try_op > op_num) {
+                break;
+            } 
+            if (op_num < EG(active_op_array)->try_catch_array[i].finally_op) {
+                finally_op_num = EG(active_op_array)->try_catch_array[i].finally_op;
+            }
+            if (EG(prev_exception)) {
+                /* leaving */
+                if (op_num < EG(active_op_array)->try_catch_array[i].catch_op) {
+                    catch_op_num = EG(active_op_array)->try_catch_array[i].catch_op;
+                }
+            }
+        }
+
+        if (catch_op_num && finally_op_num) {
+            if (catch_op_num > finally_op_num) {
+                EX(leaving) = 1;
+                ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
+                ZEND_VM_CONTINUE();
+            } else {
+                EX(leaving) = 0;
+                ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
+                ZEND_VM_CONTINUE();
+            }
+        } else if (catch_op_num) {
+            ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
+            ZEND_VM_CONTINUE();
+        } else if (finally_op_num) {
+            EX(leaving) = 1;
+            ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
+            ZEND_VM_CONTINUE();
+        } else if (EX(leaving)) {
+            ZEND_VM_NEXT_OPCODE();
+        } else {
+            ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper);
+        }
+    }
 }
 
 ZEND_VM_HANDLER(108, ZEND_THROW, CONST|TMP|VAR|CV, ANY)
@@ -4997,8 +5096,8 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY)
 {
        zend_uint op_num = EG(opline_before_exception)-EG(active_op_array)->opcodes;
        int i;
-       zend_uint catch_op_num = 0;
-       int catched = 0;
+       zend_uint catch_op_num = 0, finally_op_num = 0;
+       int catched = 0, finally = 0;
        zval restored_error_reporting;
 
        void **stack_frame = (void**)(((char*)EX_Ts()) +
@@ -5013,10 +5112,15 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY)
                if (EG(active_op_array)->try_catch_array[i].try_op > op_num) {
                        /* further blocks will not be relevant... */
                        break;
-               } else if (op_num < EG(active_op_array)->try_catch_array[i].catch_op) {
+               } 
+        if (op_num < EG(active_op_array)->try_catch_array[i].catch_op) {
                        catch_op_num = EX(op_array)->try_catch_array[i].catch_op;
-                       catched = 1;
+                       catched = i + 1;
                }
+        if (op_num < EG(active_op_array)->try_catch_array[i].finally_op) {
+            finally_op_num = EX(op_array)->try_catch_array[i].finally_op;
+            finally = i + 1;
+        }
        }
 
        while (EX(fbc)) {
@@ -5073,12 +5177,29 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY)
        }
        EX(old_error_reporting) = NULL;
 
-       if (!catched) {
-               ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper);
-       } else {
-               ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
-               ZEND_VM_CONTINUE();
-       }
+       if (catched && finally) {
+        if (finally_op_num > catch_op_num) {
+            EX(leaving) = 0;
+            ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
+            ZEND_VM_CONTINUE();
+        } else {
+            zend_exception_save(TSRMLS_C);
+            EX(leaving) = finally;
+            ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
+            ZEND_VM_CONTINUE();
+        }
+    } else if (catched) { 
+        EX(leaving) = 0;
+        ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
+        ZEND_VM_CONTINUE();
+    } else if (finally) {
+        zend_exception_save(TSRMLS_C);
+        EX(leaving) = finally;
+        ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
+        ZEND_VM_CONTINUE();
+    } else {
+        ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper);
+    }
 }
 
 ZEND_VM_HANDLER(146, ZEND_VERIFY_ABSTRACT_CLASS, ANY, ANY)
@@ -5196,4 +5317,50 @@ ZEND_VM_HANDLER(156, ZEND_SEPARATE, VAR, UNUSED)
        ZEND_VM_NEXT_OPCODE();
 }
 
+ZEND_VM_HANDLER(159, ZEND_LEAVE, ANY, ANY) {
+{
+    USE_OPLINE;
+       SAVE_OPLINE();
+    zend_uint i, op_num = opline - EG(active_op_array)->opcodes;
+
+    zend_exception_restore(TSRMLS_C);
+    if (EX(leaving)) {
+        zend_uint catch_op_num = 0, finally_op_num = 0;
+        for (i = 0; i < EX(leaving); i++) {
+            if (EG(active_op_array)->try_catch_array[i].try_op > op_num) {
+                break;
+            } 
+            if (op_num < EG(active_op_array)->try_catch_array[i].finally_op) {
+                finally_op_num = EG(active_op_array)->try_catch_array[i].finally_op;
+            }
+            if (EG(exception)) {
+                if (op_num < EG(active_op_array)->try_catch_array[i].catch_op) {
+                    catch_op_num = EG(active_op_array)->try_catch_array[i].catch_op;
+                }
+            }
+        }
+
+        if (catch_op_num && finally_op_num) {
+            if (catch_op_num > finally_op_num) {
+                ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
+                ZEND_VM_CONTINUE();
+            } else {
+                EX(leaving) = 0;
+                ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
+                ZEND_VM_CONTINUE();
+            }
+        } else if (catch_op_num) {
+            ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
+            ZEND_VM_CONTINUE();
+        } else if (finally_op_num) {
+            ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
+            ZEND_VM_CONTINUE();
+        } else {
+            ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper);
+        }
+    } else {
+        ZEND_VM_NEXT_OPCODE();
+    }
+}
+
 ZEND_VM_EXPORT_HELPER(zend_do_fcall, zend_do_fcall_common_helper)
index 5cedfbe343829cf9634f2bcd9994caecec96f9ec..df7c94f5ed479521b1ff90135f8468bf4928422d 100644 (file)
@@ -372,6 +372,7 @@ zend_vm_enter:
        EX(prev_execute_data) = EG(current_execute_data);
        EG(current_execute_data) = execute_data;
        EX(nested) = nested;
+    EX(leaving) = 0;
        nested = 1;
 
        LOAD_REGS();
@@ -1033,8 +1034,8 @@ static int ZEND_FASTCALL  ZEND_HANDLE_EXCEPTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER
 {
        zend_uint op_num = EG(opline_before_exception)-EG(active_op_array)->opcodes;
        int i;
-       zend_uint catch_op_num = 0;
-       int catched = 0;
+       zend_uint catch_op_num = 0, finally_op_num = 0;
+       int catched = 0, finally = 0;
        zval restored_error_reporting;
 
        void **stack_frame = (void**)(((char*)EX_Ts()) +
@@ -1049,10 +1050,15 @@ static int ZEND_FASTCALL  ZEND_HANDLE_EXCEPTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER
                if (EG(active_op_array)->try_catch_array[i].try_op > op_num) {
                        /* further blocks will not be relevant... */
                        break;
-               } else if (op_num < EG(active_op_array)->try_catch_array[i].catch_op) {
+               }
+        if (op_num < EG(active_op_array)->try_catch_array[i].catch_op) {
                        catch_op_num = EX(op_array)->try_catch_array[i].catch_op;
-                       catched = 1;
+                       catched = i + 1;
                }
+        if (op_num < EG(active_op_array)->try_catch_array[i].finally_op) {
+            finally_op_num = EX(op_array)->try_catch_array[i].finally_op;
+            finally = i + 1;
+        }
        }
 
        while (EX(fbc)) {
@@ -1109,12 +1115,29 @@ static int ZEND_FASTCALL  ZEND_HANDLE_EXCEPTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER
        }
        EX(old_error_reporting) = NULL;
 
-       if (!catched) {
-               return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-       } else {
-               ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
-               ZEND_VM_CONTINUE();
-       }
+       if (catched && finally) {
+        if (finally_op_num > catch_op_num) {
+            EX(leaving) = 0;
+            ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
+            ZEND_VM_CONTINUE();
+        } else {
+            zend_exception_save(TSRMLS_C);
+            EX(leaving) = finally;
+            ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
+            ZEND_VM_CONTINUE();
+        }
+    } else if (catched) {
+        EX(leaving) = 0;
+        ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
+        ZEND_VM_CONTINUE();
+    } else if (finally) {
+        zend_exception_save(TSRMLS_C);
+        EX(leaving) = finally;
+        ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
+        ZEND_VM_CONTINUE();
+    } else {
+        return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+    }
 }
 
 static int ZEND_FASTCALL  ZEND_VERIFY_ABSTRACT_CLASS_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -1152,12 +1175,60 @@ static int ZEND_FASTCALL  ZEND_USER_OPCODE_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS
        }
 }
 
+static int ZEND_FASTCALL  ZEND_LEAVE_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+    USE_OPLINE;
+       SAVE_OPLINE();
+    zend_uint i, op_num = opline - EG(active_op_array)->opcodes;
+
+    zend_exception_restore(TSRMLS_C);
+    if (EX(leaving)) {
+        zend_uint catch_op_num = 0, finally_op_num = 0;
+        for (i = 0; i < EX(leaving); i++) {
+            if (EG(active_op_array)->try_catch_array[i].try_op > op_num) {
+                break;
+            }
+            if (op_num < EG(active_op_array)->try_catch_array[i].finally_op) {
+                finally_op_num = EG(active_op_array)->try_catch_array[i].finally_op;
+            }
+            if (EG(exception)) {
+                if (op_num < EG(active_op_array)->try_catch_array[i].catch_op) {
+                    catch_op_num = EG(active_op_array)->try_catch_array[i].catch_op;
+                }
+            }
+        }
+
+        if (catch_op_num && finally_op_num) {
+            if (catch_op_num > finally_op_num) {
+                ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
+                ZEND_VM_CONTINUE();
+            } else {
+                EX(leaving) = 0;
+                ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
+                ZEND_VM_CONTINUE();
+            }
+        } else if (catch_op_num) {
+            ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
+            ZEND_VM_CONTINUE();
+        } else if (finally_op_num) {
+            ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
+            ZEND_VM_CONTINUE();
+        } else {
+            return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+        }
+    } else {
+        ZEND_VM_NEXT_OPCODE();
+    }
+}
+
 static int ZEND_FASTCALL  ZEND_FETCH_CLASS_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
        USE_OPLINE
 
        SAVE_OPLINE();
-       EG(exception) = NULL;
+    if (EG(exception)) {
+        zend_exception_save(TSRMLS_C);
+    }
        if (IS_CONST == IS_UNUSED) {
                EX_T(opline->result.var).class_entry = zend_fetch_class(NULL, 0, opline->extended_value TSRMLS_CC);
                CHECK_EXCEPTION();
@@ -1458,7 +1529,9 @@ static int ZEND_FASTCALL  ZEND_FETCH_CLASS_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_
        USE_OPLINE
 
        SAVE_OPLINE();
-       EG(exception) = NULL;
+    if (EG(exception)) {
+        zend_exception_save(TSRMLS_C);
+    }
        if (IS_TMP_VAR == IS_UNUSED) {
                EX_T(opline->result.var).class_entry = zend_fetch_class(NULL, 0, opline->extended_value TSRMLS_CC);
                CHECK_EXCEPTION();
@@ -1622,7 +1695,9 @@ static int ZEND_FASTCALL  ZEND_FETCH_CLASS_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_
        USE_OPLINE
 
        SAVE_OPLINE();
-       EG(exception) = NULL;
+    if (EG(exception)) {
+        zend_exception_save(TSRMLS_C);
+    }
        if (IS_VAR == IS_UNUSED) {
                EX_T(opline->result.var).class_entry = zend_fetch_class(NULL, 0, opline->extended_value TSRMLS_CC);
                CHECK_EXCEPTION();
@@ -1786,7 +1861,9 @@ static int ZEND_FASTCALL  ZEND_FETCH_CLASS_SPEC_UNUSED_HANDLER(ZEND_OPCODE_HANDL
        USE_OPLINE
 
        SAVE_OPLINE();
-       EG(exception) = NULL;
+    if (EG(exception)) {
+        zend_exception_save(TSRMLS_C);
+    }
        if (IS_UNUSED == IS_UNUSED) {
                EX_T(opline->result.var).class_entry = zend_fetch_class(NULL, 0, opline->extended_value TSRMLS_CC);
                CHECK_EXCEPTION();
@@ -1820,7 +1897,9 @@ static int ZEND_FASTCALL  ZEND_FETCH_CLASS_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_A
        USE_OPLINE
 
        SAVE_OPLINE();
-       EG(exception) = NULL;
+    if (EG(exception)) {
+        zend_exception_save(TSRMLS_C);
+    }
        if (IS_CV == IS_UNUSED) {
                EX_T(opline->result.var).class_entry = zend_fetch_class(NULL, 0, opline->extended_value TSRMLS_CC);
                CHECK_EXCEPTION();
@@ -2233,6 +2312,9 @@ static int ZEND_FASTCALL  ZEND_RETURN_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARG
 
                }
        } else if (!0) { /* Not a temp var */
+        if (*EG(return_value_ptr_ptr)) {
+            zval_ptr_dtor(EG(return_value_ptr_ptr));
+        }
                if (IS_CONST == IS_CONST ||
                    (PZVAL_IS_REF(retval_ptr) && Z_REFCOUNT_P(retval_ptr) > 0)) {
                        zval *ret;
@@ -2254,12 +2336,58 @@ static int ZEND_FASTCALL  ZEND_RETURN_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARG
        } else {
                zval *ret;
 
+        if (*EG(return_value_ptr_ptr)) {
+            zval_ptr_dtor(EG(return_value_ptr_ptr));
+        }
+
                ALLOC_ZVAL(ret);
                INIT_PZVAL_COPY(ret, retval_ptr);
                *EG(return_value_ptr_ptr) = ret;
        }
 
-       return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+    if (!(EG(active_op_array)->last_try_catch)) {
+        return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+    } else {
+        zend_uint i, op_num = opline - EX(op_array)->opcodes;
+        zend_uint catch_op_num = 0, finally_op_num = 0;
+        for (i=0; i<EG(active_op_array)->last_try_catch; i++) {
+            if (EG(active_op_array)->try_catch_array[i].try_op > op_num) {
+                break;
+            }
+            if (op_num < EG(active_op_array)->try_catch_array[i].finally_op) {
+                finally_op_num = EG(active_op_array)->try_catch_array[i].finally_op;
+            }
+            if (EG(prev_exception)) {
+                /* leaving */
+                if (op_num < EG(active_op_array)->try_catch_array[i].catch_op) {
+                    catch_op_num = EG(active_op_array)->try_catch_array[i].catch_op;
+                }
+            }
+        }
+
+        if (catch_op_num && finally_op_num) {
+            if (catch_op_num > finally_op_num) {
+                EX(leaving) = 1;
+                ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
+                ZEND_VM_CONTINUE();
+            } else {
+                EX(leaving) = 0;
+                ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
+                ZEND_VM_CONTINUE();
+            }
+        } else if (catch_op_num) {
+            ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
+            ZEND_VM_CONTINUE();
+        } else if (finally_op_num) {
+            EX(leaving) = 1;
+            ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
+            ZEND_VM_CONTINUE();
+        } else if (EX(leaving)) {
+            ZEND_VM_NEXT_OPCODE();
+        } else {
+            return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+        }
+    }
 }
 
 static int ZEND_FASTCALL  ZEND_RETURN_BY_REF_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -2272,6 +2400,10 @@ static int ZEND_FASTCALL  ZEND_RETURN_BY_REF_SPEC_CONST_HANDLER(ZEND_OPCODE_HAND
        SAVE_OPLINE();
 
        do {
+        if (EG(return_value_ptr_ptr) && *EG(return_value_ptr_ptr)) {
+            zval_ptr_dtor(EG(return_value_ptr_ptr));
+        }
+
                if (IS_CONST == IS_CONST || IS_CONST == IS_TMP_VAR) {
                        /* Not supposed to happen, but we'll allow it */
                        zend_error(E_NOTICE, "Only variable references should be returned by reference");
@@ -2326,7 +2458,49 @@ static int ZEND_FASTCALL  ZEND_RETURN_BY_REF_SPEC_CONST_HANDLER(ZEND_OPCODE_HAND
                }
        } while (0);
 
-       return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+    if (!(EG(active_op_array)->last_try_catch)) {
+        return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+    } else {
+        zend_uint i, op_num = opline - EX(op_array)->opcodes;
+        zend_uint catch_op_num = 0, finally_op_num = 0;
+        for (i=0; i<EG(active_op_array)->last_try_catch; i++) {
+            if (EG(active_op_array)->try_catch_array[i].try_op > op_num) {
+                break;
+            }
+            if (op_num < EG(active_op_array)->try_catch_array[i].finally_op) {
+                finally_op_num = EG(active_op_array)->try_catch_array[i].finally_op;
+            }
+            if (EG(prev_exception)) {
+                /* leaving */
+                if (op_num < EG(active_op_array)->try_catch_array[i].catch_op) {
+                    catch_op_num = EG(active_op_array)->try_catch_array[i].catch_op;
+                }
+            }
+        }
+
+        if (catch_op_num && finally_op_num) {
+            if (catch_op_num > finally_op_num) {
+                EX(leaving) = 1;
+                ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
+                ZEND_VM_CONTINUE();
+            } else {
+                EX(leaving) = 0;
+                ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
+                ZEND_VM_CONTINUE();
+            }
+        } else if (catch_op_num) {
+            ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
+            ZEND_VM_CONTINUE();
+        } else if (finally_op_num) {
+            EX(leaving) = 1;
+            ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
+            ZEND_VM_CONTINUE();
+        } else if (EX(leaving)) {
+            ZEND_VM_NEXT_OPCODE();
+        } else {
+            return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+        }
+    }
 }
 
 static int ZEND_FASTCALL  ZEND_THROW_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -6766,6 +6940,9 @@ static int ZEND_FASTCALL  ZEND_RETURN_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                        zval_dtor(free_op1.var);
                }
        } else if (!1) { /* Not a temp var */
+        if (*EG(return_value_ptr_ptr)) {
+            zval_ptr_dtor(EG(return_value_ptr_ptr));
+        }
                if (IS_TMP_VAR == IS_CONST ||
                    (PZVAL_IS_REF(retval_ptr) && Z_REFCOUNT_P(retval_ptr) > 0)) {
                        zval *ret;
@@ -6787,12 +6964,58 @@ static int ZEND_FASTCALL  ZEND_RETURN_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        } else {
                zval *ret;
 
+        if (*EG(return_value_ptr_ptr)) {
+            zval_ptr_dtor(EG(return_value_ptr_ptr));
+        }
+
                ALLOC_ZVAL(ret);
                INIT_PZVAL_COPY(ret, retval_ptr);
                *EG(return_value_ptr_ptr) = ret;
        }
 
-       return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+    if (!(EG(active_op_array)->last_try_catch)) {
+        return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+    } else {
+        zend_uint i, op_num = opline - EX(op_array)->opcodes;
+        zend_uint catch_op_num = 0, finally_op_num = 0;
+        for (i=0; i<EG(active_op_array)->last_try_catch; i++) {
+            if (EG(active_op_array)->try_catch_array[i].try_op > op_num) {
+                break;
+            }
+            if (op_num < EG(active_op_array)->try_catch_array[i].finally_op) {
+                finally_op_num = EG(active_op_array)->try_catch_array[i].finally_op;
+            }
+            if (EG(prev_exception)) {
+                /* leaving */
+                if (op_num < EG(active_op_array)->try_catch_array[i].catch_op) {
+                    catch_op_num = EG(active_op_array)->try_catch_array[i].catch_op;
+                }
+            }
+        }
+
+        if (catch_op_num && finally_op_num) {
+            if (catch_op_num > finally_op_num) {
+                EX(leaving) = 1;
+                ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
+                ZEND_VM_CONTINUE();
+            } else {
+                EX(leaving) = 0;
+                ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
+                ZEND_VM_CONTINUE();
+            }
+        } else if (catch_op_num) {
+            ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
+            ZEND_VM_CONTINUE();
+        } else if (finally_op_num) {
+            EX(leaving) = 1;
+            ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
+            ZEND_VM_CONTINUE();
+        } else if (EX(leaving)) {
+            ZEND_VM_NEXT_OPCODE();
+        } else {
+            return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+        }
+    }
 }
 
 static int ZEND_FASTCALL  ZEND_RETURN_BY_REF_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -6805,6 +7028,10 @@ static int ZEND_FASTCALL  ZEND_RETURN_BY_REF_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLE
        SAVE_OPLINE();
 
        do {
+        if (EG(return_value_ptr_ptr) && *EG(return_value_ptr_ptr)) {
+            zval_ptr_dtor(EG(return_value_ptr_ptr));
+        }
+
                if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_VAR) {
                        /* Not supposed to happen, but we'll allow it */
                        zend_error(E_NOTICE, "Only variable references should be returned by reference");
@@ -6859,7 +7086,49 @@ static int ZEND_FASTCALL  ZEND_RETURN_BY_REF_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLE
                }
        } while (0);
 
-       return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+    if (!(EG(active_op_array)->last_try_catch)) {
+        return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+    } else {
+        zend_uint i, op_num = opline - EX(op_array)->opcodes;
+        zend_uint catch_op_num = 0, finally_op_num = 0;
+        for (i=0; i<EG(active_op_array)->last_try_catch; i++) {
+            if (EG(active_op_array)->try_catch_array[i].try_op > op_num) {
+                break;
+            }
+            if (op_num < EG(active_op_array)->try_catch_array[i].finally_op) {
+                finally_op_num = EG(active_op_array)->try_catch_array[i].finally_op;
+            }
+            if (EG(prev_exception)) {
+                /* leaving */
+                if (op_num < EG(active_op_array)->try_catch_array[i].catch_op) {
+                    catch_op_num = EG(active_op_array)->try_catch_array[i].catch_op;
+                }
+            }
+        }
+
+        if (catch_op_num && finally_op_num) {
+            if (catch_op_num > finally_op_num) {
+                EX(leaving) = 1;
+                ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
+                ZEND_VM_CONTINUE();
+            } else {
+                EX(leaving) = 0;
+                ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
+                ZEND_VM_CONTINUE();
+            }
+        } else if (catch_op_num) {
+            ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
+            ZEND_VM_CONTINUE();
+        } else if (finally_op_num) {
+            EX(leaving) = 1;
+            ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
+            ZEND_VM_CONTINUE();
+        } else if (EX(leaving)) {
+            ZEND_VM_NEXT_OPCODE();
+        } else {
+            return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+        }
+    }
 }
 
 static int ZEND_FASTCALL  ZEND_THROW_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -11204,6 +11473,9 @@ static int ZEND_FASTCALL  ZEND_RETURN_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                        if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
                }
        } else if (!0) { /* Not a temp var */
+        if (*EG(return_value_ptr_ptr)) {
+            zval_ptr_dtor(EG(return_value_ptr_ptr));
+        }
                if (IS_VAR == IS_CONST ||
                    (PZVAL_IS_REF(retval_ptr) && Z_REFCOUNT_P(retval_ptr) > 0)) {
                        zval *ret;
@@ -11225,12 +11497,59 @@ static int ZEND_FASTCALL  ZEND_RETURN_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        } else {
                zval *ret;
 
+        if (*EG(return_value_ptr_ptr)) {
+            zval_ptr_dtor(EG(return_value_ptr_ptr));
+        }
+
                ALLOC_ZVAL(ret);
                INIT_PZVAL_COPY(ret, retval_ptr);
                *EG(return_value_ptr_ptr) = ret;
        }
        if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
-       return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+
+    if (!(EG(active_op_array)->last_try_catch)) {
+        return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+    } else {
+        zend_uint i, op_num = opline - EX(op_array)->opcodes;
+        zend_uint catch_op_num = 0, finally_op_num = 0;
+        for (i=0; i<EG(active_op_array)->last_try_catch; i++) {
+            if (EG(active_op_array)->try_catch_array[i].try_op > op_num) {
+                break;
+            }
+            if (op_num < EG(active_op_array)->try_catch_array[i].finally_op) {
+                finally_op_num = EG(active_op_array)->try_catch_array[i].finally_op;
+            }
+            if (EG(prev_exception)) {
+                /* leaving */
+                if (op_num < EG(active_op_array)->try_catch_array[i].catch_op) {
+                    catch_op_num = EG(active_op_array)->try_catch_array[i].catch_op;
+                }
+            }
+        }
+
+        if (catch_op_num && finally_op_num) {
+            if (catch_op_num > finally_op_num) {
+                EX(leaving) = 1;
+                ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
+                ZEND_VM_CONTINUE();
+            } else {
+                EX(leaving) = 0;
+                ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
+                ZEND_VM_CONTINUE();
+            }
+        } else if (catch_op_num) {
+            ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
+            ZEND_VM_CONTINUE();
+        } else if (finally_op_num) {
+            EX(leaving) = 1;
+            ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
+            ZEND_VM_CONTINUE();
+        } else if (EX(leaving)) {
+            ZEND_VM_NEXT_OPCODE();
+        } else {
+            return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+        }
+    }
 }
 
 static int ZEND_FASTCALL  ZEND_RETURN_BY_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -11243,6 +11562,10 @@ static int ZEND_FASTCALL  ZEND_RETURN_BY_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLE
        SAVE_OPLINE();
 
        do {
+        if (EG(return_value_ptr_ptr) && *EG(return_value_ptr_ptr)) {
+            zval_ptr_dtor(EG(return_value_ptr_ptr));
+        }
+
                if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR) {
                        /* Not supposed to happen, but we'll allow it */
                        zend_error(E_NOTICE, "Only variable references should be returned by reference");
@@ -11298,7 +11621,50 @@ static int ZEND_FASTCALL  ZEND_RETURN_BY_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLE
        } while (0);
 
        if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
-       return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+
+    if (!(EG(active_op_array)->last_try_catch)) {
+        return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+    } else {
+        zend_uint i, op_num = opline - EX(op_array)->opcodes;
+        zend_uint catch_op_num = 0, finally_op_num = 0;
+        for (i=0; i<EG(active_op_array)->last_try_catch; i++) {
+            if (EG(active_op_array)->try_catch_array[i].try_op > op_num) {
+                break;
+            }
+            if (op_num < EG(active_op_array)->try_catch_array[i].finally_op) {
+                finally_op_num = EG(active_op_array)->try_catch_array[i].finally_op;
+            }
+            if (EG(prev_exception)) {
+                /* leaving */
+                if (op_num < EG(active_op_array)->try_catch_array[i].catch_op) {
+                    catch_op_num = EG(active_op_array)->try_catch_array[i].catch_op;
+                }
+            }
+        }
+
+        if (catch_op_num && finally_op_num) {
+            if (catch_op_num > finally_op_num) {
+                EX(leaving) = 1;
+                ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
+                ZEND_VM_CONTINUE();
+            } else {
+                EX(leaving) = 0;
+                ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
+                ZEND_VM_CONTINUE();
+            }
+        } else if (catch_op_num) {
+            ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
+            ZEND_VM_CONTINUE();
+        } else if (finally_op_num) {
+            EX(leaving) = 1;
+            ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
+            ZEND_VM_CONTINUE();
+        } else if (EX(leaving)) {
+            ZEND_VM_NEXT_OPCODE();
+        } else {
+            return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+        }
+    }
 }
 
 static int ZEND_FASTCALL  ZEND_THROW_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -27205,6 +27571,9 @@ static int ZEND_FASTCALL  ZEND_RETURN_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 
                }
        } else if (!0) { /* Not a temp var */
+        if (*EG(return_value_ptr_ptr)) {
+            zval_ptr_dtor(EG(return_value_ptr_ptr));
+        }
                if (IS_CV == IS_CONST ||
                    (PZVAL_IS_REF(retval_ptr) && Z_REFCOUNT_P(retval_ptr) > 0)) {
                        zval *ret;
@@ -27226,12 +27595,58 @@ static int ZEND_FASTCALL  ZEND_RETURN_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        } else {
                zval *ret;
 
+        if (*EG(return_value_ptr_ptr)) {
+            zval_ptr_dtor(EG(return_value_ptr_ptr));
+        }
+
                ALLOC_ZVAL(ret);
                INIT_PZVAL_COPY(ret, retval_ptr);
                *EG(return_value_ptr_ptr) = ret;
        }
 
-       return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+    if (!(EG(active_op_array)->last_try_catch)) {
+        return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+    } else {
+        zend_uint i, op_num = opline - EX(op_array)->opcodes;
+        zend_uint catch_op_num = 0, finally_op_num = 0;
+        for (i=0; i<EG(active_op_array)->last_try_catch; i++) {
+            if (EG(active_op_array)->try_catch_array[i].try_op > op_num) {
+                break;
+            }
+            if (op_num < EG(active_op_array)->try_catch_array[i].finally_op) {
+                finally_op_num = EG(active_op_array)->try_catch_array[i].finally_op;
+            }
+            if (EG(prev_exception)) {
+                /* leaving */
+                if (op_num < EG(active_op_array)->try_catch_array[i].catch_op) {
+                    catch_op_num = EG(active_op_array)->try_catch_array[i].catch_op;
+                }
+            }
+        }
+
+        if (catch_op_num && finally_op_num) {
+            if (catch_op_num > finally_op_num) {
+                EX(leaving) = 1;
+                ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
+                ZEND_VM_CONTINUE();
+            } else {
+                EX(leaving) = 0;
+                ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
+                ZEND_VM_CONTINUE();
+            }
+        } else if (catch_op_num) {
+            ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
+            ZEND_VM_CONTINUE();
+        } else if (finally_op_num) {
+            EX(leaving) = 1;
+            ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
+            ZEND_VM_CONTINUE();
+        } else if (EX(leaving)) {
+            ZEND_VM_NEXT_OPCODE();
+        } else {
+            return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+        }
+    }
 }
 
 static int ZEND_FASTCALL  ZEND_RETURN_BY_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -27244,6 +27659,10 @@ static int ZEND_FASTCALL  ZEND_RETURN_BY_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER
        SAVE_OPLINE();
 
        do {
+        if (EG(return_value_ptr_ptr) && *EG(return_value_ptr_ptr)) {
+            zval_ptr_dtor(EG(return_value_ptr_ptr));
+        }
+
                if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR) {
                        /* Not supposed to happen, but we'll allow it */
                        zend_error(E_NOTICE, "Only variable references should be returned by reference");
@@ -27298,7 +27717,49 @@ static int ZEND_FASTCALL  ZEND_RETURN_BY_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER
                }
        } while (0);
 
-       return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+    if (!(EG(active_op_array)->last_try_catch)) {
+        return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+    } else {
+        zend_uint i, op_num = opline - EX(op_array)->opcodes;
+        zend_uint catch_op_num = 0, finally_op_num = 0;
+        for (i=0; i<EG(active_op_array)->last_try_catch; i++) {
+            if (EG(active_op_array)->try_catch_array[i].try_op > op_num) {
+                break;
+            }
+            if (op_num < EG(active_op_array)->try_catch_array[i].finally_op) {
+                finally_op_num = EG(active_op_array)->try_catch_array[i].finally_op;
+            }
+            if (EG(prev_exception)) {
+                /* leaving */
+                if (op_num < EG(active_op_array)->try_catch_array[i].catch_op) {
+                    catch_op_num = EG(active_op_array)->try_catch_array[i].catch_op;
+                }
+            }
+        }
+
+        if (catch_op_num && finally_op_num) {
+            if (catch_op_num > finally_op_num) {
+                EX(leaving) = 1;
+                ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
+                ZEND_VM_CONTINUE();
+            } else {
+                EX(leaving) = 0;
+                ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
+                ZEND_VM_CONTINUE();
+            }
+        } else if (catch_op_num) {
+            ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
+            ZEND_VM_CONTINUE();
+        } else if (finally_op_num) {
+            EX(leaving) = 1;
+            ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
+            ZEND_VM_CONTINUE();
+        } else if (EX(leaving)) {
+            ZEND_VM_NEXT_OPCODE();
+        } else {
+            return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+        }
+    }
 }
 
 static int ZEND_FASTCALL  ZEND_THROW_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -40794,6 +41255,31 @@ void zend_init_opcodes_handlers(void)
        ZEND_JMP_SET_VAR_SPEC_CV_HANDLER,
        ZEND_JMP_SET_VAR_SPEC_CV_HANDLER,
        ZEND_JMP_SET_VAR_SPEC_CV_HANDLER,
+       ZEND_LEAVE_SPEC_HANDLER,
+       ZEND_LEAVE_SPEC_HANDLER,
+       ZEND_LEAVE_SPEC_HANDLER,
+       ZEND_LEAVE_SPEC_HANDLER,
+       ZEND_LEAVE_SPEC_HANDLER,
+       ZEND_LEAVE_SPEC_HANDLER,
+       ZEND_LEAVE_SPEC_HANDLER,
+       ZEND_LEAVE_SPEC_HANDLER,
+       ZEND_LEAVE_SPEC_HANDLER,
+       ZEND_LEAVE_SPEC_HANDLER,
+       ZEND_LEAVE_SPEC_HANDLER,
+       ZEND_LEAVE_SPEC_HANDLER,
+       ZEND_LEAVE_SPEC_HANDLER,
+       ZEND_LEAVE_SPEC_HANDLER,
+       ZEND_LEAVE_SPEC_HANDLER,
+       ZEND_LEAVE_SPEC_HANDLER,
+       ZEND_LEAVE_SPEC_HANDLER,
+       ZEND_LEAVE_SPEC_HANDLER,
+       ZEND_LEAVE_SPEC_HANDLER,
+       ZEND_LEAVE_SPEC_HANDLER,
+       ZEND_LEAVE_SPEC_HANDLER,
+       ZEND_LEAVE_SPEC_HANDLER,
+       ZEND_LEAVE_SPEC_HANDLER,
+       ZEND_LEAVE_SPEC_HANDLER,
+       ZEND_LEAVE_SPEC_HANDLER,
        ZEND_NULL_HANDLER
   };
   zend_opcode_handlers = (opcode_handler_t*)labels;
index 426f689795fc94780ed01a14ea82f836159b93ba..f5d0b7879a9faac1e00061fe455c4574883be75f 100644 (file)
@@ -35,6 +35,7 @@ zend_vm_enter:
        EX(prev_execute_data) = EG(current_execute_data);
        EG(current_execute_data) = execute_data;
        EX(nested) = nested;
+    EX(leaving) = 0;
        nested = 1;
 
        LOAD_REGS();
index 680778c2a28737d3aabb719a6ff40ce6319a1a88..69603d1d138890a857be99038a590261ab14c34e 100644 (file)
 #define ZEND_SEPARATE                        156
 #define ZEND_QM_ASSIGN_VAR                   157
 #define ZEND_JMP_SET_VAR                     158
+#define ZEND_LEAVE                           159