SlideShare una empresa de Scribd logo
1 de 123
A peek into the OpenJDK 
compiler : goto java; 
Martin Skarsaune 
Java Developer and Co-Owner 
高 
馬 
丁
GOTO statements 
in Java!
GOTO Statement –Objective 
• Syntax: 
goto identifier; 
• Runtime 
– Program control moves to target statement 
• Other Semantics 
– Target (statement label) must be defined in same 
scope, compilation error if not 
– Potential circular gotos should give compilation 
warning.
GOTO Statement – Means 
1. OpenJDK 
– Open source Java implementation 
– Compiler implemented in Java 
2. Modify compiler source to support goto 
statements
Success case 
public class GotoSuccess { 
public static void main(String[] args) { 
one: System.out.print("goto "); 
two: System.out.print("Java"); 
goto four; 
three: System.out.print("2014"); 
goto five; 
four: System.out.print("Zone "); 
goto three; 
five: System.out.print("!"); 
} 
}
GOTO 
AHEAD 
Dijkstra 1968: 
programmerquality =100 1- 
gotos 
LoC 
æ 
è ç 
ö 
ø ÷
What is a 
Compiler? 
Compiler
What is a 
Compiler? 
front back
Parse Enter Process Attribute Flow Desugar Generate 
processAnnotations(enterTrees(… 
parseFiles(…))),…) 
… 
generate(desugar(flow(attribute(…))))
Parse Enter Process Attribute Flow Desugar Generate 
processAnnotations(enterTrees(… 
parseFiles(…))),…) 
… 
generate(desugar(flow(attribute(…))))
Parse Enter Process Attribute Flow Desugar Generate 
• Syntax: goto identifier; 
• First convert character stream to token 
stream (Scanner.java) 
[g][o][t][o][ ][f][o][u][r][;] 
GOTO IDENTIFIER SEMI
Parse Enter Process Attribute Flow Desugar Generate 
• goto is already a reserved word in Java! 
• Lucky for us, goto is therefore defined as a 
TokenKind. 
• Tokens.java:141: GOTO("goto") 
• The scanner therefore works out of the box!
Parse Enter Process Attribute Flow Desugar Generate 
final Scanner scanner=factory.newScanner(”goto identifier;”, false); 
... 
import com.sun.tools.javac.parser.Scanner; 
...
Parse Enter Process Attribute Flow Desugar Generate 
final Scanner scanner=factory.newScanner(”goto identifier;”, false); 
scanner.nextToken();
Parse Enter Process Attribute Flow Desugar Generate 
final Scanner scanner=factory.newScanner(”goto identifier;”, false); 
scanner.nextToken(); 
assertThat(”First token is GOTO”, scanner.token().kind, is(GOTO));
Parse Enter Process Attribute Flow Desugar Generate 
final Scanner scanner=factory.newScanner(”goto identifier;”, false); 
scanner.nextToken(); 
assertThat(”First token is GOTO”, scanner.token().kind, is(GOTO)); 
scanner.nextToken();
Parse Enter Process Attribute Flow Desugar Generate 
final Scanner scanner=factory.newScanner(”goto identifier;”, false); 
scanner.nextToken(); 
assertThat(”First token is GOTO”, scanner.token().kind, is(GOTO)); 
scanner.nextToken(); 
assertThat("Second token is IDENTIFIER", scanner.token().kind, 
is(IDENTIFIER));
Parse Enter Process Attribute Flow Desugar Generate 
final Scanner scanner=factory.newScanner(”goto identifier;”, false); 
scanner.nextToken(); 
assertThat(”First token is GOTO”, scanner.token().kind, is(GOTO)); 
scanner.nextToken(); 
assertThat("Second token is IDENTIFIER", scanner.token().kind, 
is(IDENTIFIER)); 
scanner.nextToken();
Parse Enter Process Attribute Flow Desugar Generate 
final Scanner scanner=factory.newScanner(”goto identifier;”, false); 
scanner.nextToken(); 
assertThat(”First token is GOTO”, scanner.token().kind, is(GOTO)); 
scanner.nextToken(); 
assertThat("Second token is IDENTIFIER", scanner.token().kind, 
is(IDENTIFIER)); 
scanner.nextToken(); 
assertThat("Third token is SEMI", scanner.token().kind, is(SEMI));
Parse Enter Process Attribute Flow Desugar Generate Abstract Syntax 
CompilationUnit 
ClassDefinition 
FieldDefintion 
MethodDefinition 
Signature 
Body 
IfStatement 
Goto 
Wikipedia: “the visitor design pattern 
is a way of separating an algorithm 
from an object structure on which it 
operates” 
visitClassDef(..) 
visitMethodDef( 
..) 
visitIf(..) 
Tree 
GOTO IDENTIFIER SEMI 
[g][o][t][o][ ][f][o][u][r][;]
Parse Enter Process Attribute Flow Desugar Generate 
Class Interface
Parse Enter Process Attribute Flow Desugar Generate 
• Interface based visitors
Parse Enter Process Attribute Flow Desugar Generate 
• Class based visitors 
public void visitGoto(JCGoto tree) { 
try { 
print("goto " + tree.label + ";"); 
} catch (IOException e) { 
throw new UncheckedIOException(e); 
} 
} 
public void visitGoto(JCGoto tree) { 
//TODO implement 
}
Parse Enter Process Attribute Flow Desugar Generate 
public class GotoResolver { 
Map<GotoTree, Name> gotos; 
Map<Name, LabeledStatementTree> targets; 
List<StatementTree> statementsInSequence; 
... 
} 
public static class JCLabeledStatement extends JCStatement 
implements LabeledStatementTree { 
… 
public GotoResolver handler; 
… 
}
Parse Enter Process Attribute Flow Desugar Generate 
TreeMaker.java: 
public JCGoto Goto(Name label, GotoResolver resolver) { 
JCGoto tree = new JCGoto(label, resolver); 
tree.pos = pos; 
return tree; 
} 
• JavacParser.parseStatement() 
case GOTO: { 
nextToken(); 
Name label = ident(); 
JCGoto t = to(F.at(pos).Goto(label, getGotoResolver())); 
accept(SEMI); 
return t; 
}
Parse Enter Process Attribute Flow Desugar Generate 
processAnnotations(enterTrees(… 
parseFiles(…))),…) 
… 
generate(desugar(flow(attribute(…))))
Parse Enter Process Attribute Flow Desugar Generate 
• Basic sanity testing of compilation unit 
– File name and folder location 
– Duplicate class names 
• Corrections 
– Add default constructor if no constructors are 
declared
Parse Enter Process Attribute Flow Desugar Generate 
• Default constructor 
public class SimpleClass { 
}
Parse Enter Process Attribute Flow Desugar Generate 
• Default constructor 
public class SimpleClass { 
public SimpleClass() { 
super(); 
} 
}
Parse Enter Process Attribute Flow Desugar Generate 
processAnnotations(enterTrees(… 
parseFiles(…))),…) 
… 
generate(desugar(flow(attribute(…))))
Parse Enter Process Attribute Flow Desugar Generate 
• Annotation processing API 
• Part of ordinary javac process since Java 1.6 
• Plugin API (see javac documentation)
Parse Enter Process Attribute Flow Desugar Generate 
• Output controlled by command line switches 
@ 
- proc:none – do not process annotations 
- proc:only – only process annotations, do not compile
Parse Enter Process Attribute Flow Desugar Generate 
processAnnotations(enterTrees(… 
parseFiles(…))),…) 
… 
generate(desugar(flow(attribute(…))))
Parse Enter Process Attribute Flow Desugar Generate 
• Semantic checks 
– Types 
– References 
• Corrections 
– Add required calls to super constructor
Parse Enter Process Attribute Flow Desugar Generate 
• We want to verify that goto target exists in 
current scope 
public class GotoMissingLabel { 
public static void main(String[] args) { 
one: System.out.print("goto "); 
two: System.out.print("Java"); 
goto six; 
three: System.out.print("2014"); 
goto five; 
four: System.out.print("Zone "); 
goto three; 
five: System.out.print("!"); 
} 
}
Parse Enter Process Attribute Flow Desugar Generate 
• Attr.java: 
@Override 
public void visitGoto(JCGoto that) { 
that.findTarget(); 
if(that.target==null) 
log.error(that.pos(), "undef.label", that.label); 
result = null; 
} 
class JCGoto: 
… 
public void findTarget() { 
this.target = (JCLabeledStatement)this.handler.findTarget(this); 
}
Parse Enter Process Attribute Flow Desugar Generate 
processAnnotations(enterTrees(… 
parseFiles(…))),…) 
… 
generate(desugar(flow(attribute(…))))
Parse Enter Process Attribute Flow Desugar Generate 
Flow analysis 
• Detect unreachable code 
• Verify assignments 
• Ensure proper method return 
• Verify (effectively) final 
• Check exception flow
Parse Enter Process Attribute Flow Desugar Generate 
We want to detect circular gotos: 
public class GotoCircularWarning { 
public static void main(String[] args) { 
one: System.out.print("goto "); 
two: System.out.print("Java"); 
goto four; 
three: System.out.print("2014"); 
goto five; 
four: System.out.print("Zone "); 
goto three; 
five: System.out.println("!"); 
goto one;//forms infinite loop 
} 
}
Parse Enter Process Attribute Flow Desugar Generate 
Flow.FlowAnalyzer class: 
@Override 
public void visitGoto(JCGoto tree) { 
if (tree.handler.detectCircularGotoPosition(tree)) 
log.warning(tree.pos, "circular.goto"); 
} 
compiler.properties: 
... 
compiler.warn.circular.goto=circular goto 
...
Parse Enter Process Attribute Flow Desugar Generate 
processAnnotations(enterTrees(… 
parseFiles(…))),…) 
… 
generate(desugar(flow(attribute(…))))
Parse Enter Process Attribute Flow Desugar Generate 
TransTypes Unlambda Lower 
• Erase generic types 
public class Bridge implements Comparator { 
}
Parse Enter Process Attribute Flow Desugar Generate 
TransTypes Unlambda Lower 
• Erase generic types 
public class Bridge implements Comparator { 
} 
public interface Comparator<T> {t 
int compare(T o1, T o2); 
}or<T> {
Parse Enter Process Attribute Flow Desugar Generate 
TransTypes Unlambda Lower 
• Erase generic types 
public class Bridge implements Comparator<Integer> { 
} 
public interface Comparator<T> {t 
int compare(T o1, T o2); 
}or<T> {
Parse Enter Process Attribute Flow Desugar Generate 
TransTypes Unlambda Lower 
• Erase generic types 
public class Bridge implements Comparator<Integer> { 
public int compare(Integer first, Integer second) { 
return first - second; 
} 
} 
public interface Comparator<T> {t 
int compare(T o1, T o2); 
}or<T> {
Parse Enter Process Attribute Flow Desugar Generate 
TransTypes Unlambda Lower 
• Erase generic types 
public class Bridge implements Comparator { 
public int compare(Integer first, Integer second) { 
return first - second; 
} 
}
Parse Enter Process Attribute Flow Desugar Generate 
TransTypes Unlambda Lower 
• Erase generic types 
public class Bridge implements Comparator { 
public int compare(Integer first, Integer second) { 
return first - second; 
} 
/*synthetic*/ 
public int compare(Object first, Object second) { 
return this.compare((Integer)first, (Integer)second); 
} 
}
Parse Enter Process Attribute Flow Desugar Generate 
TransTypes Unlambda Lower 
• Extract Inner Class 
public class Outer { 
private void foo() { } 
public Runnable fooRunner() { 
return new Runnable() { 
public void run() { 
foo(); 
} 
}; 
} 
}
Parse Enter Process Attribute Flow Desugar Generate 
TransTypes Unlambda Lower 
• Extract Inner Class 
public class Outer { 
private void foo() { } 
public Runnable fooRunner() { 
return new Runnable() { 
public void run() { 
foo(); 
} 
}; 
} 
}
Parse Enter Process Attribute Flow Desugar Generate 
TransTypes Unlambda Lower 
• Extract Inner Class 
public class Outer { 
private void foo() { } 
public Runnable fooRunner() { 
return new Outer$1(this); 
} 
} 
class Outer$1 implements Runnable { 
final Outer this$0; 
public void run() { 
this$0.foo(); 
} 
}
Parse Enter Process Attribute Flow Desugar Generate 
TransTypes Unlambda Lower 
• Extract Inner Class 
public class Outer { 
private void foo() { } 
public Runnable fooRunner() { 
return new Outer$1(this); 
} 
} 
class Outer$1 implements Runnable { 
final Outer this$0; 
Outer$1(final Outer this$0) { 
this.this$0 = this$0; 
super(); 
} 
public void run() { 
this$0.foo(); 
} 
}
Parse Enter Process Attribute Flow Desugar Generate 
TransTypes Unlambda Lower 
• Extract Inner Class 
public class Outer { 
private void foo() { } 
public Runnable fooRunner() { 
return new Outer$1(this); 
} 
} 
class Outer$1 implements Runnable { 
final Outer this$0; 
Outer$1(final Outer this$0) { 
this.this$0 = this$0; 
super(); 
} 
public void run() { 
this$0.foo(); 
} 
}
Parse Enter Process Attribute Flow Desugar Generate 
TransTypes Unlambda Lower 
• Extract Inner Class 
public class Outer { 
private void foo() { } 
public Runnable fooRunner() { 
return new Outer$1(this); 
} 
static void access$000( 
Outer x0) { 
x0.foo(); 
} 
} 
class Outer$1 implements Runnable { 
final Outer this$0; 
Outer$1(final Outer this$0) { 
this.this$0 = this$0; 
super(); 
} 
public void run() { 
Outer.access$000(this$0); 
} 
}
Parse Enter Process Attribute Flow Desugar Generate 
TransTypes Unlambda Lower 
• Boxing 
List<Integer> list = 
Arrays.asList(1, 2); 
for (Integer i : list) { 
System.out.println("Double: " + i * 2); 
}
Parse Enter Process Attribute Flow Desugar Generate 
TransTypes Unlambda Lower 
• Boxing 
List<Integer> list = 
Arrays.asList(1, 2); 
for (Integer i : list) { 
System.out.println("Double: " + i * 2); 
} 
public static <T> List<T> asList(T... a) { 
return new ArrayList<>(a); 
}
Parse Enter Process Attribute Flow Desugar Generate 
TransTypes Unlambda Lower 
• Boxing 
List<Integer> list = 
Arrays.asList(Integer.valueOf(1), Integer.valueOf(2)); 
for (Integer i : list) { 
System.out.println("Double: " + i * 2); 
}
Parse Enter Process Attribute Flow Desugar Generate 
TransTypes Unlambda Lower 
• Unboxing 
List<Integer> list = 
Arrays.asList(Integer.valueOf(1), Integer.valueOf(2)); 
for (Integer i : list) { 
System.out.println("Double: " + i * 2); 
}
Parse Enter Process Attribute Flow Desugar Generate 
TransTypes Unlambda Lower 
• Unboxing 
List<Integer> list = 
Arrays.asList(Integer.valueOf(1), Integer.valueOf(2)); 
for (Integer i : list) { 
System.out.println("Double: " + i.intValue() * 2); 
}
Parse Enter Process Attribute Flow Desugar Generate 
TransTypes Unlambda Lower 
• Varargs 
List<Integer> list = 
Arrays.asList(Integer.valueOf(1), Integer.valueOf(2)); 
for (Integer i : list) { 
System.out.println("Double: " + i.intValue() * 2); 
}
Parse Enter Process Attribute Flow Desugar Generate 
TransTypes Unlambda Lower 
• Varargs 
List<Integer> list = 
Arrays.asList(Integer.valueOf(1), Integer.valueOf(2)); 
for (Integer i : list) { 
System.out.println("Double: " + i.intValue() * 2); 
} 
public static <T> List<T> asList(T... a) { 
return new ArrayList<>(a); 
}
Parse Enter Process Attribute Flow Desugar Generate 
TransTypes Unlambda Lower 
• Varargs 
List<Integer> list = 
Arrays.asList(new Integer[]{Integer.valueOf(1), Integer.valueOf(2)}); 
for (Integer i : list) { 
System.out.println("Double: " + i.intValue() * 2); 
}
Parse Enter Process Attribute Flow Desugar Generate 
TransTypes Unlambda Lower 
• For each loop 
List<Integer> list = 
Arrays.asList(new Integer[]{Integer.valueOf(1), Integer.valueOf(2)}); 
for (Integer i : list) { 
System.out.println("Double: " + i.intValue() * 2); 
}
Parse Enter Process Attribute Flow Desugar Generate 
TransTypes Unlambda Lower 
• For each loop 
public interface Iterable<T> { 
Iterator<T> iterator(); 
} 
List<Integer> list = 
Arrays.asList(new Integer[]{Integer.valueOf(1), Integer.valueOf(2)}); 
for (Integer i : list) { 
System.out.println("Double: " + i.intValue() * 2); 
} 
static <T> List<T> asList(T... a) { 
return new ArrayList<>(a); 
}
Parse Enter Process Attribute Flow Desugar Generate 
TransTypes Unlambda Lower 
• For each loop 
List<Integer> list = 
Arrays.asList(new Integer[]{Integer.valueOf(1), Integer.valueOf(2)}); 
for (;;) { 
Integer i 
System.out.println("Double: " + i.intValue() * 2); 
}
Parse Enter Process Attribute Flow Desugar Generate 
TransTypes Unlambda Lower 
• For each loop 
List<Integer> list = 
Arrays.asList(new Integer[]{Integer.valueOf(1), Integer.valueOf(2)}); 
for (Iterator i$ = list.iterator();;) { 
Integer i 
System.out.println("Double: " + i.intValue() * 2); 
}
Parse Enter Process Attribute Flow Desugar Generate 
TransTypes Unlambda Lower 
• For each loop 
List<Integer> list = 
Arrays.asList(new Integer[]{Integer.valueOf(1), Integer.valueOf(2)}); 
for (Iterator i$ = list.iterator(); i$.hasNext();) { 
Integer i 
System.out.println("Double: " + i.intValue() * 2); 
}
Parse Enter Process Attribute Flow Desugar Generate 
TransTypes Unlambda Lower 
• For each loop 
List<Integer> list = 
Arrays.asList(new Integer[]{Integer.valueOf(1), Integer.valueOf(2)}); 
for (Iterator i$ = list.iterator(); i$.hasNext();) { 
Integer i = (Integer)i$.next(); 
System.out.println("Double: " + i.intValue() * 2); 
}
Parse Enter Process Attribute Flow Desugar Generate 
TransTypes Unlambda Lower 
• Enums 
public enum Status { 
YES, NO, MAYBE 
}
Parse Enter Process Attribute Flow Desugar Generate 
TransTypes Unlambda Lower 
• Enums 
public enum Status { 
YES, NO, MAYBE 
private Status(String $enum$name, int $enum$ordinal) { 
super($enum$name, $enum$ordinal); 
} 
}
Parse Enter Process Attribute Flow Desugar Generate 
TransTypes Unlambda Lower 
• Enums 
public enum Status { 
YES, NO, MAYBE 
private Status(String $enum$name, int $enum$ordinal) { 
super($enum$name, $enum$ordinal); 
} 
public static Status valueOf(String name) { 
return (Status)Enum.valueOf(Status.class, name); 
} 
}
Parse Enter Process Attribute Flow Desugar Generate 
TransTypes Unlambda Lower 
• Enums 
public enum Status { 
YES, NO, MAYBE 
private Status(String $enum$name, int $enum$ordinal) { 
super($enum$name, $enum$ordinal); 
} 
public static Status valueOf(String name) { 
return (Status)Enum.valueOf(Status.class, name); 
} 
private static final Status[] $VALUES = new Status[]{ 
Status.YES, Status.NO, Status.MAYBE}; 
public static Status[] values() { 
return (Status[])$VALUES.clone(); 
}
Parse Enter Process Attribute Flow Desugar Generate 
TransTypes Unlambda Lower 
• Enum based switch statements 
public class SwitchStatus { 
void switchStatus(Status status) { 
switch (status) { 
case MAYBE: 
return; 
default: 
break; 
} 
} 
}
Parse Enter Process Attribute Flow Desugar Generate 
TransTypes Unlambda Lower 
• Enum based switch statements 
public class SwitchStatus { 
void switchStatus(Status status) { 
switch (status) { 
case MAYBE: 
return; 
default: 
break; 
} 
} 
}
Parse Enter Process Attribute Flow Desugar Generate 
TransTypes Unlambda Lower 
• Enum based switch statements 
public class SwitchStatus { 
void switchStatus(Status status) { 
switch (SwitchStatus$1.$SwitchMap$Status[(status).ordinal()]) { 
case 1: 
return; 
default: 
break; 
} 
} 
}
Parse Enter Process Attribute Flow Desugar Generate 
TransTypes Unlambda Lower 
class SwitchStatus$1 { 
• Enum based switch statements 
public class SwitchStatus { 
void switchStatus(Status status) { 
switch (SwitchStatus$1.$SwitchMap$Status[(status).ordinal()]) { 
case 1: 
return; 
default: 
break; 
} 
} 
} 
}
Parse Enter Process Attribute Flow Desugar Generate 
TransTypes Unlambda Lower 
class SwitchStatus$1 { 
static final int[] $SwitchMap$Status = new int[Status.values().length]; 
• Enum based switch statements 
public class SwitchStatus { 
void switchStatus(Status status) { 
switch (SwitchStatus$1.$SwitchMap$Status[(status).ordinal()]) { 
case 1: 
return; 
default: 
break; 
} 
} 
} 
}
Parse Enter Process Attribute Flow Desugar Generate 
TransTypes Unlambda Lower 
class SwitchStatus$1 { 
static final int[] $SwitchMap$Status = new int[Status.values().length]; 
[0][0][0] 
• Enum based switch statements 
public class SwitchStatus { 
void switchStatus(Status status) { 
switch (SwitchStatus$1.$SwitchMap$Status[(status).ordinal()]) { 
case 1: 
return; 
default: 
break; 
} 
} 
} 
}
Parse Enter Process Attribute Flow Desugar Generate 
TransTypes Unlambda Lower 
class SwitchStatus$1 { 
static final int[] $SwitchMap$Status = new int[Status.values().length]; 
[0][0][1] 
static { 
• Enum based switch statements 
try { 
SwitchStatus$1.$SwitchMap$Status[Status.MAYBE.ordinal()] = 1; 
} catch public (NoSuchFieldError class SwitchStatus ex) { 
{ } 
} 
} 
void switchStatus(Status status) { 
switch (SwitchStatus$1.$SwitchMap$Status[(status).ordinal()]) { 
case 1: 
return; 
default: 
break; 
} 
} 
}
Parse Enter Process Attribute Flow Desugar Generate 
TransTypes Unlambda Lower 
class SwitchStatus$1 { 
static final int[] $SwitchMap$Status = new int[Status.values().length]; 
[0][0][1] 
static { 
• Enum based switch statements 
try { 
SwitchStatus$1.$SwitchMap$Status[Status.MAYBE.ordinal()] = 1; 
} catch public (NoSuchFieldError class SwitchStatus ex) { 
{ } 
} 
} 
void switchStatus(Status status) { 
switch (SwitchStatus$1.$SwitchMap$Status[(status).ordinal()]) { 
case 1: 
return; 
default: 
break; 
} 
} 
}
Parse Enter Process Attribute Flow Desugar Generate 
processAnnotations(enterTrees(… 
parseFiles(…))),…) 
… 
generate(desugar(flow(attribute(…))))
Parse Enter Process Attribute Flow Desugar Generate 
• Generate bytecodes 
• Organize initializers 
• String concatenation 
• Some optimizations
Parse Enter Process Attribute Flow Desugar Generate 
• Organize <init> (Constructor) 
public class InstanceInitialization { 
String key="key"; 
String value; 
public InstanceInitialization(String value) { 
this.value = value; 
} 
}
Parse Enter Process Attribute Flow Desugar Generate 
• Organize <init> (Constructor) 
public class InstanceInitialization { 
String key="key"; 
String value; 
public InstanceInitialization(String value) { 
super(); 
this.value = value; 
} 
}
Parse Enter Process Attribute Flow Desugar Generate 
• Organize <init> (Constructor) 
public class InstanceInitialization { 
String key; 
String value; 
public InstanceInitialization(String value) { 
super(); 
key = ”key”; 
this.value = value; 
} 
}
Parse Enter Process Attribute Flow Desugar Generate 
• Organize <init> (Constructor) 
public class InstanceInitialization { 
String key; 
String value; 
public <init>(String value) { 
super(); 
key = ”key”; 
this.value = value; 
} 
}
Parse Enter Process Attribute Flow Desugar Generate 
• Organize <clinit> (Static initialization) 
public class StaticInitialization { 
static String key="key"; 
static String value; 
static { 
value = value; 
} 
}
Parse Enter Process Attribute Flow Desugar Generate 
• Organize <clinit> (Static initialization) 
public class StaticInitialization { 
static String key; 
static String value; 
static { 
key="key”; 
value = value; 
} 
}
Parse Enter Process Attribute Flow Desugar Generate 
• Organize <clinit> (Static initialization) 
public class StaticInitialization { 
static String key; 
static String value; 
static void <clinit>{ 
key="key”; 
value = value; 
} 
}
Parse Enter Process Attribute Flow Desugar Generate 
• String concatenation 
Source code “Generated code” 
”string” + value
Parse Enter Process Attribute Flow Desugar Generate 
Source code “Generated code” 
”string” + value new StringBuilder()
Parse Enter Process Attribute Flow Desugar Generate 
Source code “Generated code” 
”string” + value new StringBuilder() 
.append(”string”)
Parse Enter Process Attribute Flow Desugar Generate 
Source code “Generated code” 
”string” + value new StringBuilder() 
.append(”string”) 
.append(value)
Parse Enter Process Attribute Flow Desugar Generate 
Source code “Generated code” 
”string” + value new StringBuilder() 
.append(”string”) 
.append(value) 
.toString()
Goto Generation 
• Lucky for us there is a byte code for goto 
• goto <addr>
Parse Enter Process Attribute Flow Desugar Generate 
Source code PC Byte code 
… 
if (<test>) 
{ 
<ifblock> 
} 
else 
{ 
<elseblock> 
} 
<codeafter> 
… … 
9 ifeq 
22 
… <elseblock> 
… goto 
29 
<stackmap> 
22 <ifblock> 
<stackmap> 
29 <codeafter> 
Code generator (Code.java) 
Java >= 1.6: 
marked as not alive. 
Stack map frames must be 
embedded at target of jump 
Goto instruction added to list 
of pending jumps (Chain.java) 
instruction 
Pending jumps processed
Parse Enter Process Attribute Flow Desugar Generate 
• Scenario 1: go back 
Source code PC Byte code 
… 
label: <somecode> 
… 
goto label; 
… 
20 
<stackmap> 
<somecode> 
… goto 20 
Used by goto? 
Must emit stackmap 
Emit goto to label and turn 
code generation on again
Parse Enter Process Attribute Flow Desugar Generate 
• Scenario 2: go forward 
Source code PC Byte code 
Label used? 
• emit stack frame 
• patch pending gotos 
… 
goto label; 
… 
label: <somecode> 
… 
… 
goto 
<stackmap> 
29 <somecode> 
Label position not yet known? 
• emit goto 
• add to list of pending gotos 
• turn generation on again 
29
Parse Enter Process Attribute Flow Desugar Generate 
Gen.java - Labelled 
public void visitLabelled(JCLabeledStatement tree) { 
// if the label is used from gotos, have to emit stack map 
if (tree.handler.isUsed(tree)) 
code.emitStackMap(); 
… 
}
Parse Enter Process Attribute Flow Desugar Generate 
Gen.java - Goto 
public void visitGoto(JCGoto tree) { 
tree.handler.addBranch(new Chain(code.emitJump(goto_), null, code.state.dup()), 
tree.target); 
//normally goto marks code as not alive, turn generation on 
code.entryPoint(); 
} 
Target position known? 
• Yes – patch immediately 
• No – add to list of pending gotos
Mission 
Accomplis 
hed!
ambda
Parse Enter Process Attribute Flow Desugar Generate 
TransTypes Unlambda Lower 
• Lambda implementation in Java 8 
– Language change 
– Compilation 
– Runtime support 
• Many interesting design considerations
Parse Enter Process Attribute Flow Desugar Generate 
TransTypes Unlambda Lower 
• Simple example 
public Comparator<String> lambdaExample() { 
return (String a, String b) -> a.compareTo(b); 
}
Parse Enter Process Attribute Flow Desugar Generate 
TransTypes Unlambda Lower 
• LambdaToMethod.java 
public Comparator<String> lambdaExample() { 
return (String a, String b) -> a.compareTo(b); 
} 
/*synthetic*/ 
private static int 
lambda$lambdaExample$0( 
, 
) { 
return ; 
} 
final String a 
final String b 
a.compareTo(b)
Parse Enter Process Attribute Flow Desugar Generate 
TransTypes Unlambda Lower 
public interface Comparator {/*erased*/ 
• int compare(Runtime 
Object o1, Object o2); 
} 
public Comparator<String> lambdaExample() { 
return <invokedynamic>LambdaMetafactory.metafactory( 
} 
final class LambdaExample$$Lambda$1/1834188994 
implements Comparator { 
private LambdaExample$$Lambda$1/1834188994() 
public int compare(Object,Object) 
} 
/*synthetic*/ 
private static int 
lambda$lambdaExample$0( 
final String a, 
final String b) { 
return a.compareTo(b); 
} 
Lookup(LambdaExample), /*caller*/ 
"compare", 
()Comparator, /*MethodType*/ 
(Object,Object)int, /*MethodType*/ 
lambda$lambdaExample$0, /*MethodHandle*/ 
(String,String)int); /*MethodType*/
Parse Enter Process Attribute Flow Desugar Generate 
TransTypes Unlambda Lower 
• Runtime class generation 
LambdaMetaFactory 
• metaFactory(…) 
• altMetaFactory(…) 
InnerClassLambdaMetafactory 
ASM 
Lambda Class
Parse Enter Process Attribute Flow Desugar Generate 
TransTypes Unlambda Lower 
• Serialization 
Lambda 
Instance 
Serialize 
Serialized 
Lambda 
Lambda 
Meta 
Factory 
Deserialize
Parse Enter Process Attribute Flow Desugar Generate 
TransTypes Unlambda Lower 
• Example with instance and local capture 
private int c = 3; 
public Comparator<String> withInstanceAndLocalCapture() { 
int a = 1, b = 2; 
return (String d, String e) -> d.compareTo(e) + a + b - c; 
}
Parse Enter Process Attribute Flow Desugar Generate 
TransTypes Unlambda Lower 
• Example with instance and local capture 
private int c = 3; 
public Comparator<String> withInstanceAndLocalCapture() { 
int a = 1, b = 2; 
return (String d, String e) -> d.compareTo(e) + a + b - c; 
} 
/*synthetic*/ 
private int lambda$withInstanceAndLocalCapture$1( 
final int cap$0, final int cap$1, 
final String d, final String e) { 
return d.compareTo(e) + cap$0 + cap$1 - c; 
}
Parse Enter Process Attribute Flow Desugar Generate 
TransTypes Unlambda Lower 
• Example with instance and local capture 
private int c = 3; 
public Comparator<String> withInstanceAndLocalCapture() { 
int a = 1, b = 2; 
return <invokedynamic>LambdaMetafactory.metafactory(this,a,b); 
} 
/*synthetic*/ 
private int lambda$withInstanceAndLocalCapture$1( 
final int cap$0, final int cap$1, 
final String d, final String e) { 
return d.compareTo(e) + cap$0 + cap$1 - c; 
}
Parse Enter Process Attribute Flow Desugar Generate 
TransTypes Unlambda Lower 
• Example with instance and local capture 
final class LambdaExample$$Lambda$2/2117255219 extends Object implements 
Comparator { 
public int compare(Object, Object) 
private final LambdaExample arg$1; 
private final int arg$2; 
private final int arg$3; 
private LambdaExample$$Lambda$2/2117255219(LambdaExample,int,int) 
private static Comparator get$Lambda(LambdaExample,int,int) 
} 
.lambda$withInstanceAndLocalCapture$1(arg$arg$1 2, arg$3,(String)d,(String)e)
Parse Enter Process Attribute Flow Desugar Generate 
TransTypes Unlambda Lower 
• Possible to back port ? 
– Capture generated class ? 
– Compile time generation of inner class!
Parse Enter Process Attribute Flow Desugar Generate 
TransTypes Unlambda Lower 
• Possible to back port ? 
– Capture generated class ? 
– Compile time generation of inner class!
Parse Enter Process Attribute Flow Desugar Generate 
TransTypes Unlambda Lower 
• Step 1: Enable lambda : Source.java 
public boolean allowLambda() { 
return compareTo( ) >= 0; 
} 
JDK1_85
Parse Enter Process Attribute Flow Desugar Generate 
• Step 2: Enable special handling 
boolean mustBackportLambda() { 
return this.target.compareTo(Target.JDK1_8) < 0; 
} 
TransTypes Unlambda Lower
Parse Enter Process Attribute Flow Desugar Generate 
TransTypes Unlambda Lower 
• Step 3: Implement and call lambda method 
if(!this.attr.mustBackportLambda()) 
result = makeMetafactoryIndyCall(...); 
else 
{ 
result = new LambdaBackPorter(...).implementLambdaClass(...); 
}
Parse Enter Process Attribute Flow Desugar Generate 
TransTypes Unlambda Lower 
• Step 3: Example 
private static final class Lambda$$2 implements Comparator<String> { 
Lambda$$2 { 
super(); 
} 
public int compare(String arg0, String arg1) { 
return LambdaExample.lambda$lambdaExample$0(arg0, arg1); 
} 
public int compare(Object o1, Object o2) { 
return this.compare((String)o1, (String)o2); 
} 
}
Parse Enter Process Attribute Flow Desugar Generate 
TransTypes Unlambda Lower 
• Step 3: Example 
public Comparator<String> lambdaExample() { 
} 
return LnaewmbLdaamMbedta$fa$c2t8o9r(y).;metafactory();
ambda
Resources 
• OpenJDK 
– Source: http://hg.openjdk.java.net/ 
• Compiler hacking tutorial 
– http://www.ahristov.com/tutorial/java-compiler.html 
• Lambda design discussion 
– http://cr.openjdk.java.net/~briangoetz/lambda/lambda-translation. 
html 
• Sample code: 
– https://github.com/skarsaune/goto 
• Slide pack: 
– http://www.slideshare.net/MartinSkarsaune
Questions or 
Comments? 
Martin Skarsaune 
Java Developer and Co-Owner
Thank You for 
Your Time! 
Martin Skarsaune 
Java Developer and Co-Owner 
if(you.want(nineBot)) 
goto Kantega; 
Kantega: 
eat(bbq); 
test(java.skills);

Más contenido relacionado

La actualidad más candente

#ITsubbotnik Spring 2017: Roman Iovlev "Java edge in test automation"
#ITsubbotnik Spring 2017: Roman Iovlev "Java edge in test automation"#ITsubbotnik Spring 2017: Roman Iovlev "Java edge in test automation"
#ITsubbotnik Spring 2017: Roman Iovlev "Java edge in test automation"epamspb
 
RxJava и Android. Плюсы, минусы, подводные камни
RxJava и Android. Плюсы, минусы, подводные камниRxJava и Android. Плюсы, минусы, подводные камни
RxJava и Android. Плюсы, минусы, подводные камниStfalcon Meetups
 
Java Bytecode for Discriminating Developers - JavaZone 2011
Java Bytecode for Discriminating Developers - JavaZone 2011Java Bytecode for Discriminating Developers - JavaZone 2011
Java Bytecode for Discriminating Developers - JavaZone 2011Anton Arhipov
 
TDD CrashCourse Part4: Improving Testing
TDD CrashCourse Part4: Improving TestingTDD CrashCourse Part4: Improving Testing
TDD CrashCourse Part4: Improving TestingDavid Rodenas
 
GeeCON 2017 - TestContainers. Integration testing without the hassle
GeeCON 2017 - TestContainers. Integration testing without the hassleGeeCON 2017 - TestContainers. Integration testing without the hassle
GeeCON 2017 - TestContainers. Integration testing without the hassleAnton Arhipov
 
Java 7 Launch Event at LyonJUG, Lyon France. Fork / Join framework and Projec...
Java 7 Launch Event at LyonJUG, Lyon France. Fork / Join framework and Projec...Java 7 Launch Event at LyonJUG, Lyon France. Fork / Join framework and Projec...
Java 7 Launch Event at LyonJUG, Lyon France. Fork / Join framework and Projec...julien.ponge
 
Software Testing - Invited Lecture at UNSW Sydney
Software Testing - Invited Lecture at UNSW SydneySoftware Testing - Invited Lecture at UNSW Sydney
Software Testing - Invited Lecture at UNSW Sydneyjulien.ponge
 
15 tips to improve your unit tests (Droidcon Berlin 2016 Barcamp)
15 tips to improve your unit tests (Droidcon Berlin 2016 Barcamp)15 tips to improve your unit tests (Droidcon Berlin 2016 Barcamp)
15 tips to improve your unit tests (Droidcon Berlin 2016 Barcamp)Danny Preussler
 
ES3-2020-07 Testing techniques
ES3-2020-07 Testing techniquesES3-2020-07 Testing techniques
ES3-2020-07 Testing techniquesDavid Rodenas
 
Testing Java Code Effectively
Testing Java Code EffectivelyTesting Java Code Effectively
Testing Java Code EffectivelyAndres Almiray
 
Inside PyMongo - MongoNYC
Inside PyMongo - MongoNYCInside PyMongo - MongoNYC
Inside PyMongo - MongoNYCMike Dirolf
 
Pyconie 2012
Pyconie 2012Pyconie 2012
Pyconie 2012Yaqi Zhao
 
OrientDB - The 2nd generation of (multi-model) NoSQL
OrientDB - The 2nd generation of  (multi-model) NoSQLOrientDB - The 2nd generation of  (multi-model) NoSQL
OrientDB - The 2nd generation of (multi-model) NoSQLRoberto Franchini
 
ReactJS for Programmers
ReactJS for ProgrammersReactJS for Programmers
ReactJS for ProgrammersDavid Rodenas
 
Jdk 7 4-forkjoin
Jdk 7 4-forkjoinJdk 7 4-forkjoin
Jdk 7 4-forkjoinknight1128
 

La actualidad más candente (20)

#ITsubbotnik Spring 2017: Roman Iovlev "Java edge in test automation"
#ITsubbotnik Spring 2017: Roman Iovlev "Java edge in test automation"#ITsubbotnik Spring 2017: Roman Iovlev "Java edge in test automation"
#ITsubbotnik Spring 2017: Roman Iovlev "Java edge in test automation"
 
RxJava и Android. Плюсы, минусы, подводные камни
RxJava и Android. Плюсы, минусы, подводные камниRxJava и Android. Плюсы, минусы, подводные камни
RxJava и Android. Плюсы, минусы, подводные камни
 
Java Bytecode for Discriminating Developers - JavaZone 2011
Java Bytecode for Discriminating Developers - JavaZone 2011Java Bytecode for Discriminating Developers - JavaZone 2011
Java Bytecode for Discriminating Developers - JavaZone 2011
 
TDD CrashCourse Part4: Improving Testing
TDD CrashCourse Part4: Improving TestingTDD CrashCourse Part4: Improving Testing
TDD CrashCourse Part4: Improving Testing
 
GeeCON 2017 - TestContainers. Integration testing without the hassle
GeeCON 2017 - TestContainers. Integration testing without the hassleGeeCON 2017 - TestContainers. Integration testing without the hassle
GeeCON 2017 - TestContainers. Integration testing without the hassle
 
Java 7 Launch Event at LyonJUG, Lyon France. Fork / Join framework and Projec...
Java 7 Launch Event at LyonJUG, Lyon France. Fork / Join framework and Projec...Java 7 Launch Event at LyonJUG, Lyon France. Fork / Join framework and Projec...
Java 7 Launch Event at LyonJUG, Lyon France. Fork / Join framework and Projec...
 
Software Testing - Invited Lecture at UNSW Sydney
Software Testing - Invited Lecture at UNSW SydneySoftware Testing - Invited Lecture at UNSW Sydney
Software Testing - Invited Lecture at UNSW Sydney
 
Java 7 LavaJUG
Java 7 LavaJUGJava 7 LavaJUG
Java 7 LavaJUG
 
15 tips to improve your unit tests (Droidcon Berlin 2016 Barcamp)
15 tips to improve your unit tests (Droidcon Berlin 2016 Barcamp)15 tips to improve your unit tests (Droidcon Berlin 2016 Barcamp)
15 tips to improve your unit tests (Droidcon Berlin 2016 Barcamp)
 
All things that are not code
All things that are not codeAll things that are not code
All things that are not code
 
Introduzione al TDD
Introduzione al TDDIntroduzione al TDD
Introduzione al TDD
 
ES3-2020-07 Testing techniques
ES3-2020-07 Testing techniquesES3-2020-07 Testing techniques
ES3-2020-07 Testing techniques
 
Why Sifu
Why SifuWhy Sifu
Why Sifu
 
Testing Java Code Effectively
Testing Java Code EffectivelyTesting Java Code Effectively
Testing Java Code Effectively
 
Inside PyMongo - MongoNYC
Inside PyMongo - MongoNYCInside PyMongo - MongoNYC
Inside PyMongo - MongoNYC
 
Pyconie 2012
Pyconie 2012Pyconie 2012
Pyconie 2012
 
OrientDB - The 2nd generation of (multi-model) NoSQL
OrientDB - The 2nd generation of  (multi-model) NoSQLOrientDB - The 2nd generation of  (multi-model) NoSQL
OrientDB - The 2nd generation of (multi-model) NoSQL
 
Kotlin meets Gadsu
Kotlin meets GadsuKotlin meets Gadsu
Kotlin meets Gadsu
 
ReactJS for Programmers
ReactJS for ProgrammersReactJS for Programmers
ReactJS for Programmers
 
Jdk 7 4-forkjoin
Jdk 7 4-forkjoinJdk 7 4-forkjoin
Jdk 7 4-forkjoin
 

Destacado

From Jurassic Park to Microservices
From Jurassic Park to MicroservicesFrom Jurassic Park to Microservices
From Jurassic Park to MicroservicesSven Ruppert
 
From jUnit to Mutationtesting
From jUnit to MutationtestingFrom jUnit to Mutationtesting
From jUnit to MutationtestingSven Ruppert
 
From Mess To Masterpiece - JFokus 2017
From Mess To Masterpiece - JFokus 2017From Mess To Masterpiece - JFokus 2017
From Mess To Masterpiece - JFokus 2017Sven Ruppert
 
BUILDING MODERN WEB UIS WITH WEB COMPONENTS @ Devoxx
BUILDING MODERN WEB UIS WITH WEB COMPONENTS @ DevoxxBUILDING MODERN WEB UIS WITH WEB COMPONENTS @ Devoxx
BUILDING MODERN WEB UIS WITH WEB COMPONENTS @ DevoxxHendrik Ebbers
 
JavaFX JumpStart @JavaOne 2016
JavaFX JumpStart @JavaOne 2016JavaFX JumpStart @JavaOne 2016
JavaFX JumpStart @JavaOne 2016Hendrik Ebbers
 
Test Driven Development with JavaFX
Test Driven Development with JavaFXTest Driven Development with JavaFX
Test Driven Development with JavaFXHendrik Ebbers
 
DI Frameworks - hidden pearls
DI Frameworks - hidden pearlsDI Frameworks - hidden pearls
DI Frameworks - hidden pearlsSven Ruppert
 

Destacado (8)

From Jurassic Park to Microservices
From Jurassic Park to MicroservicesFrom Jurassic Park to Microservices
From Jurassic Park to Microservices
 
From jUnit to Mutationtesting
From jUnit to MutationtestingFrom jUnit to Mutationtesting
From jUnit to Mutationtesting
 
From Mess To Masterpiece - JFokus 2017
From Mess To Masterpiece - JFokus 2017From Mess To Masterpiece - JFokus 2017
From Mess To Masterpiece - JFokus 2017
 
BUILDING MODERN WEB UIS WITH WEB COMPONENTS @ Devoxx
BUILDING MODERN WEB UIS WITH WEB COMPONENTS @ DevoxxBUILDING MODERN WEB UIS WITH WEB COMPONENTS @ Devoxx
BUILDING MODERN WEB UIS WITH WEB COMPONENTS @ Devoxx
 
JavaFX JumpStart @JavaOne 2016
JavaFX JumpStart @JavaOne 2016JavaFX JumpStart @JavaOne 2016
JavaFX JumpStart @JavaOne 2016
 
Lesson Plans 3-4-5
Lesson Plans 3-4-5Lesson Plans 3-4-5
Lesson Plans 3-4-5
 
Test Driven Development with JavaFX
Test Driven Development with JavaFXTest Driven Development with JavaFX
Test Driven Development with JavaFX
 
DI Frameworks - hidden pearls
DI Frameworks - hidden pearlsDI Frameworks - hidden pearls
DI Frameworks - hidden pearls
 

Similar a JavaZone 2014 - goto java;

Go 1.10 Release Party - PDX Go
Go 1.10 Release Party - PDX GoGo 1.10 Release Party - PDX Go
Go 1.10 Release Party - PDX GoRodolfo Carvalho
 
Informatica_MDM_User_Exits.ppt
Informatica_MDM_User_Exits.pptInformatica_MDM_User_Exits.ppt
Informatica_MDM_User_Exits.pptDurganandYedlapati
 
Groovy & Grails: Scripting for Modern Web Applications
Groovy & Grails: Scripting for Modern Web ApplicationsGroovy & Grails: Scripting for Modern Web Applications
Groovy & Grails: Scripting for Modern Web Applicationsrohitnayak
 
The definitive guide to java agents
The definitive guide to java agentsThe definitive guide to java agents
The definitive guide to java agentsRafael Winterhalter
 
Construire une application JavaFX 8 avec gradle
Construire une application JavaFX 8 avec gradleConstruire une application JavaFX 8 avec gradle
Construire une application JavaFX 8 avec gradleThierry Wasylczenko
 
Durable functions 2.0 (2019-10-10)
Durable functions 2.0 (2019-10-10)Durable functions 2.0 (2019-10-10)
Durable functions 2.0 (2019-10-10)Paco de la Cruz
 
Introduction To Groovy 2005
Introduction To Groovy 2005Introduction To Groovy 2005
Introduction To Groovy 2005Tugdual Grall
 
Python-GTK
Python-GTKPython-GTK
Python-GTKYuren Ju
 
Patterns for JVM languages JokerConf
Patterns for JVM languages JokerConfPatterns for JVM languages JokerConf
Patterns for JVM languages JokerConfJaroslaw Palka
 
Bang-Bang, you have been hacked - Yonatan Levin, KolGene
Bang-Bang, you have been hacked - Yonatan Levin, KolGeneBang-Bang, you have been hacked - Yonatan Levin, KolGene
Bang-Bang, you have been hacked - Yonatan Levin, KolGeneDroidConTLV
 
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-Tsuyoshi Yamamoto
 
What’s new in Google Dart - Seth Ladd
What’s new in Google Dart - Seth LaddWhat’s new in Google Dart - Seth Ladd
What’s new in Google Dart - Seth Laddjaxconf
 
Native Java with GraalVM
Native Java with GraalVMNative Java with GraalVM
Native Java with GraalVMSylvain Wallez
 
Aspect-Oriented Programming
Aspect-Oriented ProgrammingAspect-Oriented Programming
Aspect-Oriented ProgrammingAndrey Bratukhin
 
JDD 2016 - Sebastian Malaca - You Dont Need Unit Tests
JDD 2016 - Sebastian Malaca - You Dont Need Unit TestsJDD 2016 - Sebastian Malaca - You Dont Need Unit Tests
JDD 2016 - Sebastian Malaca - You Dont Need Unit TestsPROIDEA
 

Similar a JavaZone 2014 - goto java; (20)

Clean coding-practices
Clean coding-practicesClean coding-practices
Clean coding-practices
 
Go 1.10 Release Party - PDX Go
Go 1.10 Release Party - PDX GoGo 1.10 Release Party - PDX Go
Go 1.10 Release Party - PDX Go
 
Informatica_MDM_User_Exits.ppt
Informatica_MDM_User_Exits.pptInformatica_MDM_User_Exits.ppt
Informatica_MDM_User_Exits.ppt
 
Spring Boot
Spring BootSpring Boot
Spring Boot
 
Groovy & Grails: Scripting for Modern Web Applications
Groovy & Grails: Scripting for Modern Web ApplicationsGroovy & Grails: Scripting for Modern Web Applications
Groovy & Grails: Scripting for Modern Web Applications
 
The definitive guide to java agents
The definitive guide to java agentsThe definitive guide to java agents
The definitive guide to java agents
 
Construire une application JavaFX 8 avec gradle
Construire une application JavaFX 8 avec gradleConstruire une application JavaFX 8 avec gradle
Construire une application JavaFX 8 avec gradle
 
Durable functions 2.0 (2019-10-10)
Durable functions 2.0 (2019-10-10)Durable functions 2.0 (2019-10-10)
Durable functions 2.0 (2019-10-10)
 
Griffon @ Svwjug
Griffon @ SvwjugGriffon @ Svwjug
Griffon @ Svwjug
 
Server1
Server1Server1
Server1
 
Introduction To Groovy 2005
Introduction To Groovy 2005Introduction To Groovy 2005
Introduction To Groovy 2005
 
Python-GTK
Python-GTKPython-GTK
Python-GTK
 
Patterns for JVM languages JokerConf
Patterns for JVM languages JokerConfPatterns for JVM languages JokerConf
Patterns for JVM languages JokerConf
 
Bang-Bang, you have been hacked - Yonatan Levin, KolGene
Bang-Bang, you have been hacked - Yonatan Levin, KolGeneBang-Bang, you have been hacked - Yonatan Levin, KolGene
Bang-Bang, you have been hacked - Yonatan Levin, KolGene
 
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-
 
What’s new in Google Dart - Seth Ladd
What’s new in Google Dart - Seth LaddWhat’s new in Google Dart - Seth Ladd
What’s new in Google Dart - Seth Ladd
 
Native Java with GraalVM
Native Java with GraalVMNative Java with GraalVM
Native Java with GraalVM
 
C# 6.0 Preview
C# 6.0 PreviewC# 6.0 Preview
C# 6.0 Preview
 
Aspect-Oriented Programming
Aspect-Oriented ProgrammingAspect-Oriented Programming
Aspect-Oriented Programming
 
JDD 2016 - Sebastian Malaca - You Dont Need Unit Tests
JDD 2016 - Sebastian Malaca - You Dont Need Unit TestsJDD 2016 - Sebastian Malaca - You Dont Need Unit Tests
JDD 2016 - Sebastian Malaca - You Dont Need Unit Tests
 

Más de Martin (高馬丁) Skarsaune (10)

jmc-devoxx.pptx
jmc-devoxx.pptxjmc-devoxx.pptx
jmc-devoxx.pptx
 
Flight recordings and mission control through thick clouds
Flight recordings and mission control through thick cloudsFlight recordings and mission control through thick clouds
Flight recordings and mission control through thick clouds
 
Cloud Collaboration with Eclipse Che
Cloud Collaboration with Eclipse CheCloud Collaboration with Eclipse Che
Cloud Collaboration with Eclipse Che
 
CodeOne Java Debugging Tips
CodeOne Java Debugging TipsCodeOne Java Debugging Tips
CodeOne Java Debugging Tips
 
Java Debugging Tips @oredev
Java Debugging Tips @oredevJava Debugging Tips @oredev
Java Debugging Tips @oredev
 
Tricks
TricksTricks
Tricks
 
Small Lambda Talk @Booster2015
Small Lambda Talk @Booster2015Small Lambda Talk @Booster2015
Small Lambda Talk @Booster2015
 
Small lambda talk
Small lambda talkSmall lambda talk
Small lambda talk
 
Bring your calculations to Scala!
Bring your calculations to Scala!Bring your calculations to Scala!
Bring your calculations to Scala!
 
JavaZone 2014 - Iteration 2.0: Stream
JavaZone 2014 - Iteration 2.0: StreamJavaZone 2014 - Iteration 2.0: Stream
JavaZone 2014 - Iteration 2.0: Stream
 

Último

Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsAlberto González Trastoy
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdfWave PLM
 
Cloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackCloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackVICTOR MAESTRE RAMIREZ
 
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataAdobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataBradBedford3
 
Active Directory Penetration Testing, cionsystems.com.pdf
Active Directory Penetration Testing, cionsystems.com.pdfActive Directory Penetration Testing, cionsystems.com.pdf
Active Directory Penetration Testing, cionsystems.com.pdfCionsystems
 
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AISyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AIABDERRAOUF MEHENNI
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVshikhaohhpro
 
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...stazi3110
 
Diamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionDiamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionSolGuruz
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfkalichargn70th171
 
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...OnePlan Solutions
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...MyIntelliSource, Inc.
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Modelsaagamshah0812
 
What is Binary Language? Computer Number Systems
What is Binary Language?  Computer Number SystemsWhat is Binary Language?  Computer Number Systems
What is Binary Language? Computer Number SystemsJheuzeDellosa
 
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...gurkirankumar98700
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerThousandEyes
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providermohitmore19
 
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...soniya singh
 
HR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comHR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comFatema Valibhai
 
Project Based Learning (A.I).pptx detail explanation
Project Based Learning (A.I).pptx detail explanationProject Based Learning (A.I).pptx detail explanation
Project Based Learning (A.I).pptx detail explanationkaushalgiri8080
 

Último (20)

Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf
 
Cloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackCloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStack
 
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataAdobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
 
Active Directory Penetration Testing, cionsystems.com.pdf
Active Directory Penetration Testing, cionsystems.com.pdfActive Directory Penetration Testing, cionsystems.com.pdf
Active Directory Penetration Testing, cionsystems.com.pdf
 
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AISyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTV
 
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
 
Diamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionDiamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with Precision
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
 
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Models
 
What is Binary Language? Computer Number Systems
What is Binary Language?  Computer Number SystemsWhat is Binary Language?  Computer Number Systems
What is Binary Language? Computer Number Systems
 
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service provider
 
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
 
HR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comHR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.com
 
Project Based Learning (A.I).pptx detail explanation
Project Based Learning (A.I).pptx detail explanationProject Based Learning (A.I).pptx detail explanation
Project Based Learning (A.I).pptx detail explanation
 

JavaZone 2014 - goto java;

  • 1. A peek into the OpenJDK compiler : goto java; Martin Skarsaune Java Developer and Co-Owner 高 馬 丁
  • 2.
  • 4. GOTO Statement –Objective • Syntax: goto identifier; • Runtime – Program control moves to target statement • Other Semantics – Target (statement label) must be defined in same scope, compilation error if not – Potential circular gotos should give compilation warning.
  • 5. GOTO Statement – Means 1. OpenJDK – Open source Java implementation – Compiler implemented in Java 2. Modify compiler source to support goto statements
  • 6. Success case public class GotoSuccess { public static void main(String[] args) { one: System.out.print("goto "); two: System.out.print("Java"); goto four; three: System.out.print("2014"); goto five; four: System.out.print("Zone "); goto three; five: System.out.print("!"); } }
  • 7. GOTO AHEAD Dijkstra 1968: programmerquality =100 1- gotos LoC æ è ç ö ø ÷
  • 8. What is a Compiler? Compiler
  • 9. What is a Compiler? front back
  • 10. Parse Enter Process Attribute Flow Desugar Generate processAnnotations(enterTrees(… parseFiles(…))),…) … generate(desugar(flow(attribute(…))))
  • 11. Parse Enter Process Attribute Flow Desugar Generate processAnnotations(enterTrees(… parseFiles(…))),…) … generate(desugar(flow(attribute(…))))
  • 12. Parse Enter Process Attribute Flow Desugar Generate • Syntax: goto identifier; • First convert character stream to token stream (Scanner.java) [g][o][t][o][ ][f][o][u][r][;] GOTO IDENTIFIER SEMI
  • 13. Parse Enter Process Attribute Flow Desugar Generate • goto is already a reserved word in Java! • Lucky for us, goto is therefore defined as a TokenKind. • Tokens.java:141: GOTO("goto") • The scanner therefore works out of the box!
  • 14. Parse Enter Process Attribute Flow Desugar Generate final Scanner scanner=factory.newScanner(”goto identifier;”, false); ... import com.sun.tools.javac.parser.Scanner; ...
  • 15. Parse Enter Process Attribute Flow Desugar Generate final Scanner scanner=factory.newScanner(”goto identifier;”, false); scanner.nextToken();
  • 16. Parse Enter Process Attribute Flow Desugar Generate final Scanner scanner=factory.newScanner(”goto identifier;”, false); scanner.nextToken(); assertThat(”First token is GOTO”, scanner.token().kind, is(GOTO));
  • 17. Parse Enter Process Attribute Flow Desugar Generate final Scanner scanner=factory.newScanner(”goto identifier;”, false); scanner.nextToken(); assertThat(”First token is GOTO”, scanner.token().kind, is(GOTO)); scanner.nextToken();
  • 18. Parse Enter Process Attribute Flow Desugar Generate final Scanner scanner=factory.newScanner(”goto identifier;”, false); scanner.nextToken(); assertThat(”First token is GOTO”, scanner.token().kind, is(GOTO)); scanner.nextToken(); assertThat("Second token is IDENTIFIER", scanner.token().kind, is(IDENTIFIER));
  • 19. Parse Enter Process Attribute Flow Desugar Generate final Scanner scanner=factory.newScanner(”goto identifier;”, false); scanner.nextToken(); assertThat(”First token is GOTO”, scanner.token().kind, is(GOTO)); scanner.nextToken(); assertThat("Second token is IDENTIFIER", scanner.token().kind, is(IDENTIFIER)); scanner.nextToken();
  • 20. Parse Enter Process Attribute Flow Desugar Generate final Scanner scanner=factory.newScanner(”goto identifier;”, false); scanner.nextToken(); assertThat(”First token is GOTO”, scanner.token().kind, is(GOTO)); scanner.nextToken(); assertThat("Second token is IDENTIFIER", scanner.token().kind, is(IDENTIFIER)); scanner.nextToken(); assertThat("Third token is SEMI", scanner.token().kind, is(SEMI));
  • 21. Parse Enter Process Attribute Flow Desugar Generate Abstract Syntax CompilationUnit ClassDefinition FieldDefintion MethodDefinition Signature Body IfStatement Goto Wikipedia: “the visitor design pattern is a way of separating an algorithm from an object structure on which it operates” visitClassDef(..) visitMethodDef( ..) visitIf(..) Tree GOTO IDENTIFIER SEMI [g][o][t][o][ ][f][o][u][r][;]
  • 22. Parse Enter Process Attribute Flow Desugar Generate Class Interface
  • 23. Parse Enter Process Attribute Flow Desugar Generate • Interface based visitors
  • 24. Parse Enter Process Attribute Flow Desugar Generate • Class based visitors public void visitGoto(JCGoto tree) { try { print("goto " + tree.label + ";"); } catch (IOException e) { throw new UncheckedIOException(e); } } public void visitGoto(JCGoto tree) { //TODO implement }
  • 25. Parse Enter Process Attribute Flow Desugar Generate public class GotoResolver { Map<GotoTree, Name> gotos; Map<Name, LabeledStatementTree> targets; List<StatementTree> statementsInSequence; ... } public static class JCLabeledStatement extends JCStatement implements LabeledStatementTree { … public GotoResolver handler; … }
  • 26. Parse Enter Process Attribute Flow Desugar Generate TreeMaker.java: public JCGoto Goto(Name label, GotoResolver resolver) { JCGoto tree = new JCGoto(label, resolver); tree.pos = pos; return tree; } • JavacParser.parseStatement() case GOTO: { nextToken(); Name label = ident(); JCGoto t = to(F.at(pos).Goto(label, getGotoResolver())); accept(SEMI); return t; }
  • 27. Parse Enter Process Attribute Flow Desugar Generate processAnnotations(enterTrees(… parseFiles(…))),…) … generate(desugar(flow(attribute(…))))
  • 28. Parse Enter Process Attribute Flow Desugar Generate • Basic sanity testing of compilation unit – File name and folder location – Duplicate class names • Corrections – Add default constructor if no constructors are declared
  • 29. Parse Enter Process Attribute Flow Desugar Generate • Default constructor public class SimpleClass { }
  • 30. Parse Enter Process Attribute Flow Desugar Generate • Default constructor public class SimpleClass { public SimpleClass() { super(); } }
  • 31. Parse Enter Process Attribute Flow Desugar Generate processAnnotations(enterTrees(… parseFiles(…))),…) … generate(desugar(flow(attribute(…))))
  • 32. Parse Enter Process Attribute Flow Desugar Generate • Annotation processing API • Part of ordinary javac process since Java 1.6 • Plugin API (see javac documentation)
  • 33. Parse Enter Process Attribute Flow Desugar Generate • Output controlled by command line switches @ - proc:none – do not process annotations - proc:only – only process annotations, do not compile
  • 34. Parse Enter Process Attribute Flow Desugar Generate processAnnotations(enterTrees(… parseFiles(…))),…) … generate(desugar(flow(attribute(…))))
  • 35. Parse Enter Process Attribute Flow Desugar Generate • Semantic checks – Types – References • Corrections – Add required calls to super constructor
  • 36. Parse Enter Process Attribute Flow Desugar Generate • We want to verify that goto target exists in current scope public class GotoMissingLabel { public static void main(String[] args) { one: System.out.print("goto "); two: System.out.print("Java"); goto six; three: System.out.print("2014"); goto five; four: System.out.print("Zone "); goto three; five: System.out.print("!"); } }
  • 37. Parse Enter Process Attribute Flow Desugar Generate • Attr.java: @Override public void visitGoto(JCGoto that) { that.findTarget(); if(that.target==null) log.error(that.pos(), "undef.label", that.label); result = null; } class JCGoto: … public void findTarget() { this.target = (JCLabeledStatement)this.handler.findTarget(this); }
  • 38. Parse Enter Process Attribute Flow Desugar Generate processAnnotations(enterTrees(… parseFiles(…))),…) … generate(desugar(flow(attribute(…))))
  • 39. Parse Enter Process Attribute Flow Desugar Generate Flow analysis • Detect unreachable code • Verify assignments • Ensure proper method return • Verify (effectively) final • Check exception flow
  • 40. Parse Enter Process Attribute Flow Desugar Generate We want to detect circular gotos: public class GotoCircularWarning { public static void main(String[] args) { one: System.out.print("goto "); two: System.out.print("Java"); goto four; three: System.out.print("2014"); goto five; four: System.out.print("Zone "); goto three; five: System.out.println("!"); goto one;//forms infinite loop } }
  • 41. Parse Enter Process Attribute Flow Desugar Generate Flow.FlowAnalyzer class: @Override public void visitGoto(JCGoto tree) { if (tree.handler.detectCircularGotoPosition(tree)) log.warning(tree.pos, "circular.goto"); } compiler.properties: ... compiler.warn.circular.goto=circular goto ...
  • 42. Parse Enter Process Attribute Flow Desugar Generate processAnnotations(enterTrees(… parseFiles(…))),…) … generate(desugar(flow(attribute(…))))
  • 43. Parse Enter Process Attribute Flow Desugar Generate TransTypes Unlambda Lower • Erase generic types public class Bridge implements Comparator { }
  • 44. Parse Enter Process Attribute Flow Desugar Generate TransTypes Unlambda Lower • Erase generic types public class Bridge implements Comparator { } public interface Comparator<T> {t int compare(T o1, T o2); }or<T> {
  • 45. Parse Enter Process Attribute Flow Desugar Generate TransTypes Unlambda Lower • Erase generic types public class Bridge implements Comparator<Integer> { } public interface Comparator<T> {t int compare(T o1, T o2); }or<T> {
  • 46. Parse Enter Process Attribute Flow Desugar Generate TransTypes Unlambda Lower • Erase generic types public class Bridge implements Comparator<Integer> { public int compare(Integer first, Integer second) { return first - second; } } public interface Comparator<T> {t int compare(T o1, T o2); }or<T> {
  • 47. Parse Enter Process Attribute Flow Desugar Generate TransTypes Unlambda Lower • Erase generic types public class Bridge implements Comparator { public int compare(Integer first, Integer second) { return first - second; } }
  • 48. Parse Enter Process Attribute Flow Desugar Generate TransTypes Unlambda Lower • Erase generic types public class Bridge implements Comparator { public int compare(Integer first, Integer second) { return first - second; } /*synthetic*/ public int compare(Object first, Object second) { return this.compare((Integer)first, (Integer)second); } }
  • 49. Parse Enter Process Attribute Flow Desugar Generate TransTypes Unlambda Lower • Extract Inner Class public class Outer { private void foo() { } public Runnable fooRunner() { return new Runnable() { public void run() { foo(); } }; } }
  • 50. Parse Enter Process Attribute Flow Desugar Generate TransTypes Unlambda Lower • Extract Inner Class public class Outer { private void foo() { } public Runnable fooRunner() { return new Runnable() { public void run() { foo(); } }; } }
  • 51. Parse Enter Process Attribute Flow Desugar Generate TransTypes Unlambda Lower • Extract Inner Class public class Outer { private void foo() { } public Runnable fooRunner() { return new Outer$1(this); } } class Outer$1 implements Runnable { final Outer this$0; public void run() { this$0.foo(); } }
  • 52. Parse Enter Process Attribute Flow Desugar Generate TransTypes Unlambda Lower • Extract Inner Class public class Outer { private void foo() { } public Runnable fooRunner() { return new Outer$1(this); } } class Outer$1 implements Runnable { final Outer this$0; Outer$1(final Outer this$0) { this.this$0 = this$0; super(); } public void run() { this$0.foo(); } }
  • 53. Parse Enter Process Attribute Flow Desugar Generate TransTypes Unlambda Lower • Extract Inner Class public class Outer { private void foo() { } public Runnable fooRunner() { return new Outer$1(this); } } class Outer$1 implements Runnable { final Outer this$0; Outer$1(final Outer this$0) { this.this$0 = this$0; super(); } public void run() { this$0.foo(); } }
  • 54. Parse Enter Process Attribute Flow Desugar Generate TransTypes Unlambda Lower • Extract Inner Class public class Outer { private void foo() { } public Runnable fooRunner() { return new Outer$1(this); } static void access$000( Outer x0) { x0.foo(); } } class Outer$1 implements Runnable { final Outer this$0; Outer$1(final Outer this$0) { this.this$0 = this$0; super(); } public void run() { Outer.access$000(this$0); } }
  • 55. Parse Enter Process Attribute Flow Desugar Generate TransTypes Unlambda Lower • Boxing List<Integer> list = Arrays.asList(1, 2); for (Integer i : list) { System.out.println("Double: " + i * 2); }
  • 56. Parse Enter Process Attribute Flow Desugar Generate TransTypes Unlambda Lower • Boxing List<Integer> list = Arrays.asList(1, 2); for (Integer i : list) { System.out.println("Double: " + i * 2); } public static <T> List<T> asList(T... a) { return new ArrayList<>(a); }
  • 57. Parse Enter Process Attribute Flow Desugar Generate TransTypes Unlambda Lower • Boxing List<Integer> list = Arrays.asList(Integer.valueOf(1), Integer.valueOf(2)); for (Integer i : list) { System.out.println("Double: " + i * 2); }
  • 58. Parse Enter Process Attribute Flow Desugar Generate TransTypes Unlambda Lower • Unboxing List<Integer> list = Arrays.asList(Integer.valueOf(1), Integer.valueOf(2)); for (Integer i : list) { System.out.println("Double: " + i * 2); }
  • 59. Parse Enter Process Attribute Flow Desugar Generate TransTypes Unlambda Lower • Unboxing List<Integer> list = Arrays.asList(Integer.valueOf(1), Integer.valueOf(2)); for (Integer i : list) { System.out.println("Double: " + i.intValue() * 2); }
  • 60. Parse Enter Process Attribute Flow Desugar Generate TransTypes Unlambda Lower • Varargs List<Integer> list = Arrays.asList(Integer.valueOf(1), Integer.valueOf(2)); for (Integer i : list) { System.out.println("Double: " + i.intValue() * 2); }
  • 61. Parse Enter Process Attribute Flow Desugar Generate TransTypes Unlambda Lower • Varargs List<Integer> list = Arrays.asList(Integer.valueOf(1), Integer.valueOf(2)); for (Integer i : list) { System.out.println("Double: " + i.intValue() * 2); } public static <T> List<T> asList(T... a) { return new ArrayList<>(a); }
  • 62. Parse Enter Process Attribute Flow Desugar Generate TransTypes Unlambda Lower • Varargs List<Integer> list = Arrays.asList(new Integer[]{Integer.valueOf(1), Integer.valueOf(2)}); for (Integer i : list) { System.out.println("Double: " + i.intValue() * 2); }
  • 63. Parse Enter Process Attribute Flow Desugar Generate TransTypes Unlambda Lower • For each loop List<Integer> list = Arrays.asList(new Integer[]{Integer.valueOf(1), Integer.valueOf(2)}); for (Integer i : list) { System.out.println("Double: " + i.intValue() * 2); }
  • 64. Parse Enter Process Attribute Flow Desugar Generate TransTypes Unlambda Lower • For each loop public interface Iterable<T> { Iterator<T> iterator(); } List<Integer> list = Arrays.asList(new Integer[]{Integer.valueOf(1), Integer.valueOf(2)}); for (Integer i : list) { System.out.println("Double: " + i.intValue() * 2); } static <T> List<T> asList(T... a) { return new ArrayList<>(a); }
  • 65. Parse Enter Process Attribute Flow Desugar Generate TransTypes Unlambda Lower • For each loop List<Integer> list = Arrays.asList(new Integer[]{Integer.valueOf(1), Integer.valueOf(2)}); for (;;) { Integer i System.out.println("Double: " + i.intValue() * 2); }
  • 66. Parse Enter Process Attribute Flow Desugar Generate TransTypes Unlambda Lower • For each loop List<Integer> list = Arrays.asList(new Integer[]{Integer.valueOf(1), Integer.valueOf(2)}); for (Iterator i$ = list.iterator();;) { Integer i System.out.println("Double: " + i.intValue() * 2); }
  • 67. Parse Enter Process Attribute Flow Desugar Generate TransTypes Unlambda Lower • For each loop List<Integer> list = Arrays.asList(new Integer[]{Integer.valueOf(1), Integer.valueOf(2)}); for (Iterator i$ = list.iterator(); i$.hasNext();) { Integer i System.out.println("Double: " + i.intValue() * 2); }
  • 68. Parse Enter Process Attribute Flow Desugar Generate TransTypes Unlambda Lower • For each loop List<Integer> list = Arrays.asList(new Integer[]{Integer.valueOf(1), Integer.valueOf(2)}); for (Iterator i$ = list.iterator(); i$.hasNext();) { Integer i = (Integer)i$.next(); System.out.println("Double: " + i.intValue() * 2); }
  • 69. Parse Enter Process Attribute Flow Desugar Generate TransTypes Unlambda Lower • Enums public enum Status { YES, NO, MAYBE }
  • 70. Parse Enter Process Attribute Flow Desugar Generate TransTypes Unlambda Lower • Enums public enum Status { YES, NO, MAYBE private Status(String $enum$name, int $enum$ordinal) { super($enum$name, $enum$ordinal); } }
  • 71. Parse Enter Process Attribute Flow Desugar Generate TransTypes Unlambda Lower • Enums public enum Status { YES, NO, MAYBE private Status(String $enum$name, int $enum$ordinal) { super($enum$name, $enum$ordinal); } public static Status valueOf(String name) { return (Status)Enum.valueOf(Status.class, name); } }
  • 72. Parse Enter Process Attribute Flow Desugar Generate TransTypes Unlambda Lower • Enums public enum Status { YES, NO, MAYBE private Status(String $enum$name, int $enum$ordinal) { super($enum$name, $enum$ordinal); } public static Status valueOf(String name) { return (Status)Enum.valueOf(Status.class, name); } private static final Status[] $VALUES = new Status[]{ Status.YES, Status.NO, Status.MAYBE}; public static Status[] values() { return (Status[])$VALUES.clone(); }
  • 73. Parse Enter Process Attribute Flow Desugar Generate TransTypes Unlambda Lower • Enum based switch statements public class SwitchStatus { void switchStatus(Status status) { switch (status) { case MAYBE: return; default: break; } } }
  • 74. Parse Enter Process Attribute Flow Desugar Generate TransTypes Unlambda Lower • Enum based switch statements public class SwitchStatus { void switchStatus(Status status) { switch (status) { case MAYBE: return; default: break; } } }
  • 75. Parse Enter Process Attribute Flow Desugar Generate TransTypes Unlambda Lower • Enum based switch statements public class SwitchStatus { void switchStatus(Status status) { switch (SwitchStatus$1.$SwitchMap$Status[(status).ordinal()]) { case 1: return; default: break; } } }
  • 76. Parse Enter Process Attribute Flow Desugar Generate TransTypes Unlambda Lower class SwitchStatus$1 { • Enum based switch statements public class SwitchStatus { void switchStatus(Status status) { switch (SwitchStatus$1.$SwitchMap$Status[(status).ordinal()]) { case 1: return; default: break; } } } }
  • 77. Parse Enter Process Attribute Flow Desugar Generate TransTypes Unlambda Lower class SwitchStatus$1 { static final int[] $SwitchMap$Status = new int[Status.values().length]; • Enum based switch statements public class SwitchStatus { void switchStatus(Status status) { switch (SwitchStatus$1.$SwitchMap$Status[(status).ordinal()]) { case 1: return; default: break; } } } }
  • 78. Parse Enter Process Attribute Flow Desugar Generate TransTypes Unlambda Lower class SwitchStatus$1 { static final int[] $SwitchMap$Status = new int[Status.values().length]; [0][0][0] • Enum based switch statements public class SwitchStatus { void switchStatus(Status status) { switch (SwitchStatus$1.$SwitchMap$Status[(status).ordinal()]) { case 1: return; default: break; } } } }
  • 79. Parse Enter Process Attribute Flow Desugar Generate TransTypes Unlambda Lower class SwitchStatus$1 { static final int[] $SwitchMap$Status = new int[Status.values().length]; [0][0][1] static { • Enum based switch statements try { SwitchStatus$1.$SwitchMap$Status[Status.MAYBE.ordinal()] = 1; } catch public (NoSuchFieldError class SwitchStatus ex) { { } } } void switchStatus(Status status) { switch (SwitchStatus$1.$SwitchMap$Status[(status).ordinal()]) { case 1: return; default: break; } } }
  • 80. Parse Enter Process Attribute Flow Desugar Generate TransTypes Unlambda Lower class SwitchStatus$1 { static final int[] $SwitchMap$Status = new int[Status.values().length]; [0][0][1] static { • Enum based switch statements try { SwitchStatus$1.$SwitchMap$Status[Status.MAYBE.ordinal()] = 1; } catch public (NoSuchFieldError class SwitchStatus ex) { { } } } void switchStatus(Status status) { switch (SwitchStatus$1.$SwitchMap$Status[(status).ordinal()]) { case 1: return; default: break; } } }
  • 81. Parse Enter Process Attribute Flow Desugar Generate processAnnotations(enterTrees(… parseFiles(…))),…) … generate(desugar(flow(attribute(…))))
  • 82. Parse Enter Process Attribute Flow Desugar Generate • Generate bytecodes • Organize initializers • String concatenation • Some optimizations
  • 83. Parse Enter Process Attribute Flow Desugar Generate • Organize <init> (Constructor) public class InstanceInitialization { String key="key"; String value; public InstanceInitialization(String value) { this.value = value; } }
  • 84. Parse Enter Process Attribute Flow Desugar Generate • Organize <init> (Constructor) public class InstanceInitialization { String key="key"; String value; public InstanceInitialization(String value) { super(); this.value = value; } }
  • 85. Parse Enter Process Attribute Flow Desugar Generate • Organize <init> (Constructor) public class InstanceInitialization { String key; String value; public InstanceInitialization(String value) { super(); key = ”key”; this.value = value; } }
  • 86. Parse Enter Process Attribute Flow Desugar Generate • Organize <init> (Constructor) public class InstanceInitialization { String key; String value; public <init>(String value) { super(); key = ”key”; this.value = value; } }
  • 87. Parse Enter Process Attribute Flow Desugar Generate • Organize <clinit> (Static initialization) public class StaticInitialization { static String key="key"; static String value; static { value = value; } }
  • 88. Parse Enter Process Attribute Flow Desugar Generate • Organize <clinit> (Static initialization) public class StaticInitialization { static String key; static String value; static { key="key”; value = value; } }
  • 89. Parse Enter Process Attribute Flow Desugar Generate • Organize <clinit> (Static initialization) public class StaticInitialization { static String key; static String value; static void <clinit>{ key="key”; value = value; } }
  • 90. Parse Enter Process Attribute Flow Desugar Generate • String concatenation Source code “Generated code” ”string” + value
  • 91. Parse Enter Process Attribute Flow Desugar Generate Source code “Generated code” ”string” + value new StringBuilder()
  • 92. Parse Enter Process Attribute Flow Desugar Generate Source code “Generated code” ”string” + value new StringBuilder() .append(”string”)
  • 93. Parse Enter Process Attribute Flow Desugar Generate Source code “Generated code” ”string” + value new StringBuilder() .append(”string”) .append(value)
  • 94. Parse Enter Process Attribute Flow Desugar Generate Source code “Generated code” ”string” + value new StringBuilder() .append(”string”) .append(value) .toString()
  • 95. Goto Generation • Lucky for us there is a byte code for goto • goto <addr>
  • 96. Parse Enter Process Attribute Flow Desugar Generate Source code PC Byte code … if (<test>) { <ifblock> } else { <elseblock> } <codeafter> … … 9 ifeq 22 … <elseblock> … goto 29 <stackmap> 22 <ifblock> <stackmap> 29 <codeafter> Code generator (Code.java) Java >= 1.6: marked as not alive. Stack map frames must be embedded at target of jump Goto instruction added to list of pending jumps (Chain.java) instruction Pending jumps processed
  • 97. Parse Enter Process Attribute Flow Desugar Generate • Scenario 1: go back Source code PC Byte code … label: <somecode> … goto label; … 20 <stackmap> <somecode> … goto 20 Used by goto? Must emit stackmap Emit goto to label and turn code generation on again
  • 98. Parse Enter Process Attribute Flow Desugar Generate • Scenario 2: go forward Source code PC Byte code Label used? • emit stack frame • patch pending gotos … goto label; … label: <somecode> … … goto <stackmap> 29 <somecode> Label position not yet known? • emit goto • add to list of pending gotos • turn generation on again 29
  • 99. Parse Enter Process Attribute Flow Desugar Generate Gen.java - Labelled public void visitLabelled(JCLabeledStatement tree) { // if the label is used from gotos, have to emit stack map if (tree.handler.isUsed(tree)) code.emitStackMap(); … }
  • 100. Parse Enter Process Attribute Flow Desugar Generate Gen.java - Goto public void visitGoto(JCGoto tree) { tree.handler.addBranch(new Chain(code.emitJump(goto_), null, code.state.dup()), tree.target); //normally goto marks code as not alive, turn generation on code.entryPoint(); } Target position known? • Yes – patch immediately • No – add to list of pending gotos
  • 102. ambda
  • 103. Parse Enter Process Attribute Flow Desugar Generate TransTypes Unlambda Lower • Lambda implementation in Java 8 – Language change – Compilation – Runtime support • Many interesting design considerations
  • 104. Parse Enter Process Attribute Flow Desugar Generate TransTypes Unlambda Lower • Simple example public Comparator<String> lambdaExample() { return (String a, String b) -> a.compareTo(b); }
  • 105. Parse Enter Process Attribute Flow Desugar Generate TransTypes Unlambda Lower • LambdaToMethod.java public Comparator<String> lambdaExample() { return (String a, String b) -> a.compareTo(b); } /*synthetic*/ private static int lambda$lambdaExample$0( , ) { return ; } final String a final String b a.compareTo(b)
  • 106. Parse Enter Process Attribute Flow Desugar Generate TransTypes Unlambda Lower public interface Comparator {/*erased*/ • int compare(Runtime Object o1, Object o2); } public Comparator<String> lambdaExample() { return <invokedynamic>LambdaMetafactory.metafactory( } final class LambdaExample$$Lambda$1/1834188994 implements Comparator { private LambdaExample$$Lambda$1/1834188994() public int compare(Object,Object) } /*synthetic*/ private static int lambda$lambdaExample$0( final String a, final String b) { return a.compareTo(b); } Lookup(LambdaExample), /*caller*/ "compare", ()Comparator, /*MethodType*/ (Object,Object)int, /*MethodType*/ lambda$lambdaExample$0, /*MethodHandle*/ (String,String)int); /*MethodType*/
  • 107. Parse Enter Process Attribute Flow Desugar Generate TransTypes Unlambda Lower • Runtime class generation LambdaMetaFactory • metaFactory(…) • altMetaFactory(…) InnerClassLambdaMetafactory ASM Lambda Class
  • 108. Parse Enter Process Attribute Flow Desugar Generate TransTypes Unlambda Lower • Serialization Lambda Instance Serialize Serialized Lambda Lambda Meta Factory Deserialize
  • 109. Parse Enter Process Attribute Flow Desugar Generate TransTypes Unlambda Lower • Example with instance and local capture private int c = 3; public Comparator<String> withInstanceAndLocalCapture() { int a = 1, b = 2; return (String d, String e) -> d.compareTo(e) + a + b - c; }
  • 110. Parse Enter Process Attribute Flow Desugar Generate TransTypes Unlambda Lower • Example with instance and local capture private int c = 3; public Comparator<String> withInstanceAndLocalCapture() { int a = 1, b = 2; return (String d, String e) -> d.compareTo(e) + a + b - c; } /*synthetic*/ private int lambda$withInstanceAndLocalCapture$1( final int cap$0, final int cap$1, final String d, final String e) { return d.compareTo(e) + cap$0 + cap$1 - c; }
  • 111. Parse Enter Process Attribute Flow Desugar Generate TransTypes Unlambda Lower • Example with instance and local capture private int c = 3; public Comparator<String> withInstanceAndLocalCapture() { int a = 1, b = 2; return <invokedynamic>LambdaMetafactory.metafactory(this,a,b); } /*synthetic*/ private int lambda$withInstanceAndLocalCapture$1( final int cap$0, final int cap$1, final String d, final String e) { return d.compareTo(e) + cap$0 + cap$1 - c; }
  • 112. Parse Enter Process Attribute Flow Desugar Generate TransTypes Unlambda Lower • Example with instance and local capture final class LambdaExample$$Lambda$2/2117255219 extends Object implements Comparator { public int compare(Object, Object) private final LambdaExample arg$1; private final int arg$2; private final int arg$3; private LambdaExample$$Lambda$2/2117255219(LambdaExample,int,int) private static Comparator get$Lambda(LambdaExample,int,int) } .lambda$withInstanceAndLocalCapture$1(arg$arg$1 2, arg$3,(String)d,(String)e)
  • 113. Parse Enter Process Attribute Flow Desugar Generate TransTypes Unlambda Lower • Possible to back port ? – Capture generated class ? – Compile time generation of inner class!
  • 114. Parse Enter Process Attribute Flow Desugar Generate TransTypes Unlambda Lower • Possible to back port ? – Capture generated class ? – Compile time generation of inner class!
  • 115. Parse Enter Process Attribute Flow Desugar Generate TransTypes Unlambda Lower • Step 1: Enable lambda : Source.java public boolean allowLambda() { return compareTo( ) >= 0; } JDK1_85
  • 116. Parse Enter Process Attribute Flow Desugar Generate • Step 2: Enable special handling boolean mustBackportLambda() { return this.target.compareTo(Target.JDK1_8) < 0; } TransTypes Unlambda Lower
  • 117. Parse Enter Process Attribute Flow Desugar Generate TransTypes Unlambda Lower • Step 3: Implement and call lambda method if(!this.attr.mustBackportLambda()) result = makeMetafactoryIndyCall(...); else { result = new LambdaBackPorter(...).implementLambdaClass(...); }
  • 118. Parse Enter Process Attribute Flow Desugar Generate TransTypes Unlambda Lower • Step 3: Example private static final class Lambda$$2 implements Comparator<String> { Lambda$$2 { super(); } public int compare(String arg0, String arg1) { return LambdaExample.lambda$lambdaExample$0(arg0, arg1); } public int compare(Object o1, Object o2) { return this.compare((String)o1, (String)o2); } }
  • 119. Parse Enter Process Attribute Flow Desugar Generate TransTypes Unlambda Lower • Step 3: Example public Comparator<String> lambdaExample() { } return LnaewmbLdaamMbedta$fa$c2t8o9r(y).;metafactory();
  • 120. ambda
  • 121. Resources • OpenJDK – Source: http://hg.openjdk.java.net/ • Compiler hacking tutorial – http://www.ahristov.com/tutorial/java-compiler.html • Lambda design discussion – http://cr.openjdk.java.net/~briangoetz/lambda/lambda-translation. html • Sample code: – https://github.com/skarsaune/goto • Slide pack: – http://www.slideshare.net/MartinSkarsaune
  • 122. Questions or Comments? Martin Skarsaune Java Developer and Co-Owner
  • 123. Thank You for Your Time! Martin Skarsaune Java Developer and Co-Owner if(you.want(nineBot)) goto Kantega; Kantega: eat(bbq); test(java.skills);

Notas del editor

  1. Hello everyone. My name is Martin Skarsaune, developer working for Kantega. Today we are going to have a peek into the compiler. I assume everyone here rely on a Java compiler in their everyday work. Just out of curiosity, have anyone had a look at the compiler source code ? I guess a lot of clever developers out here have read articles, have debugged a lot of Java applications and disassempled class files to see what your Java code turns into on the other end. So some of the stuff may be known to you, never the less I think it is worth while to look at the process step by step from the inside and see with out own eyes what goes on.
  2. So we want to implement GOTO statements. So lets define what and how we want to achieve it. We want to use the following syntax: The keyword goto followed by an identifier and terminated by semicolon as other statements in Java. The good news is that goto is already a reserved word in Java, so we do not have to worry about breaking old programs, as no one will have used the string goto in existing code. As for the runtime behaviour, naturally a goto should make the program jump to the target statement. We also require some more compiler rules. First of all we require the target statement label to be defined in the same scope or block. This is a sensible simplification for the purpose of this presentation, as the runtime implications would be very complex if you allowed jumps in and out of scopes. If we do not find the label in the scope, we must give a compilation error. Then we also want to do some analysis to detect potential circular gotos. In which case we should give a warning for the statement. We choose warning instead of error here, as if you are inclined to use goto statements, you are probably quite crazy and not very happy about over protective compilers.
  3. So we want to implement GOTO statements. So lets define what and how we want to achieve it. We want to use the following syntax: The keyword goto followed by an identifier and terminated by semicolon as other statements in Java. The good news is that goto is already a reserved word in Java, so we do not have to worry about breaking old programs, as no one will have used the string goto in existing code. As for the runtime behaviour, naturally a goto should make the program jump to the target statement. We also require some more compiler rules. First of all we require the target statement label to be defined in the same scope or block. This is a sensible simplification for the purpose of this presentation, as the runtime implications would be very complex if you allowed jumps in and out of scopes. If we do not find the label in the scope, we must give a compilation error. Then we also want to do some analysis to detect potential circular gotos. In which case we should give a warning for the statement. We choose warning instead of error here, as if you are inclined to use goto statements, you are probably quite crazy and not very happy about over protective compilers.
  4. First we have a success test case, This code should compile without any errors or warnings. When running the code goto statements should execute successfully. To make things clear, we have labelled all statements in the example. If we try to follow the execution
  5. A compiler is a tool that accepts input in some sort of programming language and produces output targeted for another language or instruction set.
  6. A common compiler architecture is to try to decouple the input from the output. The front end deals with specifics handling, checks and optimizations for the given programming language, and the back end deals with generation, dependencies and optimizations for a given target platform. This separation is an obvious choice for compilers that generate native code. I was involved in a big project over several years, where we developed tools and routines for automated translation from Smalltalk to Java. In that project we did exactly this, we reused the parser and internal representation from the built in Smalltalk compiler, but instead of generating Smalltalk byte codes, we generated Java source code.
  7. For the Java compiler there are a number of main stages that form a pipeline, where the output of one stage is input to the next, this is illustrated by the code snippet below. This first diagram shows the initial stages of a compilation. As you know a pipeline is a powerful abstraction where you may separate the work into logic chunks.
  8. For the Java compiler there are a number of main stages that form a pipeline, where the output of one stage is input to the next, this is illustrated by the code snippet below. This first diagram shows the initial stages of a compilation. As you know a pipeline is a powerful abstraction where you may separate the work into logic chunks.
  9. Did you know that goto is a reserved word in Java? You may really wonder what they were thinking about? But we will certainly make good use of it! What other benefits are there to the fact that goto is a reserved word? That means that until this day no one have been able to compile Java code with goto statements. This way our changes to the language will not break any old code. We will only break new code in spectacular ways.
  10. So what is a sensible object structure for a compiler in transition between front and back end ? Commonly an Abstract Syntax Tree (or AST) is used. It is called abstract as it aims to be an abstraction away from specifics of both front and back end. This simplified example tries to illustrate a typical structure and contents of an AST. If you have for instance worked with Eclipse JDT plugins or ASM, you will recognize the similarities. We see that terms used are quite generic, and not specifically tied to either input or output. The sample items here are typically found in any modern programming language. Even if you have no hands on experience with compilers, you will probably recognize the main components here from your own mental model and understanding of Java applications. At the top (or left in this picture) we see a compilation unit, which in our case would be a Java source file. Each compilation unit contains one or more class definitions, we do not distinguish between classes and interfaces on this level. Each Class definition may in turn contain fields and method. Within each method there are zero or more statements. We also see that the syntax tree is strongly typed and attempts to give as precise, rich and detailed representation of the underlying source as possible. For instance an if statement would have dedicated expression for the condition, and separate blocks for the if and else part. Typically the syntax tree is gradually refined and enriched in several stages to simplify type inference, analysis and generation. As we will see later, processing of the syntax tree is often based on visitors. This has the advantage that you may insert logic directly where it is relevant, without having to tackle the entire structure. The visitor works its way down the tree with callbacks at each level, like this. So if you want to make changes only relevant for method definitions, you insert your code in the respective method.
  11. So what should we do to implement this in the compiler. First of all, since we introduce a new syntactic element we have to create a new kind of syntax node. There are parallell hierarchies for implementation and interface of different nodes. So we create the interface GotoTree and the class JCGoto respectively. The target of the goto is represented as a Name type.
  12. So what should we do to implement this in the compiler. First of all, since we introduce a new syntactic element we have to create a new kind of syntax node. There are parallell hierarchies for implementation and interface of different nodes. So we create the interface GotoTree and the class JCGoto respectively. The target of the goto is represented as a Name type.
  13. In addition, to simplify the presentation a bit, it is helpful with a helper object to keep track of labeled statements and goto statements in a given scope. We will come back to why this is helpful. Also for the purposes of presentation it is helpful to separate the goto specific code from where we need to interface with the existing code.
  14. For the Java compiler there are a number of main stages, where the output of one stage is input to the next, this is illustrated by the code snippet below. This first diagram shows the initial stages of a compilation. Below each stage is the enum value used to represent the state of the compiler during the phase.
  15. So we want to implement GOTO statements. So lets define what and how we want to achieve it. We want to use the following syntax: The keyword goto followed by an identifier and terminated by semicolon as other statements in Java. The good news is that goto is already a reserved word in Java, so we do not have to worry about breaking old programs, as no one will have used the string goto in existing code. As for the runtime behaviour, naturally a goto should make the program jump to the target statement. We also require some more compiler rules. First of all we require the target statement label to be defined in the same scope or block. This is a sensible simplification for the purpose of this presentation, as the runtime implications would be very complex if you allowed jumps in and out of scopes. If we do not find the label in the scope, we must give a compilation error. Then we also want to do some analysis to detect potential circular gotos. In which case we should give a warning for the statement. We choose warning instead of error here, as if you are inclined to use goto statements, you are probably quite crazy and not very happy about over protective compilers.