@@ -73,6 +73,7 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
73
73
uint32_t nesting_level;
74
74
uint32_t cur_loop_nesting_level;
75
75
bool is_prototype_only;
76
+ ASR::Function_t* main_func;
76
77
77
78
Vec<uint8_t > m_type_section;
78
79
Vec<uint8_t > m_import_section;
@@ -103,11 +104,14 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
103
104
std::map<std::string, uint32_t > m_self_func_name_idx_map;
104
105
std::map<std::string, uint32_t > m_string_to_iov_loc_map;
105
106
107
+ std::map<std::string,void (LCompilers::ASRToWASMVisitor::*)(int )> m_self_funcs_map;
108
+
106
109
public:
107
110
ASRToWASMVisitor (Allocator &al, diag::Diagnostics &diagnostics)
108
111
: m_al(al), diag(diagnostics) {
109
112
intrinsic_module = false ;
110
113
is_prototype_only = false ;
114
+ main_func = nullptr ;
111
115
nesting_level = 0 ;
112
116
cur_loop_nesting_level = 0 ;
113
117
no_of_types = 0 ;
@@ -323,9 +327,14 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
323
327
std::vector<wasm::type> results,
324
328
std::vector<wasm::type> locals,
325
329
std::string func_name,
326
- std::function<void ()> func_body) {
330
+ std::function<void ()> func_body,
331
+ int func_idx = -1
332
+ ) {
333
+
334
+ if (func_idx == -1 ) {
335
+ func_idx = no_of_types++;
336
+ }
327
337
328
- uint32_t func_idx = no_of_types;
329
338
{ // type declaration
330
339
wasm::emit_b8 (m_type_section, m_al, 0x60 );
331
340
wasm::emit_u32 (m_type_section, m_al, params.size ()); // no of params
@@ -336,7 +345,6 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
336
345
for (auto result:results) {
337
346
wasm::emit_b8 (m_type_section, m_al, result);
338
347
}
339
- no_of_types++;
340
348
}
341
349
342
350
/* ** Reference Function Prototype ***/
@@ -360,12 +368,11 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
360
368
361
369
/* ** Export the function ***/
362
370
wasm::emit_export_fn (m_export_section, m_al, func_name, func_idx); // add function to export
363
- m_self_func_name_idx_map[func_name] = func_idx;
364
371
no_of_functions++;
365
372
no_of_exports++;
366
373
}
367
374
368
- void emit_print_int () {
375
+ void emit_print_int (int fn_idx = - 1 ) {
369
376
using namespace wasm ;
370
377
define_emit_func ({i64 }, {}, {i64 , i64 , i64 , i64 }, " print_i64" , [&](){
371
378
// locals 0 is given parameter
@@ -475,10 +482,10 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
475
482
}
476
483
477
484
});
478
- });
485
+ }, fn_idx );
479
486
}
480
487
481
- void emit_print_float () {
488
+ void emit_print_float (int fn_idx = - 1 ) {
482
489
using namespace wasm ;
483
490
define_emit_func ({f64 }, {}, {i64 , i64 , i64 }, " print_f64" , [&](){
484
491
emit_if_else ([&](){
@@ -547,10 +554,10 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
547
554
548
555
wasm::emit_get_local (m_code_section, m_al, 3 );
549
556
wasm::emit_call (m_code_section, m_al, m_self_func_name_idx_map[" print_i64" ]);
550
- });
557
+ }, fn_idx );
551
558
}
552
559
553
- void emit_complex_add_32 () {
560
+ void emit_complex_add_32 (int fn_idx = - 1 ) {
554
561
using namespace wasm ;
555
562
define_emit_func ({f32 , f32 , f32 , f32 }, {f32 , f32 }, {}, " add_c32" , [&](){
556
563
wasm::emit_get_local (m_code_section, m_al, 0 );
@@ -560,10 +567,10 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
560
567
wasm::emit_get_local (m_code_section, m_al, 1 );
561
568
wasm::emit_get_local (m_code_section, m_al, 3 );
562
569
wasm::emit_f32_add (m_code_section, m_al);
563
- });
570
+ }, fn_idx );
564
571
}
565
572
566
- void emit_complex_add_64 () {
573
+ void emit_complex_add_64 (int fn_idx = - 1 ) {
567
574
using namespace wasm ;
568
575
define_emit_func ({f64 , f64 , f64 , f64 }, {f64 , f64 }, {}, " add_c64" , [&](){
569
576
wasm::emit_get_local (m_code_section, m_al, 0 );
@@ -573,10 +580,10 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
573
580
wasm::emit_get_local (m_code_section, m_al, 1 );
574
581
wasm::emit_get_local (m_code_section, m_al, 3 );
575
582
wasm::emit_f64_add (m_code_section, m_al);
576
- });
583
+ }, fn_idx );
577
584
}
578
585
579
- void emit_complex_sub_32 () {
586
+ void emit_complex_sub_32 (int fn_idx = - 1 ) {
580
587
using namespace wasm ;
581
588
define_emit_func ({f32 , f32 , f32 , f32 }, {f32 , f32 }, {}, " sub_c32" , [&](){
582
589
wasm::emit_get_local (m_code_section, m_al, 0 );
@@ -586,10 +593,10 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
586
593
wasm::emit_get_local (m_code_section, m_al, 1 );
587
594
wasm::emit_get_local (m_code_section, m_al, 3 );
588
595
wasm::emit_f32_sub (m_code_section, m_al);
589
- });
596
+ }, fn_idx );
590
597
}
591
598
592
- void emit_complex_sub_64 () {
599
+ void emit_complex_sub_64 (int fn_idx = - 1 ) {
593
600
using namespace wasm ;
594
601
define_emit_func ({f64 , f64 , f64 , f64 }, {f64 , f64 }, {}, " sub_c64" , [&](){
595
602
wasm::emit_get_local (m_code_section, m_al, 0 );
@@ -599,10 +606,10 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
599
606
wasm::emit_get_local (m_code_section, m_al, 1 );
600
607
wasm::emit_get_local (m_code_section, m_al, 3 );
601
608
wasm::emit_f64_sub (m_code_section, m_al);
602
- });
609
+ }, fn_idx );
603
610
}
604
611
605
- void emit_complex_mul_32 () {
612
+ void emit_complex_mul_32 (int fn_idx = - 1 ) {
606
613
using namespace wasm ;
607
614
define_emit_func ({f32 , f32 , f32 , f32 }, {f32 , f32 }, {}, " mul_c32" , [&](){
608
615
wasm::emit_get_local (m_code_section, m_al, 0 );
@@ -624,10 +631,10 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
624
631
wasm::emit_f32_mul (m_code_section, m_al);
625
632
626
633
wasm::emit_f32_add (m_code_section, m_al);
627
- });
634
+ }, fn_idx );
628
635
}
629
636
630
- void emit_complex_mul_64 () {
637
+ void emit_complex_mul_64 (int fn_idx = - 1 ) {
631
638
using namespace wasm ;
632
639
define_emit_func ({f64 , f64 , f64 , f64 }, {f64 , f64 }, {}, " mul_c64" , [&](){
633
640
wasm::emit_get_local (m_code_section, m_al, 0 );
@@ -649,10 +656,10 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
649
656
wasm::emit_f64_mul (m_code_section, m_al);
650
657
651
658
wasm::emit_f64_add (m_code_section, m_al);
652
- });
659
+ }, fn_idx );
653
660
}
654
661
655
- void emit_complex_abs_32 () {
662
+ void emit_complex_abs_32 (int fn_idx = - 1 ) {
656
663
using namespace wasm ;
657
664
define_emit_func ({f32 , f32 }, {f32 }, {}, " abs_c32" , [&](){
658
665
wasm::emit_get_local (m_code_section, m_al, 0 );
@@ -665,10 +672,10 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
665
672
666
673
wasm::emit_f32_add (m_code_section, m_al);
667
674
wasm::emit_f32_sqrt (m_code_section, m_al);
668
- });
675
+ }, fn_idx );
669
676
}
670
677
671
- void emit_complex_abs_64 () {
678
+ void emit_complex_abs_64 (int fn_idx = - 1 ) {
672
679
using namespace wasm ;
673
680
define_emit_func ({f64 , f64 }, {f64 }, {}, " abs_c64" , [&](){
674
681
wasm::emit_get_local (m_code_section, m_al, 0 );
@@ -681,7 +688,7 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
681
688
682
689
wasm::emit_f64_add (m_code_section, m_al);
683
690
wasm::emit_f64_sqrt (m_code_section, m_al);
684
- });
691
+ }, fn_idx );
685
692
}
686
693
687
694
template <typename T>
@@ -732,16 +739,17 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
732
739
for (int i = 0 ; i < 10 ; i++) {
733
740
emit_string (std::to_string (i));
734
741
}
735
- emit_print_int ();
736
- emit_print_float ();
737
- emit_complex_add_32 ();
738
- emit_complex_add_64 ();
739
- emit_complex_sub_32 ();
740
- emit_complex_sub_64 ();
741
- emit_complex_mul_32 ();
742
- emit_complex_mul_64 ();
743
- emit_complex_abs_32 ();
744
- emit_complex_abs_64 ();
742
+
743
+ m_self_funcs_map[" print_i64" ] = &ASRToWASMVisitor::emit_print_int;
744
+ m_self_funcs_map[" print_f64" ] = &ASRToWASMVisitor::emit_print_float;
745
+ m_self_funcs_map[" add_c32" ] = &ASRToWASMVisitor::emit_complex_add_32;
746
+ m_self_funcs_map[" add_c64" ] = &ASRToWASMVisitor::emit_complex_add_64;
747
+ m_self_funcs_map[" sub_c32" ] = &ASRToWASMVisitor::emit_complex_sub_32;
748
+ m_self_funcs_map[" sub_c64" ] = &ASRToWASMVisitor::emit_complex_sub_64;
749
+ m_self_funcs_map[" mul_c32" ] = &ASRToWASMVisitor::emit_complex_mul_32;
750
+ m_self_funcs_map[" mul_c64" ] = &ASRToWASMVisitor::emit_complex_mul_64;
751
+ m_self_funcs_map[" abs_c32" ] = &ASRToWASMVisitor::emit_complex_abs_32;
752
+ m_self_funcs_map[" abs_c64" ] = &ASRToWASMVisitor::emit_complex_abs_64;
745
753
746
754
{
747
755
// Pre-declare all functions first, then generate code
@@ -756,9 +764,7 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
756
764
x.m_global_scope ->get_scope ().end ());
757
765
ASR::symbol_t *mod = x.m_global_scope ->get_symbol (item);
758
766
if (ASR::is_a<ASR::Module_t>(*mod)) {
759
- ASR::Module_t *m =
760
- ASR::down_cast<ASR::Module_t>(mod);
761
- declare_all_functions (*(m->m_symtab ));
767
+ visit_symbol (*mod);
762
768
}
763
769
}
764
770
@@ -768,9 +774,7 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
768
774
// then the main program:
769
775
for (auto &item : x.m_global_scope ->get_scope ()) {
770
776
if (ASR::is_a<ASR::Program_t>(*item.second )) {
771
- ASR::Program_t *p =
772
- ASR::down_cast<ASR::Program_t>(item.second );
773
- declare_all_functions (*(p->m_symtab ));
777
+ visit_symbol (*item.second );
774
778
}
775
779
}
776
780
}
@@ -811,6 +815,21 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
811
815
visit_symbol (*item.second );
812
816
}
813
817
}
818
+
819
+ std::vector<std::pair<std::string, uint32_t >> ordered_self_funcs_name_idx;
820
+ for (auto self_func:m_self_func_name_idx_map) {
821
+ ordered_self_funcs_name_idx.push_back (self_func);
822
+ }
823
+
824
+ sort (ordered_self_funcs_name_idx.begin (),
825
+ ordered_self_funcs_name_idx.end (),
826
+ [](std::pair<std::string, uint32_t > &a, std::pair<std::string, uint32_t > &b){
827
+ return a.second < b.second ;
828
+ });
829
+
830
+ for (auto self_func:ordered_self_funcs_name_idx) {
831
+ (this ->*m_self_funcs_map[self_func.first ])(self_func.second );
832
+ }
814
833
}
815
834
816
835
void declare_all_functions (const SymbolTable &symtab) {
@@ -840,14 +859,15 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
840
859
declare_all_functions (*x.m_symtab );
841
860
842
861
// Generate main program code
843
- auto main_func = ASRUtils::make_Function_t_util (
844
- m_al, x.base .base .loc , x.m_symtab , s2c (m_al, " _start" ),
845
- nullptr , 0 , nullptr , 0 , x.m_body , x.n_body , nullptr ,
846
- ASR::abiType::Source, ASR::accessType::Public,
847
- ASR::deftypeType::Implementation, nullptr , false , false , false , false , false ,
848
- nullptr , 0 , nullptr , 0 , false , false , false );
849
- emit_function_prototype (*((ASR::Function_t *)main_func));
850
- emit_function_body (*((ASR::Function_t *)main_func));
862
+ if (main_func == nullptr ) {
863
+ main_func = (ASR::Function_t *)ASRUtils::make_Function_t_util (
864
+ m_al, x.base .base .loc , x.m_symtab , s2c (m_al, " _start" ),
865
+ nullptr , 0 , nullptr , 0 , x.m_body , x.n_body , nullptr ,
866
+ ASR::abiType::Source, ASR::accessType::Public,
867
+ ASR::deftypeType::Implementation, nullptr , false , false , false , false , false ,
868
+ nullptr , 0 , nullptr , 0 , false , false , false );
869
+ }
870
+ this ->visit_Function (*main_func);
851
871
}
852
872
853
873
void emit_var_type (Vec<uint8_t > &code, ASR::Variable_t *v) {
@@ -1649,24 +1669,42 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
1649
1669
switch (x.m_op ) {
1650
1670
case ASR::binopType::Add: {
1651
1671
if (a_kind == 4 ) {
1672
+ if (m_self_func_name_idx_map.find (" add_c32" ) == m_self_func_name_idx_map.end ()) {
1673
+ m_self_func_name_idx_map[" add_c32" ] = no_of_types++;
1674
+ }
1652
1675
wasm::emit_call (m_code_section, m_al, m_self_func_name_idx_map[" add_c32" ]);
1653
1676
} else {
1677
+ if (m_self_func_name_idx_map.find (" add_c64" ) == m_self_func_name_idx_map.end ()) {
1678
+ m_self_func_name_idx_map[" add_c64" ] = no_of_types++;
1679
+ }
1654
1680
wasm::emit_call (m_code_section, m_al, m_self_func_name_idx_map[" add_c64" ]);
1655
1681
}
1656
1682
break ;
1657
1683
};
1658
1684
case ASR::binopType::Sub: {
1659
1685
if (a_kind == 4 ) {
1686
+ if (m_self_func_name_idx_map.find (" sub_c32" ) == m_self_func_name_idx_map.end ()) {
1687
+ m_self_func_name_idx_map[" sub_c32" ] = no_of_types++;
1688
+ }
1660
1689
wasm::emit_call (m_code_section, m_al, m_self_func_name_idx_map[" sub_c32" ]);
1661
1690
} else {
1691
+ if (m_self_func_name_idx_map.find (" sub_c64" ) == m_self_func_name_idx_map.end ()) {
1692
+ m_self_func_name_idx_map[" sub_c64" ] = no_of_types++;
1693
+ }
1662
1694
wasm::emit_call (m_code_section, m_al, m_self_func_name_idx_map[" sub_c64" ]);
1663
1695
}
1664
1696
break ;
1665
1697
};
1666
1698
case ASR::binopType::Mul: {
1667
1699
if (a_kind == 4 ) {
1700
+ if (m_self_func_name_idx_map.find (" mul_c32" ) == m_self_func_name_idx_map.end ()) {
1701
+ m_self_func_name_idx_map[" mul_c32" ] = no_of_types++;
1702
+ }
1668
1703
wasm::emit_call (m_code_section, m_al, m_self_func_name_idx_map[" mul_c32" ]);
1669
1704
} else {
1705
+ if (m_self_func_name_idx_map.find (" mul_c64" ) == m_self_func_name_idx_map.end ()) {
1706
+ m_self_func_name_idx_map[" mul_c64" ] = no_of_types++;
1707
+ }
1670
1708
wasm::emit_call (m_code_section, m_al, m_self_func_name_idx_map[" mul_c64" ]);
1671
1709
}
1672
1710
break ;
@@ -2593,10 +2631,16 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
2593
2631
int arg_kind = -1 , dest_kind = -1 ;
2594
2632
extract_kinds (x, arg_kind, dest_kind);
2595
2633
if (arg_kind == 4 ) {
2634
+ if (m_self_func_name_idx_map.find (" abs_c32" ) == m_self_func_name_idx_map.end ()) {
2635
+ m_self_func_name_idx_map[" abs_c32" ] = no_of_types++;
2636
+ }
2596
2637
wasm::emit_call (m_code_section, m_al, m_self_func_name_idx_map[" abs_c32" ]);
2597
2638
wasm::emit_f32_const (m_code_section, m_al, 0.0 );
2598
2639
wasm::emit_f32_gt (m_code_section, m_al);
2599
2640
} else if (arg_kind == 8 ) {
2641
+ if (m_self_func_name_idx_map.find (" abs_c64" ) == m_self_func_name_idx_map.end ()) {
2642
+ m_self_func_name_idx_map[" abs_c64" ] = no_of_types++;
2643
+ }
2600
2644
wasm::emit_call (m_code_section, m_al, m_self_func_name_idx_map[" abs_c64" ]);
2601
2645
wasm::emit_f64_const (m_code_section, m_al, 0.0 );
2602
2646
wasm::emit_f64_gt (m_code_section, m_al);
@@ -2737,6 +2781,9 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
2737
2781
int a_kind = ASRUtils::extract_kind_from_ttype_t (t);
2738
2782
2739
2783
if (ASRUtils::is_integer (*t) || ASRUtils::is_logical (*t)) {
2784
+ if (m_self_func_name_idx_map.find (" print_i64" ) == m_self_func_name_idx_map.end ()) {
2785
+ m_self_func_name_idx_map[" print_i64" ] = no_of_types++;
2786
+ }
2740
2787
this ->visit_expr (*x.m_values [i]);
2741
2788
switch (a_kind) {
2742
2789
case 4 : {
@@ -2755,6 +2802,12 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
2755
2802
}
2756
2803
}
2757
2804
} else if (ASRUtils::is_real (*t)) {
2805
+ if (m_self_func_name_idx_map.find (" print_i64" ) == m_self_func_name_idx_map.end ()) {
2806
+ m_self_func_name_idx_map[" print_i64" ] = no_of_types++;
2807
+ }
2808
+ if (m_self_func_name_idx_map.find (" print_f64" ) == m_self_func_name_idx_map.end ()) {
2809
+ m_self_func_name_idx_map[" print_f64" ] = no_of_types++;
2810
+ }
2758
2811
this ->visit_expr (*x.m_values [i]);
2759
2812
switch (a_kind) {
2760
2813
case 4 : {
@@ -2786,6 +2839,12 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
2786
2839
->index );
2787
2840
wasm::emit_drop (m_code_section, m_al);
2788
2841
} else if (t->type == ASR::ttypeType::Complex) {
2842
+ if (m_self_func_name_idx_map.find (" print_i64" ) == m_self_func_name_idx_map.end ()) {
2843
+ m_self_func_name_idx_map[" print_i64" ] = no_of_types++;
2844
+ }
2845
+ if (m_self_func_name_idx_map.find (" print_f64" ) == m_self_func_name_idx_map.end ()) {
2846
+ m_self_func_name_idx_map[" print_f64" ] = no_of_types++;
2847
+ }
2789
2848
emit_call_fd_write (1 , " (" , 1 , 0 );
2790
2849
this ->visit_expr (*x.m_values [i]);
2791
2850
if (a_kind == 4 ) {
0 commit comments