Skip to content

Commit 8e6729d

Browse files
committed
ethdebug: correct handling of interfaces.
1 parent fbbe2dd commit 8e6729d

File tree

5 files changed

+48
-45
lines changed

5 files changed

+48
-45
lines changed

libevmasm/Ethdebug.cpp

+42-39
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ using namespace solidity::evmasm::ethdebug;
2525
namespace
2626
{
2727

28-
Json programInstructions(Assembly const* _assembly, LinkerObject const& _linkerObject, unsigned _sourceId)
28+
Json programInstructions(Assembly const* _assembly, LinkerObject const* _linkerObject, unsigned _sourceId)
2929
{
3030
// e.g. interfaces don't have a valid assembly object.
3131
if (_assembly)
@@ -36,53 +36,56 @@ Json programInstructions(Assembly const* _assembly, LinkerObject const& _linkerO
3636
solUnimplementedAssert(instruction.type() != VerbatimBytecode, "Verbatim bytecode is currently not supported by ethdebug.");
3737
}
3838

39-
solAssert(_linkerObject.codeSectionLocations.size() == 1);
40-
solAssert(_linkerObject.codeSectionLocations[0].end <= _linkerObject.bytecode.size());
41-
Json instructions = Json::array();
42-
for (size_t i = 0; i < _linkerObject.codeSectionLocations[0].instructionLocations.size(); ++i)
39+
if (_linkerObject)
4340
{
44-
solAssert(_assembly);
45-
LinkerObject::InstructionLocation currentInstruction = _linkerObject.codeSectionLocations[0].instructionLocations[i];
46-
size_t start = currentInstruction.start;
47-
size_t end = currentInstruction.end;
48-
size_t assemblyItemIndex = currentInstruction.assemblyItemIndex;
49-
solAssert(end <= _linkerObject.bytecode.size());
50-
solAssert(start < end);
51-
solAssert(assemblyItemIndex < _assembly->codeSections().at(0).items.size());
52-
Json operation = Json::object();
53-
operation["mnemonic"] = instructionInfo(static_cast<Instruction>(_linkerObject.bytecode[start]), _assembly->evmVersion()).name;
54-
static size_t constexpr instructionSize = 1;
55-
if (start + instructionSize < end)
41+
solAssert(_linkerObject->codeSectionLocations.size() == 1);
42+
solAssert(_linkerObject->codeSectionLocations[0].end <= _linkerObject->bytecode.size());
43+
Json instructions = Json::array();
44+
for (size_t i = 0; i < _linkerObject->codeSectionLocations[0].instructionLocations.size(); ++i)
5645
{
57-
bytes const argumentData(
58-
_linkerObject.bytecode.begin() + static_cast<std::ptrdiff_t>(start) + instructionSize,
59-
_linkerObject.bytecode.begin() + static_cast<std::ptrdiff_t>(end)
60-
);
61-
solAssert(!argumentData.empty());
62-
operation["arguments"] = Json::array({util::toHex(argumentData, util::HexPrefix::Add)});
63-
}
64-
langutil::SourceLocation const& location = _assembly->codeSections().at(0).items.at(assemblyItemIndex).location();
65-
Json instruction = Json::object();
66-
instruction["offset"] = start;
67-
instruction["operation"] = operation;
46+
solAssert(_assembly);
47+
LinkerObject::InstructionLocation currentInstruction = _linkerObject->codeSectionLocations[0].instructionLocations[i];
48+
size_t start = currentInstruction.start;
49+
size_t end = currentInstruction.end;
50+
size_t assemblyItemIndex = currentInstruction.assemblyItemIndex;
51+
solAssert(end <= _linkerObject->bytecode.size());
52+
solAssert(start < end);
53+
solAssert(assemblyItemIndex < _assembly->codeSections().at(0).items.size());
54+
Json operation = Json::object();
55+
operation["mnemonic"] = instructionInfo(static_cast<Instruction>(_linkerObject->bytecode[start]), _assembly->evmVersion()).name;
56+
static size_t constexpr instructionSize = 1;
57+
if (start + instructionSize < end)
58+
{
59+
bytes const argumentData(
60+
_linkerObject->bytecode.begin() + static_cast<std::ptrdiff_t>(start) + instructionSize,
61+
_linkerObject->bytecode.begin() + static_cast<std::ptrdiff_t>(end)
62+
);
63+
solAssert(!argumentData.empty());
64+
operation["arguments"] = Json::array({util::toHex(argumentData, util::HexPrefix::Add)});
65+
}
66+
langutil::SourceLocation const& location = _assembly->codeSections().at(0).items.at(assemblyItemIndex).location();
67+
Json instruction = Json::object();
68+
instruction["offset"] = start;
69+
instruction["operation"] = operation;
6870

69-
instruction["context"] = Json::object();
70-
instruction["context"]["code"] = Json::object();
71-
instruction["context"]["code"]["source"] = Json::object();
72-
instruction["context"]["code"]["source"]["id"] = static_cast<int>(_sourceId);
71+
instruction["context"] = Json::object();
72+
instruction["context"]["code"] = Json::object();
73+
instruction["context"]["code"]["source"] = Json::object();
74+
instruction["context"]["code"]["source"]["id"] = static_cast<int>(_sourceId);
7375

74-
instruction["context"]["code"]["range"] = Json::object();
75-
instruction["context"]["code"]["range"]["offset"] = location.start;
76-
instruction["context"]["code"]["range"]["length"] = location.end - location.start;
77-
instructions.emplace_back(instruction);
76+
instruction["context"]["code"]["range"] = Json::object();
77+
instruction["context"]["code"]["range"]["offset"] = location.start;
78+
instruction["context"]["code"]["range"]["length"] = location.end - location.start;
79+
instructions.emplace_back(instruction);
80+
}
81+
return instructions;
7882
}
79-
80-
return instructions;
83+
return Json::array();
8184
}
8285

8386
} // anonymous namespace
8487

85-
Json ethdebug::program(std::string_view _name, unsigned _sourceId, Assembly const* _assembly, LinkerObject const& _linkerObject)
88+
Json ethdebug::program(std::string_view _name, unsigned _sourceId, Assembly const* _assembly, LinkerObject const* _linkerObject)
8689
{
8790
Json result = Json::object();
8891
result["contract"] = Json::object();

libevmasm/Ethdebug.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ namespace solidity::evmasm::ethdebug
2727
{
2828

2929
// returns ethdebug/format/program.
30-
Json program(std::string_view _name, unsigned _sourceId, Assembly const* _assembly, LinkerObject const& _linkerObject);
30+
Json program(std::string_view _name, unsigned _sourceId, Assembly const* _assembly, LinkerObject const* _linkerObject);
3131

3232
// returns ethdebug/format/info/resources
3333
Json resources(std::vector<std::string> const& _sources, std::string const& _version);

libsolidity/interface/CompilerStack.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -1217,7 +1217,7 @@ Json CompilerStack::ethdebug(Contract const& _contract, bool _runtime) const
12171217
evmasm::LinkerObject const& object = _runtime ? _contract.runtimeObject : _contract.object;
12181218
std::shared_ptr<evmasm::Assembly> const& assembly = _runtime ? _contract.evmRuntimeAssembly : _contract.evmAssembly;
12191219
solAssert(sourceIndices().contains(_contract.contract->sourceUnitName()));
1220-
return evmasm::ethdebug::program(_contract.contract->name(), sourceIndices()[_contract.contract->sourceUnitName()], assembly.get(), object);
1220+
return evmasm::ethdebug::program(_contract.contract->name(), sourceIndices()[_contract.contract->sourceUnitName()], assembly.get(), &object);
12211221
}
12221222

12231223
bytes CompilerStack::cborMetadata(std::string const& _contractName, bool _forIR) const

libyul/YulStack.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -275,14 +275,14 @@ YulStack::assembleWithDeployed(std::optional<std::string_view> _deployName)
275275
);
276276
}
277277
if (debugInfoSelection().ethdebug)
278-
creationObject.ethdebug = evmasm::ethdebug::program(creationObject.assembly->name(), 0, creationObject.assembly.get(), *creationObject.bytecode.get());
278+
creationObject.ethdebug = evmasm::ethdebug::program(creationObject.assembly->name(), 0, creationObject.assembly.get(), creationObject.bytecode.get());
279279

280280
if (deployedAssembly)
281281
{
282282
deployedObject.bytecode = std::make_shared<evmasm::LinkerObject>(deployedAssembly->assemble());
283283
deployedObject.assembly = deployedAssembly;
284284
if (debugInfoSelection().ethdebug)
285-
deployedObject.ethdebug = evmasm::ethdebug::program(deployedObject.assembly->name(), 0, deployedObject.assembly.get(), *deployedObject.bytecode.get());
285+
deployedObject.ethdebug = evmasm::ethdebug::program(deployedObject.assembly->name(), 0, deployedObject.assembly.get(), deployedObject.bytecode.get());
286286
solAssert(deployedAssembly->codeSections().size() == 1);
287287
deployedObject.sourceMappings = std::make_unique<std::string>(
288288
evmasm::AssemblyItem::computeSourceMapping(

test/libevmasm/Assembler.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -434,7 +434,7 @@ BOOST_AUTO_TEST_CASE(ethdebug_program_last_instruction_with_immediate_arguments)
434434
assembly.append(AssemblyItem{0x11223344});
435435
LinkerObject output = assembly.assemble();
436436

437-
Json const program = ethdebug::program("", 0, &assembly, output);
437+
Json const program = ethdebug::program("", 0, &assembly, &output);
438438
BOOST_REQUIRE(program["instructions"].size() == 1);
439439
BOOST_REQUIRE(program["instructions"][0]["operation"]["mnemonic"] == "PUSH4");
440440
BOOST_REQUIRE(program["instructions"][0]["operation"]["arguments"][0] == "0x11223344");
@@ -445,7 +445,7 @@ BOOST_AUTO_TEST_CASE(ethdebug_program_last_instruction_with_immediate_arguments)
445445
assembly.append(AssemblyItem{0x1122334455});
446446
LinkerObject output = assembly.assemble();
447447

448-
Json const program = ethdebug::program("", 0, &assembly, output);
448+
Json const program = ethdebug::program("", 0, &assembly, &output);
449449
BOOST_REQUIRE(program["instructions"].size() == 2);
450450
BOOST_REQUIRE(program["instructions"][0]["operation"]["mnemonic"] == "PUSH0");
451451
BOOST_REQUIRE(!program["instructions"][0]["operation"].contains("arguments"));

0 commit comments

Comments
 (0)