Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 19 additions & 2 deletions src/libasr/codegen/asr_to_wasm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,13 +78,15 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
Vec<uint8_t> m_import_section;
Vec<uint8_t> m_func_section;
Vec<uint8_t> m_memory_section;
Vec<uint8_t> m_global_section;
Vec<uint8_t> m_export_section;
Vec<uint8_t> m_code_section;
Vec<uint8_t> m_data_section;

uint32_t no_of_types;
uint32_t no_of_functions;
uint32_t no_of_memories;
uint32_t no_of_globals;
uint32_t no_of_exports;
uint32_t no_of_imports;
uint32_t no_of_data_segments;
Expand All @@ -110,6 +112,7 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
avail_mem_loc = 0;
no_of_functions = 0;
no_of_memories = 0;
no_of_globals = 0;
no_of_exports = 0;
no_of_imports = 0;
no_of_data_segments = 0;
Expand All @@ -121,6 +124,7 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
m_import_section.reserve(m_al, 1024 * 128);
m_func_section.reserve(m_al, 1024 * 128);
m_memory_section.reserve(m_al, 1024 * 128);
m_global_section.reserve(m_al, 1024 * 128);
m_export_section.reserve(m_al, 1024 * 128);
m_code_section.reserve(m_al, 1024 * 128);
m_data_section.reserve(m_al, 1024 * 128);
Expand All @@ -129,10 +133,10 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
void get_wasm(Vec<uint8_t> &code) {
code.reserve(m_al, 8U /* preamble size */ +
8U /* (section id + section size) */ *
7U /* number of sections */
8U /* number of sections */
+ m_type_section.size() +
m_import_section.size() + m_func_section.size() +
m_memory_section.size() +
m_memory_section.size() + m_global_section.size() +
m_export_section.size() + m_code_section.size() +
m_data_section.size());

Expand All @@ -144,6 +148,7 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
wasm::encode_section(code, m_import_section, m_al, 2U, no_of_imports);
wasm::encode_section(code, m_func_section, m_al, 3U, no_of_functions);
wasm::encode_section(code, m_memory_section, m_al, 5U, no_of_memories);
wasm::encode_section(code, m_global_section, m_al, 6U, no_of_globals);
wasm::encode_section(code, m_export_section, m_al, 7U, no_of_exports);
wasm::encode_section(code, m_code_section, m_al, 10U, no_of_functions);
wasm::encode_section(code, m_data_section, m_al, 11U,
Expand Down Expand Up @@ -548,6 +553,16 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
no_of_exports++;
}

void declare_global_vars() {
{ // global variable to hold the available memory location
m_global_section.push_back(m_al, wasm::type::i32);
m_global_section.push_back(m_al, 0x01 /* mutable */);
wasm::emit_i32_const(m_global_section, m_al, 0);
wasm::emit_expr_end(m_global_section, m_al); // end instructions
no_of_globals++;
}
}

void visit_TranslationUnit(const ASR::TranslationUnit_t &x) {
// All loose statements must be converted to a function, so the items
// must be empty:
Expand All @@ -564,6 +579,8 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
wasm::emit_export_mem(m_export_section, m_al, "memory", 0 /* mem_idx */);
no_of_exports++;

declare_global_vars();

emit_string(" ");
emit_string("\n");
emit_string("-");
Expand Down
12 changes: 12 additions & 0 deletions src/libasr/codegen/wasm_assembler.h
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,18 @@ void emit_set_local(Vec<uint8_t> &code, Allocator &al, uint32_t idx) {
emit_u32(code, al, idx);
}

// function to emit get global variable at given index
void emit_get_global(Vec<uint8_t> &code, Allocator &al, uint32_t idx) {
code.push_back(al, 0x23);
emit_u32(code, al, idx);
}

// function to emit set global variable at given index
void emit_set_global(Vec<uint8_t> &code, Allocator &al, uint32_t idx) {
code.push_back(al, 0x24);
emit_u32(code, al, idx);
}

// function to emit call instruction
void emit_call(Vec<uint8_t> &code, Allocator &al, uint32_t idx) {
code.push_back(al, 0x10);
Expand Down
18 changes: 18 additions & 0 deletions src/libasr/codegen/wasm_decoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ class WASMDecoder {
Vec<wasm::Import> imports;
Vec<uint32_t> type_indices;
Vec<std::pair<uint32_t, uint32_t>> memories;
Vec<wasm::Global> globals;
Vec<wasm::Export> exports;
Vec<wasm::Code> codes;
Vec<wasm::Data> data_segments;
Expand Down Expand Up @@ -223,6 +224,19 @@ class WASMDecoder {
}
}

void decode_global_section(uint32_t offset) {
// read global section contents
uint32_t no_of_globals = read_u32(wasm_bytes, offset);
DEBUG("no_of_globals: " + std::to_string(no_of_globals));
globals.resize(al, no_of_globals);

for (uint32_t i = 0; i < no_of_globals; i++) {
globals.p[i].type = read_b8(wasm_bytes, offset);
globals.p[i].mut = read_b8(wasm_bytes, offset);
globals.p[i].insts_start_idx = offset;
}
}

void decode_export_section(uint32_t offset) {
// read export section contents
uint32_t no_of_exports = read_u32(wasm_bytes, offset);
Expand Down Expand Up @@ -342,6 +356,10 @@ class WASMDecoder {
decode_memory_section(index);
// exit(0);
break;
case 6U:
decode_global_section(index);
// exit(0);
break;
case 7U:
decode_export_section(index);
// exit(0);
Expand Down
20 changes: 20 additions & 0 deletions src/libasr/codegen/wasm_to_wat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,12 @@ class WATVisitor : public WASMDecoder<WATVisitor>,
void visit_LocalSet(uint32_t localidx) {
src += indent + "local.set " + std::to_string(localidx);
}
void visit_GlobalGet(uint32_t globalidx) {
src += indent + "global.get " + std::to_string(globalidx);
}
void visit_GlobalSet(uint32_t globalidx) {
src += indent + "global.set " + std::to_string(globalidx);
}
void visit_EmtpyBlockType() {}
void visit_If() {
src += indent + "if";
Expand Down Expand Up @@ -335,6 +341,20 @@ class WATVisitor : public WASMDecoder<WATVisitor>,
}
}

for (uint32_t i = 0; i < globals.size(); i++) {
std::string global_initialization_insts = "";
{
this->offset = globals.p[i].insts_start_idx;
this->indent = "";
this->src = "";
decode_instructions();
global_initialization_insts = this->src;
}
result += indent + "(global $" + std::to_string(i);
result += " " + var_type_to_string[globals[i].type];
result += " (" + global_initialization_insts + "))";
}

for (uint32_t i = 0; i < type_indices.size(); i++) {
uint32_t func_index = type_indices.p[i];
result += indent + "(func $" + std::to_string(func_index);
Expand Down
6 changes: 6 additions & 0 deletions src/libasr/codegen/wasm_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@ struct FuncType {
Vec<uint8_t> result_types;
};

struct Global {
uint8_t type;
uint8_t mut;
uint32_t insts_start_idx;
};

struct Export {
std::string name;
uint8_t kind;
Expand Down
2 changes: 1 addition & 1 deletion tests/reference/wat-bool1-234bcd1.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"outfile": null,
"outfile_hash": null,
"stdout": "wat-bool1-234bcd1.stdout",
"stdout_hash": "9d7405a88da887d95c18dc2f71c9b516f8ede0664c9e61033976e5c1",
"stdout_hash": "9509a512bd279e27e1c1a4573a344b98e984e93521cef089eb3bb334",
"stderr": null,
"stderr_hash": null,
"returncode": 0
Expand Down
1 change: 1 addition & 0 deletions tests/reference/wat-bool1-234bcd1.stdout
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
(type (;6;) (func (param) (result)))
(import "wasi_snapshot_preview1" "proc_exit" (func (;0;) (type 0)))
(import "wasi_snapshot_preview1" "fd_write" (func (;1;) (type 1)))
(global $0 i32 (i32.const 0))
(func $2 (type 2) (param i64) (result)
(local i64 i64 i64 i64)
local.get 0
Expand Down
2 changes: 1 addition & 1 deletion tests/reference/wat-expr14-5e0cb96.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"outfile": null,
"outfile_hash": null,
"stdout": "wat-expr14-5e0cb96.stdout",
"stdout_hash": "8dd0860fcf3d6380112b1f3b8011b794ffc386a86628aad179297a53",
"stdout_hash": "96f90f190be31d02b145de3fe293bc74b4a79a3a8aa4c8ebb236a4e9",
"stderr": null,
"stderr_hash": null,
"returncode": 0
Expand Down
1 change: 1 addition & 0 deletions tests/reference/wat-expr14-5e0cb96.stdout
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
(type (;5;) (func (param) (result)))
(import "wasi_snapshot_preview1" "proc_exit" (func (;0;) (type 0)))
(import "wasi_snapshot_preview1" "fd_write" (func (;1;) (type 1)))
(global $0 i32 (i32.const 0))
(func $2 (type 2) (param i64) (result)
(local i64 i64 i64 i64)
local.get 0
Expand Down
2 changes: 1 addition & 1 deletion tests/reference/wat-expr2-8b17723.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"outfile": null,
"outfile_hash": null,
"stdout": "wat-expr2-8b17723.stdout",
"stdout_hash": "b3bd5faae5f1632c099d408d9d18c58cb2cfd4f7be1dec2133ec2b1c",
"stdout_hash": "a38ec604027092a7cd322473580201a022de5e7ea948c3b63a8ab798",
"stderr": null,
"stderr_hash": null,
"returncode": 0
Expand Down
1 change: 1 addition & 0 deletions tests/reference/wat-expr2-8b17723.stdout
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
(type (;5;) (func (param) (result)))
(import "wasi_snapshot_preview1" "proc_exit" (func (;0;) (type 0)))
(import "wasi_snapshot_preview1" "fd_write" (func (;1;) (type 1)))
(global $0 i32 (i32.const 0))
(func $2 (type 2) (param i64) (result)
(local i64 i64 i64 i64)
local.get 0
Expand Down
2 changes: 1 addition & 1 deletion tests/reference/wat-expr9-f73afd1.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"outfile": null,
"outfile_hash": null,
"stdout": "wat-expr9-f73afd1.stdout",
"stdout_hash": "d1025281003011357a1e1e39c7b2eec7752f209d50805aa5a81d83fd",
"stdout_hash": "d1618163ab287b71613fd75147ae7362a7955ebc6e9f32810b21b824",
"stderr": null,
"stderr_hash": null,
"returncode": 0
Expand Down
1 change: 1 addition & 0 deletions tests/reference/wat-expr9-f73afd1.stdout
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
(type (;10;) (func (param) (result)))
(import "wasi_snapshot_preview1" "proc_exit" (func (;0;) (type 0)))
(import "wasi_snapshot_preview1" "fd_write" (func (;1;) (type 1)))
(global $0 i32 (i32.const 0))
(func $2 (type 2) (param i64) (result)
(local i64 i64 i64 i64)
local.get 0
Expand Down
2 changes: 1 addition & 1 deletion tests/reference/wat-loop1-e0046d4.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"outfile": null,
"outfile_hash": null,
"stdout": "wat-loop1-e0046d4.stdout",
"stdout_hash": "21c5d32f395a2daee2e25240b5a225f6090d2905440973edef350f44",
"stdout_hash": "07cd13d55836deabb991c7762567db212b10e869075d06a6b34476a2",
"stderr": null,
"stderr_hash": null,
"returncode": 0
Expand Down
1 change: 1 addition & 0 deletions tests/reference/wat-loop1-e0046d4.stdout
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
(type (;9;) (func (param) (result)))
(import "wasi_snapshot_preview1" "proc_exit" (func (;0;) (type 0)))
(import "wasi_snapshot_preview1" "fd_write" (func (;1;) (type 1)))
(global $0 i32 (i32.const 0))
(func $2 (type 2) (param i64) (result)
(local i64 i64 i64 i64)
local.get 0
Expand Down
2 changes: 1 addition & 1 deletion tests/reference/wat-print_str-385e953.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"outfile": null,
"outfile_hash": null,
"stdout": "wat-print_str-385e953.stdout",
"stdout_hash": "51176be242a4d758284827adeb446b6455b2e7a64f15a73daf493efb",
"stdout_hash": "5c741b7c4d2def2a49b189d20e307eba2c157d714d278fc3cc924d7f",
"stderr": null,
"stderr_hash": null,
"returncode": 0
Expand Down
1 change: 1 addition & 0 deletions tests/reference/wat-print_str-385e953.stdout
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
(type (;7;) (func (param) (result)))
(import "wasi_snapshot_preview1" "proc_exit" (func (;0;) (type 0)))
(import "wasi_snapshot_preview1" "fd_write" (func (;1;) (type 1)))
(global $0 i32 (i32.const 0))
(func $2 (type 2) (param i64) (result)
(local i64 i64 i64 i64)
local.get 0
Expand Down