Chromium Code Reviews| Index: runtime/lib/typeddata.cc |
| diff --git a/runtime/lib/typeddata.cc b/runtime/lib/typeddata.cc |
| index d9859751826042829d86f41cc4353fe26c166478..7b1e118dc76236ebc0787b6bcd3ad46f1c6671e1 100644 |
| --- a/runtime/lib/typeddata.cc |
| +++ b/runtime/lib/typeddata.cc |
| @@ -79,24 +79,34 @@ DEFINE_NATIVE_ENTRY(TypedData_length, 1) { |
| } |
| -#define COPY_DATA(type, dst, src) \ |
| - const type& dst_array = type::Cast(dst); \ |
| - const type& src_array = type::Cast(src); \ |
| - intptr_t element_size_in_bytes = dst_array.ElementSizeInBytes(); \ |
| - intptr_t length_in_bytes = length.Value() * element_size_in_bytes; \ |
| - intptr_t src_offset_in_bytes = src_start.Value() * element_size_in_bytes; \ |
| - intptr_t dst_offset_in_bytes = dst_start.Value() * element_size_in_bytes; \ |
| +#define COPY_DATA_AND_RETURN(dsttype, dst, srctype, src) \ |
|
Vyacheslav Egorov (Google)
2013/04/16 14:22:23
I'd prefer good old template to this huge macro.
|
| + const dsttype& dst_array = dsttype::Cast(dst); \ |
| + const srctype& src_array = srctype::Cast(src); \ |
| + intptr_t dst_element_size_in_bytes = dst_array.ElementSizeInBytes(); \ |
| + intptr_t src_element_size_in_bytes = src_array.ElementSizeInBytes(); \ |
| + intptr_t dst_offset_in_bytes = dst_start.Value() * dst_element_size_in_bytes;\ |
| + intptr_t src_offset_in_bytes = src_start.Value() * src_element_size_in_bytes;\ |
| + intptr_t length_in_bytes = length.Value() * src_element_size_in_bytes; \ |
| + if (src_element_size_in_bytes != dst_element_size_in_bytes) { \ |
| + return Bool::False().raw(); \ |
| + } \ |
| SetRangeCheck(src_offset_in_bytes, \ |
| length_in_bytes, \ |
| src_array.LengthInBytes(), \ |
| - element_size_in_bytes); \ |
| + src_element_size_in_bytes); \ |
| SetRangeCheck(dst_offset_in_bytes, \ |
| length_in_bytes, \ |
| dst_array.LengthInBytes(), \ |
| - element_size_in_bytes); \ |
| - type::Copy(dst_array, dst_offset_in_bytes, \ |
| - src_array, src_offset_in_bytes, \ |
| - length_in_bytes); |
| + dst_element_size_in_bytes); \ |
| + { \ |
| + NoGCScope no_gc; \ |
| + if (length_in_bytes > 0) { \ |
| + memmove(dst_array.DataAddr(dst_offset_in_bytes), \ |
| + src_array.DataAddr(src_offset_in_bytes), \ |
| + length_in_bytes); \ |
| + } \ |
| + return Bool::True().raw(); \ |
| + } |
| DEFINE_NATIVE_ENTRY(TypedData_setRange, 5) { |
| GET_NON_NULL_NATIVE_ARGUMENT(Instance, dst, arguments->NativeArgAt(0)); |
| @@ -112,17 +122,18 @@ DEFINE_NATIVE_ENTRY(TypedData_setRange, 5) { |
| args.SetAt(0, error); |
| Exceptions::ThrowByType(Exceptions::kArgument, args); |
| } |
| - if ((dst.IsTypedData() || dst.IsExternalTypedData()) && |
| - (dst.clazz() == src.clazz())) { |
| - if (dst.IsTypedData()) { |
| - ASSERT(src.IsTypedData()); |
| - COPY_DATA(TypedData, dst, src); |
| - } else { |
| - ASSERT(src.IsExternalTypedData()); |
| - ASSERT(dst.IsExternalTypedData()); |
| - COPY_DATA(ExternalTypedData, dst, src); |
| + if (dst.IsTypedData()) { |
| + if (src.IsTypedData()) { |
| + COPY_DATA_AND_RETURN(TypedData, dst, TypedData, src); |
| + } else if (src.IsExternalTypedData()) { |
| + COPY_DATA_AND_RETURN(TypedData, dst, ExternalTypedData, src); |
| + } |
| + } else if (dst.IsExternalTypedData()) { |
| + if (src.IsTypedData()) { |
| + COPY_DATA_AND_RETURN(ExternalTypedData, dst, TypedData, src); |
| + } else if (src.IsExternalTypedData()) { |
| + COPY_DATA_AND_RETURN(ExternalTypedData, dst, ExternalTypedData, src); |
| } |
| - return Bool::True().raw(); |
| } |
| return Bool::False().raw(); |
| } |