Skip to content

Commit 146d607

Browse files
committed
Merge with WebAssembly/stack-switching
2 parents 1ccd8e8 + eca06cf commit 146d607

File tree

19 files changed

+864
-87
lines changed

19 files changed

+864
-87
lines changed

document/core/appendix/changes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -462,6 +462,8 @@ Added more precise types for references. [#proposal-typedref]_
462462

463463
* Refined typing of :ref:`local instructions <valid-instr-variable>` and :ref:`instruction sequences <valid-instr-seq>` to track the :ref:`initialization status <syntax-init>` of :ref:`locals <syntax-local>` with non-:ref:`defaultable <valid-defaultable>` type
464464

465+
* Refined decoding of :ref:`active <syntax-elemmode>` :ref:`element segments <binary-elem>` with implicit element type and plain function indices (opcode :math:`0`) to produce :ref:`non-nullable <syntax-nullable>` :ref:`reference type <syntax-reftype>`.
466+
465467
* Extended :ref:`table definitions <syntax-table>` with optional initializer expression
466468

467469

document/core/appendix/index-instructions.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -334,7 +334,7 @@ def Instruction(name, opcode, type=None, validation=None, execution=None, operat
334334
Instruction(r'\STRUCTGETS~x~y', r'\hex{FB}~\hex{03}', r'[(\REF~\NULL~x)] \to [\I32]', r'valid-struct.get', r'exec-struct.get'),
335335
Instruction(r'\STRUCTGETU~x~y', r'\hex{FB}~\hex{04}', r'[(\REF~\NULL~x)] \to [\I32]', r'valid-struct.get', r'exec-struct.get'),
336336
Instruction(r'\STRUCTSET~x~y', r'\hex{FB}~\hex{05}', r'[(\REF~\NULL~x)~t] \to []', r'valid-struct.set', r'exec-struct.set'),
337-
Instruction(r'\ARRAYNEW~x', r'\hex{FB}~\hex{06}', r'[t] \to [(\REF~x)]', r'valid-array.new', r'exec-array.new'),
337+
Instruction(r'\ARRAYNEW~x', r'\hex{FB}~\hex{06}', r'[t~\I32] \to [(\REF~x)]', r'valid-array.new', r'exec-array.new'),
338338
Instruction(r'\ARRAYNEWDEFAULT~x', r'\hex{FB}~\hex{07}', r'[\I32] \to [(\REF~x)]', r'valid-array.new', r'exec-array.new'),
339339
Instruction(r'\ARRAYNEWFIXED~x~n', r'\hex{FB}~\hex{08}', r'[t^n] \to [(\REF~x)]', r'valid-array.new_fixed', r'exec-array.new_fixed'),
340340
Instruction(r'\ARRAYNEWDATA~x~y', r'\hex{FB}~\hex{09}', r'[\I32~\I32] \to [(\REF~x)]', r'valid-array.new_data', r'exec-array.new_data'),

document/core/exec/instructions.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4753,7 +4753,7 @@ Control Instructions
47534753
\begin{array}[t]{@{}r@{~}l@{}}
47544754
(\iff & S.\STABLES[F.\AMODULE.\MITABLES[x]].\TIELEM[i] = \REFFUNCADDR~a \\
47554755
\wedge & S.\SFUNCS[a] = f \\
4756-
\wedge & S \vdashdeftypematch F.\AMODULE.\MITYPES[y] \matchesdeftype f.\FITYPE)
4756+
\wedge & S \vdashdeftypematch f.\FITYPE \matchesdeftype F.\AMODULE.\MITYPES[y])
47574757
\end{array}
47584758
\\[1ex]
47594759
\begin{array}{lcl@{\qquad}l}

document/core/exec/modules.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -364,7 +364,7 @@ and list of :ref:`reference <syntax-ref>` vectors for the module's :ref:`element
364364

365365
8. For each :ref:`element segment <syntax-elem>` :math:`\elem_i` in :math:`\module.\MELEMS`, do:
366366

367-
a. Let :math:`\reftype_i` be the element :ref:`reference type <syntax-reftype>` obtained by `instantiating <type-inst>` :math:`\elem_i.\ETYPE` in :math:`\moduleinst` defined below.
367+
a. Let :math:`\reftype_i` be the element :ref:`reference type <syntax-reftype>` obtained by :ref:`instantiating <type-inst>` :math:`\elem_i.\ETYPE` in :math:`\moduleinst` defined below.
368368

369369
b. Let :math:`\elemaddr_i` be the :ref:`element address <syntax-elemaddr>` resulting from :ref:`allocating <alloc-elem>` a :ref:`element instance <syntax-eleminst>` of :ref:`reference type <syntax-reftype>` :math:`\reftype_i` with contents :math:`(\reff_{\F{e}}^\ast)^\ast[i]`.
370370

document/core/syntax/types.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -483,11 +483,11 @@ Global Types
483483
Tag Types
484484
~~~~~~~~~
485485

486-
*Tag types* classify the signature of :ref:`tags <syntax-tag>` with a function type.
486+
*Tag types* classify the signature of :ref:`tags <syntax-tag>` with a defined type |deftype|, which expands to a function type |functype|.
487487

488488
.. math::
489489
\begin{array}{llll}
490-
\production{tag type} &\tagtype &::=& \functype \\
490+
\production{tag type} &\tagtype &::=& \deftype \\
491491
\end{array}
492492
493493
Currently tags are only used for categorizing exceptions.

document/core/valid/instructions.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2601,15 +2601,15 @@ Control Instructions
26012601

26022602
* The tag :math:`C.\CTAGS[x]` must be defined in the context.
26032603

2604-
* Let :math:`[t^\ast] \to [{t'}^\ast]` be the :ref:`tag type <syntax-tagtype>` :math:`C.\CTAGS[x]`.
2604+
* Let :math:`[t^\ast] \to [{t'}^\ast]` be the :ref:`expansion <aux-expand-deftype>` of the :ref:`tag type <syntax-tagtype>` :math:`C.\CTAGS[x]`.
26052605

26062606
* The :ref:`result type <syntax-resulttype>` :math:`[{t'}^\ast]` must be empty.
26072607

2608-
* Then the instruction is valid with type :math:`[t_1^\ast t^\ast] \to [t_2^\ast]`, for any sequences of :ref:`value types <syntax-valtype>` :math:`t_1^\ast` and :math:`t_2^\ast`.
2608+
* Then the instruction is valid with type :math:`[t_1^\ast t^\ast] \to [t_2^\ast]`, for any sequences of :ref:`value types <syntax-valtype>` :math:`t_1^\ast` and :math:`t_2^\ast`.
26092609

26102610
.. math::
26112611
\frac{
2612-
C.\CTAGS[x] = [t^\ast] \to []
2612+
\expanddt(C.\CTAGS[x]) = [t^\ast] \to []
26132613
}{
26142614
C \vdashinstr \THROW~x : [t_1^\ast~t^\ast] \to [t_2^\ast]
26152615
}

document/core/valid/matching.rst

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -580,14 +580,22 @@ A :ref:`global type <syntax-globaltype>` :math:`(\mut_1~t_1)` matches :math:`(\m
580580
Tag Types
581581
~~~~~~~~~
582582

583-
A :ref:`tag type <syntax-tagtype>` :math:`\tagtype_1` matches :math:`\tagtype_2` if and only if they are the same.
583+
A :ref:`tag type <syntax-tagtype>` :math:`\deftype_1` matches :math:`\deftype_2` if and only if the :ref:`defined type <syntax-deftype>` :math:`\deftype_1` :ref:`matches <match-deftype>` :math:`\deftype_2`, and vice versa.
584584

585585
.. math::
586586
\frac{
587+
C \vdashdeftypematch \deftype_1 \matchesdeftype \deftype_2
588+
\qquad
589+
C \vdashdeftypematch \deftype_2 \matchesdeftype \deftype_1
587590
}{
588-
C \vdashtagtypematch \tagtype \matchestagtype \tagtype
591+
C \vdashtagtypematch \deftype_1 \matchestagtype \deftype_2
589592
}
590593
594+
.. note::
595+
Although the conclusion of this rule looks identical to its premise,
596+
they in fact describe different relations:
597+
the premise invokes subtyping on defined types,
598+
while the conclusion defines it on tag types that happen to be expressed as defined types.
591599

592600
.. index:: external type, function type, table type, memory type, global type
593601
.. _match-externtype:

document/core/valid/types.rst

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -551,19 +551,25 @@ Memory Types
551551
Tag Types
552552
~~~~~~~~~
553553

554-
:math:`[t_1^n] \to [t_2^m]`
555-
...........................
554+
:math:`\deftype`
555+
................
556556

557-
* The :ref:`function type <syntax-functype>` :math:`[t_1^n] \to [t_2^m]` must be :ref:`valid <valid-functype>`.
557+
558+
* The :ref:`defined type <syntax-deftype>` :math:`\deftype` must be :ref:`valid <valid-deftype>`.
559+
560+
* The :ref:`expansion <aux-expand-deftype>` of :math:`\deftype` must be a :ref:`function type <syntax-functype>` :math:`\TFUNC~[t_1^n] \toF [t_2^m]`.
558561

559562
* The type sequence :math:`t_2^m` must be empty.
560563

561564
* Then the tag type is valid.
562565

563566
.. math::
564567
\frac{
568+
C \vdashdeftype \deftype \ok
569+
\qquad
570+
\expanddt(\deftype) = \TFUNC~[t^\ast] \to []
565571
}{
566-
\vdashtagtype [t^\ast] \to [] \ok
572+
C \vdashtagtype \deftype \ok
567573
}
568574
569575

interpreter/exec/eval.ml

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,8 @@ and admin_instr' =
7272
| Label of int * instr list * code
7373
| Frame of int * frame * code
7474
| Handler of int * catch list * code
75-
| Handle of handle_table * code
76-
| Suspending of tag_inst * value stack * ref_ option * ctxt
75+
| Prompt of handle_table * code
76+
| Suspending of tag_inst * value stack * (int32 * ref_) option * ctxt
7777

7878
and ctxt = code -> code
7979
and handle_table = (tag_inst * idx) list * tag_inst list
@@ -391,7 +391,7 @@ let rec step (c : config) : config =
391391
let hs = handle_table c xls in
392392
let args, vs' = i32_split n vs e.at in
393393
cont := None;
394-
vs', [Handle (hs, ctxt (args, [])) @@ e.at]
394+
vs', [Prompt (hs, ctxt (args, [])) @@ e.at]
395395

396396
| ResumeThrow (x, y, xls), Ref (NullRef _) :: vs ->
397397
vs, [Trapping "null continuation reference" @@ e.at]
@@ -405,18 +405,21 @@ let rec step (c : config) : config =
405405
let hs = handle_table c xls in
406406
let args, vs' = i32_split (Lib.List32.length ts) vs e.at in
407407
cont := None;
408-
vs', [Handle (hs, ctxt ([], [Throwing (tagt, args) @@ e.at])) @@ e.at]
408+
vs', [Prompt (hs, ctxt ([], [Throwing (tagt, args) @@ e.at])) @@ e.at]
409409

410410
| Switch (x, y), Ref (NullRef _) :: vs ->
411411
vs, [Trapping "null continuation reference" @@ e.at]
412412

413413
| Switch (x, y), Ref (ContRef {contents = None}) :: vs ->
414414
vs, [Trapping "continuation already consumed" @@ e.at]
415415

416-
| Switch (x, y), Ref (ContRef {contents = Some (n, ctxt)} as cont) :: vs ->
416+
| Switch (x, y), Ref (ContRef ({contents = Some (n, ctxt)} as cont)) :: vs ->
417+
let FuncT (ts, _) = func_type_of_cont_type c.frame.inst (cont_type c.frame.inst x) in
418+
let FuncT (ts', _) = as_cont_func_ref_type (Lib.List.last ts) in
419+
let arity = Lib.List32.length ts' in
417420
let tagt = tag c.frame.inst y in
418421
let args, vs' = i32_split (Int32.sub n 1l) vs e.at in
419-
vs', [Suspending (tagt, args, Some cont, fun code -> code) @@ e.at]
422+
vs', [Suspending (tagt, args, Some (arity, ContRef cont), fun code -> code) @@ e.at]
420423

421424
| ReturnCall x, vs ->
422425
(match (step {c with code = (vs, [Plain (Call x) @@ e.at])}).code with
@@ -1282,35 +1285,34 @@ let rec step (c : config) : config =
12821285
with Crash (_, msg) -> Crash.error e.at msg)
12831286
)
12841287

1285-
| Handle (hso, (vs', [])), vs ->
1288+
| Prompt (hso, (vs', [])), vs ->
12861289
vs' @ vs, []
12871290

1288-
| Handle ((hs, _), (vs', {it = Suspending (tagt, vs1, None, ctxt); at} :: es')), vs
1291+
| Prompt ((hs, _), (vs', {it = Suspending (tagt, vs1, None, ctxt); at} :: es')), vs
12891292
when List.mem_assq tagt hs ->
12901293
let FuncT (_, ts) = func_type_of_tag_type c.frame.inst (Tag.type_of tagt) in
12911294
let ctxt' code = compose (ctxt code) (vs', es') in
12921295
[Ref (ContRef (ref (Some (Lib.List32.length ts, ctxt'))))] @ vs1 @ vs,
12931296
[Plain (Br (List.assq tagt hs)) @@ e.at]
12941297

1295-
| Handle ((_, hs) as hso, (vs', {it = Suspending (tagt, vs1, Some (ContRef ({contents = Some (_, ctxt)} as cont)), ctxt'); at} :: es')), vs
1298+
| Prompt ((_, hs) as hso, (vs', {it = Suspending (tagt, vs1, Some (ar, ContRef ({contents = Some (_, ctxt)} as cont)), ctxt'); at} :: es')), vs
12961299
when List.memq tagt hs ->
1297-
let FuncT (_, ts) = func_type_of_tag_type c.frame.inst (Tag.type_of tagt) in
12981300
let ctxt'' code = compose (ctxt' code) (vs', es') in
1299-
let cont' = Ref (ContRef (ref (Some (Int32.add (Lib.List32.length ts) 1l, ctxt'')))) in
1301+
let cont' = Ref (ContRef (ref (Some (ar, ctxt'')))) in
13001302
let args = cont' :: vs1 in
13011303
cont := None;
1302-
vs' @ vs, [Handle (hso, ctxt (args, [])) @@ e.at]
1304+
vs' @ vs, [Prompt (hso, ctxt (args, [])) @@ e.at]
13031305

1304-
| Handle (hso, (vs', {it = Suspending (tagt, vs1, contref, ctxt); at} :: es')), vs ->
1305-
let ctxt' code = [], [Handle (hso, compose (ctxt code) (vs', es')) @@ e.at] in
1306+
| Prompt (hso, (vs', {it = Suspending (tagt, vs1, contref, ctxt); at} :: es')), vs ->
1307+
let ctxt' code = [], [Prompt (hso, compose (ctxt code) (vs', es')) @@ e.at] in
13061308
vs, [Suspending (tagt, vs1, contref, ctxt') @@ at]
13071309

1308-
| Handle (hso, (vs', e' :: es')), vs when is_jumping e' ->
1310+
| Prompt (hso, (vs', e' :: es')), vs when is_jumping e' ->
13091311
vs, [e']
13101312

1311-
| Handle (hso, code'), vs ->
1313+
| Prompt (hso, code'), vs ->
13121314
let c' = step {c with code = code'} in
1313-
vs, [Handle (hso, c'.code) @@ e.at]
1315+
vs, [Prompt (hso, c'.code) @@ e.at]
13141316

13151317
| Suspending (_, _, _, _), _ -> assert false
13161318

interpreter/syntax/types.ml

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -114,18 +114,6 @@ let defaultable = function
114114
| BotT -> assert false
115115

116116

117-
(* Conversions & Projections *)
118-
119-
let num_type_of_addr_type = function
120-
| I32AT -> I32T
121-
| I64AT -> I64T
122-
123-
let addr_type_of_num_type = function
124-
| I32T -> I32AT
125-
| I64T -> I64AT
126-
| _ -> assert false
127-
128-
129117
(* Filters *)
130118

131119
let funcs = List.filter_map (function ExternFuncT ft -> Some ft | _ -> None)
@@ -283,14 +271,29 @@ let expand_def_type (dt : def_type) : str_type =
283271
let SubT (_, _, st) = unroll_def_type dt in
284272
st
285273

286-
(* Projections *)
274+
275+
(* Conversions & Projections *)
276+
277+
let num_type_of_addr_type = function
278+
| I32AT -> I32T
279+
| I64AT -> I64T
280+
281+
let addr_type_of_num_type = function
282+
| I32T -> I32AT
283+
| I64T -> I64AT
284+
| _ -> assert false
287285

288286
let unpacked_storage_type = function
289287
| ValStorageT t -> t
290288
| PackStorageT _ -> NumT I32T
291289

292290
let unpacked_field_type (FieldT (_mut, t)) = unpacked_storage_type t
293291

292+
let as_def_heap_type (ht : heap_type) : def_type =
293+
match ht with
294+
| DefHT def -> def
295+
| _ -> assert false
296+
294297
let as_func_str_type (st : str_type) : func_type =
295298
match st with
296299
| DefFuncT ft -> ft
@@ -311,10 +314,18 @@ let as_array_str_type (st : str_type) : array_type =
311314
| DefArrayT at -> at
312315
| _ -> assert false
313316

317+
let as_cont_func_heap_type (ht : heap_type) : func_type =
318+
let ContT ht' = as_cont_str_type (expand_def_type (as_def_heap_type ht)) in
319+
as_func_str_type (expand_def_type (as_def_heap_type ht'))
320+
321+
let as_cont_func_ref_type (rt : val_type) : func_type =
322+
match rt with
323+
| RefT (_, ht) -> as_cont_func_heap_type ht
324+
| _ -> assert false
325+
314326
let extern_type_of_import_type (ImportT (et, _, _)) = et
315327
let extern_type_of_export_type (ExportT (et, _)) = et
316328

317-
318329
(* String conversion *)
319330

320331
let string_of_idx x =

0 commit comments

Comments
 (0)