diff options
author | Gav Wood <g@ethdev.com> | 2015-01-29 08:20:33 +0800 |
---|---|---|
committer | Gav Wood <g@ethdev.com> | 2015-01-29 08:20:33 +0800 |
commit | 1ea693f3ff2fc10a8f8a94a3e2e2bf862a6d27b8 (patch) | |
tree | 8a3e4b4e9388f3f136a32fff3fdbdfae86458db1 | |
parent | 9f3b2e00b41d26137461875b467089dadefaf1e7 (diff) | |
parent | f377960012d93c91a3bf01a0264fdd2c83fcc7b7 (diff) | |
download | dexon-solidity-1ea693f3ff2fc10a8f8a94a3e2e2bf862a6d27b8.tar.gz dexon-solidity-1ea693f3ff2fc10a8f8a94a3e2e2bf862a6d27b8.tar.zst dexon-solidity-1ea693f3ff2fc10a8f8a94a3e2e2bf862a6d27b8.zip |
Merge pull request #877 from chriseth/sol_super
Super keyword.
-rw-r--r-- | SolidityCompiler.cpp | 51 | ||||
-rw-r--r-- | SolidityEndToEndTest.cpp | 24 | ||||
-rw-r--r-- | SolidityExpressionCompiler.cpp | 8 |
3 files changed, 29 insertions, 54 deletions
diff --git a/SolidityCompiler.cpp b/SolidityCompiler.cpp index 53daa9df..98397af7 100644 --- a/SolidityCompiler.cpp +++ b/SolidityCompiler.cpp @@ -108,57 +108,6 @@ BOOST_AUTO_TEST_CASE(smoke_test) checkCodePresentAt(code, expectation, boilerplateSize); } -BOOST_AUTO_TEST_CASE(different_argument_numbers) -{ - char const* sourceCode = "contract test {\n" - " function f(uint a, uint b, uint c) returns(uint d) { return b; }\n" - " function g() returns (uint e, uint h) { h = f(1, 2, 3); }\n" - "}\n"; - bytes code = compileContract(sourceCode); - unsigned shift = 103; - unsigned boilerplateSize = 116; - bytes expectation({byte(Instruction::JUMPDEST), - byte(Instruction::PUSH1), 0x0, // initialize return variable d - byte(Instruction::DUP3), - byte(Instruction::SWAP1), // assign b to d - byte(Instruction::POP), - byte(Instruction::PUSH1), byte(0xa + shift), // jump to return - byte(Instruction::JUMP), - byte(Instruction::JUMPDEST), - byte(Instruction::SWAP4), // store d and fetch return address - byte(Instruction::SWAP3), // store return address - byte(Instruction::POP), - byte(Instruction::POP), - byte(Instruction::POP), - byte(Instruction::JUMP), // end of f - byte(Instruction::JUMPDEST), // beginning of g - byte(Instruction::PUSH1), 0x0, - byte(Instruction::PUSH1), 0x0, // initialized e and h - byte(Instruction::PUSH1), byte(0x21 + shift), // ret address - byte(Instruction::PUSH1), 0x1, - byte(Instruction::PUSH1), 0x2, - byte(Instruction::PUSH1), 0x3, - byte(Instruction::PUSH1), byte(0x1 + shift), - // stack here: ret e h 0x20 1 2 3 0x1 - byte(Instruction::JUMP), - byte(Instruction::JUMPDEST), - // stack here: ret e h f(1,2,3) - byte(Instruction::SWAP1), - // stack here: ret e f(1,2,3) h - byte(Instruction::POP), - byte(Instruction::DUP1), // retrieve it again as "value of expression" - byte(Instruction::POP), // end of assignment - // stack here: ret e f(1,2,3) - byte(Instruction::JUMPDEST), - byte(Instruction::SWAP1), - // ret e f(1,2,3) - byte(Instruction::SWAP2), - // f(1,2,3) e ret - byte(Instruction::JUMP) // end of g - }); - checkCodePresentAt(code, expectation, boilerplateSize); -} - BOOST_AUTO_TEST_CASE(ifStatement) { char const* sourceCode = "contract test {\n" diff --git a/SolidityEndToEndTest.cpp b/SolidityEndToEndTest.cpp index 1ddb2273..1450095a 100644 --- a/SolidityEndToEndTest.cpp +++ b/SolidityEndToEndTest.cpp @@ -1930,6 +1930,30 @@ BOOST_AUTO_TEST_CASE(crazy_elementary_typenames_on_stack) BOOST_CHECK(callContractFunction("f()") == encodeArgs(u256(-7))); } +BOOST_AUTO_TEST_CASE(super) +{ + char const* sourceCode = R"( + contract A { function f() returns (uint r) { return 1; } } + contract B is A { function f() returns (uint r) { return super.f() | 2; } } + contract C is A { function f() returns (uint r) { return super.f() | 4; } } + contract D is B, C { function f() returns (uint r) { return super.f() | 8; } } + )"; + compileAndRun(sourceCode, 0, "D"); + BOOST_CHECK(callContractFunction("f()") == encodeArgs(1 | 2 | 4 | 8)); +} + +BOOST_AUTO_TEST_CASE(super_in_constructor) +{ + char const* sourceCode = R"( + contract A { function f() returns (uint r) { return 1; } } + contract B is A { function f() returns (uint r) { return super.f() | 2; } } + contract C is A { function f() returns (uint r) { return super.f() | 4; } } + contract D is B, C { uint data; function D() { data = super.f() | 8; } function f() returns (uint r) { return data; } } + )"; + compileAndRun(sourceCode, 0, "D"); + BOOST_CHECK(callContractFunction("f()") == encodeArgs(1 | 2 | 4 | 8)); +} + BOOST_AUTO_TEST_SUITE_END() } diff --git a/SolidityExpressionCompiler.cpp b/SolidityExpressionCompiler.cpp index 06c252db..a0cca3a3 100644 --- a/SolidityExpressionCompiler.cpp +++ b/SolidityExpressionCompiler.cpp @@ -86,7 +86,8 @@ Declaration const& resolveDeclaration(vector<string> const& _namespacedName, } bytes compileFirstExpression(const string& _sourceCode, vector<vector<string>> _functions = {}, - vector<vector<string>> _localVariables = {}, vector<shared_ptr<MagicVariableDeclaration const>> _globalDeclarations = {}) + vector<vector<string>> _localVariables = {}, + vector<shared_ptr<MagicVariableDeclaration const>> _globalDeclarations = {}) { Parser parser; ASTPointer<SourceUnit> sourceUnit; @@ -99,10 +100,12 @@ bytes compileFirstExpression(const string& _sourceCode, vector<vector<string>> _ NameAndTypeResolver resolver(declarations); resolver.registerDeclarations(*sourceUnit); + vector<ContractDefinition const*> inheritanceHierarchy; for (ASTPointer<ASTNode> const& node: sourceUnit->getNodes()) if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get())) { BOOST_REQUIRE_NO_THROW(resolver.resolveNamesAndTypes(*contract)); + inheritanceHierarchy = vector<ContractDefinition const*>(1, contract); } for (ASTPointer<ASTNode> const& node: sourceUnit->getNodes()) if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get())) @@ -116,8 +119,7 @@ bytes compileFirstExpression(const string& _sourceCode, vector<vector<string>> _ BOOST_REQUIRE(extractor.getExpression() != nullptr); CompilerContext context; - for (vector<string> const& function: _functions) - context.addFunction(dynamic_cast<FunctionDefinition const&>(resolveDeclaration(function, resolver))); + context.setInheritanceHierarchy(inheritanceHierarchy); unsigned parametersSize = _localVariables.size(); // assume they are all one slot on the stack context.adjustStackOffset(parametersSize); for (vector<string> const& variable: _localVariables) |