From: Brendan Hansen Date: Mon, 27 Jul 2020 21:37:39 +0000 (-0500) Subject: Added procedure declarations at the expression level; properly using elems now X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=a3e4d1f0eaa896297ee319a45d3f6fcd0d5b9fef;p=onyx.git Added procedure declarations at the expression level; properly using elems now --- diff --git a/include/onyxwasm.h b/include/onyxwasm.h index 72a5493e..c8e4831e 100644 --- a/include/onyxwasm.h +++ b/include/onyxwasm.h @@ -295,6 +295,9 @@ typedef struct OnyxWasmModule { // NOTE: Mapping from local ast node ptrs to indicies bh_imap local_map; + // NOTE: Mapping ptrs to elements + bh_imap elem_map; + // NOTE: Used internally as a map from strings that represent function types, // 0x7f 0x7f : 0x7f ( (i32, i32) -> i32 ) // to the function type index if it has been created. @@ -308,15 +311,16 @@ typedef struct OnyxWasmModule { bh_arr(WasmGlobal) globals; bh_arr(WasmFunc) funcs; bh_arr(WasmDatum) data; + bh_arr(i32) elems; - u32 next_type_idx; u32 export_count; - u32 element_count; + u32 next_type_idx; u32 next_func_idx; u32 next_foreign_func_idx; u32 next_global_idx; u32 next_foreign_global_idx; u32 next_datum_offset; + u32 next_elem_idx; } OnyxWasmModule; OnyxWasmModule onyx_wasm_module_create(bh_allocator alloc); diff --git a/onyx b/onyx index 5691a378..48659236 100755 Binary files a/onyx and b/onyx differ diff --git a/progs/ez.onyx b/progs/ez.onyx index e4f056cb..061cf102 100644 --- a/progs/ez.onyx +++ b/progs/ez.onyx @@ -14,7 +14,7 @@ Foo :: struct { } foo_sum :: proc (use this: ^Foo) -> i32 { - this.foo_other(); + foo_other(this); return x + y; } @@ -62,7 +62,7 @@ proc #export "main" { foo.st = st; print(alignof Foo); print(sizeof Foo); - print(foo.foo_sum()); + print(foo_sum(foo)); print_st(foo.st, 20); pa := (__heap_start as i32 + sizeof Foo) as ^PrintableArray; diff --git a/progs/fcf.onyx b/progs/fcf.onyx index f043423f..f8eea8f8 100644 --- a/progs/fcf.onyx +++ b/progs/fcf.onyx @@ -30,6 +30,18 @@ echo :: proc (i: i32) -> i32 { return i; } +I32Array :: struct { + length : i32; + data : ^i32; +} + +array_map :: proc (arr: I32Array, map: proc (i32) -> i32) { + for i: 0, arr.length arr.data[i] = map(arr.data[i]); +} + +minus_one :: proc (n: i32) -> i32 { return n - 1; } +double :: proc (n: i32) -> i32 { return n << 1; } + proc #export "main" { call_me(echo, 10); @@ -48,4 +60,14 @@ proc #export "main" { dc.right = 19; print(execute(dc)); + + len :: 10; + data := (__heap_start as i32 + sizeof DeferredCall) as ^i32; + for i: 0, len data[i] = i; + print(data as [] i32, len); + + add_one :: proc (n: i32) -> i32 { return n + 1; }; + + array_map(len, data, add_one); + print(data as [] i32, len); } diff --git a/src/onyxparser.c b/src/onyxparser.c index 7555e237..6ea6d391 100644 --- a/src/onyxparser.c +++ b/src/onyxparser.c @@ -255,6 +255,16 @@ static AstTyped* parse_factor(OnyxParser* parser) { break; } + case Token_Type_Keyword_Proc: { + retval = (AstTyped *) parse_function_definition(parser); + retval->flags |= Ast_Flag_Function_Used; + + // TODO: Maybe move this somewhere else? + add_node_to_process(parser, (AstNode *) retval); + + break; + } + default: onyx_message_add(Msg_Type_Unexpected_Token, parser->curr->pos, diff --git a/src/onyxwasm.c b/src/onyxwasm.c index 56afd045..687e27b6 100644 --- a/src/onyxwasm.c +++ b/src/onyxwasm.c @@ -240,6 +240,7 @@ static WasmType onyx_type_to_wasm_type(Type* type) { } static i32 generate_type_idx(OnyxWasmModule* mod, Type* ft); +static i32 get_element_idx(OnyxWasmModule* mod, AstFunction* func); #define WI(instr) bh_arr_push(code, ((WasmInstruction){ instr, 0x00 })) #define WID(instr, data) bh_arr_push(code, ((WasmInstruction){ instr, data })) @@ -915,8 +916,8 @@ COMPILE_FUNC(expression, AstTyped* expr) { } case Ast_Kind_Function: { - i32 funcidx = bh_imap_get(&mod->index_map, (u64) expr); - WID(WI_I32_CONST, funcidx); + i32 elemidx = get_element_idx(mod, (AstFunction *) expr); + WID(WI_I32_CONST, elemidx); break; } @@ -1192,6 +1193,22 @@ static i32 generate_type_idx(OnyxWasmModule* mod, Type* ft) { return type_idx; } +static i32 get_element_idx(OnyxWasmModule* mod, AstFunction* func) { + if (bh_imap_has(&mod->elem_map, (u64) func)) { + return bh_imap_get(&mod->elem_map, (u64) func); + } else { + i32 idx = mod->next_elem_idx; + bh_imap_put(&mod->elem_map, (u64) func, idx); + + i32 func_idx = bh_imap_get(&mod->index_map, (u64) func); + bh_arr_push(mod->elems, func_idx); + + mod->next_elem_idx++; + + return idx; + } +} + static inline b32 should_compile_function(AstFunction* fd) { // NOTE: Don't output intrinsic functions if (fd->flags & Ast_Flag_Intrinsic) return 0; @@ -1431,7 +1448,8 @@ OnyxWasmModule onyx_wasm_module_create(bh_allocator alloc) { .data = NULL, .next_datum_offset = 0, - .element_count = 0, + .elems = NULL, + .next_elem_idx = 0, .structured_jump_target = NULL, }; @@ -1441,6 +1459,7 @@ OnyxWasmModule onyx_wasm_module_create(bh_allocator alloc) { bh_arr_new(alloc, module.imports, 4); bh_arr_new(alloc, module.globals, 4); bh_arr_new(alloc, module.data, 4); + bh_arr_new(alloc, module.elems, 4); // NOTE: 16 is probably needlessly large bh_arr_new(global_heap_allocator, module.structured_jump_target, 16); @@ -1451,6 +1470,7 @@ OnyxWasmModule onyx_wasm_module_create(bh_allocator alloc) { bh_imap_init(&module.index_map, global_heap_allocator, 128); bh_imap_init(&module.local_map, global_heap_allocator, 16); + bh_imap_init(&module.elem_map, global_heap_allocator, 16); return module; } @@ -1470,7 +1490,6 @@ void onyx_wasm_module_compile(OnyxWasmModule* module, ProgramInfo* program) { switch (entity->type) { case Entity_Type_Function_Header: { if (!should_compile_function(entity->function)) break; - module->element_count++; u64 func_idx; if ((entity->function->flags & Ast_Flag_Foreign) != 0) @@ -1670,6 +1689,8 @@ static i32 output_funcsection(OnyxWasmModule* module, bh_buffer* buff) { } static i32 output_tablesection(OnyxWasmModule* module, bh_buffer* buff) { + if (bh_arr_length(module->elems) == 0) return 0; + i32 prev_len = buff->length; bh_buffer_write_byte(buff, WASM_SECTION_ID_TABLE); @@ -1682,7 +1703,7 @@ static i32 output_tablesection(OnyxWasmModule* module, bh_buffer* buff) { // NOTE: funcrefs are the only valid table element type bh_buffer_write_byte(&vec_buff, 0x70); - output_limits(module->element_count, -1, &vec_buff); + output_limits(bh_arr_length(module->elems), -1, &vec_buff); leb = uint_to_uleb128((u64) (vec_buff.length), &leb_len); bh_buffer_append(buff, leb, leb_len); @@ -1839,6 +1860,8 @@ static i32 output_startsection(OnyxWasmModule* module, bh_buffer* buff) { } static i32 output_elemsection(OnyxWasmModule* module, bh_buffer* buff) { + if (bh_arr_length(module->elems) == 0) return 0; + i32 prev_len = buff->length; bh_buffer_write_byte(buff, WASM_SECTION_ID_ELEMENT); @@ -1846,8 +1869,6 @@ static i32 output_elemsection(OnyxWasmModule* module, bh_buffer* buff) { bh_buffer vec_buff; bh_buffer_init(&vec_buff, buff->allocator, 128); - u32 func_count = bh_arr_length(module->funcs) + module->next_foreign_func_idx; - i32 leb_len; u8* leb; @@ -1861,11 +1882,11 @@ static i32 output_elemsection(OnyxWasmModule* module, bh_buffer* buff) { bh_buffer_write_byte(&vec_buff, 0x00); bh_buffer_write_byte(&vec_buff, WI_BLOCK_END); - leb = uint_to_uleb128((u64) func_count, &leb_len); + leb = uint_to_uleb128((u64) bh_arr_length(module->elems), &leb_len); bh_buffer_append(&vec_buff, leb, leb_len); - fori (funcidx, 0, func_count - 1) { - leb = uint_to_uleb128((u64) funcidx, &leb_len); + bh_arr_each(i32, elem, module->elems) { + leb = uint_to_uleb128((u64) *elem, &leb_len); bh_buffer_append(&vec_buff, leb, leb_len); }