-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Copy part 13 to part 14 (unchanged, including Java package).
- Loading branch information
Showing
92 changed files
with
6,546 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
plugins { | ||
id 'antlr' | ||
id 'me.champeau.jmh' version '0.6.6' | ||
} | ||
|
||
dependencies { | ||
antlr "org.antlr:antlr4:$antlr_version" | ||
implementation "org.graalvm.js:js:$graal_version" | ||
implementation "org.graalvm.tools:profiler:$graal_version" | ||
implementation "org.apache.commons:commons-text:1.10.0" | ||
} | ||
|
||
// required to allow GraalVM to discover our EasyScript language class | ||
test { | ||
jvmArgs '-Dgraalvm.locatorDisabled=true' | ||
} |
81 changes: 81 additions & 0 deletions
81
part-14/src/jmh/java/com/endoflineblog/truffle/part_13/CounterThisBenchmark.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
package com.endoflineblog.truffle.part_13; | ||
|
||
import org.openjdk.jmh.annotations.Benchmark; | ||
|
||
/** | ||
* A benchmark measuring the performance of storing state inside class instances. | ||
*/ | ||
public class CounterThisBenchmark extends TruffleBenchmark { | ||
private static final int INPUT = 1_000_000; | ||
|
||
private static final String COUNTER_CLASS = "" + | ||
"class CounterDirect { " + | ||
" constructor() { " + | ||
" this.count = 0; " + | ||
" } " + | ||
" increment() { " + | ||
" this.count = this.count + 1; " + | ||
" } " + | ||
" getCount() { " + | ||
" return this.count; " + | ||
" } " + | ||
"} " + | ||
"class CounterIndexed { " + | ||
" constructor() { " + | ||
" this['count'] = 0; " + | ||
" } " + | ||
" increment() { " + | ||
" this['count'] = this['count'] + 1; " + | ||
" } " + | ||
" getCount() { " + | ||
" return this['count']; " + | ||
" } " + | ||
"}"; | ||
|
||
@Override | ||
public void setup() { | ||
super.setup(); | ||
|
||
this.truffleContext.eval("ezs", COUNTER_CLASS); | ||
this.truffleContext.eval("ezs", COUNT_WITH_THIS_IN_FOR); | ||
|
||
this.truffleContext.eval("js", COUNTER_CLASS); | ||
this.truffleContext.eval("js", COUNT_WITH_THIS_IN_FOR); | ||
} | ||
|
||
private static final String COUNT_WITH_THIS_IN_FOR = "" + | ||
"function countWithThisInForDirect(n) { " + | ||
" const counter = new CounterDirect(); " + | ||
" for (let i = 0; i < n; i = i + 1) { " + | ||
" counter.increment(); " + | ||
" } " + | ||
" return counter.getCount(); " + | ||
"} " + | ||
"function countWithThisInForIndexed(n) { " + | ||
" const counter = new CounterIndexed(); " + | ||
" for (let i = 0; i < n; i = i + 1) { " + | ||
" counter['increment'](); " + | ||
" } " + | ||
" return counter['getCount'](); " + | ||
"}"; | ||
|
||
@Benchmark | ||
public int count_with_this_in_for_direct_ezs() { | ||
return this.truffleContext.eval("ezs", "countWithThisInForDirect(" + INPUT + ");").asInt(); | ||
} | ||
|
||
@Benchmark | ||
public int count_with_this_in_for_direct_js() { | ||
return this.truffleContext.eval("js", "countWithThisInForDirect(" + INPUT + ");").asInt(); | ||
} | ||
|
||
@Benchmark | ||
public int count_with_this_in_for_indexed_ezs() { | ||
return this.truffleContext.eval("ezs", "countWithThisInForIndexed(" + INPUT + ");").asInt(); | ||
} | ||
|
||
@Benchmark | ||
public int count_with_this_in_for_indexed_js() { | ||
return this.truffleContext.eval("js", "countWithThisInForIndexed(" + INPUT + ");").asInt(); | ||
} | ||
} |
43 changes: 43 additions & 0 deletions
43
part-14/src/jmh/java/com/endoflineblog/truffle/part_13/TruffleBenchmark.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
package com.endoflineblog.truffle.part_13; | ||
|
||
import org.graalvm.polyglot.Context; | ||
import org.openjdk.jmh.annotations.BenchmarkMode; | ||
import org.openjdk.jmh.annotations.Fork; | ||
import org.openjdk.jmh.annotations.Measurement; | ||
import org.openjdk.jmh.annotations.Mode; | ||
import org.openjdk.jmh.annotations.OutputTimeUnit; | ||
import org.openjdk.jmh.annotations.Scope; | ||
import org.openjdk.jmh.annotations.Setup; | ||
import org.openjdk.jmh.annotations.State; | ||
import org.openjdk.jmh.annotations.TearDown; | ||
import org.openjdk.jmh.annotations.Warmup; | ||
|
||
import java.util.concurrent.TimeUnit; | ||
|
||
/** | ||
* The common superclass of all JMH benchmarks. | ||
* Identical to the class with the same name from part 12. | ||
*/ | ||
@Warmup(iterations = 5, time = 1) | ||
@Measurement(iterations = 5, time = 1) | ||
@Fork(value = 1, jvmArgsAppend = { | ||
"-Dgraalvm.locatorDisabled=true", | ||
"--add-exports", | ||
"org.graalvm.truffle/com.oracle.truffle.api.staticobject=ALL-UNNAMED" | ||
}) | ||
@BenchmarkMode(Mode.AverageTime) | ||
@OutputTimeUnit(TimeUnit.MICROSECONDS) | ||
@State(Scope.Benchmark) | ||
public abstract class TruffleBenchmark { | ||
protected Context truffleContext; | ||
|
||
@Setup | ||
public void setup() { | ||
this.truffleContext = Context.create(); | ||
} | ||
|
||
@TearDown | ||
public void tearDown() { | ||
this.truffleContext.close(); | ||
} | ||
} |
72 changes: 72 additions & 0 deletions
72
part-14/src/main/antlr/com/endoflineblog/truffle/part_13/parsing/antlr/EasyScript.g4
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
grammar EasyScript ; | ||
|
||
@header{ | ||
package com.endoflineblog.truffle.part_13.parsing.antlr; | ||
} | ||
|
||
start : stmt+ EOF ; | ||
|
||
stmt : kind=('var' | 'let' | 'const') binding (',' binding)* ';'? #VarDeclStmt | ||
| expr1 ';'? #ExprStmt | ||
| 'function' subroutine_decl ';'? #FuncDeclStmt | ||
| 'return' expr1? ';'? #ReturnStmt | ||
| '{' stmt* '}' ';'? #BlockStmt | ||
| 'if' '(' cond=expr1 ')' then_stmt=stmt ('else' else_stmt=stmt)? #IfStmt | ||
| 'while' '(' cond=expr1 ')' body=stmt #WhileStmt | ||
| 'do' '{' stmt* '}' 'while' '(' cond=expr1 ')' ';'? #DoWhileStmt | ||
| 'for' '(' init=stmt? ';' cond=expr1? ';' updt=expr1? ')' body=stmt #ForStmt | ||
| 'break' ';'? #BreakStmt | ||
| 'continue' ';'? #ContinueStmt | ||
| 'class' ID '{' class_member* '}' ';'? #ClassDeclStmt | ||
; | ||
binding : ID ('=' expr1)? ; | ||
class_member : subroutine_decl ; | ||
subroutine_decl : name=ID '(' args=func_args ')' '{' stmt* '}' ; | ||
func_args : (ID (',' ID)* )? ; | ||
|
||
expr1 : ID '=' expr1 #AssignmentExpr1 | ||
| object=expr5 '.' ID '=' rvalue=expr1 #PropertyWriteExpr1 | ||
| arr=expr5 '[' index=expr1 ']' '=' rvalue=expr1 #ArrayIndexWriteExpr1 | ||
| expr2 #PrecedenceTwoExpr1 | ||
; | ||
expr2 : left=expr2 c=('===' | '!==') right=expr3 #EqNotEqExpr2 | ||
| expr3 #PrecedenceThreeExpr2 | ||
; | ||
expr3 : left=expr3 c=('<' | '<=' | '>' | '>=') right=expr4 #ComparisonExpr3 | ||
| expr4 #PrecedenceFourExpr3 | ||
; | ||
expr4 : left=expr4 o=('+' | '-') right=expr5 #AddSubtractExpr4 | ||
| '-' expr5 #UnaryMinusExpr4 | ||
| expr5 #PrecedenceFiveExpr4 | ||
; | ||
expr5 : expr5 '.' ID #PropertyReadExpr5 | ||
| arr=expr5 '[' index=expr1 ']' #ArrayIndexReadExpr5 | ||
| expr5 '(' (expr1 (',' expr1)*)? ')' #CallExpr5 | ||
| expr6 #PrecedenceSixExpr5 | ||
; | ||
expr6 : literal #LiteralExpr6 | ||
| 'this' #ThisExpr6 | ||
| ID #ReferenceExpr6 | ||
| '[' (expr1 (',' expr1)*)? ']' #ArrayLiteralExpr6 | ||
| 'new' constr=expr6 ('('(expr1 (',' expr1)*)?')')? #NewExpr6 | ||
| '(' expr1 ')' #PrecedenceOneExpr6 | ||
; | ||
|
||
literal : INT | DOUBLE | 'undefined' | bool_literal | string_literal ; | ||
bool_literal : 'true' | 'false' ; | ||
|
||
fragment DIGIT : [0-9] ; | ||
INT : DIGIT+ ; | ||
DOUBLE : DIGIT+ '.' DIGIT+ ; | ||
|
||
fragment LETTER : [a-zA-Z$_] ; | ||
ID : LETTER (LETTER | DIGIT)* ; | ||
|
||
string_literal: SINGLE_QUOTE_STRING | DOUBLE_QUOTE_STRING ; | ||
// see https://stackoverflow.com/questions/24557953/handling-string-literals-which-end-in-an-escaped-quote-in-antlr4 | ||
// for details | ||
SINGLE_QUOTE_STRING : '\'' (~[\\'\r\n] | '\\' ~[\r\n])* '\'' ; | ||
DOUBLE_QUOTE_STRING : '"' (~[\\"\r\n] | '\\' ~[\r\n])* '"' ; | ||
// skip all whitespace | ||
WS : (' ' | '\r' | '\t' | '\n' | '\f')+ -> skip ; |
36 changes: 36 additions & 0 deletions
36
part-14/src/main/java/com/endoflineblog/truffle/part_13/EasyScriptLanguageContext.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
package com.endoflineblog.truffle.part_13; | ||
|
||
import com.endoflineblog.truffle.part_13.common.ShapesAndPrototypes; | ||
import com.oracle.truffle.api.TruffleLanguage; | ||
import com.oracle.truffle.api.nodes.Node; | ||
import com.oracle.truffle.api.object.DynamicObject; | ||
|
||
/** | ||
* The class of the context for the | ||
* {@link EasyScriptTruffleLanguage TruffleLanguage implementaton in this part of the series}. | ||
* Very similar to the class with the same name from part 12, | ||
* the only difference being that the {@link ShapesAndPrototypes} | ||
* object is now accessible from here, instead of just the string prototype. | ||
*/ | ||
public final class EasyScriptLanguageContext { | ||
private static final TruffleLanguage.ContextReference<EasyScriptLanguageContext> REF = | ||
TruffleLanguage.ContextReference.create(EasyScriptTruffleLanguage.class); | ||
|
||
/** Retrieve the current language context for the given {@link Node}. */ | ||
public static EasyScriptLanguageContext get(Node node) { | ||
return REF.get(node); | ||
} | ||
|
||
public final DynamicObject globalScopeObject; | ||
|
||
/** | ||
* The object containing the shapes and prototypes, | ||
* both for user-defined class instances, and for built-in objects. | ||
*/ | ||
public final ShapesAndPrototypes shapesAndPrototypes; | ||
|
||
public EasyScriptLanguageContext(DynamicObject globalScopeObject, ShapesAndPrototypes shapesAndPrototypes) { | ||
this.globalScopeObject = globalScopeObject; | ||
this.shapesAndPrototypes = shapesAndPrototypes; | ||
} | ||
} |
Oops, something went wrong.