Skip to content

Commit 0513ef7

Browse files
authored
Bind the C API for components (#308)
* Fix defining fields of forward-declared structures This fixes a typo in the bindings generation script which set the `_fields` field rather than `_fields_` * Bind the C API for components * Update to latest dev branch of wasmtime * CI fixes * Python 3.9 compat
1 parent 26a66f7 commit 0513ef7

29 files changed

+4045
-99
lines changed

ci/cbindgen.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,10 @@ def type_name(ty, ptr=False, typing=False):
189189
return "POINTER({})".format(type_name(ty, False, typing))
190190

191191
if isinstance(ty, c_ast.IdentifierType):
192+
if ty.names == ['unsigned', 'char']:
193+
return "int" if typing else "c_ubyte"
192194
assert(len(ty.names) == 1)
195+
193196
if ty.names[0] == "void":
194197
return "None"
195198
elif ty.names[0] == "_Bool":
@@ -218,6 +221,8 @@ def type_name(ty, ptr=False, typing=False):
218221
return "float" if typing else "c_double"
219222
elif ty.names[0] == "size_t":
220223
return "int" if typing else "c_size_t"
224+
elif ty.names[0] == "ptrdiff_t":
225+
return "int" if typing else "c_ssize_t"
221226
elif ty.names[0] == "char":
222227
return "c_char"
223228
elif ty.names[0] == "int":

tests/component/test_component.py

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
import unittest
2+
import tempfile
3+
4+
from wasmtime import *
5+
from wasmtime.component import Component, ExportIndex
6+
7+
class TestComponent(unittest.TestCase):
8+
def test_smoke(self):
9+
Component(Engine(), '(component)')
10+
Component(Engine(), bytes(b'\0asm\x0d\0\x01\0'))
11+
Component(Engine(), bytearray(b'\0asm\x0d\0\x01\0'))
12+
13+
with self.assertRaises(WasmtimeError):
14+
Component(Engine(), '(component2)')
15+
with self.assertRaises(WasmtimeError):
16+
Component(Engine(), bytes(b'\0asm\x01\0\0\0'))
17+
18+
def test_invalid(self):
19+
with self.assertRaises(TypeError):
20+
Component(1, b'') # type: ignore
21+
with self.assertRaises(TypeError):
22+
Component(Engine(), 2) # type: ignore
23+
with self.assertRaises(WasmtimeError):
24+
Component(Engine(), b'')
25+
with self.assertRaises(WasmtimeError):
26+
Component(Engine(), b'\x00')
27+
28+
def test_serialize(self):
29+
engine = Engine()
30+
component = Component(engine, '(component)')
31+
encoded = component.serialize()
32+
component = Component.deserialize(engine, encoded)
33+
with tempfile.TemporaryDirectory() as d:
34+
path = d + '/component.bin'
35+
with open(path, 'wb') as f:
36+
f.write(encoded)
37+
component = Component.deserialize_file(engine, path)
38+
39+
# Run the destructor for `Component` which has an mmap to the file
40+
# which prevents deletion on Windows.
41+
del component
42+
43+
def test_exports(self):
44+
engine = Engine()
45+
46+
c = Component(engine, '(component)')
47+
self.assertIsNone(c.get_export_index('foo'))
48+
self.assertIsNone(c.get_export_index('foo', instance = None))
49+
50+
c = Component(engine, """
51+
(component
52+
(core module (export "foo"))
53+
)
54+
""")
55+
foo = c.get_export_index('foo')
56+
self.assertIsNotNone(foo)
57+
self.assertIsNone(c.get_export_index('foo', instance = foo))
58+
self.assertIsInstance(foo, ExportIndex)
59+
60+
c = Component(engine, """
61+
(component
62+
(core module $a)
63+
(instance (export "x")
64+
(export "m" (core module $a))
65+
)
66+
)
67+
""")
68+
self.assertIsNotNone(c.get_export_index('x'))
69+
self.assertIsNotNone(c.get_export_index('m', instance = c.get_export_index('x')))
70+
71+
c2 = Component(engine, """
72+
(component
73+
(core module $a)
74+
(instance (export "x")
75+
(export "m" (core module $a))
76+
)
77+
)
78+
""")
79+
self.assertIsNone(c2.get_export_index('m', instance = c.get_export_index('x')))

0 commit comments

Comments
 (0)