static void ast_create_virtual_node( zval *zv, zend_ast_kind kind, zend_ast *ast, zend_long version) { zval tmp_zv, tmp_zv2; object_init_ex(zv, ast_node_ce); ZVAL_LONG(&tmp_zv, kind); ast_update_property(zv, AST_STR(kind), &tmp_zv, AST_CACHE_SLOT_KIND); ZVAL_LONG(&tmp_zv, ast->attr); ast_update_property(zv, AST_STR(flags), &tmp_zv, AST_CACHE_SLOT_FLAGS); ZVAL_LONG(&tmp_zv, zend_ast_get_lineno(ast)); ast_update_property(zv, AST_STR(lineno), &tmp_zv, AST_CACHE_SLOT_LINENO); array_init(&tmp_zv); ast_update_property(zv, AST_STR(children), &tmp_zv, AST_CACHE_SLOT_CHILDREN); ZVAL_COPY(&tmp_zv2, zend_ast_get_zval(ast)); if (version >= 30) { zend_hash_add_new(Z_ARRVAL(tmp_zv), ast_kind_child_name(kind, 0), &tmp_zv2); } else { zend_hash_next_index_insert(Z_ARRVAL(tmp_zv), &tmp_zv2); } }
zend_string *ast_kind_child_name(zend_ast_kind kind, uint32_t child) { switch (kind) { case AST_NAME: switch (child) { case 0: return AST_STR(str_name); } return NULL; case AST_CLOSURE_VAR: switch (child) { case 0: return AST_STR(str_name); } return NULL; case ZEND_AST_FUNC_DECL: switch (child) { case 0: return AST_STR(str_params); case 1: return AST_STR(str_uses); case 2: return AST_STR(str_stmts); case 3: return AST_STR(str_returnType); } return NULL; case ZEND_AST_CLOSURE: switch (child) { case 0: return AST_STR(str_params); case 1: return AST_STR(str_uses); case 2: return AST_STR(str_stmts); case 3: return AST_STR(str_returnType); } return NULL; case ZEND_AST_METHOD: switch (child) { case 0: return AST_STR(str_params); case 1: return AST_STR(str_uses); case 2: return AST_STR(str_stmts); case 3: return AST_STR(str_returnType); } return NULL; case ZEND_AST_CLASS: switch (child) { case 0: return AST_STR(str_extends); case 1: return AST_STR(str_implements); case 2: return AST_STR(str_stmts); } return NULL; case ZEND_AST_MAGIC_CONST: return NULL; case ZEND_AST_TYPE: return NULL; case ZEND_AST_VAR: switch (child) { case 0: return AST_STR(str_name); } return NULL; case ZEND_AST_CONST: switch (child) { case 0: return AST_STR(str_name); } return NULL; case ZEND_AST_UNPACK: switch (child) { case 0: return AST_STR(str_expr); } return NULL; case ZEND_AST_UNARY_PLUS: switch (child) { case 0: return AST_STR(str_expr); } return NULL; case ZEND_AST_UNARY_MINUS: switch (child) { case 0: return AST_STR(str_expr); } return NULL; case ZEND_AST_CAST: switch (child) { case 0: return AST_STR(str_expr); } return NULL; case ZEND_AST_EMPTY: switch (child) { case 0: return AST_STR(str_expr); } return NULL; case ZEND_AST_ISSET: switch (child) { case 0: return AST_STR(str_var); } return NULL; case ZEND_AST_SILENCE: switch (child) { case 0: return AST_STR(str_expr); } return NULL; case ZEND_AST_SHELL_EXEC: switch (child) { case 0: return AST_STR(str_expr); } return NULL; case ZEND_AST_CLONE: switch (child) { case 0: return AST_STR(str_expr); } return NULL; case ZEND_AST_EXIT: switch (child) { case 0: return AST_STR(str_expr); } return NULL; case ZEND_AST_PRINT: switch (child) { case 0: return AST_STR(str_expr); } return NULL; case ZEND_AST_INCLUDE_OR_EVAL: switch (child) { case 0: return AST_STR(str_expr); } return NULL; case ZEND_AST_UNARY_OP: switch (child) { case 0: return AST_STR(str_expr); } return NULL; case ZEND_AST_PRE_INC: switch (child) { case 0: return AST_STR(str_var); } return NULL; case ZEND_AST_PRE_DEC: switch (child) { case 0: return AST_STR(str_var); } return NULL; case ZEND_AST_POST_INC: switch (child) { case 0: return AST_STR(str_var); } return NULL; case ZEND_AST_POST_DEC: switch (child) { case 0: return AST_STR(str_var); } return NULL; case ZEND_AST_YIELD_FROM: switch (child) { case 0: return AST_STR(str_expr); } return NULL; case ZEND_AST_GLOBAL: switch (child) { case 0: return AST_STR(str_var); } return NULL; case ZEND_AST_UNSET: switch (child) { case 0: return AST_STR(str_var); } return NULL; case ZEND_AST_RETURN: switch (child) { case 0: return AST_STR(str_expr); } return NULL; case ZEND_AST_LABEL: switch (child) { case 0: return AST_STR(str_name); } return NULL; case ZEND_AST_REF: switch (child) { case 0: return AST_STR(str_var); } return NULL; case ZEND_AST_HALT_COMPILER: switch (child) { case 0: return AST_STR(str_offset); } return NULL; case ZEND_AST_ECHO: switch (child) { case 0: return AST_STR(str_expr); } return NULL; case ZEND_AST_THROW: switch (child) { case 0: return AST_STR(str_expr); } return NULL; case ZEND_AST_GOTO: switch (child) { case 0: return AST_STR(str_label); } return NULL; case ZEND_AST_BREAK: switch (child) { case 0: return AST_STR(str_depth); } return NULL; case ZEND_AST_CONTINUE: switch (child) { case 0: return AST_STR(str_depth); } return NULL; case ZEND_AST_DIM: switch (child) { case 0: return AST_STR(str_expr); case 1: return AST_STR(str_dim); } return NULL; case ZEND_AST_PROP: switch (child) { case 0: return AST_STR(str_expr); case 1: return AST_STR(str_prop); } return NULL; case ZEND_AST_STATIC_PROP: switch (child) { case 0: return AST_STR(str_class); case 1: return AST_STR(str_prop); } return NULL; case ZEND_AST_CALL: switch (child) { case 0: return AST_STR(str_expr); case 1: return AST_STR(str_args); } return NULL; case ZEND_AST_CLASS_CONST: switch (child) { case 0: return AST_STR(str_class); case 1: return AST_STR(str_const); } return NULL; case ZEND_AST_ASSIGN: switch (child) { case 0: return AST_STR(str_var); case 1: return AST_STR(str_expr); } return NULL; case ZEND_AST_ASSIGN_REF: switch (child) { case 0: return AST_STR(str_var); case 1: return AST_STR(str_expr); } return NULL; case ZEND_AST_ASSIGN_OP: switch (child) { case 0: return AST_STR(str_var); case 1: return AST_STR(str_expr); } return NULL; case ZEND_AST_BINARY_OP: switch (child) { case 0: return AST_STR(str_left); case 1: return AST_STR(str_right); } return NULL; case ZEND_AST_GREATER: switch (child) { case 0: return AST_STR(str_left); case 1: return AST_STR(str_right); } return NULL; case ZEND_AST_GREATER_EQUAL: switch (child) { case 0: return AST_STR(str_left); case 1: return AST_STR(str_right); } return NULL; case ZEND_AST_AND: switch (child) { case 0: return AST_STR(str_left); case 1: return AST_STR(str_right); } return NULL; case ZEND_AST_OR: switch (child) { case 0: return AST_STR(str_left); case 1: return AST_STR(str_right); } return NULL; case ZEND_AST_ARRAY_ELEM: switch (child) { case 0: return AST_STR(str_value); case 1: return AST_STR(str_key); } return NULL; case ZEND_AST_NEW: switch (child) { case 0: return AST_STR(str_class); case 1: return AST_STR(str_args); } return NULL; case ZEND_AST_INSTANCEOF: switch (child) { case 0: return AST_STR(str_expr); case 1: return AST_STR(str_class); } return NULL; case ZEND_AST_YIELD: switch (child) { case 0: return AST_STR(str_value); case 1: return AST_STR(str_key); } return NULL; case ZEND_AST_COALESCE: switch (child) { case 0: return AST_STR(str_left); case 1: return AST_STR(str_right); } return NULL; case ZEND_AST_STATIC: switch (child) { case 0: return AST_STR(str_var); case 1: return AST_STR(str_default); } return NULL; case ZEND_AST_WHILE: switch (child) { case 0: return AST_STR(str_cond); case 1: return AST_STR(str_stmts); } return NULL; case ZEND_AST_DO_WHILE: switch (child) { case 0: return AST_STR(str_stmts); case 1: return AST_STR(str_cond); } return NULL; case ZEND_AST_IF_ELEM: switch (child) { case 0: return AST_STR(str_cond); case 1: return AST_STR(str_stmts); } return NULL; case ZEND_AST_SWITCH: switch (child) { case 0: return AST_STR(str_cond); case 1: return AST_STR(str_stmts); } return NULL; case ZEND_AST_SWITCH_CASE: switch (child) { case 0: return AST_STR(str_cond); case 1: return AST_STR(str_stmts); } return NULL; case ZEND_AST_DECLARE: switch (child) { case 0: return AST_STR(str_declares); case 1: return AST_STR(str_stmts); } return NULL; case ZEND_AST_PROP_ELEM: switch (child) { case 0: return AST_STR(str_name); case 1: return AST_STR(str_default); } return NULL; case ZEND_AST_CONST_ELEM: switch (child) { case 0: return AST_STR(str_name); case 1: return AST_STR(str_value); } return NULL; case ZEND_AST_USE_TRAIT: switch (child) { case 0: return AST_STR(str_traits); case 1: return AST_STR(str_adaptations); } return NULL; case ZEND_AST_TRAIT_PRECEDENCE: switch (child) { case 0: return AST_STR(str_method); case 1: return AST_STR(str_insteadof); } return NULL; case ZEND_AST_METHOD_REFERENCE: switch (child) { case 0: return AST_STR(str_class); case 1: return AST_STR(str_method); } return NULL; case ZEND_AST_NAMESPACE: switch (child) { case 0: return AST_STR(str_name); case 1: return AST_STR(str_stmts); } return NULL; case ZEND_AST_USE_ELEM: switch (child) { case 0: return AST_STR(str_name); case 1: return AST_STR(str_alias); } return NULL; case ZEND_AST_TRAIT_ALIAS: switch (child) { case 0: return AST_STR(str_method); case 1: return AST_STR(str_alias); } return NULL; case ZEND_AST_GROUP_USE: switch (child) { case 0: return AST_STR(str_prefix); case 1: return AST_STR(str_uses); } return NULL; case ZEND_AST_METHOD_CALL: switch (child) { case 0: return AST_STR(str_expr); case 1: return AST_STR(str_method); case 2: return AST_STR(str_args); } return NULL; case ZEND_AST_STATIC_CALL: switch (child) { case 0: return AST_STR(str_class); case 1: return AST_STR(str_method); case 2: return AST_STR(str_args); } return NULL; case ZEND_AST_CONDITIONAL: switch (child) { case 0: return AST_STR(str_cond); case 1: return AST_STR(str_true); case 2: return AST_STR(str_false); } return NULL; case ZEND_AST_TRY: switch (child) { case 0: return AST_STR(str_try); case 1: return AST_STR(str_catches); case 2: return AST_STR(str_finally); } return NULL; case ZEND_AST_CATCH: switch (child) { case 0: return AST_STR(str_class); case 1: return AST_STR(str_var); case 2: return AST_STR(str_stmts); } return NULL; case ZEND_AST_PARAM: switch (child) { case 0: return AST_STR(str_type); case 1: return AST_STR(str_name); case 2: return AST_STR(str_default); } return NULL; case ZEND_AST_FOR: switch (child) { case 0: return AST_STR(str_init); case 1: return AST_STR(str_cond); case 2: return AST_STR(str_loop); case 3: return AST_STR(str_stmts); } return NULL; case ZEND_AST_FOREACH: switch (child) { case 0: return AST_STR(str_expr); case 1: return AST_STR(str_value); case 2: return AST_STR(str_key); case 3: return AST_STR(str_stmts); } return NULL; } return NULL; }
static void ast_to_zval(zval *zv, zend_ast *ast, zend_long version) { zval tmp_zv; zend_bool is_decl; if (ast == NULL) { ZVAL_NULL(zv); return; } if (ast->kind == ZEND_AST_ZVAL) { ZVAL_COPY(zv, zend_ast_get_zval(ast)); return; } if (version >= 20) { switch (ast->kind) { case ZEND_AST_ASSIGN_OP: ast->attr = ast_assign_op_to_binary_op(ast->attr); break; case ZEND_AST_GREATER: ast->kind = ZEND_AST_BINARY_OP; ast->attr = AST_BINARY_IS_GREATER; break; case ZEND_AST_GREATER_EQUAL: ast->kind = ZEND_AST_BINARY_OP; ast->attr = AST_BINARY_IS_GREATER_OR_EQUAL; break; case ZEND_AST_OR: ast->kind = ZEND_AST_BINARY_OP; ast->attr = AST_BINARY_BOOL_OR; break; case ZEND_AST_AND: ast->kind = ZEND_AST_BINARY_OP; ast->attr = AST_BINARY_BOOL_AND; break; case ZEND_AST_SILENCE: ast->kind = ZEND_AST_UNARY_OP; ast->attr = AST_SILENCE; break; case ZEND_AST_UNARY_PLUS: ast->kind = ZEND_AST_UNARY_OP; ast->attr = AST_PLUS; break; case ZEND_AST_UNARY_MINUS: ast->kind = ZEND_AST_UNARY_OP; ast->attr = AST_MINUS; break; } } is_decl = ast_kind_is_decl(ast->kind); object_init_ex(zv, is_decl ? ast_decl_ce : ast_node_ce); ZVAL_LONG(&tmp_zv, ast->kind); ast_update_property(zv, AST_STR(kind), &tmp_zv, AST_CACHE_SLOT_KIND); ZVAL_LONG(&tmp_zv, zend_ast_get_lineno(ast)); ast_update_property(zv, AST_STR(lineno), &tmp_zv, AST_CACHE_SLOT_LINENO); if (is_decl) { zend_ast_decl *decl = (zend_ast_decl *) ast; ZVAL_LONG(&tmp_zv, decl->flags); ast_update_property(zv, AST_STR(flags), &tmp_zv, NULL); ZVAL_LONG(&tmp_zv, decl->end_lineno); ast_update_property(zv, AST_STR(endLineno), &tmp_zv, NULL); if (decl->name) { ZVAL_STR_COPY(&tmp_zv, decl->name); } else { ZVAL_NULL(&tmp_zv); } ast_update_property(zv, AST_STR(name), &tmp_zv, NULL); if (decl->doc_comment) { ZVAL_STR_COPY(&tmp_zv, decl->doc_comment); } else { ZVAL_NULL(&tmp_zv); } ast_update_property(zv, AST_STR(docComment), &tmp_zv, NULL); } else { ZVAL_LONG(&tmp_zv, ast->attr); ast_update_property(zv, AST_STR(flags), &tmp_zv, AST_CACHE_SLOT_FLAGS); } if (version < 15 && ast->kind == ZEND_AST_PROP_DECL) { /* Before version 15 the first docComment was stored on the PROP_DECL */ zend_ast_list *props = zend_ast_get_list(ast); uint32_t i; for (i = 0; i < props->children; ++i) { zend_ast *prop = props->child[i]; if (prop->child[2]) { ZVAL_STR_COPY(&tmp_zv, zend_ast_get_str(prop->child[2])); ast_update_property(zv, AST_STR(docComment), &tmp_zv, NULL); break; } } } if (version >= 15 && ast->kind == ZEND_AST_PROP_ELEM && ast->child[2]) { ZVAL_STR_COPY(&tmp_zv, zend_ast_get_str(ast->child[2])); ast_update_property(zv, AST_STR(docComment), &tmp_zv, NULL); } array_init(&tmp_zv); ast_update_property(zv, AST_STR(children), &tmp_zv, AST_CACHE_SLOT_CHILDREN); ast_fill_children_ht(Z_ARRVAL(tmp_zv), ast, version); }