Skip to content

[multibyte] Add multibyte array load instructions.#8504

Open
brendandahl wants to merge 1 commit intoWebAssembly:mainfrom
brendandahl:multibyte-array-load
Open

[multibyte] Add multibyte array load instructions.#8504
brendandahl wants to merge 1 commit intoWebAssembly:mainfrom
brendandahl:multibyte-array-load

Conversation

@brendandahl
Copy link
Collaborator

Prototype implementation of the new multibyte array proposal that reuses the existing memory instructions.

https://github.com/WebAssembly/multibyte-array-access/blob/944d79230b336442b1f0b3978da1908d54b9f230/proposals/multibyte-array-access/Overview.md

@brendandahl brendandahl requested a review from a team as a code owner March 20, 2026 18:57
@brendandahl brendandahl requested review from stevenfontanella and removed request for a team March 20, 2026 18:57
Comment on lines +2409 to +2411
if (curr->bytes == 1) sval = int64_t(int8_t(sval));
else if (curr->bytes == 2) sval = int64_t(int16_t(sval));
else if (curr->bytes == 4) sval = int64_t(int32_t(sval));
Copy link
Member

Choose a reason for hiding this comment

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

Can we use C++ style casts or bit operators instead of C-style casts? e.g. sval & 0xFF

Comment on lines +1151 to +1154
if (curr->ref->type.isNull()) {
parent.trap = true;
return;
}
Copy link
Member

Choose a reason for hiding this comment

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

I think we can use

      if (trapOnNull(curr->ref)) {
        return;
      }

which also handles the unreachable case. I guess the below statement setting implicitTrap is still needed because OOB access is always possible?

Copy link
Member

Choose a reason for hiding this comment

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

It would be good to add a comment about the possibility of OOB access here.

}
}

void ArrayLoad::finalize() {
Copy link
Member

Choose a reason for hiding this comment

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

I'm confused on this, doesn't ArrayLoad have a return value based on the value of bytes and signed?

Copy link
Member

Choose a reason for hiding this comment

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

I think the issue is bytes and signed is not always enough to differentiate integer and floating point loads, so we're already depending on the type be set correctly to tell us what instruction this is (and we wouldn't know how to update it even if we wanted to.)

visit(curr->index) + visit(curr->value);
}
CostType visitArrayLoad(ArrayLoad* curr) {
return 1 + nullCheckCost(curr->ref) + visit(curr->ref) + visit(curr->index);
Copy link
Member

Choose a reason for hiding this comment

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

What's the 1 for here? Can we name this constant?

Copy link
Member

Choose a reason for hiding this comment

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

We use lots of unnamed constants for base costs, so I think considering this separately would be fine.

@stevenfontanella stevenfontanella requested review from a team and tlively and removed request for a team March 20, 2026 21:09
@stevenfontanella
Copy link
Member

(Re-add binaryen reviewers for a second look)

visit(curr->index) + visit(curr->value);
}
CostType visitArrayLoad(ArrayLoad* curr) {
return 1 + nullCheckCost(curr->ref) + visit(curr->ref) + visit(curr->index);
Copy link
Member

Choose a reason for hiding this comment

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

We use lots of unnamed constants for base costs, so I think considering this separately would be fine.

Comment on lines +1151 to +1154
if (curr->ref->type.isNull()) {
parent.trap = true;
return;
}
Copy link
Member

Choose a reason for hiding this comment

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

It would be good to add a comment about the possibility of OOB access here.

auto shifts = Literal(int32_t(32 - field->getByteSize() * 8));
unsigned bits = resultType.getByteSize() == 8 ? 64 : 32;
if (bits <= bytes * 8) {
return; // No need to sign-extend for full size
Copy link
Member

Choose a reason for hiding this comment

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

We generally avoid inline comments.

Suggested change
return; // No need to sign-extend for full size
// No need to sign-extend for full size.
return;

}
}

void ArrayLoad::finalize() {
Copy link
Member

Choose a reason for hiding this comment

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

I think the issue is bytes and signed is not always enough to differentiate integer and floating point loads, so we're already depending on the type be set correctly to tell us what instruction this is (and we wouldn't know how to update it even if we wanted to.)

Comment on lines +2401 to +2402
if (curr->bytes == 1) sval = int32_t(int8_t(sval));
else if (curr->bytes == 2) sval = int32_t(int16_t(sval));
Copy link
Member

Choose a reason for hiding this comment

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

We always use brackets around if bodies, even for one-liners. (Here and below.)

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