SlideShare a Scribd company logo
1 of 67
Download to read offline
The following presentation is provided under DHMB license 
(Do Not Hurt My Brain). 
Lecturer is not responsible for the financial and moral 
damages resulting from taking too seriously the content of 
the presentation. 
Including permanent damage to neurons, reduction of 
neurotransmitter activity at the molecular level and group 
dismissal.
Software engineers 
united we stand 
divided we fall
Patterns for JVM languages 
Jarosław Pałka
about me 
work://chief_architect@lumesse 
owner://symentis.pl 
twitter://j_palka 
blog://geekyprimitives.wordpress.com 
scm:bitbucket://kcrimson 
scm:github://kcrimson
Pet project
Because having pet projects is like solving crosswords 
everyday 
Or going to a gym 
Helps your brain to stay in shape
JVM 
is 
the 
new 
assembler
Translator
source code 
↓ 
target language source code 
↓ 
machine code || interpreter
Interpreter
source code 
↓ 
execution results
Compiler
source code 
↓ 
machine code
So how does it all work?
Diving into the stream
The ALL(*) lexer and parser generator 
Which supports multiple target languages
source code 
↓lexer 
token stream 
↓parser 
IR
Intermediate Representation 
visitor 
listener 
tree
Syntax tree
local y = 1 
x = 1 + y
fragment 
DIGIT 
: 
[0-9] 
; 
fragment 
LETTER 
: 
[a-zA-Z] 
; 
String 
: 
''' .*? ''' 
| '"' .*? '"' 
; 
Number 
: 
DIGIT+ 
; 
Name 
: 
( 
'_' 
| LETTER 
)( 
'_' 
| LETTER 
| DIGIT 
)* 
; 
COMMENT 
: 
'--' .*? 'n' -> skip 
; 
NL 
: 
'r'? 'n' -> skip 
; 
WS 
: 
[ tf]+ -> skip 
;
[@0,[0..1)='x',<49>] 
[@1,[2..3)='=',<36>] 
[@2,[4..5)='1',<48>] 
[@3,[6..7)='+',<33>] 
[@4,[8..15)='"Hello"',<47>] 
[@5,[15..16)=';',<37>] 
[@6,[17..17)='',<-1=EOF>]
varlist returns [Varlist result] 
: 
var 
{$result = createVarlist($var.result);} 
( 
',' var 
{$result = createVarlist($result,$var.result);} 
)* 
; 
// 
var returns [Var result] 
: 
Name 
{ $result = createVariableName($Name.text); } 
| prefixexp '[' exp ']' 
| prefixexp '.' Name 
;
beware of left recursion
translator 
interpreter 
compiler
Interpreter pattern 
Non terminal nodes 
Terminal nodes
package pl.symentis.lua.grammar; 
import pl.symentis.lua.runtime.Context; 
public interface Statement { 
void execute(Context context); 
}
package pl.symentis.lua.grammar; 
Import pl.symentis.lua.runtime.Context; 
public interface Expression<T> { 
T evaluate(Context ctx); 
}
package pl.symentis.lua.runtime; 
public interface Context { 
VariableRef resolveVariable(String name); 
Scope enterScope(); 
Scope exitScope(); 
}
package pl.symentis.lua.runtime; 
public interface Scope { 
Scope getOuterScope(); 
VariableRef resolveVariable(String name); 
void bindVariable(String name, Object value); 
}
Into the forest of syntax tree
x = 1
public class Literal implements ExpressionNode { 
public final LuaType value; 
public Literal(LuaType value) { 
super(); 
this.value = value; 
} 
@Override 
public void accept(ExpressionVisitor visitor) { 
visitor.visit(this); 
} 
}
public class VariableName extends Var { 
public final String name; 
public VariableName(String name) { 
this.name = name; 
} 
@Override 
public void accept(ExpressionVisitor visitor) { 
visitor.visit(this); 
} 
}
public class Assignment implements StatementNode { 
public final Varlist varlist; 
public final Explist explist; 
public Assignment(Varlist varlist, Explist explist) { 
super(); 
this.varlist = varlist; 
this.explist = explist; 
} 
@Override 
public void accept(StatementVisitor visitor) { 
visitor.visit(this); 
} 
}
public void visit(Assignment assignment) { 
InterpreterExpressionVisitor varlist = createExpressionVisitor(); 
assignment.varlist.accept(varlist); 
InterpreterExpressionVisitor explist = createExpressionVisitor(); 
assignment.explist.accept(explist); 
Iterator<ExpressionNode> iterator = ((List<ExpressionNode>) explist.result()).iterator(); 
List<VariableRef> vars = (List<VariableRef>) varlist.result(); 
for (VariableRef variableRef : vars) { 
if (iterator.hasNext()) { 
ExpressionNode node = iterator.next(); 
InterpreterExpressionVisitor exp = createExpressionVisitor(); 
node.accept(exp); 
variableRef.set(exp.result()); 
} else { 
variableRef.set(LuaNil.Nil); 
} 
} 
}
public void visit(Literal literal) { 
result = literal.value; 
} 
public void visit(VariableName variableName) { 
result = context.resolveVariable(variableName.name); 
} 
public void visit(Varlist varlist) { 
List<VariableRef> refs = new ArrayList<>(); 
for (Var var : varlist.vars) { 
var.accept(this); 
refs.add((VariableRef) result()); 
} 
result = refs; 
}
translator 
interpreter 
compiler
compiler → byte code 
org.ow2.asm:asm:jar 
me.qmx.jitescript:jitescript:jar
JiteClass jiteClass = new JiteClass(classname, new String[] { p(Script.class) }); 
jiteClass.defineDefaultConstructor(); 
CodeBlock codeBlock = newCodeBlock(); 
// bind context into current runtime 
codeBlock.aload(1); 
codeBlock.invokestatic(p(RuntimeContext.class), "enterContext", sig(void.class, Context.class)); 
// parse file and start to walk through AST visitor 
StatementNode chunk = parseScript(readFileToString(script)); 
// generate byte code 
chunk.accept(new CompilerStatementVisitor(codeBlock, new HashSymbolTable())); 
codeBlock.voidreturn(); 
jiteClass.defineMethod("execute", JiteClass.ACC_PUBLIC, sig(void.class, new Class[] 
{ Context.class }), 
codeBlock); 
return jiteClass.toBytes(JDKVersion.V1_8); 
}
JiteClass jiteClass = new JiteClass(classname, new String[] { p(Script.class) }); 
jiteClass.defineDefaultConstructor(); 
CodeBlock codeBlock = newCodeBlock(); 
// bind context into current runtime 
codeBlock.aload(1); 
codeBlock.invokestatic(p(RuntimeContext.class), "enterContext", sig(void.class, Context.class)); 
// parse file and start to walk through AST visitor 
StatementNode chunk = parseScript(readFileToString(script)); 
// generate byte code 
chunk.accept(new CompilerStatementVisitor(codeBlock, new HashSymbolTable())); 
codeBlock.voidreturn(); 
jiteClass.defineMethod("execute", JiteClass.ACC_PUBLIC, sig(void.class, new Class[] 
{ Context.class }), 
codeBlock); 
return jiteClass.toBytes(JDKVersion.V1_8); 
}
JiteClass jiteClass = new JiteClass(classname, new String[] { p(Script.class) }); 
jiteClass.defineDefaultConstructor(); 
CodeBlock codeBlock = newCodeBlock(); 
// bind context into current runtime 
codeBlock.aload(1); 
codeBlock.invokestatic(p(RuntimeContext.class), "enterContext", sig(void.class, Context.class)); 
// parse file and start to walk through AST visitor 
StatementNode chunk = parseScript(readFileToString(script)); 
// generate byte code 
chunk.accept(new CompilerStatementVisitor(codeBlock, new HashSymbolTable())); 
codeBlock.voidreturn(); 
jiteClass.defineMethod("execute", JiteClass.ACC_PUBLIC, sig(void.class, new Class[] 
{ Context.class }), 
codeBlock); 
return jiteClass.toBytes(JDKVersion.V1_8); 
}
x = 1
public void visit(Assignment assignment) { 
Explist explist = assignment.explist; 
Varlist varlist = assignment.varlist; 
Iterator<Var> vars = varlist.vars.iterator(); 
for (ExpressionNode exp : explist.expressions) { 
exp.accept(new CompilerExpressionVisitor(codeBlock, symbolTable)); 
CompilerExpressionVisitor visitor = new CompilerExpressionVisitor( 
codeBlock, symbolTable); 
vars.next().accept(visitor); 
String varName = (String) visitor.result(); 
codeBlock.astore(symbolTable.index(varName)); 
} 
}
public void visit(Literal literal) { 
Object object = literal.value.asObject(); 
codeBlock.ldc(object); 
// box object into Lua type 
if (object instanceof Integer) { 
codeBlock.invokestatic(p(Integer.class), "valueOf", sig(Integer.class, int.class)); 
} else if (object instanceof Double) { 
codeBlock.invokestatic(p(Double.class), "valueOf", sig(Double.class, 
double.class)); 
} 
codeBlock.invokestatic(p(LuaTypes.class), "valueOf", sig(LuaType.class, Object.class)); 
} 
public void visit(VariableName variableName) { 
result = variableName.name; 
}
When writing bytecode compiler it helps to think about Java code 
But at the end you need to think like stack machine :)
.method public execute : (Lpl/symentis/lua4j/runtime/Context;)V 
; method code size: 21 bytes 
.limit stack 2 
.limit locals 3 
aload_1 
invokestatic pl/symentis/lua4j/compiler/RuntimeContext 
enterContext (Lpl/symentis/lua4j/runtime/Context;)V 
ldc2_w 1.0 
invokestatic java/lang/Double valueOf (D)Ljava/lang/Double; 
invokestatic pl/symentis/lua4j/types/LuaTypes valueOf [_28] 
astore_2 
aload_2 
return 
.end method
Symbol table 
maps variable local to its symbolic name
0xBA 
invokedynamic
print("Welcome","to","Jokerconf",2014)
Var var = functionCall.var; 
CompilerExpressionVisitor visitor = new CompilerExpressionVisitor(codeBlock, 
symbolTable); 
var.accept(visitor); 
String functionName = (String) visitor.result(); 
Args args = functionCall.args; 
visitor = new CompilerExpressionVisitor(codeBlock, symbolTable); 
args.accept(visitor); 
Integer argNumber = (Integer) visitor.result(); 
Class<?>[] paramTypeArr = new Class[argNumber]; 
fill(paramTypeArr, LuaType.class); 
codeBlock.invokedynamic(functionName, sig(void.class, paramTypeArr), 
Lua4JDynamicBootstrap.HANDLE, 
new Object[] {});
static final Handle HANDLE = new Handle( 
CodeBlock.H_INVOKESTATIC, 
p(Lua4JDynamicBootstrap.class), 
"bootstrap", 
sig(CallSite.class, MethodHandles.Lookup.class, String.class, 
MethodType.class));
public static CallSite bootstrap( 
MethodHandles.Lookup lookup, 
String name, 
MethodType type) throws Throwable { 
Context context = currentContext(); 
MethodHandle target=lookup.findStatic(BasicFunctions.class,name, 
methodType( 
LuaType.class, 
Context.class, 
LuaType[].class)); 
target = MethodHandles.insertArguments(handler, 0, context) 
.asCollector(LuaType[].class, type.parameterCount()); 
return new ConstantCallSite(target.asType(type)); 
}
Things to consider 
Type coercion 
Symbol table and scope 
Function handles and scope 
Global scope
https://github.com/headius/invokebinder 
A Java DSL for binding method handles forward, 
rather than backward 
https://github.com/projectodd/rephract 
Another Java DSL for invokedynamic
What's next? 
graal + truffle 
dynamic compiler + AST interpreter
Books
Thanks, 
stay cool, 
dynamically linked 
and...
Let the eternal stream of bytecode 
flow through your body
Q&A

More Related Content

What's hot

Natural Language Toolkit (NLTK), Basics
Natural Language Toolkit (NLTK), Basics Natural Language Toolkit (NLTK), Basics
Natural Language Toolkit (NLTK), Basics Prakash Pimpale
 
The Ring programming language version 1.10 book - Part 49 of 212
The Ring programming language version 1.10 book - Part 49 of 212The Ring programming language version 1.10 book - Part 49 of 212
The Ring programming language version 1.10 book - Part 49 of 212Mahmoud Samir Fayed
 
Inside the JVM - Follow the white rabbit!
Inside the JVM - Follow the white rabbit!Inside the JVM - Follow the white rabbit!
Inside the JVM - Follow the white rabbit!Sylvain Wallez
 
Introduction To Groovy 2005
Introduction To Groovy 2005Introduction To Groovy 2005
Introduction To Groovy 2005Tugdual Grall
 
Iron Languages - NYC CodeCamp 2/19/2011
Iron Languages - NYC CodeCamp 2/19/2011Iron Languages - NYC CodeCamp 2/19/2011
Iron Languages - NYC CodeCamp 2/19/2011Jimmy Schementi
 
Rapid Development with Ruby/JRuby and Rails
Rapid Development with Ruby/JRuby and RailsRapid Development with Ruby/JRuby and Rails
Rapid Development with Ruby/JRuby and Railselliando dias
 
Zero-Overhead Metaprogramming: Reflection and Metaobject Protocols Fast and w...
Zero-Overhead Metaprogramming: Reflection and Metaobject Protocols Fast and w...Zero-Overhead Metaprogramming: Reflection and Metaobject Protocols Fast and w...
Zero-Overhead Metaprogramming: Reflection and Metaobject Protocols Fast and w...Stefan Marr
 
Groovy DSLs, from Beginner to Expert - Guillaume Laforge and Paul King - Spri...
Groovy DSLs, from Beginner to Expert - Guillaume Laforge and Paul King - Spri...Groovy DSLs, from Beginner to Expert - Guillaume Laforge and Paul King - Spri...
Groovy DSLs, from Beginner to Expert - Guillaume Laforge and Paul King - Spri...Guillaume Laforge
 
Building High-Performance Language Implementations With Low Effort
Building High-Performance Language Implementations With Low EffortBuilding High-Performance Language Implementations With Low Effort
Building High-Performance Language Implementations With Low EffortStefan Marr
 
DRYing to Monad in Java8
DRYing to Monad in Java8DRYing to Monad in Java8
DRYing to Monad in Java8Dhaval Dalal
 
Kotlin boost yourproductivity
Kotlin boost yourproductivityKotlin boost yourproductivity
Kotlin boost yourproductivitynklmish
 
ADG Poznań - Kotlin for Android developers
ADG Poznań - Kotlin for Android developersADG Poznań - Kotlin for Android developers
ADG Poznań - Kotlin for Android developersBartosz Kosarzycki
 
Lambdas and Streams Master Class Part 2
Lambdas and Streams Master Class Part 2Lambdas and Streams Master Class Part 2
Lambdas and Streams Master Class Part 2José Paumard
 
Introduction to Dart
Introduction to DartIntroduction to Dart
Introduction to DartRamesh Nair
 
Behavioral Reflection
Behavioral ReflectionBehavioral Reflection
Behavioral ReflectionMarcus Denker
 

What's hot (20)

Apache Thrift
Apache ThriftApache Thrift
Apache Thrift
 
Natural Language Toolkit (NLTK), Basics
Natural Language Toolkit (NLTK), Basics Natural Language Toolkit (NLTK), Basics
Natural Language Toolkit (NLTK), Basics
 
The Ring programming language version 1.10 book - Part 49 of 212
The Ring programming language version 1.10 book - Part 49 of 212The Ring programming language version 1.10 book - Part 49 of 212
The Ring programming language version 1.10 book - Part 49 of 212
 
Inside the JVM - Follow the white rabbit!
Inside the JVM - Follow the white rabbit!Inside the JVM - Follow the white rabbit!
Inside the JVM - Follow the white rabbit!
 
Introduction To Groovy 2005
Introduction To Groovy 2005Introduction To Groovy 2005
Introduction To Groovy 2005
 
Iron Languages - NYC CodeCamp 2/19/2011
Iron Languages - NYC CodeCamp 2/19/2011Iron Languages - NYC CodeCamp 2/19/2011
Iron Languages - NYC CodeCamp 2/19/2011
 
Stoop 305-reflective programming5
Stoop 305-reflective programming5Stoop 305-reflective programming5
Stoop 305-reflective programming5
 
Rapid Development with Ruby/JRuby and Rails
Rapid Development with Ruby/JRuby and RailsRapid Development with Ruby/JRuby and Rails
Rapid Development with Ruby/JRuby and Rails
 
Zero-Overhead Metaprogramming: Reflection and Metaobject Protocols Fast and w...
Zero-Overhead Metaprogramming: Reflection and Metaobject Protocols Fast and w...Zero-Overhead Metaprogramming: Reflection and Metaobject Protocols Fast and w...
Zero-Overhead Metaprogramming: Reflection and Metaobject Protocols Fast and w...
 
Ad java prac sol set
Ad java prac sol setAd java prac sol set
Ad java prac sol set
 
Groovy DSLs, from Beginner to Expert - Guillaume Laforge and Paul King - Spri...
Groovy DSLs, from Beginner to Expert - Guillaume Laforge and Paul King - Spri...Groovy DSLs, from Beginner to Expert - Guillaume Laforge and Paul King - Spri...
Groovy DSLs, from Beginner to Expert - Guillaume Laforge and Paul King - Spri...
 
Building High-Performance Language Implementations With Low Effort
Building High-Performance Language Implementations With Low EffortBuilding High-Performance Language Implementations With Low Effort
Building High-Performance Language Implementations With Low Effort
 
DRYing to Monad in Java8
DRYing to Monad in Java8DRYing to Monad in Java8
DRYing to Monad in Java8
 
Kotlin boost yourproductivity
Kotlin boost yourproductivityKotlin boost yourproductivity
Kotlin boost yourproductivity
 
Groovy!
Groovy!Groovy!
Groovy!
 
Stoop 390-instruction stream
Stoop 390-instruction streamStoop 390-instruction stream
Stoop 390-instruction stream
 
ADG Poznań - Kotlin for Android developers
ADG Poznań - Kotlin for Android developersADG Poznań - Kotlin for Android developers
ADG Poznań - Kotlin for Android developers
 
Lambdas and Streams Master Class Part 2
Lambdas and Streams Master Class Part 2Lambdas and Streams Master Class Part 2
Lambdas and Streams Master Class Part 2
 
Introduction to Dart
Introduction to DartIntroduction to Dart
Introduction to Dart
 
Behavioral Reflection
Behavioral ReflectionBehavioral Reflection
Behavioral Reflection
 

Similar to Patterns for JVM languages JokerConf

Patterns for JVM languages - Geecon 2014
Patterns for JVM languages - Geecon 2014Patterns for JVM languages - Geecon 2014
Patterns for JVM languages - Geecon 2014Jaroslaw Palka
 
Ast transformations
Ast transformationsAst transformations
Ast transformationsHamletDRC
 
Dart structured web apps
Dart   structured web appsDart   structured web apps
Dart structured web appschrisbuckett
 
Dart, unicorns and rainbows
Dart, unicorns and rainbowsDart, unicorns and rainbows
Dart, unicorns and rainbowschrisbuckett
 
AST Transformations
AST TransformationsAST Transformations
AST TransformationsHamletDRC
 
[Deprecated] Integrating libSyntax into the compiler pipeline
[Deprecated] Integrating libSyntax into the compiler pipeline[Deprecated] Integrating libSyntax into the compiler pipeline
[Deprecated] Integrating libSyntax into the compiler pipelineYusuke Kita
 
FP in Java - Project Lambda and beyond
FP in Java - Project Lambda and beyondFP in Java - Project Lambda and beyond
FP in Java - Project Lambda and beyondMario Fusco
 
Dart London hackathon
Dart  London hackathonDart  London hackathon
Dart London hackathonchrisbuckett
 
Introduction to Scalding and Monoids
Introduction to Scalding and MonoidsIntroduction to Scalding and Monoids
Introduction to Scalding and MonoidsHugo Gävert
 
Cs267 hadoop programming
Cs267 hadoop programmingCs267 hadoop programming
Cs267 hadoop programmingKuldeep Dhole
 
Introduction to Javascript
Introduction to JavascriptIntroduction to Javascript
Introduction to JavascriptAmit Tyagi
 
Introduction to Spark with Scala
Introduction to Spark with ScalaIntroduction to Spark with Scala
Introduction to Spark with ScalaHimanshu Gupta
 
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#Mark Needham
 
Lambda Chops - Recipes for Simpler, More Expressive Code
Lambda Chops - Recipes for Simpler, More Expressive CodeLambda Chops - Recipes for Simpler, More Expressive Code
Lambda Chops - Recipes for Simpler, More Expressive CodeIan Robertson
 
Groovy Ast Transformations (greach)
Groovy Ast Transformations (greach)Groovy Ast Transformations (greach)
Groovy Ast Transformations (greach)HamletDRC
 

Similar to Patterns for JVM languages JokerConf (20)

Patterns for JVM languages - Geecon 2014
Patterns for JVM languages - Geecon 2014Patterns for JVM languages - Geecon 2014
Patterns for JVM languages - Geecon 2014
 
Ast transformations
Ast transformationsAst transformations
Ast transformations
 
Dart structured web apps
Dart   structured web appsDart   structured web apps
Dart structured web apps
 
Dart, unicorns and rainbows
Dart, unicorns and rainbowsDart, unicorns and rainbows
Dart, unicorns and rainbows
 
AST Transformations
AST TransformationsAST Transformations
AST Transformations
 
Dart
DartDart
Dart
 
[Deprecated] Integrating libSyntax into the compiler pipeline
[Deprecated] Integrating libSyntax into the compiler pipeline[Deprecated] Integrating libSyntax into the compiler pipeline
[Deprecated] Integrating libSyntax into the compiler pipeline
 
FP in Java - Project Lambda and beyond
FP in Java - Project Lambda and beyondFP in Java - Project Lambda and beyond
FP in Java - Project Lambda and beyond
 
Dart London hackathon
Dart  London hackathonDart  London hackathon
Dart London hackathon
 
Introduction to Scalding and Monoids
Introduction to Scalding and MonoidsIntroduction to Scalding and Monoids
Introduction to Scalding and Monoids
 
Interpreter Case Study - Design Patterns
Interpreter Case Study - Design PatternsInterpreter Case Study - Design Patterns
Interpreter Case Study - Design Patterns
 
Cs267 hadoop programming
Cs267 hadoop programmingCs267 hadoop programming
Cs267 hadoop programming
 
Introduction to Javascript
Introduction to JavascriptIntroduction to Javascript
Introduction to Javascript
 
Introduction to Spark with Scala
Introduction to Spark with ScalaIntroduction to Spark with Scala
Introduction to Spark with Scala
 
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
 
Power tools in Java
Power tools in JavaPower tools in Java
Power tools in Java
 
Apache Beam de A à Z
 Apache Beam de A à Z Apache Beam de A à Z
Apache Beam de A à Z
 
Lambda Chops - Recipes for Simpler, More Expressive Code
Lambda Chops - Recipes for Simpler, More Expressive CodeLambda Chops - Recipes for Simpler, More Expressive Code
Lambda Chops - Recipes for Simpler, More Expressive Code
 
Let's Go-lang
Let's Go-langLet's Go-lang
Let's Go-lang
 
Groovy Ast Transformations (greach)
Groovy Ast Transformations (greach)Groovy Ast Transformations (greach)
Groovy Ast Transformations (greach)
 

More from Jaroslaw Palka

We are crowd, we are anonymous
We are crowd, we are anonymousWe are crowd, we are anonymous
We are crowd, we are anonymousJaroslaw Palka
 
Czterej jeźdźcy apokalipsy gdy Armagedon w JVM nadchodzi
Czterej jeźdźcy apokalipsy  gdy Armagedon w JVM nadchodziCzterej jeźdźcy apokalipsy  gdy Armagedon w JVM nadchodzi
Czterej jeźdźcy apokalipsy gdy Armagedon w JVM nadchodziJaroslaw Palka
 
Systematyczny architekt na drodze ku planowanemu postarzaniu
Systematyczny architekt na drodze ku planowanemu postarzaniuSystematyczny architekt na drodze ku planowanemu postarzaniu
Systematyczny architekt na drodze ku planowanemu postarzaniuJaroslaw Palka
 
Systematyczny architekt na drodze ku planowanemu postarzaniu
Systematyczny architekt na drodze ku planowanemu postarzaniuSystematyczny architekt na drodze ku planowanemu postarzaniu
Systematyczny architekt na drodze ku planowanemu postarzaniuJaroslaw Palka
 
Patterns for organic architecture
Patterns for organic architecturePatterns for organic architecture
Patterns for organic architectureJaroslaw Palka
 
I ty też możesz mieć swoje dane w cache
I ty też możesz mieć swoje dane w cacheI ty też możesz mieć swoje dane w cache
I ty też możesz mieć swoje dane w cacheJaroslaw Palka
 
Programming and architecture of NOSQL web at 33degree
Programming and architecture of NOSQL web at 33degreeProgramming and architecture of NOSQL web at 33degree
Programming and architecture of NOSQL web at 33degreeJaroslaw Palka
 

More from Jaroslaw Palka (7)

We are crowd, we are anonymous
We are crowd, we are anonymousWe are crowd, we are anonymous
We are crowd, we are anonymous
 
Czterej jeźdźcy apokalipsy gdy Armagedon w JVM nadchodzi
Czterej jeźdźcy apokalipsy  gdy Armagedon w JVM nadchodziCzterej jeźdźcy apokalipsy  gdy Armagedon w JVM nadchodzi
Czterej jeźdźcy apokalipsy gdy Armagedon w JVM nadchodzi
 
Systematyczny architekt na drodze ku planowanemu postarzaniu
Systematyczny architekt na drodze ku planowanemu postarzaniuSystematyczny architekt na drodze ku planowanemu postarzaniu
Systematyczny architekt na drodze ku planowanemu postarzaniu
 
Systematyczny architekt na drodze ku planowanemu postarzaniu
Systematyczny architekt na drodze ku planowanemu postarzaniuSystematyczny architekt na drodze ku planowanemu postarzaniu
Systematyczny architekt na drodze ku planowanemu postarzaniu
 
Patterns for organic architecture
Patterns for organic architecturePatterns for organic architecture
Patterns for organic architecture
 
I ty też możesz mieć swoje dane w cache
I ty też możesz mieć swoje dane w cacheI ty też możesz mieć swoje dane w cache
I ty też możesz mieć swoje dane w cache
 
Programming and architecture of NOSQL web at 33degree
Programming and architecture of NOSQL web at 33degreeProgramming and architecture of NOSQL web at 33degree
Programming and architecture of NOSQL web at 33degree
 

Recently uploaded

Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...
Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...
Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...OnePlan Solutions
 
Ronisha Informatics Private Limited Catalogue
Ronisha Informatics Private Limited CatalogueRonisha Informatics Private Limited Catalogue
Ronisha Informatics Private Limited Catalogueitservices996
 
Enhancing Supply Chain Visibility with Cargo Cloud Solutions.pdf
Enhancing Supply Chain Visibility with Cargo Cloud Solutions.pdfEnhancing Supply Chain Visibility with Cargo Cloud Solutions.pdf
Enhancing Supply Chain Visibility with Cargo Cloud Solutions.pdfRTS corp
 
Strategies for using alternative queries to mitigate zero results
Strategies for using alternative queries to mitigate zero resultsStrategies for using alternative queries to mitigate zero results
Strategies for using alternative queries to mitigate zero resultsJean Silva
 
Understanding Plagiarism: Causes, Consequences and Prevention.pptx
Understanding Plagiarism: Causes, Consequences and Prevention.pptxUnderstanding Plagiarism: Causes, Consequences and Prevention.pptx
Understanding Plagiarism: Causes, Consequences and Prevention.pptxSasikiranMarri
 
VictoriaMetrics Q1 Meet Up '24 - Community & News Update
VictoriaMetrics Q1 Meet Up '24 - Community & News UpdateVictoriaMetrics Q1 Meet Up '24 - Community & News Update
VictoriaMetrics Q1 Meet Up '24 - Community & News UpdateVictoriaMetrics
 
SAM Training Session - How to use EXCEL ?
SAM Training Session - How to use EXCEL ?SAM Training Session - How to use EXCEL ?
SAM Training Session - How to use EXCEL ?Alexandre Beguel
 
2024 DevNexus Patterns for Resiliency: Shuffle shards
2024 DevNexus Patterns for Resiliency: Shuffle shards2024 DevNexus Patterns for Resiliency: Shuffle shards
2024 DevNexus Patterns for Resiliency: Shuffle shardsChristopher Curtin
 
Mastering Project Planning with Microsoft Project 2016.pptx
Mastering Project Planning with Microsoft Project 2016.pptxMastering Project Planning with Microsoft Project 2016.pptx
Mastering Project Planning with Microsoft Project 2016.pptxAS Design & AST.
 
Osi security architecture in network.pptx
Osi security architecture in network.pptxOsi security architecture in network.pptx
Osi security architecture in network.pptxVinzoCenzo
 
Key Steps in Agile Software Delivery Roadmap
Key Steps in Agile Software Delivery RoadmapKey Steps in Agile Software Delivery Roadmap
Key Steps in Agile Software Delivery RoadmapIshara Amarasekera
 
What’s New in VictoriaMetrics: Q1 2024 Updates
What’s New in VictoriaMetrics: Q1 2024 UpdatesWhat’s New in VictoriaMetrics: Q1 2024 Updates
What’s New in VictoriaMetrics: Q1 2024 UpdatesVictoriaMetrics
 
Zer0con 2024 final share short version.pdf
Zer0con 2024 final share short version.pdfZer0con 2024 final share short version.pdf
Zer0con 2024 final share short version.pdfmaor17
 
Effectively Troubleshoot 9 Types of OutOfMemoryError
Effectively Troubleshoot 9 Types of OutOfMemoryErrorEffectively Troubleshoot 9 Types of OutOfMemoryError
Effectively Troubleshoot 9 Types of OutOfMemoryErrorTier1 app
 
2024-04-09 - From Complexity to Clarity - AWS Summit AMS.pdf
2024-04-09 - From Complexity to Clarity - AWS Summit AMS.pdf2024-04-09 - From Complexity to Clarity - AWS Summit AMS.pdf
2024-04-09 - From Complexity to Clarity - AWS Summit AMS.pdfAndrey Devyatkin
 
eSoftTools IMAP Backup Software and migration tools
eSoftTools IMAP Backup Software and migration toolseSoftTools IMAP Backup Software and migration tools
eSoftTools IMAP Backup Software and migration toolsosttopstonverter
 
The Ultimate Guide to Performance Testing in Low-Code, No-Code Environments (...
The Ultimate Guide to Performance Testing in Low-Code, No-Code Environments (...The Ultimate Guide to Performance Testing in Low-Code, No-Code Environments (...
The Ultimate Guide to Performance Testing in Low-Code, No-Code Environments (...kalichargn70th171
 
JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...
JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...
JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...Bert Jan Schrijver
 
OpenChain AI Study Group - Europe and Asia Recap - 2024-04-11 - Full Recording
OpenChain AI Study Group - Europe and Asia Recap - 2024-04-11 - Full RecordingOpenChain AI Study Group - Europe and Asia Recap - 2024-04-11 - Full Recording
OpenChain AI Study Group - Europe and Asia Recap - 2024-04-11 - Full RecordingShane Coughlan
 
Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...
Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...
Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...OnePlan Solutions
 

Recently uploaded (20)

Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...
Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...
Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...
 
Ronisha Informatics Private Limited Catalogue
Ronisha Informatics Private Limited CatalogueRonisha Informatics Private Limited Catalogue
Ronisha Informatics Private Limited Catalogue
 
Enhancing Supply Chain Visibility with Cargo Cloud Solutions.pdf
Enhancing Supply Chain Visibility with Cargo Cloud Solutions.pdfEnhancing Supply Chain Visibility with Cargo Cloud Solutions.pdf
Enhancing Supply Chain Visibility with Cargo Cloud Solutions.pdf
 
Strategies for using alternative queries to mitigate zero results
Strategies for using alternative queries to mitigate zero resultsStrategies for using alternative queries to mitigate zero results
Strategies for using alternative queries to mitigate zero results
 
Understanding Plagiarism: Causes, Consequences and Prevention.pptx
Understanding Plagiarism: Causes, Consequences and Prevention.pptxUnderstanding Plagiarism: Causes, Consequences and Prevention.pptx
Understanding Plagiarism: Causes, Consequences and Prevention.pptx
 
VictoriaMetrics Q1 Meet Up '24 - Community & News Update
VictoriaMetrics Q1 Meet Up '24 - Community & News UpdateVictoriaMetrics Q1 Meet Up '24 - Community & News Update
VictoriaMetrics Q1 Meet Up '24 - Community & News Update
 
SAM Training Session - How to use EXCEL ?
SAM Training Session - How to use EXCEL ?SAM Training Session - How to use EXCEL ?
SAM Training Session - How to use EXCEL ?
 
2024 DevNexus Patterns for Resiliency: Shuffle shards
2024 DevNexus Patterns for Resiliency: Shuffle shards2024 DevNexus Patterns for Resiliency: Shuffle shards
2024 DevNexus Patterns for Resiliency: Shuffle shards
 
Mastering Project Planning with Microsoft Project 2016.pptx
Mastering Project Planning with Microsoft Project 2016.pptxMastering Project Planning with Microsoft Project 2016.pptx
Mastering Project Planning with Microsoft Project 2016.pptx
 
Osi security architecture in network.pptx
Osi security architecture in network.pptxOsi security architecture in network.pptx
Osi security architecture in network.pptx
 
Key Steps in Agile Software Delivery Roadmap
Key Steps in Agile Software Delivery RoadmapKey Steps in Agile Software Delivery Roadmap
Key Steps in Agile Software Delivery Roadmap
 
What’s New in VictoriaMetrics: Q1 2024 Updates
What’s New in VictoriaMetrics: Q1 2024 UpdatesWhat’s New in VictoriaMetrics: Q1 2024 Updates
What’s New in VictoriaMetrics: Q1 2024 Updates
 
Zer0con 2024 final share short version.pdf
Zer0con 2024 final share short version.pdfZer0con 2024 final share short version.pdf
Zer0con 2024 final share short version.pdf
 
Effectively Troubleshoot 9 Types of OutOfMemoryError
Effectively Troubleshoot 9 Types of OutOfMemoryErrorEffectively Troubleshoot 9 Types of OutOfMemoryError
Effectively Troubleshoot 9 Types of OutOfMemoryError
 
2024-04-09 - From Complexity to Clarity - AWS Summit AMS.pdf
2024-04-09 - From Complexity to Clarity - AWS Summit AMS.pdf2024-04-09 - From Complexity to Clarity - AWS Summit AMS.pdf
2024-04-09 - From Complexity to Clarity - AWS Summit AMS.pdf
 
eSoftTools IMAP Backup Software and migration tools
eSoftTools IMAP Backup Software and migration toolseSoftTools IMAP Backup Software and migration tools
eSoftTools IMAP Backup Software and migration tools
 
The Ultimate Guide to Performance Testing in Low-Code, No-Code Environments (...
The Ultimate Guide to Performance Testing in Low-Code, No-Code Environments (...The Ultimate Guide to Performance Testing in Low-Code, No-Code Environments (...
The Ultimate Guide to Performance Testing in Low-Code, No-Code Environments (...
 
JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...
JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...
JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...
 
OpenChain AI Study Group - Europe and Asia Recap - 2024-04-11 - Full Recording
OpenChain AI Study Group - Europe and Asia Recap - 2024-04-11 - Full RecordingOpenChain AI Study Group - Europe and Asia Recap - 2024-04-11 - Full Recording
OpenChain AI Study Group - Europe and Asia Recap - 2024-04-11 - Full Recording
 
Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...
Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...
Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...
 

Patterns for JVM languages JokerConf

  • 1. The following presentation is provided under DHMB license (Do Not Hurt My Brain). Lecturer is not responsible for the financial and moral damages resulting from taking too seriously the content of the presentation. Including permanent damage to neurons, reduction of neurotransmitter activity at the molecular level and group dismissal.
  • 2. Software engineers united we stand divided we fall
  • 3. Patterns for JVM languages Jarosław Pałka
  • 4. about me work://chief_architect@lumesse owner://symentis.pl twitter://j_palka blog://geekyprimitives.wordpress.com scm:bitbucket://kcrimson scm:github://kcrimson
  • 5.
  • 7. Because having pet projects is like solving crosswords everyday Or going to a gym Helps your brain to stay in shape
  • 8.
  • 9.
  • 10. JVM is the new assembler
  • 12. source code ↓ target language source code ↓ machine code || interpreter
  • 14. source code ↓ execution results
  • 16. source code ↓ machine code
  • 17. So how does it all work?
  • 18.
  • 19. Diving into the stream
  • 20. The ALL(*) lexer and parser generator Which supports multiple target languages
  • 21. source code ↓lexer token stream ↓parser IR
  • 24. local y = 1 x = 1 + y
  • 25.
  • 26.
  • 27. fragment DIGIT : [0-9] ; fragment LETTER : [a-zA-Z] ; String : ''' .*? ''' | '"' .*? '"' ; Number : DIGIT+ ; Name : ( '_' | LETTER )( '_' | LETTER | DIGIT )* ; COMMENT : '--' .*? 'n' -> skip ; NL : 'r'? 'n' -> skip ; WS : [ tf]+ -> skip ;
  • 28. [@0,[0..1)='x',<49>] [@1,[2..3)='=',<36>] [@2,[4..5)='1',<48>] [@3,[6..7)='+',<33>] [@4,[8..15)='"Hello"',<47>] [@5,[15..16)=';',<37>] [@6,[17..17)='',<-1=EOF>]
  • 29. varlist returns [Varlist result] : var {$result = createVarlist($var.result);} ( ',' var {$result = createVarlist($result,$var.result);} )* ; // var returns [Var result] : Name { $result = createVariableName($Name.text); } | prefixexp '[' exp ']' | prefixexp '.' Name ;
  • 30. beware of left recursion
  • 32. Interpreter pattern Non terminal nodes Terminal nodes
  • 33.
  • 34. package pl.symentis.lua.grammar; import pl.symentis.lua.runtime.Context; public interface Statement { void execute(Context context); }
  • 35. package pl.symentis.lua.grammar; Import pl.symentis.lua.runtime.Context; public interface Expression<T> { T evaluate(Context ctx); }
  • 36. package pl.symentis.lua.runtime; public interface Context { VariableRef resolveVariable(String name); Scope enterScope(); Scope exitScope(); }
  • 37. package pl.symentis.lua.runtime; public interface Scope { Scope getOuterScope(); VariableRef resolveVariable(String name); void bindVariable(String name, Object value); }
  • 38. Into the forest of syntax tree
  • 39. x = 1
  • 40. public class Literal implements ExpressionNode { public final LuaType value; public Literal(LuaType value) { super(); this.value = value; } @Override public void accept(ExpressionVisitor visitor) { visitor.visit(this); } }
  • 41. public class VariableName extends Var { public final String name; public VariableName(String name) { this.name = name; } @Override public void accept(ExpressionVisitor visitor) { visitor.visit(this); } }
  • 42. public class Assignment implements StatementNode { public final Varlist varlist; public final Explist explist; public Assignment(Varlist varlist, Explist explist) { super(); this.varlist = varlist; this.explist = explist; } @Override public void accept(StatementVisitor visitor) { visitor.visit(this); } }
  • 43. public void visit(Assignment assignment) { InterpreterExpressionVisitor varlist = createExpressionVisitor(); assignment.varlist.accept(varlist); InterpreterExpressionVisitor explist = createExpressionVisitor(); assignment.explist.accept(explist); Iterator<ExpressionNode> iterator = ((List<ExpressionNode>) explist.result()).iterator(); List<VariableRef> vars = (List<VariableRef>) varlist.result(); for (VariableRef variableRef : vars) { if (iterator.hasNext()) { ExpressionNode node = iterator.next(); InterpreterExpressionVisitor exp = createExpressionVisitor(); node.accept(exp); variableRef.set(exp.result()); } else { variableRef.set(LuaNil.Nil); } } }
  • 44. public void visit(Literal literal) { result = literal.value; } public void visit(VariableName variableName) { result = context.resolveVariable(variableName.name); } public void visit(Varlist varlist) { List<VariableRef> refs = new ArrayList<>(); for (Var var : varlist.vars) { var.accept(this); refs.add((VariableRef) result()); } result = refs; }
  • 46. compiler → byte code org.ow2.asm:asm:jar me.qmx.jitescript:jitescript:jar
  • 47. JiteClass jiteClass = new JiteClass(classname, new String[] { p(Script.class) }); jiteClass.defineDefaultConstructor(); CodeBlock codeBlock = newCodeBlock(); // bind context into current runtime codeBlock.aload(1); codeBlock.invokestatic(p(RuntimeContext.class), "enterContext", sig(void.class, Context.class)); // parse file and start to walk through AST visitor StatementNode chunk = parseScript(readFileToString(script)); // generate byte code chunk.accept(new CompilerStatementVisitor(codeBlock, new HashSymbolTable())); codeBlock.voidreturn(); jiteClass.defineMethod("execute", JiteClass.ACC_PUBLIC, sig(void.class, new Class[] { Context.class }), codeBlock); return jiteClass.toBytes(JDKVersion.V1_8); }
  • 48. JiteClass jiteClass = new JiteClass(classname, new String[] { p(Script.class) }); jiteClass.defineDefaultConstructor(); CodeBlock codeBlock = newCodeBlock(); // bind context into current runtime codeBlock.aload(1); codeBlock.invokestatic(p(RuntimeContext.class), "enterContext", sig(void.class, Context.class)); // parse file and start to walk through AST visitor StatementNode chunk = parseScript(readFileToString(script)); // generate byte code chunk.accept(new CompilerStatementVisitor(codeBlock, new HashSymbolTable())); codeBlock.voidreturn(); jiteClass.defineMethod("execute", JiteClass.ACC_PUBLIC, sig(void.class, new Class[] { Context.class }), codeBlock); return jiteClass.toBytes(JDKVersion.V1_8); }
  • 49. JiteClass jiteClass = new JiteClass(classname, new String[] { p(Script.class) }); jiteClass.defineDefaultConstructor(); CodeBlock codeBlock = newCodeBlock(); // bind context into current runtime codeBlock.aload(1); codeBlock.invokestatic(p(RuntimeContext.class), "enterContext", sig(void.class, Context.class)); // parse file and start to walk through AST visitor StatementNode chunk = parseScript(readFileToString(script)); // generate byte code chunk.accept(new CompilerStatementVisitor(codeBlock, new HashSymbolTable())); codeBlock.voidreturn(); jiteClass.defineMethod("execute", JiteClass.ACC_PUBLIC, sig(void.class, new Class[] { Context.class }), codeBlock); return jiteClass.toBytes(JDKVersion.V1_8); }
  • 50. x = 1
  • 51. public void visit(Assignment assignment) { Explist explist = assignment.explist; Varlist varlist = assignment.varlist; Iterator<Var> vars = varlist.vars.iterator(); for (ExpressionNode exp : explist.expressions) { exp.accept(new CompilerExpressionVisitor(codeBlock, symbolTable)); CompilerExpressionVisitor visitor = new CompilerExpressionVisitor( codeBlock, symbolTable); vars.next().accept(visitor); String varName = (String) visitor.result(); codeBlock.astore(symbolTable.index(varName)); } }
  • 52. public void visit(Literal literal) { Object object = literal.value.asObject(); codeBlock.ldc(object); // box object into Lua type if (object instanceof Integer) { codeBlock.invokestatic(p(Integer.class), "valueOf", sig(Integer.class, int.class)); } else if (object instanceof Double) { codeBlock.invokestatic(p(Double.class), "valueOf", sig(Double.class, double.class)); } codeBlock.invokestatic(p(LuaTypes.class), "valueOf", sig(LuaType.class, Object.class)); } public void visit(VariableName variableName) { result = variableName.name; }
  • 53. When writing bytecode compiler it helps to think about Java code But at the end you need to think like stack machine :)
  • 54. .method public execute : (Lpl/symentis/lua4j/runtime/Context;)V ; method code size: 21 bytes .limit stack 2 .limit locals 3 aload_1 invokestatic pl/symentis/lua4j/compiler/RuntimeContext enterContext (Lpl/symentis/lua4j/runtime/Context;)V ldc2_w 1.0 invokestatic java/lang/Double valueOf (D)Ljava/lang/Double; invokestatic pl/symentis/lua4j/types/LuaTypes valueOf [_28] astore_2 aload_2 return .end method
  • 55. Symbol table maps variable local to its symbolic name
  • 58. Var var = functionCall.var; CompilerExpressionVisitor visitor = new CompilerExpressionVisitor(codeBlock, symbolTable); var.accept(visitor); String functionName = (String) visitor.result(); Args args = functionCall.args; visitor = new CompilerExpressionVisitor(codeBlock, symbolTable); args.accept(visitor); Integer argNumber = (Integer) visitor.result(); Class<?>[] paramTypeArr = new Class[argNumber]; fill(paramTypeArr, LuaType.class); codeBlock.invokedynamic(functionName, sig(void.class, paramTypeArr), Lua4JDynamicBootstrap.HANDLE, new Object[] {});
  • 59. static final Handle HANDLE = new Handle( CodeBlock.H_INVOKESTATIC, p(Lua4JDynamicBootstrap.class), "bootstrap", sig(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class));
  • 60. public static CallSite bootstrap( MethodHandles.Lookup lookup, String name, MethodType type) throws Throwable { Context context = currentContext(); MethodHandle target=lookup.findStatic(BasicFunctions.class,name, methodType( LuaType.class, Context.class, LuaType[].class)); target = MethodHandles.insertArguments(handler, 0, context) .asCollector(LuaType[].class, type.parameterCount()); return new ConstantCallSite(target.asType(type)); }
  • 61. Things to consider Type coercion Symbol table and scope Function handles and scope Global scope
  • 62. https://github.com/headius/invokebinder A Java DSL for binding method handles forward, rather than backward https://github.com/projectodd/rephract Another Java DSL for invokedynamic
  • 63. What's next? graal + truffle dynamic compiler + AST interpreter
  • 64. Books
  • 65. Thanks, stay cool, dynamically linked and...
  • 66. Let the eternal stream of bytecode flow through your body
  • 67. Q&A