Skip to content

Commit

Permalink
Copy part 13 to part 14 (unchanged, including Java package).
Browse files Browse the repository at this point in the history
  • Loading branch information
skinny85 committed Mar 30, 2024
1 parent 410adc6 commit a4fd5d4
Show file tree
Hide file tree
Showing 92 changed files with 6,546 additions and 1 deletion.
16 changes: 16 additions & 0 deletions part-14/build.gradle
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'
}
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();
}
}
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();
}
}
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 ;
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;
}
}
Loading

0 comments on commit a4fd5d4

Please sign in to comment.