diff options
| author | Dmitry Stogov <dmitry@zend.com> | 2013-11-06 15:41:33 +0400 |
|---|---|---|
| committer | Dmitry Stogov <dmitry@zend.com> | 2013-11-06 15:41:33 +0400 |
| commit | af600c240d2efe33291e8dd71ce228b9fbc849c1 (patch) | |
| tree | 9a0940e0e80bc92ba9c371f850a595f9347cbfb6 /Zend/zend_ast.c | |
| parent | d87388ba0f6cf29eb495f9af96ab6aa353ebcc4f (diff) | |
| parent | 18e2b1a9a930d5ae15544c5a2beed6b20d58cdee (diff) | |
| download | php-git-af600c240d2efe33291e8dd71ce228b9fbc849c1.tar.gz | |
Merge branch 'const_scalar_exprs' of github.com:bwoebi/php-src into const_scalar_exprs
* 'const_scalar_exprs' of github.com:bwoebi/php-src:
Removed operations on constant arrays. They make no sense as constants are not allowed to be arrays. And as just properties are allowed to; no problem, we still don't need operations on any constant array.
Added a few more operators
Whitespace fix
converted several switches to ifs and made more opcache friendly
Fatal error about self referencing constants fixed
Fixed mem leaks, added tests and ternary operator
Working commit for constant scalar expressions (with constants). Tests will follow.
Conflicts:
Zend/Makefile.am
configure.in
win32/build/config.w32
Diffstat (limited to 'Zend/zend_ast.c')
| -rw-r--r-- | Zend/zend_ast.c | 130 |
1 files changed, 130 insertions, 0 deletions
diff --git a/Zend/zend_ast.c b/Zend/zend_ast.c new file mode 100644 index 0000000000..21c08da510 --- /dev/null +++ b/Zend/zend_ast.c @@ -0,0 +1,130 @@ +/* + +----------------------------------------------------------------------+ + | Zend Engine | + +----------------------------------------------------------------------+ + | Copyright (c) 1998-2013 Zend Technologies Ltd. (http://www.zend.com) | + +----------------------------------------------------------------------+ + | 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 | + | available through the world-wide-web at the following url: | + | http://www.zend.com/license/2_00.txt. | + | If you did not receive a copy of the Zend license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@zend.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Bob Weinand <bwoebi@php.net> | + +----------------------------------------------------------------------+ +*/ + +/* $Id$ */ + +#include "zend_ast.h" +#include "zend_execute.h" + +#define COPY_ZVAL_TO_OP(nr) \ + if (op##nr) { \ + Z_AST_P(result)->ops[nr] = emalloc(sizeof(zval)); \ + *Z_AST_P(result)->ops[nr] = *op##nr; \ + } else { \ + Z_AST_P(result)->ops[nr] = NULL; \ + } + +void zend_ast_add(zval *result, intermediary_ast_function_type func, char op_count) { + zend_ast *ast = emalloc(sizeof(zend_ast) + op_count * sizeof(zval *)); + ast->op_count = op_count; + ast->ops = (zval **)(ast + 1); + ast->refcount = 1; + ast->func = func; + Z_AST_P(result) = ast; + Z_TYPE_P(result) = IS_CONSTANT_AST; +} + +/* Do operations on constant operators at compile time (AST building time) */ + +void zend_ast_add_unary(zval *result, unary_ast_func func, zval *op0 TSRMLS_DC) { + if (!op0 || !IS_CONSTANT_TYPE(Z_TYPE_P(op0))) { + func(result, op0 TSRMLS_CC); + if (op0) zval_dtor(op0); + return; + } + + zend_ast_add(result, (intermediary_ast_function_type)func, 1); + COPY_ZVAL_TO_OP(0) +} + +void zend_ast_add_binary(zval *result, binary_ast_func func, zval *op0, zval *op1 TSRMLS_DC) { + if ((!op0 || !IS_CONSTANT_TYPE(Z_TYPE_P(op0))) && (!op1 || !IS_CONSTANT_TYPE(Z_TYPE_P(op1)))) { + func(result, op0, op1 TSRMLS_CC); + if (op0) zval_dtor(op0); + if (op1) zval_dtor(op1); + return; + } + + zend_ast_add(result, (intermediary_ast_function_type)func, 2); + COPY_ZVAL_TO_OP(0) + COPY_ZVAL_TO_OP(1) +} + +void zend_ast_add_ternary(zval *result, ternary_ast_func func, zval *op0, zval *op1, zval *op2 TSRMLS_DC) { + if ((!op0 || !IS_CONSTANT_TYPE(Z_TYPE_P(op0))) && (!op1 || !IS_CONSTANT_TYPE(Z_TYPE_P(op1))) && (!op2 || !IS_CONSTANT_TYPE(Z_TYPE_P(op2)))) { + func(result, op0, op1, op2 TSRMLS_CC); + if (op0) zval_dtor(op0); + if (op1) zval_dtor(op1); + if (op2) zval_dtor(op2); + return; + } + + zend_ast_add(result, (intermediary_ast_function_type)func, 3); + COPY_ZVAL_TO_OP(0) + COPY_ZVAL_TO_OP(1) + COPY_ZVAL_TO_OP(2) +} + +void zend_ast_evaluate(zval *result, zend_ast *ast TSRMLS_DC) { + int i; + zval **ops = emalloc((sizeof(zval *) + sizeof(zval)) * ast->op_count); + + for (i = ast->op_count; i--;) { + if (ast->ops[i] && IS_CONSTANT_TYPE(Z_TYPE_P(ast->ops[i]))) { + ops[i] = ((zval *)(ops + ast->op_count)) + i; + *ops[i] = *ast->ops[i]; + zval_copy_ctor(ops[i]); + zval_update_constant_ex(&ops[i], (void *)1, NULL TSRMLS_CC); + } else { + ops[i] = ast->ops[i]; + } + } + + switch (ast->op_count) { + case 1: + ((unary_ast_func)ast->func)(result, ops[0] TSRMLS_CC); + break; + case 2: + ((binary_ast_func)ast->func)(result, ops[0], ops[1] TSRMLS_CC); + break; + case 3: + ((ternary_ast_func)ast->func)(result, ops[0], ops[1], ops[2] TSRMLS_CC); + break; + } + + for (i = ast->op_count; i--;) { + if (ast->ops[i] != ops[i]) { + zval_dtor(ops[i]); + } + } + + efree(ops); +} + +void zend_ast_destroy(zend_ast *ast TSRMLS_DC) { + int i; + + for (i = ast->op_count; i--;) { + if (ast->ops[i] && !Z_DELREF_P(ast->ops[i])) { + zval_dtor(ast->ops[i]); + efree(ast->ops[i]); + } + } + + efree(ast); +} |
