Skip to content

[Decompiler Feature Request] add support to optimize complex enum operations #17088

@junxzm1990

Description

@junxzm1990

🚀 Feature Request

Extend the decompiler to optimize complex enum operations.

At this point, it can only decompile the following code (ref: decompiler test case cfg_opt.move)

module 0x99::cfg_opt_complex {
    enum Entity has drop {
        Person { id: u64 },
        Institution { id: u64, admin: Admin }
    }

    enum Admin has drop {
        Superuser,
        User(u64)
    }

    // Ensure function is inlined so we create nested matches in the next one.
    inline fun id(self: &Entity): u64 {
        match (self) {
            Person{id} if *id > 10 => *id,
            Institution{id, ..} => *id,
            _ => 0
        }
    }

    fun admin_id(self: &Entity): u64 {
        match (self) {
            Institution{admin: Admin::Superuser, ..} => 1 + self.id(),
            Institution{admin: Admin::User(id), ..} if *id > 10 => *id + self.id(),
            Institution{admin: Admin::User(id), ..} if  *id <= 10 => self.id() + 5,
            _ => self.id()
        }
    }
}

===>

fun admin_id(self: &Entity): u64 {
        let _t8;
        let _t6;
        let _t3;
        let _t1;
        let _t2;
        let _t5;
        'l0: loop {
            if (!((self is Institution) && (&self.admin is Superuser))) {
                loop {
                    if (self is Institution) {
                        _t5 = &self.admin;
                        if (_t5 is User) {
                            _t2 = &_t5._0;
                            if (*_t2 > 10) break
                        }
                    };
                    loop {
                        if (self is Institution) {
                            _t5 = &self.admin;
                            if (_t5 is User) {
                                if (*&_t5._0 <= 10) break}
                        };
                        _t1 = self;
                        if (_t1 is Person) {
                            _t2 = &_t1.id;
                            if (*_t2 > 10) {
                                _t3 = *_t2;
                                break 'l0
                            }
                        };
                        if (_t1 is Institution) {
                            _t3 = *&_t1.id;
                            break 'l0
                        };
                        _t3 = 0;
                        break 'l0
                    };
                    _t1 = self;
                    loop {
                        if (_t1 is Person) {
                            _t2 = &_t1.id;
                            if (*_t2 > 10) {
                                _t6 = *_t2;
                                break
                            }
                        };
                        if (_t1 is Institution) {
                            _t6 = *&_t1.id;
                            break
                        };
                        _t6 = 0;
                        break
                    };
                    _t3 = _t6 + 5;
                    break 'l0
                };
                _t1 = self;
                loop {
                    if (_t1 is Person) {
                        _t2 = &_t1.id;
                        if (*_t2 > 10) {
                            _t6 = *_t2;
                            break
                        }
                    };
                    if (_t1 is Institution) {
                        _t6 = *&_t1.id;
                        break
                    };
                    _t6 = 0;
                    break
                };
                _t3 = *_t2 + _t6;
                break
            };
            loop {
                if (self is Person) {
                    _t2 = &self.id;
                    if (*_t2 > 10) {
                        _t8 = *_t2;
                        break
                    }
                };
                if (self is Institution) {
                    _t8 = *&self.id;
                    break
                };
                _t8 = 0;
                break
            };
            _t3 = 1 + _t8;
            break
        };
        _t3
    }

Metadata

Metadata

Assignees

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions