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

feat(ops): Fallible fast ops #15989

Merged
merged 8 commits into from
Sep 23, 2022

Conversation

aapoalas
Copy link
Collaborator

Add support for fast ops to fail at any (sync) phase. If a fallible fast op returns an Err variant, the fallback option will be set true and the error gets saved to OpState. V8 will immediately, synchronously call the normal binding function, and the #[op] macro takes care of injecting a check for saved errors at the top of the binding.

The op macro and especially its fast side is starting to get pretty ugly, and this makes it uglier still. Big points of ugliness and undefined behaviour:

  1. In normal op side, the OpState borrowing is done several times at worst. There is no combined logic to figure out if OpState is needed and if it is needed as shared or unique (mut), thus leading to multiple places needing to borrow it individually.
  2. With fast call codegen, the FastApiCallbackOptions is starting to get quite confused about when it should be added into the inputs.
  3. Worse yet, if an op explicitly requires a Option<&mut FastApiCallbackOptions> parameter AND returns a Result or uses OpState, then the macro will generate two mutable borrows or one mutable and one shared borrow for the FastApiCallbackOptions, breaking Rust rules. This is likely "safe" in that its currently not used anywhere and its unlikely that it could lead to any issues since this is all synchronous code and thus race conditions are not possible. Still, it's not correct and shouldn't really be like this.

A further point that should be pondered is if it's correct to add fast_op_error into OpState or if it would be better to just use the gotham state with some core, or perhaps ops/lib.rs, defined FastOpError(Err) type.

core/ops.rs Outdated Show resolved Hide resolved
Copy link
Member

@littledivy littledivy left a comment

Choose a reason for hiding this comment

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

LGTM

@littledivy
Copy link
Member

littledivy commented Sep 22, 2022

Can you add an example in core/examples/? faillible fast ops are not used anywhere so don't have a full test for this right now

@aapoalas
Copy link
Collaborator Author

Can you add an example in core/examples/? faillible fast ops are not used anywhere so don't have a full test for this right now

There are probably a lot of fallible fast ops already around, since fast op generation is now automatic. We just don't know which ones as its automatic :)

@littledivy
Copy link
Member

Ah right...the #[op(fast)] attribute is only to enforce now?

@aapoalas
Copy link
Collaborator Author

Ah right...the #[op(fast)] attribute is only to enforce now?

Yeah. I'm planning on introducing a #[op(!fast)] to deny.

ext/websocket/lib.rs Outdated Show resolved Hide resolved
@aapoalas
Copy link
Collaborator Author

This PR should now be ready to merge.

@littledivy littledivy merged commit b5dfcbb into denoland:main Sep 23, 2022
@aapoalas aapoalas deleted the feat/fast-op-result-handling branch September 23, 2022 05:28
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.

4 participants