Skip to content

Commit

Permalink
Showing 13 changed files with 229 additions and 179 deletions.
14 changes: 14 additions & 0 deletions core/src/main/java/org/jruby/ast/RootNode.java
Original file line number Diff line number Diff line change
@@ -48,8 +48,13 @@ public class RootNode extends Node {
private StaticScope staticScope;
private Node bodyNode;
private String file;
private int endPosition;

public RootNode(ISourcePosition position, DynamicScope scope, Node bodyNode, String file) {
this(position, scope, bodyNode, file, -1);
}

public RootNode(ISourcePosition position, DynamicScope scope, Node bodyNode, String file, int endPosition) {
super(position, bodyNode.containsVariableAssignment());

assert bodyNode != null : "bodyNode is not null";
@@ -58,6 +63,7 @@ public RootNode(ISourcePosition position, DynamicScope scope, Node bodyNode, Str
this.staticScope = scope.getStaticScope();
this.bodyNode = bodyNode;
this.file = file;
this.endPosition = endPosition;
}

public NodeType getNodeType() {
@@ -108,4 +114,12 @@ public <T> T accept(NodeVisitor<T> iVisitor) {
public List<Node> childNodes() {
return createList(bodyNode);
}

public boolean hasEndPosition() {
return endPosition != -1;
}

public int getEndPosition() {
return endPosition;
}
}
212 changes: 106 additions & 106 deletions core/src/main/java/org/jruby/ast/visitor/NodeVisitor.java
Original file line number Diff line number Diff line change
@@ -41,110 +41,110 @@
* @author Benoit Cerrina
**/
public interface NodeVisitor<T> {
public T visitAliasNode(AliasNode iVisited);
public T visitAndNode(AndNode iVisited);
public T visitArgsNode(ArgsNode iVisited);
public T visitArgsCatNode(ArgsCatNode iVisited);
public T visitArgsPushNode(ArgsPushNode iVisited);
public T visitArgumentNode(ArgumentNode iVisited);
public T visitArrayNode(ArrayNode iVisited);
public T visitAttrAssignNode(AttrAssignNode iVisited);
public T visitBackRefNode(BackRefNode iVisited);
public T visitBeginNode(BeginNode iVisited);
public T visitBignumNode(BignumNode iVisited);
public T visitBlockArgNode(BlockArgNode iVisited);
public T visitBlockNode(BlockNode iVisited);
public T visitBlockPassNode(BlockPassNode iVisited);
public T visitBreakNode(BreakNode iVisited);
public T visitConstDeclNode(ConstDeclNode iVisited);
public T visitClassVarAsgnNode(ClassVarAsgnNode iVisited);
public T visitClassVarDeclNode(ClassVarDeclNode iVisited);
public T visitClassVarNode(ClassVarNode iVisited);
public T visitCallNode(CallNode iVisited);
public T visitCaseNode(CaseNode iVisited);
public T visitClassNode(ClassNode iVisited);
public T visitColon2Node(Colon2Node iVisited);
public T visitColon3Node(Colon3Node iVisited);
public T visitComplexNode(ComplexNode iVisited);
public T visitConstNode(ConstNode iVisited);
public T visitDAsgnNode(DAsgnNode iVisited);
public T visitDRegxNode(DRegexpNode iVisited);
public T visitDStrNode(DStrNode iVisited);
public T visitDSymbolNode(DSymbolNode iVisited);
public T visitDVarNode(DVarNode iVisited);
public T visitDXStrNode(DXStrNode iVisited);
public T visitDefinedNode(DefinedNode iVisited);
public T visitDefnNode(DefnNode iVisited);
public T visitDefsNode(DefsNode iVisited);
public T visitDotNode(DotNode iVisited);
public T visitEncodingNode(EncodingNode iVisited);
public T visitEnsureNode(EnsureNode iVisited);
public T visitEvStrNode(EvStrNode iVisited);
public T visitFCallNode(FCallNode iVisited);
public T visitFalseNode(FalseNode iVisited);
public T visitFixnumNode(FixnumNode iVisited);
public T visitFlipNode(FlipNode iVisited);
public T visitFloatNode(FloatNode iVisited);
public T visitForNode(ForNode iVisited);
public T visitGlobalAsgnNode(GlobalAsgnNode iVisited);
public T visitGlobalVarNode(GlobalVarNode iVisited);
public T visitHashNode(HashNode iVisited);
public T visitInstAsgnNode(InstAsgnNode iVisited);
public T visitInstVarNode(InstVarNode iVisited);
public T visitIfNode(IfNode iVisited);
public T visitIterNode(IterNode iVisited);
public T visitKeywordArgNode(KeywordArgNode iVisited);
public T visitKeywordRestArgNode(KeywordRestArgNode iVisited);
public T visitLambdaNode(LambdaNode iVisited);
public T visitListNode(ListNode iVisited);
public T visitLiteralNode(LiteralNode iVisited);
public T visitLocalAsgnNode(LocalAsgnNode iVisited);
public T visitLocalVarNode(LocalVarNode iVisited);
public T visitMultipleAsgnNode(MultipleAsgnNode iVisited);
public T visitMatch2Node(Match2Node iVisited);
public T visitMatch3Node(Match3Node iVisited);
public T visitMatchNode(MatchNode iVisited);
public T visitModuleNode(ModuleNode iVisited);
public T visitNewlineNode(NewlineNode iVisited);
public T visitNextNode(NextNode iVisited);
public T visitNilNode(NilNode iVisited);
public T visitNthRefNode(NthRefNode iVisited);
public T visitOpElementAsgnNode(OpElementAsgnNode iVisited);
public T visitOpAsgnNode(OpAsgnNode iVisited);
public T visitOpAsgnAndNode(OpAsgnAndNode iVisited);
public T visitOpAsgnOrNode(OpAsgnOrNode iVisited);
public T visitOptArgNode(OptArgNode iVisited);
public T visitOrNode(OrNode iVisited);
public T visitPreExeNode(PreExeNode iVisited);
public T visitPostExeNode(PostExeNode iVisited);
public T visitRationalNode(RationalNode iVisited);
public T visitRedoNode(RedoNode iVisited);
public T visitRegexpNode(RegexpNode iVisited);
public T visitRequiredKeywordArgumentValueNode(RequiredKeywordArgumentValueNode iVisited);
public T visitRescueBodyNode(RescueBodyNode iVisited);
public T visitRescueNode(RescueNode iVisited);
public T visitRestArgNode(RestArgNode iVisited);
public T visitRetryNode(RetryNode iVisited);
public T visitReturnNode(ReturnNode iVisited);
public T visitRootNode(RootNode iVisited);
public T visitSClassNode(SClassNode iVisited);
public T visitSelfNode(SelfNode iVisited);
public T visitSplatNode(SplatNode iVisited);
public T visitStarNode(StarNode iVisited);
public T visitStrNode(StrNode iVisited);
public T visitSuperNode(SuperNode iVisited);
public T visitSValueNode(SValueNode iVisited);
public T visitSymbolNode(SymbolNode iVisited);
public T visitTrueNode(TrueNode iVisited);
public T visitUndefNode(UndefNode iVisited);
public T visitUntilNode(UntilNode iVisited);
public T visitVAliasNode(VAliasNode iVisited);
public T visitVCallNode(VCallNode iVisited);
public T visitWhenNode(WhenNode iVisited);
public T visitWhileNode(WhileNode iVisited);
public T visitXStrNode(XStrNode iVisited);
public T visitYieldNode(YieldNode iVisited);
public T visitZArrayNode(ZArrayNode iVisited);
public T visitZSuperNode(ZSuperNode iVisited);
public T visitOther(Node iVisited);
T visitAliasNode(AliasNode iVisited);
T visitAndNode(AndNode iVisited);
T visitArgsNode(ArgsNode iVisited);
T visitArgsCatNode(ArgsCatNode iVisited);
T visitArgsPushNode(ArgsPushNode iVisited);
T visitArgumentNode(ArgumentNode iVisited);
T visitArrayNode(ArrayNode iVisited);
T visitAttrAssignNode(AttrAssignNode iVisited);
T visitBackRefNode(BackRefNode iVisited);
T visitBeginNode(BeginNode iVisited);
T visitBignumNode(BignumNode iVisited);
T visitBlockArgNode(BlockArgNode iVisited);
T visitBlockNode(BlockNode iVisited);
T visitBlockPassNode(BlockPassNode iVisited);
T visitBreakNode(BreakNode iVisited);
T visitConstDeclNode(ConstDeclNode iVisited);
T visitClassVarAsgnNode(ClassVarAsgnNode iVisited);
T visitClassVarDeclNode(ClassVarDeclNode iVisited);
T visitClassVarNode(ClassVarNode iVisited);
T visitCallNode(CallNode iVisited);
T visitCaseNode(CaseNode iVisited);
T visitClassNode(ClassNode iVisited);
T visitColon2Node(Colon2Node iVisited);
T visitColon3Node(Colon3Node iVisited);
T visitComplexNode(ComplexNode iVisited);
T visitConstNode(ConstNode iVisited);
T visitDAsgnNode(DAsgnNode iVisited);
T visitDRegxNode(DRegexpNode iVisited);
T visitDStrNode(DStrNode iVisited);
T visitDSymbolNode(DSymbolNode iVisited);
T visitDVarNode(DVarNode iVisited);
T visitDXStrNode(DXStrNode iVisited);
T visitDefinedNode(DefinedNode iVisited);
T visitDefnNode(DefnNode iVisited);
T visitDefsNode(DefsNode iVisited);
T visitDotNode(DotNode iVisited);
T visitEncodingNode(EncodingNode iVisited);
T visitEnsureNode(EnsureNode iVisited);
T visitEvStrNode(EvStrNode iVisited);
T visitFCallNode(FCallNode iVisited);
T visitFalseNode(FalseNode iVisited);
T visitFixnumNode(FixnumNode iVisited);
T visitFlipNode(FlipNode iVisited);
T visitFloatNode(FloatNode iVisited);
T visitForNode(ForNode iVisited);
T visitGlobalAsgnNode(GlobalAsgnNode iVisited);
T visitGlobalVarNode(GlobalVarNode iVisited);
T visitHashNode(HashNode iVisited);
T visitInstAsgnNode(InstAsgnNode iVisited);
T visitInstVarNode(InstVarNode iVisited);
T visitIfNode(IfNode iVisited);
T visitIterNode(IterNode iVisited);
T visitKeywordArgNode(KeywordArgNode iVisited);
T visitKeywordRestArgNode(KeywordRestArgNode iVisited);
T visitLambdaNode(LambdaNode iVisited);
T visitListNode(ListNode iVisited);
T visitLiteralNode(LiteralNode iVisited);
T visitLocalAsgnNode(LocalAsgnNode iVisited);
T visitLocalVarNode(LocalVarNode iVisited);
T visitMultipleAsgnNode(MultipleAsgnNode iVisited);
T visitMatch2Node(Match2Node iVisited);
T visitMatch3Node(Match3Node iVisited);
T visitMatchNode(MatchNode iVisited);
T visitModuleNode(ModuleNode iVisited);
T visitNewlineNode(NewlineNode iVisited);
T visitNextNode(NextNode iVisited);
T visitNilNode(NilNode iVisited);
T visitNthRefNode(NthRefNode iVisited);
T visitOpElementAsgnNode(OpElementAsgnNode iVisited);
T visitOpAsgnNode(OpAsgnNode iVisited);
T visitOpAsgnAndNode(OpAsgnAndNode iVisited);
T visitOpAsgnOrNode(OpAsgnOrNode iVisited);
T visitOptArgNode(OptArgNode iVisited);
T visitOrNode(OrNode iVisited);
T visitPreExeNode(PreExeNode iVisited);
T visitPostExeNode(PostExeNode iVisited);
T visitRationalNode(RationalNode iVisited);
T visitRedoNode(RedoNode iVisited);
T visitRegexpNode(RegexpNode iVisited);
T visitRequiredKeywordArgumentValueNode(RequiredKeywordArgumentValueNode iVisited);
T visitRescueBodyNode(RescueBodyNode iVisited);
T visitRescueNode(RescueNode iVisited);
T visitRestArgNode(RestArgNode iVisited);
T visitRetryNode(RetryNode iVisited);
T visitReturnNode(ReturnNode iVisited);
T visitRootNode(RootNode iVisited);
T visitSClassNode(SClassNode iVisited);
T visitSelfNode(SelfNode iVisited);
T visitSplatNode(SplatNode iVisited);
T visitStarNode(StarNode iVisited);
T visitStrNode(StrNode iVisited);
T visitSuperNode(SuperNode iVisited);
T visitSValueNode(SValueNode iVisited);
T visitSymbolNode(SymbolNode iVisited);
T visitTrueNode(TrueNode iVisited);
T visitUndefNode(UndefNode iVisited);
T visitUntilNode(UntilNode iVisited);
T visitVAliasNode(VAliasNode iVisited);
T visitVCallNode(VCallNode iVisited);
T visitWhenNode(WhenNode iVisited);
T visitWhileNode(WhileNode iVisited);
T visitXStrNode(XStrNode iVisited);
T visitYieldNode(YieldNode iVisited);
T visitZArrayNode(ZArrayNode iVisited);
T visitZSuperNode(ZSuperNode iVisited);
T visitOther(Node iVisited);
}
9 changes: 9 additions & 0 deletions core/src/main/java/org/jruby/lexer/yacc/RubyLexer.java
Original file line number Diff line number Diff line change
@@ -420,6 +420,7 @@ public final void reset() {
private int ruby_sourceline = 0;
private int heredoc_end = 0;
private int line_count = 0;
private int line_offset = 0;

/**
* Has lexing started yet?
@@ -438,6 +439,8 @@ public int p(int offset) {

public int nextc() {
if (lex_p == lex_pend) {
line_offset += lex_pend;

ByteList v = lex_nextline;
lex_nextline = null;

@@ -1501,6 +1504,7 @@ private int yylex() throws IOException {
return at();
case '_':
if (was_bol() && whole_match_p(END_MARKER, false)) {
line_offset += lex_pend;
__end__seen = true;
eofp = true;

@@ -2955,4 +2959,9 @@ private char scanOct(int count) throws IOException {

return value;
}

public int getLineOffset() {
return line_offset;
}

}
12 changes: 10 additions & 2 deletions core/src/main/java/org/jruby/parser/ParserSupport.java
Original file line number Diff line number Diff line change
@@ -185,6 +185,14 @@ public Node newline_node(Node node, ISourcePosition position) {
}

public Node addRootNode(Node topOfAST) {
final int endPosition;

if (lexer.isEndSeen()) {
endPosition = lexer.getLineOffset();
} else {
endPosition = -1;
}

if (result.getBeginNodes().isEmpty()) {
ISourcePosition position;
if (topOfAST == null) {
@@ -194,7 +202,7 @@ public Node addRootNode(Node topOfAST) {
position = topOfAST.getPosition();
}

return new RootNode(position, result.getScope(), topOfAST, lexer.getFile());
return new RootNode(position, result.getScope(), topOfAST, lexer.getFile(), endPosition);
}

ISourcePosition position = topOfAST != null ? topOfAST.getPosition() : result.getBeginNodes().get(0).getPosition();
@@ -206,7 +214,7 @@ public Node addRootNode(Node topOfAST) {
// Add real top to new top (unless this top is empty [only begin/end nodes or truly empty])
if (topOfAST != null) newTopOfAST.add(topOfAST);

return new RootNode(position, result.getScope(), newTopOfAST, lexer.getFile());
return new RootNode(position, result.getScope(), newTopOfAST, lexer.getFile(), endPosition);
}

/* MRI: block_append */
5 changes: 1 addition & 4 deletions spec/truffle/tags/language/predefined/data_tags.txt
Original file line number Diff line number Diff line change
@@ -3,7 +3,4 @@ slow:The DATA constant does not exist when the main script contains no __END__
slow:The DATA constant does not exist when an included file has a __END__
slow:The DATA constant does not change when an included files also has a __END__
slow:The DATA constant is included in an otherwise empty file
fails:The DATA constant succeeds in locking the file DATA came from
fails:The DATA constant does not change when an included files also has a __END__
fails:The DATA constant is included in an otherwise empty file
fails:The DATA constant exists when the main script contains __END__
slow:The DATA constant succeeds in locking the file DATA came from
9 changes: 1 addition & 8 deletions truffle/src/main/java/org/jruby/truffle/Main.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved. This
* Copyright (c) 2015, 2016 Oracle and/or its affiliates. All rights reserved. This
* code is released under a tri EPL/GPL/LGPL license. You can use it,
* redistribute it and/or modify it under the terms of the:
*
@@ -55,13 +55,6 @@ public static void main(String[] args) {

RootNode scriptNode = (RootNode) runtime.parseFromMain(filename, in);

// If no DATA, we're done with the stream, shut it down
if (runtime.fetchGlobalConstant("DATA") == null) {
try {
in.close();
} catch (IOException ioe) {
}
}
ThreadContext context = runtime.getCurrentContext();

String oldFile = context.getFile();
Original file line number Diff line number Diff line change
@@ -235,7 +235,7 @@ public GraalNode(RubyContext context, SourceSection sourceSection) {
@TruffleBoundary
@Specialization
public boolean graal() {
return Truffle.getRuntime().getName().toLowerCase(Locale.ENGLISH).contains("graal");
return getContext().onGraal();
}

}
Original file line number Diff line number Diff line change
@@ -226,7 +226,7 @@ public Object mulCoerced(VirtualFrame frame, long a, DynamicObject b) {
}
}

@CoreMethod(names = {"/", "__slash__"}, required = 1)
@CoreMethod(names = { "/", "__slash__" }, required = 1)
public abstract static class DivNode extends CoreMethodArrayArgumentsNode {

private final BranchProfile bGreaterZero = BranchProfile.create();
@@ -558,7 +558,7 @@ public Object lessEqualCoerced(VirtualFrame frame, long a, Object b) {
}
}

@CoreMethod(names = {"==", "==="}, required = 1)
@CoreMethod(names = { "==", "===" }, required = 1)
public abstract static class EqualNode extends CoreMethodArrayArgumentsNode {

@Child private CallDispatchHeadNode reverseCallNode;
@@ -596,7 +596,7 @@ public boolean equal(long a, DynamicObject b) {
@Specialization(guards = {
"!isInteger(b)",
"!isLong(b)",
"!isRubyBignum(b)"})
"!isRubyBignum(b)" })
public Object equal(VirtualFrame frame, Object a, Object b) {
return reverseCallNode.call(frame, b, "==", null, a);
}
@@ -636,10 +636,10 @@ public int compare(long a, DynamicObject b) {
}

@Specialization(guards = {
"!isInteger(b)",
"!isLong(b)",
"!isDouble(b)",
"!isRubyBignum(b)"})
"!isInteger(b)",
"!isLong(b)",
"!isDouble(b)",
"!isRubyBignum(b)" })
public Object compare(VirtualFrame frame, Object a, Object b) {
return ruby(frame, "begin; b, a = math_coerce(other, :compare_error); a <=> b; rescue ArgumentError; nil; end", "other", b);
}
@@ -682,7 +682,7 @@ public boolean greaterEqual(long a, DynamicObject b) {
"!isRubyBignum(b)",
"!isInteger(b)",
"!isLong(b)",
"!isDouble(b)"})
"!isDouble(b)" })
public Object greaterEqualCoerced(VirtualFrame frame, long a, Object b) {
return ruby(frame, "b, a = math_coerce other, :compare_error; a >= b", "other", b);
}
@@ -725,7 +725,7 @@ public boolean greater(long a, DynamicObject b) {
"!isRubyBignum(b)",
"!isInteger(b)",
"!isLong(b)",
"!isDouble(b)"})
"!isDouble(b)" })
public Object greaterCoerced(VirtualFrame frame, long a, Object b) {
return ruby(frame, "b, a = math_coerce(other, :compare_error); a > b", "other", b);
}
@@ -875,7 +875,7 @@ public Object leftShiftWithOverflow(long a, int b) {
public Object leftShiftNeg(VirtualFrame frame, long a, int b) {
if (rightShiftNode == null) {
CompilerDirectives.transferToInterpreter();
rightShiftNode = insert(RightShiftNodeFactory.create(getContext(), getSourceSection(), new RubyNode[] { null, null }));
rightShiftNode = insert(RightShiftNodeFactory.create(getContext(), getSourceSection(), new RubyNode[]{ null, null }));
}
return rightShiftNode.executeRightShift(frame, a, -b);
}
@@ -917,7 +917,7 @@ public RightShiftNode(RubyContext context, SourceSection sourceSection) {

@Specialization(guards = "b >= 0")
public int rightShift(VirtualFrame frame, int a, int b,
@Cached("createBinaryProfile()") ConditionProfile profile) {
@Cached("createBinaryProfile()") ConditionProfile profile) {
if (profile.profile(b >= Integer.SIZE - 1)) {
return a < 0 ? -1 : 0;
} else {
@@ -927,7 +927,7 @@ public int rightShift(VirtualFrame frame, int a, int b,

@Specialization(guards = "b >= 0")
public Object rightShift(VirtualFrame frame, long a, int b,
@Cached("createBinaryProfile()") ConditionProfile profile) {
@Cached("createBinaryProfile()") ConditionProfile profile) {
if (profile.profile(b >= Long.SIZE - 1)) {
return a < 0 ? -1 : 0; // int
} else {
@@ -939,7 +939,7 @@ public Object rightShift(VirtualFrame frame, long a, int b,
public Object rightShiftNeg(VirtualFrame frame, long a, int b) {
if (leftShiftNode == null) {
CompilerDirectives.transferToInterpreter();
leftShiftNode = insert(FixnumNodesFactory.LeftShiftNodeFactory.create(getContext(), getSourceSection(), new RubyNode[] { null, null }));
leftShiftNode = insert(FixnumNodesFactory.LeftShiftNodeFactory.create(getContext(), getSourceSection(), new RubyNode[]{ null, null }));
}
return leftShiftNode.executeLeftShift(frame, a, -b);
}
@@ -959,7 +959,7 @@ public int rightShift(long a, DynamicObject b) {
public Object rightShiftNeg(VirtualFrame frame, long a, DynamicObject b) {
if (leftShiftNode == null) {
CompilerDirectives.transferToInterpreter();
leftShiftNode = insert(FixnumNodesFactory.LeftShiftNodeFactory.create(getContext(), getSourceSection(), new RubyNode[] { null, null }));
leftShiftNode = insert(FixnumNodesFactory.LeftShiftNodeFactory.create(getContext(), getSourceSection(), new RubyNode[]{ null, null }));
}
return leftShiftNode.executeLeftShift(frame, a, Layouts.BIGNUM.getValue(b).negate());
}
@@ -979,7 +979,7 @@ protected static boolean isPositive(DynamicObject b) {

}

@CoreMethod(names = {"abs", "magnitude"})
@CoreMethod(names = { "abs", "magnitude" })
public abstract static class AbsNode extends CoreMethodArrayArgumentsNode {

public AbsNode(RubyContext context, SourceSection sourceSection) {
Original file line number Diff line number Diff line change
@@ -90,7 +90,7 @@ public enum YAMLEncoding {
YAML_ANY_ENCODING(UTF8Encoding.INSTANCE),
YAML_UTF8_ENCODING(UTF8Encoding.INSTANCE),
YAML_UTF16LE_ENCODING(UTF16LEEncoding.INSTANCE),
YAML_UTF16BE_ENCODING(UTF16BEEncoding.INSTANCE), ;
YAML_UTF16BE_ENCODING(UTF16BEEncoding.INSTANCE);

YAMLEncoding(Encoding encoding) {
this.encoding = encoding;
@@ -163,7 +163,7 @@ private Object doParse(DynamicObject parserObject, DynamicObject yaml, DynamicOb
Object notExplicit = !((DocumentEndEvent) event).getExplicit();
invoke(handler, "end_document", notExplicit);
} else if (event.is(Event.ID.Alias)) {
Object alias = stringOrNilFor(((AliasEvent)event).getAnchor(), tainted);
Object alias = stringOrNilFor(((AliasEvent) event).getAnchor(), tainted);
invoke(handler, "alias", alias);
} else if (event.is(Event.ID.Scalar)) {
handleScalar((ScalarEvent) event, tainted, handler);
@@ -239,14 +239,14 @@ private void handleDocumentStart(DocumentStartEvent dse, boolean tainted, Object
DumperOptions.Version _version = dse.getVersion();
Integer[] versionInts = _version == null ? null : _version.getArray();
Object version = versionInts == null ?
Layouts.ARRAY.createArray(getContext().getCoreLibrary().getArrayFactory(), null, 0):
Layouts.ARRAY.createArray(getContext().getCoreLibrary().getArrayFactory(), new Object[]{versionInts[0], versionInts[1]}, 2);
Layouts.ARRAY.createArray(getContext().getCoreLibrary().getArrayFactory(), null, 0) :
Layouts.ARRAY.createArray(getContext().getCoreLibrary().getArrayFactory(), new Object[]{ versionInts[0], versionInts[1] }, 2);

Map<String, String> tagsMap = dse.getTags();
DynamicObject tags = Layouts.ARRAY.createArray(getContext().getCoreLibrary().getArrayFactory(), null, 0);
if (tagsMap != null && tagsMap.size() > 0) {
for (Map.Entry<String, String> tag : tagsMap.entrySet()) {
Object key = stringFor(tag.getKey(), tainted);
Object key = stringFor(tag.getKey(), tainted);
Object value = stringFor(tag.getValue(), tainted);
ruby("tags.push [key, value]", "tags", tags, "key", key, "value", value);
}
@@ -317,12 +317,18 @@ private static int translateStyle(Character style) {
if (style == null) return 0; // any

switch (style) {
case 0: return 1; // plain
case '\'': return 2; // single-quoted
case '"': return 3; // double-quoted
case '|': return 4; // literal
case '>': return 5; // folded
default: return 0; // any
case 0:
return 1; // plain
case '\'':
return 2; // single-quoted
case '"':
return 3; // double-quoted
case '|':
return 4; // literal
case '>':
return 5; // folded
default:
return 0; // any
}
}

22 changes: 19 additions & 3 deletions truffle/src/main/java/org/jruby/truffle/runtime/RubyContext.java
Original file line number Diff line number Diff line change
@@ -67,6 +67,7 @@
import java.math.BigInteger;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.atomic.AtomicLong;
@@ -125,6 +126,12 @@ public RubyContext(Ruby runtime, TruffleLanguage.Env env) {

compilerOptions = Truffle.getRuntime().createCompilerOptions();

if (!onGraal()) {
System.err.println("WARNING: JRuby+Truffle is designed to be run with a JVM that has the Graal compiler. " +
"The compilation is disabled Without the Graal compiler and it runs much slower. " +
"See https://github.com/jruby/jruby/wiki/Truffle-FAQ#how-do-i-get-jrubytruffle");
}

if (compilerOptions.supportsOption("MinTimeThreshold")) {
compilerOptions.setOption("MinTimeThreshold", 100000000);
}
@@ -200,6 +207,10 @@ public RubyContext(Ruby runtime, TruffleLanguage.Env env) {
initialize();
}

public boolean onGraal() {
return Truffle.getRuntime().getName().toLowerCase(Locale.ENGLISH).contains("graal");
}

public Object send(Object object, String methodName, DynamicObject block, Object... arguments) {
CompilerAsserts.neverPartOfCompilation();

@@ -244,7 +255,7 @@ private MaterializedFrame setupInlineRubyFrame(Frame frame, Object... arguments)
RubyArguments.getSelf(frame.getArguments()),
null,
DeclarationContext.INSTANCE_EVAL,
new Object[] {}),
new Object[]{}),
new FrameDescriptor(frame.getFrameDescriptor().getDefaultValue()));

if (arguments.length % 2 == 1) {
@@ -391,7 +402,7 @@ public Object eval(ParserContext parserContext, ByteList code, DynamicObject bin

@TruffleBoundary
public Object parseAndExecute(Source source, Encoding defaultEncoding, ParserContext parserContext, Object self, MaterializedFrame parentFrame, boolean ownScopeForAssignments,
DeclarationContext declarationContext, Node currentNode) {
DeclarationContext declarationContext, Node currentNode) {
final RubyRootNode rootNode = parse(source, defaultEncoding, parserContext, parentFrame, ownScopeForAssignments, currentNode);
return execute(parserContext, declarationContext, rootNode, parentFrame, self);
}
@@ -419,7 +430,7 @@ private Object execute(ParserContext parserContext, DeclarationContext declarati
final InternalMethod method = new InternalMethod(rootNode.getSharedMethodInfo(), rootNode.getSharedMethodInfo().getName(),
declaringModule, Visibility.PUBLIC, callTarget);

return callTarget.call(RubyArguments.pack(method, parentFrame, null, self, null, declarationContext, new Object[] {}));
return callTarget.call(RubyArguments.pack(method, parentFrame, null, self, null, declarationContext, new Object[]{}));
}

public long getNextObjectID() {
@@ -605,6 +616,11 @@ public Object execute(final org.jruby.ast.RootNode rootNode) {

final RubyRootNode newRootNode = originalRootNode.withBody(wrappedBody);

if (rootNode.hasEndPosition()) {
final Object data = inlineRubyHelper(null, "Truffle::Primitive.get_data(file, offset)", "file", StringOperations.createString(this, ByteList.create(inputFile)), "offset", rootNode.getEndPosition());
Layouts.MODULE.getFields(coreLibrary.getObjectClass()).setConstant(this, null, "DATA", data);
}

return execute(ParserContext.TOP_LEVEL, DeclarationContext.TOP_LEVEL, newRootNode, null, coreLibrary.getMainObject());
}

Original file line number Diff line number Diff line change
@@ -107,6 +107,7 @@ public class BodyTranslator extends Translator {
Arrays.asList("$:", "$LOAD_PATH", "$-I", "$\"", "$LOADED_FEATURES", "$<", "$FILENAME", "$?", "$-a", "$-l", "$-p", "$!"));

private static final Map<String, String> GLOBAL_VARIABLE_ALIASES = new HashMap<String, String>();

static {
Map<String, String> m = GLOBAL_VARIABLE_ALIASES;
m.put("$-I", "$LOAD_PATH");
@@ -817,6 +818,7 @@ private RubyNode openModule(SourceSection sourceSection, RubyNode defineOrGetNod
* for self, which is the module or class object that is being defined. Therefore for a module or
* class definition we translate into a special method. We run that method with self set to be the
* newly allocated module or class.
* </p>
*/
private MethodDefinitionNode compileClassNode(SourceSection sourceSection, String name, org.jruby.ast.Node bodyNode) {
RubyNode body;
@@ -1151,7 +1153,7 @@ public RubyNode visitDefsNode(org.jruby.ast.DefsNode node) {
}

protected RubyNode translateMethodDefinition(SourceSection sourceSection, RubyNode classNode, String methodName, org.jruby.ast.ArgsNode argsNode, org.jruby.ast.Node bodyNode,
boolean isDefs) {
boolean isDefs) {
final Arity arity = MethodTranslator.getArity(argsNode);
final ArgumentDescriptor[] argumentDescriptors = Helpers.argsNodeToArgumentDescriptors(argsNode);
final SharedMethodInfo sharedMethodInfo = new SharedMethodInfo(sourceSection, environment.getLexicalScope(), arity, methodName, false, argumentDescriptors, false, false, false);
@@ -1629,7 +1631,7 @@ public RubyNode visitInstAsgnNode(org.jruby.ast.InstAsgnNode node) {
}
} else if (path.equals(corePath + "rubinius/bootstrap/string.rb") || path.equals(corePath + "rubinius/common/string.rb")) {
if (name.equals("@hash")) {
ret = StringNodesFactory.ModifyBangNodeFactory.create(context, sourceSection, new RubyNode[] {});
ret = StringNodesFactory.ModifyBangNodeFactory.create(context, sourceSection, new RubyNode[]{});
return addNewlineIfNeeded(node, ret);
}
} else if (path.equals(corePath + "rubinius/common/range.rb")) {
@@ -1692,18 +1694,18 @@ public RubyNode visitInstVarNode(org.jruby.ast.InstVarNode node) {
ret = new RubyCallNode(context, sourceSection, "full", self, null, false);
return addNewlineIfNeeded(node, ret);
} else if (name.equals("@regexp")) {
ret = MatchDataNodesFactory.RegexpNodeFactory.create(context, sourceSection, new RubyNode[] { self });
ret = MatchDataNodesFactory.RegexpNodeFactory.create(context, sourceSection, new RubyNode[]{ self });
return addNewlineIfNeeded(node, ret);
} else if (name.equals("@names")) {
ret = RegexpNodesFactory.RubiniusNamesNodeGen.create(context, sourceSection, self);
return addNewlineIfNeeded(node, ret);
}
} else if (path.equals(corePath + "rubinius/bootstrap/string.rb") || path.equals(corePath + "rubinius/common/string.rb")) {
if (name.equals("@num_bytes")) {
ret = StringNodesFactory.ByteSizeNodeFactory.create(context, sourceSection, new RubyNode[] { self });
ret = StringNodesFactory.ByteSizeNodeFactory.create(context, sourceSection, new RubyNode[]{ self });
return addNewlineIfNeeded(node, ret);
} else if (name.equals("@data")) {
final RubyNode bytes = StringNodesFactory.BytesNodeFactory.create(context, sourceSection, new RubyNode[] { self });
final RubyNode bytes = StringNodesFactory.BytesNodeFactory.create(context, sourceSection, new RubyNode[]{ self });
// Wrap in a StringData instance, see shims.
LiteralNode stringDataClass = new LiteralNode(context, sourceSection, context.getCoreLibrary().getStringDataClass());
ret = new RubyCallNode(context, sourceSection, "new", stringDataClass, null, false, bytes);
@@ -1722,21 +1724,21 @@ public RubyNode visitInstVarNode(org.jruby.ast.InstVarNode node) {
ret = HashNodesFactory.DefaultValueNodeFactory.create(context, sourceSection, self);
return addNewlineIfNeeded(node, ret);
} else if (name.equals("@default_proc")) {
ret = HashNodesFactory.DefaultProcNodeFactory.create(context, sourceSection, new RubyNode[] { self });
ret = HashNodesFactory.DefaultProcNodeFactory.create(context, sourceSection, new RubyNode[]{ self });
return addNewlineIfNeeded(node, ret);
} else if (name.equals("@size")) {
ret = HashNodesFactory.SizeNodeFactory.create(context, sourceSection, new RubyNode[] { self });
ret = HashNodesFactory.SizeNodeFactory.create(context, sourceSection, new RubyNode[]{ self });
return addNewlineIfNeeded(node, ret);
}
} else if (path.equals(corePath + "rubinius/common/range.rb") || path.equals(corePath + "rubinius/api/shims/range.rb")) {
if (name.equals("@begin")) {
ret = RangeNodesFactory.BeginNodeFactory.create(context, sourceSection, new RubyNode[] { self });
ret = RangeNodesFactory.BeginNodeFactory.create(context, sourceSection, new RubyNode[]{ self });
return addNewlineIfNeeded(node, ret);
} else if (name.equals("@end")) {
ret = RangeNodesFactory.EndNodeFactory.create(context, sourceSection, new RubyNode[] { self });
ret = RangeNodesFactory.EndNodeFactory.create(context, sourceSection, new RubyNode[]{ self });
return addNewlineIfNeeded(node, ret);
} else if (name.equals("@excl")) {
ret = RangeNodesFactory.ExcludeEndNodeFactory.create(context, sourceSection, new RubyNode[] { self });
ret = RangeNodesFactory.ExcludeEndNodeFactory.create(context, sourceSection, new RubyNode[]{ self });
return addNewlineIfNeeded(node, ret);
}
}
@@ -2409,7 +2411,7 @@ private RubyNode translateRationalComplex(SourceSection sourceSection, String na
return new RubyCallNode(
context, sourceSection, "convert",
new ReadLiteralConstantNode(context, sourceSection, moduleNode, name),
null, false, true, new RubyNode[]{a, b});
null, false, true, new RubyNode[]{ a, b });
}

@Override
@@ -2634,9 +2636,9 @@ public RubyNode visitUndefNode(org.jruby.ast.UndefNode node) {
final SourceSection sourceSection = translate(node.getPosition());
final DynamicObject nameSymbol = translateNameNodeToSymbol(node.getName());

final RubyNode ret = UndefMethodNodeFactory.create(context, sourceSection, new RubyNode[] {
final RubyNode ret = UndefMethodNodeFactory.create(context, sourceSection, new RubyNode[]{
new RaiseIfFrozenNode(new GetDefaultDefineeNode(context, sourceSection)),
new LiteralNode(context, sourceSection, new Object[] { nameSymbol })
new LiteralNode(context, sourceSection, new Object[]{ nameSymbol })
});
return addNewlineIfNeeded(node, ret);
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013, 2015 Oracle and/or its affiliates. All rights reserved. This
* Copyright (c) 2013, 2016 Oracle and/or its affiliates. All rights reserved. This
* code is released under a tri EPL/GPL/LGPL license. You can use it,
* redistribute it and/or modify it under the terms of the:
*
@@ -45,7 +45,7 @@

public class TranslatorDriver {

public static enum ParserContext {
public enum ParserContext {
TOP_LEVEL, SHELL, MODULE, EVAL, INLINE
}

@@ -146,14 +146,6 @@ private RubyRootNode parse(Node currentNode, RubyContext context, Source source,
}
}

// Get the DATA constant

final Object data = getData(context);

if (data != null) {
Layouts.MODULE.getFields(context.getCoreLibrary().getObjectClass()).setConstant(context, currentNode, "DATA", data);
}

// Translate to Ruby Truffle nodes

final BodyTranslator translator = new BodyTranslator(currentNode, context, null, environment, source, parserContext == ParserContext.TOP_LEVEL);
@@ -212,11 +204,6 @@ private RubyRootNode parse(Node currentNode, RubyContext context, Source source,
return new RubyRootNode(context, truffleNode.getSourceSection(), environment.getFrameDescriptor(), sharedMethodInfo, truffleNode, environment.needsDeclarationFrame());
}

private Object getData(RubyContext context) {
// TODO CS 18-Apr-15 restore the DATA functionality
return null;
}

private TranslatorEnvironment environmentForFrame(RubyContext context, MaterializedFrame frame) {
if (frame == null) {
return null;
20 changes: 19 additions & 1 deletion truffle/src/main/ruby/core/shims.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright (c) 2014, 2015 Oracle and/or its affiliates. All rights reserved. This
# Copyright (c) 2014, 2016 Oracle and/or its affiliates. All rights reserved. This
# code is released under a tri EPL/GPL/LGPL license. You can use it,
# redistribute it and/or modify it under the terms of the:
#
@@ -261,3 +261,21 @@ module Enumerable
# JRuby uses this for example to make proxy settings visible to stdlib/uri/common.rb

ENV_JAVA = {}

# Truffle::Primitive.get_data is used by RubyContext#execute to prepare the DATA constant

module Truffle::Primitive
def self.get_data(path, offset)
file = File.open(path)
file.seek(offset)

# I think if the file can't be locked then we just silently ignore
file.flock(File::LOCK_EX | File::LOCK_NB)

Truffle::Primitive.at_exit true do
file.flock(File::LOCK_UN)
end

file
end
end

0 comments on commit f1d645c

Please sign in to comment.