Lua Jan Midtgaard Dagstuhl Seminar 16131 State of affairs, PL-wise - - PowerPoint PPT Presentation

lua
SMART_READER_LITE
LIVE PREVIEW

Lua Jan Midtgaard Dagstuhl Seminar 16131 State of affairs, PL-wise - - PowerPoint PPT Presentation

A Static Type Analysis for Lua Lua Jan Midtgaard Dagstuhl Seminar 16131 State of affairs, PL-wise Good news: Many of todays popular programming languages (JavaScript, Python, Lua, . . . ) are dynamically typed: they enable rapid


slide-1
SLIDE 1

A Static Type Analysis for Lua

Lua

Jan Midtgaard

Dagstuhl Seminar 16131

slide-2
SLIDE 2

State of affairs, PL-wise

2 / 30

Good news: Many of today’s popular programming languages (JavaScript, Python, Lua, . . . ) are dynamically typed:

  • they enable rapid prototyping and
  • flexible software development

Bad news: In terms of software guarantees, that means

  • we don’t get many guarantees from the compiler
  • bugs may surface late in the development cycle
slide-3
SLIDE 3

Just for fun?

3 / 30

slide-4
SLIDE 4

Just for fun?

3 / 30

slide-5
SLIDE 5

This talk

4 / 30

More good news: Static analysis to the rescue! Today: Developing a static analysis (lattice) for inferring types of Lua programs

Lua

Result: A tool

slide-6
SLIDE 6

Lua?

5 / 30 Lua games picture slide courtesy of Ierusalimschy, de Figueiredo, and Celes. The above company names and logos are trademarked.

slide-7
SLIDE 7

Lua, in brief

6 / 30

  • Developed in Brazil, hence the name (’lua’ = ’moon’)
  • Similar to languages like Python and JavaScript
  • Lightweight language (few, well-chosen features):

Imperative

Dynamically typed

Builtin tables (associative arrays)

First-class functions

. . .

  • Multiparadigm (FP

, OO, . . . )

  • Lightweight, cross-platform implementation
  • Standalone and easily embeddable
slide-8
SLIDE 8

Example: Sets of numbers (Ierusalimschy’13)

7 / 30

Set = {}

  • - create a new set with the values of a given list

function Set.new (l) local set = {} for _, v in ipairs(l) do set[v] = true end return set end function Set.union (a, b) local res = Set.new {} for k in pairs(a) do res[k] = true end for k in pairs(b) do res[k] = true end return res end s1 = Set.new {10 ,20 ,30 ,50} s2 = Set.new {30 ,1} s3 = Set.union(s1,s2)

slide-9
SLIDE 9

Example: Sets of numbers, desugared

8 / 30

Set = {}

  • - create a new set with the values of a given list

Set.new = function (l) local set = {} for _, v in ipairs(l) do set[v] = true end return set end Set.union = function (a, b) local res = Set.new {} for k in pairs(a) do res[k] = true end for k in pairs(b) do res[k] = true end return res end s1 = Set.new {10 ,20 ,30 ,50} s2 = Set.new {30 ,1} s3 = Set.union(s1,s2)

slide-10
SLIDE 10

Example: Sets of numbers, desugared

8 / 30

Set = {}

  • - create a new set with the values of a given list

Set.new = function (l) local set = {} for _, v in ipairs(l) do set[v] = true end return set end Set.union = function (a, b) local res = Set.new {} for k in pairs(a) do res[k] = true end for k in pairs(b) do res[k] = true end return res end s1 = Set.new {10 ,20 ,30 ,50} s2 = Set.new {30 ,1} s3 = Set.union(s1,s2)

builtin tables

slide-11
SLIDE 11

Example: Sets of numbers, desugared

8 / 30

Set = {}

  • - create a new set with the values of a given list

Set.new = function (l) local set = {} for _, v in ipairs(l) do set[v] = true end return set end Set.union = function (a, b) local res = Set.new {} for k in pairs(a) do res[k] = true end for k in pairs(b) do res[k] = true end return res end s1 = Set.new {10 ,20 ,30 ,50} s2 = Set.new {30 ,1} s3 = Set.union(s1,s2)

tables as modules builtin tables

slide-12
SLIDE 12

Example: Sets of numbers, desugared

8 / 30

Set = {}

  • - create a new set with the values of a given list

Set.new = function (l) local set = {} for _, v in ipairs(l) do set[v] = true end return set end Set.union = function (a, b) local res = Set.new {} for k in pairs(a) do res[k] = true end for k in pairs(b) do res[k] = true end return res end s1 = Set.new {10 ,20 ,30 ,50} s2 = Set.new {30 ,1} s3 = Set.union(s1,s2)

tables as modules builtin tables lexical scope, block structure

slide-13
SLIDE 13

Lua in a bit more detail. . .

9 / 30

To add PL spice it also includes:

  • Metatables with events and metamethods:

These are used to model both OO-like inheritance and overriding

Python has similar constructions

  • Proper tail calls
  • Co-routines
  • . . .
slide-14
SLIDE 14

Example: Sets w/overriding (Ierusalimschy’13)

10 / 30

Set = {} local mt = {} -- metatable for sets

  • - create a new set with the values of a given list

function Set.new (l) local set = {} setmetatable(set ,mt) for _, v in ipairs(l) do set[v] = true end return set end function Set.union (a, b) local res = Set.new {} for k in pairs(a) do res[k] = true end for k in pairs(b) do res[k] = true end return res end mt.__add = Set.union s1 = Set.new {10 ,20 ,30 ,50} s2 = Set.new {30 ,1} s3 = s1 + s2

slide-15
SLIDE 15

Example: Sets w/overriding (Ierusalimschy’13)

10 / 30

Set = {} local mt = {} -- metatable for sets

  • - create a new set with the values of a given list

function Set.new (l) local set = {} setmetatable(set ,mt) for _, v in ipairs(l) do set[v] = true end return set end function Set.union (a, b) local res = Set.new {} for k in pairs(a) do res[k] = true end for k in pairs(b) do res[k] = true end return res end mt.__add = Set.union s1 = Set.new {10 ,20 ,30 ,50} s2 = Set.new {30 ,1} s3 = s1 + s2

declare a metatable

slide-16
SLIDE 16

Example: Sets w/overriding (Ierusalimschy’13)

10 / 30

Set = {} local mt = {} -- metatable for sets

  • - create a new set with the values of a given list

function Set.new (l) local set = {} setmetatable(set ,mt) for _, v in ipairs(l) do set[v] = true end return set end function Set.union (a, b) local res = Set.new {} for k in pairs(a) do res[k] = true end for k in pairs(b) do res[k] = true end return res end mt.__add = Set.union s1 = Set.new {10 ,20 ,30 ,50} s2 = Set.new {30 ,1} s3 = s1 + s2

declare a metatable install metatable

slide-17
SLIDE 17

Example: Sets w/overriding (Ierusalimschy’13)

10 / 30

Set = {} local mt = {} -- metatable for sets

  • - create a new set with the values of a given list

function Set.new (l) local set = {} setmetatable(set ,mt) for _, v in ipairs(l) do set[v] = true end return set end function Set.union (a, b) local res = Set.new {} for k in pairs(a) do res[k] = true end for k in pairs(b) do res[k] = true end return res end mt.__add = Set.union s1 = Set.new {10 ,20 ,30 ,50} s2 = Set.new {30 ,1} s3 = s1 + s2

declare a metatable install metatable register metamethod for addition event

slide-18
SLIDE 18

Example: Sets w/overriding (Ierusalimschy’13)

10 / 30

Set = {} local mt = {} -- metatable for sets

  • - create a new set with the values of a given list

function Set.new (l) local set = {} setmetatable(set ,mt) for _, v in ipairs(l) do set[v] = true end return set end function Set.union (a, b) local res = Set.new {} for k in pairs(a) do res[k] = true end for k in pairs(b) do res[k] = true end return res end mt.__add = Set.union s1 = Set.new {10 ,20 ,30 ,50} s2 = Set.new {30 ,1} s3 = s1 + s2

declare a metatable install metatable register metamethod for addition event utilize overridden addition

slide-19
SLIDE 19

A program analysis for types

11 / 30

  • We’ll build a forward program analysis for

approximating the run-time values of Lua programs

  • It’s not a type system (no rejected programs)
  • Instead: an over-approximation over a suitable lattice

Our challenge is to design a lattice capable of expressing types for this kind of example Related work: . . .

slide-20
SLIDE 20

A program analysis for types

11 / 30

  • We’ll build a forward program analysis for

approximating the run-time values of Lua programs

  • It’s not a type system (no rejected programs)
  • Instead: an over-approximation over a suitable lattice

Our challenge is to design a lattice capable of expressing types for this kind of example Related work: . . . lots

slide-21
SLIDE 21

Describing Lua values, take 1

12 / 30

Lua has a range of basic values:

nil, true, false, 42, 3.14, "hello", ’world’, . . . statelattice = Var − → valuelattice valuelattice = P(tag) tag = {nil, bool, number, string, userdata}

  • We record the (over-approximate) state for each

program point

slide-22
SLIDE 22

Describing Lua values, take 1

12 / 30

Lua has a range of basic values:

nil, true, false, 42, 3.14, "hello", ’world’, . . . statelattice = Var − → valuelattice valuelattice = P(tag) tag = {nil, bool, number, string, userdata}

  • We record the (over-approximate) state for each

program point

  • This can be understood as an outer function lattice
slide-23
SLIDE 23

Describing Lua values, take 1

12 / 30

Lua has a range of basic values:

nil, true, false, 42, 3.14, "hello", ’world’, . . . analysislattice = pplabel − → statelattice statelattice = Var − → valuelattice valuelattice = P(tag) tag = {nil, bool, number, string, userdata}

  • We record the (over-approximate) state for each

program point

  • This can be understood as an outer function lattice
slide-24
SLIDE 24

In Lua hashtables are everywhere!

13 / 30

In Lua even environments are hashtables:

for name ,val in pairs(_G) do print(name , type(val)) end

displays _G’s content (the global environment):

string table pairs function _G table type function arg table rawget function loadstring function ...

Tables double as modules (e.g., string.len), objects, and classes

slide-25
SLIDE 25

Approximating Lua’s hashtables (1/6)

14 / 30

As a first step we will label all allocation sites:

Set = ℓ1{}

  • - create a new set with the values of a given list

Set.new = function (l) local set = ℓ2{} for _, v in ipairs(l) do set[v] = true end return set end ...

An allocation site (a label) represents all table values

  • riginating from there (Jones-Muchnick:POPL82).

A table’s contents is available in an approximate store.

slide-26
SLIDE 26

Approximating Lua’s hashtables (2/6)

15 / 30

analysislattice = pplabel − → statelattice statelattice = storelattice × envlattice envlattice = tablelabel+ storelattice = tablelabel − → proplattice proplattice = (string − → valuelattice) × valuelattice valuelattice = P(tag) × P(tablelabel) tag = {nil, bool, number, string, userdata}

  • A table value is approximated by its label
  • storelattice and proplattice reveal the table content
  • Environments reuse this representation:

We label each scope (scope chain is a label string)

slide-27
SLIDE 27

Approximating Lua’s hashtables (3/6)

16 / 30

analysislattice = pplabel − → statelattice statelattice = storelattice × envlattice envlattice = tablelabel+ storelattice = tablelabel − → proplattice proplattice = (string − → valuelattice) × valuelattice valuelattice = P(tag) × P(tablelabel) tag = {nil, bool, number, string, userdata}

  • An extra valuelattice works as a fall back for statically

unknown entries.

  • This is good enough to model environments

(we know variable names statically)

  • But t[x] = v to a string key could write to any entry
slide-28
SLIDE 28

Approximating Lua’s hashtables (4/6)

17 / 30

analysislattice = pplabel − → statelattice statelattice = storelattice × envlattice envlattice = tablelabel+ storelattice = tablelabel − → proplattice proplattice = (string − → valuelattice) × valuelattice valuelattice = P(tag) × stringlattice × P(tablelabel) stringlattice= {⊥, ⊤} ∪ string tag = {nil, bool, number, userdata}

Solution:

  • a better approximation of string values
  • using a constant propagation lattice (∀s. ⊥ ⊑ s ⊑ ⊤)
slide-29
SLIDE 29

Approximating Lua’s hashtables (5/6)

18 / 30

analysislattice = pplabel − → statelattice statelattice = storelattice × envlattice envlattice = tablelabel+ storelattice = tablelabel − → proplattice proplattice = (string − → valuelattice) × valuelattice valuelattice = P(tag) × stringlattice × P(tablelabel) stringlattice = {⊥, ⊤} ∪ string tag = {nil, bool, number, userdata}

Challenge:

  • Lua’s hashtable keys can be any value (except nil)
  • But the lattice loses track of non-string keys!
slide-30
SLIDE 30

Approximating Lua’s hashtables (5/6)

18 / 30

analysislattice = pplabel − → statelattice statelattice = storelattice × envlattice envlattice = tablelabel+ storelattice = tablelabel − → proplattice proplattice = (string − → valuelattice) × valuelattice × valuelattice valuelattice = P(tag) × stringlattice × P(tablelabel) stringlattice = {⊥, ⊤} ∪ string tag = {nil, bool, number, userdata}

Challenge:

  • Lua’s hashtable keys can be any value (except nil)
  • But the lattice loses track of non-string keys!
  • We over-approximate all keys with an additional

valuelattice

slide-31
SLIDE 31

Approximating Lua’s hashtables (6/6)

19 / 30

analysislattice = pplabel − → statelattice statelattice = storelattice × envlattice envlattice = tablelabel+ storelattice = tablelabel − → proplattice proplattice = (string − → valuelattice) × valuelattice × valuelattice valuelattice = P(tag) × stringlattice × P(tablelabel) stringlattice = {⊥, ⊤} ∪ string tag = {nil, bool, number, userdata}

  • Lua 5.1 has setfenv which manipulates the

environment at run time

slide-32
SLIDE 32

Approximating Lua’s hashtables (6/6)

19 / 30

analysislattice = pplabel − → statelattice statelattice = storelattice × envlattice envlattice = P(tablelabel+) storelattice = tablelabel − → proplattice proplattice = (string − → valuelattice) × valuelattice × valuelattice valuelattice = P(tag) × stringlattice × P(tablelabel) stringlattice = {⊥, ⊤} ∪ string tag = {nil, bool, number, userdata}

  • Lua 5.1 has setfenv which manipulates the

environment at run time

  • We anticipate the issue and allow environment

approximation

slide-33
SLIDE 33

Lua has first class functions

20 / 30

Which means we can pass around functions as values:

function apply (f, x) return f(x) end local tmp = apply(functionℓ (x) return x end , "foo") print(tmp , apply(type , tmp))

Again we use labels:

  • A label represents all function values originating

from a function literal

  • The labels can tell us where control transfers to
  • This is known as a Control-Flow Analysis (CFA)
slide-34
SLIDE 34

A Lua type analysis lattice

21 / 30

analysislattice = pplabel − → statelattice statelattice = storelattice × envlattice envlattice = P(tablelabel+) storelattice = tablelabel − → proplattice proplattice = (string − → valuelattice) × valuelattice × valuelattice valuelattice = P(tag) × stringlattice × P(funlabel) × P(tablelabel) stringlattice = {⊥, ⊤} ∪ string tag = {nil, bool, number, userdata}

  • The extra label set tracks such function labels
slide-35
SLIDE 35

A Lua type analysis lattice

21 / 30

analysislattice = pplabel − → statelattice statelattice = storelattice × envlattice envlattice = P(tablelabel+) storelattice = tablelabel − → proplattice proplattice = (string − → valuelattice) × valuelattice × valuelattice valuelattice = P(tag) × stringlattice × P(funlabel) × P(tablelabel) stringlattice = {⊥, ⊤} ∪ string tag = {nil, bool, number, userdata}

  • The extra label set tracks such function labels
  • This is a first reasonable version
slide-36
SLIDE 36

A Lua type analysis lattice

21 / 30

analysislattice = pplabel − → statelattice statelattice = storelattice × envlattice envlattice = P(tablelabel+) storelattice = tablelabel − → proplattice proplattice = (string − → valuelattice) × valuelattice × valuelattice valuelattice = P(tag) × stringlattice × P(funlabel) × P(tablelabel) stringlattice = {⊥, ⊤} ∪ string tag = {nil, bool, number, userdata}

  • The extra label set tracks such function labels
  • This is a first reasonable version
  • But there is (plenty) of room for improvement. . .
slide-37
SLIDE 37

Room for improvement. . .

22 / 30

analysislattice = pplabel − → statelattice statelattice = storelattice × envlattice envlattice = P(tablelabel+) storelattice = tablelabel − → proplattice proplattice = (string − → valuelattice) × valuelattice × valuelattice valuelattice = P(tag) × stringlattice × P(funlabel) × P(tablelabel) stringlattice = {⊥, ⊤} ∪ string tag = {nil, bool, number, userdata}

slide-38
SLIDE 38

Room for improvement. . .

22 / 30

analysislattice = pplabel − → statelattice statelattice = storelattice × envlattice envlattice = P(tablelabel+) storelattice = tablelabel − → proplattice proplattice = (string − → valuelattice) × valuelattice × valuelattice valuelattice = P(tag) × stringlattice × P(funlabel) × P(tablelabel) stringlattice = {⊥, ⊤} ∪ string tag = {nil, bool, number, userdata}

Problem:

  • In proplattice entries may or may not be there
  • This causes too many false positives (failed lookups)
slide-39
SLIDE 39

Solution: track certainty of presence

23 / 30

analysislattice = pplabel − → statelattice statelattice = storelattice × envlattice envlattice = P(tablelabel+) storelattice = tablelabel − → proplattice proplattice = (string − → absencelattice × valuelattice) × valuelattice × valuelattice absencelattice = {⊥, ⊤} valuelattice = P(tag) × stringlattice × P(funlabel) × P(tablelabel) stringlattice = {⊥, ⊤} ∪ string tag = {nil, bool, number, userdata}

  • ⊥ = “we are certain the table entry is present”
  • ⊤ = “the table entry may be absent”
  • Akin to TAJS lattice for JavaScript (Jensen-al:SAS09)
slide-40
SLIDE 40

Tracking installed metatables

24 / 30

analysislattice = pplabel − → statelattice statelattice = storelattice × envlattice envlattice = P(tablelabel+) storelattice = tablelabel − → proplattice proplattice = ((string ∪ {metatable}) − → absencelattice × valuelattice) × valuelattice × valuelattice absencelattice = {⊥, ⊤} valuelattice = P(tag) × stringlattice × numberlattice × P(funlabel) × P(tablelabel) stringlattice = {⊥, ⊤} ∪ string numberlattice = {⊥, ⊤} tag = {nil, bool, userdata}

A special table entry models installed metatables

slide-41
SLIDE 41

Modeling Lua program execution (1/2)

25 / 30

Transfer functions over this lattice now models Lua’s semantics. The manual specifies, e.g., events with interpreters:

function add_event (op1 , op2) local o1 , o2 = tonumber(op1), tonumber(op2) if o1 and o2 then

  • - both operands are numeric?

return o1 + o2

  • - ’+’ here is the primitive ’add

’ else

  • - at least one of the operands is not numeric

local h = getbinhandler(op1 , op2 , "__add") if h then

  • - call the handler with both operands

return (h(op1 , op2)) else

  • - no handler available: default behavior

error(· · ·) end end end

slide-42
SLIDE 42

Modeling Lua program execution (1/2)

25 / 30

Transfer functions over this lattice now models Lua’s semantics. The manual specifies, e.g., events with interpreters:

function add_event (op1 , op2) local o1 , o2 = tonumber(op1), tonumber(op2) if o1 and o2 then

  • - both operands are numeric?

return o1 + o2

  • - ’+’ here is the primitive ’add

’ else

  • - at least one of the operands is not numeric

local h = getbinhandler(op1 , op2 , "__add") if h then

  • - call the handler with both operands

return (h(op1 , op2)) else

  • - no handler available: default behavior

error(· · ·) end end end

numeric add

slide-43
SLIDE 43

Modeling Lua program execution (1/2)

25 / 30

Transfer functions over this lattice now models Lua’s semantics. The manual specifies, e.g., events with interpreters:

function add_event (op1 , op2) local o1 , o2 = tonumber(op1), tonumber(op2) if o1 and o2 then

  • - both operands are numeric?

return o1 + o2

  • - ’+’ here is the primitive ’add

’ else

  • - at least one of the operands is not numeric

local h = getbinhandler(op1 , op2 , "__add") if h then

  • - call the handler with both operands

return (h(op1 , op2)) else

  • - no handler available: default behavior

error(· · ·) end end end

numeric add

  • verridden add
slide-44
SLIDE 44

Modeling Lua program execution (2/2)

26 / 30

Transfer functions over this lattice now models Lua’s semantics. We try to stick as close to the manual as possible:

and transfer_arith_event clab info op event op1 op2 = let o1 ,o2 = VL.coerce_tonum op1 , VL.coerce_tonum op2 in mvl_join (if VL.may_be_number (VL.meet o1 o2) (* -- both operands are numeric? *) then red_return (VL.binop op o1 o2) (* -- ’+’ here is the primitive ’add ’ *) else merror) (getbinhandler op1 op2 event >>= fun h -> if VL.may_be_proc h then (* -- call the handler with both operands *) transfer_calls clab h [op1;op2] info >>= adjust_to_single else (* -- no handler available: default behavior *) merror)

slide-45
SLIDE 45

Modeling Lua program execution (2/2)

26 / 30

Transfer functions over this lattice now models Lua’s semantics. We try to stick as close to the manual as possible:

and transfer_arith_event clab info op event op1 op2 = let o1 ,o2 = VL.coerce_tonum op1 , VL.coerce_tonum op2 in mvl_join (if VL.may_be_number (VL.meet o1 o2) (* -- both operands are numeric? *) then red_return (VL.binop op o1 o2) (* -- ’+’ here is the primitive ’add ’ *) else merror) (getbinhandler op1 op2 event >>= fun h -> if VL.may_be_proc h then (* -- call the handler with both operands *) transfer_calls clab h [op1;op2] info >>= adjust_to_single else (* -- no handler available: default behavior *) merror)

numeric add

slide-46
SLIDE 46

Modeling Lua program execution (2/2)

26 / 30

Transfer functions over this lattice now models Lua’s semantics. We try to stick as close to the manual as possible:

and transfer_arith_event clab info op event op1 op2 = let o1 ,o2 = VL.coerce_tonum op1 , VL.coerce_tonum op2 in mvl_join (if VL.may_be_number (VL.meet o1 o2) (* -- both operands are numeric? *) then red_return (VL.binop op o1 o2) (* -- ’+’ here is the primitive ’add ’ *) else merror) (getbinhandler op1 op2 event >>= fun h -> if VL.may_be_proc h then (* -- call the handler with both operands *) transfer_calls clab h [op1;op2] info >>= adjust_to_single else (* -- no handler available: default behavior *) merror)

numeric add

  • verridden add
slide-47
SLIDE 47

Utilizing the static analysis result

27 / 30

precise answer

this cannot happen Things outside the over-approximations are impossible, e.g., unreachable code (lets us emit a warning)

slide-48
SLIDE 48

Prototype implementation

28 / 30

We’ve built a prototype implementation

  • Functional, written in OCaml
  • One module per lattice (with associated operations)
  • AST walker, written monadically
  • Approx. 5000 LOC + 2100 LOC tests
  • Web-version thanks to js_of_ocaml
slide-49
SLIDE 49

Prototype implementation

28 / 30

We’ve built a prototype implementation

  • Functional, written in OCaml
  • One module per lattice (with associated operations)
  • AST walker, written monadically
  • Approx. 5000 LOC + 2100 LOC tests
  • Web-version thanks to js_of_ocaml

[ Very Quick Demo :-) ]

http://jmid.github.io/luata-quickcheck/

slide-50
SLIDE 50

Future work

29 / 30

  • Warnings: definitely non-existent table entries
  • Lattice refinements:

to track array indices separately

for more precise type string tracking

to handle error idiom of Lua:

local function idiv(d1 , d2) if d2 == 0 then return nil , "division by zero" else local r = d1 % d2 local q = (d1 - r)/d2 return q, r end end

  • More libraries (standard and others)
slide-51
SLIDE 51

Summary, conclusion, and reflections

30 / 30

  • We’ve taken a run-down of a non-trivial lattice
  • The resulting analysis can handle a range of Lua

examples — but leaves room for improvement

  • The analysis is exemplar of a range of type analysis

work (Aarhus U, IBM TJ Watson, KAIST, . . . ) In retrospect:

  • a global heap approximation restricts scalability

(reconsider or do symbolic/modular analysis?)

  • limited faith in magic constants for k-CFA context

sensitivity

  • an ongoing quest for good, reusable abstractions
slide-52
SLIDE 52

Summary, conclusion, and reflections

30 / 30

  • We’ve taken a run-down of a non-trivial lattice
  • The resulting analysis can handle a range of Lua

examples — but leaves room for improvement

  • The analysis is exemplar of a range of type analysis

work (Aarhus U, IBM TJ Watson, KAIST, . . . ) In retrospect:

  • a global heap approximation restricts scalability

(reconsider or do symbolic/modular analysis?)

  • limited faith in magic constants for k-CFA context

sensitivity

  • an ongoing quest for good, reusable abstractions

Thanks