YulInterpreter: Fix wrong context passed to called function

This commit is contained in:
Mathias Baumann 2019-08-08 17:00:48 +02:00
parent cbac3a4208
commit ccfcee5b80
3 changed files with 47 additions and 5 deletions

View File

@ -0,0 +1,19 @@
{
function f()
{
// Variable declaration does not shadow namesake function declaration
// because latter not visible here.
let shadow_id
}
{
// Function named `shadow_id` is in scope now.
f()
function shadow_id() {}
}
}
// ====
// EVMVersion: >=constantinople
// ----
// Trace:
// Memory dump:
// Storage dump:

View File

@ -180,14 +180,14 @@ void Interpreter::operator()(Block const& _block)
u256 Interpreter::evaluate(Expression const& _expression)
{
ExpressionEvaluator ev(m_state, m_dialect, m_variables, m_functions);
ExpressionEvaluator ev(m_state, m_dialect, m_variables, m_functions, m_scopes);
ev.visit(_expression);
return ev.value();
}
vector<u256> Interpreter::evaluateMulti(Expression const& _expression)
{
ExpressionEvaluator ev(m_state, m_dialect, m_variables, m_functions);
ExpressionEvaluator ev(m_state, m_dialect, m_variables, m_functions, m_scopes);
ev.visit(_expression);
return ev.values();
}
@ -248,7 +248,7 @@ void ExpressionEvaluator::operator()(FunctionCall const& _funCall)
// TODO function name lookup could be a little more efficient,
// we have to copy the list here.
Interpreter interpreter(m_state, m_dialect, variables, m_functions);
Interpreter interpreter(m_state, m_dialect, variables, visibleFunctionsFor(fun.name));
interpreter(fun.body);
m_values.clear();
@ -280,3 +280,20 @@ void ExpressionEvaluator::evaluateArgs(vector<Expression> const& _expr)
m_values = std::move(values);
std::reverse(m_values.begin(), m_values.end());
}
std::map<YulString, FunctionDefinition const*> ExpressionEvaluator::visibleFunctionsFor(YulString const& _name)
{
std::map<YulString, FunctionDefinition const*> functions;
for (auto const& scope: m_scopes)
{
for (auto const& symbol: scope)
if (m_functions.count(symbol) > 0)
functions[symbol] = m_functions.at(symbol);
if (scope.count(_name))
break;
}
return functions;
}

View File

@ -159,12 +159,14 @@ public:
InterpreterState& _state,
Dialect const& _dialect,
std::map<YulString, dev::u256> const& _variables,
std::map<YulString, FunctionDefinition const*> const& _functions
std::map<YulString, FunctionDefinition const*> const& _functions,
std::vector<std::set<YulString>> const& _scopes
):
m_state(_state),
m_dialect(_dialect),
m_variables(_variables),
m_functions(_functions)
m_functions(_functions),
m_scopes(_scopes)
{}
void operator()(Literal const&) override;
@ -184,12 +186,16 @@ private:
/// stores it in m_value.
void evaluateArgs(std::vector<Expression> const& _expr);
/// Extracts functions from the earlier scopes that are visible for the given function
std::map<YulString, FunctionDefinition const*> visibleFunctionsFor(YulString const& _name);
InterpreterState& m_state;
Dialect const& m_dialect;
/// Values of variables.
std::map<YulString, dev::u256> const& m_variables;
/// Meanings of functions.
std::map<YulString, FunctionDefinition const*> const& m_functions;
std::vector<std::set<YulString>> const& m_scopes;
/// Current value of the expression
std::vector<dev::u256> m_values;
};