Coverage for tests/test_func.py: 100%
115 statements
« prev ^ index » next coverage.py v7.6.12, created at 2025-02-20 16:25 +0000
« prev ^ index » next coverage.py v7.6.12, created at 2025-02-20 16:25 +0000
1import unittest
3from wasmtime import *
6class TestFunc(unittest.TestCase):
7 def test_smoke(self):
8 store = Store()
9 ty = FuncType([], [])
10 func = Func(store, ty, lambda: None)
11 func(store)
12 self.assertTrue(isinstance(func.type(store), FuncType))
14 def test_add(self):
15 store = Store()
16 ty = FuncType([ValType.i32(), ValType.i32()], [ValType.i32()])
17 func = Func(store, ty, lambda a, b: a + b)
18 self.assertEqual(func(store, 1, 2), 3)
20 def test_calls(self):
21 store = Store()
22 ty = FuncType([ValType.i32()], [])
23 func = Func(store, ty, lambda a: self.assertEqual(a, 1))
24 func(store, 1)
26 ty = FuncType([ValType.i64()], [])
27 func = Func(store, ty, lambda a: self.assertEqual(a, 2))
28 func(store, Val.i64(2))
30 ty = FuncType([ValType.f32()], [])
31 func = Func(store, ty, lambda a: self.assertEqual(a, 3.0))
32 func(store, 3.0)
34 ty = FuncType([ValType.f64()], [])
35 func = Func(store, ty, lambda a: self.assertEqual(a, 4.0))
36 func(store, 4.0)
38 def test_multi_return(self):
39 store = Store()
40 ty = FuncType([], [ValType.i32(), ValType.i32()])
41 func = Func(store, ty, lambda: [1, 2])
42 self.assertEqual(func(store), [1, 2])
44 def test_errors(self):
45 store = Store()
46 ty = FuncType([], [])
47 with self.assertRaises(TypeError):
48 Func(1, ty, lambda: None) # type: ignore
49 with self.assertRaises(TypeError):
50 Func(store, 1, lambda: None) # type: ignore
51 func = Func(store, ty, lambda: None)
52 with self.assertRaises(WasmtimeError):
53 func(store, 2)
55 ty = FuncType([ValType.i32()], [])
56 func = Func(store, ty, lambda: None)
57 with self.assertRaises(TypeError):
58 func(store, 3.0)
59 with self.assertRaises(TypeError):
60 func(store, Val.i64(3))
61 ty = FuncType([ValType.i32()], [])
63 func = Func(store, ty, lambda x: x)
64 with self.assertRaises(WasmtimeError, msg="produced results"):
65 func(store, 1)
67 def test_produce_wrong(self):
68 store = Store()
69 ty = FuncType([], [ValType.i32(), ValType.i32()])
70 func = Func(store, ty, lambda: 1)
71 with self.assertRaises(TypeError, msg="has no len"):
72 func(store)
73 func = Func(store, ty, lambda: [1, 2, 3])
74 with self.assertRaises(WasmtimeError, msg="wrong number of results"):
75 func(store)
77 def test_host_exception(self):
78 store = Store()
79 ty = FuncType([], [])
81 def do_raise():
82 raise Exception("hello")
84 func = Func(store, ty, do_raise)
85 with self.assertRaises(Exception, msg="hello"):
86 func(store)
88 def test_type(self):
89 store = Store()
90 i32 = ValType.i32()
91 i64 = ValType.i64()
92 f32 = ValType.f32()
93 f64 = ValType.f64()
94 ty = FuncType([i32, i64, f32, f64], [f64, f32, i64, i32])
96 def rev(*args):
97 ret = list(args)
98 ret.reverse()
99 return ret
101 func = Func(store, ty, rev)
102 self.assertEqual(func(store, 1, 2, 3.0, 4.0), [4.0, 3.0, 2, 1])
104 def test_access_caller(self):
105 # Test that we get *something*
106 store = Store()
108 def runtest(caller):
109 self.assertEqual(caller.get(''), None)
110 self.assertEqual(caller.get('x'), None)
111 self.assertEqual(caller.get('y'), None)
113 Func(store, FuncType([], []), runtest, access_caller=True)(store)
115 hit = {}
117 # Test that `Caller` works and that it's invalidated
118 def runtest2(caller):
119 hit['yes'] = True
120 hit['caller'] = caller
122 self.assertTrue(caller.get('bar') is None)
123 mem = caller.get('foo')
124 self.assertTrue(isinstance(mem, Memory))
126 self.assertEqual(mem.data_ptr(caller)[0], ord('f'))
127 self.assertEqual(mem.data_ptr(caller)[1], ord('o'))
128 self.assertEqual(mem.data_ptr(caller)[2], ord('o'))
129 self.assertEqual(mem.data_ptr(caller)[3], 0)
131 module = Module(store.engine, """
132 (module
133 (import "" "" (func))
134 (memory (export "foo") 1)
135 (start 0)
136 (data (i32.const 0) "foo")
137 )
138 """)
139 func = Func(store, FuncType([], []), runtest2, access_caller=True)
140 Instance(store, module, [func])
141 self.assertTrue(hit['yes'])
142 self.assertTrue(hit['caller'].get('foo') is None) # type: ignore
144 # Test that `Caller` is invalidated even on exceptions
145 hit2 = {}
147 def runtest3(caller):
148 hit2['caller'] = caller
149 self.assertTrue(caller['foo'] is not None)
150 raise WasmtimeError('foo')
152 func = Func(store, FuncType([], []), runtest3, access_caller=True)
153 with self.assertRaises(WasmtimeError, msg='foo'):
154 Instance(store, module, [func])
155 self.assertTrue(hit2['caller'].get('foo') is None)