@@ -45,8 +45,6 @@ using namespace cashew;
4545
4646extern Name WASM, RETURN_FLOW;
4747
48- enum { maxInterpreterDepth = 50 };
49-
5048// Stuff that flows around during executing expressions: a literal, or a change
5149// in control flow.
5250class Flow {
@@ -129,13 +127,16 @@ class Indenter {
129127template <typename SubType>
130128class ExpressionRunner : public OverriddenVisitor <SubType, Flow> {
131129protected:
132- // Keep a record of call depth, to guard against excessive recursion.
133- size_t depth = 0 ;
130+ Index maxDepth;
131+
132+ Index depth = 0 ;
134133
135134public:
135+ ExpressionRunner (Index maxDepth) : maxDepth(maxDepth) {}
136+
136137 Flow visit (Expression* curr) {
137138 depth++;
138- if (depth > maxInterpreterDepth ) {
139+ if (depth > maxDepth ) {
139140 trap (" interpreter recursion limit" );
140141 }
141142 auto ret = OverriddenVisitor<SubType, Flow>::visit (curr);
@@ -1056,7 +1057,9 @@ class ConstantExpressionRunner
10561057 GlobalManager& globals;
10571058
10581059public:
1059- ConstantExpressionRunner (GlobalManager& globals) : globals(globals) {}
1060+ ConstantExpressionRunner (GlobalManager& globals, Index maxDepth)
1061+ : ExpressionRunner<ConstantExpressionRunner<GlobalManager>>(maxDepth),
1062+ globals (globals) {}
10601063
10611064 Flow visitGlobalGet (GlobalGet* curr) { return Flow (globals[curr->name ]); }
10621065};
@@ -1232,9 +1235,10 @@ template<typename GlobalManager, typename SubType> class ModuleInstanceBase {
12321235 memorySize = wasm.memory .initial ;
12331236 // generate internal (non-imported) globals
12341237 ModuleUtils::iterDefinedGlobals (wasm, [&](Global* global) {
1235- globals[global->name ] = ConstantExpressionRunner<GlobalManager>(globals)
1236- .visit (global->init )
1237- .value ;
1238+ globals[global->name ] =
1239+ ConstantExpressionRunner<GlobalManager>(globals, maxDepth)
1240+ .visit (global->init )
1241+ .value ;
12381242 });
12391243
12401244 // initialize the rest of the external interface
@@ -1297,7 +1301,7 @@ template<typename GlobalManager, typename SubType> class ModuleInstanceBase {
12971301 void initializeTableContents () {
12981302 for (auto & segment : wasm.table .segments ) {
12991303 Address offset =
1300- (uint32_t )ConstantExpressionRunner<GlobalManager>(globals)
1304+ (uint32_t )ConstantExpressionRunner<GlobalManager>(globals, maxDepth )
13011305 .visit (segment.offset )
13021306 .value .geti32 ();
13031307 if (offset + segment.data .size () > wasm.table .initial ) {
@@ -1340,7 +1344,7 @@ template<typename GlobalManager, typename SubType> class ModuleInstanceBase {
13401344 // the memory.init and data.drop instructions.
13411345 Function dummyFunc;
13421346 FunctionScope dummyScope (&dummyFunc, {});
1343- RuntimeExpressionRunner runner (*this , dummyScope);
1347+ RuntimeExpressionRunner runner (*this , dummyScope, maxDepth );
13441348 runner.visit (&init);
13451349 runner.visit (&drop);
13461350 }
@@ -1387,8 +1391,11 @@ template<typename GlobalManager, typename SubType> class ModuleInstanceBase {
13871391 FunctionScope& scope;
13881392
13891393 public:
1390- RuntimeExpressionRunner (ModuleInstanceBase& instance, FunctionScope& scope)
1391- : instance(instance), scope(scope) {}
1394+ RuntimeExpressionRunner (ModuleInstanceBase& instance,
1395+ FunctionScope& scope,
1396+ Index maxDepth)
1397+ : ExpressionRunner<RuntimeExpressionRunner>(maxDepth), instance(instance),
1398+ scope (scope) {}
13921399
13931400 Flow generateArguments (const ExpressionList& operands,
13941401 LiteralList& arguments) {
@@ -1788,7 +1795,7 @@ template<typename GlobalManager, typename SubType> class ModuleInstanceBase {
17881795 // Internal function call. Must be public so that callTable implementations
17891796 // can use it (refactor?)
17901797 Literal callFunctionInternal (Name name, const LiteralList& arguments) {
1791- if (callDepth > maxInterpreterDepth ) {
1798+ if (callDepth > maxDepth ) {
17921799 externalInterface->trap (" stack limit" );
17931800 }
17941801 auto previousCallDepth = callDepth;
@@ -1807,7 +1814,8 @@ template<typename GlobalManager, typename SubType> class ModuleInstanceBase {
18071814 }
18081815#endif
18091816
1810- Flow flow = RuntimeExpressionRunner (*this , scope).visit (function->body );
1817+ Flow flow =
1818+ RuntimeExpressionRunner (*this , scope, maxDepth).visit (function->body );
18111819 // cannot still be breaking, it means we missed our stop
18121820 assert (!flow.breaking () || flow.breakTo == RETURN_FLOW);
18131821 Literal ret = flow.value ;
@@ -1831,6 +1839,8 @@ template<typename GlobalManager, typename SubType> class ModuleInstanceBase {
18311839protected:
18321840 Address memorySize; // in pages
18331841
1842+ static const Index maxDepth = 250 ;
1843+
18341844 void trapIfGt (uint64_t lhs, uint64_t rhs, const char * msg) {
18351845 if (lhs > rhs) {
18361846 std::stringstream ss;
0 commit comments