1 Javari: Adding Reference Immutability to Java Matthew Tschantz & Michael Ernst (MIT) OOPSLA’05...

Post on 08-Jan-2018

215 views 0 download

description

3 Protecting method arguments  A library routine does not modify its arguments: static void print(readonly Date d) {... // Cannot modify d } String toString() readonly {... // Cannot modify the receiver }

Transcript of 1 Javari: Adding Reference Immutability to Java Matthew Tschantz & Michael Ernst (MIT) OOPSLA’05...

1

Javari: Adding Reference Immutability to Java

Matthew Tschantz & Michael Ernst (MIT)

OOPSLA’05

Presented by Tali Shragai

2

Extension to Javari2004 [Birka] Javari: Java + (C++ const) + more…

Two new keywords: readonly, mutable OOPSLA’04: Initial Javari implementation Experience: 160,000 code lines

Better documentation Error detection and prevention Compatible with Java & existing JVMs

But: No Generics, serialization, reflection Confuses mutability & assignability

Javari 05: More keywords: assignable, romaybe Genericity, reflection, serialization Most important (?): mutability vs. assignability

3

Protecting method arguments A library routine does not modify its arguments:

static void print(readonly Date d) { ... // Cannot modify d }

String toString() readonly { ... // Cannot modify the receiver}

4

Protecting abstract state: observer methods

class Class { private Object[] signers; Object[] getSigners() { return signers; // JDK 1.1 security hole }}

myClass.getSigners()[0] = “Sun”;

5

Protecting abstract state: observer methods (revised)

class Class { private Object[] signers; readonly Object[] getSigners() { return signers; // Fixes JDK 1.1 bug }}

myClass.getSigners()[0] = “Sun”; // Error

6

Reference vs. Object immutability Reference immutability

Object modification: Readonly reference: no! Other reference: yes.

Deep: cannot modify transitively reachable state Static type checking!

Dynamic checking for mutability downcasts Object immutability:

write protect from any referenceGraph temp = new Graph();// construct the graphreadonly Graph g = temp;temp = null;// further usage through read only reference…

Javari: object immutability emulated by reference immutability

7

Related work Old trick: pass/return by value

pain for large objects C++: const, const_cast

Unsound (unchecked casts) Non-transitive! No immutability-based parameterization Leads to code duplication (const methods) No support for multidimensional arrays?

JAC [Kniesel 2001]: Implementation requires rewriting the code Unsound (subtyping, arrays) Return type mutability equals receiver's

8

Protection methods

Level Java C++ JavariLevel 1

assignmentfinal Foo a const Foo *a final Foo a

Level 2 mutability

Foo const *a readonly Foo a

Level 3 const Foo const *a final readonly Foo a

… Level ∞ Transitive protection!

9

Yield protection

Level Java C++ JavariLevel 1 mutable Foo *a assignable Foo a

Level 2 mutable Foo a

10

Readonly

readonly Date rd = new Date();rd.year = 2005; // Compile-time errorrd.incrementDay(); // Compile-time error

rd = new Foo(); // OK

11

Mutability vs. Assignability

final Date fd = null;readonly Date rd = null; fd = new Date(); // Error: finalrd = null; // OKDate d1 = fd; // OKDate d2 = rd; // Error: wrong type

Mutability Assignabilitypart of the type not part of the typemay abstract state mutate?

can be lvalue in assignment?

readonly final

12

Type systemEvery type (mutable) T has readonly T as a supertype

readonly Object

readonly Date

/*mutable*/ Object

/*mutable*/ Date

13

Immutable classes

A class/interface can be declared immutable using readonly in its class declaration. Non-static fields & methods readonly (default) Reference to its objects implicitly read-only Subclasses must be immutable too! readonly class String{…}/*readonly*/ String s1 = new String();readonly String s2 = new String();

S1 = s2; // OKS2 = s1; // OK

14

Assignability May a reference be assigned to?class Appointment {final Date time; // Same as in Javaassignable int room;

}

Appointment appoint;

appoint.time = new Date(); // Errorappoint.room = 250; // OK

15

Assignability modifiers

final: May never be assigned assignable: May always be assigned (default

for locals)

this-assignable: May be assigned through a mutable reference May not be assigned through a readonly reference Only applicable to fields (the default) The assignability depends on the mutability of the

enclosing object: “this”

16

Assignability example

class Bicycle { final int id; // Never changes assignable int hashCode; // A cache /*this-assign*/ int gear; // Abstract state}/*mutable*/ Bicycle b;readonly Bicycle rb;

17

finalclass Bicycle { final int id; // Never changes assignable int hashCode; // A cache /*this-assign*/ int gear; // Abstract

state}/*mutable*/ Bicycle b;readonly Bicycle rb;b.id = 5; // Errorrb.id = 5;// Error Resolved assignability of ref.f

Declared assignability of f

Resolved mutability of ref

mutable readonlyfinal unassignable unassignable

18

assignableclass Bicycle { final int id; // Never changes assignable int hashCode; // A cache /*this-assign*/ int gear; // Abstract state}/*mutable*/ Bicycle b;readonly Bicycle rb;b.hashCode = 5; // OKrb.hashCode = 5; // OK

Resolved assignability of ref.fDeclared assignability of f

Resolved mutability of refmutable readonly

final unassignable unassignableassignable assignable assignable

19

this-assignableclass Bicycle { final int id; // Never changes assignable int hashCode; // A cache /*this-assign*/ int gear; // Abstract state}/*mutable*/ Bicycle b;readonly Bicycle rb; b.gear = 5; // OK rb.gear = 5; // Error

Resolved assignability of ref.fDeclared assignability of f

Resolved mutability of refmutable readonly

final unassignable unassignableassignable assignable assignablethis-assignable assignable unassignable

20

Mutability

May the object’s transitive abstract state be modified?

class Date { /*this-assignable*/ int year;}

/*mutable*/ Date d;readonly Date rd;d.year = 2005; // OKrd.year = 2005; // Error

21

Mutability modifiers

readonly: May never be mutated

mutable: May always be mutated, the default for locals

this-mutable: May be mutated through mutable reference May not be mutated through readonly references Only applicable to fields (the default) The mutability depends on the mutability of the

enclosing class: “this”

22

Mutability example

class Account { readonly Customer owner; mutable RequestLog requests; /*this-mut*/ Balance bal;}/*mutable*/ Account a;readonly Account ra;

23

readonly

class Account { readonly Customer owner; mutable RequestLog requests; /*this-mut*/ Balance bal;}/*mutable*/ Account a;readonly Account ra;a.owner.setName(“Bob”); // Errorra.owner.setName(“Bob”); // Error

Mutability of ref.fDeclared mutability of f

Resolved mutability of ref

mutable readonlyreadonly readonly readonly

24

mutable

class Account { readonly Customer owner; mutable RequestLog requests; /*this-mut*/ Balance bal;}/*mutable*/ Account a;readonly Account ra;a.requests.add(“checkBalance”); // OKra.requests.add(“checkBalance”); // OK

Mutability of ref.fDeclared mutability of f

Resolved mutability of refmutable readonly

readonly readonly readonlymutable mutable mutable

mutable excludes requests from the

abstract state of the object

25

this-mutable

class Account { readonly Customer owner; mutable RequestLog requests; /*this-mut*/ Balance bal;}/*mutable*/ Account a;readonly Account ra;a.balance.withdraw(1000); // OK

Declared mutability of f

Resolved mutability of refmutable readonly

readonly readonly readonlymutable mutable mutablethis-mutable mutable ?

26

this-mutable

class Account { readonly Customer owner; mutable RequestLog requests; /*this-mut*/ Balance bal;}/*mutable*/ Account a;readonly Account ra;a.balance.withdraw(1000); // OKra.balance.withdraw(1000); // Error

Mutability of ref.fDeclared mutability of f

Resolved mutability of refmutable readonly

readonly readonly readonlymutable mutable mutablethis-mutable mutable readonly?

27

this-mutable fields reached through a readonly reference

readonly, right?

28

this-mutable fields reached through a readonly reference

readonly, right? NO, would result in type loophole allowing one to

convert a readonly reference to a mutable reference:

29

this-mutable fields reached through a readonly reference

class Student { assignable /*this-mut*/ GradeReport grades;}/*mutable*/ Student s = new Student();readonly Student rs = s;readonly GradeReport rg;/*mutable*/ GradeReport g;

rs.grades = rg; //readonly assigned to this-mutableg = s.grades; //this-mutable assigned to mutable

Downcast

rs

s

gradesNon-readonly

Readonly

Readonly??assignable

30

this-mutable fields reached through a readonly reference

Solution: Disallow readonly references to be assigned to a this-mutable field

this-mutable fields through readonly reference are: readonly as rvalue (may only be assigned to a

readonly reference) mutable as lvalue (may only be assigned with

mutable reference)

Notation: <? readonly GradeReport>

31

Uses of parametric classes

Local variable declarations: /*mut*/ List</*mut*/ Date> a; // add, mutate/*mut*/ List<readonly Date> b; // addreadonly List</*mut*/ Date> c; // mutatereadonly List<readonly Date> d; // neither

32

Inside parametric classes

Type arguments include mutability Library cannot write: class C<T> { mutable T x; }

C<readonly Date> y; // Conflicting types

Library can force a mutable type using a bound:

;

class C<T extends mutable Object> { T x; }

33

this-mutable type argumentsclass Device { /*this-mut*/ List</*this-mut*/ Driver> drivers;}

/*mutable*/ Device d;readonly Device rd;

d.drivers has type /*mut*/ List</*mut*/ Driver>/*mut*/ List</*mut*/Driver> dl = d.drivers; // OK

34

this-mutable type argumentsclass Device { /*this-mut*/ List</*this-mut*/ Driver> drivers;}

/*mutable*/ Device d;readonly Device rd;

rd.drivers has type ? readonly List<? readonly Driver>

readonly List<? readonly Driver> x = rd. drivers; //OKreadonly List<readonly Driver> y = rd. drivers; //Errorreadonly List</*mutable*/Driver> z = rd. drivers; //Error

35

Serialization

Add a readonly-ness bit to the serialized form.

De-serialization done using 2 versions of ObjectInputStream.readObject: readObjectReadonly – returns a read-only

object, without checking. readObject – returns a mutable objects, but

throws an exception if the readonly-ness bit is set.

36

Reducing code duplication In Java, each class definition defines exactly one type. In Javari,

by contrast, a class C actually denotes 2 type: C and readonly C.

romaybe keyword templates over methodsclass Conference {

/*this-mutable*/ Date d;

We wish to write two (overloaded) methods:

readonly Date getDate() readonly { return d;} /*mutable*/ Date getDate() /*mutable*/{ return d;}

Syntactic sugar:

romaybe Date getDate() romaybe { return d;}}

37

Downcasts

Javari guarantees that a readonly reference cannot be used, directly or indirectly, to modify its referent.

Down-casting a reference from readonly to mutable triggers run-time checks, which disallow any modifications done through the casted reference.

38

Downcast example

class Foo{Date d;void setD() /*mutable*/{

d = new Date();}

}Foo f1 = new Foo();

readonly Foo rf = f1;Foo f2 = (mutable)rf;

f1.d = new Date(); // OKf2.d = new Date(); // run-time errorf1.setD(); // OKF2.setD(); // run-time error

39

Contributions

Transitive reference immutability Distinguishes assignability and mutability Formal model (not shown here) Type system for full Java 5.0 including

parametric polymorphism, reflection, and serialization

Templates to reduce code duplication Interoperable with Java Still to come: type inference…

40

The End!

Thank you for listening…