代码之家  ›  专栏  ›  技术社区  ›  synchronizer

WASM热重加载实验:揭穿假设,以及如何指定数据节在哪里?

  •  0
  • synchronizer  · 技术社区  · 6 年前

    首先,为了避免让这看起来像XYZ问题,我想给出一些上下文(注意,我没有使用Emscripten):

    我想看看我是否可以实现一个热加载的形式,以C++编写的WASM程序,在Web上托管。为了做到这一点,我想拥有一段我称之为“世界之国”的记忆(对任何观看过手工英雄的人来说( https://handmadehero.org/

    struct State {
    // put everything here
    } state;
    

    通常,对于具有平台层的完全C++程序,您将在平台侧分配此结构,并通过代码的可重新加载/DLL/DyLIB部分中的函数指针向该内存提供指针。可重新加载的代码将所有的东西放入这个持久的内存中,所以如果代码需要被重新编译和重新加载,所有的状态都将继续存在,因为内存被分配在程序未被重新加载的部分。据我所知,这在华盛顿是不可能的。 首先,我必须使用WebAssembly.Memory的假设正确吗?--或者我可以在js中分配一个uint8array,并将其用于我的持久状态,与程序内存分离吗?如果是的话,是不是慢了点?

    因此,只要我不使用像WASI这样的动态分配器,而是使用我可以控制的推送分配器,这就可以工作。(我认为这是因为,假设我使用malloc获取内存地址并重新加载——malloc的内部状态将重新加载,并认为所有堆内存在不可用时都可用,因此将来的分配可能会破坏以前的分配。) 在重新加载时,我可以先将结构复制到JS端的临时缓冲区中,重新加载,从Wasm获得结构的内存位置(我将要求它存在),并将保存的内存从JS复制回位置。

    但是,如果我使用指针,这就不一样了,因为如果我更改程序(这就是要点) __data_end 可能会改变,这会抵消所有的地址!我检查了这里的链接器标志 https://lld.llvm.org/WebAssembly.html 下面是一个很好的页面,可以帮助我们可视化Wasm内存: https://dassur.ma/things/c-to-webassembly/

    如果你需要更多的细节,请告诉我。我以前在C语言中做过类似的事情,我提到过,这是一种常见的快速迭代游戏开发技术。基本上我是想在Wasm中重现它。

    编辑:显然您可以直接从另一个模块调用Wasm函数。首先,你是怎么做的,其次,访问另一个模块的内存会有什么性能特征?

    https://webassembly.org/docs/dynamic-linking/

    0 回复  |  直到 6 年前
        1
  •  0
  •   ColinE    6 年前

    WebAssembly模块在三个不同的位置保存变量状态:

    • 线性存储器
    • 与执行堆栈关联的局部变量
    • 全局变量

    如果我想实现这一点,我会在WebAssembly中创建自己的状态机,将其存储在线性内存中的已知位置。

        2
  •  0
  •   Andreas Rossberg    6 年前

    Wasm被组织成模块,模块定义了四种相关的实体:函数、内存、表、全局。代码在函数中,其他三个表示模块的状态。

    因此,模拟代码交换的一种方法是设置模块,使所有三个状态都在外部创建,并且 进口的 进入模块。这样,您就可以在外部保持它们的活动状态,并在它们可用时将其传递给升级后的模块。(您还需要确保升级后的模块不使用数据/元素段或启动函数,以覆盖预先存在的状态。)

    当然,只有当模块状态的形状在升级之间没有改变时,这才起作用。E、 例如,没有新的全局变量,内存中没有新的数据布局,否则新代码将无法理解旧状态。 那个

    推荐文章