Mechanising and Verifying The WebAssembly Specification 'At The Top Level'
Mechanising and Verifying The WebAssembly Specification 'At The Top Level'
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
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"
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)]|)
(|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’|)
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)
Figure 6. A selection of typing rules and definitions as they appear in our Isabelle model.
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