zend_ast.c 12 KB

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