Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extended builder::arrays to support any types and not just dyn_vars #82

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading