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

Commits on Feb 18, 2015

  1. 2
    Copy the full SHA
    3364a21 View commit details
  2. Copy the full SHA
    1c54123 View commit details
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/*
* Copyright (c) 2015 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:
*
* Eclipse Public License version 1.0
* GNU General Public License version 2
* GNU Lesser General Public License version 2.1
*/

package org.jruby.truffle.nodes.coerce;

import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.dsl.NodeChild;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.source.SourceSection;

import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.nodes.dispatch.CallDispatchHeadNode;
import org.jruby.truffle.nodes.dispatch.DispatchHeadNodeFactory;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.control.RaiseException;
import org.jruby.truffle.runtime.core.RubyString;
import org.jruby.truffle.runtime.core.RubySymbol;

@NodeChild(value = "child", type = RubyNode.class)
public abstract class SymbolOrToStrNode extends RubyNode {

@Child private CallDispatchHeadNode toStr;

public SymbolOrToStrNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
toStr = DispatchHeadNodeFactory.createMethodCall(context);
}

public SymbolOrToStrNode(SymbolOrToStrNode prev) {
super(prev);
toStr = prev.toStr;
}

@Specialization
public String coerceRubySymbol(RubySymbol symbol) {
return symbol.toString();
}

@Specialization
public String coerceRubyString(RubyString string) {
return string.toString();
}

@Specialization(guards = { "!isRubySymbol", "!isRubyString" })
public String coerceObject(VirtualFrame frame, Object object) {
notDesignedForCompilation();

final Object coerced;

try {
coerced = toStr.call(frame, object, "to_str", null);
} catch (RaiseException e) {
if (e.getRubyException().getLogicalClass() == getContext().getCoreLibrary().getNoMethodErrorClass()) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(getContext().getCoreLibrary().typeErrorNoImplicitConversion(object, "String", this));
} else {
throw e;
}
}

if (coerced instanceof RubyString) {
return ((RubyString) coerced).toString();
} else {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(getContext().getCoreLibrary().typeErrorBadCoercion(object, "String", "to_str", coerced, this));
}
}

@Override
public abstract String executeString(VirtualFrame frame);

@Override
public final Object execute(VirtualFrame frame) {
return executeString(frame);
}
}
101 changes: 29 additions & 72 deletions truffle/src/main/java/org/jruby/truffle/nodes/core/ModuleNodes.java
Original file line number Diff line number Diff line change
@@ -20,14 +20,15 @@
import com.oracle.truffle.api.nodes.Node.Child;
import com.oracle.truffle.api.source.Source;
import com.oracle.truffle.api.source.SourceSection;

import com.oracle.truffle.api.utilities.ConditionProfile;

import org.jcodings.Encoding;
import org.jruby.runtime.Visibility;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.nodes.RubyRootNode;
import org.jruby.truffle.nodes.cast.BooleanCastNode;
import org.jruby.truffle.nodes.cast.BooleanCastNodeFactory;
import org.jruby.truffle.nodes.coerce.SymbolOrToStrNodeFactory;
import org.jruby.truffle.nodes.coerce.ToStrNode;
import org.jruby.truffle.nodes.coerce.ToStrNodeFactory;
import org.jruby.truffle.nodes.control.SequenceNode;
@@ -780,9 +781,8 @@ public Object methodMissing(RubyModule module, RubySymbol name) {
}

@CoreMethod(names = "const_set", required = 2)
public abstract static class ConstSetNode extends CoreMethodNode {

@Child private ToStrNode toStrNode;
@NodeChildren({ @NodeChild("module"), @NodeChild("name"), @NodeChild("value") })
public abstract static class ConstSetNode extends RubyNode {

public ConstSetNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
@@ -792,23 +792,12 @@ public ConstSetNode(ConstSetNode prev) {
super(prev);
}

@Specialization
public Object setConstant(RubyModule module, RubySymbol name, Object value) {
notDesignedForCompilation();

return setConstant(module, name.toString(), value);
}

@Specialization(guards = "!isRubySymbol(arguments[1])")
public Object setConstant(VirtualFrame frame, RubyModule module, Object name, Object value) {
if (toStrNode == null) {
CompilerDirectives.transferToInterpreter();
toStrNode = insert(ToStrNodeFactory.create(getContext(), getSourceSection(), null));
}

return setConstant(module, toStrNode.executeRubyString(frame, name).toString(), value);
@CreateCast("name")
public RubyNode coerceToString(RubyNode name) {
return SymbolOrToStrNodeFactory.create(getContext(), getSourceSection(), name);
}

@Specialization
public Object setConstant(RubyModule module, String name, Object value) {
notDesignedForCompilation();

@@ -823,7 +812,8 @@ public Object setConstant(RubyModule module, String name, Object value) {
}

@CoreMethod(names = "define_method", needsBlock = true, required = 1, optional = 1)
public abstract static class DefineMethodNode extends CoreMethodNode {
@NodeChildren({ @NodeChild("module"), @NodeChild("name"), @NodeChild("proc"), @NodeChild("block") })
public abstract static class DefineMethodNode extends RubyNode {

public DefineMethodNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
@@ -833,52 +823,40 @@ public DefineMethodNode(DefineMethodNode prev) {
super(prev);
}

@Specialization
public RubySymbol defineMethod(RubyModule module, RubyString name, @SuppressWarnings("unused") UndefinedPlaceholder proc, RubyProc block) {
notDesignedForCompilation();

return defineMethod(module, name, block, UndefinedPlaceholder.INSTANCE);
@CreateCast("name")
public RubyNode coerceToString(RubyNode name) {
return SymbolOrToStrNodeFactory.create(getContext(), getSourceSection(), name);
}

@Specialization
public RubySymbol defineMethod(RubyModule module, RubyString name, RubyProc proc, @SuppressWarnings("unused") UndefinedPlaceholder block) {
notDesignedForCompilation();

final RubySymbol symbol = getContext().getSymbolTable().getSymbol(name.getBytes());
defineMethod(module, symbol, proc);
return symbol;
}

@Specialization
public RubySymbol defineMethod(RubyModule module, RubySymbol name, @SuppressWarnings("unused") UndefinedPlaceholder proc, RubyProc block) {
public RubySymbol defineMethod(RubyModule module, String name, UndefinedPlaceholder proc, RubyProc block) {
notDesignedForCompilation();

return defineMethod(module, name, block, UndefinedPlaceholder.INSTANCE);
}

@Specialization
public RubySymbol defineMethod(RubyModule module, RubySymbol name, RubyProc proc, @SuppressWarnings("unused") UndefinedPlaceholder block) {
notDesignedForCompilation();

defineMethod(module, name, proc);
return name;
public RubySymbol defineMethod(RubyModule module, String name, RubyProc proc, UndefinedPlaceholder block) {
return defineMethod(module, name, proc);
}

@Specialization
public RubySymbol defineMethod(RubyModule module, RubySymbol name, RubyMethod method, UndefinedPlaceholder block) {
public RubySymbol defineMethod(RubyModule module, String name, RubyMethod method, UndefinedPlaceholder block) {
notDesignedForCompilation();

module.addMethod(this, method.getMethod().withNewName(name.toString()));
module.addMethod(this, method.getMethod().withNewName(name));

return name;
return getContext().getSymbolTable().getSymbol(name);
}

private void defineMethod(RubyModule module, RubySymbol name, RubyProc proc) {
private RubySymbol defineMethod(RubyModule module, String name, RubyProc proc) {
notDesignedForCompilation();

final CallTarget modifiedCallTarget = proc.getCallTargetForMethods();
final InternalMethod modifiedMethod = new InternalMethod(proc.getSharedMethodInfo(), name.toString(), module, Visibility.PUBLIC, false, modifiedCallTarget, proc.getDeclarationFrame());
final InternalMethod modifiedMethod = new InternalMethod(proc.getSharedMethodInfo(), name, module, Visibility.PUBLIC, false, modifiedCallTarget, proc.getDeclarationFrame());
module.addMethod(this, modifiedMethod);

return getContext().getSymbolTable().getSymbol(name);
}

}
@@ -1486,9 +1464,8 @@ public RubyModule removeClassVariable(RubyModule module, RubySymbol name) {
}

@CoreMethod(names = "remove_const", required = 1, visibility = Visibility.PRIVATE)
public abstract static class RemoveConstNode extends CoreMethodNode {

@Child private ToStrNode toStrNode;
@NodeChildren({ @NodeChild("module"), @NodeChild("name") })
public abstract static class RemoveConstNode extends RubyNode {

public RemoveConstNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
@@ -1498,33 +1475,13 @@ public RemoveConstNode(RemoveConstNode prev) {
super(prev);
}

@Specialization
public Object removeConst(RubyModule module, RubyString name) {
notDesignedForCompilation();

return removeConstant(module, name.toString());
@CreateCast("name")
public RubyNode coerceToString(RubyNode name) {
return SymbolOrToStrNodeFactory.create(getContext(), getSourceSection(), name);
}

@Specialization
public Object removeConst(RubyModule module, RubySymbol name) {
notDesignedForCompilation();

return removeConstant(module, name.toString());
}

@Specialization(guards = "!isRubySymbol(arguments[1])")
public Object removeConst(VirtualFrame frame, RubyModule module, Object name) {
notDesignedForCompilation();

if (toStrNode == null) {
CompilerDirectives.transferToInterpreter();
toStrNode = insert(ToStrNodeFactory.create(getContext(), getSourceSection(), null));
}

return removeConstant(module, toStrNode.executeRubyString(frame, name).toString());
}

private Object removeConstant(RubyModule module, String name) {
Object removeConstant(RubyModule module, String name) {
RubyConstant oldConstant = module.removeConstant(this, name);
if (oldConstant == null) {
CompilerDirectives.transferToInterpreter();