如何在 Rust WebAssembly 中填充 performance.now
How to polyfill performance.now in Rust WebAssembly
我正在尝试在 cloudflare workers webassembly 运行时中使用 jwt_simple 库。按照链接文档中的基本示例,在执行 key.authenticate(claims)?
之前一切正常,此时在我的终端 运行 wrangler:
中生成以下堆栈跟踪
ReferenceError: performance is not defined
at __wbg_now_63f780680ee9cc56 (./index_bg.mjs:331:15)
at wasm://wasm/001926f2:wasm-function[264]:0x252a9
at wasm://wasm/001926f2:wasm-function[409]:0x2925d
at wasm://wasm/001926f2:wasm-function[167]:0x1fb99
at wasm://wasm/001926f2:wasm-function[410]:0x292b9
at wasm://wasm/001926f2:wasm-function[284]:0x25ea0
at wasm://wasm/001926f2:wasm-function[132]:0x1cbd9
at wasm://wasm/001926f2:wasm-function[38]:0x9bbc
at wasm://wasm/001926f2:wasm-function[143]:0x1dc3b
at wasm://wasm/001926f2:wasm-function[106]:0x19ccb at line 330, col 13
我怀疑这是因为当 key.authenticate
试图验证 jwt 仍然有效时它调用 performance.now
,根据 this forum post is not provided by cloudflare workers to prevent timing attacks. I don't fully understand how webassembly works, but I do know that I can polyfill performance.now
in javascript as is done here.
如何在 webassembly 环境中使用这个 polyfill?
在NodeJS运行环境中使用perf_hooks
。
import { performance } from 'perf_hooks'
否则声明一个具有存根函数的全局performance
对象:
const performance = {
now: () => Date.now(), // milliseconds used for timing diffs
}
在文件生成后替换 performace.now()
的所有实例:
$ sed -i '' 's/performance.now()/Date.now()/' index_bg.mjs
我最终使用 js_sys Reflect 库通过全局范围将 Date.now
分配给 performance.now
。
use js_sys::{global, Reflect, Object};
pub fn polyfill() {
let global = global();
//let performance = {}
let performance = Object::new();
//performance.now = global.Date.now
Reflect::set(
&performance,
&"now".into(),
&Reflect::get(
&Reflect::get(&global, &"Date".into()).unwrap(),
&"now".into()
).unwrap()
).unwrap();
//global.performance = performance
Reflect::set(
&global,
&"performance".into(),
&performance
).unwrap();
}
然后确保在需要之前调用 polyfill performance.now
我正在尝试在 cloudflare workers webassembly 运行时中使用 jwt_simple 库。按照链接文档中的基本示例,在执行 key.authenticate(claims)?
之前一切正常,此时在我的终端 运行 wrangler:
ReferenceError: performance is not defined
at __wbg_now_63f780680ee9cc56 (./index_bg.mjs:331:15)
at wasm://wasm/001926f2:wasm-function[264]:0x252a9
at wasm://wasm/001926f2:wasm-function[409]:0x2925d
at wasm://wasm/001926f2:wasm-function[167]:0x1fb99
at wasm://wasm/001926f2:wasm-function[410]:0x292b9
at wasm://wasm/001926f2:wasm-function[284]:0x25ea0
at wasm://wasm/001926f2:wasm-function[132]:0x1cbd9
at wasm://wasm/001926f2:wasm-function[38]:0x9bbc
at wasm://wasm/001926f2:wasm-function[143]:0x1dc3b
at wasm://wasm/001926f2:wasm-function[106]:0x19ccb at line 330, col 13
我怀疑这是因为当 key.authenticate
试图验证 jwt 仍然有效时它调用 performance.now
,根据 this forum post is not provided by cloudflare workers to prevent timing attacks. I don't fully understand how webassembly works, but I do know that I can polyfill performance.now
in javascript as is done here.
如何在 webassembly 环境中使用这个 polyfill?
在NodeJS运行环境中使用perf_hooks
。
import { performance } from 'perf_hooks'
否则声明一个具有存根函数的全局performance
对象:
const performance = {
now: () => Date.now(), // milliseconds used for timing diffs
}
在文件生成后替换 performace.now()
的所有实例:
$ sed -i '' 's/performance.now()/Date.now()/' index_bg.mjs
我最终使用 js_sys Reflect 库通过全局范围将 Date.now
分配给 performance.now
。
use js_sys::{global, Reflect, Object};
pub fn polyfill() {
let global = global();
//let performance = {}
let performance = Object::new();
//performance.now = global.Date.now
Reflect::set(
&performance,
&"now".into(),
&Reflect::get(
&Reflect::get(&global, &"Date".into()).unwrap(),
&"now".into()
).unwrap()
).unwrap();
//global.performance = performance
Reflect::set(
&global,
&"performance".into(),
&performance
).unwrap();
}
然后确保在需要之前调用 polyfill performance.now