Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 24b943a

Browse files
committed
WASM: Support emitting functions based on requirement
1 parent 6d47c5a commit 24b943a

File tree

1 file changed

+107
-48
lines changed

1 file changed

+107
-48
lines changed

src/libasr/codegen/asr_to_wasm.cpp

Lines changed: 107 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
7373
uint32_t nesting_level;
7474
uint32_t cur_loop_nesting_level;
7575
bool is_prototype_only;
76+
ASR::Function_t* main_func;
7677

7778
Vec<uint8_t> m_type_section;
7879
Vec<uint8_t> m_import_section;
@@ -103,11 +104,14 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
103104
std::map<std::string, uint32_t> m_self_func_name_idx_map;
104105
std::map<std::string, uint32_t> m_string_to_iov_loc_map;
105106

107+
std::map<std::string,void (LCompilers::ASRToWASMVisitor::*)(int)> m_self_funcs_map;
108+
106109
public:
107110
ASRToWASMVisitor(Allocator &al, diag::Diagnostics &diagnostics)
108111
: m_al(al), diag(diagnostics) {
109112
intrinsic_module = false;
110113
is_prototype_only = false;
114+
main_func = nullptr;
111115
nesting_level = 0;
112116
cur_loop_nesting_level = 0;
113117
no_of_types = 0;
@@ -323,9 +327,14 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
323327
std::vector<wasm::type> results,
324328
std::vector<wasm::type> locals,
325329
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+
}
327337

328-
uint32_t func_idx = no_of_types;
329338
{ // type declaration
330339
wasm::emit_b8(m_type_section, m_al, 0x60);
331340
wasm::emit_u32(m_type_section, m_al, params.size()); // no of params
@@ -336,7 +345,6 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
336345
for (auto result:results) {
337346
wasm::emit_b8(m_type_section, m_al, result);
338347
}
339-
no_of_types++;
340348
}
341349

342350
/*** Reference Function Prototype ***/
@@ -360,12 +368,11 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
360368

361369
/*** Export the function ***/
362370
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;
364371
no_of_functions++;
365372
no_of_exports++;
366373
}
367374

368-
void emit_print_int() {
375+
void emit_print_int(int fn_idx = -1) {
369376
using namespace wasm;
370377
define_emit_func({i64}, {}, {i64, i64, i64, i64}, "print_i64", [&](){
371378
// locals 0 is given parameter
@@ -475,10 +482,10 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
475482
}
476483

477484
});
478-
});
485+
}, fn_idx);
479486
}
480487

481-
void emit_print_float() {
488+
void emit_print_float(int fn_idx = -1) {
482489
using namespace wasm;
483490
define_emit_func({f64}, {}, {i64, i64, i64}, "print_f64", [&](){
484491
emit_if_else([&](){
@@ -547,10 +554,10 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
547554

548555
wasm::emit_get_local(m_code_section, m_al, 3);
549556
wasm::emit_call(m_code_section, m_al, m_self_func_name_idx_map["print_i64"]);
550-
});
557+
}, fn_idx);
551558
}
552559

553-
void emit_complex_add_32() {
560+
void emit_complex_add_32(int fn_idx = -1) {
554561
using namespace wasm;
555562
define_emit_func({f32, f32, f32, f32}, {f32, f32}, {}, "add_c32", [&](){
556563
wasm::emit_get_local(m_code_section, m_al, 0);
@@ -560,10 +567,10 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
560567
wasm::emit_get_local(m_code_section, m_al, 1);
561568
wasm::emit_get_local(m_code_section, m_al, 3);
562569
wasm::emit_f32_add(m_code_section, m_al);
563-
});
570+
}, fn_idx);
564571
}
565572

566-
void emit_complex_add_64() {
573+
void emit_complex_add_64(int fn_idx = -1) {
567574
using namespace wasm;
568575
define_emit_func({f64, f64, f64, f64}, {f64, f64}, {}, "add_c64", [&](){
569576
wasm::emit_get_local(m_code_section, m_al, 0);
@@ -573,10 +580,10 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
573580
wasm::emit_get_local(m_code_section, m_al, 1);
574581
wasm::emit_get_local(m_code_section, m_al, 3);
575582
wasm::emit_f64_add(m_code_section, m_al);
576-
});
583+
}, fn_idx);
577584
}
578585

579-
void emit_complex_sub_32() {
586+
void emit_complex_sub_32(int fn_idx = -1) {
580587
using namespace wasm;
581588
define_emit_func({f32, f32, f32, f32}, {f32, f32}, {}, "sub_c32", [&](){
582589
wasm::emit_get_local(m_code_section, m_al, 0);
@@ -586,10 +593,10 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
586593
wasm::emit_get_local(m_code_section, m_al, 1);
587594
wasm::emit_get_local(m_code_section, m_al, 3);
588595
wasm::emit_f32_sub(m_code_section, m_al);
589-
});
596+
}, fn_idx);
590597
}
591598

592-
void emit_complex_sub_64() {
599+
void emit_complex_sub_64(int fn_idx = -1) {
593600
using namespace wasm;
594601
define_emit_func({f64, f64, f64, f64}, {f64, f64}, {}, "sub_c64", [&](){
595602
wasm::emit_get_local(m_code_section, m_al, 0);
@@ -599,10 +606,10 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
599606
wasm::emit_get_local(m_code_section, m_al, 1);
600607
wasm::emit_get_local(m_code_section, m_al, 3);
601608
wasm::emit_f64_sub(m_code_section, m_al);
602-
});
609+
}, fn_idx);
603610
}
604611

605-
void emit_complex_mul_32() {
612+
void emit_complex_mul_32(int fn_idx = -1) {
606613
using namespace wasm;
607614
define_emit_func({f32, f32, f32, f32}, {f32, f32}, {}, "mul_c32", [&](){
608615
wasm::emit_get_local(m_code_section, m_al, 0);
@@ -624,10 +631,10 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
624631
wasm::emit_f32_mul(m_code_section, m_al);
625632

626633
wasm::emit_f32_add(m_code_section, m_al);
627-
});
634+
}, fn_idx);
628635
}
629636

630-
void emit_complex_mul_64() {
637+
void emit_complex_mul_64(int fn_idx = -1) {
631638
using namespace wasm;
632639
define_emit_func({f64, f64, f64, f64}, {f64, f64}, {}, "mul_c64", [&](){
633640
wasm::emit_get_local(m_code_section, m_al, 0);
@@ -649,10 +656,10 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
649656
wasm::emit_f64_mul(m_code_section, m_al);
650657

651658
wasm::emit_f64_add(m_code_section, m_al);
652-
});
659+
}, fn_idx);
653660
}
654661

655-
void emit_complex_abs_32() {
662+
void emit_complex_abs_32(int fn_idx = -1) {
656663
using namespace wasm;
657664
define_emit_func({f32, f32}, {f32}, {}, "abs_c32", [&](){
658665
wasm::emit_get_local(m_code_section, m_al, 0);
@@ -665,10 +672,10 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
665672

666673
wasm::emit_f32_add(m_code_section, m_al);
667674
wasm::emit_f32_sqrt(m_code_section, m_al);
668-
});
675+
}, fn_idx);
669676
}
670677

671-
void emit_complex_abs_64() {
678+
void emit_complex_abs_64(int fn_idx = -1) {
672679
using namespace wasm;
673680
define_emit_func({f64, f64}, {f64}, {}, "abs_c64", [&](){
674681
wasm::emit_get_local(m_code_section, m_al, 0);
@@ -681,7 +688,7 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
681688

682689
wasm::emit_f64_add(m_code_section, m_al);
683690
wasm::emit_f64_sqrt(m_code_section, m_al);
684-
});
691+
}, fn_idx);
685692
}
686693

687694
template <typename T>
@@ -732,16 +739,17 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
732739
for (int i = 0; i < 10; i++) {
733740
emit_string(std::to_string(i));
734741
}
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;
745753

746754
{
747755
// Pre-declare all functions first, then generate code
@@ -756,9 +764,7 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
756764
x.m_global_scope->get_scope().end());
757765
ASR::symbol_t *mod = x.m_global_scope->get_symbol(item);
758766
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);
762768
}
763769
}
764770

@@ -768,9 +774,7 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
768774
// then the main program:
769775
for (auto &item : x.m_global_scope->get_scope()) {
770776
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);
774778
}
775779
}
776780
}
@@ -811,6 +815,21 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
811815
visit_symbol(*item.second);
812816
}
813817
}
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+
}
814833
}
815834

816835
void declare_all_functions(const SymbolTable &symtab) {
@@ -840,14 +859,15 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
840859
declare_all_functions(*x.m_symtab);
841860

842861
// 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);
851871
}
852872

853873
void emit_var_type(Vec<uint8_t> &code, ASR::Variable_t *v) {
@@ -1649,24 +1669,42 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
16491669
switch (x.m_op) {
16501670
case ASR::binopType::Add: {
16511671
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+
}
16521675
wasm::emit_call(m_code_section, m_al, m_self_func_name_idx_map["add_c32"]);
16531676
} 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+
}
16541680
wasm::emit_call(m_code_section, m_al, m_self_func_name_idx_map["add_c64"]);
16551681
}
16561682
break;
16571683
};
16581684
case ASR::binopType::Sub: {
16591685
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+
}
16601689
wasm::emit_call(m_code_section, m_al, m_self_func_name_idx_map["sub_c32"]);
16611690
} 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+
}
16621694
wasm::emit_call(m_code_section, m_al, m_self_func_name_idx_map["sub_c64"]);
16631695
}
16641696
break;
16651697
};
16661698
case ASR::binopType::Mul: {
16671699
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+
}
16681703
wasm::emit_call(m_code_section, m_al, m_self_func_name_idx_map["mul_c32"]);
16691704
} 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+
}
16701708
wasm::emit_call(m_code_section, m_al, m_self_func_name_idx_map["mul_c64"]);
16711709
}
16721710
break;
@@ -2593,10 +2631,16 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
25932631
int arg_kind = -1, dest_kind = -1;
25942632
extract_kinds(x, arg_kind, dest_kind);
25952633
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+
}
25962637
wasm::emit_call(m_code_section, m_al, m_self_func_name_idx_map["abs_c32"]);
25972638
wasm::emit_f32_const(m_code_section, m_al, 0.0);
25982639
wasm::emit_f32_gt(m_code_section, m_al);
25992640
} 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+
}
26002644
wasm::emit_call(m_code_section, m_al, m_self_func_name_idx_map["abs_c64"]);
26012645
wasm::emit_f64_const(m_code_section, m_al, 0.0);
26022646
wasm::emit_f64_gt(m_code_section, m_al);
@@ -2737,6 +2781,9 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
27372781
int a_kind = ASRUtils::extract_kind_from_ttype_t(t);
27382782

27392783
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+
}
27402787
this->visit_expr(*x.m_values[i]);
27412788
switch (a_kind) {
27422789
case 4: {
@@ -2755,6 +2802,12 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
27552802
}
27562803
}
27572804
} 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+
}
27582811
this->visit_expr(*x.m_values[i]);
27592812
switch (a_kind) {
27602813
case 4: {
@@ -2786,6 +2839,12 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
27862839
->index);
27872840
wasm::emit_drop(m_code_section, m_al);
27882841
} 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+
}
27892848
emit_call_fd_write(1, "(", 1, 0);
27902849
this->visit_expr(*x.m_values[i]);
27912850
if (a_kind == 4) {

0 commit comments

Comments
 (0)