1 /*
2 *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 *  Copyright (C) 2008-2008 - DIGITEO - Antoine ELIAS
4 *  Copyright (C) 2010-2010 - DIGITEO - Bruno JOFRET
5 *
6  * Copyright (C) 2012 - 2016 - Scilab Enterprises
7  *
8  * This file is hereby licensed under the terms of the GNU GPL v2.0,
9  * pursuant to article 5.3.4 of the CeCILL v.2.1.
10  * This file was originally licensed under the terms of the CeCILL v2.1,
11  * and continues to be available under such terms.
12  * For more information, see the COPYING file which you should have received
13  * along with this program.
14 *
15 */
16 
17 
18 #ifndef __INTERNAL_HXX__
19 #define __INTERNAL_HXX__
20 
21 #include <vector>
22 #include <unordered_map>
23 #include <iostream>
24 #include <algorithm>
25 #include <string>
26 
27 extern "C"
28 {
29 #include "dynlib_ast.h"
30 #include "configvariable_interface.h"
31 }
32 
33 #include "scilabexception.hxx"
34 #include "localization.hxx"
35 #ifndef NDEBUG
36 #include "inspector.hxx"
37 #endif
38 
39 #define bsiz 4096
40 
41 //#define _SCILAB_DEBUGREF_
42 #ifdef _SCILAB_DEBUGREF_
43 //#define _SCILAB_DEBUGREF_WITHOUT_START_END
44 #define DecreaseRef() _decreaseref(__FILE__, __LINE__)
45 #define IncreaseRef() _increaseref(__FILE__, __LINE__)
46 #define killMe() _killme(__FILE__, __LINE__)
47 #endif
48 
49 #include "visitor.hxx"
50 
51 class Location;
52 
53 namespace types
54 {
55 
56 /*
57 ** List of types
58 */
59 class InternalType;
60 typedef std::vector<InternalType *> typed_list;
61 typedef std::unordered_map<std::wstring, InternalType *> optional_list;
62 
63 class EXTERN_AST InternalType
64 {
65 public :
66     enum ScilabType
67     {
68         ScilabNull = 0, //no type, no data, nothing !
69         /* Internal Type */
70         ScilabInternal,
71         /* Generic Types */
72         ScilabGeneric,
73         ScilabInt8,
74         ScilabUInt8,
75         ScilabInt16,
76         ScilabUInt16,
77         ScilabInt32,
78         ScilabUInt32,
79         ScilabInt64,
80         ScilabUInt64,
81         ScilabString,
82         ScilabDouble,
83         ScilabBool,
84         ScilabFloat,
85         ScilabPolynom,
86         ScilabSinglePolynom,
87         /* Callable */
88         ScilabFunction,
89         ScilabMacro,
90         ScilabMacroFile,
91         /* Implicit List */
92         ScilabImplicitList,
93         /* Container */
94         ScilabContainer,
95         ScilabList,
96         ScilabTList,
97         ScilabMList,
98         ScilabSingleStruct,
99         ScilabStruct,
100         ScilabCell,
101         /* User */
102         ScilabUserType,
103         /*For list operation*/
104         ScilabListOperation, //parent type
105         ScilabListInsertOperation,
106         ScilabListDeleteOperation,
107         ScilabListUndefinedOperation,
108         ScilabFile,
109         ScilabColon,
110         ScilabThreadId,
111         ScilabSparse,
112         ScilabSparseBool,
113         ScilabHandle,
114         ScilabVoid,
115         ScilabLibrary
116     };
117 
118     enum ScilabId
119     {
120         IdNull, //no type, no data, nothing !
121         /* Internal Type */
122         IdInternal,
123         /* Generic Types */
124         IdGeneric,
125         IdEmpty,
126         IdIdentity,
127         IdIdentityComplex,
128         IdInt8,
129         IdScalarInt8,
130         IdUInt8,
131         IdScalarUInt8,
132         IdInt16,
133         IdScalarInt16,
134         IdUInt16,
135         IdScalarUInt16,
136         IdInt32,
137         IdScalarInt32,
138         IdUInt32,
139         IdScalarUInt32,
140         IdInt64,
141         IdScalarInt64,
142         IdUInt64,
143         IdScalarUInt64,
144         IdString,
145         IdScalarString,
146         IdDouble,
147         IdDoubleComplex,
148         IdScalarDouble,
149         IdScalarDoubleComplex,
150         IdBool,
151         IdScalarBool,
152         IdPolynom,
153         IdScalarPolynomComplex,
154         IdScalarPolynom,
155         IdPolynomComplex,
156         IdSinglePolynom,
157         /* Callable */
158         IdFunction,
159         IdMacro,
160         IdMacroFile,
161         /* Implicit List */
162         IdImplicitList,
163         /* Container */
164         IdContainer,
165         IdList,
166         IdTList,
167         IdMList,
168         IdSingleStruct,
169         IdStruct,
170         IdCell,
171         /* User */
172         IdUserType,
173         /*For list operation*/
174         IdListOperation, //parent type
175         IdListInsertOperation,
176         IdListDeleteOperation,
177         IdListUndefinedOperation,
178         IdFile,
179         IdColon,
180         IdThreadId,
181         IdSparse,
182         IdSparseComplex,
183         IdSparseBool,
184         IdHandle,
185         IdScalarHandle,
186         IdVoid,
187         IdLibrary,
188         IdLast //msut always be the last value
189     };
190 
191 protected :
InternalType()192     InternalType() : m_iRef(0), m_bAllowDelete(true), m_bPrintFromStart(true), m_iSavePrintState(0), m_iRows1PrintState(0), m_iCols1PrintState(0), m_iRows2PrintState(0), m_iCols2PrintState(0), bKillMe(false)
193     {
194 #ifdef _SCILAB_DEBUGREF_
195 #if defined(_SCILAB_DEBUGREF_WITHOUT_START_END)
196         if (getStartProcessing() == 0 && getEndProcessing() == 0)
197 #endif
198         {
199             std::cout << "new_IT " << m_iRef << " " << (void*)this << std::endl;
200         }
201 #endif
202     }
203 
204 public :
205 
~InternalType()206     virtual                         ~InternalType()
207     {
208 #ifdef _SCILAB_DEBUGREF_
209 #if defined(_SCILAB_DEBUGREF_WITHOUT_START_END)
210         if (getStartProcessing() == 0 && getEndProcessing() == 0 && bKillMe == false)
211 #endif
212         {
213             std::cout << "delete_IT " << m_iRef << " " << (void*)this << std::endl;
214         }
215 #endif
216     }
217 
218     virtual void                    whoAmI(void);
219     virtual bool                    isAssignable(void);
220     virtual ScilabType              getType(void) = 0 ; //{ return ScilabInternal; }
221     virtual ScilabId                getId(void) = 0 ; //{ return ScilabInternal; }
222     virtual bool                    hasToString();
223     virtual bool                    toString(std::wostringstream& ostr) = 0;
224     virtual std::wstring            toStringInLine();
225     virtual InternalType*           clone(void) = 0;
226     virtual ast::Exp*               getExp(const Location& /*loc*/);
227 
228     template <typename T, typename F, typename ... A>
229     T* checkRef(T* _pIT, F f, A ... a)
230     {
231         if (getRef() > 1)
232         {
233             // A types:: content in more than one Scilab variable
234             // must be cloned before being modified.
235             T* pClone = _pIT->clone()->template getAs<T>();
236             T* pIT = NULL;
237             try
238             {
239                 pIT = (pClone->*f)(a...);
240             }
241             catch (const ast::InternalError& ie)
242             {
243                 pClone->killMe();
244                 throw ie;
245             }
246 
247             if (pIT == NULL)
248             {
249                 pClone->killMe();
250             }
251 
252             return pIT;
253         }
254 
255         return _pIT;
256     }
257 
258 
259 
260 #ifdef _SCILAB_DEBUGREF_
_killme(const char * f,int l)261     inline void _killme(const char * f, int l)
262     {
263 #if defined(_SCILAB_DEBUGREF_WITHOUT_START_END)
264         if (getStartProcessing() == 0 && getEndProcessing() == 0)
265 #endif
266         {
267             std::cout << "killme " << m_iRef << " " << (void*)this << " in " << f << " at line " << l << std::endl;
268         }
269 
270         if (isDeletable())
271         {
272             bKillMe = true;
273             delete this;
274         }
275     }
276 
_increaseref(const char * f,int l)277     inline void _increaseref(const char * f, int l)
278     {
279         m_iRef++;
280 #if defined(_SCILAB_DEBUGREF_WITHOUT_START_END)
281         if (getStartProcessing() == 0 && getEndProcessing() == 0)
282 #endif
283         {
284             std::cout << "incref " << m_iRef << " " << (void*)this << " in " << f << " at line " << l << std::endl;
285         }
286     }
287 
_decreaseref(const char * f,int l)288     inline void _decreaseref(const char * f, int l)
289     {
290         if (m_iRef > 0)
291         {
292             m_iRef--;
293         }
294 
295 #if defined(_SCILAB_DEBUGREF_WITHOUT_START_END)
296         if (getStartProcessing() == 0 && getEndProcessing() == 0)
297 #endif
298         {
299             std::cout << "decref " << m_iRef << " " << (void*)this << " in " << f << " at line " << l << std::endl;
300         }
301     }
302 #else
303 
killMe()304     inline void killMe()
305     {
306         if (isDeletable())
307         {
308             delete this;
309         }
310     }
311 
IncreaseRef()312     inline void IncreaseRef()
313     {
314         m_iRef++;
315     }
316 
DecreaseRef()317     inline void DecreaseRef()
318     {
319         if (m_iRef > 0)
320         {
321             m_iRef--;
322         }
323     }
324 #endif
325 
isDeletable()326     inline bool isDeletable()
327     {
328         return m_iRef == 0;
329     }
330 
isRef(int _iRef=0)331     inline bool isRef(int _iRef = 0)
332     {
333         return m_iRef > _iRef;
334     }
335 
getRef() const336     inline int getRef() const
337     {
338         return m_iRef;
339     }
340 
341     virtual bool isTrue();
342     virtual bool neg(InternalType *& /*out*/);
343     virtual bool transpose(InternalType *& /*out*/);
344     virtual bool adjoint(InternalType *& out);
345     virtual bool isFieldExtractionOverloadable() const;
346     virtual bool invoke(typed_list & /*in*/, optional_list & /*opt*/, int /*_iRetCount*/, typed_list & /*out*/, const ast::Exp & /*e*/);
347     virtual bool isInvokable() const;
348     virtual bool hasInvokeOption() const;
349     virtual int getInvokeNbIn();
350     virtual int getInvokeNbOut();
351 
getMemory(long long * _piSize,long long * _piSizePlusType)352     virtual bool getMemory(long long* _piSize, long long* _piSizePlusType)
353     {
354         *_piSize = 0;
355         *_piSizePlusType = 0;
356         return false;
357     }
358 
359     /* return type as string ( double, int, cell, list, ... )*/
360     virtual std::wstring            getTypeStr() const = 0;
361     /* return type as short string ( s, i, ce, l, ... )*/
362     virtual std::wstring            getShortTypeStr() const = 0;
363     virtual bool                    operator==(const InternalType& it);
364     virtual bool                    operator!=(const InternalType& it);
365 
366     /**
367     ** GenericType
368     ** \{
369     */
370 
371     template <class T>
getAs(void)372     inline T*                              getAs(void)
373     {
374         return static_cast<T*>(this);
375     }
376 
377     virtual bool isGenericType(void);
378     virtual bool isArrayOf(void);
379     virtual bool isString(void);
380     virtual bool isDouble(void);
381     virtual bool isSparse(void);
382     virtual bool isSparseBool(void);
383     virtual bool isFloat(void);
384     virtual bool isInt(void);
385     virtual bool isInt8(void);
386     virtual bool isUInt8(void);
387     virtual bool isInt16(void);
388     virtual bool isUInt16(void);
389     virtual bool isInt32(void);
390     virtual bool isUInt32(void);
391     virtual bool isInt64(void);
392     virtual bool isUInt64(void);
393     virtual bool isBool(void);
394     virtual bool isPoly(void);
395     virtual bool isSinglePoly(void);
396     virtual bool isCallable(void);
397     virtual bool isFunction(void);
398     virtual bool isMacro(void);
399     virtual bool isMacroFile(void);
400     virtual bool isContainer(void);
401     virtual bool isList(void);
402     virtual bool isStruct(void);
403     virtual bool isSingleStruct(void);
404     virtual bool isCell(void);
405     virtual bool isTList(void);
406     virtual bool isMList(void);
407     virtual bool isImplicitList(void);
408     virtual bool isColon(void);
409     virtual bool isDollar(void);
410     virtual bool isFile(void);
411     virtual bool isHandle(void);
412     virtual bool isSingleHandle(void);
413     virtual bool isThreadId(void);
414     virtual bool isListOperation(void);
415     virtual bool isListDelete(void);
416     virtual bool isListInsert(void);
417     virtual bool isPointer(void);
418     virtual bool isLibrary(void);
419     virtual bool isUserType(void);
420     virtual bool isVoid(void);
421 
422     void clearPrintState();
423 
424 protected :
425     int          m_iRef;
426     //use to know if we can delete this variables or if it's link to a scilab variable.
427     bool         m_bAllowDelete;
428 
429     /*variables to manage print taking care of lines*/
430     bool m_bPrintFromStart;
431     int  m_iSavePrintState;
432     int  m_iRows1PrintState;
433     int  m_iCols1PrintState;
434     int  m_iRows2PrintState;
435     int  m_iCols2PrintState;
436 
437     bool bKillMe;
438 
439 };
440 
441 }
442 
443 #ifdef _SCILAB_DEBUGREF_
444 #undef _SCILAB_DEBUGREF_
445 #endif
446 
447 #endif /* !__INTERNAL_HXX__ */
448