24 uint64_t LegacyVM::memNeed(
u256 const& _offset,
u256 const& _size)
26 return toInt63(_size ?
u512(_offset) + _size :
u512(0));
44 uint64_t LegacyVM::decodeJumpDest(
const byte*
const _code, uint64_t& _pc)
47 uint64_t dest = _code[_pc++];
48 dest = (dest << 8) | _code[_pc++];
52 uint64_t LegacyVM::decodeJumpvDest(
const byte*
const _code, uint64_t& _pc,
byte _voff)
61 if (_voff >= n) _voff = n - 1;
64 uint64_t dest = decodeJumpDest(_code, pc);
74 void LegacyVM::onOperation()
77 (m_onOp)(++m_nSteps, m_PC, m_OP,
78 m_newMemSize > m_mem.size() ? (m_newMemSize - m_mem.size()) / 32 : uint64_t(0),
79 m_runGas, m_io_gas,
this, m_ext);
85 void LegacyVM::adjustStack(
unsigned _removed,
unsigned _added)
91 if (m_stackEnd < m_SPP)
92 throwBadStack(_removed, _added);
95 throwBadStack(_removed, _added);
98 void LegacyVM::updateSSGas()
100 u256 const currentValue = m_ext->store(m_SP[0]);
101 u256 const newValue = m_SP[1];
103 if (m_schedule->eip1283Mode)
104 updateSSGasEIP1283(currentValue, newValue);
106 updateSSGasPreEIP1283(currentValue, newValue);
109 void LegacyVM::updateSSGasPreEIP1283(
u256 const& _currentValue,
u256 const& _newValue)
111 if (!_currentValue && _newValue)
112 m_runGas = toInt63(m_schedule->sstoreSetGas);
113 else if (_currentValue && !_newValue)
115 m_runGas = toInt63(m_schedule->sstoreResetGas);
116 m_ext->sub.refunds += m_schedule->sstoreRefundGas;
119 m_runGas = toInt63(m_schedule->sstoreResetGas);
122 void LegacyVM::updateSSGasEIP1283(
u256 const& _currentValue,
u256 const& _newValue)
124 if (_currentValue == _newValue)
125 m_runGas = m_schedule->sstoreUnchangedGas;
128 u256 const originalValue = m_ext->originalStorageValue(m_SP[0]);
129 if (originalValue == _currentValue)
131 if (originalValue == 0)
132 m_runGas = m_schedule->sstoreSetGas;
135 m_runGas = m_schedule->sstoreResetGas;
137 m_ext->sub.refunds += m_schedule->sstoreRefundGas;
142 m_runGas = m_schedule->sstoreUnchangedGas;
143 if (originalValue != 0)
145 if (_currentValue == 0)
146 m_ext->sub.refunds -= m_schedule->sstoreRefundGas;
148 m_ext->sub.refunds += m_schedule->sstoreRefundGas;
150 if (originalValue == _newValue)
152 if (originalValue == 0)
153 m_ext->sub.refunds +=
154 m_schedule->sstoreRefundGas + m_schedule->sstoreRefundNonzeroGas;
156 m_ext->sub.refunds += m_schedule->sstoreRefundNonzeroGas;
163 uint64_t LegacyVM::gasForMem(
u512 const& _size)
166 return toInt63((
u512)m_schedule->memoryGas * s + s * s / m_schedule->quadCoeffDiv);
169 void LegacyVM::updateIOGas()
171 if (m_io_gas < m_runGas)
173 m_io_gas -= m_runGas;
176 void LegacyVM::updateGas()
178 if (m_newMemSize > m_mem.size())
179 m_runGas += toInt63(gasForMem(m_newMemSize) - gasForMem(m_mem.size()));
180 m_runGas += (m_schedule->copyGas * ((m_copyMemSize + 31) / 32));
181 if (m_io_gas < m_runGas)
185 void LegacyVM::updateMem(uint64_t _newMem)
187 m_newMemSize = (_newMem + 31) / 32 * 32;
189 if (m_newMemSize > m_mem.size())
190 m_mem.resize(m_newMemSize);
193 void LegacyVM::logGasMem()
195 unsigned n = (unsigned)m_OP - (
unsigned)Instruction::LOG0;
196 m_runGas = toInt63(m_schedule->logGas + m_schedule->logTopicGas * n +
u512(m_schedule->logDataGas) * m_SP[1]);
197 updateMem(memNeed(m_SP[0], m_SP[1]));
200 void LegacyVM::fetchInstruction()
204 adjustStack(metric.
args, metric.
ret);
207 m_runGas = toInt63(m_schedule->tierStepGas[
static_cast<unsigned>(metric.
gasPriceTier)]);
208 m_newMemSize = m_mem.size();
219 m_io_gas_p = &_io_gas;
220 m_io_gas = uint64_t(_io_gas);
224 m_onFail = &LegacyVM::onOperation;
230 m_bounce = &LegacyVM::initEntry;
238 *m_io_gas_p = m_io_gas;
242 *m_io_gas_p = m_io_gas;
243 return std::move(m_output);
249 void LegacyVM::interpretCases()
261 if (!m_schedule->haveCreate2)
262 throwBadInstruction();
263 if (m_ext->staticCall)
264 throwDisallowedStateChange();
266 m_bounce = &LegacyVM::caseCreate;
273 if (m_ext->staticCall)
274 throwDisallowedStateChange();
276 m_bounce = &LegacyVM::caseCreate;
286 if (m_OP == Instruction::DELEGATECALL && !m_schedule->haveDelegateCall)
287 throwBadInstruction();
288 if (m_OP == Instruction::STATICCALL && !m_schedule->haveStaticCall)
289 throwBadInstruction();
290 if (m_OP == Instruction::CALL && m_ext->staticCall && m_SP[2] != 0)
291 throwDisallowedStateChange();
292 m_bounce = &LegacyVM::caseCall;
300 updateMem(memNeed(m_SP[0], m_SP[1]));
303 uint64_t b = (uint64_t)m_SP[0];
304 uint64_t s = (uint64_t)m_SP[1];
313 if (!m_schedule->haveRevert)
314 throwBadInstruction();
318 updateMem(memNeed(m_SP[0], m_SP[1]));
321 uint64_t b = (uint64_t)m_SP[0];
322 uint64_t s = (uint64_t)m_SP[1];
324 throwRevertInstruction(move(output));
331 if (m_ext->staticCall)
332 throwDisallowedStateChange();
334 m_runGas = toInt63(m_schedule->suicideGas);
338 if (m_ext->balance(m_ext->myAddress) > 0 || m_schedule->zeroValueTransferChargesNewAccountGas())
341 if (m_schedule->suicideChargesNewAccountGas() && !m_ext->exists(dest))
342 m_runGas += m_schedule->callNewAccountGas;
345 m_ext->suicide(dest);
366 updateMem(toInt63(m_SP[0]) + 32);
369 m_SPP[0] = (
u256)*(
h256 const*)(m_mem.data() + (unsigned)m_SP[0]);
376 updateMem(toInt63(m_SP[0]) + 32);
379 *(
h256*)&m_mem[(
unsigned)m_SP[0]] = (
h256)m_SP[1];
386 updateMem(toInt63(m_SP[0]) + 1);
389 m_mem[(unsigned)m_SP[0]] = (
byte)(m_SP[1] & 0xff);
396 m_runGas = toInt63(m_schedule->sha3Gas + (
u512(m_SP[1]) + 31) / 32 * m_schedule->sha3WordGas);
397 updateMem(memNeed(m_SP[0], m_SP[1]));
400 uint64_t inOff = (uint64_t)m_SP[0];
401 uint64_t inSize = (uint64_t)m_SP[1];
409 if (m_ext->staticCall)
410 throwDisallowedStateChange();
415 m_ext->log({},
bytesConstRef(m_mem.data() + (uint64_t)m_SP[0], (uint64_t)m_SP[1]));
422 if (m_ext->staticCall)
423 throwDisallowedStateChange();
428 m_ext->log({m_SP[2]},
bytesConstRef(m_mem.data() + (uint64_t)m_SP[0], (uint64_t)m_SP[1]));
435 if (m_ext->staticCall)
436 throwDisallowedStateChange();
441 m_ext->log({m_SP[2], m_SP[3]},
bytesConstRef(m_mem.data() + (uint64_t)m_SP[0], (uint64_t)m_SP[1]));
448 if (m_ext->staticCall)
449 throwDisallowedStateChange();
454 m_ext->log({m_SP[2], m_SP[3], m_SP[4]},
bytesConstRef(m_mem.data() + (uint64_t)m_SP[0], (uint64_t)m_SP[1]));
461 if (m_ext->staticCall)
462 throwDisallowedStateChange();
467 m_ext->log({m_SP[2], m_SP[3], m_SP[4], m_SP[5]},
bytesConstRef(m_mem.data() + (uint64_t)m_SP[0], (uint64_t)m_SP[1]));
473 u256 expon = m_SP[1];
474 m_runGas = toInt63(m_schedule->expGas + m_schedule->expByteGas * (32 - (
h256(expon).firstBitSet() / 8)));
479 m_SPP[0] = exp256(base, expon);
493 m_SPP[0] = m_SP[0] + m_SP[1];
503 m_SPP[0] = m_SP[0] * m_SP[1];
512 m_SPP[0] = m_SP[0] - m_SP[1];
567 m_SPP[0] = m_SP[0] < m_SP[1] ? 1 : 0;
576 m_SPP[0] = m_SP[0] > m_SP[1] ? 1 : 0;
585 m_SPP[0] =
u2s(m_SP[0]) <
u2s(m_SP[1]) ? 1 : 0;
594 m_SPP[0] =
u2s(m_SP[0]) >
u2s(m_SP[1]) ? 1 : 0;
603 m_SPP[0] = m_SP[0] == m_SP[1] ? 1 : 0;
612 m_SPP[0] = m_SP[0] ? 0 : 1;
621 m_SPP[0] = m_SP[0] & m_SP[1];
630 m_SPP[0] = m_SP[0] | m_SP[1];
639 m_SPP[0] = m_SP[0] ^ m_SP[1];
648 m_SPP[0] = m_SP[0] < 32 ? (m_SP[1] >> (unsigned)(8 * (31 - m_SP[0]))) & 0xff : 0;
655 if (!m_schedule->haveBitwiseShifting)
656 throwBadInstruction();
664 m_SPP[0] = m_SP[1] << unsigned(m_SP[0]);
671 if (!m_schedule->haveBitwiseShifting)
672 throwBadInstruction();
680 m_SPP[0] = m_SP[1] >> unsigned(m_SP[0]);
687 if (!m_schedule->haveBitwiseShifting)
688 throwBadInstruction();
693 static u256 const hibit =
u256(1) << 255;
694 static u256 const allbits =
695 u256(
"0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
697 u256 shiftee = m_SP[1];
707 unsigned amount = unsigned(m_SP[0]);
708 m_SPP[0] = shiftee >> amount;
710 m_SPP[0] |= allbits << (256 - amount);
720 m_SPP[0] = m_SP[2] ?
u256((
u512(m_SP[0]) +
u512(m_SP[1])) % m_SP[2]) : 0;
729 m_SPP[0] = m_SP[2] ?
u256((
u512(m_SP[0]) *
u512(m_SP[1])) % m_SP[2]) : 0;
740 unsigned testBit =
static_cast<unsigned>(m_SP[0]) * 8 + 7;
741 u256& number = m_SP[1];
742 u256 mask = ((
u256(1) << testBit) - 1);
743 if (boost::multiprecision::bit_test(number, testBit))
757 m_PC = decodeJumpDest(m_code.data(), m_PC);
767 m_PC = decodeJumpDest(m_code.data(), m_PC);
777 m_PC = decodeJumpvDest(m_code.data(), m_PC,
byte(m_SP[0]));
786 m_PC = decodeJumpDest(m_code.data(), m_PC);
795 m_PC = decodeJumpvDest(m_code.data(), m_PC,
byte(m_SP[0]));
849 throwBadInstruction();
1056 updateMem(toInt63(m_SP[0]) + 32);
1066 updateMem(toInt63(m_SP[0]) + 32);
1070 xmstore(simdType());
1076 m_runGas = toInt63(m_schedule->sloadGas);
1086 if (m_ext->staticCall)
1087 throwDisallowedStateChange();
1093 xsstore(simdType());
1102 xvtowide(simdType());
1111 xwidetov(simdType());
1131 xput(m_code[b], m_code[c]);
1143 xget(m_code[b], m_code[c]);
1153 xswizzle(simdType());
1162 xshuffle(simdType());
1200 throwBadInstruction();
1225 m_runGas = toInt63(m_schedule->balanceGas);
1229 m_SPP[0] = m_ext->balance(
asAddress(m_SP[0]));
1248 m_SPP[0] = m_ext->value;
1258 if (
u512(m_SP[0]) + 31 < m_ext->data.size())
1259 m_SP[0] = (
u256)*(
h256 const*)(m_ext->data.data() + (size_t)m_SP[0]);
1260 else if (m_SP[0] >= m_ext->data.size())
1264 for (uint64_t i = (uint64_t)m_SP[0], e = (uint64_t)m_SP[0] + (uint64_t)32, j = 0; i < e; ++i, ++j)
1265 r[j] = i < m_ext->data.
size() ? m_ext->data[i] : 0;
1277 m_SPP[0] = m_ext->data.size();
1281 CASE(RETURNDATASIZE)
1283 if (!m_schedule->haveReturnData)
1284 throwBadInstruction();
1289 m_SPP[0] = m_returnData.size();
1298 m_SPP[0] = m_ext->code.size();
1304 m_runGas = toInt63(m_schedule->extcodesizeGas);
1308 m_SPP[0] = m_ext->codeSizeAt(
asAddress(m_SP[0]));
1315 m_copyMemSize = toInt63(m_SP[2]);
1316 updateMem(memNeed(m_SP[0], m_SP[2]));
1319 copyDataToMemory(m_ext->data, m_SP);
1323 CASE(RETURNDATACOPY)
1326 if (!m_schedule->haveReturnData)
1327 throwBadInstruction();
1329 if (m_returnData.size() < endOfAccess)
1330 throwBufferOverrun(endOfAccess);
1332 m_copyMemSize = toInt63(m_SP[2]);
1333 updateMem(memNeed(m_SP[0], m_SP[2]));
1336 copyDataToMemory(&m_returnData, m_SP);
1343 if (!m_schedule->haveExtcodehash)
1344 throwBadInstruction();
1346 m_runGas = toInt63(m_schedule->extcodehashGas);
1356 m_copyMemSize = toInt63(m_SP[2]);
1357 updateMem(memNeed(m_SP[0], m_SP[2]));
1360 copyDataToMemory(&m_ext->code, m_SP);
1367 m_runGas = toInt63(m_schedule->extcodecopyGas);
1368 m_copyMemSize = toInt63(m_SP[3]);
1369 updateMem(memNeed(m_SP[1], m_SP[3]));
1373 copyDataToMemory(&m_ext->codeAt(a), m_SP + 1);
1383 m_SPP[0] = m_ext->gasPrice;
1390 m_runGas = toInt63(m_schedule->blockhashGas);
1393 m_SPP[0] = (
u256)m_ext->blockHash(m_SP[0]);
1402 m_SPP[0] = (
u160)m_ext->envInfo().author();
1411 m_SPP[0] = m_ext->envInfo().timestamp();
1420 m_SPP[0] = m_ext->envInfo().number();
1429 m_SPP[0] = m_ext->envInfo().difficulty();
1438 m_SPP[0] = m_ext->envInfo().gasLimit();
1453 #if EVM_USE_CONSTANT_POOL
1461 off = m_code[m_PC++] << 8;
1462 off |= m_code[m_PC++];
1463 m_PC += m_code[m_PC];
1464 m_SPP[0] = m_pool[off];
1465 TRACE_VAL(2,
"Retrieved pooled const", m_SPP[0]);
1467 throwBadInstruction();
1477 m_SPP[0] = m_code[m_PC];
1517 int numBytes = (int)m_OP - (
int)Instruction::PUSH1 + 1;
1522 for (++m_PC; numBytes--; ++m_PC)
1523 m_SPP[0] = (m_SPP[0] << 8) | m_code[m_PC];
1531 m_PC = verifyJumpDest(m_SP[0]);
1540 m_PC = verifyJumpDest(m_SP[0]);
1548 #if EVM_REPLACE_CONST_JUMP
1552 m_PC = uint64_t(m_SP[0]);
1554 throwBadInstruction();
1561 #if EVM_REPLACE_CONST_JUMP
1566 m_PC = uint64_t(m_SP[0]);
1570 throwBadInstruction();
1595 unsigned n = (unsigned)m_OP - (
unsigned)Instruction::DUP1;
1596 *(uint64_t*)m_SPP = *(uint64_t*)(m_SP + n);
1600 new(m_SPP)
u256(m_SP[n]);
1625 unsigned n = (unsigned)m_OP - (
unsigned)Instruction::SWAP1 + 1;
1633 m_runGas = toInt63(m_schedule->sloadGas);
1637 m_SPP[0] = m_ext->store(m_SP[0]);
1644 if (m_ext->staticCall)
1645 throwDisallowedStateChange();
1650 m_ext->setStore(m_SP[0], m_SP[1]);
1668 m_SPP[0] = m_mem.size();
1677 m_SPP[0] = m_io_gas;
1692 throwBadInstruction();