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)
|
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);
|
ev.visit(_expression);
|
||||||
return ev.value();
|
return ev.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<u256> Interpreter::evaluateMulti(Expression const& _expression)
|
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);
|
ev.visit(_expression);
|
||||||
return ev.values();
|
return ev.values();
|
||||||
}
|
}
|
||||||
@ -248,7 +248,7 @@ void ExpressionEvaluator::operator()(FunctionCall const& _funCall)
|
|||||||
|
|
||||||
// TODO function name lookup could be a little more efficient,
|
// TODO function name lookup could be a little more efficient,
|
||||||
// we have to copy the list here.
|
// 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);
|
interpreter(fun.body);
|
||||||
|
|
||||||
m_values.clear();
|
m_values.clear();
|
||||||
@ -280,3 +280,20 @@ void ExpressionEvaluator::evaluateArgs(vector<Expression> const& _expr)
|
|||||||
m_values = std::move(values);
|
m_values = std::move(values);
|
||||||
std::reverse(m_values.begin(), m_values.end());
|
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,
|
InterpreterState& _state,
|
||||||
Dialect const& _dialect,
|
Dialect const& _dialect,
|
||||||
std::map<YulString, dev::u256> const& _variables,
|
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_state(_state),
|
||||||
m_dialect(_dialect),
|
m_dialect(_dialect),
|
||||||
m_variables(_variables),
|
m_variables(_variables),
|
||||||
m_functions(_functions)
|
m_functions(_functions),
|
||||||
|
m_scopes(_scopes)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void operator()(Literal const&) override;
|
void operator()(Literal const&) override;
|
||||||
@ -184,12 +186,16 @@ private:
|
|||||||
/// stores it in m_value.
|
/// stores it in m_value.
|
||||||
void evaluateArgs(std::vector<Expression> const& _expr);
|
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;
|
InterpreterState& m_state;
|
||||||
Dialect const& m_dialect;
|
Dialect const& m_dialect;
|
||||||
/// Values of variables.
|
/// Values of variables.
|
||||||
std::map<YulString, dev::u256> const& m_variables;
|
std::map<YulString, dev::u256> const& m_variables;
|
||||||
/// Meanings of functions.
|
/// Meanings of functions.
|
||||||
std::map<YulString, FunctionDefinition const*> const& m_functions;
|
std::map<YulString, FunctionDefinition const*> const& m_functions;
|
||||||
|
std::vector<std::set<YulString>> const& m_scopes;
|
||||||
/// Current value of the expression
|
/// Current value of the expression
|
||||||
std::vector<dev::u256> m_values;
|
std::vector<dev::u256> m_values;
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user