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: 06473c9ec7fd^
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 73c52acf5447
Choose a head ref
  • 3 commits
  • 3 files changed
  • 1 contributor

Commits on Dec 2, 2016

  1. [Truffle] Fixed optional variable assignments using compounded consta…

    …nts with ||= assignments.
    nirvdrum committed Dec 2, 2016
    Copy the full SHA
    06473c9 View commit details
  2. [Truffle] Fixed optional variable assignments using compounded consta…

    …nts with &&= assignments.
    nirvdrum committed Dec 2, 2016
    Copy the full SHA
    e756c0a View commit details
  3. [Truffle] Fixed optional variable assignments using compounded consta…

    …nts with operator assignments.
    nirvdrum committed Dec 2, 2016
    Copy the full SHA
    73c52ac View commit details
4 changes: 0 additions & 4 deletions spec/truffle/tags/language/optional_assignments_tags.txt

This file was deleted.

Original file line number Diff line number Diff line change
@@ -10,6 +10,7 @@
package org.jruby.truffle.language.constants;

import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.nodes.NodeUtil;
import com.oracle.truffle.api.source.SourceSection;
import org.jcodings.specific.UTF8Encoding;
import org.jruby.truffle.Layouts;
@@ -77,4 +78,8 @@ public Object isDefined(VirtualFrame frame) {
}
}

public RubyNode makeWriteNode(RubyNode rhs) {
return new WriteConstantNode(name, NodeUtil.cloneNode(moduleNode), rhs);
}

}
64 changes: 45 additions & 19 deletions truffle/src/main/java/org/jruby/truffle/parser/BodyTranslator.java
Original file line number Diff line number Diff line change
@@ -2570,6 +2570,10 @@ public RubyNode visitNthRefNode(NthRefParseNode node) {

@Override
public RubyNode visitOpAsgnAndNode(OpAsgnAndParseNode node) {
return visitOpAsgnAndNode(node, node.getFirstNode().accept(this), node.getSecondNode().accept(this));
}

private RubyNode visitOpAsgnAndNode(ParseNode node, RubyNode lhs, RubyNode rhs) {
/*
* This doesn't translate as you might expect!
*
@@ -2579,10 +2583,7 @@ public RubyNode visitOpAsgnAndNode(OpAsgnAndParseNode node) {
final RubySourceSection sourceSection = translate(node.getPosition());
final SourceSection fullSourceSection = sourceSection.toSourceSection(source);

final ParseNode lhs = node.getFirstNode();
final ParseNode rhs = node.getSecondNode();

final RubyNode andNode = new AndNode(lhs.accept(this), rhs.accept(this));
final RubyNode andNode = new AndNode(lhs, rhs);
andNode.unsafeSetSourceSection(sourceSection);

final RubyNode ret = new DefinedWrapperNode(context, fullSourceSection, context.getCoreStrings().ASSIGNMENT, andNode);
@@ -2591,11 +2592,33 @@ public RubyNode visitOpAsgnAndNode(OpAsgnAndParseNode node) {

@Override
public RubyNode visitOpAsgnConstDeclNode(OpAsgnConstDeclParseNode node) {
// TODO (eregon, 7 Nov. 2016): Is there any semantic difference?
if ("&&".equals(node.getOperator())) {
return visitOpAsgnAndNode(new OpAsgnAndParseNode(node.getPosition(), node.getFirstNode(), node.getSecondNode()));
} else {
return visitOpAsgnOrNode(new OpAsgnOrParseNode(node.getPosition(), node.getFirstNode(), node.getSecondNode()));
RubyNode lhs = node.getFirstNode().accept(this);
RubyNode rhs = node.getSecondNode().accept(this);

if (!(rhs instanceof WriteConstantNode)) {
rhs = ((ReadConstantNode) lhs).makeWriteNode(rhs);
}

switch (node.getOperator()) {
case "&&": {
return visitOpAsgnAndNode(node, lhs, rhs);
}

case "||": {
final RubyNode defined = new DefinedNode(context, translateSourceSection(source, lhs.getRubySourceSection()), lhs);
lhs = new AndNode(defined, lhs);

return visitOpAsgnOrNode(node, lhs, rhs);
}

default: {
final RubySourceSection sourceSection = translate(node.getPosition());
final RubyCallNodeParameters callParameters = new RubyCallNodeParameters(context, sourceSection.toSourceSection(source), lhs, node.getOperator(), null, new RubyNode[] { rhs }, false, true, false, false, false);
final RubyNode opNode = context.getCoreMethods().createCallNode(callParameters);
final RubyNode ret = ((ReadConstantNode) lhs).makeWriteNode(opNode);

return addNewlineIfNeeded(node, ret);
}
}
}

@@ -2676,6 +2699,19 @@ public RubyNode visitOpAsgnNode(OpAsgnParseNode node) {

@Override
public RubyNode visitOpAsgnOrNode(OpAsgnOrParseNode node) {
RubyNode lhs = node.getFirstNode().accept(this);
RubyNode rhs = node.getSecondNode().accept(this);

// This is needed for class variables. Constants are handled separately in visitOpAsgnConstDeclNode.
if (node.getFirstNode().needsDefinitionCheck() && !(node.getFirstNode() instanceof InstVarParseNode)) {
RubyNode defined = new DefinedNode(context, translateSourceSection(source, lhs.getRubySourceSection()), lhs);
lhs = new AndNode(defined, lhs);
}

return visitOpAsgnOrNode(node, lhs, rhs);
}

private RubyNode visitOpAsgnOrNode(ParseNode node, RubyNode lhs, RubyNode rhs) {
/*
* This doesn't translate as you might expect!
*
@@ -2685,16 +2721,6 @@ public RubyNode visitOpAsgnOrNode(OpAsgnOrParseNode node) {
final RubySourceSection sourceSection = translate(node.getPosition());
final SourceSection fullSourceSection = sourceSection.toSourceSection(source);

RubyNode lhs = node.getFirstNode().accept(this);
RubyNode rhs = node.getSecondNode().accept(this);

// I think this is only required for constants - not instance variables

if (node.getFirstNode().needsDefinitionCheck() && !(node.getFirstNode() instanceof InstVarParseNode)) {
RubyNode defined = new DefinedNode(context, translateSourceSection(source, lhs.getRubySourceSection()), lhs);
lhs = new AndNode(defined, lhs);
}

final RubyNode ret = new DefinedWrapperNode(context, fullSourceSection, context.getCoreStrings().ASSIGNMENT,
new OrNode(lhs, rhs));