Unary operators with using for directive fix

This commit is contained in:
wechman
2022-09-28 12:05:41 +02:00
parent 6482f5bb17
commit 56bcb525bc
6 changed files with 136 additions and 34 deletions
@@ -410,6 +410,47 @@ bool ExpressionCompiler::visit(TupleExpression const& _tuple)
bool ExpressionCompiler::visit(UnaryOperation const& _unaryOperation)
{
CompilerContext::LocationSetter locationSetter(m_context, _unaryOperation);
if (_unaryOperation.annotation().userDefinedFunction)
{
FunctionDefinition const& function = *_unaryOperation.annotation().userDefinedFunction;
FunctionType const* functionType = dynamic_cast<FunctionType const*>(
function.libraryFunction() ? function.typeViaContractName() : function.type());
solAssert(functionType);
functionType = dynamic_cast<FunctionType const&>(*functionType).asBoundFunction();
solAssert(functionType);
evmasm::AssemblyItem returnLabel = m_context.pushNewTag();
_unaryOperation.subExpression().accept(*this);
utils().pushCombinedFunctionEntryLabel(
function.resolveVirtual(m_context.mostDerivedContract()),
false
);
unsigned parameterSize =
CompilerUtils::sizeOnStack(functionType->parameterTypes()) +
functionType->selfType()->sizeOnStack();
if (m_context.runtimeContext())
// We have a runtime context, so we need the creation part.
utils().rightShiftNumberOnStack(32);
else
// Extract the runtime part.
m_context << ((u256(1) << 32) - 1) << Instruction::AND;
m_context.appendJump(evmasm::AssemblyItem::JumpType::IntoFunction);
m_context << returnLabel;
unsigned returnParametersSize = CompilerUtils::sizeOnStack(functionType->returnParameterTypes());
// callee adds return parameters, but removes arguments and return label
m_context.adjustStackOffset(static_cast<int>(returnParametersSize - parameterSize) - 1);
return false;
}
Type const& type = *_unaryOperation.annotation().type;
if (type.category() == Type::Category::RationalNumber)
{
@@ -672,6 +672,34 @@ void IRGeneratorForStatements::endVisit(Return const& _return)
bool IRGeneratorForStatements::visit(UnaryOperation const& _unaryOperation)
{
setLocation(_unaryOperation);
if (_unaryOperation.annotation().userDefinedFunction)
{
_unaryOperation.subExpression().accept(*this);
setLocation(_unaryOperation);
// TODO extract from function call
FunctionDefinition const& function = *_unaryOperation.annotation().userDefinedFunction;
FunctionType const* functionType = dynamic_cast<FunctionType const*>(
function.libraryFunction() ? function.typeViaContractName() : function.type()
);
solAssert(functionType);
functionType = dynamic_cast<FunctionType const&>(*functionType).asBoundFunction();
solAssert(functionType);
// TODO virtual?
string parameter = expressionAsType(_unaryOperation.subExpression(), *functionType->selfType());
solAssert(!parameter.empty());
solAssert(function.isImplemented(), "");
define(_unaryOperation) <<
m_context.enqueueFunctionForCodeGeneration(function) <<
("(" + parameter + ")\n");
return false;
}
Type const& resultType = type(_unaryOperation);
Token const op = _unaryOperation.getOperator();