OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |