diff --git a/libevmasm/Assembly.h b/libevmasm/Assembly.h index 592119f17..ee97e9a92 100644 --- a/libevmasm/Assembly.h +++ b/libevmasm/Assembly.h @@ -83,10 +83,10 @@ public: append(AssemblyItem(std::move(_data), _arguments, _returnVariables)); } - AssemblyItem appendJump() { auto ret = append(newPushTag()); append(Instruction::JUMP); return ret; } - AssemblyItem appendJumpI() { auto ret = append(newPushTag()); append(Instruction::JUMPI); return ret; } - AssemblyItem appendJump(AssemblyItem const& _tag) { auto ret = append(_tag.pushTag()); append(Instruction::JUMP); return ret; } - AssemblyItem appendJumpI(AssemblyItem const& _tag) { auto ret = append(_tag.pushTag()); append(Instruction::JUMPI); return ret; } + AssemblyItem appendJump() { auto ret = append(newPushTag()); append(InternalInstruction::JUMP); return ret; } + AssemblyItem appendJumpI() { auto ret = append(newPushTag()); append(InternalInstruction::JUMPI); return ret; } + AssemblyItem appendJump(AssemblyItem const& _tag) { auto ret = append(_tag.pushTag()); append(InternalInstruction::JUMP); return ret; } + AssemblyItem appendJumpI(AssemblyItem const& _tag) { auto ret = append(_tag.pushTag()); append(InternalInstruction::JUMPI); return ret; } /// Adds a subroutine to the code (in the data section) and pushes its size (via a tag) /// on the stack. @returns the pushsub assembly item. diff --git a/libevmasm/AssemblyItem.cpp b/libevmasm/AssemblyItem.cpp index a36e0ddb1..c6aa026fa 100644 --- a/libevmasm/AssemblyItem.cpp +++ b/libevmasm/AssemblyItem.cpp @@ -329,7 +329,7 @@ ostream& solidity::evmasm::operator<<(ostream& _out, AssemblyItem const& _item) { case Operation: _out << " " << instructionInfo(_item.instruction()).name; - if (_item.instruction() == Instruction::JUMP || _item.instruction() == Instruction::JUMPI) + if (_item.instruction() == InternalInstruction::JUMP || _item.instruction() == InternalInstruction::JUMPI) _out << "\t" << _item.getJumpTypeAsString(); break; case Push: diff --git a/libevmasm/AssemblyItem.h b/libevmasm/AssemblyItem.h index 4aef82d8b..83819575a 100644 --- a/libevmasm/AssemblyItem.h +++ b/libevmasm/AssemblyItem.h @@ -66,7 +66,7 @@ public: AssemblyItem(u256 _push, langutil::SourceLocation _location = langutil::SourceLocation()): AssemblyItem(Push, std::move(_push), std::move(_location)) { } - AssemblyItem(Instruction _i, langutil::SourceLocation _location = langutil::SourceLocation()): + AssemblyItem(InternalInstruction _i, langutil::SourceLocation _location = langutil::SourceLocation()): m_type(Operation), m_instruction(_i), m_location(std::move(_location)) @@ -76,7 +76,7 @@ public: m_location(std::move(_location)) { if (m_type == Operation) - m_instruction = Instruction(uint8_t(_data)); + m_instruction = InternalInstruction(uint8_t(_data)); else m_data = std::make_shared(std::move(_data)); } @@ -116,7 +116,7 @@ public: bytes const& verbatimData() const { assertThrow(m_type == VerbatimBytecode, util::Exception, ""); return std::get<2>(*m_verbatimBytecode); } /// @returns the instruction of this item (only valid if type() == Operation) - Instruction instruction() const { assertThrow(m_type == Operation, util::Exception, ""); return m_instruction; } + InternalInstruction instruction() const { assertThrow(m_type == Operation, util::Exception, ""); return m_instruction; } /// @returns true if the type and data of the items are equal. bool operator==(AssemblyItem const& _other) const @@ -145,11 +145,11 @@ public: } /// Shortcut that avoids constructing an AssemblyItem just to perform the comparison. - bool operator==(Instruction _instr) const + bool operator==(InternalInstruction _instr) const { return type() == Operation && instruction() == _instr; } - bool operator!=(Instruction _instr) const { return !operator==(_instr); } + bool operator!=(InternalInstruction _instr) const { return !operator==(_instr); } static std::string computeSourceMapping( AssemblyItems const& _items, @@ -189,7 +189,7 @@ private: size_t opcodeCount() const noexcept; AssemblyItemType m_type; - Instruction m_instruction; ///< Only valid if m_type == Operation + InternalInstruction m_instruction; ///< Only valid if m_type == Operation std::shared_ptr m_data; ///< Only valid if m_type != Operation /// If m_type == VerbatimBytecode, this holds number of arguments, number of /// return variables and verbatim bytecode. diff --git a/libevmasm/BlockDeduplicator.cpp b/libevmasm/BlockDeduplicator.cpp index 5f9fa768f..e684b7f32 100644 --- a/libevmasm/BlockDeduplicator.cpp +++ b/libevmasm/BlockDeduplicator.cpp @@ -132,7 +132,7 @@ BlockDeduplicator::BlockIterator& BlockDeduplicator::BlockIterator::operator++() { if (it == end) return *this; - if (SemanticInformation::altersControlFlow(*it) && *it != AssemblyItem{Instruction::JUMPI}) + if (SemanticInformation::altersControlFlow(*it) && *it != AssemblyItem{InternalInstruction::JUMPI}) it = end; else { diff --git a/libevmasm/CommonSubexpressionEliminator.cpp b/libevmasm/CommonSubexpressionEliminator.cpp index 19b275cb6..4cd1bd400 100644 --- a/libevmasm/CommonSubexpressionEliminator.cpp +++ b/libevmasm/CommonSubexpressionEliminator.cpp @@ -88,36 +88,36 @@ void CommonSubexpressionEliminator::optimizeBreakingItem() ExpressionClasses& classes = m_state.expressionClasses(); SourceLocation const& itemLocation = m_breakingItem->location(); - if (*m_breakingItem == AssemblyItem(Instruction::JUMPI)) + if (*m_breakingItem == AssemblyItem(InternalInstruction::JUMPI)) { AssemblyItem::JumpType jumpType = m_breakingItem->getJumpType(); Id condition = m_state.stackElement(m_state.stackHeight() - 1, itemLocation); if (classes.knownNonZero(condition)) { - feedItem(AssemblyItem(Instruction::SWAP1, itemLocation), true); - feedItem(AssemblyItem(Instruction::POP, itemLocation), true); + feedItem(AssemblyItem(InternalInstruction::SWAP1, itemLocation), true); + feedItem(AssemblyItem(InternalInstruction::POP, itemLocation), true); - AssemblyItem item(Instruction::JUMP, itemLocation); + AssemblyItem item(InternalInstruction::JUMP, itemLocation); item.setJumpType(jumpType); m_breakingItem = classes.storeItem(item); } else if (classes.knownZero(condition)) { - AssemblyItem it(Instruction::POP, itemLocation); + AssemblyItem it(InternalInstruction::POP, itemLocation); feedItem(it, true); feedItem(it, true); m_breakingItem = nullptr; } } - else if (*m_breakingItem == AssemblyItem(Instruction::RETURN)) + else if (*m_breakingItem == AssemblyItem(InternalInstruction::RETURN)) { Id size = m_state.stackElement(m_state.stackHeight() - 1, itemLocation); if (classes.knownZero(size)) { - feedItem(AssemblyItem(Instruction::POP, itemLocation), true); - feedItem(AssemblyItem(Instruction::POP, itemLocation), true); - AssemblyItem item(Instruction::STOP, itemLocation); + feedItem(AssemblyItem(InternalInstruction::POP, itemLocation), true); + feedItem(AssemblyItem(InternalInstruction::POP, itemLocation), true); + AssemblyItem item(InternalInstruction::STOP, itemLocation); m_breakingItem = classes.storeItem(item); } } @@ -233,15 +233,15 @@ void CSECodeGenerator::addDependencies(Id _c) m_neededBy.insert(make_pair(argument, _c)); } if (expr.item && expr.item->type() == Operation && ( - expr.item->instruction() == Instruction::SLOAD || - expr.item->instruction() == Instruction::MLOAD || - expr.item->instruction() == Instruction::KECCAK256 + expr.item->instruction() == InternalInstruction::SLOAD || + expr.item->instruction() == InternalInstruction::MLOAD || + expr.item->instruction() == InternalInstruction::KECCAK256 )) { // this loads an unknown value from storage or memory and thus, in addition to its // arguments, depends on all store operations to addresses where we do not know that // they are different that occur before this load - StoreOperation::Target target = expr.item->instruction() == Instruction::SLOAD ? + StoreOperation::Target target = expr.item->instruction() == InternalInstruction::SLOAD ? StoreOperation::Storage : StoreOperation::Memory; Id slotToLoadFrom = expr.arguments.at(0); for (auto const& p: m_storeOperations) @@ -255,16 +255,16 @@ void CSECodeGenerator::addDependencies(Id _c) bool knownToBeIndependent = false; switch (expr.item->instruction()) { - case Instruction::SLOAD: + case InternalInstruction::SLOAD: knownToBeIndependent = m_expressionClasses.knownToBeDifferent(slot, slotToLoadFrom); break; - case Instruction::MLOAD: + case InternalInstruction::MLOAD: knownToBeIndependent = m_expressionClasses.knownToBeDifferentBy32(slot, slotToLoadFrom); break; - case Instruction::KECCAK256: + case InternalInstruction::KECCAK256: { Id length = expr.arguments.at(1); - AssemblyItem offsetInstr(Instruction::SUB, expr.item->location()); + AssemblyItem offsetInstr(InternalInstruction::SUB, expr.item->location()); Id offsetToStart = m_expressionClasses.find(offsetInstr, {slot, slotToLoadFrom}); u256 const* o = m_expressionClasses.knownConstant(offsetToStart); u256 const* l = m_expressionClasses.knownConstant(length); @@ -397,7 +397,7 @@ void CSECodeGenerator::generateClassElement(Id _c, bool _allowSequenced) while (SemanticInformation::isCommutativeOperation(*expr.item) && !m_generatedItems.empty() && - m_generatedItems.back() == AssemblyItem(Instruction::SWAP1)) + m_generatedItems.back() == AssemblyItem(InternalInstruction::SWAP1)) // this will not append a swap but remove the one that is already there appendOrRemoveSwap(m_stackHeight - 1, itemLocation); for (size_t i = 0; i < arguments.size(); ++i) @@ -464,7 +464,7 @@ bool CSECodeGenerator::removeStackTopIfPossible() return false; m_classPositions[m_stack[m_stackHeight]].erase(m_stackHeight); m_stack.erase(m_stackHeight); - appendItem(AssemblyItem(Instruction::POP)); + appendItem(AssemblyItem(InternalInstruction::POP)); return true; } diff --git a/libevmasm/ConstantOptimiser.cpp b/libevmasm/ConstantOptimiser.cpp index 37ac4c18b..346e125a3 100644 --- a/libevmasm/ConstantOptimiser.cpp +++ b/libevmasm/ConstantOptimiser.cpp @@ -84,10 +84,10 @@ bigint ConstantOptimisationMethod::simpleRunGas(AssemblyItems const& _items) bigint gas = 0; for (AssemblyItem const& item: _items) if (item.type() == Push) - gas += GasMeter::runGas(Instruction::PUSH1); + gas += GasMeter::runGas(InternalInstruction::PUSH1); else if (item.type() == Operation) { - if (item.instruction() == Instruction::EXP) + if (item.instruction() == InternalInstruction::EXP) gas += GasCosts::expGas; else gas += GasMeter::runGas(item.instruction()); @@ -131,7 +131,7 @@ void ConstantOptimisationMethod::replaceConstants( bigint LiteralMethod::gasNeeded() const { return combineGas( - simpleRunGas({Instruction::PUSH1}), + simpleRunGas({InternalInstruction::PUSH1}), // PUSHX plus data (m_params.isCreation ? GasCosts::txDataNonZeroGas(m_params.evmVersion) : GasCosts::createDataGas) + dataGas(toCompactBigEndian(m_value, 1)), 0 @@ -167,22 +167,22 @@ AssemblyItems const& CodeCopyMethod::copyRoutine() // back up memory // mload(0) - Instruction::DUP1, - Instruction::MLOAD, + InternalInstruction::DUP1, + InternalInstruction::MLOAD, // codecopy(0, , 32) u256(32), AssemblyItem(PushData, u256(1) << 16), // replaced above in actualCopyRoutine[4] - Instruction::DUP4, - Instruction::CODECOPY, + InternalInstruction::DUP4, + InternalInstruction::CODECOPY, // mload(0) - Instruction::DUP2, - Instruction::MLOAD, + InternalInstruction::DUP2, + InternalInstruction::MLOAD, // restore original memory - Instruction::SWAP2, - Instruction::MSTORE + InternalInstruction::SWAP2, + InternalInstruction::MSTORE }; return copyRoutine; } @@ -194,7 +194,7 @@ AssemblyItems ComputeMethod::findRepresentation(u256 const& _value) return AssemblyItems{_value}; else if (numberEncodingSize(~_value) < numberEncodingSize(_value)) // Negated is shorter to represent - return findRepresentation(~_value) + AssemblyItems{Instruction::NOT}; + return findRepresentation(~_value) + AssemblyItems{InternalInstruction::NOT}; else { // Decompose value into a * 2**k + b where abs(b) << 2**k @@ -226,18 +226,18 @@ AssemblyItems ComputeMethod::findRepresentation(u256 const& _value) if (m_params.evmVersion.hasBitwiseShifting()) { newRoutine += findRepresentation(upperPart); - newRoutine += AssemblyItems{u256(bits), Instruction::SHL}; + newRoutine += AssemblyItems{u256(bits), InternalInstruction::SHL}; } else { - newRoutine += AssemblyItems{u256(bits), u256(2), Instruction::EXP}; + newRoutine += AssemblyItems{u256(bits), u256(2), InternalInstruction::EXP}; if (upperPart != 1) - newRoutine += findRepresentation(upperPart) + AssemblyItems{Instruction::MUL}; + newRoutine += findRepresentation(upperPart) + AssemblyItems{InternalInstruction::MUL}; } if (lowerPart > 0) - newRoutine += AssemblyItems{Instruction::ADD}; + newRoutine += AssemblyItems{InternalInstruction::ADD}; else if (lowerPart < 0) - newRoutine.push_back(Instruction::SUB); + newRoutine.push_back(InternalInstruction::SUB); if (m_maxSteps > 0) m_maxSteps--; @@ -267,24 +267,24 @@ bool ComputeMethod::checkRepresentation(u256 const& _value, AssemblyItems const& u256* sp = &stack.back(); switch (item.instruction()) { - case Instruction::MUL: + case InternalInstruction::MUL: sp[-1] = sp[0] * sp[-1]; break; - case Instruction::EXP: + case InternalInstruction::EXP: if (sp[-1] > 0xff) return false; sp[-1] = boost::multiprecision::pow(sp[0], unsigned(sp[-1])); break; - case Instruction::ADD: + case InternalInstruction::ADD: sp[-1] = sp[0] + sp[-1]; break; - case Instruction::SUB: + case InternalInstruction::SUB: sp[-1] = sp[0] - sp[-1]; break; - case Instruction::NOT: + case InternalInstruction::NOT: sp[0] = ~sp[0]; break; - case Instruction::SHL: + case InternalInstruction::SHL: assertThrow( m_params.evmVersion.hasBitwiseShifting(), OptimizerException, @@ -293,7 +293,7 @@ bool ComputeMethod::checkRepresentation(u256 const& _value, AssemblyItems const& assertThrow(sp[0] <= u256(255), OptimizerException, "Invalid shift generated."); sp[-1] = u256(bigint(sp[-1]) << unsigned(sp[0])); break; - case Instruction::SHR: + case InternalInstruction::SHR: assertThrow( m_params.evmVersion.hasBitwiseShifting(), OptimizerException, @@ -320,7 +320,7 @@ bool ComputeMethod::checkRepresentation(u256 const& _value, AssemblyItems const& bigint ComputeMethod::gasNeeded(AssemblyItems const& _routine) const { - auto numExps = static_cast(count(_routine.begin(), _routine.end(), Instruction::EXP)); + auto numExps = static_cast(count(_routine.begin(), _routine.end(), InternalInstruction::EXP)); return combineGas( simpleRunGas(_routine) + numExps * (GasCosts::expGas + GasCosts::expByteGas(m_params.evmVersion)), // Data gas for routine: Some bytes are zero, but we ignore them. diff --git a/libevmasm/ControlFlowGraph.cpp b/libevmasm/ControlFlowGraph.cpp index cb648f90f..cd432d6ea 100644 --- a/libevmasm/ControlFlowGraph.cpp +++ b/libevmasm/ControlFlowGraph.cpp @@ -92,9 +92,9 @@ void ControlFlowGraph::splitBlocks() if (SemanticInformation::altersControlFlow(item)) { m_blocks[id].end = static_cast(index + 1); - if (item == Instruction::JUMP) + if (item == InternalInstruction::JUMP) m_blocks[id].endType = BasicBlock::EndType::JUMP; - else if (item == Instruction::JUMPI) + else if (item == InternalInstruction::JUMPI) m_blocks[id].endType = BasicBlock::EndType::JUMPI; else m_blocks[id].endType = BasicBlock::EndType::STOP; diff --git a/libevmasm/ExpressionClasses.cpp b/libevmasm/ExpressionClasses.cpp index 8cd97b6a8..16c1e1dd0 100644 --- a/libevmasm/ExpressionClasses.cpp +++ b/libevmasm/ExpressionClasses.cpp @@ -148,13 +148,13 @@ ExpressionClasses::Id ExpressionClasses::newClass(SourceLocation const& _locatio bool ExpressionClasses::knownToBeDifferent(ExpressionClasses::Id _a, ExpressionClasses::Id _b) { // Try to simplify "_a - _b" and return true iff the value is a non-zero constant. - return knownNonZero(find(Instruction::SUB, {_a, _b})); + return knownNonZero(find(InternalInstruction::SUB, {_a, _b})); } bool ExpressionClasses::knownToBeDifferentBy32(ExpressionClasses::Id _a, ExpressionClasses::Id _b) { // Try to simplify "_a - _b" and return true iff the value is at least 32 away from zero. - u256 const* v = knownConstant(find(Instruction::SUB, {_a, _b})); + u256 const* v = knownConstant(find(InternalInstruction::SUB, {_a, _b})); // forbidden interval is ["-31", 31] return v && *v + 31 > u256(62); } @@ -166,7 +166,7 @@ bool ExpressionClasses::knownZero(Id _c) bool ExpressionClasses::knownNonZero(Id _c) { - return Pattern(u256(0)).matches(representative(find(Instruction::ISZERO, {_c})), *this); + return Pattern(u256(0)).matches(representative(find(InternalInstruction::ISZERO, {_c})), *this); } u256 const* ExpressionClasses::knownConstant(Id _c) diff --git a/libevmasm/GasMeter.cpp b/libevmasm/GasMeter.cpp index d49ee9891..6091c394e 100644 --- a/libevmasm/GasMeter.cpp +++ b/libevmasm/GasMeter.cpp @@ -52,17 +52,17 @@ GasMeter::GasConsumption GasMeter::estimateMax(AssemblyItem const& _item, bool _ case PushProgramSize: case PushLibraryAddress: case PushDeployTimeAddress: - gas = runGas(Instruction::PUSH1); + gas = runGas(InternalInstruction::PUSH1); break; case Tag: - gas = runGas(Instruction::JUMPDEST); + gas = runGas(InternalInstruction::JUMPDEST); break; case Operation: { ExpressionClasses& classes = m_state->expressionClasses(); switch (_item.instruction()) { - case Instruction::SSTORE: + case InternalInstruction::SSTORE: { ExpressionClasses::Id slot = m_state->relativeStackElement(0); ExpressionClasses::Id value = m_state->relativeStackElement(-1); @@ -75,57 +75,57 @@ GasMeter::GasConsumption GasMeter::estimateMax(AssemblyItem const& _item, bool _ gas = GasCosts::totalSstoreSetGas(m_evmVersion); break; } - case Instruction::SLOAD: + case InternalInstruction::SLOAD: gas = GasCosts::sloadGas(m_evmVersion); break; - case Instruction::RETURN: - case Instruction::REVERT: + case InternalInstruction::RETURN: + case InternalInstruction::REVERT: gas = runGas(_item.instruction()); gas += memoryGas(0, -1); break; - case Instruction::MLOAD: - case Instruction::MSTORE: + case InternalInstruction::MLOAD: + case InternalInstruction::MSTORE: gas = runGas(_item.instruction()); - gas += memoryGas(classes.find(Instruction::ADD, { + gas += memoryGas(classes.find(InternalInstruction::ADD, { m_state->relativeStackElement(0), classes.find(AssemblyItem(32)) })); break; - case Instruction::MSTORE8: + case InternalInstruction::MSTORE8: gas = runGas(_item.instruction()); - gas += memoryGas(classes.find(Instruction::ADD, { + gas += memoryGas(classes.find(InternalInstruction::ADD, { m_state->relativeStackElement(0), classes.find(AssemblyItem(1)) })); break; - case Instruction::KECCAK256: + case InternalInstruction::KECCAK256: gas = GasCosts::keccak256Gas; gas += memoryGas(0, -1); gas += wordGas(GasCosts::keccak256WordGas, m_state->relativeStackElement(-1)); break; - case Instruction::CALLDATACOPY: - case Instruction::CODECOPY: - case Instruction::RETURNDATACOPY: + case InternalInstruction::CALLDATACOPY: + case InternalInstruction::CODECOPY: + case InternalInstruction::RETURNDATACOPY: gas = runGas(_item.instruction()); gas += memoryGas(0, -2); gas += wordGas(GasCosts::copyGas, m_state->relativeStackElement(-2)); break; - case Instruction::EXTCODESIZE: + case InternalInstruction::EXTCODESIZE: gas = GasCosts::extCodeGas(m_evmVersion); break; - case Instruction::EXTCODEHASH: + case InternalInstruction::EXTCODEHASH: gas = GasCosts::balanceGas(m_evmVersion); break; - case Instruction::EXTCODECOPY: + case InternalInstruction::EXTCODECOPY: gas = GasCosts::extCodeGas(m_evmVersion); gas += memoryGas(-1, -3); gas += wordGas(GasCosts::copyGas, m_state->relativeStackElement(-3)); break; - case Instruction::LOG0: - case Instruction::LOG1: - case Instruction::LOG2: - case Instruction::LOG3: - case Instruction::LOG4: + case InternalInstruction::LOG0: + case InternalInstruction::LOG1: + case InternalInstruction::LOG2: + case InternalInstruction::LOG3: + case InternalInstruction::LOG4: { gas = GasCosts::logGas + GasCosts::logTopicGas * getLogNumber(_item.instruction()); gas += memoryGas(0, -1); @@ -135,10 +135,10 @@ GasMeter::GasConsumption GasMeter::estimateMax(AssemblyItem const& _item, bool _ gas = GasConsumption::infinite(); break; } - case Instruction::CALL: - case Instruction::CALLCODE: - case Instruction::DELEGATECALL: - case Instruction::STATICCALL: + case InternalInstruction::CALL: + case InternalInstruction::CALLCODE: + case InternalInstruction::DELEGATECALL: + case InternalInstruction::STATICCALL: { if (_includeExternalCosts) // We assume that we do not know the target contract and thus, the consumption is infinite. @@ -150,10 +150,10 @@ GasMeter::GasConsumption GasMeter::estimateMax(AssemblyItem const& _item, bool _ gas += (*value); else gas = GasConsumption::infinite(); - if (_item.instruction() == Instruction::CALL) + if (_item.instruction() == InternalInstruction::CALL) gas += GasCosts::callNewAccountGas; // We very rarely know whether the address exists. int valueSize = 1; - if (_item.instruction() == Instruction::DELEGATECALL || _item.instruction() == Instruction::STATICCALL) + if (_item.instruction() == InternalInstruction::DELEGATECALL || _item.instruction() == InternalInstruction::STATICCALL) valueSize = 0; else if (!classes.knownZero(m_state->relativeStackElement(-1 - valueSize))) gas += GasCosts::callValueTransferGas; @@ -162,12 +162,12 @@ GasMeter::GasConsumption GasMeter::estimateMax(AssemblyItem const& _item, bool _ } break; } - case Instruction::SELFDESTRUCT: + case InternalInstruction::SELFDESTRUCT: gas = GasCosts::selfdestructGas(m_evmVersion); gas += GasCosts::callNewAccountGas; // We very rarely know whether the address exists. break; - case Instruction::CREATE: - case Instruction::CREATE2: + case InternalInstruction::CREATE: + case InternalInstruction::CREATE2: if (_includeExternalCosts) // We assume that we do not know the target contract and thus, the consumption is infinite. gas = GasConsumption::infinite(); @@ -177,7 +177,7 @@ GasMeter::GasConsumption GasMeter::estimateMax(AssemblyItem const& _item, bool _ gas += memoryGas(-1, -2); } break; - case Instruction::EXP: + case InternalInstruction::EXP: gas = GasCosts::expGas; if (u256 const* value = classes.knownConstant(m_state->relativeStackElement(-1))) { @@ -191,14 +191,14 @@ GasMeter::GasConsumption GasMeter::estimateMax(AssemblyItem const& _item, bool _ else gas += GasCosts::expByteGas(m_evmVersion) * 32; break; - case Instruction::BALANCE: + case InternalInstruction::BALANCE: gas = GasCosts::balanceGas(m_evmVersion); break; - case Instruction::CHAINID: - gas = runGas(Instruction::CHAINID); + case InternalInstruction::CHAINID: + gas = runGas(InternalInstruction::CHAINID); break; - case Instruction::SELFBALANCE: - gas = runGas(Instruction::SELFBALANCE); + case InternalInstruction::SELFBALANCE: + gas = runGas(InternalInstruction::SELFBALANCE); break; default: gas = runGas(_item.instruction()); @@ -246,15 +246,15 @@ GasMeter::GasConsumption GasMeter::memoryGas(int _stackPosOffset, int _stackPosS if (classes.knownZero(m_state->relativeStackElement(_stackPosSize))) return GasConsumption(0); else - return memoryGas(classes.find(Instruction::ADD, { + return memoryGas(classes.find(InternalInstruction::ADD, { m_state->relativeStackElement(_stackPosOffset), m_state->relativeStackElement(_stackPosSize) })); } -unsigned GasMeter::runGas(Instruction _instruction) +unsigned GasMeter::runGas(InternalInstruction _instruction) { - if (_instruction == Instruction::JUMPDEST) + if (_instruction == InternalInstruction::JUMPDEST) return 1; switch (instructionInfo(_instruction).gasPriceTier) diff --git a/libevmasm/GasMeter.h b/libevmasm/GasMeter.h index 306fc0208..591c12214 100644 --- a/libevmasm/GasMeter.h +++ b/libevmasm/GasMeter.h @@ -221,7 +221,7 @@ public: /// @returns gas costs for simple instructions with constant gas costs (that do not /// change with EVM versions) - static unsigned runGas(Instruction _instruction); + static unsigned runGas(InternalInstruction _instruction); /// @returns the gas cost of the supplied data, depending whether it is in creation code, or not. /// In case of @a _inCreation, the data is only sent as a transaction and is not stored, whereas diff --git a/libevmasm/Inliner.cpp b/libevmasm/Inliner.cpp index d365e312a..51344b042 100644 --- a/libevmasm/Inliner.cpp +++ b/libevmasm/Inliner.cpp @@ -85,7 +85,7 @@ bool Inliner::isInlineCandidate(size_t _tag, ranges::span _i if (_items.back().type() != Operation) return false; if ( - _items.back() != Instruction::JUMP && + _items.back() != InternalInstruction::JUMP && !SemanticInformation::terminatesControlFlow(_items.back().instruction()) ) return false; @@ -150,13 +150,13 @@ bool Inliner::shouldInlineFullFunctionBody(size_t _tag, ranges::span Inliner::shouldInline(size_t _tag, AssemblyItem const& _jump, InlinableBlock const& _block) const { - assertThrow(_jump == Instruction::JUMP, OptimizerException, ""); + assertThrow(_jump == InternalInstruction::JUMP, OptimizerException, ""); AssemblyItem blockExit = _block.items.back(); if ( _jump.getJumpType() == AssemblyItem::JumpType::IntoFunction && - blockExit == Instruction::JUMP && + blockExit == InternalInstruction::JUMP && blockExit.getJumpType() == AssemblyItem::JumpType::OutOfFunction && shouldInlineFullFunctionBody(_tag, _block.items, _block.pushTagCount) ) @@ -223,7 +223,7 @@ optional Inliner::shouldInline(size_t _tag, AssemblyItem const& _j { static AssemblyItems const jumpPattern = { AssemblyItem{PushTag}, - AssemblyItem{Instruction::JUMP}, + AssemblyItem{InternalInstruction::JUMP}, }; if ( GasMeter::dataGas(codeSize(_block.items), m_isCreation, m_evmVersion) <= @@ -250,7 +250,7 @@ void Inliner::optimise() if (next(it) != m_items.end()) { AssemblyItem const& nextItem = *next(it); - if (item.type() == PushTag && nextItem == Instruction::JUMP) + if (item.type() == PushTag && nextItem == InternalInstruction::JUMP) { if (optional tag = getLocalTag(item)) if (auto* inlinableBlock = util::valueOrNullptr(inlinableBlocks, *tag)) diff --git a/libevmasm/KnownState.cpp b/libevmasm/KnownState.cpp index 1e886f7ab..007de97c4 100644 --- a/libevmasm/KnownState.cpp +++ b/libevmasm/KnownState.cpp @@ -97,8 +97,8 @@ KnownState::StoreOperation KnownState::feedItem(AssemblyItem const& _item, bool // Since AssignImmutable breaks blocks, it should be fine to only consider its changes to the stack, which // is the same as two POPs. // Note that the StoreOperation for POP is generic and _copyItem is ignored. - feedItem(AssemblyItem(Instruction::POP), _copyItem); - return feedItem(AssemblyItem(Instruction::POP), _copyItem); + feedItem(AssemblyItem(InternalInstruction::POP), _copyItem); + return feedItem(AssemblyItem(InternalInstruction::POP), _copyItem); } else if (_item.type() == VerbatimBytecode) { @@ -129,48 +129,48 @@ KnownState::StoreOperation KnownState::feedItem(AssemblyItem const& _item, bool } else { - Instruction instruction = _item.instruction(); + InternalInstruction instruction = _item.instruction(); InstructionInfo info = instructionInfo(instruction); if (SemanticInformation::isDupInstruction(_item)) setStackElement( m_stackHeight + 1, stackElement( - m_stackHeight - static_cast(instruction) + static_cast(Instruction::DUP1), + m_stackHeight - static_cast(instruction) + static_cast(InternalInstruction::DUP1), _item.location() ) ); else if (SemanticInformation::isSwapInstruction(_item)) swapStackElements( m_stackHeight, - m_stackHeight - 1 - static_cast(instruction) + static_cast(Instruction::SWAP1), + m_stackHeight - 1 - static_cast(instruction) + static_cast(InternalInstruction::SWAP1), _item.location() ); - else if (instruction != Instruction::POP) + else if (instruction != InternalInstruction::POP) { vector arguments(static_cast(info.args)); for (size_t i = 0; i < static_cast(info.args); ++i) arguments[i] = stackElement(m_stackHeight - static_cast(i), _item.location()); switch (_item.instruction()) { - case Instruction::SSTORE: + case InternalInstruction::SSTORE: op = storeInStorage(arguments[0], arguments[1], _item.location()); break; - case Instruction::SLOAD: + case InternalInstruction::SLOAD: setStackElement( m_stackHeight + static_cast(_item.deposit()), loadFromStorage(arguments[0], _item.location()) ); break; - case Instruction::MSTORE: + case InternalInstruction::MSTORE: op = storeInMemory(arguments[0], arguments[1], _item.location()); break; - case Instruction::MLOAD: + case InternalInstruction::MLOAD: setStackElement( m_stackHeight + static_cast(_item.deposit()), loadFromMemory(arguments[0], _item.location()) ); break; - case Instruction::KECCAK256: + case InternalInstruction::KECCAK256: setStackElement( m_stackHeight + static_cast(_item.deposit()), applyKeccak256(arguments.at(0), arguments.at(1), _item.location()) @@ -335,7 +335,7 @@ KnownState::StoreOperation KnownState::storeInStorage( storageContents.insert(storageItem); m_storageContent = std::move(storageContents); - AssemblyItem item(Instruction::SSTORE, _location); + AssemblyItem item(InternalInstruction::SSTORE, _location); Id id = m_expressionClasses->find(item, {_slot, _value}, true, m_sequenceNumber); StoreOperation operation{StoreOperation::Storage, _slot, m_sequenceNumber, id}; m_storageContent[_slot] = _value; @@ -350,7 +350,7 @@ ExpressionClasses::Id KnownState::loadFromStorage(Id _slot, SourceLocation const if (m_storageContent.count(_slot)) return m_storageContent.at(_slot); - AssemblyItem item(Instruction::SLOAD, _location); + AssemblyItem item(InternalInstruction::SLOAD, _location); return m_storageContent[_slot] = m_expressionClasses->find(item, {_slot}, true, m_sequenceNumber); } @@ -367,7 +367,7 @@ KnownState::StoreOperation KnownState::storeInMemory(Id _slot, Id _value, Source memoryContents.insert(memoryItem); m_memoryContent = std::move(memoryContents); - AssemblyItem item(Instruction::MSTORE, _location); + AssemblyItem item(InternalInstruction::MSTORE, _location); Id id = m_expressionClasses->find(item, {_slot, _value}, true, m_sequenceNumber); StoreOperation operation{StoreOperation::Memory, _slot, m_sequenceNumber, id}; m_memoryContent[_slot] = _value; @@ -381,7 +381,7 @@ ExpressionClasses::Id KnownState::loadFromMemory(Id _slot, SourceLocation const& if (m_memoryContent.count(_slot)) return m_memoryContent.at(_slot); - AssemblyItem item(Instruction::MLOAD, _location); + AssemblyItem item(InternalInstruction::MLOAD, _location); return m_memoryContent[_slot] = m_expressionClasses->find(item, {_slot}, true, m_sequenceNumber); } @@ -391,7 +391,7 @@ KnownState::Id KnownState::applyKeccak256( SourceLocation const& _location ) { - AssemblyItem keccak256Item(Instruction::KECCAK256, _location); + AssemblyItem keccak256Item(InternalInstruction::KECCAK256, _location); // Special logic if length is a short constant, otherwise we cannot tell. u256 const* l = m_expressionClasses->knownConstant(_length); // unknown or too large length @@ -402,7 +402,7 @@ KnownState::Id KnownState::applyKeccak256( for (unsigned i = 0; i < length; i += 32) { Id slot = m_expressionClasses->find( - AssemblyItem(Instruction::ADD, _location), + AssemblyItem(InternalInstruction::ADD, _location), {_start, m_expressionClasses->find(u256(i))} ); arguments.push_back(loadFromMemory(slot, _location)); diff --git a/libevmasm/PathGasMeter.cpp b/libevmasm/PathGasMeter.cpp index c165985cf..1a576fe8a 100644 --- a/libevmasm/PathGasMeter.cpp +++ b/libevmasm/PathGasMeter.cpp @@ -88,7 +88,7 @@ GasMeter::GasConsumption PathGasMeter::handleQueueItem() bool branchStops = false; jumpTags.clear(); AssemblyItem const& item = m_items.at(index); - if (item.type() == Tag || item == AssemblyItem(Instruction::JUMPDEST)) + if (item.type() == Tag || item == AssemblyItem(InternalInstruction::JUMPDEST)) { // Do not allow any backwards jump. This is quite restrictive but should work for // the simplest things. @@ -96,14 +96,14 @@ GasMeter::GasConsumption PathGasMeter::handleQueueItem() return GasMeter::GasConsumption::infinite(); path->visitedJumpdests.insert(index); } - else if (item == AssemblyItem(Instruction::JUMP)) + else if (item == AssemblyItem(InternalInstruction::JUMP)) { branchStops = true; jumpTags = state->tagsInExpression(state->relativeStackElement(0)); if (jumpTags.empty()) // unknown jump destination return GasMeter::GasConsumption::infinite(); } - else if (item == AssemblyItem(Instruction::JUMPI)) + else if (item == AssemblyItem(InternalInstruction::JUMPI)) { ExpressionClasses::Id condition = state->relativeStackElement(-1); if (classes.knownNonZero(condition) || !classes.knownZero(condition)) diff --git a/libevmasm/PeepholeOptimiser.cpp b/libevmasm/PeepholeOptimiser.cpp index 334903c92..859f8d474 100644 --- a/libevmasm/PeepholeOptimiser.cpp +++ b/libevmasm/PeepholeOptimiser.cpp @@ -87,7 +87,7 @@ struct PushPop: SimplePeepholeOptimizerMethod static bool applySimple(AssemblyItem const& _push, AssemblyItem const& _pop, std::back_insert_iterator) { auto t = _push.type(); - return _pop == Instruction::POP && ( + return _pop == InternalInstruction::POP && ( SemanticInformation::isDupInstruction(_push) || t == Push || t == PushTag || t == PushSub || t == PushSubSize || t == PushProgramSize || t == PushData || t == PushLibraryAddress @@ -103,13 +103,13 @@ struct OpPop: SimplePeepholeOptimizerMethod std::back_insert_iterator _out ) { - if (_pop == Instruction::POP && _op.type() == Operation) + if (_pop == InternalInstruction::POP && _op.type() == Operation) { - Instruction instr = _op.instruction(); + InternalInstruction instr = _op.instruction(); if (instructionInfo(instr).ret == 1 && !instructionInfo(instr).sideEffects) { for (int j = 0; j < instructionInfo(instr).args; j++) - *_out = {Instruction::POP, _op.location()}; + *_out = {InternalInstruction::POP, _op.location()}; return true; } } @@ -125,20 +125,20 @@ struct OpStop: SimplePeepholeOptimizerMethod std::back_insert_iterator _out ) { - if (_stop == Instruction::STOP) + if (_stop == InternalInstruction::STOP) { if (_op.type() == Operation) { - Instruction instr = _op.instruction(); + InternalInstruction instr = _op.instruction(); if (!instructionInfo(instr).sideEffects) { - *_out = {Instruction::STOP, _op.location()}; + *_out = {InternalInstruction::STOP, _op.location()}; return true; } } else if (_op.type() == Push) { - *_out = {Instruction::STOP, _op.location()}; + *_out = {InternalInstruction::STOP, _op.location()}; return true; } } @@ -157,7 +157,7 @@ struct OpReturnRevert: SimplePeepholeOptimizerMethod ) { if ( - (_returnRevert == Instruction::RETURN || _returnRevert == Instruction::REVERT) && + (_returnRevert == InternalInstruction::RETURN || _returnRevert == InternalInstruction::REVERT) && _push.type() == Push && (_pushOrDup.type() == Push || _pushOrDup == dupInstruction(1)) ) @@ -190,7 +190,7 @@ struct DoublePush: SimplePeepholeOptimizerMethod if (_push1.type() == Push && _push2.type() == Push && _push1.data() == _push2.data()) { *_out = _push1; - *_out = {Instruction::DUP1, _push2.location()}; + *_out = {InternalInstruction::DUP1, _push2.location()}; return true; } else @@ -204,7 +204,7 @@ struct CommutativeSwap: SimplePeepholeOptimizerMethod { // Remove SWAP1 if following instruction is commutative if ( - _swap == Instruction::SWAP1 && + _swap == InternalInstruction::SWAP1 && SemanticInformation::isCommutativeOperation(_op) ) { @@ -220,15 +220,15 @@ struct SwapComparison: SimplePeepholeOptimizerMethod { static bool applySimple(AssemblyItem const& _swap, AssemblyItem const& _op, std::back_insert_iterator _out) { - static map const swappableOps{ - { Instruction::LT, Instruction::GT }, - { Instruction::GT, Instruction::LT }, - { Instruction::SLT, Instruction::SGT }, - { Instruction::SGT, Instruction::SLT } + static map const swappableOps{ + { InternalInstruction::LT, InternalInstruction::GT }, + { InternalInstruction::GT, InternalInstruction::LT }, + { InternalInstruction::SLT, InternalInstruction::SGT }, + { InternalInstruction::SGT, InternalInstruction::SLT } }; if ( - _swap == Instruction::SWAP1 && + _swap == InternalInstruction::SWAP1 && _op.type() == Operation && swappableOps.count(_op.instruction()) ) @@ -276,10 +276,10 @@ struct IsZeroIsZeroJumpI: SimplePeepholeOptimizerMethod ) { if ( - _iszero1 == Instruction::ISZERO && - _iszero2 == Instruction::ISZERO && + _iszero1 == InternalInstruction::ISZERO && + _iszero2 == InternalInstruction::ISZERO && _pushTag.type() == PushTag && - _jumpi == Instruction::JUMPI + _jumpi == InternalInstruction::JUMPI ) { *_out = _pushTag; @@ -302,13 +302,13 @@ struct EqIsZeroJumpI: SimplePeepholeOptimizerMethod ) { if ( - _eq == Instruction::EQ && - _iszero == Instruction::ISZERO && + _eq == InternalInstruction::EQ && + _iszero == InternalInstruction::ISZERO && _pushTag.type() == PushTag && - _jumpi == Instruction::JUMPI + _jumpi == InternalInstruction::JUMPI ) { - *_out = AssemblyItem(Instruction::SUB, _eq.location()); + *_out = AssemblyItem(InternalInstruction::SUB, _eq.location()); *_out = _pushTag; *_out = _jumpi; return true; @@ -332,14 +332,14 @@ struct DoubleJump: SimplePeepholeOptimizerMethod { if ( _pushTag1.type() == PushTag && - _jumpi == Instruction::JUMPI && + _jumpi == InternalInstruction::JUMPI && _pushTag2.type() == PushTag && - _jump == Instruction::JUMP && + _jump == InternalInstruction::JUMP && _tag1.type() == Tag && _pushTag1.data() == _tag1.data() ) { - *_out = AssemblyItem(Instruction::ISZERO, _jumpi.location()); + *_out = AssemblyItem(InternalInstruction::ISZERO, _jumpi.location()); *_out = _pushTag2; *_out = _jumpi; *_out = _tag1; @@ -361,13 +361,13 @@ struct JumpToNext: SimplePeepholeOptimizerMethod { if ( _pushTag.type() == PushTag && - (_jump == Instruction::JUMP || _jump == Instruction::JUMPI) && + (_jump == InternalInstruction::JUMP || _jump == InternalInstruction::JUMPI) && _tag.type() == Tag && _pushTag.data() == _tag.data() ) { - if (_jump == Instruction::JUMPI) - *_out = AssemblyItem(Instruction::POP, _jump.location()); + if (_jump == InternalInstruction::JUMPI) + *_out = AssemblyItem(InternalInstruction::POP, _jump.location()); *_out = _tag; return true; } @@ -385,7 +385,7 @@ struct TagConjunctions: SimplePeepholeOptimizerMethod std::back_insert_iterator _out ) { - if (_and != Instruction::AND) + if (_and != InternalInstruction::AND) return false; if ( _pushTag.type() == PushTag && @@ -422,8 +422,8 @@ struct TruthyAnd: SimplePeepholeOptimizerMethod { return ( _push.type() == Push && _push.data() == 0 && - _not == Instruction::NOT && - _and == Instruction::AND + _not == InternalInstruction::NOT && + _and == InternalInstruction::AND ); } }; @@ -438,12 +438,12 @@ struct UnreachableCode if (it == end) return false; if ( - it[0] != Instruction::JUMP && - it[0] != Instruction::RETURN && - it[0] != Instruction::STOP && - it[0] != Instruction::INVALID && - it[0] != Instruction::SELFDESTRUCT && - it[0] != Instruction::REVERT + it[0] != InternalInstruction::JUMP && + it[0] != InternalInstruction::RETURN && + it[0] != InternalInstruction::STOP && + it[0] != InternalInstruction::INVALID && + it[0] != InternalInstruction::SELFDESTRUCT && + it[0] != InternalInstruction::REVERT ) return false; @@ -475,7 +475,7 @@ void applyMethods(OptimiserState& _state, Method, OtherMethods... _other) size_t numberOfPops(AssemblyItems const& _items) { - return static_cast(std::count(_items.begin(), _items.end(), Instruction::POP)); + return static_cast(std::count(_items.begin(), _items.end(), InternalInstruction::POP)); } } diff --git a/libevmasm/RuleList.h b/libevmasm/RuleList.h index 9b20d0f8b..40cc546f3 100644 --- a/libevmasm/RuleList.h +++ b/libevmasm/RuleList.h @@ -367,10 +367,10 @@ std::vector> simplificationRuleListPart5( }); for (auto instr: { - Instruction::ADDRESS, - Instruction::CALLER, - Instruction::ORIGIN, - Instruction::COINBASE + InternalInstruction::ADDRESS, + InternalInstruction::CALLER, + InternalInstruction::ORIGIN, + InternalInstruction::COINBASE }) { assertThrow(Pattern::WordSize > 160, OptimizerException, ""); @@ -402,11 +402,11 @@ std::vector> simplificationRuleListPart6( std::vector> rules; // Double negation of opcodes with boolean result for (auto instr: { - Instruction::EQ, - Instruction::LT, - Instruction::SLT, - Instruction::GT, - Instruction::SGT + InternalInstruction::EQ, + InternalInstruction::LT, + InternalInstruction::SLT, + InternalInstruction::GT, + InternalInstruction::SGT }) { typename Builtins::PatternGeneratorInstance op{instr}; @@ -448,12 +448,12 @@ std::vector> simplificationRuleListPart7( std::vector> rules; // Associative operations - for (auto&& instrAndFunc: std::vector>>{ - {Instruction::ADD, std::plus()}, - {Instruction::MUL, std::multiplies()}, - {Instruction::AND, std::bit_and()}, - {Instruction::OR, std::bit_or()}, - {Instruction::XOR, std::bit_xor()} + for (auto&& instrAndFunc: std::vector>>{ + {InternalInstruction::ADD, std::plus()}, + {InternalInstruction::MUL, std::multiplies()}, + {InternalInstruction::AND, std::bit_and()}, + {InternalInstruction::OR, std::bit_or()}, + {InternalInstruction::XOR, std::bit_xor()} }) { typename Builtins::PatternGeneratorInstance op{instrAndFunc.first}; @@ -544,12 +544,12 @@ std::vector> simplificationRuleListPart7( }); // Move AND with constant across SHL and SHR by constant - for (auto instr: {Instruction::SHL, Instruction::SHR}) + for (auto instr: {InternalInstruction::SHL, InternalInstruction::SHR}) { typename Builtins::PatternGeneratorInstance shiftOp{instr}; auto replacement = [=]() -> Pattern { Word mask = - instr == Instruction::SHL ? + instr == InternalInstruction::SHL ? shlWorkaround(A.d(), unsigned(B.d())) : A.d() >> unsigned(B.d()); return Builtins::AND(shiftOp(B.d(), X), std::move(mask)); @@ -743,8 +743,8 @@ std::vector> evmRuleList( if (_evmVersion.hasSelfBalance()) rules.push_back({ - Builtins::BALANCE(Instruction::ADDRESS), - []() -> Pattern { return Instruction::SELFBALANCE; } + Builtins::BALANCE(InternalInstruction::ADDRESS), + []() -> Pattern { return InternalInstruction::SELFBALANCE; } }); rules.emplace_back( diff --git a/libevmasm/SemanticInformation.cpp b/libevmasm/SemanticInformation.cpp index acbcaa5c0..f5130dc92 100644 --- a/libevmasm/SemanticInformation.cpp +++ b/libevmasm/SemanticInformation.cpp @@ -29,12 +29,12 @@ using namespace std; using namespace solidity; using namespace solidity::evmasm; -vector SemanticInformation::readWriteOperations(Instruction _instruction) +vector SemanticInformation::readWriteOperations(InternalInstruction _instruction) { switch (_instruction) { - case Instruction::SSTORE: - case Instruction::SLOAD: + case InternalInstruction::SSTORE: + case InternalInstruction::SLOAD: { assertThrow(memory(_instruction) == Effect::None, OptimizerException, ""); assertThrow(storage(_instruction) != Effect::None, OptimizerException, ""); @@ -46,9 +46,9 @@ vector SemanticInformation::readWriteOperations( op.lengthConstant = 1; return {op}; } - case Instruction::MSTORE: - case Instruction::MSTORE8: - case Instruction::MLOAD: + case InternalInstruction::MSTORE: + case InternalInstruction::MSTORE8: + case InternalInstruction::MLOAD: { assertThrow(memory(_instruction) != Effect::None, OptimizerException, ""); assertThrow(storage(_instruction) == Effect::None, OptimizerException, ""); @@ -56,21 +56,21 @@ vector SemanticInformation::readWriteOperations( op.effect = memory(_instruction); op.location = Location::Memory; op.startParameter = 0; - if (_instruction == Instruction::MSTORE || _instruction == Instruction::MLOAD) + if (_instruction == InternalInstruction::MSTORE || _instruction == InternalInstruction::MLOAD) op.lengthConstant = 32; - else if (_instruction == Instruction::MSTORE8) + else if (_instruction == InternalInstruction::MSTORE8) op.lengthConstant = 1; return {op}; } - case Instruction::REVERT: - case Instruction::RETURN: - case Instruction::KECCAK256: - case Instruction::LOG0: - case Instruction::LOG1: - case Instruction::LOG2: - case Instruction::LOG3: - case Instruction::LOG4: + case InternalInstruction::REVERT: + case InternalInstruction::RETURN: + case InternalInstruction::KECCAK256: + case InternalInstruction::LOG0: + case InternalInstruction::LOG1: + case InternalInstruction::LOG2: + case InternalInstruction::LOG3: + case InternalInstruction::LOG4: { assertThrow(storage(_instruction) == Effect::None, OptimizerException, ""); assertThrow(memory(_instruction) == Effect::Read, OptimizerException, ""); @@ -81,7 +81,7 @@ vector SemanticInformation::readWriteOperations( op.lengthParameter = 1; return {op}; } - case Instruction::EXTCODECOPY: + case InternalInstruction::EXTCODECOPY: { assertThrow(memory(_instruction) == Effect::Write, OptimizerException, ""); assertThrow(storage(_instruction) == Effect::None, OptimizerException, ""); @@ -92,9 +92,9 @@ vector SemanticInformation::readWriteOperations( op.lengthParameter = 3; return {op}; } - case Instruction::CODECOPY: - case Instruction::CALLDATACOPY: - case Instruction::RETURNDATACOPY: + case InternalInstruction::CODECOPY: + case InternalInstruction::CALLDATACOPY: + case InternalInstruction::RETURNDATACOPY: { assertThrow(memory(_instruction) == Effect::Write, OptimizerException, ""); assertThrow(storage(_instruction) == Effect::None, OptimizerException, ""); @@ -105,17 +105,17 @@ vector SemanticInformation::readWriteOperations( op.lengthParameter = 2; return {op}; } - case Instruction::STATICCALL: - case Instruction::CALL: - case Instruction::CALLCODE: - case Instruction::DELEGATECALL: + case InternalInstruction::STATICCALL: + case InternalInstruction::CALL: + case InternalInstruction::CALLCODE: + case InternalInstruction::DELEGATECALL: { size_t paramCount = static_cast(instructionInfo(_instruction).args); vector operations{ Operation{Location::Memory, Effect::Read, paramCount - 4, paramCount - 3, {}}, Operation{Location::Storage, Effect::Read, {}, {}, {}} }; - if (_instruction != Instruction::STATICCALL) + if (_instruction != InternalInstruction::STATICCALL) operations.emplace_back(Operation{Location::Storage, Effect::Write, {}, {}, {}}); operations.emplace_back(Operation{ Location::Memory, @@ -128,8 +128,8 @@ vector SemanticInformation::readWriteOperations( }); return operations; } - case Instruction::CREATE: - case Instruction::CREATE2: + case InternalInstruction::CREATE: + case InternalInstruction::CREATE2: return vector{ Operation{ Location::Memory, @@ -141,7 +141,7 @@ vector SemanticInformation::readWriteOperations( Operation{Location::Storage, Effect::Read, {}, {}, {}}, Operation{Location::Storage, Effect::Write, {}, {}, {}} }; - case Instruction::MSIZE: + case InternalInstruction::MSIZE: // This is just to satisfy the assert below. return vector{}; default: @@ -174,18 +174,18 @@ bool SemanticInformation::breaksCSEAnalysisBlock(AssemblyItem const& _item, bool { if (isSwapInstruction(_item) || isDupInstruction(_item)) return false; - if (_item.instruction() == Instruction::GAS || _item.instruction() == Instruction::PC) + if (_item.instruction() == InternalInstruction::GAS || _item.instruction() == InternalInstruction::PC) return true; // GAS and PC assume a specific order of opcodes - if (_item.instruction() == Instruction::MSIZE) + if (_item.instruction() == InternalInstruction::MSIZE) return true; // msize is modified already by memory access, avoid that for now InstructionInfo info = instructionInfo(_item.instruction()); - if (_item.instruction() == Instruction::SSTORE) + if (_item.instruction() == InternalInstruction::SSTORE) return false; - if (_item.instruction() == Instruction::MSTORE) + if (_item.instruction() == InternalInstruction::MSTORE) return false; if (!_msizeImportant && ( - _item.instruction() == Instruction::MLOAD || - _item.instruction() == Instruction::KECCAK256 + _item.instruction() == InternalInstruction::MLOAD || + _item.instruction() == InternalInstruction::KECCAK256 )) return false; //@todo: We do not handle the following memory instructions for now: @@ -204,12 +204,12 @@ bool SemanticInformation::isCommutativeOperation(AssemblyItem const& _item) return false; switch (_item.instruction()) { - case Instruction::ADD: - case Instruction::MUL: - case Instruction::EQ: - case Instruction::AND: - case Instruction::OR: - case Instruction::XOR: + case InternalInstruction::ADD: + case InternalInstruction::MUL: + case InternalInstruction::EQ: + case InternalInstruction::AND: + case InternalInstruction::OR: + case InternalInstruction::XOR: return true; default: return false; @@ -232,7 +232,7 @@ bool SemanticInformation::isSwapInstruction(AssemblyItem const& _item) bool SemanticInformation::isJumpInstruction(AssemblyItem const& _item) { - return _item == Instruction::JUMP || _item == Instruction::JUMPI; + return _item == InternalInstruction::JUMP || _item == InternalInstruction::JUMPI; } bool SemanticInformation::altersControlFlow(AssemblyItem const& _item) @@ -243,40 +243,40 @@ bool SemanticInformation::altersControlFlow(AssemblyItem const& _item) { // note that CALL, CALLCODE and CREATE do not really alter the control flow, because we // continue on the next instruction - case Instruction::JUMP: - case Instruction::JUMPI: - case Instruction::RETURN: - case Instruction::SELFDESTRUCT: - case Instruction::STOP: - case Instruction::INVALID: - case Instruction::REVERT: + case InternalInstruction::JUMP: + case InternalInstruction::JUMPI: + case InternalInstruction::RETURN: + case InternalInstruction::SELFDESTRUCT: + case InternalInstruction::STOP: + case InternalInstruction::INVALID: + case InternalInstruction::REVERT: return true; default: return false; } } -bool SemanticInformation::terminatesControlFlow(Instruction _instruction) +bool SemanticInformation::terminatesControlFlow(InternalInstruction _instruction) { switch (_instruction) { - case Instruction::RETURN: - case Instruction::SELFDESTRUCT: - case Instruction::STOP: - case Instruction::INVALID: - case Instruction::REVERT: + case InternalInstruction::RETURN: + case InternalInstruction::SELFDESTRUCT: + case InternalInstruction::STOP: + case InternalInstruction::INVALID: + case InternalInstruction::REVERT: return true; default: return false; } } -bool SemanticInformation::reverts(Instruction _instruction) +bool SemanticInformation::reverts(InternalInstruction _instruction) { switch (_instruction) { - case Instruction::INVALID: - case Instruction::REVERT: + case InternalInstruction::INVALID: + case InternalInstruction::REVERT: return true; default: return false; @@ -292,28 +292,28 @@ bool SemanticInformation::isDeterministic(AssemblyItem const& _item) switch (_item.instruction()) { - case Instruction::CALL: - case Instruction::CALLCODE: - case Instruction::DELEGATECALL: - case Instruction::STATICCALL: - case Instruction::CREATE: - case Instruction::CREATE2: - case Instruction::GAS: - case Instruction::PC: - case Instruction::MSIZE: // depends on previous writes and reads, not only on content - case Instruction::BALANCE: // depends on previous calls - case Instruction::SELFBALANCE: // depends on previous calls - case Instruction::EXTCODESIZE: - case Instruction::EXTCODEHASH: - case Instruction::RETURNDATACOPY: // depends on previous calls - case Instruction::RETURNDATASIZE: + case InternalInstruction::CALL: + case InternalInstruction::CALLCODE: + case InternalInstruction::DELEGATECALL: + case InternalInstruction::STATICCALL: + case InternalInstruction::CREATE: + case InternalInstruction::CREATE2: + case InternalInstruction::GAS: + case InternalInstruction::PC: + case InternalInstruction::MSIZE: // depends on previous writes and reads, not only on content + case InternalInstruction::BALANCE: // depends on previous calls + case InternalInstruction::SELFBALANCE: // depends on previous calls + case InternalInstruction::EXTCODESIZE: + case InternalInstruction::EXTCODEHASH: + case InternalInstruction::RETURNDATACOPY: // depends on previous calls + case InternalInstruction::RETURNDATASIZE: return false; default: return true; } } -bool SemanticInformation::movable(Instruction _instruction) +bool SemanticInformation::movable(InternalInstruction _instruction) { // These are not really functional. if (isDupInstruction(_instruction) || isSwapInstruction(_instruction)) @@ -323,16 +323,16 @@ bool SemanticInformation::movable(Instruction _instruction) return false; switch (_instruction) { - case Instruction::KECCAK256: - case Instruction::BALANCE: - case Instruction::SELFBALANCE: - case Instruction::EXTCODESIZE: - case Instruction::EXTCODEHASH: - case Instruction::RETURNDATASIZE: - case Instruction::SLOAD: - case Instruction::PC: - case Instruction::MSIZE: - case Instruction::GAS: + case InternalInstruction::KECCAK256: + case InternalInstruction::BALANCE: + case InternalInstruction::SELFBALANCE: + case InternalInstruction::EXTCODESIZE: + case InternalInstruction::EXTCODEHASH: + case InternalInstruction::RETURNDATASIZE: + case InternalInstruction::SLOAD: + case InternalInstruction::PC: + case InternalInstruction::MSIZE: + case InternalInstruction::GAS: return false; default: return true; @@ -340,7 +340,7 @@ bool SemanticInformation::movable(Instruction _instruction) return true; } -bool SemanticInformation::canBeRemoved(Instruction _instruction) +bool SemanticInformation::canBeRemoved(InternalInstruction _instruction) { // These are not really functional. assertThrow(!isDupInstruction(_instruction) && !isSwapInstruction(_instruction), AssemblyException, ""); @@ -348,42 +348,42 @@ bool SemanticInformation::canBeRemoved(Instruction _instruction) return !instructionInfo(_instruction).sideEffects; } -bool SemanticInformation::canBeRemovedIfNoMSize(Instruction _instruction) +bool SemanticInformation::canBeRemovedIfNoMSize(InternalInstruction _instruction) { - if (_instruction == Instruction::KECCAK256 || _instruction == Instruction::MLOAD) + if (_instruction == InternalInstruction::KECCAK256 || _instruction == InternalInstruction::MLOAD) return true; else return canBeRemoved(_instruction); } -SemanticInformation::Effect SemanticInformation::memory(Instruction _instruction) +SemanticInformation::Effect SemanticInformation::memory(InternalInstruction _instruction) { switch (_instruction) { - case Instruction::CALLDATACOPY: - case Instruction::CODECOPY: - case Instruction::EXTCODECOPY: - case Instruction::RETURNDATACOPY: - case Instruction::MSTORE: - case Instruction::MSTORE8: - case Instruction::CALL: - case Instruction::CALLCODE: - case Instruction::DELEGATECALL: - case Instruction::STATICCALL: + case InternalInstruction::CALLDATACOPY: + case InternalInstruction::CODECOPY: + case InternalInstruction::EXTCODECOPY: + case InternalInstruction::RETURNDATACOPY: + case InternalInstruction::MSTORE: + case InternalInstruction::MSTORE8: + case InternalInstruction::CALL: + case InternalInstruction::CALLCODE: + case InternalInstruction::DELEGATECALL: + case InternalInstruction::STATICCALL: return SemanticInformation::Write; - case Instruction::CREATE: - case Instruction::CREATE2: - case Instruction::KECCAK256: - case Instruction::MLOAD: - case Instruction::MSIZE: - case Instruction::RETURN: - case Instruction::REVERT: - case Instruction::LOG0: - case Instruction::LOG1: - case Instruction::LOG2: - case Instruction::LOG3: - case Instruction::LOG4: + case InternalInstruction::CREATE: + case InternalInstruction::CREATE2: + case InternalInstruction::KECCAK256: + case InternalInstruction::MLOAD: + case InternalInstruction::MSIZE: + case InternalInstruction::RETURN: + case InternalInstruction::REVERT: + case InternalInstruction::LOG0: + case InternalInstruction::LOG1: + case InternalInstruction::LOG2: + case InternalInstruction::LOG3: + case InternalInstruction::LOG4: return SemanticInformation::Read; default: @@ -391,18 +391,18 @@ SemanticInformation::Effect SemanticInformation::memory(Instruction _instruction } } -bool SemanticInformation::movableApartFromEffects(Instruction _instruction) +bool SemanticInformation::movableApartFromEffects(InternalInstruction _instruction) { switch (_instruction) { - case Instruction::EXTCODEHASH: - case Instruction::EXTCODESIZE: - case Instruction::RETURNDATASIZE: - case Instruction::BALANCE: - case Instruction::SELFBALANCE: - case Instruction::SLOAD: - case Instruction::KECCAK256: - case Instruction::MLOAD: + case InternalInstruction::EXTCODEHASH: + case InternalInstruction::EXTCODESIZE: + case InternalInstruction::RETURNDATASIZE: + case InternalInstruction::BALANCE: + case InternalInstruction::SELFBALANCE: + case InternalInstruction::SLOAD: + case InternalInstruction::KECCAK256: + case InternalInstruction::MLOAD: return true; default: @@ -410,20 +410,20 @@ bool SemanticInformation::movableApartFromEffects(Instruction _instruction) } } -SemanticInformation::Effect SemanticInformation::storage(Instruction _instruction) +SemanticInformation::Effect SemanticInformation::storage(InternalInstruction _instruction) { switch (_instruction) { - case Instruction::CALL: - case Instruction::CALLCODE: - case Instruction::DELEGATECALL: - case Instruction::CREATE: - case Instruction::CREATE2: - case Instruction::SSTORE: + case InternalInstruction::CALL: + case InternalInstruction::CALLCODE: + case InternalInstruction::DELEGATECALL: + case InternalInstruction::CREATE: + case InternalInstruction::CREATE2: + case InternalInstruction::SSTORE: return SemanticInformation::Write; - case Instruction::SLOAD: - case Instruction::STATICCALL: + case InternalInstruction::SLOAD: + case InternalInstruction::STATICCALL: return SemanticInformation::Read; default: @@ -431,28 +431,28 @@ SemanticInformation::Effect SemanticInformation::storage(Instruction _instructio } } -SemanticInformation::Effect SemanticInformation::otherState(Instruction _instruction) +SemanticInformation::Effect SemanticInformation::otherState(InternalInstruction _instruction) { switch (_instruction) { - case Instruction::CALL: - case Instruction::CALLCODE: - case Instruction::DELEGATECALL: - case Instruction::CREATE: - case Instruction::CREATE2: - case Instruction::SELFDESTRUCT: - case Instruction::STATICCALL: // because it can affect returndatasize + case InternalInstruction::CALL: + case InternalInstruction::CALLCODE: + case InternalInstruction::DELEGATECALL: + case InternalInstruction::CREATE: + case InternalInstruction::CREATE2: + case InternalInstruction::SELFDESTRUCT: + case InternalInstruction::STATICCALL: // because it can affect returndatasize // Strictly speaking, log0, .., log4 writes to the state, but the EVM cannot read it, so they // are just marked as having 'other side effects.' return SemanticInformation::Write; - case Instruction::EXTCODESIZE: - case Instruction::EXTCODEHASH: - case Instruction::RETURNDATASIZE: - case Instruction::BALANCE: - case Instruction::SELFBALANCE: - case Instruction::RETURNDATACOPY: - case Instruction::EXTCODECOPY: + case InternalInstruction::EXTCODESIZE: + case InternalInstruction::EXTCODEHASH: + case InternalInstruction::RETURNDATASIZE: + case InternalInstruction::BALANCE: + case InternalInstruction::SELFBALANCE: + case InternalInstruction::RETURNDATACOPY: + case InternalInstruction::EXTCODECOPY: // PC and GAS are specifically excluded here. Instructions such as CALLER, CALLVALUE, // ADDRESS are excluded because they cannot change during execution. return SemanticInformation::Read; @@ -462,31 +462,31 @@ SemanticInformation::Effect SemanticInformation::otherState(Instruction _instruc } } -bool SemanticInformation::invalidInPureFunctions(Instruction _instruction) +bool SemanticInformation::invalidInPureFunctions(InternalInstruction _instruction) { switch (_instruction) { - case Instruction::ADDRESS: - case Instruction::SELFBALANCE: - case Instruction::BALANCE: - case Instruction::ORIGIN: - case Instruction::CALLER: - case Instruction::CALLVALUE: - case Instruction::CHAINID: - case Instruction::BASEFEE: - case Instruction::GAS: - case Instruction::GASPRICE: - case Instruction::EXTCODESIZE: - case Instruction::EXTCODECOPY: - case Instruction::EXTCODEHASH: - case Instruction::BLOCKHASH: - case Instruction::COINBASE: - case Instruction::TIMESTAMP: - case Instruction::NUMBER: - case Instruction::DIFFICULTY: - case Instruction::GASLIMIT: - case Instruction::STATICCALL: - case Instruction::SLOAD: + case InternalInstruction::ADDRESS: + case InternalInstruction::SELFBALANCE: + case InternalInstruction::BALANCE: + case InternalInstruction::ORIGIN: + case InternalInstruction::CALLER: + case InternalInstruction::CALLVALUE: + case InternalInstruction::CHAINID: + case InternalInstruction::BASEFEE: + case InternalInstruction::GAS: + case InternalInstruction::GASPRICE: + case InternalInstruction::EXTCODESIZE: + case InternalInstruction::EXTCODECOPY: + case InternalInstruction::EXTCODEHASH: + case InternalInstruction::BLOCKHASH: + case InternalInstruction::COINBASE: + case InternalInstruction::TIMESTAMP: + case InternalInstruction::NUMBER: + case InternalInstruction::DIFFICULTY: + case InternalInstruction::GASLIMIT: + case InternalInstruction::STATICCALL: + case InternalInstruction::SLOAD: return true; default: break; @@ -494,24 +494,24 @@ bool SemanticInformation::invalidInPureFunctions(Instruction _instruction) return invalidInViewFunctions(_instruction); } -bool SemanticInformation::invalidInViewFunctions(Instruction _instruction) +bool SemanticInformation::invalidInViewFunctions(InternalInstruction _instruction) { switch (_instruction) { - case Instruction::SSTORE: - case Instruction::JUMP: - case Instruction::JUMPI: - case Instruction::LOG0: - case Instruction::LOG1: - case Instruction::LOG2: - case Instruction::LOG3: - case Instruction::LOG4: - case Instruction::CREATE: - case Instruction::CALL: - case Instruction::CALLCODE: - case Instruction::DELEGATECALL: - case Instruction::CREATE2: - case Instruction::SELFDESTRUCT: + case InternalInstruction::SSTORE: + case InternalInstruction::JUMP: + case InternalInstruction::JUMPI: + case InternalInstruction::LOG0: + case InternalInstruction::LOG1: + case InternalInstruction::LOG2: + case InternalInstruction::LOG3: + case InternalInstruction::LOG4: + case InternalInstruction::CREATE: + case InternalInstruction::CALL: + case InternalInstruction::CALLCODE: + case InternalInstruction::DELEGATECALL: + case InternalInstruction::CREATE2: + case InternalInstruction::SELFDESTRUCT: return true; default: break; diff --git a/libevmasm/SemanticInformation.h b/libevmasm/SemanticInformation.h index 36aabd55f..ef0d27550 100644 --- a/libevmasm/SemanticInformation.h +++ b/libevmasm/SemanticInformation.h @@ -72,7 +72,7 @@ struct SemanticInformation /// Order matters. /// For external calls, there is just one unknown read and one unknown write operation, /// event though there might be multiple. - static std::vector readWriteOperations(Instruction _instruction); + static std::vector readWriteOperations(InternalInstruction _instruction); /// @returns true if the given items starts a new block for common subexpression analysis. /// @param _msizeImportant if false, consider an operation non-breaking if its only side-effect is that it modifies msize. @@ -84,34 +84,34 @@ struct SemanticInformation static bool isSwapInstruction(AssemblyItem const& _item); static bool isJumpInstruction(AssemblyItem const& _item); static bool altersControlFlow(AssemblyItem const& _item); - static bool terminatesControlFlow(Instruction _instruction); - static bool reverts(Instruction _instruction); + static bool terminatesControlFlow(InternalInstruction _instruction); + static bool reverts(InternalInstruction _instruction); /// @returns false if the value put on the stack by _item depends on anything else than /// the information in the current block header, memory, storage or stack. static bool isDeterministic(AssemblyItem const& _item); /// @returns true if the instruction can be moved or copied (together with its arguments) /// without altering the semantics. This means it cannot depend on storage or memory, /// cannot have any side-effects, but it can depend on a call-constant state of the blockchain. - static bool movable(Instruction _instruction); + static bool movable(InternalInstruction _instruction); /// If true, the expressions in this code can be moved or copied (together with their arguments) /// across control flow branches and instructions as long as these instructions' 'effects' do /// not influence the 'effects' of the aforementioned expressions. - static bool movableApartFromEffects(Instruction _instruction); + static bool movableApartFromEffects(InternalInstruction _instruction); /// @returns true if the instruction can be removed without changing the semantics. /// This does not mean that it has to be deterministic or retrieve information from /// somewhere else than purely the values of its arguments. - static bool canBeRemoved(Instruction _instruction); + static bool canBeRemoved(InternalInstruction _instruction); /// @returns true if the instruction can be removed without changing the semantics. /// This does not mean that it has to be deterministic or retrieve information from /// somewhere else than purely the values of its arguments. /// If true, the instruction is still allowed to influence the value returned by the /// msize instruction. - static bool canBeRemovedIfNoMSize(Instruction _instruction); - static Effect memory(Instruction _instruction); - static Effect storage(Instruction _instruction); - static Effect otherState(Instruction _instruction); - static bool invalidInPureFunctions(Instruction _instruction); - static bool invalidInViewFunctions(Instruction _instruction); + static bool canBeRemovedIfNoMSize(InternalInstruction _instruction); + static Effect memory(InternalInstruction _instruction); + static Effect storage(InternalInstruction _instruction); + static Effect otherState(InternalInstruction _instruction); + static bool invalidInPureFunctions(InternalInstruction _instruction); + static bool invalidInViewFunctions(InternalInstruction _instruction); }; } diff --git a/libevmasm/SimplificationRule.h b/libevmasm/SimplificationRule.h index aef456968..004b792c5 100644 --- a/libevmasm/SimplificationRule.h +++ b/libevmasm/SimplificationRule.h @@ -54,9 +54,9 @@ struct SimplificationRule template struct EVMBuiltins { - using InstrType = Instruction; + using InstrType = InternalInstruction; - template + template struct PatternGenerator { template constexpr Pattern operator()(Args&&... _args) const @@ -67,7 +67,7 @@ struct EVMBuiltins struct PatternGeneratorInstance { - Instruction instruction; + InternalInstruction instruction; template constexpr Pattern operator()(Args&&... _args) const { return {instruction, {std::forward(_args)...}}; @@ -75,83 +75,83 @@ struct EVMBuiltins }; - static auto constexpr STOP = PatternGenerator{}; - static auto constexpr ADD = PatternGenerator{}; - static auto constexpr SUB = PatternGenerator{}; - static auto constexpr MUL = PatternGenerator{}; - static auto constexpr DIV = PatternGenerator{}; - static auto constexpr SDIV = PatternGenerator{}; - static auto constexpr MOD = PatternGenerator{}; - static auto constexpr SMOD = PatternGenerator{}; - static auto constexpr EXP = PatternGenerator{}; - static auto constexpr NOT = PatternGenerator{}; - static auto constexpr LT = PatternGenerator{}; - static auto constexpr GT = PatternGenerator{}; - static auto constexpr SLT = PatternGenerator{}; - static auto constexpr SGT = PatternGenerator{}; - static auto constexpr EQ = PatternGenerator{}; - static auto constexpr ISZERO = PatternGenerator{}; - static auto constexpr AND = PatternGenerator{}; - static auto constexpr OR = PatternGenerator{}; - static auto constexpr XOR = PatternGenerator{}; - static auto constexpr BYTE = PatternGenerator{}; - static auto constexpr SHL = PatternGenerator{}; - static auto constexpr SHR = PatternGenerator{}; - static auto constexpr SAR = PatternGenerator{}; - static auto constexpr ADDMOD = PatternGenerator{}; - static auto constexpr MULMOD = PatternGenerator{}; - static auto constexpr SIGNEXTEND = PatternGenerator{}; - static auto constexpr KECCAK256 = PatternGenerator{}; - static auto constexpr ADDRESS = PatternGenerator{}; - static auto constexpr BALANCE = PatternGenerator{}; - static auto constexpr ORIGIN = PatternGenerator{}; - static auto constexpr CALLER = PatternGenerator{}; - static auto constexpr CALLVALUE = PatternGenerator{}; - static auto constexpr CALLDATALOAD = PatternGenerator{}; - static auto constexpr CALLDATASIZE = PatternGenerator{}; - static auto constexpr CALLDATACOPY = PatternGenerator{}; - static auto constexpr CODESIZE = PatternGenerator{}; - static auto constexpr CODECOPY = PatternGenerator{}; - static auto constexpr GASPRICE = PatternGenerator{}; - static auto constexpr EXTCODESIZE = PatternGenerator{}; - static auto constexpr EXTCODECOPY = PatternGenerator{}; - static auto constexpr RETURNDATASIZE = PatternGenerator{}; - static auto constexpr RETURNDATACOPY = PatternGenerator{}; - static auto constexpr EXTCODEHASH = PatternGenerator{}; - static auto constexpr BLOCKHASH = PatternGenerator{}; - static auto constexpr COINBASE = PatternGenerator{}; - static auto constexpr TIMESTAMP = PatternGenerator{}; - static auto constexpr NUMBER = PatternGenerator{}; - static auto constexpr DIFFICULTY = PatternGenerator{}; - static auto constexpr PREVRANDAO = PatternGenerator{}; - static auto constexpr GASLIMIT = PatternGenerator{}; - static auto constexpr CHAINID = PatternGenerator{}; - static auto constexpr SELFBALANCE = PatternGenerator{}; - static auto constexpr BASEFEE = PatternGenerator{}; - static auto constexpr POP = PatternGenerator{}; - static auto constexpr MLOAD = PatternGenerator{}; - static auto constexpr MSTORE = PatternGenerator{}; - static auto constexpr MSTORE8 = PatternGenerator{}; - static auto constexpr SLOAD = PatternGenerator{}; - static auto constexpr SSTORE = PatternGenerator{}; - static auto constexpr PC = PatternGenerator{}; - static auto constexpr MSIZE = PatternGenerator{}; - static auto constexpr GAS = PatternGenerator{}; - static auto constexpr LOG0 = PatternGenerator{}; - static auto constexpr LOG1 = PatternGenerator{}; - static auto constexpr LOG2 = PatternGenerator{}; - static auto constexpr LOG3 = PatternGenerator{}; - static auto constexpr LOG4 = PatternGenerator{}; - static auto constexpr CREATE = PatternGenerator{}; - static auto constexpr CALL = PatternGenerator{}; - static auto constexpr CALLCODE = PatternGenerator{}; - static auto constexpr STATICCALL = PatternGenerator{}; - static auto constexpr RETURN = PatternGenerator{}; - static auto constexpr DELEGATECALL = PatternGenerator{}; - static auto constexpr CREATE2 = PatternGenerator{}; - static auto constexpr REVERT = PatternGenerator{}; - static auto constexpr INVALID = PatternGenerator{}; - static auto constexpr SELFDESTRUCT = PatternGenerator{}; + static auto constexpr STOP = PatternGenerator{}; + static auto constexpr ADD = PatternGenerator{}; + static auto constexpr SUB = PatternGenerator{}; + static auto constexpr MUL = PatternGenerator{}; + static auto constexpr DIV = PatternGenerator{}; + static auto constexpr SDIV = PatternGenerator{}; + static auto constexpr MOD = PatternGenerator{}; + static auto constexpr SMOD = PatternGenerator{}; + static auto constexpr EXP = PatternGenerator{}; + static auto constexpr NOT = PatternGenerator{}; + static auto constexpr LT = PatternGenerator{}; + static auto constexpr GT = PatternGenerator{}; + static auto constexpr SLT = PatternGenerator{}; + static auto constexpr SGT = PatternGenerator{}; + static auto constexpr EQ = PatternGenerator{}; + static auto constexpr ISZERO = PatternGenerator{}; + static auto constexpr AND = PatternGenerator{}; + static auto constexpr OR = PatternGenerator{}; + static auto constexpr XOR = PatternGenerator{}; + static auto constexpr BYTE = PatternGenerator{}; + static auto constexpr SHL = PatternGenerator{}; + static auto constexpr SHR = PatternGenerator{}; + static auto constexpr SAR = PatternGenerator{}; + static auto constexpr ADDMOD = PatternGenerator{}; + static auto constexpr MULMOD = PatternGenerator{}; + static auto constexpr SIGNEXTEND = PatternGenerator{}; + static auto constexpr KECCAK256 = PatternGenerator{}; + static auto constexpr ADDRESS = PatternGenerator{}; + static auto constexpr BALANCE = PatternGenerator{}; + static auto constexpr ORIGIN = PatternGenerator{}; + static auto constexpr CALLER = PatternGenerator{}; + static auto constexpr CALLVALUE = PatternGenerator{}; + static auto constexpr CALLDATALOAD = PatternGenerator{}; + static auto constexpr CALLDATASIZE = PatternGenerator{}; + static auto constexpr CALLDATACOPY = PatternGenerator{}; + static auto constexpr CODESIZE = PatternGenerator{}; + static auto constexpr CODECOPY = PatternGenerator{}; + static auto constexpr GASPRICE = PatternGenerator{}; + static auto constexpr EXTCODESIZE = PatternGenerator{}; + static auto constexpr EXTCODECOPY = PatternGenerator{}; + static auto constexpr RETURNDATASIZE = PatternGenerator{}; + static auto constexpr RETURNDATACOPY = PatternGenerator{}; + static auto constexpr EXTCODEHASH = PatternGenerator{}; + static auto constexpr BLOCKHASH = PatternGenerator{}; + static auto constexpr COINBASE = PatternGenerator{}; + static auto constexpr TIMESTAMP = PatternGenerator{}; + static auto constexpr NUMBER = PatternGenerator{}; + static auto constexpr DIFFICULTY = PatternGenerator{}; + static auto constexpr PREVRANDAO = PatternGenerator{}; + static auto constexpr GASLIMIT = PatternGenerator{}; + static auto constexpr CHAINID = PatternGenerator{}; + static auto constexpr SELFBALANCE = PatternGenerator{}; + static auto constexpr BASEFEE = PatternGenerator{}; + static auto constexpr POP = PatternGenerator{}; + static auto constexpr MLOAD = PatternGenerator{}; + static auto constexpr MSTORE = PatternGenerator{}; + static auto constexpr MSTORE8 = PatternGenerator{}; + static auto constexpr SLOAD = PatternGenerator{}; + static auto constexpr SSTORE = PatternGenerator{}; + static auto constexpr PC = PatternGenerator{}; + static auto constexpr MSIZE = PatternGenerator{}; + static auto constexpr GAS = PatternGenerator{}; + static auto constexpr LOG0 = PatternGenerator{}; + static auto constexpr LOG1 = PatternGenerator{}; + static auto constexpr LOG2 = PatternGenerator{}; + static auto constexpr LOG3 = PatternGenerator{}; + static auto constexpr LOG4 = PatternGenerator{}; + static auto constexpr CREATE = PatternGenerator{}; + static auto constexpr CALL = PatternGenerator{}; + static auto constexpr CALLCODE = PatternGenerator{}; + static auto constexpr STATICCALL = PatternGenerator{}; + static auto constexpr RETURN = PatternGenerator{}; + static auto constexpr DELEGATECALL = PatternGenerator{}; + static auto constexpr CREATE2 = PatternGenerator{}; + static auto constexpr REVERT = PatternGenerator{}; + static auto constexpr INVALID = PatternGenerator{}; + static auto constexpr SELFDESTRUCT = PatternGenerator{}; }; } diff --git a/libevmasm/SimplificationRules.cpp b/libevmasm/SimplificationRules.cpp index a21ed4195..d518b5081 100644 --- a/libevmasm/SimplificationRules.cpp +++ b/libevmasm/SimplificationRules.cpp @@ -58,7 +58,7 @@ SimplificationRule const* Rules::findFirstMatch( bool Rules::isInitialized() const { - return !m_rules[uint8_t(Instruction::ADD)].empty(); + return !m_rules[uint8_t(InternalInstruction::ADD)].empty(); } void Rules::addRules(std::vector> const& _rules) @@ -96,7 +96,7 @@ Rules::Rules() assertThrow(isInitialized(), OptimizerException, "Rule list not properly initialized."); } -Pattern::Pattern(Instruction _instruction, std::initializer_list _arguments): +Pattern::Pattern(InternalInstruction _instruction, std::initializer_list _arguments): m_type(Operation), m_instruction(_instruction), m_arguments(_arguments) diff --git a/libevmasm/SimplificationRules.h b/libevmasm/SimplificationRules.h index b3f8da3c7..5aa547448 100644 --- a/libevmasm/SimplificationRules.h +++ b/libevmasm/SimplificationRules.h @@ -103,7 +103,7 @@ public: // Matches a specific assembly item type or anything if not given. Pattern(AssemblyItemType _type = UndefinedItem): m_type(_type) {} // Matches a given instruction with given arguments - Pattern(Instruction _instruction, std::initializer_list _arguments = {}); + Pattern(InternalInstruction _instruction, std::initializer_list _arguments = {}); /// Sets this pattern to be part of the match group with the identifier @a _group. /// Inside one rule, all patterns in the same match group have to match expressions from the /// same expression equivalence class. @@ -122,7 +122,7 @@ public: std::string toString() const; AssemblyItemType type() const { return m_type; } - Instruction instruction() const + InternalInstruction instruction() const { assertThrow(type() == Operation, OptimizerException, ""); return m_instruction; @@ -135,7 +135,7 @@ private: AssemblyItemType m_type; bool m_requireDataMatch = false; - Instruction m_instruction; ///< Only valid if m_type is Operation + InternalInstruction m_instruction; ///< Only valid if m_type is Operation std::shared_ptr m_data; ///< Only valid if m_type is not Operation std::vector m_arguments; unsigned m_matchGroup = 0; diff --git a/liblangutil/EVMVersion.cpp b/liblangutil/EVMVersion.cpp index 64da991e8..f2b6b36ce 100644 --- a/liblangutil/EVMVersion.cpp +++ b/liblangutil/EVMVersion.cpp @@ -25,28 +25,28 @@ using namespace solidity; using namespace solidity::evmasm; using namespace solidity::langutil; -bool EVMVersion::hasOpcode(Instruction _opcode) const +bool EVMVersion::hasInstruction(InternalInstruction _instruction) const { - switch (_opcode) + switch (_instruction) { - case Instruction::RETURNDATACOPY: - case Instruction::RETURNDATASIZE: + case InternalInstruction::RETURNDATACOPY: + case InternalInstruction::RETURNDATASIZE: return supportsReturndata(); - case Instruction::STATICCALL: + case InternalInstruction::STATICCALL: return hasStaticCall(); - case Instruction::SHL: - case Instruction::SHR: - case Instruction::SAR: + case InternalInstruction::SHL: + case InternalInstruction::SHR: + case InternalInstruction::SAR: return hasBitwiseShifting(); - case Instruction::CREATE2: + case InternalInstruction::CREATE2: return hasCreate2(); - case Instruction::EXTCODEHASH: + case InternalInstruction::EXTCODEHASH: return hasExtCodeHash(); - case Instruction::CHAINID: + case InternalInstruction::CHAINID: return hasChainID(); - case Instruction::SELFBALANCE: + case InternalInstruction::SELFBALANCE: return hasSelfBalance(); - case Instruction::BASEFEE: + case InternalInstruction::BASEFEE: return hasBaseFee(); case InternalInstruction::DIFFICULTY: return hasDifficulty(); diff --git a/libsolidity/analysis/ViewPureChecker.cpp b/libsolidity/analysis/ViewPureChecker.cpp index 7483af892..699f321a4 100644 --- a/libsolidity/analysis/ViewPureChecker.cpp +++ b/libsolidity/analysis/ViewPureChecker.cpp @@ -112,7 +112,7 @@ public: } private: - void checkInstruction(SourceLocation _location, evmasm::Instruction _instruction) + void checkInstruction(SourceLocation _location, evmasm::InternalInstruction _instruction) { if (evmasm::SemanticInformation::invalidInViewFunctions(_instruction)) m_reportMutability(StateMutability::NonPayable, _location); diff --git a/libsolidity/codegen/ArrayUtils.cpp b/libsolidity/codegen/ArrayUtils.cpp index 609ff9993..e74e52136 100644 --- a/libsolidity/codegen/ArrayUtils.cpp +++ b/libsolidity/codegen/ArrayUtils.cpp @@ -74,9 +74,9 @@ void ArrayUtils::copyArrayToStorage(ArrayType const& _targetType, ArrayType cons if (fromCalldata && _sourceType.isDynamicallySized()) { // stack: target_ref source_ref source_length - m_context << Instruction::SWAP1; + m_context << InternalInstruction::SWAP1; // stack: target_ref source_length source_ref - m_context << Instruction::DUP3; + m_context << InternalInstruction::DUP3; // stack: target_ref source_length source_ref target_ref m_context.callYulFunction( m_context.utilFunctions().copyByteArrayToStorageFunction(_sourceType, _targetType), @@ -87,7 +87,7 @@ void ArrayUtils::copyArrayToStorage(ArrayType const& _targetType, ArrayType cons else { // stack: target_ref source_ref - m_context << Instruction::DUP2; + m_context << InternalInstruction::DUP2; // stack: target_ref source_ref target_ref m_context.callYulFunction( m_context.utilFunctions().copyByteArrayToStorageFunction(_sourceType, _targetType), @@ -105,8 +105,8 @@ void ArrayUtils::copyArrayToStorage(ArrayType const& _targetType, ArrayType cons if (_sourceType.location() == DataLocation::Memory && _sourceType.isDynamicallySized()) { // increment source pointer to point to data - m_context << Instruction::SWAP1 << u256(0x20); - m_context << Instruction::ADD << Instruction::SWAP1; + m_context << InternalInstruction::SWAP1 << u256(0x20); + m_context << InternalInstruction::ADD << InternalInstruction::SWAP1; } // stack: target_ref source_ref source_length @@ -122,7 +122,7 @@ void ArrayUtils::copyArrayToStorage(ArrayType const& _targetType, ArrayType cons ArrayType const& _sourceType = dynamic_cast(*sourceType); ArrayType const& _targetType = dynamic_cast(*targetType); // stack: target_ref source_ref source_length - _context << Instruction::DUP3; + _context << InternalInstruction::DUP3; // stack: target_ref source_ref source_length target_ref utils.retrieveLength(_targetType); // stack: target_ref source_ref source_length target_ref target_length @@ -130,7 +130,7 @@ void ArrayUtils::copyArrayToStorage(ArrayType const& _targetType, ArrayType cons { // store new target length solAssert(!_targetType.isByteArrayOrString()); - _context << Instruction::DUP3 << Instruction::DUP3 << Instruction::SSTORE; + _context << InternalInstruction::DUP3 << InternalInstruction::DUP3 << InternalInstruction::SSTORE; } if (sourceBaseType->category() == Type::Category::Mapping) { @@ -138,35 +138,35 @@ void ArrayUtils::copyArrayToStorage(ArrayType const& _targetType, ArrayType cons solAssert(_sourceType.location() == DataLocation::Storage, ""); // nothing to copy _context - << Instruction::POP << Instruction::POP - << Instruction::POP << Instruction::POP; + << InternalInstruction::POP << InternalInstruction::POP + << InternalInstruction::POP << InternalInstruction::POP; return; } // stack: target_ref source_ref source_length target_ref target_length // compute hashes (data positions) - _context << Instruction::SWAP1; + _context << InternalInstruction::SWAP1; if (_targetType.isDynamicallySized()) CompilerUtils(_context).computeHashStatic(); // stack: target_ref source_ref source_length target_length target_data_pos - _context << Instruction::SWAP1; + _context << InternalInstruction::SWAP1; utils.convertLengthToSize(_targetType); - _context << Instruction::DUP2 << Instruction::ADD; + _context << InternalInstruction::DUP2 << InternalInstruction::ADD; // stack: target_ref source_ref source_length target_data_pos target_data_end - _context << Instruction::SWAP3; + _context << InternalInstruction::SWAP3; // stack: target_ref target_data_end source_length target_data_pos source_ref evmasm::AssemblyItem copyLoopEndWithoutByteOffset = _context.newTag(); solAssert(!_targetType.isByteArrayOrString()); // skip copying if source length is zero - _context << Instruction::DUP3 << Instruction::ISZERO; + _context << InternalInstruction::DUP3 << InternalInstruction::ISZERO; _context.appendConditionalJumpTo(copyLoopEndWithoutByteOffset); if (_sourceType.location() == DataLocation::Storage && _sourceType.isDynamicallySized()) CompilerUtils(_context).computeHashStatic(); // stack: target_ref target_data_end source_length target_data_pos source_data_pos - _context << Instruction::SWAP2; + _context << InternalInstruction::SWAP2; utils.convertLengthToSize(_sourceType); - _context << Instruction::DUP3 << Instruction::ADD; + _context << InternalInstruction::DUP3 << InternalInstruction::ADD; // stack: target_ref target_data_end source_data_pos target_data_pos source_data_end if (haveByteOffsetTarget) _context << u256(0); @@ -178,7 +178,7 @@ void ArrayUtils::copyArrayToStorage(ArrayType const& _targetType, ArrayType cons // check for loop condition _context << dupInstruction(3 + byteOffsetSize) << dupInstruction(2 + byteOffsetSize) - << Instruction::GT << Instruction::ISZERO; + << InternalInstruction::GT << InternalInstruction::ISZERO; evmasm::AssemblyItem copyLoopEnd = _context.appendConditionalJump(); // stack: target_ref target_data_end source_data_pos target_data_pos source_data_end [target_byte_offset] [source_byte_offset] // copy @@ -193,19 +193,19 @@ void ArrayUtils::copyArrayToStorage(ArrayType const& _targetType, ArrayType cons !sourceBaseArrayType.isDynamicallySized(), "Copying nested calldata dynamic arrays to storage is not implemented in the old code generator." ); - _context << Instruction::DUP3; + _context << InternalInstruction::DUP3; if (sourceBaseArrayType.location() == DataLocation::Memory) - _context << Instruction::MLOAD; - _context << Instruction::DUP3; + _context << InternalInstruction::MLOAD; + _context << InternalInstruction::DUP3; utils.copyArrayToStorage(dynamic_cast(*targetBaseType), sourceBaseArrayType); - _context << Instruction::POP; + _context << InternalInstruction::POP; } else if (directCopy) { solAssert(byteOffsetSize == 0, "Byte offset for direct copy."); _context - << Instruction::DUP3 << Instruction::SLOAD - << Instruction::DUP3 << Instruction::SSTORE; + << InternalInstruction::DUP3 << InternalInstruction::SLOAD + << InternalInstruction::DUP3 << InternalInstruction::SSTORE; } else { @@ -217,7 +217,7 @@ void ArrayUtils::copyArrayToStorage(ArrayType const& _targetType, ArrayType cons if (_sourceType.location() == DataLocation::Storage) { if (haveByteOffsetSource) - _context << Instruction::DUP2; + _context << InternalInstruction::DUP2; else _context << u256(0); StorageItem(_context, *sourceBaseType).retrieveValue(SourceLocation(), true); @@ -254,7 +254,7 @@ void ArrayUtils::copyArrayToStorage(ArrayType const& _targetType, ArrayType cons else _context << sourceBaseType->calldataHeadSize(); _context - << Instruction::ADD + << InternalInstruction::ADD << swapInstruction(2 + byteOffsetSize); } // increment target @@ -264,7 +264,7 @@ void ArrayUtils::copyArrayToStorage(ArrayType const& _targetType, ArrayType cons _context << swapInstruction(1 + byteOffsetSize) << targetBaseType->storageSize() - << Instruction::ADD + << InternalInstruction::ADD << swapInstruction(1 + byteOffsetSize); _context.appendJumpTo(copyLoopStart); _context << copyLoopEnd; @@ -272,7 +272,7 @@ void ArrayUtils::copyArrayToStorage(ArrayType const& _targetType, ArrayType cons { // clear elements that might be left over in the current slot in target // stack: target_ref target_data_end source_data_pos target_data_pos source_data_end target_byte_offset [source_byte_offset] - _context << dupInstruction(byteOffsetSize) << Instruction::ISZERO; + _context << dupInstruction(byteOffsetSize) << InternalInstruction::ISZERO; evmasm::AssemblyItem copyCleanupLoopEnd = _context.appendConditionalJump(); _context << dupInstruction(2 + byteOffsetSize) << dupInstruction(1 + byteOffsetSize); StorageItem(_context, *targetBaseType).setToZero(SourceLocation(), true); @@ -280,21 +280,21 @@ void ArrayUtils::copyArrayToStorage(ArrayType const& _targetType, ArrayType cons _context.appendJumpTo(copyLoopEnd); _context << copyCleanupLoopEnd; - _context << Instruction::POP; // might pop the source, but then target is popped next + _context << InternalInstruction::POP; // might pop the source, but then target is popped next } if (haveByteOffsetSource) - _context << Instruction::POP; + _context << InternalInstruction::POP; _context << copyLoopEndWithoutByteOffset; // zero-out leftovers in target // stack: target_ref target_data_end source_data_pos target_data_pos_updated source_data_end - _context << Instruction::POP << Instruction::SWAP1 << Instruction::POP; + _context << InternalInstruction::POP << InternalInstruction::SWAP1 << InternalInstruction::POP; // stack: target_ref target_data_end target_data_pos_updated if (targetBaseType->storageBytes() < 32) utils.clearStorageLoop(TypeProvider::uint256()); else utils.clearStorageLoop(targetBaseType); - _context << Instruction::POP; + _context << InternalInstruction::POP; } ); } @@ -323,7 +323,7 @@ void ArrayUtils::copyArrayToMemory(ArrayType const& _sourceType, bool _padToWord )"; routine += "target := add(target, len)\n"; m_context.appendInlineAssembly("{" + routine + "}", {"target", "source", "len"}); - m_context << Instruction::POP << Instruction::POP; + m_context << InternalInstruction::POP << InternalInstruction::POP; } else if (_sourceType.location() == DataLocation::Memory) { @@ -332,25 +332,25 @@ void ArrayUtils::copyArrayToMemory(ArrayType const& _sourceType, bool _padToWord if (!_sourceType.baseType()->isValueType()) { // copy using a loop - m_context << u256(0) << Instruction::SWAP3; + m_context << u256(0) << InternalInstruction::SWAP3; // stack: counter source length target auto repeat = m_context.newTag(); m_context << repeat; - m_context << Instruction::DUP2 << Instruction::DUP5; - m_context << Instruction::LT << Instruction::ISZERO; + m_context << InternalInstruction::DUP2 << InternalInstruction::DUP5; + m_context << InternalInstruction::LT << InternalInstruction::ISZERO; auto loopEnd = m_context.appendConditionalJump(); - m_context << Instruction::DUP3 << Instruction::DUP5; + m_context << InternalInstruction::DUP3 << InternalInstruction::DUP5; accessIndex(_sourceType, false); MemoryItem(m_context, *_sourceType.baseType(), true).retrieveValue(SourceLocation(), true); if (auto baseArray = dynamic_cast(_sourceType.baseType())) copyArrayToMemory(*baseArray, _padToWordBoundaries); else utils.storeInMemoryDynamic(*_sourceType.baseType()); - m_context << Instruction::SWAP3 << u256(1) << Instruction::ADD; - m_context << Instruction::SWAP3; + m_context << InternalInstruction::SWAP3 << u256(1) << InternalInstruction::ADD; + m_context << InternalInstruction::SWAP3; m_context.appendJumpTo(repeat); m_context << loopEnd; - m_context << Instruction::SWAP3; + m_context << InternalInstruction::SWAP3; utils.popStackSlots(3); // stack: updated_target_pos return; @@ -360,13 +360,13 @@ void ArrayUtils::copyArrayToMemory(ArrayType const& _sourceType, bool _padToWord if (_sourceType.isDynamicallySized()) { // change pointer to data part - m_context << Instruction::SWAP1 << u256(32) << Instruction::ADD; - m_context << Instruction::SWAP1; + m_context << InternalInstruction::SWAP1 << u256(32) << InternalInstruction::ADD; + m_context << InternalInstruction::SWAP1; } if (!_sourceType.isByteArrayOrString()) convertLengthToSize(_sourceType); // stack: - m_context << Instruction::DUP1 << Instruction::DUP4 << Instruction::DUP4; + m_context << InternalInstruction::DUP1 << InternalInstruction::DUP4 << InternalInstruction::DUP4; // We can resort to copying full 32 bytes only if // - the length is known to be a multiple of 32 or // - we will pad to full 32 bytes later anyway. @@ -375,7 +375,7 @@ void ArrayUtils::copyArrayToMemory(ArrayType const& _sourceType, bool _padToWord else utils.memoryCopy(); - m_context << Instruction::SWAP1 << Instruction::POP; + m_context << InternalInstruction::SWAP1 << InternalInstruction::POP; // stack: bool paddingNeeded = _padToWordBoundaries && _sourceType.isByteArrayOrString(); @@ -383,43 +383,43 @@ void ArrayUtils::copyArrayToMemory(ArrayType const& _sourceType, bool _padToWord if (paddingNeeded) { // stack: - m_context << Instruction::SWAP1 << Instruction::DUP2 << Instruction::ADD; + m_context << InternalInstruction::SWAP1 << InternalInstruction::DUP2 << InternalInstruction::ADD; // stack: - m_context << Instruction::SWAP1 << u256(31) << Instruction::AND; + m_context << InternalInstruction::SWAP1 << u256(31) << InternalInstruction::AND; // stack: evmasm::AssemblyItem skip = m_context.newTag(); if (_sourceType.isDynamicallySized()) { - m_context << Instruction::DUP1 << Instruction::ISZERO; + m_context << InternalInstruction::DUP1 << InternalInstruction::ISZERO; m_context.appendConditionalJumpTo(skip); } // round off, load from there. // stack - m_context << Instruction::DUP1 << Instruction::DUP3; - m_context << Instruction::SUB; + m_context << InternalInstruction::DUP1 << InternalInstruction::DUP3; + m_context << InternalInstruction::SUB; // stack: target+size remainder - m_context << Instruction::DUP1 << Instruction::MLOAD; + m_context << InternalInstruction::DUP1 << InternalInstruction::MLOAD; // Now we AND it with ~(2**(8 * (32 - remainder)) - 1) m_context << u256(1); - m_context << Instruction::DUP4 << u256(32) << Instruction::SUB; + m_context << InternalInstruction::DUP4 << u256(32) << InternalInstruction::SUB; // stack: ... 1 <32 - remainder> - m_context << u256(0x100) << Instruction::EXP << Instruction::SUB; - m_context << Instruction::NOT << Instruction::AND; + m_context << u256(0x100) << InternalInstruction::EXP << InternalInstruction::SUB; + m_context << InternalInstruction::NOT << InternalInstruction::AND; // stack: target+size remainder target+size-remainder - m_context << Instruction::DUP2 << Instruction::MSTORE; + m_context << InternalInstruction::DUP2 << InternalInstruction::MSTORE; // stack: target+size remainder target+size-remainder - m_context << u256(32) << Instruction::ADD; + m_context << u256(32) << InternalInstruction::ADD; // stack: target+size remainder - m_context << Instruction::SWAP2 << Instruction::POP; + m_context << InternalInstruction::SWAP2 << InternalInstruction::POP; if (_sourceType.isDynamicallySized()) m_context << skip.tag(); // stack - m_context << Instruction::POP; + m_context << InternalInstruction::POP; } else // stack: - m_context << Instruction::ADD; + m_context << InternalInstruction::ADD; } else { @@ -431,48 +431,48 @@ void ArrayUtils::copyArrayToMemory(ArrayType const& _sourceType, bool _padToWord retrieveLength(_sourceType); // stack here: memory_offset storage_offset length // jump to end if length is zero - m_context << Instruction::DUP1 << Instruction::ISZERO; + m_context << InternalInstruction::DUP1 << InternalInstruction::ISZERO; evmasm::AssemblyItem loopEnd = m_context.appendConditionalJump(); // Special case for tightly-stored byte arrays if (_sourceType.isByteArrayOrString()) { // stack here: memory_offset storage_offset length - m_context << Instruction::DUP1 << u256(31) << Instruction::LT; + m_context << InternalInstruction::DUP1 << u256(31) << InternalInstruction::LT; evmasm::AssemblyItem longByteArray = m_context.appendConditionalJump(); // store the short byte array (discard lower-order byte) - m_context << u256(0x100) << Instruction::DUP1; - m_context << Instruction::DUP4 << Instruction::SLOAD; - m_context << Instruction::DIV << Instruction::MUL; - m_context << Instruction::DUP4 << Instruction::MSTORE; + m_context << u256(0x100) << InternalInstruction::DUP1; + m_context << InternalInstruction::DUP4 << InternalInstruction::SLOAD; + m_context << InternalInstruction::DIV << InternalInstruction::MUL; + m_context << InternalInstruction::DUP4 << InternalInstruction::MSTORE; // stack here: memory_offset storage_offset length // add 32 or length to memory offset - m_context << Instruction::SWAP2; + m_context << InternalInstruction::SWAP2; if (_padToWordBoundaries) m_context << u256(32); else - m_context << Instruction::DUP3; - m_context << Instruction::ADD; - m_context << Instruction::SWAP2; + m_context << InternalInstruction::DUP3; + m_context << InternalInstruction::ADD; + m_context << InternalInstruction::SWAP2; m_context.appendJumpTo(loopEnd); m_context << longByteArray; } else // convert length to memory size - m_context << _sourceType.baseType()->memoryHeadSize() << Instruction::MUL; + m_context << _sourceType.baseType()->memoryHeadSize() << InternalInstruction::MUL; - m_context << Instruction::DUP3 << Instruction::ADD << Instruction::SWAP2; + m_context << InternalInstruction::DUP3 << InternalInstruction::ADD << InternalInstruction::SWAP2; if (_sourceType.isDynamicallySized()) { // actual array data is stored at KECCAK256(storage_offset) - m_context << Instruction::SWAP1; + m_context << InternalInstruction::SWAP1; utils.computeHashStatic(); - m_context << Instruction::SWAP1; + m_context << InternalInstruction::SWAP1; } // stack here: memory_end_offset storage_data_offset memory_offset bool haveByteOffset = !_sourceType.isByteArrayOrString() && storageBytes <= 16; if (haveByteOffset) - m_context << u256(0) << Instruction::SWAP1; + m_context << u256(0) << InternalInstruction::SWAP1; // stack here: memory_end_offset storage_data_offset [storage_byte_offset] memory_offset evmasm::AssemblyItem loopStart = m_context.newTag(); m_context << loopStart; @@ -480,20 +480,20 @@ void ArrayUtils::copyArrayToMemory(ArrayType const& _sourceType, bool _padToWord if (_sourceType.isByteArrayOrString()) { // Packed both in storage and memory. - m_context << Instruction::DUP2 << Instruction::SLOAD; - m_context << Instruction::DUP2 << Instruction::MSTORE; + m_context << InternalInstruction::DUP2 << InternalInstruction::SLOAD; + m_context << InternalInstruction::DUP2 << InternalInstruction::MSTORE; // increment storage_data_offset by 1 - m_context << Instruction::SWAP1 << u256(1) << Instruction::ADD; + m_context << InternalInstruction::SWAP1 << u256(1) << InternalInstruction::ADD; // increment memory offset by 32 - m_context << Instruction::SWAP1 << u256(32) << Instruction::ADD; + m_context << InternalInstruction::SWAP1 << u256(32) << InternalInstruction::ADD; } else { // stack here: memory_end_offset storage_data_offset [storage_byte_offset] memory_offset if (haveByteOffset) - m_context << Instruction::DUP3 << Instruction::DUP3; + m_context << InternalInstruction::DUP3 << InternalInstruction::DUP3; else - m_context << Instruction::DUP2 << u256(0); + m_context << InternalInstruction::DUP2 << u256(0); StorageItem(m_context, *_sourceType.baseType()).retrieveValue(SourceLocation(), true); if (auto baseArray = dynamic_cast(_sourceType.baseType())) copyArrayToMemory(*baseArray, _padToWordBoundaries); @@ -504,18 +504,18 @@ void ArrayUtils::copyArrayToMemory(ArrayType const& _sourceType, bool _padToWord incrementByteOffset(storageBytes, 2, 3); else { - m_context << Instruction::SWAP1; - m_context << storageSize << Instruction::ADD; - m_context << Instruction::SWAP1; + m_context << InternalInstruction::SWAP1; + m_context << storageSize << InternalInstruction::ADD; + m_context << InternalInstruction::SWAP1; } } // check for loop condition - m_context << Instruction::DUP1 << dupInstruction(haveByteOffset ? 5 : 4); - m_context << Instruction::GT; + m_context << InternalInstruction::DUP1 << dupInstruction(haveByteOffset ? 5 : 4); + m_context << InternalInstruction::GT; m_context.appendConditionalJumpTo(loopStart); // stack here: memory_end_offset storage_data_offset [storage_byte_offset] memory_offset if (haveByteOffset) - m_context << Instruction::SWAP1 << Instruction::POP; + m_context << InternalInstruction::SWAP1 << InternalInstruction::POP; if (!_sourceType.isByteArrayOrString()) { solAssert(_sourceType.calldataStride() % 32 == 0, ""); @@ -526,12 +526,12 @@ void ArrayUtils::copyArrayToMemory(ArrayType const& _sourceType, bool _padToWord // memory_end_offset - start is the actual length (we want to compute the ceil of). // memory_offset - start is its next multiple of 32, but it might be off by 32. // so we compute: memory_end_offset += (memory_offset - memory_end_offest) & 31 - m_context << Instruction::DUP3 << Instruction::SWAP1 << Instruction::SUB; - m_context << u256(31) << Instruction::AND; - m_context << Instruction::DUP3 << Instruction::ADD; - m_context << Instruction::SWAP2; + m_context << InternalInstruction::DUP3 << InternalInstruction::SWAP1 << InternalInstruction::SUB; + m_context << u256(31) << InternalInstruction::AND; + m_context << InternalInstruction::DUP3 << InternalInstruction::ADD; + m_context << InternalInstruction::SWAP2; } - m_context << loopEnd << Instruction::POP << Instruction::POP; + m_context << loopEnd << InternalInstruction::POP << InternalInstruction::POP; } } @@ -555,20 +555,20 @@ void ArrayUtils::clearArray(ArrayType const& _typeIn) const if (_type.baseType()->isValueType()) solAssert(_type.baseType()->storageSize() <= 1, "Invalid size for value type."); - _context << Instruction::POP; // remove byte offset + _context << InternalInstruction::POP; // remove byte offset if (_type.isDynamicallySized()) ArrayUtils(_context).clearDynamicArray(_type); else if (_type.length() == 0 || _type.baseType()->category() == Type::Category::Mapping) - _context << Instruction::POP; + _context << InternalInstruction::POP; else if (_type.baseType()->isValueType() && _type.storageSize() <= 5) { // unroll loop for small arrays @todo choose a good value // Note that we loop over storage slots here, not elements. for (unsigned i = 1; i < _type.storageSize(); ++i) _context - << u256(0) << Instruction::DUP2 << Instruction::SSTORE - << u256(1) << Instruction::ADD; - _context << u256(0) << Instruction::SWAP1 << Instruction::SSTORE; + << u256(0) << InternalInstruction::DUP2 << InternalInstruction::SSTORE + << u256(1) << InternalInstruction::ADD; + _context << u256(0) << InternalInstruction::SWAP1 << InternalInstruction::SSTORE; } else if (!_type.baseType()->isValueType() && _type.length() <= 4) { @@ -579,22 +579,22 @@ void ArrayUtils::clearArray(ArrayType const& _typeIn) const _context << u256(0); StorageItem(_context, *_type.baseType()).setToZero(SourceLocation(), false); _context - << Instruction::POP - << u256(_type.baseType()->storageSize()) << Instruction::ADD; + << InternalInstruction::POP + << u256(_type.baseType()->storageSize()) << InternalInstruction::ADD; } _context << u256(0); StorageItem(_context, *_type.baseType()).setToZero(SourceLocation(), true); } else { - _context << Instruction::DUP1 << _type.length(); + _context << InternalInstruction::DUP1 << _type.length(); ArrayUtils(_context).convertLengthToSize(_type); - _context << Instruction::ADD << Instruction::SWAP1; + _context << InternalInstruction::ADD << InternalInstruction::SWAP1; if (_type.baseType()->storageBytes() < 32) ArrayUtils(_context).clearStorageLoop(TypeProvider::uint256()); else ArrayUtils(_context).clearStorageLoop(_type.baseType()); - _context << Instruction::POP; + _context << InternalInstruction::POP; } solAssert(_context.stackHeight() == stackHeightStart - 2, ""); } @@ -609,15 +609,15 @@ void ArrayUtils::clearDynamicArray(ArrayType const& _type) const // fetch length retrieveLength(_type); // set length to zero - m_context << u256(0) << Instruction::DUP3 << Instruction::SSTORE; + m_context << u256(0) << InternalInstruction::DUP3 << InternalInstruction::SSTORE; // Special case: short byte arrays are stored togeher with their length evmasm::AssemblyItem endTag = m_context.newTag(); if (_type.isByteArrayOrString()) { // stack: ref old_length - m_context << Instruction::DUP1 << u256(31) << Instruction::LT; + m_context << InternalInstruction::DUP1 << u256(31) << InternalInstruction::LT; evmasm::AssemblyItem longByteArray = m_context.appendConditionalJump(); - m_context << Instruction::POP; + m_context << InternalInstruction::POP; m_context.appendJumpTo(endTag); m_context.adjustStackOffset(1); // needed because of jump m_context << longByteArray; @@ -625,11 +625,11 @@ void ArrayUtils::clearDynamicArray(ArrayType const& _type) const // stack: ref old_length convertLengthToSize(_type); // compute data positions - m_context << Instruction::SWAP1; + m_context << InternalInstruction::SWAP1; CompilerUtils(m_context).computeHashStatic(); // stack: len data_pos - m_context << Instruction::SWAP1 << Instruction::DUP2 << Instruction::ADD - << Instruction::SWAP1; + m_context << InternalInstruction::SWAP1 << InternalInstruction::DUP2 << InternalInstruction::ADD + << InternalInstruction::SWAP1; // stack: data_pos_end data_pos if (_type.storageStride() < 32) clearStorageLoop(TypeProvider::uint256()); @@ -637,7 +637,7 @@ void ArrayUtils::clearDynamicArray(ArrayType const& _type) const clearStorageLoop(_type.baseType()); // cleanup m_context << endTag; - m_context << Instruction::POP; + m_context << InternalInstruction::POP; } void ArrayUtils::resizeDynamicArray(ArrayType const& _typeIn) const @@ -670,13 +670,13 @@ void ArrayUtils::resizeDynamicArray(ArrayType const& _typeIn) const evmasm::AssemblyItem regularPath = _context.newTag(); // We start by a large case-distinction about the old and new length of the byte array. - _context << Instruction::DUP3 << Instruction::SLOAD; + _context << InternalInstruction::DUP3 << InternalInstruction::SLOAD; // stack: ref new_length current_length ref_value solAssert(_context.stackHeight() - stackHeightStart == 4 - 2, "3"); - _context << Instruction::DUP2 << u256(31) << Instruction::LT; + _context << InternalInstruction::DUP2 << u256(31) << InternalInstruction::LT; evmasm::AssemblyItem currentIsLong = _context.appendConditionalJump(); - _context << Instruction::DUP3 << u256(31) << Instruction::LT; + _context << InternalInstruction::DUP3 << u256(31) << InternalInstruction::LT; evmasm::AssemblyItem newIsLong = _context.appendConditionalJump(); // Here: short -> short @@ -684,17 +684,17 @@ void ArrayUtils::resizeDynamicArray(ArrayType const& _typeIn) const // Compute 1 << (256 - 8 * new_size) evmasm::AssemblyItem shortToShort = _context.newTag(); _context << shortToShort; - _context << Instruction::DUP3 << u256(8) << Instruction::MUL; - _context << u256(0x100) << Instruction::SUB; - _context << u256(2) << Instruction::EXP; + _context << InternalInstruction::DUP3 << u256(8) << InternalInstruction::MUL; + _context << u256(0x100) << InternalInstruction::SUB; + _context << u256(2) << InternalInstruction::EXP; // Divide and multiply by that value, clearing bits. - _context << Instruction::DUP1 << Instruction::SWAP2; - _context << Instruction::DIV << Instruction::MUL; + _context << InternalInstruction::DUP1 << InternalInstruction::SWAP2; + _context << InternalInstruction::DIV << InternalInstruction::MUL; // Insert 2*length. - _context << Instruction::DUP3 << Instruction::DUP1 << Instruction::ADD; - _context << Instruction::OR; + _context << InternalInstruction::DUP3 << InternalInstruction::DUP1 << InternalInstruction::ADD; + _context << InternalInstruction::OR; // Store. - _context << Instruction::DUP4 << Instruction::SSTORE; + _context << InternalInstruction::DUP4 << InternalInstruction::SSTORE; solAssert(_context.stackHeight() - stackHeightStart == 3 - 2, "3"); _context.appendJumpTo(resizeEnd); @@ -705,24 +705,24 @@ void ArrayUtils::resizeDynamicArray(ArrayType const& _typeIn) const // stack: ref new_length current_length ref_value solAssert(_context.stackHeight() - stackHeightStart == 4 - 2, "3"); // Zero out lower-order byte. - _context << u256(0xff) << Instruction::NOT << Instruction::AND; + _context << u256(0xff) << InternalInstruction::NOT << InternalInstruction::AND; // Store at data location. - _context << Instruction::DUP4; + _context << InternalInstruction::DUP4; CompilerUtils(_context).computeHashStatic(); - _context << Instruction::SSTORE; + _context << InternalInstruction::SSTORE; // stack: ref new_length current_length // Store new length: Compule 2*length + 1 and store it. - _context << Instruction::DUP2 << Instruction::DUP1 << Instruction::ADD; - _context << u256(1) << Instruction::ADD; + _context << InternalInstruction::DUP2 << InternalInstruction::DUP1 << InternalInstruction::ADD; + _context << u256(1) << InternalInstruction::ADD; // stack: ref new_length current_length 2*new_length+1 - _context << Instruction::DUP4 << Instruction::SSTORE; + _context << InternalInstruction::DUP4 << InternalInstruction::SSTORE; solAssert(_context.stackHeight() - stackHeightStart == 3 - 2, "3"); _context.appendJumpTo(resizeEnd); _context.adjustStackOffset(1); // we have to do that because of the jumps _context << currentIsLong; - _context << Instruction::DUP3 << u256(31) << Instruction::LT; + _context << InternalInstruction::DUP3 << u256(31) << InternalInstruction::LT; _context.appendConditionalJumpTo(regularPath); // Here: long -> short @@ -731,51 +731,51 @@ void ArrayUtils::resizeDynamicArray(ArrayType const& _typeIn) const // stack: ref new_length current_length ref_value solAssert(_context.stackHeight() - stackHeightStart == 4 - 2, "3"); - _context << Instruction::POP << Instruction::DUP3; + _context << InternalInstruction::POP << InternalInstruction::DUP3; CompilerUtils(_context).computeHashStatic(); - _context << Instruction::DUP1 << Instruction::SLOAD << Instruction::SWAP1; + _context << InternalInstruction::DUP1 << InternalInstruction::SLOAD << InternalInstruction::SWAP1; // stack: ref new_length current_length first_word data_location - _context << Instruction::DUP3; + _context << InternalInstruction::DUP3; ArrayUtils(_context).convertLengthToSize(_type); - _context << Instruction::DUP2 << Instruction::ADD << Instruction::SWAP1; + _context << InternalInstruction::DUP2 << InternalInstruction::ADD << InternalInstruction::SWAP1; // stack: ref new_length current_length first_word data_location_end data_location ArrayUtils(_context).clearStorageLoop(TypeProvider::uint256()); - _context << Instruction::POP; + _context << InternalInstruction::POP; // stack: ref new_length current_length first_word solAssert(_context.stackHeight() - stackHeightStart == 4 - 2, "3"); _context.appendJumpTo(shortToShort); _context << regularPath; // stack: ref new_length current_length ref_value - _context << Instruction::POP; + _context << InternalInstruction::POP; } // Change of length for a regular array (i.e. length at location, data at KECCAK256(location)). // stack: ref new_length old_length // store new length - _context << Instruction::DUP2; + _context << InternalInstruction::DUP2; if (_type.isByteArrayOrString()) // For a "long" byte array, store length as 2*length+1 - _context << Instruction::DUP1 << Instruction::ADD << u256(1) << Instruction::ADD; - _context << Instruction::DUP4 << Instruction::SSTORE; + _context << InternalInstruction::DUP1 << InternalInstruction::ADD << u256(1) << InternalInstruction::ADD; + _context << InternalInstruction::DUP4 << InternalInstruction::SSTORE; // skip if size is not reduced - _context << Instruction::DUP2 << Instruction::DUP2 - << Instruction::GT << Instruction::ISZERO; + _context << InternalInstruction::DUP2 << InternalInstruction::DUP2 + << InternalInstruction::GT << InternalInstruction::ISZERO; _context.appendConditionalJumpTo(resizeEnd); // size reduced, clear the end of the array // stack: ref new_length old_length ArrayUtils(_context).convertLengthToSize(_type); - _context << Instruction::DUP2; + _context << InternalInstruction::DUP2; ArrayUtils(_context).convertLengthToSize(_type); // stack: ref new_length old_size new_size // compute data positions - _context << Instruction::DUP4; + _context << InternalInstruction::DUP4; CompilerUtils(_context).computeHashStatic(); // stack: ref new_length old_size new_size data_pos - _context << Instruction::SWAP2 << Instruction::DUP3 << Instruction::ADD; + _context << InternalInstruction::SWAP2 << InternalInstruction::DUP3 << InternalInstruction::ADD; // stack: ref new_length data_pos new_size delete_end - _context << Instruction::SWAP2 << Instruction::ADD; + _context << InternalInstruction::SWAP2 << InternalInstruction::ADD; // stack: ref new_length delete_end delete_start if (_type.storageStride() < 32) ArrayUtils(_context).clearStorageLoop(TypeProvider::uint256()); @@ -784,7 +784,7 @@ void ArrayUtils::resizeDynamicArray(ArrayType const& _typeIn) const _context << resizeEnd; // cleanup - _context << Instruction::POP << Instruction::POP << Instruction::POP; + _context << InternalInstruction::POP << InternalInstruction::POP << InternalInstruction::POP; solAssert(_context.stackHeight() == stackHeightStart - 2, ""); } ); @@ -806,7 +806,7 @@ void ArrayUtils::incrementDynamicArraySize(ArrayType const& _type) const // lowest-order byte (we actually use a mask with fewer bits) must // be (31*2+0) = 62 - m_context << Instruction::DUP1 << Instruction::SLOAD << Instruction::DUP1; + m_context << InternalInstruction::DUP1 << InternalInstruction::SLOAD << InternalInstruction::DUP1; m_context.callYulFunction(m_context.utilFunctions().extractByteArrayLengthFunction(), 1, 1); m_context.appendInlineAssembly(R"({ // We have to copy if length is exactly 31, because that marks @@ -824,7 +824,7 @@ void ArrayUtils::incrementDynamicArraySize(ArrayType const& _type) const // return new length in ref ref := add(length, 1) })", {"ref", "data", "length"}); - m_context << Instruction::POP << Instruction::POP; + m_context << InternalInstruction::POP << InternalInstruction::POP; } else m_context.appendInlineAssembly(R"({ @@ -843,7 +843,7 @@ void ArrayUtils::popStorageArrayElement(ArrayType const& _type) const if (_type.isByteArrayOrString()) { - m_context << Instruction::DUP1 << Instruction::SLOAD << Instruction::DUP1; + m_context << InternalInstruction::DUP1 << InternalInstruction::SLOAD << InternalInstruction::DUP1; m_context.callYulFunction(m_context.utilFunctions().extractByteArrayLengthFunction(), 1, 1); util::Whiskers code(R"({ if iszero(length) { @@ -892,25 +892,25 @@ void ArrayUtils::popStorageArrayElement(ArrayType const& _type) const code("panicSelector", util::selectorFromSignatureU256("Panic(uint256)").str()); code("emptyArrayPop", to_string(unsigned(util::PanicCode::EmptyArrayPop))); m_context.appendInlineAssembly(code.render(), {"ref", "slot_value", "length"}); - m_context << Instruction::POP << Instruction::POP << Instruction::POP; + m_context << InternalInstruction::POP << InternalInstruction::POP << InternalInstruction::POP; } else { // stack: ArrayReference retrieveLength(_type); // stack: ArrayReference oldLength - m_context << Instruction::DUP1; + m_context << InternalInstruction::DUP1; // stack: ArrayReference oldLength oldLength - m_context << Instruction::ISZERO; + m_context << InternalInstruction::ISZERO; m_context.appendConditionalPanic(util::PanicCode::EmptyArrayPop); // Stack: ArrayReference oldLength - m_context << u256(1) << Instruction::SWAP1 << Instruction::SUB; + m_context << u256(1) << InternalInstruction::SWAP1 << InternalInstruction::SUB; // Stack ArrayReference newLength if (_type.baseType()->category() != Type::Category::Mapping) { - m_context << Instruction::DUP2 << Instruction::DUP2; + m_context << InternalInstruction::DUP2 << InternalInstruction::DUP2; // Stack ArrayReference newLength ArrayReference newLength; accessIndex(_type, false); // Stack: ArrayReference newLength storage_slot byte_offset @@ -918,7 +918,7 @@ void ArrayUtils::popStorageArrayElement(ArrayType const& _type) const } // Stack: ArrayReference newLength - m_context << Instruction::SWAP1 << Instruction::SSTORE; + m_context << InternalInstruction::SWAP1 << InternalInstruction::SSTORE; } } @@ -934,7 +934,7 @@ void ArrayUtils::clearStorageLoop(Type const* _type) const unsigned stackHeightStart = _context.stackHeight(); if (_type->category() == Type::Category::Mapping) { - _context << Instruction::POP; + _context << InternalInstruction::POP; return; } // stack: end_pos pos @@ -943,22 +943,22 @@ void ArrayUtils::clearStorageLoop(Type const* _type) const _context << loopStart; // check for loop condition _context << - Instruction::DUP1 << - Instruction::DUP3 << - Instruction::GT << - Instruction::ISZERO; + InternalInstruction::DUP1 << + InternalInstruction::DUP3 << + InternalInstruction::GT << + InternalInstruction::ISZERO; evmasm::AssemblyItem zeroLoopEnd = _context.newTag(); _context.appendConditionalJumpTo(zeroLoopEnd); // delete _context << u256(0); StorageItem(_context, *_type).setToZero(SourceLocation(), false); - _context << Instruction::POP; + _context << InternalInstruction::POP; // increment - _context << _type->storageSize() << Instruction::ADD; + _context << _type->storageSize() << InternalInstruction::ADD; _context.appendJumpTo(loopStart); // cleanup _context << zeroLoopEnd; - _context << Instruction::POP; + _context << InternalInstruction::POP; solAssert(_context.stackHeight() == stackHeightStart - 1, ""); } @@ -973,17 +973,17 @@ void ArrayUtils::convertLengthToSize(ArrayType const& _arrayType, bool _pad) con { unsigned baseBytes = _arrayType.baseType()->storageBytes(); if (baseBytes == 0) - m_context << Instruction::POP << u256(1); + m_context << InternalInstruction::POP << u256(1); else if (baseBytes <= 16) { unsigned itemsPerSlot = 32 / baseBytes; m_context - << u256(itemsPerSlot - 1) << Instruction::ADD - << u256(itemsPerSlot) << Instruction::SWAP1 << Instruction::DIV; + << u256(itemsPerSlot - 1) << InternalInstruction::ADD + << u256(itemsPerSlot) << InternalInstruction::SWAP1 << InternalInstruction::DIV; } } else - m_context << _arrayType.baseType()->storageSize() << Instruction::MUL; + m_context << _arrayType.baseType()->storageSize() << InternalInstruction::MUL; } else { @@ -993,12 +993,12 @@ void ArrayUtils::convertLengthToSize(ArrayType const& _arrayType, bool _pad) con m_context << _arrayType.memoryStride(); else m_context << _arrayType.calldataStride(); - m_context << Instruction::MUL; + m_context << InternalInstruction::MUL; } else if (_pad) - m_context << u256(31) << Instruction::ADD - << u256(32) << Instruction::DUP1 - << Instruction::SWAP2 << Instruction::DIV << Instruction::MUL; + m_context << u256(31) << InternalInstruction::ADD + << u256(32) << InternalInstruction::DUP1 + << InternalInstruction::SWAP2 << InternalInstruction::DIV << InternalInstruction::MUL; } } @@ -1015,10 +1015,10 @@ void ArrayUtils::retrieveLength(ArrayType const& _arrayType, unsigned _stackDept // length is stored on the stack break; case DataLocation::Memory: - m_context << Instruction::MLOAD; + m_context << InternalInstruction::MLOAD; break; case DataLocation::Storage: - m_context << Instruction::SLOAD; + m_context << InternalInstruction::SLOAD; if (_arrayType.isByteArrayOrString()) m_context.callYulFunction(m_context.utilFunctions().extractByteArrayLengthFunction(), 1, 1); break; @@ -1037,13 +1037,13 @@ void ArrayUtils::accessIndex(ArrayType const& _arrayType, bool _doBoundsCheck, b ArrayUtils::retrieveLength(_arrayType, 1); // Stack: ref [length] index length // check out-of-bounds access - m_context << Instruction::DUP2 << Instruction::LT << Instruction::ISZERO; + m_context << InternalInstruction::DUP2 << InternalInstruction::LT << InternalInstruction::ISZERO; // out-of-bounds access throws exception m_context.appendConditionalPanic(util::PanicCode::ArrayOutOfBounds); } if (location == DataLocation::CallData && _arrayType.isDynamicallySized()) // remove length if present - m_context << Instruction::SWAP1 << Instruction::POP; + m_context << InternalInstruction::SWAP1 << InternalInstruction::POP; // stack: switch (location) @@ -1051,46 +1051,46 @@ void ArrayUtils::accessIndex(ArrayType const& _arrayType, bool _doBoundsCheck, b case DataLocation::Memory: // stack: if (!_arrayType.isByteArrayOrString()) - m_context << u256(_arrayType.memoryHeadSize()) << Instruction::MUL; + m_context << u256(_arrayType.memoryHeadSize()) << InternalInstruction::MUL; if (_arrayType.isDynamicallySized()) - m_context << u256(32) << Instruction::ADD; + m_context << u256(32) << InternalInstruction::ADD; if (_keepReference) - m_context << Instruction::DUP2; - m_context << Instruction::ADD; + m_context << InternalInstruction::DUP2; + m_context << InternalInstruction::ADD; break; case DataLocation::CallData: if (!_arrayType.isByteArrayOrString()) { m_context << _arrayType.calldataStride(); - m_context << Instruction::MUL; + m_context << InternalInstruction::MUL; } // stack: if (_keepReference) - m_context << Instruction::DUP2; - m_context << Instruction::ADD; + m_context << InternalInstruction::DUP2; + m_context << InternalInstruction::ADD; break; case DataLocation::Storage: { if (_keepReference) - m_context << Instruction::DUP2; + m_context << InternalInstruction::DUP2; else - m_context << Instruction::SWAP1; + m_context << InternalInstruction::SWAP1; // stack: [] evmasm::AssemblyItem endTag = m_context.newTag(); if (_arrayType.isByteArrayOrString()) { // Special case of short byte arrays. - m_context << Instruction::SWAP1; - m_context << Instruction::DUP2 << Instruction::SLOAD; - m_context << u256(1) << Instruction::AND << Instruction::ISZERO; + m_context << InternalInstruction::SWAP1; + m_context << InternalInstruction::DUP2 << InternalInstruction::SLOAD; + m_context << u256(1) << InternalInstruction::AND << InternalInstruction::ISZERO; // No action needed for short byte arrays. m_context.appendConditionalJumpTo(endTag); - m_context << Instruction::SWAP1; + m_context << InternalInstruction::SWAP1; } if (_arrayType.isDynamicallySized()) CompilerUtils(m_context).computeHashStatic(); - m_context << Instruction::SWAP1; + m_context << InternalInstruction::SWAP1; if (_arrayType.baseType()->storageBytes() <= 16) { // stack: @@ -1099,22 +1099,22 @@ void ArrayUtils::accessIndex(ArrayType const& _arrayType, bool _doBoundsCheck, b unsigned byteSize = _arrayType.baseType()->storageBytes(); solAssert(byteSize != 0, ""); unsigned itemsPerSlot = 32 / byteSize; - m_context << u256(itemsPerSlot) << Instruction::SWAP2; + m_context << u256(itemsPerSlot) << InternalInstruction::SWAP2; // stack: itemsPerSlot index data_ref m_context - << Instruction::DUP3 << Instruction::DUP3 - << Instruction::DIV << Instruction::ADD + << InternalInstruction::DUP3 << InternalInstruction::DUP3 + << InternalInstruction::DIV << InternalInstruction::ADD // stack: itemsPerSlot index (data_ref + index / itemsPerSlot) - << Instruction::SWAP2 << Instruction::SWAP1 - << Instruction::MOD; + << InternalInstruction::SWAP2 << InternalInstruction::SWAP1 + << InternalInstruction::MOD; if (byteSize != 1) - m_context << u256(byteSize) << Instruction::MUL; + m_context << u256(byteSize) << InternalInstruction::MUL; } else { if (_arrayType.baseType()->storageSize() != 1) - m_context << _arrayType.baseType()->storageSize() << Instruction::MUL; - m_context << Instruction::ADD << u256(0); + m_context << _arrayType.baseType()->storageSize() << InternalInstruction::MUL; + m_context << InternalInstruction::ADD << u256(0); } m_context << endTag; break; @@ -1179,26 +1179,26 @@ void ArrayUtils::incrementByteOffset(unsigned _byteSize, unsigned _byteOffsetPos // } if (_byteOffsetPosition > 1) m_context << swapInstruction(_byteOffsetPosition - 1); - m_context << u256(_byteSize) << Instruction::ADD; + m_context << u256(_byteSize) << InternalInstruction::ADD; if (_byteOffsetPosition > 1) m_context << swapInstruction(_byteOffsetPosition - 1); // compute, X := (byteOffset + byteSize - 1) / 32, should be 1 iff byteOffset + bytesize > 32 m_context << u256(32) << dupInstruction(1 + _byteOffsetPosition) << u256(_byteSize - 1) - << Instruction::ADD << Instruction::DIV; + << InternalInstruction::ADD << InternalInstruction::DIV; // increment storage offset if X == 1 (just add X to it) // stack: X m_context << swapInstruction(_storageOffsetPosition) << dupInstruction(_storageOffsetPosition + 1) - << Instruction::ADD << swapInstruction(_storageOffsetPosition); + << InternalInstruction::ADD << swapInstruction(_storageOffsetPosition); // stack: X // set source_byte_offset to zero if X == 1 (using source_byte_offset *= 1 - X) - m_context << u256(1) << Instruction::SUB; + m_context << u256(1) << InternalInstruction::SUB; // stack: 1 - X if (_byteOffsetPosition == 1) - m_context << Instruction::MUL; + m_context << InternalInstruction::MUL; else m_context - << dupInstruction(_byteOffsetPosition + 1) << Instruction::MUL - << swapInstruction(_byteOffsetPosition) << Instruction::POP; + << dupInstruction(_byteOffsetPosition + 1) << InternalInstruction::MUL + << swapInstruction(_byteOffsetPosition) << InternalInstruction::POP; } diff --git a/libsolidity/codegen/CompilerContext.cpp b/libsolidity/codegen/CompilerContext.cpp index 948502e69..80caa2cf5 100644 --- a/libsolidity/codegen/CompilerContext.cpp +++ b/libsolidity/codegen/CompilerContext.cpp @@ -329,7 +329,7 @@ pair CompilerContext::storageLocationOfVariable(Declaration cons CompilerContext& CompilerContext::appendJump(evmasm::AssemblyItem::JumpType _jumpType) { - evmasm::AssemblyItem item(Instruction::JUMP); + evmasm::AssemblyItem item(InternalInstruction::JUMP); item.setJumpType(_jumpType); return *this << item; } @@ -342,7 +342,7 @@ CompilerContext& CompilerContext::appendPanic(util::PanicCode _code) CompilerContext& CompilerContext::appendConditionalPanic(util::PanicCode _code) { - *this << Instruction::ISZERO; + *this << InternalInstruction::ISZERO; evmasm::AssemblyItem afterTag = appendConditionalJump(); appendPanic(_code); *this << afterTag; @@ -366,7 +366,7 @@ CompilerContext& CompilerContext::appendConditionalRevert(bool _forwardReturnDat })", {"condition"}); else appendInlineAssembly("{ if condition { " + revertReasonIfDebug(_message) + " } }", {"condition"}); - *this << Instruction::POP; + *this << InternalInstruction::POP; return *this; } @@ -430,7 +430,7 @@ void CompilerContext::appendInlineAssembly( else { _assembly.appendInstruction(swapInstruction(static_cast(stackDiff))); - _assembly.appendInstruction(Instruction::POP); + _assembly.appendInstruction(InternalInstruction::POP); } }; diff --git a/libsolidity/codegen/CompilerContext.h b/libsolidity/codegen/CompilerContext.h index a796ac60b..78e1b786c 100644 --- a/libsolidity/codegen/CompilerContext.h +++ b/libsolidity/codegen/CompilerContext.h @@ -251,7 +251,7 @@ public: /// Append elements to the current instruction list and adjust @a m_stackOffset. CompilerContext& operator<<(evmasm::AssemblyItem const& _item) { m_asm->append(_item); return *this; } - CompilerContext& operator<<(evmasm::Instruction _instruction) { m_asm->append(_instruction); return *this; } + CompilerContext& operator<<(evmasm::InternalInstruction _instruction) { m_asm->append(_instruction); return *this; } CompilerContext& operator<<(u256 const& _value) { m_asm->append(_value); return *this; } CompilerContext& operator<<(bytes const& _data) { m_asm->append(_data); return *this; } diff --git a/libsolidity/codegen/CompilerUtils.cpp b/libsolidity/codegen/CompilerUtils.cpp index 783a7b1a4..c748e219f 100644 --- a/libsolidity/codegen/CompilerUtils.cpp +++ b/libsolidity/codegen/CompilerUtils.cpp @@ -62,33 +62,33 @@ void CompilerUtils::initialiseFreeMemoryPointer() void CompilerUtils::fetchFreeMemoryPointer() { - m_context << u256(freeMemoryPointer) << Instruction::MLOAD; + m_context << u256(freeMemoryPointer) << InternalInstruction::MLOAD; } void CompilerUtils::storeFreeMemoryPointer() { - m_context << u256(freeMemoryPointer) << Instruction::MSTORE; + m_context << u256(freeMemoryPointer) << InternalInstruction::MSTORE; } void CompilerUtils::allocateMemory() { fetchFreeMemoryPointer(); - m_context << Instruction::SWAP1 << Instruction::DUP2 << Instruction::ADD; + m_context << InternalInstruction::SWAP1 << InternalInstruction::DUP2 << InternalInstruction::ADD; storeFreeMemoryPointer(); } void CompilerUtils::allocateMemory(u256 const& size) { fetchFreeMemoryPointer(); - m_context << Instruction::DUP1 << size << Instruction::ADD; + m_context << InternalInstruction::DUP1 << size << InternalInstruction::ADD; storeFreeMemoryPointer(); } void CompilerUtils::toSizeAfterFreeMemoryPointer() { fetchFreeMemoryPointer(); - m_context << Instruction::DUP1 << Instruction::SWAP2 << Instruction::SUB; - m_context << Instruction::SWAP1; + m_context << InternalInstruction::DUP1 << InternalInstruction::SWAP2 << InternalInstruction::SUB; + m_context << InternalInstruction::SWAP1; } void CompilerUtils::revertWithStringData(Type const& _argumentType) @@ -96,12 +96,12 @@ void CompilerUtils::revertWithStringData(Type const& _argumentType) solAssert(_argumentType.isImplicitlyConvertibleTo(*TypeProvider::fromElementaryTypeName("string memory"))); fetchFreeMemoryPointer(); m_context << util::selectorFromSignatureU256("Error(string)"); - m_context << Instruction::DUP2 << Instruction::MSTORE; - m_context << u256(4) << Instruction::ADD; + m_context << InternalInstruction::DUP2 << InternalInstruction::MSTORE; + m_context << u256(4) << InternalInstruction::ADD; // Stack: abiEncode({&_argumentType}, {TypeProvider::array(DataLocation::Memory, true)}); toSizeAfterFreeMemoryPointer(); - m_context << Instruction::REVERT; + m_context << InternalInstruction::REVERT; } void CompilerUtils::revertWithError( @@ -112,19 +112,19 @@ void CompilerUtils::revertWithError( { fetchFreeMemoryPointer(); m_context << util::selectorFromSignatureU256(_signature); - m_context << Instruction::DUP2 << Instruction::MSTORE; - m_context << u256(4) << Instruction::ADD; + m_context << InternalInstruction::DUP2 << InternalInstruction::MSTORE; + m_context << u256(4) << InternalInstruction::ADD; // Stack: abiEncode(_argumentTypes, _parameterTypes); toSizeAfterFreeMemoryPointer(); - m_context << Instruction::REVERT; + m_context << InternalInstruction::REVERT; } void CompilerUtils::returnDataToArray() { if (m_context.evmVersion().supportsReturndata()) { - m_context << Instruction::RETURNDATASIZE; + m_context << InternalInstruction::RETURNDATASIZE; m_context.appendInlineAssembly(R"({ switch v case 0 { v := 0x60 @@ -142,7 +142,7 @@ void CompilerUtils::returnDataToArray() void CompilerUtils::accessCalldataTail(Type const& _type) { - m_context << Instruction::SWAP1; + m_context << InternalInstruction::SWAP1; m_context.callYulFunction( m_context.utilFunctions().accessCalldataTailFunction(_type), 2, @@ -170,7 +170,7 @@ void CompilerUtils::loadFromMemoryDynamic( ) { if (_keepUpdatedMemoryOffset) - m_context << Instruction::DUP1; + m_context << InternalInstruction::DUP1; if (auto arrayType = dynamic_cast(&_type)) { @@ -178,7 +178,7 @@ void CompilerUtils::loadFromMemoryDynamic( solAssert(!_fromCalldata); solAssert(_padToWordBoundaries); if (_keepUpdatedMemoryOffset) - m_context << arrayType->memoryDataSize() << Instruction::ADD; + m_context << arrayType->memoryDataSize() << InternalInstruction::ADD; } else { @@ -187,7 +187,7 @@ void CompilerUtils::loadFromMemoryDynamic( { // update memory counter moveToStackTop(_type.sizeOnStack()); - m_context << u256(numBytes) << Instruction::ADD; + m_context << u256(numBytes) << InternalInstruction::ADD; } } } @@ -196,7 +196,7 @@ void CompilerUtils::storeInMemory(unsigned _offset) { unsigned numBytes = prepareMemoryStore(*TypeProvider::uint256(), true); if (numBytes > 0) - m_context << u256(_offset) << Instruction::MSTORE; + m_context << u256(_offset) << InternalInstruction::MSTORE; } void CompilerUtils::storeInMemoryDynamic(Type const& _type, bool _padToWordBoundaries, bool _cleanup) @@ -212,13 +212,13 @@ void CompilerUtils::storeInMemoryDynamic(Type const& _type, bool _padToWordBound } else if (auto str = dynamic_cast(&_type)) { - m_context << Instruction::DUP1; + m_context << InternalInstruction::DUP1; storeStringData(bytesConstRef(str->value())); if (_padToWordBoundaries) m_context << u256(max(32, ((str->value().size() + 31) / 32) * 32)); else m_context << u256(str->value().size()); - m_context << Instruction::ADD; + m_context << InternalInstruction::ADD; } else if ( _type.category() == Type::Category::Function && @@ -226,14 +226,14 @@ void CompilerUtils::storeInMemoryDynamic(Type const& _type, bool _padToWordBound ) { combineExternalFunctionType(true); - m_context << Instruction::DUP2 << Instruction::MSTORE; - m_context << u256(_padToWordBoundaries ? 32 : 24) << Instruction::ADD; + m_context << InternalInstruction::DUP2 << InternalInstruction::MSTORE; + m_context << u256(_padToWordBoundaries ? 32 : 24) << InternalInstruction::ADD; } else if (_type.isValueType()) { unsigned numBytes = prepareMemoryStore(_type, _padToWordBoundaries, _cleanup); - m_context << Instruction::DUP2 << Instruction::MSTORE; - m_context << u256(numBytes) << Instruction::ADD; + m_context << InternalInstruction::DUP2 << InternalInstruction::MSTORE; + m_context << u256(numBytes) << InternalInstruction::ADD; } else // Should never happen { @@ -268,12 +268,12 @@ void CompilerUtils::abiDecode(TypePointers const& _typeParameters, bool _fromMem templ("revertString", m_context.revertReasonIfDebug("Calldata too short")); m_context.appendInlineAssembly(templ.render(), {"len"}); - m_context << Instruction::DUP2 << Instruction::ADD; - m_context << Instruction::SWAP1; + m_context << InternalInstruction::DUP2 << InternalInstruction::ADD; + m_context << InternalInstruction::SWAP1; /// Stack: // Retain the offset pointer as base_offset, the point from which the data offsets are computed. - m_context << Instruction::DUP1; + m_context << InternalInstruction::DUP1; for (Type const* parameterType: _typeParameters) { // stack: v1 v2 ... v(k-1) input_end base_offset current_offset @@ -295,14 +295,14 @@ void CompilerUtils::abiDecode(TypePointers const& _typeParameters, bool _fromMem if (arrayType.isDynamicallySized()) { // compute data pointer - m_context << Instruction::DUP1 << Instruction::MLOAD; + m_context << InternalInstruction::DUP1 << InternalInstruction::MLOAD; // stack: v1 v2 ... v(k-1) input_end base_offset current_offset data_offset fetchFreeMemoryPointer(); // stack: v1 v2 ... v(k-1) input_end base_offset current_offset data_offset dstmem moveIntoStack(4); // stack: v1 v2 ... v(k-1) dstmem input_end base_offset current_offset data_offset - m_context << Instruction::DUP5; + m_context << InternalInstruction::DUP5; // stack: v1 v2 ... v(k-1) dstmem input_end base_offset current_offset data_offset dstmem // Check that the data pointer is valid and that length times @@ -327,19 +327,19 @@ void CompilerUtils::abiDecode(TypePointers const& _typeParameters, bool _fromMem templ("revertStringLength", m_context.revertReasonIfDebug("ABI memory decoding: invalid data length")); m_context.appendInlineAssembly(templ.render(), {"input_end", "base_offset", "offset", "ptr", "dst"}); // stack: v1 v2 ... v(k-1) dstmem input_end base_offset current_offset data_ptr dstdata - m_context << Instruction::SWAP1; + m_context << InternalInstruction::SWAP1; // stack: v1 v2 ... v(k-1) dstmem input_end base_offset current_offset dstdata data_ptr ArrayUtils(m_context).copyArrayToMemory(arrayType, true); // stack: v1 v2 ... v(k-1) dstmem input_end base_offset current_offset mem_end storeFreeMemoryPointer(); - m_context << u256(0x20) << Instruction::ADD; + m_context << u256(0x20) << InternalInstruction::ADD; } else { // Size has already been checked for this one. moveIntoStack(2); - m_context << Instruction::DUP3; - m_context << u256(arrayType.calldataHeadSize()) << Instruction::ADD; + m_context << InternalInstruction::DUP3; + m_context << u256(arrayType.calldataHeadSize()) << InternalInstruction::ADD; } } else @@ -350,7 +350,7 @@ void CompilerUtils::abiDecode(TypePointers const& _typeParameters, bool _fromMem { // put on stack: data_pointer length loadFromMemoryDynamic(*TypeProvider::uint256(), !_fromMemory); - m_context << Instruction::SWAP1; + m_context << InternalInstruction::SWAP1; // stack: input_end base_offset next_pointer data_offset m_context.appendInlineAssembly(Whiskers(R"({ if gt(data_offset, 0x100000000) { } @@ -358,7 +358,7 @@ void CompilerUtils::abiDecode(TypePointers const& _typeParameters, bool _fromMem // TODO add test ("revertString", m_context.revertReasonIfDebug("ABI calldata decoding: invalid data offset")) .render(), {"data_offset"}); - m_context << Instruction::DUP3 << Instruction::ADD; + m_context << InternalInstruction::DUP3 << InternalInstruction::ADD; // stack: input_end base_offset next_pointer array_head_ptr m_context.appendInlineAssembly(Whiskers(R"({ if gt(add(array_head_ptr, 0x20), input_end) { } @@ -369,7 +369,7 @@ void CompilerUtils::abiDecode(TypePointers const& _typeParameters, bool _fromMem // retrieve length loadFromMemoryDynamic(*TypeProvider::uint256(), !_fromMemory, true); // stack: input_end base_offset next_pointer array_length data_pointer - m_context << Instruction::SWAP2; + m_context << InternalInstruction::SWAP2; // stack: input_end base_offset data_pointer array_length next_pointer m_context.appendInlineAssembly(Whiskers(R"({ if or( @@ -384,8 +384,8 @@ void CompilerUtils::abiDecode(TypePointers const& _typeParameters, bool _fromMem { // size has already been checked // stack: input_end base_offset data_offset - m_context << Instruction::DUP1; - m_context << u256(calldataType->calldataHeadSize()) << Instruction::ADD; + m_context << InternalInstruction::DUP1; + m_context << u256(calldataType->calldataHeadSize()) << InternalInstruction::ADD; } if (arrayType.location() == DataLocation::Memory) { @@ -400,10 +400,10 @@ void CompilerUtils::abiDecode(TypePointers const& _typeParameters, bool _fromMem // move input_end up // stack: input_end base_offset calldata_ref [length] next_calldata moveToStackTop(2 + arrayType.sizeOnStack()); - m_context << Instruction::SWAP1; + m_context << InternalInstruction::SWAP1; // stack: base_offset calldata_ref [length] input_end next_calldata moveToStackTop(2 + arrayType.sizeOnStack()); - m_context << Instruction::SWAP1; + m_context << InternalInstruction::SWAP1; // stack: calldata_ref [length] input_end base_offset next_calldata } } @@ -460,7 +460,7 @@ void CompilerUtils::encodeToMemory( // of the nth dynamic parameter, which is filled once the dynamic parts are processed. // store memory start pointer - m_context << Instruction::DUP1; + m_context << InternalInstruction::DUP1; unsigned argSize = CompilerUtils::sizeOnStack(_givenTypes); unsigned stackPos = 0; // advances through the argument values @@ -472,7 +472,7 @@ void CompilerUtils::encodeToMemory( if (targetType->isDynamicallySized() && !_copyDynamicDataInPlace) { // leave end_of_mem as dyn head pointer - m_context << Instruction::DUP1 << u256(32) << Instruction::ADD; + m_context << InternalInstruction::DUP1 << u256(32) << InternalInstruction::ADD; dynPointers++; assertThrow( (argSize + dynPointers) < 16, @@ -540,10 +540,10 @@ void CompilerUtils::encodeToMemory( StackTooDeepError, util::stackTooDeepString ); - m_context << dupInstruction(2 + dynPointers) << Instruction::DUP2; - m_context << Instruction::SUB; + m_context << dupInstruction(2 + dynPointers) << InternalInstruction::DUP2; + m_context << InternalInstruction::SUB; m_context << dupInstruction(2 + dynPointers - thisDynPointer); - m_context << Instruction::MSTORE; + m_context << InternalInstruction::MSTORE; // stack: ... if (_givenTypes[i]->category() == Type::Category::StringLiteral) { @@ -589,7 +589,7 @@ void CompilerUtils::encodeToMemory( storeInMemoryDynamic(*TypeProvider::uint256(), true); // stack: ... // copy the new memory pointer - m_context << swapInstruction(arrayType->sizeOnStack() + 1) << Instruction::POP; + m_context << swapInstruction(arrayType->sizeOnStack() + 1) << InternalInstruction::POP; // stack: ... // copy data part ArrayUtils(m_context).copyArrayToMemory(*arrayType, _padToWordBoundaries); @@ -628,8 +628,8 @@ void CompilerUtils::abiEncodeV2( void CompilerUtils::abiDecodeV2(TypePointers const& _parameterTypes, bool _fromMemory) { // stack: [stack top] - m_context << Instruction::DUP2 << Instruction::ADD; - m_context << Instruction::SWAP1; + m_context << InternalInstruction::DUP2 << InternalInstruction::ADD; + m_context << InternalInstruction::SWAP1; // stack: string decoderName = m_context.abiFunctions().tupleDecoder(_parameterTypes, _fromMemory); m_context.callYulFunction(decoderName, 2, sizeOnStack(_parameterTypes)); @@ -655,12 +655,12 @@ void CompilerUtils::zeroInitialiseMemoryArray(ArrayType const& _type) m_context << repeat; pushZeroValue(*_type.baseType()); storeInMemoryDynamic(*_type.baseType()); - m_context << Instruction::SWAP1 << u256(1) << Instruction::SWAP1; - m_context << Instruction::SUB << Instruction::SWAP1; - m_context << Instruction::DUP2; + m_context << InternalInstruction::SWAP1 << u256(1) << InternalInstruction::SWAP1; + m_context << InternalInstruction::SUB << InternalInstruction::SWAP1; + m_context << InternalInstruction::DUP2; m_context.appendConditionalJumpTo(repeat); } - m_context << Instruction::SWAP1 << Instruction::POP; + m_context << InternalInstruction::SWAP1 << InternalInstruction::POP; } void CompilerUtils::memoryCopy32() @@ -676,7 +676,7 @@ void CompilerUtils::memoryCopy32() )", { "len", "dst", "src" } ); - m_context << Instruction::POP << Instruction::POP << Instruction::POP; + m_context << InternalInstruction::POP << InternalInstruction::POP << InternalInstruction::POP; } void CompilerUtils::memoryCopy() @@ -705,7 +705,7 @@ void CompilerUtils::memoryCopy() )", { "len", "dst", "src" } ); - m_context << Instruction::POP << Instruction::POP << Instruction::POP; + m_context << InternalInstruction::POP << InternalInstruction::POP << InternalInstruction::POP; } void CompilerUtils::splitExternalFunctionType(bool _leftAligned) @@ -714,29 +714,29 @@ void CompilerUtils::splitExternalFunctionType(bool _leftAligned) // address (right aligned), function identifier (right aligned) if (_leftAligned) { - m_context << Instruction::DUP1; + m_context << InternalInstruction::DUP1; rightShiftNumberOnStack(64 + 32); //
- m_context << Instruction::SWAP1; + m_context << InternalInstruction::SWAP1; rightShiftNumberOnStack(64); } else { - m_context << Instruction::DUP1; + m_context << InternalInstruction::DUP1; rightShiftNumberOnStack(32); - m_context << ((u256(1) << 160) - 1) << Instruction::AND << Instruction::SWAP1; + m_context << ((u256(1) << 160) - 1) << InternalInstruction::AND << InternalInstruction::SWAP1; } - m_context << u256(0xffffffffUL) << Instruction::AND; + m_context << u256(0xffffffffUL) << InternalInstruction::AND; } void CompilerUtils::combineExternalFunctionType(bool _leftAligned) { //
- m_context << u256(0xffffffffUL) << Instruction::AND << Instruction::SWAP1; + m_context << u256(0xffffffffUL) << InternalInstruction::AND << InternalInstruction::SWAP1; if (!_leftAligned) - m_context << ((u256(1) << 160) - 1) << Instruction::AND; + m_context << ((u256(1) << 160) - 1) << InternalInstruction::AND; leftShiftNumberOnStack(32); - m_context << Instruction::OR; + m_context << InternalInstruction::OR; if (_leftAligned) leftShiftNumberOnStack(64); } @@ -752,7 +752,7 @@ void CompilerUtils::pushCombinedFunctionEntryLabel(Declaration const& _function, if (_runtimeOnly) m_context << rtc->functionEntryLabel(_function).toSubAssemblyTag(m_context.runtimeSub()) << - Instruction::OR; + InternalInstruction::OR; } } @@ -839,12 +839,12 @@ void CompilerUtils::convertType( solAssert(targetTypeCategory == Type::Category::FixedBytes, "Invalid type conversion requested."); FixedBytesType const& targetType = dynamic_cast(_targetType); if (typeOnStack.numBytes() == 0 || targetType.numBytes() == 0) - m_context << Instruction::POP << u256(0); + m_context << InternalInstruction::POP << u256(0); else if (targetType.numBytes() > typeOnStack.numBytes() || _cleanupNeeded) { unsigned bytes = min(typeOnStack.numBytes(), targetType.numBytes()); m_context << ((u256(1) << (256 - bytes * 8)) - 1); - m_context << Instruction::NOT << Instruction::AND; + m_context << InternalInstruction::NOT << InternalInstruction::AND; } } break; @@ -855,7 +855,7 @@ void CompilerUtils::convertType( { EnumType const& enumType = dynamic_cast(_typeOnStack); solAssert(enumType.numberOfMembers() > 0, "empty enum should have caused a parser error."); - m_context << u256(enumType.numberOfMembers() - 1) << Instruction::DUP2 << Instruction::GT; + m_context << u256(enumType.numberOfMembers() - 1) << InternalInstruction::DUP2 << InternalInstruction::GT; if (_asPartOfArgumentDecoding) m_context.appendConditionalRevert(false, "Enum out of range"); else @@ -897,7 +897,7 @@ void CompilerUtils::convertType( convertType(_typeOnStack, *_typeOnStack.mobileType(), true); EnumType const& enumType = dynamic_cast(_targetType); solAssert(enumType.numberOfMembers() > 0, "empty enum should have caused a parser error."); - m_context << u256(enumType.numberOfMembers() - 1) << Instruction::DUP2 << Instruction::GT; + m_context << u256(enumType.numberOfMembers() - 1) << InternalInstruction::DUP2 << InternalInstruction::GT; m_context.appendConditionalPanic(util::PanicCode::EnumConversionError); enumOverflowCheckPending = false; } @@ -951,7 +951,7 @@ void CompilerUtils::convertType( if (targetType.numBits() < 256) m_context << ((u256(1) << targetType.numBits()) - 1) - << Instruction::AND; + << InternalInstruction::AND; chopSignBitsPending = false; } } @@ -975,7 +975,7 @@ void CompilerUtils::convertType( size_t storageSize = 32 + ((data.size() + 31) / 32) * 32; allocateMemory(storageSize); // stack: mempos - m_context << Instruction::DUP1 << u256(data.size()); + m_context << InternalInstruction::DUP1 << u256(data.size()); storeInMemoryDynamic(*TypeProvider::uint256()); // stack: mempos datapos storeStringData(data); @@ -1001,7 +1001,7 @@ void CompilerUtils::convertType( bool fromCalldata = typeOnStack.dataStoredIn(DataLocation::CallData); solAssert(typeOnStack.sizeOnStack() == (fromCalldata ? 2 : 1)); if (fromCalldata) - m_context << Instruction::SWAP1; + m_context << InternalInstruction::SWAP1; m_context.callYulFunction( m_context.utilFunctions().bytesToFixedBytesConversionFunction( @@ -1039,7 +1039,7 @@ void CompilerUtils::convertType( // stack: offset length(optional in case of dynamically sized array) solAssert(typeOnStack.sizeOnStack() == (typeOnStack.isDynamicallySized() ? 2 : 1)); if (typeOnStack.isDynamicallySized()) - m_context << Instruction::SWAP1; + m_context << InternalInstruction::SWAP1; m_context.callYulFunction( m_context.utilFunctions().conversionFunction(typeOnStack, targetType), @@ -1055,18 +1055,18 @@ void CompilerUtils::convertType( // allocate memory // stack: (variably sized) - m_context << Instruction::DUP1; + m_context << InternalInstruction::DUP1; ArrayUtils(m_context).convertLengthToSize(targetType, true); // stack: (variably sized) if (targetType.isDynamicallySized()) - m_context << u256(0x20) << Instruction::ADD; + m_context << u256(0x20) << InternalInstruction::ADD; allocateMemory(); // stack: (variably sized) - m_context << Instruction::DUP1; + m_context << InternalInstruction::DUP1; moveIntoStack(2 + stackSize); if (targetType.isDynamicallySized()) { - m_context << Instruction::DUP2; + m_context << InternalInstruction::DUP2; storeInMemoryDynamic(*TypeProvider::uint256()); } // stack: (variably sized) @@ -1077,12 +1077,12 @@ void CompilerUtils::convertType( } else { - m_context << u256(0) << Instruction::SWAP1; + m_context << u256(0) << InternalInstruction::SWAP1; // stack: (variably sized) auto repeat = m_context.newTag(); m_context << repeat; - m_context << Instruction::DUP3 << Instruction::DUP3; - m_context << Instruction::LT << Instruction::ISZERO; + m_context << InternalInstruction::DUP3 << InternalInstruction::DUP3; + m_context << InternalInstruction::LT << InternalInstruction::ISZERO; auto loopEnd = m_context.appendConditionalJump(); copyToStackTop(3 + stackSize, stackSize); copyToStackTop(2 + stackSize, 1); @@ -1091,11 +1091,11 @@ void CompilerUtils::convertType( StorageItem(m_context, *typeOnStack.baseType()).retrieveValue(SourceLocation(), true); convertType(*typeOnStack.baseType(), *targetType.baseType(), _cleanupNeeded); storeInMemoryDynamic(*targetType.baseType(), true); - m_context << Instruction::SWAP1 << u256(1) << Instruction::ADD; - m_context << Instruction::SWAP1; + m_context << InternalInstruction::SWAP1 << u256(1) << InternalInstruction::ADD; + m_context << InternalInstruction::SWAP1; m_context.appendJumpTo(repeat); m_context << loopEnd; - m_context << Instruction::POP; + m_context << InternalInstruction::POP; } // stack: (variably sized) popStackSlots(2 + stackSize); @@ -1127,7 +1127,7 @@ void CompilerUtils::convertType( solAssert(typeOnStack.dataStoredIn(DataLocation::CallData)); solAssert(typeOnStack.sizeOnStack() == 2); - m_context << Instruction::SWAP1; + m_context << InternalInstruction::SWAP1; m_context.callYulFunction( m_context.utilFunctions().bytesToFixedBytesConversionFunction( typeOnStack.arrayType(), @@ -1181,13 +1181,13 @@ void CompilerUtils::convertType( CompilerUtils utils(_context); // stack: utils.allocateMemory(typeOnStack->memoryDataSize()); - _context << Instruction::SWAP1 << Instruction::DUP2; + _context << InternalInstruction::SWAP1 << InternalInstruction::DUP2; // stack: for (auto const& member: typeOnStack->members(nullptr)) { solAssert(!member.type->containsNestedMapping()); pair const& offsets = typeOnStack->storageOffsetsOfMember(member.name); - _context << offsets.first << Instruction::DUP3 << Instruction::ADD; + _context << offsets.first << InternalInstruction::DUP3 << InternalInstruction::ADD; _context << u256(offsets.second); StorageItem(_context, *member.type).retrieveValue(SourceLocation(), true); Type const* targetMemberType = targetType->memberType(member.name); @@ -1195,7 +1195,7 @@ void CompilerUtils::convertType( utils.convertType(*member.type, *targetMemberType, true); utils.storeInMemoryDynamic(*targetMemberType, true); } - _context << Instruction::POP << Instruction::POP; + _context << InternalInstruction::POP << InternalInstruction::POP; }; if (typeOnStack.recursive()) m_context.callLowLevelFunction( @@ -1221,9 +1221,9 @@ void CompilerUtils::convertType( } else { - m_context << Instruction::DUP1; - m_context << Instruction::CALLDATASIZE; - m_context << Instruction::SUB; + m_context << InternalInstruction::DUP1; + m_context << InternalInstruction::CALLDATASIZE; + m_context << InternalInstruction::SUB; abiDecode({&targetType}, false); } break; @@ -1271,12 +1271,12 @@ void CompilerUtils::convertType( for (unsigned j = 0; j < min(sourceSize, targetSize); ++j) m_context << swapInstruction(depth + targetSize - sourceSize) << - Instruction::POP; + InternalInstruction::POP; // Value shrank for (unsigned j = targetSize; j < sourceSize; ++j) { moveToStackTop(depth + targetSize - sourceSize, 1); - m_context << Instruction::POP; + m_context << InternalInstruction::POP; } // Value grew if (targetSize > sourceSize) @@ -1290,7 +1290,7 @@ void CompilerUtils::convertType( case Type::Category::Bool: solAssert(_targetType == _typeOnStack, "Invalid conversion for bool."); if (_cleanupNeeded) - m_context << Instruction::ISZERO << Instruction::ISZERO; + m_context << InternalInstruction::ISZERO << InternalInstruction::ISZERO; break; default: // we used to allow conversions from function to address @@ -1314,7 +1314,7 @@ void CompilerUtils::convertType( if (_cleanupNeeded && _targetType.canBeStored() && _targetType.storageBytes() < 32) m_context << ((u256(1) << (8 * _targetType.storageBytes())) - 1) - << Instruction::AND; + << InternalInstruction::AND; break; } @@ -1337,7 +1337,7 @@ void CompilerUtils::pushZeroValue(Type const& _type) m_context << runCon->lowLevelFunctionTag("$invalidFunction", 0, 0, [](CompilerContext& _context) { _context.appendPanic(util::PanicCode::InvalidInternalFunction); }).toSubAssemblyTag(m_context.runtimeSub()); - m_context << Instruction::OR; + m_context << InternalInstruction::OR; } return; } @@ -1352,7 +1352,7 @@ void CompilerUtils::pushZeroValue(Type const& _type) if (referenceType->location() == DataLocation::CallData) { solAssert(referenceType->sizeOnStack() == 1 || referenceType->sizeOnStack() == 2); - m_context << Instruction::CALLDATASIZE; + m_context << InternalInstruction::CALLDATASIZE; if (referenceType->sizeOnStack() == 2) m_context << 0; return; @@ -1376,7 +1376,7 @@ void CompilerUtils::pushZeroValue(Type const& _type) CompilerUtils utils(_context); utils.allocateMemory(max(32u, type->memoryDataSize())); - _context << Instruction::DUP1; + _context << InternalInstruction::DUP1; if (auto structType = dynamic_cast(type)) for (auto const& member: structType->members(nullptr)) @@ -1389,7 +1389,7 @@ void CompilerUtils::pushZeroValue(Type const& _type) solAssert(!arrayType->isDynamicallySized()); if (arrayType->length() > 0) { - _context << arrayType->length() << Instruction::SWAP1; + _context << arrayType->length() << InternalInstruction::SWAP1; // stack: items_to_do memory_pos utils.zeroInitialiseMemoryArray(*arrayType); // stack: updated_memory_pos @@ -1399,7 +1399,7 @@ void CompilerUtils::pushZeroValue(Type const& _type) solAssert(false, "Requested initialisation for unknown type: " + type->toString()); // remove the updated memory pointer - _context << Instruction::POP; + _context << InternalInstruction::POP; } ); } @@ -1422,7 +1422,7 @@ void CompilerUtils::moveToStackVariable(VariableDeclaration const& _variable) util::errinfo_comment(util::stackTooDeepString) ); for (unsigned i = 0; i < size; ++i) - m_context << swapInstruction(stackPosition - size + 1) << Instruction::POP; + m_context << swapInstruction(stackPosition - size + 1) << InternalInstruction::POP; } void CompilerUtils::copyToStackTop(unsigned _stackDepth, unsigned _itemSize) @@ -1481,7 +1481,7 @@ void CompilerUtils::popStackElement(Type const& _type) void CompilerUtils::popStackSlots(size_t _amount) { for (size_t i = 0; i < _amount; ++i) - m_context << Instruction::POP; + m_context << InternalInstruction::POP; } void CompilerUtils::popAndJump(unsigned _toHeight, evmasm::AssemblyItem const& _jumpTo) @@ -1504,7 +1504,7 @@ unsigned CompilerUtils::sizeOnStack(vector const& _variableTypes) void CompilerUtils::computeHashStatic() { storeInMemory(0); - m_context << u256(32) << u256(0) << Instruction::KECCAK256; + m_context << u256(32) << u256(0) << InternalInstruction::KECCAK256; } void CompilerUtils::copyContractCodeToMemory(ContractDefinition const& contract, bool _creation) @@ -1523,9 +1523,9 @@ void CompilerUtils::copyContractCodeToMemory(ContractDefinition const& contract, _context.compiledContractRuntime(contract); // pushes size auto subroutine = _context.addSubroutine(assembly); - _context << Instruction::DUP1 << subroutine; - _context << Instruction::DUP4 << Instruction::CODECOPY; - _context << Instruction::ADD; + _context << InternalInstruction::DUP1 << subroutine; + _context << InternalInstruction::DUP4 << InternalInstruction::CODECOPY; + _context << InternalInstruction::ADD; } ); } @@ -1541,14 +1541,14 @@ void CompilerUtils::storeStringData(bytesConstRef _data) m_context << u256(h256(_data.cropped(i), h256::AlignLeft)); storeInMemoryDynamic(*TypeProvider::uint256()); } - m_context << Instruction::POP; + m_context << InternalInstruction::POP; } else { // stack: mempos mempos_data m_context.appendData(_data.toBytes()); - m_context << u256(_data.size()) << Instruction::SWAP2; - m_context << Instruction::CODECOPY; + m_context << u256(_data.size()) << InternalInstruction::SWAP2; + m_context << InternalInstruction::CODECOPY; } } @@ -1566,11 +1566,11 @@ unsigned CompilerUtils::loadFromMemoryHelper(Type const& _type, bool _fromCallda isExternalFunctionType = true; if (numBytes == 0) { - m_context << Instruction::POP << u256(0); + m_context << InternalInstruction::POP << u256(0); return numBytes; } solAssert(numBytes <= 32, "Static memory load of more than 32 bytes requested."); - m_context << (_fromCalldata ? Instruction::CALLDATALOAD : Instruction::MLOAD); + m_context << (_fromCalldata ? InternalInstruction::CALLDATALOAD : InternalInstruction::MLOAD); bool cleanupNeeded = true; if (isExternalFunctionType) splitExternalFunctionType(true); @@ -1599,18 +1599,18 @@ void CompilerUtils::cleanHigherOrderBits(IntegerType const& _typeOnStack) if (_typeOnStack.numBits() == 256) return; else if (_typeOnStack.isSigned()) - m_context << u256(_typeOnStack.numBits() / 8 - 1) << Instruction::SIGNEXTEND; + m_context << u256(_typeOnStack.numBits() / 8 - 1) << InternalInstruction::SIGNEXTEND; else - m_context << ((u256(1) << _typeOnStack.numBits()) - 1) << Instruction::AND; + m_context << ((u256(1) << _typeOnStack.numBits()) - 1) << InternalInstruction::AND; } void CompilerUtils::leftShiftNumberOnStack(unsigned _bits) { solAssert(_bits < 256); if (m_context.evmVersion().hasBitwiseShifting()) - m_context << _bits << Instruction::SHL; + m_context << _bits << InternalInstruction::SHL; else - m_context << (u256(1) << _bits) << Instruction::MUL; + m_context << (u256(1) << _bits) << InternalInstruction::MUL; } void CompilerUtils::rightShiftNumberOnStack(unsigned _bits) @@ -1618,9 +1618,9 @@ void CompilerUtils::rightShiftNumberOnStack(unsigned _bits) solAssert(_bits < 256); // NOTE: If we add signed right shift, SAR rounds differently than SDIV if (m_context.evmVersion().hasBitwiseShifting()) - m_context << _bits << Instruction::SHR; + m_context << _bits << InternalInstruction::SHR; else - m_context << (u256(1) << _bits) << Instruction::SWAP1 << Instruction::DIV; + m_context << (u256(1) << _bits) << InternalInstruction::SWAP1 << InternalInstruction::DIV; } unsigned CompilerUtils::prepareMemoryStore(Type const& _type, bool _padToWords, bool _cleanup) diff --git a/libsolidity/codegen/ContractCompiler.cpp b/libsolidity/codegen/ContractCompiler.cpp index a6e7ab2fb..085d1ae3d 100644 --- a/libsolidity/codegen/ContractCompiler.cpp +++ b/libsolidity/codegen/ContractCompiler.cpp @@ -142,7 +142,7 @@ void ContractCompiler::initializeContext( void ContractCompiler::appendCallValueCheck() { // Throw if function is not payable but call contained ether. - m_context << Instruction::CALLVALUE; + m_context << InternalInstruction::CALLVALUE; m_context.appendConditionalRevert(false, "Ether sent to non-payable function"); } @@ -201,9 +201,9 @@ size_t ContractCompiler::packIntoContractCreator(ContractDefinition const& _cont ); m_context.pushSubroutineSize(m_context.runtimeSub()); if (immutables.empty()) - m_context << Instruction::DUP1; + m_context << InternalInstruction::DUP1; m_context.pushSubroutineOffset(m_context.runtimeSub()); - m_context << u256(0) << Instruction::CODECOPY; + m_context << u256(0) << InternalInstruction::CODECOPY; // Assign immutable values from stack in reversed order. for (auto const& immutable: immutables | ranges::views::reverse) { @@ -216,7 +216,7 @@ size_t ContractCompiler::packIntoContractCreator(ContractDefinition const& _cont } if (!immutables.empty()) m_context.pushSubroutineSize(m_context.runtimeSub()); - m_context << u256(0) << Instruction::RETURN; + m_context << u256(0) << InternalInstruction::RETURN; return m_context.runtimeSub(); } @@ -298,13 +298,13 @@ void ContractCompiler::appendConstructor(FunctionDefinition const& _constructor) // which is the size of the generated code (``programSize``) // plus the constructor arguments added to the transaction payload. m_context.appendProgramSize(); - m_context << Instruction::CODESIZE << Instruction::SUB; + m_context << InternalInstruction::CODESIZE << InternalInstruction::SUB; // stack: - m_context << Instruction::DUP1; + m_context << InternalInstruction::DUP1; m_context.appendProgramSize(); - m_context << Instruction::DUP4 << Instruction::CODECOPY; + m_context << InternalInstruction::DUP4 << InternalInstruction::CODECOPY; // stack: - m_context << Instruction::DUP2 << Instruction::DUP2 << Instruction::ADD; + m_context << InternalInstruction::DUP2 << InternalInstruction::DUP2 << InternalInstruction::ADD; // stack: CompilerUtils(m_context).storeFreeMemoryPointer(); // stack: @@ -318,7 +318,7 @@ void ContractCompiler::appendDelegatecallCheck() // Special constant that will be replaced by the address at deploy time. // At compilation time, this is just "PUSH20 00...000". m_context.appendDeployTimeAddress(); - m_context << Instruction::ADDRESS << Instruction::EQ; + m_context << InternalInstruction::ADDRESS << InternalInstruction::EQ; // The result on the stack is // "We have not been called via DELEGATECALL". } @@ -366,7 +366,7 @@ void ContractCompiler::appendInternalSelector( { size_t pivotIndex = _ids.size() / 2; FixedHash<4> pivot{_ids.at(pivotIndex)}; - m_context << dupInstruction(1) << u256(FixedHash<4>::Arith(pivot)) << Instruction::GT; + m_context << dupInstruction(1) << u256(FixedHash<4>::Arith(pivot)) << InternalInstruction::GT; evmasm::AssemblyItem lessTag{m_context.appendConditionalJump()}; // Here, we have funid >= pivot vector> larger{_ids.begin() + static_cast(pivotIndex), _ids.end()}; @@ -380,7 +380,7 @@ void ContractCompiler::appendInternalSelector( { for (auto const& id: _ids) { - m_context << dupInstruction(1) << u256(FixedHash<4>::Arith(id)) << Instruction::EQ; + m_context << dupInstruction(1) << u256(FixedHash<4>::Arith(id)) << InternalInstruction::EQ; m_context.appendConditionalJumpTo(_entryPoints.at(id)); } m_context.appendJumpTo(_notFoundTag); @@ -439,7 +439,7 @@ void ContractCompiler::appendFunctionSelector(ContractDefinition const& _contrac // directly jump to fallback or ether receiver if the data is too short to contain a function selector // also guards against short data - m_context << u256(4) << Instruction::CALLDATASIZE << Instruction::LT; + m_context << u256(4) << InternalInstruction::CALLDATASIZE << InternalInstruction::LT; m_context.appendConditionalJumpTo(notFoundOrReceiveEther); // retrieve the function signature hash from the calldata @@ -467,7 +467,7 @@ void ContractCompiler::appendFunctionSelector(ContractDefinition const& _contrac if (etherReceiver) { // directly jump to fallback, if there is calldata - m_context << Instruction::CALLDATASIZE; + m_context << InternalInstruction::CALLDATASIZE; m_context.appendConditionalJumpTo(notFound); solAssert(!_contract.isLibrary(), ""); @@ -475,7 +475,7 @@ void ContractCompiler::appendFunctionSelector(ContractDefinition const& _contrac solAssert(FunctionType(*etherReceiver).parameterTypes().empty(), ""); solAssert(FunctionType(*etherReceiver).returnParameterTypes().empty(), ""); etherReceiver->accept(*this); - m_context << Instruction::STOP; + m_context << InternalInstruction::STOP; } m_context << notFound; @@ -489,17 +489,17 @@ void ContractCompiler::appendFunctionSelector(ContractDefinition const& _contrac m_context.setStackOffset(0); if (!FunctionType(*fallback).parameterTypes().empty()) - m_context << u256(0) << Instruction::CALLDATASIZE; + m_context << u256(0) << InternalInstruction::CALLDATASIZE; fallback->accept(*this); if (FunctionType(*fallback).returnParameterTypes().empty()) - m_context << Instruction::STOP; + m_context << InternalInstruction::STOP; else { - m_context << Instruction::DUP1 << Instruction::MLOAD << Instruction::SWAP1; - m_context << u256(0x20) << Instruction::ADD; - m_context << Instruction::RETURN; + m_context << InternalInstruction::DUP1 << InternalInstruction::MLOAD << InternalInstruction::SWAP1; + m_context << u256(0x20) << InternalInstruction::ADD; + m_context << InternalInstruction::RETURN; } } else @@ -534,7 +534,7 @@ void ContractCompiler::appendFunctionSelector(ContractDefinition const& _contrac { // Parameter for calldataUnpacker m_context << CompilerUtils::dataStartOffset; - m_context << Instruction::DUP1 << Instruction::CALLDATASIZE << Instruction::SUB; + m_context << InternalInstruction::DUP1 << InternalInstruction::CALLDATASIZE << InternalInstruction::SUB; CompilerUtils(m_context).abiDecode(functionType->parameterTypes()); } m_context.appendJumpTo( @@ -557,7 +557,7 @@ void ContractCompiler::appendReturnValuePacker(TypePointers const& _typeParamete { CompilerUtils utils(m_context); if (_typeParameters.empty()) - m_context << Instruction::STOP; + m_context << InternalInstruction::STOP; else { utils.fetchFreeMemoryPointer(); @@ -565,7 +565,7 @@ void ContractCompiler::appendReturnValuePacker(TypePointers const& _typeParamete // its data to add the needed parts and we avoid a memory copy. utils.abiEncode(_typeParameters, _typeParameters, _isLibrary); utils.toSizeAfterFreeMemoryPointer(); - m_context << Instruction::RETURN; + m_context << InternalInstruction::RETURN; } } @@ -678,7 +678,7 @@ bool ContractCompiler::visit(FunctionDefinition const& _function) while (!stackLayout.empty() && stackLayout.back() != static_cast(stackLayout.size() - 1)) if (stackLayout.back() < 0) { - m_context << Instruction::POP; + m_context << InternalInstruction::POP; stackLayout.pop_back(); } else @@ -920,7 +920,7 @@ bool ContractCompiler::visit(InlineAssembly const& _inlineAssembly) util::errinfo_comment(util::stackTooDeepString) ); _assembly.appendInstruction(swapInstruction(stackDiff)); - _assembly.appendInstruction(Instruction::POP); + _assembly.appendInstruction(InternalInstruction::POP); } }; @@ -1046,17 +1046,17 @@ void ContractCompiler::handleCatch(vector> const& _ca solAssert(m_context.evmVersion().supportsReturndata(), ""); // stack: - m_context << Instruction::DUP1 << util::selectorFromSignatureU32("Error(string)") << Instruction::EQ; - m_context << Instruction::ISZERO; + m_context << InternalInstruction::DUP1 << util::selectorFromSignatureU32("Error(string)") << InternalInstruction::EQ; + m_context << InternalInstruction::ISZERO; m_context.appendConditionalJumpTo(panicTag); - m_context << Instruction::POP; // remove selector + m_context << InternalInstruction::POP; // remove selector // Try to decode the error message. // If this fails, leaves 0 on the stack, otherwise the pointer to the data string. m_context.callYulFunction(m_context.utilFunctions().tryDecodeErrorMessageFunction(), 0, 1); - m_context << Instruction::DUP1; + m_context << InternalInstruction::DUP1; AssemblyItem decodeSuccessTag = m_context.appendConditionalJump(); - m_context << Instruction::POP; + m_context << InternalInstruction::POP; m_context.appendJumpTo(fallbackTag); m_context.adjustStackOffset(1); @@ -1078,15 +1078,15 @@ void ContractCompiler::handleCatch(vector> const& _ca solAssert(m_context.evmVersion().supportsReturndata(), ""); // stack: - m_context << util::selectorFromSignatureU32("Panic(uint256)") << Instruction::EQ; - m_context << Instruction::ISZERO; + m_context << util::selectorFromSignatureU32("Panic(uint256)") << InternalInstruction::EQ; + m_context << InternalInstruction::ISZERO; m_context.appendConditionalJumpTo(fallbackTag); m_context.callYulFunction(m_context.utilFunctions().tryDecodePanicDataFunction(), 0, 2); - m_context << Instruction::SWAP1; + m_context << InternalInstruction::SWAP1; // stack: AssemblyItem decodeSuccessTag = m_context.appendConditionalJump(); - m_context << Instruction::POP; + m_context << InternalInstruction::POP; m_context.appendJumpTo(fallbackTag); m_context.adjustStackOffset(1); @@ -1096,7 +1096,7 @@ void ContractCompiler::handleCatch(vector> const& _ca m_context.adjustStackOffset(1); } if (error || panic) - m_context << Instruction::POP; // selector + m_context << InternalInstruction::POP; // selector m_context << fallbackTag; if (fallback) { @@ -1156,7 +1156,7 @@ bool ContractCompiler::visit(IfStatement const& _ifStatement) StackHeightChecker checker(m_context); CompilerContext::LocationSetter locationSetter(m_context, _ifStatement); compileExpression(_ifStatement.condition()); - m_context << Instruction::ISZERO; + m_context << InternalInstruction::ISZERO; evmasm::AssemblyItem falseTag = m_context.appendConditionalJump(); evmasm::AssemblyItem endTag = falseTag; _ifStatement.trueStatement().accept(*this); @@ -1192,14 +1192,14 @@ bool ContractCompiler::visit(WhileStatement const& _whileStatement) m_context << condition; compileExpression(_whileStatement.condition()); - m_context << Instruction::ISZERO << Instruction::ISZERO; + m_context << InternalInstruction::ISZERO << InternalInstruction::ISZERO; m_context.appendConditionalJumpTo(loopStart); } else { m_continueTags.emplace_back(loopStart, m_context.stackHeight()); compileExpression(_whileStatement.condition()); - m_context << Instruction::ISZERO; + m_context << InternalInstruction::ISZERO; m_context.appendConditionalJumpTo(loopEnd); _whileStatement.body().accept(*this); @@ -1236,7 +1236,7 @@ bool ContractCompiler::visit(ForStatement const& _forStatement) if (_forStatement.condition()) { compileExpression(*_forStatement.condition()); - m_context << Instruction::ISZERO; + m_context << InternalInstruction::ISZERO; m_context.appendConditionalJumpTo(loopEnd); } diff --git a/libsolidity/codegen/ExpressionCompiler.cpp b/libsolidity/codegen/ExpressionCompiler.cpp index 911ff3a7a..1a38228e1 100644 --- a/libsolidity/codegen/ExpressionCompiler.cpp +++ b/libsolidity/codegen/ExpressionCompiler.cpp @@ -150,7 +150,7 @@ void ExpressionCompiler::appendStateVariableAccessor(VariableDeclaration const& solAssert(CompilerUtils::freeMemoryPointer >= 0x40, ""); // pop offset - m_context << Instruction::POP; + m_context << InternalInstruction::POP; if (paramTypes[i]->isDynamicallySized()) { solAssert( @@ -175,7 +175,7 @@ void ExpressionCompiler::appendStateVariableAccessor(VariableDeclaration const& slot_pos := hash })", {"slot_pos", "key_ptr"}); - m_context << Instruction::POP; + m_context << InternalInstruction::POP; } else { @@ -188,7 +188,7 @@ void ExpressionCompiler::appendStateVariableAccessor(VariableDeclaration const& utils().copyToStackTop(static_cast(paramTypes.size() - i), 1); utils().storeInMemory(0); m_context << u256(64) << u256(0); - m_context << Instruction::KECCAK256; + m_context << InternalInstruction::KECCAK256; } // push offset @@ -198,15 +198,15 @@ void ExpressionCompiler::appendStateVariableAccessor(VariableDeclaration const& else if (auto arrayType = dynamic_cast(returnType)) { // pop offset - m_context << Instruction::POP; + m_context << InternalInstruction::POP; utils().copyToStackTop(static_cast(paramTypes.size() - i + 1), 1); ArrayUtils(m_context).retrieveLength(*arrayType, 1); // Stack: ref [length] index length // check out-of-bounds access - m_context << Instruction::DUP2 << Instruction::LT; + m_context << InternalInstruction::DUP2 << InternalInstruction::LT; auto tag = m_context.appendConditionalJump(); - m_context << u256(0) << Instruction::DUP1 << Instruction::REVERT; + m_context << u256(0) << InternalInstruction::DUP1 << InternalInstruction::REVERT; m_context << tag; ArrayUtils(m_context).accessIndex(*arrayType, false); @@ -217,11 +217,11 @@ void ExpressionCompiler::appendStateVariableAccessor(VariableDeclaration const& } // remove index arguments. if (paramTypes.size() == 1) - m_context << Instruction::SWAP2 << Instruction::POP << Instruction::SWAP1; + m_context << InternalInstruction::SWAP2 << InternalInstruction::POP << InternalInstruction::SWAP1; else if (paramTypes.size() >= 2) { m_context << swapInstruction(static_cast(paramTypes.size())); - m_context << Instruction::POP; + m_context << InternalInstruction::POP; m_context << swapInstruction(static_cast(paramTypes.size())); utils().popStackSlots(paramTypes.size() - 1); } @@ -232,7 +232,7 @@ void ExpressionCompiler::appendStateVariableAccessor(VariableDeclaration const& { solAssert(!_varDecl.immutable(), ""); // remove offset - m_context << Instruction::POP; + m_context << InternalInstruction::POP; auto const& names = accessorType.returnParameterNames(); // struct for (size_t i = 0; i < names.size(); ++i) @@ -243,7 +243,7 @@ void ExpressionCompiler::appendStateVariableAccessor(VariableDeclaration const& if (!arrayType->isByteArrayOrString()) continue; pair const& offsets = structType->storageOffsetsOfMember(names[i]); - m_context << Instruction::DUP1 << u256(offsets.first) << Instruction::ADD << u256(offsets.second); + m_context << InternalInstruction::DUP1 << u256(offsets.first) << InternalInstruction::ADD << u256(offsets.second); Type const* memberType = structType->memberType(names[i]); StorageItem(m_context, *memberType).retrieveValue(SourceLocation(), true); utils().convertType(*memberType, *returnTypes[i]); @@ -251,7 +251,7 @@ void ExpressionCompiler::appendStateVariableAccessor(VariableDeclaration const& retSizeOnStack += returnTypes[i]->sizeOnStack(); } // remove slot - m_context << Instruction::POP; + m_context << InternalInstruction::POP; } else { @@ -355,7 +355,7 @@ bool ExpressionCompiler::visit(Assignment const& _assignment) ); // value [lvalue_ref] updated_value for (unsigned i = 0; i < itemSize; ++i) - m_context << swapInstruction(itemSize + lvalueSize) << Instruction::POP; + m_context << swapInstruction(itemSize + lvalueSize) << InternalInstruction::POP; } m_currentLValue->storeValue(*_assignment.annotation().type, _assignment.location()); } @@ -371,7 +371,7 @@ bool ExpressionCompiler::visit(TupleExpression const& _tuple) solAssert(!arrayType.isDynamicallySized(), "Cannot create dynamically sized inline array."); utils().allocateMemory(max(u256(32u), arrayType.memoryDataSize())); - m_context << Instruction::DUP1; + m_context << InternalInstruction::DUP1; for (auto const& component: _tuple.components()) { @@ -379,7 +379,7 @@ bool ExpressionCompiler::visit(TupleExpression const& _tuple) utils().storeInMemoryDynamic(*arrayType.baseType(), true); } - m_context << Instruction::POP; + m_context << InternalInstruction::POP; } else { @@ -422,10 +422,10 @@ bool ExpressionCompiler::visit(UnaryOperation const& _unaryOperation) switch (_unaryOperation.getOperator()) { case Token::Not: // ! - m_context << Instruction::ISZERO; + m_context << InternalInstruction::ISZERO; break; case Token::BitNot: // ~ - m_context << Instruction::NOT; + m_context << InternalInstruction::NOT; break; case Token::Delete: // delete solAssert(!!m_currentLValue, "LValue not retrieved."); @@ -444,7 +444,7 @@ bool ExpressionCompiler::visit(UnaryOperation const& _unaryOperation) { // store value for later solUnimplementedAssert(type.sizeOnStack() == 1, "Stack size != 1 not implemented."); - m_context << Instruction::DUP1; + m_context << InternalInstruction::DUP1; if (m_currentLValue->sizeOnStack() > 0) for (unsigned i = 1 + m_currentLValue->sizeOnStack(); i > 0; --i) m_context << swapInstruction(i); @@ -456,7 +456,7 @@ bool ExpressionCompiler::visit(UnaryOperation const& _unaryOperation) else { m_context << u256(1); - m_context << Instruction::ADD; + m_context << InternalInstruction::ADD; } } else @@ -466,7 +466,7 @@ bool ExpressionCompiler::visit(UnaryOperation const& _unaryOperation) else { m_context << u256(1); - m_context << Instruction::SWAP1 << Instruction::SUB; + m_context << InternalInstruction::SWAP1 << InternalInstruction::SUB; } } // Stack for prefix: [ref...] (*ref)+-1 @@ -489,7 +489,7 @@ bool ExpressionCompiler::visit(UnaryOperation const& _unaryOperation) if (m_context.arithmetic() == Arithmetic::Checked) m_context.callYulFunction(m_context.utilFunctions().negateNumberCheckedFunction(type), 1, 1); else - m_context << u256(0) << Instruction::SUB; + m_context << u256(0) << InternalInstruction::SUB; break; default: solAssert(false, "Invalid unary operator: " + string(TokenTraits::toString(_unaryOperation.getOperator()))); @@ -600,14 +600,14 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) auto const& structType = dynamic_cast(*type.actualType()); utils().allocateMemory(max(u256(32u), structType.memoryDataSize())); - m_context << Instruction::DUP1; + m_context << InternalInstruction::DUP1; for (unsigned i = 0; i < arguments.size(); ++i) { acceptAndConvert(*arguments[i], *functionType->parameterTypes()[i]); utils().storeInMemoryDynamic(*functionType->parameterTypes()[i]); } - m_context << Instruction::POP; + m_context << InternalInstruction::POP; } else { @@ -670,7 +670,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) utils().rightShiftNumberOnStack(32); else // Extract the runtime part. - m_context << ((u256(1) << 32) - 1) << Instruction::AND; + m_context << ((u256(1) << 32) - 1) << InternalInstruction::AND; m_context.appendJump(evmasm::AssemblyItem::JumpType::IntoFunction); m_context << returnLabel; @@ -716,7 +716,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) if (function.saltSet()) { m_context << dupInstruction(2 + (function.valueSet() ? 1 : 0)); - m_context << Instruction::SWAP1; + m_context << InternalInstruction::SWAP1; } // now: [salt], [value], [salt], memory_end_ptr @@ -730,19 +730,19 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) // now: [salt], [value], [salt], size, offset, value if (function.saltSet()) - m_context << Instruction::CREATE2; + m_context << InternalInstruction::CREATE2; else - m_context << Instruction::CREATE; + m_context << InternalInstruction::CREATE; // now: [salt], [value], address if (function.valueSet()) - m_context << swapInstruction(1) << Instruction::POP; + m_context << swapInstruction(1) << InternalInstruction::POP; if (function.saltSet()) - m_context << swapInstruction(1) << Instruction::POP; + m_context << swapInstruction(1) << InternalInstruction::POP; // Check if zero (reverted) - m_context << Instruction::DUP1 << Instruction::ISZERO; + m_context << InternalInstruction::DUP1 << InternalInstruction::ISZERO; if (_functionCall.annotation().tryCall) { // If this is a try call, return "
1" in the success case and @@ -767,7 +767,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) if (stackDepth > 0) m_context << swapInstruction(stackDepth); if (function.gasSet()) - m_context << Instruction::POP; + m_context << InternalInstruction::POP; break; } case FunctionType::Kind::SetValue: @@ -776,7 +776,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) // Note that function is not the original function, but the ".value" function. // Its values of gasSet and valueSet is equal to the original function's though. if (function.valueSet()) - m_context << Instruction::POP; + m_context << InternalInstruction::POP; arguments.front()->accept(*this); break; case FunctionType::Kind::Send: @@ -788,8 +788,8 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) m_context << u256(evmasm::GasCosts::callStipend); acceptAndConvert(*arguments.front(), *function.parameterTypes().front(), true); // gas <- gas * !value - m_context << Instruction::SWAP1 << Instruction::DUP2; - m_context << Instruction::ISZERO << Instruction::MUL << Instruction::SWAP1; + m_context << InternalInstruction::SWAP1 << InternalInstruction::DUP2; + m_context << InternalInstruction::ISZERO << InternalInstruction::MUL << InternalInstruction::SWAP1; FunctionType::Options callOptions; callOptions.valueSet = true; callOptions.gasSet = true; @@ -810,7 +810,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) if (function.kind() == FunctionType::Kind::Transfer) { // Check if zero (out of stack or not enough balance). - m_context << Instruction::ISZERO; + m_context << InternalInstruction::ISZERO; // Revert message bubbles up. m_context.appendConditionalRevert(true); } @@ -818,7 +818,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) } case FunctionType::Kind::Selfdestruct: acceptAndConvert(*arguments.front(), *function.parameterTypes().front(), true); - m_context << Instruction::SELFDESTRUCT; + m_context << InternalInstruction::SELFDESTRUCT; break; case FunctionType::Kind::Revert: { @@ -861,15 +861,15 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) // Optimization: If type is bytes or string, then do not encode, // but directly compute keccak256 on memory. ArrayUtils(m_context).retrieveLength(*TypeProvider::bytesMemory()); - m_context << Instruction::SWAP1 << u256(0x20) << Instruction::ADD; - m_context << Instruction::KECCAK256; + m_context << InternalInstruction::SWAP1 << u256(0x20) << InternalInstruction::ADD; + m_context << InternalInstruction::KECCAK256; } else { utils().fetchFreeMemoryPointer(); utils().packedEncode({argType}, TypePointers()); utils().toSizeAfterFreeMemoryPointer(); - m_context << Instruction::KECCAK256; + m_context << InternalInstruction::KECCAK256; } break; } @@ -893,7 +893,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) {referenceType} ); utils().toSizeAfterFreeMemoryPointer(); - m_context << Instruction::KECCAK256; + m_context << InternalInstruction::KECCAK256; } else { @@ -993,21 +993,21 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) case FunctionType::Kind::BlockHash: { acceptAndConvert(*arguments[0], *function.parameterTypes()[0], true); - m_context << Instruction::BLOCKHASH; + m_context << InternalInstruction::BLOCKHASH; break; } case FunctionType::Kind::AddMod: case FunctionType::Kind::MulMod: { acceptAndConvert(*arguments[2], *TypeProvider::uint256()); - m_context << Instruction::DUP1 << Instruction::ISZERO; + m_context << InternalInstruction::DUP1 << InternalInstruction::ISZERO; m_context.appendConditionalPanic(util::PanicCode::DivisionByZero); for (unsigned i = 1; i < 3; i ++) acceptAndConvert(*arguments[2 - i], *TypeProvider::uint256()); if (function.kind() == FunctionType::Kind::AddMod) - m_context << Instruction::ADDMOD; + m_context << InternalInstruction::ADDMOD; else - m_context << Instruction::MULMOD; + m_context << InternalInstruction::MULMOD; break; } case FunctionType::Kind::ECRecover: @@ -1041,10 +1041,10 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) solAssert(arrayType, ""); // stack: ArrayReference - m_context << u256(1) << Instruction::DUP2; + m_context << u256(1) << InternalInstruction::DUP2; ArrayUtils(m_context).incrementDynamicArraySize(*arrayType); // stack: ArrayReference 1 newLength - m_context << Instruction::SUB; + m_context << InternalInstruction::SUB; // stack: ArrayReference (newLength-1) ArrayUtils(m_context).accessIndex(*arrayType, false); @@ -1067,10 +1067,10 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) // stack: ArrayReference argValue utils().moveToStackTop(argType->sizeOnStack(), 1); // stack: argValue ArrayReference - m_context << Instruction::DUP1; + m_context << InternalInstruction::DUP1; ArrayUtils(m_context).incrementDynamicArraySize(*arrayType); // stack: argValue ArrayReference newLength - m_context << u256(1) << Instruction::SWAP1 << Instruction::SUB; + m_context << u256(1) << InternalInstruction::SWAP1 << InternalInstruction::SUB; // stack: argValue ArrayReference (newLength-1) ArrayUtils(m_context).accessIndex(*arrayType, false); // stack: argValue storageSlot slotOffset @@ -1137,13 +1137,13 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) } utils().fetchFreeMemoryPointer(); // stack: ... - m_context << u256(32) << Instruction::ADD; + m_context << u256(32) << InternalInstruction::ADD; utils().packedEncode(argumentTypes, targetTypes); utils().fetchFreeMemoryPointer(); m_context.appendInlineAssembly(R"({ mstore(mem_ptr, sub(sub(mem_end, mem_ptr), 0x20)) })", {"mem_end", "mem_ptr"}); - m_context << Instruction::SWAP1; + m_context << InternalInstruction::SWAP1; utils().storeFreeMemoryPointer(); break; @@ -1159,42 +1159,42 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) // Make sure we can allocate memory without overflow m_context << u256(0xffffffffffffffff); - m_context << Instruction::DUP2; - m_context << Instruction::GT; + m_context << InternalInstruction::DUP2; + m_context << InternalInstruction::GT; m_context.appendConditionalPanic(PanicCode::ResourceError); // Stack: requested_length utils().fetchFreeMemoryPointer(); // Stack: requested_length memptr - m_context << Instruction::SWAP1; + m_context << InternalInstruction::SWAP1; // Stack: memptr requested_length // store length - m_context << Instruction::DUP1 << Instruction::DUP3 << Instruction::MSTORE; + m_context << InternalInstruction::DUP1 << InternalInstruction::DUP3 << InternalInstruction::MSTORE; // Stack: memptr requested_length // update free memory pointer - m_context << Instruction::DUP1; + m_context << InternalInstruction::DUP1; // Stack: memptr requested_length requested_length if (arrayType.isByteArrayOrString()) // Round up to multiple of 32 - m_context << u256(31) << Instruction::ADD << u256(31) << Instruction::NOT << Instruction::AND; + m_context << u256(31) << InternalInstruction::ADD << u256(31) << InternalInstruction::NOT << InternalInstruction::AND; else - m_context << arrayType.baseType()->memoryHeadSize() << Instruction::MUL; + m_context << arrayType.baseType()->memoryHeadSize() << InternalInstruction::MUL; // stacK: memptr requested_length data_size - m_context << u256(32) << Instruction::ADD; - m_context << Instruction::DUP3 << Instruction::ADD; + m_context << u256(32) << InternalInstruction::ADD; + m_context << InternalInstruction::DUP3 << InternalInstruction::ADD; utils().storeFreeMemoryPointer(); // Stack: memptr requested_length // Check if length is zero - m_context << Instruction::DUP1 << Instruction::ISZERO; + m_context << InternalInstruction::DUP1 << InternalInstruction::ISZERO; auto skipInit = m_context.appendConditionalJump(); // Always initialize because the free memory pointer might point at // a dirty memory area. - m_context << Instruction::DUP2 << u256(32) << Instruction::ADD; + m_context << InternalInstruction::DUP2 << u256(32) << InternalInstruction::ADD; utils().zeroInitialiseMemoryArray(arrayType); m_context << skipInit; - m_context << Instruction::POP; + m_context << InternalInstruction::POP; break; } case FunctionType::Kind::Assert: @@ -1227,7 +1227,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) } // Stack: // jump if condition was met - m_context << Instruction::ISZERO << Instruction::ISZERO; + m_context << InternalInstruction::ISZERO << InternalInstruction::ISZERO; auto success = m_context.appendConditionalJump(); if (function.kind() == FunctionType::Kind::Assert) // condition was not met, flag an error @@ -1291,7 +1291,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) // stack now: [] .. // adjust by 32(+4) bytes to accommodate the length(+selector) - m_context << u256(32 + (hasSelectorOrSignature ? 4 : 0)) << Instruction::ADD; + m_context << u256(32 + (hasSelectorOrSignature ? 4 : 0)) << InternalInstruction::ADD; // stack now: [] .. if (isPacked) @@ -1311,7 +1311,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) m_context.appendInlineAssembly(R"({ mstore(mem_ptr, sub(sub(mem_end, mem_ptr), 0x20)) })", {"mem_end", "mem_ptr"}); - m_context << Instruction::SWAP1; + m_context << InternalInstruction::SWAP1; utils().storeFreeMemoryPointer(); // stack: [] @@ -1338,7 +1338,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) // stack: utils().packedEncode(TypePointers{selectorType}, TypePointers()); utils().toSizeAfterFreeMemoryPointer(); - m_context << Instruction::KECCAK256; + m_context << InternalInstruction::KECCAK256; // stack: dataOnStack = TypeProvider::fixedBytes(32); @@ -1358,7 +1358,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) solAssert(selectorType->sizeOnStack() == 2); // stack: // Extract selector from the stack - m_context << Instruction::SWAP1 << Instruction::POP; + m_context << InternalInstruction::SWAP1 << InternalInstruction::POP; } // Conversion will be done below dataOnStack = TypeProvider::uint(32); @@ -1378,7 +1378,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) let mask := )" + mask + R"( mstore(data_start, or(and(data, mask), selector)) })", {"mem_ptr", "selector"}); - m_context << Instruction::POP; + m_context << InternalInstruction::POP; } // stack now: @@ -1405,8 +1405,8 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) else { utils().convertType(*firstArgType, *TypeProvider::bytesMemory()); - m_context << Instruction::DUP1 << u256(32) << Instruction::ADD; - m_context << Instruction::SWAP1 << Instruction::MLOAD; + m_context << InternalInstruction::DUP1 << u256(32) << InternalInstruction::ADD; + m_context << InternalInstruction::SWAP1 << InternalInstruction::MLOAD; // stack now: utils().abiDecode(targetTypes, true); @@ -1414,7 +1414,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) break; } case FunctionType::Kind::GasLeft: - m_context << Instruction::GAS; + m_context << InternalInstruction::GAS; break; case FunctionType::Kind::MetaType: // No code to generate. @@ -1649,7 +1649,7 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess) dynamic_cast(arg->annotation().referencedDeclaration) ) { - m_context << Instruction::SELFBALANCE; + m_context << InternalInstruction::SELFBALANCE; return false; } @@ -1671,7 +1671,7 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess) *TypeProvider::address(), true ); - m_context << Instruction::EXTCODESIZE; + m_context << InternalInstruction::EXTCODESIZE; return false; } @@ -1713,7 +1713,7 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess) *TypeProvider::address(), true ); - m_context << Instruction::BALANCE; + m_context << InternalInstruction::BALANCE; } else if (member == "code") { @@ -1724,28 +1724,28 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess) true ); - m_context << Instruction::DUP1 << Instruction::EXTCODESIZE; + m_context << InternalInstruction::DUP1 << InternalInstruction::EXTCODESIZE; // Stack post:
- m_context << Instruction::DUP1; + m_context << InternalInstruction::DUP1; // Account for the size field of `bytes memory` - m_context << u256(32) << Instruction::ADD; + m_context << u256(32) << InternalInstruction::ADD; utils().allocateMemory(); // Stack post:
// Store size at mem_offset - m_context << Instruction::DUP2 << Instruction::DUP2 << Instruction::MSTORE; + m_context << InternalInstruction::DUP2 << InternalInstruction::DUP2 << InternalInstruction::MSTORE; - m_context << u256(0) << Instruction::SWAP1 << Instruction::DUP1; + m_context << u256(0) << InternalInstruction::SWAP1 << InternalInstruction::DUP1; // Stack post:
0 - m_context << u256(32) << Instruction::ADD << Instruction::SWAP1; + m_context << u256(32) << InternalInstruction::ADD << InternalInstruction::SWAP1; // Stack post:
0 - m_context << Instruction::SWAP4; + m_context << InternalInstruction::SWAP4; // Stack post: 0
- m_context << Instruction::EXTCODECOPY; + m_context << InternalInstruction::EXTCODECOPY; // Stack post: } else if (member == "codehash") @@ -1755,7 +1755,7 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess) *TypeProvider::address(), true ); - m_context << Instruction::EXTCODEHASH; + m_context << InternalInstruction::EXTCODEHASH; } else if ((set{"send", "transfer"}).count(member)) { @@ -1785,7 +1785,7 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess) if (functionType.kind() == FunctionType::Kind::External) CompilerUtils(m_context).popStackSlots(functionType.sizeOnStack() - 2); - m_context << Instruction::SWAP1 << Instruction::POP; + m_context << InternalInstruction::SWAP1 << InternalInstruction::POP; /// need to store it as bytes4 utils().leftShiftNumberOnStack(224); @@ -1805,34 +1805,34 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess) case Type::Category::Magic: // we can ignore the kind of magic and only look at the name of the member if (member == "coinbase") - m_context << Instruction::COINBASE; + m_context << InternalInstruction::COINBASE; else if (member == "timestamp") - m_context << Instruction::TIMESTAMP; + m_context << InternalInstruction::TIMESTAMP; else if (member == "difficulty") - m_context << Instruction::DIFFICULTY; + m_context << InternalInstruction::DIFFICULTY; else if (member == "prevrandao") - m_context << Instruction::PREVRANDAO; + m_context << InternalInstruction::PREVRANDAO; else if (member == "number") - m_context << Instruction::NUMBER; + m_context << InternalInstruction::NUMBER; else if (member == "gaslimit") - m_context << Instruction::GASLIMIT; + m_context << InternalInstruction::GASLIMIT; else if (member == "sender") - m_context << Instruction::CALLER; + m_context << InternalInstruction::CALLER; else if (member == "value") - m_context << Instruction::CALLVALUE; + m_context << InternalInstruction::CALLVALUE; else if (member == "origin") - m_context << Instruction::ORIGIN; + m_context << InternalInstruction::ORIGIN; else if (member == "gasprice") - m_context << Instruction::GASPRICE; + m_context << InternalInstruction::GASPRICE; else if (member == "chainid") - m_context << Instruction::CHAINID; + m_context << InternalInstruction::CHAINID; else if (member == "basefee") - m_context << Instruction::BASEFEE; + m_context << InternalInstruction::BASEFEE; else if (member == "data") - m_context << u256(0) << Instruction::CALLDATASIZE; + m_context << u256(0) << InternalInstruction::CALLDATASIZE; else if (member == "sig") - m_context << u256(0) << Instruction::CALLDATALOAD - << (u256(0xffffffff) << (256 - 32)) << Instruction::AND; + m_context << u256(0) << InternalInstruction::CALLDATALOAD + << (u256(0xffffffff) << (256 - 32)) << InternalInstruction::AND; else if (member == "gas") solAssert(false, "Gas has been removed."); else if (member == "blockhash") @@ -1844,7 +1844,7 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess) solAssert(!contractType.isSuper(), ""); ContractDefinition const& contract = contractType.contractDefinition(); utils().fetchFreeMemoryPointer(); - m_context << Instruction::DUP1 << u256(32) << Instruction::ADD; + m_context << InternalInstruction::DUP1 << u256(32) << InternalInstruction::ADD; utils().copyContractCodeToMemory(contract, member == "creationCode"); // Stack: start end m_context.appendInlineAssembly( @@ -1854,7 +1854,7 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess) })")("free", to_string(CompilerUtils::freeMemoryPointer)).render(), {"start", "end"} ); - m_context << Instruction::POP; + m_context << InternalInstruction::POP; } else if (member == "name") { @@ -1865,9 +1865,9 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess) dynamic_cast(*arg).contractDefinition(); utils().allocateMemory(((contract.name().length() + 31) / 32) * 32 + 32); // store string length - m_context << u256(contract.name().length()) << Instruction::DUP2 << Instruction::MSTORE; + m_context << u256(contract.name().length()) << InternalInstruction::DUP2 << InternalInstruction::MSTORE; // adjust pointer - m_context << Instruction::DUP1 << u256(32) << Instruction::ADD; + m_context << InternalInstruction::DUP1 << u256(32) << InternalInstruction::ADD; utils().storeStringData(contract.name()); } else if (member == "interfaceId") @@ -1903,13 +1903,13 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess) case DataLocation::Storage: { pair const& offsets = type.storageOffsetsOfMember(member); - m_context << offsets.first << Instruction::ADD << u256(offsets.second); + m_context << offsets.first << InternalInstruction::ADD << u256(offsets.second); setLValueToStorageItem(_memberAccess); break; } case DataLocation::Memory: { - m_context << type.memoryOffsetOfMember(member) << Instruction::ADD; + m_context << type.memoryOffsetOfMember(member) << InternalInstruction::ADD; setLValue(_memberAccess, *memberType); break; } @@ -1917,13 +1917,13 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess) { if (_memberAccess.annotation().type->isDynamicallyEncoded()) { - m_context << Instruction::DUP1; - m_context << type.calldataOffsetOfMember(member) << Instruction::ADD; + m_context << InternalInstruction::DUP1; + m_context << type.calldataOffsetOfMember(member) << InternalInstruction::ADD; CompilerUtils(m_context).accessCalldataTail(*memberType); } else { - m_context << type.calldataOffsetOfMember(member) << Instruction::ADD; + m_context << type.calldataOffsetOfMember(member) << InternalInstruction::ADD; // For non-value types the calldata offset is returned directly. if (memberType->isValueType()) { @@ -1971,14 +1971,14 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess) switch (type.location()) { case DataLocation::CallData: - m_context << Instruction::SWAP1 << Instruction::POP; + m_context << InternalInstruction::SWAP1 << InternalInstruction::POP; break; case DataLocation::Storage: ArrayUtils(m_context).retrieveLength(type); - m_context << Instruction::SWAP1 << Instruction::POP; + m_context << InternalInstruction::SWAP1 << InternalInstruction::POP; break; case DataLocation::Memory: - m_context << Instruction::MLOAD; + m_context << InternalInstruction::MLOAD; break; } } @@ -2066,7 +2066,7 @@ bool ExpressionCompiler::visit(IndexAccess const& _indexAccess) TypePointers{_indexAccess.indexExpression()->annotation().type}, TypePointers{keyType} ); - m_context << Instruction::SWAP1; + m_context << InternalInstruction::SWAP1; utils().storeInMemoryDynamic(*TypeProvider::uint256()); utils().toSizeAfterFreeMemoryPointer(); } @@ -2074,12 +2074,12 @@ bool ExpressionCompiler::visit(IndexAccess const& _indexAccess) { m_context << u256(0); // memory position appendExpressionCopyToMemory(*keyType, *_indexAccess.indexExpression()); - m_context << Instruction::SWAP1; + m_context << InternalInstruction::SWAP1; solAssert(CompilerUtils::freeMemoryPointer >= 0x40, ""); utils().storeInMemoryDynamic(*TypeProvider::uint256()); m_context << u256(0); } - m_context << Instruction::KECCAK256; + m_context << InternalInstruction::KECCAK256; m_context << u256(0); setLValueToStorageItem(_indexAccess); break; @@ -2138,11 +2138,11 @@ bool ExpressionCompiler::visit(IndexAccess const& _indexAccess) // stack layout: // check out-of-bounds access m_context << u256(fixedBytesType.numBytes()); - m_context << Instruction::DUP2 << Instruction::LT << Instruction::ISZERO; + m_context << InternalInstruction::DUP2 << InternalInstruction::LT << InternalInstruction::ISZERO; // out-of-bounds access throws exception m_context.appendConditionalPanic(util::PanicCode::ArrayOutOfBounds); - m_context << Instruction::BYTE; + m_context << InternalInstruction::BYTE; utils().leftShiftNumberOnStack(256 - 8); break; } @@ -2187,16 +2187,16 @@ bool ExpressionCompiler::visit(IndexRangeAccess const& _indexAccess) m_context << u256(0); // stack: offset length sliceStart - m_context << Instruction::SWAP1; + m_context << InternalInstruction::SWAP1; // stack: offset sliceStart length if (_indexAccess.endExpression()) acceptAndConvert(*_indexAccess.endExpression(), *TypeProvider::uint256()); else - m_context << Instruction::DUP1; + m_context << InternalInstruction::DUP1; // stack: offset sliceStart length sliceEnd - m_context << Instruction::SWAP3; + m_context << InternalInstruction::SWAP3; // stack: sliceEnd sliceStart length offset m_context.callYulFunction(m_context.utilFunctions().calldataArrayIndexRangeAccess(*arrayType), 4, 2); @@ -2216,7 +2216,7 @@ void ExpressionCompiler::endVisit(Identifier const& _identifier) if (dynamic_cast(magicVar->type())) { solAssert(_identifier.name() == "this", ""); - m_context << Instruction::ADDRESS; + m_context << InternalInstruction::ADDRESS; } break; default: @@ -2294,11 +2294,11 @@ void ExpressionCompiler::appendAndOrOperatorCode(BinaryOperation const& _binaryO solAssert(c_op == Token::Or || c_op == Token::And, ""); _binaryOperation.leftExpression().accept(*this); - m_context << Instruction::DUP1; + m_context << InternalInstruction::DUP1; if (c_op == Token::And) - m_context << Instruction::ISZERO; + m_context << InternalInstruction::ISZERO; evmasm::AssemblyItem endLabel = m_context.appendConditionalJump(); - m_context << Instruction::POP; + m_context << InternalInstruction::POP; _binaryOperation.rightExpression().accept(*this); m_context << endLabel; } @@ -2311,18 +2311,18 @@ void ExpressionCompiler::appendCompareOperatorCode(Token _operator, Type const& if (functionType && functionType->kind() == FunctionType::Kind::External) { solUnimplementedAssert(functionType->sizeOnStack() == 2, ""); - m_context << Instruction::SWAP3; + m_context << InternalInstruction::SWAP3; - m_context << ((u256(1) << 160) - 1) << Instruction::AND; - m_context << Instruction::SWAP1; - m_context << ((u256(1) << 160) - 1) << Instruction::AND; - m_context << Instruction::EQ; - m_context << Instruction::SWAP2; - m_context << ((u256(1) << 32) - 1) << Instruction::AND; - m_context << Instruction::SWAP1; - m_context << ((u256(1) << 32) - 1) << Instruction::AND; - m_context << Instruction::EQ; - m_context << Instruction::AND; + m_context << ((u256(1) << 160) - 1) << InternalInstruction::AND; + m_context << InternalInstruction::SWAP1; + m_context << ((u256(1) << 160) - 1) << InternalInstruction::AND; + m_context << InternalInstruction::EQ; + m_context << InternalInstruction::SWAP2; + m_context << ((u256(1) << 32) - 1) << InternalInstruction::AND; + m_context << InternalInstruction::SWAP1; + m_context << ((u256(1) << 32) - 1) << InternalInstruction::AND; + m_context << InternalInstruction::EQ; + m_context << InternalInstruction::AND; } else { @@ -2331,14 +2331,14 @@ void ExpressionCompiler::appendCompareOperatorCode(Token _operator, Type const& { // We have to remove the upper bits (construction time value) because they might // be "unknown" in one of the operands and not in the other. - m_context << ((u256(1) << 32) - 1) << Instruction::AND; - m_context << Instruction::SWAP1; - m_context << ((u256(1) << 32) - 1) << Instruction::AND; + m_context << ((u256(1) << 32) - 1) << InternalInstruction::AND; + m_context << InternalInstruction::SWAP1; + m_context << ((u256(1) << 32) - 1) << InternalInstruction::AND; } - m_context << Instruction::EQ; + m_context << InternalInstruction::EQ; } if (_operator == Token::NotEqual) - m_context << Instruction::ISZERO; + m_context << InternalInstruction::ISZERO; } else { @@ -2351,19 +2351,19 @@ void ExpressionCompiler::appendCompareOperatorCode(Token _operator, Type const& { case Token::GreaterThanOrEqual: m_context << - (isSigned ? Instruction::SLT : Instruction::LT) << - Instruction::ISZERO; + (isSigned ? InternalInstruction::SLT : InternalInstruction::LT) << + InternalInstruction::ISZERO; break; case Token::LessThanOrEqual: m_context << - (isSigned ? Instruction::SGT : Instruction::GT) << - Instruction::ISZERO; + (isSigned ? InternalInstruction::SGT : InternalInstruction::GT) << + InternalInstruction::ISZERO; break; case Token::GreaterThan: - m_context << (isSigned ? Instruction::SGT : Instruction::GT); + m_context << (isSigned ? InternalInstruction::SGT : InternalInstruction::GT); break; case Token::LessThan: - m_context << (isSigned ? Instruction::SLT : Instruction::LT); + m_context << (isSigned ? InternalInstruction::SLT : InternalInstruction::LT); break; default: solAssert(false, "Unknown comparison operator."); @@ -2422,25 +2422,25 @@ void ExpressionCompiler::appendArithmeticOperatorCode(Token _operator, Type cons switch (_operator) { case Token::Add: - m_context << Instruction::ADD; + m_context << InternalInstruction::ADD; break; case Token::Sub: - m_context << Instruction::SUB; + m_context << InternalInstruction::SUB; break; case Token::Mul: - m_context << Instruction::MUL; + m_context << InternalInstruction::MUL; break; case Token::Div: case Token::Mod: { // Test for division by zero - m_context << Instruction::DUP2 << Instruction::ISZERO; + m_context << InternalInstruction::DUP2 << InternalInstruction::ISZERO; m_context.appendConditionalPanic(util::PanicCode::DivisionByZero); if (_operator == Token::Div) - m_context << (c_isSigned ? Instruction::SDIV : Instruction::DIV); + m_context << (c_isSigned ? InternalInstruction::SDIV : InternalInstruction::DIV); else - m_context << (c_isSigned ? Instruction::SMOD : Instruction::MOD); + m_context << (c_isSigned ? InternalInstruction::SMOD : InternalInstruction::MOD); break; } default: @@ -2454,13 +2454,13 @@ void ExpressionCompiler::appendBitOperatorCode(Token _operator) switch (_operator) { case Token::BitOr: - m_context << Instruction::OR; + m_context << InternalInstruction::OR; break; case Token::BitAnd: - m_context << Instruction::AND; + m_context << InternalInstruction::AND; break; case Token::BitXor: - m_context << Instruction::XOR; + m_context << InternalInstruction::XOR; break; default: solAssert(false, "Unknown bit operator."); @@ -2489,20 +2489,20 @@ void ExpressionCompiler::appendShiftOperatorCode(Token _operator, Type const& _v else solAssert(false, "Invalid shift amount type."); - m_context << Instruction::SWAP1; + m_context << InternalInstruction::SWAP1; // stack: value_to_shift shift_amount switch (_operator) { case Token::SHL: if (m_context.evmVersion().hasBitwiseShifting()) - m_context << Instruction::SHL; + m_context << InternalInstruction::SHL; else - m_context << u256(2) << Instruction::EXP << Instruction::MUL; + m_context << u256(2) << InternalInstruction::EXP << InternalInstruction::MUL; break; case Token::SAR: if (m_context.evmVersion().hasBitwiseShifting()) - m_context << (c_valueSigned ? Instruction::SAR : Instruction::SHR); + m_context << (c_valueSigned ? InternalInstruction::SAR : InternalInstruction::SHR); else { if (c_valueSigned) @@ -2528,7 +2528,7 @@ void ExpressionCompiler::appendShiftOperatorCode(Token _operator, Type const& _v m_context.appendInlineAssembly(R"({ value_to_shift := div(value_to_shift, exp(2, shift_amount)) })", {"value_to_shift", "shift_amount"}); - m_context << Instruction::POP; + m_context << InternalInstruction::POP; } break; @@ -2550,7 +2550,7 @@ void ExpressionCompiler::appendExpOperatorCode(Type const& _valueType, Type cons dynamic_cast(_exponentType) ), 2, 1); else - m_context << Instruction::EXP; + m_context << InternalInstruction::EXP; } void ExpressionCompiler::appendExternalFunctionCall( @@ -2626,8 +2626,8 @@ void ExpressionCompiler::appendExternalFunctionCall( // zero bytes (which we cannot detect). solAssert(0 < retSize && retSize <= 32, ""); utils().fetchFreeMemoryPointer(); - m_context << u256(0) << Instruction::DUP2 << Instruction::MSTORE; - m_context << u256(32) << Instruction::ADD; + m_context << u256(0) << InternalInstruction::DUP2 << InternalInstruction::MSTORE; + m_context << u256(32) << InternalInstruction::ADD; utils().storeFreeMemoryPointer(); } @@ -2642,7 +2642,7 @@ void ExpressionCompiler::appendExternalFunctionCall( m_context << u256(0); utils().fetchFreeMemoryPointer(); // This touches too much, but that way we save some rounding arithmetic - m_context << u256(retSize) << Instruction::ADD << Instruction::MSTORE; + m_context << u256(retSize) << InternalInstruction::ADD << InternalInstruction::MSTORE; } } @@ -2687,15 +2687,15 @@ void ExpressionCompiler::appendExternalFunctionCall( if (funKind == FunctionType::Kind::ECRecover) { // In this case, output is 32 bytes before input and has already been cleared. - m_context << u256(32) << Instruction::DUP2 << Instruction::SUB << Instruction::SWAP1; + m_context << u256(32) << InternalInstruction::DUP2 << InternalInstruction::SUB << InternalInstruction::SWAP1; // Here: - m_context << Instruction::DUP1 << Instruction::DUP5 << Instruction::SUB; - m_context << Instruction::SWAP1; + m_context << InternalInstruction::DUP1 << InternalInstruction::DUP5 << InternalInstruction::SUB; + m_context << InternalInstruction::SWAP1; } else { - m_context << Instruction::DUP1 << Instruction::DUP4 << Instruction::SUB; - m_context << Instruction::DUP2; + m_context << InternalInstruction::DUP1 << InternalInstruction::DUP4 << InternalInstruction::SUB; + m_context << InternalInstruction::DUP2; } // CALL arguments: outSize, outOff, inSize, inOff (already present up to here) @@ -2725,7 +2725,7 @@ void ExpressionCompiler::appendExternalFunctionCall( m_context.revertStrings() >= RevertStrings::Debug ) { - m_context << Instruction::DUP1 << Instruction::EXTCODESIZE << Instruction::ISZERO; + m_context << InternalInstruction::DUP1 << InternalInstruction::EXTCODESIZE << InternalInstruction::ISZERO; m_context.appendConditionalRevert(false, "Target contract does not contain code"); existenceChecked = true; } @@ -2735,7 +2735,7 @@ void ExpressionCompiler::appendExternalFunctionCall( m_context << dupInstruction(m_context.baseToCurrentStackOffset(gasStackPos)); else if (m_context.evmVersion().canOverchargeGasForCall()) // Send all gas (requires tangerine whistle EVM) - m_context << Instruction::GAS; + m_context << InternalInstruction::GAS; else { // send all gas except the amount needed to execute "SUB" and "CALL" @@ -2745,15 +2745,15 @@ void ExpressionCompiler::appendExternalFunctionCall( gasNeededByCaller += evmasm::GasCosts::callValueTransferGas; if (!existenceChecked) gasNeededByCaller += evmasm::GasCosts::callNewAccountGas; // we never know - m_context << gasNeededByCaller << Instruction::GAS << Instruction::SUB; + m_context << gasNeededByCaller << InternalInstruction::GAS << InternalInstruction::SUB; } // Order is important here, STATICCALL might overlap with DELEGATECALL. if (isDelegateCall) - m_context << Instruction::DELEGATECALL; + m_context << InternalInstruction::DELEGATECALL; else if (useStaticCall) - m_context << Instruction::STATICCALL; + m_context << InternalInstruction::STATICCALL; else - m_context << Instruction::CALL; + m_context << InternalInstruction::CALL; unsigned remainsSize = 2u + // contract address, input_memory_end @@ -2766,7 +2766,7 @@ void ExpressionCompiler::appendExternalFunctionCall( if (!returnSuccessConditionAndReturndata && !_tryCall) { // Propagate error condition (if CALL pushes 0 on stack). - m_context << Instruction::ISZERO; + m_context << InternalInstruction::ISZERO; m_context.appendConditionalRevert(true); } else @@ -2777,9 +2777,9 @@ void ExpressionCompiler::appendExternalFunctionCall( if (_tryCall) { - m_context << Instruction::DUP1 << Instruction::ISZERO; + m_context << InternalInstruction::DUP1 << InternalInstruction::ISZERO; m_context.appendConditionalJumpTo(endTag); - m_context << Instruction::POP; + m_context << InternalInstruction::POP; } if (returnSuccessConditionAndReturndata) @@ -2804,7 +2804,7 @@ void ExpressionCompiler::appendExternalFunctionCall( // Failing ecrecover cannot be detected, so we clear output before the call. m_context << u256(32); utils().fetchFreeMemoryPointer(); - m_context << Instruction::SUB << Instruction::MLOAD; + m_context << InternalInstruction::SUB << InternalInstruction::MLOAD; } else if (!returnTypes.empty()) { @@ -2832,7 +2832,7 @@ void ExpressionCompiler::appendExternalFunctionCall( solAssert(retSize > 0, ""); // Always use the actual return length, and not our calculated expected length, if returndatacopy is supported. // This ensures it can catch badly formatted input from external calls. - m_context << (haveReturndatacopy ? evmasm::AssemblyItem(Instruction::RETURNDATASIZE) : u256(retSize)); + m_context << (haveReturndatacopy ? evmasm::AssemblyItem(InternalInstruction::RETURNDATASIZE) : u256(retSize)); // Stack: return_data_start return_data_size if (needToUpdateFreeMemoryPtr) m_context.appendInlineAssembly(R"({ diff --git a/libsolidity/codegen/LValue.cpp b/libsolidity/codegen/LValue.cpp index 2708d319d..31f82b211 100644 --- a/libsolidity/codegen/LValue.cpp +++ b/libsolidity/codegen/LValue.cpp @@ -70,7 +70,7 @@ void StackVariable::storeValue(Type const&, SourceLocation const& _location, boo ); else if (stackDiff > 0) for (unsigned i = 0; i < m_size; ++i) - m_context << swapInstruction(stackDiff) << Instruction::POP; + m_context << swapInstruction(stackDiff) << InternalInstruction::POP; if (!_move) retrieveValue(_location); } @@ -92,11 +92,11 @@ void MemoryItem::retrieveValue(SourceLocation const&, bool _remove) const if (m_dataType->isValueType()) { if (!_remove) - m_context << Instruction::DUP1; + m_context << InternalInstruction::DUP1; CompilerUtils(m_context).loadFromMemoryDynamic(*m_dataType, false, m_padded, false); } else - m_context << Instruction::MLOAD; + m_context << InternalInstruction::MLOAD; } void MemoryItem::storeValue(Type const& _sourceType, SourceLocation const&, bool _move) const @@ -117,13 +117,13 @@ void MemoryItem::storeValue(Type const& _sourceType, SourceLocation const&, bool solAssert(m_dataType->calldataEncodedSize(false) == 1, "Invalid non-padded type."); solAssert(m_dataType->category() != Type::Category::UserDefinedValueType, ""); if (m_dataType->category() == Type::Category::FixedBytes) - m_context << u256(0) << Instruction::BYTE; - m_context << Instruction::SWAP1 << Instruction::MSTORE8; + m_context << u256(0) << InternalInstruction::BYTE; + m_context << InternalInstruction::SWAP1 << InternalInstruction::MSTORE8; } else { utils.storeInMemoryDynamic(*m_dataType, m_padded); - m_context << Instruction::POP; + m_context << InternalInstruction::POP; } } else @@ -132,10 +132,10 @@ void MemoryItem::storeValue(Type const& _sourceType, SourceLocation const&, bool solAssert(m_dataType->sizeOnStack() == 1, ""); if (!_move) - m_context << Instruction::DUP2 << Instruction::SWAP1; + m_context << InternalInstruction::DUP2 << InternalInstruction::SWAP1; // stack: [value] value lvalue // only store the reference - m_context << Instruction::MSTORE; + m_context << InternalInstruction::MSTORE; } } @@ -145,7 +145,7 @@ void MemoryItem::setToZero(SourceLocation const&, bool _removeReference) const solAssert(_removeReference, ""); utils.pushZeroValue(*m_dataType); utils.storeInMemoryDynamic(*m_dataType, m_padded); - m_context << Instruction::POP; + m_context << InternalInstruction::POP; } @@ -184,7 +184,7 @@ void ImmutableItem::storeValue(Type const& _sourceType, SourceLocation const&, b else utils.copyToStackTop(m_dataType->sizeOnStack() + 1, m_dataType->sizeOnStack()); utils.storeInMemoryDynamic(*m_dataType); - m_context << Instruction::POP; + m_context << InternalInstruction::POP; } void ImmutableItem::setToZero(SourceLocation const&, bool) const @@ -218,15 +218,15 @@ void StorageItem::retrieveValue(SourceLocation const&, bool _remove) const { solAssert(m_dataType->sizeOnStack() == 1, "Invalid storage ref size."); if (_remove) - m_context << Instruction::POP; // remove byte offset + m_context << InternalInstruction::POP; // remove byte offset else - m_context << Instruction::DUP2; + m_context << InternalInstruction::DUP2; return; } if (!_remove) CompilerUtils(m_context).copyToStackTop(sizeOnStack(), sizeOnStack()); if (m_dataType->storageBytes() == 32) - m_context << Instruction::POP << Instruction::SLOAD; + m_context << InternalInstruction::POP << InternalInstruction::SLOAD; else { Type const* type = m_dataType; @@ -234,8 +234,8 @@ void StorageItem::retrieveValue(SourceLocation const&, bool _remove) const type = type->encodingType(); bool cleaned = false; m_context - << Instruction::SWAP1 << Instruction::SLOAD << Instruction::SWAP1 - << u256(0x100) << Instruction::EXP << Instruction::SWAP1 << Instruction::DIV; + << InternalInstruction::SWAP1 << InternalInstruction::SLOAD << InternalInstruction::SWAP1 + << u256(0x100) << InternalInstruction::EXP << InternalInstruction::SWAP1 << InternalInstruction::DIV; if (type->category() == Type::Category::FixedPoint) // implementation should be very similar to the integer case. solUnimplemented("Not yet implemented - FixedPointType."); @@ -248,9 +248,9 @@ void StorageItem::retrieveValue(SourceLocation const&, bool _remove) const } else if (fun->kind() == FunctionType::Kind::Internal) { - m_context << Instruction::DUP1 << Instruction::ISZERO; + m_context << InternalInstruction::DUP1 << InternalInstruction::ISZERO; CompilerUtils(m_context).pushZeroValue(*fun); - m_context << Instruction::MUL << Instruction::OR; + m_context << InternalInstruction::MUL << InternalInstruction::OR; } } else if (type->leftAligned()) @@ -263,14 +263,14 @@ void StorageItem::retrieveValue(SourceLocation const&, bool _remove) const dynamic_cast(*type).isSigned() ) { - m_context << u256(type->storageBytes() - 1) << Instruction::SIGNEXTEND; + m_context << u256(type->storageBytes() - 1) << InternalInstruction::SIGNEXTEND; cleaned = true; } if (!cleaned) { solAssert(type->sizeOnStack() == 1, ""); - m_context << ((u256(0x1) << (8 * type->storageBytes())) - 1) << Instruction::AND; + m_context << ((u256(0x1) << (8 * type->storageBytes())) - 1) << InternalInstruction::AND; } } } @@ -289,29 +289,29 @@ void StorageItem::storeValue(Type const& _sourceType, SourceLocation const& _loc { solAssert(m_dataType->sizeOnStack() == 1, "Invalid stack size."); // offset should be zero - m_context << Instruction::POP; + m_context << InternalInstruction::POP; if (!_move) - m_context << Instruction::DUP2 << Instruction::SWAP1; + m_context << InternalInstruction::DUP2 << InternalInstruction::SWAP1; - m_context << Instruction::SWAP1; + m_context << InternalInstruction::SWAP1; utils.convertType(_sourceType, *m_dataType, true); - m_context << Instruction::SWAP1; + m_context << InternalInstruction::SWAP1; - m_context << Instruction::SSTORE; + m_context << InternalInstruction::SSTORE; } else { // OR the value into the other values in the storage slot - m_context << u256(0x100) << Instruction::EXP; + m_context << u256(0x100) << InternalInstruction::EXP; // stack: value storage_ref multiplier // fetch old value - m_context << Instruction::DUP2 << Instruction::SLOAD; + m_context << InternalInstruction::DUP2 << InternalInstruction::SLOAD; // stack: value storage_ref multiplier old_full_value // clear bytes in old value m_context - << Instruction::DUP2 << ((u256(1) << (8 * m_dataType->storageBytes())) - 1) - << Instruction::MUL; - m_context << Instruction::NOT << Instruction::AND << Instruction::SWAP1; + << InternalInstruction::DUP2 << ((u256(1) << (8 * m_dataType->storageBytes())) - 1) + << InternalInstruction::MUL; + m_context << InternalInstruction::NOT << InternalInstruction::AND << InternalInstruction::SWAP1; // stack: value storage_ref cleared_value multiplier utils.copyToStackTop(3 + m_dataType->sizeOnStack(), m_dataType->sizeOnStack()); // stack: value storage_ref cleared_value multiplier value @@ -333,7 +333,7 @@ void StorageItem::storeValue(Type const& _sourceType, SourceLocation const& _loc solAssert(fun->sizeOnStack() == 1, ""); m_context << ((u256(1) << (8 * m_dataType->storageBytes())) - 1) << - Instruction::AND; + InternalInstruction::AND; } } else if (m_dataType->leftAligned()) @@ -350,9 +350,9 @@ void StorageItem::storeValue(Type const& _sourceType, SourceLocation const& _loc // remove the higher order bits utils.convertType(_sourceType, *m_dataType, true, true); } - m_context << Instruction::MUL << Instruction::OR; + m_context << InternalInstruction::MUL << InternalInstruction::OR; // stack: value storage_ref updated_value - m_context << Instruction::SWAP1 << Instruction::SSTORE; + m_context << InternalInstruction::SWAP1 << InternalInstruction::SSTORE; if (_move) utils.popStackElement(*m_dataType); } @@ -365,19 +365,19 @@ void StorageItem::storeValue(Type const& _sourceType, SourceLocation const& _loc ); if (m_dataType->category() == Type::Category::Array) { - m_context << Instruction::POP; // remove byte offset + m_context << InternalInstruction::POP; // remove byte offset ArrayUtils(m_context).copyArrayToStorage( dynamic_cast(*m_dataType), dynamic_cast(_sourceType) ); if (_move) - m_context << Instruction::POP; + m_context << InternalInstruction::POP; } else if (m_dataType->category() == Type::Category::Struct) { // stack layout: source_ref target_ref target_offset // note that we have structs, so offset should be zero and are ignored - m_context << Instruction::POP; + m_context << InternalInstruction::POP; auto const& structType = dynamic_cast(*m_dataType); auto const& sourceType = dynamic_cast(_sourceType); solAssert( @@ -389,7 +389,7 @@ void StorageItem::storeValue(Type const& _sourceType, SourceLocation const& _loc { solAssert(sourceType.sizeOnStack() == 1, ""); solAssert(structType.sizeOnStack() == 1, ""); - m_context << Instruction::DUP2 << Instruction::DUP2; + m_context << InternalInstruction::DUP2 << InternalInstruction::DUP2; m_context.callYulFunction(m_context.utilFunctions().updateStorageValueFunction(sourceType, structType, 0), 2, 0); } else @@ -404,7 +404,7 @@ void StorageItem::storeValue(Type const& _sourceType, SourceLocation const& _loc { // stack layout: source_ref target_ref pair const& offsets = sourceType.storageOffsetsOfMember(member.name); - m_context << offsets.first << Instruction::DUP3 << Instruction::ADD; + m_context << offsets.first << InternalInstruction::DUP3 << InternalInstruction::ADD; m_context << u256(offsets.second); // stack: source_ref target_ref source_member_ref source_member_off StorageItem(m_context, *sourceMemberType).retrieveValue(_location, true); @@ -415,13 +415,13 @@ void StorageItem::storeValue(Type const& _sourceType, SourceLocation const& _loc solAssert(sourceType.location() == DataLocation::Memory, ""); // stack layout: source_ref target_ref m_context << sourceType.memoryOffsetOfMember(member.name); - m_context << Instruction::DUP3 << Instruction::ADD; + m_context << InternalInstruction::DUP3 << InternalInstruction::ADD; MemoryItem(m_context, *sourceMemberType).retrieveValue(_location, true); // stack layout: source_ref target_ref source_value... } unsigned stackSize = sourceMemberType->sizeOnStack(); pair const& offsets = structType.storageOffsetsOfMember(member.name); - m_context << dupInstruction(1 + stackSize) << offsets.first << Instruction::ADD; + m_context << dupInstruction(1 + stackSize) << offsets.first << InternalInstruction::ADD; m_context << u256(offsets.second); // stack: source_ref target_ref target_off source_value... target_member_ref target_member_byte_off StorageItem(m_context, *memberType).storeValue(*sourceMemberType, _location, true); @@ -432,7 +432,7 @@ void StorageItem::storeValue(Type const& _sourceType, SourceLocation const& _loc if (_move) utils.popStackSlots(2); else - m_context << Instruction::SWAP1 << Instruction::POP; + m_context << InternalInstruction::SWAP1 << InternalInstruction::POP; } else BOOST_THROW_EXCEPTION( @@ -464,12 +464,12 @@ void StorageItem::setToZero(SourceLocation const&, bool _removeReference) const continue; pair const& offsets = structType.storageOffsetsOfMember(member.name); m_context - << offsets.first << Instruction::DUP3 << Instruction::ADD + << offsets.first << InternalInstruction::DUP3 << InternalInstruction::ADD << u256(offsets.second); StorageItem(m_context, *memberType).setToZero(); } if (_removeReference) - m_context << Instruction::POP << Instruction::POP; + m_context << InternalInstruction::POP << InternalInstruction::POP; } else { @@ -480,23 +480,23 @@ void StorageItem::setToZero(SourceLocation const&, bool _removeReference) const { // offset should be zero m_context - << Instruction::POP << u256(0) - << Instruction::SWAP1 << Instruction::SSTORE; + << InternalInstruction::POP << u256(0) + << InternalInstruction::SWAP1 << InternalInstruction::SSTORE; } else { - m_context << u256(0x100) << Instruction::EXP; + m_context << u256(0x100) << InternalInstruction::EXP; // stack: storage_ref multiplier // fetch old value - m_context << Instruction::DUP2 << Instruction::SLOAD; + m_context << InternalInstruction::DUP2 << InternalInstruction::SLOAD; // stack: storage_ref multiplier old_full_value // clear bytes in old value m_context - << Instruction::SWAP1 << ((u256(1) << (8 * m_dataType->storageBytes())) - 1) - << Instruction::MUL; - m_context << Instruction::NOT << Instruction::AND; + << InternalInstruction::SWAP1 << ((u256(1) << (8 * m_dataType->storageBytes())) - 1) + << InternalInstruction::MUL; + m_context << InternalInstruction::NOT << InternalInstruction::AND; // stack: storage_ref cleared_value - m_context << Instruction::SWAP1 << Instruction::SSTORE; + m_context << InternalInstruction::SWAP1 << InternalInstruction::SSTORE; } } } @@ -510,47 +510,47 @@ void StorageByteArrayElement::retrieveValue(SourceLocation const&, bool _remove) { // stack: ref byte_number if (_remove) - m_context << Instruction::SWAP1 << Instruction::SLOAD - << Instruction::SWAP1 << Instruction::BYTE; + m_context << InternalInstruction::SWAP1 << InternalInstruction::SLOAD + << InternalInstruction::SWAP1 << InternalInstruction::BYTE; else - m_context << Instruction::DUP2 << Instruction::SLOAD - << Instruction::DUP2 << Instruction::BYTE; - m_context << (u256(1) << (256 - 8)) << Instruction::MUL; + m_context << InternalInstruction::DUP2 << InternalInstruction::SLOAD + << InternalInstruction::DUP2 << InternalInstruction::BYTE; + m_context << (u256(1) << (256 - 8)) << InternalInstruction::MUL; } void StorageByteArrayElement::storeValue(Type const&, SourceLocation const&, bool _move) const { // stack: value ref byte_number - m_context << u256(31) << Instruction::SUB << u256(0x100) << Instruction::EXP; + m_context << u256(31) << InternalInstruction::SUB << u256(0x100) << InternalInstruction::EXP; // stack: value ref (1<<(8*(31-byte_number))) - m_context << Instruction::DUP2 << Instruction::SLOAD; + m_context << InternalInstruction::DUP2 << InternalInstruction::SLOAD; // stack: value ref (1<<(8*(31-byte_number))) old_full_value // clear byte in old value - m_context << Instruction::DUP2 << u256(0xff) << Instruction::MUL - << Instruction::NOT << Instruction::AND; + m_context << InternalInstruction::DUP2 << u256(0xff) << InternalInstruction::MUL + << InternalInstruction::NOT << InternalInstruction::AND; // stack: value ref (1<<(32-byte_number)) old_full_value_with_cleared_byte - m_context << Instruction::SWAP1; - m_context << (u256(1) << (256 - 8)) << Instruction::DUP5 << Instruction::DIV - << Instruction::MUL << Instruction::OR; + m_context << InternalInstruction::SWAP1; + m_context << (u256(1) << (256 - 8)) << InternalInstruction::DUP5 << InternalInstruction::DIV + << InternalInstruction::MUL << InternalInstruction::OR; // stack: value ref new_full_value - m_context << Instruction::SWAP1 << Instruction::SSTORE; + m_context << InternalInstruction::SWAP1 << InternalInstruction::SSTORE; if (_move) - m_context << Instruction::POP; + m_context << InternalInstruction::POP; } void StorageByteArrayElement::setToZero(SourceLocation const&, bool _removeReference) const { // stack: ref byte_number solAssert(_removeReference, ""); - m_context << u256(31) << Instruction::SUB << u256(0x100) << Instruction::EXP; + m_context << u256(31) << InternalInstruction::SUB << u256(0x100) << InternalInstruction::EXP; // stack: ref (1<<(8*(31-byte_number))) - m_context << Instruction::DUP2 << Instruction::SLOAD; + m_context << InternalInstruction::DUP2 << InternalInstruction::SLOAD; // stack: ref (1<<(8*(31-byte_number))) old_full_value // clear byte in old value - m_context << Instruction::SWAP1 << u256(0xff) << Instruction::MUL; - m_context << Instruction::NOT << Instruction::AND; + m_context << InternalInstruction::SWAP1 << u256(0xff) << InternalInstruction::MUL; + m_context << InternalInstruction::NOT << InternalInstruction::AND; // stack: ref old_full_value_with_cleared_byte - m_context << Instruction::SWAP1 << Instruction::SSTORE; + m_context << InternalInstruction::SWAP1 << InternalInstruction::SSTORE; } TupleObject::TupleObject( diff --git a/libsolidity/interface/GasEstimator.cpp b/libsolidity/interface/GasEstimator.cpp index 512f91bee..1fa1be8b9 100644 --- a/libsolidity/interface/GasEstimator.cpp +++ b/libsolidity/interface/GasEstimator.cpp @@ -56,26 +56,26 @@ GasEstimator::GasConsumption GasEstimator::functionalEstimation( using Id = ExpressionClasses::Id; using Ids = vector; Id hashValue = classes.find(u256(util::selectorFromSignatureU32(_signature))); - Id calldata = classes.find(Instruction::CALLDATALOAD, Ids{classes.find(u256(0))}); + Id calldata = classes.find(InternalInstruction::CALLDATALOAD, Ids{classes.find(u256(0))}); if (!m_evmVersion.hasBitwiseShifting()) // div(calldataload(0), 1 << 224) equals to hashValue classes.forceEqual( hashValue, - Instruction::DIV, + InternalInstruction::DIV, Ids{calldata, classes.find(u256(1) << 224)} ); else // shr(0xe0, calldataload(0)) equals to hashValue classes.forceEqual( hashValue, - Instruction::SHR, + InternalInstruction::SHR, Ids{classes.find(u256(0xe0)), calldata} ); // lt(calldatasize(), 4) equals to 0 (ignore the shortcut for fallback functions) classes.forceEqual( classes.find(u256(0)), - Instruction::LT, - Ids{classes.find(Instruction::CALLDATASIZE), classes.find(u256(4))} + InternalInstruction::LT, + Ids{classes.find(InternalInstruction::CALLDATASIZE), classes.find(u256(4))} ); } diff --git a/libyul/AsmAnalysis.cpp b/libyul/AsmAnalysis.cpp index 83fb0f5fc..b6228201c 100644 --- a/libyul/AsmAnalysis.cpp +++ b/libyul/AsmAnalysis.cpp @@ -702,7 +702,7 @@ bool AsmAnalyzer::validateInstructions(std::string const& _instructionIdentifier return false; } -bool AsmAnalyzer::validateInstructions(evmasm::Instruction _instr, SourceLocation const& _location) +bool AsmAnalyzer::validateInstructions(evmasm::InternalInstruction _instr, SourceLocation const& _location) { // We assume that returndatacopy, returndatasize and staticcall are either all available // or all not available. @@ -712,9 +712,9 @@ bool AsmAnalyzer::validateInstructions(evmasm::Instruction _instr, SourceLocatio // These instructions are disabled in the dialect. yulAssert( - _instr != evmasm::Instruction::JUMP && - _instr != evmasm::Instruction::JUMPI && - _instr != evmasm::Instruction::JUMPDEST, + _instr != evmasm::InternalInstruction::JUMP && + _instr != evmasm::InternalInstruction::JUMPI && + _instr != evmasm::InternalInstruction::JUMPDEST, ""); bool returnValue = true; @@ -733,29 +733,29 @@ bool AsmAnalyzer::validateInstructions(evmasm::Instruction _instr, SourceLocatio returnValue = false; }; - if (_instr == evmasm::Instruction::RETURNDATACOPY && !m_evmVersion.supportsReturndata()) + if (_instr == evmasm::InternalInstruction::RETURNDATACOPY && !m_evmVersion.supportsReturndata()) errorForVM(7756_error, "only available for Byzantium-compatible"); - else if (_instr == evmasm::Instruction::RETURNDATASIZE && !m_evmVersion.supportsReturndata()) + else if (_instr == evmasm::InternalInstruction::RETURNDATASIZE && !m_evmVersion.supportsReturndata()) errorForVM(4778_error, "only available for Byzantium-compatible"); - else if (_instr == evmasm::Instruction::STATICCALL && !m_evmVersion.hasStaticCall()) + else if (_instr == evmasm::InternalInstruction::STATICCALL && !m_evmVersion.hasStaticCall()) errorForVM(1503_error, "only available for Byzantium-compatible"); - else if (_instr == evmasm::Instruction::SHL && !m_evmVersion.hasBitwiseShifting()) + else if (_instr == evmasm::InternalInstruction::SHL && !m_evmVersion.hasBitwiseShifting()) errorForVM(6612_error, "only available for Constantinople-compatible"); - else if (_instr == evmasm::Instruction::SHR && !m_evmVersion.hasBitwiseShifting()) + else if (_instr == evmasm::InternalInstruction::SHR && !m_evmVersion.hasBitwiseShifting()) errorForVM(7458_error, "only available for Constantinople-compatible"); - else if (_instr == evmasm::Instruction::SAR && !m_evmVersion.hasBitwiseShifting()) + else if (_instr == evmasm::InternalInstruction::SAR && !m_evmVersion.hasBitwiseShifting()) errorForVM(2054_error, "only available for Constantinople-compatible"); - else if (_instr == evmasm::Instruction::CREATE2 && !m_evmVersion.hasCreate2()) + else if (_instr == evmasm::InternalInstruction::CREATE2 && !m_evmVersion.hasCreate2()) errorForVM(6166_error, "only available for Constantinople-compatible"); - else if (_instr == evmasm::Instruction::EXTCODEHASH && !m_evmVersion.hasExtCodeHash()) + else if (_instr == evmasm::InternalInstruction::EXTCODEHASH && !m_evmVersion.hasExtCodeHash()) errorForVM(7110_error, "only available for Constantinople-compatible"); - else if (_instr == evmasm::Instruction::CHAINID && !m_evmVersion.hasChainID()) + else if (_instr == evmasm::InternalInstruction::CHAINID && !m_evmVersion.hasChainID()) errorForVM(1561_error, "only available for Istanbul-compatible"); - else if (_instr == evmasm::Instruction::SELFBALANCE && !m_evmVersion.hasSelfBalance()) + else if (_instr == evmasm::InternalInstruction::SELFBALANCE && !m_evmVersion.hasSelfBalance()) errorForVM(7721_error, "only available for Istanbul-compatible"); - else if (_instr == evmasm::Instruction::BASEFEE && !m_evmVersion.hasBaseFee()) + else if (_instr == evmasm::InternalInstruction::BASEFEE && !m_evmVersion.hasBaseFee()) errorForVM(5430_error, "only available for London-compatible"); - else if (_instr == evmasm::Instruction::PC) + else if (_instr == evmasm::InternalInstruction::PC) m_errorReporter.error( 2450_error, Error::Type::SyntaxError, diff --git a/libyul/AsmAnalysis.h b/libyul/AsmAnalysis.h index c71b4cbe3..56b7ce3c5 100644 --- a/libyul/AsmAnalysis.h +++ b/libyul/AsmAnalysis.h @@ -114,7 +114,7 @@ private: void expectValidType(YulString _type, langutil::SourceLocation const& _location); void expectType(YulString _expectedType, YulString _givenType, langutil::SourceLocation const& _location); - bool validateInstructions(evmasm::Instruction _instr, langutil::SourceLocation const& _location); + bool validateInstructions(evmasm::InternalInstruction _instr, langutil::SourceLocation const& _location); bool validateInstructions(std::string const& _instrIdentifier, langutil::SourceLocation const& _location); bool validateInstructions(FunctionCall const& _functionCall); diff --git a/libyul/backends/evm/AbstractAssembly.h b/libyul/backends/evm/AbstractAssembly.h index 2d7be9001..5fe55384c 100644 --- a/libyul/backends/evm/AbstractAssembly.h +++ b/libyul/backends/evm/AbstractAssembly.h @@ -40,7 +40,7 @@ struct SourceLocation; namespace solidity::evmasm { -enum class Instruction: uint8_t; +enum class InternalInstruction: uint8_t; } namespace solidity::yul @@ -66,7 +66,7 @@ public: virtual int stackHeight() const = 0; virtual void setStackHeight(int height) = 0; /// Append an EVM instruction. - virtual void appendInstruction(evmasm::Instruction _instruction) = 0; + virtual void appendInstruction(evmasm::InternalInstruction _instruction) = 0; /// Append a constant. virtual void appendConstant(u256 const& _constant) = 0; /// Append a label. diff --git a/libyul/backends/evm/ConstantOptimiser.cpp b/libyul/backends/evm/ConstantOptimiser.cpp index 59e987b69..99ba1659c 100644 --- a/libyul/backends/evm/ConstantOptimiser.cpp +++ b/libyul/backends/evm/ConstantOptimiser.cpp @@ -48,24 +48,24 @@ struct MiniEVMInterpreter return std::visit(*this, _expr); } - u256 eval(evmasm::Instruction _instr, vector const& _arguments) + u256 eval(evmasm::InternalInstruction _instr, vector const& _arguments) { vector args; for (auto const& arg: _arguments) args.emplace_back(eval(arg)); switch (_instr) { - case evmasm::Instruction::ADD: + case evmasm::InternalInstruction::ADD: return args.at(0) + args.at(1); - case evmasm::Instruction::SUB: + case evmasm::InternalInstruction::SUB: return args.at(0) - args.at(1); - case evmasm::Instruction::MUL: + case evmasm::InternalInstruction::MUL: return args.at(0) * args.at(1); - case evmasm::Instruction::EXP: + case evmasm::InternalInstruction::EXP: return exp256(args.at(0), args.at(1)); - case evmasm::Instruction::SHL: + case evmasm::InternalInstruction::SHL: return args.at(0) > 255 ? 0 : (args.at(1) << unsigned(args.at(0))); - case evmasm::Instruction::NOT: + case evmasm::InternalInstruction::NOT: return ~args.at(0); default: yulAssert(false, "Invalid operation generated in constant optimizer."); diff --git a/libyul/backends/evm/EVMCodeTransform.cpp b/libyul/backends/evm/EVMCodeTransform.cpp index 7c9bf05cf..63ef9bd72 100644 --- a/libyul/backends/evm/EVMCodeTransform.cpp +++ b/libyul/backends/evm/EVMCodeTransform.cpp @@ -118,7 +118,7 @@ void CodeTransform::freeUnusedVariables(bool _popUnusedSlotsAtStackTop) while (m_unusedStackSlots.count(m_assembly.stackHeight() - 1)) { yulAssert(m_unusedStackSlots.erase(m_assembly.stackHeight() - 1), ""); - m_assembly.appendInstruction(evmasm::Instruction::POP); + m_assembly.appendInstruction(evmasm::InternalInstruction::POP); } } @@ -168,7 +168,7 @@ void CodeTransform::operator()(VariableDeclaration const& _varDecl) if (atTopOfStack) { m_context->variableStackHeights.erase(&var); - m_assembly.appendInstruction(evmasm::Instruction::POP); + m_assembly.appendInstruction(evmasm::InternalInstruction::POP); } else m_variablesScheduledForDeletion.insert(&var); @@ -186,7 +186,7 @@ void CodeTransform::operator()(VariableDeclaration const& _varDecl) m_context->variableStackHeights[&var] = slot; if (size_t heightDiff = variableHeightDiff(var, varName, true)) m_assembly.appendInstruction(evmasm::swapInstruction(static_cast(heightDiff - 1))); - m_assembly.appendInstruction(evmasm::Instruction::POP); + m_assembly.appendInstruction(evmasm::InternalInstruction::POP); break; } if (!foundUnusedSlot) @@ -197,10 +197,10 @@ void CodeTransform::operator()(VariableDeclaration const& _varDecl) void CodeTransform::stackError(StackTooDeepError _error, int _targetStackHeight) { - m_assembly.appendInstruction(evmasm::Instruction::INVALID); + m_assembly.appendInstruction(evmasm::InternalInstruction::INVALID); // Correct the stack. while (m_assembly.stackHeight() > _targetStackHeight) - m_assembly.appendInstruction(evmasm::Instruction::POP); + m_assembly.appendInstruction(evmasm::InternalInstruction::POP); while (m_assembly.stackHeight() < _targetStackHeight) m_assembly.appendConstant(u256(0)); // Store error. @@ -303,7 +303,7 @@ void CodeTransform::operator()(If const& _if) { visitExpression(*_if.condition); m_assembly.setSourceLocation(originLocationOf(_if)); - m_assembly.appendInstruction(evmasm::Instruction::ISZERO); + m_assembly.appendInstruction(evmasm::InternalInstruction::ISZERO); AbstractAssembly::LabelID end = m_assembly.newLabelId(); m_assembly.appendJumpToIf(end); (*this)(_if.body); @@ -327,7 +327,7 @@ void CodeTransform::operator()(Switch const& _switch) caseBodies[&c] = bodyLabel; yulAssert(m_assembly.stackHeight() == expressionHeight + 1, ""); m_assembly.appendInstruction(evmasm::dupInstruction(2)); - m_assembly.appendInstruction(evmasm::Instruction::EQ); + m_assembly.appendInstruction(evmasm::InternalInstruction::EQ); m_assembly.appendJumpToIf(bodyLabel); } else @@ -353,7 +353,7 @@ void CodeTransform::operator()(Switch const& _switch) m_assembly.setSourceLocation(originLocationOf(_switch)); m_assembly.appendLabel(end); - m_assembly.appendInstruction(evmasm::Instruction::POP); + m_assembly.appendInstruction(evmasm::InternalInstruction::POP); } void CodeTransform::operator()(FunctionDefinition const& _function) @@ -471,7 +471,7 @@ void CodeTransform::operator()(FunctionDefinition const& _function) while (!stackLayout.empty() && stackLayout.back() != static_cast(stackLayout.size() - 1)) if (stackLayout.back() < 0) { - m_assembly.appendInstruction(evmasm::Instruction::POP); + m_assembly.appendInstruction(evmasm::InternalInstruction::POP); stackLayout.pop_back(); } else @@ -508,7 +508,7 @@ void CodeTransform::operator()(ForLoop const& _forLoop) visitExpression(*_forLoop.condition); m_assembly.setSourceLocation(originLocationOf(_forLoop)); - m_assembly.appendInstruction(evmasm::Instruction::ISZERO); + m_assembly.appendInstruction(evmasm::InternalInstruction::ISZERO); m_assembly.appendJumpToIf(loopEnd); int const stackHeightBody = m_assembly.stackHeight(); @@ -533,7 +533,7 @@ int CodeTransform::appendPopUntil(int _targetDepth) { int const stackDiffAfter = m_assembly.stackHeight() - _targetDepth; for (int i = 0; i < stackDiffAfter; ++i) - m_assembly.appendInstruction(evmasm::Instruction::POP); + m_assembly.appendInstruction(evmasm::InternalInstruction::POP); return stackDiffAfter; } @@ -733,7 +733,7 @@ void CodeTransform::finalizeBlock(Block const& _block, optional blockStartS yulAssert(!m_context->variableReferences.count(&var), ""); } else - m_assembly.appendInstruction(evmasm::Instruction::POP); + m_assembly.appendInstruction(evmasm::InternalInstruction::POP); } if (blockStartStackHeight) @@ -758,7 +758,7 @@ void CodeTransform::generateAssignment(Identifier const& _variableName) Scope::Variable const& _var = std::get(*var); if (size_t heightDiff = variableHeightDiff(_var, _variableName.name, true)) m_assembly.appendInstruction(evmasm::swapInstruction(static_cast(heightDiff - 1))); - m_assembly.appendInstruction(evmasm::Instruction::POP); + m_assembly.appendInstruction(evmasm::InternalInstruction::POP); decreaseReference(_variableName.name, _var); } else diff --git a/libyul/backends/evm/EVMDialect.cpp b/libyul/backends/evm/EVMDialect.cpp index f4fc1b44f..dd8a41eeb 100644 --- a/libyul/backends/evm/EVMDialect.cpp +++ b/libyul/backends/evm/EVMDialect.cpp @@ -48,7 +48,7 @@ namespace pair createEVMFunction( string const& _name, - evmasm::Instruction _instruction + evmasm::InternalInstruction _instruction ) { evmasm::InstructionInfo info = evmasm::instructionInfo(_instruction); @@ -71,7 +71,7 @@ pair createEVMFunction( f.controlFlowSideEffects.canRevert = false; } } - f.isMSize = _instruction == evmasm::Instruction::MSIZE; + f.isMSize = _instruction == evmasm::InternalInstruction::MSIZE; f.literalArguments.clear(); f.instruction = _instruction; f.generateCode = [_instruction]( @@ -114,9 +114,9 @@ set createReservedIdentifiers(langutil::EVMVersion _evmVersion) { // TODO remove this in 0.9.0. We allow creating functions or identifiers in Yul with the name // basefee for VMs before london. - auto baseFeeException = [&](evmasm::Instruction _instr) -> bool + auto baseFeeException = [&](evmasm::InternalInstruction _instr) -> bool { - return _instr == evmasm::Instruction::BASEFEE && _evmVersion < langutil::EVMVersion::london(); + return _instr == evmasm::InternalInstruction::BASEFEE && _evmVersion < langutil::EVMVersion::london(); }; // TODO remove this in 0.9.0. We allow creating functions or identifiers in Yul with the name // prevrandao for VMs before paris. @@ -162,12 +162,12 @@ map createBuiltins(langutil::EVMVersion _evmVe instruction = evmasm::InternalInstruction::DIFFICULTY; if ( - !evmasm::isDupInstruction(opcode) && - !evmasm::isSwapInstruction(opcode) && - !evmasm::isPushInstruction(opcode) && - opcode != evmasm::Instruction::JUMP && - opcode != evmasm::Instruction::JUMPI && - opcode != evmasm::Instruction::JUMPDEST && + !evmasm::isDupInstruction(instruction) && + !evmasm::isSwapInstruction(instruction) && + !evmasm::isPushInstruction(instruction) && + instruction != evmasm::InternalInstruction::JUMP && + instruction != evmasm::InternalInstruction::JUMPI && + instruction != evmasm::InternalInstruction::JUMPDEST && _evmVersion.hasInstruction(instruction) ) builtins.emplace(createEVMFunction(name, instruction)); @@ -256,7 +256,7 @@ map createBuiltins(langutil::EVMVersion _evmVe AbstractAssembly& _assembly, BuiltinContext& ) { - _assembly.appendInstruction(evmasm::Instruction::CODECOPY); + _assembly.appendInstruction(evmasm::InternalInstruction::CODECOPY); } )); builtins.emplace(createFunction( @@ -352,7 +352,7 @@ EVMDialect const& EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion _ return *dialects[_version]; } -SideEffects EVMDialect::sideEffectsOfInstruction(evmasm::Instruction _instruction) +SideEffects EVMDialect::sideEffectsOfInstruction(evmasm::InternalInstruction _instruction) { auto translate = [](evmasm::SemanticInformation::Effect _e) -> SideEffects::Effect { @@ -465,11 +465,11 @@ EVMDialectTyped::EVMDialectTyped(langutil::EVMVersion _evmVersion, bool _objectA // TODO this should use a Panic. // A value larger than 1 causes an invalid instruction. _assembly.appendConstant(2); - _assembly.appendInstruction(evmasm::Instruction::DUP2); - _assembly.appendInstruction(evmasm::Instruction::LT); + _assembly.appendInstruction(evmasm::InternalInstruction::DUP2); + _assembly.appendInstruction(evmasm::InternalInstruction::LT); AbstractAssembly::LabelID inRange = _assembly.newLabelId(); _assembly.appendJumpToIf(inRange); - _assembly.appendInstruction(evmasm::Instruction::INVALID); + _assembly.appendInstruction(evmasm::InternalInstruction::INVALID); _assembly.appendLabel(inRange); })); m_functions["u256_to_bool"_yulstring].parameters = {"u256"_yulstring}; diff --git a/libyul/backends/evm/EVMDialect.h b/libyul/backends/evm/EVMDialect.h index 28649f3e5..ca9279e11 100644 --- a/libyul/backends/evm/EVMDialect.h +++ b/libyul/backends/evm/EVMDialect.h @@ -50,7 +50,7 @@ struct BuiltinContext struct BuiltinFunctionForEVM: public BuiltinFunction { - std::optional instruction; + std::optional instruction; /// Function to generate code for the given function call and append it to the abstract /// assembly. Expects all non-literal arguments of the call to be on stack in reverse order /// (i.e. right-most argument pushed first). @@ -91,7 +91,7 @@ struct EVMDialect: public Dialect bool providesObjectAccess() const { return m_objectAccess; } - static SideEffects sideEffectsOfInstruction(evmasm::Instruction _instruction); + static SideEffects sideEffectsOfInstruction(evmasm::InternalInstruction _instruction); protected: BuiltinFunctionForEVM const* verbatimFunction(size_t _arguments, size_t _returnVariables) const; diff --git a/libyul/backends/evm/EVMMetrics.cpp b/libyul/backends/evm/EVMMetrics.cpp index bd39f966f..80ebafcbd 100644 --- a/libyul/backends/evm/EVMMetrics.cpp +++ b/libyul/backends/evm/EVMMetrics.cpp @@ -41,7 +41,7 @@ bigint GasMeter::costs(Expression const& _expression) const return combineCosts(GasMeterVisitor::costs(_expression, m_dialect, m_isCreation)); } -bigint GasMeter::instructionCosts(evmasm::Instruction _instruction) const +bigint GasMeter::instructionCosts(evmasm::InternalInstruction _instruction) const { return combineCosts(GasMeterVisitor::instructionCosts(_instruction, m_dialect, m_isCreation)); } @@ -64,7 +64,7 @@ pair GasMeterVisitor::costs( } pair GasMeterVisitor::instructionCosts( - evmasm::Instruction _instruction, + evmasm::InternalInstruction _instruction, EVMDialect const& _dialect, bool _isCreation ) @@ -88,7 +88,7 @@ void GasMeterVisitor::operator()(FunctionCall const& _funCall) void GasMeterVisitor::operator()(Literal const& _lit) { - m_runGas += evmasm::GasMeter::runGas(evmasm::Instruction::PUSH1); + m_runGas += evmasm::GasMeter::runGas(evmasm::InternalInstruction::PUSH1); m_dataGas += singleByteDataGas() + evmasm::GasMeter::dataGas( @@ -100,7 +100,7 @@ void GasMeterVisitor::operator()(Literal const& _lit) void GasMeterVisitor::operator()(Identifier const&) { - m_runGas += evmasm::GasMeter::runGas(evmasm::Instruction::DUP1); + m_runGas += evmasm::GasMeter::runGas(evmasm::InternalInstruction::DUP1); m_dataGas += singleByteDataGas(); } @@ -112,11 +112,11 @@ bigint GasMeterVisitor::singleByteDataGas() const return evmasm::GasCosts::createDataGas; } -void GasMeterVisitor::instructionCostsInternal(evmasm::Instruction _instruction) +void GasMeterVisitor::instructionCostsInternal(evmasm::InternalInstruction _instruction) { - if (_instruction == evmasm::Instruction::EXP) + if (_instruction == evmasm::InternalInstruction::EXP) m_runGas += evmasm::GasCosts::expGas + evmasm::GasCosts::expByteGas(m_dialect.evmVersion()); - else if (_instruction == evmasm::Instruction::KECCAK256) + else if (_instruction == evmasm::InternalInstruction::KECCAK256) // Assumes that Keccak-256 is computed on a single word (rounded up). m_runGas += evmasm::GasCosts::keccak256Gas + evmasm::GasCosts::keccak256WordGas; else diff --git a/libyul/backends/evm/EVMMetrics.h b/libyul/backends/evm/EVMMetrics.h index b67cb77cd..3b30e33ee 100644 --- a/libyul/backends/evm/EVMMetrics.h +++ b/libyul/backends/evm/EVMMetrics.h @@ -53,7 +53,7 @@ public: bigint costs(Expression const& _expression) const; /// @returns the combined costs of deploying and running the instruction, not including /// the costs for its arguments. - bigint instructionCosts(evmasm::Instruction _instruction) const; + bigint instructionCosts(evmasm::InternalInstruction _instruction) const; private: bigint combineCosts(std::pair _costs) const; @@ -73,7 +73,7 @@ public: ); static std::pair instructionCosts( - evmasm::Instruction _instruction, + evmasm::InternalInstruction _instruction, EVMDialect const& _dialect, bool _isCreation = false ); @@ -93,7 +93,7 @@ private: /// Computes the cost of storing and executing the single instruction (excluding its arguments). /// For EXP, it assumes that the exponent is at most 255. /// Does not work particularly exact for anything apart from arithmetic. - void instructionCostsInternal(evmasm::Instruction _instruction); + void instructionCostsInternal(evmasm::InternalInstruction _instruction); EVMDialect const& m_dialect; bool m_isCreation = false; diff --git a/libyul/backends/evm/EthAssemblyAdapter.cpp b/libyul/backends/evm/EthAssemblyAdapter.cpp index 685f56cbc..50b876b76 100644 --- a/libyul/backends/evm/EthAssemblyAdapter.cpp +++ b/libyul/backends/evm/EthAssemblyAdapter.cpp @@ -59,7 +59,7 @@ void EthAssemblyAdapter::setStackHeight(int height) m_assembly.setDeposit(height); } -void EthAssemblyAdapter::appendInstruction(evmasm::Instruction _instruction) +void EthAssemblyAdapter::appendInstruction(evmasm::InternalInstruction _instruction) { m_assembly.append(_instruction); } @@ -101,7 +101,7 @@ void EthAssemblyAdapter::appendVerbatim(bytes _data, size_t _arguments, size_t _ void EthAssemblyAdapter::appendJump(int _stackDiffAfter, JumpType _jumpType) { - appendJumpInstruction(evmasm::Instruction::JUMP, _jumpType); + appendJumpInstruction(evmasm::InternalInstruction::JUMP, _jumpType); m_assembly.adjustDeposit(_stackDiffAfter); } @@ -114,7 +114,7 @@ void EthAssemblyAdapter::appendJumpTo(LabelID _labelId, int _stackDiffAfter, Jum void EthAssemblyAdapter::appendJumpToIf(LabelID _labelId, JumpType _jumpType) { appendLabelReference(_labelId); - appendJumpInstruction(evmasm::Instruction::JUMPI, _jumpType); + appendJumpInstruction(evmasm::InternalInstruction::JUMPI, _jumpType); } void EthAssemblyAdapter::appendAssemblySize() @@ -188,9 +188,9 @@ EthAssemblyAdapter::LabelID EthAssemblyAdapter::assemblyTagToIdentifier(evmasm:: return LabelID(id); } -void EthAssemblyAdapter::appendJumpInstruction(evmasm::Instruction _instruction, JumpType _jumpType) +void EthAssemblyAdapter::appendJumpInstruction(evmasm::InternalInstruction _instruction, JumpType _jumpType) { - yulAssert(_instruction == evmasm::Instruction::JUMP || _instruction == evmasm::Instruction::JUMPI, ""); + yulAssert(_instruction == evmasm::InternalInstruction::JUMP || _instruction == evmasm::InternalInstruction::JUMPI, ""); evmasm::AssemblyItem jump(_instruction); switch (_jumpType) { diff --git a/libyul/backends/evm/EthAssemblyAdapter.h b/libyul/backends/evm/EthAssemblyAdapter.h index 87047ccbf..77d7e4de0 100644 --- a/libyul/backends/evm/EthAssemblyAdapter.h +++ b/libyul/backends/evm/EthAssemblyAdapter.h @@ -43,7 +43,7 @@ public: void setSourceLocation(langutil::SourceLocation const& _location) override; int stackHeight() const override; void setStackHeight(int height) override; - void appendInstruction(evmasm::Instruction _instruction) override; + void appendInstruction(evmasm::InternalInstruction _instruction) override; void appendConstant(u256 const& _constant) override; void appendLabel(LabelID _labelId) override; void appendLabelReference(LabelID _labelId) override; @@ -69,7 +69,7 @@ public: private: static LabelID assemblyTagToIdentifier(evmasm::AssemblyItem const& _tag); - void appendJumpInstruction(evmasm::Instruction _instruction, JumpType _jumpType); + void appendJumpInstruction(evmasm::InternalInstruction _instruction, JumpType _jumpType); evmasm::Assembly& m_assembly; std::map m_dataHashBySubId; diff --git a/libyul/backends/evm/NoOutputAssembly.cpp b/libyul/backends/evm/NoOutputAssembly.cpp index e26204201..a32ee5f8c 100644 --- a/libyul/backends/evm/NoOutputAssembly.cpp +++ b/libyul/backends/evm/NoOutputAssembly.cpp @@ -35,7 +35,7 @@ using namespace solidity::util; using namespace solidity::langutil; -void NoOutputAssembly::appendInstruction(evmasm::Instruction _instr) +void NoOutputAssembly::appendInstruction(evmasm::InternalInstruction _instr) { m_stackHeight += instructionInfo(_instr).ret - instructionInfo(_instr).args; } @@ -47,7 +47,7 @@ void NoOutputAssembly::appendConstant(u256 const&) void NoOutputAssembly::appendLabel(LabelID) { - appendInstruction(evmasm::Instruction::JUMPDEST); + appendInstruction(evmasm::InternalInstruction::JUMPDEST); } void NoOutputAssembly::appendLabelReference(LabelID) @@ -77,7 +77,7 @@ void NoOutputAssembly::appendVerbatim(bytes, size_t _arguments, size_t _returnVa void NoOutputAssembly::appendJump(int _stackDiffAfter, JumpType) { - appendInstruction(evmasm::Instruction::JUMP); + appendInstruction(evmasm::InternalInstruction::JUMP); m_stackHeight += _stackDiffAfter; } @@ -90,12 +90,12 @@ void NoOutputAssembly::appendJumpTo(LabelID _labelId, int _stackDiffAfter, JumpT void NoOutputAssembly::appendJumpToIf(LabelID _labelId, JumpType) { appendLabelReference(_labelId); - appendInstruction(evmasm::Instruction::JUMPI); + appendInstruction(evmasm::InternalInstruction::JUMPI); } void NoOutputAssembly::appendAssemblySize() { - appendInstruction(evmasm::Instruction::PUSH1); + appendInstruction(evmasm::InternalInstruction::PUSH1); } pair, AbstractAssembly::SubID> NoOutputAssembly::createSubAssembly(bool, std::string) @@ -106,12 +106,12 @@ pair, AbstractAssembly::SubID> NoOutputAssembly::cr void NoOutputAssembly::appendDataOffset(std::vector const&) { - appendInstruction(evmasm::Instruction::PUSH1); + appendInstruction(evmasm::InternalInstruction::PUSH1); } void NoOutputAssembly::appendDataSize(std::vector const&) { - appendInstruction(evmasm::Instruction::PUSH1); + appendInstruction(evmasm::InternalInstruction::PUSH1); } AbstractAssembly::SubID NoOutputAssembly::appendData(bytes const&) @@ -140,7 +140,7 @@ NoOutputEVMDialect::NoOutputEVMDialect(EVMDialect const& _copyFrom): { for (size_t i: ranges::views::iota(0u, _call.arguments.size())) if (!fun.second.literalArgument(i)) - _assembly.appendInstruction(evmasm::Instruction::POP); + _assembly.appendInstruction(evmasm::InternalInstruction::POP); for (size_t i = 0; i < returns; i++) _assembly.appendConstant(u256(0)); diff --git a/libyul/backends/evm/NoOutputAssembly.h b/libyul/backends/evm/NoOutputAssembly.h index 1103392ef..fb07cd372 100644 --- a/libyul/backends/evm/NoOutputAssembly.h +++ b/libyul/backends/evm/NoOutputAssembly.h @@ -51,7 +51,7 @@ public: void setSourceLocation(langutil::SourceLocation const&) override {} int stackHeight() const override { return m_stackHeight; } void setStackHeight(int height) override { m_stackHeight = height; } - void appendInstruction(evmasm::Instruction _instruction) override; + void appendInstruction(evmasm::InternalInstruction _instruction) override; void appendConstant(u256 const& _constant) override; void appendLabel(LabelID _labelId) override; void appendLabelReference(LabelID _labelId) override; diff --git a/libyul/backends/evm/OptimizedEVMCodeTransform.cpp b/libyul/backends/evm/OptimizedEVMCodeTransform.cpp index db73ba2a7..92e153b1b 100644 --- a/libyul/backends/evm/OptimizedEVMCodeTransform.cpp +++ b/libyul/backends/evm/OptimizedEVMCodeTransform.cpp @@ -345,14 +345,14 @@ void OptimizedEVMCodeTransform::createStackLayout(std::shared_ptr(m_stack.size()), ""); @@ -407,7 +407,7 @@ void OptimizedEVMCodeTransform::operator()(CFG::BasicBlock const& _block) std::visit(util::GenericVisitor{ [&](CFG::BasicBlock::MainExit const&) { - m_assembly.appendInstruction(evmasm::Instruction::STOP); + m_assembly.appendInstruction(evmasm::InternalInstruction::STOP); }, [&](CFG::BasicBlock::Jump const& _jump) { diff --git a/libyul/backends/evm/StackLayoutGenerator.cpp b/libyul/backends/evm/StackLayoutGenerator.cpp index 8b39b364f..f6b6a8e2d 100644 --- a/libyul/backends/evm/StackLayoutGenerator.cpp +++ b/libyul/backends/evm/StackLayoutGenerator.cpp @@ -763,7 +763,7 @@ void StackLayoutGenerator::fillInJunk(CFG::BasicBlock const& _block) opGas += 1000; } }; - auto pop = [&]() { opGas += evmasm::GasMeter::runGas(evmasm::Instruction::POP); }; + auto pop = [&]() { opGas += evmasm::GasMeter::runGas(evmasm::InternalInstruction::POP); }; createStackLayout(_source, _target, swap, dupOrPush, pop); return opGas; }; diff --git a/libyul/optimiser/ExpressionSimplifier.cpp b/libyul/optimiser/ExpressionSimplifier.cpp index caf74cfb7..7311bad5f 100644 --- a/libyul/optimiser/ExpressionSimplifier.cpp +++ b/libyul/optimiser/ExpressionSimplifier.cpp @@ -50,7 +50,7 @@ void ExpressionSimplifier::visit(Expression& _expression) _expression = match->action().toExpression(debugDataOf(_expression)); if (auto* functionCall = get_if(&_expression)) - if (optional instruction = toEVMInstruction(m_dialect, functionCall->functionName.name)) + if (optional instruction = toEVMInstruction(m_dialect, functionCall->functionName.name)) for (auto op: evmasm::SemanticInformation::readWriteOperations(*instruction)) if (op.startParameter && op.lengthParameter) { diff --git a/libyul/optimiser/Metrics.cpp b/libyul/optimiser/Metrics.cpp index 298dfe9c1..b82ab25ab 100644 --- a/libyul/optimiser/Metrics.cpp +++ b/libyul/optimiser/Metrics.cpp @@ -178,7 +178,7 @@ void CodeCost::visit(Expression const& _expression) ASTWalker::visit(_expression); } -void CodeCost::addInstructionCost(evmasm::Instruction _instruction) +void CodeCost::addInstructionCost(evmasm::InternalInstruction _instruction) { evmasm::Tier gasPriceTier = evmasm::instructionInfo(_instruction).gasPriceTier; if (gasPriceTier < evmasm::Tier::VeryLow) diff --git a/libyul/optimiser/Metrics.h b/libyul/optimiser/Metrics.h index f86e3b28d..e0345a002 100644 --- a/libyul/optimiser/Metrics.h +++ b/libyul/optimiser/Metrics.h @@ -124,7 +124,7 @@ private: void visit(Expression const& _expression) override; private: - void addInstructionCost(evmasm::Instruction _instruction); + void addInstructionCost(evmasm::InternalInstruction _instruction); Dialect const& m_dialect; size_t m_cost = 0; diff --git a/libyul/optimiser/OptimizerUtilities.cpp b/libyul/optimiser/OptimizerUtilities.cpp index ba06b2180..d2142540d 100644 --- a/libyul/optimiser/OptimizerUtilities.cpp +++ b/libyul/optimiser/OptimizerUtilities.cpp @@ -50,7 +50,7 @@ bool yul::isRestrictedIdentifier(Dialect const& _dialect, YulString const& _iden return _identifier.empty() || TokenTraits::isYulKeyword(_identifier.str()) || _dialect.reservedIdentifier(_identifier); } -optional yul::toEVMInstruction(Dialect const& _dialect, YulString const& _name) +optional yul::toEVMInstruction(Dialect const& _dialect, YulString const& _name) { if (auto const* dialect = dynamic_cast(&_dialect)) if (BuiltinFunctionForEVM const* builtin = dialect->builtin(_name)) diff --git a/libyul/optimiser/OptimizerUtilities.h b/libyul/optimiser/OptimizerUtilities.h index b491e57e1..88820c4ff 100644 --- a/libyul/optimiser/OptimizerUtilities.h +++ b/libyul/optimiser/OptimizerUtilities.h @@ -31,7 +31,7 @@ namespace solidity::evmasm { -enum class Instruction: uint8_t; +enum class InternalInstruction: uint8_t; } namespace solidity::yul @@ -47,7 +47,7 @@ void removeEmptyBlocks(Block& _block); bool isRestrictedIdentifier(Dialect const& _dialect, YulString const& _identifier); /// Helper function that returns the instruction, if the `_name` is a BuiltinFunction -std::optional toEVMInstruction(Dialect const& _dialect, YulString const& _name); +std::optional toEVMInstruction(Dialect const& _dialect, YulString const& _name); class StatementRemover: public ASTModifier { diff --git a/libyul/optimiser/ReasoningBasedSimplifier.cpp b/libyul/optimiser/ReasoningBasedSimplifier.cpp index af39978ed..84c1c0e2d 100644 --- a/libyul/optimiser/ReasoningBasedSimplifier.cpp +++ b/libyul/optimiser/ReasoningBasedSimplifier.cpp @@ -109,7 +109,7 @@ ReasoningBasedSimplifier::ReasoningBasedSimplifier( smtutil::Expression ReasoningBasedSimplifier::encodeEVMBuiltin( - evmasm::Instruction _instruction, + evmasm::InternalInstruction _instruction, vector const& _arguments ) { @@ -119,19 +119,19 @@ smtutil::Expression ReasoningBasedSimplifier::encodeEVMBuiltin( ); switch (_instruction) { - case evmasm::Instruction::ADD: + case evmasm::InternalInstruction::ADD: return wrap(arguments.at(0) + arguments.at(1)); - case evmasm::Instruction::MUL: + case evmasm::InternalInstruction::MUL: return wrap(arguments.at(0) * arguments.at(1)); - case evmasm::Instruction::SUB: + case evmasm::InternalInstruction::SUB: return wrap(arguments.at(0) - arguments.at(1)); - case evmasm::Instruction::DIV: + case evmasm::InternalInstruction::DIV: return smtutil::Expression::ite( arguments.at(1) == constantValue(0), constantValue(0), arguments.at(0) / arguments.at(1) ); - case evmasm::Instruction::SDIV: + case evmasm::InternalInstruction::SDIV: return smtutil::Expression::ite( arguments.at(1) == constantValue(0), constantValue(0), @@ -143,13 +143,13 @@ smtutil::Expression ReasoningBasedSimplifier::encodeEVMBuiltin( twosComplementToSigned(arguments.at(1)) )) ); - case evmasm::Instruction::MOD: + case evmasm::InternalInstruction::MOD: return smtutil::Expression::ite( arguments.at(1) == constantValue(0), constantValue(0), arguments.at(0) % arguments.at(1) ); - case evmasm::Instruction::SMOD: + case evmasm::InternalInstruction::SMOD: return smtutil::Expression::ite( arguments.at(1) == constantValue(0), constantValue(0), @@ -158,61 +158,61 @@ smtutil::Expression ReasoningBasedSimplifier::encodeEVMBuiltin( twosComplementToSigned(arguments.at(1)) )) ); - case evmasm::Instruction::LT: + case evmasm::InternalInstruction::LT: return booleanValue(arguments.at(0) < arguments.at(1)); - case evmasm::Instruction::SLT: + case evmasm::InternalInstruction::SLT: return booleanValue(twosComplementToSigned(arguments.at(0)) < twosComplementToSigned(arguments.at(1))); - case evmasm::Instruction::GT: + case evmasm::InternalInstruction::GT: return booleanValue(arguments.at(0) > arguments.at(1)); - case evmasm::Instruction::SGT: + case evmasm::InternalInstruction::SGT: return booleanValue(twosComplementToSigned(arguments.at(0)) > twosComplementToSigned(arguments.at(1))); - case evmasm::Instruction::EQ: + case evmasm::InternalInstruction::EQ: return booleanValue(arguments.at(0) == arguments.at(1)); - case evmasm::Instruction::ISZERO: + case evmasm::InternalInstruction::ISZERO: return booleanValue(arguments.at(0) == constantValue(0)); - case evmasm::Instruction::AND: + case evmasm::InternalInstruction::AND: return smtutil::Expression::ite( (arguments.at(0) == 0 || arguments.at(0) == 1) && (arguments.at(1) == 0 || arguments.at(1) == 1), booleanValue(arguments.at(0) == 1 && arguments.at(1) == 1), bv2int(int2bv(arguments.at(0)) & int2bv(arguments.at(1))) ); - case evmasm::Instruction::OR: + case evmasm::InternalInstruction::OR: return smtutil::Expression::ite( (arguments.at(0) == 0 || arguments.at(0) == 1) && (arguments.at(1) == 0 || arguments.at(1) == 1), booleanValue(arguments.at(0) == 1 || arguments.at(1) == 1), bv2int(int2bv(arguments.at(0)) | int2bv(arguments.at(1))) ); - case evmasm::Instruction::XOR: + case evmasm::InternalInstruction::XOR: return bv2int(int2bv(arguments.at(0)) ^ int2bv(arguments.at(1))); - case evmasm::Instruction::NOT: + case evmasm::InternalInstruction::NOT: return smtutil::Expression(u256(-1)) - arguments.at(0); - case evmasm::Instruction::SHL: + case evmasm::InternalInstruction::SHL: return smtutil::Expression::ite( arguments.at(0) > 255, constantValue(0), bv2int(int2bv(arguments.at(1)) << int2bv(arguments.at(0))) ); - case evmasm::Instruction::SHR: + case evmasm::InternalInstruction::SHR: return smtutil::Expression::ite( arguments.at(0) > 255, constantValue(0), bv2int(int2bv(arguments.at(1)) >> int2bv(arguments.at(0))) ); - case evmasm::Instruction::SAR: + case evmasm::InternalInstruction::SAR: return smtutil::Expression::ite( arguments.at(0) > 255, constantValue(0), bv2int(smtutil::Expression::ashr(int2bv(arguments.at(1)), int2bv(arguments.at(0)))) ); - case evmasm::Instruction::ADDMOD: + case evmasm::InternalInstruction::ADDMOD: return smtutil::Expression::ite( arguments.at(2) == constantValue(0), constantValue(0), (arguments.at(0) + arguments.at(1)) % arguments.at(2) ); - case evmasm::Instruction::MULMOD: + case evmasm::InternalInstruction::MULMOD: return smtutil::Expression::ite( arguments.at(2) == constantValue(0), constantValue(0), diff --git a/libyul/optimiser/ReasoningBasedSimplifier.h b/libyul/optimiser/ReasoningBasedSimplifier.h index c458a36d0..1b659a7ef 100644 --- a/libyul/optimiser/ReasoningBasedSimplifier.h +++ b/libyul/optimiser/ReasoningBasedSimplifier.h @@ -65,7 +65,7 @@ private: ); smtutil::Expression encodeEVMBuiltin( - evmasm::Instruction _instruction, + evmasm::InternalInstruction _instruction, std::vector const& _arguments ) override; diff --git a/libyul/optimiser/SMTSolver.h b/libyul/optimiser/SMTSolver.h index d92a84c1d..a51d96d21 100644 --- a/libyul/optimiser/SMTSolver.h +++ b/libyul/optimiser/SMTSolver.h @@ -58,7 +58,7 @@ protected: /// The encoding for a builtin. The type of encoding determines what we are /// solving for. virtual smtutil::Expression encodeEVMBuiltin( - evmasm::Instruction _instruction, + evmasm::InternalInstruction _instruction, std::vector const& _arguments ) = 0; diff --git a/libyul/optimiser/SimplificationRules.cpp b/libyul/optimiser/SimplificationRules.cpp index 9d0144750..054ff226b 100644 --- a/libyul/optimiser/SimplificationRules.cpp +++ b/libyul/optimiser/SimplificationRules.cpp @@ -72,10 +72,10 @@ SimplificationRules::Rule const* SimplificationRules::findFirstMatch( bool SimplificationRules::isInitialized() const { - return !m_rules[uint8_t(evmasm::Instruction::ADD)].empty(); + return !m_rules[uint8_t(evmasm::InternalInstruction::ADD)].empty(); } -std::optional const*>> +std::optional const*>> SimplificationRules::instructionAndArguments(Dialect const& _dialect, Expression const& _expr) { if (holds_alternative(_expr)) @@ -122,7 +122,7 @@ SimplificationRules::SimplificationRules(std::optional _ev assertThrow(isInitialized(), OptimizerException, "Rule list not properly initialized."); } -yul::Pattern::Pattern(evmasm::Instruction _instruction, initializer_list _arguments): +yul::Pattern::Pattern(evmasm::InternalInstruction _instruction, initializer_list _arguments): m_kind(PatternKind::Operation), m_instruction(_instruction), m_arguments(_arguments) @@ -229,7 +229,7 @@ bool Pattern::matches( return true; } -evmasm::Instruction Pattern::instruction() const +evmasm::InternalInstruction Pattern::instruction() const { assertThrow(m_kind == PatternKind::Operation, OptimizerException, ""); return m_instruction; diff --git a/libyul/optimiser/SimplificationRules.h b/libyul/optimiser/SimplificationRules.h index 7444c47fb..ef6150737 100644 --- a/libyul/optimiser/SimplificationRules.h +++ b/libyul/optimiser/SimplificationRules.h @@ -69,7 +69,7 @@ public: /// by the constructor, but we had some issues with static initialization. bool isInitialized() const; - static std::optional const*>> + static std::optional const*>> instructionAndArguments(Dialect const& _dialect, Expression const& _expr); private: @@ -110,7 +110,7 @@ public: // Matches a specific constant value. Pattern(u256 const& _value): m_kind(PatternKind::Constant), m_data(std::make_shared(_value)) {} // Matches a given instruction with given arguments - Pattern(evmasm::Instruction _instruction, std::initializer_list _arguments = {}); + Pattern(evmasm::InternalInstruction _instruction, std::initializer_list _arguments = {}); /// Sets this pattern to be part of the match group with the identifier @a _group. /// Inside one rule, all patterns in the same match group have to match expressions from the /// same expression equivalence class. @@ -127,7 +127,7 @@ public: /// @returns the data of the matched expression if this pattern is part of a match group. u256 d() const; - evmasm::Instruction instruction() const; + evmasm::InternalInstruction instruction() const; /// Turns this pattern into an actual expression. Should only be called /// for patterns resulting from an action, i.e. with match groups assigned. @@ -137,7 +137,7 @@ private: Expression const& matchGroupValue() const; PatternKind m_kind = PatternKind::Any; - evmasm::Instruction m_instruction; ///< Only valid if m_kind is Operation + evmasm::InternalInstruction m_instruction; ///< Only valid if m_kind is Operation std::shared_ptr m_data; ///< Only valid if m_kind is Constant std::vector m_arguments; unsigned m_matchGroup = 0; diff --git a/libyul/optimiser/UnusedStoreEliminator.cpp b/libyul/optimiser/UnusedStoreEliminator.cpp index 2e96be2e7..77bfbe89c 100644 --- a/libyul/optimiser/UnusedStoreEliminator.cpp +++ b/libyul/optimiser/UnusedStoreEliminator.cpp @@ -129,7 +129,7 @@ void UnusedStoreEliminator::operator()(Leave const&) void UnusedStoreEliminator::visit(Statement const& _statement) { - using evmasm::Instruction; + using evmasm::InternalInstruction; UnusedStoreBase::visit(_statement); @@ -139,7 +139,7 @@ void UnusedStoreEliminator::visit(Statement const& _statement) FunctionCall const* funCall = get_if(&exprStatement->expression); yulAssert(funCall); - optional instruction = toEVMInstruction(m_dialect, funCall->functionName.name); + optional instruction = toEVMInstruction(m_dialect, funCall->functionName.name); if (!instruction) return; @@ -152,14 +152,14 @@ void UnusedStoreEliminator::visit(Statement const& _statement) // both by querying a combination of semantic information and by listing the instructions. // This way the assert below should be triggered on any change. using evmasm::SemanticInformation; - bool isStorageWrite = (*instruction == Instruction::SSTORE); + bool isStorageWrite = (*instruction == InternalInstruction::SSTORE); bool isMemoryWrite = - *instruction == Instruction::EXTCODECOPY || - *instruction == Instruction::CODECOPY || - *instruction == Instruction::CALLDATACOPY || - *instruction == Instruction::RETURNDATACOPY || - *instruction == Instruction::MSTORE || - *instruction == Instruction::MSTORE8; + *instruction == InternalInstruction::EXTCODECOPY || + *instruction == InternalInstruction::CODECOPY || + *instruction == InternalInstruction::CALLDATACOPY || + *instruction == InternalInstruction::RETURNDATACOPY || + *instruction == InternalInstruction::MSTORE || + *instruction == InternalInstruction::MSTORE8; bool isCandidateForRemoval = SemanticInformation::otherState(*instruction) != SemanticInformation::Write && ( SemanticInformation::storage(*instruction) == SemanticInformation::Write || @@ -169,7 +169,7 @@ void UnusedStoreEliminator::visit(Statement const& _statement) if (isCandidateForRemoval) { State initialState = State::Undecided; - if (*instruction == Instruction::RETURNDATACOPY) + if (*instruction == InternalInstruction::RETURNDATACOPY) { initialState = State::Used; auto startOffset = identifierNameIfSSA(funCall->arguments.at(1)); @@ -181,7 +181,7 @@ void UnusedStoreEliminator::visit(Statement const& _statement) if ( knowledge.knownToBeZero(*startOffset) && lengthCall && - toEVMInstruction(m_dialect, lengthCall->functionName.name) == Instruction::RETURNDATASIZE + toEVMInstruction(m_dialect, lengthCall->functionName.name) == InternalInstruction::RETURNDATASIZE ) initialState = State::Undecided; } @@ -203,7 +203,7 @@ vector UnusedStoreEliminator::operationsFromFu FunctionCall const& _functionCall ) const { - using evmasm::Instruction; + using evmasm::InternalInstruction; YulString functionName = _functionCall.functionName.name; SideEffects sideEffects; @@ -212,7 +212,7 @@ vector UnusedStoreEliminator::operationsFromFu else sideEffects = m_functionSideEffects.at(functionName); - optional instruction = toEVMInstruction(m_dialect, functionName); + optional instruction = toEVMInstruction(m_dialect, functionName); if (!instruction) { vector result; diff --git a/test/libevmasm/Assembler.cpp b/test/libevmasm/Assembler.cpp index ef9477bcf..1ff62a8a2 100644 --- a/test/libevmasm/Assembler.cpp +++ b/test/libevmasm/Assembler.cpp @@ -74,12 +74,12 @@ BOOST_AUTO_TEST_CASE(all_assembly_items) // PushImmutable _subAsm.appendImmutable("someImmutable"); _subAsm.append(AssemblyItem(PushTag, 0)); - _subAsm.append(Instruction::INVALID); + _subAsm.append(InternalInstruction::INVALID); shared_ptr _subAsmPtr = make_shared(_subAsm); _verbatimAsm.appendVerbatim({0xff,0xff}, 0, 0); _verbatimAsm.appendVerbatim({0x74, 0x65, 0x73, 0x74}, 0, 1); - _verbatimAsm.append(Instruction::MSTORE); + _verbatimAsm.append(InternalInstruction::MSTORE); shared_ptr _verbatimAsmPtr = make_shared(_verbatimAsm); // Tag @@ -89,7 +89,7 @@ BOOST_AUTO_TEST_CASE(all_assembly_items) _assembly.append(u256(1)); _assembly.append(u256(2)); // Push - auto keccak256 = AssemblyItem(Instruction::KECCAK256); + auto keccak256 = AssemblyItem(InternalInstruction::KECCAK256); _assembly.m_currentModifierDepth = 1; _assembly.append(keccak256); _assembly.m_currentModifierDepth = 0; @@ -117,7 +117,7 @@ BOOST_AUTO_TEST_CASE(all_assembly_items) _assembly.append(u256(2)); _assembly.appendImmutableAssignment("someImmutable"); // Operation - _assembly.append(Instruction::STOP); + _assembly.append(InternalInstruction::STOP); _assembly.appendToAuxiliaryData(bytes{0x42, 0x66}); _assembly.appendToAuxiliaryData(bytes{0xee, 0xaa}); diff --git a/test/libevmasm/Optimiser.cpp b/test/libevmasm/Optimiser.cpp index 6fc3c5a74..29ed60824 100644 --- a/test/libevmasm/Optimiser.cpp +++ b/test/libevmasm/Optimiser.cpp @@ -70,7 +70,7 @@ namespace AssemblyItems input = addDummyLocations(_input); bool usesMsize = ranges::any_of(_input, [](AssemblyItem const& _i) { - return _i == AssemblyItem{Instruction::MSIZE} || _i.type() == VerbatimBytecode; + return _i == AssemblyItem{InternalInstruction::MSIZE} || _i.type() == VerbatimBytecode; }); evmasm::CommonSubexpressionEliminator cse(_state); BOOST_REQUIRE(cse.feedItems(input.begin(), input.end(), usesMsize) == input.end()); @@ -78,7 +78,7 @@ namespace for (AssemblyItem const& item: output) { - BOOST_CHECK(item == Instruction::POP || item.location().isValid()); + BOOST_CHECK(item == InternalInstruction::POP || item.location().isValid()); } return output; } @@ -100,7 +100,7 @@ namespace AssemblyItems optimisedItems; bool usesMSize = ranges::any_of(_input, [](AssemblyItem const& _i) { - return _i == AssemblyItem{Instruction::MSIZE} || _i.type() == VerbatimBytecode; + return _i == AssemblyItem{InternalInstruction::MSIZE} || _i.type() == VerbatimBytecode; }); auto iter = _input.begin(); @@ -160,7 +160,7 @@ BOOST_AUTO_TEST_SUITE(Optimiser) BOOST_AUTO_TEST_CASE(cse_push_immutable_same) { AssemblyItem pushImmutable{PushImmutable, 0x1234}; - checkCSE({pushImmutable, pushImmutable}, {pushImmutable, Instruction::DUP1}); + checkCSE({pushImmutable, pushImmutable}, {pushImmutable, InternalInstruction::DUP1}); } BOOST_AUTO_TEST_CASE(cse_push_immutable_different) @@ -187,7 +187,7 @@ BOOST_AUTO_TEST_CASE(cse_assign_immutable_breaks) AssemblyItems input = addDummyLocations(AssemblyItems{ u256(0x42), {AssignImmutable, 0x1234}, - Instruction::ORIGIN + InternalInstruction::ORIGIN }); evmasm::CommonSubexpressionEliminator cse{evmasm::KnownState()}; @@ -200,9 +200,9 @@ BOOST_AUTO_TEST_CASE(cse_intermediate_swap) evmasm::KnownState state; evmasm::CommonSubexpressionEliminator cse(state); AssemblyItems input{ - Instruction::SWAP1, Instruction::POP, Instruction::ADD, u256(0), Instruction::SWAP1, - Instruction::SLOAD, Instruction::SWAP1, u256(100), Instruction::EXP, Instruction::SWAP1, - Instruction::DIV, u256(0xff), Instruction::AND + InternalInstruction::SWAP1, InternalInstruction::POP, InternalInstruction::ADD, u256(0), InternalInstruction::SWAP1, + InternalInstruction::SLOAD, InternalInstruction::SWAP1, u256(100), InternalInstruction::EXP, InternalInstruction::SWAP1, + InternalInstruction::DIV, u256(0xff), InternalInstruction::AND }; BOOST_REQUIRE(cse.feedItems(input.begin(), input.end(), false) == input.end()); AssemblyItems output = cse.getOptimizedItems(); @@ -211,33 +211,33 @@ BOOST_AUTO_TEST_CASE(cse_intermediate_swap) BOOST_AUTO_TEST_CASE(cse_negative_stack_access) { - AssemblyItems input{Instruction::DUP2, u256(0)}; + AssemblyItems input{InternalInstruction::DUP2, u256(0)}; checkCSE(input, input); } BOOST_AUTO_TEST_CASE(cse_negative_stack_end) { - AssemblyItems input{Instruction::ADD}; + AssemblyItems input{InternalInstruction::ADD}; checkCSE(input, input); } BOOST_AUTO_TEST_CASE(cse_intermediate_negative_stack) { - AssemblyItems input{Instruction::ADD, u256(1), Instruction::DUP1}; + AssemblyItems input{InternalInstruction::ADD, u256(1), InternalInstruction::DUP1}; checkCSE(input, input); } BOOST_AUTO_TEST_CASE(cse_pop) { - checkCSE({Instruction::POP}, {Instruction::POP}); + checkCSE({InternalInstruction::POP}, {InternalInstruction::POP}); } BOOST_AUTO_TEST_CASE(cse_unneeded_items) { AssemblyItems input{ - Instruction::ADD, - Instruction::SWAP1, - Instruction::POP, + InternalInstruction::ADD, + InternalInstruction::SWAP1, + InternalInstruction::POP, u256(7), u256(8), }; @@ -246,75 +246,75 @@ BOOST_AUTO_TEST_CASE(cse_unneeded_items) BOOST_AUTO_TEST_CASE(cse_constant_addition) { - AssemblyItems input{u256(7), u256(8), Instruction::ADD}; + AssemblyItems input{u256(7), u256(8), InternalInstruction::ADD}; checkCSE(input, {u256(7 + 8)}); } BOOST_AUTO_TEST_CASE(cse_invariants) { AssemblyItems input{ - Instruction::DUP1, - Instruction::DUP1, + InternalInstruction::DUP1, + InternalInstruction::DUP1, u256(0), - Instruction::OR, - Instruction::OR + InternalInstruction::OR, + InternalInstruction::OR }; - checkCSE(input, {Instruction::DUP1}); + checkCSE(input, {InternalInstruction::DUP1}); } BOOST_AUTO_TEST_CASE(cse_subself) { - checkCSE({Instruction::DUP1, Instruction::SUB}, {Instruction::POP, u256(0)}); + checkCSE({InternalInstruction::DUP1, InternalInstruction::SUB}, {InternalInstruction::POP, u256(0)}); } BOOST_AUTO_TEST_CASE(cse_subother) { - checkCSE({Instruction::SUB}, {Instruction::SUB}); + checkCSE({InternalInstruction::SUB}, {InternalInstruction::SUB}); } BOOST_AUTO_TEST_CASE(cse_double_negation) { - checkCSE({Instruction::DUP5, Instruction::NOT, Instruction::NOT}, {Instruction::DUP5}); + checkCSE({InternalInstruction::DUP5, InternalInstruction::NOT, InternalInstruction::NOT}, {InternalInstruction::DUP5}); } BOOST_AUTO_TEST_CASE(cse_double_iszero) { - checkCSE({Instruction::GT, Instruction::ISZERO, Instruction::ISZERO}, {Instruction::GT}); - checkCSE({Instruction::GT, Instruction::ISZERO}, {Instruction::GT, Instruction::ISZERO}); + checkCSE({InternalInstruction::GT, InternalInstruction::ISZERO, InternalInstruction::ISZERO}, {InternalInstruction::GT}); + checkCSE({InternalInstruction::GT, InternalInstruction::ISZERO}, {InternalInstruction::GT, InternalInstruction::ISZERO}); checkCSE( - {Instruction::ISZERO, Instruction::ISZERO, Instruction::ISZERO}, - {Instruction::ISZERO} + {InternalInstruction::ISZERO, InternalInstruction::ISZERO, InternalInstruction::ISZERO}, + {InternalInstruction::ISZERO} ); } BOOST_AUTO_TEST_CASE(cse_associativity) { AssemblyItems input{ - Instruction::DUP1, - Instruction::DUP1, + InternalInstruction::DUP1, + InternalInstruction::DUP1, u256(0), - Instruction::OR, - Instruction::OR + InternalInstruction::OR, + InternalInstruction::OR }; - checkCSE(input, {Instruction::DUP1}); + checkCSE(input, {InternalInstruction::DUP1}); } BOOST_AUTO_TEST_CASE(cse_associativity2) { AssemblyItems input{ u256(0), - Instruction::DUP2, + InternalInstruction::DUP2, u256(2), u256(1), - Instruction::DUP6, - Instruction::ADD, + InternalInstruction::DUP6, + InternalInstruction::ADD, u256(2), - Instruction::ADD, - Instruction::ADD, - Instruction::ADD, - Instruction::ADD + InternalInstruction::ADD, + InternalInstruction::ADD, + InternalInstruction::ADD, + InternalInstruction::ADD }; - checkCSE(input, {Instruction::DUP2, Instruction::DUP2, Instruction::ADD, u256(5), Instruction::ADD}); + checkCSE(input, {InternalInstruction::DUP2, InternalInstruction::DUP2, InternalInstruction::ADD, u256(5), InternalInstruction::ADD}); } BOOST_AUTO_TEST_CASE(cse_double_shift_right_overflow) @@ -322,11 +322,11 @@ BOOST_AUTO_TEST_CASE(cse_double_shift_right_overflow) if (solidity::test::CommonOptions::get().evmVersion().hasBitwiseShifting()) { AssemblyItems input{ - Instruction::CALLVALUE, + InternalInstruction::CALLVALUE, u256(2), - Instruction::SHR, + InternalInstruction::SHR, u256(-1), - Instruction::SHR + InternalInstruction::SHR }; checkCSE(input, {u256(0)}); } @@ -337,11 +337,11 @@ BOOST_AUTO_TEST_CASE(cse_double_shift_left_overflow) if (solidity::test::CommonOptions::get().evmVersion().hasBitwiseShifting()) { AssemblyItems input{ - Instruction::DUP1, + InternalInstruction::DUP1, u256(2), - Instruction::SHL, + InternalInstruction::SHL, u256(-1), - Instruction::SHL + InternalInstruction::SHL }; checkCSE(input, {u256(0)}); } @@ -351,41 +351,41 @@ BOOST_AUTO_TEST_CASE(cse_byte_ordering_bug) { AssemblyItems input{ u256(31), - Instruction::CALLVALUE, - Instruction::BYTE + InternalInstruction::CALLVALUE, + InternalInstruction::BYTE }; - checkCSE(input, {u256(31), Instruction::CALLVALUE, Instruction::BYTE}); + checkCSE(input, {u256(31), InternalInstruction::CALLVALUE, InternalInstruction::BYTE}); } BOOST_AUTO_TEST_CASE(cse_byte_ordering_fix) { AssemblyItems input{ - Instruction::CALLVALUE, + InternalInstruction::CALLVALUE, u256(31), - Instruction::BYTE + InternalInstruction::BYTE }; - checkCSE(input, {u256(0xff), Instruction::CALLVALUE, Instruction::AND}); + checkCSE(input, {u256(0xff), InternalInstruction::CALLVALUE, InternalInstruction::AND}); } BOOST_AUTO_TEST_CASE(cse_storage) { AssemblyItems input{ u256(0), - Instruction::SLOAD, + InternalInstruction::SLOAD, u256(0), - Instruction::SLOAD, - Instruction::ADD, + InternalInstruction::SLOAD, + InternalInstruction::ADD, u256(0), - Instruction::SSTORE + InternalInstruction::SSTORE }; checkCSE(input, { u256(0), - Instruction::DUP1, - Instruction::SLOAD, - Instruction::DUP1, - Instruction::ADD, - Instruction::SWAP1, - Instruction::SSTORE + InternalInstruction::DUP1, + InternalInstruction::SLOAD, + InternalInstruction::DUP1, + InternalInstruction::ADD, + InternalInstruction::SWAP1, + InternalInstruction::SSTORE }); } @@ -395,18 +395,18 @@ BOOST_AUTO_TEST_CASE(cse_noninterleaved_storage) // read in the meantime AssemblyItems input{ u256(7), - Instruction::DUP2, - Instruction::SSTORE, - Instruction::DUP1, - Instruction::SLOAD, + InternalInstruction::DUP2, + InternalInstruction::SSTORE, + InternalInstruction::DUP1, + InternalInstruction::SLOAD, u256(8), - Instruction::DUP3, - Instruction::SSTORE + InternalInstruction::DUP3, + InternalInstruction::SSTORE }; checkCSE(input, { u256(8), - Instruction::DUP2, - Instruction::SSTORE, + InternalInstruction::DUP2, + InternalInstruction::SSTORE, u256(7) }); } @@ -416,13 +416,13 @@ BOOST_AUTO_TEST_CASE(cse_interleaved_storage) // stores and reads to/from two unknown locations, should not optimize away the first store AssemblyItems input{ u256(7), - Instruction::DUP2, - Instruction::SSTORE, // store to "DUP1" - Instruction::DUP2, - Instruction::SLOAD, // read from "DUP2", might be equal to "DUP1" + InternalInstruction::DUP2, + InternalInstruction::SSTORE, // store to "DUP1" + InternalInstruction::DUP2, + InternalInstruction::SLOAD, // read from "DUP2", might be equal to "DUP1" u256(0), - Instruction::DUP3, - Instruction::SSTORE // store different value to "DUP1" + InternalInstruction::DUP3, + InternalInstruction::SSTORE // store different value to "DUP1" }; checkCSE(input, input); } @@ -433,22 +433,22 @@ BOOST_AUTO_TEST_CASE(cse_interleaved_storage_same_value) // but it should optimize away the second, since we already know the value will be the same AssemblyItems input{ u256(7), - Instruction::DUP2, - Instruction::SSTORE, // store to "DUP1" - Instruction::DUP2, - Instruction::SLOAD, // read from "DUP2", might be equal to "DUP1" + InternalInstruction::DUP2, + InternalInstruction::SSTORE, // store to "DUP1" + InternalInstruction::DUP2, + InternalInstruction::SLOAD, // read from "DUP2", might be equal to "DUP1" u256(6), u256(1), - Instruction::ADD, - Instruction::DUP3, - Instruction::SSTORE // store same value to "DUP1" + InternalInstruction::ADD, + InternalInstruction::DUP3, + InternalInstruction::SSTORE // store same value to "DUP1" }; checkCSE(input, { u256(7), - Instruction::DUP2, - Instruction::SSTORE, - Instruction::DUP2, - Instruction::SLOAD + InternalInstruction::DUP2, + InternalInstruction::SSTORE, + InternalInstruction::DUP2, + InternalInstruction::SLOAD }); } @@ -459,19 +459,19 @@ BOOST_AUTO_TEST_CASE(cse_interleaved_storage_at_known_location) AssemblyItems input{ u256(0x70), u256(1), - Instruction::SSTORE, // store to 1 + InternalInstruction::SSTORE, // store to 1 u256(2), - Instruction::SLOAD, // read from 2, is different from 1 + InternalInstruction::SLOAD, // read from 2, is different from 1 u256(0x90), u256(1), - Instruction::SSTORE // store different value at 1 + InternalInstruction::SSTORE // store different value at 1 }; checkCSE(input, { u256(2), - Instruction::SLOAD, + InternalInstruction::SLOAD, u256(0x90), u256(1), - Instruction::SSTORE + InternalInstruction::SSTORE }); } @@ -481,69 +481,69 @@ BOOST_AUTO_TEST_CASE(cse_interleaved_storage_at_known_location_offset) // should optimize away the first store, because we know that the location is different AssemblyItems input{ u256(0x70), - Instruction::DUP2, + InternalInstruction::DUP2, u256(1), - Instruction::ADD, - Instruction::SSTORE, // store to "DUP1"+1 - Instruction::DUP1, + InternalInstruction::ADD, + InternalInstruction::SSTORE, // store to "DUP1"+1 + InternalInstruction::DUP1, u256(2), - Instruction::ADD, - Instruction::SLOAD, // read from "DUP1"+2, is different from "DUP1"+1 + InternalInstruction::ADD, + InternalInstruction::SLOAD, // read from "DUP1"+2, is different from "DUP1"+1 u256(0x90), - Instruction::DUP3, + InternalInstruction::DUP3, u256(1), - Instruction::ADD, - Instruction::SSTORE // store different value at "DUP1"+1 + InternalInstruction::ADD, + InternalInstruction::SSTORE // store different value at "DUP1"+1 }; checkCSE(input, { u256(2), - Instruction::DUP2, - Instruction::ADD, - Instruction::SLOAD, + InternalInstruction::DUP2, + InternalInstruction::ADD, + InternalInstruction::SLOAD, u256(0x90), u256(1), - Instruction::DUP4, - Instruction::ADD, - Instruction::SSTORE + InternalInstruction::DUP4, + InternalInstruction::ADD, + InternalInstruction::SSTORE }); } BOOST_AUTO_TEST_CASE(cse_deep_stack) { AssemblyItems input{ - Instruction::ADD, - Instruction::SWAP1, - Instruction::POP, - Instruction::SWAP8, - Instruction::POP, - Instruction::SWAP8, - Instruction::POP, - Instruction::SWAP8, - Instruction::SWAP5, - Instruction::POP, - Instruction::POP, - Instruction::POP, - Instruction::POP, - Instruction::POP, + InternalInstruction::ADD, + InternalInstruction::SWAP1, + InternalInstruction::POP, + InternalInstruction::SWAP8, + InternalInstruction::POP, + InternalInstruction::SWAP8, + InternalInstruction::POP, + InternalInstruction::SWAP8, + InternalInstruction::SWAP5, + InternalInstruction::POP, + InternalInstruction::POP, + InternalInstruction::POP, + InternalInstruction::POP, + InternalInstruction::POP, }; checkCSE(input, { - Instruction::SWAP4, - Instruction::SWAP12, - Instruction::SWAP3, - Instruction::SWAP11, - Instruction::POP, - Instruction::SWAP1, - Instruction::SWAP3, - Instruction::ADD, - Instruction::SWAP8, - Instruction::POP, - Instruction::SWAP6, - Instruction::POP, - Instruction::POP, - Instruction::POP, - Instruction::POP, - Instruction::POP, - Instruction::POP, + InternalInstruction::SWAP4, + InternalInstruction::SWAP12, + InternalInstruction::SWAP3, + InternalInstruction::SWAP11, + InternalInstruction::POP, + InternalInstruction::SWAP1, + InternalInstruction::SWAP3, + InternalInstruction::ADD, + InternalInstruction::SWAP8, + InternalInstruction::POP, + InternalInstruction::SWAP6, + InternalInstruction::POP, + InternalInstruction::POP, + InternalInstruction::POP, + InternalInstruction::POP, + InternalInstruction::POP, + InternalInstruction::POP, }); } @@ -552,9 +552,9 @@ BOOST_AUTO_TEST_CASE(cse_jumpi_no_jump) AssemblyItems input{ u256(0), u256(1), - Instruction::DUP2, + InternalInstruction::DUP2, AssemblyItem(PushTag, 1), - Instruction::JUMPI + InternalInstruction::JUMPI }; checkCSE(input, { u256(0), @@ -567,15 +567,15 @@ BOOST_AUTO_TEST_CASE(cse_jumpi_jump) AssemblyItems input{ u256(1), u256(1), - Instruction::DUP2, + InternalInstruction::DUP2, AssemblyItem(PushTag, 1), - Instruction::JUMPI + InternalInstruction::JUMPI }; checkCSE(input, { u256(1), - Instruction::DUP1, + InternalInstruction::DUP1, AssemblyItem(PushTag, 1), - Instruction::JUMP + InternalInstruction::JUMP }); } @@ -583,8 +583,8 @@ BOOST_AUTO_TEST_CASE(cse_empty_keccak256) { AssemblyItems input{ u256(0), - Instruction::DUP2, - Instruction::KECCAK256 + InternalInstruction::DUP2, + InternalInstruction::KECCAK256 }; checkCSE(input, { u256(util::keccak256(bytesConstRef())) @@ -596,15 +596,15 @@ BOOST_AUTO_TEST_CASE(cse_partial_keccak256) AssemblyItems input{ u256(0xabcd) << (256 - 16), u256(0), - Instruction::MSTORE, + InternalInstruction::MSTORE, u256(2), u256(0), - Instruction::KECCAK256 + InternalInstruction::KECCAK256 }; checkCSE(input, { u256(0xabcd) << (256 - 16), u256(0), - Instruction::MSTORE, + InternalInstruction::MSTORE, u256(util::keccak256(bytes{0xab, 0xcd})) }); } @@ -613,24 +613,24 @@ BOOST_AUTO_TEST_CASE(cse_keccak256_twice_same_location) { // Keccak-256 twice from same dynamic location AssemblyItems input{ - Instruction::DUP2, - Instruction::DUP1, - Instruction::MSTORE, + InternalInstruction::DUP2, + InternalInstruction::DUP1, + InternalInstruction::MSTORE, u256(64), - Instruction::DUP2, - Instruction::KECCAK256, + InternalInstruction::DUP2, + InternalInstruction::KECCAK256, u256(64), - Instruction::DUP3, - Instruction::KECCAK256 + InternalInstruction::DUP3, + InternalInstruction::KECCAK256 }; checkCSE(input, { - Instruction::DUP2, - Instruction::DUP1, - Instruction::MSTORE, + InternalInstruction::DUP2, + InternalInstruction::DUP1, + InternalInstruction::MSTORE, u256(64), - Instruction::DUP2, - Instruction::KECCAK256, - Instruction::DUP1 + InternalInstruction::DUP2, + InternalInstruction::KECCAK256, + InternalInstruction::DUP1 }); } @@ -638,32 +638,32 @@ BOOST_AUTO_TEST_CASE(cse_keccak256_twice_same_content) { // Keccak-256 twice from different dynamic location but with same content AssemblyItems input{ - Instruction::DUP1, + InternalInstruction::DUP1, u256(0x80), - Instruction::MSTORE, // m[128] = DUP1 + InternalInstruction::MSTORE, // m[128] = DUP1 u256(0x20), u256(0x80), - Instruction::KECCAK256, // keccak256(m[128..(128+32)]) - Instruction::DUP2, + InternalInstruction::KECCAK256, // keccak256(m[128..(128+32)]) + InternalInstruction::DUP2, u256(12), - Instruction::MSTORE, // m[12] = DUP1 + InternalInstruction::MSTORE, // m[12] = DUP1 u256(0x20), u256(12), - Instruction::KECCAK256 // keccak256(m[12..(12+32)]) + InternalInstruction::KECCAK256 // keccak256(m[12..(12+32)]) }; checkCSE(input, { u256(0x80), - Instruction::DUP2, - Instruction::DUP2, - Instruction::MSTORE, + InternalInstruction::DUP2, + InternalInstruction::DUP2, + InternalInstruction::MSTORE, u256(0x20), - Instruction::SWAP1, - Instruction::KECCAK256, + InternalInstruction::SWAP1, + InternalInstruction::KECCAK256, u256(12), - Instruction::DUP3, - Instruction::SWAP1, - Instruction::MSTORE, - Instruction::DUP1 + InternalInstruction::DUP3, + InternalInstruction::SWAP1, + InternalInstruction::MSTORE, + InternalInstruction::DUP1 }); } @@ -673,24 +673,24 @@ BOOST_AUTO_TEST_CASE(cse_keccak256_twice_same_content_dynamic_store_in_between) // dynamic mstore in between, which forces us to re-calculate the hash AssemblyItems input{ u256(0x80), - Instruction::DUP2, - Instruction::DUP2, - Instruction::MSTORE, // m[128] = DUP1 + InternalInstruction::DUP2, + InternalInstruction::DUP2, + InternalInstruction::MSTORE, // m[128] = DUP1 u256(0x20), - Instruction::DUP1, - Instruction::DUP3, - Instruction::KECCAK256, // keccak256(m[128..(128+32)]) + InternalInstruction::DUP1, + InternalInstruction::DUP3, + InternalInstruction::KECCAK256, // keccak256(m[128..(128+32)]) u256(12), - Instruction::DUP5, - Instruction::DUP2, - Instruction::MSTORE, // m[12] = DUP1 - Instruction::DUP12, - Instruction::DUP14, - Instruction::MSTORE, // destroys memory knowledge - Instruction::SWAP2, - Instruction::SWAP1, - Instruction::SWAP2, - Instruction::KECCAK256 // keccak256(m[12..(12+32)]) + InternalInstruction::DUP5, + InternalInstruction::DUP2, + InternalInstruction::MSTORE, // m[12] = DUP1 + InternalInstruction::DUP12, + InternalInstruction::DUP14, + InternalInstruction::MSTORE, // destroys memory knowledge + InternalInstruction::SWAP2, + InternalInstruction::SWAP1, + InternalInstruction::SWAP2, + InternalInstruction::KECCAK256 // keccak256(m[12..(12+32)]) }; checkCSE(input, input); } @@ -701,31 +701,31 @@ BOOST_AUTO_TEST_CASE(cse_keccak256_twice_same_content_noninterfering_store_in_be // dynamic mstore in between, but does not force us to re-calculate the hash AssemblyItems input{ u256(0x80), - Instruction::DUP2, - Instruction::DUP2, - Instruction::MSTORE, // m[128] = DUP1 + InternalInstruction::DUP2, + InternalInstruction::DUP2, + InternalInstruction::MSTORE, // m[128] = DUP1 u256(0x20), - Instruction::DUP1, - Instruction::DUP3, - Instruction::KECCAK256, // keccak256(m[128..(128+32)]) + InternalInstruction::DUP1, + InternalInstruction::DUP3, + InternalInstruction::KECCAK256, // keccak256(m[128..(128+32)]) u256(12), - Instruction::DUP5, - Instruction::DUP2, - Instruction::MSTORE, // m[12] = DUP1 - Instruction::DUP12, + InternalInstruction::DUP5, + InternalInstruction::DUP2, + InternalInstruction::MSTORE, // m[12] = DUP1 + InternalInstruction::DUP12, u256(12 + 32), - Instruction::MSTORE, // does not destroy memory knowledge - Instruction::DUP13, + InternalInstruction::MSTORE, // does not destroy memory knowledge + InternalInstruction::DUP13, u256(128 - 32), - Instruction::MSTORE, // does not destroy memory knowledge + InternalInstruction::MSTORE, // does not destroy memory knowledge u256(0x20), u256(12), - Instruction::KECCAK256 // keccak256(m[12..(12+32)]) + InternalInstruction::KECCAK256 // keccak256(m[12..(12+32)]) }; // if this changes too often, only count the number of SHA3 and MSTORE instructions AssemblyItems output = CSE(input); - BOOST_CHECK_EQUAL(4, count(output.begin(), output.end(), AssemblyItem(Instruction::MSTORE))); - BOOST_CHECK_EQUAL(1, count(output.begin(), output.end(), AssemblyItem(Instruction::KECCAK256))); + BOOST_CHECK_EQUAL(4, count(output.begin(), output.end(), AssemblyItem(InternalInstruction::MSTORE))); + BOOST_CHECK_EQUAL(1, count(output.begin(), output.end(), AssemblyItem(InternalInstruction::KECCAK256))); } BOOST_AUTO_TEST_CASE(cse_with_initially_known_stack) @@ -733,19 +733,19 @@ BOOST_AUTO_TEST_CASE(cse_with_initially_known_stack) evmasm::KnownState state = createInitialState(AssemblyItems{ u256(0x12), u256(0x20), - Instruction::ADD + InternalInstruction::ADD }); AssemblyItems input{ u256(0x12 + 0x20) }; - checkCSE(input, AssemblyItems{Instruction::DUP1}, state); + checkCSE(input, AssemblyItems{InternalInstruction::DUP1}, state); } BOOST_AUTO_TEST_CASE(cse_equality_on_initially_known_stack) { - evmasm::KnownState state = createInitialState(AssemblyItems{Instruction::DUP1}); + evmasm::KnownState state = createInitialState(AssemblyItems{InternalInstruction::DUP1}); AssemblyItems input{ - Instruction::EQ + InternalInstruction::EQ }; AssemblyItems output = CSE(input, state); // check that it directly pushes 1 (true) @@ -758,18 +758,18 @@ BOOST_AUTO_TEST_CASE(cse_access_previous_sequence) // from a sequenced expression which is not in its scope. evmasm::KnownState state = createInitialState(AssemblyItems{ u256(0), - Instruction::SLOAD, + InternalInstruction::SLOAD, u256(1), - Instruction::ADD, + InternalInstruction::ADD, u256(0), - Instruction::SSTORE + InternalInstruction::SSTORE }); // now stored: val_1 + 1 (value at sequence 1) // if in the following instructions, the SLOAD cresolves to "val_1 + 1", // this cannot be generated because we cannot load from sequence 1 anymore. AssemblyItems input{ u256(0), - Instruction::SLOAD, + InternalInstruction::SLOAD, }; BOOST_CHECK_THROW(CSE(input, state), StackTooDeepException); // @todo for now, this throws an exception, but it should recover to the following @@ -780,8 +780,8 @@ BOOST_AUTO_TEST_CASE(cse_access_previous_sequence) BOOST_AUTO_TEST_CASE(cse_optimise_return) { checkCSE( - AssemblyItems{u256(0), u256(7), Instruction::RETURN}, - AssemblyItems{Instruction::STOP} + AssemblyItems{u256(0), u256(7), InternalInstruction::RETURN}, + AssemblyItems{InternalInstruction::STOP} ); } @@ -790,7 +790,7 @@ BOOST_AUTO_TEST_CASE(control_flow_graph_remove_unused) // remove parts of the code that are unused AssemblyItems input{ AssemblyItem(PushTag, 1), - Instruction::JUMP, + InternalInstruction::JUMP, u256(7), AssemblyItem(Tag, 1), }; @@ -801,15 +801,15 @@ BOOST_AUTO_TEST_CASE(control_flow_graph_remove_unused_loop) { AssemblyItems input{ AssemblyItem(PushTag, 3), - Instruction::JUMP, + InternalInstruction::JUMP, AssemblyItem(Tag, 1), u256(7), AssemblyItem(PushTag, 2), - Instruction::JUMP, + InternalInstruction::JUMP, AssemblyItem(Tag, 2), u256(8), AssemblyItem(PushTag, 1), - Instruction::JUMP, + InternalInstruction::JUMP, AssemblyItem(Tag, 3), u256(11) }; @@ -822,15 +822,15 @@ BOOST_AUTO_TEST_CASE(control_flow_graph_reconnect_single_jump_source) AssemblyItems input{ u256(1), AssemblyItem(PushTag, 1), - Instruction::JUMP, + InternalInstruction::JUMP, AssemblyItem(Tag, 2), u256(2), AssemblyItem(PushTag, 3), - Instruction::JUMP, + InternalInstruction::JUMP, AssemblyItem(Tag, 1), u256(3), AssemblyItem(PushTag, 2), - Instruction::JUMP, + InternalInstruction::JUMP, AssemblyItem(Tag, 3), u256(4), }; @@ -843,9 +843,9 @@ BOOST_AUTO_TEST_CASE(control_flow_graph_do_not_remove_returned_to) AssemblyItems input{ AssemblyItem(PushTag, 1), AssemblyItem(PushTag, 2), - Instruction::JUMP, + InternalInstruction::JUMP, AssemblyItem(Tag, 2), - Instruction::JUMP, + InternalInstruction::JUMP, AssemblyItem(Tag, 1), u256(2) }; @@ -859,16 +859,16 @@ BOOST_AUTO_TEST_CASE(block_deduplicator) AssemblyItem(PushTag, 1), AssemblyItem(PushTag, 3), u256(6), - Instruction::SWAP3, - Instruction::JUMP, + InternalInstruction::SWAP3, + InternalInstruction::JUMP, AssemblyItem(Tag, 1), u256(6), - Instruction::SWAP3, - Instruction::JUMP, + InternalInstruction::SWAP3, + InternalInstruction::JUMP, AssemblyItem(Tag, 2), u256(6), - Instruction::SWAP3, - Instruction::JUMP, + InternalInstruction::SWAP3, + InternalInstruction::JUMP, AssemblyItem(Tag, 3) }; BlockDeduplicator deduplicator(input); @@ -887,11 +887,11 @@ BOOST_AUTO_TEST_CASE(block_deduplicator_assign_immutable_same) AssemblyItem(Tag, 1), u256(42), AssemblyItem{AssignImmutable, 0x1234}, - Instruction::JUMP, + InternalInstruction::JUMP, AssemblyItem(Tag, 2), u256(42), AssemblyItem{AssignImmutable, 0x1234}, - Instruction::JUMP + InternalInstruction::JUMP }; AssemblyItems input = AssemblyItems{ @@ -915,11 +915,11 @@ BOOST_AUTO_TEST_CASE(block_deduplicator_assign_immutable_different_value) AssemblyItem(Tag, 1), u256(42), AssemblyItem{AssignImmutable, 0x1234}, - Instruction::JUMP, + InternalInstruction::JUMP, AssemblyItem(Tag, 2), u256(23), AssemblyItem{AssignImmutable, 0x1234}, - Instruction::JUMP + InternalInstruction::JUMP }; BlockDeduplicator deduplicator(input); BOOST_CHECK(!deduplicator.deduplicate()); @@ -933,11 +933,11 @@ BOOST_AUTO_TEST_CASE(block_deduplicator_assign_immutable_different_hash) AssemblyItem(Tag, 1), u256(42), AssemblyItem{AssignImmutable, 0x1234}, - Instruction::JUMP, + InternalInstruction::JUMP, AssemblyItem(Tag, 2), u256(42), AssemblyItem{AssignImmutable, 0xABCD}, - Instruction::JUMP + InternalInstruction::JUMP }; BlockDeduplicator deduplicator(input); BOOST_CHECK(!deduplicator.deduplicate()); @@ -947,23 +947,23 @@ BOOST_AUTO_TEST_CASE(block_deduplicator_loops) { AssemblyItems input{ u256(0), - Instruction::SLOAD, + InternalInstruction::SLOAD, AssemblyItem(PushTag, 1), AssemblyItem(PushTag, 2), - Instruction::JUMPI, - Instruction::JUMP, + InternalInstruction::JUMPI, + InternalInstruction::JUMP, AssemblyItem(Tag, 1), u256(5), u256(6), - Instruction::SSTORE, + InternalInstruction::SSTORE, AssemblyItem(PushTag, 1), - Instruction::JUMP, + InternalInstruction::JUMP, AssemblyItem(Tag, 2), u256(5), u256(6), - Instruction::SSTORE, + InternalInstruction::SSTORE, AssemblyItem(PushTag, 2), - Instruction::JUMP, + InternalInstruction::JUMP, }; BlockDeduplicator deduplicator(input); deduplicator.deduplicate(); @@ -979,27 +979,27 @@ BOOST_AUTO_TEST_CASE(clear_unreachable_code) { AssemblyItems items{ AssemblyItem(PushTag, 1), - Instruction::JUMP, + InternalInstruction::JUMP, u256(0), - Instruction::SLOAD, + InternalInstruction::SLOAD, AssemblyItem(Tag, 2), u256(5), u256(6), - Instruction::SSTORE, + InternalInstruction::SSTORE, AssemblyItem(PushTag, 1), - Instruction::JUMP, + InternalInstruction::JUMP, u256(5), u256(6) }; AssemblyItems expectation{ AssemblyItem(PushTag, 1), - Instruction::JUMP, + InternalInstruction::JUMP, AssemblyItem(Tag, 2), u256(5), u256(6), - Instruction::SSTORE, + InternalInstruction::SSTORE, AssemblyItem(PushTag, 1), - Instruction::JUMP + InternalInstruction::JUMP }; PeepholeOptimiser peepOpt(items); BOOST_REQUIRE(peepOpt.optimise()); @@ -1021,9 +1021,9 @@ BOOST_AUTO_TEST_CASE(peephole_double_push) }; AssemblyItems expectation{ u256(0), - Instruction::DUP1, + InternalInstruction::DUP1, u256(5), - Instruction::DUP1, + InternalInstruction::DUP1, u256(4), u256(5) }; @@ -1039,9 +1039,9 @@ BOOST_AUTO_TEST_CASE(peephole_pop_calldatasize) { AssemblyItems items{ u256(4), - Instruction::CALLDATASIZE, - Instruction::LT, - Instruction::POP + InternalInstruction::CALLDATASIZE, + InternalInstruction::LT, + InternalInstruction::POP }; PeepholeOptimiser peepOpt(items); for (size_t i = 0; i < 3; i++) @@ -1051,20 +1051,20 @@ BOOST_AUTO_TEST_CASE(peephole_pop_calldatasize) BOOST_AUTO_TEST_CASE(peephole_commutative_swap1) { - vector ops{ - Instruction::ADD, - Instruction::MUL, - Instruction::EQ, - Instruction::AND, - Instruction::OR, - Instruction::XOR + vector ops{ + InternalInstruction::ADD, + InternalInstruction::MUL, + InternalInstruction::EQ, + InternalInstruction::AND, + InternalInstruction::OR, + InternalInstruction::XOR }; - for (Instruction const op: ops) + for (InternalInstruction const op: ops) { AssemblyItems items{ u256(1), u256(2), - Instruction::SWAP1, + InternalInstruction::SWAP1, op, u256(4), u256(5) @@ -1088,20 +1088,20 @@ BOOST_AUTO_TEST_CASE(peephole_commutative_swap1) BOOST_AUTO_TEST_CASE(peephole_noncommutative_swap1) { // NOTE: not comprehensive - vector ops{ - Instruction::SUB, - Instruction::DIV, - Instruction::SDIV, - Instruction::MOD, - Instruction::SMOD, - Instruction::EXP + vector ops{ + InternalInstruction::SUB, + InternalInstruction::DIV, + InternalInstruction::SDIV, + InternalInstruction::MOD, + InternalInstruction::SMOD, + InternalInstruction::EXP }; - for (Instruction const op: ops) + for (InternalInstruction const op: ops) { AssemblyItems items{ u256(1), u256(2), - Instruction::SWAP1, + InternalInstruction::SWAP1, op, u256(4), u256(5) @@ -1109,7 +1109,7 @@ BOOST_AUTO_TEST_CASE(peephole_noncommutative_swap1) AssemblyItems expectation{ u256(1), u256(2), - Instruction::SWAP1, + InternalInstruction::SWAP1, op, u256(4), u256(5) @@ -1125,11 +1125,11 @@ BOOST_AUTO_TEST_CASE(peephole_noncommutative_swap1) BOOST_AUTO_TEST_CASE(peephole_swap_comparison) { - map swappableOps{ - { Instruction::LT, Instruction::GT }, - { Instruction::GT, Instruction::LT }, - { Instruction::SLT, Instruction::SGT }, - { Instruction::SGT, Instruction::SLT } + map swappableOps{ + { InternalInstruction::LT, InternalInstruction::GT }, + { InternalInstruction::GT, InternalInstruction::LT }, + { InternalInstruction::SLT, InternalInstruction::SGT }, + { InternalInstruction::SGT, InternalInstruction::SLT } }; for (auto const& op: swappableOps) @@ -1137,7 +1137,7 @@ BOOST_AUTO_TEST_CASE(peephole_swap_comparison) AssemblyItems items{ u256(1), u256(2), - Instruction::SWAP1, + InternalInstruction::SWAP1, op.first, u256(4), u256(5) @@ -1162,18 +1162,18 @@ BOOST_AUTO_TEST_CASE(peephole_truthy_and) { AssemblyItems items{ AssemblyItem(Tag, 1), - Instruction::BALANCE, + InternalInstruction::BALANCE, u256(0), - Instruction::NOT, - Instruction::AND, + InternalInstruction::NOT, + InternalInstruction::AND, AssemblyItem(PushTag, 1), - Instruction::JUMPI + InternalInstruction::JUMPI }; AssemblyItems expectation{ AssemblyItem(Tag, 1), - Instruction::BALANCE, + InternalInstruction::BALANCE, AssemblyItem(PushTag, 1), - Instruction::JUMPI + InternalInstruction::JUMPI }; PeepholeOptimiser peepOpt(items); BOOST_REQUIRE(peepOpt.optimise()); @@ -1189,24 +1189,24 @@ BOOST_AUTO_TEST_CASE(peephole_iszero_iszero_jumpi) AssemblyItems items{ AssemblyItem(Tag, 1), u256(0), - Instruction::CALLDATALOAD, - Instruction::ISZERO, - Instruction::ISZERO, + InternalInstruction::CALLDATALOAD, + InternalInstruction::ISZERO, + InternalInstruction::ISZERO, AssemblyItem(PushTag, 1), - Instruction::JUMPI, + InternalInstruction::JUMPI, u256(0), u256(0x20), - Instruction::RETURN + InternalInstruction::RETURN }; AssemblyItems expectation{ AssemblyItem(Tag, 1), u256(0), - Instruction::CALLDATALOAD, + InternalInstruction::CALLDATALOAD, AssemblyItem(PushTag, 1), - Instruction::JUMPI, + InternalInstruction::JUMPI, u256(0), u256(0x20), - Instruction::RETURN + InternalInstruction::RETURN }; PeepholeOptimiser peepOpt(items); BOOST_REQUIRE(peepOpt.optimise()); @@ -1226,14 +1226,14 @@ BOOST_AUTO_TEST_CASE(jumpdest_removal) AssemblyItem(Tag, 3), u256(6), AssemblyItem(Tag, 1), - Instruction::JUMP, + InternalInstruction::JUMP, }; AssemblyItems expectation{ AssemblyItem(PushTag, 1), u256(5), u256(6), AssemblyItem(Tag, 1), - Instruction::JUMP + InternalInstruction::JUMP }; JumpdestRemover jdr(items); BOOST_REQUIRE(jdr.optimise({})); @@ -1257,11 +1257,11 @@ BOOST_AUTO_TEST_CASE(jumpdest_removal_subassemblies) auto t1 = sub->newTag(); sub->append(t1); sub->append(u256(2)); - sub->append(Instruction::JUMP); + sub->append(InternalInstruction::JUMP); auto t2 = sub->newTag(); sub->append(t2); // Identical to T1, will be unified sub->append(u256(2)); - sub->append(Instruction::JUMP); + sub->append(InternalInstruction::JUMP); auto t3 = sub->newTag(); sub->append(t3); auto t4 = sub->newTag(); @@ -1270,7 +1270,7 @@ BOOST_AUTO_TEST_CASE(jumpdest_removal_subassemblies) sub->append(t5); // This will be removed sub->append(u256(7)); sub->append(t4.pushTag()); - sub->append(Instruction::JUMP); + sub->append(InternalInstruction::JUMP); size_t subId = static_cast(main.appendSubroutine(sub).data()); main.append(t1.toSubAssemblyTag(subId)); @@ -1301,7 +1301,7 @@ BOOST_AUTO_TEST_CASE(jumpdest_removal_subassemblies) ); AssemblyItems expectationSub{ - u256(1), t1.tag(), u256(2), Instruction::JUMP, t4.tag(), u256(7), t4.pushTag(), Instruction::JUMP + u256(1), t1.tag(), u256(2), InternalInstruction::JUMP, t4.tag(), u256(7), t4.pushTag(), InternalInstruction::JUMP }; BOOST_CHECK_EQUAL_COLLECTIONS( sub->items().begin(), sub->items().end(), @@ -1313,21 +1313,21 @@ BOOST_AUTO_TEST_CASE(cse_sub_zero) { checkCSE({ u256(0), - Instruction::DUP2, - Instruction::SUB + InternalInstruction::DUP2, + InternalInstruction::SUB }, { - Instruction::DUP1 + InternalInstruction::DUP1 }); checkCSE({ - Instruction::DUP1, + InternalInstruction::DUP1, u256(0), - Instruction::SUB + InternalInstruction::SUB }, { u256(0), - Instruction::DUP2, - Instruction::SWAP1, - Instruction::SUB + InternalInstruction::DUP2, + InternalInstruction::SWAP1, + InternalInstruction::SUB }); } @@ -1343,8 +1343,8 @@ BOOST_AUTO_TEST_CASE(cse_mload_pop) { AssemblyItems input{ u256(1000), - Instruction::MLOAD, - Instruction::POP, + InternalInstruction::MLOAD, + InternalInstruction::POP, }; AssemblyItems output{ @@ -1359,12 +1359,12 @@ BOOST_AUTO_TEST_CASE(cse_verbatim_mload) auto verbatim = AssemblyItem{bytes{1, 2, 3, 4, 5}, 0, 0}; AssemblyItems input{ u256(1000), - Instruction::MLOAD, // Should not be removed - Instruction::POP, + InternalInstruction::MLOAD, // Should not be removed + InternalInstruction::POP, verbatim, u256(1000), - Instruction::MLOAD, // Should not be removed - Instruction::POP, + InternalInstruction::MLOAD, // Should not be removed + InternalInstruction::POP, }; checkFullCSE(input, input); @@ -1375,16 +1375,16 @@ BOOST_AUTO_TEST_CASE(cse_sload_verbatim_dup) auto verbatim = AssemblyItem{bytes{1, 2, 3, 4, 5}, 0, 0}; AssemblyItems input{ u256(0), - Instruction::SLOAD, + InternalInstruction::SLOAD, u256(0), - Instruction::SLOAD, + InternalInstruction::SLOAD, verbatim }; AssemblyItems output{ u256(0), - Instruction::SLOAD, - Instruction::DUP1, + InternalInstruction::SLOAD, + InternalInstruction::DUP1, verbatim }; @@ -1397,10 +1397,10 @@ BOOST_AUTO_TEST_CASE(cse_verbatim_sload_sideeffect) auto verbatim = AssemblyItem{bytes{1, 2, 3, 4, 5}, 0, 0}; AssemblyItems input{ u256(0), - Instruction::SLOAD, + InternalInstruction::SLOAD, verbatim, u256(0), - Instruction::SLOAD, + InternalInstruction::SLOAD, }; checkFullCSE(input, input); @@ -1411,10 +1411,10 @@ BOOST_AUTO_TEST_CASE(cse_verbatim_eq) auto verbatim = AssemblyItem{bytes{1, 2, 3, 4, 5}, 0, 0}; AssemblyItems input{ u256(0), - Instruction::SLOAD, + InternalInstruction::SLOAD, verbatim, - Instruction::DUP1, - Instruction::EQ + InternalInstruction::DUP1, + InternalInstruction::EQ }; checkFullCSE(input, input); @@ -1423,10 +1423,10 @@ BOOST_AUTO_TEST_CASE(cse_verbatim_eq) BOOST_AUTO_TEST_CASE(verbatim_knownstate) { KnownState state = createInitialState(AssemblyItems{ - Instruction::DUP1, - Instruction::DUP2, - Instruction::DUP3, - Instruction::DUP4 + InternalInstruction::DUP1, + InternalInstruction::DUP2, + InternalInstruction::DUP3, + InternalInstruction::DUP4 }); map const& stackElements = state.stackElements(); @@ -1469,26 +1469,26 @@ BOOST_AUTO_TEST_CASE(cse_remove_redundant_shift_masking) { checkCSE({ u256(boost::multiprecision::pow(u256(2), i) - 1), - Instruction::CALLVALUE, + InternalInstruction::CALLVALUE, u256(256-i), - Instruction::SHR, - Instruction::AND + InternalInstruction::SHR, + InternalInstruction::AND }, { - Instruction::CALLVALUE, + InternalInstruction::CALLVALUE, u256(256-i), - Instruction::SHR, + InternalInstruction::SHR, }); checkCSE({ - Instruction::CALLVALUE, + InternalInstruction::CALLVALUE, u256(256-i), - Instruction::SHR, + InternalInstruction::SHR, u256(boost::multiprecision::pow(u256(2), i)-1), - Instruction::AND + InternalInstruction::AND }, { - Instruction::CALLVALUE, + InternalInstruction::CALLVALUE, u256(256-i), - Instruction::SHR, + InternalInstruction::SHR, }); } @@ -1497,61 +1497,61 @@ BOOST_AUTO_TEST_CASE(cse_remove_redundant_shift_masking) { checkCSE({ u256(boost::multiprecision::pow(u256(2), i) - 1), - Instruction::CALLVALUE, + InternalInstruction::CALLVALUE, u256(255-i), - Instruction::SHR, - Instruction::AND + InternalInstruction::SHR, + InternalInstruction::AND }, { // Opt. did some reordering - Instruction::CALLVALUE, + InternalInstruction::CALLVALUE, u256(255-i), - Instruction::SHR, + InternalInstruction::SHR, u256(boost::multiprecision::pow(u256(2), i)-1), - Instruction::AND + InternalInstruction::AND }); checkCSE({ - Instruction::CALLVALUE, + InternalInstruction::CALLVALUE, u256(255-i), - Instruction::SHR, + InternalInstruction::SHR, u256(boost::multiprecision::pow(u256(2), i)-1), - Instruction::AND + InternalInstruction::AND }, { // Opt. did some reordering u256(boost::multiprecision::pow(u256(2), i)-1), - Instruction::CALLVALUE, + InternalInstruction::CALLVALUE, u256(255-i), - Instruction::SHR, - Instruction::AND + InternalInstruction::SHR, + InternalInstruction::AND }); } //(x >> (31*8)) & 0xffffffff checkCSE({ - Instruction::CALLVALUE, + InternalInstruction::CALLVALUE, u256(31*8), - Instruction::SHR, + InternalInstruction::SHR, u256(0xffffffff), - Instruction::AND + InternalInstruction::AND }, { - Instruction::CALLVALUE, + InternalInstruction::CALLVALUE, u256(31*8), - Instruction::SHR + InternalInstruction::SHR }); } BOOST_AUTO_TEST_CASE(cse_remove_unwanted_masking_of_address) { - vector ops{ - Instruction::ADDRESS, - Instruction::CALLER, - Instruction::ORIGIN, - Instruction::COINBASE + vector ops{ + InternalInstruction::ADDRESS, + InternalInstruction::CALLER, + InternalInstruction::ORIGIN, + InternalInstruction::COINBASE }; for (auto const& op: ops) { checkCSE({ u256("0xffffffffffffffffffffffffffffffffffffffff"), op, - Instruction::AND + InternalInstruction::AND }, { op }); @@ -1559,7 +1559,7 @@ BOOST_AUTO_TEST_CASE(cse_remove_unwanted_masking_of_address) checkCSE({ op, u256("0xffffffffffffffffffffffffffffffffffffffff"), - Instruction::AND + InternalInstruction::AND }, { op }); @@ -1568,43 +1568,43 @@ BOOST_AUTO_TEST_CASE(cse_remove_unwanted_masking_of_address) checkCSE({ u256(1234), op, - Instruction::AND + InternalInstruction::AND }, { op, u256(1234), - Instruction::AND + InternalInstruction::AND }); checkCSE({ op, u256(1234), - Instruction::AND + InternalInstruction::AND }, { u256(1234), op, - Instruction::AND + InternalInstruction::AND }); } // leave other opcodes untouched checkCSE({ u256("0xffffffffffffffffffffffffffffffffffffffff"), - Instruction::CALLVALUE, - Instruction::AND + InternalInstruction::CALLVALUE, + InternalInstruction::AND }, { - Instruction::CALLVALUE, + InternalInstruction::CALLVALUE, u256("0xffffffffffffffffffffffffffffffffffffffff"), - Instruction::AND + InternalInstruction::AND }); checkCSE({ - Instruction::CALLVALUE, + InternalInstruction::CALLVALUE, u256("0xffffffffffffffffffffffffffffffffffffffff"), - Instruction::AND + InternalInstruction::AND }, { u256("0xffffffffffffffffffffffffffffffffffffffff"), - Instruction::CALLVALUE, - Instruction::AND + InternalInstruction::CALLVALUE, + InternalInstruction::AND }); } @@ -1614,69 +1614,69 @@ BOOST_AUTO_TEST_CASE(cse_replace_too_large_shift) return; checkCSE({ - Instruction::CALLVALUE, + InternalInstruction::CALLVALUE, u256(299), - Instruction::SHL + InternalInstruction::SHL }, { u256(0) }); checkCSE({ - Instruction::CALLVALUE, + InternalInstruction::CALLVALUE, u256(299), - Instruction::SHR + InternalInstruction::SHR }, { u256(0) }); checkCSE({ - Instruction::CALLVALUE, + InternalInstruction::CALLVALUE, u256(255), - Instruction::SHL + InternalInstruction::SHL }, { - Instruction::CALLVALUE, + InternalInstruction::CALLVALUE, u256(255), - Instruction::SHL + InternalInstruction::SHL }); checkCSE({ - Instruction::CALLVALUE, + InternalInstruction::CALLVALUE, u256(255), - Instruction::SHR + InternalInstruction::SHR }, { - Instruction::CALLVALUE, + InternalInstruction::CALLVALUE, u256(255), - Instruction::SHR + InternalInstruction::SHR }); } BOOST_AUTO_TEST_CASE(inliner) { - AssemblyItem jumpInto{Instruction::JUMP}; + AssemblyItem jumpInto{InternalInstruction::JUMP}; jumpInto.setJumpType(AssemblyItem::JumpType::IntoFunction); - AssemblyItem jumpOutOf{Instruction::JUMP}; + AssemblyItem jumpOutOf{InternalInstruction::JUMP}; jumpOutOf.setJumpType(AssemblyItem::JumpType::OutOfFunction); AssemblyItems items{ AssemblyItem(PushTag, 1), AssemblyItem(PushTag, 2), jumpInto, AssemblyItem(Tag, 1), - Instruction::STOP, + InternalInstruction::STOP, AssemblyItem(Tag, 2), - Instruction::CALLVALUE, - Instruction::SWAP1, + InternalInstruction::CALLVALUE, + InternalInstruction::SWAP1, jumpOutOf, }; AssemblyItems expectation{ AssemblyItem(PushTag, 1), - Instruction::CALLVALUE, - Instruction::SWAP1, - Instruction::JUMP, + InternalInstruction::CALLVALUE, + InternalInstruction::SWAP1, + InternalInstruction::JUMP, AssemblyItem(Tag, 1), - Instruction::STOP, + InternalInstruction::STOP, AssemblyItem(Tag, 2), - Instruction::CALLVALUE, - Instruction::SWAP1, + InternalInstruction::CALLVALUE, + InternalInstruction::SWAP1, jumpOutOf, }; Inliner{items, {}, Assembly::OptimiserSettings{}.expectedExecutionsPerDeployment, false, {}}.optimise(); @@ -1693,13 +1693,13 @@ BOOST_AUTO_TEST_CASE(inliner_no_inline_type) AssemblyItems items{ AssemblyItem(PushTag, 1), AssemblyItem(PushTag, 2), - Instruction::JUMP, + InternalInstruction::JUMP, AssemblyItem(Tag, 1), - Instruction::STOP, + InternalInstruction::STOP, AssemblyItem(Tag, 2), - Instruction::CALLVALUE, - Instruction::SWAP1, - Instruction::JUMP, + InternalInstruction::CALLVALUE, + InternalInstruction::SWAP1, + InternalInstruction::JUMP, }; Inliner{items, {}, Assembly::OptimiserSettings{}.expectedExecutionsPerDeployment, false, {}}.optimise(); BOOST_CHECK_EQUAL_COLLECTIONS( @@ -1712,19 +1712,19 @@ BOOST_AUTO_TEST_CASE(inliner_no_inline) { AssemblyItems items{ AssemblyItem(PushTag, 1), - Instruction::JUMP, + InternalInstruction::JUMP, AssemblyItem(Tag, 1), - Instruction::CALLVALUE, - Instruction::JUMPI, - Instruction::JUMP, + InternalInstruction::CALLVALUE, + InternalInstruction::JUMPI, + InternalInstruction::JUMP, }; AssemblyItems expectation{ AssemblyItem(PushTag, 1), - Instruction::JUMP, + InternalInstruction::JUMP, AssemblyItem(Tag, 1), - Instruction::CALLVALUE, - Instruction::JUMPI, - Instruction::JUMP, + InternalInstruction::CALLVALUE, + InternalInstruction::JUMPI, + InternalInstruction::JUMP, }; Inliner{items, {}, Assembly::OptimiserSettings{}.expectedExecutionsPerDeployment, false, {}}.optimise(); BOOST_CHECK_EQUAL_COLLECTIONS( @@ -1736,24 +1736,24 @@ BOOST_AUTO_TEST_CASE(inliner_no_inline) BOOST_AUTO_TEST_CASE(inliner_single_jump) { - AssemblyItem jumpInto{Instruction::JUMP}; + AssemblyItem jumpInto{InternalInstruction::JUMP}; jumpInto.setJumpType(AssemblyItem::JumpType::IntoFunction); - AssemblyItem jumpOutOf{Instruction::JUMP}; + AssemblyItem jumpOutOf{InternalInstruction::JUMP}; jumpOutOf.setJumpType(AssemblyItem::JumpType::OutOfFunction); AssemblyItems items{ AssemblyItem(PushTag, 1), AssemblyItem(PushTag, 2), jumpInto, AssemblyItem(Tag, 1), - Instruction::STOP, + InternalInstruction::STOP, AssemblyItem(Tag, 2), jumpOutOf, }; AssemblyItems expectation{ AssemblyItem(PushTag, 1), - Instruction::JUMP, + InternalInstruction::JUMP, AssemblyItem(Tag, 1), - Instruction::STOP, + InternalInstruction::STOP, AssemblyItem(Tag, 2), jumpOutOf, }; @@ -1766,7 +1766,7 @@ BOOST_AUTO_TEST_CASE(inliner_single_jump) BOOST_AUTO_TEST_CASE(inliner_end_of_bytecode) { - AssemblyItem jumpInto{Instruction::JUMP}; + AssemblyItem jumpInto{InternalInstruction::JUMP}; jumpInto.setJumpType(AssemblyItem::JumpType::IntoFunction); // Cannot inline, since the block at Tag_2 does not end in a jump. AssemblyItems items{ @@ -1774,7 +1774,7 @@ BOOST_AUTO_TEST_CASE(inliner_end_of_bytecode) AssemblyItem(PushTag, 2), jumpInto, AssemblyItem(Tag, 1), - Instruction::STOP, + InternalInstruction::STOP, AssemblyItem(Tag, 2), }; Inliner{items, {}, Assembly::OptimiserSettings{}.expectedExecutionsPerDeployment, false, {}}.optimise(); @@ -1787,9 +1787,9 @@ BOOST_AUTO_TEST_CASE(inliner_end_of_bytecode) BOOST_AUTO_TEST_CASE(inliner_cse_break) { - AssemblyItem jumpInto{Instruction::JUMP}; + AssemblyItem jumpInto{InternalInstruction::JUMP}; jumpInto.setJumpType(AssemblyItem::JumpType::IntoFunction); - AssemblyItem jumpOutOf{Instruction::JUMP}; + AssemblyItem jumpOutOf{InternalInstruction::JUMP}; jumpOutOf.setJumpType(AssemblyItem::JumpType::OutOfFunction); // Could be inlined, but we only consider non-CSE-breaking blocks ending in JUMP so far. AssemblyItems items{ @@ -1797,9 +1797,9 @@ BOOST_AUTO_TEST_CASE(inliner_cse_break) AssemblyItem(PushTag, 2), jumpInto, AssemblyItem(Tag, 1), - Instruction::STOP, + InternalInstruction::STOP, AssemblyItem(Tag, 2), - Instruction::STOP, // CSE breaking instruction + InternalInstruction::STOP, // CSE breaking instruction jumpOutOf }; Inliner{items, {}, Assembly::OptimiserSettings{}.expectedExecutionsPerDeployment, false, {}}.optimise(); @@ -1813,14 +1813,14 @@ BOOST_AUTO_TEST_CASE(inliner_stop) { AssemblyItems items{ AssemblyItem(PushTag, 1), - Instruction::JUMP, + InternalInstruction::JUMP, AssemblyItem(Tag, 1), - Instruction::STOP + InternalInstruction::STOP }; AssemblyItems expectation{ - Instruction::STOP, + InternalInstruction::STOP, AssemblyItem(Tag, 1), - Instruction::STOP + InternalInstruction::STOP }; Inliner{items, {}, Assembly::OptimiserSettings{}.expectedExecutionsPerDeployment, false, {}}.optimise(); BOOST_CHECK_EQUAL_COLLECTIONS( @@ -1835,9 +1835,9 @@ BOOST_AUTO_TEST_CASE(inliner_stop_jumpi) AssemblyItems items{ u256(1), AssemblyItem(PushTag, 1), - Instruction::JUMPI, + InternalInstruction::JUMPI, AssemblyItem(Tag, 1), - Instruction::STOP + InternalInstruction::STOP }; AssemblyItems expectation = items; Inliner{items, {}, Assembly::OptimiserSettings{}.expectedExecutionsPerDeployment, false, {}}.optimise(); @@ -1851,20 +1851,20 @@ BOOST_AUTO_TEST_CASE(inliner_revert) { AssemblyItems items{ AssemblyItem(PushTag, 1), - Instruction::JUMP, + InternalInstruction::JUMP, AssemblyItem(Tag, 1), u256(0), - Instruction::DUP1, - Instruction::REVERT + InternalInstruction::DUP1, + InternalInstruction::REVERT }; AssemblyItems expectation{ u256(0), - Instruction::DUP1, - Instruction::REVERT, + InternalInstruction::DUP1, + InternalInstruction::REVERT, AssemblyItem(Tag, 1), u256(0), - Instruction::DUP1, - Instruction::REVERT + InternalInstruction::DUP1, + InternalInstruction::REVERT }; Inliner{items, {}, Assembly::OptimiserSettings{}.expectedExecutionsPerDeployment, false, {}}.optimise(); @@ -1879,11 +1879,11 @@ BOOST_AUTO_TEST_CASE(inliner_revert_increased_datagas) // Inlining this would increase data gas (5 bytes v/s 4 bytes), therefore, skipped. AssemblyItems items{ AssemblyItem(PushTag, 1), - Instruction::JUMP, + InternalInstruction::JUMP, AssemblyItem(Tag, 1), u256(0), u256(0), - Instruction::REVERT + InternalInstruction::REVERT }; AssemblyItems expectation = items; @@ -1898,15 +1898,15 @@ BOOST_AUTO_TEST_CASE(inliner_invalid) { AssemblyItems items{ AssemblyItem(PushTag, 1), - Instruction::JUMP, + InternalInstruction::JUMP, AssemblyItem(Tag, 1), - Instruction::INVALID + InternalInstruction::INVALID }; AssemblyItems expectation = { - Instruction::INVALID, + InternalInstruction::INVALID, AssemblyItem(Tag, 1), - Instruction::INVALID + InternalInstruction::INVALID }; Inliner{items, {}, Assembly::OptimiserSettings{}.expectedExecutionsPerDeployment, false, {}}.optimise(); BOOST_CHECK_EQUAL_COLLECTIONS( diff --git a/test/libsolidity/SolidityExpressionCompiler.cpp b/test/libsolidity/SolidityExpressionCompiler.cpp index 2741290fc..288197453 100644 --- a/test/libsolidity/SolidityExpressionCompiler.cpp +++ b/test/libsolidity/SolidityExpressionCompiler.cpp @@ -197,7 +197,7 @@ BOOST_AUTO_TEST_CASE(literal_true) )"; bytes code = compileFirstExpression(sourceCode); - bytes expectation({uint8_t(Instruction::PUSH1), 0x1}); + bytes expectation({uint8_t(InternalInstruction::PUSH1), 0x1}); BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end()); } @@ -210,7 +210,7 @@ BOOST_AUTO_TEST_CASE(literal_false) )"; bytes code = compileFirstExpression(sourceCode); - bytes expectation({uint8_t(Instruction::PUSH1), 0x0}); + bytes expectation({uint8_t(InternalInstruction::PUSH1), 0x0}); BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end()); } @@ -223,7 +223,7 @@ BOOST_AUTO_TEST_CASE(int_literal) )"; bytes code = compileFirstExpression(sourceCode); - bytes expectation({uint8_t(Instruction::PUSH10), 0x12, 0x34, 0x56, 0x78, 0x90, + bytes expectation({uint8_t(InternalInstruction::PUSH10), 0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56, 0x78, 0x90}); BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end()); } @@ -239,7 +239,7 @@ BOOST_AUTO_TEST_CASE(int_with_wei_ether_subdenomination) )"; bytes code = compileFirstExpression(sourceCode); - bytes expectation({uint8_t(Instruction::PUSH1), 0x1}); + bytes expectation({uint8_t(InternalInstruction::PUSH1), 0x1}); BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end()); } @@ -254,7 +254,7 @@ BOOST_AUTO_TEST_CASE(int_with_gwei_ether_subdenomination) )"; bytes code = compileFirstExpression(sourceCode); - bytes expectation({uint8_t(Instruction::PUSH4), 0x3b, 0x9a, 0xca, 0x00}); + bytes expectation({uint8_t(InternalInstruction::PUSH4), 0x3b, 0x9a, 0xca, 0x00}); BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end()); } @@ -269,7 +269,7 @@ BOOST_AUTO_TEST_CASE(int_with_ether_ether_subdenomination) )"; bytes code = compileFirstExpression(sourceCode); - bytes expectation({uint8_t(Instruction::PUSH8), 0xd, 0xe0, 0xb6, 0xb3, 0xa7, 0x64, 0x00, 0x00}); + bytes expectation({uint8_t(InternalInstruction::PUSH8), 0xd, 0xe0, 0xb6, 0xb3, 0xa7, 0x64, 0x00, 0x00}); BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end()); } @@ -285,22 +285,22 @@ BOOST_AUTO_TEST_CASE(comparison) bytes expectation; if (solidity::test::CommonOptions::get().optimize) expectation = { - uint8_t(Instruction::PUSH2), 0x11, 0xaa, - uint8_t(Instruction::PUSH2), 0x10, 0xaa, - uint8_t(Instruction::LT), uint8_t(Instruction::ISZERO), uint8_t(Instruction::ISZERO), - uint8_t(Instruction::PUSH1), 0x1, - uint8_t(Instruction::ISZERO), uint8_t(Instruction::ISZERO), - uint8_t(Instruction::EQ), - uint8_t(Instruction::ISZERO) + uint8_t(InternalInstruction::PUSH2), 0x11, 0xaa, + uint8_t(InternalInstruction::PUSH2), 0x10, 0xaa, + uint8_t(InternalInstruction::LT), uint8_t(InternalInstruction::ISZERO), uint8_t(InternalInstruction::ISZERO), + uint8_t(InternalInstruction::PUSH1), 0x1, + uint8_t(InternalInstruction::ISZERO), uint8_t(InternalInstruction::ISZERO), + uint8_t(InternalInstruction::EQ), + uint8_t(InternalInstruction::ISZERO) }; else expectation = { - uint8_t(Instruction::PUSH1), 0x1, uint8_t(Instruction::ISZERO), uint8_t(Instruction::ISZERO), - uint8_t(Instruction::PUSH2), 0x11, 0xaa, - uint8_t(Instruction::PUSH2), 0x10, 0xaa, - uint8_t(Instruction::LT), uint8_t(Instruction::ISZERO), uint8_t(Instruction::ISZERO), - uint8_t(Instruction::EQ), - uint8_t(Instruction::ISZERO) + uint8_t(InternalInstruction::PUSH1), 0x1, uint8_t(InternalInstruction::ISZERO), uint8_t(InternalInstruction::ISZERO), + uint8_t(InternalInstruction::PUSH2), 0x11, 0xaa, + uint8_t(InternalInstruction::PUSH2), 0x10, 0xaa, + uint8_t(InternalInstruction::LT), uint8_t(InternalInstruction::ISZERO), uint8_t(InternalInstruction::ISZERO), + uint8_t(InternalInstruction::EQ), + uint8_t(InternalInstruction::ISZERO) }; BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end()); } @@ -315,23 +315,23 @@ BOOST_AUTO_TEST_CASE(short_circuiting) bytes code = compileFirstExpression(sourceCode); bytes expectation{ - uint8_t(Instruction::PUSH1), 0x12, // 8 + 10 - uint8_t(Instruction::PUSH1), 0x4, - uint8_t(Instruction::GT), - uint8_t(Instruction::ISZERO), // after this we have 4 <= 8 + 10 - uint8_t(Instruction::DUP1), - uint8_t(Instruction::PUSH1), 0x11, - uint8_t(Instruction::JUMPI), // short-circuit if it is true - uint8_t(Instruction::POP), - uint8_t(Instruction::PUSH1), 0x2, - uint8_t(Instruction::PUSH1), 0x9, - uint8_t(Instruction::EQ), - uint8_t(Instruction::ISZERO), // after this we have 9 != 2 - uint8_t(Instruction::JUMPDEST), - uint8_t(Instruction::ISZERO), uint8_t(Instruction::ISZERO), - uint8_t(Instruction::PUSH1), 0x1, uint8_t(Instruction::ISZERO), uint8_t(Instruction::ISZERO), - uint8_t(Instruction::EQ), - uint8_t(Instruction::ISZERO) + uint8_t(InternalInstruction::PUSH1), 0x12, // 8 + 10 + uint8_t(InternalInstruction::PUSH1), 0x4, + uint8_t(InternalInstruction::GT), + uint8_t(InternalInstruction::ISZERO), // after this we have 4 <= 8 + 10 + uint8_t(InternalInstruction::DUP1), + uint8_t(InternalInstruction::PUSH1), 0x11, + uint8_t(InternalInstruction::JUMPI), // short-circuit if it is true + uint8_t(InternalInstruction::POP), + uint8_t(InternalInstruction::PUSH1), 0x2, + uint8_t(InternalInstruction::PUSH1), 0x9, + uint8_t(InternalInstruction::EQ), + uint8_t(InternalInstruction::ISZERO), // after this we have 9 != 2 + uint8_t(InternalInstruction::JUMPDEST), + uint8_t(InternalInstruction::ISZERO), uint8_t(InternalInstruction::ISZERO), + uint8_t(InternalInstruction::PUSH1), 0x1, uint8_t(InternalInstruction::ISZERO), uint8_t(InternalInstruction::ISZERO), + uint8_t(InternalInstruction::EQ), + uint8_t(InternalInstruction::ISZERO) }; BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end()); } @@ -347,108 +347,108 @@ BOOST_AUTO_TEST_CASE(arithmetic) bytes panic = bytes{ - uint8_t(Instruction::JUMPDEST), - uint8_t(Instruction::PUSH32) + uint8_t(InternalInstruction::JUMPDEST), + uint8_t(InternalInstruction::PUSH32) } + util::fromHex("4E487B7100000000000000000000000000000000000000000000000000000000") + bytes{ - uint8_t(Instruction::PUSH1), 0x0, - uint8_t(Instruction::MSTORE), - uint8_t(Instruction::PUSH1), 0x12, - uint8_t(Instruction::PUSH1), 0x4, - uint8_t(Instruction::MSTORE), - uint8_t(Instruction::PUSH1), 0x24, - uint8_t(Instruction::PUSH1), 0x0, - uint8_t(Instruction::REVERT), - uint8_t(Instruction::JUMPDEST), - uint8_t(Instruction::JUMP), - uint8_t(Instruction::JUMPDEST) + uint8_t(InternalInstruction::PUSH1), 0x0, + uint8_t(InternalInstruction::MSTORE), + uint8_t(InternalInstruction::PUSH1), 0x12, + uint8_t(InternalInstruction::PUSH1), 0x4, + uint8_t(InternalInstruction::MSTORE), + uint8_t(InternalInstruction::PUSH1), 0x24, + uint8_t(InternalInstruction::PUSH1), 0x0, + uint8_t(InternalInstruction::REVERT), + uint8_t(InternalInstruction::JUMPDEST), + uint8_t(InternalInstruction::JUMP), + uint8_t(InternalInstruction::JUMPDEST) }; bytes expectation; if (solidity::test::CommonOptions::get().optimize) expectation = bytes{ - uint8_t(Instruction::PUSH1), 0x2, - uint8_t(Instruction::PUSH1), 0x3, - uint8_t(Instruction::PUSH1), 0x5, - uint8_t(Instruction::DUP4), - uint8_t(Instruction::PUSH1), 0x8, - uint8_t(Instruction::XOR), - uint8_t(Instruction::PUSH1), 0x7, - uint8_t(Instruction::AND), - uint8_t(Instruction::PUSH1), 0x6, - uint8_t(Instruction::OR), - uint8_t(Instruction::SUB), - uint8_t(Instruction::PUSH1), 0x4, - uint8_t(Instruction::ADD), - uint8_t(Instruction::DUP2), - uint8_t(Instruction::ISZERO), - uint8_t(Instruction::ISZERO), - uint8_t(Instruction::PUSH1), 0x20, - uint8_t(Instruction::JUMPI), - uint8_t(Instruction::PUSH1), 0x1f, - uint8_t(Instruction::PUSH1), 0x36, - uint8_t(Instruction::JUMP), - uint8_t(Instruction::JUMPDEST), - uint8_t(Instruction::JUMPDEST), - uint8_t(Instruction::MOD), - uint8_t(Instruction::DUP2), - uint8_t(Instruction::ISZERO), - uint8_t(Instruction::ISZERO), - uint8_t(Instruction::PUSH1), 0x2e, - uint8_t(Instruction::JUMPI), - uint8_t(Instruction::PUSH1), 0x2d, - uint8_t(Instruction::PUSH1), 0x36, - uint8_t(Instruction::JUMP), - uint8_t(Instruction::JUMPDEST), - uint8_t(Instruction::JUMPDEST), - uint8_t(Instruction::DIV), - uint8_t(Instruction::PUSH1), 0x1, - uint8_t(Instruction::MUL), - uint8_t(Instruction::PUSH1), 0x67, - uint8_t(Instruction::JUMP) + uint8_t(InternalInstruction::PUSH1), 0x2, + uint8_t(InternalInstruction::PUSH1), 0x3, + uint8_t(InternalInstruction::PUSH1), 0x5, + uint8_t(InternalInstruction::DUP4), + uint8_t(InternalInstruction::PUSH1), 0x8, + uint8_t(InternalInstruction::XOR), + uint8_t(InternalInstruction::PUSH1), 0x7, + uint8_t(InternalInstruction::AND), + uint8_t(InternalInstruction::PUSH1), 0x6, + uint8_t(InternalInstruction::OR), + uint8_t(InternalInstruction::SUB), + uint8_t(InternalInstruction::PUSH1), 0x4, + uint8_t(InternalInstruction::ADD), + uint8_t(InternalInstruction::DUP2), + uint8_t(InternalInstruction::ISZERO), + uint8_t(InternalInstruction::ISZERO), + uint8_t(InternalInstruction::PUSH1), 0x20, + uint8_t(InternalInstruction::JUMPI), + uint8_t(InternalInstruction::PUSH1), 0x1f, + uint8_t(InternalInstruction::PUSH1), 0x36, + uint8_t(InternalInstruction::JUMP), + uint8_t(InternalInstruction::JUMPDEST), + uint8_t(InternalInstruction::JUMPDEST), + uint8_t(InternalInstruction::MOD), + uint8_t(InternalInstruction::DUP2), + uint8_t(InternalInstruction::ISZERO), + uint8_t(InternalInstruction::ISZERO), + uint8_t(InternalInstruction::PUSH1), 0x2e, + uint8_t(InternalInstruction::JUMPI), + uint8_t(InternalInstruction::PUSH1), 0x2d, + uint8_t(InternalInstruction::PUSH1), 0x36, + uint8_t(InternalInstruction::JUMP), + uint8_t(InternalInstruction::JUMPDEST), + uint8_t(InternalInstruction::JUMPDEST), + uint8_t(InternalInstruction::DIV), + uint8_t(InternalInstruction::PUSH1), 0x1, + uint8_t(InternalInstruction::MUL), + uint8_t(InternalInstruction::PUSH1), 0x67, + uint8_t(InternalInstruction::JUMP) } + panic; else expectation = bytes{ - uint8_t(Instruction::PUSH1), 0x1, - uint8_t(Instruction::PUSH1), 0x2, - uint8_t(Instruction::PUSH1), 0x3, - uint8_t(Instruction::PUSH1), 0x4, - uint8_t(Instruction::PUSH1), 0x5, - uint8_t(Instruction::PUSH1), 0x6, - uint8_t(Instruction::PUSH1), 0x7, - uint8_t(Instruction::PUSH1), 0x8, - uint8_t(Instruction::DUP9), - uint8_t(Instruction::XOR), - uint8_t(Instruction::AND), - uint8_t(Instruction::OR), - uint8_t(Instruction::SUB), - uint8_t(Instruction::ADD), - uint8_t(Instruction::DUP2), - uint8_t(Instruction::ISZERO), - uint8_t(Instruction::ISZERO), - uint8_t(Instruction::PUSH1), 0x22, - uint8_t(Instruction::JUMPI), - uint8_t(Instruction::PUSH1), 0x21, - uint8_t(Instruction::PUSH1), 0x36, - uint8_t(Instruction::JUMP), - uint8_t(Instruction::JUMPDEST), - uint8_t(Instruction::JUMPDEST), - uint8_t(Instruction::MOD), - uint8_t(Instruction::DUP2), - uint8_t(Instruction::ISZERO), - uint8_t(Instruction::ISZERO), - uint8_t(Instruction::PUSH1), 0x30, - uint8_t(Instruction::JUMPI), - uint8_t(Instruction::PUSH1), 0x2f, - uint8_t(Instruction::PUSH1), 0x36, - uint8_t(Instruction::JUMP), - uint8_t(Instruction::JUMPDEST), - uint8_t(Instruction::JUMPDEST), - uint8_t(Instruction::DIV), - uint8_t(Instruction::MUL), - uint8_t(Instruction::PUSH1), 0x67, - uint8_t(Instruction::JUMP) + uint8_t(InternalInstruction::PUSH1), 0x1, + uint8_t(InternalInstruction::PUSH1), 0x2, + uint8_t(InternalInstruction::PUSH1), 0x3, + uint8_t(InternalInstruction::PUSH1), 0x4, + uint8_t(InternalInstruction::PUSH1), 0x5, + uint8_t(InternalInstruction::PUSH1), 0x6, + uint8_t(InternalInstruction::PUSH1), 0x7, + uint8_t(InternalInstruction::PUSH1), 0x8, + uint8_t(InternalInstruction::DUP9), + uint8_t(InternalInstruction::XOR), + uint8_t(InternalInstruction::AND), + uint8_t(InternalInstruction::OR), + uint8_t(InternalInstruction::SUB), + uint8_t(InternalInstruction::ADD), + uint8_t(InternalInstruction::DUP2), + uint8_t(InternalInstruction::ISZERO), + uint8_t(InternalInstruction::ISZERO), + uint8_t(InternalInstruction::PUSH1), 0x22, + uint8_t(InternalInstruction::JUMPI), + uint8_t(InternalInstruction::PUSH1), 0x21, + uint8_t(InternalInstruction::PUSH1), 0x36, + uint8_t(InternalInstruction::JUMP), + uint8_t(InternalInstruction::JUMPDEST), + uint8_t(InternalInstruction::JUMPDEST), + uint8_t(InternalInstruction::MOD), + uint8_t(InternalInstruction::DUP2), + uint8_t(InternalInstruction::ISZERO), + uint8_t(InternalInstruction::ISZERO), + uint8_t(InternalInstruction::PUSH1), 0x30, + uint8_t(InternalInstruction::JUMPI), + uint8_t(InternalInstruction::PUSH1), 0x2f, + uint8_t(InternalInstruction::PUSH1), 0x36, + uint8_t(InternalInstruction::JUMP), + uint8_t(InternalInstruction::JUMPDEST), + uint8_t(InternalInstruction::JUMPDEST), + uint8_t(InternalInstruction::DIV), + uint8_t(InternalInstruction::MUL), + uint8_t(InternalInstruction::PUSH1), 0x67, + uint8_t(InternalInstruction::JUMP) } + panic; BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end()); @@ -466,23 +466,23 @@ BOOST_AUTO_TEST_CASE(unary_operators) bytes expectation; if (solidity::test::CommonOptions::get().optimize) expectation = { - uint8_t(Instruction::DUP1), - uint8_t(Instruction::PUSH1), 0x0, - uint8_t(Instruction::SUB), - uint8_t(Instruction::NOT), - uint8_t(Instruction::PUSH1), 0x2, - uint8_t(Instruction::EQ), - uint8_t(Instruction::ISZERO) + uint8_t(InternalInstruction::DUP1), + uint8_t(InternalInstruction::PUSH1), 0x0, + uint8_t(InternalInstruction::SUB), + uint8_t(InternalInstruction::NOT), + uint8_t(InternalInstruction::PUSH1), 0x2, + uint8_t(InternalInstruction::EQ), + uint8_t(InternalInstruction::ISZERO) }; else expectation = { - uint8_t(Instruction::PUSH1), 0x2, - uint8_t(Instruction::DUP2), - uint8_t(Instruction::PUSH1), 0x0, - uint8_t(Instruction::SUB), - uint8_t(Instruction::NOT), - uint8_t(Instruction::EQ), - uint8_t(Instruction::ISZERO) + uint8_t(InternalInstruction::PUSH1), 0x2, + uint8_t(InternalInstruction::DUP2), + uint8_t(InternalInstruction::PUSH1), 0x0, + uint8_t(InternalInstruction::SUB), + uint8_t(InternalInstruction::NOT), + uint8_t(InternalInstruction::EQ), + uint8_t(InternalInstruction::ISZERO) }; BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end()); } @@ -498,47 +498,47 @@ BOOST_AUTO_TEST_CASE(unary_inc_dec) // Stack: a, x bytes expectation{ - uint8_t(Instruction::DUP2), - uint8_t(Instruction::DUP1), - uint8_t(Instruction::PUSH1), 0x1, - uint8_t(Instruction::ADD), + uint8_t(InternalInstruction::DUP2), + uint8_t(InternalInstruction::DUP1), + uint8_t(InternalInstruction::PUSH1), 0x1, + uint8_t(InternalInstruction::ADD), // Stack here: a x a (a+1) - uint8_t(Instruction::SWAP3), - uint8_t(Instruction::POP), // first ++ + uint8_t(InternalInstruction::SWAP3), + uint8_t(InternalInstruction::POP), // first ++ // Stack here: (a+1) x a - uint8_t(Instruction::DUP3), - uint8_t(Instruction::PUSH1), 0x1, - uint8_t(Instruction::ADD), + uint8_t(InternalInstruction::DUP3), + uint8_t(InternalInstruction::PUSH1), 0x1, + uint8_t(InternalInstruction::ADD), // Stack here: (a+1) x a (a+2) - uint8_t(Instruction::SWAP3), - uint8_t(Instruction::POP), + uint8_t(InternalInstruction::SWAP3), + uint8_t(InternalInstruction::POP), // Stack here: (a+2) x a - uint8_t(Instruction::DUP3), // second ++ - uint8_t(Instruction::XOR), + uint8_t(InternalInstruction::DUP3), // second ++ + uint8_t(InternalInstruction::XOR), // Stack here: (a+2) x a^(a+2) - uint8_t(Instruction::DUP3), - uint8_t(Instruction::DUP1), - uint8_t(Instruction::PUSH1), 0x1, - uint8_t(Instruction::SWAP1), - uint8_t(Instruction::SUB), + uint8_t(InternalInstruction::DUP3), + uint8_t(InternalInstruction::DUP1), + uint8_t(InternalInstruction::PUSH1), 0x1, + uint8_t(InternalInstruction::SWAP1), + uint8_t(InternalInstruction::SUB), // Stack here: (a+2) x a^(a+2) (a+2) (a+1) - uint8_t(Instruction::SWAP4), - uint8_t(Instruction::POP), // first -- - uint8_t(Instruction::XOR), + uint8_t(InternalInstruction::SWAP4), + uint8_t(InternalInstruction::POP), // first -- + uint8_t(InternalInstruction::XOR), // Stack here: (a+1) x a^(a+2)^(a+2) - uint8_t(Instruction::DUP3), - uint8_t(Instruction::PUSH1), 0x1, - uint8_t(Instruction::SWAP1), - uint8_t(Instruction::SUB), + uint8_t(InternalInstruction::DUP3), + uint8_t(InternalInstruction::PUSH1), 0x1, + uint8_t(InternalInstruction::SWAP1), + uint8_t(InternalInstruction::SUB), // Stack here: (a+1) x a^(a+2)^(a+2) a - uint8_t(Instruction::SWAP3), - uint8_t(Instruction::POP), // second ++ + uint8_t(InternalInstruction::SWAP3), + uint8_t(InternalInstruction::POP), // second ++ // Stack here: a x a^(a+2)^(a+2) - uint8_t(Instruction::DUP3), // will change - uint8_t(Instruction::XOR), - uint8_t(Instruction::SWAP1), - uint8_t(Instruction::POP), - uint8_t(Instruction::DUP1) + uint8_t(InternalInstruction::DUP3), // will change + uint8_t(InternalInstruction::XOR), + uint8_t(InternalInstruction::SWAP1), + uint8_t(InternalInstruction::POP), + uint8_t(InternalInstruction::DUP1) }; // Stack here: a x a^(a+2)^(a+2)^a BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end()); @@ -557,27 +557,27 @@ BOOST_AUTO_TEST_CASE(assignment) bytes expectation; if (solidity::test::CommonOptions::get().optimize) expectation = { - uint8_t(Instruction::DUP1), - uint8_t(Instruction::DUP3), - uint8_t(Instruction::ADD), - uint8_t(Instruction::SWAP2), - uint8_t(Instruction::POP), - uint8_t(Instruction::DUP2), - uint8_t(Instruction::PUSH1), 0x2, - uint8_t(Instruction::MUL) + uint8_t(InternalInstruction::DUP1), + uint8_t(InternalInstruction::DUP3), + uint8_t(InternalInstruction::ADD), + uint8_t(InternalInstruction::SWAP2), + uint8_t(InternalInstruction::POP), + uint8_t(InternalInstruction::DUP2), + uint8_t(InternalInstruction::PUSH1), 0x2, + uint8_t(InternalInstruction::MUL) }; else expectation = { - uint8_t(Instruction::PUSH1), 0x2, - uint8_t(Instruction::DUP2), - uint8_t(Instruction::DUP4), - uint8_t(Instruction::ADD), + uint8_t(InternalInstruction::PUSH1), 0x2, + uint8_t(InternalInstruction::DUP2), + uint8_t(InternalInstruction::DUP4), + uint8_t(InternalInstruction::ADD), // Stack here: a b 2 a+b - uint8_t(Instruction::SWAP3), - uint8_t(Instruction::POP), - uint8_t(Instruction::DUP3), + uint8_t(InternalInstruction::SWAP3), + uint8_t(InternalInstruction::POP), + uint8_t(InternalInstruction::DUP3), // Stack here: a+b b 2 a+b - uint8_t(Instruction::MUL) + uint8_t(InternalInstruction::MUL) }; BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end()); } @@ -591,7 +591,7 @@ BOOST_AUTO_TEST_CASE(negative_literals_8bits) )"; bytes code = compileFirstExpression(sourceCode); - bytes expectation(bytes({uint8_t(Instruction::PUSH32)}) + bytes(31, 0xff) + bytes(1, 0x80)); + bytes expectation(bytes({uint8_t(InternalInstruction::PUSH32)}) + bytes(31, 0xff) + bytes(1, 0x80)); BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end()); } @@ -604,7 +604,7 @@ BOOST_AUTO_TEST_CASE(negative_literals_16bits) )"; bytes code = compileFirstExpression(sourceCode); - bytes expectation(bytes({uint8_t(Instruction::PUSH32)}) + bytes(30, 0xff) + bytes{0xf5, 0x43}); + bytes expectation(bytes({uint8_t(InternalInstruction::PUSH32)}) + bytes(30, 0xff) + bytes{0xf5, 0x43}); BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end()); } @@ -619,7 +619,7 @@ BOOST_AUTO_TEST_CASE(intermediately_overflowing_literals) )"; bytes code = compileFirstExpression(sourceCode); - bytes expectation(bytes({uint8_t(Instruction::PUSH1), 0xbf})); + bytes expectation(bytes({uint8_t(InternalInstruction::PUSH1), 0xbf})); BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end()); } @@ -635,8 +635,8 @@ BOOST_AUTO_TEST_CASE(blockhash) bytes code = compileFirstExpression(sourceCode, {}, {}); - bytes expectation({uint8_t(Instruction::PUSH1), 0x03, - uint8_t(Instruction::BLOCKHASH)}); + bytes expectation({uint8_t(InternalInstruction::PUSH1), 0x03, + uint8_t(InternalInstruction::BLOCKHASH)}); BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end()); } @@ -651,7 +651,7 @@ BOOST_AUTO_TEST_CASE(gas_left) )"; bytes code = compileFirstExpression(sourceCode, {}, {}); - bytes expectation = bytes({uint8_t(Instruction::GAS)}); + bytes expectation = bytes({uint8_t(InternalInstruction::GAS)}); BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end()); } @@ -669,7 +669,7 @@ BOOST_AUTO_TEST_CASE(selfbalance) if (solidity::test::CommonOptions::get().evmVersion().hasSelfBalance()) { - bytes expectation({uint8_t(Instruction::SELFBALANCE)}); + bytes expectation({uint8_t(InternalInstruction::SELFBALANCE)}); BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end()); } } diff --git a/test/libsolidity/SolidityOptimizer.cpp b/test/libsolidity/SolidityOptimizer.cpp index a1580fb53..b14ff51f8 100644 --- a/test/libsolidity/SolidityOptimizer.cpp +++ b/test/libsolidity/SolidityOptimizer.cpp @@ -104,12 +104,12 @@ public: /// @returns the number of instructions in the given bytecode, not taking the metadata hash /// into account. - size_t numInstructions(bytes const& _bytecode, std::optional _which = std::optional{}) + size_t numInstructions(bytes const& _bytecode, std::optional _which = std::optional{}) { bytes realCode = bytecodeSansMetadata(_bytecode); BOOST_REQUIRE_MESSAGE(!realCode.empty(), "Invalid or missing metadata in bytecode."); size_t instructions = 0; - evmasm::eachInstruction(realCode, [&](Instruction _instr, u256 const&) { + evmasm::eachInstruction(realCode, langutil::EVMVersion(), [&](InternalInstruction _instr, u256 const&) { if (!_which || *_which == _instr) instructions++; }); @@ -287,8 +287,8 @@ BOOST_AUTO_TEST_CASE(retain_information_in_branches) bytes optimizedBytecode = compileAndRunWithOptimizer(sourceCode, 0, "c", true); size_t numSHA3s = 0; - eachInstruction(optimizedBytecode, [&](Instruction _instr, u256 const&) { - if (_instr == Instruction::KECCAK256) + eachInstruction(optimizedBytecode, langutil::EVMVersion(), [&](InternalInstruction _instr, u256 const&) { + if (_instr == InternalInstruction::KECCAK256) numSHA3s++; }); // TEST DISABLED - OPTIMIZER IS NOT EFFECTIVE ON THIS ONE ANYMORE @@ -330,8 +330,8 @@ BOOST_AUTO_TEST_CASE(store_tags_as_unions) bytes optimizedBytecode = compileAndRunWithOptimizer(sourceCode, 0, "test", true); size_t numSHA3s = 0; - eachInstruction(optimizedBytecode, [&](Instruction _instr, u256 const&) { - if (_instr == Instruction::KECCAK256) + eachInstruction(optimizedBytecode, langutil::EVMVersion(), [&](InternalInstruction _instr, u256 const&) { + if (_instr == InternalInstruction::KECCAK256) numSHA3s++; }); // TEST DISABLED UNTIL 93693404 IS IMPLEMENTED @@ -635,8 +635,8 @@ BOOST_AUTO_TEST_CASE(optimise_multi_stores) )"; compileBothVersions(sourceCode); compareVersions("f()"); - BOOST_CHECK_EQUAL(numInstructions(m_nonOptimizedBytecode, Instruction::SSTORE), 8); - BOOST_CHECK_EQUAL(numInstructions(m_optimizedBytecode, Instruction::SSTORE), 7); + BOOST_CHECK_EQUAL(numInstructions(m_nonOptimizedBytecode, InternalInstruction::SSTORE), 8); + BOOST_CHECK_EQUAL(numInstructions(m_optimizedBytecode, InternalInstruction::SSTORE), 7); } BOOST_AUTO_TEST_CASE(optimise_constant_to_codecopy) @@ -672,8 +672,8 @@ BOOST_AUTO_TEST_CASE(optimise_constant_to_codecopy) compareVersions("h()"); compareVersions("i()"); // This is counting in the deployed code. - BOOST_CHECK_EQUAL(numInstructions(m_nonOptimizedBytecode, Instruction::CODECOPY), 0); - BOOST_CHECK_EQUAL(numInstructions(m_optimizedBytecode, Instruction::CODECOPY), 4); + BOOST_CHECK_EQUAL(numInstructions(m_nonOptimizedBytecode, InternalInstruction::CODECOPY), 0); + BOOST_CHECK_EQUAL(numInstructions(m_optimizedBytecode, InternalInstruction::CODECOPY), 4); } BOOST_AUTO_TEST_CASE(byte_access) @@ -722,7 +722,7 @@ BOOST_AUTO_TEST_CASE(avoid_double_cleanup) )"; compileBothVersions(sourceCode, 0, "C", 50); // Check that there is no double AND instruction in the resulting code - BOOST_CHECK_EQUAL(numInstructions(m_nonOptimizedBytecode, Instruction::AND), 1); + BOOST_CHECK_EQUAL(numInstructions(m_nonOptimizedBytecode, InternalInstruction::AND), 1); } BOOST_AUTO_TEST_SUITE_END() diff --git a/test/tools/yulInterpreter/EVMInstructionInterpreter.cpp b/test/tools/yulInterpreter/EVMInstructionInterpreter.cpp index 0a3c920a5..0b0dc5323 100644 --- a/test/tools/yulInterpreter/EVMInstructionInterpreter.cpp +++ b/test/tools/yulInterpreter/EVMInstructionInterpreter.cpp @@ -87,12 +87,12 @@ void copyZeroExtended( using u512 = boost::multiprecision::number>; u256 EVMInstructionInterpreter::eval( - evmasm::Instruction _instruction, + evmasm::InternalInstruction _instruction, vector const& _arguments ) { using namespace solidity::evmasm; - using evmasm::Instruction; + using evmasm::InternalInstruction; auto info = instructionInfo(_instruction); yulAssert(static_cast(info.args) == _arguments.size(), ""); @@ -100,53 +100,53 @@ u256 EVMInstructionInterpreter::eval( auto const& arg = _arguments; switch (_instruction) { - case Instruction::STOP: + case InternalInstruction::STOP: logTrace(_instruction); BOOST_THROW_EXCEPTION(ExplicitlyTerminated()); // --------------- arithmetic --------------- - case Instruction::ADD: + case InternalInstruction::ADD: return arg[0] + arg[1]; - case Instruction::MUL: + case InternalInstruction::MUL: return arg[0] * arg[1]; - case Instruction::SUB: + case InternalInstruction::SUB: return arg[0] - arg[1]; - case Instruction::DIV: + case InternalInstruction::DIV: return arg[1] == 0 ? 0 : arg[0] / arg[1]; - case Instruction::SDIV: + case InternalInstruction::SDIV: return arg[1] == 0 ? 0 : s2u(u2s(arg[0]) / u2s(arg[1])); - case Instruction::MOD: + case InternalInstruction::MOD: return arg[1] == 0 ? 0 : arg[0] % arg[1]; - case Instruction::SMOD: + case InternalInstruction::SMOD: return arg[1] == 0 ? 0 : s2u(u2s(arg[0]) % u2s(arg[1])); - case Instruction::EXP: + case InternalInstruction::EXP: return exp256(arg[0], arg[1]); - case Instruction::NOT: + case InternalInstruction::NOT: return ~arg[0]; - case Instruction::LT: + case InternalInstruction::LT: return arg[0] < arg[1] ? 1 : 0; - case Instruction::GT: + case InternalInstruction::GT: return arg[0] > arg[1] ? 1 : 0; - case Instruction::SLT: + case InternalInstruction::SLT: return u2s(arg[0]) < u2s(arg[1]) ? 1 : 0; - case Instruction::SGT: + case InternalInstruction::SGT: return u2s(arg[0]) > u2s(arg[1]) ? 1 : 0; - case Instruction::EQ: + case InternalInstruction::EQ: return arg[0] == arg[1] ? 1 : 0; - case Instruction::ISZERO: + case InternalInstruction::ISZERO: return arg[0] == 0 ? 1 : 0; - case Instruction::AND: + case InternalInstruction::AND: return arg[0] & arg[1]; - case Instruction::OR: + case InternalInstruction::OR: return arg[0] | arg[1]; - case Instruction::XOR: + case InternalInstruction::XOR: return arg[0] ^ arg[1]; - case Instruction::BYTE: + case InternalInstruction::BYTE: return arg[0] >= 32 ? 0 : (arg[1] >> unsigned(8 * (31 - arg[0]))) & 0xff; - case Instruction::SHL: + case InternalInstruction::SHL: return arg[0] > 255 ? 0 : (arg[1] << unsigned(arg[0])); - case Instruction::SHR: + case InternalInstruction::SHR: return arg[0] > 255 ? 0 : (arg[1] >> unsigned(arg[0])); - case Instruction::SAR: + case InternalInstruction::SAR: { static u256 const hibit = u256(1) << 255; if (arg[0] >= 256) @@ -160,11 +160,11 @@ u256 EVMInstructionInterpreter::eval( return v; } } - case Instruction::ADDMOD: + case InternalInstruction::ADDMOD: return arg[2] == 0 ? 0 : u256((u512(arg[0]) + u512(arg[1])) % arg[2]); - case Instruction::MULMOD: + case InternalInstruction::MULMOD: return arg[2] == 0 ? 0 : u256((u512(arg[0]) * u512(arg[1])) % arg[2]); - case Instruction::SIGNEXTEND: + case InternalInstruction::SIGNEXTEND: if (arg[0] >= 31) return arg[1]; else @@ -179,7 +179,7 @@ u256 EVMInstructionInterpreter::eval( return ret; } // --------------- blockchain stuff --------------- - case Instruction::KECCAK256: + case InternalInstruction::KECCAK256: { if (!accessMemory(arg[0], arg[1])) return u256("0x1234cafe1234cafe1234cafe") + arg[0]; @@ -187,26 +187,26 @@ u256 EVMInstructionInterpreter::eval( uint64_t size = uint64_t(arg[1] & uint64_t(-1)); return u256(keccak256(readMemory(offset, size))); } - case Instruction::ADDRESS: + case InternalInstruction::ADDRESS: return h256(m_state.address, h256::AlignRight); - case Instruction::BALANCE: + case InternalInstruction::BALANCE: if (arg[0] == h256(m_state.address, h256::AlignRight)) return m_state.selfbalance; else return m_state.balance; - case Instruction::SELFBALANCE: + case InternalInstruction::SELFBALANCE: return m_state.selfbalance; - case Instruction::ORIGIN: + case InternalInstruction::ORIGIN: return h256(m_state.origin, h256::AlignRight); - case Instruction::CALLER: + case InternalInstruction::CALLER: return h256(m_state.caller, h256::AlignRight); - case Instruction::CALLVALUE: + case InternalInstruction::CALLVALUE: return m_state.callvalue; - case Instruction::CALLDATALOAD: + case InternalInstruction::CALLDATALOAD: return readZeroExtended(m_state.calldata, arg[0]); - case Instruction::CALLDATASIZE: + case InternalInstruction::CALLDATASIZE: return m_state.calldata.size(); - case Instruction::CALLDATACOPY: + case InternalInstruction::CALLDATACOPY: logTrace(_instruction, arg); if (accessMemory(arg[0], arg[2])) copyZeroExtended( @@ -214,9 +214,9 @@ u256 EVMInstructionInterpreter::eval( size_t(arg[0]), size_t(arg[1]), size_t(arg[2]) ); return 0; - case Instruction::CODESIZE: + case InternalInstruction::CODESIZE: return m_state.code.size(); - case Instruction::CODECOPY: + case InternalInstruction::CODECOPY: logTrace(_instruction, arg); if (accessMemory(arg[0], arg[2])) copyZeroExtended( @@ -224,17 +224,17 @@ u256 EVMInstructionInterpreter::eval( size_t(arg[0]), size_t(arg[1]), size_t(arg[2]) ); return 0; - case Instruction::GASPRICE: + case InternalInstruction::GASPRICE: return m_state.gasprice; - case Instruction::CHAINID: + case InternalInstruction::CHAINID: return m_state.chainid; - case Instruction::BASEFEE: + case InternalInstruction::BASEFEE: return m_state.basefee; - case Instruction::EXTCODESIZE: + case InternalInstruction::EXTCODESIZE: return u256(keccak256(h256(arg[0]))) & 0xffffff; - case Instruction::EXTCODEHASH: + case InternalInstruction::EXTCODEHASH: return u256(keccak256(h256(arg[0] + 1))); - case Instruction::EXTCODECOPY: + case InternalInstruction::EXTCODECOPY: logTrace(_instruction, arg); if (accessMemory(arg[1], arg[3])) // TODO this way extcodecopy and codecopy do the same thing. @@ -243,9 +243,9 @@ u256 EVMInstructionInterpreter::eval( size_t(arg[1]), size_t(arg[2]), size_t(arg[3]) ); return 0; - case Instruction::RETURNDATASIZE: + case InternalInstruction::RETURNDATASIZE: return m_state.returndata.size(); - case Instruction::RETURNDATACOPY: + case InternalInstruction::RETURNDATACOPY: logTrace(_instruction, arg); if (accessMemory(arg[0], arg[2])) copyZeroExtended( @@ -253,87 +253,89 @@ u256 EVMInstructionInterpreter::eval( size_t(arg[0]), size_t(arg[1]), size_t(arg[2]) ); return 0; - case Instruction::BLOCKHASH: + case InternalInstruction::BLOCKHASH: if (arg[0] >= m_state.blockNumber || arg[0] + 256 < m_state.blockNumber) return 0; else return 0xaaaaaaaa + (arg[0] - m_state.blockNumber - 256); - case Instruction::COINBASE: + case InternalInstruction::COINBASE: return h256(m_state.coinbase, h256::AlignRight); - case Instruction::TIMESTAMP: + case InternalInstruction::TIMESTAMP: return m_state.timestamp; - case Instruction::NUMBER: + case InternalInstruction::NUMBER: return m_state.blockNumber; - case Instruction::DIFFICULTY: + case InternalInstruction::DIFFICULTY: + // TODO should be properly implemented + case InternalInstruction::PREVRANDAO: return m_state.difficulty; - case Instruction::GASLIMIT: + case InternalInstruction::GASLIMIT: return m_state.gaslimit; // --------------- memory / storage / logs --------------- - case Instruction::MLOAD: + case InternalInstruction::MLOAD: accessMemory(arg[0], 0x20); return readMemoryWord(arg[0]); - case Instruction::MSTORE: + case InternalInstruction::MSTORE: accessMemory(arg[0], 0x20); writeMemoryWord(arg[0], arg[1]); return 0; - case Instruction::MSTORE8: + case InternalInstruction::MSTORE8: accessMemory(arg[0], 1); m_state.memory[arg[0]] = uint8_t(arg[1] & 0xff); return 0; - case Instruction::SLOAD: + case InternalInstruction::SLOAD: return m_state.storage[h256(arg[0])]; - case Instruction::SSTORE: + case InternalInstruction::SSTORE: m_state.storage[h256(arg[0])] = h256(arg[1]); return 0; - case Instruction::PC: + case InternalInstruction::PC: return 0x77; - case Instruction::MSIZE: + case InternalInstruction::MSIZE: return m_state.msize; - case Instruction::GAS: + case InternalInstruction::GAS: return 0x99; - case Instruction::LOG0: + case InternalInstruction::LOG0: accessMemory(arg[0], arg[1]); logTrace(_instruction, arg); return 0; - case Instruction::LOG1: + case InternalInstruction::LOG1: accessMemory(arg[0], arg[1]); logTrace(_instruction, arg); return 0; - case Instruction::LOG2: + case InternalInstruction::LOG2: accessMemory(arg[0], arg[1]); logTrace(_instruction, arg); return 0; - case Instruction::LOG3: + case InternalInstruction::LOG3: accessMemory(arg[0], arg[1]); logTrace(_instruction, arg); return 0; - case Instruction::LOG4: + case InternalInstruction::LOG4: accessMemory(arg[0], arg[1]); logTrace(_instruction, arg); return 0; // --------------- calls --------------- - case Instruction::CREATE: + case InternalInstruction::CREATE: accessMemory(arg[1], arg[2]); logTrace(_instruction, arg); return (0xcccccc + arg[1]) & u256("0xffffffffffffffffffffffffffffffffffffffff"); - case Instruction::CREATE2: + case InternalInstruction::CREATE2: accessMemory(arg[1], arg[2]); logTrace(_instruction, arg); return (0xdddddd + arg[1]) & u256("0xffffffffffffffffffffffffffffffffffffffff"); - case Instruction::CALL: - case Instruction::CALLCODE: + case InternalInstruction::CALL: + case InternalInstruction::CALLCODE: // TODO assign returndata accessMemory(arg[3], arg[4]); accessMemory(arg[5], arg[6]); logTrace(_instruction, arg); return arg[0] & 1; - case Instruction::DELEGATECALL: - case Instruction::STATICCALL: + case InternalInstruction::DELEGATECALL: + case InternalInstruction::STATICCALL: accessMemory(arg[2], arg[3]); accessMemory(arg[4], arg[5]); logTrace(_instruction, arg); return 0; - case Instruction::RETURN: + case InternalInstruction::RETURN: { bytes data; if (accessMemory(arg[0], arg[1])) @@ -341,92 +343,93 @@ u256 EVMInstructionInterpreter::eval( logTrace(_instruction, arg, data); BOOST_THROW_EXCEPTION(ExplicitlyTerminated()); } - case Instruction::REVERT: + case InternalInstruction::REVERT: accessMemory(arg[0], arg[1]); logTrace(_instruction, arg); m_state.storage.clear(); m_state.trace.clear(); BOOST_THROW_EXCEPTION(ExplicitlyTerminated()); - case Instruction::INVALID: + case InternalInstruction::INVALID: logTrace(_instruction); m_state.storage.clear(); m_state.trace.clear(); BOOST_THROW_EXCEPTION(ExplicitlyTerminated()); - case Instruction::SELFDESTRUCT: + case InternalInstruction::SELFDESTRUCT: logTrace(_instruction, arg); m_state.storage.clear(); m_state.trace.clear(); BOOST_THROW_EXCEPTION(ExplicitlyTerminated()); - case Instruction::POP: + case InternalInstruction::POP: break; // --------------- invalid in strict assembly --------------- - case Instruction::JUMP: - case Instruction::JUMPI: - case Instruction::JUMPDEST: - case Instruction::PUSH1: - case Instruction::PUSH2: - case Instruction::PUSH3: - case Instruction::PUSH4: - case Instruction::PUSH5: - case Instruction::PUSH6: - case Instruction::PUSH7: - case Instruction::PUSH8: - case Instruction::PUSH9: - case Instruction::PUSH10: - case Instruction::PUSH11: - case Instruction::PUSH12: - case Instruction::PUSH13: - case Instruction::PUSH14: - case Instruction::PUSH15: - case Instruction::PUSH16: - case Instruction::PUSH17: - case Instruction::PUSH18: - case Instruction::PUSH19: - case Instruction::PUSH20: - case Instruction::PUSH21: - case Instruction::PUSH22: - case Instruction::PUSH23: - case Instruction::PUSH24: - case Instruction::PUSH25: - case Instruction::PUSH26: - case Instruction::PUSH27: - case Instruction::PUSH28: - case Instruction::PUSH29: - case Instruction::PUSH30: - case Instruction::PUSH31: - case Instruction::PUSH32: - case Instruction::DUP1: - case Instruction::DUP2: - case Instruction::DUP3: - case Instruction::DUP4: - case Instruction::DUP5: - case Instruction::DUP6: - case Instruction::DUP7: - case Instruction::DUP8: - case Instruction::DUP9: - case Instruction::DUP10: - case Instruction::DUP11: - case Instruction::DUP12: - case Instruction::DUP13: - case Instruction::DUP14: - case Instruction::DUP15: - case Instruction::DUP16: - case Instruction::SWAP1: - case Instruction::SWAP2: - case Instruction::SWAP3: - case Instruction::SWAP4: - case Instruction::SWAP5: - case Instruction::SWAP6: - case Instruction::SWAP7: - case Instruction::SWAP8: - case Instruction::SWAP9: - case Instruction::SWAP10: - case Instruction::SWAP11: - case Instruction::SWAP12: - case Instruction::SWAP13: - case Instruction::SWAP14: - case Instruction::SWAP15: - case Instruction::SWAP16: + case InternalInstruction::JUMP: + case InternalInstruction::JUMPI: + case InternalInstruction::JUMPDEST: + case InternalInstruction::PUSH1: + case InternalInstruction::PUSH2: + case InternalInstruction::PUSH3: + case InternalInstruction::PUSH4: + case InternalInstruction::PUSH5: + case InternalInstruction::PUSH6: + case InternalInstruction::PUSH7: + case InternalInstruction::PUSH8: + case InternalInstruction::PUSH9: + case InternalInstruction::PUSH10: + case InternalInstruction::PUSH11: + case InternalInstruction::PUSH12: + case InternalInstruction::PUSH13: + case InternalInstruction::PUSH14: + case InternalInstruction::PUSH15: + case InternalInstruction::PUSH16: + case InternalInstruction::PUSH17: + case InternalInstruction::PUSH18: + case InternalInstruction::PUSH19: + case InternalInstruction::PUSH20: + case InternalInstruction::PUSH21: + case InternalInstruction::PUSH22: + case InternalInstruction::PUSH23: + case InternalInstruction::PUSH24: + case InternalInstruction::PUSH25: + case InternalInstruction::PUSH26: + case InternalInstruction::PUSH27: + case InternalInstruction::PUSH28: + case InternalInstruction::PUSH29: + case InternalInstruction::PUSH30: + case InternalInstruction::PUSH31: + case InternalInstruction::PUSH32: + case InternalInstruction::DUP1: + case InternalInstruction::DUP2: + case InternalInstruction::DUP3: + case InternalInstruction::DUP4: + case InternalInstruction::DUP5: + case InternalInstruction::DUP6: + case InternalInstruction::DUP7: + case InternalInstruction::DUP8: + case InternalInstruction::DUP9: + case InternalInstruction::DUP10: + case InternalInstruction::DUP11: + case InternalInstruction::DUP12: + case InternalInstruction::DUP13: + case InternalInstruction::DUP14: + case InternalInstruction::DUP15: + case InternalInstruction::DUP16: + case InternalInstruction::SWAP1: + case InternalInstruction::SWAP2: + case InternalInstruction::SWAP3: + case InternalInstruction::SWAP4: + case InternalInstruction::SWAP5: + case InternalInstruction::SWAP6: + case InternalInstruction::SWAP7: + case InternalInstruction::SWAP8: + case InternalInstruction::SWAP9: + case InternalInstruction::SWAP10: + case InternalInstruction::SWAP11: + case InternalInstruction::SWAP12: + case InternalInstruction::SWAP13: + case InternalInstruction::SWAP14: + case InternalInstruction::SWAP15: + case InternalInstruction::SWAP16: + case InternalInstruction::MAX_INTERNAL_INSTRUCTION: { yulAssert(false, ""); return 0; @@ -519,7 +522,7 @@ void EVMInstructionInterpreter::writeMemoryWord(u256 const& _offset, u256 const& void EVMInstructionInterpreter::logTrace( - evmasm::Instruction _instruction, + evmasm::InternalInstruction _instruction, std::vector const& _arguments, bytes const& _data ) diff --git a/test/tools/yulInterpreter/EVMInstructionInterpreter.h b/test/tools/yulInterpreter/EVMInstructionInterpreter.h index c05af8c1a..87ed9fe7d 100644 --- a/test/tools/yulInterpreter/EVMInstructionInterpreter.h +++ b/test/tools/yulInterpreter/EVMInstructionInterpreter.h @@ -30,7 +30,7 @@ namespace solidity::evmasm { -enum class Instruction: uint8_t; +enum class InternalInstruction: uint8_t; } namespace solidity::yul @@ -71,7 +71,7 @@ public: m_disableMemoryWriteInstructions(_disableMemWriteTrace) {} /// Evaluate instruction - u256 eval(evmasm::Instruction _instruction, std::vector const& _arguments); + u256 eval(evmasm::InternalInstruction _instruction, std::vector const& _arguments); /// Evaluate builtin function u256 evalBuiltin( BuiltinFunctionForEVM const& _fun, @@ -95,7 +95,7 @@ private: void writeMemoryWord(u256 const& _offset, u256 const& _value); void logTrace( - evmasm::Instruction _instruction, + evmasm::InternalInstruction _instruction, std::vector const& _arguments = {}, bytes const& _data = {} ); diff --git a/test/tools/yulInterpreter/EwasmBuiltinInterpreter.cpp b/test/tools/yulInterpreter/EwasmBuiltinInterpreter.cpp index 36f51b11c..de2a6faca 100644 --- a/test/tools/yulInterpreter/EwasmBuiltinInterpreter.cpp +++ b/test/tools/yulInterpreter/EwasmBuiltinInterpreter.cpp @@ -180,7 +180,7 @@ u256 EwasmBuiltinInterpreter::evalBuiltin( return arg.at(0) & uint32_t(-1); else if (fun == "unreachable") { - logTrace(evmasm::Instruction::INVALID, {}); + logTrace(evmasm::InternalInstruction::INVALID, {}); BOOST_THROW_EXCEPTION(ExplicitlyTerminated()); } else if (fun == "i64.store") @@ -334,7 +334,7 @@ u256 EwasmBuiltinInterpreter::evalEthBuiltin(string const& _fun, vector const& _arguments, bytes const& _data) +void EwasmBuiltinInterpreter::logTrace(evmasm::InternalInstruction _instruction, std::vector const& _arguments, bytes const& _data) { logTrace(evmasm::instructionInfo(_instruction).name, _arguments, _data); } diff --git a/test/tools/yulInterpreter/EwasmBuiltinInterpreter.h b/test/tools/yulInterpreter/EwasmBuiltinInterpreter.h index 1837f7509..153bc5162 100644 --- a/test/tools/yulInterpreter/EwasmBuiltinInterpreter.h +++ b/test/tools/yulInterpreter/EwasmBuiltinInterpreter.h @@ -30,7 +30,7 @@ namespace solidity::evmasm { -enum class Instruction: uint8_t; +enum class InternalInstruction: uint8_t; } namespace solidity::yul @@ -127,7 +127,7 @@ private: util::h256 readBytes32(uint64_t _offset) { accessMemory(_offset, 32); return util::h256(readMemory(_offset, 32)); } util::h160 readAddress(uint64_t _offset) { accessMemory(_offset, 20); return util::h160(readMemory(_offset, 20)); } - void logTrace(evmasm::Instruction _instruction, std::vector const& _arguments = {}, bytes const& _data = {}); + void logTrace(evmasm::InternalInstruction _instruction, std::vector const& _arguments = {}, bytes const& _data = {}); /// Appends a log to the trace representing an instruction or similar operation by string, /// with arguments and auxiliary data (if nonempty). void logTrace(std::string const& _pseudoInstruction, std::vector const& _arguments = {}, bytes const& _data = {});