diff options
Diffstat (limited to 'src/emscripten-optimizer/simple_ast.cpp')
-rw-r--r-- | src/emscripten-optimizer/simple_ast.cpp | 153 |
1 files changed, 121 insertions, 32 deletions
diff --git a/src/emscripten-optimizer/simple_ast.cpp b/src/emscripten-optimizer/simple_ast.cpp index dddaeab02..75685f80e 100644 --- a/src/emscripten-optimizer/simple_ast.cpp +++ b/src/emscripten-optimizer/simple_ast.cpp @@ -54,31 +54,124 @@ bool Ref::operator!() { // Arena -Arena arena; +GlobalMixedArena arena; -Arena::~Arena() { - for (auto* chunk : chunks) { - delete[] chunk; - } - for (auto* chunk : arr_chunks) { - delete[] chunk; - } +// Value + +Value& Value::setAssign(Ref target, Ref value) { + asAssign()->target() = target; + asAssign()->value() = value; + return *this; } -Ref Arena::alloc() { - if (chunks.size() == 0 || index == CHUNK_SIZE) { - chunks.push_back(new Value[CHUNK_SIZE]); - index = 0; - } - return &chunks.back()[index++]; +Value& Value::setAssignName(IString target, Ref value) { + asAssignName()->target() = target; + asAssignName()->value() = value; + return *this; +} + +Assign* Value::asAssign() { + assert(isAssign()); + return static_cast<Assign*>(this); +} + +AssignName* Value::asAssignName() { + assert(isAssignName()); + return static_cast<AssignName*>(this); } -ArrayStorage* Arena::allocArray() { - if (arr_chunks.size() == 0 || arr_index == CHUNK_SIZE) { - arr_chunks.push_back(new ArrayStorage[CHUNK_SIZE]); - arr_index = 0; +void Value::stringify(std::ostream &os, bool pretty) { + static int indent = 0; + #define indentify() { for (int i_ = 0; i_ < indent; i_++) os << " "; } + switch (type) { + case String: { + if (str.str) { + os << '"' << str.str << '"'; + } else { + os << "\"(null)\""; + } + break; + } + case Number: { + os << std::setprecision(17) << num; // doubles can have 17 digits of precision + break; + } + case Array: { + if (arr->size() == 0) { + os << "[]"; + break; + } + os << '['; + if (pretty) { + os << std::endl; + indent++; + } + for (size_t i = 0; i < arr->size(); i++) { + if (i > 0) { + if (pretty) os << "," << std::endl; + else os << ", "; + } + indentify(); + (*arr)[i]->stringify(os, pretty); + } + if (pretty) { + os << std::endl; + indent--; + } + indentify(); + os << ']'; + break; + } + case Null: { + os << "null"; + break; + } + case Bool: { + os << (boo ? "true" : "false"); + break; + } + case Object: { + os << '{'; + if (pretty) { + os << std::endl; + indent++; + } + bool first = true; + for (auto i : *obj) { + if (first) { + first = false; + } else { + os << ", "; + if (pretty) os << std::endl; + } + indentify(); + os << '"' << i.first.c_str() << "\": "; + i.second->stringify(os, pretty); + } + if (pretty) { + os << std::endl; + indent--; + } + indentify(); + os << '}'; + break; + } + case Assign_: { + os << "["; + ref->stringify(os, pretty); + os << ", "; + asAssign()->value()->stringify(os, pretty); + os << "]"; + break; + } + case AssignName_: { + os << "[\"" << asAssignName()->target().str << "\""; + os << ", "; + asAssignName()->value()->stringify(os, pretty); + os << "]"; + break; + } } - return &arr_chunks.back()[arr_index++]; } // dump @@ -161,7 +254,7 @@ void traversePre(Ref node, std::function<void (Ref)> visit) { int index = 0; ArrayStorage* arr = &node->getArray(); int arrsize = (int)arr->size(); - Ref* arrdata = arr->data(); + Ref* arrdata = &(*arr)[0]; stack.push_back(TraverseInfo(node, arr)); while (1) { if (index < arrsize) { @@ -173,7 +266,7 @@ void traversePre(Ref node, std::function<void (Ref)> visit) { visit(sub); arr = &sub->getArray(); arrsize = (int)arr->size(); - arrdata = arr->data(); + arrdata = &(*arr)[0]; stack.push_back(TraverseInfo(sub, arr)); } } else { @@ -183,7 +276,7 @@ void traversePre(Ref node, std::function<void (Ref)> visit) { index = back.index; arr = back.arr; arrsize = (int)arr->size(); - arrdata = arr->data(); + arrdata = &(*arr)[0]; } } } @@ -196,7 +289,7 @@ void traversePrePost(Ref node, std::function<void (Ref)> visitPre, std::function int index = 0; ArrayStorage* arr = &node->getArray(); int arrsize = (int)arr->size(); - Ref* arrdata = arr->data(); + Ref* arrdata = &(*arr)[0]; stack.push_back(TraverseInfo(node, arr)); while (1) { if (index < arrsize) { @@ -208,7 +301,7 @@ void traversePrePost(Ref node, std::function<void (Ref)> visitPre, std::function visitPre(sub); arr = &sub->getArray(); arrsize = (int)arr->size(); - arrdata = arr->data(); + arrdata = &(*arr)[0]; stack.push_back(TraverseInfo(sub, arr)); } } else { @@ -219,7 +312,7 @@ void traversePrePost(Ref node, std::function<void (Ref)> visitPre, std::function index = back.index; arr = back.arr; arrsize = (int)arr->size(); - arrdata = arr->data(); + arrdata = &(*arr)[0]; } } } @@ -232,7 +325,7 @@ void traversePrePostConditional(Ref node, std::function<bool (Ref)> visitPre, st int index = 0; ArrayStorage* arr = &node->getArray(); int arrsize = (int)arr->size(); - Ref* arrdata = arr->data(); + Ref* arrdata = &(*arr)[0]; stack.push_back(TraverseInfo(node, arr)); while (1) { if (index < arrsize) { @@ -244,7 +337,7 @@ void traversePrePostConditional(Ref node, std::function<bool (Ref)> visitPre, st index = 0; arr = &sub->getArray(); arrsize = (int)arr->size(); - arrdata = arr->data(); + arrdata = &(*arr)[0]; stack.push_back(TraverseInfo(sub, arr)); } } @@ -256,7 +349,7 @@ void traversePrePostConditional(Ref node, std::function<bool (Ref)> visitPre, st index = back.index; arr = back.arr; arrsize = (int)arr->size(); - arrdata = arr->data(); + arrdata = &(*arr)[0]; } } } @@ -275,8 +368,4 @@ void traverseFunctions(Ref ast, std::function<void (Ref)> visit) { } } -// ValueBuilder - -IStringSet ValueBuilder::statable("assign call binary unary-prefix name num conditional dot new sub seq string object array"); - } // namespace cashew |