summaryrefslogtreecommitdiff
path: root/src/expr-visitor.h
diff options
context:
space:
mode:
authorBen Smith <binjimin@gmail.com>2018-02-21 11:58:02 -0800
committerGitHub <noreply@github.com>2018-02-21 11:58:02 -0800
commitcbfa1b2f199dc5219b870c3f8bee67031bd65c33 (patch)
treefe39fca8efbef210cbb34ac024d701633cc494b2 /src/expr-visitor.h
parent8c799ef5afebc881326daa3ce54551daf48a542b (diff)
downloadwabt-cbfa1b2f199dc5219b870c3f8bee67031bd65c33.tar.gz
wabt-cbfa1b2f199dc5219b870c3f8bee67031bd65c33.tar.bz2
wabt-cbfa1b2f199dc5219b870c3f8bee67031bd65c33.zip
Rewrite ExprVisitor to be non-recursive (#765)
This will help with wasm modules that have very deeply nested blocks. See issue #752.
Diffstat (limited to 'src/expr-visitor.h')
-rw-r--r--src/expr-visitor.h29
1 files changed, 29 insertions, 0 deletions
diff --git a/src/expr-visitor.h b/src/expr-visitor.h
index c715b89c..82ff3aed 100644
--- a/src/expr-visitor.h
+++ b/src/expr-visitor.h
@@ -34,7 +34,36 @@ class ExprVisitor {
Result VisitFunc(Func*);
private:
+ enum class State {
+ Default,
+ Block,
+ IfTrue,
+ IfFalse,
+ Loop,
+ Try,
+ TryCatch,
+ };
+
+ Result HandleDefaultState(Expr*);
+ void PushDefault(Expr*);
+ void PopDefault();
+ void PushExprlist(State state, Expr*, ExprList&);
+ void PopExprlist();
+ void PushCatch(Expr*, Index catch_index, ExprList&);
+ void PopCatch();
+
Delegate* delegate_;
+
+ // Use parallel arrays instead of array of structs so we can avoid allocating
+ // unneeded objects. ExprList::iterator has no default constructor, so it
+ // must only be allocated for states that use it.
+ //
+ // NOTE(binji): This can be simplified when the new exception proposal is
+ // implemented, as it only allows for one catch block per try block.
+ std::vector<State> state_stack_;
+ std::vector<Expr*> expr_stack_;
+ std::vector<ExprList::iterator> expr_iter_stack_;
+ std::vector<Index> catch_index_stack_;
};
class ExprVisitor::Delegate {