Index: src/code-stub-assembler.cc |
diff --git a/src/code-stub-assembler.cc b/src/code-stub-assembler.cc |
index 6d4ce690ff97f01062099ea524a4ea1c767f1cef..98a14a91959349ef5ec7afa73634461757dfaa45 100644 |
--- a/src/code-stub-assembler.cc |
+++ b/src/code-stub-assembler.cc |
@@ -5401,21 +5401,6 @@ Node* CodeStubAssembler::LoadScriptContext(Node* context, int context_index) { |
IntPtrConstant(offset)); |
} |
-Node* CodeStubAssembler::ClampedToUint8(Node* int32_value) { |
Igor Sheludko
2016/11/30 09:32:05
I renamed it and moved down.
|
- Label done(this); |
- Node* int32_zero = Int32Constant(0); |
- Node* int32_255 = Int32Constant(255); |
- Variable var_value(this, MachineRepresentation::kWord32); |
- var_value.Bind(int32_value); |
- GotoIf(Uint32LessThanOrEqual(int32_value, int32_255), &done); |
- var_value.Bind(int32_zero); |
- GotoIf(Int32LessThan(int32_value, int32_zero), &done); |
- var_value.Bind(int32_255); |
- Goto(&done); |
- Bind(&done); |
- return var_value.value(); |
-} |
- |
namespace { |
// Converts typed array elements kind to a machine representations. |
@@ -5448,7 +5433,8 @@ void CodeStubAssembler::StoreElement(Node* elements, ElementsKind kind, |
ParameterMode mode) { |
if (IsFixedTypedArrayElementsKind(kind)) { |
if (kind == UINT8_CLAMPED_ELEMENTS) { |
- value = ClampedToUint8(value); |
+ CSA_ASSERT(this, |
+ Word32Equal(value, Word32And(Int32Constant(0xff), value))); |
} |
Node* offset = ElementOffsetFromIndex(index, kind, mode, 0); |
MachineRepresentation rep = ElementsKindToMachineRepresentation(kind); |
@@ -5467,6 +5453,106 @@ void CodeStubAssembler::StoreElement(Node* elements, ElementsKind kind, |
} |
} |
+Node* CodeStubAssembler::Int32ToUint8Clamped(Node* int32_value) { |
+ Label done(this); |
+ Node* int32_zero = Int32Constant(0); |
+ Node* int32_255 = Int32Constant(255); |
+ Variable var_value(this, MachineRepresentation::kWord32); |
+ var_value.Bind(int32_value); |
+ GotoIf(Uint32LessThanOrEqual(int32_value, int32_255), &done); |
+ var_value.Bind(int32_zero); |
+ GotoIf(Int32LessThan(int32_value, int32_zero), &done); |
+ var_value.Bind(int32_255); |
+ Goto(&done); |
+ Bind(&done); |
+ return var_value.value(); |
+} |
+ |
+Node* CodeStubAssembler::Float64ToUint8Clamped(Node* float64_value) { |
+ Label done(this); |
+ Variable var_value(this, MachineRepresentation::kWord32); |
+ var_value.Bind(Int32Constant(0)); |
+ GotoIf(Float64LessThanOrEqual(float64_value, Float64Constant(0.0)), &done); |
+ var_value.Bind(Int32Constant(255)); |
+ GotoIf(Float64LessThanOrEqual(Float64Constant(255.0), float64_value), &done); |
+ { |
+ Node* rounded_value = Float64RoundTiesEven(float64_value); |
+ var_value.Bind(TruncateFloat64ToWord32(rounded_value)); |
+ Goto(&done); |
+ } |
+ Bind(&done); |
+ return var_value.value(); |
+} |
+ |
+Node* CodeStubAssembler::PrepareValueForWriteToTypedArray( |
+ Node* input, ElementsKind elements_kind, Label* bailout) { |
+ DCHECK(IsFixedTypedArrayElementsKind(elements_kind)); |
+ |
+ MachineRepresentation rep; |
+ switch (elements_kind) { |
+ case UINT8_ELEMENTS: |
+ case INT8_ELEMENTS: |
+ case UINT16_ELEMENTS: |
+ case INT16_ELEMENTS: |
+ case UINT32_ELEMENTS: |
+ case INT32_ELEMENTS: |
+ case UINT8_CLAMPED_ELEMENTS: |
+ rep = MachineRepresentation::kWord32; |
+ break; |
+ case FLOAT32_ELEMENTS: |
+ rep = MachineRepresentation::kFloat32; |
+ break; |
+ case FLOAT64_ELEMENTS: |
+ rep = MachineRepresentation::kFloat64; |
+ break; |
+ default: |
+ UNREACHABLE(); |
+ return nullptr; |
+ } |
+ |
+ Variable var_result(this, rep); |
+ Label done(this, &var_result), if_smi(this); |
+ GotoIf(TaggedIsSmi(input), &if_smi); |
+ // Try to convert a heap number to a Smi. |
+ GotoUnless(IsHeapNumberMap(LoadMap(input)), bailout); |
+ { |
+ Node* value = LoadHeapNumberValue(input); |
+ if (rep == MachineRepresentation::kWord32) { |
+ if (elements_kind == UINT8_CLAMPED_ELEMENTS) { |
+ value = Float64ToUint8Clamped(value); |
+ } else { |
+ value = TruncateFloat64ToWord32(value); |
+ } |
+ } else if (rep == MachineRepresentation::kFloat32) { |
+ value = TruncateFloat64ToFloat32(value); |
+ } else { |
+ DCHECK_EQ(MachineRepresentation::kFloat64, rep); |
+ } |
+ var_result.Bind(value); |
+ Goto(&done); |
+ } |
+ |
+ Bind(&if_smi); |
+ { |
+ Node* value = SmiToWord32(input); |
+ if (rep == MachineRepresentation::kFloat32) { |
+ value = RoundInt32ToFloat32(value); |
+ } else if (rep == MachineRepresentation::kFloat64) { |
+ value = ChangeInt32ToFloat64(value); |
+ } else { |
+ DCHECK_EQ(MachineRepresentation::kWord32, rep); |
+ if (elements_kind == UINT8_CLAMPED_ELEMENTS) { |
+ value = Int32ToUint8Clamped(value); |
+ } |
+ } |
+ var_result.Bind(value); |
+ Goto(&done); |
+ } |
+ |
+ Bind(&done); |
+ return var_result.value(); |
+} |
+ |
void CodeStubAssembler::EmitElementStore(Node* object, Node* key, Node* value, |
bool is_jsarray, |
ElementsKind elements_kind, |
@@ -5489,16 +5575,7 @@ void CodeStubAssembler::EmitElementStore(Node* object, Node* key, Node* value, |
// TODO(ishell): call ToNumber() on value and don't bailout but be careful |
// to call it only once if we decide to bailout because of bounds checks. |
- if (IsFixedFloatElementsKind(elements_kind)) { |
- // TODO(ishell): move float32 truncation into PrepareValueForWrite. |
- value = PrepareValueForWrite(value, Representation::Double(), bailout); |
- if (elements_kind == FLOAT32_ELEMENTS) { |
- value = TruncateFloat64ToFloat32(value); |
- } |
- } else { |
- // TODO(ishell): It's fine for word8/16/32 to truncate the result. |
- value = TryToIntptr(value, bailout); |
- } |
+ value = PrepareValueForWriteToTypedArray(value, elements_kind, bailout); |
// There must be no allocations between the buffer load and |
// and the actual store to backing store, because GC may decide that |
@@ -5552,7 +5629,7 @@ void CodeStubAssembler::EmitElementStore(Node* object, Node* key, Node* value, |
if (IsFastSmiElementsKind(elements_kind)) { |
GotoUnless(TaggedIsSmi(value), bailout); |
} else if (IsFastDoubleElementsKind(elements_kind)) { |
- value = PrepareValueForWrite(value, Representation::Double(), bailout); |
+ value = TryTaggedToFloat64(value, bailout); |
} |
if (IsGrowStoreMode(store_mode)) { |