Browse Source

Gas counting for CREATE instruction

cl-refactor
Paweł Bylica 10 years ago
parent
commit
b37ce8e972
  1. 5
      libevmjit-cpp/Env.cpp
  2. 6
      libevmjit/Compiler.cpp
  3. 10
      libevmjit/Ext.cpp
  4. 2
      libevmjit/Ext.h
  5. 3
      libevmjit/GasMeter.cpp

5
libevmjit-cpp/Env.cpp

@ -47,7 +47,7 @@ extern "C"
_env->suicide(right160(*_address)); _env->suicide(right160(*_address));
} }
EXPORT void env_create(ExtVMFace* _env, i256* _endowment, byte* _initBeg, uint64_t _initSize, h256* o_address) EXPORT void env_create(ExtVMFace* _env, i256* io_gas, i256* _endowment, byte* _initBeg, uint64_t _initSize, h256* o_address)
{ {
assert(_env->depth < 1024); // TODO: Handle call depth assert(_env->depth < 1024); // TODO: Handle call depth
@ -56,9 +56,10 @@ extern "C"
if (_env->balance(_env->myAddress) >= endowment) if (_env->balance(_env->myAddress) >= endowment)
{ {
_env->subBalance(endowment); _env->subBalance(endowment);
u256 gas; // TODO: Handle gas auto gas = llvm2eth(*io_gas);
OnOpFunc onOp {}; // TODO: Handle that thing OnOpFunc onOp {}; // TODO: Handle that thing
h256 address(_env->create(endowment, gas, {_initBeg, _initSize}, onOp), h256::AlignRight); h256 address(_env->create(endowment, gas, {_initBeg, _initSize}, onOp), h256::AlignRight);
*io_gas = eth2llvm(gas);
*o_address = address; *o_address = address;
} }
else else

6
libevmjit/Compiler.cpp

@ -741,7 +741,11 @@ void Compiler::compileBasicBlock(BasicBlock& _basicBlock, bytes const& _bytecode
auto initSize = stack.pop(); auto initSize = stack.pop();
_memory.require(initOff, initSize); _memory.require(initOff, initSize);
auto address = _ext.create(endowment, initOff, initSize); _gasMeter.commitCostBlock();
auto gas = _runtimeManager.getGas();
auto address = _ext.create(gas, endowment, initOff, initSize);
_runtimeManager.setGas(gas);
stack.push(address); stack.push(address);
break; break;
} }

10
libevmjit/Ext.cpp

@ -52,7 +52,7 @@ Ext::Ext(RuntimeManager& _runtimeManager, Memory& _memoryMan):
llvm::Type* sha3ArgsTypes[] = {Type::BytePtr, Type::Size, Type::WordPtr}; llvm::Type* sha3ArgsTypes[] = {Type::BytePtr, Type::Size, Type::WordPtr};
m_sha3 = llvm::Function::Create(llvm::FunctionType::get(Type::Void, sha3ArgsTypes, false), Linkage::ExternalLinkage, "env_sha3", module); m_sha3 = llvm::Function::Create(llvm::FunctionType::get(Type::Void, sha3ArgsTypes, false), Linkage::ExternalLinkage, "env_sha3", module);
llvm::Type* createArgsTypes[] = {Type::EnvPtr, Type::WordPtr, Type::BytePtr, Type::Size, Type::WordPtr}; llvm::Type* createArgsTypes[] = {Type::EnvPtr, Type::WordPtr, Type::WordPtr, Type::BytePtr, Type::Size, Type::WordPtr};
m_create = llvm::Function::Create(llvm::FunctionType::get(Type::Void, createArgsTypes, false), Linkage::ExternalLinkage, "env_create", module); m_create = llvm::Function::Create(llvm::FunctionType::get(Type::Void, createArgsTypes, false), Linkage::ExternalLinkage, "env_create", module);
llvm::Type* callArgsTypes[] = {Type::EnvPtr, Type::WordPtr, Type::WordPtr, Type::WordPtr, Type::BytePtr, Type::Size, Type::BytePtr, Type::Size, Type::WordPtr}; llvm::Type* callArgsTypes[] = {Type::EnvPtr, Type::WordPtr, Type::WordPtr, Type::WordPtr, Type::BytePtr, Type::Size, Type::BytePtr, Type::Size, Type::WordPtr};
@ -106,12 +106,14 @@ void Ext::suicide(llvm::Value* _address)
m_builder.CreateCall2(m_suicide, getRuntimeManager().getEnv(), m_args[0]); m_builder.CreateCall2(m_suicide, getRuntimeManager().getEnv(), m_args[0]);
} }
llvm::Value* Ext::create(llvm::Value* _endowment, llvm::Value* _initOff, llvm::Value* _initSize) llvm::Value* Ext::create(llvm::Value*& _gas, llvm::Value* _endowment, llvm::Value* _initOff, llvm::Value* _initSize)
{ {
m_builder.CreateStore(_endowment, m_args[0]); m_builder.CreateStore(_gas, m_args[0]);
m_builder.CreateStore(_endowment, m_arg2);
auto begin = m_memoryMan.getBytePtr(_initOff); auto begin = m_memoryMan.getBytePtr(_initOff);
auto size = m_builder.CreateTrunc(_initSize, Type::Size, "size"); auto size = m_builder.CreateTrunc(_initSize, Type::Size, "size");
createCall(m_create, getRuntimeManager().getEnv(), m_args[0], begin, size, m_args[1]); createCall(m_create, getRuntimeManager().getEnv(), m_args[0], m_arg2, begin, size, m_args[1]);
_gas = m_builder.CreateLoad(m_args[0]); // Return gas
llvm::Value* address = m_builder.CreateLoad(m_args[1]); llvm::Value* address = m_builder.CreateLoad(m_args[1]);
address = Endianness::toNative(m_builder, address); address = Endianness::toNative(m_builder, address);
return address; return address;

2
libevmjit/Ext.h

@ -29,7 +29,7 @@ public:
llvm::Value* balance(llvm::Value* _address); llvm::Value* balance(llvm::Value* _address);
void suicide(llvm::Value* _address); void suicide(llvm::Value* _address);
llvm::Value* calldataload(llvm::Value* _index); llvm::Value* calldataload(llvm::Value* _index);
llvm::Value* create(llvm::Value* _endowment, llvm::Value* _initOff, llvm::Value* _initSize); llvm::Value* create(llvm::Value*& _gas, llvm::Value* _endowment, llvm::Value* _initOff, llvm::Value* _initSize);
llvm::Value* call(llvm::Value*& _gas, llvm::Value* _receiveAddress, llvm::Value* _value, llvm::Value* _inOff, llvm::Value* _inSize, llvm::Value* _outOff, llvm::Value* _outSize, llvm::Value* _codeAddress); llvm::Value* call(llvm::Value*& _gas, llvm::Value* _receiveAddress, llvm::Value* _value, llvm::Value* _inOff, llvm::Value* _inSize, llvm::Value* _outOff, llvm::Value* _outSize, llvm::Value* _codeAddress);
llvm::Value* sha3(llvm::Value* _inOff, llvm::Value* _inSize); llvm::Value* sha3(llvm::Value* _inOff, llvm::Value* _inSize);

3
libevmjit/GasMeter.cpp

@ -83,7 +83,7 @@ bool isCostBlockEnd(Instruction _inst)
// Basic block terminators like STOP are not needed on the list // Basic block terminators like STOP are not needed on the list
// as cost will be commited at the end of basic block // as cost will be commited at the end of basic block
// CALL & CALLCODE are commited manually // CALL, CALLCODE & CREATE are commited manually
switch (_inst) switch (_inst)
{ {
@ -94,7 +94,6 @@ bool isCostBlockEnd(Instruction _inst)
case Instruction::MSTORE8: case Instruction::MSTORE8:
case Instruction::SSTORE: case Instruction::SSTORE:
case Instruction::GAS: case Instruction::GAS:
case Instruction::CREATE:
return true; return true;
default: default:

Loading…
Cancel
Save