| 1441 | } |
| 1442 | |
| 1443 | void ContractCompiler::appendModifierOrFunctionCode() |
| 1444 | { |
| 1445 | solAssert(m_currentFunction, ""); |
| 1446 | unsigned stackSurplus = 0; |
| 1447 | Block const* codeBlock = nullptr; |
| 1448 | std::vector<VariableDeclaration const*> addedVariables; |
| 1449 | |
| 1450 | m_modifierDepth++; |
| 1451 | m_context.setModifierDepth(m_modifierDepth); |
| 1452 | |
| 1453 | if (m_modifierDepth >= m_currentFunction->modifiers().size()) |
| 1454 | { |
| 1455 | solAssert(m_currentFunction->isImplemented(), ""); |
| 1456 | codeBlock = &m_currentFunction->body(); |
| 1457 | } |
| 1458 | else |
| 1459 | { |
| 1460 | ASTPointer<ModifierInvocation> const& modifierInvocation = m_currentFunction->modifiers()[m_modifierDepth]; |
| 1461 | |
| 1462 | // constructor call should be excluded |
| 1463 | if (dynamic_cast<ContractDefinition const*>(modifierInvocation->name().annotation().referencedDeclaration)) |
| 1464 | appendModifierOrFunctionCode(); |
| 1465 | else |
| 1466 | { |
| 1467 | ModifierDefinition const& referencedModifier = dynamic_cast<ModifierDefinition const&>( |
| 1468 | *modifierInvocation->name().annotation().referencedDeclaration |
| 1469 | ); |
| 1470 | VirtualLookup lookup = *modifierInvocation->name().annotation().requiredLookup; |
| 1471 | solAssert(lookup == VirtualLookup::Virtual || lookup == VirtualLookup::Static, ""); |
| 1472 | ModifierDefinition const& modifier = |
| 1473 | lookup == VirtualLookup::Virtual ? |
| 1474 | referencedModifier.resolveVirtual(m_context.mostDerivedContract()) : |
| 1475 | referencedModifier; |
| 1476 | |
| 1477 | CompilerContext::LocationSetter locationSetter(m_context, modifier); |
| 1478 | std::vector<ASTPointer<Expression>> const& modifierArguments = |
| 1479 | modifierInvocation->arguments() ? *modifierInvocation->arguments() : std::vector<ASTPointer<Expression>>(); |
| 1480 | |
| 1481 | solAssert(modifier.parameters().size() == modifierArguments.size(), ""); |
| 1482 | for (unsigned i = 0; i < modifier.parameters().size(); ++i) |
| 1483 | { |
| 1484 | m_context.addVariable(*modifier.parameters()[i]); |
| 1485 | addedVariables.push_back(modifier.parameters()[i].get()); |
| 1486 | compileExpression( |
| 1487 | *modifierArguments[i], |
| 1488 | modifier.parameters()[i]->annotation().type |
| 1489 | ); |
| 1490 | } |
| 1491 | |
| 1492 | stackSurplus = CompilerUtils::sizeOnStack(modifier.parameters()); |
| 1493 | codeBlock = &modifier.body(); |
| 1494 | } |
| 1495 | } |
| 1496 | |
| 1497 | if (codeBlock) |
| 1498 | { |
| 1499 | m_context.setArithmetic(Arithmetic::Checked); |
| 1500 |
nothing calls this directly
no test coverage detected