Document that type holes kill polymorphic recursion
[ghc.git] / rts / RtsSymbolInfo.c
1 /* -----------------------------------------------------------------------------
2 *
3 * (c) The GHC Team, 2000-2015
4 *
5 * RTS Symbols
6 *
7 * ---------------------------------------------------------------------------*/
8
9 #include "ghcplatform.h"
10 #include "RtsSymbolInfo.h"
11
12 #include "Rts.h"
13 #include "HsFFI.h"
14
15 #include "Hash.h"
16 #include "RtsUtils.h"
17
18 #include <stdbool.h>
19
20 /* Generic function to update any extra info fields. */
21 void setSymbolInfo(ObjectCode *owner, const void *label, symbolUpdater updater)
22 {
23 SymbolInfo *info;
24 if (owner && label)
25 {
26 info = NULL;
27 if (!owner->extraInfos)
28 owner->extraInfos = allocStrHashTable();
29 else
30 info = lookupStrHashTable(owner->extraInfos, label);
31
32 if (!info)
33 {
34 info = stgMallocBytes(sizeof(SymbolInfo), "setSymbolInfo");
35 info->kind = 0;
36 }
37
38 updater(info);
39 insertStrHashTable(owner->extraInfos, label, info);
40 }
41 }
42
43 /* -----------------------------------------------------------------------------
44 * Performs a check to see if the symbol at the given address
45 * is a weak symbol or not.
46 *
47 * Returns: true on symbol being weak, else false
48 */
49 bool isSymbolWeak(ObjectCode *owner, const void *label)
50 {
51 SymbolInfo *info;
52 return owner
53 && label
54 && owner->extraInfos
55 && (info = lookupStrHashTable(owner->extraInfos, label)) != NULL
56 && (info->kind & KIND_WEAK) == KIND_WEAK;
57 }
58
59 /* -----------------------------------------------------------------------------
60 * Performs a check to see if the symbol at the given address
61 * is an import symbol or not.
62 *
63 * Returns: true on symbol being weak, else false
64 */
65 bool isSymbolImport(ObjectCode *owner, const void *label)
66 {
67 SymbolInfo *info;
68 return owner
69 && label
70 && owner->extraInfos
71 && (info = lookupStrHashTable(owner->extraInfos, label)) != NULL
72 && (info->kind & KIND_IMPORT) == KIND_IMPORT;
73 }
74
75 static void markWeak(SymbolInfo* info)
76 {
77 if(info)
78 info->kind |= KIND_WEAK;
79 }
80
81 static void markImport(SymbolInfo* info)
82 {
83 if(info)
84 info->kind |= KIND_IMPORT;
85 }
86
87 static void unmarkImport(SymbolInfo* info)
88 {
89 if(info)
90 info->kind &= ~KIND_IMPORT;
91 }
92
93 /* -----------------------------------------------------------------------------
94 * Marks the symbol at the given address as weak or not.
95 * If the extra symbol infos table has not been initialized
96 * yet this will create and allocate a new Hashtable
97 */
98 void setWeakSymbol(ObjectCode *owner, const void *label)
99 {
100 setSymbolInfo (owner, label, &markWeak);
101 }
102
103 /* -----------------------------------------------------------------------------
104 * Marks the symbol at the given address as import or not.
105 * If the extra symbol infos table has not been initialized
106 * yet this will create and allocate a new Hashtable
107 */
108 void setImportSymbol(ObjectCode *owner, const void *label)
109 {
110 setSymbolInfo (owner, label, &markImport);
111 }
112
113 /* -----------------------------------------------------------------------------
114 * Clear the import symbol flag.
115 * If the extra symbol infos table has not been initialized
116 * yet this will create and allocate a new Hashtable
117 */
118 void clearImportSymbol(ObjectCode *owner, const void *label)
119 {
120 setSymbolInfo (owner, label, &unmarkImport);
121 }