Beispiel #1
0
static void zend_persist_ast_calc(zend_ast *ast)
{
	uint32_t i;

	if (ast->kind == ZEND_AST_ZVAL) {
		ADD_SIZE(sizeof(zend_ast_zval));
		zend_persist_zval_calc(zend_ast_get_zval(ast));
	} else if (zend_ast_is_list(ast)) {
		zend_ast_list *list = zend_ast_get_list(ast);
		ADD_SIZE(sizeof(zend_ast_list) - sizeof(zend_ast *) + sizeof(zend_ast *) * list->children);
		for (i = 0; i < list->children; i++) {
			if (list->child[i]) {
				zend_persist_ast_calc(list->child[i]);
			}
		}
	} else {
		uint32_t children = zend_ast_get_num_children(ast);
		ADD_SIZE(sizeof(zend_ast) - sizeof(zend_ast *) + sizeof(zend_ast *) * children);
		for (i = 0; i < children; i++) {
			if (ast->child[i]) {
				zend_persist_ast_calc(ast->child[i]);
			}
		}
	}
}
Beispiel #2
0
static inline zend_bool ast_is_name(zend_ast *ast, zend_ast *parent, uint32_t i) {
	if (!ast || ast->kind != ZEND_AST_ZVAL || Z_TYPE_P(zend_ast_get_zval(ast)) != IS_STRING) {
		return 0;
	}

	if (parent->kind == ZEND_AST_NAME_LIST) {
		return 1;
	}

	if (i == 0) {
		return parent->kind == ZEND_AST_CATCH || parent->kind == ZEND_AST_CLASS
			|| parent->kind == ZEND_AST_PARAM || parent->kind == ZEND_AST_METHOD_REFERENCE
			|| parent->kind == ZEND_AST_CALL || parent->kind == ZEND_AST_CONST
			|| parent->kind == ZEND_AST_NEW || parent->kind == ZEND_AST_STATIC_CALL
			|| parent->kind == ZEND_AST_CLASS_CONST || parent->kind == ZEND_AST_STATIC_PROP
			;
	}

	if (i == 1) {
		return parent->kind == ZEND_AST_INSTANCEOF;
	}

	if (i == 3) {
		return parent->kind == ZEND_AST_FUNC_DECL || parent->kind == ZEND_AST_CLOSURE
			|| parent->kind == ZEND_AST_METHOD;
	}

	return 0;
}
Beispiel #3
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);
	}
}
Beispiel #4
0
static void ast_create_virtual_node(zval *zv, zend_ast_kind kind, zend_ast *ast) {
	zval tmp_zv, tmp_zv2;

	object_init_ex(zv, ast_node_ce);

	ZVAL_LONG(&tmp_zv, kind);
	ast_update_property(zv, AST_G(str_kind), &tmp_zv, AST_CACHE_SLOT_KIND);

	ZVAL_LONG(&tmp_zv, ast->attr);
	ast_update_property(zv, AST_G(str_flags), &tmp_zv, AST_CACHE_SLOT_FLAGS);

	ZVAL_LONG(&tmp_zv, zend_ast_get_lineno(ast));
	ast_update_property(zv, AST_G(str_lineno), &tmp_zv, AST_CACHE_SLOT_LINENO);

	array_init(&tmp_zv);
	ast_update_property(zv, AST_G(str_children), &tmp_zv, AST_CACHE_SLOT_CHILDREN);

	ZVAL_COPY(&tmp_zv2, zend_ast_get_zval(ast));
	zend_hash_next_index_insert(Z_ARRVAL(tmp_zv), &tmp_zv2);
}
static zend_ast *zend_ast_clone(zend_ast *ast)
{
	uint32_t i;

	if (ast->kind == ZEND_AST_ZVAL) {
		zend_ast_zval *copy = emalloc(sizeof(zend_ast_zval));
		copy->kind = ZEND_AST_ZVAL;
		copy->attr = ast->attr;
		ZVAL_COPY_VALUE(&copy->val, zend_ast_get_zval(ast));
		zend_clone_zval(&copy->val, 0);
		return (zend_ast *) copy;
	} else if (zend_ast_is_list(ast)) {
		zend_ast_list *list = zend_ast_get_list(ast);
		zend_ast_list *copy = emalloc(
			sizeof(zend_ast_list) - sizeof(zend_ast *) + sizeof(zend_ast *) * list->children);
		copy->kind = list->kind;
		copy->attr = list->attr;
		copy->children = list->children;
		for (i = 0; i < list->children; i++) {
			if (list->child[i]) {
				copy->child[i] = zend_ast_clone(list->child[i]);
			} else {
				copy->child[i] = NULL;
			}
		}
		return (zend_ast *) copy;
	} else {
		uint32_t children = zend_ast_get_num_children(ast);
		zend_ast *copy = emalloc(sizeof(zend_ast) - sizeof(zend_ast *) + sizeof(zend_ast *) * children);
		copy->kind = ast->kind;
		copy->attr = ast->attr;
		for (i = 0; i < children; i++) {
			if (ast->child[i]) {
				copy->child[i] = zend_ast_clone(ast->child[i]);
			} else {
				copy->child[i] = NULL;
			}
		}
		return copy;
	}
}
Beispiel #6
0
static void ast_to_zval(zval *zv, zend_ast *ast) {
	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;
	}

	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_G(str_kind), &tmp_zv, AST_CACHE_SLOT_KIND);

	ZVAL_LONG(&tmp_zv, zend_ast_get_lineno(ast));
	ast_update_property(zv, AST_G(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_G(str_flags), &tmp_zv, NULL);

		ZVAL_LONG(&tmp_zv, decl->end_lineno);
		ast_update_property(zv, AST_G(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_G(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_G(str_docComment), &tmp_zv, NULL);
	} else {
		ZVAL_LONG(&tmp_zv, ast->attr);
		ast_update_property(zv, AST_G(str_flags), &tmp_zv, AST_CACHE_SLOT_FLAGS);
	}
	
	if (ast->kind == ZEND_AST_PROP_DECL) {
		zend_ast_list *props = zend_ast_get_list(ast);
		zend_ast *last_prop = props->child[props->children - 1];

		/* PROP_DECL stores the doc comment as last property */
		if (last_prop->kind == ZEND_AST_ZVAL) {
			props->children -= 1;

			ZVAL_STR(&tmp_zv, zend_ast_get_str(last_prop));
			ast_update_property(zv, AST_G(str_docComment), &tmp_zv, NULL);
		}
	}

	array_init(&tmp_zv);
	ast_update_property(zv, AST_G(str_children), &tmp_zv, AST_CACHE_SLOT_CHILDREN);

	{
		uint32_t i, count;
		zend_ast **children = ast_get_children(ast, &count);
		for (i = 0; i < count; ++i) {
			zend_ast *child = children[i];
			zval child_zv;

			if (ast_is_name(child, ast, i)) {
				ast_create_virtual_node(&child_zv, AST_NAME, child);
			} else if (ast->kind == ZEND_AST_CLOSURE_USES) {
				ast_create_virtual_node(&child_zv, AST_CLOSURE_VAR, child);
			} else {
				ast_to_zval(&child_zv, child);
			}

			zend_hash_next_index_insert(Z_ARRVAL(tmp_zv), &child_zv);
		}
	}
}
Beispiel #7
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);
}