Fabcoin Core  0.16.2
P2P Digital Currency
Compiler.cpp
Go to the documentation of this file.
1 #include "Compiler.h"
2 
3 #include <fstream>
4 #include <chrono>
5 #include <sstream>
6 
8 #include <llvm/IR/CFG.h>
9 #include <llvm/IR/Module.h>
10 #include <llvm/IR/IntrinsicInst.h>
12 
13 #include "JIT.h"
14 #include "Instruction.h"
15 #include "Type.h"
16 #include "Memory.h"
17 #include "Ext.h"
18 #include "GasMeter.h"
19 #include "Utils.h"
20 #include "Endianness.h"
21 #include "Arith256.h"
22 #include "RuntimeManager.h"
23 
24 namespace dev
25 {
26 namespace eth
27 {
28 namespace jit
29 {
30 
31 static const auto c_destIdxLabel = "destIdx";
32 
33 Compiler::Compiler(Options const& _options, evm_mode _mode, llvm::LLVMContext& _llvmContext):
34  m_options(_options),
35  m_mode(_mode),
36  m_builder(_llvmContext)
37 {
38  Type::init(m_builder.getContext());
39 }
40 
41 std::vector<BasicBlock> Compiler::createBasicBlocks(code_iterator _codeBegin, code_iterator _codeEnd)
42 {
44  auto skipPushDataAndGetNext = [](code_iterator _curr, code_iterator _end)
45  {
46  static const auto push1 = static_cast<size_t>(Instruction::PUSH1);
47  static const auto push32 = static_cast<size_t>(Instruction::PUSH32);
48  size_t offset = 1;
49  if (*_curr >= push1 && *_curr <= push32)
50  offset += std::min<size_t>(*_curr - push1 + 1, (_end - _curr) - 1);
51  return _curr + offset;
52  };
53 
54  std::vector<BasicBlock> blocks;
55 
56  bool isDead = false;
57  auto begin = _codeBegin; // begin of current block
58  for (auto curr = begin, next = begin; curr != _codeEnd; curr = next)
59  {
60  next = skipPushDataAndGetNext(curr, _codeEnd);
61 
62  if (isDead)
63  {
64  if (Instruction(*curr) == Instruction::JUMPDEST)
65  {
66  isDead = false;
67  begin = curr;
68  }
69  else
70  continue;
71  }
72 
73  bool isEnd = false;
74  switch (Instruction(*curr))
75  {
76  case Instruction::JUMP:
78  case Instruction::STOP:
80  isDead = true;
81  case Instruction::JUMPI:
82  isEnd = true;
83  break;
84 
85  default:
86  break;
87  }
88 
89  assert(next <= _codeEnd);
90  if (next == _codeEnd || Instruction(*next) == Instruction::JUMPDEST)
91  isEnd = true;
92 
93  if (isEnd)
94  {
95  auto beginIdx = begin - _codeBegin;
96  blocks.emplace_back(beginIdx, begin, next, m_mainFunc);
97  begin = next;
98  }
99  }
100 
101  return blocks;
102 }
103 
105 {
106  auto jumpTable = llvm::cast<llvm::SwitchInst>(m_jumpTableBB->getTerminator());
107  auto jumpTableInput = llvm::cast<llvm::PHINode>(m_jumpTableBB->begin());
108 
109  // Iterate through all EVM instructions blocks (skip first one and last 4 - special blocks).
110  for (auto it = std::next(m_mainFunc->begin()), end = std::prev(m_mainFunc->end(), 4); it != end; ++it)
111  {
112  auto nextBlockIter = it;
113  ++nextBlockIter; // If the last code block, that will be "stop" block.
114  auto currentBlockPtr = &(*it);
115  auto nextBlockPtr = &(*nextBlockIter);
116 
117  auto term = it->getTerminator();
118  llvm::BranchInst* jump = nullptr;
119 
120  if (!term) // Block may have no terminator if the next instruction is a jump destination.
121  IRBuilder{currentBlockPtr}.CreateBr(nextBlockPtr);
122  else if ((jump = llvm::dyn_cast<llvm::BranchInst>(term)) && jump->getSuccessor(0) == m_jumpTableBB)
123  {
124  auto destIdx = llvm::cast<llvm::ValueAsMetadata>(jump->getMetadata(c_destIdxLabel)->getOperand(0))->getValue();
125  if (auto constant = llvm::dyn_cast<llvm::ConstantInt>(destIdx))
126  {
127  // If destination index is a constant do direct jump to the destination block.
128  auto bb = jumpTable->findCaseValue(constant).getCaseSuccessor();
129  jump->setSuccessor(0, bb);
130  }
131  else
132  jumpTableInput->addIncoming(destIdx, currentBlockPtr); // Fill up PHI node
133 
134  if (jump->isConditional())
135  jump->setSuccessor(1, &(*nextBlockIter)); // Set next block for conditional jumps
136  }
137  }
138 
139  auto simplifiedInput = jumpTableInput->getNumIncomingValues() == 0 ?
140  llvm::UndefValue::get(jumpTableInput->getType()) :
141  jumpTableInput->hasConstantValue();
142  if (simplifiedInput)
143  {
144  jumpTableInput->replaceAllUsesWith(simplifiedInput);
145  jumpTableInput->eraseFromParent();
146  }
147 }
148 
149 std::unique_ptr<llvm::Module> Compiler::compile(code_iterator _begin, code_iterator _end, std::string const& _id)
150 {
151  auto module = llvm::make_unique<llvm::Module>(_id, m_builder.getContext()); // TODO: Provide native DataLayout
152 
153  // Create main function
154  auto mainFuncType = llvm::FunctionType::get(Type::MainReturn, Type::RuntimePtr, false);
155  m_mainFunc = llvm::Function::Create(mainFuncType, llvm::Function::ExternalLinkage, _id, module.get());
156  m_mainFunc->getArgumentList().front().setName("rt");
157 
158  // Create entry basic block
159  auto entryBB = llvm::BasicBlock::Create(m_builder.getContext(), "Entry", m_mainFunc);
160 
161  auto blocks = createBasicBlocks(_begin, _end);
162 
163  // Special "Stop" block. Guarantees that there exists a next block after the code blocks (also when there are no code blocks).
164  auto stopBB = llvm::BasicBlock::Create(m_mainFunc->getContext(), "Stop", m_mainFunc);
165  m_jumpTableBB = llvm::BasicBlock::Create(m_mainFunc->getContext(), "JumpTable", m_mainFunc);
166  auto abortBB = llvm::BasicBlock::Create(m_mainFunc->getContext(), "Abort", m_mainFunc);
167 
168  m_builder.SetInsertPoint(m_jumpTableBB); // Must be before basic blocks compilation
169  auto target = m_builder.CreatePHI(Type::Word, 16, "target");
170  m_builder.CreateSwitch(target, abortBB);
171 
172  m_builder.SetInsertPoint(entryBB);
173 
174 
175  // Init runtime structures.
176  RuntimeManager runtimeManager(m_builder, _begin, _end);
177  GasMeter gasMeter(m_builder, runtimeManager, m_mode);
178  Memory memory(runtimeManager, gasMeter);
179  Ext ext(runtimeManager, memory);
180  Arith256 arith(m_builder);
181 
182  auto jmpBufWords = m_builder.CreateAlloca(Type::BytePtr, m_builder.getInt64(3), "jmpBuf.words");
183  auto frameaddress = llvm::Intrinsic::getDeclaration(module.get(), llvm::Intrinsic::frameaddress);
184  auto fp = m_builder.CreateCall(frameaddress, m_builder.getInt32(0), "fp");
185  m_builder.CreateStore(fp, jmpBufWords);
186  auto stacksave = llvm::Intrinsic::getDeclaration(module.get(), llvm::Intrinsic::stacksave);
187  auto sp = m_builder.CreateCall(stacksave, {}, "sp");
188  auto jmpBufSp = m_builder.CreateConstInBoundsGEP1_64(jmpBufWords, 2, "jmpBuf.sp");
189  m_builder.CreateStore(sp, jmpBufSp);
190  auto setjmp = llvm::Intrinsic::getDeclaration(module.get(), llvm::Intrinsic::eh_sjlj_setjmp);
191  auto jmpBuf = m_builder.CreateBitCast(jmpBufWords, Type::BytePtr, "jmpBuf");
192  auto r = m_builder.CreateCall(setjmp, jmpBuf);
193  auto normalFlow = m_builder.CreateICmpEQ(r, m_builder.getInt32(0));
194  runtimeManager.setJmpBuf(jmpBuf);
195  m_builder.CreateCondBr(normalFlow, entryBB->getNextNode(), abortBB, Type::expectTrue);
196 
197  for (auto& block: blocks)
198  compileBasicBlock(block, runtimeManager, arith, memory, ext, gasMeter);
199 
200  // Code for special blocks:
201  m_builder.SetInsertPoint(stopBB);
202  runtimeManager.exit(ReturnCode::Stop);
203 
204  m_builder.SetInsertPoint(abortBB);
205  runtimeManager.exit(ReturnCode::OutOfGas);
206 
207  resolveJumps();
208 
209  return module;
210 }
211 
212 
213 void Compiler::compileBasicBlock(BasicBlock& _basicBlock, RuntimeManager& _runtimeManager,
214  Arith256& _arith, Memory& _memory, Ext& _ext, GasMeter& _gasMeter)
215 {
216  m_builder.SetInsertPoint(_basicBlock.llvm());
217  LocalStack stack{m_builder, _runtimeManager};
218 
219  for (auto it = _basicBlock.begin(); it != _basicBlock.end(); ++it)
220  {
221  auto inst = Instruction(*it);
222 
223  _gasMeter.count(inst);
224 
225  switch (inst)
226  {
227 
228  case Instruction::ADD:
229  {
230  auto lhs = stack.pop();
231  auto rhs = stack.pop();
232  auto result = m_builder.CreateAdd(lhs, rhs);
233  stack.push(result);
234  break;
235  }
236 
237  case Instruction::SUB:
238  {
239  auto lhs = stack.pop();
240  auto rhs = stack.pop();
241  auto result = m_builder.CreateSub(lhs, rhs);
242  stack.push(result);
243  break;
244  }
245 
246  case Instruction::MUL:
247  {
248  auto lhs = stack.pop();
249  auto rhs = stack.pop();
250  auto res = m_builder.CreateMul(lhs, rhs);
251  stack.push(res);
252  break;
253  }
254 
255  case Instruction::DIV:
256  {
257  auto d = stack.pop();
258  auto n = stack.pop();
259  auto divByZero = m_builder.CreateICmpEQ(n, Constant::get(0));
260  n = m_builder.CreateSelect(divByZero, Constant::get(1), n); // protect against hardware signal
261  auto r = m_builder.CreateUDiv(d, n);
262  r = m_builder.CreateSelect(divByZero, Constant::get(0), r);
263  stack.push(r);
264  break;
265  }
266 
267  case Instruction::SDIV:
268  {
269  auto d = stack.pop();
270  auto n = stack.pop();
271  auto divByZero = m_builder.CreateICmpEQ(n, Constant::get(0));
272  auto divByMinusOne = m_builder.CreateICmpEQ(n, Constant::get(-1));
273  n = m_builder.CreateSelect(divByZero, Constant::get(1), n); // protect against hardware signal
274  auto r = m_builder.CreateSDiv(d, n);
275  r = m_builder.CreateSelect(divByZero, Constant::get(0), r);
276  auto dNeg = m_builder.CreateSub(Constant::get(0), d);
277  r = m_builder.CreateSelect(divByMinusOne, dNeg, r); // protect against undef i256.min / -1
278  stack.push(r);
279  break;
280  }
281 
282  case Instruction::MOD:
283  {
284  auto d = stack.pop();
285  auto n = stack.pop();
286  auto divByZero = m_builder.CreateICmpEQ(n, Constant::get(0));
287  n = m_builder.CreateSelect(divByZero, Constant::get(1), n); // protect against hardware signal
288  auto r = m_builder.CreateURem(d, n);
289  r = m_builder.CreateSelect(divByZero, Constant::get(0), r);
290  stack.push(r);
291  break;
292  }
293 
294  case Instruction::SMOD:
295  {
296  auto d = stack.pop();
297  auto n = stack.pop();
298  auto divByZero = m_builder.CreateICmpEQ(n, Constant::get(0));
299  auto divByMinusOne = m_builder.CreateICmpEQ(n, Constant::get(-1));
300  n = m_builder.CreateSelect(divByZero, Constant::get(1), n); // protect against hardware signal
301  auto r = m_builder.CreateSRem(d, n);
302  r = m_builder.CreateSelect(divByZero, Constant::get(0), r);
303  r = m_builder.CreateSelect(divByMinusOne, Constant::get(0), r); // protect against undef i256.min / -1
304  stack.push(r);
305  break;
306  }
307 
308  case Instruction::ADDMOD:
309  {
310  auto i512Ty = m_builder.getIntNTy(512);
311  auto a = stack.pop();
312  auto b = stack.pop();
313  auto m = stack.pop();
314  auto divByZero = m_builder.CreateICmpEQ(m, Constant::get(0));
315  a = m_builder.CreateZExt(a, i512Ty);
316  b = m_builder.CreateZExt(b, i512Ty);
317  m = m_builder.CreateZExt(m, i512Ty);
318  auto s = m_builder.CreateNUWAdd(a, b);
319  s = m_builder.CreateURem(s, m);
320  s = m_builder.CreateTrunc(s, Type::Word);
321  s = m_builder.CreateSelect(divByZero, Constant::get(0), s);
322  stack.push(s);
323  break;
324  }
325 
326  case Instruction::MULMOD:
327  {
328  auto i512Ty = m_builder.getIntNTy(512);
329  auto a = stack.pop();
330  auto b = stack.pop();
331  auto m = stack.pop();
332  auto divByZero = m_builder.CreateICmpEQ(m, Constant::get(0));
333  a = m_builder.CreateZExt(a, i512Ty);
334  b = m_builder.CreateZExt(b, i512Ty);
335  m = m_builder.CreateZExt(m, i512Ty);
336  auto p = m_builder.CreateNUWMul(a, b);
337  p = m_builder.CreateURem(p, m);
338  p = m_builder.CreateTrunc(p, Type::Word);
339  p = m_builder.CreateSelect(divByZero, Constant::get(0), p);
340  stack.push(p);
341  break;
342  }
343 
344  case Instruction::EXP:
345  {
346  auto base = stack.pop();
347  auto exponent = stack.pop();
348  _gasMeter.countExp(exponent);
349  auto ret = _arith.exp(base, exponent);
350  stack.push(ret);
351  break;
352  }
353 
354  case Instruction::NOT:
355  {
356  auto value = stack.pop();
357  auto ret = m_builder.CreateXor(value, Constant::get(-1), "bnot");
358  stack.push(ret);
359  break;
360  }
361 
362  case Instruction::LT:
363  {
364  auto lhs = stack.pop();
365  auto rhs = stack.pop();
366  auto res1 = m_builder.CreateICmpULT(lhs, rhs);
367  auto res256 = m_builder.CreateZExt(res1, Type::Word);
368  stack.push(res256);
369  break;
370  }
371 
372  case Instruction::GT:
373  {
374  auto lhs = stack.pop();
375  auto rhs = stack.pop();
376  auto res1 = m_builder.CreateICmpUGT(lhs, rhs);
377  auto res256 = m_builder.CreateZExt(res1, Type::Word);
378  stack.push(res256);
379  break;
380  }
381 
382  case Instruction::SLT:
383  {
384  auto lhs = stack.pop();
385  auto rhs = stack.pop();
386  auto res1 = m_builder.CreateICmpSLT(lhs, rhs);
387  auto res256 = m_builder.CreateZExt(res1, Type::Word);
388  stack.push(res256);
389  break;
390  }
391 
392  case Instruction::SGT:
393  {
394  auto lhs = stack.pop();
395  auto rhs = stack.pop();
396  auto res1 = m_builder.CreateICmpSGT(lhs, rhs);
397  auto res256 = m_builder.CreateZExt(res1, Type::Word);
398  stack.push(res256);
399  break;
400  }
401 
402  case Instruction::EQ:
403  {
404  auto lhs = stack.pop();
405  auto rhs = stack.pop();
406  auto res1 = m_builder.CreateICmpEQ(lhs, rhs);
407  auto res256 = m_builder.CreateZExt(res1, Type::Word);
408  stack.push(res256);
409  break;
410  }
411 
412  case Instruction::ISZERO:
413  {
414  auto top = stack.pop();
415  auto iszero = m_builder.CreateICmpEQ(top, Constant::get(0), "iszero");
416  auto result = m_builder.CreateZExt(iszero, Type::Word);
417  stack.push(result);
418  break;
419  }
420 
421  case Instruction::AND:
422  {
423  auto lhs = stack.pop();
424  auto rhs = stack.pop();
425  auto res = m_builder.CreateAnd(lhs, rhs);
426  stack.push(res);
427  break;
428  }
429 
430  case Instruction::OR:
431  {
432  auto lhs = stack.pop();
433  auto rhs = stack.pop();
434  auto res = m_builder.CreateOr(lhs, rhs);
435  stack.push(res);
436  break;
437  }
438 
439  case Instruction::XOR:
440  {
441  auto lhs = stack.pop();
442  auto rhs = stack.pop();
443  auto res = m_builder.CreateXor(lhs, rhs);
444  stack.push(res);
445  break;
446  }
447 
448  case Instruction::BYTE:
449  {
450  const auto idx = stack.pop();
451  auto value = Endianness::toBE(m_builder, stack.pop());
452 
453  auto idxValid = m_builder.CreateICmpULT(idx, Constant::get(32), "idxValid");
454  auto bytes = m_builder.CreateBitCast(value, llvm::VectorType::get(Type::Byte, 32), "bytes");
455  // TODO: Workaround for LLVM bug. Using big value of index causes invalid memory access.
456  auto safeIdx = m_builder.CreateTrunc(idx, m_builder.getIntNTy(5));
457  // TODO: Workaround for LLVM bug. DAG Builder used sext on index instead of zext
458  safeIdx = m_builder.CreateZExt(safeIdx, Type::Size);
459  auto byte = m_builder.CreateExtractElement(bytes, safeIdx, "byte");
460  value = m_builder.CreateZExt(byte, Type::Word);
461  value = m_builder.CreateSelect(idxValid, value, Constant::get(0));
462  stack.push(value);
463  break;
464  }
465 
467  {
468  auto idx = stack.pop();
469  auto word = stack.pop();
470 
471  auto k32_ = m_builder.CreateTrunc(idx, m_builder.getIntNTy(5), "k_32");
472  auto k32 = m_builder.CreateZExt(k32_, Type::Size);
473  auto k32x8 = m_builder.CreateMul(k32, m_builder.getInt64(8), "kx8");
474 
475  // test for word >> (k * 8 + 7)
476  auto bitpos = m_builder.CreateAdd(k32x8, m_builder.getInt64(7), "bitpos");
477  auto bitposEx = m_builder.CreateZExt(bitpos, Type::Word);
478  auto bitval = m_builder.CreateLShr(word, bitposEx, "bitval");
479  auto bittest = m_builder.CreateTrunc(bitval, Type::Bool, "bittest");
480 
481  auto mask_ = m_builder.CreateShl(Constant::get(1), bitposEx);
482  auto mask = m_builder.CreateSub(mask_, Constant::get(1), "mask");
483 
484  auto negmask = m_builder.CreateXor(mask, llvm::ConstantInt::getAllOnesValue(Type::Word), "negmask");
485  auto val1 = m_builder.CreateOr(word, negmask);
486  auto val0 = m_builder.CreateAnd(word, mask);
487 
488  auto kInRange = m_builder.CreateICmpULE(idx, llvm::ConstantInt::get(Type::Word, 30));
489  auto result = m_builder.CreateSelect(kInRange,
490  m_builder.CreateSelect(bittest, val1, val0),
491  word);
492  stack.push(result);
493  break;
494  }
495 
496  case Instruction::SHA3:
497  {
498  auto inOff = stack.pop();
499  auto inSize = stack.pop();
500  _memory.require(inOff, inSize);
501  _gasMeter.countSha3Data(inSize);
502  auto hash = _ext.sha3(inOff, inSize);
503  stack.push(hash);
504  break;
505  }
506 
507  case Instruction::POP:
508  {
509  stack.pop();
510  break;
511  }
512 
514  {
515  auto value = readPushData(it, _basicBlock.end());
516  stack.push(Constant::get(value));
517  break;
518  }
519 
521  {
522  auto index = static_cast<size_t>(inst) - static_cast<size_t>(Instruction::DUP1);
523  stack.dup(index);
524  break;
525  }
526 
528  {
529  auto index = static_cast<size_t>(inst) - static_cast<size_t>(Instruction::SWAP1) + 1;
530  stack.swap(index);
531  break;
532  }
533 
534  case Instruction::MLOAD:
535  {
536  auto addr = stack.pop();
537  auto word = _memory.loadWord(addr);
538  stack.push(word);
539  break;
540  }
541 
542  case Instruction::MSTORE:
543  {
544  auto addr = stack.pop();
545  auto word = stack.pop();
546  _memory.storeWord(addr, word);
547  break;
548  }
549 
551  {
552  auto addr = stack.pop();
553  auto word = stack.pop();
554  _memory.storeByte(addr, word);
555  break;
556  }
557 
558  case Instruction::MSIZE:
559  {
560  auto word = _memory.getSize();
561  stack.push(word);
562  break;
563  }
564 
565  case Instruction::SLOAD:
566  {
567  auto index = stack.pop();
568  auto value = _ext.sload(index);
569  stack.push(value);
570  break;
571  }
572 
573  case Instruction::SSTORE:
574  {
575  auto index = stack.pop();
576  auto value = stack.pop();
577  _gasMeter.countSStore(_ext, index, value);
578  _ext.sstore(index, value);
579  break;
580  }
581 
582  case Instruction::JUMP:
583  case Instruction::JUMPI:
584  {
585  auto destIdx = llvm::MDNode::get(m_builder.getContext(), llvm::ValueAsMetadata::get(stack.pop()));
586 
587  // Create branch instruction, initially to jump table.
588  // Destination will be optimized with direct jump during jump resolving if destination index is a constant.
589  auto jumpInst = (inst == Instruction::JUMP) ?
590  m_builder.CreateBr(m_jumpTableBB) :
591  m_builder.CreateCondBr(m_builder.CreateICmpNE(stack.pop(), Constant::get(0), "jump.check"), m_jumpTableBB, nullptr);
592 
593  // Attach medatada to branch instruction with information about destination index.
594  jumpInst->setMetadata(c_destIdxLabel, destIdx);
595  break;
596  }
597 
599  {
600  // Add the basic block to the jump table.
601  assert(it == _basicBlock.begin() && "JUMPDEST must be the first instruction of a basic block");
602  auto jumpTable = llvm::cast<llvm::SwitchInst>(m_jumpTableBB->getTerminator());
603  jumpTable->addCase(Constant::get(_basicBlock.firstInstrIdx()), _basicBlock.llvm());
604  break;
605  }
606 
607  case Instruction::PC:
608  {
609  auto value = Constant::get(it - _basicBlock.begin() + _basicBlock.firstInstrIdx());
610  stack.push(value);
611  break;
612  }
613 
614  case Instruction::GAS:
615  {
616  _gasMeter.commitCostBlock();
617  stack.push(m_builder.CreateZExt(_runtimeManager.getGas(), Type::Word));
618  break;
619  }
620 
622  stack.push(_ext.query(EVM_ADDRESS));
623  break;
624  case Instruction::CALLER:
625  stack.push(_ext.query(EVM_CALLER));
626  break;
627  case Instruction::ORIGIN:
628  stack.push(_ext.query(EVM_ORIGIN));
629  break;
631  stack.push(_ext.query(EVM_COINBASE));
632  break;
633 
635  stack.push(_ext.query(EVM_GAS_PRICE));
636  break;
637 
639  stack.push(_ext.query(EVM_DIFFICULTY));
640  break;
641 
643  stack.push(_ext.query(EVM_GAS_LIMIT));
644  break;
645 
646  case Instruction::NUMBER:
647  stack.push(_ext.query(EVM_NUMBER));
648  break;
649 
651  stack.push(_ext.query(EVM_TIMESTAMP));
652  break;
653 
655  {
656  auto beValue = _runtimeManager.getValue();
657  stack.push(Endianness::toNative(m_builder, beValue));
658  break;
659  }
660 
662  stack.push(_runtimeManager.getCodeSize());
663  break;
664 
666  stack.push(_runtimeManager.getCallDataSize());
667  break;
668 
670  {
671  auto number = stack.pop();
672  // If number bigger than int64 assume the result is 0.
673  auto limitC = m_builder.getInt64(std::numeric_limits<int64_t>::max());
674  auto limit = m_builder.CreateZExt(limitC, Type::Word);
675  auto isBigNumber = m_builder.CreateICmpUGT(number, limit);
676  auto hash = _ext.blockHash(number);
677  // TODO: Try to eliminate the call if the number is invalid.
678  hash = m_builder.CreateSelect(isBigNumber, Constant::get(0), hash);
679  stack.push(hash);
680  break;
681  }
682 
684  {
685  auto address = stack.pop();
686  auto value = _ext.balance(address);
687  stack.push(value);
688  break;
689  }
690 
692  {
693  auto addr = stack.pop();
694  auto codesize = _ext.extcodesize(addr);
695  stack.push(codesize);
696  break;
697  }
698 
700  {
701  auto destMemIdx = stack.pop();
702  auto srcIdx = stack.pop();
703  auto reqBytes = stack.pop();
704 
705  auto srcPtr = _runtimeManager.getCallData();
706  auto srcSize = _runtimeManager.getCallDataSize();
707 
708  _memory.copyBytes(srcPtr, srcSize, srcIdx, destMemIdx, reqBytes);
709  break;
710  }
711 
713  {
714  auto destMemIdx = stack.pop();
715  auto srcIdx = stack.pop();
716  auto reqBytes = stack.pop();
717 
718  auto srcPtr = _runtimeManager.getCode(); // TODO: Code & its size are constants, feature #80814234
719  auto srcSize = _runtimeManager.getCodeSize();
720 
721  _memory.copyBytes(srcPtr, srcSize, srcIdx, destMemIdx, reqBytes);
722  break;
723  }
724 
726  {
727  auto addr = stack.pop();
728  auto destMemIdx = stack.pop();
729  auto srcIdx = stack.pop();
730  auto reqBytes = stack.pop();
731 
732  auto codeRef = _ext.extcode(addr);
733 
734  _memory.copyBytes(codeRef.ptr, codeRef.size, srcIdx, destMemIdx, reqBytes);
735  break;
736  }
737 
739  {
740  auto idx = stack.pop();
741  auto value = _ext.calldataload(idx);
742  stack.push(value);
743  break;
744  }
745 
746  case Instruction::CREATE:
747  {
748  auto endowment = stack.pop();
749  auto initOff = stack.pop();
750  auto initSize = stack.pop();
751  _memory.require(initOff, initSize);
752 
753  _gasMeter.commitCostBlock();
754  auto gas = _runtimeManager.getGas();
755  llvm::Value* gasKept = (m_mode >= EVM_ANTI_DOS) ?
756  m_builder.CreateLShr(gas, 6) :
757  m_builder.getInt64(0);
758  auto createGas = m_builder.CreateSub(gas, gasKept, "create.gas", true, true);
759  llvm::Value* r = nullptr;
760  llvm::Value* pAddr = nullptr;
761  std::tie(r, pAddr) = _ext.create(createGas, endowment, initOff, initSize);
762 
763  auto ret =
764  m_builder.CreateICmpSGE(r, m_builder.getInt64(0), "create.ret");
765  auto rmagic = m_builder.CreateSelect(
766  ret, m_builder.getInt64(0), m_builder.getInt64(EVM_CALL_FAILURE),
767  "call.rmagic");
768  // TODO: optimize
769  auto gasLeft = m_builder.CreateSub(r, rmagic, "create.gasleft");
770  gas = m_builder.CreateAdd(gasLeft, gasKept);
771  _runtimeManager.setGas(gas);
772 
773  llvm::Value* addr = m_builder.CreateLoad(pAddr);
774  addr = Endianness::toNative(m_builder, addr);
775  addr = m_builder.CreateZExt(addr, Type::Word);
776  addr = m_builder.CreateSelect(ret, addr, Constant::get(0));
777  stack.push(addr);
778  break;
779  }
780 
782  if (m_mode == EVM_FRONTIER)
783  {
784  // Invalid opcode in Frontier compatibility mode.
785  _runtimeManager.exit(ReturnCode::OutOfGas);
786  it = _basicBlock.end() - 1; // finish block compilation
787  break;
788  }
789  // else, fall-through
790  case Instruction::CALL:
792  {
793  auto kind = (inst == Instruction::CALL) ?
794  EVM_CALL :
795  (inst == Instruction::CALLCODE) ? EVM_CALLCODE :
797  auto callGas = stack.pop();
798  auto address = stack.pop();
799  auto value = (kind == EVM_DELEGATECALL) ? Constant::get(0) : stack.pop();
800 
801  auto inOff = stack.pop();
802  auto inSize = stack.pop();
803  auto outOff = stack.pop();
804  auto outSize = stack.pop();
805 
806  _gasMeter.commitCostBlock();
807 
808  // Require memory for in and out buffers
809  _memory.require(outOff, outSize); // Out buffer first as we guess
810  // it will be after the in one
811  _memory.require(inOff, inSize);
812 
813  auto noTransfer = m_builder.CreateICmpEQ(value, Constant::get(0));
814  auto transferCost = m_builder.CreateSelect(
815  noTransfer, m_builder.getInt64(0),
816  m_builder.getInt64(JITSchedule::valueTransferGas::value));
817  _gasMeter.count(transferCost, _runtimeManager.getJmpBuf(),
818  _runtimeManager.getGasPtr());
819 
820  if (inst == Instruction::CALL)
821  {
822  auto accountExists = _ext.exists(address);
823  auto noPenaltyCond = accountExists;
824  if (m_mode >= EVM_CLEARING)
825  noPenaltyCond = m_builder.CreateOr(accountExists, noTransfer);
826  auto penalty = m_builder.CreateSelect(noPenaltyCond,
827  m_builder.getInt64(0),
828  m_builder.getInt64(JITSchedule::callNewAccount::value));
829  _gasMeter.count(penalty, _runtimeManager.getJmpBuf(),
830  _runtimeManager.getGasPtr());
831  }
832 
833  if (m_mode >= EVM_ANTI_DOS)
834  {
835  auto gas = _runtimeManager.getGas();
836  auto gas64th = m_builder.CreateLShr(gas, 6);
837  auto gasMaxAllowed = m_builder.CreateZExt(
838  m_builder.CreateSub(gas, gas64th, "gas.maxallowed",
839  true, true), Type::Word);
840  auto cmp = m_builder.CreateICmpUGT(callGas, gasMaxAllowed);
841  callGas = m_builder.CreateSelect(cmp, gasMaxAllowed, callGas);
842  }
843 
844  _gasMeter.count(callGas, _runtimeManager.getJmpBuf(),
845  _runtimeManager.getGasPtr());
846  auto stipend = m_builder.CreateSelect(
847  noTransfer, m_builder.getInt64(0),
848  m_builder.getInt64(JITSchedule::callStipend::value));
849  auto gas = m_builder.CreateTrunc(callGas, Type::Gas, "call.gas.declared");
850  gas = m_builder.CreateAdd(gas, stipend, "call.gas", true, true);
851  auto r = _ext.call(kind, gas, address, value, inOff, inSize, outOff,
852  outSize);
853  auto ret =
854  m_builder.CreateICmpSGE(r, m_builder.getInt64(0), "call.ret");
855  auto rmagic = m_builder.CreateSelect(
856  ret, m_builder.getInt64(0), m_builder.getInt64(EVM_CALL_FAILURE),
857  "call.rmagic");
858  // TODO: optimize
859  auto finalGas = m_builder.CreateSub(r, rmagic, "call.finalgas");
860  _gasMeter.giveBack(finalGas);
861  stack.push(m_builder.CreateZExt(ret, Type::Word));
862  break;
863  }
864 
865  case Instruction::RETURN:
866  {
867  auto index = stack.pop();
868  auto size = stack.pop();
869 
870  _memory.require(index, size);
871  _runtimeManager.registerReturnData(index, size);
872 
873  _runtimeManager.exit(ReturnCode::Return);
874  break;
875  }
876 
878  {
879  auto dest = stack.pop();
880  if (m_mode >= EVM_ANTI_DOS)
881  {
882  auto destExists = _ext.exists(dest);
883  auto noPenaltyCond = destExists;
884  if (m_mode >= EVM_CLEARING)
885  {
886  auto addr = _ext.query(EVM_ADDRESS);
887  auto balance = _ext.balance(addr);
888  auto noTransfer = m_builder.CreateICmpEQ(balance,
889  Constant::get(0));
890  noPenaltyCond = m_builder.CreateOr(destExists, noTransfer);
891  }
892  auto penalty = m_builder.CreateSelect(
893  noPenaltyCond, m_builder.getInt64(0),
894  m_builder.getInt64(JITSchedule::callNewAccount::value));
895  _gasMeter.count(penalty, _runtimeManager.getJmpBuf(),
896  _runtimeManager.getGasPtr());
897  }
898  _ext.selfdestruct(dest);
899  }
900  // Fallthrough.
901  case Instruction::STOP:
902  _runtimeManager.exit(ReturnCode::Stop);
903  break;
904 
905  case Instruction::LOG0:
906  case Instruction::LOG1:
907  case Instruction::LOG2:
908  case Instruction::LOG3:
909  case Instruction::LOG4:
910  {
911  auto beginIdx = stack.pop();
912  auto numBytes = stack.pop();
913  _memory.require(beginIdx, numBytes);
914 
915  // This will commit the current cost block
916  _gasMeter.countLogData(numBytes);
917 
918  llvm::SmallVector<llvm::Value*, 4> topics;
919  auto numTopics = static_cast<size_t>(inst) - static_cast<size_t>(Instruction::LOG0);
920  for (size_t i = 0; i < numTopics; ++i)
921  topics.emplace_back(stack.pop());
922 
923  _ext.log(beginIdx, numBytes, topics);
924  break;
925  }
926 
927  default: // Invalid instruction - abort
928  _runtimeManager.exit(ReturnCode::OutOfGas);
929  it = _basicBlock.end() - 1; // finish block compilation
930  }
931  }
932 
933  _gasMeter.commitCostBlock();
934 
935  stack.finalize();
936 }
937 
938 
939 }
940 }
941 }
signed greater-than comparision
bitwise OR operation
Adapted from code found on http://stackoverflow.com/questions/180947/base64-decode-snippet-in-c Origi...
Definition: Arith256.cpp:15
exponential operation
unsigned modular addition
get external code size (from another contract)
void commitCostBlock()
Finalize cost-block by checking gas needed for the block before the block.
Definition: GasMeter.cpp:135
Compiler(Options const &_options, evm_mode _mode, llvm::LLVMContext &_llvmContext)
Definition: Compiler.cpp:33
unsigned modular multiplication
get the block&#39;s timestamp
place 1 byte item on stack
void countSha3Data(llvm::Value *_dataLength)
Count gas cost of SHA3 data.
Definition: GasMeter.cpp:116
MemoryRef extcode(llvm::Value *_addr)
Definition: Ext.cpp:393
conditionally alter the program counter
void log(llvm::Value *_memIdx, llvm::Value *_numBytes, llvm::ArrayRef< llvm::Value * > _topics)
Definition: Ext.cpp:422
llvm::Value * sload(llvm::Value *_index)
Definition: Ext.cpp:265
copy input data in current environment to memory
llvm::Value * query(evm_query_key _key)
Definition: Ext.cpp:313
addition operation
retrieve single byte from word
llvm::Value * sha3(llvm::Value *_inOff, llvm::Value *_inSize)
Definition: Ext.cpp:383
get execution origination address
Makes a log entry; 4 topics.
get the block&#39;s number
Current block difficulty for DIFFICULTY.
Definition: evm.h:116
static llvm::PointerType * RuntimePtr
Definition: Type.h:39
integer division operation
Current block number for NUMBER.
Definition: evm.h:118
assert(len-trim+(2 *lenIndices)<=WIDTH)
get the block&#39;s coinbase address
set a potential jump destination
get input data of current environment
llvm::Value * loadWord(llvm::Value *_addr)
Definition: Memory.cpp:162
llvm::BasicBlock * m_jumpTableBB
Block with a jump table.
Definition: Compiler.h:48
Transaction gas price for GASPRICE.
Definition: evm.h:114
void require(llvm::Value *_offset, llvm::Value *_size)
Requires the amount of memory to for data defined by offset and size. And counts gas fee for that mem...
Definition: Memory.cpp:199
save byte to memory
instr_idx firstInstrIdx() const
Definition: BasicBlock.h:74
halt execution and register account for later deletion
signed integer division operation
load word from storage
byte const * code_iterator
Definition: Common.h:11
#define ANY_PUSH
Definition: Instruction.h:169
signed less-than comparision
halt execution returning output data
llvm::Value * balance(llvm::Value *_address)
Definition: Ext.cpp:355
Address of the contract for ADDRESS.
Definition: evm.h:111
get address of currently executing account
#define a(i)
remove item from stack
get hash of most recent complete block
Message sender address for CALLER.
Definition: evm.h:112
Ran out of gas executing code of the transaction.
get the program counter
void copyBytes(llvm::Value *_srcPtr, llvm::Value *_srcSize, llvm::Value *_srcIndex, llvm::Value *_destMemIdx, llvm::Value *_byteCount)
Definition: Memory.cpp:209
static llvm::PointerType * BytePtr
Definition: Type.h:30
compute SHA3-256 hash
Config::Value_type Value
greater-than comparision
get size of code running in current environment
static llvm::Value * toBE(IRBuilder &_builder, llvm::Value *_word)
Definition: Endianness.h:14
Request CALLCODE.
Definition: evm.h:280
Current block timestamp for TIMESTAMP.
Definition: evm.h:119
llvm::Value * exists(llvm::Value *_address)
Definition: Ext.cpp:364
copies the highest item in the stack to the top of the stack
Makes a log entry; no topics.
get the size of active memory
ExecStats::duration max
Definition: ExecStats.cpp:36
std::vector< BasicBlock > createBasicBlocks(code_iterator _begin, code_iterator _end)
Definition: Compiler.cpp:41
get the block&#39;s gas limit
#define ANY_DUP
Definition: Instruction.h:202
llvm::Value * exp(llvm::Value *_arg1, llvm::Value *_arg2)
Definition: Arith256.cpp:379
get balance of the given account
save word to storage
Request CALL.
Definition: evm.h:278
message-call with another account&#39;s code only
less-than comparision
static llvm::IntegerType * Word
Definition: Type.h:21
Transaction origin address for ORIGIN.
Definition: evm.h:113
equality comparision
void storeWord(llvm::Value *_addr, llvm::Value *_word)
Definition: Memory.cpp:168
std::vector< byte > bytes
Definition: Common.h:75
void sstore(llvm::Value *_index, llvm::Value *_value)
Definition: Ext.cpp:274
get size of input data in current environment
void countExp(llvm::Value *_exponent)
Calculate & count additional gas cost for EXP instruction.
Definition: GasMeter.cpp:81
Current block miner address for COINBASE.
Definition: evm.h:115
extend length of signed integer
static llvm::ConstantInt * get(int64_t _n)
Returns word-size constant.
Definition: Type.cpp:55
llvm::Value * call(evm_call_kind _kind, llvm::Value *_gas, llvm::Value *_addr, llvm::Value *_value, llvm::Value *_inOff, llvm::Value *_inSize, llvm::Value *_outOff, llvm::Value *_outSize)
Definition: Ext.cpp:461
static llvm::Value * toNative(IRBuilder &_builder, llvm::Value *_word)
Definition: Endianness.h:15
static llvm::IntegerType * MainReturn
Main function return type.
Definition: Type.h:35
copy code running in current environment to memory
bitwise AND operation
void exit(ReturnCode _returnCode)
evm_mode
EVM compatibility mode aka chain mode.
Definition: evm.h:359
signed modulo remainder operation
Request DELEGATECALL. The value param ignored.
Definition: evm.h:279
llvm::Value * extcodesize(llvm::Value *_addr)
Definition: Ext.cpp:409
void compileBasicBlock(BasicBlock &_basicBlock, class RuntimeManager &_runtimeManager, class Arith256 &_arith, class Memory &_memory, class Ext &_ext, class GasMeter &_gasMeter)
Definition: Compiler.cpp:213
subtraction operation
mulitplication operation
like CALLCODE but keeps caller&#39;s value and sender
llvm::BasicBlock * llvm()
Definition: BasicBlock.h:72
#define b(i, j)
Instruction
Virtual machine bytecode instruction.
Definition: Instruction.h:39
code_iterator begin() const
Definition: BasicBlock.h:75
get the amount of available gas
copy external code (from another contract)
void giveBack(llvm::Value *_gas)
Give back an amount of gas not used by a call.
Definition: GasMeter.cpp:129
get deposited value by the instruction/transaction responsible for this execution ...
place 32 byte item on stack
get price of gas in current environment
IRBuilder m_builder
Helper class for generating IR.
Definition: Compiler.h:45
void countLogData(llvm::Value *_dataLength)
Count gas cost of LOG data.
Definition: GasMeter.cpp:108
alter the program counter to a jumpdest
swaps the highest and second highest value on the stack
void setJmpBuf(llvm::Value *_jmpBuf)
Makes a log entry; 1 topic.
bitwise XOR operation
uint8_t const size_t const size
Definition: sha3.h:20
std::unique_ptr< llvm::Module > compile(code_iterator _begin, code_iterator _end, std::string const &_id)
Definition: Compiler.cpp:149
uint8_t byte
Definition: Common.h:10
evm_mode m_mode
EVM compatibility mode.
Definition: Compiler.h:42
#define ANY_SWAP
Definition: Instruction.h:219
code_iterator end() const
Definition: BasicBlock.h:76
message-call into an account
get the block&#39;s difficulty
llvm::Function * m_mainFunc
Main program function.
Definition: Compiler.h:51
static llvm::IntegerType * Bool
Definition: Type.h:24
llvm::Value * getSize()
Definition: Memory.cpp:189
save word to memory
void storeByte(llvm::Value *_addr, llvm::Value *_byte)
Definition: Memory.cpp:174
std::tuple< llvm::Value *, llvm::Value * > create(llvm::Value *_gas, llvm::Value *_endowment, llvm::Value *_initOff, llvm::Value *_initSize)
Definition: Ext.cpp:487
void count(Instruction _inst)
Count step cost of instruction.
Definition: GasMeter.cpp:56
llvm::APInt readPushData(code_iterator &_curr, code_iterator _end)
Reads PUSH data from pointed fragment of bytecode and constructs number out of it Reading out of byte...
Definition: Instruction.cpp:12
static llvm::IntegerType * Size
Definition: Type.h:25
static void init(llvm::LLVMContext &_context)
Definition: Type.cpp:30
Current block gas limit for GASLIMIT.
Definition: evm.h:117
#define d(i)
Definition: sha.cpp:732
struct evm_uint160be address(struct evm_env *env)
Definition: capi.c:13
llvm::IRBuilder<> IRBuilder
static llvm::MDNode * expectTrue
Definition: Type.h:42
Makes a log entry; 3 topics.
void countSStore(class Ext &_ext, llvm::Value *_index, llvm::Value *_newValue)
Calculate & count gas cost for SSTORE instruction.
Definition: GasMeter.cpp:97
load word from memory
llvm::Value * blockHash(llvm::Value *_number)
Definition: Ext.cpp:373
simple not operator
static llvm::IntegerType * Gas
Definition: Type.h:26
llvm::Value * calldataload(llvm::Value *_index)
Definition: Ext.cpp:290
word32 word
Definition: config.h:308
static llvm::IntegerType * Byte
Definition: Type.h:29
void selfdestruct(llvm::Value *_beneficiary)
Definition: Ext.cpp:282
bitwise NOT opertation
modulo remainder operation
create a new account with associated code
Makes a log entry; 2 topics.