Skip to content

Conversation

@malcolmstill
Copy link
Contributor

@malcolmstill malcolmstill commented Dec 25, 2022

The Buffer api is not complete as detailed in #155.

Specifically swap16, swap32 and swap64 are unimplemented.

This PR:

  • Implements swap16, swap32 and swap64 in src/bun.js/bindings/JSBuffer.cpp
  • Adds supporting tests to test/bun.js/buffer.test.js, testing:
    • Correct swapping behaviour for several examples
    • An error is thrown if the buffers are not appropriately sized (not multiples of the swap byte size, i.e. 2, 4, or 8 bytes for swap16, swap32 and swap64 respectively)

To do:

  • Port node tests

Copy link
Collaborator

@Jarred-Sumner Jarred-Sumner left a comment

Choose a reason for hiding this comment

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

Thank you for this. It's great that you wrote tests.

Some comments.

To make this fast, we could probably copy some of the code from node-bswap (it has an MIT license). Would need to verify that the output is the same though

return JSC::JSValue::encode(jsUndefined());
}

uint8_t* typedVector = castedThis->typedVector();
Copy link
Collaborator

Choose a reason for hiding this comment

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

Typed Arrays can become "detached". When detached, the vector or typedVector will return a nullptr. That means we have to check for this. It's fortunately pretty uncommon, so we can mark the branch as UNLIKELY

    if (UNLIKELY(castedThis->isDetached())) {
        throwVMTypeError(lexicalGlobalObject, throwScope, "Buffer is detached"_s);
        return JSValue::encode(jsUndefined());
    }

return JSC::JSValue::encode(jsUndefined());
}

uint8_t* typedVector = castedThis->typedVector();
Copy link
Collaborator

Choose a reason for hiding this comment

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

need to check for isDetached

uint8_t* typedVector = castedThis->typedVector();

for (size_t i = 0; i < length/size; i++) {
for (size_t j = 0; j < size/2; j++) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

  1. Ideally, this would use SIMD, leveraging AVX2 on x64 and ARM NEON on aarch64.
  2. We can move size/2 out of the inner loop


for (size_t i = 0; i < length/size; i++) {
for (size_t j = 0; j < size/2; j++) {
uint8_t temp = typedVector[size*i+j];
Copy link
Collaborator

Choose a reason for hiding this comment

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

This is a lot of multiplication. Can we turn this into one add in the outer loop and one add in the inner loop?

["", ""],
["a1", "1a"],
["a1b2", "1a2b"]
];
Copy link
Collaborator

Choose a reason for hiding this comment

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

@malcolmstill malcolmstill marked this pull request as draft December 26, 2022 21:38
- Use constexpr
- Clean up the indexing
- Check for detached
- Use suggested text for exception text
@Jarred-Sumner Jarred-Sumner marked this pull request as ready for review January 11, 2023 02:43
@Jarred-Sumner
Copy link
Collaborator

We need this and I don't think it's worth packages not working by this not being implemented

So I'm going to merge this.

Thank you

@Jarred-Sumner Jarred-Sumner merged commit f1e6ea2 into oven-sh:main Jan 11, 2023
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.

2 participants