Modular Instrumentation of Interpreters in JavaScript Florent - - PowerPoint PPT Presentation

modular instrumentation of interpreters in javascript
SMART_READER_LITE
LIVE PREVIEW

Modular Instrumentation of Interpreters in JavaScript Florent - - PowerPoint PPT Presentation

Modular Instrumentation of Interpreters in JavaScript Florent Marchand de Kerchove, Jacques Noy, Mario Sdholt ASCOLA, Mines Nantes FOAL15 @ Fort Collins, March 16, 2015 The Instrumentation Problem www The web { Web browsers { {


slide-1
SLIDE 1

Modular Instrumentation of Interpreters in JavaScript

Florent Marchand de Kerchove, Jacques Noyé, Mario Südholt ASCOLA, Mines Nantes FOAL’15 @ Fort Collins, March 16, 2015

slide-2
SLIDE 2

The Instrumentation Problem

slide-3
SLIDE 3

www

SpiderMonkey (C++) V8 (C++) JavaScript engines Web browsers{

{

The web {

Other JavaScript interpreters: Rhino (Java) Narcissus (JavaScript)

  • 1
slide-4
SLIDE 4

Narcissus

Metacircular JavaScript interpreter by Mozilla Breeding ground for testing new language features Used by Austin and Flanagan to implement the faceted evaluation analysis

2

slide-5
SLIDE 5

The faceted evaluation analysis

Faceted evaluation is a dynamic information flow analysis.

public private Principal

Each value has two facets. The private value is visible only to a set of principals.

  • A “program counter” keeps track of the current

set of principals in branches.

  • 3
slide-6
SLIDE 6

Faceted evaluation in vivo

4

slide-7
SLIDE 7

Faceted evaluation in vivo

Standalone concern, scattered code Any part of the interpreter liable to change Program counter is threaded through calls Difficult to compose analyses

  • 4
slide-8
SLIDE 8

The Instrumentation Problem

Four requirements for modular instrumentation: Modularity: interpreter and analysis as modules Intercession: can add or alter any part of the interpreter Local state: can thread state local to an analysis Pluggability: can toggle the analysis dynamically

  • 5
slide-9
SLIDE 9

Building an interpreter with modules

slide-10
SLIDE 10

A language of arithmetic expressions

Num Plus eval show

6

slide-11
SLIDE 11

Ingredients

Same client code, different results Dictionary objects as modules Delegation via prototypes Name shadowing Closures Late binding

  • 7
slide-12
SLIDE 12

The num data variant

var num = { new(n) { return {__proto__: this, n} }, eval() { return this.n }} var e1 = num.new(3) e1.eval() //: 3

e1 n new eval num

8

slide-13
SLIDE 13

The num data variant

var num = { new(n) { return {__proto__: this, n} }, eval() { return this.n }} var e1 = num.new(3) e1.eval() //: 3

e1 n new eval num

9

slide-14
SLIDE 14

Adding a data variant

var plus = { new(l, r) { return {__proto__: this, l, r,} }, eval() { return this.l.eval() + this.r.eval() }} var e2 = plus.new(num.new(1), num.new(2)) e2 l r new eval plus

10

slide-15
SLIDE 15

Adding an operation, destructively

num.show = function() { return this.n.toString() } plus.show = function() {…} e1.show() //: “3”

e1 n new eval show num

11

slide-16
SLIDE 16

Adding an operation as a module

var show = base => { var num = {__proto__: base.num, show() { return this.n.toString() }} var plus = {…} return {num, plus} } var s = show({num, plus})

new eval plus show s.plus

12

slide-17
SLIDE 17

Unsafe mixing of data variants

s.plus.new(num.new(1), s.num.new(2)).show() //: TypeError: this.l.show is not a function

new eval num show s.num

13

slide-18
SLIDE 18

A use-case for with

with(show({num, plus})) { plus.new(num.new(1), num.new(2)).show() } Inside with: num show new eval Outside with: num new eval

14

slide-19
SLIDE 19

Instrumented language

Num Plus eval double state

15

slide-20
SLIDE 20

Modifying operations

var double = num_orig => { var num = {__proto__: num_orig, eval() { return super.eval() * 2 }} return {num} } with(double(num)) { plus.new(num.new(1), num.new(2)).eval() } //: 6

num eval: super .eval() * 2 new eval: this.n

16

slide-21
SLIDE 21

Modifying operations

with(double(num)) { with(double(num)) { plus.new(num.new(1), num.new(2)).eval() }} //: 12

num new eval: this.n eval: super.eval() * 2 eval: super.eval() * 2

17

slide-22
SLIDE 22

Threading state

var state = (base, pc = 0) => { var num = {__proto__: base.num, eval() { pc++; return super.eval() }} var plus = {…} var getPC = () => pc return {num, plus, getPC} }

num eval: pc++ new eval

18

slide-23
SLIDE 23

Threading state

with (state({num, plus})) { getPC() //: 0 plus.new(num.new(1), num.new(2)).eval() //: 3 getPC() //: 3 }

num eval: pc++ new eval

19

slide-24
SLIDE 24

All combined

with (state({num,plus})){ with (double(num)) { with (show({num,plus})){ getPC() //: 0 let n = plus.new(num.new(1), num.new(2)) n.eval() //: 6 getPC() //: 3 n.show() //: “1 + 2” }}}

n.l n show eval eval new eval

20

slide-25
SLIDE 25

Wrap-up

slide-26
SLIDE 26

Num Plus eval show state double

A simple modular interpreter

The instrumentation problem: Simple language ingredients: Modularity Intercession Local state Pluggability

  • Dictionaries as modules

Closures

  • Delegation

Late binding

  • 21