@@ -44,22 +44,20 @@ template <class S> S modWorkaround(S const& _a, S const& _b)
4444 return (S)(bigint (_a) % bigint (_b));
4545}
4646
47- // / @returns a list of simplification rules given certain match placeholders.
48- // / A, B and C should represent constants, X and Y arbitrary expressions.
49- // / The simplifications should neven change the order of evaluation of
50- // / arbitrary operations.
47+ // simplificationRuleList below was split up into parts to prevent
48+ // stack overflows in the JavaScript optimizer for emscripten builds
49+ // that affected certain browser versions.
5150template <class Pattern >
52- std::vector<SimplificationRule<Pattern>> simplificationRuleList (
51+ std::vector<SimplificationRule<Pattern>> simplificationRuleListPart1 (
5352 Pattern A,
5453 Pattern B,
5554 Pattern C,
56- Pattern X ,
57- Pattern Y
55+ Pattern,
56+ Pattern
5857)
5958{
60- std::vector<SimplificationRule<Pattern>> rules;
61- rules += std::vector<SimplificationRule<Pattern>>{
62- // arithmetics on constants
59+ return std::vector<SimplificationRule<Pattern>> {
60+ // arithmetic on constants
6361 {{Instruction::ADD, {A, B}}, [=]{ return A.d () + B.d (); }, false },
6462 {{Instruction::MUL, {A, B}}, [=]{ return A.d () * B.d (); }, false },
6563 {{Instruction::SUB, {A, B}}, [=]{ return A.d () - B.d (); }, false },
@@ -98,8 +96,20 @@ std::vector<SimplificationRule<Pattern>> simplificationRuleList(
9896 if (A.d () > 255 )
9997 return u256 (0 );
10098 return B.d () >> unsigned (A.d ());
101- }, false },
99+ }, false }
100+ };
101+ }
102102
103+ template <class Pattern >
104+ std::vector<SimplificationRule<Pattern>> simplificationRuleListPart2 (
105+ Pattern,
106+ Pattern,
107+ Pattern,
108+ Pattern X,
109+ Pattern
110+ )
111+ {
112+ return std::vector<SimplificationRule<Pattern>> {
103113 // invariants involving known constants
104114 {{Instruction::ADD, {X, 0 }}, [=]{ return X; }, false },
105115 {{Instruction::ADD, {0 , X}}, [=]{ return X; }, false },
@@ -129,8 +139,20 @@ std::vector<SimplificationRule<Pattern>> simplificationRuleList(
129139 {{Instruction::MOD, {X, 0 }}, [=]{ return u256 (0 ); }, true },
130140 {{Instruction::MOD, {0 , X}}, [=]{ return u256 (0 ); }, true },
131141 {{Instruction::EQ, {X, 0 }}, [=]() -> Pattern { return {Instruction::ISZERO, {X}}; }, false },
132- {{Instruction::EQ, {0 , X}}, [=]() -> Pattern { return {Instruction::ISZERO, {X}}; }, false },
142+ {{Instruction::EQ, {0 , X}}, [=]() -> Pattern { return {Instruction::ISZERO, {X}}; }, false }
143+ };
144+ }
133145
146+ template <class Pattern >
147+ std::vector<SimplificationRule<Pattern>> simplificationRuleListPart3 (
148+ Pattern,
149+ Pattern,
150+ Pattern,
151+ Pattern X,
152+ Pattern
153+ )
154+ {
155+ return std::vector<SimplificationRule<Pattern>> {
134156 // operations involving an expression and itself
135157 {{Instruction::AND, {X, X}}, [=]{ return X; }, true },
136158 {{Instruction::OR, {X, X}}, [=]{ return X; }, true },
@@ -141,8 +163,20 @@ std::vector<SimplificationRule<Pattern>> simplificationRuleList(
141163 {{Instruction::SLT, {X, X}}, [=]{ return u256 (0 ); }, true },
142164 {{Instruction::GT, {X, X}}, [=]{ return u256 (0 ); }, true },
143165 {{Instruction::SGT, {X, X}}, [=]{ return u256 (0 ); }, true },
144- {{Instruction::MOD, {X, X}}, [=]{ return u256 (0 ); }, true },
166+ {{Instruction::MOD, {X, X}}, [=]{ return u256 (0 ); }, true }
167+ };
168+ }
145169
170+ template <class Pattern >
171+ std::vector<SimplificationRule<Pattern>> simplificationRuleListPart4 (
172+ Pattern,
173+ Pattern,
174+ Pattern,
175+ Pattern X,
176+ Pattern Y
177+ )
178+ {
179+ return std::vector<SimplificationRule<Pattern>> {
146180 // logical instruction combinations
147181 {{Instruction::NOT, {{Instruction::NOT, {X}}}}, [=]{ return X; }, false },
148182 {{Instruction::XOR, {X, {Instruction::XOR, {X, Y}}}}, [=]{ return Y; }, true },
@@ -162,6 +196,19 @@ std::vector<SimplificationRule<Pattern>> simplificationRuleList(
162196 {{Instruction::OR, {X, {Instruction::NOT, {X}}}}, [=]{ return ~u256 (0 ); }, true },
163197 {{Instruction::OR, {{Instruction::NOT, {X}}, X}}, [=]{ return ~u256 (0 ); }, true },
164198 };
199+ }
200+
201+
202+ template <class Pattern >
203+ std::vector<SimplificationRule<Pattern>> simplificationRuleListPart5 (
204+ Pattern,
205+ Pattern,
206+ Pattern,
207+ Pattern X,
208+ Pattern
209+ )
210+ {
211+ std::vector<SimplificationRule<Pattern>> rules;
165212
166213 // Replace MOD X, <power-of-two> with AND X, <power-of-two> - 1
167214 for (size_t i = 0 ; i < 256 ; ++i)
@@ -193,7 +240,19 @@ std::vector<SimplificationRule<Pattern>> simplificationRuleList(
193240 false
194241 });
195242 }
243+ return rules;
244+ }
196245
246+ template <class Pattern >
247+ std::vector<SimplificationRule<Pattern>> simplificationRuleListPart6 (
248+ Pattern,
249+ Pattern,
250+ Pattern,
251+ Pattern X,
252+ Pattern Y
253+ )
254+ {
255+ std::vector<SimplificationRule<Pattern>> rules;
197256 // Double negation of opcodes with boolean result
198257 for (auto const & op: std::vector<Instruction>{
199258 Instruction::EQ,
@@ -220,6 +279,19 @@ std::vector<SimplificationRule<Pattern>> simplificationRuleList(
220279 false
221280 });
222281
282+ return rules;
283+ }
284+
285+ template <class Pattern >
286+ std::vector<SimplificationRule<Pattern>> simplificationRuleListPart7 (
287+ Pattern A,
288+ Pattern B,
289+ Pattern,
290+ Pattern X,
291+ Pattern Y
292+ )
293+ {
294+ std::vector<SimplificationRule<Pattern>> rules;
223295 // Associative operations
224296 for (auto const & opFun: std::vector<std::pair<Instruction,std::function<u256 (u256 const &,u256 const &)>>>{
225297 {Instruction::ADD, std::plus<u256>()},
@@ -259,6 +331,19 @@ std::vector<SimplificationRule<Pattern>> simplificationRuleList(
259331 }};
260332 }
261333 }
334+ return rules;
335+ }
336+
337+ template <class Pattern >
338+ std::vector<SimplificationRule<Pattern>> simplificationRuleListPart8 (
339+ Pattern A,
340+ Pattern,
341+ Pattern,
342+ Pattern X,
343+ Pattern Y
344+ )
345+ {
346+ std::vector<SimplificationRule<Pattern>> rules;
262347
263348 // move constants across subtractions
264349 rules += std::vector<SimplificationRule<Pattern>>{
@@ -292,5 +377,30 @@ std::vector<SimplificationRule<Pattern>> simplificationRuleList(
292377 return rules;
293378}
294379
380+ // / @returns a list of simplification rules given certain match placeholders.
381+ // / A, B and C should represent constants, X and Y arbitrary expressions.
382+ // / The simplifications should never change the order of evaluation of
383+ // / arbitrary operations.
384+ template <class Pattern >
385+ std::vector<SimplificationRule<Pattern>> simplificationRuleList (
386+ Pattern A,
387+ Pattern B,
388+ Pattern C,
389+ Pattern X,
390+ Pattern Y
391+ )
392+ {
393+ std::vector<SimplificationRule<Pattern>> rules;
394+ rules += simplificationRuleListPart1 (A, B, C, X, Y);
395+ rules += simplificationRuleListPart2 (A, B, C, X, Y);
396+ rules += simplificationRuleListPart3 (A, B, C, X, Y);
397+ rules += simplificationRuleListPart4 (A, B, C, X, Y);
398+ rules += simplificationRuleListPart5 (A, B, C, X, Y);
399+ rules += simplificationRuleListPart6 (A, B, C, X, Y);
400+ rules += simplificationRuleListPart7 (A, B, C, X, Y);
401+ rules += simplificationRuleListPart8 (A, B, C, X, Y);
402+ return rules;
403+ }
404+
295405}
296406}
0 commit comments