| 378 | } |
| 379 | |
| 380 | void CompilerContext::appendInlineAssembly( |
| 381 | std::string const& _assembly, |
| 382 | std::vector<std::string> const& _localVariables, |
| 383 | std::set<std::string> const& _externallyUsedFunctions, |
| 384 | bool _system, |
| 385 | OptimiserSettings const& _optimiserSettings, |
| 386 | std::string _sourceName |
| 387 | ) |
| 388 | { |
| 389 | unsigned startStackHeight = stackHeight(); |
| 390 | |
| 391 | std::set<yul::YulName> externallyUsedIdentifiers; |
| 392 | for (auto const& fun: _externallyUsedFunctions) |
| 393 | externallyUsedIdentifiers.insert(yul::YulName(fun)); |
| 394 | for (auto const& var: _localVariables) |
| 395 | externallyUsedIdentifiers.insert(yul::YulName(var)); |
| 396 | |
| 397 | yul::ExternalIdentifierAccess identifierAccess; |
| 398 | identifierAccess.resolve = [&]( |
| 399 | yul::Identifier const& _identifier, |
| 400 | yul::IdentifierContext, |
| 401 | bool _insideFunction |
| 402 | ) -> bool |
| 403 | { |
| 404 | if (_insideFunction) |
| 405 | return false; |
| 406 | return util::contains(_localVariables, _identifier.name.str()); |
| 407 | }; |
| 408 | identifierAccess.generateCode = [&]( |
| 409 | yul::Identifier const& _identifier, |
| 410 | yul::IdentifierContext _context, |
| 411 | yul::AbstractAssembly& _assembly |
| 412 | ) |
| 413 | { |
| 414 | solAssert(_context == yul::IdentifierContext::RValue || _context == yul::IdentifierContext::LValue, ""); |
| 415 | auto it = std::find(_localVariables.begin(), _localVariables.end(), _identifier.name.str()); |
| 416 | solAssert(it != _localVariables.end(), ""); |
| 417 | auto stackDepth = static_cast<size_t>(distance(it, _localVariables.end())); |
| 418 | size_t stackDiff = static_cast<size_t>(_assembly.stackHeight()) - startStackHeight + stackDepth; |
| 419 | if (_context == yul::IdentifierContext::LValue) |
| 420 | stackDiff -= 1; |
| 421 | if (stackDiff < 1 || stackDiff > reachableStackDepth()) |
| 422 | BOOST_THROW_EXCEPTION( |
| 423 | StackTooDeepError() << |
| 424 | errinfo_sourceLocation(nativeLocationOf(_identifier)) << |
| 425 | util::errinfo_comment(util::stackTooDeepString) |
| 426 | ); |
| 427 | if (_context == yul::IdentifierContext::RValue) |
| 428 | _assembly.appendInstruction(dupInstruction(static_cast<unsigned>(stackDiff))); |
| 429 | else |
| 430 | { |
| 431 | _assembly.appendInstruction(swapInstruction(static_cast<unsigned>(stackDiff))); |
| 432 | _assembly.appendInstruction(Instruction::POP); |
| 433 | } |
| 434 | }; |
| 435 | |
| 436 | ErrorList errors; |
| 437 | ErrorReporter errorReporter(errors); |
no test coverage detected