PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LCOV - code coverage report
Current view: top level - Zend - zend_ast.c (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 181 209 86.6 %
Date: 2014-08-04 Functions: 11 11 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :    +----------------------------------------------------------------------+
       3             :    | Zend Engine                                                          |
       4             :    +----------------------------------------------------------------------+
       5             :    | Copyright (c) 1998-2014 Zend Technologies Ltd. (http://www.zend.com) |
       6             :    +----------------------------------------------------------------------+
       7             :    | This source file is subject to version 2.00 of the Zend license,     |
       8             :    | that is bundled with this package in the file LICENSE, and is        |
       9             :    | available through the world-wide-web at the following url:           |
      10             :    | http://www.zend.com/license/2_00.txt.                                |
      11             :    | If you did not receive a copy of the Zend license and are unable to  |
      12             :    | obtain it through the world-wide-web, please send a note to          |
      13             :    | license@zend.com so we can mail you a copy immediately.              |
      14             :    +----------------------------------------------------------------------+
      15             :    | Authors: Bob Weinand <bwoebi@php.net>                                |
      16             :    |          Dmitry Stogov <dmitry@zend.com>                             |
      17             :    +----------------------------------------------------------------------+
      18             : */
      19             : 
      20             : /* $Id$ */
      21             : 
      22             : #include "zend_ast.h"
      23             : #include "zend_API.h"
      24             : #include "zend_operators.h"
      25             : 
      26       20943 : ZEND_API zend_ast *zend_ast_create_constant(zval *zv)
      27             : {
      28       20943 :         zend_ast *ast = emalloc(sizeof(zend_ast) + sizeof(zval));
      29       20943 :         ast->kind = ZEND_CONST;
      30       20943 :         ast->children = 0;
      31       20943 :         ast->u.val = (zval*)(ast + 1);
      32       41886 :         INIT_PZVAL_COPY(ast->u.val, zv);
      33       20943 :         return ast;
      34             : }
      35             : 
      36          54 : ZEND_API zend_ast* zend_ast_create_unary(uint kind, zend_ast *op0)
      37             : {
      38          54 :         zend_ast *ast = emalloc(sizeof(zend_ast));
      39          54 :         ast->kind = kind;
      40          54 :         ast->children = 1;
      41          54 :         (&ast->u.child)[0] = op0;
      42          54 :         return ast;
      43             : }
      44             : 
      45          61 : ZEND_API zend_ast* zend_ast_create_binary(uint kind, zend_ast *op0, zend_ast *op1)
      46             : {
      47          61 :         zend_ast *ast = emalloc(sizeof(zend_ast) + sizeof(zend_ast*));
      48          61 :         ast->kind = kind;
      49          61 :         ast->children = 2;
      50          61 :         (&ast->u.child)[0] = op0;
      51          61 :         (&ast->u.child)[1] = op1;
      52          61 :         return ast;
      53             : }
      54             : 
      55           2 : ZEND_API zend_ast* zend_ast_create_ternary(uint kind, zend_ast *op0, zend_ast *op1, zend_ast *op2)
      56             : {
      57           2 :         zend_ast *ast = emalloc(sizeof(zend_ast) + sizeof(zend_ast*) * 2);
      58           2 :         ast->kind = kind;
      59           2 :         ast->children = 3;
      60           2 :         (&ast->u.child)[0] = op0;
      61           2 :         (&ast->u.child)[1] = op1;
      62           2 :         (&ast->u.child)[2] = op2;
      63           2 :         return ast;
      64             : }
      65             : 
      66        1172 : ZEND_API zend_ast* zend_ast_create_dynamic(uint kind)
      67             : {
      68        1172 :         zend_ast *ast = emalloc(sizeof(zend_ast) + sizeof(zend_ast*) * 3); /* use 4 children as deafult */
      69        1172 :         ast->kind = kind;
      70        1172 :         ast->children = 0;
      71        1172 :         return ast;
      72             : }
      73             : 
      74        6590 : ZEND_API void zend_ast_dynamic_add(zend_ast **ast, zend_ast *op)
      75             : {
      76        6590 :         if ((*ast)->children >= 4 && (*ast)->children == ((*ast)->children & -(*ast)->children)) {
      77        1049 :                 *ast = erealloc(*ast, sizeof(zend_ast) + sizeof(zend_ast*) * ((*ast)->children * 2 + 1));
      78             :         }
      79        6590 :         (&(*ast)->u.child)[(*ast)->children++] = op;
      80        6590 : }
      81             : 
      82        1172 : ZEND_API void zend_ast_dynamic_shrink(zend_ast **ast)
      83             : {
      84        1172 :         *ast = erealloc(*ast, sizeof(zend_ast) + sizeof(zend_ast*) * ((*ast)->children - 1));
      85        1172 : }
      86             : 
      87        4754 : ZEND_API int zend_ast_is_ct_constant(zend_ast *ast)
      88             : {
      89             :         int i;
      90             : 
      91        4754 :         if (ast->kind == ZEND_CONST) {
      92        3468 :                 return !IS_CONSTANT_TYPE(Z_TYPE_P(ast->u.val));
      93             :         } else {
      94        7815 :                 for (i = 0; i < ast->children; i++) {
      95        6634 :                         if ((&ast->u.child)[i]) {
      96        3490 :                                 if (!zend_ast_is_ct_constant((&ast->u.child)[i])) {
      97         105 :                                         return 0;
      98             :                                 }
      99             :                         }
     100             :                 }
     101        1181 :                 return 1;
     102             :         }
     103             : }
     104             : 
     105        4896 : ZEND_API void zend_ast_evaluate(zval *result, zend_ast *ast, zend_class_entry *scope TSRMLS_DC)
     106             : {
     107             :         zval op1, op2;
     108             : 
     109        4896 :         switch (ast->kind) {
     110             :                 case ZEND_ADD:
     111          11 :                         zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC);
     112          11 :                         zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC);
     113          11 :                         add_function(result, &op1, &op2 TSRMLS_CC);
     114             :                         zval_dtor(&op1);
     115             :                         zval_dtor(&op2);
     116          11 :                         break;
     117             :                 case ZEND_SUB:
     118           0 :                         zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC);
     119           0 :                         zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC);
     120           0 :                         sub_function(result, &op1, &op2 TSRMLS_CC);
     121             :                         zval_dtor(&op1);
     122             :                         zval_dtor(&op2);
     123           0 :                         break;
     124             :                 case ZEND_MUL:
     125           4 :                         zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC);
     126           4 :                         zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC);
     127           4 :                         mul_function(result, &op1, &op2 TSRMLS_CC);
     128             :                         zval_dtor(&op1);
     129             :                         zval_dtor(&op2);
     130           4 :                         break;
     131             :                 case ZEND_POW:
     132           1 :                         zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC);
     133           1 :                         zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC);
     134           1 :                         pow_function(result, &op1, &op2 TSRMLS_CC);
     135             :                         zval_dtor(&op1);
     136             :                         zval_dtor(&op2);
     137           1 :                         break;
     138             :                 case ZEND_DIV:
     139           1 :                         zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC);
     140           1 :                         zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC);
     141           1 :                         div_function(result, &op1, &op2 TSRMLS_CC);
     142             :                         zval_dtor(&op1);
     143             :                         zval_dtor(&op2);
     144           1 :                         break;
     145             :                 case ZEND_MOD:
     146           0 :                         zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC);
     147           0 :                         zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC);
     148           0 :                         mod_function(result, &op1, &op2 TSRMLS_CC);
     149             :                         zval_dtor(&op1);
     150             :                         zval_dtor(&op2);
     151           0 :                         break;
     152             :                 case ZEND_SL:
     153           6 :                         zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC);
     154           6 :                         zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC);
     155           6 :                         shift_left_function(result, &op1, &op2 TSRMLS_CC);
     156             :                         zval_dtor(&op1);
     157             :                         zval_dtor(&op2);
     158           6 :                         break;
     159             :                 case ZEND_SR:
     160           0 :                         zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC);
     161           0 :                         zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC);
     162           0 :                         shift_right_function(result, &op1, &op2 TSRMLS_CC);
     163             :                         zval_dtor(&op1);
     164             :                         zval_dtor(&op2);
     165           0 :                         break;
     166             :                 case ZEND_CONCAT:
     167          12 :                         zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC);
     168          12 :                         zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC);
     169          12 :                         concat_function(result, &op1, &op2 TSRMLS_CC);
     170             :                         zval_dtor(&op1);
     171             :                         zval_dtor(&op2);
     172          12 :                         break;
     173             :                 case ZEND_BW_OR:
     174           2 :                         zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC);
     175           2 :                         zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC);
     176           2 :                         bitwise_or_function(result, &op1, &op2 TSRMLS_CC);
     177             :                         zval_dtor(&op1);
     178             :                         zval_dtor(&op2);
     179           2 :                         break;
     180             :                 case ZEND_BW_AND:
     181           0 :                         zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC);
     182           0 :                         zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC);
     183           0 :                         bitwise_and_function(result, &op1, &op2 TSRMLS_CC);
     184             :                         zval_dtor(&op1);
     185             :                         zval_dtor(&op2);
     186           0 :                         break;
     187             :                 case ZEND_BW_XOR:
     188           0 :                         zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC);
     189           0 :                         zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC);
     190           0 :                         bitwise_xor_function(result, &op1, &op2 TSRMLS_CC);
     191             :                         zval_dtor(&op1);
     192             :                         zval_dtor(&op2);
     193           0 :                         break;
     194             :                 case ZEND_BW_NOT:
     195           1 :                         zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC);
     196           1 :                         bitwise_not_function(result, &op1 TSRMLS_CC);
     197             :                         zval_dtor(&op1);
     198           1 :                         break;
     199             :                 case ZEND_BOOL_NOT:
     200           0 :                         zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC);
     201           0 :                         boolean_not_function(result, &op1 TSRMLS_CC);
     202             :                         zval_dtor(&op1);
     203           0 :                         break;
     204             :                 case ZEND_BOOL_XOR:
     205           2 :                         zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC);
     206           2 :                         zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC);
     207           2 :                         boolean_xor_function(result, &op1, &op2 TSRMLS_CC);
     208             :                         zval_dtor(&op1);
     209             :                         zval_dtor(&op2);
     210           2 :                         break;
     211             :                 case ZEND_IS_IDENTICAL:
     212           1 :                         zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC);
     213           1 :                         zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC);
     214           1 :                         is_identical_function(result, &op1, &op2 TSRMLS_CC);
     215             :                         zval_dtor(&op1);
     216             :                         zval_dtor(&op2);
     217           1 :                         break;
     218             :                 case ZEND_IS_NOT_IDENTICAL:
     219           1 :                         zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC);
     220           1 :                         zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC);
     221           1 :                         is_not_identical_function(result, &op1, &op2 TSRMLS_CC);
     222             :                         zval_dtor(&op1);
     223             :                         zval_dtor(&op2);
     224           1 :                         break;
     225             :                 case ZEND_IS_EQUAL:
     226           1 :                         zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC);
     227           1 :                         zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC);
     228           1 :                         is_equal_function(result, &op1, &op2 TSRMLS_CC);
     229             :                         zval_dtor(&op1);
     230             :                         zval_dtor(&op2);
     231           1 :                         break;
     232             :                 case ZEND_IS_NOT_EQUAL:
     233           1 :                         zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC);
     234           1 :                         zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC);
     235           1 :                         is_not_equal_function(result, &op1, &op2 TSRMLS_CC);
     236             :                         zval_dtor(&op1);
     237             :                         zval_dtor(&op2);
     238           1 :                         break;
     239             :                 case ZEND_IS_SMALLER:
     240           2 :                         zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC);
     241           2 :                         zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC);
     242           2 :                         is_smaller_function(result, &op1, &op2 TSRMLS_CC);
     243             :                         zval_dtor(&op1);
     244             :                         zval_dtor(&op2);
     245           2 :                         break;
     246             :                 case ZEND_IS_SMALLER_OR_EQUAL:
     247           2 :                         zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC);
     248           2 :                         zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC);
     249           2 :                         is_smaller_or_equal_function(result, &op1, &op2 TSRMLS_CC);
     250             :                         zval_dtor(&op1);
     251             :                         zval_dtor(&op2);
     252           2 :                         break;
     253             :                 case ZEND_CONST:
     254             :                         /* class constants may be updated in-place */
     255        3601 :                         if (scope) {
     256           9 :                                 if (IS_CONSTANT_TYPE(Z_TYPE_P(ast->u.val))) {
     257           6 :                                         zval_update_constant_ex(&ast->u.val, 1, scope TSRMLS_CC);
     258             :                                 }
     259           6 :                                 *result = *ast->u.val;
     260           6 :                                 zval_copy_ctor(result);
     261             :                         } else {
     262        3592 :                                 *result = *ast->u.val;
     263        3592 :                                 zval_copy_ctor(result);
     264        3592 :                                 if (IS_CONSTANT_TYPE(Z_TYPE_P(result))) {
     265         164 :                                         zval_update_constant_ex(&result, 1, scope TSRMLS_CC);
     266             :                                 }
     267             :                         }
     268        3582 :                         break;
     269             :                 case ZEND_BOOL_AND:
     270           2 :                         zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC);
     271           2 :                         if (zend_is_true(&op1 TSRMLS_CC)) {
     272           2 :                                 zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC);
     273           2 :                                 ZVAL_BOOL(result, zend_is_true(&op2 TSRMLS_CC));
     274             :                                 zval_dtor(&op2);
     275             :                         } else {
     276           0 :                                 ZVAL_BOOL(result, 0);
     277             :                         }
     278             :                         zval_dtor(&op1);
     279           2 :                         break;
     280             :                 case ZEND_BOOL_OR:
     281           2 :                         zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC);
     282           2 :                         if (zend_is_true(&op1 TSRMLS_CC)) {
     283           1 :                                 ZVAL_BOOL(result, 1);
     284             :                         } else {
     285           1 :                                 zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC);
     286           1 :                                 ZVAL_BOOL(result, zend_is_true(&op2 TSRMLS_CC));
     287             :                                 zval_dtor(&op2);
     288             :                         }
     289             :                         zval_dtor(&op1);
     290           2 :                         break;
     291             :                 case ZEND_SELECT:
     292           2 :                         zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC);
     293           2 :                         if (zend_is_true(&op1 TSRMLS_CC)) {
     294           1 :                                 if (!(&ast->u.child)[1]) {
     295           1 :                                         *result = op1;
     296             :                                 } else {
     297           0 :                                         zend_ast_evaluate(result, (&ast->u.child)[1], scope TSRMLS_CC);
     298             :                                         zval_dtor(&op1);
     299             :                                 }
     300             :                         } else {
     301           1 :                                 zend_ast_evaluate(result, (&ast->u.child)[2], scope TSRMLS_CC);
     302             :                                 zval_dtor(&op1);
     303             :                         }
     304           2 :                         break;
     305             :                 case ZEND_UNARY_PLUS:
     306           2 :                         ZVAL_LONG(&op1, 0);
     307           2 :                         zend_ast_evaluate(&op2, (&ast->u.child)[0], scope TSRMLS_CC);
     308           2 :                         add_function(result, &op1, &op2 TSRMLS_CC);
     309             :                         zval_dtor(&op2);
     310           2 :                         break;
     311             :                 case ZEND_UNARY_MINUS:
     312          51 :                         ZVAL_LONG(&op1, 0);
     313          51 :                         zend_ast_evaluate(&op2, (&ast->u.child)[0], scope TSRMLS_CC);
     314          51 :                         sub_function(result, &op1, &op2 TSRMLS_CC);
     315             :                         zval_dtor(&op2);
     316          51 :                         break;
     317             :                 case ZEND_INIT_ARRAY:
     318        1178 :                         INIT_PZVAL(result);
     319        1178 :                         array_init(result);
     320             :                         {
     321             :                                 int i;
     322             :                                 zend_bool has_key;
     323        4461 :                                 for (i = 0; i < ast->children; i+=2) {
     324             :                                         zval *expr;
     325        3302 :                                         MAKE_STD_ZVAL(expr);
     326        3302 :                                         if ((has_key = !!(&ast->u.child)[i])) {
     327         152 :                                                 zend_ast_evaluate(&op1, (&ast->u.child)[i], scope TSRMLS_CC);
     328             :                                         }
     329        3296 :                                         zend_ast_evaluate(expr, (&ast->u.child)[i+1], scope TSRMLS_CC);
     330        3283 :                                         zend_do_add_static_array_element(result, has_key?&op1:NULL, expr);
     331             :                                 }
     332             :                         }
     333        1159 :                         break;
     334             :                 case ZEND_FETCH_DIM_R:
     335          10 :                         zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC);
     336          10 :                         zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC);
     337             :                         {
     338             :                                 zval *tmp;
     339          10 :                                 zend_fetch_dimension_by_zval(&tmp, &op1, &op2 TSRMLS_CC);
     340          20 :                                 ZVAL_ZVAL(result, tmp, 1, 1);
     341             :                         }
     342             :                         zval_dtor(&op1);
     343             :                         zval_dtor(&op2);
     344          10 :                         break;
     345             :                 default:
     346           0 :                         zend_error(E_ERROR, "Unsupported constant expression");
     347             :         }
     348        4858 : }
     349             : 
     350           8 : ZEND_API zend_ast *zend_ast_copy(zend_ast *ast)
     351             : {
     352           8 :         if (ast == NULL) {
     353           0 :                 return NULL;
     354           8 :         } else if (ast->kind == ZEND_CONST) {
     355           6 :                 zend_ast *copy = zend_ast_create_constant(ast->u.val);
     356           6 :                 zval_copy_ctor(copy->u.val);
     357           6 :                 return copy;
     358           2 :         } else if (ast->children) {
     359           2 :                 zend_ast *new = emalloc(sizeof(zend_ast) + sizeof(zend_ast*) * (ast->children - 1));
     360             :                 int i;
     361           2 :                 new->kind = ast->kind;
     362           2 :                 new->children = ast->children;
     363           8 :                 for (i = 0; i < ast->children; i++) {
     364           6 :                         (&new->u.child)[i] = zend_ast_copy((&ast->u.child)[i]);
     365             :                 }
     366           2 :                 return new;
     367             :         }
     368           0 :         return zend_ast_create_dynamic(ast->kind);
     369             : }
     370             : 
     371        4895 : ZEND_API void zend_ast_destroy(zend_ast *ast)
     372             : {
     373             :         int i;
     374             : 
     375        4895 :         if (ast->kind == ZEND_CONST) {
     376        3604 :                 zval_dtor(ast->u.val);
     377             :         } else {
     378        8069 :                 for (i = 0; i < ast->children; i++) {
     379        6778 :                         if ((&ast->u.child)[i]) {
     380        3629 :                                 zend_ast_destroy((&ast->u.child)[i]);
     381             :                         }
     382             :                 }
     383             :         }
     384        4895 :         efree(ast);
     385        4895 : }

Generated by: LCOV version 1.10

Generated at Mon, 04 Aug 2014 15:49:00 +0000 (18 days ago)

Copyright © 2005-2014 The PHP Group
All rights reserved.