diff --git a/spectec/spec/wasm-3.0/8-reduction.watsup b/spectec/spec/wasm-3.0/8-reduction.watsup index d62f4bae03..dd07ba012c 100644 --- a/spectec/spec/wasm-3.0/8-reduction.watsup +++ b/spectec/spec/wasm-3.0/8-reduction.watsup @@ -184,6 +184,9 @@ rule Step_read/return_call: rule Step_read/return_call_ref-label: z; (LABEL_ k `{instr'*} val* (RETURN_CALL_REF yy) instr*) ~> val* (RETURN_CALL_REF yy) +rule Step_read/return_call_ref-handler: + z; (HANDLER_ k `{catch*} val* (RETURN_CALL_REF yy) instr*) ~> val* (RETURN_CALL_REF yy) + rule Step_read/return_call_ref-frame-null: z; (FRAME_ k `{f} val* (REF.NULL ht) (RETURN_CALL_REF yy) instr*) ~> TRAP diff --git a/spectec/src/al/al_util.ml b/spectec/src/al/al_util.ml index 84d71ef51f..b6d5e520ff 100644 --- a/spectec/src/al/al_util.ml +++ b/spectec/src/al/al_util.ml @@ -191,6 +191,10 @@ let unwrap_listv: value -> value growable_array = function let unwrap_listv_to_array (v: value): value array = !(unwrap_listv v) let unwrap_listv_to_list (v: value): value list = unwrap_listv_to_array v |> Array.to_list +let unwrap_seq_to_array: value -> value array = function + | OptV opt -> opt |> Option.to_list |> Array.of_list + | v -> unwrap_listv_to_array v + let unwrap_textv: value -> string = function | TextV str -> str | v -> fail_value "unwrap_textv" v diff --git a/spectec/src/backend-interpreter/exception.ml b/spectec/src/backend-interpreter/exception.ml index d8013ec3d4..32a81e3510 100644 --- a/spectec/src/backend-interpreter/exception.ml +++ b/spectec/src/backend-interpreter/exception.ml @@ -1,4 +1,5 @@ exception Trap +exception Throw exception OutOfMemory exception Timeout exception MissingReturnValue of string diff --git a/spectec/src/backend-interpreter/interpreter.ml b/spectec/src/backend-interpreter/interpreter.ml index 2d4e9492a6..c27c7d454a 100644 --- a/spectec/src/backend-interpreter/interpreter.ml +++ b/spectec/src/backend-interpreter/interpreter.ml @@ -248,8 +248,8 @@ and eval_expr env expr = (* TODO: interpret CompE *) raise (Exception.MissingReturnValue "CompE") *) | CatE (e1, e2) -> - let a1 = eval_expr env e1 |> unwrap_listv_to_array in - let a2 = eval_expr env e2 |> unwrap_listv_to_array in + let a1 = eval_expr env e1 |> unwrap_seq_to_array in + let a2 = eval_expr env e2 |> unwrap_seq_to_array in Array.append a1 a2 |> listV | LenE e -> eval_expr env e |> unwrap_listv_to_array |> Array.length |> Z.of_int |> numV @@ -609,6 +609,7 @@ and step_instr (fname: string) (ctx: AlContext.t) (env: value Env.t) (instr: ins call_func f args |> ignore; ctx | TrapI -> raise Exception.Trap + | ThrowI _ -> raise Exception.Throw | NopI -> ctx | ReturnI None -> AlContext.tl ctx | ReturnI (Some e) -> diff --git a/spectec/src/backend-interpreter/runner.ml b/spectec/src/backend-interpreter/runner.ml index a555fa10f6..2889832c7b 100644 --- a/spectec/src/backend-interpreter/runner.ml +++ b/spectec/src/backend-interpreter/runner.ml @@ -9,6 +9,7 @@ open Ds (* Errors *) +module Assert = Reference_interpreter.Error.Make () let error_interpret at msg = Error.error at "interpreter" msg (* Logging *) @@ -170,6 +171,11 @@ let test_assertion assertion = fail with Exception.Trap -> success ) + | AssertException action -> ( + match run_action action with + | exception Exception.Throw -> success + | _ -> Assert.error assertion.at "expected exception" + ) (* ignore other kinds of assertions *) | _ -> pass diff --git a/spectec/src/il2al/manual.ml b/spectec/src/il2al/manual.ml index 3d430140d0..a9c649fd20 100644 --- a/spectec/src/il2al/manual.ml +++ b/spectec/src/il2al/manual.ml @@ -36,14 +36,15 @@ let manual_algos = [eval_expr] let return_instrs_of_instantiate config = let store, frame, rhs = config in + let vals, instrs = rhs in let ty = listT admininstrT in let ty' = varT "moduleinst" [] in let ty'' = Il.Ast.TupT (List.map (fun t -> no_name, t) [store.note; ty']) $ no_region in [ enterI ( frameE (Some (numE Z.zero ~note:natT), frame) ~note:callframeT, - listE ([ caseE ([[atom_of_name "FRAME_" "admininstr"]], []) ~note:admininstrT]) ~note:ty, - rhs + catE (instrs, (listE [caseE ([[atom_of_name "FRAME_" "admininstr"]], []) ~note:admininstrT] ~note:ty)) ~note:ty, + vals ); returnI (Some (tupE [ store; @@ -52,6 +53,7 @@ let return_instrs_of_instantiate config = ] let return_instrs_of_invoke config = let _, frame, rhs = config in + let vals, instrs = rhs in let arity = varE "k" ~note:natT in let value = varE "val" ~note:valT in let ty = listT admininstrT in @@ -64,8 +66,8 @@ let return_instrs_of_invoke config = letI (arity, len_expr); enterI ( frameE (Some (arity), frame) ~note:callframeT, - listE ([caseE ([[atom_of_name "FRAME_" "admininstr"]], []) ~note:admininstrT]) ~note:ty, - rhs + catE (instrs, listE [caseE ([[atom_of_name "FRAME_" "admininstr"]], []) ~note:admininstrT] ~note:ty) ~note:ty, + vals ); popI (iterE (value, ["val"], ListN (arity, None)) ~note:ty'); returnI (Some (iterE (value, ["val"], ListN (arity, None)) ~note:ty')) diff --git a/spectec/src/il2al/translate.ml b/spectec/src/il2al/translate.ml index 17ac527133..4f645804e7 100644 --- a/spectec/src/il2al/translate.ml +++ b/spectec/src/il2al/translate.ml @@ -150,6 +150,54 @@ let lhs_of_prem pr = | Il.LetPr (lhs, _, _) -> lhs | _ -> Error.error pr.at "prose translation" "expected a LetPr" +let rec is_wasm_value e = + (* TODO: use hint? *) + match e.it with + | Il.SubE (e, _, _) -> is_wasm_value e + | Il.CaseE ([{it = Atom id; _}]::_, _) when + List.mem id [ + "CONST"; + "VCONST"; + "REF.I31_NUM"; + "REF.STRUCT_ADDR"; + "REF.ARRAY_ADDR"; + "REF.EXN_ADDR"; + "REF.FUNC_ADDR"; + "REF.HOST_ADDR"; + "REF.EXTERN"; + "REF.NULL" + ] -> true + | Il.CallE (id, _) when id.it = "const" -> true + | _ -> Valid.sub_typ e.note valT +let is_wasm_instr e = + (* TODO: use hint? *) + Valid.sub_typ e.note instrT || Valid.sub_typ e.note admininstrT + +let split_vals (exp: Il.exp): Il.exp list * Il.exp list = + (* ASSUMPTION: exp is of the form v* i* *) + let rec spread_cat e = + match e.it with + | Il.CatE (e1, e2) -> spread_cat e1 @ spread_cat e2 + | Il.ListE es -> List.map (fun e' -> {e' with it = Il.ListE [e']; note = e.note}) es + | _ -> [e] + in + let is_wasm_values e = + match e.it with + | Il.IterE (e, _) -> is_wasm_value e + | Il.ListE es -> List.for_all is_wasm_value es + | _ -> false + in + + spread_cat exp + |> List.partition is_wasm_values + +let concat_exprs es = + match es with + | [] -> assert false + | hd :: tl -> List.fold_left (fun e1 e2 -> + catE (e1, e2) ~at:(over_region [e1.at; e2.at]) ~note:hd.note + ) hd tl + (** Translation *) (* `Il.iter` -> `iter` *) @@ -431,27 +479,9 @@ let rec translate_rhs exp = let instrs = translate_rhs inner_exp in List.map (walker.walk_instr walker) instrs (* Value *) - | _ when Valid.sub_typ exp.note valT -> [ pushI (translate_exp exp) ] - | Il.CaseE ([{it = Atom id; _}]::_, _) when List.mem id [ - (* TODO: Consider automating this *) - "CONST"; - "VCONST"; - "REF.I31_NUM"; - "REF.STRUCT_ADDR"; - "REF.ARRAY_ADDR"; - "REF.EXN_ADDR"; - "REF.FUNC_ADDR"; - "REF.HOST_ADDR"; - "REF.EXTERN"; - "REF.NULL" - ] -> [ pushI { (translate_exp exp) with note=valT } ~at:at ] - (* TODO: use hint *) - | Il.CallE (id, _) when id.it = "const" -> - [ pushI { (translate_exp exp) with note=valT } ~at:at ] + | _ when is_wasm_value exp -> [ pushI {(translate_exp exp) with note = valT} ] (* Instr *) - (* TODO: use hint *) - | _ when Valid.sub_typ exp.note instrT || Valid.sub_typ exp.note admininstrT -> - [ executeI (translate_exp exp) ] + | _ when is_wasm_instr exp -> [ executeI (translate_exp exp) ] | _ -> error_exp exp "expression on rhs of reduction" and translate_context_rhs exp = @@ -989,13 +1019,21 @@ and translate_prem prem = let translate_prems = List.fold_right (fun prem il -> translate_prem prem |> insert_instrs il) -(* s; f; e -> `expr * expr * instr list` *) +(* s; f; e -> `expr * expr * instr list * expr list` *) let get_config_return_instrs name exp at = assert(is_config exp); let state, rhs = split_config exp in let store, f = split_state state in - - let config = translate_exp store, translate_exp f, translate_rhs rhs in + let vals, instrs = split_vals rhs in + + let config = + translate_exp store, + translate_exp f, + ( + List.concat_map translate_rhs vals, + List.map translate_exp instrs |> concat_exprs + ) + in (* HARDCODE: hardcoding required for config returning helper functions *) match name with | "instantiate" -> Manual.return_instrs_of_instantiate config @@ -1215,6 +1253,7 @@ let rec translate_rgroup' instr_name rgroup = | _ -> assert false ) pops in let u_group = Il2il.unify_ctxt popped_vars subgroup in + let pops, u_group = extract_pops u_group in let ctxt = extract_context (List.hd u_group) |> Option.get in let atom = case_of_case ctxt |> List.hd |> List.hd in let cond = ContextKindE atom $$ atom.at % boolT in @@ -1224,7 +1263,8 @@ let rec translate_rgroup' instr_name rgroup = List.map (translate_reduction ~context_opt:(Some middle_instr)) u_group (* TODO: Consider inserting otherwise to normal case also *) |> List.mapi (fun i instrs -> if i = 0 || is_otherwise instrs then instrs else [otherwiseI instrs]) - |> Transpile.merge_blocks in + |> Transpile.merge_blocks + |> translate_prems pops in k, [ ifI ( cond, diff --git a/spectec/test-frontend/TEST.md b/spectec/test-frontend/TEST.md index a8cd922ca9..1a2851221a 100644 --- a/spectec/test-frontend/TEST.md +++ b/spectec/test-frontend/TEST.md @@ -5797,6 +5797,10 @@ relation Step_read: `%~>%`(config, instr*) rule return_call_ref-label{z : state, k : nat, instr'* : instr*, val* : val*, yy : typeuse, instr* : instr*}: `%~>%`(`%;%`_config(z, [`LABEL_%{%}%`_instr(k, instr'*{instr' : instr}, (val : val <: instr)*{val : val} :: [RETURN_CALL_REF_instr(yy)] :: instr*{instr : instr})]), (val : val <: instr)*{val : val} :: [RETURN_CALL_REF_instr(yy)]) + ;; 8-reduction.watsup + rule return_call_ref-handler{z : state, k : nat, catch* : catch*, val* : val*, yy : typeuse, instr* : instr*}: + `%~>%`(`%;%`_config(z, [`HANDLER_%{%}%`_instr(k, catch*{catch : catch}, (val : val <: instr)*{val : val} :: [RETURN_CALL_REF_instr(yy)] :: instr*{instr : instr})]), (val : val <: instr)*{val : val} :: [RETURN_CALL_REF_instr(yy)]) + ;; 8-reduction.watsup rule return_call_ref-frame-null{z : state, k : nat, f : frame, val* : val*, ht : heaptype, yy : typeuse, instr* : instr*}: `%~>%`(`%;%`_config(z, [`FRAME_%{%}%`_instr(k, f, (val : val <: instr)*{val : val} :: [REF.NULL_instr(ht)] :: [RETURN_CALL_REF_instr(yy)] :: instr*{instr : instr})]), [TRAP_instr]) @@ -6295,142 +6299,142 @@ relation Step: `%~>%`(config, config) `%~>%`(`%;%`_config(z, instr*{instr : instr}), `%;%`_config(z, instr'*{instr' : instr})) -- Step_read: `%~>%`(`%;%`_config(z, instr*{instr : instr}), instr'*{instr' : instr}) - ;; 8-reduction.watsup:218.1-223.49 + ;; 8-reduction.watsup:221.1-226.49 rule throw{z : state, val^n : val^n, n : n, x : idx, exn : exninst, a : addr, t^n : valtype^n}: `%~>%`(`%;%`_config(z, (val : val <: instr)^n{val : val} :: [THROW_instr(x)]), `%;%`_config($add_exninst(z, [exn]), [REF.EXN_ADDR_instr(a) THROW_REF_instr])) -- Expand: `%~~%`($tag(z, x).TYPE_taginst, FUNC_comptype(`%->%`_functype(`%`_resulttype(t^n{t : valtype}), `%`_resulttype([])))) -- if (a = |$exninst(z)|) -- if (exn = {TAG $tagaddr(z)[x!`%`_idx.0], FIELDS val^n{val : val}}) - ;; 8-reduction.watsup:285.1-287.36 + ;; 8-reduction.watsup:288.1-290.36 rule ctxt-label{z : state, n : n, instr_0* : instr*, instr* : instr*, z' : state, instr'* : instr*}: `%~>%`(`%;%`_config(z, [`LABEL_%{%}%`_instr(n, instr_0*{instr_0 : instr}, instr*{instr : instr})]), `%;%`_config(z', [`LABEL_%{%}%`_instr(n, instr_0*{instr_0 : instr}, instr'*{instr' : instr})])) -- Step: `%~>%`(`%;%`_config(z, instr*{instr : instr}), `%;%`_config(z', instr'*{instr' : instr})) - ;; 8-reduction.watsup:289.1-291.44 + ;; 8-reduction.watsup:292.1-294.44 rule ctxt-frame{s : store, f : frame, n : n, f' : frame, instr* : instr*, s' : store, instr'* : instr*}: `%~>%`(`%;%`_config(`%;%`_state(s, f), [`FRAME_%{%}%`_instr(n, f', instr*{instr : instr})]), `%;%`_config(`%;%`_state(s', f), [`FRAME_%{%}%`_instr(n, f', instr'*{instr' : instr})])) -- Step: `%~>%`(`%;%`_config(`%;%`_state(s, f'), instr*{instr : instr}), `%;%`_config(`%;%`_state(s', f'), instr'*{instr' : instr})) - ;; 8-reduction.watsup:409.1-413.65 + ;; 8-reduction.watsup:412.1-416.65 rule struct.new{z : state, val^n : val^n, n : n, x : idx, si : structinst, a : addr, mut^n : mut^n, zt^n : storagetype^n}: `%~>%`(`%;%`_config(z, (val : val <: instr)^n{val : val} :: [STRUCT.NEW_instr(x)]), `%;%`_config($add_structinst(z, [si]), [REF.STRUCT_ADDR_instr(a)])) -- Expand: `%~~%`($type(z, x), STRUCT_comptype(`%`_structtype(`%%`_fieldtype(mut, zt)^n{mut : mut, zt : storagetype}))) -- if (a = |$structinst(z)|) -- if (si = {TYPE $type(z, x), FIELDS $packfield_(zt, val)^n{val : val, zt : storagetype}}) - ;; 8-reduction.watsup:429.1-430.53 + ;; 8-reduction.watsup:432.1-433.53 rule struct.set-null{z : state, ht : heaptype, val : val, x : idx, i : nat}: `%~>%`(`%;%`_config(z, [REF.NULL_instr(ht) (val : val <: instr) STRUCT.SET_instr(x, `%`_u32(i))]), `%;%`_config(z, [TRAP_instr])) - ;; 8-reduction.watsup:432.1-434.45 + ;; 8-reduction.watsup:435.1-437.45 rule struct.set-struct{z : state, a : addr, val : val, x : idx, i : nat, zt* : storagetype*, mut* : mut*}: `%~>%`(`%;%`_config(z, [REF.STRUCT_ADDR_instr(a) (val : val <: instr) STRUCT.SET_instr(x, `%`_u32(i))]), `%;%`_config($with_struct(z, a, i, $packfield_(zt*{zt : storagetype}[i], val)), [])) -- Expand: `%~~%`($type(z, x), STRUCT_comptype(`%`_structtype(`%%`_fieldtype(mut, zt)*{mut : mut, zt : storagetype}))) - ;; 8-reduction.watsup:447.1-452.65 + ;; 8-reduction.watsup:450.1-455.65 rule array.new_fixed{z : state, val^n : val^n, n : n, x : idx, ai : arrayinst, a : addr, mut : mut, zt : storagetype}: `%~>%`(`%;%`_config(z, (val : val <: instr)^n{val : val} :: [ARRAY.NEW_FIXED_instr(x, `%`_u32(n))]), `%;%`_config($add_arrayinst(z, [ai]), [REF.ARRAY_ADDR_instr(a)])) -- Expand: `%~~%`($type(z, x), ARRAY_comptype(`%%`_arraytype(mut, zt))) -- if ((a = |$arrayinst(z)|) /\ (ai = {TYPE $type(z, x), FIELDS $packfield_(zt, val)^n{val : val}})) - ;; 8-reduction.watsup:492.1-493.64 + ;; 8-reduction.watsup:495.1-496.64 rule array.set-null{z : state, ht : heaptype, i : nat, val : val, x : idx}: `%~>%`(`%;%`_config(z, [REF.NULL_instr(ht) CONST_instr(I32_numtype, `%`_num_(i)) (val : val <: instr) ARRAY.SET_instr(x)]), `%;%`_config(z, [TRAP_instr])) - ;; 8-reduction.watsup:495.1-497.39 + ;; 8-reduction.watsup:498.1-500.39 rule array.set-oob{z : state, a : addr, i : nat, val : val, x : idx}: `%~>%`(`%;%`_config(z, [REF.ARRAY_ADDR_instr(a) CONST_instr(I32_numtype, `%`_num_(i)) (val : val <: instr) ARRAY.SET_instr(x)]), `%;%`_config(z, [TRAP_instr])) -- if (i >= |$arrayinst(z)[a].FIELDS_arrayinst|) - ;; 8-reduction.watsup:499.1-502.43 + ;; 8-reduction.watsup:502.1-505.43 rule array.set-array{z : state, a : addr, i : nat, val : val, x : idx, zt : storagetype, mut : mut}: `%~>%`(`%;%`_config(z, [REF.ARRAY_ADDR_instr(a) CONST_instr(I32_numtype, `%`_num_(i)) (val : val <: instr) ARRAY.SET_instr(x)]), `%;%`_config($with_array(z, a, i, $packfield_(zt, val)), [])) -- Expand: `%~~%`($type(z, x), ARRAY_comptype(`%%`_arraytype(mut, zt))) - ;; 8-reduction.watsup:803.1-804.56 + ;; 8-reduction.watsup:806.1-807.56 rule local.set{z : state, val : val, x : idx}: `%~>%`(`%;%`_config(z, [(val : val <: instr) LOCAL.SET_instr(x)]), `%;%`_config($with_local(z, x, val), [])) - ;; 8-reduction.watsup:816.1-817.58 + ;; 8-reduction.watsup:819.1-820.58 rule global.set{z : state, val : val, x : idx}: `%~>%`(`%;%`_config(z, [(val : val <: instr) GLOBAL.SET_instr(x)]), `%;%`_config($with_global(z, x, val), [])) - ;; 8-reduction.watsup:830.1-832.33 + ;; 8-reduction.watsup:833.1-835.33 rule table.set-oob{z : state, i : nat, ref : ref, x : idx}: `%~>%`(`%;%`_config(z, [CONST_instr(I32_numtype, `%`_num_(i)) (ref : ref <: instr) TABLE.SET_instr(x)]), `%;%`_config(z, [TRAP_instr])) -- if (i >= |$table(z, x).REFS_tableinst|) - ;; 8-reduction.watsup:834.1-836.32 + ;; 8-reduction.watsup:837.1-839.32 rule table.set-val{z : state, i : nat, ref : ref, x : idx}: `%~>%`(`%;%`_config(z, [CONST_instr(I32_numtype, `%`_num_(i)) (ref : ref <: instr) TABLE.SET_instr(x)]), `%;%`_config($with_table(z, x, i, ref), [])) -- if (i < |$table(z, x).REFS_tableinst|) - ;; 8-reduction.watsup:844.1-847.46 + ;; 8-reduction.watsup:847.1-850.46 rule table.grow-succeed{z : state, ref : ref, n : n, x : idx, ti : tableinst}: `%~>%`(`%;%`_config(z, [(ref : ref <: instr) CONST_instr(I32_numtype, `%`_num_(n)) TABLE.GROW_instr(x)]), `%;%`_config($with_tableinst(z, x, ti), [CONST_instr(I32_numtype, `%`_num_(|$table(z, x).REFS_tableinst|))])) -- if (ti = $growtable($table(z, x), n, ref)) - ;; 8-reduction.watsup:849.1-850.81 + ;; 8-reduction.watsup:852.1-853.81 rule table.grow-fail{z : state, ref : ref, n : n, x : idx}: `%~>%`(`%;%`_config(z, [(ref : ref <: instr) CONST_instr(I32_numtype, `%`_num_(n)) TABLE.GROW_instr(x)]), `%;%`_config(z, [CONST_instr(I32_numtype, `%`_num_($invsigned_(32, - (1 : nat <: int))))])) - ;; 8-reduction.watsup:910.1-911.51 + ;; 8-reduction.watsup:913.1-914.51 rule elem.drop{z : state, x : idx}: `%~>%`(`%;%`_config(z, [ELEM.DROP_instr(x)]), `%;%`_config($with_elem(z, x, []), [])) - ;; 8-reduction.watsup:994.1-997.60 + ;; 8-reduction.watsup:997.1-1000.60 rule store-num-oob{z : state, i : nat, nt : numtype, c : num_(nt), x : idx, ao : memarg}: `%~>%`(`%;%`_config(z, [CONST_instr(I32_numtype, `%`_num_(i)) CONST_instr(nt, c) STORE_instr(nt, ?(), x, ao)]), `%;%`_config(z, [TRAP_instr])) -- if (((i + ao.OFFSET_memarg!`%`_u32.0) + ($size(nt) / 8)) > |$mem(z, x).BYTES_meminst|) - ;; 8-reduction.watsup:999.1-1003.29 + ;; 8-reduction.watsup:1002.1-1006.29 rule store-num-val{z : state, i : nat, nt : numtype, c : num_(nt), x : idx, ao : memarg, b* : byte*}: `%~>%`(`%;%`_config(z, [CONST_instr(I32_numtype, `%`_num_(i)) CONST_instr(nt, c) STORE_instr(nt, ?(), x, ao)]), `%;%`_config($with_mem(z, x, (i + ao.OFFSET_memarg!`%`_u32.0), ($size(nt) / 8), b*{b : byte}), [])) -- if (b*{b : byte} = $nbytes_(nt, c)) - ;; 8-reduction.watsup:1005.1-1008.52 + ;; 8-reduction.watsup:1008.1-1011.52 rule store-pack-oob{z : state, i : nat, Inn : Inn, c : num_((Inn : Inn <: numtype)), nt : numtype, n : n, x : idx, ao : memarg}: `%~>%`(`%;%`_config(z, [CONST_instr(I32_numtype, `%`_num_(i)) CONST_instr((Inn : Inn <: numtype), c) STORE_instr(nt, ?(`%`_sz(n)), x, ao)]), `%;%`_config(z, [TRAP_instr])) -- if (((i + ao.OFFSET_memarg!`%`_u32.0) + (n / 8)) > |$mem(z, x).BYTES_meminst|) - ;; 8-reduction.watsup:1010.1-1014.52 + ;; 8-reduction.watsup:1013.1-1017.52 rule store-pack-val{z : state, i : nat, Inn : Inn, c : num_((Inn : Inn <: numtype)), nt : numtype, n : n, x : idx, ao : memarg, b* : byte*}: `%~>%`(`%;%`_config(z, [CONST_instr(I32_numtype, `%`_num_(i)) CONST_instr((Inn : Inn <: numtype), c) STORE_instr(nt, ?(`%`_sz(n)), x, ao)]), `%;%`_config($with_mem(z, x, (i + ao.OFFSET_memarg!`%`_u32.0), (n / 8), b*{b : byte}), [])) -- if (b*{b : byte} = $ibytes_(n, $wrap__($size((Inn : Inn <: numtype)), n, c))) - ;; 8-reduction.watsup:1016.1-1018.63 + ;; 8-reduction.watsup:1019.1-1021.63 rule vstore-oob{z : state, i : nat, c : vec_(V128_Vnn), x : idx, ao : memarg}: `%~>%`(`%;%`_config(z, [CONST_instr(I32_numtype, `%`_num_(i)) VCONST_instr(V128_vectype, c) VSTORE_instr(V128_vectype, x, ao)]), `%;%`_config(z, [TRAP_instr])) -- if (((i + ao.OFFSET_memarg!`%`_u32.0) + ($vsize(V128_vectype) / 8)) > |$mem(z, x).BYTES_meminst|) - ;; 8-reduction.watsup:1020.1-1022.31 + ;; 8-reduction.watsup:1023.1-1025.31 rule vstore-val{z : state, i : nat, c : vec_(V128_Vnn), x : idx, ao : memarg, b* : byte*}: `%~>%`(`%;%`_config(z, [CONST_instr(I32_numtype, `%`_num_(i)) VCONST_instr(V128_vectype, c) VSTORE_instr(V128_vectype, x, ao)]), `%;%`_config($with_mem(z, x, (i + ao.OFFSET_memarg!`%`_u32.0), ($vsize(V128_vectype) / 8), b*{b : byte}), [])) -- if (b*{b : byte} = $vbytes_(V128_vectype, c)) - ;; 8-reduction.watsup:1025.1-1027.50 + ;; 8-reduction.watsup:1028.1-1030.50 rule vstore_lane-oob{z : state, i : nat, c : vec_(V128_Vnn), N : N, x : idx, ao : memarg, j : nat}: `%~>%`(`%;%`_config(z, [CONST_instr(I32_numtype, `%`_num_(i)) VCONST_instr(V128_vectype, c) VSTORE_LANE_instr(V128_vectype, `%`_sz(N), x, ao, `%`_laneidx(j))]), `%;%`_config(z, [TRAP_instr])) -- if (((i + ao.OFFSET_memarg!`%`_u32.0) + N) > |$mem(z, x).BYTES_meminst|) - ;; 8-reduction.watsup:1029.1-1033.49 + ;; 8-reduction.watsup:1032.1-1036.49 rule vstore_lane-val{z : state, i : nat, c : vec_(V128_Vnn), N : N, x : idx, ao : memarg, j : nat, b* : byte*, Jnn : Jnn, M : M}: `%~>%`(`%;%`_config(z, [CONST_instr(I32_numtype, `%`_num_(i)) VCONST_instr(V128_vectype, c) VSTORE_LANE_instr(V128_vectype, `%`_sz(N), x, ao, `%`_laneidx(j))]), `%;%`_config($with_mem(z, x, (i + ao.OFFSET_memarg!`%`_u32.0), (N / 8), b*{b : byte}), [])) -- if (N = $lsize((Jnn : Jnn <: lanetype))) -- if (M = (128 / N)) -- if (b*{b : byte} = $ibytes_(N, `%`_iN($lanes_(`%X%`_shape((Jnn : Jnn <: lanetype), `%`_dim(M)), c)[j]!`%`_lane_.0))) - ;; 8-reduction.watsup:1041.1-1044.37 + ;; 8-reduction.watsup:1044.1-1047.37 rule memory.grow-succeed{z : state, n : n, x : idx, mi : meminst}: `%~>%`(`%;%`_config(z, [CONST_instr(I32_numtype, `%`_num_(n)) MEMORY.GROW_instr(x)]), `%;%`_config($with_meminst(z, x, mi), [CONST_instr(I32_numtype, `%`_num_((|$mem(z, x).BYTES_meminst| / (64 * $Ki))))])) -- if (mi = $growmem($mem(z, x), n)) - ;; 8-reduction.watsup:1046.1-1047.78 + ;; 8-reduction.watsup:1049.1-1050.78 rule memory.grow-fail{z : state, n : n, x : idx}: `%~>%`(`%;%`_config(z, [CONST_instr(I32_numtype, `%`_num_(n)) MEMORY.GROW_instr(x)]), `%;%`_config(z, [CONST_instr(I32_numtype, `%`_num_($invsigned_(32, - (1 : nat <: int))))])) - ;; 8-reduction.watsup:1107.1-1108.51 + ;; 8-reduction.watsup:1110.1-1111.51 rule data.drop{z : state, x : idx}: `%~>%`(`%;%`_config(z, [DATA.DROP_instr(x)]), `%;%`_config($with_data(z, x, []), [])) } diff --git a/spectec/test-interpreter/TEST.md b/spectec/test-interpreter/TEST.md index 04a888864d..f59f2a955f 100644 --- a/spectec/test-interpreter/TEST.md +++ b/spectec/test-interpreter/TEST.md @@ -1398,10 +1398,10 @@ watsup 0.4 generator - 4/4 (100.00%) ===== ../../test-interpreter/spec-test-3/throw.wast ===== -- 3/3 (100.00%) +- 10/10 (100.00%) ===== ../../test-interpreter/spec-test-3/throw_ref.wast ===== -- 6/6 (100.00%) +- 13/13 (100.00%) ===== ../../test-interpreter/spec-test-3/token.wast ===== - 35/35 (100.00%) @@ -1410,7 +1410,7 @@ watsup 0.4 generator - 36/36 (100.00%) ===== ../../test-interpreter/spec-test-3/try_table.wast ===== -- 45/45 (100.00%) +- 49/49 (100.00%) ===== ../../test-interpreter/spec-test-3/type-canon.wast ===== - 2/2 (100.00%) @@ -1448,7 +1448,7 @@ watsup 0.4 generator ===== ../../test-interpreter/spec-test-3/utf8-invalid-encoding.wast ===== - 0/0 (100.00%) -Total [46963/46963] (100.00%) +Total [46981/46981] (100.00%) == Complete. ``` diff --git a/spectec/test-latex/TEST.md b/spectec/test-latex/TEST.md index 7dca496be6..53a6405158 100644 --- a/spectec/test-latex/TEST.md +++ b/spectec/test-latex/TEST.md @@ -8196,6 +8196,7 @@ $$ $$ \begin{array}{@{}l@{}rcl@{}l@{}} {[\textsc{\scriptsize E{-}return\_call\_ref{-}label}]} \quad & z ; ({{\mathsf{label}}_{k}}{\{ {{\mathit{instr}'}^\ast} \}}~{{\mathit{val}}^\ast}~(\mathsf{return\_call\_ref}~y)~{{\mathit{instr}}^\ast}) &\hookrightarrow& {{\mathit{val}}^\ast}~(\mathsf{return\_call\_ref}~y) \\ +{[\textsc{\scriptsize E{-}return\_call\_ref{-}handler}]} \quad & z ; ({{\mathsf{handler}}_{k}}{\{ {{\mathit{catch}}^\ast} \}}~{{\mathit{val}}^\ast}~(\mathsf{return\_call\_ref}~y)~{{\mathit{instr}}^\ast}) &\hookrightarrow& {{\mathit{val}}^\ast}~(\mathsf{return\_call\_ref}~y) \\ {[\textsc{\scriptsize E{-}return\_call\_ref{-}frame{-}null}]} \quad & z ; ({{\mathsf{frame}}_{k}}{\{ f \}}~{{\mathit{val}}^\ast}~(\mathsf{ref{.}null}~{\mathit{ht}})~(\mathsf{return\_call\_ref}~y)~{{\mathit{instr}}^\ast}) &\hookrightarrow& \mathsf{trap} \\ {[\textsc{\scriptsize E{-}return\_call\_ref{-}frame{-}addr}]} \quad & z ; ({{\mathsf{frame}}_{k}}{\{ f \}}~{{\mathit{val}'}^\ast}~{{\mathit{val}}^{n}}~(\mathsf{ref{.}func}~a)~(\mathsf{return\_call\_ref}~y)~{{\mathit{instr}}^\ast}) &\hookrightarrow& \multicolumn{2}{l@{}}{ {{\mathit{val}}^{n}}~(\mathsf{ref{.}func}~a)~(\mathsf{call\_ref}~y) } \\ &&& \multicolumn{2}{l@{}}{\quad \mbox{if}~z{.}\mathsf{funcs}{}[a]{.}\mathsf{type} \approx \mathsf{func}~({t_1^{n}} \rightarrow {t_2^{m}})} \\ diff --git a/spectec/test-middlend/TEST.md b/spectec/test-middlend/TEST.md index 0081c02325..15d6fce661 100644 --- a/spectec/test-middlend/TEST.md +++ b/spectec/test-middlend/TEST.md @@ -5787,6 +5787,10 @@ relation Step_read: `%~>%`(config, instr*) rule return_call_ref-label{z : state, k : nat, instr'* : instr*, val* : val*, yy : typeuse, instr* : instr*}: `%~>%`(`%;%`_config(z, [`LABEL_%{%}%`_instr(k, instr'*{instr' : instr}, (val : val <: instr)*{val : val} :: [RETURN_CALL_REF_instr(yy)] :: instr*{instr : instr})]), (val : val <: instr)*{val : val} :: [RETURN_CALL_REF_instr(yy)]) + ;; 8-reduction.watsup + rule return_call_ref-handler{z : state, k : nat, catch* : catch*, val* : val*, yy : typeuse, instr* : instr*}: + `%~>%`(`%;%`_config(z, [`HANDLER_%{%}%`_instr(k, catch*{catch : catch}, (val : val <: instr)*{val : val} :: [RETURN_CALL_REF_instr(yy)] :: instr*{instr : instr})]), (val : val <: instr)*{val : val} :: [RETURN_CALL_REF_instr(yy)]) + ;; 8-reduction.watsup rule return_call_ref-frame-null{z : state, k : nat, f : frame, val* : val*, ht : heaptype, yy : typeuse, instr* : instr*}: `%~>%`(`%;%`_config(z, [`FRAME_%{%}%`_instr(k, f, (val : val <: instr)*{val : val} :: [REF.NULL_instr(ht)] :: [RETURN_CALL_REF_instr(yy)] :: instr*{instr : instr})]), [TRAP_instr]) @@ -6285,142 +6289,142 @@ relation Step: `%~>%`(config, config) `%~>%`(`%;%`_config(z, instr*{instr : instr}), `%;%`_config(z, instr'*{instr' : instr})) -- Step_read: `%~>%`(`%;%`_config(z, instr*{instr : instr}), instr'*{instr' : instr}) - ;; 8-reduction.watsup:218.1-223.49 + ;; 8-reduction.watsup:221.1-226.49 rule throw{z : state, val^n : val^n, n : n, x : idx, exn : exninst, a : addr, t^n : valtype^n}: `%~>%`(`%;%`_config(z, (val : val <: instr)^n{val : val} :: [THROW_instr(x)]), `%;%`_config($add_exninst(z, [exn]), [REF.EXN_ADDR_instr(a) THROW_REF_instr])) -- Expand: `%~~%`($tag(z, x).TYPE_taginst, FUNC_comptype(`%->%`_functype(`%`_resulttype(t^n{t : valtype}), `%`_resulttype([])))) -- if (a = |$exninst(z)|) -- if (exn = {TAG $tagaddr(z)[x!`%`_idx.0], FIELDS val^n{val : val}}) - ;; 8-reduction.watsup:285.1-287.36 + ;; 8-reduction.watsup:288.1-290.36 rule ctxt-label{z : state, n : n, instr_0* : instr*, instr* : instr*, z' : state, instr'* : instr*}: `%~>%`(`%;%`_config(z, [`LABEL_%{%}%`_instr(n, instr_0*{instr_0 : instr}, instr*{instr : instr})]), `%;%`_config(z', [`LABEL_%{%}%`_instr(n, instr_0*{instr_0 : instr}, instr'*{instr' : instr})])) -- Step: `%~>%`(`%;%`_config(z, instr*{instr : instr}), `%;%`_config(z', instr'*{instr' : instr})) - ;; 8-reduction.watsup:289.1-291.44 + ;; 8-reduction.watsup:292.1-294.44 rule ctxt-frame{s : store, f : frame, n : n, f' : frame, instr* : instr*, s' : store, instr'* : instr*}: `%~>%`(`%;%`_config(`%;%`_state(s, f), [`FRAME_%{%}%`_instr(n, f', instr*{instr : instr})]), `%;%`_config(`%;%`_state(s', f), [`FRAME_%{%}%`_instr(n, f', instr'*{instr' : instr})])) -- Step: `%~>%`(`%;%`_config(`%;%`_state(s, f'), instr*{instr : instr}), `%;%`_config(`%;%`_state(s', f'), instr'*{instr' : instr})) - ;; 8-reduction.watsup:409.1-413.65 + ;; 8-reduction.watsup:412.1-416.65 rule struct.new{z : state, val^n : val^n, n : n, x : idx, si : structinst, a : addr, mut^n : mut^n, zt^n : storagetype^n}: `%~>%`(`%;%`_config(z, (val : val <: instr)^n{val : val} :: [STRUCT.NEW_instr(x)]), `%;%`_config($add_structinst(z, [si]), [REF.STRUCT_ADDR_instr(a)])) -- Expand: `%~~%`($type(z, x), STRUCT_comptype(`%`_structtype(`%%`_fieldtype(mut, zt)^n{mut : mut, zt : storagetype}))) -- if (a = |$structinst(z)|) -- if (si = {TYPE $type(z, x), FIELDS $packfield_(zt, val)^n{val : val, zt : storagetype}}) - ;; 8-reduction.watsup:429.1-430.53 + ;; 8-reduction.watsup:432.1-433.53 rule struct.set-null{z : state, ht : heaptype, val : val, x : idx, i : nat}: `%~>%`(`%;%`_config(z, [REF.NULL_instr(ht) (val : val <: instr) STRUCT.SET_instr(x, `%`_u32(i))]), `%;%`_config(z, [TRAP_instr])) - ;; 8-reduction.watsup:432.1-434.45 + ;; 8-reduction.watsup:435.1-437.45 rule struct.set-struct{z : state, a : addr, val : val, x : idx, i : nat, zt* : storagetype*, mut* : mut*}: `%~>%`(`%;%`_config(z, [REF.STRUCT_ADDR_instr(a) (val : val <: instr) STRUCT.SET_instr(x, `%`_u32(i))]), `%;%`_config($with_struct(z, a, i, $packfield_(zt*{zt : storagetype}[i], val)), [])) -- Expand: `%~~%`($type(z, x), STRUCT_comptype(`%`_structtype(`%%`_fieldtype(mut, zt)*{mut : mut, zt : storagetype}))) - ;; 8-reduction.watsup:447.1-452.65 + ;; 8-reduction.watsup:450.1-455.65 rule array.new_fixed{z : state, val^n : val^n, n : n, x : idx, ai : arrayinst, a : addr, mut : mut, zt : storagetype}: `%~>%`(`%;%`_config(z, (val : val <: instr)^n{val : val} :: [ARRAY.NEW_FIXED_instr(x, `%`_u32(n))]), `%;%`_config($add_arrayinst(z, [ai]), [REF.ARRAY_ADDR_instr(a)])) -- Expand: `%~~%`($type(z, x), ARRAY_comptype(`%%`_arraytype(mut, zt))) -- if ((a = |$arrayinst(z)|) /\ (ai = {TYPE $type(z, x), FIELDS $packfield_(zt, val)^n{val : val}})) - ;; 8-reduction.watsup:492.1-493.64 + ;; 8-reduction.watsup:495.1-496.64 rule array.set-null{z : state, ht : heaptype, i : nat, val : val, x : idx}: `%~>%`(`%;%`_config(z, [REF.NULL_instr(ht) CONST_instr(I32_numtype, `%`_num_(i)) (val : val <: instr) ARRAY.SET_instr(x)]), `%;%`_config(z, [TRAP_instr])) - ;; 8-reduction.watsup:495.1-497.39 + ;; 8-reduction.watsup:498.1-500.39 rule array.set-oob{z : state, a : addr, i : nat, val : val, x : idx}: `%~>%`(`%;%`_config(z, [REF.ARRAY_ADDR_instr(a) CONST_instr(I32_numtype, `%`_num_(i)) (val : val <: instr) ARRAY.SET_instr(x)]), `%;%`_config(z, [TRAP_instr])) -- if (i >= |$arrayinst(z)[a].FIELDS_arrayinst|) - ;; 8-reduction.watsup:499.1-502.43 + ;; 8-reduction.watsup:502.1-505.43 rule array.set-array{z : state, a : addr, i : nat, val : val, x : idx, zt : storagetype, mut : mut}: `%~>%`(`%;%`_config(z, [REF.ARRAY_ADDR_instr(a) CONST_instr(I32_numtype, `%`_num_(i)) (val : val <: instr) ARRAY.SET_instr(x)]), `%;%`_config($with_array(z, a, i, $packfield_(zt, val)), [])) -- Expand: `%~~%`($type(z, x), ARRAY_comptype(`%%`_arraytype(mut, zt))) - ;; 8-reduction.watsup:803.1-804.56 + ;; 8-reduction.watsup:806.1-807.56 rule local.set{z : state, val : val, x : idx}: `%~>%`(`%;%`_config(z, [(val : val <: instr) LOCAL.SET_instr(x)]), `%;%`_config($with_local(z, x, val), [])) - ;; 8-reduction.watsup:816.1-817.58 + ;; 8-reduction.watsup:819.1-820.58 rule global.set{z : state, val : val, x : idx}: `%~>%`(`%;%`_config(z, [(val : val <: instr) GLOBAL.SET_instr(x)]), `%;%`_config($with_global(z, x, val), [])) - ;; 8-reduction.watsup:830.1-832.33 + ;; 8-reduction.watsup:833.1-835.33 rule table.set-oob{z : state, i : nat, ref : ref, x : idx}: `%~>%`(`%;%`_config(z, [CONST_instr(I32_numtype, `%`_num_(i)) (ref : ref <: instr) TABLE.SET_instr(x)]), `%;%`_config(z, [TRAP_instr])) -- if (i >= |$table(z, x).REFS_tableinst|) - ;; 8-reduction.watsup:834.1-836.32 + ;; 8-reduction.watsup:837.1-839.32 rule table.set-val{z : state, i : nat, ref : ref, x : idx}: `%~>%`(`%;%`_config(z, [CONST_instr(I32_numtype, `%`_num_(i)) (ref : ref <: instr) TABLE.SET_instr(x)]), `%;%`_config($with_table(z, x, i, ref), [])) -- if (i < |$table(z, x).REFS_tableinst|) - ;; 8-reduction.watsup:844.1-847.46 + ;; 8-reduction.watsup:847.1-850.46 rule table.grow-succeed{z : state, ref : ref, n : n, x : idx, ti : tableinst}: `%~>%`(`%;%`_config(z, [(ref : ref <: instr) CONST_instr(I32_numtype, `%`_num_(n)) TABLE.GROW_instr(x)]), `%;%`_config($with_tableinst(z, x, ti), [CONST_instr(I32_numtype, `%`_num_(|$table(z, x).REFS_tableinst|))])) -- if (ti = $growtable($table(z, x), n, ref)) - ;; 8-reduction.watsup:849.1-850.81 + ;; 8-reduction.watsup:852.1-853.81 rule table.grow-fail{z : state, ref : ref, n : n, x : idx}: `%~>%`(`%;%`_config(z, [(ref : ref <: instr) CONST_instr(I32_numtype, `%`_num_(n)) TABLE.GROW_instr(x)]), `%;%`_config(z, [CONST_instr(I32_numtype, `%`_num_($invsigned_(32, - (1 : nat <: int))))])) - ;; 8-reduction.watsup:910.1-911.51 + ;; 8-reduction.watsup:913.1-914.51 rule elem.drop{z : state, x : idx}: `%~>%`(`%;%`_config(z, [ELEM.DROP_instr(x)]), `%;%`_config($with_elem(z, x, []), [])) - ;; 8-reduction.watsup:994.1-997.60 + ;; 8-reduction.watsup:997.1-1000.60 rule store-num-oob{z : state, i : nat, nt : numtype, c : num_(nt), x : idx, ao : memarg}: `%~>%`(`%;%`_config(z, [CONST_instr(I32_numtype, `%`_num_(i)) CONST_instr(nt, c) STORE_instr(nt, ?(), x, ao)]), `%;%`_config(z, [TRAP_instr])) -- if (((i + ao.OFFSET_memarg!`%`_u32.0) + ($size(nt) / 8)) > |$mem(z, x).BYTES_meminst|) - ;; 8-reduction.watsup:999.1-1003.29 + ;; 8-reduction.watsup:1002.1-1006.29 rule store-num-val{z : state, i : nat, nt : numtype, c : num_(nt), x : idx, ao : memarg, b* : byte*}: `%~>%`(`%;%`_config(z, [CONST_instr(I32_numtype, `%`_num_(i)) CONST_instr(nt, c) STORE_instr(nt, ?(), x, ao)]), `%;%`_config($with_mem(z, x, (i + ao.OFFSET_memarg!`%`_u32.0), ($size(nt) / 8), b*{b : byte}), [])) -- if (b*{b : byte} = $nbytes_(nt, c)) - ;; 8-reduction.watsup:1005.1-1008.52 + ;; 8-reduction.watsup:1008.1-1011.52 rule store-pack-oob{z : state, i : nat, Inn : Inn, c : num_((Inn : Inn <: numtype)), nt : numtype, n : n, x : idx, ao : memarg}: `%~>%`(`%;%`_config(z, [CONST_instr(I32_numtype, `%`_num_(i)) CONST_instr((Inn : Inn <: numtype), c) STORE_instr(nt, ?(`%`_sz(n)), x, ao)]), `%;%`_config(z, [TRAP_instr])) -- if (((i + ao.OFFSET_memarg!`%`_u32.0) + (n / 8)) > |$mem(z, x).BYTES_meminst|) - ;; 8-reduction.watsup:1010.1-1014.52 + ;; 8-reduction.watsup:1013.1-1017.52 rule store-pack-val{z : state, i : nat, Inn : Inn, c : num_((Inn : Inn <: numtype)), nt : numtype, n : n, x : idx, ao : memarg, b* : byte*}: `%~>%`(`%;%`_config(z, [CONST_instr(I32_numtype, `%`_num_(i)) CONST_instr((Inn : Inn <: numtype), c) STORE_instr(nt, ?(`%`_sz(n)), x, ao)]), `%;%`_config($with_mem(z, x, (i + ao.OFFSET_memarg!`%`_u32.0), (n / 8), b*{b : byte}), [])) -- if (b*{b : byte} = $ibytes_(n, $wrap__($size((Inn : Inn <: numtype)), n, c))) - ;; 8-reduction.watsup:1016.1-1018.63 + ;; 8-reduction.watsup:1019.1-1021.63 rule vstore-oob{z : state, i : nat, c : vec_(V128_Vnn), x : idx, ao : memarg}: `%~>%`(`%;%`_config(z, [CONST_instr(I32_numtype, `%`_num_(i)) VCONST_instr(V128_vectype, c) VSTORE_instr(V128_vectype, x, ao)]), `%;%`_config(z, [TRAP_instr])) -- if (((i + ao.OFFSET_memarg!`%`_u32.0) + ($vsize(V128_vectype) / 8)) > |$mem(z, x).BYTES_meminst|) - ;; 8-reduction.watsup:1020.1-1022.31 + ;; 8-reduction.watsup:1023.1-1025.31 rule vstore-val{z : state, i : nat, c : vec_(V128_Vnn), x : idx, ao : memarg, b* : byte*}: `%~>%`(`%;%`_config(z, [CONST_instr(I32_numtype, `%`_num_(i)) VCONST_instr(V128_vectype, c) VSTORE_instr(V128_vectype, x, ao)]), `%;%`_config($with_mem(z, x, (i + ao.OFFSET_memarg!`%`_u32.0), ($vsize(V128_vectype) / 8), b*{b : byte}), [])) -- if (b*{b : byte} = $vbytes_(V128_vectype, c)) - ;; 8-reduction.watsup:1025.1-1027.50 + ;; 8-reduction.watsup:1028.1-1030.50 rule vstore_lane-oob{z : state, i : nat, c : vec_(V128_Vnn), N : N, x : idx, ao : memarg, j : nat}: `%~>%`(`%;%`_config(z, [CONST_instr(I32_numtype, `%`_num_(i)) VCONST_instr(V128_vectype, c) VSTORE_LANE_instr(V128_vectype, `%`_sz(N), x, ao, `%`_laneidx(j))]), `%;%`_config(z, [TRAP_instr])) -- if (((i + ao.OFFSET_memarg!`%`_u32.0) + N) > |$mem(z, x).BYTES_meminst|) - ;; 8-reduction.watsup:1029.1-1033.49 + ;; 8-reduction.watsup:1032.1-1036.49 rule vstore_lane-val{z : state, i : nat, c : vec_(V128_Vnn), N : N, x : idx, ao : memarg, j : nat, b* : byte*, Jnn : Jnn, M : M}: `%~>%`(`%;%`_config(z, [CONST_instr(I32_numtype, `%`_num_(i)) VCONST_instr(V128_vectype, c) VSTORE_LANE_instr(V128_vectype, `%`_sz(N), x, ao, `%`_laneidx(j))]), `%;%`_config($with_mem(z, x, (i + ao.OFFSET_memarg!`%`_u32.0), (N / 8), b*{b : byte}), [])) -- if (N = $lsize((Jnn : Jnn <: lanetype))) -- if (M = (128 / N)) -- if (b*{b : byte} = $ibytes_(N, `%`_iN($lanes_(`%X%`_shape((Jnn : Jnn <: lanetype), `%`_dim(M)), c)[j]!`%`_lane_.0))) - ;; 8-reduction.watsup:1041.1-1044.37 + ;; 8-reduction.watsup:1044.1-1047.37 rule memory.grow-succeed{z : state, n : n, x : idx, mi : meminst}: `%~>%`(`%;%`_config(z, [CONST_instr(I32_numtype, `%`_num_(n)) MEMORY.GROW_instr(x)]), `%;%`_config($with_meminst(z, x, mi), [CONST_instr(I32_numtype, `%`_num_((|$mem(z, x).BYTES_meminst| / (64 * $Ki))))])) -- if (mi = $growmem($mem(z, x), n)) - ;; 8-reduction.watsup:1046.1-1047.78 + ;; 8-reduction.watsup:1049.1-1050.78 rule memory.grow-fail{z : state, n : n, x : idx}: `%~>%`(`%;%`_config(z, [CONST_instr(I32_numtype, `%`_num_(n)) MEMORY.GROW_instr(x)]), `%;%`_config(z, [CONST_instr(I32_numtype, `%`_num_($invsigned_(32, - (1 : nat <: int))))])) - ;; 8-reduction.watsup:1107.1-1108.51 + ;; 8-reduction.watsup:1110.1-1111.51 rule data.drop{z : state, x : idx}: `%~>%`(`%;%`_config(z, [DATA.DROP_instr(x)]), `%;%`_config($with_data(z, x, []), [])) } @@ -14170,6 +14174,10 @@ relation Step_read: `%~>%`(config, instr*) rule return_call_ref-label{z : state, k : nat, instr'* : instr*, val* : val*, yy : typeuse, instr* : instr*}: `%~>%`(`%;%`_config(z, [`LABEL_%{%}%`_instr(k, instr'*{instr' : instr}, (val : val <: instr)*{val : val} :: [RETURN_CALL_REF_instr(yy)] :: instr*{instr : instr})]), (val : val <: instr)*{val : val} :: [RETURN_CALL_REF_instr(yy)]) + ;; 8-reduction.watsup + rule return_call_ref-handler{z : state, k : nat, catch* : catch*, val* : val*, yy : typeuse, instr* : instr*}: + `%~>%`(`%;%`_config(z, [`HANDLER_%{%}%`_instr(k, catch*{catch : catch}, (val : val <: instr)*{val : val} :: [RETURN_CALL_REF_instr(yy)] :: instr*{instr : instr})]), (val : val <: instr)*{val : val} :: [RETURN_CALL_REF_instr(yy)]) + ;; 8-reduction.watsup rule return_call_ref-frame-null{z : state, k : nat, f : frame, val* : val*, ht : heaptype, yy : typeuse, instr* : instr*}: `%~>%`(`%;%`_config(z, [`FRAME_%{%}%`_instr(k, f, (val : val <: instr)*{val : val} :: [REF.NULL_instr(ht)] :: [RETURN_CALL_REF_instr(yy)] :: instr*{instr : instr})]), [TRAP_instr]) @@ -14668,142 +14676,142 @@ relation Step: `%~>%`(config, config) `%~>%`(`%;%`_config(z, instr*{instr : instr}), `%;%`_config(z, instr'*{instr' : instr})) -- Step_read: `%~>%`(`%;%`_config(z, instr*{instr : instr}), instr'*{instr' : instr}) - ;; 8-reduction.watsup:218.1-223.49 + ;; 8-reduction.watsup:221.1-226.49 rule throw{z : state, val^n : val^n, n : n, x : idx, exn : exninst, a : addr, t^n : valtype^n}: `%~>%`(`%;%`_config(z, (val : val <: instr)^n{val : val} :: [THROW_instr(x)]), `%;%`_config($add_exninst(z, [exn]), [REF.EXN_ADDR_instr(a) THROW_REF_instr])) -- Expand: `%~~%`($tag(z, x).TYPE_taginst, FUNC_comptype(`%->%`_functype(`%`_resulttype(t^n{t : valtype}), `%`_resulttype([])))) -- if (a = |$exninst(z)|) -- if (exn = {TAG $tagaddr(z)[x!`%`_idx.0], FIELDS val^n{val : val}}) - ;; 8-reduction.watsup:285.1-287.36 + ;; 8-reduction.watsup:288.1-290.36 rule ctxt-label{z : state, n : n, instr_0* : instr*, instr* : instr*, z' : state, instr'* : instr*}: `%~>%`(`%;%`_config(z, [`LABEL_%{%}%`_instr(n, instr_0*{instr_0 : instr}, instr*{instr : instr})]), `%;%`_config(z', [`LABEL_%{%}%`_instr(n, instr_0*{instr_0 : instr}, instr'*{instr' : instr})])) -- Step: `%~>%`(`%;%`_config(z, instr*{instr : instr}), `%;%`_config(z', instr'*{instr' : instr})) - ;; 8-reduction.watsup:289.1-291.44 + ;; 8-reduction.watsup:292.1-294.44 rule ctxt-frame{s : store, f : frame, n : n, f' : frame, instr* : instr*, s' : store, instr'* : instr*}: `%~>%`(`%;%`_config(`%;%`_state(s, f), [`FRAME_%{%}%`_instr(n, f', instr*{instr : instr})]), `%;%`_config(`%;%`_state(s', f), [`FRAME_%{%}%`_instr(n, f', instr'*{instr' : instr})])) -- Step: `%~>%`(`%;%`_config(`%;%`_state(s, f'), instr*{instr : instr}), `%;%`_config(`%;%`_state(s', f'), instr'*{instr' : instr})) - ;; 8-reduction.watsup:409.1-413.65 + ;; 8-reduction.watsup:412.1-416.65 rule struct.new{z : state, val^n : val^n, n : n, x : idx, si : structinst, a : addr, mut^n : mut^n, zt^n : storagetype^n}: `%~>%`(`%;%`_config(z, (val : val <: instr)^n{val : val} :: [STRUCT.NEW_instr(x)]), `%;%`_config($add_structinst(z, [si]), [REF.STRUCT_ADDR_instr(a)])) -- Expand: `%~~%`($type(z, x), STRUCT_comptype(`%`_structtype(`%%`_fieldtype(mut, zt)^n{mut : mut, zt : storagetype}))) -- if (a = |$structinst(z)|) -- if (si = {TYPE $type(z, x), FIELDS $packfield_(zt, val)^n{val : val, zt : storagetype}}) - ;; 8-reduction.watsup:429.1-430.53 + ;; 8-reduction.watsup:432.1-433.53 rule struct.set-null{z : state, ht : heaptype, val : val, x : idx, i : nat}: `%~>%`(`%;%`_config(z, [REF.NULL_instr(ht) (val : val <: instr) STRUCT.SET_instr(x, `%`_u32(i))]), `%;%`_config(z, [TRAP_instr])) - ;; 8-reduction.watsup:432.1-434.45 + ;; 8-reduction.watsup:435.1-437.45 rule struct.set-struct{z : state, a : addr, val : val, x : idx, i : nat, zt* : storagetype*, mut* : mut*}: `%~>%`(`%;%`_config(z, [REF.STRUCT_ADDR_instr(a) (val : val <: instr) STRUCT.SET_instr(x, `%`_u32(i))]), `%;%`_config($with_struct(z, a, i, $packfield_(zt*{zt : storagetype}[i], val)), [])) -- Expand: `%~~%`($type(z, x), STRUCT_comptype(`%`_structtype(`%%`_fieldtype(mut, zt)*{mut : mut, zt : storagetype}))) - ;; 8-reduction.watsup:447.1-452.65 + ;; 8-reduction.watsup:450.1-455.65 rule array.new_fixed{z : state, val^n : val^n, n : n, x : idx, ai : arrayinst, a : addr, mut : mut, zt : storagetype}: `%~>%`(`%;%`_config(z, (val : val <: instr)^n{val : val} :: [ARRAY.NEW_FIXED_instr(x, `%`_u32(n))]), `%;%`_config($add_arrayinst(z, [ai]), [REF.ARRAY_ADDR_instr(a)])) -- Expand: `%~~%`($type(z, x), ARRAY_comptype(`%%`_arraytype(mut, zt))) -- if ((a = |$arrayinst(z)|) /\ (ai = {TYPE $type(z, x), FIELDS $packfield_(zt, val)^n{val : val}})) - ;; 8-reduction.watsup:492.1-493.64 + ;; 8-reduction.watsup:495.1-496.64 rule array.set-null{z : state, ht : heaptype, i : nat, val : val, x : idx}: `%~>%`(`%;%`_config(z, [REF.NULL_instr(ht) CONST_instr(I32_numtype, `%`_num_(i)) (val : val <: instr) ARRAY.SET_instr(x)]), `%;%`_config(z, [TRAP_instr])) - ;; 8-reduction.watsup:495.1-497.39 + ;; 8-reduction.watsup:498.1-500.39 rule array.set-oob{z : state, a : addr, i : nat, val : val, x : idx}: `%~>%`(`%;%`_config(z, [REF.ARRAY_ADDR_instr(a) CONST_instr(I32_numtype, `%`_num_(i)) (val : val <: instr) ARRAY.SET_instr(x)]), `%;%`_config(z, [TRAP_instr])) -- if (i >= |$arrayinst(z)[a].FIELDS_arrayinst|) - ;; 8-reduction.watsup:499.1-502.43 + ;; 8-reduction.watsup:502.1-505.43 rule array.set-array{z : state, a : addr, i : nat, val : val, x : idx, zt : storagetype, mut : mut}: `%~>%`(`%;%`_config(z, [REF.ARRAY_ADDR_instr(a) CONST_instr(I32_numtype, `%`_num_(i)) (val : val <: instr) ARRAY.SET_instr(x)]), `%;%`_config($with_array(z, a, i, $packfield_(zt, val)), [])) -- Expand: `%~~%`($type(z, x), ARRAY_comptype(`%%`_arraytype(mut, zt))) - ;; 8-reduction.watsup:803.1-804.56 + ;; 8-reduction.watsup:806.1-807.56 rule local.set{z : state, val : val, x : idx}: `%~>%`(`%;%`_config(z, [(val : val <: instr) LOCAL.SET_instr(x)]), `%;%`_config($with_local(z, x, val), [])) - ;; 8-reduction.watsup:816.1-817.58 + ;; 8-reduction.watsup:819.1-820.58 rule global.set{z : state, val : val, x : idx}: `%~>%`(`%;%`_config(z, [(val : val <: instr) GLOBAL.SET_instr(x)]), `%;%`_config($with_global(z, x, val), [])) - ;; 8-reduction.watsup:830.1-832.33 + ;; 8-reduction.watsup:833.1-835.33 rule table.set-oob{z : state, i : nat, ref : ref, x : idx}: `%~>%`(`%;%`_config(z, [CONST_instr(I32_numtype, `%`_num_(i)) (ref : ref <: instr) TABLE.SET_instr(x)]), `%;%`_config(z, [TRAP_instr])) -- if (i >= |$table(z, x).REFS_tableinst|) - ;; 8-reduction.watsup:834.1-836.32 + ;; 8-reduction.watsup:837.1-839.32 rule table.set-val{z : state, i : nat, ref : ref, x : idx}: `%~>%`(`%;%`_config(z, [CONST_instr(I32_numtype, `%`_num_(i)) (ref : ref <: instr) TABLE.SET_instr(x)]), `%;%`_config($with_table(z, x, i, ref), [])) -- if (i < |$table(z, x).REFS_tableinst|) - ;; 8-reduction.watsup:844.1-847.46 + ;; 8-reduction.watsup:847.1-850.46 rule table.grow-succeed{z : state, ref : ref, n : n, x : idx, ti : tableinst}: `%~>%`(`%;%`_config(z, [(ref : ref <: instr) CONST_instr(I32_numtype, `%`_num_(n)) TABLE.GROW_instr(x)]), `%;%`_config($with_tableinst(z, x, ti), [CONST_instr(I32_numtype, `%`_num_(|$table(z, x).REFS_tableinst|))])) -- if (ti = !($growtable($table(z, x), n, ref))) - ;; 8-reduction.watsup:849.1-850.81 + ;; 8-reduction.watsup:852.1-853.81 rule table.grow-fail{z : state, ref : ref, n : n, x : idx}: `%~>%`(`%;%`_config(z, [(ref : ref <: instr) CONST_instr(I32_numtype, `%`_num_(n)) TABLE.GROW_instr(x)]), `%;%`_config(z, [CONST_instr(I32_numtype, `%`_num_($invsigned_(32, - (1 : nat <: int))))])) - ;; 8-reduction.watsup:910.1-911.51 + ;; 8-reduction.watsup:913.1-914.51 rule elem.drop{z : state, x : idx}: `%~>%`(`%;%`_config(z, [ELEM.DROP_instr(x)]), `%;%`_config($with_elem(z, x, []), [])) - ;; 8-reduction.watsup:994.1-997.60 + ;; 8-reduction.watsup:997.1-1000.60 rule store-num-oob{z : state, i : nat, nt : numtype, c : num_(nt), x : idx, ao : memarg}: `%~>%`(`%;%`_config(z, [CONST_instr(I32_numtype, `%`_num_(i)) CONST_instr(nt, c) STORE_instr(nt, ?(), x, ao)]), `%;%`_config(z, [TRAP_instr])) -- if (((i + ao.OFFSET_memarg!`%`_u32.0) + ($size(nt) / 8)) > |$mem(z, x).BYTES_meminst|) - ;; 8-reduction.watsup:999.1-1003.29 + ;; 8-reduction.watsup:1002.1-1006.29 rule store-num-val{z : state, i : nat, nt : numtype, c : num_(nt), x : idx, ao : memarg, b* : byte*}: `%~>%`(`%;%`_config(z, [CONST_instr(I32_numtype, `%`_num_(i)) CONST_instr(nt, c) STORE_instr(nt, ?(), x, ao)]), `%;%`_config($with_mem(z, x, (i + ao.OFFSET_memarg!`%`_u32.0), ($size(nt) / 8), b*{b : byte}), [])) -- if (b*{b : byte} = $nbytes_(nt, c)) - ;; 8-reduction.watsup:1005.1-1008.52 + ;; 8-reduction.watsup:1008.1-1011.52 rule store-pack-oob{z : state, i : nat, Inn : Inn, c : num_((Inn : Inn <: numtype)), nt : numtype, n : n, x : idx, ao : memarg}: `%~>%`(`%;%`_config(z, [CONST_instr(I32_numtype, `%`_num_(i)) CONST_instr((Inn : Inn <: numtype), c) STORE_instr(nt, ?(`%`_sz(n)), x, ao)]), `%;%`_config(z, [TRAP_instr])) -- if (((i + ao.OFFSET_memarg!`%`_u32.0) + (n / 8)) > |$mem(z, x).BYTES_meminst|) - ;; 8-reduction.watsup:1010.1-1014.52 + ;; 8-reduction.watsup:1013.1-1017.52 rule store-pack-val{z : state, i : nat, Inn : Inn, c : num_((Inn : Inn <: numtype)), nt : numtype, n : n, x : idx, ao : memarg, b* : byte*}: `%~>%`(`%;%`_config(z, [CONST_instr(I32_numtype, `%`_num_(i)) CONST_instr((Inn : Inn <: numtype), c) STORE_instr(nt, ?(`%`_sz(n)), x, ao)]), `%;%`_config($with_mem(z, x, (i + ao.OFFSET_memarg!`%`_u32.0), (n / 8), b*{b : byte}), [])) -- if (b*{b : byte} = $ibytes_(n, $wrap__($size((Inn : Inn <: numtype)), n, c))) - ;; 8-reduction.watsup:1016.1-1018.63 + ;; 8-reduction.watsup:1019.1-1021.63 rule vstore-oob{z : state, i : nat, c : vec_(V128_Vnn), x : idx, ao : memarg}: `%~>%`(`%;%`_config(z, [CONST_instr(I32_numtype, `%`_num_(i)) VCONST_instr(V128_vectype, c) VSTORE_instr(V128_vectype, x, ao)]), `%;%`_config(z, [TRAP_instr])) -- if (((i + ao.OFFSET_memarg!`%`_u32.0) + ($vsize(V128_vectype) / 8)) > |$mem(z, x).BYTES_meminst|) - ;; 8-reduction.watsup:1020.1-1022.31 + ;; 8-reduction.watsup:1023.1-1025.31 rule vstore-val{z : state, i : nat, c : vec_(V128_Vnn), x : idx, ao : memarg, b* : byte*}: `%~>%`(`%;%`_config(z, [CONST_instr(I32_numtype, `%`_num_(i)) VCONST_instr(V128_vectype, c) VSTORE_instr(V128_vectype, x, ao)]), `%;%`_config($with_mem(z, x, (i + ao.OFFSET_memarg!`%`_u32.0), ($vsize(V128_vectype) / 8), b*{b : byte}), [])) -- if (b*{b : byte} = $vbytes_(V128_vectype, c)) - ;; 8-reduction.watsup:1025.1-1027.50 + ;; 8-reduction.watsup:1028.1-1030.50 rule vstore_lane-oob{z : state, i : nat, c : vec_(V128_Vnn), N : N, x : idx, ao : memarg, j : nat}: `%~>%`(`%;%`_config(z, [CONST_instr(I32_numtype, `%`_num_(i)) VCONST_instr(V128_vectype, c) VSTORE_LANE_instr(V128_vectype, `%`_sz(N), x, ao, `%`_laneidx(j))]), `%;%`_config(z, [TRAP_instr])) -- if (((i + ao.OFFSET_memarg!`%`_u32.0) + N) > |$mem(z, x).BYTES_meminst|) - ;; 8-reduction.watsup:1029.1-1033.49 + ;; 8-reduction.watsup:1032.1-1036.49 rule vstore_lane-val{z : state, i : nat, c : vec_(V128_Vnn), N : N, x : idx, ao : memarg, j : nat, b* : byte*, Jnn : Jnn, M : M}: `%~>%`(`%;%`_config(z, [CONST_instr(I32_numtype, `%`_num_(i)) VCONST_instr(V128_vectype, c) VSTORE_LANE_instr(V128_vectype, `%`_sz(N), x, ao, `%`_laneidx(j))]), `%;%`_config($with_mem(z, x, (i + ao.OFFSET_memarg!`%`_u32.0), (N / 8), b*{b : byte}), [])) -- if (N = $lsize((Jnn : Jnn <: lanetype))) -- if (M = (128 / N)) -- if (b*{b : byte} = $ibytes_(N, `%`_iN($lanes_(`%X%`_shape((Jnn : Jnn <: lanetype), `%`_dim(M)), c)[j]!`%`_lane_.0))) - ;; 8-reduction.watsup:1041.1-1044.37 + ;; 8-reduction.watsup:1044.1-1047.37 rule memory.grow-succeed{z : state, n : n, x : idx, mi : meminst}: `%~>%`(`%;%`_config(z, [CONST_instr(I32_numtype, `%`_num_(n)) MEMORY.GROW_instr(x)]), `%;%`_config($with_meminst(z, x, mi), [CONST_instr(I32_numtype, `%`_num_((|$mem(z, x).BYTES_meminst| / (64 * $Ki))))])) -- if (mi = !($growmem($mem(z, x), n))) - ;; 8-reduction.watsup:1046.1-1047.78 + ;; 8-reduction.watsup:1049.1-1050.78 rule memory.grow-fail{z : state, n : n, x : idx}: `%~>%`(`%;%`_config(z, [CONST_instr(I32_numtype, `%`_num_(n)) MEMORY.GROW_instr(x)]), `%;%`_config(z, [CONST_instr(I32_numtype, `%`_num_($invsigned_(32, - (1 : nat <: int))))])) - ;; 8-reduction.watsup:1107.1-1108.51 + ;; 8-reduction.watsup:1110.1-1111.51 rule data.drop{z : state, x : idx}: `%~>%`(`%;%`_config(z, [DATA.DROP_instr(x)]), `%;%`_config($with_data(z, x, []), [])) } @@ -22553,6 +22561,10 @@ relation Step_read: `%~>%`(config, instr*) rule return_call_ref-label{z : state, k : nat, instr'* : instr*, val* : val*, yy : typeuse, instr* : instr*}: `%~>%`(`%;%`_config(z, [`LABEL_%{%}%`_instr(k, instr'*{instr' : instr}, (val : val <: instr)*{val : val} :: [RETURN_CALL_REF_instr(yy)] :: instr*{instr : instr})]), (val : val <: instr)*{val : val} :: [RETURN_CALL_REF_instr(yy)]) + ;; 8-reduction.watsup + rule return_call_ref-handler{z : state, k : nat, catch* : catch*, val* : val*, yy : typeuse, instr* : instr*}: + `%~>%`(`%;%`_config(z, [`HANDLER_%{%}%`_instr(k, catch*{catch : catch}, (val : val <: instr)*{val : val} :: [RETURN_CALL_REF_instr(yy)] :: instr*{instr : instr})]), (val : val <: instr)*{val : val} :: [RETURN_CALL_REF_instr(yy)]) + ;; 8-reduction.watsup rule return_call_ref-frame-null{z : state, k : nat, f : frame, val* : val*, ht : heaptype, yy : typeuse, instr* : instr*}: `%~>%`(`%;%`_config(z, [`FRAME_%{%}%`_instr(k, f, (val : val <: instr)*{val : val} :: [REF.NULL_instr(ht)] :: [RETURN_CALL_REF_instr(yy)] :: instr*{instr : instr})]), [TRAP_instr]) @@ -23051,142 +23063,142 @@ relation Step: `%~>%`(config, config) `%~>%`(`%;%`_config(z, instr*{instr : instr}), `%;%`_config(z, instr'*{instr' : instr})) -- Step_read: `%~>%`(`%;%`_config(z, instr*{instr : instr}), instr'*{instr' : instr}) - ;; 8-reduction.watsup:218.1-223.49 + ;; 8-reduction.watsup:221.1-226.49 rule throw{z : state, val^n : val^n, n : n, x : idx, exn : exninst, a : addr, t^n : valtype^n}: `%~>%`(`%;%`_config(z, (val : val <: instr)^n{val : val} :: [THROW_instr(x)]), `%;%`_config($add_exninst(z, [exn]), [REF.EXN_ADDR_instr(a) THROW_REF_instr])) -- Expand: `%~~%`($tag(z, x).TYPE_taginst, FUNC_comptype(`%->%`_functype(`%`_resulttype(t^n{t : valtype}), `%`_resulttype([])))) -- if (a = |$exninst(z)|) -- if (exn = {TAG $tagaddr(z)[x!`%`_idx.0], FIELDS val^n{val : val}}) - ;; 8-reduction.watsup:285.1-287.36 + ;; 8-reduction.watsup:288.1-290.36 rule ctxt-label{z : state, n : n, instr_0* : instr*, instr* : instr*, z' : state, instr'* : instr*}: `%~>%`(`%;%`_config(z, [`LABEL_%{%}%`_instr(n, instr_0*{instr_0 : instr}, instr*{instr : instr})]), `%;%`_config(z', [`LABEL_%{%}%`_instr(n, instr_0*{instr_0 : instr}, instr'*{instr' : instr})])) -- Step: `%~>%`(`%;%`_config(z, instr*{instr : instr}), `%;%`_config(z', instr'*{instr' : instr})) - ;; 8-reduction.watsup:289.1-291.44 + ;; 8-reduction.watsup:292.1-294.44 rule ctxt-frame{s : store, f : frame, n : n, f' : frame, instr* : instr*, s' : store, instr'* : instr*}: `%~>%`(`%;%`_config(`%;%`_state(s, f), [`FRAME_%{%}%`_instr(n, f', instr*{instr : instr})]), `%;%`_config(`%;%`_state(s', f), [`FRAME_%{%}%`_instr(n, f', instr'*{instr' : instr})])) -- Step: `%~>%`(`%;%`_config(`%;%`_state(s, f'), instr*{instr : instr}), `%;%`_config(`%;%`_state(s', f'), instr'*{instr' : instr})) - ;; 8-reduction.watsup:409.1-413.65 + ;; 8-reduction.watsup:412.1-416.65 rule struct.new{z : state, val^n : val^n, n : n, x : idx, si : structinst, a : addr, mut^n : mut^n, zt^n : storagetype^n}: `%~>%`(`%;%`_config(z, (val : val <: instr)^n{val : val} :: [STRUCT.NEW_instr(x)]), `%;%`_config($add_structinst(z, [si]), [REF.STRUCT_ADDR_instr(a)])) -- Expand: `%~~%`($type(z, x), STRUCT_comptype(`%`_structtype(`%%`_fieldtype(mut, zt)^n{mut : mut, zt : storagetype}))) -- if (a = |$structinst(z)|) -- if (si = {TYPE $type(z, x), FIELDS $packfield_(zt, val)^n{val : val, zt : storagetype}}) - ;; 8-reduction.watsup:429.1-430.53 + ;; 8-reduction.watsup:432.1-433.53 rule struct.set-null{z : state, ht : heaptype, val : val, x : idx, i : nat}: `%~>%`(`%;%`_config(z, [REF.NULL_instr(ht) (val : val <: instr) STRUCT.SET_instr(x, `%`_u32(i))]), `%;%`_config(z, [TRAP_instr])) - ;; 8-reduction.watsup:432.1-434.45 + ;; 8-reduction.watsup:435.1-437.45 rule struct.set-struct{z : state, a : addr, val : val, x : idx, i : nat, zt* : storagetype*, mut* : mut*}: `%~>%`(`%;%`_config(z, [REF.STRUCT_ADDR_instr(a) (val : val <: instr) STRUCT.SET_instr(x, `%`_u32(i))]), `%;%`_config($with_struct(z, a, i, $packfield_(zt*{zt : storagetype}[i], val)), [])) -- Expand: `%~~%`($type(z, x), STRUCT_comptype(`%`_structtype(`%%`_fieldtype(mut, zt)*{mut : mut, zt : storagetype}))) - ;; 8-reduction.watsup:447.1-452.65 + ;; 8-reduction.watsup:450.1-455.65 rule array.new_fixed{z : state, val^n : val^n, n : n, x : idx, ai : arrayinst, a : addr, mut : mut, zt : storagetype}: `%~>%`(`%;%`_config(z, (val : val <: instr)^n{val : val} :: [ARRAY.NEW_FIXED_instr(x, `%`_u32(n))]), `%;%`_config($add_arrayinst(z, [ai]), [REF.ARRAY_ADDR_instr(a)])) -- Expand: `%~~%`($type(z, x), ARRAY_comptype(`%%`_arraytype(mut, zt))) -- if ((a = |$arrayinst(z)|) /\ (ai = {TYPE $type(z, x), FIELDS $packfield_(zt, val)^n{val : val}})) - ;; 8-reduction.watsup:492.1-493.64 + ;; 8-reduction.watsup:495.1-496.64 rule array.set-null{z : state, ht : heaptype, i : nat, val : val, x : idx}: `%~>%`(`%;%`_config(z, [REF.NULL_instr(ht) CONST_instr(I32_numtype, `%`_num_(i)) (val : val <: instr) ARRAY.SET_instr(x)]), `%;%`_config(z, [TRAP_instr])) - ;; 8-reduction.watsup:495.1-497.39 + ;; 8-reduction.watsup:498.1-500.39 rule array.set-oob{z : state, a : addr, i : nat, val : val, x : idx}: `%~>%`(`%;%`_config(z, [REF.ARRAY_ADDR_instr(a) CONST_instr(I32_numtype, `%`_num_(i)) (val : val <: instr) ARRAY.SET_instr(x)]), `%;%`_config(z, [TRAP_instr])) -- if (i >= |$arrayinst(z)[a].FIELDS_arrayinst|) - ;; 8-reduction.watsup:499.1-502.43 + ;; 8-reduction.watsup:502.1-505.43 rule array.set-array{z : state, a : addr, i : nat, val : val, x : idx, zt : storagetype, mut : mut}: `%~>%`(`%;%`_config(z, [REF.ARRAY_ADDR_instr(a) CONST_instr(I32_numtype, `%`_num_(i)) (val : val <: instr) ARRAY.SET_instr(x)]), `%;%`_config($with_array(z, a, i, $packfield_(zt, val)), [])) -- Expand: `%~~%`($type(z, x), ARRAY_comptype(`%%`_arraytype(mut, zt))) - ;; 8-reduction.watsup:803.1-804.56 + ;; 8-reduction.watsup:806.1-807.56 rule local.set{z : state, val : val, x : idx}: `%~>%`(`%;%`_config(z, [(val : val <: instr) LOCAL.SET_instr(x)]), `%;%`_config($with_local(z, x, val), [])) - ;; 8-reduction.watsup:816.1-817.58 + ;; 8-reduction.watsup:819.1-820.58 rule global.set{z : state, val : val, x : idx}: `%~>%`(`%;%`_config(z, [(val : val <: instr) GLOBAL.SET_instr(x)]), `%;%`_config($with_global(z, x, val), [])) - ;; 8-reduction.watsup:830.1-832.33 + ;; 8-reduction.watsup:833.1-835.33 rule table.set-oob{z : state, i : nat, ref : ref, x : idx}: `%~>%`(`%;%`_config(z, [CONST_instr(I32_numtype, `%`_num_(i)) (ref : ref <: instr) TABLE.SET_instr(x)]), `%;%`_config(z, [TRAP_instr])) -- if (i >= |$table(z, x).REFS_tableinst|) - ;; 8-reduction.watsup:834.1-836.32 + ;; 8-reduction.watsup:837.1-839.32 rule table.set-val{z : state, i : nat, ref : ref, x : idx}: `%~>%`(`%;%`_config(z, [CONST_instr(I32_numtype, `%`_num_(i)) (ref : ref <: instr) TABLE.SET_instr(x)]), `%;%`_config($with_table(z, x, i, ref), [])) -- if (i < |$table(z, x).REFS_tableinst|) - ;; 8-reduction.watsup:844.1-847.46 + ;; 8-reduction.watsup:847.1-850.46 rule table.grow-succeed{z : state, ref : ref, n : n, x : idx, ti : tableinst}: `%~>%`(`%;%`_config(z, [(ref : ref <: instr) CONST_instr(I32_numtype, `%`_num_(n)) TABLE.GROW_instr(x)]), `%;%`_config($with_tableinst(z, x, ti), [CONST_instr(I32_numtype, `%`_num_(|$table(z, x).REFS_tableinst|))])) -- if (ti = !($growtable($table(z, x), n, ref))) - ;; 8-reduction.watsup:849.1-850.81 + ;; 8-reduction.watsup:852.1-853.81 rule table.grow-fail{z : state, ref : ref, n : n, x : idx}: `%~>%`(`%;%`_config(z, [(ref : ref <: instr) CONST_instr(I32_numtype, `%`_num_(n)) TABLE.GROW_instr(x)]), `%;%`_config(z, [CONST_instr(I32_numtype, `%`_num_($invsigned_(32, - (1 : nat <: int))))])) - ;; 8-reduction.watsup:910.1-911.51 + ;; 8-reduction.watsup:913.1-914.51 rule elem.drop{z : state, x : idx}: `%~>%`(`%;%`_config(z, [ELEM.DROP_instr(x)]), `%;%`_config($with_elem(z, x, []), [])) - ;; 8-reduction.watsup:994.1-997.60 + ;; 8-reduction.watsup:997.1-1000.60 rule store-num-oob{z : state, i : nat, nt : numtype, c : num_(nt), x : idx, ao : memarg}: `%~>%`(`%;%`_config(z, [CONST_instr(I32_numtype, `%`_num_(i)) CONST_instr(nt, c) STORE_instr(nt, ?(), x, ao)]), `%;%`_config(z, [TRAP_instr])) -- if (((i + ao.OFFSET_memarg!`%`_u32.0) + ($size(nt) / 8)) > |$mem(z, x).BYTES_meminst|) - ;; 8-reduction.watsup:999.1-1003.29 + ;; 8-reduction.watsup:1002.1-1006.29 rule store-num-val{z : state, i : nat, nt : numtype, c : num_(nt), x : idx, ao : memarg, b* : byte*}: `%~>%`(`%;%`_config(z, [CONST_instr(I32_numtype, `%`_num_(i)) CONST_instr(nt, c) STORE_instr(nt, ?(), x, ao)]), `%;%`_config($with_mem(z, x, (i + ao.OFFSET_memarg!`%`_u32.0), ($size(nt) / 8), b*{b : byte}), [])) -- if (b*{b : byte} = $nbytes_(nt, c)) - ;; 8-reduction.watsup:1005.1-1008.52 + ;; 8-reduction.watsup:1008.1-1011.52 rule store-pack-oob{z : state, i : nat, Inn : Inn, c : num_((Inn : Inn <: numtype)), nt : numtype, n : n, x : idx, ao : memarg}: `%~>%`(`%;%`_config(z, [CONST_instr(I32_numtype, `%`_num_(i)) CONST_instr((Inn : Inn <: numtype), c) STORE_instr(nt, ?(`%`_sz(n)), x, ao)]), `%;%`_config(z, [TRAP_instr])) -- if (((i + ao.OFFSET_memarg!`%`_u32.0) + (n / 8)) > |$mem(z, x).BYTES_meminst|) - ;; 8-reduction.watsup:1010.1-1014.52 + ;; 8-reduction.watsup:1013.1-1017.52 rule store-pack-val{z : state, i : nat, Inn : Inn, c : num_((Inn : Inn <: numtype)), nt : numtype, n : n, x : idx, ao : memarg, b* : byte*}: `%~>%`(`%;%`_config(z, [CONST_instr(I32_numtype, `%`_num_(i)) CONST_instr((Inn : Inn <: numtype), c) STORE_instr(nt, ?(`%`_sz(n)), x, ao)]), `%;%`_config($with_mem(z, x, (i + ao.OFFSET_memarg!`%`_u32.0), (n / 8), b*{b : byte}), [])) -- if (b*{b : byte} = $ibytes_(n, $wrap__($size((Inn : Inn <: numtype)), n, c))) - ;; 8-reduction.watsup:1016.1-1018.63 + ;; 8-reduction.watsup:1019.1-1021.63 rule vstore-oob{z : state, i : nat, c : vec_(V128_Vnn), x : idx, ao : memarg}: `%~>%`(`%;%`_config(z, [CONST_instr(I32_numtype, `%`_num_(i)) VCONST_instr(V128_vectype, c) VSTORE_instr(V128_vectype, x, ao)]), `%;%`_config(z, [TRAP_instr])) -- if (((i + ao.OFFSET_memarg!`%`_u32.0) + ($vsize(V128_vectype) / 8)) > |$mem(z, x).BYTES_meminst|) - ;; 8-reduction.watsup:1020.1-1022.31 + ;; 8-reduction.watsup:1023.1-1025.31 rule vstore-val{z : state, i : nat, c : vec_(V128_Vnn), x : idx, ao : memarg, b* : byte*}: `%~>%`(`%;%`_config(z, [CONST_instr(I32_numtype, `%`_num_(i)) VCONST_instr(V128_vectype, c) VSTORE_instr(V128_vectype, x, ao)]), `%;%`_config($with_mem(z, x, (i + ao.OFFSET_memarg!`%`_u32.0), ($vsize(V128_vectype) / 8), b*{b : byte}), [])) -- if (b*{b : byte} = $vbytes_(V128_vectype, c)) - ;; 8-reduction.watsup:1025.1-1027.50 + ;; 8-reduction.watsup:1028.1-1030.50 rule vstore_lane-oob{z : state, i : nat, c : vec_(V128_Vnn), N : N, x : idx, ao : memarg, j : nat}: `%~>%`(`%;%`_config(z, [CONST_instr(I32_numtype, `%`_num_(i)) VCONST_instr(V128_vectype, c) VSTORE_LANE_instr(V128_vectype, `%`_sz(N), x, ao, `%`_laneidx(j))]), `%;%`_config(z, [TRAP_instr])) -- if (((i + ao.OFFSET_memarg!`%`_u32.0) + N) > |$mem(z, x).BYTES_meminst|) - ;; 8-reduction.watsup:1029.1-1033.49 + ;; 8-reduction.watsup:1032.1-1036.49 rule vstore_lane-val{z : state, i : nat, c : vec_(V128_Vnn), N : N, x : idx, ao : memarg, j : nat, b* : byte*, Jnn : Jnn, M : M}: `%~>%`(`%;%`_config(z, [CONST_instr(I32_numtype, `%`_num_(i)) VCONST_instr(V128_vectype, c) VSTORE_LANE_instr(V128_vectype, `%`_sz(N), x, ao, `%`_laneidx(j))]), `%;%`_config($with_mem(z, x, (i + ao.OFFSET_memarg!`%`_u32.0), (N / 8), b*{b : byte}), [])) -- if (N = $lsize((Jnn : Jnn <: lanetype))) -- if (M = (128 / N)) -- if (b*{b : byte} = $ibytes_(N, `%`_iN($lanes_(`%X%`_shape((Jnn : Jnn <: lanetype), `%`_dim(M)), c)[j]!`%`_lane_.0))) - ;; 8-reduction.watsup:1041.1-1044.37 + ;; 8-reduction.watsup:1044.1-1047.37 rule memory.grow-succeed{z : state, n : n, x : idx, mi : meminst}: `%~>%`(`%;%`_config(z, [CONST_instr(I32_numtype, `%`_num_(n)) MEMORY.GROW_instr(x)]), `%;%`_config($with_meminst(z, x, mi), [CONST_instr(I32_numtype, `%`_num_((|$mem(z, x).BYTES_meminst| / (64 * $Ki))))])) -- if (mi = !($growmem($mem(z, x), n))) - ;; 8-reduction.watsup:1046.1-1047.78 + ;; 8-reduction.watsup:1049.1-1050.78 rule memory.grow-fail{z : state, n : n, x : idx}: `%~>%`(`%;%`_config(z, [CONST_instr(I32_numtype, `%`_num_(n)) MEMORY.GROW_instr(x)]), `%;%`_config(z, [CONST_instr(I32_numtype, `%`_num_($invsigned_(32, - (1 : nat <: int))))])) - ;; 8-reduction.watsup:1107.1-1108.51 + ;; 8-reduction.watsup:1110.1-1111.51 rule data.drop{z : state, x : idx}: `%~>%`(`%;%`_config(z, [DATA.DROP_instr(x)]), `%;%`_config($with_data(z, x, []), [])) } @@ -31096,6 +31108,10 @@ relation Step_read: `%~>%`(config, instr*) rule return_call_ref-label{z : state, k : nat, instr'* : instr*, val* : val*, yy : typeuse, instr* : instr*}: `%~>%`(`%;%`_config(z, [`LABEL_%{%}%`_instr(k, instr'*{instr' : instr}, (val : val <: instr)*{val : val} :: [RETURN_CALL_REF_instr(yy)] :: instr*{instr : instr})]), (val : val <: instr)*{val : val} :: [RETURN_CALL_REF_instr(yy)]) + ;; 8-reduction.watsup + rule return_call_ref-handler{z : state, k : nat, catch* : catch*, val* : val*, yy : typeuse, instr* : instr*}: + `%~>%`(`%;%`_config(z, [`HANDLER_%{%}%`_instr(k, catch*{catch : catch}, (val : val <: instr)*{val : val} :: [RETURN_CALL_REF_instr(yy)] :: instr*{instr : instr})]), (val : val <: instr)*{val : val} :: [RETURN_CALL_REF_instr(yy)]) + ;; 8-reduction.watsup rule return_call_ref-frame-null{z : state, k : nat, f : frame, val* : val*, ht : heaptype, yy : typeuse, instr* : instr*}: `%~>%`(`%;%`_config(z, [`FRAME_%{%}%`_instr(k, f, (val : val <: instr)*{val : val} :: [REF.NULL_instr(ht)] :: [RETURN_CALL_REF_instr(yy)] :: instr*{instr : instr})]), [TRAP_instr]) @@ -31620,7 +31636,7 @@ relation Step: `%~>%`(config, config) `%~>%`(`%;%`_config(z, instr*{instr : instr}), `%;%`_config(z, instr'*{instr' : instr})) -- Step_read: `%~>%`(`%;%`_config(z, instr*{instr : instr}), instr'*{instr' : instr}) - ;; 8-reduction.watsup:218.1-223.49 + ;; 8-reduction.watsup:221.1-226.49 rule throw{z : state, val^n : val^n, n : n, x : idx, exn : exninst, a : addr, t^n : valtype^n}: `%~>%`(`%;%`_config(z, (val : val <: instr)^n{val : val} :: [THROW_instr(x)]), `%;%`_config($add_exninst(z, [exn]), [REF.EXN_ADDR_instr(a) THROW_REF_instr])) -- if (x!`%`_idx.0 < |$tagaddr(z)|) @@ -31628,123 +31644,123 @@ relation Step: `%~>%`(config, config) -- if (a = |$exninst(z)|) -- if (exn = {TAG $tagaddr(z)[x!`%`_idx.0], FIELDS val^n{val : val}}) - ;; 8-reduction.watsup:285.1-287.36 + ;; 8-reduction.watsup:288.1-290.36 rule ctxt-label{z : state, n : n, instr_0* : instr*, instr* : instr*, z' : state, instr'* : instr*}: `%~>%`(`%;%`_config(z, [`LABEL_%{%}%`_instr(n, instr_0*{instr_0 : instr}, instr*{instr : instr})]), `%;%`_config(z', [`LABEL_%{%}%`_instr(n, instr_0*{instr_0 : instr}, instr'*{instr' : instr})])) -- Step: `%~>%`(`%;%`_config(z, instr*{instr : instr}), `%;%`_config(z', instr'*{instr' : instr})) - ;; 8-reduction.watsup:289.1-291.44 + ;; 8-reduction.watsup:292.1-294.44 rule ctxt-frame{s : store, f : frame, n : n, f' : frame, instr* : instr*, s' : store, instr'* : instr*}: `%~>%`(`%;%`_config(`%;%`_state(s, f), [`FRAME_%{%}%`_instr(n, f', instr*{instr : instr})]), `%;%`_config(`%;%`_state(s', f), [`FRAME_%{%}%`_instr(n, f', instr'*{instr' : instr})])) -- Step: `%~>%`(`%;%`_config(`%;%`_state(s, f'), instr*{instr : instr}), `%;%`_config(`%;%`_state(s', f'), instr'*{instr' : instr})) - ;; 8-reduction.watsup:409.1-413.65 + ;; 8-reduction.watsup:412.1-416.65 rule struct.new{z : state, val^n : val^n, n : n, x : idx, si : structinst, a : addr, mut^n : mut^n, zt^n : storagetype^n}: `%~>%`(`%;%`_config(z, (val : val <: instr)^n{val : val} :: [STRUCT.NEW_instr(x)]), `%;%`_config($add_structinst(z, [si]), [REF.STRUCT_ADDR_instr(a)])) -- Expand: `%~~%`($type(z, x), STRUCT_comptype(`%`_structtype(`%%`_fieldtype(mut, zt)^n{mut : mut, zt : storagetype}))) -- if (a = |$structinst(z)|) -- if (si = {TYPE $type(z, x), FIELDS $packfield_(zt, val)^n{val : val, zt : storagetype}}) - ;; 8-reduction.watsup:429.1-430.53 + ;; 8-reduction.watsup:432.1-433.53 rule struct.set-null{z : state, ht : heaptype, val : val, x : idx, i : nat}: `%~>%`(`%;%`_config(z, [REF.NULL_instr(ht) (val : val <: instr) STRUCT.SET_instr(x, `%`_u32(i))]), `%;%`_config(z, [TRAP_instr])) - ;; 8-reduction.watsup:432.1-434.45 + ;; 8-reduction.watsup:435.1-437.45 rule struct.set-struct{z : state, a : addr, val : val, x : idx, i : nat, zt* : storagetype*, mut* : mut*}: `%~>%`(`%;%`_config(z, [REF.STRUCT_ADDR_instr(a) (val : val <: instr) STRUCT.SET_instr(x, `%`_u32(i))]), `%;%`_config($with_struct(z, a, i, $packfield_(zt*{zt : storagetype}[i], val)), [])) -- if (|mut*{mut : mut}| = |zt*{zt : storagetype}|) -- if (i < |zt*{zt : storagetype}|) -- Expand: `%~~%`($type(z, x), STRUCT_comptype(`%`_structtype(`%%`_fieldtype(mut, zt)*{mut : mut, zt : storagetype}))) - ;; 8-reduction.watsup:447.1-452.65 + ;; 8-reduction.watsup:450.1-455.65 rule array.new_fixed{z : state, val^n : val^n, n : n, x : idx, ai : arrayinst, a : addr, mut : mut, zt : storagetype}: `%~>%`(`%;%`_config(z, (val : val <: instr)^n{val : val} :: [ARRAY.NEW_FIXED_instr(x, `%`_u32(n))]), `%;%`_config($add_arrayinst(z, [ai]), [REF.ARRAY_ADDR_instr(a)])) -- Expand: `%~~%`($type(z, x), ARRAY_comptype(`%%`_arraytype(mut, zt))) -- if ((a = |$arrayinst(z)|) /\ (ai = {TYPE $type(z, x), FIELDS $packfield_(zt, val)^n{val : val}})) - ;; 8-reduction.watsup:492.1-493.64 + ;; 8-reduction.watsup:495.1-496.64 rule array.set-null{z : state, ht : heaptype, i : nat, val : val, x : idx}: `%~>%`(`%;%`_config(z, [REF.NULL_instr(ht) CONST_instr(I32_numtype, `%`_num_(i)) (val : val <: instr) ARRAY.SET_instr(x)]), `%;%`_config(z, [TRAP_instr])) - ;; 8-reduction.watsup:495.1-497.39 + ;; 8-reduction.watsup:498.1-500.39 rule array.set-oob{z : state, a : addr, i : nat, val : val, x : idx}: `%~>%`(`%;%`_config(z, [REF.ARRAY_ADDR_instr(a) CONST_instr(I32_numtype, `%`_num_(i)) (val : val <: instr) ARRAY.SET_instr(x)]), `%;%`_config(z, [TRAP_instr])) -- if (a < |$arrayinst(z)|) -- if (i >= |$arrayinst(z)[a].FIELDS_arrayinst|) - ;; 8-reduction.watsup:499.1-502.43 + ;; 8-reduction.watsup:502.1-505.43 rule array.set-array{z : state, a : addr, i : nat, val : val, x : idx, zt : storagetype, mut : mut}: `%~>%`(`%;%`_config(z, [REF.ARRAY_ADDR_instr(a) CONST_instr(I32_numtype, `%`_num_(i)) (val : val <: instr) ARRAY.SET_instr(x)]), `%;%`_config($with_array(z, a, i, $packfield_(zt, val)), [])) -- Expand: `%~~%`($type(z, x), ARRAY_comptype(`%%`_arraytype(mut, zt))) - ;; 8-reduction.watsup:803.1-804.56 + ;; 8-reduction.watsup:806.1-807.56 rule local.set{z : state, val : val, x : idx}: `%~>%`(`%;%`_config(z, [(val : val <: instr) LOCAL.SET_instr(x)]), `%;%`_config($with_local(z, x, val), [])) - ;; 8-reduction.watsup:816.1-817.58 + ;; 8-reduction.watsup:819.1-820.58 rule global.set{z : state, val : val, x : idx}: `%~>%`(`%;%`_config(z, [(val : val <: instr) GLOBAL.SET_instr(x)]), `%;%`_config($with_global(z, x, val), [])) - ;; 8-reduction.watsup:830.1-832.33 + ;; 8-reduction.watsup:833.1-835.33 rule table.set-oob{z : state, i : nat, ref : ref, x : idx}: `%~>%`(`%;%`_config(z, [CONST_instr(I32_numtype, `%`_num_(i)) (ref : ref <: instr) TABLE.SET_instr(x)]), `%;%`_config(z, [TRAP_instr])) -- if (i >= |$table(z, x).REFS_tableinst|) - ;; 8-reduction.watsup:834.1-836.32 + ;; 8-reduction.watsup:837.1-839.32 rule table.set-val{z : state, i : nat, ref : ref, x : idx}: `%~>%`(`%;%`_config(z, [CONST_instr(I32_numtype, `%`_num_(i)) (ref : ref <: instr) TABLE.SET_instr(x)]), `%;%`_config($with_table(z, x, i, ref), [])) -- if (i < |$table(z, x).REFS_tableinst|) - ;; 8-reduction.watsup:844.1-847.46 + ;; 8-reduction.watsup:847.1-850.46 rule table.grow-succeed{z : state, ref : ref, n : n, x : idx, ti : tableinst}: `%~>%`(`%;%`_config(z, [(ref : ref <: instr) CONST_instr(I32_numtype, `%`_num_(n)) TABLE.GROW_instr(x)]), `%;%`_config($with_tableinst(z, x, ti), [CONST_instr(I32_numtype, `%`_num_(|$table(z, x).REFS_tableinst|))])) -- if ($growtable($table(z, x), n, ref) =/= ?()) -- if (ti = !($growtable($table(z, x), n, ref))) - ;; 8-reduction.watsup:849.1-850.81 + ;; 8-reduction.watsup:852.1-853.81 rule table.grow-fail{z : state, ref : ref, n : n, x : idx}: `%~>%`(`%;%`_config(z, [(ref : ref <: instr) CONST_instr(I32_numtype, `%`_num_(n)) TABLE.GROW_instr(x)]), `%;%`_config(z, [CONST_instr(I32_numtype, `%`_num_($invsigned_(32, - (1 : nat <: int))))])) - ;; 8-reduction.watsup:910.1-911.51 + ;; 8-reduction.watsup:913.1-914.51 rule elem.drop{z : state, x : idx}: `%~>%`(`%;%`_config(z, [ELEM.DROP_instr(x)]), `%;%`_config($with_elem(z, x, []), [])) - ;; 8-reduction.watsup:994.1-997.60 + ;; 8-reduction.watsup:997.1-1000.60 rule store-num-oob{z : state, i : nat, nt : numtype, c : num_(nt), x : idx, ao : memarg}: `%~>%`(`%;%`_config(z, [CONST_instr(I32_numtype, `%`_num_(i)) CONST_instr(nt, c) STORE_instr(nt, ?(), x, ao)]), `%;%`_config(z, [TRAP_instr])) -- if (((i + ao.OFFSET_memarg!`%`_u32.0) + ($size(nt) / 8)) > |$mem(z, x).BYTES_meminst|) - ;; 8-reduction.watsup:999.1-1003.29 + ;; 8-reduction.watsup:1002.1-1006.29 rule store-num-val{z : state, i : nat, nt : numtype, c : num_(nt), x : idx, ao : memarg, b* : byte*}: `%~>%`(`%;%`_config(z, [CONST_instr(I32_numtype, `%`_num_(i)) CONST_instr(nt, c) STORE_instr(nt, ?(), x, ao)]), `%;%`_config($with_mem(z, x, (i + ao.OFFSET_memarg!`%`_u32.0), ($size(nt) / 8), b*{b : byte}), [])) -- if (b*{b : byte} = $nbytes_(nt, c)) - ;; 8-reduction.watsup:1005.1-1008.52 + ;; 8-reduction.watsup:1008.1-1011.52 rule store-pack-oob{z : state, i : nat, Inn : Inn, c : num_((Inn : Inn <: numtype)), nt : numtype, n : n, x : idx, ao : memarg}: `%~>%`(`%;%`_config(z, [CONST_instr(I32_numtype, `%`_num_(i)) CONST_instr((Inn : Inn <: numtype), c) STORE_instr(nt, ?(`%`_sz(n)), x, ao)]), `%;%`_config(z, [TRAP_instr])) -- if (((i + ao.OFFSET_memarg!`%`_u32.0) + (n / 8)) > |$mem(z, x).BYTES_meminst|) - ;; 8-reduction.watsup:1010.1-1014.52 + ;; 8-reduction.watsup:1013.1-1017.52 rule store-pack-val{z : state, i : nat, Inn : Inn, c : num_((Inn : Inn <: numtype)), nt : numtype, n : n, x : idx, ao : memarg, b* : byte*}: `%~>%`(`%;%`_config(z, [CONST_instr(I32_numtype, `%`_num_(i)) CONST_instr((Inn : Inn <: numtype), c) STORE_instr(nt, ?(`%`_sz(n)), x, ao)]), `%;%`_config($with_mem(z, x, (i + ao.OFFSET_memarg!`%`_u32.0), (n / 8), b*{b : byte}), [])) -- if (b*{b : byte} = $ibytes_(n, $wrap__($size((Inn : Inn <: numtype)), n, c))) - ;; 8-reduction.watsup:1016.1-1018.63 + ;; 8-reduction.watsup:1019.1-1021.63 rule vstore-oob{z : state, i : nat, c : vec_(V128_Vnn), x : idx, ao : memarg}: `%~>%`(`%;%`_config(z, [CONST_instr(I32_numtype, `%`_num_(i)) VCONST_instr(V128_vectype, c) VSTORE_instr(V128_vectype, x, ao)]), `%;%`_config(z, [TRAP_instr])) -- if (((i + ao.OFFSET_memarg!`%`_u32.0) + ($vsize(V128_vectype) / 8)) > |$mem(z, x).BYTES_meminst|) - ;; 8-reduction.watsup:1020.1-1022.31 + ;; 8-reduction.watsup:1023.1-1025.31 rule vstore-val{z : state, i : nat, c : vec_(V128_Vnn), x : idx, ao : memarg, b* : byte*}: `%~>%`(`%;%`_config(z, [CONST_instr(I32_numtype, `%`_num_(i)) VCONST_instr(V128_vectype, c) VSTORE_instr(V128_vectype, x, ao)]), `%;%`_config($with_mem(z, x, (i + ao.OFFSET_memarg!`%`_u32.0), ($vsize(V128_vectype) / 8), b*{b : byte}), [])) -- if (b*{b : byte} = $vbytes_(V128_vectype, c)) - ;; 8-reduction.watsup:1025.1-1027.50 + ;; 8-reduction.watsup:1028.1-1030.50 rule vstore_lane-oob{z : state, i : nat, c : vec_(V128_Vnn), N : N, x : idx, ao : memarg, j : nat}: `%~>%`(`%;%`_config(z, [CONST_instr(I32_numtype, `%`_num_(i)) VCONST_instr(V128_vectype, c) VSTORE_LANE_instr(V128_vectype, `%`_sz(N), x, ao, `%`_laneidx(j))]), `%;%`_config(z, [TRAP_instr])) -- if (((i + ao.OFFSET_memarg!`%`_u32.0) + N) > |$mem(z, x).BYTES_meminst|) - ;; 8-reduction.watsup:1029.1-1033.49 + ;; 8-reduction.watsup:1032.1-1036.49 rule vstore_lane-val{z : state, i : nat, c : vec_(V128_Vnn), N : N, x : idx, ao : memarg, j : nat, b* : byte*, Jnn : Jnn, M : M}: `%~>%`(`%;%`_config(z, [CONST_instr(I32_numtype, `%`_num_(i)) VCONST_instr(V128_vectype, c) VSTORE_LANE_instr(V128_vectype, `%`_sz(N), x, ao, `%`_laneidx(j))]), `%;%`_config($with_mem(z, x, (i + ao.OFFSET_memarg!`%`_u32.0), (N / 8), b*{b : byte}), [])) -- if (j < |$lanes_(`%X%`_shape((Jnn : Jnn <: lanetype), `%`_dim(M)), c)|) @@ -31752,17 +31768,17 @@ relation Step: `%~>%`(config, config) -- if (M = (128 / N)) -- if (b*{b : byte} = $ibytes_(N, `%`_iN($lanes_(`%X%`_shape((Jnn : Jnn <: lanetype), `%`_dim(M)), c)[j]!`%`_lane_.0))) - ;; 8-reduction.watsup:1041.1-1044.37 + ;; 8-reduction.watsup:1044.1-1047.37 rule memory.grow-succeed{z : state, n : n, x : idx, mi : meminst}: `%~>%`(`%;%`_config(z, [CONST_instr(I32_numtype, `%`_num_(n)) MEMORY.GROW_instr(x)]), `%;%`_config($with_meminst(z, x, mi), [CONST_instr(I32_numtype, `%`_num_((|$mem(z, x).BYTES_meminst| / (64 * $Ki))))])) -- if ($growmem($mem(z, x), n) =/= ?()) -- if (mi = !($growmem($mem(z, x), n))) - ;; 8-reduction.watsup:1046.1-1047.78 + ;; 8-reduction.watsup:1049.1-1050.78 rule memory.grow-fail{z : state, n : n, x : idx}: `%~>%`(`%;%`_config(z, [CONST_instr(I32_numtype, `%`_num_(n)) MEMORY.GROW_instr(x)]), `%;%`_config(z, [CONST_instr(I32_numtype, `%`_num_($invsigned_(32, - (1 : nat <: int))))])) - ;; 8-reduction.watsup:1107.1-1108.51 + ;; 8-reduction.watsup:1110.1-1111.51 rule data.drop{z : state, x : idx}: `%~>%`(`%;%`_config(z, [DATA.DROP_instr(x)]), `%;%`_config($with_data(z, x, []), [])) } diff --git a/spectec/test-prose/TEST.md b/spectec/test-prose/TEST.md index 36d0544d1a..fbad7fc17a 100644 --- a/spectec/test-prose/TEST.md +++ b/spectec/test-prose/TEST.md @@ -2137,15 +2137,7 @@ watsup 0.4 generator #. Perform :math:`{\mathrm{initdata}}({\mathit{moduleinst}}, {i_{\mathsf{d}}^\ast}, {{b^\ast}^\ast})`. -#. Push the activation of :math:`f` with arity :math:`0` to the stack. - -#. If :math:`{(\mathsf{call}~{x'})^?}` is defined, then: - - a. Let :math:`{\mathit{instr}}_0` be :math:`{(\mathsf{call}~{x'})^?}`. - - #. Execute the instruction :math:`{\mathit{instr}}_0`. - -#. Pop the activation of :math:`f` with arity :math:`0` from the stack. +#. Enter :math:`{(\mathsf{call}~{x'})^?}~\mathsf{frame}` with label the activation of :math:`f` with arity :math:`0`. #. Return :math:`f{.}\mathsf{module}`. @@ -2164,17 +2156,9 @@ watsup 0.4 generator #. Let :math:`k` be :math:`{|{t_2^\ast}|}`. -#. Push the activation of :math:`f` with arity :math:`k` to the stack. +#. Enter :math:`(\mathsf{call}~{\mathit{fa}})~\mathsf{frame}` with label the activation of :math:`f` with arity :math:`k`. -#. Push the values :math:`{{\mathit{val}}^{n}}` to the stack. - -#. Execute the instruction :math:`(\mathsf{call}~{\mathit{fa}})`. - -#. Pop all values :math:`{{\mathit{val}}^\ast}` from the top of the stack. - -#. Pop the activation of :math:`f` with arity :math:`k` from the stack. - -#. Push the values :math:`{{\mathit{val}}^\ast}` to the stack. + a. Push the values :math:`{{\mathit{val}}^{n}}` to the stack. #. Pop the values :math:`{{\mathit{val}}^{k}}` from the stack. @@ -3894,12 +3878,8 @@ instantiate z module externaddr* 27. Let f be { LOCALS: []; MODULE: moduleinst; }. 28. Perform $initelem(moduleinst, i_E*, moduleinst.FUNCS[x]**). 29. Perform $initdata(moduleinst, i_D*, b**). -30. Push the activation of f with arity 0 to the stack. -31. If (CALL x')? is defined, then: - a. Let ?(instr_0) be (CALL x')?. - b. Execute the instruction instr_0. -32. Pop the activation of f with arity 0 from the stack. -33. Return f.MODULE. +30. Enter (CALL x')? ++ [FRAME_] with label the activation of f with arity 0. +31. Return f.MODULE. invoke z fa val^n 1. Let f be { LOCALS: []; MODULE: { TYPES: []; FUNCS: []; GLOBALS: []; TABLES: []; MEMS: []; EXPORTS: []; }; }. @@ -3907,14 +3887,10 @@ invoke z fa val^n 3. Let (t_1^n -> t_2*) be $funcinst(z)[fa].TYPE. 4. Pop the activation of _f from the stack. 5. Let k be |t_2*|. -6. Push the activation of f with arity k to the stack. -7. Push the values val^n to the stack. -8. Execute the instruction (CALL_ADDR fa). -9. Pop all values val* from the top of the stack. -10. Pop the activation of f with arity k from the stack. -11. Push the values val* to the stack. -12. Pop the values val^k from the stack. -13. Return val^k. +6. Enter [(CALL_ADDR fa)] ++ [FRAME_] with label the activation of f with arity k. + a. Push the values val^n to the stack. +7. Pop the values val^k from the stack. +8. Return val^k. Step_pure/unreachable 1. Trap. @@ -7938,19 +7914,7 @@ watsup 0.4 generator #. Let :math:`f` be :math:`\{ \begin{array}[t]{@{}l@{}}\mathsf{locals}~\epsilon,\; \mathsf{module}~{\mathit{moduleinst}} \}\end{array}`. -#. Push the activation of :math:`f` with arity :math:`0` to the stack. - -#. Execute the instruction :math:`{{\mathit{instr}}_{\mathsf{e}}^\ast}`. - -#. Execute the instruction :math:`{{\mathit{instr}}_{\mathsf{d}}^\ast}`. - -#. If :math:`{(\mathsf{call}~x)^?}` is defined, then: - - a. Let :math:`{\mathit{instr}}_0` be :math:`{(\mathsf{call}~x)^?}`. - - #. Execute the instruction :math:`{\mathit{instr}}_0`. - -#. Pop the activation of :math:`f` with arity :math:`0` from the stack. +#. Enter :math:`{{\mathit{instr}}_{\mathsf{e}}^\ast}~{{\mathit{instr}}_{\mathsf{d}}^\ast}~{(\mathsf{call}~x)^?}~\mathsf{frame}` with label the activation of :math:`f` with arity :math:`0`. #. Return :math:`f{.}\mathsf{module}`. @@ -7969,17 +7933,9 @@ watsup 0.4 generator #. Let :math:`k` be :math:`{|{t_2^\ast}|}`. -#. Push the activation of :math:`f` with arity :math:`k` to the stack. - -#. Push the values :math:`{{\mathit{val}}^{n}}` to the stack. - -#. Execute the instruction :math:`(\mathsf{call}~{\mathit{fa}})`. - -#. Pop all values :math:`{{\mathit{val}}^\ast}` from the top of the stack. +#. Enter :math:`(\mathsf{call}~{\mathit{fa}})~\mathsf{frame}` with label the activation of :math:`f` with arity :math:`k`. -#. Pop the activation of :math:`f` with arity :math:`k` from the stack. - -#. Push the values :math:`{{\mathit{val}}^\ast}` to the stack. + a. Push the values :math:`{{\mathit{val}}^{n}}` to the stack. #. Pop the values :math:`{{\mathit{val}}^{k}}` from the stack. @@ -11553,14 +11509,8 @@ instantiate z module externaddr* 24. Pop the activation of _f from the stack. 25. Let moduleinst be $allocmodule(module, externaddr*, val*, ref**). 26. Let f be { LOCALS: []; MODULE: moduleinst; }. -27. Push the activation of f with arity 0 to the stack. -28. Execute the instruction instr_E*. -29. Execute the instruction instr_D*. -30. If (CALL x)? is defined, then: - a. Let ?(instr_0) be (CALL x)?. - b. Execute the instruction instr_0. -31. Pop the activation of f with arity 0 from the stack. -32. Return f.MODULE. +27. Enter instr_E* ++ instr_D* ++ (CALL x)? ++ [FRAME_] with label the activation of f with arity 0. +28. Return f.MODULE. invoke z fa val^n 1. Let f be { LOCALS: []; MODULE: { TYPES: []; FUNCS: []; GLOBALS: []; TABLES: []; MEMS: []; ELEMS: []; DATAS: []; EXPORTS: []; }; }. @@ -11568,14 +11518,10 @@ invoke z fa val^n 3. Let (t_1^n -> t_2*) be $funcinst(z)[fa].TYPE. 4. Pop the activation of _f from the stack. 5. Let k be |t_2*|. -6. Push the activation of f with arity k to the stack. -7. Push the values val^n to the stack. -8. Execute the instruction (CALL_ADDR fa). -9. Pop all values val* from the top of the stack. -10. Pop the activation of f with arity k from the stack. -11. Push the values val* to the stack. -12. Pop the values val^k from the stack. -13. Return val^k. +6. Enter [(CALL_ADDR fa)] ++ [FRAME_] with label the activation of f with arity k. + a. Push the values val^n to the stack. +7. Pop the values val^k from the stack. +8. Return val^k. Step_pure/unreachable 1. Trap. @@ -19418,19 +19364,7 @@ watsup 0.4 generator #. Let :math:`f` be :math:`\{ \begin{array}[t]{@{}l@{}}\mathsf{locals}~\epsilon,\; \mathsf{module}~{\mathit{moduleinst}} \}\end{array}`. -#. Push the activation of :math:`f` with arity :math:`0` to the stack. - -#. Execute the instruction :math:`{{\mathit{instr}}_{\mathsf{e}}^\ast}`. - -#. Execute the instruction :math:`{{\mathit{instr}}_{\mathsf{d}}^\ast}`. - -#. If :math:`{{\mathit{instr}}_{\mathsf{s}}^?}` is defined, then: - - a. Let :math:`{\mathit{instr}}_0` be :math:`{{\mathit{instr}}_{\mathsf{s}}^?}`. - - #. Execute the instruction :math:`{\mathit{instr}}_0`. - -#. Pop the activation of :math:`f` with arity :math:`0` from the stack. +#. Enter :math:`{{\mathit{instr}}_{\mathsf{e}}^\ast}~{{\mathit{instr}}_{\mathsf{d}}^\ast}~{{\mathit{instr}}_{\mathsf{s}}^?}~\mathsf{frame}` with label the activation of :math:`f` with arity :math:`0`. #. Return :math:`f{.}\mathsf{module}`. @@ -19451,19 +19385,11 @@ watsup 0.4 generator #. Let :math:`k` be :math:`{|{t_2^\ast}|}`. -#. Push the activation of :math:`f` with arity :math:`k` to the stack. +#. Enter :math:`(\mathsf{call\_ref}~s{.}\mathsf{funcs}{}[{\mathit{funcaddr}}]{.}\mathsf{type})~\mathsf{frame}` with label the activation of :math:`f` with arity :math:`k`. -#. Push the values :math:`{{\mathit{val}}^\ast}` to the stack. - -#. Push the value :math:`(\mathsf{ref{.}func}~{\mathit{funcaddr}})` to the stack. - -#. Execute the instruction :math:`(\mathsf{call\_ref}~s{.}\mathsf{funcs}{}[{\mathit{funcaddr}}]{.}\mathsf{type})`. - -#. Pop all values :math:`{{\mathit{val}}^\ast}` from the top of the stack. - -#. Pop the activation of :math:`f` with arity :math:`k` from the stack. + a. Push the values :math:`{{\mathit{val}}^\ast}` to the stack. -#. Push the values :math:`{{\mathit{val}}^\ast}` to the stack. + #. Push the value :math:`(\mathsf{ref{.}func}~{\mathit{funcaddr}})` to the stack. #. Pop the values :math:`{{\mathit{val}}^{k}}` from the stack. @@ -20688,51 +20614,61 @@ watsup 0.4 generator #. Execute the instruction :math:`(\mathsf{return\_call\_ref}~y)`. -#. Else if the top of the stack is a :math:`\mathsf{frame}`, then: +#. Else if the top of the stack is a :math:`\mathsf{handler}`, then: a. Push the values :math:`{{\mathit{val}}^\ast}` to the stack. - #. Assert: Due to validation, a value is on the top of the stack. + #. Pop all values :math:`{{\mathit{val}}^\ast}` from the top of the stack. - #. Pop the value :math:`{\mathit{instr}}_{\mathit{u{\kern-0.1em\scriptstyle 0}}}` from the stack. + #. Exit from :math:`\mathsf{handler}`. - #. Pop all values :math:`{{\mathit{val}}^\ast}` from the top of the stack. + #. Push the values :math:`{{\mathit{val}}^\ast}` to the stack. + + #. Execute the instruction :math:`(\mathsf{return\_call\_ref}~y)`. - #. If :math:`{\mathit{instr}}_{\mathit{u{\kern-0.1em\scriptstyle 0}}}` is of the case :math:`\mathsf{ref{.}null}`, then: +#. Else: - 1) Pop the current frame from the stack. + a. If the top of the stack is a :math:`\mathsf{frame}`, then: - #) Trap. + 1) Push the values :math:`{{\mathit{val}}^\ast}` to the stack. - #. Assert: Due to validation, a value is on the top of the stack. + #) Assert: Due to validation, a value is on the top of the stack. - #. Pop the value :math:`{\mathit{instr}}_{\mathit{u{\kern-0.1em\scriptstyle 0}}}` from the stack. + #) Pop the value :math:`{\mathit{instr}}_{\mathit{u{\kern-0.1em\scriptstyle 0}}}` from the stack. - #. If :math:`{\mathit{instr}}_{\mathit{u{\kern-0.1em\scriptstyle 0}}}` is of the case :math:`\mathsf{ref{.}func}`, then: + #) Pop all values :math:`{{\mathit{val}}^\ast}` from the top of the stack. - 1) Let :math:`(\mathsf{ref{.}func}~a)` be :math:`{\mathit{instr}}_{\mathit{u{\kern-0.1em\scriptstyle 0}}}`. + #) If :math:`{\mathit{instr}}_{\mathit{u{\kern-0.1em\scriptstyle 0}}}` is of the case :math:`\mathsf{ref{.}null}`, then: - #) If :math:`a` is less than :math:`{|z{.}\mathsf{funcs}|}`, then: + a) Pop the current frame from the stack. - a) Assert: Due to validation, :math:`{\mathrm{expand}}(z{.}\mathsf{funcs}{}[a]{.}\mathsf{type})` is of the case :math:`\mathsf{func}`. + #) Trap. - #) Let :math:`(\mathsf{func}~{\mathit{functype}}_0)` be :math:`{\mathrm{expand}}(z{.}\mathsf{funcs}{}[a]{.}\mathsf{type})`. + #) If :math:`{\mathit{instr}}_{\mathit{u{\kern-0.1em\scriptstyle 0}}}` is of the case :math:`\mathsf{ref{.}func}`, then: - #) Let :math:`({t_1^{n}}~\rightarrow~{t_2^{m}})` be :math:`{\mathit{functype}}_0`. + a) Let :math:`(\mathsf{ref{.}func}~a)` be :math:`{\mathit{instr}}_{\mathit{u{\kern-0.1em\scriptstyle 0}}}`. - #) Assert: Due to validation, there are at least :math:`n` values on the top of the stack. + #) If :math:`a` is less than :math:`{|z{.}\mathsf{funcs}|}`, then: - #) Pop the values :math:`{{\mathit{val}}^{n}}` from the stack. + 1. Assert: Due to validation, :math:`{\mathrm{expand}}(z{.}\mathsf{funcs}{}[a]{.}\mathsf{type})` is of the case :math:`\mathsf{func}`. - #) Pop all values :math:`{{\mathit{val}'}^\ast}` from the top of the stack. + #. Let :math:`(\mathsf{func}~{\mathit{functype}}_0)` be :math:`{\mathrm{expand}}(z{.}\mathsf{funcs}{}[a]{.}\mathsf{type})`. - #) Pop the current frame from the stack. + #. Let :math:`({t_1^{n}}~\rightarrow~{t_2^{m}})` be :math:`{\mathit{functype}}_0`. + + #. Assert: Due to validation, there are at least :math:`n` values on the top of the stack. + + #. Pop the values :math:`{{\mathit{val}}^{n}}` from the stack. + + #. Pop all values :math:`{{\mathit{val}'}^\ast}` from the top of the stack. + + #. Pop the current frame from the stack. - #) Push the values :math:`{{\mathit{val}}^{n}}` to the stack. + #. Push the values :math:`{{\mathit{val}}^{n}}` to the stack. - #) Push the value :math:`(\mathsf{ref{.}func}~a)` to the stack. + #. Push the value :math:`(\mathsf{ref{.}func}~a)` to the stack. - #) Execute the instruction :math:`(\mathsf{call\_ref}~y)`. + #. Execute the instruction :math:`(\mathsf{call\_ref}~y)`. :math:`\mathsf{throw\_ref}` @@ -26235,14 +26171,8 @@ instantiate z module externaddr* 27. Pop the activation of _f from the stack. 28. Let moduleinst be $allocmodule(module, externaddr*, val_G*, ref_T*, ref_E**). 29. Let f be { LOCALS: []; MODULE: moduleinst; }. -30. Push the activation of f with arity 0 to the stack. -31. Execute the instruction instr_E*. -32. Execute the instruction instr_D*. -33. If instr_S? is defined, then: - a. Let ?(instr_0) be instr_S?. - b. Execute the instruction instr_0. -34. Pop the activation of f with arity 0 from the stack. -35. Return f.MODULE. +30. Enter instr_E* ++ instr_D* ++ instr_S? ++ [FRAME_] with label the activation of f with arity 0. +31. Return f.MODULE. invoke funcaddr val* 1. Let f be { LOCALS: []; MODULE: { TYPES: []; FUNCS: []; GLOBALS: []; TABLES: []; MEMS: []; TAGS: []; ELEMS: []; DATAS: []; EXPORTS: []; }; }. @@ -26251,15 +26181,11 @@ invoke funcaddr val* 4. Let (t_1* -> t_2*) be functype_0. 5. Assert: Due to validation, ($Val_type(val) is t_1)*. 6. Let k be |t_2*|. -7. Push the activation of f with arity k to the stack. -8. Push the values val* to the stack. -9. Push the value (REF.FUNC_ADDR funcaddr) to the stack. -10. Execute the instruction (CALL_REF s.FUNCS[funcaddr].TYPE). -11. Pop all values val* from the top of the stack. -12. Pop the activation of f with arity k from the stack. -13. Push the values val* to the stack. -14. Pop the values val^k from the stack. -15. Return val^k. +7. Enter [(CALL_REF s.FUNCS[funcaddr].TYPE)] ++ [FRAME_] with label the activation of f with arity k. + a. Push the values val* to the stack. + b. Push the value (REF.FUNC_ADDR funcaddr) to the stack. +8. Pop the values val^k from the stack. +9. Return val^k. allocXs X Y X_u0* Y_u1* 1. If (X_u0* is []), then: @@ -26839,7 +26765,13 @@ Step_read/return_call_ref yy c. Pop the current label from the stack. d. Push the values val* to the stack. e. Execute the instruction (RETURN_CALL_REF yy). -4. Else if the top of the stack is a FRAME_, then: +4. Else if the top of the stack is a HANDLER_, then: + a. Push the values val* to the stack. + b. Pop all values val* from the top of the stack. + c. Exit from HANDLER_. + d. Push the values val* to the stack. + e. Execute the instruction (RETURN_CALL_REF yy). +5. Else if the top of the stack is a FRAME_, then: a. Push the values val* to the stack. b. Assert: Due to validation, a value is on the top of the stack. c. Pop the value instr_u0 from the stack. @@ -26847,9 +26779,7 @@ Step_read/return_call_ref yy e. If instr_u0 is of the case REF.NULL, then: 1) Pop the current frame from the stack. 2) Trap. - f. Assert: Due to validation, a value is on the top of the stack. - g. Pop the value instr_u0 from the stack. - h. If instr_u0 is of the case REF.FUNC_ADDR, then: + f. If instr_u0 is of the case REF.FUNC_ADDR, then: 1) Let (REF.FUNC_ADDR a) be instr_u0. 2) If (a < |$funcinst(z)|), then: a) Assert: Due to validation, $expanddt($funcinst(z)[a].TYPE) is of the case FUNC. diff --git a/spectec/test-splice/TEST.md b/spectec/test-splice/TEST.md index f03e9edc0b..acdc5cd17b 100644 --- a/spectec/test-splice/TEST.md +++ b/spectec/test-splice/TEST.md @@ -1042,6 +1042,7 @@ warning: rule `Step_read/call_ref-null` was never spliced warning: rule `Step_read/call_ref-func` was never spliced warning: rule `Step_read/return_call` was never spliced warning: rule `Step_read/return_call_ref-label` was never spliced +warning: rule `Step_read/return_call_ref-handler` was never spliced warning: rule `Step_read/return_call_ref-frame-null` was never spliced warning: rule `Step_read/return_call_ref-frame-addr` was never spliced warning: rule `Step_read/throw_ref-null` was never spliced