Skip to content

Commit

Permalink
Mermaid: Draw nested regions as nested subgraphs
Browse files Browse the repository at this point in the history
  • Loading branch information
xFrednet committed Nov 1, 2024
1 parent 75b0056 commit 3fc374d
Show file tree
Hide file tree
Showing 2 changed files with 132 additions and 53 deletions.
155 changes: 102 additions & 53 deletions src/rt/ui/mermaid.cc
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,17 @@ namespace rt::ui
const char* IMMUTABLE_REGION_COLOR = "#485464";
const char* IMMUTABLE_EDGE_COLOR = "#94f7ff";

// const char* REGION_COLORS[] = {
// "#6d6d6d",
// "#626262",
// "#575757",
// "#4c4c4c",
// "#414141",
// "#363636",
// "#2b2b2b"};
const char* REGION_COLORS[] = {
"#666", "#555", "#444", "#333", "#222", "#111"};

const char* LOCAL_REGION_ID = "LocalReg";
const char* IMM_REGION_ID = "ImmReg";
const char* COWN_REGION_ID = "CownReg";
Expand Down Expand Up @@ -64,6 +75,13 @@ namespace rt::ui
return os;
}

struct RegionInfo
{
std::vector<size_t> nodes;
std::vector<objects::Region*> regions;
bool drawn;
};

class MermaidDiagram
{
MermaidUI* info;
Expand All @@ -75,13 +93,14 @@ namespace rt::ui
// Give a nice id to each object.
std::map<objects::DynObject*, NodeInfo> nodes;
std::map<objects::Region*, std::vector<std::size_t>> region_strings;
std::map<objects::Region*, RegionInfo> regions;

public:
MermaidDiagram(MermaidUI* info_) : info(info_), out(info->out)
{
// Add nullptr
nodes[nullptr] = {0};
region_strings[rt::objects::immutable_region].push_back(0);
regions[objects::immutable_region].nodes.push_back(0);
}

void color_edge(size_t edge_id, const char* color)
Expand Down Expand Up @@ -186,8 +205,9 @@ namespace rt::ui

// Footer
out << markers.second;
out << (reachable ? "" : ":::unreachable");
out << (dst->is_immutable() ? ":::immutable" : "");
out
<< (dst->is_immutable() ? ":::immutable" :
(reachable ? "" : ":::unreachable"));
out << std::endl;

result = node;
Expand Down Expand Up @@ -232,7 +252,7 @@ namespace rt::ui
auto region = objects::get_region(dst);
if (region != nullptr)
{
region_strings[region].push_back(node->id);
regions[region].nodes.push_back(node->id);
}

return true;
Expand All @@ -251,70 +271,99 @@ namespace rt::ui
}
}

void draw_regions()
void
draw_region_body(objects::Region* r, RegionInfo* info, std::string& indent)
{
// Output any region parent edges.
for (auto [region, objects] : region_strings)
indent += " ";
for (auto obj : info->nodes)
{
if (region->parent == nullptr)
{
continue;
}
if ((!info->draw_cown_region) && region->parent == objects::cown_region)
{
continue;
}

out << " region" << region->parent << " <-.-o region" << region
<< std::endl;
edge_counter += 1;
out << indent << "id" << obj << std::endl;
}
for (auto reg : info->regions)
{
draw_region(reg, indent);
}
indent.erase(indent.size() - 2);
}

// Output all the region membership information
for (auto [region, objects] : region_strings)
void draw_region(objects::Region* r, std::string& indent)
{
auto info = &regions[r];
if (info->drawn)
{
if (
((!info->draw_cown_region) && region == objects::cown_region) ||
((!info->draw_immutable_region) &&
region == objects::immutable_region))
{
continue;
}
return;
}
info->drawn = true;
auto depth = indent.size() / 2;

out << "subgraph ";
// Header
out << indent << "subgraph ";
out << "reg" << r << "[\" \"]" << std::endl;

if (region == objects::get_local_region())
{
out << LOCAL_REGION_ID << "[\"Local region\"]" << std::endl;
}
else if (region == objects::immutable_region)
{
out << IMM_REGION_ID << "[\"Immutable region\"]" << std::endl;
out << " id0" << std::endl;
}
else if (region == objects::cown_region)
{
out << COWN_REGION_ID << "[\"Cown region\"]" << std::endl;
out << " region" << region << "[\\" << region
<< "<br/>sbrc=" << region->sub_region_reference_count << "/]"
<< std::endl;
}
else
{
out << "region" << region << "[\" \"]" << std::endl;
}
for (auto obj : objects)
{
out << " id" << obj << std::endl;
}
// Content
draw_region_body(r, info, indent);

// Footer
out << indent << "end" << std::endl;
out << indent << "style reg" << r
<< " fill:" << REGION_COLORS[depth % std::size(REGION_COLORS)]
<< std::endl;
}

void draw_regions()
{
// Build parent relations
for (auto [reg, _] : regions)
{
regions[reg->parent].regions.push_back(reg);
}

std::string indent;
if (info->draw_cown_region)
{
auto region = objects::cown_region;
out << "subgraph " << COWN_REGION_ID << "[\"Cown region\"]"
<< std::endl;
draw_region_body(region, &regions[region], indent);
out << "end" << std::endl;
out << "style " << COWN_REGION_ID << " fill:" << REGION_COLORS[0]
<< std::endl;
}
regions[objects::cown_region].drawn = true;

if (info->draw_immutable_region)
{
auto region = objects::immutable_region;
out << "subgraph " << IMM_REGION_ID << "[\"Immutable region\"]"
<< std::endl;
draw_region_body(region, &regions[region], indent);
out << "end" << std::endl;
out << "style " << IMM_REGION_ID << " fill:" << IMMUTABLE_REGION_COLOR
<< std::endl;
}
regions[objects::immutable_region].drawn = true;

// Local region
{
auto region = objects::get_local_region();
out << "subgraph " << LOCAL_REGION_ID << "[\"Local region\"]"
<< std::endl;
draw_region_body(objects::cown_region, &regions[region], indent);
out << "end" << std::endl;
out << "style " << LOCAL_REGION_ID << " fill:" << REGION_COLORS[0]
<< std::endl;
}
regions[objects::get_local_region()].drawn = true;

// Draw all other regions
for (auto reg : regions[nullptr].regions)
{
draw_region(reg, indent);
}
for (auto reg : regions[objects::cown_region].regions)
{
draw_region(reg, indent);
}
}

void draw_taint()
Expand Down
30 changes: 30 additions & 0 deletions tests/regions/region4.vpy
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Create multiple regions
r1 = Region()
r1.level = "One"

r2 = Region()
r2.level = "Two"

r3 = Region()
r3.level = "Three"

r4 = Region()
r4.level = "Four"

r5 = Region()
r5.level = "Five"

# Stack regions
r1.n = move r2
r1.n.n = r3

r4.n = move r5
r3.n = move r4
drop r3

# Move this into a cown
c = cown(move r1)

# Check the visuals
mermaid_show_cown_region()
mermaid_show_immutable_region()

0 comments on commit 3fc374d

Please sign in to comment.