added bulk-memory intrinsics; bug fix
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Wed, 3 Feb 2021 21:20:52 +0000 (15:20 -0600)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Wed, 3 Feb 2021 21:20:52 +0000 (15:20 -0600)
12 files changed:
bin/onyx
core/intrinsics/wasm.onyx
core/memory.onyx
include/onyxastnodes.h
include/onyxwasm.h
onyx.exe
src/onyxbuiltins.c
src/onyxparser.c
src/onyxutils.c
src/onyxwasm.c
tests/aoc-2020/day19.onyx
tests/aoc-2020/day20.onyx

index d7b1484a24c599b37f944fd5a7b36a16f96078f7..732de5b6931f0c46f1d209ec4e61261294e19acf 100755 (executable)
Binary files a/bin/onyx and b/bin/onyx differ
index db95e792c8465b1499fd99594cbc4aa098562e84..0d2d115d6e701a76d137db36d919555ac7f39479 100644 (file)
@@ -2,6 +2,8 @@ package core.intrinsics.wasm
 
 memory_size  :: () -> i32 #intrinsic ---
 memory_grow  :: (val: i32) -> i32 #intrinsic ---
+memory_copy  :: (dst: rawptr, src: rawptr, count: i32) -> void #intrinsic ---
+memory_fill  :: (dst: rawptr, byte: u8, count: i32) -> void #intrinsic ---
 
 clz_i32      :: (val: i32) -> i32 #intrinsic ---
 ctz_i32      :: (val: i32) -> i32 #intrinsic ---
index 838acb585feec9dc4fe5a7fe7f3dc62874e179db..ed6e2d9488b7554f4b41f497776adb865809d63b 100644 (file)
@@ -8,14 +8,26 @@ package core.memory
 // However, it might be worth switching to an intrinsic completely
 // and having the intrinsic know whether or not to output the instruction
 // or an inlined version of this procedure.
-copy :: (dst_: rawptr, src_: rawptr, len: u32) {
+use package core.intrinsics.wasm { memory_copy, memory_fill }
+
+// Even though I thought this would work, this method of aliases functions
+// does not currently work. There needs to be a second level of indirection
+// on entities to allow for this case to work, which may not be hard to change
+// but still needs to happen.
+// copy :: memory_copy
+// set  :: memory_fill
+
+copy :: (dest: rawptr, src: rawptr, count: i32) do memory_copy(dest, src, count);
+set  :: (dest: rawptr, byte: u8, count: i32)    do memory_fill(dest, byte, count);
+
+// Old and slow copy and set
+copy_ :: (dst_: rawptr, src_: rawptr, len: u32) {
     dst := cast(^u8) dst_;
     src := cast(^u8) src_;
     for i: 0 .. len do dst[i] = src[i];
 }
 
-// The same thing goes for this procedure too.
-set :: (start: rawptr, length: u32, value: u8) {
+set_ :: (start: rawptr, value: u8, length: u32) {
     s := cast(^u8) start;
     for i: 0 .. length do s[i] = value;
 }
index 7ca3b8f158c226c090471aa5b74195afb3f49296..32fec4ec06bd4e14bacd5fea08b4e78f4e2ccc78 100644 (file)
@@ -276,6 +276,7 @@ typedef enum OnyxIntrinsic {
     ONYX_INTRINSIC_UNDEFINED,
 
     ONYX_INTRINSIC_MEMORY_SIZE, ONYX_INTRINSIC_MEMORY_GROW,
+    ONYX_INTRINSIC_MEMORY_COPY, ONYX_INTRINSIC_MEMORY_FILL,
 
     ONYX_INTRINSIC_I32_CLZ,   ONYX_INTRINSIC_I32_CTZ, ONYX_INTRINSIC_I32_POPCNT,
     ONYX_INTRINSIC_I32_AND,   ONYX_INTRINSIC_I32_OR,  ONYX_INTRINSIC_I32_XOR,
index 3d966549a19902584d30a4476dbc988f3a37463f..2bd9816bdfaf8a979ae1a888f9dec121738b412b 100644 (file)
@@ -17,6 +17,7 @@ typedef struct WasmFuncType {
 } WasmFuncType;
 
 #define SIMD_INSTR_MASK 0x10000
+#define EXT_INSTR_MASK  0x20000
 
 typedef enum WasmInstructionType {
     WI_UNREACHABLE                   = 0x00,
@@ -410,6 +411,10 @@ typedef enum WasmInstructionType {
     WI_I32X4_TRUNC_SAT_F32X4_U       = SIMD_INSTR_MASK | 249,
     WI_F32X4_CONVERT_I32X4_S         = SIMD_INSTR_MASK | 250,
     WI_F32X4_CONVERT_I32X4_U         = SIMD_INSTR_MASK | 251,
+    
+    
+    WI_MEMORY_COPY                   = EXT_INSTR_MASK | 0x0a,
+    WI_MEMORY_FILL                   = EXT_INSTR_MASK | 0x0b,
 } WasmInstructionType;
 
 typedef union {
index 1506e5e5613a039d8212ca73cd302de78252e67a..1c6e84522261ca419a1856de24b869b03fffc947 100644 (file)
Binary files a/onyx.exe and b/onyx.exe differ
index a978e86c6da80016b3bd26ba0777fafdde333580..4ce2a2565000cf07202df732aec7cff60347a401 100644 (file)
@@ -84,6 +84,8 @@ bh_table(OnyxIntrinsic) intrinsic_table;
 static IntrinsicMap builtin_intrinsics[] = {
     { "memory_size",  ONYX_INTRINSIC_MEMORY_SIZE },
     { "memory_grow",  ONYX_INTRINSIC_MEMORY_GROW },
+    { "memory_copy",  ONYX_INTRINSIC_MEMORY_COPY },
+    { "memory_fill",  ONYX_INTRINSIC_MEMORY_FILL },
 
     { "clz_i32",      ONYX_INTRINSIC_I32_CLZ },
     { "ctz_i32",      ONYX_INTRINSIC_I32_CTZ },
index 7e834a3d446c1e0fee69ff6b69002bbd8c94a231..fe7a86a07bfa77bed41fcb98f2c24b2a11d37d10 100644 (file)
@@ -618,7 +618,7 @@ static AstTyped* parse_factor(OnyxParser* parser) {
 
             case Token_Type_Right_Arrow: {
                 AstBinaryOp* method_call = make_node(AstBinaryOp, Ast_Kind_Method_Call);
-                method_call->token = expect_token(parser, Token_Type_Right_Arrow);  
+                method_call->token = expect_token(parser, Token_Type_Right_Arrow);
                 method_call->left = retval;
                 method_call->right = parse_factor(parser);
 
@@ -829,7 +829,7 @@ static AstIfWhile* parse_if_stmt(OnyxParser* parser) {
     AstIfWhile* root_if = if_node;
 
     // CLEANUP: All of the control blocks use this same kind of logic, and it
-    // is underpowered for what I think should be possible. Factor it out and 
+    // is underpowered for what I think should be possible. Factor it out and
     // make it better?
     if (peek_token(1)->type == ':') {
         OnyxToken* local_sym = expect_token(parser, Token_Type_Symbol);
@@ -1265,7 +1265,7 @@ static AstNode* parse_statement(OnyxParser* parser) {
             retval = parse_jump_stmt(parser, Token_Type_Keyword_Break, Jump_Type_Break);
             break;
 
-        case Token_Type_Keyword_Continue: 
+        case Token_Type_Keyword_Continue:
             retval = parse_jump_stmt(parser, Token_Type_Keyword_Continue, Jump_Type_Continue);
             break;
 
@@ -1640,7 +1640,7 @@ static AstStructType* parse_struct(OnyxParser* parser) {
             bh_arr_push(poly_params, ((AstPolyStructParam) {
                 .token = sym_token,
                 .type_node = param_type,
-                .type = NULL, 
+                .type = NULL,
             }));
 
             if (parser->curr->type != ')')
@@ -1742,7 +1742,7 @@ static AstStructType* parse_struct(OnyxParser* parser) {
             }
 
             bh_arr_each(OnyxToken *, member_name, member_list_temp) {
-                AstStructMember* mem = make_node(AstStructMember, Ast_Kind_Struct_Member);    
+                AstStructMember* mem = make_node(AstStructMember, Ast_Kind_Struct_Member);
                 mem->token = *member_name;
                 mem->type_node = member_type;
                 mem->initial_value = initial_value;
@@ -1833,7 +1833,7 @@ static void parse_function_params(OnyxParser* parser, AstFunction* func) {
             curr_param.default_value = parse_expression(parser, 0);
 
         if (param_is_baked) {
-            param_is_baked = 0;    
+            param_is_baked = 0;
 
             bh_arr(AstPolyParam) pv = *parser->polymorph_context.poly_params;
             bh_arr_push(pv, ((AstPolyParam) {
@@ -2171,7 +2171,7 @@ static AstBinding* parse_top_level_binding(OnyxParser* parser, OnyxToken* symbol
         // HACK: This should maybe be entered elsewhere?
         ENTITY_SUBMIT(node);
     }
-
+    
     AstBinding* binding = make_node(AstBinding, Ast_Kind_Binding);
     binding->token = symbol;
     binding->node = (AstNode *) node;
index f09493214e4276ac84f9e4482fd84feccf2033ec..b04cf5d359f55df38a008d4b4034fd9da0fb77d4 100644 (file)
@@ -123,10 +123,6 @@ AstNode* symbol_raw_resolve(Scope* start_scope, char* sym) {
 
     if (res == NULL) return NULL;
 
-    if (res->kind == Ast_Kind_Symbol) {
-        return symbol_resolve(start_scope, res->token);
-    }
-
     return res;
 }
 
index a0d90f42978c8e9903465e6bb97d7ebbc17700a1..18e384a9c228dc01677e67c4b5c144e6eb8c5538 100644 (file)
@@ -1398,6 +1398,8 @@ EMIT_FUNC(intrinsic_call, AstCall* call) {
     switch (call->intrinsic) {
         case ONYX_INTRINSIC_MEMORY_SIZE:  WID(WI_MEMORY_SIZE, 0x00); break;
         case ONYX_INTRINSIC_MEMORY_GROW:  WID(WI_MEMORY_GROW, 0x00); break;
+        case ONYX_INTRINSIC_MEMORY_COPY:  WIL(WI_MEMORY_COPY, 0x00); break;
+        case ONYX_INTRINSIC_MEMORY_FILL:  WID(WI_MEMORY_FILL, 0x00); break;
 
         case ONYX_INTRINSIC_I32_CLZ:      WI(WI_I32_CLZ); break;
         case ONYX_INTRINSIC_I32_CTZ:      WI(WI_I32_CTZ); break;
@@ -3502,6 +3504,11 @@ static void output_instruction(WasmFunc* func, WasmInstruction* instr, bh_buffer
         bh_buffer_write_byte(buff, 0xFD);
         leb = uint_to_uleb128((u64) (instr->type &~ SIMD_INSTR_MASK), &leb_len);
         bh_buffer_append(buff, leb, leb_len);
+        
+    } else if (instr->type & EXT_INSTR_MASK) {
+        bh_buffer_write_byte(buff, 0xFC);
+        leb = uint_to_uleb128((u64) (instr->type &~ EXT_INSTR_MASK), &leb_len);
+        bh_buffer_append(buff, leb, leb_len);
 
     } else {
         bh_buffer_write_byte(buff, (u8) instr->type);
@@ -3527,9 +3534,18 @@ static void output_instruction(WasmFunc* func, WasmInstruction* instr, bh_buffer
         case WI_IF_START:
         case WI_MEMORY_SIZE:
         case WI_MEMORY_GROW:
+        case WI_MEMORY_FILL:
             leb = uint_to_uleb128((u64) instr->data.i1, &leb_len);
             bh_buffer_append(buff, leb, leb_len);
             break;
+        
+        case WI_MEMORY_COPY:
+            leb = uint_to_uleb128((u64) instr->data.i1, &leb_len);
+            bh_buffer_append(buff, leb, leb_len);
+        
+            leb = uint_to_uleb128((u64) instr->data.i2, &leb_len);
+            bh_buffer_append(buff, leb, leb_len);
+            break;
 
         case WI_JUMP_TABLE: {
             BranchTable* bt = (BranchTable *) instr->data.p;
index d503098b3ec66902a46fb0f54a103b964247c0f5..2dd97c4e8a22cb58574feb49d49edf14e8a609cd 100644 (file)
@@ -84,7 +84,7 @@ cyk_algorithm :: proc (use grammar: ^Grammar, input: str) -> bool {
     mem_size := sizeof bool * input.count * input.count * max_terminal;
     T := cast(^bool) calloc(mem_size);
     defer cfree(T);
-    memory.set(T, mem_size, ~~false);
+    memory.set(T, ~~false, mem_size);
 
     for s: 0 .. input.count {
         for ^term: terminate_rules {
index b4fca178bd9c3ad7c407e0b05150f8b897b3f5c4..a7fe3278eb995389b045dcb9b6f0adc34e739f55 100644 (file)
@@ -327,7 +327,7 @@ main :: proc (args: [] cstr) {
        printf("Corner product: %l\n", prod);
 
     grid : [12 * 12] u32;
-    memory.set(^grid, sizeof [12 * 12] u32, 0);
+    memory.set(^grid, 0, sizeof [12 * 12] u32);
 
     to_process : [..] tile_pos_state;
     array.init(^to_process);