@@ -210,31 +210,39 @@ The subsequent definitions of loading and storing a value from linear memory
210
210
require additional context, which is threaded through most subsequent
211
211
definitions via the ` cx ` parameter:
212
212
``` python
213
+ class Context :
214
+ opts: CanonicalOptions
215
+ inst: ComponentInstance
216
+ called_as_export: bool
217
+ ```
218
+
219
+ The ` opts ` field represents the [ ` canonopt ` ] values supplied to
220
+ currently-executing ` canon lift ` or ` canon lower ` :
221
+ ``` python
213
222
class CanonicalOptions :
214
223
memory: bytearray
215
224
string_encoding: str
216
225
realloc: Callable[[int ,int ,int ,int ],int ]
217
226
post_return: Callable[[],None ]
227
+ ```
218
228
229
+ The ` inst ` field represents the component instance that the currently-executing
230
+ canonical definition is defined to execute inside. The ` may_enter ` and
231
+ ` may_leave ` fields are used to enforce the [ component invariants] : ` may_leave `
232
+ indicates whether the instance may call out to an import and the ` may_enter `
233
+ state indicates whether the instance may be called from the outside world
234
+ through an export.
235
+ ``` python
219
236
class ComponentInstance :
220
237
may_leave = True
221
238
may_enter = True
222
239
# ...
223
-
224
- class Context :
225
- opts: CanonicalOptions
226
- inst: ComponentInstance
227
240
```
228
- Going through the fields of ` Context ` :
229
-
230
- The ` opts ` field represents the [ ` canonopt ` ] values supplied to
231
- currently-executing ` canon lift ` or ` canon lower ` .
232
241
233
- The ` inst ` field represents the component instance that the currently-executing
234
- canonical definition is closed over. The ` may_enter ` and ` may_leave ` fields are
235
- used to enforce the [ component invariants] : ` may_leave ` indicates whether the
236
- instance may call out to an import and the ` may_enter ` state indicates whether
237
- the instance may be called from the outside world through an export.
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).
238
246
239
247
240
248
### Loading
@@ -1204,29 +1212,29 @@ component*.
1204
1212
1205
1213
Given the above closure arguments, ` canon_lift ` is defined:
1206
1214
``` python
1207
- def canon_lift (callee_cx , callee , ft , args , called_as_export ):
1208
- if called_as_export:
1209
- trap_if(not callee_cx .inst.may_enter)
1210
- 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
1211
1219
else :
1212
- assert (not callee_cx .inst.may_enter)
1220
+ assert (not cx .inst.may_enter)
1213
1221
1214
- assert (callee_cx .inst.may_leave)
1215
- callee_cx .inst.may_leave = False
1216
- flat_args = lower_values(callee_cx , MAX_FLAT_PARAMS , args, ft.param_types())
1217
- 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
1218
1226
1219
1227
try :
1220
1228
flat_results = callee(flat_args)
1221
1229
except CoreWebAssemblyException:
1222
1230
trap()
1223
1231
1224
- 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())
1225
1233
def post_return ():
1226
- if callee_cx .opts.post_return is not None :
1227
- callee_cx .opts.post_return(flat_results)
1228
- if called_as_export:
1229
- 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
1230
1238
1231
1239
return (results, post_return)
1232
1240
```
@@ -1237,15 +1245,13 @@ boundaries. Thus, if a component wishes to signal an error, it must use some
1237
1245
sort of explicit type such as ` result ` (whose ` error ` case particular language
1238
1246
bindings may choose to map to and from exceptions).
1239
1247
1240
- The ` called_as_export ` parameter indicates whether ` canon_lift ` is being called
1241
- as part of a component export or whether this ` canon_lift ` is being called
1242
- internally (for example, by a child component instance). By clearing
1243
- ` may_enter ` for the duration of ` canon_lift ` when called as an export, the
1244
- dynamic traps ensure that components cannot be reentered, which is a [ component
1245
- invariant] . Furthermore, because ` may_enter ` is not cleared on the exceptional
1246
- exit path taken by ` trap() ` , if there is a trap during Core WebAssembly
1247
- execution or lifting/lowering, the component is left permanently un-enterable,
1248
- 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] .
1249
1255
1250
1256
The contract assumed by ` canon_lift ` (and ensured by ` canon_lower ` below) is
1251
1257
that the caller of ` canon_lift ` * must* call ` post_return ` right after lowering
@@ -1272,17 +1278,17 @@ Thus, from the perspective of Core WebAssembly, `$f` is a [function instance]
1272
1278
containing a ` hostfunc ` that closes over ` $opts ` , ` $inst ` , ` $callee ` and ` $ft `
1273
1279
and, when called from Core WebAssembly code, calls ` canon_lower ` , which is defined as:
1274
1280
``` python
1275
- def canon_lower (caller_cx , callee , ft , flat_args ):
1276
- 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)
1277
1283
1278
1284
flat_args = ValueIter(flat_args)
1279
- 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())
1280
1286
1281
1287
results, post_return = callee(args)
1282
1288
1283
- caller_cx .inst.may_leave = False
1284
- flat_results = lower_values(caller_cx , MAX_FLAT_RESULTS , results, ft.result_types(), flat_args)
1285
- 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
1286
1292
1287
1293
post_return()
1288
1294
0 commit comments