From aa1a8d94445dc410fd0664516d0ed40b32753d36 Mon Sep 17 00:00:00 2001 From: Ajay Brahmakshatriya Date: Tue, 8 Oct 2024 21:13:47 -0700 Subject: [PATCH] Extended builder::arrays to support any types and not just dyn_vars --- include/builder/array.h | 91 ++++++++++++++++++------------ samples/outputs.var_names/sample43 | 24 ++++++++ samples/outputs/sample43 | 24 ++++++++ samples/sample43.cpp | 22 ++++++++ 4 files changed, 126 insertions(+), 35 deletions(-) diff --git a/include/builder/array.h b/include/builder/array.h index f235615..fc00ddf 100644 --- a/include/builder/array.h +++ b/include/builder/array.h @@ -5,103 +5,118 @@ namespace builder { + +// If the array is of dyn_vars, we initialize with a +// builder, anything else and we directly initialize with T +// This avoids unnecessary copies unless entirely necessary +template +struct initializer_selector { + typedef const T type; +}; + +template +struct initializer_selector> { + typedef builder type; +}; + + + template -class dyn_arr { +class array { private: - dyn_var *m_arr = nullptr; + T *m_arr = nullptr; size_t actual_size = 0; public: - dyn_arr() { + array() { if (size) { actual_size = size; - m_arr = (dyn_var *)new char[sizeof(dyn_var) * actual_size]; + m_arr = (T *)new char[sizeof(T) * actual_size]; for (static_var i = 0; i < actual_size; i++) { - new (m_arr + i) dyn_var(); + new (m_arr + i) T(); } + // static tags for array nodes need to be adjusted // so they are treated different from each other despite // being declared at the same location. // dyn_arr are special case of vars that escape their static scope but still // shouldn't be treated together // We do this by adding additional metadata on all of them - for (static_var i = 0; i < actual_size; i++) { - m_arr[i].block_var->template setMetadata("allow_escape_scope", 1); - } + + // We are removing the metadata for allow_escape_scope because it is not being + // used anyway right now. Enabling this would require us to set it as a variable + // inside the context so all the dynamic variables constructed in this block would have + // the metadata set + } } - dyn_arr(const std::initializer_list &init) { + // We need a SFINAE constructor of anything that is convertible to T + // but let's stick with T for now + array(const std::initializer_list::type> &init) { if (size) { actual_size = size; } else { actual_size = init.size(); } - m_arr = (dyn_var *)new char[sizeof(dyn_var) * actual_size]; + m_arr = (T *)new char[sizeof(T) * actual_size]; for (static_var i = 0; i < actual_size; i++) { if (i < init.size()) - new (m_arr + i) dyn_var(*(init.begin() + i)); + new (m_arr + i) T(*(init.begin() + i)); else - new (m_arr + i) dyn_var(); - } - for (static_var i = 0; i < actual_size; i++) { - m_arr[i].block_var->template setMetadata("allow_escape_scope", 1); + new (m_arr + i) T(); } } + + void set_size(size_t new_size) { assert(size == 0 && "set_size should be only called for dyn_arr without size"); assert(m_arr == nullptr && "set_size should be only called once"); actual_size = new_size; - m_arr = (dyn_var *)new char[sizeof(dyn_var) * actual_size]; - for (static_var i = 0; i < actual_size; i++) { - new (m_arr + i) dyn_var(); - } + m_arr = (T *)new char[sizeof(T) * actual_size]; for (static_var i = 0; i < actual_size; i++) { - m_arr[i].block_var->template setMetadata("allow_escape_scope", 1); + new (m_arr + i) T(); } } template - void initialize_from_other(const dyn_arr &other) { + void initialize_from_other(const array &other) { if (size) { actual_size = size; } else { actual_size = other.actual_size; } - m_arr = (dyn_var *)new char[sizeof(dyn_var) * actual_size]; + m_arr = (T*)new char[sizeof(T) * actual_size]; for (static_var i = 0; i < actual_size; i++) { if (i < other.actual_size) - new (m_arr + i) dyn_var(other[i]); + new (m_arr + i) T(other[i]); else - new (m_arr + i) dyn_var(); - } - for (static_var i = 0; i < actual_size; i++) { - m_arr[i].block_var->template setMetadata("allow_escape_scope", 1); + new (m_arr + i) T(); } } - dyn_arr(const dyn_arr &other) { + array(const array &other) { initialize_from_other(other); } template - dyn_arr(const dyn_arr &other) { + array(const array &other) { initialize_from_other(other); } - dyn_arr &operator=(const dyn_arr &other) = delete; + array &operator=(const array &other) = delete; - dyn_var &operator[](size_t index) { + T &operator[](size_t index) { assert(m_arr != nullptr && "Should call set_size for arrays that don't have a size"); return m_arr[index]; } - const dyn_var &operator[](size_t index) const { + const T &operator[](size_t index) const { assert(m_arr != nullptr && "Should call set_size for arrays that don't have a size"); return m_arr[index]; } - ~dyn_arr() { + ~array() { if (m_arr) { for (static_var i = 0; i < actual_size; i++) { - m_arr[i].~dyn_var(); + m_arr[i].~T(); } delete[](char *) m_arr; @@ -109,9 +124,15 @@ class dyn_arr { } template - friend class dyn_arr; + friend class array; }; +template +using dyn_arr = array, N>; + +template +using arr = array; + } // namespace builder #endif diff --git a/samples/outputs.var_names/sample43 b/samples/outputs.var_names/sample43 index 1a30f57..5fc6d6d 100644 --- a/samples/outputs.var_names/sample43 +++ b/samples/outputs.var_names/sample43 @@ -22,5 +22,29 @@ void foo (void) { int var17; int var18; int var19; + int var20; + int* var21; + var20 = 0; + int var22; + int* var23; + var22 = 0; + int var24; + int* var25; + var24 = 0; + int var26; + int* var27; + var26 = 0; + int var28; + int* var29; + var28 = 0; + var21 = (&(var22)); + int var30 = var20; + int* var31 = var21; + int var32 = var22; + int* var33 = var23; + int var34 = var30; + int* var35 = var31; + int var36 = var32; + int* var37 = var33; } diff --git a/samples/outputs/sample43 b/samples/outputs/sample43 index 1a30f57..5fc6d6d 100644 --- a/samples/outputs/sample43 +++ b/samples/outputs/sample43 @@ -22,5 +22,29 @@ void foo (void) { int var17; int var18; int var19; + int var20; + int* var21; + var20 = 0; + int var22; + int* var23; + var22 = 0; + int var24; + int* var25; + var24 = 0; + int var26; + int* var27; + var26 = 0; + int var28; + int* var29; + var28 = 0; + var21 = (&(var22)); + int var30 = var20; + int* var31 = var21; + int var32 = var22; + int* var33 = var23; + int var34 = var30; + int* var35 = var31; + int var36 = var32; + int* var37 = var33; } diff --git a/samples/sample43.cpp b/samples/sample43.cpp index 65eb9e0..a946384 100644 --- a/samples/sample43.cpp +++ b/samples/sample43.cpp @@ -4,8 +4,22 @@ using builder::dyn_arr; using builder::dyn_var; +using builder::arr; + using namespace std; + + +struct container { + dyn_var idx; + dyn_var next; + + container() { + idx = 0; + } +}; + + static void foo() { dyn_arr x; x[0] = 1; @@ -21,6 +35,14 @@ static void foo() { dyn_arr b = y; dyn_arr c = a; + + + arr containers; + containers[0].next = &(containers[1].idx); + + + arr conts = {containers[0], containers[1]}; + } int main(int argc, char *argv[]) { auto ast = builder::builder_context().extract_function_ast(foo, "foo");