@@ -5,7 +5,6 @@ use crate::{
55 error:: { Error , Result } ,
66 ffi:: get_struct_field_type_at,
77 metadata:: { drop_overrides:: DropOverridesMeta , MetadataStorage } ,
8- native_panic,
98 starknet:: handler:: StarknetSyscallHandlerCallbacks ,
109 utils:: { get_integer_layout, BlockExt , GepIndex , ProgramRegistryExt , PRIME } ,
1110} ;
@@ -140,8 +139,8 @@ pub fn build<'ctx, 'this>(
140139 StarknetConcreteLibfunc :: Sha256ProcessBlock ( info) => build_sha256_process_block_syscall (
141140 context, registry, entry, location, helper, metadata, info,
142141 ) ,
143- StarknetConcreteLibfunc :: MetaTxV0 ( _ ) => {
144- native_panic ! ( "Implement MetaTxV0 libfunc" ) ;
142+ StarknetConcreteLibfunc :: MetaTxV0 ( info ) => {
143+ build_meta_tx_v0 ( context , registry , entry , location , helper , metadata , info )
145144 }
146145 #[ cfg( feature = "with-cheatcode" ) ]
147146 StarknetConcreteLibfunc :: Testing ( TestingConcreteLibfunc :: Cheatcode ( info) ) => {
@@ -2124,6 +2123,221 @@ pub fn build_library_call<'ctx, 'this>(
21242123 Ok ( ( ) )
21252124}
21262125
2126+ pub fn build_meta_tx_v0 < ' ctx , ' this > (
2127+ context : & ' ctx Context ,
2128+ registry : & ProgramRegistry < CoreType , CoreLibfunc > ,
2129+ entry : & ' this Block < ' ctx > ,
2130+ location : Location < ' ctx > ,
2131+ helper : & LibfuncHelper < ' ctx , ' this > ,
2132+ metadata : & mut MetadataStorage ,
2133+ info : & SignatureOnlyConcreteLibfunc ,
2134+ ) -> Result < ( ) > {
2135+ // pub extern fn call_contract_syscall(
2136+ // address: ContractAddress,
2137+ // entry_point_selector: felt252,
2138+ // calldata: Span<felt252>,
2139+ // ) -> SyscallResult<Span<felt252>> implicits(GasBuiltin, System) nopanic;
2140+ //
2141+ // extern fn meta_tx_v0_syscall(
2142+ // address: ContractAddress,
2143+ // entry_point_selector: felt252,
2144+ // calldata: Span<felt252>,
2145+ // signature: Span<felt252>,
2146+ // ) -> SyscallResult<Span<felt252>> implicits(GasBuiltin, System) nopanic;
2147+
2148+ // Extract self pointer.
2149+ let ptr = entry. load (
2150+ context,
2151+ location,
2152+ entry. arg ( 1 ) ?,
2153+ llvm:: r#type:: pointer ( context, 0 ) ,
2154+ ) ?;
2155+
2156+ // Allocate space for the return value.
2157+ let ( result_layout, ( result_tag_ty, result_tag_layout) , variant_tys) =
2158+ crate :: types:: r#enum:: get_type_for_variants (
2159+ context,
2160+ helper,
2161+ registry,
2162+ metadata,
2163+ & [
2164+ info. branch_signatures ( ) [ 0 ] . vars [ 2 ] . ty . clone ( ) ,
2165+ info. branch_signatures ( ) [ 1 ] . vars [ 2 ] . ty . clone ( ) ,
2166+ ] ,
2167+ ) ?;
2168+
2169+ let result_ptr = helper. init_block ( ) . alloca1 (
2170+ context,
2171+ location,
2172+ llvm:: r#type:: r#struct (
2173+ context,
2174+ & [
2175+ result_tag_ty,
2176+ llvm:: r#type:: array (
2177+ IntegerType :: new ( context, 8 ) . into ( ) ,
2178+ ( result_layout. size ( ) - 1 ) . try_into ( ) ?,
2179+ ) ,
2180+ ] ,
2181+ false ,
2182+ ) ,
2183+ result_layout. align ( ) ,
2184+ ) ?;
2185+
2186+ // Allocate space and write the current gas.
2187+ let ( gas_ty, gas_layout) = registry. build_type_with_layout (
2188+ context,
2189+ helper,
2190+ metadata,
2191+ & info. param_signatures ( ) [ 0 ] . ty ,
2192+ ) ?;
2193+ let gas_builtin_ptr =
2194+ helper
2195+ . init_block ( )
2196+ . alloca1 ( context, location, gas_ty, gas_layout. align ( ) ) ?;
2197+ entry. store ( context, location, gas_builtin_ptr, entry. arg ( 0 ) ?) ?;
2198+
2199+ // Allocate `address` argument and write the value.
2200+ let address_arg_ptr = helper. init_block ( ) . alloca_int ( context, location, 252 ) ?;
2201+ entry. store ( context, location, address_arg_ptr, entry. arg ( 2 ) ?) ?;
2202+
2203+ // Allocate `entry_point_selector` argument and write its value.
2204+ let entry_point_selector_arg_ptr = helper. init_block ( ) . alloca_int ( context, location, 252 ) ?;
2205+ entry. store (
2206+ context,
2207+ location,
2208+ entry_point_selector_arg_ptr,
2209+ entry. arg ( 3 ) ?,
2210+ ) ?;
2211+
2212+ // Allocate `calldata` argument and write the value.
2213+ let calldata_arg_ty = llvm:: r#type:: r#struct (
2214+ context,
2215+ & [ llvm:: r#type:: r#struct (
2216+ context,
2217+ & [
2218+ llvm:: r#type:: pointer ( context, 0 ) ,
2219+ IntegerType :: new ( context, 32 ) . into ( ) ,
2220+ IntegerType :: new ( context, 32 ) . into ( ) ,
2221+ IntegerType :: new ( context, 32 ) . into ( ) ,
2222+ ] ,
2223+ false ,
2224+ ) ] ,
2225+ false ,
2226+ ) ;
2227+ let calldata_arg_ptr = helper. init_block ( ) . alloca1 (
2228+ context,
2229+ location,
2230+ calldata_arg_ty,
2231+ get_integer_layout ( 64 ) . align ( ) ,
2232+ ) ?;
2233+ entry. store ( context, location, calldata_arg_ptr, entry. arg ( 4 ) ?) ?;
2234+
2235+ // Allocate `signature` argument and write the value.
2236+ let signature_arg_ty = calldata_arg_ty;
2237+ let signature_arg_ptr = helper. init_block ( ) . alloca1 (
2238+ context,
2239+ location,
2240+ signature_arg_ty,
2241+ get_integer_layout ( 64 ) . align ( ) ,
2242+ ) ?;
2243+ entry. store ( context, location, signature_arg_ptr, entry. arg ( 5 ) ?) ?;
2244+
2245+ // Extract function pointer.
2246+ let fn_ptr = entry. gep (
2247+ context,
2248+ location,
2249+ entry. arg ( 1 ) ?,
2250+ & [ GepIndex :: Const (
2251+ StarknetSyscallHandlerCallbacks :: < ( ) > :: META_TX_V0 . try_into ( ) ?,
2252+ ) ] ,
2253+ llvm:: r#type:: pointer ( context, 0 ) ,
2254+ ) ?;
2255+ let fn_ptr = entry. load ( context, location, fn_ptr, llvm:: r#type:: pointer ( context, 0 ) ) ?;
2256+
2257+ entry. append_operation (
2258+ OperationBuilder :: new ( "llvm.call" , location)
2259+ . add_operands ( & [
2260+ fn_ptr,
2261+ result_ptr,
2262+ ptr,
2263+ gas_builtin_ptr,
2264+ address_arg_ptr,
2265+ entry_point_selector_arg_ptr,
2266+ calldata_arg_ptr,
2267+ signature_arg_ptr,
2268+ ] )
2269+ . build ( ) ?,
2270+ ) ;
2271+
2272+ let result = entry. load (
2273+ context,
2274+ location,
2275+ result_ptr,
2276+ llvm:: r#type:: r#struct (
2277+ context,
2278+ & [
2279+ result_tag_ty,
2280+ llvm:: r#type:: array (
2281+ IntegerType :: new ( context, 8 ) . into ( ) ,
2282+ ( result_layout. size ( ) - 1 ) . try_into ( ) ?,
2283+ ) ,
2284+ ] ,
2285+ false ,
2286+ ) ,
2287+ ) ?;
2288+ let result_tag = entry. extract_value (
2289+ context,
2290+ location,
2291+ result,
2292+ IntegerType :: new ( context, 1 ) . into ( ) ,
2293+ 0 ,
2294+ ) ?;
2295+
2296+ let payload_ok = {
2297+ let ptr = entry. gep (
2298+ context,
2299+ location,
2300+ result_ptr,
2301+ & [ GepIndex :: Const (
2302+ result_tag_layout. extend ( variant_tys[ 0 ] . 1 ) ?. 1 . try_into ( ) ?,
2303+ ) ] ,
2304+ IntegerType :: new ( context, 8 ) . into ( ) ,
2305+ ) ?;
2306+ entry. load ( context, location, ptr, variant_tys[ 0 ] . 0 ) ?
2307+ } ;
2308+ let payload_err = {
2309+ let ptr = entry. gep (
2310+ context,
2311+ location,
2312+ result_ptr,
2313+ & [ GepIndex :: Const (
2314+ result_tag_layout. extend ( variant_tys[ 1 ] . 1 ) ?. 1 . try_into ( ) ?,
2315+ ) ] ,
2316+ IntegerType :: new ( context, 8 ) . into ( ) ,
2317+ ) ?;
2318+ entry. load ( context, location, ptr, variant_tys[ 1 ] . 0 ) ?
2319+ } ;
2320+
2321+ let remaining_gas = entry. load (
2322+ context,
2323+ location,
2324+ gas_builtin_ptr,
2325+ IntegerType :: new ( context, 64 ) . into ( ) ,
2326+ ) ?;
2327+
2328+ entry. append_operation ( helper. cond_br (
2329+ context,
2330+ result_tag,
2331+ [ 1 , 0 ] ,
2332+ [
2333+ & [ remaining_gas, entry. arg ( 1 ) ?, payload_err] ,
2334+ & [ remaining_gas, entry. arg ( 1 ) ?, payload_ok] ,
2335+ ] ,
2336+ location,
2337+ ) ) ;
2338+ Ok ( ( ) )
2339+ }
2340+
21272341pub fn build_replace_class < ' ctx , ' this > (
21282342 context : & ' ctx Context ,
21292343 registry : & ProgramRegistry < CoreType , CoreLibfunc > ,
0 commit comments