10
10
//
11
11
// ===----------------------------------------------------------------------===//
12
12
13
- #include " swift/Runtime/Metadata.h"
14
13
#include " swift/Runtime/Concurrent.h"
14
+ #include " swift/Runtime/HeapObject.h"
15
+ #include " swift/Runtime/Metadata.h"
15
16
#include " gtest/gtest.h"
16
17
#include < iterator>
17
18
#include < functional>
@@ -1120,13 +1121,7 @@ TEST(WitnessTableTest, getGenericWitnessTable) {
1120
1121
}
1121
1122
}
1122
1123
1123
- TEST (TestOpaqueExistentialBox, test_assignWithCopy_pod) {
1124
- auto any =
1125
- swift_getExistentialTypeMetadata (ProtocolClassConstraint::Any,
1126
- /* superclass=*/ nullptr , 0 , nullptr );
1127
- auto anyVWT = any->getValueWitnesses ();
1128
-
1129
- ValueWitnessTable testTable;
1124
+ static void initialize_pod_witness_table (ValueWitnessTable &testTable) {
1130
1125
testTable.size = sizeof (ValueBuffer);
1131
1126
testTable.flags = ValueWitnessFlags ()
1132
1127
.withAlignment (alignof (ValueBuffer))
@@ -1135,19 +1130,22 @@ TEST(TestOpaqueExistentialBox, test_assignWithCopy_pod) {
1135
1130
.withInlineStorage (true );
1136
1131
testTable.stride = sizeof (ValueBuffer);
1137
1132
installCommonValueWitnesses (&testTable);
1133
+ }
1134
+
1135
+ TEST (TestOpaqueExistentialBox, test_assignWithCopy_pod) {
1136
+ auto any =
1137
+ swift_getExistentialTypeMetadata (ProtocolClassConstraint::Any,
1138
+ /* superclass=*/ nullptr , 0 , nullptr );
1139
+ auto anyVWT = any->getValueWitnesses ();
1140
+
1141
+ ValueWitnessTable testTable;
1142
+ initialize_pod_witness_table (testTable);
1138
1143
FullOpaqueMetadata testMetadata = {{&testTable}, {{MetadataKind::Opaque}}};
1139
1144
Metadata *metadata = &testMetadata.base ;
1140
1145
1141
1146
ValueWitnessTable testTable2;
1142
- testTable2.size = sizeof (ValueBuffer);
1143
- testTable2.flags = ValueWitnessFlags ()
1144
- .withAlignment (alignof (ValueBuffer))
1145
- .withPOD (true )
1146
- .withBitwiseTakable (true )
1147
- .withInlineStorage (true );
1148
- testTable2.stride = sizeof (ValueBuffer);
1149
- installCommonValueWitnesses (&testTable2);
1150
- FullOpaqueMetadata testMetadata2 = {{&testTable}, {{MetadataKind::Opaque}}};
1147
+ initialize_pod_witness_table (testTable2);
1148
+ FullOpaqueMetadata testMetadata2 = {{&testTable2}, {{MetadataKind::Opaque}}};
1151
1149
Metadata *metadata2 = &testMetadata2.base ;
1152
1150
1153
1151
void *zeroPtr = nullptr ;
@@ -1175,27 +1173,13 @@ TEST(TestOpaqueExistentialBox, test_assignWithTake_pod) {
1175
1173
auto anyVWT = any->getValueWitnesses ();
1176
1174
1177
1175
ValueWitnessTable testTable;
1178
- testTable.size = sizeof (ValueBuffer);
1179
- testTable.flags = ValueWitnessFlags ()
1180
- .withAlignment (alignof (ValueBuffer))
1181
- .withPOD (true )
1182
- .withBitwiseTakable (true )
1183
- .withInlineStorage (true );
1184
- testTable.stride = sizeof (ValueBuffer);
1185
- installCommonValueWitnesses (&testTable);
1176
+ initialize_pod_witness_table (testTable);
1186
1177
FullOpaqueMetadata testMetadata = {{&testTable}, {{MetadataKind::Opaque}}};
1187
1178
Metadata *metadata = &testMetadata.base ;
1188
1179
1189
1180
ValueWitnessTable testTable2;
1190
- testTable2.size = sizeof (ValueBuffer);
1191
- testTable2.flags = ValueWitnessFlags ()
1192
- .withAlignment (alignof (ValueBuffer))
1193
- .withPOD (true )
1194
- .withBitwiseTakable (true )
1195
- .withInlineStorage (true );
1196
- testTable2.stride = sizeof (ValueBuffer);
1197
- installCommonValueWitnesses (&testTable2);
1198
- FullOpaqueMetadata testMetadata2 = {{&testTable}, {{MetadataKind::Opaque}}};
1181
+ initialize_pod_witness_table (testTable2);
1182
+ FullOpaqueMetadata testMetadata2 = {{&testTable2}, {{MetadataKind::Opaque}}};
1199
1183
Metadata *metadata2 = &testMetadata2.base ;
1200
1184
1201
1185
void *zeroPtr = nullptr ;
@@ -1215,3 +1199,228 @@ TEST(TestOpaqueExistentialBox, test_assignWithTake_pod) {
1215
1199
EXPECT_EQ (existBox.buffer .PrivateData [1 ], otherPtr);
1216
1200
EXPECT_EQ (existBox.buffer .PrivateData [2 ], zeroPtr);
1217
1201
}
1202
+
1203
+ static void initialize_indirect_witness_table (ValueWitnessTable &testTable) {
1204
+ testTable.size = sizeof (ValueBuffer) + 1 ;
1205
+ testTable.flags = ValueWitnessFlags ()
1206
+ .withAlignment (alignof (ValueBuffer))
1207
+ .withPOD (true )
1208
+ .withBitwiseTakable (true )
1209
+ .withInlineStorage (false );
1210
+ testTable.stride = sizeof (ValueBuffer) + 1 ;
1211
+ installCommonValueWitnesses (&testTable);
1212
+ }
1213
+
1214
+ TEST (TestOpaqueExistentialBox, test_assignWithCopy_indirect_indirect) {
1215
+ auto any =
1216
+ swift_getExistentialTypeMetadata (ProtocolClassConstraint::Any,
1217
+ /* superclass=*/ nullptr , 0 , nullptr );
1218
+ auto anyVWT = any->getValueWitnesses ();
1219
+
1220
+ ValueWitnessTable testTable;
1221
+ initialize_indirect_witness_table (testTable);
1222
+ FullOpaqueMetadata testMetadata = {{&testTable}, {{MetadataKind::Opaque}}};
1223
+ Metadata *metadata = &testMetadata.base ;
1224
+
1225
+ ValueWitnessTable testTable2;
1226
+ initialize_indirect_witness_table (testTable2);
1227
+ FullOpaqueMetadata testMetadata2 = {{&testTable2}, {{MetadataKind::Opaque}}};
1228
+ Metadata *metadata2 = &testMetadata2.base ;
1229
+
1230
+ void *zeroPtr = nullptr ;
1231
+ auto refAndObjectAddr = BoxPair (swift_allocBox (metadata));
1232
+ swift_retain (refAndObjectAddr.first );
1233
+ auto refAndObjectAddr2 = BoxPair (swift_allocBox (metadata2));
1234
+ struct {
1235
+ ValueBuffer buffer;
1236
+ Metadata *type;
1237
+ uintptr_t canary;
1238
+ } existBox{{{refAndObjectAddr.first , nullptr , nullptr }}, metadata, 0x5A5A5A5AU },
1239
+ existBox2{{{refAndObjectAddr2.first , nullptr , nullptr }}, metadata2, 0xB5A5A5A5U };
1240
+
1241
+ anyVWT->assignWithCopy (reinterpret_cast <OpaqueValue *>(&existBox),
1242
+ reinterpret_cast <OpaqueValue *>(&existBox2), any);
1243
+
1244
+ EXPECT_EQ (existBox.type , metadata2);
1245
+ EXPECT_EQ (existBox.canary , 0x5A5A5A5AU );
1246
+ EXPECT_EQ (existBox.buffer .PrivateData [0 ], refAndObjectAddr2.first );
1247
+ EXPECT_EQ (swift_retainCount (refAndObjectAddr.first ), 1 );
1248
+ EXPECT_EQ (swift_retainCount (refAndObjectAddr2.first ), 2 );
1249
+ }
1250
+
1251
+ TEST (TestOpaqueExistentialBox, test_assignWithTake_indirect_indirect) {
1252
+ auto any =
1253
+ swift_getExistentialTypeMetadata (ProtocolClassConstraint::Any,
1254
+ /* superclass=*/ nullptr , 0 , nullptr );
1255
+ auto anyVWT = any->getValueWitnesses ();
1256
+
1257
+ ValueWitnessTable testTable;
1258
+ initialize_indirect_witness_table (testTable);
1259
+ FullOpaqueMetadata testMetadata = {{&testTable}, {{MetadataKind::Opaque}}};
1260
+ Metadata *metadata = &testMetadata.base ;
1261
+
1262
+ ValueWitnessTable testTable2;
1263
+ initialize_indirect_witness_table (testTable2);
1264
+ FullOpaqueMetadata testMetadata2 = {{&testTable2}, {{MetadataKind::Opaque}}};
1265
+ Metadata *metadata2 = &testMetadata2.base ;
1266
+
1267
+ void *zeroPtr = nullptr ;
1268
+ auto refAndObjectAddr = BoxPair (swift_allocBox (metadata));
1269
+ swift_retain (refAndObjectAddr.first );
1270
+ auto refAndObjectAddr2 = BoxPair (swift_allocBox (metadata2));
1271
+ struct {
1272
+ ValueBuffer buffer;
1273
+ Metadata *type;
1274
+ uintptr_t canary;
1275
+ } existBox{{{refAndObjectAddr.first , nullptr , nullptr }}, metadata, 0x5A5A5A5AU },
1276
+ existBox2{{{refAndObjectAddr2.first , nullptr , nullptr }}, metadata2, 0xB5A5A5A5U };
1277
+
1278
+ anyVWT->assignWithTake (reinterpret_cast <OpaqueValue *>(&existBox),
1279
+ reinterpret_cast <OpaqueValue *>(&existBox2), any);
1280
+
1281
+ EXPECT_EQ (existBox.type , metadata2);
1282
+ EXPECT_EQ (existBox.canary , 0x5A5A5A5AU );
1283
+ EXPECT_EQ (existBox.buffer .PrivateData [0 ], refAndObjectAddr2.first );
1284
+ EXPECT_EQ (swift_retainCount (refAndObjectAddr.first ), 1 );
1285
+ EXPECT_EQ (swift_retainCount (refAndObjectAddr2.first ), 1 );
1286
+ }
1287
+
1288
+ TEST (TestOpaqueExistentialBox, test_assignWithCopy_pod_indirect) {
1289
+ auto any =
1290
+ swift_getExistentialTypeMetadata (ProtocolClassConstraint::Any,
1291
+ /* superclass=*/ nullptr , 0 , nullptr );
1292
+ auto anyVWT = any->getValueWitnesses ();
1293
+
1294
+ ValueWitnessTable testTable;
1295
+ initialize_pod_witness_table (testTable);
1296
+ FullOpaqueMetadata testMetadata = {{&testTable}, {{MetadataKind::Opaque}}};
1297
+ Metadata *metadata = &testMetadata.base ;
1298
+
1299
+ ValueWitnessTable testTable2;
1300
+ initialize_indirect_witness_table (testTable2);
1301
+ FullOpaqueMetadata testMetadata2 = {{&testTable2}, {{MetadataKind::Opaque}}};
1302
+ Metadata *metadata2 = &testMetadata2.base ;
1303
+
1304
+ auto refAndObjectAddr2 = BoxPair (swift_allocBox (metadata2));
1305
+ struct {
1306
+ ValueBuffer buffer;
1307
+ Metadata *type;
1308
+ uintptr_t canary;
1309
+ } existBox{{{nullptr , nullptr , nullptr }}, metadata, 0x5A5A5A5AU },
1310
+ existBox2{{{refAndObjectAddr2.first , nullptr , nullptr }}, metadata2, 0xB5A5A5A5U };
1311
+
1312
+ anyVWT->assignWithCopy (reinterpret_cast <OpaqueValue *>(&existBox),
1313
+ reinterpret_cast <OpaqueValue *>(&existBox2), any);
1314
+
1315
+ EXPECT_EQ (existBox.type , metadata2);
1316
+ EXPECT_EQ (existBox.canary , 0x5A5A5A5AU );
1317
+ EXPECT_EQ (existBox.buffer .PrivateData [0 ], refAndObjectAddr2.first );
1318
+ EXPECT_EQ (swift_retainCount (refAndObjectAddr2.first ), 2 );
1319
+ }
1320
+
1321
+ TEST (TestOpaqueExistentialBox, test_assignWithTake_pod_indirect) {
1322
+ auto any =
1323
+ swift_getExistentialTypeMetadata (ProtocolClassConstraint::Any,
1324
+ /* superclass=*/ nullptr , 0 , nullptr );
1325
+ auto anyVWT = any->getValueWitnesses ();
1326
+
1327
+ ValueWitnessTable testTable;
1328
+ initialize_pod_witness_table (testTable);
1329
+ FullOpaqueMetadata testMetadata = {{&testTable}, {{MetadataKind::Opaque}}};
1330
+ Metadata *metadata = &testMetadata.base ;
1331
+
1332
+ ValueWitnessTable testTable2;
1333
+ initialize_indirect_witness_table (testTable2);
1334
+ FullOpaqueMetadata testMetadata2 = {{&testTable2}, {{MetadataKind::Opaque}}};
1335
+ Metadata *metadata2 = &testMetadata2.base ;
1336
+
1337
+ auto refAndObjectAddr2 = BoxPair (swift_allocBox (metadata2));
1338
+ struct {
1339
+ ValueBuffer buffer;
1340
+ Metadata *type;
1341
+ uintptr_t canary;
1342
+ } existBox{{{nullptr , nullptr , nullptr }}, metadata, 0x5A5A5A5AU },
1343
+ existBox2{{{refAndObjectAddr2.first , nullptr , nullptr }}, metadata2, 0xB5A5A5A5U };
1344
+
1345
+ anyVWT->assignWithTake (reinterpret_cast <OpaqueValue *>(&existBox),
1346
+ reinterpret_cast <OpaqueValue *>(&existBox2), any);
1347
+
1348
+ EXPECT_EQ (existBox.type , metadata2);
1349
+ EXPECT_EQ (existBox.canary , 0x5A5A5A5AU );
1350
+ EXPECT_EQ (existBox.buffer .PrivateData [0 ], refAndObjectAddr2.first );
1351
+ EXPECT_EQ (swift_retainCount (refAndObjectAddr2.first ), 1 );
1352
+ }
1353
+
1354
+ TEST (TestOpaqueExistentialBox, test_assignWithCopy_indirect_pod) {
1355
+ auto any =
1356
+ swift_getExistentialTypeMetadata (ProtocolClassConstraint::Any,
1357
+ /* superclass=*/ nullptr , 0 , nullptr );
1358
+ auto anyVWT = any->getValueWitnesses ();
1359
+
1360
+ ValueWitnessTable testTable;
1361
+ initialize_pod_witness_table (testTable);
1362
+ FullOpaqueMetadata testMetadata = {{&testTable}, {{MetadataKind::Opaque}}};
1363
+ Metadata *metadata = &testMetadata.base ;
1364
+
1365
+ ValueWitnessTable testTable2;
1366
+ initialize_indirect_witness_table (testTable2);
1367
+ FullOpaqueMetadata testMetadata2 = {{&testTable2}, {{MetadataKind::Opaque}}};
1368
+ Metadata *metadata2 = &testMetadata2.base ;
1369
+
1370
+ auto refAndObjectAddr2 = BoxPair (swift_allocBox (metadata2));
1371
+ void *someAddr = &anyVWT;
1372
+ swift_retain (refAndObjectAddr2.first );
1373
+ struct {
1374
+ ValueBuffer buffer;
1375
+ Metadata *type;
1376
+ uintptr_t canary;
1377
+ } existBox2{{{someAddr, nullptr , someAddr}}, metadata, 0x5A5A5A5AU },
1378
+ existBox{{{refAndObjectAddr2.first , nullptr , nullptr }}, metadata2, 0xB5A5A5A5U };
1379
+
1380
+ anyVWT->assignWithCopy (reinterpret_cast <OpaqueValue *>(&existBox),
1381
+ reinterpret_cast <OpaqueValue *>(&existBox2), any);
1382
+
1383
+ EXPECT_EQ (existBox.type , metadata);
1384
+ EXPECT_EQ (existBox.canary , 0xB5A5A5A5U );
1385
+ EXPECT_EQ (existBox.buffer .PrivateData [0 ], someAddr);
1386
+ EXPECT_EQ (existBox.buffer .PrivateData [1 ], nullptr );
1387
+ EXPECT_EQ (existBox.buffer .PrivateData [2 ], someAddr);
1388
+ EXPECT_EQ (swift_retainCount (refAndObjectAddr2.first ), 1 );
1389
+ }
1390
+
1391
+ TEST (TestOpaqueExistentialBox, test_assignWithTake_indirect_pod) {
1392
+ auto any =
1393
+ swift_getExistentialTypeMetadata (ProtocolClassConstraint::Any,
1394
+ /* superclass=*/ nullptr , 0 , nullptr );
1395
+ auto anyVWT = any->getValueWitnesses ();
1396
+
1397
+ ValueWitnessTable testTable;
1398
+ initialize_pod_witness_table (testTable);
1399
+ FullOpaqueMetadata testMetadata = {{&testTable}, {{MetadataKind::Opaque}}};
1400
+ Metadata *metadata = &testMetadata.base ;
1401
+
1402
+ ValueWitnessTable testTable2;
1403
+ initialize_indirect_witness_table (testTable2);
1404
+ FullOpaqueMetadata testMetadata2 = {{&testTable2}, {{MetadataKind::Opaque}}};
1405
+ Metadata *metadata2 = &testMetadata2.base ;
1406
+
1407
+ auto refAndObjectAddr2 = BoxPair (swift_allocBox (metadata2));
1408
+ void *someAddr = &anyVWT;
1409
+ swift_retain (refAndObjectAddr2.first );
1410
+ struct {
1411
+ ValueBuffer buffer;
1412
+ Metadata *type;
1413
+ uintptr_t canary;
1414
+ } existBox2{{{someAddr, nullptr , someAddr}}, metadata, 0x5A5A5A5AU },
1415
+ existBox{{{refAndObjectAddr2.first , nullptr , nullptr }}, metadata2, 0xB5A5A5A5U };
1416
+
1417
+ anyVWT->assignWithTake (reinterpret_cast <OpaqueValue *>(&existBox),
1418
+ reinterpret_cast <OpaqueValue *>(&existBox2), any);
1419
+
1420
+ EXPECT_EQ (existBox.type , metadata);
1421
+ EXPECT_EQ (existBox.canary , 0xB5A5A5A5U );
1422
+ EXPECT_EQ (existBox.buffer .PrivateData [0 ], someAddr);
1423
+ EXPECT_EQ (existBox.buffer .PrivateData [1 ], nullptr );
1424
+ EXPECT_EQ (existBox.buffer .PrivateData [2 ], someAddr);
1425
+ EXPECT_EQ (swift_retainCount (refAndObjectAddr2.first ), 1 );
1426
+ }
0 commit comments