| 221 | } |
| 222 | |
| 223 | SubAssemblyID ContractCompiler::deployLibrary(ContractDefinition const& _contract) |
| 224 | { |
| 225 | solAssert(!!m_runtimeCompiler, ""); |
| 226 | solAssert(_contract.isLibrary(), "Tried to deploy contract as library."); |
| 227 | |
| 228 | appendMissingFunctions(); |
| 229 | m_runtimeCompiler->appendMissingFunctions(); |
| 230 | |
| 231 | CompilerContext::LocationSetter locationSetter(m_context, _contract); |
| 232 | |
| 233 | solAssert(!m_context.runtimeSub().empty(), "Runtime sub not registered"); |
| 234 | m_context.pushSubroutineSize(m_context.runtimeSub()); |
| 235 | m_context.pushSubroutineOffset(m_context.runtimeSub()); |
| 236 | // This code replaces the address added by appendDeployTimeAddress(). |
| 237 | m_context.appendInlineAssembly( |
| 238 | util::Whiskers(R"( |
| 239 | { |
| 240 | // If code starts at 11, an mstore(0) writes to the full PUSH20 plus data |
| 241 | // without the need for a shift. |
| 242 | let codepos := 11 |
| 243 | codecopy(codepos, subOffset, subSize) |
| 244 | // Check that the first opcode is a PUSH20 |
| 245 | if iszero(eq(0x73, byte(0, mload(codepos)))) { |
| 246 | mstore(0, <panicSelector>) |
| 247 | mstore(4, <panicCode>) |
| 248 | revert(0, 0x24) |
| 249 | } |
| 250 | mstore(0, address()) |
| 251 | mstore8(codepos, 0x73) |
| 252 | return(codepos, subSize) |
| 253 | } |
| 254 | )") |
| 255 | ("panicSelector", util::selectorFromSignatureU256("Panic(uint256)").str()) |
| 256 | ("panicCode", "0") |
| 257 | .render(), |
| 258 | {"subSize", "subOffset"} |
| 259 | ); |
| 260 | |
| 261 | return m_context.runtimeSub(); |
| 262 | } |
| 263 | |
| 264 | void ContractCompiler::appendBaseConstructor(FunctionDefinition const& _constructor) |
| 265 | { |
nothing calls this directly
no test coverage detected