Skip to content

Commit d0e8f4d

Browse files
ajtownssipa
authored andcommitted
[refactor] interpreter: define interface for vfExec
Includes comments added by Pieter Wuille.
1 parent 89fb241 commit d0e8f4d

File tree

1 file changed

+27
-3
lines changed

1 file changed

+27
-3
lines changed

src/script/interpreter.cpp

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,30 @@ int FindAndDelete(CScript& script, const CScript& b)
278278
return nFound;
279279
}
280280

281+
namespace {
282+
/** A data type to abstract out the condition stack during script execution.
283+
*
284+
* Conceptually it acts like a vector of booleans, one for each level of nested
285+
* IF/THEN/ELSE, indicating whether we're in the active or inactive branch of
286+
* each.
287+
*
288+
* The elements on the stack cannot be observed individually; we only need to
289+
* expose whether the stack is empty and whether or not any false values are
290+
* present at all. To implement OP_ELSE, a toggle_top modifier is added, which
291+
* flips the last value without returning it.
292+
*/
293+
class ConditionStack {
294+
private:
295+
std::vector<bool> m_flags;
296+
public:
297+
bool empty() { return m_flags.empty(); }
298+
bool all_true() { return !std::count(m_flags.begin(), m_flags.end(), false); }
299+
void push_back(bool f) { m_flags.push_back(f); }
300+
void pop_back() { m_flags.pop_back(); }
301+
void toggle_top() { m_flags.back() = !m_flags.back(); }
302+
};
303+
}
304+
281305
bool EvalScript(std::vector<std::vector<unsigned char> >& stack, const CScript& script, unsigned int flags, const BaseSignatureChecker& checker, SigVersion sigversion, ScriptError* serror)
282306
{
283307
static const CScriptNum bnZero(0);
@@ -293,7 +317,7 @@ bool EvalScript(std::vector<std::vector<unsigned char> >& stack, const CScript&
293317
CScript::const_iterator pbegincodehash = script.begin();
294318
opcodetype opcode;
295319
valtype vchPushValue;
296-
std::vector<bool> vfExec;
320+
ConditionStack vfExec;
297321
std::vector<valtype> altstack;
298322
set_error(serror, SCRIPT_ERR_UNKNOWN_ERROR);
299323
if (script.size() > MAX_SCRIPT_SIZE)
@@ -305,7 +329,7 @@ bool EvalScript(std::vector<std::vector<unsigned char> >& stack, const CScript&
305329
{
306330
while (pc < pend)
307331
{
308-
bool fExec = !count(vfExec.begin(), vfExec.end(), false);
332+
bool fExec = vfExec.all_true();
309333

310334
//
311335
// Read instruction
@@ -494,7 +518,7 @@ bool EvalScript(std::vector<std::vector<unsigned char> >& stack, const CScript&
494518
{
495519
if (vfExec.empty())
496520
return set_error(serror, SCRIPT_ERR_UNBALANCED_CONDITIONAL);
497-
vfExec.back() = !vfExec.back();
521+
vfExec.toggle_top();
498522
}
499523
break;
500524

0 commit comments

Comments
 (0)