@@ -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 ;
@@ -357,9 +361,14 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
357
361
std::vector<wasm::type> results,
358
362
std::vector<wasm::type> locals,
359
363
std::string func_name,
360
- std::function<void ()> func_body) {
364
+ std::function<void ()> func_body,
365
+ int func_idx = -1
366
+ ) {
367
+
368
+ if (func_idx == -1 ) {
369
+ func_idx = no_of_types++;
370
+ }
361
371
362
- uint32_t func_idx = no_of_types;
363
372
{ // type declaration
364
373
wasm::emit_b8 (m_type_section, m_al, 0x60 );
365
374
wasm::emit_u32 (m_type_section, m_al, params.size ()); // no of params
@@ -370,7 +379,6 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
370
379
for (auto result:results) {
371
380
wasm::emit_b8 (m_type_section, m_al, result);
372
381
}
373
- no_of_types++;
374
382
}
375
383
376
384
/* ** Reference Function Prototype ***/
@@ -394,12 +402,11 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
394
402
395
403
/* ** Export the function ***/
396
404
wasm::emit_export_fn (m_export_section, m_al, func_name, func_idx); // add function to export
397
- m_self_func_name_idx_map[func_name] = func_idx;
398
405
no_of_functions++;
399
406
no_of_exports++;
400
407
}
401
408
402
- void emit_print_int () {
409
+ void emit_print_int (int fn_idx = - 1 ) {
403
410
using namespace wasm ;
404
411
define_emit_func ({i64 }, {}, {i64 , i64 , i64 , i64 }, " print_i64" , [&](){
405
412
// locals 0 is given parameter
@@ -509,10 +516,10 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
509
516
}
510
517
511
518
});
512
- });
519
+ }, fn_idx );
513
520
}
514
521
515
- void emit_print_float () {
522
+ void emit_print_float (int fn_idx = - 1 ) {
516
523
using namespace wasm ;
517
524
define_emit_func ({f64 }, {}, {i64 , i64 , i64 }, " print_f64" , [&](){
518
525
emit_if_else ([&](){
@@ -581,10 +588,10 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
581
588
582
589
wasm::emit_get_local (m_code_section, m_al, 3 );
583
590
wasm::emit_call (m_code_section, m_al, m_self_func_name_idx_map[" print_i64" ]);
584
- });
591
+ }, fn_idx );
585
592
}
586
593
587
- void emit_complex_add_32 () {
594
+ void emit_complex_add_32 (int fn_idx = - 1 ) {
588
595
using namespace wasm ;
589
596
define_emit_func ({f32 , f32 , f32 , f32 }, {f32 , f32 }, {}, " add_c32" , [&](){
590
597
wasm::emit_get_local (m_code_section, m_al, 0 );
@@ -594,10 +601,10 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
594
601
wasm::emit_get_local (m_code_section, m_al, 1 );
595
602
wasm::emit_get_local (m_code_section, m_al, 3 );
596
603
wasm::emit_f32_add (m_code_section, m_al);
597
- });
604
+ }, fn_idx );
598
605
}
599
606
600
- void emit_complex_add_64 () {
607
+ void emit_complex_add_64 (int fn_idx = - 1 ) {
601
608
using namespace wasm ;
602
609
define_emit_func ({f64 , f64 , f64 , f64 }, {f64 , f64 }, {}, " add_c64" , [&](){
603
610
wasm::emit_get_local (m_code_section, m_al, 0 );
@@ -607,10 +614,10 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
607
614
wasm::emit_get_local (m_code_section, m_al, 1 );
608
615
wasm::emit_get_local (m_code_section, m_al, 3 );
609
616
wasm::emit_f64_add (m_code_section, m_al);
610
- });
617
+ }, fn_idx );
611
618
}
612
619
613
- void emit_complex_sub_32 () {
620
+ void emit_complex_sub_32 (int fn_idx = - 1 ) {
614
621
using namespace wasm ;
615
622
define_emit_func ({f32 , f32 , f32 , f32 }, {f32 , f32 }, {}, " sub_c32" , [&](){
616
623
wasm::emit_get_local (m_code_section, m_al, 0 );
@@ -620,10 +627,10 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
620
627
wasm::emit_get_local (m_code_section, m_al, 1 );
621
628
wasm::emit_get_local (m_code_section, m_al, 3 );
622
629
wasm::emit_f32_sub (m_code_section, m_al);
623
- });
630
+ }, fn_idx );
624
631
}
625
632
626
- void emit_complex_sub_64 () {
633
+ void emit_complex_sub_64 (int fn_idx = - 1 ) {
627
634
using namespace wasm ;
628
635
define_emit_func ({f64 , f64 , f64 , f64 }, {f64 , f64 }, {}, " sub_c64" , [&](){
629
636
wasm::emit_get_local (m_code_section, m_al, 0 );
@@ -633,10 +640,10 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
633
640
wasm::emit_get_local (m_code_section, m_al, 1 );
634
641
wasm::emit_get_local (m_code_section, m_al, 3 );
635
642
wasm::emit_f64_sub (m_code_section, m_al);
636
- });
643
+ }, fn_idx );
637
644
}
638
645
639
- void emit_complex_mul_32 () {
646
+ void emit_complex_mul_32 (int fn_idx = - 1 ) {
640
647
using namespace wasm ;
641
648
define_emit_func ({f32 , f32 , f32 , f32 }, {f32 , f32 }, {}, " mul_c32" , [&](){
642
649
wasm::emit_get_local (m_code_section, m_al, 0 );
@@ -658,10 +665,10 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
658
665
wasm::emit_f32_mul (m_code_section, m_al);
659
666
660
667
wasm::emit_f32_add (m_code_section, m_al);
661
- });
668
+ }, fn_idx );
662
669
}
663
670
664
- void emit_complex_mul_64 () {
671
+ void emit_complex_mul_64 (int fn_idx = - 1 ) {
665
672
using namespace wasm ;
666
673
define_emit_func ({f64 , f64 , f64 , f64 }, {f64 , f64 }, {}, " mul_c64" , [&](){
667
674
wasm::emit_get_local (m_code_section, m_al, 0 );
@@ -683,10 +690,10 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
683
690
wasm::emit_f64_mul (m_code_section, m_al);
684
691
685
692
wasm::emit_f64_add (m_code_section, m_al);
686
- });
693
+ }, fn_idx );
687
694
}
688
695
689
- void emit_complex_abs_32 () {
696
+ void emit_complex_abs_32 (int fn_idx = - 1 ) {
690
697
using namespace wasm ;
691
698
define_emit_func ({f32 , f32 }, {f32 }, {}, " abs_c32" , [&](){
692
699
wasm::emit_get_local (m_code_section, m_al, 0 );
@@ -699,10 +706,10 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
699
706
700
707
wasm::emit_f32_add (m_code_section, m_al);
701
708
wasm::emit_f32_sqrt (m_code_section, m_al);
702
- });
709
+ }, fn_idx );
703
710
}
704
711
705
- void emit_complex_abs_64 () {
712
+ void emit_complex_abs_64 (int fn_idx = - 1 ) {
706
713
using namespace wasm ;
707
714
define_emit_func ({f64 , f64 }, {f64 }, {}, " abs_c64" , [&](){
708
715
wasm::emit_get_local (m_code_section, m_al, 0 );
@@ -715,7 +722,7 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
715
722
716
723
wasm::emit_f64_add (m_code_section, m_al);
717
724
wasm::emit_f64_sqrt (m_code_section, m_al);
718
- });
725
+ }, fn_idx );
719
726
}
720
727
721
728
template <typename T>
@@ -766,16 +773,17 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
766
773
for (int i = 0 ; i < 10 ; i++) {
767
774
emit_string (std::to_string (i));
768
775
}
769
- emit_print_int ();
770
- emit_print_float ();
771
- emit_complex_add_32 ();
772
- emit_complex_add_64 ();
773
- emit_complex_sub_32 ();
774
- emit_complex_sub_64 ();
775
- emit_complex_mul_32 ();
776
- emit_complex_mul_64 ();
777
- emit_complex_abs_32 ();
778
- emit_complex_abs_64 ();
776
+
777
+ m_self_funcs_map[" print_i64" ] = &ASRToWASMVisitor::emit_print_int;
778
+ m_self_funcs_map[" print_f64" ] = &ASRToWASMVisitor::emit_print_float;
779
+ m_self_funcs_map[" add_c32" ] = &ASRToWASMVisitor::emit_complex_add_32;
780
+ m_self_funcs_map[" add_c64" ] = &ASRToWASMVisitor::emit_complex_add_64;
781
+ m_self_funcs_map[" sub_c32" ] = &ASRToWASMVisitor::emit_complex_sub_32;
782
+ m_self_funcs_map[" sub_c64" ] = &ASRToWASMVisitor::emit_complex_sub_64;
783
+ m_self_funcs_map[" mul_c32" ] = &ASRToWASMVisitor::emit_complex_mul_32;
784
+ m_self_funcs_map[" mul_c64" ] = &ASRToWASMVisitor::emit_complex_mul_64;
785
+ m_self_funcs_map[" abs_c32" ] = &ASRToWASMVisitor::emit_complex_abs_32;
786
+ m_self_funcs_map[" abs_c64" ] = &ASRToWASMVisitor::emit_complex_abs_64;
779
787
780
788
{
781
789
// Pre-declare all functions first, then generate code
@@ -790,9 +798,7 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
790
798
x.m_global_scope ->get_scope ().end ());
791
799
ASR::symbol_t *mod = x.m_global_scope ->get_symbol (item);
792
800
if (ASR::is_a<ASR::Module_t>(*mod)) {
793
- ASR::Module_t *m =
794
- ASR::down_cast<ASR::Module_t>(mod);
795
- declare_all_functions (*(m->m_symtab ));
801
+ visit_symbol (*mod);
796
802
}
797
803
}
798
804
@@ -802,9 +808,7 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
802
808
// then the main program:
803
809
for (auto &item : x.m_global_scope ->get_scope ()) {
804
810
if (ASR::is_a<ASR::Program_t>(*item.second )) {
805
- ASR::Program_t *p =
806
- ASR::down_cast<ASR::Program_t>(item.second );
807
- declare_all_functions (*(p->m_symtab ));
811
+ visit_symbol (*item.second );
808
812
}
809
813
}
810
814
}
@@ -845,6 +849,21 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
845
849
visit_symbol (*item.second );
846
850
}
847
851
}
852
+
853
+ std::vector<std::pair<std::string, uint32_t >> ordered_self_funcs_name_idx;
854
+ for (auto self_func:m_self_func_name_idx_map) {
855
+ ordered_self_funcs_name_idx.push_back (self_func);
856
+ }
857
+
858
+ sort (ordered_self_funcs_name_idx.begin (),
859
+ ordered_self_funcs_name_idx.end (),
860
+ [](std::pair<std::string, uint32_t > &a, std::pair<std::string, uint32_t > &b){
861
+ return a.second < b.second ;
862
+ });
863
+
864
+ for (auto self_func:ordered_self_funcs_name_idx) {
865
+ (this ->*m_self_funcs_map[self_func.first ])(self_func.second );
866
+ }
848
867
}
849
868
850
869
void declare_all_functions (const SymbolTable &symtab) {
@@ -876,14 +895,15 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
876
895
declare_all_functions (*x.m_symtab );
877
896
878
897
// Generate main program code
879
- auto main_func = ASRUtils::make_Function_t_util (
880
- m_al, x.base .base .loc , x.m_symtab , s2c (m_al, " _start" ),
881
- nullptr , 0 , nullptr , 0 , x.m_body , x.n_body , nullptr ,
882
- ASR::abiType::Source, ASR::accessType::Public,
883
- ASR::deftypeType::Implementation, nullptr , false , false , false , false , false ,
884
- nullptr , 0 , nullptr , 0 , false , false , false );
885
- emit_function_prototype (*((ASR::Function_t *)main_func));
886
- emit_function_body (*((ASR::Function_t *)main_func));
898
+ if (main_func == nullptr ) {
899
+ main_func = (ASR::Function_t *)ASRUtils::make_Function_t_util (
900
+ m_al, x.base .base .loc , x.m_symtab , s2c (m_al, " _start" ),
901
+ nullptr , 0 , nullptr , 0 , x.m_body , x.n_body , nullptr ,
902
+ ASR::abiType::Source, ASR::accessType::Public,
903
+ ASR::deftypeType::Implementation, nullptr , false , false , false , false , false ,
904
+ nullptr , 0 , nullptr , 0 , false , false , false );
905
+ }
906
+ this ->visit_Function (*main_func);
887
907
}
888
908
889
909
void emit_var_type (Vec<uint8_t > &code, ASR::Variable_t *v) {
@@ -1685,24 +1705,42 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
1685
1705
switch (x.m_op ) {
1686
1706
case ASR::binopType::Add: {
1687
1707
if (a_kind == 4 ) {
1708
+ if (m_self_func_name_idx_map.find (" add_c32" ) == m_self_func_name_idx_map.end ()) {
1709
+ m_self_func_name_idx_map[" add_c32" ] = no_of_types++;
1710
+ }
1688
1711
wasm::emit_call (m_code_section, m_al, m_self_func_name_idx_map[" add_c32" ]);
1689
1712
} else {
1713
+ if (m_self_func_name_idx_map.find (" add_c64" ) == m_self_func_name_idx_map.end ()) {
1714
+ m_self_func_name_idx_map[" add_c64" ] = no_of_types++;
1715
+ }
1690
1716
wasm::emit_call (m_code_section, m_al, m_self_func_name_idx_map[" add_c64" ]);
1691
1717
}
1692
1718
break ;
1693
1719
};
1694
1720
case ASR::binopType::Sub: {
1695
1721
if (a_kind == 4 ) {
1722
+ if (m_self_func_name_idx_map.find (" sub_c32" ) == m_self_func_name_idx_map.end ()) {
1723
+ m_self_func_name_idx_map[" sub_c32" ] = no_of_types++;
1724
+ }
1696
1725
wasm::emit_call (m_code_section, m_al, m_self_func_name_idx_map[" sub_c32" ]);
1697
1726
} else {
1727
+ if (m_self_func_name_idx_map.find (" sub_c64" ) == m_self_func_name_idx_map.end ()) {
1728
+ m_self_func_name_idx_map[" sub_c64" ] = no_of_types++;
1729
+ }
1698
1730
wasm::emit_call (m_code_section, m_al, m_self_func_name_idx_map[" sub_c64" ]);
1699
1731
}
1700
1732
break ;
1701
1733
};
1702
1734
case ASR::binopType::Mul: {
1703
1735
if (a_kind == 4 ) {
1736
+ if (m_self_func_name_idx_map.find (" mul_c32" ) == m_self_func_name_idx_map.end ()) {
1737
+ m_self_func_name_idx_map[" mul_c32" ] = no_of_types++;
1738
+ }
1704
1739
wasm::emit_call (m_code_section, m_al, m_self_func_name_idx_map[" mul_c32" ]);
1705
1740
} else {
1741
+ if (m_self_func_name_idx_map.find (" mul_c64" ) == m_self_func_name_idx_map.end ()) {
1742
+ m_self_func_name_idx_map[" mul_c64" ] = no_of_types++;
1743
+ }
1706
1744
wasm::emit_call (m_code_section, m_al, m_self_func_name_idx_map[" mul_c64" ]);
1707
1745
}
1708
1746
break ;
@@ -2629,10 +2667,16 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
2629
2667
int arg_kind = -1 , dest_kind = -1 ;
2630
2668
extract_kinds (x, arg_kind, dest_kind);
2631
2669
if (arg_kind == 4 ) {
2670
+ if (m_self_func_name_idx_map.find (" abs_c32" ) == m_self_func_name_idx_map.end ()) {
2671
+ m_self_func_name_idx_map[" abs_c32" ] = no_of_types++;
2672
+ }
2632
2673
wasm::emit_call (m_code_section, m_al, m_self_func_name_idx_map[" abs_c32" ]);
2633
2674
wasm::emit_f32_const (m_code_section, m_al, 0.0 );
2634
2675
wasm::emit_f32_gt (m_code_section, m_al);
2635
2676
} else if (arg_kind == 8 ) {
2677
+ if (m_self_func_name_idx_map.find (" abs_c64" ) == m_self_func_name_idx_map.end ()) {
2678
+ m_self_func_name_idx_map[" abs_c64" ] = no_of_types++;
2679
+ }
2636
2680
wasm::emit_call (m_code_section, m_al, m_self_func_name_idx_map[" abs_c64" ]);
2637
2681
wasm::emit_f64_const (m_code_section, m_al, 0.0 );
2638
2682
wasm::emit_f64_gt (m_code_section, m_al);
@@ -2773,6 +2817,9 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
2773
2817
int a_kind = ASRUtils::extract_kind_from_ttype_t (t);
2774
2818
2775
2819
if (ASRUtils::is_integer (*t) || ASRUtils::is_logical (*t)) {
2820
+ if (m_self_func_name_idx_map.find (" print_i64" ) == m_self_func_name_idx_map.end ()) {
2821
+ m_self_func_name_idx_map[" print_i64" ] = no_of_types++;
2822
+ }
2776
2823
this ->visit_expr (*x.m_values [i]);
2777
2824
switch (a_kind) {
2778
2825
case 4 : {
@@ -2791,6 +2838,12 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
2791
2838
}
2792
2839
}
2793
2840
} else if (ASRUtils::is_real (*t)) {
2841
+ if (m_self_func_name_idx_map.find (" print_i64" ) == m_self_func_name_idx_map.end ()) {
2842
+ m_self_func_name_idx_map[" print_i64" ] = no_of_types++;
2843
+ }
2844
+ if (m_self_func_name_idx_map.find (" print_f64" ) == m_self_func_name_idx_map.end ()) {
2845
+ m_self_func_name_idx_map[" print_f64" ] = no_of_types++;
2846
+ }
2794
2847
this ->visit_expr (*x.m_values [i]);
2795
2848
switch (a_kind) {
2796
2849
case 4 : {
@@ -2822,6 +2875,12 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
2822
2875
->index );
2823
2876
wasm::emit_drop (m_code_section, m_al);
2824
2877
} else if (t->type == ASR::ttypeType::Complex) {
2878
+ if (m_self_func_name_idx_map.find (" print_i64" ) == m_self_func_name_idx_map.end ()) {
2879
+ m_self_func_name_idx_map[" print_i64" ] = no_of_types++;
2880
+ }
2881
+ if (m_self_func_name_idx_map.find (" print_f64" ) == m_self_func_name_idx_map.end ()) {
2882
+ m_self_func_name_idx_map[" print_f64" ] = no_of_types++;
2883
+ }
2825
2884
emit_call_fd_write (1 , " (" , 1 , 0 );
2826
2885
this ->visit_expr (*x.m_values [i]);
2827
2886
if (a_kind == 4 ) {
0 commit comments