Index: ObjFW.xcodeproj/project.pbxproj ================================================================== --- ObjFW.xcodeproj/project.pbxproj +++ ObjFW.xcodeproj/project.pbxproj @@ -164,10 +164,14 @@ 4B187E59163EA3DA0049A832 /* OFDictionary+NSObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B187E37163EA3DA0049A832 /* OFDictionary+NSObject.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B187E5B163EA3DA0049A832 /* OFDictionary+NSObject.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B187E38163EA3DA0049A832 /* OFDictionary+NSObject.m */; }; 4B187E5C163EA3DA0049A832 /* OFString+NSObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B187E39163EA3DA0049A832 /* OFString+NSObject.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B187E5E163EA3DA0049A832 /* OFString+NSObject.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B187E3A163EA3DA0049A832 /* OFString+NSObject.m */; }; 4B187E62163EA46D0049A832 /* ObjFW.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B3D23761337FBC800DD29B8 /* ObjFW.framework */; }; + 4B1F61B61F6623B800278BCB /* call.S in Sources */ = {isa = PBXBuildFile; fileRef = 4B1F61B21F6623B700278BCB /* call.S */; }; + 4B1F61B71F6623B800278BCB /* call.S in Sources */ = {isa = PBXBuildFile; fileRef = 4B1F61B21F6623B700278BCB /* call.S */; }; + 4B1F61B81F6623B800278BCB /* invoke.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B1F61B31F6623B700278BCB /* invoke.m */; }; + 4B1F61B91F6623B800278BCB /* invoke.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B1F61B31F6623B700278BCB /* invoke.m */; }; 4B2227A71D4FE23700A41CD3 /* atomic_builtins.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B2227A11D4FE23700A41CD3 /* atomic_builtins.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B2227A81D4FE23700A41CD3 /* atomic_no_threads.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B2227A21D4FE23700A41CD3 /* atomic_no_threads.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B2227A91D4FE23700A41CD3 /* atomic_osatomic.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B2227A31D4FE23700A41CD3 /* atomic_osatomic.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B2227AA1D4FE23700A41CD3 /* atomic_powerpc.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B2227A41D4FE23700A41CD3 /* atomic_powerpc.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B2227AB1D4FE23700A41CD3 /* atomic_sync_builtins.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B2227A51D4FE23700A41CD3 /* atomic_sync_builtins.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -1297,10 +1301,14 @@ 4B187E38163EA3DA0049A832 /* OFDictionary+NSObject.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "OFDictionary+NSObject.m"; path = "src/bridge/OFDictionary+NSObject.m"; sourceTree = ""; }; 4B187E39163EA3DA0049A832 /* OFString+NSObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "OFString+NSObject.h"; path = "src/bridge/OFString+NSObject.h"; sourceTree = ""; }; 4B187E3A163EA3DA0049A832 /* OFString+NSObject.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "OFString+NSObject.m"; path = "src/bridge/OFString+NSObject.m"; sourceTree = ""; }; 4B19023A1338D6A2000374C9 /* Makefile */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.make; name = Makefile; path = src/Makefile; sourceTree = SOURCE_ROOT; }; 4B19023D1338D6D5000374C9 /* Makefile */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.make; name = Makefile; path = tests/Makefile; sourceTree = ""; }; + 4B1F61B21F6623B700278BCB /* call.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; name = call.S; path = src/invocation/call.S; sourceTree = ""; }; + 4B1F61B31F6623B700278BCB /* invoke.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = invoke.m; path = src/invocation/invoke.m; sourceTree = ""; }; + 4B1F61B41F6623B800278BCB /* apple-call-x86_64.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; name = "apple-call-x86_64.S"; path = "src/invocation/apple-call-x86_64.S"; sourceTree = ""; }; + 4B1F61B51F6623B800278BCB /* invoke-x86_64.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "invoke-x86_64.m"; path = "src/invocation/invoke-x86_64.m"; sourceTree = ""; }; 4B2227A11D4FE23700A41CD3 /* atomic_builtins.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = atomic_builtins.h; path = src/atomic_builtins.h; sourceTree = ""; }; 4B2227A21D4FE23700A41CD3 /* atomic_no_threads.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = atomic_no_threads.h; path = src/atomic_no_threads.h; sourceTree = ""; }; 4B2227A31D4FE23700A41CD3 /* atomic_osatomic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = atomic_osatomic.h; path = src/atomic_osatomic.h; sourceTree = ""; }; 4B2227A41D4FE23700A41CD3 /* atomic_powerpc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = atomic_powerpc.h; path = src/atomic_powerpc.h; sourceTree = ""; }; 4B2227A51D4FE23700A41CD3 /* atomic_sync_builtins.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = atomic_sync_builtins.h; path = src/atomic_sync_builtins.h; sourceTree = ""; }; @@ -1978,10 +1986,21 @@ 4B187E23163EA3DA0049A832 /* Bridge-Info.plist */, 4B187E24163EA3DA0049A832 /* Makefile */, ); name = "Supporting Files"; sourceTree = ""; + }; + 4B1F61B11F66239200278BCB /* Invocation */ = { + isa = PBXGroup; + children = ( + 4B1F61B41F6623B800278BCB /* apple-call-x86_64.S */, + 4B1F61B21F6623B700278BCB /* call.S */, + 4B1F61B51F6623B800278BCB /* invoke-x86_64.m */, + 4B1F61B31F6623B700278BCB /* invoke.m */, + ); + name = Invocation; + sourceTree = ""; }; 4B3D23771337FBC800DD29B8 /* Products */ = { isa = PBXGroup; children = ( 4BF33AF0133807310059CEF7 /* Tests */, @@ -2053,10 +2072,11 @@ children = ( 4B187E07163EA2730049A832 /* Bridge */, 4B17FF6E133A28E0003E6DCD /* Exceptions */, 4B610DC41E31A46600AB26BA /* Encodings */, 4B5C112717E9AAC1003C917F /* Forwarding */, + 4B1F61B11F66239200278BCB /* Invocation */, 4B3D23801337FBC800DD29B8 /* Supporting Files */, 4B175C1D116D130B003C99CB /* OFApplication.h */, 4B175C1E116D130B003C99CB /* OFApplication.m */, 4B67995A1099E7C50041064A /* OFArray.h */, 4B67995B1099E7C50041064A /* OFArray.m */, @@ -3505,10 +3525,12 @@ 4B276E3F1E493D5000E20CE4 /* koi8-r.m in Sources */, 4B5EBFBA1E25A937004FE6A2 /* mac_roman.m in Sources */, 4BF3A22A1E25EA48002EA46F /* windows-1251.m in Sources */, 4B2C21971DA292BE00735907 /* windows-1252.m in Sources */, 4B2C21D41DA292BE00735907 /* forwarding.S in Sources */, + 4B1F61B71F6623B800278BCB /* call.S in Sources */, + 4B1F61B91F6623B800278BCB /* invoke.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B3D23711337FBC800DD29B8 /* Sources */ = { isa = PBXSourcesBuildPhase; @@ -3714,10 +3736,12 @@ 4B276E3D1E493D5000E20CE4 /* koi8-u.m in Sources */, 4B5EBFB91E25A937004FE6A2 /* mac_roman.m in Sources */, 4BF3A2291E25EA48002EA46F /* windows-1251.m in Sources */, 4B3D23BA1337FC0D00DD29B8 /* windows-1252.m in Sources */, 4B5C112F17E9AB3E003C917F /* forwarding.S in Sources */, + 4B1F61B61F6623B800278BCB /* call.S in Sources */, + 4B1F61B81F6623B800278BCB /* invoke.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 4B5D706D1DA2F87A00B3B2D7 /* Sources */ = { isa = PBXSourcesBuildPhase; Index: configure.ac ================================================================== --- configure.ac +++ configure.ac @@ -222,10 +222,12 @@ AC_SUBST(OBJFW_SHARED_LIB, "${LIB_PREFIX}objfw${LIB_SUFFIX}") AC_SUBST(EXCEPTIONS_LIB_A, "exceptions.lib.a") AC_SUBST(EXCEPTIONS_EXCEPTIONS_LIB_A, "exceptions/exceptions.lib.a") AC_SUBST(FORWARDING_LIB_A, "forwarding.lib.a") AC_SUBST(FORWARDING_FORWARDING_LIB_A, "forwarding/forwarding.lib.a") + AC_SUBST(INVOCATION_LIB_A, "invocation.lib.a") + AC_SUBST(INVOCATION_INVOCATION_LIB_A, "invocation/invocation.lib.a") AC_SUBST(LOOKUP_ASM_LIB_A, "lookup-asm.lib.a") AC_SUBST(LOOKUP_ASM_LOOKUP_ASM_LIB_A, "lookup-asm/lookup-asm.lib.a") ], [ AC_SUBST(LIBOBJFW_DEP, "../src/libobjfw.a") AC_SUBST(LIBOBJFW_DEP_LVL2, "../../src/libobjfw.a") @@ -235,10 +237,12 @@ AC_SUBST(OBJFW_STATIC_LIB, "libobjfw.a") AC_SUBST(EXCEPTIONS_A, "exceptions.a") AC_SUBST(EXCEPTIONS_EXCEPTIONS_A, "exceptions/exceptions.a") AC_SUBST(FORWARDING_A, "forwarding.a") AC_SUBST(FORWARDING_FORWARDING_A, "forwarding/forwarding.a") + AC_SUBST(INVOCATION_A, "invocation.a") + AC_SUBST(INVOCATION_INVOCATION_A, "invocation/invocation.a") AC_SUBST(LOOKUP_ASM_A, "lookup-asm.a") AC_SUBST(LOOKUP_ASM_LOOKUP_ASM_A, "lookup-asm/lookup-asm.a") ]) AC_DEFINE_UNQUOTED(PLUGIN_SUFFIX, "$PLUGIN_SUFFIX", [Suffix for plugins]) Index: extra.mk.in ================================================================== --- extra.mk.in +++ extra.mk.in @@ -32,10 +32,14 @@ FORWARDING_FORWARDING_A = @FORWARDING_FORWARDING_A@ FORWARDING_FORWARDING_LIB_A = @FORWARDING_FORWARDING_LIB_A@ FORWARDING_LIB_A = @FORWARDING_LIB_A@ FOUNDATION_COMPAT_M = @FOUNDATION_COMPAT_M@ INSTANCE_M = @INSTANCE_M@ +INVOCATION_A = @INVOCATION_A@ +INVOCATION_INVOCATION_A = @INVOCATION_INVOCATION_A@ +INVOCATION_INVOCATION_LIB_A = @INVOCATION_INVOCATION_LIB_A@ +INVOCATION_LIB_A = @INVOCATION_LIB_A@ LIBOBJFW_DEP = @LIBOBJFW_DEP@ LIBOBJFW_DEP_LVL2 = @LIBOBJFW_DEP_LVL2@ LOOKUP_ASM_A = @LOOKUP_ASM_A@ LOOKUP_ASM_LIB_A = @LOOKUP_ASM_LIB_A@ LOOKUP_ASM_LOOKUP_ASM_A = @LOOKUP_ASM_LOOKUP_ASM_A@ Index: src/Makefile ================================================================== --- src/Makefile +++ src/Makefile @@ -1,8 +1,8 @@ include ../extra.mk -SUBDIRS = ${RUNTIME} exceptions ${ENCODINGS} forwarding +SUBDIRS = ${RUNTIME} exceptions ${ENCODINGS} forwarding invocation SUBDIRS_AFTER = ${BRIDGE} DISTCLEAN = objfw-defs.h SHARED_LIB = ${OBJFW_SHARED_LIB} STATIC_LIB = ${OBJFW_STATIC_LIB} @@ -175,17 +175,19 @@ OFTCPSocket+SOCKS5.m OBJS_EXTRA = ${RUNTIME_RUNTIME_A} \ ${EXCEPTIONS_EXCEPTIONS_A} \ ${ENCODINGS_ENCODINGS_A} \ - ${FORWARDING_FORWARDING_A} + ${FORWARDING_FORWARDING_A} \ + ${INVOCATION_INVOCATION_A} LIB_OBJS_EXTRA = ${RUNTIME_RUNTIME_LIB_A} \ ${EXCEPTIONS_EXCEPTIONS_LIB_A} \ ${ENCODINGS_ENCODINGS_LIB_A} \ - ${FORWARDING_FORWARDING_LIB_A} + ${FORWARDING_FORWARDING_LIB_A} \ + ${INVOCATION_INVOCATION_LIB_A} include ../buildsys.mk CPPFLAGS += -I. -I.. -Iexceptions -Iruntime LD = ${OBJC} LDFLAGS += ${REEXPORT_RUNTIME} LIBS += -Lruntime ${RUNTIME_LIBS} Index: src/OFInvocation.h ================================================================== --- src/OFInvocation.h +++ src/OFInvocation.h @@ -15,10 +15,16 @@ */ #import "OFObject.h" OF_ASSUME_NONNULL_BEGIN + +#ifdef OF_APPLE_RUNTIME +# ifdef OF_X86_64 +# define OF_INVOCATION_CAN_INVOKE +# endif +#endif @class OFMethodSignature; @class OFMutableArray OF_GENERIC(ObjectType); @class OFMutableData; @@ -85,8 +91,15 @@ * @brief Gets the return value. * * @param buffer The buffer in which the return value is stored */ - (void)getReturnValue: (void *)buffer; + +#ifdef OF_INVOCATION_CAN_INVOKE +/*! + * @brief Invokes the method. + */ +- (void)invoke; +#endif @end OF_ASSUME_NONNULL_END Index: src/OFInvocation.m ================================================================== --- src/OFInvocation.m +++ src/OFInvocation.m @@ -20,10 +20,14 @@ #import "OFInvocation.h" #import "OFArray.h" #import "OFData.h" #import "OFMethodSignature.h" + +#ifdef OF_INVOCATION_CAN_INVOKE +extern void of_invocation_invoke(OFInvocation *); +#endif @implementation OFInvocation @synthesize methodSignature = _methodSignature; + (instancetype)invocationWithMethodSignature: (OFMethodSignature *)signature @@ -104,6 +108,13 @@ - (void)getReturnValue: (void *)buffer { memcpy(buffer, [_returnValue items], [_returnValue itemSize]); } + +#ifdef OF_INVOCATION_CAN_INVOKE +- (void)invoke +{ + of_invocation_invoke(self); +} +#endif @end Index: src/ObjFW.h ================================================================== --- src/ObjFW.h +++ src/ObjFW.h @@ -38,10 +38,11 @@ #import "OFEnumerator.h" #import "OFNull.h" #import "OFMethodSignature.h" +#import "OFInvocation.h" #import "OFIntrospection.h" #import "OFNumber.h" #import "OFDate.h" #import "OFURL.h" ADDED src/invocation/Makefile Index: src/invocation/Makefile ================================================================== --- src/invocation/Makefile +++ src/invocation/Makefile @@ -0,0 +1,12 @@ +include ../../extra.mk + +STATIC_PIC_LIB_NOINST = ${INVOCATION_LIB_A} +STATIC_LIB_NOINST = ${INVOCATION_A} + +SRCS = call.S \ + invoke.m + +include ../../buildsys.mk + +ASFLAGS += -I../.. -I.. +OBJCFLAGS += -I../.. -I.. -I../exceptions ADDED src/invocation/apple-call-x86_64.S Index: src/invocation/apple-call-x86_64.S ================================================================== --- src/invocation/apple-call-x86_64.S +++ src/invocation/apple-call-x86_64.S @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017 + * Jonathan Schleifer + * + * 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" + +.globl _of_invocation_call + +.section __TEXT, __text, regular, pure_instructions +_of_invocation_call: + pushq %rbp + movq %rsp, %rbp + + subq $16, %rsp + movq %rdi, -8(%rbp) + + movdqa 176(%rdi), %xmm7 + movdqa 160(%rdi), %xmm6 + movdqa 144(%rdi), %xmm5 + movdqa 128(%rdi), %xmm4 + movdqa 112(%rdi), %xmm3 + movdqa 96(%rdi), %xmm2 + movdqa 80(%rdi), %xmm1 + movdqa 64(%rdi), %xmm0 + + movq 40(%rdi), %r9 + movq 32(%rdi), %r8 + movq 24(%rdi), %rcx + movq 16(%rdi), %rdx + movq 8(%rdi), %rsi + movq 0(%rdi), %rdi + + call _objc_msgSend + + movq -8(%rbp), %rdi + movq %rax, 48(%rdi) + movq %rdx, 56(%rdi) + movdqa %xmm0, 64(%rdi) + movdqa %xmm1, 80(%rdi) + + movq %rbp, %rsp + popq %rbp + + ret ADDED src/invocation/call.S Index: src/invocation/call.S ================================================================== --- src/invocation/call.S +++ src/invocation/call.S @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017 + * Jonathan Schleifer + * + * 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 "platform.h" + +#ifdef OF_APPLE_RUNTIME +# if defined(OF_X86_64) +# include "apple-call-x86_64.S" +# endif +#endif ADDED src/invocation/invoke-x86_64.m Index: src/invocation/invoke-x86_64.m ================================================================== --- src/invocation/invoke-x86_64.m +++ src/invocation/invoke-x86_64.m @@ -0,0 +1,199 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017 + * Jonathan Schleifer + * + * 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 +#include + +#import "OFInvocation.h" +#import "OFMethodSignature.h" + +#import "OFInvalidFormatException.h" + +#define NUM_GPR_IN 6 +#define NUM_GPR_OUT 2 +#define NUM_SSE_IN 8 +#define NUM_SSE_OUT 2 + +struct registers { + uint64_t gpr[NUM_GPR_IN + NUM_GPR_OUT]; + __m128 sse[NUM_SSE_IN]; +}; + +extern void of_invocation_call(struct registers *); + +void +of_invocation_invoke(OFInvocation *invocation) +{ + OFMethodSignature *methodSignature = [invocation methodSignature]; + size_t numberOfArguments = [methodSignature numberOfArguments]; + const char *typeEncoding; + struct registers registers; + size_t currentGPR = 0, currentSSE = 0; + + for (size_t i = 0; i < numberOfArguments; i++) { + union { + uint64_t gpr; + __m128 sse; + } value; + enum { + VALUE_GPR, + VALUE_SSE + } valueType; + + typeEncoding = [methodSignature argumentTypeAtIndex: i]; + + if (*typeEncoding == 'r') + typeEncoding++; + + switch (*typeEncoding) { +#define CASE_GPR(encoding, type) \ + case encoding: \ + { \ + type tmp; \ + [invocation getArgument: &tmp \ + atIndex: i]; \ + value.gpr = tmp; \ + valueType = VALUE_GPR; \ + } \ + break; + CASE_GPR('c', char) + CASE_GPR('C', unsigned char) + CASE_GPR('i', int) + CASE_GPR('I', unsigned int) + CASE_GPR('s', short) + CASE_GPR('S', unsigned short) + CASE_GPR('l', long) + CASE_GPR('L', unsigned long) + CASE_GPR('q', long long) + CASE_GPR('Q', unsigned long long) +#ifdef __SIZEOF_INT128__ + /* TODO: 't' */ + /* TODO: 'T' */ +#endif + case 'f': + { + float tmp; + [invocation getArgument: &tmp + atIndex: i]; + value.sse = _mm_set_ss(tmp); + valueType = VALUE_SSE; + } + break; + case 'd': + { + double tmp; + [invocation getArgument: &tmp + atIndex: i]; + value.sse = _mm_set_sd(tmp); + valueType = VALUE_SSE; + } + break; + /* TODO: 'D' */ + CASE_GPR('B', _Bool) + CASE_GPR('*', uintptr_t) + CASE_GPR('@', uintptr_t) + CASE_GPR('#', uintptr_t) + CASE_GPR(':', uintptr_t) + /* TODO: '[' */ + /* TODO: '{' */ + /* TODO: '(' */ + CASE_GPR('^', uintptr_t) +#ifndef __STDC_NO_COMPLEX__ + /* TODO: 'j' */ +#endif + default: + @throw [OFInvalidFormatException exception]; +#undef CASE_GPR + } + + if (valueType == VALUE_GPR) { + if (currentGPR < NUM_GPR_IN) + registers.gpr[currentGPR++] = value.gpr; + else + /* TODO */ + abort(); + } else if (valueType == VALUE_SSE) { + if (currentSSE < NUM_SSE_IN) + registers.sse[currentSSE++] = value.sse; + else + /* TODO */ + abort(); + } + } + + of_invocation_call(®isters); + + typeEncoding = [methodSignature methodReturnType]; + + if (*typeEncoding == 'r') + typeEncoding++; + + switch (*typeEncoding) { +#define CASE_GPR(encoding, type) \ + case encoding: \ + { \ + type tmp = (type)registers.gpr[NUM_GPR_IN]; \ + [invocation setReturnValue: &tmp]; \ + } \ + break; + CASE_GPR('c', char) + CASE_GPR('C', unsigned char) + CASE_GPR('i', int) + CASE_GPR('I', unsigned int) + CASE_GPR('s', short) + CASE_GPR('S', unsigned short) + CASE_GPR('l', long) + CASE_GPR('L', unsigned long) + CASE_GPR('q', long long) + CASE_GPR('Q', unsigned long long) +#ifdef __SIZEOF_INT128__ + /* TODO: 't' */ + /* TODO: 'T' */ +#endif + case 'f': + { + float tmp; + _mm_store_ss(&tmp, registers.sse[0]); + [invocation setReturnValue: &tmp]; + } + break; + case 'd': + { + double tmp; + _mm_store_sd(&tmp, registers.sse[0]); + [invocation setReturnValue: &tmp]; + } + break; + /* TODO: 'D' */ + CASE_GPR('B', _Bool) + CASE_GPR('*', uintptr_t) + CASE_GPR('@', uintptr_t) + CASE_GPR('#', uintptr_t) + CASE_GPR(':', uintptr_t) + /* TODO: '[' */ + /* TODO: '{' */ + /* TODO: '(' */ + CASE_GPR('^', uintptr_t) +#ifndef __STDC_NO_COMPLEX__ + /* TODO: 'j' */ +#endif + default: + @throw [OFInvalidFormatException exception]; +#undef CASE_GPR + } +} ADDED src/invocation/invoke.m Index: src/invocation/invoke.m ================================================================== --- src/invocation/invoke.m +++ src/invocation/invoke.m @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017 + * Jonathan Schleifer + * + * 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 "platform.h" + +#ifdef OF_X86_64 +# include "invoke-x86_64.m" +#else +/* To not have an empty translation unit otherwise */ +int of_invocation_cannot_invoke; +#endif