<commit_before>#define __BSD_VISIBLE 1
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <errno.h>
#include "objc/runtime.h"
#include "objc/hooks.h"
#include "sarray2.h"
#include "selector.h"
#include "class.h"
#include "lock.h"
#include "method.h"
#include "dtable.h"
#include "visibility.h"
#include "asmconstants.h"

_Static_assert(__builtin_offsetof(struct objc_class, dtable) == DTABLE_OFFSET,
		"Incorrect dtable offset for assembly");
_Static_assert(__builtin_offsetof(SparseArray, shift) == SHIFT_OFFSET,
		"Incorrect shift offset for assembly");
_Static_assert(__builtin_offsetof(SparseArray, data) == DATA_OFFSET,
		"Incorrect data offset for assembly");
// Slots are now a public interface to part of the method structure, so make
// sure that it's safe to use method and slot structures interchangeably.
_Static_assert(__builtin_offsetof(struct objc_slot2, method) == SLOT_OFFSET,
		"Incorrect slot offset for assembly");
_Static_assert(__builtin_offsetof(struct objc_method, imp) == SLOT_OFFSET,
		"Incorrect slot offset for assembly");

PRIVATE dtable_t uninstalled_dtable;
#if defined(WITH_TRACING) && defined (__x86_64)
PRIVATE dtable_t tracing_dtable;
#endif
#ifndef ENOTSUP
#	define ENOTSUP -1
#endif

/** Head of the list of temporary dtables.  Protected by initialize_lock. */
PRIVATE InitializingDtable *temporary_dtables;
/** Lock used to protect the temporary dtables list. */
PRIVATE mutex_t initialize_lock;
/** The size of the largest dtable.  This is a sparse array shift value, so is
 * 2^x in increments of 8. */
static uint32_t dtable_depth = 8;

_Atomic(uint64_t) objc_method_cache_version;

/**
 * Starting at `cls`, finds the class that provides the implementation of the
 * method identified by `sel`.
 */
static Class ownerForMethod(Class cls, SEL sel)
{
	struct objc_slot2 *slot = objc_get_slot2(cls, sel, NULL);
	if (slot == NULL)
	{
		return Nil;
	}
	if (cls->super_class == NULL)
	{
		return cls;
	}
	if (objc_get_slot2(cls->super_class, sel, NULL) == slot)
	{
		return ownerForMethod(cls->super_class, sel);
	}
	return cls;
}

/**
 * Returns YES if the class implements a method for the specified selector, NO
 * otherwise.
 */
static BOOL ownsMethod(Class cls, SEL sel)
{
	return ownerForMethod(cls, sel) == cls;
}


#ifdef DEBUG_ARC_COMPAT
#define ARC_DEBUG_LOG(...) fprintf(stderr, __VA_LIST__)
#else
#define ARC_DEBUG_LOG(...) do {} while(0)
#endif

/**
 * Checks whether the class implements memory management methods, and whether
 * they are safe to use with ARC.
 */
static void checkARCAccessors(Class cls)
{
	static SEL retain, release, autorelease, isARC;
	if (NULL == retain)
	{
		retain = sel_registerName("retain");
		release = sel_registerName("release");
		autorelease = sel_registerName("autorelease");
		isARC = sel_registerName("_ARCCompliantRetainRelease");
	}
	Class owner = ownerForMethod(cls, retain);
	if ((NULL != owner) && !ownsMethod(owner, isARC))
	{
		ARC_DEBUG_LOG("%s does not support ARC correctly (implements retain)\n", cls->name);
		objc_clear_class_flag(cls, objc_class_flag_fast_arc);
		return;
	}
	owner = ownerForMethod(cls, retain);
	if ((NULL != owner) && !ownsMethod(owner, isARC))
	{
		ARC_DEBUG_LOG("%s does not support ARC correctly (implements release)\n", cls->name);
		objc_clear_class_flag(cls, objc_class_flag_fast_arc);
		return;
	}
	owner = ownerForMethod(cls, retain);
	if ((NULL != owner) && !ownsMethod(owner, isARC))
	{
		ARC_DEBUG_LOG("%s does not support ARC correctly (implements autorelease)\n", cls->name);
		objc_clear_class_flag(cls, objc_class_flag_fast_arc);
		return;
	}
	objc_set_class_flag(cls, objc_class_flag_fast_arc);
}

static BOOL selEqualUnTyped(SEL expected, SEL untyped)
{
	return (expected->index == untyped->index)<commit_msg>Fix fast-ARC checks.<commit_after>#define __BSD_VISIBLE 1
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <errno.h>
#include "objc/runtime.h"
#include "objc/hooks.h"
#include "sarray2.h"
#include "selector.h"
#include "class.h"
#include "lock.h"
#include "method.h"
#include "dtable.h"
#include "visibility.h"
#include "asmconstants.h"

_Static_assert(__builtin_offsetof(struct objc_class, dtable) == DTABLE_OFFSET,
		"Incorrect dtable offset for assembly");
_Static_assert(__builtin_offsetof(SparseArray, shift) == SHIFT_OFFSET,
		"Incorrect shift offset for assembly");
_Static_assert(__builtin_offsetof(SparseArray, data) == DATA_OFFSET,
		"Incorrect data offset for assembly");
// Slots are now a public interface to part of the method structure, so make
// sure that it's safe to use method and slot structures interchangeably.
_Static_assert(__builtin_offsetof(struct objc_slot2, method) == SLOT_OFFSET,
		"Incorrect slot offset for assembly");
_Static_assert(__builtin_offsetof(struct objc_method, imp) == SLOT_OFFSET,
		"Incorrect slot offset for assembly");

PRIVATE dtable_t uninstalled_dtable;
#if defined(WITH_TRACING) && defined (__x86_64)
PRIVATE dtable_t tracing_dtable;
#endif
#ifndef ENOTSUP
#	define ENOTSUP -1
#endif

/** Head of the list of temporary dtables.  Protected by initialize_lock. */
PRIVATE InitializingDtable *temporary_dtables;
/** Lock used to protect the temporary dtables list. */
PRIVATE mutex_t initialize_lock;
/** The size of the largest dtable.  This is a sparse array shift value, so is
 * 2^x in increments of 8. */
static uint32_t dtable_depth = 8;

_Atomic(uint64_t) objc_method_cache_version;

/**
 * Starting at `cls`, finds the class that provides the implementation of the
 * method identified by `sel`.
 */
static Class ownerForMethod(Class cls, SEL sel)
{
	struct objc_slot2 *slot = objc_get_slot2(cls, sel, NULL);
	if (slot == NULL)
	{
		return Nil;
	}
	if (cls->super_class == NULL)
	{
		return cls;
	}
	if (objc_get_slot2(cls->super_class, sel, NULL) == slot)
	{
		return ownerForMethod(cls->super_class, sel);
	}
	return cls;
}

/**
 * Returns YES if the class implements a method for the specified selector, NO
 * otherwise.
 */
static BOOL ownsMethod(Class cls, SEL sel)
{
	return ownerForMethod(cls, sel) == cls;
}


#ifdef DEBUG_ARC_COMPAT
#define ARC_DEBUG_LOG(...) fprintf(stderr, __VA_LIST__)
#else
#define ARC_DEBUG_LOG(...) do {} while(0)
#endif

/**
 * Checks whether the class implements memory management methods, and whether
 * they are safe to use with ARC.
 */
static void checkARCAccessors(Class cls)
{
	static SEL retain, release, autorelease, isARC;
	if (NULL == retain)
	{
		retain = sel_registerName("retain");
		release = sel_registerName("release");
		autorelease = sel_registerName("autorelease");
		isARC = sel_registerName("_ARCCompliantRetainRelease");
	}
	Class owner = ownerForMethod(cls, retain);
	if ((NULL != owner) && !ownsMethod(owner, isARC))
	{
		ARC_DEBUG_LOG("%s does not support ARC correctly (implements retain)\n", cls->name);
		objc_clear_class_flag(cls, objc_class_flag_fast_arc);
		return;
	}
	owner = ownerForMethod(cls, release);
	if ((NULL != owner) && !ownsMethod(owner, isARC))
	{
		ARC_DEBUG_LOG("%s does not support ARC correctly (implements release)\n", cls->name);
		objc_clear_class_flag(cls, objc_class_flag_fast_arc);
		return;
	}
	owner = ownerForMethod(cls, autorelease);
	if ((NULL != owner) && !ownsMethod(owner, isARC))
	{
		ARC_DEBUG_LOG("%s does not support ARC correctly (implements autorelease)\n", cls->name);
		objc_clear_class_flag(cls, objc_class_flag_fast_arc);
		return;
	}
	objc_set_class_flag(cls, objc_class_flag_fast_arc);
}

static BOOL selEqualUnTyped(SEL expected, SEL untyped)
{
	return (expected->index == untyped->index)
{'fraction_non_alphanumeric': 0.11755340321082659, 'fraction_numerical': 0.005041793817168635, 'mean_word_length': 5.437233134073441, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 27, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2413601', 'n_tokens_mistral': 2672, 'n_tokens_neox': 2592, 'n_words': 721}