OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | |
2 // for details. All rights reserved. Use of this source code is governed by a | |
3 // BSD-style license that can be found in the LICENSE file. | |
4 | |
5 #include "vm/bootstrap_natives.h" | |
6 | |
7 #include "include/dart_api.h" | |
8 | |
9 #include "vm/bigint_operations.h" | |
10 #include "vm/exceptions.h" | |
11 #include "vm/native_entry.h" | |
12 #include "vm/object.h" | |
13 | |
14 namespace dart { | |
15 | |
16 // ByteArray | |
17 | |
18 // Checks to see if (index * num_bytes) is in the range | |
19 // [0..array.ByteLength()). without the risk of integer overflow. If | |
20 // the index is out of range, then a RangeError is thrown. | |
21 static void RangeCheck(const ByteArray& array, | |
22 intptr_t index, | |
23 intptr_t num_bytes) { | |
24 if (!Utils::RangeCheck(index, num_bytes, array.ByteLength())) { | |
25 const String& error = String::Handle(String::NewFormatted( | |
26 "index (%"Pd") must be in the range [0..%"Pd")", | |
27 (index / num_bytes), (array.ByteLength() / num_bytes))); | |
28 const Array& args = Array::Handle(Array::New(1)); | |
29 args.SetAt(0, error); | |
30 Exceptions::ThrowByType(Exceptions::kRange, args); | |
31 } | |
32 } | |
33 | |
34 | |
35 // Checks to see if a length is in the range [0..max]. If the length | |
36 // is out of range, then an ArgumentError is thrown. | |
37 static void LengthCheck(intptr_t len, intptr_t max) { | |
38 if (len < 0 || len > max) { | |
39 const String& error = String::Handle(String::NewFormatted( | |
40 "length (%"Pd") must be in the range [0..%"Pd"]", len, max)); | |
41 const Array& args = Array::Handle(Array::New(1)); | |
42 args.SetAt(0, error); | |
43 Exceptions::ThrowByType(Exceptions::kArgument, args); | |
44 } | |
45 } | |
46 | |
47 | |
48 #define GETTER_ARGUMENTS(ArrayT, ValueT) \ | |
49 GET_NON_NULL_NATIVE_ARGUMENT(ArrayT, array, arguments->NativeArgAt(0)); \ | |
50 GET_NON_NULL_NATIVE_ARGUMENT(Smi, index, arguments->NativeArgAt(1)); | |
51 | |
52 | |
53 #define SETTER_ARGUMENTS(ArrayT, ObjectT, ValueT) \ | |
54 GET_NON_NULL_NATIVE_ARGUMENT(ArrayT, array, arguments->NativeArgAt(0)); \ | |
55 GET_NON_NULL_NATIVE_ARGUMENT(Smi, index, arguments->NativeArgAt(1)); \ | |
56 GET_NON_NULL_NATIVE_ARGUMENT( \ | |
57 ObjectT, value_object, arguments->NativeArgAt(2)); | |
58 | |
59 | |
60 #define GETTER(ArrayT, ObjectT, ValueT) \ | |
61 GETTER_ARGUMENTS(ArrayT, ValueT); \ | |
62 RangeCheck(array, index.Value() * sizeof(ValueT), sizeof(ValueT)); \ | |
63 ValueT result = array.At(index.Value()); \ | |
64 return ObjectT::New(result); | |
65 | |
66 | |
67 #define SETTER(ArrayT, ObjectT, Getter, ValueT) \ | |
68 SETTER_ARGUMENTS(ArrayT, ObjectT, ValueT); \ | |
69 RangeCheck(array, index.Value() * sizeof(ValueT), sizeof(ValueT)); \ | |
70 ValueT value = value_object.Getter(); \ | |
71 array.SetAt(index.Value(), value); \ | |
72 return Object::null(); | |
73 | |
74 | |
75 #define UNALIGNED_GETTER(ArrayT, ObjectT, ValueT) \ | |
76 GETTER_ARGUMENTS(ArrayT, ValueT); \ | |
77 RangeCheck(array, index.Value(), sizeof(ValueT)); \ | |
78 ValueT result; \ | |
79 ByteArray::Copy(&result, array, index.Value(), sizeof(ValueT)); \ | |
80 return ObjectT::New(result); | |
81 | |
82 | |
83 #define UNALIGNED_SETTER(ArrayT, ObjectT, Getter, ValueT) \ | |
84 SETTER_ARGUMENTS(ArrayT, ObjectT, ValueT); \ | |
85 RangeCheck(array, index.Value(), sizeof(ValueT)); \ | |
86 ValueT src = value_object.Getter(); \ | |
87 ByteArray::Copy(array, index.Value(), &src, sizeof(ValueT)); \ | |
88 return Integer::New(index.Value() + sizeof(ValueT)); | |
89 | |
90 | |
91 #define SCALED_UNALIGNED_GETTER(ArrayT, ObjectT, ValueT) \ | |
92 GETTER_ARGUMENTS(ArrayT, ValueT); \ | |
93 RangeCheck(array, index.Value() * sizeof(ValueT), sizeof(ValueT)); \ | |
94 ValueT result; \ | |
95 ByteArray::Copy(&result, array, \ | |
96 index.Value() * sizeof(ValueT), sizeof(ValueT)); \ | |
97 return ObjectT::New(result); | |
98 | |
99 | |
100 #define SCALED_UNALIGNED_SETTER(ArrayT, ObjectT, Getter, ValueT) \ | |
101 SETTER_ARGUMENTS(ArrayT, ObjectT, ValueT); \ | |
102 RangeCheck(array, index.Value() * sizeof(ValueT), sizeof(ValueT)); \ | |
103 ValueT src = value_object.Getter(); \ | |
104 ByteArray::Copy(array, index.Value() * sizeof(ValueT), &src, sizeof(ValueT));\ | |
105 return Integer::New(index.Value() + sizeof(ValueT)); | |
106 | |
107 | |
108 #define UINT64_TO_INTEGER(value, integer) \ | |
109 if (value > static_cast<uint64_t>(Mint::kMaxValue)) { \ | |
110 result = BigintOperations::NewFromUint64(value); \ | |
111 } else if (value > static_cast<uint64_t>(Smi::kMaxValue)) { \ | |
112 result = Mint::New(value); \ | |
113 } else { \ | |
114 result = Smi::New(value); \ | |
115 } | |
116 | |
117 | |
118 #define GETTER_UINT64(ArrayT) \ | |
119 GETTER_ARGUMENTS(ArrayT, uint64_t); \ | |
120 intptr_t size = sizeof(uint64_t); \ | |
121 RangeCheck(array, index.Value() * size, size); \ | |
122 uint64_t value = array.At(index.Value()); \ | |
123 Integer& result = Integer::Handle(); \ | |
124 UINT64_TO_INTEGER(value, result); \ | |
125 return result.raw(); | |
126 | |
127 | |
128 #define UNALIGNED_GETTER_UINT64(ArrayT) \ | |
129 GETTER_ARGUMENTS(ArrayT, uint64_t); \ | |
130 RangeCheck(array, index.Value(), sizeof(uint64_t)); \ | |
131 uint64_t value; \ | |
132 ByteArray::Copy(&value, array, index.Value(), sizeof(uint64_t)); \ | |
133 Integer& result = Integer::Handle(); \ | |
134 UINT64_TO_INTEGER(value, result); \ | |
135 return result.raw(); | |
136 | |
137 | |
138 #define INTEGER_TO_UINT64(integer, uint64) \ | |
139 if (integer.IsBigint()) { \ | |
140 const Bigint& bigint = Bigint::Cast(integer); \ | |
141 ASSERT(BigintOperations::FitsIntoUint64(bigint)); \ | |
142 value = BigintOperations::AbsToUint64(bigint); \ | |
143 } else { \ | |
144 ASSERT(integer.IsMint() || integer.IsSmi()); \ | |
145 value = integer.AsInt64Value(); \ | |
146 } \ | |
147 | |
148 | |
149 #define SETTER_UINT64(ArrayT) \ | |
150 SETTER_ARGUMENTS(ArrayT, Integer, uint64_t); \ | |
151 intptr_t size = sizeof(uint64_t); \ | |
152 RangeCheck(array, index.Value() * size, size); \ | |
153 uint64_t value; \ | |
154 INTEGER_TO_UINT64(value_object, value); \ | |
155 array.SetAt(index.Value(), value); \ | |
156 return Object::null(); | |
157 | |
158 | |
159 #define UNALIGNED_SETTER_UINT64(ArrayT) \ | |
160 SETTER_ARGUMENTS(ArrayT, Integer, uint64_t); \ | |
161 RangeCheck(array, index.Value(), sizeof(uint64_t)); \ | |
162 uint64_t value; \ | |
163 INTEGER_TO_UINT64(value_object, value); \ | |
164 ByteArray::Copy(array, index.Value(), &value, sizeof(uint64_t)); \ | |
165 return Integer::New(index.Value() + sizeof(uint64_t)); | |
166 | |
167 | |
168 DEFINE_NATIVE_ENTRY(ByteArray_getLength, 1) { | |
169 GET_NON_NULL_NATIVE_ARGUMENT(ByteArray, array, arguments->NativeArgAt(0)); | |
170 return Smi::New(array.Length()); | |
171 } | |
172 | |
173 | |
174 DEFINE_NATIVE_ENTRY(ByteArray_getInt8, 2) { | |
175 UNALIGNED_GETTER(ByteArray, Smi, int8_t); | |
176 } | |
177 | |
178 | |
179 DEFINE_NATIVE_ENTRY(ByteArray_setInt8, 3) { | |
180 UNALIGNED_SETTER(ByteArray, Smi, Value, int8_t); | |
181 } | |
182 | |
183 | |
184 DEFINE_NATIVE_ENTRY(ByteArray_getUint8, 2) { | |
185 UNALIGNED_GETTER(ByteArray, Smi, uint8_t); | |
186 } | |
187 | |
188 | |
189 DEFINE_NATIVE_ENTRY(ByteArray_setUint8, 3) { | |
190 UNALIGNED_SETTER(ByteArray, Smi, Value, uint8_t); | |
191 } | |
192 | |
193 | |
194 DEFINE_NATIVE_ENTRY(ByteArray_getInt16, 2) { | |
195 UNALIGNED_GETTER(ByteArray, Smi, int16_t); | |
196 } | |
197 | |
198 | |
199 DEFINE_NATIVE_ENTRY(ByteArray_setInt16, 3) { | |
200 UNALIGNED_SETTER(ByteArray, Smi, Value, int16_t); | |
201 } | |
202 | |
203 | |
204 DEFINE_NATIVE_ENTRY(ByteArray_getUint16, 2) { | |
205 UNALIGNED_GETTER(ByteArray, Smi, uint16_t); | |
206 } | |
207 | |
208 | |
209 DEFINE_NATIVE_ENTRY(ByteArray_setUint16, 3) { | |
210 UNALIGNED_SETTER(ByteArray, Smi, Value, uint16_t); | |
211 } | |
212 | |
213 | |
214 DEFINE_NATIVE_ENTRY(ByteArray_getInt32, 2) { | |
215 UNALIGNED_GETTER(ByteArray, Integer, int32_t); | |
216 } | |
217 | |
218 | |
219 DEFINE_NATIVE_ENTRY(ByteArray_setInt32, 3) { | |
220 UNALIGNED_SETTER(ByteArray, Integer, AsInt64Value, int32_t); | |
221 } | |
222 | |
223 | |
224 DEFINE_NATIVE_ENTRY(ByteArray_getUint32, 2) { | |
225 UNALIGNED_GETTER(ByteArray, Integer, uint32_t); | |
226 } | |
227 | |
228 | |
229 DEFINE_NATIVE_ENTRY(ByteArray_setUint32, 3) { | |
230 UNALIGNED_SETTER(ByteArray, Integer, AsInt64Value, uint32_t); | |
231 } | |
232 | |
233 | |
234 DEFINE_NATIVE_ENTRY(ByteArray_getInt64, 2) { | |
235 UNALIGNED_GETTER(ByteArray, Integer, int64_t); | |
236 } | |
237 | |
238 | |
239 DEFINE_NATIVE_ENTRY(ByteArray_setInt64, 3) { | |
240 UNALIGNED_SETTER(ByteArray, Integer, AsInt64Value, int64_t); | |
241 } | |
242 | |
243 | |
244 DEFINE_NATIVE_ENTRY(ByteArray_getUint64, 2) { | |
245 UNALIGNED_GETTER_UINT64(ByteArray); | |
246 } | |
247 | |
248 | |
249 DEFINE_NATIVE_ENTRY(ByteArray_setUint64, 3) { | |
250 UNALIGNED_SETTER_UINT64(ByteArray); | |
251 } | |
252 | |
253 | |
254 DEFINE_NATIVE_ENTRY(ByteArray_getFloat32, 2) { | |
255 UNALIGNED_GETTER(ByteArray, Double, float); | |
256 } | |
257 | |
258 | |
259 DEFINE_NATIVE_ENTRY(ByteArray_setFloat32, 3) { | |
260 UNALIGNED_SETTER(ByteArray, Double, value, float); | |
261 } | |
262 | |
263 | |
264 DEFINE_NATIVE_ENTRY(ByteArray_getFloat64, 2) { | |
265 UNALIGNED_GETTER(ByteArray, Double, double); | |
266 } | |
267 | |
268 | |
269 DEFINE_NATIVE_ENTRY(ByteArray_setFloat64, 3) { | |
270 UNALIGNED_SETTER(ByteArray, Double, value, double); | |
271 } | |
272 | |
273 | |
274 DEFINE_NATIVE_ENTRY(ByteArray_setRange, 5) { | |
275 ByteArray& dst = ByteArray::CheckedHandle(arguments->NativeArgAt(0)); | |
276 GET_NON_NULL_NATIVE_ARGUMENT(Smi, dst_start, arguments->NativeArgAt(1)); | |
277 GET_NON_NULL_NATIVE_ARGUMENT(Smi, length, arguments->NativeArgAt(2)); | |
278 GET_NON_NULL_NATIVE_ARGUMENT(ByteArray, src, arguments->NativeArgAt(3)); | |
279 GET_NON_NULL_NATIVE_ARGUMENT(Smi, src_start, arguments->NativeArgAt(4)); | |
280 intptr_t length_value = length.Value(); | |
281 intptr_t src_start_value = src_start.Value(); | |
282 intptr_t dst_start_value = dst_start.Value(); | |
283 if (length_value < 0) { | |
284 const String& error = String::Handle(String::NewFormatted( | |
285 "length (%"Pd") must be non-negative", length_value)); | |
286 const Array& args = Array::Handle(Array::New(1)); | |
287 args.SetAt(0, error); | |
288 Exceptions::ThrowByType(Exceptions::kArgument, args); | |
289 } | |
290 RangeCheck(src, src_start_value, length_value); | |
291 RangeCheck(dst, dst_start_value, length_value); | |
292 ByteArray::Copy(dst, dst_start_value, src, src_start_value, length_value); | |
293 return Object::null(); | |
294 } | |
295 | |
296 | |
297 static void PeerFinalizer(Dart_Handle handle, void* peer) { | |
298 Dart_DeletePersistentHandle(handle); | |
299 OS::AlignedFree(peer); | |
300 } | |
301 | |
302 | |
303 // Int8Array | |
304 | |
305 DEFINE_NATIVE_ENTRY(Int8Array_new, 1) { | |
306 GET_NON_NULL_NATIVE_ARGUMENT(Smi, length, arguments->NativeArgAt(0)); | |
307 intptr_t len = length.Value(); | |
308 LengthCheck(len, Int8Array::kMaxElements); | |
309 return Int8Array::New(len); | |
310 } | |
311 | |
312 | |
313 DEFINE_NATIVE_ENTRY(Int8List_newTransferable, 1) { | |
314 const int kAlignment = 16; | |
315 GET_NON_NULL_NATIVE_ARGUMENT(Smi, length, arguments->NativeArgAt(0)); | |
316 intptr_t len = length.Value(); | |
317 LengthCheck(len, Int8Array::kMaxElements); | |
318 int8_t* bytes = OS::AllocateAlignedArray<int8_t>(len, kAlignment); | |
319 const ExternalInt8Array& obj = | |
320 ExternalInt8Array::Handle(ExternalInt8Array::New(bytes, len)); | |
321 obj.AddFinalizer(bytes, PeerFinalizer); | |
322 return obj.raw(); | |
323 } | |
324 | |
325 | |
326 DEFINE_NATIVE_ENTRY(Int8Array_getIndexed, 2) { | |
327 GETTER(Int8Array, Smi, int8_t); | |
328 } | |
329 | |
330 | |
331 DEFINE_NATIVE_ENTRY(Int8Array_setIndexed, 3) { | |
332 SETTER(Int8Array, Smi, Value, int8_t); | |
333 } | |
334 | |
335 | |
336 // Uint8Array | |
337 | |
338 DEFINE_NATIVE_ENTRY(Uint8Array_new, 1) { | |
339 GET_NON_NULL_NATIVE_ARGUMENT(Smi, length, arguments->NativeArgAt(0)); | |
340 intptr_t len = length.Value(); | |
341 LengthCheck(len, Uint8Array::kMaxElements); | |
342 return Uint8Array::New(len); | |
343 } | |
344 | |
345 | |
346 DEFINE_NATIVE_ENTRY(Uint8List_newTransferable, 1) { | |
347 const int kAlignment = 16; | |
348 GET_NON_NULL_NATIVE_ARGUMENT(Smi, length, arguments->NativeArgAt(0)); | |
349 intptr_t len = length.Value(); | |
350 LengthCheck(len, Uint8Array::kMaxElements); | |
351 uint8_t* bytes = OS::AllocateAlignedArray<uint8_t>(len, kAlignment); | |
352 const ExternalUint8Array& obj = | |
353 ExternalUint8Array::Handle(ExternalUint8Array::New(bytes, len)); | |
354 obj.AddFinalizer(bytes, PeerFinalizer); | |
355 return obj.raw(); | |
356 } | |
357 | |
358 | |
359 DEFINE_NATIVE_ENTRY(Uint8Array_getIndexed, 2) { | |
360 GETTER(Uint8Array, Smi, uint8_t); | |
361 } | |
362 | |
363 | |
364 DEFINE_NATIVE_ENTRY(Uint8Array_setIndexed, 3) { | |
365 SETTER(Uint8Array, Smi, Value, uint8_t); | |
366 } | |
367 | |
368 | |
369 // Uint8ClampedArray | |
370 | |
371 DEFINE_NATIVE_ENTRY(Uint8ClampedArray_new, 1) { | |
372 GET_NON_NULL_NATIVE_ARGUMENT(Smi, length, arguments->NativeArgAt(0)); | |
373 intptr_t len = length.Value(); | |
374 LengthCheck(len, Uint8ClampedArray::kMaxElements); | |
375 return Uint8ClampedArray::New(len); | |
376 } | |
377 | |
378 | |
379 DEFINE_NATIVE_ENTRY(Uint8ClampedList_newTransferable, 1) { | |
380 const int kAlignment = 16; | |
381 GET_NON_NULL_NATIVE_ARGUMENT(Smi, length, arguments->NativeArgAt(0)); | |
382 intptr_t len = length.Value(); | |
383 LengthCheck(len, Uint8ClampedArray::kMaxElements); | |
384 uint8_t* bytes = OS::AllocateAlignedArray<uint8_t>(len, kAlignment); | |
385 const ExternalUint8ClampedArray& obj = ExternalUint8ClampedArray::Handle( | |
386 ExternalUint8ClampedArray::New(bytes, len)); | |
387 obj.AddFinalizer(bytes, PeerFinalizer); | |
388 return obj.raw(); | |
389 } | |
390 | |
391 | |
392 DEFINE_NATIVE_ENTRY(Uint8ClampedArray_getIndexed, 2) { | |
393 GETTER(Uint8ClampedArray, Smi, uint8_t); | |
394 } | |
395 | |
396 | |
397 DEFINE_NATIVE_ENTRY(Uint8ClampedArray_setIndexed, 3) { | |
398 SETTER(Uint8ClampedArray, Smi, Value, uint8_t); | |
399 } | |
400 | |
401 | |
402 // Int16Array | |
403 | |
404 DEFINE_NATIVE_ENTRY(Int16Array_new, 1) { | |
405 GET_NON_NULL_NATIVE_ARGUMENT(Smi, length, arguments->NativeArgAt(0)); | |
406 intptr_t len = length.Value(); | |
407 LengthCheck(len, Int16Array::kMaxElements); | |
408 return Int16Array::New(len); | |
409 } | |
410 | |
411 | |
412 DEFINE_NATIVE_ENTRY(Int16List_newTransferable, 1) { | |
413 const int kAlignment = 16; | |
414 GET_NON_NULL_NATIVE_ARGUMENT(Smi, length, arguments->NativeArgAt(0)); | |
415 intptr_t len = length.Value(); | |
416 LengthCheck(len, Int16Array::kMaxElements); | |
417 int16_t* bytes = OS::AllocateAlignedArray<int16_t>(len, kAlignment); | |
418 const ExternalInt16Array& obj = | |
419 ExternalInt16Array::Handle(ExternalInt16Array::New(bytes, len)); | |
420 obj.AddFinalizer(bytes, PeerFinalizer); | |
421 return obj.raw(); | |
422 } | |
423 | |
424 | |
425 DEFINE_NATIVE_ENTRY(Int16Array_getIndexed, 2) { | |
426 GETTER(Int16Array, Smi, int16_t); | |
427 } | |
428 | |
429 | |
430 DEFINE_NATIVE_ENTRY(Int16Array_setIndexed, 3) { | |
431 SETTER(Int16Array, Smi, Value, int16_t); | |
432 } | |
433 | |
434 | |
435 // Uint16Array | |
436 | |
437 DEFINE_NATIVE_ENTRY(Uint16Array_new, 1) { | |
438 GET_NON_NULL_NATIVE_ARGUMENT(Smi, length, arguments->NativeArgAt(0)); | |
439 intptr_t len = length.Value(); | |
440 LengthCheck(len, Uint16Array::kMaxElements); | |
441 return Uint16Array::New(len); | |
442 } | |
443 | |
444 | |
445 DEFINE_NATIVE_ENTRY(Uint16List_newTransferable, 1) { | |
446 const int kAlignment = 16; | |
447 GET_NON_NULL_NATIVE_ARGUMENT(Smi, length, arguments->NativeArgAt(0)); | |
448 intptr_t len = length.Value(); | |
449 LengthCheck(len, Uint16Array::kMaxElements); | |
450 uint16_t* bytes = OS::AllocateAlignedArray<uint16_t>(len, kAlignment); | |
451 const ExternalUint16Array& obj = | |
452 ExternalUint16Array::Handle(ExternalUint16Array::New(bytes, len)); | |
453 obj.AddFinalizer(bytes, PeerFinalizer); | |
454 return obj.raw(); | |
455 } | |
456 | |
457 | |
458 DEFINE_NATIVE_ENTRY(Uint16Array_getIndexed, 2) { | |
459 GETTER(Uint16Array, Smi, uint16_t); | |
460 } | |
461 | |
462 | |
463 DEFINE_NATIVE_ENTRY(Uint16Array_setIndexed, 3) { | |
464 SETTER(Uint16Array, Smi, Value, uint16_t); | |
465 } | |
466 | |
467 | |
468 // Int32Array | |
469 | |
470 DEFINE_NATIVE_ENTRY(Int32Array_new, 1) { | |
471 GET_NON_NULL_NATIVE_ARGUMENT(Smi, length, arguments->NativeArgAt(0)); | |
472 intptr_t len = length.Value(); | |
473 LengthCheck(len, Int32Array::kMaxElements); | |
474 return Int32Array::New(len); | |
475 } | |
476 | |
477 | |
478 DEFINE_NATIVE_ENTRY(Int32List_newTransferable, 1) { | |
479 const int kAlignment = 16; | |
480 GET_NON_NULL_NATIVE_ARGUMENT(Smi, length, arguments->NativeArgAt(0)); | |
481 intptr_t len = length.Value(); | |
482 LengthCheck(len, Int32Array::kMaxElements); | |
483 int32_t* bytes = OS::AllocateAlignedArray<int32_t>(len, kAlignment); | |
484 const ExternalInt32Array& obj = | |
485 ExternalInt32Array::Handle(ExternalInt32Array::New(bytes, len)); | |
486 obj.AddFinalizer(bytes, PeerFinalizer); | |
487 return obj.raw(); | |
488 } | |
489 | |
490 | |
491 DEFINE_NATIVE_ENTRY(Int32Array_getIndexed, 2) { | |
492 GETTER(Int32Array, Integer, int32_t); | |
493 } | |
494 | |
495 | |
496 DEFINE_NATIVE_ENTRY(Int32Array_setIndexed, 3) { | |
497 SETTER(Int32Array, Integer, AsInt64Value, int32_t); | |
498 } | |
499 | |
500 | |
501 // Uint32Array | |
502 | |
503 DEFINE_NATIVE_ENTRY(Uint32Array_new, 1) { | |
504 GET_NON_NULL_NATIVE_ARGUMENT(Smi, length, arguments->NativeArgAt(0)); | |
505 intptr_t len = length.Value(); | |
506 LengthCheck(len, Uint32Array::kMaxElements); | |
507 return Uint32Array::New(len); | |
508 } | |
509 | |
510 | |
511 DEFINE_NATIVE_ENTRY(Uint32List_newTransferable, 1) { | |
512 const int kAlignment = 16; | |
513 GET_NON_NULL_NATIVE_ARGUMENT(Smi, length, arguments->NativeArgAt(0)); | |
514 intptr_t len = length.Value(); | |
515 LengthCheck(len, Uint32Array::kMaxElements); | |
516 uint32_t* bytes = OS::AllocateAlignedArray<uint32_t>(len, kAlignment); | |
517 const ExternalUint32Array& obj = | |
518 ExternalUint32Array::Handle(ExternalUint32Array::New(bytes, len)); | |
519 obj.AddFinalizer(bytes, PeerFinalizer); | |
520 return obj.raw(); | |
521 } | |
522 | |
523 | |
524 DEFINE_NATIVE_ENTRY(Uint32Array_getIndexed, 2) { | |
525 GETTER(Uint32Array, Integer, uint32_t); | |
526 } | |
527 | |
528 | |
529 DEFINE_NATIVE_ENTRY(Uint32Array_setIndexed, 3) { | |
530 SETTER(Uint32Array, Integer, AsInt64Value, uint32_t); | |
531 } | |
532 | |
533 | |
534 // Int64Array | |
535 | |
536 DEFINE_NATIVE_ENTRY(Int64Array_new, 1) { | |
537 GET_NON_NULL_NATIVE_ARGUMENT(Smi, length, arguments->NativeArgAt(0)); | |
538 intptr_t len = length.Value(); | |
539 LengthCheck(len, Int64Array::kMaxElements); | |
540 return Int64Array::New(len); | |
541 } | |
542 | |
543 | |
544 DEFINE_NATIVE_ENTRY(Int64List_newTransferable, 1) { | |
545 const int kAlignment = 16; | |
546 GET_NON_NULL_NATIVE_ARGUMENT(Smi, length, arguments->NativeArgAt(0)); | |
547 intptr_t len = length.Value(); | |
548 LengthCheck(len, Int64Array::kMaxElements); | |
549 int64_t* bytes = OS::AllocateAlignedArray<int64_t>(len, kAlignment); | |
550 const ExternalInt64Array& obj = | |
551 ExternalInt64Array::Handle(ExternalInt64Array::New(bytes, len)); | |
552 obj.AddFinalizer(bytes, PeerFinalizer); | |
553 return obj.raw(); | |
554 } | |
555 | |
556 | |
557 DEFINE_NATIVE_ENTRY(Int64Array_getIndexed, 2) { | |
558 GETTER(Int64Array, Integer, int64_t); | |
559 } | |
560 | |
561 | |
562 DEFINE_NATIVE_ENTRY(Int64Array_setIndexed, 3) { | |
563 SETTER(Int64Array, Integer, AsInt64Value, int64_t); | |
564 } | |
565 | |
566 | |
567 // Uint64Array | |
568 | |
569 DEFINE_NATIVE_ENTRY(Uint64Array_new, 1) { | |
570 GET_NON_NULL_NATIVE_ARGUMENT(Smi, length, arguments->NativeArgAt(0)); | |
571 intptr_t len = length.Value(); | |
572 LengthCheck(len, Uint64Array::kMaxElements); | |
573 return Uint64Array::New(len); | |
574 } | |
575 | |
576 | |
577 DEFINE_NATIVE_ENTRY(Uint64List_newTransferable, 1) { | |
578 const int kAlignment = 16; | |
579 GET_NON_NULL_NATIVE_ARGUMENT(Smi, length, arguments->NativeArgAt(0)); | |
580 intptr_t len = length.Value(); | |
581 LengthCheck(len, Uint64Array::kMaxElements); | |
582 uint64_t* bytes = OS::AllocateAlignedArray<uint64_t>(len, kAlignment); | |
583 const ExternalUint64Array& obj = | |
584 ExternalUint64Array::Handle(ExternalUint64Array::New(bytes, len)); | |
585 obj.AddFinalizer(bytes, PeerFinalizer); | |
586 return obj.raw(); | |
587 } | |
588 | |
589 | |
590 DEFINE_NATIVE_ENTRY(Uint64Array_getIndexed, 2) { | |
591 GETTER_UINT64(Uint64Array); | |
592 } | |
593 | |
594 | |
595 DEFINE_NATIVE_ENTRY(Uint64Array_setIndexed, 3) { | |
596 SETTER_UINT64(Uint64Array); | |
597 } | |
598 | |
599 | |
600 // Float32Array | |
601 | |
602 DEFINE_NATIVE_ENTRY(Float32Array_new, 1) { | |
603 GET_NON_NULL_NATIVE_ARGUMENT(Smi, length, arguments->NativeArgAt(0)); | |
604 intptr_t len = length.Value(); | |
605 LengthCheck(len, Float32Array::kMaxElements); | |
606 return Float32Array::New(len); | |
607 } | |
608 | |
609 | |
610 DEFINE_NATIVE_ENTRY(Float32List_newTransferable, 1) { | |
611 const int kAlignment = 16; | |
612 GET_NON_NULL_NATIVE_ARGUMENT(Smi, length, arguments->NativeArgAt(0)); | |
613 intptr_t len = length.Value(); | |
614 LengthCheck(len, Float32Array::kMaxElements); | |
615 float* bytes = OS::AllocateAlignedArray<float>(len, kAlignment); | |
616 const ExternalFloat32Array& obj = | |
617 ExternalFloat32Array::Handle(ExternalFloat32Array::New(bytes, len)); | |
618 obj.AddFinalizer(bytes, PeerFinalizer); | |
619 return obj.raw(); | |
620 } | |
621 | |
622 | |
623 DEFINE_NATIVE_ENTRY(Float32Array_getIndexed, 2) { | |
624 GETTER(Float32Array, Double, float); | |
625 } | |
626 | |
627 | |
628 DEFINE_NATIVE_ENTRY(Float32Array_setIndexed, 3) { | |
629 SETTER(Float32Array, Double, value, float); | |
630 } | |
631 | |
632 | |
633 // Float64Array | |
634 | |
635 DEFINE_NATIVE_ENTRY(Float64Array_new, 1) { | |
636 GET_NON_NULL_NATIVE_ARGUMENT(Smi, length, arguments->NativeArgAt(0)); | |
637 intptr_t len = length.Value(); | |
638 LengthCheck(len, Float64Array::kMaxElements); | |
639 return Float64Array::New(len); | |
640 } | |
641 | |
642 | |
643 DEFINE_NATIVE_ENTRY(Float64List_newTransferable, 1) { | |
644 const int kAlignment = 16; | |
645 GET_NON_NULL_NATIVE_ARGUMENT(Smi, length, arguments->NativeArgAt(0)); | |
646 intptr_t len = length.Value(); | |
647 LengthCheck(len, Float64Array::kMaxElements); | |
648 double* bytes = OS::AllocateAlignedArray<double>(len, kAlignment); | |
649 const ExternalFloat64Array& obj = | |
650 ExternalFloat64Array::Handle(ExternalFloat64Array::New(bytes, len)); | |
651 obj.AddFinalizer(bytes, PeerFinalizer); | |
652 return obj.raw(); | |
653 } | |
654 | |
655 | |
656 DEFINE_NATIVE_ENTRY(Float64Array_getIndexed, 2) { | |
657 GETTER(Float64Array, Double, double); | |
658 } | |
659 | |
660 | |
661 DEFINE_NATIVE_ENTRY(Float64Array_setIndexed, 3) { | |
662 SETTER(Float64Array, Double, value, double); | |
663 } | |
664 | |
665 | |
666 // ExternalInt8Array | |
667 | |
668 DEFINE_NATIVE_ENTRY(ExternalInt8Array_getIndexed, 2) { | |
669 GETTER(ExternalInt8Array, Smi, int8_t); | |
670 } | |
671 | |
672 | |
673 DEFINE_NATIVE_ENTRY(ExternalInt8Array_setIndexed, 3) { | |
674 SETTER(ExternalInt8Array, Smi, Value, int8_t); | |
675 } | |
676 | |
677 | |
678 // ExternalUint8Array | |
679 | |
680 DEFINE_NATIVE_ENTRY(ExternalUint8Array_getIndexed, 2) { | |
681 SCALED_UNALIGNED_GETTER(ExternalUint8Array, Smi, uint8_t); | |
682 } | |
683 | |
684 | |
685 DEFINE_NATIVE_ENTRY(ExternalUint8Array_setIndexed, 3) { | |
686 SCALED_UNALIGNED_SETTER(ExternalUint8Array, Smi, Value, uint8_t); | |
687 } | |
688 | |
689 | |
690 // ExternalUint8ClampedArray | |
691 | |
692 DEFINE_NATIVE_ENTRY(ExternalUint8ClampedArray_getIndexed, 2) { | |
693 SCALED_UNALIGNED_GETTER(ExternalUint8ClampedArray, Smi, uint8_t); | |
694 } | |
695 | |
696 | |
697 DEFINE_NATIVE_ENTRY(ExternalUint8ClampedArray_setIndexed, 3) { | |
698 SCALED_UNALIGNED_SETTER(ExternalUint8ClampedArray, Smi, Value, uint8_t); | |
699 } | |
700 | |
701 | |
702 // ExternalInt16Array | |
703 | |
704 DEFINE_NATIVE_ENTRY(ExternalInt16Array_getIndexed, 2) { | |
705 GETTER(ExternalInt16Array, Smi, int16_t); | |
706 } | |
707 | |
708 | |
709 DEFINE_NATIVE_ENTRY(ExternalInt16Array_setIndexed, 3) { | |
710 SETTER(ExternalInt16Array, Smi, Value, int16_t); | |
711 } | |
712 | |
713 | |
714 // ExternalUint16Array | |
715 | |
716 DEFINE_NATIVE_ENTRY(ExternalUint16Array_getIndexed, 2) { | |
717 SCALED_UNALIGNED_GETTER(ExternalUint16Array, Smi, uint16_t); | |
718 } | |
719 | |
720 | |
721 DEFINE_NATIVE_ENTRY(ExternalUint16Array_setIndexed, 3) { | |
722 SCALED_UNALIGNED_SETTER(ExternalUint16Array, Smi, Value, uint16_t); | |
723 } | |
724 | |
725 | |
726 // ExternalInt32Array | |
727 | |
728 DEFINE_NATIVE_ENTRY(ExternalInt32Array_getIndexed, 2) { | |
729 GETTER(ExternalInt32Array, Integer, int32_t); | |
730 } | |
731 | |
732 | |
733 DEFINE_NATIVE_ENTRY(ExternalInt32Array_setIndexed, 3) { | |
734 SETTER(ExternalInt32Array, Integer, AsInt64Value, int32_t); | |
735 } | |
736 | |
737 | |
738 // ExternalUint32Array | |
739 | |
740 DEFINE_NATIVE_ENTRY(ExternalUint32Array_getIndexed, 2) { | |
741 SCALED_UNALIGNED_GETTER(ExternalUint32Array, Integer, uint32_t); | |
742 } | |
743 | |
744 | |
745 DEFINE_NATIVE_ENTRY(ExternalUint32Array_setIndexed, 3) { | |
746 SCALED_UNALIGNED_SETTER(ExternalUint32Array, Integer, AsInt64Value, uint32_t); | |
747 } | |
748 | |
749 | |
750 // ExternalInt64Array | |
751 | |
752 DEFINE_NATIVE_ENTRY(ExternalInt64Array_getIndexed, 2) { | |
753 GETTER(ExternalInt64Array, Integer, int64_t); | |
754 } | |
755 | |
756 | |
757 DEFINE_NATIVE_ENTRY(ExternalInt64Array_setIndexed, 3) { | |
758 SETTER(ExternalInt64Array, Integer, AsInt64Value, int64_t); | |
759 } | |
760 | |
761 | |
762 // ExternalUint64Array | |
763 | |
764 DEFINE_NATIVE_ENTRY(ExternalUint64Array_getIndexed, 2) { | |
765 GETTER_UINT64(ExternalUint64Array); | |
766 } | |
767 | |
768 | |
769 DEFINE_NATIVE_ENTRY(ExternalUint64Array_setIndexed, 3) { | |
770 SETTER_UINT64(ExternalUint64Array); | |
771 } | |
772 | |
773 | |
774 // ExternalFloat32Array | |
775 | |
776 DEFINE_NATIVE_ENTRY(ExternalFloat32Array_getIndexed, 2) { | |
777 GETTER(ExternalFloat32Array, Double, float); | |
778 } | |
779 | |
780 | |
781 DEFINE_NATIVE_ENTRY(ExternalFloat32Array_setIndexed, 3) { | |
782 SETTER(ExternalFloat32Array, Double, value, float); | |
783 } | |
784 | |
785 | |
786 // ExternalFloat64Array | |
787 | |
788 DEFINE_NATIVE_ENTRY(ExternalFloat64Array_getIndexed, 2) { | |
789 GETTER(ExternalFloat64Array, Double, double); | |
790 } | |
791 | |
792 | |
793 DEFINE_NATIVE_ENTRY(ExternalFloat64Array_setIndexed, 3) { | |
794 SETTER(ExternalFloat64Array, Double, value, double); | |
795 } | |
796 | |
797 } // namespace dart | |
OLD | NEW |