Skip to content

Add support for optional numbers #630

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

Merged
merged 8 commits into from
Aug 3, 2018
Merged

Conversation

afdw
Copy link
Contributor

@afdw afdw commented Aug 3, 2018

Fixes #624.

@alexcrichton
Copy link
Contributor

Thanks for this!

It looks like the in-memory representation of optional types is a u32 indicating whether it's Some or None and then the payload itself? That seems plausible to me!

@fitzgen was experimenting using the "global stack" as well for the payload and/or discriminant, as this I believe would enable a blanket implementation for all Option<T> rather than needing a per-type solution (like we need today)

Another option I was thinking of is that if we want to go the super-specialized route we could support Option<T> for all T that aren't f64 or u64 by using f64 as the ABI value, choosing an out-of-range sentinel for None for each type (e.g. None::<u32> becomes NaN, None::<f32> becomes Some(f64::max_value()), etc)

I'm not sure what the best option is here, but I'm curious what @fitzgen thinks of this too!

@afdw
Copy link
Contributor Author

afdw commented Aug 3, 2018

Other approaches are possible, yes. But implementing manually means that it's possible to do it better, more compact (like I do with optional i8, u8, i16 and u16 types, using a single u32 argument/return type everywhere). And we don't have too many primitives.

Is passing (and converting) float significantly cheaper than passing 2 integers / integer and 32-bit float?

@alexcrichton
Copy link
Contributor

True yeah! I personally like the idea of using more compact representations as well, and I think using u32 where possible is a great example of that.

In terms of cost I'm not actually sure, but I'd imagine that it's pretty negligible for wasm-bindgen's purposes

@@ -154,7 +154,27 @@ impl Descriptor {
}
}

pub fn get_64bit(&self) -> Option<bool> {
pub fn is_primitive(&self) -> bool {
Copy link
Contributor

Choose a reason for hiding this comment

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

Could this perhaps be named slightly differently to something like is_wasm_native_type or something like that?

}
}

pub fn is_as_u32(&self) -> bool {
Copy link
Contributor

Choose a reason for hiding this comment

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

Could this perhaps be renamed to is_abi_as_u32?

"\n\
if (!isLikeNone({0})) {{\n\
_assertNum({0});\n\
}}\n\
Copy link
Contributor

Choose a reason for hiding this comment

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

Nowadays all the \n\ markers here should be fine to clean up, the auto-formatting will strip them all away anyway!

@afdw afdw force-pushed the master branch 2 times, most recently from b7f53ed to b374f95 Compare August 3, 2018 15:32
@fitzgen
Copy link
Member

fitzgen commented Aug 3, 2018

I don't have any concrete work in progress, so don't block this on me!

Regarding blanket vs targeted impls: I also doubt that there is observable overhead to putting a discriminant on the global stack. But targeted impls mean that we have to write many impls instead of a single one. I suspect that we will want to move to a blanket impl eventually. But it is also an implementation detail that can be changed at a later date.

@afdw
Copy link
Contributor Author

afdw commented Aug 3, 2018

I think it's now implemented for all of the primitive types.

@alexcrichton alexcrichton merged commit 61b3d52 into rustwasm:master Aug 3, 2018
@alexcrichton
Copy link
Contributor

Thanks so much @afdw!

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.

3 participants