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

Commits on Sep 20, 2014

  1. Copy the full SHA
    200e05c View commit details
  2. Copy the full SHA
    7ef5314 View commit details
Original file line number Diff line number Diff line change
@@ -43,6 +43,10 @@ public Variable getResult() {
return result;
}

public List<Operand> getPieces() {
return pieces;
}

@Override
public void updateResult(Variable v) {
this.result = v;
@@ -82,6 +86,8 @@ public Object interpret(ThreadContext context, StaticScope currScope, DynamicSco
newString.append((piece instanceof RubyString) ? (RubyString) piece : piece.to_s());
}

newString.setFrozen(true);

return self.callMethod(context, "`", newString);
}

40 changes: 38 additions & 2 deletions core/src/main/java/org/jruby/ir/targets/JVMVisitor.java
Original file line number Diff line number Diff line change
@@ -14,6 +14,7 @@
import org.jruby.ir.operands.Boolean;
import org.jruby.ir.operands.Float;
import org.jruby.ir.operands.GlobalVariable;
import org.jruby.ir.operands.Label;
import org.jruby.ir.representations.BasicBlock;
import org.jruby.ir.runtime.IRRuntimeHelpers;
import org.jruby.parser.StaticScope;
@@ -598,7 +599,35 @@ public void AluInstr(AluInstr instr) {

@Override
public void BacktickInstr(BacktickInstr instr) {
super.BacktickInstr(instr); //To change body of overridden methods use File | Settings | File Templates.
// prepare for call to "`" below
jvmMethod().loadContext();
jvmMethod().loadSelf(); // TODO: remove caller
jvmMethod().loadSelf();

ByteList csByteList = new ByteList();
jvmMethod().pushString(csByteList);

for (Operand p : instr.getPieces()) {
// visit piece and ensure it's a string
visit(p);
jvmAdapter().dup();
org.objectweb.asm.Label after = new org.objectweb.asm.Label();
jvmAdapter().instance_of(p(RubyString.class));
jvmAdapter().iftrue(after);
jvmAdapter().invokevirtual(p(IRubyObject.class), "anyToString", sig(IRubyObject.class));

jvmAdapter().label(after);
jvmAdapter().invokevirtual(p(RubyString.class), "append", sig(RubyString.class, IRubyObject.class));
}

// freeze the string
jvmAdapter().dup();
jvmAdapter().ldc(true);
jvmAdapter().invokeinterface(p(IRubyObject.class), "setFrozen", sig(void.class, boolean.class));

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

@Override
@@ -2062,7 +2091,14 @@ public void StringLiteral(StringLiteral stringliteral) {

@Override
public void SValue(SValue svalue) {
super.SValue(svalue); //To change body of overridden methods use File | Settings | File Templates.
visit(svalue.getArray());
jvmAdapter().dup();
jvmAdapter().instance_of(p(RubyArray.class));
org.objectweb.asm.Label after = new org.objectweb.asm.Label();
jvmAdapter().iftrue(after);
jvmAdapter().pop();
jvmMethod().pushNil();
jvmAdapter().label(after);
}

@Override
26 changes: 26 additions & 0 deletions spec/compiler/general_spec.rb
Original file line number Diff line number Diff line change
@@ -827,4 +827,30 @@ class JRUBY4925
x = compile_and_run '::JRUBY4925_BLAH, a = 1, 2'
expect(JRUBY4925_BLAH).to eq 1
end

it "compiles backquotes (backtick)" do
x = compile_and_run 'o = Object.new; def o.`(str); str; end; def o.go; `hello`; end; o.go'

expect(x).to eq 'hello'
end

it "creates frozen strings for backquotes (backtick)" do
x = compile_and_run 'o = Object.new; def o.`(str); str; end; def o.go; `hello`; end; o.go'

expect(x).to be_frozen
end

it "compiles rest args passed to return, break, and next (svalue)" do
x = compile_and_run 'a = [1,2,3]; 1.times { break *a }'

expect(x).to eq [1,2,3]

x = compile_and_run 'a = [1,2,3]; lambda { return *a }.call'

expect(x).to eq [1,2,3]

x = compile_and_run 'a = [1,2,3]; def foo; yield; end; foo { next *a }'

expect(x).to eq [1,2,3]
end
end
18 changes: 0 additions & 18 deletions test/jruby/test_ast_inspector.rb

This file was deleted.