fixing rebase conflicts

add ElementaryTypes::BytesMemory and ElementaryTypes::StringMemory

fix rebase conflicts

fixing rebase conflicts

use make_shared instead of new

fix tabs and StateMutability parameter

create address and addressType functions, fix spaces in comment

fix typo and switch nonpayable to payable

fix spaces

fix comment again
This commit is contained in:
Jordan Last 2018-09-13 14:29:12 -06:00
parent e7daed68c1
commit d0497aacc0
4 changed files with 16 additions and 9 deletions

View File

@ -92,7 +92,7 @@ To run a subset of tests, filters can be used:
``soltest -t TestSuite/TestName -- --ipcpath /tmp/testeth/geth.ipc --testpath ./test``, ``soltest -t TestSuite/TestName -- --ipcpath /tmp/testeth/geth.ipc --testpath ./test``,
where ``TestName`` can be a wildcard ``*``. where ``TestName`` can be a wildcard ``*``.
Alternatively, there is a testing script at ``scripts/test.sh`` which executes all tests and runs Alternatively, there is a testing script at ``scripts/tests.sh`` which executes all tests and runs
``cpp-ethereum`` automatically if it is in the path (but does not download it). ``cpp-ethereum`` automatically if it is in the path (but does not download it).
Travis CI even runs some additional tests (including ``solc-js`` and testing third party Solidity frameworks) that require compiling the Emscripten target. Travis CI even runs some additional tests (including ``solc-js`` and testing third party Solidity frameworks) that require compiling the Emscripten target.

View File

@ -535,7 +535,7 @@ TypePointers TypeChecker::typeCheckABIDecodeAndRetrieveReturnType(FunctionCall c
toString(arguments.size()) + toString(arguments.size()) +
" were provided." " were provided."
); );
if (arguments.size() >= 1 && !type(*arguments.front())->isImplicitlyConvertibleTo(ArrayType(DataLocation::Memory))) if (arguments.size() >= 1 && !type(*arguments.front())->isImplicitlyConvertibleTo(ArrayType::bytesMemory()))
m_errorReporter.typeError( m_errorReporter.typeError(
arguments.front()->location(), arguments.front()->location(),
"Invalid type for argument in function call. " "Invalid type for argument in function call. "
@ -2131,7 +2131,7 @@ bool TypeChecker::visit(MemberAccess const& _memberAccess)
"after argument-dependent lookup in " + exprType->toString() + "after argument-dependent lookup in " + exprType->toString() +
(memberName == "value" ? " - did you forget the \"payable\" modifier?" : "."); (memberName == "value" ? " - did you forget the \"payable\" modifier?" : ".");
if (exprType->category() == Type::Category::Contract) if (exprType->category() == Type::Category::Contract)
for (auto const& addressMember: AddressType(StateMutability::Payable).nativeMembers(nullptr)) for (auto const& addressMember: AddressType::addressPayable().nativeMembers(nullptr))
if (addressMember.name == memberName) if (addressMember.name == memberName)
{ {
Identifier const* var = dynamic_cast<Identifier const*>(&_memberAccess.expression()); Identifier const* var = dynamic_cast<Identifier const*>(&_memberAccess.expression());

View File

@ -319,6 +319,9 @@ protected:
class AddressType: public Type class AddressType: public Type
{ {
public: public:
static AddressType& address() { static std::shared_ptr<AddressType> addr(std::make_shared<AddressType>(StateMutability::NonPayable)); return *addr; }
static AddressType& addressPayable() { static std::shared_ptr<AddressType> addr(std::make_shared<AddressType>(StateMutability::Payable)); return *addr; }
virtual Category category() const override { return Category::Address; } virtual Category category() const override { return Category::Address; }
explicit AddressType(StateMutability _stateMutability); explicit AddressType(StateMutability _stateMutability);
@ -361,6 +364,7 @@ public:
{ {
Unsigned, Signed Unsigned, Signed
}; };
virtual Category category() const override { return Category::Integer; } virtual Category category() const override { return Category::Integer; }
explicit IntegerType(unsigned _bits, Modifier _modifier = Modifier::Unsigned); explicit IntegerType(unsigned _bits, Modifier _modifier = Modifier::Unsigned);
@ -661,6 +665,9 @@ protected:
class ArrayType: public ReferenceType class ArrayType: public ReferenceType
{ {
public: public:
static ArrayType& bytesMemory() { static std::shared_ptr<ArrayType> addr(std::make_shared<ArrayType>(DataLocation::Memory)); return *addr; }
static ArrayType& stringMemory() { static std::shared_ptr<ArrayType> addr(std::make_shared<ArrayType>(DataLocation::Memory, true)); return *addr; }
virtual Category category() const override { return Category::Array; } virtual Category category() const override { return Category::Array; }
/// Constructor for a byte array ("bytes") and string. /// Constructor for a byte array ("bytes") and string.

View File

@ -710,9 +710,9 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
arguments.front()->accept(*this); arguments.front()->accept(*this);
// Optimization: If type is bytes or string, then do not encode, // Optimization: If type is bytes or string, then do not encode,
// but directly compute keccak256 on memory. // but directly compute keccak256 on memory.
if (*argType == ArrayType(DataLocation::Memory) || *argType == ArrayType(DataLocation::Memory, true)) if (*argType == ArrayType::bytesMemory() || *argType == ArrayType::stringMemory())
{ {
ArrayUtils(m_context).retrieveLength(ArrayType(DataLocation::Memory)); ArrayUtils(m_context).retrieveLength(ArrayType::bytesMemory());
m_context << Instruction::SWAP1 << u256(0x20) << Instruction::ADD; m_context << Instruction::SWAP1 << u256(0x20) << Instruction::ADD;
} }
else else
@ -1086,7 +1086,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
utils().abiDecode(targetTypes, false); utils().abiDecode(targetTypes, false);
else else
{ {
utils().convertType(*firstArgType, ArrayType(DataLocation::Memory)); utils().convertType(*firstArgType, ArrayType::bytesMemory());
m_context << Instruction::DUP1 << u256(32) << Instruction::ADD; m_context << Instruction::DUP1 << u256(32) << Instruction::ADD;
m_context << Instruction::SWAP1 << Instruction::MLOAD; m_context << Instruction::SWAP1 << Instruction::MLOAD;
// stack now: <mem_pos> <length> // stack now: <mem_pos> <length>
@ -1259,7 +1259,7 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess)
identifier = FunctionType(*function).externalIdentifier(); identifier = FunctionType(*function).externalIdentifier();
else else
solAssert(false, "Contract member is neither variable nor function."); solAssert(false, "Contract member is neither variable nor function.");
utils().convertType(type, AddressType(type.isPayable() ? StateMutability::Payable : StateMutability::NonPayable), true); utils().convertType(type, type.isPayable() ? AddressType::addressPayable() : AddressType::address(), true);
m_context << identifier; m_context << identifier;
} }
else else
@ -1277,7 +1277,7 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess)
{ {
utils().convertType( utils().convertType(
*_memberAccess.expression().annotation().type, *_memberAccess.expression().annotation().type,
AddressType(StateMutability::NonPayable), AddressType::address(),
true true
); );
m_context << Instruction::BALANCE; m_context << Instruction::BALANCE;
@ -1294,7 +1294,7 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess)
else if ((set<string>{"call", "callcode", "delegatecall", "staticcall"}).count(member)) else if ((set<string>{"call", "callcode", "delegatecall", "staticcall"}).count(member))
utils().convertType( utils().convertType(
*_memberAccess.expression().annotation().type, *_memberAccess.expression().annotation().type,
AddressType(StateMutability::NonPayable), AddressType::address(),
true true
); );
else else