Browse Source

Codegen for CODECOPY.

[Delivers #80644732]
cl-refactor
artur-zawlocki 10 years ago
parent
commit
2e3e764fb5
  1. 34
      evmcc/Compiler.cpp
  2. 4
      evmcc/ExecutionEngine.cpp
  3. 16
      evmcc/Ext.cpp
  4. 2
      evmcc/Ext.h
  5. 2
      evmcc/test/ext/calldatacopy1.evm
  6. 2
      evmcc/test/ext/calldatacopy1.lll
  7. 1
      evmcc/test/ext/codecopy1.evm
  8. 13
      evmcc/test/ext/codecopy1.lll
  9. 1
      evmcc/test/ext/codecopy2.evm
  10. 13
      evmcc/test/ext/codecopy2.lll
  11. 1
      evmcc/test/ext/codecopy3.evm
  12. 13
      evmcc/test/ext/codecopy3.lll

34
evmcc/Compiler.cpp

@ -736,32 +736,39 @@ std::unique_ptr<llvm::Module> Compiler::compile(const dev::bytes& bytecode)
break;
}
case Instruction::CODESIZE:
{
auto value = ext.codesize();
stack.push(value);
break;
}
case Instruction::CALLDATACOPY:
case Instruction::CODECOPY:
{
auto zero256 = ConstantInt::get(Type::i256, 0);
auto destMemIdx = stack.pop();
auto srcDataIdx = stack.pop();
auto srcIdx = stack.pop();
auto reqBytes = stack.pop();
// FIXME: ensure memory size reqMemSize.
auto reqMemSize = builder.CreateAdd(destMemIdx, reqBytes, "req_mem_size");
memory.require(reqMemSize);
auto memPtr = memory.getData();
auto destPtr = builder.CreateGEP(memPtr, destMemIdx, "dest_mem_ptr");
auto calldataPtr = ext.calldata();
auto srcPtr = builder.CreateGEP(calldataPtr, srcDataIdx, "src_idx");
auto srcBasePtr = inst == Instruction::CALLDATACOPY ? ext.calldata() : ext.code();
auto srcPtr = builder.CreateGEP(srcBasePtr, srcIdx, "src_idx");
auto calldataSize = ext.calldatasize();
auto srcSize = inst == Instruction::CALLDATACOPY ? ext.calldatasize() : ext.codesize();
// remaining data bytes:
auto remDataSize = builder.CreateSub(calldataSize, srcDataIdx);
auto remSizeNegative = builder.CreateICmpSLT(remDataSize, zero256);
auto remDataBytes = builder.CreateSelect(remSizeNegative, zero256, remDataSize, "rem_data_bytes");
auto remSrcSize = builder.CreateSub(srcSize, srcIdx);
auto remSizeNegative = builder.CreateICmpSLT(remSrcSize, zero256);
auto remSrcBytes = builder.CreateSelect(remSizeNegative, zero256, remSrcSize, "rem_src_bytes");
auto tooLittleDataBytes = builder.CreateICmpULT(remDataBytes, reqBytes);
auto bytesToCopy = builder.CreateSelect(tooLittleDataBytes, remDataBytes, reqBytes, "bytes_to_copy");
auto tooLittleDataBytes = builder.CreateICmpULT(remSrcBytes, reqBytes);
auto bytesToCopy = builder.CreateSelect(tooLittleDataBytes, remSrcBytes, reqBytes, "bytes_to_copy");
builder.CreateMemCpy(destPtr, srcPtr, bytesToCopy, 0);
@ -783,13 +790,6 @@ std::unique_ptr<llvm::Module> Compiler::compile(const dev::bytes& bytecode)
break;
}
case Instruction::CODESIZE:
{
auto value = Constant::get(bytecode.size());
stack.push(value);
break;
}
case Instruction::PREVHASH:
{
auto value = ext.prevhash();

4
evmcc/ExecutionEngine.cpp

@ -85,6 +85,8 @@ int ExecutionEngine::run(std::unique_ptr<llvm::Module> _module)
ext->currentBlock.gasLimit = 1008;
std::string calldata = "Hello the Beautiful World of Ethereum!";
ext->data = calldata;
unsigned char fakecode[] = { 0x0d, 0x0e, 0x0a, 0x0d, 0x0b, 0x0e, 0xe, 0xf };
ext->code = decltype(ext->code)(fakecode, 8);
// Init runtime
uint64_t gas = 1000000;
@ -114,4 +116,4 @@ int ExecutionEngine::run(std::unique_ptr<llvm::Module> _module)
return 0;
}
}
}

16
evmcc/Ext.cpp

@ -37,7 +37,9 @@ struct ExtData
i256 number;
i256 difficulty;
i256 gaslimit;
i256 codesize;
const byte* calldata;
const byte* code;
};
Ext::Ext(llvm::IRBuilder<>& _builder, llvm::Module* module)
@ -47,6 +49,8 @@ Ext::Ext(llvm::IRBuilder<>& _builder, llvm::Module* module)
auto i256Ty = m_builder.getIntNTy(256);
auto i256PtrTy = i256Ty->getPointerTo();
auto i8PtrTy = m_builder.getInt8PtrTy();
m_args[0] = m_builder.CreateAlloca(i256Ty, nullptr, "ext.index");
m_args[1] = m_builder.CreateAlloca(i256Ty, nullptr, "ext.value");
m_arg2 = m_builder.CreateAlloca(i256Ty, nullptr, "ext.arg2");
@ -69,7 +73,10 @@ Ext::Ext(llvm::IRBuilder<>& _builder, llvm::Module* module)
i256Ty, // i256 number;
i256Ty, // i256 difficulty;
i256Ty, // i256 gaslimit;
m_builder.getInt8PtrTy() // byte* calldata
i256Ty, // i256 codesize
i8PtrTy, // byte* calldata
i8PtrTy, // byte* code
};
auto extDataTy = StructType::create(elements, "ext.Data");
@ -88,7 +95,6 @@ Ext::Ext(llvm::IRBuilder<>& _builder, llvm::Module* module)
m_sha3 = Function::Create(TypeBuilder<void(i<256>*, i<256>*, i<256>*), true>::get(ctx), Linkage::ExternalLinkage, "ext_sha3", module);
m_exp = Function::Create(TypeBuilder<void(i<256>*, i<256>*, i<256>*), true>::get(ctx), Linkage::ExternalLinkage, "ext_exp", module);
m_builder.CreateCall(m_init, m_data);
}
@ -124,7 +130,9 @@ 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::codesize() { return getDataElem(12, "codesize"); }
Value* Ext::calldata() { return getDataElem(13, "calldata"); }
Value* Ext::code() { return getDataElem(14, "code"); }
Value* Ext::calldataload(Value* _index)
{
@ -219,7 +227,9 @@ 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->codesize = eth2llvm(ext.code.size());
_extData->calldata = ext.data.data();
_extData->code = ext.code.data();
}
EXPORT void ext_store(i256* _index, i256* _value)

2
evmcc/Ext.h

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

2
evmcc/test/ext/calldatacopy1.evm

@ -1 +1 @@
60146000600a37600053600a6014f2
60326000600a37600053600a6014f2

2
evmcc/test/ext/calldatacopy1.lll

@ -1,5 +1,5 @@
(asm
20 ;; byte count
50 ;; byte count
0 ;; source index in calldata array
10 ;; dest index in memory
CALLDATACOPY

1
evmcc/test/ext/codecopy1.evm

@ -0,0 +1 @@
60146000600a39600053600a6014f2

13
evmcc/test/ext/codecopy1.lll

@ -0,0 +1,13 @@
(asm
20 ;; byte count
0 ;; source index in code array
10 ;; dest index in memory
CODECOPY
0
MLOAD ;; to dump memory
10
20
RETURN
)

1
evmcc/test/ext/codecopy2.evm

@ -0,0 +1 @@
606464e8d4a510006000396000536000600af2

13
evmcc/test/ext/codecopy2.lll

@ -0,0 +1,13 @@
(asm
100 ;; byte count
1000000000000 ;; source index in code array
0 ;; dest index in memory
CODECOPY
0
MLOAD ;; to dump memory
0
10
RETURN
)

1
evmcc/test/ext/codecopy3.evm

@ -0,0 +1 @@
3860006000396000536000600af2

13
evmcc/test/ext/codecopy3.lll

@ -0,0 +1,13 @@
(asm
CODESIZE ;; byte count
0 ;; source index in code array
0 ;; dest index in memory
CODECOPY
0
MLOAD ;; to dump memory
0
10
RETURN
)
Loading…
Cancel
Save