mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Remove error reporter from code generation phase.
This commit is contained in:
parent
19f707aeaa
commit
ef3d5874fe
@ -73,14 +73,14 @@ void CodeTransform::operator()(Assignment const& _assignment)
|
||||
{
|
||||
visitExpression(*_assignment.value);
|
||||
m_assembly.setSourceLocation(_assignment.location);
|
||||
generateAssignment(_assignment.variableName, _assignment.location);
|
||||
generateAssignment(_assignment.variableName);
|
||||
checkStackHeight(&_assignment);
|
||||
}
|
||||
|
||||
void CodeTransform::operator()(StackAssignment const& _assignment)
|
||||
{
|
||||
m_assembly.setSourceLocation(_assignment.location);
|
||||
generateAssignment(_assignment.variableName, _assignment.location);
|
||||
generateAssignment(_assignment.variableName);
|
||||
checkStackHeight(&_assignment);
|
||||
}
|
||||
|
||||
@ -172,7 +172,7 @@ void CodeTransform::operator()(assembly::Identifier const& _identifier)
|
||||
if (m_scope->lookup(_identifier.name, Scope::NonconstVisitor(
|
||||
[=](Scope::Variable& _var)
|
||||
{
|
||||
if (int heightDiff = variableHeightDiff(_var, _identifier.location, false))
|
||||
if (int heightDiff = variableHeightDiff(_var, false))
|
||||
m_assembly.appendInstruction(solidity::dupInstruction(heightDiff));
|
||||
else
|
||||
// Store something to balance the stack
|
||||
@ -320,7 +320,7 @@ void CodeTransform::operator()(FunctionDefinition const& _function)
|
||||
m_assembly.appendConstant(u256(0));
|
||||
}
|
||||
|
||||
CodeTransform(m_errorReporter, m_assembly, m_info, m_evm15, m_identifierAccess, localStackAdjustment)
|
||||
CodeTransform(m_assembly, m_info, m_evm15, m_identifierAccess, localStackAdjustment)
|
||||
.run(_function.body);
|
||||
|
||||
{
|
||||
@ -366,7 +366,7 @@ void CodeTransform::operator()(FunctionDefinition const& _function)
|
||||
|
||||
void CodeTransform::operator()(Block const& _block)
|
||||
{
|
||||
CodeTransform(m_errorReporter, m_assembly, m_info, m_evm15, m_identifierAccess, m_stackAdjustment).run(_block);
|
||||
CodeTransform(m_assembly, m_info, m_evm15, m_identifierAccess, m_stackAdjustment).run(_block);
|
||||
}
|
||||
|
||||
AbstractAssembly::LabelID CodeTransform::labelFromIdentifier(Identifier const& _identifier)
|
||||
@ -394,14 +394,14 @@ void CodeTransform::visitExpression(Statement const& _expression)
|
||||
expectDeposit(1, height);
|
||||
}
|
||||
|
||||
void CodeTransform::generateAssignment(Identifier const& _variableName, SourceLocation const& _location)
|
||||
void CodeTransform::generateAssignment(Identifier const& _variableName)
|
||||
{
|
||||
solAssert(m_scope, "");
|
||||
auto var = m_scope->lookup(_variableName.name);
|
||||
if (var)
|
||||
{
|
||||
Scope::Variable const& _var = boost::get<Scope::Variable>(*var);
|
||||
if (int heightDiff = variableHeightDiff(_var, _location, true))
|
||||
if (int heightDiff = variableHeightDiff(_var, true))
|
||||
m_assembly.appendInstruction(solidity::swapInstruction(heightDiff - 1));
|
||||
m_assembly.appendInstruction(solidity::Instruction::POP);
|
||||
}
|
||||
@ -415,14 +415,12 @@ void CodeTransform::generateAssignment(Identifier const& _variableName, SourceLo
|
||||
}
|
||||
}
|
||||
|
||||
int CodeTransform::variableHeightDiff(solidity::assembly::Scope::Variable const& _var, SourceLocation const& _location, bool _forSwap)
|
||||
int CodeTransform::variableHeightDiff(solidity::assembly::Scope::Variable const& _var, bool _forSwap)
|
||||
{
|
||||
int heightDiff = m_assembly.stackHeight() - _var.stackHeight;
|
||||
if (heightDiff <= (_forSwap ? 1 : 0) || heightDiff > (_forSwap ? 17 : 16))
|
||||
{
|
||||
//@TODO move this to analysis phase.
|
||||
m_errorReporter.typeError(
|
||||
_location,
|
||||
solUnimplemented(
|
||||
"Variable inaccessible, too deep inside stack (" + boost::lexical_cast<string>(heightDiff) + ")"
|
||||
);
|
||||
return 0;
|
||||
|
@ -61,12 +61,11 @@ public:
|
||||
/// Create the code transformer.
|
||||
/// @param _identifierAccess used to resolve identifiers external to the inline assembly
|
||||
CodeTransform(
|
||||
solidity::ErrorReporter& _errorReporter,
|
||||
julia::AbstractAssembly& _assembly,
|
||||
solidity::assembly::AsmAnalysisInfo& _analysisInfo,
|
||||
bool _evm15 = false,
|
||||
ExternalIdentifierAccess const& _identifierAccess = ExternalIdentifierAccess()
|
||||
): CodeTransform(_errorReporter, _assembly, _analysisInfo, _evm15, _identifierAccess, _assembly.stackHeight())
|
||||
): CodeTransform(_assembly, _analysisInfo, _evm15, _identifierAccess, _assembly.stackHeight())
|
||||
{
|
||||
}
|
||||
|
||||
@ -75,14 +74,12 @@ public:
|
||||
|
||||
protected:
|
||||
CodeTransform(
|
||||
solidity::ErrorReporter& _errorReporter,
|
||||
julia::AbstractAssembly& _assembly,
|
||||
solidity::assembly::AsmAnalysisInfo& _analysisInfo,
|
||||
bool _evm15,
|
||||
ExternalIdentifierAccess const& _identifierAccess,
|
||||
int _stackAdjustment
|
||||
):
|
||||
m_errorReporter(_errorReporter),
|
||||
m_assembly(_assembly),
|
||||
m_info(_analysisInfo),
|
||||
m_evm15(_evm15),
|
||||
@ -109,12 +106,12 @@ private:
|
||||
/// Generates code for an expression that is supposed to return a single value.
|
||||
void visitExpression(solidity::assembly::Statement const& _expression);
|
||||
|
||||
void generateAssignment(solidity::assembly::Identifier const& _variableName, SourceLocation const& _location);
|
||||
void generateAssignment(solidity::assembly::Identifier const& _variableName);
|
||||
|
||||
/// Determines the stack height difference to the given variables. Automatically generates
|
||||
/// errors if it is not yet in scope or the height difference is too large. Returns 0 on
|
||||
/// errors and the (positive) stack height difference otherwise.
|
||||
int variableHeightDiff(solidity::assembly::Scope::Variable const& _var, SourceLocation const& _location, bool _forSwap);
|
||||
/// Determines the stack height difference to the given variables. Throws
|
||||
/// if it is not yet in scope or the height difference is too large. Returns
|
||||
/// the (positive) stack height difference otherwise.
|
||||
int variableHeightDiff(solidity::assembly::Scope::Variable const& _var, bool _forSwap);
|
||||
|
||||
void expectDeposit(int _deposit, int _oldHeight);
|
||||
|
||||
@ -123,7 +120,6 @@ private:
|
||||
/// Assigns the label's or function's id to a value taken from eth::Assembly if it has not yet been set.
|
||||
void assignLabelIdIfUnset(boost::optional<AbstractAssembly::LabelID>& _labelId);
|
||||
|
||||
solidity::ErrorReporter& m_errorReporter;
|
||||
julia::AbstractAssembly& m_assembly;
|
||||
solidity::assembly::AsmAnalysisInfo& m_info;
|
||||
solidity::assembly::Scope* m_scope = nullptr;
|
||||
|
@ -524,9 +524,6 @@ bool ContractCompiler::visit(FunctionDefinition const& _function)
|
||||
|
||||
bool ContractCompiler::visit(InlineAssembly const& _inlineAssembly)
|
||||
{
|
||||
ErrorList errors;
|
||||
ErrorReporter errorReporter(errors);
|
||||
assembly::CodeGenerator codeGen(errorReporter);
|
||||
unsigned startStackHeight = m_context.stackHeight();
|
||||
julia::ExternalIdentifierAccess identifierAccess;
|
||||
identifierAccess.resolve = [&](assembly::Identifier const& _identifier, julia::IdentifierContext, bool)
|
||||
@ -648,13 +645,12 @@ bool ContractCompiler::visit(InlineAssembly const& _inlineAssembly)
|
||||
}
|
||||
};
|
||||
solAssert(_inlineAssembly.annotation().analysisInfo, "");
|
||||
codeGen.assemble(
|
||||
assembly::CodeGenerator::assemble(
|
||||
_inlineAssembly.operations(),
|
||||
*_inlineAssembly.annotation().analysisInfo,
|
||||
m_context.nonConstAssembly(),
|
||||
identifierAccess
|
||||
);
|
||||
solAssert(Error::containsOnlyWarnings(errorReporter.errors()), "Code generation for inline assembly with errors requested.");
|
||||
m_context.setStackOffset(startStackHeight);
|
||||
return false;
|
||||
}
|
||||
|
@ -140,7 +140,7 @@ eth::Assembly assembly::CodeGenerator::assemble(
|
||||
{
|
||||
eth::Assembly assembly;
|
||||
EthAssemblyAdapter assemblyAdapter(assembly);
|
||||
julia::CodeTransform(m_errorReporter, assemblyAdapter, _analysisInfo, false, _identifierAccess).run(_parsedData);
|
||||
julia::CodeTransform(assemblyAdapter, _analysisInfo, false, _identifierAccess).run(_parsedData);
|
||||
return assembly;
|
||||
}
|
||||
|
||||
@ -152,5 +152,5 @@ void assembly::CodeGenerator::assemble(
|
||||
)
|
||||
{
|
||||
EthAssemblyAdapter assemblyAdapter(_assembly);
|
||||
julia::CodeTransform(m_errorReporter, assemblyAdapter, _analysisInfo, false, _identifierAccess).run(_parsedData);
|
||||
julia::CodeTransform(assemblyAdapter, _analysisInfo, false, _identifierAccess).run(_parsedData);
|
||||
}
|
||||
|
@ -34,7 +34,6 @@ class Assembly;
|
||||
}
|
||||
namespace solidity
|
||||
{
|
||||
class ErrorReporter;
|
||||
namespace assembly
|
||||
{
|
||||
struct Block;
|
||||
@ -42,24 +41,19 @@ struct Block;
|
||||
class CodeGenerator
|
||||
{
|
||||
public:
|
||||
CodeGenerator(ErrorReporter& _errorReporter):
|
||||
m_errorReporter(_errorReporter) {}
|
||||
/// Performs code generation and @returns the result.
|
||||
eth::Assembly assemble(
|
||||
static eth::Assembly assemble(
|
||||
Block const& _parsedData,
|
||||
AsmAnalysisInfo& _analysisInfo,
|
||||
julia::ExternalIdentifierAccess const& _identifierAccess = julia::ExternalIdentifierAccess()
|
||||
);
|
||||
/// Performs code generation and appends generated to to _assembly.
|
||||
void assemble(
|
||||
static void assemble(
|
||||
Block const& _parsedData,
|
||||
AsmAnalysisInfo& _analysisInfo,
|
||||
eth::Assembly& _assembly,
|
||||
julia::ExternalIdentifierAccess const& _identifierAccess = julia::ExternalIdentifierAccess()
|
||||
);
|
||||
|
||||
private:
|
||||
ErrorReporter& m_errorReporter;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -66,8 +66,7 @@ eth::Assembly InlineAssemblyStack::assemble()
|
||||
AsmAnalysisInfo analysisInfo;
|
||||
AsmAnalyzer analyzer(analysisInfo, m_errorReporter);
|
||||
solAssert(analyzer.analyze(*m_parserResult), "");
|
||||
CodeGenerator codeGen(m_errorReporter);
|
||||
return codeGen.assemble(*m_parserResult, analysisInfo);
|
||||
return CodeGenerator::assemble(*m_parserResult, analysisInfo);
|
||||
}
|
||||
|
||||
bool InlineAssemblyStack::parseAndAssemble(
|
||||
@ -87,7 +86,8 @@ bool InlineAssemblyStack::parseAndAssemble(
|
||||
AsmAnalysisInfo analysisInfo;
|
||||
AsmAnalyzer analyzer(analysisInfo, errorReporter, false, _identifierAccess.resolve);
|
||||
solAssert(analyzer.analyze(*parserResult), "");
|
||||
CodeGenerator(errorReporter).assemble(*parserResult, analysisInfo, _assembly, _identifierAccess);
|
||||
solAssert(errorReporter.errors().empty(), "");
|
||||
CodeGenerator::assemble(*parserResult, analysisInfo, _assembly, _identifierAccess);
|
||||
|
||||
// At this point, the assembly might be messed up, but we should throw an
|
||||
// internal compiler error anyway.
|
||||
|
@ -76,7 +76,7 @@ bool AssemblyStack::analyzeParsed()
|
||||
return m_analysisSuccessful;
|
||||
}
|
||||
|
||||
eth::LinkerObject AssemblyStack::assemble(Machine _machine)
|
||||
eth::LinkerObject AssemblyStack::assemble(Machine _machine) const
|
||||
{
|
||||
solAssert(m_analysisSuccessful, "");
|
||||
solAssert(m_parserResult, "");
|
||||
@ -86,13 +86,13 @@ eth::LinkerObject AssemblyStack::assemble(Machine _machine)
|
||||
{
|
||||
case Machine::EVM:
|
||||
{
|
||||
auto assembly = assembly::CodeGenerator(m_errorReporter).assemble(*m_parserResult, *m_analysisInfo);
|
||||
auto assembly = assembly::CodeGenerator::assemble(*m_parserResult, *m_analysisInfo);
|
||||
return assembly.assemble();
|
||||
}
|
||||
case Machine::EVM15:
|
||||
{
|
||||
julia::EVMAssembly assembly(true);
|
||||
julia::CodeTransform(m_errorReporter, assembly, *m_analysisInfo, true).run(*m_parserResult);
|
||||
julia::CodeTransform(assembly, *m_analysisInfo, true).run(*m_parserResult);
|
||||
return assembly.finalize();
|
||||
}
|
||||
case Machine::eWasm:
|
||||
@ -102,7 +102,7 @@ eth::LinkerObject AssemblyStack::assemble(Machine _machine)
|
||||
return eth::LinkerObject();
|
||||
}
|
||||
|
||||
string AssemblyStack::print()
|
||||
string AssemblyStack::print() const
|
||||
{
|
||||
solAssert(m_parserResult, "");
|
||||
return assembly::AsmPrinter(m_language == Language::JULIA)(*m_parserResult);
|
||||
|
@ -65,13 +65,13 @@ public:
|
||||
bool analyze(assembly::Block const& _block, Scanner const* _scanner = nullptr);
|
||||
|
||||
/// Run the assembly step (should only be called after parseAndAnalyze).
|
||||
eth::LinkerObject assemble(Machine _machine);
|
||||
eth::LinkerObject assemble(Machine _machine) const;
|
||||
|
||||
/// @returns the errors generated during parsing, analysis (and potentially assembly).
|
||||
ErrorList const& errors() const { return m_errors; }
|
||||
|
||||
/// Pretty-print the input after having parsed it.
|
||||
std::string print();
|
||||
std::string print() const;
|
||||
|
||||
private:
|
||||
bool analyzeParsed();
|
||||
|
Loading…
Reference in New Issue
Block a user