~thestr4ng3r/wasmcert-isabelle

2d8d14bbbae3aacd3a8941db87253c67d80a1b86 — Florian Märkl 1 year, 4 months ago 53027ee
Make Demo even nicer
M WebAssembly/Demo/Demo.thy => WebAssembly/Demo/Demo.thy +47 -16
@@ 2,28 2,59 @@ theory Demo
  imports WebAssembly_SML.Reflect Show.Show_Instances
begin

text\<open>Helper function for running\<close>
ML\<open>
val (module, s, i, exps, start) = load @{theory} "block.wasm"
val state = Wasm.c_init s (Wasm.nat_of_integer 0) []
fun run_and_show state fuel =
  let
    val _ = if fuel > 0 then run_and_show state (fuel - 1) else ()
    val s's = case Wasm.c_run (Wasm.nat_of_integer fuel) state of
        (Wasm.Set s') => s'
      | _ => raise (Fail "unexpected set")
  in
    writeln ("After " ^ (Int.toString fuel) ^ " steps:");
    if length s's = 1 then
      let
        val s' = List.nth (s's, 0)
      in
        writeln ("  program counter: " ^ (Int.toString (Wasm.integer_of_nat (Wasm.c_ei (Wasm.c_pc s')))));
        writeln ("  value stack:     " ^ (Wasm.show_vs (Wasm.val_stack s')));
        writeln ("  reconstruction:  " ^ Wasm.show_es (Wasm.c_es s'));
        if Wasm.terminated s' then writeln "  TERMINATED! ==================================" else ()
      end
    else
      writeln ("  " ^ Int.toString (length s's) ^ " states")
  end

fun show_function s i =
  let
    val es = case List.nth (Wasm.funcs s, i) of
      Wasm.Func_native (_, _, _, es) => es
      | _ => raise (Fail "not a native function")
    val r = Wasm.show_b_es es
  in
    writeln r
  end
\<close>

text\<open>
Load a module from a binary file.
This includes full type-checking and instantiation.
\<close>
ML\<open>val (module, s, i, exps, start) = load @{theory} "block.wasm"\<close>

ML\<open>
val _ = let
  val (Wasm.Set s') = Wasm.c_run  (Wasm.nat_of_integer 4) state
  val r = Wasm.show_es (Wasm.c_es (List.nth (s', 0)))
in
  writeln r
end
text\<open>
Inspect the raw code of function 0 in the instantiated store.
\<close>
ML\<open>val _ = show_function s 0\<close>

ML\<open>
let
  val Wasm.Func_native (_, _, _, es) = List.nth (Wasm.funcs s, 0)
  val r = Wasm.show_b_es es
in
  writeln r
end
text\<open>
Initialize our interpreter using function 0 as the entrypoint
\<close>
ML\<open>val state = Wasm.c_init s (Wasm.nat_of_integer 0) []\<close>

text\<open>
Run and reconstruct!
\<close>
ML\<open>val _ = run_and_show state 10\<close>

end
\ No newline at end of file

D WebAssembly/Demo/add.wasm => WebAssembly/Demo/add.wasm +0 -0
A WebAssembly/Demo/block.wat => WebAssembly/Demo/block.wat +13 -0
@@ 0,0 1,13 @@
(module
 (export "block" (func $block))
 (func $block (result i32)
  (local i32)
  i32.const 13
  i32.const 34
  block (param i32) (result i32)
   local.get 0
   i32.add
  end
  drop
 )
)

A WebAssembly/Demo/linear.wat => WebAssembly/Demo/linear.wat +10 -0
@@ 0,0 1,10 @@
(module
 (export "linear" (func $linear))
 (func $linear (result i32)
  i32.const 34
  i32.const 13
  i32.sub
  i32.const 2
  i32.mul
 )
)

M WebAssembly/PC_Interpreter/Interpreter.thy => WebAssembly/PC_Interpreter/Interpreter.thy +4 -4
@@ 56,13 56,13 @@ Cheating function to forcefully bring a list to at least a given length.
Our use-cases would not necessarily need it as the lengths could be shown from typing too,
but this requires significant additional effort and it is irrelevant for what we are trying to show.
\<close>
definition fill_length :: "nat \<Rightarrow> 'a list \<Rightarrow> 'a list" where
  "fill_length n l \<equiv> l @ replicate (n - length l) undefined"
definition fill_length :: "nat \<Rightarrow> v list \<Rightarrow> v list" where
  "fill_length n l \<equiv> l @ replicate (n - length l) (ConstInt32 0)" \<comment>\<open>ConstInt32 0 could be just undefined here. But then SML crashes because it's strict :-(\<close>

definition rip :: "nat \<Rightarrow> 'a list \<Rightarrow> 'a list" where
definition rip :: "nat \<Rightarrow> v list \<Rightarrow> v list" where
  "rip n l = fill_length n (take n l)"

definition tear :: "nat \<Rightarrow> 'a list \<Rightarrow> 'a list" where
definition tear :: "nat \<Rightarrow> v list \<Rightarrow> v list" where
  "tear n l \<equiv> fill_length n (tail n l)"

definition c_return_vs :: "c_state \<Rightarrow> v list" where

M WebAssembly/SML/Printing.thy => WebAssembly/SML/Printing.thy +1 -0
@@ 272,6 272,7 @@ instance apply standard unfolding equal_mem_rep_def .. end

definition show_es :: "e list \<Rightarrow> String.literal" where "show_es es \<equiv> String.implode (show es)"
definition show_b_es :: "b_e list \<Rightarrow> String.literal" where "show_b_es bs \<equiv> String.implode (show bs)"
definition show_vs :: "v list \<Rightarrow> String.literal" where "show_vs vs \<equiv> String.implode (show vs)"

export_code open m_imports module_type_checker interp_instantiate typing run c_run
  in SML module_name WasmRef_Isa file_prefix WasmRef_Isa

M WebAssembly/SML/Reflect.thy => WebAssembly/SML/Reflect.thy +2 -2
@@ 15,8 15,8 @@ code_reflect Wasm
    and module_import_ext = _ and module_export_ext = _
    and s_ext = _
  functions m_imports module_type_checker interp_instantiate typing run c_run
    nat_of_integer SML_int32_to_isabelle_int32 SML_int64_to_isabelle_int64 SML_char_to_isabelle_byte
    c_init c_step c_run c_es s.funcs show_es show_b_es Func_native set
    nat_of_integer integer_of_nat SML_int32_to_isabelle_int32 SML_int64_to_isabelle_int64 SML_char_to_isabelle_byte
    c_init c_step c_run c_es s.funcs show_es show_b_es Func_native set terminated val_stack c_ei c_pc show_vs

ML_file "Decode.ML"