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

Getting C compiler errors when using functions that return real values #63

Closed
TheGrandmother opened this issue Jan 29, 2015 · 7 comments

Comments

@TheGrandmother
Copy link
Contributor

When i try to compile this code :

class Main
    def main() : void{
        let 
            b = new Bob
        in
            print("{}\n",get b.glenn())
    }

class Bob
    a : real
    def init() :void {
        this.a = 0.0;
    }
    def glenn() : real{
        let
            b = 1.0 : real
        in
            if (b + this.a > 2) then
                100.0
            else
                2.0
    }

i get the following errors from the compiler :

lol_src/Main.pony.c:80:29: error: pointer cannot be cast to type 'double'
  double _tmp_4 = ((double) future_get_actor(_fut_2));
                            ^~~~~~~~~~~~~~~~~~~~~~~~

lol_src/Bob.pony.c:168:35: error: operand of type 'double' cannot be cast to a pointer type
      future_fulfil(fut, ((void*) Bob_glenn(p)));
                                  ^~~~~~~~~~~~

I get no type errors or other errors from the encore parser.

BUT if i change the return type of glenn to int as follows:

class Main
    def main() : void{
        let 
            b = new Bob
        in
            print("{}\n",get b.glenn())
    }

class Bob
    a : real
    def init() :void {
        this.a = 0.0;
    }
    def glenn() : int{
        let
            b = 1.0 : real
        in
            if (b + this.a > 2) then
                100
            else
                2
    }

it compiles without errors :(

@TheGrandmother TheGrandmother changed the title C compiler errors when using functions that return real values Getting C compiler errors when using functions that return real values Jan 29, 2015
@supercooldave
Copy link

It seems to be an interaction between Futures and real. Let's write a simpler test case that reveals the bug.

class Main
    def main() : void{
        let 
            b = new Bob
        in
            print("{}\n",get b.glenn())
    }

class Bob
    def glenn() : real{
        2.1
    }

Does this fail? Anything simpler? (I can have a look later.)

@TheGrandmother
Copy link
Contributor Author

Still fails.

@supercooldave
Copy link

Failing test added in commit 8f21f1a.
See file: src/tests/encore/basic/realfutures.enc

@albertnetymk
Copy link
Contributor

Future values should be allocated on the heap of the producer.

The corresponding C code for

  def glenn() : real{
    2.1
  }

is
fulfil(fut, ((void *) Bob_glenn(p))); while the correct output should be

double *fut_v = pony_alloc(sizeof *fut_v);
*fut_v = Bob_glenn(p);
fulfil(fut, fut_v);

This only affects values whose size is greater than one word, namely sizeof(void*).

@EliasC
Copy link
Contributor

EliasC commented Jan 29, 2015

I propose we use pony_arg_t (union of int, double and void *) for futures. It is used when sending values between actors and in a few other places already. Then we don't need to worry about what fits in a word and not, and we don't have allocate any primitives before sending them in futures.

The reason we haven't seen this yet is that we mostly use ints and pack them into the void * type of futures. Good that someone finally started using reals :)

@albertnetymk
Copy link
Contributor

+1 for pony_arg_t

@EliasC
Copy link
Contributor

EliasC commented Feb 5, 2015

Fixed as of d13f203

@EliasC EliasC closed this as completed Feb 5, 2015
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

4 participants