diff options
author | Alon Zakai <azakai@google.com> | 2019-06-03 19:09:46 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-06-03 19:09:46 -0700 |
commit | 9d4f053070fa4a0d61663901d5206c025d694bb2 (patch) | |
tree | b721ef95e0570192d84a8601a6b6dfe62ae90a20 /src | |
parent | fe99e3458f11d1a01fa3ad5b68883dbcba3903af (diff) | |
download | binaryen-9d4f053070fa4a0d61663901d5206c025d694bb2.tar.gz binaryen-9d4f053070fa4a0d61663901d5206c025d694bb2.tar.bz2 binaryen-9d4f053070fa4a0d61663901d5206c025d694bb2.zip |
Add a recursion limit for the interpreter's expression runner (#2160)
We previously had one for calls (the spec tests check for infinite recursion).
This is an internal limit of the interpreter, until we un-recursify it, which may make sense at some point - but it's unlikely interpreting massively-recursive things will be beneficial in the optimizer anyhow, since if it could do something with them, it could also do so on the smaller pieces iteratively.
Diffstat (limited to 'src')
-rw-r--r-- | src/wasm-interpreter.h | 13 |
1 files changed, 11 insertions, 2 deletions
diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h index 85a50163a..7dd9688c3 100644 --- a/src/wasm-interpreter.h +++ b/src/wasm-interpreter.h @@ -45,7 +45,7 @@ using namespace cashew; extern Name WASM, RETURN_FLOW; -enum { maxCallDepth = 250 }; +enum { maxInterpreterDepth = 250 }; // Stuff that flows around during executing expressions: a literal, or a change // in control flow. @@ -128,8 +128,16 @@ public: // Execute an expression template<typename SubType> class ExpressionRunner : public OverriddenVisitor<SubType, Flow> { +protected: + // Keep a record of call depth, to guard against excessive recursion. + size_t depth = 0; + public: Flow visit(Expression* curr) { + depth++; + if (depth > maxInterpreterDepth) { + trap("interpreter recursion limit"); + } auto ret = OverriddenVisitor<SubType, Flow>::visit(curr); if (!ret.breaking() && (isConcreteType(curr->type) || isConcreteType(ret.value.type))) { @@ -142,6 +150,7 @@ public: #endif assert(ret.value.type == curr->type); } + depth--; return ret; } @@ -1790,7 +1799,7 @@ public: // Internal function call. Must be public so that callTable implementations // can use it (refactor?) Literal callFunctionInternal(Name name, const LiteralList& arguments) { - if (callDepth > maxCallDepth) { + if (callDepth > maxInterpreterDepth) { externalInterface->trap("stack limit"); } auto previousCallDepth = callDepth; |