a mechanized formalization of the webassembly specification ... › ~mtf › student-resources ›...

15
RIT Computer Science Capstone Report 20191 A Mechanized Formalization of the WebAssembly Specification in Coq Xuan Huang Department of Computer Science Golisano College of Computing and Information Sciences Rochester Institute of Technology Rochester, NY 14586 [email protected] Abstract—We developed a mechanized formalization of W3C WebAssembly Core Specification 1.0 [1] in the Coq [2] proof assistant, and (almost) completed a mechanized proof that this semantics is sound, implying both its type safety and memory safety. Wasm has been designed [3] and standardized [1] with formal semantics. In contrast to prior work [4], our mechanized formalization closely follows the standard, exposed issues and provided bug fixes. Our work serves as a foundation for certified software development in the Coq community. Existing projects can incorporate ours to build certified compilers (CompCert [5], Vellvm [6]) and certified interfacing layers (JSCert [7], CertiKOS [8]). Index Terms—Programming languages; Mechanized seman- tics; Type soundness I. I NTRODUCTION A. Theory of programming languages The formal study of programming languages focuses on de- scribing the semantics of programming languages with math- ematical precision, to help with thoroughly understanding the meaning of computer programs and writing reliable software. Intellectual tools enable us to represent language structures as mathematical objects and language behaviors in terms of math- ematical functions and relations, allowing the reasoning about and the proving of general properties: the dynamic semantics are often expressed as an operational semantics, a method of specifying the behavior of a programming language by writing an abstract interpreter on the abstract syntax; and the static semantics are often expressed as a type system, a method of specifying rules governing the correct use of a language. With these precise definitions, we can establish properties of all programs in a given language. One of the most important properties that we want to investigate and prove is safety, often referred to type soundness, establishing the coherence of the dynamic and static semantics and guaranteeing that well-typed programs are well-behaved and do not get stuck. Traditionally [9][10], formalizations and proofs were writ- ten via pen-and-paper and the correctness could only be man- ually checked. As languages being studied become larger, it is increasingly impossible and error-prone to develop human- generated type safety proofs, as they often require checking thousands of cases. Some languages such as Standard ML, were formally defined [11] with early efforts [12] and later mechanized ones [13] on proving its soundness; however, most other languages such as Haskell are only believed to be sound. To solve these problems, much current research in programming languages is being done with the aid of automated proof assistants such as Coq, Isabelle/HOL, Twelf, Agda, NuPRL, where formalizations are written as code, and the proofs are constructed as rigorous logical arguments and their correctness are mechanically checked by the proof- checker. Formalization and proofs checked in this way are thus known as mechanized and formally-verified. B. WebAssembly WebAssembly is a safe, portable, low-level bytecode lan- guage and stack-based virtual machine designed for the in- creasingly sophisticated domain of Web applications. It offers compact representation, efficient validation and compilation, and low to no-overhead execution. It is the first new language on the Web since JavaScript’s long monopoly. Nowadays, a significant amount of JavaScript running on the Web is actu- ally compiled from other languages. Although state-of-the-art JavaScript engines such as Google’s V8 have been optimized to be very fast, JavaScript is deficient as a compilation target due to its original design as a high-level scripting language and being memory-managed and dynamically-typed. One of the main goals of WebAssembly is to become a more appropriate and universal compilation target for the open Web platform. WebAssembly is the first industrial-strength language or VM that has been designed from the start with a formal semantics, which is accomplished in lockstep and help with making the language semantics drastically simpler [3]. An initial WebAssembly design and specification was published in 2017 as a research paper appearing at PLDI, a premier venue for PL research. This paper provided a full-fledged formal specification of the WebAssembly language in a traditional programming language research manner, including the abstract syntax, typing rules, and operational semantics. The paper also claimed that the WebAssembly type system enjoys the standard soundness property, although no proof is pointed to in the paper. In 2018, Conrad Watt developed a mechanized specification and presented a machine-verified proof of the soundness in Isabelle, closely following the 2017 paper defi- nition, together with a verified executable interpreter and type checker [4]. Rochester Institute of Technology 1 | Page

Upload: others

Post on 26-Jun-2020

9 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: A Mechanized Formalization of the WebAssembly Specification ... › ~mtf › student-resources › ... · a certified interfacing layer between WebAssembly and its embedder can

RIT Computer Science • Capstone Report • 20191

A Mechanized Formalization of the WebAssemblySpecification in Coq

Xuan HuangDepartment of Computer Science

Golisano College of Computing and Information SciencesRochester Institute of Technology

Rochester, NY [email protected]

Abstract—We developed a mechanized formalization of W3CWebAssembly Core Specification 1.0 [1] in the Coq [2] proofassistant, and (almost) completed a mechanized proof that thissemantics is sound, implying both its type safety and memorysafety. Wasm has been designed [3] and standardized [1] withformal semantics. In contrast to prior work [4], our mechanizedformalization closely follows the standard, exposed issues andprovided bug fixes. Our work serves as a foundation for certifiedsoftware development in the Coq community. Existing projectscan incorporate ours to build certified compilers (CompCert [5],Vellvm [6]) and certified interfacing layers (JSCert [7], CertiKOS[8]).

Index Terms—Programming languages; Mechanized seman-tics; Type soundness

I. INTRODUCTION

A. Theory of programming languages

The formal study of programming languages focuses on de-scribing the semantics of programming languages with math-ematical precision, to help with thoroughly understanding themeaning of computer programs and writing reliable software.Intellectual tools enable us to represent language structures asmathematical objects and language behaviors in terms of math-ematical functions and relations, allowing the reasoning aboutand the proving of general properties: the dynamic semanticsare often expressed as an operational semantics, a methodof specifying the behavior of a programming language bywriting an abstract interpreter on the abstract syntax; and thestatic semantics are often expressed as a type system, a methodof specifying rules governing the correct use of a language.With these precise definitions, we can establish properties ofall programs in a given language. One of the most importantproperties that we want to investigate and prove is safety, oftenreferred to type soundness, establishing the coherence of thedynamic and static semantics and guaranteeing that well-typedprograms are well-behaved and do not get stuck.

Traditionally [9][10], formalizations and proofs were writ-ten via pen-and-paper and the correctness could only be man-ually checked. As languages being studied become larger, itis increasingly impossible and error-prone to develop human-generated type safety proofs, as they often require checkingthousands of cases. Some languages such as Standard ML,were formally defined [11] with early efforts [12] and latermechanized ones [13] on proving its soundness; however,

most other languages such as Haskell are only believed tobe sound. To solve these problems, much current researchin programming languages is being done with the aid ofautomated proof assistants such as Coq, Isabelle/HOL, Twelf,Agda, NuPRL, where formalizations are written as code,and the proofs are constructed as rigorous logical argumentsand their correctness are mechanically checked by the proof-checker. Formalization and proofs checked in this way are thusknown as mechanized and formally-verified.

B. WebAssembly

WebAssembly is a safe, portable, low-level bytecode lan-guage and stack-based virtual machine designed for the in-creasingly sophisticated domain of Web applications. It offerscompact representation, efficient validation and compilation,and low to no-overhead execution. It is the first new languageon the Web since JavaScript’s long monopoly. Nowadays, asignificant amount of JavaScript running on the Web is actu-ally compiled from other languages. Although state-of-the-artJavaScript engines such as Google’s V8 have been optimizedto be very fast, JavaScript is deficient as a compilation targetdue to its original design as a high-level scripting language andbeing memory-managed and dynamically-typed. One of themain goals of WebAssembly is to become a more appropriateand universal compilation target for the open Web platform.

WebAssembly is the first industrial-strength language orVM that has been designed from the start with a formalsemantics, which is accomplished in lockstep and help withmaking the language semantics drastically simpler [3]. Aninitial WebAssembly design and specification was published in2017 as a research paper appearing at PLDI, a premier venuefor PL research. This paper provided a full-fledged formalspecification of the WebAssembly language in a traditionalprogramming language research manner, including the abstractsyntax, typing rules, and operational semantics. The paperalso claimed that the WebAssembly type system enjoys thestandard soundness property, although no proof is pointed toin the paper. In 2018, Conrad Watt developed a mechanizedspecification and presented a machine-verified proof of thesoundness in Isabelle, closely following the 2017 paper defi-nition, together with a verified executable interpreter and typechecker [4].

Rochester Institute of Technology 1 | P a g e

Page 2: A Mechanized Formalization of the WebAssembly Specification ... › ~mtf › student-resources › ... · a certified interfacing layer between WebAssembly and its embedder can

RIT Computer Science • Capstone Report • 20191

C. Motivations

The main motivations of our work are to mechanize therecently finalized W3C WebAssembly Core Specification 1.0and to bring a WebAssembly formalization into the Coqcommunity and support the existing projects there.

W3C WebAssembly Specification: WebAssembly has beenstandardized as an open W3C standard [1] and has recently(relative to the writing of this report) reached the final "Rec-ommendation (REC)" phase on December 05, 2019 [14].In addition to pseudo-code-like English prose, the standardspecification also includes a complete set of formal semantics,using traditional textbooks approaches similar to the 2017paper’s. However, it differs from the 2017 paper formalizationin many detailed ways:

1) The step relation is defined with evaluation contexts thatbring non-determinism.

2) Stack frames are made explicit and switched via evalu-ation contexts.

3) Allocations in the store and indirection through ad-dresses are made explicit.

4) Some details are specified to correspond more closelywith the actual byte encoding.

5) More structures are explicitly named and defined, re-flecting more implementation details.

6) The store typing and extension (weakening) are defineddifferently.

We guess that most of the WebAssembly specificationreaders, e.g., engine developers, upstream compiler develop-ers, and application developers would exclusively follow thepublished, standardized W3C specification. Thus our mecha-nization chooses to closely follow the official specification [1]rather than the 2017 paper definition [3]. We believe that doingso increases the verification strength and relevance of ourwork, and would be appreciated by potential certified softwareprojects that might be built on top of our work.

Maintaining a mechanization against a living specificationcould be challenging. We find that it is a perfect time formechanizing since we know that we are targeting a fixedspecification that is guaranteed to be relevant for a longtime. A dream is that our mechanized specification can bepart of the creation of future WebAssembly standards: manynew proposals of WebAssembly have been planned and notyet fully formalized. Our work could help with exposingissues and proving that new proposals do not break soundnesswhile adding expressiveness. In fact, we have already adoptedthe multi-value proposal [15] to be a little bit more future-proof, and our work has found 1 small mismatch [16] inthe core specification and several larger ones (e.g. [17]) inthe multi-value extension of the specification. We believe thatstarting with the most up-to-date specification makes it easierto integrate new proposals that also start with the same basespecification.

The Coq Community: Coq has become one of the mostsuccessful platforms for modeling programming languageswith formally verified assurances and developing large-scale,

in-production certified software systems, notably CompCert[5], Vellvm [6], CertiKOS [8], JSCert [7] and many others suchas those in the DeepSpec program [18]. We also discoveredthat a machine-checkable formal semantics of WebAssemblyin Coq has been requested by the WebAssembly community[19], and there hasn’t been any work being accomplished andpublished yet.

A WebAssembly mechanized formalization will open manyinteresting possibilities. For instance, one can build a certi-fied compiler that translates higher-level programming lan-guages or intermediate languages into WebAsssembly, andformally prove that such translation preserves the semanticsof the original programs. Great candidates are a certified C-to-WebAssembly compiler with CompCert, and a certifiedWebAssembly backend for LLVM with Vellvm. Similarly,a certified interfacing layer between WebAssembly and itsembedder can be proved to be safe and correct with respect tothe defined specifications. WebAssembly JavaScript Interfaces[20] has been standardized, and WASI, or WebAssembly SystemInterface [21] is a recent ongoing effort to push WebAssemblybeyond web browsers to native applications running atopstandard operating systems through interfaces such as POSIX.We can see opportunities to integrate our mechanization withJSCert and CertiKOS here.

D. Summary

The contributions of this paper are:

• A mechanized formalization of the W3C WebAssemblyCore Specification 1.0 in Coq;

• A (almost) completed mechanized soundness proof ofWebAssembly’s type system.

The source code of this project can be obtained here [22].The rest of this paper is structured as follows. In Section

2 we give a brief overview of the project, describing thestructures, results, and challenges in general. From Section 3to 5 we anatomize the WebAssembly language into structure,validation, and execution, where we have organized our mech-anization and paper in the same order as their correspondentsin the official specification. We believe that structuring ourmechanization and paper in this order greatly encouragesthe reader to look at the official specification side-by-sidewith our mechanization and observe our eyeball-closeness.Although some of the terminology used in the standard isdifferent from that used in programming language research,we nonetheless adopt the specification’s terminology for thesame reason of making it easier to align the formalization withthe specification. We will walk through a selected subset ofour Coq mechanization, describe specific challenges we facedin each part, and compare it with related work as appropriate.Section 6 introduces the soundness theorem and discusses thepreservation and progress lemmas in detail. Section 7 discussesrelated work and Section 8 draw some final conclusion anddiscuss future work.

Rochester Institute of Technology 2 | P a g e

Page 3: A Mechanized Formalization of the WebAssembly Specification ... › ~mtf › student-resources › ... · a certified interfacing layer between WebAssembly and its embedder can

RIT Computer Science • Capstone Report • 20191

Fig. 1. Project overview

II. OVERVIEW

A. Methodology

WebAssembly, as most other typed languages, is formalizedas inductive tree structures, i.e. abstract syntax, correspondingto the Structure section of the official specification, with judge-ments and inference rules for operational semantics and statictyping rules, corresponding to the Execution and Validationsections of the official specification, respectively. We faithfullymechanized those mathematical definitions into Coq code withthree design principles: eyeball-closeness, correctness, andgood engineering.

To develop the type soundness proofs, we needed to extendour typing rules to cover runtime structures such as results,stores, configurations, and administrative instructions that arenot present in the source but are necessary for reasoning aboutthe validity (or type) of these structures during the executionof WebAssembly. The official specification includes a subsec-tion in the appendix for Soundness which helpfully providedmost of these typing rules. This subsection also provide thestatements of the preservation lemma, the progress lemma,and the soundness theorem in a mostly formal approachwhich helped us embarking our journey. Finally, we indepen-dently developed machine-checked proofs of preservation andprogress lemmas, by induction on syntax or derivations, andthe soundness theorem, as a corollary.

B. Project Structures and Results

The structure and results are visualized in Figure 1.We started our mechanization as strict correspondents of

these four sections (and their subsections), but soon found thedependency relation is circular. We ended up structuring ourmechanization as the mapping relations visualized in Figure 1,

where the Value.v, Types.v, Int.v, Float.v, Numerics.vare extracted for clearer dependency relations and separation ofconcerns. This structure was heavily influenced by the officialWebAssembly reference interpreter written in OCaml. Coq andOCaml have similar module systems that allow us to mirrorthe abstraction and avoid similar constraints quite smoothly.Another reason is that one of our future plans would requireus to interoperate with the reference interpreter in these partsand having a isomorphic structure would be very beneficialthere.

To give a rough idea of the scale of the WebAssemblylanguage, the PDF version of the official WebAssembly spec-ification is 144 pages long, and the four sections that we areparticularly interested in are 67 pages long in total. N.B. Thespecification contains both English prose and formal notationsin roughly one-to-one ratio so the pure formal subset that wemechanized would be roughly 34 pages. Our mechanizationcurrently are around 5000 lines of Coq code, with roughly2000 of them being the mechanized formalization that corre-sponds to the 34 pages, developed in roughly 2.5 man-weeks.The line counts in Figure 1 are larger because many of themcontain lemmas as well.

The remaining 3000 lines of code are proofs of lemmasand theorems. Our current proof developed in roughly 4 man-weeks does not yet cover the full mechanized definition.However, our proof is able to show that the progress propertyholds for the numeric subset, as well as the type preservationproperty holds for both numeric subset and structured controlflow subset. Importantly, during the development of theseproofs, we spent substantial times investigating and improvingour design principles. We believe we have passed major tech-nical challenges and our proof structures and infrastructures

Rochester Institute of Technology 3 | P a g e

Page 4: A Mechanized Formalization of the WebAssembly Specification ... › ~mtf › student-resources › ... · a certified interfacing layer between WebAssembly and its embedder can

RIT Computer Science • Capstone Report • 20191

Fig. 2. λ→ in textbooks

have been well-established according to our design principles,and are capable of extending to the full language. We estimatethat the line counts of the full proof would double the numbersof current proof.

We can compare the scale of WebAssembly with λ→

(the simply typed λ calculus) that is frequently used in thetextbooks. As we visualized in Figure 2, λ→ takes roughly7 pages of definitions and 8 pages of proofs to establishtype safety in Types and Programming Languages [9]. N.B.As a textbook, the ratio of English prose to formal notationis likely higher than that of the WebAssembly specification.Software Foundation - Programming Language Foundation[23] presents a mechanized definition of λ→ in less than 200lines of Coq code and proves the soundness properties in under300 lines of Coq. In conclusion, WebAssembly is roughly 10times larger than the λ→. As for the informal/formal ratio, ourmechanization demonstrates a comparable conciseness withthe textbooks in the definition part of mechanization. Theproof, however, doesn’t seem like it will grow linearly as thedefinitions.

C. Design Principles and Challenges

Challenges arise for each of the design principles we wantedto pursue.

Eyeball-closeness: Mechanization can be questioned onhow faithful that they can represent the official specifications.JSCert [7] advocated the approach of establishing the textualcorrespondence between the official specification and themechanization for obtaining trust. We heavily adopted thisapproach, especially because the official WebAssembly spec-ification has already invested on maintaining a set of formalsemantics, which would drastically reduce the difficulties ofeyeball assessment.

Our mechanization use the same naming and order as thespecification whenever possible. We heavily leveraged theCoq’s syntax extensions and interpretation scopes [24] to beas close as possible to the formal notations used in officialspecifications. The challenges often come with the presenceof syntax overloading in the official specification that is con-venient for the specification authors, as a "slightly-informal"formal notations. While in Coq, we have to inconvenientlymake those cases explicit and still strive for a good-enougheyeball closeness.

Correctness: Correctness is arguably the most critical prin-ciples that a mechanization should achieve. Here we defined

the correctness as "capturing all the important details pre-cisely". We strive to be as precise as possible and there aretwo significant challenges.

The first is that the official specification, although notatedformally, is still designed as less than a fully formal spec-ification and is more likely to obscure facts and details, ascompared to its original paper alternatives. This has been amajor reason that related work [4] did not choose to followit in a mechanization. Fortunately, the official specificationauthors have been very supportive to our work.

The second is that the official specification contained detailsthat might not be relevant to its meta-theory thus couldbe safely omitted or generalized in the mechanization. Forexample, the underlying representation of integers, floatingpoint numbers and memories are abstracted out as parameters.Another examples are the vectors, indexes, and addresses,which are bounded in the official specification, but generalizedto be unbounded in our mechanization.

We also have future plans to further validate our correctness,as discussed in Section 8.

Qualities of Engineering: Qualities of engineering aresometimes overlooked when discussing mechanized proof be-cause people are usually more interested in the result and (ex-plicitly) not interested in looking into the actual code. We careabout proof engineering because we expect our mechanizationwill grow as the official specification of WebAssembly grows,and we don’t want that growing to be so painful.

We focus on improving of our proof engineering from theaspects of scalability and maintainability: Lemmas that arereusable are extracted into the ProofAux.v module; proofsare decoupled into cases that would not interfere with siblings;duplicate proof routines are optimized as Coq’s Ltac tactics;code and proof are documented, etc. We also divide largemodules so that the build process is more incremental andcache friendly. The challenge is that improving qualities ofengineering takes time; additional time needed to be spent onrefactoring working, but unsatisfactory (from a proof engineer-ing standpoint), code.

III. STRUCTURE

WebAssembly has two concrete representations: a binaryformat and a text format. Both map to the same structure andare described by traditional abstract syntax in the standard.Our mechanization is concise enough to be squeezed into onepage and is presented in Listing 1.

Rochester Institute of Technology 4 | P a g e

Page 5: A Mechanized Formalization of the WebAssembly Specification ... › ~mtf › student-resources › ... · a certified interfacing layer between WebAssembly and its embedder can

RIT Computer Science • Capstone Report • 20191

(* Values.v *)From Wasm Require Export Int. (* I32.t, I64.t *)From Wasm Require Export Float.(* F32.t, F64.t *)Definition val := op I32.t I64.t F32.t F64.t.Parameter byte : Type.Parameter char : Type.Definition name := list char.

(* Types.v *)Inductive valtype := T_i32 | T_i64 | T_f32 | T_f64.Notation resulttype := (list valtype).Inductive functype := FT (_ _: resulttype).Notation "ts1 −→ ts2" := (FT ts1 ts2).

Inductive blocktype :=| BT_typeidx (t: typeidx)| BT_valtype (v: option valtype).

Inductive instr :=| Const (val: val)| Unop (op: unop)| Binop (op: binop)| Testop (op: testop)| Relop (op: relop)| Cvtop (op: cvtop)| Drop| Select| Local_get (i: localidx)| Local_set (i: localidx)| Local_tee (i: localidx)| Global_get (i: globalidx)| Global_set (i: globalidx)| Load (* future work *)| Store (* future work *)| Memory_size| Memory_grow| Nop| Unreachable| Block (bt: blocktype) (b: list instr)| Loop (bt: blocktype) (b: list instr)| If (bt: blocktype) (b1: list instr) (b2: list instr)| Br (l: labelidx)| Br_if (l: labelidx)| Br_table (ls: list labelidx) (l: labelidx)| Return| Call (f: funcidx)| Call_indirect (t: typeidx).

Notation ...idx := nat.Definition expr : Type := list instr.Record func := {F_type : typeidx;F_locals : list valtype;F_body : expr;

}.Record table := { T_type : tabletype; }.Record mem := { ME_type : memtype; }.Record global := {

G_type : globaltype;G_init : expr;

}.Record elem := {

EL_table : tableidx;EL_offset : expr;EL_init : list funcidx;

}.Record data := {

D_data : memidx;D_offset : expr;D_init : list byte;

}.(* similarly for importdesc and import *)Inductive exportdesc :=

| EXD_func (_: funcidx)| EXD_table (_: tableidx)| EXD_mem (_: memidx)| EXD_global (_: globalidx).

Record export := {EX_name: name;EX_desc: exportdesc;

}.Record module := {

M_types : list functype;M_funcs : list func;M_tables : list table;M_mems : list mem;M_globals : list global;M_elem : list elem;M_data : list data;M_start : option start;M_imports : list import;M_exports : list export;

}.

Listing 1. Structure

A. Values

As a low-level language, WebAssembly operates only onprimitive numeric values. However, according to their inter-pretation, the standard defines them into four classes:

• Bytes that are raw and uninterpreted;• Integers with bit width N and whether they are signed

or unsigned;• Floating-point numbers in either 32 or 64 bits, mostly

follow the IEEE754-219 standard;• Names and chars, defined by Unicode.

Since our focus is not the actual encoding of values, weabstracted out their underlying representations as Parameterobjects in Coq. The Int and Float modules establish theinterface of the operations that we expect the concrete imple-

mentations of integers and floating-point numbers to provideand export I32.t, I64.t, F32.t, and F64.t as abstract typesand grouped as val.

Inductive op (i32 i64 f32 f64 : Type) :=| i32 (_: i32) | i64 (_: i64)| f32 (_: f32) | f64 (_: f64).

Listing 2. Structure - Numeric grouping

This grouping is inspired from the official WebAssemblyreference interpreter written in OCaml. Because most numericoperations are bounded-polymorphic over these four values,such groupings can be extremely convenient for code reusesand concise mechanizations.

Rochester Institute of Technology 5 | P a g e

Page 6: A Mechanized Formalization of the WebAssembly Specification ... › ~mtf › student-resources › ... · a certified interfacing layer between WebAssembly and its embedder can

RIT Computer Science • Capstone Report • 20191

Inductive sx := U | S.Module IntOp.Inductive unop := Clz | Ctz | Popcnt.Inductive binop := Add | Sub | Mul | Div (_: sx) | Rem (_: sx) | And | Or | Xor | Shl | Shr (_: sx) | Rotl | Rotr.Inductive testop:= Eqz.Inductive relop := Eq | Ne | Lt (_: sx) | Gt (_: sx) | Le (_: sx) | Ge (_: sx).Inductive cvtop := Wrap_i64 | Extend_i32 (_: sx) | Trunc_f32 (_: sx) | Trunc_f64 (_: sx) | Reinterpret.End IntOp.Module IOp32 := IntOp.Definition unop := op IOp32.unop IOp64.unop FOp32.unop FOp64.unop.

Listing 3. Structure - Numeric instructions

B. Types

There are only four basic machine types, or value types inWebAssembly: integers and floating-point numbers, in either32 or 64 bit width. Similar to other stack-based virtualmachines, executing instructions in the WebAssembly VMconsumes a sequence of such values from the stack as argu-ments and leaves a sequence of such values on the stack as theresult. Sequence of values are classified as a result type, anda function type is defined as a pair of result types (argumentand result). We take advantages of Coq’s syntax extensionmechanisms to make the notation for function types close tothe standard. In addition to the stack, other structures such aslinear memory, tables, and globals in WebAssembly are typedas well.

C. Instructions

Instructions are the core of WebAssembly programs. Recallthat WebAssembly is conceptually a stack machine whereinstructions manipulate values on an implicit operand stack,consuming (popping) argument values and producing (push-ing) result values. The specification defines 171 individualopcodes [25], each corresponding to a dedicated instructions.We highlight two challenges we faced in this section.

Numeric Instructions: This category corresponds to 126out of 171 opcodes, but they can be divided into only 6subcategories: Constants, Unary, Binary, Tests, Comparisons,and Conversions. The standard uses conventions to occa-sionally write them in the grouped manner for convenience.Our mechanization mimics such conventions via module-leveland term-level parameterization and grouping, again, inspiredby the official WebAssembly reference interpreter, for bothcode reuses and eyeball-closeness; see Listing 3. N.B. Thesegroupings are not fully regular over different value typesand subcategories; the official specification hacked these byparameterizing bit width and signed/unsigned at the meta-language level to define only the valid combinations. Wewould have to explicitly exclude those cases through extradefinitions.

Control Instructions: During the mechanization of thiscategory we discovered a difference between the currentspecification and original paper definition where the currentspecification constrains control instructions to consume zeroor more values from the stack and to produce at most onevalue. To be a somewhat future-proof and to also have the

convenience of greater generality, we adopted the multi-valueproposal [15], which introduces block types that are expressedeither by directly unfolding an optional value type (whichwe represent as Coq option) into a function type or takingan indirection through a type index. Another caveat is thatthe specification includes an explicit end opcode among thecontrol instructions, which we ignored for now and went withthe original paper definition. This will likely to change in thefuture.

D. Modules

WebAssembly programs are organized into modules. Amodule collects definitions for types, functions, tables, memo-ries and globals. In addition, it can declare imports and exportsand provide initialization logic in the form of data and elementsegments or a start function. Our mechanization differs withthe official specification in some minor ways:• The official specification defines modules with forward

references to sub-structures, but in our mechanizationmust organize things so that definitions always precedeuses.

• Indices are defined as bounded u32 (unsigned 32-bitintegers) in the specification, but we generalize them toCoq’s unbounded nat type.

• Similarly, vectors are defined as sequences with at most232−1 elements in the specification, but generalize themto Coq’s unbounded list type.

IV. VALIDATION

WebAssembly programs must be validated before beingexecuted. This is essentially a type system. The standarddefines the validity of a module and its contents via natu-ral deduction style typing rules over the structure (abstractsyntax). We mechanize those inference rules using textbooktechniques [23] by translating them into Coq’s inductivelydefined propositions, where parameterized inductive typesrepresent properties or relations and the constructors representrules asserting membership.

The standard conveniently overloads the "`" notation andleverage hyperlinks to identify the rules being instantiated. OurCoq mechanization leverage shorthand notations except thatthey have to be syntactically differentiated with an acronymsuffix. We believed that have established good-enough eyeballcloseness for our purpose. A selective subset of definitions

Rochester Institute of Technology 6 | P a g e

Page 7: A Mechanized Formalization of the WebAssembly Specification ... › ~mtf › student-resources › ... · a certified interfacing layer between WebAssembly and its embedder can

RIT Computer Science • Capstone Report • 20191

Record context := {C_types : list functype;C_funcs : list functype;C_tables : list tabletype;C_mems : list memtype;C_globals : list globaltype;C_locals : list valtype;C_labels : list resulttype;C_return : option resulttype;

}.

Reserved Notation "'`l' l '∈ ' k" (at level 70).Inductive valid_limit : limits → I32.t → Prop :=

| VL__none: ∀ n k,n ≤ k →`l {| L_min := n; L_max := None |} ∈ k

| VL__some: ∀ n m k,n ≤ k ∧ m ≤ k ∧ n ≤ m →`l {| L_min := n; L_max := (Some m) |} ∈ k

Reserved Notation "C '`bt' bt '∈ ' ft" (at level 70).Inductive valid_tabletype : tabletype → Prop :=

| VTT: ∀ limits elemtype,`l limits ∈ I32.max (* 232 *) →`tt (limits, elemtype) ok

Reserved Notation "C '`bt' bt '∈ ' ft" (at level 70).Inductive valid_blocktype : context → blocktype →

functype → Prop :=

| VBT_typeidx: ∀ C i ft,C.(C_types).[i] = Some ft →C `bt BT_typeidx i ∈ ft

| VBT_valtype__some: ∀ C t,C `bt BT_valtype (Some t) ∈ [] −→ [t]

| VBT_valtype__none: ∀ C,C `bt BT_valtype None ∈ [] −→ []

Reserved Notation "C '`' instr '∈ ' ft" (at level 70).Reserved Notation "C '`∗ ' instrs '∈ ' ft" (at level 70)

.Inductive valid_instr : context → instr → functype

→ Prop :=

| VI_binop : ∀ C t op,t = type_of op →C ` Binop op ∈ [t; t] −→ [t]

| VI_local_get : ∀ C x t,C.(C_locals).[x] = Some t →C ` Local_get x ∈ [] −→ [t]

| VI_if : ∀ C bt ts1 ts2 instrs1 instrs2,C `bt bt ∈ ts1 −→ ts2 →C,labels ts2 `∗ instrs1 ∈ ts1 −→ ts2 →C,labels ts2 `∗ instrs2 ∈ ts1 −→ ts2 →C ` If bt instrs1 instrs2 ∈ (ts1 ++ [T_i32]) −→

ts2

| VI_call : ∀ C x ts1 ts2,C.(C_funcs).[x] = Some (ts1 −→ ts2) →C ` Call x ∈ ts1 −→ ts2

| VI_select : ∀ C t,C ` Select ∈ [t; t; T_i32] −→ [t]

| VI_br : ∀ C l ts ts1 ts2,C.(C_labels).[l] = Some ts →C ` Br l ∈ (ts1 ++ ts) −→ ts2

with valid_instrs : context → list instr → functype→ Prop :=

| VIS_empty : ∀ C ts,C `∗ [] ∈ ts −→ ts

| VIS_snoc : ∀ C instrs instrNts0 ts1 ts ts3,C `∗ instrs ∈ ts1 −→ (ts0 ++ ts) (* ts2 *) →C ` instrN∈ ts −→ ts3 →C `∗ instrs ++ [instrN] ∈ ts1 −→ (ts0 ++ ts3)

Listing 4. Validation - A selection of definitions and typing rules

and typing rules are presented in Listings 4 and 6. TheReserved Notation we introduced are included in the codesamples below to introduce the notations for readers, but weomit the where clause that connect them with definitions forconciseness.

A. Contexts

A necessary component for type checking is a typing con-text, defined in the Conventions subsection of the Validationsection of the standard. Coq’s Record feature provides opti-mized notation for accessing fields, but that is not sufficient tous. The official specification defined conventions for accessingand updating list items and record fields. We did our best toestablish good-enough eyeball-closeness for all of these cases,as demonstrated in Listing 5.

Notation idx := nth_error.Notation "l '.[' x ]" := (idx l x)

Notation "C ',labels' x" := (cons_labels C x)Notation "C ',locals' x" := (cons_locals C x)Notation "C 'with_return' = x" := (replace_return C x)

Example _ := C,labels [T_f32],labels [T_i32].Example _ : C.(C_locals).[2]) = None.

Listing 5. Validation - Notations for context

B. Types

Type declarations require little validation. There was restric-tion on function types where the arity of the returned typecan not be larger than 1, but this is lifted by the multi-valueproposal we adopted. So the only interesting checks are inthe occurrence of limits and block types that we discussed

Rochester Institute of Technology 7 | P a g e

Page 8: A Mechanized Formalization of the WebAssembly Specification ... › ~mtf › student-resources › ... · a certified interfacing layer between WebAssembly and its embedder can

RIT Computer Science • Capstone Report • 20191

Reserved Notation "C '`f' f ∈ ft" (at level 70).Inductive valid_func : context → func → functype →

Prop :=

| VF : ∀ C x ts expr ts1 ts2,C.(C_types).[x] = Some (ts1 −→ ts2) →C,locals* (ts1 ++ ts),labels [ts2]

with_return = Some ts2 `e expr ∈ ts2 →C `f {|

F_type := x;F_locals := ts;F_body := expr |} ∈ ts1 −→ ts2

Reserved Notation "C '`f*' fs ∈ fts" (at level 70).Inductive valid_funcs : context → list func → list

functype → Prop :=

| VFS: ∀ C fs fts,∀2 (fun func ft ⇒ C `f func ∈ ft) fs fts →C `f* fs ∈ fts

Reserved Notation "'`' M ∈ ty" (at level 70).Inductive valid_module: module → functype → Prop :=

| VM : ∀ its ets fts tts functypes funcs tables,let C := {|

C_types := functypes;C_funcs := fts;C_tables := tts;C_locals := [];C_labels := [];C_return := None; |} in

`ft* functypes ok →C `f* funcs ∈ fts →C `t* tables ∈ tts →length C.(C_tables) ≤ 1 →` {|

M_types := functypes;M_funcs := funcs;M_tables := tables;

|} ∈ its −→ ets

Listing 6. Validation - A selection of typing rules (continued)

in Section 3. Limits are validated by ensuring the requestedamount is between the lower bound and the optional upperbounds. We give an example of instantiating this rule tovalidate table types in Listing 4; validating memory types issimilar.

C. InstructionsInstructions are given function types that describe how they

manipulate the operand stack, and we can validate (type check)programs that consist of sequences of instructions. We selectsome of them to present in Listing 4. Those instructions areeasier due to being monomorphic:• Binary operations consume two values and produce one;

all values must have the same type, which is specified bythe operator.

• Getting a local variable requires it to be defined in thecontext.

• Conditionals take an i32 value (interpreted as a boolean)and require the two branches to have the same block type.

• Function calls are typed according to the correspondingfunction defined in the context.

The more interesting ones are those that are polymorphicand there are two degrees of them:• value-polymorphic: the value types of one or several

individual operands is unconstrained. This is the case forall parametric instructions, including drop and select.

• stack-polymorphic: all or most of the function type isunconstrained. This is the case for all control instructionsthat performs a unconditional control transfer, e.g. br,br_table, unreachable, and return.

The rules for validating a sequence of instructions aredefined (via mutual recursion) with the rules for validatinga single instruction.

D. ModulesModules need to be validated as well, by validating all of the

components they contain. Most of these are a straightforward

translation of the standard, so we only include here the typingrule for functions. We explicitly introduced rules for typing asequence of components with same kind, e.g. the valid_funcswas introduced to more closely match the convenient notationused by the standard. The module typing rule is huge with19 premises. We show here in Listing 6 only a specializedrule for typing a module comprised of only types, funcs andtables.

V. EXECUTION

Execution is the most complicated part of the officialspecification. It has exposed most of the challenges duringthe mechanization phase of our work.

The execution behavior of WebAssembly is defined interms of an abstract machine that steps between differentprogram states, which includes a stack that records all theinstructions and operand values and that we represented as aCoq list and an abstract store that consists of all instancesof functions, tables, memories, and globals that have beenallocated and that we represented as a Coq record. Those in-stances in the store are referenced through abstract addresses.Although a concrete implementation would likely to assignvirtual memory addresses to those instances dynamically, thespecification abstracted out these implementation details bydefining addresses as simply indices of the respective storecomponents, which we represented as unbounded nat.

The WebAssembly source program are represented as mod-ules which need to be first instantiated before running. Theresult of instantiation, termed module instances, collects theinstances of exports and addresses for other entities, corre-sponding to their respective declarations from the originalmodule, in the same order as the static indices of module.

In conclusion, a module and its respective module instanceare connected through static indices, while a module instanceand its respective store are connected through indirection withaddresses. We have presented our mechanization of store and

Rochester Institute of Technology 8 | P a g e

Page 9: A Mechanized Formalization of the WebAssembly Specification ... › ~mtf › student-resources › ... · a certified interfacing layer between WebAssembly and its embedder can

RIT Computer Science • Capstone Report • 20191

Record store := {S_funcs : list funcinst;S_tables : list tableinst;S_mems : list meminst;S_globals : list globalinst;

}.Record moduleinst := {MI_types : list functype;MI_funcaddrs : list funcaddr;MI_tableaddrs : list tableaddr;MI_memaddrs : list memaddr;MI_globaladdrs : list globaladdr;MI_exports : list exportinst;

}.

Inductive result := R_vals (_: list val) | R_trap.Inductive admin_instr :=| Plain (_: instr)| Trap| Invoke (closure: funcaddr)| Init_elem (_: tableaddr) (_: I32.t) (_: list funcidx)| Init_data (_: memaddr) (_: I32.t) (_: list byte)| Label (n: nat) (cont body: list admin_instr)| Frame (n: nat) (_: frame) (body: list admin_instr).

Notation "↑ instrs" := (map Plain instrs)Notation "� vals" := (map Plain (map Const vals))

Record frame := {A_locals: list val;A_module: moduleinst;

}.

Inductive hostfunc := .Record funcinst__wasm := {

FI_type__wasm : functype; (* spec [type] *)FI_module : moduleinst;FI_code : func;

}.Record funcinst__host := {

FI_type__host : functype; (* spec [type] *)FI_hostcode : hostfunc;

}.Inductive funcinst :=| FI_wasm (_: funcinst__wasm)| FI_host (_: funcinst__host).Coercion FI_wasm : funcinst__wasm >-> funcinst.Coercion FI_host : funcinst__host >-> funcinst.

Definition FI_type (f: funcinst) : functype :=match f with| FI_wasm f ⇒ f.(FI_type__wasm)| FI_host f ⇒ f.(FI_type__host)end.

Notation " f '.(FI_type)' " := (FI_type f).

Listing 7. Execution - A selection of definitions

module instances in Listing 7. N.B. The official specificationincludes the instantiation and allocation process but they arenot necessary for the proof of type soundness. So they aresafely omitted.

A. Runtime Structures

We selectively discuss other runtime structures that haveraised interesting challenges.

Values: The specification reuses the same notation forvalues as for the const instructions. Such coincidence isconvenient for the official specification but raises challengesfor us — how should we model this? We explored two options:

1) A dependent pair of an instruction and an evidence thatthis instruction is a const instruction.

2) A dedicated definition for values, which could howeverbe lifted into instruction as appropriate.

Both should work but we proceeded with the second option– the val definition we have presented in Section 3; the constinstructions are simply defined as a thin wrapper of val.The benefits are that it works with other components of ourmechanization coherently and it’s simpler. We tried to bridgegap of eyeball-closeness via Coq’s coercion mechanisms but itwas more limited than we expected and was not able to satisfyus in most cases [26].

Results: Results could either be a sequence of values or atrap. This is one of the places that required us to be able todistinguish values from other instructions statically and ourval definition has been capable for this purpose.

Administrative Instructions: In order to express the reduc-tions of traps, function calls, and control flows, the syntax

of instructions is extended in the specification. The twomost interesting ones are the Label and Frame administrativeinstructions that model labels and frames "on the stack".

The specification syntactically extends the original set ofinstructions with the administrative instructions and implicittransforms the meaning of the instr syntactic class to be theextended instruction set from that point onward. Although thisarrangement looks convenient and we could do the same inCoq as well, it would not able to exploit the fact that these aretwo distinct sets and that there is a clear separation in their usesites in the mechanization. Our mechanization thus choosesto keep instr closed and scoped in the use of structure andvalidation, and introduces another new admin_instr type witha constructor Plain that can lift plain instruction (instr) as aadmin_instr to accomplish the set inclusion. The challengethat arises is how to keep a good-enough eyeball closeness.Since Coq’s coercion mechanisms could not satisfy our usecases [26], we introduced dedicated short prefix notation tovisually mediate these problems.

Function Instances: Function instances have also exposedspecial challenges on our mechanization. The specificationconveniently overload the funcinst syntactic class whichis actually a sum of WebAssembly-native function instancesand host function instances. Further complicating things, theuse of the type field is overloaded as well. Our solution ispresented in the Listing 7, where we carefully leverage both acoercion and a notation to create an illusion that the FI_typeis overloaded across the two instances. An alternative solutionwould be using a dependent record but we found this simplesolution is sufficient for such small, one-off use case.

Rochester Institute of Technology 9 | P a g e

Page 10: A Mechanized Formalization of the WebAssembly Specification ... › ~mtf › student-resources › ... · a certified interfacing layer between WebAssembly and its embedder can

RIT Computer Science • Capstone Report • 20191

Inductive block_context : nat → Type :=| B_nil : ∀ (_: list val) (* [_] *) (_: list admin_instr),

block_context 0| B_cons : ∀ {k: nat} (_: list val) (n: nat) (_: list admin_instr) (B: block_context k) (_: list admin_instr),

block_context (k+1).Inductive eval_context :=| E_hole| E_seq (_: list val) (E: eval_context) (_: list admin_instr)| E_label (n: nat) (_: list admin_instr) (E: eval_context).

Fixpoint plugB{k: nat} (B: block_context k) (hole: list admin_instr) : list admin_instr :=match B with| B_nil vals instrs ⇒ �vals ++ hole ++ instrs| B_cons vals n cont B' instrs ⇒ �vals ++ [Label n cont (plugB B' hole)] ++ instrsend.

Fixpoint plugE(E: eval_context) (hole: list admin_instr) : list admin_instr :=match E with| E_hole ⇒ hole| E_seq vals E instrs ⇒ �vals ++ (plugE E hole) ++ instrs| E_label n cont E ⇒ [Label n cont (plugE E hole)]end.

Listing 8. Execution - Evaluation and block contexts

Definition thread : Type := frame * list admin_instr.Definition config : Type := store * thread.

Notation S_F_instrs :=(store * frame * list admin_instr)%type.

Notation "$" := (fun (cfg: config) ⇒match cfg with| (store, (F, instrs)) ⇒ (store, F, instrs)end).

Reserved Notation "instrs1 '↪→S ' instrs2".Inductive step_simple : list admin_instr → list

admin_instr → Prop :=

| SS_binop__some : ∀ op val1 val2 val,eval_binop op val1 val2 = Ok (Some val) → ↑[Const val1; Const val2; Binop op] ↪→S ↑[Const val]

| SS_br : ∀ n ainstrs l (Bl: block_context l) vals,length vals = n →[Label n ainstrs (plugB Bl (�vals ++ ↑[Br l]))]↪→S �vals ++ ainstrs

Reserved Notation "SFI1 '↪→ ' SFI2".Inductive step: S_F_instrs → S_F_instrs → Prop :=

| SC_simple : ∀ S F ainstrs ainstrs',ainstrs ↪→S ainstrs' →(S,F, ainstrs) ↪→ (S,F, ainstrs')

| SC_call : ∀ S F x a,F.(A_module).(MI_funcaddrs).[x] = Some a →(S,F, ↑[Call x]) ↪→ (S,F, [Invoke a])

| SC_loop : ∀ S F m n ts1 ts2 bt instrs vals,m = length ts1 →n = length ts2 →length vals = m →expand F bt = Some (ts1 −→ ts2) →(S,F, �vals ++ ↑[Loop bt instrs]) ↪→ (S,F,

[Label m ↑[Loop bt instrs] (�vals ++ ↑instrs)])

| SC_E : ∀ E S S' F F' ainstrs ainstrs',(S,F,ainstrs) ↪→ (S',F',ainstrs') →(S,F,plugE E ainstrs) ↪→ (S',F',plugE E ainstrs')

Listing 9. Execution - A selection of operational semantics

Evaluation/Block Contexts: The specification heavily usestwo contexts: Evaluation contexts and Block contexts. Mech-anizing them required not just Inductive definitions but alsoFixpoint for plugging those contexts. We haven’t introduceda complicated notation but have instead simply used short-handed names for those plugging functions. The structure ofBlock contexts by itself might be the single most interestingone from a type-theory perspective — it’s indexed by howmany labels surrounding the hole and is dependently-typed.Fortunately, Coq is also a dependently-typed programminglanguage and we can define such structure in the most precisemanner. Our mechanization is given in Listing 8.

Configurations: The specification defines a configuration asa product of store and thread and defines a thread as another

product of a frame and an instruction sequence. However,the actual stepping relation is defined on a unfolded formof configuration. In Coq, we have to perform such unfoldingexplicitly, so we introduced a special $ notation to unfold ourconfig type as a 3-tuple, captured as S_F_instrs. The reasonof having an explicit definition of a thread is both for theeyeball-closeness, and as a preparation to welcome the futurethreads proposal of WebAssembly [27].

B. Instructions

The execution of WebAssembly is performed by executingeach individual instructions. The specification convenientlyomits S (store) and/or F (frame) when they are not changedby the instruction. We discovered the operational semantics of

Rochester Institute of Technology 10 | P a g e

Page 11: A Mechanized Formalization of the WebAssembly Specification ... › ~mtf › student-resources › ... · a certified interfacing layer between WebAssembly and its embedder can

RIT Computer Science • Capstone Report • 20191

instructions can be roughly grouped as the simple ones, thatdo not change the store and frame at all, and the full ones, thateither change store or frame. We showcase a selective subsetof both cases in our mechanization in Listing 9.

VI. SOUNDNESS

The soundness property of WebAssembly implies its typesafety and memory safety. Such properties are usually arequirement for any toy language in academic programminglanguage research, but it is nontrivial for larger and industry-originated programming languages such as WebAssembly tohave such property. Both the original paper and the officialspecification have stated these theorems (without proof); wediscuss the development of our mechanized soundness proofin this section.

A. Extended Typing

The typing rules defined in the Validation section only coverthe source portion of the WebAssembly language. With theintroduction of runtime structures such as stores, instance, andadministrative instructions in the Execution section, we needto add typing rules to describe them in order to reason aboutthe full language. Another group of relations introduced areextensions, written as �, which capture the properties thatentries in stores and instances in stores must not be mis-modified or removed during the lifetime of the program.

The Soundness subsection in the official specification help-fully described all those necessary pieces that we coulddirectly mechanize. Most of those rules are quite verbose andrequire us to be very careful to correctly capture all the details,but they did not introduce any significant new challenges.

B. Theorem Statements

The official specification includes a set of theorem state-ments for preservation, progress, and soundness in the endof the Soundness subsection. Those theorems are written inEnglish with formal notation appearing within the parenthesis.Both the preservation and progress statements are fairly stan-dard, so our mechanization is literally the same with only oneexception. The progress theorems in the specification stateswhat are terminal threads and configurations in English prose,while we have explicitly defined a relation result_threadthat unpacks a thread and requires that its instruction sequencecomponent is a result, so that we can define progress in Coqboth concisely and with eyeball-closeness, without losing anydegree of formalism, as presented in Listing 10.

The soundness theorem in the specification, however, isdefined in an equivalent, but slightly unfolded or interpretedway. Fortunately, it’s well known that soundness is a corollaryof preservation and progress lemma so we shall simply focuson showing these two properties in our mechanized proofs.

C. Theorem Proofs

There have been several challenges that were specific to theprooving of the theorems.

Generality: We started our proofs by directly proving themechanized theorems that correspond directly to the specifi-cation theorems, we were able to show that both preservationand progress hold for the numeric subset of the WebAssemblylanguage without too many problems. However, we got stackafter enriching the active subset of our mechanization toinclude control instructions. The major problem that we hadwas that the theorem statements are too specific, resulting inan induction hypothesis that was too weak to be useful. Ourlater investigations determined that the specification theoremsare actually specialized to the typing rules for configurations,caring only about the cases of top-level frame, where thereshould be no return values and instructions of current threadare started in an empty stack. Such statements are too spe-cific to yield an induction hypothesis that covers all of theintermediate program states during the execution.

As a result, we fully-generalized the theorem statements tostrengthen the induction hypothesis and use it as the centralproof, making the top-level frame case as a corollary. Wegive an example of the generalized preservation in Listing 10.Using these techniques, we are able to prove the structuredcontrol flow subset enjoys the preservation property as well.We estimated this approach would eliminate many issues oncefor all.

Non-determinism and Polymorphism: Many components ofthe WebAssembly languages are highly non-deterministic andpolymorphic and make the proof trickier. We briefly discussthree sources of them:

1) Evaluation contexts are recursively defined and theirdecompositions are extremely flexible. There are alwaysinfinite numbers of ways to decompose a instructionsequence. There is usually only one possible choice ofdecomposition for each specific reduction rule, but thespecific choice often requires manual effort to find. Tomake things worse, proving cases such as SC_E (Listing9) that operate on an arbitrary evaluation context can besurprisingly challenging.

2) The validity of instruction sequences in the originalpaper definition is defined by three rules: one for ε(empty sequence), one for composition, and one forweakening. The weakening rule is not syntax directedand make use of an arbitrary (unconstrained) sequence oftypes. The official specification merged this weakeningrule into the previous two rules, which not only doesnot make this non-determinism better, but also makesthe rules harder to use and obscures the truth. We endedup deriving the weakening rule from the merged rules.

3) Stack unwinding and stack-polymorphism are used forexecution and validation of structured control flow.Consider an unconditional branch. During execution, asthe SS_br rule presented in Listing 9, an unconditionalbranch will (temporarily) pop a number of values fromthe operand stack, then discard values and instructions(presented as a block context) as it unwinds the stack tothe target label, and then push the previously poppedvalues together with the target label’s continuation.

Rochester Institute of Technology 11 | P a g e

Page 12: A Mechanized Formalization of the WebAssembly Specification ... › ~mtf › student-resources › ... · a certified interfacing layer between WebAssembly and its embedder can

RIT Computer Science • Capstone Report • 20191

Notation "! res" := (result_to_ainstr res) (at level 9).Reserved Notation " '`R' T '∈ ' rt" (at level 70).Inductive result_thread :thread → resulttype → Prop :=| RT : ∀ res rt F,`r res ∈ rt →`R (F, !res) ∈ rt

Theorem preservation: ∀ S T S' T' rt,`c (S, T) ∈ rt →$(S, T) ↪→ $(S', T') →`c (S', T') ∈ rt ∧ `S S � S'.

Proof. ... Qed.

Theorem progress : ∀ S T rt,`c (S, T) ∈ rt →`R T ∈ rt ∨∃ S' T', $(S, T) ↪→ $(S', T').

Proof. ... Qed.

Theorem preservation :∀ S F S' F' C ainstrs ainstrs' ts1 ts2,`S S ok →S `A F ∈ C →(S,C) `a* ainstrs ∈ ts1 −→ ts2 →(S, F, ainstrs) ↪→ (S', F', ainstrs') →

(* --------------------------------------------*)`S S � S' ∧`S S' ok ∧S' `A F' ∈ C ∧(S',C) `a* ainstrs' ∈ ts1 −→ ts2.

Proof. ... Qed.

Corollary preservation__toplevel : ∀ S T S' T' rt,`c (S, T) ∈ rt →$(S, T) ↪→ $(S', T') →`c (S', T') ∈ rt ∧ `S S � S'.

Proof. ... Qed.

Listing 10. Soundness

During validation, as the VI_br rule presented in Listing4, an unconditional branch is stack-polymorphic, dueto the values and instructions that will be discardedduring stack unwinding. Such parameters need to bechose carefully from the proof context to make sure therules are invoked as appropriate.

Infrastructures: Some structures that are frequently usedin the specification have required us to develop a substantialamount of lemmas and tactics for them. List "snoc" is themost representative example of that. Both the typing rulesand operational semantics of WebAssembly are defined ina surprising "snoc" (the opposite of "cons") order. This isextremely anti-ergonomic as we are still using Coq’s listtype and most of the standard libraries are written for "cons"(standard) order. We had to develop our own rich set of lemmasand tactics for "snoc" order. Other examples include a Forall2predicate used to establish correspondence between two (equallengthed) lists; length-related reasoning on lists that is usedwhenever a static index is relevant; equality and distributiveproperties over lifting and injection, etc. There are yet othersthat are more specialized to the WebAssembly proof.

VII. RELATED WORK

A. Mechanized Programming Languages and Coq

Pen-and-paper specifications and proofs written in math-ematical languages (also known as formal languages) areconsidered formal but their reliability has been questionednowadays. Mechanization (that is, formal, machine-checkedverification techniques), have elevated the standard of beingformal in programming languages study to a whole new level— "formal proofs are code." More and more current researchof or related to programming languages has adopted this newstandard and applied it in a vast variety of projects. Thenumber of them has developed beyond we can reasonablycover, so we only highlight those that are most closely relatedto our motivations.

In the CompCert project [28], Leroy [5] built a formally-verified optimizing compiler for a significant subset of C(later extending to almost all of the ISO C99 standard),pioneering the approach of using Coq proof assistant bothfor programming the software and for proving its correctness.To accomplish this job, each phase of the compiler had tobe mechanized, including their C subset Clight [29] all theway to PowerPC assembly. Zhao et al. introduced Vellvm(verified LLVM) [6], which provides a mechanized formalsemantics of the LLVM IR (intermediate representation), typesystem and properties for reasoning about programs expressedin LLVM IR and transformations that operate on it. Gu etal. developed CertiKOS [8], a certified concurrent OS kernel,where each kernel module is verified and composed back viacertified abstraction layers [30]. Bodin et al. developed JSCert[7], a mechanized formalization of the current ECMAScript 5standard in Coq, where they advocate the eyeball-closeness ofthe textual correspondence between the official specificationand the mechanization as one of the main methodologiesfor obtaining trust in a mechanized formalization; this workdirectly influenced our design principle.

We also shall mention that Coq is not the only toolfor mechanizing and verifying programming languages. Forinstance, CakeML [31], a verified implementation of ML isa recent notable project from the Isabelle community. Thecentral, common ideas of all these projects are the benefitsof mechanized metatheory [32], [33] and deep specification[18]. Our project is an instance of following such trends andhelp to make these practices mainstream.

B. Mechanized WebAssemblyAs we have discussed in Section 1, there have been three

substantial efforts on formalizing WebAssembly: a preliminaryspecification [3] emphasizing formal semantics and aimed atthe programming languages research community, a mecha-nized specification and machine-verified proof of soundnessdeveloped by Conrad Watt [4], and the W3C WebAssemblyCore Specification 1.0 [1] aimed at a wide audience. Here, we

Rochester Institute of Technology 12 | P a g e

Page 13: A Mechanized Formalization of the WebAssembly Specification ... › ~mtf › student-resources › ... · a certified interfacing layer between WebAssembly and its embedder can

RIT Computer Science • Capstone Report • 20191

discuss the differences between Conrad Watt’s mechanizationand our mechanization in detail.

On Proof Assistants: The first significant difference is inthe choice of proof assistant. Watt used Isabelle/HOL and weused Coq; both are among the most mature proof assistantsavailable. In contrast with many relatively new proof assistantsthat have only been used in academia, they have both beenused for many successful large-scale and production-qualityformal verification projects that are relevant to both academiaand industry. We assume that both proof assistants are correctand provide strong verification strength with no significantdifference.

There are some technical differences in their underlyinglogics and development experiences. Isabelle is based onhigher-order (classical) logic and Coq is based on the calculusof (co)inductive constructions, a type theory which can serveas both dependently-typed programming language and as aconstructive logic (a.k.a., intuitionistic logic) and does notinclude the law of the excluded middle as an axiom. Wefound one structure in the WebAssembly specification thatis dependently-typed — the block context that defined aslabels indexed by depth — where Coq admits a slightly moreconvenient definition. Both logical systems are sufficientlyexpressive for our mechanization purpose without any prob-lems. Isabelle and its precursor LCF are often classified asautomated in which the main proof method is resolution andunification, while the main proof method in Coq is constructiveproof. However, Coq includes automatic theorem provingtactics as an extension to bridge this gap.

On Following the Specification: The second difference isin the choice of specification that the mechanization mostlyfollows. Both Watt and we observe that the original We-bAssembly paper differs from the W3C specification in theirrepresentation of certain specification artifacts; Watt was ob-serving this on the 2017 draft version of the specification andwe are observing this on the version 1.0 that was recentlyfinalized in December 2019. In the future, we expect there willbe even greater divergence from the original WebAssemblypaper and the W3C WebAssembly specification.

As Watt mentioned in his paper, he tried to primarilyfollow the paper’s representations except for a few cases,since it was designed as a formal specification. We, in con-trast, choose to follow the W3C WebAssembly specification,for the reasons of being more real-world and being ableto potentially reach a wider audience. This decision doesmake our work harder in many significant ways. Essentially,more verbose and structured definitions and more explicit anddetailed arrangements were required for the specification to besufficiently concrete to be a useful guide for implementationsand, simultaneously, to be sufficiently abstract so as to notconstrain a implementation too much; this enlarged the scaleof the definitions and obscured facts during the proofs of manytheorems, and contributed to the relative unfriendliness of theW3C WebAssembly specification for mechanization.

On Interoperability: The third difference is about the in-teroperability of the mechanization. Unsurprisingly, this is

closely related to the proof assistant being using. Proof assis-tants often resemble and/or include a programming language.In fact, type-theory-based proof assistants such as Coq, Agda,and Lean are often seen as a dependently-typed programminglanguage whose type system happens to be expressive enoughto be capable of expressing logical statements (and, therefore,whose well-typed terms are proofs of logical statements).When discussing interoperability, programming languages areoften considered to be a soft boundary. Although not always,there are quite a lot of cases where multiple programminglanguages can communicate as part of the same system eitherthrough translations, or through a common runtime system, orthrough foreign function interfaces. At a minimum, softwarewritten in different programming languages can communicatethrough either internet protocols (e.g. HTTP) or through anoperating system (e.g. inter-process communications or files).

Proof assistants, or proof-capable programming languages,however, are much weaker from the perspective of interop-erability. To our knowledge, there have been no such foreignfunction interfaces yet developed that can communicate acrossproof assistants and still preserve the strength of verification.(There do exist approaches such as translation validation withverified validators [5] and proof-carrying code that allow therebuilding of trust in some or most degree either by the recon-struction of proofs or via a certificate.) As a result, both Watt’sand our mechanizations are effectively scoped within theirrespective proof assistant’s community. Our mechanizationcould not be used by notable Isabelle projects such as CakeMLor seL4, and neither could the the Isabelle mechanization beused by Coq projects.

VIII. CONCLUSIONS AND FUTURE WORK

This paper has described how we developed a trusted,mechanized formalization of the W3C WebAssembly CoreSpecification 1.0 in Coq. We have mechanized the formalsemantics included in the specification including the structures(abstract syntax), validation (type system), and execution (op-erational semantics). Our mechanization aims to establish aeyeball-closeness with the official specification. We have alsomechanized all extended typing rules for runtime structuresrequired for our mechanized soundness proof. Our proof isable to show that the progress property and preservationproperty holds for a substantial subset of WebAssembly withrespect to our mechanization. We believed we have passedmajor technical challenges and our proof structures and in-frastructures are capable of extending to the full language.

It remains to be seen what impact could our work will makein the larger WebAssembly community. But we are optimisticabout the relevance of and opportunities for our mechaniza-tion. It is unprecedented that four major Web browser vendors[3] can collaborate to bringing a new, low-level language andvirtual machine that enables high performance applicationson the Web without compromising the safety of the users.We have also seen WebAssembly being attractive to domainsbeyond just the Web [21]. The uses of and interests in We-bAssembly has been growing fast and we expect this trend will

Rochester Institute of Technology 13 | P a g e

Page 14: A Mechanized Formalization of the WebAssembly Specification ... › ~mtf › student-resources › ... · a certified interfacing layer between WebAssembly and its embedder can

RIT Computer Science • Capstone Report • 20191

continue. As with other Web technologies, WebAssembly isstandardized by W3C working groups. The version 1.0 of threeW3C standards of WebAssembly have been recently finalized[14] and are still evolving. What is also unprecedented isthe inclusion of a complete set of formal semantics in aW3C standard. Substantial efforts have been made to developand maintain this formal semantics and the WebAssemblycommunity group is further investing in this approach in all ofthe new proposals [27] including multi-value, reference types,tail call, threads, SIMD, etc.; supporting formal verificationtechniques and certified software developments are one themain goals of having these formal semantics.

We have many future plans. The most direct and obviousone is to complete the soundness proof. Then, we would beinterested in enriching our mechanization to include activeproposals [27], either by following the order of their statusin standardization process, or by selecting those that are mostinteresting in terms of having impact on type soundness,e.g. reference types. Third, we would like to develop areference interpreter and type checker, ones that are provedto be correct with respect to our mechanized specification,and that extracted from Coq to OCaml. This approach hasbeen pioneered by the JSRef reference interpreter presentedin the JSCert project [7] and it has also been adopted inConrad Watt’s Isabelle mechanization, which cleverly reuseparts from the official WebAssembly reference interpreterwritten in OCaml [4]. Our mechanization has been developedwith this possibility in mind and such executable artifacts canincrease the practically of the project and allow the use ofofficial testing suites to increase trust in our mechanization.Finally, we are, of course, interested in interoperating with allthe existing projects within the Coq community to developcertified software, as discussed in Section 1.

ACKNOWLEDGMENT

This work was supervised by Prof. Matthew Fluet. We thankAndreas Rossberg for his support during this work.

REFERENCES

[1] (2019) WebAssembly Core Specification. [Online]. Available:https://www.w3.org/TR/wasm-core-1

[2] (2019) The Coq Proof Assistant. [Online]. Available: https://coq.inria.fr[3] A. Haas, A. Rossberg, D. L. Schuff, B. L. Titzer, M. Holman,

D. Gohman, L. Wagner, A. Zakai, and J. Bastien, “Bringingthe Web Up to Speed with WebAssembly,” in Proceedingsof the 38th ACM SIGPLAN Conference on ProgrammingLanguage Design and Implementation, ser. PLDI 2017. NewYork, NY, USA: ACM, 2017, pp. 185–200. [Online]. Available:http://doi.acm.org/10.1145/3062341.3062363

[4] C. Watt, “Mechanising and Verifying the WebAssembly Specification,”in Proceedings of the 7th ACM SIGPLAN International Conferenceon Certified Programs and Proofs, ser. CPP 2018. NewYork, NY, USA: ACM, 2018, pp. 53–65. [Online]. Available:http://doi.acm.org/10.1145/3167082

[5] X. Leroy, “Formal certification of a compiler back-end, or: programminga compiler with a proof assistant,” in 33rd ACM symposium onPrinciples of Programming Languages. ACM Press, 2006, pp. 42–54.[Online]. Available: http://xavierleroy.org/publi/compiler-certif.pdf

[6] J. Zhao, S. Nagarakatte, M. M. Martin, and S. Zdancewic,“Formalizing the LLVM Intermediate Representation for VerifiedProgram Transformations,” in Proceedings of the 39th AnnualACM SIGPLAN-SIGACT Symposium on Principles of ProgrammingLanguages, ser. POPL ’12. New York, NY, USA: ACM, 2012, pp. 427–440. [Online]. Available: http://doi.acm.org/10.1145/2103656.2103709

[7] M. Bodin, A. Chargueraud, D. Filaretti, P. Gardner, S. Maffeis,D. Naudziuniene, A. Schmitt, and G. Smith, “A Trusted MechanisedJavaScript Specification,” in Proceedings of the 41st ACM SIGPLAN-SIGACT Symposium on Principles of Programming Languages, ser.POPL ’14. New York, NY, USA: ACM, 2014, pp. 87–100. [Online].Available: http://doi.acm.org/10.1145/2535838.2535876

[8] R. Gu, Z. Shao, H. Chen, X. Wu, J. Kim, V. Sjöberg, and D. Costanzo,“CertiKOS: An Extensible Architecture for Building CertifiedConcurrent OS Kernels,” in Proceedings of the 12th USENIX Conferenceon Operating Systems Design and Implementation, ser. OSDI’16.Berkeley, CA, USA: USENIX Association, 2016, pp. 653–669.[Online]. Available: http://dl.acm.org/citation.cfm?id=3026877.3026928

[9] B. C. Pierce, Types and Programming Languages. MIT Press, 2002.[10] P. R. Harper, Practical Foundations for Programming Languages. New

York, NY, USA: Cambridge University Press, 2012.[11] R. Milner, M. Tofte, and D. Macqueen, The Definition of Standard ML.

Cambridge, MA, USA: MIT Press, 1997.[12] M. Vaninwegen, “Towards type preservation in core SML,” 01 1997.[13] D. K. Lee, K. Crary, and R. Harper, “Towards a Mechanized Metatheory

of Standard ML,” in Proceedings of the 34th Annual ACM SIGPLAN-SIGACT Symposium on Principles of Programming Languages, ser.POPL ’07. New York, NY, USA: ACM, 2007, pp. 173–184. [Online].Available: http://doi.acm.org/10.1145/1190216.1190245

[14] (2019) W3C Recommends WebAssembly to push the limitsfor speed, efficiency and responsiveness. [Online]. Available:https://www.w3.org/blog/news/archives/8123

[15] (2019) Multi-value Proposal for WebAssembly. [Online]. Available:https://github.com/WebAssembly/multi-value

[16] (2019) [spec] Fix valid tableinst and meminst premises. [Online].Available: https://github.com/WebAssembly/spec/pull/1093

[17] (2019) [spec] Control instr should carry vals into block. [Online].Available: https://github.com/WebAssembly/multi-value/pull/36

[18] (2019) The Science of Deep Specfication. [Online]. Available:https://deepspec.org/main

[19] (2019) Machine-Checkable Formal Semantics. [Online]. Available:https://github.com/WebAssembly/design/issues/1198

[20] (2019) WebAssembly JavaScript Interface. [Online]. Available:https://www.w3.org/TR/wasm-js-api-1/

[21] (2019) WebAssembly System Interface. [Online]. Available:https://github.com/WebAssembly/WASI

[22] (2019) WasmCert. [Online]. Available:https://github.com/Huxpro/WasmCert

[23] B. C. Pierce, A. A. de Amorim, C. Casinghino, M. Gaboardi,M. Greenberg, C. Hritcu, V. Sjöberg, A. Tolmach, and B. Yorgey,Programming Language Foundations, ser. Software Foundations series,volume 2. Electronic textbook, May 2018, version 5.5. [Online].Available: http://www.cis.upenn.edu/ bcpierce/sf

[24] (2019) Syntax extensions and interpretation scopes. [Online]. Available:https://coq.inria.fr/doc/user-extensions/syntax-extensions.html

[25] (2017) WebAssembly Index of Instructions. [Online]. Available:http://webassembly.github.io/spec/core/appendix/index-instructions.html

[26] (2019) Coercion not working with datatype. [Online]. Available:https://github.com/coq/coq/issues/10898

[27] (2019) WebAssembly proposals. [Online]. Available:https://github.com/WebAssembly/proposals

[28] (2019) CompCert. [Online]. Available: http://compcert.inria.fr/[29] S. Blazy and X. Leroy, “Mechanized Semantics for the Clight

Subset of the C Language,” Journal of Automated Reasoning,vol. 43, no. 3, p. 263–288, Jul 2009. [Online]. Available:http://dx.doi.org/10.1007/s10817-009-9148-3

[30] R. Gu, J. Koenig, T. Ramananandro, Z. Shao, X. N. Wu, S.-C. Weng,H. Zhang, and Y. Guo, “Deep Specifications and Certified AbstractionLayers,” in Proceedings of the 42Nd Annual ACM SIGPLAN-SIGACTSymposium on Principles of Programming Languages, ser. POPL ’15.New York, NY, USA: ACM, 2015, pp. 595–608. [Online]. Available:http://doi.acm.org/10.1145/2676726.2676975

[31] R. Kumar, M. O. Myreen, M. Norrish, and S. Owens, “CakeML:A Verified Implementation of ML,” in Proceedings of the 41st

Rochester Institute of Technology 14 | P a g e

Page 15: A Mechanized Formalization of the WebAssembly Specification ... › ~mtf › student-resources › ... · a certified interfacing layer between WebAssembly and its embedder can

RIT Computer Science • Capstone Report • 20191

ACM SIGPLAN-SIGACT Symposium on Principles of ProgrammingLanguages, ser. POPL ’14. New York, NY, USA: ACM, 2014, pp. 179–191. [Online]. Available: http://doi.acm.org/10.1145/2535838.2535841

[32] B. E. Aydemir, A. Bohannon, M. Fairbairn, J. N. Foster, B. C.Pierce, P. Sewell, D. Vytiniotis, G. Washburn, S. Weirich, andS. Zdancewic, “Mechanized Metatheory for the Masses: The PoplMarkChallenge,” in Proceedings of the 18th International Conference onTheorem Proving in Higher Order Logics, ser. TPHOLs’05. Berlin,Heidelberg: Springer-Verlag, 2005, pp. 50–65. [Online]. Available:http://dx.doi.org/10.1007/11541868_4

[33] R. Harper, “Mechanizing the Meta-theory of Programming Languages,”in Proceedings of the Tenth ACM SIGPLAN InternationalConference on Functional Programming, ser. ICFP ’05. NewYork, NY, USA: ACM, 2005, pp. 240–240. [Online]. Available:http://doi.acm.org/10.1145/1086365.1086396

Rochester Institute of Technology 15 | P a g e