Skip to content

Commit 9d4f053

Browse files
authored
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.
1 parent fe99e34 commit 9d4f053

1 file changed

Lines changed: 11 additions & 2 deletions

File tree

src/wasm-interpreter.h

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ using namespace cashew;
4545

4646
extern Name WASM, RETURN_FLOW;
4747

48-
enum { maxCallDepth = 250 };
48+
enum { maxInterpreterDepth = 250 };
4949

5050
// Stuff that flows around during executing expressions: a literal, or a change
5151
// in control flow.
@@ -128,8 +128,16 @@ class Indenter {
128128
// Execute an expression
129129
template<typename SubType>
130130
class ExpressionRunner : public OverriddenVisitor<SubType, Flow> {
131+
protected:
132+
// Keep a record of call depth, to guard against excessive recursion.
133+
size_t depth = 0;
134+
131135
public:
132136
Flow visit(Expression* curr) {
137+
depth++;
138+
if (depth > maxInterpreterDepth) {
139+
trap("interpreter recursion limit");
140+
}
133141
auto ret = OverriddenVisitor<SubType, Flow>::visit(curr);
134142
if (!ret.breaking() &&
135143
(isConcreteType(curr->type) || isConcreteType(ret.value.type))) {
@@ -142,6 +150,7 @@ class ExpressionRunner : public OverriddenVisitor<SubType, Flow> {
142150
#endif
143151
assert(ret.value.type == curr->type);
144152
}
153+
depth--;
145154
return ret;
146155
}
147156

@@ -1790,7 +1799,7 @@ template<typename GlobalManager, typename SubType> class ModuleInstanceBase {
17901799
// Internal function call. Must be public so that callTable implementations
17911800
// can use it (refactor?)
17921801
Literal callFunctionInternal(Name name, const LiteralList& arguments) {
1793-
if (callDepth > maxCallDepth) {
1802+
if (callDepth > maxInterpreterDepth) {
17941803
externalInterface->trap("stack limit");
17951804
}
17961805
auto previousCallDepth = callDepth;

0 commit comments

Comments
 (0)