Move ArrayBuffer.prototype.slice implementation to C++
This will be useful for sharing the implementation with SharedArrayBuffer.prototype.slice. BUG=v8:5897 Review-Url: https://codereview.chromium.org/2697013009 Cr-Commit-Position: refs/heads/master@{#43503}
This commit is contained in:
parent
9c385f0405
commit
cb8fb46aa3
1
BUILD.gn
1
BUILD.gn
@ -438,7 +438,6 @@ action("js2c") {
|
||||
"src/js/v8natives.js",
|
||||
"src/js/array.js",
|
||||
"src/js/string.js",
|
||||
"src/js/arraybuffer.js",
|
||||
"src/js/typedarray.js",
|
||||
"src/js/collection.js",
|
||||
"src/js/weak-collection.js",
|
||||
|
@ -223,7 +223,7 @@ class Genesis BASE_EMBEDDED {
|
||||
|
||||
Handle<JSFunction> InstallArrayBuffer(Handle<JSObject> target,
|
||||
const char* name, Builtins::Name call,
|
||||
BuiltinFunctionId id);
|
||||
BuiltinFunctionId id, bool is_shared);
|
||||
Handle<JSFunction> InstallInternalArray(Handle<JSObject> target,
|
||||
const char* name,
|
||||
ElementsKind elements_kind);
|
||||
@ -2550,7 +2550,7 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
|
||||
{ // -- A r r a y B u f f e r
|
||||
Handle<JSFunction> array_buffer_fun = InstallArrayBuffer(
|
||||
global, "ArrayBuffer", Builtins::kArrayBufferPrototypeGetByteLength,
|
||||
BuiltinFunctionId::kArrayBufferByteLength);
|
||||
BuiltinFunctionId::kArrayBufferByteLength, false);
|
||||
InstallWithIntrinsicDefaultProto(isolate, array_buffer_fun,
|
||||
Context::ARRAY_BUFFER_FUN_INDEX);
|
||||
InstallSpeciesGetter(array_buffer_fun);
|
||||
@ -3688,7 +3688,7 @@ void Genesis::InitializeGlobal_harmony_sharedarraybuffer() {
|
||||
Handle<JSFunction> shared_array_buffer_fun =
|
||||
InstallArrayBuffer(global, "SharedArrayBuffer",
|
||||
Builtins::kSharedArrayBufferPrototypeGetByteLength,
|
||||
BuiltinFunctionId::kSharedArrayBufferByteLength);
|
||||
BuiltinFunctionId::kSharedArrayBufferByteLength, true);
|
||||
native_context()->set_shared_array_buffer_fun(*shared_array_buffer_fun);
|
||||
|
||||
Handle<String> name = factory->InternalizeUtf8String("Atomics");
|
||||
@ -3867,7 +3867,8 @@ void Genesis::InitializeGlobal_icu_case_mapping() {
|
||||
Handle<JSFunction> Genesis::InstallArrayBuffer(Handle<JSObject> target,
|
||||
const char* name,
|
||||
Builtins::Name call,
|
||||
BuiltinFunctionId id) {
|
||||
BuiltinFunctionId id,
|
||||
bool is_shared) {
|
||||
// Create the %ArrayBufferPrototype%
|
||||
// Setup the {prototype} with the given {name} for @@toStringTag.
|
||||
Handle<JSObject> prototype =
|
||||
@ -3897,6 +3898,12 @@ Handle<JSFunction> Genesis::InstallArrayBuffer(Handle<JSObject> target,
|
||||
SimpleInstallGetter(prototype, factory()->byte_length_string(), call, false,
|
||||
id);
|
||||
|
||||
// TODO(binji): support SharedArrayBuffer.prototype.slice as well.
|
||||
if (!is_shared) {
|
||||
SimpleInstallFunction(prototype, "slice",
|
||||
Builtins::kArrayBufferPrototypeSlice, 2, true);
|
||||
}
|
||||
|
||||
return array_buffer_fun;
|
||||
}
|
||||
|
||||
|
@ -11,6 +11,15 @@
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
#define CHECK_IS_NOT_SHARED_ARRAY_BUFFER(name, method) \
|
||||
if (name->is_shared()) { \
|
||||
THROW_NEW_ERROR_RETURN_FAILURE( \
|
||||
isolate, \
|
||||
NewTypeError(MessageTemplate::kIncompatibleMethodReceiver, \
|
||||
isolate->factory()->NewStringFromAsciiChecked(method), \
|
||||
name)); \
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// ES6 section 21.1 ArrayBuffer Objects
|
||||
|
||||
@ -63,17 +72,10 @@ BUILTIN(ArrayBufferConstructor_ConstructStub) {
|
||||
|
||||
// ES6 section 24.1.4.1 get ArrayBuffer.prototype.byteLength
|
||||
BUILTIN(ArrayBufferPrototypeGetByteLength) {
|
||||
const char* const kMethodName = "get ArrayBuffer.prototype.byteLength";
|
||||
HandleScope scope(isolate);
|
||||
CHECK_RECEIVER(JSArrayBuffer, array_buffer,
|
||||
"get ArrayBuffer.prototype.byteLength");
|
||||
|
||||
if (array_buffer->is_shared()) {
|
||||
THROW_NEW_ERROR_RETURN_FAILURE(
|
||||
isolate, NewTypeError(MessageTemplate::kIncompatibleMethodReceiver,
|
||||
isolate->factory()->NewStringFromAsciiChecked(
|
||||
"get ArrayBuffer.prototype.byteLength"),
|
||||
args.receiver()));
|
||||
}
|
||||
CHECK_RECEIVER(JSArrayBuffer, array_buffer, kMethodName);
|
||||
CHECK_IS_NOT_SHARED_ARRAY_BUFFER(array_buffer, kMethodName);
|
||||
// TODO(franzih): According to the ES6 spec, we should throw a TypeError
|
||||
// here if the JSArrayBuffer is detached.
|
||||
return array_buffer->byte_length();
|
||||
@ -87,5 +89,154 @@ BUILTIN(ArrayBufferIsView) {
|
||||
return isolate->heap()->ToBoolean(arg->IsJSArrayBufferView());
|
||||
}
|
||||
|
||||
// ES #sec-arraybuffer.prototype.slice
|
||||
// ArrayBuffer.prototype.slice ( start, end )
|
||||
BUILTIN(ArrayBufferPrototypeSlice) {
|
||||
const char* const kMethodName = "ArrayBuffer.prototype.slice";
|
||||
HandleScope scope(isolate);
|
||||
Handle<Object> start = args.at(1);
|
||||
Handle<Object> end = args.atOrUndefined(isolate, 2);
|
||||
|
||||
// 2. If Type(O) is not Object, throw a TypeError exception.
|
||||
// 3. If O does not have an [[ArrayBufferData]] internal slot, throw a
|
||||
// TypeError exception.
|
||||
CHECK_RECEIVER(JSArrayBuffer, array_buffer, kMethodName);
|
||||
// 4. If IsSharedArrayBuffer(O) is true, throw a TypeError exception.
|
||||
CHECK_IS_NOT_SHARED_ARRAY_BUFFER(array_buffer, kMethodName);
|
||||
|
||||
// 5. If IsDetachedBuffer(buffer) is true, throw a TypeError exception.
|
||||
if (array_buffer->was_neutered()) {
|
||||
THROW_NEW_ERROR_RETURN_FAILURE(
|
||||
isolate, NewTypeError(MessageTemplate::kDetachedOperation,
|
||||
isolate->factory()->NewStringFromAsciiChecked(
|
||||
kMethodName)));
|
||||
}
|
||||
|
||||
// 6. Let len be O.[[ArrayBufferByteLength]].
|
||||
double const len = array_buffer->byte_length()->Number();
|
||||
|
||||
// 7. Let relativeStart be ? ToInteger(start).
|
||||
Handle<Object> relative_start;
|
||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, relative_start,
|
||||
Object::ToInteger(isolate, start));
|
||||
|
||||
// 8. If relativeStart < 0, let first be max((len + relativeStart), 0); else
|
||||
// let first be min(relativeStart, len).
|
||||
double const first = (relative_start->Number() < 0)
|
||||
? Max(len + relative_start->Number(), 0.0)
|
||||
: Min(relative_start->Number(), len);
|
||||
Handle<Object> first_obj = isolate->factory()->NewNumber(first);
|
||||
|
||||
// 9. If end is undefined, let relativeEnd be len; else let relativeEnd be ?
|
||||
// ToInteger(end).
|
||||
double relative_end;
|
||||
if (end->IsUndefined(isolate)) {
|
||||
relative_end = len;
|
||||
} else {
|
||||
Handle<Object> relative_end_obj;
|
||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, relative_end_obj,
|
||||
Object::ToInteger(isolate, end));
|
||||
relative_end = relative_end_obj->Number();
|
||||
}
|
||||
|
||||
// 10. If relativeEnd < 0, let final be max((len + relativeEnd), 0); else let
|
||||
// final be min(relativeEnd, len).
|
||||
double const final_ = (relative_end < 0) ? Max(len + relative_end, 0.0)
|
||||
: Min(relative_end, len);
|
||||
|
||||
// 11. Let newLen be max(final-first, 0).
|
||||
double const new_len = Max(final_ - first, 0.0);
|
||||
Handle<Object> new_len_obj = isolate->factory()->NewNumber(new_len);
|
||||
|
||||
// 12. Let ctor be ? SpeciesConstructor(O, %ArrayBuffer%).
|
||||
Handle<JSFunction> arraybuffer_fun = isolate->array_buffer_fun();
|
||||
Handle<Object> ctor;
|
||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
|
||||
isolate, ctor,
|
||||
Object::SpeciesConstructor(
|
||||
isolate, Handle<JSReceiver>::cast(args.receiver()), arraybuffer_fun));
|
||||
|
||||
// 13. Let new be ? Construct(ctor, newLen).
|
||||
Handle<JSReceiver> new_;
|
||||
{
|
||||
const int argc = 1;
|
||||
|
||||
ScopedVector<Handle<Object>> argv(argc);
|
||||
argv[0] = new_len_obj;
|
||||
|
||||
Handle<Object> new_obj;
|
||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
|
||||
isolate, new_obj,
|
||||
Execution::New(Handle<JSFunction>::cast(ctor), argc, argv.start()));
|
||||
|
||||
new_ = Handle<JSReceiver>::cast(new_obj);
|
||||
}
|
||||
|
||||
// 14. If new does not have an [[ArrayBufferData]] internal slot, throw a
|
||||
// TypeError exception.
|
||||
if (!new_->IsJSArrayBuffer()) {
|
||||
THROW_NEW_ERROR_RETURN_FAILURE(
|
||||
isolate,
|
||||
NewTypeError(MessageTemplate::kIncompatibleMethodReceiver,
|
||||
isolate->factory()->NewStringFromAsciiChecked(kMethodName),
|
||||
new_));
|
||||
}
|
||||
|
||||
// 15. If IsSharedArrayBuffer(new) is true, throw a TypeError exception.
|
||||
Handle<JSArrayBuffer> new_array_buffer = Handle<JSArrayBuffer>::cast(new_);
|
||||
CHECK_IS_NOT_SHARED_ARRAY_BUFFER(new_array_buffer, kMethodName);
|
||||
|
||||
// 16. If IsDetachedBuffer(new) is true, throw a TypeError exception.
|
||||
if (new_array_buffer->was_neutered()) {
|
||||
THROW_NEW_ERROR_RETURN_FAILURE(
|
||||
isolate, NewTypeError(MessageTemplate::kDetachedOperation,
|
||||
isolate->factory()->NewStringFromAsciiChecked(
|
||||
kMethodName)));
|
||||
}
|
||||
|
||||
// 17. If SameValue(new, O) is true, throw a TypeError exception.
|
||||
if (new_->SameValue(*args.receiver())) {
|
||||
THROW_NEW_ERROR_RETURN_FAILURE(
|
||||
isolate, NewTypeError(MessageTemplate::kArrayBufferSpeciesThis));
|
||||
}
|
||||
|
||||
// 18. If new.[[ArrayBufferByteLength]] < newLen, throw a TypeError exception.
|
||||
if (new_array_buffer->byte_length()->Number() < new_len) {
|
||||
THROW_NEW_ERROR_RETURN_FAILURE(
|
||||
isolate, NewTypeError(MessageTemplate::kArrayBufferTooShort));
|
||||
}
|
||||
|
||||
// 19. NOTE: Side-effects of the above steps may have detached O.
|
||||
// 20. If IsDetachedBuffer(O) is true, throw a TypeError exception.
|
||||
if (array_buffer->was_neutered()) {
|
||||
THROW_NEW_ERROR_RETURN_FAILURE(
|
||||
isolate, NewTypeError(MessageTemplate::kDetachedOperation,
|
||||
isolate->factory()->NewStringFromAsciiChecked(
|
||||
kMethodName)));
|
||||
}
|
||||
|
||||
// 21. Let fromBuf be O.[[ArrayBufferData]].
|
||||
// 22. Let toBuf be new.[[ArrayBufferData]].
|
||||
// 23. Perform CopyDataBlockBytes(toBuf, 0, fromBuf, first, newLen).
|
||||
size_t first_size = 0, new_len_size = 0;
|
||||
CHECK(TryNumberToSize(*first_obj, &first_size));
|
||||
CHECK(TryNumberToSize(*new_len_obj, &new_len_size));
|
||||
DCHECK(NumberToSize(new_array_buffer->byte_length()) >= new_len_size);
|
||||
|
||||
if (new_len_size != 0) {
|
||||
size_t from_byte_length = NumberToSize(array_buffer->byte_length());
|
||||
USE(from_byte_length);
|
||||
DCHECK(first_size <= from_byte_length);
|
||||
DCHECK(from_byte_length - first_size >= new_len_size);
|
||||
uint8_t* from_data =
|
||||
reinterpret_cast<uint8_t*>(array_buffer->backing_store());
|
||||
uint8_t* to_data =
|
||||
reinterpret_cast<uint8_t*>(new_array_buffer->backing_store());
|
||||
CopyBytes(to_data, from_data + first_size, new_len_size);
|
||||
}
|
||||
|
||||
return *new_;
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
@ -289,6 +289,7 @@ class Isolate;
|
||||
CPP(ArrayBufferConstructor_ConstructStub) \
|
||||
CPP(ArrayBufferPrototypeGetByteLength) \
|
||||
CPP(ArrayBufferIsView) \
|
||||
CPP(ArrayBufferPrototypeSlice) \
|
||||
\
|
||||
/* AsyncFunction */ \
|
||||
TFJ(AsyncFunctionAwaitCaught, 3) \
|
||||
|
@ -1,81 +0,0 @@
|
||||
// Copyright 2013 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.
|
||||
|
||||
(function(global, utils) {
|
||||
|
||||
"use strict";
|
||||
|
||||
%CheckIsBootstrapping();
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Imports
|
||||
|
||||
var GlobalArrayBuffer = global.ArrayBuffer;
|
||||
var MaxSimple;
|
||||
var MinSimple;
|
||||
var SpeciesConstructor;
|
||||
|
||||
utils.Import(function(from) {
|
||||
MaxSimple = from.MaxSimple;
|
||||
MinSimple = from.MinSimple;
|
||||
SpeciesConstructor = from.SpeciesConstructor;
|
||||
});
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
// ES6 Draft 15.13.5.5.3
|
||||
function ArrayBufferSlice(start, end) {
|
||||
if (!IS_ARRAYBUFFER(this)) {
|
||||
throw %make_type_error(kIncompatibleMethodReceiver,
|
||||
'ArrayBuffer.prototype.slice', this);
|
||||
}
|
||||
|
||||
var relativeStart = TO_INTEGER(start);
|
||||
if (!IS_UNDEFINED(end)) {
|
||||
end = TO_INTEGER(end);
|
||||
}
|
||||
var first;
|
||||
var byte_length = %_ArrayBufferGetByteLength(this);
|
||||
if (relativeStart < 0) {
|
||||
first = MaxSimple(byte_length + relativeStart, 0);
|
||||
} else {
|
||||
first = MinSimple(relativeStart, byte_length);
|
||||
}
|
||||
var relativeEnd = IS_UNDEFINED(end) ? byte_length : end;
|
||||
var fin;
|
||||
if (relativeEnd < 0) {
|
||||
fin = MaxSimple(byte_length + relativeEnd, 0);
|
||||
} else {
|
||||
fin = MinSimple(relativeEnd, byte_length);
|
||||
}
|
||||
|
||||
if (fin < first) {
|
||||
fin = first;
|
||||
}
|
||||
var newLen = fin - first;
|
||||
var constructor = SpeciesConstructor(this, GlobalArrayBuffer, true);
|
||||
var result = new constructor(newLen);
|
||||
if (!IS_ARRAYBUFFER(result)) {
|
||||
throw %make_type_error(kIncompatibleMethodReceiver,
|
||||
'ArrayBuffer.prototype.slice', result);
|
||||
}
|
||||
// Checks for detached source/target ArrayBuffers are done inside of
|
||||
// %ArrayBufferSliceImpl; the reordering of checks does not violate
|
||||
// the spec because all exceptions thrown are TypeErrors.
|
||||
if (result === this) {
|
||||
throw %make_type_error(kArrayBufferSpeciesThis);
|
||||
}
|
||||
if (%_ArrayBufferGetByteLength(result) < newLen) {
|
||||
throw %make_type_error(kArrayBufferTooShort);
|
||||
}
|
||||
|
||||
%ArrayBufferSliceImpl(this, result, first, newLen);
|
||||
return result;
|
||||
}
|
||||
|
||||
utils.InstallFunctions(GlobalArrayBuffer.prototype, DONT_ENUM, [
|
||||
"slice", ArrayBufferSlice
|
||||
]);
|
||||
|
||||
})
|
@ -2331,6 +2331,42 @@ MaybeHandle<Object> Object::ArraySpeciesConstructor(
|
||||
}
|
||||
}
|
||||
|
||||
// ES6 section 7.3.20 SpeciesConstructor ( O, defaultConstructor )
|
||||
MUST_USE_RESULT MaybeHandle<Object> Object::SpeciesConstructor(
|
||||
Isolate* isolate, Handle<JSReceiver> recv,
|
||||
Handle<JSFunction> default_ctor) {
|
||||
Handle<Object> ctor_obj;
|
||||
ASSIGN_RETURN_ON_EXCEPTION(
|
||||
isolate, ctor_obj,
|
||||
JSObject::GetProperty(recv, isolate->factory()->constructor_string()),
|
||||
Object);
|
||||
|
||||
if (ctor_obj->IsUndefined(isolate)) return default_ctor;
|
||||
|
||||
if (!ctor_obj->IsJSReceiver()) {
|
||||
THROW_NEW_ERROR(isolate,
|
||||
NewTypeError(MessageTemplate::kConstructorNotReceiver),
|
||||
Object);
|
||||
}
|
||||
|
||||
Handle<JSReceiver> ctor = Handle<JSReceiver>::cast(ctor_obj);
|
||||
|
||||
Handle<Object> species;
|
||||
ASSIGN_RETURN_ON_EXCEPTION(
|
||||
isolate, species,
|
||||
JSObject::GetProperty(ctor, isolate->factory()->species_symbol()),
|
||||
Object);
|
||||
|
||||
if (species->IsNullOrUndefined(isolate)) {
|
||||
return default_ctor;
|
||||
}
|
||||
|
||||
if (species->IsConstructor()) return species;
|
||||
|
||||
THROW_NEW_ERROR(
|
||||
isolate, NewTypeError(MessageTemplate::kSpeciesNotConstructor), Object);
|
||||
}
|
||||
|
||||
bool Object::IterationHasObservableEffects() {
|
||||
// Check that this object is an array.
|
||||
if (!IsJSArray()) return true;
|
||||
|
@ -1437,6 +1437,11 @@ class Object {
|
||||
MUST_USE_RESULT static MaybeHandle<Object> ArraySpeciesConstructor(
|
||||
Isolate* isolate, Handle<Object> original_array);
|
||||
|
||||
// ES6 section 7.3.20 SpeciesConstructor ( O, defaultConstructor )
|
||||
MUST_USE_RESULT static MaybeHandle<Object> SpeciesConstructor(
|
||||
Isolate* isolate, Handle<JSReceiver> recv,
|
||||
Handle<JSFunction> default_ctor);
|
||||
|
||||
// Tries to convert an object to an array length. Returns true and sets the
|
||||
// output parameter if it succeeds.
|
||||
inline bool ToArrayLength(uint32_t* index);
|
||||
|
@ -1306,43 +1306,6 @@ RUNTIME_FUNCTION(Runtime_StringReplaceNonGlobalRegExpWithFunction) {
|
||||
|
||||
namespace {
|
||||
|
||||
// ES##sec-speciesconstructor
|
||||
// SpeciesConstructor ( O, defaultConstructor )
|
||||
MUST_USE_RESULT MaybeHandle<Object> SpeciesConstructor(
|
||||
Isolate* isolate, Handle<JSReceiver> recv,
|
||||
Handle<JSFunction> default_ctor) {
|
||||
Handle<Object> ctor_obj;
|
||||
ASSIGN_RETURN_ON_EXCEPTION(
|
||||
isolate, ctor_obj,
|
||||
JSObject::GetProperty(recv, isolate->factory()->constructor_string()),
|
||||
Object);
|
||||
|
||||
if (ctor_obj->IsUndefined(isolate)) return default_ctor;
|
||||
|
||||
if (!ctor_obj->IsJSReceiver()) {
|
||||
THROW_NEW_ERROR(isolate,
|
||||
NewTypeError(MessageTemplate::kConstructorNotReceiver),
|
||||
Object);
|
||||
}
|
||||
|
||||
Handle<JSReceiver> ctor = Handle<JSReceiver>::cast(ctor_obj);
|
||||
|
||||
Handle<Object> species;
|
||||
ASSIGN_RETURN_ON_EXCEPTION(
|
||||
isolate, species,
|
||||
JSObject::GetProperty(ctor, isolate->factory()->species_symbol()),
|
||||
Object);
|
||||
|
||||
if (species->IsNullOrUndefined(isolate)) {
|
||||
return default_ctor;
|
||||
}
|
||||
|
||||
if (species->IsConstructor()) return species;
|
||||
|
||||
THROW_NEW_ERROR(
|
||||
isolate, NewTypeError(MessageTemplate::kSpeciesNotConstructor), Object);
|
||||
}
|
||||
|
||||
MUST_USE_RESULT MaybeHandle<Object> ToUint32(Isolate* isolate,
|
||||
Handle<Object> object,
|
||||
uint32_t* out) {
|
||||
@ -1384,7 +1347,7 @@ RUNTIME_FUNCTION(Runtime_RegExpSplit) {
|
||||
Handle<JSFunction> regexp_fun = isolate->regexp_function();
|
||||
Handle<Object> ctor;
|
||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
|
||||
isolate, ctor, SpeciesConstructor(isolate, recv, regexp_fun));
|
||||
isolate, ctor, Object::SpeciesConstructor(isolate, recv, regexp_fun));
|
||||
|
||||
Handle<Object> flags_obj;
|
||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
|
||||
|
@ -21,39 +21,6 @@ RUNTIME_FUNCTION(Runtime_ArrayBufferGetByteLength) {
|
||||
}
|
||||
|
||||
|
||||
RUNTIME_FUNCTION(Runtime_ArrayBufferSliceImpl) {
|
||||
HandleScope scope(isolate);
|
||||
DCHECK_EQ(4, args.length());
|
||||
CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, source, 0);
|
||||
CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, target, 1);
|
||||
CONVERT_NUMBER_ARG_HANDLE_CHECKED(first, 2);
|
||||
CONVERT_NUMBER_ARG_HANDLE_CHECKED(new_length, 3);
|
||||
|
||||
if (source->was_neutered() || target->was_neutered()) {
|
||||
THROW_NEW_ERROR_RETURN_FAILURE(
|
||||
isolate, NewTypeError(MessageTemplate::kDetachedOperation,
|
||||
isolate->factory()->NewStringFromAsciiChecked(
|
||||
"ArrayBuffer.prototype.slice")));
|
||||
}
|
||||
|
||||
CHECK(!source.is_identical_to(target));
|
||||
size_t start = 0, target_length = 0;
|
||||
CHECK(TryNumberToSize(*first, &start));
|
||||
CHECK(TryNumberToSize(*new_length, &target_length));
|
||||
CHECK(NumberToSize(target->byte_length()) >= target_length);
|
||||
|
||||
if (target_length == 0) return isolate->heap()->undefined_value();
|
||||
|
||||
size_t source_byte_length = NumberToSize(source->byte_length());
|
||||
CHECK(start <= source_byte_length);
|
||||
CHECK(source_byte_length - start >= target_length);
|
||||
uint8_t* source_data = reinterpret_cast<uint8_t*>(source->backing_store());
|
||||
uint8_t* target_data = reinterpret_cast<uint8_t*>(target->backing_store());
|
||||
CopyBytes(target_data, source_data + start, target_length);
|
||||
return isolate->heap()->undefined_value();
|
||||
}
|
||||
|
||||
|
||||
RUNTIME_FUNCTION(Runtime_ArrayBufferNeuter) {
|
||||
HandleScope scope(isolate);
|
||||
DCHECK_EQ(1, args.length());
|
||||
|
@ -615,7 +615,6 @@ namespace internal {
|
||||
|
||||
#define FOR_EACH_INTRINSIC_TYPEDARRAY(F) \
|
||||
F(ArrayBufferGetByteLength, 1, 1) \
|
||||
F(ArrayBufferSliceImpl, 4, 1) \
|
||||
F(ArrayBufferNeuter, 1, 1) \
|
||||
F(TypedArrayInitialize, 6, 1) \
|
||||
F(TypedArrayInitializeFromArrayLike, 4, 1) \
|
||||
|
@ -2266,7 +2266,6 @@
|
||||
'js/v8natives.js',
|
||||
'js/array.js',
|
||||
'js/string.js',
|
||||
'js/arraybuffer.js',
|
||||
'js/typedarray.js',
|
||||
'js/collection.js',
|
||||
'js/weak-collection.js',
|
||||
|
Loading…
Reference in New Issue
Block a user