-
Notifications
You must be signed in to change notification settings - Fork 75
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
fix: 修复load .wasm文件对importObject的处理 #1705
base: master
Are you sure you want to change the base?
Changes from 4 commits
8daa5bb
74048e2
76dc555
9400f58
49b470e
d9bb9bc
d0aea67
1a31062
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -1,9 +1,14 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
use std::collections::HashMap; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
use std::fs::File; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
use std::io::Read; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
use std::sync::Arc; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
use anyhow; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
use wasmparser::{Import, Parser, Payload}; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
use crate::ast::file::{Content, JsContent}; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
use crate::compiler::Context; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
use crate::plugin::Plugin; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
use crate::plugin::{Plugin, PluginLoadParam}; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
pub struct WasmRuntimePlugin {} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -27,4 +32,88 @@ impl Plugin for WasmRuntimePlugin { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Ok(vec![]) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
fn load( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
&self, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
param: &PluginLoadParam, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
_context: &Arc<Context>, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
) -> anyhow::Result<Option<Content>> { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
let file = param.file; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if file.path.to_string_lossy().ends_with(".wasm") { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
let final_file_name = format!( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
"{}.{}.{}", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
file.get_file_stem(), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
file.get_content_hash()?, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
file.extname | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
let origin_path = file.pathname.to_string_lossy().to_string(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
_context.emit_assets(origin_path, final_file_name.clone()); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
let mut buffer = Vec::new(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
File::open(&file.path)?.read_to_end(&mut buffer)?; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// Parse wasm file to get imports | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
let mut import_objs_map: HashMap<&str, Vec<String>> = HashMap::new(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
for payload in Parser::new(0).parse_all(&buffer) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if let Ok(Payload::ImportSection(imports)) = payload { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
for import in imports { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if let Ok(Import { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
module, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
name, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
ty: _, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}) = import | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if let Some(import_obj) = import_objs_map.get_mut(module) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import_obj.push(name.to_string()); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} else { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import_objs_map.insert(module, vec![name.to_string()]); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion 优化WASM导入解析的错误处理 当前代码在处理导入时的错误处理可以更加完善。建议: - if let Ok(Import { module, name, ty: _ }) = import
+ match import {
+ Ok(Import { module, name, ty: _ }) => {
+ if let Some(import_obj) = import_objs_map.get_mut(module) {
+ import_obj.push(name.to_string());
+ } else {
+ import_objs_map.insert(module, vec![name.to_string()]);
+ }
+ },
+ Err(e) => log::warn!("解析WASM导入时出错: {}", e)
+ } 📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
let mut js_imports_str = String::new(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
let mut import_objs_str = String::new(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
for (index, (key, value)) in import_objs_map.iter().enumerate() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
js_imports_str.push_str(&format!( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
"import * as module{module_idx} from \"{module}\";\n", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
module_idx = index, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
module = key | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
)); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import_objs_str.push_str(&format!( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
"\"{module}\": {{ {names} }}", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
module = key, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
names = value | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
.iter() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
.map(|name| format!("\"{}\": module{}[\"{}\"]", name, index, name)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
.collect::<Vec<String>>() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
.join(", ") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
)); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
let mut content = String::new(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
content.push_str(&js_imports_str); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if import_objs_str.is_empty() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
content.push_str(&format!( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
"module.exports = require._interopreRequireWasm(exports, \"{}\")", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
final_file_name | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
)); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} else { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
content.push_str(&format!( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
"module.exports = require._interopreRequireWasm(exports, \"{}\", {{{}}})", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+106
to
+111
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 检查 在生成的JavaScript代码中,使用了 如果存在拼写错误,建议修改如下: - "module.exports = require._interopreRequireWasm(exports, \"{}\")",
+ "module.exports = require._interopRequireWasm(exports, \"{}\")",
💡 Codebase verification 函数名称拼写错误 在
🔗 Analysis chain验证 请确认 运行以下脚本以检查该函数的定义: 🏁 Scripts executedThe following scripts were executed for the analysis: Script: #!/bin/bash
# 描述:在代码库中搜索`_interopRequireWasm`函数的定义
# 测试:在所有JavaScript文件中查找`_interopRequireWasm`的定义,期望能够找到函数定义的位置。
rg '_interopRequireWasm' --type js
Length of output: 34 Script: #!/bin/bash
# 扩大搜索范围,不限制文件类型
rg -l "_interopreRequireWasm"
# 搜索可能的runtime或helper文件
fd -e js -e ts "runtime|helper" --type f
# 检查项目根目录下的配置文件,查找相关依赖或配置
fd "package.json|webpack|rollup|vite" --max-depth 2 --type f --exec cat {}
Length of output: 3456 Script: #!/bin/bash
# 检查wasm_runtime.js文件中的_interopreRequireWasm函数定义
cat crates/mako/src/plugins/wasm_runtime/wasm_runtime.js
# 检查其他可能引用此函数的文件内容
cat crates/mako/src/build/load.rs
Length of output: 12053 |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
final_file_name, import_objs_str | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
)); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return Ok(Some(Content::Js(JsContent { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
content, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
..Default::default() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}))); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Ok(None) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
/* tslint:disable */ | ||
/* eslint-disable */ | ||
/** | ||
*/ | ||
export function greet(): void; | ||
/** | ||
* @param {string} name | ||
*/ | ||
export function greet2(name: string): void; | ||
/** | ||
* @param {number} a | ||
* @param {number} b | ||
* @returns {number} | ||
*/ | ||
export function minus(a: number, b: number): number; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
import { __wbg_set_wasm } from './index_bg.js'; | ||
import * as wasm from './index_bg.wasm'; | ||
__wbg_set_wasm(wasm); | ||
export * from './index_bg.js'; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
let wasm; | ||
export function __wbg_set_wasm(val) { | ||
wasm = val; | ||
} | ||
|
||
const lTextDecoder = | ||
typeof TextDecoder === 'undefined' | ||
? (0, module.require)('util').TextDecoder | ||
: TextDecoder; | ||
|
||
let cachedTextDecoder = new lTextDecoder('utf-8', { | ||
ignoreBOM: true, | ||
fatal: true, | ||
}); | ||
|
||
cachedTextDecoder.decode(); | ||
|
||
let cachedUint8ArrayMemory0 = null; | ||
|
||
function getUint8ArrayMemory0() { | ||
if ( | ||
cachedUint8ArrayMemory0 === null || | ||
cachedUint8ArrayMemory0.byteLength === 0 | ||
) { | ||
cachedUint8ArrayMemory0 = new Uint8Array(wasm.memory.buffer); | ||
} | ||
return cachedUint8ArrayMemory0; | ||
} | ||
Comment on lines
+21
to
+28
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion 确保内存视图在内存增长时更新 在 |
||
|
||
function getStringFromWasm0(ptr, len) { | ||
ptr = ptr >>> 0; | ||
return cachedTextDecoder.decode( | ||
getUint8ArrayMemory0().subarray(ptr, ptr + len), | ||
); | ||
} | ||
/** | ||
*/ | ||
export function greet() { | ||
wasm.greet(); | ||
} | ||
|
||
let WASM_VECTOR_LEN = 0; | ||
|
||
const lTextEncoder = | ||
typeof TextEncoder === 'undefined' | ||
? (0, module.require)('util').TextEncoder | ||
: TextEncoder; | ||
|
||
let cachedTextEncoder = new lTextEncoder('utf-8'); | ||
|
||
const encodeString = | ||
typeof cachedTextEncoder.encodeInto === 'function' | ||
? function (arg, view) { | ||
return cachedTextEncoder.encodeInto(arg, view); | ||
} | ||
: function (arg, view) { | ||
const buf = cachedTextEncoder.encode(arg); | ||
view.set(buf); | ||
return { | ||
read: arg.length, | ||
written: buf.length, | ||
}; | ||
}; | ||
|
||
function passStringToWasm0(arg, malloc, realloc) { | ||
if (realloc === undefined) { | ||
const buf = cachedTextEncoder.encode(arg); | ||
const ptr = malloc(buf.length, 1) >>> 0; | ||
getUint8ArrayMemory0() | ||
.subarray(ptr, ptr + buf.length) | ||
.set(buf); | ||
WASM_VECTOR_LEN = buf.length; | ||
return ptr; | ||
} | ||
|
||
let len = arg.length; | ||
let ptr = malloc(len, 1) >>> 0; | ||
|
||
const mem = getUint8ArrayMemory0(); | ||
|
||
let offset = 0; | ||
|
||
for (; offset < len; offset++) { | ||
const code = arg.charCodeAt(offset); | ||
if (code > 0x7f) break; | ||
mem[ptr + offset] = code; | ||
} | ||
|
||
if (offset !== len) { | ||
if (offset !== 0) { | ||
arg = arg.slice(offset); | ||
} | ||
ptr = realloc(ptr, len, (len = offset + arg.length * 3), 1) >>> 0; | ||
const view = getUint8ArrayMemory0().subarray(ptr + offset, ptr + len); | ||
const ret = encodeString(arg, view); | ||
|
||
offset += ret.written; | ||
ptr = realloc(ptr, len, offset, 1) >>> 0; | ||
Comment on lines
+94
to
+98
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 更新内存指针以防止访问错误 在内存重分配后, |
||
} | ||
|
||
WASM_VECTOR_LEN = offset; | ||
return ptr; | ||
} | ||
Comment on lines
+65
to
+103
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 优化字符串传递到 WASM 的实现
|
||
/** | ||
* @param {string} name | ||
*/ | ||
export function greet2(name) { | ||
const ptr0 = passStringToWasm0( | ||
name, | ||
wasm.__wbindgen_malloc, | ||
wasm.__wbindgen_realloc, | ||
); | ||
const len0 = WASM_VECTOR_LEN; | ||
wasm.greet2(ptr0, len0); | ||
} | ||
|
||
/** | ||
* @param {number} a | ||
* @param {number} b | ||
* @returns {number} | ||
*/ | ||
export function minus(a, b) { | ||
const ret = wasm.minus(a, b); | ||
return ret; | ||
} | ||
|
||
export function __wbg_alert_f837f172b2a24942(arg0, arg1) { | ||
alert(getStringFromWasm0(arg0, arg1)); | ||
} | ||
|
||
export function __wbg_prompt_ec584a06a1c7c28b(arg0, arg1) { | ||
prompt(getStringFromWasm0(arg0, arg1)); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
/* tslint:disable */ | ||
/* eslint-disable */ | ||
export const memory: WebAssembly.Memory; | ||
export function greet2(a: number, b: number): void; | ||
export function minus(a: number, b: number): number; | ||
export function greet(): void; | ||
export function __wbindgen_malloc(a: number, b: number): number; | ||
export function __wbindgen_realloc( | ||
a: number, | ||
b: number, | ||
c: number, | ||
d: number, | ||
): number; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codebase verification
建议更新 wasmparser 依赖版本
当前使用的版本 (0.207.0) 已过时。最新的稳定版本是 0.220.0,建议:
wasmparser = "^0.220.0"
安全检查显示该包没有已知的安全漏洞。
🔗 Analysis chain
建议检查 wasmparser 的版本选择
建议考虑以下几点:
^0.207.0
)来自动接收补丁版本的更新运行以下脚本来验证版本信息:
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
Length of output: 439