Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: jruby/jruby
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: e0f5e82bcbfd
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 97fa30d23784
Choose a head ref
  • 2 commits
  • 6 files changed
  • 1 contributor

Commits on Jan 3, 2016

  1. Copy the full SHA
    46bdc3c View commit details

Commits on Jan 4, 2016

  1. [Truffle] DATA locking.

    chrisseaton committed Jan 4, 2016
    Copy the full SHA
    97fa30d View commit details
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;
}
}
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;

@@ -2952,4 +2956,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 */
4 changes: 0 additions & 4 deletions spec/truffle/tags/language/predefined/data_tags.txt
Original file line number Diff line number Diff line change
@@ -3,7 +3,3 @@ 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__
Original file line number Diff line number Diff line change
@@ -605,6 +605,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());
}

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