mirror of
https://github.com/php/php-src.git
synced 2024-11-23 18:04:36 +08:00
fixed support for constant expressions
This commit is contained in:
parent
73b8e9aef4
commit
f4c2810ab4
@ -5888,26 +5888,27 @@ void zend_do_add_static_array_element(znode *result, znode *offset, const znode
|
||||
if (offset) {
|
||||
switch (Z_TYPE(offset->u.constant) & IS_CONSTANT_TYPE_MASK) {
|
||||
case IS_CONSTANT:
|
||||
/* Ugly hack to denote that this value has a constant index */
|
||||
Z_TYPE(element) |= IS_CONSTANT_INDEX;
|
||||
//??? /* Ugly hack to denote that this value has a constant index */
|
||||
Z_STR(offset->u.constant)->gc.u.v.flags |= IS_STR_CONSTANT;
|
||||
//??? Z_TYPE(element) |= IS_CONSTANT_INDEX;
|
||||
//??? Z_STRVAL(offset->u.constant) = erealloc(Z_STRVAL(offset->u.constant), Z_STRLEN(offset->u.constant)+3);
|
||||
//??? Z_STRVAL(offset->u.constant)[Z_STRLEN(offset->u.constant)+1] = Z_TYPE(offset->u.constant);
|
||||
//??? Z_STRVAL(offset->u.constant)[Z_STRLEN(offset->u.constant)+2] = 0;
|
||||
//??? zend_symtable_update(Z_ARRVAL(result->u.constant), Z_STRVAL(offset->u.constant), Z_STRLEN(offset->u.constant)+3, &element, sizeof(zval *), NULL);
|
||||
zend_symtable_update(Z_ARRVAL(result->u.constant), Z_STR(offset->u.constant), &element);
|
||||
zval_dtor(&offset->u.constant);
|
||||
break;
|
||||
case IS_CONSTANT_AST: {
|
||||
/* Another ugly hack to store the data about the AST in the array */
|
||||
//??? char* key;
|
||||
//??? /* Another ugly hack to store the data about the AST in the array */
|
||||
zend_string *key;
|
||||
//??? int len = sizeof(zend_ast *);
|
||||
Z_TYPE(element) |= IS_CONSTANT_INDEX;
|
||||
//??? Z_TYPE(element) |= IS_CONSTANT_INDEX;
|
||||
Z_STR(offset->u.constant)->gc.u.v.flags |= IS_STR_AST;
|
||||
|
||||
//??? key = emalloc(len + 2);
|
||||
//??? *(zend_ast **)key = Z_AST(offset->u.constant);
|
||||
key = STR_INIT((char*)Z_AST(offset->u.constant), sizeof(zend_ast*), 0);
|
||||
//??? key[len] = Z_TYPE(offset->u.constant);
|
||||
//??? key[len + 1] = 0;
|
||||
//??? zend_symtable_update(Z_ARRVAL(result->u.constant), key, len + 2, &element, sizeof(zval *), NULL);
|
||||
//??? efree(key);
|
||||
zend_symtable_update(Z_ARRVAL(result->u.constant), key, &element);
|
||||
STR_RELEASE(key);
|
||||
break;
|
||||
}
|
||||
case IS_STRING:
|
||||
|
@ -451,7 +451,7 @@ ZEND_API int zend_is_true(zval *op TSRMLS_DC) /* {{{ */
|
||||
|
||||
#include "../TSRM/tsrm_strtok_r.h"
|
||||
|
||||
#define IS_VISITED_CONSTANT IS_CONSTANT_INDEX
|
||||
#define IS_VISITED_CONSTANT 0x080 //??? IS_CONSTANT_INDEX
|
||||
#define IS_CONSTANT_VISITED(p) (Z_TYPE_P(p) & IS_VISITED_CONSTANT)
|
||||
#define Z_REAL_TYPE_P(p) (Z_TYPE_P(p) & ~IS_VISITED_CONSTANT)
|
||||
#define MARK_CONSTANT_VISITED(p) Z_TYPE_P(p) |= IS_VISITED_CONSTANT
|
||||
@ -460,10 +460,10 @@ static void zval_deep_copy(zval *p)
|
||||
{
|
||||
zval value;
|
||||
|
||||
ZVAL_COPY_VALUE(&value, p);
|
||||
Z_TYPE(value) &= ~IS_CONSTANT_INDEX;
|
||||
zval_copy_ctor(&value);
|
||||
Z_TYPE(value) = Z_TYPE_P(p);
|
||||
ZVAL_DUP(&value, p);
|
||||
//??? Z_TYPE(value) &= ~IS_CONSTANT_INDEX;
|
||||
//??? zval_copy_ctor(&value);
|
||||
//??? Z_TYPE(value) = Z_TYPE_P(p);
|
||||
ZVAL_COPY_VALUE(p, &value);
|
||||
}
|
||||
|
||||
@ -546,9 +546,9 @@ ZEND_API int zval_update_constant_ex(zval *p, void *arg, zend_class_entry *scope
|
||||
}
|
||||
} else {
|
||||
if (inline_change) {
|
||||
//??? STR_RELEASE(Z_STR_P(p));
|
||||
STR_RELEASE(Z_STR_P(p));
|
||||
}
|
||||
*p = const_value;
|
||||
ZVAL_COPY_VALUE(p, &const_value);
|
||||
}
|
||||
|
||||
if (IS_REFCOUNTED(Z_TYPE_P(p))) Z_SET_REFCOUNT_P(p, refcount);
|
||||
@ -572,56 +572,62 @@ ZEND_API int zval_update_constant_ex(zval *p, void *arg, zend_class_entry *scope
|
||||
/* First go over the array and see if there are any constant indices */
|
||||
zend_hash_internal_pointer_reset(Z_ARRVAL_P(p));
|
||||
while ((element = zend_hash_get_current_data(Z_ARRVAL_P(p))) != NULL) {
|
||||
if (!(Z_TYPE_P(element) & IS_CONSTANT_INDEX)) {
|
||||
zend_hash_move_forward(Z_ARRVAL_P(p));
|
||||
continue;
|
||||
}
|
||||
Z_TYPE_P(element) &= ~IS_CONSTANT_INDEX;
|
||||
if (zend_hash_get_current_key_ex(Z_ARRVAL_P(p), &str_index, &num_index, 0, NULL) != HASH_KEY_IS_STRING) {
|
||||
zend_hash_move_forward(Z_ARRVAL_P(p));
|
||||
continue;
|
||||
}
|
||||
if (!(str_index->gc.u.v.flags & (IS_STR_CONSTANT | IS_STR_AST))) {
|
||||
zend_hash_move_forward(Z_ARRVAL_P(p));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (str_index->gc.u.v.flags & IS_STR_AST) {
|
||||
zend_ast_evaluate(&const_value, (zend_ast *)str_index->val, scope TSRMLS_CC);
|
||||
zend_ast_destroy((zend_ast *)str_index->val);
|
||||
//???
|
||||
#if 0
|
||||
if (str_index[str_index_len - 2] == IS_CONSTANT_AST) {
|
||||
zend_ast_evaluate(&const_value, *(zend_ast **)str_index, scope TSRMLS_CC);
|
||||
zend_ast_destroy(*(zend_ast **)str_index);
|
||||
} else if (!zend_get_constant_ex(str_index, str_index_len - 3, &const_value, scope, str_index[str_index_len - 2] TSRMLS_CC)) {
|
||||
char *actual;
|
||||
const char *save = str_index;
|
||||
if ((colon = (char*)zend_memrchr(str_index, ':', str_index_len - 3))) {
|
||||
zend_error(E_ERROR, "Undefined class constant '%s'", str_index);
|
||||
str_index_len -= ((colon - str_index) + 1);
|
||||
str_index = colon;
|
||||
} else if (!zend_get_constant_ex(str_index->val, str_index->len, &const_value, scope, 0 /*???str_index[str_index_len - 2]*/ TSRMLS_CC)) {
|
||||
char *actual, *str;
|
||||
const char *save = str_index->val;
|
||||
int len;
|
||||
|
||||
str = str_index->val;
|
||||
len = str_index->len;
|
||||
if ((colon = (char*)zend_memrchr(str, ':', len))) {
|
||||
zend_error(E_ERROR, "Undefined class constant '%s'", str);
|
||||
len -= ((colon - str) + 1);
|
||||
str = colon;
|
||||
} else {
|
||||
if (str_index[str_index_len - 2] & IS_CONSTANT_UNQUALIFIED) {
|
||||
if ((actual = (char *)zend_memrchr(str_index, '\\', str_index_len - 3))) {
|
||||
if (str_index->gc.u.v.flags & IS_STR_CONSTANT_UNQUALIFIED) {
|
||||
if ((actual = (char *)zend_memrchr(str, '\\', len))) {
|
||||
actual++;
|
||||
str_index_len -= (actual - str_index);
|
||||
str_index = actual;
|
||||
len -= (actual - str);
|
||||
str = actual;
|
||||
}
|
||||
}
|
||||
if (str_index[0] == '\\') {
|
||||
++str_index;
|
||||
--str_index_len;
|
||||
if (str[0] == '\\') {
|
||||
++str;
|
||||
--len;
|
||||
}
|
||||
if (save[0] == '\\') {
|
||||
++save;
|
||||
}
|
||||
if ((str_index[str_index_len - 2] & IS_CONSTANT_UNQUALIFIED) == 0) {
|
||||
if (str_index->gc.u.v.flags & IS_STR_CONSTANT_UNQUALIFIED) {
|
||||
zend_error(E_ERROR, "Undefined constant '%s'", save);
|
||||
}
|
||||
zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'", str_index, str_index);
|
||||
}
|
||||
ZVAL_STRINGL(&const_value, str_index, str_index_len-3);
|
||||
if (str == str_index->val && len == str_index->len) {
|
||||
ZVAL_STR(&const_value, str_index);
|
||||
} else {
|
||||
ZVAL_STRINGL(&const_value, str, len);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (Z_REFCOUNT_P(element) > 1) {
|
||||
ZVAL_DUP(&new_val, element);
|
||||
|
||||
/* preserve this bit for inheritance */
|
||||
Z_TYPE_P(element) |= IS_CONSTANT_INDEX;
|
||||
//??? Z_TYPE_P(element) |= IS_CONSTANT_INDEX;
|
||||
zval_ptr_dtor(element);
|
||||
ZVAL_COPY_VALUE(element, &new_val);
|
||||
}
|
||||
|
@ -198,7 +198,7 @@ struct _zend_ast_ref {
|
||||
/* Ugly hack to support constants as static array indices */
|
||||
#define IS_CONSTANT_TYPE_MASK 0x00f
|
||||
#define IS_CONSTANT_UNQUALIFIED 0x010
|
||||
#define IS_CONSTANT_INDEX 0x080
|
||||
//???#define IS_CONSTANT_INDEX 0x080
|
||||
#define IS_LEXICAL_VAR 0x020
|
||||
#define IS_LEXICAL_REF 0x040
|
||||
#define IS_CONSTANT_IN_NAMESPACE 0x100
|
||||
@ -212,11 +212,15 @@ struct _zend_ast_ref {
|
||||
#define Z_TYPE(zval) (zval).type
|
||||
#define Z_TYPE_P(zval_p) Z_TYPE(*(zval_p))
|
||||
|
||||
/* string flags (zval.value->gc.u.vflags) */
|
||||
/* string flags (zval.value->gc.u.flags) */
|
||||
#define IS_STR_PERSISTENT (1<<0) /* allocated using malloc */
|
||||
#define IS_STR_INTERNED (1<<1) /* interned string */
|
||||
#define IS_STR_PERMANENT (1<<2) /* relives request boundary */
|
||||
|
||||
#define IS_STR_CONSTANT (1<<3) /* constant index */
|
||||
#define IS_STR_CONSTANT_UNQUALIFIED (1<<4) /* the same as IS_CONSTANT_UNQUALIFIED */
|
||||
#define IS_STR_AST (1<<5) /* constant expression index */
|
||||
|
||||
/* object flags (zval.value->gc.u.vflags) */
|
||||
#define IS_OBJ_APPLY_COUNT 0x07
|
||||
#define IS_OBJ_DESTRUCTOR_CALLED (1<<3)
|
||||
|
Loading…
Reference in New Issue
Block a user