Skip to content

Commit

Permalink
[interpreter] Add boilerplate for ref.exn result patterns
Browse files Browse the repository at this point in the history
  • Loading branch information
rossberg committed Oct 14, 2023
1 parent 512ddf1 commit 620e80a
Show file tree
Hide file tree
Showing 5 changed files with 20 additions and 14 deletions.
26 changes: 13 additions & 13 deletions interpreter/exec/eval.ml
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ and admin_instr' =
| Throwing of Tag.t * value stack
| Label of int32 * instr list * code
| Frame of int32 * frame * code
| Handle of int32 * catch list * code
| Handler of int32 * catch list * code

type config =
{
Expand Down Expand Up @@ -244,7 +244,7 @@ let rec step (c : config) : config =
let n1 = Lib.List32.length ts1 in
let n2 = Lib.List32.length ts2 in
let args, vs' = take n1 vs e.at, drop n1 vs e.at in
vs', [Handle (n2, cs, (args, [Label (n2, [], ([], List.map plain es')) @@ e.at])) @@ e.at]
vs', [Handler (n2, cs, (args, [Label (n2, [], ([], List.map plain es')) @@ e.at])) @@ e.at]

| Drop, v :: vs' ->
vs', []
Expand Down Expand Up @@ -691,36 +691,36 @@ let rec step (c : config) : config =
let c' = step {frame = frame'; code = code'; budget = c.budget - 1} in
vs, [Frame (n, c'.frame, c'.code) @@ e.at]

| Handle (n, cs, (vs', [])), vs ->
| Handler (n, cs, (vs', [])), vs ->
vs' @ vs, []

| Handle (n, cs, (vs', ({it = Trapping _ | Breaking _ | Returning _ | ReturningInvoke _; at} as e) :: es')), vs ->
| Handler (n, cs, (vs', ({it = Trapping _ | Breaking _ | Returning _ | ReturningInvoke _; at} as e) :: es')), vs ->
vs, [e]

| Handle (n, {it = Catch (x1, x2); _} :: cs, (vs', {it = Throwing (a, vs0); at} :: es')), vs ->
| Handler (n, {it = Catch (x1, x2); _} :: cs, (vs', {it = Throwing (a, vs0); at} :: es')), vs ->
if a == tag frame.inst x1 then
vs0 @ vs, [Plain (Br x2) @@ e.at]
else
vs, [Handle (n, cs, (vs', {it = Throwing (a, vs0); at} :: es')) @@ e.at]
vs, [Handler (n, cs, (vs', {it = Throwing (a, vs0); at} :: es')) @@ e.at]

| Handle (n, {it = CatchRef (x1, x2); _} :: cs, (vs', {it = Throwing (a, vs0); at} :: es')), vs ->
| Handler (n, {it = CatchRef (x1, x2); _} :: cs, (vs', {it = Throwing (a, vs0); at} :: es')), vs ->
if a == tag frame.inst x1 then
Ref (ExnRef (a, vs0)) :: vs0 @ vs, [Plain (Br x2) @@ e.at]
else
vs, [Handle (n, cs, (vs', {it = Throwing (a, vs0); at} :: es')) @@ e.at]
vs, [Handler (n, cs, (vs', {it = Throwing (a, vs0); at} :: es')) @@ e.at]

| Handle (n, {it = CatchAll x; _} :: cs, (vs', {it = Throwing (a, vs0); at} :: es')), vs ->
| Handler (n, {it = CatchAll x; _} :: cs, (vs', {it = Throwing (a, vs0); at} :: es')), vs ->
vs, [Plain (Br x) @@ e.at]

| Handle (n, {it = CatchAllRef x; _} :: cs, (vs', {it = Throwing (a, vs0); at} :: es')), vs ->
| Handler (n, {it = CatchAllRef x; _} :: cs, (vs', {it = Throwing (a, vs0); at} :: es')), vs ->
Ref (ExnRef (a, vs0)) :: vs, [Plain (Br x) @@ e.at]

| Handle (n, [], (vs', {it = Throwing (a, vs0); at} :: es')), vs ->
| Handler (n, [], (vs', {it = Throwing (a, vs0); at} :: es')), vs ->
vs, [Throwing (a, vs0) @@ at]

| Handle (n, cs, code'), vs ->
| Handler (n, cs, code'), vs ->
let c' = step {c with code = code'} in
vs, [Handle (n, cs, c'.code) @@ e.at]
vs, [Handler (n, cs, c'.code) @@ e.at]

| Invoke func, vs when c.budget = 0 ->
Exhaustion.error e.at "call stack exhausted"
Expand Down
1 change: 1 addition & 0 deletions interpreter/script/run.ml
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,7 @@ let assert_ref_pat r p =
match r, p with
| r, RefPat r' -> r = r'.it
| Instance.FuncRef _, RefTypePat Types.FuncRefType
| Values.ExnRef _, RefTypePat Types.ExnRefType
| ExternRef _, RefTypePat Types.ExternRefType -> true
| _ -> false

Expand Down
1 change: 1 addition & 0 deletions interpreter/text/lexer.mll
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,7 @@ rule token = parse

| "ref.null" -> REF_NULL
| "ref.func" -> REF_FUNC
| "ref.exn" -> REF_EXN
| "ref.extern" -> REF_EXTERN
| "ref.is_null" -> REF_IS_NULL

Expand Down
3 changes: 2 additions & 1 deletion interpreter/text/parser.mly
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ let inline_type_explicit (c : context) x ft at =
%token<string> OFFSET_EQ_NAT ALIGN_EQ_NAT
%token<string Source.phrase -> Ast.instr' * Values.num> CONST
%token<Ast.instr'> UNARY BINARY TEST COMPARE CONVERT
%token REF_NULL REF_FUNC REF_EXTERN REF_IS_NULL
%token REF_NULL REF_FUNC REF_EXN REF_EXTERN REF_IS_NULL
%token<int option -> Memory.offset -> Ast.instr'> VEC_LOAD VEC_STORE
%token<int option -> Memory.offset -> int -> Ast.instr'> VEC_LOAD_LANE VEC_STORE_LANE
%token<V128.shape -> string Source.phrase list -> Source.region -> Ast.instr' * Values.vec> VEC_CONST
Expand Down Expand Up @@ -1260,6 +1260,7 @@ result :
| LPAR CONST NAN RPAR { NumResult (NanPat (nanop $2 ($3 @@ ati 3))) @@ at () }
| literal_ref { RefResult (RefPat ($1 @@ at ())) @@ at () }
| LPAR REF_FUNC RPAR { RefResult (RefTypePat FuncRefType) @@ at () }
/*| LPAR REF_EXN RPAR { RefResult (RefTypePat ExnRefType) @@ at () }*/
| LPAR REF_EXTERN RPAR { RefResult (RefTypePat ExternRefType) @@ at () }
| LPAR VEC_CONST VEC_SHAPE numpat_list RPAR {
if V128.num_lanes $3 <> List.length $4 then
Expand Down
3 changes: 3 additions & 0 deletions test/core/ref_null.wast
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
(module
(func (export "externref") (result externref) (ref.null extern))
(func (export "exnref") (result exnref) (ref.null exn))
(func (export "funcref") (result funcref) (ref.null func))

(global externref (ref.null extern))
(global exnref (ref.null exn))
(global funcref (ref.null func))
)

(assert_return (invoke "externref") (ref.null extern))
(assert_return (invoke "exnref") (ref.null exn))
(assert_return (invoke "funcref") (ref.null func))

0 comments on commit 620e80a

Please sign in to comment.