summaryrefslogtreecommitdiff
path: root/Zend/zend_ast.c
diff options
context:
space:
mode:
Diffstat (limited to 'Zend/zend_ast.c')
-rw-r--r--Zend/zend_ast.c79
1 files changed, 60 insertions, 19 deletions
diff --git a/Zend/zend_ast.c b/Zend/zend_ast.c
index 9a0808db9..583a52321 100644
--- a/Zend/zend_ast.c
+++ b/Zend/zend_ast.c
@@ -63,6 +63,27 @@ ZEND_API zend_ast* zend_ast_create_ternary(uint kind, zend_ast *op0, zend_ast *o
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 */
+ ast->kind = kind;
+ ast->children = 0;
+ return ast;
+}
+
+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));
+ }
+ (&(*ast)->u.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));
+}
+
ZEND_API int zend_ast_is_ct_constant(zend_ast *ast)
{
int i;
@@ -233,7 +254,7 @@ ZEND_API void zend_ast_evaluate(zval *result, zend_ast *ast, zend_class_entry *s
*result = *ast->u.val;
zval_copy_ctor(result);
if (IS_CONSTANT_TYPE(Z_TYPE_P(result))) {
- zval_update_constant_ex(&result, (void *) 1, scope TSRMLS_CC);
+ zval_update_constant_ex(&result, 1, scope TSRMLS_CC);
}
break;
case ZEND_BOOL_AND:
@@ -284,6 +305,35 @@ ZEND_API void zend_ast_evaluate(zval *result, zend_ast *ast, zend_class_entry *s
sub_function(result, &op1, &op2 TSRMLS_CC);
zval_dtor(&op2);
break;
+ case ZEND_INIT_ARRAY:
+ INIT_PZVAL(result);
+ array_init(result);
+ {
+ int i;
+ zend_bool has_key;
+ for (i = 0; i < ast->children; i+=2) {
+ zval *expr;
+ MAKE_STD_ZVAL(expr);
+ if ((has_key = !!(&ast->u.child)[i])) {
+ zend_ast_evaluate(&op1, (&ast->u.child)[i], scope TSRMLS_CC);
+ }
+ zend_ast_evaluate(expr, (&ast->u.child)[i+1], scope TSRMLS_CC);
+ zend_do_add_static_array_element(result, has_key?&op1:NULL, expr);
+ }
+ }
+ break;
+ case ZEND_FETCH_DIM_R:
+ zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC);
+ zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC);
+ {
+ zval *tmp;
+ zend_fetch_dimension_by_zval(&tmp, &op1, &op2 TSRMLS_CC);
+ *result = *tmp;
+ efree(tmp);
+ }
+ zval_dtor(&op1);
+ zval_dtor(&op2);
+ break;
default:
zend_error(E_ERROR, "Unsupported constant expression");
}
@@ -297,26 +347,17 @@ ZEND_API zend_ast *zend_ast_copy(zend_ast *ast)
zend_ast *copy = zend_ast_create_constant(ast->u.val);
zval_copy_ctor(copy->u.val);
return copy;
- } else {
- switch (ast->children) {
- case 1:
- return zend_ast_create_unary(
- ast->kind,
- zend_ast_copy((&ast->u.child)[0]));
- case 2:
- return zend_ast_create_binary(
- ast->kind,
- zend_ast_copy((&ast->u.child)[0]),
- zend_ast_copy((&ast->u.child)[1]));
- case 3:
- return zend_ast_create_ternary(
- ast->kind,
- zend_ast_copy((&ast->u.child)[0]),
- zend_ast_copy((&ast->u.child)[1]),
- zend_ast_copy((&ast->u.child)[2]));
+ } else if (ast->children) {
+ 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]);
}
+ return new;
}
- return NULL;
+ return zend_ast_create_dynamic(ast->kind);
}
ZEND_API void zend_ast_destroy(zend_ast *ast)