| Index: src/builtins/builtins-sharedarraybuffer.cc
|
| diff --git a/src/builtins/builtins-sharedarraybuffer.cc b/src/builtins/builtins-sharedarraybuffer.cc
|
| index 85d08bbcee1c4e6be013bcdbaa31abbe964b000c..7ee144901e1a074818704e50886065439ee1234f 100644
|
| --- a/src/builtins/builtins-sharedarraybuffer.cc
|
| +++ b/src/builtins/builtins-sharedarraybuffer.cc
|
| @@ -638,6 +638,61 @@
|
| return ToObject(isolate, result);
|
| }
|
|
|
| +// Uint8Clamped functions
|
| +
|
| +uint8_t ClampToUint8(int32_t value) {
|
| + if (value < 0) return 0;
|
| + if (value > 255) return 255;
|
| + return value;
|
| +}
|
| +
|
| +inline Object* DoCompareExchangeUint8Clamped(Isolate* isolate, void* buffer,
|
| + size_t index,
|
| + Handle<Object> oldobj,
|
| + Handle<Object> newobj) {
|
| + typedef int32_t convert_type;
|
| + uint8_t oldval = ClampToUint8(FromObject<convert_type>(oldobj));
|
| + uint8_t newval = ClampToUint8(FromObject<convert_type>(newobj));
|
| + uint8_t result = CompareExchangeSeqCst(static_cast<uint8_t*>(buffer) + index,
|
| + oldval, newval);
|
| + return ToObject(isolate, result);
|
| +}
|
| +
|
| +#define DO_UINT8_CLAMPED_OP(name, op) \
|
| + inline Object* Do##name##Uint8Clamped(Isolate* isolate, void* buffer, \
|
| + size_t index, Handle<Object> obj) { \
|
| + typedef int32_t convert_type; \
|
| + uint8_t* p = static_cast<uint8_t*>(buffer) + index; \
|
| + convert_type operand = FromObject<convert_type>(obj); \
|
| + uint8_t expected; \
|
| + uint8_t result; \
|
| + do { \
|
| + expected = *p; \
|
| + result = ClampToUint8(static_cast<convert_type>(expected) op operand); \
|
| + } while (CompareExchangeSeqCst(p, expected, result) != expected); \
|
| + return ToObject(isolate, expected); \
|
| + }
|
| +
|
| +DO_UINT8_CLAMPED_OP(Add, +)
|
| +DO_UINT8_CLAMPED_OP(Sub, -)
|
| +DO_UINT8_CLAMPED_OP(And, &)
|
| +DO_UINT8_CLAMPED_OP(Or, |)
|
| +DO_UINT8_CLAMPED_OP(Xor, ^)
|
| +
|
| +#undef DO_UINT8_CLAMPED_OP
|
| +
|
| +inline Object* DoExchangeUint8Clamped(Isolate* isolate, void* buffer,
|
| + size_t index, Handle<Object> obj) {
|
| + typedef int32_t convert_type;
|
| + uint8_t* p = static_cast<uint8_t*>(buffer) + index;
|
| + uint8_t result = ClampToUint8(FromObject<convert_type>(obj));
|
| + uint8_t expected;
|
| + do {
|
| + expected = *p;
|
| + } while (CompareExchangeSeqCst(p, expected, result) != expected);
|
| + return ToObject(isolate, expected);
|
| +}
|
| +
|
| } // anonymous namespace
|
|
|
| // Duplicated from objects.h
|
| @@ -686,7 +741,8 @@
|
| #undef TYPED_ARRAY_CASE
|
|
|
| case kExternalUint8ClampedArray:
|
| - UNREACHABLE();
|
| + return DoCompareExchangeUint8Clamped(isolate, source, i, expectedValue,
|
| + replacementValue);
|
|
|
| default:
|
| break;
|
| @@ -727,7 +783,7 @@
|
| #undef TYPED_ARRAY_CASE
|
|
|
| case kExternalUint8ClampedArray:
|
| - UNREACHABLE();
|
| + return DoAddUint8Clamped(isolate, source, i, value);
|
|
|
| default:
|
| break;
|
| @@ -768,7 +824,7 @@
|
| #undef TYPED_ARRAY_CASE
|
|
|
| case kExternalUint8ClampedArray:
|
| - UNREACHABLE();
|
| + return DoSubUint8Clamped(isolate, source, i, value);
|
|
|
| default:
|
| break;
|
| @@ -809,7 +865,7 @@
|
| #undef TYPED_ARRAY_CASE
|
|
|
| case kExternalUint8ClampedArray:
|
| - UNREACHABLE();
|
| + return DoAndUint8Clamped(isolate, source, i, value);
|
|
|
| default:
|
| break;
|
| @@ -850,7 +906,7 @@
|
| #undef TYPED_ARRAY_CASE
|
|
|
| case kExternalUint8ClampedArray:
|
| - UNREACHABLE();
|
| + return DoOrUint8Clamped(isolate, source, i, value);
|
|
|
| default:
|
| break;
|
| @@ -891,7 +947,7 @@
|
| #undef TYPED_ARRAY_CASE
|
|
|
| case kExternalUint8ClampedArray:
|
| - UNREACHABLE();
|
| + return DoXorUint8Clamped(isolate, source, i, value);
|
|
|
| default:
|
| break;
|
| @@ -932,7 +988,7 @@
|
| #undef TYPED_ARRAY_CASE
|
|
|
| case kExternalUint8ClampedArray:
|
| - UNREACHABLE();
|
| + return DoExchangeUint8Clamped(isolate, source, i, value);
|
|
|
| default:
|
| break;
|
|
|