diff options
author | Michaël Zasso <targos@protonmail.com> | 2018-07-25 19:30:07 +0200 |
---|---|---|
committer | Michaël Zasso <targos@protonmail.com> | 2018-07-26 08:31:50 +0200 |
commit | 6a31d05340b22fc413ee83eaacd0a5565bbbe799 (patch) | |
tree | 78f9e1c2f417244842f6422f17e1816e70317100 /deps/v8/src/builtins/builtins-typed-array.cc | |
parent | 4d94bb2b1f72b6b612983a517a39c5545724a3ad (diff) | |
download | android-node-v8-6a31d05340b22fc413ee83eaacd0a5565bbbe799.tar.gz android-node-v8-6a31d05340b22fc413ee83eaacd0a5565bbbe799.tar.bz2 android-node-v8-6a31d05340b22fc413ee83eaacd0a5565bbbe799.zip |
deps: update V8 to 6.8.275.24
PR-URL: https://github.com/nodejs/node/pull/21079
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Yang Guo <yangguo@chromium.org>
Diffstat (limited to 'deps/v8/src/builtins/builtins-typed-array.cc')
-rw-r--r-- | deps/v8/src/builtins/builtins-typed-array.cc | 277 |
1 files changed, 277 insertions, 0 deletions
diff --git a/deps/v8/src/builtins/builtins-typed-array.cc b/deps/v8/src/builtins/builtins-typed-array.cc new file mode 100644 index 0000000000..6fcc279c66 --- /dev/null +++ b/deps/v8/src/builtins/builtins-typed-array.cc @@ -0,0 +1,277 @@ +// Copyright 2016 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "src/builtins/builtins-utils.h" +#include "src/builtins/builtins.h" +#include "src/counters.h" +#include "src/elements.h" +#include "src/objects-inl.h" + +namespace v8 { +namespace internal { + +// ----------------------------------------------------------------------------- +// ES6 section 22.2 TypedArray Objects + +// ES6 section 22.2.3.1 get %TypedArray%.prototype.buffer +BUILTIN(TypedArrayPrototypeBuffer) { + HandleScope scope(isolate); + CHECK_RECEIVER(JSTypedArray, typed_array, + "get %TypedArray%.prototype.buffer"); + return *typed_array->GetBuffer(); +} + +namespace { + +int64_t CapRelativeIndex(Handle<Object> num, int64_t minimum, int64_t maximum) { + int64_t relative; + if (V8_LIKELY(num->IsSmi())) { + relative = Smi::ToInt(*num); + } else { + DCHECK(num->IsHeapNumber()); + double fp = HeapNumber::cast(*num)->value(); + if (V8_UNLIKELY(!std::isfinite(fp))) { + // +Infinity / -Infinity + DCHECK(!std::isnan(fp)); + return fp < 0 ? minimum : maximum; + } + relative = static_cast<int64_t>(fp); + } + return relative < 0 ? std::max<int64_t>(relative + maximum, minimum) + : std::min<int64_t>(relative, maximum); +} + +} // namespace + +BUILTIN(TypedArrayPrototypeCopyWithin) { + HandleScope scope(isolate); + + Handle<JSTypedArray> array; + const char* method = "%TypedArray%.prototype.copyWithin"; + ASSIGN_RETURN_FAILURE_ON_EXCEPTION( + isolate, array, JSTypedArray::Validate(isolate, args.receiver(), method)); + + int64_t len = array->length_value(); + int64_t to = 0; + int64_t from = 0; + int64_t final = len; + + if (V8_LIKELY(args.length() > 1)) { + Handle<Object> num; + ASSIGN_RETURN_FAILURE_ON_EXCEPTION( + isolate, num, Object::ToInteger(isolate, args.at<Object>(1))); + to = CapRelativeIndex(num, 0, len); + + if (args.length() > 2) { + ASSIGN_RETURN_FAILURE_ON_EXCEPTION( + isolate, num, Object::ToInteger(isolate, args.at<Object>(2))); + from = CapRelativeIndex(num, 0, len); + + Handle<Object> end = args.atOrUndefined(isolate, 3); + if (!end->IsUndefined(isolate)) { + ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, num, + Object::ToInteger(isolate, end)); + final = CapRelativeIndex(num, 0, len); + } + } + } + + int64_t count = std::min<int64_t>(final - from, len - to); + if (count <= 0) return *array; + + // TypedArray buffer may have been transferred/detached during parameter + // processing above. Return early in this case, to prevent potential UAF error + // TODO(caitp): throw here, as though the full algorithm were performed (the + // throw would have come from ecma262/#sec-integerindexedelementget) + // (see ) + if (V8_UNLIKELY(array->WasNeutered())) return *array; + + // Ensure processed indexes are within array bounds + DCHECK_GE(from, 0); + DCHECK_LT(from, len); + DCHECK_GE(to, 0); + DCHECK_LT(to, len); + DCHECK_GE(len - count, 0); + + Handle<FixedTypedArrayBase> elements( + FixedTypedArrayBase::cast(array->elements())); + size_t element_size = array->element_size(); + to = to * element_size; + from = from * element_size; + count = count * element_size; + + uint8_t* data = static_cast<uint8_t*>(elements->DataPtr()); + std::memmove(data + to, data + from, count); + + return *array; +} + +BUILTIN(TypedArrayPrototypeFill) { + HandleScope scope(isolate); + + Handle<JSTypedArray> array; + const char* method = "%TypedArray%.prototype.fill"; + ASSIGN_RETURN_FAILURE_ON_EXCEPTION( + isolate, array, JSTypedArray::Validate(isolate, args.receiver(), method)); + ElementsKind kind = array->GetElementsKind(); + + Handle<Object> obj_value = args.atOrUndefined(isolate, 1); + if (kind == BIGINT64_ELEMENTS || kind == BIGUINT64_ELEMENTS) { + ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, obj_value, + BigInt::FromObject(isolate, obj_value)); + } else { + ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, obj_value, + Object::ToNumber(obj_value)); + } + + int64_t len = array->length_value(); + int64_t start = 0; + int64_t end = len; + + if (args.length() > 2) { + Handle<Object> num = args.atOrUndefined(isolate, 2); + if (!num->IsUndefined(isolate)) { + ASSIGN_RETURN_FAILURE_ON_EXCEPTION( + isolate, num, Object::ToInteger(isolate, num)); + start = CapRelativeIndex(num, 0, len); + + num = args.atOrUndefined(isolate, 3); + if (!num->IsUndefined(isolate)) { + ASSIGN_RETURN_FAILURE_ON_EXCEPTION( + isolate, num, Object::ToInteger(isolate, num)); + end = CapRelativeIndex(num, 0, len); + } + } + } + + int64_t count = end - start; + if (count <= 0) return *array; + + if (V8_UNLIKELY(array->WasNeutered())) return *array; + + // Ensure processed indexes are within array bounds + DCHECK_GE(start, 0); + DCHECK_LT(start, len); + DCHECK_GE(end, 0); + DCHECK_LE(end, len); + DCHECK_LE(count, len); + + return ElementsAccessor::ForKind(kind)->Fill(isolate, array, obj_value, + static_cast<uint32_t>(start), + static_cast<uint32_t>(end)); +} + +BUILTIN(TypedArrayPrototypeIncludes) { + HandleScope scope(isolate); + + Handle<JSTypedArray> array; + const char* method = "%TypedArray%.prototype.includes"; + ASSIGN_RETURN_FAILURE_ON_EXCEPTION( + isolate, array, JSTypedArray::Validate(isolate, args.receiver(), method)); + + if (args.length() < 2) return isolate->heap()->false_value(); + + int64_t len = array->length_value(); + if (len == 0) return isolate->heap()->false_value(); + + int64_t index = 0; + if (args.length() > 2) { + Handle<Object> num; + ASSIGN_RETURN_FAILURE_ON_EXCEPTION( + isolate, num, Object::ToInteger(isolate, args.at<Object>(2))); + index = CapRelativeIndex(num, 0, len); + } + + // TODO(cwhan.tunz): throw. See the above comment in CopyWithin. + if (V8_UNLIKELY(array->WasNeutered())) return isolate->heap()->false_value(); + + Handle<Object> search_element = args.atOrUndefined(isolate, 1); + ElementsAccessor* elements = array->GetElementsAccessor(); + Maybe<bool> result = elements->IncludesValue(isolate, array, search_element, + static_cast<uint32_t>(index), + static_cast<uint32_t>(len)); + MAYBE_RETURN(result, isolate->heap()->exception()); + return *isolate->factory()->ToBoolean(result.FromJust()); +} + +BUILTIN(TypedArrayPrototypeIndexOf) { + HandleScope scope(isolate); + + Handle<JSTypedArray> array; + const char* method = "%TypedArray%.prototype.indexOf"; + ASSIGN_RETURN_FAILURE_ON_EXCEPTION( + isolate, array, JSTypedArray::Validate(isolate, args.receiver(), method)); + + int64_t len = array->length_value(); + if (len == 0) return Smi::FromInt(-1); + + int64_t index = 0; + if (args.length() > 2) { + Handle<Object> num; + ASSIGN_RETURN_FAILURE_ON_EXCEPTION( + isolate, num, Object::ToInteger(isolate, args.at<Object>(2))); + index = CapRelativeIndex(num, 0, len); + } + + // TODO(cwhan.tunz): throw. See the above comment in CopyWithin. + if (V8_UNLIKELY(array->WasNeutered())) return Smi::FromInt(-1); + + Handle<Object> search_element = args.atOrUndefined(isolate, 1); + ElementsAccessor* elements = array->GetElementsAccessor(); + Maybe<int64_t> result = elements->IndexOfValue(isolate, array, search_element, + static_cast<uint32_t>(index), + static_cast<uint32_t>(len)); + MAYBE_RETURN(result, isolate->heap()->exception()); + return *isolate->factory()->NewNumberFromInt64(result.FromJust()); +} + +BUILTIN(TypedArrayPrototypeLastIndexOf) { + HandleScope scope(isolate); + + Handle<JSTypedArray> array; + const char* method = "%TypedArray%.prototype.lastIndexOf"; + ASSIGN_RETURN_FAILURE_ON_EXCEPTION( + isolate, array, JSTypedArray::Validate(isolate, args.receiver(), method)); + + int64_t len = array->length_value(); + if (len == 0) return Smi::FromInt(-1); + + int64_t index = len - 1; + if (args.length() > 2) { + Handle<Object> num; + ASSIGN_RETURN_FAILURE_ON_EXCEPTION( + isolate, num, Object::ToInteger(isolate, args.at<Object>(2))); + // Set a negative value (-1) for returning -1 if num is negative and + // len + num is still negative. Upper bound is len - 1. + index = std::min<int64_t>(CapRelativeIndex(num, -1, len), len - 1); + } + + if (index < 0) return Smi::FromInt(-1); + + // TODO(cwhan.tunz): throw. See the above comment in CopyWithin. + if (V8_UNLIKELY(array->WasNeutered())) return Smi::FromInt(-1); + + Handle<Object> search_element = args.atOrUndefined(isolate, 1); + ElementsAccessor* elements = array->GetElementsAccessor(); + Maybe<int64_t> result = elements->LastIndexOfValue( + isolate, array, search_element, static_cast<uint32_t>(index)); + MAYBE_RETURN(result, isolate->heap()->exception()); + return *isolate->factory()->NewNumberFromInt64(result.FromJust()); +} + +BUILTIN(TypedArrayPrototypeReverse) { + HandleScope scope(isolate); + + Handle<JSTypedArray> array; + const char* method = "%TypedArray%.prototype.reverse"; + ASSIGN_RETURN_FAILURE_ON_EXCEPTION( + isolate, array, JSTypedArray::Validate(isolate, args.receiver(), method)); + + ElementsAccessor* elements = array->GetElementsAccessor(); + elements->Reverse(*array); + return *array; +} + +} // namespace internal +} // namespace v8 |