mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Use AbstractAssemblyStack in CommandLineInterface
This commit is contained in:
parent
f1528e166a
commit
f94a800b9d
@ -43,9 +43,9 @@
|
|||||||
|
|
||||||
#include <libyul/YulStack.h>
|
#include <libyul/YulStack.h>
|
||||||
|
|
||||||
#include <libevmasm/Instruction.h>
|
|
||||||
#include <libevmasm/Disassemble.h>
|
#include <libevmasm/Disassemble.h>
|
||||||
#include <libevmasm/GasMeter.h>
|
#include <libevmasm/GasMeter.h>
|
||||||
|
#include <libevmasm/Instruction.h>
|
||||||
|
|
||||||
#include <liblangutil/Exceptions.h>
|
#include <liblangutil/Exceptions.h>
|
||||||
#include <liblangutil/SourceReferenceFormatter.h>
|
#include <liblangutil/SourceReferenceFormatter.h>
|
||||||
@ -171,18 +171,19 @@ static bool coloredOutput(CommandLineOptions const& _options)
|
|||||||
void CommandLineInterface::handleEVMAssembly(string const& _contract)
|
void CommandLineInterface::handleEVMAssembly(string const& _contract)
|
||||||
{
|
{
|
||||||
solAssert(CompilerInputModes.count(m_options.input.mode) == 1);
|
solAssert(CompilerInputModes.count(m_options.input.mode) == 1);
|
||||||
|
solAssert(m_assemblyStack);
|
||||||
|
|
||||||
if (m_options.compiler.outputs.asm_ || m_options.compiler.outputs.asmJson)
|
if (m_options.compiler.outputs.asm_ || m_options.compiler.outputs.asmJson)
|
||||||
{
|
{
|
||||||
string assembly;
|
string assembly;
|
||||||
if (m_options.compiler.outputs.asmJson)
|
if (m_options.compiler.outputs.asmJson)
|
||||||
assembly = util::jsonPrint(removeNullMembers(m_compiler->assemblyJSON(_contract)), m_options.formatting.json);
|
assembly = util::jsonPrint(removeNullMembers(m_assemblyStack->assemblyJSON(_contract)), m_options.formatting.json);
|
||||||
else
|
else
|
||||||
assembly = m_compiler->assemblyString(_contract, m_fileReader.sourceUnits());
|
assembly = m_assemblyStack->assemblyString(_contract, m_fileReader.sourceUnits());
|
||||||
|
|
||||||
if (!m_options.output.dir.empty())
|
if (!m_options.output.dir.empty())
|
||||||
createFile(
|
createFile(
|
||||||
m_compiler->filesystemFriendlyName(_contract) +
|
m_assemblyStack->filesystemFriendlyName(_contract) +
|
||||||
(m_options.compiler.outputs.asmJson ? "_evm.json" : ".evm"),
|
(m_options.compiler.outputs.asmJson ? "_evm.json" : ".evm"),
|
||||||
assembly
|
assembly
|
||||||
);
|
);
|
||||||
@ -194,18 +195,19 @@ void CommandLineInterface::handleEVMAssembly(string const& _contract)
|
|||||||
void CommandLineInterface::handleBinary(string const& _contract)
|
void CommandLineInterface::handleBinary(string const& _contract)
|
||||||
{
|
{
|
||||||
solAssert(CompilerInputModes.count(m_options.input.mode) == 1);
|
solAssert(CompilerInputModes.count(m_options.input.mode) == 1);
|
||||||
|
solAssert(m_assemblyStack);
|
||||||
|
|
||||||
string binary;
|
string binary;
|
||||||
string binaryRuntime;
|
string binaryRuntime;
|
||||||
if (m_options.compiler.outputs.binary)
|
if (m_options.compiler.outputs.binary)
|
||||||
binary = objectWithLinkRefsHex(m_compiler->object(_contract));
|
binary = objectWithLinkRefsHex(m_assemblyStack->object(_contract));
|
||||||
if (m_options.compiler.outputs.binaryRuntime)
|
if (m_options.compiler.outputs.binaryRuntime)
|
||||||
binaryRuntime = objectWithLinkRefsHex(m_compiler->runtimeObject(_contract));
|
binaryRuntime = objectWithLinkRefsHex(m_assemblyStack->runtimeObject(_contract));
|
||||||
|
|
||||||
if (m_options.compiler.outputs.binary)
|
if (m_options.compiler.outputs.binary)
|
||||||
{
|
{
|
||||||
if (!m_options.output.dir.empty())
|
if (!m_options.output.dir.empty())
|
||||||
createFile(m_compiler->filesystemFriendlyName(_contract) + ".bin", binary);
|
createFile(m_assemblyStack->filesystemFriendlyName(_contract) + ".bin", binary);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sout() << "Binary:" << endl;
|
sout() << "Binary:" << endl;
|
||||||
@ -215,7 +217,7 @@ void CommandLineInterface::handleBinary(string const& _contract)
|
|||||||
if (m_options.compiler.outputs.binaryRuntime)
|
if (m_options.compiler.outputs.binaryRuntime)
|
||||||
{
|
{
|
||||||
if (!m_options.output.dir.empty())
|
if (!m_options.output.dir.empty())
|
||||||
createFile(m_compiler->filesystemFriendlyName(_contract) + ".bin-runtime", binaryRuntime);
|
createFile(m_assemblyStack->filesystemFriendlyName(_contract) + ".bin-runtime", binaryRuntime);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sout() << "Binary of the runtime part:" << endl;
|
sout() << "Binary of the runtime part:" << endl;
|
||||||
@ -227,11 +229,12 @@ void CommandLineInterface::handleBinary(string const& _contract)
|
|||||||
void CommandLineInterface::handleOpcode(string const& _contract)
|
void CommandLineInterface::handleOpcode(string const& _contract)
|
||||||
{
|
{
|
||||||
solAssert(CompilerInputModes.count(m_options.input.mode) == 1);
|
solAssert(CompilerInputModes.count(m_options.input.mode) == 1);
|
||||||
|
solAssert(m_assemblyStack);
|
||||||
|
|
||||||
string opcodes{evmasm::disassemble(m_compiler->object(_contract).bytecode, m_options.output.evmVersion)};
|
string opcodes{evmasm::disassemble(m_assemblyStack->object(_contract).bytecode, m_options.output.evmVersion)};
|
||||||
|
|
||||||
if (!m_options.output.dir.empty())
|
if (!m_options.output.dir.empty())
|
||||||
createFile(m_compiler->filesystemFriendlyName(_contract) + ".opcode", opcodes);
|
createFile(m_assemblyStack->filesystemFriendlyName(_contract) + ".opcode", opcodes);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sout() << "Opcodes:" << endl;
|
sout() << "Opcodes:" << endl;
|
||||||
@ -708,8 +711,10 @@ void CommandLineInterface::processInput()
|
|||||||
case InputMode::EVMAssemblerJSON:
|
case InputMode::EVMAssemblerJSON:
|
||||||
assembleFromEvmAssemblyJson();
|
assembleFromEvmAssemblyJson();
|
||||||
handleCombinedJSON();
|
handleCombinedJSON();
|
||||||
handleBytecode("");
|
|
||||||
handleEVMAssembly("");
|
solAssert(m_evmAssemblyStack);
|
||||||
|
handleBytecode(m_evmAssemblyStack->name());
|
||||||
|
handleEVMAssembly(m_evmAssemblyStack->name());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -730,19 +735,38 @@ void CommandLineInterface::printLicense()
|
|||||||
void CommandLineInterface::assembleFromEvmAssemblyJson()
|
void CommandLineInterface::assembleFromEvmAssemblyJson()
|
||||||
{
|
{
|
||||||
solAssert(m_options.input.mode == InputMode::EVMAssemblerJSON);
|
solAssert(m_options.input.mode == InputMode::EVMAssemblerJSON);
|
||||||
solAssert(m_compiler == nullptr);
|
solAssert(!m_assemblyStack);
|
||||||
|
solAssert(!m_evmAssemblyStack && !m_compiler);
|
||||||
|
|
||||||
|
bool importSuccessful = false;
|
||||||
|
unique_ptr<evmasm::EVMAssemblyStack> evmAssemblyStack;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
solAssert(m_fileReader.sourceUnits().size() == 1);
|
solAssert(m_fileReader.sourceUnits().size() == 1);
|
||||||
auto&& [sourceUnitName, source] = *m_fileReader.sourceUnits().begin();
|
auto&& [sourceUnitName, source] = *m_fileReader.sourceUnits().begin();
|
||||||
m_compiler = make_unique<CompilerStack>(m_universalCallback.callback());
|
|
||||||
m_compiler->importFromEVMAssemblyStack(sourceUnitName, source);
|
evmAssemblyStack = make_unique<evmasm::EVMAssemblyStack>(m_options.output.evmVersion);
|
||||||
|
if (m_options.output.debugInfoSelection.has_value())
|
||||||
|
evmAssemblyStack->selectDebugInfo(m_options.output.debugInfoSelection.value());
|
||||||
|
|
||||||
|
// TODO: Why does it report errors both with exceptions and with an error code?
|
||||||
|
// It should always throw when the operation is not successful.
|
||||||
|
importSuccessful = evmAssemblyStack->parseAndAnalyze(sourceUnitName, source);
|
||||||
}
|
}
|
||||||
catch (evmasm::AssemblyImportException const& _exception)
|
catch (evmasm::AssemblyImportException const& _exception)
|
||||||
{
|
{
|
||||||
solThrow(CommandLineExecutionError, "Assembly Import Error: "s + _exception.what());
|
solThrow(CommandLineExecutionError, "Assembly Import Error: "s + _exception.what());
|
||||||
}
|
}
|
||||||
solRequire(m_compiler != nullptr, CommandLineExecutionError, "Assembly Import Error: Could not create compiler object.");
|
|
||||||
|
if (importSuccessful)
|
||||||
|
{
|
||||||
|
evmAssemblyStack->assemble();
|
||||||
|
m_evmAssemblyStack = std::move(evmAssemblyStack);
|
||||||
|
m_assemblyStack = m_evmAssemblyStack.get();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
solThrow(CommandLineExecutionError, "Assembly Import Error: Could not create compiler object.");
|
||||||
}
|
}
|
||||||
|
|
||||||
void CommandLineInterface::compile()
|
void CommandLineInterface::compile()
|
||||||
@ -750,6 +774,7 @@ void CommandLineInterface::compile()
|
|||||||
solAssert(CompilerInputModes.count(m_options.input.mode) == 1);
|
solAssert(CompilerInputModes.count(m_options.input.mode) == 1);
|
||||||
|
|
||||||
m_compiler = make_unique<CompilerStack>(m_universalCallback.callback());
|
m_compiler = make_unique<CompilerStack>(m_universalCallback.callback());
|
||||||
|
m_assemblyStack = m_compiler.get();
|
||||||
|
|
||||||
SourceReferenceFormatter formatter(serr(false), *m_compiler, coloredOutput(m_options), m_options.formatting.withErrorIds);
|
SourceReferenceFormatter formatter(serr(false), *m_compiler, coloredOutput(m_options), m_options.formatting.withErrorIds);
|
||||||
|
|
||||||
@ -860,6 +885,7 @@ void CommandLineInterface::compile()
|
|||||||
void CommandLineInterface::handleCombinedJSON()
|
void CommandLineInterface::handleCombinedJSON()
|
||||||
{
|
{
|
||||||
solAssert(CompilerInputModes.count(m_options.input.mode) == 1);
|
solAssert(CompilerInputModes.count(m_options.input.mode) == 1);
|
||||||
|
solAssert(m_assemblyStack);
|
||||||
|
|
||||||
if (!m_options.compiler.combinedJsonRequests.has_value())
|
if (!m_options.compiler.combinedJsonRequests.has_value())
|
||||||
return;
|
return;
|
||||||
@ -867,7 +893,7 @@ void CommandLineInterface::handleCombinedJSON()
|
|||||||
Json::Value output(Json::objectValue);
|
Json::Value output(Json::objectValue);
|
||||||
|
|
||||||
output[g_strVersion] = frontend::VersionString;
|
output[g_strVersion] = frontend::VersionString;
|
||||||
vector<string> contracts = m_compiler->contractNames();
|
vector<string> contracts = m_assemblyStack->contractNames();
|
||||||
|
|
||||||
if (!contracts.empty())
|
if (!contracts.empty())
|
||||||
output[g_strContracts] = Json::Value(Json::objectValue);
|
output[g_strContracts] = Json::Value(Json::objectValue);
|
||||||
@ -878,37 +904,37 @@ void CommandLineInterface::handleCombinedJSON()
|
|||||||
contractData[g_strAbi] = m_compiler->contractABI(contractName);
|
contractData[g_strAbi] = m_compiler->contractABI(contractName);
|
||||||
if (m_options.compiler.combinedJsonRequests->metadata)
|
if (m_options.compiler.combinedJsonRequests->metadata)
|
||||||
contractData["metadata"] = m_compiler->metadata(contractName);
|
contractData["metadata"] = m_compiler->metadata(contractName);
|
||||||
if (m_options.compiler.combinedJsonRequests->binary && m_compiler->compilationSuccessful())
|
if (m_options.compiler.combinedJsonRequests->binary && m_assemblyStack->compilationSuccessful())
|
||||||
contractData[g_strBinary] = m_compiler->object(contractName).toHex();
|
contractData[g_strBinary] = m_assemblyStack->object(contractName).toHex();
|
||||||
if (m_options.compiler.combinedJsonRequests->binaryRuntime && m_compiler->compilationSuccessful())
|
if (m_options.compiler.combinedJsonRequests->binaryRuntime && m_assemblyStack->compilationSuccessful())
|
||||||
contractData[g_strBinaryRuntime] = m_compiler->runtimeObject(contractName).toHex();
|
contractData[g_strBinaryRuntime] = m_assemblyStack->runtimeObject(contractName).toHex();
|
||||||
if (m_options.compiler.combinedJsonRequests->opcodes && m_compiler->compilationSuccessful())
|
if (m_options.compiler.combinedJsonRequests->opcodes && m_assemblyStack->compilationSuccessful())
|
||||||
contractData[g_strOpcodes] = evmasm::disassemble(m_compiler->object(contractName).bytecode, m_options.output.evmVersion);
|
contractData[g_strOpcodes] = evmasm::disassemble(m_assemblyStack->object(contractName).bytecode, m_options.output.evmVersion);
|
||||||
if (m_options.compiler.combinedJsonRequests->asm_ && m_compiler->compilationSuccessful())
|
if (m_options.compiler.combinedJsonRequests->asm_ && m_assemblyStack->compilationSuccessful())
|
||||||
contractData[g_strAsm] = m_compiler->assemblyJSON(contractName);
|
contractData[g_strAsm] = m_assemblyStack->assemblyJSON(contractName);
|
||||||
if (m_options.compiler.combinedJsonRequests->storageLayout && m_compiler->compilationSuccessful())
|
if (m_options.compiler.combinedJsonRequests->storageLayout && m_assemblyStack->compilationSuccessful())
|
||||||
contractData[g_strStorageLayout] = m_compiler->storageLayout(contractName);
|
contractData[g_strStorageLayout] = m_compiler->storageLayout(contractName);
|
||||||
if (m_options.compiler.combinedJsonRequests->generatedSources && m_compiler->compilationSuccessful())
|
if (m_options.compiler.combinedJsonRequests->generatedSources && m_assemblyStack->compilationSuccessful())
|
||||||
contractData[g_strGeneratedSources] = m_compiler->generatedSources(contractName, false);
|
contractData[g_strGeneratedSources] = m_compiler->generatedSources(contractName, false);
|
||||||
if (m_options.compiler.combinedJsonRequests->generatedSourcesRuntime && m_compiler->compilationSuccessful())
|
if (m_options.compiler.combinedJsonRequests->generatedSourcesRuntime && m_assemblyStack->compilationSuccessful())
|
||||||
contractData[g_strGeneratedSourcesRuntime] = m_compiler->generatedSources(contractName, true);
|
contractData[g_strGeneratedSourcesRuntime] = m_compiler->generatedSources(contractName, true);
|
||||||
if (m_options.compiler.combinedJsonRequests->srcMap && m_compiler->compilationSuccessful())
|
if (m_options.compiler.combinedJsonRequests->srcMap && m_assemblyStack->compilationSuccessful())
|
||||||
{
|
{
|
||||||
auto map = m_compiler->sourceMapping(contractName);
|
auto map = m_assemblyStack->sourceMapping(contractName);
|
||||||
contractData[g_strSrcMap] = map ? *map : "";
|
contractData[g_strSrcMap] = map ? *map : "";
|
||||||
}
|
}
|
||||||
if (m_options.compiler.combinedJsonRequests->srcMapRuntime && m_compiler->compilationSuccessful())
|
if (m_options.compiler.combinedJsonRequests->srcMapRuntime && m_assemblyStack->compilationSuccessful())
|
||||||
{
|
{
|
||||||
auto map = m_compiler->runtimeSourceMapping(contractName);
|
auto map = m_assemblyStack->runtimeSourceMapping(contractName);
|
||||||
contractData[g_strSrcMapRuntime] = map ? *map : "";
|
contractData[g_strSrcMapRuntime] = map ? *map : "";
|
||||||
}
|
}
|
||||||
if (m_options.compiler.combinedJsonRequests->funDebug && m_compiler->compilationSuccessful())
|
if (m_options.compiler.combinedJsonRequests->funDebug && m_assemblyStack->compilationSuccessful())
|
||||||
contractData[g_strFunDebug] = StandardCompiler::formatFunctionDebugData(
|
contractData[g_strFunDebug] = StandardCompiler::formatFunctionDebugData(
|
||||||
m_compiler->object(contractName).functionDebugData
|
m_assemblyStack->object(contractName).functionDebugData
|
||||||
);
|
);
|
||||||
if (m_options.compiler.combinedJsonRequests->funDebugRuntime && m_compiler->compilationSuccessful())
|
if (m_options.compiler.combinedJsonRequests->funDebugRuntime && m_assemblyStack->compilationSuccessful())
|
||||||
contractData[g_strFunDebugRuntime] = StandardCompiler::formatFunctionDebugData(
|
contractData[g_strFunDebugRuntime] = StandardCompiler::formatFunctionDebugData(
|
||||||
m_compiler->runtimeObject(contractName).functionDebugData
|
m_assemblyStack->runtimeObject(contractName).functionDebugData
|
||||||
);
|
);
|
||||||
if (m_options.compiler.combinedJsonRequests->signatureHashes)
|
if (m_options.compiler.combinedJsonRequests->signatureHashes)
|
||||||
contractData[g_strSignatureHashes] = m_compiler->interfaceSymbols(contractName)["methods"];
|
contractData[g_strSignatureHashes] = m_compiler->interfaceSymbols(contractName)["methods"];
|
||||||
@ -926,7 +952,7 @@ void CommandLineInterface::handleCombinedJSON()
|
|||||||
// Indices into this array are used to abbreviate source names in source locations.
|
// Indices into this array are used to abbreviate source names in source locations.
|
||||||
output[g_strSourceList] = Json::Value(Json::arrayValue);
|
output[g_strSourceList] = Json::Value(Json::arrayValue);
|
||||||
|
|
||||||
for (auto const& source: m_compiler->sourceNames())
|
for (auto const& source: m_assemblyStack->sourceNames())
|
||||||
output[g_strSourceList].append(source);
|
output[g_strSourceList].append(source);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -935,6 +961,7 @@ void CommandLineInterface::handleCombinedJSON()
|
|||||||
output[g_strSources] = Json::Value(Json::objectValue);
|
output[g_strSources] = Json::Value(Json::objectValue);
|
||||||
for (auto const& sourceCode: m_fileReader.sourceUnits())
|
for (auto const& sourceCode: m_fileReader.sourceUnits())
|
||||||
{
|
{
|
||||||
|
solAssert(m_compiler);
|
||||||
ASTJsonExporter converter(m_compiler->state(), m_compiler->sourceIndices());
|
ASTJsonExporter converter(m_compiler->state(), m_compiler->sourceIndices());
|
||||||
output[g_strSources][sourceCode.first] = Json::Value(Json::objectValue);
|
output[g_strSources][sourceCode.first] = Json::Value(Json::objectValue);
|
||||||
output[g_strSources][sourceCode.first]["AST"] = converter.toJson(m_compiler->ast(sourceCode.first));
|
output[g_strSources][sourceCode.first]["AST"] = converter.toJson(m_compiler->ast(sourceCode.first));
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
|
|
||||||
#include <solc/CommandLineParser.h>
|
#include <solc/CommandLineParser.h>
|
||||||
|
|
||||||
|
#include <libevmasm/AbstractAssemblyStack.h>
|
||||||
#include <libevmasm/EVMAssemblyStack.h>
|
#include <libevmasm/EVMAssemblyStack.h>
|
||||||
#include <libsolidity/interface/CompilerStack.h>
|
#include <libsolidity/interface/CompilerStack.h>
|
||||||
#include <libsolidity/interface/DebugSettings.h>
|
#include <libsolidity/interface/DebugSettings.h>
|
||||||
@ -147,6 +148,8 @@ private:
|
|||||||
UniversalCallback m_universalCallback{m_fileReader, m_solverCommand};
|
UniversalCallback m_universalCallback{m_fileReader, m_solverCommand};
|
||||||
std::optional<std::string> m_standardJsonInput;
|
std::optional<std::string> m_standardJsonInput;
|
||||||
std::unique_ptr<frontend::CompilerStack> m_compiler;
|
std::unique_ptr<frontend::CompilerStack> m_compiler;
|
||||||
|
std::unique_ptr<evmasm::EVMAssemblyStack> m_evmAssemblyStack;
|
||||||
|
evmasm::AbstractAssemblyStack* m_assemblyStack = nullptr;
|
||||||
CommandLineOptions m_options;
|
CommandLineOptions m_options;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user