| 2558 | } |
| 2559 | |
| 2560 | void ExpressionCompiler::appendArithmeticOperatorCode(Token _operator, Type const& _type) |
| 2561 | { |
| 2562 | if (_type.category() == Type::Category::FixedPoint) |
| 2563 | solUnimplemented("Not yet implemented - FixedPointType."); |
| 2564 | |
| 2565 | IntegerType const& type = dynamic_cast<IntegerType const&>(_type); |
| 2566 | if (m_context.arithmetic() == Arithmetic::Checked) |
| 2567 | { |
| 2568 | std::string functionName; |
| 2569 | switch (_operator) |
| 2570 | { |
| 2571 | case Token::Add: |
| 2572 | functionName = m_context.utilFunctions().overflowCheckedIntAddFunction(type); |
| 2573 | break; |
| 2574 | case Token::Sub: |
| 2575 | functionName = m_context.utilFunctions().overflowCheckedIntSubFunction(type); |
| 2576 | break; |
| 2577 | case Token::Mul: |
| 2578 | functionName = m_context.utilFunctions().overflowCheckedIntMulFunction(type); |
| 2579 | break; |
| 2580 | case Token::Div: |
| 2581 | functionName = m_context.utilFunctions().overflowCheckedIntDivFunction(type); |
| 2582 | break; |
| 2583 | case Token::Mod: |
| 2584 | functionName = m_context.utilFunctions().intModFunction(type); |
| 2585 | break; |
| 2586 | case Token::Exp: |
| 2587 | // EXP is handled in a different function. |
| 2588 | default: |
| 2589 | solAssert(false, "Unknown arithmetic operator."); |
| 2590 | } |
| 2591 | // TODO Maybe we want to force-inline this? |
| 2592 | m_context.callYulFunction(functionName, 2, 1); |
| 2593 | } |
| 2594 | else |
| 2595 | { |
| 2596 | bool const c_isSigned = type.isSigned(); |
| 2597 | |
| 2598 | switch (_operator) |
| 2599 | { |
| 2600 | case Token::Add: |
| 2601 | m_context << Instruction::ADD; |
| 2602 | break; |
| 2603 | case Token::Sub: |
| 2604 | m_context << Instruction::SUB; |
| 2605 | break; |
| 2606 | case Token::Mul: |
| 2607 | m_context << Instruction::MUL; |
| 2608 | break; |
| 2609 | case Token::Div: |
| 2610 | case Token::Mod: |
| 2611 | { |
| 2612 | // Test for division by zero |
| 2613 | m_context << Instruction::DUP2 << Instruction::ISZERO; |
| 2614 | m_context.appendConditionalPanic(util::PanicCode::DivisionByZero); |
| 2615 | |
| 2616 | if (_operator == Token::Div) |
| 2617 | m_context << (c_isSigned ? Instruction::SDIV : Instruction::DIV); |
nothing calls this directly
no test coverage detected