Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
snapshot_test.cc
Go to the documentation of this file.
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 "platform/globals.h"
6
8#include "platform/assert.h"
9#include "platform/unicode.h"
10#include "vm/app_snapshot.h"
11#include "vm/class_finalizer.h"
12#include "vm/dart_api_impl.h"
13#include "vm/dart_api_message.h"
14#include "vm/dart_api_state.h"
16#include "vm/flags.h"
17#include "vm/message_snapshot.h"
18#include "vm/snapshot.h"
19#include "vm/symbols.h"
20#include "vm/timer.h"
21#include "vm/unit_test.h"
22
23namespace dart {
24
25// Check if serialized and deserialized objects are equal.
26static bool Equals(const Object& expected, const Object& actual) {
27 if (expected.IsNull()) {
28 return actual.IsNull();
29 }
30 if (expected.IsSmi()) {
31 if (actual.IsSmi()) {
32 return expected.ptr() == actual.ptr();
33 }
34 return false;
35 }
36 if (expected.IsDouble()) {
37 if (actual.IsDouble()) {
38 Double& dbl1 = Double::Handle();
39 Double& dbl2 = Double::Handle();
40 dbl1 ^= expected.ptr();
41 dbl2 ^= actual.ptr();
42 return dbl1.value() == dbl2.value();
43 }
44 return false;
45 }
46 if (expected.IsBool()) {
47 if (actual.IsBool()) {
48 return expected.ptr() == actual.ptr();
49 }
50 return false;
51 }
52 return false;
53}
54
55// Compare two Dart_CObject object graphs rooted in first and
56// second. The second graph will be destroyed by this operation no matter
57// whether the graphs are equal or not.
58static void CompareDartCObjects(Dart_CObject* first, Dart_CObject* second) {
59 // Return immediately if entering a cycle.
60 if (second->type == Dart_CObject_kNumberOfTypes) return;
61
62 EXPECT_EQ(first->type, second->type);
63 switch (first->type) {
65 // Nothing more to compare.
66 break;
68 EXPECT_EQ(first->value.as_bool, second->value.as_bool);
69 break;
71 EXPECT_EQ(first->value.as_int32, second->value.as_int32);
72 break;
74 EXPECT_EQ(first->value.as_int64, second->value.as_int64);
75 break;
77 EXPECT_EQ(first->value.as_double, second->value.as_double);
78 break;
80 EXPECT_STREQ(first->value.as_string, second->value.as_string);
81 break;
83 EXPECT_EQ(first->value.as_typed_data.length,
84 second->value.as_typed_data.length);
85 for (int i = 0; i < first->value.as_typed_data.length; i++) {
86 EXPECT_EQ(first->value.as_typed_data.values[i],
87 second->value.as_typed_data.values[i]);
88 }
89 break;
91 // Use invalid type as a visited marker to avoid infinite
92 // recursion on graphs with cycles.
94 EXPECT_EQ(first->value.as_array.length, second->value.as_array.length);
95 for (int i = 0; i < first->value.as_array.length; i++) {
97 second->value.as_array.values[i]);
98 }
99 break;
101 EXPECT_EQ(first->value.as_capability.id, second->value.as_capability.id);
102 break;
103 default:
104 EXPECT(false);
105 }
106}
107
108static void CheckEncodeDecodeMessage(Zone* zone, Dart_CObject* root) {
109 // Encode and decode the message.
110 std::unique_ptr<Message> message =
112
113 Dart_CObject* new_root = ReadApiMessage(zone, message.get());
114
115 // Check that the two messages are the same.
116 CompareDartCObjects(root, new_root);
117}
118
119static void ExpectEncodeFail(Zone* zone, Dart_CObject* root) {
120 std::unique_ptr<Message> message =
122 EXPECT(message == nullptr);
123}
124
126 StackZone zone(thread);
127
128 // Write snapshot with object content.
129 const Object& null_object = Object::Handle();
130 std::unique_ptr<Message> message =
131 WriteMessage(/* same_group */ false, null_object, ILLEGAL_PORT,
133
134 // Read object back from the snapshot.
135 const Object& serialized_object =
136 Object::Handle(ReadMessage(thread, message.get()));
137 EXPECT(Equals(null_object, serialized_object));
138
139 // Read object back from the snapshot into a C structure.
140 ApiNativeScope scope;
141 Dart_CObject* root = ReadApiMessage(scope.zone(), message.get());
142 EXPECT_NOTNULL(root);
143 EXPECT_EQ(Dart_CObject_kNull, root->type);
144 CheckEncodeDecodeMessage(scope.zone(), root);
145}
146
148 StackZone zone(thread);
149
150 // Write snapshot with object content.
151 const Smi& smi = Smi::Handle(Smi::New(124));
152 std::unique_ptr<Message> message = WriteMessage(
153 /* same_group */ false, smi, ILLEGAL_PORT, Message::kNormalPriority);
154
155 // Read object back from the snapshot.
156 const Object& serialized_object =
157 Object::Handle(ReadMessage(thread, message.get()));
158 EXPECT(Equals(smi, serialized_object));
159
160 // Read object back from the snapshot into a C structure.
161 ApiNativeScope scope;
162 Dart_CObject* root = ReadApiMessage(scope.zone(), message.get());
163 EXPECT_NOTNULL(root);
164 EXPECT_EQ(Dart_CObject_kInt32, root->type);
165 EXPECT_EQ(smi.Value(), root->value.as_int32);
166 CheckEncodeDecodeMessage(scope.zone(), root);
167}
168
170 StackZone zone(thread);
171
172 // Write snapshot with object content.
173 const Smi& smi = Smi::Handle(Smi::New(-1));
174 std::unique_ptr<Message> message = WriteMessage(
175 /* same_group */ false, smi, ILLEGAL_PORT, Message::kNormalPriority);
176
177 // Read object back from the snapshot.
178 const Object& serialized_object =
179 Object::Handle(ReadMessage(thread, message.get()));
180 EXPECT(Equals(smi, serialized_object));
181
182 // Read object back from the snapshot into a C structure.
183 ApiNativeScope scope;
184 Dart_CObject* root = ReadApiMessage(scope.zone(), message.get());
185 EXPECT_NOTNULL(root);
186 EXPECT_EQ(Dart_CObject_kInt32, root->type);
187 EXPECT_EQ(smi.Value(), root->value.as_int32);
188 CheckEncodeDecodeMessage(scope.zone(), root);
189}
190
192 // Write snapshot with object content.
193 std::unique_ptr<Message> message = WriteMessage(
194 /* same_group */ false, mint, ILLEGAL_PORT, Message::kNormalPriority);
195
196 {
197 // Switch to a regular zone, where VM handle allocation is allowed.
198 Thread* thread = Thread::Current();
199 StackZone zone(thread);
200 // Read object back from the snapshot.
201 const Object& serialized_object =
202 Object::Handle(ReadMessage(thread, message.get()));
203 EXPECT(serialized_object.IsMint());
204 }
205
206 // Read object back from the snapshot into a C structure.
207 Dart_CObject* root = ReadApiMessage(zone, message.get());
208 EXPECT_NOTNULL(root);
209 CheckEncodeDecodeMessage(zone, root);
210 return root;
211}
212
213void CheckMint(int64_t value) {
214 ApiNativeScope scope;
216
217 Mint& mint = Mint::Handle();
218 mint ^= Integer::New(value);
219 Dart_CObject* mint_cobject =
221// On 64-bit platforms mints always require 64-bits as the smi range
222// here covers most of the 64-bit range. On 32-bit platforms the smi
223// range covers most of the 32-bit range and values outside that
224// range are also represented as mints.
225#if defined(ARCH_IS_64_BIT) && !defined(DART_COMPRESSED_POINTERS)
226 EXPECT_EQ(Dart_CObject_kInt64, mint_cobject->type);
227 EXPECT_EQ(value, mint_cobject->value.as_int64);
228#else
229 if (kMinInt32 < value && value < kMaxInt32) {
230 EXPECT_EQ(Dart_CObject_kInt32, mint_cobject->type);
231 EXPECT_EQ(value, mint_cobject->value.as_int32);
232 } else {
233 EXPECT_EQ(Dart_CObject_kInt64, mint_cobject->type);
234 EXPECT_EQ(value, mint_cobject->value.as_int64);
235 }
236#endif
237}
238
239ISOLATE_UNIT_TEST_CASE(SerializeMints) {
240 // Min positive mint.
242 // Min positive mint + 1.
244 // Max negative mint.
246 // Max negative mint - 1.
248 // Max positive mint.
250 // Max positive mint - 1.
251 CheckMint(kMaxInt64 - 1);
252 // Min negative mint.
254 // Min negative mint + 1.
255 CheckMint(kMinInt64 + 1);
256}
257
258ISOLATE_UNIT_TEST_CASE(SerializeDouble) {
259 StackZone zone(thread);
260
261 // Write snapshot with object content.
262 const Double& dbl = Double::Handle(Double::New(101.29));
263 std::unique_ptr<Message> message = WriteMessage(
264 /* same_group */ false, dbl, ILLEGAL_PORT, Message::kNormalPriority);
265
266 // Read object back from the snapshot.
267 const Object& serialized_object =
268 Object::Handle(ReadMessage(thread, message.get()));
269 EXPECT(Equals(dbl, serialized_object));
270
271 // Read object back from the snapshot into a C structure.
272 ApiNativeScope scope;
273 Dart_CObject* root = ReadApiMessage(scope.zone(), message.get());
274 EXPECT_NOTNULL(root);
275 EXPECT_EQ(Dart_CObject_kDouble, root->type);
276 EXPECT_EQ(dbl.value(), root->value.as_double);
277 CheckEncodeDecodeMessage(scope.zone(), root);
278}
279
281 StackZone zone(thread);
282
283 // Write snapshot with true object.
284 const Bool& bl = Bool::True();
285 std::unique_ptr<Message> message = WriteMessage(
286 /* same_group */ false, bl, ILLEGAL_PORT, Message::kNormalPriority);
287
288 // Read object back from the snapshot.
289 const Object& serialized_object =
290 Object::Handle(ReadMessage(thread, message.get()));
291 fprintf(stderr, "%s / %s\n", bl.ToCString(), serialized_object.ToCString());
292
293 EXPECT(Equals(bl, serialized_object));
294
295 // Read object back from the snapshot into a C structure.
296 ApiNativeScope scope;
297 Dart_CObject* root = ReadApiMessage(scope.zone(), message.get());
298 EXPECT_NOTNULL(root);
299 EXPECT_EQ(Dart_CObject_kBool, root->type);
300 EXPECT_EQ(true, root->value.as_bool);
301 CheckEncodeDecodeMessage(scope.zone(), root);
302}
303
304ISOLATE_UNIT_TEST_CASE(SerializeFalse) {
305 StackZone zone(thread);
306
307 // Write snapshot with false object.
308 const Bool& bl = Bool::False();
309 std::unique_ptr<Message> message = WriteMessage(
310 /* same_group */ false, bl, ILLEGAL_PORT, Message::kNormalPriority);
311
312 // Read object back from the snapshot.
313 const Object& serialized_object =
314 Object::Handle(ReadMessage(thread, message.get()));
315 EXPECT(Equals(bl, serialized_object));
316
317 // Read object back from the snapshot into a C structure.
318 ApiNativeScope scope;
319 Dart_CObject* root = ReadApiMessage(scope.zone(), message.get());
320 EXPECT_NOTNULL(root);
321 EXPECT_EQ(Dart_CObject_kBool, root->type);
322 EXPECT_EQ(false, root->value.as_bool);
323 CheckEncodeDecodeMessage(scope.zone(), root);
324}
325
326ISOLATE_UNIT_TEST_CASE(SerializeCapability) {
327 // Write snapshot with object content.
328 const Capability& capability = Capability::Handle(Capability::New(12345));
329 std::unique_ptr<Message> message =
330 WriteMessage(/* same_group */ false, capability, ILLEGAL_PORT,
332
333 // Read object back from the snapshot.
335 obj ^= ReadMessage(thread, message.get());
336
337 EXPECT_EQ(static_cast<uint64_t>(12345), obj.Id());
338
339 // Read object back from the snapshot into a C structure.
340 ApiNativeScope scope;
341 Dart_CObject* root = ReadApiMessage(scope.zone(), message.get());
342 EXPECT_NOTNULL(root);
343 EXPECT_EQ(Dart_CObject_kCapability, root->type);
344 int64_t id = root->value.as_capability.id;
345 EXPECT_EQ(12345, id);
346 CheckEncodeDecodeMessage(scope.zone(), root);
347}
348
349#define TEST_ROUND_TRIP_IDENTICAL(object) \
350 { \
351 const Object& before = Object::Handle(object); \
352 std::unique_ptr<Message> message = \
353 WriteMessage(/* same_group */ false, before, ILLEGAL_PORT, \
354 Message::kNormalPriority); \
355 const Object& after = Object::Handle(ReadMessage(thread, message.get())); \
356 EXPECT(before.ptr() == after.ptr()); \
357 }
358
373
374static void TestString(const char* cstr) {
375 Thread* thread = Thread::Current();
376 EXPECT(Utf8::IsValid(reinterpret_cast<const uint8_t*>(cstr), strlen(cstr)));
377 // Write snapshot with object content.
378 String& str = String::Handle(String::New(cstr));
379 std::unique_ptr<Message> message = WriteMessage(
380 /* same_group */ false, str, ILLEGAL_PORT, Message::kNormalPriority);
381
382 // Read object back from the snapshot.
383 String& serialized_str = String::Handle();
384 serialized_str ^= ReadMessage(thread, message.get());
385 EXPECT(str.Equals(serialized_str));
386
387 // Read object back from the snapshot into a C structure.
388 ApiNativeScope scope;
389 Dart_CObject* root = ReadApiMessage(scope.zone(), message.get());
390 EXPECT_EQ(Dart_CObject_kString, root->type);
391 EXPECT_STREQ(cstr, root->value.as_string);
392 CheckEncodeDecodeMessage(scope.zone(), root);
393}
394
395ISOLATE_UNIT_TEST_CASE(SerializeString) {
396 TestString("This string shall be serialized");
397 TestString("æøå"); // This file is UTF-8 encoded.
398 const char* data =
399 "\x01"
400 "\x7F"
401 "\xC2\x80" // U+0080
402 "\xDF\xBF" // U+07FF
403 "\xE0\xA0\x80" // U+0800
404 "\xEF\xBF\xBF"; // U+FFFF
405
407 // TODO(sgjesse): Add tests with non-BMP characters.
408}
409
410ISOLATE_UNIT_TEST_CASE(SerializeArray) {
411 // Write snapshot with object content.
412 const int kArrayLength = 10;
413 Array& array = Array::Handle(Array::New(kArrayLength));
414 Smi& smi = Smi::Handle();
415 for (int i = 0; i < kArrayLength; i++) {
416 smi ^= Smi::New(i);
417 array.SetAt(i, smi);
418 }
419 std::unique_ptr<Message> message = WriteMessage(
420 /* same_group */ false, array, ILLEGAL_PORT, Message::kNormalPriority);
421
422 // Read object back from the snapshot.
423 Array& serialized_array = Array::Handle();
424 serialized_array ^= ReadMessage(thread, message.get());
425 EXPECT(array.CanonicalizeEquals(serialized_array));
426
427 // Read object back from the snapshot into a C structure.
428 ApiNativeScope scope;
429 Dart_CObject* root = ReadApiMessage(scope.zone(), message.get());
430 EXPECT_EQ(Dart_CObject_kArray, root->type);
431 EXPECT_EQ(kArrayLength, root->value.as_array.length);
432 for (int i = 0; i < kArrayLength; i++) {
433 Dart_CObject* element = root->value.as_array.values[i];
434 EXPECT_EQ(Dart_CObject_kInt32, element->type);
435 EXPECT_EQ(i, element->value.as_int32);
436 }
437 CheckEncodeDecodeMessage(scope.zone(), root);
438}
439
440ISOLATE_UNIT_TEST_CASE(SerializeArrayWithTypeArgument) {
441 // Write snapshot with object content.
442 const int kArrayLength = 10;
443 Array& array =
445
446 Smi& smi = Smi::Handle();
447 for (int i = 0; i < kArrayLength; i++) {
448 smi ^= Smi::New(i);
449 array.SetAt(i, smi);
450 }
451 std::unique_ptr<Message> message = WriteMessage(
452 /* same_group */ false, array, ILLEGAL_PORT, Message::kNormalPriority);
453
454 // Read object back from the snapshot.
455 Array& serialized_array = Array::Handle();
456 serialized_array ^= ReadMessage(thread, message.get());
457 EXPECT(array.CanonicalizeEquals(serialized_array));
458
459 // Read object back from the snapshot into a C structure.
460 ApiNativeScope scope;
461 Dart_CObject* root = ReadApiMessage(scope.zone(), message.get());
462 EXPECT_EQ(Dart_CObject_kArray, root->type);
463 EXPECT_EQ(kArrayLength, root->value.as_array.length);
464 for (int i = 0; i < kArrayLength; i++) {
465 Dart_CObject* element = root->value.as_array.values[i];
466 EXPECT_EQ(Dart_CObject_kInt32, element->type);
467 EXPECT_EQ(i, element->value.as_int32);
468 }
469 CheckEncodeDecodeMessage(scope.zone(), root);
470}
471
472TEST_CASE(FailSerializeLargeArray) {
473 Dart_CObject root;
474 root.type = Dart_CObject_kArray;
475 root.value.as_array.length = Array::kMaxElements + 1;
476 root.value.as_array.values = nullptr;
477 ApiNativeScope scope;
478 ExpectEncodeFail(scope.zone(), &root);
479}
480
481TEST_CASE(FailSerializeLargeNestedArray) {
482 Dart_CObject parent;
483 Dart_CObject child;
484 Dart_CObject* values[1] = {&child};
485
486 parent.type = Dart_CObject_kArray;
487 parent.value.as_array.length = 1;
488 parent.value.as_array.values = values;
491 ApiNativeScope scope;
492 ExpectEncodeFail(scope.zone(), &parent);
493}
494
495TEST_CASE(FailSerializeLargeTypedDataInt8) {
496 Dart_CObject root;
497 root.type = Dart_CObject_kTypedData;
498 root.value.as_typed_data.type = Dart_TypedData_kInt8;
499 root.value.as_typed_data.length =
500 TypedData::MaxElements(kTypedDataInt8ArrayCid) + 1;
501 ApiNativeScope scope;
502 ExpectEncodeFail(scope.zone(), &root);
503}
504
505TEST_CASE(FailSerializeLargeTypedDataUint8) {
506 Dart_CObject root;
507 root.type = Dart_CObject_kTypedData;
508 root.value.as_typed_data.type = Dart_TypedData_kUint8;
509 root.value.as_typed_data.length =
510 TypedData::MaxElements(kTypedDataUint8ArrayCid) + 1;
511 ApiNativeScope scope;
512 ExpectEncodeFail(scope.zone(), &root);
513}
514
515TEST_CASE(FailSerializeLargeExternalTypedData) {
516 Dart_CObject root;
518 root.value.as_external_typed_data.type = Dart_TypedData_kUint8;
519 root.value.as_external_typed_data.length =
520 ExternalTypedData::MaxElements(kExternalTypedDataUint8ArrayCid) + 1;
521 ApiNativeScope scope;
522 ExpectEncodeFail(scope.zone(), &root);
523}
524
525TEST_CASE(FailSerializeLargeUnmodifiableExternalTypedData) {
526 Dart_CObject root;
528 root.value.as_external_typed_data.type = Dart_TypedData_kUint8;
529 root.value.as_external_typed_data.length =
530 ExternalTypedData::MaxElements(kExternalTypedDataUint8ArrayCid) + 1;
531 ApiNativeScope scope;
532 ExpectEncodeFail(scope.zone(), &root);
533}
534
535ISOLATE_UNIT_TEST_CASE(SerializeEmptyArray) {
536 // Write snapshot with object content.
537 const int kArrayLength = 0;
538 Array& array = Array::Handle(Array::New(kArrayLength));
539 std::unique_ptr<Message> message = WriteMessage(
540 /* same_group */ false, array, ILLEGAL_PORT, Message::kNormalPriority);
541
542 // Read object back from the snapshot.
543 Array& serialized_array = Array::Handle();
544 serialized_array ^= ReadMessage(thread, message.get());
545 EXPECT(array.CanonicalizeEquals(serialized_array));
546
547 // Read object back from the snapshot into a C structure.
548 ApiNativeScope scope;
549 Dart_CObject* root = ReadApiMessage(scope.zone(), message.get());
550 EXPECT_EQ(Dart_CObject_kArray, root->type);
551 EXPECT_EQ(kArrayLength, root->value.as_array.length);
552 EXPECT(root->value.as_array.values == nullptr);
553 CheckEncodeDecodeMessage(scope.zone(), root);
554}
555
556ISOLATE_UNIT_TEST_CASE(SerializeByteArray) {
557 // Write snapshot with object content.
558 const int kTypedDataLength = 256;
559 TypedData& typed_data = TypedData::Handle(
560 TypedData::New(kTypedDataUint8ArrayCid, kTypedDataLength));
561 for (int i = 0; i < kTypedDataLength; i++) {
562 typed_data.SetUint8(i, i);
563 }
564 std::unique_ptr<Message> message =
565 WriteMessage(/* same_group */ false, typed_data, ILLEGAL_PORT,
567
568 // Read object back from the snapshot.
569 TypedData& serialized_typed_data = TypedData::Handle();
570 serialized_typed_data ^= ReadMessage(thread, message.get());
571 EXPECT(serialized_typed_data.IsTypedData());
572
573 // Read object back from the snapshot into a C structure.
574 ApiNativeScope scope;
575 Dart_CObject* root = ReadApiMessage(scope.zone(), message.get());
576 EXPECT_EQ(Dart_CObject_kTypedData, root->type);
577 EXPECT_EQ(kTypedDataLength, root->value.as_typed_data.length);
578 for (int i = 0; i < kTypedDataLength; i++) {
579 EXPECT(root->value.as_typed_data.values[i] == i);
580 }
581 CheckEncodeDecodeMessage(scope.zone(), root);
582}
583
584#define TEST_TYPED_ARRAY(darttype, ctype) \
585 { \
586 StackZone zone(thread); \
587 const int kArrayLength = 127; \
588 TypedData& array = TypedData::Handle( \
589 TypedData::New(kTypedData##darttype##ArrayCid, kArrayLength)); \
590 intptr_t scale = array.ElementSizeInBytes(); \
591 for (int i = 0; i < kArrayLength; i++) { \
592 array.Set##darttype((i * scale), i); \
593 } \
594 std::unique_ptr<Message> message = \
595 WriteMessage(/* same_group */ false, array, ILLEGAL_PORT, \
596 Message::kNormalPriority); \
597 TypedData& serialized_array = TypedData::Handle(); \
598 serialized_array ^= ReadMessage(thread, message.get()); \
599 for (int i = 0; i < kArrayLength; i++) { \
600 EXPECT_EQ(static_cast<ctype>(i), \
601 serialized_array.Get##darttype(i* scale)); \
602 } \
603 }
604
605#define TEST_EXTERNAL_TYPED_ARRAY(darttype, ctype) \
606 { \
607 StackZone zone(thread); \
608 ctype data[] = {0, 11, 22, 33, 44, 55, 66, 77}; \
609 intptr_t length = ARRAY_SIZE(data); \
610 ExternalTypedData& array = ExternalTypedData::Handle( \
611 ExternalTypedData::New(kExternalTypedData##darttype##ArrayCid, \
612 reinterpret_cast<uint8_t*>(data), length)); \
613 intptr_t scale = array.ElementSizeInBytes(); \
614 std::unique_ptr<Message> message = \
615 WriteMessage(/* same_group */ false, array, ILLEGAL_PORT, \
616 Message::kNormalPriority); \
617 ExternalTypedData& serialized_array = ExternalTypedData::Handle(); \
618 serialized_array ^= ReadMessage(thread, message.get()); \
619 for (int i = 0; i < length; i++) { \
620 EXPECT_EQ(static_cast<ctype>(data[i]), \
621 serialized_array.Get##darttype(i* scale)); \
622 } \
623 }
624
625#define TEST_UNMODIFIABLE_EXTERNAL_TYPED_ARRAY(darttype, ctype) \
626 { \
627 StackZone zone(thread); \
628 ctype data[] = {0, 11, 22, 33, 44, 55, 66, 77}; \
629 intptr_t length = ARRAY_SIZE(data); \
630 ExternalTypedData& array = ExternalTypedData::Handle( \
631 ExternalTypedData::New(kExternalTypedData##darttype##ArrayCid, \
632 reinterpret_cast<uint8_t*>(data), length)); \
633 TypedDataView& view = TypedDataView::Handle(TypedDataView::New( \
634 kUnmodifiableTypedData##darttype##ArrayViewCid, array, 0, length)); \
635 intptr_t scale = array.ElementSizeInBytes(); \
636 std::unique_ptr<Message> message = WriteMessage( \
637 /* same_group */ false, view, ILLEGAL_PORT, Message::kNormalPriority); \
638 TypedDataView& serialized_view = TypedDataView::Handle(); \
639 serialized_view ^= ReadMessage(thread, message.get()); \
640 for (int i = 0; i < length; i++) { \
641 EXPECT_EQ(static_cast<ctype>(data[i]), \
642 serialized_view.Get##darttype(i* scale)); \
643 } \
644 }
645
646ISOLATE_UNIT_TEST_CASE(SerializeTypedArray) {
647 TEST_TYPED_ARRAY(Int8, int8_t);
648 TEST_TYPED_ARRAY(Uint8, uint8_t);
649 TEST_TYPED_ARRAY(Int16, int16_t);
650 TEST_TYPED_ARRAY(Uint16, uint16_t);
651 TEST_TYPED_ARRAY(Int32, int32_t);
652 TEST_TYPED_ARRAY(Uint32, uint32_t);
653 TEST_TYPED_ARRAY(Int64, int64_t);
654 TEST_TYPED_ARRAY(Uint64, uint64_t);
655 TEST_TYPED_ARRAY(Float32, float);
656 TEST_TYPED_ARRAY(Float64, double);
657}
658
659ISOLATE_UNIT_TEST_CASE(SerializeExternalTypedArray) {
660 TEST_EXTERNAL_TYPED_ARRAY(Int8, int8_t);
661 TEST_EXTERNAL_TYPED_ARRAY(Uint8, uint8_t);
662 TEST_EXTERNAL_TYPED_ARRAY(Int16, int16_t);
663 TEST_EXTERNAL_TYPED_ARRAY(Uint16, uint16_t);
664 TEST_EXTERNAL_TYPED_ARRAY(Int32, int32_t);
665 TEST_EXTERNAL_TYPED_ARRAY(Uint32, uint32_t);
666 TEST_EXTERNAL_TYPED_ARRAY(Int64, int64_t);
667 TEST_EXTERNAL_TYPED_ARRAY(Uint64, uint64_t);
668 TEST_EXTERNAL_TYPED_ARRAY(Float32, float);
669 TEST_EXTERNAL_TYPED_ARRAY(Float64, double);
670}
671
672ISOLATE_UNIT_TEST_CASE(SerializeUnmodifiableExternalTypedArray) {
683}
684
685ISOLATE_UNIT_TEST_CASE(SerializeEmptyByteArray) {
686 // Write snapshot with object content.
687 const int kTypedDataLength = 0;
688 TypedData& typed_data = TypedData::Handle(
689 TypedData::New(kTypedDataUint8ArrayCid, kTypedDataLength));
690 std::unique_ptr<Message> message =
691 WriteMessage(/* same_group */ false, typed_data, ILLEGAL_PORT,
693
694 // Read object back from the snapshot.
695 TypedData& serialized_typed_data = TypedData::Handle();
696 serialized_typed_data ^= ReadMessage(thread, message.get());
697 EXPECT(serialized_typed_data.IsTypedData());
698
699 // Read object back from the snapshot into a C structure.
700 ApiNativeScope scope;
701 Dart_CObject* root = ReadApiMessage(scope.zone(), message.get());
702 EXPECT_EQ(Dart_CObject_kTypedData, root->type);
703 EXPECT_EQ(Dart_TypedData_kUint8, root->value.as_typed_data.type);
704 EXPECT_EQ(kTypedDataLength, root->value.as_typed_data.length);
705 EXPECT(root->value.as_typed_data.values == nullptr);
706 CheckEncodeDecodeMessage(scope.zone(), root);
707}
708
709VM_UNIT_TEST_CASE(FullSnapshot) {
710 // clang-format off
711 auto kScriptChars = Utils::CStringUniquePtr(
713 nullptr,
714 "class Fields {\n"
715 " Fields(int i, int j) : fld1 = i, fld2 = j {}\n"
716 " int fld1;\n"
717 " final int fld2;\n"
718 " final int bigint_fld = 0xfffffffffff;\n"
719 " static int%s fld3;\n"
720 " static const int smi_sfld = 10;\n"
721 " static const int bigint_sfld = 0xfffffffffff;\n"
722 "}\n"
723 "class Expect {\n"
724 " static void equals(x, y) {\n"
725 " if (x != y) throw new ArgumentError('not equal');\n"
726 " }\n"
727 "}\n"
728 "class FieldsTest {\n"
729 " static Fields testMain() {\n"
730 " Expect.equals(true, Fields.bigint_sfld == 0xfffffffffff);\n"
731 " Fields obj = new Fields(10, 20);\n"
732 " Expect.equals(true, obj.bigint_fld == 0xfffffffffff);\n"
733 " return obj;\n"
734 " }\n"
735 "}\n",
737 std::free);
738 // clang-format on
740
741 uint8_t* isolate_snapshot_data_buffer;
742
743 // Start an Isolate, load a script and create a full snapshot.
744 Timer timer1;
745 timer1.Start();
746 {
747 TestIsolateScope __test_isolate__;
748
749 // Create a test library and Load up a test script in it.
750 TestCase::LoadTestScript(kScriptChars.get(), nullptr);
751
752 Thread* thread = Thread::Current();
753 TransitionNativeToVM transition(thread);
754 StackZone zone(thread);
755 HandleScope scope(thread);
756
758 {
759 TransitionVMToNative to_native(thread);
761 }
762 timer1.Stop();
763 OS::PrintErr("Without Snapshot: %" Pd64 "us\n", timer1.TotalElapsedTime());
764
765 // Write snapshot with object content.
767 FullSnapshotWriter writer(
768 Snapshot::kFull, /*vm_snapshot_data=*/nullptr, &isolate_snapshot_data,
769 /*vm_image_writer=*/nullptr, /*iso_image_writer=*/nullptr);
770 writer.WriteFullSnapshot();
771 // Take ownership so it doesn't get freed by the stream destructor.
772 intptr_t unused;
773 isolate_snapshot_data_buffer = isolate_snapshot_data.Steal(&unused);
774 }
775
776 // Now Create another isolate using the snapshot and execute a method
777 // from the script.
778 Timer timer2;
779 timer2.Start();
780 TestCase::CreateTestIsolateFromSnapshot(isolate_snapshot_data_buffer);
781 {
782 Dart_EnterScope(); // Start a Dart API scope for invoking API functions.
783 timer2.Stop();
784 OS::PrintErr("From Snapshot: %" Pd64 "us\n", timer2.TotalElapsedTime());
785
786 // Invoke a function which returns an object.
787 Dart_Handle cls = Dart_GetClass(TestCase::lib(), NewString("FieldsTest"));
788 result = Dart_Invoke(cls, NewString("testMain"), 0, nullptr);
791 }
793 free(isolate_snapshot_data_buffer);
794}
795
796// Helper function to call a top level Dart function and serialize the result.
797static std::unique_ptr<Message> GetSerialized(Dart_Handle lib,
798 const char* dart_function) {
800 {
802 result = Dart_Invoke(lib, NewString(dart_function), 0, nullptr);
804 }
806
807 // Serialize the object into a message.
808 return WriteMessage(/* same_group */ false, obj, ILLEGAL_PORT,
810}
811
812static void CheckString(Dart_Handle dart_string, const char* expected) {
814 String& str = String::Handle();
815 str ^= Api::UnwrapHandle(dart_string);
816 std::unique_ptr<Message> message = WriteMessage(
817 /* same_group */ false, str, ILLEGAL_PORT, Message::kNormalPriority);
818
819 // Read object back from the snapshot into a C structure.
820 ApiNativeScope scope;
821 Dart_CObject* root = ReadApiMessage(zone.GetZone(), message.get());
822 EXPECT_NOTNULL(root);
823 EXPECT_EQ(Dart_CObject_kString, root->type);
824 EXPECT_STREQ(expected, root->value.as_string);
825 CheckEncodeDecodeMessage(zone.GetZone(), root);
826}
827
828static void CheckStringInvalid(Dart_Handle dart_string) {
830 String& str = String::Handle();
831 str ^= Api::UnwrapHandle(dart_string);
832 std::unique_ptr<Message> message = WriteMessage(
833 /* same_group */ false, str, ILLEGAL_PORT, Message::kNormalPriority);
834
835 // Read object back from the snapshot into a C structure.
836 ApiNativeScope scope;
837 Dart_CObject* root = ReadApiMessage(zone.GetZone(), message.get());
838 EXPECT_NOTNULL(root);
839 EXPECT_EQ(Dart_CObject_kUnsupported, root->type);
840}
841
842VM_UNIT_TEST_CASE(DartGeneratedMessages) {
843 static const char* kCustomIsolateScriptChars =
844 "final int kArrayLength = 10;\n"
845 "getSmi() {\n"
846 " return 42;\n"
847 "}\n"
848 "getAsciiString() {\n"
849 " return \"Hello, world!\";\n"
850 "}\n"
851 "getNonAsciiString() {\n"
852 " return \"Blåbærgrød\";\n"
853 "}\n"
854 "getNonBMPString() {\n"
855 " return \"\\u{10000}\\u{1F601}\\u{1F637}\\u{20000}\";\n"
856 "}\n"
857 "getLeadSurrogateString() {\n"
858 " return String.fromCharCodes([0xd800]);\n"
859 "}\n"
860 "getTrailSurrogateString() {\n"
861 " return \"\\u{10000}\".substring(1);\n"
862 "}\n"
863 "getSurrogatesString() {\n"
864 " return String.fromCharCodes([0xdc00, 0xdc00, 0xd800, 0xd800]);\n"
865 "}\n"
866 "getCrappyString() {\n"
867 " return String.fromCharCodes([0xd800, 32, 0xdc00, 32]);\n"
868 "}\n"
869 "getList() {\n"
870 " return List.filled(kArrayLength, null);\n"
871 "}\n";
872
874 Isolate* isolate = Isolate::Current();
875 EXPECT(isolate != nullptr);
877
878 Dart_Handle lib =
880 EXPECT_VALID(lib);
881 Dart_Handle smi_result;
882 smi_result = Dart_Invoke(lib, NewString("getSmi"), 0, nullptr);
883 EXPECT_VALID(smi_result);
884
885 Dart_Handle ascii_string_result;
886 ascii_string_result =
887 Dart_Invoke(lib, NewString("getAsciiString"), 0, nullptr);
888 EXPECT_VALID(ascii_string_result);
889 EXPECT(Dart_IsString(ascii_string_result));
890
891 Dart_Handle non_ascii_string_result;
892 non_ascii_string_result =
893 Dart_Invoke(lib, NewString("getNonAsciiString"), 0, nullptr);
894 EXPECT_VALID(non_ascii_string_result);
895 EXPECT(Dart_IsString(non_ascii_string_result));
896
897 Dart_Handle non_bmp_string_result;
898 non_bmp_string_result =
899 Dart_Invoke(lib, NewString("getNonBMPString"), 0, nullptr);
900 EXPECT_VALID(non_bmp_string_result);
901 EXPECT(Dart_IsString(non_bmp_string_result));
902
903 Dart_Handle lead_surrogate_string_result;
904 lead_surrogate_string_result =
905 Dart_Invoke(lib, NewString("getLeadSurrogateString"), 0, nullptr);
906 EXPECT_VALID(lead_surrogate_string_result);
907 EXPECT(Dart_IsString(lead_surrogate_string_result));
908
909 Dart_Handle trail_surrogate_string_result;
910 trail_surrogate_string_result =
911 Dart_Invoke(lib, NewString("getTrailSurrogateString"), 0, nullptr);
912 EXPECT_VALID(trail_surrogate_string_result);
913 EXPECT(Dart_IsString(trail_surrogate_string_result));
914
915 Dart_Handle surrogates_string_result;
916 surrogates_string_result =
917 Dart_Invoke(lib, NewString("getSurrogatesString"), 0, nullptr);
918 EXPECT_VALID(surrogates_string_result);
919 EXPECT(Dart_IsString(surrogates_string_result));
920
921 Dart_Handle crappy_string_result;
922 crappy_string_result =
923 Dart_Invoke(lib, NewString("getCrappyString"), 0, nullptr);
924 EXPECT_VALID(crappy_string_result);
925 EXPECT(Dart_IsString(crappy_string_result));
926
927 {
928 Thread* thread = Thread::Current();
929 CHECK_API_SCOPE(thread);
930 TransitionNativeToVM transition(thread);
931 HANDLESCOPE(thread);
932
933 {
934 StackZone zone(thread);
935 Smi& smi = Smi::Handle();
936 smi ^= Api::UnwrapHandle(smi_result);
937 std::unique_ptr<Message> message = WriteMessage(
938 /* same_group */ false, smi, ILLEGAL_PORT, Message::kNormalPriority);
939
940 // Read object back from the snapshot into a C structure.
941 ApiNativeScope scope;
942 Dart_CObject* root = ReadApiMessage(scope.zone(), message.get());
943 EXPECT_NOTNULL(root);
944 EXPECT_EQ(Dart_CObject_kInt32, root->type);
945 EXPECT_EQ(42, root->value.as_int32);
946 CheckEncodeDecodeMessage(scope.zone(), root);
947 }
948 CheckString(ascii_string_result, "Hello, world!");
949 CheckString(non_ascii_string_result, "Blåbærgrød");
950 CheckString(non_bmp_string_result,
951 "\xf0\x90\x80\x80"
952 "\xf0\x9f\x98\x81"
953 "\xf0\x9f\x98\xb7"
954 "\xf0\xa0\x80\x80");
955 CheckStringInvalid(lead_surrogate_string_result);
956 CheckStringInvalid(trail_surrogate_string_result);
957 CheckStringInvalid(crappy_string_result);
958 CheckStringInvalid(surrogates_string_result);
959 }
962}
963
964VM_UNIT_TEST_CASE(DartGeneratedListMessages) {
965 const int kArrayLength = 10;
966 const char* kScriptChars =
967 "final int kArrayLength = 10;\n"
968 "getList() {\n"
969 " return List.filled(kArrayLength, null);\n"
970 "}\n"
971 "getIntList() {\n"
972 " var list = List<int>.filled(kArrayLength, 0);\n"
973 " for (var i = 0; i < kArrayLength; i++) list[i] = i;\n"
974 " return list;\n"
975 "}\n"
976 "getStringList() {\n"
977 " var list = List<String>.filled(kArrayLength, '');\n"
978 " for (var i = 0; i < kArrayLength; i++) list[i] = i.toString();\n"
979 " return list;\n"
980 "}\n"
981 "getMixedList() {\n"
982 " var list = List<dynamic>.filled(kArrayLength, null);\n"
983 " list[0] = 0;\n"
984 " list[1] = '1';\n"
985 " list[2] = 2.2;\n"
986 " list[3] = true;\n"
987 " return list;\n"
988 "}\n";
989
991 Thread* thread = Thread::Current();
992 EXPECT(thread->isolate() != nullptr);
994
995 Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, nullptr);
996 EXPECT_VALID(lib);
997
998 {
999 CHECK_API_SCOPE(thread);
1000 TransitionNativeToVM transition(thread);
1001 HANDLESCOPE(thread);
1002 StackZone zone(thread);
1003 {
1004 // Generate a list of nulls from Dart code.
1005 std::unique_ptr<Message> message = GetSerialized(lib, "getList");
1006 ApiNativeScope scope;
1007 Dart_CObject* root = ReadApiMessage(scope.zone(), message.get());
1008 EXPECT_NOTNULL(root);
1009 EXPECT_EQ(Dart_CObject_kArray, root->type);
1010 EXPECT_EQ(kArrayLength, root->value.as_array.length);
1011 for (int i = 0; i < kArrayLength; i++) {
1012 EXPECT_EQ(Dart_CObject_kNull, root->value.as_array.values[i]->type);
1013 }
1014 CheckEncodeDecodeMessage(scope.zone(), root);
1015 }
1016 {
1017 // Generate a list of ints from Dart code.
1018 std::unique_ptr<Message> message = GetSerialized(lib, "getIntList");
1019 ApiNativeScope scope;
1020 Dart_CObject* root = ReadApiMessage(scope.zone(), message.get());
1021 EXPECT_NOTNULL(root);
1022 EXPECT_EQ(Dart_CObject_kArray, root->type);
1023 EXPECT_EQ(kArrayLength, root->value.as_array.length);
1024 for (int i = 0; i < kArrayLength; i++) {
1025 EXPECT_EQ(Dart_CObject_kInt32, root->value.as_array.values[i]->type);
1026 EXPECT_EQ(i, root->value.as_array.values[i]->value.as_int32);
1027 }
1028 CheckEncodeDecodeMessage(scope.zone(), root);
1029 }
1030 {
1031 // Generate a list of strings from Dart code.
1032 std::unique_ptr<Message> message = GetSerialized(lib, "getStringList");
1033 ApiNativeScope scope;
1034 Dart_CObject* root = ReadApiMessage(scope.zone(), message.get());
1035 EXPECT_NOTNULL(root);
1036 EXPECT_EQ(Dart_CObject_kArray, root->type);
1037 EXPECT_EQ(kArrayLength, root->value.as_array.length);
1038 for (int i = 0; i < kArrayLength; i++) {
1039 EXPECT_EQ(Dart_CObject_kString, root->value.as_array.values[i]->type);
1040 char buffer[3];
1041 snprintf(buffer, sizeof(buffer), "%d", i);
1042 EXPECT_STREQ(buffer, root->value.as_array.values[i]->value.as_string);
1043 }
1044 }
1045 {
1046 // Generate a list of objects of different types from Dart code.
1047 std::unique_ptr<Message> message = GetSerialized(lib, "getMixedList");
1048 ApiNativeScope scope;
1049 Dart_CObject* root = ReadApiMessage(scope.zone(), message.get());
1050 EXPECT_NOTNULL(root);
1051 EXPECT_EQ(Dart_CObject_kArray, root->type);
1052 EXPECT_EQ(kArrayLength, root->value.as_array.length);
1053
1054 EXPECT_EQ(Dart_CObject_kInt32, root->value.as_array.values[0]->type);
1055 EXPECT_EQ(0, root->value.as_array.values[0]->value.as_int32);
1056 EXPECT_EQ(Dart_CObject_kString, root->value.as_array.values[1]->type);
1057 EXPECT_STREQ("1", root->value.as_array.values[1]->value.as_string);
1058 EXPECT_EQ(Dart_CObject_kDouble, root->value.as_array.values[2]->type);
1059 EXPECT_EQ(2.2, root->value.as_array.values[2]->value.as_double);
1060 EXPECT_EQ(Dart_CObject_kBool, root->value.as_array.values[3]->type);
1061 EXPECT_EQ(true, root->value.as_array.values[3]->value.as_bool);
1062
1063 for (int i = 0; i < kArrayLength; i++) {
1064 if (i > 3) {
1065 EXPECT_EQ(Dart_CObject_kNull, root->value.as_array.values[i]->type);
1066 }
1067 }
1068 }
1069 }
1072}
1073
1074VM_UNIT_TEST_CASE(DartGeneratedArrayLiteralMessages) {
1075 const int kArrayLength = 10;
1076 const char* kScriptChars =
1077 "final int kArrayLength = 10;\n"
1078 "getList() {\n"
1079 " return [null, null, null, null, null, null, null, null, null, null];\n"
1080 "}\n"
1081 "getIntList() {\n"
1082 " return [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];\n"
1083 "}\n"
1084 "getStringList() {\n"
1085 " return ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];\n"
1086 "}\n"
1087 "getListList() {\n"
1088 " return <dynamic>[[],"
1089 " [0],"
1090 " [0, 1],"
1091 " [0, 1, 2],"
1092 " [0, 1, 2, 3],"
1093 " [0, 1, 2, 3, 4],"
1094 " [0, 1, 2, 3, 4, 5],"
1095 " [0, 1, 2, 3, 4, 5, 6],"
1096 " [0, 1, 2, 3, 4, 5, 6, 7],"
1097 " [0, 1, 2, 3, 4, 5, 6, 7, 8]];\n"
1098 "}\n"
1099 "getMixedList() {\n"
1100 " var list = [];\n"
1101 " list.add(0);\n"
1102 " list.add('1');\n"
1103 " list.add(2.2);\n"
1104 " list.add(true);\n"
1105 " list.add([]);\n"
1106 " list.add(<dynamic>[[]]);\n"
1107 " list.add(<dynamic>[<dynamic>[[]]]);\n"
1108 " list.add(<dynamic>[1, <dynamic>[2, [3]]]);\n"
1109 " list.add(<dynamic>[1, <dynamic>[1, 2, [1, 2, 3]]]);\n"
1110 " list.add([1, 2, 3]);\n"
1111 " return list;\n"
1112 "}\n";
1113
1115 Thread* thread = Thread::Current();
1116 EXPECT(thread->isolate() != nullptr);
1118
1119 Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, nullptr);
1120 EXPECT_VALID(lib);
1121
1122 {
1123 CHECK_API_SCOPE(thread);
1124 TransitionNativeToVM transition(thread);
1125 HANDLESCOPE(thread);
1126 StackZone zone(thread);
1127 {
1128 // Generate a list of nulls from Dart code.
1129 std::unique_ptr<Message> message = GetSerialized(lib, "getList");
1130 ApiNativeScope scope;
1131 Dart_CObject* root = ReadApiMessage(scope.zone(), message.get());
1132 EXPECT_NOTNULL(root);
1133 EXPECT_EQ(Dart_CObject_kArray, root->type);
1134 EXPECT_EQ(kArrayLength, root->value.as_array.length);
1135 for (int i = 0; i < kArrayLength; i++) {
1136 EXPECT_EQ(Dart_CObject_kNull, root->value.as_array.values[i]->type);
1137 }
1138 CheckEncodeDecodeMessage(scope.zone(), root);
1139 }
1140 {
1141 // Generate a list of ints from Dart code.
1142 std::unique_ptr<Message> message = GetSerialized(lib, "getIntList");
1143 ApiNativeScope scope;
1144 Dart_CObject* root = ReadApiMessage(scope.zone(), message.get());
1145 EXPECT_NOTNULL(root);
1146 EXPECT_EQ(Dart_CObject_kArray, root->type);
1147 EXPECT_EQ(kArrayLength, root->value.as_array.length);
1148 for (int i = 0; i < kArrayLength; i++) {
1149 EXPECT_EQ(Dart_CObject_kInt32, root->value.as_array.values[i]->type);
1150 EXPECT_EQ(i, root->value.as_array.values[i]->value.as_int32);
1151 }
1152 CheckEncodeDecodeMessage(scope.zone(), root);
1153 }
1154 {
1155 // Generate a list of strings from Dart code.
1156 std::unique_ptr<Message> message = GetSerialized(lib, "getStringList");
1157 ApiNativeScope scope;
1158 Dart_CObject* root = ReadApiMessage(scope.zone(), message.get());
1159 EXPECT_NOTNULL(root);
1160 EXPECT_EQ(Dart_CObject_kArray, root->type);
1161 EXPECT_EQ(kArrayLength, root->value.as_array.length);
1162 for (int i = 0; i < kArrayLength; i++) {
1163 EXPECT_EQ(Dart_CObject_kString, root->value.as_array.values[i]->type);
1164 char buffer[3];
1165 snprintf(buffer, sizeof(buffer), "%d", i);
1166 EXPECT_STREQ(buffer, root->value.as_array.values[i]->value.as_string);
1167 }
1168 }
1169 {
1170 // Generate a list of lists from Dart code.
1171 std::unique_ptr<Message> message = GetSerialized(lib, "getListList");
1172 ApiNativeScope scope;
1173 Dart_CObject* root = ReadApiMessage(scope.zone(), message.get());
1174 EXPECT_NOTNULL(root);
1175 EXPECT_EQ(Dart_CObject_kArray, root->type);
1176 EXPECT_EQ(kArrayLength, root->value.as_array.length);
1177 for (int i = 0; i < kArrayLength; i++) {
1178 Dart_CObject* element = root->value.as_array.values[i];
1179 EXPECT_EQ(Dart_CObject_kArray, element->type);
1180 EXPECT_EQ(i, element->value.as_array.length);
1181 for (int j = 0; j < i; j++) {
1182 EXPECT_EQ(Dart_CObject_kInt32,
1183 element->value.as_array.values[j]->type);
1184 EXPECT_EQ(j, element->value.as_array.values[j]->value.as_int32);
1185 }
1186 }
1187 }
1188 {
1189 // Generate a list of objects of different types from Dart code.
1190 std::unique_ptr<Message> message = GetSerialized(lib, "getMixedList");
1191 ApiNativeScope scope;
1192 Dart_CObject* root = ReadApiMessage(scope.zone(), message.get());
1193 EXPECT_NOTNULL(root);
1194 EXPECT_EQ(Dart_CObject_kArray, root->type);
1195 EXPECT_EQ(kArrayLength, root->value.as_array.length);
1196
1197 EXPECT_EQ(Dart_CObject_kInt32, root->value.as_array.values[0]->type);
1198 EXPECT_EQ(0, root->value.as_array.values[0]->value.as_int32);
1199 EXPECT_EQ(Dart_CObject_kString, root->value.as_array.values[1]->type);
1200 EXPECT_STREQ("1", root->value.as_array.values[1]->value.as_string);
1201 EXPECT_EQ(Dart_CObject_kDouble, root->value.as_array.values[2]->type);
1202 EXPECT_EQ(2.2, root->value.as_array.values[2]->value.as_double);
1203 EXPECT_EQ(Dart_CObject_kBool, root->value.as_array.values[3]->type);
1204 EXPECT_EQ(true, root->value.as_array.values[3]->value.as_bool);
1205
1206 for (int i = 0; i < kArrayLength; i++) {
1207 if (i > 3) {
1208 EXPECT_EQ(Dart_CObject_kArray, root->value.as_array.values[i]->type);
1209 }
1210 }
1211
1212 Dart_CObject* element;
1213 Dart_CObject* e;
1214
1215 // []
1216 element = root->value.as_array.values[4];
1217 EXPECT_EQ(0, element->value.as_array.length);
1218
1219 // [[]]
1220 element = root->value.as_array.values[5];
1221 EXPECT_EQ(1, element->value.as_array.length);
1222 element = element->value.as_array.values[0];
1223 EXPECT_EQ(Dart_CObject_kArray, element->type);
1224 EXPECT_EQ(0, element->value.as_array.length);
1225
1226 // [[[]]]"
1227 element = root->value.as_array.values[6];
1228 EXPECT_EQ(1, element->value.as_array.length);
1229 element = element->value.as_array.values[0];
1230 EXPECT_EQ(Dart_CObject_kArray, element->type);
1231 EXPECT_EQ(1, element->value.as_array.length);
1232 element = element->value.as_array.values[0];
1233 EXPECT_EQ(Dart_CObject_kArray, element->type);
1234 EXPECT_EQ(0, element->value.as_array.length);
1235
1236 // [1, [2, [3]]]
1237 element = root->value.as_array.values[7];
1238 EXPECT_EQ(2, element->value.as_array.length);
1239 e = element->value.as_array.values[0];
1240 EXPECT_EQ(Dart_CObject_kInt32, e->type);
1241 EXPECT_EQ(1, e->value.as_int32);
1242 element = element->value.as_array.values[1];
1243 EXPECT_EQ(Dart_CObject_kArray, element->type);
1244 EXPECT_EQ(2, element->value.as_array.length);
1245 e = element->value.as_array.values[0];
1246 EXPECT_EQ(Dart_CObject_kInt32, e->type);
1247 EXPECT_EQ(2, e->value.as_int32);
1248 element = element->value.as_array.values[1];
1249 EXPECT_EQ(Dart_CObject_kArray, element->type);
1250 EXPECT_EQ(1, element->value.as_array.length);
1251 e = element->value.as_array.values[0];
1252 EXPECT_EQ(Dart_CObject_kInt32, e->type);
1253 EXPECT_EQ(3, e->value.as_int32);
1254
1255 // [1, [1, 2, [1, 2, 3]]]
1256 element = root->value.as_array.values[8];
1257 EXPECT_EQ(2, element->value.as_array.length);
1258 e = element->value.as_array.values[0];
1259 EXPECT_EQ(Dart_CObject_kInt32, e->type);
1260 e = element->value.as_array.values[0];
1261 EXPECT_EQ(Dart_CObject_kInt32, e->type);
1262 EXPECT_EQ(1, e->value.as_int32);
1263 element = element->value.as_array.values[1];
1264 EXPECT_EQ(Dart_CObject_kArray, element->type);
1265 EXPECT_EQ(3, element->value.as_array.length);
1266 for (int i = 0; i < 2; i++) {
1267 e = element->value.as_array.values[i];
1268 EXPECT_EQ(Dart_CObject_kInt32, e->type);
1269 EXPECT_EQ(i + 1, e->value.as_int32);
1270 }
1271 element = element->value.as_array.values[2];
1272 EXPECT_EQ(Dart_CObject_kArray, element->type);
1273 EXPECT_EQ(3, element->value.as_array.length);
1274 for (int i = 0; i < 3; i++) {
1275 e = element->value.as_array.values[i];
1276 EXPECT_EQ(Dart_CObject_kInt32, e->type);
1277 EXPECT_EQ(i + 1, e->value.as_int32);
1278 }
1279
1280 // [1, 2, 3]
1281 element = root->value.as_array.values[9];
1282 EXPECT_EQ(3, element->value.as_array.length);
1283 for (int i = 0; i < 3; i++) {
1284 e = element->value.as_array.values[i];
1285 EXPECT_EQ(Dart_CObject_kInt32, e->type);
1286 EXPECT_EQ(i + 1, e->value.as_int32);
1287 }
1288 }
1289 }
1292}
1293
1294VM_UNIT_TEST_CASE(DartGeneratedListMessagesWithBackref) {
1295 const int kArrayLength = 10;
1296 const char* kScriptChars =
1297 "import 'dart:typed_data';\n"
1298 "final int kArrayLength = 10;\n"
1299 "getStringList() {\n"
1300 " var s = 'Hello, world!';\n"
1301 " var list = List<String>.filled(kArrayLength, '');\n"
1302 " for (var i = 0; i < kArrayLength; i++) list[i] = s;\n"
1303 " return list;\n"
1304 "}\n"
1305 "getMintList() {\n"
1306 " var mint = 0x7FFFFFFFFFFFFFFF;\n"
1307 " var list = List.filled(kArrayLength, 0);\n"
1308 " for (var i = 0; i < kArrayLength; i++) list[i] = mint;\n"
1309 " return list;\n"
1310 "}\n"
1311 "getDoubleList() {\n"
1312 " var d = 3.14;\n"
1313 " var list = List<double>.filled(kArrayLength, 0.0);\n"
1314 " for (var i = 0; i < kArrayLength; i++) list[i] = d;\n"
1315 " return list;\n"
1316 "}\n"
1317 "getTypedDataList() {\n"
1318 " var byte_array = Uint8List(256);\n"
1319 " var list = List<dynamic>.filled(kArrayLength, null);\n"
1320 " for (var i = 0; i < kArrayLength; i++) list[i] = byte_array;\n"
1321 " return list;\n"
1322 "}\n"
1323 "getTypedDataViewList() {\n"
1324 " var uint8_list = Uint8List(256);\n"
1325 " uint8_list[64] = 1;\n"
1326 " var uint8_list_view =\n"
1327 " Uint8List.view(uint8_list.buffer, 64, 128);\n"
1328 " var list = List<dynamic>.filled(kArrayLength, null);\n"
1329 " for (var i = 0; i < kArrayLength; i++) list[i] = uint8_list_view;\n"
1330 " return list;\n"
1331 "}\n"
1332 "getMixedList() {\n"
1333 " var list = List<dynamic>.filled(kArrayLength, null);\n"
1334 " for (var i = 0; i < kArrayLength; i++) {\n"
1335 " list[i] = ((i % 2) == 0) ? 'A' : 2.72;\n"
1336 " }\n"
1337 " return list;\n"
1338 "}\n"
1339 "getSelfRefList() {\n"
1340 " var list = List<dynamic>.filled(kArrayLength, null, growable: true);\n"
1341 " for (var i = 0; i < kArrayLength; i++) {\n"
1342 " list[i] = list;\n"
1343 " }\n"
1344 " return list;\n"
1345 "}\n";
1346
1348 Thread* thread = Thread::Current();
1349 EXPECT(thread->isolate() != nullptr);
1351
1352 Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, nullptr);
1353 EXPECT_VALID(lib);
1354
1355 {
1356 CHECK_API_SCOPE(thread);
1357 TransitionNativeToVM transition(thread);
1358 HANDLESCOPE(thread);
1359 StackZone zone(thread);
1360 {
1361 // Generate a list of strings from Dart code.
1362 std::unique_ptr<Message> message = GetSerialized(lib, "getStringList");
1363 ApiNativeScope scope;
1364 Dart_CObject* root = ReadApiMessage(scope.zone(), message.get());
1365 EXPECT_NOTNULL(root);
1366 EXPECT_EQ(Dart_CObject_kArray, root->type);
1367 EXPECT_EQ(kArrayLength, root->value.as_array.length);
1368 for (int i = 0; i < kArrayLength; i++) {
1369 Dart_CObject* element = root->value.as_array.values[i];
1370 EXPECT_EQ(root->value.as_array.values[0], element);
1371 EXPECT_EQ(Dart_CObject_kString, element->type);
1372 EXPECT_STREQ("Hello, world!", element->value.as_string);
1373 }
1374 }
1375 {
1376 // Generate a list of medium ints from Dart code.
1377 std::unique_ptr<Message> message = GetSerialized(lib, "getMintList");
1378 ApiNativeScope scope;
1379 Dart_CObject* root = ReadApiMessage(scope.zone(), message.get());
1380 EXPECT_NOTNULL(root);
1381 EXPECT_EQ(Dart_CObject_kArray, root->type);
1382 EXPECT_EQ(kArrayLength, root->value.as_array.length);
1383 for (int i = 0; i < kArrayLength; i++) {
1384 Dart_CObject* element = root->value.as_array.values[i];
1385 EXPECT_EQ(root->value.as_array.values[0], element);
1386 EXPECT_EQ(Dart_CObject_kInt64, element->type);
1387 EXPECT_EQ(DART_INT64_C(0x7FFFFFFFFFFFFFFF), element->value.as_int64);
1388 }
1389 }
1390 {
1391 // Generate a list of doubles from Dart code.
1392 std::unique_ptr<Message> message = GetSerialized(lib, "getDoubleList");
1393 ApiNativeScope scope;
1394 Dart_CObject* root = ReadApiMessage(scope.zone(), message.get());
1395 EXPECT_NOTNULL(root);
1396 EXPECT_EQ(Dart_CObject_kArray, root->type);
1397 EXPECT_EQ(kArrayLength, root->value.as_array.length);
1398 Dart_CObject* element = root->value.as_array.values[0];
1399 EXPECT_EQ(Dart_CObject_kDouble, element->type);
1400 EXPECT_EQ(3.14, element->value.as_double);
1401 for (int i = 1; i < kArrayLength; i++) {
1402 element = root->value.as_array.values[i];
1403 EXPECT_EQ(Dart_CObject_kDouble, element->type);
1404 EXPECT_EQ(3.14, element->value.as_double);
1405 }
1406 }
1407 {
1408 // Generate a list of Uint8Lists from Dart code.
1409 std::unique_ptr<Message> message = GetSerialized(lib, "getTypedDataList");
1410 ApiNativeScope scope;
1411 Dart_CObject* root = ReadApiMessage(scope.zone(), message.get());
1412 EXPECT_NOTNULL(root);
1413 EXPECT_EQ(Dart_CObject_kArray, root->type);
1414 EXPECT_EQ(kArrayLength, root->value.as_array.length);
1415 for (int i = 0; i < kArrayLength; i++) {
1416 Dart_CObject* element = root->value.as_array.values[i];
1417 EXPECT_EQ(root->value.as_array.values[0], element);
1418 EXPECT_EQ(Dart_CObject_kTypedData, element->type);
1419 EXPECT_EQ(Dart_TypedData_kUint8, element->value.as_typed_data.type);
1420 EXPECT_EQ(256, element->value.as_typed_data.length);
1421 }
1422 }
1423 {
1424 // Generate a list of Uint8List views from Dart code.
1425 std::unique_ptr<Message> message =
1426 GetSerialized(lib, "getTypedDataViewList");
1427 ApiNativeScope scope;
1428 Dart_CObject* root = ReadApiMessage(scope.zone(), message.get());
1429 EXPECT_NOTNULL(root);
1430 EXPECT_EQ(Dart_CObject_kArray, root->type);
1431 EXPECT_EQ(kArrayLength, root->value.as_array.length);
1432 for (int i = 0; i < kArrayLength; i++) {
1433 Dart_CObject* element = root->value.as_array.values[i];
1434 EXPECT_EQ(root->value.as_array.values[0], element);
1435 EXPECT_EQ(Dart_CObject_kTypedData, element->type);
1436 EXPECT_EQ(Dart_TypedData_kUint8, element->value.as_typed_data.type);
1437 EXPECT_EQ(128, element->value.as_typed_data.length);
1438 EXPECT_EQ(1, element->value.as_typed_data.values[0]);
1439 EXPECT_EQ(0, element->value.as_typed_data.values[1]);
1440 }
1441 }
1442 {
1443 // Generate a list of objects of different types from Dart code.
1444 std::unique_ptr<Message> message = GetSerialized(lib, "getMixedList");
1445 ApiNativeScope scope;
1446 Dart_CObject* root = ReadApiMessage(scope.zone(), message.get());
1447 EXPECT_NOTNULL(root);
1448 EXPECT_EQ(Dart_CObject_kArray, root->type);
1449 EXPECT_EQ(kArrayLength, root->value.as_array.length);
1450 Dart_CObject* element = root->value.as_array.values[0];
1451 EXPECT_EQ(Dart_CObject_kString, element->type);
1452 EXPECT_STREQ("A", element->value.as_string);
1453 element = root->value.as_array.values[1];
1454 EXPECT_EQ(Dart_CObject_kDouble, element->type);
1455 EXPECT_EQ(2.72, element->value.as_double);
1456 for (int i = 2; i < kArrayLength; i++) {
1457 element = root->value.as_array.values[i];
1458 if ((i % 2) == 0) {
1459 EXPECT_EQ(root->value.as_array.values[0], element);
1460 EXPECT_EQ(Dart_CObject_kString, element->type);
1461 EXPECT_STREQ("A", element->value.as_string);
1462 } else {
1463 EXPECT_EQ(Dart_CObject_kDouble, element->type);
1464 EXPECT_EQ(2.72, element->value.as_double);
1465 }
1466 }
1467 }
1468 {
1469 // Generate a list of objects of different types from Dart code.
1470 std::unique_ptr<Message> message = GetSerialized(lib, "getSelfRefList");
1471 ApiNativeScope scope;
1472 Dart_CObject* root = ReadApiMessage(scope.zone(), message.get());
1473 EXPECT_NOTNULL(root);
1474 EXPECT_EQ(Dart_CObject_kArray, root->type);
1475 EXPECT_EQ(kArrayLength, root->value.as_array.length);
1476 for (int i = 0; i < kArrayLength; i++) {
1477 Dart_CObject* element = root->value.as_array.values[i];
1478 EXPECT_EQ(Dart_CObject_kArray, element->type);
1479 EXPECT_EQ(root, element);
1480 }
1481 }
1482 }
1485}
1486
1487VM_UNIT_TEST_CASE(DartGeneratedArrayLiteralMessagesWithBackref) {
1488 const int kArrayLength = 10;
1489 const char* kScriptChars =
1490 "import 'dart:typed_data';\n"
1491 "final int kArrayLength = 10;\n"
1492 "getStringList() {\n"
1493 " var s = 'Hello, world!';\n"
1494 " var list = [s, s, s, s, s, s, s, s, s, s];\n"
1495 " return list;\n"
1496 "}\n"
1497 "getMintList() {\n"
1498 " var mint = 0x7FFFFFFFFFFFFFFF;\n"
1499 " var list = [mint, mint, mint, mint, mint,\n"
1500 " mint, mint, mint, mint, mint];\n"
1501 " return list;\n"
1502 "}\n"
1503 "getDoubleList() {\n"
1504 " var d = 3.14;\n"
1505 " var list = [3.14, 3.14, 3.14, 3.14, 3.14, 3.14];\n"
1506 " list.add(3.14);\n"
1507 " list.add(3.14);\n"
1508 " list.add(3.14);\n"
1509 " list.add(3.14);\n"
1510 " return list;\n"
1511 "}\n"
1512 "getTypedDataList() {\n"
1513 " var byte_array = new Uint8List(256);\n"
1514 " var list = [];\n"
1515 " for (var i = 0; i < kArrayLength; i++) {\n"
1516 " list.add(byte_array);\n"
1517 " }\n"
1518 " return list;\n"
1519 "}\n"
1520 "getTypedDataViewList() {\n"
1521 " var uint8_list = new Uint8List(256);\n"
1522 " uint8_list[64] = 1;\n"
1523 " var uint8_list_view =\n"
1524 " new Uint8List.view(uint8_list.buffer, 64, 128);\n"
1525 " var list = [];\n"
1526 " for (var i = 0; i < kArrayLength; i++) {\n"
1527 " list.add(uint8_list_view);\n"
1528 " }\n"
1529 " return list;\n"
1530 "}\n"
1531 "getMixedList() {\n"
1532 " var list = [];\n"
1533 " for (var i = 0; i < kArrayLength; i++) {\n"
1534 " list.add(((i % 2) == 0) ? '.' : 2.72);\n"
1535 " }\n"
1536 " return list;\n"
1537 "}\n"
1538 "getSelfRefList() {\n"
1539 " var list = [];\n"
1540 " for (var i = 0; i < kArrayLength; i++) {\n"
1541 " list.add(list);\n"
1542 " }\n"
1543 " return list;\n"
1544 "}\n";
1545
1547 Thread* thread = Thread::Current();
1548 EXPECT(thread->isolate() != nullptr);
1550
1551 Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, nullptr);
1552 EXPECT_VALID(lib);
1553
1554 {
1555 CHECK_API_SCOPE(thread);
1556 TransitionNativeToVM transition(thread);
1557 HANDLESCOPE(thread);
1558 StackZone zone(thread);
1559 {
1560 // Generate a list of strings from Dart code.
1561 std::unique_ptr<Message> message = GetSerialized(lib, "getStringList");
1562 ApiNativeScope scope;
1563 Dart_CObject* root = ReadApiMessage(scope.zone(), message.get());
1564 EXPECT_NOTNULL(root);
1565 EXPECT_EQ(Dart_CObject_kArray, root->type);
1566 EXPECT_EQ(kArrayLength, root->value.as_array.length);
1567 for (int i = 0; i < kArrayLength; i++) {
1568 Dart_CObject* element = root->value.as_array.values[i];
1569 EXPECT_EQ(root->value.as_array.values[0], element);
1570 EXPECT_EQ(Dart_CObject_kString, element->type);
1571 EXPECT_STREQ("Hello, world!", element->value.as_string);
1572 }
1573 }
1574 {
1575 // Generate a list of medium ints from Dart code.
1576 std::unique_ptr<Message> message = GetSerialized(lib, "getMintList");
1577 ApiNativeScope scope;
1578 Dart_CObject* root = ReadApiMessage(scope.zone(), message.get());
1579 EXPECT_NOTNULL(root);
1580 EXPECT_EQ(Dart_CObject_kArray, root->type);
1581 EXPECT_EQ(kArrayLength, root->value.as_array.length);
1582 for (int i = 0; i < kArrayLength; i++) {
1583 Dart_CObject* element = root->value.as_array.values[i];
1584 EXPECT_EQ(root->value.as_array.values[0], element);
1585 EXPECT_EQ(Dart_CObject_kInt64, element->type);
1586 EXPECT_EQ(DART_INT64_C(0x7FFFFFFFFFFFFFFF), element->value.as_int64);
1587 }
1588 }
1589 {
1590 // Generate a list of doubles from Dart code.
1591 std::unique_ptr<Message> message = GetSerialized(lib, "getDoubleList");
1592 ApiNativeScope scope;
1593 Dart_CObject* root = ReadApiMessage(scope.zone(), message.get());
1594 EXPECT_NOTNULL(root);
1595 EXPECT_EQ(Dart_CObject_kArray, root->type);
1596 EXPECT_EQ(kArrayLength, root->value.as_array.length);
1597 Dart_CObject* element = root->value.as_array.values[0];
1598 EXPECT_EQ(Dart_CObject_kDouble, element->type);
1599 EXPECT_EQ(3.14, element->value.as_double);
1600 for (int i = 1; i < kArrayLength; i++) {
1601 element = root->value.as_array.values[i];
1602 EXPECT_EQ(Dart_CObject_kDouble, element->type);
1603 EXPECT_EQ(3.14, element->value.as_double);
1604 }
1605 }
1606 {
1607 // Generate a list of Uint8Lists from Dart code.
1608 std::unique_ptr<Message> message = GetSerialized(lib, "getTypedDataList");
1609 ApiNativeScope scope;
1610 Dart_CObject* root = ReadApiMessage(scope.zone(), message.get());
1611 EXPECT_NOTNULL(root);
1612 EXPECT_EQ(Dart_CObject_kArray, root->type);
1613 EXPECT_EQ(kArrayLength, root->value.as_array.length);
1614 for (int i = 0; i < kArrayLength; i++) {
1615 Dart_CObject* element = root->value.as_array.values[i];
1616 EXPECT_EQ(root->value.as_array.values[0], element);
1617 EXPECT_EQ(Dart_CObject_kTypedData, element->type);
1618 EXPECT_EQ(Dart_TypedData_kUint8, element->value.as_typed_data.type);
1619 EXPECT_EQ(256, element->value.as_typed_data.length);
1620 }
1621 }
1622 {
1623 // Generate a list of Uint8List views from Dart code.
1624 std::unique_ptr<Message> message =
1625 GetSerialized(lib, "getTypedDataViewList");
1626 ApiNativeScope scope;
1627 Dart_CObject* root = ReadApiMessage(scope.zone(), message.get());
1628 EXPECT_NOTNULL(root);
1629 EXPECT_EQ(Dart_CObject_kArray, root->type);
1630 EXPECT_EQ(kArrayLength, root->value.as_array.length);
1631 for (int i = 0; i < kArrayLength; i++) {
1632 Dart_CObject* element = root->value.as_array.values[i];
1633 EXPECT_EQ(root->value.as_array.values[0], element);
1634 EXPECT_EQ(Dart_CObject_kTypedData, element->type);
1635 EXPECT_EQ(Dart_TypedData_kUint8, element->value.as_typed_data.type);
1636 EXPECT_EQ(128, element->value.as_typed_data.length);
1637 EXPECT_EQ(1, element->value.as_typed_data.values[0]);
1638 EXPECT_EQ(0, element->value.as_typed_data.values[1]);
1639 }
1640 }
1641 {
1642 // Generate a list of objects of different types from Dart code.
1643 std::unique_ptr<Message> message = GetSerialized(lib, "getMixedList");
1644 ApiNativeScope scope;
1645 Dart_CObject* root = ReadApiMessage(scope.zone(), message.get());
1646 EXPECT_NOTNULL(root);
1647 EXPECT_EQ(Dart_CObject_kArray, root->type);
1648 EXPECT_EQ(kArrayLength, root->value.as_array.length);
1649 Dart_CObject* element = root->value.as_array.values[0];
1650 EXPECT_EQ(Dart_CObject_kString, element->type);
1651 EXPECT_STREQ(".", element->value.as_string);
1652 element = root->value.as_array.values[1];
1653 EXPECT_EQ(Dart_CObject_kDouble, element->type);
1654 EXPECT_EQ(2.72, element->value.as_double);
1655 for (int i = 2; i < kArrayLength; i++) {
1656 Dart_CObject* element = root->value.as_array.values[i];
1657 if ((i % 2) == 0) {
1658 EXPECT_EQ(root->value.as_array.values[0], element);
1659 EXPECT_EQ(Dart_CObject_kString, element->type);
1660 EXPECT_STREQ(".", element->value.as_string);
1661 } else {
1662 EXPECT_EQ(Dart_CObject_kDouble, element->type);
1663 EXPECT_EQ(2.72, element->value.as_double);
1664 }
1665 }
1666 }
1667 {
1668 // Generate a list of objects of different types from Dart code.
1669 std::unique_ptr<Message> message = GetSerialized(lib, "getSelfRefList");
1670 ApiNativeScope scope;
1671 Dart_CObject* root = ReadApiMessage(scope.zone(), message.get());
1672 EXPECT_NOTNULL(root);
1673 EXPECT_EQ(Dart_CObject_kArray, root->type);
1674 EXPECT_EQ(kArrayLength, root->value.as_array.length);
1675 for (int i = 0; i < kArrayLength; i++) {
1676 Dart_CObject* element = root->value.as_array.values[i];
1677 EXPECT_EQ(Dart_CObject_kArray, element->type);
1678 EXPECT_EQ(root, element);
1679 }
1680 }
1681 }
1684}
1685
1686static void CheckTypedData(Dart_CObject* object,
1687 Dart_TypedData_Type typed_data_type,
1688 int len) {
1689 EXPECT_EQ(Dart_CObject_kTypedData, object->type);
1690 EXPECT_EQ(typed_data_type, object->value.as_typed_data.type);
1691 EXPECT_EQ(len, object->value.as_typed_data.length);
1692}
1693
1694VM_UNIT_TEST_CASE(DartGeneratedListMessagesWithTypedData) {
1695 static const char* kScriptChars =
1696 "import 'dart:typed_data';\n"
1697 "getTypedDataList() {\n"
1698 " var list = List<dynamic>.filled(13, null);\n"
1699 " var index = 0;\n"
1700 " list[index++] = Int8List(256);\n"
1701 " list[index++] = Uint8List(256);\n"
1702 " list[index++] = Int16List(256);\n"
1703 " list[index++] = Uint16List(256);\n"
1704 " list[index++] = Int32List(256);\n"
1705 " list[index++] = Uint32List(256);\n"
1706 " list[index++] = Int64List(256);\n"
1707 " list[index++] = Uint64List(256);\n"
1708 " list[index++] = Float32List(256);\n"
1709 " list[index++] = Float64List(256);\n"
1710 " list[index++] = Int32x4List(256);\n"
1711 " list[index++] = Float32x4List(256);\n"
1712 " list[index++] = Float64x2List(256);\n"
1713 " return list;\n"
1714 "}\n"
1715 "getTypedDataViewList() {\n"
1716 " var list = List<dynamic>.filled(45, null);\n"
1717 " var index = 0;\n"
1718 " list[index++] = Int8List.view(Int8List(256).buffer);\n"
1719 " list[index++] = Uint8List.view(Uint8List(256).buffer);\n"
1720 " list[index++] = Int16List.view(new Int16List(256).buffer);\n"
1721 " list[index++] = Uint16List.view(new Uint16List(256).buffer);\n"
1722 " list[index++] = Int32List.view(new Int32List(256).buffer);\n"
1723 " list[index++] = Uint32List.view(new Uint32List(256).buffer);\n"
1724 " list[index++] = Int64List.view(new Int64List(256).buffer);\n"
1725 " list[index++] = Uint64List.view(new Uint64List(256).buffer);\n"
1726 " list[index++] = Float32List.view(new Float32List(256).buffer);\n"
1727 " list[index++] = Float64List.view(new Float64List(256).buffer);\n"
1728 " list[index++] = Int32x4List.view(new Int32x4List(256).buffer);\n"
1729 " list[index++] = Float32x4List.view(new Float32x4List(256).buffer);\n"
1730 " list[index++] = Float64x2List.view(new Float64x2List(256).buffer);\n"
1731
1732 " list[index++] = Int8List.view(new Int16List(256).buffer);\n"
1733 " list[index++] = Uint8List.view(new Uint16List(256).buffer);\n"
1734 " list[index++] = Int8List.view(new Int32List(256).buffer);\n"
1735 " list[index++] = Uint8List.view(new Uint32List(256).buffer);\n"
1736 " list[index++] = Int8List.view(new Int64List(256).buffer);\n"
1737 " list[index++] = Uint8List.view(new Uint64List(256).buffer);\n"
1738 " list[index++] = Int8List.view(new Float32List(256).buffer);\n"
1739 " list[index++] = Uint8List.view(new Float32List(256).buffer);\n"
1740 " list[index++] = Int8List.view(new Float64List(256).buffer);\n"
1741 " list[index++] = Uint8List.view(new Float64List(256).buffer);\n"
1742 " list[index++] = Int8List.view(new Int32x4List(256).buffer);\n"
1743 " list[index++] = Uint8List.view(new Int32x4List(256).buffer);\n"
1744 " list[index++] = Int8List.view(new Float32x4List(256).buffer);\n"
1745 " list[index++] = Uint8List.view(new Float32x4List(256).buffer);\n"
1746 " list[index++] = Int8List.view(new Float64x2List(256).buffer);\n"
1747 " list[index++] = Uint8List.view(new Float64x2List(256).buffer);\n"
1748
1749 " list[index++] = Int16List.view(new Int8List(256).buffer);\n"
1750 " list[index++] = Uint16List.view(new Uint8List(256).buffer);\n"
1751 " list[index++] = Int16List.view(new Int32List(256).buffer);\n"
1752 " list[index++] = Uint16List.view(new Uint32List(256).buffer);\n"
1753 " list[index++] = Int16List.view(new Int64List(256).buffer);\n"
1754 " list[index++] = Uint16List.view(new Uint64List(256).buffer);\n"
1755 " list[index++] = Int16List.view(new Float32List(256).buffer);\n"
1756 " list[index++] = Uint16List.view(new Float32List(256).buffer);\n"
1757 " list[index++] = Int16List.view(new Float64List(256).buffer);\n"
1758 " list[index++] = Uint16List.view(new Float64List(256).buffer);\n"
1759 " list[index++] = Int16List.view(new Int32x4List(256).buffer);\n"
1760 " list[index++] = Uint16List.view(new Int32x4List(256).buffer);\n"
1761 " list[index++] = Int16List.view(new Float32x4List(256).buffer);\n"
1762 " list[index++] = Uint16List.view(new Float32x4List(256).buffer);\n"
1763 " list[index++] = Int16List.view(new Float64x2List(256).buffer);\n"
1764 " list[index++] = Uint16List.view(new Float64x2List(256).buffer);\n"
1765 " return list;\n"
1766 "}\n"
1767 "getMultipleTypedDataViewList() {\n"
1768 " var list = List<dynamic>.filled(13, null);\n"
1769 " var index = 0;\n"
1770 " var data = Uint8List(256).buffer;\n"
1771 " list[index++] = Int8List.view(data);\n"
1772 " list[index++] = Uint8List.view(data);\n"
1773 " list[index++] = Int16List.view(data);\n"
1774 " list[index++] = Uint16List.view(data);\n"
1775 " list[index++] = Int32List.view(data);\n"
1776 " list[index++] = Uint32List.view(data);\n"
1777 " list[index++] = Int64List.view(data);\n"
1778 " list[index++] = Uint64List.view(data);\n"
1779 " list[index++] = Float32List.view(data);\n"
1780 " list[index++] = Float64List.view(data);\n"
1781 " list[index++] = Int32x4List.view(data);\n"
1782 " list[index++] = Float32x4List.view(data);\n"
1783 " list[index++] = Float64x2List.view(data);\n"
1784 " return list;\n"
1785 "}\n";
1786
1788 Thread* thread = Thread::Current();
1789 EXPECT(thread->isolate() != nullptr);
1791
1792 Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, nullptr);
1793 EXPECT_VALID(lib);
1794
1795 {
1796 CHECK_API_SCOPE(thread);
1797 TransitionNativeToVM transition(thread);
1798 HANDLESCOPE(thread);
1799 StackZone zone(thread);
1800 {
1801 // Generate a list of Uint8Lists from Dart code.
1802 std::unique_ptr<Message> message = GetSerialized(lib, "getTypedDataList");
1803 ApiNativeScope scope;
1804 Dart_CObject* root = ReadApiMessage(scope.zone(), message.get());
1805 EXPECT_NOTNULL(root);
1806 EXPECT_EQ(Dart_CObject_kArray, root->type);
1807 struct {
1809 int size;
1810 } expected[] = {
1818
1819 int i = 0;
1820 while (expected[i].type != Dart_TypedData_kInvalid) {
1821 CheckTypedData(root->value.as_array.values[i], expected[i].type,
1822 expected[i].size);
1823 i++;
1824 }
1825 EXPECT_EQ(i, root->value.as_array.length);
1826 }
1827 {
1828 // Generate a list of Uint8List views from Dart code.
1829 std::unique_ptr<Message> message =
1830 GetSerialized(lib, "getTypedDataViewList");
1831 ApiNativeScope scope;
1832 Dart_CObject* root = ReadApiMessage(scope.zone(), message.get());
1833 EXPECT_NOTNULL(root);
1834 EXPECT_EQ(Dart_CObject_kArray, root->type);
1835 struct {
1837 int size;
1838 } expected[] = {
1846
1855
1864
1866
1867 int i = 0;
1868 while (expected[i].type != Dart_TypedData_kInvalid) {
1869 CheckTypedData(root->value.as_array.values[i], expected[i].type,
1870 expected[i].size);
1871 i++;
1872 }
1873 EXPECT_EQ(i, root->value.as_array.length);
1874 }
1875 {
1876 // Generate a list of Uint8Lists from Dart code.
1877 std::unique_ptr<Message> message =
1878 GetSerialized(lib, "getMultipleTypedDataViewList");
1879 ApiNativeScope scope;
1880 Dart_CObject* root = ReadApiMessage(scope.zone(), message.get());
1881 EXPECT_NOTNULL(root);
1882 EXPECT_EQ(Dart_CObject_kArray, root->type);
1883 struct {
1885 int size;
1886 } expected[] = {
1894
1895 int i = 0;
1896 while (expected[i].type != Dart_TypedData_kInvalid) {
1897 CheckTypedData(root->value.as_array.values[i], expected[i].type,
1898 expected[i].size);
1899
1900 // All views point to the same data.
1901 EXPECT_EQ(root->value.as_array.values[0]->value.as_typed_data.values,
1902 root->value.as_array.values[i]->value.as_typed_data.values);
1903 i++;
1904 }
1905 EXPECT_EQ(i, root->value.as_array.length);
1906 }
1907 }
1910}
1911
1912static void MallocFinalizer(void* isolate_callback_data, void* peer) {
1913 free(peer);
1914}
1915static void NoopFinalizer(void* isolate_callback_data, void* peer) {}
1916
1917VM_UNIT_TEST_CASE(PostCObject) {
1918 // Create a native port for posting from C to Dart
1919 TestIsolateScope __test_isolate__;
1920 const char* kScriptChars =
1921 "import 'dart:isolate';\n"
1922 "main() {\n"
1923 " var messageCount = 0;\n"
1924 " var exception = '';\n"
1925 " var port = new RawReceivePort();\n"
1926 " var sendPort = port.sendPort;\n"
1927 " port.handler = (message) {\n"
1928 " if (messageCount < 9) {\n"
1929 " exception = '$exception${message}';\n"
1930 " } else {\n"
1931 " exception = '$exception${message.length}';\n"
1932 " for (int i = 0; i < message.length; i++) {\n"
1933 " exception = '$exception${message[i]}';\n"
1934 " }\n"
1935 " }\n"
1936 " messageCount++;\n"
1937 " if (messageCount == 13) throw new Exception(exception);\n"
1938 " };\n"
1939 " return sendPort;\n"
1940 "}\n";
1941 Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, nullptr);
1943
1944 Dart_Handle send_port = Dart_Invoke(lib, NewString("main"), 0, nullptr);
1945 EXPECT_VALID(send_port);
1946 Dart_Port port_id;
1947 Dart_Handle result = Dart_SendPortGetId(send_port, &port_id);
1949
1950 // Setup single object message.
1951 Dart_CObject object;
1952
1953 object.type = Dart_CObject_kNull;
1954 EXPECT(Dart_PostCObject(port_id, &object));
1955
1956 object.type = Dart_CObject_kBool;
1957 object.value.as_bool = true;
1958 EXPECT(Dart_PostCObject(port_id, &object));
1959
1960 object.type = Dart_CObject_kBool;
1961 object.value.as_bool = false;
1962 EXPECT(Dart_PostCObject(port_id, &object));
1963
1964 object.type = Dart_CObject_kInt32;
1965 object.value.as_int32 = 123;
1966 EXPECT(Dart_PostCObject(port_id, &object));
1967
1968 object.type = Dart_CObject_kString;
1969 object.value.as_string = const_cast<char*>("456");
1970 EXPECT(Dart_PostCObject(port_id, &object));
1971
1972 object.type = Dart_CObject_kString;
1973 object.value.as_string = const_cast<char*>("æøå");
1974 EXPECT(Dart_PostCObject(port_id, &object));
1975
1976 object.type = Dart_CObject_kString;
1977 object.value.as_string = const_cast<char*>("");
1978 EXPECT(Dart_PostCObject(port_id, &object));
1979
1980 object.type = Dart_CObject_kDouble;
1981 object.value.as_double = 3.14;
1982 EXPECT(Dart_PostCObject(port_id, &object));
1983
1984 object.type = Dart_CObject_kArray;
1985 object.value.as_array.length = 0;
1986 EXPECT(Dart_PostCObject(port_id, &object));
1987
1988 const int kArrayLength = 10;
1989 Dart_CObject* array = reinterpret_cast<Dart_CObject*>(Dart_ScopeAllocate(
1990 sizeof(Dart_CObject) + sizeof(Dart_CObject*) * kArrayLength)); // NOLINT
1991 array->type = Dart_CObject_kArray;
1992 array->value.as_array.length = kArrayLength;
1993 array->value.as_array.values = reinterpret_cast<Dart_CObject**>(array + 1);
1994 for (int i = 0; i < kArrayLength; i++) {
1995 Dart_CObject* element = reinterpret_cast<Dart_CObject*>(
1997 element->type = Dart_CObject_kInt32;
1998 element->value.as_int32 = i;
1999 array->value.as_array.values[i] = element;
2000 }
2001 EXPECT(Dart_PostCObject(port_id, array));
2002
2003 object.type = Dart_CObject_kTypedData;
2004 object.value.as_typed_data.type = Dart_TypedData_kUint8;
2005 uint8_t data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8};
2006 object.value.as_typed_data.length = ARRAY_SIZE(data);
2007 object.value.as_typed_data.values = data;
2008 EXPECT(Dart_PostCObject(port_id, &object));
2009
2010 object.type = Dart_CObject_kExternalTypedData;
2011 object.value.as_typed_data.type = Dart_TypedData_kUint8;
2012 uint8_t* external_data = reinterpret_cast<uint8_t*>(malloc(sizeof(data)));
2013 memmove(external_data, data, sizeof(data));
2014 object.value.as_external_typed_data.length = ARRAY_SIZE(data);
2015 object.value.as_external_typed_data.data = external_data;
2016 object.value.as_external_typed_data.peer = external_data;
2017 object.value.as_external_typed_data.callback = MallocFinalizer;
2018 EXPECT(Dart_PostCObject(port_id, &object));
2019
2021 object.value.as_typed_data.type = Dart_TypedData_kUint8;
2022 static const uint8_t unmodifiable_data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8};
2023 object.value.as_external_typed_data.length = ARRAY_SIZE(unmodifiable_data);
2024 object.value.as_external_typed_data.data =
2025 const_cast<uint8_t*>(unmodifiable_data);
2026 object.value.as_external_typed_data.peer = nullptr;
2027 object.value.as_external_typed_data.callback = NoopFinalizer;
2028 EXPECT(Dart_PostCObject(port_id, &object));
2029
2030 result = Dart_RunLoop();
2033 EXPECT_SUBSTRING(
2034 "Exception: "
2035 "nulltruefalse123456æøå3.14[]"
2036 "100123456789901234567890123456789012345678\n",
2038
2040}
2041
2042TEST_CASE(IsKernelNegative) {
2043 EXPECT(!Dart_IsKernel(nullptr, 0));
2044
2045 uint8_t buffer[4] = {0, 0, 0, 0};
2047}
2048
2049} // namespace dart
static bool unused
#define EXPECT(type, expectedAlignment, expectedSize)
static ObjectPtr UnwrapHandle(Dart_Handle object)
static Dart_Handle CheckAndFinalizePendingClasses(Thread *thread)
static constexpr intptr_t kMaxElements
Definition object.h:10898
static ArrayPtr New(intptr_t len, Heap::Space space=Heap::kNew)
Definition object.h:10933
virtual bool CanonicalizeEquals(const Instance &other) const
Definition object.cc:24781
void SetAt(intptr_t index, const Object &value) const
Definition object.h:10858
static const Bool & False()
Definition object.h:10778
static const Bool & True()
Definition object.h:10776
uint64_t Id() const
Definition object.h:12391
static CapabilityPtr New(uint64_t id, Heap::Space space=Heap::kNew)
Definition object.cc:25852
static DoublePtr New(double d, Heap::Space space=Heap::kNew)
Definition object.cc:23481
double value() const
Definition object.h:10094
static intptr_t MaxElements(intptr_t class_id)
Definition object.h:11718
void WriteFullSnapshot(GrowableArray< LoadingUnitSerializationData * > *data=nullptr)
static constexpr intptr_t kInitialSize
static IntegerPtr New(const String &str, Heap::Space space=Heap::kNew)
Definition object.cc:23063
static Isolate * Current()
Definition isolate.h:939
@ kNormalPriority
Definition message.h:28
static void static void PrintErr(const char *format,...) PRINTF_ATTRIBUTE(1
static char * SCreate(Zone *zone, const char *format,...) PRINTF_ATTRIBUTE(2
static ClassPtr pc_descriptors_class()
Definition object.h:540
static ClassPtr class_class()
Definition object.h:513
static ClassPtr exception_handlers_class()
Definition object.h:546
static ClassPtr instructions_class()
Definition object.h:532
ObjectPtr ptr() const
Definition object.h:332
static ClassPtr type_arguments_class()
Definition object.h:517
static ClassPtr context_class()
Definition object.h:549
static ClassPtr code_class()
Definition object.h:531
virtual const char * ToCString() const
Definition object.h:366
static ClassPtr library_class()
Definition object.h:526
static ClassPtr field_class()
Definition object.h:524
static ClassPtr script_class()
Definition object.h:525
bool IsNull() const
Definition object.h:363
static ClassPtr context_scope_class()
Definition object.h:550
static Object & Handle()
Definition object.h:407
static ClassPtr function_class()
Definition object.h:519
static SmiPtr New(intptr_t value)
Definition object.h:9985
intptr_t Value() const
Definition object.h:9969
static constexpr intptr_t kMaxValue
Definition object.h:9966
static constexpr intptr_t kMinValue
Definition object.h:9967
Zone * GetZone()
Definition zone.h:213
bool Equals(const String &str) const
Definition object.h:13311
static StringPtr New(const char *cstr, Heap::Space space=Heap::kNew)
Definition object.cc:23777
static Dart_Handle lib()
Definition unit_test.cc:629
static Dart_Handle LoadTestScript(const char *script, Dart_NativeEntryResolver resolver, const char *lib_uri=RESOLVED_USER_TEST_URI, bool finalize=true, bool allow_compile_errors=false)
Definition unit_test.cc:422
static const char * NullableTag()
Definition unit_test.h:421
static Dart_Isolate CreateTestIsolate(const char *name=nullptr, void *isolate_group_data=nullptr, void *isolate_data=nullptr)
Definition unit_test.cc:139
static Dart_Isolate CreateTestIsolateFromSnapshot(uint8_t *buffer, const char *name=nullptr)
Definition unit_test.h:381
static Thread * Current()
Definition thread.h:361
Isolate * isolate() const
Definition thread.h:533
void Stop()
Definition timer.h:117
void Start()
Definition timer.h:111
int64_t TotalElapsedTime() const
Definition timer.h:123
static TypePtr ObjectType()
Definition object.cc:21878
static bool IsTypedData(const Instance &obj)
Definition object.h:11677
static intptr_t MaxElements(intptr_t class_id)
Definition object.h:11658
static TypedDataPtr New(intptr_t class_id, intptr_t len, Heap::Space space=Heap::kNew)
Definition object.cc:25666
static bool IsValid(const uint8_t *utf8_array, intptr_t array_len)
Definition unicode.cc:70
std::unique_ptr< char, decltype(std::free) * > CStringUniquePtr
Definition utils.h:644
#define ILLEGAL_PORT
Definition dart_api.h:1530
int64_t Dart_Port
Definition dart_api.h:1524
struct _Dart_Handle * Dart_Handle
Definition dart_api.h:258
Dart_TypedData_Type
Definition dart_api.h:2603
@ Dart_TypedData_kFloat32x4
Definition dart_api.h:2617
@ Dart_TypedData_kInt32x4
Definition dart_api.h:2616
@ Dart_TypedData_kUint8
Definition dart_api.h:2606
@ Dart_TypedData_kUint32
Definition dart_api.h:2611
@ Dart_TypedData_kInt32
Definition dart_api.h:2610
@ Dart_TypedData_kUint16
Definition dart_api.h:2609
@ Dart_TypedData_kFloat64x2
Definition dart_api.h:2618
@ Dart_TypedData_kUint64
Definition dart_api.h:2613
@ Dart_TypedData_kFloat32
Definition dart_api.h:2614
@ Dart_TypedData_kInt16
Definition dart_api.h:2608
@ Dart_TypedData_kFloat64
Definition dart_api.h:2615
@ Dart_TypedData_kInt8
Definition dart_api.h:2605
@ Dart_TypedData_kInt64
Definition dart_api.h:2612
@ Dart_TypedData_kInvalid
Definition dart_api.h:2619
#define CHECK_API_SCOPE(thread)
@ Dart_CObject_kInt64
@ Dart_CObject_kNumberOfTypes
@ Dart_CObject_kDouble
@ Dart_CObject_kUnmodifiableExternalTypedData
@ Dart_CObject_kTypedData
@ Dart_CObject_kString
@ Dart_CObject_kArray
@ Dart_CObject_kUnsupported
@ Dart_CObject_kNull
@ Dart_CObject_kExternalTypedData
@ Dart_CObject_kInt32
@ Dart_CObject_kBool
@ Dart_CObject_kCapability
#define ASSERT(E)
static const uint8_t buffer[]
uint8_t value
GAsyncResult * result
#define HANDLESCOPE(thread)
Definition handles.h:321
Win32Message message
constexpr int64_t kMaxInt64
Definition globals.h:486
static bool Equals(const Object &expected, const Object &actual)
constexpr int64_t kMinInt64
Definition globals.h:485
ObjectPtr ReadMessage(Thread *thread, Message *message)
DART_EXPORT void Dart_EnterScope()
static std::unique_ptr< Message > GetSerialized(Dart_Handle lib, const char *dart_function)
DART_EXPORT bool Dart_ErrorHasException(Dart_Handle handle)
static void CheckStringInvalid(Dart_Handle dart_string)
DART_EXPORT Dart_Handle Dart_Invoke(Dart_Handle target, Dart_Handle name, int number_of_arguments, Dart_Handle *arguments)
DART_EXPORT bool Dart_IsKernel(const uint8_t *buffer, intptr_t buffer_size)
DART_EXPORT Dart_Handle Dart_GetClass(Dart_Handle library, Dart_Handle class_name)
constexpr int32_t kMinInt32
Definition globals.h:482
void * malloc(size_t size)
Definition allocation.cc:19
void TestString(BaseTextBuffer *f, LoopInfo *loop, const GrowableArray< BlockEntryInstr * > &preorder)
Definition loops_test.cc:27
DART_EXPORT const char * Dart_GetError(Dart_Handle handle)
DART_EXPORT uint8_t * Dart_ScopeAllocate(intptr_t size)
Dart_CObject * SerializeAndDeserializeMint(Zone *zone, const Mint &mint)
DART_EXPORT bool Dart_IsError(Dart_Handle handle)
void CheckMint(int64_t value)
static void CompareDartCObjects(Dart_CObject *first, Dart_CObject *second)
static void CheckEncodeDecodeMessage(Zone *zone, Dart_CObject *root)
static void CheckString(Dart_Handle dart_string, const char *expected)
Dart_CObject * ReadApiMessage(Zone *zone, Message *message)
static const char * kCustomIsolateScriptChars
Dart_Handle NewString(const char *str)
DART_EXPORT Dart_Handle Dart_RunLoop()
DART_EXPORT void Dart_ExitScope()
std::unique_ptr< Message > WriteMessage(bool same_group, const Object &obj, Dart_Port dest_port, Message::Priority priority)
static void NoopFinalizer(void *isolate_callback_data, void *peer)
Definition heap_test.cc:436
constexpr int32_t kMaxInt32
Definition globals.h:483
std::unique_ptr< Message > WriteApiMessage(Zone *zone, Dart_CObject *obj, Dart_Port dest_port, Message::Priority priority)
DART_EXPORT bool Dart_PostCObject(Dart_Port port_id, Dart_CObject *message)
DART_EXPORT bool Dart_IsString(Dart_Handle object)
static int8_t data[kExtLength]
static void MallocFinalizer(void *isolate_callback_data, void *peer)
DART_EXPORT Dart_Handle Dart_SendPortGetId(Dart_Handle port, Dart_Port *port_id)
DART_EXPORT void Dart_ShutdownIsolate()
static void CheckTypedData(Dart_CObject *object, Dart_TypedData_Type typed_data_type, int len)
static void ExpectEncodeFail(Zone *zone, Dart_CObject *root)
#define Pd64
Definition globals.h:416
#define DART_INT64_C(x)
Definition globals.h:433
#define TEST_EXTERNAL_TYPED_ARRAY(darttype, ctype)
#define TEST_TYPED_ARRAY(darttype, ctype)
#define TEST_UNMODIFIABLE_EXTERNAL_TYPED_ARRAY(darttype, ctype)
#define TEST_ROUND_TRIP_IDENTICAL(object)
union _Dart_CObject::@86 value
Dart_CObject_Type type
struct _Dart_CObject::@86::@88 as_capability
struct _Dart_CObject::@86::@90 as_typed_data
const char * as_string
struct _Dart_CObject::@86::@89 as_array
struct _Dart_CObject ** values
#define VM_UNIT_TEST_CASE(name)
Definition unit_test.h:33
#define ISOLATE_UNIT_TEST_CASE(name)
Definition unit_test.h:64
#define TEST_CASE(name)
Definition unit_test.h:85
#define EXPECT_VALID(handle)
Definition unit_test.h:650
#define ARRAY_SIZE(array)
Definition globals.h:72