Skip to content

Commit e80a1de

Browse files
committed
Move called_as_export into Context
1 parent c489282 commit e80a1de

File tree

3 files changed

+62
-56
lines changed

3 files changed

+62
-56
lines changed

design/mvp/CanonicalABI.md

+33-29
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,7 @@ definitions via the `cx` parameter:
213213
class Context:
214214
opts: CanonicalOptions
215215
inst: ComponentInstance
216+
called_as_export: bool
216217
```
217218

218219
The `opts` field represents the [`canonopt`] values supplied to
@@ -238,6 +239,11 @@ class ComponentInstance:
238239
# ...
239240
```
240241

242+
Lastly, the `called_as_export` field indicates whether the lifted function is
243+
being called through a component export or whether this is an internal call,
244+
(for example, when a child component calls an import that is defined by its
245+
parent component).
246+
241247

242248
### Loading
243249

@@ -1206,29 +1212,29 @@ component*.
12061212

12071213
Given the above closure arguments, `canon_lift` is defined:
12081214
```python
1209-
def canon_lift(callee_cx, callee, ft, args, called_as_export):
1210-
if called_as_export:
1211-
trap_if(not callee_cx.inst.may_enter)
1212-
callee_cx.inst.may_enter = False
1215+
def canon_lift(cx, callee, ft, args):
1216+
if cx.called_as_export:
1217+
trap_if(not cx.inst.may_enter)
1218+
cx.inst.may_enter = False
12131219
else:
1214-
assert(not callee_cx.inst.may_enter)
1220+
assert(not cx.inst.may_enter)
12151221

1216-
assert(callee_cx.inst.may_leave)
1217-
callee_cx.inst.may_leave = False
1218-
flat_args = lower_values(callee_cx, MAX_FLAT_PARAMS, args, ft.param_types())
1219-
callee_cx.inst.may_leave = True
1222+
assert(cx.inst.may_leave)
1223+
cx.inst.may_leave = False
1224+
flat_args = lower_values(cx, MAX_FLAT_PARAMS, args, ft.param_types())
1225+
cx.inst.may_leave = True
12201226

12211227
try:
12221228
flat_results = callee(flat_args)
12231229
except CoreWebAssemblyException:
12241230
trap()
12251231

1226-
results = lift_values(callee_cx, MAX_FLAT_RESULTS, ValueIter(flat_results), ft.result_types())
1232+
results = lift_values(cx, MAX_FLAT_RESULTS, ValueIter(flat_results), ft.result_types())
12271233
def post_return():
1228-
if callee_cx.opts.post_return is not None:
1229-
callee_cx.opts.post_return(flat_results)
1230-
if called_as_export:
1231-
callee_cx.inst.may_enter = True
1234+
if cx.opts.post_return is not None:
1235+
cx.opts.post_return(flat_results)
1236+
if cx.called_as_export:
1237+
cx.inst.may_enter = True
12321238

12331239
return (results, post_return)
12341240
```
@@ -1239,15 +1245,13 @@ boundaries. Thus, if a component wishes to signal an error, it must use some
12391245
sort of explicit type such as `result` (whose `error` case particular language
12401246
bindings may choose to map to and from exceptions).
12411247

1242-
The `called_as_export` parameter indicates whether `canon_lift` is being called
1243-
as part of a component export or whether this `canon_lift` is being called
1244-
internally (for example, by a child component instance). By clearing
1245-
`may_enter` for the duration of `canon_lift` when called as an export, the
1246-
dynamic traps ensure that components cannot be reentered, which is a [component
1247-
invariant]. Furthermore, because `may_enter` is not cleared on the exceptional
1248-
exit path taken by `trap()`, if there is a trap during Core WebAssembly
1249-
execution or lifting/lowering, the component is left permanently un-enterable,
1250-
ensuring the lockdown-after-trap [component invariant].
1248+
By clearing `may_enter` for the duration of `canon_lift` when the function is
1249+
called as an export, the dynamic traps ensure that components cannot be
1250+
reentered, ensuring the non-reentrance [component invariant]. Furthermore,
1251+
because `may_enter` is not cleared on the exceptional exit path taken by
1252+
`trap()`, if there is a trap during Core WebAssembly execution of lifting or
1253+
lowering, the component is left permanently un-enterable, ensuring the
1254+
lockdown-after-trap [component invariant].
12511255

12521256
The contract assumed by `canon_lift` (and ensured by `canon_lower` below) is
12531257
that the caller of `canon_lift` *must* call `post_return` right after lowering
@@ -1274,17 +1278,17 @@ Thus, from the perspective of Core WebAssembly, `$f` is a [function instance]
12741278
containing a `hostfunc` that closes over `$opts`, `$inst`, `$callee` and `$ft`
12751279
and, when called from Core WebAssembly code, calls `canon_lower`, which is defined as:
12761280
```python
1277-
def canon_lower(caller_cx, callee, ft, flat_args):
1278-
trap_if(not caller_cx.inst.may_leave)
1281+
def canon_lower(cx, callee, ft, flat_args):
1282+
trap_if(not cx.inst.may_leave)
12791283

12801284
flat_args = ValueIter(flat_args)
1281-
args = lift_values(caller_cx, MAX_FLAT_PARAMS, flat_args, ft.param_types())
1285+
args = lift_values(cx, MAX_FLAT_PARAMS, flat_args, ft.param_types())
12821286

12831287
results, post_return = callee(args)
12841288

1285-
caller_cx.inst.may_leave = False
1286-
flat_results = lower_values(caller_cx, MAX_FLAT_RESULTS, results, ft.result_types(), flat_args)
1287-
caller_cx.inst.may_leave = True
1289+
cx.inst.may_leave = False
1290+
flat_results = lower_values(cx, MAX_FLAT_RESULTS, results, ft.result_types(), flat_args)
1291+
cx.inst.may_leave = True
12881292

12891293
post_return()
12901294

design/mvp/canonical-abi/definitions.py

+21-20
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,7 @@ def num_i32_flags(labels):
275275
class Context:
276276
opts: CanonicalOptions
277277
inst: ComponentInstance
278+
called_as_export: bool
278279

279280
#
280281

@@ -1007,45 +1008,45 @@ def lower_values(cx, max_flat, vs, ts, out_param = None):
10071008

10081009
### `lift`
10091010

1010-
def canon_lift(callee_cx, callee, ft, args, called_as_export):
1011-
if called_as_export:
1012-
trap_if(not callee_cx.inst.may_enter)
1013-
callee_cx.inst.may_enter = False
1011+
def canon_lift(cx, callee, ft, args):
1012+
if cx.called_as_export:
1013+
trap_if(not cx.inst.may_enter)
1014+
cx.inst.may_enter = False
10141015
else:
1015-
assert(not callee_cx.inst.may_enter)
1016+
assert(not cx.inst.may_enter)
10161017

1017-
assert(callee_cx.inst.may_leave)
1018-
callee_cx.inst.may_leave = False
1019-
flat_args = lower_values(callee_cx, MAX_FLAT_PARAMS, args, ft.param_types())
1020-
callee_cx.inst.may_leave = True
1018+
assert(cx.inst.may_leave)
1019+
cx.inst.may_leave = False
1020+
flat_args = lower_values(cx, MAX_FLAT_PARAMS, args, ft.param_types())
1021+
cx.inst.may_leave = True
10211022

10221023
try:
10231024
flat_results = callee(flat_args)
10241025
except CoreWebAssemblyException:
10251026
trap()
10261027

1027-
results = lift_values(callee_cx, MAX_FLAT_RESULTS, ValueIter(flat_results), ft.result_types())
1028+
results = lift_values(cx, MAX_FLAT_RESULTS, ValueIter(flat_results), ft.result_types())
10281029
def post_return():
1029-
if callee_cx.opts.post_return is not None:
1030-
callee_cx.opts.post_return(flat_results)
1031-
if called_as_export:
1032-
callee_cx.inst.may_enter = True
1030+
if cx.opts.post_return is not None:
1031+
cx.opts.post_return(flat_results)
1032+
if cx.called_as_export:
1033+
cx.inst.may_enter = True
10331034

10341035
return (results, post_return)
10351036

10361037
### `lower`
10371038

1038-
def canon_lower(caller_cx, callee, ft, flat_args):
1039-
trap_if(not caller_cx.inst.may_leave)
1039+
def canon_lower(cx, callee, ft, flat_args):
1040+
trap_if(not cx.inst.may_leave)
10401041

10411042
flat_args = ValueIter(flat_args)
1042-
args = lift_values(caller_cx, MAX_FLAT_PARAMS, flat_args, ft.param_types())
1043+
args = lift_values(cx, MAX_FLAT_PARAMS, flat_args, ft.param_types())
10431044

10441045
results, post_return = callee(args)
10451046

1046-
caller_cx.inst.may_leave = False
1047-
flat_results = lower_values(caller_cx, MAX_FLAT_RESULTS, results, ft.result_types(), flat_args)
1048-
caller_cx.inst.may_leave = True
1047+
cx.inst.may_leave = False
1048+
flat_results = lower_values(cx, MAX_FLAT_RESULTS, results, ft.result_types(), flat_args)
1049+
cx.inst.may_leave = True
10491050

10501051
post_return()
10511052

design/mvp/canonical-abi/run_tests.py

+8-7
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,15 @@ def realloc(self, original_ptr, original_size, alignment, new_size):
3232
self.memory[ret : ret + original_size] = self.memory[original_ptr : original_ptr + original_size]
3333
return ret
3434

35-
def mk_cx(memory, encoding = None, realloc = None, post_return = None):
35+
def mk_cx(memory = bytearray(), encoding = 'utf8', realloc = None, post_return = None):
3636
cx = Context()
3737
cx.opts = CanonicalOptions()
3838
cx.opts.memory = memory
3939
cx.opts.string_encoding = encoding
4040
cx.opts.realloc = realloc
4141
cx.opts.post_return = post_return
4242
cx.inst = ComponentInstance()
43+
cx.called_as_export = True
4344
return cx
4445

4546
def mk_str(s):
@@ -56,7 +57,7 @@ def fail(msg):
5657
raise BaseException(msg)
5758

5859
def test(t, vals_to_lift, v,
59-
cx = mk_cx(bytearray(), 'utf8', None, None),
60+
cx = mk_cx(),
6061
dst_encoding = None,
6162
lower_t = None,
6263
lower_v = None):
@@ -85,7 +86,7 @@ def test_name():
8586
heap = Heap(5*len(cx.opts.memory))
8687
if dst_encoding is None:
8788
dst_encoding = cx.opts.string_encoding
88-
cx = mk_cx(heap.memory, dst_encoding, heap.realloc, None)
89+
cx = mk_cx(heap.memory, dst_encoding, heap.realloc)
8990
lowered_vals = lower_flat(cx, v, lower_t)
9091
assert(flatten_type(lower_t) == list(map(lambda v: v.t, lowered_vals)))
9192

@@ -200,7 +201,7 @@ def test_nan64(inbits, outbits):
200201
def test_string_internal(src_encoding, dst_encoding, s, encoded, tagged_code_units):
201202
heap = Heap(len(encoded))
202203
heap.memory[:] = encoded[:]
203-
cx = mk_cx(heap.memory, src_encoding, None, None)
204+
cx = mk_cx(heap.memory, src_encoding)
204205
v = (s, src_encoding, tagged_code_units)
205206
test(String(), [0, tagged_code_units], v, cx, dst_encoding)
206207

@@ -237,7 +238,7 @@ def test_string(src_encoding, dst_encoding, s):
237238

238239
def test_heap(t, expect, args, byte_array):
239240
heap = Heap(byte_array)
240-
cx = mk_cx(heap.memory, 'utf8', None, None)
241+
cx = mk_cx(heap.memory)
241242
test(t, args, expect, cx)
242243

243244
test_heap(List(Record([])), [{},{},{}], [0,3], [])
@@ -348,10 +349,10 @@ def test_roundtrip(t, v):
348349

349350
callee_heap = Heap(1000)
350351
callee_cx = mk_cx(callee_heap.memory, 'utf8', callee_heap.realloc, lambda x: () )
351-
lifted_callee = lambda args: canon_lift(callee_cx, callee, ft, args, True)
352+
lifted_callee = lambda args: canon_lift(callee_cx, callee, ft, args)
352353

353354
caller_heap = Heap(1000)
354-
caller_cx = mk_cx(caller_heap.memory, 'utf8', caller_heap.realloc, None)
355+
caller_cx = mk_cx(caller_heap.memory, 'utf8', caller_heap.realloc)
355356

356357
flat_args = lower_flat(caller_cx, v, t)
357358
flat_results = canon_lower(caller_cx, lifted_callee, ft, flat_args)

0 commit comments

Comments
 (0)