clone wasm store engine (#3542)
This resolves https://github.com/tree-sitter/tree-sitter/issues/3454. This brings the usage of wasmtime::Engine in line with how wasmtime intends it to be used. All wasmtime functions that receive an Engine always receive an `&Engine`, never an owned `Engine`. They are always responsible for cloning the reference if they need it. This brings the usage of wasmtime::Engine in line with how TSParser treats TSLanguages: when setting a language to the parser, the parser is responsible for cloning the reference to the TSLanguage. It is counterintuitive for TSParser to have different behavior when receiving wasmtime_engine_t. C API users also expect this behavior, see "Memory Management" [here](https://docs.wasmtime.dev/c-api/wasm_8h.html). Talking about the C API: without this change, failing to clone the `wasmtime_engine_t` (which, again, is never something API users need to do in wasmtime) and then reusing the engine in multiple TSLanguages results in a use after free. With this change, failing to call `wasm_engine_delete` on your owned Engine results in a memory leak. Memory leaks are safer than use-after-free.
This commit is contained in:
parent
5364ac4ea8
commit
b5e4ef6d9a
5 changed files with 20 additions and 21 deletions
|
|
@ -592,9 +592,9 @@ fn run() -> Result<()> {
|
|||
if parse_options.wasm {
|
||||
let engine = tree_sitter::wasmtime::Engine::default();
|
||||
parser
|
||||
.set_wasm_store(tree_sitter::WasmStore::new(engine.clone()).unwrap())
|
||||
.set_wasm_store(tree_sitter::WasmStore::new(&engine).unwrap())
|
||||
.unwrap();
|
||||
loader.use_wasm(engine);
|
||||
loader.use_wasm(&engine);
|
||||
}
|
||||
|
||||
let timeout = parse_options.timeout.unwrap_or_default();
|
||||
|
|
@ -690,9 +690,9 @@ fn run() -> Result<()> {
|
|||
if test_options.wasm {
|
||||
let engine = tree_sitter::wasmtime::Engine::default();
|
||||
parser
|
||||
.set_wasm_store(tree_sitter::WasmStore::new(engine.clone()).unwrap())
|
||||
.set_wasm_store(tree_sitter::WasmStore::new(&engine).unwrap())
|
||||
.unwrap();
|
||||
loader.use_wasm(engine);
|
||||
loader.use_wasm(&engine);
|
||||
}
|
||||
|
||||
let languages = loader.languages_at_path(¤t_dir)?;
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ fn test_wasm_stdlib_symbols() {
|
|||
#[test]
|
||||
fn test_load_wasm_ruby_language() {
|
||||
allocations::record(|| {
|
||||
let mut store = WasmStore::new(ENGINE.clone()).unwrap();
|
||||
let mut store = WasmStore::new(&ENGINE).unwrap();
|
||||
let mut parser = Parser::new();
|
||||
let wasm = fs::read(WASM_DIR.join("tree-sitter-ruby.wasm")).unwrap();
|
||||
let language = store.load_language("ruby", &wasm).unwrap();
|
||||
|
|
@ -50,7 +50,7 @@ fn test_load_wasm_ruby_language() {
|
|||
#[test]
|
||||
fn test_load_wasm_html_language() {
|
||||
allocations::record(|| {
|
||||
let mut store = WasmStore::new(ENGINE.clone()).unwrap();
|
||||
let mut store = WasmStore::new(&ENGINE).unwrap();
|
||||
let mut parser = Parser::new();
|
||||
let wasm = fs::read(WASM_DIR.join("tree-sitter-html.wasm")).unwrap();
|
||||
let language = store.load_language("html", &wasm).unwrap();
|
||||
|
|
@ -69,7 +69,7 @@ fn test_load_wasm_html_language() {
|
|||
#[test]
|
||||
fn test_load_wasm_rust_language() {
|
||||
allocations::record(|| {
|
||||
let mut store = WasmStore::new(ENGINE.clone()).unwrap();
|
||||
let mut store = WasmStore::new(&ENGINE).unwrap();
|
||||
let mut parser = Parser::new();
|
||||
let wasm = fs::read(WASM_DIR.join("tree-sitter-rust.wasm")).unwrap();
|
||||
let language = store.load_language("rust", &wasm).unwrap();
|
||||
|
|
@ -83,7 +83,7 @@ fn test_load_wasm_rust_language() {
|
|||
#[test]
|
||||
fn test_load_wasm_javascript_language() {
|
||||
allocations::record(|| {
|
||||
let mut store = WasmStore::new(ENGINE.clone()).unwrap();
|
||||
let mut store = WasmStore::new(&ENGINE).unwrap();
|
||||
let mut parser = Parser::new();
|
||||
let wasm = fs::read(WASM_DIR.join("tree-sitter-javascript.wasm")).unwrap();
|
||||
let language = store.load_language("javascript", &wasm).unwrap();
|
||||
|
|
@ -97,7 +97,7 @@ fn test_load_wasm_javascript_language() {
|
|||
#[test]
|
||||
fn test_load_multiple_wasm_languages() {
|
||||
allocations::record(|| {
|
||||
let mut store = WasmStore::new(ENGINE.clone()).unwrap();
|
||||
let mut store = WasmStore::new(&ENGINE).unwrap();
|
||||
let mut parser = Parser::new();
|
||||
|
||||
let wasm_cpp = fs::read(WASM_DIR.join("tree-sitter-cpp.wasm")).unwrap();
|
||||
|
|
@ -113,7 +113,7 @@ fn test_load_multiple_wasm_languages() {
|
|||
|
||||
let mut parser2 = Parser::new();
|
||||
parser2
|
||||
.set_wasm_store(WasmStore::new(ENGINE.clone()).unwrap())
|
||||
.set_wasm_store(WasmStore::new(&ENGINE).unwrap())
|
||||
.unwrap();
|
||||
let mut query_cursor = QueryCursor::new();
|
||||
|
||||
|
|
@ -174,7 +174,7 @@ fn test_load_multiple_wasm_languages() {
|
|||
#[test]
|
||||
fn test_load_and_reload_wasm_language() {
|
||||
allocations::record(|| {
|
||||
let mut store = WasmStore::new(ENGINE.clone()).unwrap();
|
||||
let mut store = WasmStore::new(&ENGINE).unwrap();
|
||||
|
||||
let wasm_rust = fs::read(WASM_DIR.join("tree-sitter-rust.wasm")).unwrap();
|
||||
let wasm_typescript = fs::read(WASM_DIR.join("tree-sitter-typescript.wasm")).unwrap();
|
||||
|
|
@ -199,18 +199,18 @@ fn test_load_and_reload_wasm_language() {
|
|||
#[test]
|
||||
fn test_reset_wasm_store() {
|
||||
allocations::record(|| {
|
||||
let mut language_store = WasmStore::new(ENGINE.clone()).unwrap();
|
||||
let mut language_store = WasmStore::new(&ENGINE).unwrap();
|
||||
let wasm = fs::read(WASM_DIR.join("tree-sitter-rust.wasm")).unwrap();
|
||||
let language = language_store.load_language("rust", &wasm).unwrap();
|
||||
|
||||
let mut parser = Parser::new();
|
||||
let parser_store = WasmStore::new(ENGINE.clone()).unwrap();
|
||||
let parser_store = WasmStore::new(&ENGINE).unwrap();
|
||||
parser.set_wasm_store(parser_store).unwrap();
|
||||
parser.set_language(&language).unwrap();
|
||||
let tree = parser.parse("fn main() {}", None).unwrap();
|
||||
assert_eq!(tree.root_node().to_sexp(), "(source_file (function_item name: (identifier) parameters: (parameters) body: (block)))");
|
||||
|
||||
let parser_store = WasmStore::new(ENGINE.clone()).unwrap();
|
||||
let parser_store = WasmStore::new(&ENGINE).unwrap();
|
||||
parser.set_wasm_store(parser_store).unwrap();
|
||||
let tree = parser.parse("fn main() {}", None).unwrap();
|
||||
assert_eq!(tree.root_node().to_sexp(), "(source_file (function_item name: (identifier) parameters: (parameters) body: (block)))");
|
||||
|
|
@ -220,7 +220,7 @@ fn test_reset_wasm_store() {
|
|||
#[test]
|
||||
fn test_load_wasm_errors() {
|
||||
allocations::record(|| {
|
||||
let mut store = WasmStore::new(ENGINE.clone()).unwrap();
|
||||
let mut store = WasmStore::new(&ENGINE).unwrap();
|
||||
let wasm = fs::read(WASM_DIR.join("tree-sitter-rust.wasm")).unwrap();
|
||||
|
||||
let bad_wasm = &wasm[1..];
|
||||
|
|
@ -252,7 +252,7 @@ fn test_load_wasm_errors() {
|
|||
#[test]
|
||||
fn test_wasm_oom() {
|
||||
allocations::record(|| {
|
||||
let mut store = WasmStore::new(ENGINE.clone()).unwrap();
|
||||
let mut store = WasmStore::new(&ENGINE).unwrap();
|
||||
let mut parser = Parser::new();
|
||||
let wasm = fs::read(WASM_DIR.join("tree-sitter-html.wasm")).unwrap();
|
||||
let language = store.load_language("html", &wasm).unwrap();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue