zend_ast.c 67 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430
  1. /*
  2. +----------------------------------------------------------------------+
  3. | Zend Engine |
  4. +----------------------------------------------------------------------+
  5. | Copyright (c) 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@php.net> |
  17. +----------------------------------------------------------------------+
  18. */
  19. #include "zend_ast.h"
  20. #include "zend_API.h"
  21. #include "zend_operators.h"
  22. #include "zend_language_parser.h"
  23. #include "zend_smart_str.h"
  24. #include "zend_exceptions.h"
  25. #include "zend_constants.h"
  26. #include "zend_enum.h"
  27. ZEND_API zend_ast_process_t zend_ast_process = NULL;
  28. static inline void *zend_ast_alloc(size_t size) {
  29. return zend_arena_alloc(&CG(ast_arena), size);
  30. }
  31. static inline void *zend_ast_realloc(void *old, size_t old_size, size_t new_size) {
  32. void *new = zend_ast_alloc(new_size);
  33. memcpy(new, old, old_size);
  34. return new;
  35. }
  36. static inline size_t zend_ast_list_size(uint32_t children) {
  37. return sizeof(zend_ast_list) - sizeof(zend_ast *) + sizeof(zend_ast *) * children;
  38. }
  39. ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_znode(znode *node) {
  40. zend_ast_znode *ast;
  41. ast = zend_ast_alloc(sizeof(zend_ast_znode));
  42. ast->kind = ZEND_AST_ZNODE;
  43. ast->attr = 0;
  44. ast->lineno = CG(zend_lineno);
  45. ast->node = *node;
  46. return (zend_ast *) ast;
  47. }
  48. static zend_always_inline zend_ast * zend_ast_create_zval_int(zval *zv, uint32_t attr, uint32_t lineno) {
  49. zend_ast_zval *ast;
  50. ast = zend_ast_alloc(sizeof(zend_ast_zval));
  51. ast->kind = ZEND_AST_ZVAL;
  52. ast->attr = attr;
  53. ZVAL_COPY_VALUE(&ast->val, zv);
  54. Z_LINENO(ast->val) = lineno;
  55. return (zend_ast *) ast;
  56. }
  57. ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_zval_with_lineno(zval *zv, uint32_t lineno) {
  58. return zend_ast_create_zval_int(zv, 0, lineno);
  59. }
  60. ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_zval_ex(zval *zv, zend_ast_attr attr) {
  61. return zend_ast_create_zval_int(zv, attr, CG(zend_lineno));
  62. }
  63. ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_zval(zval *zv) {
  64. return zend_ast_create_zval_int(zv, 0, CG(zend_lineno));
  65. }
  66. ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_zval_from_str(zend_string *str) {
  67. zval zv;
  68. ZVAL_STR(&zv, str);
  69. return zend_ast_create_zval_int(&zv, 0, CG(zend_lineno));
  70. }
  71. ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_zval_from_long(zend_long lval) {
  72. zval zv;
  73. ZVAL_LONG(&zv, lval);
  74. return zend_ast_create_zval_int(&zv, 0, CG(zend_lineno));
  75. }
  76. ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_constant(zend_string *name, zend_ast_attr attr) {
  77. zend_ast_zval *ast;
  78. ast = zend_ast_alloc(sizeof(zend_ast_zval));
  79. ast->kind = ZEND_AST_CONSTANT;
  80. ast->attr = attr;
  81. ZVAL_STR(&ast->val, name);
  82. Z_LINENO(ast->val) = CG(zend_lineno);
  83. return (zend_ast *) ast;
  84. }
  85. ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_class_const_or_name(zend_ast *class_name, zend_ast *name) {
  86. zend_string *name_str = zend_ast_get_str(name);
  87. if (zend_string_equals_literal_ci(name_str, "class")) {
  88. zend_string_release(name_str);
  89. return zend_ast_create(ZEND_AST_CLASS_NAME, class_name);
  90. } else {
  91. return zend_ast_create(ZEND_AST_CLASS_CONST, class_name, name);
  92. }
  93. }
  94. ZEND_API zend_ast *zend_ast_create_decl(
  95. zend_ast_kind kind, uint32_t flags, uint32_t start_lineno, zend_string *doc_comment,
  96. zend_string *name, zend_ast *child0, zend_ast *child1, zend_ast *child2, zend_ast *child3, zend_ast *child4
  97. ) {
  98. zend_ast_decl *ast;
  99. ast = zend_ast_alloc(sizeof(zend_ast_decl));
  100. ast->kind = kind;
  101. ast->attr = 0;
  102. ast->start_lineno = start_lineno;
  103. ast->end_lineno = CG(zend_lineno);
  104. ast->flags = flags;
  105. ast->lex_pos = LANG_SCNG(yy_text);
  106. ast->doc_comment = doc_comment;
  107. ast->name = name;
  108. ast->child[0] = child0;
  109. ast->child[1] = child1;
  110. ast->child[2] = child2;
  111. ast->child[3] = child3;
  112. ast->child[4] = child4;
  113. return (zend_ast *) ast;
  114. }
  115. #if ZEND_AST_SPEC
  116. ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_0(zend_ast_kind kind) {
  117. zend_ast *ast;
  118. ZEND_ASSERT(kind >> ZEND_AST_NUM_CHILDREN_SHIFT == 0);
  119. ast = zend_ast_alloc(zend_ast_size(0));
  120. ast->kind = kind;
  121. ast->attr = 0;
  122. ast->lineno = CG(zend_lineno);
  123. return ast;
  124. }
  125. ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_1(zend_ast_kind kind, zend_ast *child) {
  126. zend_ast *ast;
  127. uint32_t lineno;
  128. ZEND_ASSERT(kind >> ZEND_AST_NUM_CHILDREN_SHIFT == 1);
  129. ast = zend_ast_alloc(zend_ast_size(1));
  130. ast->kind = kind;
  131. ast->attr = 0;
  132. ast->child[0] = child;
  133. if (child) {
  134. lineno = zend_ast_get_lineno(child);
  135. } else {
  136. lineno = CG(zend_lineno);
  137. }
  138. ast->lineno = lineno;
  139. return ast;
  140. }
  141. ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_2(zend_ast_kind kind, zend_ast *child1, zend_ast *child2) {
  142. zend_ast *ast;
  143. uint32_t lineno;
  144. ZEND_ASSERT(kind >> ZEND_AST_NUM_CHILDREN_SHIFT == 2);
  145. ast = zend_ast_alloc(zend_ast_size(2));
  146. ast->kind = kind;
  147. ast->attr = 0;
  148. ast->child[0] = child1;
  149. ast->child[1] = child2;
  150. if (child1) {
  151. lineno = zend_ast_get_lineno(child1);
  152. } else if (child2) {
  153. lineno = zend_ast_get_lineno(child2);
  154. } else {
  155. lineno = CG(zend_lineno);
  156. }
  157. ast->lineno = lineno;
  158. return ast;
  159. }
  160. ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_3(zend_ast_kind kind, zend_ast *child1, zend_ast *child2, zend_ast *child3) {
  161. zend_ast *ast;
  162. uint32_t lineno;
  163. ZEND_ASSERT(kind >> ZEND_AST_NUM_CHILDREN_SHIFT == 3);
  164. ast = zend_ast_alloc(zend_ast_size(3));
  165. ast->kind = kind;
  166. ast->attr = 0;
  167. ast->child[0] = child1;
  168. ast->child[1] = child2;
  169. ast->child[2] = child3;
  170. if (child1) {
  171. lineno = zend_ast_get_lineno(child1);
  172. } else if (child2) {
  173. lineno = zend_ast_get_lineno(child2);
  174. } else if (child3) {
  175. lineno = zend_ast_get_lineno(child3);
  176. } else {
  177. lineno = CG(zend_lineno);
  178. }
  179. ast->lineno = lineno;
  180. return ast;
  181. }
  182. ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_4(zend_ast_kind kind, zend_ast *child1, zend_ast *child2, zend_ast *child3, zend_ast *child4) {
  183. zend_ast *ast;
  184. uint32_t lineno;
  185. ZEND_ASSERT(kind >> ZEND_AST_NUM_CHILDREN_SHIFT == 4);
  186. ast = zend_ast_alloc(zend_ast_size(4));
  187. ast->kind = kind;
  188. ast->attr = 0;
  189. ast->child[0] = child1;
  190. ast->child[1] = child2;
  191. ast->child[2] = child3;
  192. ast->child[3] = child4;
  193. if (child1) {
  194. lineno = zend_ast_get_lineno(child1);
  195. } else if (child2) {
  196. lineno = zend_ast_get_lineno(child2);
  197. } else if (child3) {
  198. lineno = zend_ast_get_lineno(child3);
  199. } else if (child4) {
  200. lineno = zend_ast_get_lineno(child4);
  201. } else {
  202. lineno = CG(zend_lineno);
  203. }
  204. ast->lineno = lineno;
  205. return ast;
  206. }
  207. ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_5(zend_ast_kind kind, zend_ast *child1, zend_ast *child2, zend_ast *child3, zend_ast *child4, zend_ast *child5) {
  208. zend_ast *ast;
  209. uint32_t lineno;
  210. ZEND_ASSERT(kind >> ZEND_AST_NUM_CHILDREN_SHIFT == 5);
  211. ast = zend_ast_alloc(zend_ast_size(5));
  212. ast->kind = kind;
  213. ast->attr = 0;
  214. ast->child[0] = child1;
  215. ast->child[1] = child2;
  216. ast->child[2] = child3;
  217. ast->child[3] = child4;
  218. ast->child[4] = child5;
  219. if (child1) {
  220. lineno = zend_ast_get_lineno(child1);
  221. } else if (child2) {
  222. lineno = zend_ast_get_lineno(child2);
  223. } else if (child3) {
  224. lineno = zend_ast_get_lineno(child3);
  225. } else if (child4) {
  226. lineno = zend_ast_get_lineno(child4);
  227. } else if (child5) {
  228. lineno = zend_ast_get_lineno(child5);
  229. } else {
  230. lineno = CG(zend_lineno);
  231. }
  232. ast->lineno = lineno;
  233. return ast;
  234. }
  235. ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_list_0(zend_ast_kind kind) {
  236. zend_ast *ast;
  237. zend_ast_list *list;
  238. ast = zend_ast_alloc(zend_ast_list_size(4));
  239. list = (zend_ast_list *) ast;
  240. list->kind = kind;
  241. list->attr = 0;
  242. list->lineno = CG(zend_lineno);
  243. list->children = 0;
  244. return ast;
  245. }
  246. ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_list_1(zend_ast_kind kind, zend_ast *child) {
  247. zend_ast *ast;
  248. zend_ast_list *list;
  249. uint32_t lineno;
  250. ast = zend_ast_alloc(zend_ast_list_size(4));
  251. list = (zend_ast_list *) ast;
  252. list->kind = kind;
  253. list->attr = 0;
  254. list->children = 1;
  255. list->child[0] = child;
  256. if (child) {
  257. lineno = zend_ast_get_lineno(child);
  258. if (lineno > CG(zend_lineno)) {
  259. lineno = CG(zend_lineno);
  260. }
  261. } else {
  262. lineno = CG(zend_lineno);
  263. }
  264. list->lineno = lineno;
  265. return ast;
  266. }
  267. ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_list_2(zend_ast_kind kind, zend_ast *child1, zend_ast *child2) {
  268. zend_ast *ast;
  269. zend_ast_list *list;
  270. uint32_t lineno;
  271. ast = zend_ast_alloc(zend_ast_list_size(4));
  272. list = (zend_ast_list *) ast;
  273. list->kind = kind;
  274. list->attr = 0;
  275. list->children = 2;
  276. list->child[0] = child1;
  277. list->child[1] = child2;
  278. if (child1) {
  279. lineno = zend_ast_get_lineno(child1);
  280. if (lineno > CG(zend_lineno)) {
  281. lineno = CG(zend_lineno);
  282. }
  283. } else if (child2) {
  284. lineno = zend_ast_get_lineno(child2);
  285. if (lineno > CG(zend_lineno)) {
  286. lineno = CG(zend_lineno);
  287. }
  288. } else {
  289. list->children = 0;
  290. lineno = CG(zend_lineno);
  291. }
  292. list->lineno = lineno;
  293. return ast;
  294. }
  295. #else
  296. static zend_ast *zend_ast_create_from_va_list(zend_ast_kind kind, zend_ast_attr attr, va_list va) {
  297. uint32_t i, children = kind >> ZEND_AST_NUM_CHILDREN_SHIFT;
  298. zend_ast *ast;
  299. ast = zend_ast_alloc(zend_ast_size(children));
  300. ast->kind = kind;
  301. ast->attr = attr;
  302. ast->lineno = (uint32_t) -1;
  303. for (i = 0; i < children; ++i) {
  304. ast->child[i] = va_arg(va, zend_ast *);
  305. if (ast->child[i] != NULL) {
  306. uint32_t lineno = zend_ast_get_lineno(ast->child[i]);
  307. if (lineno < ast->lineno) {
  308. ast->lineno = lineno;
  309. }
  310. }
  311. }
  312. if (ast->lineno == UINT_MAX) {
  313. ast->lineno = CG(zend_lineno);
  314. }
  315. return ast;
  316. }
  317. ZEND_API zend_ast *zend_ast_create_ex(zend_ast_kind kind, zend_ast_attr attr, ...) {
  318. va_list va;
  319. zend_ast *ast;
  320. va_start(va, attr);
  321. ast = zend_ast_create_from_va_list(kind, attr, va);
  322. va_end(va);
  323. return ast;
  324. }
  325. ZEND_API zend_ast *zend_ast_create(zend_ast_kind kind, ...) {
  326. va_list va;
  327. zend_ast *ast;
  328. va_start(va, kind);
  329. ast = zend_ast_create_from_va_list(kind, 0, va);
  330. va_end(va);
  331. return ast;
  332. }
  333. ZEND_API zend_ast *zend_ast_create_list(uint32_t init_children, zend_ast_kind kind, ...) {
  334. zend_ast *ast;
  335. zend_ast_list *list;
  336. ast = zend_ast_alloc(zend_ast_list_size(4));
  337. list = (zend_ast_list *) ast;
  338. list->kind = kind;
  339. list->attr = 0;
  340. list->lineno = CG(zend_lineno);
  341. list->children = 0;
  342. {
  343. va_list va;
  344. uint32_t i;
  345. va_start(va, kind);
  346. for (i = 0; i < init_children; ++i) {
  347. zend_ast *child = va_arg(va, zend_ast *);
  348. ast = zend_ast_list_add(ast, child);
  349. if (child != NULL) {
  350. uint32_t lineno = zend_ast_get_lineno(child);
  351. if (lineno < ast->lineno) {
  352. ast->lineno = lineno;
  353. }
  354. }
  355. }
  356. va_end(va);
  357. }
  358. return ast;
  359. }
  360. #endif
  361. static inline bool is_power_of_two(uint32_t n) {
  362. return ((n != 0) && (n == (n & (~n + 1))));
  363. }
  364. ZEND_API zend_ast * ZEND_FASTCALL zend_ast_list_add(zend_ast *ast, zend_ast *op) {
  365. zend_ast_list *list = zend_ast_get_list(ast);
  366. if (list->children >= 4 && is_power_of_two(list->children)) {
  367. list = zend_ast_realloc(list,
  368. zend_ast_list_size(list->children), zend_ast_list_size(list->children * 2));
  369. }
  370. list->child[list->children++] = op;
  371. return (zend_ast *) list;
  372. }
  373. static zend_result zend_ast_add_array_element(zval *result, zval *offset, zval *expr)
  374. {
  375. if (Z_TYPE_P(offset) == IS_UNDEF) {
  376. if (!zend_hash_next_index_insert(Z_ARRVAL_P(result), expr)) {
  377. zend_throw_error(NULL,
  378. "Cannot add element to the array as the next element is already occupied");
  379. return FAILURE;
  380. }
  381. return SUCCESS;
  382. }
  383. if (array_set_zval_key(Z_ARRVAL_P(result), offset, expr) == FAILURE) {
  384. return FAILURE;
  385. }
  386. zval_ptr_dtor_nogc(offset);
  387. zval_ptr_dtor_nogc(expr);
  388. return SUCCESS;
  389. }
  390. static zend_result zend_ast_add_unpacked_element(zval *result, zval *expr) {
  391. if (EXPECTED(Z_TYPE_P(expr) == IS_ARRAY)) {
  392. HashTable *ht = Z_ARRVAL_P(expr);
  393. zval *val;
  394. zend_string *key;
  395. ZEND_HASH_FOREACH_STR_KEY_VAL(ht, key, val) {
  396. if (key) {
  397. zend_hash_update(Z_ARRVAL_P(result), key, val);
  398. } else {
  399. if (!zend_hash_next_index_insert(Z_ARRVAL_P(result), val)) {
  400. zend_throw_error(NULL,
  401. "Cannot add element to the array as the next element is already occupied");
  402. return FAILURE;
  403. }
  404. }
  405. Z_TRY_ADDREF_P(val);
  406. } ZEND_HASH_FOREACH_END();
  407. return SUCCESS;
  408. }
  409. /* Objects or references cannot occur in a constant expression. */
  410. zend_throw_error(NULL, "Only arrays and Traversables can be unpacked");
  411. return FAILURE;
  412. }
  413. zend_class_entry *zend_ast_fetch_class(zend_ast *ast, zend_class_entry *scope)
  414. {
  415. return zend_fetch_class_with_scope(zend_ast_get_str(ast), (ast->attr >> ZEND_CONST_EXPR_NEW_FETCH_TYPE_SHIFT) | ZEND_FETCH_CLASS_EXCEPTION, scope);
  416. }
  417. ZEND_API zend_result ZEND_FASTCALL zend_ast_evaluate(zval *result, zend_ast *ast, zend_class_entry *scope)
  418. {
  419. zval op1, op2;
  420. zend_result ret = SUCCESS;
  421. switch (ast->kind) {
  422. case ZEND_AST_BINARY_OP:
  423. if (UNEXPECTED(zend_ast_evaluate(&op1, ast->child[0], scope) != SUCCESS)) {
  424. ret = FAILURE;
  425. } else if (UNEXPECTED(zend_ast_evaluate(&op2, ast->child[1], scope) != SUCCESS)) {
  426. zval_ptr_dtor_nogc(&op1);
  427. ret = FAILURE;
  428. } else {
  429. binary_op_type op = get_binary_op(ast->attr);
  430. ret = op(result, &op1, &op2);
  431. zval_ptr_dtor_nogc(&op1);
  432. zval_ptr_dtor_nogc(&op2);
  433. }
  434. break;
  435. case ZEND_AST_GREATER:
  436. case ZEND_AST_GREATER_EQUAL:
  437. if (UNEXPECTED(zend_ast_evaluate(&op1, ast->child[0], scope) != SUCCESS)) {
  438. ret = FAILURE;
  439. } else if (UNEXPECTED(zend_ast_evaluate(&op2, ast->child[1], scope) != SUCCESS)) {
  440. zval_ptr_dtor_nogc(&op1);
  441. ret = FAILURE;
  442. } else {
  443. /* op1 > op2 is the same as op2 < op1 */
  444. binary_op_type op = ast->kind == ZEND_AST_GREATER
  445. ? is_smaller_function : is_smaller_or_equal_function;
  446. ret = op(result, &op2, &op1);
  447. zval_ptr_dtor_nogc(&op1);
  448. zval_ptr_dtor_nogc(&op2);
  449. }
  450. break;
  451. case ZEND_AST_UNARY_OP:
  452. if (UNEXPECTED(zend_ast_evaluate(&op1, ast->child[0], scope) != SUCCESS)) {
  453. ret = FAILURE;
  454. } else {
  455. unary_op_type op = get_unary_op(ast->attr);
  456. ret = op(result, &op1);
  457. zval_ptr_dtor_nogc(&op1);
  458. }
  459. break;
  460. case ZEND_AST_ZVAL:
  461. {
  462. zval *zv = zend_ast_get_zval(ast);
  463. ZVAL_COPY(result, zv);
  464. break;
  465. }
  466. case ZEND_AST_CONSTANT:
  467. {
  468. zend_string *name = zend_ast_get_constant_name(ast);
  469. zval *zv = zend_get_constant_ex(name, scope, ast->attr);
  470. if (UNEXPECTED(zv == NULL)) {
  471. ZVAL_UNDEF(result);
  472. return FAILURE;
  473. }
  474. ZVAL_COPY_OR_DUP(result, zv);
  475. break;
  476. }
  477. case ZEND_AST_CONSTANT_CLASS:
  478. if (scope) {
  479. ZVAL_STR_COPY(result, scope->name);
  480. } else {
  481. ZVAL_EMPTY_STRING(result);
  482. }
  483. break;
  484. case ZEND_AST_CLASS_NAME:
  485. if (!scope) {
  486. zend_throw_error(NULL, "Cannot use \"self\" when no class scope is active");
  487. return FAILURE;
  488. }
  489. if (ast->attr == ZEND_FETCH_CLASS_SELF) {
  490. ZVAL_STR_COPY(result, scope->name);
  491. } else if (ast->attr == ZEND_FETCH_CLASS_PARENT) {
  492. if (!scope->parent) {
  493. zend_throw_error(NULL,
  494. "Cannot use \"parent\" when current class scope has no parent");
  495. return FAILURE;
  496. }
  497. ZVAL_STR_COPY(result, scope->parent->name);
  498. } else {
  499. ZEND_ASSERT(0 && "Should have errored during compilation");
  500. }
  501. break;
  502. case ZEND_AST_AND:
  503. if (UNEXPECTED(zend_ast_evaluate(&op1, ast->child[0], scope) != SUCCESS)) {
  504. ret = FAILURE;
  505. break;
  506. }
  507. if (zend_is_true(&op1)) {
  508. if (UNEXPECTED(zend_ast_evaluate(&op2, ast->child[1], scope) != SUCCESS)) {
  509. zval_ptr_dtor_nogc(&op1);
  510. ret = FAILURE;
  511. break;
  512. }
  513. ZVAL_BOOL(result, zend_is_true(&op2));
  514. zval_ptr_dtor_nogc(&op2);
  515. } else {
  516. ZVAL_FALSE(result);
  517. }
  518. zval_ptr_dtor_nogc(&op1);
  519. break;
  520. case ZEND_AST_OR:
  521. if (UNEXPECTED(zend_ast_evaluate(&op1, ast->child[0], scope) != SUCCESS)) {
  522. ret = FAILURE;
  523. break;
  524. }
  525. if (zend_is_true(&op1)) {
  526. ZVAL_TRUE(result);
  527. } else {
  528. if (UNEXPECTED(zend_ast_evaluate(&op2, ast->child[1], scope) != SUCCESS)) {
  529. zval_ptr_dtor_nogc(&op1);
  530. ret = FAILURE;
  531. break;
  532. }
  533. ZVAL_BOOL(result, zend_is_true(&op2));
  534. zval_ptr_dtor_nogc(&op2);
  535. }
  536. zval_ptr_dtor_nogc(&op1);
  537. break;
  538. case ZEND_AST_CONDITIONAL:
  539. if (UNEXPECTED(zend_ast_evaluate(&op1, ast->child[0], scope) != SUCCESS)) {
  540. ret = FAILURE;
  541. break;
  542. }
  543. if (zend_is_true(&op1)) {
  544. if (!ast->child[1]) {
  545. *result = op1;
  546. } else {
  547. if (UNEXPECTED(zend_ast_evaluate(result, ast->child[1], scope) != SUCCESS)) {
  548. zval_ptr_dtor_nogc(&op1);
  549. ret = FAILURE;
  550. break;
  551. }
  552. zval_ptr_dtor_nogc(&op1);
  553. }
  554. } else {
  555. if (UNEXPECTED(zend_ast_evaluate(result, ast->child[2], scope) != SUCCESS)) {
  556. zval_ptr_dtor_nogc(&op1);
  557. ret = FAILURE;
  558. break;
  559. }
  560. zval_ptr_dtor_nogc(&op1);
  561. }
  562. break;
  563. case ZEND_AST_COALESCE:
  564. if (UNEXPECTED(zend_ast_evaluate(&op1, ast->child[0], scope) != SUCCESS)) {
  565. ret = FAILURE;
  566. break;
  567. }
  568. if (Z_TYPE(op1) > IS_NULL) {
  569. *result = op1;
  570. } else {
  571. if (UNEXPECTED(zend_ast_evaluate(result, ast->child[1], scope) != SUCCESS)) {
  572. zval_ptr_dtor_nogc(&op1);
  573. ret = FAILURE;
  574. break;
  575. }
  576. zval_ptr_dtor_nogc(&op1);
  577. }
  578. break;
  579. case ZEND_AST_UNARY_PLUS:
  580. if (UNEXPECTED(zend_ast_evaluate(&op2, ast->child[0], scope) != SUCCESS)) {
  581. ret = FAILURE;
  582. } else {
  583. ZVAL_LONG(&op1, 0);
  584. ret = add_function(result, &op1, &op2);
  585. zval_ptr_dtor_nogc(&op2);
  586. }
  587. break;
  588. case ZEND_AST_UNARY_MINUS:
  589. if (UNEXPECTED(zend_ast_evaluate(&op2, ast->child[0], scope) != SUCCESS)) {
  590. ret = FAILURE;
  591. } else {
  592. ZVAL_LONG(&op1, 0);
  593. ret = sub_function(result, &op1, &op2);
  594. zval_ptr_dtor_nogc(&op2);
  595. }
  596. break;
  597. case ZEND_AST_ARRAY:
  598. {
  599. uint32_t i;
  600. zend_ast_list *list = zend_ast_get_list(ast);
  601. if (!list->children) {
  602. ZVAL_EMPTY_ARRAY(result);
  603. break;
  604. }
  605. array_init(result);
  606. for (i = 0; i < list->children; i++) {
  607. zend_ast *elem = list->child[i];
  608. if (elem->kind == ZEND_AST_UNPACK) {
  609. if (UNEXPECTED(zend_ast_evaluate(&op1, elem->child[0], scope) != SUCCESS)) {
  610. zval_ptr_dtor_nogc(result);
  611. return FAILURE;
  612. }
  613. if (UNEXPECTED(zend_ast_add_unpacked_element(result, &op1) != SUCCESS)) {
  614. zval_ptr_dtor_nogc(&op1);
  615. zval_ptr_dtor_nogc(result);
  616. return FAILURE;
  617. }
  618. zval_ptr_dtor_nogc(&op1);
  619. continue;
  620. }
  621. if (elem->child[1]) {
  622. if (UNEXPECTED(zend_ast_evaluate(&op1, elem->child[1], scope) != SUCCESS)) {
  623. zval_ptr_dtor_nogc(result);
  624. return FAILURE;
  625. }
  626. } else {
  627. ZVAL_UNDEF(&op1);
  628. }
  629. if (UNEXPECTED(zend_ast_evaluate(&op2, elem->child[0], scope) != SUCCESS)) {
  630. zval_ptr_dtor_nogc(&op1);
  631. zval_ptr_dtor_nogc(result);
  632. return FAILURE;
  633. }
  634. if (UNEXPECTED(zend_ast_add_array_element(result, &op1, &op2) != SUCCESS)) {
  635. zval_ptr_dtor_nogc(&op1);
  636. zval_ptr_dtor_nogc(&op2);
  637. zval_ptr_dtor_nogc(result);
  638. return FAILURE;
  639. }
  640. }
  641. }
  642. break;
  643. case ZEND_AST_DIM:
  644. if (ast->child[1] == NULL) {
  645. zend_error_noreturn(E_COMPILE_ERROR, "Cannot use [] for reading");
  646. }
  647. if (UNEXPECTED(zend_ast_evaluate(&op1, ast->child[0], scope) != SUCCESS)) {
  648. ret = FAILURE;
  649. break;
  650. }
  651. // DIM on objects is disallowed because it allows executing arbitrary expressions
  652. if (Z_TYPE(op1) == IS_OBJECT) {
  653. zval_ptr_dtor_nogc(&op1);
  654. zend_throw_error(NULL, "Cannot use [] on objects in constant expression");
  655. ret = FAILURE;
  656. break;
  657. }
  658. if (UNEXPECTED(zend_ast_evaluate(&op2, ast->child[1], scope) != SUCCESS)) {
  659. zval_ptr_dtor_nogc(&op1);
  660. ret = FAILURE;
  661. break;
  662. }
  663. zend_fetch_dimension_const(result, &op1, &op2, (ast->attr & ZEND_DIM_IS) ? BP_VAR_IS : BP_VAR_R);
  664. zval_ptr_dtor_nogc(&op1);
  665. zval_ptr_dtor_nogc(&op2);
  666. if (UNEXPECTED(EG(exception))) {
  667. return FAILURE;
  668. }
  669. break;
  670. case ZEND_AST_CONST_ENUM_INIT:
  671. {
  672. // Preloading will attempt to resolve constants but objects can't be stored in shm
  673. // Aborting here to store the const AST instead
  674. if (CG(in_compilation)) {
  675. return FAILURE;
  676. }
  677. zend_ast *class_name_ast = ast->child[0];
  678. zend_string *class_name = zend_ast_get_str(class_name_ast);
  679. zend_ast *case_name_ast = ast->child[1];
  680. zend_string *case_name = zend_ast_get_str(case_name_ast);
  681. zend_ast *case_value_ast = ast->child[2];
  682. zval *case_value_zv = case_value_ast != NULL
  683. ? zend_ast_get_zval(case_value_ast)
  684. : NULL;
  685. zend_class_entry *ce = zend_lookup_class(class_name);
  686. zend_enum_new(result, ce, case_name, case_value_zv);
  687. break;
  688. }
  689. case ZEND_AST_CLASS_CONST:
  690. {
  691. zend_string *class_name = zend_ast_get_str(ast->child[0]);
  692. zend_string *const_name = zend_ast_get_str(ast->child[1]);
  693. zval *zv = zend_get_class_constant_ex(class_name, const_name, scope, ast->attr);
  694. if (UNEXPECTED(zv == NULL)) {
  695. ZVAL_UNDEF(result);
  696. return FAILURE;
  697. }
  698. ZVAL_COPY_OR_DUP(result, zv);
  699. break;
  700. }
  701. case ZEND_AST_NEW:
  702. {
  703. zend_class_entry *ce = zend_ast_fetch_class(ast->child[0], scope);
  704. if (!ce) {
  705. return FAILURE;
  706. }
  707. if (object_init_ex(result, ce) != SUCCESS) {
  708. return FAILURE;
  709. }
  710. zend_ast_list *args_ast = zend_ast_get_list(ast->child[1]);
  711. if (args_ast->attr) {
  712. /* Has named arguments. */
  713. HashTable *args = zend_new_array(args_ast->children);
  714. for (uint32_t i = 0; i < args_ast->children; i++) {
  715. zend_ast *arg_ast = args_ast->child[i];
  716. zend_string *name = NULL;
  717. zval arg;
  718. if (arg_ast->kind == ZEND_AST_NAMED_ARG) {
  719. name = zend_ast_get_str(arg_ast->child[0]);
  720. arg_ast = arg_ast->child[1];
  721. }
  722. if (zend_ast_evaluate(&arg, arg_ast, scope) == FAILURE) {
  723. zend_array_destroy(args);
  724. zval_ptr_dtor(result);
  725. return FAILURE;
  726. }
  727. if (name) {
  728. if (!zend_hash_add(args, name, &arg)) {
  729. zend_throw_error(NULL,
  730. "Named parameter $%s overwrites previous argument",
  731. ZSTR_VAL(name));
  732. zend_array_destroy(args);
  733. zval_ptr_dtor(result);
  734. return FAILURE;
  735. }
  736. } else {
  737. zend_hash_next_index_insert(args, &arg);
  738. }
  739. }
  740. zend_function *ctor = Z_OBJ_HT_P(result)->get_constructor(Z_OBJ_P(result));
  741. if (ctor) {
  742. zend_call_known_function(
  743. ctor, Z_OBJ_P(result), Z_OBJCE_P(result), NULL, 0, NULL, args);
  744. }
  745. zend_array_destroy(args);
  746. } else {
  747. ALLOCA_FLAG(use_heap)
  748. zval *args = do_alloca(sizeof(zval) * args_ast->children, use_heap);
  749. for (uint32_t i = 0; i < args_ast->children; i++) {
  750. if (zend_ast_evaluate(&args[i], args_ast->child[i], scope) == FAILURE) {
  751. for (uint32_t j = 0; j < i; j++) {
  752. zval_ptr_dtor(&args[j]);
  753. }
  754. free_alloca(args, use_heap);
  755. zval_ptr_dtor(result);
  756. return FAILURE;
  757. }
  758. }
  759. zend_function *ctor = Z_OBJ_HT_P(result)->get_constructor(Z_OBJ_P(result));
  760. if (ctor) {
  761. zend_call_known_instance_method(
  762. ctor, Z_OBJ_P(result), NULL, args_ast->children, args);
  763. }
  764. for (uint32_t i = 0; i < args_ast->children; i++) {
  765. zval_ptr_dtor(&args[i]);
  766. }
  767. free_alloca(args, use_heap);
  768. }
  769. if (EG(exception)) {
  770. zend_object_store_ctor_failed(Z_OBJ_P(result));
  771. zval_ptr_dtor(result);
  772. return FAILURE;
  773. }
  774. return SUCCESS;
  775. }
  776. default:
  777. zend_throw_error(NULL, "Unsupported constant expression");
  778. ret = FAILURE;
  779. }
  780. return ret;
  781. }
  782. static size_t ZEND_FASTCALL zend_ast_tree_size(zend_ast *ast)
  783. {
  784. size_t size;
  785. if (ast->kind == ZEND_AST_ZVAL || ast->kind == ZEND_AST_CONSTANT) {
  786. size = sizeof(zend_ast_zval);
  787. } else if (zend_ast_is_list(ast)) {
  788. uint32_t i;
  789. zend_ast_list *list = zend_ast_get_list(ast);
  790. size = zend_ast_list_size(list->children);
  791. for (i = 0; i < list->children; i++) {
  792. if (list->child[i]) {
  793. size += zend_ast_tree_size(list->child[i]);
  794. }
  795. }
  796. } else {
  797. uint32_t i, children = zend_ast_get_num_children(ast);
  798. size = zend_ast_size(children);
  799. for (i = 0; i < children; i++) {
  800. if (ast->child[i]) {
  801. size += zend_ast_tree_size(ast->child[i]);
  802. }
  803. }
  804. }
  805. return size;
  806. }
  807. static void* ZEND_FASTCALL zend_ast_tree_copy(zend_ast *ast, void *buf)
  808. {
  809. if (ast->kind == ZEND_AST_ZVAL) {
  810. zend_ast_zval *new = (zend_ast_zval*)buf;
  811. new->kind = ZEND_AST_ZVAL;
  812. new->attr = ast->attr;
  813. ZVAL_COPY(&new->val, zend_ast_get_zval(ast));
  814. buf = (void*)((char*)buf + sizeof(zend_ast_zval));
  815. } else if (ast->kind == ZEND_AST_CONSTANT) {
  816. zend_ast_zval *new = (zend_ast_zval*)buf;
  817. new->kind = ZEND_AST_CONSTANT;
  818. new->attr = ast->attr;
  819. ZVAL_STR_COPY(&new->val, zend_ast_get_constant_name(ast));
  820. buf = (void*)((char*)buf + sizeof(zend_ast_zval));
  821. } else if (zend_ast_is_list(ast)) {
  822. zend_ast_list *list = zend_ast_get_list(ast);
  823. zend_ast_list *new = (zend_ast_list*)buf;
  824. uint32_t i;
  825. new->kind = list->kind;
  826. new->attr = list->attr;
  827. new->children = list->children;
  828. buf = (void*)((char*)buf + zend_ast_list_size(list->children));
  829. for (i = 0; i < list->children; i++) {
  830. if (list->child[i]) {
  831. new->child[i] = (zend_ast*)buf;
  832. buf = zend_ast_tree_copy(list->child[i], buf);
  833. } else {
  834. new->child[i] = NULL;
  835. }
  836. }
  837. } else {
  838. uint32_t i, children = zend_ast_get_num_children(ast);
  839. zend_ast *new = (zend_ast*)buf;
  840. new->kind = ast->kind;
  841. new->attr = ast->attr;
  842. buf = (void*)((char*)buf + zend_ast_size(children));
  843. for (i = 0; i < children; i++) {
  844. if (ast->child[i]) {
  845. new->child[i] = (zend_ast*)buf;
  846. buf = zend_ast_tree_copy(ast->child[i], buf);
  847. } else {
  848. new->child[i] = NULL;
  849. }
  850. }
  851. }
  852. return buf;
  853. }
  854. ZEND_API zend_ast_ref * ZEND_FASTCALL zend_ast_copy(zend_ast *ast)
  855. {
  856. size_t tree_size;
  857. zend_ast_ref *ref;
  858. ZEND_ASSERT(ast != NULL);
  859. tree_size = zend_ast_tree_size(ast) + sizeof(zend_ast_ref);
  860. ref = emalloc(tree_size);
  861. zend_ast_tree_copy(ast, GC_AST(ref));
  862. GC_SET_REFCOUNT(ref, 1);
  863. GC_TYPE_INFO(ref) = GC_CONSTANT_AST;
  864. return ref;
  865. }
  866. ZEND_API void ZEND_FASTCALL zend_ast_destroy(zend_ast *ast)
  867. {
  868. tail_call:
  869. if (!ast) {
  870. return;
  871. }
  872. if (EXPECTED(ast->kind >= ZEND_AST_VAR)) {
  873. uint32_t i, children = zend_ast_get_num_children(ast);
  874. for (i = 1; i < children; i++) {
  875. zend_ast_destroy(ast->child[i]);
  876. }
  877. ast = ast->child[0];
  878. goto tail_call;
  879. } else if (EXPECTED(ast->kind == ZEND_AST_ZVAL)) {
  880. zval_ptr_dtor_nogc(zend_ast_get_zval(ast));
  881. } else if (EXPECTED(zend_ast_is_list(ast))) {
  882. zend_ast_list *list = zend_ast_get_list(ast);
  883. if (list->children) {
  884. uint32_t i;
  885. for (i = 1; i < list->children; i++) {
  886. zend_ast_destroy(list->child[i]);
  887. }
  888. ast = list->child[0];
  889. goto tail_call;
  890. }
  891. } else if (EXPECTED(ast->kind == ZEND_AST_CONSTANT)) {
  892. zend_string_release_ex(zend_ast_get_constant_name(ast), 0);
  893. } else if (EXPECTED(ast->kind >= ZEND_AST_FUNC_DECL)) {
  894. zend_ast_decl *decl = (zend_ast_decl *) ast;
  895. if (decl->name) {
  896. zend_string_release_ex(decl->name, 0);
  897. }
  898. if (decl->doc_comment) {
  899. zend_string_release_ex(decl->doc_comment, 0);
  900. }
  901. zend_ast_destroy(decl->child[0]);
  902. zend_ast_destroy(decl->child[1]);
  903. zend_ast_destroy(decl->child[2]);
  904. zend_ast_destroy(decl->child[3]);
  905. ast = decl->child[4];
  906. goto tail_call;
  907. }
  908. }
  909. ZEND_API void ZEND_FASTCALL zend_ast_ref_destroy(zend_ast_ref *ast)
  910. {
  911. zend_ast_destroy(GC_AST(ast));
  912. efree(ast);
  913. }
  914. ZEND_API void zend_ast_apply(zend_ast *ast, zend_ast_apply_func fn, void *context) {
  915. if (zend_ast_is_list(ast)) {
  916. zend_ast_list *list = zend_ast_get_list(ast);
  917. uint32_t i;
  918. for (i = 0; i < list->children; ++i) {
  919. fn(&list->child[i], context);
  920. }
  921. } else {
  922. uint32_t i, children = zend_ast_get_num_children(ast);
  923. for (i = 0; i < children; ++i) {
  924. fn(&ast->child[i], context);
  925. }
  926. }
  927. }
  928. /*
  929. * Operator Precedence
  930. * ====================
  931. * priority associativity operators
  932. * ----------------------------------
  933. * 10 left include, include_once, eval, require, require_once
  934. * 20 left ,
  935. * 30 left or
  936. * 40 left xor
  937. * 50 left and
  938. * 60 right print
  939. * 70 right yield
  940. * 80 right =>
  941. * 85 right yield from
  942. * 90 right = += -= *= /= .= %= &= |= ^= <<= >>= **=
  943. * 100 left ? :
  944. * 110 right ??
  945. * 120 left ||
  946. * 130 left &&
  947. * 140 left |
  948. * 150 left ^
  949. * 160 left &
  950. * 170 non-associative == != === !==
  951. * 180 non-associative < <= > >= <=>
  952. * 185 left .
  953. * 190 left << >>
  954. * 200 left + -
  955. * 210 left * / %
  956. * 220 right !
  957. * 230 non-associative instanceof
  958. * 240 right + - ++ -- ~ (type) @
  959. * 250 right **
  960. * 260 left [
  961. * 270 non-associative clone new
  962. */
  963. static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int priority, int indent);
  964. static ZEND_COLD void zend_ast_export_str(smart_str *str, zend_string *s)
  965. {
  966. size_t i;
  967. for (i = 0; i < ZSTR_LEN(s); i++) {
  968. unsigned char c = ZSTR_VAL(s)[i];
  969. if (c == '\'' || c == '\\') {
  970. smart_str_appendc(str, '\\');
  971. smart_str_appendc(str, c);
  972. } else {
  973. smart_str_appendc(str, c);
  974. }
  975. }
  976. }
  977. static ZEND_COLD void zend_ast_export_qstr(smart_str *str, char quote, zend_string *s)
  978. {
  979. size_t i;
  980. for (i = 0; i < ZSTR_LEN(s); i++) {
  981. unsigned char c = ZSTR_VAL(s)[i];
  982. if (c < ' ') {
  983. switch (c) {
  984. case '\n':
  985. smart_str_appends(str, "\\n");
  986. break;
  987. case '\r':
  988. smart_str_appends(str, "\\r");
  989. break;
  990. case '\t':
  991. smart_str_appends(str, "\\t");
  992. break;
  993. case '\f':
  994. smart_str_appends(str, "\\f");
  995. break;
  996. case '\v':
  997. smart_str_appends(str, "\\v");
  998. break;
  999. #ifdef ZEND_WIN32
  1000. case VK_ESCAPE:
  1001. #else
  1002. case '\e':
  1003. #endif
  1004. smart_str_appends(str, "\\e");
  1005. break;
  1006. default:
  1007. smart_str_appends(str, "\\0");
  1008. smart_str_appendc(str, '0' + (c / 8));
  1009. smart_str_appendc(str, '0' + (c % 8));
  1010. break;
  1011. }
  1012. } else {
  1013. if (c == quote || c == '$' || c == '\\') {
  1014. smart_str_appendc(str, '\\');
  1015. }
  1016. smart_str_appendc(str, c);
  1017. }
  1018. }
  1019. }
  1020. static ZEND_COLD void zend_ast_export_indent(smart_str *str, int indent)
  1021. {
  1022. while (indent > 0) {
  1023. smart_str_appends(str, " ");
  1024. indent--;
  1025. }
  1026. }
  1027. static ZEND_COLD void zend_ast_export_name(smart_str *str, zend_ast *ast, int priority, int indent)
  1028. {
  1029. if (ast->kind == ZEND_AST_ZVAL) {
  1030. zval *zv = zend_ast_get_zval(ast);
  1031. if (Z_TYPE_P(zv) == IS_STRING) {
  1032. smart_str_append(str, Z_STR_P(zv));
  1033. return;
  1034. }
  1035. }
  1036. zend_ast_export_ex(str, ast, priority, indent);
  1037. }
  1038. static ZEND_COLD void zend_ast_export_ns_name(smart_str *str, zend_ast *ast, int priority, int indent)
  1039. {
  1040. if (ast->kind == ZEND_AST_ZVAL) {
  1041. zval *zv = zend_ast_get_zval(ast);
  1042. if (Z_TYPE_P(zv) == IS_STRING) {
  1043. if (ast->attr == ZEND_NAME_FQ) {
  1044. smart_str_appendc(str, '\\');
  1045. } else if (ast->attr == ZEND_NAME_RELATIVE) {
  1046. smart_str_appends(str, "namespace\\");
  1047. }
  1048. smart_str_append(str, Z_STR_P(zv));
  1049. return;
  1050. }
  1051. }
  1052. zend_ast_export_ex(str, ast, priority, indent);
  1053. }
  1054. static ZEND_COLD bool zend_ast_valid_var_char(char ch)
  1055. {
  1056. unsigned char c = (unsigned char)ch;
  1057. if (c != '_' && c < 127 &&
  1058. (c < '0' || c > '9') &&
  1059. (c < 'A' || c > 'Z') &&
  1060. (c < 'a' || c > 'z')) {
  1061. return 0;
  1062. }
  1063. return 1;
  1064. }
  1065. static ZEND_COLD bool zend_ast_valid_var_name(const char *s, size_t len)
  1066. {
  1067. unsigned char c;
  1068. size_t i;
  1069. if (len == 0) {
  1070. return 0;
  1071. }
  1072. c = (unsigned char)s[0];
  1073. if (c != '_' && c < 127 &&
  1074. (c < 'A' || c > 'Z') &&
  1075. (c < 'a' || c > 'z')) {
  1076. return 0;
  1077. }
  1078. for (i = 1; i < len; i++) {
  1079. c = (unsigned char)s[i];
  1080. if (c != '_' && c < 127 &&
  1081. (c < '0' || c > '9') &&
  1082. (c < 'A' || c > 'Z') &&
  1083. (c < 'a' || c > 'z')) {
  1084. return 0;
  1085. }
  1086. }
  1087. return 1;
  1088. }
  1089. static ZEND_COLD bool zend_ast_var_needs_braces(char ch)
  1090. {
  1091. return ch == '[' || zend_ast_valid_var_char(ch);
  1092. }
  1093. static ZEND_COLD void zend_ast_export_var(smart_str *str, zend_ast *ast, int priority, int indent)
  1094. {
  1095. if (ast->kind == ZEND_AST_ZVAL) {
  1096. zval *zv = zend_ast_get_zval(ast);
  1097. if (Z_TYPE_P(zv) == IS_STRING &&
  1098. zend_ast_valid_var_name(Z_STRVAL_P(zv), Z_STRLEN_P(zv))) {
  1099. smart_str_append(str, Z_STR_P(zv));
  1100. return;
  1101. }
  1102. } else if (ast->kind == ZEND_AST_VAR) {
  1103. zend_ast_export_ex(str, ast, 0, indent);
  1104. return;
  1105. }
  1106. smart_str_appendc(str, '{');
  1107. zend_ast_export_name(str, ast, 0, indent);
  1108. smart_str_appendc(str, '}');
  1109. }
  1110. static ZEND_COLD void zend_ast_export_list(smart_str *str, zend_ast_list *list, bool separator, int priority, int indent)
  1111. {
  1112. uint32_t i = 0;
  1113. while (i < list->children) {
  1114. if (i != 0 && separator) {
  1115. smart_str_appends(str, ", ");
  1116. }
  1117. zend_ast_export_ex(str, list->child[i], priority, indent);
  1118. i++;
  1119. }
  1120. }
  1121. static ZEND_COLD void zend_ast_export_encaps_list(smart_str *str, char quote, zend_ast_list *list, int indent)
  1122. {
  1123. uint32_t i = 0;
  1124. zend_ast *ast;
  1125. while (i < list->children) {
  1126. ast = list->child[i];
  1127. if (ast->kind == ZEND_AST_ZVAL) {
  1128. zval *zv = zend_ast_get_zval(ast);
  1129. ZEND_ASSERT(Z_TYPE_P(zv) == IS_STRING);
  1130. zend_ast_export_qstr(str, quote, Z_STR_P(zv));
  1131. } else if (ast->kind == ZEND_AST_VAR &&
  1132. ast->child[0]->kind == ZEND_AST_ZVAL &&
  1133. (i + 1 == list->children ||
  1134. list->child[i + 1]->kind != ZEND_AST_ZVAL ||
  1135. !zend_ast_var_needs_braces(
  1136. *Z_STRVAL_P(
  1137. zend_ast_get_zval(list->child[i + 1]))))) {
  1138. zend_ast_export_ex(str, ast, 0, indent);
  1139. } else {
  1140. smart_str_appendc(str, '{');
  1141. zend_ast_export_ex(str, ast, 0, indent);
  1142. smart_str_appendc(str, '}');
  1143. }
  1144. i++;
  1145. }
  1146. }
  1147. static ZEND_COLD void zend_ast_export_name_list_ex(smart_str *str, zend_ast_list *list, int indent, const char *separator)
  1148. {
  1149. uint32_t i = 0;
  1150. while (i < list->children) {
  1151. if (i != 0) {
  1152. smart_str_appends(str, separator);
  1153. }
  1154. zend_ast_export_name(str, list->child[i], 0, indent);
  1155. i++;
  1156. }
  1157. }
  1158. #define zend_ast_export_name_list(s, l, i) zend_ast_export_name_list_ex(s, l, i, ", ")
  1159. #define zend_ast_export_catch_name_list(s, l, i) zend_ast_export_name_list_ex(s, l, i, "|")
  1160. static ZEND_COLD void zend_ast_export_var_list(smart_str *str, zend_ast_list *list, int indent)
  1161. {
  1162. uint32_t i = 0;
  1163. while (i < list->children) {
  1164. if (i != 0) {
  1165. smart_str_appends(str, ", ");
  1166. }
  1167. if (list->child[i]->attr & ZEND_BIND_REF) {
  1168. smart_str_appendc(str, '&');
  1169. }
  1170. smart_str_appendc(str, '$');
  1171. zend_ast_export_name(str, list->child[i], 20, indent);
  1172. i++;
  1173. }
  1174. }
  1175. static ZEND_COLD void zend_ast_export_stmt(smart_str *str, zend_ast *ast, int indent)
  1176. {
  1177. if (!ast) {
  1178. return;
  1179. }
  1180. if (ast->kind == ZEND_AST_STMT_LIST ||
  1181. ast->kind == ZEND_AST_TRAIT_ADAPTATIONS) {
  1182. zend_ast_list *list = (zend_ast_list*)ast;
  1183. uint32_t i = 0;
  1184. while (i < list->children) {
  1185. ast = list->child[i];
  1186. zend_ast_export_stmt(str, ast, indent);
  1187. i++;
  1188. }
  1189. } else {
  1190. zend_ast_export_indent(str, indent);
  1191. zend_ast_export_ex(str, ast, 0, indent);
  1192. switch (ast->kind) {
  1193. case ZEND_AST_LABEL:
  1194. case ZEND_AST_IF:
  1195. case ZEND_AST_SWITCH:
  1196. case ZEND_AST_WHILE:
  1197. case ZEND_AST_TRY:
  1198. case ZEND_AST_FOR:
  1199. case ZEND_AST_FOREACH:
  1200. case ZEND_AST_FUNC_DECL:
  1201. case ZEND_AST_METHOD:
  1202. case ZEND_AST_CLASS:
  1203. case ZEND_AST_USE_TRAIT:
  1204. case ZEND_AST_NAMESPACE:
  1205. case ZEND_AST_DECLARE:
  1206. break;
  1207. default:
  1208. smart_str_appendc(str, ';');
  1209. break;
  1210. }
  1211. smart_str_appendc(str, '\n');
  1212. }
  1213. }
  1214. static ZEND_COLD void zend_ast_export_if_stmt(smart_str *str, zend_ast_list *list, int indent)
  1215. {
  1216. uint32_t i;
  1217. zend_ast *ast;
  1218. tail_call:
  1219. i = 0;
  1220. while (i < list->children) {
  1221. ast = list->child[i];
  1222. ZEND_ASSERT(ast->kind == ZEND_AST_IF_ELEM);
  1223. if (ast->child[0]) {
  1224. if (i == 0) {
  1225. smart_str_appends(str, "if (");
  1226. } else {
  1227. zend_ast_export_indent(str, indent);
  1228. smart_str_appends(str, "} elseif (");
  1229. }
  1230. zend_ast_export_ex(str, ast->child[0], 0, indent);
  1231. smart_str_appends(str, ") {\n");
  1232. zend_ast_export_stmt(str, ast->child[1], indent + 1);
  1233. } else {
  1234. zend_ast_export_indent(str, indent);
  1235. smart_str_appends(str, "} else ");
  1236. if (ast->child[1] && ast->child[1]->kind == ZEND_AST_IF) {
  1237. list = (zend_ast_list*)ast->child[1];
  1238. goto tail_call;
  1239. } else {
  1240. smart_str_appends(str, "{\n");
  1241. zend_ast_export_stmt(str, ast->child[1], indent + 1);
  1242. }
  1243. }
  1244. i++;
  1245. }
  1246. zend_ast_export_indent(str, indent);
  1247. smart_str_appendc(str, '}');
  1248. }
  1249. static ZEND_COLD void zend_ast_export_zval(smart_str *str, zval *zv, int priority, int indent)
  1250. {
  1251. ZVAL_DEREF(zv);
  1252. switch (Z_TYPE_P(zv)) {
  1253. case IS_NULL:
  1254. smart_str_appends(str, "null");
  1255. break;
  1256. case IS_FALSE:
  1257. smart_str_appends(str, "false");
  1258. break;
  1259. case IS_TRUE:
  1260. smart_str_appends(str, "true");
  1261. break;
  1262. case IS_LONG:
  1263. smart_str_append_long(str, Z_LVAL_P(zv));
  1264. break;
  1265. case IS_DOUBLE:
  1266. smart_str_append_double(
  1267. str, Z_DVAL_P(zv), (int) EG(precision), /* zero_fraction */ false);
  1268. break;
  1269. case IS_STRING:
  1270. smart_str_appendc(str, '\'');
  1271. zend_ast_export_str(str, Z_STR_P(zv));
  1272. smart_str_appendc(str, '\'');
  1273. break;
  1274. case IS_ARRAY: {
  1275. zend_long idx;
  1276. zend_string *key;
  1277. zval *val;
  1278. bool first = true;
  1279. smart_str_appendc(str, '[');
  1280. ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(zv), idx, key, val) {
  1281. if (first) {
  1282. first = false;
  1283. } else {
  1284. smart_str_appends(str, ", ");
  1285. }
  1286. if (key) {
  1287. smart_str_appendc(str, '\'');
  1288. zend_ast_export_str(str, key);
  1289. smart_str_appends(str, "' => ");
  1290. } else {
  1291. smart_str_append_long(str, idx);
  1292. smart_str_appends(str, " => ");
  1293. }
  1294. zend_ast_export_zval(str, val, 0, indent);
  1295. } ZEND_HASH_FOREACH_END();
  1296. smart_str_appendc(str, ']');
  1297. break;
  1298. }
  1299. case IS_CONSTANT_AST:
  1300. zend_ast_export_ex(str, Z_ASTVAL_P(zv), priority, indent);
  1301. break;
  1302. EMPTY_SWITCH_DEFAULT_CASE();
  1303. }
  1304. }
  1305. static ZEND_COLD void zend_ast_export_class_no_header(smart_str *str, zend_ast_decl *decl, int indent) {
  1306. if (decl->child[0]) {
  1307. smart_str_appends(str, " extends ");
  1308. zend_ast_export_ns_name(str, decl->child[0], 0, indent);
  1309. }
  1310. if (decl->child[1]) {
  1311. smart_str_appends(str, " implements ");
  1312. zend_ast_export_ex(str, decl->child[1], 0, indent);
  1313. }
  1314. smart_str_appends(str, " {\n");
  1315. zend_ast_export_stmt(str, decl->child[2], indent + 1);
  1316. zend_ast_export_indent(str, indent);
  1317. smart_str_appends(str, "}");
  1318. }
  1319. static ZEND_COLD void zend_ast_export_attribute_group(smart_str *str, zend_ast *ast, int indent) {
  1320. zend_ast_list *list = zend_ast_get_list(ast);
  1321. for (uint32_t i = 0; i < list->children; i++) {
  1322. zend_ast *attr = list->child[i];
  1323. if (i) {
  1324. smart_str_appends(str, ", ");
  1325. }
  1326. zend_ast_export_ns_name(str, attr->child[0], 0, indent);
  1327. if (attr->child[1]) {
  1328. smart_str_appendc(str, '(');
  1329. zend_ast_export_ex(str, attr->child[1], 0, indent);
  1330. smart_str_appendc(str, ')');
  1331. }
  1332. }
  1333. }
  1334. static ZEND_COLD void zend_ast_export_attributes(smart_str *str, zend_ast *ast, int indent, bool newlines) {
  1335. zend_ast_list *list = zend_ast_get_list(ast);
  1336. uint32_t i;
  1337. for (i = 0; i < list->children; i++) {
  1338. smart_str_appends(str, "#[");
  1339. zend_ast_export_attribute_group(str, list->child[i], indent);
  1340. smart_str_appends(str, "]");
  1341. if (newlines) {
  1342. smart_str_appendc(str, '\n');
  1343. zend_ast_export_indent(str, indent);
  1344. } else {
  1345. smart_str_appendc(str, ' ');
  1346. }
  1347. }
  1348. }
  1349. static ZEND_COLD void zend_ast_export_visibility(smart_str *str, uint32_t flags) {
  1350. if (flags & ZEND_ACC_PUBLIC) {
  1351. smart_str_appends(str, "public ");
  1352. } else if (flags & ZEND_ACC_PROTECTED) {
  1353. smart_str_appends(str, "protected ");
  1354. } else if (flags & ZEND_ACC_PRIVATE) {
  1355. smart_str_appends(str, "private ");
  1356. }
  1357. }
  1358. static ZEND_COLD void zend_ast_export_type(smart_str *str, zend_ast *ast, int indent) {
  1359. if (ast->kind == ZEND_AST_TYPE_UNION) {
  1360. zend_ast_list *list = zend_ast_get_list(ast);
  1361. for (uint32_t i = 0; i < list->children; i++) {
  1362. if (i != 0) {
  1363. smart_str_appendc(str, '|');
  1364. }
  1365. zend_ast_export_type(str, list->child[i], indent);
  1366. }
  1367. return;
  1368. }
  1369. if (ast->kind == ZEND_AST_TYPE_INTERSECTION) {
  1370. zend_ast_list *list = zend_ast_get_list(ast);
  1371. for (uint32_t i = 0; i < list->children; i++) {
  1372. if (i != 0) {
  1373. smart_str_appendc(str, '&');
  1374. }
  1375. zend_ast_export_type(str, list->child[i], indent);
  1376. }
  1377. return;
  1378. }
  1379. if (ast->attr & ZEND_TYPE_NULLABLE) {
  1380. smart_str_appendc(str, '?');
  1381. }
  1382. zend_ast_export_ns_name(str, ast, 0, indent);
  1383. }
  1384. #define BINARY_OP(_op, _p, _pl, _pr) do { \
  1385. op = _op; \
  1386. p = _p; \
  1387. pl = _pl; \
  1388. pr = _pr; \
  1389. goto binary_op; \
  1390. } while (0)
  1391. #define PREFIX_OP(_op, _p, _pl) do { \
  1392. op = _op; \
  1393. p = _p; \
  1394. pl = _pl; \
  1395. goto prefix_op; \
  1396. } while (0)
  1397. #define FUNC_OP(_op) do { \
  1398. op = _op; \
  1399. goto func_op; \
  1400. } while (0)
  1401. #define POSTFIX_OP(_op, _p, _pl) do { \
  1402. op = _op; \
  1403. p = _p; \
  1404. pl = _pl; \
  1405. goto postfix_op; \
  1406. } while (0)
  1407. #define APPEND_NODE_1(_op) do { \
  1408. op = _op; \
  1409. goto append_node_1; \
  1410. } while (0)
  1411. #define APPEND_STR(_op) do { \
  1412. op = _op; \
  1413. goto append_str; \
  1414. } while (0)
  1415. #define APPEND_DEFAULT_VALUE(n) do { \
  1416. p = n; \
  1417. goto append_default_value; \
  1418. } while (0)
  1419. static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int priority, int indent)
  1420. {
  1421. zend_ast_decl *decl;
  1422. int p, pl, pr;
  1423. const char *op;
  1424. tail_call:
  1425. if (!ast) {
  1426. return;
  1427. }
  1428. switch (ast->kind) {
  1429. /* special nodes */
  1430. case ZEND_AST_ZVAL:
  1431. zend_ast_export_zval(str, zend_ast_get_zval(ast), priority, indent);
  1432. break;
  1433. case ZEND_AST_CONSTANT: {
  1434. zend_string *name = zend_ast_get_constant_name(ast);
  1435. smart_str_appendl(str, ZSTR_VAL(name), ZSTR_LEN(name));
  1436. break;
  1437. }
  1438. case ZEND_AST_CONSTANT_CLASS:
  1439. smart_str_appendl(str, "__CLASS__", sizeof("__CLASS__")-1);
  1440. break;
  1441. case ZEND_AST_ZNODE:
  1442. /* This AST kind is only used for temporary nodes during compilation */
  1443. ZEND_UNREACHABLE();
  1444. break;
  1445. /* declaration nodes */
  1446. case ZEND_AST_FUNC_DECL:
  1447. case ZEND_AST_CLOSURE:
  1448. case ZEND_AST_ARROW_FUNC:
  1449. case ZEND_AST_METHOD:
  1450. decl = (zend_ast_decl *) ast;
  1451. if (decl->child[4]) {
  1452. bool newlines = !(ast->kind == ZEND_AST_CLOSURE || ast->kind == ZEND_AST_ARROW_FUNC);
  1453. zend_ast_export_attributes(str, decl->child[4], indent, newlines);
  1454. }
  1455. zend_ast_export_visibility(str, decl->flags);
  1456. if (decl->flags & ZEND_ACC_STATIC) {
  1457. smart_str_appends(str, "static ");
  1458. }
  1459. if (decl->flags & ZEND_ACC_ABSTRACT) {
  1460. smart_str_appends(str, "abstract ");
  1461. }
  1462. if (decl->flags & ZEND_ACC_FINAL) {
  1463. smart_str_appends(str, "final ");
  1464. }
  1465. if (decl->kind == ZEND_AST_ARROW_FUNC) {
  1466. smart_str_appends(str, "fn");
  1467. } else {
  1468. smart_str_appends(str, "function ");
  1469. }
  1470. if (decl->flags & ZEND_ACC_RETURN_REFERENCE) {
  1471. smart_str_appendc(str, '&');
  1472. }
  1473. if (ast->kind != ZEND_AST_CLOSURE && ast->kind != ZEND_AST_ARROW_FUNC) {
  1474. smart_str_appendl(str, ZSTR_VAL(decl->name), ZSTR_LEN(decl->name));
  1475. }
  1476. smart_str_appendc(str, '(');
  1477. zend_ast_export_ex(str, decl->child[0], 0, indent);
  1478. smart_str_appendc(str, ')');
  1479. zend_ast_export_ex(str, decl->child[1], 0, indent);
  1480. if (decl->child[3]) {
  1481. smart_str_appends(str, ": ");
  1482. zend_ast_export_type(str, decl->child[3], indent);
  1483. }
  1484. if (decl->child[2]) {
  1485. if (decl->kind == ZEND_AST_ARROW_FUNC) {
  1486. ZEND_ASSERT(decl->child[2]->kind == ZEND_AST_RETURN);
  1487. smart_str_appends(str, " => ");
  1488. zend_ast_export_ex(str, decl->child[2]->child[0], 0, indent);
  1489. break;
  1490. }
  1491. smart_str_appends(str, " {\n");
  1492. zend_ast_export_stmt(str, decl->child[2], indent + 1);
  1493. zend_ast_export_indent(str, indent);
  1494. smart_str_appendc(str, '}');
  1495. if (ast->kind != ZEND_AST_CLOSURE) {
  1496. smart_str_appendc(str, '\n');
  1497. }
  1498. } else {
  1499. smart_str_appends(str, ";\n");
  1500. }
  1501. break;
  1502. case ZEND_AST_CLASS:
  1503. decl = (zend_ast_decl *) ast;
  1504. if (decl->child[3]) {
  1505. zend_ast_export_attributes(str, decl->child[3], indent, 1);
  1506. }
  1507. if (decl->flags & ZEND_ACC_INTERFACE) {
  1508. smart_str_appends(str, "interface ");
  1509. } else if (decl->flags & ZEND_ACC_TRAIT) {
  1510. smart_str_appends(str, "trait ");
  1511. } else if (decl->flags & ZEND_ACC_ENUM) {
  1512. smart_str_appends(str, "enum ");
  1513. } else {
  1514. if (decl->flags & ZEND_ACC_EXPLICIT_ABSTRACT_CLASS) {
  1515. smart_str_appends(str, "abstract ");
  1516. }
  1517. if (decl->flags & ZEND_ACC_FINAL) {
  1518. smart_str_appends(str, "final ");
  1519. }
  1520. smart_str_appends(str, "class ");
  1521. }
  1522. smart_str_appendl(str, ZSTR_VAL(decl->name), ZSTR_LEN(decl->name));
  1523. if (decl->flags & ZEND_ACC_ENUM && decl->child[4]) {
  1524. smart_str_appends(str, ": ");
  1525. zend_ast_export_type(str, decl->child[4], indent);
  1526. }
  1527. zend_ast_export_class_no_header(str, decl, indent);
  1528. smart_str_appendc(str, '\n');
  1529. break;
  1530. /* list nodes */
  1531. case ZEND_AST_ARG_LIST:
  1532. case ZEND_AST_EXPR_LIST:
  1533. case ZEND_AST_PARAM_LIST:
  1534. simple_list:
  1535. zend_ast_export_list(str, (zend_ast_list*)ast, 1, 20, indent);
  1536. break;
  1537. case ZEND_AST_ARRAY:
  1538. smart_str_appendc(str, '[');
  1539. zend_ast_export_list(str, (zend_ast_list*)ast, 1, 20, indent);
  1540. smart_str_appendc(str, ']');
  1541. break;
  1542. case ZEND_AST_ENCAPS_LIST:
  1543. smart_str_appendc(str, '"');
  1544. zend_ast_export_encaps_list(str, '"', (zend_ast_list*)ast, indent);
  1545. smart_str_appendc(str, '"');
  1546. break;
  1547. case ZEND_AST_STMT_LIST:
  1548. case ZEND_AST_TRAIT_ADAPTATIONS:
  1549. zend_ast_export_stmt(str, ast, indent);
  1550. break;
  1551. case ZEND_AST_IF:
  1552. zend_ast_export_if_stmt(str, (zend_ast_list*)ast, indent);
  1553. break;
  1554. case ZEND_AST_SWITCH_LIST:
  1555. case ZEND_AST_CATCH_LIST:
  1556. case ZEND_AST_MATCH_ARM_LIST:
  1557. zend_ast_export_list(str, (zend_ast_list*)ast, 0, 0, indent);
  1558. break;
  1559. case ZEND_AST_CLOSURE_USES:
  1560. smart_str_appends(str, " use(");
  1561. zend_ast_export_var_list(str, (zend_ast_list*)ast, indent);
  1562. smart_str_appendc(str, ')');
  1563. break;
  1564. case ZEND_AST_PROP_GROUP: {
  1565. zend_ast *type_ast = ast->child[0];
  1566. zend_ast *prop_ast = ast->child[1];
  1567. if (ast->child[2]) {
  1568. zend_ast_export_attributes(str, ast->child[2], indent, 1);
  1569. }
  1570. zend_ast_export_visibility(str, ast->attr);
  1571. if (ast->attr & ZEND_ACC_STATIC) {
  1572. smart_str_appends(str, "static ");
  1573. }
  1574. if (ast->attr & ZEND_ACC_READONLY) {
  1575. smart_str_appends(str, "readonly ");
  1576. }
  1577. if (type_ast) {
  1578. zend_ast_export_type(str, type_ast, indent);
  1579. smart_str_appendc(str, ' ');
  1580. }
  1581. ast = prop_ast;
  1582. goto simple_list;
  1583. }
  1584. case ZEND_AST_CONST_DECL:
  1585. smart_str_appends(str, "const ");
  1586. goto simple_list;
  1587. case ZEND_AST_CLASS_CONST_GROUP:
  1588. if (ast->child[1]) {
  1589. zend_ast_export_attributes(str, ast->child[1], indent, 1);
  1590. }
  1591. zend_ast_export_visibility(str, ast->attr);
  1592. smart_str_appends(str, "const ");
  1593. ast = ast->child[0];
  1594. goto simple_list;
  1595. case ZEND_AST_NAME_LIST:
  1596. zend_ast_export_name_list(str, (zend_ast_list*)ast, indent);
  1597. break;
  1598. case ZEND_AST_USE:
  1599. smart_str_appends(str, "use ");
  1600. if (ast->attr == T_FUNCTION) {
  1601. smart_str_appends(str, "function ");
  1602. } else if (ast->attr == T_CONST) {
  1603. smart_str_appends(str, "const ");
  1604. }
  1605. goto simple_list;
  1606. /* 0 child nodes */
  1607. case ZEND_AST_MAGIC_CONST:
  1608. switch (ast->attr) {
  1609. case T_LINE: APPEND_STR("__LINE__");
  1610. case T_FILE: APPEND_STR("__FILE__");
  1611. case T_DIR: APPEND_STR("__DIR__");
  1612. case T_TRAIT_C: APPEND_STR("__TRAIT__");
  1613. case T_METHOD_C: APPEND_STR("__METHOD__");
  1614. case T_FUNC_C: APPEND_STR("__FUNCTION__");
  1615. case T_NS_C: APPEND_STR("__NAMESPACE__");
  1616. case T_CLASS_C: APPEND_STR("__CLASS__");
  1617. EMPTY_SWITCH_DEFAULT_CASE();
  1618. }
  1619. break;
  1620. case ZEND_AST_TYPE:
  1621. switch (ast->attr & ~ZEND_TYPE_NULLABLE) {
  1622. case IS_ARRAY: APPEND_STR("array");
  1623. case IS_CALLABLE: APPEND_STR("callable");
  1624. case IS_STATIC: APPEND_STR("static");
  1625. case IS_MIXED: APPEND_STR("mixed");
  1626. EMPTY_SWITCH_DEFAULT_CASE();
  1627. }
  1628. break;
  1629. /* 1 child node */
  1630. case ZEND_AST_VAR:
  1631. smart_str_appendc(str, '$');
  1632. zend_ast_export_var(str, ast->child[0], 0, indent);
  1633. break;
  1634. case ZEND_AST_CONST:
  1635. zend_ast_export_ns_name(str, ast->child[0], 0, indent);
  1636. break;
  1637. case ZEND_AST_UNPACK:
  1638. smart_str_appends(str, "...");
  1639. ast = ast->child[0];
  1640. goto tail_call;
  1641. case ZEND_AST_UNARY_PLUS: PREFIX_OP("+", 240, 241);
  1642. case ZEND_AST_UNARY_MINUS: PREFIX_OP("-", 240, 241);
  1643. case ZEND_AST_CAST:
  1644. switch (ast->attr) {
  1645. case IS_NULL: PREFIX_OP("(unset)", 240, 241);
  1646. case _IS_BOOL: PREFIX_OP("(bool)", 240, 241);
  1647. case IS_LONG: PREFIX_OP("(int)", 240, 241);
  1648. case IS_DOUBLE: PREFIX_OP("(double)", 240, 241);
  1649. case IS_STRING: PREFIX_OP("(string)", 240, 241);
  1650. case IS_ARRAY: PREFIX_OP("(array)", 240, 241);
  1651. case IS_OBJECT: PREFIX_OP("(object)", 240, 241);
  1652. EMPTY_SWITCH_DEFAULT_CASE();
  1653. }
  1654. break;
  1655. case ZEND_AST_EMPTY:
  1656. FUNC_OP("empty");
  1657. case ZEND_AST_ISSET:
  1658. FUNC_OP("isset");
  1659. case ZEND_AST_SILENCE:
  1660. PREFIX_OP("@", 240, 241);
  1661. case ZEND_AST_SHELL_EXEC:
  1662. smart_str_appendc(str, '`');
  1663. if (ast->child[0]->kind == ZEND_AST_ENCAPS_LIST) {
  1664. zend_ast_export_encaps_list(str, '`', (zend_ast_list*)ast->child[0], indent);
  1665. } else {
  1666. zval *zv;
  1667. ZEND_ASSERT(ast->child[0]->kind == ZEND_AST_ZVAL);
  1668. zv = zend_ast_get_zval(ast->child[0]);
  1669. ZEND_ASSERT(Z_TYPE_P(zv) == IS_STRING);
  1670. zend_ast_export_qstr(str, '`', Z_STR_P(zv));
  1671. }
  1672. smart_str_appendc(str, '`');
  1673. break;
  1674. case ZEND_AST_CLONE:
  1675. PREFIX_OP("clone ", 270, 271);
  1676. case ZEND_AST_EXIT:
  1677. if (ast->child[0]) {
  1678. FUNC_OP("exit");
  1679. } else {
  1680. APPEND_STR("exit");
  1681. }
  1682. break;
  1683. case ZEND_AST_PRINT:
  1684. PREFIX_OP("print ", 60, 61);
  1685. case ZEND_AST_INCLUDE_OR_EVAL:
  1686. switch (ast->attr) {
  1687. case ZEND_INCLUDE_ONCE: FUNC_OP("include_once");
  1688. case ZEND_INCLUDE: FUNC_OP("include");
  1689. case ZEND_REQUIRE_ONCE: FUNC_OP("require_once");
  1690. case ZEND_REQUIRE: FUNC_OP("require");
  1691. case ZEND_EVAL: FUNC_OP("eval");
  1692. EMPTY_SWITCH_DEFAULT_CASE();
  1693. }
  1694. break;
  1695. case ZEND_AST_UNARY_OP:
  1696. switch (ast->attr) {
  1697. case ZEND_BW_NOT: PREFIX_OP("~", 240, 241);
  1698. case ZEND_BOOL_NOT: PREFIX_OP("!", 240, 241);
  1699. EMPTY_SWITCH_DEFAULT_CASE();
  1700. }
  1701. break;
  1702. case ZEND_AST_PRE_INC:
  1703. PREFIX_OP("++", 240, 241);
  1704. case ZEND_AST_PRE_DEC:
  1705. PREFIX_OP("--", 240, 241);
  1706. case ZEND_AST_POST_INC:
  1707. POSTFIX_OP("++", 240, 241);
  1708. case ZEND_AST_POST_DEC:
  1709. POSTFIX_OP("--", 240, 241);
  1710. case ZEND_AST_GLOBAL:
  1711. APPEND_NODE_1("global");
  1712. case ZEND_AST_UNSET:
  1713. FUNC_OP("unset");
  1714. case ZEND_AST_RETURN:
  1715. APPEND_NODE_1("return");
  1716. case ZEND_AST_LABEL:
  1717. zend_ast_export_name(str, ast->child[0], 0, indent);
  1718. smart_str_appendc(str, ':');
  1719. break;
  1720. case ZEND_AST_REF:
  1721. smart_str_appendc(str, '&');
  1722. ast = ast->child[0];
  1723. goto tail_call;
  1724. case ZEND_AST_HALT_COMPILER:
  1725. APPEND_STR("__HALT_COMPILER()");
  1726. case ZEND_AST_ECHO:
  1727. APPEND_NODE_1("echo");
  1728. case ZEND_AST_THROW:
  1729. APPEND_NODE_1("throw");
  1730. case ZEND_AST_GOTO:
  1731. smart_str_appends(str, "goto ");
  1732. zend_ast_export_name(str, ast->child[0], 0, indent);
  1733. break;
  1734. case ZEND_AST_BREAK:
  1735. APPEND_NODE_1("break");
  1736. case ZEND_AST_CONTINUE:
  1737. APPEND_NODE_1("continue");
  1738. /* 2 child nodes */
  1739. case ZEND_AST_DIM:
  1740. zend_ast_export_ex(str, ast->child[0], 260, indent);
  1741. smart_str_appendc(str, '[');
  1742. if (ast->child[1]) {
  1743. zend_ast_export_ex(str, ast->child[1], 0, indent);
  1744. }
  1745. smart_str_appendc(str, ']');
  1746. break;
  1747. case ZEND_AST_PROP:
  1748. case ZEND_AST_NULLSAFE_PROP:
  1749. zend_ast_export_ex(str, ast->child[0], 0, indent);
  1750. smart_str_appends(str, ast->kind == ZEND_AST_NULLSAFE_PROP ? "?->" : "->");
  1751. zend_ast_export_var(str, ast->child[1], 0, indent);
  1752. break;
  1753. case ZEND_AST_STATIC_PROP:
  1754. zend_ast_export_ns_name(str, ast->child[0], 0, indent);
  1755. smart_str_appends(str, "::$");
  1756. zend_ast_export_var(str, ast->child[1], 0, indent);
  1757. break;
  1758. case ZEND_AST_CALL:
  1759. zend_ast_export_ns_name(str, ast->child[0], 0, indent);
  1760. smart_str_appendc(str, '(');
  1761. zend_ast_export_ex(str, ast->child[1], 0, indent);
  1762. smart_str_appendc(str, ')');
  1763. break;
  1764. case ZEND_AST_CALLABLE_CONVERT:
  1765. smart_str_appends(str, "...");
  1766. break;
  1767. case ZEND_AST_CLASS_CONST:
  1768. zend_ast_export_ns_name(str, ast->child[0], 0, indent);
  1769. smart_str_appends(str, "::");
  1770. zend_ast_export_name(str, ast->child[1], 0, indent);
  1771. break;
  1772. case ZEND_AST_CLASS_NAME:
  1773. if (ast->child[0] == NULL) {
  1774. /* The const expr representation stores the fetch type instead. */
  1775. switch (ast->attr) {
  1776. case ZEND_FETCH_CLASS_SELF:
  1777. smart_str_appends(str, "self");
  1778. break;
  1779. case ZEND_FETCH_CLASS_PARENT:
  1780. smart_str_appends(str, "parent");
  1781. break;
  1782. EMPTY_SWITCH_DEFAULT_CASE()
  1783. }
  1784. } else {
  1785. zend_ast_export_ns_name(str, ast->child[0], 0, indent);
  1786. }
  1787. smart_str_appends(str, "::class");
  1788. break;
  1789. case ZEND_AST_ASSIGN: BINARY_OP(" = ", 90, 91, 90);
  1790. case ZEND_AST_ASSIGN_REF: BINARY_OP(" =& ", 90, 91, 90);
  1791. case ZEND_AST_ASSIGN_OP:
  1792. switch (ast->attr) {
  1793. case ZEND_ADD: BINARY_OP(" += ", 90, 91, 90);
  1794. case ZEND_SUB: BINARY_OP(" -= ", 90, 91, 90);
  1795. case ZEND_MUL: BINARY_OP(" *= ", 90, 91, 90);
  1796. case ZEND_DIV: BINARY_OP(" /= ", 90, 91, 90);
  1797. case ZEND_MOD: BINARY_OP(" %= ", 90, 91, 90);
  1798. case ZEND_SL: BINARY_OP(" <<= ", 90, 91, 90);
  1799. case ZEND_SR: BINARY_OP(" >>= ", 90, 91, 90);
  1800. case ZEND_CONCAT: BINARY_OP(" .= ", 90, 91, 90);
  1801. case ZEND_BW_OR: BINARY_OP(" |= ", 90, 91, 90);
  1802. case ZEND_BW_AND: BINARY_OP(" &= ", 90, 91, 90);
  1803. case ZEND_BW_XOR: BINARY_OP(" ^= ", 90, 91, 90);
  1804. case ZEND_POW: BINARY_OP(" **= ", 90, 91, 90);
  1805. EMPTY_SWITCH_DEFAULT_CASE();
  1806. }
  1807. break;
  1808. case ZEND_AST_ASSIGN_COALESCE: BINARY_OP(" \?\?= ", 90, 91, 90);
  1809. case ZEND_AST_BINARY_OP:
  1810. switch (ast->attr) {
  1811. case ZEND_ADD: BINARY_OP(" + ", 200, 200, 201);
  1812. case ZEND_SUB: BINARY_OP(" - ", 200, 200, 201);
  1813. case ZEND_MUL: BINARY_OP(" * ", 210, 210, 211);
  1814. case ZEND_DIV: BINARY_OP(" / ", 210, 210, 211);
  1815. case ZEND_MOD: BINARY_OP(" % ", 210, 210, 211);
  1816. case ZEND_SL: BINARY_OP(" << ", 190, 190, 191);
  1817. case ZEND_SR: BINARY_OP(" >> ", 190, 190, 191);
  1818. case ZEND_CONCAT: BINARY_OP(" . ", 185, 185, 186);
  1819. case ZEND_BW_OR: BINARY_OP(" | ", 140, 140, 141);
  1820. case ZEND_BW_AND: BINARY_OP(" & ", 160, 160, 161);
  1821. case ZEND_BW_XOR: BINARY_OP(" ^ ", 150, 150, 151);
  1822. case ZEND_IS_IDENTICAL: BINARY_OP(" === ", 170, 171, 171);
  1823. case ZEND_IS_NOT_IDENTICAL: BINARY_OP(" !== ", 170, 171, 171);
  1824. case ZEND_IS_EQUAL: BINARY_OP(" == ", 170, 171, 171);
  1825. case ZEND_IS_NOT_EQUAL: BINARY_OP(" != ", 170, 171, 171);
  1826. case ZEND_IS_SMALLER: BINARY_OP(" < ", 180, 181, 181);
  1827. case ZEND_IS_SMALLER_OR_EQUAL: BINARY_OP(" <= ", 180, 181, 181);
  1828. case ZEND_POW: BINARY_OP(" ** ", 250, 251, 250);
  1829. case ZEND_BOOL_XOR: BINARY_OP(" xor ", 40, 40, 41);
  1830. case ZEND_SPACESHIP: BINARY_OP(" <=> ", 180, 181, 181);
  1831. EMPTY_SWITCH_DEFAULT_CASE();
  1832. }
  1833. break;
  1834. case ZEND_AST_GREATER: BINARY_OP(" > ", 180, 181, 181);
  1835. case ZEND_AST_GREATER_EQUAL: BINARY_OP(" >= ", 180, 181, 181);
  1836. case ZEND_AST_AND: BINARY_OP(" && ", 130, 130, 131);
  1837. case ZEND_AST_OR: BINARY_OP(" || ", 120, 120, 121);
  1838. case ZEND_AST_ARRAY_ELEM:
  1839. if (ast->child[1]) {
  1840. zend_ast_export_ex(str, ast->child[1], 80, indent);
  1841. smart_str_appends(str, " => ");
  1842. }
  1843. if (ast->attr)
  1844. smart_str_appendc(str, '&');
  1845. zend_ast_export_ex(str, ast->child[0], 80, indent);
  1846. break;
  1847. case ZEND_AST_NEW:
  1848. smart_str_appends(str, "new ");
  1849. if (ast->child[0]->kind == ZEND_AST_CLASS) {
  1850. zend_ast_decl *decl = (zend_ast_decl *) ast->child[0];
  1851. if (decl->child[3]) {
  1852. zend_ast_export_attributes(str, decl->child[3], indent, 0);
  1853. }
  1854. smart_str_appends(str, "class");
  1855. if (!zend_ast_is_list(ast->child[1])
  1856. || zend_ast_get_list(ast->child[1])->children) {
  1857. smart_str_appendc(str, '(');
  1858. zend_ast_export_ex(str, ast->child[1], 0, indent);
  1859. smart_str_appendc(str, ')');
  1860. }
  1861. zend_ast_export_class_no_header(str, decl, indent);
  1862. } else {
  1863. zend_ast_export_ns_name(str, ast->child[0], 0, indent);
  1864. smart_str_appendc(str, '(');
  1865. zend_ast_export_ex(str, ast->child[1], 0, indent);
  1866. smart_str_appendc(str, ')');
  1867. }
  1868. break;
  1869. case ZEND_AST_INSTANCEOF:
  1870. zend_ast_export_ex(str, ast->child[0], 0, indent);
  1871. smart_str_appends(str, " instanceof ");
  1872. zend_ast_export_ns_name(str, ast->child[1], 0, indent);
  1873. break;
  1874. case ZEND_AST_YIELD:
  1875. if (priority > 70) smart_str_appendc(str, '(');
  1876. smart_str_appends(str, "yield ");
  1877. if (ast->child[0]) {
  1878. if (ast->child[1]) {
  1879. zend_ast_export_ex(str, ast->child[1], 70, indent);
  1880. smart_str_appends(str, " => ");
  1881. }
  1882. zend_ast_export_ex(str, ast->child[0], 70, indent);
  1883. }
  1884. if (priority > 70) smart_str_appendc(str, ')');
  1885. break;
  1886. case ZEND_AST_YIELD_FROM:
  1887. PREFIX_OP("yield from ", 85, 86);
  1888. case ZEND_AST_COALESCE: BINARY_OP(" ?? ", 110, 111, 110);
  1889. case ZEND_AST_STATIC:
  1890. smart_str_appends(str, "static $");
  1891. zend_ast_export_name(str, ast->child[0], 0, indent);
  1892. APPEND_DEFAULT_VALUE(1);
  1893. case ZEND_AST_WHILE:
  1894. smart_str_appends(str, "while (");
  1895. zend_ast_export_ex(str, ast->child[0], 0, indent);
  1896. smart_str_appends(str, ") {\n");
  1897. zend_ast_export_stmt(str, ast->child[1], indent + 1);
  1898. zend_ast_export_indent(str, indent);
  1899. smart_str_appendc(str, '}');
  1900. break;
  1901. case ZEND_AST_DO_WHILE:
  1902. smart_str_appends(str, "do {\n");
  1903. zend_ast_export_stmt(str, ast->child[0], indent + 1);
  1904. zend_ast_export_indent(str, indent);
  1905. smart_str_appends(str, "} while (");
  1906. zend_ast_export_ex(str, ast->child[1], 0, indent);
  1907. smart_str_appendc(str, ')');
  1908. break;
  1909. case ZEND_AST_IF_ELEM:
  1910. if (ast->child[0]) {
  1911. smart_str_appends(str, "if (");
  1912. zend_ast_export_ex(str, ast->child[0], 0, indent);
  1913. smart_str_appends(str, ") {\n");
  1914. zend_ast_export_stmt(str, ast->child[1], indent + 1);
  1915. } else {
  1916. smart_str_appends(str, "else {\n");
  1917. zend_ast_export_stmt(str, ast->child[1], indent + 1);
  1918. }
  1919. zend_ast_export_indent(str, indent);
  1920. smart_str_appendc(str, '}');
  1921. break;
  1922. case ZEND_AST_SWITCH:
  1923. smart_str_appends(str, "switch (");
  1924. zend_ast_export_ex(str, ast->child[0], 0, indent);
  1925. smart_str_appends(str, ") {\n");
  1926. zend_ast_export_ex(str, ast->child[1], 0, indent + 1);
  1927. zend_ast_export_indent(str, indent);
  1928. smart_str_appendc(str, '}');
  1929. break;
  1930. case ZEND_AST_SWITCH_CASE:
  1931. zend_ast_export_indent(str, indent);
  1932. if (ast->child[0]) {
  1933. smart_str_appends(str, "case ");
  1934. zend_ast_export_ex(str, ast->child[0], 0, indent);
  1935. smart_str_appends(str, ":\n");
  1936. } else {
  1937. smart_str_appends(str, "default:\n");
  1938. }
  1939. zend_ast_export_stmt(str, ast->child[1], indent + 1);
  1940. break;
  1941. case ZEND_AST_MATCH:
  1942. smart_str_appends(str, "match (");
  1943. zend_ast_export_ex(str, ast->child[0], 0, indent);
  1944. smart_str_appends(str, ") {\n");
  1945. zend_ast_export_ex(str, ast->child[1], 0, indent + 1);
  1946. zend_ast_export_indent(str, indent);
  1947. smart_str_appendc(str, '}');
  1948. break;
  1949. case ZEND_AST_MATCH_ARM:
  1950. zend_ast_export_indent(str, indent);
  1951. if (ast->child[0]) {
  1952. zend_ast_export_list(str, (zend_ast_list*)ast->child[0], 1, 0, indent);
  1953. smart_str_appends(str, " => ");
  1954. } else {
  1955. smart_str_appends(str, "default => ");
  1956. }
  1957. zend_ast_export_ex(str, ast->child[1], 0, 0);
  1958. smart_str_appends(str, ",\n");
  1959. break;
  1960. case ZEND_AST_DECLARE:
  1961. smart_str_appends(str, "declare(");
  1962. ZEND_ASSERT(ast->child[0]->kind == ZEND_AST_CONST_DECL);
  1963. zend_ast_export_list(str, (zend_ast_list*)ast->child[0], 1, 0, indent);
  1964. smart_str_appendc(str, ')');
  1965. if (ast->child[1]) {
  1966. smart_str_appends(str, " {\n");
  1967. zend_ast_export_stmt(str, ast->child[1], indent + 1);
  1968. zend_ast_export_indent(str, indent);
  1969. smart_str_appendc(str, '}');
  1970. } else {
  1971. smart_str_appendc(str, ';');
  1972. }
  1973. break;
  1974. case ZEND_AST_PROP_ELEM:
  1975. smart_str_appendc(str, '$');
  1976. ZEND_FALLTHROUGH;
  1977. case ZEND_AST_CONST_ELEM:
  1978. zend_ast_export_name(str, ast->child[0], 0, indent);
  1979. APPEND_DEFAULT_VALUE(1);
  1980. case ZEND_AST_USE_TRAIT:
  1981. smart_str_appends(str, "use ");
  1982. zend_ast_export_ex(str, ast->child[0], 0, indent);
  1983. if (ast->child[1]) {
  1984. smart_str_appends(str, " {\n");
  1985. zend_ast_export_ex(str, ast->child[1], 0, indent + 1);
  1986. zend_ast_export_indent(str, indent);
  1987. smart_str_appends(str, "}");
  1988. } else {
  1989. smart_str_appends(str, ";");
  1990. }
  1991. break;
  1992. case ZEND_AST_TRAIT_PRECEDENCE:
  1993. zend_ast_export_ex(str, ast->child[0], 0, indent);
  1994. smart_str_appends(str, " insteadof ");
  1995. zend_ast_export_ex(str, ast->child[1], 0, indent);
  1996. break;
  1997. case ZEND_AST_METHOD_REFERENCE:
  1998. if (ast->child[0]) {
  1999. zend_ast_export_name(str, ast->child[0], 0, indent);
  2000. smart_str_appends(str, "::");
  2001. }
  2002. zend_ast_export_name(str, ast->child[1], 0, indent);
  2003. break;
  2004. case ZEND_AST_NAMESPACE:
  2005. smart_str_appends(str, "namespace");
  2006. if (ast->child[0]) {
  2007. smart_str_appendc(str, ' ');
  2008. zend_ast_export_name(str, ast->child[0], 0, indent);
  2009. }
  2010. if (ast->child[1]) {
  2011. smart_str_appends(str, " {\n");
  2012. zend_ast_export_stmt(str, ast->child[1], indent + 1);
  2013. zend_ast_export_indent(str, indent);
  2014. smart_str_appends(str, "}\n");
  2015. } else {
  2016. smart_str_appendc(str, ';');
  2017. }
  2018. break;
  2019. case ZEND_AST_USE_ELEM:
  2020. case ZEND_AST_TRAIT_ALIAS:
  2021. zend_ast_export_name(str, ast->child[0], 0, indent);
  2022. if (ast->attr & ZEND_ACC_PUBLIC) {
  2023. smart_str_appends(str, " as public");
  2024. } else if (ast->attr & ZEND_ACC_PROTECTED) {
  2025. smart_str_appends(str, " as protected");
  2026. } else if (ast->attr & ZEND_ACC_PRIVATE) {
  2027. smart_str_appends(str, " as private");
  2028. } else if (ast->child[1]) {
  2029. smart_str_appends(str, " as");
  2030. }
  2031. if (ast->child[1]) {
  2032. smart_str_appendc(str, ' ');
  2033. zend_ast_export_name(str, ast->child[1], 0, indent);
  2034. }
  2035. break;
  2036. case ZEND_AST_NAMED_ARG:
  2037. smart_str_append(str, zend_ast_get_str(ast->child[0]));
  2038. smart_str_appends(str, ": ");
  2039. ast = ast->child[1];
  2040. goto tail_call;
  2041. /* 3 child nodes */
  2042. case ZEND_AST_METHOD_CALL:
  2043. case ZEND_AST_NULLSAFE_METHOD_CALL:
  2044. zend_ast_export_ex(str, ast->child[0], 0, indent);
  2045. smart_str_appends(str, ast->kind == ZEND_AST_NULLSAFE_METHOD_CALL ? "?->" : "->");
  2046. zend_ast_export_var(str, ast->child[1], 0, indent);
  2047. smart_str_appendc(str, '(');
  2048. zend_ast_export_ex(str, ast->child[2], 0, indent);
  2049. smart_str_appendc(str, ')');
  2050. break;
  2051. case ZEND_AST_STATIC_CALL:
  2052. zend_ast_export_ns_name(str, ast->child[0], 0, indent);
  2053. smart_str_appends(str, "::");
  2054. zend_ast_export_var(str, ast->child[1], 0, indent);
  2055. smart_str_appendc(str, '(');
  2056. zend_ast_export_ex(str, ast->child[2], 0, indent);
  2057. smart_str_appendc(str, ')');
  2058. break;
  2059. case ZEND_AST_CONDITIONAL:
  2060. if (priority > 100) smart_str_appendc(str, '(');
  2061. zend_ast_export_ex(str, ast->child[0], 100, indent);
  2062. if (ast->child[1]) {
  2063. smart_str_appends(str, " ? ");
  2064. zend_ast_export_ex(str, ast->child[1], 101, indent);
  2065. smart_str_appends(str, " : ");
  2066. } else {
  2067. smart_str_appends(str, " ?: ");
  2068. }
  2069. zend_ast_export_ex(str, ast->child[2], 101, indent);
  2070. if (priority > 100) smart_str_appendc(str, ')');
  2071. break;
  2072. case ZEND_AST_TRY:
  2073. smart_str_appends(str, "try {\n");
  2074. zend_ast_export_stmt(str, ast->child[0], indent + 1);
  2075. zend_ast_export_indent(str, indent);
  2076. zend_ast_export_ex(str, ast->child[1], 0, indent);
  2077. if (ast->child[2]) {
  2078. smart_str_appends(str, "} finally {\n");
  2079. zend_ast_export_stmt(str, ast->child[2], indent + 1);
  2080. zend_ast_export_indent(str, indent);
  2081. }
  2082. smart_str_appendc(str, '}');
  2083. break;
  2084. case ZEND_AST_CATCH:
  2085. smart_str_appends(str, "} catch (");
  2086. zend_ast_export_catch_name_list(str, zend_ast_get_list(ast->child[0]), indent);
  2087. if (ast->child[1]) {
  2088. smart_str_appends(str, " $");
  2089. zend_ast_export_var(str, ast->child[1], 0, indent);
  2090. }
  2091. smart_str_appends(str, ") {\n");
  2092. zend_ast_export_stmt(str, ast->child[2], indent + 1);
  2093. zend_ast_export_indent(str, indent);
  2094. break;
  2095. case ZEND_AST_PARAM:
  2096. if (ast->child[3]) {
  2097. zend_ast_export_attributes(str, ast->child[3], indent, 0);
  2098. }
  2099. if (ast->child[0]) {
  2100. zend_ast_export_type(str, ast->child[0], indent);
  2101. smart_str_appendc(str, ' ');
  2102. }
  2103. if (ast->attr & ZEND_PARAM_REF) {
  2104. smart_str_appendc(str, '&');
  2105. }
  2106. if (ast->attr & ZEND_PARAM_VARIADIC) {
  2107. smart_str_appends(str, "...");
  2108. }
  2109. smart_str_appendc(str, '$');
  2110. zend_ast_export_name(str, ast->child[1], 0, indent);
  2111. APPEND_DEFAULT_VALUE(2);
  2112. case ZEND_AST_ENUM_CASE:
  2113. if (ast->child[3]) {
  2114. zend_ast_export_attributes(str, ast->child[3], indent, 1);
  2115. }
  2116. smart_str_appends(str, "case ");
  2117. zend_ast_export_name(str, ast->child[0], 0, indent);
  2118. if (ast->child[1]) {
  2119. smart_str_appends(str, " = ");
  2120. zend_ast_export_ex(str, ast->child[1], 0, indent);
  2121. }
  2122. break;
  2123. /* 4 child nodes */
  2124. case ZEND_AST_FOR:
  2125. smart_str_appends(str, "for (");
  2126. zend_ast_export_ex(str, ast->child[0], 0, indent);
  2127. smart_str_appendc(str, ';');
  2128. if (ast->child[1]) {
  2129. smart_str_appendc(str, ' ');
  2130. zend_ast_export_ex(str, ast->child[1], 0, indent);
  2131. }
  2132. smart_str_appendc(str, ';');
  2133. if (ast->child[2]) {
  2134. smart_str_appendc(str, ' ');
  2135. zend_ast_export_ex(str, ast->child[2], 0, indent);
  2136. }
  2137. smart_str_appends(str, ") {\n");
  2138. zend_ast_export_stmt(str, ast->child[3], indent + 1);
  2139. zend_ast_export_indent(str, indent);
  2140. smart_str_appendc(str, '}');
  2141. break;
  2142. case ZEND_AST_FOREACH:
  2143. smart_str_appends(str, "foreach (");
  2144. zend_ast_export_ex(str, ast->child[0], 0, indent);
  2145. smart_str_appends(str, " as ");
  2146. if (ast->child[2]) {
  2147. zend_ast_export_ex(str, ast->child[2], 0, indent);
  2148. smart_str_appends(str, " => ");
  2149. }
  2150. zend_ast_export_ex(str, ast->child[1], 0, indent);
  2151. smart_str_appends(str, ") {\n");
  2152. zend_ast_export_stmt(str, ast->child[3], indent + 1);
  2153. zend_ast_export_indent(str, indent);
  2154. smart_str_appendc(str, '}');
  2155. break;
  2156. EMPTY_SWITCH_DEFAULT_CASE();
  2157. }
  2158. return;
  2159. binary_op:
  2160. if (priority > p) smart_str_appendc(str, '(');
  2161. zend_ast_export_ex(str, ast->child[0], pl, indent);
  2162. smart_str_appends(str, op);
  2163. zend_ast_export_ex(str, ast->child[1], pr, indent);
  2164. if (priority > p) smart_str_appendc(str, ')');
  2165. return;
  2166. prefix_op:
  2167. if (priority > p) smart_str_appendc(str, '(');
  2168. smart_str_appends(str, op);
  2169. zend_ast_export_ex(str, ast->child[0], pl, indent);
  2170. if (priority > p) smart_str_appendc(str, ')');
  2171. return;
  2172. postfix_op:
  2173. if (priority > p) smart_str_appendc(str, '(');
  2174. zend_ast_export_ex(str, ast->child[0], pl, indent);
  2175. smart_str_appends(str, op);
  2176. if (priority > p) smart_str_appendc(str, ')');
  2177. return;
  2178. func_op:
  2179. smart_str_appends(str, op);
  2180. smart_str_appendc(str, '(');
  2181. zend_ast_export_ex(str, ast->child[0], 0, indent);
  2182. smart_str_appendc(str, ')');
  2183. return;
  2184. append_node_1:
  2185. smart_str_appends(str, op);
  2186. if (ast->child[0]) {
  2187. smart_str_appendc(str, ' ');
  2188. ast = ast->child[0];
  2189. goto tail_call;
  2190. }
  2191. return;
  2192. append_str:
  2193. smart_str_appends(str, op);
  2194. return;
  2195. append_default_value:
  2196. if (ast->child[p]) {
  2197. smart_str_appends(str, " = ");
  2198. ast = ast->child[p];
  2199. goto tail_call;
  2200. }
  2201. return;
  2202. }
  2203. ZEND_API ZEND_COLD zend_string *zend_ast_export(const char *prefix, zend_ast *ast, const char *suffix)
  2204. {
  2205. smart_str str = {0};
  2206. smart_str_appends(&str, prefix);
  2207. zend_ast_export_ex(&str, ast, 0, 0);
  2208. smart_str_appends(&str, suffix);
  2209. smart_str_0(&str);
  2210. return str.s;
  2211. }
  2212. zend_ast * ZEND_FASTCALL zend_ast_with_attributes(zend_ast *ast, zend_ast *attr)
  2213. {
  2214. ZEND_ASSERT(attr->kind == ZEND_AST_ATTRIBUTE_LIST);
  2215. switch (ast->kind) {
  2216. case ZEND_AST_FUNC_DECL:
  2217. case ZEND_AST_CLOSURE:
  2218. case ZEND_AST_METHOD:
  2219. case ZEND_AST_ARROW_FUNC:
  2220. ((zend_ast_decl *) ast)->child[4] = attr;
  2221. break;
  2222. case ZEND_AST_CLASS:
  2223. ((zend_ast_decl *) ast)->child[3] = attr;
  2224. break;
  2225. case ZEND_AST_PROP_GROUP:
  2226. ast->child[2] = attr;
  2227. break;
  2228. case ZEND_AST_PARAM:
  2229. case ZEND_AST_ENUM_CASE:
  2230. ast->child[3] = attr;
  2231. break;
  2232. case ZEND_AST_CLASS_CONST_GROUP:
  2233. ast->child[1] = attr;
  2234. break;
  2235. EMPTY_SWITCH_DEFAULT_CASE()
  2236. }
  2237. return ast;
  2238. }