Skip to content

Commit

Permalink
Implement uninitialized storage functions.
Browse files Browse the repository at this point in the history
  • Loading branch information
chriseth committed Nov 16, 2016
1 parent b6992d7 commit 47794c1
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 14 deletions.
1 change: 1 addition & 0 deletions libevmasm/Assembly.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -485,6 +485,7 @@ LinkerObject const& Assembly::assemble() const
break;
case Tag:
tagPos[(unsigned)i.data()] = ret.bytecode.size();
assertThrow(ret.bytecode.size() < 0xffffffffL, AssemblyException, "Tag too large.");
assertThrow(i.data() != 0, AssemblyException, "");
ret.bytecode.push_back((byte)Instruction::JUMPDEST);
break;
Expand Down
2 changes: 2 additions & 0 deletions libsolidity/codegen/CompilerContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ namespace solidity {
class CompilerContext
{
public:
bool isCreationPhase() const { return m_mode == CompilationMode::Creation; }

void addMagicGlobal(MagicVariableDeclaration const& _declaration);
void addStateVariable(VariableDeclaration const& _declaration, u256 const& _storageOffset, unsigned _byteOffset);
void addVariable(VariableDeclaration const& _declaration, unsigned _offsetToCurrent = 0);
Expand Down
26 changes: 15 additions & 11 deletions libsolidity/codegen/LValue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -190,11 +190,11 @@ void StorageItem::retrieveValue(SourceLocation const&, bool _remove) const
dynamic_cast<IntegerType const&>(*m_dataType).isSigned()
)
m_context << u256(m_dataType->storageBytes() - 1) << Instruction::SIGNEXTEND;
else if (
m_dataType->category() == Type::Category::Function &&
dynamic_cast<FunctionType const&>(*m_dataType).location() == FunctionType::Location::External
)
CompilerUtils(m_context).splitExternalFunctionType(false);
else if (FunctionType const* fun = dynamic_cast<decltype(fun)>(m_dataType))
{
if (fun->location() == FunctionType::Location::External)
CompilerUtils(m_context).splitExternalFunctionType(false);
}
else
{
solAssert(m_dataType->sizeOnStack() == 1, "");
Expand Down Expand Up @@ -236,12 +236,16 @@ void StorageItem::storeValue(Type const& _sourceType, SourceLocation const& _loc
// stack: value storage_ref cleared_value multiplier
utils.copyToStackTop(3 + m_dataType->sizeOnStack(), m_dataType->sizeOnStack());
// stack: value storage_ref cleared_value multiplier value
if (
m_dataType->category() == Type::Category::Function &&
dynamic_cast<FunctionType const&>(*m_dataType).location() == FunctionType::Location::External
)
// Combine the two-item function type into a single stack slot.
utils.combineExternalFunctionType(false);
if (FunctionType const* fun = dynamic_cast<decltype(fun)>(m_dataType))
{
if (fun->location() == FunctionType::Location::External)
// Combine the two-item function type into a single stack slot.
utils.combineExternalFunctionType(false);
else
m_context <<
((u256(1) << (8 * m_dataType->storageBytes())) - 1) <<
Instruction::AND;
}
else if (m_dataType->category() == Type::Category::FixedBytes)
m_context
<< (u256(0x1) << (256 - 8 * dynamic_cast<FixedBytesType const&>(*m_dataType).numBytes()))
Expand Down
4 changes: 1 addition & 3 deletions test/libsolidity/SolidityEndToEndTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7631,8 +7631,6 @@ BOOST_AUTO_TEST_CASE(calling_uninitialized_function)

BOOST_AUTO_TEST_CASE(calling_uninitialized_function_in_detail)
{
// Storage default value of zero would be correct jump dest, this tests that
// that is properly handled.
char const* sourceCode = R"(
contract C {
function() internal returns (uint) x;
Expand All @@ -7641,7 +7639,7 @@ BOOST_AUTO_TEST_CASE(calling_uninitialized_function_in_detail)
if (mutex > 0)
return 7;
mutex = 1;
// If this test fails, it will jump to "0" and re-execute this function.
// Avoid re-executing this function if we jump somewhere.
x();
return 2;
}
Expand Down

0 comments on commit 47794c1

Please sign in to comment.