@ -41,45 +41,76 @@ const std::map<std::string, Instruction> eth::c_instructions =
{ " EXP " , Instruction : : EXP } ,
{ " NEG " , Instruction : : NEG } ,
{ " LT " , Instruction : : LT } ,
{ " LE " , Instruction : : LE } ,
{ " GT " , Instruction : : GT } ,
{ " GE " , Instruction : : GE } ,
{ " EQ " , Instruction : : EQ } ,
{ " NOT " , Instruction : : NOT } ,
{ " MYADDRESS " , Instruction : : MYADDRESS } ,
{ " TXSENDER " , Instruction : : TXSENDER } ,
{ " TXVALUE " , Instruction : : TXVALUE } ,
{ " TXDATAN " , Instruction : : TXDATAN } ,
{ " TXDATA " , Instruction : : TXDATA } ,
{ " BLK_PREVHASH " , Instruction : : BLK_PREVHASH } ,
{ " BLK_COINBASE " , Instruction : : BLK_COINBASE } ,
{ " BLK_TIMESTAMP " , Instruction : : BLK_TIMESTAMP } ,
{ " BLK_NUMBER " , Instruction : : BLK_NUMBER } ,
{ " BLK_DIFFICULTY " , Instruction : : BLK_DIFFICULTY } ,
{ " BLK_NONCE " , Instruction : : BLK_NONCE } ,
{ " BASEFEE " , Instruction : : BASEFEE } ,
{ " SHA256 " , Instruction : : SHA256 } ,
{ " RIPEMD160 " , Instruction : : RIPEMD160 } ,
{ " ECMUL " , Instruction : : ECMUL } ,
{ " ECADD " , Instruction : : ECADD } ,
{ " ECSIGN " , Instruction : : ECSIGN } ,
{ " ECRECOVER " , Instruction : : ECRECOVER } ,
{ " ECVALID " , Instruction : : ECVALID } ,
{ " AND " , Instruction : : AND } ,
{ " OR " , Instruction : : OR } ,
{ " XOR " , Instruction : : XOR } ,
{ " BYTE " , Instruction : : BYTE } ,
{ " SHA3 " , Instruction : : SHA3 } ,
{ " PUSH " , Instruction : : PUSH } ,
{ " ADDRESS " , Instruction : : ADDRESS } ,
{ " BALANCE " , Instruction : : BALANCE } ,
{ " ORIGIN " , Instruction : : ORIGIN } ,
{ " CALLER " , Instruction : : CALLER } ,
{ " CALLVALUE " , Instruction : : CALLVALUE } ,
{ " CALLDATALOAD " , Instruction : : CALLDATALOAD } ,
{ " CALLDATASIZE " , Instruction : : CALLDATASIZE } ,
{ " BASEFEE " , Instruction : : GASPRICE } ,
{ " PREVHASH " , Instruction : : PREVHASH } ,
{ " COINBASE " , Instruction : : COINBASE } ,
{ " TIMESTAMP " , Instruction : : TIMESTAMP } ,
{ " NUMBER " , Instruction : : NUMBER } ,
{ " DIFFICULTY " , Instruction : : DIFFICULTY } ,
{ " GASLIMIT " , Instruction : : GASLIMIT } ,
{ " POP " , Instruction : : POP } ,
{ " DUP " , Instruction : : DUP } ,
{ " SWAP " , Instruction : : SWAP } ,
{ " MLOAD " , Instruction : : MLOAD } ,
{ " MSTORE " , Instruction : : MSTORE } ,
{ " MSTORE8 " , Instruction : : MSTORE8 } ,
{ " SLOAD " , Instruction : : SLOAD } ,
{ " SSTORE " , Instruction : : SSTORE } ,
{ " JMP " , Instruction : : JMP } ,
{ " JMPI " , Instruction : : JMPI } ,
{ " IND " , Instruction : : IND } ,
{ " EXTRO " , Instruction : : EXTRO } ,
{ " BALANCE " , Instruction : : BALANCE } ,
{ " MKTX " , Instruction : : MKTX } ,
{ " JUMP " , Instruction : : JUMP } ,
{ " JUMPI " , Instruction : : JUMPI } ,
{ " PC " , Instruction : : PC } ,
{ " MEMSIZE " , Instruction : : MEMSIZE } ,
{ " GAS " , Instruction : : GAS } ,
{ " PUSH1 " , Instruction : : PUSH1 } ,
{ " PUSH2 " , Instruction : : PUSH2 } ,
{ " PUSH3 " , Instruction : : PUSH3 } ,
{ " PUSH4 " , Instruction : : PUSH4 } ,
{ " PUSH5 " , Instruction : : PUSH5 } ,
{ " PUSH6 " , Instruction : : PUSH6 } ,
{ " PUSH7 " , Instruction : : PUSH7 } ,
{ " PUSH8 " , Instruction : : PUSH8 } ,
{ " PUSH9 " , Instruction : : PUSH9 } ,
{ " PUSH10 " , Instruction : : PUSH10 } ,
{ " PUSH11 " , Instruction : : PUSH11 } ,
{ " PUSH12 " , Instruction : : PUSH12 } ,
{ " PUSH13 " , Instruction : : PUSH13 } ,
{ " PUSH14 " , Instruction : : PUSH14 } ,
{ " PUSH15 " , Instruction : : PUSH15 } ,
{ " PUSH16 " , Instruction : : PUSH16 } ,
{ " PUSH17 " , Instruction : : PUSH17 } ,
{ " PUSH18 " , Instruction : : PUSH18 } ,
{ " PUSH19 " , Instruction : : PUSH19 } ,
{ " PUSH20 " , Instruction : : PUSH20 } ,
{ " PUSH21 " , Instruction : : PUSH21 } ,
{ " PUSH22 " , Instruction : : PUSH22 } ,
{ " PUSH23 " , Instruction : : PUSH23 } ,
{ " PUSH24 " , Instruction : : PUSH24 } ,
{ " PUSH25 " , Instruction : : PUSH25 } ,
{ " PUSH26 " , Instruction : : PUSH26 } ,
{ " PUSH27 " , Instruction : : PUSH27 } ,
{ " PUSH28 " , Instruction : : PUSH28 } ,
{ " PUSH29 " , Instruction : : PUSH29 } ,
{ " PUSH30 " , Instruction : : PUSH30 } ,
{ " PUSH31 " , Instruction : : PUSH31 } ,
{ " PUSH32 " , Instruction : : PUSH32 } ,
{ " CREATE " , Instruction : : CREATE } ,
{ " CALL " , Instruction : : CALL } ,
{ " RETURN " , Instruction : : RETURN } ,
{ " SUICIDE " , Instruction : : SUICIDE }
} ;
@ -96,45 +127,76 @@ const std::map<Instruction, InstructionInfo> eth::c_instructionInfo =
{ Instruction : : EXP , { " EXP " , 0 , 2 , 1 } } ,
{ Instruction : : NEG , { " NEG " , 0 , 1 , 1 } } ,
{ Instruction : : LT , { " LT " , 0 , 2 , 1 } } ,
{ Instruction : : LE , { " LE " , 0 , 2 , 1 } } ,
{ Instruction : : GT , { " GT " , 0 , 2 , 1 } } ,
{ Instruction : : GE , { " GE " , 0 , 2 , 1 } } ,
{ Instruction : : EQ , { " EQ " , 0 , 2 , 1 } } ,
{ Instruction : : NOT , { " NOT " , 0 , 1 , 1 } } ,
{ Instruction : : MYADDRESS , { " MYADDRESS " , 0 , 0 , 1 } } ,
{ Instruction : : TXSENDER , { " TXSENDER " , 0 , 0 , 1 } } ,
{ Instruction : : TXVALUE , { " TXVALUE " , 0 , 0 , 1 } } ,
{ Instruction : : TXDATAN , { " TXDATAN " , 0 , 0 , 1 } } ,
{ Instruction : : TXDATA , { " TXDATA " , 0 , 1 , 1 } } ,
{ Instruction : : BLK_PREVHASH , { " BLK_PREVHASH " , 0 , 0 , 1 } } ,
{ Instruction : : BLK_COINBASE , { " BLK_COINBASE " , 0 , 0 , 1 } } ,
{ Instruction : : BLK_TIMESTAMP , { " BLK_TIMESTAMP " , 0 , 0 , 1 } } ,
{ Instruction : : BLK_NUMBER , { " BLK_NUMBER " , 0 , 0 , 1 } } ,
{ Instruction : : BLK_DIFFICULTY , { " BLK_DIFFICULTY " , 0 , 0 , 1 } } ,
{ Instruction : : BLK_NONCE , { " BLK_NONCE " , 0 , 0 , 1 } } ,
{ Instruction : : BASEFEE , { " BASEFEE " , 0 , 0 , 1 } } ,
{ Instruction : : SHA256 , { " SHA256 " , 0 , - 1 , 1 } } ,
{ Instruction : : RIPEMD160 , { " RIPEMD160 " , 0 , - 1 , 1 } } ,
{ Instruction : : ECMUL , { " ECMUL " , 0 , 3 , 2 } } ,
{ Instruction : : ECADD , { " ECADD " , 0 , 4 , 2 } } ,
{ Instruction : : ECSIGN , { " ECSIGN " , 0 , 2 , 3 } } ,
{ Instruction : : ECRECOVER , { " ECRECOVER " , 0 , 4 , 2 } } ,
{ Instruction : : ECVALID , { " ECVALID " , 0 , 2 , 1 } } ,
{ Instruction : : SHA3 , { " SHA3 " , 0 , - 1 , 1 } } ,
{ Instruction : : PUSH , { " PUSH " , 1 , 0 , 1 } } ,
{ Instruction : : ADD , { " ADD " , 0 , 2 , 1 } } ,
{ Instruction : : OR , { " OR " , 0 , 2 , 1 } } ,
{ Instruction : : XOR , { " XOR " , 0 , 2 , 1 } } ,
{ Instruction : : BYTE , { " BYTE " , 0 , 2 , 1 } } ,
{ Instruction : : SHA3 , { " SHA3 " , 0 , 2 , 1 } } ,
{ Instruction : : ADDRESS , { " ADDRESS " , 0 , 0 , 1 } } ,
{ Instruction : : BALANCE , { " BALANCE " , 0 , 1 , 1 } } ,
{ Instruction : : ORIGIN , { " ORIGIN " , 0 , 1 , 1 } } ,
{ Instruction : : CALLER , { " CALLER " , 0 , 0 , 1 } } ,
{ Instruction : : CALLVALUE , { " CALLVALUE " , 0 , 0 , 1 } } ,
{ Instruction : : CALLDATALOAD , { " CALLDATALOAD " , 0 , 1 , 1 } } ,
{ Instruction : : CALLDATASIZE , { " CALLDATASIZE " , 0 , 0 , 1 } } ,
{ Instruction : : GASPRICE , { " BASEFEE " , 0 , 0 , 1 } } ,
{ Instruction : : PREVHASH , { " PREVHASH " , 0 , 0 , 1 } } ,
{ Instruction : : COINBASE , { " COINBASE " , 0 , 0 , 1 } } ,
{ Instruction : : TIMESTAMP , { " TIMESTAMP " , 0 , 0 , 1 } } ,
{ Instruction : : NUMBER , { " NUMBER " , 0 , 0 , 1 } } ,
{ Instruction : : DIFFICULTY , { " DIFFICULTY " , 0 , 0 , 1 } } ,
{ Instruction : : GASLIMIT , { " GASLIMIT " , 0 , 0 , 1 } } ,
{ Instruction : : POP , { " POP " , 0 , 1 , 0 } } ,
{ Instruction : : DUP , { " DUP " , 0 , 1 , 2 } } ,
{ Instruction : : SWAP , { " SWAP " , 0 , 2 , 2 } } ,
{ Instruction : : MLOAD , { " MLOAD " , 0 , 1 , 1 } } ,
{ Instruction : : MSTORE , { " MSTORE " , 0 , 2 , 0 } } ,
{ Instruction : : MSTORE8 , { " MSTORE8 " , 0 , 2 , 0 } } ,
{ Instruction : : SLOAD , { " SLOAD " , 0 , 1 , 1 } } ,
{ Instruction : : SSTORE , { " SSTORE " , 0 , 2 , 0 } } ,
{ Instruction : : JMP , { " JMP " , 0 , 1 , 0 } } ,
{ Instruction : : JMPI , { " JMPI " , 0 , 2 , 0 } } ,
{ Instruction : : IND , { " IND " , 0 , 0 , 1 } } ,
{ Instruction : : EXTRO , { " EXTRO " , 0 , 2 , 1 } } ,
{ Instruction : : BALANCE , { " BALANCE " , 0 , 1 , 1 } } ,
{ Instruction : : MKTX , { " MKTX " , 0 , - 3 , 0 } } ,
{ Instruction : : JUMP , { " JUMP " , 0 , 1 , 0 } } ,
{ Instruction : : JUMPI , { " JUMPI " , 0 , 2 , 0 } } ,
{ Instruction : : PC , { " PC " , 0 , 0 , 1 } } ,
{ Instruction : : MEMSIZE , { " MEMSIZE " , 0 , 0 , 1 } } ,
{ Instruction : : GAS , { " GAS " , 0 , 0 , 1 } } ,
{ Instruction : : PUSH1 , { " PUSH1 " , 1 , 0 , 1 } } ,
{ Instruction : : PUSH2 , { " PUSH2 " , 2 , 0 , 1 } } ,
{ Instruction : : PUSH3 , { " PUSH3 " , 3 , 0 , 1 } } ,
{ Instruction : : PUSH4 , { " PUSH4 " , 4 , 0 , 1 } } ,
{ Instruction : : PUSH5 , { " PUSH5 " , 5 , 0 , 1 } } ,
{ Instruction : : PUSH6 , { " PUSH6 " , 6 , 0 , 1 } } ,
{ Instruction : : PUSH7 , { " PUSH7 " , 7 , 0 , 1 } } ,
{ Instruction : : PUSH8 , { " PUSH8 " , 8 , 0 , 1 } } ,
{ Instruction : : PUSH9 , { " PUSH9 " , 9 , 0 , 1 } } ,
{ Instruction : : PUSH10 , { " PUSH10 " , 10 , 0 , 1 } } ,
{ Instruction : : PUSH11 , { " PUSH11 " , 11 , 0 , 1 } } ,
{ Instruction : : PUSH12 , { " PUSH12 " , 12 , 0 , 1 } } ,
{ Instruction : : PUSH13 , { " PUSH13 " , 13 , 0 , 1 } } ,
{ Instruction : : PUSH14 , { " PUSH14 " , 14 , 0 , 1 } } ,
{ Instruction : : PUSH15 , { " PUSH15 " , 15 , 0 , 1 } } ,
{ Instruction : : PUSH16 , { " PUSH16 " , 16 , 0 , 1 } } ,
{ Instruction : : PUSH17 , { " PUSH17 " , 17 , 0 , 1 } } ,
{ Instruction : : PUSH18 , { " PUSH18 " , 18 , 0 , 1 } } ,
{ Instruction : : PUSH19 , { " PUSH19 " , 19 , 0 , 1 } } ,
{ Instruction : : PUSH20 , { " PUSH20 " , 20 , 0 , 1 } } ,
{ Instruction : : PUSH21 , { " PUSH21 " , 21 , 0 , 1 } } ,
{ Instruction : : PUSH22 , { " PUSH22 " , 22 , 0 , 1 } } ,
{ Instruction : : PUSH23 , { " PUSH23 " , 23 , 0 , 1 } } ,
{ Instruction : : PUSH24 , { " PUSH24 " , 24 , 0 , 1 } } ,
{ Instruction : : PUSH25 , { " PUSH25 " , 25 , 0 , 1 } } ,
{ Instruction : : PUSH26 , { " PUSH26 " , 26 , 0 , 1 } } ,
{ Instruction : : PUSH27 , { " PUSH27 " , 27 , 0 , 1 } } ,
{ Instruction : : PUSH28 , { " PUSH28 " , 28 , 0 , 1 } } ,
{ Instruction : : PUSH29 , { " PUSH29 " , 29 , 0 , 1 } } ,
{ Instruction : : PUSH30 , { " PUSH30 " , 30 , 0 , 1 } } ,
{ Instruction : : PUSH31 , { " PUSH31 " , 31 , 0 , 1 } } ,
{ Instruction : : PUSH32 , { " PUSH32 " , 32 , 0 , 1 } } ,
{ Instruction : : CREATE , { " CREATE " , 0 , 3 , 1 } } ,
{ Instruction : : CALL , { " CALL " , 0 , 7 , 1 } } ,
{ Instruction : : RETURN , { " RETURN " , 0 , 2 , 0 } } ,
{ Instruction : : SUICIDE , { " SUICIDE " , 0 , 1 , 0 } }
} ;
@ -174,9 +236,9 @@ static u256 readNumeric(string _v, bool _quiet)
return 0 ;
}
u256 s eth : : assemble ( std : : string const & _code , bool _quiet )
byte s eth : : assemble ( std : : string const & _code , bool _quiet )
{
u256 s ret ;
byte s ret ;
map < string , unsigned > known ;
map < unsigned , string > req ;
char const * d = _code . data ( ) ;
@ -184,11 +246,11 @@ u256s eth::assemble(std::string const& _code, bool _quiet)
while ( d ! = e )
{
// skip to next token
for ( ; d ! = e & & ! isalnum ( * d ) & & * d ! = ' _ ' & & * d ! = ' : ' & & * d ! = ' " ' ; + + d ) { }
for ( ; d ! = e & & ! isalnum ( * d ) & & * d ! = ' _ ' /*&& *d != ':' && *d != '"'*/ ; + + d ) { }
if ( d = = e )
break ;
if ( * d = = ' " ' )
/* if (*d == '"')
{
string s = readQuoted ( d , e ) ;
if ( s . size ( ) > 32 )
@ -202,15 +264,15 @@ u256s eth::assemble(std::string const& _code, bool _quiet)
memset ( valHash . data ( ) + s . size ( ) , 0 , 32 - s . size ( ) ) ;
ret . push_back ( ( u256 ) valHash ) ;
}
else
else */
{
char const * s = d ;
for ( ; d ! = e & & ( isalnum ( * d ) | | * d = = ' _ ' | | * d = = ' : ' | | * d = = ' " ' ) ; + + d ) { }
for ( ; d ! = e & & ( isalnum ( * d ) | | * d = = ' _ ' /* || *d == ':' || *d == '"'*/ ) ; + + d ) { }
string t = string ( s , d - s ) ;
if ( isdigit ( t [ 0 ] ) )
ret . push_back ( readNumeric ( t , _quiet ) ) ;
else if ( t . back ( ) = = ' : ' )
ret . push_back ( ( byte ) readNumeric ( t , _quiet ) ) ;
/* else if (t.back() == ':')
known [ t . substr ( 0 , t . size ( ) - 1 ) ] = ( unsigned ) ret . size ( ) ;
else
{
@ -222,7 +284,7 @@ u256s eth::assemble(std::string const& _code, bool _quiet)
req [ ( unsigned ) ret . size ( ) ] = t ;
ret . push_back ( 0 ) ;
}
}
} */
}
}
for ( auto i : req )
@ -235,12 +297,41 @@ u256s eth::assemble(std::string const& _code, bool _quiet)
return ret ;
}
static void appendCode ( u256s & o_code , vector < unsigned > & o_locs , u256s _code , vector < unsigned > & _locs )
/// @returns the number of addition bytes required for the PUSH.
static void increaseLocation ( bytes & o_code , unsigned _pos , unsigned _inc )
{
assert ( o_code [ _pos ] = = ( byte ) Instruction : : PUSH4 ) ;
bytesRef r ( & o_code [ 1 + _pos ] , 4 ) ;
toBigEndian ( fromBigEndian < uint32_t > ( bytesConstRef ( & o_code [ 1 + _pos ] , 4 ) ) + _inc , r ) ;
}
static void pushLocation ( bytes & o_code , uint32_t _locationValue )
{
o_code . push_back ( ( byte ) Instruction : : PUSH4 ) ;
o_code . resize ( o_code . size ( ) + 4 ) ;
bytesRef r ( & o_code [ o_code . size ( ) - 4 ] , 4 ) ;
toBigEndian ( _locationValue , r ) ;
}
static unsigned pushLiteral ( bytes & o_code , u256 _literalValue )
{
unsigned br = max < unsigned > ( 1 , bytesRequired ( _literalValue ) ) ;
o_code . push_back ( ( byte ) Instruction : : PUSH1 + br - 1 ) ;
o_code . resize ( o_code . size ( ) + br ) ;
for ( unsigned i = 0 ; i < br ; + + i )
{
o_code [ o_code . size ( ) - 1 - i ] = ( byte ) ( _literalValue & 0xff ) ;
_literalValue > > = 8 ;
}
return br + 1 ;
}
static void appendCode ( bytes & o_code , vector < unsigned > & o_locs , bytes _code , vector < unsigned > & _locs )
{
o_locs . reserve ( o_locs . size ( ) + _locs . size ( ) ) ;
for ( auto i : _locs )
{
_code [ i ] + = ( u256 ) o_code . size ( ) ;
increaseLocation ( _code , i , ( unsigned ) o_code . size ( ) ) ;
o_locs . push_back ( i + ( unsigned ) o_code . size ( ) ) ;
}
o_code . reserve ( o_code . size ( ) + _code . size ( ) ) ;
@ -248,10 +339,10 @@ static void appendCode(u256s& o_code, vector<unsigned>& o_locs, u256s _code, vec
o_code . push_back ( i ) ;
}
static int compileLispFragment ( char const * & d , char const * e , bool _quiet , u256 s& o_code , vector < unsigned > & o_locs )
static int compileLispFragment ( char const * & d , char const * e , bool _quiet , byte s& o_code , vector < unsigned > & o_locs )
{
std : : map < std : : string , Instruction > const c_arith = { { " + " , Instruction : : ADD } , { " - " , Instruction : : SUB } , { " * " , Instruction : : MUL } , { " / " , Instruction : : DIV } , { " % " , Instruction : : MOD } } ;
std : : map < std : : string , Instruction > const c_binary = { { " < " , Instruction : : LT } , { " <= " , Instruction : : LE } , { " > " , Instruction : : GT } , { " >= " , Instruction : : GE } , { " = " , Instruction : : EQ } , { " != " , Instruction : : NOT } } ;
std : : map < std : : string , pair < Instruction , bool > > const c_binary = { { " < " , { Instruction : : LT , false } } , { " <= " , { Instruction : : GT , true } } , { " > " , { Instruction : : GT , false } } , { " >= " , { Instruction : : LT , true } } , { " = " , { Instruction : : EQ , false } } , { " != " , { Instruction : : EQ , true } } } ;
std : : map < std : : string , Instruction > const c_unary = { { " ! " , Instruction : : NOT } } ;
std : : set < char > const c_allowed = { ' + ' , ' - ' , ' * ' , ' / ' , ' % ' , ' < ' , ' > ' , ' = ' , ' ! ' } ;
@ -321,9 +412,9 @@ static int compileLispFragment(char const*& d, char const* e, bool _quiet, u256s
bool bareLoad = true ;
if ( exec )
{
u256 s codes ;
byte s codes ;
vector < unsigned > locs ;
if ( compileLispFragment ( d , e , _quiet , codes , locs ) )
if ( compileLispFragment ( d , e , _quiet , codes , locs ) ! = - 1 )
{
appendCode ( o_code , o_locs , codes , locs ) ;
while ( compileLispFragment ( d , e , _quiet , codes , locs ) ! = - 1 )
@ -332,10 +423,9 @@ static int compileLispFragment(char const*& d, char const* e, bool _quiet, u256s
bareLoad = false ;
}
}
o_code . push_back ( Instruction : : PUSH ) ;
o_code . push_back ( literalValue ) ;
pushLiteral ( o_code , literalValue ) ;
if ( exec )
o_code . push_back ( bareLoad ? Instruction : : SLOAD : Instruction : : SSTORE ) ;
o_code . push_back ( bareLoad ? ( byte ) Instruction : : SLOAD : ( byte ) Instruction : : SSTORE ) ;
}
else
{
@ -343,7 +433,7 @@ static int compileLispFragment(char const*& d, char const* e, bool _quiet, u256s
if ( t = = " IF " )
{
// Compile all the code...
u256 s codes [ 4 ] ;
byte s codes [ 4 ] ;
vector < unsigned > locs [ 4 ] ;
for ( int i = 0 ; i < 3 ; + + i )
{
@ -356,40 +446,38 @@ static int compileLispFragment(char const*& d, char const* e, bool _quiet, u256s
if ( compileLispFragment ( d , e , _quiet , codes [ 3 ] , locs [ 3 ] ) ! = - 1 )
return false ;
// First fragment - predicate
appendCode ( o_code , o_locs , codes [ 0 ] , locs [ 0 ] ) ;
// Push the positive location.
o_code . push_back ( Instruction : : PUSH ) ;
unsigned posLocation = ( unsigned ) o_code . size ( ) ;
o_locs . push_back ( posLocation ) ;
o_code . push_back ( 0 ) ;
pushLocation ( o_code , 0 ) ;
// First fragment - predicate
appendCode ( o_code , o_locs , codes [ 0 ] , locs [ 0 ] ) ;
// Jump to positive if true.
o_code . push_back ( Instruction : : JMPI ) ;
// Jump to negative if false.
o_code . push_back ( ( byte ) Instruction : : JUMPI ) ;
// Second fragment - negative.
appendCode ( o_code , o_locs , codes [ 2 ] , locs [ 2 ] ) ;
// Jump to end after negative.
o_code . push_back ( Instruction : : PUSH ) ;
unsigned endLocation = ( unsigned ) o_code . size ( ) ;
o_locs . push_back ( endLocation ) ;
o_code . push_back ( 0 ) ;
o_code . push_back ( Instruction : : JMP ) ;
pushLocation ( o_code , 0 ) ;
o_code . push_back ( ( byte ) Instruction : : JU MP ) ;
// Third fragment - positive.
o_code [ posLocation ] = o_code . size ( ) ;
increaseLocation ( o_code , posLocation , o_code . size ( ) ) ;
appendCode ( o_code , o_locs , codes [ 1 ] , locs [ 1 ] ) ;
// At end now.
o_code [ endLocation ] = o_code . size ( ) ;
increaseLocation ( o_code , endLocation , o_code . size ( ) ) ;
}
else if ( t = = " WHEN " | | t = = " UNLESS " )
{
outs = 0 ;
// Compile all the code...
u256 s codes [ 3 ] ;
byte s codes [ 3 ] ;
vector < unsigned > locs [ 3 ] ;
for ( int i = 0 ; i < 2 ; + + i )
{
@ -398,36 +486,35 @@ static int compileLispFragment(char const*& d, char const* e, bool _quiet, u256s
return false ;
if ( i = = 1 )
for ( int j = 0 ; j < o ; + + j )
codes [ i ] . push_back ( Instruction : : POP ) ; // pop additional items off stack for the previous item (final item's returns get left on).
codes [ i ] . push_back ( ( byte ) Instruction : : POP ) ; // pop additional items off stack for the previous item (final item's returns get left on).
}
if ( compileLispFragment ( d , e , _quiet , codes [ 2 ] , locs [ 2 ] ) ! = - 1 )
return false ;
// First fragment - predicate
appendCode ( o_code , o_locs , codes [ 0 ] , locs [ 0 ] ) ;
if ( t = = " WHEN " )
o_code . push_back ( ( byte ) Instruction : : NOT ) ;
// Push the positive location.
o_code . push_back ( Instruction : : PUSH ) ;
unsigned endLocation = ( unsigned ) o_code . size ( ) ;
o_locs . push_back ( endLocation ) ;
o_code . push_back ( 0 ) ;
// First fragment - predicate
appendCode ( o_code , o_locs , codes [ 0 ] , locs [ 0 ] ) ;
pushLocation ( o_code , 0 ) ;
// Jump to end...
if ( t = = " WHEN " )
o_code . push_back ( Instruction : : NOT ) ;
o_code . push_back ( Instruction : : JMPI ) ;
o_code . push_back ( ( byte ) Instruction : : JUMPI ) ;
// Second fragment - negative.
appendCode ( o_code , o_locs , codes [ 1 ] , locs [ 1 ] ) ;
// At end now.
o_code [ endLocation ] = o_code . size ( ) ;
increaseLocation ( o_code , endLocation , o_code . size ( ) ) ;
}
else if ( t = = " FOR " )
{
outs = 0 ;
// Compile all the code...
u256 s codes [ 3 ] ;
byte s codes [ 3 ] ;
vector < unsigned > locs [ 3 ] ;
for ( int i = 0 ; i < 2 ; + + i )
{
@ -436,50 +523,48 @@ static int compileLispFragment(char const*& d, char const* e, bool _quiet, u256s
return false ;
if ( i = = 1 )
for ( int j = 0 ; j < o ; + + j )
codes [ i ] . push_back ( Instruction : : POP ) ; // pop additional items off stack for the previous item (final item's returns get left on).
codes [ i ] . push_back ( ( byte ) Instruction : : POP ) ; // pop additional items off stack for the previous item (final item's returns get left on).
}
if ( compileLispFragment ( d , e , _quiet , codes [ 2 ] , locs [ 2 ] ) ! = - 1 )
return false ;
unsigned startLocation = ( unsigned ) o_code . size ( ) ;
// First fragment - predicate
appendCode ( o_code , o_locs , codes [ 0 ] , locs [ 0 ] ) ;
o_code . push_back ( ( byte ) Instruction : : NOT ) ;
// Push the positive location.
o_code . push_back ( Instruction : : PUSH ) ;
unsigned endInsertion = ( unsigned ) o_code . size ( ) ;
o_locs . push_back ( endInsertion ) ;
o_code . push_back ( 0 ) ;
// First fragment - predicate
appendCode ( o_code , o_locs , codes [ 0 ] , locs [ 0 ] ) ;
pushLocation ( o_code , 0 ) ;
// Jump to positive if true.
o_code . push_back ( Instruction : : NOT ) ;
o_code . push_back ( Instruction : : JMPI ) ;
o_code . push_back ( ( byte ) Instruction : : JUMPI ) ;
// Second fragment - negative.
appendCode ( o_code , o_locs , codes [ 1 ] , locs [ 1 ] ) ;
// Jump to end after negative.
o_code . push_back ( Instruction : : PUSH ) ;
o_locs . push_back ( ( unsigned ) o_code . size ( ) ) ;
o_code . push_back ( startLocation ) ;
o_code . push_back ( Instruction : : JMP ) ;
pushLocation ( o_code , startLocation ) ;
o_code . push_back ( ( byte ) Instruction : : JU MP ) ;
// At end now.
o_code [ endInsertion ] = o_code . size ( ) ;
increaseLocation ( o_code , endInsertion , o_code . size ( ) ) ;
}
else if ( t = = " SEQ " )
{
while ( d ! = e )
{
u256 s codes ;
byte s codes ;
vector < unsigned > locs ;
outs = 0 ;
int o ;
if ( ( o = compileLispFragment ( d , e , _quiet , codes , locs ) ) > - 1 )
{
for ( int i = 0 ; i < outs ; + + i )
o_code . push_back ( Instruction : : POP ) ; // pop additional items off stack for the previous item (final item's returns get left on).
o_code . push_back ( ( byte ) Instruction : : POP ) ; // pop additional items off stack for the previous item (final item's returns get left on).
outs = o ;
appendCode ( o_code , o_locs , codes , locs ) ;
}
@ -491,14 +576,14 @@ static int compileLispFragment(char const*& d, char const* e, bool _quiet, u256s
{
if ( exec )
{
vector < pair < u256 s, vector < unsigned > > > codes ( 1 ) ;
vector < pair < byte s, vector < unsigned > > > codes ( 1 ) ;
int totalArgs = 0 ;
while ( d ! = e )
{
int o = compileLispFragment ( d , e , _quiet , codes . back ( ) . first , codes . back ( ) . second ) ;
if ( o < 1 )
break ;
codes . push_back ( pair < u256 s, vector < unsigned > > ( ) ) ;
codes . push_back ( pair < byte s, vector < unsigned > > ( ) ) ;
totalArgs + = o ;
}
if ( totalArgs < 2 )
@ -513,12 +598,9 @@ static int compileLispFragment(char const*& d, char const* e, bool _quiet, u256s
{
appendCode ( o_code , o_locs , it - > first , it - > second ) ;
if ( i = = datan )
{
o_code . push_back ( Instruction : : PUSH ) ;
o_code . push_back ( datan ) ;
}
pushLocation ( o_code , datan ) ;
}
o_code . push_back ( Instruction : : MKTX ) ;
o_code . push_back ( ( byte ) Instruction : : CALL ) ;
outs = 0 ;
}
}
@ -526,7 +608,7 @@ static int compileLispFragment(char const*& d, char const* e, bool _quiet, u256s
{
while ( d ! = e )
{
u256 s codes ;
byte s codes ;
vector < unsigned > locs ;
outs = 0 ;
int o ;
@ -541,7 +623,7 @@ static int compileLispFragment(char const*& d, char const* e, bool _quiet, u256s
}
else if ( t = = " AND " )
{
vector < u256 s> codes ;
vector < byte s> codes ;
vector < vector < unsigned > > locs ;
while ( d ! = e )
{
@ -567,25 +649,23 @@ static int compileLispFragment(char const*& d, char const* e, bool _quiet, u256s
if ( codes . size ( ) > 1 )
{
o_code . push_back ( Instruction : : PUSH ) ;
o_code . push_back ( 0 ) ;
pushLiteral ( o_code , 0 ) ;
for ( unsigned i = 1 ; i < codes . size ( ) ; + + i )
{
// Check if true - predicate
appendCode ( o_code , o_locs , codes [ i - 1 ] , locs [ i - 1 ] ) ;
// Push the false location.
o_code . push_back ( Instruction : : PUSH ) ;
ends . push_back ( ( unsigned ) o_code . size ( ) ) ;
o_locs . push_back ( ends . back ( ) ) ;
o_code . push_back ( 0 ) ;
// Check if true - predicate
appendCode ( o_code , o_locs , codes [ i - 1 ] , locs [ i - 1 ] ) ;
pushLocation ( o_code , 0 ) ;
// Jump to end...
o_code . push_back ( Instruction : : NOT ) ;
o_code . push_back ( Instruction : : JMPI ) ;
o_code . push_back ( ( byte ) Instruction : : NOT ) ;
o_code . push_back ( ( byte ) Instruction : : JU MPI ) ;
}
o_code . push_back ( Instruction : : POP ) ;
o_code . push_back ( ( byte ) Instruction : : POP ) ;
}
// Check if true - predicate
@ -593,11 +673,11 @@ static int compileLispFragment(char const*& d, char const* e, bool _quiet, u256s
// At end now.
for ( auto i : ends )
o_code [ i ] = o_code . size ( ) ;
increaseLocation ( o_code , i , o_code . size ( ) ) ;
}
else if ( t = = " OR " )
{
vector < u256 s> codes ;
vector < byte s> codes ;
vector < vector < unsigned > > locs ;
while ( d ! = e )
{
@ -621,24 +701,22 @@ static int compileLispFragment(char const*& d, char const* e, bool _quiet, u256s
if ( codes . size ( ) > 1 )
{
o_code . push_back ( Instruction : : PUSH ) ;
o_code . push_back ( 1 ) ;
pushLiteral ( o_code , 1 ) ;
for ( unsigned i = 1 ; i < codes . size ( ) ; + + i )
{
// Check if true - predicate
appendCode ( o_code , o_locs , codes [ i - 1 ] , locs [ i - 1 ] ) ;
// Push the false location.
o_code . push_back ( Instruction : : PUSH ) ;
ends . push_back ( ( unsigned ) o_code . size ( ) ) ;
o_locs . push_back ( ends . back ( ) ) ;
o_code . push_back ( 0 ) ;
// Check if true - predicate
appendCode ( o_code , o_locs , codes [ i - 1 ] , locs [ i - 1 ] ) ;
pushLocation ( o_code , 0 ) ;
// Jump to end...
o_code . push_back ( Instruction : : JMPI ) ;
o_code . push_back ( ( byte ) Instruction : : JUMPI ) ;
}
o_code . push_back ( Instruction : : POP ) ;
o_code . push_back ( ( byte ) Instruction : : POP ) ;
}
// Check if true - predicate
@ -646,7 +724,7 @@ static int compileLispFragment(char const*& d, char const* e, bool _quiet, u256s
// At end now.
for ( auto i : ends )
o_code [ i ] = o_code . size ( ) ;
increaseLocation ( o_code , i , o_code . size ( ) ) ;
}
else
{
@ -655,14 +733,14 @@ static int compileLispFragment(char const*& d, char const* e, bool _quiet, u256s
{
if ( exec )
{
vector < pair < u256 s, vector < unsigned > > > codes ( 1 ) ;
vector < pair < byte s, vector < unsigned > > > codes ( 1 ) ;
int totalArgs = 0 ;
while ( d ! = e )
{
int o = compileLispFragment ( d , e , _quiet , codes . back ( ) . first , codes . back ( ) . second ) ;
if ( o < 1 )
break ;
codes . push_back ( pair < u256 s, vector < unsigned > > ( ) ) ;
codes . push_back ( pair < byte s, vector < unsigned > > ( ) ) ;
totalArgs + = o ;
}
int ea = c_instructionInfo . at ( it - > second ) . args ;
@ -674,13 +752,13 @@ static int compileLispFragment(char const*& d, char const* e, bool _quiet, u256s
for ( auto it = codes . rbegin ( ) ; it ! = codes . rend ( ) ; + + it )
appendCode ( o_code , o_locs , it - > first , it - > second ) ;
o_code . push_back ( ( u256 ) it - > second ) ;
o_code . push_back ( ( byte ) it - > second ) ;
outs = c_instructionInfo . at ( it - > second ) . ret ;
}
else
{
o_code . push_back ( Instruction : : PUSH ) ;
o_code . push_back ( it - > second ) ;
o_code . push_back ( ( byte ) Instruction : : PUSH1 ) ;
o_code . push_back ( ( byte ) it - > second ) ;
}
}
else
@ -688,42 +766,39 @@ static int compileLispFragment(char const*& d, char const* e, bool _quiet, u256s
auto it = c_arith . find ( t ) ;
if ( it ! = c_arith . end ( ) )
{
int i = 0 ;
vector < pair < bytes , vector < unsigned > > > codes ( 1 ) ;
int totalArgs = 0 ;
while ( d ! = e )
{
u256s codes ;
vector < unsigned > locs ;
int o = compileLispFragment ( d , e , _quiet , codes , locs ) ;
if ( o = = - 1 )
{
if ( ! i )
cwarn < < " Expected at least one argument to operation " < < t ;
break ;
}
if ( o = = 0 )
{
cwarn < < " null operation given to " < < t ;
int o = compileLispFragment ( d , e , _quiet , codes . back ( ) . first , codes . back ( ) . second ) ;
if ( o < 1 )
break ;
}
appendCode ( o_code , o_locs , codes , locs ) ;
i + = o ;
for ( ; i > 1 ; - - i )
o_code . push_back ( ( u256 ) it - > second ) ;
codes . push_back ( pair < bytes , vector < unsigned > > ( ) ) ;
totalArgs + = o ;
}
codes . pop_back ( ) ;
if ( ! totalArgs )
{
cwarn < < " Expected at least one argument to operation " < < t ;
break ;
}
for ( auto jt = codes . rbegin ( ) ; jt ! = codes . rend ( ) ; + + jt )
appendCode ( o_code , o_locs , jt - > first , jt - > second ) ;
o_code . push_back ( ( byte ) it - > second ) ;
}
else
{
auto it = c_binary . find ( t ) ;
if ( it ! = c_binary . end ( ) )
{
vector < pair < u256 s, vector < unsigned > > > codes ( 1 ) ;
vector < pair < byte s, vector < unsigned > > > codes ( 1 ) ;
int totalArgs = 0 ;
while ( d ! = e )
{
int o = compileLispFragment ( d , e , _quiet , codes . back ( ) . first , codes . back ( ) . second ) ;
if ( o < 1 )
break ;
codes . push_back ( pair < u256 s, vector < unsigned > > ( ) ) ;
codes . push_back ( pair < byte s, vector < unsigned > > ( ) ) ;
totalArgs + = o ;
}
codes . pop_back ( ) ;
@ -733,18 +808,18 @@ static int compileLispFragment(char const*& d, char const* e, bool _quiet, u256s
cwarn < < " Expected two arguments to binary operator " < < t < < " ; got " < < totalArgs < < " . " ;
break ;
}
for ( auto i t = codes . rbegin ( ) ; i t ! = codes . rend ( ) ; + + i t)
appendCode ( o_code , o_locs , i t- > first , i t- > second ) ;
if ( it - > second = = Instruction : : NOT )
o_code . push_back ( Instruction : : EQ ) ;
o_code . push_back ( ( u256 ) it - > second ) ;
for ( auto j t = codes . rbegin ( ) ; j t ! = codes . rend ( ) ; + + j t)
appendCode ( o_code , o_locs , j t- > first , j t- > second ) ;
if ( it - > second . second )
o_code . push_back ( ( byte ) Instruction : : NOT ) ;
o_code . push_back ( ( byte ) it - > second . first ) ;
}
else
{
auto it = c_unary . find ( t ) ;
if ( it ! = c_unary . end ( ) )
{
vector < pair < u256 s, vector < unsigned > > > codes ( 1 ) ;
vector < pair < byte s, vector < unsigned > > > codes ( 1 ) ;
int totalArgs = 0 ;
while ( d ! = e )
{
@ -752,7 +827,7 @@ static int compileLispFragment(char const*& d, char const* e, bool _quiet, u256s
if ( o = = - 1 )
break ;
totalArgs + = o ;
codes . push_back ( pair < u256 s, vector < unsigned > > ( ) ) ;
codes . push_back ( pair < byte s, vector < unsigned > > ( ) ) ;
}
codes . pop_back ( ) ;
// int i = (int)codes.size();
@ -763,7 +838,7 @@ static int compileLispFragment(char const*& d, char const* e, bool _quiet, u256s
}
for ( auto it = codes . rbegin ( ) ; it ! = codes . rend ( ) ; + + it )
appendCode ( o_code , o_locs , it - > first , it - > second ) ;
o_code . push_back ( it - > second ) ;
o_code . push_back ( ( byte ) it - > second ) ;
}
else if ( ! _quiet )
cwarn < < " Unknown assembler token " < < t ;
@ -781,29 +856,31 @@ static int compileLispFragment(char const*& d, char const* e, bool _quiet, u256s
return - 1 ;
}
u256 s eth : : compileLisp ( std : : string const & _code , bool _quiet )
byte s eth : : compileLisp ( std : : string const & _code , bool _quiet , bytes & _ini t )
{
char const * d = _code . data ( ) ;
char const * e = _code . data ( ) + _code . size ( ) ;
u256 s ret ;
byte s ret ;
vector < unsigned > locs ;
compileLispFragment ( d , e , _quiet , ret , locs ) ;
locs . clear ( ) ;
compileLispFragment ( d , e , _quiet , _init , locs ) ;
return ret ;
}
string eth : : disassemble ( u256 s const & _mem )
string eth : : disassemble ( byte s const & _mem )
{
stringstream ret ;
uint numerics = 0 ;
for ( auto it = _mem . begin ( ) ; it ! = _mem . end ( ) ; + + it )
{
u256 n = * it ;
auto iit = c_instructionInfo . find ( ( Instruction ) ( uint ) n ) ;
if ( numerics | | iit = = c_instructionInfo . end ( ) | | ( u256 ) ( uint ) iit - > first ! = n ) // not an instruction or expecting an argument...
byte n = * it ;
auto iit = c_instructionInfo . find ( ( Instruction ) n ) ;
if ( numerics | | iit = = c_instructionInfo . end ( ) | | ( byte ) iit - > first ! = n ) // not an instruction or expecting an argument...
{
if ( numerics )
numerics - - ;
ret < < " 0x " < < hex < < n < < " " ;
ret < < " 0x " < < hex < < ( int ) n < < " " ;
}
else
{