From: Nikita Popov Date: Fri, 6 Jun 2014 20:35:21 +0000 (+0200) Subject: Remove (&ast->u.child)[i] weirdness X-Git-Tag: POST_AST_MERGE^2~203 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=98918fe65bba68050952b5097308a9028e4b6950;p=php Remove (&ast->u.child)[i] weirdness --- diff --git a/Zend/zend_ast.c b/Zend/zend_ast.c index 7a9547b475..82bf42b0d2 100644 --- a/Zend/zend_ast.c +++ b/Zend/zend_ast.c @@ -25,11 +25,11 @@ ZEND_API zend_ast *zend_ast_create_constant(zval *zv) { - zend_ast *ast = emalloc(sizeof(zend_ast) + sizeof(zval)); + zend_ast_zval *ast = emalloc(sizeof(zend_ast_zval)); ast->kind = ZEND_CONST; ast->children = 0; - ZVAL_COPY_VALUE(&ast->u.val, zv); - return ast; + ZVAL_COPY_VALUE(&ast->val, zv); + return (zend_ast *) ast; } ZEND_API zend_ast* zend_ast_create_unary(uint kind, zend_ast *op0) @@ -37,50 +37,55 @@ ZEND_API zend_ast* zend_ast_create_unary(uint kind, zend_ast *op0) zend_ast *ast = emalloc(sizeof(zend_ast)); ast->kind = kind; ast->children = 1; - (&ast->u.child)[0] = op0; + ast->child[0] = op0; return ast; } ZEND_API zend_ast* zend_ast_create_binary(uint kind, zend_ast *op0, zend_ast *op1) { - zend_ast *ast = emalloc(sizeof(zend_ast) + sizeof(zend_ast*)); + zend_ast *ast = emalloc(sizeof(zend_ast) + sizeof(zend_ast *)); ast->kind = kind; ast->children = 2; - (&ast->u.child)[0] = op0; - (&ast->u.child)[1] = op1; + ast->child[0] = op0; + ast->child[1] = op1; return ast; } ZEND_API zend_ast* zend_ast_create_ternary(uint kind, zend_ast *op0, zend_ast *op1, zend_ast *op2) { - zend_ast *ast = emalloc(sizeof(zend_ast) + sizeof(zend_ast*) * 2); + zend_ast *ast = emalloc(sizeof(zend_ast) + sizeof(zend_ast *) * 2); ast->kind = kind; ast->children = 3; - (&ast->u.child)[0] = op0; - (&ast->u.child)[1] = op1; - (&ast->u.child)[2] = op2; + ast->child[0] = op0; + ast->child[1] = op1; + ast->child[2] = op2; return ast; } ZEND_API zend_ast* zend_ast_create_dynamic(uint kind) { - zend_ast *ast = emalloc(sizeof(zend_ast) + sizeof(zend_ast*) * 3); /* use 4 children as deafult */ + /* use 4 children as default */ + zend_ast *ast = emalloc(sizeof(zend_ast) + sizeof(zend_ast *) * 3); ast->kind = kind; ast->children = 0; return ast; } +static inline zend_bool is_power_of_two(unsigned short n) { + return n == (n & -n); +} + ZEND_API void zend_ast_dynamic_add(zend_ast **ast, zend_ast *op) { - if ((*ast)->children >= 4 && (*ast)->children == ((*ast)->children & -(*ast)->children)) { - *ast = erealloc(*ast, sizeof(zend_ast) + sizeof(zend_ast*) * ((*ast)->children * 2 + 1)); + if ((*ast)->children >= 4 && is_power_of_two((*ast)->children)) { + *ast = erealloc(*ast, sizeof(zend_ast) + sizeof(zend_ast *) * ((*ast)->children * 2 - 1)); } - (&(*ast)->u.child)[(*ast)->children++] = op; + (*ast)->child[(*ast)->children++] = op; } ZEND_API void zend_ast_dynamic_shrink(zend_ast **ast) { - *ast = erealloc(*ast, sizeof(zend_ast) + sizeof(zend_ast*) * ((*ast)->children - 1)); + *ast = erealloc(*ast, sizeof(zend_ast) + sizeof(zend_ast *) * ((*ast)->children - 1)); } ZEND_API int zend_ast_is_ct_constant(zend_ast *ast) @@ -88,11 +93,11 @@ ZEND_API int zend_ast_is_ct_constant(zend_ast *ast) int i; if (ast->kind == ZEND_CONST) { - return !Z_CONSTANT(ast->u.val); + return !Z_CONSTANT_P(zend_ast_get_zval(ast)); } else { for (i = 0; i < ast->children; i++) { - if ((&ast->u.child)[i]) { - if (!zend_ast_is_ct_constant((&ast->u.child)[i])) { + if (ast->child[i]) { + if (!zend_ast_is_ct_constant(ast->child[i])) { return 0; } } @@ -139,158 +144,158 @@ ZEND_API void zend_ast_evaluate(zval *result, zend_ast *ast, zend_class_entry *s switch (ast->kind) { case ZEND_ADD: - zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC); - zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC); + zend_ast_evaluate(&op1, ast->child[0], scope TSRMLS_CC); + zend_ast_evaluate(&op2, ast->child[1], scope TSRMLS_CC); add_function(result, &op1, &op2 TSRMLS_CC); zval_dtor(&op1); zval_dtor(&op2); break; case ZEND_SUB: - zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC); - zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC); + zend_ast_evaluate(&op1, ast->child[0], scope TSRMLS_CC); + zend_ast_evaluate(&op2, ast->child[1], scope TSRMLS_CC); sub_function(result, &op1, &op2 TSRMLS_CC); zval_dtor(&op1); zval_dtor(&op2); break; case ZEND_MUL: - zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC); - zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC); + zend_ast_evaluate(&op1, ast->child[0], scope TSRMLS_CC); + zend_ast_evaluate(&op2, ast->child[1], scope TSRMLS_CC); mul_function(result, &op1, &op2 TSRMLS_CC); zval_dtor(&op1); zval_dtor(&op2); break; case ZEND_POW: - zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC); - zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC); + zend_ast_evaluate(&op1, ast->child[0], scope TSRMLS_CC); + zend_ast_evaluate(&op2, ast->child[1], scope TSRMLS_CC); pow_function(result, &op1, &op2 TSRMLS_CC); zval_dtor(&op1); zval_dtor(&op2); break; case ZEND_DIV: - zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC); - zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC); + zend_ast_evaluate(&op1, ast->child[0], scope TSRMLS_CC); + zend_ast_evaluate(&op2, ast->child[1], scope TSRMLS_CC); div_function(result, &op1, &op2 TSRMLS_CC); zval_dtor(&op1); zval_dtor(&op2); break; case ZEND_MOD: - zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC); - zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC); + zend_ast_evaluate(&op1, ast->child[0], scope TSRMLS_CC); + zend_ast_evaluate(&op2, ast->child[1], scope TSRMLS_CC); mod_function(result, &op1, &op2 TSRMLS_CC); zval_dtor(&op1); zval_dtor(&op2); break; case ZEND_SL: - zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC); - zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC); + zend_ast_evaluate(&op1, ast->child[0], scope TSRMLS_CC); + zend_ast_evaluate(&op2, ast->child[1], scope TSRMLS_CC); shift_left_function(result, &op1, &op2 TSRMLS_CC); zval_dtor(&op1); zval_dtor(&op2); break; case ZEND_SR: - zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC); - zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC); + zend_ast_evaluate(&op1, ast->child[0], scope TSRMLS_CC); + zend_ast_evaluate(&op2, ast->child[1], scope TSRMLS_CC); shift_right_function(result, &op1, &op2 TSRMLS_CC); zval_dtor(&op1); zval_dtor(&op2); break; case ZEND_CONCAT: - zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC); - zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC); + zend_ast_evaluate(&op1, ast->child[0], scope TSRMLS_CC); + zend_ast_evaluate(&op2, ast->child[1], scope TSRMLS_CC); concat_function(result, &op1, &op2 TSRMLS_CC); zval_dtor(&op1); zval_dtor(&op2); break; case ZEND_BW_OR: - zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC); - zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC); + zend_ast_evaluate(&op1, ast->child[0], scope TSRMLS_CC); + zend_ast_evaluate(&op2, ast->child[1], scope TSRMLS_CC); bitwise_or_function(result, &op1, &op2 TSRMLS_CC); zval_dtor(&op1); zval_dtor(&op2); break; case ZEND_BW_AND: - zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC); - zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC); + zend_ast_evaluate(&op1, ast->child[0], scope TSRMLS_CC); + zend_ast_evaluate(&op2, ast->child[1], scope TSRMLS_CC); bitwise_and_function(result, &op1, &op2 TSRMLS_CC); zval_dtor(&op1); zval_dtor(&op2); break; case ZEND_BW_XOR: - zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC); - zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC); + zend_ast_evaluate(&op1, ast->child[0], scope TSRMLS_CC); + zend_ast_evaluate(&op2, ast->child[1], scope TSRMLS_CC); bitwise_xor_function(result, &op1, &op2 TSRMLS_CC); zval_dtor(&op1); zval_dtor(&op2); break; case ZEND_BW_NOT: - zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC); + zend_ast_evaluate(&op1, ast->child[0], scope TSRMLS_CC); bitwise_not_function(result, &op1 TSRMLS_CC); zval_dtor(&op1); break; case ZEND_BOOL_NOT: - zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC); + zend_ast_evaluate(&op1, ast->child[0], scope TSRMLS_CC); boolean_not_function(result, &op1 TSRMLS_CC); zval_dtor(&op1); break; case ZEND_BOOL_XOR: - zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC); - zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC); + zend_ast_evaluate(&op1, ast->child[0], scope TSRMLS_CC); + zend_ast_evaluate(&op2, ast->child[1], scope TSRMLS_CC); boolean_xor_function(result, &op1, &op2 TSRMLS_CC); zval_dtor(&op1); zval_dtor(&op2); break; case ZEND_IS_IDENTICAL: - zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC); - zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC); + zend_ast_evaluate(&op1, ast->child[0], scope TSRMLS_CC); + zend_ast_evaluate(&op2, ast->child[1], scope TSRMLS_CC); is_identical_function(result, &op1, &op2 TSRMLS_CC); zval_dtor(&op1); zval_dtor(&op2); break; case ZEND_IS_NOT_IDENTICAL: - zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC); - zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC); + zend_ast_evaluate(&op1, ast->child[0], scope TSRMLS_CC); + zend_ast_evaluate(&op2, ast->child[1], scope TSRMLS_CC); is_not_identical_function(result, &op1, &op2 TSRMLS_CC); zval_dtor(&op1); zval_dtor(&op2); break; case ZEND_IS_EQUAL: - zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC); - zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC); + zend_ast_evaluate(&op1, ast->child[0], scope TSRMLS_CC); + zend_ast_evaluate(&op2, ast->child[1], scope TSRMLS_CC); is_equal_function(result, &op1, &op2 TSRMLS_CC); zval_dtor(&op1); zval_dtor(&op2); break; case ZEND_IS_NOT_EQUAL: - zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC); - zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC); + zend_ast_evaluate(&op1, ast->child[0], scope TSRMLS_CC); + zend_ast_evaluate(&op2, ast->child[1], scope TSRMLS_CC); is_not_equal_function(result, &op1, &op2 TSRMLS_CC); zval_dtor(&op1); zval_dtor(&op2); break; case ZEND_IS_SMALLER: - zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC); - zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC); + zend_ast_evaluate(&op1, ast->child[0], scope TSRMLS_CC); + zend_ast_evaluate(&op2, ast->child[1], scope TSRMLS_CC); is_smaller_function(result, &op1, &op2 TSRMLS_CC); zval_dtor(&op1); zval_dtor(&op2); break; case ZEND_IS_SMALLER_OR_EQUAL: - zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC); - zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC); + zend_ast_evaluate(&op1, ast->child[0], scope TSRMLS_CC); + zend_ast_evaluate(&op2, ast->child[1], scope TSRMLS_CC); is_smaller_or_equal_function(result, &op1, &op2 TSRMLS_CC); zval_dtor(&op1); zval_dtor(&op2); break; case ZEND_CONST: - ZVAL_DUP(result, &ast->u.val); + ZVAL_DUP(result, zend_ast_get_zval(ast)); if (Z_OPT_CONSTANT_P(result)) { zval_update_constant_ex(result, 1, scope TSRMLS_CC); } break; case ZEND_BOOL_AND: - zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC); + zend_ast_evaluate(&op1, ast->child[0], scope TSRMLS_CC); if (zend_is_true(&op1 TSRMLS_CC)) { - zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC); + zend_ast_evaluate(&op2, ast->child[1], scope TSRMLS_CC); ZVAL_BOOL(result, zend_is_true(&op2 TSRMLS_CC)); zval_dtor(&op2); } else { @@ -299,39 +304,39 @@ ZEND_API void zend_ast_evaluate(zval *result, zend_ast *ast, zend_class_entry *s zval_dtor(&op1); break; case ZEND_BOOL_OR: - zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC); + zend_ast_evaluate(&op1, ast->child[0], scope TSRMLS_CC); if (zend_is_true(&op1 TSRMLS_CC)) { ZVAL_BOOL(result, 1); } else { - zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC); + zend_ast_evaluate(&op2, ast->child[1], scope TSRMLS_CC); ZVAL_BOOL(result, zend_is_true(&op2 TSRMLS_CC)); zval_dtor(&op2); } zval_dtor(&op1); break; case ZEND_SELECT: - zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC); + zend_ast_evaluate(&op1, ast->child[0], scope TSRMLS_CC); if (zend_is_true(&op1 TSRMLS_CC)) { - if (!(&ast->u.child)[1]) { + if (!ast->child[1]) { *result = op1; } else { - zend_ast_evaluate(result, (&ast->u.child)[1], scope TSRMLS_CC); + zend_ast_evaluate(result, ast->child[1], scope TSRMLS_CC); zval_dtor(&op1); } } else { - zend_ast_evaluate(result, (&ast->u.child)[2], scope TSRMLS_CC); + zend_ast_evaluate(result, ast->child[2], scope TSRMLS_CC); zval_dtor(&op1); } break; case ZEND_UNARY_PLUS: ZVAL_LONG(&op1, 0); - zend_ast_evaluate(&op2, (&ast->u.child)[0], scope TSRMLS_CC); + zend_ast_evaluate(&op2, ast->child[0], scope TSRMLS_CC); add_function(result, &op1, &op2 TSRMLS_CC); zval_dtor(&op2); break; case ZEND_UNARY_MINUS: ZVAL_LONG(&op1, 0); - zend_ast_evaluate(&op2, (&ast->u.child)[0], scope TSRMLS_CC); + zend_ast_evaluate(&op2, ast->child[0], scope TSRMLS_CC); sub_function(result, &op1, &op2 TSRMLS_CC); zval_dtor(&op2); break; @@ -340,12 +345,12 @@ ZEND_API void zend_ast_evaluate(zval *result, zend_ast *ast, zend_class_entry *s { int i; for (i = 0; i < ast->children; i+=2) { - if ((&ast->u.child)[i]) { - zend_ast_evaluate(&op1, (&ast->u.child)[i], scope TSRMLS_CC); + if (ast->child[i]) { + zend_ast_evaluate(&op1, ast->child[i], scope TSRMLS_CC); } else { ZVAL_UNDEF(&op1); } - zend_ast_evaluate(&op2, (&ast->u.child)[i+1], scope TSRMLS_CC); + zend_ast_evaluate(&op2, ast->child[i+1], scope TSRMLS_CC); zend_ast_add_array_element(result, &op1, &op2 TSRMLS_CC); } } @@ -360,16 +365,16 @@ ZEND_API zend_ast *zend_ast_copy(zend_ast *ast) if (ast == NULL) { return NULL; } else if (ast->kind == ZEND_CONST) { - zend_ast *copy = zend_ast_create_constant(&ast->u.val); - zval_copy_ctor(©->u.val); + zend_ast *copy = zend_ast_create_constant(zend_ast_get_zval(ast)); + zval_copy_ctor(zend_ast_get_zval(copy)); return copy; } else if (ast->children) { - zend_ast *new = emalloc(sizeof(zend_ast) + sizeof(zend_ast*) * (ast->children - 1)); + zend_ast *new = emalloc(sizeof(zend_ast) + sizeof(zend_ast *) * (ast->children - 1)); int i; new->kind = ast->kind; new->children = ast->children; for (i = 0; i < ast->children; i++) { - (&new->u.child)[i] = zend_ast_copy((&ast->u.child)[i]); + new->child[i] = zend_ast_copy(ast->child[i]); } return new; } @@ -381,11 +386,11 @@ ZEND_API void zend_ast_destroy(zend_ast *ast) int i; if (ast->kind == ZEND_CONST) { - zval_dtor(&ast->u.val); + zval_dtor(zend_ast_get_zval(ast)); } else { for (i = 0; i < ast->children; i++) { - if ((&ast->u.child)[i]) { - zend_ast_destroy((&ast->u.child)[i]); + if (ast->child[i]) { + zend_ast_destroy(ast->child[i]); } } } diff --git a/Zend/zend_ast.h b/Zend/zend_ast.h index 8678299f0f..d411e4e802 100644 --- a/Zend/zend_ast.h +++ b/Zend/zend_ast.h @@ -37,12 +37,19 @@ typedef enum _zend_ast_kind { struct _zend_ast { unsigned short kind; unsigned short children; - union { - zval val; - zend_ast *child; - } u; + zend_ast *child[1]; }; +typedef struct _zend_ast_zval { + unsigned short kind; + unsigned short children; + zval val; +} zend_ast_zval; + +static inline zval *zend_ast_get_zval(zend_ast *ast) { + return &((zend_ast_zval *) ast)->val; +} + ZEND_API zend_ast *zend_ast_create_constant(zval *zv); ZEND_API zend_ast *zend_ast_create_unary(uint kind, zend_ast *op0); diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index f5efd84144..f7adf95ed3 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -7478,7 +7478,7 @@ void zend_make_immutable_array_r(zval *zv TSRMLS_DC) /* {{{ */ void zend_do_constant_expression(znode *result, zend_ast *ast TSRMLS_DC) /* {{{ */ { if (ast->kind == ZEND_CONST) { - ZVAL_COPY_VALUE(&result->u.constant, &ast->u.val); + ZVAL_COPY_VALUE(&result->u.constant, zend_ast_get_zval(ast)); efree(ast); } else if (zend_ast_is_ct_constant(ast)) { zend_ast_evaluate(&result->u.constant, ast, NULL TSRMLS_CC);