Skip to content

Commit

Permalink
Merge pull request lcompilers#1520 from Shaikh-Ubaid/wasm_global_section
Browse files Browse the repository at this point in the history
WASM: Support global section
  • Loading branch information
Shaikh-Ubaid committed Feb 14, 2023
2 parents 0daef38 + 34de388 commit 813c8fb
Show file tree
Hide file tree
Showing 17 changed files with 87 additions and 8 deletions.
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

0 comments on commit 813c8fb

Please sign in to comment.