mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
commit
1ea693f3ff
@ -108,57 +108,6 @@ BOOST_AUTO_TEST_CASE(smoke_test)
|
|||||||
checkCodePresentAt(code, expectation, boilerplateSize);
|
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)
|
BOOST_AUTO_TEST_CASE(ifStatement)
|
||||||
{
|
{
|
||||||
char const* sourceCode = "contract test {\n"
|
char const* sourceCode = "contract test {\n"
|
||||||
|
@ -1930,6 +1930,30 @@ BOOST_AUTO_TEST_CASE(crazy_elementary_typenames_on_stack)
|
|||||||
BOOST_CHECK(callContractFunction("f()") == encodeArgs(u256(-7)));
|
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()
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -86,7 +86,8 @@ Declaration const& resolveDeclaration(vector<string> const& _namespacedName,
|
|||||||
}
|
}
|
||||||
|
|
||||||
bytes compileFirstExpression(const string& _sourceCode, vector<vector<string>> _functions = {},
|
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;
|
Parser parser;
|
||||||
ASTPointer<SourceUnit> sourceUnit;
|
ASTPointer<SourceUnit> sourceUnit;
|
||||||
@ -99,10 +100,12 @@ bytes compileFirstExpression(const string& _sourceCode, vector<vector<string>> _
|
|||||||
NameAndTypeResolver resolver(declarations);
|
NameAndTypeResolver resolver(declarations);
|
||||||
resolver.registerDeclarations(*sourceUnit);
|
resolver.registerDeclarations(*sourceUnit);
|
||||||
|
|
||||||
|
vector<ContractDefinition const*> inheritanceHierarchy;
|
||||||
for (ASTPointer<ASTNode> const& node: sourceUnit->getNodes())
|
for (ASTPointer<ASTNode> const& node: sourceUnit->getNodes())
|
||||||
if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))
|
if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))
|
||||||
{
|
{
|
||||||
BOOST_REQUIRE_NO_THROW(resolver.resolveNamesAndTypes(*contract));
|
BOOST_REQUIRE_NO_THROW(resolver.resolveNamesAndTypes(*contract));
|
||||||
|
inheritanceHierarchy = vector<ContractDefinition const*>(1, contract);
|
||||||
}
|
}
|
||||||
for (ASTPointer<ASTNode> const& node: sourceUnit->getNodes())
|
for (ASTPointer<ASTNode> const& node: sourceUnit->getNodes())
|
||||||
if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))
|
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);
|
BOOST_REQUIRE(extractor.getExpression() != nullptr);
|
||||||
|
|
||||||
CompilerContext context;
|
CompilerContext context;
|
||||||
for (vector<string> const& function: _functions)
|
context.setInheritanceHierarchy(inheritanceHierarchy);
|
||||||
context.addFunction(dynamic_cast<FunctionDefinition const&>(resolveDeclaration(function, resolver)));
|
|
||||||
unsigned parametersSize = _localVariables.size(); // assume they are all one slot on the stack
|
unsigned parametersSize = _localVariables.size(); // assume they are all one slot on the stack
|
||||||
context.adjustStackOffset(parametersSize);
|
context.adjustStackOffset(parametersSize);
|
||||||
for (vector<string> const& variable: _localVariables)
|
for (vector<string> const& variable: _localVariables)
|
||||||
|
Loading…
Reference in New Issue
Block a user