1+ use crate :: irgen:: constants:: constant_gen;
12use crate :: Codegen ;
23use alloy_primitives:: { hex, keccak256} ;
34use huff_neo_utils:: bytecode:: { BytecodeRes , Bytes , CircularCodeSizeIndices , Jump , Jumps } ;
@@ -8,6 +9,7 @@ use huff_neo_utils::opcodes::Opcode;
89use huff_neo_utils:: prelude:: {
910 BuiltinFunctionArg , BuiltinFunctionCall , BuiltinFunctionKind , Contract , MacroDefinition , MacroInvocation , TableDefinition ,
1011} ;
12+ use std:: fmt:: Display ;
1113
1214// TODO: First step to refactor and split the function into smaller functions
1315#[ allow( clippy:: too_many_arguments) ]
@@ -98,10 +100,17 @@ pub fn builtin_function_gen<'a>(
98100 bytes. push ( ( starting_offset, Bytes ( push_bytes) ) ) ;
99101 }
100102 BuiltinFunctionKind :: RightPad => {
101- let push_bytes = right_pad ( evm_version, contract, bf) ?;
103+ let push_bytes = builtin_pad ( evm_version, contract, bf, PadDirection :: Right ) ?;
102104 * offset += push_bytes. len ( ) / 2 ;
103105 bytes. push ( ( starting_offset, Bytes ( push_bytes) ) ) ;
104106 }
107+ BuiltinFunctionKind :: LeftPad => {
108+ return Err ( CodegenError {
109+ kind : CodegenErrorKind :: InvalidArguments ( String :: from ( "LeftPad is not supported in a function or macro" ) ) ,
110+ span : bf. span . clone ( ) ,
111+ token : None ,
112+ } ) ;
113+ }
105114 BuiltinFunctionKind :: DynConstructorArg => {
106115 if bf. args . len ( ) != 2 {
107116 tracing:: error!(
@@ -475,19 +484,38 @@ pub fn function_signature(contract: &Contract, bf: &BuiltinFunctionCall) -> Resu
475484 Ok ( push_bytes)
476485}
477486
478- pub fn right_pad ( evm_version : & EVMVersion , contract : & Contract , bf : & BuiltinFunctionCall ) -> Result < String , CodegenError > {
487+ #[ derive( Debug , Clone , PartialEq ) ]
488+ pub enum PadDirection {
489+ Left ,
490+ Right ,
491+ }
492+ impl Display for PadDirection {
493+ fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
494+ match self {
495+ PadDirection :: Left => write ! ( f, "__LEFTPAD" ) ,
496+ PadDirection :: Right => write ! ( f, "__RIGHTPAD" ) ,
497+ }
498+ }
499+ }
500+
501+ pub fn builtin_pad (
502+ evm_version : & EVMVersion ,
503+ contract : & Contract ,
504+ bf : & BuiltinFunctionCall ,
505+ direction : PadDirection ,
506+ ) -> Result < String , CodegenError > {
479507 if bf. args . len ( ) != 1 {
480- tracing:: error!( target = "codegen" , "Incorrect number of arguments passed to __RIGHTPAD , should be 1: {}" , bf. args. len( ) ) ;
508+ tracing:: error!( target = "codegen" , "Incorrect number of arguments passed to {direction} , should be 1: {}" , bf. args. len( ) ) ;
481509 return Err ( CodegenError {
482510 kind : CodegenErrorKind :: InvalidArguments ( format ! (
483- "Incorrect number of arguments passed to __RIGHTPAD , should be 1: {}" ,
511+ "Incorrect number of arguments passed to {direction} , should be 1: {}" ,
484512 bf. args. len( )
485513 ) ) ,
486514 span : bf. span . clone ( ) ,
487515 token : None ,
488516 } ) ;
489517 }
490- let first_arg = match bf. args [ 0 ] {
518+ let first_arg = match & bf. args [ 0 ] {
491519 BuiltinFunctionArg :: Argument ( ref arg) => arg. name . clone ( ) . unwrap_or_default ( ) ,
492520 BuiltinFunctionArg :: BuiltinFunctionCall ( ref inner_call) => {
493521 match inner_call. kind {
@@ -500,27 +528,33 @@ pub fn right_pad(evm_version: &EVMVersion, contract: &Contract, bf: &BuiltinFunc
500528 push_bytes[ 2 ..] . to_string ( ) // remove opcode
501529 }
502530 _ => {
503- tracing:: error!( target: "codegen" , "Invalid argument type passed to __RIGHTPAD " ) ;
531+ tracing:: error!( target: "codegen" , "Invalid function call argument type passed to {direction} " ) ;
504532 return Err ( CodegenError {
505- kind : CodegenErrorKind :: InvalidArguments ( String :: from ( "Invalid argument type passed to __RIGHTPAD " ) ) ,
533+ kind : CodegenErrorKind :: InvalidArguments ( format ! ( "Invalid argument type passed to {direction} " ) ) ,
506534 span : bf. span . clone ( ) ,
507535 token : None ,
508536 } ) ;
509537 }
510538 }
511539 }
540+ BuiltinFunctionArg :: Constant ( name, span) => {
541+ let push_bytes = constant_gen ( evm_version, name, contract, span) ?;
542+ push_bytes[ 2 ..] . to_string ( ) // remove opcode
543+ }
512544 _ => {
513- tracing:: error!( target: "codegen" , "Invalid argument type passed to __RIGHTPAD " ) ;
545+ tracing:: error!( target: "codegen" , "Invalid argument type passed to {direction} " ) ;
514546 return Err ( CodegenError {
515- kind : CodegenErrorKind :: InvalidArguments ( String :: from ( "Invalid argument type passed to __RIGHTPAD " ) ) ,
547+ kind : CodegenErrorKind :: InvalidArguments ( format ! ( "Invalid argument type passed to {direction} " ) ) ,
516548 span : bf. span . clone ( ) ,
517549 token : None ,
518550 } ) ;
519551 }
520552 } ;
521553 let hex = format_even_bytes ( first_arg) ;
522- let push_bytes = format ! ( "{}{hex}{}" , Opcode :: Push32 , "0" . repeat( 64 - hex. len( ) ) ) ;
523- Ok ( push_bytes)
554+ if direction == PadDirection :: Left {
555+ return Ok ( format ! ( "{}{}{hex}" , Opcode :: Push32 , "0" . repeat( 64 - hex. len( ) ) ) ) ;
556+ }
557+ Ok ( format ! ( "{}{hex}{}" , Opcode :: Push32 , "0" . repeat( 64 - hex. len( ) ) ) )
524558}
525559
526560pub fn builtin_bytes ( evm_version : & EVMVersion , bf : & BuiltinFunctionCall ) -> Result < String , CodegenError > {
0 commit comments