Merge branch 'master' into merge-fastcgi

This commit is contained in:
Xinchen Hui 2015-05-24 14:23:34 +08:00
commit 61f652a179
20 changed files with 195 additions and 319 deletions

View File

@ -0,0 +1,16 @@
--TEST--
Break out of while loop that is followed by a return statement and inside a foreach loop
--FILE--
<?php
$a = [42];
foreach ($a as $b) {
while (1) {
break 2;
}
return;
}
?>
===DONE===
--EXPECT--
===DONE===

View File

@ -179,13 +179,13 @@ ZEND_API void zend_assert_valid_class_name(const zend_string *name) /* {{{ */
}
/* }}} */
typedef struct _scalar_typehint_info {
typedef struct _builtin_type_info {
const char* name;
const size_t name_len;
const zend_uchar type;
} scalar_typehint_info;
} builtin_type_info;
static const scalar_typehint_info scalar_typehints[] = {
static const builtin_type_info builtin_types[] = {
{"int", sizeof("int") - 1, IS_LONG},
{"float", sizeof("float") - 1, IS_DOUBLE},
{"string", sizeof("string") - 1, IS_STRING},
@ -193,31 +193,20 @@ static const scalar_typehint_info scalar_typehints[] = {
{NULL, 0, IS_UNDEF}
};
static zend_always_inline const scalar_typehint_info* zend_find_scalar_typehint(const zend_string *name) /* {{{ */
static zend_always_inline zend_uchar zend_lookup_builtin_type_by_name(const zend_string *name) /* {{{ */
{
const scalar_typehint_info *info = &scalar_typehints[0];
const builtin_type_info *info = &builtin_types[0];
for (; info->name; ++info) {
if (name->len == info->name_len
&& zend_binary_strcasecmp(name->val, name->len, info->name, info->name_len) == 0
) {
return info;
return info->type;
}
}
return NULL;
}
/* }}} */
static zend_always_inline zend_uchar zend_lookup_scalar_typehint_by_name(const zend_string *const_name) /* {{{ */
{
const scalar_typehint_info *info = zend_find_scalar_typehint(const_name);
if (info) {
return info->type;
} else {
return 0;
}
return 0;
}
/* }}} */
@ -572,30 +561,37 @@ void zend_stop_lexing(void) {
LANG_SCNG(yy_cursor) = LANG_SCNG(yy_limit);
}
static inline void zend_begin_loop(void) /* {{{ */
static inline void zend_begin_loop(const znode *loop_var) /* {{{ */
{
zend_brk_cont_element *brk_cont_element;
int parent;
int parent = CG(context).current_brk_cont;
parent = CG(context).current_brk_cont;
CG(context).current_brk_cont = CG(active_op_array)->last_brk_cont;
brk_cont_element = get_next_brk_cont_element(CG(active_op_array));
brk_cont_element->start = get_next_op_number(CG(active_op_array));
brk_cont_element->parent = parent;
if (loop_var) {
zend_stack_push(&CG(loop_var_stack), loop_var);
brk_cont_element->start = get_next_op_number(CG(active_op_array));
} else {
/* The start field is used to free temporary variables in case of exceptions.
* We won't try to free something of we don't have loop variable. */
brk_cont_element->start = -1;
}
}
/* }}} */
static inline void zend_end_loop(int cont_addr, int has_loop_var) /* {{{ */
static inline void zend_end_loop(int cont_addr) /* {{{ */
{
if (!has_loop_var) {
/* The start fileld is used to free temporary variables in case of exceptions.
* We won't try to free something of we don't have loop variable.
*/
CG(active_op_array)->brk_cont_array[CG(context).current_brk_cont].start = -1;
zend_brk_cont_element *brk_cont_element
= &CG(active_op_array)->brk_cont_array[CG(context).current_brk_cont];
brk_cont_element->cont = cont_addr;
brk_cont_element->brk = get_next_op_number(CG(active_op_array));
CG(context).current_brk_cont = brk_cont_element->parent;
if (brk_cont_element->start >= 0) {
zend_stack_del_top(&CG(loop_var_stack));
}
CG(active_op_array)->brk_cont_array[CG(context).current_brk_cont].cont = cont_addr;
CG(active_op_array)->brk_cont_array[CG(context).current_brk_cont].brk = get_next_op_number(CG(active_op_array));
CG(context).current_brk_cont = CG(active_op_array)->brk_cont_array[CG(context).current_brk_cont].parent;
}
/* }}} */
@ -3448,17 +3444,7 @@ void zend_compile_unset(zend_ast *ast) /* {{{ */
static void zend_free_foreach_and_switch_variables(void) /* {{{ */
{
uint32_t opnum_start, opnum_end, i;
opnum_start = get_next_op_number(CG(active_op_array));
zend_stack_apply(&CG(loop_var_stack), ZEND_STACK_APPLY_TOPDOWN, (int (*)(void *element)) generate_free_loop_var);
opnum_end = get_next_op_number(CG(active_op_array));
for (i = opnum_start; i < opnum_end; ++i) {
CG(active_op_array)->opcodes[i].extended_value |= EXT_TYPE_FREE_ON_RETURN;
}
}
/* }}} */
@ -3531,26 +3517,27 @@ void zend_compile_break_continue(zend_ast *ast) /* {{{ */
{
zend_ast *depth_ast = ast->child[0];
znode depth_node;
zend_op *opline;
int depth;
ZEND_ASSERT(ast->kind == ZEND_AST_BREAK || ast->kind == ZEND_AST_CONTINUE);
if (depth_ast) {
zval *depth_zv;
if (depth_ast->kind != ZEND_AST_ZVAL) {
zend_error_noreturn(E_COMPILE_ERROR, "'%s' operator with non-constant operand "
"is no longer supported", ast->kind == ZEND_AST_BREAK ? "break" : "continue");
}
zend_compile_expr(&depth_node, depth_ast);
if (Z_TYPE(depth_node.u.constant) != IS_LONG || Z_LVAL(depth_node.u.constant) < 1) {
depth_zv = zend_ast_get_zval(depth_ast);
if (Z_TYPE_P(depth_zv) != IS_LONG || Z_LVAL_P(depth_zv) < 1) {
zend_error_noreturn(E_COMPILE_ERROR, "'%s' operator accepts only positive numbers",
ast->kind == ZEND_AST_BREAK ? "break" : "continue");
}
depth = Z_LVAL_P(depth_zv);
} else {
depth_node.op_type = IS_CONST;
ZVAL_LONG(&depth_node.u.constant, 1);
depth = 1;
}
if (CG(context).current_brk_cont == -1) {
@ -3558,20 +3545,27 @@ void zend_compile_break_continue(zend_ast *ast) /* {{{ */
ast->kind == ZEND_AST_BREAK ? "break" : "continue");
} else {
int array_offset = CG(context).current_brk_cont;
zend_long nest_level = Z_LVAL(depth_node.u.constant);
zend_long nest_level = depth;
znode *loop_var = zend_stack_top(&CG(loop_var_stack));
do {
if (array_offset == -1) {
zend_error_noreturn(E_COMPILE_ERROR, "Cannot '%s' %d level%s",
ast->kind == ZEND_AST_BREAK ? "break" : "continue",
Z_LVAL(depth_node.u.constant), (Z_LVAL(depth_node.u.constant) == 1) ? "" : "s");
depth, depth == 1 ? "" : "s");
}
if (nest_level > 1 && CG(active_op_array)->brk_cont_array[array_offset].start >= 0) {
generate_free_loop_var(loop_var);
loop_var--;
}
array_offset = CG(active_op_array)->brk_cont_array[array_offset].parent;
} while (--nest_level > 0);
}
opline = zend_emit_op(NULL, ast->kind == ZEND_AST_BREAK ? ZEND_BRK : ZEND_CONT,
NULL, &depth_node);
opline->op1.opline_num = CG(context).current_brk_cont;
opline = zend_emit_op(NULL, ast->kind == ZEND_AST_BREAK ? ZEND_BRK : ZEND_CONT, NULL, NULL);
opline->op1.num = CG(context).current_brk_cont;
opline->op2.num = depth;
}
/* }}} */
@ -3616,7 +3610,7 @@ void zend_compile_while(zend_ast *ast) /* {{{ */
opnum_jmp = zend_emit_jump(0);
zend_begin_loop();
zend_begin_loop(NULL);
opnum_start = get_next_op_number(CG(active_op_array));
zend_compile_stmt(stmt_ast);
@ -3627,7 +3621,7 @@ void zend_compile_while(zend_ast *ast) /* {{{ */
zend_emit_cond_jump(ZEND_JMPNZ, &cond_node, opnum_start);
zend_end_loop(opnum_cond, 0);
zend_end_loop(opnum_cond);
}
/* }}} */
@ -3639,7 +3633,7 @@ void zend_compile_do_while(zend_ast *ast) /* {{{ */
znode cond_node;
uint32_t opnum_start, opnum_cond;
zend_begin_loop();
zend_begin_loop(NULL);
opnum_start = get_next_op_number(CG(active_op_array));
zend_compile_stmt(stmt_ast);
@ -3649,7 +3643,7 @@ void zend_compile_do_while(zend_ast *ast) /* {{{ */
zend_emit_cond_jump(ZEND_JMPNZ, &cond_node, opnum_start);
zend_end_loop(opnum_cond, 0);
zend_end_loop(opnum_cond);
}
/* }}} */
@ -3690,7 +3684,7 @@ void zend_compile_for(zend_ast *ast) /* {{{ */
opnum_jmp = zend_emit_jump(0);
zend_begin_loop();
zend_begin_loop(NULL);
opnum_start = get_next_op_number(CG(active_op_array));
zend_compile_stmt(stmt_ast);
@ -3705,7 +3699,7 @@ void zend_compile_for(zend_ast *ast) /* {{{ */
zend_emit_cond_jump(ZEND_JMPNZ, &result, opnum_start);
zend_end_loop(opnum_loop, 0);
zend_end_loop(opnum_loop);
}
/* }}} */
@ -3749,9 +3743,6 @@ void zend_compile_foreach(zend_ast *ast) /* {{{ */
opnum_reset = get_next_op_number(CG(active_op_array));
opline = zend_emit_op(&reset_node, by_ref ? ZEND_FE_RESET_RW : ZEND_FE_RESET_R, &expr_node, NULL);
reset_node.flag = 1; /* generate FE_FREE */
zend_stack_push(&CG(loop_var_stack), &reset_node);
opnum_fetch = get_next_op_number(CG(active_op_array));
opline = zend_emit_op(NULL, by_ref ? ZEND_FE_FETCH_RW : ZEND_FE_FETCH_R, &reset_node, NULL);
@ -3775,7 +3766,8 @@ void zend_compile_foreach(zend_ast *ast) /* {{{ */
zend_emit_assign_znode(key_ast, &key_node);
}
zend_begin_loop();
reset_node.flag = 1; /* generate FE_FREE */
zend_begin_loop(&reset_node);
zend_compile_stmt(stmt_ast);
@ -3787,10 +3779,9 @@ void zend_compile_foreach(zend_ast *ast) /* {{{ */
opline = &CG(active_op_array)->opcodes[opnum_fetch];
opline->extended_value = get_next_op_number(CG(active_op_array));
zend_end_loop(opnum_fetch, 1);
zend_end_loop(opnum_fetch);
generate_free_loop_var(&reset_node);
zend_stack_del_top(&CG(loop_var_stack));
}
/* }}} */
@ -3851,10 +3842,8 @@ void zend_compile_switch(zend_ast *ast) /* {{{ */
zend_compile_expr(&expr_node, expr_ast);
expr_node.flag = 0;
zend_stack_push(&CG(loop_var_stack), &expr_node);
zend_begin_loop();
expr_node.flag = 0; /* Generate normal FREE */
zend_begin_loop(&expr_node);
case_node.op_type = IS_TMP_VAR;
case_node.u.op.var = get_temporary_variable(CG(active_op_array));
@ -3913,16 +3902,14 @@ void zend_compile_switch(zend_ast *ast) /* {{{ */
zend_update_jump_target_to_next(opnum_default_jmp);
}
zend_end_loop(get_next_op_number(CG(active_op_array)), 1);
zend_end_loop(get_next_op_number(CG(active_op_array)));
if (expr_node.op_type == IS_VAR || expr_node.op_type == IS_TMP_VAR) {
zend_emit_op(NULL, ZEND_FREE,
&expr_node, NULL);
zend_emit_op(NULL, ZEND_FREE, &expr_node, NULL);
} else if (expr_node.op_type == IS_CONST) {
zval_dtor(&expr_node.u.constant);
}
zend_stack_del_top(&CG(loop_var_stack));
efree(jmpnz_opnums);
}
/* }}} */
@ -4194,6 +4181,35 @@ ZEND_API void zend_set_function_arg_flags(zend_function *func) /* {{{ */
}
/* }}} */
static void zend_compile_typename(zend_ast *ast, zend_arg_info *arg_info) /* {{{ */
{
if (ast->kind == ZEND_AST_TYPE) {
arg_info->type_hint = ast->attr;
} else {
zend_string *class_name = zend_ast_get_str(ast);
zend_uchar type = zend_lookup_builtin_type_by_name(class_name);
if (type != 0) {
arg_info->type_hint = type;
} else {
uint32_t fetch_type = zend_get_class_fetch_type_ast(ast);
if (fetch_type == ZEND_FETCH_CLASS_DEFAULT) {
class_name = zend_resolve_class_name_ast(ast);
zend_assert_valid_class_name(class_name);
} else {
zend_ensure_valid_class_fetch_type(fetch_type);
zend_string_addref(class_name);
}
arg_info->type_hint = IS_OBJECT;
arg_info->class_name = class_name;
}
}
}
/* }}} */
void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast) /* {{{ */
{
zend_ast_list *list = zend_ast_get_list(ast);
@ -4211,28 +4227,7 @@ void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast) /* {{{ */
arg_infos->allow_null = 0;
arg_infos->class_name = NULL;
if (return_type_ast->kind == ZEND_AST_TYPE) {
arg_infos->type_hint = return_type_ast->attr;
} else {
zend_string *class_name = zend_ast_get_str(return_type_ast);
zend_uchar type = zend_lookup_scalar_typehint_by_name(class_name);
if (type != 0) {
arg_infos->type_hint = type;
} else {
uint32_t fetch_type = zend_get_class_fetch_type_ast(return_type_ast);
if (fetch_type == ZEND_FETCH_CLASS_DEFAULT) {
class_name = zend_resolve_class_name_ast(return_type_ast);
zend_assert_valid_class_name(class_name);
} else {
zend_ensure_valid_class_fetch_type(fetch_type);
zend_string_addref(class_name);
}
arg_infos->type_hint = IS_OBJECT;
arg_infos->class_name = class_name;
}
}
zend_compile_typename(return_type_ast, arg_infos);
arg_infos++;
op_array->fn_flags |= ZEND_ACC_HAS_RETURN_TYPE;
@ -4323,8 +4318,9 @@ void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast) /* {{{ */
op_array->fn_flags |= ZEND_ACC_HAS_TYPE_HINTS;
arg_info->allow_null = has_null_default;
zend_compile_typename(type_ast, arg_info);
if (type_ast->kind == ZEND_AST_TYPE) {
arg_info->type_hint = type_ast->attr;
if (arg_info->type_hint == IS_ARRAY) {
if (default_ast && !has_null_default
&& Z_TYPE(default_node.u.constant) != IS_ARRAY
@ -4340,32 +4336,13 @@ void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast) /* {{{ */
}
}
} else {
zend_string *class_name = zend_ast_get_str(type_ast);
zend_uchar type;
type = zend_lookup_scalar_typehint_by_name(class_name);
if (type != 0) {
arg_info->type_hint = type;
} else {
uint32_t fetch_type = zend_get_class_fetch_type_ast(type_ast);
if (fetch_type == ZEND_FETCH_CLASS_DEFAULT) {
class_name = zend_resolve_class_name_ast(type_ast);
zend_assert_valid_class_name(class_name);
} else {
zend_ensure_valid_class_fetch_type(fetch_type);
zend_string_addref(class_name);
}
arg_info->type_hint = IS_OBJECT;
arg_info->class_name = class_name;
}
if (default_ast && !has_null_default && !Z_CONSTANT(default_node.u.constant)) {
if (arg_info->class_name) {
zend_error_noreturn(E_COMPILE_ERROR, "Default value for parameters "
"with a class type hint can only be NULL");
} else if (!ZEND_SAME_FAKE_TYPE(arg_info->type_hint, Z_TYPE(default_node.u.constant))) {
zend_error_noreturn(E_COMPILE_ERROR, "Default value for parameters "
"with a %s type hint can only be %s or NULL", class_name->val, class_name->val);
"with a %s type hint can only be %s or NULL", arg_info->class_name->val, arg_info->class_name->val);
}
}
}

View File

@ -183,16 +183,6 @@ typedef struct _zend_try_catch_element {
uint32_t finally_end;
} zend_try_catch_element;
#if SIZEOF_ZEND_LONG == 8
# ifdef _WIN32
# define THIS_HASHVAL 6385726429Ui64
# else
# define THIS_HASHVAL 6385726429ULL
# endif
#else
#define THIS_HASHVAL 2090759133UL
#endif
/* method flags (types) */
#define ZEND_ACC_STATIC 0x01
#define ZEND_ACC_ABSTRACT 0x02
@ -884,8 +874,6 @@ ZEND_API void zend_assert_valid_class_name(const zend_string *const_name);
#define ZEND_FETCH_ARG_MASK 0x000fffff
#define EXT_TYPE_FREE_ON_RETURN (1<<2)
#define ZEND_MEMBER_FUNC_CALL 1<<0
#define ZEND_ARG_SEND_BY_REF (1<<0)
@ -961,6 +949,11 @@ static zend_always_inline int zend_check_arg_send_type(const zend_function *zf,
#define ZEND_ARRAY_NOT_PACKED (1<<1)
#define ZEND_ARRAY_SIZE_SHIFT 2
/* Pseudo-opcodes that are used only temporarily during compilation */
#define ZEND_BRK 254
#define ZEND_CONT 255
END_EXTERN_C()
#define ZEND_CLONE_FUNC_NAME "__clone"

View File

@ -1732,21 +1732,17 @@ static inline zend_brk_cont_element* zend_brk_cont(int nest_levels, int array_of
do {
ZEND_ASSERT(array_offset != -1);
jmp_to = &op_array->brk_cont_array[array_offset];
if (nest_levels>1) {
if (nest_levels > 1 && jmp_to->start >= 0) {
zend_op *brk_opline = &op_array->opcodes[jmp_to->brk];
if (brk_opline->opcode == ZEND_FREE) {
if (!(brk_opline->extended_value & EXT_TYPE_FREE_ON_RETURN)) {
zval_ptr_dtor_nogc(EX_VAR(brk_opline->op1.var));
}
zval_ptr_dtor_nogc(EX_VAR(brk_opline->op1.var));
} else if (brk_opline->opcode == ZEND_FE_FREE) {
if (!(brk_opline->extended_value & EXT_TYPE_FREE_ON_RETURN)) {
zval *var = EX_VAR(brk_opline->op1.var);
if (Z_TYPE_P(var) != IS_ARRAY && Z_FE_ITER_P(var) != (uint32_t)-1) {
zend_hash_iterator_del(Z_FE_ITER_P(var));
}
zval_ptr_dtor_nogc(var);
zval *var = EX_VAR(brk_opline->op1.var);
if (Z_TYPE_P(var) != IS_ARRAY && Z_FE_ITER_P(var) != (uint32_t)-1) {
zend_hash_iterator_del(Z_FE_ITER_P(var));
}
zval_ptr_dtor_nogc(var);
}
}
array_offset = jmp_to->parent;

View File

@ -25,7 +25,7 @@
#include "main/php_stdint.h"
/* This is the heart of the whole int64 enablement in zval. */
#if defined(__X86_64__) || defined(__LP64__) || defined(_LP64) || defined(_WIN64)
#if defined(__x86_64__) || defined(__LP64__) || defined(_LP64) || defined(_WIN64)
# define ZEND_ENABLE_ZVAL_LONG64 1
#endif

View File

@ -666,6 +666,20 @@ static void zend_resolve_finally_ret(zend_op_array *op_array, uint32_t op_num)
}
}
static uint32_t zend_get_brk_cont_target(const zend_op_array *op_array, const zend_op *opline) {
int nest_levels = opline->op2.num;
int array_offset = opline->op1.num;
zend_brk_cont_element *jmp_to;
do {
jmp_to = &op_array->brk_cont_array[array_offset];
if (nest_levels > 1) {
array_offset = jmp_to->parent;
}
} while (--nest_levels > 0);
return opline->opcode == ZEND_BRK ? jmp_to->brk : jmp_to->cont;
}
static void zend_resolve_finally_calls(zend_op_array *op_array)
{
uint32_t i, j;
@ -681,22 +695,8 @@ static void zend_resolve_finally_calls(zend_op_array *op_array)
break;
case ZEND_BRK:
case ZEND_CONT:
{
int nest_levels, array_offset;
zend_brk_cont_element *jmp_to;
nest_levels = Z_LVAL(op_array->literals[opline->op2.constant]);
if ((array_offset = opline->op1.opline_num) != -1) {
do {
jmp_to = &op_array->brk_cont_array[array_offset];
if (nest_levels > 1) {
array_offset = jmp_to->parent;
}
} while (--nest_levels > 0);
zend_resolve_finally_call(op_array, i, opline->opcode == ZEND_BRK ? jmp_to->brk : jmp_to->cont);
break;
}
}
zend_resolve_finally_call(op_array, i, zend_get_brk_cont_target(op_array, opline));
break;
case ZEND_GOTO:
if (Z_TYPE_P(CT_CONSTANT_EX(op_array, opline->op2.constant)) != IS_LONG) {
uint32_t num = opline->op2.constant;
@ -774,6 +774,16 @@ ZEND_API int pass_two(zend_op_array *op_array)
case ZEND_DECLARE_INHERITED_CLASS_DELAYED:
opline->extended_value = (uint32_t)(zend_intptr_t)ZEND_CALL_VAR_NUM(NULL, op_array->last_var + opline->extended_value);
break;
case ZEND_BRK:
case ZEND_CONT:
{
uint32_t jmp_target = zend_get_brk_cont_target(op_array, opline);
opline->opcode = ZEND_JMP;
opline->op1.opline_num = jmp_target;
opline->op2.num = 0;
ZEND_PASS_TWO_UPDATE_JMP_TARGET(op_array, opline, opline->op1);
}
break;
case ZEND_GOTO:
if (Z_TYPE_P(RT_CONSTANT(op_array, opline->op2)) != IS_LONG) {
zend_resolve_goto_label(op_array, opline, 1);

View File

@ -802,7 +802,7 @@ static zend_always_inline uint32_t zval_delref_p(zval* pz) {
return --GC_REFCOUNT(Z_COUNTED_P(pz));
}
#if SIZEOF_ZEND_LONG == 4
#if SIZEOF_SIZE_T == 4
# define ZVAL_COPY_VALUE_EX(z, v, gc, t) \
do { \
uint32_t _w2 = v->value.ww.w2; \
@ -810,14 +810,14 @@ static zend_always_inline uint32_t zval_delref_p(zval* pz) {
z->value.ww.w2 = _w2; \
Z_TYPE_INFO_P(z) = t; \
} while (0)
#elif SIZEOF_ZEND_LONG == 8
#elif SIZEOF_SIZE_T == 8
# define ZVAL_COPY_VALUE_EX(z, v, gc, t) \
do { \
Z_COUNTED_P(z) = gc; \
Z_TYPE_INFO_P(z) = t; \
} while (0)
#else
# error "Unknbown SIZEOF_ZEND_LONG"
# error "Unknown SIZEOF_SIZE_T"
#endif
#define ZVAL_COPY_VALUE(z, v) \

View File

@ -4816,31 +4816,8 @@ ZEND_VM_HANDLER(52, ZEND_BOOL, CONST|TMPVAR|CV, ANY)
ZEND_VM_NEXT_OPCODE();
}
ZEND_VM_HANDLER(50, ZEND_BRK, ANY, CONST)
{
USE_OPLINE
zend_brk_cont_element *el;
SAVE_OPLINE();
el = zend_brk_cont(Z_LVAL_P(EX_CONSTANT(opline->op2)), opline->op1.opline_num,
&EX(func)->op_array, execute_data);
ZEND_VM_JMP(EX(func)->op_array.opcodes + el->brk);
}
ZEND_VM_HANDLER(51, ZEND_CONT, ANY, CONST)
{
USE_OPLINE
zend_brk_cont_element *el;
SAVE_OPLINE();
el = zend_brk_cont(Z_LVAL_P(EX_CONSTANT(opline->op2)), opline->op1.opline_num,
&EX(func)->op_array, execute_data);
ZEND_VM_JMP(EX(func)->op_array.opcodes + el->cont);
}
ZEND_VM_HANDLER(100, ZEND_GOTO, ANY, CONST)
{
zend_op *brk_opline;
USE_OPLINE
zend_brk_cont_element *el;
@ -4848,14 +4825,12 @@ ZEND_VM_HANDLER(100, ZEND_GOTO, ANY, CONST)
el = zend_brk_cont(Z_LVAL_P(EX_CONSTANT(opline->op2)), opline->extended_value,
&EX(func)->op_array, execute_data);
brk_opline = EX(func)->op_array.opcodes + el->brk;
if (el->start >= 0) {
zend_op *brk_opline = EX(func)->op_array.opcodes + el->brk;
if (brk_opline->opcode == ZEND_FREE) {
if (!(brk_opline->extended_value & EXT_TYPE_FREE_ON_RETURN)) {
if (brk_opline->opcode == ZEND_FREE) {
zval_ptr_dtor_nogc(EX_VAR(brk_opline->op1.var));
}
} else if (brk_opline->opcode == ZEND_FE_FREE) {
if (!(brk_opline->extended_value & EXT_TYPE_FREE_ON_RETURN)) {
} else if (brk_opline->opcode == ZEND_FE_FREE) {
zval *var = EX_VAR(brk_opline->op1.var);
if (Z_TYPE_P(var) != IS_ARRAY && Z_FE_ITER_P(var) != (uint32_t)-1) {
zend_hash_iterator_del(Z_FE_ITER_P(var));
@ -7264,17 +7239,13 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY)
zend_op *brk_opline = &EX(func)->op_array.opcodes[EX(func)->op_array.brk_cont_array[i].brk];
if (brk_opline->opcode == ZEND_FREE) {
if (!(brk_opline->extended_value & EXT_TYPE_FREE_ON_RETURN)) {
zval_ptr_dtor_nogc(EX_VAR(brk_opline->op1.var));
}
zval_ptr_dtor_nogc(EX_VAR(brk_opline->op1.var));
} else if (brk_opline->opcode == ZEND_FE_FREE) {
if (!(brk_opline->extended_value & EXT_TYPE_FREE_ON_RETURN)) {
zval *var = EX_VAR(brk_opline->op1.var);
if (Z_TYPE_P(var) != IS_ARRAY && Z_FE_ITER_P(var) != (uint32_t)-1) {
zend_hash_iterator_del(Z_FE_ITER_P(var));
}
zval_ptr_dtor_nogc(var);
zval *var = EX_VAR(brk_opline->op1.var);
if (Z_TYPE_P(var) != IS_ARRAY && Z_FE_ITER_P(var) != (uint32_t)-1) {
zend_hash_iterator_del(Z_FE_ITER_P(var));
}
zval_ptr_dtor_nogc(var);
} else if (brk_opline->opcode == ZEND_END_SILENCE) {
/* restore previous error_reporting value */
if (!EG(error_reporting) && Z_LVAL_P(EX_VAR(brk_opline->op1.var)) != 0) {

View File

@ -1615,17 +1615,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_HANDLE_EXCEPTION_SPEC_HANDLER(
zend_op *brk_opline = &EX(func)->op_array.opcodes[EX(func)->op_array.brk_cont_array[i].brk];
if (brk_opline->opcode == ZEND_FREE) {
if (!(brk_opline->extended_value & EXT_TYPE_FREE_ON_RETURN)) {
zval_ptr_dtor_nogc(EX_VAR(brk_opline->op1.var));
}
zval_ptr_dtor_nogc(EX_VAR(brk_opline->op1.var));
} else if (brk_opline->opcode == ZEND_FE_FREE) {
if (!(brk_opline->extended_value & EXT_TYPE_FREE_ON_RETURN)) {
zval *var = EX_VAR(brk_opline->op1.var);
if (Z_TYPE_P(var) != IS_ARRAY && Z_FE_ITER_P(var) != (uint32_t)-1) {
zend_hash_iterator_del(Z_FE_ITER_P(var));
}
zval_ptr_dtor_nogc(var);
zval *var = EX_VAR(brk_opline->op1.var);
if (Z_TYPE_P(var) != IS_ARRAY && Z_FE_ITER_P(var) != (uint32_t)-1) {
zend_hash_iterator_del(Z_FE_ITER_P(var));
}
zval_ptr_dtor_nogc(var);
} else if (brk_opline->opcode == ZEND_END_SILENCE) {
/* restore previous error_reporting value */
if (!EG(error_reporting) && Z_LVAL_P(EX_VAR(brk_opline->op1.var)) != 0) {
@ -2352,31 +2348,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RECV_INIT_SPEC_CONST_HANDLER(Z
ZEND_VM_NEXT_OPCODE();
}
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BRK_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
zend_brk_cont_element *el;
SAVE_OPLINE();
el = zend_brk_cont(Z_LVAL_P(EX_CONSTANT(opline->op2)), opline->op1.opline_num,
&EX(func)->op_array, execute_data);
ZEND_VM_JMP(EX(func)->op_array.opcodes + el->brk);
}
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONT_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
zend_brk_cont_element *el;
SAVE_OPLINE();
el = zend_brk_cont(Z_LVAL_P(EX_CONSTANT(opline->op2)), opline->op1.opline_num,
&EX(func)->op_array, execute_data);
ZEND_VM_JMP(EX(func)->op_array.opcodes + el->cont);
}
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_GOTO_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
zend_op *brk_opline;
USE_OPLINE
zend_brk_cont_element *el;
@ -2384,14 +2357,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_GOTO_SPEC_CONST_HANDLER(ZEND_O
el = zend_brk_cont(Z_LVAL_P(EX_CONSTANT(opline->op2)), opline->extended_value,
&EX(func)->op_array, execute_data);
brk_opline = EX(func)->op_array.opcodes + el->brk;
if (el->start >= 0) {
zend_op *brk_opline = EX(func)->op_array.opcodes + el->brk;
if (brk_opline->opcode == ZEND_FREE) {
if (!(brk_opline->extended_value & EXT_TYPE_FREE_ON_RETURN)) {
if (brk_opline->opcode == ZEND_FREE) {
zval_ptr_dtor_nogc(EX_VAR(brk_opline->op1.var));
}
} else if (brk_opline->opcode == ZEND_FE_FREE) {
if (!(brk_opline->extended_value & EXT_TYPE_FREE_ON_RETURN)) {
} else if (brk_opline->opcode == ZEND_FE_FREE) {
zval *var = EX_VAR(brk_opline->op1.var);
if (Z_TYPE_P(var) != IS_ARRAY && Z_FE_ITER_P(var) != (uint32_t)-1) {
zend_hash_iterator_del(Z_FE_ITER_P(var));
@ -46685,52 +46656,52 @@ void zend_init_opcodes_handlers(void)
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_BRK_SPEC_CONST_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_BRK_SPEC_CONST_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_BRK_SPEC_CONST_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_BRK_SPEC_CONST_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_BRK_SPEC_CONST_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_CONT_SPEC_CONST_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_CONT_SPEC_CONST_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_CONT_SPEC_CONST_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_CONT_SPEC_CONST_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_CONT_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_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,

View File

@ -72,8 +72,8 @@ const char *zend_vm_opcodes_map[173] = {
"ZEND_JMPNZ_EX",
"ZEND_CASE",
NULL,
"ZEND_BRK",
"ZEND_CONT",
NULL,
NULL,
"ZEND_BOOL",
"ZEND_FAST_CONCAT",
"ZEND_ROPE_INIT",

View File

@ -82,8 +82,6 @@ END_EXTERN_C()
#define ZEND_JMPZ_EX 46
#define ZEND_JMPNZ_EX 47
#define ZEND_CASE 48
#define ZEND_BRK 50
#define ZEND_CONT 51
#define ZEND_BOOL 52
#define ZEND_FAST_CONCAT 53
#define ZEND_ROPE_INIT 54

View File

@ -121,7 +121,7 @@ typedef unsigned __int64 uint64_t;
#include <strings.h>
#endif
#if defined(__X86_64__) || defined(__LP64__) || defined(_LP64) || defined(_WIN64)
#if defined(__x86_64__) || defined(__LP64__) || defined(_LP64) || defined(_WIN64)
typedef int64_t timelib_long;
typedef uint64_t timelib_ulong;
# define TIMELIB_LONG_MAX INT64_MAX

View File

@ -123,12 +123,9 @@ static int find_code_blocks(zend_op_array *op_array, zend_cfg *cfg, zend_optimiz
blocks[0].start_opline_no = 0;
while (opline < end) {
switch((unsigned)opline->opcode) {
case ZEND_BRK:
case ZEND_CONT:
case ZEND_GOTO:
/* would not optimize non-optimized BRK/CONTs - we cannot
really know where it jumps, so these optimizations are
too dangerous */
/* would not optimize GOTOs - we cannot really know where it jumps,
* so these optimizations are too dangerous */
return 0;
case ZEND_FAST_CALL:
START_BLOCK_OP(ZEND_OP1(opline).opline_num);

View File

@ -613,8 +613,6 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx)
case ZEND_EXIT:
case ZEND_THROW:
case ZEND_CATCH:
case ZEND_BRK:
case ZEND_CONT:
case ZEND_GOTO:
case ZEND_FAST_CALL:
case ZEND_FAST_RET:

View File

@ -181,59 +181,6 @@ void zend_optimizer_pass2(zend_op_array *op_array)
opline->opcode = ZEND_JMP;
}
break;
case ZEND_BRK:
case ZEND_CONT:
{
zend_brk_cont_element *jmp_to;
int array_offset;
int nest_levels;
int dont_optimize = 0;
ZEND_ASSERT(ZEND_OP2_TYPE(opline) == IS_CONST);
ZEND_ASSERT(Z_TYPE(ZEND_OP2_LITERAL(opline)) == IS_LONG);
nest_levels = Z_LVAL(ZEND_OP2_LITERAL(opline));
array_offset = ZEND_OP1(opline).opline_num;
while (1) {
if (array_offset == -1) {
dont_optimize = 1; /* don't optimize this bogus break/continue, let the executor shout */
break;
}
jmp_to = &op_array->brk_cont_array[array_offset];
array_offset = jmp_to->parent;
if (--nest_levels > 0) {
if (op_array->opcodes[jmp_to->brk].opcode == ZEND_FREE ||
op_array->opcodes[jmp_to->brk].opcode == ZEND_FE_FREE ||
op_array->opcodes[jmp_to->brk].opcode == ZEND_END_SILENCE) {
dont_optimize = 1;
break;
}
} else {
break;
}
}
if (dont_optimize) {
break;
}
/* optimize - convert to a JMP */
switch (opline->opcode) {
case ZEND_BRK:
MAKE_NOP(opline);
ZEND_OP1(opline).opline_num = jmp_to->brk;
break;
case ZEND_CONT:
MAKE_NOP(opline);
ZEND_OP1(opline).opline_num = jmp_to->cont;
break;
}
opline->opcode = ZEND_JMP;
/* MAKE_NOP() already set op1 and op2 to IS_UNUSED */
}
break;
}
opline++;
}

View File

@ -322,8 +322,6 @@ continue_jmp_ex_optimization:
op->opcode == ZEND_JMPNZ ||
op->opcode == ZEND_JMPNZ_EX ||
op->opcode == ZEND_JMPZNZ ||
op->opcode == ZEND_BRK ||
op->opcode == ZEND_CONT ||
op->opcode == ZEND_CASE ||
op->opcode == ZEND_RETURN ||
op->opcode == ZEND_RETURN_BY_REF ||
@ -358,8 +356,6 @@ continue_jmp_ex_optimization:
op->opcode == ZEND_JMPNZ ||
op->opcode == ZEND_JMPNZ_EX ||
op->opcode == ZEND_JMPZNZ ||
op->opcode == ZEND_BRK ||
op->opcode == ZEND_CONT ||
op->opcode == ZEND_CASE ||
op->opcode == ZEND_RETURN ||
op->opcode == ZEND_RETURN_BY_REF ||

View File

@ -5253,7 +5253,7 @@ PHP_FUNCTION(openssl_encrypt)
/* }}} */
/* {{{ proto string openssl_decrypt(string data, string method, string password [, long options=0 [, string $iv = '']])
Takes raw or base64 encoded string and dectupt it using given method and key */
Takes raw or base64 encoded string and decrypts it using given method and key */
PHP_FUNCTION(openssl_decrypt)
{
zend_long options = 0;

View File

@ -522,7 +522,7 @@ PHP_FUNCTION(file_get_contents)
zend_bool use_include_path = 0;
php_stream *stream;
zend_long offset = -1;
zend_long maxlen = PHP_STREAM_COPY_ALL;
zend_long maxlen = (ssize_t) PHP_STREAM_COPY_ALL;
zval *zcontext = NULL;
php_stream_context *context = NULL;
zend_string *contents;

View File

@ -397,7 +397,7 @@ PHP_FUNCTION(stream_get_contents)
{
php_stream *stream;
zval *zsrc;
zend_long maxlen = PHP_STREAM_COPY_ALL,
zend_long maxlen = (ssize_t) PHP_STREAM_COPY_ALL,
desiredpos = -1L;
zend_string *contents;

View File

@ -312,6 +312,11 @@ static inline int add_post_vars(zval *arr, post_var_data_t *vars, zend_bool eof)
return SUCCESS;
}
#ifdef PHP_WIN32
#define SAPI_POST_HANDLER_BUFSIZ 16384
#else
# define SAPI_POST_HANDLER_BUFSIZ BUFSIZ
#endif
SAPI_API SAPI_POST_HANDLER_FUNC(php_std_post_handler)
{
zval *arr = (zval *) arg;
@ -322,8 +327,8 @@ SAPI_API SAPI_POST_HANDLER_FUNC(php_std_post_handler)
memset(&post_data, 0, sizeof(post_data));
while (!php_stream_eof(s)) {
char buf[BUFSIZ] = {0};
size_t len = php_stream_read(s, buf, BUFSIZ);
char buf[SAPI_POST_HANDLER_BUFSIZ] = {0};
size_t len = php_stream_read(s, buf, SAPI_POST_HANDLER_BUFSIZ);
if (len && len != (size_t) -1) {
smart_str_appendl(&post_data.str, buf, len);
@ -334,7 +339,7 @@ SAPI_API SAPI_POST_HANDLER_FUNC(php_std_post_handler)
}
}
if (len != BUFSIZ){
if (len != SAPI_POST_HANDLER_BUFSIZ){
break;
}
}
@ -345,6 +350,7 @@ SAPI_API SAPI_POST_HANDLER_FUNC(php_std_post_handler)
}
}
}
#undef SAPI_POST_HANDLER_BUFSIZ
SAPI_API SAPI_INPUT_FILTER_FUNC(php_default_input_filter)
{