starting to implement threading on the browser
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Sat, 16 Oct 2021 21:42:40 +0000 (16:42 -0500)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Sat, 16 Oct 2021 21:42:40 +0000 (16:42 -0500)
core/intrinsics/atomics.onyx [new file with mode: 0644]
core/std.onyx
include/astnodes.h
include/wasm.h
src/builtins.c
src/wasm_intrinsics.c
src/wasm_output.c

diff --git a/core/intrinsics/atomics.onyx b/core/intrinsics/atomics.onyx
new file mode 100644 (file)
index 0000000..30a41bc
--- /dev/null
@@ -0,0 +1,26 @@
+package core.intrinsics.atomics
+
+#private_file {
+    runtime :: package Runtime
+
+    #if !#defined(runtime.Allow_Multi_Threading) {
+        #error "Multi-threading is not enabled so you cannot include the 'core.intrinsics.atomics' package."
+    }
+}
+
+// __atomic_wait is only valid for i32 and i64
+__atomic_wait   :: (addr: ^$T, value: T, timeout: i64 = 0) -> i32 #intrinsic ---
+__atomic_notify :: (addr: rawptr, maximum: i32 = 1) -> i32 #intrinsic ---
+
+__atomic_fence  :: () -> void #intrinsic ---
+
+// These are only valid for the eight integer types (i8, u8, i16, u16, i32, u32, i64, u64)
+__atomic_load    :: (addr: ^$T) -> T                       #intrinsic ---
+__atomic_store   :: (addr: ^$T, value: T) -> void          #intrinsic ---
+__atomic_add     :: (addr: ^$T, value: T) -> T             #intrinsic ---
+__atomic_sub     :: (addr: ^$T, value: T) -> T             #intrinsic ---
+__atomic_and     :: (addr: ^$T, value: T) -> T             #intrinsic ---
+__atomic_or      :: (addr: ^$T, value: T) -> T             #intrinsic ---
+__atomic_xor     :: (addr: ^$T, value: T) -> T             #intrinsic ---
+__atomic_xchg    :: (addr: ^$T, value: T) -> T             #intrinsic ---
+__atomic_cmpxchg :: (addr: ^$T, compare: T, value: T) -> T #intrinsic ---
index ba6f91a0db989df723bbc2256164705cdb169745..43602d9db2c83f1b5aad786f2133ed1ed1417c4d 100644 (file)
@@ -52,3 +52,7 @@ package core
 #if runtime.Runtime != runtime.Runtime_Custom {
     #load "./stdio"
 }
+
+#if #defined(runtime.Allow_Multi_Threading) {
+    #load "./intrinsics/atomics"
+}
\ No newline at end of file
index 20966dd9aae33c0565f9cdda2b21554c6d6aae3e..78b4b570445e08516e492f1f35d15069aa5676c1 100644 (file)
@@ -457,6 +457,21 @@ typedef enum OnyxIntrinsic {
     ONYX_INTRINSIC_I32X4_TRUNC_SAT_F32X4_U,
     ONYX_INTRINSIC_F32X4_CONVERT_I32X4_S,
     ONYX_INTRINSIC_F32X4_CONVERT_I32X4_U,
+
+    ONYX_INTRINSIC_ATOMIC_WAIT,
+    ONYX_INTRINSIC_ATOMIC_NOTIFY,
+
+    ONYX_INTRINSIC_ATOMIC_FENCE,
+
+    ONYX_INTRINSIC_ATOMIC_LOAD,
+    ONYX_INTRINSIC_ATOMIC_STORE,
+    ONYX_INTRINSIC_ATOMIC_ADD,
+    ONYX_INTRINSIC_ATOMIC_SUB,
+    ONYX_INTRINSIC_ATOMIC_AND,
+    ONYX_INTRINSIC_ATOMIC_OR,
+    ONYX_INTRINSIC_ATOMIC_XOR,
+    ONYX_INTRINSIC_ATOMIC_XCHG,
+    ONYX_INTRINSIC_ATOMIC_CMPXCHG,
 } OnyxIntrinsic;
 
 typedef enum CallingConvention {
index 7d0ddc30eb63fc2d4bb181e1d52d7a76cb4395d0..d09f7da8fefa292150d09e568c9a7f14d81e4504 100644 (file)
@@ -16,8 +16,9 @@ typedef struct WasmFuncType {
     WasmType param_types[];
 } WasmFuncType;
 
-#define SIMD_INSTR_MASK 0x10000
-#define EXT_INSTR_MASK  0x20000
+#define SIMD_INSTR_MASK   0x10000
+#define EXT_INSTR_MASK    0x20000
+#define ATOMIC_INSTR_MASK 0x40000
 
 typedef enum WasmInstructionType {
     WI_UNREACHABLE                   = 0x00,
@@ -425,6 +426,7 @@ typedef enum WasmInstructionType {
     
     WI_MEMORY_COPY                   = EXT_INSTR_MASK | 0x0a,
     WI_MEMORY_FILL                   = EXT_INSTR_MASK | 0x0b,
+
 } WasmInstructionType;
 
 typedef union {
index 511effa60c3a4c58d0e67e82d4a7761519b5e66d..f70ea09b1e729ae5da757cf5ff146524f6cb7a07 100644 (file)
@@ -332,6 +332,21 @@ static IntrinsicMap builtin_intrinsics[] = {
     { "f32x4_convert_i32x4_s",   ONYX_INTRINSIC_F32X4_CONVERT_I32X4_S },
     { "f32x4_convert_i32x4_u",   ONYX_INTRINSIC_F32X4_CONVERT_I32X4_U },
 
+    { "__atomic_wait",    ONYX_INTRINSIC_ATOMIC_WAIT    },
+    { "__atomic_notify",  ONYX_INTRINSIC_ATOMIC_NOTIFY  },
+
+    { "__atomic_fence",   ONYX_INTRINSIC_ATOMIC_FENCE   },
+
+    { "__atomic_load",    ONYX_INTRINSIC_ATOMIC_LOAD    },
+    { "__atomic_store",   ONYX_INTRINSIC_ATOMIC_STORE   },
+    { "__atomic_add",     ONYX_INTRINSIC_ATOMIC_ADD     },
+    { "__atomic_sub",     ONYX_INTRINSIC_ATOMIC_SUB     },
+    { "__atomic_and",     ONYX_INTRINSIC_ATOMIC_AND     },
+    { "__atomic_or",      ONYX_INTRINSIC_ATOMIC_OR      },
+    { "__atomic_xor",     ONYX_INTRINSIC_ATOMIC_XOR     },
+    { "__atomic_xchg",    ONYX_INTRINSIC_ATOMIC_XCHG    },
+    { "__atomic_cmpxchg", ONYX_INTRINSIC_ATOMIC_CMPXCHG },
+
     { NULL, ONYX_INTRINSIC_UNDEFINED },
 };
 
index b39fad86a4cdfcbb467300caf66ddfceb8ba4988..e61192b6f28d68737b03026143ecf343351b5833 100644 (file)
@@ -151,3 +151,39 @@ EMIT_FUNC(initialize_type, Type* type, OnyxToken* where) {
     
     *pcode = code;
 }
+
+EMIT_FUNC(intrinsic_atomic_wait, Type* type, OnyxToken* where) {
+}
+
+EMIT_FUNC(intrinsic_atomic_notify, Type* type, OnyxToken* where) {
+}
+
+EMIT_FUNC_NO_ARGS(intrinsic_atomic_fence) {
+}
+
+EMIT_FUNC(intrinsic_atomic_load, Type* type, OnyxToken* where) {
+}
+
+EMIT_FUNC(intrinsic_atomic_store, Type* type, OnyxToken* where) {
+}
+
+EMIT_FUNC(intrinsic_atomic_add, Type* type, OnyxToken* where) {
+}
+
+EMIT_FUNC(intrinsic_atomic_sub, Type* type, OnyxToken* where) {
+}
+
+EMIT_FUNC(intrinsic_atomic_and, Type* type, OnyxToken* where) {
+}
+
+EMIT_FUNC(intrinsic_atomic_or, Type* type, OnyxToken* where) {
+}
+
+EMIT_FUNC(intrinsic_atomic_xor, Type* type, OnyxToken* where) {
+}
+
+EMIT_FUNC(intrinsic_atomic_xchg, Type* type, OnyxToken* where) {
+}
+
+EMIT_FUNC(intrinsic_atomic_cmpxchg, Type* type, OnyxToken* where) {
+}
index e1c576450d53f5851314ac58fb6a4753c597befe..8ab0598dac324dbd70b4fc0f075a3f681aec2382 100644 (file)
@@ -406,6 +406,11 @@ static void output_instruction(WasmFunc* func, WasmInstruction* instr, bh_buffer
         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 if (instr->type & ATOMIC_INSTR_MASK) {
+        bh_buffer_write_byte(buff, 0xFE);
+        leb = uint_to_uleb128((u64) (instr->type &~ ATOMIC_INSTR_MASK), &leb_len);
+        bh_buffer_append(buff, leb, leb_len);
         
     } else {
         bh_buffer_write_byte(buff, (u8) instr->type);