]> granicus.if.org Git - php/commitdiff
Avoid memory allocation/deallocation in BEGIN_SILENCE/END_SILENCE opcode handlers.
authorDmitry Stogov <dmitry@zend.com>
Tue, 2 Sep 2014 18:13:24 +0000 (22:13 +0400)
committerDmitry Stogov <dmitry@zend.com>
Tue, 2 Sep 2014 18:13:24 +0000 (22:13 +0400)
Zend/zend_types.h
Zend/zend_vm_def.h
Zend/zend_vm_execute.h

index 47f408f4b37dc3320da6063e88e58b7dc3050f23..368311aedb697084702ae5a293944f6046b8f26d 100644 (file)
@@ -134,6 +134,7 @@ struct _zval_struct {
                uint32_t     str_offset;           /* string offset */
                uint32_t     cache_slot;           /* literal cache slot */
                uint32_t     lineno;               /* line number (for ast nodes) */
+               int          error_reporting;      /* old error_reporting (@) */
        } u2;
 };
 
index 72f9d3bd0433d76bdd4761efcd23b24ea069e1ee..a1fbba752e46b5618ef3881ed95a1fa44b7e6a0d 100644 (file)
@@ -5048,22 +5048,27 @@ ZEND_VM_HANDLER(57, ZEND_BEGIN_SILENCE, ANY, ANY)
        USE_OPLINE
 
        SAVE_OPLINE();
-       ZVAL_LONG(EX_VAR(opline->result.var), EG(error_reporting));
-       if (Z_TYPE(EX(old_error_reporting)) == IS_UNDEF) {
-               ZVAL_LONG(&EX(old_error_reporting), EG(error_reporting));
-       }
 
-       if (EG(error_reporting)) {
-               do {
-                       EG(error_reporting) = 0;
-                       if (!EG(error_reporting_ini_entry)) {
-                               zend_ini_entry *p = zend_hash_str_find_ptr(EG(ini_directives), "error_reporting", sizeof("error_reporting")-1);
-                               if (p) {
-                                       EG(error_reporting_ini_entry) = p;
-                               } else {
-                                       break;
-                               }
+       EX_VAR(opline->result.var)->u2.error_reporting = EG(error_reporting);
+       do {
+               if (!EG(error_reporting_ini_entry)) {
+                       zend_ini_entry *p = zend_hash_str_find_ptr(EG(ini_directives), "error_reporting", sizeof("error_reporting")-1);
+                       if (p) {
+                               EG(error_reporting_ini_entry) = p;
+                       } else {
+                               EG(error_reporting) = 0;
+                               break;
                        }
+               }
+               ZVAL_NEW_STR(EX_VAR(opline->result.var), EG(error_reporting_ini_entry)->value);
+               if (EG(error_reporting_ini_entry)->value) {
+                       zend_string_addref(EG(error_reporting_ini_entry)->value);
+               }
+               if (Z_TYPE(EX(old_error_reporting)) == IS_UNDEF) {
+                       ZVAL_NEW_STR(&EX(old_error_reporting), EG(error_reporting_ini_entry)->value);
+               }
+               if (EG(error_reporting)) {
+                       EG(error_reporting) = 0;
                        if (!EG(error_reporting_ini_entry)->modified) {
                                if (!EG(modified_ini_directives)) {
                                        ALLOC_HASHTABLE(EG(modified_ini_directives));
@@ -5082,9 +5087,8 @@ ZEND_VM_HANDLER(57, ZEND_BEGIN_SILENCE, ANY, ANY)
                        } else {
                                EG(error_reporting_ini_entry)->value = zend_string_init("0", sizeof("0")-1, 0);
                        }
-               } while (0);
-       }
-       CHECK_EXCEPTION();
+               }
+       } while (0);
        ZEND_VM_NEXT_OPCODE();
 }
 
@@ -5098,25 +5102,30 @@ ZEND_VM_HANDLER(142, ZEND_RAISE_ABSTRACT_ERROR, ANY, ANY)
 ZEND_VM_HANDLER(58, ZEND_END_SILENCE, TMP, ANY)
 {
        USE_OPLINE
-       char buf[MAX_LENGTH_OF_LONG + 1];
-       char *res;
 
        SAVE_OPLINE();
-       if (!EG(error_reporting) && Z_LVAL_P(EX_VAR(opline->op1.var)) != 0) {
-               EG(error_reporting) = Z_LVAL_P(EX_VAR(opline->op1.var));
-               _zend_print_signed_to_buf(buf + sizeof(buf) - 1, EG(error_reporting), zend_ulong, res);
-               if (EXPECTED(EG(error_reporting_ini_entry) != NULL)) {
+       if (!EG(error_reporting)) {
+               EG(error_reporting) = EX_VAR(opline->op1.var)->u2.error_reporting;
+               if (EXPECTED(Z_TYPE_P(EX_VAR(opline->op1.var)) == IS_STRING)) {
                        if (EXPECTED(EG(error_reporting_ini_entry)->modified &&
                            EG(error_reporting_ini_entry)->value != EG(error_reporting_ini_entry)->orig_value)) {
                                zend_string_release(EG(error_reporting_ini_entry)->value);
                        }
-                       EG(error_reporting_ini_entry)->value = zend_string_init(res, buf + sizeof(buf) - 1 - res, 0);
-               } 
+                       EG(error_reporting_ini_entry)->value = Z_STR_P(EX_VAR(opline->op1.var));
+                       if (Z_TYPE(EX(old_error_reporting)) != IS_UNDEF &&
+                           Z_STR(EX(old_error_reporting)) == EG(error_reporting_ini_entry)->value) {
+                               ZVAL_UNDEF(&EX(old_error_reporting));
+                       }
+               }
+       } else {
+               if (EXPECTED(Z_TYPE_P(EX_VAR(opline->op1.var)) == IS_STRING)) {
+                       zend_string_release(Z_STR_P(EX_VAR(opline->op1.var)));
+                       if (Z_TYPE(EX(old_error_reporting)) != IS_UNDEF &&
+                           Z_STR(EX(old_error_reporting)) == Z_STR_P(EX_VAR(opline->op1.var))) {
+                               ZVAL_UNDEF(&EX(old_error_reporting));
+                       }
+               }
        }
-//???  if (EX(old_error_reporting) == EX_VAR(opline->op1.var)) {
-//???          EX(old_error_reporting) = NULL;
-//???  }
-       CHECK_EXCEPTION();
        ZEND_VM_NEXT_OPCODE();
 }
 
@@ -5472,18 +5481,19 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY)
        }
 
        /* restore previous error_reporting value */
-       if (!EG(error_reporting) && Z_TYPE(EX(old_error_reporting)) != IS_UNDEF && Z_LVAL(EX(old_error_reporting)) != 0) {
-               zval restored_error_reporting;
-               zend_string *key;
-
-               ZVAL_LONG(&restored_error_reporting, Z_LVAL(EX(old_error_reporting)));
-               convert_to_string(&restored_error_reporting);
-               key = zend_string_init("error_reporting", sizeof("error_reporting")-1, 0);
-               zend_alter_ini_entry_ex(key, Z_STR(restored_error_reporting), ZEND_INI_USER, ZEND_INI_STAGE_RUNTIME, 1 TSRMLS_CC);
-               zend_string_free(key);
-               zval_dtor(&restored_error_reporting);
-       }
-       ZVAL_UNDEF(&EX(old_error_reporting));
+       if (Z_TYPE(EX(old_error_reporting)) != IS_UNDEF) {
+               if (!EG(error_reporting)) {
+                       zend_string *key;
+
+                       key = zend_string_init("error_reporting", sizeof("error_reporting")-1, 0);
+                       zend_alter_ini_entry_ex(key, Z_STR(EX(old_error_reporting)), ZEND_INI_USER, ZEND_INI_STAGE_RUNTIME, 1 TSRMLS_CC);
+                       zend_string_free(key);
+               }
+               if (Z_STR(EX(old_error_reporting))) {
+                       zend_string_release(Z_STR(EX(old_error_reporting)));
+               }
+               ZVAL_UNDEF(&EX(old_error_reporting));
+       }
 
        if (finally_op_num && (!catch_op_num || catch_op_num >= finally_op_num)) {
                if (EX(delayed_exception)) {
index 6110c818107b08d293fb47d6435ad7d154b11aa1..211890461614b34dcc792a0d8cb59c22f5631433 100644 (file)
@@ -1108,22 +1108,27 @@ static int ZEND_FASTCALL  ZEND_BEGIN_SILENCE_SPEC_HANDLER(ZEND_OPCODE_HANDLER_AR
        USE_OPLINE
 
        SAVE_OPLINE();
-       ZVAL_LONG(EX_VAR(opline->result.var), EG(error_reporting));
-       if (Z_TYPE(EX(old_error_reporting)) == IS_UNDEF) {
-               ZVAL_LONG(&EX(old_error_reporting), EG(error_reporting));
-       }
 
-       if (EG(error_reporting)) {
-               do {
-                       EG(error_reporting) = 0;
-                       if (!EG(error_reporting_ini_entry)) {
-                               zend_ini_entry *p = zend_hash_str_find_ptr(EG(ini_directives), "error_reporting", sizeof("error_reporting")-1);
-                               if (p) {
-                                       EG(error_reporting_ini_entry) = p;
-                               } else {
-                                       break;
-                               }
+       EX_VAR(opline->result.var)->u2.error_reporting = EG(error_reporting);
+       do {
+               if (!EG(error_reporting_ini_entry)) {
+                       zend_ini_entry *p = zend_hash_str_find_ptr(EG(ini_directives), "error_reporting", sizeof("error_reporting")-1);
+                       if (p) {
+                               EG(error_reporting_ini_entry) = p;
+                       } else {
+                               EG(error_reporting) = 0;
+                               break;
                        }
+               }
+               ZVAL_NEW_STR(EX_VAR(opline->result.var), EG(error_reporting_ini_entry)->value);
+               if (EG(error_reporting_ini_entry)->value) {
+                       zend_string_addref(EG(error_reporting_ini_entry)->value);
+               }
+               if (Z_TYPE(EX(old_error_reporting)) == IS_UNDEF) {
+                       ZVAL_NEW_STR(&EX(old_error_reporting), EG(error_reporting_ini_entry)->value);
+               }
+               if (EG(error_reporting)) {
+                       EG(error_reporting) = 0;
                        if (!EG(error_reporting_ini_entry)->modified) {
                                if (!EG(modified_ini_directives)) {
                                        ALLOC_HASHTABLE(EG(modified_ini_directives));
@@ -1142,9 +1147,8 @@ static int ZEND_FASTCALL  ZEND_BEGIN_SILENCE_SPEC_HANDLER(ZEND_OPCODE_HANDLER_AR
                        } else {
                                EG(error_reporting_ini_entry)->value = zend_string_init("0", sizeof("0")-1, 0);
                        }
-               } while (0);
-       }
-       CHECK_EXCEPTION();
+               }
+       } while (0);
        ZEND_VM_NEXT_OPCODE();
 }
 
@@ -1367,18 +1371,19 @@ static int ZEND_FASTCALL  ZEND_HANDLE_EXCEPTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER
        }
 
        /* restore previous error_reporting value */
-       if (!EG(error_reporting) && Z_TYPE(EX(old_error_reporting)) != IS_UNDEF && Z_LVAL(EX(old_error_reporting)) != 0) {
-               zval restored_error_reporting;
-               zend_string *key;
+       if (Z_TYPE(EX(old_error_reporting)) != IS_UNDEF) {
+               if (!EG(error_reporting)) {
+                       zend_string *key;
 
-               ZVAL_LONG(&restored_error_reporting, Z_LVAL(EX(old_error_reporting)));
-               convert_to_string(&restored_error_reporting);
-               key = zend_string_init("error_reporting", sizeof("error_reporting")-1, 0);
-               zend_alter_ini_entry_ex(key, Z_STR(restored_error_reporting), ZEND_INI_USER, ZEND_INI_STAGE_RUNTIME, 1 TSRMLS_CC);
-               zend_string_free(key);
-               zval_dtor(&restored_error_reporting);
+                       key = zend_string_init("error_reporting", sizeof("error_reporting")-1, 0);
+                       zend_alter_ini_entry_ex(key, Z_STR(EX(old_error_reporting)), ZEND_INI_USER, ZEND_INI_STAGE_RUNTIME, 1 TSRMLS_CC);
+                       zend_string_free(key);
+               }
+               if (Z_STR(EX(old_error_reporting))) {
+                       zend_string_release(Z_STR(EX(old_error_reporting)));
+               }
+               ZVAL_UNDEF(&EX(old_error_reporting));
        }
-       ZVAL_UNDEF(&EX(old_error_reporting));
 
        if (finally_op_num && (!catch_op_num || catch_op_num >= finally_op_num)) {
                if (EX(delayed_exception)) {
@@ -10032,25 +10037,30 @@ static int ZEND_FASTCALL  ZEND_EXIT_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 static int ZEND_FASTCALL  ZEND_END_SILENCE_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
        USE_OPLINE
-       char buf[MAX_LENGTH_OF_LONG + 1];
-       char *res;
 
        SAVE_OPLINE();
-       if (!EG(error_reporting) && Z_LVAL_P(EX_VAR(opline->op1.var)) != 0) {
-               EG(error_reporting) = Z_LVAL_P(EX_VAR(opline->op1.var));
-               _zend_print_signed_to_buf(buf + sizeof(buf) - 1, EG(error_reporting), zend_ulong, res);
-               if (EXPECTED(EG(error_reporting_ini_entry) != NULL)) {
+       if (!EG(error_reporting)) {
+               EG(error_reporting) = EX_VAR(opline->op1.var)->u2.error_reporting;
+               if (EXPECTED(Z_TYPE_P(EX_VAR(opline->op1.var)) == IS_STRING)) {
                        if (EXPECTED(EG(error_reporting_ini_entry)->modified &&
                            EG(error_reporting_ini_entry)->value != EG(error_reporting_ini_entry)->orig_value)) {
                                zend_string_release(EG(error_reporting_ini_entry)->value);
                        }
-                       EG(error_reporting_ini_entry)->value = zend_string_init(res, buf + sizeof(buf) - 1 - res, 0);
+                       EG(error_reporting_ini_entry)->value = Z_STR_P(EX_VAR(opline->op1.var));
+                       if (Z_TYPE(EX(old_error_reporting)) != IS_UNDEF &&
+                           Z_STR(EX(old_error_reporting)) == EG(error_reporting_ini_entry)->value) {
+                               ZVAL_UNDEF(&EX(old_error_reporting));
+                       }
+               }
+       } else {
+               if (EXPECTED(Z_TYPE_P(EX_VAR(opline->op1.var)) == IS_STRING)) {
+                       zend_string_release(Z_STR_P(EX_VAR(opline->op1.var)));
+                       if (Z_TYPE(EX(old_error_reporting)) != IS_UNDEF &&
+                           Z_STR(EX(old_error_reporting)) == Z_STR_P(EX_VAR(opline->op1.var))) {
+                               ZVAL_UNDEF(&EX(old_error_reporting));
+                       }
                }
        }
-//???  if (EX(old_error_reporting) == EX_VAR(opline->op1.var)) {
-//???          EX(old_error_reporting) = NULL;
-//???  }
-       CHECK_EXCEPTION();
        ZEND_VM_NEXT_OPCODE();
 }