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: 2360152da741
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 9dfb4fb59ef6
Choose a head ref
  • 6 commits
  • 11 files changed
  • 1 contributor

Commits on Mar 4, 2015

  1. 3
    Copy the full SHA
    758c51d View commit details
  2. RSpec 3 syntax.

    headius committed Mar 4, 2015
    Copy the full SHA
    b89523f View commit details
  3. Unused import.

    headius committed Mar 4, 2015
    Copy the full SHA
    9654f6a View commit details
  4. Copy the full SHA
    2219e51 View commit details
  5. Remove kcode from regexp options; not used anymore.

    Leaving it in place broke the "none" flag, since kcode EUC and
    NONE shared the value 32.
    headius committed Mar 4, 2015
    Copy the full SHA
    e05baa2 View commit details
  6. Copy the full SHA
    9dfb4fb View commit details
10 changes: 5 additions & 5 deletions core/src/main/java/org/jruby/RubyRegexp.java
Original file line number Diff line number Diff line change
@@ -83,8 +83,8 @@ public class RubyRegexp extends RubyObject implements ReOptions, EncodingCapable
private ByteList str = ByteList.EMPTY_BYTELIST;
private RegexpOptions options;

public static final int ARG_ENCODING_FIXED = 16;
public static final int ARG_ENCODING_NONE = 32;
public static final int ARG_ENCODING_FIXED = ReOptions.RE_FIXED;
public static final int ARG_ENCODING_NONE = ReOptions.RE_NONE;

public void setLiteral() {
options.setLiteral(true);
@@ -206,8 +206,8 @@ public static RubyClass createRegexpClass(Ruby runtime) {
regexpClass.defineConstant("EXTENDED", runtime.newFixnum(RE_OPTION_EXTENDED));
regexpClass.defineConstant("MULTILINE", runtime.newFixnum(RE_OPTION_MULTILINE));

regexpClass.defineConstant("FIXEDENCODING", runtime.newFixnum(ARG_ENCODING_FIXED));
regexpClass.defineConstant("NOENCODING", runtime.newFixnum(ARG_ENCODING_NONE));
regexpClass.defineConstant("FIXEDENCODING", runtime.newFixnum(RE_FIXED));
regexpClass.defineConstant("NOENCODING", runtime.newFixnum(RE_NONE));

regexpClass.defineAnnotatedMethods(RubyRegexp.class);
regexpClass.getSingletonClass().defineAlias("compile", "new");
@@ -2146,7 +2146,7 @@ public static void marshalTo(RubyRegexp regexp, MarshalStream output) throws jav

int options = regexp.pattern.getOptions() & EMBEDDABLE;

if (regexp.getOptions().isFixed()) options |= ARG_ENCODING_FIXED;
if (regexp.getOptions().isFixed()) options |= RE_FIXED;

output.writeByte(options);
}
Original file line number Diff line number Diff line change
@@ -7,7 +7,7 @@
* of what we renamed them as. This is just enough wrapper for us to maintain a nice
* debug string.
*/
public class TemporaryLocalReplacementVariable extends TemporaryLocalVariable {
public class TemporaryLocalReplacementVariable extends TemporaryLocalVariable implements DepthCloneable {
public static final String PREFIX = "%t_";
private final String oldName;

@@ -26,4 +26,9 @@ public Variable clone(SimpleCloneInfo ii) {
public String getPrefix() {
return "%t_" + oldName + "_";
}

@Override
public Operand cloneForDepth(int n) {
return this;
}
}
6 changes: 6 additions & 0 deletions core/src/main/java/org/jruby/ir/runtime/IRRuntimeHelpers.java
Original file line number Diff line number Diff line change
@@ -31,6 +31,7 @@
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.runtime.callsite.FunctionalCachingCallSite;
import org.jruby.runtime.callsite.NormalCachingCallSite;
import org.jruby.runtime.callsite.VariableCachingCallSite;
import org.jruby.util.ByteList;
import org.jruby.util.DefinedMessage;
import org.jruby.util.RegexpOptions;
@@ -1309,4 +1310,9 @@ public static FunctionalCachingCallSite newFunctionalCachingCallSite(String name
public static NormalCachingCallSite newNormalCachingCallSite(String name) {
return new NormalCachingCallSite(name);
}

@JIT
public static VariableCachingCallSite newVariableCachingCallSite(String name) {
return new VariableCachingCallSite(name);
}
}
Original file line number Diff line number Diff line change
@@ -12,6 +12,7 @@
import org.jruby.ir.IRScope;
import org.jruby.ir.operands.UndefinedValue;
import org.jruby.ir.runtime.IRRuntimeHelpers;
import org.jruby.runtime.CallType;
import org.jruby.runtime.CompiledIRBlockBody;
import org.jruby.runtime.Helpers;
import org.jruby.runtime.ThreadContext;
@@ -335,8 +336,9 @@ public void pushBlockBody(Handle handle, org.jruby.runtime.Signature signature,
* @param name name of the method to invoke
* @param arity arity of the call
* @param hasClosure whether a closure will be on the stack for passing
* @param callType
*/
public abstract void invokeSelf(String name, int arity, boolean hasClosure);
public abstract void invokeSelf(String name, int arity, boolean hasClosure, CallType callType);

/**
* Invoke a superclass method from an instance context.
21 changes: 17 additions & 4 deletions core/src/main/java/org/jruby/ir/targets/IRBytecodeAdapter6.java
Original file line number Diff line number Diff line change
@@ -6,7 +6,6 @@

import com.headius.invokebinder.Signature;
import java.math.BigInteger;
import java.util.concurrent.Callable;

import org.jcodings.Encoding;
import org.jruby.Ruby;
@@ -34,6 +33,7 @@
import org.jruby.runtime.callsite.CachingCallSite;
import org.jruby.runtime.callsite.FunctionalCachingCallSite;
import org.jruby.runtime.callsite.NormalCachingCallSite;
import org.jruby.runtime.callsite.VariableCachingCallSite;
import org.jruby.util.ByteList;
import org.jruby.util.JavaNameMangler;
import org.jruby.util.RegexpOptions;
@@ -286,7 +286,20 @@ public void invoke(String name, int arity, boolean hasClosure, CallType callType
adapter2.ifnonnull(doCall);
adapter2.pop();
adapter2.ldc(name);
Class siteClass = callType == CallType.NORMAL ? NormalCachingCallSite.class : FunctionalCachingCallSite.class;
Class<? extends CachingCallSite> siteClass;
switch (callType) {
case NORMAL:
siteClass = NormalCachingCallSite.class;
break;
case FUNCTIONAL:
siteClass = FunctionalCachingCallSite.class;
break;
case VARIABLE:
siteClass = VariableCachingCallSite.class;
break;
default:
throw new RuntimeException("BUG: Unexpected call type " + callType + " in JVM6 invoke logic");
}
adapter2.invokestatic(p(IRRuntimeHelpers.class), "new" + siteClass.getSimpleName(), sig(siteClass, String.class));
adapter2.dup();
adapter2.putstatic(getClassData().clsName, methodName, ci(CachingCallSite.class));
@@ -440,10 +453,10 @@ public void invokeOtherOneFloat(String name, double flote) {
adapter.invokestatic(getClassData().clsName, methodName, incomingSig);
}

public void invokeSelf(String name, int arity, boolean hasClosure) {
public void invokeSelf(String name, int arity, boolean hasClosure, CallType callType) {
if (arity > MAX_ARGUMENTS) throw new NotCompilableException("call to `" + name + "' has more than " + MAX_ARGUMENTS + " arguments");

invoke(name, arity, hasClosure, CallType.FUNCTIONAL);
invoke(name, arity, hasClosure, callType);
}

public void invokeInstanceSuper(String name, int arity, boolean hasClosure, boolean[] splatmap) {
12 changes: 7 additions & 5 deletions core/src/main/java/org/jruby/ir/targets/IRBytecodeAdapter7.java
Original file line number Diff line number Diff line change
@@ -18,6 +18,7 @@
import org.jruby.ir.runtime.IRRuntimeHelpers;
import org.jruby.parser.StaticScope;
import org.jruby.runtime.Block;
import org.jruby.runtime.CallType;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.runtime.invokedynamic.InvokeDynamicSupport;
@@ -162,20 +163,21 @@ public void invokeOtherOneFloat(String name, double flote) {
0);
}

public void invokeSelf(String name, int arity, boolean hasClosure) {
public void invokeSelf(String name, int arity, boolean hasClosure, CallType callType) {
if (arity > MAX_ARGUMENTS) throw new NotCompilableException("call to `" + name + "' has more than " + MAX_ARGUMENTS + " arguments");

String action = callType == CallType.FUNCTIONAL ? "callFunctional" : "callVariable";
if (hasClosure) {
if (arity == -1) {
adapter.invokedynamic("invokeSelf:" + JavaNameMangler.mangleMethodName(name), sig(JVM.OBJECT, params(ThreadContext.class, JVM.OBJECT, JVM.OBJECT, JVM.OBJECT_ARRAY, Block.class)), SelfInvokeSite.BOOTSTRAP);
adapter.invokedynamic(action + ":" + JavaNameMangler.mangleMethodName(name), sig(JVM.OBJECT, params(ThreadContext.class, JVM.OBJECT, JVM.OBJECT, JVM.OBJECT_ARRAY, Block.class)), SelfInvokeSite.BOOTSTRAP);
} else {
adapter.invokedynamic("invokeSelf:" + JavaNameMangler.mangleMethodName(name), sig(JVM.OBJECT, params(ThreadContext.class, JVM.OBJECT, arity + 2, Block.class)), SelfInvokeSite.BOOTSTRAP);
adapter.invokedynamic(action + ":" + JavaNameMangler.mangleMethodName(name), sig(JVM.OBJECT, params(ThreadContext.class, JVM.OBJECT, arity + 2, Block.class)), SelfInvokeSite.BOOTSTRAP);
}
} else {
if (arity == -1) {
adapter.invokedynamic("invokeSelf:" + JavaNameMangler.mangleMethodName(name), sig(JVM.OBJECT, params(ThreadContext.class, JVM.OBJECT, JVM.OBJECT, JVM.OBJECT_ARRAY)), SelfInvokeSite.BOOTSTRAP);
adapter.invokedynamic(action + ":" + JavaNameMangler.mangleMethodName(name), sig(JVM.OBJECT, params(ThreadContext.class, JVM.OBJECT, JVM.OBJECT, JVM.OBJECT_ARRAY)), SelfInvokeSite.BOOTSTRAP);
} else {
adapter.invokedynamic("invokeSelf:" + JavaNameMangler.mangleMethodName(name), sig(JVM.OBJECT, params(ThreadContext.class, JVM.OBJECT, JVM.OBJECT, JVM.OBJECT, arity)), SelfInvokeSite.BOOTSTRAP);
adapter.invokedynamic(action + ":" + JavaNameMangler.mangleMethodName(name), sig(JVM.OBJECT, params(ThreadContext.class, JVM.OBJECT, JVM.OBJECT, JVM.OBJECT, arity)), SelfInvokeSite.BOOTSTRAP);
}
}
}
6 changes: 4 additions & 2 deletions core/src/main/java/org/jruby/ir/targets/JVMVisitor.java
Original file line number Diff line number Diff line change
@@ -670,7 +670,7 @@ public void BacktickInstr(BacktickInstr instr) {
jvmAdapter().invokeinterface(p(IRubyObject.class), "setFrozen", sig(void.class, boolean.class));

// invoke the "`" method on self
jvmMethod().invokeSelf("`", 1, false);
jvmMethod().invokeSelf("`", 1, false, CallType.FUNCTIONAL);
jvmStoreLocal(instr.getResult());
}

@@ -832,8 +832,10 @@ private void compileCallCommon(IRBytecodeAdapter m, String name, Operand[] args,

switch (callType) {
case FUNCTIONAL:
m.invokeSelf(name, arity, hasClosure, CallType.FUNCTIONAL);
break;
case VARIABLE:
m.invokeSelf(name, arity, hasClosure);
m.invokeSelf(name, arity, hasClosure, CallType.VARIABLE);
break;
case NORMAL:
m.invokeOther(name, arity, hasClosure);
9 changes: 4 additions & 5 deletions core/src/main/java/org/jruby/ir/targets/SelfInvokeSite.java
Original file line number Diff line number Diff line change
@@ -27,18 +27,17 @@
* Created by headius on 10/23/14.
*/
public class SelfInvokeSite extends InvokeSite {
public SelfInvokeSite(MethodType type, String name) {
super(type, name, CallType.FUNCTIONAL);
}

public SelfInvokeSite(MethodType type, String name, CallType callType) {
super(type, name, callType);
}

public static Handle BOOTSTRAP = new Handle(Opcodes.H_INVOKESTATIC, p(SelfInvokeSite.class), "bootstrap", sig(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class));

public static CallSite bootstrap(MethodHandles.Lookup lookup, String name, MethodType type) {
InvokeSite site = new SelfInvokeSite(type, JavaNameMangler.demangleMethodName(name.split(":")[1]));
String[] nameComponents = name.split(":");
String methodName = JavaNameMangler.demangleMethodName(nameComponents[1]);
CallType callType = nameComponents[0].equals("callFunctional") ? CallType.FUNCTIONAL : CallType.VARIABLE;
InvokeSite site = new SelfInvokeSite(type, methodName, callType);

return InvokeSite.bootstrap(site, lookup);
}
11 changes: 6 additions & 5 deletions core/src/main/java/org/jruby/parser/ReOptions.java
Original file line number Diff line number Diff line change
@@ -30,21 +30,22 @@
***** END LICENSE BLOCK *****/
package org.jruby.parser;

import org.jruby.RubyRegexp;

public interface ReOptions {
int RE_OPTION_IGNORECASE = 1;
int RE_OPTION_EXTENDED = 2;
int RE_OPTION_MULTILINE = 4;
int RE_OPTION_SINGLELINE = 8;
int RE_OPTION_POSIXLINE = (RE_OPTION_MULTILINE | RE_OPTION_SINGLELINE);
int RE_OPTION_LONGEST = 16;
int RE_MAY_IGNORECASE = 32;
int RE_FIXED = 16;
int RE_NONE = 32;
int RE_UNICODE = 64;
int RE_OPTION_ONCE = 128; // odd...but it is odd in ruby too.
int RE_LITERAL = 256; // reusing regexp_options since we used
// and we won't escape regexp_options.
int RE_DEFAULT = 512; // Only for RubyRegexp. for kcode default
int RE_FIXED = RubyRegexp.ARG_ENCODING_FIXED;

@Deprecated
int RE_OPTION_LONGEST = 16;
@Deprecated
int RE_MAY_IGNORECASE = 32;
}
10 changes: 5 additions & 5 deletions core/src/main/java/org/jruby/util/RegexpOptions.java
Original file line number Diff line number Diff line change
@@ -174,6 +174,7 @@ public int toEmbeddedOptions() {
if (literal) options |= RubyRegexp.RE_LITERAL;
if (kcodeDefault) options |= RubyRegexp.RE_DEFAULT;
if (fixed) options |= RubyRegexp.RE_FIXED;
if (encodingNone) options |= RubyRegexp.ARG_ENCODING_NONE;

return options;
}
@@ -189,7 +190,6 @@ public int toJoniOptions() {
if (multiline) options |= RubyRegexp.RE_OPTION_MULTILINE;
if (ignorecase) options |= RubyRegexp.RE_OPTION_IGNORECASE;
if (extended) options |= RubyRegexp.RE_OPTION_EXTENDED;
if (!isKcodeDefault()) options |= kcode.bits();
return options;
}

@@ -202,7 +202,7 @@ public int toOptions() {
if (ignorecase) options |= RubyRegexp.RE_OPTION_IGNORECASE;
if (extended) options |= RubyRegexp.RE_OPTION_EXTENDED;
if (fixed) options |= RubyRegexp.RE_FIXED;
if (encodingNone) options |= RubyRegexp.ARG_ENCODING_NONE;
if (encodingNone) options |= RubyRegexp.RE_NONE;
return options;
}

@@ -212,14 +212,14 @@ public static RegexpOptions fromEmbeddedOptions(int embeddedOptions) {
options.kcodeDefault = (embeddedOptions & RubyRegexp.RE_DEFAULT) != 0;
options.setOnce((embeddedOptions & RubyRegexp.RE_OPTION_ONCE) != 0);
options.setLiteral((embeddedOptions & RubyRegexp.RE_LITERAL) != 0);
options.setFixed((embeddedOptions & RubyRegexp.RE_FIXED) != 0);
options.setFixed((embeddedOptions & RubyRegexp.RE_FIXED) != 0);
options.setEncodingNone((embeddedOptions & RubyRegexp.RE_NONE) != 0);

return options;
}

public static RegexpOptions fromJoniOptions(int joniOptions) {
KCode kcode = KCode.fromBits(joniOptions);
RegexpOptions options = new RegexpOptions(kcode, kcode == KCode.NONE);
RegexpOptions options = new RegexpOptions();
options.setMultiline((joniOptions & RubyRegexp.RE_OPTION_MULTILINE) != 0);
options.setIgnorecase((joniOptions & RubyRegexp.RE_OPTION_IGNORECASE) != 0);
options.setExtended((joniOptions & RubyRegexp.RE_OPTION_EXTENDED) != 0);
27 changes: 25 additions & 2 deletions spec/compiler/general_spec.rb
Original file line number Diff line number Diff line change
@@ -996,7 +996,7 @@ def a; true; end
protected; def c; true; end
end.new
[obj.a, (obj.b rescue false), (obj.c rescue false)]') do |x|
x.should == [true, false, false]
expect(x).to eq([true, false, false])
end
end

@@ -1006,7 +1006,30 @@ def a; __callee__; end
define_method :b, instance_method(:a)
end.new
[obj.a, obj.b]') do |x|
x.should == [:a, :b]
expect(x).to eq([:a, :b])
end
end

it "raises appropriate missing-method error for call type" do
# Variable
run('begin; does_not_exist; rescue NameError; $!; end') do |x|
expect(x).to be_instance_of(NameError)
end

# Functional
run('begin; does_not_exist(); rescue NameError; $!; end') do |x|
expect(x).to be_instance_of(NoMethodError)
end

# Normal
run('begin; self.does_not_exist; rescue NameError; $!; end') do |x|
expect(x).to be_instance_of(NoMethodError)
end
end

it "preserves 'encoding none' flag for literal regexp" do
run('/a/n.options') do |x|
expect(x).to eq(32)
end
end
end