Skip to content

Commit

Permalink
Introduce zend_function_call_entry structure
Browse files Browse the repository at this point in the history
Instead of directly pushing the zend_function* onto the
function_call_stack, push this structure. This allows us to store
additional data on this stack.
  • Loading branch information
nikic committed Feb 26, 2014
1 parent 44053a9 commit cefa7f8
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 20 deletions.
44 changes: 24 additions & 20 deletions Zend/zend_compile.c
Expand Up @@ -102,6 +102,13 @@ ZEND_API zend_compiler_globals compiler_globals;
ZEND_API zend_executor_globals executor_globals;
#endif

static void zend_push_function_call_entry(zend_function *fbc TSRMLS_DC) /* {{{ */
{
zend_function_call_entry fcall = { fbc };
zend_stack_push(&CG(function_call_stack), &fcall, sizeof(zend_function_call_entry));
}
/* }}} */

static void zend_duplicate_property_info(zend_property_info *property_info) /* {{{ */
{
property_info->name = str_estrndup(property_info->name, property_info->name_length);
Expand Down Expand Up @@ -1989,7 +1996,7 @@ int zend_do_begin_function_call(znode *function_name, zend_bool check_namespace
efree(Z_STRVAL(function_name->u.constant));
Z_STRVAL(function_name->u.constant) = lcname;

zend_stack_push(&CG(function_call_stack), (void *) &function, sizeof(zend_function *));
zend_push_function_call_entry(function TSRMLS_CC);
if (CG(context).nested_calls + 1 > CG(active_op_array)->nested_calls) {
CG(active_op_array)->nested_calls = CG(context).nested_calls + 1;
}
Expand All @@ -2002,7 +2009,6 @@ void zend_do_begin_method_call(znode *left_bracket TSRMLS_DC) /* {{{ */
{
zend_op *last_op;
int last_op_number;
unsigned char *ptr = NULL;

zend_do_end_variable_parse(left_bracket, BP_VAR_R, 0 TSRMLS_CC);
zend_do_begin_variable_parse(TSRMLS_C);
Expand Down Expand Up @@ -2046,7 +2052,7 @@ void zend_do_begin_method_call(znode *left_bracket TSRMLS_DC) /* {{{ */
}
}

zend_stack_push(&CG(function_call_stack), (void *) &ptr, sizeof(zend_function *));
zend_push_function_call_entry(NULL TSRMLS_CC);
if (++CG(context).nested_calls > CG(active_op_array)->nested_calls) {
CG(active_op_array)->nested_calls = CG(context).nested_calls;
}
Expand All @@ -2069,7 +2075,6 @@ void zend_do_clone(znode *result, const znode *expr TSRMLS_DC) /* {{{ */

void zend_do_begin_dynamic_function_call(znode *function_name, int ns_call TSRMLS_DC) /* {{{ */
{
unsigned char *ptr = NULL;
zend_op *opline;

opline = get_next_op(CG(active_op_array) TSRMLS_CC);
Expand All @@ -2095,7 +2100,7 @@ void zend_do_begin_dynamic_function_call(znode *function_name, int ns_call TSRML
}
}

zend_stack_push(&CG(function_call_stack), (void *) &ptr, sizeof(zend_function *));
zend_push_function_call_entry(NULL TSRMLS_CC);
if (++CG(context).nested_calls > CG(active_op_array)->nested_calls) {
CG(active_op_array)->nested_calls = CG(context).nested_calls;
}
Expand Down Expand Up @@ -2490,7 +2495,6 @@ void zend_do_build_full_name(znode *result, znode *prefix, znode *name, int is_c
int zend_do_begin_class_member_function_call(znode *class_name, znode *method_name TSRMLS_DC) /* {{{ */
{
znode class_node;
unsigned char *ptr = NULL;
zend_op *opline;

if (method_name->op_type == IS_CONST) {
Expand Down Expand Up @@ -2539,7 +2543,7 @@ int zend_do_begin_class_member_function_call(znode *class_name, znode *method_na
SET_NODE(opline->op2, method_name);
}

zend_stack_push(&CG(function_call_stack), (void *) &ptr, sizeof(zend_function *));
zend_push_function_call_entry(NULL TSRMLS_CC);
if (++CG(context).nested_calls > CG(active_op_array)->nested_calls) {
CG(active_op_array)->nested_calls = CG(context).nested_calls;
}
Expand All @@ -2559,11 +2563,11 @@ void zend_do_end_function_call(znode *function_name, znode *result, const znode
}
opline = &CG(active_op_array)->opcodes[Z_LVAL(function_name->u.constant)];
} else {
zend_function **function_ptr_ptr;
zend_stack_top(&CG(function_call_stack), (void **) &function_ptr_ptr);
zend_function_call_entry *fcall;
zend_stack_top(&CG(function_call_stack), (void **) &fcall);

opline = get_next_op(CG(active_op_array) TSRMLS_CC);
if (*function_ptr_ptr) {
if (fcall->fbc) {
opline->opcode = ZEND_DO_FCALL;
SET_NODE(opline->op1, function_name);
SET_UNUSED(opline->op2);
Expand Down Expand Up @@ -2603,12 +2607,13 @@ void zend_do_pass_param(znode *param, zend_uchar op, int offset TSRMLS_DC) /* {{
{
zend_op *opline;
int original_op = op;
zend_function **function_ptr_ptr, *function_ptr;
zend_function_call_entry *fcall;
zend_function *function_ptr;
int send_by_reference = 0;
int send_function = 0;

zend_stack_top(&CG(function_call_stack), (void **) &function_ptr_ptr);
function_ptr = *function_ptr_ptr;
zend_stack_top(&CG(function_call_stack), (void **) &fcall);
function_ptr = fcall->fbc;

if (original_op == ZEND_SEND_REF) {
if (function_ptr &&
Expand Down Expand Up @@ -2710,15 +2715,15 @@ void zend_do_pass_param(znode *param, zend_uchar op, int offset TSRMLS_DC) /* {{
void zend_do_unpack_params(znode *params, int offset TSRMLS_DC) /* {{{ */
{
zend_op *opline;
zend_function **function_ptr_ptr;
zend_function_call_entry *fcall;

zend_stack_top(&CG(function_call_stack), (void **) &function_ptr_ptr);
if (*function_ptr_ptr) {
zend_stack_top(&CG(function_call_stack), (void **) &fcall);
if (fcall->fbc) {
/* If argument unpacking is used argument numbers and sending modes can no longer be
* computed at compile time, thus we need access to EX(call). In order to have it we
* retroactively emit a ZEND_INIT_FCALL_BY_NAME opcode. */
zval func_name;
ZVAL_STRING(&func_name, (*function_ptr_ptr)->common.function_name, 1);
ZVAL_STRING(&func_name, fcall->fbc->common.function_name, 1);

opline = get_next_op(CG(active_op_array) TSRMLS_CC);
opline->opcode = ZEND_INIT_FCALL_BY_NAME;
Expand All @@ -2729,7 +2734,7 @@ void zend_do_unpack_params(znode *params, int offset TSRMLS_DC) /* {{{ */
GET_CACHE_SLOT(opline->op2.constant);

++CG(context).nested_calls;
*function_ptr_ptr = NULL;
fcall->fbc = NULL;
}

opline = get_next_op(CG(active_op_array) TSRMLS_CC);
Expand Down Expand Up @@ -5577,7 +5582,6 @@ void zend_do_pop_object(znode *object TSRMLS_DC) /* {{{ */
void zend_do_begin_new_object(znode *new_token, znode *class_type TSRMLS_DC) /* {{{ */
{
zend_op *opline;
unsigned char *ptr = NULL;

new_token->u.op.opline_num = get_next_op_number(CG(active_op_array));
opline = get_next_op(CG(active_op_array) TSRMLS_CC);
Expand All @@ -5588,7 +5592,7 @@ void zend_do_begin_new_object(znode *new_token, znode *class_type TSRMLS_DC) /*
SET_NODE(opline->op1, class_type);
SET_UNUSED(opline->op2);

zend_stack_push(&CG(function_call_stack), (void *) &ptr, sizeof(unsigned char *));
zend_push_function_call_entry(NULL TSRMLS_CC);
if (++CG(context).nested_calls > CG(active_op_array)->nested_calls) {
CG(active_op_array)->nested_calls = CG(context).nested_calls;
}
Expand Down
3 changes: 3 additions & 0 deletions Zend/zend_compile.h
Expand Up @@ -363,6 +363,9 @@ typedef struct _zend_function_state {
void **arguments;
} zend_function_state;

typedef struct _zend_function_call_entry {
zend_function *fbc;
} zend_function_call_entry;

typedef struct _zend_switch_entry {
znode cond;
Expand Down

0 comments on commit cefa7f8

Please sign in to comment.