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)
124 byte nPush = (
byte)op - (
byte)Instruction::PUSH1 + 1;
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)