aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGav Wood <g@ethdev.com>2015-01-29 08:20:33 +0800
committerGav Wood <g@ethdev.com>2015-01-29 08:20:33 +0800
commit1ea693f3ff2fc10a8f8a94a3e2e2bf862a6d27b8 (patch)
tree8a3e4b4e9388f3f136a32fff3fdbdfae86458db1
parent9f3b2e00b41d26137461875b467089dadefaf1e7 (diff)
parentf377960012d93c91a3bf01a0264fdd2c83fcc7b7 (diff)
downloaddexon-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.cpp51
-rw-r--r--SolidityEndToEndTest.cpp24
-rw-r--r--SolidityExpressionCompiler.cpp8
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)