-
Notifications
You must be signed in to change notification settings - Fork 55
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Wiring SharedMemory with it's corresponding bindings (#255)
* Wiring SharedMemory with it's corresponding bindings * Restoring _bindings.py as is being autogenerated out of the C-API interface in the wasmtime runtime repo * Removing SharedMemory read/write methods, as they are also not implemented in the Rust API for wasmtime. A SharedMemory is not associated to any Store, and the read/write methods from the linear memory seem to rely on the Store in order to properly operate. * Making SharedMemory inherit from the Manager type * Adding runtime typechecking to SharedMemory::_from_raw * After regenerating the bindings from wasmtime c-api (main/dev branch) and adjusting the shared memory arguments to match the new api, I found out that I needed to adjust other parts of the bindings that I guess have changed since the last release. In this commit, I only change the (shared) memory related ones, but I think I can adjust the rest of the c-api that has changed as well in the following commits. * Update to latest wasmtime dev (#257) * Retoring bindings from main branch as it was updated to latest changes in the C-APO from Wasmtime runtime repo * * Fixing Python types as suggested by mypy * Adding some unit tests for shared memory * Adding unit tests for shared memory --------- Co-authored-by: Jesse Rusak <[email protected]>
- Loading branch information
Showing
7 changed files
with
156 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
import unittest | ||
|
||
from wasmtime import * | ||
|
||
|
||
class TestSharedMemory(unittest.TestCase): | ||
def test_new(self): | ||
engine = Store().engine | ||
memory_type = MemoryType(Limits(1, 2), is_64=False, shared=True) | ||
assert(not memory_type.is_64) | ||
shared_memory = SharedMemory(engine, memory_type) | ||
with self.assertRaises(TypeError): | ||
shared_memory.grow('') # type: ignore | ||
with self.assertRaises(WasmtimeError): | ||
shared_memory.grow(-1) | ||
self.assertEqual(shared_memory.data_ptr()[0], 0) | ||
self.assertEqual(shared_memory.data_len(), 65536) | ||
self.assertTrue(isinstance(shared_memory.type(), MemoryType)) | ||
|
||
def test_grow(self): | ||
engine = Store().engine | ||
memory_type = MemoryType(Limits(1, 2), shared=True) | ||
shared_memory = SharedMemory(engine, memory_type) | ||
assert(shared_memory.grow(1) == 1) | ||
assert(shared_memory.grow(0) == 2) | ||
with self.assertRaises(WasmtimeError): | ||
shared_memory.grow(1) | ||
|
||
def test_errors(self): | ||
engine = Store().engine | ||
ty = MemoryType(Limits(1, 2), shared=True) | ||
with self.assertRaises(AttributeError): | ||
SharedMemory(1, ty) # type: ignore | ||
with self.assertRaises(AttributeError): | ||
SharedMemory(engine, 1) # type: ignore | ||
|
||
def test_shared_memory_type_fails_if_no_max_specified(self): | ||
with self.assertRaises(WasmtimeError): | ||
# Shared memories must have a max size | ||
MemoryType(Limits(0x100000000, None), shared=True) | ||
|
||
def test_shared_memory_type_works_if_min_max_i64_is_set(self): | ||
ty = MemoryType(Limits(0x100000000, 0x100000000), is_64=True, shared=True) | ||
assert(ty.limits.min == 0x100000000) | ||
assert(ty.limits.max == 0x100000000) | ||
assert(ty.is_64) | ||
|
||
def test_shared_memory_type_fails_if_is_too_large(self): | ||
with self.assertRaises(WasmtimeError): | ||
MemoryType(Limits(1, 0x100000000), shared=True) | ||
|
||
def test_memory_type_has_to_be_shared(self): | ||
engine = Store().engine | ||
ty = MemoryType(Limits(1, 2)) | ||
with self.assertRaises(WasmtimeError): | ||
SharedMemory(engine, ty) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
from . import _ffi as ffi | ||
from ctypes import * | ||
import ctypes | ||
from typing import Optional, Any | ||
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_ptr = POINTER(ffi.wasmtime_sharedmemory_t)() | ||
error = ffi.wasmtime_sharedmemory_new(engine.ptr(), ty.ptr(), byref(sharedmemory_ptr)) | ||
if error: | ||
raise WasmtimeError._from_ptr(error) | ||
self._set_ptr(sharedmemory_ptr) | ||
|
||
def _delete(self, ptr: "ctypes._Pointer[ffi.wasmtime_sharedmemory_t]") -> None: | ||
ffi.wasmtime_sharedmemory_delete(ptr) | ||
|
||
@classmethod | ||
def _from_ptr(cls, ptr: "ctypes._Pointer[ffi.wasmtime_sharedmemory_t]") -> "SharedMemory": | ||
if not isinstance(ptr, POINTER(ffi.wasmtime_sharedmemory_t)): | ||
raise TypeError("wrong shared memory pointer type provided to _from_ptr") | ||
|
||
ty: "SharedMemory" = cls.__new__(cls) | ||
ty._set_ptr(ptr) | ||
return ty | ||
|
||
def type(self) -> MemoryType: | ||
""" | ||
Gets the type of this memory as a `MemoryType` | ||
""" | ||
|
||
ptr = ffi.wasmtime_sharedmemory_type(self.ptr()) | ||
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(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(self.ptr()) | ||
|
||
def data_len(self) -> int: | ||
""" | ||
Returns the raw byte length of this memory. | ||
""" | ||
|
||
return ffi.wasmtime_sharedmemory_data_size(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) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters