Index: src/runtime/runtime-atomics.cc |
diff --git a/src/runtime/runtime-atomics.cc b/src/runtime/runtime-atomics.cc |
index f5366ac612e5978e0e0c8da86a2a538327f14e1a..c9b78769cdc5a8630b3e254de8719c2d7e2583c5 100644 |
--- a/src/runtime/runtime-atomics.cc |
+++ b/src/runtime/runtime-atomics.cc |
@@ -424,6 +424,79 @@ inline Object* DoExchange(Isolate* isolate, void* buffer, size_t index, |
return ToObject<T>(isolate, FromAtomic<T>(result)); |
} |
+ |
+// Uint8Clamped functions |
+ |
+uint8_t ClampToUint8(int32_t value) { |
+ if (value < 0) return 0; |
+ if (value > 255) return 255; |
+ return value; |
Jarin
2015/06/22 07:04:03
Hmm, I am really surprised this does not need any
binji
2015/06/22 18:21:04
I didn't notice it until you mentioned it. I check
|
+} |
+ |
+ |
+inline Object* DoCompareExchangeUint8Clamped(Isolate* isolate, void* buffer, |
+ size_t index, |
+ Handle<Object> oldobj, |
+ Handle<Object> newobj) { |
+ typedef int32_t convert_type; |
+ typedef uint8_t atomic_type; |
+ atomic_type oldval = ClampToUint8(FromObject<convert_type>(oldobj)); |
+ atomic_type newval = ClampToUint8(FromObject<convert_type>(newobj)); |
+ atomic_type result = CompareExchangeSeqCst( |
+ static_cast<atomic_type*>(buffer) + index, oldval, newval); |
+ return ToObject<uint8_t>(isolate, FromAtomic<uint8_t>(result)); |
+} |
+ |
+ |
+inline Object* DoStoreUint8Clamped(Isolate* isolate, void* buffer, size_t index, |
+ Handle<Object> obj) { |
+ typedef int32_t convert_type; |
+ typedef uint8_t atomic_type; |
+ atomic_type value = ClampToUint8(FromObject<convert_type>(obj)); |
+ StoreSeqCst(static_cast<atomic_type*>(buffer) + index, value); |
+ return *obj; |
+} |
+ |
+ |
+#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; \ |
+ typedef uint8_t atomic_type; \ |
+ atomic_type* p = static_cast<atomic_type*>(buffer) + index; \ |
+ convert_type operand = FromObject<convert_type>(obj); \ |
+ atomic_type expected; \ |
+ atomic_type result; \ |
+ do { \ |
+ expected = *p; \ |
+ result = ClampToUint8(static_cast<convert_type>(expected) op operand); \ |
+ } while (CompareExchangeSeqCst(p, expected, result) != expected); \ |
+ return ToObject<uint8_t>(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; |
+ typedef uint8_t atomic_type; |
+ atomic_type* p = static_cast<atomic_type*>(buffer) + index; |
+ atomic_type result = ClampToUint8(FromObject<convert_type>(obj)); |
+ atomic_type expected; |
+ do { |
+ expected = *p; |
+ } while (CompareExchangeSeqCst(p, expected, result) != expected); |
+ return ToObject<uint8_t>(isolate, expected); |
+} |
+ |
+ |
} // anonymous namespace |
// Duplicated from objects.h |
@@ -434,8 +507,7 @@ inline Object* DoExchange(Isolate* isolate, void* buffer, size_t index, |
V(Uint16, uint16, UINT16, uint16_t, 2) \ |
V(Int16, int16, INT16, int16_t, 2) \ |
V(Uint32, uint32, UINT32, uint32_t, 4) \ |
- V(Int32, int32, INT32, int32_t, 4) \ |
- V(Uint8Clamped, uint8_clamped, UINT8_CLAMPED, uint8_t, 1) |
+ V(Int32, int32, INT32, int32_t, 4) |
RUNTIME_FUNCTION(Runtime_AtomicsCompareExchange) { |
@@ -455,9 +527,19 @@ RUNTIME_FUNCTION(Runtime_AtomicsCompareExchange) { |
case kExternal##Type##Array: \ |
return DoCompareExchange<ctype>(isolate, buffer, index, oldobj, newobj); |
- TYPED_ARRAYS(TYPED_ARRAY_CASE) |
+ INTEGER_TYPED_ARRAYS(TYPED_ARRAY_CASE) |
#undef TYPED_ARRAY_CASE |
+ case kExternalFloat32Array: |
+ return DoCompareExchange<float>(isolate, buffer, index, oldobj, newobj); |
+ |
+ case kExternalFloat64Array: |
+ return DoCompareExchange<double>(isolate, buffer, index, oldobj, newobj); |
+ |
+ case kExternalUint8ClampedArray: |
+ return DoCompareExchangeUint8Clamped(isolate, buffer, index, oldobj, |
+ newobj); |
+ |
default: |
break; |
} |
@@ -510,9 +592,18 @@ RUNTIME_FUNCTION(Runtime_AtomicsStore) { |
case kExternal##Type##Array: \ |
return DoStore<ctype>(isolate, buffer, index, value); |
- TYPED_ARRAYS(TYPED_ARRAY_CASE) |
+ INTEGER_TYPED_ARRAYS(TYPED_ARRAY_CASE) |
#undef TYPED_ARRAY_CASE |
+ case kExternalFloat32Array: |
+ return DoStore<float>(isolate, buffer, index, value); |
+ |
+ case kExternalFloat64Array: |
+ return DoStore<double>(isolate, buffer, index, value); |
+ |
+ case kExternalUint8ClampedArray: |
+ return DoStoreUint8Clamped(isolate, buffer, index, value); |
+ |
default: |
break; |
} |
@@ -541,6 +632,9 @@ RUNTIME_FUNCTION(Runtime_AtomicsAdd) { |
INTEGER_TYPED_ARRAYS(TYPED_ARRAY_CASE) |
#undef TYPED_ARRAY_CASE |
+ case kExternalUint8ClampedArray: |
+ return DoAddUint8Clamped(isolate, buffer, index, value); |
+ |
case kExternalFloat32Array: |
case kExternalFloat64Array: |
default: |
@@ -571,6 +665,9 @@ RUNTIME_FUNCTION(Runtime_AtomicsSub) { |
INTEGER_TYPED_ARRAYS(TYPED_ARRAY_CASE) |
#undef TYPED_ARRAY_CASE |
+ case kExternalUint8ClampedArray: |
+ return DoSubUint8Clamped(isolate, buffer, index, value); |
+ |
case kExternalFloat32Array: |
case kExternalFloat64Array: |
default: |
@@ -601,6 +698,9 @@ RUNTIME_FUNCTION(Runtime_AtomicsAnd) { |
INTEGER_TYPED_ARRAYS(TYPED_ARRAY_CASE) |
#undef TYPED_ARRAY_CASE |
+ case kExternalUint8ClampedArray: |
+ return DoAndUint8Clamped(isolate, buffer, index, value); |
+ |
case kExternalFloat32Array: |
case kExternalFloat64Array: |
default: |
@@ -631,6 +731,9 @@ RUNTIME_FUNCTION(Runtime_AtomicsOr) { |
INTEGER_TYPED_ARRAYS(TYPED_ARRAY_CASE) |
#undef TYPED_ARRAY_CASE |
+ case kExternalUint8ClampedArray: |
+ return DoOrUint8Clamped(isolate, buffer, index, value); |
+ |
case kExternalFloat32Array: |
case kExternalFloat64Array: |
default: |
@@ -661,6 +764,9 @@ RUNTIME_FUNCTION(Runtime_AtomicsXor) { |
INTEGER_TYPED_ARRAYS(TYPED_ARRAY_CASE) |
#undef TYPED_ARRAY_CASE |
+ case kExternalUint8ClampedArray: |
+ return DoXorUint8Clamped(isolate, buffer, index, value); |
+ |
case kExternalFloat32Array: |
case kExternalFloat64Array: |
default: |
@@ -691,6 +797,9 @@ RUNTIME_FUNCTION(Runtime_AtomicsExchange) { |
INTEGER_TYPED_ARRAYS(TYPED_ARRAY_CASE) |
#undef TYPED_ARRAY_CASE |
+ case kExternalUint8ClampedArray: |
+ return DoExchangeUint8Clamped(isolate, buffer, index, value); |
+ |
case kExternalFloat32Array: |
case kExternalFloat64Array: |
default: |