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);
-}
-/* }}} */
-
static zend_property_info *zend_duplicate_property_info(zend_property_info *property_info) /* {{{ */
{
zend_property_info* new_property_info = emalloc(sizeof(zend_property_info));
}
/* }}} */
-void zend_do_unary_op(zend_uchar op, znode *result, znode *op1 TSRMLS_DC) /* {{{ */
-{
- zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
-
- opline->opcode = op;
- opline->result_type = IS_TMP_VAR;
- opline->result.var = get_temporary_variable(CG(active_op_array));
- SET_NODE(opline->op1, op1);
- GET_NODE(result, opline->result);
- SET_UNUSED(opline->op2);
-}
-/* }}} */
-
#define MAKE_NOP(opline) { opline->opcode = ZEND_NOP; memset(&opline->result,0,sizeof(opline->result)); memset(&opline->op1,0,sizeof(opline->op1)); memset(&opline->op2,0,sizeof(opline->op2)); opline->result_type=opline->op1_type=opline->op2_type=IS_UNUSED; }
static void zend_do_op_data(zend_op *data_op, znode *value TSRMLS_DC) /* {{{ */
}
/* }}} */
-static zend_bool zend_can_parse_variable_for_write(znode *variable TSRMLS_DC) /* {{{ */
-{
- zend_llist *fetch_list_ptr = zend_stack_top(&CG(bp_stack));
- zend_llist_element *le = fetch_list_ptr->head;
- for (le = fetch_list_ptr->head; le; le = le->next) {
- zend_op *opline = (zend_op *) le->data;
- if ((opline->opcode != ZEND_SEPARATE && opline->opcode != ZEND_FETCH_W)
- && (opline->op1_type == IS_TMP_VAR || opline->op1_type == IS_CONST)
- ) {
- return 0;
- }
- }
- return 1;
-}
-/* }}} */
-
void zend_do_end_variable_parse(znode *variable, int type, int arg_offset TSRMLS_DC) /* {{{ */
{
zend_llist *fetch_list_ptr = zend_stack_top(&CG(bp_stack));
}
/* }}} */
-void zend_do_shell_exec(znode *result, znode *cmd TSRMLS_DC) /* {{{ */
-{
- zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
-
- switch (cmd->op_type) {
- case IS_CONST:
- case IS_TMP_VAR:
- opline->opcode = ZEND_SEND_VAL;
- break;
- default:
- opline->opcode = ZEND_SEND_VAR;
- break;
- }
- SET_NODE(opline->op1, cmd);
- opline->op2.opline_num = 1;
- opline->extended_value = ZEND_DO_FCALL;
- SET_UNUSED(opline->op2);
-
- /* FIXME: exception support not added to this op2 */
- opline = get_next_op(CG(active_op_array) TSRMLS_CC);
- opline->opcode = ZEND_DO_FCALL;
- opline->result.var = get_temporary_variable(CG(active_op_array));
- opline->result_type = IS_VAR;
- LITERAL_STR(opline->op1, STR_INIT("shell_exec", sizeof("shell_exec")-1, 0));
- opline->op1_type = IS_CONST;
- GET_CACHE_SLOT(opline->op1.constant);
- opline->extended_value = 1;
- SET_UNUSED(opline->op2);
- opline->op2.num = CG(context).nested_calls;
- GET_NODE(result, opline->result);
-
- if (CG(context).nested_calls + 1 > CG(active_op_array)->nested_calls) {
- CG(active_op_array)->nested_calls = CG(context).nested_calls + 1;
- }
- if (CG(context).used_stack + 2 > CG(active_op_array)->used_stack) {
- CG(active_op_array)->used_stack = CG(context).used_stack + 2;
- }
-}
-/* }}} */
-
-void zend_do_init_array(znode *result, znode *expr, znode *offset, zend_bool is_ref TSRMLS_DC) /* {{{ */
-{
- int op_num = get_next_op_number(CG(active_op_array));
- zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
-
- result->u.op.opline_num = op_num;
-
- opline->opcode = ZEND_INIT_ARRAY;
- opline->result.var = get_temporary_variable(CG(active_op_array));
- opline->result_type = IS_TMP_VAR;
- opline->extended_value = is_ref; /* extval = size << 2 | not_packed << 1 | is_ref */
-
- if (expr) {
- opline->extended_value += 1 << ZEND_ARRAY_SIZE_SHIFT; /* increment size */
- SET_NODE(opline->op1, expr);
- if (offset) {
- SET_NODE(opline->op2, offset);
- if (opline->op2_type == IS_CONST && Z_TYPE(CONSTANT(opline->op2.constant)) == IS_STRING) {
- ulong index;
- int numeric = 0;
-
- opline->extended_value |= ZEND_ARRAY_NOT_PACKED;
- ZEND_HANDLE_NUMERIC_EX(Z_STRVAL(CONSTANT(opline->op2.constant)), Z_STRLEN(CONSTANT(opline->op2.constant))+1, index, numeric = 1);
- if (numeric) {
- zval_dtor(&CONSTANT(opline->op2.constant));
- ZVAL_LONG(&CONSTANT(opline->op2.constant), index);
- }
- }
- } else {
- SET_UNUSED(opline->op2);
- }
- } else {
- SET_UNUSED(opline->op1);
- SET_UNUSED(opline->op2);
- }
-}
-/* }}} */
-
-void zend_do_add_array_element(znode *result, znode *expr, znode *offset, zend_bool is_ref TSRMLS_DC) /* {{{ */
-{
- zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
- zend_op *init_opline = &CG(active_op_array)->opcodes[result->u.op.opline_num];
- init_opline->extended_value += 1 << ZEND_ARRAY_SIZE_SHIFT; /* increment size */
-
- opline->opcode = ZEND_ADD_ARRAY_ELEMENT;
- COPY_NODE(opline->result, init_opline->result);
- SET_NODE(opline->op1, expr);
- if (offset) {
- SET_NODE(opline->op2, offset);
- if (opline->op2_type == IS_CONST && Z_TYPE(CONSTANT(opline->op2.constant)) == IS_STRING) {
- ulong index;
- int numeric = 0;
-
- init_opline->extended_value |= ZEND_ARRAY_NOT_PACKED;
- ZEND_HANDLE_NUMERIC_EX(Z_STRVAL(CONSTANT(opline->op2.constant)), Z_STRLEN(CONSTANT(opline->op2.constant))+1, index, numeric = 1);
- if (numeric) {
- zval_dtor(&CONSTANT(opline->op2.constant));
- ZVAL_LONG(&CONSTANT(opline->op2.constant), index);
- }
- }
- } else {
- SET_UNUSED(opline->op2);
- }
- opline->extended_value = is_ref;
-}
-/* }}} */
-
-void zend_do_end_array(znode *result, const znode *array_node TSRMLS_DC) /* {{{ */
-{
- int next_op_num = get_next_op_number(CG(active_op_array));
- zend_op *init_opline = &CG(active_op_array)->opcodes[array_node->u.op.opline_num];
- zend_op *opline;
- int i;
- int constant_array = 0;
- zval array;
-
- /* check if constructed array consists only from constants */
- if ((init_opline->op1_type & (IS_UNUSED | IS_CONST)) &&
- (init_opline->op2_type & (IS_UNUSED | IS_CONST))) {
- if (next_op_num == array_node->u.op.opline_num + 1) {
- constant_array = 1;
- } else if ((init_opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT) == next_op_num - array_node->u.op.opline_num) {
- opline = init_opline + 1;
- i = next_op_num - array_node->u.op.opline_num - 1;
- while (i > 0) {
- if (opline->opcode != ZEND_ADD_ARRAY_ELEMENT ||
- opline->op1_type != IS_CONST ||
- !(opline->op2_type & (IS_UNUSED | IS_CONST))) {
- break;
- }
- opline++;
- i--;
- }
- if (i == 0) {
- constant_array = 1;
- }
- }
- }
-
- if (constant_array) {
- /* try to construct constant array */
- zend_uint size;
- long num;
- zend_string *str;
-
- if (init_opline->op1_type != IS_UNUSED) {
- size = init_opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT;
- } else {
- size = 0;
- }
- ZVAL_NEW_ARR(&array);
- zend_hash_init(Z_ARRVAL(array), size, NULL, ZVAL_PTR_DTOR, 0);
-
- if (init_opline->op1_type != IS_UNUSED) {
- /* Explicitly initialize array as not-packed if flag is set */
- if (init_opline->extended_value & ZEND_ARRAY_NOT_PACKED) {
- zend_hash_real_init(Z_ARRVAL(array), 0);
- }
-
- opline = init_opline;
- i = next_op_num - array_node->u.op.opline_num;
- while (i > 0 && constant_array) {
- if (opline->op2_type == IS_CONST) {
- switch (Z_TYPE(CONSTANT(opline->op2.constant))) {
- case IS_LONG:
- num = Z_LVAL(CONSTANT(opline->op2.constant));
-num_index:
- zend_hash_index_update(Z_ARRVAL(array), num, &CONSTANT(opline->op1.constant));
- if (Z_REFCOUNTED(CONSTANT(opline->op1.constant))) Z_ADDREF(CONSTANT(opline->op1.constant));
- break;
- case IS_STRING:
- str = Z_STR(CONSTANT(opline->op2.constant));
-str_index:
- zend_hash_update(Z_ARRVAL(array), str, &CONSTANT(opline->op1.constant));
- if (Z_REFCOUNTED(CONSTANT(opline->op1.constant))) Z_ADDREF(CONSTANT(opline->op1.constant));
- break;
- case IS_DOUBLE:
- num = zend_dval_to_lval(Z_DVAL(CONSTANT(opline->op2.constant)));
- goto num_index;
- case IS_FALSE:
- num = 0;
- goto num_index;
- case IS_TRUE:
- num = 1;
- goto num_index;
- case IS_NULL:
- str = STR_EMPTY_ALLOC();
- goto str_index;
- default:
- constant_array = 0;
- break;
- }
- } else {
- zend_hash_next_index_insert(Z_ARRVAL(array), &CONSTANT(opline->op1.constant));
- if (Z_REFCOUNTED(CONSTANT(opline->op1.constant))) Z_ADDREF(CONSTANT(opline->op1.constant));
- }
- opline++;
- i--;
- }
- if (!constant_array) {
- zval_dtor(&array);
- }
- }
- }
-
- if (constant_array) {
- /* remove run-time array construction and use constant array instead */
- opline = &CG(active_op_array)->opcodes[next_op_num-1];
- while (opline != init_opline) {
- if (opline->op2_type == IS_CONST) {
- zend_del_literal(CG(active_op_array), opline->op2.constant);
- }
- zend_del_literal(CG(active_op_array), opline->op1.constant);
- opline--;
- }
- if (opline->op2_type == IS_CONST) {
- zend_del_literal(CG(active_op_array), opline->op2.constant);
- }
- if (opline->op1_type == IS_CONST) {
- zend_del_literal(CG(active_op_array), opline->op1.constant);
- }
- CG(active_op_array)->last = array_node->u.op.opline_num;
-
- zend_make_immutable_array(&array TSRMLS_CC);
-
- result->op_type = IS_CONST;
- ZVAL_COPY_VALUE(&result->u.constant, &array);
- } else {
- GET_NODE(result, init_opline->result);
- }
-}
-/* }}} */
-
void zend_init_list(void *result, void *item TSRMLS_DC) /* {{{ */
{
void** list = emalloc(sizeof(void*) * 2);
}
/* }}} */
-void zend_do_include_or_eval(int type, znode *result, znode *op1 TSRMLS_DC) /* {{{ */
-{
- zend_do_extended_fcall_begin(TSRMLS_C);
- {
- zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
-
- opline->opcode = ZEND_INCLUDE_OR_EVAL;
- opline->result_type = IS_VAR;
- opline->result.var = get_temporary_variable(CG(active_op_array));
- SET_NODE(opline->op1, op1);
- SET_UNUSED(opline->op2);
- opline->extended_value = type;
- GET_NODE(result, opline->result);
- }
- zend_do_extended_fcall_end(TSRMLS_C);
-}
-/* }}} */
-
-void zend_do_indirect_reference(znode *result, znode *variable TSRMLS_DC) /* {{{ */
-{
- fetch_simple_variable_ex(result, variable, 0, ZEND_FETCH_R TSRMLS_CC);
-
- /* there is a chance someone is accessing $this */
- if (CG(active_op_array)->scope && CG(active_op_array)->this_var == -1) {
- zend_string *key = STR_INIT("this", sizeof("this")-1, 0);
- CG(active_op_array)->this_var = lookup_cv(CG(active_op_array), key TSRMLS_CC);
- }
-}
-/* }}} */
-
-void zend_do_unset(znode *variable TSRMLS_DC) /* {{{ */
-{
- zend_op *last_op;
-
- zend_check_writable_variable(variable);
-
- if (variable->op_type == IS_CV) {
- zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
- opline->opcode = ZEND_UNSET_VAR;
- SET_NODE(opline->op1, variable);
- SET_UNUSED(opline->op2);
- SET_UNUSED(opline->result);
- opline->extended_value = ZEND_FETCH_LOCAL | ZEND_QUICK_SET;
- } else {
- last_op = &CG(active_op_array)->opcodes[get_next_op_number(CG(active_op_array))-1];
-
- switch (last_op->opcode) {
- case ZEND_FETCH_UNSET:
- last_op->opcode = ZEND_UNSET_VAR;
- SET_UNUSED(last_op->result);
- break;
- case ZEND_FETCH_DIM_UNSET:
- last_op->opcode = ZEND_UNSET_DIM;
- SET_UNUSED(last_op->result);
- break;
- case ZEND_FETCH_OBJ_UNSET:
- last_op->opcode = ZEND_UNSET_OBJ;
- SET_UNUSED(last_op->result);
- break;
-
- }
- }
-}
-/* }}} */
-
-void zend_do_isset_or_isempty(int type, znode *result, znode *variable TSRMLS_DC) /* {{{ */
-{
- zend_op *last_op;
-
- if (zend_is_call(variable->u.ast)) {
- if (type == ZEND_ISEMPTY) {
- /* empty(func()) can be transformed to !func() */
- AST_COMPILE(variable, variable->u.ast);
- zend_do_unary_op(ZEND_BOOL_NOT, result, variable TSRMLS_CC);
- } else {
- zend_error_noreturn(E_COMPILE_ERROR, "Cannot use isset() on the result of a function call (you can use \"null !== func()\" instead)");
- }
-
- return;
- }
-
- AST_COMPILE_VAR(variable, variable->u.ast, BP_VAR_IS);
-
- if (variable->op_type == IS_CV) {
- last_op = get_next_op(CG(active_op_array) TSRMLS_CC);
- last_op->opcode = ZEND_ISSET_ISEMPTY_VAR;
- SET_NODE(last_op->op1, variable);
- SET_UNUSED(last_op->op2);
- last_op->result.var = get_temporary_variable(CG(active_op_array));
- last_op->extended_value = ZEND_FETCH_LOCAL | ZEND_QUICK_SET;
- } else {
- last_op = &CG(active_op_array)->opcodes[get_next_op_number(CG(active_op_array))-1];
-
- switch (last_op->opcode) {
- case ZEND_FETCH_IS:
- last_op->opcode = ZEND_ISSET_ISEMPTY_VAR;
- break;
- case ZEND_FETCH_DIM_IS:
- last_op->opcode = ZEND_ISSET_ISEMPTY_DIM_OBJ;
- break;
- case ZEND_FETCH_OBJ_IS:
- last_op->opcode = ZEND_ISSET_ISEMPTY_PROP_OBJ;
- break;
- }
- }
- last_op->result_type = IS_TMP_VAR;
- last_op->extended_value |= type;
-
- GET_NODE(result, last_op->result);
-}
-/* }}} */
-
-void zend_do_instanceof(znode *result, znode *expr, znode *class_znode, int type TSRMLS_DC) /* {{{ */
-{
- int last_op_number = get_next_op_number(CG(active_op_array));
- zend_op *opline;
-
- if (last_op_number > 0) {
- opline = &CG(active_op_array)->opcodes[last_op_number-1];
- if (opline->opcode == ZEND_FETCH_CLASS) {
- opline->extended_value |= ZEND_FETCH_CLASS_NO_AUTOLOAD;
- }
- }
-
- if (expr->op_type == IS_CONST) {
- zend_error_noreturn(E_COMPILE_ERROR, "instanceof expects an object instance, constant given");
- }
-
- opline = get_next_op(CG(active_op_array) TSRMLS_CC);
- opline->opcode = ZEND_INSTANCEOF;
- opline->result_type = IS_TMP_VAR;
- opline->result.var = get_temporary_variable(CG(active_op_array));
- SET_NODE(opline->op1, expr);
-
- SET_NODE(opline->op2, class_znode);
-
- GET_NODE(result, opline->result);
-}
-/* }}} */
-
static zend_bool zend_can_write_to_variable(zend_ast *ast);
void zend_do_foreach_begin(znode *foreach_token, znode *open_brackets_token, znode *array, znode *as_token, int variable TSRMLS_DC) /* {{{ */
}
/* }}} */
-void zend_do_begin_silence(znode *strudel_token TSRMLS_DC) /* {{{ */
-{
- zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
-
- opline->opcode = ZEND_BEGIN_SILENCE;
- opline->result_type = IS_TMP_VAR;
- opline->result.var = get_temporary_variable(CG(active_op_array));
- SET_UNUSED(opline->op1);
- SET_UNUSED(opline->op2);
- GET_NODE(strudel_token, opline->result);
-}
-/* }}} */
-
-void zend_do_end_silence(znode *strudel_token TSRMLS_DC) /* {{{ */
-{
- zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
-
- opline->opcode = ZEND_END_SILENCE;
- SET_NODE(opline->op1, strudel_token);
- SET_UNUSED(opline->op2);
-}
-/* }}} */
-
void zend_do_extended_info(TSRMLS_D) /* {{{ */
{
zend_op *opline;
/* parser-driven code generators */
-void zend_do_unary_op(zend_uchar op, znode *result, znode *op1 TSRMLS_DC);
void zend_do_assign(znode *result, znode *variable, znode *value TSRMLS_DC);
void zend_do_assign_ref(znode *result, znode *lvar, znode *rvar TSRMLS_DC);
void fetch_simple_variable(znode *result, znode *varname, int bp TSRMLS_DC);
void fetch_simple_variable_ex(znode *result, znode *varname, int bp, zend_uchar op TSRMLS_DC);
-void zend_do_indirect_reference(znode *result, znode *variable TSRMLS_DC);
void zend_do_fetch_static_variable(znode *varname, znode *static_assignment, int fetch_type TSRMLS_DC);
void zend_do_fetch_global_variable(znode *varname, const znode *static_assignment, int fetch_type TSRMLS_DC);
void zend_do_receive_param(zend_uchar op, znode *varname, znode *initialization, znode *class_type, zend_bool pass_by_reference, zend_bool is_variadic TSRMLS_DC);
void zend_do_fetch_class(znode *result, znode *class_name TSRMLS_DC);
void zend_do_build_full_name(znode *result, znode *prefix, znode *name, int is_class_member TSRMLS_DC);
-void zend_do_end_function_call(znode *function_name, znode *result, int is_method, int is_dynamic_fcall TSRMLS_DC);
void zend_do_return(znode *expr, int do_end_vparse TSRMLS_DC);
void zend_do_handle_exception(TSRMLS_D);
void zend_do_fetch_constant(znode *result, znode *constant_container, znode *constant_name, int mode, zend_bool check_namespace TSRMLS_DC);
-void zend_do_shell_exec(znode *result, znode *cmd TSRMLS_DC);
-
-void zend_do_init_array(znode *result, znode *expr, znode *offset, zend_bool is_ref TSRMLS_DC);
-void zend_do_add_array_element(znode *result, znode *expr, znode *offset, zend_bool is_ref TSRMLS_DC);
-void zend_do_end_array(znode *result, const znode *array_node TSRMLS_DC);
-
/* Functions for a null terminated pointer list, used for traits parsing and compilation */
void zend_init_list(void *result, void *item TSRMLS_DC);
void zend_add_to_list(void *result, void *item TSRMLS_DC);
-
-void zend_do_include_or_eval(int type, znode *result, znode *op1 TSRMLS_DC);
-
-void zend_do_unset(znode *variable TSRMLS_DC);
-void zend_do_isset_or_isempty(int type, znode *result, znode *variable TSRMLS_DC);
-
-void zend_do_instanceof(znode *result, znode *expr, znode *class_znode, int type TSRMLS_DC);
-
void zend_do_foreach_begin(znode *foreach_token, znode *open_brackets_token, znode *array, znode *as_token, int variable TSRMLS_DC);
void zend_do_foreach_cont(znode *foreach_token, const znode *open_brackets_token, const znode *as_token, znode *value, znode *key TSRMLS_DC);
void zend_do_foreach_end(const znode *foreach_token, const znode *as_token TSRMLS_DC);
void zend_do_declare_stmt(znode *var, znode *val TSRMLS_DC);
void zend_do_declare_end(const znode *declare_token TSRMLS_DC);
-void zend_do_begin_silence(znode *strudel_token TSRMLS_DC);
-void zend_do_end_silence(znode *strudel_token TSRMLS_DC);
-
void zend_do_extended_info(TSRMLS_D);
void zend_do_extended_fcall_begin(TSRMLS_D);
void zend_do_extended_fcall_end(TSRMLS_D);