Exemple #1
0
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);
	}
}
Exemple #2
0
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;
}
Exemple #3
0
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);
}