modular instrumentation of interpreters in javascript
play

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 { {


  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

  2. The Instrumentation Problem

  3. www The web { Web browsers { { JavaScript engines SpiderMonkey (C++) V8 (C++) Other JavaScript interpreters: • Rhino (Java) • Narcissus (JavaScript) 1

  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

  5. The faceted evaluation analysis Faceted evaluation is a dynamic information flow analysis. • Each value has two facets. • The private value is visible only to a set of principals. Principal private public • A “program counter” keeps track of the current set of principals in branches. 3

  6. Faceted evaluation in vivo 4

  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

  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

  9. Building an interpreter with modules

  10. A language of arithmetic expressions Num Plus eval show 6

  11. Ingredients • Dictionary objects as modules • Delegation via prototypes • Name shadowing • Closures • Late binding Same client code, different results 7

  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 num eval 8

  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 num eval 9

  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 new plus r eval 10

  15. Adding an operation, destructively num.show = function() { return this.n.toString() } plus.show = function() {…} e1.show() //: “3” e1 n new num eval show 11

  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}) s.plus show new plus eval 12

  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 s.num show new num eval 13

  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

  19. Instrumented language Num Plus state eval double 15

  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

  21. Modifying operations with(double(num)) { with(double(num)) { plus.new(num.new(1), num.new(2)).eval() }} //: 12 num eval: super.eval() * 2 eval: super.eval() * 2 new eval: this.n 17

  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

  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

  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

  25. Wrap-up

  26. A simple modular interpreter The instrumentation problem: • Modularity Num Plus double state • Intercession eval • Local state show • Pluggability Simple language ingredients: • Delegation • Dictionaries as modules • Late binding • Closures 21

Recommend


More recommend