mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
YulInterpreter: Fix wrong context passed to called function
This commit is contained in:
parent
cbac3a4208
commit
ccfcee5b80
19
test/libyul/yulInterpreterTests/shadowed_symbol.yul
Normal file
19
test/libyul/yulInterpreterTests/shadowed_symbol.yul
Normal 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:
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user