diff options
author | Dmitry Stogov <dmitry@php.net> | 2007-08-17 12:05:19 +0000 |
---|---|---|
committer | Dmitry Stogov <dmitry@php.net> | 2007-08-17 12:05:19 +0000 |
commit | 6e3a76898ec32f1c1a29e550d1011806ef637f61 (patch) | |
tree | ece72b132987bd96666ed1d1ad9e0c24aef79bd4 | |
parent | 8c43fddada8e8d43fb44550d734a329291d37bf9 (diff) | |
download | php-git-6e3a76898ec32f1c1a29e550d1011806ef637f61.tar.gz |
Namespaces: improved run-time speed
-rw-r--r-- | Zend/zend_compile.c | 75 | ||||
-rw-r--r-- | Zend/zend_vm_def.h | 68 | ||||
-rw-r--r-- | Zend/zend_vm_execute.h | 700 |
3 files changed, 262 insertions, 581 deletions
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 99c883e029..6e87c7ebc7 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -1579,7 +1579,7 @@ void zend_do_begin_dynamic_function_call(znode *function_name TSRMLS_DC) /* {{{ } /* }}} */ -void zend_resolve_class_name(znode *class_name, ulong *fetch_type TSRMLS_DC) /* {{{ */ +void zend_resolve_class_name(znode *class_name, ulong *fetch_type, int check_ns_name TSRMLS_DC) /* {{{ */ { zstr compound; unsigned int lcname_len; @@ -1642,14 +1642,17 @@ void zend_resolve_class_name(znode *class_name, ulong *fetch_type TSRMLS_DC) /* zval_copy_ctor(&class_name->u.constant); } else if (CG(current_namespace)) { zend_class_entry **pce; - unsigned int ns_lcname_len; - zstr ns_lcname = zend_u_str_case_fold(Z_TYPE_P(CG(current_namespace)), Z_UNIVAL_P(CG(current_namespace)), Z_UNILEN_P(CG(current_namespace)), 0, &ns_lcname_len); - if (ns_lcname_len == lcname_len && - memcmp(lcname.v, ns_lcname.v, UG(unicode)?UBYTES(lcname_len):lcname_len) == 0) { - *fetch_type |= ZEND_FETCH_CLASS_RT_NS_NAME; + if (check_ns_name) { + unsigned int ns_lcname_len; + zstr ns_lcname = zend_u_str_case_fold(Z_TYPE_P(CG(current_namespace)), Z_UNIVAL_P(CG(current_namespace)), Z_UNILEN_P(CG(current_namespace)), 0, &ns_lcname_len); + + if (ns_lcname_len == lcname_len && + memcmp(lcname.v, ns_lcname.v, UG(unicode)?UBYTES(lcname_len):lcname_len) == 0) { + *fetch_type |= ZEND_FETCH_CLASS_RT_NS_NAME; + } + efree(ns_lcname.v); } - efree(ns_lcname.v); if (zend_u_hash_find(CG(class_table), Z_TYPE(class_name->u.constant), lcname, lcname_len+1, (void**)&pce) == SUCCESS && (*pce)->type == ZEND_INTERNAL_CLASS) { @@ -1690,7 +1693,7 @@ void zend_do_fetch_class(znode *result, znode *class_name TSRMLS_DC) /* {{{ */ zval_dtor(&class_name->u.constant); break; default: { - zend_resolve_class_name(class_name, &opline->extended_value TSRMLS_CC); + zend_resolve_class_name(class_name, &opline->extended_value, 0 TSRMLS_CC); opline->op2 = *class_name; break; } @@ -1761,7 +1764,7 @@ void zend_do_begin_class_member_function_call(znode *class_name, znode *method_n method_name->op_type == IS_CONST && ZEND_FETCH_CLASS_DEFAULT == zend_get_class_fetch_type(Z_TYPE(class_name->u.constant), Z_UNIVAL(class_name->u.constant), Z_UNILEN(class_name->u.constant))) { fetch_type = ZEND_FETCH_CLASS_GLOBAL; - zend_resolve_class_name(class_name, &fetch_type TSRMLS_CC); + zend_resolve_class_name(class_name, &fetch_type, 1 TSRMLS_CC); class_node = *class_name; } else { zend_do_fetch_class(&class_node, class_name TSRMLS_CC); @@ -1772,6 +1775,58 @@ void zend_do_begin_class_member_function_call(znode *class_name, znode *method_n opline->op1 = class_node; opline->op2 = *method_name; + if (class_node.op_type == IS_CONST && + method_name->op_type == IS_CONST) { + /* Prebuild ns::func name to speedup run-time check */ + zstr fname, lcname; + unsigned int len, lcname_len; + + opline = get_next_op(CG(active_op_array) TSRMLS_CC); + opline->opcode = ZEND_OP_DATA; + opline->op1.op_type = IS_CONST; + SET_UNUSED(opline->op2); + + len = Z_UNILEN(class_node.u.constant) + 2 + Z_UNILEN(method_name->u.constant); + if (UG(unicode)) { + fname.u = eumalloc(len + 1); + memcpy(fname.u, Z_USTRVAL(class_node.u.constant), UBYTES(Z_USTRLEN(class_node.u.constant))); + fname.u[Z_USTRLEN(class_node.u.constant)] = ':'; + fname.u[Z_USTRLEN(class_node.u.constant)+1] = ':'; + memcpy(fname.u+Z_USTRLEN(class_node.u.constant)+2, + Z_USTRVAL(method_name->u.constant), + UBYTES(Z_USTRLEN(method_name->u.constant)+1)); + lcname = zend_u_str_case_fold(IS_UNICODE, fname, len, 1, &lcname_len); + opline->extended_value = zend_u_hash_func(IS_UNICODE, lcname, lcname_len + 1); + ZVAL_UNICODEL(&opline->op1.u.constant, lcname.u, lcname_len, 0); + } else { + fname.s = emalloc(len + 1); + memcpy(fname.s, Z_STRVAL(class_node.u.constant), Z_STRLEN(class_node.u.constant)); + fname.s[Z_STRLEN(class_node.u.constant)] = ':'; + fname.s[Z_STRLEN(class_node.u.constant)+1] = ':'; + memcpy(fname.s+Z_STRLEN(class_node.u.constant)+2, + Z_STRVAL(method_name->u.constant), + Z_STRLEN(method_name->u.constant)+1); + lcname = zend_u_str_case_fold(IS_STRING, fname, len, 1, &lcname_len); + opline->extended_value = zend_u_hash_func(IS_STRING, lcname, lcname_len + 1); + ZVAL_STRINGL(&opline->op1.u.constant, lcname.s, lcname_len, 0); + } + efree(fname.v); + + if (fetch_type & ZEND_FETCH_CLASS_RT_NS_NAME) { + zstr colon; + + if (UG(unicode) && (colon.u = u_memchr(lcname.u, ':', lcname_len)) && colon.u[1] == ':') { + colon.u += 2; + opline->op2.op_type = IS_CONST; + ZVAL_UNICODEL(&opline->op2.u.constant, colon.u, lcname_len - (colon.u - lcname.u), 1); + } else if (!UG(unicode) && (colon.s = memchr(lcname.s, ':', lcname_len)) && colon.s[1] == ':') { + colon.s += 2; + opline->op2.op_type = IS_CONST; + ZVAL_STRINGL(&opline->op2.u.constant, colon.s, lcname_len - (colon.s - lcname.s), 1); + } + } + } + zend_stack_push(&CG(function_call_stack), (void *) &ptr, sizeof(zend_function *)); zend_do_extended_fcall_begin(TSRMLS_C); } @@ -3658,7 +3713,7 @@ void zend_do_fetch_constant(znode *result, znode *constant_container, znode *con ulong fetch_type; if (ZEND_FETCH_CLASS_DEFAULT == zend_get_class_fetch_type(Z_TYPE(constant_container->u.constant), Z_UNIVAL(constant_container->u.constant), Z_UNILEN(constant_container->u.constant))) { - zend_resolve_class_name(constant_container, &fetch_type TSRMLS_CC); + zend_resolve_class_name(constant_container, &fetch_type, 1 TSRMLS_CC); } zend_do_fetch_class_name(NULL, constant_container, constant_name TSRMLS_CC); *result = *constant_container; diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index e0f2eb2867..546080118a 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -1793,33 +1793,11 @@ ZEND_VM_HANDLER(113, ZEND_INIT_STATIC_METHOD_CALL, CONST|VAR, CONST|TMP|VAR|UNUS if (OP1_TYPE == IS_CONST && OP2_TYPE == IS_CONST) { /* try a function in namespace */ - zstr fname, lcname; - unsigned int len, lcname_len; - - len = Z_UNILEN(opline->op1.u.constant) + 2 + Z_UNILEN(opline->op2.u.constant); - if (UG(unicode)) { - fname.u = eumalloc(len + 1); - memcpy(fname.u, Z_USTRVAL(opline->op1.u.constant), UBYTES(Z_USTRLEN(opline->op1.u.constant))); - fname.u[Z_USTRLEN(opline->op1.u.constant)] = ':'; - fname.u[Z_USTRLEN(opline->op1.u.constant)+1] = ':'; - memcpy(fname.u+Z_USTRLEN(opline->op1.u.constant)+2, - Z_USTRVAL(opline->op2.u.constant), - UBYTES(Z_USTRLEN(opline->op2.u.constant)+1)); - lcname = zend_u_str_case_fold(IS_UNICODE, fname, len, 1, &lcname_len); - } else { - fname.s = emalloc(len + 1); - memcpy(fname.s, Z_STRVAL(opline->op1.u.constant), Z_STRLEN(opline->op1.u.constant)); - fname.s[Z_STRLEN(opline->op1.u.constant)] = ':'; - fname.s[Z_STRLEN(opline->op1.u.constant)+1] = ':'; - memcpy(fname.s+Z_STRLEN(opline->op1.u.constant)+2, - Z_STRVAL(opline->op2.u.constant), - Z_STRLEN(opline->op2.u.constant)+1); - lcname = zend_u_str_case_fold(IS_STRING, fname, len, 1, &lcname_len); - } - efree(fname.v); + zend_op *op_data = opline+1; - if (zend_u_hash_find(EG(function_table), ZEND_STR_TYPE, lcname, lcname_len+1, (void **) &EX(fbc))==SUCCESS) { - efree(lcname.v); + ZEND_VM_INC_OPCODE(); + + if (zend_u_hash_quick_find(EG(function_table), Z_TYPE(op_data->op1.u.constant), Z_UNIVAL(op_data->op1.u.constant), Z_UNILEN(op_data->op1.u.constant)+1, op_data->extended_value, (void **) &EX(fbc))==SUCCESS) { EX(object) = NULL; ZEND_VM_NEXT_OPCODE(); } @@ -1828,34 +1806,24 @@ ZEND_VM_HANDLER(113, ZEND_INIT_STATIC_METHOD_CALL, CONST|VAR, CONST|TMP|VAR|UNUS ce = zend_u_fetch_class(Z_TYPE(opline->op1.u.constant), Z_UNIVAL(opline->op1.u.constant), Z_UNILEN(opline->op1.u.constant), (opline->extended_value & ZEND_FETCH_CLASS_RT_NS_NAME) ? (opline->extended_value & ~ZEND_FETCH_CLASS_RT_NS_CHECK) : opline->extended_value TSRMLS_CC); if (!ce) { - if (opline->extended_value & ZEND_FETCH_CLASS_RT_NS_NAME) { - zstr ns; - - if (UG(unicode) && (ns.u = u_memchr(lcname.u, ':', lcname_len)) && ns.u[1] == ':') { - ns.u += 2; - lcname_len -= (ns.u - lcname.u); - if (zend_u_hash_find(EG(function_table), ZEND_STR_TYPE, ns, lcname_len+1, (void **) &EX(fbc))==SUCCESS) { - efree(lcname.v); - EX(object) = NULL; - ZEND_VM_NEXT_OPCODE(); - } - } else if (!UG(unicode) && (ns.s = memchr(lcname.s, ':', lcname_len)) && ns.s[1] == ':') { - ns.s += 2; - lcname_len -= (ns.s - lcname.s); - if (zend_u_hash_find(EG(function_table), ZEND_STR_TYPE, ns, lcname_len+1, (void **) &EX(fbc))==SUCCESS) { - efree(lcname.v); - EX(object) = NULL; - ZEND_VM_NEXT_OPCODE(); - } + if ((opline->extended_value & ZEND_FETCH_CLASS_RT_NS_NAME) && + op_data->op2.op_type == IS_CONST) { + + if (zend_u_hash_find(EG(function_table), Z_TYPE(op_data->op2.u.constant), Z_UNIVAL(op_data->op2.u.constant), Z_UNILEN(op_data->op2.u.constant) + 1, (void **) &EX(fbc))==SUCCESS) { + EX(object) = NULL; + ZEND_VM_NEXT_OPCODE(); } + if (opline->extended_value & ZEND_FETCH_CLASS_RT_NS_CHECK) { - lcname_len -= Z_UNILEN(opline->op2.u.constant) + 2; + zstr ce_name; + unsigned ce_name_len = Z_UNILEN(op_data->op1.u.constant) - (Z_UNILEN(op_data->op2.u.constant) + 2); if (UG(unicode)) { - ns.u[lcname_len] = 0; + ce_name.u = eustrndup(Z_USTRVAL(op_data->op1.u.constant), ce_name_len); } else { - ns.s[lcname_len] = 0; + ce_name.s = estrndup(Z_STRVAL(op_data->op1.u.constant), ce_name_len); } - ce = zend_u_fetch_class(Z_TYPE(opline->op1.u.constant), ns, lcname_len, opline->extended_value & ~ZEND_FETCH_CLASS_RT_NS_CHECK TSRMLS_CC); + ce = zend_u_fetch_class(Z_TYPE(opline->op1.u.constant), ce_name, ce_name_len, opline->extended_value & ~ZEND_FETCH_CLASS_RT_NS_CHECK TSRMLS_CC); + efree(ce_name.v); if (!ce) { zend_error(E_ERROR, "Class '%R' not found", Z_TYPE(opline->op1.u.constant), Z_UNIVAL(opline->op1.u.constant)); } @@ -1866,8 +1834,6 @@ ZEND_VM_HANDLER(113, ZEND_INIT_STATIC_METHOD_CALL, CONST|VAR, CONST|TMP|VAR|UNUS zend_error(E_ERROR, "Class '%R' not found", Z_TYPE(opline->op1.u.constant), Z_UNIVAL(opline->op1.u.constant)); } } - - efree(lcname.v); } else { ce = EX_T(opline->op1.u.var).class_entry; } diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 2fa433fcaa..fa46efb4d1 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -2545,33 +2545,11 @@ static int ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HAN if (IS_CONST == IS_CONST && IS_CONST == IS_CONST) { /* try a function in namespace */ - zstr fname, lcname; - unsigned int len, lcname_len; - - len = Z_UNILEN(opline->op1.u.constant) + 2 + Z_UNILEN(opline->op2.u.constant); - if (UG(unicode)) { - fname.u = eumalloc(len + 1); - memcpy(fname.u, Z_USTRVAL(opline->op1.u.constant), UBYTES(Z_USTRLEN(opline->op1.u.constant))); - fname.u[Z_USTRLEN(opline->op1.u.constant)] = ':'; - fname.u[Z_USTRLEN(opline->op1.u.constant)+1] = ':'; - memcpy(fname.u+Z_USTRLEN(opline->op1.u.constant)+2, - Z_USTRVAL(opline->op2.u.constant), - UBYTES(Z_USTRLEN(opline->op2.u.constant)+1)); - lcname = zend_u_str_case_fold(IS_UNICODE, fname, len, 1, &lcname_len); - } else { - fname.s = emalloc(len + 1); - memcpy(fname.s, Z_STRVAL(opline->op1.u.constant), Z_STRLEN(opline->op1.u.constant)); - fname.s[Z_STRLEN(opline->op1.u.constant)] = ':'; - fname.s[Z_STRLEN(opline->op1.u.constant)+1] = ':'; - memcpy(fname.s+Z_STRLEN(opline->op1.u.constant)+2, - Z_STRVAL(opline->op2.u.constant), - Z_STRLEN(opline->op2.u.constant)+1); - lcname = zend_u_str_case_fold(IS_STRING, fname, len, 1, &lcname_len); - } - efree(fname.v); - - if (zend_u_hash_find(EG(function_table), ZEND_STR_TYPE, lcname, lcname_len+1, (void **) &EX(fbc))==SUCCESS) { - efree(lcname.v); + zend_op *op_data = opline+1; + + ZEND_VM_INC_OPCODE(); + + if (zend_u_hash_quick_find(EG(function_table), Z_TYPE(op_data->op1.u.constant), Z_UNIVAL(op_data->op1.u.constant), Z_UNILEN(op_data->op1.u.constant)+1, op_data->extended_value, (void **) &EX(fbc))==SUCCESS) { EX(object) = NULL; ZEND_VM_NEXT_OPCODE(); } @@ -2580,34 +2558,24 @@ static int ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HAN ce = zend_u_fetch_class(Z_TYPE(opline->op1.u.constant), Z_UNIVAL(opline->op1.u.constant), Z_UNILEN(opline->op1.u.constant), (opline->extended_value & ZEND_FETCH_CLASS_RT_NS_NAME) ? (opline->extended_value & ~ZEND_FETCH_CLASS_RT_NS_CHECK) : opline->extended_value TSRMLS_CC); if (!ce) { - if (opline->extended_value & ZEND_FETCH_CLASS_RT_NS_NAME) { - zstr ns; - - if (UG(unicode) && (ns.u = u_memchr(lcname.u, ':', lcname_len)) && ns.u[1] == ':') { - ns.u += 2; - lcname_len -= (ns.u - lcname.u); - if (zend_u_hash_find(EG(function_table), ZEND_STR_TYPE, ns, lcname_len+1, (void **) &EX(fbc))==SUCCESS) { - efree(lcname.v); - EX(object) = NULL; - ZEND_VM_NEXT_OPCODE(); - } - } else if (!UG(unicode) && (ns.s = memchr(lcname.s, ':', lcname_len)) && ns.s[1] == ':') { - ns.s += 2; - lcname_len -= (ns.s - lcname.s); - if (zend_u_hash_find(EG(function_table), ZEND_STR_TYPE, ns, lcname_len+1, (void **) &EX(fbc))==SUCCESS) { - efree(lcname.v); - EX(object) = NULL; - ZEND_VM_NEXT_OPCODE(); - } + if ((opline->extended_value & ZEND_FETCH_CLASS_RT_NS_NAME) && + op_data->op2.op_type == IS_CONST) { + + if (zend_u_hash_find(EG(function_table), Z_TYPE(op_data->op2.u.constant), Z_UNIVAL(op_data->op2.u.constant), Z_UNILEN(op_data->op2.u.constant) + 1, (void **) &EX(fbc))==SUCCESS) { + EX(object) = NULL; + ZEND_VM_NEXT_OPCODE(); } + if (opline->extended_value & ZEND_FETCH_CLASS_RT_NS_CHECK) { - lcname_len -= Z_UNILEN(opline->op2.u.constant) + 2; + zstr ce_name; + unsigned ce_name_len = Z_UNILEN(op_data->op1.u.constant) - (Z_UNILEN(op_data->op2.u.constant) + 2); if (UG(unicode)) { - ns.u[lcname_len] = 0; + ce_name.u = eustrndup(Z_USTRVAL(op_data->op1.u.constant), ce_name_len); } else { - ns.s[lcname_len] = 0; + ce_name.s = estrndup(Z_STRVAL(op_data->op1.u.constant), ce_name_len); } - ce = zend_u_fetch_class(Z_TYPE(opline->op1.u.constant), ns, lcname_len, opline->extended_value & ~ZEND_FETCH_CLASS_RT_NS_CHECK TSRMLS_CC); + ce = zend_u_fetch_class(Z_TYPE(opline->op1.u.constant), ce_name, ce_name_len, opline->extended_value & ~ZEND_FETCH_CLASS_RT_NS_CHECK TSRMLS_CC); + efree(ce_name.v); if (!ce) { zend_error(E_ERROR, "Class '%R' not found", Z_TYPE(opline->op1.u.constant), Z_UNIVAL(opline->op1.u.constant)); } @@ -2618,8 +2586,6 @@ static int ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HAN zend_error(E_ERROR, "Class '%R' not found", Z_TYPE(opline->op1.u.constant), Z_UNIVAL(opline->op1.u.constant)); } } - - efree(lcname.v); } else { ce = EX_T(opline->op1.u.var).class_entry; } @@ -3050,33 +3016,11 @@ static int ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDL if (IS_CONST == IS_CONST && IS_TMP_VAR == IS_CONST) { /* try a function in namespace */ - zstr fname, lcname; - unsigned int len, lcname_len; - - len = Z_UNILEN(opline->op1.u.constant) + 2 + Z_UNILEN(opline->op2.u.constant); - if (UG(unicode)) { - fname.u = eumalloc(len + 1); - memcpy(fname.u, Z_USTRVAL(opline->op1.u.constant), UBYTES(Z_USTRLEN(opline->op1.u.constant))); - fname.u[Z_USTRLEN(opline->op1.u.constant)] = ':'; - fname.u[Z_USTRLEN(opline->op1.u.constant)+1] = ':'; - memcpy(fname.u+Z_USTRLEN(opline->op1.u.constant)+2, - Z_USTRVAL(opline->op2.u.constant), - UBYTES(Z_USTRLEN(opline->op2.u.constant)+1)); - lcname = zend_u_str_case_fold(IS_UNICODE, fname, len, 1, &lcname_len); - } else { - fname.s = emalloc(len + 1); - memcpy(fname.s, Z_STRVAL(opline->op1.u.constant), Z_STRLEN(opline->op1.u.constant)); - fname.s[Z_STRLEN(opline->op1.u.constant)] = ':'; - fname.s[Z_STRLEN(opline->op1.u.constant)+1] = ':'; - memcpy(fname.s+Z_STRLEN(opline->op1.u.constant)+2, - Z_STRVAL(opline->op2.u.constant), - Z_STRLEN(opline->op2.u.constant)+1); - lcname = zend_u_str_case_fold(IS_STRING, fname, len, 1, &lcname_len); - } - efree(fname.v); - - if (zend_u_hash_find(EG(function_table), ZEND_STR_TYPE, lcname, lcname_len+1, (void **) &EX(fbc))==SUCCESS) { - efree(lcname.v); + zend_op *op_data = opline+1; + + ZEND_VM_INC_OPCODE(); + + if (zend_u_hash_quick_find(EG(function_table), Z_TYPE(op_data->op1.u.constant), Z_UNIVAL(op_data->op1.u.constant), Z_UNILEN(op_data->op1.u.constant)+1, op_data->extended_value, (void **) &EX(fbc))==SUCCESS) { EX(object) = NULL; ZEND_VM_NEXT_OPCODE(); } @@ -3085,34 +3029,24 @@ static int ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDL ce = zend_u_fetch_class(Z_TYPE(opline->op1.u.constant), Z_UNIVAL(opline->op1.u.constant), Z_UNILEN(opline->op1.u.constant), (opline->extended_value & ZEND_FETCH_CLASS_RT_NS_NAME) ? (opline->extended_value & ~ZEND_FETCH_CLASS_RT_NS_CHECK) : opline->extended_value TSRMLS_CC); if (!ce) { - if (opline->extended_value & ZEND_FETCH_CLASS_RT_NS_NAME) { - zstr ns; - - if (UG(unicode) && (ns.u = u_memchr(lcname.u, ':', lcname_len)) && ns.u[1] == ':') { - ns.u += 2; - lcname_len -= (ns.u - lcname.u); - if (zend_u_hash_find(EG(function_table), ZEND_STR_TYPE, ns, lcname_len+1, (void **) &EX(fbc))==SUCCESS) { - efree(lcname.v); - EX(object) = NULL; - ZEND_VM_NEXT_OPCODE(); - } - } else if (!UG(unicode) && (ns.s = memchr(lcname.s, ':', lcname_len)) && ns.s[1] == ':') { - ns.s += 2; - lcname_len -= (ns.s - lcname.s); - if (zend_u_hash_find(EG(function_table), ZEND_STR_TYPE, ns, lcname_len+1, (void **) &EX(fbc))==SUCCESS) { - efree(lcname.v); - EX(object) = NULL; - ZEND_VM_NEXT_OPCODE(); - } + if ((opline->extended_value & ZEND_FETCH_CLASS_RT_NS_NAME) && + op_data->op2.op_type == IS_CONST) { + + if (zend_u_hash_find(EG(function_table), Z_TYPE(op_data->op2.u.constant), Z_UNIVAL(op_data->op2.u.constant), Z_UNILEN(op_data->op2.u.constant) + 1, (void **) &EX(fbc))==SUCCESS) { + EX(object) = NULL; + ZEND_VM_NEXT_OPCODE(); } + if (opline->extended_value & ZEND_FETCH_CLASS_RT_NS_CHECK) { - lcname_len -= Z_UNILEN(opline->op2.u.constant) + 2; + zstr ce_name; + unsigned ce_name_len = Z_UNILEN(op_data->op1.u.constant) - (Z_UNILEN(op_data->op2.u.constant) + 2); if (UG(unicode)) { - ns.u[lcname_len] = 0; + ce_name.u = eustrndup(Z_USTRVAL(op_data->op1.u.constant), ce_name_len); } else { - ns.s[lcname_len] = 0; + ce_name.s = estrndup(Z_STRVAL(op_data->op1.u.constant), ce_name_len); } - ce = zend_u_fetch_class(Z_TYPE(opline->op1.u.constant), ns, lcname_len, opline->extended_value & ~ZEND_FETCH_CLASS_RT_NS_CHECK TSRMLS_CC); + ce = zend_u_fetch_class(Z_TYPE(opline->op1.u.constant), ce_name, ce_name_len, opline->extended_value & ~ZEND_FETCH_CLASS_RT_NS_CHECK TSRMLS_CC); + efree(ce_name.v); if (!ce) { zend_error(E_ERROR, "Class '%R' not found", Z_TYPE(opline->op1.u.constant), Z_UNIVAL(opline->op1.u.constant)); } @@ -3123,8 +3057,6 @@ static int ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDL zend_error(E_ERROR, "Class '%R' not found", Z_TYPE(opline->op1.u.constant), Z_UNIVAL(opline->op1.u.constant)); } } - - efree(lcname.v); } else { ce = EX_T(opline->op1.u.var).class_entry; } @@ -3556,33 +3488,11 @@ static int ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDL if (IS_CONST == IS_CONST && IS_VAR == IS_CONST) { /* try a function in namespace */ - zstr fname, lcname; - unsigned int len, lcname_len; - - len = Z_UNILEN(opline->op1.u.constant) + 2 + Z_UNILEN(opline->op2.u.constant); - if (UG(unicode)) { - fname.u = eumalloc(len + 1); - memcpy(fname.u, Z_USTRVAL(opline->op1.u.constant), UBYTES(Z_USTRLEN(opline->op1.u.constant))); - fname.u[Z_USTRLEN(opline->op1.u.constant)] = ':'; - fname.u[Z_USTRLEN(opline->op1.u.constant)+1] = ':'; - memcpy(fname.u+Z_USTRLEN(opline->op1.u.constant)+2, - Z_USTRVAL(opline->op2.u.constant), - UBYTES(Z_USTRLEN(opline->op2.u.constant)+1)); - lcname = zend_u_str_case_fold(IS_UNICODE, fname, len, 1, &lcname_len); - } else { - fname.s = emalloc(len + 1); - memcpy(fname.s, Z_STRVAL(opline->op1.u.constant), Z_STRLEN(opline->op1.u.constant)); - fname.s[Z_STRLEN(opline->op1.u.constant)] = ':'; - fname.s[Z_STRLEN(opline->op1.u.constant)+1] = ':'; - memcpy(fname.s+Z_STRLEN(opline->op1.u.constant)+2, - Z_STRVAL(opline->op2.u.constant), - Z_STRLEN(opline->op2.u.constant)+1); - lcname = zend_u_str_case_fold(IS_STRING, fname, len, 1, &lcname_len); - } - efree(fname.v); - - if (zend_u_hash_find(EG(function_table), ZEND_STR_TYPE, lcname, lcname_len+1, (void **) &EX(fbc))==SUCCESS) { - efree(lcname.v); + zend_op *op_data = opline+1; + + ZEND_VM_INC_OPCODE(); + + if (zend_u_hash_quick_find(EG(function_table), Z_TYPE(op_data->op1.u.constant), Z_UNIVAL(op_data->op1.u.constant), Z_UNILEN(op_data->op1.u.constant)+1, op_data->extended_value, (void **) &EX(fbc))==SUCCESS) { EX(object) = NULL; ZEND_VM_NEXT_OPCODE(); } @@ -3591,34 +3501,24 @@ static int ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDL ce = zend_u_fetch_class(Z_TYPE(opline->op1.u.constant), Z_UNIVAL(opline->op1.u.constant), Z_UNILEN(opline->op1.u.constant), (opline->extended_value & ZEND_FETCH_CLASS_RT_NS_NAME) ? (opline->extended_value & ~ZEND_FETCH_CLASS_RT_NS_CHECK) : opline->extended_value TSRMLS_CC); if (!ce) { - if (opline->extended_value & ZEND_FETCH_CLASS_RT_NS_NAME) { - zstr ns; - - if (UG(unicode) && (ns.u = u_memchr(lcname.u, ':', lcname_len)) && ns.u[1] == ':') { - ns.u += 2; - lcname_len -= (ns.u - lcname.u); - if (zend_u_hash_find(EG(function_table), ZEND_STR_TYPE, ns, lcname_len+1, (void **) &EX(fbc))==SUCCESS) { - efree(lcname.v); - EX(object) = NULL; - ZEND_VM_NEXT_OPCODE(); - } - } else if (!UG(unicode) && (ns.s = memchr(lcname.s, ':', lcname_len)) && ns.s[1] == ':') { - ns.s += 2; - lcname_len -= (ns.s - lcname.s); - if (zend_u_hash_find(EG(function_table), ZEND_STR_TYPE, ns, lcname_len+1, (void **) &EX(fbc))==SUCCESS) { - efree(lcname.v); - EX(object) = NULL; - ZEND_VM_NEXT_OPCODE(); - } + if ((opline->extended_value & ZEND_FETCH_CLASS_RT_NS_NAME) && + op_data->op2.op_type == IS_CONST) { + + if (zend_u_hash_find(EG(function_table), Z_TYPE(op_data->op2.u.constant), Z_UNIVAL(op_data->op2.u.constant), Z_UNILEN(op_data->op2.u.constant) + 1, (void **) &EX(fbc))==SUCCESS) { + EX(object) = NULL; + ZEND_VM_NEXT_OPCODE(); } + if (opline->extended_value & ZEND_FETCH_CLASS_RT_NS_CHECK) { - lcname_len -= Z_UNILEN(opline->op2.u.constant) + 2; + zstr ce_name; + unsigned ce_name_len = Z_UNILEN(op_data->op1.u.constant) - (Z_UNILEN(op_data->op2.u.constant) + 2); if (UG(unicode)) { - ns.u[lcname_len] = 0; + ce_name.u = eustrndup(Z_USTRVAL(op_data->op1.u.constant), ce_name_len); } else { - ns.s[lcname_len] = 0; + ce_name.s = estrndup(Z_STRVAL(op_data->op1.u.constant), ce_name_len); } - ce = zend_u_fetch_class(Z_TYPE(opline->op1.u.constant), ns, lcname_len, opline->extended_value & ~ZEND_FETCH_CLASS_RT_NS_CHECK TSRMLS_CC); + ce = zend_u_fetch_class(Z_TYPE(opline->op1.u.constant), ce_name, ce_name_len, opline->extended_value & ~ZEND_FETCH_CLASS_RT_NS_CHECK TSRMLS_CC); + efree(ce_name.v); if (!ce) { zend_error(E_ERROR, "Class '%R' not found", Z_TYPE(opline->op1.u.constant), Z_UNIVAL(opline->op1.u.constant)); } @@ -3629,8 +3529,6 @@ static int ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDL zend_error(E_ERROR, "Class '%R' not found", Z_TYPE(opline->op1.u.constant), Z_UNIVAL(opline->op1.u.constant)); } } - - efree(lcname.v); } else { ce = EX_T(opline->op1.u.var).class_entry; } @@ -3828,33 +3726,11 @@ static int ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HA if (IS_CONST == IS_CONST && IS_UNUSED == IS_CONST) { /* try a function in namespace */ - zstr fname, lcname; - unsigned int len, lcname_len; - - len = Z_UNILEN(opline->op1.u.constant) + 2 + Z_UNILEN(opline->op2.u.constant); - if (UG(unicode)) { - fname.u = eumalloc(len + 1); - memcpy(fname.u, Z_USTRVAL(opline->op1.u.constant), UBYTES(Z_USTRLEN(opline->op1.u.constant))); - fname.u[Z_USTRLEN(opline->op1.u.constant)] = ':'; - fname.u[Z_USTRLEN(opline->op1.u.constant)+1] = ':'; - memcpy(fname.u+Z_USTRLEN(opline->op1.u.constant)+2, - Z_USTRVAL(opline->op2.u.constant), - UBYTES(Z_USTRLEN(opline->op2.u.constant)+1)); - lcname = zend_u_str_case_fold(IS_UNICODE, fname, len, 1, &lcname_len); - } else { - fname.s = emalloc(len + 1); - memcpy(fname.s, Z_STRVAL(opline->op1.u.constant), Z_STRLEN(opline->op1.u.constant)); - fname.s[Z_STRLEN(opline->op1.u.constant)] = ':'; - fname.s[Z_STRLEN(opline->op1.u.constant)+1] = ':'; - memcpy(fname.s+Z_STRLEN(opline->op1.u.constant)+2, - Z_STRVAL(opline->op2.u.constant), - Z_STRLEN(opline->op2.u.constant)+1); - lcname = zend_u_str_case_fold(IS_STRING, fname, len, 1, &lcname_len); - } - efree(fname.v); - - if (zend_u_hash_find(EG(function_table), ZEND_STR_TYPE, lcname, lcname_len+1, (void **) &EX(fbc))==SUCCESS) { - efree(lcname.v); + zend_op *op_data = opline+1; + + ZEND_VM_INC_OPCODE(); + + if (zend_u_hash_quick_find(EG(function_table), Z_TYPE(op_data->op1.u.constant), Z_UNIVAL(op_data->op1.u.constant), Z_UNILEN(op_data->op1.u.constant)+1, op_data->extended_value, (void **) &EX(fbc))==SUCCESS) { EX(object) = NULL; ZEND_VM_NEXT_OPCODE(); } @@ -3863,34 +3739,24 @@ static int ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HA ce = zend_u_fetch_class(Z_TYPE(opline->op1.u.constant), Z_UNIVAL(opline->op1.u.constant), Z_UNILEN(opline->op1.u.constant), (opline->extended_value & ZEND_FETCH_CLASS_RT_NS_NAME) ? (opline->extended_value & ~ZEND_FETCH_CLASS_RT_NS_CHECK) : opline->extended_value TSRMLS_CC); if (!ce) { - if (opline->extended_value & ZEND_FETCH_CLASS_RT_NS_NAME) { - zstr ns; - - if (UG(unicode) && (ns.u = u_memchr(lcname.u, ':', lcname_len)) && ns.u[1] == ':') { - ns.u += 2; - lcname_len -= (ns.u - lcname.u); - if (zend_u_hash_find(EG(function_table), ZEND_STR_TYPE, ns, lcname_len+1, (void **) &EX(fbc))==SUCCESS) { - efree(lcname.v); - EX(object) = NULL; - ZEND_VM_NEXT_OPCODE(); - } - } else if (!UG(unicode) && (ns.s = memchr(lcname.s, ':', lcname_len)) && ns.s[1] == ':') { - ns.s += 2; - lcname_len -= (ns.s - lcname.s); - if (zend_u_hash_find(EG(function_table), ZEND_STR_TYPE, ns, lcname_len+1, (void **) &EX(fbc))==SUCCESS) { - efree(lcname.v); - EX(object) = NULL; - ZEND_VM_NEXT_OPCODE(); - } + if ((opline->extended_value & ZEND_FETCH_CLASS_RT_NS_NAME) && + op_data->op2.op_type == IS_CONST) { + + if (zend_u_hash_find(EG(function_table), Z_TYPE(op_data->op2.u.constant), Z_UNIVAL(op_data->op2.u.constant), Z_UNILEN(op_data->op2.u.constant) + 1, (void **) &EX(fbc))==SUCCESS) { + EX(object) = NULL; + ZEND_VM_NEXT_OPCODE(); } + if (opline->extended_value & ZEND_FETCH_CLASS_RT_NS_CHECK) { - lcname_len -= Z_UNILEN(opline->op2.u.constant) + 2; + zstr ce_name; + unsigned ce_name_len = Z_UNILEN(op_data->op1.u.constant) - (Z_UNILEN(op_data->op2.u.constant) + 2); if (UG(unicode)) { - ns.u[lcname_len] = 0; + ce_name.u = eustrndup(Z_USTRVAL(op_data->op1.u.constant), ce_name_len); } else { - ns.s[lcname_len] = 0; + ce_name.s = estrndup(Z_STRVAL(op_data->op1.u.constant), ce_name_len); } - ce = zend_u_fetch_class(Z_TYPE(opline->op1.u.constant), ns, lcname_len, opline->extended_value & ~ZEND_FETCH_CLASS_RT_NS_CHECK TSRMLS_CC); + ce = zend_u_fetch_class(Z_TYPE(opline->op1.u.constant), ce_name, ce_name_len, opline->extended_value & ~ZEND_FETCH_CLASS_RT_NS_CHECK TSRMLS_CC); + efree(ce_name.v); if (!ce) { zend_error(E_ERROR, "Class '%R' not found", Z_TYPE(opline->op1.u.constant), Z_UNIVAL(opline->op1.u.constant)); } @@ -3901,8 +3767,6 @@ static int ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HA zend_error(E_ERROR, "Class '%R' not found", Z_TYPE(opline->op1.u.constant), Z_UNIVAL(opline->op1.u.constant)); } } - - efree(lcname.v); } else { ce = EX_T(opline->op1.u.var).class_entry; } @@ -4302,33 +4166,11 @@ static int ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLE if (IS_CONST == IS_CONST && IS_CV == IS_CONST) { /* try a function in namespace */ - zstr fname, lcname; - unsigned int len, lcname_len; - - len = Z_UNILEN(opline->op1.u.constant) + 2 + Z_UNILEN(opline->op2.u.constant); - if (UG(unicode)) { - fname.u = eumalloc(len + 1); - memcpy(fname.u, Z_USTRVAL(opline->op1.u.constant), UBYTES(Z_USTRLEN(opline->op1.u.constant))); - fname.u[Z_USTRLEN(opline->op1.u.constant)] = ':'; - fname.u[Z_USTRLEN(opline->op1.u.constant)+1] = ':'; - memcpy(fname.u+Z_USTRLEN(opline->op1.u.constant)+2, - Z_USTRVAL(opline->op2.u.constant), - UBYTES(Z_USTRLEN(opline->op2.u.constant)+1)); - lcname = zend_u_str_case_fold(IS_UNICODE, fname, len, 1, &lcname_len); - } else { - fname.s = emalloc(len + 1); - memcpy(fname.s, Z_STRVAL(opline->op1.u.constant), Z_STRLEN(opline->op1.u.constant)); - fname.s[Z_STRLEN(opline->op1.u.constant)] = ':'; - fname.s[Z_STRLEN(opline->op1.u.constant)+1] = ':'; - memcpy(fname.s+Z_STRLEN(opline->op1.u.constant)+2, - Z_STRVAL(opline->op2.u.constant), - Z_STRLEN(opline->op2.u.constant)+1); - lcname = zend_u_str_case_fold(IS_STRING, fname, len, 1, &lcname_len); - } - efree(fname.v); - - if (zend_u_hash_find(EG(function_table), ZEND_STR_TYPE, lcname, lcname_len+1, (void **) &EX(fbc))==SUCCESS) { - efree(lcname.v); + zend_op *op_data = opline+1; + + ZEND_VM_INC_OPCODE(); + + if (zend_u_hash_quick_find(EG(function_table), Z_TYPE(op_data->op1.u.constant), Z_UNIVAL(op_data->op1.u.constant), Z_UNILEN(op_data->op1.u.constant)+1, op_data->extended_value, (void **) &EX(fbc))==SUCCESS) { EX(object) = NULL; ZEND_VM_NEXT_OPCODE(); } @@ -4337,34 +4179,24 @@ static int ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLE ce = zend_u_fetch_class(Z_TYPE(opline->op1.u.constant), Z_UNIVAL(opline->op1.u.constant), Z_UNILEN(opline->op1.u.constant), (opline->extended_value & ZEND_FETCH_CLASS_RT_NS_NAME) ? (opline->extended_value & ~ZEND_FETCH_CLASS_RT_NS_CHECK) : opline->extended_value TSRMLS_CC); if (!ce) { - if (opline->extended_value & ZEND_FETCH_CLASS_RT_NS_NAME) { - zstr ns; - - if (UG(unicode) && (ns.u = u_memchr(lcname.u, ':', lcname_len)) && ns.u[1] == ':') { - ns.u += 2; - lcname_len -= (ns.u - lcname.u); - if (zend_u_hash_find(EG(function_table), ZEND_STR_TYPE, ns, lcname_len+1, (void **) &EX(fbc))==SUCCESS) { - efree(lcname.v); - EX(object) = NULL; - ZEND_VM_NEXT_OPCODE(); - } - } else if (!UG(unicode) && (ns.s = memchr(lcname.s, ':', lcname_len)) && ns.s[1] == ':') { - ns.s += 2; - lcname_len -= (ns.s - lcname.s); - if (zend_u_hash_find(EG(function_table), ZEND_STR_TYPE, ns, lcname_len+1, (void **) &EX(fbc))==SUCCESS) { - efree(lcname.v); - EX(object) = NULL; - ZEND_VM_NEXT_OPCODE(); - } + if ((opline->extended_value & ZEND_FETCH_CLASS_RT_NS_NAME) && + op_data->op2.op_type == IS_CONST) { + + if (zend_u_hash_find(EG(function_table), Z_TYPE(op_data->op2.u.constant), Z_UNIVAL(op_data->op2.u.constant), Z_UNILEN(op_data->op2.u.constant) + 1, (void **) &EX(fbc))==SUCCESS) { + EX(object) = NULL; + ZEND_VM_NEXT_OPCODE(); } + if (opline->extended_value & ZEND_FETCH_CLASS_RT_NS_CHECK) { - lcname_len -= Z_UNILEN(opline->op2.u.constant) + 2; + zstr ce_name; + unsigned ce_name_len = Z_UNILEN(op_data->op1.u.constant) - (Z_UNILEN(op_data->op2.u.constant) + 2); if (UG(unicode)) { - ns.u[lcname_len] = 0; + ce_name.u = eustrndup(Z_USTRVAL(op_data->op1.u.constant), ce_name_len); } else { - ns.s[lcname_len] = 0; + ce_name.s = estrndup(Z_STRVAL(op_data->op1.u.constant), ce_name_len); } - ce = zend_u_fetch_class(Z_TYPE(opline->op1.u.constant), ns, lcname_len, opline->extended_value & ~ZEND_FETCH_CLASS_RT_NS_CHECK TSRMLS_CC); + ce = zend_u_fetch_class(Z_TYPE(opline->op1.u.constant), ce_name, ce_name_len, opline->extended_value & ~ZEND_FETCH_CLASS_RT_NS_CHECK TSRMLS_CC); + efree(ce_name.v); if (!ce) { zend_error(E_ERROR, "Class '%R' not found", Z_TYPE(opline->op1.u.constant), Z_UNIVAL(opline->op1.u.constant)); } @@ -4375,8 +4207,6 @@ static int ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLE zend_error(E_ERROR, "Class '%R' not found", Z_TYPE(opline->op1.u.constant), Z_UNIVAL(opline->op1.u.constant)); } } - - efree(lcname.v); } else { ce = EX_T(opline->op1.u.var).class_entry; } @@ -10208,33 +10038,11 @@ static int ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDL if (IS_VAR == IS_CONST && IS_CONST == IS_CONST) { /* try a function in namespace */ - zstr fname, lcname; - unsigned int len, lcname_len; - - len = Z_UNILEN(opline->op1.u.constant) + 2 + Z_UNILEN(opline->op2.u.constant); - if (UG(unicode)) { - fname.u = eumalloc(len + 1); - memcpy(fname.u, Z_USTRVAL(opline->op1.u.constant), UBYTES(Z_USTRLEN(opline->op1.u.constant))); - fname.u[Z_USTRLEN(opline->op1.u.constant)] = ':'; - fname.u[Z_USTRLEN(opline->op1.u.constant)+1] = ':'; - memcpy(fname.u+Z_USTRLEN(opline->op1.u.constant)+2, - Z_USTRVAL(opline->op2.u.constant), - UBYTES(Z_USTRLEN(opline->op2.u.constant)+1)); - lcname = zend_u_str_case_fold(IS_UNICODE, fname, len, 1, &lcname_len); - } else { - fname.s = emalloc(len + 1); - memcpy(fname.s, Z_STRVAL(opline->op1.u.constant), Z_STRLEN(opline->op1.u.constant)); - fname.s[Z_STRLEN(opline->op1.u.constant)] = ':'; - fname.s[Z_STRLEN(opline->op1.u.constant)+1] = ':'; - memcpy(fname.s+Z_STRLEN(opline->op1.u.constant)+2, - Z_STRVAL(opline->op2.u.constant), - Z_STRLEN(opline->op2.u.constant)+1); - lcname = zend_u_str_case_fold(IS_STRING, fname, len, 1, &lcname_len); - } - efree(fname.v); - - if (zend_u_hash_find(EG(function_table), ZEND_STR_TYPE, lcname, lcname_len+1, (void **) &EX(fbc))==SUCCESS) { - efree(lcname.v); + zend_op *op_data = opline+1; + + ZEND_VM_INC_OPCODE(); + + if (zend_u_hash_quick_find(EG(function_table), Z_TYPE(op_data->op1.u.constant), Z_UNIVAL(op_data->op1.u.constant), Z_UNILEN(op_data->op1.u.constant)+1, op_data->extended_value, (void **) &EX(fbc))==SUCCESS) { EX(object) = NULL; ZEND_VM_NEXT_OPCODE(); } @@ -10243,34 +10051,24 @@ static int ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDL ce = zend_u_fetch_class(Z_TYPE(opline->op1.u.constant), Z_UNIVAL(opline->op1.u.constant), Z_UNILEN(opline->op1.u.constant), (opline->extended_value & ZEND_FETCH_CLASS_RT_NS_NAME) ? (opline->extended_value & ~ZEND_FETCH_CLASS_RT_NS_CHECK) : opline->extended_value TSRMLS_CC); if (!ce) { - if (opline->extended_value & ZEND_FETCH_CLASS_RT_NS_NAME) { - zstr ns; - - if (UG(unicode) && (ns.u = u_memchr(lcname.u, ':', lcname_len)) && ns.u[1] == ':') { - ns.u += 2; - lcname_len -= (ns.u - lcname.u); - if (zend_u_hash_find(EG(function_table), ZEND_STR_TYPE, ns, lcname_len+1, (void **) &EX(fbc))==SUCCESS) { - efree(lcname.v); - EX(object) = NULL; - ZEND_VM_NEXT_OPCODE(); - } - } else if (!UG(unicode) && (ns.s = memchr(lcname.s, ':', lcname_len)) && ns.s[1] == ':') { - ns.s += 2; - lcname_len -= (ns.s - lcname.s); - if (zend_u_hash_find(EG(function_table), ZEND_STR_TYPE, ns, lcname_len+1, (void **) &EX(fbc))==SUCCESS) { - efree(lcname.v); - EX(object) = NULL; - ZEND_VM_NEXT_OPCODE(); - } + if ((opline->extended_value & ZEND_FETCH_CLASS_RT_NS_NAME) && + op_data->op2.op_type == IS_CONST) { + + if (zend_u_hash_find(EG(function_table), Z_TYPE(op_data->op2.u.constant), Z_UNIVAL(op_data->op2.u.constant), Z_UNILEN(op_data->op2.u.constant) + 1, (void **) &EX(fbc))==SUCCESS) { + EX(object) = NULL; + ZEND_VM_NEXT_OPCODE(); } + if (opline->extended_value & ZEND_FETCH_CLASS_RT_NS_CHECK) { - lcname_len -= Z_UNILEN(opline->op2.u.constant) + 2; + zstr ce_name; + unsigned ce_name_len = Z_UNILEN(op_data->op1.u.constant) - (Z_UNILEN(op_data->op2.u.constant) + 2); if (UG(unicode)) { - ns.u[lcname_len] = 0; + ce_name.u = eustrndup(Z_USTRVAL(op_data->op1.u.constant), ce_name_len); } else { - ns.s[lcname_len] = 0; + ce_name.s = estrndup(Z_STRVAL(op_data->op1.u.constant), ce_name_len); } - ce = zend_u_fetch_class(Z_TYPE(opline->op1.u.constant), ns, lcname_len, opline->extended_value & ~ZEND_FETCH_CLASS_RT_NS_CHECK TSRMLS_CC); + ce = zend_u_fetch_class(Z_TYPE(opline->op1.u.constant), ce_name, ce_name_len, opline->extended_value & ~ZEND_FETCH_CLASS_RT_NS_CHECK TSRMLS_CC); + efree(ce_name.v); if (!ce) { zend_error(E_ERROR, "Class '%R' not found", Z_TYPE(opline->op1.u.constant), Z_UNIVAL(opline->op1.u.constant)); } @@ -10281,8 +10079,6 @@ static int ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDL zend_error(E_ERROR, "Class '%R' not found", Z_TYPE(opline->op1.u.constant), Z_UNIVAL(opline->op1.u.constant)); } } - - efree(lcname.v); } else { ce = EX_T(opline->op1.u.var).class_entry; } @@ -11945,33 +11741,11 @@ static int ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER if (IS_VAR == IS_CONST && IS_TMP_VAR == IS_CONST) { /* try a function in namespace */ - zstr fname, lcname; - unsigned int len, lcname_len; - - len = Z_UNILEN(opline->op1.u.constant) + 2 + Z_UNILEN(opline->op2.u.constant); - if (UG(unicode)) { - fname.u = eumalloc(len + 1); - memcpy(fname.u, Z_USTRVAL(opline->op1.u.constant), UBYTES(Z_USTRLEN(opline->op1.u.constant))); - fname.u[Z_USTRLEN(opline->op1.u.constant)] = ':'; - fname.u[Z_USTRLEN(opline->op1.u.constant)+1] = ':'; - memcpy(fname.u+Z_USTRLEN(opline->op1.u.constant)+2, - Z_USTRVAL(opline->op2.u.constant), - UBYTES(Z_USTRLEN(opline->op2.u.constant)+1)); - lcname = zend_u_str_case_fold(IS_UNICODE, fname, len, 1, &lcname_len); - } else { - fname.s = emalloc(len + 1); - memcpy(fname.s, Z_STRVAL(opline->op1.u.constant), Z_STRLEN(opline->op1.u.constant)); - fname.s[Z_STRLEN(opline->op1.u.constant)] = ':'; - fname.s[Z_STRLEN(opline->op1.u.constant)+1] = ':'; - memcpy(fname.s+Z_STRLEN(opline->op1.u.constant)+2, - Z_STRVAL(opline->op2.u.constant), - Z_STRLEN(opline->op2.u.constant)+1); - lcname = zend_u_str_case_fold(IS_STRING, fname, len, 1, &lcname_len); - } - efree(fname.v); - - if (zend_u_hash_find(EG(function_table), ZEND_STR_TYPE, lcname, lcname_len+1, (void **) &EX(fbc))==SUCCESS) { - efree(lcname.v); + zend_op *op_data = opline+1; + + ZEND_VM_INC_OPCODE(); + + if (zend_u_hash_quick_find(EG(function_table), Z_TYPE(op_data->op1.u.constant), Z_UNIVAL(op_data->op1.u.constant), Z_UNILEN(op_data->op1.u.constant)+1, op_data->extended_value, (void **) &EX(fbc))==SUCCESS) { EX(object) = NULL; ZEND_VM_NEXT_OPCODE(); } @@ -11980,34 +11754,24 @@ static int ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER ce = zend_u_fetch_class(Z_TYPE(opline->op1.u.constant), Z_UNIVAL(opline->op1.u.constant), Z_UNILEN(opline->op1.u.constant), (opline->extended_value & ZEND_FETCH_CLASS_RT_NS_NAME) ? (opline->extended_value & ~ZEND_FETCH_CLASS_RT_NS_CHECK) : opline->extended_value TSRMLS_CC); if (!ce) { - if (opline->extended_value & ZEND_FETCH_CLASS_RT_NS_NAME) { - zstr ns; - - if (UG(unicode) && (ns.u = u_memchr(lcname.u, ':', lcname_len)) && ns.u[1] == ':') { - ns.u += 2; - lcname_len -= (ns.u - lcname.u); - if (zend_u_hash_find(EG(function_table), ZEND_STR_TYPE, ns, lcname_len+1, (void **) &EX(fbc))==SUCCESS) { - efree(lcname.v); - EX(object) = NULL; - ZEND_VM_NEXT_OPCODE(); - } - } else if (!UG(unicode) && (ns.s = memchr(lcname.s, ':', lcname_len)) && ns.s[1] == ':') { - ns.s += 2; - lcname_len -= (ns.s - lcname.s); - if (zend_u_hash_find(EG(function_table), ZEND_STR_TYPE, ns, lcname_len+1, (void **) &EX(fbc))==SUCCESS) { - efree(lcname.v); - EX(object) = NULL; - ZEND_VM_NEXT_OPCODE(); - } + if ((opline->extended_value & ZEND_FETCH_CLASS_RT_NS_NAME) && + op_data->op2.op_type == IS_CONST) { + + if (zend_u_hash_find(EG(function_table), Z_TYPE(op_data->op2.u.constant), Z_UNIVAL(op_data->op2.u.constant), Z_UNILEN(op_data->op2.u.constant) + 1, (void **) &EX(fbc))==SUCCESS) { + EX(object) = NULL; + ZEND_VM_NEXT_OPCODE(); } + if (opline->extended_value & ZEND_FETCH_CLASS_RT_NS_CHECK) { - lcname_len -= Z_UNILEN(opline->op2.u.constant) + 2; + zstr ce_name; + unsigned ce_name_len = Z_UNILEN(op_data->op1.u.constant) - (Z_UNILEN(op_data->op2.u.constant) + 2); if (UG(unicode)) { - ns.u[lcname_len] = 0; + ce_name.u = eustrndup(Z_USTRVAL(op_data->op1.u.constant), ce_name_len); } else { - ns.s[lcname_len] = 0; + ce_name.s = estrndup(Z_STRVAL(op_data->op1.u.constant), ce_name_len); } - ce = zend_u_fetch_class(Z_TYPE(opline->op1.u.constant), ns, lcname_len, opline->extended_value & ~ZEND_FETCH_CLASS_RT_NS_CHECK TSRMLS_CC); + ce = zend_u_fetch_class(Z_TYPE(opline->op1.u.constant), ce_name, ce_name_len, opline->extended_value & ~ZEND_FETCH_CLASS_RT_NS_CHECK TSRMLS_CC); + efree(ce_name.v); if (!ce) { zend_error(E_ERROR, "Class '%R' not found", Z_TYPE(opline->op1.u.constant), Z_UNIVAL(opline->op1.u.constant)); } @@ -12018,8 +11782,6 @@ static int ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER zend_error(E_ERROR, "Class '%R' not found", Z_TYPE(opline->op1.u.constant), Z_UNIVAL(opline->op1.u.constant)); } } - - efree(lcname.v); } else { ce = EX_T(opline->op1.u.var).class_entry; } @@ -13674,33 +13436,11 @@ static int ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER if (IS_VAR == IS_CONST && IS_VAR == IS_CONST) { /* try a function in namespace */ - zstr fname, lcname; - unsigned int len, lcname_len; - - len = Z_UNILEN(opline->op1.u.constant) + 2 + Z_UNILEN(opline->op2.u.constant); - if (UG(unicode)) { - fname.u = eumalloc(len + 1); - memcpy(fname.u, Z_USTRVAL(opline->op1.u.constant), UBYTES(Z_USTRLEN(opline->op1.u.constant))); - fname.u[Z_USTRLEN(opline->op1.u.constant)] = ':'; - fname.u[Z_USTRLEN(opline->op1.u.constant)+1] = ':'; - memcpy(fname.u+Z_USTRLEN(opline->op1.u.constant)+2, - Z_USTRVAL(opline->op2.u.constant), - UBYTES(Z_USTRLEN(opline->op2.u.constant)+1)); - lcname = zend_u_str_case_fold(IS_UNICODE, fname, len, 1, &lcname_len); - } else { - fname.s = emalloc(len + 1); - memcpy(fname.s, Z_STRVAL(opline->op1.u.constant), Z_STRLEN(opline->op1.u.constant)); - fname.s[Z_STRLEN(opline->op1.u.constant)] = ':'; - fname.s[Z_STRLEN(opline->op1.u.constant)+1] = ':'; - memcpy(fname.s+Z_STRLEN(opline->op1.u.constant)+2, - Z_STRVAL(opline->op2.u.constant), - Z_STRLEN(opline->op2.u.constant)+1); - lcname = zend_u_str_case_fold(IS_STRING, fname, len, 1, &lcname_len); - } - efree(fname.v); - - if (zend_u_hash_find(EG(function_table), ZEND_STR_TYPE, lcname, lcname_len+1, (void **) &EX(fbc))==SUCCESS) { - efree(lcname.v); + zend_op *op_data = opline+1; + + ZEND_VM_INC_OPCODE(); + + if (zend_u_hash_quick_find(EG(function_table), Z_TYPE(op_data->op1.u.constant), Z_UNIVAL(op_data->op1.u.constant), Z_UNILEN(op_data->op1.u.constant)+1, op_data->extended_value, (void **) &EX(fbc))==SUCCESS) { EX(object) = NULL; ZEND_VM_NEXT_OPCODE(); } @@ -13709,34 +13449,24 @@ static int ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER ce = zend_u_fetch_class(Z_TYPE(opline->op1.u.constant), Z_UNIVAL(opline->op1.u.constant), Z_UNILEN(opline->op1.u.constant), (opline->extended_value & ZEND_FETCH_CLASS_RT_NS_NAME) ? (opline->extended_value & ~ZEND_FETCH_CLASS_RT_NS_CHECK) : opline->extended_value TSRMLS_CC); if (!ce) { - if (opline->extended_value & ZEND_FETCH_CLASS_RT_NS_NAME) { - zstr ns; - - if (UG(unicode) && (ns.u = u_memchr(lcname.u, ':', lcname_len)) && ns.u[1] == ':') { - ns.u += 2; - lcname_len -= (ns.u - lcname.u); - if (zend_u_hash_find(EG(function_table), ZEND_STR_TYPE, ns, lcname_len+1, (void **) &EX(fbc))==SUCCESS) { - efree(lcname.v); - EX(object) = NULL; - ZEND_VM_NEXT_OPCODE(); - } - } else if (!UG(unicode) && (ns.s = memchr(lcname.s, ':', lcname_len)) && ns.s[1] == ':') { - ns.s += 2; - lcname_len -= (ns.s - lcname.s); - if (zend_u_hash_find(EG(function_table), ZEND_STR_TYPE, ns, lcname_len+1, (void **) &EX(fbc))==SUCCESS) { - efree(lcname.v); - EX(object) = NULL; - ZEND_VM_NEXT_OPCODE(); - } + if ((opline->extended_value & ZEND_FETCH_CLASS_RT_NS_NAME) && + op_data->op2.op_type == IS_CONST) { + + if (zend_u_hash_find(EG(function_table), Z_TYPE(op_data->op2.u.constant), Z_UNIVAL(op_data->op2.u.constant), Z_UNILEN(op_data->op2.u.constant) + 1, (void **) &EX(fbc))==SUCCESS) { + EX(object) = NULL; + ZEND_VM_NEXT_OPCODE(); } + if (opline->extended_value & ZEND_FETCH_CLASS_RT_NS_CHECK) { - lcname_len -= Z_UNILEN(opline->op2.u.constant) + 2; + zstr ce_name; + unsigned ce_name_len = Z_UNILEN(op_data->op1.u.constant) - (Z_UNILEN(op_data->op2.u.constant) + 2); if (UG(unicode)) { - ns.u[lcname_len] = 0; + ce_name.u = eustrndup(Z_USTRVAL(op_data->op1.u.constant), ce_name_len); } else { - ns.s[lcname_len] = 0; + ce_name.s = estrndup(Z_STRVAL(op_data->op1.u.constant), ce_name_len); } - ce = zend_u_fetch_class(Z_TYPE(opline->op1.u.constant), ns, lcname_len, opline->extended_value & ~ZEND_FETCH_CLASS_RT_NS_CHECK TSRMLS_CC); + ce = zend_u_fetch_class(Z_TYPE(opline->op1.u.constant), ce_name, ce_name_len, opline->extended_value & ~ZEND_FETCH_CLASS_RT_NS_CHECK TSRMLS_CC); + efree(ce_name.v); if (!ce) { zend_error(E_ERROR, "Class '%R' not found", Z_TYPE(opline->op1.u.constant), Z_UNIVAL(opline->op1.u.constant)); } @@ -13747,8 +13477,6 @@ static int ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER zend_error(E_ERROR, "Class '%R' not found", Z_TYPE(opline->op1.u.constant), Z_UNIVAL(opline->op1.u.constant)); } } - - efree(lcname.v); } else { ce = EX_T(opline->op1.u.var).class_entry; } @@ -14601,33 +14329,11 @@ static int ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HAND if (IS_VAR == IS_CONST && IS_UNUSED == IS_CONST) { /* try a function in namespace */ - zstr fname, lcname; - unsigned int len, lcname_len; - - len = Z_UNILEN(opline->op1.u.constant) + 2 + Z_UNILEN(opline->op2.u.constant); - if (UG(unicode)) { - fname.u = eumalloc(len + 1); - memcpy(fname.u, Z_USTRVAL(opline->op1.u.constant), UBYTES(Z_USTRLEN(opline->op1.u.constant))); - fname.u[Z_USTRLEN(opline->op1.u.constant)] = ':'; - fname.u[Z_USTRLEN(opline->op1.u.constant)+1] = ':'; - memcpy(fname.u+Z_USTRLEN(opline->op1.u.constant)+2, - Z_USTRVAL(opline->op2.u.constant), - UBYTES(Z_USTRLEN(opline->op2.u.constant)+1)); - lcname = zend_u_str_case_fold(IS_UNICODE, fname, len, 1, &lcname_len); - } else { - fname.s = emalloc(len + 1); - memcpy(fname.s, Z_STRVAL(opline->op1.u.constant), Z_STRLEN(opline->op1.u.constant)); - fname.s[Z_STRLEN(opline->op1.u.constant)] = ':'; - fname.s[Z_STRLEN(opline->op1.u.constant)+1] = ':'; - memcpy(fname.s+Z_STRLEN(opline->op1.u.constant)+2, - Z_STRVAL(opline->op2.u.constant), - Z_STRLEN(opline->op2.u.constant)+1); - lcname = zend_u_str_case_fold(IS_STRING, fname, len, 1, &lcname_len); - } - efree(fname.v); - - if (zend_u_hash_find(EG(function_table), ZEND_STR_TYPE, lcname, lcname_len+1, (void **) &EX(fbc))==SUCCESS) { - efree(lcname.v); + zend_op *op_data = opline+1; + + ZEND_VM_INC_OPCODE(); + + if (zend_u_hash_quick_find(EG(function_table), Z_TYPE(op_data->op1.u.constant), Z_UNIVAL(op_data->op1.u.constant), Z_UNILEN(op_data->op1.u.constant)+1, op_data->extended_value, (void **) &EX(fbc))==SUCCESS) { EX(object) = NULL; ZEND_VM_NEXT_OPCODE(); } @@ -14636,34 +14342,24 @@ static int ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HAND ce = zend_u_fetch_class(Z_TYPE(opline->op1.u.constant), Z_UNIVAL(opline->op1.u.constant), Z_UNILEN(opline->op1.u.constant), (opline->extended_value & ZEND_FETCH_CLASS_RT_NS_NAME) ? (opline->extended_value & ~ZEND_FETCH_CLASS_RT_NS_CHECK) : opline->extended_value TSRMLS_CC); if (!ce) { - if (opline->extended_value & ZEND_FETCH_CLASS_RT_NS_NAME) { - zstr ns; - - if (UG(unicode) && (ns.u = u_memchr(lcname.u, ':', lcname_len)) && ns.u[1] == ':') { - ns.u += 2; - lcname_len -= (ns.u - lcname.u); - if (zend_u_hash_find(EG(function_table), ZEND_STR_TYPE, ns, lcname_len+1, (void **) &EX(fbc))==SUCCESS) { - efree(lcname.v); - EX(object) = NULL; - ZEND_VM_NEXT_OPCODE(); - } - } else if (!UG(unicode) && (ns.s = memchr(lcname.s, ':', lcname_len)) && ns.s[1] == ':') { - ns.s += 2; - lcname_len -= (ns.s - lcname.s); - if (zend_u_hash_find(EG(function_table), ZEND_STR_TYPE, ns, lcname_len+1, (void **) &EX(fbc))==SUCCESS) { - efree(lcname.v); - EX(object) = NULL; - ZEND_VM_NEXT_OPCODE(); - } + if ((opline->extended_value & ZEND_FETCH_CLASS_RT_NS_NAME) && + op_data->op2.op_type == IS_CONST) { + + if (zend_u_hash_find(EG(function_table), Z_TYPE(op_data->op2.u.constant), Z_UNIVAL(op_data->op2.u.constant), Z_UNILEN(op_data->op2.u.constant) + 1, (void **) &EX(fbc))==SUCCESS) { + EX(object) = NULL; + ZEND_VM_NEXT_OPCODE(); } + if (opline->extended_value & ZEND_FETCH_CLASS_RT_NS_CHECK) { - lcname_len -= Z_UNILEN(opline->op2.u.constant) + 2; + zstr ce_name; + unsigned ce_name_len = Z_UNILEN(op_data->op1.u.constant) - (Z_UNILEN(op_data->op2.u.constant) + 2); if (UG(unicode)) { - ns.u[lcname_len] = 0; + ce_name.u = eustrndup(Z_USTRVAL(op_data->op1.u.constant), ce_name_len); } else { - ns.s[lcname_len] = 0; + ce_name.s = estrndup(Z_STRVAL(op_data->op1.u.constant), ce_name_len); } - ce = zend_u_fetch_class(Z_TYPE(opline->op1.u.constant), ns, lcname_len, opline->extended_value & ~ZEND_FETCH_CLASS_RT_NS_CHECK TSRMLS_CC); + ce = zend_u_fetch_class(Z_TYPE(opline->op1.u.constant), ce_name, ce_name_len, opline->extended_value & ~ZEND_FETCH_CLASS_RT_NS_CHECK TSRMLS_CC); + efree(ce_name.v); if (!ce) { zend_error(E_ERROR, "Class '%R' not found", Z_TYPE(opline->op1.u.constant), Z_UNIVAL(opline->op1.u.constant)); } @@ -14674,8 +14370,6 @@ static int ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HAND zend_error(E_ERROR, "Class '%R' not found", Z_TYPE(opline->op1.u.constant), Z_UNIVAL(opline->op1.u.constant)); } } - - efree(lcname.v); } else { ce = EX_T(opline->op1.u.var).class_entry; } @@ -15980,33 +15674,11 @@ static int ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ if (IS_VAR == IS_CONST && IS_CV == IS_CONST) { /* try a function in namespace */ - zstr fname, lcname; - unsigned int len, lcname_len; - - len = Z_UNILEN(opline->op1.u.constant) + 2 + Z_UNILEN(opline->op2.u.constant); - if (UG(unicode)) { - fname.u = eumalloc(len + 1); - memcpy(fname.u, Z_USTRVAL(opline->op1.u.constant), UBYTES(Z_USTRLEN(opline->op1.u.constant))); - fname.u[Z_USTRLEN(opline->op1.u.constant)] = ':'; - fname.u[Z_USTRLEN(opline->op1.u.constant)+1] = ':'; - memcpy(fname.u+Z_USTRLEN(opline->op1.u.constant)+2, - Z_USTRVAL(opline->op2.u.constant), - UBYTES(Z_USTRLEN(opline->op2.u.constant)+1)); - lcname = zend_u_str_case_fold(IS_UNICODE, fname, len, 1, &lcname_len); - } else { - fname.s = emalloc(len + 1); - memcpy(fname.s, Z_STRVAL(opline->op1.u.constant), Z_STRLEN(opline->op1.u.constant)); - fname.s[Z_STRLEN(opline->op1.u.constant)] = ':'; - fname.s[Z_STRLEN(opline->op1.u.constant)+1] = ':'; - memcpy(fname.s+Z_STRLEN(opline->op1.u.constant)+2, - Z_STRVAL(opline->op2.u.constant), - Z_STRLEN(opline->op2.u.constant)+1); - lcname = zend_u_str_case_fold(IS_STRING, fname, len, 1, &lcname_len); - } - efree(fname.v); - - if (zend_u_hash_find(EG(function_table), ZEND_STR_TYPE, lcname, lcname_len+1, (void **) &EX(fbc))==SUCCESS) { - efree(lcname.v); + zend_op *op_data = opline+1; + + ZEND_VM_INC_OPCODE(); + + if (zend_u_hash_quick_find(EG(function_table), Z_TYPE(op_data->op1.u.constant), Z_UNIVAL(op_data->op1.u.constant), Z_UNILEN(op_data->op1.u.constant)+1, op_data->extended_value, (void **) &EX(fbc))==SUCCESS) { EX(object) = NULL; ZEND_VM_NEXT_OPCODE(); } @@ -16015,34 +15687,24 @@ static int ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ ce = zend_u_fetch_class(Z_TYPE(opline->op1.u.constant), Z_UNIVAL(opline->op1.u.constant), Z_UNILEN(opline->op1.u.constant), (opline->extended_value & ZEND_FETCH_CLASS_RT_NS_NAME) ? (opline->extended_value & ~ZEND_FETCH_CLASS_RT_NS_CHECK) : opline->extended_value TSRMLS_CC); if (!ce) { - if (opline->extended_value & ZEND_FETCH_CLASS_RT_NS_NAME) { - zstr ns; - - if (UG(unicode) && (ns.u = u_memchr(lcname.u, ':', lcname_len)) && ns.u[1] == ':') { - ns.u += 2; - lcname_len -= (ns.u - lcname.u); - if (zend_u_hash_find(EG(function_table), ZEND_STR_TYPE, ns, lcname_len+1, (void **) &EX(fbc))==SUCCESS) { - efree(lcname.v); - EX(object) = NULL; - ZEND_VM_NEXT_OPCODE(); - } - } else if (!UG(unicode) && (ns.s = memchr(lcname.s, ':', lcname_len)) && ns.s[1] == ':') { - ns.s += 2; - lcname_len -= (ns.s - lcname.s); - if (zend_u_hash_find(EG(function_table), ZEND_STR_TYPE, ns, lcname_len+1, (void **) &EX(fbc))==SUCCESS) { - efree(lcname.v); - EX(object) = NULL; - ZEND_VM_NEXT_OPCODE(); - } + if ((opline->extended_value & ZEND_FETCH_CLASS_RT_NS_NAME) && + op_data->op2.op_type == IS_CONST) { + + if (zend_u_hash_find(EG(function_table), Z_TYPE(op_data->op2.u.constant), Z_UNIVAL(op_data->op2.u.constant), Z_UNILEN(op_data->op2.u.constant) + 1, (void **) &EX(fbc))==SUCCESS) { + EX(object) = NULL; + ZEND_VM_NEXT_OPCODE(); } + if (opline->extended_value & ZEND_FETCH_CLASS_RT_NS_CHECK) { - lcname_len -= Z_UNILEN(opline->op2.u.constant) + 2; + zstr ce_name; + unsigned ce_name_len = Z_UNILEN(op_data->op1.u.constant) - (Z_UNILEN(op_data->op2.u.constant) + 2); if (UG(unicode)) { - ns.u[lcname_len] = 0; + ce_name.u = eustrndup(Z_USTRVAL(op_data->op1.u.constant), ce_name_len); } else { - ns.s[lcname_len] = 0; + ce_name.s = estrndup(Z_STRVAL(op_data->op1.u.constant), ce_name_len); } - ce = zend_u_fetch_class(Z_TYPE(opline->op1.u.constant), ns, lcname_len, opline->extended_value & ~ZEND_FETCH_CLASS_RT_NS_CHECK TSRMLS_CC); + ce = zend_u_fetch_class(Z_TYPE(opline->op1.u.constant), ce_name, ce_name_len, opline->extended_value & ~ZEND_FETCH_CLASS_RT_NS_CHECK TSRMLS_CC); + efree(ce_name.v); if (!ce) { zend_error(E_ERROR, "Class '%R' not found", Z_TYPE(opline->op1.u.constant), Z_UNIVAL(opline->op1.u.constant)); } @@ -16053,8 +15715,6 @@ static int ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ zend_error(E_ERROR, "Class '%R' not found", Z_TYPE(opline->op1.u.constant), Z_UNIVAL(opline->op1.u.constant)); } } - - efree(lcname.v); } else { ce = EX_T(opline->op1.u.var).class_entry; } |