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

cannnot call C functions #5

Closed
kojix2 opened this issue Aug 16, 2017 · 6 comments
Closed

cannnot call C functions #5

kojix2 opened this issue Aug 16, 2017 · 6 comments

Comments

@kojix2
Copy link
Member

kojix2 commented Aug 16, 2017

Hello.
I tried the sample code. #4 (comment)

lib "<math.h>" # Yes, "do" is obsolete.
  double cos(double)
end

class A
   def math
      return cos(4.5)
   end
end

However, the following error occured on my computer.

/path/2.3.4/lib/ruby/gems/2.3.0/gems/rubex-0.0.1/lib/rubex/ast/expression.rb:694:in `code_for_ruby_method_call': undefined method `c_code' for nil:NilClass (NoMethodError)
	from /path/2.3.4/lib/ruby/gems/2.3.0/gems/rubex-0.0.1/lib/rubex/ast/expression.rb:646:in `c_code'
	from /path/2.3.4/lib/ruby/gems/2.3.0/gems/rubex-0.0.1/lib/rubex/ast/expression.rb:777:in `generate_evaluation_code'
	from /path/2.3.4/lib/ruby/2.3.0/forwardable.rb:204:in `generate_evaluation_code'
	from /path/2.3.4/lib/ruby/gems/2.3.0/gems/rubex-0.0.1/lib/rubex/ast/statement.rb:361:in `generate_code'
	from /path/2.3.4/lib/ruby/gems/2.3.0/gems/rubex-0.0.1/lib/rubex/ast/top_statement.rb:213:in `block in generate_statements'
	from /path/2.3.4/lib/ruby/gems/2.3.0/gems/rubex-0.0.1/lib/rubex/ast/top_statement.rb:212:in `each'
	from /path/2.3.4/lib/ruby/gems/2.3.0/gems/rubex-0.0.1/lib/rubex/ast/top_statement.rb:212:in `generate_statements'
	from /path/2.3.4/lib/ruby/gems/2.3.0/gems/rubex-0.0.1/lib/rubex/ast/top_statement.rb:202:in `generate_function_definition'
	from /path/2.3.4/lib/ruby/gems/2.3.0/gems/rubex-0.0.1/lib/rubex/ast/top_statement.rb:180:in `block in generate_code'
	from /path/2.3.4/lib/ruby/gems/2.3.0/gems/rubex-0.0.1/lib/rubex/code_writer.rb:127:in `block'
	from /path/2.3.4/lib/ruby/gems/2.3.0/gems/rubex-0.0.1/lib/rubex/ast/top_statement.rb:179:in `generate_code'
	from /path/2.3.4/lib/ruby/gems/2.3.0/gems/rubex-0.0.1/lib/rubex/ast/top_statement.rb:261:in `generate_code'
	from /path/2.3.4/lib/ruby/gems/2.3.0/gems/rubex-0.0.1/lib/rubex/ast/top_statement.rb:333:in `block in generate_code'
	from /path/2.3.4/lib/ruby/gems/2.3.0/gems/rubex-0.0.1/lib/rubex/ast/top_statement.rb:332:in `each'
	from /path/2.3.4/lib/ruby/gems/2.3.0/gems/rubex-0.0.1/lib/rubex/ast/top_statement.rb:332:in `generate_code'
	from /path/2.3.4/lib/ruby/gems/2.3.0/gems/rubex-0.0.1/lib/rubex/ast/node.rb:189:in `block in generate_code'
	from /path/2.3.4/lib/ruby/gems/2.3.0/gems/rubex-0.0.1/lib/rubex/ast/node.rb:188:in `each'
	from /path/2.3.4/lib/ruby/gems/2.3.0/gems/rubex-0.0.1/lib/rubex/ast/node.rb:188:in `generate_code'
	from /path/2.3.4/lib/ruby/gems/2.3.0/gems/rubex-0.0.1/lib/rubex/ast/node.rb:17:in `process_statements'
	from /path/2.3.4/lib/ruby/gems/2.3.0/gems/rubex-0.0.1/lib/rubex/compiler.rb:50:in `generate_code'
	from /path/2.3.4/lib/ruby/gems/2.3.0/gems/rubex-0.0.1/lib/rubex/compiler.rb:9:in `compile'
	from /path/2.3.4/lib/ruby/gems/2.3.0/gems/rubex-0.0.1/bin/rubex:10:in `<top (required)>'
	from /path/2.3.4/bin/rubex:22:in `load'
	from /path/2.3.4/bin/rubex:22:in `<main>'

The following code can be executed without error. But it shows me a bit strange behavior.

lib "<math.h>"
  double cos(double)
end

def stray_cos
  return cos(4.5)
end

class A
  def cos
    return cos(4.5)
  end
end
irb(main):001:0> require './r5.so'
=> true
irb(main):002:0> stray_cos
=> -0.2107957994307797
irb(main):003:0> A.new.cos
=> 4.5 # ??
irb(main):004:0> A.new.stray_cos
=> -0.2107957994307797

This is C file.

/* C extension for r5.
This file in generated by Rubex::Compiler. Do not change!
File generation time: ***.*/

#include <ruby.h>
#include <stdint.h>
#include <stdbool.h>
#include <math.h>

#define __rubex_INT2BOOL(arg) (arg ? Qtrue : Qfalse)


VALUE rb_cObject;
VALUE __rubex_rb_cls_A;
static VALUE __rubex_rb_f_Object_stray_cos (int argc,VALUE* argv,VALUE __rubex_arg_self);
static VALUE __rubex_rb_f_A_cos (int argc,VALUE* argv,VALUE __rubex_arg_self);

VALUE __rubex_char2rubystr(char ch);
VALUE __rubex_char2rubystr(char ch)
{
  char s[2];
  s[0] = ch;
  s[1] = '\0';
  return rb_str_new2(s);
}


static VALUE __rubex_rb_f_Object_stray_cos (int argc,VALUE* argv,VALUE __rubex_arg_self)
{
  if (argc < 0)
  {
    rb_raise(rb_eArgError, "Need 0 args, not %d", argc);
  }


  /* Rubex file location: /home/kojix2/Ruby/rubex/r5.rubex:6 */
  return rb_float_new(cos(4.5));
}

static VALUE __rubex_rb_f_A_cos (int argc,VALUE* argv,VALUE __rubex_arg_self)
{
  VALUE __rubex_rb_f_A_cos_actual_args[0];
  if (argc < 0)
  {
    rb_raise(rb_eArgError, "Need 0 args, not %d", argc);
  }


  /* Rubex file location: /home/kojix2/Ruby/rubex/r5.rubex:11 */
  return __rubex_rb_f_A_cos_actual_args[0] = rb_float_new(4.5);
  __rubex_rb_f_A_cos(1, __rubex_rb_f_A_cos_actual_args,__rubex_arg_self);
}


void Init_r5 ();
void Init_r5 ()
{
  VALUE __rubex_rb_cls_A;

  __rubex_rb_cls_A = rb_define_class("A", rb_cObject);

  rb_define_method(rb_cObject ,"stray_cos", __rubex_rb_f_Object_stray_cos, -1);
  rb_define_method(__rubex_rb_cls_A ,"cos", __rubex_rb_f_A_cos, -1);
}

Perhaps the setting and the execution environment are not sufficient, and that may be the reason it does not work. However, as it may be useful for something, I will report it as it is.
Thank you.

@kojix2 kojix2 changed the title cannnot call C functions in the class cannnot call C functions Aug 16, 2017
@v0dro
Copy link
Member

v0dro commented Aug 16, 2017

Thank you for your report. The first example is working on my computer. Can you use the current master and see if it still works? Also can you write the commands that you used over here?

As for the second example:

lib "<math.h>"
  double cos(double)
end

def stray_cos
  return cos(4.5)
end

class A
  def cos
    return cos(4.5)
  end
end

The A.new.cos is not working because Rubex is assuming that cos is a C method. Since C methods are not namespaced, it is currently not possible to use the same name as the C method for the Ruby method. So if you write code like this:

lib "<math.h>"
  double cos(double)
end

def stray_cos
  return cos(4.5)
end

class A
  def ruby_cos
    return cos(4.5)
  end
end

It will work with A.new.ruby_cos. I will write the namespacing feature in the future work soon.

@kojix2
Copy link
Member Author

kojix2 commented Aug 16, 2017

A.new.ruby_cos works good!
The first example still not work. I will think about it for a while. Thank you.

@v0dro v0dro changed the title cannnot call C functions Allow Ruby methods with same names as extern C functions. Aug 18, 2017
@v0dro v0dro changed the title Allow Ruby methods with same names as extern C functions. cannnot call C functions Aug 18, 2017
@v0dro
Copy link
Member

v0dro commented Aug 18, 2017

If there are any updates please post in this thread. Closing for now.

@v0dro v0dro closed this as completed Aug 18, 2017
@kojix2
Copy link
Member Author

kojix2 commented Aug 27, 2017

I tried experiment

m1.rubex

lib "<math.h>"
  double sin(doublue)
end

def top_sin(x)
  sin(x)
end

class RMath
  def ruby_sin(x)
    sin(x)
  end
end

m2.rubex

lib "<math.h>"
  double sin(doublue)
end

class RMath
  def ruby_sin(x)
    sin(x)
  end
end

change rubex-0.0.1/lib/rubex/symbol_table/scope.rb

172     private
173       def recursive_find name, scope
174         if scope
175           require 'rainbow'
176           if scope.has_entry?(name)
177             puts Rainbow("+" << name.to_s << " in " << scope.name.to_s).green
178             return scope[name]
179           else
180             puts Rainbow("- " << name.to_s << " in " << scope.name.to_s).red
181             return recursive_find(name, scope.outer_scope)
182           end
183         end
184 
185         return nil
186       end
rubex m1.rubex
+ Object in Object
+ Object in Object
+ top_sin in Object
+ x in top_sin
- sin in top_sin
+ sin in Object
- sin in top_sin
+ sin in Object
- sin in top_sin
+ sin in Object
- top_sin in top_sin
+ top_sin in Object
+ RMath in Object
+ ruby_sin in RMath
+ x in ruby_sin
- sin in ruby_sin
- sin in RMath
+ sin in Object
- sin in ruby_sin
- sin in RMath
+ sin in Object
- sin in ruby_sin
- sin in RMath
+ sin in Object
- ruby_sin in ruby_sin
+ ruby_sin in RMath
- sin in top_sin
+ sin in Object
- sin in ruby_sin
- sin in RMath
+ sin in Object
+ RMath in Object
+ Object in Object
+ Object in Object
+ RMath in Object

Succeeded

rubex m2.rubex
- Object in Object
+ RMath in Object
+ ruby_sin in RMath
+ x in ruby_sin
- sin in ruby_sin
- sin in RMath
- sin in Object
- sin in ruby_sin
- sin in RMath
- sin in Object
+ sin in ruby_sin
- ruby_sin in ruby_sin
+ ruby_sin in RMath
+ sin in ruby_sin
+ sin in ruby_sin

error

2.4.0/gems/rubex-0.0.1/lib/rubex/ast/expression.rb:694:in `code_for_ruby_method_call': undefined method `c_code' for nil:NilClass (NoMethodError)

Well. I do not know whether it is correct or wrong.
Mr. v0dro, do you understand something?

@v0dro
Copy link
Member

v0dro commented Aug 27, 2017

Investigating.

@v0dro v0dro reopened this Aug 27, 2017
@v0dro
Copy link
Member

v0dro commented Aug 27, 2017

Has been fixed in c9793b6

Thank you for your report! Do send more :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants