@ -8,10 +8,9 @@
# include <libdevcrypto/SHA3.h>
# include "Runtime.h"
# include "Type.h"
# include "Endianness.h"
using namespace llvm ;
namespace dev
{
namespace eth
@ -27,27 +26,14 @@ inline u256 fromAddress(Address _a)
struct ExtData
{
i256 address ;
i256 caller ;
i256 origin ;
i256 callvalue ;
i256 calldatasize ;
i256 gasprice ;
i256 prevhash ;
i256 coinbase ;
i256 timestamp ;
i256 number ;
i256 difficulty ;
i256 gaslimit ;
i256 codesize ;
const byte * calldata ;
const byte * code ;
} ;
Ext : : Ext ( llvm : : IRBuilder < > & _build er) :
CompilerHelper ( _build er)
Ext : : Ext ( RuntimeManager & _runtimeManager ) :
RuntimeHelper ( _runtimeManager )
{
auto & & ctx = _builder . getContext ( ) ;
auto & & ctx = m_builder . getContext ( ) ;
auto module = getModule ( ) ;
auto i256Ty = m_builder . getIntNTy ( 256 ) ;
@ -64,52 +50,27 @@ Ext::Ext(llvm::IRBuilder<>& _builder):
m_arg7 = m_builder . CreateAlloca ( i256Ty , nullptr , " ext.arg7 " ) ;
m_arg8 = m_builder . CreateAlloca ( i256Ty , nullptr , " ext.arg8 " ) ;
Type * elements [ ] = {
i256Ty , // i256 address;
i256Ty , // i256 caller;
i256Ty , // i256 origin;
i256Ty , // i256 callvalue;
i256Ty , // i256 calldatasize;
i256Ty , // i256 gasprice;
i256Ty , // i256 prevhash;
i256Ty , // i256 coinbase;
i256Ty , // i256 timestamp;
i256Ty , // i256 number;
i256Ty , // i256 difficulty;
i256Ty , // i256 gaslimit;
i256Ty , // i256 codesize
i8PtrTy , // byte* calldata
i8PtrTy , // byte* code
} ;
auto extDataTy = StructType : : create ( elements , " ext.Data " ) ;
m_data = m_builder . CreateAlloca ( extDataTy , nullptr , " ext.data " ) ;
using llvm : : types : : i ;
using Linkage = llvm : : GlobalValue : : LinkageTypes ;
m_init = Function : : Create ( FunctionType : : get ( m_builder . getVoidTy ( ) , extDataTy - > getPointerTo ( ) , false ) , Linkage : : ExternalLinkage , " ext_init " , module ) ;
m_store = Function : : Create ( TypeBuilder < void ( i < 256 > * , i < 256 > * ) , true > : : get ( ctx ) , Linkage : : ExternalLinkage , " ext_store " , module ) ;
m_setStore = Function : : Create ( TypeBuilder < void ( i < 256 > * , i < 256 > * ) , true > : : get ( ctx ) , Linkage : : ExternalLinkage , " ext_setStore " , module ) ;
m_calldataload = Function : : Create ( TypeBuilder < void ( i < 256 > * , i < 256 > * ) , true > : : get ( ctx ) , Linkage : : ExternalLinkage , " ext_calldataload " , module ) ;
m_balance = Function : : Create ( TypeBuilder < void ( i < 256 > * , i < 256 > * ) , true > : : get ( ctx ) , Linkage : : ExternalLinkage , " ext_balance " , module ) ;
m_suicide = Function : : Create ( TypeBuilder < void ( i < 256 > * ) , true > : : get ( ctx ) , Linkage : : ExternalLinkage , " ext_suicide " , module ) ;
m_create = Function : : Create ( TypeBuilder < void ( i < 256 > * , i < 256 > * , i < 256 > * , i < 256 > * ) , true > : : get ( ctx ) , Linkage : : ExternalLinkage , " ext_create " , module ) ;
Type * args [ ] = { i256PtrTy , i256PtrTy , i256PtrTy , i256PtrTy , i256PtrTy , i256PtrTy , i256PtrTy , i256PtrTy , i256PtrTy } ;
m_call = Function : : Create ( FunctionType : : get ( m_builder . getVoidTy ( ) , args , false ) , Linkage : : ExternalLinkage , " ext_call " , module ) ;
m_bswap = Intrinsic : : getDeclaration ( module , Intrinsic : : bswap , i256Ty ) ;
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_codeAt = Function : : Create ( TypeBuilder < i < 8 > * ( i < 256 > * ) , true > : : get ( ctx ) , Linkage : : ExternalLinkage , " ext_codeAt " , module ) ;
m_codesizeAt = Function : : Create ( TypeBuilder < void ( i < 256 > * , i < 256 > * ) , true > : : get ( ctx ) , Linkage : : ExternalLinkage , " ext_codesizeAt " , module ) ;
m_builder . CreateCall ( m_init , m_data ) ;
llvm : : Type * argsTypes [ ] = { Type : : RuntimePtr , Type : : WordPtr , Type : : WordPtr , Type : : WordPtr , Type : : WordPtr , Type : : WordPtr , Type : : WordPtr , Type : : WordPtr , Type : : WordPtr , Type : : WordPtr } ;
m_store = llvm : : Function : : Create ( llvm : : FunctionType : : get ( Type : : Void , { argsTypes , 3 } , false ) , Linkage : : ExternalLinkage , " ext_store " , module ) ;
m_setStore = llvm : : Function : : Create ( llvm : : FunctionType : : get ( Type : : Void , { argsTypes , 3 } , false ) , Linkage : : ExternalLinkage , " ext_setStore " , module ) ;
m_calldataload = llvm : : Function : : Create ( llvm : : FunctionType : : get ( Type : : Void , { argsTypes , 3 } , false ) , Linkage : : ExternalLinkage , " ext_calldataload " , module ) ;
m_balance = llvm : : Function : : Create ( llvm : : FunctionType : : get ( Type : : Void , { argsTypes , 3 } , false ) , Linkage : : ExternalLinkage , " ext_balance " , module ) ;
m_suicide = llvm : : Function : : Create ( llvm : : FunctionType : : get ( Type : : Void , { argsTypes , 2 } , false ) , Linkage : : ExternalLinkage , " ext_suicide " , module ) ;
m_create = llvm : : Function : : Create ( llvm : : FunctionType : : get ( Type : : Void , { argsTypes , 5 } , false ) , Linkage : : ExternalLinkage , " ext_create " , module ) ;
m_call = llvm : : Function : : Create ( llvm : : FunctionType : : get ( Type : : Void , argsTypes , false ) , Linkage : : ExternalLinkage , " ext_call " , module ) ;
m_sha3 = llvm : : Function : : Create ( llvm : : FunctionType : : get ( Type : : Void , { argsTypes , 4 } , false ) , Linkage : : ExternalLinkage , " ext_sha3 " , module ) ;
m_exp = llvm : : Function : : Create ( llvm : : FunctionType : : get ( Type : : Void , { argsTypes , 4 } , false ) , Linkage : : ExternalLinkage , " ext_exp " , module ) ;
m_codeAt = llvm : : Function : : Create ( llvm : : FunctionType : : get ( Type : : BytePtr , Type : : WordPtr , false ) , Linkage : : ExternalLinkage , " ext_codeAt " , module ) ;
m_codesizeAt = llvm : : Function : : Create ( llvm : : FunctionType : : get ( Type : : Void , { argsTypes , 3 } , false ) , Linkage : : ExternalLinkage , " ext_codesizeAt " , module ) ;
}
llvm : : Value * Ext : : store ( llvm : : Value * _index )
{
m_builder . CreateStore ( _index , m_args [ 0 ] ) ;
m_builder . CreateCall ( m_store , m_args ) ; // Uses native endianness
m_builder . CreateCall3 ( m_store , getRuntimeManager ( ) . getRuntimePtr ( ) , m_args [ 0 ] , m_args [ 1 ] ) ; // Uses native endianness
return m_builder . CreateLoad ( m_args [ 1 ] ) ;
}
@ -117,62 +78,40 @@ void Ext::setStore(llvm::Value* _index, llvm::Value* _value)
{
m_builder . CreateStore ( _index , m_args [ 0 ] ) ;
m_builder . CreateStore ( _value , m_args [ 1 ] ) ;
m_builder . CreateCall ( m_setStore , m_args ) ; // Uses native endianness
}
Value * Ext : : getDataElem ( unsigned _index , const Twine & _name )
{
auto valuePtr = m_builder . CreateStructGEP ( m_data , _index , _name ) ;
return m_builder . CreateLoad ( valuePtr ) ;
m_builder . CreateCall3 ( m_setStore , getRuntimeManager ( ) . getRuntimePtr ( ) , m_args [ 0 ] , m_args [ 1 ] ) ; // Uses native endianness
}
Value * Ext : : address ( ) { return getDataElem ( 0 , " address " ) ; }
Value * Ext : : caller ( ) { return getDataElem ( 1 , " caller " ) ; }
Value * Ext : : origin ( ) { return getDataElem ( 2 , " origin " ) ; }
Value * Ext : : callvalue ( ) { return getDataElem ( 3 , " callvalue " ) ; }
Value * Ext : : calldatasize ( ) { return getDataElem ( 4 , " calldatasize " ) ; }
Value * Ext : : gasprice ( ) { return getDataElem ( 5 , " gasprice " ) ; }
Value * Ext : : prevhash ( ) { return getDataElem ( 6 , " prevhash " ) ; }
Value * Ext : : coinbase ( ) { return getDataElem ( 7 , " coinbase " ) ; }
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 : : codesize ( ) { return getDataElem ( 12 , " codesize " ) ; }
Value * Ext : : calldata ( ) { return getDataElem ( 13 , " calldata " ) ; }
Value * Ext : : code ( ) { return getDataElem ( 14 , " code " ) ; }
Value * Ext : : calldataload ( Value * _index )
llvm : : Value * Ext : : calldataload ( llvm : : Value * _index )
{
m_builder . CreateStore ( _index , m_args [ 0 ] ) ;
m_builder . CreateCall ( m_calldataload , m_args ) ;
m_builder . CreateCall3 ( m_calldataload , getRuntimeManager ( ) . getRuntimePtr ( ) , m_args [ 0 ] , m_args [ 1 ] ) ;
auto ret = m_builder . CreateLoad ( m_args [ 1 ] ) ;
return Endianness : : toNative ( m_builder , ret ) ;
}
Value * Ext : : balance ( Value * _address )
llvm : : Value * Ext : : balance ( llvm : : Value * _address )
{
auto address = Endianness : : toBE ( m_builder , _address ) ;
m_builder . CreateStore ( address , m_args [ 0 ] ) ;
m_builder . CreateCall ( m_balance , m_args ) ;
m_builder . CreateCall3 ( m_balance , getRuntimeManager ( ) . getRuntimePtr ( ) , m_args [ 0 ] , m_args [ 1 ] ) ;
return m_builder . CreateLoad ( m_args [ 1 ] ) ;
}
void Ext : : suicide ( Value * _address )
void Ext : : suicide ( llvm : : Value * _address )
{
auto address = Endianness : : toBE ( m_builder , _address ) ;
m_builder . CreateStore ( address , m_args [ 0 ] ) ;
m_builder . CreateCall ( m_suicide , m_args [ 0 ] ) ;
m_builder . CreateCall2 ( m_suicide , getRuntimeManager ( ) . getRuntimePtr ( ) , m_args [ 0 ] ) ;
}
Value * Ext : : create ( llvm : : Value * _endowment , llvm : : Value * _initOff , llvm : : Value * _initSize )
llvm : : Value * Ext : : create ( llvm : : Value * _endowment , llvm : : Value * _initOff , llvm : : Value * _initSize )
{
m_builder . CreateStore ( _endowment , m_args [ 0 ] ) ;
m_builder . CreateStore ( _initOff , m_arg2 ) ;
m_builder . CreateStore ( _initSize , m_arg3 ) ;
Value * args [ ] = { m_args [ 0 ] , m_arg2 , m_arg3 , m_args [ 1 ] } ;
llvm : : Value * args [ ] = { getRuntimeManager ( ) . getRuntimePtr ( ) , m_args [ 0 ] , m_arg2 , m_arg3 , m_args [ 1 ] } ;
m_builder . CreateCall ( m_create , args ) ;
Value * address = m_builder . CreateLoad ( m_args [ 1 ] ) ;
llvm : : Value * address = m_builder . CreateLoad ( m_args [ 1 ] ) ;
address = Endianness : : toNative ( m_builder , address ) ;
return address ;
}
@ -190,7 +129,7 @@ llvm::Value* Ext::call(llvm::Value*& _gas, llvm::Value* _receiveAddress, llvm::V
auto codeAddress = Endianness : : toBE ( m_builder , _codeAddress ) ;
m_builder . CreateStore ( codeAddress , m_arg8 ) ;
llvm : : Value * args [ ] = { m_args [ 0 ] , m_arg2 , m_arg3 , m_arg4 , m_arg5 , m_arg6 , m_arg7 , m_arg8 , m_args [ 1 ] } ;
llvm : : Value * args [ ] = { getRuntimeManager ( ) . getRuntimePtr ( ) , m_args [ 0 ] , m_arg2 , m_arg3 , m_arg4 , m_arg5 , m_arg6 , m_arg7 , m_arg8 , m_args [ 1 ] } ;
m_builder . CreateCall ( m_call , args ) ;
_gas = m_builder . CreateLoad ( m_args [ 0 ] ) ; // Return gas
return m_builder . CreateLoad ( m_args [ 1 ] ) ;
@ -200,9 +139,9 @@ llvm::Value* Ext::sha3(llvm::Value* _inOff, llvm::Value* _inSize)
{
m_builder . CreateStore ( _inOff , m_args [ 0 ] ) ;
m_builder . CreateStore ( _inSize , m_arg2 ) ;
llvm : : Value * args [ ] = { m_args [ 0 ] , m_arg2 , m_args [ 1 ] } ;
llvm : : Value * args [ ] = { getRuntimeManager ( ) . getRuntimePtr ( ) , m_args [ 0 ] , m_arg2 , m_args [ 1 ] } ;
m_builder . CreateCall ( m_sha3 , args ) ;
Value * hash = m_builder . CreateLoad ( m_args [ 1 ] ) ;
llvm : : Value * hash = m_builder . CreateLoad ( m_args [ 1 ] ) ;
hash = Endianness : : toNative ( m_builder , hash ) ;
return hash ;
}
@ -211,7 +150,7 @@ llvm::Value* Ext::exp(llvm::Value* _left, llvm::Value* _right)
{
m_builder . CreateStore ( _left , m_args [ 0 ] ) ;
m_builder . CreateStore ( _right , m_arg2 ) ;
llvm : : Value * args [ ] = { m_args [ 0 ] , m_arg2 , m_args [ 1 ] } ;
llvm : : Value * args [ ] = { getRuntimeManager ( ) . getRuntimePtr ( ) , m_args [ 0 ] , m_arg2 , m_args [ 1 ] } ;
m_builder . CreateCall ( m_exp , args ) ;
return m_builder . CreateLoad ( m_args [ 1 ] ) ;
}
@ -220,14 +159,14 @@ llvm::Value* Ext::codeAt(llvm::Value* _addr)
{
auto addr = Endianness : : toBE ( m_builder , _addr ) ;
m_builder . CreateStore ( addr , m_args [ 0 ] ) ;
return m_builder . CreateCall ( m_codeAt , m_args [ 0 ] ) ;
return m_builder . CreateCall2 ( m_codeAt , getRuntimeManager ( ) . getRuntimePtr ( ) , m_args [ 0 ] ) ;
}
llvm : : Value * Ext : : codesizeAt ( llvm : : Value * _addr )
{
auto addr = Endianness : : toBE ( m_builder , _addr ) ;
m_builder . CreateStore ( addr , m_args [ 0 ] ) ;
llvm : : Value * args [ ] = { m_args [ 0 ] , m_args [ 1 ] } ;
llvm : : Value * args [ ] = { getRuntimeManager ( ) . getRuntimePtr ( ) , m_args [ 0 ] , m_args [ 1 ] } ;
m_builder . CreateCall ( m_codesizeAt , args ) ;
return m_builder . CreateLoad ( m_args [ 1 ] ) ;
}
@ -240,64 +179,44 @@ extern "C"
using namespace dev : : eth : : jit ;
EXPORT void ext_init ( ExtData * _extData )
{
auto & & ext = Runtime : : getExt ( ) ;
_extData - > address = eth2llvm ( fromAddress ( ext . myAddress ) ) ;
_extData - > caller = eth2llvm ( fromAddress ( ext . caller ) ) ;
_extData - > origin = eth2llvm ( fromAddress ( ext . origin ) ) ;
_extData - > callvalue = eth2llvm ( ext . value ) ;
_extData - > gasprice = eth2llvm ( ext . gasPrice ) ;
_extData - > calldatasize = eth2llvm ( ext . data . size ( ) ) ;
_extData - > prevhash = eth2llvm ( ext . previousBlock . hash ) ;
_extData - > coinbase = eth2llvm ( fromAddress ( ext . currentBlock . coinbaseAddress ) ) ;
_extData - > timestamp = eth2llvm ( ext . currentBlock . timestamp ) ;
_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 )
EXPORT void ext_store ( Runtime * _rt , i256 * _index , i256 * _value )
{
auto index = llvm2eth ( * _index ) ;
auto value = Runtime : : getExt ( ) . store ( index ) ; // Interface uses native endianness
auto value = _rt - > getExt ( ) . store ( index ) ; // Interface uses native endianness
* _value = eth2llvm ( value ) ;
}
EXPORT void ext_setStore ( i256 * _index , i256 * _value )
EXPORT void ext_setStore ( Runtime * _rt , i256 * _index , i256 * _value )
{
auto index = llvm2eth ( * _index ) ;
auto value = llvm2eth ( * _value ) ;
Runtime : : getExt ( ) . setStore ( index , value ) ; // Interface uses native endianness
_rt - > getExt ( ) . setStore ( index , value ) ; // Interface uses native endianness
}
EXPORT void ext_calldataload ( i256 * _index , i256 * _value )
EXPORT void ext_calldataload ( Runtime * _rt , i256 * _index , i256 * _value )
{
auto index = static_cast < size_t > ( llvm2eth ( * _index ) ) ;
assert ( index + 31 > index ) ; // TODO: Handle large index
auto b = reinterpret_cast < byte * > ( _value ) ;
for ( size_t i = index , j = 0 ; i < = index + 31 ; + + i , + + j )
b [ j ] = i < Runtime : : getExt ( ) . data . size ( ) ? Runtime : : getExt ( ) . data [ i ] : 0 ; // Keep Big Endian
b [ j ] = i < _rt - > getExt ( ) . data . size ( ) ? _rt - > getExt ( ) . data [ i ] : 0 ; // Keep Big Endian
// TODO: It all can be done by adding padding to data or by using min() algorithm without branch
}
EXPORT void ext_balance ( h256 * _address , i256 * _value )
EXPORT void ext_balance ( Runtime * _rt , h256 * _address , i256 * _value )
{
auto u = Runtime : : getExt ( ) . balance ( right160 ( * _address ) ) ;
auto u = _rt - > getExt ( ) . balance ( right160 ( * _address ) ) ;
* _value = eth2llvm ( u ) ;
}
EXPORT void ext_suicide ( h256 * _address )
EXPORT void ext_suicide ( Runtime * _rt , h256 * _address )
{
Runtime : : getExt ( ) . suicide ( right160 ( * _address ) ) ;
_rt - > getExt ( ) . suicide ( right160 ( * _address ) ) ;
}
EXPORT void ext_create ( i256 * _endowment , i256 * _initOff , i256 * _initSize , h256 * _address )
EXPORT void ext_create ( Runtime * _rt , i256 * _endowment , i256 * _initOff , i256 * _initSize , h256 * _address )
{
auto & & ext = Runtime : : getExt ( ) ;
auto & & ext = _rt - > getExt ( ) ;
auto endowment = llvm2eth ( * _endowment ) ;
if ( ext . balance ( ext . myAddress ) > = endowment )
@ -306,7 +225,8 @@ EXPORT void ext_create(i256* _endowment, i256* _initOff, i256* _initSize, h256*
u256 gas ; // TODO: Handle gas
auto initOff = static_cast < size_t > ( llvm2eth ( * _initOff ) ) ;
auto initSize = static_cast < size_t > ( llvm2eth ( * _initSize ) ) ;
auto & & initRef = bytesConstRef ( Runtime : : getMemory ( ) . data ( ) + initOff , initSize ) ;
//auto&& initRef = bytesConstRef(Runtime::getMemory().data() + initOff, initSize);
bytesConstRef initRef ;
OnOpFunc onOp { } ; // TODO: Handle that thing
h256 address = ext . create ( endowment , & gas , initRef , onOp ) ;
* _address = address ;
@ -317,9 +237,9 @@ EXPORT void ext_create(i256* _endowment, i256* _initOff, i256* _initSize, h256*
EXPORT void ext_call ( i256 * _gas , h256 * _receiveAddress , i256 * _value , i256 * _inOff , i256 * _inSize , i256 * _outOff , i256 * _outSize , h256 * _codeAddress , i256 * _ret )
EXPORT void ext_call ( Runtime * _rt , i256 * _gas , h256 * _receiveAddress , i256 * _value , i256 * _inOff , i256 * _inSize , i256 * _outOff , i256 * _outSize , h256 * _codeAddress , i256 * _ret )
{
auto & & ext = Runtime : : getExt ( ) ;
auto & & ext = _rt - > getExt ( ) ;
auto value = llvm2eth ( * _value ) ;
auto ret = false ;
@ -332,8 +252,8 @@ EXPORT void ext_call(i256* _gas, h256* _receiveAddress, i256* _value, i256* _inO
auto inSize = static_cast < size_t > ( llvm2eth ( * _inSize ) ) ;
auto outOff = static_cast < size_t > ( llvm2eth ( * _outOff ) ) ;
auto outSize = static_cast < size_t > ( llvm2eth ( * _outSize ) ) ;
auto & & inRef = bytesConstRef ( Runtime : : getMemory ( ) . data ( ) + inOff , inSize ) ;
auto & & outRef = bytesConstRef ( Runtime : : getMemory ( ) . data ( ) + outOff , outSize ) ;
auto & & inRef = bytesConstRef ( ) ; //Runtime::getMemory().data() + inOff, inSize);
auto & & outRef = bytesConstRef ( ) ; // Runtime::getMemory().data() + outOff, outSize);
OnOpFunc onOp { } ; // TODO: Handle that thing
auto codeAddress = right160 ( * _codeAddress ) ;
ret = ext . call ( receiveAddress , value , inRef , & gas , outRef , onOp , { } , codeAddress ) ;
@ -343,16 +263,16 @@ EXPORT void ext_call(i256* _gas, h256* _receiveAddress, i256* _value, i256* _inO
_ret - > a = ret ? 1 : 0 ;
}
EXPORT void ext_sha3 ( i256 * _inOff , i256 * _inSize , i256 * _ret )
EXPORT void ext_sha3 ( Runtime * _rt , i256 * _inOff , i256 * _inSize , i256 * _ret )
{
auto inOff = static_cast < size_t > ( llvm2eth ( * _inOff ) ) ;
auto inSize = static_cast < size_t > ( llvm2eth ( * _inSize ) ) ;
auto dataRef = bytesConstRef ( Runtime : : getMemory ( ) . data ( ) + inOff , inSize ) ;
auto dataRef = bytesConstRef ( ) ; // Runtime::getMemory().data() + inOff, inSize);
auto hash = sha3 ( dataRef ) ;
* _ret = * reinterpret_cast < i256 * > ( & hash ) ;
}
EXPORT void ext_exp ( i256 * _left , i256 * _right , i256 * _ret )
EXPORT void ext_exp ( Runtime * _rt , i256 * _left , i256 * _right , i256 * _ret )
{
bigint left = llvm2eth ( * _left ) ;
bigint right = llvm2eth ( * _right ) ;
@ -360,17 +280,17 @@ EXPORT void ext_exp(i256* _left, i256* _right, i256* _ret)
* _ret = eth2llvm ( ret ) ;
}
EXPORT unsigned char * ext_codeAt ( h256 * _addr256 )
EXPORT unsigned char * ext_codeAt ( Runtime * _rt , h256 * _addr256 ) //FIXME: Check endianess
{
auto & & ext = Runtime : : getExt ( ) ;
auto & & ext = _rt - > getExt ( ) ;
auto addr = right160 ( * _addr256 ) ;
auto & code = ext . codeAt ( addr ) ;
return const_cast < unsigned char * > ( code . data ( ) ) ;
}
EXPORT void ext_codesizeAt ( h256 * _addr256 , i256 * _ret )
EXPORT void ext_codesizeAt ( Runtime * _rt , h256 * _addr256 , i256 * _ret ) //FIXME: Check endianess
{
auto & & ext = Runtime : : getExt ( ) ;
auto & & ext = _rt - > getExt ( ) ;
auto addr = right160 ( * _addr256 ) ;
auto & code = ext . codeAt ( addr ) ;
* _ret = eth2llvm ( u256 ( code . size ( ) ) ) ;