summaryrefslogtreecommitdiff
path: root/Zend
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@php.net>2007-11-22 09:02:55 +0000
committerDmitry Stogov <dmitry@php.net>2007-11-22 09:02:55 +0000
commitea0a1c09e9b35401358306a768ad81dc2adbe0ab (patch)
tree39d8aba0f1c209c68fdc1a42ee33ae89c3dafdd4 /Zend
parent5d37d09c382e9cf5fc4a48d7fa50f384526a6549 (diff)
downloadphp-git-ea0a1c09e9b35401358306a768ad81dc2adbe0ab.tar.gz
Speed-up of ZEND_DO_FCALL and ZEND_INIT_FCALL_BY_NAME by lowercasing and calculating hash values at compile time.
Diffstat (limited to 'Zend')
-rw-r--r--Zend/zend_compile.c47
-rw-r--r--Zend/zend_vm_def.h65
-rw-r--r--Zend/zend_vm_execute.h216
-rw-r--r--Zend/zend_vm_opcodes.h1
4 files changed, 164 insertions, 165 deletions
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c
index 761e56b3cc..84e1181e8c 100644
--- a/Zend/zend_compile.c
+++ b/Zend/zend_compile.c
@@ -1446,8 +1446,16 @@ void zend_do_begin_method_call(znode *left_bracket TSRMLS_DC)
zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
opline->opcode = ZEND_INIT_FCALL_BY_NAME;
opline->op2 = *left_bracket;
- opline->extended_value = 0;
- SET_UNUSED(opline->op1);
+ if (opline->op2.op_type == IS_CONST) {
+ opline->op1.op_type = IS_CONST;
+ Z_TYPE(opline->op1.u.constant) = IS_STRING;
+ Z_STRVAL(opline->op1.u.constant) = zend_str_tolower_dup(Z_STRVAL(opline->op2.u.constant), Z_STRLEN(opline->op2.u.constant));
+ Z_STRLEN(opline->op1.u.constant) = Z_STRLEN(opline->op2.u.constant);
+ opline->extended_value = zend_hash_func(Z_STRVAL(opline->op1.u.constant), Z_STRLEN(opline->op1.u.constant) + 1);
+ } else {
+ opline->extended_value = 0;
+ SET_UNUSED(opline->op1);
+ }
}
zend_stack_push(&CG(function_call_stack), (void *) &ptr, sizeof(zend_function *));
@@ -1474,19 +1482,42 @@ void zend_do_begin_dynamic_function_call(znode *function_name, int prefix_len TS
zend_op *opline;
opline = get_next_op(CG(active_op_array) TSRMLS_CC);
- opline->opcode = ZEND_INIT_FCALL_BY_NAME;
- opline->op2 = *function_name;
- opline->extended_value = 0;
if (prefix_len) {
/* In run-time PHP will check for function with full name and
internal function with short name */
+ opline->opcode = ZEND_INIT_NS_FCALL_BY_NAME;
+ opline->op2 = *function_name;
+ opline->extended_value = 0;
opline->op1.op_type = IS_CONST;
- ZVAL_LONG(&opline->op1.u.constant, prefix_len);
+ Z_TYPE(opline->op1.u.constant) = IS_STRING;
+ Z_STRVAL(opline->op1.u.constant) = zend_str_tolower_dup(Z_STRVAL(opline->op2.u.constant), Z_STRLEN(opline->op2.u.constant));
+ Z_STRLEN(opline->op1.u.constant) = Z_STRLEN(opline->op2.u.constant);
+ opline->extended_value = zend_hash_func(Z_STRVAL(opline->op1.u.constant), Z_STRLEN(opline->op1.u.constant) + 1);
+ opline = get_next_op(CG(active_op_array) TSRMLS_CC);
+ opline->opcode = ZEND_OP_DATA;
+ opline->op1.op_type = IS_CONST;
+ Z_TYPE(opline->op1.u.constant) = IS_STRING;
+ Z_STRLEN(opline->op1.u.constant) = Z_STRLEN(function_name->u.constant) - prefix_len;
+ Z_STRVAL(opline->op1.u.constant) = zend_str_tolower_dup(Z_STRVAL(function_name->u.constant) + prefix_len, Z_STRLEN(opline->op1.u.constant));
+ opline->extended_value = zend_hash_func(Z_STRVAL(opline->op1.u.constant), Z_STRLEN(opline->op1.u.constant) + 1);
} else {
- SET_UNUSED(opline->op1);
+ opline->opcode = ZEND_INIT_FCALL_BY_NAME;
+ opline->op2 = *function_name;
+ if (opline->op2.op_type == IS_CONST) {
+ opline->op1.op_type = IS_CONST;
+ Z_TYPE(opline->op1.u.constant) = IS_STRING;
+ Z_STRVAL(opline->op1.u.constant) = zend_str_tolower_dup(Z_STRVAL(opline->op2.u.constant), Z_STRLEN(opline->op2.u.constant));
+ Z_STRLEN(opline->op1.u.constant) = Z_STRLEN(opline->op2.u.constant);
+ opline->extended_value = zend_hash_func(Z_STRVAL(opline->op1.u.constant), Z_STRLEN(opline->op1.u.constant) + 1);
+ } else {
+ opline->extended_value = 0;
+ SET_UNUSED(opline->op1);
+ }
}
+
+
zend_stack_push(&CG(function_call_stack), (void *) &ptr, sizeof(zend_function *));
zend_do_extended_fcall_begin(TSRMLS_C);
}
@@ -1731,6 +1762,7 @@ void zend_do_end_function_call(znode *function_name, znode *result, znode *argum
if (!is_method && !is_dynamic_fcall && function_name->op_type==IS_CONST) {
opline->opcode = ZEND_DO_FCALL;
opline->op1 = *function_name;
+ ZVAL_LONG(&opline->op2.u.constant, zend_hash_func(Z_STRVAL(function_name->u.constant), Z_STRLEN(function_name->u.constant) + 1));
} else {
opline->opcode = ZEND_DO_FCALL_BY_NAME;
SET_UNUSED(opline->op1);
@@ -3654,6 +3686,7 @@ void zend_do_shell_exec(znode *result, znode *cmd TSRMLS_DC)
opline->op1.op_type = IS_CONST;
opline->extended_value = 1;
SET_UNUSED(opline->op2);
+ ZVAL_LONG(&opline->op2.u.constant, zend_hash_func("shell_exec", sizeof("shell_exec")));
*result = opline->result;
}
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
index 8c33e7d24b..e94676461d 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -1876,60 +1876,65 @@ ZEND_VM_HANDLER(59, ZEND_INIT_FCALL_BY_NAME, ANY, CONST|TMP|VAR|CV)
{
zend_op *opline = EX(opline);
zval *function_name;
- zend_function *function;
char *function_name_strval, *lcname;
int function_name_strlen;
zend_free_op free_op2;
+ int ret;
zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
if (OP2_TYPE == IS_CONST) {
- function_name_strval = opline->op2.u.constant.value.str.val;
- function_name_strlen = opline->op2.u.constant.value.str.len;
+ function_name_strval = Z_STRVAL(opline->op2.u.constant);
+ ret = zend_hash_quick_find(EG(function_table), Z_STRVAL(opline->op1.u.constant), Z_STRLEN(opline->op1.u.constant)+1, opline->extended_value, (void **) &EX(fbc));
} else {
function_name = GET_OP2_ZVAL_PTR(BP_VAR_R);
if (Z_TYPE_P(function_name) != IS_STRING) {
zend_error_noreturn(E_ERROR, "Function name must be a string");
}
- function_name_strval = function_name->value.str.val;
- function_name_strlen = function_name->value.str.len;
- }
-
- if (OP2_TYPE != IS_CONST &&
- function_name_strval[0] == ':' &&
- function_name_strval[1] == ':') {
-
- function_name_strlen -= 2;
- lcname = zend_str_tolower_dup(function_name_strval + 2, function_name_strlen);
- } else {
- lcname = zend_str_tolower_dup(function_name_strval, function_name_strlen);
- }
- if (zend_hash_find(EG(function_table), lcname, function_name_strlen+1, (void **) &function)==FAILURE) {
- efree(lcname);
+ function_name_strval = Z_STRVAL_P(function_name);
+ function_name_strlen = Z_STRLEN_P(function_name);
+ if (function_name_strval[0] == ':' &&
+ function_name_strval[1] == ':') {
- if (OP2_TYPE == IS_CONST && opline->op1.op_type == IS_CONST) {
- function_name_strlen -= Z_LVAL(opline->op1.u.constant);
- lcname = zend_str_tolower_dup(function_name_strval + Z_LVAL(opline->op1.u.constant), function_name_strlen);
- if (zend_hash_find(EG(function_table), lcname, function_name_strlen+1, (void **) &function)==FAILURE ||
- function->type != ZEND_INTERNAL_FUNCTION) {
- efree(lcname);
- zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval);
- }
+ function_name_strlen -= 2;
+ lcname = zend_str_tolower_dup(function_name_strval + 2, function_name_strlen);
} else {
- zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval);
+ lcname = zend_str_tolower_dup(function_name_strval, function_name_strlen);
}
+ ret = zend_hash_find(EG(function_table), lcname, function_name_strlen+1, (void **) &EX(fbc));
+ efree(lcname);
+ }
+
+ if (ret == FAILURE) {
+ zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval);
}
- efree(lcname);
if (OP2_TYPE != IS_CONST) {
FREE_OP2();
}
EX(object) = NULL;
+ ZEND_VM_NEXT_OPCODE();
+}
+
- EX(fbc) = function;
+ZEND_VM_HANDLER(69, ZEND_INIT_NS_FCALL_BY_NAME, ANY, CONST)
+{
+ zend_op *opline = EX(opline);
+ zend_op *op_data = opline + 1;
+ ZEND_VM_INC_OPCODE();
+ zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
+
+ if (zend_hash_quick_find(EG(function_table), Z_STRVAL(opline->op1.u.constant), Z_STRLEN(opline->op1.u.constant)+1, opline->extended_value, (void **) &EX(fbc))==FAILURE) {
+ if (zend_hash_quick_find(EG(function_table), Z_STRVAL(op_data->op1.u.constant), Z_STRLEN(op_data->op1.u.constant)+1, op_data->extended_value, (void **) &EX(fbc))==FAILURE ||
+ EX(fbc)->type != ZEND_INTERNAL_FUNCTION) {
+ zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL(opline->op2.u.constant));
+ }
+ }
+
+ EX(object) = NULL;
ZEND_VM_NEXT_OPCODE();
}
@@ -2134,7 +2139,7 @@ ZEND_VM_HANDLER(60, ZEND_DO_FCALL, CONST, ANY)
zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
- if (zend_hash_find(EG(function_table), fname->value.str.val, fname->value.str.len+1, (void **) &EX(function_state).function)==FAILURE) {
+ if (zend_hash_quick_find(EG(function_table), fname->value.str.val, fname->value.str.len+1, Z_LVAL(opline->op2.u.constant), (void **) &EX(function_state).function)==FAILURE) {
zend_error_noreturn(E_ERROR, "Call to undefined function %s()", fname->value.str.val);
}
EX(object) = NULL;
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index 45f879ea16..098aaa6f35 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -648,60 +648,65 @@ static int ZEND_INIT_FCALL_BY_NAME_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
zend_op *opline = EX(opline);
zval *function_name;
- zend_function *function;
char *function_name_strval, *lcname;
int function_name_strlen;
+ int ret;
zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
if (IS_CONST == IS_CONST) {
- function_name_strval = opline->op2.u.constant.value.str.val;
- function_name_strlen = opline->op2.u.constant.value.str.len;
+ function_name_strval = Z_STRVAL(opline->op2.u.constant);
+ ret = zend_hash_quick_find(EG(function_table), Z_STRVAL(opline->op1.u.constant), Z_STRLEN(opline->op1.u.constant)+1, opline->extended_value, (void **) &EX(fbc));
} else {
function_name = &opline->op2.u.constant;
if (Z_TYPE_P(function_name) != IS_STRING) {
zend_error_noreturn(E_ERROR, "Function name must be a string");
}
- function_name_strval = function_name->value.str.val;
- function_name_strlen = function_name->value.str.len;
- }
-
- if (IS_CONST != IS_CONST &&
- function_name_strval[0] == ':' &&
- function_name_strval[1] == ':') {
-
- function_name_strlen -= 2;
- lcname = zend_str_tolower_dup(function_name_strval + 2, function_name_strlen);
- } else {
- lcname = zend_str_tolower_dup(function_name_strval, function_name_strlen);
- }
- if (zend_hash_find(EG(function_table), lcname, function_name_strlen+1, (void **) &function)==FAILURE) {
- efree(lcname);
+ function_name_strval = Z_STRVAL_P(function_name);
+ function_name_strlen = Z_STRLEN_P(function_name);
+ if (function_name_strval[0] == ':' &&
+ function_name_strval[1] == ':') {
- if (IS_CONST == IS_CONST && opline->op1.op_type == IS_CONST) {
- function_name_strlen -= Z_LVAL(opline->op1.u.constant);
- lcname = zend_str_tolower_dup(function_name_strval + Z_LVAL(opline->op1.u.constant), function_name_strlen);
- if (zend_hash_find(EG(function_table), lcname, function_name_strlen+1, (void **) &function)==FAILURE ||
- function->type != ZEND_INTERNAL_FUNCTION) {
- efree(lcname);
- zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval);
- }
+ function_name_strlen -= 2;
+ lcname = zend_str_tolower_dup(function_name_strval + 2, function_name_strlen);
} else {
- zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval);
+ lcname = zend_str_tolower_dup(function_name_strval, function_name_strlen);
}
+ ret = zend_hash_find(EG(function_table), lcname, function_name_strlen+1, (void **) &EX(fbc));
+ efree(lcname);
+ }
+
+ if (ret == FAILURE) {
+ zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval);
}
- efree(lcname);
if (IS_CONST != IS_CONST) {
}
EX(object) = NULL;
+ ZEND_VM_NEXT_OPCODE();
+}
+
+
+static int ZEND_INIT_NS_FCALL_BY_NAME_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ zend_op *opline = EX(opline);
+ zend_op *op_data = opline + 1;
- EX(fbc) = function;
+ ZEND_VM_INC_OPCODE();
+ zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
+
+ if (zend_hash_quick_find(EG(function_table), Z_STRVAL(opline->op1.u.constant), Z_STRLEN(opline->op1.u.constant)+1, opline->extended_value, (void **) &EX(fbc))==FAILURE) {
+ if (zend_hash_quick_find(EG(function_table), Z_STRVAL(op_data->op1.u.constant), Z_STRLEN(op_data->op1.u.constant)+1, op_data->extended_value, (void **) &EX(fbc))==FAILURE ||
+ EX(fbc)->type != ZEND_INTERNAL_FUNCTION) {
+ zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL(opline->op2.u.constant));
+ }
+ }
+ EX(object) = NULL;
ZEND_VM_NEXT_OPCODE();
}
@@ -807,60 +812,45 @@ static int ZEND_INIT_FCALL_BY_NAME_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
zend_op *opline = EX(opline);
zval *function_name;
- zend_function *function;
char *function_name_strval, *lcname;
int function_name_strlen;
zend_free_op free_op2;
+ int ret;
zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
if (IS_TMP_VAR == IS_CONST) {
- function_name_strval = opline->op2.u.constant.value.str.val;
- function_name_strlen = opline->op2.u.constant.value.str.len;
+ function_name_strval = Z_STRVAL(opline->op2.u.constant);
+ ret = zend_hash_quick_find(EG(function_table), Z_STRVAL(opline->op1.u.constant), Z_STRLEN(opline->op1.u.constant)+1, opline->extended_value, (void **) &EX(fbc));
} else {
function_name = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
if (Z_TYPE_P(function_name) != IS_STRING) {
zend_error_noreturn(E_ERROR, "Function name must be a string");
}
- function_name_strval = function_name->value.str.val;
- function_name_strlen = function_name->value.str.len;
- }
-
- if (IS_TMP_VAR != IS_CONST &&
- function_name_strval[0] == ':' &&
- function_name_strval[1] == ':') {
+ function_name_strval = Z_STRVAL_P(function_name);
+ function_name_strlen = Z_STRLEN_P(function_name);
+ if (function_name_strval[0] == ':' &&
+ function_name_strval[1] == ':') {
- function_name_strlen -= 2;
- lcname = zend_str_tolower_dup(function_name_strval + 2, function_name_strlen);
- } else {
- lcname = zend_str_tolower_dup(function_name_strval, function_name_strlen);
- }
- if (zend_hash_find(EG(function_table), lcname, function_name_strlen+1, (void **) &function)==FAILURE) {
- efree(lcname);
-
- if (IS_TMP_VAR == IS_CONST && opline->op1.op_type == IS_CONST) {
- function_name_strlen -= Z_LVAL(opline->op1.u.constant);
- lcname = zend_str_tolower_dup(function_name_strval + Z_LVAL(opline->op1.u.constant), function_name_strlen);
- if (zend_hash_find(EG(function_table), lcname, function_name_strlen+1, (void **) &function)==FAILURE ||
- function->type != ZEND_INTERNAL_FUNCTION) {
- efree(lcname);
- zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval);
- }
+ function_name_strlen -= 2;
+ lcname = zend_str_tolower_dup(function_name_strval + 2, function_name_strlen);
} else {
- zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval);
+ lcname = zend_str_tolower_dup(function_name_strval, function_name_strlen);
}
+ ret = zend_hash_find(EG(function_table), lcname, function_name_strlen+1, (void **) &EX(fbc));
+ efree(lcname);
+ }
+
+ if (ret == FAILURE) {
+ zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval);
}
- efree(lcname);
if (IS_TMP_VAR != IS_CONST) {
zval_dtor(free_op2.var);
}
EX(object) = NULL;
-
- EX(fbc) = function;
-
ZEND_VM_NEXT_OPCODE();
}
@@ -923,60 +913,45 @@ static int ZEND_INIT_FCALL_BY_NAME_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
zend_op *opline = EX(opline);
zval *function_name;
- zend_function *function;
char *function_name_strval, *lcname;
int function_name_strlen;
zend_free_op free_op2;
+ int ret;
zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
if (IS_VAR == IS_CONST) {
- function_name_strval = opline->op2.u.constant.value.str.val;
- function_name_strlen = opline->op2.u.constant.value.str.len;
+ function_name_strval = Z_STRVAL(opline->op2.u.constant);
+ ret = zend_hash_quick_find(EG(function_table), Z_STRVAL(opline->op1.u.constant), Z_STRLEN(opline->op1.u.constant)+1, opline->extended_value, (void **) &EX(fbc));
} else {
function_name = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
if (Z_TYPE_P(function_name) != IS_STRING) {
zend_error_noreturn(E_ERROR, "Function name must be a string");
}
- function_name_strval = function_name->value.str.val;
- function_name_strlen = function_name->value.str.len;
- }
-
- if (IS_VAR != IS_CONST &&
- function_name_strval[0] == ':' &&
- function_name_strval[1] == ':') {
-
- function_name_strlen -= 2;
- lcname = zend_str_tolower_dup(function_name_strval + 2, function_name_strlen);
- } else {
- lcname = zend_str_tolower_dup(function_name_strval, function_name_strlen);
- }
- if (zend_hash_find(EG(function_table), lcname, function_name_strlen+1, (void **) &function)==FAILURE) {
- efree(lcname);
+ function_name_strval = Z_STRVAL_P(function_name);
+ function_name_strlen = Z_STRLEN_P(function_name);
+ if (function_name_strval[0] == ':' &&
+ function_name_strval[1] == ':') {
- if (IS_VAR == IS_CONST && opline->op1.op_type == IS_CONST) {
- function_name_strlen -= Z_LVAL(opline->op1.u.constant);
- lcname = zend_str_tolower_dup(function_name_strval + Z_LVAL(opline->op1.u.constant), function_name_strlen);
- if (zend_hash_find(EG(function_table), lcname, function_name_strlen+1, (void **) &function)==FAILURE ||
- function->type != ZEND_INTERNAL_FUNCTION) {
- efree(lcname);
- zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval);
- }
+ function_name_strlen -= 2;
+ lcname = zend_str_tolower_dup(function_name_strval + 2, function_name_strlen);
} else {
- zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval);
+ lcname = zend_str_tolower_dup(function_name_strval, function_name_strlen);
}
+ ret = zend_hash_find(EG(function_table), lcname, function_name_strlen+1, (void **) &EX(fbc));
+ efree(lcname);
+ }
+
+ if (ret == FAILURE) {
+ zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval);
}
- efree(lcname);
if (IS_VAR != IS_CONST) {
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
}
EX(object) = NULL;
-
- EX(fbc) = function;
-
ZEND_VM_NEXT_OPCODE();
}
@@ -1067,60 +1042,45 @@ static int ZEND_INIT_FCALL_BY_NAME_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
zend_op *opline = EX(opline);
zval *function_name;
- zend_function *function;
char *function_name_strval, *lcname;
int function_name_strlen;
+ int ret;
zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
if (IS_CV == IS_CONST) {
- function_name_strval = opline->op2.u.constant.value.str.val;
- function_name_strlen = opline->op2.u.constant.value.str.len;
+ function_name_strval = Z_STRVAL(opline->op2.u.constant);
+ ret = zend_hash_quick_find(EG(function_table), Z_STRVAL(opline->op1.u.constant), Z_STRLEN(opline->op1.u.constant)+1, opline->extended_value, (void **) &EX(fbc));
} else {
function_name = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);
if (Z_TYPE_P(function_name) != IS_STRING) {
zend_error_noreturn(E_ERROR, "Function name must be a string");
}
- function_name_strval = function_name->value.str.val;
- function_name_strlen = function_name->value.str.len;
- }
-
- if (IS_CV != IS_CONST &&
- function_name_strval[0] == ':' &&
- function_name_strval[1] == ':') {
+ function_name_strval = Z_STRVAL_P(function_name);
+ function_name_strlen = Z_STRLEN_P(function_name);
+ if (function_name_strval[0] == ':' &&
+ function_name_strval[1] == ':') {
- function_name_strlen -= 2;
- lcname = zend_str_tolower_dup(function_name_strval + 2, function_name_strlen);
- } else {
- lcname = zend_str_tolower_dup(function_name_strval, function_name_strlen);
- }
- if (zend_hash_find(EG(function_table), lcname, function_name_strlen+1, (void **) &function)==FAILURE) {
- efree(lcname);
-
- if (IS_CV == IS_CONST && opline->op1.op_type == IS_CONST) {
- function_name_strlen -= Z_LVAL(opline->op1.u.constant);
- lcname = zend_str_tolower_dup(function_name_strval + Z_LVAL(opline->op1.u.constant), function_name_strlen);
- if (zend_hash_find(EG(function_table), lcname, function_name_strlen+1, (void **) &function)==FAILURE ||
- function->type != ZEND_INTERNAL_FUNCTION) {
- efree(lcname);
- zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval);
- }
+ function_name_strlen -= 2;
+ lcname = zend_str_tolower_dup(function_name_strval + 2, function_name_strlen);
} else {
- zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval);
+ lcname = zend_str_tolower_dup(function_name_strval, function_name_strlen);
}
+ ret = zend_hash_find(EG(function_table), lcname, function_name_strlen+1, (void **) &EX(fbc));
+ efree(lcname);
+ }
+
+ if (ret == FAILURE) {
+ zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval);
}
- efree(lcname);
if (IS_CV != IS_CONST) {
}
EX(object) = NULL;
-
- EX(fbc) = function;
-
ZEND_VM_NEXT_OPCODE();
}
@@ -1420,7 +1380,7 @@ static int ZEND_DO_FCALL_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
- if (zend_hash_find(EG(function_table), fname->value.str.val, fname->value.str.len+1, (void **) &EX(function_state).function)==FAILURE) {
+ if (zend_hash_quick_find(EG(function_table), fname->value.str.val, fname->value.str.len+1, Z_LVAL(opline->op2.u.constant), (void **) &EX(function_state).function)==FAILURE) {
zend_error_noreturn(E_ERROR, "Call to undefined function %s()", fname->value.str.val);
}
EX(object) = NULL;
@@ -29742,27 +29702,27 @@ void zend_init_opcodes_handlers(void)
ZEND_NEW_SPEC_HANDLER,
ZEND_NEW_SPEC_HANDLER,
ZEND_NEW_SPEC_HANDLER,
+ ZEND_INIT_NS_FCALL_BY_NAME_SPEC_CONST_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
+ ZEND_INIT_NS_FCALL_BY_NAME_SPEC_CONST_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
+ ZEND_INIT_NS_FCALL_BY_NAME_SPEC_CONST_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
+ ZEND_INIT_NS_FCALL_BY_NAME_SPEC_CONST_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
- ZEND_NULL_HANDLER,
- ZEND_NULL_HANDLER,
- ZEND_NULL_HANDLER,
- ZEND_NULL_HANDLER,
- ZEND_NULL_HANDLER,
+ ZEND_INIT_NS_FCALL_BY_NAME_SPEC_CONST_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
diff --git a/Zend/zend_vm_opcodes.h b/Zend/zend_vm_opcodes.h
index d663ea6d55..7b11303639 100644
--- a/Zend/zend_vm_opcodes.h
+++ b/Zend/zend_vm_opcodes.h
@@ -87,6 +87,7 @@
#define ZEND_SEND_VAR 66
#define ZEND_SEND_REF 67
#define ZEND_NEW 68
+#define ZEND_INIT_NS_FCALL_BY_NAME 69
#define ZEND_FREE 70
#define ZEND_INIT_ARRAY 71
#define ZEND_ADD_ARRAY_ELEMENT 72