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: 176 204 86.3 %
Date: 2014-07-21 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       20942 : ZEND_API zend_ast *zend_ast_create_constant(zval *zv)
      27             : {
      28       20942 :         zend_ast *ast = emalloc(sizeof(zend_ast) + sizeof(zval));
      29       20942 :         ast->kind = ZEND_CONST;
      30       20942 :         ast->children = 0;
      31       20942 :         ast->u.val = (zval*)(ast + 1);
      32       41884 :         INIT_PZVAL_COPY(ast->u.val, zv);
      33       20942 :         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        1170 : ZEND_API zend_ast* zend_ast_create_dynamic(uint kind)
      67             : {
      68        1170 :         zend_ast *ast = emalloc(sizeof(zend_ast) + sizeof(zend_ast*) * 3); /* use 4 children as deafult */
      69        1170 :         ast->kind = kind;
      70        1170 :         ast->children = 0;
      71        1170 :         return ast;
      72             : }
      73             : 
      74        6586 : ZEND_API void zend_ast_dynamic_add(zend_ast **ast, zend_ast *op)
      75             : {
      76        6586 :         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        6586 :         (&(*ast)->u.child)[(*ast)->children++] = op;
      80        6586 : }
      81             : 
      82        1170 : ZEND_API void zend_ast_dynamic_shrink(zend_ast **ast)
      83             : {
      84        1170 :         *ast = erealloc(*ast, sizeof(zend_ast) + sizeof(zend_ast*) * ((*ast)->children - 1));
      85        1170 : }
      86             : 
      87        4750 : ZEND_API int zend_ast_is_ct_constant(zend_ast *ast)
      88             : {
      89             :         int i;
      90             : 
      91        4750 :         if (ast->kind == ZEND_CONST) {
      92        3466 :                 return !IS_CONSTANT_TYPE(Z_TYPE_P(ast->u.val));
      93             :         } else {
      94        7811 :                 for (i = 0; i < ast->children; i++) {
      95        6630 :                         if ((&ast->u.child)[i]) {
      96        3488 :                                 if (!zend_ast_is_ct_constant((&ast->u.child)[i])) {
      97         103 :                                         return 0;
      98             :                                 }
      99             :                         }
     100             :                 }
     101        1181 :                 return 1;
     102             :         }
     103             : }
     104             : 
     105        4888 : ZEND_API void zend_ast_evaluate(zval *result, zend_ast *ast, zend_class_entry *scope TSRMLS_DC)
     106             : {
     107             :         zval op1, op2;
     108             : 
     109        4888 :         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        3597 :                         *result = *ast->u.val;
     255        3597 :                         zval_copy_ctor(result);
     256        3597 :                         if (IS_CONSTANT_TYPE(Z_TYPE_P(result))) {
     257         166 :                                 zval_update_constant_ex(&result, 1, scope TSRMLS_CC);
     258             :                         }
     259        3582 :                         break;
     260             :                 case ZEND_BOOL_AND:
     261           2 :                         zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC);
     262           2 :                         if (zend_is_true(&op1 TSRMLS_CC)) {
     263           2 :                                 zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC);
     264           2 :                                 ZVAL_BOOL(result, zend_is_true(&op2 TSRMLS_CC));
     265             :                                 zval_dtor(&op2);
     266             :                         } else {
     267           0 :                                 ZVAL_BOOL(result, 0);
     268             :                         }
     269             :                         zval_dtor(&op1);
     270           2 :                         break;
     271             :                 case ZEND_BOOL_OR:
     272           2 :                         zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC);
     273           2 :                         if (zend_is_true(&op1 TSRMLS_CC)) {
     274           1 :                                 ZVAL_BOOL(result, 1);
     275             :                         } else {
     276           1 :                                 zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC);
     277           1 :                                 ZVAL_BOOL(result, zend_is_true(&op2 TSRMLS_CC));
     278             :                                 zval_dtor(&op2);
     279             :                         }
     280             :                         zval_dtor(&op1);
     281           2 :                         break;
     282             :                 case ZEND_SELECT:
     283           2 :                         zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC);
     284           2 :                         if (zend_is_true(&op1 TSRMLS_CC)) {
     285           1 :                                 if (!(&ast->u.child)[1]) {
     286           1 :                                         *result = op1;
     287             :                                 } else {
     288           0 :                                         zend_ast_evaluate(result, (&ast->u.child)[1], scope TSRMLS_CC);
     289             :                                         zval_dtor(&op1);
     290             :                                 }
     291             :                         } else {
     292           1 :                                 zend_ast_evaluate(result, (&ast->u.child)[2], scope TSRMLS_CC);
     293             :                                 zval_dtor(&op1);
     294             :                         }
     295           2 :                         break;
     296             :                 case ZEND_UNARY_PLUS:
     297           2 :                         ZVAL_LONG(&op1, 0);
     298           2 :                         zend_ast_evaluate(&op2, (&ast->u.child)[0], scope TSRMLS_CC);
     299           2 :                         add_function(result, &op1, &op2 TSRMLS_CC);
     300             :                         zval_dtor(&op2);
     301           2 :                         break;
     302             :                 case ZEND_UNARY_MINUS:
     303          51 :                         ZVAL_LONG(&op1, 0);
     304          51 :                         zend_ast_evaluate(&op2, (&ast->u.child)[0], scope TSRMLS_CC);
     305          51 :                         sub_function(result, &op1, &op2 TSRMLS_CC);
     306             :                         zval_dtor(&op2);
     307          51 :                         break;
     308             :                 case ZEND_INIT_ARRAY:
     309        1174 :                         INIT_PZVAL(result);
     310        1174 :                         array_init(result);
     311             :                         {
     312             :                                 int i;
     313             :                                 zend_bool has_key;
     314        4457 :                                 for (i = 0; i < ast->children; i+=2) {
     315             :                                         zval *expr;
     316        3298 :                                         MAKE_STD_ZVAL(expr);
     317        3298 :                                         if ((has_key = !!(&ast->u.child)[i])) {
     318         152 :                                                 zend_ast_evaluate(&op1, (&ast->u.child)[i], scope TSRMLS_CC);
     319             :                                         }
     320        3292 :                                         zend_ast_evaluate(expr, (&ast->u.child)[i+1], scope TSRMLS_CC);
     321        3283 :                                         zend_do_add_static_array_element(result, has_key?&op1:NULL, expr);
     322             :                                 }
     323             :                         }
     324        1159 :                         break;
     325             :                 case ZEND_FETCH_DIM_R:
     326          10 :                         zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC);
     327          10 :                         zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC);
     328             :                         {
     329             :                                 zval *tmp;
     330          10 :                                 zend_fetch_dimension_by_zval(&tmp, &op1, &op2 TSRMLS_CC);
     331          20 :                                 ZVAL_ZVAL(result, tmp, 1, 1);
     332             :                         }
     333             :                         zval_dtor(&op1);
     334             :                         zval_dtor(&op2);
     335          10 :                         break;
     336             :                 default:
     337           0 :                         zend_error(E_ERROR, "Unsupported constant expression");
     338             :         }
     339        4858 : }
     340             : 
     341           8 : ZEND_API zend_ast *zend_ast_copy(zend_ast *ast)
     342             : {
     343           8 :         if (ast == NULL) {
     344           0 :                 return NULL;
     345           8 :         } else if (ast->kind == ZEND_CONST) {
     346           6 :                 zend_ast *copy = zend_ast_create_constant(ast->u.val);
     347           6 :                 zval_copy_ctor(copy->u.val);
     348           6 :                 return copy;
     349           2 :         } else if (ast->children) {
     350           2 :                 zend_ast *new = emalloc(sizeof(zend_ast) + sizeof(zend_ast*) * (ast->children - 1));
     351             :                 int i;
     352           2 :                 new->kind = ast->kind;
     353           2 :                 new->children = ast->children;
     354           8 :                 for (i = 0; i < ast->children; i++) {
     355           6 :                         (&new->u.child)[i] = zend_ast_copy((&ast->u.child)[i]);
     356             :                 }
     357           2 :                 return new;
     358             :         }
     359           0 :         return zend_ast_create_dynamic(ast->kind);
     360             : }
     361             : 
     362        4880 : ZEND_API void zend_ast_destroy(zend_ast *ast)
     363             : {
     364             :         int i;
     365             : 
     366        4880 :         if (ast->kind == ZEND_CONST) {
     367        3595 :                 zval_dtor(ast->u.val);
     368             :         } else {
     369        8051 :                 for (i = 0; i < ast->children; i++) {
     370        6766 :                         if ((&ast->u.child)[i]) {
     371        3619 :                                 zend_ast_destroy((&ast->u.child)[i]);
     372             :                         }
     373             :                 }
     374             :         }
     375        4880 :         efree(ast);
     376        4880 : }

Generated by: LCOV version 1.10

Generated at Tue, 22 Jul 2014 01:33:05 +0000 (40 hours ago)

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