-
Notifications
You must be signed in to change notification settings - Fork 11
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
Can't compile cup program which has a function which returns a struct #9
Comments
This is a known limitation, and there are currently no plans (by me at least) of passing around structs as values to/from functions. The reason for this is so that all function return values can fit in a single x86_64 register. Allowing passing structs as arguments / as return values would necessitate figuring out how (and where) to properly allocate the space in the caller, and then copying the whole struct into that location. If this is something you're interested in working on, I'm happy to provide any assistance I can, but I am personally more focussed on other projects at the moment to work on this myself. |
Okay, maybe I'll try to play around with that, but I'm not really an assembly programmer or something so idk. |
Would it make sense to push struct fields to the stack instead of passing a struct on the register? |
Yep. let's assume the following example: fn get_a(): A {
let obj: A;
...
return obj;
}
fn foo() {
let a_in_foo: A = get_a();
} Here, we'd want to do something like:
There are some cases to be careful of, which I'm not exactly sure what the best way to handle is, such as: fn foo(): A { return get_a(); }
fn bar(): A { return foo(); }
fn baz(): A { return bar(); } One way to deal with this would be to allocate / copy an intermediate object in each function, but that seems very wasteful. It would be nice to have some way to "figure out" where the object actually needs to be allocated, and then just pass around pointers. Obviously that is more complex, and doesn't need to all be implemented at once. Just make sure that any design you pick leaves room for improvements like these to be made in the future, and that at the very least such situations are handled correctly, even if it is inefficient. |
A bit offtopic question but can I share ideas/suggestions in issue tracker? |
Sure. |
Struct copying for var to var cannot be done too? |
It would be nice to support that as well. I didn't mention it because that part would be fairly straightforward, we just copy the fields from the location of the first variable to the other. |
I've just noticed that you can do something like that: import "std/memory.cup"
struct A{
i: i32;
}
initialize A(b: i32){
self.i = b;
}
fn main(){
let a: A* = new A(5);
let b = 5;
let c: A = *a;
print(c.i);
} Copy by dereferencing. |
I don't believe I ever added any logic in the compiler that loops over all members of a struct and copies it over. Even though this passes type checking, I suspect this won't actually work for structs that don't fit in a register. In the current state of the language this should throw an error. |
Btw by allocating space in stack frame do you mean just pushing onto stack or something else? |
You should be able to use the |
So we allocate more space during parsing of the function? |
From what I see it is already done in function parsing. |
I don't think I'm able to implement this. |
No worries, thanks for trying! |
I tried to compile the following program:
Compiler tells me:
The text was updated successfully, but these errors were encountered: