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

Functions with assembly containing mcli result in MemoryOverflow when passed a literal #1455

Open
simonr0204 opened this issue May 3, 2022 · 8 comments
Labels
bug Something isn't working compiler General compiler. Should eventually become more specific as the issue is triaged P: medium

Comments

@simonr0204
Copy link
Contributor

simonr0204 commented May 3, 2022

For example, in order to call :

    fn from(bits: b256) -> EthAddress{
        asm(r1: bits) {
            mcli r1 i12;
        };
        ...
        ...
    }

the parameter must first be assigned to a variable. :

    let temp= 0x... ; 
    let address = ~EthAddress::from(temp);

otherwise a MemoryOverflow error occurs.

@simonr0204 simonr0204 added the bug Something isn't working label May 3, 2022
@adlerjohn adlerjohn added the compiler General compiler. Should eventually become more specific as the issue is triaged label May 3, 2022
@otrho
Copy link
Contributor

otrho commented May 3, 2022

Here's a full repro showing that yep, the passed value must be in a local variable and not passed as a literal.

script;

fn f(bits: b256) {
  asm(r1: bits) {
    mcli r1 i12;
  };
}

fn main() {
    // This works.
    let b = 0xABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB;
    f(b);

    // This fails.
    f(0xCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD);
}

The second call is trying to use a literal which is referenced directly in the data section which is not stack memory and therefore causes the MemoryOverflow.

@adlerjohn
Copy link
Contributor

I wouldn't call this a bug, since it's expected behavior than you can't clear memory outside your owned stack or heap range.

@otrho
Copy link
Contributor

otrho commented May 3, 2022

It's a bit tricky for Sway devs with the implicit by-reference semantics, versus having explicit references in the language.

We tend to say anything that doesn't fit in a register is passed around by reference, but the Sway dev doesn't want to think about whether it was allocated somewhere on the stack by the compiler or not.

So I think the above should work, and the inliner needs to put all args onto the stack by default, and later if we find that copying it is unnecessary we can optimise it away.

Once we're back to non-critical work I'm very keen to update the memory model we currently use in the IR, and this fix fits into that scope of work.

@mohammadfawaz
Copy link
Contributor

mohammadfawaz commented May 3, 2022

So I think the above should work, and the inliner needs to put all args onto the stack by default, and later if we find that copying it is unnecessary we can optimise it away.

This is reasonable I think. If we do this, then only devs writing asm blocks would potentially face the issue above and that's probably okay (unless an asm block follows the same behavior as functions and put its args onto the stack?).

E.g.:

script;

fn main() {
    asm(r1: 0xCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCD) {
        mcli r1 i12;
    };
}

@otrho
Copy link
Contributor

otrho commented May 3, 2022

Ugh, even then I feel like r1 should be a reference to something... it's not unreasonable to want this to work. At the very least it should be a compile error rather than a panic.

@mohammadfawaz
Copy link
Contributor

mohammadfawaz commented May 3, 2022

Yes absolutely... I wanted to say that legal code should never panic (unless intentional, e.g.: assert), but we can't ever make that promise to someone writing asm blocks.

@mohammadfawaz
Copy link
Contributor

mohammadfawaz commented Jul 5, 2022

Some updates from: #2217 (comment)

I'm starting to think that this behavior should be disallowed by implementing mutability checking in asm blocks AND disallow passing literals (which are basically constants) as mut to function arguments and asm blocks (once mut is supported for both).

@otrho
Copy link
Contributor

otrho commented Jul 5, 2022

That would work too. 🙂

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working compiler General compiler. Should eventually become more specific as the issue is triaged P: medium
Projects
Status: Todo
Development

No branches or pull requests

4 participants