From e512358bc96b7be58bf4f2d5a2c5de75f119138a Mon Sep 17 00:00:00 2001 From: Jacek Sieka Date: Thu, 13 Apr 2017 04:57:10 +0800 Subject: [PATCH] Linux abi take 3 (#5692) * avoid generating object fields for imported types * fix some abi/type issues for linux_amd64 --- compiler/ccgtypes.nim | 2 +- lib/posix/epoll.nim | 6 ++++-- lib/posix/termios.nim | 26 +++++++++++++++++++------- lib/pure/times.nim | 34 ++++++++++++++++++++++++---------- lib/system/ansi_c.nim | 10 ++++++++-- lib/system/syslocks.nim | 9 +++++++++ lib/system/threads.nim | 34 +++++++++++++++++++++------------- 7 files changed, 86 insertions(+), 35 deletions(-) diff --git a/compiler/ccgtypes.nim b/compiler/ccgtypes.nim index 9915ad355f..2b7cfaea1c 100644 --- a/compiler/ccgtypes.nim +++ b/compiler/ccgtypes.nim @@ -988,7 +988,7 @@ proc genObjectInfo(m: BModule, typ, origType: PType, name: Rope) = if typ.kind == tyObject: genTypeInfoAux(m, typ, origType, name) else: genTypeInfoAuxBase(m, typ, origType, name, rope("0")) var tmp = getNimNode(m) - if not isImportedCppType(typ): + if not isImportedType(typ): genObjectFields(m, typ, origType, typ.n, tmp) addf(m.s[cfsTypeInit3], "$1.node = &$2;$n", [name, tmp]) var t = typ.sons[0] diff --git a/lib/posix/epoll.nim b/lib/posix/epoll.nim index 276dd812db..86b9775766 100644 --- a/lib/posix/epoll.nim +++ b/lib/posix/epoll.nim @@ -38,8 +38,10 @@ type epoll_data* {.importc: "union epoll_data", header: "", pure, final.} = object # TODO: This is actually a union. #thePtr* {.importc: "ptr".}: pointer - fd* {.importc: "fd".}: cint # \ - #u32*: uint32 + fd* {.importc: "fd".}: cint + when defined(linux) and defined(amd64): + u32: uint32 # this field ensures that binary size is right - it cannot be + # used because its offset is wrong #u64*: uint64 epoll_event* {.importc: "struct epoll_event", header: "", pure, final.} = object diff --git a/lib/posix/termios.nim b/lib/posix/termios.nim index af62bdb3dd..21b21aefb0 100644 --- a/lib/posix/termios.nim +++ b/lib/posix/termios.nim @@ -18,13 +18,25 @@ type const NCCS* = when defined(macosx): 20 else: 32 -type - Termios* {.importc: "struct termios", header: "".} = object - c_iflag*: Cflag # input mode flags - c_oflag*: Cflag # output mode flags - c_cflag*: Cflag # control mode flags - c_lflag*: Cflag # local mode flags - c_cc*: array[NCCS, cuchar] # control characters +when defined(linux) and defined(amd64): + type + Termios* {.importc: "struct termios", header: "".} = object + c_iflag*: Cflag # input mode flags + c_oflag*: Cflag # output mode flags + c_cflag*: Cflag # control mode flags + c_lflag*: Cflag # local mode flags + c_line*: cuchar + c_cc*: array[NCCS, cuchar] # control characters + c_ispeed*: Speed + c_ospeed*: Speed +else: + type + Termios* {.importc: "struct termios", header: "".} = object + c_iflag*: Cflag # input mode flags + c_oflag*: Cflag # output mode flags + c_cflag*: Cflag # control mode flags + c_lflag*: Cflag # local mode flags + c_cc*: array[NCCS, cuchar] # control characters # cc characters diff --git a/lib/pure/times.nim b/lib/pure/times.nim index 1b088c0acc..bad003a3e1 100644 --- a/lib/pure/times.nim +++ b/lib/pure/times.nim @@ -47,15 +47,26 @@ type dMon, dTue, dWed, dThu, dFri, dSat, dSun when defined(posix) and not defined(JS): - type - TimeImpl {.importc: "time_t", header: "".} = int - Time* = distinct TimeImpl ## distinct type that represents a time - ## measured as number of seconds since the epoch + when defined(linux) and defined(amd64): + type + TimeImpl {.importc: "time_t", header: "".} = clong + Time* = distinct TimeImpl ## distinct type that represents a time + ## measured as number of seconds since the epoch - Timeval {.importc: "struct timeval", - header: "".} = object ## struct timeval - tv_sec: int ## Seconds. - tv_usec: int ## Microseconds. + Timeval {.importc: "struct timeval", + header: "".} = object ## struct timeval + tv_sec: clong ## Seconds. + tv_usec: clong ## Microseconds. + else: + type + TimeImpl {.importc: "time_t", header: "".} = int + Time* = distinct TimeImpl ## distinct type that represents a time + ## measured as number of seconds since the epoch + + Timeval {.importc: "struct timeval", + header: "".} = object ## struct timeval + tv_sec: int ## Seconds. + tv_usec: int ## Microseconds. # we cannot import posix.nim here, because posix.nim depends on times.nim. # Ok, we could, but I don't want circular dependencies. @@ -1103,7 +1114,7 @@ when not defined(JS): when defined(freebsd) or defined(netbsd) or defined(openbsd) or defined(macosx): type - StructTM {.importc: "struct tm", final.} = object + StructTM {.importc: "struct tm".} = object second {.importc: "tm_sec".}, minute {.importc: "tm_min".}, hour {.importc: "tm_hour".}, @@ -1116,7 +1127,7 @@ when not defined(JS): gmtoff {.importc: "tm_gmtoff".}: clong else: type - StructTM {.importc: "struct tm", final.} = object + StructTM {.importc: "struct tm".} = object second {.importc: "tm_sec".}, minute {.importc: "tm_min".}, hour {.importc: "tm_hour".}, @@ -1126,6 +1137,9 @@ when not defined(JS): weekday {.importc: "tm_wday".}, yearday {.importc: "tm_yday".}, isdst {.importc: "tm_isdst".}: cint + when defined(linux) and defined(amd64): + gmtoff {.importc: "tm_gmtoff".}: clong + zone {.importc: "tm_zone".}: cstring type TimeInfoPtr = ptr StructTM Clock {.importc: "clock_t".} = distinct int diff --git a/lib/system/ansi_c.nim b/lib/system/ansi_c.nim index 52065531b9..b2f6d314fb 100644 --- a/lib/system/ansi_c.nim +++ b/lib/system/ansi_c.nim @@ -26,8 +26,14 @@ proc c_memset(p: pointer, value: cint, size: csize): pointer {. proc c_strcmp(a, b: cstring): cint {. importc: "strcmp", header: "", noSideEffect.} -type - C_JmpBuf {.importc: "jmp_buf", header: "".} = object +when defined(linux) and defined(amd64): + type + C_JmpBuf {.importc: "jmp_buf", header: "", bycopy.} = object + abi: array[200 div sizeof(clong), clong] +else: + type + C_JmpBuf {.importc: "jmp_buf", header: "".} = object + when defined(windows): const diff --git a/lib/system/syslocks.nim b/lib/system/syslocks.nim index 9d056611fb..fb354880f9 100644 --- a/lib/system/syslocks.nim +++ b/lib/system/syslocks.nim @@ -102,12 +102,21 @@ else: SysLock {.importc: "pthread_mutex_t", pure, final, header: """#include #include """.} = object + when defined(linux) and defined(amd64): + abi: array[40 div sizeof(clong), clong] + SysLockAttr {.importc: "pthread_mutexattr_t", pure, final header: """#include #include """.} = object + when defined(linux) and defined(amd64): + abi: array[4 div sizeof(cint), cint] # actually a cint + SysCond {.importc: "pthread_cond_t", pure, final, header: """#include #include """.} = object + when defined(linux) and defined(amd64): + abi: array[48 div sizeof(clonglong), clonglong] + SysLockType = distinct cint proc initSysLock(L: var SysLock, attr: ptr SysLockAttr = nil) {. diff --git a/lib/system/threads.nim b/lib/system/threads.nim index 7743fffff5..d1012e9c52 100644 --- a/lib/system/threads.nim +++ b/lib/system/threads.nim @@ -177,18 +177,28 @@ else: else: type Time = int + when defined(linux) and defined(amd64): + type + SysThread* {.importc: "pthread_t", + header: "" .} = distinct culong + Pthread_attr {.importc: "pthread_attr_t", + header: "".} = object + abi: array[56 div sizeof(clong), clong] + ThreadVarSlot {.importc: "pthread_key_t", + header: "".} = distinct cuint + else: + type + SysThread* {.importc: "pthread_t", header: "".} = object + Pthread_attr {.importc: "pthread_attr_t", + header: "".} = object + ThreadVarSlot {.importc: "pthread_key_t", + header: "".} = object type - SysThread* {.importc: "pthread_t", header: "", - final, pure.} = object - Pthread_attr {.importc: "pthread_attr_t", - header: "", final, pure.} = object - - Timespec {.importc: "struct timespec", - header: "", final, pure.} = object + Timespec {.importc: "struct timespec", header: "".} = object tv_sec: Time tv_nsec: clong {.deprecated: [TSysThread: SysThread, Tpthread_attr: PThreadAttr, - Ttimespec: Timespec].} + Ttimespec: Timespec, TThreadVarSlot: ThreadVarSlot].} proc pthread_attr_init(a1: var PthreadAttr) {. importc, header: pthreadh.} @@ -205,11 +215,6 @@ else: proc pthread_cancel(a1: SysThread): cint {. importc: "pthread_cancel", header: pthreadh.} - type - ThreadVarSlot {.importc: "pthread_key_t", pure, final, - header: "".} = object - {.deprecated: [TThreadVarSlot: ThreadVarSlot].} - proc pthread_getspecific(a1: ThreadVarSlot): pointer {. importc: "pthread_getspecific", header: pthreadh.} proc pthread_key_create(a1: ptr ThreadVarSlot, @@ -234,6 +239,9 @@ else: importc: "pthread_attr_setstack", header: pthreadh.} type CpuSet {.importc: "cpu_set_t", header: schedh.} = object + when defined(linux) and defined(amd64): + abi: array[1024 div (8 * sizeof(culong)), culong] + proc cpusetZero(s: var CpuSet) {.importc: "CPU_ZERO", header: schedh.} proc cpusetIncl(cpu: cint; s: var CpuSet) {. importc: "CPU_SET", header: schedh.}