R_object_helper.h 3.74 KB
Newer Older
1
2
3
4
5
6
7
/*!
 * 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
8
9
10
11
 * We previously did not want to use R's headers because of license concerns. This is no longer a concern:
 * https://github.com/microsoft/LightGBM/issues/629#issuecomment-474995635
 * For now, this wrapper is LightGBM's interface from R to C.
 * If R changes the way it defines objects, this file will need to be updated as well.
12
 */
Guolin Ke's avatar
Guolin Ke committed
13
14
15
16
17
#ifndef R_OBJECT_HELPER_H_
#define R_OBJECT_HELPER_H_

#include <cstdint>

18
19
20
#define R_NO_REMAP
#define R_USE_C99_IN_CXX
#include <Rinternals.h>
21

22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#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;
};
38

Guolin Ke's avatar
Guolin Ke committed
39
struct lgbm_primsxp {
Guolin Ke's avatar
Guolin Ke committed
40
41
42
  int offset;
};

Guolin Ke's avatar
Guolin Ke committed
43
44
45
46
struct lgbm_symsxp {
  struct LGBM_SER *pname;
  struct LGBM_SER *value;
  struct LGBM_SER *internal;
Guolin Ke's avatar
Guolin Ke committed
47
48
};

Guolin Ke's avatar
Guolin Ke committed
49
50
51
52
struct lgbm_listsxp {
  struct LGBM_SER *carval;
  struct LGBM_SER *cdrval;
  struct LGBM_SER *tagval;
Guolin Ke's avatar
Guolin Ke committed
53
54
};

Guolin Ke's avatar
Guolin Ke committed
55
56
57
58
struct lgbm_envsxp {
  struct LGBM_SER *frame;
  struct LGBM_SER *enclos;
  struct LGBM_SER *hashtab;
Guolin Ke's avatar
Guolin Ke committed
59
60
};

Guolin Ke's avatar
Guolin Ke committed
61
62
63
64
struct lgbm_closxp {
  struct LGBM_SER *formals;
  struct LGBM_SER *body;
  struct LGBM_SER *env;
Guolin Ke's avatar
Guolin Ke committed
65
66
};

Guolin Ke's avatar
Guolin Ke committed
67
68
69
70
struct lgbm_promsxp {
  struct LGBM_SER *value;
  struct LGBM_SER *expr;
  struct LGBM_SER *env;
Guolin Ke's avatar
Guolin Ke committed
71
72
};

Guolin Ke's avatar
Guolin Ke committed
73
74
75
76
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
77
  union {
Guolin Ke's avatar
Guolin Ke committed
78
79
80
81
82
83
    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
84
  } u;
Guolin Ke's avatar
Guolin Ke committed
85
} LGBM_SER, *LGBM_SE;
Guolin Ke's avatar
Guolin Ke committed
86

Guolin Ke's avatar
Guolin Ke committed
87
struct lgbm_vecsxp {
88
89
  R_xlen_t length;
  R_xlen_t truelength;
Guolin Ke's avatar
Guolin Ke committed
90
91
};

Guolin Ke's avatar
Guolin Ke committed
92
93
94
95
96
97
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
98

Guolin Ke's avatar
Guolin Ke committed
99
typedef union { VECTOR_SER s; double align; } SEXPREC_ALIGN;
Guolin Ke's avatar
Guolin Ke committed
100

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

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

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

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

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

111
#define R_IS_NULL(x)   ((*reinterpret_cast<LGBM_SE>(x)).sxpinfo.type == 0)
Guolin Ke's avatar
Guolin Ke committed
112
113
114
115

// 64bit pointer
#if INTPTR_MAX == INT64_MAX

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

118
119
120
121
122
123
  inline void R_SET_PTR(LGBM_SE x, void* ptr) {
    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
124
  }
125
126
127
128
129
130
131
132
133
134

  inline void* R_GET_PTR(LGBM_SE x) {
    if (R_IS_NULL(x)) {
      return nullptr;
    } else {
      auto ret = reinterpret_cast<void*>(R_ADDR(x)[0]);
      if (ret == NULL) {
        ret = nullptr;
      }
      return ret;
Guolin Ke's avatar
Guolin Ke committed
135
136
137
138
139
    }
  }

#else

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

142
143
144
145
146
147
  inline void R_SET_PTR(LGBM_SE x, void* ptr) {
    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
148
  }
149
150
151
152
153
154
155
156
157
158

  inline void* R_GET_PTR(LGBM_SE x) {
    if (R_IS_NULL(x)) {
      return nullptr;
    } else {
      auto ret = reinterpret_cast<void*>(R_ADDR(x)[0]);
      if (ret == NULL) {
        ret = nullptr;
      }
      return ret;
Guolin Ke's avatar
Guolin Ke committed
159
160
161
    }
  }

162
#endif  // INTPTR_MAX == INT64_MAX
Guolin Ke's avatar
Guolin Ke committed
163

164
#endif  // R_OBJECT_HELPER_H_