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: 2e4e39af0db3
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 648bfaa05937
Choose a head ref
  • 4 commits
  • 4 files changed
  • 1 contributor

Commits on Oct 8, 2015

  1. [Truffle] Add slow spec tag.

    eregon committed Oct 8, 2015
    Copy the full SHA
    21b580d View commit details
  2. Copy the full SHA
    57af10c View commit details
  3. Copy the full SHA
    e538c66 View commit details
  4. [Truffle] No need for a ModuleTranslator anymore.

    * The default definee take care of properly finding the right definee,
      even in class_eval/instance_eval.
    eregon committed Oct 8, 2015
    Copy the full SHA
    648bfaa View commit details
1 change: 1 addition & 0 deletions spec/truffle/tags/language/alias_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
slow:The alias keyword on top level defines the alias on Object
Original file line number Diff line number Diff line change
@@ -9,6 +9,7 @@
*/
package org.jruby.truffle.translator;

import com.oracle.truffle.api.Truffle;
import com.oracle.truffle.api.frame.FrameSlot;
import com.oracle.truffle.api.nodes.NodeUtil;
import com.oracle.truffle.api.object.DynamicObject;
@@ -23,8 +24,8 @@
import org.jruby.lexer.yacc.InvalidSourcePosition;
import org.jruby.runtime.ArgumentDescriptor;
import org.jruby.runtime.Helpers;
import org.jruby.runtime.Visibility;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.nodes.RubyRootNode;
import org.jruby.truffle.nodes.ThreadLocalObjectNode;
import org.jruby.truffle.nodes.arguments.IsRubiniusUndefinedNode;
import org.jruby.truffle.nodes.cast.*;
@@ -99,7 +100,6 @@ public class BodyTranslator extends Translator {
protected final TranslatorEnvironment environment;

public boolean translatingForStatement = false;
public boolean useClassVariablesAsIfInClass = false;
private boolean translatingNextExpression = false;
private boolean translatingWhile = false;
protected String currentCallMethodName = null;
@@ -828,16 +828,50 @@ private RubyNode openModule(SourceSection sourceSection, RubyNode defineOrGetNod
final TranslatorEnvironment newEnvironment = new TranslatorEnvironment(context, environment, environment.getParseEnvironment(),
environment.getParseEnvironment().allocateReturnID(), true, true, sharedMethodInfo, name, false, null);

final ModuleTranslator classTranslator = new ModuleTranslator(currentNode, context, this, newEnvironment, source);
final BodyTranslator moduleTranslator = new BodyTranslator(currentNode, context, this, newEnvironment, source, false);

final MethodDefinitionNode definitionMethod = classTranslator.compileClassNode(sourceSection, name, bodyNode);
final MethodDefinitionNode definitionMethod = moduleTranslator.compileClassNode(sourceSection, name, bodyNode);

return new OpenModuleNode(context, sourceSection, defineOrGetNode, definitionMethod, newLexicalScope);
} finally {
environment.popLexicalScope();
}
}

/**
* Translates module and class nodes.
* <p>
* In Ruby, a module or class definition is somewhat like a method. It has a local scope and a value
* 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.
*/
private MethodDefinitionNode compileClassNode(SourceSection sourceSection, String name, org.jruby.ast.Node bodyNode) {
RubyNode body;

parentSourceSection.push(sourceSection);
try {
body = translateNodeOrNil(sourceSection, bodyNode);
} finally {
parentSourceSection.pop();
}

if (environment.getFlipFlopStates().size() > 0) {
body = SequenceNode.sequence(context, sourceSection, initFlipFlopStates(sourceSection), body);
}

body = new CatchReturnPlaceholderNode(context, sourceSection, body, environment.getReturnID());

final RubyRootNode rootNode = new RubyRootNode(context, sourceSection, environment.getFrameDescriptor(), environment.getSharedMethodInfo(), body, environment.needsDeclarationFrame());

return new MethodDefinitionNode(
context,
sourceSection,
environment.getSharedMethodInfo().getName(),
environment.getSharedMethodInfo(),
Truffle.getRuntime().createCallTarget(rootNode));
}

@Override
public RubyNode visitClassNode(org.jruby.ast.ClassNode node) {
final SourceSection sourceSection = translate(node.getPosition());
@@ -1080,7 +1114,36 @@ public RubyNode visitDefnNode(org.jruby.ast.DefnNode node) {
final SourceSection sourceSection = translate(node.getPosition(), node.getName());
final RubyNode classNode = new GetDefaultDefineeNode(context, sourceSection);

final RubyNode ret = translateMethodDefinition(sourceSection, classNode, node.getName(), node.getArgsNode(), node.getBodyNode(), false);
String methodName = node.getName();

// If we have a method we've defined in a node, but would like to delegate some corner cases out to the
// Rubinius implementation for simplicity, we need a way to resolve the naming conflict. The naive solution
// here is to append "_internal" to the method name, which can then be called like any other method. This is
// a bit different than aliasing because normally if a Rubinius method name conflicts with an already defined
// method, we simply ignore the method definition. Here we explicitly rename the method so it's always defined.

final String path = sourceSection.getSource().getPath();
final String coreRubiniusPath = context.getCoreLibrary().getCoreLoadPath() + "/core/rubinius/";
if (path.startsWith(coreRubiniusPath)) {
boolean rename = false;

if (path.equals(coreRubiniusPath + "common/array.rb")) {
rename = methodName.equals("zip");
} else if (path.equals(coreRubiniusPath + "common/float.rb")) {
rename = methodName.equals("round");
} else if (path.equals(coreRubiniusPath + "common/range.rb")) {
rename = methodName.equals("each") || methodName.equals("step") || methodName.equals("to_a");
} else if (path.equals(coreRubiniusPath + "common/integer.rb")) {
rename = methodName.equals("downto") || methodName.equals("upto");
}

if (rename) {
methodName = methodName + "_internal";
}
}

final RubyNode ret = translateMethodDefinition(sourceSection, classNode, methodName, node.getArgsNode(), node.getBodyNode(), false);

return addNewlineIfNeeded(node, ret);
}

@@ -1774,10 +1837,6 @@ public RubyNode visitIterNode(org.jruby.ast.IterNode node) {
final MethodTranslator methodCompiler = new MethodTranslator(currentNode, context, this, newEnvironment, true, source, argsNode);
methodCompiler.translatingForStatement = translatingForStatement;

if (translatingForStatement && useClassVariablesAsIfInClass) {
methodCompiler.useClassVariablesAsIfInClass = true;
}

final RubyNode ret = methodCompiler.compileBlockNode(translate(node.getPosition()), sharedMethodInfo.getName(), node.getBodyNode(), sharedMethodInfo, Type.PROC);
return addNewlineIfNeeded(node, ret);
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -137,13 +137,7 @@ private RubyRootNode parse(Node currentNode, RubyContext context, Source source,

// Translate to Ruby Truffle nodes

final BodyTranslator translator;

if (parserContext == ParserContext.MODULE) {
translator = new ModuleTranslator(currentNode, context, null, environment, source);
} else {
translator = new BodyTranslator(currentNode, context, null, environment, source, parserContext == ParserContext.TOP_LEVEL);
}
final BodyTranslator translator = new BodyTranslator(currentNode, context, null, environment, source, parserContext == ParserContext.TOP_LEVEL);

RubyNode truffleNode;