aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorchriseth <c@ethdev.com>2016-11-08 03:08:05 +0800
committerchriseth <c@ethdev.com>2016-11-16 21:37:18 +0800
commit47794c1da406a28f0e8a10e3e57cd935f5cc7f3d (patch)
tree94a8a509f31f9b5bb8741a10af4ba92c47e88969
parentb6992d740a849d28f7c2a52bef0ba6b3740c9179 (diff)
downloaddexon-solidity-47794c1da406a28f0e8a10e3e57cd935f5cc7f3d.tar.gz
dexon-solidity-47794c1da406a28f0e8a10e3e57cd935f5cc7f3d.tar.zst
dexon-solidity-47794c1da406a28f0e8a10e3e57cd935f5cc7f3d.zip
Implement uninitialized storage functions.
-rw-r--r--libevmasm/Assembly.cpp1
-rw-r--r--libsolidity/codegen/CompilerContext.h2
-rw-r--r--libsolidity/codegen/LValue.cpp26
-rw-r--r--test/libsolidity/SolidityEndToEndTest.cpp4
4 files changed, 19 insertions, 14 deletions
diff --git a/libevmasm/Assembly.cpp b/libevmasm/Assembly.cpp
index e881c1e2..e19b6b0d 100644
--- a/libevmasm/Assembly.cpp
+++ b/libevmasm/Assembly.cpp
@@ -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;
diff --git a/libsolidity/codegen/CompilerContext.h b/libsolidity/codegen/CompilerContext.h
index 0c1500b0..6c509685 100644
--- a/libsolidity/codegen/CompilerContext.h
+++ b/libsolidity/codegen/CompilerContext.h
@@ -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);
diff --git a/libsolidity/codegen/LValue.cpp b/libsolidity/codegen/LValue.cpp
index d2c75445..66449fc4 100644
--- a/libsolidity/codegen/LValue.cpp
+++ b/libsolidity/codegen/LValue.cpp
@@ -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, "");
@@ -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()))
diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp
index 44dba9b2..c665b050 100644
--- a/test/libsolidity/SolidityEndToEndTest.cpp
+++ b/test/libsolidity/SolidityEndToEndTest.cpp
@@ -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;
@@ -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;
}