Skip to content

Commit

Permalink
Merge branch 'master' into truffle-head
Browse files Browse the repository at this point in the history
  • Loading branch information
chrisseaton committed Dec 25, 2014
2 parents f3e944c + 5ec7e73 commit 587715a
Show file tree
Hide file tree
Showing 40 changed files with 665 additions and 167 deletions.
3 changes: 2 additions & 1 deletion core/src/main/java/org/jruby/truffle/TruffleBridgeImpl.java
Expand Up @@ -14,6 +14,7 @@
import com.oracle.truffle.api.Truffle;
import com.oracle.truffle.api.frame.MaterializedFrame;
import com.oracle.truffle.api.source.SourceSection;
import org.jcodings.specific.UTF8Encoding;
import org.jruby.TruffleBridge;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.truffle.nodes.RubyNode;
Expand Down Expand Up @@ -161,7 +162,7 @@ public Object execute(final TranslatorDriver.ParserContext parserContext, final
source = Source.fromBytes(bytes, inputFile, new BytesDecoder.UTF8BytesDecoder());
}

return truffleContext.execute(truffleContext, source, parserContext, self, parentFrame, null, new NodeWrapper() {
return truffleContext.execute(truffleContext, source, UTF8Encoding.INSTANCE, parserContext, self, parentFrame, null, new NodeWrapper() {
@Override
public RubyNode wrap(RubyNode node) {
RubyContext context = node.getContext();
Expand Down
29 changes: 27 additions & 2 deletions core/src/main/java/org/jruby/truffle/nodes/cast/ArrayCastNode.java
Expand Up @@ -23,19 +23,30 @@
import org.jruby.truffle.runtime.core.RubyBignum;
import org.jruby.truffle.runtime.core.RubyNilClass;

/*
* TODO(CS): could probably unify this with SplatCastNode with some final configuration options.
*/
@NodeChild("child")
public abstract class ArrayCastNode extends RubyNode {

private final SplatCastNode.NilBehavior nilBehavior;

@Child protected DispatchHeadNode toArrayNode;

public ArrayCastNode(RubyContext context, SourceSection sourceSection) {
this(context, sourceSection, SplatCastNode.NilBehavior.NIL);
}

public ArrayCastNode(RubyContext context, SourceSection sourceSection, SplatCastNode.NilBehavior nilBehavior) {
super(context, sourceSection);
toArrayNode = new DispatchHeadNode(context, Dispatch.MissingBehavior.RETURN_MISSING);
this.nilBehavior = nilBehavior;
}

public ArrayCastNode(ArrayCastNode prev) {
super(prev);
toArrayNode = prev.toArrayNode;
nilBehavior = prev.nilBehavior;
}

protected abstract RubyNode getChild();
Expand Down Expand Up @@ -71,8 +82,22 @@ public RubyArray cast(RubyArray array) {
}

@Specialization
public RubyNilClass cast(RubyNilClass nil) {
return nil;
public Object cast(RubyNilClass nil) {
switch (nilBehavior) {
case EMPTY_ARRAY:
return new RubyArray(getContext().getCoreLibrary().getArrayClass());

case ARRAY_WITH_NIL:
return RubyArray.fromObject(getContext().getCoreLibrary().getArrayClass(), getContext().getCoreLibrary().getNilObject());

case NIL:
return nil;

default: {
CompilerAsserts.neverPartOfCompilation();
throw new UnsupportedOperationException();
}
}
}

@Specialization(guards = {"!isRubyNilClass", "!isRubyArray"})
Expand Down
101 changes: 101 additions & 0 deletions core/src/main/java/org/jruby/truffle/nodes/cast/HashCastNode.java
@@ -0,0 +1,101 @@
/*
* Copyright (c) 2014 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.cast;

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.Dispatch;
import org.jruby.truffle.nodes.dispatch.DispatchHeadNode;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.control.RaiseException;
import org.jruby.truffle.runtime.core.*;

// TODO(CS): copy and paste of ArrayCastNode

@NodeChild("child")
public abstract class HashCastNode extends RubyNode {

@Child protected DispatchHeadNode toHashNode;

public HashCastNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
toHashNode = new DispatchHeadNode(context, Dispatch.MissingBehavior.RETURN_MISSING);
}

public HashCastNode(HashCastNode prev) {
super(prev);
toHashNode = prev.toHashNode;
}

protected abstract RubyNode getChild();

@Specialization
public RubyNilClass cast(boolean value) {
return getContext().getCoreLibrary().getNilObject();
}

@Specialization
public RubyNilClass cast(int value) {
return getContext().getCoreLibrary().getNilObject();
}

@Specialization
public RubyNilClass cast(long value) {
return getContext().getCoreLibrary().getNilObject();
}

@Specialization
public RubyNilClass cast(double value) {
return getContext().getCoreLibrary().getNilObject();
}

@Specialization
public RubyNilClass cast(RubyBignum value) {
return getContext().getCoreLibrary().getNilObject();
}

@Specialization
public RubyHash cast(RubyHash hash) {
return hash;
}

@Specialization
public RubyNilClass cast(RubyNilClass nil) {
return nil;
}

@Specialization(guards = {"!isRubyNilClass", "!isRubyHash"})
public Object cast(VirtualFrame frame, RubyBasicObject object) {
notDesignedForCompilation();

final Object result = toHashNode.call(frame, object, "to_hash", null, new Object[]{});

if (result == Dispatch.MISSING) {
return getContext().getCoreLibrary().getNilObject();
}

if (!(result instanceof RubyHash)) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(getContext().getCoreLibrary().typeErrorShouldReturn(object.toString(), "to_hash", "HAsh", this));
}

return result;
}

@Override
public void executeVoid(VirtualFrame frame) {
getChild().executeVoid(frame);
}

}
Expand Up @@ -33,7 +33,8 @@ public abstract class SplatCastNode extends RubyNode {

public static enum NilBehavior {
EMPTY_ARRAY,
ARRAY_WITH_NIL
ARRAY_WITH_NIL,
NIL
}

private final NilBehavior nilBehavior;
Expand Down Expand Up @@ -91,9 +92,8 @@ public RubyArray splat(VirtualFrame frame, RubyArray array) {
public RubyArray splat(VirtualFrame frame, Object object) {
notDesignedForCompilation();

RubyString toAString = getContext().makeString("to_a"); // TODO

if (respondToCast.executeBoolean(frame, respondToToA.call(frame, object, "respond_to?", null, toAString, true))) {
// TODO(CS): why are we directly calling #respond_to? instead of using a respondsTo on a dispatch head node?
if (respondToCast.executeBoolean(frame, respondToToA.call(frame, object, "respond_to?", null, getContext().makeString("to_a"), true))) {
final Object array = toA.call(frame, object, "to_a", null);

if (array instanceof RubyArray) {
Expand Down
Expand Up @@ -18,7 +18,6 @@
import org.jruby.truffle.nodes.methods.ExceptionTranslatingNode;
import org.jruby.truffle.runtime.*;
import org.jruby.truffle.runtime.control.*;
import org.jruby.truffle.runtime.core.RubyBasicObject;

/**
* Represents a block of code run with exception handlers. There's no {@code try} keyword in Ruby -
Expand Down Expand Up @@ -73,7 +72,8 @@ public Object execute(VirtualFrame frame) {
private Object handleException(VirtualFrame frame, RaiseException exception) {
CompilerAsserts.neverPartOfCompilation();

getContext().getCoreLibrary().getGlobalVariablesObject().setInstanceVariable("$!", exception.getRubyException());
notDesignedForCompilation();
getContext().getCoreLibrary().getGlobalVariablesObject().getOperations().setInstanceVariable(getContext().getCoreLibrary().getGlobalVariablesObject(), "$!", exception.getRubyException());

for (RescueNode rescue : rescueParts) {
if (rescue.canHandle(frame, exception.getRubyException())) {
Expand Down
Expand Up @@ -1948,6 +1948,13 @@ public RubyArray initialize(VirtualFrame frame, RubyArray array, int size, Undef
return array;
}

@Specialization
public RubyArray initialize(RubyArray array, RubyArray copy, UndefinedPlaceholder defaultValue, UndefinedPlaceholder block) {
notDesignedForCompilation();
array.setStore(copy.slowToArray(), copy.getSize());
return array;
}

}

@CoreMethod(names = "initialize_copy", visibility = Visibility.PRIVATE, required = 1)
Expand Down
Expand Up @@ -234,7 +234,7 @@ public InstanceEvalNode(InstanceEvalNode prev) {
public Object instanceEval(VirtualFrame frame, Object receiver, RubyString string, UndefinedPlaceholder block) {
notDesignedForCompilation();

return getContext().eval(string.toString(), receiver, this);
return getContext().eval(string.getBytes(), receiver, this);
}

@Specialization
Expand Down
Expand Up @@ -14,8 +14,10 @@
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.nodes.dispatch.DispatchHeadNode;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.core.RubyEncoding;
import org.jruby.truffle.runtime.core.RubyRegexp;
import org.jruby.truffle.runtime.core.RubyString;
import org.jruby.truffle.translator.BodyTranslator;
import org.jruby.util.RegexpOptions;

public class InteroplatedRegexpNode extends RubyNode {
Expand Down Expand Up @@ -43,7 +45,20 @@ public RubyRegexp executeRubyRegexp(VirtualFrame frame) {
}

final org.jruby.RubyString preprocessed = org.jruby.RubyRegexp.preprocessDRegexp(getContext().getRuntime(), strings, options);
return new RubyRegexp(this, getContext().getCoreLibrary().getRegexpClass(), preprocessed.getByteList(), options.toOptions());

final RubyRegexp regexp = new RubyRegexp(this, getContext().getCoreLibrary().getRegexpClass(), preprocessed.getByteList(), options.toOptions());

if (options.isEncodingNone()) {
// This isn't quite right - we shouldn't be looking up by name, we need a real reference to this constants

if (!BodyTranslator.all7Bit(preprocessed.getByteList().bytes())) {
regexp.forceEncoding((RubyEncoding) getContext().getCoreLibrary().getEncodingClass().getConstants().get("ASCII_8BIT").getValue());
} else {
regexp.forceEncoding((RubyEncoding) getContext().getCoreLibrary().getEncodingClass().getConstants().get("US_ASCII").getValue());
}
}

return regexp;
}

@Override
Expand Down
Expand Up @@ -13,6 +13,7 @@
import com.oracle.truffle.api.source.*;
import com.oracle.truffle.api.frame.*;
import com.oracle.truffle.api.nodes.*;
import com.oracle.truffle.api.utilities.ConditionProfile;
import org.jruby.truffle.nodes.*;
import org.jruby.truffle.nodes.cast.ToSNode;
import org.jruby.truffle.nodes.dispatch.DispatchHeadNode;
Expand All @@ -28,21 +29,38 @@ public final class InterpolatedStringNode extends RubyNode {

@Children protected final ToSNode[] children;

@Child protected KernelNodes.TaintedNode taintedNode;
@Child protected KernelNodes.TaintNode taintNode;

private final ConditionProfile taintProfile = ConditionProfile.createCountingProfile();

public InterpolatedStringNode(RubyContext context, SourceSection sourceSection, ToSNode[] children) {
super(context, sourceSection);
this.children = children;
taintedNode = KernelNodesFactory.TaintedNodeFactory.create(context, sourceSection, new RubyNode[]{});
taintNode = KernelNodesFactory.TaintNodeFactory.create(context, sourceSection, new RubyNode[]{});
}

@ExplodeLoop
@Override
public Object execute(VirtualFrame frame) {
final RubyString[] strings = new RubyString[children.length];

boolean tainted = false;

for (int n = 0; n < children.length; n++) {
strings[n] = children[n].executeString(frame);
final RubyString toInterpolate = children[n].executeString(frame);
strings[n] = toInterpolate;
tainted |= taintedNode.tainted(toInterpolate);
}

final RubyString string = concat(strings);

if (taintProfile.profile(tainted)) {
taintNode.taint(string);
}

return concat(strings);
return string;
}

@CompilerDirectives.TruffleBoundary
Expand Down

0 comments on commit 587715a

Please sign in to comment.