Skip to content
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

Update wabt submodule #16

Merged
merged 4 commits into from
Jun 16, 2018
Merged

Update wabt submodule #16

merged 4 commits into from
Jun 16, 2018

Conversation

Kimundi
Copy link
Contributor

@Kimundi Kimundi commented Jun 6, 2018

As a means to fix #15, I've updated the wabt submodule dependency to the current master.

  • Added FFI bindings for WabtWriteScriptResult
  • Added High-Level wrapper for WabtWriteScriptResult
  • Changed write_binaries and wat2wasm to only work with in-memory buffers
  • Removed tempdir dependency
  • Made ModuleBinary::into_vec() infallible

Depends on #17
Closes #9
Closes #15

@pepyakin
Copy link
Owner

pepyakin commented Jun 6, 2018

Ah, yeah, you're right, bindings are now out of date!

I think the reason why Script::write_binaries() doesn't do anything has something to do with transition from writing directly to a file to writing into a streams (#9).

To start: write_binaries takes one wast (it's like wat format but with special scripting abilities) file and produces one json file (aka spec) with 1 or many wasm files. This json contains a specification how to run one of these files and how to check the results.

I see the following way for dealing with this:

  1. Add a new result type WabtWriteScriptResult in sys bindings.
  2. Add bindings for corresponding functions for this type. We will need wabt_write_script_result_release_json_output_buffer in the next step.
  3. Update high-level wrappers. We need to introduce a special kind of result for WabtWriteScriptResult. It should hold a json buffer and buffers for all output wasm modules. We need a special methods for extracting them. Note that extracting is done via "release" method, essentially, just a move if speaking in Rust terms. You can take a look at ParseWastResult as an example.
  4. write_binaries. Basically, we don't need to take output filename anymore to specify output filename. Instead, we can return WabtWriteScriptResult directly or return tuple consisting of json buffer and vector of wasm module buffers/Vec<u8>.
  5. Next, we can get rid of tempfile and tempdir and all file handling altogher! Instead, we can make wat2wasm return data buffer with JSON and then parse it right away with serde! And instead of reading wasm module binaries from files we can pass vectors with modules directly!

@Kimundi
Copy link
Contributor Author

Kimundi commented Jun 15, 2018

Alright, so I've followed your bullet point list up to 3) so far. :) Do the higher level bindings look like you'd expect?

@Kimundi
Copy link
Contributor Author

Kimundi commented Jun 15, 2018

Also, a question about those take_ Functions in general - they usually pass a internal FFI raw pointer to a release function, but still call the corresponding destroy methods in their Drop impl - is that correct?

@Kimundi
Copy link
Contributor Author

Kimundi commented Jun 15, 2018

Alright, I'm now at 5). Modules no longer get written to temporary files, but to get rid of tempfile handling entirely I also need to make the input files live in buffers, which currently makes me trace the code paths of Script::parse.

@pepyakin
Copy link
Owner

Also, a question about those take_ Functions in general - they usually pass a internal FFI raw pointer to a release function, but still call the corresponding destroy methods in their Drop impl - is that correct?

Yes. release is somewhat similar to rust's Option::take: it moves the value out of the container and puts None/null instead of it.
On the other hand, destroy frees the whole structure that contains these releasable-containtainers.

@Kimundi
Copy link
Contributor Author

Kimundi commented Jun 15, 2018

Alright, I think this PR is now complete.


Just to be sure about the release vs destroy: In the native source its fine to call destroy after the pointer had already been released?

- Added FFI bindings for WabtWriteScriptResult
- Added High-Level wrapper for WabtWriteScriptResult
- Changed write_binaries and wat2wasm to only work with in-memory buffers
- Removed tempdir dependency
- Made ModuleBinary::into_vec() infallible
@Kimundi Kimundi changed the title WIP: Update wabt submodule Update wabt submodule Jun 15, 2018
src/lib.rs Outdated
self.raw_script,
source_cstr.as_ptr(),
out_cstr.as_ptr(),
std::ptr::null(),
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you use ptr::null?

src/lib.rs Outdated
}
}

fn get_module_count(&self) -> usize {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need for superfluous get_

src/lib.rs Outdated
}
}

fn get_module_filename(&self, index: usize) -> &str {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need for superfluous get_

@@ -523,19 +473,27 @@ impl<F32: FromBits<u32>, F64: FromBits<u64>> ScriptParser<F32, F64> {
None => return Ok(None),
};

let get_module = |filename, s: &Self| {
let mut r = None;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indent

@pepyakin
Copy link
Owner

Just to be sure about the release vs. destroy: In the native source its fine to call destroy after the pointer had already been released?

That not just fine, it is required in order not to introduce a memory leak. release only gives up the ownership of data, but doesn't free it. destroy frees it : )

@Kimundi
Copy link
Contributor Author

Kimundi commented Jun 15, 2018

Ah, now I get it, thanks. :)

@pepyakin
Copy link
Owner

Ah, now I get it, thanks. :)

But now I realized one thing: these APIs seems to be not safe. The second call of take will return nullptr.

ffi::wabt_write_script_result_release_module_output_buffer(
self.raw_script_result, i)
};
let name = self.module_filename(i);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we instead of CStr use String::from_utf8_lossy? At least it doesn't panic upon issues with utf8

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, I found using the lossy variants dangerous for this, as you might generate name collisions that way, and I was under the assumption that WebAssembly embraced utf8 anyway.

I could also just store the names as CString or Vec<u8> there?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's actually a good idea! We are only using these filenames for matching them with JSON commands, right? Even if we also need these filenames in order to display error messages, I think we can use from_utf8_lossy here (since error reporting isn't that critcial and it doesn't panic).

@@ -523,19 +473,27 @@ impl<F32: FromBits<u32>, F64: FromBits<u64>> ScriptParser<F32, F64> {
None => return Ok(None),
};

let get_module = |filename, s: &Self| {
let mut r = None;
for &(ref name, ref module) in &s.modules {
Copy link
Owner

@pepyakin pepyakin Jun 15, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like a job for a HashMap!

To clarify: I mean we could collect modules not into a Vec but into a HashMap in WabtWriteScriptResultRelease

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, indeed.

@pepyakin pepyakin merged commit 7a61c08 into pepyakin:master Jun 16, 2018
@pepyakin
Copy link
Owner

Well done! Thank you very much!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Build error due to GCC 8.0 warning Use Streams API to parse wasm scripts
2 participants