Skip to content

Remove basic reference types#4802

Merged
tlively merged 3 commits into
mainfrom
simplify-types
Jul 21, 2022
Merged

Remove basic reference types#4802
tlively merged 3 commits into
mainfrom
simplify-types

Conversation

@tlively

@tlively tlively commented Jul 14, 2022

Copy link
Copy Markdown
Member

Basic reference types like Type::funcref, Type::anyref, etc. made it easy to
accidentally forget to handle reference types with the same basic HeapTypes but
the opposite nullability. In principle there is nothing special about the types
with shorthands except in the binary and text formats. Removing these shorthands
from the internal type representation by removing all basic reference types
makes some code more complicated locally, but simplifies code globally and
encourages properly handling both nullable and non-nullable reference types.

@tlively tlively requested a review from kripken July 14, 2022 04:40
@tlively

tlively commented Jul 14, 2022

Copy link
Copy Markdown
Member Author

Current dependencies on/for this PR:

This comment was auto-generated by Graphite.

@tlively

tlively commented Jul 14, 2022

Copy link
Copy Markdown
Member Author

This is a draft because the fuzzer is turning up new bugs, but it should be otherwise pretty much done so I thought I'd upload it for review. (I'm out through Monday, so I'll have to fix those bugs next week.)

@dcodeIO

This comment was marked as resolved.

@kripken kripken left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Great!

;; CHECK: (import "env" "get_dataref" (func $get_dataref (param i32 i32 dataref) (result dataref)))

;; CHECK: (import "env" "set_dataref" (func $set_dataref (param i32 i32 dataref) (result dataref)))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

why are these removed but funcref remains in this file?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Since GC support was incomplete, it seemed simpler to remove what support was there while keeping the tested functionality covering the standardized reference types feature.

Comment thread test/example/c-api-kitchen-sink.txt Outdated
BinaryenPackedTypeInt8: 1
BinaryenPackedTypeInt16: 2
BinaryenFeatureMVP: 0
yenFeatureMVP: 0

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

typo?

Comment thread src/wasm/wasm.cpp
Comment thread src/wasm.h
Name table;
Expression* offset;
Type type = Type::funcref;
Type type = Type(HeapType::func, Nullable);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This works...? I'm surprised C++ allows it. It the function call done once statically, or each time in the constructor?

(this constructor isn't even a constexpr...)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Yes, default initializers are executed at object construction time. Similarly, default function arguments are evaluated when the function is called.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Are you not worried about a function call on each construction here? I guess element segments are not that common...

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I am slightly worried about using the Type constructor in more places. It's rather expensive because it has to do a lookup in the global type store. I'll do some quick measurements to check that this isn't a big performance regression.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Quick measurement didn't show anything concerning.

Comment thread src/wasm/wasm-type.cpp
bool Type::isNullable() const {
if (isBasic()) {
return id >= funcref && id <= eqref; // except i31ref and dataref
return false;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

yay for reduced complexity

tlively added 3 commits July 19, 2022 16:32
Basic reference types like `Type::funcref`, `Type::anyref`, etc. made it easy to
accidentally forget to handle reference types with the same basic HeapTypes but
the opposite nullability. In principle there is nothing special about the types
with shorthands except in the binary and text formats. Removing these shorthands
from the internal type representation by removing all basic reference types
makes some code more complicated locally, but simplifies code globally and
encourages properly handling both nullable and non-nullable reference types.
@tlively tlively marked this pull request as ready for review July 19, 2022 23:33
@tlively tlively requested a review from kripken July 19, 2022 23:33
@tlively

tlively commented Jul 19, 2022

Copy link
Copy Markdown
Member Author

The fuzzer is looking pretty good on this, too 🎉

@tlively tlively merged commit da5035f into main Jul 21, 2022
@tlively tlively deleted the simplify-types branch July 21, 2022 03:13
@MaxGraey

MaxGraey commented Jul 23, 2022

Copy link
Copy Markdown
Contributor

It seems this changes break C- and JS- APIs

We got

[wasm-validator error in module] unexpected false: Only funcref is valid for table type (when reference types are disabled), on 
table
[wasm-validator error in module] unexpected false: Only funcref and anyref are valid for table type (when typed-function references are disabled), on 
table
[wasm-validator error in module] funcref != funcref: element segment type must be the same as the table type, on 
elem

with this recent changes

@tlively

tlively commented Jul 25, 2022

Copy link
Copy Markdown
Member Author

@MaxGraey are you perhaps hard-coding the old values for funcref and anyref somewhere? They're now represented by pointers, so their values may change between executions, but the C and JS APIs should still work to get the new pointer values, and caching those values within a single execution should still work fine.

@MaxGraey

Copy link
Copy Markdown
Contributor

Thank for response! Yes they were cached at compile time, not at runtime. Looks like we'll have to refactor that part on our side.

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