Understanding and Verifying JavaScript Programs Philippa Gardner - - PowerPoint PPT Presentation

understanding and verifying javascript programs
SMART_READER_LITE
LIVE PREVIEW

Understanding and Verifying JavaScript Programs Philippa Gardner - - PowerPoint PPT Presentation

Understanding and Verifying JavaScript Programs Philippa Gardner Imperial College London LFCS 30th Anniversary 1/31 JavaScript at Imperial Philippa Gardner Jos e Fragoso Santos Petar Maksimovi c Daiva Naud zi unien e Azalea


slide-1
SLIDE 1

1/31

Understanding and Verifying JavaScript Programs

Philippa Gardner

Imperial College London

LFCS 30th Anniversary

slide-2
SLIDE 2

2/31

JavaScript at Imperial

Philippa Gardner Jos´ e Fragoso Santos Petar Maksimovi´ c Daiva Naudˇ zi¯ unien˙ e Azalea Raad Thomas Wood

slide-3
SLIDE 3

3/31

Mechanised Language Specification

Standard ML: formal definition Milner, Harper, MacQueen, Tofte, 1990 and 1997; mechanised definition Lee, Crary, Harper, 2006. C: many partial definitions, some mechanised e.g. by Norrish 1998 , Leroy 2009; complete mechanised definition Ellison, Rosu, 2012; lots of recent work on C11, e.g. Batty’s thesis, 2014. Fragments of Java: many partial (large) definitions, first studied by Drossopoulou, Eisenbach, 1997; mechanised definition, Syme, 1998. Javascript: complete formal definition of the ECMAScript 3 standard (ES3), Maffeis, Mitchell, Tally, 2008; mechanised definition of ES5, us, 2014; Park, Stefanescu, Rosu, 2015.

slide-4
SLIDE 4

4/31

JavaScript at Imperial

DOM Specification

  • P. Gardner, G. Smith, M. Wheelhouse, U. Zarfaty.

Local Hoare Reasoning about the DOM, PODS 2008.

slide-5
SLIDE 5

4/31

JavaScript at Imperial

DOM Specification JSLogic: a program logic for JavaScript

  • P. Gardner, S. Maffeis, G. Smith.

Towards a Program Logic for JavaScript, POPL 2012.

slide-6
SLIDE 6

4/31

JavaScript at Imperial

DOM Specification JSLogic: a program logic for JavaScript JSCert: a mechanised specification of ES5 in Coq

  • M. Bodin, A. Chargu´

eraud, D. Filaretti, P. Gardner,

  • S. Maffeis, D. Naudˇ

zi¯ unien˙ e, A. Schmitt, G. Smith. A Trusted Mechanised JavaScript Specification, POPL 2014.

JSCert JavaScript JSRef Test262

  • Inria Collaborators
  • A. Schmitt
  • A. Chargu´

eraud

  • M. Bodin
slide-7
SLIDE 7

4/31

JavaScript at Imperial

DOM Specification JSLogic: a program logic for JavaScript JSCert: a mechanised specification of ES5 in Coq

JSIL: an intermediate language for JavaScript JSVerify: a verification tool for JavaScript

slide-8
SLIDE 8

5/31

JavaScript and Verification

JavaScript

slide-9
SLIDE 9

6/31

JavaScript and Verification

ECMAScript 5 English Standard

Language Libraries

How is it organised?

Chapters 1-7: Overview, notation, parsing Chapters 8-14: Language constructs Chapter 15: Library functions

slide-10
SLIDE 10

7/31

JavaScript and Verification

ES5 Strict

Language Libraries

How is it organised?

Same as before; strict-only features throughout chapters 8-15

How is it different?

Better behavioural properties: lexicographic scoping, mandatory variable declarations, explicit error throwing...

slide-11
SLIDE 11

8/31

JavaScript and Verification

Core ES5 Strict Non-core Libraries What is Core ES5 Strict?

All of the language constructs Core library functions Non-core library functions definable using the core language

Why the core language?

Important for verification

slide-12
SLIDE 12

9/31

Verifying Core ES5 Strict

Core ES5 Strict

  • JSIL: simple intermediate goto language, good for

verification, memory model similar to JavaScript

  • Semantics-directed compilation from Core ES5 Strict to JSIL
  • Core library functions implemented in JSIL
  • JSVerify: Smallfoot-like verification tool for JSIL

(in future for JavaScript)

  • Core library functions specified and verified using JSVerify
slide-13
SLIDE 13

10/31

JavaScript vs. JSIL Verification

slide-14
SLIDE 14

11/31

Incorporating Non-core Libraries

Non-core Libraries Axiomatic specification to verify client programs

Does not follow the standard, which is operational

Justification of specifications

Informal appeal to the English standard Reference implementation in JSIL or Core ES5 Strict, following the standard, verified with JSVerify, tested against Test262 Verification of industrial-strength library implementations

slide-15
SLIDE 15

12/31

Introducing JSIL

Core ES5 Strict JSCert

JSIL

Non-core libraries Semantics-directed compilation

slide-16
SLIDE 16

12/31

Introducing JSIL

Core ES5 Strict JSCert

JSIL

Non-core libraries Semantics-directed compilation

To be implemented

Attributes, for-in, getters/setters, the arguments object Some core library functions

slide-17
SLIDE 17

13/31

The Syntax of JSIL

Expressions: e ::= v | x | ⊖ e | e ⊕ e | typeof (e) v | e.oe | e.ve | base (e) | field (e) Commands: c ::= skip | x := e | x := new () | x := [e, e] | [e, e] := e | delete (e) | x := hasField (e, e) | x := protoField (e, e) | x := protoObj (e, e) | goto i | goto [e] i, j | x := e(e) with j

slide-18
SLIDE 18

13/31

The Syntax of JSIL

Expressions: e ::= v | x | ⊖ e | e ⊕ e | typeof (e) v | e.oe | e.ve | base (e) | field (e) Commands: c ::= skip | x := e | x := new () | x := [e, e] | [e, e] := e | delete (e) | x := hasField (e, e) | x := protoField (e, e) | x := protoObj (e, e) | goto i | goto [e] i, j | x := e(e) with j Extensible objects, dynamic fields

slide-19
SLIDE 19

13/31

The Syntax of JSIL

Expressions: e ::= v | x | ⊖ e | e ⊕ e | typeof (e) v | e.oe | e.ve | base (e) | field (e) Commands: c ::= skip | x := e | x := new () | x := [e, e] | [e, e] := e | delete (e) | x := hasField (e, e) | x := protoField(e, e) | x := protoObj(e, e) | goto i | goto [e] i, j | x := e(e) with j Prototype chains

slide-20
SLIDE 20

13/31

The Syntax of JSIL

Expressions: e ::= v | x | ⊖ e | e ⊕ e | typeof (e) v | e.oe | e.ve | base (e) | field (e) Commands: c ::= skip | x := e | x := new () | x := [e, e] | [e, e] := e | delete (e) | x := hasField (e, e) | x := protoField (e, e) | x := protoObj (e, e) | goto i | goto [e] i, j | x := e(e) with j Dynamic function choice

slide-21
SLIDE 21

13/31

The Syntax of JSIL

Expressions: e ::= v | x | ⊖ e | e ⊕ e | typeof (e) v | e.oe | e.ve | base (e) | field (e) Commands: c ::= skip | x := e | x := new () | x := [e, e] | [e, e] := e | delete (e) | x := hasField (e, e) | x := protoField (e, e) | x := protoObj (e, e) | goto i | goto [e] i, j | x := e(e) with j Procedures: proc ::= proc m(x){c}

slide-22
SLIDE 22

14/31

Compiling ES5 Strict to JSIL

JavaScript Code

Object.prototype.foo = 1; var bar = 2; function f() { this.baz = this.bar + foo; } f.prototype.bar = 3

Three ways of calling f:

  • Function call: f()
  • Method call: this.f()
  • Constructor call: new f()
slide-23
SLIDE 23

15/31

Compiling Functions

  • Each function translated to a top-level procedure.
  • Global code translated to a special procedure main.
  • No nesting of procedures.
  • Scope and the this object as first two parameters

JavaScript Code JSIL Code function f() { ... } proc f(xsc, xthis){...} Global code proc main(){...}

slide-24
SLIDE 24

16/31

Compiling ES5 Strict to JSIL

JavaScript Code

Object.prototype.foo = 1; var bar = 2; function f() { this.baz = this.bar + foo; } f.prototype.bar = 3

Heap

slide-25
SLIDE 25

17/31

Compiling ES5 Strict to JSIL

JavaScript Code

Object.prototype.foo = 1; var bar = 2; function f() { this.baz = this.bar + foo; } f.prototype.bar = 3

JSIL Code

[lop, “foo”] := 1

Heap

slide-26
SLIDE 26

18/31

Compiling ES5 Strict to JSIL

JavaScript Code

Object.prototype.foo = 1; var bar = 2; function f() { this.baz = this.bar + foo; } f.prototype.bar = 3

JSIL Code

[lg, “bar”] := 2

Heap

slide-27
SLIDE 27

19/31

Compiling ES5 Strict to JSIL

JavaScript Code

Object.prototype.foo = 1; var bar = 2; function f() { this.baz = this.bar + foo; } f.prototype.bar = 3

JSIL Code

xfp := new() [xfp, @proto] := lop xfo := new() [xfo, @code] := “f” [xfo, @scope] := [lg] [xfo, @proto] := ... [xfo, ”prototype”] := xfp [lg, “f”] := xfo

Heap

slide-28
SLIDE 28

20/31

Compiling ES5 Strict to JSIL

JavaScript Code

Object.prototype.foo = 1; var bar = 2; function f() { this.baz = this.bar + foo; } f.prototype.bar = 3

JSIL Code

[xfp, “bar”] := 3

Heap

slide-29
SLIDE 29

21/31

Constructor call: new f()

JavaScript Code

Object.prototype.foo = 1; var bar = 2; function f() { this.baz = this.bar + foo; } f.prototype.bar = 3

new f() ←

− constructor call

JSIL Code

xn := new() xfo := [lg, “f”] xfp := [xfo, “prototype”] [xn, @proto] := xfp xscope := [xfo, @scope] xthis := xn xf := [xfo, @code] xret := xf (xscope, xthis)

Heap

slide-30
SLIDE 30

22/31

Constructor call: new f()

In this case, the this is bound to the newly created object.

this.baz = this.bar + foo

slide-31
SLIDE 31

22/31

Constructor call: new f()

In this case, the this is bound to the newly created object.

this.baz = this.bar + foo ln.obaz

Step 1

slide-32
SLIDE 32

22/31

Constructor call: new f()

In this case, the this is bound to the newly created object.

this.baz = this.bar + foo ln.obaz

Step 1

ln.obar

Step 2

slide-33
SLIDE 33

22/31

Constructor call: new f()

In this case, the this is bound to the newly created object.

this.baz = this.bar + foo ln.obaz

Step 1

ln.obar

Step 2

getValue(ln.obar)

Step 3

slide-34
SLIDE 34

22/31

Constructor call: new f()

In this case, the this is bound to the newly created object.

this.baz = this.bar + foo ln.obaz

Step 1

ln.obar

Step 2

getValue(ln.obar)

Step 3

3

Step 4

slide-35
SLIDE 35

22/31

Constructor call: new f()

In this case, the this is bound to the newly created object.

this.baz = this.bar + foo ln.obaz

Step 1

ln.obar

Step 2

getValue(ln.obar)

Step 3

3

Step 4

lg.vfoo

Step 5

slide-36
SLIDE 36

22/31

Constructor call: new f()

In this case, the this is bound to the newly created object.

this.baz = this.bar + foo ln.obaz

Step 1

ln.obar

Step 2

getValue(ln.obar)

Step 3

3

Step 4

lg.vfoo

Step 5

getValue(lg.vfoo)

Step 6

slide-37
SLIDE 37

22/31

Constructor call: new f()

In this case, the this is bound to the newly created object.

this.baz = this.bar + foo ln.obaz

Step 1

ln.obar

Step 2

getValue(ln.obar)

Step 3

3

Step 4

lg.vfoo

Step 5

getValue(lg.vfoo)

Step 6

1

Step 7

slide-38
SLIDE 38

22/31

Constructor call: new f()

In this case, the this is bound to the newly created object.

this.baz = this.bar + foo ln.obaz

Step 1

ln.obar

Step 2

getValue(ln.obar)

Step 3

3

Step 4

lg.vfoo

Step 5

getValue(lg.vfoo)

Step 6

1

Step 7

4

Step 8 Step 8

slide-39
SLIDE 39

22/31

Constructor call: new f()

In this case, the this is bound to the newly created object.

this.baz = this.bar + foo ln.obaz

Step 1

ln.obar

Step 2

getValue(ln.obar)

Step 3

3

Step 4

lg.vfoo

Step 5

getValue(lg.vfoo)

Step 6

1

Step 7

4

Step 8 Step 8

slide-40
SLIDE 40

23/31

Function call: f()

For function calls in strict mode, this is bound to undefined.

this.baz = this.bar + foo undefined.obaz

Step 1

undefined.obar

Step 2

getValue(undefined.obar)

Step 3

ERROR

Step 4

slide-41
SLIDE 41

24/31

Method call: this.f()

In this case, this is bound to the global object.

this.baz = this.bar + foo lg.obaz

Step 1

lg.obar

Step 2

getValue(lg.obar)

Step 3

2

Step 4

lg.vfoo

Step 5

getValue(lg.vfoo)

Step 6

1

Step 7

3

Step 8 Step 8

slide-42
SLIDE 42

25/31

Trust: Proof and Testing

Core ES5 Strict JSCert

JSIL

Non-core libraries

  • Similar heaps.

Semantics-directed compilation. Pen-and-paper correctness proof. Extensive testing using the Test262 conformance test suite.

slide-43
SLIDE 43

26/31

Testing Methodology and Results

ES6 Test262 14998 tests Considerably better test classification than ES5 Test262.

slide-44
SLIDE 44

26/31

Testing Methodology and Results

ES6 Test262 14998 tests Considerably better test classification than ES5 Test262. ES5 Strict 10958 Tests Tests for ES6 features, Annex B, non-strict mode features

slide-45
SLIDE 45

26/31

Testing Methodology and Results

ES6 Test262 14998 tests Considerably better test classification than ES5 Test262. ES5 Strict 10958 Tests Tests for ES6 features, Annex B, non-strict mode features Core ES5 Strict 4599 Tests Tests for non-core features

slide-46
SLIDE 46

26/31

Testing Methodology and Results

ES6 Test262 14998 tests Considerably better test classification than ES5 Test262. ES5 Strict 10958 Tests Tests for ES6 features, Annex B, non-strict mode features Core ES5 Strict 4599 Tests Tests for non-core features Compiler Coverage 2738 Tests Tests for core features still to be implemented

slide-47
SLIDE 47

26/31

Testing Methodology and Results

ES6 Test262 14998 tests Considerably better test classification than ES5 Test262. ES5 Strict 10958 Tests Tests for ES6 features, Annex B, non-strict mode features Core ES5 Strict 4599 Tests Tests for non-core features Compiler Coverage 2738 Tests Tests for core features still to be implemented Tests using non-implemented core features Compiler Coverage 2481 Tests

slide-48
SLIDE 48

26/31

Testing Methodology and Results

ES6 Test262 14998 tests Considerably better test classification than ES5 Test262. ES5 Strict 10958 Tests Tests for ES6 features, Annex B, non-strict mode features Core ES5 Strict 4599 Tests Tests for non-core features Compiler Coverage 2738 Tests Tests for core features still to be implemented Tests using non-implemented core features Tests using non-core features Compiler Coverage 2481 Tests Compiler Coverage 2388 Tests

slide-49
SLIDE 49

26/31

Testing Methodology and Results

ES6 Test262 14998 tests Considerably better test classification than ES5 Test262. ES5 Strict 10958 Tests Tests for ES6 features, Annex B, non-strict mode features Core ES5 Strict 4599 Tests Tests for non-core features Compiler Coverage 2738 Tests Tests for core features still to be implemented Tests using non-implemented core features Tests using non-core features Compiler Coverage 2481 Tests Compiler Coverage 2388 Tests 99.6% success rate, 2378 passes, 10 failures due to parser issues, string/number conversion

slide-50
SLIDE 50

27/31

JSVerify: a Smallfoot-type Verification Tool for JSIL

Core ES5 Strict JSCert

JSIL

Non-core libraries

  • JSVerify
slide-51
SLIDE 51

28/31

JSVerify for Internal and Core Functions

JSVerify is used to specify and verify our JSIL implementations

  • f the internal and core library functions, such as getValue.

Example: getValue

x . = L.oY ∗ Π(L :: LS, Y, Z) getValue(x) {Precondition ∗ ret . = Z}

getValue(ln.obar) 3

slide-52
SLIDE 52

29/31

JSVerify for Internal and Core Functions

JSVerify is used to specify and verify our JSIL implementations

  • f the internal and core library functions, such as getValue.

Example: getValue

x . = undefined.oY getValue(x) {Precondition ∗ ret . = error}

getValue(undefined.obar) ERROR

slide-53
SLIDE 53

30/31

JSVerify for Non-core Functions

Core ES5 Strict JSCert

JSIL

Non-core libraries

  • JSVerify
  • Axiomatic specifications for non-core functions
  • Reference implementation in JSIL or Core ES5 Strict,

following the standard, verified with JSVerify, tested against Test262

slide-54
SLIDE 54

31/31

JSIL as a Service

Infer (Facebook) CBMC (Oxford/Amazon) Rosette JSVerify Core ES5 Strict JSCert

JSIL

  • DOM

Non-core libraries