]> granicus.if.org Git - php/commitdiff
Merge branch 'PHP-7.2' into PHP-7.3
authorNikita Popov <nikita.ppv@gmail.com>
Thu, 29 Aug 2019 10:32:23 +0000 (12:32 +0200)
committerNikita Popov <nikita.ppv@gmail.com>
Thu, 29 Aug 2019 10:33:04 +0000 (12:33 +0200)
1  2 
Zend/zend_vm_def.h
Zend/zend_vm_execute.h

index 0bedf907a2846f68c2c192f005669e78ab83e951,df0a3d98124487f33078b37fff09e37599a918b2..99b731b11a94c4542ce9745e814738c5cd0ba1cf
@@@ -2442,10 -2415,9 +2447,9 @@@ ZEND_VM_HOT_HELPER(zend_leave_helper, A
                        }
                        OBJ_RELEASE(object);
                } else if (UNEXPECTED(call_info & ZEND_CALL_CLOSURE)) {
 -                      OBJ_RELEASE((zend_object*)execute_data->func->op_array.prototype);
 +                      OBJ_RELEASE(ZEND_CLOSURE_OBJECT(EX(func)));
                }
  
-               zend_vm_stack_free_extra_args_ex(call_info, execute_data);
                old_execute_data = execute_data;
                execute_data = EX(prev_execute_data);
                zend_vm_stack_free_call_frame_ex(call_info, old_execute_data);
index 1c95ac57a0fa3a28adb5bcd14e405c9d1b582f0b,28fc5dabe44d1ff1c939a2d4e05cd58117f47a1f..b29f5bddc6c2cd18eb4120e7b1b3868a765de3eb
@@@ -553,10 -485,9 +558,9 @@@ static ZEND_OPCODE_HANDLER_RET ZEND_FAS
                        }
                        OBJ_RELEASE(object);
                } else if (UNEXPECTED(call_info & ZEND_CALL_CLOSURE)) {
 -                      OBJ_RELEASE((zend_object*)execute_data->func->op_array.prototype);
 +                      OBJ_RELEASE(ZEND_CLOSURE_OBJECT(EX(func)));
                }
  
-               zend_vm_stack_free_extra_args_ex(call_info, execute_data);
                old_execute_data = execute_data;
                execute_data = EX(prev_execute_data);
                zend_vm_stack_free_call_frame_ex(call_info, old_execute_data);
@@@ -55335,125 -59744,7 +55339,129 @@@ ZEND_API void execute_ex(zend_execute_d
  #endif
  #endif
  #if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)
-               zend_vm_stack_free_extra_args_ex(call_info, execute_data);
 +zend_leave_helper_SPEC_LABEL:
 +{
 +      zend_execute_data *old_execute_data;
 +      uint32_t call_info = EX_CALL_INFO();
 +
 +      if (EXPECTED((call_info & (ZEND_CALL_CODE|ZEND_CALL_TOP|ZEND_CALL_HAS_SYMBOL_TABLE|ZEND_CALL_FREE_EXTRA_ARGS|ZEND_CALL_ALLOCATED)) == 0)) {
 +              i_free_compiled_variables(execute_data);
 +
 +              EG(current_execute_data) = EX(prev_execute_data);
 +              if (UNEXPECTED(call_info & ZEND_CALL_RELEASE_THIS)) {
 +                      zend_object *object = Z_OBJ(execute_data->This);
 +#if 0
 +                      if (UNEXPECTED(EG(exception) != NULL) && (EX(opline)->op1.num & ZEND_CALL_CTOR)) {
 +#else
 +                      if (UNEXPECTED(EG(exception) != NULL) && (call_info & ZEND_CALL_CTOR)) {
 +#endif
 +                              GC_DELREF(object);
 +                              zend_object_store_ctor_failed(object);
 +                      }
 +                      OBJ_RELEASE(object);
 +              } else if (UNEXPECTED(call_info & ZEND_CALL_CLOSURE)) {
 +                      OBJ_RELEASE(ZEND_CLOSURE_OBJECT(EX(func)));
 +              }
 +              EG(vm_stack_top) = (zval*)execute_data;
 +              execute_data = EX(prev_execute_data);
 +
 +              if (UNEXPECTED(EG(exception) != NULL)) {
 +                      zend_rethrow_exception(execute_data);
 +                      HANDLE_EXCEPTION_LEAVE();
 +              }
 +
 +              LOAD_NEXT_OPLINE();
 +              ZEND_VM_LEAVE();
 +      } else if (EXPECTED((call_info & (ZEND_CALL_CODE|ZEND_CALL_TOP)) == 0)) {
 +              i_free_compiled_variables(execute_data);
 +
 +              if (UNEXPECTED(call_info & ZEND_CALL_HAS_SYMBOL_TABLE)) {
 +                      zend_clean_and_cache_symbol_table(EX(symbol_table));
 +              }
 +              EG(current_execute_data) = EX(prev_execute_data);
++
++              /* Free extra args before releasing the closure,
++               * as that may free the op_array. */
++              zend_vm_stack_free_extra_args_ex(call_info, execute_data);
++
 +              if (UNEXPECTED(call_info & ZEND_CALL_RELEASE_THIS)) {
 +                      zend_object *object = Z_OBJ(execute_data->This);
 +#if 0
 +                      if (UNEXPECTED(EG(exception) != NULL) && (EX(opline)->op1.num & ZEND_CALL_CTOR)) {
 +#else
 +                      if (UNEXPECTED(EG(exception) != NULL) && (call_info & ZEND_CALL_CTOR)) {
 +#endif
 +                              GC_DELREF(object);
 +                              zend_object_store_ctor_failed(object);
 +                      }
 +                      OBJ_RELEASE(object);
 +              } else if (UNEXPECTED(call_info & ZEND_CALL_CLOSURE)) {
 +                      OBJ_RELEASE(ZEND_CLOSURE_OBJECT(EX(func)));
 +              }
 +
 +              old_execute_data = execute_data;
 +              execute_data = EX(prev_execute_data);
 +              zend_vm_stack_free_call_frame_ex(call_info, old_execute_data);
 +
 +              if (UNEXPECTED(EG(exception) != NULL)) {
 +                      zend_rethrow_exception(execute_data);
 +                      HANDLE_EXCEPTION_LEAVE();
 +              }
 +
 +              LOAD_NEXT_OPLINE();
 +              ZEND_VM_LEAVE();
 +      } else if (EXPECTED((call_info & ZEND_CALL_TOP) == 0)) {
 +              zend_detach_symbol_table(execute_data);
 +              destroy_op_array(&EX(func)->op_array);
 +              efree_size(EX(func), sizeof(zend_op_array));
 +              old_execute_data = execute_data;
 +              execute_data = EG(current_execute_data) = EX(prev_execute_data);
 +              zend_vm_stack_free_call_frame_ex(call_info, old_execute_data);
 +
 +              zend_attach_symbol_table(execute_data);
 +              if (UNEXPECTED(EG(exception) != NULL)) {
 +                      zend_rethrow_exception(execute_data);
 +                      HANDLE_EXCEPTION_LEAVE();
 +              }
 +
 +              LOAD_NEXT_OPLINE();
 +              ZEND_VM_LEAVE();
 +      } else {
 +              if (EXPECTED((call_info & ZEND_CALL_CODE) == 0)) {
 +                      i_free_compiled_variables(execute_data);
 +                      if (UNEXPECTED(call_info & (ZEND_CALL_HAS_SYMBOL_TABLE|ZEND_CALL_FREE_EXTRA_ARGS))) {
 +                              if (UNEXPECTED(call_info & ZEND_CALL_HAS_SYMBOL_TABLE)) {
 +                                      zend_clean_and_cache_symbol_table(EX(symbol_table));
 +                              }
 +                              zend_vm_stack_free_extra_args_ex(call_info, execute_data);
 +                      }
 +                      EG(current_execute_data) = EX(prev_execute_data);
 +                      if (UNEXPECTED(call_info & ZEND_CALL_CLOSURE)) {
 +                              OBJ_RELEASE(ZEND_CLOSURE_OBJECT(EX(func)));
 +                      }
 +                      ZEND_VM_RETURN();
 +              } else /* if (call_kind == ZEND_CALL_TOP_CODE) */ {
 +                      zend_array *symbol_table = EX(symbol_table);
 +
 +                      zend_detach_symbol_table(execute_data);
 +                      old_execute_data = EX(prev_execute_data);
 +                      while (old_execute_data) {
 +                              if (old_execute_data->func && (ZEND_CALL_INFO(old_execute_data) & ZEND_CALL_HAS_SYMBOL_TABLE)) {
 +                                      if (old_execute_data->symbol_table == symbol_table) {
 +                                              zend_attach_symbol_table(old_execute_data);
 +                                      }
 +                                      break;
 +                              }
 +                              old_execute_data = old_execute_data->prev_execute_data;
 +                      }
 +                      EG(current_execute_data) = EX(prev_execute_data);
 +                      ZEND_VM_RETURN();
 +              }
 +      }
 +}
 +
                        HYBRID_CASE(ZEND_JMP_SPEC):
 +                              VM_TRACE(ZEND_JMP_SPEC)
                                ZEND_JMP_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
                                HYBRID_BREAK();
                        HYBRID_CASE(ZEND_DO_ICALL_SPEC_RETVAL_UNUSED):