Browse Source

Initial implementation for CALLDATACOPY

[Delivers #80644732]
cl-refactor
artur-zawlocki 10 years ago
parent
commit
0d9740514a
  1. 30
      evmcc/Compiler.cpp
  2. 6
      evmcc/Ext.cpp
  3. 1
      evmcc/Ext.h
  4. 5
      evmcc/Memory.cpp
  5. 1
      evmcc/Memory.h

30
evmcc/Compiler.cpp

@ -736,6 +736,36 @@ std::unique_ptr<llvm::Module> Compiler::compile(const dev::bytes& bytecode)
break;
}
case Instruction::CALLDATACOPY:
{
auto zero256 = ConstantInt::get(Type::i256, 0);
auto destMemIdx = stack.pop();
auto srcDataIdx = stack.pop();
auto reqByteCount = stack.pop();
// FIXME: ensure memory size reqMemSize.
auto reqMemSize = builder.CreateAdd(destMemIdx, reqByteCount);
auto reqMemWord = builder.CreateSub(reqMemSize, ConstantInt::get(Type::i256, 32));
memory.loadWord(reqMemWord);
auto memPtr = memory.getData();
auto destPtr = builder.CreateGEP(memPtr, destMemIdx);
auto calldataPtr = ext.calldata();
auto srcPtr = builder.CreateGEP(calldataPtr, srcDataIdx);
auto calldataSize = ext.calldatasize();
// remaining data bytes:
auto remDataSize = builder.CreateSub(calldataSize, srcDataIdx);
auto remSizeNegative = builder.CreateICmpSLT(remDataSize, zero256);
auto bytesToCopy = builder.CreateSelect(remSizeNegative, zero256, remDataSize);
builder.CreateMemCpy(destPtr, srcPtr, bytesToCopy, 0);
break;
}
case Instruction::CALLDATALOAD:
{
auto index = stack.pop();

6
evmcc/Ext.cpp

@ -14,7 +14,6 @@ using llvm::types::i;
using Linkage = llvm::GlobalValue::LinkageTypes;
using dev::h256;
using dev::u256;
namespace evmcc
{
@ -70,7 +69,7 @@ Ext::Ext(llvm::IRBuilder<>& _builder, llvm::Module* module)
i256Ty, // i256 number;
i256Ty, // i256 difficulty;
i256Ty, // i256 gaslimit;
//m_builder.getInt8PtrTy()
m_builder.getInt8PtrTy() // byte* calldata
};
auto extDataTy = StructType::create(elements, "ext.Data");
@ -125,6 +124,7 @@ Value* Ext::timestamp() { return getDataElem(8, "timestamp"); }
Value* Ext::number() { return getDataElem(9, "number"); }
Value* Ext::difficulty() { return getDataElem(10, "difficulty"); }
Value* Ext::gaslimit() { return getDataElem(11, "gaslimit"); }
Value* Ext::calldata() { return getDataElem(12, "calldata"); }
Value* Ext::calldataload(Value* _index)
{
@ -218,7 +218,7 @@ EXPORT void ext_init(ExtData* _extData)
_extData->number = eth2llvm(ext.currentBlock.number);
_extData->difficulty = eth2llvm(ext.currentBlock.difficulty);
_extData->gaslimit = eth2llvm(ext.currentBlock.gasLimit);
//_extData->calldata = ext.data.data();
_extData->calldata = ext.data.data();
}
EXPORT void ext_store(i256* _index, i256* _value)

1
evmcc/Ext.h

@ -31,6 +31,7 @@ public:
llvm::Value* number();
llvm::Value* difficulty();
llvm::Value* gaslimit();
llvm::Value* calldata();
llvm::Value* balance(llvm::Value* _address);
void suicide(llvm::Value* _address);

5
evmcc/Memory.cpp

@ -126,6 +126,11 @@ void Memory::storeByte(llvm::Value* _addr, llvm::Value* _word)
dump(0);
}
llvm::Value* Memory::getData()
{
return m_builder.CreateLoad(m_data);
}
llvm::Value* Memory::getSize()
{
return m_builder.CreateLoad(m_size);

1
evmcc/Memory.h

@ -18,6 +18,7 @@ public:
llvm::Value* loadWord(llvm::Value* _addr);
void storeWord(llvm::Value* _addr, llvm::Value* _word);
void storeByte(llvm::Value* _addr, llvm::Value* _byte);
llvm::Value* getData();
llvm::Value* getSize();
void registerReturnData(llvm::Value* _index, llvm::Value* _size);

Loading…
Cancel
Save