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

Commits on Jun 4, 2015

  1. 5
    Copy the full SHA
    845fe74 View commit details
  2. Copy the full SHA
    f9ece65 View commit details
1 change: 0 additions & 1 deletion spec/truffle/tags/core/regexp/match_tags.txt

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
* 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.rubinius;

import com.oracle.truffle.api.Truffle;
import com.oracle.truffle.api.frame.FrameDescriptor;
import com.oracle.truffle.api.frame.FrameInstance;
import com.oracle.truffle.api.frame.FrameInstanceVisitor;
import com.oracle.truffle.api.frame.FrameSlot;
import com.oracle.truffle.api.frame.FrameSlotTypeException;
import com.oracle.truffle.api.frame.MaterializedFrame;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.source.SourceSection;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.ThreadLocalObject;
import org.jruby.util.Memo;

public class RubiniusLastStringReadNode extends RubyNode {

public RubiniusLastStringReadNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
}

@Override
public Object execute(VirtualFrame frame) {
final Memo<Integer> frameCount = new Memo<>(0);

// Rubinius expects $_ to be thread-local, rather than frame-local. If we see it in a method call, we need
// to look to the caller's frame to get the correct value, otherwise it will be nil.
final MaterializedFrame callerFrame = Truffle.getRuntime().iterateFrames(new FrameInstanceVisitor<MaterializedFrame>() {

@Override
public MaterializedFrame visitFrame(FrameInstance frameInstance) {
if (frameCount.get() == 0) {
return frameInstance.getFrame(FrameInstance.FrameAccess.READ_WRITE, false).materialize();
} else {
frameCount.set(frameCount.get() + 1);
return null;
}
}

});

final FrameSlot slot = callerFrame.getFrameDescriptor().findFrameSlot("$_");
try {
final ThreadLocalObject threadLocalObject = (ThreadLocalObject) callerFrame.getObject(slot);
return threadLocalObject.get();
} catch (FrameSlotTypeException e) {
throw new UnsupportedOperationException(e);
}
}
}
Original file line number Diff line number Diff line change
@@ -68,6 +68,7 @@
import org.jruby.truffle.nodes.objects.SelfNode;
import org.jruby.truffle.nodes.rubinius.CallRubiniusPrimitiveNode;
import org.jruby.truffle.nodes.rubinius.InvokeRubiniusPrimitiveNode;
import org.jruby.truffle.nodes.rubinius.RubiniusLastStringReadNode;
import org.jruby.truffle.nodes.rubinius.RubiniusPrimitiveConstructor;
import org.jruby.truffle.nodes.rubinius.RubiniusSingleBlockArgNode;
import org.jruby.truffle.nodes.yield.YieldNode;
@@ -1481,7 +1482,11 @@ public RubyNode visitGlobalVarNode(org.jruby.ast.GlobalVarNode node) {
RubyNode readNode = environment.findLocalVarNode(name, sourceSection);

if (name.equals("$_")) {
readNode = GetFromThreadLocalNodeGen.create(context, sourceSection, readNode);
if (sourceSection.getSource().getPath().equals("core:/core/rubinius/common/regexp.rb")) {
readNode = new RubiniusLastStringReadNode(context, sourceSection);
} else {
readNode = GetFromThreadLocalNodeGen.create(context, sourceSection, readNode);
}
}

return readNode;