Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master' into truffle-head
Browse files Browse the repository at this point in the history
  • Loading branch information
eregon committed Oct 29, 2016
2 parents 5687926 + 7bebb15 commit 98362a3
Show file tree
Hide file tree
Showing 292 changed files with 2,856 additions and 1,560 deletions.
2 changes: 1 addition & 1 deletion core/pom.rb
Expand Up @@ -48,7 +48,7 @@
jar 'com.github.jnr:jnr-netdb:1.1.6', :exclusions => ['com.github.jnr:jnr-ffi']
jar 'com.github.jnr:jnr-enxio:0.13', :exclusions => ['com.github.jnr:jnr-ffi']
jar 'com.github.jnr:jnr-x86asm:1.0.2', :exclusions => ['com.github.jnr:jnr-ffi']
jar 'com.github.jnr:jnr-unixsocket:0.13', :exclusions => ['com.github.jnr:jnr-ffi']
jar 'com.github.jnr:jnr-unixsocket:0.14', :exclusions => ['com.github.jnr:jnr-ffi']
jar 'com.github.jnr:jnr-posix:3.0.31', :exclusions => ['com.github.jnr:jnr-ffi']
jar 'com.github.jnr:jnr-constants:0.9.4', :exclusions => ['com.github.jnr:jnr-ffi']
jar 'com.github.jnr:jnr-ffi:2.1.0'
Expand Down
2 changes: 1 addition & 1 deletion core/pom.xml
Expand Up @@ -126,7 +126,7 @@ DO NOT MODIFIY - GENERATED CODE
<dependency>
<groupId>com.github.jnr</groupId>
<artifactId>jnr-unixsocket</artifactId>
<version>0.13</version>
<version>0.14</version>
<exclusions>
<exclusion>
<artifactId>jnr-ffi</artifactId>
Expand Down
10 changes: 6 additions & 4 deletions core/src/main/java/org/jruby/RubyComplex.java
Expand Up @@ -82,6 +82,11 @@
@JRubyClass(name = "Complex", parent = "Numeric")
public class RubyComplex extends RubyNumeric {

private static final String[] UNDEFINED = new String[]{
"<", "<=", "<=>", ">", ">=", "between?", "divmod", "floor", "ceil", "modulo", "round", "step",
"truncate", "positive?", "negative?"
};

public static RubyClass createComplexClass(Ruby runtime) {
RubyClass complexc = runtime.defineClass("Complex", runtime.getNumeric(), COMPLEX_ALLOCATOR);
runtime.setComplex(complexc);
Expand All @@ -96,10 +101,7 @@ public static RubyClass createComplexClass(Ruby runtime) {
complexc.getSingletonClass().undefineMethod("allocate");
complexc.getSingletonClass().undefineMethod("new");

String[]undefined = {"<", "<=", "<=>", ">", ">=", "between?", "divmod",
"floor", "ceil", "modulo", "round", "step", "truncate"};

for (String undef : undefined) {
for (String undef : UNDEFINED) {
complexc.undefineMethod(undef);
}

Expand Down
39 changes: 31 additions & 8 deletions core/src/main/java/org/jruby/RubyRange.java
Expand Up @@ -50,6 +50,7 @@
import org.jruby.runtime.BlockCallback;
import org.jruby.runtime.CallBlock;
import org.jruby.runtime.ClassIndex;
import org.jruby.runtime.JavaSites;
import org.jruby.runtime.ObjectAllocator;
import org.jruby.runtime.ObjectMarshal;
import org.jruby.runtime.Signature;
Expand Down Expand Up @@ -477,18 +478,16 @@ public IRubyObject each(final ThreadContext context, final Block block) {
return enumeratorizeWithSize(context, this, "each", enumSizeFn(context));
}
final Ruby runtime = context.runtime;
if (begin instanceof RubyTime) {
throw runtime.newTypeError("can't iterate from Time");
} else if (begin instanceof RubyFixnum && end instanceof RubyFixnum) {
if (begin instanceof RubyFixnum && end instanceof RubyFixnum) {
fixnumEach(context, runtime, block);
} else if (begin instanceof RubySymbol) {
} else if (begin instanceof RubySymbol && end instanceof RubySymbol) {
begin.asString().uptoCommon(context, end.asString(), isExclusive, block, true);
} else {
IRubyObject tmp = begin.checkStringType();
if (!tmp.isNil()) {
((RubyString) tmp).uptoCommon(context, end, isExclusive, block);
} else {
if (!begin.respondsTo("succ")) {
if (!discreteObject(context, begin)) {
throw runtime.newTypeError("can't iterate from "
+ begin.getMetaClass().getName());
}
Expand Down Expand Up @@ -682,11 +681,16 @@ public IRubyObject include_p19(ThreadContext context, IRubyObject obj) {
@JRubyMethod(name = {"include?", "member?"}, frame = true)
public IRubyObject include_p(ThreadContext context, final IRubyObject obj) {
final Ruby runtime = context.runtime;
if ( begin instanceof RubyNumeric || end instanceof RubyNumeric
|| ! TypeConverter.convertToTypeWithCheck(begin, runtime.getInteger(), "to_int").isNil()
|| ! TypeConverter.convertToTypeWithCheck(end, runtime.getInteger(), "to_int").isNil() ) {

boolean iterable = begin instanceof RubyNumeric || end instanceof RubyNumeric ||
linearObject(context, begin) || linearObject(context, end);

if (iterable
|| !TypeConverter.convertToTypeWithCheck(context, begin, runtime.getInteger(), sites(context).to_int_checked).isNil()
|| !TypeConverter.convertToTypeWithCheck(context, end, runtime.getInteger(), sites(context).to_int_checked).isNil()) {
return cover_p(context, obj);
}

if ( begin instanceof RubyString && end instanceof RubyString
&& ((RubyString) begin).getByteList().getRealSize() == 1
&& ((RubyString) end).getByteList().getRealSize() == 1 ) {
Expand All @@ -707,9 +711,24 @@ public IRubyObject include_p(ThreadContext context, final IRubyObject obj) {
}
}
}

return Helpers.invokeSuper(context, this, obj, Block.NULL_BLOCK);
}

private static boolean discreteObject(ThreadContext context, IRubyObject obj) {
if (obj instanceof RubyTime) return false;
return sites(context).respond_to_succ.respondsTo(context, obj, obj, false);
}

private static boolean linearObject(ThreadContext context, IRubyObject obj) {
if (obj instanceof RubyFixnum || obj instanceof RubyFloat) return true;
// if (SPECIAL_CONST_P(obj)) return FALSE;
if (obj instanceof RubyBignum) return true;
if (obj instanceof RubyNumeric) return true;
if (obj instanceof RubyTime) return true;
return false;
}

@JRubyMethod(name = "===")
public IRubyObject eqq_p(ThreadContext context, IRubyObject obj) {
return callMethod(context, "include?", obj);
Expand Down Expand Up @@ -912,4 +931,8 @@ public static boolean isRangeLike(ThreadContext context, IRubyObject obj, Respon
return respond_to_begin.respondsTo(context, obj, obj) &&
respond_to_end.respondsTo(context, obj, obj);
}

private static JavaSites.RangeSites sites(ThreadContext context) {
return context.sites.Range;
}
}
8 changes: 7 additions & 1 deletion core/src/main/java/org/jruby/ir/IRBuilder.java
Expand Up @@ -3353,10 +3353,16 @@ private boolean canBacktraceBeRemoved(RescueNode rescueNode) {
if (RubyInstanceConfig.FULL_TRACE_ENABLED || !(rescueNode instanceof RescueModNode) &&
rescueNode.getElseNode() != null) return false;

Node body = rescueNode.getRescueNode().getBodyNode();

// This optimization omits backtrace info for the exception getting rescued so we cannot
// optimize the exception variable.
if (body instanceof GlobalVarNode && ((GlobalVarNode) body).getName().equals("$!")) return false;

// FIXME: This MIGHT be able to expand to more complicated expressions like Hash or Array if they
// contain only SideEffectFree nodes. Constructing a literal out of these should be safe from
// effecting or being able to access $!.
return rescueNode.getRescueNode().getBodyNode() instanceof SideEffectFree;
return body instanceof SideEffectFree;
}

private Operand buildRescueInternal(RescueNode rescueNode, EnsureBlockInfo ensure) {
Expand Down
Expand Up @@ -2,10 +2,14 @@

import org.jruby.dirgra.Edge;
import org.jruby.ir.dataflow.FlowGraphNode;
import org.jruby.ir.instructions.ClosureAcceptingInstr;
import org.jruby.ir.instructions.Instr;
import org.jruby.ir.instructions.ResultInstr;
import org.jruby.ir.operands.LocalVariable;
import org.jruby.ir.operands.Operand;
import org.jruby.ir.operands.Variable;
import org.jruby.ir.operands.WrappedIRClosure;
import org.jruby.ir.IRClosure;
import org.jruby.ir.IRFlags;
import org.jruby.ir.representations.BasicBlock;

Expand Down Expand Up @@ -81,28 +85,58 @@ public void applyTransferFunction(Instr i) {
}
}

public void identifyInits(Set<Variable> undefinedVars) {
int parentScopeDepth = 1;
if (problem.getScope().getFlags().contains(IRFlags.REUSE_PARENT_DYNSCOPE)) {
parentScopeDepth = 0;
private void identifyUndefinedVarsInClosure(Set<Variable> undefinedVars, IRClosure cl, int nestingLevel) {
int clBaseDepth = nestingLevel + (cl.getFlags().contains(IRFlags.REUSE_PARENT_DYNSCOPE) ? 0 : 1);
cl.setUpUseDefLocalVarMaps();
for (LocalVariable lv: cl.getUsedLocalVariables()) {
// This can happen where an outer scope variable
// is not used in this scope but is used in a nested
// scope. Ex: ~jruby/bin/ast:21
if (problem.getDFVar(lv) == null) {
continue;
}

// Find variables which belong to the problem.getScope()
if (lv.getScopeDepth() == clBaseDepth && !tmp.get(problem.getDFVar(lv))) {
// We want lv suitable for initializing in this scope
undefinedVars.add(lv.getScopeDepth() == 0 ? lv : lv.cloneForDepth(0));
tmp.set(problem.getDFVar(lv));
}
}

// System.out.println("BB " + basicBlock + "; state\n" + toString());
// Recurse
for (IRClosure nestedCl: cl.getClosures()) {
identifyUndefinedVarsInClosure(undefinedVars, nestedCl, nestingLevel + 1);
}
}

public void identifyInits(Set<Variable> undefinedVars) {
int parentScopeDepth = problem.getScope().getFlags().contains(IRFlags.REUSE_PARENT_DYNSCOPE) ? 0 : 1;

initSolution();
for (Instr i: basicBlock.getInstrs()) {
// Variables that belong to outer scopes should always
// be considered defined.
for (Variable v: i.getUsedVariables()) {
LocalVariable lv;
if (!v.isSelf()) {
if (v instanceof LocalVariable && ((LocalVariable)v).getScopeDepth() >= parentScopeDepth) {
tmp.set(problem.getDFVar(v));
if (v instanceof LocalVariable) {
lv = (LocalVariable)v;
// Variables that belong to outer scopes
// are considered already defined.
if (lv.getScopeDepth() < parentScopeDepth && !tmp.get(problem.getDFVar(v))) {
// We want lv suitable for initializing in this scope
undefinedVars.add(lv.getScopeDepth() == 0 ? lv : lv.cloneForDepth(0));
}
tmp.set(problem.getDFVar(lv));
}
}
}

if (!tmp.get(problem.getDFVar(v))) {
// System.out.println("Variable " + v + " in instr " + i + " in " + basicBlock + " isn't defined!");
undefinedVars.add(v);
}
if (i instanceof ClosureAcceptingInstr) {
// Find all variables used in the closure and
// figure out if they are defined are not.
Operand o = ((ClosureAcceptingInstr)i).getClosureArg();
if (o != null && o instanceof WrappedIRClosure) {
identifyUndefinedVarsInClosure(undefinedVars, ((WrappedIRClosure)o).getClosure(), 0);
}
}

Expand Down
Expand Up @@ -82,8 +82,8 @@ public void applyTransferFunction(Instr i) {
// At this site, a binding will get allocated if it has not been already!
if (o != null && o instanceof WrappedIRClosure) {
// In this first pass, the current scope and the call's closure are considered
// independent of each other which means any variable that is used by the variable
// will get spilled into the binding. This is clearly conservative, but simplifies
// independent of each other which means any variable that is used by the closure
// will get spilled into the binding. This is clearly conservative, but simplifies
// the analysis.
IRClosure cl = ((WrappedIRClosure) o).getClosure();

Expand Down
Expand Up @@ -23,6 +23,11 @@ public int getArgIndex() {
return argIndex;
}

@Override
public String[] toStringNonOperandArgs() {
return new String[] { "i:" + argIndex };
}

public IRubyObject receiveArg(ThreadContext context, IRubyObject[] args, boolean keywordArgumentSupplied) {
throw new RuntimeException("ReceiveArgBase.interpret called! " + this.getClass().getName() + " does not define receiveArg");
}
Expand Down
Expand Up @@ -30,6 +30,8 @@ private void decrementScopeDepth(LocalVariable v, IRScope s, Map<Operand, Operan
}

public void eliminateLocalVars(IRScope s) {
assert s.getClosures().isEmpty() : "We assume that if a scope has nested closures, it uses a dynamic scoope.";

Map<Operand, Operand> varRenameMap = new HashMap<Operand, Operand>();
// Record the fact that we eliminated the scope
s.getFlags().add(IRFlags.DYNSCOPE_ELIMINATED);
Expand Down
6 changes: 6 additions & 0 deletions core/src/main/java/org/jruby/runtime/JavaSites.java
Expand Up @@ -36,6 +36,7 @@ public class JavaSites {
public final BigDecimalSites BigDecimal = new BigDecimalSites();
public final ComplexSites Complex = new ComplexSites();
public final RationalSites Rational = new RationalSites();
public final RangeSites Range = new RangeSites();
public final ZlibSites Zlib = new ZlibSites();

public static class BasicObjectSites {
Expand Down Expand Up @@ -364,6 +365,11 @@ public static class RationalSites {
public final CheckedSites to_r_checked = new CheckedSites("to_r");
}

public static class RangeSites {
public final RespondToCallSite respond_to_succ = new RespondToCallSite("succ");
public final CheckedSites to_int_checked = new CheckedSites("to_int");
}

public static class ZlibSites {
public final RespondToCallSite reader_respond_to = new RespondToCallSite();
public final RespondToCallSite writer_respond_to = new RespondToCallSite();
Expand Down
4 changes: 3 additions & 1 deletion spec/mspec/lib/mspec.rb
Expand Up @@ -13,6 +13,8 @@
require 'pp'
rescue LoadError
module Kernel
alias pretty_inspect inspect
def pretty_inspect
inspect
end
end
end
7 changes: 3 additions & 4 deletions spec/mspec/lib/mspec/commands/mkspec.rb 100644 → 100755
@@ -1,11 +1,10 @@
#! /usr/bin/env ruby
#!/usr/bin/env ruby

require 'fileutils'
require 'rbconfig'
require 'mspec/version'
require 'mspec/utils/options'
require 'mspec/utils/name_map'

require 'mspec/helpers/fs'

class MkSpec
attr_reader :config
Expand Down Expand Up @@ -63,7 +62,7 @@ def create_directory(mod)
return nil
end
else
FileUtils.mkdir_p subdir
mkdir_p subdir
end

subdir
Expand Down
12 changes: 8 additions & 4 deletions spec/mspec/lib/mspec/expectations/expectations.rb
@@ -1,4 +1,6 @@
class SpecExpectationNotMetError < StandardError; end
class SpecExpectationNotMetError < StandardError
end

class SpecExpectationNotFoundError < StandardError
def message
"No behavior expectation was found in the example"
Expand All @@ -7,10 +9,12 @@ def message

class SpecExpectation
def self.fail_with(expected, actual)
if expected.to_s.size + actual.to_s.size > 80
message = expected.to_s.chomp + "\n" + actual.to_s
expected_to_s = expected.to_s
actual_to_s = actual.to_s
if expected_to_s.size + actual_to_s.size > 80
message = expected_to_s.chomp + "\n" + actual_to_s
else
message = expected.to_s + " " + actual.to_s
message = expected_to_s + " " + actual_to_s
end
Kernel.raise SpecExpectationNotMetError, message
end
Expand Down
13 changes: 7 additions & 6 deletions spec/mspec/lib/mspec/expectations/should.rb
@@ -1,10 +1,11 @@
class Object
NO_MATCHER_GIVEN = Object.new
def should(matcher=NO_MATCHER_GIVEN)

def should(matcher = NO_MATCHER_GIVEN)
MSpec.expectation
MSpec.actions :expectation, MSpec.current.state
unless matcher.equal?(NO_MATCHER_GIVEN)
unless matcher.matches?(self)
unless matcher.equal? NO_MATCHER_GIVEN
unless matcher.matches? self
expected, actual = matcher.failure_message
SpecExpectation.fail_with(expected, actual)
end
Expand All @@ -13,11 +14,11 @@ def should(matcher=NO_MATCHER_GIVEN)
end
end

def should_not(matcher=NO_MATCHER_GIVEN)
def should_not(matcher = NO_MATCHER_GIVEN)
MSpec.expectation
MSpec.actions :expectation, MSpec.current.state
unless matcher.equal?(NO_MATCHER_GIVEN)
if matcher.matches?(self)
unless matcher.equal? NO_MATCHER_GIVEN
if matcher.matches? self
expected, actual = matcher.negative_failure_message
SpecExpectation.fail_with(expected, actual)
end
Expand Down
8 changes: 4 additions & 4 deletions spec/mspec/lib/mspec/mocks/proxy.rb
Expand Up @@ -128,10 +128,10 @@ def any_number_of_times

def with(*args)
raise ArgumentError, "you must specify the expected arguments" if args.empty?
@arguments = *args
behaves_like_ruby_1_9 = *[]
if (behaves_like_ruby_1_9)
@arguments = @arguments.first if @arguments.length <= 1
if args.length == 1
@arguments = args.first
else
@arguments = args
end
self
end
Expand Down

0 comments on commit 98362a3

Please sign in to comment.