19 free(phantom_array_buffer->backing_store());
23 size_t allocated_length =
24 NumberToSize(isolate, phantom_array_buffer->byte_length());
27 ->AdjustAmountOfExternalAllocatedMemory(
28 -
static_cast<int64_t
>(allocated_length));
37 bool is_external,
void* data,
38 size_t allocated_length) {
39 DCHECK(array_buffer->GetInternalFieldCount() ==
44 array_buffer->set_backing_store(data);
46 array_buffer->set_is_external(is_external);
49 isolate->
factory()->NewNumberFromSize(allocated_length);
50 CHECK(byte_length->IsSmi() || byte_length->IsHeapNumber());
51 array_buffer->set_byte_length(*byte_length);
55 array_buffer->set_weak_first_view(isolate->
heap()->undefined_value());
61 size_t allocated_length,
65 if (allocated_length != 0) {
72 if (data ==
NULL)
return false;
80 ->AdjustAmountOfExternalAllocatedMemory(allocated_length);
87 Isolate* isolate = array_buffer->GetIsolate();
88 for (
Handle<Object> view_obj(array_buffer->weak_first_view(), isolate);
89 !view_obj->IsUndefined();) {
91 if (view->IsJSTypedArray()) {
92 JSTypedArray::cast(*view)->Neuter();
93 }
else if (view->IsJSDataView()) {
94 JSDataView::cast(*view)->Neuter();
98 view_obj =
handle(view->weak_next(), isolate);
100 array_buffer->Neuter();
106 DCHECK(args.length() == 2);
109 if (!holder->byte_length()->IsUndefined()) {
113 size_t allocated_length = 0;
116 isolate, NewRangeError(
"invalid_array_buffer_length",
117 HandleVector<Object>(
NULL, 0)));
122 isolate, NewRangeError(
"invalid_array_buffer_length",
123 HandleVector<Object>(
NULL, 0)));
130 SealHandleScope shs(isolate);
131 DCHECK(args.length() == 1);
133 return holder->byte_length();
139 DCHECK(args.length() == 3);
146 size_t target_length =
NumberToSize(isolate, target->byte_length());
148 if (target_length == 0)
return isolate->heap()->undefined_value();
150 size_t source_byte_length =
NumberToSize(isolate, source->byte_length());
153 uint8_t* source_data =
reinterpret_cast<uint8_t*
>(source->backing_store());
154 uint8_t* target_data =
reinterpret_cast<uint8_t*
>(target->backing_store());
155 CopyBytes(target_data, source_data + start, target_length);
156 return isolate->heap()->undefined_value();
162 DCHECK(args.length() == 1);
164 return isolate->heap()->ToBoolean(object->IsJSArrayBufferView());
170 DCHECK(args.length() == 1);
172 if (array_buffer->backing_store() ==
NULL) {
174 return isolate->heap()->undefined_value();
176 DCHECK(!array_buffer->is_external());
177 void* backing_store = array_buffer->backing_store();
178 size_t byte_length =
NumberToSize(isolate, array_buffer->byte_length());
179 array_buffer->set_is_external(
true);
182 return isolate->heap()->undefined_value();
189 size_t* element_size) {
191 #define ARRAY_ID_CASE(Type, type, TYPE, ctype, size) \
192 case ARRAY_ID_##TYPE: \
193 *array_type = kExternal##Type##Array; \
194 *external_elements_kind = EXTERNAL_##TYPE##_ELEMENTS; \
195 *fixed_elements_kind = TYPE##_ELEMENTS; \
196 *element_size = size; \
210 DCHECK(args.length() == 5);
221 size_t element_size = 1;
226 &fixed_elements_kind, &element_size);
227 RUNTIME_ASSERT(holder->map()->elements_kind() == fixed_elements_kind);
229 size_t byte_offset = 0;
230 size_t byte_length = 0;
234 if (maybe_buffer->IsJSArrayBuffer()) {
236 size_t array_buffer_byte_length =
239 RUNTIME_ASSERT(array_buffer_byte_length - byte_offset >= byte_length);
245 size_t length = byte_length / element_size;
249 isolate, NewRangeError(
"invalid_typed_array_length",
250 HandleVector<Object>(
NULL, 0)));
255 DCHECK(holder->GetInternalFieldCount() ==
260 Handle<Object> length_obj = isolate->factory()->NewNumberFromSize(length);
261 holder->set_length(*length_obj);
262 holder->set_byte_offset(*byte_offset_object);
263 holder->set_byte_length(*byte_length_object);
265 if (!maybe_buffer->IsNull()) {
267 holder->set_buffer(*buffer);
268 holder->set_weak_next(buffer->weak_first_view());
269 buffer->set_weak_first_view(*holder);
272 static_cast<int>(length), array_type,
273 static_cast<uint8_t*
>(buffer->backing_store()) + byte_offset);
280 holder->set_weak_next(isolate->heap()->undefined_value());
282 isolate->factory()->NewFixedTypedArray(
static_cast<int>(length),
284 holder->set_elements(*elements);
286 return isolate->heap()->undefined_value();
297 DCHECK(args.length() == 4);
307 size_t element_size = 1;
312 &fixed_elements_kind, &element_size);
314 RUNTIME_ASSERT(holder->map()->elements_kind() == fixed_elements_kind);
317 if (source->IsJSTypedArray() &&
318 JSTypedArray::cast(*source)->type() == array_type) {
319 length_obj =
Handle<Object>(JSTypedArray::cast(*source)->length(), isolate);
325 (length > (
kMaxInt / element_size))) {
327 isolate, NewRangeError(
"invalid_typed_array_length",
328 HandleVector<Object>(
NULL, 0)));
330 size_t byte_length = length * element_size;
332 DCHECK(holder->GetInternalFieldCount() ==
357 isolate, NewRangeError(
"invalid_array_buffer_length",
358 HandleVector<Object>(
NULL, 0)));
361 holder->set_buffer(*buffer);
364 isolate->factory()->NewNumberFromSize(byte_length));
365 holder->set_byte_length(*byte_length_obj);
366 holder->set_length(*length_obj);
367 holder->set_weak_next(buffer->weak_first_view());
368 buffer->set_weak_first_view(*holder);
371 static_cast<int>(length), array_type,
372 static_cast<uint8_t*
>(buffer->backing_store()));
377 if (source->IsJSTypedArray()) {
380 if (typed_array->type() == holder->type()) {
381 uint8_t* backing_store =
382 static_cast<uint8_t*
>(typed_array->GetBuffer()->backing_store());
383 size_t source_byte_offset =
385 memcpy(buffer->backing_store(), backing_store + source_byte_offset,
387 return isolate->heap()->true_value();
391 return isolate->heap()->false_value();
395 #define BUFFER_VIEW_GETTER(Type, getter, accessor) \
396 RUNTIME_FUNCTION(Runtime_##Type##Get##getter) { \
397 HandleScope scope(isolate); \
398 DCHECK(args.length() == 1); \
399 CONVERT_ARG_HANDLE_CHECKED(JS##Type, holder, 0); \
400 return holder->accessor(); \
408 #undef BUFFER_VIEW_GETTER
412 DCHECK(args.length() == 1);
414 return *holder->GetBuffer();
435 DCHECK(args.length() == 3);
436 if (!args[0]->IsJSTypedArray()) {
439 NewTypeError(
"not_typed_array", HandleVector<Object>(
NULL, 0)));
442 if (!args[1]->IsJSTypedArray())
453 size_t target_length =
NumberToSize(isolate, target->length());
454 size_t source_length =
NumberToSize(isolate, source->length());
455 size_t target_byte_length =
NumberToSize(isolate, target->byte_length());
456 size_t source_byte_length =
NumberToSize(isolate, source->byte_length());
457 if (offset > target_length || offset + source_length > target_length ||
458 offset + source_length < offset) {
460 isolate, NewRangeError(
"typed_array_set_source_too_large",
461 HandleVector<Object>(
NULL, 0)));
464 size_t target_offset =
NumberToSize(isolate, target->byte_offset());
465 size_t source_offset =
NumberToSize(isolate, source->byte_offset());
466 uint8_t* target_base =
467 static_cast<uint8_t*
>(target->GetBuffer()->backing_store()) +
469 uint8_t* source_base =
470 static_cast<uint8_t*
>(source->GetBuffer()->backing_store()) +
474 if (target->type() == source->type()) {
475 memmove(target_base + offset * target->element_size(), source_base,
481 if ((source_base <= target_base &&
482 source_base + source_byte_length > target_base) ||
483 (target_base <= source_base &&
484 target_base + target_byte_length > source_base)) {
486 DCHECK(target->GetBuffer()->backing_store() ==
487 source->GetBuffer()->backing_store());
496 DCHECK(args.length() == 0);
505 DCHECK(args.length() == 4);
511 DCHECK(holder->GetInternalFieldCount() ==
516 size_t buffer_length = 0;
531 holder->set_buffer(*buffer);
532 holder->set_byte_offset(*byte_offset);
533 holder->set_byte_length(*byte_length);
535 holder->set_weak_next(buffer->weak_first_view());
536 buffer->set_weak_first_view(*holder);
538 return isolate->heap()->undefined_value();
543 #ifdef V8_TARGET_LITTLE_ENDIAN
544 return !is_little_endian;
546 return is_little_endian;
552 inline void CopyBytes(uint8_t* target, uint8_t* source) {
553 for (
int i = 0;
i < n;
i++) {
554 *(target++) = *(source++);
560 inline void FlipBytes(uint8_t* target, uint8_t* source) {
561 source = source + (n - 1);
562 for (
int i = 0;
i < n;
i++) {
563 *(target++) = *(source--);
568 template <
typename T>
572 bool is_little_endian,
T* result) {
573 size_t byte_offset = 0;
579 size_t data_view_byte_offset =
581 size_t data_view_byte_length =
583 if (byte_offset +
sizeof(
T) > data_view_byte_length ||
584 byte_offset +
sizeof(
T) < byte_offset) {
590 uint8_t bytes[
sizeof(
T)];
594 size_t buffer_offset = data_view_byte_offset + byte_offset;
596 buffer_offset +
sizeof(
T));
598 static_cast<uint8_t*
>(buffer->backing_store()) + buffer_offset;
600 FlipBytes<sizeof(T)>(value.bytes, source);
602 CopyBytes<sizeof(T)>(value.bytes, source);
604 *result = value.data;
609 template <
typename T>
612 bool is_little_endian,
T data) {
613 size_t byte_offset = 0;
619 size_t data_view_byte_offset =
621 size_t data_view_byte_length =
623 if (byte_offset +
sizeof(
T) > data_view_byte_length ||
624 byte_offset +
sizeof(
T) < byte_offset) {
630 uint8_t bytes[
sizeof(
T)];
635 size_t buffer_offset = data_view_byte_offset + byte_offset;
637 buffer_offset +
sizeof(
T));
639 static_cast<uint8_t*
>(buffer->backing_store()) + buffer_offset;
641 FlipBytes<sizeof(T)>(target, value.bytes);
643 CopyBytes<sizeof(T)>(target, value.bytes);
649 #define DATA_VIEW_GETTER(TypeName, Type, Converter) \
650 RUNTIME_FUNCTION(Runtime_DataViewGet##TypeName) { \
651 HandleScope scope(isolate); \
652 DCHECK(args.length() == 3); \
653 CONVERT_ARG_HANDLE_CHECKED(JSDataView, holder, 0); \
654 CONVERT_NUMBER_ARG_HANDLE_CHECKED(offset, 1); \
655 CONVERT_BOOLEAN_ARG_CHECKED(is_little_endian, 2); \
657 if (DataViewGetValue(isolate, holder, offset, is_little_endian, \
659 return *isolate->factory()->Converter(result); \
661 THROW_NEW_ERROR_RETURN_FAILURE( \
662 isolate, NewRangeError("invalid_data_view_accessor_offset", \
663 HandleVector<Object>(NULL, 0))); \
676 #undef DATA_VIEW_GETTER
679 template <
typename T>
721 return static_cast<float>(value);
731 #define DATA_VIEW_SETTER(TypeName, Type) \
732 RUNTIME_FUNCTION(Runtime_DataViewSet##TypeName) { \
733 HandleScope scope(isolate); \
734 DCHECK(args.length() == 4); \
735 CONVERT_ARG_HANDLE_CHECKED(JSDataView, holder, 0); \
736 CONVERT_NUMBER_ARG_HANDLE_CHECKED(offset, 1); \
737 CONVERT_NUMBER_ARG_HANDLE_CHECKED(value, 2); \
738 CONVERT_BOOLEAN_ARG_CHECKED(is_little_endian, 3); \
739 Type v = DataViewConvertValue<Type>(value->Number()); \
740 if (DataViewSetValue(isolate, holder, offset, is_little_endian, v)) { \
741 return isolate->heap()->undefined_value(); \
743 THROW_NEW_ERROR_RETURN_FAILURE( \
744 isolate, NewRangeError("invalid_data_view_accessor_offset", \
745 HandleVector<Object>(NULL, 0))); \
758 #undef DATA_VIEW_SETTER
static const int kInternalFieldCount
virtual void * Allocate(size_t length)=0
Allocate |length| bytes.
virtual void Free(void *data, size_t length)=0
Free the memory block of size |length|, pointed to by |data|.
virtual void * AllocateUninitialized(size_t length)=0
Allocate |length| bytes.
static const int kInternalFieldCount
Isolate represents an isolated instance of the V8 engine.
The superclass of all JavaScript values and objects.
static const int kDataOffset
static Handle< T > cast(Handle< S > that)
void set_array_buffers_list(Object *object)
Object * array_buffers_list() const
static void SetMapAndElements(Handle< JSObject > object, Handle< Map > map, Handle< FixedArrayBase > elements)
static Handle< Map > GetElementsTransitionMap(Handle< JSObject > object, ElementsKind to_kind)
static void NeuterArrayBuffer(Handle< JSArrayBuffer > array_buffer)
static void SetupArrayBuffer(Isolate *isolate, Handle< JSArrayBuffer > array_buffer, bool is_external, void *data, size_t allocated_length)
static void ArrayIdToTypeAndSize(int array_id, ExternalArrayType *type, ElementsKind *external_elements_kind, ElementsKind *fixed_elements_kind, size_t *element_size)
static void FreeArrayBuffer(Isolate *isolate, JSArrayBuffer *phantom_array_buffer)
static bool SetupArrayBufferAllocatingData(Isolate *isolate, Handle< JSArrayBuffer > array_buffer, size_t allocated_length, bool initialize=true)
static const int kMaxValue
static Smi * FromInt(int value)
static v8::ArrayBuffer::Allocator * ArrayBufferAllocator()
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf map
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long enable alignment of csp to bytes on platforms which prefer the register to always be NULL
#define THROW_NEW_ERROR_RETURN_FAILURE(isolate, call)
#define DCHECK(condition)
static T DataViewConvertValue(double value)
static bool NeedToFlipBytes(bool is_little_endian)
uint32_t DoubleToUint32(double x)
bool IsExternalArrayElementsKind(ElementsKind kind)
int16_t DataViewConvertValue< int16_t >(double value)
@ TYPED_ARRAY_SET_TYPED_ARRAY_SAME_TYPE
@ TYPED_ARRAY_SET_TYPED_ARRAY_NONOVERLAPPING
@ TYPED_ARRAY_SET_TYPED_ARRAY_OVERLAPPING
@ TYPED_ARRAY_SET_NON_TYPED_ARRAY
Handle< T > handle(T *t, Isolate *isolate)
void FlipBytes(uint8_t *target, uint8_t *source)
static bool DataViewGetValue(Isolate *isolate, Handle< JSDataView > data_view, Handle< Object > byte_offset_obj, bool is_little_endian, T *result)
static bool DataViewSetValue(Isolate *isolate, Handle< JSDataView > data_view, Handle< Object > byte_offset_obj, bool is_little_endian, T data)
uint8_t DataViewConvertValue< uint8_t >(double value)
int32_t DoubleToInt32(double x)
float DataViewConvertValue< float >(double value)
double DataViewConvertValue< double >(double value)
int8_t DataViewConvertValue< int8_t >(double value)
size_t NumberToSize(Isolate *isolate, Object *number)
uint32_t DataViewConvertValue< uint32_t >(double value)
bool TryNumberToSize(Isolate *isolate, Object *number, size_t *result)
uint16_t DataViewConvertValue< uint16_t >(double value)
int32_t DataViewConvertValue< int32_t >(double value)
void CopyBytes(uint8_t *target, uint8_t *source)
Debugger support for the V8 JavaScript engine.
#define ARRAY_ID_CASE(Type, type, TYPE, ctype, size)
#define DATA_VIEW_GETTER(TypeName, Type, Converter)
#define DATA_VIEW_SETTER(TypeName, Type)
#define BUFFER_VIEW_GETTER(Type, getter, accessor)
#define CONVERT_ARG_CHECKED(Type, name, index)
#define RUNTIME_ASSERT(value)
#define CONVERT_ARG_HANDLE_CHECKED(Type, name, index)
#define CONVERT_NUMBER_ARG_HANDLE_CHECKED(name, index)
#define CONVERT_SMI_ARG_CHECKED(name, index)
#define DCHECK_OBJECT_SIZE(size)
#define T(name, string, precedence)