typing local control and state using flow analysis

39
Typing Local Control and State Using Flow Analysis Arjun Guha, Claudiu Saftoiu, and Shriram Krishnamurthi 1

Upload: duscha

Post on 23-Feb-2016

31 views

Category:

Documents


0 download

DESCRIPTION

Typing Local Control and State Using Flow Analysis. Arjun Guha, Claudiu Saftoiu, and Shriram Krishnamurthi. why add types?. JavaScript [Anderson ’05, Heidegger ‘09 ] LISP [Reynolds ’68, Cartwright ’75] Ruby [ Furr ’09 ] Scheme [Tobin- Hochstadt ‘06 ] Smalltalk [Suzuki ’80 ] - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Typing Local Control and State Using Flow Analysis

1

Typing Local Control and State Using Flow Analysis

Arjun Guha, Claudiu Saftoiu, and Shriram Krishnamurthi

Page 2: Typing Local Control and State Using Flow Analysis

2

why add types?

• JavaScript [Anderson ’05, Heidegger ‘09]

• LISP [Reynolds ’68, Cartwright ’75]• Ruby [Furr ’09]• Scheme [Tobin-Hochstadt ‘06]• Smalltalk [Suzuki ’80]• Thorn [Bloom ’09]• etc.

Page 3: Typing Local Control and State Using Flow Analysis

3

why we want types for JavaScript

verifying security-critical code

documentation

Caja

FBJS

Page 4: Typing Local Control and State Using Flow Analysis

4

untyped code in the wild

Page 5: Typing Local Control and State Using Flow Analysis

5

function fromOrigin(p) { if (typeof p === "object") { return Math.sqrt(p.x * p.x + p.y * p.y); } else { return Math.abs(p); }}

Object with numeric

x and y fieldsNumber

Union of the two

Page 6: Typing Local Control and State Using Flow Analysis

6

T = Num | Bool | String | Undef | T T | Any | T … T-> T | {field: T, …} Explicit

typeannotations(primarily on

functions)

Page 7: Typing Local Control and State Using Flow Analysis

7

function fromOrigin(p) { if (typeof p === "object") { return Math.sqrt(p.x * p.x + p.y * p.y); } else { return Math.abs(p); }}

p: {x: Num, y: Num}

p: Num

p: {x: Num, y: Num} Num

Page 8: Typing Local Control and State Using Flow Analysis

8

Control Operatorsif, ?:while, for, do, for inswitch, continue, break, label:&&, ||, throw, try catch finally

Page 9: Typing Local Control and State Using Flow Analysis

9

if (val === null) { return "null"; } var fields = [ ]; for (var p in val) { var v = serialize(val[p]); if (typeof v === "string") { fields.push(p + ": " + v); } } return "{ " + fields.join(", ") + " }";}

function serialize(val) { switch (typeof val) { case "undefined": case "function": return false; case "boolean": return val ? "true" : "false"; case "number": return "" + val; case "string": return val; }

Any String Bool

where is case

"object"?

Page 10: Typing Local Control and State Using Flow Analysis

10

function serialize(val) { switch (typeof val) { case "undefined": case "function": return false; case "boolean": return val ? "true" : "false"; case "number": return "" + val; case "string": return val; }

if (val === null) { return "null"; } var fields = [ ]; for (var p in val) { var v = serialize(val[p]); if (typeof v === "string") { fields.push(p + ": " + v); } } return "{ " + fields.join(", ") + " }";}

Any String Bool

implicit case "object"

Page 11: Typing Local Control and State Using Flow Analysis

11

var slice = function (arr, start, stop) {

var result = []; for (var i = 0; i <= stop - start; i++) { result[i] = arr[start + i]; } return result;}

slice([5, 7, 11, 13], 0, 2) [5, 7, 11]

slice([5, 7, 11, 13], 2)arity

mismatch error?

Page 12: Typing Local Control and State Using Flow Analysis

12

var slice = function (arr, start, stop) {

if (typeof stop === "undefined") { stop = arr.length – 1; }

var result = []; for (var i = 0; i <= stop - start; i++) { result[i] = arr[start + i]; } return result;}

slice([5, 7, 11, 13], 0, 2) [5, 7, 11]

slice([5, 7, 11, 13], 2) [11, 13]

stop: Undef

stop: Num

stop: Num Undef

stop: Num

start: Numarr: Array<a>

Page 13: Typing Local Control and State Using Flow Analysis

13

Checks For JS Gadgets

ADsafe Python stdlib

Ruby stdlib

Django

Rails

LOC 617,766

2,000 313,938

190,002

91,999 294,807

undefined/null

3,298 0 1,686 538 868 712

instanceof 17 45 613 1,730 647 764typeof 474 40 381 N/A 4 N/Afield-presence

unknown

unknown

504 171 348 719

Total Checks

3,789 95 3,184 2,439 1,867 2,195pervasive runtime checks in various

scripting languages

Page 14: Typing Local Control and State Using Flow Analysis

14

Moral“Scripting language” programmers

use state and non-trivial control flow

to refine types

Page 15: Typing Local Control and State Using Flow Analysis

15

A TYPE SYSTEM FOR JAVASCRIPT

Page 16: Typing Local Control and State Using Flow Analysis

16

Page 17: Typing Local Control and State Using Flow Analysis

17

Soundness[Preservation]

If e : T and e e’, e’ : T

[Progress]If e : T,• e is a value, or• e’ . e e’

Thisis

true…but

not very useful!

Proving this needs a semantics.

"The Essence of JavaScript" (ECOOP

2010)

Page 18: Typing Local Control and State Using Flow Analysis

18

function fromOrigin(p) { /* {x: Num, y: Num} Num -> Num */ if (typeof p === "object") { return Math.sqrt(p.x * p.x + p.y * p.y); } else { return Math.abs(p); }}

This is not typeable!

Page 19: Typing Local Control and State Using Flow Analysis

19

function fromOrigin(p) { /* {x: Num, y: Num} Num -> Num */ if (typeof p === "object") { var pt = cast p …; return Math.sqrt(pt.x * pt.x + pt.y * pt.y); } else { var pf = cast p …; return Math.abs(pf); }}

Page 20: Typing Local Control and State Using Flow Analysis

20

CastingCasting is an operation between types

But JavaScript (and Scheme, Python, …)have only tags

Tag = "number" | "string" | … | {field: T, …} "object" | T … -> T "function"

Page 21: Typing Local Control and State Using Flow Analysis

21

Should really becalled tagof…

function fromOrigin(p) { /* {x: Num, y: Num} Num -> Num */ if (typeof p === "object") { var pt = cast p …; return Math.sqrt(pt.x * pt.x + pt.y * pt.y); } else { var pf = cast p …; return Math.abs(pf); }}

Page 22: Typing Local Control and State Using Flow Analysis

22

function fromOrigin(p) { /* {x: Num, y: Num} Num -> Num */ if (typeof p === "object") { var pt = tagcheck(set("object"), p); return Math.sqrt(pt.x * pt.x + pt.y * pt.y); } else { var pf = tagcheck(set("number"), p); return Math.abs(pf); }}

Page 23: Typing Local Control and State Using Flow Analysis

23

Introducing tagchecktagcheck R e

Reduce e to value vLet t be the typeof (i.e., the tag of) vIf t is in R, return v; else error (tagerr)

Set of

tags

Anexpressi

on

Page 24: Typing Local Control and State Using Flow Analysis

24

runtime : Type 2Tag

static : 2Tag Typestatic : 2Tag Type Type

Page 25: Typing Local Control and State Using Flow Analysis

25

static : 2Tag Type Type

static(set("string", "bool"), Str Num Bool)= Str Boolstatic(set("object"), {x: Num, y: Num} Num))

= {x: Num, y: Num}

Given a set of tags…

…and a type…

…pick out the parts

of the type that correspond to the

tags

Page 26: Typing Local Control and State Using Flow Analysis

26

Determine static type,

identify presumed run-time

tags,

…that’s the

resulting static type

narrow type

based on these two…

Page 27: Typing Local Control and State Using Flow Analysis

27

Num Str

set("string") Str

static(set("string"), Num Str)

Page 28: Typing Local Control and State Using Flow Analysis

28

function fromOrigin(p) { /* {x: Num, y: Num} Num -> Num */ if (typeof p === "object") { var pt = tagcheck(set("object"), p); return Math.sqrt(pt.x * pt.x + pt.y * pt.y); } else { var pf = tagcheck(set("number"), p); return Math.abs(pf); }}

Page 29: Typing Local Control and State Using Flow Analysis

29

tagcheck Failure Modestag set R is inconsistent

with the type S

resulting type T is

inconsistent with

the context’s needs

actual run-time tag is simply notcontained in R

Page 30: Typing Local Control and State Using Flow Analysis

30

Soundness[Preservation]

If e : T and e e’, e’ : T

[Progress]If e : T,• e is a value, or• e’ . e e’, or• e = E[tagerr ]

Page 31: Typing Local Control and State Using Flow Analysis

31

1. How to prevent programs from resulting in the new run-time error (tagerr)?

2. Who’s going to write tagchecks?

Page 32: Typing Local Control and State Using Flow Analysis

32

FLOW ANALYSIS1. Value sets are about tags, not values

2. Only inside procedures; halts at calls

3. Intermediate representation (CPS, ANF, SSA, …)

Page 33: Typing Local Control and State Using Flow Analysis

33

function fromOrigin(p) { /* {x: Num, y: Num } Num -> Num */ var t1 = typeof p; var t2 = (t1 === "object"); if (t2) { var t3 = p.x; var t4 = p.x; var t5 = t3 * t4; var t6 = p.y; var t7 = p.y; var t8 = t6 * t7; var t9 = t5 + t8; return Math.sqrt(t9); } else { return Math.abs(p); }}

p = {"object"}t1 = typeof pt2 = true

p = {"number"}t1 = typeof pt2 = false

p = runtime({ x: Num, y: Num } Num)p = {"object", "number"}

p = {"object", "number"}t1 = typeof pt2 = t1 === "object"

Page 34: Typing Local Control and State Using Flow Analysis

34

function fromOrigin(p) { /* {x: Num, y: Num } Num -> Num */ var t1 = typeof p; var t2 = (t1 === "object"); if (t2) {

var t3 = p.x; var t4 = p.x; var t5 = t3 * t4; var t6 = p.y; var t7 = p.y; var t8 = t6 * t7; var t9 = t5 + t8; return Math.sqrt(t9); } else {

return Math.abs(p); }}

p = {"object"}t1 = typeof pt2 = true

p = {"number"}t1 = typeof pt2 = false

Page 35: Typing Local Control and State Using Flow Analysis

35

p = {"object"}t1 = typeof pt2 = true

p = {"number"}t1 = typeof pt2 = false

function fromOrigin(p) { /* {x: Num, y: Num } Num -> Num */ var t1 = typeof p; var t2 = (t1 === "object"); if (t2) { var pt = tagcheck(set("object"), p); var t3 = pt.x; var t4 = pt.x; var t5 = t3 * t4; var t6 = pt.y; var t7 = pt.y; var t8 = t6 * t7; var t9 = t5 + t8; return Math.sqrt(t9); } else { var pf = tagcheck(set("number"), p); return Math.abs(pf); }}

Page 36: Typing Local Control and State Using Flow Analysis

36

function fromOrigin(p) { /* { x: Num, y: Num } Num -> Num */ ...}

fromOrigin(500)fromOrigin({ x : 20, y: 900 })

fromOrigin("invalid argument")

actual arguments ignored by flows

therefore, invalid arguments ignored too!

p = runtime({ x: Num, y: Num } Num) = {"object", "number"}

Page 37: Typing Local Control and State Using Flow Analysis

37

[Type Pres.]If e : T and e e’, e’ : T[Type Prog.]If e : T,• e is a value, or• e’ . e e’, or• e = E[tagerr]

[Flow Soundness]If e : ok and e e’,• e’ : ok, or• e is a βv redex(func(x) : T … { return e })(v)

tagof(v) runtime(T)

Combined Soundness for Types and Flows

Page 38: Typing Local Control and State Using Flow Analysis

38

Our RecipeSimple type checker (not quite

enough)Add tagcheck (breaks progress)Simple flow analysis (w/ preservation

broken)

“Types on the outside, flows on the inside”

The composition is soundThe performance is great (seconds on

netbook)

Page 39: Typing Local Control and State Using Flow Analysis

39

JavaScript Semantics (ECOOP 2010)

Typing Local Control and State (ESOP 2011)

Typing Objects (in progress)

Verifying Web Sandboxes

Types as Documentation for

JavaScript programs