Created
July 13, 2014 02:56
-
-
Save laruence/10a37813fcb5938ea1f9 to your computer and use it in GitHub Desktop.
defined handler
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c | |
index 56d0d97..5331b4b 100644 | |
--- a/Zend/zend_compile.c | |
+++ b/Zend/zend_compile.c | |
@@ -2751,6 +2751,27 @@ static int zend_do_convert_strlen(zend_op *init_opline, znode *result TSRMLS_DC) | |
} | |
/* }}} */ | |
+static int zend_do_convert_defined(zend_op *init_opline, znode *result TSRMLS_DC) /* {{{ */ | |
+{ | |
+ zend_op *opline = init_opline + 1; | |
+ | |
+ if (opline->opcode != ZEND_SEND_VAL || | |
+ opline->op1_type != IS_CONST || | |
+ Z_TYPE(CONSTANT(opline->op1.constant)) != IS_STRING) { | |
+ return 0; | |
+ } | |
+ | |
+ MAKE_NOP(init_opline); | |
+ opline->opcode = ZEND_DEFINED; | |
+ opline->extended_value = 0; | |
+ GET_CACHE_SLOT(opline->op1.constant); | |
+ opline->result.var = get_temporary_variable(CG(active_op_array)); | |
+ opline->result_type = IS_TMP_VAR; | |
+ GET_NODE(result, opline->result); | |
+ return 1; | |
+} | |
+/* }}} */ | |
+ | |
void zend_do_end_function_call(znode *function_name, znode *result, int is_method, int is_dynamic_fcall TSRMLS_DC) /* {{{ */ | |
{ | |
zend_op *opline; | |
@@ -2788,6 +2809,14 @@ void zend_do_end_function_call(znode *function_name, znode *result, int is_metho | |
fcall->arg_num = 0; | |
} | |
} | |
+ } else if (func->common.function_name->len == sizeof("defined")-1 && | |
+ memcmp(func->common.function_name->val, "defined", sizeof("defined")-1) == 0) { | |
+ if (fcall->arg_num == 1) { | |
+ if (zend_do_convert_defined(opline, result TSRMLS_CC)) { | |
+ zend_stack_del_top(&CG(function_call_stack)); | |
+ return; | |
+ } | |
+ } | |
} else if ((CG(compiler_options) & ZEND_COMPILE_NO_BUILTIN_STRLEN) == 0 && | |
func->common.function_name->len == sizeof("strlen")-1 && | |
memcmp(func->common.function_name->val, "strlen", sizeof("strlen")-1) == 0) { | |
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h | |
index dfe6651..e8d3aa4 100644 | |
--- a/Zend/zend_vm_def.h | |
+++ b/Zend/zend_vm_def.h | |
@@ -5884,4 +5884,23 @@ ZEND_VM_C_LABEL(strlen_error): | |
ZEND_VM_NEXT_OPCODE(); | |
} | |
+ZEND_VM_HANDLER(122, ZEND_DEFINED, CONST, ANY) | |
+{ | |
+ USE_OPLINE | |
+ zval *name, *c; | |
+ | |
+ SAVE_OPLINE(); | |
+ name = GET_OP1_ZVAL_PTR(BP_VAR_R); | |
+ if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op1.zv))) { | |
+ ZVAL_TRUE(EX_VAR(opline->result.var)); | |
+ } else if ((c = zend_get_constant_ex(Z_STR_P(name), NULL, ZEND_FETCH_CLASS_SILENT TSRMLS_CC)) == NULL) { | |
+ ZVAL_FALSE(EX_VAR(opline->result.var)); | |
+ } else { | |
+ CACHE_PTR(Z_CACHE_SLOT_P(opline->op1.zv), c); | |
+ ZVAL_TRUE(EX_VAR(opline->result.var)); | |
+ } | |
+ CHECK_EXCEPTION(); | |
+ ZEND_VM_NEXT_OPCODE(); | |
+} | |
+ | |
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 ecd15ff..a883a29 100644 | |
--- a/Zend/zend_vm_execute.h | |
+++ b/Zend/zend_vm_execute.h | |
@@ -3399,6 +3399,25 @@ strlen_error: | |
ZEND_VM_NEXT_OPCODE(); | |
} | |
+static int ZEND_FASTCALL ZEND_DEFINED_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) | |
+{ | |
+ USE_OPLINE | |
+ zval *name, *c; | |
+ | |
+ SAVE_OPLINE(); | |
+ name = opline->op1.zv; | |
+ if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op1.zv))) { | |
+ ZVAL_TRUE(EX_VAR(opline->result.var)); | |
+ } else if ((c = zend_get_constant_ex(Z_STR_P(name), NULL, ZEND_FETCH_CLASS_SILENT TSRMLS_CC)) == NULL) { | |
+ ZVAL_FALSE(EX_VAR(opline->result.var)); | |
+ } else { | |
+ CACHE_PTR(Z_CACHE_SLOT_P(opline->op1.zv), c); | |
+ ZVAL_TRUE(EX_VAR(opline->result.var)); | |
+ } | |
+ CHECK_EXCEPTION(); | |
+ ZEND_VM_NEXT_OPCODE(); | |
+} | |
+ | |
static int ZEND_FASTCALL ZEND_ADD_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) | |
{ | |
USE_OPLINE | |
@@ -43796,11 +43815,11 @@ void zend_init_opcodes_handlers(void) | |
ZEND_STRLEN_SPEC_CV_HANDLER, | |
ZEND_STRLEN_SPEC_CV_HANDLER, | |
ZEND_STRLEN_SPEC_CV_HANDLER, | |
- ZEND_NULL_HANDLER, | |
- ZEND_NULL_HANDLER, | |
- ZEND_NULL_HANDLER, | |
- ZEND_NULL_HANDLER, | |
- ZEND_NULL_HANDLER, | |
+ ZEND_DEFINED_SPEC_CONST_HANDLER, | |
+ ZEND_DEFINED_SPEC_CONST_HANDLER, | |
+ ZEND_DEFINED_SPEC_CONST_HANDLER, | |
+ ZEND_DEFINED_SPEC_CONST_HANDLER, | |
+ ZEND_DEFINED_SPEC_CONST_HANDLER, | |
ZEND_NULL_HANDLER, | |
ZEND_NULL_HANDLER, | |
ZEND_NULL_HANDLER, | |
diff --git a/Zend/zend_vm_opcodes.c b/Zend/zend_vm_opcodes.c | |
index 7ae371e..6bb6d78 100644 | |
--- a/Zend/zend_vm_opcodes.c | |
+++ b/Zend/zend_vm_opcodes.c | |
@@ -144,7 +144,7 @@ const char *zend_vm_opcodes_map[169] = { | |
"ZEND_SEND_ARRAY", | |
"ZEND_SEND_USER", | |
"ZEND_STRLEN", | |
- NULL, | |
+ "ZEND_DEFINED", | |
NULL, | |
NULL, | |
NULL, | |
diff --git a/Zend/zend_vm_opcodes.h b/Zend/zend_vm_opcodes.h | |
index 1c20fc6..51516c1 100644 | |
--- a/Zend/zend_vm_opcodes.h | |
+++ b/Zend/zend_vm_opcodes.h | |
@@ -145,6 +145,7 @@ ZEND_API const char *zend_get_opcode_name(zend_uchar opcode); | |
#define ZEND_SEND_ARRAY 119 | |
#define ZEND_SEND_USER 120 | |
#define ZEND_STRLEN 121 | |
+#define ZEND_DEFINED 122 | |
#define ZEND_PRE_INC_OBJ 132 | |
#define ZEND_PRE_DEC_OBJ 133 | |
#define ZEND_POST_INC_OBJ 134 | |
diff --git a/ext/opcache/Optimizer/compact_literals.c b/ext/opcache/Optimizer/compact_literals.c | |
index 61a50a9..7790afb 100644 | |
--- a/ext/opcache/Optimizer/compact_literals.c | |
+++ b/ext/opcache/Optimizer/compact_literals.c | |
@@ -147,6 +147,9 @@ static void optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_c | |
case ZEND_CATCH: | |
LITERAL_INFO(opline->op1.constant, LITERAL_CLASS, 1, 1, 2); | |
break; | |
+ case ZEND_DEFINED: | |
+ LITERAL_INFO(opline->op1.constant, LITERAL_CONST, 1, 1, 1); | |
+ break; | |
case ZEND_FETCH_CONSTANT: | |
if (ZEND_OP1_TYPE(opline) == IS_UNUSED) { | |
if ((opline->extended_value & (IS_CONSTANT_IN_NAMESPACE|IS_CONSTANT_UNQUALIFIED)) == (IS_CONSTANT_IN_NAMESPACE|IS_CONSTANT_UNQUALIFIED)) { | |
diff --git a/ext/opcache/Optimizer/pass1_5.c b/ext/opcache/Optimizer/pass1_5.c | |
index c1235b6..b2e5b1c 100644 | |
--- a/ext/opcache/Optimizer/pass1_5.c | |
+++ b/ext/opcache/Optimizer/pass1_5.c | |
@@ -468,6 +468,19 @@ if (ZEND_OPTIMIZER_PASS_1 & OPTIMIZATION_LEVEL) { | |
MAKE_NOP(opline); | |
} | |
break; | |
+ case ZEND_DEFINED: | |
+ { | |
+ zval c; | |
+ zend_uint tv = ZEND_RESULT(opline).var; | |
+ if (!zend_get_persistent_constant(Z_STR(ZEND_OP1_LITERAL(opline)), &c, 0 TSRMLS_CC)) { | |
+ break; | |
+ } | |
+ ZVAL_TRUE(&c); | |
+ replace_tmp_by_const(op_array, opline, tv, &c TSRMLS_CC); | |
+ literal_dtor(&ZEND_OP1_LITERAL(opline)); | |
+ MAKE_NOP(opline); | |
+ } | |
+ break; | |
#if ZEND_EXTENSION_API_NO > PHP_5_2_X_API_NO | |
case ZEND_DECLARE_CONST: | |
if (collect_constants && |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment