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

Commits on May 9, 2015

  1. Copy the full SHA
    317ecaa View commit details
  2. Copy the full SHA
    00a1712 View commit details
1 change: 1 addition & 0 deletions spec/mspec/lib/mspec/matchers.rb
Original file line number Diff line number Diff line change
@@ -10,6 +10,7 @@
require 'mspec/matchers/be_nan'
require 'mspec/matchers/be_nil'
require 'mspec/matchers/be_true'
require 'mspec/matchers/be_true_or_false'
require 'mspec/matchers/be_valid_dns_name'
require 'mspec/matchers/complain'
require 'mspec/matchers/eql'
20 changes: 20 additions & 0 deletions spec/mspec/lib/mspec/matchers/be_true_or_false.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
class BeTrueOrFalseMatcher
def matches?(actual)
@actual = actual
@actual == true || @actual == false
end

def failure_message
["Expected #{@actual.inspect}", "to be true or false"]
end

def negative_failure_message
["Expected #{@actual.inspect}", "not to be true or false"]
end
end

class Object
def be_true_or_false
BeTrueOrFalseMatcher.new
end
end
19 changes: 19 additions & 0 deletions spec/mspec/spec/matchers/be_true_or_false_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
require 'spec_helper'
require 'mspec/expectations/expectations'
require 'mspec/matchers'

describe BeTrueOrFalseMatcher do
it "matches when actual is true" do
BeTrueOrFalseMatcher.new.matches?(true).should == true
end

it "matches when actual is false" do
BeTrueOrFalseMatcher.new.matches?(false).should == true
end

it "provides a useful failure message" do
matcher = BeTrueOrFalseMatcher.new
matcher.matches?("some string")
matcher.failure_message.should == ["Expected \"some string\"", "to be true or false"]
end
end
Original file line number Diff line number Diff line change
@@ -169,55 +169,6 @@ public RubyNilClass assertNotCompiled() {

}

@CoreMethod(names = "dump_call_stack", onSingleton = true)
public abstract static class DumpCallStackNode extends CoreMethodArrayArgumentsNode {

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

@CompilerDirectives.TruffleBoundary
@Specialization
public RubyNilClass dumpCallStack() {
for (String line : Backtrace.DEBUG_FORMATTER.format(getContext(), null, RubyCallStack.getBacktrace(this))) {
System.err.println(line);
}

return nil();
}

}

@CoreMethod(names = "flush_stdout", onSingleton = true)
public abstract static class FlushStdoutNode extends CoreMethodArrayArgumentsNode {

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

@Specialization
public RubyNilClass flush() {
getContext().getRuntime().getOut().flush();
return nil();
}

}

@CoreMethod(names = "full_tree", onSingleton = true)
public abstract static class FullTreeNode extends CoreMethodArrayArgumentsNode {

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

@CompilerDirectives.TruffleBoundary
@Specialization
public RubyString fullTree() {
return getContext().makeString(NodeUtil.printTreeToString(Truffle.getRuntime().getCallerFrame().getCallNode().getRootNode()));
}

}

@CoreMethod(names = "java_class_of", onSingleton = true, required = 1)
public abstract static class JavaClassOfNode extends CoreMethodArrayArgumentsNode {

@@ -227,7 +178,7 @@ public JavaClassOfNode(RubyContext context, SourceSection sourceSection) {

@Specialization
public RubyString javaClassOf(Object value) {
return getContext().makeString(value.getClass().getName());
return getContext().makeString(value.getClass().getSimpleName());
}

}
@@ -243,112 +194,16 @@ public DumpStringNode(RubyContext context, SourceSection sourceSection) {
@Specialization
public RubyString dumpString(RubyString string) {
final StringBuilder builder = new StringBuilder();
builder.append("\"");

for (byte b : string.getByteList().unsafeBytes()) {
builder.append(String.format("\\x%02x", b));
}

builder.append("\"");

return getContext().makeString(builder.toString());
}

}

@CoreMethod(names = "source_attribution_tree", onSingleton = true)
public abstract static class SourceAttributionTreeNode extends CoreMethodArrayArgumentsNode {

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

@CompilerDirectives.TruffleBoundary
@Specialization
public RubyString sourceAttributionTree() {
return getContext().makeString(NodeUtil.printSourceAttributionTree(Truffle.getRuntime().getCallerFrame().getCallNode().getRootNode()));
}

}

@CoreMethod(names = "storage_class", onSingleton = true, required = 1)
public abstract static class StorageClassNode extends CoreMethodArrayArgumentsNode {

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

@Specialization
public RubyString storageClass(RubyArray array) {
if (array.getStore() == null) {
return getContext().makeString("null");
} else {
return getContext().makeString(array.getStore().getClass().getName());
}
}

@Specialization
public RubyString storageClass(RubyHash hash) {
if (hash.getStore() == null) {
return getContext().makeString("null");
} else {
return getContext().makeString(hash.getStore().getClass().getName());
}
}

}

@CoreMethod(names = "panic", onSingleton = true)
public abstract static class PanicNode extends CoreMethodArrayArgumentsNode {

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

@Specialization
public RubyNilClass doPanic() {
DebugOperations.panic(getContext(), this, null);
return nil();
}

}

@CoreMethod(names = "parse_tree", onSingleton = true)
public abstract static class ParseTreeNode extends CoreMethodArrayArgumentsNode {

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

@CompilerDirectives.TruffleBoundary
@Specialization
public Object parseTree(VirtualFrame frame) {
final org.jruby.ast.Node parseTree = RubyCallStack.getCallingMethod(frame).getSharedMethodInfo().getParseTree();

if (parseTree == null) {
return nil();
} else {
return getContext().makeString(parseTree.toString(true, 0));
}
}

}

@CoreMethod(names = "tree", onSingleton = true)
public abstract static class TreeNode extends CoreMethodArrayArgumentsNode {

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

@CompilerDirectives.TruffleBoundary
@Specialization
public RubyString tree() {
return getContext().makeString(NodeUtil.printCompactTreeToString(Truffle.getRuntime().getCallerFrame().getCallNode().getRootNode()));
}

}

@CoreMethod(names = "graal?", onSingleton = true)
public abstract static class GraalNode extends CoreMethodArrayArgumentsNode {

4 changes: 3 additions & 1 deletion truffle/src/main/ruby/core.rb
Original file line number Diff line number Diff line change
@@ -238,8 +238,10 @@

# Load JRuby+Truffle specific classes

require_relative 'core/truffle/truffle'
require_relative 'core/truffle/attachments'
require_relative 'core/truffle/debug'
require_relative 'core/truffle/runtime'
require_relative 'core/truffle/truffle'

# Start running Ruby code outside classes

46 changes: 46 additions & 0 deletions truffle/src/main/ruby/core/truffle/attachments.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# 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

module Truffle

# Attach blocks to specific lines of existing code. Like
# `Kernel#set_trace_func`, but for specific lines only, and fast enough to
# be used for hot-code-path monkey patching if you want.
module Attachments

# Attach a block to be called each time before a given line in a given file
# is executed, passing the binding at that point to the block.
# @return [nil]
#
# # Examples
#
# ```
# Truffle::Attachments.attach __FILE__, 21 do |binding|
# # Double the value of local variable foo before this line runs
# binding.local_variable_set(:foo, binding.local_variable_get(:foo) * 2)
# end
# ```
def self.attach(file, line, &block)
Truffle::Primitive.attach file, line, &block
end

# Detach all blocks at a given line in a given file.
# @return [nil]
#
# # Examples
#
# ```
# Truffle::Attachments.detach __FILE__, 21
# ```
def self.detach(file, line)
Truffle::Primitive.attach file, line
end

end

end
37 changes: 37 additions & 0 deletions truffle/src/main/ruby/core/truffle/runtime.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# 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

module Truffle

# Information about the Truffle runtime system and utilities for interacting
# with it.
module Runtime

# Return the name of the Java class used to represent this object, as a
# String.
# @return [String]
def self.java_class_of(object)
Truffle::Primitive.java_class_of(object)
end

# Dump a string as a String of escaped literal bytes.
# @return [String]
def self.dump_string(string)
Truffle::Primitive.dump_string(string)
end

# Print a String directly to stderr without going through the normal
# Ruby and runtime IO systems.
# @return [nil]
def self.debug_print(string)
Truffle::Primitive.debug_print string
end

end

end
13 changes: 12 additions & 1 deletion truffle/src/main/ruby/core/truffle/truffle.rb
Original file line number Diff line number Diff line change
@@ -12,7 +12,7 @@
module Truffle

# The version of Truffle and Graal in use.
# @return [String] a version string such as `"0.6"`, or `"undefined"` if running on a non-Graal JVM.
# @return [String] a version string such as `"0.7"`, or `"undefined"` if running on a non-Graal JVM.
def self.version
Primitive.graal_version
end
@@ -27,4 +27,15 @@ def self.substrate?
Primitive.substrate?
end

# Return the Binding of the method which calls this method.
# @return [Binding]
# @!scope class
define_singleton_method :binding_of_caller, Truffle::Primitive.method(:binding_of_caller).unbind

# Returns the source (such as the file name) of the method which calls this
# method.
# @return [String]
# @!scope class
define_singleton_method :source_of_caller, Truffle::Primitive.method(:source_of_caller).unbind

end