@@ -40,6 +40,7 @@ Section [The Abstract Format](`e:erts:absform.md`) in ERTS User's Guide.
40
40
strict_ra = [], % Strict record accesses
41
41
checked_ra = [], % Successfully accessed records
42
42
dialyzer = false , % Compiler option 'dialyzer'
43
+ rec_init_count = 0 , % Number of generated record init functions
43
44
new_forms = #{}, % New forms
44
45
strict_rec_tests = true :: boolean ()
45
46
}).
@@ -96,7 +97,12 @@ forms([{function,Anno,N,A,Cs0} | Fs0], St0) ->
96
97
forms ([F | Fs0 ], St0 ) ->
97
98
{Fs ,St } = forms (Fs0 , St0 ),
98
99
{[F | Fs ], St };
99
- forms ([], # exprec {new_forms = FsN }= St ) -> {maps :values (FsN ),St };
100
+ forms ([], # exprec {new_forms = FsN }= St ) ->
101
+ {[{'function' , Anno ,
102
+ maps :get (Def ,FsN ),
103
+ 0 ,
104
+ [{'clause' , Anno , [], [], [Def ]}]}
105
+ || {_ ,Anno ,_ }= Def <- maps :keys (FsN )], St };
100
106
forms ([], St ) -> {[],St }.
101
107
102
108
clauses ([{clause ,Anno ,H0 ,G0 ,B0 } | Cs0 ], St0 ) ->
@@ -373,28 +379,30 @@ expr({record_index,Anno,Name,F}, St) ->
373
379
expr (I , St );
374
380
expr ({record ,Anno0 ,Name ,Is }, St ) ->
375
381
Anno = mark_record (Anno0 , St ),
376
-
377
- IsUndefined = [{RF , AnnoRF , Field , {atom , AnnoRF , 'undefined' }} || {record_field = RF , AnnoRF , Field , _ } <- Is ],
378
- Fields = lists :flatten (lists :sort ([atom_to_list (FieldAtom ) || {record_field , _ , {atom , _ , FieldAtom }, _ } <- Is ])),
379
- R_default_init = [{atom ,Anno ,Name } |
380
- record_inits (record_fields (Name , Anno0 , St ),IsUndefined )],
381
382
R_init = [{atom ,Anno ,Name } |
382
383
record_inits (record_fields (Name , Anno0 , St ), Is )],
383
384
Vars = lists :flatten (traverse_af (Is , fun save_vars /2 )),
384
385
% % If R_init contains free variables that was not bound via Is
385
386
case free_variables (R_init , Vars ) of
386
387
true ->
387
- FName = list_to_atom (" erl_expand_records_init_" ++ atom_to_list (Name )++ " _" ++ Fields ),
388
+ IsUndefined = [{RF , AnnoRF , Field , {atom , AnnoRF , 'undefined' }} || {record_field = RF , AnnoRF , Field , _ } <- Is ],
389
+ R_default_init = [{atom ,Anno ,Name } |
390
+ record_inits (record_fields (Name , Anno0 , St ),IsUndefined )],
388
391
% % add a function to the module that returns the
389
392
% % initialized record, we generate different init functions
390
393
% % depending on which fields that will override the default value
391
- {Tup , St1 } = expr ({tuple ,Anno ,R_default_init },St ),
392
- F = {'function' , Anno , FName , 0 ,
393
- [{'clause' , Anno , [], [], [Tup ]}]},
394
- % % replace the record expression with a call expression
394
+ {Def , St1 } = expr ({tuple ,Anno ,R_default_init },St ),
395
+ Map = St1 # exprec .new_forms ,
396
+ {FName ,St2 } = case maps :get (Def , Map , undefined ) of
397
+ undefined ->
398
+ C = St1 # exprec .rec_init_count ,
399
+ NewName = list_to_atom (" rec_init$^" ++ integer_to_list (C )),
400
+ {NewName , St1 # exprec {rec_init_count = C + 1 , new_forms = Map #{Def => NewName }}};
401
+ OldName -> {OldName ,St1 }
402
+ end ,
403
+ % % replace the init record expression with a call expression
395
404
% % to the newly added function and a record update
396
- C = {call ,Anno ,{atom ,Anno ,FName },[]},
397
- expr ({record , Anno0 , C , Name , Is },St1 # exprec {new_forms = (St # exprec .new_forms )#{FName => F }});
405
+ expr ({record , Anno0 , {call ,Anno ,{atom ,Anno ,FName },[]}, Name , Is },St2 );
398
406
false ->
399
407
% % No free variables means that we can just
400
408
% % output the record as a tuple.
0 commit comments