27 auto offset =
static_cast<size_t>(_sp[0]);
28 s512 bigIndex = _sp[1];
29 auto index =
static_cast<size_t>(bigIndex);
30 auto size =
static_cast<size_t>(_sp[2]);
32 size_t sizeToBeCopied = bigIndex + size > _data.
size() ? _data.
size() < bigIndex ? 0 : _data.
size() - index : size;
34 if (sizeToBeCopied > 0)
35 std::memcpy(m_mem.data() + offset, _data.
data() + index, sizeToBeCopied);
36 if (size > sizeToBeCopied)
37 std::memset(m_mem.data() + offset + sizeToBeCopied, 0, size - sizeToBeCopied);
43 void LegacyVM::throwOutOfGas()
48 void LegacyVM::throwBadInstruction()
53 void LegacyVM::throwBadJumpDestination()
58 void LegacyVM::throwDisallowedStateChange()
60 BOOST_THROW_EXCEPTION(DisallowedStateChange());
66 void LegacyVM::throwBadStack(
unsigned _removed,
unsigned _added)
68 bigint size = m_stackEnd - m_SPP;
89 void LegacyVM::throwBufferOverrun(
bigint const& _endOfAccess)
97 int64_t LegacyVM::verifyJumpDest(
u256 const& _dest,
bool _throw)
100 if (_dest <= 0x7FFFFFFFFFFFFFFF) {
104 uint64_t pc = uint64_t(_dest);
105 if (std::binary_search(m_jumpDests.begin(), m_jumpDests.end(), pc))
109 throwBadJumpDestination();
118 void LegacyVM::caseCreate()
120 m_bounce = &LegacyVM::interpretCases;
121 m_runGas = toInt63(m_schedule->createGas);
124 u256 const endowment = m_SP[0];
125 u256 const initOff = m_SP[1];
126 u256 const initSize = m_SP[2];
129 if (m_OP == Instruction::CREATE2)
133 m_runGas += toInt63((
u512{initSize} + 31) / 32 * m_schedule->sha3WordGas);
136 updateMem(memNeed(initOff, initSize));
140 m_returnData.clear();
142 if (m_ext->balance(m_ext->myAddress) >= endowment && m_ext->depth < 1024)
144 *m_io_gas_p = m_io_gas;
145 u256 createGas = *m_io_gas_p;
146 if (!m_schedule->staticCallDepthLimit())
147 createGas -= createGas / 64;
148 u256 gas = createGas;
151 auto off =
static_cast<size_t>(initOff);
152 auto size =
static_cast<size_t>(initSize);
156 CreateResult result = m_ext->create(endowment, gas, initCode, m_OP, salt, m_onOp);
160 *m_io_gas_p -= (createGas - gas);
161 m_io_gas = uint64_t(*m_io_gas_p);
168 void LegacyVM::caseCall()
170 m_bounce = &LegacyVM::interpretCases;
177 m_returnData.clear();
180 if (caseCallSetup(callParams.get(), output))
193 m_SPP[0] = result.
status == EVMC_SUCCESS ? 1 : 0;
197 m_io_gas += uint64_t(callParams->gas);
207 m_runGas = toInt63(m_schedule->callGas);
209 callParams->
staticCall = (m_OP == Instruction::STATICCALL || m_ext->staticCall);
211 bool const haveValueArg = m_OP == Instruction::CALL || m_OP == Instruction::CALLCODE;
214 if (m_OP == Instruction::CALL && !m_ext->exists(destinationAddr))
215 if (m_SP[2] > 0 || m_schedule->zeroValueTransferChargesNewAccountGas())
216 m_runGas += toInt63(m_schedule->callNewAccountGas);
218 if (haveValueArg && m_SP[2] > 0)
219 m_runGas += toInt63(m_schedule->callValueTransferGas);
221 size_t const sizesOffset = haveValueArg ? 3 : 2;
222 u256 inputOffset = m_SP[sizesOffset];
223 u256 inputSize = m_SP[sizesOffset + 1];
224 u256 outputOffset = m_SP[sizesOffset + 2];
225 u256 outputSize = m_SP[sizesOffset + 3];
226 uint64_t inputMemNeed = memNeed(inputOffset, inputSize);
227 uint64_t outputMemNeed = memNeed(outputOffset, outputSize);
229 m_newMemSize = std::max(inputMemNeed, outputMemNeed);
230 updateMem(m_newMemSize);
234 if (m_schedule->staticCallDepthLimit())
237 callParams->
gas = m_SP[0];
242 u256 maxAllowedCallGas = m_io_gas - m_io_gas / 64;
243 callParams->
gas = std::min(m_SP[0], maxAllowedCallGas);
246 m_runGas = toInt63(callParams->
gas);
249 if (haveValueArg && m_SP[2] > 0)
250 callParams->
gas += m_schedule->callStipend;
259 else if (m_OP == Instruction::DELEGATECALL)
263 uint64_t inOff = (uint64_t)inputOffset;
264 uint64_t inSize = (uint64_t)inputSize;
265 uint64_t outOff = (uint64_t)outputOffset;
266 uint64_t outSize = (uint64_t)outputSize;
268 if (m_ext->balance(m_ext->myAddress) >= callParams->
valueTransfer && m_ext->depth < 1024)
270 callParams->
onOp = m_onOp;
271 callParams->
senderAddress = m_OP == Instruction::DELEGATECALL ? m_ext->caller : m_ext->myAddress;
272 callParams->
receiveAddress = (m_OP == Instruction::CALL || m_OP == Instruction::STATICCALL) ? callParams->
codeAddress : m_ext->myAddress;
274 o_output =
bytesRef(m_mem.data() + outOff, outSize);