OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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/runtime/runtime-utils.h" | 5 #include "src/runtime/runtime-utils.h" |
6 | 6 |
7 #include "src/arguments.h" | 7 #include "src/arguments.h" |
8 #include "src/factory.h" | 8 #include "src/factory.h" |
9 #include "src/messages.h" | 9 #include "src/messages.h" |
10 #include "src/objects-inl.h" | 10 #include "src/objects-inl.h" |
11 #include "src/runtime/runtime.h" | 11 #include "src/runtime/runtime.h" |
12 | 12 |
13 namespace v8 { | 13 namespace v8 { |
14 namespace internal { | 14 namespace internal { |
15 | 15 |
16 void Runtime::SetupArrayBuffer(Isolate* isolate, | |
17 Handle<JSArrayBuffer> array_buffer, | |
18 bool is_external, void* data, | |
19 size_t allocated_length, SharedFlag shared) { | |
20 DCHECK(array_buffer->GetInternalFieldCount() == | |
21 v8::ArrayBuffer::kInternalFieldCount); | |
22 for (int i = 0; i < v8::ArrayBuffer::kInternalFieldCount; i++) { | |
23 array_buffer->SetInternalField(i, Smi::FromInt(0)); | |
24 } | |
25 array_buffer->set_backing_store(data); | |
26 array_buffer->set_bit_field(0); | |
27 array_buffer->set_is_external(is_external); | |
28 array_buffer->set_is_neuterable(shared == SharedFlag::kNotShared); | |
29 array_buffer->set_is_shared(shared == SharedFlag::kShared); | |
30 | |
31 if (data && !is_external) { | |
32 isolate->heap()->RegisterNewArrayBuffer( | |
33 isolate->heap()->InNewSpace(*array_buffer), data, allocated_length); | |
34 } | |
35 | |
36 Handle<Object> byte_length = | |
37 isolate->factory()->NewNumberFromSize(allocated_length); | |
38 CHECK(byte_length->IsSmi() || byte_length->IsHeapNumber()); | |
39 array_buffer->set_byte_length(*byte_length); | |
40 } | |
41 | |
42 | |
43 bool Runtime::SetupArrayBufferAllocatingData(Isolate* isolate, | |
44 Handle<JSArrayBuffer> array_buffer, | |
45 size_t allocated_length, | |
46 bool initialize, | |
47 SharedFlag shared) { | |
48 void* data; | |
49 CHECK(isolate->array_buffer_allocator() != NULL); | |
50 // Prevent creating array buffers when serializing. | |
51 DCHECK(!isolate->serializer_enabled()); | |
52 if (allocated_length != 0) { | |
53 if (initialize) { | |
54 data = isolate->array_buffer_allocator()->Allocate(allocated_length); | |
55 } else { | |
56 data = isolate->array_buffer_allocator()->AllocateUninitialized( | |
57 allocated_length); | |
58 } | |
59 if (data == NULL) return false; | |
60 } else { | |
61 data = NULL; | |
62 } | |
63 | |
64 SetupArrayBuffer(isolate, array_buffer, false, data, allocated_length, | |
65 shared); | |
66 return true; | |
67 } | |
68 | |
69 | 16 |
70 RUNTIME_FUNCTION(Runtime_ArrayBufferInitialize) { | 17 RUNTIME_FUNCTION(Runtime_ArrayBufferInitialize) { |
71 HandleScope scope(isolate); | 18 HandleScope scope(isolate); |
72 DCHECK(args.length() == 3); | 19 DCHECK(args.length() == 3); |
73 CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, holder, 0); | 20 CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, holder, 0); |
74 CONVERT_NUMBER_ARG_HANDLE_CHECKED(byteLength, 1); | 21 CONVERT_NUMBER_ARG_HANDLE_CHECKED(byteLength, 1); |
75 CONVERT_BOOLEAN_ARG_CHECKED(is_shared, 2); | 22 CONVERT_BOOLEAN_ARG_CHECKED(is_shared, 2); |
76 if (!holder->byte_length()->IsUndefined()) { | 23 if (!holder->byte_length()->IsUndefined()) { |
77 // ArrayBuffer is already initialized; probably a fuzz test. | 24 // ArrayBuffer is already initialized; probably a fuzz test. |
78 return *holder; | 25 return *holder; |
79 } | 26 } |
80 size_t allocated_length = 0; | 27 size_t allocated_length = 0; |
81 if (!TryNumberToSize(isolate, *byteLength, &allocated_length)) { | 28 if (!TryNumberToSize(isolate, *byteLength, &allocated_length)) { |
82 THROW_NEW_ERROR_RETURN_FAILURE( | 29 THROW_NEW_ERROR_RETURN_FAILURE( |
83 isolate, NewRangeError(MessageTemplate::kInvalidArrayBufferLength)); | 30 isolate, NewRangeError(MessageTemplate::kInvalidArrayBufferLength)); |
84 } | 31 } |
85 if (!Runtime::SetupArrayBufferAllocatingData( | 32 if (!JSArrayBuffer::SetupAllocatingData( |
86 isolate, holder, allocated_length, true, | 33 holder, isolate, allocated_length, true, |
87 is_shared ? SharedFlag::kShared : SharedFlag::kNotShared)) { | 34 is_shared ? SharedFlag::kShared : SharedFlag::kNotShared)) { |
88 THROW_NEW_ERROR_RETURN_FAILURE( | 35 THROW_NEW_ERROR_RETURN_FAILURE( |
89 isolate, NewRangeError(MessageTemplate::kInvalidArrayBufferLength)); | 36 isolate, NewRangeError(MessageTemplate::kInvalidArrayBufferLength)); |
90 } | 37 } |
91 return *holder; | 38 return *holder; |
92 } | 39 } |
93 | 40 |
94 | 41 |
95 RUNTIME_FUNCTION(Runtime_ArrayBufferGetByteLength) { | 42 RUNTIME_FUNCTION(Runtime_ArrayBufferGetByteLength) { |
96 SealHandleScope shs(isolate); | 43 SealHandleScope shs(isolate); |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
232 Handle<JSArrayBuffer> buffer = Handle<JSArrayBuffer>::cast(maybe_buffer); | 179 Handle<JSArrayBuffer> buffer = Handle<JSArrayBuffer>::cast(maybe_buffer); |
233 holder->set_buffer(*buffer); | 180 holder->set_buffer(*buffer); |
234 | 181 |
235 Handle<FixedTypedArrayBase> elements = | 182 Handle<FixedTypedArrayBase> elements = |
236 isolate->factory()->NewFixedTypedArrayWithExternalPointer( | 183 isolate->factory()->NewFixedTypedArrayWithExternalPointer( |
237 static_cast<int>(length), array_type, | 184 static_cast<int>(length), array_type, |
238 static_cast<uint8_t*>(buffer->backing_store()) + byte_offset); | 185 static_cast<uint8_t*>(buffer->backing_store()) + byte_offset); |
239 holder->set_elements(*elements); | 186 holder->set_elements(*elements); |
240 } else { | 187 } else { |
241 Handle<JSArrayBuffer> buffer = isolate->factory()->NewJSArrayBuffer(); | 188 Handle<JSArrayBuffer> buffer = isolate->factory()->NewJSArrayBuffer(); |
242 Runtime::SetupArrayBuffer(isolate, buffer, true, NULL, byte_length, | 189 JSArrayBuffer::Setup(buffer, isolate, true, NULL, byte_length, |
243 SharedFlag::kNotShared); | 190 SharedFlag::kNotShared); |
244 holder->set_buffer(*buffer); | 191 holder->set_buffer(*buffer); |
245 Handle<FixedTypedArrayBase> elements = | 192 Handle<FixedTypedArrayBase> elements = |
246 isolate->factory()->NewFixedTypedArray(static_cast<int>(length), | 193 isolate->factory()->NewFixedTypedArray(static_cast<int>(length), |
247 array_type, initialize); | 194 array_type, initialize); |
248 holder->set_elements(*elements); | 195 holder->set_elements(*elements); |
249 } | 196 } |
250 return isolate->heap()->undefined_value(); | 197 return isolate->heap()->undefined_value(); |
251 } | 198 } |
252 | 199 |
253 | 200 |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
307 // If source is a typed array, this loop will always run to completion, | 254 // If source is a typed array, this loop will always run to completion, |
308 // so we are sure that the backing store will be initialized. | 255 // so we are sure that the backing store will be initialized. |
309 // Otherwise, the indexing operation might throw, so the loop will not | 256 // Otherwise, the indexing operation might throw, so the loop will not |
310 // run to completion and the typed array might remain partly initialized. | 257 // run to completion and the typed array might remain partly initialized. |
311 // However we further assume that the caller of this function is a typed array | 258 // However we further assume that the caller of this function is a typed array |
312 // constructor, and the exception will propagate out of the constructor, | 259 // constructor, and the exception will propagate out of the constructor, |
313 // therefore uninitialized memory will not be accessible by a user program. | 260 // therefore uninitialized memory will not be accessible by a user program. |
314 // | 261 // |
315 // TODO(dslomov): revise this once we support subclassing. | 262 // TODO(dslomov): revise this once we support subclassing. |
316 | 263 |
317 if (!Runtime::SetupArrayBufferAllocatingData(isolate, buffer, byte_length, | 264 if (!JSArrayBuffer::SetupAllocatingData(buffer, isolate, byte_length, |
318 false)) { | 265 false)) { |
319 THROW_NEW_ERROR_RETURN_FAILURE( | 266 THROW_NEW_ERROR_RETURN_FAILURE( |
320 isolate, NewRangeError(MessageTemplate::kInvalidArrayBufferLength)); | 267 isolate, NewRangeError(MessageTemplate::kInvalidArrayBufferLength)); |
321 } | 268 } |
322 | 269 |
323 holder->set_buffer(*buffer); | 270 holder->set_buffer(*buffer); |
324 holder->set_byte_offset(Smi::FromInt(0)); | 271 holder->set_byte_offset(Smi::FromInt(0)); |
325 Handle<Object> byte_length_obj( | 272 Handle<Object> byte_length_obj( |
326 isolate->factory()->NewNumberFromSize(byte_length)); | 273 isolate->factory()->NewNumberFromSize(byte_length)); |
327 holder->set_byte_length(*byte_length_obj); | 274 holder->set_byte_length(*byte_length_obj); |
328 holder->set_length(*length_obj); | 275 holder->set_length(*length_obj); |
(...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
735 DATA_VIEW_SETTER(Uint16, uint16_t) | 682 DATA_VIEW_SETTER(Uint16, uint16_t) |
736 DATA_VIEW_SETTER(Int16, int16_t) | 683 DATA_VIEW_SETTER(Int16, int16_t) |
737 DATA_VIEW_SETTER(Uint32, uint32_t) | 684 DATA_VIEW_SETTER(Uint32, uint32_t) |
738 DATA_VIEW_SETTER(Int32, int32_t) | 685 DATA_VIEW_SETTER(Int32, int32_t) |
739 DATA_VIEW_SETTER(Float32, float) | 686 DATA_VIEW_SETTER(Float32, float) |
740 DATA_VIEW_SETTER(Float64, double) | 687 DATA_VIEW_SETTER(Float64, double) |
741 | 688 |
742 #undef DATA_VIEW_SETTER | 689 #undef DATA_VIEW_SETTER |
743 } // namespace internal | 690 } // namespace internal |
744 } // namespace v8 | 691 } // namespace v8 |
OLD | NEW |