@@ -8,7 +8,7 @@ use crate::codegen::{Builtin, Expression};
88use crate :: emit:: binary:: Binary ;
99use crate :: emit:: storage:: StorageSlot ;
1010use crate :: emit:: stylus:: StylusTarget ;
11- use crate :: emit:: { ContractArgs , TargetRuntime , Variable } ;
11+ use crate :: emit:: { expression :: expression , ContractArgs , TargetRuntime , Variable } ;
1212use crate :: emit_context;
1313use crate :: sema:: ast:: { self , CallTy } ;
1414use crate :: sema:: ast:: { Function , Type } ;
@@ -895,6 +895,47 @@ impl<'a> TargetRuntime<'a> for StylusTarget {
895895 emit_context ! ( bin) ;
896896
897897 match expr {
898+ Expression :: Builtin {
899+ kind : Builtin :: Balance ,
900+ args,
901+ ..
902+ } => {
903+ let address = expression ( self , bin, & args[ 0 ] , vartab, function) . into_array_value ( ) ;
904+
905+ let address_ptr = bin
906+ . builder
907+ . build_alloca ( bin. address_type ( ) , "address" )
908+ . unwrap ( ) ;
909+
910+ bin. builder . build_store ( address_ptr, address) . unwrap ( ) ;
911+
912+ let balance = bin
913+ . builder
914+ . build_alloca ( bin. value_type ( ) , "balance" )
915+ . unwrap ( ) ;
916+
917+ call ! (
918+ "account_balance" ,
919+ & [ address_ptr. into( ) , balance. into( ) ] ,
920+ "account_balance"
921+ ) ;
922+
923+ // smoelius: Balance is big-endian and must be byte-swapped.
924+ let temp = bin. builder . build_alloca ( bin. value_type ( ) , "hash" ) . unwrap ( ) ;
925+
926+ call ! (
927+ "__beNtoleN" ,
928+ & [
929+ balance. into( ) ,
930+ temp. into( ) ,
931+ i32_const!( bin. ns. value_length as u64 ) . into( )
932+ ]
933+ ) ;
934+
935+ bin. builder
936+ . build_load ( bin. value_type ( ) , temp, "balance" )
937+ . unwrap ( )
938+ }
898939 Expression :: Builtin {
899940 kind : Builtin :: BaseFee ,
900941 ..
@@ -951,6 +992,90 @@ impl<'a> TargetRuntime<'a> for StylusTarget {
951992
952993 chainid. into ( )
953994 }
995+ Expression :: Builtin {
996+ kind : Builtin :: ContractCode ,
997+ args,
998+ ..
999+ } => {
1000+ let address = expression ( self , bin, & args[ 0 ] , vartab, function) . into_array_value ( ) ;
1001+
1002+ let address_ptr = bin
1003+ . builder
1004+ . build_alloca ( bin. address_type ( ) , "address" )
1005+ . unwrap ( ) ;
1006+
1007+ bin. builder . build_store ( address_ptr, address) . unwrap ( ) ;
1008+
1009+ let size = call ! (
1010+ "account_code_size" ,
1011+ & [ address_ptr. into( ) ] ,
1012+ "account_code_size"
1013+ )
1014+ . try_as_basic_value ( )
1015+ . left ( )
1016+ . unwrap ( )
1017+ . into_int_value ( ) ;
1018+
1019+ let account_code = bin
1020+ . builder
1021+ . build_array_alloca ( bin. context . i8_type ( ) , size, "account_code" )
1022+ . unwrap ( ) ;
1023+
1024+ call ! (
1025+ "account_code" ,
1026+ & [
1027+ address_ptr. into( ) ,
1028+ i32_zero!( ) . into( ) ,
1029+ size. into( ) ,
1030+ account_code. into( ) ,
1031+ ] ,
1032+ "account_code"
1033+ ) ;
1034+
1035+ call ! (
1036+ "vector_new" ,
1037+ & [ size. into( ) , i32_const!( 1 ) . into( ) , account_code. into( ) ]
1038+ )
1039+ . try_as_basic_value ( )
1040+ . left ( )
1041+ . unwrap ( )
1042+ }
1043+ Expression :: Builtin {
1044+ kind : Builtin :: ContractCodehash ,
1045+ args,
1046+ ..
1047+ } => {
1048+ let address = expression ( self , bin, & args[ 0 ] , vartab, function) . into_array_value ( ) ;
1049+
1050+ let address_ptr = bin
1051+ . builder
1052+ . build_alloca ( bin. address_type ( ) , "address" )
1053+ . unwrap ( ) ;
1054+
1055+ bin. builder . build_store ( address_ptr, address) . unwrap ( ) ;
1056+
1057+ let ty = bin. context . custom_width_int_type ( 256 ) ;
1058+
1059+ let digest_ptr = bin. builder . build_alloca ( ty, "digest" ) . unwrap ( ) ;
1060+
1061+ call ! (
1062+ "account_codehash" ,
1063+ & [ address_ptr. into( ) , digest_ptr. into( ) ] ,
1064+ "account_codehash"
1065+ ) ;
1066+
1067+ call ! (
1068+ "vector_new" ,
1069+ & [
1070+ i32_const!( 32 ) . into( ) ,
1071+ i32_const!( 1 ) . into( ) ,
1072+ digest_ptr. into( )
1073+ ]
1074+ )
1075+ . try_as_basic_value ( )
1076+ . left ( )
1077+ . unwrap ( )
1078+ }
9541079 Expression :: Builtin {
9551080 kind : Builtin :: Gasleft ,
9561081 ..
@@ -1020,6 +1145,33 @@ impl<'a> TargetRuntime<'a> for StylusTarget {
10201145 call ! ( "__memcpy" , & [ dest. into( ) , args. into( ) , args_len. into( ) ] ) ;
10211146 v
10221147 }
1148+ Expression :: Builtin {
1149+ kind : Builtin :: Gasprice ,
1150+ ..
1151+ } => {
1152+ let gasprice = bin
1153+ . builder
1154+ . build_alloca ( bin. value_type ( ) , "gasprice" )
1155+ . unwrap ( ) ;
1156+
1157+ call ! ( "tx_gas_price" , & [ gasprice. into( ) ] , "tx_gas_price" ) ;
1158+
1159+ // smoelius: `gasprice` is big-endian and must be byte-swapped.
1160+ let temp = bin. builder . build_alloca ( bin. value_type ( ) , "hash" ) . unwrap ( ) ;
1161+
1162+ call ! (
1163+ "__beNtoleN" ,
1164+ & [
1165+ gasprice. into( ) ,
1166+ temp. into( ) ,
1167+ i32_const!( bin. ns. value_length as u64 ) . into( )
1168+ ]
1169+ ) ;
1170+
1171+ bin. builder
1172+ . build_load ( bin. value_type ( ) , temp, "balance" )
1173+ . unwrap ( )
1174+ }
10231175 Expression :: Builtin {
10241176 kind : Builtin :: Origin ,
10251177 ..
0 commit comments