| 2569 | } |
| 2570 | |
| 2571 | std::string YulUtilFunctions::nextArrayElementFunction(ArrayType const& _type) |
| 2572 | { |
| 2573 | solAssert(!_type.isByteArrayOrString(), ""); |
| 2574 | if (_type.dataStoredIn(DataLocation::Storage)) |
| 2575 | solAssert(_type.baseType()->storageBytes() > 16, ""); |
| 2576 | std::string functionName = "array_nextElement_" + _type.identifier(); |
| 2577 | return m_functionCollector.createFunction(functionName, [&]() { |
| 2578 | Whiskers templ(R"( |
| 2579 | function <functionName>(ptr) -> next { |
| 2580 | next := add(ptr, <advance>) |
| 2581 | } |
| 2582 | )"); |
| 2583 | templ("functionName", functionName); |
| 2584 | switch (_type.location()) |
| 2585 | { |
| 2586 | case DataLocation::Memory: |
| 2587 | templ("advance", "0x20"); |
| 2588 | break; |
| 2589 | case DataLocation::Storage: |
| 2590 | { |
| 2591 | u256 size = _type.baseType()->storageSize(); |
| 2592 | solAssert(size >= 1, ""); |
| 2593 | templ("advance", toCompactHexWithPrefix(size)); |
| 2594 | break; |
| 2595 | } |
| 2596 | case DataLocation::Transient: |
| 2597 | solUnimplemented("Transient data location is only supported for value types."); |
| 2598 | break; |
| 2599 | case DataLocation::CallData: |
| 2600 | { |
| 2601 | u256 size = _type.calldataStride(); |
| 2602 | solAssert(size >= 32 && size % 32 == 0, ""); |
| 2603 | templ("advance", toCompactHexWithPrefix(size)); |
| 2604 | break; |
| 2605 | } |
| 2606 | } |
| 2607 | return templ.render(); |
| 2608 | }); |
| 2609 | } |
| 2610 | |
| 2611 | std::string YulUtilFunctions::copyArrayFromStorageToMemoryFunction(ArrayType const& _from, ArrayType const& _to) |
| 2612 | { |
no test coverage detected