]> granicus.if.org Git - php/commitdiff
Fixed support for unspecialized and GOTO and SWITCH executor
authorDmitry Stogov <dmitry@zend.com>
Wed, 16 Apr 2014 22:12:06 +0000 (02:12 +0400)
committerDmitry Stogov <dmitry@zend.com>
Wed, 16 Apr 2014 22:12:06 +0000 (02:12 +0400)
Zend/zend_execute.c
Zend/zend_vm_gen.php

index d548c4b695b9a6ee535e5c5edb104674357b9d39..762333d1258ca82305474609260282832da1611a 100644 (file)
@@ -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)) {
index 5614052520700969e34aa5654120970ea03d9a92..03d660e2f901f1ac45465e82d1d247ecca97ae7c 100644 (file)
@@ -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");