Skip to content

Commit

Permalink
Merge pull request #82 from AjayBrahmakshatriya/master
Browse files Browse the repository at this point in the history
Extended builder::arrays to support any types and not just dyn_vars
  • Loading branch information
AjayBrahmakshatriya authored Oct 9, 2024
2 parents ea71cf5 + aa1a8d9 commit ad66595
Show file tree
Hide file tree
Showing 4 changed files with 126 additions and 35 deletions.
91 changes: 56 additions & 35 deletions include/builder/array.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,113 +5,134 @@

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 <typename T>
struct initializer_selector {
typedef const T type;
};

template <typename T>
struct initializer_selector<dyn_var<T>> {
typedef builder type;
};



template <typename T, size_t size = 0>
class dyn_arr {
class array {
private:
dyn_var<T> *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<T> *)new char[sizeof(dyn_var<T>) * actual_size];
m_arr = (T *)new char[sizeof(T) * actual_size];
for (static_var<size_t> i = 0; i < actual_size; i++) {
new (m_arr + i) dyn_var<T>();
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<size_t> i = 0; i < actual_size; i++) {
m_arr[i].block_var->template setMetadata<int>("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<builder> &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<typename initializer_selector<T>::type> &init) {
if (size) {
actual_size = size;
} else {
actual_size = init.size();
}
m_arr = (dyn_var<T> *)new char[sizeof(dyn_var<T>) * actual_size];
m_arr = (T *)new char[sizeof(T) * actual_size];
for (static_var<size_t> i = 0; i < actual_size; i++) {
if (i < init.size())
new (m_arr + i) dyn_var<T>(*(init.begin() + i));
new (m_arr + i) T(*(init.begin() + i));
else
new (m_arr + i) dyn_var<T>();
}
for (static_var<size_t> i = 0; i < actual_size; i++) {
m_arr[i].block_var->template setMetadata<int>("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<T> *)new char[sizeof(dyn_var<T>) * actual_size];
for (static_var<size_t> i = 0; i < actual_size; i++) {
new (m_arr + i) dyn_var<T>();
}
m_arr = (T *)new char[sizeof(T) * actual_size];
for (static_var<size_t> i = 0; i < actual_size; i++) {
m_arr[i].block_var->template setMetadata<int>("allow_escape_scope", 1);
new (m_arr + i) T();
}
}

template <typename T2, size_t N>
void initialize_from_other(const dyn_arr<T2, N> &other) {
void initialize_from_other(const array<T2, N> &other) {
if (size) {
actual_size = size;
} else {
actual_size = other.actual_size;
}
m_arr = (dyn_var<T> *)new char[sizeof(dyn_var<T>) * actual_size];
m_arr = (T*)new char[sizeof(T) * actual_size];
for (static_var<size_t> i = 0; i < actual_size; i++) {
if (i < other.actual_size)
new (m_arr + i) dyn_var<T>(other[i]);
new (m_arr + i) T(other[i]);
else
new (m_arr + i) dyn_var<T>();
}
for (static_var<size_t> i = 0; i < actual_size; i++) {
m_arr[i].block_var->template setMetadata<int>("allow_escape_scope", 1);
new (m_arr + i) T();
}
}

dyn_arr(const dyn_arr &other) {
array(const array &other) {
initialize_from_other(other);
}
template <typename T2, size_t N>
dyn_arr(const dyn_arr<T2, N> &other) {
array(const array<T2, N> &other) {
initialize_from_other(other);
}

dyn_arr &operator=(const dyn_arr &other) = delete;
array &operator=(const array &other) = delete;

dyn_var<T> &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<T> &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<size_t> i = 0; i < actual_size; i++) {
m_arr[i].~dyn_var<T>();
m_arr[i].~T();
}

delete[](char *) m_arr;
}
}

template <typename T2, size_t N>
friend class dyn_arr;
friend class array;
};

template <typename T, size_t N = 0>
using dyn_arr = array<dyn_var<T>, N>;

template <typename T, size_t N = 0>
using arr = array<T, N>;

} // namespace builder

#endif
24 changes: 24 additions & 0 deletions samples/outputs.var_names/sample43
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

24 changes: 24 additions & 0 deletions samples/outputs/sample43
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

22 changes: 22 additions & 0 deletions samples/sample43.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,22 @@

using builder::dyn_arr;
using builder::dyn_var;
using builder::arr;

using namespace std;



struct container {
dyn_var<int> idx;
dyn_var<int*> next;

container() {
idx = 0;
}
};


static void foo() {
dyn_arr<int, 3> x;
x[0] = 1;
Expand All @@ -21,6 +35,14 @@ static void foo() {

dyn_arr<int> b = y;
dyn_arr<int, 5> c = a;


arr<container, 5> containers;
containers[0].next = &(containers[1].idx);


arr<container, 2> conts = {containers[0], containers[1]};

}
int main(int argc, char *argv[]) {
auto ast = builder::builder_context().extract_function_ast(foo, "foo");
Expand Down

0 comments on commit ad66595

Please sign in to comment.