| 3458 | } |
| 3459 | |
| 3460 | void IRGeneratorForStatements::handleCatch(TryStatement const& _tryStatement) |
| 3461 | { |
| 3462 | setLocation(_tryStatement); |
| 3463 | std::string const runFallback = m_context.newYulVariable(); |
| 3464 | appendCode() << "let " << runFallback << " := 1\n"; |
| 3465 | |
| 3466 | // This function returns zero on "short returndata". We have to add a success flag |
| 3467 | // once we implement custom error codes. |
| 3468 | if (_tryStatement.errorClause() || _tryStatement.panicClause()) |
| 3469 | appendCode() << "switch " << m_utils.returnDataSelectorFunction() << "()\n"; |
| 3470 | |
| 3471 | if (TryCatchClause const* errorClause = _tryStatement.errorClause()) |
| 3472 | { |
| 3473 | appendCode() << "case " << selectorFromSignatureU32("Error(string)") << " {\n"; |
| 3474 | setLocation(*errorClause); |
| 3475 | std::string const dataVariable = m_context.newYulVariable(); |
| 3476 | appendCode() << "let " << dataVariable << " := " << m_utils.tryDecodeErrorMessageFunction() << "()\n"; |
| 3477 | appendCode() << "if " << dataVariable << " {\n"; |
| 3478 | appendCode() << runFallback << " := 0\n"; |
| 3479 | if (errorClause->parameters()) |
| 3480 | { |
| 3481 | solAssert(errorClause->parameters()->parameters().size() == 1); |
| 3482 | IRVariable const& var = m_context.addLocalVariable(*errorClause->parameters()->parameters().front()); |
| 3483 | define(var) << dataVariable << "\n"; |
| 3484 | } |
| 3485 | errorClause->accept(*this); |
| 3486 | setLocation(*errorClause); |
| 3487 | appendCode() << "}\n"; |
| 3488 | setLocation(_tryStatement); |
| 3489 | appendCode() << "}\n"; |
| 3490 | } |
| 3491 | if (TryCatchClause const* panicClause = _tryStatement.panicClause()) |
| 3492 | { |
| 3493 | appendCode() << "case " << selectorFromSignatureU32("Panic(uint256)") << " {\n"; |
| 3494 | setLocation(*panicClause); |
| 3495 | std::string const success = m_context.newYulVariable(); |
| 3496 | std::string const code = m_context.newYulVariable(); |
| 3497 | appendCode() << "let " << success << ", " << code << " := " << m_utils.tryDecodePanicDataFunction() << "()\n"; |
| 3498 | appendCode() << "if " << success << " {\n"; |
| 3499 | appendCode() << runFallback << " := 0\n"; |
| 3500 | if (panicClause->parameters()) |
| 3501 | { |
| 3502 | solAssert(panicClause->parameters()->parameters().size() == 1); |
| 3503 | IRVariable const& var = m_context.addLocalVariable(*panicClause->parameters()->parameters().front()); |
| 3504 | define(var) << code << "\n"; |
| 3505 | } |
| 3506 | panicClause->accept(*this); |
| 3507 | setLocation(*panicClause); |
| 3508 | appendCode() << "}\n"; |
| 3509 | setLocation(_tryStatement); |
| 3510 | appendCode() << "}\n"; |
| 3511 | } |
| 3512 | |
| 3513 | setLocation(_tryStatement); |
| 3514 | appendCode() << "if " << runFallback << " {\n"; |
| 3515 | if (_tryStatement.fallbackClause()) |
| 3516 | handleCatchFallback(*_tryStatement.fallbackClause()); |
| 3517 | else |
nothing calls this directly
no test coverage detected