Merge pull request #1072 from chriseth/sol_external

bytes ABI type and external visibility specifier
This commit is contained in:
Gav Wood 2015-02-17 19:38:35 +01:00
commit a86ee7f011
4 changed files with 149 additions and 8 deletions

View File

@ -96,7 +96,7 @@ BOOST_AUTO_TEST_CASE(smoke_test)
"}\n"; "}\n";
bytes code = compileContract(sourceCode); bytes code = compileContract(sourceCode);
unsigned boilerplateSize = 69; unsigned boilerplateSize = 70;
bytes expectation({byte(Instruction::JUMPDEST), bytes expectation({byte(Instruction::JUMPDEST),
byte(Instruction::PUSH1), 0x0, // initialize local variable x byte(Instruction::PUSH1), 0x0, // initialize local variable x
byte(Instruction::PUSH1), 0x2, byte(Instruction::PUSH1), 0x2,
@ -114,8 +114,8 @@ BOOST_AUTO_TEST_CASE(ifStatement)
" function f() { bool x; if (x) 77; else if (!x) 78; else 79; }" " function f() { bool x; if (x) 77; else if (!x) 78; else 79; }"
"}\n"; "}\n";
bytes code = compileContract(sourceCode); bytes code = compileContract(sourceCode);
unsigned shift = 56; unsigned shift = 57;
unsigned boilerplateSize = 69; unsigned boilerplateSize = 70;
bytes expectation({byte(Instruction::JUMPDEST), bytes expectation({byte(Instruction::JUMPDEST),
byte(Instruction::PUSH1), 0x0, byte(Instruction::PUSH1), 0x0,
byte(Instruction::DUP1), byte(Instruction::DUP1),
@ -155,8 +155,8 @@ BOOST_AUTO_TEST_CASE(loops)
" function f() { while(true){1;break;2;continue;3;return;4;} }" " function f() { while(true){1;break;2;continue;3;return;4;} }"
"}\n"; "}\n";
bytes code = compileContract(sourceCode); bytes code = compileContract(sourceCode);
unsigned shift = 56; unsigned shift = 57;
unsigned boilerplateSize = 69; unsigned boilerplateSize = 70;
bytes expectation({byte(Instruction::JUMPDEST), bytes expectation({byte(Instruction::JUMPDEST),
byte(Instruction::JUMPDEST), byte(Instruction::JUMPDEST),
byte(Instruction::PUSH1), 0x1, byte(Instruction::PUSH1), 0x1,

View File

@ -2283,9 +2283,9 @@ BOOST_AUTO_TEST_CASE(bytes_from_calldata_to_memory)
} }
)"; )";
compileAndRun(sourceCode); compileAndRun(sourceCode);
bytes calldata = bytes(61, 0x22) + bytes(12, 0x12); bytes calldata1 = bytes(61, 0x22) + bytes(12, 0x12);
sendMessage(calldata, false); sendMessage(calldata1, false);
BOOST_CHECK(m_output == encodeArgs(dev::sha3(bytes{'a', 'b', 'c'} + calldata))); BOOST_CHECK(m_output == encodeArgs(dev::sha3(bytes{'a', 'b', 'c'} + calldata1)));
} }
BOOST_AUTO_TEST_CASE(call_forward_bytes) BOOST_AUTO_TEST_CASE(call_forward_bytes)
@ -2534,6 +2534,49 @@ BOOST_AUTO_TEST_CASE(constructing_enums_from_ints)
BOOST_CHECK(callContractFunction("test()") == encodeArgs(1)); BOOST_CHECK(callContractFunction("test()") == encodeArgs(1));
} }
BOOST_AUTO_TEST_CASE(external_function)
{
char const* sourceCode = R"(
contract c {
function f(uint a) returns (uint) { return a; }
function test(uint a, uint b) external returns (uint r_a, uint r_b) {
r_a = f(a + 7);
r_b = b;
}
}
)";
compileAndRun(sourceCode);
BOOST_CHECK(callContractFunction("test(uint256,uint256)", 2, 3) == encodeArgs(2+7, 3));
}
BOOST_AUTO_TEST_CASE(bytes_in_arguments)
{
char const* sourceCode = R"(
contract c {
uint result;
function f(uint a, uint b) { result += a + b; }
function g(uint a) { result *= a; }
function test(uint a, bytes data1, bytes data2, uint b) external returns (uint r_a, uint r, uint r_b, uint l) {
r_a = a;
this.call(data1);
this.call(data2);
r = result;
r_b = b;
l = data1.length;
}
}
)";
compileAndRun(sourceCode);
string innercalldata1 = asString(FixedHash<4>(dev::sha3("f(uint256,uint256)")).asBytes() + encodeArgs(8, 9));
bytes calldata1 = encodeArgs(u256(innercalldata1.length()), 12, innercalldata1, 13);
string innercalldata2 = asString(FixedHash<4>(dev::sha3("g(uint256)")).asBytes() + encodeArgs(3));
bytes calldata = encodeArgs(
u256(innercalldata1.length()), u256(innercalldata2.length()),
12, innercalldata1, innercalldata2, 13);
BOOST_CHECK(callContractFunction("test(uint256,bytes,bytes,uint256)", calldata)
== encodeArgs(12, (8 + 9) * 3, 13, u256(innercalldata1.length())));
}
BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE_END()
} }

View File

@ -1083,6 +1083,86 @@ BOOST_AUTO_TEST_CASE(enum_duplicate_values)
BOOST_CHECK_THROW(parseTextAndResolveNames(text), DeclarationError); BOOST_CHECK_THROW(parseTextAndResolveNames(text), DeclarationError);
} }
BOOST_AUTO_TEST_CASE(private_visibility)
{
char const* sourceCode = R"(
contract base {
function f() private {}
}
contract derived is base {
function g() { f(); }
}
)";
BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), DeclarationError);
}
BOOST_AUTO_TEST_CASE(private_visibility_via_explicit_base_access)
{
char const* sourceCode = R"(
contract base {
function f() private {}
}
contract derived is base {
function g() { base.f(); }
}
)";
BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), TypeError);
}
BOOST_AUTO_TEST_CASE(external_visibility)
{
char const* sourceCode = R"(
contract c {
function f() external {}
function g() { f(); }
}
)";
BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), DeclarationError);
}
BOOST_AUTO_TEST_CASE(external_base_visibility)
{
char const* sourceCode = R"(
contract base {
function f() external {}
}
contract derived is base {
function g() { base.f(); }
}
)";
BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), TypeError);
}
BOOST_AUTO_TEST_CASE(external_argument_assign)
{
char const* sourceCode = R"(
contract c {
function f(uint a) external { a = 1; }
}
)";
BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), TypeError);
}
BOOST_AUTO_TEST_CASE(external_argument_increment)
{
char const* sourceCode = R"(
contract c {
function f(uint a) external { a++; }
}
)";
BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), TypeError);
}
BOOST_AUTO_TEST_CASE(external_argument_delete)
{
char const* sourceCode = R"(
contract c {
function f(uint a) external { delete a; }
}
)";
BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), TypeError);
}
BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE_END()
} }

View File

@ -735,6 +735,24 @@ BOOST_AUTO_TEST_CASE(malformed_enum_declaration)
BOOST_CHECK_THROW(parseText(text), ParserError); BOOST_CHECK_THROW(parseText(text), ParserError);
} }
BOOST_AUTO_TEST_CASE(external_function)
{
char const* text = R"(
contract c {
function x() external {}
})";
BOOST_CHECK_NO_THROW(parseTextExplainError(text));
}
BOOST_AUTO_TEST_CASE(external_variable)
{
char const* text = R"(
contract c {
uint external x;
})";
BOOST_CHECK_THROW(parseText(text), ParserError);
}
BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE_END()
} }