b9490df9b531add6db44be52138dae2078ca6d8d
[public/netxms.git] / include / nxsl_classes.h
1 /*
2 ** NetXMS - Network Management System
3 ** Copyright (C) 2005, 2006 Victor Kirhenshtein
4 **
5 ** This program is free software; you can redistribute it and/or modify
6 ** it under the terms of the GNU General Public License as published by
7 ** the Free Software Foundation; either version 2 of the License, or
8 ** (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., 675 Mass Ave, Cambridge, MA 02139, USA.
18 **
19 ** $module: nxsl_classes.h
20 **
21 **/
22
23 #ifndef _nxsl_classes_h_
24 #define _nxsl_classes_h_
25
26 #include <nms_threads.h>
27 #include <nms_util.h>
28 #include <nxcpapi.h>
29
30
31 //
32 // Constants
33 //
34
35 #define MAX_CLASS_NAME 64
36
37
38 //
39 // Data types
40 //
41
42 #define NXSL_DT_NULL 0
43 #define NXSL_DT_OBJECT 1
44 #define NXSL_DT_ARRAY 2
45 #define NXSL_DT_STRING 3
46 #define NXSL_DT_REAL 4
47 #define NXSL_DT_INT32 5
48 #define NXSL_DT_INT64 6
49 #define NXSL_DT_UINT32 7
50 #define NXSL_DT_UINT64 8
51
52
53 //
54 // Simple stack class
55 //
56
57 class LIBNXSL_EXPORTABLE NXSL_Stack
58 {
59 private:
60 int m_nStackSize;
61 int m_nStackPos;
62 void **m_ppData;
63
64 public:
65 NXSL_Stack(void);
66 ~NXSL_Stack();
67
68 void Push(void *pData);
69 void *Pop(void);
70 void *Peek(void);
71 void **PeekList(int nLevel) { return &m_ppData[m_nStackPos - nLevel]; }
72
73 int Size(void) { return m_nStackPos; }
74 };
75
76
77 //
78 // Class representing NXSL class
79 //
80
81 class NXSL_Value;
82 class NXSL_Object;
83
84 class LIBNXSL_EXPORTABLE NXSL_Class
85 {
86 protected:
87 char m_szName[MAX_CLASS_NAME];
88
89 public:
90 NXSL_Class();
91 virtual ~NXSL_Class();
92
93 virtual NXSL_Value *GetAttr(NXSL_Object *pObject, char *pszAttr);
94 virtual BOOL SetAttr(NXSL_Object *pObject, char *pszAttr, NXSL_Value *pValue);
95
96 virtual void OnObjectDelete(NXSL_Object *object);
97
98 char *Name(void) { return m_szName; }
99 };
100
101
102 //
103 // Object instance
104 //
105
106 class LIBNXSL_EXPORTABLE NXSL_Object
107 {
108 private:
109 NXSL_Class *m_pClass;
110 void *m_pData;
111
112 public:
113 NXSL_Object(NXSL_Object *pObject);
114 NXSL_Object(NXSL_Class *pClass, void *pData);
115 ~NXSL_Object();
116
117 NXSL_Class *Class() { return m_pClass; }
118 void *Data() { return m_pData; }
119 };
120
121
122 //
123 // Array
124 //
125
126 class LIBNXSL_EXPORTABLE NXSL_Array
127 {
128 private:
129 int m_refCount;
130 NXSL_Value **m_data;
131
132 public:
133 NXSL_Array();
134 NXSL_Array(NXSL_Array *src);
135 ~NXSL_Array();
136
137 void IncRefCount() { m_refCount++; }
138 void DecRefCount() { m_refCount--; }
139 BOOL IsUnused() { return m_refCount < 1; }
140
141 void Set(int index, NXSL_Value *value);
142 NXSL_Value *Get(int index);
143 };
144
145
146 //
147 // Variable or constant value
148 //
149
150 class LIBNXSL_EXPORTABLE NXSL_Value
151 {
152 protected:
153 DWORD m_dwStrLen;
154 char *m_pszValStr;
155 BYTE m_nDataType;
156 BYTE m_bStringIsValid;
157 union
158 {
159 LONG nInt32;
160 DWORD uInt32;
161 INT64 nInt64;
162 QWORD uInt64;
163 double dReal;
164 NXSL_Object *pObject;
165 NXSL_Array *pArray;
166 } m_value;
167
168 void UpdateNumber(void);
169 void UpdateString(void);
170
171 void InvalidateString(void)
172 {
173 safe_free(m_pszValStr);
174 m_pszValStr = NULL;
175 m_bStringIsValid = FALSE;
176 }
177
178 public:
179 NXSL_Value(void);
180 NXSL_Value(const NXSL_Value *);
181 NXSL_Value(NXSL_Object *pObject);
182 NXSL_Value(NXSL_Array *pArray);
183 NXSL_Value(LONG nValue);
184 NXSL_Value(INT64 nValue);
185 NXSL_Value(DWORD uValue);
186 NXSL_Value(QWORD uValue);
187 NXSL_Value(double dValue);
188 NXSL_Value(const TCHAR *pszValue);
189 NXSL_Value(const TCHAR *pszValue, DWORD dwLen);
190 ~NXSL_Value();
191
192 void Set(LONG nValue);
193
194 BOOL Convert(int nDataType);
195 int DataType(void) { return m_nDataType; }
196
197 BOOL IsNull(void) { return (m_nDataType == NXSL_DT_NULL); }
198 BOOL IsObject(void) { return (m_nDataType == NXSL_DT_OBJECT); }
199 BOOL IsArray(void) { return (m_nDataType == NXSL_DT_ARRAY); }
200 BOOL IsString(void) { return (m_nDataType >= NXSL_DT_STRING); }
201 BOOL IsNumeric(void) { return (m_nDataType > NXSL_DT_STRING); }
202 BOOL IsReal(void) { return (m_nDataType == NXSL_DT_REAL); }
203 BOOL IsInteger(void) { return (m_nDataType > NXSL_DT_REAL); }
204 BOOL IsUnsigned(void) { return (m_nDataType >= NXSL_DT_UINT32); }
205 BOOL IsZero(void);
206 BOOL IsNonZero(void);
207
208 char *GetValueAsString(DWORD *pdwLen);
209 char *GetValueAsCString(void);
210 LONG GetValueAsInt32(void);
211 DWORD GetValueAsUInt32(void);
212 INT64 GetValueAsInt64(void);
213 QWORD GetValueAsUInt64(void);
214 double GetValueAsReal(void);
215 NXSL_Object *GetValueAsObject(void) { return (m_nDataType == NXSL_DT_OBJECT) ? m_value.pObject : NULL; }
216 NXSL_Array *GetValueAsArray(void) { return (m_nDataType == NXSL_DT_ARRAY) ? m_value.pArray : NULL; }
217
218 void Concatenate(char *pszString, DWORD dwLen);
219
220 void Increment(void);
221 void Decrement(void);
222 void Negate(void);
223 void BitNot(void);
224
225 void Add(NXSL_Value *pVal);
226 void Sub(NXSL_Value *pVal);
227 void Mul(NXSL_Value *pVal);
228 void Div(NXSL_Value *pVal);
229 void Rem(NXSL_Value *pVal);
230 void BitAnd(NXSL_Value *pVal);
231 void BitOr(NXSL_Value *pVal);
232 void BitXor(NXSL_Value *pVal);
233 void LShift(int nBits);
234 void RShift(int nBits);
235
236 BOOL EQ(NXSL_Value *pVal);
237 BOOL LT(NXSL_Value *pVal);
238 BOOL LE(NXSL_Value *pVal);
239 BOOL GT(NXSL_Value *pVal);
240 BOOL GE(NXSL_Value *pVal);
241 };
242
243
244 //
245 // Function structure
246 //
247
248 struct NXSL_Function
249 {
250 char m_szName[MAX_FUNCTION_NAME];
251 DWORD m_dwAddr;
252 };
253
254
255 //
256 // External function structure
257 //
258
259 struct NXSL_ExtFunction
260 {
261 char m_szName[MAX_FUNCTION_NAME];
262 int (* m_pfHandler)(int argc, NXSL_Value **argv, NXSL_Value **ppResult);
263 int m_iNumArgs; // Number of arguments or -1 fo variable number
264 };
265
266
267 //
268 // Environment for NXSL program
269 //
270
271 class NXSL_Program;
272 class NXSL_Library;
273
274 class LIBNXSL_EXPORTABLE NXSL_Environment
275 {
276 private:
277 DWORD m_dwNumFunctions;
278 NXSL_ExtFunction *m_pFunctionList;
279
280 NXSL_Library *m_pLibrary;
281
282 FILE *m_pStdIn;
283 FILE *m_pStdOut;
284
285 public:
286 NXSL_Environment();
287 ~NXSL_Environment();
288
289 void SetIO(FILE *pIn, FILE *pOut) { m_pStdIn = pIn; m_pStdOut = pOut; }
290 FILE *GetStdIn(void) { return m_pStdIn; }
291 FILE *GetStdOut(void) { return m_pStdOut; }
292
293 void SetLibrary(NXSL_Library *pLib) { m_pLibrary = pLib; }
294
295 NXSL_ExtFunction *FindFunction(char *pszName);
296 void RegisterFunctionSet(DWORD dwNumFunctions, NXSL_ExtFunction *pList);
297
298 BOOL UseModule(NXSL_Program *pMain, char *pszName);
299 };
300
301
302 //
303 // Runtime variable information
304 //
305
306 class LIBNXSL_EXPORTABLE NXSL_Variable
307 {
308 protected:
309 TCHAR *m_pszName;
310 NXSL_Value *m_pValue;
311
312 public:
313 NXSL_Variable(const TCHAR *pszName);
314 NXSL_Variable(const TCHAR *pszName, NXSL_Value *pValue);
315 NXSL_Variable(NXSL_Variable *pSrc);
316 ~NXSL_Variable();
317
318 const TCHAR *Name(void) { return m_pszName; }
319 NXSL_Value *Value(void) { return m_pValue; }
320 void Set(NXSL_Value *pValue);
321 };
322
323
324 //
325 // Varable system
326 //
327
328 class LIBNXSL_EXPORTABLE NXSL_VariableSystem
329 {
330 protected:
331 DWORD m_dwNumVariables;
332 NXSL_Variable **m_ppVariableList;
333
334 public:
335 NXSL_VariableSystem(void);
336 NXSL_VariableSystem(NXSL_VariableSystem *pSrc);
337 ~NXSL_VariableSystem();
338
339 NXSL_Variable *Find(const TCHAR *pszName);
340 NXSL_Variable *Create(const TCHAR *pszName, NXSL_Value *pValue = NULL);
341 };
342
343
344 //
345 // Single execution instruction
346 //
347
348 class LIBNXSL_EXPORTABLE NXSL_Instruction
349 {
350 friend class NXSL_Program;
351
352 protected:
353 int m_nOpCode;
354 union
355 {
356 NXSL_Value *m_pConstant;
357 char *m_pszString;
358 DWORD m_dwAddr;
359 } m_operand;
360 int m_nStackItems;
361 int m_nSourceLine;
362
363 public:
364 NXSL_Instruction(int nLine, int nOpCode);
365 NXSL_Instruction(int nLine, int nOpCode, NXSL_Value *pValue);
366 NXSL_Instruction(int nLine, int nOpCode, char *pszString);
367 NXSL_Instruction(int nLine, int nOpCode, char *pszString, int nStackItems);
368 NXSL_Instruction(int nLine, int nOpCode, DWORD dwAddr);
369 NXSL_Instruction(int nLine, int nOpCode, int nStackItems);
370 NXSL_Instruction(NXSL_Instruction *pSrc);
371 ~NXSL_Instruction();
372 };
373
374
375 //
376 // Used module information
377 //
378
379 struct NXSL_Module
380 {
381 char m_szName[MAX_PATH];
382 DWORD m_dwCodeStart;
383 DWORD m_dwCodeSize;
384 DWORD m_dwFunctionStart;
385 DWORD m_dwNumFunctions;
386 };
387
388
389 //
390 // Class representing compiled NXSL program
391 //
392
393 class LIBNXSL_EXPORTABLE NXSL_Program
394 {
395 protected:
396 NXSL_Environment *m_pEnv;
397
398 NXSL_Instruction **m_ppInstructionSet;
399 DWORD m_dwCodeSize;
400 DWORD m_dwCurrPos;
401
402 DWORD m_dwNumPreloads;
403 char **m_ppszPreloadList;
404
405 DWORD m_dwSubLevel;
406 NXSL_Stack *m_pDataStack;
407 NXSL_Stack *m_pCodeStack;
408 int m_nBindPos;
409
410 NXSL_VariableSystem *m_pConstants;
411 NXSL_VariableSystem *m_pGlobals;
412 NXSL_VariableSystem *m_pLocals;
413
414 DWORD m_dwNumFunctions;
415 NXSL_Function *m_pFunctionList;
416
417 DWORD m_dwNumModules;
418 NXSL_Module *m_pModuleList;
419
420 NXSL_Value *m_pRetValue;
421 int m_nErrorCode;
422 TCHAR *m_pszErrorText;
423
424 void Execute(void);
425 void CallFunction(int nArgCount);
426 void DoUnaryOperation(int nOpCode);
427 void DoBinaryOperation(int nOpCode);
428 void Error(int nError);
429 NXSL_Value *MatchRegexp(NXSL_Value *pValue, NXSL_Value *pRegexp, BOOL bIgnoreCase);
430
431 NXSL_Variable *FindOrCreateVariable(TCHAR *pszName);
432 NXSL_Variable *CreateVariable(TCHAR *pszName);
433
434 DWORD GetFunctionAddress(char *pszName);
435 void RelocateCode(DWORD dwStartOffset, DWORD dwLen, DWORD dwShift);
436 DWORD FinalJumpDestination(DWORD dwAddr);
437
438 public:
439 NXSL_Program(void);
440 ~NXSL_Program();
441
442 BOOL AddFunction(const char *pszName, DWORD dwAddr, char *pszError);
443 void ResolveFunctions(void);
444 void AddInstruction(NXSL_Instruction *pInstruction);
445 void ResolveLastJump(int nOpCode);
446 void CreateJumpAt(DWORD dwOpAddr, DWORD dwJumpAddr);
447 void AddPreload(char *pszName);
448 void UseModule(NXSL_Program *pModule, const char *pszName);
449 void Optimize(void);
450
451 void SetGlobalVariable(const TCHAR *pszName, NXSL_Value *pValue);
452 NXSL_Variable *FindGlobalVariable(const TCHAR *pszName) { return m_pGlobals->Find(pszName); }
453
454 int Run(NXSL_Environment *pEnv = NULL, DWORD argc = 0,
455 NXSL_Value **argv = NULL, NXSL_VariableSystem *pUserLocals = NULL,
456 NXSL_VariableSystem **ppGlobals = NULL);
457
458 DWORD CodeSize(void) { return m_dwCodeSize; }
459
460 void Dump(FILE *pFile);
461 TCHAR *GetErrorText(void) { return m_pszErrorText; }
462 NXSL_Value *GetResult(void) { return m_pRetValue; }
463 };
464
465
466 //
467 // Script library
468 //
469
470 class LIBNXSL_EXPORTABLE NXSL_Library
471 {
472 private:
473 DWORD m_dwNumScripts;
474 NXSL_Program **m_ppScriptList;
475 char **m_ppszNames;
476 DWORD *m_pdwIdList;
477 MUTEX m_mutex;
478
479 void Delete(int nIndex);
480
481 public:
482 NXSL_Library(void);
483 ~NXSL_Library();
484
485 void Lock(void) { MutexLock(m_mutex, INFINITE); }
486 void Unlock(void) { MutexUnlock(m_mutex); }
487
488 BOOL AddScript(DWORD dwId, char *pszName, NXSL_Program *pScript);
489 void DeleteScript(char *pszName);
490 void DeleteScript(DWORD dwId);
491 NXSL_Program *FindScript(char *pszName);
492
493 void FillMessage(CSCPMessage *pMsg);
494 };
495
496
497 #endif