0% found this document useful (0 votes)
95 views12 pages

Mechanising and Verifying The WebAssembly Specification 'At The Top Level'

The document summarizes a study that mechanized and verified the WebAssembly specification in the Isabelle proof assistant. It presents a mechanized specification of the WebAssembly language semantics and type system, along with a verified executable interpreter and type checker. It also details a fully mechanized proof of soundness for the WebAssembly type system, which uncovered issues in the official specification that influenced its development. The work aims to increase confidence in the WebAssembly specification through formal verification.

Uploaded by

Jason Wong
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
95 views12 pages

Mechanising and Verifying The WebAssembly Specification 'At The Top Level'

The document summarizes a study that mechanized and verified the WebAssembly specification in the Isabelle proof assistant. It presents a mechanized specification of the WebAssembly language semantics and type system, along with a verified executable interpreter and type checker. It also details a fully mechanized proof of soundness for the WebAssembly type system, which uncovered issues in the official specification that influenced its development. The work aims to increase confidence in the WebAssembly specification through formal verification.

Uploaded by

Jason Wong
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 12

Mechanising and Verifying the WebAssembly

Specification
Conrad Watt
University of Cambridge
[email protected]
Abstract Attempts to offer a more appropriate language in the
WebAssembly is a new low-level language currently being browser as a compilation target, most notably Google’s Na-
implemented in all major web browsers. It is designed to tive Client [Google 2017], have until now met with low adop-
become the universal compilation target for the web, obsolet- tion rates and patchwork support across different browsers.
ing existing solutions in this area, such as asm.js and Native WebAssembly is the first true cross-party offering in this
Client. The WebAssembly working group has incorporated area. It is just as much the result of a political process as
formal techniques into the development of the language, but it is a technical one: the WebAssembly working group con-
their efforts so far have focussed on pen and paper formal tains representatives from Google, Microsoft, Apple, and
specification. Mozilla, and each of these companies have committed to
We present a mechanised Isabelle specification for the fully supporting WebAssembly in their respective browsers.
WebAssembly language, together with a verified executable WebAssembly is designed to be embedded within a host
interpreter and type checker. Moreover, we present a fully environment. The canonical example is a WebAssembly im-
mechanised proof of the soundness of the WebAssembly type plementation running inside a web browser’s JavaScript en-
system, and detail how our work on this proof has exposed gine. When a host program invokes a WebAssembly func-
several issues with the official WebAssembly specification, tion, the function executes in a sandbox that cannot access
influencing its development. Finally, we give a brief account the host’s wider state. The host program can either simply
of our efforts in performing differential fuzzing of our inter- be a thin wrapper around a self-contained WebAssembly
preter against industry implementations. function, or can choose to call out to WebAssembly only at
certain points where efficiency is desired. It is anticipated
that the majority of WebAssembly code will be produced
1 Introduction through compilation from C/C++, using the official Binaryen
JavaScript’s continued monopoly on the modern web has toolchain [WebAssembly Community Group 2017a].
caused the ecosystem to develop in unintuitive ways. De- The designers of WebAssembly have made it an explicit
spite its original design as a high-level scripting language, goal to specify the language in a way that makes it amenable
a significant proportion of JavaScript currently running on to formal analysis and verification. The draft specifica-
the web is generated by compilation from C/C++, targetting tion [WebAssembly Community Group 2017d] explains all
the asm.js subset. JavaScript was never designed to be a low- semantic behaviour both in English prose, and with an ac-
level compilation target, and even the severe restrictions of companying natural deduction style formal rule. Moreover,
asm.js, disallowing nearly all of its dynamic behaviour, are members of the working group have recently produced a
not enough to save asm.js code from significant performance paper that details a non-mechanised formal semantics for a
penalties compared to native compilation [Zakai and Nyman large core of the language [Haas et al. 2017a]. This paper, and
2013]. the official specification, both state that the WebAssembly
Furthermore, the ubiquity of asm.js has placed unexpected type system enjoys several soundness properties.
and arguably inappropriate pressures on the evolution of the We have produced a full Isabelle mechanisation of the core
JavaScript specification. For example, a proposal to expose na- execution semantics and type system of the WebAssembly
tive SIMD vector instructions and types has recently reached language (§3). In addition, we have created a mechanised
the final candidate stage for inclusion into the JavaScript proof for the type soundness properties stated in the working
specification [TC39 2017b]. SIMD instructions are normally group’s paper. In order to complete this proof, several defi-
only explicitly utilised at the level of native assembly, or ciencies in the official WebAssembly specification, uncovered
in the lowest-level C/C++ programs to eke out a final few by our proof and modelling work, needed to be corrected
percent of performance in arithmetic-heavy algorithms. The by the specification authors (§4). In some cases, these meant
proposed feature is motivated by a desire to increase the that the type system was originally unsound.
efficiency of C/C++ code compiled to JavaScript, but it also We have maintained a constructive dialogue with elements
bloats the specification, complicates JavaScript engine opti- of the working group, mechanising and verifying new fea-
misations, and is practically unusable in hand-coded scripts. tures as they are added to the specification. In particular, the
1
i32.const n 7→ EConst (ConstInt32 n)

i32.const 4
i32.const 2 i32.add 7→ Unop_i T_i32 Add
i32.const 1 { i32.const 4 {
i32.add i32.const 3 loop
i32.add i32.add i32.const 7 e1 7→ Loop ([] _> [])
e2 [e1, e2, ...]
Figure 1. A trivial WebAssembly stack, reduced according to
...
the language’s small-step semantics. end

Figure 2. A selection of mappings from concrete opcodes (tex-


tual representation) to abstract operations (specification repre-
sentation, in Isabelle).
loop label <c> loop
i32.const 4 i32.const 4 i32.const 4
i32.const 2 i32.const 2 label <c> i32.const 2
i32.const 1 { i32.const 1 { i32.const 4 { { i32.const 1
i32.add i32.add i32.const 3 label <c> i32.add
i32.add i32.add i32.add i32.const 7 i32.add
br 0 br 0 br 0 br 0 br 0
end end end end end

Figure 3. A WebAssembly stack illustrating the behaviour of the loop opcode.

mechanism by which a WebAssembly implementation inter- of a simple WebAssembly program according to this relation.
faces with its host environment was not formally specified This example is given in (slightly simplified) WebAssembly
in the working group’s original paper. Extending our mech- text format, an officially supported textual representation
anisation to model this feature revealed a deficiency in the designed to present WebAssembly bytecode in a human-
WebAssembly specification that sabotaged the soundness of readable way.
the type system. WebAssembly is not a large language. Its official specifi-
We have also defined a separate verified executable inter- cation defines 171 individual opcodes [WebAssembly Com-
preter (§6) and type checker (§5). Like many verified lan- munity Group 2017b], but each of these can be viewed as
guage implementations, these artefacts require integration different specialisations of the 28 abstract operations spec-
with an external parser and linker to run as standalone pro- ified in the working group’s paper [Haas et al. 2017a]. All
grams, which introduces an untrusted interface. We use the WebAssembly behaviour is specified at the level of abstract
official reference WebAssembly interpreter, implemented operations, not concrete opcodes.
in Ocaml, for this purpose. Our core proofs of correctness WebAssembly makes it an explicit goal to eliminate un-
allow us to experimentally validate our mechanised specifi- defined behaviour from the specification [Haas et al. 2017a].
cation using our executable interpreter, both by leveraging Its heap is a linear array of bytes and all accesses are bounds-
the official WebAssembly conformance test suite, and by con- checked, and there is no integer-pointer distinction when
ducting fuzzing experiments. These initial validation efforts addressing into it. In addition, WebAssembly value types
are detailed towards the end of the paper (§7). have no trap representations; every sequence of 32 or 64
All Isabelle and OCaml code discussed in this paper is bits can be deserialised into a valid value of any type of the
included in the supplementary materials, and will shortly be appropriate length. WebAssembly requires all programs to
released publicly under a BSD-style license. At a rough count, undergo validation (type checking) before they can be ex-
our work contains ~11,000 non-whitespace, non-comment ecuted. This allows a number of properties to be statically
lines of Isabelle code, with the mechanisation of the specifi- checked. For example, it is a type error if an operation stati-
cation itself coming to ~700 lines of code. cally accesses a local variable index that is out of bounds.
The design of the language also attempts to minimise non-
2 The structure of WebAssembly determinism. There are only two sources of non-determinism
in “pure" WebAssembly. Firstly, the bit representation of NaN
WebAssembly is a stack-based, bytecode language. Its exe- floating point values is not precisely specified, and implemen-
cution semantics are naturally specified using a small-step tations are free to have multiple NaN representations which
reduction relation. Figure 1 is an illustration of the execution
2
they may choose to use non-deterministically. Secondly, the terminates. WebAssembly’s unique approach to control flow
grow_memory instruction, which allocates additional memory is a significant component of the challenge in proving type
to the heap, is allowed to fail non-deterministically. soundness and correctness properties of implementations,
The other source of non-determinism is interaction with especially since a single br instruction can break multiple
the host environment. A WebAssembly implementation may loops at once (although only the outermost, “targetted" loop
invoke host functions, effectively API calls which transfer will have its continuation pushed).
control to the host environment. The behaviour of these host When relating the loop instruction to the Loop abstract
functions is specified as entirely non-deterministic, subject operation (Figure 2), notice how a function type annotation
to certain restrictions designed to preserve the integrity of ([] _> []) is introduced. In the current WebAssembly
the WebAssembly state, which will be discussed in more specification, control flow opcodes are not allowed to ma-
detail in our section on the soundness proof (§4). nipulate values which occur outside their own inner con-
text [Haas et al. 2017a]. Therefore, the type of the arguments
2.1 The semantics of WebAssembly to the abstract operation will always be the empty list. How-
Throughout this section, we will use extracts from our Is- ever, allowing these constructs to accept arguments is a
abelle mechanisation of the specification to illustrate fun- planned future feature, and therefore the abstract operation
damental components of the language. Unless otherwise supports this.
stated, these definitions correspond exactly to those of the of- A selection of reduction rules and an AST extension for
ficial specification [WebAssembly Community Group 2017d], administrative operations can be found in Figure 5. The ad-
aside from the minor syntactic differences inherant in mech- ministrative operations are Trap, which represents an unre-
anisation. Our Isabelle representation of the language’s core coverable error, Callcl (also named Invoke in some versions
AST can be found in Figure 4, and a mapping of some perti- of the specification) which represents the invocation of a
nent concrete opcodes to abstract operations of the AST is function closure, Label, which represents a section of code
given in Figure 2. that can be broken out of by Br, and Local, which represents
As the inclusion of a “loop" opcode in this mapping may the local context of an invoked function.
have hinted, WebAssembly’s approach to control flow is un- This Isabelle definition that we provide here differs from
usual. Unlike most other bytecode languages, WebAssembly the official specification in one minor way. The specifica-
does not contain any mechanism for unstructured control tion’s reduction semantics define an execution context struc-
flow, such as branch or goto. Instead its binary format explic- ture of a single hole surrounded by nested labels. This struc-
itly includes the loop, if, and block instructions, which cre- ture is dependently typed; one of the structure’s elements is
ate a form of structured control flow by bookending sections a number which must be equal to the number of labels recur-
of the stack. This behaviour is illustrated in Figure 3. Notice sively nested within itself. This requires type-level arithmetic
how the original “linear" program of Figure 1 is bookended to implement. Since Isabelle does not support this, we im-
with the loop and end opcodes, which form an evaluation plement the dependent restrictions on the structure using a
context. The first step of reducing the loop is to convert “well-formed" predicate, Lfilled, the rules for which can also
it to the “administrative instruction" label. Administrative be found in Figure 5. Intuitively, Lfilled k lholed es les
instructions (hereafter, “administrative operations") are not can be read as "les is the result of filling in the k-nested
part of the binary format. They are purely specification con- execution context lholed with es". In practice, all semantic
trivances, extensions to the core abstract operations designed rules and proofs can be expressed in terms of Lfilled, and
to keep track of intermediate state during a reduction. The the underlying structure of the execution context is only
conversion from loop to label effectively unrolls the loop inspected during our proofs.
once, with the (abbreviated) continuation element of the la- The full reduction relation for WebAssembly is defined
bel, <c>, keeping track of the operations which make up the between configurations, which consist of a stack of abstract
continuation of the loop. This becomes relevant when paired operations, together with a program store and a list of local
with the br instruction. variables, and an instance index which indicates which parts
The br instruction is officially named “branch" in the spec- of the global store are “owned" by the currently running pro-
ification, but it functions more like a combination of the gram. For example, the Call rule pushes a closure object onto
JavaScript break and continue statements: br n transfers the stack selected using the sfunc operation, which looks up
execution to end of the nth innermost evaluation context the appropriate closure based on the current instance index
(zero indexed), effectively popping all intervening instruc- together with the call index. Parts of the reduction relation
tions from the stack. When a label is targetted in this way, its may be elided where they are not involved in a particular
continuation element is then pushed onto the stack. This has rule. For example, the Label_Trap rule describes the propa-
the effect of bringing the loop to its next iteration. If control gation of exceptions through enclosing labels, and does not
falls off the end of the label without executing a br instruc- depend on the current instance, the store, or local variables.
tion, the continuation is discarded and the loop therefore
3
— values — value and function types
datatype (’a,’b,’c,’d) datatype
v = t = T_i32 | T_i64 | T_f32 | T_f64
ConstInt32 ’a datatype
| ConstInt64 ’b tf = Tf "t list" "t list" ("_ ’_> _" 60)
| ConstFloat32 ’c
| ConstFloat64 ’d — global variables (with mutability flag)
datatype
— basic expressions mut = T_immut | T_mut
datatype (’a,’b,’c,’d) record (’a,’b,’c,’d) global =
b_e = g_mut :: mut
Unreachable g_val :: "(’a,’b,’c,’d) v"
| Nop
| Drop — packed types and signedness bit (for memory accesses)
| Select datatype
| Block tf "((’a,’b,’c,’d) b_e) list" tp = Tp_i8 | Tp_i16 | Tp_i32
| Loop tf "((’a,’b,’c,’d) b_e) list" datatype
| If tf sx = S | U
"((’a,’b,’c,’d) b_e) list"
"((’a,’b,’c,’d) b_e) list" — function closures
| Br i datatype (’a,’b,’c,’d,’host)
| Br_if i cl =
| Br_table "i ne_list" Func_native i tf "t list" "((’a,’b,’c,’d) b_e) list"
| Return | Func_host tf ’host
| Call i
| Call_indirect i — instances
| Get_local i record (’a,’b,’c,’d,’host) inst =
| Set_local i types :: "tf list"
| Tee_local i funcs :: "i list"
| Get_global i tab :: "i option"
| Set_global i mem :: "i option"
| Load t "(tp × sx) option" a off globs :: "i list"
| Store t "tp option" a off
| Current_memory — function tables
| Grow_memory type_synonym (’a,’b,’c,’d,’host) tabinst =
| EConst "(’a,’b,’c,’d) v" ("C _" 60) "(((’a,’b,’c,’d,’host) cl) option) list"
| Unop_i t unop_i
| Unop_f t unop_f — the program store
| Binop_i t binop_i record (’a,’b,’c,’d,’meminst,’host) s =
| Binop_f t binop_f inst :: "((’a,’b,’c,’d,’host) inst) list"
| Testop t testop funcs :: "((’a,’b,’c,’d,’host) cl) list"
| Relop_i t relop_i tab :: "((’a,’b,’c,’d,’host) tabinst) list"
| Relop_f t relop_f mem :: "’meminst list"
| Cvtop t cvtop t "sx option" globs :: "((’a,’b,’c,’d) global) list"
type_synonym i = nat
datatype unop_i = Clz | Ctz | Popcnt
datatype unop_f = Neg | Abs | Ceil | Floor | Trunc | Nearest | Sqrt
datatype binop_i = Add | Sub | Mul | Div sx | Rem sx | And | Or | Xor | Shl | Shr sx | Rotl | Rotr
datatype binop_f = Addf | Subf | Mulf | Divf | Min | Max | Copysign
datatype testop = Eqz
datatype relop_i = Eq | Ne | Lt sx | Gt sx | Le sx | Ge sx
datatype relop_f = Eqf | Nef | Ltf | Gtf | Lef | Gef
datatype cvtop = Convert | Reinterpret

Figure 4. Core WebAssembly AST and supporting definitions, as they appear in our Isabelle model. Values, expressions,
and components of the program store are parameterised by type variables so as to abstract the underlying representation of
WebAssembly types, the heap, and the host environment.

4
— administrative instructions
datatype (’a,’b,’c,’d,’host)
e =
Basic "(’a,’b,’c,’d) b_e" ("$_" 60)
| Trap
| Callcl "(’a,’b,’c,’d,’host) cl"
| Label nat "((’a,’b,’c,’d,’host) e) list" "((’a,’b,’c,’d,’host) e) list"
| Local nat i "((’a,’b,’c,’d) v) list" "((’a,’b,’c,’d,’host) e) list"

app_binop_i iop c1 c2 = (Some c)


Binop_i32_Some
(|[$i32.const c1, $i32.const c2, $(Binop_i T_i32 iop)]|) { (|[$i32.const c]|)

app_binop_i iop c1 c2 = None


Binop_i32_None
(|[$i32.const c1, $i32.const c2, $(Binop_i T_i32 iop)]|) { (|[Trap]|)

const_list vs
Label_Trap Label_Const
(|[Label n es [Trap]]|) { (|[Trap]|) (|[Label n es vs]|) { (|vs|)

length vi = j
Get_Local
(|s;(vi @ [v] @ vs);[$(Get_local j)]|) {_i (|s;(vi @ [v] @ vs);[$(C v)]|)

Call
(|s;vs;[$(Call j)]|) {_i (|s;vs;[Callcl (sfunc s i j)]|)

cl = Func_native j (t1s _> t2s) ts es ves = ($$* vcs)


length vcs = length t1s length t2s = m zeros ts = zs
Callcl
(|s;vs;ves @ [Callcl cl]|) {_i (|s;vs;[Local m j (vcs@zs) [$(Block ([] _> t2s) es)]]|)

— Definitions (type variables elided)


— an execution context of nested labels with a single hole inductive reduce_simple :: "[e list, e list] ⇒ bool" and
— (type variables elided for brevity) reduce :: "[s, v list, e list, nat, s, v list, e list] ⇒ bool"
datatype (snip) — Abbreviations
Lholed = (|es|) { (|es’|) ≡ reduce_simple es es’
— L0 = e* [<hole>] e* (|s;vs;es|) {_i (|s’;vs’;es’|) ≡ reduce s vs es i s’ vs’ es’
LBase "e list" "e list" C ≡ EConst
— L(i+1) = e* (Label n e* Li) e* $ ≡ Basic
| LRec "e list" nat "e list" Lholed "e list" $* es ≡ map $ es
$$* ves ≡ map (λv. $C v) ves

lholed = (LBase vs es’) const_list vs (|es|) { (|es’|)


L0 Reduce_Simple
Lfilled 0 lholed es (vs @ es @ es’) (|s;vs;es|) {_i (|s;vs;es’|)

Lfilled k lk es lfilledk lholed = (LRec vs n es’ lk es’’) const_list vs


LN
Lfilled (k+1) lholed es (vs @ [Label n es’ lfilledk] @ es’’)

(|s;vs;es|) {_i (|s’;vs’;es’|) Lfilled k lholed es les Lfilled k lholed es’ les’
Label_Context
(|s;vs;les|) {_i (|s’;vs’;les’|)

(|s;vs;es|) {_i (|s’;vs’;es’|)


Local_Context
(|s;v0s;[Local n i vs es]|) {_j (|s’;v0s;[Local n i vs’ es’]|)

Lfilled i lholed (vs @ [$(Br i)]) lfilled length vs = n const_list vs


Br
[Label n es lfilled]|) { (|vs @ es|)

Figure 5. A selection of reduction rules as they appear in our Isabelle model, re-formatted in a natural deduction style.
5
record t_context =
types_t :: "tf list"
— definition
func_t :: "tf list"
inductive b_e_typing :: "[t_context, ((’a,’b,’c,’d) b_e) list, tf] ⇒ bool"
global :: "tg list"
— abbreviation
table :: "nat option"
(C ⊢ es : tf) ≡ b_e_typing C es tf
memory :: "nat option"
local :: "t list" is_int_t t
label :: "(t list) list" Binop_i
C ⊢ [Binop_i t _] : ([t,t] _> [t])
return :: "(t list) option"

tf = (tn _> tm) C(|label := ([tn] @ (label C))|) ⊢ es : (tn _> tm)
Loop
C ⊢ [Loop tf es] : (tn _> tm)

i < length(label C) (label C)!i = ts C ⊢ es : (t1s _> t2s)


Br Weakening
C ⊢ [Br i] : (t1s @ ts _> t2s) C ⊢ es : (ts @ t1s _> ts @ t2s)

C ⊢ es : (t1s _> t2s) C ⊢ [e] : (t2s _> t3s)


Composition
C ⊢ es @ [e] : (t1s _> t3s)

Figure 6. A selection of typing rules and definitions as they appear in our Isabelle model.

block block is completely arbitrary. This is because the Br instruction


br 0 br 0
guarantees that all subsequent operations in the same ex-
i32.const 1 i32.const 1
i32.add f32.const 0
ecution context will never be executed. However, it is still
end i32.add possible for this dead code to be ill-typed. Consider the stack
end of Figure 7. The left-hand stack is well-typed, since the type
of Br can “fill in" the missing integer argument. However,
Figure 7. Two WebAssembly stacks illustrating the typing no matter what type is picked when typing Br in the right-
behaviour of Br. Only the left-hand stack is well-typed. hand stack, the mismatching integer and float types of the
subsequent operations cause the stack to be ill-typed. The
implications of this design are relevant to our verified type
2.2 The type system of WebAssembly checker.
A selection of WebAssembly’s typing rules can be found The type system is claimed in the official specification
in Figure 6. WebAssembly has four concrete value types, to be sound with respect to the stack reduction relation,
corresponding to 32- and 64-bit floats and integers. Every in the sense that well-typed programs enjoy progress and
value in WebAssembly has one of these four types. Opcodes preservation properties during execution.
have a type of the form (t* _> t*) , effectively a function Lemma (Preservation). Given a configuration (|s;vs;es|)
from list of values to list of values. These opcode types com- with type t* in i, if (|s;vs;es|) {_i (|s’;vs’;es’|) then
pose as expected, and the type of a stack of instructions is (|s’;vs’;es’|) also has type t* in i.
therefore also (t* _> t*), the composition of its constituent
operations. All typing derivations are with respect to a type Lemma (Progress). If a configuration (|s;vs;es|) has type t*
context which represents the typing information of the in- in i, then either es is a bare Trap representing an exception, or
stance the program is running in. a list of constant values, or there exists (|s’;vs’;es’|) such that
(|s;vs;es|) {_i (|s’;vs’;es’|)
Configurations are typed with respect to one of the in-
stances contained in their store. A configuration containing WebAssembly’s type system is very similar (most likely
a stack of type ([] _> t*) under instance i can be said to unwittingly) to the “stack effect calculus" [Poial 1990], a
have type t* in i. The type of a WebAssembly program is the decades-old type system initially proposed as part of an effort
type of its initial configuration. to formalise the Forth language. This is mostly a historical
Some WebAssembly typing rules are highly non- curiosity, as despite Forth’s similarity to WebAssembly as
deterministic. Figure 6 gives the typing rule for Br. The “in- another stack-based language with structured control flow,
put" type of the Br operation is partially determined by the most existing formal work on Forth is not applicable to We-
label element of the typing context, which is extended while bAssembly due to the decision to model control flow using
typing the inner part of a “breakable" operation (see the a separate control stack [Power and Sinclair 2004] [Knaggs
typing rule for loop). However, the type of the result, t2s, 1993] , whereas in WebAssembly all values, operations and
6
control instructions are held (at least abstractly) in the same There are a small number of situations where the original
stack. However, recent discussions about the typing ramifica- WebAssembly paper and the draft specification document
tions of adding a hypothetical “dup" opcode to WebAssembly differ in their representation of certain specification artefacts.
dovetail neatly with existing theory on more polymorphic We try to primarily follow the paper’s representation, since
variants of the stack effect calculus [Poial 2002]. it is more directly designed as a formal specification. In some
cases, however we must adopt the draft specification’s rep-
resentation in order to model a feature which the paper did
3 The model
not support, or to improve compatibility with the untrusted
We have built a full mechanisation of the core WebAssembly parser/linker that we use to make our verified interpreter
specification as it appears in the working group’s original pa- executable as a standalone program, since its internal state
per [Haas et al. 2017a], extended with features and behaviour is more heavily based on the draft specification.
added to the official draft specification [WebAssembly Com- In particular, the paper formalisation stores functions de-
munity Group 2017d] after its publication. This mechanisa- clared within WebAssembly programs within each instance
tion adheres as strictly as possible to the ideals of “eyeball itself. This is possible because the formalisation gives only
closeness", first explicitly advocated for by JSCert [Bodin a sketch description of the instantiation process. In the full
et al. 2014], a mechanisation of the ES5 JavaScript specifi- draft specification, multiple instances may share the same
cation. Eyeball closeness is a design principle of the formal store, and one may export a function that is imported by
model such that there is a line to line textual correspondance another. Instances cannot directly access each other, and
between the official specification and the mechanisation. In therefore a single copy of the function can be held directly
the ideal case, someone familiar with the official specifica- in the store, with each instance maintaining a reference to
tion should be able to read an eyeball close mechanisation it. Using this arrangement instead of the paper’s (which ef-
as though it is re-stating the specification in an unfamiliar fectively makes a copy of an imported function every time
pseudocode. Compared to JSCert, our model enjoys a signif- a new instance is created) more accurately represents the
icant advantage in preserving eyeball closeness in that all instantiated state in real implementations, and allows our
WebAssembly reduction and typing rules in the specification verified interpreter to interface with the official reference in-
already include a definition in formal notation. This means terpreter’s instantiation mechanism, since we do not model
that our definitions can be eyeball close at the level of speci- it ourselves.
fication logical sentence to mechanisation logical sentence, A perennial concern when defining a mechanised specifi-
not merely specification English sentence to mechanisation cation is accurately handling arithmetic, especially floating
logical sentence. point calculations. We use Isabelle’s locale mechanism to
The core of the mechanisation is our definition of two abstract the implementation of arithmetic and the heap as
inductive relations, which correspond to the WebAssembly parameters. Any proofs completed within the locale give
specification’s reduction and typing rules. These relations results that are implicitly quantified over all possible imple-
are not directly executable, but we define separate executable mentations, so long as they satisfy the locale assumptions,
functions for an interpreter and type checker, and prove them which encode the properties of the heap that we rely on.
correct with respect to their corresponding relation. We also use locales to abstract the behaviour of the host
Our work does not formalise the mapping of concrete op- environment, allowing our proofs to range over all possible
codes to abstract operations, as we consider this to be part of hosts. We slightly restrict the behaviour of host functions
work of the parser, which we do not model. This is consistent compared to the full behaviour allowed by the latest official
with the way the official specification specifies the structure specification. We allow host functions to arbirarily mutate
of the binary format. Because of this, our model already the heap, but not the function table or the list of declared
has full support for loops with non-empty arguments, even global variables. We have found that this behaviour is suffi-
though this feature is not available yet due to the restrictions cient to pass all available WebAssembly conformance tests,
in place on the binary format. and execute all WebAssembly programs encountered “in the
Similarly, as previously mentioned, we do not model the wild" so far.
instantation process of a WebAssembly module. This is a Another advantage of locales is that they force us to be
linking and allocation phase that must be carried out before explicit in the assumptions we make about the behaviour of
a WebAssembly program can be executed. Instead, our mech- untrusted code interfacing with our verified interpreter. For
anisation deals purely with the WebAssembly execution en- example, when carrying out code extraction for integration
vironment in its post-instantiation form, often referred to as with the official reference interpreter, we must explicitly
an instance. Within the official specification, both instantia- axiomatise our assumption that the native OCaml code we
tion and parsing are self-contained sections and therefore interface with has well-behaved host functions.
our decision not to support them had no negative effect on
the rest of our mechanisation.
7
theorem preservation: value to propagate as intended, and the reduction could in-
assumes "⊢_i s;vs;es : ts"
correctly become stuck before Trap reached the top of the
"(|s;vs;es|) {_i (|s’;vs’;es’|) "
stack, violating the progress property.
shows "⊢_i s’;vs’;es’ : ts"
We discovered this issue while attempting to prove the
theorem progress: progress property, and were able to communicate a coun-
assumes "⊢_i s;vs;es : ts" terexample to the specification authors, as well as a suggested
shows "const_list es ∨ solution, which was ultimately adopted into the specifica-
es = [Trap] ∨ tion.
(∃ s’ vs’ es’. (|s;vs;es|) {_i (|s’;vs’;es’|) )"
4.2 Return
Figure 8. The preservation and progress properties, as they
Originally, the Return operation was simply specified as a
appear in our Isabelle proof.
“maximal" break. That is, it would reduce to Br n, where n
was the number of nested labels within the current function
lemma progress_LN1: call. However, we discovered that the typing rule given was
assumes "(Lfilled j lholed [$Br (j+k)] es)" incorrect, with the effect that a Return operation could occur
"S·C ⊢ es : (ts _> ts’)" outside a function call and still be well typed. The infor-
shows "length (label C) > k" mal intention of the specification was that such a program
should be rejected by validation. Determining the correct fix
Figure 9. An auxiliary lemma in the progress property proof. was an extended process, and we assisted a member of the
working group by modelling several possible solutions. The
final solution involved changing the structure of the Label
4 Soundness and Local operations to keep track of the arity of the value
We have produced a fully mechanised proof of both sound- to be returned from their inner context, as well as altering
ness properties (Figure 8) as they are stated in the work- the semantics of Return so that it now breaks directly to the
ing group’s original paper. Prior to our work, no proof of outside of the function call instead of being defined in terms
soundness for the type system, mechanised or otherwise, of Br.
was available. Each property was proven by induction, over A former draft of the semantics where these two issues
either the reduction or the typing relation. are still present can be found on the official GitHub reposi-
To prove each of these properties, a large number of auxil- tory [Haas et al. 2017b].
iary lemmas needed to be established. This was most notable
when dealing with the inductive cases that involved recur- 4.3 Host functions
sive execution contexts mixed with control flow. Figure 9 Since host functions may behave in arbitrary, non-
shows one of these lemmas, which must be proven by induc- deterministic ways that fall outside the space of possible
tion over the definition of the Lfilled predicate. The lemma WebAssembly behaviours, they are required to preserve cer-
is a generalised version of a property that is required to prove tain invariants on the runtime state, so that they do not
the progress property; a Br n instruction is only well-typed dynamically invalidate an assumption that would otherwise
if it is surrounded by at least n+1 breakable labels. always hold throughout “normal" execution. For example, a
In the course of conducting this proof, we identified sev- host function may deallocate portions of memory, or change
eral errors in the official specification which were acknowl- the type of an immutable global variable. We discovered
edged and fixed by members of the working group. In some that the invariants as they were stated in the specification
cases, these errors meant that the type system was originally were too weak, so that a host function could obey them yet
unsound. We detail the most significant examples here. still cause a well-typed program to crash [Rossberg 2017a],
in violation of the progress property. Ultimately, this sec-
4.1 Exception propagation tion of the specification was entirely re-written to fix this
As previously mentioned, the WebAssembly semantics has problem [Rossberg 2017b].
a Trap administrative operation which is used to model an
unrecoverable exception. A Trap value is generated by run- 5 An executable type checker
time errors such as division by 0 or out-of-bounds memory We have defined, separate from our model, an executable
accesses. Once it is generated, all other execution ceases, type checker in Isabelle, and proven it sound and complete
and the Trap value propagates through all function calls and with respect to the inductive typing relation of our mechani-
nested control structures, terminating the program when sation. We did not use Isabelle’s tools to extract executable
it reaches the top of the stack. However, the original draft code from the original typing relation (a process known as
specification we based our model on did not allow the Trap animation), because we desired our type checker to match
8
datatype ct = datatype checker_type = datatype res_crash =
TAny TopType "ct list" CError
| TSome t | Type "t list" | CExhaustion
| Bot
datatype (’a,’b,’c,’d) res =
Figure 10. An extended type syntax, for use with the exe- RCrash res_crash
cutable type checker. | RTrap
| RValue "(((’a,’b,’c,’d) v) list)"
theorem b_e_typing_equiv_b_e_type_checker:
datatype (’a,’b,’c,’d,’e) res_step =
shows "(C ⊢ es : (tn _> tm)) =
RSCrash res_crash
(b_e_type_checker C es (tn _> tm))"
| RSBreak nat "(((’a,’b,’c,’d) v) list)"
| RSReturn "(((’a,’b,’c,’d) v) list)"
Figure 11. Equivalence of our type checker with our induc-
| RSNormal "(((’a,’b,’c,’d,’e) e) list)"
tive typing relation.
Figure 12. Interpreter result types.
the behaviour of industry implementations by running in a
single pass. inspect an unconstrained stack with the Select operation.
As previously mentioned, one quirk of WebAssembly’s Therefore, a stack that does not have an unconstrained base
type system is that it requires the full stack to be typed, even cannot include polymorphic value types, and therefore the
if a control instruction guarantees that a certain portion of Type stack type, representing the type of an exact stack, is a
the stack is dead code. This is accomplished by giving the list of t rather than ct. Finally, Bot represents a stack with
section of stack terminated by the control instruction an no valid type.
arbitrary type, but it is still possible for the remainder of the The type checking algorithm walks the stack from top to
stack to be ill-typed. This has implications for a concrete bottom, operation by operation. Each operation produces
type checking algorithm. WebAssembly’s type system is in- and consumes a certain number of (potentially polymorphic)
tended to be checkable in one pass over the stack. However, type symbols, or makes the entire stack type TopType [], the
this requires a richer representation of the types of interme- entirely unconstrained stack. Bot is produced if the correct
diate sections of the stack than is possible using the normal type cannot be consumed, or if some other condition is not
WebAssembly syntax. Upon scanning to, for example, a br satisfied, such as a Br operation attempting to break out of
instruction, a type checker with no polymorphic symbols more labels than are present.
does not have the information it needs to pick the arbitrary This extended type syntax can be viewed as a constraint
concrete type that will allow the rest of the stack to be well- system with the solutions being types in the form of the
typed. If, instead, the type checker is allowed access to some original syntax. We prove that, for all WebAssembly pro-
symbol representing an unconstrained type, it can progress, grams, the types that satisfy our model’s typing relation are
contraining the type of the stack as it encounters further exactly the solutions to the constraints our type checker
instructions. generates. Finally, we define a top level function which takes
We implement a single-pass type checker which internally a type-annotated WebAssembly program, and runs our type
types the stack using an extended version of the WebAssem- checker, checking that the type annotations satisfy the re-
bly type syntax which includes polymorphic symbols. We sulting constraints. This function therefore returns true if
introduce no more polymorphism than is necessary to fa- and only if the program is well-typed, and can be automati-
cilitate single-pass typing, so as to simplify the proofs. The cally used by Isabelle’s code generation tools as an efficient,
definition of our extended type syntax can be found in Fig- executable version of our model’s typing relation.
ure 10. Our type checker does not perform full type inference,
Polymorphism occurs at two levels. First, an individual since we are allowed to assume during implementation that
value type on the stack can be polymorphic. This is repre- the “initial" stack type, at the start the typing pass, is an exact
sented by the TAny type. Second, the stack itself can be poly- type. However, this could be an interesting future extension.
morphic in its contents, including length. The only way the
stack itself can become polymorphic is by executing an un- 6 An executable interpreter
conditional control flow instruction, which makes the whole We have implemented an executable interpreter as an Isabelle
stack unconstrained for the purposes of typing. TopType rep- function, and proven it sound with respect to the mechanised
resents this unconstrained stack, which may include certain specification. Again, we decided against attempting to di-
constrained types appended to its head, including polymor- rectly animate the reduction relation for several reasons.
phic value types, by subsequent instructions. Currently, the Firstly, the definition of reduction given in the specification
only way to generate a single polymorphic value type is to makes use of inductively defined evaluation contexts. Our
9
lemma run_step_break_imp_lfilled:
assumes "run_step d i (s,vs,es) = (s’, vs’, RSBreak n res)"
shows "s = s’ ∧
vs = vs’ ∧
(∃ n’ lfilled es_c. n’ ≥ n ∧
Lfilled_exact (n’-n) lfilled ((vs_to_es res) @ [$Br n’] @ es_c) es)"

Figure 13. Relating the RSBreak control result to an evaluation context of nested labels.

mechanisation stays faithful to this in order to maximise eye- RSBreak control result to the underlying structure of the eval-
ball closeness. However, this arrangement does not lend itself uated code. In particular, it encodes that an RSBreak n res
to direct animation, since there is no syntax-directed way control result must have originated from a Br n’ operation
of determining which part of a given WebAssembly stack nested (n’-n) labels deep, with exactly the constant values
is the evaluation context and which part takes the place of res directly preceeding it on the stack. Lfilled_exact is a
the “hole". Secondly, the semantics for exception propaga- tweaked definition of Lfilled used exclusively during the
tion contain a significant amount of trivial, confluent non- soundness proof. Unlike Lfilled, Lfilled_exact exposes all
determinism. A direct animation would require handling constant values on the stack at the same level as the “hole",
this; for example, by representing the possible reductions in in this case, res, allowing them to be referred to during the
a choice monad, despite the different choices not affecting proof.
the final result. Finally, our relational definition of reduction At the top level, our interpreter repeatedly calls the one
makes use of a number of highly inefficient list manipula- step evaluation function until either a result or error is
tions, which even a "naive" interpreter would not carry out. reached. We turn “getting stuck" (having no reduction ac-
Instead, we chose to define a separate executable inter- cording to the semantics) into an explicity signalled error.
preter as a function from WebAssembly configuration to Because all functions in Isabelle require a termination proof,
result, and prove it sound with respect to the reduction rela- we augment this interpreter with a standard fuel value which
tion. In doing this, we enjoy the dual advantages of having a decreases each iteration. The WebAssembly specification re-
specification in a form conducive to proofs, and a potentially quires all implementations to gracefully implement a limit
optimising interpreter which avoids the performance pitfalls on the level of nested function calls, so we separately keep
of a direct animation of the reduction relation. Indeed, our track of a depth parameter which decreases every time a
interpreter implements a more efficient representation of function context is entered. A function executed with a re-
constant values on the stack, which reduces the frequency maining depth of 0 results in a simulated stack exhaustion
with which the stack (as a list of operations) needs to be split error.
and concatenated during execution. Our executable interpreter cannot run as a stand-alone
The core of the executable interpreter is a one step evalu- function, since, as previously explained, we do not model
ation function which mirrors the one step reduction relation instantation, or decoding of the binary format. Therefore, to
of the specification. For most operations, the function pro- obtain a complete WebAssembly engine, we use Isabelle’s
ceeds exactly as in the reduction relation. The reduction rules extraction mechanism to extract our interpreter function to
focussing on execution contexts (see the Label_Context rule OCaml, and integrate it with the working group’s reference
of Figure 5) translate naturally into a simple recursive defini- WebAssembly implementation, also written in OCaml. This
tion. The main complications in this strategy are the control requires that we implement an untrusted interface with the
flow instructions Br and Return. For example, the Br instruc- reference implementation’s AST. For convenience, we also
tion is defined as breaking out of all enclosing labels in a make use of the reference interpreter’s internal implementa-
single step. We therefore extend the evaluation function to tion/representation of integers, floating point, and the heap.
return a res_step (Figure 12) , which can either be a stack In principle, these could be replaced with Isabelle defined
after one step of reduction, or a special “control result" which and extracted definitions, but the correctness of these defini-
signals that an outer call of the evaluation function is for a tions is entirely orthogonal to our soundness results, and the
label which is being broken to. reference implementation makes use of Ocaml-native types
Invocations of the evaluation function which result in a that are more efficent.
new stack can be directly proven to be sound with respect
to the reduction relation. In order to prove the behaviour 7 Validation and fuzzing
of the evaluation function sound for control flow instruc- Our executable interpreter, suitably augmented with the ref-
tions which involve one of these control results as a return erence parser and linker, successfully passes all core language
value, certain auxiliary lemmas must be established. Fig- conformance tests available in the WebAssembly reposi-
ure 13 shows one of these lemmas. This lemma relates an tory [WebAssembly Community Group 2017c]. Due to the
10
soundness result we have with respect to our mechanised to investigate a WebAssembly backend for the CakeML com-
specification, these tests also serve to validate our model. piler. Indeed, its maintainers acknowledge this as a possible
In addition to this, we have conducted differential test- direction for the project [CakeML project 2017].
ing of our executable interpreter against several major We- The Java Virtual Machine and bytecode have been ex-
bAssembly engines. This was done both with the purpose of tensively formalised, with a mechanisation existing in Is-
validating our interpeter, and potentially discovering seman- abelle [Klein and Nipkow 2006]. As previously discussed,
tic bugs in commercial WebAssembly engines. Tests were the Java bytecode does not share WebAssembly’ approach to
generated using the CSmith tool [Yang et al. 2011], combined control flow, and therefore the comparisions we can make to
with the official Binaryen toolchain [WebAssembly Commu- their model are limited. An extension to this work [Lochbih-
nity Group 2017a] to convert the generated C tests into We- ler and Bulwahn 2011] uses locales to abstract over memory
bAssembly. This mimics how most WebAssembly programs consistency models, similar to the way we use the same
will be produced “in the wild". No errors were found either feature to abstract over different implementations of the
in our implementation or any commercial engine, although WebAssembly heap.
a crash bug was discovered within the Binaryen toolchain As previously discussed, some formal work has been done
itself, which was reported and fixed by the developers [Watt on the Forth language [Knaggs 1993]. To the best of our
2017]. knowledge, no mechanisation work exists.

9 Future work
8 Related work To reduce our reliance on the official reference interpreter
in making our verified interpreter executable, it would be
Our mechanisation draws heavily from the original formal- valuable to model the instantiation phase of WebAssembly
isation by the WebAssembly working group [Haas et al. program execution. This is an area of the specification un-
2017a]. However, this formalisation is purely handwritten, dergoing active re-writing [Rossberg 2017c], so it would be
contains no support for interaction with the host environ- challenging to keep the model abreast of ongoing changes.
ment, and offers no proof of the two soundness properties it A major incoming feature for WebAssembly is integration
claims the type system enjoys. To the best of our knowledge, with the SharedArrayBuffer proposal [TC39 2017a], which
our work represents the first mechanised formalisation of adds a weak memory semantics to both WebAssembly and
the complete WebAssembly core language, as well as the JavaScript. Correct specification of weak memory models
first full proof, mechanised or otherwise, of the soundness is a major open problem. The models of many languages
of the WebAssembly type system. have been shown to have fundamental deficiencies [Batty
The structure and organisation of our proofs and exe- et al. 2015], including the C++11 memory model, which We-
cutable artefacts owe a great debt to the JSCert project [Bodin bAssembly must be “compatible" with in some sense, if it is
et al. 2014], which mechanised the ES5 JavaScript specifica- intended to be a compilation target. This is an area where
tion. JSCert separated its specification and executable imple- timely input from the formal verification community could
mentation in order to offer a specification which could be have a tangible impact on the health of the langage. In partic-
used to build proofs about language properties without sac- ular, it is important to work out to what extent the memory
rificing eyeball closeness, which its contributors argued was model of the SharedArrayBuffer proposal falls foul of known
necessary to relate proven properties back to the original tex- problems in the field, such as the issue of "thin air" execu-
tual specification. We consider our project to have benefited tions.
significantly from following JSCert’s lead in this arrange- Finally, Ethereum developers have announced eWASM
ment: our work in proving WebAssembly’s type soundness [Ethereum Group 2017], a proposal to use WebAssembly
properties identified several important issues with the official as the bytecode representation of programs running on the
specification which we could not have discovered without Ethereum virtual machine. Our existing model needs almonst
embarking on such a “deep" proof of a language property, no extension to be a faithful model of this new virtual ma-
and might not have been so immediately actionable by the chine, and there is scope for useful verification work, partic-
official specification authors had we not maintained eyeball ularly in verifying translations from the old bytecode rep-
closeness. Furthermore, we can now guarantee, through our resentation, which has also been recently modelled [Hirai
proofs, that the type system is sound in a way that would 2017], to WebAssembly.
not be possible for a “light-weight" specification.
The CakeML project [Kumar et al. 2014] includes formal
models of several intermediate, assembly-like languages.
10 Summary
Due to WebAssembly’s positioning as a web-compatible, We have presented a full mechanisation of the core We-
platform-independant compilation target, it may be fruitful bAssembly language, together with several proofs of sound-
ness, and verified implementations of a type checker and
11
interpreter. In the course of conducting these proofs, we have org/10.1145/2535838.2535841
identified and assisted in fixing several errors in the official Andreas Lochbihler and Lukas Bulwahn. 2011. Animating the Formalised
WebAssembly specification. Semantics of a Java-like Language. In Proceedings of the Second Interna-
tional Conference on Interactive Theorem Proving (ITP’11). Springer-Verlag,
Berlin, Heidelberg, 216–232. http://dl.acm.org/citation.cfm?id=2033939.
Acknowledgments 2033958
Conrad Watt is supported by an EPSRC Doctoral Training Jaanus Poial. 1990. Algebraic Specification of Stack Effects for Forth Pro-
award, and the REMS EPSRC program grant (EP/K008528/1). grams. In Forml Conference Proceedings (Forml 1990). The Forth Interest
Group, San Jose, CA, USA, 282–290.
We thank Peter Sewell and Andreas Rossberg for their advice Jaanus Poial. 2002. Stack effect calculus with typed wildcards, polymorphism
during this work. and inheritance. In Proc. 18-th EuroForth Conference.
James F. Power and David Sinclair. 2004. A Formal Model of Forth Control
References Words in the Pi-Calculus. J. UCS 10, 9 (2004), 1272–1293. https://doi.org/
10.3217/jucs-010-09-1272
Mark Batty, Kayvan Memarian, Kyndylan Nienhuis, Jean Pichon-Pharabod, Andreas Rossberg. 2017a. [spec] Fix and clean up invariants for host
and Peter Sewell. 2015. The Problem of Programming Language Concur- functions. (September 2017). Retrieved October 7, 2017 from https:
rency Semantics. Springer Berlin Heidelberg, Berlin, Heidelberg, 283–307. //github.com/WebAssembly/spec/pull/563
https://doi.org/10.1007/978-3-662-46669-8_12 Andreas Rossberg. 2017b. [spec] Fix and clean up invariants
Martin Bodin, Arthur Chargueraud, Daniele Filaretti, Philippa Gardner, for host functions. (September 2017). Retrieved October
Sergio Maffeis, Daiva Naudziuniene, Alan Schmitt, and Gareth Smith. 7, 2017 from https://github.com/WebAssembly/spec/commit/
2014. A Trusted Mechanised JavaScript Specification. In Proceedings of 772d87705ea4786c0d44d41902097e91cf31f82b
the 41st ACM SIGPLAN-SIGACT Symposium on Principles of Programming Andreas Rossberg. 2017c. [spec] Fix and clean up invariants for host
Languages (POPL ’14). ACM, New York, NY, USA, 87–100. https://doi. functions. (September 2017). Retrieved October 7, 2017 from https:
org/10.1145/2535838.2535876 //github.com/WebAssembly/spec/pull/563
CakeML project. 2017. CakeML Projects. (2017). Retrieved October 7, 2017 TC39. 2017a. Memory Model. (September 2017). Retrieved October 7, 2017
from https://cakeml.org/projects from https://tc39.github.io/ecma262/#sec-memory-model
Ethereum Group. 2017. eWASM. (2017). Retrieved October 7, 2017 from TC39. 2017b. SIMD.js specification v0.9. (April 2017). Retrieved October 7,
https://github.com/ewasm 2017 from http://tc39.github.io/ecmascript_simd/
Google. 2017. Welcome to Native Client. (2017). Retrieved October 7, 2017 Conrad Watt. 2017. Crash in wasm-opt on certain optimisation levels.
from https://developer.chrome.com/native-client (August 2017). Retrieved October 7, 2017 from https://github.com/
Andreas Haas, Andreas Rossberg, Derek L. Schuff, Ben L. Titzer, Michael WebAssembly/binaryen/issues/1149
Holman, Dan Gohman, Luke Wagner, Alon Zakai, and JF Bastien. 2017a. WebAssembly Community Group. 2017a. Binaryen. (October 2017). Re-
Bringing the Web Up to Speed with WebAssembly. In Proceedings of the trieved October 7, 2017 from https://github.com/WebAssembly/binaryen
38th ACM SIGPLAN Conference on Programming Language Design and WebAssembly Community Group. 2017b. Instructions. (September 2017). Re-
Implementation (PLDI 2017). ACM, New York, NY, USA, 185–200. trieved October 7, 2017 from https://webassembly.github.io/spec/binary/
Andreas Haas, Andreas Rossberg, Derek L. Schuff, Ben L. Titzer, Michael instructions.html
Holman, Dan Gohman, Luke Wagner, Alon Zakai, and JF Bastien. 2017b. WebAssembly Community Group. 2017c. WebAssembly. (October 2017).
Bringing the Web Up to Speed with WebAssembly. (March 2017). Re- Retrieved October 7, 2017 from https://github.com/WebAssembly
trieved October 7, 2017 from https://github.com/WebAssembly/spec/ WebAssembly Community Group. 2017d. WebAssembly Specification. (Sep-
blob/bbb26c42b62096baff86089767531c3b1f108a85/papers/pldi2017.pdf tember 2017). Retrieved October 7, 2017 from https://webassembly.
Yoichi Hirai. 2017. Defining the Ethereum Virtual Machine for Interactive github.io/spec/
Theorem Provers. In 1st Workshop on Trusted Smart Contracts. Xuejun Yang, Yang Chen, Eric Eide, and John Regehr. 2011. Finding
Gerwin Klein and Tobias Nipkow. 2006. A Machine-checked Model for a and Understanding Bugs in C Compilers. In Proceedings of the 32Nd
Java-like Language, Virtual Machine, and Compiler. ACM Trans. Program. ACM SIGPLAN Conference on Programming Language Design and Im-
Lang. Syst. 28, 4 (July 2006), 619–695. https://doi.org/10.1145/1146809. plementation (PLDI ’11). ACM, New York, NY, USA, 283–294. https:
1146811 //doi.org/10.1145/1993498.1993532
Peter J Knaggs. 1993. Towards a Formal Forth. (September 1993). Retrieved Alon Zakai and Robert Nyman. 2013. Gap between asm.js and native
October 7, 2017 from http://www.rigwit.co.uk/papers/formal2.pdf performance gets even narrower with float32 optimizations. (December
Ramana Kumar, Magnus O. Myreen, Michael Norrish, and Scott Owens. 2013). Retrieved October 7, 2017 from https://hacks.mozilla.org/2013/12/
2014. CakeML: A Verified Implementation of ML. In Proceedings of the 20/
41st ACM SIGPLAN-SIGACT Symposium on Principles of Programming
Languages (POPL ’14). ACM, New York, NY, USA, 179–191. https://doi.

12

You might also like