Skip to content

Commit bc09e3f

Browse files
authored
Merge pull request #1548 from Shaikh-Ubaid/wasm_block_call
WASM: Initial support for BlockCall
2 parents cbdf2e5 + 21c3e0e commit bc09e3f

File tree

1 file changed

+56
-26
lines changed

1 file changed

+56
-26
lines changed

src/libasr/codegen/asr_to_wasm.cpp

Lines changed: 56 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
101101
uint32_t nesting_level;
102102
uint32_t cur_loop_nesting_level;
103103
bool is_prototype_only;
104+
bool is_local_vars_only;
104105
ASR::Function_t* main_func;
105106

106107
Vec<uint8_t> m_type_section;
@@ -138,6 +139,7 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
138139
ASRToWASMVisitor(Allocator &al, diag::Diagnostics &diagnostics)
139140
: m_al(al), diag(diagnostics) {
140141
is_prototype_only = false;
142+
is_local_vars_only = false;
141143
main_func = nullptr;
142144
nesting_level = 0;
143145
cur_loop_nesting_level = 0;
@@ -897,42 +899,30 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
897899
}
898900
}
899901

900-
template <typename T>
901-
void emit_local_vars(const T &x,
902-
int var_idx /* starting index for local vars */) {
903-
/********************* Local Vars Types List *********************/
904-
uint32_t len_idx_code_section_local_vars_list =
905-
wasm::emit_len_placeholder(m_code_section, m_al);
906-
int local_vars_cnt = 0;
907-
for (auto &item : x.m_symtab->get_scope()) {
902+
void emit_local_vars(SymbolTable* symtab) {
903+
for (auto &item : symtab->get_scope()) {
908904
if (ASR::is_a<ASR::Variable_t>(*item.second)) {
909905
ASR::Variable_t *v =
910906
ASR::down_cast<ASR::Variable_t>(item.second);
911907
if (v->m_intent == ASRUtils::intent_local ||
912908
v->m_intent == ASRUtils::intent_return_var) {
913-
wasm::emit_u32(m_code_section, m_al,
914-
1U); // count of local vars of this type
915-
emit_var_type(m_code_section,
916-
v); // emit the type of this var
917-
m_var_name_idx_map[get_hash((ASR::asr_t *)v)] = var_idx++;
918-
local_vars_cnt++;
909+
wasm::emit_u32(m_code_section, m_al, 1U); // count of local vars of this type
910+
emit_var_type(m_code_section, v); // emit the type of this var
911+
m_var_name_idx_map[get_hash((ASR::asr_t *)v)] = cur_sym_info->no_of_variables++;
919912
if (!ASRUtils::is_array(v->m_type) && ASRUtils::is_complex(*v->m_type)) {
920913
// emit type again for imaginary part
921914
wasm::emit_u32(m_code_section, m_al, 1U); // count of local vars of this type
922915
emit_var_type(m_code_section, v); // emit the type of this var
923-
var_idx++;
924-
local_vars_cnt++;
916+
cur_sym_info->no_of_variables++;
925917
}
926918
}
927919
}
928920
}
929-
// fixup length of local vars list
930-
wasm::emit_u32_b32_idx(m_code_section, m_al,
931-
len_idx_code_section_local_vars_list,
932-
local_vars_cnt);
921+
}
933922

923+
void initialize_local_vars(SymbolTable* symtab) {
934924
// initialize the value for local variables if initialization exists
935-
for (auto &item : x.m_symtab->get_scope()) {
925+
for (auto &item : symtab->get_scope()) {
936926
if (ASR::is_a<ASR::Variable_t>(*item.second)) {
937927
ASR::Variable_t *v =
938928
ASR::down_cast<ASR::Variable_t>(item.second);
@@ -978,7 +968,6 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
978968
}
979969
}
980970
}
981-
982971
void emit_function_prototype(const ASR::Function_t &x) {
983972
SymbolFuncInfo *s = new SymbolFuncInfo;
984973

@@ -1044,6 +1033,15 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
10441033
s; // add function to map
10451034
}
10461035

1036+
template <typename T>
1037+
void visit_BlockStatements(const T& x) {
1038+
for (size_t i = 0; i < x.n_body; i++) {
1039+
if (ASR::is_a<ASR::BlockCall_t>(*x.m_body[i])) {
1040+
this->visit_stmt(*x.m_body[i]);
1041+
}
1042+
}
1043+
}
1044+
10471045
void emit_function_body(const ASR::Function_t &x) {
10481046
LCOMPILERS_ASSERT(m_func_name_idx_map.find(get_hash((ASR::asr_t *)&x)) !=
10491047
m_func_name_idx_map.end());
@@ -1058,17 +1056,35 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
10581056
uint32_t len_idx_code_section_func_size =
10591057
wasm::emit_len_placeholder(m_code_section, m_al);
10601058

1061-
emit_local_vars(x, cur_sym_info->no_of_variables);
1059+
{
1060+
is_local_vars_only = true;
1061+
int params_cnt = cur_sym_info->no_of_variables;
1062+
/********************* Local Vars Types List *********************/
1063+
uint32_t len_idx_code_section_local_vars_list =
1064+
wasm::emit_len_placeholder(m_code_section, m_al);
1065+
1066+
emit_local_vars(x.m_symtab);
1067+
visit_BlockStatements(x);
1068+
1069+
// fixup length of local vars list
1070+
wasm::emit_u32_b32_idx(m_code_section, m_al,
1071+
len_idx_code_section_local_vars_list,
1072+
cur_sym_info->no_of_variables - params_cnt);
1073+
is_local_vars_only = false;
1074+
}
1075+
1076+
initialize_local_vars(x.m_symtab);
1077+
10621078
for (size_t i = 0; i < x.n_body; i++) {
10631079
this->visit_stmt(*x.m_body[i]);
10641080
}
1081+
10651082
if (strcmp(x.m_name, "_start") == 0) {
10661083
wasm::emit_i32_const(m_code_section, m_al, 0 /* zero exit code */);
10671084
wasm::emit_call(m_code_section, m_al, m_import_func_idx_map[proc_exit]);
10681085
}
1069-
if ((x.n_body == 0) ||
1070-
((x.n_body > 0) &&
1071-
!ASR::is_a<ASR::Return_t>(*x.m_body[x.n_body - 1]))) {
1086+
1087+
if (x.n_body == 0 || !ASR::is_a<ASR::Return_t>(*x.m_body[x.n_body - 1])) {
10721088
handle_return();
10731089
}
10741090
wasm::emit_expr_end(m_code_section, m_al);
@@ -1126,6 +1142,20 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
11261142
emit_function_body(x);
11271143
}
11281144

1145+
void visit_BlockCall(const ASR::BlockCall_t &x) {
1146+
LCOMPILERS_ASSERT(ASR::is_a<ASR::Block_t>(*x.m_m));
1147+
ASR::Block_t* block = ASR::down_cast<ASR::Block_t>(x.m_m);
1148+
if (is_local_vars_only) {
1149+
emit_local_vars(block->m_symtab);
1150+
visit_BlockStatements(*block);
1151+
} else {
1152+
initialize_local_vars(block->m_symtab);
1153+
for (size_t i = 0; i < block->n_body; i++) {
1154+
this->visit_stmt(*block->m_body[i]);
1155+
}
1156+
}
1157+
}
1158+
11291159
uint32_t emit_memory_store(ASR::expr_t *v) {
11301160
auto ttype = ASRUtils::expr_type(v);
11311161
auto kind = ASRUtils::extract_kind_from_ttype_t(ttype);

0 commit comments

Comments
 (0)