Changeset View
Changeset View
Standalone View
Standalone View
src/script/interpreter.cpp
Show First 20 Lines • Show All 331 Lines • ▼ Show 20 Lines | try { | ||||
// Note how OP_RESERVED does not count towards the opcode limit. | // Note how OP_RESERVED does not count towards the opcode limit. | ||||
if (opcode > OP_16 && ++nOpCount > MAX_OPS_PER_SCRIPT) { | if (opcode > OP_16 && ++nOpCount > MAX_OPS_PER_SCRIPT) { | ||||
return set_error(serror, SCRIPT_ERR_OP_COUNT); | return set_error(serror, SCRIPT_ERR_OP_COUNT); | ||||
} | } | ||||
if (opcode == OP_CAT || opcode == OP_SUBSTR || opcode == OP_LEFT || | if (opcode == OP_CAT || opcode == OP_SUBSTR || opcode == OP_LEFT || | ||||
opcode == OP_RIGHT || opcode == OP_INVERT || opcode == OP_2MUL || | opcode == OP_RIGHT || opcode == OP_INVERT || opcode == OP_2MUL || | ||||
opcode == OP_2DIV || opcode == OP_MUL || opcode == OP_DIV || | opcode == OP_2DIV || opcode == OP_MUL || opcode == OP_MOD || | ||||
opcode == OP_MOD || opcode == OP_LSHIFT || opcode == OP_RSHIFT) { | opcode == OP_LSHIFT || opcode == OP_RSHIFT) { | ||||
// Disabled opcodes. | // Disabled opcodes. | ||||
return set_error(serror, SCRIPT_ERR_DISABLED_OPCODE); | return set_error(serror, SCRIPT_ERR_DISABLED_OPCODE); | ||||
} | } | ||||
if (fExec && 0 <= opcode && opcode <= OP_PUSHDATA4) { | if (fExec && 0 <= opcode && opcode <= OP_PUSHDATA4) { | ||||
if (fRequireMinimal && | if (fRequireMinimal && | ||||
!CheckMinimalPush(vchPushValue, opcode)) { | !CheckMinimalPush(vchPushValue, opcode)) { | ||||
return set_error(serror, SCRIPT_ERR_MINIMALDATA); | return set_error(serror, SCRIPT_ERR_MINIMALDATA); | ||||
▲ Show 20 Lines • Show All 538 Lines • ▼ Show 20 Lines | try { | ||||
break; | break; | ||||
} | } | ||||
popstack(stack); | popstack(stack); | ||||
stack.push_back(bn.getvch()); | stack.push_back(bn.getvch()); | ||||
} break; | } break; | ||||
case OP_ADD: | case OP_ADD: | ||||
case OP_SUB: | case OP_SUB: | ||||
case OP_DIV: | |||||
case OP_BOOLAND: | case OP_BOOLAND: | ||||
case OP_BOOLOR: | case OP_BOOLOR: | ||||
case OP_NUMEQUAL: | case OP_NUMEQUAL: | ||||
case OP_NUMEQUALVERIFY: | case OP_NUMEQUALVERIFY: | ||||
case OP_NUMNOTEQUAL: | case OP_NUMNOTEQUAL: | ||||
case OP_LESSTHAN: | case OP_LESSTHAN: | ||||
case OP_GREATERTHAN: | case OP_GREATERTHAN: | ||||
case OP_LESSTHANOREQUAL: | case OP_LESSTHANOREQUAL: | ||||
case OP_GREATERTHANOREQUAL: | case OP_GREATERTHANOREQUAL: | ||||
case OP_MIN: | case OP_MIN: | ||||
case OP_MAX: { | case OP_MAX: { | ||||
// (x1 x2 -- out) | // (x1 x2 -- out) | ||||
if (stack.size() < 2) { | if (stack.size() < 2) { | ||||
return set_error( | return set_error( | ||||
serror, SCRIPT_ERR_INVALID_STACK_OPERATION); | serror, SCRIPT_ERR_INVALID_STACK_OPERATION); | ||||
} | } | ||||
// first two inputs must be minimally encoded numbers | |||||
CScriptNum bn1(stacktop(-2), fRequireMinimal); | CScriptNum bn1(stacktop(-2), fRequireMinimal); | ||||
CScriptNum bn2(stacktop(-1), fRequireMinimal); | CScriptNum bn2(stacktop(-1), fRequireMinimal); | ||||
CScriptNum bn(0); | CScriptNum bn(0); | ||||
switch (opcode) { | switch (opcode) { | ||||
case OP_ADD: | case OP_ADD: | ||||
bn = bn1 + bn2; | bn = bn1 + bn2; | ||||
break; | break; | ||||
case OP_SUB: | case OP_SUB: | ||||
bn = bn1 - bn2; | bn = bn1 - bn2; | ||||
break; | break; | ||||
case OP_DIV: | |||||
// 2nd operand must not be 0 | |||||
if (bn2 == 0) { | |||||
return set_error( | |||||
serror, SCRIPT_ERR_DIV_BY_ZERO); | |||||
} | |||||
bn = bn1 / bn2; | |||||
break; | |||||
case OP_BOOLAND: | case OP_BOOLAND: | ||||
bn = (bn1 != bnZero && bn2 != bnZero); | bn = (bn1 != bnZero && bn2 != bnZero); | ||||
break; | break; | ||||
case OP_BOOLOR: | case OP_BOOLOR: | ||||
bn = (bn1 != bnZero || bn2 != bnZero); | bn = (bn1 != bnZero || bn2 != bnZero); | ||||
break; | break; | ||||
case OP_NUMEQUAL: | case OP_NUMEQUAL: | ||||
bn = (bn1 == bn2); | bn = (bn1 == bn2); | ||||
▲ Show 20 Lines • Show All 730 Lines • Show Last 20 Lines |