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

[Feature]: virtual table for Item Class #1429

Closed
KobeBryant114514 opened this issue Jan 10, 2024 · 6 comments
Closed

[Feature]: virtual table for Item Class #1429

KobeBryant114514 opened this issue Jan 10, 2024 · 6 comments
Labels
enhancement Intended improvement or added functionality priority: medium Needs attention
Milestone

Comments

@KobeBryant114514
Copy link

KobeBryant114514 commented Jan 10, 2024

Is your feature request related to a problem? Please describe.

经过几天研究,把Item注册逻辑基本搞清楚了,但是我需要完整的Item类的虚表,不能带有__unk__函数,不能有错误函数,否则无法继承Item类。
我不知道如何修复Item类的虚表。希望能将虚表修复,或者提供一个导出或修复的方法我去自行修复。

Describe the solution you'd like

修复好Item类的全部虚表。
或者提供一个导出或修复虚表的方法我去自行解决。
已知有16个__unk__函数需要修复
以及还有两个函数虽然不是__unk__,但是参数应该是错误的,因为编译器报无法访问的符号,分别是
virtual bool calculatePlacePos(class ItemStackBase& instance, class Actor& entity, uchar& face, class BlockPos& pos) const;
virtual int getAnimationFrameFor(class Mob* holder, bool asItemEntity, class ItemStack const* item, bool shouldAnimate) const;

Describe alternatives you've considered

No response

Additional context

No response

@KawaiiNahida
Copy link
Member

1 unk的函数理论上只靠Windows版本数据没有办法知道具体是什么的 建议看看linux版本也许有点机会
2 如果编译器没有生成构造函数 是不会尝试link虚函数的,请确认你确实有需要这样的构造函数,也可以通过手动拷贝虚表的方法获得可更改的虚表
3 hg生成的一切函数理论上都是可靠的

@KobeBryant114514
Copy link
Author

KobeBryant114514 commented Jan 11, 2024

1 unk的函数理论上只靠Windows版本数据没有办法知道具体是什么的 建议看看linux版本也许有点机会 2 如果编译器没有生成构造函数 是不会尝试link虚函数的,请确认你确实有需要这样的构造函数,也可以通过手动拷贝虚表的方法获得可更改的虚表 3 hg生成的一切函数理论上都是可靠的

  1. 正是需要生成构造函数,需要继承构造并且注册Item,所以说才需要虚表。这个需求是确实存在的。
  2. 部分函数参数可能有问题,比如说我提到的两个有问题的函数,第二个给的是
    virtual int getAnimationFrameFor(class Mob*, bool, class ItemStack const*, bool) const;
    实际上应该是
    virtual int getAnimationFrameFor(class Mob*, bool, class ItemStack const*, const bool) const;
    第一个我不知道错在哪里

@quizhizhe
Copy link
Contributor

getAnimationFrameFor其实是没错的,编译器说没有找到的符号可能是虚表没有补全的原因。至于item的虚表,虚表的维护其实比较麻烦,缺的都是手动补的,所以没有必要的情况下,我们是不会手动去补全虚表的,如果都要虚表的补全,后续我们的维护成本会非常高。linux版有较全的虚表,我建议是,你可以linux版与win版结合来补全虚表。

@KawaiiNahida
Copy link
Member

virtual int getAnimationFrameFor(class Mob*, bool, class ItemStack const*, bool) const;
virtual int getAnimationFrameFor(class Mob*, bool, class ItemStack const*, const bool) const;

对于abi来说这个bool加上const是没有任何意义的,并且msvc-undname和llvm-undname对该函数签名?getAnimationFrameFor@Item@@UEBAHPEAVMob@@_NPEBVItemStack@@_N@Z的解析看不到const的标记,我猜是msvc的一些奇怪行为,可能得每次手动修正

@KawaiiNahida
Copy link
Member

此外HeaderGenerator会在寒假期间逐步重构并添加跨版本虚表确定的功能,以准确的确认被优化的函数在虚表中的顺序,在此之前提供一种手动构造的方式构造类型的思路,以满足测试需要,后续LL更新后也可以低成本的切换为正常的cpp写法

class BaseClass {
    virtual void func1();
    virtual void func2();
    virtual void func3();
    virtual void func4();
    virtual void func5();
};

class NewClass : public BaseClass {
    // 以下的函数是将要重写Base函数的函数,但是由于msvc的一些怪异行为,
    // 手动实现继承重写时,必须声明为非virtual函数,并且不得和已有virtual函数有相同名称
    void v_func1();
    void v_func2();
    void v_func3();
    void v_func4();
    void v_func5();

    static NewClass* CreateManually() {
        struct NewClass_c {
            uint64_t* vftable;
            char      filler[16]; // filler for other members
        };
        NewClass_c* instance_c = new NewClass_c();
        NewClass* instalce = instance_c;
        // copy vtable
        constexpr size_t vftableSize = 5;
        uint64_t* vftableSrc  = resolveSymbol("??_7NewClass@@6B@");
        uint64_t* vftableDst  = new uint64_t[vftableSize];
        memcpy(vftableDst, vftableSrc, sizeof(uint64_t) * vftableSize);
        // set override functions
        vftableDst[0] = (uint64_t)&NewClass::v_func1;
        vftableDst[1] = (uint64_t)&NewClass::v_func2;
        vftableDst[2] = (uint64_t)&NewClass::v_func3;
        vftableDst[3] = (uint64_t)&NewClass::v_func4;
        vftableDst[4] = (uint64_t)&NewClass::v_func5;
        // set vtable
        instance_c->vftable = vftableDst;

        // initialize other members
        // ...

        return instance;
    }
};

@RimuruChan RimuruChan added this to the 1.0.0 milestone Jan 15, 2024
@Dofes Dofes added enhancement Intended improvement or added functionality priority: medium Needs attention status: in progress Currently being worked on labels Feb 8, 2024
@Redbeanw44602
Copy link
Contributor

d257c51
After 0.8.0, the virtual function table of the Linux version of BDS has been used for repair.

@RimuruChan RimuruChan removed the status: in progress Currently being worked on label Mar 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Intended improvement or added functionality priority: medium Needs attention
Development

No branches or pull requests

6 participants