Artifact da0a13a473b764af55e0c778478f54be635a9ae460fe1e13f345cb83a59bc7ba:
- File
src/runtime/dtable.m
— part of check-in
[79011c5f56]
at
2017-06-07 21:38:21
on branch trunk
— runtime: Move all globals into a single struct
This is required to create a .library on MorphOS. (user: js, size: 4499) [annotate] [blame] [check-ins using]
/* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017 * Jonathan Schleifer <js@heap.zone> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include <stdio.h> #include <stdlib.h> #import "runtime.h" #import "runtime-private.h" #import "globals.h" #define empty_dtable_level2 objc_globals.empty_dtable_level2 #define empty_dtable_level3 objc_globals.empty_dtable_level3 static void init(void) { empty_dtable_level2 = malloc(sizeof(struct objc_dtable_level2)); if (empty_dtable_level2 == NULL) OBJC_ERROR("Not enough memory to allocate dtable!"); #ifdef OF_SELUID24 empty_dtable_level3 = malloc(sizeof(struct objc_dtable_level3)); if (empty_dtable_level3 == NULL) OBJC_ERROR("Not enough memory to allocate dtable!"); #endif #ifdef OF_SELUID24 for (uint_fast16_t i = 0; i < 256; i++) { empty_dtable_level2->buckets[i] = empty_dtable_level3; empty_dtable_level3->buckets[i] = (IMP)0; } #else for (uint_fast16_t i = 0; i < 256; i++) empty_dtable_level2->buckets[i] = (IMP)0; #endif } struct objc_dtable * objc_dtable_new(void) { struct objc_dtable *dtable; #ifdef OF_SELUID24 if (empty_dtable_level2 == NULL || empty_dtable_level3 == NULL) init(); #else if (empty_dtable_level2 == NULL) init(); #endif if ((dtable = malloc(sizeof(struct objc_dtable))) == NULL) OBJC_ERROR("Not enough memory to allocate dtable!"); for (uint_fast16_t i = 0; i < 256; i++) dtable->buckets[i] = empty_dtable_level2; return dtable; } void objc_dtable_copy(struct objc_dtable *dst, struct objc_dtable *src) { for (uint_fast16_t i = 0; i < 256; i++) { if (src->buckets[i] == empty_dtable_level2) continue; #ifdef OF_SELUID24 for (uint_fast16_t j = 0; j < 256; j++) { if (src->buckets[i]->buckets[j] == empty_dtable_level3) continue; for (uint_fast16_t k = 0; k < 256; k++) { IMP obj; uint32_t idx; obj = src->buckets[i]->buckets[j]->buckets[k]; if (obj == (IMP)0) continue; idx = (uint32_t) (((uint32_t)i << 16) | (j << 8) | k); objc_dtable_set(dst, idx, obj); } } #else for (uint_fast16_t j = 0; j < 256; j++) { IMP obj = src->buckets[i]->buckets[j]; uint32_t idx; if (obj == (IMP)0) continue; idx = (uint32_t)((i << 8) | j); objc_dtable_set(dst, idx, obj); } #endif } } void objc_dtable_set(struct objc_dtable *dtable, uint32_t idx, IMP obj) { #ifdef OF_SELUID24 uint8_t i = idx >> 16; uint8_t j = idx >> 8; uint8_t k = idx; #else uint8_t i = idx >> 8; uint8_t j = idx; #endif if (dtable->buckets[i] == empty_dtable_level2) { struct objc_dtable_level2 *level2 = malloc(sizeof(struct objc_dtable_level2)); if (level2 == NULL) OBJC_ERROR("Not enough memory to insert into dtable!"); for (uint_fast16_t l = 0; l < 256; l++) #ifdef OF_SELUID24 level2->buckets[l] = empty_dtable_level3; #else level2->buckets[l] = (IMP)0; #endif dtable->buckets[i] = level2; } #ifdef OF_SELUID24 if (dtable->buckets[i]->buckets[j] == empty_dtable_level3) { struct objc_dtable_level3 *level3 = malloc(sizeof(struct objc_dtable_level3)); if (level3 == NULL) OBJC_ERROR("Not enough memory to insert into dtable!"); for (uint_fast16_t l = 0; l < 256; l++) level3->buckets[l] = (IMP)0; dtable->buckets[i]->buckets[j] = level3; } dtable->buckets[i]->buckets[j]->buckets[k] = obj; #else dtable->buckets[i]->buckets[j] = obj; #endif } void objc_dtable_free(struct objc_dtable *dtable) { for (uint_fast16_t i = 0; i < 256; i++) { if (dtable->buckets[i] == empty_dtable_level2) continue; #ifdef OF_SELUID24 for (uint_fast16_t j = 0; j < 256; j++) if (dtable->buckets[i]->buckets[j] != empty_dtable_level3) free(dtable->buckets[i]->buckets[j]); #endif free(dtable->buckets[i]); } free(dtable); } void objc_dtable_cleanup(void) { if (empty_dtable_level2 != NULL) free(empty_dtable_level2); #ifdef OF_SELUID24 if (empty_dtable_level3 != NULL) free(empty_dtable_level3); #endif empty_dtable_level2 = NULL; #ifdef OF_SELUID24 empty_dtable_level3 = NULL; #endif }