1 /* Domain-independent part of the Java interface: inline functions.
2 Copyright (C) 2001-2010 Roberto Bagnara <bagnara@cs.unipr.it>
3 Copyright (C) 2010-2016 BUGSENG srl (http://bugseng.com)
4
5 This file is part of the Parma Polyhedra Library (PPL).
6
7 The PPL is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 3 of the License, or (at your
10 option) any later version.
11
12 The PPL is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software Foundation,
19 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1307, USA.
20
21 For the most up-to-date information see the Parma Polyhedra Library
22 site: http://bugseng.com/products/ppl/ . */
23
24 #ifndef PPL_ppl_java_common_inlines_hh
25 #define PPL_ppl_java_common_inlines_hh 1
26
27 #include <cassert>
28
29 namespace Parma_Polyhedra_Library {
30
31 namespace Interfaces {
32
33 namespace Java {
34
35 template <typename U, typename V>
36 U
37 jtype_to_unsigned(const V& value) {
38 if (value < 0)
39 throw std::invalid_argument("not an unsigned integer.");
40
41 if (sizeof(U) < sizeof(V)) {
42 if (value > static_cast<V>(std::numeric_limits<U>::max()))
43 throw std::invalid_argument("unsigned integer out of range.");
44 }
45
46 return value;
47 }
48
49 template <typename T>
50 inline void
set_ptr(JNIEnv * env,jobject ppl_object,const T * address,bool to_be_marked)51 set_ptr(JNIEnv* env, jobject ppl_object,
52 const T* address, bool to_be_marked) {
53 const T* ptr = (to_be_marked ? mark(address) : address);
54 jlong pointer_value = reinterpret_cast<jlong>(ptr);
55 assert(reinterpret_cast<const T*>(pointer_value) == ptr);
56 env->SetLongField(ppl_object, cached_FMIDs.PPL_Object_ptr_ID, pointer_value);
57 }
58
59 inline void*
get_ptr(JNIEnv * env,jobject ppl_object)60 get_ptr(JNIEnv* env, jobject ppl_object) {
61 jlong pointer_value
62 = env->GetLongField(ppl_object, cached_FMIDs.PPL_Object_ptr_ID);
63 void* ptr = reinterpret_cast<void*>(pointer_value);
64 assert(reinterpret_cast<jlong>(ptr) == pointer_value);
65 return unmark(ptr);
66 }
67
68 inline bool
is_java_marked(JNIEnv * env,jobject ppl_object)69 is_java_marked(JNIEnv* env, jobject ppl_object) {
70 jlong pointer_value
71 = env->GetLongField(ppl_object, cached_FMIDs.PPL_Object_ptr_ID);
72 const void* ptr = reinterpret_cast<const void*>(pointer_value);
73 assert(reinterpret_cast<jlong>(ptr) == pointer_value);
74 return marked(ptr);
75 }
76
77 inline void
set_coefficient(JNIEnv * env,jobject dst,jobject src)78 set_coefficient(JNIEnv* env, jobject dst, jobject src) {
79 jobject src_bi
80 = env->GetObjectField(src, cached_FMIDs.Coefficient_value_ID);
81 env->SetObjectField(dst, cached_FMIDs.Coefficient_value_ID, src_bi);
82 }
83
84 inline void
set_by_reference(JNIEnv * env,jobject by_ref_dst,jobject src)85 set_by_reference(JNIEnv* env, jobject by_ref_dst, jobject src) {
86 env->SetObjectField(by_ref_dst,
87 cached_FMIDs.By_Reference_obj_ID,
88 src);
89 }
90
91 inline jobject
get_by_reference(JNIEnv * env,jobject by_reference)92 get_by_reference(JNIEnv* env, jobject by_reference) {
93 return env->GetObjectField(by_reference, cached_FMIDs.By_Reference_obj_ID);
94 }
95
96 template <typename R>
97 jobject
build_linear_expression(JNIEnv * env,const R & r)98 build_linear_expression(JNIEnv* env, const R& r) {
99 jobject j_ret;
100 PPL_DIRTY_TEMP_COEFFICIENT(coefficient);
101 dimension_type varid = 0;
102 dimension_type space_dimension = r.space_dimension();
103 while (varid < space_dimension
104 && (coefficient = r.coefficient(Variable(varid))) == 0)
105 ++varid;
106 if (varid >= space_dimension) {
107 jobject j_coefficient_zero = build_java_coeff(env, Coefficient(0));
108 j_ret = env->NewObject(cached_classes.Linear_Expression_Coefficient,
109 cached_FMIDs.Linear_Expression_Coefficient_init_ID,
110 j_coefficient_zero);
111 CHECK_RESULT_THROW(env, j_ret);
112 }
113 else {
114 jmethodID coeff_var_init_ID
115 = cached_FMIDs.Linear_Expression_Times_init_from_coeff_var_ID;
116 jobject j_coefficient = build_java_coeff(env, coefficient);
117 jobject j_variable = build_java_variable(env, Variable(varid));
118 jclass j_le_times_class = cached_classes.Linear_Expression_Times;
119 jobject j_coeff_var = env->NewObject(j_le_times_class,
120 coeff_var_init_ID,
121 j_coefficient, j_variable);
122 CHECK_EXCEPTION_THROW(env);
123 j_ret = j_coeff_var;
124 while (true) {
125 ++varid;
126 while (varid < space_dimension
127 && (coefficient = r.coefficient(Variable(varid))) == 0)
128 ++varid;
129 if (varid >= space_dimension)
130 break;
131 else {
132 j_coefficient = build_java_coeff(env, coefficient);
133 j_variable = build_java_variable(env, Variable(varid));
134 j_coeff_var = env->NewObject(j_le_times_class,
135 coeff_var_init_ID,
136 j_coefficient, j_variable);
137 CHECK_EXCEPTION_THROW(env);
138 j_ret = env->CallObjectMethod(j_ret,
139 cached_FMIDs.Linear_Expression_sum_ID,
140 j_coeff_var);
141 CHECK_EXCEPTION_THROW(env);
142 }
143 }
144 }
145 return j_ret;
146 }
147
148 inline Variable
build_cxx_variable(JNIEnv * env,jobject j_var)149 build_cxx_variable(JNIEnv* env, jobject j_var) {
150 return Variable(env->GetIntField(j_var, cached_FMIDs.Variable_varid_ID));
151 }
152
153 inline jobject
build_java_variable(JNIEnv * env,const Variable var)154 build_java_variable(JNIEnv* env, const Variable var) {
155 jlong j_var_id = var.id();
156 jobject ret = env->NewObject(cached_classes.Variable,
157 cached_FMIDs.Variable_init_ID,
158 j_var_id);
159 CHECK_RESULT_THROW(env, ret);
160 return ret;
161 }
162
163 inline Coefficient
build_cxx_coeff(JNIEnv * env,jobject j_coeff)164 build_cxx_coeff(JNIEnv* env, jobject j_coeff) {
165 jstring bi_string
166 = (jstring) env->CallObjectMethod(j_coeff,
167 cached_FMIDs.Coefficient_toString_ID);
168 CHECK_EXCEPTION_THROW(env);
169 const char *nativeString = env->GetStringUTFChars(bi_string, 0);
170 CHECK_RESULT_THROW(env, nativeString);
171 PPL_DIRTY_TEMP_COEFFICIENT(ppl_coeff);
172 ppl_coeff = Coefficient(nativeString);
173 env->ReleaseStringUTFChars(bi_string, nativeString);
174 return ppl_coeff;
175 }
176
177 inline jobject
build_java_coeff(JNIEnv * env,const Coefficient & ppl_coeff)178 build_java_coeff(JNIEnv* env, const Coefficient& ppl_coeff) {
179 std::ostringstream s;
180 s << ppl_coeff;
181 std::string str = s.str();
182 jstring coeff_string = env->NewStringUTF(str.c_str());
183 CHECK_RESULT_THROW(env, coeff_string);
184 jobject ret = env->NewObject(cached_classes.Coefficient,
185 cached_FMIDs.Coefficient_init_from_String_ID,
186 coeff_string);
187 CHECK_RESULT_THROW(env, ret);
188 return ret;
189 }
190
191 template <typename System, typename Elem_Builder>
192 System
193 build_cxx_system(JNIEnv* env, jobject j_iterable, Elem_Builder build_cxx_elem) {
194 // Get the iterator.
195 jobject j_iter
196 = env->CallObjectMethod(j_iterable, cached_FMIDs.System_iterator_ID);
197 CHECK_EXCEPTION_THROW(env);
198 // Get the iterator method IDs.
199 jmethodID has_next_mID = cached_FMIDs.System_Iterator_has_next_ID;
200 jmethodID next_mID = cached_FMIDs.System_Iterator_next_ID;
201 // Initialize an empty system.
202 System cxx_sys;
203 jobject j_element;
204 jboolean has_next_value = env->CallBooleanMethod(j_iter, has_next_mID);
205 CHECK_EXCEPTION_ASSERT(env);
206 while (has_next_value) {
207 j_element = env->CallObjectMethod(j_iter, next_mID);
208 CHECK_EXCEPTION_ASSERT(env);
209 cxx_sys.insert(build_cxx_elem(env, j_element));
210 has_next_value = env->CallBooleanMethod(j_iter, has_next_mID);
211 CHECK_EXCEPTION_ASSERT(env);
212 }
213 return cxx_sys;
214 }
215
216 inline Congruence_System
build_cxx_congruence_system(JNIEnv * env,jobject j_iterable)217 build_cxx_congruence_system(JNIEnv* env, jobject j_iterable) {
218 return
219 build_cxx_system<Congruence_System>(env, j_iterable, build_cxx_congruence);
220 }
221
222 inline Constraint_System
build_cxx_constraint_system(JNIEnv * env,jobject j_iterable)223 build_cxx_constraint_system(JNIEnv* env, jobject j_iterable) {
224 return
225 build_cxx_system<Constraint_System>(env, j_iterable, build_cxx_constraint);
226 }
227
228 inline Generator_System
build_cxx_generator_system(JNIEnv * env,jobject j_iterable)229 build_cxx_generator_system(JNIEnv* env, jobject j_iterable) {
230 return
231 build_cxx_system<Generator_System>(env, j_iterable, build_cxx_generator);
232 }
233
234 inline Grid_Generator_System
build_cxx_grid_generator_system(JNIEnv * env,jobject j_iterable)235 build_cxx_grid_generator_system(JNIEnv* env, jobject j_iterable) {
236 return build_cxx_system<Grid_Generator_System> (env, j_iterable,
237 build_cxx_grid_generator);
238 }
239
240 } // namespace Java
241
242 } // namespace Interfaces
243
244 } // namespace Parma_Polyhedra_Library
245
246 #endif // !defined(PPL_ppl_java_common_inlines_hh)
247