Differences From Artifact [132bb904b5]:
- File
src/runtime/class.m
— part of check-in
[3b3729a316]
at
2019-06-25 20:09:55
on branch trunk
— runtime: Don't use static selectors
Static selectors are initialized by a global constructor that might run
too late: If a class has a +[load] that triggers an +[initialize], this
could result in trying to call +[initialize] with the selector in
class.m still being uninitialized. When this happens, it results in a
weird looking crash in an entirely unrelated method. This is because
when uninitialized, the selector name has not been replaced with a
selector UID yet, meaning the pointer to the selector name is treated as
the selector UID. As the dispatch only considers the low 16 bits of the
selector UID for performance reasons, it will just take the low 16 bits
of the pointer to the selector name as the UID without any complaints.
This can then result in calling a random method on that class which then
crashes. (user: js, size: 21746) [annotate] [blame] [check-ins using]
To Artifact [d1f09c48dd]:
- File src/runtime/class.m — part of check-in [688eef7561] at 2019-11-24 15:22:55 on branch trunk — runtime: Make ivars opaque and provide an API (user: js, size: 21745) [annotate] [blame] [check-ins using]
︙ | ︙ | |||
253 254 255 256 257 258 259 | OBJC_ERROR("Not enough memory for subclass list of class %s\n", class->superclass->name); class->superclass->subclassList[i] = class; class->superclass->subclassList[i + 1] = Nil; } | < | | | | | | | | | 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 | OBJC_ERROR("Not enough memory for subclass list of class %s\n", class->superclass->name); class->superclass->subclassList[i] = class; class->superclass->subclassList[i + 1] = Nil; } static void updateIvarOffsets(Class class) { if (!(class->info & OBJC_CLASS_INFO_NEW_ABI)) return; if (class->instanceSize > 0) return; class->instanceSize = -class->instanceSize; if (class->superclass != Nil) { class->instanceSize += class->superclass->instanceSize; if (class->ivars != NULL) { for (unsigned int i = 0; i < class->ivars->count; i++) { class->ivars->ivars[i].offset += class->superclass->instanceSize; *class->ivarOffsets[i] = class->ivars->ivars[i].offset; } } } else for (unsigned int i = 0; i < class->ivars->count; i++) *class->ivarOffsets[i] = class->ivars->ivars[i].offset; } static void setupClass(Class class) { const char *superclassName; |
︙ | ︙ | |||
309 310 311 312 313 314 315 | class->isa->superclass = super->isa; addSubclass(class); addSubclass(class->isa); } else class->isa->superclass = class; | | | 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 | class->isa->superclass = super->isa; addSubclass(class); addSubclass(class->isa); } else class->isa->superclass = class; updateIvarOffsets(class); class->info |= OBJC_CLASS_INFO_SETUP; class->isa->info |= OBJC_CLASS_INFO_SETUP; } static void initializeClass(Class class) |
︙ | ︙ |