SlideShare a Scribd company logo
1 of 62
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.
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
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","Geecon",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));
}
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
Thanks,
stay cool,
dynamically linked
and...
Let the eternal stream of bytecode
flow through your body
Q&A

More Related Content

What's hot

JavaScript Fundamentals & JQuery
JavaScript Fundamentals & JQueryJavaScript Fundamentals & JQuery
JavaScript Fundamentals & JQuery
Jamshid Hashimi
 

What's hot (20)

Javascript basics for automation testing
Javascript  basics for automation testingJavascript  basics for automation testing
Javascript basics for automation testing
 
5 Tips for Better JavaScript
5 Tips for Better JavaScript5 Tips for Better JavaScript
5 Tips for Better JavaScript
 
Fundamental JavaScript [UTC, March 2014]
Fundamental JavaScript [UTC, March 2014]Fundamental JavaScript [UTC, March 2014]
Fundamental JavaScript [UTC, March 2014]
 
Javascript
JavascriptJavascript
Javascript
 
JavaScript Best Pratices
JavaScript Best PraticesJavaScript Best Pratices
JavaScript Best Pratices
 
JavaScript - From Birth To Closure
JavaScript - From Birth To ClosureJavaScript - From Birth To Closure
JavaScript - From Birth To Closure
 
JavaScript 101
JavaScript 101JavaScript 101
JavaScript 101
 
Scalable JavaScript Design Patterns
Scalable JavaScript Design PatternsScalable JavaScript Design Patterns
Scalable JavaScript Design Patterns
 
Javascript Design Patterns
Javascript Design PatternsJavascript Design Patterns
Javascript Design Patterns
 
Java Script Best Practices
Java Script Best PracticesJava Script Best Practices
Java Script Best Practices
 
JavaScript Basics
JavaScript BasicsJavaScript Basics
JavaScript Basics
 
WEB TECHNOLOGIES JavaScript
WEB TECHNOLOGIES JavaScriptWEB TECHNOLOGIES JavaScript
WEB TECHNOLOGIES JavaScript
 
A Deeper look into Javascript Basics
A Deeper look into Javascript BasicsA Deeper look into Javascript Basics
A Deeper look into Javascript Basics
 
Intro to Javascript
Intro to JavascriptIntro to Javascript
Intro to Javascript
 
JavaScript Fundamentals & JQuery
JavaScript Fundamentals & JQueryJavaScript Fundamentals & JQuery
JavaScript Fundamentals & JQuery
 
Design patterns in java script, jquery, angularjs
Design patterns in java script, jquery, angularjsDesign patterns in java script, jquery, angularjs
Design patterns in java script, jquery, angularjs
 
Java script
Java scriptJava script
Java script
 
Javascript basics
Javascript basicsJavascript basics
Javascript basics
 
How AngularJS Embraced Traditional Design Patterns
How AngularJS Embraced Traditional Design PatternsHow AngularJS Embraced Traditional Design Patterns
How AngularJS Embraced Traditional Design Patterns
 
Javascript Common Design Patterns
Javascript Common Design PatternsJavascript Common Design Patterns
Javascript Common Design Patterns
 

Similar to Patterns for JVM languages - Geecon 2014

AST Transformations
AST TransformationsAST Transformations
AST Transformations
HamletDRC
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
Hiroshi Ono
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
Hiroshi Ono
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
Hiroshi Ono
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
Hiroshi Ono
 

Similar to Patterns for JVM languages - Geecon 2014 (20)

Patterns for JVM languages JokerConf
Patterns for JVM languages JokerConfPatterns for JVM languages JokerConf
Patterns for JVM languages JokerConf
 
Ast transformations
Ast transformationsAst transformations
Ast transformations
 
Interpreter Case Study - Design Patterns
Interpreter Case Study - Design PatternsInterpreter Case Study - Design Patterns
Interpreter Case Study - Design Patterns
 
TypeScript Introduction
TypeScript IntroductionTypeScript Introduction
TypeScript Introduction
 
AST Transformations
AST TransformationsAST Transformations
AST Transformations
 
Activator and Reactive at Play NYC meetup
Activator and Reactive at Play NYC meetupActivator and Reactive at Play NYC meetup
Activator and Reactive at Play NYC meetup
 
Groovy Ast Transformations (greach)
Groovy Ast Transformations (greach)Groovy Ast Transformations (greach)
Groovy Ast Transformations (greach)
 
FalsyValues. Dmitry Soshnikov - ECMAScript 6
FalsyValues. Dmitry Soshnikov - ECMAScript 6FalsyValues. Dmitry Soshnikov - ECMAScript 6
FalsyValues. Dmitry Soshnikov - ECMAScript 6
 
Decoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DICDecoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DIC
 
JNI - Java & C in the same project
JNI - Java & C in the same projectJNI - Java & C in the same project
JNI - Java & C in the same project
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
 
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
 
So various polymorphism in Scala
So various polymorphism in ScalaSo various polymorphism in Scala
So various polymorphism in Scala
 
Going fullstack React(ive) - Paulo Lopes - Codemotion Amsterdam 2017
Going fullstack React(ive) - Paulo Lopes - Codemotion Amsterdam 2017Going fullstack React(ive) - Paulo Lopes - Codemotion Amsterdam 2017
Going fullstack React(ive) - Paulo Lopes - Codemotion Amsterdam 2017
 
​"Delegates, Delegates everywhere" Владимир Миронов
​"Delegates, Delegates everywhere" Владимир Миронов​"Delegates, Delegates everywhere" Владимир Миронов
​"Delegates, Delegates everywhere" Владимир Миронов
 
JavaFX 2.0 With Alternative Languages - JavaOne 2011
JavaFX 2.0 With Alternative Languages - JavaOne 2011JavaFX 2.0 With Alternative Languages - JavaOne 2011
JavaFX 2.0 With Alternative Languages - JavaOne 2011
 
Kotlin Austin Droids April 14 2016
Kotlin Austin Droids April 14 2016Kotlin Austin Droids April 14 2016
Kotlin Austin Droids April 14 2016
 

More from Jaroslaw 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 nadchodzi
Jaroslaw 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 postarzaniu
Jaroslaw Palka
 
Patterns for organic architecture
Patterns for organic architecturePatterns for organic architecture
Patterns for organic architecture
Jaroslaw 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

AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
VictorSzoltysek
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service provider
mohitmore19
 

Recently uploaded (20)

8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students
 
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
 
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview Questions
 
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
 
10 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 202410 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 2024
 
Announcing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareAnnouncing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK Software
 
VTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnVTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learn
 
Architecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the pastArchitecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the past
 
The Top App Development Trends Shaping the Industry in 2024-25 .pdf
The Top App Development Trends Shaping the Industry in 2024-25 .pdfThe Top App Development Trends Shaping the Industry in 2024-25 .pdf
The Top App Development Trends Shaping the Industry in 2024-25 .pdf
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service provider
 
%in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park %in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park
 
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
 
%+27788225528 love spells in Vancouver Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Vancouver Psychic Readings, Attraction spells,Br...%+27788225528 love spells in Vancouver Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Vancouver Psychic Readings, Attraction spells,Br...
 
Microsoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdfMicrosoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdf
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
 
Define the academic and professional writing..pdf
Define the academic and professional writing..pdfDefine the academic and professional writing..pdf
Define the academic and professional writing..pdf
 

Patterns for JVM languages - Geecon 2014

  • 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.
  • 5. Because having pet projects is like solving crosswords everyday Or going to a gym Helps your brain to stay in shape
  • 6.
  • 7.
  • 10. source code ↓ target language source code ↓ machine code || interpreter
  • 15. So how does it all work?
  • 16. Diving into the stream
  • 20. local y = 1 x = 1 + y
  • 21.
  • 22.
  • 23.
  • 24. 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 ;
  • 26. 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 ;
  • 27. beware of left recursion
  • 29. Interpreter pattern Non terminal nodes Terminal nodes
  • 30.
  • 31. package pl.symentis.lua.grammar; import pl.symentis.lua.runtime.Context; public interface Statement { void execute(Context context); }
  • 32. package pl.symentis.lua.grammar; Import pl.symentis.lua.runtime.Context; public interface Expression<T> { T evaluate(Context ctx); }
  • 33. package pl.symentis.lua.runtime; public interface Context { VariableRef resolveVariable(String name); Scope enterScope(); Scope exitScope(); }
  • 34. package pl.symentis.lua.runtime; public interface Scope { Scope getOuterScope(); VariableRef resolveVariable(String name); void bindVariable(String name, Object value); }
  • 35. Into the forest of syntax tree
  • 36. x = 1
  • 37. 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); } }
  • 38. 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); } }
  • 39. 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); } }
  • 40. 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); } } }
  • 41. 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; }
  • 43. compiler → byte code org.ow2.asm:asm:jar me.qmx.jitescript:jitescript:jar
  • 44. 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); }
  • 45. 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); }
  • 46. 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); }
  • 47. x = 1
  • 48. 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)); } }
  • 49. 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; }
  • 50. When writing bytecode compiler it helps to think about Java code But at the end you need to think like stack machine :)
  • 51. .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
  • 52. Symbol table maps variable local to its symbolic name
  • 55. 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[] {});
  • 56. static final Handle HANDLE = new Handle( CodeBlock.H_INVOKESTATIC, p(Lua4JDynamicBootstrap.class), "bootstrap", sig(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class));
  • 57. 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)); }
  • 58. 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
  • 59. What's next? graal + truffle dynamic compiler + AST interpreter
  • 61. Let the eternal stream of bytecode flow through your body
  • 62. Q&A