diff options
| author | Dmitry Stogov <dmitry@zend.com> | 2015-03-12 20:39:04 +0300 | 
|---|---|---|
| committer | Dmitry Stogov <dmitry@zend.com> | 2015-03-12 20:39:04 +0300 | 
| commit | 6289f7e52f07d411bce0a0a99fe65bfbe87e4290 (patch) | |
| tree | 4f1e75fedc250e79e301f4a7cede2afd6117ecc8 | |
| parent | 41571e7fa97feb2f43fc1ed3844daada35a29587 (diff) | |
| download | php-git-6289f7e52f07d411bce0a0a99fe65bfbe87e4290.tar.gz | |
Executor cleanup: fix GOTO and SWITCH VMs, remove aility to build additional PHP-5.0 compatible VM, hide executor implementation details.
| -rw-r--r-- | Zend/zend_compile.h | 10 | ||||
| -rw-r--r-- | Zend/zend_execute.c | 12 | ||||
| -rw-r--r-- | Zend/zend_execute.h | 2 | ||||
| -rw-r--r-- | Zend/zend_vm_def.h | 29 | ||||
| -rw-r--r-- | Zend/zend_vm_execute.h | 149 | ||||
| -rw-r--r-- | Zend/zend_vm_gen.php | 134 | ||||
| -rw-r--r-- | ext/opcache/Optimizer/zend_optimizer_internal.h | 2 | 
7 files changed, 169 insertions, 169 deletions
diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index 8e4148795e..42f55f9521 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -129,16 +129,10 @@ void zend_compile_var(znode *node, zend_ast *ast, uint32_t type);  void zend_eval_const_expr(zend_ast **ast_ptr);  void zend_const_expr_to_zval(zval *result, zend_ast *ast); -#define ZEND_OPCODE_HANDLER_ARGS zend_execute_data *execute_data -#define ZEND_OPCODE_HANDLER_ARGS_PASSTHRU execute_data - -typedef int (*user_opcode_handler_t) (ZEND_OPCODE_HANDLER_ARGS); -typedef int (ZEND_FASTCALL *opcode_handler_t) (ZEND_OPCODE_HANDLER_ARGS); - -extern ZEND_API opcode_handler_t *zend_opcode_handlers; +typedef int (*user_opcode_handler_t) (zend_execute_data *execute_data);  struct _zend_op { -	opcode_handler_t handler; +	const void *handler;  	znode_op op1;  	znode_op op2;  	znode_op result; diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 59e585e35b..4a8b4694b7 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -411,9 +411,10 @@ static zend_always_inline zval *_get_zval_ptr(int op_type, znode_op node, const  		*should_free = NULL;  		if (op_type == IS_CONST) {  			return EX_CONSTANT(node); -		} else { -			ZEND_ASSERT(op_type == IS_CV); +		} else if (op_type == IS_CV) {  			return _get_zval_ptr_cv(execute_data, node.var, type); +		} else { +			return NULL;  		}  	}  } @@ -431,9 +432,10 @@ static zend_always_inline zval *_get_zval_ptr_deref(int op_type, znode_op node,  		*should_free = NULL;  		if (op_type == IS_CONST) {  			return EX_CONSTANT(node); -		} else { -			ZEND_ASSERT(op_type == IS_CV); +		} else if (op_type == IS_CV) {  			return _get_zval_ptr_cv_deref(execute_data, node.var, type); +		} else { +			return NULL;  		}  	}  } @@ -1688,8 +1690,6 @@ static int zend_check_symbol(zval *pz)  #define CHECK_SYMBOL_TABLES()  #endif -ZEND_API opcode_handler_t *zend_opcode_handlers; -  ZEND_API void execute_internal(zend_execute_data *execute_data, zval *return_value)  {  	execute_data->func->internal_function.handler(execute_data, return_value); diff --git a/Zend/zend_execute.h b/Zend/zend_execute.h index d33735291a..0149da6929 100644 --- a/Zend/zend_execute.h +++ b/Zend/zend_execute.h @@ -252,8 +252,6 @@ typedef zval* zend_free_op;  ZEND_API zval *zend_get_zval_ptr(int op_type, const znode_op *node, const zend_execute_data *execute_data, zend_free_op *should_free, int type); -ZEND_API int zend_do_fcall(ZEND_OPCODE_HANDLER_ARGS); -  ZEND_API void zend_clean_and_cache_symbol_table(zend_array *symbol_table);  void zend_free_compiled_variables(zend_execute_data *execute_data); diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index ffb737d2a2..09de8b2f4c 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -353,11 +353,14 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_obj_helper, VAR|UNUSED|CV, CONST|TMPVAR|  {  	USE_OPLINE  	zend_free_op free_op1, free_op2, free_op_data1; -	zval *object = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_RW); -	zval *property = GET_OP2_ZVAL_PTR(BP_VAR_R); +	zval *object; +	zval *property;  	zval *value;  	zval *zptr; +	SAVE_OPLINE(); +	object = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_RW); +	property = GET_OP2_ZVAL_PTR(BP_VAR_R);  	if (OP1_TYPE == IS_VAR && UNEXPECTED(object == NULL)) {  		zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an object");  		FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var); @@ -2805,13 +2808,15 @@ ZEND_VM_HANDLER(118, ZEND_INIT_USER_CALL, CONST, CONST|TMPVAR|CV)  {  	USE_OPLINE  	zend_free_op free_op2; -	zval *function_name = GET_OP2_ZVAL_PTR(BP_VAR_R); +	zval *function_name;  	zend_fcall_info_cache fcc;  	char *error = NULL;  	zend_function *func;  	zend_class_entry *called_scope;  	zend_object *object; +	SAVE_OPLINE(); +	function_name = GET_OP2_ZVAL_PTR(BP_VAR_R);  	if (zend_is_callable_ex(function_name, NULL, 0, NULL, &fcc, &error)) {  		if (error) {  			efree(error); @@ -2929,8 +2934,6 @@ ZEND_VM_HANDLER(129, ZEND_DO_ICALL, ANY, ANY)  	SAVE_OPLINE();  	EX(call) = call->prev_execute_data; -	LOAD_OPLINE(); -  	call->called_scope = EX(called_scope);  	Z_OBJ(call->This) = Z_OBJ(EX(This)); @@ -2977,8 +2980,6 @@ ZEND_VM_HANDLER(130, ZEND_DO_UCALL, ANY, ANY)  	SAVE_OPLINE();  	EX(call) = call->prev_execute_data; -	LOAD_OPLINE(); -  	EG(scope) = NULL;  	ret = NULL;  	call->symbol_table = NULL; @@ -3004,8 +3005,6 @@ ZEND_VM_HANDLER(131, ZEND_DO_FCALL_BY_NAME, ANY, ANY)  	SAVE_OPLINE();  	EX(call) = call->prev_execute_data; -	LOAD_OPLINE(); -  	if (EXPECTED(fbc->type == ZEND_USER_FUNCTION)) {  		EG(scope) = NULL;  		if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_GENERATOR) != 0)) { @@ -3562,6 +3561,7 @@ ZEND_VM_HANDLER(117, ZEND_SEND_VAR, VAR|CV, ANY)  	zval *varptr, *arg;  	zend_free_op free_op1; +	SAVE_OPLINE();  	varptr = GET_OP1_ZVAL_PTR(BP_VAR_R);  	arg = ZEND_CALL_VAR(EX(call), opline->result.var);  	if (Z_ISREF_P(varptr)) { @@ -3660,6 +3660,7 @@ ZEND_VM_HANDLER(66, ZEND_SEND_VAR_EX, VAR|CV, ANY)  	if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, opline->op2.num)) {  		ZEND_VM_DISPATCH_TO_HANDLER(ZEND_SEND_REF);  	} +	SAVE_OPLINE();  	varptr = GET_OP1_ZVAL_PTR(BP_VAR_R);  	arg = ZEND_CALL_VAR(EX(call), opline->result.var);  	if (Z_ISREF_P(varptr)) { @@ -3682,6 +3683,7 @@ ZEND_VM_HANDLER(165, ZEND_SEND_UNPACK, ANY, ANY)  	int arg_num;  	SAVE_OPLINE(); +	SAVE_OPLINE();  	args = GET_OP1_ZVAL_PTR(BP_VAR_R);  	arg_num = ZEND_CALL_NUM_ARGS(EX(call)) + 1; @@ -3846,6 +3848,7 @@ ZEND_VM_HANDLER(119, ZEND_SEND_ARRAY, ANY, ANY)  	zval *args;  	SAVE_OPLINE(); +	SAVE_OPLINE();  	args = GET_OP1_ZVAL_PTR(BP_VAR_R);  	if (UNEXPECTED(Z_TYPE_P(args) != IS_ARRAY)) { @@ -3969,6 +3972,7 @@ ZEND_VM_HANDLER(120, ZEND_SEND_USER, VAR|CV, ANY)  	zval *arg, *param, tmp;  	zend_free_op free_op1; +	SAVE_OPLINE();  	arg = GET_OP1_ZVAL_PTR(BP_VAR_R);  	param = ZEND_CALL_VAR(EX(call), opline->result.var); @@ -5289,7 +5293,6 @@ ZEND_VM_HANDLER(125, ZEND_FE_RESET_RW, CONST|TMP|VAR|CV, ANY)  ZEND_VM_HANDLER(78, ZEND_FE_FETCH_R, VAR, ANY)  {  	USE_OPLINE -	zend_free_op free_op1;  	zval *array;  	zval *value;  	HashTable *fe_ht; @@ -5449,7 +5452,6 @@ ZEND_VM_HANDLER(78, ZEND_FE_FETCH_R, VAR, ANY)  ZEND_VM_HANDLER(126, ZEND_FE_FETCH_RW, VAR, ANY)  {  	USE_OPLINE -	zend_free_op free_op1;  	zval *array;  	zval *value;  	HashTable *fe_ht; @@ -6485,7 +6487,7 @@ ZEND_VM_HANDLER(150, ZEND_USER_OPCODE, ANY, ANY)  	int ret;  	SAVE_OPLINE(); -	ret = zend_user_opcode_handlers[opline->opcode](ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_INTERNAL); +	ret = zend_user_opcode_handlers[opline->opcode](execute_data);  	LOAD_OPLINE();  	switch (ret) { @@ -6590,6 +6592,7 @@ ZEND_VM_HANDLER(160, ZEND_YIELD, CONST|TMP|VAR|CV|UNUSED, CONST|TMP|VAR|CV|UNUSE  	/* The generator object is stored in EX(return_value) */  	zend_generator *generator = (zend_generator *) EX(return_value); +	SAVE_OPLINE();  	if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {  		zend_error(E_EXCEPTION | E_ERROR, "Cannot yield from finally in a force-closed generator");  		FREE_UNFETCHED_OP2(); @@ -6728,6 +6731,7 @@ ZEND_VM_HANDLER(159, ZEND_DISCARD_EXCEPTION, ANY, ANY)  	/* check for delayed exception */  	if (Z_OBJ_P(fast_call) != NULL) { +		SAVE_OPLINE();  		/* discard the previously thrown exception */  		OBJ_RELEASE(Z_OBJ_P(fast_call));  		Z_OBJ_P(fast_call) = NULL; @@ -6990,4 +6994,3 @@ ZEND_VM_HANDLER(151, ZEND_ASSERT_CHECK, ANY, ANY)  	}  } -ZEND_VM_EXPORT_HANDLER(zend_do_fcall, ZEND_DO_FCALL) diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 66cbf0453a..b66e724358 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -306,9 +306,15 @@ static zend_uchar zend_user_opcodes[256] = {0,  	241,242,243,244,245,246,247,248,249,250,251,252,253,254,255  }; -static opcode_handler_t zend_vm_get_opcode_handler(zend_uchar opcode, const zend_op* op); +static const void **zend_opcode_handlers; +static const void *zend_vm_get_opcode_handler(zend_uchar opcode, const zend_op* op); +#define ZEND_OPCODE_HANDLER_ARGS zend_execute_data *execute_data +#define ZEND_OPCODE_HANDLER_ARGS_PASSTHRU execute_data + +typedef int (ZEND_FASTCALL *opcode_handler_t) (ZEND_OPCODE_HANDLER_ARGS); +  #undef OPLINE  #undef DCL_OPLINE  #undef USE_OPLINE @@ -329,9 +335,8 @@ static opcode_handler_t zend_vm_get_opcode_handler(zend_uchar opcode, const zend  #define ZEND_VM_RETURN()           return -1  #define ZEND_VM_ENTER()            return  1  #define ZEND_VM_LEAVE()            return  2 -#define ZEND_VM_DISPATCH(opcode, opline) return zend_vm_get_opcode_handler(opcode, opline)(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); +#define ZEND_VM_DISPATCH(opcode, opline) return ((opcode_handler_t)zend_vm_get_opcode_handler(opcode, opline))(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); -#define ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_INTERNAL execute_data  ZEND_API void execute_ex(zend_execute_data *execute_data)  { @@ -349,7 +354,7 @@ ZEND_API void execute_ex(zend_execute_data *execute_data)  		}  #endif -		if (UNEXPECTED((ret = OPLINE->handler(execute_data)) != 0)) { +		if (UNEXPECTED((ret = ((opcode_handler_t)OPLINE->handler)(execute_data)) != 0)) {  			if (EXPECTED(ret > 0)) {  				execute_data = EG(current_execute_data);  			} else { @@ -495,8 +500,6 @@ static int ZEND_FASTCALL  ZEND_DO_ICALL_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)  	SAVE_OPLINE();  	EX(call) = call->prev_execute_data; -	LOAD_OPLINE(); -  	call->called_scope = EX(called_scope);  	Z_OBJ(call->This) = Z_OBJ(EX(This)); @@ -543,8 +546,6 @@ static int ZEND_FASTCALL  ZEND_DO_UCALL_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)  	SAVE_OPLINE();  	EX(call) = call->prev_execute_data; -	LOAD_OPLINE(); -  	EG(scope) = NULL;  	ret = NULL;  	call->symbol_table = NULL; @@ -570,8 +571,6 @@ static int ZEND_FASTCALL  ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER(ZEND_OPCODE_HANDLER  	SAVE_OPLINE();  	EX(call) = call->prev_execute_data; -	LOAD_OPLINE(); -  	if (EXPECTED(fbc->type == ZEND_USER_FUNCTION)) {  		EG(scope) = NULL;  		if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_GENERATOR) != 0)) { @@ -885,6 +884,7 @@ static int ZEND_FASTCALL  ZEND_SEND_UNPACK_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS  	int arg_num;  	SAVE_OPLINE(); +	SAVE_OPLINE();  	args = get_zval_ptr(opline->op1_type, opline->op1, execute_data, &free_op1, BP_VAR_R);  	arg_num = ZEND_CALL_NUM_ARGS(EX(call)) + 1; @@ -1049,6 +1049,7 @@ static int ZEND_FASTCALL  ZEND_SEND_ARRAY_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)  	zval *args;  	SAVE_OPLINE(); +	SAVE_OPLINE();  	args = get_zval_ptr(opline->op1_type, opline->op1, execute_data, &free_op1, BP_VAR_R);  	if (UNEXPECTED(Z_TYPE_P(args) != IS_ARRAY)) { @@ -1621,7 +1622,7 @@ static int ZEND_FASTCALL  ZEND_USER_OPCODE_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS  	int ret;  	SAVE_OPLINE(); -	ret = zend_user_opcode_handlers[opline->opcode](ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_INTERNAL); +	ret = zend_user_opcode_handlers[opline->opcode](execute_data);  	LOAD_OPLINE();  	switch (ret) { @@ -1651,6 +1652,7 @@ static int ZEND_FASTCALL  ZEND_DISCARD_EXCEPTION_SPEC_HANDLER(ZEND_OPCODE_HANDLE  	/* check for delayed exception */  	if (Z_OBJ_P(fast_call) != NULL) { +		SAVE_OPLINE();  		/* discard the previously thrown exception */  		OBJ_RELEASE(Z_OBJ_P(fast_call));  		Z_OBJ_P(fast_call) = NULL; @@ -4685,13 +4687,15 @@ static int ZEND_FASTCALL  ZEND_INIT_USER_CALL_SPEC_CONST_CONST_HANDLER(ZEND_OPCO  {  	USE_OPLINE -	zval *function_name = EX_CONSTANT(opline->op2); +	zval *function_name;  	zend_fcall_info_cache fcc;  	char *error = NULL;  	zend_function *func;  	zend_class_entry *called_scope;  	zend_object *object; +	SAVE_OPLINE(); +	function_name = EX_CONSTANT(opline->op2);  	if (zend_is_callable_ex(function_name, NULL, 0, NULL, &fcc, &error)) {  		if (error) {  			efree(error); @@ -4769,7 +4773,7 @@ static int ZEND_FASTCALL  ZEND_FETCH_CONSTANT_SPEC_CONST_CONST_HANDLER(ZEND_OPCO  			if ((opline->extended_value & IS_CONSTANT_UNQUALIFIED) != 0) {  				char *actual = (char *)zend_memrchr(Z_STRVAL_P(EX_CONSTANT(opline->op2)), '\\', Z_STRLEN_P(EX_CONSTANT(opline->op2)));  				if (!actual) { -					ZVAL_STR(EX_VAR(opline->result.var), zend_string_copy(Z_STR_P(EX_CONSTANT(opline->op2)))); +					ZVAL_STR_COPY(EX_VAR(opline->result.var), Z_STR_P(EX_CONSTANT(opline->op2)));  				} else {  					actual++;  					ZVAL_STRINGL(EX_VAR(opline->result.var), @@ -5350,6 +5354,7 @@ static int ZEND_FASTCALL  ZEND_YIELD_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLE  	/* The generator object is stored in EX(return_value) */  	zend_generator *generator = (zend_generator *) EX(return_value); +	SAVE_OPLINE();  	if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {  		zend_error(E_EXCEPTION | E_ERROR, "Cannot yield from finally in a force-closed generator"); @@ -5533,6 +5538,7 @@ static int ZEND_FASTCALL  ZEND_YIELD_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_  	/* The generator object is stored in EX(return_value) */  	zend_generator *generator = (zend_generator *) EX(return_value); +	SAVE_OPLINE();  	if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {  		zend_error(E_EXCEPTION | E_ERROR, "Cannot yield from finally in a force-closed generator");  		zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); @@ -6051,6 +6057,7 @@ static int ZEND_FASTCALL  ZEND_YIELD_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_  	/* The generator object is stored in EX(return_value) */  	zend_generator *generator = (zend_generator *) EX(return_value); +	SAVE_OPLINE();  	if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {  		zend_error(E_EXCEPTION | E_ERROR, "Cannot yield from finally in a force-closed generator");  		zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); @@ -6878,6 +6885,7 @@ static int ZEND_FASTCALL  ZEND_YIELD_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDL  	/* The generator object is stored in EX(return_value) */  	zend_generator *generator = (zend_generator *) EX(return_value); +	SAVE_OPLINE();  	if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {  		zend_error(E_EXCEPTION | E_ERROR, "Cannot yield from finally in a force-closed generator"); @@ -7678,13 +7686,15 @@ static int ZEND_FASTCALL  ZEND_INIT_USER_CALL_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_  {  	USE_OPLINE -	zval *function_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); +	zval *function_name;  	zend_fcall_info_cache fcc;  	char *error = NULL;  	zend_function *func;  	zend_class_entry *called_scope;  	zend_object *object; +	SAVE_OPLINE(); +	function_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);  	if (zend_is_callable_ex(function_name, NULL, 0, NULL, &fcc, &error)) {  		if (error) {  			efree(error); @@ -8083,6 +8093,7 @@ static int ZEND_FASTCALL  ZEND_YIELD_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_A  	/* The generator object is stored in EX(return_value) */  	zend_generator *generator = (zend_generator *) EX(return_value); +	SAVE_OPLINE();  	if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {  		zend_error(E_EXCEPTION | E_ERROR, "Cannot yield from finally in a force-closed generator"); @@ -8869,13 +8880,15 @@ static int ZEND_FASTCALL  ZEND_INIT_USER_CALL_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPC  {  	USE_OPLINE  	zend_free_op free_op2; -	zval *function_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); +	zval *function_name;  	zend_fcall_info_cache fcc;  	char *error = NULL;  	zend_function *func;  	zend_class_entry *called_scope;  	zend_object *object; +	SAVE_OPLINE(); +	function_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);  	if (zend_is_callable_ex(function_name, NULL, 0, NULL, &fcc, &error)) {  		if (error) {  			efree(error); @@ -10279,6 +10292,7 @@ static int ZEND_FASTCALL  ZEND_YIELD_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_  	/* The generator object is stored in EX(return_value) */  	zend_generator *generator = (zend_generator *) EX(return_value); +	SAVE_OPLINE();  	if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {  		zend_error(E_EXCEPTION | E_ERROR, "Cannot yield from finally in a force-closed generator"); @@ -10447,6 +10461,7 @@ static int ZEND_FASTCALL  ZEND_YIELD_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR  	/* The generator object is stored in EX(return_value) */  	zend_generator *generator = (zend_generator *) EX(return_value); +	SAVE_OPLINE();  	if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {  		zend_error(E_EXCEPTION | E_ERROR, "Cannot yield from finally in a force-closed generator");  		zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); @@ -10615,6 +10630,7 @@ static int ZEND_FASTCALL  ZEND_YIELD_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR  	/* The generator object is stored in EX(return_value) */  	zend_generator *generator = (zend_generator *) EX(return_value); +	SAVE_OPLINE();  	if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {  		zend_error(E_EXCEPTION | E_ERROR, "Cannot yield from finally in a force-closed generator");  		zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); @@ -10937,6 +10953,7 @@ static int ZEND_FASTCALL  ZEND_YIELD_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER  	/* The generator object is stored in EX(return_value) */  	zend_generator *generator = (zend_generator *) EX(return_value); +	SAVE_OPLINE();  	if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {  		zend_error(E_EXCEPTION | E_ERROR, "Cannot yield from finally in a force-closed generator"); @@ -11415,6 +11432,7 @@ static int ZEND_FASTCALL  ZEND_YIELD_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG  	/* The generator object is stored in EX(return_value) */  	zend_generator *generator = (zend_generator *) EX(return_value); +	SAVE_OPLINE();  	if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {  		zend_error(E_EXCEPTION | E_ERROR, "Cannot yield from finally in a force-closed generator"); @@ -12161,6 +12179,7 @@ static int ZEND_FASTCALL  ZEND_SEND_VAR_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG  	zval *varptr, *arg;  	zend_free_op free_op1; +	SAVE_OPLINE();  	varptr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);  	arg = ZEND_CALL_VAR(EX(call), opline->result.var);  	if (Z_ISREF_P(varptr)) { @@ -12259,6 +12278,7 @@ static int ZEND_FASTCALL  ZEND_SEND_VAR_EX_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_  	if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, opline->op2.num)) {  		return ZEND_SEND_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);  	} +	SAVE_OPLINE();  	varptr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);  	arg = ZEND_CALL_VAR(EX(call), opline->result.var);  	if (Z_ISREF_P(varptr)) { @@ -12279,6 +12299,7 @@ static int ZEND_FASTCALL  ZEND_SEND_USER_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR  	zval *arg, *param, tmp;  	zend_free_op free_op1; +	SAVE_OPLINE();  	arg = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);  	param = ZEND_CALL_VAR(EX(call), opline->result.var); @@ -12796,7 +12817,6 @@ static int ZEND_FASTCALL  ZEND_FE_RESET_RW_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_  static int ZEND_FASTCALL  ZEND_FE_FETCH_R_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)  {  	USE_OPLINE -  	zval *array;  	zval *value;  	HashTable *fe_ht; @@ -12956,7 +12976,6 @@ static int ZEND_FASTCALL  ZEND_FE_FETCH_R_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_A  static int ZEND_FASTCALL  ZEND_FE_FETCH_RW_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)  {  	USE_OPLINE -  	zval *array;  	zval *value;  	HashTable *fe_ht; @@ -13310,11 +13329,14 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_CONST(int (*b  {  	USE_OPLINE  	zend_free_op free_op1, free_op_data1; -	zval *object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); -	zval *property = EX_CONSTANT(opline->op2); +	zval *object; +	zval *property;  	zval *value;  	zval *zptr; +	SAVE_OPLINE(); +	object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); +	property = EX_CONSTANT(opline->op2);  	if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) {  		zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an object");  		FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var); @@ -14513,7 +14535,7 @@ static int ZEND_FASTCALL  ZEND_FETCH_CONSTANT_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE  			if ((opline->extended_value & IS_CONSTANT_UNQUALIFIED) != 0) {  				char *actual = (char *)zend_memrchr(Z_STRVAL_P(EX_CONSTANT(opline->op2)), '\\', Z_STRLEN_P(EX_CONSTANT(opline->op2)));  				if (!actual) { -					ZVAL_STR(EX_VAR(opline->result.var), zend_string_copy(Z_STR_P(EX_CONSTANT(opline->op2)))); +					ZVAL_STR_COPY(EX_VAR(opline->result.var), Z_STR_P(EX_CONSTANT(opline->op2)));  				} else {  					actual++;  					ZVAL_STRINGL(EX_VAR(opline->result.var), @@ -14856,6 +14878,7 @@ static int ZEND_FASTCALL  ZEND_YIELD_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_  	/* The generator object is stored in EX(return_value) */  	zend_generator *generator = (zend_generator *) EX(return_value); +	SAVE_OPLINE();  	if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {  		zend_error(E_EXCEPTION | E_ERROR, "Cannot yield from finally in a force-closed generator"); @@ -15062,6 +15085,7 @@ static int ZEND_FASTCALL  ZEND_YIELD_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR  	/* The generator object is stored in EX(return_value) */  	zend_generator *generator = (zend_generator *) EX(return_value); +	SAVE_OPLINE();  	if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {  		zend_error(E_EXCEPTION | E_ERROR, "Cannot yield from finally in a force-closed generator");  		zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); @@ -15328,6 +15352,7 @@ static int ZEND_FASTCALL  ZEND_YIELD_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR  	/* The generator object is stored in EX(return_value) */  	zend_generator *generator = (zend_generator *) EX(return_value); +	SAVE_OPLINE();  	if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {  		zend_error(E_EXCEPTION | E_ERROR, "Cannot yield from finally in a force-closed generator");  		zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); @@ -16239,6 +16264,7 @@ static int ZEND_FASTCALL  ZEND_YIELD_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER  	/* The generator object is stored in EX(return_value) */  	zend_generator *generator = (zend_generator *) EX(return_value); +	SAVE_OPLINE();  	if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {  		zend_error(E_EXCEPTION | E_ERROR, "Cannot yield from finally in a force-closed generator"); @@ -16405,11 +16431,14 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_CV(int (*bina  {  	USE_OPLINE  	zend_free_op free_op1, free_op_data1; -	zval *object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); -	zval *property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); +	zval *object; +	zval *property;  	zval *value;  	zval *zptr; +	SAVE_OPLINE(); +	object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); +	property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);  	if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) {  		zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an object");  		FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var); @@ -17913,6 +17942,7 @@ static int ZEND_FASTCALL  ZEND_YIELD_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG  	/* The generator object is stored in EX(return_value) */  	zend_generator *generator = (zend_generator *) EX(return_value); +	SAVE_OPLINE();  	if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {  		zend_error(E_EXCEPTION | E_ERROR, "Cannot yield from finally in a force-closed generator"); @@ -18053,11 +18083,14 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_TMPVAR(int (*  {  	USE_OPLINE  	zend_free_op free_op1, free_op2, free_op_data1; -	zval *object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); -	zval *property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); +	zval *object; +	zval *property;  	zval *value;  	zval *zptr; +	SAVE_OPLINE(); +	object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); +	property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);  	if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) {  		zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an object");  		FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var); @@ -19579,11 +19612,14 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_CONST(int  {  	USE_OPLINE  	zend_free_op free_op_data1; -	zval *object = _get_obj_zval_ptr_unused(execute_data); -	zval *property = EX_CONSTANT(opline->op2); +	zval *object; +	zval *property;  	zval *value;  	zval *zptr; +	SAVE_OPLINE(); +	object = _get_obj_zval_ptr_unused(execute_data); +	property = EX_CONSTANT(opline->op2);  	if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) {  		zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an object");  		FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var); @@ -20557,7 +20593,7 @@ static int ZEND_FASTCALL  ZEND_FETCH_CONSTANT_SPEC_UNUSED_CONST_HANDLER(ZEND_OPC  			if ((opline->extended_value & IS_CONSTANT_UNQUALIFIED) != 0) {  				char *actual = (char *)zend_memrchr(Z_STRVAL_P(EX_CONSTANT(opline->op2)), '\\', Z_STRLEN_P(EX_CONSTANT(opline->op2)));  				if (!actual) { -					ZVAL_STR(EX_VAR(opline->result.var), zend_string_copy(Z_STR_P(EX_CONSTANT(opline->op2)))); +					ZVAL_STR_COPY(EX_VAR(opline->result.var), Z_STR_P(EX_CONSTANT(opline->op2)));  				} else {  					actual++;  					ZVAL_STRINGL(EX_VAR(opline->result.var), @@ -20965,6 +21001,7 @@ static int ZEND_FASTCALL  ZEND_YIELD_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDL  	/* The generator object is stored in EX(return_value) */  	zend_generator *generator = (zend_generator *) EX(return_value); +	SAVE_OPLINE();  	if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {  		zend_error(E_EXCEPTION | E_ERROR, "Cannot yield from finally in a force-closed generator"); @@ -21102,6 +21139,7 @@ static int ZEND_FASTCALL  ZEND_YIELD_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER  	/* The generator object is stored in EX(return_value) */  	zend_generator *generator = (zend_generator *) EX(return_value); +	SAVE_OPLINE();  	if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {  		zend_error(E_EXCEPTION | E_ERROR, "Cannot yield from finally in a force-closed generator");  		zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); @@ -21239,6 +21277,7 @@ static int ZEND_FASTCALL  ZEND_YIELD_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HANDLER  	/* The generator object is stored in EX(return_value) */  	zend_generator *generator = (zend_generator *) EX(return_value); +	SAVE_OPLINE();  	if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {  		zend_error(E_EXCEPTION | E_ERROR, "Cannot yield from finally in a force-closed generator");  		zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); @@ -21715,6 +21754,7 @@ static int ZEND_FASTCALL  ZEND_YIELD_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HAND  	/* The generator object is stored in EX(return_value) */  	zend_generator *generator = (zend_generator *) EX(return_value); +	SAVE_OPLINE();  	if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {  		zend_error(E_EXCEPTION | E_ERROR, "Cannot yield from finally in a force-closed generator"); @@ -21849,11 +21889,14 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_CV(int (*b  {  	USE_OPLINE  	zend_free_op free_op_data1; -	zval *object = _get_obj_zval_ptr_unused(execute_data); -	zval *property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); +	zval *object; +	zval *property;  	zval *value;  	zval *zptr; +	SAVE_OPLINE(); +	object = _get_obj_zval_ptr_unused(execute_data); +	property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);  	if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) {  		zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an object");  		FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var); @@ -23136,6 +23179,7 @@ static int ZEND_FASTCALL  ZEND_YIELD_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_  	/* The generator object is stored in EX(return_value) */  	zend_generator *generator = (zend_generator *) EX(return_value); +	SAVE_OPLINE();  	if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {  		zend_error(E_EXCEPTION | E_ERROR, "Cannot yield from finally in a force-closed generator"); @@ -23270,11 +23314,14 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_TMPVAR(int  {  	USE_OPLINE  	zend_free_op free_op2, free_op_data1; -	zval *object = _get_obj_zval_ptr_unused(execute_data); -	zval *property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); +	zval *object; +	zval *property;  	zval *value;  	zval *zptr; +	SAVE_OPLINE(); +	object = _get_obj_zval_ptr_unused(execute_data); +	property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);  	if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) {  		zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an object");  		FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var); @@ -25096,6 +25143,7 @@ static int ZEND_FASTCALL  ZEND_SEND_VAR_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS  	zval *varptr, *arg; +	SAVE_OPLINE();  	varptr = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var);  	arg = ZEND_CALL_VAR(EX(call), opline->result.var);  	if (Z_ISREF_P(varptr)) { @@ -25193,6 +25241,7 @@ static int ZEND_FASTCALL  ZEND_SEND_VAR_EX_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_A  	if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, opline->op2.num)) {  		return ZEND_SEND_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);  	} +	SAVE_OPLINE();  	varptr = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var);  	arg = ZEND_CALL_VAR(EX(call), opline->result.var);  	if (Z_ISREF_P(varptr)) { @@ -25213,6 +25262,7 @@ static int ZEND_FASTCALL  ZEND_SEND_USER_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG  	zval *arg, *param, tmp; +	SAVE_OPLINE();  	arg = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var);  	param = ZEND_CALL_VAR(EX(call), opline->result.var); @@ -26380,11 +26430,14 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_CONST(int (*bi  {  	USE_OPLINE  	zend_free_op free_op_data1; -	zval *object = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var); -	zval *property = EX_CONSTANT(opline->op2); +	zval *object; +	zval *property;  	zval *value;  	zval *zptr; +	SAVE_OPLINE(); +	object = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var); +	property = EX_CONSTANT(opline->op2);  	if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) {  		zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an object");  		FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var); @@ -28480,6 +28533,7 @@ static int ZEND_FASTCALL  ZEND_YIELD_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_A  	/* The generator object is stored in EX(return_value) */  	zend_generator *generator = (zend_generator *) EX(return_value); +	SAVE_OPLINE();  	if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {  		zend_error(E_EXCEPTION | E_ERROR, "Cannot yield from finally in a force-closed generator"); @@ -28756,6 +28810,7 @@ static int ZEND_FASTCALL  ZEND_YIELD_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG  	/* The generator object is stored in EX(return_value) */  	zend_generator *generator = (zend_generator *) EX(return_value); +	SAVE_OPLINE();  	if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {  		zend_error(E_EXCEPTION | E_ERROR, "Cannot yield from finally in a force-closed generator");  		zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); @@ -29413,6 +29468,7 @@ static int ZEND_FASTCALL  ZEND_YIELD_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG  	/* The generator object is stored in EX(return_value) */  	zend_generator *generator = (zend_generator *) EX(return_value); +	SAVE_OPLINE();  	if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {  		zend_error(E_EXCEPTION | E_ERROR, "Cannot yield from finally in a force-closed generator");  		zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); @@ -30523,6 +30579,7 @@ static int ZEND_FASTCALL  ZEND_YIELD_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_  	/* The generator object is stored in EX(return_value) */  	zend_generator *generator = (zend_generator *) EX(return_value); +	SAVE_OPLINE();  	if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {  		zend_error(E_EXCEPTION | E_ERROR, "Cannot yield from finally in a force-closed generator"); @@ -30948,11 +31005,14 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_CV(int (*binar  {  	USE_OPLINE  	zend_free_op free_op_data1; -	zval *object = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var); -	zval *property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); +	zval *object; +	zval *property;  	zval *value;  	zval *zptr; +	SAVE_OPLINE(); +	object = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var); +	property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);  	if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) {  		zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an object");  		FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var); @@ -32681,6 +32741,7 @@ static int ZEND_FASTCALL  ZEND_YIELD_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS  	/* The generator object is stored in EX(return_value) */  	zend_generator *generator = (zend_generator *) EX(return_value); +	SAVE_OPLINE();  	if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {  		zend_error(E_EXCEPTION | E_ERROR, "Cannot yield from finally in a force-closed generator"); @@ -33095,11 +33156,14 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_TMPVAR(int (*b  {  	USE_OPLINE  	zend_free_op free_op2, free_op_data1; -	zval *object = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var); -	zval *property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); +	zval *object; +	zval *property;  	zval *value;  	zval *zptr; +	SAVE_OPLINE(); +	object = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var); +	property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);  	if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) {  		zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an object");  		FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var); @@ -38408,7 +38472,7 @@ static int ZEND_FASTCALL ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)  void zend_init_opcodes_handlers(void)  { -  static const opcode_handler_t labels[] = { +  static const void *labels[] = {    	ZEND_NOP_SPEC_HANDLER,    	ZEND_NOP_SPEC_HANDLER,    	ZEND_NOP_SPEC_HANDLER, @@ -42686,9 +42750,9 @@ void zend_init_opcodes_handlers(void)    	ZEND_SPACESHIP_SPEC_CV_CV_HANDLER,    	ZEND_NULL_HANDLER    }; -  zend_opcode_handlers = (opcode_handler_t*)labels; +  zend_opcode_handlers = labels;  } -static opcode_handler_t zend_vm_get_opcode_handler(zend_uchar opcode, const zend_op* op) +static const void *zend_vm_get_opcode_handler(zend_uchar opcode, const zend_op* op)  {  		static const int zend_vm_decode[] = {  			_UNUSED_CODE, /* 0              */ @@ -42717,8 +42781,3 @@ ZEND_API void zend_vm_set_opcode_handler(zend_op* op)  	op->handler = zend_vm_get_opcode_handler(zend_user_opcodes[op->opcode], op);  } -ZEND_API int zend_do_fcall(ZEND_OPCODE_HANDLER_ARGS) -{ -	return ZEND_DO_FCALL_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); -} - diff --git a/Zend/zend_vm_gen.php b/Zend/zend_vm_gen.php index 65b1c72c06..244080c3a4 100644 --- a/Zend/zend_vm_gen.php +++ b/Zend/zend_vm_gen.php @@ -639,7 +639,7 @@ function gen_handler($f, $spec, $kind, $name, $op1, $op2, $use, $code, $lineno)  			break;  		case ZEND_VM_KIND_SWITCH:  			if ($spec) { -				out($f,"case ".((string)($opnames[$name]*25+($typecode[$op1]*5)+$typecode[$op2])).": /*".$name."_SPEC".$prefix[$op1].$prefix[$op2]."_HANDLER*/"); +				out($f,"case ".((string)($opnames[$name]*25+($typecode[$op1=="TMPVAR"?"TMP":$op1]*5)+$typecode[$op2=="TMPVAR"?"TMP":$op2])).": /*".$name."_SPEC".$prefix[$op1].$prefix[$op2]."_HANDLER*/");  			} else {  				out($f,"case ".$name.":");  			} @@ -717,10 +717,10 @@ function gen_labels($f, $spec, $kind, $prolog) {  										out($f,$prolog."ZEND_NULL_HANDLER,\n");  										break;  									case ZEND_VM_KIND_SWITCH: -										out($f,$prolog."(opcode_handler_t)-1,\n"); +										out($f,$prolog."(void*)(uintptr_t)-1,\n");  										break;  									case ZEND_VM_KIND_GOTO: -										out($f,$prolog."(opcode_handler_t)&&ZEND_NULL_HANDLER,\n"); +										out($f,$prolog."(void*)&&ZEND_NULL_HANDLER,\n");  										break;  								}  							} @@ -763,10 +763,10 @@ function gen_labels($f, $spec, $kind, $prolog) {  										out($f,$prolog.$dsc["op"]."_SPEC".$prefix[$op1].$prefix[$op2]."_HANDLER,\n");  										break;  									case ZEND_VM_KIND_SWITCH: -										out($f,$prolog."(opcode_handler_t)".((string)($num*25+$typecode[$op1]*5+$typecode[$op2])).",\n"); +										out($f,$prolog."(void*)(uintptr_t)".((string)($num*25+$typecode[$op1=="TMPVAR"?"TMP":$op1]*5+$typecode[$op2=="TMPVAR"?"TMP":$op2])).",\n");  										break;  									case ZEND_VM_KIND_GOTO: -										out($f,$prolog."(opcode_handler_t)&&".$dsc["op"]."_SPEC".$prefix[$op1].$prefix[$op2]."_HANDLER,\n"); +										out($f,$prolog."(void*)&&".$dsc["op"]."_SPEC".$prefix[$op1].$prefix[$op2]."_HANDLER,\n");  										break;  								}  							} else { @@ -776,10 +776,10 @@ function gen_labels($f, $spec, $kind, $prolog) {  										out($f,$prolog."ZEND_NULL_HANDLER,\n");  										break;  									case ZEND_VM_KIND_SWITCH: -										out($f,$prolog."(opcode_handler_t)-1,\n"); +										out($f,$prolog."(void*)(uintptr_t)-1,\n");  										break;  									case ZEND_VM_KIND_GOTO: -										out($f,$prolog."(opcode_handler_t)&&ZEND_NULL_HANDLER,\n"); +										out($f,$prolog."(void*)&&ZEND_NULL_HANDLER,\n");  										break;  								}  							} @@ -801,10 +801,10 @@ function gen_labels($f, $spec, $kind, $prolog) {  						out($f,$prolog."ZEND_NULL_HANDLER,\n");  						break;  					case ZEND_VM_KIND_SWITCH: -						out($f,$prolog."(opcode_handler_t)-1,\n"); +						out($f,$prolog."(void*)(uintptr_t)-1,\n");  						break;  					case ZEND_VM_KIND_GOTO: -						out($f,$prolog."(opcode_handler_t)&&ZEND_NULL_HANDLER,\n"); +						out($f,$prolog."(void*)&&ZEND_NULL_HANDLER,\n");  						break;  				}  				$next++; @@ -816,10 +816,10 @@ function gen_labels($f, $spec, $kind, $prolog) {  					out($f,$prolog.$dsc["op"]."_HANDLER,\n");  					break;  				case ZEND_VM_KIND_SWITCH: -					out($f,$prolog."(opcode_handler_t)".((string)$num).",\n"); +					out($f,$prolog."(void*)(uintptr_t)".((string)$num).",\n");  					break;  				case ZEND_VM_KIND_GOTO: -					out($f,$prolog."(opcode_handler_t)&&".$dsc["op"]."_HANDLER,\n"); +					out($f,$prolog."(void*)&&".$dsc["op"]."_HANDLER,\n");  					break;  			}  		} @@ -831,10 +831,10 @@ function gen_labels($f, $spec, $kind, $prolog) {  			out($f,$prolog."ZEND_NULL_HANDLER\n");  			break;  		case ZEND_VM_KIND_SWITCH: -			out($f,$prolog."(opcode_handler_t)-1\n"); +			out($f,$prolog."(void*)(uintptr_t)-1\n");  			break;  		case ZEND_VM_KIND_GOTO: -			out($f,$prolog."(opcode_handler_t)&&ZEND_NULL_HANDLER\n"); +			out($f,$prolog."(void*)&&ZEND_NULL_HANDLER\n");  			break;  	}  } @@ -942,7 +942,7 @@ function skip_blanks($f, $prolog, $epilog) {  }  // Generates executor from skeleton file and definition (specialized or unspecialized) -function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name, $old) { +function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name) {  	global $params, $skeleton_file, $line_no;  	$lineno      = 0; @@ -952,13 +952,16 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name,  		if (preg_match("/(.*)[{][%]([A-Z_]*)[%][}](.*)/", $line, $m)) {  			switch ($m[2]) {  				case "DEFINES": -					if (ZEND_VM_OLD_EXECUTOR && $spec) { -						out($f,"static int zend_vm_old_executor = 0;\n\n"); -					} -					out($f,"static opcode_handler_t zend_vm_get_opcode_handler(zend_uchar opcode, const zend_op* op);\n\n"); +					out($f,"static const void **zend_opcode_handlers;\n"); +					out($f,"static const void *zend_vm_get_opcode_handler(zend_uchar opcode, const zend_op* op);\n\n");  					switch ($kind) {  						case ZEND_VM_KIND_CALL: -							out($f,"\n");								 +							out($f,"\n"); +							out($f,"#define ZEND_OPCODE_HANDLER_ARGS zend_execute_data *execute_data\n"); +							out($f,"#define ZEND_OPCODE_HANDLER_ARGS_PASSTHRU execute_data\n"); +							out($f,"\n"); +							out($f,"typedef int (ZEND_FASTCALL *opcode_handler_t) (ZEND_OPCODE_HANDLER_ARGS);\n"); +							out($f,"\n");  							out($f,"#undef OPLINE\n");  							out($f,"#undef DCL_OPLINE\n");  							out($f,"#undef USE_OPLINE\n"); @@ -979,9 +982,8 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name,  							out($f,"#define ZEND_VM_RETURN()           return -1\n");  							out($f,"#define ZEND_VM_ENTER()            return  1\n");  							out($f,"#define ZEND_VM_LEAVE()            return  2\n"); -							out($f,"#define ZEND_VM_DISPATCH(opcode, opline) return zend_vm_get_opcode_handler(opcode, opline)(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);\n\n"); -							out($f,"#define ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_INTERNAL execute_data -"); +							out($f,"#define ZEND_VM_DISPATCH(opcode, opline) return ((opcode_handler_t)zend_vm_get_opcode_handler(opcode, opline))(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);\n"); +							out($f,"\n");  							break;  						case ZEND_VM_KIND_SWITCH:  							out($f,"\n"); @@ -1005,9 +1007,8 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name,  							out($f,"#define ZEND_VM_RETURN()   return\n");  							out($f,"#define ZEND_VM_ENTER()    execute_data = EG(current_execute_data); LOAD_OPLINE(); ZEND_VM_CONTINUE()\n");  							out($f,"#define ZEND_VM_LEAVE()    ZEND_VM_CONTINUE()\n"); -							out($f,"#define ZEND_VM_DISPATCH(opcode, opline) dispatch_handler = zend_vm_get_opcode_handler(opcode, opline); goto zend_vm_dispatch;\n\n"); -							out($f,"#define ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_INTERNAL execute_data -"); +							out($f,"#define ZEND_VM_DISPATCH(opcode, opline) dispatch_handler = zend_vm_get_opcode_handler(opcode, opline); goto zend_vm_dispatch;\n"); +							out($f,"\n");  							break;  						case ZEND_VM_KIND_GOTO:  							out($f,"\n"); @@ -1037,9 +1038,8 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name,  							out($f,"#define ZEND_VM_RETURN()   return\n");  							out($f,"#define ZEND_VM_ENTER()    execute_data = EG(current_execute_data); LOAD_OPLINE(); ZEND_VM_CONTINUE()\n");  							out($f,"#define ZEND_VM_LEAVE()    ZEND_VM_CONTINUE()\n"); -							out($f,"#define ZEND_VM_DISPATCH(opcode, opline) goto *(void**)(zend_vm_get_opcode_handler(opcode, opline));\n\n"); -							out($f,"#define ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_INTERNAL execute_data -"); +							out($f,"#define ZEND_VM_DISPATCH(opcode, opline) goto *(void**)(zend_vm_get_opcode_handler(opcode, opline));\n"); +							out($f,"\n");  							break;  					}  					break; @@ -1049,7 +1049,7 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name,  				case "HELPER_VARS":  					if ($kind != ZEND_VM_KIND_CALL) {  						if ($kind == ZEND_VM_KIND_SWITCH) { -							out($f,$m[1]."opcode_handler_t dispatch_handler;\n"); +							out($f,$m[1]."const void *dispatch_handler;\n");  						}  					  // Emit local variables those are used for helpers' parameters  						foreach ($params as $param => $x) { @@ -1065,10 +1065,10 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name,  					  // zend_opcode_handlers initialization  						$prolog = $m[1];  						out($f,$prolog."if (execute_data == NULL) {\n"); -						out($f,$prolog."\tstatic const opcode_handler_t labels[] = {\n"); +						out($f,$prolog."\tstatic const void* labels[] = {\n");  						gen_labels($f, $spec, $kind, $prolog."\t\t");  						out($f,$prolog."\t};\n"); -						out($f,$prolog."\tzend_opcode_handlers = (opcode_handler_t*)labels;\n"); +						out($f,$prolog."\tzend_opcode_handlers = (const void **)labels;\n");  						out($f,$prolog."\treturn;\n");  						out($f,$prolog."}\n");  					} else { @@ -1090,10 +1090,10 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name,  				  // Emit code that dispatches to opcode handler  					switch ($kind) {  						case ZEND_VM_KIND_CALL: -							out($f, $m[1]."if (UNEXPECTED((ret = OPLINE->handler(execute_data)) != 0))".$m[3]."\n"); +							out($f, $m[1]."if (UNEXPECTED((ret = ((opcode_handler_t)OPLINE->handler)(execute_data)) != 0))".$m[3]."\n");  							break;  						case ZEND_VM_KIND_SWITCH: -							out($f, $m[1]."dispatch_handler = OPLINE->handler;\nzend_vm_dispatch:\n".$m[1]."switch ((int)dispatch_handler)".$m[3]."\n"); +							out($f, $m[1]."dispatch_handler = OPLINE->handler;\nzend_vm_dispatch:\n".$m[1]."switch ((int)(uintptr_t)dispatch_handler)".$m[3]."\n");  							break;  						case ZEND_VM_KIND_GOTO:  							out($f, $m[1]."goto *(void**)(OPLINE->handler);".$m[3]."\n"); @@ -1115,12 +1115,7 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name,  					break;  				case "EXTERNAL_EXECUTOR":  					if ($kind == ZEND_VM_KIND_CALL) { -					  // Unspecialized executor with CALL threading is the same as the -					  // old one, so we don't need to produce code twitch -						if (!$old || ZEND_VM_SPEC || (ZEND_VM_KIND != ZEND_VM_KIND_CALL)) { -							// Emit executor code -							gen_executor_code($f, $spec, $kind, $m[1]); -						} +						gen_executor_code($f, $spec, $kind, $m[1]);  					}  					break;  				case "INITIALIZER_NAME": @@ -1135,20 +1130,10 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name,  						out($f,$prolog."");  						out($f,$prolog.$executor_name."_ex(NULL);\n");  					} else { -						if ($old) { -						  // Reserving space for user-defined opcodes -							out($f,$prolog."static opcode_handler_t labels[512] = {\n"); -						} else { -							out($f,$prolog."static const opcode_handler_t labels[] = {\n"); -						} +						out($f,$prolog."static const void *labels[] = {\n");  						gen_labels($f, $spec, $kind, $prolog."\t");  						out($f,$prolog."};\n"); -						out($f,$prolog."zend_opcode_handlers = (opcode_handler_t*)labels;\n"); -						if ($old) { -						  // Setup old executor -							out($f,$prolog."zend_vm_old_executor = 1;\n"); -							out($f,$prolog."zend_execute = old_execute;\n"); -						} +						out($f,$prolog."zend_opcode_handlers = labels;\n");  					}  					break;  				default: @@ -1391,31 +1376,14 @@ function gen_vm($def, $skel) {  	out($f, "255\n};\n\n");  	// Generate specialized executor -	gen_executor($f, $skl, ZEND_VM_SPEC, ZEND_VM_KIND, "execute", "zend_init_opcodes_handlers", 0); - -	// Generate un-specialized executor -	if (ZEND_VM_OLD_EXECUTOR) { -		out($f,"\n/* Old executor */\n\n"); -		out($f,"#undef ZEND_VM_CONTINUE\n\n"); -		out($f,"#undef ZEND_VM_RETURN\n\n"); -		out($f,"#undef ZEND_VM_ENTER\n\n"); -		out($f,"#undef ZEND_VM_LEAVE\n\n"); -		out($f,"#undef ZEND_VM_DISPATCH\n\n"); -		out($f,"#undef ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_INTERNAL\n\n"); -		gen_executor($f, $skl, 0, ZEND_VM_KIND_CALL, "old_execute", "zend_vm_use_old_executor", 1); -	} +	gen_executor($f, $skl, ZEND_VM_SPEC, ZEND_VM_KIND, "execute", "zend_init_opcodes_handlers");  	// Generate zend_vm_get_opcode_handler() function -	out($f, "static opcode_handler_t zend_vm_get_opcode_handler(zend_uchar opcode, const zend_op* op)\n"); +	out($f, "static const void *zend_vm_get_opcode_handler(zend_uchar opcode, const zend_op* op)\n");  	out($f, "{\n");  	if (!ZEND_VM_SPEC) {  		out($f, "\treturn zend_opcode_handlers[opcode];\n");  	} else { -		if (ZEND_VM_OLD_EXECUTOR) { -			out($f, "\tif (zend_vm_old_executor) {\n"); -			out($f, "\t\treturn zend_opcode_handlers[opcode];\n"); -			out($f, "\t} else {\n"); -		}  		out($f, "\t\tstatic const int zend_vm_decode[] = {\n");  		out($f, "\t\t\t_UNUSED_CODE, /* 0              */\n");  		out($f, "\t\t\t_CONST_CODE,  /* 1 = IS_CONST   */\n"); @@ -1436,9 +1404,6 @@ function gen_vm($def, $skel) {  		out($f, "\t\t\t_CV_CODE      /* 16 = IS_CV     */\n");  		out($f, "\t\t};\n");  		out($f, "\t\treturn zend_opcode_handlers[opcode * 25 + zend_vm_decode[op->op1_type] * 5 + zend_vm_decode[op->op2_type]];\n"); -		if (ZEND_VM_OLD_EXECUTOR) { -			out($f, "\t}\n"); -		}  	}  	out($f, "}\n\n"); @@ -1450,7 +1415,6 @@ function gen_vm($def, $skel) {  	// Export handlers and helpers  	if (count($export) > 0 && -	    !ZEND_VM_OLD_EXECUTOR &&  	    ZEND_VM_KIND != ZEND_VM_KIND_CALL) {  		out($f,"#undef OPLINE\n");  		out($f,"#undef DCL_OPLINE\n"); @@ -1473,14 +1437,12 @@ function gen_vm($def, $skel) {  		out($f,"#undef ZEND_VM_ENTER\n");  		out($f,"#undef ZEND_VM_LEAVE\n");  		out($f,"#undef ZEND_VM_DISPATCH\n"); -		out($f,"#undef ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_INTERNAL\n\n");  		out($f,"#define ZEND_VM_CONTINUE()   return  0\n");  		out($f,"#define ZEND_VM_RETURN()     return -1\n");  		out($f,"#define ZEND_VM_ENTER()      return  1\n");  		out($f,"#define ZEND_VM_LEAVE()      return  2\n");  		out($f,"#define ZEND_VM_DISPATCH(opcode, opline) return zend_vm_get_opcode_handler(opcode, opline)(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);\n\n"); -		out($f,"#define ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_INTERNAL execute_data -\n"); +		out($f,"\n");  	}  	foreach ($export as $dsk) {  		list($kind, $func, $name) = $dsk; @@ -1498,15 +1460,7 @@ function gen_vm($def, $skel) {  			$code = $h['code'];  		}  		$done = 0; -		if (ZEND_VM_OLD_EXECUTOR) { -			if ($kind == "handler") { -				out($f, "{\n\treturn ".$name."_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);\n}\n\n"); -				$done = 1; -			} else if ($helpers[$name]["param"] == null) { -				out($f, "{\n\treturn ".$name."(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);\n}\n\n"); -				$done = 1; -			} -		} else if (ZEND_VM_KIND == ZEND_VM_KIND_CALL) { +		if (ZEND_VM_KIND == ZEND_VM_KIND_CALL) {  			if ($kind == "handler") {  				$op = $opcodes[$opnames[$name]];  				if (isset($op['op1']["ANY"]) && isset($op['op2']["ANY"])) { @@ -1535,7 +1489,6 @@ function usage() {  	     "\nOptions:".  	     "\n  --with-vm-kind=CALL|SWITCH|GOTO - select threading model (default is CALL)".  	     "\n  --without-specializer           - disable executor specialization". -	     "\n  --with-old-executor             - enable old executor".  	     "\n  --with-lines                    - enable #line directives".  	     "\n\n");  } @@ -1562,9 +1515,6 @@ for ($i = 1;  $i < $argc; $i++) {  	} else if ($argv[$i] == "--without-specializer") {  	  // Disabling specialization  		define("ZEND_VM_SPEC", 0); -	} else if ($argv[$i] == "--with-old-executor") { -	  // Disabling code for old-style executor -		define("ZEND_VM_OLD_EXECUTOR", 1);  	} else if ($argv[$i] == "--with-lines") {  		// Enabling debugging using original zend_vm_def.h  		define("ZEND_VM_LINES", 1); @@ -1587,10 +1537,6 @@ if (!defined("ZEND_VM_SPEC")) {    // Using specialized executor by default  	define("ZEND_VM_SPEC", 1);  } -if (!defined("ZEND_VM_OLD_EXECUTOR")) { -  // Include old-style executor by default -	define("ZEND_VM_OLD_EXECUTOR", 0); -}  if (!defined("ZEND_VM_LINES")) {    // Disabling #line directives  	define("ZEND_VM_LINES", 0); diff --git a/ext/opcache/Optimizer/zend_optimizer_internal.h b/ext/opcache/Optimizer/zend_optimizer_internal.h index 2bdffcaac3..05e1e09ca5 100644 --- a/ext/opcache/Optimizer/zend_optimizer_internal.h +++ b/ext/opcache/Optimizer/zend_optimizer_internal.h @@ -40,7 +40,7 @@  	memset(&(opline)->op1, 0, sizeof((opline)->op1)); \  	memset(&(opline)->op2, 0, sizeof((opline)->op2)); \  	(opline)->result_type = (opline)->op1_type = (opline)->op2_type=IS_UNUSED; \ -	(opline)->handler = zend_opcode_handlers[ZEND_NOP]; \ +	zend_vm_set_opcode_handler(opline); \  } while (0);  #define RESULT_USED(op)	    (((op->result_type & IS_VAR) && !(op->result_type & EXT_TYPE_UNUSED)) || op->result_type == IS_TMP_VAR)  #define RESULT_UNUSED(op)	((op->result_type & EXT_TYPE_UNUSED) != 0)  | 
