Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1584)

Side by Side Diff: src/builtins/builtins-typedarray.cc

Issue 2763473002: [typedarrays] Move %TypedArray%.prototype.slice to C++ (Closed)
Patch Set: Add tests Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 the V8 project authors. All rights reserved. 1 // Copyright 2016 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/builtins/builtins-utils.h" 5 #include "src/builtins/builtins-utils.h"
6 #include "src/builtins/builtins.h" 6 #include "src/builtins/builtins.h"
7 #include "src/counters.h" 7 #include "src/counters.h"
8 #include "src/elements.h" 8 #include "src/elements.h"
9 #include "src/objects-inl.h" 9 #include "src/objects-inl.h"
10 10
(...skipping 23 matching lines...) Expand all
34 // +Infinity / -Infinity 34 // +Infinity / -Infinity
35 DCHECK(!std::isnan(fp)); 35 DCHECK(!std::isnan(fp));
36 return fp < 0 ? minimum : maximum; 36 return fp < 0 ? minimum : maximum;
37 } 37 }
38 relative = static_cast<int64_t>(fp); 38 relative = static_cast<int64_t>(fp);
39 } 39 }
40 return relative < 0 ? std::max<int64_t>(relative + maximum, minimum) 40 return relative < 0 ? std::max<int64_t>(relative + maximum, minimum)
41 : std::min<int64_t>(relative, maximum); 41 : std::min<int64_t>(relative, maximum);
42 } 42 }
43 43
44 // ES7 section 22.2.4.6 TypedArrayCreate ( constructor, argumentList )
45 // Only for the case when argumentList is a list of a single number (size)
46 MaybeHandle<JSTypedArray> TypedArrayCreate(Isolate* isolate,
47 Handle<JSFunction> default_ctor,
48 int64_t size,
49 const char* method_name) {
50 // 1. Let newTypedArray be ? Construct(constructor, argumentList).
51 Handle<Object> new_obj;
52 {
53 const int argc = 1;
54 ScopedVector<Handle<Object>> argv(argc);
55 argv[0] = isolate->factory()->NewNumber(size);
56 ASSIGN_RETURN_ON_EXCEPTION(
57 isolate, new_obj, Execution::New((default_ctor), argc, argv.start()),
58 JSTypedArray);
59 }
60
61 // 2. Perform ? ValidateTypedArray(newTypedArray).
62 Handle<JSTypedArray> new_array;
63 ASSIGN_RETURN_ON_EXCEPTION(
64 isolate, new_array, JSTypedArray::Validate(isolate, new_obj, method_name),
65 JSTypedArray);
66
67 // 3. If newTypedArray.[[ArrayLength]] < size, throw a TypeError exception.
68 if (new_array->length_value() < size) {
69 const MessageTemplate::Template message =
70 MessageTemplate::kTypedArrayTooShort;
71 THROW_NEW_ERROR(isolate, NewTypeError(message), JSTypedArray);
72 }
73
74 // 4. Return newTypedArray.
75 return new_array;
76 }
77
78 // ES7 section 22.2.4.7 TypedArraySpeciesCreate ( exemplar, argumentList )
79 // Only for the case when argumentList is a list of a single number (size)
80 MaybeHandle<JSTypedArray> TypedArraySpeciesCreate(Isolate* isolate,
81 Handle<JSTypedArray> exemplar,
82 int64_t size,
83 const char* method_name) {
84 // 1. Assert: exemplar is an Object that has a [[TypedArrayName]] internal
85 // slot.
86 DCHECK(examplar->IsJSTypedArray());
87
88 // 2. Let defaultConstructor be the intrinsic object listed in column one of
89 // Table 51 for exemplar.[[TypedArrayName]].
90 Handle<JSFunction> default_ctor = isolate->uint8_array_fun();
91 switch (exemplar->type()) {
92 #define TYPED_ARRAY_CTOR(Type, type, TYPE, ctype, size) \
93 case kExternal##Type##Array: { \
94 default_ctor = isolate->type##_array_fun(); \
95 break; \
96 }
97
98 TYPED_ARRAYS(TYPED_ARRAY_CTOR)
99 #undef TYPED_ARRAY_CTOR
100 default:
101 UNREACHABLE();
102 }
103
104 // 3. Let constructor be ? SpeciesConstructor(exemplar, defaultConstructor).
105 Handle<Object> ctor;
106 ASSIGN_RETURN_ON_EXCEPTION(
107 isolate, ctor,
108 Object::SpeciesConstructor(isolate, exemplar, default_ctor),
109 JSTypedArray);
110
111 // 4. Return ? TypedArrayCreate(constructor, argumentList).
112 return TypedArrayCreate(isolate, Handle<JSFunction>::cast(ctor), size,
113 method_name);
114 }
115
44 } // namespace 116 } // namespace
45 117
46 BUILTIN(TypedArrayPrototypeCopyWithin) { 118 BUILTIN(TypedArrayPrototypeCopyWithin) {
47 HandleScope scope(isolate); 119 HandleScope scope(isolate);
48 120
49 Handle<JSTypedArray> array; 121 Handle<JSTypedArray> array;
50 const char* method = "%TypedArray%.prototype.copyWithin"; 122 const char* method = "%TypedArray%.prototype.copyWithin";
51 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( 123 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
52 isolate, array, JSTypedArray::Validate(isolate, args.receiver(), method)); 124 isolate, array, JSTypedArray::Validate(isolate, args.receiver(), method));
53 125
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
199 if (V8_UNLIKELY(array->WasNeutered())) return Smi::FromInt(-1); 271 if (V8_UNLIKELY(array->WasNeutered())) return Smi::FromInt(-1);
200 272
201 Handle<Object> search_element = args.atOrUndefined(isolate, 1); 273 Handle<Object> search_element = args.atOrUndefined(isolate, 1);
202 ElementsAccessor* elements = array->GetElementsAccessor(); 274 ElementsAccessor* elements = array->GetElementsAccessor();
203 Maybe<int64_t> result = elements->LastIndexOfValue( 275 Maybe<int64_t> result = elements->LastIndexOfValue(
204 isolate, array, search_element, static_cast<uint32_t>(index)); 276 isolate, array, search_element, static_cast<uint32_t>(index));
205 MAYBE_RETURN(result, isolate->heap()->exception()); 277 MAYBE_RETURN(result, isolate->heap()->exception());
206 return *isolate->factory()->NewNumberFromInt64(result.FromJust()); 278 return *isolate->factory()->NewNumberFromInt64(result.FromJust());
207 } 279 }
208 280
281 BUILTIN(TypedArrayPrototypeSlice) {
282 HandleScope scope(isolate);
283
284 Handle<JSTypedArray> array;
285 const char* method = "%TypedArray%.prototype.slice";
286 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
287 isolate, array, JSTypedArray::Validate(isolate, args.receiver(), method));
288
289 int64_t len = array->length_value();
290 int64_t start = 0;
291 int64_t end = len;
292 {
293 Handle<Object> num = args.atOrUndefined(isolate, 1);
294 if (!num->IsUndefined(isolate)) {
295 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, num,
296 Object::ToInteger(isolate, num));
297 start = CapRelativeIndex(num, 0, len);
298
299 num = args.atOrUndefined(isolate, 2);
300 if (!num->IsUndefined(isolate)) {
301 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, num,
302 Object::ToInteger(isolate, num));
303 end = CapRelativeIndex(num, 0, len);
304 }
305 }
306 }
307
308 int64_t count = std::max<int64_t>(end - start, 0);
309
310 Handle<JSTypedArray> result_array;
311 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
312 isolate, result_array,
313 TypedArraySpeciesCreate(isolate, array, count, method));
314
315 // TODO(cwhan.tunz): neutering check of the result_array should be done in
316 // TypedArraySpeciesCreate, but currently ValidateTypedArray does not throw
317 // for neutered buffer, so this is a temporary neutering check for the result
318 // array
319 if (V8_UNLIKELY(result_array->WasNeutered())) return *result_array;
320
321 // TODO(cwhan.tunz): should throw.
322 if (V8_UNLIKELY(array->WasNeutered())) return *result_array;
323
324 // Fast path for the same type result array
325 if (result_array->type() == array->type()) {
326 int64_t element_size = array->element_size();
327
328 Handle<FixedTypedArrayBase> src_elements(
329 FixedTypedArrayBase::cast(array->elements()));
330 Handle<FixedTypedArrayBase> result_elements(
331 FixedTypedArrayBase::cast(result_array->elements()));
Camillo Bruni 2017/03/20 13:37:25 nit: No need for handles here. Add "DisallowHeapAl
Choongwoo Han 2017/03/21 12:39:03 Done.
332
333 uint8_t* src = static_cast<uint8_t*>(src_elements->DataPtr());
334 uint8_t* result = static_cast<uint8_t*>(result_elements->DataPtr());
335 std::memcpy(result, src + start * element_size, count * element_size);
336 return *result_array;
337 }
338
339 // If the types of the two typed arrays are different, take a slow path
340 ElementsAccessor* source_accessor = array->GetElementsAccessor();
341 ElementsAccessor* result_accessor = result_array->GetElementsAccessor();
342 for (int64_t k = start; k < end; k++) {
343 Handle<Object> elem = source_accessor->Get(array, k);
344 result_accessor->Set(result_array, k, *elem);
Camillo Bruni 2017/03/20 13:37:25 If you push this loop down into the elements acces
Choongwoo Han 2017/03/21 12:39:03 What is the meaning of one virtual call? also, I'm
345 }
346 return *result_array;
347 }
348
209 } // namespace internal 349 } // namespace internal
210 } // namespace v8 350 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698