如何解决为什么在生成返回字符串的函数时wasm-opt在wasm-pack构建中失败?
我正在这里浏览有关Conway生活游戏的Rust wasm教程:https://rustwasm.github.io/docs/book/game-of-life/implementing.html
文件中最简单的功能之一称为Universe.render
(这是用于呈现表示游戏状态的字符串的功能)。运行wasm-pack build
时会导致错误:
Fatal: error in validating input
Error: Failed to execute `wasm-opt`: exited with exit code: 1
full command: "/home/vaer/.cache/.wasm-pack/wasm-opt-4d7a65327e9363b7/wasm-opt" "/home/vaer/src/learn-rust/wasm-game-of-life/pkg/wasm_game_of_life_bg.wasm" "-o" "/home/vaer/src/learn-rust/wasm-game-of-life/pkg/wasm_game_of_life_bg.wasm-opt.wasm" "-O"
To disable `wasm-opt`,add `wasm-opt = false` to your package Metadata in your `Cargo.toml`.
如果我删除该功能,则代码将正确构建。如果我将其替换为以下函数,则构建将失败,并显示相同的错误:
pub fn wtf() -> String {
String::from("wtf")
}
以下是我的全部代码:
mod utils;
use wasm_bindgen::prelude::*;
// When the `wee_alloc` feature is enabled,use `wee_alloc` as the global
// allocator.
#[cfg(feature = "wee_alloc")]
#[global_allocator]
static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
// Begin game of life impl
use std::fmt;
#[wasm_bindgen]
#[repr(u8)]
#[derive(Clone,copy,Debug,PartialEq,Eq)]
pub enum Cell {
Dead = 0,Alive = 1,}
#[wasm_bindgen]
pub struct Universe {
width: u32,height: u32,cells: Vec<Cell>,}
impl fmt::display for Universe {
fn fmt(&self,f: &mut fmt::Formatter) -> fmt::Result {
for line in self.cells.as_slice().chunks(self.width as usize) {
for &cell in line {
let symbol = if cell == Cell::Dead { '◻' } else { '◼' };
write!(f,"{}",symbol)?;
}
write!(f,"\n")?;
}
Ok(())
}
}
impl Universe {
fn get_index(&self,row: u32,column: u32) -> usize {
(row * self.width + column) as usize
}
fn live_neighbor_count(&self,column: u32) -> u8 {
let mut count = 0;
for delta_row in [self.height - 1,1].iter().cloned() {
for delta_col in [self.width - 1,1].iter().cloned() {
if delta_row == 0 && delta_col == 0 {
continue;
}
let neighbor_row = (row + delta_row) % self.height;
let neighbor_col = (column + delta_col) % self.width;
let idx = self.get_index(neighbor_row,neighbor_col);
count += self.cells[idx] as u8;
}
}
count
}
}
/// Public methods,exported to JavaScript.
#[wasm_bindgen]
impl Universe {
pub fn tick(&mut self) {
let mut next = self.cells.clone();
for row in 0..self.height {
for col in 0..self.width {
let idx = self.get_index(row,col);
let cell = self.cells[idx];
let live_neighbors = self.live_neighbor_count(row,col);
let next_cell = match (cell,live_neighbors) {
// Rule 1: Any live cell with fewer than two live neighbours
// dies,as if caused by underpopulation.
(Cell::Alive,x) if x < 2 => Cell::Dead,// Rule 2: Any live cell with two or three live neighbours
// lives on to the next generation.
(Cell::Alive,2) | (Cell::Alive,3) => Cell::Alive,// Rule 3: Any live cell with more than three live
// neighbours dies,as if by overpopulation.
(Cell::Alive,x) if x > 3 => Cell::Dead,// Rule 4: Any dead cell with exactly three live neighbours
// becomes a live cell,as if by reproduction.
(Cell::Dead,// All other cells remain in the same state.
(otherwise,_) => otherwise,};
next[idx] = next_cell;
}
}
self.cells = next;
}
pub fn new() -> Universe {
let width = 64;
let height = 64;
let cells = (0..width * height)
.map(|i| {
if i % 2 == 0 || i % 7 == 0 {
Cell::Alive
} else {
Cell::Dead
}
})
.collect();
Universe {
width,height,cells,}
}
pub fn render(&self) -> String {
self.to_string()
}
}
仅删除此文件底部的render
函数将使构建成功。用返回render
的任何函数替换String
函数会导致构建失败。为什么?
解决方法
事实证明这不是预期的行为;相反,它是wasm-pack
的错误:https://github.com/rustwasm/wasm-pack/issues/886
现在可以通过将以下内容添加到项目的cargo.toml
中来解决该问题:
[package.metadata.wasm-pack.profile.release]
wasm-opt = ["-Oz","--enable-mutable-globals"]
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。