@@ -574,12 +574,15 @@ void evmSetMCopy(zen::runtime::EVMInstance *Instance, uint64_t Dest,
574574}
575575void evmSetReturn (zen::runtime::EVMInstance *Instance, uint64_t Offset,
576576 uint64_t Len) {
577- if (!Instance->expandMemoryChecked (Offset, Len)) {
578- return ;
577+ std::vector<uint8_t > ReturnData;
578+ if (Len > 0 ) {
579+ if (!Instance->expandMemoryChecked (Offset, Len)) {
580+ return ;
581+ }
582+ auto &Memory = Instance->getMemory ();
583+ ReturnData = std::vector<uint8_t >(Memory.begin () + Offset,
584+ Memory.begin () + Offset + Len);
579585 }
580- auto &Memory = Instance->getMemory ();
581- std::vector<uint8_t > ReturnData (Memory.begin () + Offset,
582- Memory.begin () + Offset + Len);
583586 Instance->setReturnData (ReturnData);
584587
585588 evmc::Result ExeResult (EVMC_SUCCESS , 0 ,
@@ -591,6 +594,10 @@ void evmSetReturn(zen::runtime::EVMInstance *Instance, uint64_t Offset,
591594}
592595void evmSetCallDataCopy (zen::runtime::EVMInstance *Instance,
593596 uint64_t DestOffset, uint64_t Offset, uint64_t Size) {
597+ // When Size is 0, no memory operations are needed
598+ if (Size == 0 ) {
599+ return ;
600+ }
594601 if (!Instance->expandMemoryChecked (DestOffset, Size)) {
595602 return ;
596603 }
@@ -626,23 +633,27 @@ void evmSetCallDataCopy(zen::runtime::EVMInstance *Instance,
626633void evmSetExtCodeCopy (zen::runtime::EVMInstance *Instance,
627634 const uint8_t *Address, uint64_t DestOffset,
628635 uint64_t Offset, uint64_t Size) {
629- if (!Instance->expandMemoryChecked (DestOffset, Size)) {
630- return ;
631- }
632- if (uint64_t CopyGas = calculateWordCopyGas (Size)) {
633- Instance->chargeGas (CopyGas);
634- }
635-
636636 const zen::runtime::EVMModule *Module = Instance->getModule ();
637637 ZEN_ASSERT (Module && Module->Host );
638638 evmc::address Addr = loadAddressFromLE (Address);
639-
640639 evmc_revision Rev = Instance->getRevision ();
641640 if (Rev >= EVMC_BERLIN &&
642641 Module->Host ->access_account (Addr) == EVMC_ACCESS_COLD ) {
643642 Instance->chargeGas (zen::evm::ADDITIONAL_COLD_ACCOUNT_ACCESS_COST );
644643 }
645644
645+ // When Size is 0, no memory operations are needed
646+ if (Size == 0 ) {
647+ return ;
648+ }
649+
650+ if (!Instance->expandMemoryChecked (DestOffset, Size)) {
651+ return ;
652+ }
653+ if (uint64_t CopyGas = calculateWordCopyGas (Size)) {
654+ Instance->chargeGas (CopyGas);
655+ }
656+
646657 auto &Memory = Instance->getMemory ();
647658 size_t CodeSize = Module->Host ->get_code_size (Addr);
648659
@@ -665,6 +676,10 @@ void evmSetExtCodeCopy(zen::runtime::EVMInstance *Instance,
665676
666677void evmSetReturnDataCopy (zen::runtime::EVMInstance *Instance,
667678 uint64_t DestOffset, uint64_t Offset, uint64_t Size) {
679+ // When Size is 0, no memory operations are needed
680+ if (Size == 0 ) {
681+ return ;
682+ }
668683 if (!Instance->expandMemoryChecked (DestOffset, Size)) {
669684 return ;
670685 }
@@ -705,14 +720,16 @@ static void evmEmitLogGeneric(zen::runtime::EVMInstance *Instance,
705720 const evmc_message *Msg = Instance->getCurrentMessage ();
706721 ZEN_ASSERT (Msg && " No current message set in EVMInstance" );
707722
708- // Calculate required memory size and charge gas
709- if (!Instance->expandMemoryChecked (Offset, Size)) {
710- return ;
723+ // Only expand memory if we actually need to access it (Size > 0)
724+ const uint8_t *Data = nullptr ;
725+ if (Size > 0 ) {
726+ if (!Instance->expandMemoryChecked (Offset, Size)) {
727+ return ;
728+ }
729+ auto &Memory = Instance->getMemory ();
730+ Data = Memory.data () + Offset;
711731 }
712732
713- auto &Memory = Instance->getMemory ();
714- const uint8_t *Data = Memory.data () + Offset;
715-
716733 // Build topic array - only include non-null topics
717734 evmc::bytes32 Topics[MaxTopics] = {};
718735 size_t ActualNumTopics = 0 ;
@@ -805,13 +822,16 @@ const uint8_t *evmHandleCreateInternal(zen::runtime::EVMInstance *Instance,
805822 }
806823
807824 // Calculate required memory size and charge gas
808- if (!Instance->expandMemoryChecked (Offset, Size)) {
809- Instance->setReturnData ({});
810- return ZeroAddress;
811- }
825+ const uint8_t *InitCode = nullptr ;
826+ if (Size > 0 ) {
827+ if (!Instance->expandMemoryChecked (Offset, Size)) {
828+ Instance->setReturnData ({});
829+ return ZeroAddress;
830+ }
812831
813- auto &Memory = Instance->getMemory ();
814- const uint8_t *InitCode = Memory.data () + Offset;
832+ auto &Memory = Instance->getMemory ();
833+ InitCode = Memory.data () + Offset;
834+ }
815835
816836 // Create message for CREATE/CREATE2
817837 evmc_message CreateMsg = {};
@@ -928,10 +948,15 @@ static uint64_t evmHandleCallInternal(zen::runtime::EVMInstance *Instance,
928948 }
929949
930950 // Calculate required memory sizes for input and output
931- if (!Instance->expandMemoryChecked (ArgsOffset, ArgsSize, RetOffset,
932- RetSize)) {
933- Instance->setReturnData ({});
934- return 0 ;
951+ // Only expand memory if we actually need to access it
952+ bool needArgsMemory = ArgsSize > 0 ;
953+ bool needRetMemory = RetSize > 0 ;
954+ if (needArgsMemory || needRetMemory) {
955+ if (!Instance->expandMemoryChecked (ArgsOffset, ArgsSize, RetOffset,
956+ RetSize)) {
957+ Instance->setReturnData ({});
958+ return 0 ;
959+ }
935960 }
936961
937962 auto &Memory = Instance->getMemory ();
@@ -1088,12 +1113,15 @@ uint64_t evmHandleStaticCall(zen::runtime::EVMInstance *Instance, uint64_t Gas,
10881113
10891114void evmSetRevert (zen::runtime::EVMInstance *Instance, uint64_t Offset,
10901115 uint64_t Size) {
1091- if (!Instance->expandMemoryChecked (Offset, Size)) {
1092- return ;
1116+ std::vector<uint8_t > ReturnData;
1117+ if (Size > 0 ) {
1118+ if (!Instance->expandMemoryChecked (Offset, Size)) {
1119+ return ;
1120+ }
1121+ auto &Memory = Instance->getMemory ();
1122+ ReturnData = std::vector<uint8_t >(Memory.begin () + Offset,
1123+ Memory.begin () + Offset + Size);
10931124 }
1094- auto &Memory = Instance->getMemory ();
1095- std::vector<uint8_t > ReturnData (Memory.begin () + Offset,
1096- Memory.begin () + Offset + Size);
10971125 Instance->setReturnData (std::move (ReturnData));
10981126 const int64_t GasLeft =
10991127 Instance ? static_cast <int64_t >(Instance->getGas ()) : 0 ;
@@ -1107,6 +1135,10 @@ void evmSetRevert(zen::runtime::EVMInstance *Instance, uint64_t Offset,
11071135
11081136void evmSetCodeCopy (zen::runtime::EVMInstance *Instance, uint64_t DestOffset,
11091137 uint64_t Offset, uint64_t Size) {
1138+ // When Size is 0, no memory operations are needed
1139+ if (Size == 0 ) {
1140+ return ;
1141+ }
11101142 if (!Instance->expandMemoryChecked (DestOffset, Size)) {
11111143 return ;
11121144 }
@@ -1136,15 +1168,17 @@ void evmSetCodeCopy(zen::runtime::EVMInstance *Instance, uint64_t DestOffset,
11361168
11371169const uint8_t *evmGetKeccak256 (zen::runtime::EVMInstance *Instance,
11381170 uint64_t Offset, uint64_t Length) {
1139- if (!Instance->expandMemoryChecked (Offset, Length)) {
1140- return nullptr ;
1171+ const uint8_t *InputData = nullptr ;
1172+ if (Length > 0 ) {
1173+ if (!Instance->expandMemoryChecked (Offset, Length)) {
1174+ return nullptr ;
1175+ }
1176+ const uint64_t ExtraGas =
1177+ static_cast <uint64_t >(numWords (static_cast <uint64_t >(Length))) * 6 ;
1178+ Instance->chargeGas (ExtraGas);
1179+ auto &Memory = Instance->getMemory ();
1180+ InputData = Memory.data () + Offset;
11411181 }
1142- const uint64_t ExtraGas =
1143- static_cast <uint64_t >(numWords (static_cast <uint64_t >(Length))) * 6 ;
1144- Instance->chargeGas (ExtraGas);
1145-
1146- auto &Memory = Instance->getMemory ();
1147- const uint8_t *InputData = Memory.data () + Offset;
11481182
11491183 auto &Cache = Instance->getMessageCache ();
11501184 evmc::bytes32 HashResult;
0 commit comments