From e7b2d8009d4b6339116d566ef811f45a9811697a Mon Sep 17 00:00:00 2001 From: xFrednet Date: Fri, 18 Oct 2024 18:17:03 +0200 Subject: [PATCH] Mermaid: Make mermaid aware of cowns --- src/rt/core.h | 13 +++++++------ src/rt/objects/dyn_object.h | 8 ++++++++ src/rt/rt.cc | 21 ++++++--------------- src/rt/ui/mermaid.cc | 22 ++++++++++++++++++---- 4 files changed, 39 insertions(+), 25 deletions(-) diff --git a/src/rt/core.h b/src/rt/core.h index 0ede3cb..a36db45 100644 --- a/src/rt/core.h +++ b/src/rt/core.h @@ -198,12 +198,8 @@ namespace rt::core // // FIXME: Also check that the region has a LRC == 1, with 1 // being the reference passed into this constructor - this->set("region", region); - } - - bool is_aquired() - { - return aquired; + auto old = this->set("region", region); + assert(old == nullptr); } std::string get_name() @@ -220,6 +216,11 @@ namespace rt::core { return true; } + + bool is_cown_aquired() override + { + return aquired; + } }; inline std::set* globals() diff --git a/src/rt/objects/dyn_object.h b/src/rt/objects/dyn_object.h index 973e312..e4332c3 100644 --- a/src/rt/objects/dyn_object.h +++ b/src/rt/objects/dyn_object.h @@ -261,6 +261,14 @@ namespace rt::objects { return false; } + virtual bool is_cown_aquired() + { + assert(false && "should only be called on cowns"); + } + bool is_opaque() + { + return this->is_cown() && !this->is_cown_aquired(); + } [[nodiscard]] DynObject* get(std::string name) { diff --git a/src/rt/rt.cc b/src/rt/rt.cc index a24ee65..a7f2b08 100644 --- a/src/rt/rt.cc +++ b/src/rt/rt.cc @@ -56,14 +56,9 @@ namespace rt objects::DynObject* get(objects::DynObject* obj, std::string key) { - if (obj->get_prototype() == core::cownPrototypeObject()) + if (obj->is_opaque()) { - core::CownObject* cown = reinterpret_cast(obj); - if (!cown->is_aquired()) - { - ui::error( - "the cown needs to be aquired, before its data can be accessed"); - } + ui::error("opaque objects can't be accessed"); } return obj->get(key); } @@ -88,15 +83,11 @@ namespace rt objects::DynObject* set(objects::DynObject* obj, std::string key, objects::DynObject* value) { - if (obj->get_prototype() == core::cownPrototypeObject()) + if (obj->is_opaque()) { - core::CownObject* cown = reinterpret_cast(obj); - if (!cown->is_aquired()) - { - // Overwriting data can change the RC and then call destructors of the - // type this action therefore requires the cown to be aquired - ui::error("the cown needs to be aquired, before its data can modified"); - } + // Overwriting data can change the RC and then call destructors of the + // type this action therefore requires the cown to be aquired + ui::error("opaque objects can't be modified"); } return obj->set(key, value); diff --git a/src/rt/ui/mermaid.cc b/src/rt/ui/mermaid.cc index 7e38e91..2e78bec 100644 --- a/src/rt/ui/mermaid.cc +++ b/src/rt/ui/mermaid.cc @@ -10,6 +10,15 @@ namespace rt::ui { + struct MermaidDecoration + { + const char* start; + const char* end; + const char* out; + }; + const inline auto NORMAL = MermaidDecoration{"[", "]", "-->"}; + const inline auto COWN = MermaidDecoration{"[[", "]]", "-.->"}; + void replace(std::string& text, std::string from, std::string replace) { size_t pos = 0; @@ -64,9 +73,13 @@ namespace rt::ui { return false; } + auto src_deco = ((src && src->is_cown()) ? &COWN : &NORMAL); + auto dst_deco = ((dst && dst->is_cown()) ? &COWN : &NORMAL); + if (src != nullptr) { - out << " id" << visited[src] << " -->|" << escape(key) << "| "; + out << " id" << visited[src] << " " << src_deco->out << "|" + << escape(key) << "| "; } if (visited.find(dst) != visited.end()) { @@ -75,11 +88,12 @@ namespace rt::ui } auto curr_id = id++; visited[dst] = curr_id; - out << "id" << curr_id << "[ "; + out << "id" << curr_id << dst_deco->start << " "; out << escape(dst->get_name()); out << "
rc=" << dst->rc; - out << " ]" << (unreachable ? ":::unreachable" : "") << std::endl; + out << " " << dst_deco->end << (unreachable ? ":::unreachable" : "") + << std::endl; auto region = objects::DynObject::get_region(dst); if (region != nullptr) @@ -169,7 +183,7 @@ namespace rt::ui out << "class id" << visited[dst] << " tainted;" << std::endl; tainted.insert(dst); - return true; + return dst->is_opaque(); }; for (auto root : *taint)