-
Notifications
You must be signed in to change notification settings - Fork 81
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 #1705
base: master
Are you sure you want to change the base?
fix: load wasm #1705
Changes from 2 commits
8daa5bb
74048e2
76dc555
9400f58
49b470e
d9bb9bc
d0aea67
1a31062
24822c4
96c3240
f037029
4511ec6
d9c513d
6b37ba9
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,83 @@ 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.as_path())?.read_to_end(&mut buffer)?; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// Parse wasm file to get imports | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
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 建议改进错误处理和内存管理 当前实现存在以下需要注意的地方:
建议修改如下: - File::open(file.path.as_path())?.read_to_end(&mut buffer)?;
+ File::open(&file.path)
+ .map_err(|e| anyhow::anyhow!("无法打开WASM文件 {}: {}", file.path.display(), e))?
+ .read_to_end(&mut buffer)
+ .map_err(|e| anyhow::anyhow!("读取WASM文件失败: {}", e))?; 对于大文件,可以考虑使用流式处理或设置最大文件大小限制。 📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
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()]); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
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, \"{}\", {{{}}})", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
xusd320 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
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; | ||
} | ||
xusd320 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
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; | ||
xusd320 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
WASM_VECTOR_LEN = offset; | ||
return ptr; | ||
} | ||
xusd320 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
/** | ||
* @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