mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-20 03:36:44 +00:00
parent
42b14ae334
commit
df932921dc
12 changed files with 79 additions and 23 deletions
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
60146000600a37600053600a6014f2
|
||||
60326000600a37600053600a6014f2
|
||||
|
|
|
|||
|
|
@ -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
Normal file
1
evmcc/test/ext/codecopy1.evm
Normal file
|
|
@ -0,0 +1 @@
|
|||
60146000600a39600053600a6014f2
|
||||
13
evmcc/test/ext/codecopy1.lll
Normal file
13
evmcc/test/ext/codecopy1.lll
Normal file
|
|
@ -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
Normal file
1
evmcc/test/ext/codecopy2.evm
Normal file
|
|
@ -0,0 +1 @@
|
|||
606464e8d4a510006000396000536000600af2
|
||||
13
evmcc/test/ext/codecopy2.lll
Normal file
13
evmcc/test/ext/codecopy2.lll
Normal file
|
|
@ -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
Normal file
1
evmcc/test/ext/codecopy3.evm
Normal file
|
|
@ -0,0 +1 @@
|
|||
3860006000396000536000600af2
|
||||
13
evmcc/test/ext/codecopy3.lll
Normal file
13
evmcc/test/ext/codecopy3.lll
Normal file
|
|
@ -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…
Reference in a new issue