Index: src/elements.cc |
diff --git a/src/elements.cc b/src/elements.cc |
index 7b7f6893d84b557224acb1232b7798eb39cbb461..b36ed4f276593a544292db9035e62575aa46a7de 100644 |
--- a/src/elements.cc |
+++ b/src/elements.cc |
@@ -470,6 +470,23 @@ static void SortIndices( |
} |
} |
+static Object* FillNumberSlowPath(Isolate* isolate, Handle<JSTypedArray> array, |
+ Handle<Object> obj_value, |
+ uint32_t start, uint32_t end) { |
+ const char* kMethodName = "%TypedArray%.prototype.fill"; |
+ Handle<Object> cast_value; |
+ ElementsAccessor* elements = array->GetElementsAccessor(); |
+ |
+ for (uint32_t k = start; k < end; ++k) { |
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
+ isolate, cast_value, Object::ToNumber(obj_value)); |
+ // TODO(caitp,cbruni): throw on neutered array |
+ if (V8_UNLIKELY(array->WasNeutered())) return *array; |
+ elements->Set(array, k, *cast_value); |
+ } |
+ return *array; |
+} |
+ |
static Maybe<bool> IncludesValueSlowPath(Isolate* isolate, |
Handle<JSObject> receiver, |
Handle<Object> value, |
@@ -1191,6 +1208,17 @@ class ElementsAccessorBase : public ElementsAccessor { |
return Subclass::GetCapacityImpl(holder, backing_store); |
} |
+ static Object* FillImpl(Isolate* isolate, Handle<JSObject> receiver, |
+ Handle<Object> obj_value, uint32_t start, uint32_t end) { |
+ UNREACHABLE(); |
+ return *receiver; |
+ } |
+ |
+ Object* Fill(Isolate* isolate, Handle<JSObject> receiver, |
+ Handle<Object> obj_value, uint32_t start, uint32_t end) { |
+ return Subclass::FillImpl(isolate, receiver, obj_value, start, end); |
+ } |
+ |
static Maybe<bool> IncludesValueImpl(Isolate* isolate, |
Handle<JSObject> receiver, |
Handle<Object> value, |
@@ -2815,6 +2843,58 @@ class TypedElementsAccessor |
return Just(true); |
} |
+ template <typename T, ElementsKind K = Kind> |
+ static inline uint8_t MaybeClamp( |
Camillo Bruni
2017/03/14 09:30:35
ConvertNumberToUint8Clamped(Handle<Object> obj_val
rongjie
2017/03/14 10:08:48
Done.
|
+ Handle<Object> obj_value, JSTypedArray* array, |
+ typename std::enable_if<K == UINT8_CLAMPED_ELEMENTS, T>::type = 0) { |
+ double value = 0.0; |
+ if (obj_value->IsSmi()) { |
+ value = Smi::cast(*obj_value)->value(); |
Camillo Bruni
2017/03/14 09:30:36
Special case directly on Smi and avoid slow double
rongjie
2017/03/14 10:08:48
Done.
|
+ } else { |
+ DCHECK(obj_value->IsHeapNumber()); |
+ value = HeapNumber::cast(*obj_value)->value(); |
+ } |
+ value = std::min<double>(std::max<double>(0, value), 255); |
+ return static_cast<uint8_t>(value); |
+ } |
+ |
+ template <typename T, ElementsKind K = Kind> |
+ static inline T MaybeClamp( |
Camillo Bruni
2017/03/14 09:30:36
static ctype ConvertToNumber(Handle<Object> obj_va
Camillo Bruni
2017/03/14 09:31:21
On 2017/03/14 at 09:30:36, Camillo Bruni wrote:
>
rongjie
2017/03/14 10:08:47
Done.
|
+ Handle<Object> obj_value, JSTypedArray* array, |
+ typename std::enable_if<K != UINT8_CLAMPED_ELEMENTS, T>::type = 0) { |
+ T value = 0; |
Camillo Bruni
2017/03/14 09:30:36
ctype value = 0;
rongjie
2017/03/14 10:08:48
Done.
|
+ if (obj_value->IsSmi()) { |
+ value = static_cast<T>(Smi::cast(*obj_value)->value()); |
+ } else { |
+ DCHECK(obj_value->IsHeapNumber()); |
+ value = static_cast<T>(HeapNumber::cast(*obj_value)->value()); |
+ } |
+ return value; |
+ } |
+ |
+ static Object* FillImpl(Isolate* isolate, Handle<JSObject> receiver, |
+ Handle<Object> obj_value, uint32_t start, uint32_t end) { |
+ Handle<JSTypedArray> array = Handle<JSTypedArray>::cast(receiver); |
+ DCHECK(!array->WasNeutered()); |
+ |
+ if (!obj_value->IsNumber()) { |
+ return FillNumberSlowPath(isolate, array, obj_value, start, end); |
+ } |
+ |
+ ctype value = MaybeClamp<ctype>(obj_value, *array); |
Camillo Bruni
2017/03/14 09:30:35
I'm not a too big can of the the additional templa
rongjie
2017/03/14 10:08:47
Done.
I previously tested similar solution but wi
|
+ |
+ // Ensure indexes are within array bounds |
+ DCHECK_LE(0, start); |
+ DCHECK_LE(start, end); |
+ DCHECK_LE(end, array->length_value()); |
+ |
+ DisallowHeapAllocation no_gc; |
+ BackingStore* elements = BackingStore::cast(receiver->elements()); |
+ ctype* data = static_cast<ctype*>(elements->DataPtr()); |
+ std::fill(data + start, data + end, value); |
+ return *array; |
+ } |
+ |
static Maybe<bool> IncludesValueImpl(Isolate* isolate, |
Handle<JSObject> receiver, |
Handle<Object> value, |