From 6634b9ee9e558789d5673df6ba2f712eb1f10412 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Thu, 28 Nov 2024 23:35:58 +0100 Subject: [PATCH 1/2] Replace InvalidDeposit exception with assertions - We never actually catch it so it's already de facto handled like a failed assert, just with worse diagnostics. --- libevmasm/Assembly.h | 4 ++-- libevmasm/Exceptions.h | 1 - libevmasm/KnownState.cpp | 4 ++-- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/libevmasm/Assembly.h b/libevmasm/Assembly.h index 4b52ca3d7970..f2da01e22f9a 100644 --- a/libevmasm/Assembly.h +++ b/libevmasm/Assembly.h @@ -127,8 +127,8 @@ class Assembly void appendToAuxiliaryData(bytes const& _data) { m_auxiliaryData += _data; } int deposit() const { return m_deposit; } - void adjustDeposit(int _adjustment) { m_deposit += _adjustment; assertThrow(m_deposit >= 0, InvalidDeposit, ""); } - void setDeposit(int _deposit) { m_deposit = _deposit; assertThrow(m_deposit >= 0, InvalidDeposit, ""); } + void adjustDeposit(int _adjustment) { m_deposit += _adjustment; solAssert(m_deposit >= 0); } + void setDeposit(int _deposit) { m_deposit = _deposit; solAssert(m_deposit >= 0); } std::string const& name() const { return m_name; } /// Changes the source location used for each appended item. diff --git a/libevmasm/Exceptions.h b/libevmasm/Exceptions.h index ae6d1bf9c617..032ed4411aca 100644 --- a/libevmasm/Exceptions.h +++ b/libevmasm/Exceptions.h @@ -33,7 +33,6 @@ struct OptimizerException: virtual AssemblyException {}; struct StackTooDeepException: virtual OptimizerException {}; struct ItemNotAvailableException: virtual OptimizerException {}; -DEV_SIMPLE_EXCEPTION(InvalidDeposit); DEV_SIMPLE_EXCEPTION(InvalidOpcode); } diff --git a/libevmasm/KnownState.cpp b/libevmasm/KnownState.cpp index 3878ae0fdd75..66553bc06633 100644 --- a/libevmasm/KnownState.cpp +++ b/libevmasm/KnownState.cpp @@ -120,7 +120,7 @@ KnownState::StoreOperation KnownState::feedItem(AssemblyItem const& _item, bool } else if (_item.type() != Operation) { - assertThrow(_item.deposit() == 1, InvalidDeposit, ""); + solAssert(_item.deposit() == 1); if (_item.pushedValue()) // only available after assembly stage, should not be used for optimisation setStackElement(++m_stackHeight, m_expressionClasses->find(*_item.pushedValue())); @@ -194,7 +194,7 @@ KnownState::StoreOperation KnownState::feedItem(AssemblyItem const& _item, bool resetStorage(); if (invMem || invStor) m_sequenceNumber += 2; // Increment by two because it can read and write - assertThrow(info.ret <= 1, InvalidDeposit, ""); + solAssert(info.ret <= 1); if (info.ret == 1) setStackElement( m_stackHeight + static_cast(_item.deposit()), From c127395fabcf87605693829132de30501aa8e21e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Fri, 29 Nov 2024 02:17:14 +0100 Subject: [PATCH 2/2] Replace InvalidOpcode exception with AssemblyImportException and asserts - The only case where it needs to be an exception is assembly import. In other situations we don't catch it so it's effectively an assert. --- libevmasm/Assembly.cpp | 6 +++--- libevmasm/Exceptions.h | 2 -- libevmasm/Instruction.h | 9 +++++---- libsolidity/interface/StandardCompiler.cpp | 4 ---- .../standard_import_asm_json_invalid_opcode/output.json | 4 ++-- 5 files changed, 10 insertions(+), 15 deletions(-) diff --git a/libevmasm/Assembly.cpp b/libevmasm/Assembly.cpp index fdc27241550b..5bf8e25082e9 100644 --- a/libevmasm/Assembly.cpp +++ b/libevmasm/Assembly.cpp @@ -281,7 +281,7 @@ AssemblyItem Assembly::createAssemblyItemFromJSON(Json const& _json, std::vector result = item; } else - solThrow(InvalidOpcode, "Invalid opcode: " + name); + solThrow(AssemblyImportException, "Invalid opcode (" + name + ")"); } result.setLocation(location); result.m_modifierDepth = modifierDepth; @@ -1236,7 +1236,7 @@ LinkerObject const& Assembly::assembleLegacy() const ret.bytecode += assembleTag(item, ret.bytecode.size(), true); break; default: - assertThrow(false, InvalidOpcode, "Unexpected opcode while assembling."); + solAssert(false, "Unexpected opcode while assembling."); } } @@ -1469,7 +1469,7 @@ LinkerObject const& Assembly::assembleEOF() const break; } default: - solThrow(InvalidOpcode, "Unexpected opcode while assembling."); + solAssert(false, "Unexpected opcode while assembling."); } } diff --git a/libevmasm/Exceptions.h b/libevmasm/Exceptions.h index 032ed4411aca..c9d0633e4c2c 100644 --- a/libevmasm/Exceptions.h +++ b/libevmasm/Exceptions.h @@ -33,6 +33,4 @@ struct OptimizerException: virtual AssemblyException {}; struct StackTooDeepException: virtual OptimizerException {}; struct ItemNotAvailableException: virtual OptimizerException {}; -DEV_SIMPLE_EXCEPTION(InvalidOpcode); - } diff --git a/libevmasm/Instruction.h b/libevmasm/Instruction.h index 76998c538d5f..84c6e34e6272 100644 --- a/libevmasm/Instruction.h +++ b/libevmasm/Instruction.h @@ -26,6 +26,7 @@ #include #include #include +#include namespace solidity::evmasm { @@ -267,28 +268,28 @@ inline unsigned getLogNumber(Instruction _inst) /// @returns the PUSH<_number> instruction inline Instruction pushInstruction(unsigned _number) { - assertThrow(_number <= 32, InvalidOpcode, std::string("Invalid PUSH instruction requested (") + std::to_string(_number) + ")."); + solAssert(_number <= 32); return Instruction(unsigned(Instruction::PUSH0) + _number); } /// @returns the DUP<_number> instruction inline Instruction dupInstruction(unsigned _number) { - assertThrow(1 <= _number && _number <= 16, InvalidOpcode, std::string("Invalid DUP instruction requested (") + std::to_string(_number) + ")."); + solAssert(1 <= _number && _number <= 16); return Instruction(unsigned(Instruction::DUP1) + _number - 1); } /// @returns the SWAP<_number> instruction inline Instruction swapInstruction(unsigned _number) { - assertThrow(1 <= _number && _number <= 16, InvalidOpcode, std::string("Invalid SWAP instruction requested (") + std::to_string(_number) + ")."); + solAssert(1 <= _number && _number <= 16); return Instruction(unsigned(Instruction::SWAP1) + _number - 1); } /// @returns the LOG<_number> instruction inline Instruction logInstruction(unsigned _number) { - assertThrow(_number <= 4, InvalidOpcode, std::string("Invalid LOG instruction requested (") + std::to_string(_number) + ")."); + solAssert(_number <= 4); return Instruction(unsigned(Instruction::LOG0) + _number); } diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index c5248e42e2f4..351a17b897d6 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -1220,10 +1220,6 @@ Json StandardCompiler::importEVMAssembly(StandardCompiler::InputsAndSettings _in { return formatFatalError(Error::Type::Exception, "Assembly import error: " + std::string(e.what())); } - catch (evmasm::InvalidOpcode const& e) - { - return formatFatalError(Error::Type::Exception, "Assembly import error: " + std::string(e.what())); - } catch (...) { return formatError( diff --git a/test/cmdlineTests/standard_import_asm_json_invalid_opcode/output.json b/test/cmdlineTests/standard_import_asm_json_invalid_opcode/output.json index cccd241d9416..14e502301f20 100644 --- a/test/cmdlineTests/standard_import_asm_json_invalid_opcode/output.json +++ b/test/cmdlineTests/standard_import_asm_json_invalid_opcode/output.json @@ -2,8 +2,8 @@ "errors": [ { "component": "general", - "formattedMessage": "Assembly import error: InvalidOpcode", - "message": "Assembly import error: InvalidOpcode", + "formattedMessage": "Assembly import error: Invalid opcode (INVALID_OPCODE)", + "message": "Assembly import error: Invalid opcode (INVALID_OPCODE)", "severity": "error", "type": "Exception" }