mirror of
https://github.com/php/php-src.git
synced 2025-08-15 21:48:51 +02:00
Always use IS_CONSTANT_AST (IS_CONSTANT is removed).
This commit is contained in:
parent
08c0998b1f
commit
ef5ea48741
31 changed files with 229 additions and 235 deletions
|
@ -13,7 +13,7 @@ PHP 7.2 INTERNALS UPGRADE NOTES
|
|||
j. Run-time constant operand addressing
|
||||
k. Array/Object recursion protection
|
||||
l. HASH_FLAG_PERSISTENT
|
||||
m. zend_ast_ref
|
||||
m. AST and IS_CONSTANT
|
||||
|
||||
2. Build system changes
|
||||
a. Unix build system changes
|
||||
|
@ -94,6 +94,11 @@ PHP 7.2 INTERNALS UPGRADE NOTES
|
|||
zend_ast_destroy_and_free() is removed. ZVAL_NEW_AST() is replaced
|
||||
by ZVAL_AST().
|
||||
|
||||
IS_CONSTANT type and Z_CONST_FLAGS() are removed. Now constants are always
|
||||
represented using IS_CONSTANT_AST (ZEND_AST_CONSTANT kind). AST node
|
||||
attributes are used instead of constant flags. IS_TYPE_CONSTANT flag is
|
||||
removed, but Z_CONSTANT() macro is kept for compatibility.
|
||||
|
||||
========================
|
||||
2. Build system changes
|
||||
========================
|
||||
|
|
|
@ -1150,7 +1150,7 @@ ZEND_API int zend_update_class_constants(zend_class_entry *class_type) /* {{{ */
|
|||
|
||||
ZEND_HASH_FOREACH_PTR(&class_type->constants_table, c) {
|
||||
val = &c->value;
|
||||
if (Z_CONSTANT_P(val)) {
|
||||
if (Z_TYPE_P(val) == IS_CONSTANT_AST) {
|
||||
if (UNEXPECTED(zval_update_constant_ex(val, c->ce) != SUCCESS)) {
|
||||
return FAILURE;
|
||||
}
|
||||
|
@ -1167,7 +1167,7 @@ ZEND_API int zend_update_class_constants(zend_class_entry *class_type) /* {{{ */
|
|||
val = (zval*)((char*)class_type->default_properties_table + prop_info->offset - OBJ_PROP_TO_OFFSET(0));
|
||||
}
|
||||
ZVAL_DEREF(val);
|
||||
if (Z_CONSTANT_P(val)) {
|
||||
if (Z_TYPE_P(val) == IS_CONSTANT_AST) {
|
||||
if (UNEXPECTED(zval_update_constant_ex(val, ce) != SUCCESS)) {
|
||||
return FAILURE;
|
||||
}
|
||||
|
@ -3685,12 +3685,12 @@ ZEND_API int zend_declare_property_ex(zend_class_entry *ce, zend_string *name, z
|
|||
|
||||
if (ce->type == ZEND_INTERNAL_CLASS) {
|
||||
property_info = pemalloc(sizeof(zend_property_info), 1);
|
||||
if ((access_type & ZEND_ACC_STATIC) || Z_CONSTANT_P(property)) {
|
||||
if ((access_type & ZEND_ACC_STATIC) || Z_TYPE_P(property) == IS_CONSTANT_AST) {
|
||||
ce->ce_flags &= ~ZEND_ACC_CONSTANTS_UPDATED;
|
||||
}
|
||||
} else {
|
||||
property_info = zend_arena_alloc(&CG(arena), sizeof(zend_property_info));
|
||||
if (Z_CONSTANT_P(property)) {
|
||||
if (Z_TYPE_P(property) == IS_CONSTANT_AST) {
|
||||
ce->ce_flags &= ~ZEND_ACC_CONSTANTS_UPDATED;
|
||||
}
|
||||
}
|
||||
|
@ -3846,7 +3846,7 @@ ZEND_API int zend_declare_class_constant_ex(zend_class_entry *ce, zend_string *n
|
|||
Z_ACCESS_FLAGS(c->value) = access_type;
|
||||
c->doc_comment = doc_comment;
|
||||
c->ce = ce;
|
||||
if (Z_CONSTANT_P(value)) {
|
||||
if (Z_TYPE_P(value) == IS_CONSTANT_AST) {
|
||||
ce->ce_flags &= ~ZEND_ACC_CONSTANTS_UPDATED;
|
||||
}
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "zend_language_parser.h"
|
||||
#include "zend_smart_str.h"
|
||||
#include "zend_exceptions.h"
|
||||
#include "zend_constants.h"
|
||||
|
||||
ZEND_API zend_ast_process_t zend_ast_process = NULL;
|
||||
|
||||
|
@ -72,6 +73,17 @@ ZEND_API zend_ast *zend_ast_create_zval_ex(zval *zv, zend_ast_attr attr) {
|
|||
return zend_ast_create_zval_with_lineno(zv, attr, CG(zend_lineno));
|
||||
}
|
||||
|
||||
ZEND_API zend_ast *zend_ast_create_constant(zend_string *name, zend_ast_attr attr) {
|
||||
zend_ast_zval *ast;
|
||||
|
||||
ast = zend_ast_alloc(sizeof(zend_ast_zval));
|
||||
ast->kind = ZEND_AST_CONSTANT;
|
||||
ast->attr = attr;
|
||||
ZVAL_STR(&ast->val, name);
|
||||
ast->val.u2.lineno = CG(zend_lineno);
|
||||
return (zend_ast *) ast;
|
||||
}
|
||||
|
||||
ZEND_API zend_ast *zend_ast_create_decl(
|
||||
zend_ast_kind kind, uint32_t flags, uint32_t start_lineno, zend_string *doc_comment,
|
||||
zend_string *name, zend_ast *child0, zend_ast *child1, zend_ast *child2, zend_ast *child3
|
||||
|
@ -276,25 +288,30 @@ ZEND_API int zend_ast_evaluate(zval *result, zend_ast *ast, zend_class_entry *sc
|
|||
{
|
||||
zval *zv = zend_ast_get_zval(ast);
|
||||
|
||||
if (Z_OPT_CONSTANT_P(zv)) {
|
||||
if (Z_TYPE_FLAGS_P(zv) & IS_TYPE_REFCOUNTED) {
|
||||
if (UNEXPECTED(zval_update_constant_ex(zv, scope) != SUCCESS)) {
|
||||
ret = FAILURE;
|
||||
break;
|
||||
}
|
||||
ZVAL_COPY(result, zv);
|
||||
} else {
|
||||
ZVAL_COPY_VALUE(result, zv);
|
||||
if (UNEXPECTED(zval_update_constant_ex(result, scope) != SUCCESS)) {
|
||||
ret = FAILURE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ZVAL_COPY(result, zv);
|
||||
}
|
||||
ZVAL_COPY(result, zv);
|
||||
break;
|
||||
}
|
||||
case ZEND_AST_CONSTANT:
|
||||
{
|
||||
zend_string *name = zend_ast_get_constant_name(ast);
|
||||
zval *zv = zend_get_constant_ex(name, scope, ast->attr);
|
||||
|
||||
if (UNEXPECTED(zv == NULL)) {
|
||||
ZVAL_UNDEF(result);
|
||||
ret = zend_use_undefined_constant(name, ast->attr, result);
|
||||
break;
|
||||
}
|
||||
ZVAL_DUP(result, zv);
|
||||
break;
|
||||
}
|
||||
case ZEND_AST_CONSTANT_CLASS:
|
||||
ZEND_ASSERT(EG(current_execute_data));
|
||||
if (scope && scope->name) {
|
||||
ZVAL_STR_COPY(result, scope->name);
|
||||
} else {
|
||||
ZVAL_EMPTY_STRING(result);
|
||||
}
|
||||
break;
|
||||
case ZEND_AST_AND:
|
||||
if (UNEXPECTED(zend_ast_evaluate(&op1, ast->child[0], scope) != SUCCESS)) {
|
||||
ret = FAILURE;
|
||||
|
@ -455,7 +472,7 @@ static size_t zend_ast_tree_size(zend_ast *ast)
|
|||
{
|
||||
size_t size;
|
||||
|
||||
if (ast->kind == ZEND_AST_ZVAL) {
|
||||
if (ast->kind == ZEND_AST_ZVAL || ast->kind == ZEND_AST_CONSTANT) {
|
||||
size = sizeof(zend_ast_zval);
|
||||
} else if (zend_ast_is_list(ast)) {
|
||||
uint32_t i;
|
||||
|
@ -488,6 +505,12 @@ static void* zend_ast_tree_copy(zend_ast *ast, void *buf)
|
|||
new->attr = ast->attr;
|
||||
ZVAL_COPY(&new->val, zend_ast_get_zval(ast));
|
||||
buf = (void*)((char*)buf + sizeof(zend_ast_zval));
|
||||
} else if (ast->kind == ZEND_AST_CONSTANT) {
|
||||
zend_ast_zval *new = (zend_ast_zval*)buf;
|
||||
new->kind = ZEND_AST_CONSTANT;
|
||||
new->attr = ast->attr;
|
||||
ZVAL_STR_COPY(&new->val, zend_ast_get_constant_name(ast));
|
||||
buf = (void*)((char*)buf + sizeof(zend_ast_zval));
|
||||
} else if (zend_ast_is_list(ast)) {
|
||||
zend_ast_list *list = zend_ast_get_list(ast);
|
||||
zend_ast_list *new = (zend_ast_list*)buf;
|
||||
|
@ -548,6 +571,9 @@ ZEND_API void zend_ast_destroy(zend_ast *ast) {
|
|||
* become invalid. GC would cause such a reference in the root buffer. */
|
||||
zval_ptr_dtor_nogc(zend_ast_get_zval(ast));
|
||||
break;
|
||||
case ZEND_AST_CONSTANT:
|
||||
zend_string_release(zend_ast_get_constant_name(ast));
|
||||
break;
|
||||
case ZEND_AST_FUNC_DECL:
|
||||
case ZEND_AST_CLOSURE:
|
||||
case ZEND_AST_METHOD:
|
||||
|
@ -996,9 +1022,6 @@ static void zend_ast_export_zval(smart_str *str, zval *zv, int priority, int ind
|
|||
} ZEND_HASH_FOREACH_END();
|
||||
smart_str_appendc(str, ']');
|
||||
break;
|
||||
case IS_CONSTANT:
|
||||
smart_str_appendl(str, Z_STRVAL_P(zv), Z_STRLEN_P(zv));
|
||||
break;
|
||||
case IS_CONSTANT_AST:
|
||||
zend_ast_export_ex(str, Z_ASTVAL_P(zv), priority, indent);
|
||||
break;
|
||||
|
@ -1078,6 +1101,14 @@ tail_call:
|
|||
case ZEND_AST_ZVAL:
|
||||
zend_ast_export_zval(str, zend_ast_get_zval(ast), priority, indent);
|
||||
break;
|
||||
case ZEND_AST_CONSTANT: {
|
||||
zend_string *name = zend_ast_get_constant_name(ast);
|
||||
smart_str_appendl(str, ZSTR_VAL(name), ZSTR_LEN(name));
|
||||
break;
|
||||
}
|
||||
case ZEND_AST_CONSTANT_CLASS:
|
||||
smart_str_appendl(str, "__CLASS__", sizeof("__CLASS__")-1);
|
||||
break;
|
||||
case ZEND_AST_ZNODE:
|
||||
/* This AST kind is only used for temporary nodes during compilation */
|
||||
ZEND_ASSERT(0);
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
enum _zend_ast_kind {
|
||||
/* special nodes */
|
||||
ZEND_AST_ZVAL = 1 << ZEND_AST_SPECIAL_SHIFT,
|
||||
ZEND_AST_CONSTANT,
|
||||
ZEND_AST_ZNODE,
|
||||
|
||||
/* declaration nodes */
|
||||
|
@ -61,6 +62,7 @@ enum _zend_ast_kind {
|
|||
/* 0 child nodes */
|
||||
ZEND_AST_MAGIC_CONST = 0 << ZEND_AST_NUM_CHILDREN_SHIFT,
|
||||
ZEND_AST_TYPE,
|
||||
ZEND_AST_CONSTANT_CLASS,
|
||||
|
||||
/* 1 child node */
|
||||
ZEND_AST_VAR = 1 << ZEND_AST_NUM_CHILDREN_SHIFT,
|
||||
|
@ -192,6 +194,8 @@ extern ZEND_API zend_ast_process_t zend_ast_process;
|
|||
ZEND_API zend_ast *zend_ast_create_zval_with_lineno(zval *zv, zend_ast_attr attr, uint32_t lineno);
|
||||
ZEND_API zend_ast *zend_ast_create_zval_ex(zval *zv, zend_ast_attr attr);
|
||||
|
||||
ZEND_API zend_ast *zend_ast_create_constant(zend_string *name, zend_ast_attr attr);
|
||||
|
||||
ZEND_API zend_ast *zend_ast_create_ex(zend_ast_kind kind, zend_ast_attr attr, ...);
|
||||
ZEND_API zend_ast *zend_ast_create(zend_ast_kind kind, ...);
|
||||
|
||||
|
@ -230,6 +234,12 @@ static zend_always_inline zend_string *zend_ast_get_str(zend_ast *ast) {
|
|||
return Z_STR_P(zv);
|
||||
}
|
||||
|
||||
static zend_always_inline zend_string *zend_ast_get_constant_name(zend_ast *ast) {
|
||||
ZEND_ASSERT(ast->kind == ZEND_AST_CONSTANT);
|
||||
ZEND_ASSERT(Z_TYPE(((zend_ast_zval *) ast)->val) == IS_STRING);
|
||||
return Z_STR(((zend_ast_zval *) ast)->val);
|
||||
}
|
||||
|
||||
static zend_always_inline uint32_t zend_ast_get_num_children(zend_ast *ast) {
|
||||
ZEND_ASSERT(!zend_ast_is_list(ast));
|
||||
return ast->kind >> ZEND_AST_NUM_CHILDREN_SHIFT;
|
||||
|
|
|
@ -1071,7 +1071,7 @@ static void add_class_vars(zend_class_entry *scope, zend_class_entry *ce, int st
|
|||
|
||||
/* this is necessary to make it able to work with default array
|
||||
* properties, returned to user */
|
||||
if (Z_OPT_CONSTANT_P(prop)) {
|
||||
if (Z_OPT_TYPE_P(prop) == IS_CONSTANT_AST) {
|
||||
if (UNEXPECTED(zval_update_constant_ex(prop, NULL) != SUCCESS)) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -460,7 +460,7 @@ void zend_del_literal(zend_op_array *op_array, int n) /* {{{ */
|
|||
/* Common part of zend_add_literal and zend_append_individual_literal */
|
||||
static inline void zend_insert_literal(zend_op_array *op_array, zval *zv, int literal_position) /* {{{ */
|
||||
{
|
||||
if (Z_TYPE_P(zv) == IS_STRING || Z_TYPE_P(zv) == IS_CONSTANT) {
|
||||
if (Z_TYPE_P(zv) == IS_STRING) {
|
||||
zend_string_hash_val(Z_STR_P(zv));
|
||||
Z_STR_P(zv) = zend_new_interned_string(Z_STR_P(zv));
|
||||
if (ZSTR_IS_INTERNED(Z_STR_P(zv))) {
|
||||
|
@ -5518,8 +5518,9 @@ void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast) /* {{{ */
|
|||
zend_bool allow_null;
|
||||
zend_bool has_null_default = default_ast
|
||||
&& (Z_TYPE(default_node.u.constant) == IS_NULL
|
||||
|| (Z_TYPE(default_node.u.constant) == IS_CONSTANT
|
||||
&& strcasecmp(Z_STRVAL(default_node.u.constant), "NULL") == 0));
|
||||
|| (Z_TYPE(default_node.u.constant) == IS_CONSTANT_AST
|
||||
&& Z_ASTVAL(default_node.u.constant)->kind == ZEND_AST_CONSTANT
|
||||
&& strcasecmp(ZSTR_VAL(zend_ast_get_constant_name(Z_ASTVAL(default_node.u.constant))), "NULL") == 0));
|
||||
zend_bool is_explicitly_nullable = (type_ast->attr & ZEND_TYPE_NULLABLE) == ZEND_TYPE_NULLABLE;
|
||||
|
||||
op_array->fn_flags |= ZEND_ACC_HAS_TYPE_HINTS;
|
||||
|
@ -5536,19 +5537,19 @@ void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast) /* {{{ */
|
|||
if (ZEND_TYPE_CODE(arg_info->type) == IS_ARRAY) {
|
||||
if (default_ast && !has_null_default
|
||||
&& Z_TYPE(default_node.u.constant) != IS_ARRAY
|
||||
&& !Z_CONSTANT(default_node.u.constant)
|
||||
&& Z_TYPE(default_node.u.constant) != IS_CONSTANT_AST
|
||||
) {
|
||||
zend_error_noreturn(E_COMPILE_ERROR, "Default value for parameters "
|
||||
"with array type can only be an array or NULL");
|
||||
}
|
||||
} else if (ZEND_TYPE_CODE(arg_info->type) == IS_CALLABLE && default_ast) {
|
||||
if (!has_null_default && !Z_CONSTANT(default_node.u.constant)) {
|
||||
if (!has_null_default && Z_TYPE(default_node.u.constant) != IS_CONSTANT_AST) {
|
||||
zend_error_noreturn(E_COMPILE_ERROR, "Default value for parameters "
|
||||
"with callable type can only be NULL");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (default_ast && !has_null_default && !Z_CONSTANT(default_node.u.constant)) {
|
||||
if (default_ast && !has_null_default && Z_TYPE(default_node.u.constant) != IS_CONSTANT_AST) {
|
||||
if (ZEND_TYPE_IS_CLASS(arg_info->type)) {
|
||||
zend_error_noreturn(E_COMPILE_ERROR, "Default value for parameters "
|
||||
"with a class type can only be NULL");
|
||||
|
@ -7916,6 +7917,7 @@ void zend_compile_const_expr_class_const(zend_ast **ast_ptr) /* {{{ */
|
|||
zend_ast *const_ast = ast->child[1];
|
||||
zend_string *class_name;
|
||||
zend_string *const_name = zend_ast_get_str(const_ast);
|
||||
zend_string *name;
|
||||
zval result;
|
||||
int fetch_type;
|
||||
|
||||
|
@ -7943,16 +7945,13 @@ void zend_compile_const_expr_class_const(zend_ast **ast_ptr) /* {{{ */
|
|||
zend_string_addref(class_name);
|
||||
}
|
||||
|
||||
Z_STR(result) = zend_concat3(
|
||||
name = zend_concat3(
|
||||
ZSTR_VAL(class_name), ZSTR_LEN(class_name), "::", 2, ZSTR_VAL(const_name), ZSTR_LEN(const_name));
|
||||
|
||||
Z_TYPE_INFO(result) = IS_CONSTANT_EX;
|
||||
Z_CONST_FLAGS(result) = fetch_type;
|
||||
|
||||
zend_ast_destroy(ast);
|
||||
zend_string_release(class_name);
|
||||
|
||||
*ast_ptr = zend_ast_create_zval(&result);
|
||||
*ast_ptr = zend_ast_create_constant(name, fetch_type);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
@ -7962,25 +7961,21 @@ void zend_compile_const_expr_const(zend_ast **ast_ptr) /* {{{ */
|
|||
zend_ast *name_ast = ast->child[0];
|
||||
zend_string *orig_name = zend_ast_get_str(name_ast);
|
||||
zend_bool is_fully_qualified;
|
||||
zval result;
|
||||
zend_string *resolved_name;
|
||||
|
||||
zval result, resolved_name;
|
||||
ZVAL_STR(&resolved_name, zend_resolve_const_name(
|
||||
orig_name, name_ast->attr, &is_fully_qualified));
|
||||
resolved_name = zend_resolve_const_name(
|
||||
orig_name, name_ast->attr, &is_fully_qualified);
|
||||
|
||||
if (zend_try_ct_eval_const(&result, Z_STR(resolved_name), is_fully_qualified)) {
|
||||
zend_string_release(Z_STR(resolved_name));
|
||||
if (zend_try_ct_eval_const(&result, resolved_name, is_fully_qualified)) {
|
||||
zend_string_release(resolved_name);
|
||||
zend_ast_destroy(ast);
|
||||
*ast_ptr = zend_ast_create_zval(&result);
|
||||
return;
|
||||
}
|
||||
|
||||
Z_TYPE_INFO(resolved_name) = IS_CONSTANT_EX;
|
||||
if (!is_fully_qualified) {
|
||||
Z_CONST_FLAGS(resolved_name) = IS_CONSTANT_UNQUALIFIED;
|
||||
}
|
||||
|
||||
zend_ast_destroy(ast);
|
||||
*ast_ptr = zend_ast_create_zval(&resolved_name);
|
||||
*ast_ptr = zend_ast_create_constant(resolved_name, !is_fully_qualified ? IS_CONSTANT_UNQUALIFIED : 0);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
@ -7993,14 +7988,8 @@ void zend_compile_const_expr_magic_const(zend_ast **ast_ptr) /* {{{ */
|
|||
CG(active_class_entry) &&
|
||||
(CG(active_class_entry)->ce_flags & ZEND_ACC_TRAIT) != 0);
|
||||
|
||||
{
|
||||
zval const_zv;
|
||||
Z_STR(const_zv) = zend_string_init("__CLASS__", sizeof("__CLASS__")-1, 0);
|
||||
Z_TYPE_INFO(const_zv) = IS_CONSTANT_EX | (IS_CONSTANT_CLASS << Z_CONST_FLAGS_SHIFT);
|
||||
|
||||
zend_ast_destroy(ast);
|
||||
*ast_ptr = zend_ast_create_zval(&const_zv);
|
||||
}
|
||||
zend_ast_destroy(ast);
|
||||
*ast_ptr = zend_ast_create_ex(ZEND_AST_CONSTANT_CLASS, 0);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
|
|
@ -886,6 +886,10 @@ void zend_assert_valid_class_name(const zend_string *const_name);
|
|||
|
||||
#define ZEND_DIM_IS 1
|
||||
|
||||
#define IS_CONSTANT_UNQUALIFIED 0x010
|
||||
#define IS_CONSTANT_CLASS 0x080 /* __CLASS__ in trait */
|
||||
#define IS_CONSTANT_IN_NAMESPACE 0x100
|
||||
|
||||
static zend_always_inline int zend_check_arg_send_type(const zend_function *zf, uint32_t arg_num, uint32_t mask)
|
||||
{
|
||||
arg_num--;
|
||||
|
|
|
@ -348,7 +348,7 @@ ZEND_API zval *zend_get_constant_ex(zend_string *cname, zend_class_entry *scope,
|
|||
}
|
||||
}
|
||||
|
||||
if (ret_constant && Z_CONSTANT_P(ret_constant)) {
|
||||
if (ret_constant && Z_TYPE_P(ret_constant) == IS_CONSTANT_AST) {
|
||||
if (Z_TYPE_P(ret_constant) == IS_CONSTANT_AST) {
|
||||
if (IS_CONSTANT_VISITED(ret_constant)) {
|
||||
zend_throw_error(NULL, "Cannot declare self-referencing constant '%s::%s'", ZSTR_VAL(class_name), ZSTR_VAL(constant_name));
|
||||
|
|
|
@ -729,7 +729,7 @@ static ZEND_COLD void zend_verify_arg_error(
|
|||
|
||||
static int is_null_constant(zend_class_entry *scope, zval *default_value)
|
||||
{
|
||||
if (Z_CONSTANT_P(default_value)) {
|
||||
if (Z_TYPE_P(default_value) == IS_CONSTANT_AST) {
|
||||
zval constant;
|
||||
|
||||
ZVAL_COPY(&constant, default_value);
|
||||
|
|
|
@ -131,6 +131,7 @@ static zend_always_inline zval* zend_assign_to_variable(zval *variable_ptr, zval
|
|||
|
||||
ZEND_API int zval_update_constant(zval *pp);
|
||||
ZEND_API int zval_update_constant_ex(zval *pp, zend_class_entry *scope);
|
||||
ZEND_API int zend_use_undefined_constant(zend_string *name, zend_ast_attr attr, zval *result);
|
||||
|
||||
/* dedicated Zend executor functions - do not use! */
|
||||
struct _zend_vm_stack {
|
||||
|
|
|
@ -542,90 +542,63 @@ ZEND_API void _zval_internal_ptr_dtor(zval *zval_ptr ZEND_FILE_LINE_DC) /* {{{ *
|
|||
}
|
||||
/* }}} */
|
||||
|
||||
ZEND_API int zend_use_undefined_constant(zend_string *name, zend_ast_attr attr, zval *result) /* {{{ */
|
||||
{
|
||||
char *colon;
|
||||
|
||||
if (UNEXPECTED(EG(exception))) {
|
||||
return FAILURE;
|
||||
} else if ((colon = (char*)zend_memrchr(ZSTR_VAL(name), ':', ZSTR_LEN(name)))) {
|
||||
zend_throw_error(NULL, "Undefined class constant '%s'", ZSTR_VAL(name));
|
||||
return FAILURE;
|
||||
} else if ((attr & IS_CONSTANT_UNQUALIFIED) == 0) {
|
||||
zend_throw_error(NULL, "Undefined constant '%s'", ZSTR_VAL(name));
|
||||
return FAILURE;
|
||||
} else {
|
||||
char *actual = ZSTR_VAL(name);
|
||||
size_t actual_len = ZSTR_LEN(name);
|
||||
char *slash = (char *) zend_memrchr(actual, '\\', actual_len);
|
||||
|
||||
if (slash) {
|
||||
actual = slash + 1;
|
||||
actual_len -= (actual - ZSTR_VAL(name));
|
||||
}
|
||||
|
||||
zend_error(E_WARNING, "Use of undefined constant %s - assumed '%s' (this will throw an Error in a future version of PHP)", actual, actual);
|
||||
if (EG(exception)) {
|
||||
return FAILURE;
|
||||
} else {
|
||||
zval_ptr_dtor_nogc(result);
|
||||
ZVAL_STRINGL(result, actual, actual_len);
|
||||
}
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
ZEND_API int zval_update_constant_ex(zval *p, zend_class_entry *scope) /* {{{ */
|
||||
{
|
||||
zval *const_value;
|
||||
char *colon;
|
||||
zend_bool inline_change;
|
||||
if (Z_TYPE_P(p) == IS_CONSTANT_AST) {
|
||||
zend_ast *ast = Z_ASTVAL_P(p);
|
||||
|
||||
if (Z_TYPE_P(p) == IS_CONSTANT) {
|
||||
if (IS_CONSTANT_VISITED(p)) {
|
||||
zend_throw_error(NULL, "Cannot declare self-referencing constant '%s'", Z_STRVAL_P(p));
|
||||
return FAILURE;
|
||||
}
|
||||
inline_change = (Z_TYPE_FLAGS_P(p) & IS_TYPE_REFCOUNTED) != 0;
|
||||
SEPARATE_ZVAL_NOREF(p);
|
||||
MARK_CONSTANT_VISITED(p);
|
||||
if (Z_CONST_FLAGS_P(p) & IS_CONSTANT_CLASS) {
|
||||
ZEND_ASSERT(EG(current_execute_data));
|
||||
if (inline_change) {
|
||||
zend_string_release(Z_STR_P(p));
|
||||
}
|
||||
if (scope && scope->name) {
|
||||
ZVAL_STR_COPY(p, scope->name);
|
||||
} else {
|
||||
ZVAL_EMPTY_STRING(p);
|
||||
}
|
||||
} else if (UNEXPECTED((const_value = zend_get_constant_ex(Z_STR_P(p), scope, Z_CONST_FLAGS_P(p))) == NULL)) {
|
||||
if (UNEXPECTED(EG(exception))) {
|
||||
RESET_CONSTANT_VISITED(p);
|
||||
return FAILURE;
|
||||
} else if ((colon = (char*)zend_memrchr(Z_STRVAL_P(p), ':', Z_STRLEN_P(p)))) {
|
||||
zend_throw_error(NULL, "Undefined class constant '%s'", Z_STRVAL_P(p));
|
||||
RESET_CONSTANT_VISITED(p);
|
||||
return FAILURE;
|
||||
} else {
|
||||
if ((Z_CONST_FLAGS_P(p) & IS_CONSTANT_UNQUALIFIED) == 0) {
|
||||
zend_throw_error(NULL, "Undefined constant '%s'", Z_STRVAL_P(p));
|
||||
RESET_CONSTANT_VISITED(p);
|
||||
return FAILURE;
|
||||
} else {
|
||||
zend_string *save = Z_STR_P(p);
|
||||
char *actual = Z_STRVAL_P(p);
|
||||
size_t actual_len = Z_STRLEN_P(p);
|
||||
char *slash = (char *) zend_memrchr(actual, '\\', actual_len);
|
||||
if (slash) {
|
||||
actual = slash + 1;
|
||||
actual_len -= (actual - Z_STRVAL_P(p));
|
||||
}
|
||||
if (ast->kind == ZEND_AST_CONSTANT) {
|
||||
zend_string *name = zend_ast_get_constant_name(ast);
|
||||
zval *zv = zend_get_constant_ex(name, scope, ast->attr);
|
||||
|
||||
zend_error(E_WARNING, "Use of undefined constant %s - assumed '%s' (this will throw an Error in a future version of PHP)", actual, actual);
|
||||
if (EG(exception)) {
|
||||
RESET_CONSTANT_VISITED(p);
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
if (!inline_change) {
|
||||
ZVAL_STRINGL(p, actual, actual_len);
|
||||
} else {
|
||||
if (slash) {
|
||||
ZVAL_STRINGL(p, actual, actual_len);
|
||||
zend_string_release(save);
|
||||
} else {
|
||||
Z_TYPE_INFO_P(p) = Z_REFCOUNTED_P(p) ?
|
||||
IS_STRING_EX : IS_INTERNED_STRING_EX;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (UNEXPECTED(zv == NULL)) {
|
||||
return zend_use_undefined_constant(name, ast->attr, p);
|
||||
}
|
||||
} else {
|
||||
if (inline_change) {
|
||||
zend_string_release(Z_STR_P(p));
|
||||
}
|
||||
ZVAL_COPY_VALUE(p, const_value);
|
||||
zval_opt_copy_ctor(p);
|
||||
}
|
||||
} else if (Z_TYPE_P(p) == IS_CONSTANT_AST) {
|
||||
zval tmp;
|
||||
|
||||
inline_change = (Z_TYPE_FLAGS_P(p) & IS_TYPE_REFCOUNTED) != 0;
|
||||
if (UNEXPECTED(zend_ast_evaluate(&tmp, Z_ASTVAL_P(p), scope) != SUCCESS)) {
|
||||
return FAILURE;
|
||||
}
|
||||
if (inline_change) {
|
||||
zval_ptr_dtor_nogc(p);
|
||||
ZVAL_DUP(p, zv);
|
||||
} else {
|
||||
zval tmp;
|
||||
|
||||
if (UNEXPECTED(zend_ast_evaluate(&tmp, ast, scope) != SUCCESS)) {
|
||||
return FAILURE;
|
||||
}
|
||||
zval_ptr_dtor_nogc(p);
|
||||
ZVAL_COPY_VALUE(p, &tmp);
|
||||
}
|
||||
ZVAL_COPY_VALUE(p, &tmp);
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
|
|
|
@ -497,9 +497,7 @@ static ZEND_COLD zend_string *zend_get_function_declaration(const zend_function
|
|||
if (precv && precv->opcode == ZEND_RECV_INIT && precv->op2_type != IS_UNUSED) {
|
||||
zval *zv = RT_CONSTANT(precv, precv->op2);
|
||||
|
||||
if (Z_TYPE_P(zv) == IS_CONSTANT) {
|
||||
smart_str_append(&str, Z_STR_P(zv));
|
||||
} else if (Z_TYPE_P(zv) == IS_FALSE) {
|
||||
if (Z_TYPE_P(zv) == IS_FALSE) {
|
||||
smart_str_appends(&str, "false");
|
||||
} else if (Z_TYPE_P(zv) == IS_TRUE) {
|
||||
smart_str_appends(&str, "true");
|
||||
|
@ -515,7 +513,12 @@ static ZEND_COLD zend_string *zend_get_function_declaration(const zend_function
|
|||
} else if (Z_TYPE_P(zv) == IS_ARRAY) {
|
||||
smart_str_appends(&str, "Array");
|
||||
} else if (Z_TYPE_P(zv) == IS_CONSTANT_AST) {
|
||||
smart_str_appends(&str, "<expression>");
|
||||
zend_ast *ast = Z_ASTVAL_P(zv);
|
||||
if (ast->kind == ZEND_AST_CONSTANT) {
|
||||
smart_str_append(&str, zend_ast_get_constant_name(ast));
|
||||
} else {
|
||||
smart_str_appends(&str, "<expression>");
|
||||
}
|
||||
} else {
|
||||
zend_string *zv_str = zval_get_string(zv);
|
||||
smart_str_append(&str, zv_str);
|
||||
|
@ -769,7 +772,7 @@ static void do_inherit_class_constant(zend_string *name, zend_class_constant *pa
|
|||
ZSTR_VAL(ce->name), ZSTR_VAL(name), zend_visibility_string(Z_ACCESS_FLAGS(parent_const->value)), ZSTR_VAL(ce->parent->name), (Z_ACCESS_FLAGS(parent_const->value) & ZEND_ACC_PUBLIC) ? "" : " or weaker");
|
||||
}
|
||||
} else if (!(Z_ACCESS_FLAGS(parent_const->value) & ZEND_ACC_PRIVATE)) {
|
||||
if (Z_CONSTANT(parent_const->value)) {
|
||||
if (Z_TYPE(parent_const->value) == IS_CONSTANT_AST) {
|
||||
ce->ce_flags &= ~ZEND_ACC_CONSTANTS_UPDATED;
|
||||
}
|
||||
if (ce->type & ZEND_INTERNAL_CLASS) {
|
||||
|
@ -845,7 +848,7 @@ ZEND_API void zend_do_inheritance(zend_class_entry *ce, zend_class_entry *parent
|
|||
#ifdef ZTS
|
||||
if (parent_ce->type != ce->type) {
|
||||
ZVAL_DUP(dst, src);
|
||||
if (Z_OPT_CONSTANT_P(dst)) {
|
||||
if (Z_OPT_TYPE_P(dst) == IS_CONSTANT_AST) {
|
||||
ce->ce_flags &= ~ZEND_ACC_CONSTANTS_UPDATED;
|
||||
}
|
||||
continue;
|
||||
|
@ -853,7 +856,7 @@ ZEND_API void zend_do_inheritance(zend_class_entry *ce, zend_class_entry *parent
|
|||
#endif
|
||||
|
||||
ZVAL_COPY(dst, src);
|
||||
if (Z_OPT_CONSTANT_P(dst)) {
|
||||
if (Z_OPT_TYPE_P(dst) == IS_CONSTANT_AST) {
|
||||
ce->ce_flags &= ~ZEND_ACC_CONSTANTS_UPDATED;
|
||||
}
|
||||
} while (dst != end);
|
||||
|
@ -894,7 +897,7 @@ ZEND_API void zend_do_inheritance(zend_class_entry *ce, zend_class_entry *parent
|
|||
}
|
||||
ZVAL_COPY_VALUE(dst, src);
|
||||
Z_ADDREF_P(dst);
|
||||
if (Z_CONSTANT_P(Z_REFVAL_P(dst))) {
|
||||
if (Z_TYPE_P(Z_REFVAL_P(dst)) == IS_CONSTANT_AST) {
|
||||
ce->ce_flags &= ~ZEND_ACC_CONSTANTS_UPDATED;
|
||||
}
|
||||
} while (dst != end);
|
||||
|
@ -982,7 +985,7 @@ static void do_inherit_iface_constant(zend_string *name, zend_class_constant *c,
|
|||
{
|
||||
if (do_inherit_constant_check(&ce->constants_table, c, name, iface)) {
|
||||
zend_class_constant *ct;
|
||||
if (Z_CONSTANT(c->value)) {
|
||||
if (Z_TYPE(c->value) == IS_CONSTANT_AST) {
|
||||
ce->ce_flags &= ~ZEND_ACC_CONSTANTS_UPDATED;
|
||||
}
|
||||
if (ce->type & ZEND_INTERNAL_CLASS) {
|
||||
|
|
|
@ -183,8 +183,8 @@ struct _zval_struct {
|
|||
ZEND_ENDIAN_LOHI_4(
|
||||
zend_uchar type, /* active type */
|
||||
zend_uchar type_flags,
|
||||
zend_uchar const_flags,
|
||||
zend_uchar reserved) /* call info for EX(This) */
|
||||
zend_uchar _unused,
|
||||
zend_uchar _reserved) /* call info for EX(This) */
|
||||
} v;
|
||||
uint32_t type_info;
|
||||
} u1;
|
||||
|
@ -372,7 +372,6 @@ struct _zend_ast_ref {
|
|||
#define IS_REFERENCE 10
|
||||
|
||||
/* constant expressions */
|
||||
#define IS_CONSTANT 11
|
||||
#define IS_CONSTANT_AST 12
|
||||
|
||||
/* fake types */
|
||||
|
@ -402,9 +401,6 @@ static zend_always_inline zend_uchar zval_get_type(const zval* pz) {
|
|||
#define Z_TYPE_FLAGS(zval) (zval).u1.v.type_flags
|
||||
#define Z_TYPE_FLAGS_P(zval_p) Z_TYPE_FLAGS(*(zval_p))
|
||||
|
||||
#define Z_CONST_FLAGS(zval) (zval).u1.v.const_flags
|
||||
#define Z_CONST_FLAGS_P(zval_p) Z_CONST_FLAGS(*(zval_p))
|
||||
|
||||
#define Z_TYPE_INFO(zval) (zval).u1.type_info
|
||||
#define Z_TYPE_INFO_P(zval_p) Z_TYPE_INFO(*(zval_p))
|
||||
|
||||
|
@ -432,7 +428,6 @@ static zend_always_inline zend_uchar zval_get_type(const zval* pz) {
|
|||
#define Z_TYPE_MASK 0xff
|
||||
|
||||
#define Z_TYPE_FLAGS_SHIFT 8
|
||||
#define Z_CONST_FLAGS_SHIFT 16
|
||||
|
||||
#define GC_REFCOUNT(p) (p)->gc.refcount
|
||||
#define GC_TYPE(p) (p)->gc.u.v.type
|
||||
|
@ -465,31 +460,24 @@ static zend_always_inline zend_uchar zval_get_type(const zval* pz) {
|
|||
#define GC_OBJECT (IS_OBJECT | (GC_COLLECTABLE << GC_FLAGS_SHIFT))
|
||||
|
||||
/* zval.u1.v.type_flags */
|
||||
#define IS_TYPE_CONSTANT (1<<0)
|
||||
#define IS_TYPE_REFCOUNTED (1<<2)
|
||||
#define IS_TYPE_COPYABLE (1<<4)
|
||||
#define IS_CONSTANT_VISITED_MARK (1<<5)
|
||||
|
||||
/* extended types */
|
||||
#define IS_INTERNED_STRING_EX IS_STRING
|
||||
|
||||
#define IS_STRING_EX (IS_STRING | (( IS_TYPE_REFCOUNTED | IS_TYPE_COPYABLE) << Z_TYPE_FLAGS_SHIFT))
|
||||
#define IS_ARRAY_EX (IS_ARRAY | (( IS_TYPE_REFCOUNTED | IS_TYPE_COPYABLE) << Z_TYPE_FLAGS_SHIFT))
|
||||
#define IS_OBJECT_EX (IS_OBJECT | (( IS_TYPE_REFCOUNTED ) << Z_TYPE_FLAGS_SHIFT))
|
||||
#define IS_RESOURCE_EX (IS_RESOURCE | (( IS_TYPE_REFCOUNTED ) << Z_TYPE_FLAGS_SHIFT))
|
||||
#define IS_REFERENCE_EX (IS_REFERENCE | (( IS_TYPE_REFCOUNTED ) << Z_TYPE_FLAGS_SHIFT))
|
||||
#define IS_STRING_EX (IS_STRING | ((IS_TYPE_REFCOUNTED | IS_TYPE_COPYABLE) << Z_TYPE_FLAGS_SHIFT))
|
||||
#define IS_ARRAY_EX (IS_ARRAY | ((IS_TYPE_REFCOUNTED | IS_TYPE_COPYABLE) << Z_TYPE_FLAGS_SHIFT))
|
||||
#define IS_OBJECT_EX (IS_OBJECT | ((IS_TYPE_REFCOUNTED ) << Z_TYPE_FLAGS_SHIFT))
|
||||
#define IS_RESOURCE_EX (IS_RESOURCE | ((IS_TYPE_REFCOUNTED ) << Z_TYPE_FLAGS_SHIFT))
|
||||
#define IS_REFERENCE_EX (IS_REFERENCE | ((IS_TYPE_REFCOUNTED ) << Z_TYPE_FLAGS_SHIFT))
|
||||
|
||||
#define IS_CONSTANT_EX (IS_CONSTANT | ((IS_TYPE_CONSTANT | IS_TYPE_REFCOUNTED | IS_TYPE_COPYABLE) << Z_TYPE_FLAGS_SHIFT))
|
||||
#define IS_CONSTANT_AST_EX (IS_CONSTANT_AST | ((IS_TYPE_CONSTANT | IS_TYPE_REFCOUNTED | IS_TYPE_COPYABLE) << Z_TYPE_FLAGS_SHIFT))
|
||||
#define IS_CONSTANT_AST_EX (IS_CONSTANT_AST | ((IS_TYPE_REFCOUNTED | IS_TYPE_COPYABLE) << Z_TYPE_FLAGS_SHIFT))
|
||||
|
||||
/* zval.u1.v.const_flags */
|
||||
#define IS_CONSTANT_UNQUALIFIED 0x010
|
||||
#define IS_CONSTANT_VISITED_MARK 0x020
|
||||
#define IS_CONSTANT_CLASS 0x080 /* __CLASS__ in trait */
|
||||
#define IS_CONSTANT_IN_NAMESPACE 0x100 /* used only in opline->extended_value */
|
||||
|
||||
#define IS_CONSTANT_VISITED(p) (Z_CONST_FLAGS_P(p) & IS_CONSTANT_VISITED_MARK)
|
||||
#define MARK_CONSTANT_VISITED(p) Z_CONST_FLAGS_P(p) |= IS_CONSTANT_VISITED_MARK
|
||||
#define RESET_CONSTANT_VISITED(p) Z_CONST_FLAGS_P(p) &= ~IS_CONSTANT_VISITED_MARK
|
||||
#define IS_CONSTANT_VISITED(p) (Z_TYPE_FLAGS_P(p) & IS_CONSTANT_VISITED_MARK)
|
||||
#define MARK_CONSTANT_VISITED(p) Z_TYPE_FLAGS_P(p) |= IS_CONSTANT_VISITED_MARK
|
||||
#define RESET_CONSTANT_VISITED(p) Z_TYPE_FLAGS_P(p) &= ~IS_CONSTANT_VISITED_MARK
|
||||
|
||||
/* string flags (zval.value->gc.u.flags) */
|
||||
#define IS_STR_INTERNED GC_IMMUTABLE /* interned string */
|
||||
|
@ -526,7 +514,7 @@ static zend_always_inline zend_uchar zval_get_type(const zval* pz) {
|
|||
#define Z_UNPROTECT_RECURSION_P(zv) Z_UNPROTECT_RECURSION(*(zv))
|
||||
|
||||
/* All data types < IS_STRING have their constructor/destructors skipped */
|
||||
#define Z_CONSTANT(zval) ((Z_TYPE_FLAGS(zval) & IS_TYPE_CONSTANT) != 0)
|
||||
#define Z_CONSTANT(zval) (Z_TYPE(zval) == IS_CONSTANT_AST)
|
||||
#define Z_CONSTANT_P(zval_p) Z_CONSTANT(*(zval_p))
|
||||
|
||||
#define Z_REFCOUNTED(zval) ((Z_TYPE_FLAGS(zval) & IS_TYPE_REFCOUNTED) != 0)
|
||||
|
@ -545,7 +533,7 @@ static zend_always_inline zend_uchar zval_get_type(const zval* pz) {
|
|||
#define Z_OPT_TYPE(zval) (Z_TYPE_INFO(zval) & Z_TYPE_MASK)
|
||||
#define Z_OPT_TYPE_P(zval_p) Z_OPT_TYPE(*(zval_p))
|
||||
|
||||
#define Z_OPT_CONSTANT(zval) ((Z_TYPE_INFO(zval) & (IS_TYPE_CONSTANT << Z_TYPE_FLAGS_SHIFT)) != 0)
|
||||
#define Z_OPT_CONSTANT(zval) (Z_OPT_TYPE(zval) == IS_CONSTANT_AST)
|
||||
#define Z_OPT_CONSTANT_P(zval_p) Z_OPT_CONSTANT(*(zval_p))
|
||||
|
||||
#define Z_OPT_REFCOUNTED(zval) ((Z_TYPE_INFO(zval) & (IS_TYPE_REFCOUNTED << Z_TYPE_FLAGS_SHIFT)) != 0)
|
||||
|
|
|
@ -31,8 +31,7 @@
|
|||
ZEND_API void ZEND_FASTCALL _zval_dtor_func(zend_refcounted *p ZEND_FILE_LINE_DC)
|
||||
{
|
||||
switch (GC_TYPE(p)) {
|
||||
case IS_STRING:
|
||||
case IS_CONSTANT: {
|
||||
case IS_STRING: {
|
||||
zend_string *str = (zend_string*)p;
|
||||
CHECK_ZVAL_STRING_REL(str);
|
||||
zend_string_free(str);
|
||||
|
@ -79,7 +78,6 @@ ZEND_API void _zval_internal_dtor(zval *zvalue ZEND_FILE_LINE_DC)
|
|||
{
|
||||
switch (Z_TYPE_P(zvalue)) {
|
||||
case IS_STRING:
|
||||
case IS_CONSTANT:
|
||||
CHECK_ZVAL_STRING_REL(Z_STR_P(zvalue));
|
||||
zend_string_release(Z_STR_P(zvalue));
|
||||
break;
|
||||
|
@ -110,7 +108,6 @@ ZEND_API void _zval_internal_dtor_for_ptr(zval *zvalue ZEND_FILE_LINE_DC)
|
|||
{
|
||||
switch (Z_TYPE_P(zvalue)) {
|
||||
case IS_STRING:
|
||||
case IS_CONSTANT:
|
||||
CHECK_ZVAL_STRING_REL(Z_STR_P(zvalue));
|
||||
zend_string_free(Z_STR_P(zvalue));
|
||||
break;
|
||||
|
@ -170,9 +167,6 @@ ZEND_API void ZEND_FASTCALL _zval_copy_ctor_func(zval *zvalue ZEND_FILE_LINE_DC)
|
|||
} else if (EXPECTED(Z_TYPE_P(zvalue) == IS_STRING)) {
|
||||
CHECK_ZVAL_STRING_REL(Z_STR_P(zvalue));
|
||||
ZVAL_NEW_STR(zvalue, zend_string_dup(Z_STR_P(zvalue), 0));
|
||||
} else if (EXPECTED(Z_TYPE_P(zvalue) == IS_CONSTANT)) {
|
||||
CHECK_ZVAL_STRING_REL(Z_STR_P(zvalue));
|
||||
Z_STR_P(zvalue) = zend_string_dup(Z_STR_P(zvalue), 0);
|
||||
} else if (EXPECTED(Z_TYPE_P(zvalue) == IS_CONSTANT_AST)) {
|
||||
ZVAL_AST(zvalue, zend_ast_copy(Z_ASTVAL_P(zvalue)));
|
||||
}
|
||||
|
|
|
@ -4676,7 +4676,7 @@ ZEND_VM_HOT_HANDLER(64, ZEND_RECV_INIT, NUM, CONST)
|
|||
param = _get_zval_ptr_cv_undef_BP_VAR_W(opline->result.var EXECUTE_DATA_CC);
|
||||
if (arg_num > EX_NUM_ARGS()) {
|
||||
ZVAL_COPY(param, RT_CONSTANT(opline, opline->op2));
|
||||
if (Z_OPT_CONSTANT_P(param)) {
|
||||
if (Z_OPT_TYPE_P(param) == IS_CONSTANT_AST) {
|
||||
SAVE_OPLINE();
|
||||
if (UNEXPECTED(zval_update_constant_ex(param, EX(func)->op_array.scope) != SUCCESS)) {
|
||||
zval_ptr_dtor_nogc(param);
|
||||
|
@ -5078,7 +5078,7 @@ ZEND_VM_HANDLER(181, ZEND_FETCH_CLASS_CONSTANT, VAR|CONST|UNUSED|CLASS_FETCH, CO
|
|||
HANDLE_EXCEPTION();
|
||||
}
|
||||
value = &c->value;
|
||||
if (Z_CONSTANT_P(value)) {
|
||||
if (Z_TYPE_P(value) == IS_CONSTANT_AST) {
|
||||
zval_update_constant_ex(value, c->ce);
|
||||
if (UNEXPECTED(EG(exception) != NULL)) {
|
||||
ZVAL_UNDEF(EX_VAR(opline->result.var));
|
||||
|
@ -7932,7 +7932,7 @@ ZEND_VM_HANDLER(183, ZEND_BIND_STATIC, CV, CONST, REF)
|
|||
value = zend_hash_find(ht, Z_STR_P(varname));
|
||||
|
||||
if (opline->extended_value) {
|
||||
if (Z_CONSTANT_P(value)) {
|
||||
if (Z_TYPE_P(value) == IS_CONSTANT_AST) {
|
||||
SAVE_OPLINE();
|
||||
if (UNEXPECTED(zval_update_constant_ex(value, EX(func)->op_array.scope) != SUCCESS)) {
|
||||
ZVAL_NULL(variable_ptr);
|
||||
|
|
|
@ -2292,7 +2292,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RECV_INIT_SPEC_CON
|
|||
param = _get_zval_ptr_cv_undef_BP_VAR_W(opline->result.var EXECUTE_DATA_CC);
|
||||
if (arg_num > EX_NUM_ARGS()) {
|
||||
ZVAL_COPY(param, RT_CONSTANT(opline, opline->op2));
|
||||
if (Z_OPT_CONSTANT_P(param)) {
|
||||
if (Z_OPT_TYPE_P(param) == IS_CONSTANT_AST) {
|
||||
SAVE_OPLINE();
|
||||
if (UNEXPECTED(zval_update_constant_ex(param, EX(func)->op_array.scope) != SUCCESS)) {
|
||||
zval_ptr_dtor_nogc(param);
|
||||
|
@ -5746,7 +5746,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_CONS
|
|||
HANDLE_EXCEPTION();
|
||||
}
|
||||
value = &c->value;
|
||||
if (Z_CONSTANT_P(value)) {
|
||||
if (Z_TYPE_P(value) == IS_CONSTANT_AST) {
|
||||
zval_update_constant_ex(value, c->ce);
|
||||
if (UNEXPECTED(EG(exception) != NULL)) {
|
||||
ZVAL_UNDEF(EX_VAR(opline->result.var));
|
||||
|
@ -19629,7 +19629,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_
|
|||
HANDLE_EXCEPTION();
|
||||
}
|
||||
value = &c->value;
|
||||
if (Z_CONSTANT_P(value)) {
|
||||
if (Z_TYPE_P(value) == IS_CONSTANT_AST) {
|
||||
zval_update_constant_ex(value, c->ce);
|
||||
if (UNEXPECTED(EG(exception) != NULL)) {
|
||||
ZVAL_UNDEF(EX_VAR(opline->result.var));
|
||||
|
@ -28467,7 +28467,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUS
|
|||
HANDLE_EXCEPTION();
|
||||
}
|
||||
value = &c->value;
|
||||
if (Z_CONSTANT_P(value)) {
|
||||
if (Z_TYPE_P(value) == IS_CONSTANT_AST) {
|
||||
zval_update_constant_ex(value, c->ce);
|
||||
if (UNEXPECTED(EG(exception) != NULL)) {
|
||||
ZVAL_UNDEF(EX_VAR(opline->result.var));
|
||||
|
@ -38504,7 +38504,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BIND_STATIC_SPEC_CV_CONST_HAND
|
|||
value = zend_hash_find(ht, Z_STR_P(varname));
|
||||
|
||||
if (opline->extended_value) {
|
||||
if (Z_CONSTANT_P(value)) {
|
||||
if (Z_TYPE_P(value) == IS_CONSTANT_AST) {
|
||||
SAVE_OPLINE();
|
||||
if (UNEXPECTED(zval_update_constant_ex(value, EX(func)->op_array.scope) != SUCCESS)) {
|
||||
ZVAL_NULL(variable_ptr);
|
||||
|
|
|
@ -176,7 +176,6 @@ PHP_COM_DOTNET_API void php_com_variant_from_zval(VARIANT *v, zval *z, int codep
|
|||
break;
|
||||
|
||||
case IS_RESOURCE:
|
||||
case IS_CONSTANT:
|
||||
case IS_CONSTANT_AST:
|
||||
default:
|
||||
V_VT(v) = VT_NULL;
|
||||
|
|
|
@ -422,7 +422,6 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx
|
|||
}
|
||||
break;
|
||||
case IS_STRING:
|
||||
case IS_CONSTANT:
|
||||
if (info[i].flags & LITERAL_MAY_MERGE) {
|
||||
if (info[i].flags & LITERAL_EX_OBJ) {
|
||||
int key_len = sizeof("$this->") - 1 + Z_STRLEN(op_array->literals[i]);
|
||||
|
|
|
@ -123,7 +123,7 @@ static void zend_try_inline_call(zend_op_array *op_array, zend_op *fcall, zend_o
|
|||
i = fcall->extended_value;
|
||||
|
||||
do {
|
||||
if (Z_CONSTANT_P(RT_CONSTANT(&func->op_array.opcodes[i], func->op_array.opcodes[i].op2))) {
|
||||
if (Z_TYPE_P(RT_CONSTANT(&func->op_array.opcodes[i], func->op_array.opcodes[i].op2)) == IS_CONSTANT_AST) {
|
||||
return;
|
||||
}
|
||||
i++;
|
||||
|
|
|
@ -35,8 +35,6 @@
|
|||
#include "zend_execute.h"
|
||||
#include "zend_vm.h"
|
||||
|
||||
#define ZEND_IS_CONSTANT_TYPE(t) ((t) == IS_CONSTANT)
|
||||
|
||||
void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx)
|
||||
{
|
||||
int i = 0;
|
||||
|
@ -305,11 +303,10 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx)
|
|||
(Z_ACCESS_FLAGS(cc->value) & ZEND_ACC_PPP_MASK) == ZEND_ACC_PUBLIC) {
|
||||
c = &cc->value;
|
||||
if (Z_TYPE_P(c) == IS_CONSTANT_AST) {
|
||||
break;
|
||||
}
|
||||
if (ZEND_IS_CONSTANT_TYPE(Z_TYPE_P(c))) {
|
||||
if (!zend_optimizer_get_persistent_constant(Z_STR_P(c), &t, 1) ||
|
||||
ZEND_IS_CONSTANT_TYPE(Z_TYPE(t))) {
|
||||
zend_ast *ast = Z_ASTVAL_P(c);
|
||||
if (ast->kind != ZEND_AST_CONSTANT
|
||||
|| !zend_optimizer_get_persistent_constant(zend_ast_get_constant_name(ast), &t, 1)
|
||||
|| Z_TYPE(t) == IS_CONSTANT_AST) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -455,9 +455,6 @@ static void zend_dump_op(const zend_op_array *op_array, const zend_basic_block *
|
|||
if (opline->extended_value & IS_CONSTANT_UNQUALIFIED) {
|
||||
fprintf(stderr, " (unqualified)");
|
||||
}
|
||||
if (opline->extended_value & IS_CONSTANT_CLASS) {
|
||||
fprintf(stderr, " (__class__)");
|
||||
}
|
||||
if (opline->extended_value & IS_CONSTANT_IN_NAMESPACE) {
|
||||
fprintf(stderr, " (in-namespace)");
|
||||
}
|
||||
|
|
|
@ -2748,7 +2748,7 @@ static int zend_update_type_info(const zend_op_array *op_array,
|
|||
if (arg_info) {
|
||||
tmp = zend_fetch_arg_info(script, arg_info, &ce);
|
||||
if (opline->opcode == ZEND_RECV_INIT &&
|
||||
Z_CONSTANT_P(CRT_CONSTANT_EX(op_array, opline, opline->op2, ssa->rt_constants))) {
|
||||
Z_TYPE_P(CRT_CONSTANT_EX(op_array, opline, opline->op2, ssa->rt_constants)) == IS_CONSTANT_AST) {
|
||||
/* The constant may resolve to NULL */
|
||||
tmp |= MAY_BE_NULL;
|
||||
}
|
||||
|
@ -4260,7 +4260,7 @@ int zend_may_throw(const zend_op *opline, zend_op_array *op_array, zend_ssa *ssa
|
|||
case ZEND_COUNT:
|
||||
return (t1 & MAY_BE_ANY) != MAY_BE_ARRAY;
|
||||
case ZEND_RECV_INIT:
|
||||
if (Z_CONSTANT_P(CRT_CONSTANT_EX(op_array, opline, opline->op2, ssa->rt_constants))) {
|
||||
if (Z_TYPE_P(CRT_CONSTANT_EX(op_array, opline, opline->op2, ssa->rt_constants)) == IS_CONSTANT_AST) {
|
||||
return 1;
|
||||
}
|
||||
if (op_array->fn_flags & ZEND_ACC_HAS_TYPE_HINTS) {
|
||||
|
|
|
@ -159,9 +159,7 @@ DEFINE_SSA_OP_RANGE_OVERFLOW(op2)
|
|||
#define OP2_RANGE_OVERFLOW() (_ssa_op2_range_overflow (op_array, ssa, opline))
|
||||
|
||||
static zend_always_inline uint32_t _const_op_type(const zval *zv) {
|
||||
if (Z_TYPE_P(zv) == IS_CONSTANT) {
|
||||
return MAY_BE_RC1 | MAY_BE_RCN | MAY_BE_ANY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_ANY;
|
||||
} else if (Z_TYPE_P(zv) == IS_CONSTANT_AST) {
|
||||
if (Z_TYPE_P(zv) == IS_CONSTANT_AST) {
|
||||
return MAY_BE_RC1 | MAY_BE_RCN | MAY_BE_ANY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_ANY;
|
||||
} else if (Z_TYPE_P(zv) == IS_ARRAY) {
|
||||
HashTable *ht = Z_ARRVAL_P(zv);
|
||||
|
|
|
@ -278,7 +278,7 @@ static zend_ast *zend_file_cache_serialize_ast(zend_ast *ast,
|
|||
ret = ast;
|
||||
UNSERIALIZE_PTR(ast);
|
||||
|
||||
if (ast->kind == ZEND_AST_ZVAL) {
|
||||
if (ast->kind == ZEND_AST_ZVAL || ast->kind == ZEND_AST_CONSTANT) {
|
||||
zend_file_cache_serialize_zval(&((zend_ast_zval*)ast)->val, script, info, buf);
|
||||
} else if (zend_ast_is_list(ast)) {
|
||||
zend_ast_list *list = zend_ast_get_list(ast);
|
||||
|
@ -305,7 +305,6 @@ static void zend_file_cache_serialize_zval(zval *zv,
|
|||
{
|
||||
switch (Z_TYPE_P(zv)) {
|
||||
case IS_STRING:
|
||||
case IS_CONSTANT:
|
||||
if (!IS_SERIALIZED(Z_STR_P(zv))) {
|
||||
SERIALIZE_STR(Z_STR_P(zv));
|
||||
}
|
||||
|
@ -893,7 +892,7 @@ static zend_ast *zend_file_cache_unserialize_ast(zend_ast *ast,
|
|||
|
||||
UNSERIALIZE_PTR(ast);
|
||||
|
||||
if (ast->kind == ZEND_AST_ZVAL) {
|
||||
if (ast->kind == ZEND_AST_ZVAL || ast->kind == ZEND_AST_CONSTANT) {
|
||||
zend_file_cache_unserialize_zval(&((zend_ast_zval*)ast)->val, script, buf);
|
||||
} else if (zend_ast_is_list(ast)) {
|
||||
zend_ast_list *list = zend_ast_get_list(ast);
|
||||
|
@ -919,7 +918,6 @@ static void zend_file_cache_unserialize_zval(zval *zv,
|
|||
{
|
||||
switch (Z_TYPE_P(zv)) {
|
||||
case IS_STRING:
|
||||
case IS_CONSTANT:
|
||||
if (!IS_UNSERIALIZED(Z_STR_P(zv))) {
|
||||
UNSERIALIZE_STR(Z_STR_P(zv));
|
||||
}
|
||||
|
@ -945,8 +943,6 @@ static void zend_file_cache_unserialize_zval(zval *zv,
|
|||
break;
|
||||
case IS_CONSTANT_AST:
|
||||
if (!IS_UNSERIALIZED(Z_AST_P(zv))) {
|
||||
zend_ast_ref *ast;
|
||||
|
||||
UNSERIALIZE_PTR(Z_AST_P(zv));
|
||||
zend_file_cache_unserialize_ast(Z_ASTVAL_P(zv), script, buf);
|
||||
}
|
||||
|
|
|
@ -249,7 +249,7 @@ static zend_ast *zend_persist_ast(zend_ast *ast)
|
|||
uint32_t i;
|
||||
zend_ast *node;
|
||||
|
||||
if (ast->kind == ZEND_AST_ZVAL) {
|
||||
if (ast->kind == ZEND_AST_ZVAL || ast->kind == ZEND_AST_CONSTANT) {
|
||||
zend_ast_zval *copy = zend_accel_memdup(ast, sizeof(zend_ast_zval));
|
||||
zend_persist_zval(©->val);
|
||||
node = (zend_ast *) copy;
|
||||
|
@ -282,7 +282,6 @@ static void zend_persist_zval(zval *z)
|
|||
|
||||
switch (Z_TYPE_P(z)) {
|
||||
case IS_STRING:
|
||||
case IS_CONSTANT:
|
||||
zend_accel_store_interned_string(Z_STR_P(z));
|
||||
Z_TYPE_FLAGS_P(z) &= ~ (IS_TYPE_REFCOUNTED | IS_TYPE_COPYABLE);
|
||||
break;
|
||||
|
@ -320,12 +319,12 @@ static void zend_persist_zval(zval *z)
|
|||
new_ptr = zend_shared_alloc_get_xlat_entry(Z_AST_P(z));
|
||||
if (new_ptr) {
|
||||
Z_AST_P(z) = new_ptr;
|
||||
Z_TYPE_FLAGS_P(z) = IS_TYPE_CONSTANT | IS_TYPE_COPYABLE;
|
||||
Z_TYPE_FLAGS_P(z) = IS_TYPE_COPYABLE;
|
||||
} else {
|
||||
zend_ast_ref *old_ref = Z_AST_P(z);
|
||||
Z_ARR_P(z) = zend_accel_memdup(Z_AST_P(z), sizeof(zend_ast_ref));
|
||||
zend_persist_ast(GC_AST(old_ref));
|
||||
Z_TYPE_FLAGS_P(z) = IS_TYPE_CONSTANT | IS_TYPE_COPYABLE;
|
||||
Z_TYPE_FLAGS_P(z) = IS_TYPE_COPYABLE;
|
||||
GC_REFCOUNT(Z_COUNTED_P(z)) = 2;
|
||||
efree(old_ref);
|
||||
}
|
||||
|
|
|
@ -94,9 +94,9 @@ static void zend_persist_ast_calc(zend_ast *ast)
|
|||
{
|
||||
uint32_t i;
|
||||
|
||||
if (ast->kind == ZEND_AST_ZVAL) {
|
||||
if (ast->kind == ZEND_AST_ZVAL || ast->kind == ZEND_AST_CONSTANT) {
|
||||
ADD_SIZE(sizeof(zend_ast_zval));
|
||||
zend_persist_zval_calc(zend_ast_get_zval(ast));
|
||||
zend_persist_zval_calc(&((zend_ast_zval*)(ast))->val);
|
||||
} else if (zend_ast_is_list(ast)) {
|
||||
zend_ast_list *list = zend_ast_get_list(ast);
|
||||
ADD_SIZE(sizeof(zend_ast_list) - sizeof(zend_ast *) + sizeof(zend_ast *) * list->children);
|
||||
|
@ -122,7 +122,6 @@ static void zend_persist_zval_calc(zval *z)
|
|||
|
||||
switch (Z_TYPE_P(z)) {
|
||||
case IS_STRING:
|
||||
case IS_CONSTANT:
|
||||
ADD_INTERNED_STRING(Z_STR_P(z), 0);
|
||||
if (ZSTR_IS_INTERNED(Z_STR_P(z))) {
|
||||
Z_TYPE_FLAGS_P(z) &= ~ (IS_TYPE_REFCOUNTED | IS_TYPE_COPYABLE);
|
||||
|
|
|
@ -2806,7 +2806,7 @@ ZEND_METHOD(reflection_parameter, getDefaultValue)
|
|||
}
|
||||
|
||||
ZVAL_DUP(return_value, RT_CONSTANT(precv, precv->op2));
|
||||
if (Z_CONSTANT_P(return_value)) {
|
||||
if (Z_TYPE_P(return_value) == IS_CONSTANT_AST) {
|
||||
zval_update_constant_ex(return_value, param->fptr->common.scope);
|
||||
}
|
||||
}
|
||||
|
@ -2829,8 +2829,13 @@ ZEND_METHOD(reflection_parameter, isDefaultValueConstant)
|
|||
}
|
||||
|
||||
precv = _reflection_param_get_default_precv(INTERNAL_FUNCTION_PARAM_PASSTHRU, param);
|
||||
if (precv && Z_TYPE_P(RT_CONSTANT(precv, precv->op2)) == IS_CONSTANT) {
|
||||
RETURN_TRUE;
|
||||
if (precv && Z_TYPE_P(RT_CONSTANT(precv, precv->op2)) == IS_CONSTANT_AST) {
|
||||
zend_ast *ast = Z_ASTVAL_P(RT_CONSTANT(precv, precv->op2));
|
||||
|
||||
if (ast->kind == ZEND_AST_CONSTANT
|
||||
|| ast->kind == ZEND_AST_CONSTANT_CLASS) {
|
||||
RETURN_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_FALSE;
|
||||
|
@ -2854,8 +2859,14 @@ ZEND_METHOD(reflection_parameter, getDefaultValueConstantName)
|
|||
}
|
||||
|
||||
precv = _reflection_param_get_default_precv(INTERNAL_FUNCTION_PARAM_PASSTHRU, param);
|
||||
if (precv && Z_TYPE_P(RT_CONSTANT(precv, precv->op2)) == IS_CONSTANT) {
|
||||
RETURN_STR_COPY(Z_STR_P(RT_CONSTANT(precv, precv->op2)));
|
||||
if (precv && Z_TYPE_P(RT_CONSTANT(precv, precv->op2)) == IS_CONSTANT_AST) {
|
||||
zend_ast *ast = Z_ASTVAL_P(RT_CONSTANT(precv, precv->op2));
|
||||
|
||||
if (ast->kind == ZEND_AST_CONSTANT) {
|
||||
RETURN_STR_COPY(zend_ast_get_constant_name(ast));
|
||||
} else if (ast->kind == ZEND_AST_CONSTANT_CLASS) {
|
||||
RETURN_STRINGL("__CLASS__", sizeof("__CLASS__")-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
@ -3698,7 +3709,7 @@ ZEND_METHOD(reflection_class_constant, getValue)
|
|||
GET_REFLECTION_OBJECT_PTR(ref);
|
||||
|
||||
ZVAL_DUP(return_value, &ref->value);
|
||||
if (Z_CONSTANT_P(return_value)) {
|
||||
if (Z_TYPE_P(return_value) == IS_CONSTANT_AST) {
|
||||
zval_update_constant_ex(return_value, ref->ce);
|
||||
}
|
||||
}
|
||||
|
@ -3834,7 +3845,7 @@ static void add_class_vars(zend_class_entry *ce, int statics, zval *return_value
|
|||
|
||||
/* this is necessary to make it able to work with default array
|
||||
* properties, returned to user */
|
||||
if (Z_CONSTANT(prop_copy)) {
|
||||
if (Z_TYPE(prop_copy) == IS_CONSTANT_AST) {
|
||||
if (UNEXPECTED(zval_update_constant_ex(&prop_copy, NULL) != SUCCESS)) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -149,7 +149,6 @@ encode defaultEncoding[] = {
|
|||
{{IS_DOUBLE, XSD_FLOAT_STRING, XSD_NAMESPACE, NULL, NULL}, to_zval_double, to_xml_double},
|
||||
{{IS_FALSE, XSD_BOOLEAN_STRING, XSD_NAMESPACE, NULL, NULL}, to_zval_bool, to_xml_bool},
|
||||
{{IS_TRUE, XSD_BOOLEAN_STRING, XSD_NAMESPACE, NULL, NULL}, to_zval_bool, to_xml_bool},
|
||||
{{IS_CONSTANT, XSD_STRING_STRING, XSD_NAMESPACE, NULL, NULL}, to_zval_string, to_xml_string},
|
||||
{{IS_ARRAY, SOAP_ENC_ARRAY_STRING, SOAP_1_1_ENC_NAMESPACE, NULL, NULL}, to_zval_array, guess_array_map},
|
||||
{{IS_OBJECT, SOAP_ENC_OBJECT_STRING, SOAP_1_1_ENC_NAMESPACE, NULL, NULL}, to_zval_object, to_xml_object},
|
||||
{{IS_ARRAY, SOAP_ENC_ARRAY_STRING, SOAP_1_2_ENC_NAMESPACE, NULL, NULL}, to_zval_array, guess_array_map},
|
||||
|
|
|
@ -3880,7 +3880,7 @@ PHP_FUNCTION(constant)
|
|||
c = zend_get_constant_ex(const_name, scope, ZEND_FETCH_CLASS_SILENT);
|
||||
if (c) {
|
||||
ZVAL_DUP(return_value, c);
|
||||
if (Z_CONSTANT_P(return_value)) {
|
||||
if (Z_TYPE_P(return_value) == IS_CONSTANT_AST) {
|
||||
if (UNEXPECTED(zval_update_constant_ex(return_value, scope) != SUCCESS)) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1339,9 +1339,6 @@ XMLRPC_VALUE_TYPE get_zval_xmlrpc_type(zval* value, zval* newvalue) /* {{{ */
|
|||
case IS_DOUBLE:
|
||||
type = xmlrpc_double;
|
||||
break;
|
||||
case IS_CONSTANT:
|
||||
type = xmlrpc_string;
|
||||
break;
|
||||
case IS_STRING:
|
||||
type = xmlrpc_string;
|
||||
break;
|
||||
|
|
|
@ -844,12 +844,17 @@ char *phpdbg_short_zval_print(zval *zv, int maxlen) /* {{{ */
|
|||
ZSTR_VAL(str), ZSTR_LEN(str) <= maxlen ? 0 : '+');
|
||||
break;
|
||||
}
|
||||
case IS_CONSTANT:
|
||||
decode = estrdup("<constant>");
|
||||
break;
|
||||
case IS_CONSTANT_AST:
|
||||
decode = estrdup("<ast>");
|
||||
case IS_CONSTANT_AST: {
|
||||
zend_ast *ast = Z_ASTVAL_P(zv);
|
||||
|
||||
if (ast->kind == ZEND_AST_CONSTANT
|
||||
|| ast->kind == ZEND_AST_CONSTANT_CLASS) {
|
||||
decode = estrdup("<constant>");
|
||||
} else {
|
||||
decode = estrdup("<ast>");
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
spprintf(&decode, 0, "unknown type: %d", Z_TYPE_P(zv));
|
||||
break;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue