From: Dmitry Stogov Date: Thu, 16 Jun 2005 06:00:48 +0000 (+0000) Subject: USER_OPCODE API is improvet. X-Git-Tag: php-5.1.0b2~166 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3c1a774ddc332059be32c7be2701aab11e73c763;p=php USER_OPCODE API is improvet. Implemented ability to dispatch from user handler to internal handler of another opcode. --- diff --git a/Zend/zend_execute.h b/Zend/zend_execute.h index 509d624b4f..f196fa7c9d 100644 --- a/Zend/zend_execute.h +++ b/Zend/zend_execute.h @@ -180,6 +180,8 @@ ZEND_API zval** zend_get_compiled_variable_value(zend_execute_data *execute_data #define ZEND_USER_OPCODE_RETURN 1 /* exit from executor (return from function) */ #define ZEND_USER_OPCODE_DISPATCH 2 /* call original opcode handler */ +#define ZEND_USER_OPCODE_DISPATCH_TO 0x100 /* call original handler of returned opcode */ + ZEND_API int zend_set_user_opcode_handler(zend_uchar opcode, opcode_handler_t handler); ZEND_API opcode_handler_t zend_get_user_opcode_handler(zend_uchar opcode); diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 7e6e825a00..9a0f1d8870 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -3578,14 +3578,17 @@ ZEND_VM_HANDLER(146, ZEND_VERIFY_ABSTRACT_CLASS, ANY, ANY) ZEND_VM_HANDLER(150, ZEND_USER_OPCODE, ANY, ANY) { - switch (zend_user_opcode_handlers[EX(opline)->opcode](ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_INTERNAL)) { + int ret = zend_user_opcode_handlers[EX(opline)->opcode](ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_INTERNAL); + + switch (ret) { case ZEND_USER_OPCODE_CONTINUE: ZEND_VM_CONTINUE(); case ZEND_USER_OPCODE_RETURN: ZEND_VM_RETURN(); case ZEND_USER_OPCODE_DISPATCH: + ZEND_VM_DISPATCH(EX(opline)->opcode, EX(opline)); default: - ZEND_VM_DISPATCH(EX(opline)); + ZEND_VM_DISPATCH(ret & 0xff, EX(opline)); } } diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 4fa471003a..9f49f90263 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -27,7 +27,7 @@ static opcode_handler_t zend_vm_get_opcode_handler(zend_uchar opcode, zend_op* o #define ZEND_VM_CONTINUE() return 0 #define ZEND_VM_RETURN() return 1 -#define ZEND_VM_DISPATCH(op) return zend_vm_get_opcode_handler(op->opcode, op)(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); +#define ZEND_VM_DISPATCH(opcode, opline) return zend_vm_get_opcode_handler(opcode, opline)(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); #define ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_INTERNAL execute_data TSRMLS_CC @@ -555,14 +555,17 @@ static int ZEND_VERIFY_ABSTRACT_CLASS_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS) static int ZEND_USER_OPCODE_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - switch (zend_user_opcode_handlers[EX(opline)->opcode](ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_INTERNAL)) { + int ret = zend_user_opcode_handlers[EX(opline)->opcode](ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_INTERNAL); + + switch (ret) { case ZEND_USER_OPCODE_CONTINUE: ZEND_VM_CONTINUE(); case ZEND_USER_OPCODE_RETURN: ZEND_VM_RETURN(); case ZEND_USER_OPCODE_DISPATCH: + ZEND_VM_DISPATCH(EX(opline)->opcode, EX(opline)); default: - ZEND_VM_DISPATCH(EX(opline)); + ZEND_VM_DISPATCH(ret & 0xff, EX(opline)); } } diff --git a/Zend/zend_vm_gen.php b/Zend/zend_vm_gen.php index c930709a93..a395ee05d6 100644 --- a/Zend/zend_vm_gen.php +++ b/Zend/zend_vm_gen.php @@ -747,21 +747,21 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name, out($f,"\n"); out($f,"#define ZEND_VM_CONTINUE() return 0\n"); out($f,"#define ZEND_VM_RETURN() return 1\n"); - out($f,"#define ZEND_VM_DISPATCH(op) return zend_vm_get_opcode_handler(op->opcode, op)(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);\n\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 TSRMLS_CC\n"); break; case ZEND_VM_KIND_SWITCH: out($f,"\n"); out($f,"#define ZEND_VM_CONTINUE() goto zend_vm_continue\n"); out($f,"#define ZEND_VM_RETURN() return\n"); - out($f,"#define ZEND_VM_DISPATCH(op) dispatch_handler = zend_vm_get_opcode_handler(op->opcode, op); goto zend_vm_dispatch;\n\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"); break; case ZEND_VM_KIND_GOTO: out($f,"\n"); out($f,"#define ZEND_VM_CONTINUE() goto *(void**)(EX(opline)->handler)\n"); out($f,"#define ZEND_VM_RETURN() return\n"); - out($f,"#define ZEND_VM_DISPATCH(op) goto *(void**)(zend_vm_get_opcode_handler(op->opcode, op));\n\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"); break; }