Java$as$a$Platform - GOTO Conferencegotocon.com/dl/goto-cph-2011/slides/OlaBini_JavaAsA... ·...

55
Ola Bini computational metalinguist [email protected] http://olabini.com/blog Java as a Platform torsdag den 12 maj 2011

Transcript of Java$as$a$Platform - GOTO Conferencegotocon.com/dl/goto-cph-2011/slides/OlaBini_JavaAsA... ·...

Page 1: Java$as$a$Platform - GOTO Conferencegotocon.com/dl/goto-cph-2011/slides/OlaBini_JavaAsA... · 2011-05-12 · Kawa Lili Lisp LL Mapyrus MetaJ Mini NetLogo Nice Obol PERCobol PLAN Pnuts

Ola  Binicomputational  metalinguist  

[email protected]://olabini.com/blog

Java  as  a  Platform

torsdag den 12 maj 2011

Page 2: Java$as$a$Platform - GOTO Conferencegotocon.com/dl/goto-cph-2011/slides/OlaBini_JavaAsA... · 2011-05-12 · Kawa Lili Lisp LL Mapyrus MetaJ Mini NetLogo Nice Obol PERCobol PLAN Pnuts

From  Sweden  to  Chicago  through  ThoughtWorks

Language  geek  at  ThoughtWorks

JRuby  core  developer,  Ioke  and  Seph  creator

Member  of  the  JSR  292  EG

Your  host

torsdag den 12 maj 2011

Page 3: Java$as$a$Platform - GOTO Conferencegotocon.com/dl/goto-cph-2011/slides/OlaBini_JavaAsA... · 2011-05-12 · Kawa Lili Lisp LL Mapyrus MetaJ Mini NetLogo Nice Obol PERCobol PLAN Pnuts

Platform

torsdag den 12 maj 2011

Page 4: Java$as$a$Platform - GOTO Conferencegotocon.com/dl/goto-cph-2011/slides/OlaBini_JavaAsA... · 2011-05-12 · Kawa Lili Lisp LL Mapyrus MetaJ Mini NetLogo Nice Obol PERCobol PLAN Pnuts

What  you  get

torsdag den 12 maj 2011

Page 5: Java$as$a$Platform - GOTO Conferencegotocon.com/dl/goto-cph-2011/slides/OlaBini_JavaAsA... · 2011-05-12 · Kawa Lili Lisp LL Mapyrus MetaJ Mini NetLogo Nice Obol PERCobol PLAN Pnuts

torsdag den 12 maj 2011

Page 6: Java$as$a$Platform - GOTO Conferencegotocon.com/dl/goto-cph-2011/slides/OlaBini_JavaAsA... · 2011-05-12 · Kawa Lili Lisp LL Mapyrus MetaJ Mini NetLogo Nice Obol PERCobol PLAN Pnuts

torsdag den 12 maj 2011

Page 7: Java$as$a$Platform - GOTO Conferencegotocon.com/dl/goto-cph-2011/slides/OlaBini_JavaAsA... · 2011-05-12 · Kawa Lili Lisp LL Mapyrus MetaJ Mini NetLogo Nice Obol PERCobol PLAN Pnuts

Code  loading

torsdag den 12 maj 2011

Page 8: Java$as$a$Platform - GOTO Conferencegotocon.com/dl/goto-cph-2011/slides/OlaBini_JavaAsA... · 2011-05-12 · Kawa Lili Lisp LL Mapyrus MetaJ Mini NetLogo Nice Obol PERCobol PLAN Pnuts

Platform  independence

torsdag den 12 maj 2011

Page 9: Java$as$a$Platform - GOTO Conferencegotocon.com/dl/goto-cph-2011/slides/OlaBini_JavaAsA... · 2011-05-12 · Kawa Lili Lisp LL Mapyrus MetaJ Mini NetLogo Nice Obol PERCobol PLAN Pnuts

torsdag den 12 maj 2011

Page 10: Java$as$a$Platform - GOTO Conferencegotocon.com/dl/goto-cph-2011/slides/OlaBini_JavaAsA... · 2011-05-12 · Kawa Lili Lisp LL Mapyrus MetaJ Mini NetLogo Nice Obol PERCobol PLAN Pnuts

JIT

torsdag den 12 maj 2011

Page 11: Java$as$a$Platform - GOTO Conferencegotocon.com/dl/goto-cph-2011/slides/OlaBini_JavaAsA... · 2011-05-12 · Kawa Lili Lisp LL Mapyrus MetaJ Mini NetLogo Nice Obol PERCobol PLAN Pnuts

torsdag den 12 maj 2011

Page 12: Java$as$a$Platform - GOTO Conferencegotocon.com/dl/goto-cph-2011/slides/OlaBini_JavaAsA... · 2011-05-12 · Kawa Lili Lisp LL Mapyrus MetaJ Mini NetLogo Nice Obol PERCobol PLAN Pnuts

Languages

torsdag den 12 maj 2011

Page 13: Java$as$a$Platform - GOTO Conferencegotocon.com/dl/goto-cph-2011/slides/OlaBini_JavaAsA... · 2011-05-12 · Kawa Lili Lisp LL Mapyrus MetaJ Mini NetLogo Nice Obol PERCobol PLAN Pnuts

AardappelABCLAJLogoAnvil

BDC SchemeBeanShellBex Script

BiglooBistroCAL

CeylonCKI Prolog

ClojureCOCOA

CONVERTCorrelate

Demeter/JavadSelfFan

FScriptFunnel

GosuGroovy

HeclHojo

HotSchemeHotTEA

IokeiScript

JaclJaja

JaninoJatha

javalogJBasicJickleJLog

JMatchJoin Java

JoyJJRuby

JScheme

JudoScriptJythonKawaLiliLispLL

MapyrusMetaJMini

NetLogoNiceObol

PERCobolPLANPnutsPS3i

QuercusResinRhinorLogoSather

ScalaSISCSixxSkij

SleepSmallWorldStarLogo

Talks2TermWare

ThorntuProlog

Turtle Tracksuts

v-languageW4F

webLISPWLShellXProlog

YasslYnc/Javascript

Yoixtorsdag den 12 maj 2011

Page 14: Java$as$a$Platform - GOTO Conferencegotocon.com/dl/goto-cph-2011/slides/OlaBini_JavaAsA... · 2011-05-12 · Kawa Lili Lisp LL Mapyrus MetaJ Mini NetLogo Nice Obol PERCobol PLAN Pnuts

Paradigms

torsdag den 12 maj 2011

Page 15: Java$as$a$Platform - GOTO Conferencegotocon.com/dl/goto-cph-2011/slides/OlaBini_JavaAsA... · 2011-05-12 · Kawa Lili Lisp LL Mapyrus MetaJ Mini NetLogo Nice Obol PERCobol PLAN Pnuts

Object  Oriented

torsdag den 12 maj 2011

Page 16: Java$as$a$Platform - GOTO Conferencegotocon.com/dl/goto-cph-2011/slides/OlaBini_JavaAsA... · 2011-05-12 · Kawa Lili Lisp LL Mapyrus MetaJ Mini NetLogo Nice Obol PERCobol PLAN Pnuts

Statically  typed

torsdag den 12 maj 2011

Page 17: Java$as$a$Platform - GOTO Conferencegotocon.com/dl/goto-cph-2011/slides/OlaBini_JavaAsA... · 2011-05-12 · Kawa Lili Lisp LL Mapyrus MetaJ Mini NetLogo Nice Obol PERCobol PLAN Pnuts

Dynamically  typed

torsdag den 12 maj 2011

Page 18: Java$as$a$Platform - GOTO Conferencegotocon.com/dl/goto-cph-2011/slides/OlaBini_JavaAsA... · 2011-05-12 · Kawa Lili Lisp LL Mapyrus MetaJ Mini NetLogo Nice Obol PERCobol PLAN Pnuts

Concatenative

torsdag den 12 maj 2011

Page 19: Java$as$a$Platform - GOTO Conferencegotocon.com/dl/goto-cph-2011/slides/OlaBini_JavaAsA... · 2011-05-12 · Kawa Lili Lisp LL Mapyrus MetaJ Mini NetLogo Nice Obol PERCobol PLAN Pnuts

And  many  more...

torsdag den 12 maj 2011

Page 20: Java$as$a$Platform - GOTO Conferencegotocon.com/dl/goto-cph-2011/slides/OlaBini_JavaAsA... · 2011-05-12 · Kawa Lili Lisp LL Mapyrus MetaJ Mini NetLogo Nice Obol PERCobol PLAN Pnuts

What’s  missing?

torsdag den 12 maj 2011

Page 21: Java$as$a$Platform - GOTO Conferencegotocon.com/dl/goto-cph-2011/slides/OlaBini_JavaAsA... · 2011-05-12 · Kawa Lili Lisp LL Mapyrus MetaJ Mini NetLogo Nice Obol PERCobol PLAN Pnuts

torsdag den 12 maj 2011

Page 22: Java$as$a$Platform - GOTO Conferencegotocon.com/dl/goto-cph-2011/slides/OlaBini_JavaAsA... · 2011-05-12 · Kawa Lili Lisp LL Mapyrus MetaJ Mini NetLogo Nice Obol PERCobol PLAN Pnuts

Light  code  loading

torsdag den 12 maj 2011

Page 23: Java$as$a$Platform - GOTO Conferencegotocon.com/dl/goto-cph-2011/slides/OlaBini_JavaAsA... · 2011-05-12 · Kawa Lili Lisp LL Mapyrus MetaJ Mini NetLogo Nice Obol PERCobol PLAN Pnuts

Variablestatic  typing

torsdag den 12 maj 2011

Page 24: Java$as$a$Platform - GOTO Conferencegotocon.com/dl/goto-cph-2011/slides/OlaBini_JavaAsA... · 2011-05-12 · Kawa Lili Lisp LL Mapyrus MetaJ Mini NetLogo Nice Obol PERCobol PLAN Pnuts

torsdag den 12 maj 2011

Page 25: Java$as$a$Platform - GOTO Conferencegotocon.com/dl/goto-cph-2011/slides/OlaBini_JavaAsA... · 2011-05-12 · Kawa Lili Lisp LL Mapyrus MetaJ Mini NetLogo Nice Obol PERCobol PLAN Pnuts

torsdag den 12 maj 2011

Page 26: Java$as$a$Platform - GOTO Conferencegotocon.com/dl/goto-cph-2011/slides/OlaBini_JavaAsA... · 2011-05-12 · Kawa Lili Lisp LL Mapyrus MetaJ Mini NetLogo Nice Obol PERCobol PLAN Pnuts

Value  objects

torsdag den 12 maj 2011

Page 27: Java$as$a$Platform - GOTO Conferencegotocon.com/dl/goto-cph-2011/slides/OlaBini_JavaAsA... · 2011-05-12 · Kawa Lili Lisp LL Mapyrus MetaJ Mini NetLogo Nice Obol PERCobol PLAN Pnuts

JVM  Safepoint

torsdag den 12 maj 2011

Page 28: Java$as$a$Platform - GOTO Conferencegotocon.com/dl/goto-cph-2011/slides/OlaBini_JavaAsA... · 2011-05-12 · Kawa Lili Lisp LL Mapyrus MetaJ Mini NetLogo Nice Obol PERCobol PLAN Pnuts

JVM  Library  Help

torsdag den 12 maj 2011

Page 29: Java$as$a$Platform - GOTO Conferencegotocon.com/dl/goto-cph-2011/slides/OlaBini_JavaAsA... · 2011-05-12 · Kawa Lili Lisp LL Mapyrus MetaJ Mini NetLogo Nice Obol PERCobol PLAN Pnuts

Symbolic  freedom

torsdag den 12 maj 2011

Page 30: Java$as$a$Platform - GOTO Conferencegotocon.com/dl/goto-cph-2011/slides/OlaBini_JavaAsA... · 2011-05-12 · Kawa Lili Lisp LL Mapyrus MetaJ Mini NetLogo Nice Obol PERCobol PLAN Pnuts

Interface  Injection

torsdag den 12 maj 2011

Page 31: Java$as$a$Platform - GOTO Conferencegotocon.com/dl/goto-cph-2011/slides/OlaBini_JavaAsA... · 2011-05-12 · Kawa Lili Lisp LL Mapyrus MetaJ Mini NetLogo Nice Obol PERCobol PLAN Pnuts

Language  Specific  Invocation

torsdag den 12 maj 2011

Page 32: Java$as$a$Platform - GOTO Conferencegotocon.com/dl/goto-cph-2011/slides/OlaBini_JavaAsA... · 2011-05-12 · Kawa Lili Lisp LL Mapyrus MetaJ Mini NetLogo Nice Obol PERCobol PLAN Pnuts

The  DaVinci  Machine

torsdag den 12 maj 2011

Page 33: Java$as$a$Platform - GOTO Conferencegotocon.com/dl/goto-cph-2011/slides/OlaBini_JavaAsA... · 2011-05-12 · Kawa Lili Lisp LL Mapyrus MetaJ Mini NetLogo Nice Obol PERCobol PLAN Pnuts

JSR292

torsdag den 12 maj 2011

Page 34: Java$as$a$Platform - GOTO Conferencegotocon.com/dl/goto-cph-2011/slides/OlaBini_JavaAsA... · 2011-05-12 · Kawa Lili Lisp LL Mapyrus MetaJ Mini NetLogo Nice Obol PERCobol PLAN Pnuts

Dynamic  dispatch  today

torsdag den 12 maj 2011

Page 35: Java$as$a$Platform - GOTO Conferencegotocon.com/dl/goto-cph-2011/slides/OlaBini_JavaAsA... · 2011-05-12 · Kawa Lili Lisp LL Mapyrus MetaJ Mini NetLogo Nice Obol PERCobol PLAN Pnuts

Some  machinery

torsdag den 12 maj 2011

Page 36: Java$as$a$Platform - GOTO Conferencegotocon.com/dl/goto-cph-2011/slides/OlaBini_JavaAsA... · 2011-05-12 · Kawa Lili Lisp LL Mapyrus MetaJ Mini NetLogo Nice Obol PERCobol PLAN Pnuts

Analog  to  ThreadLocal

Allows  association  of  classes  to  values

Values  are  computed  lazily

Installation  of  new  values  happen  atomically

It  works  on  any  type,  including  int.class  or  void.class

You  can  remove  Class  Values  for  a  specific  type  too

Class  Values

torsdag den 12 maj 2011

Page 37: Java$as$a$Platform - GOTO Conferencegotocon.com/dl/goto-cph-2011/slides/OlaBini_JavaAsA... · 2011-05-12 · Kawa Lili Lisp LL Mapyrus MetaJ Mini NetLogo Nice Obol PERCobol PLAN Pnuts

import java.lang.ClassValue;

public class ClassValueTest { private final static ClassValue<MethodTable> methods = new ClassValue<MethodTable>() { public MethodTable computeValue(Class<?> type) { return MethodTable.newTableFor(type); } };

public static void main(String[] args) { MethodTable intMethods = methods.get(int.class); MethodTable stringMethods = methods.get(String.class); // Do something extremely cool here }}torsdag den 12 maj 2011

Page 38: Java$as$a$Platform - GOTO Conferencegotocon.com/dl/goto-cph-2011/slides/OlaBini_JavaAsA... · 2011-05-12 · Kawa Lili Lisp LL Mapyrus MetaJ Mini NetLogo Nice Obol PERCobol PLAN Pnuts

Method  Handles

torsdag den 12 maj 2011

Page 39: Java$as$a$Platform - GOTO Conferencegotocon.com/dl/goto-cph-2011/slides/OlaBini_JavaAsA... · 2011-05-12 · Kawa Lili Lisp LL Mapyrus MetaJ Mini NetLogo Nice Obol PERCobol PLAN Pnuts

Collect  arguments

Spread  arguments

Binding  to  a  specific  object

Convert  a  MethodHandle  to  an  instance  of  a  SAM

Convert  arguments

Filter  arguments  and  return  values

Fold  arguments

Catch  exceptions

Permute  arguments

Combinators

torsdag den 12 maj 2011

Page 40: Java$as$a$Platform - GOTO Conferencegotocon.com/dl/goto-cph-2011/slides/OlaBini_JavaAsA... · 2011-05-12 · Kawa Lili Lisp LL Mapyrus MetaJ Mini NetLogo Nice Obol PERCobol PLAN Pnuts

static  MethodHandle  guardWithTest(MethodHandle  test,                                                                                                              MethodHandle  target,                                                                                                            MethodHandle  fallback)                                        

Easy  way  to  implement  Monomorphic  Inline  Cache

Most  likely  thing  to  be  returned  from  InvokeDynamic

Guard  with  test

torsdag den 12 maj 2011

Page 41: Java$as$a$Platform - GOTO Conferencegotocon.com/dl/goto-cph-2011/slides/OlaBini_JavaAsA... · 2011-05-12 · Kawa Lili Lisp LL Mapyrus MetaJ Mini NetLogo Nice Obol PERCobol PLAN Pnuts

MethodHandle  guardWithTest(MH  target,  MH  fallback)

static  void  invalidateAll(SwitchPoint[]  switchPoints)

Makes  it  possible  to  publish  a  one  time  state  transition

It  begins  in  a  valid  state

Can  at  any  point  become  invalid

Invalidation  is  global,  immediate  and  permanent

SwitchPoint

torsdag den 12 maj 2011

Page 42: Java$as$a$Platform - GOTO Conferencegotocon.com/dl/goto-cph-2011/slides/OlaBini_JavaAsA... · 2011-05-12 · Kawa Lili Lisp LL Mapyrus MetaJ Mini NetLogo Nice Obol PERCobol PLAN Pnuts

InvokeDynamic

torsdag den 12 maj 2011

Page 43: Java$as$a$Platform - GOTO Conferencegotocon.com/dl/goto-cph-2011/slides/OlaBini_JavaAsA... · 2011-05-12 · Kawa Lili Lisp LL Mapyrus MetaJ Mini NetLogo Nice Obol PERCobol PLAN Pnuts

Call  site

torsdag den 12 maj 2011

Page 44: Java$as$a$Platform - GOTO Conferencegotocon.com/dl/goto-cph-2011/slides/OlaBini_JavaAsA... · 2011-05-12 · Kawa Lili Lisp LL Mapyrus MetaJ Mini NetLogo Nice Obol PERCobol PLAN Pnuts

Bootstrap  Method

torsdag den 12 maj 2011

Page 45: Java$as$a$Platform - GOTO Conferencegotocon.com/dl/goto-cph-2011/slides/OlaBini_JavaAsA... · 2011-05-12 · Kawa Lili Lisp LL Mapyrus MetaJ Mini NetLogo Nice Obol PERCobol PLAN Pnuts

public static CallSite bootstrapOne( MethodHandles.Lookup callerClassLookup, String methodName, MethodType typeDescriptor, String staticArg1, String staticArg2) { return new ConstantCallSite(someMethodHandle);}

torsdag den 12 maj 2011

Page 46: Java$as$a$Platform - GOTO Conferencegotocon.com/dl/goto-cph-2011/slides/OlaBini_JavaAsA... · 2011-05-12 · Kawa Lili Lisp LL Mapyrus MetaJ Mini NetLogo Nice Obol PERCobol PLAN Pnuts

InvokeDynamic

torsdag den 12 maj 2011

Page 47: Java$as$a$Platform - GOTO Conferencegotocon.com/dl/goto-cph-2011/slides/OlaBini_JavaAsA... · 2011-05-12 · Kawa Lili Lisp LL Mapyrus MetaJ Mini NetLogo Nice Obol PERCobol PLAN Pnuts

An  Example

torsdag den 12 maj 2011

Page 48: Java$as$a$Platform - GOTO Conferencegotocon.com/dl/goto-cph-2011/slides/OlaBini_JavaAsA... · 2011-05-12 · Kawa Lili Lisp LL Mapyrus MetaJ Mini NetLogo Nice Obol PERCobol PLAN Pnuts

SephCallSite.java

public class SephCallSite extends MutableCallSite { private enum Morphicity { NILADIC, MONOMORPHIC, POLYMORPHIC, MEGAMORPHIC }

int numberOfGuards = 0; Morphicity morphicity = Morphicity.NILADIC;

public SephCallSite(MethodType type) { super(type); }}

torsdag den 12 maj 2011

Page 49: Java$as$a$Platform - GOTO Conferencegotocon.com/dl/goto-cph-2011/slides/OlaBini_JavaAsA... · 2011-05-12 · Kawa Lili Lisp LL Mapyrus MetaJ Mini NetLogo Nice Obol PERCobol PLAN Pnuts

AbstractionCompiler.java

String bootstrapName = "basicSephBootstrap";boolean fullPumping = false;

if(first) { if(current == last) { bootstrapName = "noReceiverTailCallSephBootstrap"; fullPumping = true; } else { bootstrapName = "noReceiverSephBootstrap"; fullPumping = false; }} else if(current == last) { bootstrapName = "tailCallSephBootstrap"; fullPumping = true;}

ma.dynamicCall(encode(current.name()), sigFor(arity), bootstrapNamed(bootstrapName + possibleIntrinsic));

torsdag den 12 maj 2011

Page 50: Java$as$a$Platform - GOTO Conferencegotocon.com/dl/goto-cph-2011/slides/OlaBini_JavaAsA... · 2011-05-12 · Kawa Lili Lisp LL Mapyrus MetaJ Mini NetLogo Nice Obol PERCobol PLAN Pnuts

Bootstrap.java

private static CallSite bootstrap(MethodHandles.Lookup lookup, String name, MethodType type, String bootstrapType) { SephCallSite site = new SephCallSite(type); MethodType fallbackType = type.insertParameterTypes(0, SephCallSite.class, String.class); MethodHandle fallback = MethodHandles.insertArguments( findStatic(Bootstrap.class, bootstrapType, fallbackType), 0, site, decode(name)); site.setTarget(fallback); return site;}

public static CallSite basicSephBootstrap(MethodHandles.Lookup lookup, String name, MethodType type) { return bootstrap(lookup, name, type, "fallback");}

torsdag den 12 maj 2011

Page 51: Java$as$a$Platform - GOTO Conferencegotocon.com/dl/goto-cph-2011/slides/OlaBini_JavaAsA... · 2011-05-12 · Kawa Lili Lisp LL Mapyrus MetaJ Mini NetLogo Nice Obol PERCobol PLAN Pnuts

Bootstrap.java  (continued)

public static SephObject fallback(SephCallSite site, String name, SephObject receiver, SThread thread, LexicalScope scope, IPersistentList args) { SephObject value = receiver.get(name); if(null == value) { throw new RuntimeException(" *** couldn't find: " + name + " on " + receiver); } if(value.isActivatable()) { site.installActivatableEntry(receiver, null, value, -1); return value.activateWith(receiver, thread, scope, args); } else { site.installConstantEntry(receiver, null, value, -1); } return value;}

torsdag den 12 maj 2011

Page 52: Java$as$a$Platform - GOTO Conferencegotocon.com/dl/goto-cph-2011/slides/OlaBini_JavaAsA... · 2011-05-12 · Kawa Lili Lisp LL Mapyrus MetaJ Mini NetLogo Nice Obol PERCobol PLAN Pnuts

Bootstrap.java  (continued)

public static SephObject initialSetup_intrinsic_if(SephCallSite site, MethodHandle slow, SephObject receiver, SThread thread, LexicalScope scope, MethodHandle test, MethodHandle then, MethodHandle _else) throws Throwable { MethodHandle guarded = thread.runtime.INTRINSIC_IF_SP.guardWithTest( INTRINSIC_IF_MH, replaceCompletely3(slow, site)); site.setTarget(guarded); return (SephObject)guarded.invokeExact(receiver, thread, scope, test, then, _else);}

torsdag den 12 maj 2011

Page 53: Java$as$a$Platform - GOTO Conferencegotocon.com/dl/goto-cph-2011/slides/OlaBini_JavaAsA... · 2011-05-12 · Kawa Lili Lisp LL Mapyrus MetaJ Mini NetLogo Nice Obol PERCobol PLAN Pnuts

Runtime.java

public final SwitchPoint INTRINSIC_IF_SP = new SwitchPoint();public static void empty() {}public static void invalidate(SwitchPoint sp) { SwitchPoint.invalidateAll(new SwitchPoint[] {sp});}public final MethodHandle INVALIDATE_IF = INTRINSIC_IF_SP.guardWithTest( INVALIDATE_MH.bindTo(INTRINSIC_IF_SP), EMPTY_MH);public void checkIntrinsicAssignment(String name) { name = name.intern(); try { if(name == "true") { INVALIDATE_TRUE.invokeExact(); } else if(name == "if") { INVALIDATE_IF.invokeExact(); } } catch(Throwable e) {}}

torsdag den 12 maj 2011

Page 54: Java$as$a$Platform - GOTO Conferencegotocon.com/dl/goto-cph-2011/slides/OlaBini_JavaAsA... · 2011-05-12 · Kawa Lili Lisp LL Mapyrus MetaJ Mini NetLogo Nice Obol PERCobol PLAN Pnuts

JSR292.next?

torsdag den 12 maj 2011