ObjFW  Diff

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]:


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
292
		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;








<

|












|
|
|

|
|



|
|







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
316
317
318
319
320
321
322
323
		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)







|







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)