Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP Atomics API #175

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
116 changes: 116 additions & 0 deletions src/binaryen_stubs_expressions.c
Expand Up @@ -2074,3 +2074,119 @@ caml_binaryen_tablegrow_set_delta(value _exp, value _delta) {
BinaryenTableGrowSetDelta(exp, delta);
CAMLreturn(Val_unit);
}

// Atomics

CAMLprim value
caml_binaryen_atomic_load(value _module, value _bytes, value _offset, value _ty, value _ptr, value _memoryName) {
CAMLparam5(_module, _bytes, _offset, _ty, _ptr);
CAMLxparam1(_memoryName);
BinaryenModuleRef module = BinaryenModuleRef_val(_module);
int bytes = Int_val(_bytes);
int offset = Int_val(_offset);
BinaryenType ty = BinaryenType_val(_ty);
BinaryenExpressionRef ptr = BinaryenExpressionRef_val(_ptr);
char* memoryName = Safe_String_val(_memoryName);
BinaryenExpressionRef res = BinaryenAtomicLoad(module, bytes, offset, ty, ptr, memoryName);
CAMLreturn(alloc_BinaryenExpressionRef(res));
}
CAMLprim value
caml_binaryen_atomic_load__bytecode(value * argv) {
return caml_binaryen_atomic_load(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5]);
}

CAMLprim value
caml_binaryen_atomic_store(value _module, value _bytes, value _offset, value _ptr, value _val, value _ty, value _memoryName) {
CAMLparam5(_module, _bytes, _offset, _ptr, _val);
CAMLxparam2(_ty, _memoryName);
BinaryenModuleRef module = BinaryenModuleRef_val(_module);
int bytes = Int_val(_bytes);
int offset = Int_val(_offset);
BinaryenExpressionRef ptr = BinaryenExpressionRef_val(_ptr);
BinaryenExpressionRef val = BinaryenExpressionRef_val(_val);
BinaryenType ty = BinaryenType_val(_ty);
char* memoryName = Safe_String_val(_memoryName);
BinaryenExpressionRef res = BinaryenAtomicStore(module, bytes, offset, ptr, val, ty, memoryName);
CAMLreturn(alloc_BinaryenExpressionRef(res));
}
CAMLprim value
caml_binaryen_atomic_store__bytecode(value * argv) {
return caml_binaryen_atomic_store(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6]);
}

CAMLprim value
caml_binaryen_atomic_rmw(value _module, value _op, value _bytes, value _offset, value _ptr, value _val, value _ty, value _memoryName) {
CAMLparam5(_module, _op, _bytes, _offset, _ptr);
CAMLxparam3(_val, _ty, _memoryName);
BinaryenModuleRef module = BinaryenModuleRef_val(_module);
BinaryenOp op = BinaryenOp_val(_op);
BinaryenIndex bytes = Int_val(_bytes);
BinaryenIndex offset = Int_val(_offset);
BinaryenExpressionRef ptr = BinaryenExpressionRef_val(_ptr);
BinaryenExpressionRef val = BinaryenExpressionRef_val(_val);
BinaryenType ty = BinaryenType_val(_ty);
char* memoryName = Safe_String_val(_memoryName);
BinaryenExpressionRef res = BinaryenAtomicRMW(module, op, bytes, offset, ptr, val, ty, memoryName);
CAMLreturn(alloc_BinaryenExpressionRef(res));
}
CAMLprim value
caml_binaryen_atomic_rmw__bytecode(value * argv) {
return caml_binaryen_atomic_rmw(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7]);
}

CAMLprim value
caml_binaryen_atomic_cmpxchg(value _module, value _bytes, value _offset, value _ptr, value _expected, value _replacement, value _ty, value _memoryName) {
CAMLparam5(_module, _bytes, _offset, _ptr, _expected);
CAMLxparam3(_replacement, _ty, _memoryName);
BinaryenModuleRef module = BinaryenModuleRef_val(_module);
BinaryenIndex bytes = Int_val(_bytes);
BinaryenIndex offset = Int_val(_offset);
BinaryenExpressionRef ptr = BinaryenExpressionRef_val(_ptr);
BinaryenExpressionRef expected = BinaryenExpressionRef_val(_expected);
BinaryenExpressionRef replacement = BinaryenExpressionRef_val(_replacement);
BinaryenType ty = BinaryenType_val(_ty);
char* memoryName = Safe_String_val(_memoryName);
BinaryenExpressionRef res = BinaryenAtomicCmpxchg(module, bytes, offset, ptr, expected, replacement, ty, memoryName);
CAMLreturn(alloc_BinaryenExpressionRef(res));
}
CAMLprim value
caml_binaryen_atomic_cmpxchg__bytecode(value * argv) {
return caml_binaryen_atomic_cmpxchg(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7]);
}

CAMLprim value
caml_binaryen_atomic_wait(value _module, value _ptr, value _expected, value _timeout, value _ty, value _memoryName) {
CAMLparam5(_module, _ptr, _expected, _timeout, _ty);
CAMLxparam1(_memoryName);
BinaryenModuleRef module = BinaryenModuleRef_val(_module);
BinaryenExpressionRef ptr = BinaryenExpressionRef_val(_ptr);
BinaryenExpressionRef expected = BinaryenExpressionRef_val(_expected);
BinaryenExpressionRef timeout = BinaryenExpressionRef_val(_timeout);
BinaryenType ty = BinaryenType_val(_ty);
char* memoryName = Safe_String_val(_memoryName);
BinaryenExpressionRef res = BinaryenAtomicWait(module, ptr, expected, timeout, ty, memoryName);
CAMLreturn(alloc_BinaryenExpressionRef(res));
}
CAMLprim value
caml_binaryen_atomic_wait__bytecode(value * argv) {
return caml_binaryen_atomic_wait(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5]);
}

CAMLprim value
caml_binaryen_atomic_notify(value _module, value _ptr, value _notifyCount, value _memoryName) {
CAMLparam4(_module, _ptr, _notifyCount, _memoryName);
BinaryenModuleRef module = BinaryenModuleRef_val(_module);
BinaryenExpressionRef ptr = BinaryenExpressionRef_val(_ptr);
BinaryenExpressionRef notifyCount = BinaryenExpressionRef_val(_notifyCount);
char* memoryName = Safe_String_val(_memoryName);
BinaryenExpressionRef res = BinaryenAtomicNotify(module, ptr, notifyCount, memoryName);
CAMLreturn(alloc_BinaryenExpressionRef(res));
}

CAMLprim value
caml_binaryen_atomic_fence(value _module) {
CAMLparam1(_module);
BinaryenModuleRef module = BinaryenModuleRef_val(_module);
BinaryenExpressionRef res = BinaryenAtomicFence(module);
CAMLreturn(alloc_BinaryenExpressionRef(res));
}
128 changes: 128 additions & 0 deletions src/binaryen_stubs_expressions.js
Expand Up @@ -1826,3 +1826,131 @@ function caml_binaryen_tablegrow_get_delta(exp) {
function caml_binaryen_tablegrow_set_delta(exp, delta) {
return Binaryen.TableGrow.setDelta(exp, delta);
}

// Atomics

//Provides:
//Requires:
function caml_binaryen_atomic_load(value _module, value _bytes, value _offset, value _ty, value _ptr, value _memoryName) {
CAMLparam5(_module, _bytes, _offset, _ty, _ptr);
CAMLxparam1(_memoryName);
BinaryenModuleRef module = BinaryenModuleRef_val(_module);
int bytes = Int_val(_bytes);
int offset = Int_val(_offset);
BinaryenType ty = BinaryenType_val(_ty);
BinaryenExpressionRef ptr = BinaryenExpressionRef_val(_ptr);
char* memoryName = Safe_String_val(_memoryName);
BinaryenExpressionRef res = BinaryenAtomicLoad(module, bytes, offset, ty, ptr, memoryName);
CAMLreturn(alloc_BinaryenExpressionRef(res));
}
//Provides:
//Requires:
function caml_binaryen_atomic_load__bytecode(value * argv) {
return caml_binaryen_atomic_load(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5]);
}

//Provides:
//Requires:
function caml_binaryen_atomic_store(value _module, value _bytes, value _offset, value _ptr, value _val, value _ty, value _memoryName) {
CAMLparam5(_module, _bytes, _offset, _ptr, _val);
CAMLxparam2(_ty, _memoryName);
BinaryenModuleRef module = BinaryenModuleRef_val(_module);
int bytes = Int_val(_bytes);
int offset = Int_val(_offset);
BinaryenExpressionRef ptr = BinaryenExpressionRef_val(_ptr);
BinaryenExpressionRef val = BinaryenExpressionRef_val(_val);
BinaryenType ty = BinaryenType_val(_ty);
char* memoryName = Safe_String_val(_memoryName);
BinaryenExpressionRef res = BinaryenAtomicStore(module, bytes, offset, ptr, val, ty, memoryName);
CAMLreturn(alloc_BinaryenExpressionRef(res));
}
//Provides:
//Requires:
function caml_binaryen_atomic_store__bytecode(value * argv) {
return caml_binaryen_atomic_store(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6]);
}

//Provides:
//Requires:
function caml_binaryen_atomic_rmw(value _module, value _op, value _bytes, value _offset, value _ptr, value _val, value _ty, value _memoryName) {
CAMLparam5(_module, _op, _bytes, _offset, _ptr);
CAMLxparam3(_val, _ty, _memoryName);
BinaryenModuleRef module = BinaryenModuleRef_val(_module);
BinaryenOp op = BinaryenOp_val(_op);
BinaryenIndex bytes = Int_val(_bytes);
BinaryenIndex offset = Int_val(_offset);
BinaryenExpressionRef ptr = BinaryenExpressionRef_val(_ptr);
BinaryenExpressionRef val = BinaryenExpressionRef_val(_val);
BinaryenType ty = BinaryenType_val(_ty);
char* memoryName = Safe_String_val(_memoryName);
BinaryenExpressionRef res = BinaryenAtomicRMW(module, op, bytes, offset, ptr, val, ty, memoryName);
CAMLreturn(alloc_BinaryenExpressionRef(res));
}
//Provides:
//Requires:
function caml_binaryen_atomic_rmw__bytecode(value * argv) {
return caml_binaryen_atomic_rmw(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7]);
}

//Provides:
//Requires:
function caml_binaryen_atomic_cmpxchg(value _module, value _bytes, value _offset, value _ptr, value _expected, value _replacement, value _ty, value _memoryName) {
CAMLparam5(_module, _bytes, _offset, _ptr, _expected);
CAMLxparam3(_replacement, _ty, _memoryName);
BinaryenModuleRef module = BinaryenModuleRef_val(_module);
BinaryenIndex bytes = Int_val(_bytes);
BinaryenIndex offset = Int_val(_offset);
BinaryenExpressionRef ptr = BinaryenExpressionRef_val(_ptr);
BinaryenExpressionRef expected = BinaryenExpressionRef_val(_expected);
BinaryenExpressionRef replacement = BinaryenExpressionRef_val(_replacement);
BinaryenType ty = BinaryenType_val(_ty);
char* memoryName = Safe_String_val(_memoryName);
BinaryenExpressionRef res = BinaryenAtomicCmpxchg(module, bytes, offset, ptr, expected, replacement, ty, memoryName);
CAMLreturn(alloc_BinaryenExpressionRef(res));
}
//Provides:
//Requires:
function caml_binaryen_atomic_cmpxchg__bytecode(value * argv) {
return caml_binaryen_atomic_cmpxchg(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7]);
}

//Provides:
//Requires:
function caml_binaryen_atomic_wait(value _module, value _ptr, value _expected, value _timeout, value _ty, value _memoryName) {
CAMLparam5(_module, _ptr, _expected, _timeout, _ty);
CAMLxparam1(_memoryName);
BinaryenModuleRef module = BinaryenModuleRef_val(_module);
BinaryenExpressionRef ptr = BinaryenExpressionRef_val(_ptr);
BinaryenExpressionRef expected = BinaryenExpressionRef_val(_expected);
BinaryenExpressionRef timeout = BinaryenExpressionRef_val(_timeout);
BinaryenType ty = BinaryenType_val(_ty);
char* memoryName = Safe_String_val(_memoryName);
BinaryenExpressionRef res = BinaryenAtomicWait(module, ptr, expected, timeout, ty, memoryName);
CAMLreturn(alloc_BinaryenExpressionRef(res));
}
//Provides:
//Requires:
function caml_binaryen_atomic_wait__bytecode(value * argv) {
return caml_binaryen_atomic_wait(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5]);
}

//Provides:
//Requires:
function caml_binaryen_atomic_notify(value _module, value _ptr, value _notifyCount, value _memoryName) {
CAMLparam4(_module, _ptr, _notifyCount, _memoryName);
BinaryenModuleRef module = BinaryenModuleRef_val(_module);
BinaryenExpressionRef ptr = BinaryenExpressionRef_val(_ptr);
BinaryenExpressionRef notifyCount = BinaryenExpressionRef_val(_notifyCount);
char* memoryName = Safe_String_val(_memoryName);
BinaryenExpressionRef res = BinaryenAtomicNotify(module, ptr, notifyCount, memoryName);
CAMLreturn(alloc_BinaryenExpressionRef(res));
}

//Provides:
//Requires:
function caml_binaryen_atomic_fence(value _module) {
CAMLparam1(_module);
BinaryenModuleRef module = BinaryenModuleRef_val(_module);
BinaryenExpressionRef res = BinaryenAtomicFence(module);
CAMLreturn(alloc_BinaryenExpressionRef(res));
}
64 changes: 64 additions & 0 deletions src/expression.ml
Expand Up @@ -897,3 +897,67 @@ module Table_grow = struct
external set_delta : t -> t -> unit = "caml_binaryen_tablegrow_set_delta"
(** Sets the delta of a `Table.grow` expression. *)
end

module Atomic = struct
external load :
Module.t ->
bytes:int ->
offset:int ->
typ:Type.t ->
ptr:t ->
memory_name:string ->
t = "caml_binaryen_atomic_load__bytecode" "caml_binaryen_atomic_load"
(** module, bytes, offset, ty, ptr, memoryName *)

external store :
Module.t ->
bytes:int ->
offset:int ->
ptr:t ->
value:t ->
typ:Type.t ->
memory_name:string ->
t = "caml_binaryen_atomic_store__bytecode" "caml_binaryen_atomic_store"
(** module, bytes, offset, ptr, val, ty, memoryName *)

external rmw :
Module.t ->
op:Op.t ->
bytes:int ->
offset:int ->
ptr:t ->
value:t ->
typ:Type.t ->
memory_name:string ->
t = "caml_binaryen_atomic_rmw__bytecode" "caml_binaryen_atomic_rmw"
(** module, op, bytes, offset, ptr, val, ty, memoryName *)

external cmpxchg :
Module.t ->
bytes:int ->
offset:int ->
ptr:t ->
expected:t ->
replacement:t ->
typ:Type.t ->
memory_name:string ->
t = "caml_binaryen_atomic_cmpxchg__bytecode" "caml_binaryen_atomic_cmpxchg"
(** module, bytes, offset, ptr, expected, replacement, ty, memoryName *)

external wait :
Module.t ->
ptr:t ->
expected:t ->
timeout:t ->
typ:Type.t ->
memory_name:string ->
t = "caml_binaryen_atomic_wait__bytecode" "caml_binaryen_atomic_wait"
(** module, ptr, expected, timeout, ty, memoryName *)

external notify :
Module.t -> ptr:t -> notify_count:t -> memory_name:string -> t
= "caml_binaryen_atomic_notify"
(** module, ptr, notifyCount, memoryName *)

external fence : Module.t -> t = "caml_binaryen_atomic_fence"
end
62 changes: 62 additions & 0 deletions src/expression.mli
Expand Up @@ -417,3 +417,65 @@ module Table_grow : sig
val set_delta : t -> t -> unit
(** Sets the delta of a `Table.grow` expression. *)
end

module Atomic : sig
val load :
Module.t ->
bytes:int ->
offset:int ->
typ:Type.t ->
ptr:t ->
memory_name:string ->
t
(** module, bytes, offset, ty, ptr, memoryName *)

val store :
Module.t ->
bytes:int ->
offset:int ->
ptr:t ->
value:t ->
typ:Type.t ->
memory_name:string ->
t
(** module, bytes, offset, ptr, val, ty, memoryName *)

val rmw :
Module.t ->
op:Op.t ->
bytes:int ->
offset:int ->
ptr:t ->
value:t ->
typ:Type.t ->
memory_name:string ->
t
(** module, op, bytes, offset, ptr, val, ty, memoryName *)

val cmpxchg :
Module.t ->
bytes:int ->
offset:int ->
ptr:t ->
expected:t ->
replacement:t ->
typ:Type.t ->
memory_name:string ->
t
(** module, bytes, offset, ptr, expected, replacement, ty, memoryName *)

val wait :
Module.t ->
ptr:t ->
expected:t ->
timeout:t ->
typ:Type.t ->
memory_name:string ->
t
(** module, ptr, expected, timeout, ty, memoryName *)

val notify : Module.t -> ptr:t -> notify_count:t -> memory_name:string -> t
(** module, ptr, notifyCount, memoryName *)

val fence : Module.t -> t
end