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

Wiring SharedMemory with it's corresponding bindings #255

Draft
wants to merge 7 commits into
base: main
Choose a base branch
from
2 changes: 2 additions & 0 deletions wasmtime/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
from ._instance import Instance
from ._wasi import WasiConfig
from ._linker import Linker
from ._sharedmemory import SharedMemory

__all__ = [
'wat2wasm',
Expand All @@ -50,6 +51,7 @@
'Caller',
'Table',
'Memory',
'SharedMemory',
'Global',
'Trap',
'TrapCode',
Expand Down
8 changes: 6 additions & 2 deletions wasmtime/_extern.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@


def wrap_extern(ptr: ffi.wasmtime_extern_t) -> AsExtern:
from wasmtime import Func, Table, Global, Memory, Module, Instance
from wasmtime import Func, Table, Global, Memory, SharedMemory, Module, Instance

if ptr.kind == ffi.WASMTIME_EXTERN_FUNC.value:
return Func._from_raw(ptr.of.func)
Expand All @@ -15,6 +15,8 @@ def wrap_extern(ptr: ffi.wasmtime_extern_t) -> AsExtern:
return Global._from_raw(ptr.of.global_)
if ptr.kind == ffi.WASMTIME_EXTERN_MEMORY.value:
return Memory._from_raw(ptr.of.memory)
if ptr.kind == ffi.WASMTIME_EXTERN_SHAREDMEMORY.value:
return SharedMemory._from_raw(ptr.of.sharedmemory)
if ptr.kind == ffi.WASMTIME_EXTERN_INSTANCE.value:
return Instance._from_raw(ptr.of.instance)
if ptr.kind == ffi.WASMTIME_EXTERN_MODULE.value:
Expand All @@ -23,14 +25,16 @@ def wrap_extern(ptr: ffi.wasmtime_extern_t) -> AsExtern:


def get_extern_ptr(item: AsExtern) -> ffi.wasmtime_extern_t:
from wasmtime import Func, Table, Global, Memory, Module, Instance
from wasmtime import Func, Table, Global, Memory, SharedMemory, Module, Instance

if isinstance(item, Func):
return item._as_extern()
elif isinstance(item, Global):
return item._as_extern()
elif isinstance(item, Memory):
return item._as_extern()
elif isinstance(item, SharedMemory):
return item._as_extern()
elif isinstance(item, Table):
return item._as_extern()
elif isinstance(item, Module):
Expand Down
1 change: 1 addition & 0 deletions wasmtime/_ffi.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
WASMTIME_EXTERN_GLOBAL = c_uint8(1)
WASMTIME_EXTERN_TABLE = c_uint8(2)
WASMTIME_EXTERN_MEMORY = c_uint8(3)
WASMTIME_EXTERN_SHAREDMEMORY = c_uint8(4)
atilag marked this conversation as resolved.
Show resolved Hide resolved
WASMTIME_EXTERN_INSTANCE = c_uint8(4)
WASMTIME_EXTERN_MODULE = c_uint8(5)

Expand Down
74 changes: 74 additions & 0 deletions wasmtime/_sharedmemory.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
from . import _ffi as ffi
from ctypes import *
import ctypes
from wasmtime import MemoryType, WasmtimeError, Engine, Managed
from ._store import Storelike



class SharedMemory(Managed["ctypes._Pointer[ffi.wasmtime_sharedmemory_t]"]):
def __init__(self, engine: Engine, ty: MemoryType):
"""
Creates a new shared memory in `store` with the given `ty`
"""

sharedmemory = ffi.wasmtime_sharedmemory_t()
ptr = POINTER(ffi.wasmtime_sharedmemory_t)()
error = ffi.wasmtime_sharedmemory_new(engine.ptr(), ty.ptr(), byref(ptr))
if error:
raise WasmtimeError._from_ptr(error)
self._set_ptr(sharedmemory)

@classmethod
def _from_raw(cls, sharedmemory: ffi.wasmtime_sharedmemory_t) -> "SharedMemory":
ty: "SharedMemory" = cls.__new__(cls)
ty._set_ptr(sharedmemory)
atilag marked this conversation as resolved.
Show resolved Hide resolved
return ty

def type(self) -> MemoryType:
"""
Gets the type of this memory as a `MemoryType`
"""

ptr = ffi.wasmtime_sharedmemory_type(byref(self._sharedmemory))
return MemoryType._from_ptr(ptr, None)

def grow(self, delta: int) -> int:
"""
Grows this memory by the given number of pages
"""

if delta < 0:
raise WasmtimeError("cannot grow by negative amount")
prev = ffi.c_uint64(0)
error = ffi.wasmtime_sharedmemory_grow(byref(self.ptr()), delta, byref(prev))
if error:
raise WasmtimeError._from_ptr(error)
return prev.value

def size(self) -> int:
"""
Returns the size, in WebAssembly pages, of this shared memory.
"""

return ffi.wasmtime_sharedmemory_size(byref(self.ptr()))

def data_ptr(self) -> "ctypes._Pointer[c_ubyte]":
"""
Returns the raw pointer in memory where this wasm shared memory lives.

Remember that all accesses to wasm shared memory should be bounds-checked
against the `data_len` method.
"""
return ffi.wasmtime_sharedmemory_data(byref(self.ptr()))

def data_len(self) -> int:
"""
Returns the raw byte length of this memory.
"""

return ffi.wasmtime_sharedmemory_data_size(byref(self.ptr()))

def _as_extern(self) -> ffi.wasmtime_extern_t:
union = ffi.wasmtime_extern_union(sharedmemory=pointer(self.ptr()))
return ffi.wasmtime_extern_t(ffi.WASMTIME_EXTERN_SHAREDMEMORY, union)
15 changes: 12 additions & 3 deletions wasmtime/_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ def _as_extern(self) -> "ctypes._Pointer[ffi.wasm_externtype_t]":


class MemoryType(Managed["ctypes._Pointer[ffi.wasm_memorytype_t]"]):
def __init__(self, limits: Limits, is_64: bool = False):
def __init__(self, limits: Limits, is_64: bool = False, shared: bool = True):
if not isinstance(limits, Limits):
raise TypeError("expected Limits")
if is_64:
Expand All @@ -296,7 +296,8 @@ def __init__(self, limits: Limits, is_64: bool = False):
ptr = ffi.wasmtime_memorytype_new(limits.min,
limits.max is not None,
limits.max if limits.max else 0,
is_64)
is_64,
shared)
if not ptr:
raise WasmtimeError("failed to allocate MemoryType")
self._set_ptr(ptr)
Expand Down Expand Up @@ -331,10 +332,18 @@ def is_64(self) -> bool:
Returns whether or not this is a 64-bit memory
"""
return ffi.wasmtime_memorytype_is64(self.ptr())

@property
def is_shared(self) -> bool:
"""
Returns whether or not this is a shared memory
"""
return ffi.wasmtime_memorytype_isshared(self.ptr())


def _as_extern(self) -> "ctypes._Pointer[ffi.wasm_externtype_t]":
return ffi.wasm_memorytype_as_externtype_const(self.ptr())


def wrap_externtype(ptr: "ctypes._Pointer[ffi.wasm_externtype_t]", owner: Optional[Any]) -> "AsExternType":
if not isinstance(ptr, POINTER(ffi.wasm_externtype_t)):
Expand Down
Loading