mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Debug information for immutable references.
This commit is contained in:
parent
8451639f17
commit
81652686be
@ -530,7 +530,7 @@ LinkerObject const& Assembly::assemble() const
|
||||
LinkerObject& ret = m_assembledObject;
|
||||
|
||||
size_t subTagSize = 1;
|
||||
map<u256, vector<size_t>> immutableReferencesBySub;
|
||||
map<u256, pair<string, vector<size_t>>> immutableReferencesBySub;
|
||||
for (auto const& sub: m_subs)
|
||||
{
|
||||
auto const& linkerObject = sub->assemble();
|
||||
@ -554,7 +554,7 @@ LinkerObject const& Assembly::assemble() const
|
||||
for (auto const& i: m_items)
|
||||
if (i.type() == AssignImmutable)
|
||||
{
|
||||
i.setImmutableOccurrences(immutableReferencesBySub[i.data()].size());
|
||||
i.setImmutableOccurrences(immutableReferencesBySub[i.data()].second.size());
|
||||
setsImmutables = true;
|
||||
}
|
||||
else if (i.type() == PushImmutable)
|
||||
@ -660,11 +660,12 @@ LinkerObject const& Assembly::assemble() const
|
||||
break;
|
||||
case PushImmutable:
|
||||
ret.bytecode.push_back(uint8_t(Instruction::PUSH32));
|
||||
ret.immutableReferences[i.data()].emplace_back(ret.bytecode.size());
|
||||
ret.immutableReferences[i.data()].first = m_immutables.at(i.data());
|
||||
ret.immutableReferences[i.data()].second.emplace_back(ret.bytecode.size());
|
||||
ret.bytecode.resize(ret.bytecode.size() + 32);
|
||||
break;
|
||||
case AssignImmutable:
|
||||
for (auto const& offset: immutableReferencesBySub[i.data()])
|
||||
for (auto const& offset: immutableReferencesBySub[i.data()].second)
|
||||
{
|
||||
ret.bytecode.push_back(uint8_t(Instruction::DUP1));
|
||||
// TODO: should we make use of the constant optimizer methods for pushing the offsets?
|
||||
|
@ -40,9 +40,9 @@ struct LinkerObject
|
||||
/// need to be replaced by the actual addresses by the linker.
|
||||
std::map<size_t, std::string> linkReferences;
|
||||
|
||||
/// Map from hashes of the identifiers of immutable variables to a list of offsets into the bytecode
|
||||
/// that refer to their values.
|
||||
std::map<u256, std::vector<size_t>> immutableReferences;
|
||||
/// Map from hashes of the identifiers of immutable variables to the full identifier of the immutable and
|
||||
/// to a list of offsets into the bytecode that refer to their values.
|
||||
std::map<u256, std::pair<std::string, std::vector<size_t>>> immutableReferences;
|
||||
|
||||
/// Appends the bytecode of @a _other and incorporates its link references.
|
||||
void append(LinkerObject const& _other);
|
||||
|
@ -90,13 +90,7 @@ size_t CompilerContext::immutableMemoryOffset(VariableDeclaration const& _variab
|
||||
|
||||
vector<string> CompilerContext::immutableVariableSlotNames(VariableDeclaration const& _variable)
|
||||
{
|
||||
string baseName =
|
||||
_variable.annotation().contract->fullyQualifiedName() +
|
||||
"." +
|
||||
_variable.name() +
|
||||
" (" +
|
||||
to_string(_variable.id()) +
|
||||
")";
|
||||
string baseName = to_string(_variable.id());
|
||||
solAssert(_variable.annotation().type->sizeOnStack() > 0, "");
|
||||
if (_variable.annotation().type->sizeOnStack() == 1)
|
||||
return {baseName};
|
||||
|
@ -234,6 +234,7 @@ bool isBinaryRequested(Json::Value const& _outputSelection)
|
||||
"wast", "wasm", "ewasm.wast", "ewasm.wasm",
|
||||
"evm.deployedBytecode", "evm.deployedBytecode.object", "evm.deployedBytecode.opcodes",
|
||||
"evm.deployedBytecode.sourceMap", "evm.deployedBytecode.linkReferences",
|
||||
"evm.deployedBytecode.immutableReferences",
|
||||
"evm.bytecode", "evm.bytecode.object", "evm.bytecode.opcodes", "evm.bytecode.sourceMap",
|
||||
"evm.bytecode.linkReferences",
|
||||
"evm.gasEstimates", "evm.legacyAssembly", "evm.assembly"
|
||||
@ -309,13 +310,36 @@ Json::Value formatLinkReferences(std::map<size_t, std::string> const& linkRefere
|
||||
return ret;
|
||||
}
|
||||
|
||||
Json::Value collectEVMObject(evmasm::LinkerObject const& _object, string const* _sourceMap)
|
||||
Json::Value formatImmutableReferences(map<u256, pair<string, vector<size_t>>> const& _immutableReferences)
|
||||
{
|
||||
Json::Value ret(Json::objectValue);
|
||||
|
||||
for (auto const& immutableReference: _immutableReferences)
|
||||
{
|
||||
auto const& [identifier, byteOffsets] = immutableReference.second;
|
||||
Json::Value array(Json::arrayValue);
|
||||
for (size_t byteOffset: byteOffsets)
|
||||
{
|
||||
Json::Value byteRange(Json::arrayValue);
|
||||
byteRange.append(Json::UInt(byteOffset));
|
||||
byteRange.append(Json::UInt(32)); // immutable references are currently always 32 bytes wide
|
||||
array.append(byteRange);
|
||||
}
|
||||
ret[identifier] = array;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
Json::Value collectEVMObject(evmasm::LinkerObject const& _object, string const* _sourceMap, bool _runtimeObject)
|
||||
{
|
||||
Json::Value output = Json::objectValue;
|
||||
output["object"] = _object.toHex();
|
||||
output["opcodes"] = evmasm::disassemble(_object.bytecode);
|
||||
output["sourceMap"] = _sourceMap ? *_sourceMap : "";
|
||||
output["linkReferences"] = formatLinkReferences(_object.linkReferences);
|
||||
if (_runtimeObject)
|
||||
output["immutableReferences"] = formatImmutableReferences(_object.immutableReferences);
|
||||
return output;
|
||||
}
|
||||
|
||||
@ -982,19 +1006,21 @@ Json::Value StandardCompiler::compileSolidity(StandardCompiler::InputsAndSetting
|
||||
))
|
||||
evmData["bytecode"] = collectEVMObject(
|
||||
compilerStack.object(contractName),
|
||||
compilerStack.sourceMapping(contractName)
|
||||
compilerStack.sourceMapping(contractName),
|
||||
false
|
||||
);
|
||||
|
||||
if (compilationSuccess && isArtifactRequested(
|
||||
_inputsAndSettings.outputSelection,
|
||||
file,
|
||||
name,
|
||||
{ "evm.deployedBytecode", "evm.deployedBytecode.object", "evm.deployedBytecode.opcodes", "evm.deployedBytecode.sourceMap", "evm.deployedBytecode.linkReferences" },
|
||||
{ "evm.deployedBytecode", "evm.deployedBytecode.object", "evm.deployedBytecode.opcodes", "evm.deployedBytecode.sourceMap", "evm.deployedBytecode.linkReferences", "evm.deployedBytecode.immutableReferences" },
|
||||
wildcardMatchesExperimental
|
||||
))
|
||||
evmData["deployedBytecode"] = collectEVMObject(
|
||||
compilerStack.runtimeObject(contractName),
|
||||
compilerStack.runtimeSourceMapping(contractName)
|
||||
compilerStack.runtimeSourceMapping(contractName),
|
||||
true
|
||||
);
|
||||
|
||||
if (!evmData.empty())
|
||||
@ -1081,7 +1107,7 @@ Json::Value StandardCompiler::compileYul(InputsAndSettings _inputsAndSettings)
|
||||
{ "evm.bytecode", "evm.bytecode.object", "evm.bytecode.opcodes", "evm.bytecode.sourceMap", "evm.bytecode.linkReferences" },
|
||||
wildcardMatchesExperimental
|
||||
))
|
||||
output["contracts"][sourceName][contractName]["evm"]["bytecode"] = collectEVMObject(*object.bytecode, object.sourceMappings.get());
|
||||
output["contracts"][sourceName][contractName]["evm"]["bytecode"] = collectEVMObject(*object.bytecode, object.sourceMappings.get(), false);
|
||||
|
||||
if (isArtifactRequested(_inputsAndSettings.outputSelection, sourceName, contractName, "irOptimized", wildcardMatchesExperimental))
|
||||
output["contracts"][sourceName][contractName]["irOptimized"] = stack.print();
|
||||
|
18
test/cmdlineTests/standard_immutable_references/input.json
Normal file
18
test/cmdlineTests/standard_immutable_references/input.json
Normal file
@ -0,0 +1,18 @@
|
||||
{
|
||||
"language": "Solidity",
|
||||
"sources": {
|
||||
"a.sol": {
|
||||
"content": "contract A { uint256 immutable x = 1; function f() public view returns (uint256) { return x; } }"
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"evmVersion": "petersburg",
|
||||
"outputSelection": {
|
||||
"*": {
|
||||
"A": [
|
||||
"evm.deployedBytecode.immutableReferences"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,2 @@
|
||||
{"contracts":{"a.sol":{"A":{"evm":{"deployedBytecode":{"immutableReferences":{"3":[[77,32]]},"linkReferences":{},"object":"bytecode removed","opcodes":"opcodes removed","sourceMap":"0:96:0:-:0;;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;0:96:0;;;;;;;;;;;;;;;;12:1:-1;9;2:12;38:56:0;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;72:7;90:1;83:8;;38:56;:::o"}}}}},"errors":[{"component":"general","formattedMessage":"a.sol: Warning: Source file does not specify required compiler version!
|
||||
","message":"Source file does not specify required compiler version!","severity":"warning","sourceLocation":{"end":-1,"file":"a.sol","start":-1},"type":"Warning"}],"sources":{"a.sol":{"id":0}}}
|
Loading…
Reference in New Issue
Block a user