@@ -134,18 +134,38 @@ void MetadataLayout::destroy() const {
134
134
135
135
/* ****************************** NOMINAL TYPES ********************************/
136
136
137
+ Offset NominalMetadataLayout::emitOffset (IRGenFunction &IGF,
138
+ StoredOffset offset) const {
139
+ assert (offset.isValid ());
140
+
141
+ if (offset.isStatic ())
142
+ return Offset (offset.getStaticOffset ());
143
+
144
+ Address offsetBaseAddr (
145
+ IGF.IGM .getAddrOfClassMetadataBaseOffset (cast<ClassDecl>(getDecl ()),
146
+ NotForDefinition),
147
+ IGF.IGM .getPointerAlignment ());
148
+
149
+ // FIXME: Should this be an invariant load?
150
+ auto *offsetBaseVal =
151
+ IGF.Builder .CreateLoad (offsetBaseAddr, " base" );
152
+
153
+ auto relativeOffset = offset.getRelativeOffset ().getValue ();
154
+ auto *offsetVal =
155
+ IGF.Builder .CreateAdd (offsetBaseVal,
156
+ llvm::ConstantInt::get (IGF.IGM .SizeTy ,
157
+ relativeOffset));
158
+ return Offset (offsetVal);
159
+ }
160
+
137
161
Size
138
162
NominalMetadataLayout::getStaticGenericRequirementsOffset () const {
139
- assert (GenericRequirements.isValid ());
140
- assert (GenericRequirements.isStatic () && " resilient metadata layout unsupported!" );
141
163
return GenericRequirements.getStaticOffset ();
142
164
}
143
165
144
166
Offset
145
167
NominalMetadataLayout::getGenericRequirementsOffset (IRGenFunction &IGF) const {
146
- assert (GenericRequirements.isValid ());
147
- assert (GenericRequirements.isStatic () && " resilient metadata layout unsupported!" );
148
- return Offset (GenericRequirements.getStaticOffset ());
168
+ return emitOffset (IGF, GenericRequirements);
149
169
}
150
170
151
171
static llvm::Value *emitLoadOfGenericRequirement (IRGenFunction &IGF,
@@ -323,11 +343,7 @@ Size ClassMetadataLayout::getInstanceAlignMaskOffset() const {
323
343
ClassMetadataLayout::MethodInfo
324
344
ClassMetadataLayout::getMethodInfo (IRGenFunction &IGF, SILDeclRef method) const {
325
345
auto &stored = getStoredMethodInfo (method);
326
-
327
- assert (stored.TheOffset .isStatic () &&
328
- " resilient class metadata layout unsupported!" );
329
- auto offset = Offset (stored.TheOffset .getStaticOffset ());
330
-
346
+ auto offset = emitOffset (IGF, stored.TheOffset );
331
347
return MethodInfo (offset);
332
348
}
333
349
@@ -339,45 +355,50 @@ Size ClassMetadataLayout::getStaticMethodOffset(SILDeclRef method) const{
339
355
return stored.TheOffset .getStaticOffset ();
340
356
}
341
357
342
- Size
343
- ClassMetadataLayout::getStaticVTableOffset () const {
344
- // TODO: if class is resilient, return the offset relative to the start
345
- // of immediate class metadata
346
- assert (VTableOffset.isStatic ());
347
- return VTableOffset.getStaticOffset ();
348
- }
349
-
350
358
Offset
351
359
ClassMetadataLayout::getVTableOffset (IRGenFunction &IGF) const {
352
- // TODO: implement resilient metadata layout
353
- assert (VTableOffset.isStatic ());
354
- return Offset (VTableOffset.getStaticOffset ());
360
+ return emitOffset (IGF, VTableOffset);
355
361
}
356
362
357
363
Offset ClassMetadataLayout::getFieldOffset (IRGenFunction &IGF,
358
364
VarDecl *field) const {
359
- // TODO: implement resilient metadata layout
360
- return Offset (getStaticFieldOffset (field));
365
+ return emitOffset (IGF, getStoredFieldOffset (field));
361
366
}
367
+
362
368
Size ClassMetadataLayout::getStaticFieldOffset (VarDecl *field) const {
363
369
auto &stored = getStoredFieldOffset (field);
364
370
assert (stored.isStatic () && " resilient class metadata layout unsupported!" );
365
371
return stored.getStaticOffset ();
366
372
}
367
373
374
+ Size
375
+ ClassMetadataLayout::getRelativeGenericRequirementsOffset () const {
376
+ return GenericRequirements.getRelativeOffset ();
377
+ }
378
+
368
379
Size
369
380
ClassMetadataLayout::getStaticFieldOffsetVectorOffset () const {
370
- // TODO: if class is resilient, return the offset relative to the start
371
- // of immediate class metadata
372
- assert (FieldOffsetVector.isStatic ());
373
381
return FieldOffsetVector.getStaticOffset ();
374
382
}
375
383
384
+ Size
385
+ ClassMetadataLayout::getRelativeFieldOffsetVectorOffset () const {
386
+ return FieldOffsetVector.getRelativeOffset ();
387
+ }
388
+
389
+ Size
390
+ ClassMetadataLayout::getStaticVTableOffset () const {
391
+ return VTableOffset.getStaticOffset ();
392
+ }
393
+
394
+ Size
395
+ ClassMetadataLayout::getRelativeVTableOffset () const {
396
+ return VTableOffset.getRelativeOffset ();
397
+ }
398
+
376
399
Offset
377
400
ClassMetadataLayout::getFieldOffsetVectorOffset (IRGenFunction &IGF) const {
378
- // TODO: implement resilient metadata layout
379
- assert (FieldOffsetVector.isStatic ());
380
- return Offset (FieldOffsetVector.getStaticOffset ());
401
+ return emitOffset (IGF, FieldOffsetVector);
381
402
}
382
403
383
404
Size irgen::getClassFieldOffsetOffset (IRGenModule &IGM, ClassDecl *theClass,
@@ -398,8 +419,8 @@ llvm::Value *irgen::emitClassFieldOffset(IRGenFunction &IGF,
398
419
399
420
Address irgen::emitAddressOfClassFieldOffset (IRGenFunction &IGF,
400
421
llvm::Value *metadata,
401
- ClassDecl *theClass,
402
- VarDecl *field) {
422
+ ClassDecl *theClass,
423
+ VarDecl *field) {
403
424
auto offset = IGF.IGM .getMetadataLayout (theClass).getFieldOffset (IGF, field);
404
425
auto slot = IGF.emitAddressAtOffset (metadata, offset, IGF.IGM .SizeTy ,
405
426
IGF.IGM .getPointerAlignment ());
0 commit comments