A Principled Intermediate Language for JavaScript Verification Daiva Naudˇ zi¯ unien˙ e Imperial College London Resource Reasoning Meeting 1/40
The Team Thomas Philippa Gareth Smith Wood Gardner Petar Jos´ e Fragoso Maksimovi´ c Santos 2/40
Running Example: Where is Alice? var Person = function (x) { this .name = x; } Person.prototype.sayHi = function () { return ”Hi! I am ” + this .name; } var alice = new Person(”Alice”); alice .sayHi(); 3/40
Where is Alice? var Person = function (x) { this .name = x; } Person.prototype.sayHi = function () { return “Hi! I am ” + this .name; l g } Person: var alice = new Person(”Alice”); x person alice.sayHi(); @code: “PProc” 1. Evaluate the function literal @scope: [ l g ] and assign to var Person @proto: l fp x proto 2. Evaluate the function literal, prototype: @proto: l op and assign to “Person.prototype.sayHi” 3. Create new object 4. Evaluate function body with this being an object created in Step 3 5. Assign new object to var alice 6. Call alice.sayHi() 4/40
Where is Alice? var Person = function (x) { this .name = x; l g } Person.prototype.sayHi = function () { Person: return “Hi! I am ” + this .name; x person } @code: “PProc” var alice = new Person(”Alice”); @scope: [ l g ] alice.sayHi(); x proto @proto: l fp @proto: l op prototype: 1. Evaluate the function literal and assign to var Person sayHi: 2. Evaluate the function literal, and assign to “Person.prototype.sayHi” 3. Create new object 4. Evaluate function body with this being an object created in Step 3 5. Assign new object to var alice 6. Call alice.sayHi() 5/40
Where is Alice? var Person = function (x) { this .name = x; l g } Person.prototype.sayHi = function () { Person: return “Hi! I am ” + this .name; x person x this } @code: “PProc” var alice = new Person(”Alice”); @proto: @scope: [ l g ] alice.sayHi(); x proto @proto: l fp @proto: l op prototype: 1. Evaluate the function literal and assign to var Person sayHi: 2. Evaluate the function literal, and assign to “Person.prototype.sayHi” 3. Create new object 4. Evaluate function body with this being an object created in Step 3 5. Assign new object to var alice 6. Call alice.sayHi() 6/40
Where is Alice? var Person = function (x) { this .name = x; } l g Person.prototype.sayHi = function () { Person: return “Hi! I am ” + this .name; x this x person } @proto: var alice = new Person(”Alice”); @code: “PProc” name: “Alice” @scope: [ l g ] alice.sayHi(); x proto @proto: l fp @proto: l op 1. Evaluate the function literal and assign to var Person prototype: 2. Evaluate the function literal, sayHi: and assign to “Person.prototype.sayHi” 3. Create new object 4. Evaluate function body with this being an object created in Step 3 5. Assign new object to var alice 6. Call alice.sayHi() 7/40
Where is Alice? var Person = function (x) { this .name = x; l g } alice: Person.prototype.sayHi = function () { Person: return “Hi! I am ” + this .name; x this x person } @proto: var alice = new Person(”Alice”); @code: “PProc” name: “Alice” @scope: [ l g ] alice.sayHi(); x proto @proto: l fp @proto: l op 1. Evaluate the function literal and assign to var Person prototype: 2. Evaluate the function literal, sayHi: and assign to “Person.prototype.sayHi” 3. Create new object 4. Evaluate function body with this being an object created in Step 3 5. Assign new object to var alice 6. Call alice.sayHi() 8/40
Where is Alice? var Person = function (x) { this .name = x; l g } alice: Person.prototype.sayHi = function () { Person: return “Hi! I am ” + this .name; x this x person } @proto: @code: “PProc” var alice = new Person(”Alice”); name: “Alice” alice.sayHi(); @scope: [ l g ] x proto @proto: l fp @proto: l op 1. Evaluate the function literal and assign to var Person prototype: 2. Evaluate the function literal, sayHi: and assign to “Person.prototype.sayHi” 3. Create new object 4. Evaluate function body with this being an object created in Step 3 5. Assign new object to var alice 6. Call alice.sayHi() 9/40
Running Wrong Example: We Cannot Find Alice var Person = function (x) { this .name = x; } Person.prototype.sayHi = function () { return ”Hi! I am ” + this .name; } var alice = Person(”Alice”); alice .sayHi(); 10/40
We cannot find Alice var Person = function (x) { this .name = x; } l g Person.prototype.sayHi = function () { Person: return “Hi! I am ” + this .name; x this x person } @proto: var alice = Person(”Alice”); @code: “PProc” name: “Alice” @scope: [ l g ] alice.sayHi(); x proto @proto: l fp @proto: l op 1. Evaluate the function literal and assign to var Person prototype: 2. Evaluate the function literal, sayHi: and assign to “Person.prototype.sayHi” 3. Create new object 4. Evaluate function body with this being undefined 5. Assign return value to var alice 6. Call alice.sayHi() 11/40
Verifying JavaScript Programs ‘Towards a Program Logic for JavaScript’, POPL’12, Gardner, Maffeis, and Smith. 12/40
Overall Project JSVerify: A verification tool for JavaScript programs based on an intermediate language JSIL � JS Logic ES5 Strict � JSVerify � JSIL Logic JSIL 13/40
From ES5 Strict to JSIL - Our choices We implemented, tested, and proved correct a ES5 Strict principled translation from ES5 Strict to JSIL. JSIL was specifically designed as a simple verification language for Javascript: Principled ◮ small language; Translation ◮ simple semantics; ◮ similar memory model to JavaScript’s memory model. JSIL 14/40
JSIL Simple goto language: � C ∈ Cmd x := E | skip | goto l | goto [ E ] l 1 , l 2 l denotes a label and E is an expression with no side effects. 15/40
JSIL Procedure calls: � C ∈ Cmd x := E | skip | goto l | goto [ E ] l 1 , l 2 | x := p ( E , . . . , E ) p ∈ { E , eval , built-in-PId } 16/40
JSIL JavaScript heap commands: � C ∈ Cmd x := E | skip | goto l | goto [ E ] l 1 , l 2 | x := p ( E , . . . , E ) | x := new () | x := hasField ( E , E ) | x := [ E , E ] | [ E , E ] := E | x := delete ( E , E ) 17/40
JSIL Prototype-based inheritance: � C ∈ Cmd x := E | skip | goto l | goto [ E ] l 1 , l 2 | x := p ( E , . . . , E ) | x := new () | x := hasField ( E , E ) | x := [ E , E ] | [ E , E ] := E | x := delete ( E , E ) | x := protoField ( E , E ) | x := protoObj ( E , E ) 18/40
JSIL � C ∈ Cmd x := E | skip | goto l | goto [ E ] l 1 , l 2 | x := p ( E , . . . , E ) | x := new () | x := hasField ( E , E ) | x := [ E , E ] | [ E , E ] := E | x := delete ( E , E ) | x := protoField ( E , E ) | x := protoObj ( E , E ) � proc PId ( x 1 , . . . , x n ) { Procedure 0: C 0 1: C 1 . . . m: C m } 19/40
JSIL Logic versus JS Logic 20/40
However... The complexity of JavaScript does not disappear. It has moved to the code generated by the translation 21/40
Back to Example: Where is Alice? var Person = function (x) { this .name = x; } var alice = new Person(”Alice”); 22/40
Translating: Where is Alice in JSIL? ◮ The translation generates a top level procedure for each function literal. ◮ The translation generates a special procedure main for the global code. ◮ No nesting of procedures. JavaScript Code JSIL Code var Person = function (x) { ... } proc PProc ( x sc , x this , x ) { ... } Whole Program proc main () { ... } 23/40
Translating: Where is Alice in JSIL? JSIL Code x proto := new () JavaScript Code [ x proto , @ proto ] := l op x person := new () var Person = function (x) { [ x person , @ code ] := “ PProc ” this .name = x; [ x person , @ scope ] := [ l g ] } [ x person , @ proto ] := l fp var alice = new Person(”Alice”); [ x person , “ prototype ”] := x proto l g 1. Evaluate the function literal 2. Assign function object to var Person 3. Create new object x person 4. Evaluate function body with @code: “PProc” this being an object created in Step 3 @scope: [ l g ] 5. Assign new object to var alice @proto: l fp x proto prototype: @proto: l op 24/40
Translating: Where is Alice in JSIL? JavaScript Code JSIL Code var Person = function (x) { [ l g , “ Person ”] := x person this .name = x; } l g var alice = new Person(”Alice”); Person: x person 1. Evaluate the function literal 2. Assign function object to var Person @code: “PProc” @scope: [ l g ] 3. Create new object 4. Evaluate function body with @proto: l fp x proto this being an object created in Step 3 prototype: @proto: l op 5. Assign new object to var Alice 25/40
Translating: Where is Alice in JSIL? JavaScript Code JSIL Code x this := new () var Person = function (x) { [ x this , @ proto ] := x proto this .name = x; } l g var alice = new Person(”Alice”); Person: x person 1. Evaluate the function literal x this 2. Assign function object to var Person @code: “PProc” 3. Create new object @proto: @scope: [ l g ] 4. Evaluate function body with @proto: l fp x proto this being an object created in Step 3 prototype: @proto: l op 5. Assign new object to var alice 26/40
Recommend
More recommend