Fabcoin Core  0.16.2
P2P Digital Currency
Ext.cpp
Go to the documentation of this file.
1 #include "Ext.h"
2 
4 #include <llvm/IR/IntrinsicInst.h>
5 #include <llvm/IR/Module.h>
7 
8 #include "RuntimeManager.h"
9 #include "Memory.h"
10 #include "Type.h"
11 #include "Endianness.h"
12 
13 namespace dev
14 {
15 namespace eth
16 {
17 namespace jit
18 {
19 
20 Ext::Ext(RuntimeManager& _runtimeManager, Memory& _memoryMan) :
21  RuntimeHelper(_runtimeManager),
22  m_memoryMan(_memoryMan)
23 {
24  m_funcs = decltype(m_funcs)();
25  m_argAllocas = decltype(m_argAllocas)();
26  m_size = m_builder.CreateAlloca(Type::Size, nullptr, "env.size");
27 }
28 
29 namespace
30 {
31 
32 using FuncDesc = std::tuple<char const*, llvm::FunctionType*>;
33 
34 llvm::FunctionType* getFunctionType(llvm::Type* _returnType, std::initializer_list<llvm::Type*> const& _argsTypes)
35 {
36  return llvm::FunctionType::get(_returnType, llvm::ArrayRef<llvm::Type*>{_argsTypes.begin(), _argsTypes.size()}, false);
37 }
38 
39 std::array<FuncDesc, sizeOf<EnvFunc>::value> const& getEnvFuncDescs()
40 {
41  static std::array<FuncDesc, sizeOf<EnvFunc>::value> descs{{
42  FuncDesc{"env_sload", getFunctionType(Type::Void, {Type::EnvPtr, Type::WordPtr, Type::WordPtr})},
43  FuncDesc{"env_sstore", getFunctionType(Type::Void, {Type::EnvPtr, Type::WordPtr, Type::WordPtr})},
44  FuncDesc{"env_sha3", getFunctionType(Type::Void, {Type::BytePtr, Type::Size, Type::WordPtr})},
45  FuncDesc{"env_balance", getFunctionType(Type::Void, {Type::WordPtr, Type::EnvPtr, Type::WordPtr})},
46  FuncDesc{"env_create", getFunctionType(Type::Void, {Type::EnvPtr, Type::GasPtr, Type::WordPtr, Type::BytePtr, Type::Size, Type::WordPtr})},
48  FuncDesc{"env_log", getFunctionType(Type::Void, {Type::EnvPtr, Type::BytePtr, Type::Size, Type::WordPtr, Type::WordPtr, Type::WordPtr, Type::WordPtr})},
49  FuncDesc{"env_blockhash", getFunctionType(Type::Void, {Type::EnvPtr, Type::WordPtr, Type::WordPtr})},
50  FuncDesc{"env_extcode", getFunctionType(Type::BytePtr, {Type::EnvPtr, Type::WordPtr, Type::Size->getPointerTo()})},
51  }};
52 
53  return descs;
54 }
55 
56 llvm::Function* createFunc(EnvFunc _id, llvm::Module* _module)
57 {
58  auto&& desc = getEnvFuncDescs()[static_cast<size_t>(_id)];
59  return llvm::Function::Create(std::get<1>(desc), llvm::Function::ExternalLinkage, std::get<0>(desc), _module);
60 }
61 
62 llvm::Function* getQueryFunc(llvm::Module* _module)
63 {
64  static const auto funcName = "evm.query";
65  auto func = _module->getFunction(funcName);
66  if (!func)
67  {
68  // TODO: Mark the function as pure to eliminate multiple calls.
69  auto i32 = llvm::IntegerType::getInt32Ty(_module->getContext());
70  auto fty = llvm::FunctionType::get(Type::Void, {Type::WordPtr, Type::EnvPtr, i32, Type::WordPtr}, false);
71  func = llvm::Function::Create(fty, llvm::Function::ExternalLinkage, funcName, _module);
72  func->addAttribute(1, llvm::Attribute::NoAlias);
73  func->addAttribute(1, llvm::Attribute::NoCapture);
74  func->addAttribute(4, llvm::Attribute::ReadOnly);
75  func->addAttribute(4, llvm::Attribute::NoAlias);
76  func->addAttribute(4, llvm::Attribute::NoCapture);
77  }
78  return func;
79 }
80 
81 llvm::Function* getUpdateFunc(llvm::Module* _module)
82 {
83  static const auto funcName = "evm.update";
84  auto func = _module->getFunction(funcName);
85  if (!func)
86  {
87  auto i32 = llvm::IntegerType::getInt32Ty(_module->getContext());
88  auto fty = llvm::FunctionType::get(Type::Void, {Type::EnvPtr, i32, Type::WordPtr, Type::WordPtr}, false);
89  func = llvm::Function::Create(fty, llvm::Function::ExternalLinkage, funcName, _module);
90  func->addAttribute(3, llvm::Attribute::ReadOnly);
91  func->addAttribute(3, llvm::Attribute::NoAlias);
92  func->addAttribute(3, llvm::Attribute::NoCapture);
93  func->addAttribute(4, llvm::Attribute::ReadOnly);
94  func->addAttribute(4, llvm::Attribute::NoAlias);
95  func->addAttribute(4, llvm::Attribute::NoCapture);
96  }
97  return func;
98 }
99 
100 llvm::StructType* getMemRefTy(llvm::Module* _module)
101 {
102  static const auto name = "evm.memref";
103  auto ty = _module->getTypeByName(name);
104  if (!ty)
105  ty = llvm::StructType::create({Type::BytePtr, Type::Size}, name);
106  return ty;
107 }
108 
109 llvm::Function* getCallFunc(llvm::Module* _module)
110 {
111  static const auto funcName = "call";
112  auto func = _module->getFunction(funcName);
113  if (!func)
114  {
115  auto i32 = llvm::IntegerType::getInt32Ty(_module->getContext());
116  auto hash160Ty = llvm::IntegerType::getIntNTy(_module->getContext(), 160);
117  auto fty = llvm::FunctionType::get(
118  Type::Gas,
119  {Type::EnvPtr, i32, Type::Gas, hash160Ty->getPointerTo(), Type::WordPtr, Type::BytePtr, Type::Size, Type::BytePtr, Type::Size},
120  false);
121  func = llvm::Function::Create(fty, llvm::Function::ExternalLinkage, "evm.call", _module);
122  func->addAttribute(4, llvm::Attribute::ReadOnly);
123  func->addAttribute(4, llvm::Attribute::NoAlias);
124  func->addAttribute(4, llvm::Attribute::NoCapture);
125  func->addAttribute(5, llvm::Attribute::ReadOnly);
126  func->addAttribute(5, llvm::Attribute::NoAlias);
127  func->addAttribute(5, llvm::Attribute::NoCapture);
128  func->addAttribute(6, llvm::Attribute::ReadOnly);
129  func->addAttribute(6, llvm::Attribute::NoCapture);
130  func->addAttribute(8, llvm::Attribute::NoCapture);
131  auto callFunc = func;
132 
133  // Create a call wrapper to handle additional checks.
134  func = llvm::Function::Create(fty, llvm::Function::PrivateLinkage, funcName, _module);
135  func->addAttribute(4, llvm::Attribute::ReadOnly);
136  func->addAttribute(4, llvm::Attribute::NoAlias);
137  func->addAttribute(4, llvm::Attribute::NoCapture);
138  func->addAttribute(5, llvm::Attribute::ReadOnly);
139  func->addAttribute(5, llvm::Attribute::NoAlias);
140  func->addAttribute(5, llvm::Attribute::NoCapture);
141  func->addAttribute(6, llvm::Attribute::ReadOnly);
142  func->addAttribute(6, llvm::Attribute::NoCapture);
143  func->addAttribute(8, llvm::Attribute::NoCapture);
144 
145  auto iter = func->arg_begin();
146  auto& env = *iter;
147  std::advance(iter, 1);
148  auto& callKind = *iter;
149  std::advance(iter, 1);
150  auto& gas = *iter;
151  std::advance(iter, 2);
152  auto& valuePtr = *iter;
153 
154  auto& ctx = _module->getContext();
155  llvm::IRBuilder<> builder(ctx);
156  auto entryBB = llvm::BasicBlock::Create(ctx, "Entry", func);
157  auto checkTransferBB = llvm::BasicBlock::Create(ctx, "CheckTransfer", func);
158  auto checkBalanceBB = llvm::BasicBlock::Create(ctx, "CheckBalance", func);
159  auto callBB = llvm::BasicBlock::Create(ctx, "Call", func);
160  auto failBB = llvm::BasicBlock::Create(ctx, "Fail", func);
161 
162  builder.SetInsertPoint(entryBB);
163  auto v = builder.CreateAlloca(Type::Word);
164  auto addr = builder.CreateAlloca(Type::Word);
165  auto queryFn = getQueryFunc(_module);
166  auto undef = llvm::UndefValue::get(Type::WordPtr);
167  builder.CreateCall(queryFn, {v, &env, builder.getInt32(EVM_CALL_DEPTH), undef});
168  auto depthPtr = builder.CreateBitCast(v, builder.getInt64Ty()->getPointerTo());
169  auto depth = builder.CreateLoad(depthPtr);
170  auto depthOk = builder.CreateICmpSLT(depth, builder.getInt64(1024));
171  builder.CreateCondBr(depthOk, checkTransferBB, failBB);
172 
173  builder.SetInsertPoint(checkTransferBB);
174  auto notDelegateCall = builder.CreateICmpNE(&callKind, builder.getInt32(EVM_DELEGATECALL));
175  llvm::Value* value = builder.CreateLoad(&valuePtr);
176  auto valueNonZero = builder.CreateICmpNE(value, Constant::get(0));
177  auto transfer = builder.CreateAnd(notDelegateCall, valueNonZero);
178  builder.CreateCondBr(transfer, checkBalanceBB, callBB);
179 
180  builder.SetInsertPoint(checkBalanceBB);
181  builder.CreateCall(queryFn, {addr, &env, builder.getInt32(EVM_ADDRESS), undef});
182  builder.CreateCall(queryFn, {v, &env, builder.getInt32(EVM_BALANCE), addr});
183  llvm::Value* balance = builder.CreateLoad(v);
184  balance = Endianness::toNative(builder, balance);
185  value = Endianness::toNative(builder, value);
186  auto balanceOk = builder.CreateICmpUGE(balance, value);
187  builder.CreateCondBr(balanceOk, callBB, failBB);
188 
189  builder.SetInsertPoint(callBB);
190  llvm::Value* args[9];
191  auto outIt = std::begin(args);
192  for (auto it = func->arg_begin(); it != func->arg_end(); ++it, ++outIt)
193  *outIt = &*it;
194  auto ret = builder.CreateCall(callFunc, args);
195  builder.CreateRet(ret);
196 
197  builder.SetInsertPoint(failBB);
198  auto failRet = builder.CreateOr(&gas, builder.getInt64(EVM_CALL_FAILURE));
199  builder.CreateRet(failRet);
200  }
201  return func;
202 }
203 
204 }
205 
206 
207 
209 {
210  auto& a = m_argAllocas[m_argCounter];
211  if (!a)
212  {
214  auto allocaIt = getMainFunction()->front().begin();
215  auto allocaPtr = &(*allocaIt);
216  std::advance(allocaIt, m_argCounter); // Skip already created allocas
217  m_builder.SetInsertPoint(allocaPtr);
218  a = m_builder.CreateAlloca(Type::Word, nullptr, {"a.", std::to_string(m_argCounter)});
219  }
220  ++m_argCounter;
221  return a;
222 }
223 
225 {
226  auto a = getArgAlloca();
227  m_builder.CreateStore(_value, a);
228  return a;
229 }
230 
231 llvm::CallInst* Ext::createCall(EnvFunc _funcId, std::initializer_list<llvm::Value*> const& _args)
232 {
233  auto& func = m_funcs[static_cast<size_t>(_funcId)];
234  if (!func)
235  func = createFunc(_funcId, getModule());
236 
237  m_argCounter = 0;
238  return m_builder.CreateCall(func, {_args.begin(), _args.size()});
239 }
240 
241 llvm::Value* Ext::createCABICall(llvm::Function* _func, std::initializer_list<llvm::Value*> const& _args)
242 {
243  auto args = llvm::SmallVector<llvm::Value*, 8>{_args};
244  for (auto&& farg: _func->args())
245  {
246  if (farg.hasByValAttr() || farg.getType()->isPointerTy())
247  {
248  auto& arg = args[farg.getArgNo()];
249  // TODO: Remove defensive check and always use it this way.
250  if (!arg->getType()->isPointerTy())
251  {
252  auto mem = getArgAlloca();
253  // TODO: The bitcast may be redundant
254  mem = m_builder.CreateBitCast(mem, arg->getType()->getPointerTo());
255  m_builder.CreateStore(arg, mem);
256  arg = mem;
257  }
258  }
259  }
260 
261  m_argCounter = 0;
262  return m_builder.CreateCall(_func, args);
263 }
264 
266 {
267  auto index = Endianness::toBE(m_builder, _index);
268  auto func = getQueryFunc(getModule());
269  auto pValue = getArgAlloca();
270  createCABICall(func, {pValue, getRuntimeManager().getEnvPtr(), m_builder.getInt32(EVM_SLOAD), index});
271  return Endianness::toNative(m_builder, m_builder.CreateLoad(pValue));
272 }
273 
274 void Ext::sstore(llvm::Value* _index, llvm::Value* _value)
275 {
276  auto index = Endianness::toBE(m_builder, _index);
277  auto value = Endianness::toBE(m_builder, _value);
278  auto func = getUpdateFunc(getModule());
279  createCABICall(func, {getRuntimeManager().getEnvPtr(), m_builder.getInt32(EVM_SSTORE), index, value});
280 }
281 
282 void Ext::selfdestruct(llvm::Value* _beneficiary)
283 {
284  auto func = getUpdateFunc(getModule());
285  auto b = Endianness::toBE(m_builder, _beneficiary);
286  auto undef = llvm::UndefValue::get(Type::WordPtr);
287  createCABICall(func, {getRuntimeManager().getEnvPtr(), m_builder.getInt32(EVM_SELFDESTRUCT), b, undef});
288 }
289 
291 {
292  auto ret = getArgAlloca();
293  auto result = m_builder.CreateBitCast(ret, Type::BytePtr);
294 
295  auto callDataSize = getRuntimeManager().getCallDataSize();
296  auto callDataSize64 = m_builder.CreateTrunc(callDataSize, Type::Size);
297  auto idxValid = m_builder.CreateICmpULT(_idx, callDataSize);
298  auto idx = m_builder.CreateTrunc(m_builder.CreateSelect(idxValid, _idx, callDataSize), Type::Size, "idx");
299 
300  auto end = m_builder.CreateNUWAdd(idx, m_builder.getInt64(32));
301  end = m_builder.CreateSelect(m_builder.CreateICmpULE(end, callDataSize64), end, callDataSize64);
302  auto copySize = m_builder.CreateNUWSub(end, idx);
303  auto padSize = m_builder.CreateNUWSub(m_builder.getInt64(32), copySize);
304  auto dataBegin = m_builder.CreateGEP(Type::Byte, getRuntimeManager().getCallData(), idx);
305  m_builder.CreateMemCpy(result, dataBegin, copySize, 1);
306  auto pad = m_builder.CreateGEP(Type::Byte, result, copySize);
307  m_builder.CreateMemSet(pad, m_builder.getInt8(0), padSize, 1);
308 
309  m_argCounter = 0; // Release args allocas. TODO: This is a bad design
310  return Endianness::toNative(m_builder, m_builder.CreateLoad(ret));
311 }
312 
314 {
315  auto func = getQueryFunc(getModule());
316  auto undef = llvm::UndefValue::get(Type::WordPtr);
317  auto pResult = getArgAlloca();
318  createCABICall(func, {pResult, getRuntimeManager().getEnvPtr(), m_builder.getInt32(_key), undef});
319  llvm::Value* v = m_builder.CreateLoad(pResult);
320 
321  switch (_key)
322  {
323  case EVM_GAS_PRICE:
324  case EVM_DIFFICULTY:
326  break;
327  case EVM_ADDRESS:
328  case EVM_CALLER:
329  case EVM_ORIGIN:
330  case EVM_COINBASE:
331  {
332  auto mask160 = llvm::APInt(160, -1, true).zext(256);
334  v = m_builder.CreateAnd(v, mask160);
335  break;
336  }
337  case EVM_GAS_LIMIT:
338  case EVM_NUMBER:
339  case EVM_TIMESTAMP:
340  {
341  // Use only 64-bit -- single word. The rest is uninitialized.
342  // We could have mask 63 bits, but there is very little to gain in cost
343  // of additional and operation.
344  auto mask64 = llvm::APInt(256, std::numeric_limits<uint64_t>::max());
345  v = m_builder.CreateAnd(v, mask64);
346  break;
347  }
348  default:
349  break;
350  }
351 
352  return v;
353 }
354 
356 {
357  auto func = getQueryFunc(getModule());
358  auto address = Endianness::toBE(m_builder, _address);
359  auto pResult = getArgAlloca();
360  createCABICall(func, {pResult, getRuntimeManager().getEnvPtr(), m_builder.getInt32(EVM_BALANCE), address});
361  return Endianness::toNative(m_builder, m_builder.CreateLoad(pResult));
362 }
363 
365 {
366  auto func = getQueryFunc(getModule());
367  auto address = Endianness::toBE(m_builder, _address);
368  auto pResult = getArgAlloca();
370  return m_builder.CreateTrunc(m_builder.CreateLoad(pResult), m_builder.getInt1Ty());
371 }
372 
374 {
375  auto func = getQueryFunc(getModule());
376  // TODO: We can explicitly trunc the number to i64. The optimizer will know
377  // that we care only about these 64 bit, not all 256.
378  auto pResult = getArgAlloca();
379  createCABICall(func, {pResult, getRuntimeManager().getEnvPtr(), m_builder.getInt32(EVM_BLOCKHASH), _number});
380  return Endianness::toNative(m_builder, m_builder.CreateLoad(pResult));
381 }
382 
384 {
385  auto begin = m_memoryMan.getBytePtr(_inOff);
386  auto size = m_builder.CreateTrunc(_inSize, Type::Size, "size");
387  auto ret = getArgAlloca();
388  createCall(EnvFunc::sha3, {begin, size, ret});
389  llvm::Value* hash = m_builder.CreateLoad(ret);
390  return Endianness::toNative(m_builder, hash);
391 }
392 
394 {
395  auto func = getQueryFunc(getModule());
396  // TODO: We care only about 20 bytes here. Can we do it better?
397  auto address = Endianness::toBE(m_builder, _addr);
398  auto vPtr = getArgAlloca();
400  auto memRefTy = getMemRefTy(getModule());
401  auto memRefPtr = m_builder.CreateBitCast(vPtr, memRefTy->getPointerTo());
402  auto memRef = m_builder.CreateLoad(memRefTy, memRefPtr, "memref");
403  auto code = m_builder.CreateExtractValue(memRef, 0, "code");
404  auto size = m_builder.CreateExtractValue(memRef, 1, "codesize");
405  auto size256 = m_builder.CreateZExt(size, Type::Word);
406  return {code, size256};
407 }
408 
410 {
411  auto func = getQueryFunc(getModule());
412  // TODO: We care only about 20 bytes here. Can we do it better?
413  auto address = Endianness::toBE(m_builder, _addr);
414  auto vPtr = getArgAlloca();
416  auto int64ty = m_builder.getInt64Ty();
417  auto sizePtr = m_builder.CreateBitCast(vPtr, int64ty->getPointerTo());
418  auto size = m_builder.CreateLoad(int64ty, sizePtr, "codesize");
419  return m_builder.CreateZExt(size, Type::Word);
420 }
421 
422 void Ext::log(llvm::Value* _memIdx, llvm::Value* _numBytes, llvm::ArrayRef<llvm::Value*> _topics)
423 {
424  if (!m_topics)
425  {
427  auto& entryBB = getMainFunction()->front();
428  m_builder.SetInsertPoint(&entryBB, entryBB.begin());
429  m_topics = m_builder.CreateAlloca(Type::Word, m_builder.getInt32(4), "topics");
430  }
431 
432  auto begin = m_memoryMan.getBytePtr(_memIdx);
433  auto size = m_builder.CreateTrunc(_numBytes, Type::Size, "size");
434 
435  for (size_t i = 0; i < _topics.size(); ++i)
436  {
437  auto t = Endianness::toBE(m_builder, _topics[i]);
438  auto p = m_builder.CreateConstGEP1_32(m_topics, static_cast<unsigned>(i));
439  m_builder.CreateStore(t, p);
440  }
441 
442  auto func = getUpdateFunc(getModule());
443  auto a = getArgAlloca();
444  auto memRefTy = getMemRefTy(getModule());
445  auto pMemRef = m_builder.CreateBitCast(a, memRefTy->getPointerTo());
446  auto pData = m_builder.CreateConstGEP2_32(memRefTy, pMemRef, 0, 0, "log.data");
447  m_builder.CreateStore(begin, pData);
448  auto pSize = m_builder.CreateConstGEP2_32(memRefTy, pMemRef, 0, 1, "log.size");
449  m_builder.CreateStore(size, pSize);
450 
451  auto b = getArgAlloca();
452  pMemRef = m_builder.CreateBitCast(b, memRefTy->getPointerTo());
453  pData = m_builder.CreateConstGEP2_32(memRefTy, pMemRef, 0, 0, "topics.data");
454  m_builder.CreateStore(m_builder.CreateBitCast(m_topics, m_builder.getInt8PtrTy()), pData);
455  pSize = m_builder.CreateConstGEP2_32(memRefTy, pMemRef, 0, 1, "topics.size");
456  m_builder.CreateStore(m_builder.getInt64(_topics.size() * 32), pSize);
457 
458  createCABICall(func, {getRuntimeManager().getEnvPtr(), m_builder.getInt32(EVM_LOG), a, b});
459 }
460 
462  llvm::Value* _gas,
463  llvm::Value* _addr,
464  llvm::Value* _value,
465  llvm::Value* _inOff,
466  llvm::Value* _inSize,
467  llvm::Value* _outOff,
468  llvm::Value* _outSize)
469 {
470  auto gas = m_builder.CreateTrunc(_gas, Type::Size);
471  auto addr = m_builder.CreateTrunc(_addr, m_builder.getIntNTy(160));
472  addr = Endianness::toBE(m_builder, addr);
473  auto inData = m_memoryMan.getBytePtr(_inOff);
474  auto inSize = m_builder.CreateTrunc(_inSize, Type::Size);
475  auto outData = m_memoryMan.getBytePtr(_outOff);
476  auto outSize = m_builder.CreateTrunc(_outSize, Type::Size);
477 
478  auto value = getArgAlloca();
479  m_builder.CreateStore(Endianness::toBE(m_builder, _value), value);
480 
481  auto func = getCallFunc(getModule());
482  return createCABICall(
483  func, {getRuntimeManager().getEnvPtr(), m_builder.getInt32(_kind), gas,
484  addr, value, inData, inSize, outData, outSize});
485 }
486 
487 std::tuple<llvm::Value*, llvm::Value*> Ext::create(llvm::Value* _gas,
488  llvm::Value* _endowment,
489  llvm::Value* _initOff,
490  llvm::Value* _initSize)
491 {
492  auto addrTy = m_builder.getIntNTy(160);
493  auto value = getArgAlloca();
494  m_builder.CreateStore(Endianness::toBE(m_builder, _endowment), value);
495  auto inData = m_memoryMan.getBytePtr(_initOff);
496  auto inSize = m_builder.CreateTrunc(_initSize, Type::Size);
497  auto pAddr =
498  m_builder.CreateBitCast(getArgAlloca(), m_builder.getInt8PtrTy());
499 
500  auto func = getCallFunc(getModule());
501  auto ret = createCABICall(
502  func, {getRuntimeManager().getEnvPtr(), m_builder.getInt32(EVM_CREATE),
503  _gas, llvm::UndefValue::get(addrTy), value, inData, inSize, pAddr,
504  m_builder.getInt64(20)});
505 
506  pAddr = m_builder.CreateBitCast(pAddr, addrTy->getPointerTo());
507  return std::tuple<llvm::Value*, llvm::Value*>{ret, pAddr};
508 }
509 }
510 }
511 }
llvm::Value * getBytePtr(llvm::Value *_index)
Definition: Memory.cpp:194
Adapted from code found on http://stackoverflow.com/questions/180947/base64-decode-snippet-in-c Origi...
Definition: Arith256.cpp:15
llvm::Module * getModule()
Reference to the IR module being compiled.
MemoryRef extcode(llvm::Value *_addr)
Definition: Ext.cpp:393
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
llvm::Value * query(evm_query_key _key)
Definition: Ext.cpp:313
Update storage entry.
Definition: evm.h:239
static llvm::Type * Void
Definition: Type.h:32
llvm::Value * sha3(llvm::Value *_inOff, llvm::Value *_inSize)
Definition: Ext.cpp:383
#define g(i)
Definition: sha.cpp:735
Current block difficulty for DIFFICULTY.
Definition: evm.h:116
Current block number for NUMBER.
Definition: evm.h:118
Transaction gas price for GASPRICE.
Definition: evm.h:114
bytes code
Definition: SmartVM.cpp:45
static llvm::PointerType * WordPtr
Definition: Type.h:22
llvm::Value * getArgAlloca()
Definition: Ext.cpp:208
std::array< llvm::Function *, sizeOf< EnvFunc >::value > m_funcs
Definition: Ext.h:79
llvm::Value * balance(llvm::Value *_address)
Definition: Ext.cpp:355
Address of the contract for ADDRESS.
Definition: evm.h:111
llvm::Value * m_size
Definition: Ext.h:77
#define a(i)
Request CREATE. Semantic of some params changes.
Definition: evm.h:281
Message sender address for CALLER.
Definition: evm.h:112
static llvm::PointerType * BytePtr
Definition: Type.h:30
Config::Value_type Value
static llvm::Value * toBE(IRBuilder &_builder, llvm::Value *_word)
Definition: Endianness.h:14
Current call depth.
Definition: evm.h:125
Current block timestamp for TIMESTAMP.
Definition: evm.h:119
llvm::Value * exists(llvm::Value *_address)
Definition: Ext.cpp:364
Balance of a given address for BALANCE.
Definition: evm.h:122
const char * name
Definition: rest.cpp:36
ExecStats::duration max
Definition: ExecStats.cpp:36
static llvm::IntegerType * Word
Definition: Type.h:21
evm_query_fn queryFn
Definition: JIT.cpp:140
Transaction origin address for ORIGIN.
Definition: evm.h:113
void sstore(llvm::Value *_index, llvm::Value *_value)
Definition: Ext.cpp:274
evm_call_kind
The kind of call-like instruction.
Definition: evm.h:277
Current block miner address for COINBASE.
Definition: evm.h:115
Block hash of by block number for BLOCKHASH.
Definition: evm.h:123
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
Check if an account exists.
Definition: evm.h:124
llvm::Function * getMainFunction()
Reference to the main module function.
Request DELEGATECALL. The value param ignored.
Definition: evm.h:279
llvm::Value * m_topics
Memory for array of up to 4 log topics TODO: Merge this memory with args allocas. ...
Definition: Ext.h:85
llvm::Value * extcodesize(llvm::Value *_addr)
Definition: Ext.cpp:409
Code by an address for EXTCODECOPY.
Definition: evm.h:120
#define b(i, j)
std::array< llvm::Value *, 8 > m_argAllocas
Definition: Ext.h:80
static llvm::PointerType * GasPtr
Definition: Type.h:27
Memory & m_memoryMan
Definition: Ext.h:75
Storage value of a given key for SLOAD.
Definition: evm.h:110
uint8_t const size_t const size
Definition: sha3.h:20
Mark contract as selfdestructed and set beneficiary address.
Definition: evm.h:241
Code size by an address for EXTCODESIZE.
Definition: evm.h:121
Log.
Definition: evm.h:240
llvm::Value * byPtr(llvm::Value *_value)
Definition: Ext.cpp:224
Compiler helper that depends on runtime data.
static llvm::IntegerType * Bool
Definition: Type.h:24
llvm::CallInst * createCall(EnvFunc _funcId, std::initializer_list< llvm::Value * > const &_args)
Definition: Ext.cpp:231
std::tuple< llvm::Value *, llvm::Value * > create(llvm::Value *_gas, llvm::Value *_endowment, llvm::Value *_initOff, llvm::Value *_initSize)
Definition: Ext.cpp:487
static llvm::IntegerType * Size
Definition: Type.h:25
IRBuilder & m_builder
Reference to parent compiler IR builder.
Current block gas limit for GASLIMIT.
Definition: evm.h:117
RuntimeManager & getRuntimeManager()
struct evm_uint160be address(struct evm_env *env)
Definition: capi.c:13
size_t m_argCounter
Definition: Ext.h:81
Ext(RuntimeManager &_runtimeManager, Memory &_memoryMan)
Definition: Ext.cpp:20
evm_query_key
The query callback key.
Definition: evm.h:109
llvm::Value * blockHash(llvm::Value *_number)
Definition: Ext.cpp:373
static llvm::IntegerType * Gas
Definition: Type.h:26
llvm::Value * calldataload(llvm::Value *_index)
Definition: Ext.cpp:290
static llvm::PointerType * EnvPtr
Definition: Type.h:37
static llvm::IntegerType * Byte
Definition: Type.h:29
void selfdestruct(llvm::Value *_beneficiary)
Definition: Ext.cpp:282
llvm::Value * createCABICall(llvm::Function *_func, std::initializer_list< llvm::Value * > const &_args)
Definition: Ext.cpp:241