aboutsummaryrefslogtreecommitdiffstats
path: root/LValue.cpp
diff options
context:
space:
mode:
authorChristian <c@ethdev.com>2015-03-04 00:55:28 +0800
committerchriseth <c@ethdev.com>2015-03-05 20:19:59 +0800
commitb84cf62d6bd3a9caa8a9a7f1dcd427418170aed9 (patch)
treec775f78562d5775487ba8b884d0499023734a7db /LValue.cpp
parenta4d772315d814408c057a9473c2c1fefa351a5b4 (diff)
downloaddexon-solidity-b84cf62d6bd3a9caa8a9a7f1dcd427418170aed9.tar
dexon-solidity-b84cf62d6bd3a9caa8a9a7f1dcd427418170aed9.tar.gz
dexon-solidity-b84cf62d6bd3a9caa8a9a7f1dcd427418170aed9.tar.bz2
dexon-solidity-b84cf62d6bd3a9caa8a9a7f1dcd427418170aed9.tar.lz
dexon-solidity-b84cf62d6bd3a9caa8a9a7f1dcd427418170aed9.tar.xz
dexon-solidity-b84cf62d6bd3a9caa8a9a7f1dcd427418170aed9.tar.zst
dexon-solidity-b84cf62d6bd3a9caa8a9a7f1dcd427418170aed9.zip
Index access for calldata arrays.
Diffstat (limited to 'LValue.cpp')
-rw-r--r--LValue.cpp59
1 files changed, 58 insertions, 1 deletions
diff --git a/LValue.cpp b/LValue.cpp
index 452ca1c7..f5730020 100644
--- a/LValue.cpp
+++ b/LValue.cpp
@@ -232,6 +232,64 @@ void StorageItem::setToZero(SourceLocation const&, bool _removeReference) const
}
}
+/// Used in StorageByteArrayElement
+static IntegerType byteType(8, IntegerType::Modifier::Hash);
+
+StorageByteArrayElement::StorageByteArrayElement(CompilerContext& _compilerContext):
+ LValue(_compilerContext, byteType)
+{
+}
+
+void StorageByteArrayElement::retrieveValue(SourceLocation const&, bool _remove) const
+{
+ // stack: ref bytenr
+ if (_remove)
+ m_context << eth::Instruction::SWAP1 << eth::Instruction::SLOAD
+ << eth::Instruction::SWAP1 << eth::Instruction::BYTE;
+ else
+ m_context << eth::Instruction::DUP2 << eth::Instruction::SLOAD
+ << eth::Instruction::DUP2 << eth::Instruction::BYTE;
+}
+
+void StorageByteArrayElement::storeValue(Type const&, SourceLocation const&, bool _move) const
+{
+ //@todo optimize this
+
+ // stack: value ref bytenr
+ m_context << u256(31) << eth::Instruction::SUB << u256(0x100) << eth::Instruction::EXP;
+ // stack: value ref (1<<(8*(31-bytenr)))
+ m_context << eth::Instruction::DUP2 << eth::Instruction::SLOAD;
+ // stack: value ref (1<<(8*(31-bytenr))) old_full_value
+ // clear byte in old value
+ m_context << eth::Instruction::DUP2 << u256(0xff) << eth::Instruction::MUL
+ << eth::Instruction::NOT << eth::Instruction::AND;
+ // stack: value ref (1<<(32-bytenr)) old_full_value_with_cleared_byte
+ m_context << eth::Instruction::SWAP1 << eth::Instruction::DUP4 << eth::Instruction::MUL
+ << eth::Instruction::OR;
+ // stack: value ref new_full_value
+ m_context << eth::Instruction::SWAP1 << eth::Instruction::SSTORE;
+ if (_move)
+ m_context << eth::Instruction::POP;
+}
+
+void StorageByteArrayElement::setToZero(SourceLocation const&, bool _removeReference) const
+{
+ // stack: ref bytenr
+ if (!_removeReference)
+ m_context << eth::Instruction::SWAP1 << eth::Instruction::DUP2;
+ m_context << u256(31) << eth::Instruction::SUB << u256(0x100) << eth::Instruction::EXP;
+ // stack: ref (1<<(8*(31-bytenr)))
+ m_context << eth::Instruction::DUP2 << eth::Instruction::SLOAD;
+ // stack: ref (1<<(8*(31-bytenr))) old_full_value
+ // clear byte in old value
+ m_context << eth::Instruction::SWAP1 << u256(0xff) << eth::Instruction::MUL << eth::Instruction::AND;
+ // stack: ref old_full_value_with_cleared_byte
+ m_context << eth::Instruction::SWAP1 << eth::Instruction::SSTORE;
+ if (!_removeReference)
+ m_context << eth::Instruction::SWAP1;
+ else
+ m_context << eth::Instruction::POP;
+}
StorageArrayLength::StorageArrayLength(CompilerContext& _compilerContext, const ArrayType& _arrayType):
LValue(_compilerContext, *_arrayType.getMemberType("length")),
@@ -262,4 +320,3 @@ void StorageArrayLength::setToZero(SourceLocation const&, bool _removeReference)
m_context << eth::Instruction::DUP1;
ArrayUtils(m_context).clearDynamicArray(m_arrayType);
}
-