aboutsummaryrefslogtreecommitdiffstats
path: root/libsolidity/codegen/ExpressionCompiler.cpp
diff options
context:
space:
mode:
authorchriseth <chris@ethereum.org>2019-01-18 07:16:06 +0800
committerGitHub <noreply@github.com>2019-01-18 07:16:06 +0800
commit2ec997e697e306dd54165aad365406ee88c534cb (patch)
tree5e943e23d38e332de3eedd33be11f2cf9df5fd69 /libsolidity/codegen/ExpressionCompiler.cpp
parent0711873a2f13d7b0f27e268fcd0a7683665f339d (diff)
parent2a92403690a4998ab097503231ac39f854b9c76c (diff)
downloaddexon-solidity-2ec997e697e306dd54165aad365406ee88c534cb.tar
dexon-solidity-2ec997e697e306dd54165aad365406ee88c534cb.tar.gz
dexon-solidity-2ec997e697e306dd54165aad365406ee88c534cb.tar.bz2
dexon-solidity-2ec997e697e306dd54165aad365406ee88c534cb.tar.lz
dexon-solidity-2ec997e697e306dd54165aad365406ee88c534cb.tar.xz
dexon-solidity-2ec997e697e306dd54165aad365406ee88c534cb.tar.zst
dexon-solidity-2ec997e697e306dd54165aad365406ee88c534cb.zip
Merge pull request #5775 from ethereum/codeAccess
Provide access to code of contract types.
Diffstat (limited to 'libsolidity/codegen/ExpressionCompiler.cpp')
-rw-r--r--libsolidity/codegen/ExpressionCompiler.cpp38
1 files changed, 22 insertions, 16 deletions
diff --git a/libsolidity/codegen/ExpressionCompiler.cpp b/libsolidity/codegen/ExpressionCompiler.cpp
index be2709ae..e6bb163d 100644
--- a/libsolidity/codegen/ExpressionCompiler.cpp
+++ b/libsolidity/codegen/ExpressionCompiler.cpp
@@ -594,22 +594,8 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
}
ContractDefinition const* contract =
&dynamic_cast<ContractType const&>(*function.returnParameterTypes().front()).contractDefinition();
- m_context.callLowLevelFunction(
- "$copyContractCreationCodeToMemory_" + contract->type()->identifier(),
- 0,
- 1,
- [contract](CompilerContext& _context)
- {
- // copy the contract's code into memory
- eth::Assembly const& assembly = _context.compiledContract(*contract);
- CompilerUtils(_context).fetchFreeMemoryPointer();
- // pushes size
- auto subroutine = _context.addSubroutine(make_shared<eth::Assembly>(assembly));
- _context << Instruction::DUP1 << subroutine;
- _context << Instruction::DUP4 << Instruction::CODECOPY;
- _context << Instruction::ADD;
- }
- );
+ utils().fetchFreeMemoryPointer();
+ utils().copyContractCodeToMemory(*contract, true);
utils().abiEncode(argumentTypes, function.parameterTypes());
// now on stack: memory_end_ptr
// need: size, offset, endowment
@@ -1107,6 +1093,9 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
case FunctionType::Kind::GasLeft:
m_context << Instruction::GAS;
break;
+ case FunctionType::Kind::MetaType:
+ // No code to generate.
+ break;
}
}
return false;
@@ -1348,6 +1337,23 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess)
solAssert(false, "Gas has been removed.");
else if (member == "blockhash")
solAssert(false, "Blockhash has been removed.");
+ else if (member == "creationCode" || member == "runtimeCode")
+ {
+ TypePointer arg = dynamic_cast<MagicType const&>(*_memberAccess.expression().annotation().type).typeArgument();
+ ContractDefinition const& contract = dynamic_cast<ContractType const&>(*arg).contractDefinition();
+ utils().fetchFreeMemoryPointer();
+ m_context << Instruction::DUP1 << u256(32) << Instruction::ADD;
+ utils().copyContractCodeToMemory(contract, member == "creationCode");
+ // Stack: start end
+ m_context.appendInlineAssembly(
+ Whiskers(R"({
+ mstore(start, sub(end, add(start, 0x20)))
+ mstore(<free>, end)
+ })")("free", to_string(CompilerUtils::freeMemoryPointer)).render(),
+ {"start", "end"}
+ );
+ m_context << Instruction::POP;
+ }
else
solAssert(false, "Unknown magic member.");
break;