Skip to content

Commit

Permalink
Merge branch 'master' into newabi
Browse files Browse the repository at this point in the history
Simplify the setSubclass dtable updating mechanism.
  • Loading branch information
davidchisnall committed Apr 11, 2018
2 parents c50db7b + 8021533 commit b81df02
Show file tree
Hide file tree
Showing 26 changed files with 747 additions and 50 deletions.
7 changes: 7 additions & 0 deletions ANNOUNCE
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,13 @@ Highlights of this release include:
requirements, which should fix issues relating to using vector types in
Objective-C objects.

- The option to build a separate libobjcxx has been removed. The runtime will
now depend on the C++ standard library implementation if no useable C++
runtime is available. Note that C++ exception interworking does not work
because LLVM's libc++abi (shipped by Apple) does not provide GNU-compatible
hooks and so Objective-C++ exception support will be automatically disabled
on this platform. Any other platforms shipping libc++abi should consider
either GNU libsupc++ or libcxxrt as an alternative.

You may obtain the code for this release from git and use the 1.x branch:

Expand Down
2 changes: 1 addition & 1 deletion CMake/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 2.8)
cmake_minimum_required(VERSION 3.1)

add_executable(test_cxx_runtime typeinfo_test.cc)
set(CMAKE_CXX_IMPLICIT_LINK_LIBRARIES "")
Expand Down
18 changes: 17 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
cmake_minimum_required(VERSION 2.8)
cmake_minimum_required(VERSION 3.1)

project(libobjc)
enable_language(ASM)

INCLUDE (CheckCXXSourceCompiles)

macro(install_symlink filepath sympath)
install(CODE "execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink ${filepath} ${sympath})")
install(CODE "message(\"-- Symlinking: ${sympath} -> ${filepath}\")")
Expand Down Expand Up @@ -364,3 +366,17 @@ if (TESTS)
add_subdirectory(Test)
endif (TESTS)

CHECK_CXX_SOURCE_COMPILES("
#include <stdlib.h>
extern \"C\" {
__attribute__((weak))
void *__cxa_allocate_exception(size_t thrown_size) noexcept;
}
#include <exception>
int main() { return 0; }" CXA_ALLOCATE_EXCEPTION_NOEXCEPT_COMPILES)

if (CXA_ALLOCATE_EXCEPTION_NOEXCEPT_COMPILES)
add_definitions(-DCXA_ALLOCATE_EXCEPTION_SPECIFIER=noexcept)
else ()
add_definitions(-DCXA_ALLOCATE_EXCEPTION_SPECIFIER=)
endif ()
39 changes: 37 additions & 2 deletions Test/AssociatedObject.m
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
#include "Test.h"
#include <stdio.h>
#include <inttypes.h>

static BOOL deallocCalled = NO;
static const char* objc_setAssociatedObjectKey = "objc_setAssociatedObjectKey";
Expand All @@ -19,8 +21,41 @@ int main(void)
@autoreleasepool {
Associated *object = [Associated new];
Test *holder = [[Test new] autorelease];
objc_setAssociatedObject(object, &objc_setAssociatedObjectKey, holder, OBJC_ASSOCIATION_RETAIN);
objc_setAssociatedObject(holder, &objc_setAssociatedObjectKey, object, OBJC_ASSOCIATION_RETAIN);
[object release];
}
assert(!deallocCalled);
}
// dealloc should be called when holder is released during pool drain
assert(deallocCalled);

deallocCalled = NO;

Associated *object = [Associated new];
Test *holder = [Test new];
objc_setAssociatedObject(holder, &objc_setAssociatedObjectKey, object, OBJC_ASSOCIATION_RETAIN);
[object release]; // commuted into associated object storage
objc_setAssociatedObject(holder, &objc_setAssociatedObjectKey, nil, OBJC_ASSOCIATION_ASSIGN);
[holder release];

assert(deallocCalled);

object = [Associated new];
holder = [Test new];
for (uintptr_t i = 1; i <= 20; ++i)
{
objc_setAssociatedObject(holder, (void*)i, object, OBJC_ASSOCIATION_RETAIN);
}
int lost = 0;
for (uintptr_t i = 1; i <= 20; ++i)
{
if (object != objc_getAssociatedObject(holder, (void*)i))
{
fprintf(stderr, "lost object %" PRIuPTR "\n", i);
++lost;
}
}
[holder release];
[object release];
assert(0 == lost);
return 0;
}
2 changes: 2 additions & 0 deletions Test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ set(TESTS
MethodArguments.m
zeroSizedIVar.m
exchange.m
hash_table_delete.c
setSuperclass.m
)

# List of single-file tests that won't work with the legacy ABI and so
Expand Down
64 changes: 64 additions & 0 deletions Test/hash_table_delete.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#include <stdbool.h>
#include <stdint.h>

struct test_struct {
uintptr_t key;
};

struct test_struct null_placeholder = {0};

static int test_compare(const void *key, const struct test_struct test) {
return (uintptr_t)key == test.key;
}

// force hash collisions
static uint32_t test_key_hash(const void *ptr) {
return ((uint32_t)(uintptr_t)ptr)>>2;
}

static uint32_t test_value_hash(const struct test_struct test) {
return test.key>>2;
}

static int test_is_null(const struct test_struct test) {
return test.key == 0;
}

#define MAP_TABLE_NAME test
#define MAP_TABLE_COMPARE_FUNCTION test_compare
#define MAP_TABLE_VALUE_TYPE struct test_struct
#define MAP_TABLE_VALUE_NULL test_is_null
#define MAP_TABLE_HASH_KEY test_key_hash
#define MAP_TABLE_HASH_VALUE test_value_hash
#define MAP_TABLE_VALUE_PLACEHOLDER null_placeholder
#define MAP_TABLE_ACCESS_BY_REFERENCE 1
#define MAP_TABLE_SINGLE_THREAD 1
#define MAP_TABLE_NO_LOCK 1

#include "../hash_table.h"

int main(int argc, char *argv[])
{
test_table *testTable;
test_initialize(&testTable, 128);

struct test_struct one, two, three;
one.key = 1;
two.key = 2;
three.key = 3;

test_insert(testTable, one);
test_insert(testTable, two);
test_insert(testTable, three);

test_remove(testTable, (void*)2);
test_remove(testTable, (void*)1);

struct test_struct *pthree = test_table_get(testTable, (void*)3);
if (!pthree) {
fprintf(stderr, "failed to find value (key=3) inserted into hash table\n");
return 1;
}

return 0;
}
Loading

0 comments on commit b81df02

Please sign in to comment.