@@ -9,7 +9,7 @@ use crate::{
99
1010use super :: { DefaultRuntimeProvider , RuntimeFunction , RuntimeProvider } ;
1111
12- use fe_mir:: ir:: TypeId ;
12+ use fe_mir:: ir:: { types :: TupleDef , Type , TypeId , TypeKind } ;
1313
1414use yultsur:: * ;
1515
@@ -287,6 +287,59 @@ pub(super) fn make_aggregate_init(
287287 RuntimeFunction ( func_def)
288288}
289289
290+ pub ( super ) fn make_enum_init (
291+ provider : & mut DefaultRuntimeProvider ,
292+ db : & dyn CodegenDb ,
293+ func_name : & str ,
294+ legalized_ty : TypeId ,
295+ arg_tys : Vec < TypeId > ,
296+ ) -> RuntimeFunction {
297+ debug_assert ! ( arg_tys. len( ) > 1 ) ;
298+
299+ let func_name = YulVariable :: new ( func_name) ;
300+ let is_sptr = legalized_ty. is_sptr ( db. upcast ( ) ) ;
301+ let ptr = YulVariable :: new ( "ptr" ) ;
302+ let tag = YulVariable :: new ( "tag" ) ;
303+ let tag_ty = arg_tys[ 0 ] ;
304+ let enum_data = || {
305+ ( 0 ..arg_tys. len ( ) - 1 )
306+ . into_iter ( )
307+ . map ( |i| YulVariable :: new ( format ! { "arg{}" , i} ) )
308+ } ;
309+
310+ let tuple_def = TupleDef {
311+ items : arg_tys. iter ( ) . copied ( ) . skip ( 1 ) . collect ( ) ,
312+ } ;
313+ let tuple_ty = db. mir_intern_type (
314+ Type {
315+ kind : TypeKind :: Tuple ( tuple_def) ,
316+ analyzer_ty : None ,
317+ }
318+ . into ( ) ,
319+ ) ;
320+ let data_ptr_ty = make_ptr ( db, tuple_ty, is_sptr) ;
321+ let data_offset = legalized_ty
322+ . deref ( db. upcast ( ) )
323+ . enum_data_offset ( db. upcast ( ) , SLOT_SIZE ) ;
324+ let enum_data_init = statements ! {
325+ [ statement! { [ ptr. ident( ) ] : = add( [ ptr. expr( ) ] , [ literal_expression!{ ( data_offset) } ] ) } ]
326+ [ yul:: Statement :: Expression ( provider. aggregate_init(
327+ db,
328+ ptr. expr( ) ,
329+ enum_data( ) . map( |arg| arg. expr( ) ) . collect( ) ,
330+ data_ptr_ty, arg_tys. iter( ) . copied( ) . skip( 1 ) . collect( ) ) ) ]
331+ } ;
332+
333+ let enum_data_args: Vec < _ > = enum_data ( ) . map ( |var| var. ident ( ) ) . collect ( ) ;
334+ let func_def = function_definition ! {
335+ function [ func_name. ident( ) ] ( [ ptr. ident( ) ] , [ tag. ident( ) ] , [ enum_data_args...] ) {
336+ [ yul:: Statement :: Expression ( provider. ptr_store( db, ptr. expr( ) , tag. expr( ) , make_ptr( db, tag_ty, is_sptr) ) ) ]
337+ [ enum_data_init...]
338+ }
339+ } ;
340+ RuntimeFunction :: from_statement ( func_def)
341+ }
342+
290343pub ( super ) fn make_string_copy (
291344 provider : & mut DefaultRuntimeProvider ,
292345 db : & dyn CodegenDb ,
0 commit comments