Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

TreatJS: Higher-Order Contracts for JavaScript

Dagstuhl Seminar on Scripting Languages and Frameworks: Analysis and Verification
Wadern, Germany, June 2014

  • Login to see the comments

  • Be the first to like this

TreatJS: Higher-Order Contracts for JavaScript

  1. 1. TreatJS Higher-Order Contracts for JavaScript Matthias Keil, Peter Thiemann Institute for Computer Science University of Freiburg Freiburg, Germany June 30, 2014, Dagstuhl Seminar on Scripting Languages and Frameworks: Analysis and Verification
  2. 2. Introduction TreatJS Language embedded contract system for JavaScript Enforced by run-time monitoring Inspiration similar to Contracts.js [Disney] Contract Specifies the interface of a software component Obligations - Benefits Matthias Keil, Peter Thiemann TreatJS June 30, 2014 2 / 14
  3. 3. Features Standard abstractions for higher-order-contracts (base, function, and object contracts) [Findler,Felleisen’02] Support for boolean combinations (and, or, not contracts) as building blocks for intersection, union, and implication Contract constructors generalize dependent contracts Non-interference for contract execution Matthias Keil, Peter Thiemann TreatJS June 30, 2014 3 / 14
  4. 4. Base Contract [Findler,Felleisen’02] Base Contracts are built from predicates Specified by a plain JavaScript function 1 function typeOfNumber (arg) { 2 return (typeof arg) === ’number’; 3 }; 4 var IsNumber = BaseContract(typeOfNumber, ’IsNumber’); Matthias Keil, Peter Thiemann TreatJS June 30, 2014 4 / 14
  5. 5. Base Contract [Findler,Felleisen’02] Base Contracts are built from predicates Specified by a plain JavaScript function 1 function typeOfNumber (arg) { 2 return (typeof arg) === ’number’; 3 }; 4 var IsNumber = BaseContract(typeOfNumber, ’IsNumber’); 5 assert(1, IsNumber); Value v fulfills BaseContract (B) iff: B(v) = true Matthias Keil, Peter Thiemann TreatJS June 30, 2014 4 / 14
  6. 6. Base Contract [Findler,Felleisen’02] Base Contracts are predicates Specified by a plain JavaScript function 1 function typeOfNumber (arg) { 2 return (typeof arg) === ’number’; 3 }; 4 var IsNumber = BaseContract(typeOfNumber, ’IsNumber’); 5 assert(’a’, IsNumber); Blame the Value Value v gets blamed for contract B iff: B(v) = false Matthias Keil, Peter Thiemann TreatJS June 30, 2014 4 / 14
  7. 7. Function Contract [Findler,Felleisen’02] 1 // Number × Number → Number 2 function addUnchecked(x, y) { 3 return (x + y); 4 } Matthias Keil, Peter Thiemann TreatJS June 30, 2014 5 / 14
  8. 8. Function Contract [Findler,Felleisen’02] 1 // Number × Number → Number 2 function addUnchecked(x, y) { 3 return (x + y); 4 } 5 var addChecked = assert(addUnchecked, 6 FunctionContract([IsNumber, IsNumber], IsNumber)); Matthias Keil, Peter Thiemann TreatJS June 30, 2014 5 / 14
  9. 9. Function Contract [Findler,Felleisen’02] 1 // Number × Number → Number 2 function addUnchecked(x, y) { 3 return (x + y); 4 } 5 addChecked(1, 1); x is an acceptable argument for contract C → C iff: (x fulfills C) Function f fulfills contract C → C at argument x iff: (x fulfills C) → (f (x) fulfills C ) Matthias Keil, Peter Thiemann TreatJS June 30, 2014 6 / 14
  10. 10. Function Contract [Findler,Felleisen’02] 1 // Number × Number → Number 2 function addUnchecked(x, y) { 3 return (x + y); 4 } 5 addChecked(’a’, ’a’); Blame the Argument Argument x gets blamed for C → C iff: ¬ (x is an acceptable argument for contract C → C ) iff: ¬ (x fulfills C) Matthias Keil, Peter Thiemann TreatJS June 30, 2014 6 / 14
  11. 11. Function Contract [Findler,Felleisen’02] 1 // Number × Number → Number 2 function addUnchecked(x, y) { 3 return (x0 y0) ? (x + y) : ’Error’; 4 } 5 addChecked(0, 1); Blame the Fucntion Function f gets blamed for C → C at argument x iff: ¬ (Function f fulfills contract C → C at argument x) iff: (x fulfills C) ∧ ¬ (f (x) fulfills C ) Matthias Keil, Peter Thiemann TreatJS June 30, 2014 6 / 14
  12. 12. TreatJS New! Matthias Keil, Peter Thiemann TreatJS June 30, 2014 7 / 14
  13. 13. Intersection Contract 1 // Number × Number → Number 2 function addUnchecked(x, y) { 3 return (x + y); 4 } 5 addChecked(’a’, ’a’); Matthias Keil, Peter Thiemann TreatJS June 30, 2014 8 / 14
  14. 14. Intersection Contract 1 // (Number × Number → Number) ∩ (String × String → String) 2 function addUnchecked(x, y) { 3 return (x + y); 4 } Matthias Keil, Peter Thiemann TreatJS June 30, 2014 8 / 14
  15. 15. Intersection Contract 1 // (Number × Number → Number) ∩ (String × String → String) 2 function addUnchecked(x, y) { 3 return (x + y); 4 } 5 var addChecked = assert(addUnchecked, Intersection( 6 FunctionContract([IsNumber, IsNumber], IsNumber) 7 FunctionContract([IsString, IsString], IsString)); Matthias Keil, Peter Thiemann TreatJS June 30, 2014 8 / 14
  16. 16. Intersection Contract 1 // (Number × Number → Number) ∩ (String × String → String) 2 function addUnchecked(x, y) { 3 return (x + y); 4 } 5 addChecked(’a’, ’a’); x is an acceptable argument for contract C ∩ C iff: (x is acceptable arg. for C) ∨ (x is acceptable arg. for C ) Function f fulfills contract C ∩ C at argument x iff: (f fulfills C at x) ∧ (f fulfills C at x) Matthias Keil, Peter Thiemann TreatJS June 30, 2014 8 / 14
  17. 17. Intersection Contract 1 // (Number × Number → Number) ∩ (String × String → String) 2 function addUnchecked(x, y) { 3 return (x + y); 4 } 5 addChecked(true, true); Blame the Argument Argument x gets blamed for C ∩ C iff: Matthias Keil, Peter Thiemann TreatJS June 30, 2014 8 / 14
  18. 18. Intersection Contract 1 // (Number × Number → Number) ∩ (String × String → String) 2 function addUnchecked(x, y) { 3 return (x + y); 4 } 5 addChecked(true, true); Blame the Argument Argument x gets blamed for C ∩ C iff: ¬ (x is an acceptable argument for contract C ∩ C ) Matthias Keil, Peter Thiemann TreatJS June 30, 2014 8 / 14
  19. 19. Intersection Contract 1 // (Number × Number → Number) ∩ (String × String → String) 2 function addUnchecked(x, y) { 3 return (x + y); 4 } 5 addChecked(true, true); Blame the Argument Argument x gets blamed for C ∩ C iff: ¬ (x is an acceptable argument for contract C ∩ C ) ¬ ((x is acc. arg. for C) ∨ (x is acc. arg. for C )) Matthias Keil, Peter Thiemann TreatJS June 30, 2014 8 / 14
  20. 20. Intersection Contract 1 // (Number × Number → Number) ∩ (String × String → String) 2 function addUnchecked(x, y) { 3 return (x + y); 4 } 5 addChecked(true, true); Blame the Argument Argument x gets blamed for C ∩ C iff: ¬ (x is an acceptable argument for contract C ∩ C ) ¬ ((x is acc. arg. for C) ∨ (x is acc. arg. for C )) ¬(x is acc. arg. for C) ∧ ¬(x is acc. arg. for C ) Matthias Keil, Peter Thiemann TreatJS June 30, 2014 8 / 14
  21. 21. Intersection Contract 1 // (Number × Number → Number) ∩ (String × String → String) 2 function addUnchecked(x, y) { 3 return (x + y); 4 } 5 addChecked(true, true); Blame the Argument Argument x gets blamed for C ∩ C iff: ¬ (x is an acceptable argument for contract C ∩ C ) ¬ ((x is acc. arg. for C) ∨ (x is acc. arg. for C )) ¬(x is acc. arg. for C) ∧ ¬(x is acc. arg. for C ) (x gets blamed for C) ∧ (x gets blamed for C) Matthias Keil, Peter Thiemann TreatJS June 30, 2014 8 / 14
  22. 22. Intersection Contract 1 // (Number × Number → Number) ∩ (String × String → String) 2 function addUnchecked(x, y) { 3 return (x0 y0) ? (x + y) : ’Error’; 4 } 5 addChecked(0, 1); Blame the Function Function f gets blamed for C ∩ C at argument x iff: (f gets blamed for C at x) ∨ (f gets blamed for C at x) Matthias Keil, Peter Thiemann TreatJS June 30, 2014 8 / 14
  23. 23. Union Contract 1 // (Number × Number → Number) ∪ (Number × Number → String) 2 function addUnchecked(x, y) { 3 return (x0 y0) ? (x + y) : ’Error’; 4 } Matthias Keil, Peter Thiemann TreatJS June 30, 2014 9 / 14
  24. 24. Union Contract 1 // (Number × Number → Number) ∪ (Number × Number → String) 2 function addUnchecked(x, y) { 3 return (x0 y0) ? (x + y) : ’Error’; 4 } 5 var addChecked = assert(addUnchecked, Union( 6 FunctionContract([IsNumber, IsNumber], IsNumber) 7 FunctionContract([IsNumber, IsNumber], IsString)); Matthias Keil, Peter Thiemann TreatJS June 30, 2014 9 / 14
  25. 25. Union Contract 1 // (Number × Number → Number) ∪ (Number × Number → String) 2 function addUnchecked(x, y) { 3 return (x0 y0) ? (x + y) : ’Error’; 4 } 5 addChecked(0, 1); Argument x is an acceptable argument for contract C ∪ C iff: (x is acceptable arg. for C) ∧ (x is acceptable arg. for C ) Function f fulfills contract C ∪ C at argument x iff: (f fulfills C at x) ∨ (f fulfills C at x) Matthias Keil, Peter Thiemann TreatJS June 30, 2014 9 / 14
  26. 26. Union Contract 1 // (Number × Number → Number) ∪ (Number × Number → String) 2 function addUnchecked(x, y) { 3 return (x0 y0) ? (x + y) : ’Error’; 4 } 5 addChecked(’a’, ’a’); Blame the Argument Argument x gets blamed for C ∪ C iff: (x gets blamed for C) ∨ (x gets blamed for C) Matthias Keil, Peter Thiemann TreatJS June 30, 2014 9 / 14
  27. 27. Union Contract 1 // (Number × Number → Number) ∪ (Number × Number → String) 2 function addUnchecked(x, y) { 3 return (x0 y0) ? (x + y) : undefined; 4 } 5 addChecked(0, 1); Blame the Fucntion Function f gets blamed for C ∪ C at argument x iff: (f gets blamed for C at x) ∧ (f gets blamed for C ) at x Matthias Keil, Peter Thiemann TreatJS June 30, 2014 9 / 14
  28. 28. Non-Interference No syntactic restrictions on predicates Problem: contract may interfere with program execution Solution: Predicate evaluation takes place in a sandbox 1 function typeOfNumber (arg) { 2 type = (typeof arg); Access forbidden 3 return type === ’number’; 4 }; 5 var FaultyIsNumber = 6 BaseContract(typeOfNumber, ’FaultyIsNumber’); Matthias Keil, Peter Thiemann TreatJS June 30, 2014 10 / 14
  29. 29. Non-Interference No syntactic restrictions on predicates Problem: contract may interfere with program execution Solution: Predicate evaluation takes place in a sandbox 1 var IsArray = BaseContract(function (arg) { 2 return (arg instanceof Array); Access forbidden 3 }); Matthias Keil, Peter Thiemann TreatJS June 30, 2014 10 / 14
  30. 30. Non-Interference No syntactic restrictions on predicates Problem: contract may interfere with program execution Solution: Predicate evaluation takes place in a sandbox 1 var IsArray = BaseContract(function (arg) { 2 return (arg instanceof InsideArray); 3 }); 4 var IsArrayComplete = With({InsideArray:Array}, IsArray); Matthias Keil, Peter Thiemann TreatJS June 30, 2014 11 / 14
  31. 31. Contract Constructor 1 // T × T → T 2 function addUnchecked(x, y) { 3 return (x + y); 4 } Matthias Keil, Peter Thiemann TreatJS June 30, 2014 12 / 14
  32. 32. Contract Constructor 1 // T × T → T 2 function addUnchecked(x, y) { 3 return (x + y); 4 } 5 var addChecked = assert(addUnchecked, 6 FunctionContract([CheckType, CheckType], CheckType)): 7 var CheckType = BaseContract(function (arg) { 8 // to be completed 9 }); Matthias Keil, Peter Thiemann TreatJS June 30, 2014 12 / 14
  33. 33. Contract Constructor Constructor gets evaluated in a sandbox, like a predicate Returns a contract No further sandboxing for predicates 1 var ctor = Constructor(function() { 2 var type = undefined; 3 var CheckType = BaseContract(function (arg) { 4 type = type || (typeof arg); 5 return type === (typeof arg); 6 }); 7 return FunctionContract([CheckType, CheckType], CheckType): 8 }, ’SameType’); Matthias Keil, Peter Thiemann TreatJS June 30, 2014 12 / 14
  34. 34. Dependent Contract 1 var SameTypeCtor = Constructor(function(arg) { 2 var type = (typeof arg); 3 return BaseContract(function (arg) { 4 return (typeof arg) === type); 5 }); 6 }); Matthias Keil, Peter Thiemann TreatJS June 30, 2014 13 / 14
  35. 35. Dependent Contract 1 var SameTypeCtor = Constructor(function(arg) { 2 var type = (typeof arg); 3 return BaseContract(function (arg) { 4 return (typeof arg) === type); 5 }); 6 }); 7 var addChecked = assert(addUnchecked, 8 DependentContract(SameTypeCtor)); Matthias Keil, Peter Thiemann TreatJS June 30, 2014 13 / 14
  36. 36. Conclusion TreatJS: Language embedded, higher-order contract system for JavaScript Support for intersection and union contracts Systematic blame calculation Composable sandboxing that guarantees non-interference Contract constructors with local scope Matthias Keil, Peter Thiemann TreatJS June 30, 2014 14 / 14

×