24 std::array<InstructionMetric, 256> LegacyVM::c_metrics;
25 void LegacyVM::initMetrics()
30 for (
unsigned i = 0; i < 256; ++i)
34 c_metrics[i].args = op.
args;
35 c_metrics[i].ret = op.
ret;
42 void LegacyVM::copyCode(
int _extraBytes)
47 auto extendedSize = m_ext->code.size() + _extraBytes;
48 m_code.reserve(extendedSize);
50 m_code.resize(extendedSize);
53 void LegacyVM::optimize()
57 size_t const nBytes = m_ext->code.size();
62 for (
size_t pc = 0; pc < nBytes; ++pc)
69 op == Instruction::PUSHC ||
70 op == Instruction::JUMPC ||
71 op == Instruction::JUMPCI
75 m_code[pc] = (
byte)Instruction::INVALID;
78 if (op == Instruction::JUMPDEST)
80 m_jumpDests.push_back(pc);
83 (
byte)Instruction::PUSH1 <= (
byte)op &&
84 (
byte)op <= (
byte)Instruction::PUSH32
87 pc += (
byte)op - (
byte)Instruction::PUSH1 + 1;
91 op == Instruction::JUMPTO ||
92 op == Instruction::JUMPIF ||
93 op == Instruction::JUMPSUB)
98 else if (op == Instruction::JUMPV || op == Instruction::JUMPSUBV)
101 pc += 4 * m_code[pc];
103 else if (op == Instruction::BEGINSUB)
105 m_beginSubs.push_back(pc);
107 else if (op == Instruction::BEGINDATA)
114 #ifdef EVM_DO_FIRST_PASS_OPTIMIZATION 116 TRACE_STR(1,
"Do first pass optimizations")
117 for (
size_t pc = 0; pc < nBytes; ++pc)
122 if ((
byte)Instruction::PUSH1 <= (
byte)op && (
byte)op <= (
byte)Instruction::PUSH32)
128 for (uint64_t i = pc+2, n = nPush; --n; ++i) {
129 val = (val << 8) | m_code[i];
132 #if EVM_USE_CONSTANT_POOL 139 uint16_t pool_off = m_pool.size();
141 TRACE_VAL(1,
"... in pool at offset" , pool_off);
142 m_pool.push_back(val);
145 m_code[pc] =
byte(op = Instruction::PUSHC);
146 m_code[pc+3] = nPush - 2;
147 m_code[pc+2] = pool_off & 0xff;
148 m_code[pc+1] = pool_off >> 8;
154 #if EVM_REPLACE_CONST_JUMP 159 size_t i = pc + nPush + 1;
161 if (op == Instruction::JUMP)
163 TRACE_VAL(1,
"Replace const JUMP with JUMPC to", val)
166 if (0 <= verifyJumpDest(val,
false))
167 m_code[i] =
byte(op = Instruction::JUMPC);
171 else if (op == Instruction::JUMPI)
173 TRACE_VAL(1,
"Replace const JUMPI with JUMPCI to", val)
176 if (0 <= verifyJumpDest(val,
false))
177 m_code[i] =
byte(op = Instruction::JUMPCI);
194 void LegacyVM::initEntry()
196 m_bounce = &LegacyVM::interpretCases;
210 using boost::multiprecision::limb_type;
214 if (static_cast<limb_type>(_exponent) & 1)
#define TRACE_PRE_OPT(level, pc, op)
#define TRACE_OP(level, pc, op)
int const args
Number of items required on the stack for this instruction (and, for the purposes of ret...
InstructionInfo instructionInfo(Instruction _inst)
Information on all the instructions.
int const ret
Number of items placed (back) on the stack by this instruction, assuming args items were removed...
Tier const gasPriceTier
Tier for gas pricing.
#define TRACE_STR(level, str)
Instruction
Virtual machine bytecode instruction.
Information structure for a particular instruction.
boost::multiprecision::number< boost::multiprecision::cpp_int_backend< 256, 256, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void > > u256
#define TRACE_VAL(level, name, val)
#define TRACE_POST_OPT(level, pc, op)