fitzgen opened Issue #2498:
In https://github.com/bytecodealliance/wasmtime/pull/2497#discussion_r541118846 we added support for generating nested modules, and we generate these modules by concatenating strings of WAT and then passing it to
Module::new
which internally checks for WAT strings and assembles them into Wasm bytes if necessary.We can make this more efficient, improving the number of test cases we fuzz in a given amount of time, by generating Wasm bytes directly via the
wasm-encoder
crate, rather than generating a WAT string. Thewasm-encoder
crate has builder methods that should make it pretty straightforward to translate theWatGenerator
into aWasmGenerator
.If you want to work on this issue, leave a comment, and let me know whatever questions you have!
Info for getting up and running with contributing: https://docs.wasmtime.dev/contributing.html
fitzgen labeled Issue #2498:
In https://github.com/bytecodealliance/wasmtime/pull/2497#discussion_r541118846 we added support for generating nested modules, and we generate these modules by concatenating strings of WAT and then passing it to
Module::new
which internally checks for WAT strings and assembles them into Wasm bytes if necessary.We can make this more efficient, improving the number of test cases we fuzz in a given amount of time, by generating Wasm bytes directly via the
wasm-encoder
crate, rather than generating a WAT string. Thewasm-encoder
crate has builder methods that should make it pretty straightforward to translate theWatGenerator
into aWasmGenerator
.If you want to work on this issue, leave a comment, and let me know whatever questions you have!
Info for getting up and running with contributing: https://docs.wasmtime.dev/contributing.html
fitzgen labeled Issue #2498:
In https://github.com/bytecodealliance/wasmtime/pull/2497#discussion_r541118846 we added support for generating nested modules, and we generate these modules by concatenating strings of WAT and then passing it to
Module::new
which internally checks for WAT strings and assembles them into Wasm bytes if necessary.We can make this more efficient, improving the number of test cases we fuzz in a given amount of time, by generating Wasm bytes directly via the
wasm-encoder
crate, rather than generating a WAT string. Thewasm-encoder
crate has builder methods that should make it pretty straightforward to translate theWatGenerator
into aWasmGenerator
.If you want to work on this issue, leave a comment, and let me know whatever questions you have!
Info for getting up and running with contributing: https://docs.wasmtime.dev/contributing.html
github-actions[bot] commented on Issue #2498:
Subscribe to Label Action
cc @fitzgen
<details>
This issue or pull request has been labeled: "fuzzing"Thus the following users have been cc'd because of the following labels:
- fitzgen: fuzzing
To subscribe or unsubscribe from this label, edit the <code>.github/subscribe-to-label.json</code> configuration file.
Learn more.
</details>
stevenbarragan commented on Issue #2498:
Hi @fitzgen I'd love to start contributing to wasmtime. Let me dive in and try to figure it out. I'll follow in here with questions.
fitzgen commented on Issue #2498:
@stevenbarragan great! One thing to be aware of, that I forgot to mention when filing this issue, is that the WAT text format is a tiny bit higher level than Wasm is at the byte level. For example, WAT allows you to define a function and its signature type at the same time, while wasm bytes require you to pre-declare a function signature type and then reference that type via its index from the function.
That is, this WAT snippet:
(func (param i32 i32) (result i32) ...)
desugars to basically this
wasm-encoder
usage:// Define a function signature in the `Type` section. let mut types = wasm_encoder::TypeSection::new(); types.function( vec![wasm_encoder::ValType::I32, wasm_encoder::ValType::I32], vec![wasm_encoder::ValType::I32], ); // Declare the function's type in the `Function` section. let mut funcs = wasm_encoder::FunctionSection::new(); funcs.func(0); // first type in type section let locals = vec![...]; let mut func = Function::new(locals); // call `func.instruction(...)` to define instructions in this function body... // Add the function body to the `Code` section. let mut code = wasm_encoder::CodeSection::new(); code.function(&body);
Let me know if you aren't sure about how to translate any given snippet of WAT into
wasm-encoder
API calls and I can help you out.
misapprehand commented on Issue #2498:
Hi @fitzgen, I commit PR 2535 about this issue.
But I still have some questions
- I cannot find the functions "dummy_instance" and "dummy_module" is called. So I just run fuzz_target compile and instantiate. But I not sure whether it is the right to check the two functions which use wat generator
- Cannot find how to convert from wasm::ValType::V128 to wasm_encoder::ValType and wasm_encoder::Instruction
See file wencoder_generator.rs , commented by //TODOIn wencoder_generator.rs fn value_to_instruction(ty: &ValType) -> Instruction { match ty { .... ValType::V128 => Instruction::F64Const(0.0), // TODO Do not know the right Instrunction type ... } } fn value_to_value(from: &ValType) -> wasm_encoder::ValType { match from { ... ValType::V128 => wasm_encoder::ValType::FuncRef, // TODO Do not know the right value ... } }
3 . The u32 value 0 in Export Type is right ?
eg. Export::Function(0) ,Export::Global(0) .fn extern_to_export(val: &wasmtime::ExternType) -> wasm_encoder::Export { match val { wasmtime::ExternType::Func(_) => wasm_encoder::Export::Function(0), <--- 0 is right ? wasmtime::ExternType::Global(_) => wasm_encoder::Export::Global(0), wasmtime::ExternType::Table(_) => wasm_encoder::Export::Table(0), wasmtime::ExternType::Memory(_) => wasm_encoder::Export::Memory(0), wasmtime::ExternType::Instance(_) => wasm_encoder::Export::Instance(0), wasmtime::ExternType::Module(_) => wasm_encoder::Export::Module(0), } }
misapprehand edited a comment on Issue #2498:
Hi @fitzgen, I commit PR 2535 about this issue.
But I still have some questions
- Cannot find how to convert from wasm::ValType::V128 to wasm_encoder::ValType and wasm_encoder::Instruction
See file wencoder_generator.rs , commented by //TODOIn wencoder_generator.rs fn value_to_instruction(ty: &ValType) -> Instruction { match ty { .... ValType::V128 => Instruction::F64Const(0.0), // TODO Do not know the right Instrunction type ... } } fn value_to_value(from: &ValType) -> wasm_encoder::ValType { match from { ... ValType::V128 => wasm_encoder::ValType::FuncRef, // TODO Do not know the right value ... } }
2 . The u32 value 0 in Export Type is right ?
eg. Export::Function(0) ,Export::Global(0) .fn extern_to_export(val: &wasmtime::ExternType) -> wasm_encoder::Export { match val { wasmtime::ExternType::Func(_) => wasm_encoder::Export::Function(0), <--- 0 is right ? wasmtime::ExternType::Global(_) => wasm_encoder::Export::Global(0), wasmtime::ExternType::Table(_) => wasm_encoder::Export::Table(0), wasmtime::ExternType::Memory(_) => wasm_encoder::Export::Memory(0), wasmtime::ExternType::Instance(_) => wasm_encoder::Export::Instance(0), wasmtime::ExternType::Module(_) => wasm_encoder::Export::Module(0), } }
fitzgen commented on Issue #2498:
Re (1) we just haven't implemented
v128
support inwasm-encoder
. I've opened https://github.com/bytecodealliance/wasm-tools/pull/187 to add enough support to unblock you here.
fitzgen commented on Issue #2498:
Re (2) I think we want a
num_funcs
member andnum_globals
member of theWencoder
builder struct and thenexport
should define the given item, let its index be the currentself.num_whatever
value, and then incrementself.num_whatever
. This index is then the thing that should be used instead of0
inwasm_encoder::Export::Whatever
.Does that make sense?
misapprehand commented on Issue #2498:
self.num_whatever just list self.tmp in WatGenerator ?
pub struct WatGenerator { tmp: usize, <--- is it num_funcs? dst: String, }
fitzgen commented on Issue #2498:
There needs to be a separate counter for each index space: one for globals, one for tables, one for functions, one for memories.
The
tmp
member was a hack for generating unique names in WAT. Unlike WAT, raw Wasm doesn't have names, so we have to refer to things by the actual index.
misapprehand commented on Issue #2498:
Make sense. I will update PR after wasm_encoder has updated. :)
fitzgen commented on Issue #2498:
after wasm_encoder has updated
Already published :)
misapprehand commented on Issue #2498:
@fitzgen, I have updated PR 2535
misapprehand commented on Issue #2498:
@fitzgen, I have updated PR 2535. There are two questions.
- In function mudle_init, I am not sure the nth of type in embedded module. I use enumerate index. I think it may not correct.
Current test case only import/export simple module. Can you add more complex modules to test case?fn module_init<'a>(&mut self, module: &'a mut Module, item_type: &ModuleType) -> &'a Module { let mut import_section = ImportSection::new(); for (i, imp) in item_type.imports().into_iter().enumerate() { import_section.import( imp.module(), imp.name(), extern_to_entity(&imp.ty(), i as u32), <-- I use i as nth of type ); } module.section(&import_section); let mut export_section = ExportSection::new(); for (i, exp) in item_type.exports().into_iter().enumerate() { export_section.export(&exp.name(), extern_to_export(&exp.ty(), i as u32)); <-- I use i as nth of type } module.section(&export_section); module }
- I do not find the way to instantiate which module. My current solution is instantiate one by one from Vec _self.modules_for_instantiate_ which stores all the export module index.
fn item_import(&mut self, ty: &ExternType) { ..... ExternType::Instance(v) => { ... // No sure following code is right if !self.modules_for_instantiate.is_empty() { self.instance_section.instantiate( self.modules_for_instantiate.remove(0), v.exports() .into_iter() .enumerate() .map(|(i, it)| (it.name(), extern_to_export(&it.ty(), i as u32))), ); self.num_instances += 1; } self.num_instances - 1 }
Last updated: Dec 23 2024 at 12:05 UTC