aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorchriseth <chris@ethereum.org>2017-05-29 22:52:51 +0800
committerGitHub <noreply@github.com>2017-05-29 22:52:51 +0800
commit8b29cc55357b4eec12c771707ed4025d11ca4365 (patch)
tree7474badc8dfe8d7685b560ab9e9d5be1e50323dc
parent9822deeed9d0be1324d6b6bdbdf83ae7ebca9b69 (diff)
parent4af55c78ebcacb5cfda1b573253cac6e6824d67a (diff)
downloaddexon-solidity-8b29cc55357b4eec12c771707ed4025d11ca4365.tar
dexon-solidity-8b29cc55357b4eec12c771707ed4025d11ca4365.tar.gz
dexon-solidity-8b29cc55357b4eec12c771707ed4025d11ca4365.tar.bz2
dexon-solidity-8b29cc55357b4eec12c771707ed4025d11ca4365.tar.lz
dexon-solidity-8b29cc55357b4eec12c771707ed4025d11ca4365.tar.xz
dexon-solidity-8b29cc55357b4eec12c771707ed4025d11ca4365.tar.zst
dexon-solidity-8b29cc55357b4eec12c771707ed4025d11ca4365.zip
Merge pull request #2319 from ethereum/virtualBlocks
Introduce virtual blocks for function arguments.
-rw-r--r--libsolidity/inlineasm/AsmAnalysis.cpp15
-rw-r--r--libsolidity/inlineasm/AsmAnalysis.h4
-rw-r--r--libsolidity/inlineasm/AsmAnalysisInfo.h3
-rw-r--r--libsolidity/inlineasm/AsmScopeFiller.cpp21
-rw-r--r--libsolidity/inlineasm/AsmScopeFiller.h6
5 files changed, 28 insertions, 21 deletions
diff --git a/libsolidity/inlineasm/AsmAnalysis.cpp b/libsolidity/inlineasm/AsmAnalysis.cpp
index eeb7d0a6..9f512f87 100644
--- a/libsolidity/inlineasm/AsmAnalysis.cpp
+++ b/libsolidity/inlineasm/AsmAnalysis.cpp
@@ -46,7 +46,7 @@ set<string> const builtinTypes{"bool", "u8", "s8", "u32", "s32", "u64", "s64", "
bool AsmAnalyzer::analyze(Block const& _block)
{
- if (!(ScopeFiller(m_info.scopes, m_errors))(_block))
+ if (!(ScopeFiller(m_info, m_errors))(_block))
return false;
return (*this)(_block);
@@ -206,16 +206,17 @@ bool AsmAnalyzer::operator()(assembly::VariableDeclaration const& _varDecl)
bool AsmAnalyzer::operator()(assembly::FunctionDefinition const& _funDef)
{
- Scope& bodyScope = scope(&_funDef.body);
+ Block const* virtualBlock = m_info.virtualBlocks.at(&_funDef).get();
+ solAssert(virtualBlock, "");
+ Scope& varScope = scope(virtualBlock);
for (auto const& var: _funDef.arguments + _funDef.returns)
{
expectValidType(var.type, var.location);
- boost::get<Scope::Variable>(bodyScope.identifiers.at(var.name)).active = true;
+ boost::get<Scope::Variable>(varScope.identifiers.at(var.name)).active = true;
}
int const stackHeight = m_stackHeight;
m_stackHeight = _funDef.arguments.size() + _funDef.returns.size();
- m_virtualVariablesInNextBlock = m_stackHeight;
bool success = (*this)(_funDef.body);
@@ -337,10 +338,10 @@ bool AsmAnalyzer::operator()(Switch const& _switch)
bool AsmAnalyzer::operator()(Block const& _block)
{
bool success = true;
+ auto previousScope = m_currentScope;
m_currentScope = &scope(&_block);
- int const initialStackHeight = m_stackHeight - m_virtualVariablesInNextBlock;
- m_virtualVariablesInNextBlock = 0;
+ int const initialStackHeight = m_stackHeight;
for (auto const& s: _block.statements)
if (!boost::apply_visitor(*this, s))
@@ -366,8 +367,8 @@ bool AsmAnalyzer::operator()(Block const& _block)
success = false;
}
- m_currentScope = m_currentScope->superScope;
m_info.stackHeightInfo[&_block] = m_stackHeight;
+ m_currentScope = previousScope;
return success;
}
diff --git a/libsolidity/inlineasm/AsmAnalysis.h b/libsolidity/inlineasm/AsmAnalysis.h
index 87d41e11..14b18c4a 100644
--- a/libsolidity/inlineasm/AsmAnalysis.h
+++ b/libsolidity/inlineasm/AsmAnalysis.h
@@ -91,10 +91,6 @@ private:
Scope& scope(assembly::Block const* _block);
void expectValidType(std::string const& type, SourceLocation const& _location);
- /// This is used when we enter the body of a function definition. There, the parameters
- /// and return parameters appear as variables which are already on the stack before
- /// we enter the block.
- int m_virtualVariablesInNextBlock = 0;
int m_stackHeight = 0;
julia::ExternalIdentifierAccess::Resolver const& m_resolver;
Scope* m_currentScope = nullptr;
diff --git a/libsolidity/inlineasm/AsmAnalysisInfo.h b/libsolidity/inlineasm/AsmAnalysisInfo.h
index 18382db0..78c1fbe0 100644
--- a/libsolidity/inlineasm/AsmAnalysisInfo.h
+++ b/libsolidity/inlineasm/AsmAnalysisInfo.h
@@ -24,6 +24,7 @@
#include <map>
#include <memory>
+#include <vector>
namespace dev
{
@@ -55,6 +56,8 @@ struct AsmAnalysisInfo
using Scopes = std::map<assembly::Block const*, std::shared_ptr<Scope>>;
Scopes scopes;
StackHeightInfo stackHeightInfo;
+ /// Virtual blocks which will be used for scopes for function arguments and return values.
+ std::map<FunctionDefinition const*, std::shared_ptr<assembly::Block const>> virtualBlocks;
};
}
diff --git a/libsolidity/inlineasm/AsmScopeFiller.cpp b/libsolidity/inlineasm/AsmScopeFiller.cpp
index 7eb6a9ed..3fade842 100644
--- a/libsolidity/inlineasm/AsmScopeFiller.cpp
+++ b/libsolidity/inlineasm/AsmScopeFiller.cpp
@@ -22,6 +22,7 @@
#include <libsolidity/inlineasm/AsmData.h>
#include <libsolidity/inlineasm/AsmScope.h>
+#include <libsolidity/inlineasm/AsmAnalysisInfo.h>
#include <libsolidity/interface/Exceptions.h>
#include <libsolidity/interface/Utils.h>
@@ -36,8 +37,8 @@ using namespace dev;
using namespace dev::solidity;
using namespace dev::solidity::assembly;
-ScopeFiller::ScopeFiller(ScopeFiller::Scopes& _scopes, ErrorList& _errors):
- m_scopes(_scopes), m_errors(_errors)
+ScopeFiller::ScopeFiller(AsmAnalysisInfo& _info, ErrorList& _errors):
+ m_info(_info), m_errors(_errors)
{
m_currentScope = &scope(nullptr);
}
@@ -84,16 +85,22 @@ bool ScopeFiller::operator()(assembly::FunctionDefinition const& _funDef)
));
success = false;
}
- Scope& body = scope(&_funDef.body);
- body.superScope = m_currentScope;
- body.functionScope = true;
+
+ auto virtualBlock = m_info.virtualBlocks[&_funDef] = make_shared<Block>();
+ Scope& varScope = scope(virtualBlock.get());
+ varScope.superScope = m_currentScope;
+ m_currentScope = &varScope;
+ varScope.functionScope = true;
for (auto const& var: _funDef.arguments + _funDef.returns)
- if (!registerVariable(var, _funDef.location, body))
+ if (!registerVariable(var, _funDef.location, varScope))
success = false;
if (!(*this)(_funDef.body))
success = false;
+ solAssert(m_currentScope == &varScope, "");
+ m_currentScope = m_currentScope->superScope;
+
return success;
}
@@ -137,7 +144,7 @@ bool ScopeFiller::registerVariable(TypedName const& _name, SourceLocation const&
Scope& ScopeFiller::scope(Block const* _block)
{
- auto& scope = m_scopes[_block];
+ auto& scope = m_info.scopes[_block];
if (!scope)
scope = make_shared<Scope>();
return *scope;
diff --git a/libsolidity/inlineasm/AsmScopeFiller.h b/libsolidity/inlineasm/AsmScopeFiller.h
index c7179b3b..42e80141 100644
--- a/libsolidity/inlineasm/AsmScopeFiller.h
+++ b/libsolidity/inlineasm/AsmScopeFiller.h
@@ -49,6 +49,7 @@ struct FunctionCall;
struct Switch;
struct Scope;
+struct AsmAnalysisInfo;
/**
* Fills scopes with identifiers and checks for name clashes.
@@ -57,8 +58,7 @@ struct Scope;
class ScopeFiller: public boost::static_visitor<bool>
{
public:
- using Scopes = std::map<assembly::Block const*, std::shared_ptr<Scope>>;
- ScopeFiller(Scopes& _scopes, ErrorList& _errors);
+ ScopeFiller(AsmAnalysisInfo& _info, ErrorList& _errors);
bool operator()(assembly::Instruction const&) { return true; }
bool operator()(assembly::Literal const&) { return true; }
@@ -83,7 +83,7 @@ private:
Scope& scope(assembly::Block const* _block);
Scope* m_currentScope = nullptr;
- Scopes& m_scopes;
+ AsmAnalysisInfo& m_info;
ErrorList& m_errors;
};