API documentation  2.0rc1
client.h
1 /****************************************************************
2  *
3  * Copyright (C) 2012-2015 Alessandro Pignotti <alessandro@leaningtech.com>
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18  *
19  ***************************************************************/
20 
21 #ifndef _CHEERP_CLIENT_a335cd00
22 #define _CHEERP_CLIENT_a335cd00
23 
24 #include "cheerp/types.h"
25 #include "cheerp/clientlib.h"
26 #include <cheerpintrin.h>
27 
28 #include <utility>
29 #include <functional>
30 #include <vector>
31 
32 namespace [[cheerp::genericjs]] cheerp
33 {
34 
35 template<typename... Args>
36 void console_log(const char* message, Args&&... optionalParams)
37 {
38  client::console.log(message, static_cast<Args&&>(optionalParams)...);
39 }
40 
41 static void console_log(int message)
42 {
43  client::console.log(message);
44 }
45 
46 static void console_log(double message)
47 {
48  client::console.log(message);
49 }
50 
51 static double date_now()
52 {
53  return client::Date::now();
54 }
55 
56 template<class, class> struct CallbackHelper; // undefined
57 
58 template<class T, bool B, class R, class... Args> struct CallbackHelperBase;
59 
60 template<class R>
62 {
63  template<class T, class... Args>
64  static R invoke(T* func, Args... args)
65  {
66  auto ret = (*func)(static_cast<Args&&>(args)...);
67  delete func;
68  return ret;
69  }
70 };
71 
72 template<>
73 struct InvokeHelper<void>
74 {
75  template<class T, class... Args>
76  static void invoke(T* func, Args... args)
77  {
78  (*func)(static_cast<Args&&>(args)...);
79  delete func;
80  }
81 };
82 
83 template<class T, class R, class... Args>
84 struct CallbackHelperBase<T, false, R, Args...>
85 {
86  typedef R (func_type)(Args...);
87  static client::EventListener* make_callback(const T& func)
88  {
89  return __builtin_cheerp_create_closure<client::EventListener>(&InvokeHelper<R>::template invoke<T, Args...>,
90  new T(func));
91  }
92 };
93 
94 template<class T, class R, class... Args>
95 struct CallbackHelperBase<T, true, R, Args...>
96 {
97  typedef R (func_type)(Args...);
98  static client::EventListener* make_callback(const T& func)
99  {
100  return __builtin_cheerp_make_complete_object<client::EventListener>((func_type*)func);
101  }
102 };
103 
104 template<class T, class C, class R, class... Args>
105 struct CallbackHelper<T, R(C::*)(Args...) const>:
106  public CallbackHelperBase<T, std::is_convertible<T, R(*)(Args...)>::value, R, Args...>
107 {
108 };
109 
110 template<class T, class C, class R, class... Args>
111 struct CallbackHelper<T, R(C::*)(Args...)>:
112  public CallbackHelperBase<T, std::is_convertible<T, R(*)(Args...)>::value, R, Args...>
113 {
114 };
115 
121 template<class T>
123 {
124  typedef decltype(&T::operator()) lambda_type;
125  typedef CallbackHelper<T, lambda_type> callback_helper;
126  return callback_helper::make_callback(func);
127 }
128 
133 template<class R, class... Args>
134 client::EventListener* Callback(R (*func)(Args...))
135 {
136  return __builtin_cheerp_make_complete_object<client::EventListener>(func);
137 }
138 
139 template<typename T>
141 
142 template<>
143 struct TypedArrayForPointerType<unsigned char>
144 {
146 };
147 
148 template<>
149 struct TypedArrayForPointerType<signed char>
150 {
152 };
153 
154 template<>
155 struct TypedArrayForPointerType<unsigned short>
156 {
158 };
159 
160 template<>
161 struct TypedArrayForPointerType<signed short>
162 {
164 };
165 
166 template<>
167 struct TypedArrayForPointerType<unsigned int>
168 {
170 };
171 
172 template<>
173 struct TypedArrayForPointerType<signed int>
174 {
176 };
177 
178 template<>
180 {
182 };
183 
184 template<>
186 {
188 };
189 
190 template<typename P,typename T=typename TypedArrayForPointerType<P>::type>
191 T* MakeTypedArray(const P* ptr, size_t size=0)
192 {
193  size_t offset=__builtin_cheerp_pointer_offset(ptr);
194  T* buf=__builtin_cheerp_make_complete_object<T>(__builtin_cheerp_pointer_base<T>(ptr));
195  size_t elementSize=sizeof(P);
196  if(size==0)
197  return offset==0 ? buf : buf->subarray(offset);
198  else
199  return offset==0 && buf->get_length()==size/elementSize ? buf : buf->subarray(offset, offset+size/elementSize);
200 }
201 
202 template<typename T>
203 T* MakeTypedArray(const void* ptr, size_t size=0)
204 {
205  size_t offset=__builtin_cheerp_pointer_offset(ptr);
206  //We use Int8Array to access BYTES_PER_ELEMENT
207  client::Int8Array* buf=__builtin_cheerp_make_complete_object<client::Int8Array>(__builtin_cheerp_pointer_base<client::Int8Array>(ptr));
208  size_t elementSize=buf->get_BYTES_PER_ELEMENT();
209  if(size==0)
210  return new T(buf->get_buffer(), offset*elementSize);
211  else
212  {
213  size_t newElementSize = sizeof((*((T*)nullptr))[0]);
214  return new T(buf->get_buffer(), offset*elementSize, size/newElementSize);
215  }
216 }
217 
218 inline client::ArrayBufferView* MakeArrayBufferView(const void* ptr, size_t size=0)
219 {
220  size_t offset=__builtin_cheerp_pointer_offset(ptr);
221  //We use Int8Array to access BYTES_PER_ELEMENT
222  client::Int8Array* buf=__builtin_cheerp_make_complete_object<client::Int8Array>(__builtin_cheerp_pointer_base<client::Int8Array>(ptr));
223  size_t elementSize=buf->get_BYTES_PER_ELEMENT();
224  if(size==0)
225  return offset==0 ? buf : buf->subarray(offset);
226  else
227  return offset==0 && buf->get_length()==size/elementSize ? buf : buf->subarray(offset, offset+size/elementSize);
228 }
229 
230 // Helper class to access the [] operator on JS array-like objects
231 template<class T>
232 class ArrayRef
233 {
234 private:
235  T* obj;
236 public:
237  ArrayRef(T* o):obj(o)
238  {
239  }
241  {
242  return obj;
243  }
244  const T* operator->() const
245  {
246  return obj;
247  }
248  decltype((*obj)[0]) operator[](int index)
249  {
250  return (*obj)[index];
251  }
252  decltype((*static_cast<const T*>(obj))[0]) operator[](int index) const
253  {
254  return (*obj)[index];
255  }
256 };
257 
258 template<class T>
260 {
261  return ArrayRef<T>(obj);
262 }
263 
264 } //End of namespace cheerp
265 
266 #define CHEERP_SAFE_INLINE(r, p, x, ...) ({ struct [[cheerp::genericjs]] CheerpTmp { static r Run p { x; } }; CheerpTmp::Run(__VA_ARGS__); })
267 
268 // Begin CHEERP_OBJECT macro
269 // Make a FOREACH macro
270 #define _CHEERP_ITER_0(WHAT, X)
271 #define _CHEERP_ITER_1(WHAT, X) WHAT(X)
272 #define _CHEERP_ITER_2(WHAT, X, ...) WHAT(X), _CHEERP_ITER_1(WHAT, __VA_ARGS__)
273 #define _CHEERP_ITER_3(WHAT, X, ...) WHAT(X), _CHEERP_ITER_2(WHAT, __VA_ARGS__)
274 #define _CHEERP_ITER_4(WHAT, X, ...) WHAT(X), _CHEERP_ITER_3(WHAT, __VA_ARGS__)
275 #define _CHEERP_ITER_5(WHAT, X, ...) WHAT(X), _CHEERP_ITER_4(WHAT, __VA_ARGS__)
276 #define _CHEERP_ITER_6(WHAT, X, ...) WHAT(X), _CHEERP_ITER_5(WHAT, __VA_ARGS__)
277 #define _CHEERP_ITER_7(WHAT, X, ...) WHAT(X), _CHEERP_ITER_6(WHAT, __VA_ARGS__)
278 #define _CHEERP_ITER_8(WHAT, X, ...) WHAT(X), _CHEERP_ITER_7(WHAT, __VA_ARGS__)
279 #define _CHEERP_ITER_9(WHAT, X, ...) WHAT(X), _CHEERP_ITER_8(WHAT, __VA_ARGS__)
280 #define _CHEERP_ITER_10(WHAT, X, ...) WHAT(X), _CHEERP_ITER_9(WHAT, __VA_ARGS__)
281 #define _CHEERP_ITER_11(WHAT, X, ...) WHAT(X), _CHEERP_ITER_10(WHAT, __VA_ARGS__)
282 #define _CHEERP_ITER_12(WHAT, X, ...) WHAT(X), _CHEERP_ITER_11(WHAT, __VA_ARGS__)
283 #define _CHEERP_ITER_13(WHAT, X, ...) WHAT(X), _CHEERP_ITER_12(WHAT, __VA_ARGS__)
284 #define _CHEERP_ITER_14(WHAT, X, ...) WHAT(X), _CHEERP_ITER_13(WHAT, __VA_ARGS__)
285 #define _CHEERP_ITER_15(WHAT, X, ...) WHAT(X), _CHEERP_ITER_14(WHAT, __VA_ARGS__)
286 #define _CHEERP_ITER_16(WHAT, X, ...) WHAT(X), _CHEERP_ITER_15(WHAT, __VA_ARGS__)
287 //... repeat as needed
288 
289 #define _CHEERP_GET_MACRO(_0 \
290  ,_1 \
291  ,_2 \
292  ,_3 \
293  ,_4 \
294  ,_5 \
295  ,_6 \
296  ,_7 \
297  ,_8 \
298  ,_9 \
299  ,_10 \
300  ,_11 \
301  ,_12 \
302  ,_13 \
303  ,_14 \
304  ,_15 \
305  ,_16 \
306  ,NAME,...) NAME
307 #define _CHEERP_FOR_EACH(action,...) \
308  _CHEERP_GET_MACRO(_0, ##__VA_ARGS__ \
309  ,_CHEERP_ITER_16 \
310  ,_CHEERP_ITER_15 \
311  ,_CHEERP_ITER_14 \
312  ,_CHEERP_ITER_13 \
313  ,_CHEERP_ITER_12 \
314  ,_CHEERP_ITER_11 \
315  ,_CHEERP_ITER_10 \
316  ,_CHEERP_ITER_9 \
317  ,_CHEERP_ITER_8 \
318  ,_CHEERP_ITER_7 \
319  ,_CHEERP_ITER_6 \
320  ,_CHEERP_ITER_5 \
321  ,_CHEERP_ITER_4 \
322  ,_CHEERP_ITER_3 \
323  ,_CHEERP_ITER_2 \
324  ,_CHEERP_ITER_1 \
325  ,_CHEERP_ITER_0 \
326  )(action,__VA_ARGS__)
327 
328 
329 #define _CHEERP_STRING_VALUE(...) _CHEERP_STRING_VALUE__(__VA_ARGS__)
330 #define _CHEERP_STRING_VALUE__(...) #__VA_ARGS__
331 
332 #define _CHEERP_FIELD(x) x :%[_## x ##_]
333 #define _CHEERP_REG(x) [_## x ##_]"r"(x)
334 #define CHEERP_OBJECT(...) ({client::Object* r;__asm__("{" _CHEERP_STRING_VALUE(_CHEERP_FOR_EACH(_CHEERP_FIELD, __VA_ARGS__)) "}" : "=r"(r) : _CHEERP_FOR_EACH(_CHEERP_REG, __VA_ARGS__));r;})
335 // End CHEERP_OBJECT macro
336 
337 #endif
Definition: client.h:232
Definition: clientlib.h:1656
client::Int32Array type
Definition: client.h:175
Definition: clientlib.h:1790
client::Float64Array type
Definition: client.h:187
static client::EventListener * make_callback(const T &func)
Definition: client.h:87
T * operator->()
Definition: client.h:240
Definition: clientlib.h:1522
Definition: client.h:140
decltype((*obj) operator[][0])(int index)
Definition: client.h:248
ArrayRef< T > makeArrayRef(T *obj)
Definition: client.h:259
Definition: clientlib.h:1407
client::Uint8Array type
Definition: client.h:145
Int8Array * subarray(double begin)
client::Uint32Array type
Definition: client.h:169
Definition: clientlib.h:1455
Definition: clientlib.h:1723
Definition: clientlib.h:4724
client::Float32Array type
Definition: client.h:181
Definition: client.h:56
const T * operator->() const
Definition: client.h:244
Console console
ArrayRef(T *o)
Definition: client.h:237
client::ArrayBufferView * MakeArrayBufferView(const void *ptr, size_t size=0)
Definition: client.h:218
T * MakeTypedArray(const P *ptr, size_t size=0)
Definition: client.h:191
static R invoke(T *func, Args... args)
Definition: client.h:64
Definition: clientlib.h:1991
static client::EventListener * make_callback(const T &func)
Definition: client.h:98
void console_log(const char *message, Args &&... optionalParams)
Definition: client.h:36
Definition: client.h:58
client::Uint16Array type
Definition: client.h:157
ArrayBuffer * get_buffer()
double get_BYTES_PER_ELEMENT()
decltype((*static_cast< const T * >(obj)) operator[][0])(int index) const
Definition: client.h:252
Definition: clientlib.h:1924
client::EventListener * Callback(const T &func)
Definition: client.h:122
static void invoke(T *func, Args... args)
Definition: client.h:76
Definition: client.h:61
client::Int16Array type
Definition: client.h:163
Definition: clientlib.h:1857
client::Int8Array type
Definition: client.h:151
Definition: client.h:32