From 2bcb9922cedaa24bc0e7e0af79c97cc574692d63 Mon Sep 17 00:00:00 2001 From: Shaikh Ubaid Date: Fri, 7 Apr 2023 16:12:20 +0530 Subject: [PATCH] WASM: Move type and mem_align to wasm_utils Rename type to var_type Also define and use vt2s() and k2s() --- src/libasr/codegen/asr_to_wasm.cpp | 22 ++++++------- src/libasr/codegen/wasm_assembler.h | 18 ++++------- src/libasr/codegen/wasm_decoder.h | 9 ------ src/libasr/codegen/wasm_to_wat.cpp | 19 ++++++----- src/libasr/codegen/wasm_to_x64.cpp | 12 +++---- src/libasr/codegen/wasm_to_x86.cpp | 8 ++--- src/libasr/codegen/wasm_utils.h | 50 +++++++++++++++++++++++++++++ 7 files changed, 87 insertions(+), 51 deletions(-) diff --git a/src/libasr/codegen/asr_to_wasm.cpp b/src/libasr/codegen/asr_to_wasm.cpp index 881df0cfedd..890880bdb78 100644 --- a/src/libasr/codegen/asr_to_wasm.cpp +++ b/src/libasr/codegen/asr_to_wasm.cpp @@ -108,7 +108,7 @@ class ASRToWASMVisitor : public ASR::BaseVisitor { bool is_local_vars_only; ASR::Function_t* main_func; wasm::WASMAssembler wa; - std::vector local_vars; + std::vector local_vars; uint32_t avail_mem_loc; uint32_t digits_mem_loc; @@ -144,8 +144,8 @@ class ASRToWASMVisitor : public ASR::BaseVisitor { } void import_function(IMPORT_FUNC fn, - std::vector param_types, - std::vector result_types) { + std::vector param_types, + std::vector result_types) { int func_idx = wa.emit_func_type(param_types, result_types); m_import_func_idx_map[fn] = func_idx; wa.emit_import_fn( "wasi_snapshot_preview1", import_fn_to_str(fn), func_idx); @@ -616,11 +616,11 @@ class ASRToWASMVisitor : public ASR::BaseVisitor { wa.emit_declare_mem(min_no_pages, max_no_pages); wa.emit_export_mem("memory", 0 /* mem_idx */); - m_compiler_globals[cur_mem_loc] = wa.declare_global_var(wasm::type::i32, 0); - m_compiler_globals[tmp_reg_i32] = wa.declare_global_var(wasm::type::i32, 0); - m_compiler_globals[tmp_reg_i64] = wa.declare_global_var(wasm::type::i64, 0); - m_compiler_globals[tmp_reg_f32] = wa.declare_global_var(wasm::type::f32, 0); - m_compiler_globals[tmp_reg_f64] = wa.declare_global_var(wasm::type::f64, 0); + m_compiler_globals[cur_mem_loc] = wa.declare_global_var(wasm::var_type::i32, 0); + m_compiler_globals[tmp_reg_i32] = wa.declare_global_var(wasm::var_type::i32, 0); + m_compiler_globals[tmp_reg_i64] = wa.declare_global_var(wasm::var_type::i64, 0); + m_compiler_globals[tmp_reg_f32] = wa.declare_global_var(wasm::var_type::f32, 0); + m_compiler_globals[tmp_reg_f64] = wa.declare_global_var(wasm::var_type::f64, 0); emit_string(" "); emit_string("\n"); @@ -717,7 +717,7 @@ class ASRToWASMVisitor : public ASR::BaseVisitor { this->visit_Function(*main_func); } - void get_var_type(ASR::Variable_t *v, std::vector &type_vec) { + void get_var_type(ASR::Variable_t *v, std::vector &type_vec) { using namespace wasm; bool is_array = ASRUtils::is_array(v->m_type); @@ -934,7 +934,7 @@ class ASRToWASMVisitor : public ASR::BaseVisitor { void emit_function_prototype(const ASR::Function_t &x) { SymbolFuncInfo *s = new SymbolFuncInfo; - std::vector params, results; + std::vector params, results; s->referenced_vars.reserve(m_al, x.n_args); for (size_t i = 0; i < x.n_args; i++) { @@ -961,7 +961,7 @@ class ASRToWASMVisitor : public ASR::BaseVisitor { } } - s->index = wa.emit_func_type(params, results);; + s->index = wa.emit_func_type(params, results); m_func_name_idx_map[get_hash((ASR::asr_t *)&x)] = s; } diff --git a/src/libasr/codegen/wasm_assembler.h b/src/libasr/codegen/wasm_assembler.h index 660f467a41d..4d39b95fde4 100644 --- a/src/libasr/codegen/wasm_assembler.h +++ b/src/libasr/codegen/wasm_assembler.h @@ -7,10 +7,6 @@ namespace LCompilers { namespace wasm { -enum type { i32 = 0x7F, i64 = 0x7E, f32 = 0x7D, f64 = 0x7C}; - -enum mem_align { b8 = 0, b16 = 1, b32 = 2, b64 = 3 }; - void emit_expr_end(Vec &code, Allocator &al) { code.push_back(al, 0x0B); } @@ -213,7 +209,7 @@ class WASMAssembler: public WASM_INSTS_VISITOR::WASMInstsAssembler ¶ms, std::vector &results) { + uint32_t emit_func_type(std::vector ¶ms, std::vector &results) { wasm::emit_b8(m_type_section, m_al, 0x60); wasm::emit_u32(m_type_section, m_al, params.size()); @@ -299,7 +295,7 @@ class WASMAssembler: public WASM_INSTS_VISITOR::WASMInstsAssembler &locals, std::function func_body) { + void emit_func_body(uint32_t func_idx, std::string func_name, std::vector &locals, std::function func_body) { /*** Reference Function Prototype ***/ wasm::emit_u32(m_func_section, m_al, func_idx); @@ -327,9 +323,9 @@ class WASMAssembler: public WASM_INSTS_VISITOR::WASMInstsAssembler params, - std::vector results, - std::vector locals, + std::vector params, + std::vector results, + std::vector locals, std::string func_name, std::function func_body) { @@ -338,7 +334,7 @@ class WASMAssembler: public WASM_INSTS_VISITOR::WASMInstsAssembler - uint32_t declare_global_var(wasm::type var_type, T init_val) { + uint32_t declare_global_var(wasm::var_type var_type, T init_val) { m_global_section.push_back(m_al, var_type); m_global_section.push_back(m_al, true /* mutable */); switch (var_type) @@ -367,7 +363,7 @@ class WASMAssembler: public WASM_INSTS_VISITOR::WASMInstsAssembler locals) { + uint32_t emit_local_vars(std::vector locals) { uint32_t no_of_locals = 0; for (auto v:locals) { emit_u32(m_code_section, m_al, 1); diff --git a/src/libasr/codegen/wasm_decoder.h b/src/libasr/codegen/wasm_decoder.h index d2a7fdebef8..c42405ad16f 100644 --- a/src/libasr/codegen/wasm_decoder.h +++ b/src/libasr/codegen/wasm_decoder.h @@ -4,8 +4,6 @@ #include #include -#include -#include #include // #define WAT_DEBUG @@ -48,9 +46,6 @@ class WASMDecoder { Struct &self() { return static_cast(*this); } public: - std::unordered_map var_type_to_string; - std::unordered_map kind_to_string; - Allocator &al; diag::Diagnostics &diag; Vec wasm_bytes; @@ -67,10 +62,6 @@ class WASMDecoder { WASMDecoder(Allocator &al, diag::Diagnostics &diagonostics) : al(al), diag(diagonostics) { - var_type_to_string = { - {0x7F, "i32"}, {0x7E, "i64"}, {0x7D, "f32"}, {0x7C, "f64"}}; - kind_to_string = { - {0x00, "func"}, {0x01, "table"}, {0x02, "memory"}, {0x03, "global"}}; PREAMBLE_SIZE = 8 /* BYTES */; // wasm_bytes.reserve(al, 1024 * 128); diff --git a/src/libasr/codegen/wasm_to_wat.cpp b/src/libasr/codegen/wasm_to_wat.cpp index 25bff32dfbe..2ca0e7f2d91 100644 --- a/src/libasr/codegen/wasm_to_wat.cpp +++ b/src/libasr/codegen/wasm_to_wat.cpp @@ -313,13 +313,12 @@ class WATVisitor : public WASMDecoder, result += indent + "(type (;" + std::to_string(i) + ";) (func (param"; for (uint32_t j = 0; j < func_types[i].param_types.size(); j++) { - result += - " " + var_type_to_string[func_types[i].param_types.p[j]]; + result += " " + vt2s(func_types[i].param_types.p[j]); } result += ") (result"; for (uint32_t j = 0; j < func_types[i].result_types.size(); j++) { result += - " " + var_type_to_string[func_types[i].result_types.p[j]]; + " " + vt2s(func_types[i].result_types.p[j]); } result += ")))"; } @@ -350,8 +349,8 @@ class WATVisitor : public WASMDecoder, decode_instructions(); global_initialization_insts = this->src; } - std::string global_type = ((globals[i].mut == 0x00) ? var_type_to_string[globals[i].type]: - "(mut " + var_type_to_string[globals[i].type] + ")" ); + std::string global_type = ((globals[i].mut == 0x00) ? vt2s(globals[i].type): + "(mut " + vt2s(globals[i].type) + ")" ); result += indent + "(global $" + std::to_string(i); result += " " + global_type; result += " (" + global_initialization_insts + "))"; @@ -365,20 +364,20 @@ class WATVisitor : public WASMDecoder, j++) { result += " " + - var_type_to_string[func_types[func_index].param_types.p[j]]; + vt2s(func_types[func_index].param_types.p[j]); } result += ") (result"; for (uint32_t j = 0; j < func_types[func_index].result_types.size(); j++) { - result += " " + var_type_to_string[func_types[func_index] - .result_types.p[j]]; + result += " " + vt2s(func_types[func_index] + .result_types.p[j]); } result += ")"; result += indent + " (local"; for (uint32_t j = 0; j < codes.p[i].locals.size(); j++) { for (uint32_t k = 0; k < codes.p[i].locals.p[j].count; k++) { result += - " " + var_type_to_string[codes.p[i].locals.p[j].type]; + " " + vt2s(codes.p[i].locals.p[j].type); } } result += ")"; @@ -403,7 +402,7 @@ class WATVisitor : public WASMDecoder, for (uint32_t i = 0; i < exports.size(); i++) { result += indent + "(export \"" + exports.p[i].name + "\" (" + - kind_to_string[exports.p[i].kind] + " " + + k2s(exports.p[i].kind) + " " + std::to_string(exports.p[i].index) + "))"; } diff --git a/src/libasr/codegen/wasm_to_x64.cpp b/src/libasr/codegen/wasm_to_x64.cpp index 6cd85a5e322..169d21823e0 100644 --- a/src/libasr/codegen/wasm_to_x64.cpp +++ b/src/libasr/codegen/wasm_to_x64.cpp @@ -212,7 +212,7 @@ class X64Visitor : public WASMDecoder, void visit_GlobalGet(uint32_t globalidx) { std::string loc = "global_" + std::to_string(globalidx); - std::string var_type = var_type_to_string[globals[globalidx].type]; + std::string var_type = vt2s(globals[globalidx].type); X64Reg base = X64Reg::rbx; m_a.asm_mov_r64_label(X64Reg::rbx, loc); @@ -235,7 +235,7 @@ class X64Visitor : public WASMDecoder, } std::string loc = "global_" + std::to_string(globalidx); - std::string var_type = var_type_to_string[globals[globalidx].type]; + std::string var_type = vt2s(globals[globalidx].type); X64Reg base = X64Reg::rbx; m_a.asm_mov_r64_label(X64Reg::rbx, loc); @@ -257,7 +257,7 @@ class X64Visitor : public WASMDecoder, auto cur_func_param_type = func_types[type_indices[cur_func_idx]]; int no_of_params = (int)cur_func_param_type.param_types.size(); if ((int)localidx < no_of_params) { - std::string var_type = var_type_to_string[cur_func_param_type.param_types[localidx]]; + std::string var_type = vt2s(cur_func_param_type.param_types[localidx]); if (var_type == "i32" || var_type == "i64") { m_a.asm_mov_r64_m64(X64Reg::rax, &base, nullptr, 1, 8 * (2 + no_of_params - (int)localidx - 1)); m_a.asm_push_r64(X64Reg::rax); @@ -271,7 +271,7 @@ class X64Visitor : public WASMDecoder, } } else { localidx -= no_of_params; - std::string var_type = var_type_to_string[codes[cur_func_idx].locals[localidx].type]; + std::string var_type = vt2s(codes[cur_func_idx].locals[localidx].type); if (var_type == "i32" || var_type == "i64") { m_a.asm_mov_r64_m64(X64Reg::rax, &base, nullptr, 1, -8 * (1 + (int)localidx)); m_a.asm_push_r64(X64Reg::rax); @@ -291,7 +291,7 @@ class X64Visitor : public WASMDecoder, auto cur_func_param_type = func_types[type_indices[cur_func_idx]]; int no_of_params = (int)cur_func_param_type.param_types.size(); if ((int)localidx < no_of_params) { - std::string var_type = var_type_to_string[cur_func_param_type.param_types[localidx]]; + std::string var_type = vt2s(cur_func_param_type.param_types[localidx]); if (var_type == "i32" || var_type == "i64") { m_a.asm_pop_r64(X64Reg::rax); m_a.asm_mov_m64_r64(&base, nullptr, 1, 8 * (2 + no_of_params - (int)localidx - 1), X64Reg::rax); @@ -305,7 +305,7 @@ class X64Visitor : public WASMDecoder, } } else { localidx -= no_of_params; - std::string var_type = var_type_to_string[codes[cur_func_idx].locals[localidx].type]; + std::string var_type = vt2s(codes[cur_func_idx].locals[localidx].type); if (var_type == "i32" || var_type == "i64") { m_a.asm_pop_r64(X64Reg::rax); m_a.asm_mov_m64_r64(&base, nullptr, 1, -8 * (1 + (int)localidx), X64Reg::rax); diff --git a/src/libasr/codegen/wasm_to_x86.cpp b/src/libasr/codegen/wasm_to_x86.cpp index 1c51cef3e3b..2099491e115 100644 --- a/src/libasr/codegen/wasm_to_x86.cpp +++ b/src/libasr/codegen/wasm_to_x86.cpp @@ -209,7 +209,7 @@ class X86Visitor : public WASMDecoder, auto cur_func_param_type = func_types[type_indices[cur_func_idx]]; int no_of_params = (int)cur_func_param_type.param_types.size(); if ((int)localidx < no_of_params) { - std::string var_type = var_type_to_string[cur_func_param_type.param_types[localidx]]; + std::string var_type = vt2s(cur_func_param_type.param_types[localidx]); if (var_type == "i32") { m_a.asm_mov_r32_m32(X86Reg::eax, &base, nullptr, 1, 4 * (2 + no_of_params - (int)localidx - 1)); m_a.asm_push_r32(X86Reg::eax); @@ -227,7 +227,7 @@ class X86Visitor : public WASMDecoder, } else { localidx -= no_of_params; - std::string var_type = var_type_to_string[codes[cur_func_idx].locals[localidx].type]; + std::string var_type = vt2s(codes[cur_func_idx].locals[localidx].type); if (var_type == "i32") { m_a.asm_mov_r32_m32(X86Reg::eax, &base, nullptr, 1, -4 * (1 + localidx)); m_a.asm_push_r32(X86Reg::eax); @@ -249,7 +249,7 @@ class X86Visitor : public WASMDecoder, auto cur_func_param_type = func_types[type_indices[cur_func_idx]]; int no_of_params = (int)cur_func_param_type.param_types.size(); if ((int)localidx < no_of_params) { - std::string var_type = var_type_to_string[cur_func_param_type.param_types[localidx]]; + std::string var_type = vt2s(cur_func_param_type.param_types[localidx]); if (var_type == "i32") { m_a.asm_pop_r32(X86Reg::eax); m_a.asm_mov_m32_r32(&base, nullptr, 1, 4 * (2 + no_of_params - (int)localidx - 1), X86Reg::eax); @@ -267,7 +267,7 @@ class X86Visitor : public WASMDecoder, } else { localidx -= no_of_params; - std::string var_type = var_type_to_string[codes[cur_func_idx].locals[localidx].type]; + std::string var_type = vt2s(codes[cur_func_idx].locals[localidx].type); if (var_type == "i32") { m_a.asm_pop_r32(X86Reg::eax); m_a.asm_mov_m32_r32(&base, nullptr, 1, -4 * (1 + (int)localidx), X86Reg::eax); diff --git a/src/libasr/codegen/wasm_utils.h b/src/libasr/codegen/wasm_utils.h index d82f8fd42f2..77458402993 100644 --- a/src/libasr/codegen/wasm_utils.h +++ b/src/libasr/codegen/wasm_utils.h @@ -11,6 +11,56 @@ namespace LCompilers { namespace wasm { +enum var_type: uint8_t { + i32 = 0x7F, + i64 = 0x7E, + f32 = 0x7D, + f64 = 0x7C +}; + +enum mem_align : uint8_t { + b8 = 0, + b16 = 1, + b32 = 2, + b64 = 3 +}; + +enum wasm_kind: uint8_t { + func = 0x00, + table = 0x01, + memory = 0x02, + global = 0x03 +}; + +template +std::string vt2s(T vt) { + switch(vt) { + case var_type::i32: return "i32"; + case var_type::i64: return "i64"; + case var_type::f32: return "f32"; + case var_type::f64: return "f64"; + default: + std::cerr << "Unsupported wasm var_type" << std::endl; + LCOMPILERS_ASSERT(false); + return ""; + + } +} + +template +std::string k2s(T k) { + switch(k) { + case wasm_kind::func: return "func"; + case wasm_kind::table: return "table"; + case wasm_kind::memory: return "memory"; + case wasm_kind::global: return "global"; + default: + std::cerr << "Unsupported wasm kind" << std::endl; + LCOMPILERS_ASSERT(false); + return ""; + } +} + struct FuncType { Vec param_types; Vec result_types;