From: Dmitry Stogov Date: Wed, 16 Apr 2014 22:12:06 +0000 (+0400) Subject: Fixed support for unspecialized and GOTO and SWITCH executor X-Git-Tag: POST_PHPNG_MERGE~412^2~82^2~15 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6976eb2919ff9fc347866f789447d6b3b8329d0f;p=php Fixed support for unspecialized and GOTO and SWITCH executor --- diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index d548c4b695..762333d125 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -51,7 +51,9 @@ typedef int (*incdec_t)(zval *); #define get_zval_ptr(op_type, node, ex, should_free, type) _get_zval_ptr(op_type, node, ex, should_free, type TSRMLS_CC) +#define get_zval_ptr_deref(op_type, node, ex, should_free, type) _get_zval_ptr_deref(op_type, node, ex, should_free, type TSRMLS_CC) #define get_zval_ptr_ptr(op_type, node, ex, should_free, type) _get_zval_ptr_ptr(op_type, node, ex, should_free, type TSRMLS_CC) +#define get_zval_ptr_ptr_undef(op_type, node, ex, should_free, type) _get_zval_ptr_ptr(op_type, node, ex, should_free, type TSRMLS_CC) #define get_obj_zval_ptr(op_type, node, ex, should_free, type) _get_obj_zval_ptr(op_type, node, ex, should_free, type TSRMLS_CC) #define get_obj_zval_ptr_ptr(op_type, node, ex, should_free, type) _get_obj_zval_ptr_ptr(op_type, node, ex, should_free, type TSRMLS_CC) @@ -434,6 +436,19 @@ static zend_always_inline zval *_get_zval_ptr_ptr_var(zend_uint var, const zend_ } } +static inline zval *_get_zval_ptr_ptr(int op_type, const znode_op *node, const zend_execute_data *execute_data, zend_free_op *should_free, int type TSRMLS_DC) +{ + zval *ret; + + if (op_type == IS_CV) { + should_free->var = NULL; + return _get_zval_ptr_cv(execute_data, node->var, type TSRMLS_CC); + } else /* if (op_type == IS_VAR) */ { + ZEND_ASSERT(op_type == IS_VAR); + return _get_zval_ptr_ptr_var(node->var, execute_data, should_free TSRMLS_CC); + } +} + static zend_always_inline zval *_get_obj_zval_ptr_unused(TSRMLS_D) { if (EXPECTED(Z_OBJ(EG(This)) != NULL)) { @@ -457,6 +472,19 @@ static inline zval *_get_obj_zval_ptr(int op_type, znode_op *op, const zend_exec return get_zval_ptr(op_type, op, execute_data, should_free, type); } +static inline zval *_get_obj_zval_ptr_ptr(int op_type, const znode_op *node, const zend_execute_data *execute_data, zend_free_op *should_free, int type TSRMLS_DC) +{ + if (op_type == IS_UNUSED) { + if (EXPECTED(Z_OBJ(EG(This)) != NULL)) { + should_free->var = NULL; + return &EG(This); + } else { + zend_error_noreturn(E_ERROR, "Using $this when not in object context"); + } + } + return get_zval_ptr_ptr(op_type, node, execute_data, should_free, type); +} + static inline void zend_assign_to_variable_reference(zval *variable_ptr, zval *value_ptr TSRMLS_DC) { if (EXPECTED(variable_ptr != value_ptr)) { diff --git a/Zend/zend_vm_gen.php b/Zend/zend_vm_gen.php index 5614052520..03d660e2f9 100644 --- a/Zend/zend_vm_gen.php +++ b/Zend/zend_vm_gen.php @@ -942,7 +942,7 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name, out($f,"#define LOAD_REGS()\n"); out($f,"#define ZEND_VM_CONTINUE() goto zend_vm_continue\n"); out($f,"#define ZEND_VM_RETURN() EG(in_execution) = original_in_execution; return\n"); - out($f,"#define ZEND_VM_ENTER() ZEND_VM_CONTINUE()\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 TSRMLS_CC\n"); @@ -974,7 +974,7 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name, out($f,"#define LOAD_REGS()\n"); out($f,"#define ZEND_VM_CONTINUE() goto *(void**)(OPLINE->handler)\n"); out($f,"#define ZEND_VM_RETURN() EG(in_execution) = original_in_execution; return\n"); - out($f,"#define ZEND_VM_ENTER() ZEND_VM_CONTINUE()\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 TSRMLS_CC\n");