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

Add metered compile and check functions to c api #736

Closed
wants to merge 1 commit into from
Closed

Add metered compile and check functions to c api #736

wants to merge 1 commit into from

Conversation

ethanfrey
Copy link
Contributor

Created metering.rs and exposed:

  • wasmer_compile_with_limit - hardcoded to singlepass backend now, as only stable one
  • wasmer_instance_get_points_used
  • wasmer_instance_set_points_used

I also added a metering feature flag. And the functions default to wasmer_compile and "noops" if the feature is disabled (but expose the same API).

I will work on testing an example in the go-ext-wasm repo, then submit this for review, but I am happy for any early feedback as well.

lib/runtime/src/cache.rs Outdated Show resolved Hide resolved
@@ -96,6 +96,7 @@ pub mod global;
pub mod import;
pub mod instance;
pub mod memory;
pub mod metering;
Copy link
Contributor

Choose a reason for hiding this comment

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

You can add the attribute #[cfg(feature = "metering")] here, and remove all the same attributes in metering.rs. I believe it will simplify the code :-).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The problem is that it would expose a different C ABI then, and the go wrapper would fail to compile. Since go doesn't support conditional compilation feature tags as rust does, I think it would break the go bindings to have different ABIs (okay, there is some stuff for architecture, but nothing like rust's feature switches).

I can change that out if this is not a problem, but wanted the least breaking change possible (especially since the abi is committed to the go-ext-wasmer repo)

Choose a reason for hiding this comment

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

Golang build tags can be used to select the proper C ABI object to link against.


/*** placeholder implementation if metering feature off ***/

// Without metering, wasmer_compile_with_limit is a copy of wasmer_compile
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not sure we need fallbacks. If metering feature is on, then wasmer_compile_with_limit will exist, otherwise it will be absent.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

See above point about the bindings - the ABI is copied into the other repo. I feel this option is more a way to merge for now without it being fully tested, then metering can be always on (remove conditions) when it is ready to release.

If this is fully supported in master of go-ext-wasmer, then it should be also in the default binary builds of the .so files

Copy link
Contributor Author

Choose a reason for hiding this comment

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

To elaborate, cgo will panic on link error (no build) if the linked dll doesn't have the referenced methods. This is why I need stubs (go doesn't have smart feature flags)

Choose a reason for hiding this comment

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

I don't think that wasmer_compile_with_limit should return without error if the feature is disabled. At least the function should inform the user that it can't enforce a limit.

@Hywan Hywan self-assigned this Sep 6, 2019
[features]
default = ["cranelift-backend"]
debug = ["wasmer-runtime/debug"]
cranelift-backend = ["wasmer-runtime/cranelift", "wasmer-runtime/default-backend-cranelift"]
llvm-backend = ["wasmer-runtime/llvm", "wasmer-runtime/default-backend-llvm"]
singlepass-backend = ["wasmer-runtime/singlepass", "wasmer-runtime/default-backend-singlepass"]
metering = ["wasmer-runtime/singlepass", "wasmer-middleware-common", "wasmer-singlepass-backend"]
Copy link
Contributor

Choose a reason for hiding this comment

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

Since singlepass-backend is already a feature, you can simplify the “feature dependency” by writing:

metering = ["singlepass-backend", "wasmer-middleware-common"]

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I did that. It then sets wasmer-runtime/default-backend-singlepass.
and the default features set wasmer-runtime/default-backend-cranelift.

Setting two default backends caused a panic or compile issue. (I can look up the line if you want). I had to set this to avoid crashes. Ideal would be to disable the cranelift-backend completely for the metered build I guess. But I don't know how to disable default features.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Also note that singlepass-backend wouldn't even compile without an extra dependency added. Or maybe that is the problem. Hmmm...

lib/runtime-c-api/src/metering.rs Show resolved Hide resolved
lib/runtime-c-api/src/metering.rs Show resolved Hide resolved
lib/runtime-c-api/src/metering.rs Show resolved Hide resolved
lib/runtime-c-api/src/metering.rs Show resolved Hide resolved
lib/runtime-c-api/src/metering.rs Outdated Show resolved Hide resolved
@Hywan
Copy link
Contributor

Hywan commented Sep 18, 2019

The fact that only the Singlepass backend support gas metering annoys me. The go-ext-wasm language integration works with the Cranelift backend. To support the Singlepass backend, it means that the shared library we share with our CI must embed two backends. Or we should distribute 2 shared libraries: One with the Singlepass backend, and one with the Cranelift backend.

Thoughts @syrusakbary?

Copy link
Contributor Author

@ethanfrey ethanfrey left a comment

Choose a reason for hiding this comment

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

Thanks for the feedback.

I think much would simplify if we could disable the default feature and just force default singlepass when metering was enabled.

This would provide consistency in each format, although two targetted builds:

  • a fast one (cranelift) with stubs for metering to be abi compatible, that don't meter.
  • a slow one (singlepass) with metering enabled.

I guess this leaves the go-ext-wasm on a branch for a while, but I am definitely happier to stick on a go branch that points to the runtime master than a branch off a branch that will be maintainability nightmare.

@ethanfrey
Copy link
Contributor Author

Also, any idea how to get the C tests to run: eg. https://github.com/wasmerio/wasmer/pull/736/files#diff-105bd7892c64c7216319c0f4f58e0d18 ?

@Hywan
Copy link
Contributor

Hywan commented Sep 18, 2019

@ethanfrey
Copy link
Contributor Author

789f2ce fixes the features so metering will disable cranelift and enable singlepass as default compiler for a smoother experience. This requires running tests with the --no-default--features flag, like: cargo test --features metering --no-default-features

This fails on a serialization issue, but notably the same issue exists without metering: cargo test --features singlepass-backend --no-default-features. I will check master, but I think singlepass-backend is not properly handled in the c api (although worked fine in pure rust I believe). Guess non-cranelift path is relatively untested here.

@ethanfrey ethanfrey marked this pull request as ready for review September 20, 2019 10:32
@ethanfrey
Copy link
Contributor Author

I addressed all issues and added a section to the README on feature flags.
The c test for testing metering and serialization of metered code is also enabled.

Note that this currently only passes all c tests for:

cargo test --no-default-features --features llvm-backend,metering

test-module-metering-serialize requires metering to be enabled (and working) and serialization to be working. serialization is known to be broken on singlepass backend (see #811) and gas metering / middleware is known to be broken on the cranelift backend (see #819)

@AdamSLevy
Copy link

I rebased this PR on the latest master: https://github.com/AdamSLevy/wasmer/tree/metering

details here:
https://github.com/confio/wasmer/pull/1

Add wasmer_compile_with_limit api

Try adding metering functions - need help to compile

Metering api compiles with feature flag on and off

Fixed linter errors in metering.rs

Added some TODOs to check serialization failure

Fix u32 -> u64 in gas limit

Try to make C test case for using wasmer_compile_with_limit

Run cargo +stable fmt --all

Clean up feature setup with --no-default-features, singlepass-backend fails

get_metered_compiler uses whatever default backend

Handle null input in metering api

wasmer_compile_with_limit -> wasmer_compile_with_gas_metering

Update deps to 0.7.0 after rebase

Use llvm backend by default for metering - all tests pass

Add basic test-module-metering-serialize test

Only passes with --features metering

Expose CraneliftModuleCodeGenerator to test with --metering, document issues

Fix linter issue

Do not export undocumented Cranelift MCG
@Hywan
Copy link
Contributor

Hywan commented Dec 18, 2020

Hello,

Now that Wasmer 1.0.0-beta2 is released, which contains a new middleware API, do you still need the features from the PR? If yes, can you rebase it, or do you want us to do that?

Note that we now align our C API onto the official standard Wasm C API. Middleware and metering are not part of this standard. That's why we have a vendor-specific API and I think such features will fit there.

@ethanfrey
Copy link
Contributor Author

Oh, we can close this. I stopped using the c api a year ago to write my logic in rust and use custom high level ffi bindings to go.

I like the new Middleware design btw

@ethanfrey ethanfrey closed this Dec 18, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🎉 enhancement New feature! 📦 lib-c-api About wasmer-c-api
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants