Skip to content

Commit d85de22

Browse files
authored
Merge pull request #10267 from ethereum/fixAssemblyAccessToConstants
[SolYul] Implement inline assembly access to constants.
2 parents 9f0a631 + 1508b08 commit d85de22

File tree

4 files changed

+50
-2
lines changed

4 files changed

+50
-2
lines changed

Diff for: libsolidity/codegen/ir/IRGeneratorForStatements.cpp

+44-2
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include <libsolidity/codegen/CompilerUtils.h>
3131
#include <libsolidity/codegen/ReturnInfo.h>
3232
#include <libsolidity/ast/TypeProvider.h>
33+
#include <libsolidity/ast/ASTUtils.h>
3334

3435
#include <libevmasm/GasMeter.h>
3536

@@ -110,7 +111,7 @@ struct CopyTranslate: public yul::ASTCopier
110111
solUnimplementedAssert(varDecl, "");
111112
string const& suffix = reference.suffix;
112113

113-
if (suffix.empty())
114+
if (suffix.empty() && !varDecl->isStateVariable())
114115
{
115116
auto const& var = m_context.localVariable(*varDecl);
116117
solAssert(var.type().sizeOnStack() == 1, "");
@@ -122,7 +123,48 @@ struct CopyTranslate: public yul::ASTCopier
122123
}
123124

124125
string value;
125-
if (varDecl->isStateVariable())
126+
if (varDecl->isConstant())
127+
{
128+
VariableDeclaration const* variable = rootConstVariableDeclaration(*varDecl);
129+
solAssert(variable, "");
130+
131+
if (variable->value()->annotation().type->category() == Type::Category::RationalNumber)
132+
{
133+
u256 intValue = dynamic_cast<RationalNumberType const&>(*variable->value()->annotation().type).literalValue(nullptr);
134+
if (auto const* bytesType = dynamic_cast<FixedBytesType const*>(variable->type()))
135+
intValue <<= 256 - 8 * bytesType->numBytes();
136+
else
137+
solAssert(variable->type()->category() == Type::Category::Integer, "");
138+
value = intValue.str();
139+
}
140+
else if (auto const* literal = dynamic_cast<Literal const*>(variable->value().get()))
141+
{
142+
TypePointer type = literal->annotation().type;
143+
144+
switch (type->category())
145+
{
146+
case Type::Category::Bool:
147+
case Type::Category::Address:
148+
solAssert(type->category() == variable->annotation().type->category(), "");
149+
value = toCompactHexWithPrefix(type->literalValue(literal));
150+
break;
151+
case Type::Category::StringLiteral:
152+
{
153+
auto const& stringLiteral = dynamic_cast<StringLiteralType const&>(*type);
154+
solAssert(variable->type()->category() == Type::Category::FixedBytes, "");
155+
unsigned const numBytes = dynamic_cast<FixedBytesType const&>(*variable->type()).numBytes();
156+
solAssert(stringLiteral.value().size() <= numBytes, "");
157+
value = formatNumber(u256(h256(stringLiteral.value(), h256::AlignLeft)));
158+
break;
159+
}
160+
default:
161+
solAssert(false, "");
162+
}
163+
}
164+
else
165+
solAssert(false, "Invalid constant in inline assembly.");
166+
}
167+
else if (varDecl->isStateVariable())
126168
{
127169
if (suffix == "slot")
128170
value = m_context.storageLocationOfStateVariable(*varDecl).first.str();

Diff for: test/libsolidity/semanticTests/constants/asm_address_constant_regression.sol

+2
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,7 @@ contract C {
88
}
99
}
1010

11+
// ====
12+
// compileViaYul: also
1113
// ----
1214
// f() -> 0x00

Diff for: test/libsolidity/semanticTests/inlineAssembly/constant_access.sol

+2
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,7 @@ contract C {
1414
}
1515
}
1616
}
17+
// ====
18+
// compileViaYul: also
1719
// ----
1820
// f() -> 2, left(0xabcd), left(0x616263), true, 0x1212121212121212121212121212121212121212

Diff for: test/libsolidity/semanticTests/inlineAssembly/constant_access_referencing.sol

+2
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,7 @@ contract C {
2222
}
2323
}
2424
}
25+
// ====
26+
// compileViaYul: also
2527
// ----
2628
// f() -> 2, left(0xabcd), left(0x616263), true, 0x1212121212121212121212121212121212121212

0 commit comments

Comments
 (0)