|
30 | 30 | (import "" "future.new" (func $future.new (result i64))) |
31 | 31 | (import "" "future.read" (func $future.read (param i32 i32) (result i32))) |
32 | 32 | (import "" "future.write" (func $future.write (param i32 i32) (result i32))) |
33 | | - (import "" "task.return" (func $task.return (param i32))) |
| 33 | + (import "" "task.return0" (func $task.return0)) |
| 34 | + (import "" "task.return1" (func $task.return1 (param i32))) |
34 | 35 | (import "" "R-rep" (func $R-rep (param i32) (result i32))) |
35 | 36 | (import "" "R-drop" (func $R-drop (param i32))) |
36 | 37 |
|
|
49 | 50 | ) |
50 | 51 | (func (export "dont-drop-cb") (param i32 i32 i32) (result i32) |
51 | 52 | ;; We were resumed by resume-dont-drop |
52 | | - (call $task.return (global.get $dont-drop-result)) |
| 53 | + (call $task.return1 (global.get $dont-drop-result)) |
53 | 54 | (i32.const 0 (; EXIT ;)) |
54 | 55 | ) |
55 | 56 | (func (export "drop-handle") (result i32) |
|
75 | 76 | (then unreachable)) |
76 | 77 | (call $waitable.join (local.get $futr) (global.get $dont-drop-ws)) |
77 | 78 | ) |
| 79 | + (func (export "drop-other-and-self") (param $h i32) (result i32) |
| 80 | + (local $result i32) |
| 81 | + (local.set $result (call $R-rep (global.get $handle))) |
| 82 | + (call $R-drop (global.get $handle)) |
| 83 | + (call $R-drop (local.get $h)) |
| 84 | + (call $task.return1 (local.get $result)) |
| 85 | + (i32.const 0 (; EXIT ;)) |
| 86 | + ) |
| 87 | + (func (export "drop-wrong-one") (param $h i32) (result i32) |
| 88 | + (call $R-drop (global.get $handle)) |
| 89 | + ;; trap b/c $h wasn't dropped |
| 90 | + (call $task.return0) |
| 91 | + (i32.const 0 (; EXIT ;)) |
| 92 | + ) |
| 93 | + (func (export "unreachable-cb") (param i32 i32 i32) (result i32) |
| 94 | + unreachable |
| 95 | + ) |
78 | 96 | ) |
79 | 97 | (type $FT (future)) |
80 | 98 | (alias export $d "R" (type $R)) |
81 | | - (canon task.return (result u32) (core func $task.return)) |
| 99 | + (canon task.return (core func $task.return0)) |
| 100 | + (canon task.return (result u32) (core func $task.return1)) |
82 | 101 | (canon waitable.join (core func $waitable.join)) |
83 | 102 | (canon waitable-set.new (core func $waitable-set.new)) |
84 | 103 | (canon future.new $FT (core func $future.new)) |
|
87 | 106 | (canon lower (func $d "R-rep") (core func $R-rep)) |
88 | 107 | (canon resource.drop $R (core func $R-drop)) |
89 | 108 | (core instance $dm (instantiate $DM (with "" (instance |
90 | | - (export "task.return" (func $task.return)) |
| 109 | + (export "task.return0" (func $task.return0)) |
| 110 | + (export "task.return1" (func $task.return1)) |
91 | 111 | (export "waitable.join" (func $waitable.join)) |
92 | 112 | (export "waitable-set.new" (func $waitable-set.new)) |
93 | 113 | (export "future.new" (func $future.new)) |
|
105 | 125 | (func (export "resume-dont-drop") |
106 | 126 | (canon lift (core func $dm "resume-dont-drop")) |
107 | 127 | ) |
| 128 | + (func (export "drop-other-and-self") (param "self" (borrow $R)) (result u32) |
| 129 | + (canon lift (core func $dm "drop-other-and-self") async (callback (func $dm "unreachable-cb"))) |
| 130 | + ) |
| 131 | + (func (export "drop-wrong-one") (param "self" (borrow $R)) |
| 132 | + (canon lift (core func $dm "drop-wrong-one") async (callback (func $dm "unreachable-cb"))) |
| 133 | + ) |
108 | 134 | ) |
109 | 135 |
|
110 | 136 | (component $E |
|
117 | 143 | (export "dont-drop" (func async (param "self" (borrow $R)) (result u32))) |
118 | 144 | (export "drop-handle" (func (result u32))) |
119 | 145 | (export "resume-dont-drop" (func)) |
| 146 | + (export "drop-other-and-self" (func (param "self" (borrow $R)) (result u32))) |
| 147 | + (export "drop-wrong-one" (func (param "self" (borrow $R)))) |
120 | 148 | )) |
121 | 149 | (core module $Memory (memory (export "mem") 1)) |
122 | 150 | (core instance $memory (instantiate $Memory)) |
|
129 | 157 | (import "" "dont-drop" (func $dont-drop (param i32 i32) (result i32))) |
130 | 158 | (import "" "drop-handle" (func $drop-handle (result i32))) |
131 | 159 | (import "" "resume-dont-drop" (func $resume-dont-drop)) |
132 | | - (func (export "do-it-right") (result i32) |
| 160 | + (import "" "drop-other-and-self" (func $drop-other-and-self (param i32) (result i32))) |
| 161 | + (import "" "drop-wrong-one" (func $drop-wrong-one (param i32))) |
| 162 | + (func (export "drop-other-no-self") (result i32) |
133 | 163 | (local $ret i32) |
134 | 164 | (local $retp i32) (local $retp2 i32) |
135 | 165 | (local $handle i32) |
136 | 166 | (local $subtask i32) |
137 | 167 | (local $magic i32) |
138 | 168 | (local $ws i32) (local $event_code i32) |
139 | 169 |
|
140 | | - ;; Create a resource storign $magic as it's rep |
| 170 | + ;; Create a resource storing $magic as it's rep |
141 | 171 | (local.set $magic (i32.const 10)) |
142 | 172 | (local.set $handle (call $R-new (local.get $magic))) |
143 | 173 |
|
|
174 | 204 |
|
175 | 205 | i32.const 42 |
176 | 206 | ) |
| 207 | + (func (export "drop-other-and-self") (result i32) |
| 208 | + (local $ret i32) |
| 209 | + (local $retp i32) (local $retp2 i32) |
| 210 | + (local $handle i32) |
| 211 | + (local $subtask i32) |
| 212 | + (local $magic i32) |
| 213 | + (local $ws i32) (local $event_code i32) |
| 214 | + |
| 215 | + ;; Create a resource storing $magic as it's rep |
| 216 | + (local.set $magic (i32.const 11)) |
| 217 | + (local.set $handle (call $R-new (local.get $magic))) |
| 218 | + |
| 219 | + ;; Kick off a call to dont-drop that will block |
| 220 | + (local.set $retp (i32.const 16)) |
| 221 | + (local.set $ret (call $dont-drop (local.get $handle) (local.get $retp))) |
| 222 | + (if (i32.ne (i32.const 1 (; STARTED ;)) (i32.and (local.get $ret) (i32.const 0xf))) |
| 223 | + (then unreachable)) |
| 224 | + (local.set $subtask (i32.shr_u (local.get $ret) (i32.const 4))) |
| 225 | + |
| 226 | + ;; This will drop dont-drop's *and* its own borrowed handle |
| 227 | + (local.set $ret (call $drop-other-and-self (local.get $handle))) |
| 228 | + (if (i32.ne (local.get $magic) (local.get $ret)) |
| 229 | + (then unreachable)) |
| 230 | + |
| 231 | + ;; this unblocks $subtask |
| 232 | + (call $resume-dont-drop) |
| 233 | + |
| 234 | + ;; now wait for $subtask to return, so that it can run before the test is over |
| 235 | + (local.set $ws (call $waitable-set.new)) |
| 236 | + (call $waitable.join (local.get $subtask) (local.get $ws)) |
| 237 | + (local.set $retp2 (i32.const 32)) |
| 238 | + (local.set $event_code (call $waitable-set.wait (local.get $ws) (local.get $retp2))) |
| 239 | + (if (i32.ne (i32.const 1 (; SUBTASK ;)) (local.get $event_code)) |
| 240 | + (then unreachable)) |
| 241 | + (if (i32.ne (local.get $subtask) (i32.load (local.get $retp2))) |
| 242 | + (then unreachable)) |
| 243 | + (if (i32.ne (i32.const 2 (; RETURNED=2 | (0<<4) ;)) (i32.load offset=4 (local.get $retp2))) |
| 244 | + (then unreachable)) |
| 245 | + |
| 246 | + ;; $subtask should return the rep passed to $R-new. |
| 247 | + (if (i32.ne (local.get $magic) (i32.load (local.get $retp))) |
| 248 | + (then unreachable)) |
| 249 | + |
| 250 | + i32.const 43 |
| 251 | + ) |
| 252 | + (func (export "drop-other-miss-self") |
| 253 | + (local $ret i32) |
| 254 | + (local $retp i32) |
| 255 | + (local $handle i32) |
| 256 | + (local $subtask i32) |
| 257 | + |
| 258 | + (local.set $handle (call $R-new (i32.const 42))) |
| 259 | + |
| 260 | + ;; Kick off a call to dont-drop that will block |
| 261 | + (local.set $retp (i32.const 16)) |
| 262 | + (local.set $ret (call $dont-drop (local.get $handle) (local.get $retp))) |
| 263 | + (if (i32.ne (i32.const 1 (; STARTED ;)) (i32.and (local.get $ret) (i32.const 0xf))) |
| 264 | + (then unreachable)) |
| 265 | + (local.set $subtask (i32.shr_u (local.get $ret) (i32.const 4))) |
| 266 | + |
| 267 | + ;; Call drop-wrong-one which will drop the above call's borrow, but not its own and trap |
| 268 | + (call $drop-wrong-one (local.get $handle)) |
| 269 | + ) |
177 | 270 | ) |
178 | 271 | (canon waitable.join (core func $waitable.join)) |
179 | 272 | (canon waitable-set.new (core func $waitable-set.new)) |
|
182 | 275 | (canon lower (func $d "dont-drop") async (memory $memory "mem") (core func $dont-drop)) |
183 | 276 | (canon lower (func $d "drop-handle") (core func $drop-handle)) |
184 | 277 | (canon lower (func $d "resume-dont-drop") (core func $resume-dont-drop)) |
| 278 | + (canon lower (func $d "drop-other-and-self") (core func $drop-other-and-self)) |
| 279 | + (canon lower (func $d "drop-wrong-one") (core func $drop-wrong-one)) |
185 | 280 | (core instance $em (instantiate $EM (with "" (instance |
186 | 281 | (export "mem" (memory $memory "mem")) |
187 | 282 | (export "waitable.join" (func $waitable.join)) |
|
191 | 286 | (export "dont-drop" (func $dont-drop)) |
192 | 287 | (export "drop-handle" (func $drop-handle)) |
193 | 288 | (export "resume-dont-drop" (func $resume-dont-drop)) |
| 289 | + (export "drop-other-and-self" (func $drop-other-and-self)) |
| 290 | + (export "drop-wrong-one" (func $drop-wrong-one)) |
194 | 291 | )))) |
195 | | - (func (export "do-it-right") async (result u32) (canon lift (core func $em "do-it-right"))) |
| 292 | + (func (export "drop-other-no-self") async (result u32) (canon lift (core func $em "drop-other-no-self"))) |
| 293 | + (func (export "drop-other-and-self") async (result u32) (canon lift (core func $em "drop-other-and-self"))) |
| 294 | + (func (export "drop-other-miss-self") async (canon lift (core func $em "drop-other-miss-self"))) |
196 | 295 | ) |
197 | 296 | (instance $c (instantiate $C)) |
198 | 297 | (instance $d (instantiate $D (with "c" (instance $c)))) |
199 | 298 | (instance $e (instantiate $E (with "c" (instance $c)) (with "d" (instance $d)))) |
200 | | - (func (export "do-it-right") (alias export $e "do-it-right")) |
| 299 | + (func (export "drop-other-no-self") (alias export $e "drop-other-no-self")) |
| 300 | + (func (export "drop-other-and-self") (alias export $e "drop-other-and-self")) |
| 301 | + (func (export "drop-other-miss-self") (alias export $e "drop-other-miss-self")) |
201 | 302 | ) |
202 | 303 |
|
203 | 304 | (component instance $i $Test) |
204 | | -(assert_return (invoke "do-it-right") (u32.const 42)) |
| 305 | +(assert_return (invoke "drop-other-no-self") (u32.const 42)) |
| 306 | +(component instance $i $Test) |
| 307 | +(assert_return (invoke "drop-other-and-self") (u32.const 43)) |
| 308 | +(component instance $i $Test) |
| 309 | +(assert_trap (invoke "drop-other-miss-self") "borrow handles still remain at the end of the call") |
0 commit comments