aboutsummaryrefslogtreecommitdiff
path: root/src/bun.js
diff options
context:
space:
mode:
authorGravatar Malcolm Still <malcolm.still@gmail.com> 2023-01-11 02:43:58 +0000
committerGravatar GitHub <noreply@github.com> 2023-01-10 18:43:58 -0800
commitf1e6ea22541fba2e7354b8440f6efe0f3292c546 (patch)
tree55c77187daec7d50809accb655987d4df4aabd3c /src/bun.js
parent56a6cf716e3c7c0613245ceb67492b9a2aaf4912 (diff)
downloadbun-f1e6ea22541fba2e7354b8440f6efe0f3292c546.tar.gz
bun-f1e6ea22541fba2e7354b8440f6efe0f3292c546.tar.zst
bun-f1e6ea22541fba2e7354b8440f6efe0f3292c546.zip
Implement Buffer swap16, swap32, swap64 (#1659)
* Implement Buffer swap16, swap32, swap64 * Initial incorporation of feedback - Use constexpr - Clean up the indexing - Check for detached - Use suggested text for exception text
Diffstat (limited to 'src/bun.js')
-rw-r--r--src/bun.js/bindings/JSBuffer.cpp88
1 files changed, 85 insertions, 3 deletions
diff --git a/src/bun.js/bindings/JSBuffer.cpp b/src/bun.js/bindings/JSBuffer.cpp
index 623c67bcb..a89492359 100644
--- a/src/bun.js/bindings/JSBuffer.cpp
+++ b/src/bun.js/bindings/JSBuffer.cpp
@@ -1114,17 +1114,99 @@ static inline JSC::EncodedJSValue jsBufferPrototypeFunction_lastIndexOfBody(JSC:
static inline JSC::EncodedJSValue jsBufferPrototypeFunction_swap16Body(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSArrayBufferView>::ClassParameter castedThis)
{
auto& vm = JSC::getVM(lexicalGlobalObject);
- return JSC::JSValue::encode(jsUndefined());
+ auto scope = DECLARE_THROW_SCOPE(vm);
+
+ constexpr int elemSize = 2;
+ int64_t length = static_cast<int64_t>(castedThis->byteLength());
+ if (length % elemSize != 0) {
+ throwRangeError(lexicalGlobalObject, scope, "Buffer size must be a multiple of 16-bits"_s);
+ return JSC::JSValue::encode(jsUndefined());
+ }
+
+ if (UNLIKELY(castedThis->isDetached())) {
+ throwVMTypeError(lexicalGlobalObject, scope, "Buffer is detached"_s);
+ return JSValue::encode(jsUndefined());
+ }
+
+ uint8_t* typedVector = castedThis->typedVector();
+
+ for (size_t elem = 0; elem < length; elem += elemSize) {
+ const size_t right = elem + 1;
+
+ uint8_t temp = typedVector[elem];
+ typedVector[elem] = typedVector[right];
+ typedVector[right] = temp;
+ }
+
+ return JSC::JSValue::encode(castedThis);
}
static inline JSC::EncodedJSValue jsBufferPrototypeFunction_swap32Body(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSArrayBufferView>::ClassParameter castedThis)
{
auto& vm = JSC::getVM(lexicalGlobalObject);
- return JSC::JSValue::encode(jsUndefined());
+ auto scope = DECLARE_THROW_SCOPE(vm);
+
+ constexpr int elemSize = 4;
+ int64_t length = static_cast<int64_t>(castedThis->byteLength());
+ if (length % elemSize != 0) {
+ throwRangeError(lexicalGlobalObject, scope, "Buffer size must be a multiple of 32-bits"_s);
+ return JSC::JSValue::encode(jsUndefined());
+ }
+
+ if (UNLIKELY(castedThis->isDetached())) {
+ throwVMTypeError(lexicalGlobalObject, scope, "Buffer is detached"_s);
+ return JSValue::encode(jsUndefined());
+ }
+
+ uint8_t* typedVector = castedThis->typedVector();
+
+ constexpr size_t swaps = elemSize/2;
+ for (size_t elem = 0; elem < length; elem += elemSize) {
+ const size_t right = elem + elemSize - 1;
+ for (size_t k = 0; k < swaps; k++) {
+ const size_t i = right - k;
+ const size_t j = elem + k;
+
+ uint8_t temp = typedVector[i];
+ typedVector[i] = typedVector[j];
+ typedVector[j] = temp;
+ }
+ }
+
+ return JSC::JSValue::encode(castedThis);
}
static inline JSC::EncodedJSValue jsBufferPrototypeFunction_swap64Body(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSArrayBufferView>::ClassParameter castedThis)
{
auto& vm = JSC::getVM(lexicalGlobalObject);
- return JSC::JSValue::encode(jsUndefined());
+ auto scope = DECLARE_THROW_SCOPE(vm);
+
+ constexpr size_t elemSize = 8;
+ int64_t length = static_cast<int64_t>(castedThis->byteLength());
+ if (length % elemSize != 0) {
+ throwRangeError(lexicalGlobalObject, scope, "Buffer size must be a multiple of 64-bits"_s);
+ return JSC::JSValue::encode(jsUndefined());
+ }
+
+ if (UNLIKELY(castedThis->isDetached())) {
+ throwVMTypeError(lexicalGlobalObject, scope, "Buffer is detached"_s);
+ return JSValue::encode(jsUndefined());
+ }
+
+ uint8_t* typedVector = castedThis->typedVector();
+
+ constexpr size_t swaps = elemSize/2;
+ for (size_t elem = 0; elem < length; elem += elemSize) {
+ const size_t right = elem + elemSize - 1;
+ for (size_t k = 0; k < swaps; k++) {
+ const size_t i = right - k;
+ const size_t j = elem + k;
+
+ uint8_t temp = typedVector[i];
+ typedVector[i] = typedVector[j];
+ typedVector[j] = temp;
+ }
+ }
+
+ return JSC::JSValue::encode(castedThis);
}
static inline JSC::EncodedJSValue jsBufferPrototypeFunction_toStringBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSArrayBufferView>::ClassParameter castedThis)