[Sol -> Yul] Implement delete for function pointers

This commit is contained in:
Mathias Baumann
2019-05-23 15:51:59 +02:00
parent 81702717b0
commit 981983089c
8 changed files with 89 additions and 6 deletions
+19
View File
@@ -1138,6 +1138,25 @@ string YulUtilFunctions::negateNumberCheckedFunction(Type const& _type)
});
}
string YulUtilFunctions::zeroValueFunction(Type const& _type)
{
solUnimplementedAssert(_type.sizeOnStack() == 1, "Stacksize not yet implemented!");
solUnimplementedAssert(_type.isValueType(), "Zero value for non-value types not yet implemented");
string const functionName = "zero_value_for_" + _type.identifier();
return m_functionCollector->createFunction(functionName, [&]() {
return Whiskers(R"(
function <functionName>() -> ret {
<body>
}
)")
("functionName", functionName)
("body", "ret := 0x0")
.render();
});
}
string YulUtilFunctions::conversionFunctionSpecial(Type const& _from, Type const& _to)
{
string functionName =
+3
View File
@@ -183,6 +183,9 @@ public:
std::string negateNumberCheckedFunction(Type const& _type);
/// @returns the name of a function that returns the zero value for the
/// provided type
std::string zeroValueFunction(Type const& _type);
private:
/// Special case of conversionFunction - handles everything that does not
/// use exactly one variable to hold the value.
@@ -114,7 +114,7 @@ string IRGenerationContext::internalDispatch(size_t _in, size_t _out)
string funName = "dispatch_internal_in_" + to_string(_in) + "_out_" + to_string(_out);
return m_functions->createFunction(funName, [&]() {
Whiskers templ(R"(
function <functionName>(fun <comma> <in>) -> <out> {
function <functionName>(fun <comma> <in>) <arrow> <out> {
switch fun
<#cases>
case <funID>
@@ -129,6 +129,7 @@ string IRGenerationContext::internalDispatch(size_t _in, size_t _out)
templ("comma", _in > 0 ? "," : "");
YulUtilFunctions utils(m_evmVersion, m_functions);
templ("in", utils.suffixedVariableNameList("in_", 0, _in));
templ("arrow", _out > 0 ? "->" : "");
templ("out", utils.suffixedVariableNameList("out_", 0, _out));
vector<map<string, string>> functions;
for (auto const& contract: m_inheritanceHierarchy)
@@ -138,10 +139,15 @@ string IRGenerationContext::internalDispatch(size_t _in, size_t _out)
function->parameters().size() == _in &&
function->returnParameters().size() == _out
)
{
// 0 is reserved for uninitialized function pointers
solAssert(function->id() != 0, "Unexpected function ID: 0");
functions.emplace_back(map<string, string> {
{ "funID", to_string(function->id()) },
{ "name", functionName(*function)}
});
}
templ("cases", move(functions));
return templ.render();
});
@@ -246,7 +246,13 @@ void IRGeneratorForStatements::endVisit(UnaryOperation const& _unaryOperation)
Type const& resultType = type(_unaryOperation);
Token const op = _unaryOperation.getOperator();
if (resultType.category() == Type::Category::RationalNumber)
if (op == Token::Delete)
{
solAssert(!!m_currentLValue, "LValue not retrieved.");
m_code << m_currentLValue->setToZero();
m_currentLValue.reset();
}
else if (resultType.category() == Type::Category::RationalNumber)
{
defineExpression(_unaryOperation) <<
formatNumber(resultType.literalValue(nullptr)) <<
+10
View File
@@ -22,6 +22,7 @@
#include <libsolidity/codegen/ir/IRGenerationContext.h>
#include <libsolidity/codegen/YulUtilFunctions.h>
#include <libsolidity/codegen/CompilerUtils.h>
#include <libsolidity/ast/AST.h>
#include <libdevcore/Whiskers.h>
@@ -45,6 +46,11 @@ string IRLocalVariable::storeValue(string const& _value, Type const& _type) cons
return m_variableName + " := " + _value + "\n";
}
string IRLocalVariable::setToZero() const
{
return storeValue(m_context.utils().zeroValueFunction(*m_type) + "()", *m_type);
}
IRStorageItem::IRStorageItem(
IRGenerationContext& _context,
VariableDeclaration const& _varDecl
@@ -110,3 +116,7 @@ string IRStorageItem::storeValue(string const& _value, Type const& _sourceType)
}
}
string IRStorageItem::setToZero() const
{
solUnimplemented("Delete for storage location not yet implemented");
}
+4
View File
@@ -51,6 +51,8 @@ public:
/// of type @a _type in the lvalue. Might perform type conversion.
virtual std::string storeValue(std::string const& _value, Type const& _type) const = 0;
/// Returns code that will reset the stored value to zero
virtual std::string setToZero() const = 0;
protected:
IRGenerationContext& m_context;
Type const* m_type;
@@ -66,6 +68,7 @@ public:
std::string retrieveValue() const override { return m_variableName; }
std::string storeValue(std::string const& _value, Type const& _type) const override;
std::string setToZero() const override;
private:
std::string m_variableName;
};
@@ -86,6 +89,7 @@ public:
std::string retrieveValue() const override;
std::string storeValue(std::string const& _value, Type const& _type) const override;
std::string setToZero() const override;
private:
std::string m_slot;
unsigned m_offset;