summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@php.net>2007-08-17 12:05:19 +0000
committerDmitry Stogov <dmitry@php.net>2007-08-17 12:05:19 +0000
commit6e3a76898ec32f1c1a29e550d1011806ef637f61 (patch)
treeece72b132987bd96666ed1d1ad9e0c24aef79bd4
parent8c43fddada8e8d43fb44550d734a329291d37bf9 (diff)
downloadphp-git-6e3a76898ec32f1c1a29e550d1011806ef637f61.tar.gz
Namespaces: improved run-time speed
-rw-r--r--Zend/zend_compile.c75
-rw-r--r--Zend/zend_vm_def.h68
-rw-r--r--Zend/zend_vm_execute.h700
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;
}