diff options
Diffstat (limited to 'Zend/zend_vm_execute.h')
-rw-r--r-- | Zend/zend_vm_execute.h | 228 |
1 files changed, 106 insertions, 122 deletions
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index b1bcd74d23..0fcae113ba 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -339,7 +339,7 @@ static opcode_handler_t zend_vm_get_opcode_handler(zend_uchar opcode, zend_op* o #define EX_Ts() EX(Ts) -static zend_execute_data *zend_create_execute_data_from_op_array(zend_op_array *op_array, zend_bool nested TSRMLS_DC) { +zend_execute_data *zend_create_execute_data_from_op_array(zend_op_array *op_array, zend_bool nested TSRMLS_DC) { zend_execute_data *execute_data; /* @@ -689,7 +689,11 @@ static int ZEND_FASTCALL zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_AR ret->var.fcall_returned_reference = (fbc->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0; } - if (EXPECTED(zend_execute == execute)) { + if (EG(active_op_array)->fn_flags & ZEND_ACC_GENERATOR) { + if (RETURN_VALUE_USED(opline)) { + EX_T(opline->result.var).var.ptr = zend_generator_create_zval(EG(active_op_array) TSRMLS_CC); + } + } else if (EXPECTED(zend_execute == execute)) { if (EXPECTED(EG(exception) == NULL)) { ZEND_VM_ENTER(); } @@ -1201,101 +1205,6 @@ static int ZEND_FASTCALL ZEND_USER_OPCODE_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS } } -static int ZEND_FASTCALL ZEND_SUSPEND_AND_RETURN_GENERATOR_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - zend_bool nested = EX(nested); - zend_execute_data *prev_execute_data = EX(prev_execute_data); - - if (EG(return_value_ptr_ptr)) { - zval *return_value; - zend_generator *generator; - - ALLOC_INIT_ZVAL(return_value); - object_init_ex(return_value, zend_ce_generator); - - *EG(return_value_ptr_ptr) = return_value; - - /* back up some executor globals */ - SAVE_OPLINE(); - - EX(current_scope) = EG(scope); - EX(current_called_scope) = EG(called_scope); - - if (EG(This)) { - Z_ADDREF_P(EG(This)); - } - EX(current_this) = EG(This); - - /* back up the execution context */ - generator = (zend_generator *) zend_object_store_get_object(return_value TSRMLS_CC); - generator->execute_data = execute_data; - - /* We have to add another stack frame so the generator function shows - * up in backtraces and func_get_all() can access the function - * arguments. */ - EX(prev_execute_data) = emalloc(sizeof(zend_execute_data)); - if (prev_execute_data) { - memcpy(EX(prev_execute_data), prev_execute_data, sizeof(zend_execute_data)); - EX(prev_execute_data)->function_state.arguments = zend_copy_arguments(prev_execute_data->function_state.arguments); - } else { - memset(EX(prev_execute_data), 0, sizeof(zend_execute_data)); - EX(prev_execute_data)->function_state.function = (zend_function *) EX(op_array); - EX(prev_execute_data)->function_state.arguments = NULL; - } - } - - /* restore the previous execution context */ - EG(current_execute_data) = prev_execute_data; - - /* if there is no return value pointer we are responsible for freeing the - * execution data */ - if (!EG(return_value_ptr_ptr)) { - if (!EG(active_symbol_table)) { - zend_free_compiled_variables(EX_CVs(), execute_data->op_array->last_var); - } else { - zend_clean_and_cache_symbol_table(EG(active_symbol_table) TSRMLS_CC); - } - efree(execute_data); - } - - - /* Happens whenever the function is invoked using call_user_function, - * e.g. when doing a dynamic function call using call_user_func(). */ - if (!nested) { - EG(opline_ptr) = NULL; - ZEND_VM_RETURN(); - } - - /* Free $this and stack arguments */ - if (EG(This)) { - zval_ptr_dtor(&EG(This)); - } - - zend_vm_stack_clear_multiple(TSRMLS_C); - - /* Bring back the previous execution context */ - execute_data = EG(current_execute_data); - - EG(opline_ptr) = &EX(opline); - EG(active_op_array) = EX(op_array); - EG(return_value_ptr_ptr) = EX(original_return_value); - EG(active_symbol_table) = EX(symbol_table); - EG(This) = EX(current_this); - EG(scope) = EX(current_scope); - EG(called_scope) = EX(current_called_scope); - - EX(function_state).function = (zend_function *) EX(op_array); - EX(function_state).arguments = NULL; - - EX(object) = EX(current_object); - EX(called_scope) = DECODE_CTOR(EX(called_scope)); - - LOAD_REGS(); - LOAD_OPLINE(); - ZEND_VM_INC_OPCODE(); - ZEND_VM_LEAVE(); -} - static int ZEND_FASTCALL ZEND_FETCH_CLASS_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -4252,6 +4161,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLE Z_ADDREF(EG(uninitialized_zval)); AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + /* We increment to the next op, so we are at the correct position when the + * generator is resumed. */ + ZEND_VM_INC_OPCODE(); + /* The GOTO VM uses a local opline variable. We need to set the opline * variable in execute_data so we don't resume at an old position. */ SAVE_OPLINE(); @@ -4937,6 +4850,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ Z_ADDREF(EG(uninitialized_zval)); AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + /* We increment to the next op, so we are at the correct position when the + * generator is resumed. */ + ZEND_VM_INC_OPCODE(); + /* The GOTO VM uses a local opline variable. We need to set the opline * variable in execute_data so we don't resume at an old position. */ SAVE_OPLINE(); @@ -5948,6 +5865,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ Z_ADDREF(EG(uninitialized_zval)); AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + /* We increment to the next op, so we are at the correct position when the + * generator is resumed. */ + ZEND_VM_INC_OPCODE(); + /* The GOTO VM uses a local opline variable. We need to set the opline * variable in execute_data so we don't resume at an old position. */ SAVE_OPLINE(); @@ -6652,6 +6573,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDL Z_ADDREF(EG(uninitialized_zval)); AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + /* We increment to the next op, so we are at the correct position when the + * generator is resumed. */ + ZEND_VM_INC_OPCODE(); + /* The GOTO VM uses a local opline variable. We need to set the opline * variable in execute_data so we don't resume at an old position. */ SAVE_OPLINE(); @@ -7396,6 +7321,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_A Z_ADDREF(EG(uninitialized_zval)); AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + /* We increment to the next op, so we are at the correct position when the + * generator is resumed. */ + ZEND_VM_INC_OPCODE(); + /* The GOTO VM uses a local opline variable. We need to set the opline * variable in execute_data so we don't resume at an old position. */ SAVE_OPLINE(); @@ -9448,6 +9377,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ Z_ADDREF(EG(uninitialized_zval)); AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + /* We increment to the next op, so we are at the correct position when the + * generator is resumed. */ + ZEND_VM_INC_OPCODE(); + /* The GOTO VM uses a local opline variable. We need to set the opline * variable in execute_data so we don't resume at an old position. */ SAVE_OPLINE(); @@ -10133,6 +10066,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR Z_ADDREF(EG(uninitialized_zval)); AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + /* We increment to the next op, so we are at the correct position when the + * generator is resumed. */ + ZEND_VM_INC_OPCODE(); + /* The GOTO VM uses a local opline variable. We need to set the opline * variable in execute_data so we don't resume at an old position. */ SAVE_OPLINE(); @@ -11144,6 +11081,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR Z_ADDREF(EG(uninitialized_zval)); AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + /* We increment to the next op, so we are at the correct position when the + * generator is resumed. */ + ZEND_VM_INC_OPCODE(); + /* The GOTO VM uses a local opline variable. We need to set the opline * variable in execute_data so we don't resume at an old position. */ SAVE_OPLINE(); @@ -11714,6 +11655,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER Z_ADDREF(EG(uninitialized_zval)); AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + /* We increment to the next op, so we are at the correct position when the + * generator is resumed. */ + ZEND_VM_INC_OPCODE(); + /* The GOTO VM uses a local opline variable. We need to set the opline * variable in execute_data so we don't resume at an old position. */ SAVE_OPLINE(); @@ -12396,6 +12341,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG Z_ADDREF(EG(uninitialized_zval)); AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + /* We increment to the next op, so we are at the correct position when the + * generator is resumed. */ + ZEND_VM_INC_OPCODE(); + /* The GOTO VM uses a local opline variable. We need to set the opline * variable in execute_data so we don't resume at an old position. */ SAVE_OPLINE(); @@ -16306,6 +16255,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ Z_ADDREF(EG(uninitialized_zval)); AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + /* We increment to the next op, so we are at the correct position when the + * generator is resumed. */ + ZEND_VM_INC_OPCODE(); + /* The GOTO VM uses a local opline variable. We need to set the opline * variable in execute_data so we don't resume at an old position. */ SAVE_OPLINE(); @@ -18379,6 +18332,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR Z_ADDREF(EG(uninitialized_zval)); AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + /* We increment to the next op, so we are at the correct position when the + * generator is resumed. */ + ZEND_VM_INC_OPCODE(); + /* The GOTO VM uses a local opline variable. We need to set the opline * variable in execute_data so we don't resume at an old position. */ SAVE_OPLINE(); @@ -20833,6 +20790,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR Z_ADDREF(EG(uninitialized_zval)); AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + /* We increment to the next op, so we are at the correct position when the + * generator is resumed. */ + ZEND_VM_INC_OPCODE(); + /* The GOTO VM uses a local opline variable. We need to set the opline * variable in execute_data so we don't resume at an old position. */ SAVE_OPLINE(); @@ -21964,6 +21925,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER Z_ADDREF(EG(uninitialized_zval)); AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + /* We increment to the next op, so we are at the correct position when the + * generator is resumed. */ + ZEND_VM_INC_OPCODE(); + /* The GOTO VM uses a local opline variable. We need to set the opline * variable in execute_data so we don't resume at an old position. */ SAVE_OPLINE(); @@ -24086,6 +24051,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG Z_ADDREF(EG(uninitialized_zval)); AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + /* We increment to the next op, so we are at the correct position when the + * generator is resumed. */ + ZEND_VM_INC_OPCODE(); + /* The GOTO VM uses a local opline variable. We need to set the opline * variable in execute_data so we don't resume at an old position. */ SAVE_OPLINE(); @@ -25565,6 +25534,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDL Z_ADDREF(EG(uninitialized_zval)); AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + /* We increment to the next op, so we are at the correct position when the + * generator is resumed. */ + ZEND_VM_INC_OPCODE(); + /* The GOTO VM uses a local opline variable. We need to set the opline * variable in execute_data so we don't resume at an old position. */ SAVE_OPLINE(); @@ -26868,6 +26841,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER Z_ADDREF(EG(uninitialized_zval)); AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + /* We increment to the next op, so we are at the correct position when the + * generator is resumed. */ + ZEND_VM_INC_OPCODE(); + /* The GOTO VM uses a local opline variable. We need to set the opline * variable in execute_data so we don't resume at an old position. */ SAVE_OPLINE(); @@ -28172,6 +28149,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HANDLER Z_ADDREF(EG(uninitialized_zval)); AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + /* We increment to the next op, so we are at the correct position when the + * generator is resumed. */ + ZEND_VM_INC_OPCODE(); + /* The GOTO VM uses a local opline variable. We need to set the opline * variable in execute_data so we don't resume at an old position. */ SAVE_OPLINE(); @@ -28586,6 +28567,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HAND Z_ADDREF(EG(uninitialized_zval)); AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + /* We increment to the next op, so we are at the correct position when the + * generator is resumed. */ + ZEND_VM_INC_OPCODE(); + /* The GOTO VM uses a local opline variable. We need to set the opline * variable in execute_data so we don't resume at an old position. */ SAVE_OPLINE(); @@ -29886,6 +29871,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ Z_ADDREF(EG(uninitialized_zval)); AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + /* We increment to the next op, so we are at the correct position when the + * generator is resumed. */ + ZEND_VM_INC_OPCODE(); + /* The GOTO VM uses a local opline variable. We need to set the opline * variable in execute_data so we don't resume at an old position. */ SAVE_OPLINE(); @@ -33395,6 +33384,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_A Z_ADDREF(EG(uninitialized_zval)); AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + /* We increment to the next op, so we are at the correct position when the + * generator is resumed. */ + ZEND_VM_INC_OPCODE(); + /* The GOTO VM uses a local opline variable. We need to set the opline * variable in execute_data so we don't resume at an old position. */ SAVE_OPLINE(); @@ -35337,6 +35330,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG Z_ADDREF(EG(uninitialized_zval)); AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + /* We increment to the next op, so we are at the correct position when the + * generator is resumed. */ + ZEND_VM_INC_OPCODE(); + /* The GOTO VM uses a local opline variable. We need to set the opline * variable in execute_data so we don't resume at an old position. */ SAVE_OPLINE(); @@ -37659,6 +37656,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG Z_ADDREF(EG(uninitialized_zval)); AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + /* We increment to the next op, so we are at the correct position when the + * generator is resumed. */ + ZEND_VM_INC_OPCODE(); + /* The GOTO VM uses a local opline variable. We need to set the opline * variable in execute_data so we don't resume at an old position. */ SAVE_OPLINE(); @@ -38649,6 +38650,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ Z_ADDREF(EG(uninitialized_zval)); AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + /* We increment to the next op, so we are at the correct position when the + * generator is resumed. */ + ZEND_VM_INC_OPCODE(); + /* The GOTO VM uses a local opline variable. We need to set the opline * variable in execute_data so we don't resume at an old position. */ SAVE_OPLINE(); @@ -40639,6 +40644,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS Z_ADDREF(EG(uninitialized_zval)); AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + /* We increment to the next op, so we are at the correct position when the + * generator is resumed. */ + ZEND_VM_INC_OPCODE(); + /* The GOTO VM uses a local opline variable. We need to set the opline * variable in execute_data so we don't resume at an old position. */ SAVE_OPLINE(); @@ -44630,31 +44639,6 @@ 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_SUSPEND_AND_RETURN_GENERATOR_SPEC_HANDLER, - ZEND_SUSPEND_AND_RETURN_GENERATOR_SPEC_HANDLER, - ZEND_SUSPEND_AND_RETURN_GENERATOR_SPEC_HANDLER, - ZEND_SUSPEND_AND_RETURN_GENERATOR_SPEC_HANDLER, - ZEND_SUSPEND_AND_RETURN_GENERATOR_SPEC_HANDLER, - ZEND_SUSPEND_AND_RETURN_GENERATOR_SPEC_HANDLER, - ZEND_SUSPEND_AND_RETURN_GENERATOR_SPEC_HANDLER, - ZEND_SUSPEND_AND_RETURN_GENERATOR_SPEC_HANDLER, - ZEND_SUSPEND_AND_RETURN_GENERATOR_SPEC_HANDLER, - ZEND_SUSPEND_AND_RETURN_GENERATOR_SPEC_HANDLER, - ZEND_SUSPEND_AND_RETURN_GENERATOR_SPEC_HANDLER, - ZEND_SUSPEND_AND_RETURN_GENERATOR_SPEC_HANDLER, - ZEND_SUSPEND_AND_RETURN_GENERATOR_SPEC_HANDLER, - ZEND_SUSPEND_AND_RETURN_GENERATOR_SPEC_HANDLER, - ZEND_SUSPEND_AND_RETURN_GENERATOR_SPEC_HANDLER, - ZEND_SUSPEND_AND_RETURN_GENERATOR_SPEC_HANDLER, - ZEND_SUSPEND_AND_RETURN_GENERATOR_SPEC_HANDLER, - ZEND_SUSPEND_AND_RETURN_GENERATOR_SPEC_HANDLER, - ZEND_SUSPEND_AND_RETURN_GENERATOR_SPEC_HANDLER, - ZEND_SUSPEND_AND_RETURN_GENERATOR_SPEC_HANDLER, - ZEND_SUSPEND_AND_RETURN_GENERATOR_SPEC_HANDLER, - ZEND_SUSPEND_AND_RETURN_GENERATOR_SPEC_HANDLER, - ZEND_SUSPEND_AND_RETURN_GENERATOR_SPEC_HANDLER, - ZEND_SUSPEND_AND_RETURN_GENERATOR_SPEC_HANDLER, - ZEND_SUSPEND_AND_RETURN_GENERATOR_SPEC_HANDLER, ZEND_YIELD_SPEC_CONST_CONST_HANDLER, ZEND_YIELD_SPEC_CONST_TMP_HANDLER, ZEND_YIELD_SPEC_CONST_VAR_HANDLER, |