Presentation is loading. Please wait.

Presentation is loading. Please wait.

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

Similar presentations


Presentation on theme: "Typing Local Control and State Using Flow Analysis Arjun Guha, Claudiu Saftoiu, and Shriram Krishnamurthi 1."— Presentation transcript:

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

2 why add types? 2 JavaScript [Anderson ’05, Heidegger ‘09] LISP [Reynolds ’68, Cartwright ’75] Ruby [Furr ’09] Scheme [Tobin-Hochstadt ‘06] Smalltalk [Suzuki ’80] Thorn [Bloom ’09] etc.

3 why we want types for JavaScript 3 verifying security-critical code documentation Caja FBJS

4 untyped code in the wild 4

5 function fromOrigin(p) { if (typeof p === "object") { return Math.sqrt(p.x * p.x + p.y * p.y); } else { return Math.abs(p); } 5 Object with numeric x and y fields Number Union of the two

6 T = Num | Bool | String | Undef | T  T | Any | T  …  T-> T | {field: T, …} 6 Explicit type annotations (primarily on functions)

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

8 Control Operators if, ?: while, for, do, for in switch, continue, break, label: &&, ||, throw, try catch finally 8

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; } 9 Any  String  Bool where is case "object" ?

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(", ") + " }"; } 10 Any  String  Bool implicit case "object"

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) 11 arity mismatch error?

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] 12 stop: Undef stop: Num stop: Num  Undef stop: Num start: Numarr: Array

13 Checks ForJS Gadgets ADsafePython stdlib Ruby stdlib DjangoRails LOC617,7662,000313,938190,00291,999294,807 undefined/null3,29801,686538868712 instanceof17456131,730647764 typeof47440381N/A4 field-presenceunknown 504171348719 Total Checks3,789953,1842,4391,8672,195 13 pervasive runtime checks in various scripting languages

14 Moral “Scripting language” programmers use state and non-trivial control flow to refine types 14

15 A T YPE S YSTEM FOR J AVA S CRIPT 15

16 16

17 Soundness [Preservation] If e : T and e  e’, e’ : T [Progress] If e : T, e is a value, or  e’. e  e’ 17 This is true… but not very useful! Proving this needs a semantics. "The Essence of JavaScript" (ECOOP 2010) Proving this needs a semantics. "The Essence of JavaScript" (ECOOP 2010)

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); } } 18 This is not typeable!

19 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); }

20 Casting Casting is an operation between types But JavaScript (and Scheme, Python, …) have only tags Tag = "number" | "string" | … | {field: T, …}"object" | T  … -> T"function" 20

21 Should really be called tagof … 21 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); }

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); } 22

23 Introducing tagcheck tagcheck R e Reduce e to value v Let t be the typeof (i.e., the tag of) v If t is in R, return v; else error ( tagerr ) 23 Set of tags An expression

24 24 runtime : Type  2 Tag static : 2 Tag  Type static : 2 Tag  Type  Type

25 25 static : 2 Tag  Type  Type static (set("string", "bool"), Str  Num  Bool) = Str  Bool static (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

26 26 Determine static type, identify presumed run-time tags, …that’s the resulting static type narrow type based on these two…

27 27 Num  Str set("string")Str static (set("string"), Num  Str)

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); } 28

29 tagcheck Failure Modes 29 tag set R is inconsistent with the type S resulting type T is inconsistent with the context’s needs actual run-time tag is simply not contained in R

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 ] 30

31 31 1.How to prevent programs from resulting in the new run-time error ( tagerr )? 2.Who’s going to write tagcheck s?

32 F LOW A NALYSIS 1.Value sets are about tags, not values 2.Only inside procedures; halts at calls 3.Intermediate representation (CPS, ANF, SSA, …) 32

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); } 33 p = {"object"} t1 = typeof p t2 = true p = {"number"} t1 = typeof p t2 = false p = runtime({ x: Num, y: Num }  Num) p = {"object", "number"} t1 = typeof p t2 = t1 === "object"

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); } 34 p = {"object"} t1 = typeof p t2 = true p = {"number"} t1 = typeof p t2 = false

35 35 p = {"object"} t1 = typeof p t2 = true p = {"number"} t1 = typeof p t2 = 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); }

36 function fromOrigin(p) { /* { x: Num, y: Num }  Num -> Num */... } fromOrigin(500) fromOrigin({ x : 20, y: 900 }) fromOrigin("invalid argument") 36 actual arguments ignored by flows therefore, invalid arguments ignored too! p = runtime({ x: Num, y: Num }  Num) = {"object", "number"}

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] 37 [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

38 Our Recipe Simple 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 sound The performance is great (seconds on netbook) 38

39 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


Download ppt "Typing Local Control and State Using Flow Analysis Arjun Guha, Claudiu Saftoiu, and Shriram Krishnamurthi 1."

Similar presentations


Ads by Google