Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

jrubyc: variable ruby_result is already defined in method #812

Closed
phs opened this issue Jun 19, 2013 · 2 comments
Closed

jrubyc: variable ruby_result is already defined in method #812

phs opened this issue Jun 19, 2013 · 2 comments

Comments

@phs
Copy link
Contributor

phs commented Jun 19, 2013

jrubyc is not sandboxing the name of its java method return value away from the arguments names. Notice the double IRubyObject ruby_result below.

Perhaps prefix arguments with ruby_arg_?

$ jruby --version
jruby 1.7.4 (1.9.3p392) 2013-05-16 2390d3b on Java HotSpot(TM) 64-Bit Server VM 1.7.0_12-ea-b08 +indy [darwin-x86_64]
$ cat jrubyc_name_mangling.rb
class C
  java_signature 'public int f(int result)'
  def f(arg)
    arg
  end
end
$ jrubyc --java --javac jrubyc_name_mangling.rb
/Users/phil/derp/C.java:65: error: variable ruby_result is already defined in method f(int)
        IRubyObject ruby_result = Helpers.invoke(__ruby__.getCurrentContext(), this, "f", ruby_result);
                    ^
1 error
$ cat C.java
import org.jruby.Ruby;
import org.jruby.RubyObject;
import org.jruby.runtime.Helpers;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.javasupport.JavaUtil;
import org.jruby.RubyClass;


public class C extends RubyObject  {
    private static final Ruby __ruby__ = Ruby.getGlobalRuntime();
    private static final RubyClass __metaclass__;

    static {
        String source = new StringBuilder("class C\n" +
            "  java_signature 'public int f(int result)'\n" +
            "  def f(arg)\n" +
            "    arg\n" +
            "  end\n" +
            "end\n" +
            "").toString();
        __ruby__.executeScript(source, "jrubyc_name_mangling.rb");
        RubyClass metaclass = __ruby__.getClass("C");
        metaclass.setRubyStaticAllocator(C.class);
        if (metaclass == null) throw new NoClassDefFoundError("Could not load Ruby class: C");
        __metaclass__ = metaclass;
    }

    /**
     * Standard Ruby object constructor, for construction-from-Ruby purposes.
     * Generally not for user consumption.
     *
     * @param ruby The JRuby instance this object will belong to
     * @param metaclass The RubyClass representing the Ruby class of this object
     */
    private C(Ruby ruby, RubyClass metaclass) {
        super(ruby, metaclass);
    }

    /**
     * A static method used by JRuby for allocating instances of this object
     * from Ruby. Generally not for user comsumption.
     *
     * @param ruby The JRuby instance this object will belong to
     * @param metaclass The RubyClass representing the Ruby class of this object
     */
    public static IRubyObject __allocate__(Ruby ruby, RubyClass metaClass) {
        return new C(ruby, metaClass);
    }

    /**
     * Default constructor. Invokes this(Ruby, RubyClass) with the classloader-static
     * Ruby and RubyClass instances assocated with this class, and then invokes the
     * no-argument 'initialize' method in Ruby.
     */
    public C() {
        this(__ruby__, __metaclass__);
        Helpers.invoke(__ruby__.getCurrentContext(), this, "initialize");
    }


    public int f(int result) {
        IRubyObject ruby_result = JavaUtil.convertJavaToRuby(__ruby__, result);
        IRubyObject ruby_result = Helpers.invoke(__ruby__.getCurrentContext(), this, "f", ruby_result);
        return (Integer)ruby_result.toJava(int.class);

    }

}
@headius
Copy link
Member

headius commented Jun 23, 2013

Want to come up with a PR? The code for this is all in Ruby.

On Wed, Jun 19, 2013 at 3:02 PM, Phil Smith notifications@github.comwrote:

jrubyc is not sandboxing the name of its java method return value away
from the arguments names. Notice the double IRubyObject ruby_result below.

Perhaps prefix arguments with ruby_arg_?

$ jruby --version
jruby 1.7.4 (1.9.3p392) 2013-05-16 2390d3b on Java HotSpot(TM) 64-Bit Server VM 1.7.0_12-ea-b08 +indy [darwin-x86_64]
$ cat jrubyc_name_mangling.rb

class C
java_signature 'public int f(int result)'
def f(arg)
arg
endend

$ jrubyc --java --javac jrubyc_name_mangling.rb
/Users/phil/derp/C.java:65: error: variable ruby_result is already defined in method f(int)
IRubyObject ruby_result = Helpers.invoke(ruby.getCurrentContext(), this, "f", ruby_result);
^
1 error
$ cat C.java

import org.jruby.Ruby;import org.jruby.RubyObject;import org.jruby.runtime.Helpers;import org.jruby.runtime.builtin.IRubyObject;import org.jruby.javasupport.JavaUtil;import org.jruby.RubyClass;

public class C extends RubyObject {
private static final Ruby ruby = Ruby.getGlobalRuntime();
private static final RubyClass metaclass;

static {
    String source = new StringBuilder("class C\n" +
        "  java_signature 'public int f(int result)'\n" +
        "  def f(arg)\n" +
        "    arg\n" +
        "  end\n" +
        "end\n" +
        "").toString();
    __ruby__.executeScript(source, "jrubyc_name_mangling.rb");
    RubyClass metaclass = __ruby__.getClass("C");
    metaclass.setRubyStaticAllocator(C.class);
    if (metaclass == null) throw new NoClassDefFoundError("Could not load Ruby class: C");
    __metaclass__ = metaclass;
}

/**     * Standard Ruby object constructor, for construction-from-Ruby purposes.     * Generally not for user consumption.     *     * @param ruby The JRuby instance this object will belong to     * @param metaclass The RubyClass representing the Ruby class of this object     */
private C(Ruby ruby, RubyClass metaclass) {
    super(ruby, metaclass);
}

/**     * A static method used by JRuby for allocating instances of this object     * from Ruby. Generally not for user comsumption.     *     * @param ruby The JRuby instance this object will belong to     * @param metaclass The RubyClass representing the Ruby class of this object     */
public static IRubyObject __allocate__(Ruby ruby, RubyClass metaClass) {
    return new C(ruby, metaClass);
}

/**     * Default constructor. Invokes this(Ruby, RubyClass) with the classloader-static     * Ruby and RubyClass instances assocated with this class, and then invokes the     * no-argument 'initialize' method in Ruby.     */
public C() {
    this(__ruby__, __metaclass__);
    Helpers.invoke(__ruby__.getCurrentContext(), this, "initialize");
}


public int f(int result) {
    IRubyObject ruby_result = JavaUtil.convertJavaToRuby(__ruby__, result);
    IRubyObject ruby_result = Helpers.invoke(__ruby__.getCurrentContext(), this, "f", ruby_result);
    return (Integer)ruby_result.toJava(int.class);

}

}


Reply to this email directly or view it on GitHubhttps://github.com//issues/812
.

headius pushed a commit that referenced this issue Jul 24, 2013
A ruby argument named 'result' will conflict with the stack local used for the return value: both will become 'ruby_result' in java.  Namespace arguments away from this by prefixing them with 'ruby_arg_' instead of merely 'ruby_'.

See #812
@rtyler
Copy link

rtyler commented Aug 7, 2015

At least with JRuby 9k, this is no bug is no longer present:

➜  sandbox  cat > name-mangler.rb
class C
  java_signature 'public int f(int result)'
  def f(arg)
    arg
  end
end
➜  sandbox  rvm use jruby@rubygems
Using /home/tyler/.rvm/gems/jruby-9.0.0.0 with gemset rubygems
➜  sandbox  jrubyc --java --javac name-mangler.rb 
➜  sandbox  ls
C.class  C.java  name-mangler.rb
➜  sandbox 

@rtyler rtyler closed this as completed Aug 7, 2015
@enebo enebo added this to the JRuby 9.0.0.0 milestone Aug 20, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants