R_object_helper.h 4.12 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
/*!
 * Copyright (c) 2017 Microsoft Corporation. All rights reserved.
 * Licensed under the MIT License. See LICENSE file in the project root for license information.
 *
 * \brief A simple wrapper for accessing data in R object.
 *
 * \note
 * Due to license issue, we cannot include R's header file, so use this simple wrapper instead.
 * However, if R changes the way it defines objects, this file will need to be updated as well.
 */
Guolin Ke's avatar
Guolin Ke committed
11
12
13
14
15
16
#ifndef R_OBJECT_HELPER_H_
#define R_OBJECT_HELPER_H_

#include <cstdint>

#define TYPE_BITS 5
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
// use .Internal(internalsID()) to uuid
#define R_INTERNALS_UUID "2fdf6c18-697a-4ba7-b8ef-11c0d92f1327"


#ifdef R_VER_ABOVE_35
#define NAMED_BITS 16
struct lgbm_sxpinfo {
  unsigned int type : 5;
  unsigned int scalar : 1;
  unsigned int obj : 1;
  unsigned int alt : 1;
  unsigned int gp : 16;
  unsigned int mark : 1;
  unsigned int debug : 1;
  unsigned int trace : 1;
  unsigned int spare : 1;
  unsigned int gcgen : 1;
  unsigned int gccls : 3;
  unsigned int named : NAMED_BITS;
  unsigned int extra : 32 - NAMED_BITS;
};

// 64bit pointer
#if INTPTR_MAX == INT64_MAX
Guolin Ke's avatar
Guolin Ke committed
41
typedef int64_t R_xlen_t;
42
43
44
45
46
#else
typedef int R_xlen_t;
#endif

#else
Guolin Ke's avatar
Guolin Ke committed
47
struct lgbm_sxpinfo {
Guolin Ke's avatar
Guolin Ke committed
48
49
50
51
52
53
54
55
56
57
58
59
  unsigned int type : 5;
  unsigned int obj : 1;
  unsigned int named : 2;
  unsigned int gp : 16;
  unsigned int mark : 1;
  unsigned int debug : 1;
  unsigned int trace : 1;
  unsigned int spare : 1;
  unsigned int gcgen : 1;
  unsigned int gccls : 3;
};

60
61
62
typedef int R_xlen_t;
#endif

Guolin Ke's avatar
Guolin Ke committed
63
struct lgbm_primsxp {
Guolin Ke's avatar
Guolin Ke committed
64
65
66
  int offset;
};

Guolin Ke's avatar
Guolin Ke committed
67
68
69
70
struct lgbm_symsxp {
  struct LGBM_SER *pname;
  struct LGBM_SER *value;
  struct LGBM_SER *internal;
Guolin Ke's avatar
Guolin Ke committed
71
72
};

Guolin Ke's avatar
Guolin Ke committed
73
74
75
76
struct lgbm_listsxp {
  struct LGBM_SER *carval;
  struct LGBM_SER *cdrval;
  struct LGBM_SER *tagval;
Guolin Ke's avatar
Guolin Ke committed
77
78
};

Guolin Ke's avatar
Guolin Ke committed
79
80
81
82
struct lgbm_envsxp {
  struct LGBM_SER *frame;
  struct LGBM_SER *enclos;
  struct LGBM_SER *hashtab;
Guolin Ke's avatar
Guolin Ke committed
83
84
};

Guolin Ke's avatar
Guolin Ke committed
85
86
87
88
struct lgbm_closxp {
  struct LGBM_SER *formals;
  struct LGBM_SER *body;
  struct LGBM_SER *env;
Guolin Ke's avatar
Guolin Ke committed
89
90
};

Guolin Ke's avatar
Guolin Ke committed
91
92
93
94
struct lgbm_promsxp {
  struct LGBM_SER *value;
  struct LGBM_SER *expr;
  struct LGBM_SER *env;
Guolin Ke's avatar
Guolin Ke committed
95
96
};

Guolin Ke's avatar
Guolin Ke committed
97
98
99
100
typedef struct LGBM_SER {
  struct lgbm_sxpinfo sxpinfo;
  struct LGBM_SER* attrib;
  struct LGBM_SER* gengc_next_node, *gengc_prev_node;
Guolin Ke's avatar
Guolin Ke committed
101
  union {
Guolin Ke's avatar
Guolin Ke committed
102
103
104
105
106
107
    struct lgbm_primsxp primsxp;
    struct lgbm_symsxp symsxp;
    struct lgbm_listsxp listsxp;
    struct lgbm_envsxp envsxp;
    struct lgbm_closxp closxp;
    struct lgbm_promsxp promsxp;
Guolin Ke's avatar
Guolin Ke committed
108
  } u;
Guolin Ke's avatar
Guolin Ke committed
109
} LGBM_SER, *LGBM_SE;
Guolin Ke's avatar
Guolin Ke committed
110

Guolin Ke's avatar
Guolin Ke committed
111
struct lgbm_vecsxp {
112
113
  R_xlen_t length;
  R_xlen_t truelength;
Guolin Ke's avatar
Guolin Ke committed
114
115
};

Guolin Ke's avatar
Guolin Ke committed
116
117
118
119
120
121
typedef struct VECTOR_SER {
  struct lgbm_sxpinfo sxpinfo;
  struct LGBM_SER* attrib;
  struct LGBM_SER* gengc_next_node, *gengc_prev_node;
  struct lgbm_vecsxp vecsxp;
} VECTOR_SER, *VECSE;
Guolin Ke's avatar
Guolin Ke committed
122

Guolin Ke's avatar
Guolin Ke committed
123
typedef union { VECTOR_SER s; double align; } SEXPREC_ALIGN;
Guolin Ke's avatar
Guolin Ke committed
124

Guolin Ke's avatar
Guolin Ke committed
125
#define DATAPTR(x)  ((reinterpret_cast<SEXPREC_ALIGN*>(x)) + 1)
Guolin Ke's avatar
Guolin Ke committed
126

Guolin Ke's avatar
Guolin Ke committed
127
#define R_CHAR_PTR(x)     (reinterpret_cast<char*>DATAPTR(x))
Guolin Ke's avatar
Guolin Ke committed
128

Guolin Ke's avatar
Guolin Ke committed
129
#define R_INT_PTR(x)  (reinterpret_cast<int*> DATAPTR(x))
Guolin Ke's avatar
Guolin Ke committed
130

Guolin Ke's avatar
Guolin Ke committed
131
#define R_INT64_PTR(x)  (reinterpret_cast<int64_t*> DATAPTR(x))
Guolin Ke's avatar
Guolin Ke committed
132

Guolin Ke's avatar
Guolin Ke committed
133
#define R_REAL_PTR(x)     (reinterpret_cast<double*> DATAPTR(x))
Guolin Ke's avatar
Guolin Ke committed
134

Guolin Ke's avatar
Guolin Ke committed
135
#define R_AS_INT(x) (*(reinterpret_cast<int*> DATAPTR(x)))
Guolin Ke's avatar
Guolin Ke committed
136

Guolin Ke's avatar
Guolin Ke committed
137
#define R_AS_INT64(x) (*(reinterpret_cast<int64_t*> DATAPTR(x)))
Guolin Ke's avatar
Guolin Ke committed
138

Guolin Ke's avatar
Guolin Ke committed
139
#define R_IS_NULL(x) ((*reinterpret_cast<LGBM_SE>(x)).sxpinfo.type == 0)
Guolin Ke's avatar
Guolin Ke committed
140
141
142
143

// 64bit pointer
#if INTPTR_MAX == INT64_MAX

Guolin Ke's avatar
Guolin Ke committed
144
#define R_ADDR(x)  (reinterpret_cast<int64_t*> DATAPTR(x))
Guolin Ke's avatar
Guolin Ke committed
145

Guolin Ke's avatar
Guolin Ke committed
146
inline void R_SET_PTR(LGBM_SE x, void* ptr) {
Guolin Ke's avatar
Guolin Ke committed
147
148
149
150
151
152
153
  if (ptr == nullptr) {
    R_ADDR(x)[0] = (int64_t)(NULL);
  } else {
    R_ADDR(x)[0] = (int64_t)(ptr);
  }
}

Guolin Ke's avatar
Guolin Ke committed
154
inline void* R_GET_PTR(LGBM_SE x) {
Guolin Ke's avatar
Guolin Ke committed
155
156
157
  if (R_IS_NULL(x)) {
    return nullptr;
  } else {
Guolin Ke's avatar
Guolin Ke committed
158
    auto ret = reinterpret_cast<void*>(R_ADDR(x)[0]);
Guolin Ke's avatar
Guolin Ke committed
159
160
161
162
163
164
165
166
167
    if (ret == NULL) {
      ret = nullptr;
    }
    return ret;
  }
}

#else

Guolin Ke's avatar
Guolin Ke committed
168
#define R_ADDR(x)  (reinterpret_cast<int32_t*> DATAPTR(x))
Guolin Ke's avatar
Guolin Ke committed
169

Guolin Ke's avatar
Guolin Ke committed
170
inline void R_SET_PTR(LGBM_SE x, void* ptr) {
Guolin Ke's avatar
Guolin Ke committed
171
172
173
174
175
176
177
  if (ptr == nullptr) {
    R_ADDR(x)[0] = (int32_t)(NULL);
  } else {
    R_ADDR(x)[0] = (int32_t)(ptr);
  }
}

Guolin Ke's avatar
Guolin Ke committed
178
inline void* R_GET_PTR(LGBM_SE x) {
Guolin Ke's avatar
Guolin Ke committed
179
180
181
  if (R_IS_NULL(x)) {
    return nullptr;
  } else {
Guolin Ke's avatar
Guolin Ke committed
182
    auto ret = reinterpret_cast<void*>(R_ADDR(x)[0]);
Guolin Ke's avatar
Guolin Ke committed
183
184
185
186
187
188
189
190
191
    if (ret == NULL) {
      ret = nullptr;
    }
    return ret;
  }
}

#endif

192
#endif  // R_OBJECT_HELPER_H_