version 1.1, 2012/02/21 23:47:52
|
version 1.1.1.4, 2014/06/15 20:04:03
|
Line 2
|
Line 2
|
+----------------------------------------------------------------------+ |
+----------------------------------------------------------------------+ |
| Zend Engine | |
| Zend Engine | |
+----------------------------------------------------------------------+ |
+----------------------------------------------------------------------+ |
| Copyright (c) 1998-2012 Zend Technologies Ltd. (http://www.zend.com) | | | Copyright (c) 1998-2014 Zend Technologies Ltd. (http://www.zend.com) | |
+----------------------------------------------------------------------+ |
+----------------------------------------------------------------------+ |
| This source file is subject to version 2.00 of the Zend license, | |
| This source file is subject to version 2.00 of the Zend license, | |
| that is bundled with this package in the file LICENSE, and is | |
| that is bundled with this package in the file LICENSE, and is | |
Line 36
|
Line 36
|
#include "zend_interfaces.h" |
#include "zend_interfaces.h" |
#include "zend_closures.h" |
#include "zend_closures.h" |
#include "zend_vm.h" |
#include "zend_vm.h" |
|
#include "zend_dtrace.h" |
|
|
/* Virtual current working directory support */ |
/* Virtual current working directory support */ |
#include "tsrm_virtual_cwd.h" |
#include "tsrm_virtual_cwd.h" |
Line 48
|
Line 49
|
|
|
typedef int (*incdec_t)(zval *); |
typedef int (*incdec_t)(zval *); |
|
|
#define get_zval_ptr(node, Ts, should_free, type) _get_zval_ptr(node, Ts, should_free, type TSRMLS_CC) | #define get_zval_ptr(op_type, node, Ts, should_free, type) _get_zval_ptr(op_type, node, Ts, should_free, type TSRMLS_CC) |
#define get_zval_ptr_ptr(node, Ts, should_free, type) _get_zval_ptr_ptr(node, Ts, should_free, type TSRMLS_CC) | #define get_zval_ptr_ptr(op_type, node, Ts, should_free, type) _get_zval_ptr_ptr(op_type, node, Ts, should_free, type TSRMLS_CC) |
#define get_obj_zval_ptr(node, Ts, should_free, type) _get_obj_zval_ptr(node, Ts, should_free, type TSRMLS_CC) | #define get_obj_zval_ptr(op_type, node, Ts, should_free, type) _get_obj_zval_ptr(op_type, node, Ts, should_free, type TSRMLS_CC) |
#define get_obj_zval_ptr_ptr(node, Ts, should_free, type) _get_obj_zval_ptr_ptr(node, Ts, should_free, type TSRMLS_CC) | #define get_obj_zval_ptr_ptr(op_type, node, Ts, should_free, type) _get_obj_zval_ptr_ptr(op_type, node, Ts, should_free, type TSRMLS_CC) |
|
|
/* Prototypes */ |
/* Prototypes */ |
static void zend_extension_statement_handler(const zend_extension *extension, zend_op_array *op_array TSRMLS_DC); |
static void zend_extension_statement_handler(const zend_extension *extension, zend_op_array *op_array TSRMLS_DC); |
static void zend_extension_fcall_begin_handler(const zend_extension *extension, zend_op_array *op_array TSRMLS_DC); |
static void zend_extension_fcall_begin_handler(const zend_extension *extension, zend_op_array *op_array TSRMLS_DC); |
static void zend_extension_fcall_end_handler(const zend_extension *extension, zend_op_array *op_array TSRMLS_DC); |
static void zend_extension_fcall_end_handler(const zend_extension *extension, zend_op_array *op_array TSRMLS_DC); |
|
|
#define RETURN_VALUE_USED(opline) (!((opline)->result.u.EA.type & EXT_TYPE_UNUSED)) | #define RETURN_VALUE_USED(opline) (!((opline)->result_type & EXT_TYPE_UNUSED)) |
|
|
#define EX_T(offset) (*(temp_variable *)((char *) EX(Ts) + offset)) |
|
#define T(offset) (*(temp_variable *)((char *) Ts + offset)) |
#define T(offset) (*(temp_variable *)((char *) Ts + offset)) |
|
#define CV(var) CVs[var] |
|
|
#define TEMP_VAR_STACK_LIMIT 2000 |
#define TEMP_VAR_STACK_LIMIT 2000 |
|
|
Line 92 static zend_always_inline void zend_pzval_unlock_free_
|
Line 93 static zend_always_inline void zend_pzval_unlock_free_
|
} |
} |
} |
} |
|
|
|
#undef zval_ptr_dtor |
|
#define zval_ptr_dtor(pzv) i_zval_ptr_dtor(*(pzv) ZEND_FILE_LINE_CC) |
|
|
#define PZVAL_UNLOCK(z, f) zend_pzval_unlock_func(z, f, 1 TSRMLS_CC) |
#define PZVAL_UNLOCK(z, f) zend_pzval_unlock_func(z, f, 1 TSRMLS_CC) |
#define PZVAL_UNLOCK_EX(z, f, u) zend_pzval_unlock_func(z, f, u TSRMLS_CC) |
#define PZVAL_UNLOCK_EX(z, f, u) zend_pzval_unlock_func(z, f, u TSRMLS_CC) |
#define PZVAL_UNLOCK_FREE(z) zend_pzval_unlock_free_func(z TSRMLS_CC) |
#define PZVAL_UNLOCK_FREE(z) zend_pzval_unlock_free_func(z TSRMLS_CC) |
#define PZVAL_LOCK(z) Z_ADDREF_P((z)) |
#define PZVAL_LOCK(z) Z_ADDREF_P((z)) |
#define RETURN_VALUE_UNUSED(pzn) (((pzn)->u.EA.type & EXT_TYPE_UNUSED)) | #define SELECTIVE_PZVAL_LOCK(pzv, opline) if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(pzv); } |
#define SELECTIVE_PZVAL_LOCK(pzv, pzn) if (!RETURN_VALUE_UNUSED(pzn)) { PZVAL_LOCK(pzv); } | |
|
|
#define AI_USE_PTR(ai) \ | #define EXTRACT_ZVAL_PTR(t) do { \ |
if ((ai).ptr_ptr) { \ | temp_variable *__t = (t); \ |
(ai).ptr = *((ai).ptr_ptr); \ | if (__t->var.ptr_ptr) { \ |
(ai).ptr_ptr = &((ai).ptr); \ | __t->var.ptr = *__t->var.ptr_ptr; \ |
} else { \ | __t->var.ptr_ptr = &__t->var.ptr; \ |
(ai).ptr = NULL; \ | if (!PZVAL_IS_REF(__t->var.ptr) && \ |
} | Z_REFCOUNT_P(__t->var.ptr) > 2) { \ |
| SEPARATE_ZVAL(__t->var.ptr_ptr); \ |
| } \ |
| } \ |
| } while (0) |
|
|
#define AI_SET_PTR(ai, val) \ | #define AI_SET_PTR(t, val) do { \ |
(ai).ptr = (val); \ | temp_variable *__t = (t); \ |
(ai).ptr_ptr = &((ai).ptr); | __t->var.ptr = (val); \ |
| __t->var.ptr_ptr = &__t->var.ptr; \ |
| } while (0) |
|
|
#define FREE_OP(should_free) \ |
#define FREE_OP(should_free) \ |
if (should_free.var) { \ |
if (should_free.var) { \ |
Line 134 static zend_always_inline void zend_pzval_unlock_free_
|
Line 143 static zend_always_inline void zend_pzval_unlock_free_
|
|
|
#define IS_TMP_FREE(should_free) ((zend_uintptr_t)should_free.var & 1L) |
#define IS_TMP_FREE(should_free) ((zend_uintptr_t)should_free.var & 1L) |
|
|
#define INIT_PZVAL_COPY(z,v) \ |
|
(z)->value = (v)->value; \ |
|
Z_TYPE_P(z) = Z_TYPE_P(v); \ |
|
Z_SET_REFCOUNT_P(z, 1); \ |
|
Z_UNSET_ISREF_P(z); |
|
|
|
#define MAKE_REAL_ZVAL_PTR(val) \ |
#define MAKE_REAL_ZVAL_PTR(val) \ |
do { \ |
do { \ |
zval *_tmp; \ |
zval *_tmp; \ |
ALLOC_ZVAL(_tmp); \ |
ALLOC_ZVAL(_tmp); \ |
_tmp->value = (val)->value; \ | INIT_PZVAL_COPY(_tmp, (val)); \ |
Z_TYPE_P(_tmp) = Z_TYPE_P(val); \ | (val) = _tmp; \ |
Z_SET_REFCOUNT_P(_tmp, 1); \ | |
Z_UNSET_ISREF_P(_tmp); \ | |
val = _tmp; \ | |
} while (0) |
} while (0) |
|
|
/* End of zend_execute_locks.h */ |
/* End of zend_execute_locks.h */ |
Line 172 ZEND_API zval** zend_get_compiled_variable_value(const
|
Line 172 ZEND_API zval** zend_get_compiled_variable_value(const
|
return execute_data_ptr->CVs[var]; |
return execute_data_ptr->CVs[var]; |
} |
} |
|
|
static zend_always_inline zval *_get_zval_ptr_tmp(const znode *node, const temp_variable *Ts, zend_free_op *should_free TSRMLS_DC) | static zend_always_inline zval *_get_zval_ptr_tmp(zend_uint var, const temp_variable *Ts, zend_free_op *should_free TSRMLS_DC) |
{ |
{ |
return should_free->var = &T(node->u.var).tmp_var; | return should_free->var = &T(var).tmp_var; |
} |
} |
|
|
static zval *_get_zval_ptr_var_string_offset(const znode *node, const temp_variable *Ts, zend_free_op *should_free TSRMLS_DC) | static zend_always_inline zval *_get_zval_ptr_var(zend_uint var, const temp_variable *Ts, zend_free_op *should_free TSRMLS_DC) |
{ |
{ |
temp_variable *T = &T(node->u.var); | zval *ptr = T(var).var.ptr; |
zval *str = T->str_offset.str; | |
zval *ptr; | |
|
|
/* string offset */ | PZVAL_UNLOCK(ptr, should_free); |
ALLOC_ZVAL(ptr); | |
T->str_offset.ptr = ptr; | |
should_free->var = ptr; | |
| |
if (T->str_offset.str->type != IS_STRING | |
|| ((int)T->str_offset.offset < 0) | |
|| (T->str_offset.str->value.str.len <= (int)T->str_offset.offset)) { | |
ptr->value.str.val = STR_EMPTY_ALLOC(); | |
ptr->value.str.len = 0; | |
} else { | |
ptr->value.str.val = estrndup(str->value.str.val + T->str_offset.offset, 1); | |
ptr->value.str.len = 1; | |
} | |
PZVAL_UNLOCK_FREE(str); | |
Z_SET_REFCOUNT_P(ptr, 1); | |
Z_SET_ISREF_P(ptr); | |
ptr->type = IS_STRING; | |
return ptr; |
return ptr; |
} |
} |
|
|
static zend_always_inline zval *_get_zval_ptr_var(const znode *node, const temp_variable *Ts, zend_free_op *should_free TSRMLS_DC) | static zend_never_inline zval **_get_zval_cv_lookup(zval ***ptr, zend_uint var, int type TSRMLS_DC) |
{ |
{ |
zval *ptr = T(node->u.var).var.ptr; |
|
if (EXPECTED(ptr != NULL)) { |
|
PZVAL_UNLOCK(ptr, should_free); |
|
return ptr; |
|
} else { |
|
return _get_zval_ptr_var_string_offset(node, Ts, should_free TSRMLS_CC); |
|
} |
|
} |
|
|
|
static zval **_get_zval_cv_lookup(zval ***ptr, zend_uint var, int type TSRMLS_DC) |
|
{ |
|
zend_compiled_variable *cv = &CV_DEF_OF(var); |
zend_compiled_variable *cv = &CV_DEF_OF(var); |
|
|
if (!EG(active_symbol_table) || |
if (!EG(active_symbol_table) || |
Line 246 static zval **_get_zval_cv_lookup(zval ***ptr, zend_ui
|
Line 216 static zval **_get_zval_cv_lookup(zval ***ptr, zend_ui
|
return *ptr; |
return *ptr; |
} |
} |
|
|
static zend_always_inline zval *_get_zval_ptr_cv(const znode *node, const temp_variable *Ts, int type TSRMLS_DC) | static zend_never_inline zval **_get_zval_cv_lookup_BP_VAR_R(zval ***ptr, zend_uint var TSRMLS_DC) |
{ |
{ |
zval ***ptr = &CV_OF(node->u.var); | zend_compiled_variable *cv = &CV_DEF_OF(var); |
|
|
|
if (!EG(active_symbol_table) || |
|
zend_hash_quick_find(EG(active_symbol_table), cv->name, cv->name_len+1, cv->hash_value, (void **)ptr)==FAILURE) { |
|
zend_error(E_NOTICE, "Undefined variable: %s", cv->name); |
|
return &EG(uninitialized_zval_ptr); |
|
} |
|
return *ptr; |
|
} |
|
|
|
static zend_never_inline zval **_get_zval_cv_lookup_BP_VAR_UNSET(zval ***ptr, zend_uint var TSRMLS_DC) |
|
{ |
|
zend_compiled_variable *cv = &CV_DEF_OF(var); |
|
|
|
if (!EG(active_symbol_table) || |
|
zend_hash_quick_find(EG(active_symbol_table), cv->name, cv->name_len+1, cv->hash_value, (void **)ptr)==FAILURE) { |
|
zend_error(E_NOTICE, "Undefined variable: %s", cv->name); |
|
return &EG(uninitialized_zval_ptr); |
|
} |
|
return *ptr; |
|
} |
|
|
|
static zend_never_inline zval **_get_zval_cv_lookup_BP_VAR_IS(zval ***ptr, zend_uint var TSRMLS_DC) |
|
{ |
|
zend_compiled_variable *cv = &CV_DEF_OF(var); |
|
|
|
if (!EG(active_symbol_table) || |
|
zend_hash_quick_find(EG(active_symbol_table), cv->name, cv->name_len+1, cv->hash_value, (void **)ptr)==FAILURE) { |
|
return &EG(uninitialized_zval_ptr); |
|
} |
|
return *ptr; |
|
} |
|
|
|
static zend_never_inline zval **_get_zval_cv_lookup_BP_VAR_RW(zval ***ptr, zend_uint var TSRMLS_DC) |
|
{ |
|
zend_compiled_variable *cv = &CV_DEF_OF(var); |
|
|
|
if (!EG(active_symbol_table)) { |
|
Z_ADDREF(EG(uninitialized_zval)); |
|
*ptr = (zval**)EG(current_execute_data)->CVs + (EG(active_op_array)->last_var + var); |
|
**ptr = &EG(uninitialized_zval); |
|
zend_error(E_NOTICE, "Undefined variable: %s", cv->name); |
|
} else if (zend_hash_quick_find(EG(active_symbol_table), cv->name, cv->name_len+1, cv->hash_value, (void **)ptr)==FAILURE) { |
|
Z_ADDREF(EG(uninitialized_zval)); |
|
zend_hash_quick_update(EG(active_symbol_table), cv->name, cv->name_len+1, cv->hash_value, &EG(uninitialized_zval_ptr), sizeof(zval *), (void **)ptr); |
|
zend_error(E_NOTICE, "Undefined variable: %s", cv->name); |
|
} |
|
return *ptr; |
|
} |
|
|
|
static zend_never_inline zval **_get_zval_cv_lookup_BP_VAR_W(zval ***ptr, zend_uint var TSRMLS_DC) |
|
{ |
|
zend_compiled_variable *cv = &CV_DEF_OF(var); |
|
|
|
if (!EG(active_symbol_table)) { |
|
Z_ADDREF(EG(uninitialized_zval)); |
|
*ptr = (zval**)EG(current_execute_data)->CVs + (EG(active_op_array)->last_var + var); |
|
**ptr = &EG(uninitialized_zval); |
|
} else if (zend_hash_quick_find(EG(active_symbol_table), cv->name, cv->name_len+1, cv->hash_value, (void **)ptr)==FAILURE) { |
|
Z_ADDREF(EG(uninitialized_zval)); |
|
zend_hash_quick_update(EG(active_symbol_table), cv->name, cv->name_len+1, cv->hash_value, &EG(uninitialized_zval_ptr), sizeof(zval *), (void **)ptr); |
|
} |
|
return *ptr; |
|
} |
|
|
|
static zend_always_inline zval *_get_zval_ptr_cv(zend_uint var, int type TSRMLS_DC) |
|
{ |
|
zval ***ptr = &CV_OF(var); |
|
|
if (UNEXPECTED(*ptr == NULL)) { |
if (UNEXPECTED(*ptr == NULL)) { |
return *_get_zval_cv_lookup(ptr, node->u.var, type TSRMLS_CC); | return *_get_zval_cv_lookup(ptr, var, type TSRMLS_CC); |
} |
} |
return **ptr; |
return **ptr; |
} |
} |
|
|
static inline zval *_get_zval_ptr(znode *node, const temp_variable *Ts, zend_free_op *should_free, int type TSRMLS_DC) | static zend_always_inline zval *_get_zval_ptr_cv_BP_VAR_R(zval ***CVs, zend_uint var TSRMLS_DC) |
{ |
{ |
|
zval ***ptr = &CV(var); |
|
|
|
if (UNEXPECTED(*ptr == NULL)) { |
|
return *_get_zval_cv_lookup_BP_VAR_R(ptr, var TSRMLS_CC); |
|
} |
|
return **ptr; |
|
} |
|
|
|
static zend_always_inline zval *_get_zval_ptr_cv_BP_VAR_UNSET(zval ***CVs, zend_uint var TSRMLS_DC) |
|
{ |
|
zval ***ptr = &CV(var); |
|
|
|
if (UNEXPECTED(*ptr == NULL)) { |
|
return *_get_zval_cv_lookup_BP_VAR_UNSET(ptr, var TSRMLS_CC); |
|
} |
|
return **ptr; |
|
} |
|
|
|
static zend_always_inline zval *_get_zval_ptr_cv_BP_VAR_IS(zval ***CVs, zend_uint var TSRMLS_DC) |
|
{ |
|
zval ***ptr = &CV(var); |
|
|
|
if (UNEXPECTED(*ptr == NULL)) { |
|
return *_get_zval_cv_lookup_BP_VAR_IS(ptr, var TSRMLS_CC); |
|
} |
|
return **ptr; |
|
} |
|
|
|
static zend_always_inline zval *_get_zval_ptr_cv_BP_VAR_RW(zval ***CVs, zend_uint var TSRMLS_DC) |
|
{ |
|
zval ***ptr = &CV(var); |
|
|
|
if (UNEXPECTED(*ptr == NULL)) { |
|
return *_get_zval_cv_lookup_BP_VAR_RW(ptr, var TSRMLS_CC); |
|
} |
|
return **ptr; |
|
} |
|
|
|
static zend_always_inline zval *_get_zval_ptr_cv_BP_VAR_W(zval ***CVs, zend_uint var TSRMLS_DC) |
|
{ |
|
zval ***ptr = &CV(var); |
|
|
|
if (UNEXPECTED(*ptr == NULL)) { |
|
return *_get_zval_cv_lookup_BP_VAR_W(ptr, var TSRMLS_CC); |
|
} |
|
return **ptr; |
|
} |
|
|
|
static inline zval *_get_zval_ptr(int op_type, const znode_op *node, const temp_variable *Ts, zend_free_op *should_free, int type TSRMLS_DC) |
|
{ |
/* should_free->is_var = 0; */ |
/* should_free->is_var = 0; */ |
switch (node->op_type) { | switch (op_type) { |
case IS_CONST: |
case IS_CONST: |
should_free->var = 0; |
should_free->var = 0; |
return &node->u.constant; | return node->zv; |
break; |
break; |
case IS_TMP_VAR: |
case IS_TMP_VAR: |
should_free->var = TMP_FREE(&T(node->u.var).tmp_var); | should_free->var = TMP_FREE(&T(node->var).tmp_var); |
return &T(node->u.var).tmp_var; | return &T(node->var).tmp_var; |
break; |
break; |
case IS_VAR: |
case IS_VAR: |
return _get_zval_ptr_var(node, Ts, should_free TSRMLS_CC); | return _get_zval_ptr_var(node->var, Ts, should_free TSRMLS_CC); |
break; |
break; |
case IS_UNUSED: |
case IS_UNUSED: |
should_free->var = 0; |
should_free->var = 0; |
Line 277 static inline zval *_get_zval_ptr(znode *node, const t
|
Line 364 static inline zval *_get_zval_ptr(znode *node, const t
|
break; |
break; |
case IS_CV: |
case IS_CV: |
should_free->var = 0; |
should_free->var = 0; |
return _get_zval_ptr_cv(node, Ts, type TSRMLS_CC); | return _get_zval_ptr_cv(node->var, type TSRMLS_CC); |
break; |
break; |
EMPTY_SWITCH_DEFAULT_CASE() |
EMPTY_SWITCH_DEFAULT_CASE() |
} |
} |
return NULL; |
return NULL; |
} |
} |
|
|
static zend_always_inline zval **_get_zval_ptr_ptr_var(const znode *node, const temp_variable *Ts, zend_free_op *should_free TSRMLS_DC) | static zend_always_inline zval **_get_zval_ptr_ptr_var(zend_uint var, const temp_variable *Ts, zend_free_op *should_free TSRMLS_DC) |
{ |
{ |
zval** ptr_ptr = T(node->u.var).var.ptr_ptr; | zval** ptr_ptr = T(var).var.ptr_ptr; |
|
|
if (EXPECTED(ptr_ptr != NULL)) { |
if (EXPECTED(ptr_ptr != NULL)) { |
PZVAL_UNLOCK(*ptr_ptr, should_free); |
PZVAL_UNLOCK(*ptr_ptr, should_free); |
} else { |
} else { |
/* string offset */ |
/* string offset */ |
PZVAL_UNLOCK(T(node->u.var).str_offset.str, should_free); | PZVAL_UNLOCK(T(var).str_offset.str, should_free); |
} |
} |
return ptr_ptr; |
return ptr_ptr; |
} |
} |
|
|
static zend_always_inline zval **_get_zval_ptr_ptr_cv(const znode *node, const temp_variable *Ts, int type TSRMLS_DC) | static zend_always_inline zval **_get_zval_ptr_ptr_cv(zend_uint var, int type TSRMLS_DC) |
{ |
{ |
zval ***ptr = &CV_OF(node->u.var); | zval ***ptr = &CV_OF(var); |
|
|
if (UNEXPECTED(*ptr == NULL)) { |
if (UNEXPECTED(*ptr == NULL)) { |
return _get_zval_cv_lookup(ptr, node->u.var, type TSRMLS_CC); | return _get_zval_cv_lookup(ptr, var, type TSRMLS_CC); |
} |
} |
return *ptr; |
return *ptr; |
} |
} |
|
|
static inline zval **_get_zval_ptr_ptr(const znode *node, const temp_variable *Ts, zend_free_op *should_free, int type TSRMLS_DC) | static zend_always_inline zval **_get_zval_ptr_ptr_cv_BP_VAR_R(zval ***CVs, zend_uint var TSRMLS_DC) |
{ |
{ |
if (node->op_type == IS_CV) { | zval ***ptr = &CV(var); |
| |
| if (UNEXPECTED(*ptr == NULL)) { |
| return _get_zval_cv_lookup_BP_VAR_R(ptr, var TSRMLS_CC); |
| } |
| return *ptr; |
| } |
| |
| static zend_always_inline zval **_get_zval_ptr_ptr_cv_BP_VAR_UNSET(zval ***CVs, zend_uint var TSRMLS_DC) |
| { |
| zval ***ptr = &CV(var); |
| |
| if (UNEXPECTED(*ptr == NULL)) { |
| return _get_zval_cv_lookup_BP_VAR_UNSET(ptr, var TSRMLS_CC); |
| } |
| return *ptr; |
| } |
| |
| static zend_always_inline zval **_get_zval_ptr_ptr_cv_BP_VAR_IS(zval ***CVs, zend_uint var TSRMLS_DC) |
| { |
| zval ***ptr = &CV(var); |
| |
| if (UNEXPECTED(*ptr == NULL)) { |
| return _get_zval_cv_lookup_BP_VAR_IS(ptr, var TSRMLS_CC); |
| } |
| return *ptr; |
| } |
| |
| static zend_always_inline zval **_get_zval_ptr_ptr_cv_BP_VAR_RW(zval ***CVs, zend_uint var TSRMLS_DC) |
| { |
| zval ***ptr = &CV(var); |
| |
| if (UNEXPECTED(*ptr == NULL)) { |
| return _get_zval_cv_lookup_BP_VAR_RW(ptr, var TSRMLS_CC); |
| } |
| return *ptr; |
| } |
| |
| static zend_always_inline zval **_get_zval_ptr_ptr_cv_BP_VAR_W(zval ***CVs, zend_uint var TSRMLS_DC) |
| { |
| zval ***ptr = &CV(var); |
| |
| if (UNEXPECTED(*ptr == NULL)) { |
| return _get_zval_cv_lookup_BP_VAR_W(ptr, var TSRMLS_CC); |
| } |
| return *ptr; |
| } |
| |
| static inline zval **_get_zval_ptr_ptr(int op_type, const znode_op *node, const temp_variable *Ts, zend_free_op *should_free, int type TSRMLS_DC) |
| { |
| if (op_type == IS_CV) { |
should_free->var = 0; |
should_free->var = 0; |
return _get_zval_ptr_ptr_cv(node, Ts, type TSRMLS_CC); | return _get_zval_ptr_ptr_cv(node->var, type TSRMLS_CC); |
} else if (node->op_type == IS_VAR) { | } else if (op_type == IS_VAR) { |
return _get_zval_ptr_ptr_var(node, Ts, should_free TSRMLS_CC); | return _get_zval_ptr_ptr_var(node->var, Ts, should_free TSRMLS_CC); |
} else { |
} else { |
should_free->var = 0; |
should_free->var = 0; |
return NULL; |
return NULL; |
Line 330 static zend_always_inline zval *_get_obj_zval_ptr_unus
|
Line 467 static zend_always_inline zval *_get_obj_zval_ptr_unus
|
} |
} |
} |
} |
|
|
static inline zval **_get_obj_zval_ptr_ptr(const znode *op, const temp_variable *Ts, zend_free_op *should_free, int type TSRMLS_DC) | static inline zval **_get_obj_zval_ptr_ptr(int op_type, const znode_op *op, const temp_variable *Ts, zend_free_op *should_free, int type TSRMLS_DC) |
{ |
{ |
if (op->op_type == IS_UNUSED) { | if (op_type == IS_UNUSED) { |
if (EXPECTED(EG(This) != NULL)) { |
if (EXPECTED(EG(This) != NULL)) { |
/* this should actually never be modified, _ptr_ptr is modified only when |
/* this should actually never be modified, _ptr_ptr is modified only when |
the object is empty */ |
the object is empty */ |
Line 342 static inline zval **_get_obj_zval_ptr_ptr(const znode
|
Line 479 static inline zval **_get_obj_zval_ptr_ptr(const znode
|
zend_error_noreturn(E_ERROR, "Using $this when not in object context"); |
zend_error_noreturn(E_ERROR, "Using $this when not in object context"); |
} |
} |
} |
} |
return get_zval_ptr_ptr(op, Ts, should_free, type); | return get_zval_ptr_ptr(op_type, op, Ts, should_free, type); |
} |
} |
|
|
static zend_always_inline zval **_get_obj_zval_ptr_ptr_unused(TSRMLS_D) |
static zend_always_inline zval **_get_obj_zval_ptr_ptr_unused(TSRMLS_D) |
Line 355 static zend_always_inline zval **_get_obj_zval_ptr_ptr
|
Line 492 static zend_always_inline zval **_get_obj_zval_ptr_ptr
|
} |
} |
} |
} |
|
|
static inline zval *_get_obj_zval_ptr(znode *op, const temp_variable *Ts, zend_free_op *should_free, int type TSRMLS_DC) | static inline zval *_get_obj_zval_ptr(int op_type, znode_op *op, const temp_variable *Ts, zend_free_op *should_free, int type TSRMLS_DC) |
{ |
{ |
if (op->op_type == IS_UNUSED) { | if (op_type == IS_UNUSED) { |
if (EXPECTED(EG(This) != NULL)) { |
if (EXPECTED(EG(This) != NULL)) { |
should_free->var = 0; |
should_free->var = 0; |
return EG(This); |
return EG(This); |
Line 365 static inline zval *_get_obj_zval_ptr(znode *op, const
|
Line 502 static inline zval *_get_obj_zval_ptr(znode *op, const
|
zend_error_noreturn(E_ERROR, "Using $this when not in object context"); |
zend_error_noreturn(E_ERROR, "Using $this when not in object context"); |
} |
} |
} |
} |
return get_zval_ptr(op, Ts, should_free, type); | return get_zval_ptr(op_type, op, Ts, should_free, type); |
} |
} |
|
|
static inline void zend_switch_free(temp_variable *T, int extended_value TSRMLS_DC) |
|
{ |
|
if (T->var.ptr) { |
|
if (extended_value & ZEND_FE_RESET_VARIABLE) { /* foreach() free */ |
|
Z_DELREF_P(T->var.ptr); |
|
} |
|
zval_ptr_dtor(&T->var.ptr); |
|
} else if (!T->var.ptr_ptr) { |
|
/* perform the equivalent of equivalent of a |
|
* quick & silent get_zval_ptr, and FREE_OP |
|
*/ |
|
PZVAL_UNLOCK_FREE(T->str_offset.str); |
|
} |
|
} |
|
|
|
static void zend_assign_to_variable_reference(zval **variable_ptr_ptr, zval **value_ptr_ptr TSRMLS_DC) |
static void zend_assign_to_variable_reference(zval **variable_ptr_ptr, zval **value_ptr_ptr TSRMLS_DC) |
{ |
{ |
zval *variable_ptr = *variable_ptr_ptr; |
zval *variable_ptr = *variable_ptr_ptr; |
zval *value_ptr = *value_ptr_ptr; |
zval *value_ptr = *value_ptr_ptr; |
|
|
if (variable_ptr == EG(error_zval_ptr) || value_ptr==EG(error_zval_ptr)) { | if (variable_ptr == &EG(error_zval) || value_ptr == &EG(error_zval)) { |
variable_ptr_ptr = &EG(uninitialized_zval_ptr); |
variable_ptr_ptr = &EG(uninitialized_zval_ptr); |
} else if (variable_ptr != value_ptr) { |
} else if (variable_ptr != value_ptr) { |
if (!PZVAL_IS_REF(value_ptr)) { |
if (!PZVAL_IS_REF(value_ptr)) { |
Line 396 static void zend_assign_to_variable_reference(zval **v
|
Line 518 static void zend_assign_to_variable_reference(zval **v
|
Z_DELREF_P(value_ptr); |
Z_DELREF_P(value_ptr); |
if (Z_REFCOUNT_P(value_ptr)>0) { |
if (Z_REFCOUNT_P(value_ptr)>0) { |
ALLOC_ZVAL(*value_ptr_ptr); |
ALLOC_ZVAL(*value_ptr_ptr); |
**value_ptr_ptr = *value_ptr; | ZVAL_COPY_VALUE(*value_ptr_ptr, value_ptr); |
value_ptr = *value_ptr_ptr; |
value_ptr = *value_ptr_ptr; |
zendi_zval_copy_ctor(*value_ptr); |
zendi_zval_copy_ctor(*value_ptr); |
} |
} |
Line 411 static void zend_assign_to_variable_reference(zval **v
|
Line 533 static void zend_assign_to_variable_reference(zval **v
|
} else if (!Z_ISREF_P(variable_ptr)) { |
} else if (!Z_ISREF_P(variable_ptr)) { |
if (variable_ptr_ptr == value_ptr_ptr) { |
if (variable_ptr_ptr == value_ptr_ptr) { |
SEPARATE_ZVAL(variable_ptr_ptr); |
SEPARATE_ZVAL(variable_ptr_ptr); |
} else if (variable_ptr==EG(uninitialized_zval_ptr) | } else if (variable_ptr==&EG(uninitialized_zval) |
|| Z_REFCOUNT_P(variable_ptr)>2) { |
|| Z_REFCOUNT_P(variable_ptr)>2) { |
/* we need to separate */ |
/* we need to separate */ |
Z_SET_REFCOUNT_P(variable_ptr, Z_REFCOUNT_P(variable_ptr) - 2); |
Z_SET_REFCOUNT_P(variable_ptr, Z_REFCOUNT_P(variable_ptr) - 2); |
ALLOC_ZVAL(*variable_ptr_ptr); |
ALLOC_ZVAL(*variable_ptr_ptr); |
**variable_ptr_ptr = *variable_ptr; | ZVAL_COPY_VALUE(*variable_ptr_ptr, variable_ptr); |
zval_copy_ctor(*variable_ptr_ptr); |
zval_copy_ctor(*variable_ptr_ptr); |
*value_ptr_ptr = *variable_ptr_ptr; |
*value_ptr_ptr = *variable_ptr_ptr; |
Z_SET_REFCOUNT_PP(variable_ptr_ptr, 2); |
Z_SET_REFCOUNT_PP(variable_ptr_ptr, 2); |
Line 432 static inline void make_real_object(zval **object_ptr
|
Line 554 static inline void make_real_object(zval **object_ptr
|
|| (Z_TYPE_PP(object_ptr) == IS_BOOL && Z_LVAL_PP(object_ptr) == 0) |
|| (Z_TYPE_PP(object_ptr) == IS_BOOL && Z_LVAL_PP(object_ptr) == 0) |
|| (Z_TYPE_PP(object_ptr) == IS_STRING && Z_STRLEN_PP(object_ptr) == 0) |
|| (Z_TYPE_PP(object_ptr) == IS_STRING && Z_STRLEN_PP(object_ptr) == 0) |
) { |
) { |
zend_error(E_STRICT, "Creating default object from empty value"); |
|
|
|
SEPARATE_ZVAL_IF_NOT_REF(object_ptr); |
SEPARATE_ZVAL_IF_NOT_REF(object_ptr); |
zval_dtor(*object_ptr); |
zval_dtor(*object_ptr); |
object_init(*object_ptr); |
object_init(*object_ptr); |
|
zend_error(E_WARNING, "Creating default object from empty value"); |
} |
} |
} |
} |
|
|
static inline char * zend_verify_arg_class_kind(const zend_arg_info *cur_arg_info, ulong fetch_type, const char **class_name, zend_class_entry **pce TSRMLS_DC) | ZEND_API char * zend_verify_arg_class_kind(const zend_arg_info *cur_arg_info, ulong fetch_type, const char **class_name, zend_class_entry **pce TSRMLS_DC) |
{ |
{ |
*pce = zend_fetch_class(cur_arg_info->class_name, cur_arg_info->class_name_len, (fetch_type | ZEND_FETCH_CLASS_AUTO | ZEND_FETCH_CLASS_NO_AUTOLOAD) TSRMLS_CC); |
*pce = zend_fetch_class(cur_arg_info->class_name, cur_arg_info->class_name_len, (fetch_type | ZEND_FETCH_CLASS_AUTO | ZEND_FETCH_CLASS_NO_AUTOLOAD) TSRMLS_CC); |
|
|
Line 452 static inline char * zend_verify_arg_class_kind(const
|
Line 573 static inline char * zend_verify_arg_class_kind(const
|
} |
} |
} |
} |
|
|
static inline int zend_verify_arg_error(const zend_function *zf, zend_uint arg_num, const zend_arg_info *cur_arg_info, const char *need_msg, const char *need_kind, const char *given_msg, char *given_kind TSRMLS_DC) | ZEND_API int zend_verify_arg_error(int error_type, const zend_function *zf, zend_uint arg_num, const char *need_msg, const char *need_kind, const char *given_msg, const char *given_kind TSRMLS_DC) |
{ |
{ |
zend_execute_data *ptr = EG(current_execute_data)->prev_execute_data; |
zend_execute_data *ptr = EG(current_execute_data)->prev_execute_data; |
char *fname = zf->common.function_name; | const char *fname = zf->common.function_name; |
char *fsep; |
char *fsep; |
char *fclass; | const char *fclass; |
|
|
if (zf->common.scope) { |
if (zf->common.scope) { |
fsep = "::"; |
fsep = "::"; |
Line 468 static inline int zend_verify_arg_error(const zend_fun
|
Line 589 static inline int zend_verify_arg_error(const zend_fun
|
} |
} |
|
|
if (ptr && ptr->op_array) { |
if (ptr && ptr->op_array) { |
zend_error(E_RECOVERABLE_ERROR, "Argument %d passed to %s%s%s() must %s%s, %s%s given, called in %s on line %d and defined", arg_num, fclass, fsep, fname, need_msg, need_kind, given_msg, given_kind, ptr->op_array->filename, ptr->opline->lineno); | zend_error(error_type, "Argument %d passed to %s%s%s() must %s%s, %s%s given, called in %s on line %d and defined", arg_num, fclass, fsep, fname, need_msg, need_kind, given_msg, given_kind, ptr->op_array->filename, ptr->opline->lineno); |
} else { |
} else { |
zend_error(E_RECOVERABLE_ERROR, "Argument %d passed to %s%s%s() must %s%s, %s%s given", arg_num, fclass, fsep, fname, need_msg, need_kind, given_msg, given_kind); | zend_error(error_type, "Argument %d passed to %s%s%s() must %s%s, %s%s given", arg_num, fclass, fsep, fname, need_msg, need_kind, given_msg, given_kind); |
} |
} |
return 0; |
return 0; |
} |
} |
Line 493 static inline int zend_verify_arg_type(zend_function *
|
Line 614 static inline int zend_verify_arg_type(zend_function *
|
|
|
if (!arg) { |
if (!arg) { |
need_msg = zend_verify_arg_class_kind(cur_arg_info, fetch_type, &class_name, &ce TSRMLS_CC); |
need_msg = zend_verify_arg_class_kind(cur_arg_info, fetch_type, &class_name, &ce TSRMLS_CC); |
return zend_verify_arg_error(zf, arg_num, cur_arg_info, need_msg, class_name, "none", "" TSRMLS_CC); | return zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, need_msg, class_name, "none", "" TSRMLS_CC); |
} |
} |
if (Z_TYPE_P(arg) == IS_OBJECT) { |
if (Z_TYPE_P(arg) == IS_OBJECT) { |
need_msg = zend_verify_arg_class_kind(cur_arg_info, fetch_type, &class_name, &ce TSRMLS_CC); |
need_msg = zend_verify_arg_class_kind(cur_arg_info, fetch_type, &class_name, &ce TSRMLS_CC); |
if (!ce || !instanceof_function(Z_OBJCE_P(arg), ce TSRMLS_CC)) { |
if (!ce || !instanceof_function(Z_OBJCE_P(arg), ce TSRMLS_CC)) { |
return zend_verify_arg_error(zf, arg_num, cur_arg_info, need_msg, class_name, "instance of ", Z_OBJCE_P(arg)->name TSRMLS_CC); | return zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, need_msg, class_name, "instance of ", Z_OBJCE_P(arg)->name TSRMLS_CC); |
} |
} |
} else if (Z_TYPE_P(arg) != IS_NULL || !cur_arg_info->allow_null) { |
} else if (Z_TYPE_P(arg) != IS_NULL || !cur_arg_info->allow_null) { |
need_msg = zend_verify_arg_class_kind(cur_arg_info, fetch_type, &class_name, &ce TSRMLS_CC); |
need_msg = zend_verify_arg_class_kind(cur_arg_info, fetch_type, &class_name, &ce TSRMLS_CC); |
return zend_verify_arg_error(zf, arg_num, cur_arg_info, need_msg, class_name, zend_zval_type_name(arg), "" TSRMLS_CC); | return zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, need_msg, class_name, zend_zval_type_name(arg), "" TSRMLS_CC); |
} |
} |
} else if (cur_arg_info->array_type_hint) { | } else if (cur_arg_info->type_hint) { |
if (!arg) { | switch(cur_arg_info->type_hint) { |
return zend_verify_arg_error(zf, arg_num, cur_arg_info, "be an array", "", "none", "" TSRMLS_CC); | case IS_ARRAY: |
| if (!arg) { |
| return zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, "be of the type array", "", "none", "" TSRMLS_CC); |
| } |
| |
| if (Z_TYPE_P(arg) != IS_ARRAY && (Z_TYPE_P(arg) != IS_NULL || !cur_arg_info->allow_null)) { |
| return zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, "be of the type array", "", zend_zval_type_name(arg), "" TSRMLS_CC); |
| } |
| break; |
| |
| case IS_CALLABLE: |
| if (!arg) { |
| return zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, "be callable", "", "none", "" TSRMLS_CC); |
| } |
| if (!zend_is_callable(arg, IS_CALLABLE_CHECK_SILENT, NULL TSRMLS_CC) && (Z_TYPE_P(arg) != IS_NULL || !cur_arg_info->allow_null)) { |
| return zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, "be callable", "", zend_zval_type_name(arg), "" TSRMLS_CC); |
| } |
| break; |
| |
| default: |
| zend_error(E_ERROR, "Unknown typehint"); |
} |
} |
if (Z_TYPE_P(arg) != IS_ARRAY && (Z_TYPE_P(arg) != IS_NULL || !cur_arg_info->allow_null)) { |
|
return zend_verify_arg_error(zf, arg_num, cur_arg_info, "be an array", "", zend_zval_type_name(arg), "" TSRMLS_CC); |
|
} |
|
} |
} |
return 1; |
return 1; |
} |
} |
|
|
static inline void zend_assign_to_object(znode *result, zval **object_ptr, zval *property_name, znode *value_op, const temp_variable *Ts, int opcode TSRMLS_DC) | static inline void zend_assign_to_object(zval **retval, zval **object_ptr, zval *property_name, int value_type, znode_op *value_op, const temp_variable *Ts, int opcode, const zend_literal *key TSRMLS_DC) |
| |
{ |
{ |
zval *object = *object_ptr; |
zval *object = *object_ptr; |
zend_free_op free_value; |
zend_free_op free_value; |
zval *value = get_zval_ptr(value_op, Ts, &free_value, BP_VAR_R); | zval *value = get_zval_ptr(value_type, value_op, Ts, &free_value, BP_VAR_R); |
zval **retval = &T(result->u.var).var.ptr; | |
|
|
if (Z_TYPE_P(object) != IS_OBJECT) { |
if (Z_TYPE_P(object) != IS_OBJECT) { |
if (object == EG(error_zval_ptr)) { | if (object == &EG(error_zval)) { |
if (!RETURN_VALUE_UNUSED(result)) { | if (retval) { |
*retval = EG(uninitialized_zval_ptr); | *retval = &EG(uninitialized_zval); |
PZVAL_LOCK(*retval); |
PZVAL_LOCK(*retval); |
} |
} |
FREE_OP(free_value); |
FREE_OP(free_value); |
Line 538 static inline void zend_assign_to_object(znode *result
|
Line 674 static inline void zend_assign_to_object(znode *result
|
SEPARATE_ZVAL_IF_NOT_REF(object_ptr); |
SEPARATE_ZVAL_IF_NOT_REF(object_ptr); |
object = *object_ptr; |
object = *object_ptr; |
Z_ADDREF_P(object); |
Z_ADDREF_P(object); |
zend_error(E_STRICT, "Creating default object from empty value"); | zend_error(E_WARNING, "Creating default object from empty value"); |
if (Z_REFCOUNT_P(object) == 1) { |
if (Z_REFCOUNT_P(object) == 1) { |
/* object was removed by error handler, nothing to assign to */ |
/* object was removed by error handler, nothing to assign to */ |
zval_ptr_dtor(&object); |
zval_ptr_dtor(&object); |
Line 554 static inline void zend_assign_to_object(znode *result
|
Line 690 static inline void zend_assign_to_object(znode *result
|
object_init(object); |
object_init(object); |
} else { |
} else { |
zend_error(E_WARNING, "Attempt to assign property of non-object"); |
zend_error(E_WARNING, "Attempt to assign property of non-object"); |
if (!RETURN_VALUE_UNUSED(result)) { | if (retval) { |
*retval = EG(uninitialized_zval_ptr); | *retval = &EG(uninitialized_zval); |
PZVAL_LOCK(*retval); |
PZVAL_LOCK(*retval); |
} |
} |
FREE_OP(free_value); |
FREE_OP(free_value); |
return; |
return; |
} |
} |
} |
} |
| |
/* separate our value if necessary */ |
/* separate our value if necessary */ |
if (value_op->op_type == IS_TMP_VAR) { | if (value_type == IS_TMP_VAR) { |
zval *orig_value = value; |
zval *orig_value = value; |
|
|
ALLOC_ZVAL(value); |
ALLOC_ZVAL(value); |
*value = *orig_value; | ZVAL_COPY_VALUE(value, orig_value); |
Z_UNSET_ISREF_P(value); |
Z_UNSET_ISREF_P(value); |
Z_SET_REFCOUNT_P(value, 0); |
Z_SET_REFCOUNT_P(value, 0); |
} else if (value_op->op_type == IS_CONST) { | } else if (value_type == IS_CONST) { |
zval *orig_value = value; |
zval *orig_value = value; |
|
|
ALLOC_ZVAL(value); |
ALLOC_ZVAL(value); |
*value = *orig_value; | ZVAL_COPY_VALUE(value, orig_value); |
Z_UNSET_ISREF_P(value); |
Z_UNSET_ISREF_P(value); |
Z_SET_REFCOUNT_P(value, 0); |
Z_SET_REFCOUNT_P(value, 0); |
zval_copy_ctor(value); |
zval_copy_ctor(value); |
Line 586 static inline void zend_assign_to_object(znode *result
|
Line 722 static inline void zend_assign_to_object(znode *result
|
if (opcode == ZEND_ASSIGN_OBJ) { |
if (opcode == ZEND_ASSIGN_OBJ) { |
if (!Z_OBJ_HT_P(object)->write_property) { |
if (!Z_OBJ_HT_P(object)->write_property) { |
zend_error(E_WARNING, "Attempt to assign property of non-object"); |
zend_error(E_WARNING, "Attempt to assign property of non-object"); |
if (!RETURN_VALUE_UNUSED(result)) { | if (retval) { |
*retval = EG(uninitialized_zval_ptr); | *retval = &EG(uninitialized_zval); |
PZVAL_LOCK(*retval); | PZVAL_LOCK(&EG(uninitialized_zval)); |
} |
} |
if (value_op->op_type == IS_TMP_VAR) { | if (value_type == IS_TMP_VAR) { |
FREE_ZVAL(value); |
FREE_ZVAL(value); |
} else if (value_op->op_type == IS_CONST) { | } else if (value_type == IS_CONST) { |
zval_ptr_dtor(&value); |
zval_ptr_dtor(&value); |
} |
} |
FREE_OP(free_value); |
FREE_OP(free_value); |
return; |
return; |
} |
} |
Z_OBJ_HT_P(object)->write_property(object, property_name, value TSRMLS_CC); | Z_OBJ_HT_P(object)->write_property(object, property_name, value, key TSRMLS_CC); |
} else { |
} else { |
/* Note: property_name in this case is really the array index! */ |
/* Note: property_name in this case is really the array index! */ |
if (!Z_OBJ_HT_P(object)->write_dimension) { |
if (!Z_OBJ_HT_P(object)->write_dimension) { |
Line 607 static inline void zend_assign_to_object(znode *result
|
Line 743 static inline void zend_assign_to_object(znode *result
|
Z_OBJ_HT_P(object)->write_dimension(object, property_name, value TSRMLS_CC); |
Z_OBJ_HT_P(object)->write_dimension(object, property_name, value TSRMLS_CC); |
} |
} |
|
|
if (!RETURN_VALUE_UNUSED(result) && !EG(exception)) { | if (retval && !EG(exception)) { |
AI_SET_PTR(T(result->u.var).var, value); | *retval = value; |
PZVAL_LOCK(value); |
PZVAL_LOCK(value); |
} |
} |
zval_ptr_dtor(&value); |
zval_ptr_dtor(&value); |
Line 625 static inline int zend_assign_to_string_offset(const t
|
Line 761 static inline int zend_assign_to_string_offset(const t
|
} |
} |
|
|
if (T->str_offset.offset >= Z_STRLEN_P(T->str_offset.str)) { |
if (T->str_offset.offset >= Z_STRLEN_P(T->str_offset.str)) { |
Z_STRVAL_P(T->str_offset.str) = (char *) erealloc(Z_STRVAL_P(T->str_offset.str), T->str_offset.offset+1+1); | if (IS_INTERNED(Z_STRVAL_P(T->str_offset.str))) { |
| char *tmp = (char *) emalloc(T->str_offset.offset+1+1); |
| |
| memcpy(tmp, Z_STRVAL_P(T->str_offset.str), Z_STRLEN_P(T->str_offset.str)+1); |
| Z_STRVAL_P(T->str_offset.str) = tmp; |
| } else { |
| Z_STRVAL_P(T->str_offset.str) = (char *) erealloc(Z_STRVAL_P(T->str_offset.str), T->str_offset.offset+1+1); |
| } |
memset(Z_STRVAL_P(T->str_offset.str) + Z_STRLEN_P(T->str_offset.str), |
memset(Z_STRVAL_P(T->str_offset.str) + Z_STRLEN_P(T->str_offset.str), |
' ', |
' ', |
T->str_offset.offset - Z_STRLEN_P(T->str_offset.str)); |
T->str_offset.offset - Z_STRLEN_P(T->str_offset.str)); |
Z_STRVAL_P(T->str_offset.str)[T->str_offset.offset+1] = 0; |
Z_STRVAL_P(T->str_offset.str)[T->str_offset.offset+1] = 0; |
Z_STRLEN_P(T->str_offset.str) = T->str_offset.offset+1; |
Z_STRLEN_P(T->str_offset.str) = T->str_offset.offset+1; |
|
} else if (IS_INTERNED(Z_STRVAL_P(T->str_offset.str))) { |
|
char *tmp = (char *) emalloc(Z_STRLEN_P(T->str_offset.str) + 1); |
|
|
|
memcpy(tmp, Z_STRVAL_P(T->str_offset.str), Z_STRLEN_P(T->str_offset.str) + 1); |
|
Z_STRVAL_P(T->str_offset.str) = tmp; |
} |
} |
|
|
if (Z_TYPE_P(value) != IS_STRING) { |
if (Z_TYPE_P(value) != IS_STRING) { |
zval tmp = *value; | zval tmp; |
|
|
|
ZVAL_COPY_VALUE(&tmp, value); |
if (value_type != IS_TMP_VAR) { |
if (value_type != IS_TMP_VAR) { |
zval_copy_ctor(&tmp); |
zval_copy_ctor(&tmp); |
} |
} |
Line 659 static inline int zend_assign_to_string_offset(const t
|
Line 808 static inline int zend_assign_to_string_offset(const t
|
return 1; |
return 1; |
} |
} |
|
|
static inline zval* zend_assign_to_variable(zval **variable_ptr_ptr, zval *value, int is_tmp_var TSRMLS_DC) | |
| static inline zval* zend_assign_tmp_to_variable(zval **variable_ptr_ptr, zval *value TSRMLS_DC) |
{ |
{ |
zval *variable_ptr = *variable_ptr_ptr; |
zval *variable_ptr = *variable_ptr_ptr; |
zval garbage; |
zval garbage; |
|
|
if (variable_ptr == EG(error_zval_ptr)) { | if (Z_TYPE_P(variable_ptr) == IS_OBJECT && |
if (is_tmp_var) { | UNEXPECTED(Z_OBJ_HANDLER_P(variable_ptr, set) != NULL)) { |
zval_dtor(value); | Z_OBJ_HANDLER_P(variable_ptr, set)(variable_ptr_ptr, value TSRMLS_CC); |
| return variable_ptr; |
| } |
| |
| if (UNEXPECTED(Z_REFCOUNT_P(variable_ptr) > 1) && |
| EXPECTED(!PZVAL_IS_REF(variable_ptr))) { |
| /* we need to split */ |
| Z_DELREF_P(variable_ptr); |
| GC_ZVAL_CHECK_POSSIBLE_ROOT(variable_ptr); |
| ALLOC_ZVAL(variable_ptr); |
| INIT_PZVAL_COPY(variable_ptr, value); |
| *variable_ptr_ptr = variable_ptr; |
| return variable_ptr; |
| } else { |
| if (EXPECTED(Z_TYPE_P(variable_ptr) <= IS_BOOL)) { |
| /* nothing to destroy */ |
| ZVAL_COPY_VALUE(variable_ptr, value); |
| } else { |
| ZVAL_COPY_VALUE(&garbage, variable_ptr); |
| ZVAL_COPY_VALUE(variable_ptr, value); |
| _zval_dtor_func(&garbage ZEND_FILE_LINE_CC); |
} |
} |
return EG(uninitialized_zval_ptr); | return variable_ptr; |
} |
} |
|
} |
|
|
if (Z_TYPE_P(variable_ptr) == IS_OBJECT && Z_OBJ_HANDLER_P(variable_ptr, set)) { | static inline zval* zend_assign_const_to_variable(zval **variable_ptr_ptr, zval *value TSRMLS_DC) |
| { |
| zval *variable_ptr = *variable_ptr_ptr; |
| zval garbage; |
| |
| if (Z_TYPE_P(variable_ptr) == IS_OBJECT && |
| UNEXPECTED(Z_OBJ_HANDLER_P(variable_ptr, set) != NULL)) { |
Z_OBJ_HANDLER_P(variable_ptr, set)(variable_ptr_ptr, value TSRMLS_CC); |
Z_OBJ_HANDLER_P(variable_ptr, set)(variable_ptr_ptr, value TSRMLS_CC); |
return variable_ptr; |
return variable_ptr; |
} |
} |
|
|
if (PZVAL_IS_REF(variable_ptr)) { | if (UNEXPECTED(Z_REFCOUNT_P(variable_ptr) > 1) && |
if (variable_ptr!=value) { | EXPECTED(!PZVAL_IS_REF(variable_ptr))) { |
zend_uint refcount = Z_REFCOUNT_P(variable_ptr); | /* we need to split */ |
| Z_DELREF_P(variable_ptr); |
garbage = *variable_ptr; | GC_ZVAL_CHECK_POSSIBLE_ROOT(variable_ptr); |
*variable_ptr = *value; | ALLOC_ZVAL(variable_ptr); |
Z_SET_REFCOUNT_P(variable_ptr, refcount); | INIT_PZVAL_COPY(variable_ptr, value); |
Z_SET_ISREF_P(variable_ptr); | zval_copy_ctor(variable_ptr); |
if (!is_tmp_var) { | *variable_ptr_ptr = variable_ptr; |
zendi_zval_copy_ctor(*variable_ptr); | return variable_ptr; |
} | } else { |
zendi_zval_dtor(garbage); | if (EXPECTED(Z_TYPE_P(variable_ptr) <= IS_BOOL)) { |
return variable_ptr; | /* nothing to destroy */ |
| ZVAL_COPY_VALUE(variable_ptr, value); |
| zendi_zval_copy_ctor(*variable_ptr); |
| } else { |
| ZVAL_COPY_VALUE(&garbage, variable_ptr); |
| ZVAL_COPY_VALUE(variable_ptr, value); |
| zendi_zval_copy_ctor(*variable_ptr); |
| _zval_dtor_func(&garbage ZEND_FILE_LINE_CC); |
} |
} |
} else { | return variable_ptr; |
if (Z_DELREF_P(variable_ptr)==0) { | } |
if (!is_tmp_var) { | } |
if (variable_ptr==value) { | |
Z_ADDREF_P(variable_ptr); | static inline zval* zend_assign_to_variable(zval **variable_ptr_ptr, zval *value TSRMLS_DC) |
} else if (PZVAL_IS_REF(value)) { | { |
garbage = *variable_ptr; | zval *variable_ptr = *variable_ptr_ptr; |
*variable_ptr = *value; | zval garbage; |
INIT_PZVAL(variable_ptr); | |
zval_copy_ctor(variable_ptr); | if (Z_TYPE_P(variable_ptr) == IS_OBJECT && |
zendi_zval_dtor(garbage); | UNEXPECTED(Z_OBJ_HANDLER_P(variable_ptr, set) != NULL)) { |
return variable_ptr; | Z_OBJ_HANDLER_P(variable_ptr, set)(variable_ptr_ptr, value TSRMLS_CC); |
| return variable_ptr; |
| } |
| |
| if (EXPECTED(!PZVAL_IS_REF(variable_ptr))) { |
| if (Z_REFCOUNT_P(variable_ptr)==1) { |
| if (UNEXPECTED(variable_ptr == value)) { |
| return variable_ptr; |
| } else if (EXPECTED(!PZVAL_IS_REF(value))) { |
| Z_ADDREF_P(value); |
| *variable_ptr_ptr = value; |
| if (EXPECTED(variable_ptr != &EG(uninitialized_zval))) { |
| GC_REMOVE_ZVAL_FROM_BUFFER(variable_ptr); |
| zval_dtor(variable_ptr); |
| efree(variable_ptr); |
} else { |
} else { |
Z_ADDREF_P(value); | Z_DELREF_P(variable_ptr); |
*variable_ptr_ptr = value; | |
if (variable_ptr != &EG(uninitialized_zval)) { | |
GC_REMOVE_ZVAL_FROM_BUFFER(variable_ptr); | |
zval_dtor(variable_ptr); | |
efree(variable_ptr); | |
} | |
return value; | |
} |
} |
|
return value; |
} else { |
} else { |
garbage = *variable_ptr; | goto copy_value; |
*variable_ptr = *value; | |
INIT_PZVAL(variable_ptr); | |
zendi_zval_dtor(garbage); | |
return variable_ptr; | |
} |
} |
} else { /* we need to split */ |
} else { /* we need to split */ |
GC_ZVAL_CHECK_POSSIBLE_ROOT(*variable_ptr_ptr); | Z_DELREF_P(variable_ptr); |
if (!is_tmp_var) { | GC_ZVAL_CHECK_POSSIBLE_ROOT(variable_ptr); |
if (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0) { | if (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0) { |
ALLOC_ZVAL(variable_ptr); | ALLOC_ZVAL(variable_ptr); |
*variable_ptr_ptr = variable_ptr; | *variable_ptr_ptr = variable_ptr; |
*variable_ptr = *value; | INIT_PZVAL_COPY(variable_ptr, value); |
Z_SET_REFCOUNT_P(variable_ptr, 1); | zval_copy_ctor(variable_ptr); |
zval_copy_ctor(variable_ptr); | return variable_ptr; |
} else { | |
*variable_ptr_ptr = value; | |
Z_ADDREF_P(value); | |
} | |
} else { |
} else { |
ALLOC_ZVAL(*variable_ptr_ptr); | *variable_ptr_ptr = value; |
Z_SET_REFCOUNT_P(value, 1); | Z_ADDREF_P(value); |
**variable_ptr_ptr = *value; | Z_UNSET_ISREF_P(value); |
| return value; |
} |
} |
} |
} |
Z_UNSET_ISREF_PP(variable_ptr_ptr); | } else { |
| if (EXPECTED(variable_ptr != value)) { |
| copy_value: |
| if (EXPECTED(Z_TYPE_P(variable_ptr) <= IS_BOOL)) { |
| /* nothing to destroy */ |
| ZVAL_COPY_VALUE(variable_ptr, value); |
| zendi_zval_copy_ctor(*variable_ptr); |
| } else { |
| ZVAL_COPY_VALUE(&garbage, variable_ptr); |
| ZVAL_COPY_VALUE(variable_ptr, value); |
| zendi_zval_copy_ctor(*variable_ptr); |
| _zval_dtor_func(&garbage ZEND_FILE_LINE_CC); |
| } |
| } |
| return variable_ptr; |
} |
} |
|
|
return *variable_ptr_ptr; |
|
} |
} |
|
|
|
|
/* Utility Functions for Extensions */ |
/* Utility Functions for Extensions */ |
static void zend_extension_statement_handler(const zend_extension *extension, zend_op_array *op_array TSRMLS_DC) |
static void zend_extension_statement_handler(const zend_extension *extension, zend_op_array *op_array TSRMLS_DC) |
{ |
{ |
Line 770 static void zend_extension_fcall_end_handler(const zen
|
Line 966 static void zend_extension_fcall_end_handler(const zen
|
} |
} |
|
|
|
|
static inline HashTable *zend_get_target_symbol_table(const zend_op *opline, const temp_variable *Ts, int type, const zval *variable TSRMLS_DC) | static inline HashTable *zend_get_target_symbol_table(int fetch_type TSRMLS_DC) |
{ |
{ |
switch (opline->op2.u.EA.type) { | switch (fetch_type) { |
case ZEND_FETCH_LOCAL: |
case ZEND_FETCH_LOCAL: |
if (!EG(active_symbol_table)) { |
if (!EG(active_symbol_table)) { |
zend_rebuild_symbol_table(TSRMLS_C); |
zend_rebuild_symbol_table(TSRMLS_C); |
Line 795 static inline HashTable *zend_get_target_symbol_table(
|
Line 991 static inline HashTable *zend_get_target_symbol_table(
|
return NULL; |
return NULL; |
} |
} |
|
|
static inline zval **zend_fetch_dimension_address_inner(HashTable *ht, const zval *dim, int type TSRMLS_DC) | static inline zval **zend_fetch_dimension_address_inner(HashTable *ht, const zval *dim, int dim_type, int type TSRMLS_DC) |
{ |
{ |
zval **retval; |
zval **retval; |
char *offset_key; |
char *offset_key; |
int offset_key_length; |
int offset_key_length; |
long index; | ulong hval; |
|
|
switch (dim->type) { |
switch (dim->type) { |
case IS_NULL: |
case IS_NULL: |
offset_key = ""; |
offset_key = ""; |
offset_key_length = 0; |
offset_key_length = 0; |
|
hval = zend_inline_hash_func("", 1); |
goto fetch_string_dim; |
goto fetch_string_dim; |
|
|
case IS_STRING: |
case IS_STRING: |
| |
offset_key = dim->value.str.val; |
offset_key = dim->value.str.val; |
offset_key_length = dim->value.str.len; |
offset_key_length = dim->value.str.len; |
| |
| if (dim_type == IS_CONST) { |
| hval = Z_HASH_P(dim); |
| } else { |
| ZEND_HANDLE_NUMERIC_EX(offset_key, offset_key_length+1, hval, goto num_index); |
| if (IS_INTERNED(offset_key)) { |
| hval = INTERNED_HASH(offset_key); |
| } else { |
| hval = zend_hash_func(offset_key, offset_key_length+1); |
| } |
| } |
fetch_string_dim: |
fetch_string_dim: |
if (zend_symtable_find(ht, offset_key, offset_key_length+1, (void **) &retval) == FAILURE) { | if (zend_hash_quick_find(ht, offset_key, offset_key_length+1, hval, (void **) &retval) == FAILURE) { |
switch (type) { |
switch (type) { |
case BP_VAR_R: |
case BP_VAR_R: |
zend_error(E_NOTICE, "Undefined index: %s", offset_key); |
zend_error(E_NOTICE, "Undefined index: %s", offset_key); |
Line 830 fetch_string_dim:
|
Line 1037 fetch_string_dim:
|
zval *new_zval = &EG(uninitialized_zval); |
zval *new_zval = &EG(uninitialized_zval); |
|
|
Z_ADDREF_P(new_zval); |
Z_ADDREF_P(new_zval); |
zend_symtable_update(ht, offset_key, offset_key_length+1, &new_zval, sizeof(zval *), (void **) &retval); | zend_hash_quick_update(ht, offset_key, offset_key_length+1, hval, &new_zval, sizeof(zval *), (void **) &retval); |
} |
} |
break; |
break; |
} |
} |
} |
} |
break; |
break; |
case IS_DOUBLE: |
case IS_DOUBLE: |
index = zend_dval_to_lval(Z_DVAL_P(dim)); | hval = zend_dval_to_lval(Z_DVAL_P(dim)); |
goto num_index; |
goto num_index; |
case IS_RESOURCE: |
case IS_RESOURCE: |
zend_error(E_STRICT, "Resource ID#%ld used as offset, casting to integer (%ld)", Z_LVAL_P(dim), Z_LVAL_P(dim)); |
zend_error(E_STRICT, "Resource ID#%ld used as offset, casting to integer (%ld)", Z_LVAL_P(dim), Z_LVAL_P(dim)); |
/* Fall Through */ |
/* Fall Through */ |
case IS_BOOL: |
case IS_BOOL: |
case IS_LONG: |
case IS_LONG: |
index = Z_LVAL_P(dim); | hval = Z_LVAL_P(dim); |
num_index: |
num_index: |
if (zend_hash_index_find(ht, index, (void **) &retval) == FAILURE) { | if (zend_hash_index_find(ht, hval, (void **) &retval) == FAILURE) { |
switch (type) { |
switch (type) { |
case BP_VAR_R: |
case BP_VAR_R: |
zend_error(E_NOTICE,"Undefined offset: %ld", index); | zend_error(E_NOTICE,"Undefined offset: %ld", hval); |
/* break missing intentionally */ |
/* break missing intentionally */ |
case BP_VAR_UNSET: |
case BP_VAR_UNSET: |
case BP_VAR_IS: |
case BP_VAR_IS: |
retval = &EG(uninitialized_zval_ptr); |
retval = &EG(uninitialized_zval_ptr); |
break; |
break; |
case BP_VAR_RW: |
case BP_VAR_RW: |
zend_error(E_NOTICE,"Undefined offset: %ld", index); | zend_error(E_NOTICE,"Undefined offset: %ld", hval); |
/* break missing intentionally */ |
/* break missing intentionally */ |
case BP_VAR_W: { |
case BP_VAR_W: { |
zval *new_zval = &EG(uninitialized_zval); |
zval *new_zval = &EG(uninitialized_zval); |
|
|
Z_ADDREF_P(new_zval); |
Z_ADDREF_P(new_zval); |
zend_hash_index_update(ht, index, &new_zval, sizeof(zval *), (void **) &retval); | zend_hash_index_update(ht, hval, &new_zval, sizeof(zval *), (void **) &retval); |
} |
} |
break; |
break; |
} |
} |
Line 877 num_index:
|
Line 1084 num_index:
|
return retval; |
return retval; |
} |
} |
|
|
static void zend_fetch_dimension_address(temp_variable *result, zval **container_ptr, zval *dim, int dim_is_tmp_var, int type TSRMLS_DC) | static void zend_fetch_dimension_address(temp_variable *result, zval **container_ptr, zval *dim, int dim_type, int type TSRMLS_DC) |
{ |
{ |
zval *container = *container_ptr; |
zval *container = *container_ptr; |
zval **retval; |
zval **retval; |
Line 900 fetch_from_array:
|
Line 1107 fetch_from_array:
|
Z_DELREF_P(new_zval); |
Z_DELREF_P(new_zval); |
} |
} |
} else { |
} else { |
retval = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, type TSRMLS_CC); | retval = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, dim_type, type TSRMLS_CC); |
} |
} |
result->var.ptr_ptr = retval; |
result->var.ptr_ptr = retval; |
PZVAL_LOCK(*retval); |
PZVAL_LOCK(*retval); |
Line 908 fetch_from_array:
|
Line 1115 fetch_from_array:
|
break; |
break; |
|
|
case IS_NULL: |
case IS_NULL: |
if (container == EG(error_zval_ptr)) { | if (container == &EG(error_zval)) { |
result->var.ptr_ptr = &EG(error_zval_ptr); |
result->var.ptr_ptr = &EG(error_zval_ptr); |
PZVAL_LOCK(EG(error_zval_ptr)); |
PZVAL_LOCK(EG(error_zval_ptr)); |
} else if (type != BP_VAR_UNSET) { |
} else if (type != BP_VAR_UNSET) { |
Line 938 convert_to_array:
|
Line 1145 convert_to_array:
|
zend_error_noreturn(E_ERROR, "[] operator not supported for strings"); |
zend_error_noreturn(E_ERROR, "[] operator not supported for strings"); |
} |
} |
|
|
|
if (type != BP_VAR_UNSET) { |
|
SEPARATE_ZVAL_IF_NOT_REF(container_ptr); |
|
} |
|
|
if (Z_TYPE_P(dim) != IS_LONG) { |
if (Z_TYPE_P(dim) != IS_LONG) { |
|
|
switch(Z_TYPE_P(dim)) { |
switch(Z_TYPE_P(dim)) { |
/* case IS_LONG: */ |
/* case IS_LONG: */ |
case IS_STRING: |
case IS_STRING: |
|
if (IS_LONG == is_numeric_string(Z_STRVAL_P(dim), Z_STRLEN_P(dim), NULL, NULL, -1)) { |
|
break; |
|
} |
|
if (type != BP_VAR_UNSET) { |
|
zend_error(E_WARNING, "Illegal string offset '%s'", dim->value.str.val); |
|
} |
|
|
|
break; |
case IS_DOUBLE: |
case IS_DOUBLE: |
case IS_NULL: |
case IS_NULL: |
case IS_BOOL: |
case IS_BOOL: |
/* do nothing */ | zend_error(E_NOTICE, "String offset cast occurred"); |
break; |
break; |
default: |
default: |
zend_error(E_WARNING, "Illegal offset type"); |
zend_error(E_WARNING, "Illegal offset type"); |
Line 957 convert_to_array:
|
Line 1177 convert_to_array:
|
convert_to_long(&tmp); |
convert_to_long(&tmp); |
dim = &tmp; |
dim = &tmp; |
} |
} |
if (type != BP_VAR_UNSET) { |
|
SEPARATE_ZVAL_IF_NOT_REF(container_ptr); |
|
} |
|
container = *container_ptr; |
container = *container_ptr; |
result->str_offset.str = container; |
result->str_offset.str = container; |
PZVAL_LOCK(container); |
PZVAL_LOCK(container); |
result->str_offset.offset = Z_LVAL_P(dim); |
result->str_offset.offset = Z_LVAL_P(dim); |
result->var.ptr_ptr = NULL; | result->str_offset.ptr_ptr = NULL; |
result->var.ptr = NULL; | |
return; |
return; |
} |
} |
break; |
break; |
Line 976 convert_to_array:
|
Line 1192 convert_to_array:
|
} else { |
} else { |
zval *overloaded_result; |
zval *overloaded_result; |
|
|
if (dim_is_tmp_var) { | if (dim_type == IS_TMP_VAR) { |
zval *orig = dim; |
zval *orig = dim; |
MAKE_REAL_ZVAL_PTR(dim); |
MAKE_REAL_ZVAL_PTR(dim); |
ZVAL_NULL(orig); |
ZVAL_NULL(orig); |
Line 989 convert_to_array:
|
Line 1205 convert_to_array:
|
zval *tmp = overloaded_result; |
zval *tmp = overloaded_result; |
|
|
ALLOC_ZVAL(overloaded_result); |
ALLOC_ZVAL(overloaded_result); |
*overloaded_result = *tmp; | ZVAL_COPY_VALUE(overloaded_result, tmp); |
zval_copy_ctor(overloaded_result); |
zval_copy_ctor(overloaded_result); |
Z_UNSET_ISREF_P(overloaded_result); |
Z_UNSET_ISREF_P(overloaded_result); |
Z_SET_REFCOUNT_P(overloaded_result, 0); |
Z_SET_REFCOUNT_P(overloaded_result, 0); |
Line 1003 convert_to_array:
|
Line 1219 convert_to_array:
|
} else { |
} else { |
retval = &EG(error_zval_ptr); |
retval = &EG(error_zval_ptr); |
} |
} |
AI_SET_PTR(result->var, *retval); | AI_SET_PTR(result, *retval); |
PZVAL_LOCK(*retval); |
PZVAL_LOCK(*retval); |
if (dim_is_tmp_var) { | if (dim_type == IS_TMP_VAR) { |
zval_ptr_dtor(&dim); |
zval_ptr_dtor(&dim); |
} |
} |
} |
} |
Line 1021 convert_to_array:
|
Line 1237 convert_to_array:
|
default: |
default: |
if (type == BP_VAR_UNSET) { |
if (type == BP_VAR_UNSET) { |
zend_error(E_WARNING, "Cannot unset offset in a non-array variable"); |
zend_error(E_WARNING, "Cannot unset offset in a non-array variable"); |
AI_SET_PTR(result->var, EG(uninitialized_zval_ptr)); | AI_SET_PTR(result, &EG(uninitialized_zval)); |
PZVAL_LOCK(EG(uninitialized_zval_ptr)); | PZVAL_LOCK(&EG(uninitialized_zval)); |
} else { |
} else { |
zend_error(E_WARNING, "Cannot use a scalar value as an array"); |
zend_error(E_WARNING, "Cannot use a scalar value as an array"); |
result->var.ptr_ptr = &EG(error_zval_ptr); |
result->var.ptr_ptr = &EG(error_zval_ptr); |
Line 1032 convert_to_array:
|
Line 1248 convert_to_array:
|
} |
} |
} |
} |
|
|
static void zend_fetch_dimension_address_read(temp_variable *result, zval **container_ptr, zval *dim, int dim_is_tmp_var, int type TSRMLS_DC) | static void zend_fetch_dimension_address_read(temp_variable *result, zval *container, zval *dim, int dim_type, int type TSRMLS_DC) |
{ |
{ |
zval *container = *container_ptr; |
|
zval **retval; |
zval **retval; |
|
|
switch (Z_TYPE_P(container)) { |
switch (Z_TYPE_P(container)) { |
|
|
case IS_ARRAY: |
case IS_ARRAY: |
retval = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, type TSRMLS_CC); | retval = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, dim_type, type TSRMLS_CC); |
if (result) { | AI_SET_PTR(result, *retval); |
AI_SET_PTR(result->var, *retval); | PZVAL_LOCK(*retval); |
PZVAL_LOCK(*retval); | |
} | |
return; |
return; |
break; |
|
|
|
case IS_NULL: |
case IS_NULL: |
if (result) { | AI_SET_PTR(result, &EG(uninitialized_zval)); |
AI_SET_PTR(result->var, EG(uninitialized_zval_ptr)); | PZVAL_LOCK(&EG(uninitialized_zval)); |
PZVAL_LOCK(EG(uninitialized_zval_ptr)); | |
} | |
return; |
return; |
break; |
|
|
|
case IS_STRING: { |
case IS_STRING: { |
zval tmp; |
zval tmp; |
|
zval *ptr; |
|
|
if (Z_TYPE_P(dim) != IS_LONG) { |
if (Z_TYPE_P(dim) != IS_LONG) { |
switch(Z_TYPE_P(dim)) { |
switch(Z_TYPE_P(dim)) { |
/* case IS_LONG: */ |
/* case IS_LONG: */ |
case IS_STRING: |
case IS_STRING: |
|
if (IS_LONG == is_numeric_string(Z_STRVAL_P(dim), Z_STRLEN_P(dim), NULL, NULL, -1)) { |
|
break; |
|
} |
|
if (type != BP_VAR_IS) { |
|
zend_error(E_WARNING, "Illegal string offset '%s'", dim->value.str.val); |
|
} |
|
break; |
case IS_DOUBLE: |
case IS_DOUBLE: |
case IS_NULL: |
case IS_NULL: |
case IS_BOOL: |
case IS_BOOL: |
/* do nothing */ | if (type != BP_VAR_IS) { |
| zend_error(E_NOTICE, "String offset cast occurred"); |
| } |
break; |
break; |
default: |
default: |
zend_error(E_WARNING, "Illegal offset type"); |
zend_error(E_WARNING, "Illegal offset type"); |
break; |
break; |
} |
} |
|
|
tmp = *dim; | ZVAL_COPY_VALUE(&tmp, dim); |
zval_copy_ctor(&tmp); |
zval_copy_ctor(&tmp); |
convert_to_long(&tmp); |
convert_to_long(&tmp); |
dim = &tmp; |
dim = &tmp; |
} |
} |
if (result) { | |
if ((Z_LVAL_P(dim) < 0 || Z_STRLEN_P(container) <= Z_LVAL_P(dim)) && type != BP_VAR_IS) { | ALLOC_ZVAL(ptr); |
| INIT_PZVAL(ptr); |
| Z_TYPE_P(ptr) = IS_STRING; |
| |
| if (Z_LVAL_P(dim) < 0 || Z_STRLEN_P(container) <= Z_LVAL_P(dim)) { |
| if (type != BP_VAR_IS) { |
zend_error(E_NOTICE, "Uninitialized string offset: %ld", Z_LVAL_P(dim)); |
zend_error(E_NOTICE, "Uninitialized string offset: %ld", Z_LVAL_P(dim)); |
} |
} |
result->str_offset.str = container; | Z_STRVAL_P(ptr) = STR_EMPTY_ALLOC(); |
PZVAL_LOCK(container); | Z_STRLEN_P(ptr) = 0; |
result->str_offset.offset = Z_LVAL_P(dim); | } else { |
result->var.ptr_ptr = NULL; | Z_STRVAL_P(ptr) = (char*)emalloc(2); |
result->var.ptr = NULL; | Z_STRVAL_P(ptr)[0] = Z_STRVAL_P(container)[Z_LVAL_P(dim)]; |
| Z_STRVAL_P(ptr)[1] = 0; |
| Z_STRLEN_P(ptr) = 1; |
} |
} |
|
AI_SET_PTR(result, ptr); |
return; |
return; |
} |
} |
break; |
break; |
Line 1098 static void zend_fetch_dimension_address_read(temp_var
|
Line 1325 static void zend_fetch_dimension_address_read(temp_var
|
} else { |
} else { |
zval *overloaded_result; |
zval *overloaded_result; |
|
|
if (dim_is_tmp_var) { | if (dim_type == IS_TMP_VAR) { |
zval *orig = dim; |
zval *orig = dim; |
MAKE_REAL_ZVAL_PTR(dim); |
MAKE_REAL_ZVAL_PTR(dim); |
ZVAL_NULL(orig); |
ZVAL_NULL(orig); |
Line 1106 static void zend_fetch_dimension_address_read(temp_var
|
Line 1333 static void zend_fetch_dimension_address_read(temp_var
|
overloaded_result = Z_OBJ_HT_P(container)->read_dimension(container, dim, type TSRMLS_CC); |
overloaded_result = Z_OBJ_HT_P(container)->read_dimension(container, dim, type TSRMLS_CC); |
|
|
if (overloaded_result) { |
if (overloaded_result) { |
if (result) { | AI_SET_PTR(result, overloaded_result); |
AI_SET_PTR(result->var, overloaded_result); | PZVAL_LOCK(overloaded_result); |
PZVAL_LOCK(overloaded_result); | |
} else if (Z_REFCOUNT_P(overloaded_result) == 0) { | |
/* Destroy unused result from offsetGet() magic method */ | |
Z_SET_REFCOUNT_P(overloaded_result, 1); | |
zval_ptr_dtor(&overloaded_result); | |
} | |
} else if (result) { |
} else if (result) { |
AI_SET_PTR(result->var, EG(uninitialized_zval_ptr)); | AI_SET_PTR(result, &EG(uninitialized_zval)); |
PZVAL_LOCK(EG(uninitialized_zval_ptr)); | PZVAL_LOCK(&EG(uninitialized_zval)); |
} |
} |
if (dim_is_tmp_var) { | if (dim_type == IS_TMP_VAR) { |
zval_ptr_dtor(&dim); |
zval_ptr_dtor(&dim); |
} |
} |
} |
} |
return; |
return; |
break; |
|
|
|
default: |
default: |
if (result) { | AI_SET_PTR(result, &EG(uninitialized_zval)); |
AI_SET_PTR(result->var, EG(uninitialized_zval_ptr)); | PZVAL_LOCK(&EG(uninitialized_zval)); |
PZVAL_LOCK(EG(uninitialized_zval_ptr)); | |
} | |
return; |
return; |
break; |
|
} |
} |
} |
} |
|
|
static void zend_fetch_property_address(temp_variable *result, zval **container_ptr, zval *prop_ptr, int type TSRMLS_DC) | static void zend_fetch_property_address(temp_variable *result, zval **container_ptr, zval *prop_ptr, const zend_literal *key, int type TSRMLS_DC) |
{ |
{ |
zval *container = *container_ptr;; |
zval *container = *container_ptr;; |
|
|
if (Z_TYPE_P(container) != IS_OBJECT) { |
if (Z_TYPE_P(container) != IS_OBJECT) { |
if (container == EG(error_zval_ptr)) { | if (container == &EG(error_zval)) { |
result->var.ptr_ptr = &EG(error_zval_ptr); |
result->var.ptr_ptr = &EG(error_zval_ptr); |
PZVAL_LOCK(*result->var.ptr_ptr); | PZVAL_LOCK(EG(error_zval_ptr)); |
return; |
return; |
} |
} |
|
|
Line 1165 static void zend_fetch_property_address(temp_variable
|
Line 1382 static void zend_fetch_property_address(temp_variable
|
} |
} |
|
|
if (Z_OBJ_HT_P(container)->get_property_ptr_ptr) { |
if (Z_OBJ_HT_P(container)->get_property_ptr_ptr) { |
zval **ptr_ptr = Z_OBJ_HT_P(container)->get_property_ptr_ptr(container, prop_ptr TSRMLS_CC); | zval **ptr_ptr = Z_OBJ_HT_P(container)->get_property_ptr_ptr(container, prop_ptr, key TSRMLS_CC); |
if (NULL == ptr_ptr) { |
if (NULL == ptr_ptr) { |
zval *ptr; |
zval *ptr; |
|
|
if (Z_OBJ_HT_P(container)->read_property && |
if (Z_OBJ_HT_P(container)->read_property && |
(ptr = Z_OBJ_HT_P(container)->read_property(container, prop_ptr, type TSRMLS_CC)) != NULL) { | (ptr = Z_OBJ_HT_P(container)->read_property(container, prop_ptr, type, key TSRMLS_CC)) != NULL) { |
AI_SET_PTR(result->var, ptr); | AI_SET_PTR(result, ptr); |
PZVAL_LOCK(ptr); |
PZVAL_LOCK(ptr); |
} else { |
} else { |
zend_error_noreturn(E_ERROR, "Cannot access undefined property for object with overloaded property access"); |
zend_error_noreturn(E_ERROR, "Cannot access undefined property for object with overloaded property access"); |
Line 1181 static void zend_fetch_property_address(temp_variable
|
Line 1398 static void zend_fetch_property_address(temp_variable
|
PZVAL_LOCK(*ptr_ptr); |
PZVAL_LOCK(*ptr_ptr); |
} |
} |
} else if (Z_OBJ_HT_P(container)->read_property) { |
} else if (Z_OBJ_HT_P(container)->read_property) { |
zval *ptr = Z_OBJ_HT_P(container)->read_property(container, prop_ptr, type TSRMLS_CC); | zval *ptr = Z_OBJ_HT_P(container)->read_property(container, prop_ptr, type, key TSRMLS_CC); |
|
|
AI_SET_PTR(result->var, ptr); | AI_SET_PTR(result, ptr); |
PZVAL_LOCK(ptr); |
PZVAL_LOCK(ptr); |
} else { |
} else { |
zend_error(E_WARNING, "This object doesn't support property references"); |
zend_error(E_WARNING, "This object doesn't support property references"); |
Line 1192 static void zend_fetch_property_address(temp_variable
|
Line 1409 static void zend_fetch_property_address(temp_variable
|
} |
} |
} |
} |
|
|
static inline zend_brk_cont_element* zend_brk_cont(const zval *nest_levels_zval, int array_offset, const zend_op_array *op_array, const temp_variable *Ts TSRMLS_DC) | static inline zend_brk_cont_element* zend_brk_cont(int nest_levels, int array_offset, const zend_op_array *op_array, const temp_variable *Ts TSRMLS_DC) |
{ |
{ |
zval tmp; | int original_nest_levels = nest_levels; |
int nest_levels, original_nest_levels; | |
zend_brk_cont_element *jmp_to; |
zend_brk_cont_element *jmp_to; |
|
|
if (nest_levels_zval->type != IS_LONG) { |
|
tmp = *nest_levels_zval; |
|
zval_copy_ctor(&tmp); |
|
convert_to_long(&tmp); |
|
nest_levels = tmp.value.lval; |
|
} else { |
|
nest_levels = nest_levels_zval->value.lval; |
|
} |
|
original_nest_levels = nest_levels; |
|
do { |
do { |
if (array_offset==-1) { |
if (array_offset==-1) { |
zend_error_noreturn(E_ERROR, "Cannot break/continue %d level%s", original_nest_levels, (original_nest_levels == 1) ? "" : "s"); |
zend_error_noreturn(E_ERROR, "Cannot break/continue %d level%s", original_nest_levels, (original_nest_levels == 1) ? "" : "s"); |
Line 1217 static inline zend_brk_cont_element* zend_brk_cont(con
|
Line 1424 static inline zend_brk_cont_element* zend_brk_cont(con
|
|
|
switch (brk_opline->opcode) { |
switch (brk_opline->opcode) { |
case ZEND_SWITCH_FREE: |
case ZEND_SWITCH_FREE: |
if (brk_opline->op1.u.EA.type != EXT_TYPE_FREE_ON_RETURN) { | if (!(brk_opline->extended_value & EXT_TYPE_FREE_ON_RETURN)) { |
zend_switch_free(&T(brk_opline->op1.u.var), brk_opline->extended_value TSRMLS_CC); | zval_ptr_dtor(&T(brk_opline->op1.var).var.ptr); |
} |
} |
break; |
break; |
case ZEND_FREE: |
case ZEND_FREE: |
if (brk_opline->op1.u.EA.type != EXT_TYPE_FREE_ON_RETURN) { | if (!(brk_opline->extended_value & EXT_TYPE_FREE_ON_RETURN)) { |
zendi_zval_dtor(T(brk_opline->op1.u.var).tmp_var); | zendi_zval_dtor(T(brk_opline->op1.var).tmp_var); |
} |
} |
break; |
break; |
} |
} |
Line 1269 ZEND_API opcode_handler_t *zend_opcode_handlers;
|
Line 1476 ZEND_API opcode_handler_t *zend_opcode_handlers;
|
|
|
ZEND_API void execute_internal(zend_execute_data *execute_data_ptr, int return_value_used TSRMLS_DC) |
ZEND_API void execute_internal(zend_execute_data *execute_data_ptr, int return_value_used TSRMLS_DC) |
{ |
{ |
zval **return_value_ptr = &(*(temp_variable *)((char *) execute_data_ptr->Ts + execute_data_ptr->opline->result.u.var)).var.ptr; | zval **return_value_ptr = &(*(temp_variable *)((char *) execute_data_ptr->Ts + execute_data_ptr->opline->result.var)).var.ptr; |
((zend_internal_function *) execute_data_ptr->function_state.function)->handler(execute_data_ptr->opline->extended_value, *return_value_ptr, execute_data_ptr->function_state.function->common.return_reference?return_value_ptr:NULL, execute_data_ptr->object, return_value_used TSRMLS_CC); | ((zend_internal_function *) execute_data_ptr->function_state.function)->handler(execute_data_ptr->opline->extended_value, *return_value_ptr, (execute_data_ptr->function_state.function->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)?return_value_ptr:NULL, execute_data_ptr->object, return_value_used TSRMLS_CC); |
} |
} |
|
|
#define ZEND_VM_NEXT_OPCODE() \ |
#define ZEND_VM_NEXT_OPCODE() \ |
CHECK_SYMBOL_TABLES() \ |
CHECK_SYMBOL_TABLES() \ |
EX(opline)++; \ | ZEND_VM_INC_OPCODE(); \ |
ZEND_VM_CONTINUE() |
ZEND_VM_CONTINUE() |
|
|
#define ZEND_VM_SET_OPCODE(new_op) \ |
#define ZEND_VM_SET_OPCODE(new_op) \ |
CHECK_SYMBOL_TABLES() \ |
CHECK_SYMBOL_TABLES() \ |
EX(opline) = new_op | OPLINE = new_op |
|
|
#define ZEND_VM_JMP(new_op) \ |
#define ZEND_VM_JMP(new_op) \ |
CHECK_SYMBOL_TABLES() \ |
|
if (EXPECTED(!EG(exception))) { \ |
if (EXPECTED(!EG(exception))) { \ |
EX(opline) = new_op; \ | ZEND_VM_SET_OPCODE(new_op); \ |
| } else { \ |
| LOAD_OPLINE(); \ |
} \ |
} \ |
ZEND_VM_CONTINUE() |
ZEND_VM_CONTINUE() |
|
|
#define ZEND_VM_INC_OPCODE() \ |
#define ZEND_VM_INC_OPCODE() \ |
EX(opline)++ | OPLINE++ |
|
|
|
#ifdef __GNUC__ |
|
# define ZEND_VM_GUARD(name) __asm__("#" #name) |
|
#else |
|
# define ZEND_VM_GUARD(name) |
|
#endif |
|
|
#include "zend_vm_execute.h" |
#include "zend_vm_execute.h" |
|
|
ZEND_API int zend_set_user_opcode_handler(zend_uchar opcode, user_opcode_handler_t handler) |
ZEND_API int zend_set_user_opcode_handler(zend_uchar opcode, user_opcode_handler_t handler) |
{ |
{ |
if (opcode != ZEND_USER_OPCODE) { |
if (opcode != ZEND_USER_OPCODE) { |
zend_user_opcodes[opcode] = ZEND_USER_OPCODE; | if (handler == NULL) { |
| /* restore the original handler */ |
| zend_user_opcodes[opcode] = opcode; |
| } else { |
| zend_user_opcodes[opcode] = ZEND_USER_OPCODE; |
| } |
zend_user_opcode_handlers[opcode] = handler; |
zend_user_opcode_handlers[opcode] = handler; |
return SUCCESS; |
return SUCCESS; |
} |
} |
Line 1309 ZEND_API user_opcode_handler_t zend_get_user_opcode_ha
|
Line 1528 ZEND_API user_opcode_handler_t zend_get_user_opcode_ha
|
return zend_user_opcode_handlers[opcode]; |
return zend_user_opcode_handlers[opcode]; |
} |
} |
|
|
ZEND_API zval *zend_get_zval_ptr(znode *node, const temp_variable *Ts, zend_free_op *should_free, int type TSRMLS_DC) { | ZEND_API zval *zend_get_zval_ptr(int op_type, const znode_op *node, const temp_variable *Ts, zend_free_op *should_free, int type TSRMLS_DC) { |
return get_zval_ptr(node, Ts, should_free, type); | return get_zval_ptr(op_type, node, Ts, should_free, type); |
} |
} |
|
|
ZEND_API zval **zend_get_zval_ptr_ptr(const znode *node, const temp_variable *Ts, zend_free_op *should_free, int type TSRMLS_DC) { | ZEND_API zval **zend_get_zval_ptr_ptr(int op_type, const znode_op *node, const temp_variable *Ts, zend_free_op *should_free, int type TSRMLS_DC) { |
return get_zval_ptr_ptr(node, Ts, should_free, type); | return get_zval_ptr_ptr(op_type, node, Ts, should_free, type); |
} |
} |
|
|
/* |
/* |