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