Implemented Sensor class; Added LoRaWAN subagent
[public/netxms.git] / include / nxsl_classes.h
CommitLineData
b36dc6ff
VK
1/*
2** NetXMS - Network Management System
6b29839d 3** Copyright (C) 2003-2014 Victor Kirhenshtein
b36dc6ff
VK
4**
5** This program is free software; you can redistribute it and/or modify
65d2c384
VK
6** it under the terms of the GNU Lesser General Public License as published by
7** the Free Software Foundation; either version 3 of the License, or
b36dc6ff
VK
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**
65d2c384 15** You should have received a copy of the GNU Lesser General Public License
b36dc6ff
VK
16** along with this program; if not, write to the Free Software
17** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18**
ccc34207 19** File: nxsl_classes.h
b36dc6ff
VK
20**
21**/
22
23#ifndef _nxsl_classes_h_
24#define _nxsl_classes_h_
25
adbf1a29
VK
26#include <nms_threads.h>
27#include <nms_util.h>
9f2ad16c 28#include <nxcpapi.h>
bf9daa23 29#include <geolocation.h>
adbf1a29 30
b36dc6ff 31//
2c75fa6f
VK
32// Constants
33//
34
35#define MAX_CLASS_NAME 64
6b29839d 36#define INVALID_ADDRESS ((UINT32)0xFFFFFFFF)
2c75fa6f 37
6b29839d
VK
38/**
39 * NXSL data types
40 */
41enum NXSL_DataTypes
42{
43 NXSL_DT_NULL = 0,
44 NXSL_DT_OBJECT = 1,
45 NXSL_DT_ARRAY = 2,
46 NXSL_DT_ITERATOR = 3,
06f09671
VK
47 NXSL_DT_HASHMAP = 4,
48 NXSL_DT_STRING = 5,
49 NXSL_DT_REAL = 6,
50 NXSL_DT_INT32 = 7,
51 NXSL_DT_INT64 = 8,
52 NXSL_DT_UINT32 = 9,
53 NXSL_DT_UINT64 = 10
6b29839d 54};
b36dc6ff 55
49fbe41f
VK
56/**
57 * NXSL stack class
58 */
b36dc6ff
VK
59class LIBNXSL_EXPORTABLE NXSL_Stack
60{
61private:
62 int m_nStackSize;
63 int m_nStackPos;
64 void **m_ppData;
65
66public:
bb5365ed 67 NXSL_Stack();
b36dc6ff
VK
68 ~NXSL_Stack();
69
bb5365ed
VK
70 void push(void *pData);
71 void *pop();
72 void *peek();
7de1151b 73 void *peekAt(int offset);
bb5365ed 74 void **peekList(int nLevel) { return &m_ppData[m_nStackPos - nLevel]; }
b36dc6ff 75
bb5365ed 76 int getSize() { return m_nStackPos; }
b36dc6ff
VK
77};
78
2c75fa6f
VK
79class NXSL_Value;
80class NXSL_Object;
6b29839d 81class NXSL_VM;
2c75fa6f 82
49fbe41f 83/**
55bdca5a
VK
84 * External method structure
85 */
86struct NXSL_ExtMethod
87{
6b29839d 88 int (* handler)(NXSL_Object *object, int argc, NXSL_Value **argv, NXSL_Value **result, NXSL_VM *vm);
55bdca5a
VK
89 int numArgs; // Number of arguments or -1 for variable number
90};
91
63e99e56
VK
92#define NXSL_METHOD_DEFINITION(clazz, name) \
93 static int M_##clazz##_##name (NXSL_Object *object, int argc, NXSL_Value **argv, NXSL_Value **result, NXSL_VM *vm)
55bdca5a 94
63e99e56 95#define NXSL_REGISTER_METHOD(clazz, name, argc) { \
55bdca5a 96 NXSL_ExtMethod *m = new NXSL_ExtMethod; \
63e99e56 97 m->handler = M_##clazz##_##name; \
55bdca5a
VK
98 m->numArgs = argc; \
99 m_methods->set(_T(#name), m); \
100 }
101
102/**
49fbe41f
VK
103 * Class representing NXSL class
104 */
2c75fa6f
VK
105class LIBNXSL_EXPORTABLE NXSL_Class
106{
e2845745 107private:
c42b4551 108 TCHAR m_name[MAX_CLASS_NAME];
e2845745
VK
109 StringList m_classHierarchy;
110
111protected:
55bdca5a 112 StringObjectMap<NXSL_ExtMethod> *m_methods;
2c75fa6f 113
e2845745
VK
114 void setName(const TCHAR *name);
115
2c75fa6f
VK
116public:
117 NXSL_Class();
118 virtual ~NXSL_Class();
119
63e99e56
VK
120 virtual NXSL_Value *getAttr(NXSL_Object *object, const TCHAR *attr);
121 virtual bool setAttr(NXSL_Object *object, const TCHAR *attr, NXSL_Value *value);
2c75fa6f 122
6b29839d 123 virtual int callMethod(const TCHAR *name, NXSL_Object *object, int argc, NXSL_Value **argv, NXSL_Value **result, NXSL_VM *vm);
49fbe41f 124
25e5c41d 125 virtual void onObjectCreate(NXSL_Object *object);
bb5365ed 126 virtual void onObjectDelete(NXSL_Object *object);
84ae3a17 127
e2845745
VK
128 const TCHAR *getName() const { return m_name; }
129 bool instanceOf(const TCHAR *name) const { return !_tcscmp(name, m_name) || m_classHierarchy.contains(name); }
2c75fa6f
VK
130};
131
49fbe41f
VK
132/**
133 * Class data - object and reference count
134 */
bdd1560b
VK
135struct __nxsl_class_data
136{
137 void *data;
138 int refCount;
139};
140
49fbe41f
VK
141/**
142 * Object instance
143 */
2c75fa6f
VK
144class LIBNXSL_EXPORTABLE NXSL_Object
145{
146private:
bdd1560b
VK
147 NXSL_Class *m_class;
148 __nxsl_class_data *m_data;
2c75fa6f
VK
149
150public:
25e5c41d
VK
151 NXSL_Object(NXSL_Object *object);
152 NXSL_Object(NXSL_Class *nxslClass, void *data);
2c75fa6f 153 ~NXSL_Object();
9e52272a 154
bdd1560b
VK
155 NXSL_Class *getClass() { return m_class; }
156 void *getData() { return m_data->data; }
2c75fa6f
VK
157};
158
49fbe41f 159/**
28e4009a
VK
160 * Reference counting object
161 */
162class LIBNXSL_EXPORTABLE NXSL_HandleCountObject
163{
164protected:
165 int m_handleCount;
166
167public:
168 NXSL_HandleCountObject()
169 {
170 m_handleCount = 0;
171 }
172
173 void incHandleCount() { m_handleCount++; }
174 void decHandleCount() { m_handleCount--; }
175 bool isUnused() { return m_handleCount < 1; }
176 bool isShared() { return m_handleCount > 1; }
177};
178
179/**
49fbe41f
VK
180 * Array element
181 */
ffee16a5
VK
182struct NXSL_ArrayElement
183{
184 int index;
185 NXSL_Value *value;
186};
187
49fbe41f
VK
188/**
189 * NXSL array
190 */
28e4009a 191class LIBNXSL_EXPORTABLE NXSL_Array : public NXSL_HandleCountObject
45ae7827
VK
192{
193private:
ffee16a5
VK
194 int m_size;
195 int m_allocated;
196 NXSL_ArrayElement *m_data;
45ae7827
VK
197
198public:
199 NXSL_Array();
01116597
VK
200 NXSL_Array(const NXSL_Array *src);
201 NXSL_Array(const StringList *values);
45ae7827
VK
202 ~NXSL_Array();
203
503b147f
VK
204 int size() const { return m_size; }
205 int getMinIndex() const { return (m_size > 0) ? m_data[0].index : 0; }
bc217f1b 206 int getMaxIndex() const { return (m_size > 0) ? m_data[m_size - 1].index : 0; }
d32e7ef1 207
503b147f
VK
208 StringList *toStringList() const;
209
210 NXSL_Value *get(int index) const;
211 NXSL_Value *getByPosition(int position) const;
212
213 void set(int index, NXSL_Value *value);
738119a1
VK
214 void append(NXSL_Value *value) { if (m_size == 0) { set(0, value); } else { set(getMaxIndex() + 1, value); } }
215 void insert(int index, NXSL_Value *value);
216 void remove(int index);
217
218 int callMethod(const TCHAR *name, int argc, NXSL_Value **argv, NXSL_Value **result, NXSL_VM *vm);
22aa5156
VK
219};
220
55bdca5a 221/**
06f09671
VK
222 * NXSL hash map
223 */
28e4009a 224class LIBNXSL_EXPORTABLE NXSL_HashMap : public NXSL_HandleCountObject
06f09671
VK
225{
226private:
06f09671
VK
227 StringObjectMap<NXSL_Value> *m_values;
228
229public:
230 NXSL_HashMap();
231 NXSL_HashMap(const NXSL_HashMap *src);
232 ~NXSL_HashMap();
233
06f09671
VK
234 void set(const TCHAR *key, NXSL_Value *value) { m_values->set(key, value); }
235 NXSL_Value *get(const TCHAR *key) const { return m_values->get(key); }
503b147f
VK
236 NXSL_Value *getKeys() const;
237 NXSL_Value *getValues() const;
06f09671 238
24bfa28b
VK
239 StringMap *toStringMap() const;
240
06f09671
VK
241 int size() const { return m_values->size(); }
242};
243
244/**
55bdca5a
VK
245 * Iterator for arrays
246 */
22aa5156
VK
247class LIBNXSL_EXPORTABLE NXSL_Iterator
248{
249private:
250 int m_refCount;
251 TCHAR *m_variable;
252 NXSL_Array *m_array;
253 int m_position;
254
255public:
256 NXSL_Iterator(const TCHAR *variable, NXSL_Array *array);
257 ~NXSL_Iterator();
258
259 const TCHAR *getVariableName() { return m_variable; }
260
261 void incRefCount() { m_refCount++; }
262 void decRefCount() { m_refCount--; }
28e4009a 263 bool isUnused() { return m_refCount < 1; }
22aa5156
VK
264
265 NXSL_Value *next();
266
267 static int createIterator(NXSL_Stack *stack);
45ae7827
VK
268};
269
55bdca5a 270/**
28e4009a
VK
271 * Object handle
272 */
273template <class T> class NXSL_Handle
274{
275private:
276 T *m_object;
277 int m_refCount;
278
279public:
280 NXSL_Handle(T *o)
281 {
282 m_object = o;
283 o->incHandleCount();
284 m_refCount = 0;
285 }
286 NXSL_Handle(NXSL_Handle<T> *h)
287 {
288 m_object = h->m_object;
289 m_object->incHandleCount();
290 m_refCount = 0;
291 }
292 ~NXSL_Handle()
293 {
294 m_object->decHandleCount();
295 if (m_object->isUnused())
296 delete m_object;
297 }
298
299 void incRefCount() { m_refCount++; }
300 void decRefCount() { m_refCount--; }
301 bool isUnused() { return m_refCount < 1; }
302 bool isShared() { return m_refCount > 1; }
303
304 T *getObject() { return m_object; }
305 bool isSharedObject() { return m_object->isShared(); }
306
307 void cloneObject()
308 {
309 m_object->decHandleCount();
310 m_object = new T(m_object);
311 m_object->incHandleCount();
312 }
313};
314
315/**
55bdca5a
VK
316 * Variable or constant value
317 */
b36dc6ff
VK
318class LIBNXSL_EXPORTABLE NXSL_Value
319{
320protected:
967893bb 321 UINT32 m_dwStrLen;
512623c4 322 TCHAR *m_pszValStr;
977e7d9d
VK
323#ifdef UNICODE
324 char *m_valueMBStr; // value as MB string; NULL until first request
325#endif
512623c4 326 TCHAR *m_name;
bd40de8f
VK
327 BYTE m_nDataType;
328 BYTE m_bStringIsValid;
329 union
330 {
967893bb
VK
331 INT32 nInt32;
332 UINT32 uInt32;
bd40de8f 333 INT64 nInt64;
967893bb 334 UINT64 uInt64;
bd40de8f 335 double dReal;
06f09671 336 NXSL_Object *object;
06f09671 337 NXSL_Iterator *iterator;
28e4009a
VK
338 NXSL_Handle<NXSL_Array> *arrayHandle;
339 NXSL_Handle<NXSL_HashMap> *hashMapHandle;
2c75fa6f 340 } m_value;
bd40de8f 341
bb5365ed
VK
342 void updateNumber();
343 void updateString();
b36dc6ff 344
bb5365ed 345 void invalidateString()
9e52272a 346 {
977e7d9d
VK
347 safe_free_and_null(m_pszValStr);
348#ifdef UNICODE
349 safe_free_and_null(m_valueMBStr);
350#endif
9e52272a
VK
351 m_bStringIsValid = FALSE;
352 }
353
b36dc6ff 354public:
bb5365ed 355 NXSL_Value();
06f09671
VK
356 NXSL_Value(const NXSL_Value *src);
357 NXSL_Value(NXSL_Object *object);
358 NXSL_Value(NXSL_Array *array);
359 NXSL_Value(NXSL_Iterator *iterator);
360 NXSL_Value(NXSL_HashMap *hashMap);
967893bb 361 NXSL_Value(INT32 nValue);
bd40de8f 362 NXSL_Value(INT64 nValue);
967893bb
VK
363 NXSL_Value(UINT32 uValue);
364 NXSL_Value(UINT64 uValue);
b36dc6ff 365 NXSL_Value(double dValue);
06f09671
VK
366 NXSL_Value(const TCHAR *value);
367 NXSL_Value(const TCHAR *value, UINT32 len);
08b214c6 368#ifdef UNICODE
06f09671 369 NXSL_Value(const char *value);
08b214c6 370#endif
b36dc6ff
VK
371 ~NXSL_Value();
372
06f09671 373 void set(INT32 value);
bb5365ed 374
06f09671 375 void setName(const TCHAR *name) { safe_free(m_name); m_name = _tcsdup_ex(name); }
4b47d7d7 376 const TCHAR *getName() const { return m_name; }
512623c4 377
bb5365ed 378 bool convert(int nDataType);
4b47d7d7
VK
379 int getDataType() const { return m_nDataType; }
380
381 bool isNull() const { return (m_nDataType == NXSL_DT_NULL); }
382 bool isObject() const { return (m_nDataType == NXSL_DT_OBJECT); }
383 bool isObject(const TCHAR *className) const;
384 bool isArray() const { return (m_nDataType == NXSL_DT_ARRAY); }
06f09671 385 bool isHashMap() const { return (m_nDataType == NXSL_DT_HASHMAP); }
4b47d7d7
VK
386 bool isIterator() const { return (m_nDataType == NXSL_DT_ITERATOR); }
387 bool isString() const { return (m_nDataType >= NXSL_DT_STRING); }
388 bool isNumeric() const { return (m_nDataType > NXSL_DT_STRING); }
389 bool isReal() const { return (m_nDataType == NXSL_DT_REAL); }
390 bool isInteger() const { return (m_nDataType > NXSL_DT_REAL); }
391 bool isUnsigned() const { return (m_nDataType >= NXSL_DT_UINT32); }
392 bool isZero() const;
393 bool isNonZero() const;
bb5365ed 394
06f09671 395 const TCHAR *getValueAsString(UINT32 *len);
bb5365ed 396 const TCHAR *getValueAsCString();
977e7d9d
VK
397#ifdef UNICODE
398 const char *getValueAsMBString();
399#else
400 const char *getValueAsMBString() { return getValueAsCString(); }
401#endif
967893bb
VK
402 INT32 getValueAsInt32();
403 UINT32 getValueAsUInt32();
bb5365ed 404 INT64 getValueAsInt64();
967893bb 405 UINT64 getValueAsUInt64();
bb5365ed 406 double getValueAsReal();
034e2615 407 bool getValueAsBoolean() { return getValueAsInt32() != 0; }
06f09671 408 NXSL_Object *getValueAsObject() { return (m_nDataType == NXSL_DT_OBJECT) ? m_value.object : NULL; }
28e4009a
VK
409 NXSL_Array *getValueAsArray() { return (m_nDataType == NXSL_DT_ARRAY) ? m_value.arrayHandle->getObject() : NULL; }
410 NXSL_HashMap *getValueAsHashMap() { return (m_nDataType == NXSL_DT_HASHMAP) ? m_value.hashMapHandle->getObject() : NULL; }
06f09671 411 NXSL_Iterator *getValueAsIterator() { return (m_nDataType == NXSL_DT_ITERATOR) ? m_value.iterator : NULL; }
bb5365ed 412
06f09671 413 void concatenate(const TCHAR *string, UINT32 len);
bd40de8f 414
bb5365ed
VK
415 void increment();
416 void decrement();
417 void negate();
418 void bitNot();
419
420 void add(NXSL_Value *pVal);
421 void sub(NXSL_Value *pVal);
422 void mul(NXSL_Value *pVal);
423 void div(NXSL_Value *pVal);
424 void rem(NXSL_Value *pVal);
425 void bitAnd(NXSL_Value *pVal);
426 void bitOr(NXSL_Value *pVal);
427 void bitXor(NXSL_Value *pVal);
428 void lshift(int nBits);
429 void rshift(int nBits);
bd40de8f
VK
430
431 BOOL EQ(NXSL_Value *pVal);
432 BOOL LT(NXSL_Value *pVal);
433 BOOL LE(NXSL_Value *pVal);
434 BOOL GT(NXSL_Value *pVal);
435 BOOL GE(NXSL_Value *pVal);
4b47d7d7 436
28e4009a
VK
437 void copyOnWrite();
438 void onVariableSet();
439
4b47d7d7
VK
440 bool equals(const NXSL_Value *v) const;
441 void serialize(ByteStream& s) const;
442
443 static NXSL_Value *load(ByteStream& s);
b36dc6ff
VK
444};
445
49fbe41f
VK
446/**
447 * NXSL function definition structure
448 */
6b29839d 449class NXSL_Function
b36dc6ff 450{
6b29839d 451public:
c42b4551 452 TCHAR m_name[MAX_FUNCTION_NAME];
967893bb 453 UINT32 m_dwAddr;
6b29839d 454
c42b4551
VK
455 NXSL_Function() { m_name[0] = 0; m_dwAddr = INVALID_ADDRESS; }
456 NXSL_Function(NXSL_Function *src) { nx_strncpy(m_name, src->m_name, MAX_FUNCTION_NAME); m_dwAddr = src->m_dwAddr; }
4b47d7d7 457 NXSL_Function(const TCHAR *name, UINT32 addr) { nx_strncpy(m_name, name, MAX_FUNCTION_NAME); m_dwAddr = addr; }
b36dc6ff
VK
458};
459
49fbe41f
VK
460/**
461 * External function structure
462 */
b36dc6ff
VK
463struct NXSL_ExtFunction
464{
c42b4551 465 TCHAR m_name[MAX_FUNCTION_NAME];
6b29839d 466 int (* m_pfHandler)(int argc, NXSL_Value **argv, NXSL_Value **result, NXSL_VM *vm);
bb5365ed 467 int m_iNumArgs; // Number of arguments or -1 for variable number
b36dc6ff
VK
468};
469
f11423ed
VK
470/**
471 * External selector structure
472 */
473struct NXSL_ExtSelector
474{
475 TCHAR m_name[MAX_FUNCTION_NAME];
476 int (* m_handler)(const TCHAR *name, NXSL_Value *options, int argc, NXSL_Value **argv, int *selection, NXSL_VM *vm);
477};
478
7e32778c
VK
479/**
480 * NXSL module import information
481 */
482struct NXSL_ModuleImport
483{
484 TCHAR name[MAX_PATH];
485 int lineNumber; // line number in source code where module was referenced
486};
487
fd421eca 488class NXSL_Library;
2791a0c9 489
55bdca5a
VK
490/**
491 * Environment for NXSL program
492 */
b36dc6ff
VK
493class LIBNXSL_EXPORTABLE NXSL_Environment
494{
495private:
bf9daa23 496 int m_numFunctions;
f11423ed 497 NXSL_ExtFunction *m_functions;
b36dc6ff 498
bf9daa23 499 int m_numSelectors;
f11423ed
VK
500 NXSL_ExtSelector *m_selectors;
501
502 NXSL_Library *m_library;
fd421eca 503
b36dc6ff
VK
504public:
505 NXSL_Environment();
c5e1f0bb 506 virtual ~NXSL_Environment();
b36dc6ff 507
2773ef30 508 virtual void print(NXSL_Value *value);
bb5365ed
VK
509 virtual void trace(int level, const TCHAR *text);
510
6b1f3e44
VK
511 virtual void configureVM(NXSL_VM *vm);
512
f11423ed
VK
513 void setLibrary(NXSL_Library *lib) { m_library = lib; }
514
515 NXSL_ExtFunction *findFunction(const TCHAR *name);
bf9daa23 516 void registerFunctionSet(int count, NXSL_ExtFunction *list);
fd421eca 517
f11423ed 518 NXSL_ExtSelector *findSelector(const TCHAR *name);
bf9daa23 519 void registerSelectorSet(int count, NXSL_ExtSelector *list);
2791a0c9 520
7e32778c 521 bool loadModule(NXSL_VM *vm, const NXSL_ModuleImport *importInfo);
b36dc6ff
VK
522};
523
3993eba0
VK
524/**
525 * Runtime variable information
526 */
b36dc6ff
VK
527class LIBNXSL_EXPORTABLE NXSL_Variable
528{
529protected:
530 TCHAR *m_pszName;
531 NXSL_Value *m_pValue;
c742e8c8 532 bool m_isConstant;
b36dc6ff
VK
533
534public:
1b41ebe2 535 NXSL_Variable(const TCHAR *pszName);
c742e8c8 536 NXSL_Variable(const TCHAR *pszName, NXSL_Value *pValue, bool constant = false);
b36dc6ff
VK
537 NXSL_Variable(NXSL_Variable *pSrc);
538 ~NXSL_Variable();
539
bb5365ed
VK
540 const TCHAR *getName() { return m_pszName; }
541 NXSL_Value *getValue() { return m_pValue; }
542 void setValue(NXSL_Value *pValue);
c742e8c8 543 bool isConstant() { return m_isConstant; }
b36dc6ff
VK
544};
545
18321496
VK
546/**
547 * Varable system
548 */
b36dc6ff
VK
549class LIBNXSL_EXPORTABLE NXSL_VariableSystem
550{
551protected:
6b29839d 552 ObjectArray<NXSL_Variable> *m_variables;
c742e8c8 553 bool m_isConstant;
b36dc6ff
VK
554
555public:
c742e8c8 556 NXSL_VariableSystem(bool constant = false);
6b29839d 557 NXSL_VariableSystem(NXSL_VariableSystem *src);
b36dc6ff
VK
558 ~NXSL_VariableSystem();
559
bb5365ed
VK
560 NXSL_Variable *find(const TCHAR *pszName);
561 NXSL_Variable *create(const TCHAR *pszName, NXSL_Value *pValue = NULL);
c742e8c8 562 void merge(NXSL_VariableSystem *src);
6b29839d
VK
563 void addAll(StringObjectMap<NXSL_Value> *src);
564 void clear() { m_variables->clear(); }
c742e8c8 565 bool isConstant() { return m_isConstant; }
b36dc6ff
VK
566};
567
18321496 568/**
4b47d7d7
VK
569 * Instruction's operand type
570 */
571enum OperandType
572{
573 OP_TYPE_NONE = 0,
574 OP_TYPE_ADDR = 1,
575 OP_TYPE_STRING = 2,
576 OP_TYPE_CONST = 3
577};
578
579/**
18321496
VK
580 * Single execution instruction
581 */
b36dc6ff
VK
582class LIBNXSL_EXPORTABLE NXSL_Instruction
583{
584 friend class NXSL_Program;
6b29839d 585 friend class NXSL_VM;
b36dc6ff
VK
586
587protected:
4b47d7d7
VK
588 INT16 m_nOpCode;
589 INT16 m_nStackItems;
b36dc6ff
VK
590 union
591 {
592 NXSL_Value *m_pConstant;
08b214c6 593 TCHAR *m_pszString;
967893bb 594 UINT32 m_dwAddr;
b36dc6ff 595 } m_operand;
4b47d7d7 596 INT32 m_nSourceLine;
b36dc6ff
VK
597
598public:
57f34c0a
VK
599 NXSL_Instruction(int nLine, short nOpCode);
600 NXSL_Instruction(int nLine, short nOpCode, NXSL_Value *pValue);
601 NXSL_Instruction(int nLine, short nOpCode, char *pszString);
602 NXSL_Instruction(int nLine, short nOpCode, char *pszString, short nStackItems);
603 NXSL_Instruction(int nLine, short nOpCode, UINT32 dwAddr);
604 NXSL_Instruction(int nLine, short nOpCode, short nStackItems);
2791a0c9 605 NXSL_Instruction(NXSL_Instruction *pSrc);
b36dc6ff 606 ~NXSL_Instruction();
4b47d7d7
VK
607
608 OperandType getOperandType();
b36dc6ff
VK
609};
610
55bdca5a
VK
611/**
612 * NXSL module information
613 */
2791a0c9
VK
614struct NXSL_Module
615{
6b29839d
VK
616 TCHAR m_name[MAX_PATH];
617 UINT32 m_codeStart;
618 int m_codeSize;
619 int m_functionStart;
620 int m_numFunctions;
2791a0c9
VK
621};
622
55bdca5a 623/**
6b29839d 624 * Compiled NXSL program
55bdca5a 625 */
b36dc6ff
VK
626class LIBNXSL_EXPORTABLE NXSL_Program
627{
6b29839d
VK
628 friend class NXSL_VM;
629
b36dc6ff 630protected:
6b29839d 631 ObjectArray<NXSL_Instruction> *m_instructionSet;
7e32778c 632 ObjectArray<NXSL_ModuleImport> *m_requiredModules;
6b29839d
VK
633 StringObjectMap<NXSL_Value> *m_constants;
634 ObjectArray<NXSL_Function> *m_functions;
635
636 UINT32 getFinalJumpDestination(UINT32 dwAddr, int srcJump);
637
638public:
639 NXSL_Program();
640 ~NXSL_Program();
641
642 bool addFunction(const char *pszName, UINT32 dwAddr, char *pszError);
643 void resolveFunctions();
644 void addInstruction(NXSL_Instruction *pInstruction) { m_instructionSet->add(pInstruction); }
f11423ed 645 void resolveLastJump(int opcode, int offset = 0);
6b29839d 646 void createJumpAt(UINT32 dwOpAddr, UINT32 dwJumpAddr);
7e32778c 647 void addRequiredModule(const char *name, int lineNumber);
6b29839d
VK
648 void optimize();
649 void removeInstructions(UINT32 start, int count);
650 bool addConstant(const char *name, NXSL_Value *value);
651
652 UINT32 getCodeSize() { return m_instructionSet->size(); }
653
654 void dump(FILE *pFile);
4b47d7d7
VK
655 void serialize(ByteStream& s);
656
657 static NXSL_Program *load(ByteStream& s, TCHAR *errMsg, size_t errMsgSize);
6b29839d
VK
658};
659
660/**
0207b7dd
EJ
661 * NXSL Script
662 */
663class LIBNXSL_EXPORTABLE NXSL_LibraryScript
664{
665protected:
666 UINT32 m_id;
667 uuid m_guid;
668 TCHAR m_name[1024];
669 TCHAR *m_source;
670 NXSL_Program *m_program;
671 TCHAR m_error[1024];
672
673public:
674 NXSL_LibraryScript();
675 NXSL_LibraryScript(UINT32 id, uuid guid, const TCHAR *name, TCHAR *source);
676 ~NXSL_LibraryScript();
677
678 bool isValid() const { return m_program != NULL; }
679
680 const uuid& getGuid() { return m_guid; }
681 UINT32 getId() { return m_id; }
682
683 const TCHAR *getName() { return m_name; }
684 const TCHAR *getCode() { return m_source; }
685 const TCHAR *getError() { return m_error; }
686
687 NXSL_Program *getProgram() { return m_program; }
688
689 void fillMessage(NXCPMessage *msg, UINT32 base);
690 void fillMessage(NXCPMessage *msg);
691};
692
693/**
6b29839d
VK
694 * Script library
695 */
696class LIBNXSL_EXPORTABLE NXSL_Library
697{
698private:
0207b7dd 699 ObjectArray<NXSL_LibraryScript> *m_scriptList;
6b29839d
VK
700 MUTEX m_mutex;
701
702 void deleteInternal(int nIndex);
703
704public:
705 NXSL_Library();
706 ~NXSL_Library();
707
708 void lock() { MutexLock(m_mutex); }
709 void unlock() { MutexUnlock(m_mutex); }
b36dc6ff 710
0207b7dd 711 BOOL addScript(NXSL_LibraryScript *script);
6b29839d
VK
712 void deleteScript(const TCHAR *name);
713 void deleteScript(UINT32 id);
0207b7dd
EJ
714 NXSL_Program *findNxslProgram(const TCHAR *name);
715 NXSL_LibraryScript *findScript(UINT32 id);
6b29839d 716 NXSL_VM *createVM(const TCHAR *name, NXSL_Environment *env);
b36dc6ff 717
0207b7dd 718 void fillMessage(NXCPMessage *msg);
6b29839d
VK
719};
720
721/**
a3906178
VK
722 * Catch point information
723 */
724struct NXSL_CatchPoint
725{
726 UINT32 addr;
727 UINT32 subLevel;
728 int dataStackSize;
729};
730
731/**
19eae342
VK
732 * NXSL storage class - base class for actual persistent storage
733 */
734class LIBNXSL_EXPORTABLE NXSL_Storage
735{
c73892ef
VK
736public:
737 NXSL_Storage();
738 virtual ~NXSL_Storage();
739
740 /**
741 * Write to storage. Storage becomes owner of provided value.
742 * Passing NULL value will effectively remove value from storage.
743 */
744 virtual void write(const TCHAR *name, NXSL_Value *value) = 0;
745
746 /**
747 * Read from storage. Returns new value owned by caller. Returns NXSL NULL if there are no value with given name.
748 */
749 virtual NXSL_Value *read(const TCHAR *name) = 0;
750};
751
752/**
753 * NXSL storage local implementation
754 */
755class LIBNXSL_EXPORTABLE NXSL_LocalStorage : public NXSL_Storage
756{
19eae342
VK
757protected:
758 StringObjectMap<NXSL_Value> *m_values;
759
760public:
c73892ef
VK
761 NXSL_LocalStorage();
762 virtual ~NXSL_LocalStorage();
19eae342
VK
763
764 virtual void write(const TCHAR *name, NXSL_Value *value);
765 virtual NXSL_Value *read(const TCHAR *name);
766};
767
768/**
6b29839d
VK
769 * NXSL virtual machine
770 */
771class LIBNXSL_EXPORTABLE NXSL_VM
772{
400e55c4 773private:
53c3d1e7 774 static EnumerationCallbackResult createConstantsCallback(const TCHAR *key, const void *value, void *data);
400e55c4 775
6b29839d
VK
776protected:
777 NXSL_Environment *m_env;
778 void *m_userData;
779
780 ObjectArray<NXSL_Instruction> *m_instructionSet;
781 UINT32 m_cp;
2791a0c9 782
967893bb 783 UINT32 m_dwSubLevel;
a3906178
VK
784 NXSL_Stack *m_dataStack;
785 NXSL_Stack *m_codeStack;
786 NXSL_Stack *m_catchStack;
b36dc6ff
VK
787 int m_nBindPos;
788
400e55c4
VK
789 NXSL_VariableSystem *m_constants;
790 NXSL_VariableSystem *m_globals;
791 NXSL_VariableSystem *m_locals;
b36dc6ff 792
19eae342
VK
793 NXSL_Storage *m_storage;
794 NXSL_Storage *m_localStorage;
795
6b29839d
VK
796 ObjectArray<NXSL_Function> *m_functions;
797 ObjectArray<NXSL_Module> *m_modules;
2791a0c9 798
9e52272a 799 NXSL_Value *m_pRetValue;
a3906178
VK
800 int m_errorCode;
801 int m_errorLine;
802 TCHAR *m_errorText;
b36dc6ff 803
bb5365ed 804 void execute();
a3906178 805 bool unwind();
bb5365ed 806 void callFunction(int nArgCount);
f11423ed 807 UINT32 callSelector(const TCHAR *name, int numElements);
bb5365ed
VK
808 void doUnaryOperation(int nOpCode);
809 void doBinaryOperation(int nOpCode);
06f09671
VK
810 void getOrUpdateArrayElement(int opcode, NXSL_Value *array, NXSL_Value *index);
811 bool setArrayElement(NXSL_Value *array, NXSL_Value *index, NXSL_Value *value);
bc217f1b 812 void getArrayAttribute(NXSL_Array *a, const TCHAR *attribute, bool safe);
06f09671
VK
813 void getOrUpdateHashMapElement(int opcode, NXSL_Value *hashMap, NXSL_Value *key);
814 bool setHashMapElement(NXSL_Value *hashMap, NXSL_Value *key, NXSL_Value *value);
bc217f1b 815 void getHashMapAttribute(NXSL_HashMap *m, const TCHAR *attribute, bool safe);
7e32778c 816 void error(int errorCode, int sourceLine = -1);
bb5365ed 817 NXSL_Value *matchRegexp(NXSL_Value *pValue, NXSL_Value *pRegexp, BOOL bIgnoreCase);
b36dc6ff 818
bd9ffdf0 819 NXSL_Variable *findVariable(const TCHAR *pszName);
22aa5156
VK
820 NXSL_Variable *findOrCreateVariable(const TCHAR *pszName);
821 NXSL_Variable *createVariable(const TCHAR *pszName);
b36dc6ff 822
967893bb 823 void relocateCode(UINT32 dwStartOffset, UINT32 dwLen, UINT32 dwShift);
6b29839d 824 UINT32 getFunctionAddress(const TCHAR *pszName);
2791a0c9 825
b36dc6ff 826public:
19eae342 827 NXSL_VM(NXSL_Environment *env = NULL, NXSL_Storage *storage = NULL);
6b29839d 828 ~NXSL_VM();
b36dc6ff 829
7e32778c 830 void loadModule(NXSL_Program *module, const NXSL_ModuleImport *importInfo);
b36dc6ff 831
bb5365ed 832 void setGlobalVariable(const TCHAR *pszName, NXSL_Value *pValue);
400e55c4 833 NXSL_Variable *findGlobalVariable(const TCHAR *pszName) { return m_globals->find(pszName); }
1b41ebe2 834
99730c0c
VK
835 bool addConstant(const TCHAR *name, NXSL_Value *value);
836
0a96e4e9
VK
837 void setStorage(NXSL_Storage *storage);
838
19eae342
VK
839 void storageWrite(const TCHAR *name, NXSL_Value *value) { m_storage->write(name, value); }
840 void storageWrite(const TCHAR *name, const TCHAR *value) { m_storage->write(name, new NXSL_Value(value)); }
841 void storageWrite(const TCHAR *name, INT32 value) { m_storage->write(name, new NXSL_Value(value)); }
842 void storageWrite(const TCHAR *name, UINT32 value) { m_storage->write(name, new NXSL_Value(value)); }
843 void storageWrite(const TCHAR *name, INT64 value) { m_storage->write(name, new NXSL_Value(value)); }
844 void storageWrite(const TCHAR *name, UINT64 value) { m_storage->write(name, new NXSL_Value(value)); }
845 void storageWrite(const TCHAR *name, double value) { m_storage->write(name, new NXSL_Value(value)); }
846 NXSL_Value *storageRead(const TCHAR *name) { return m_storage->read(name); }
847
6b29839d 848 bool load(NXSL_Program *program);
17b1ab4a 849 bool run(ObjectArray<NXSL_Value> *args, NXSL_VariableSystem *pUserLocals = NULL,
0fa2aacc
VK
850 NXSL_VariableSystem **ppGlobals = NULL, NXSL_VariableSystem *pConstants = NULL,
851 const TCHAR *entryPoint = NULL);
17b1ab4a 852 bool run(int argc, NXSL_Value **argv, NXSL_VariableSystem *pUserLocals = NULL,
6b29839d
VK
853 NXSL_VariableSystem **ppGlobals = NULL, NXSL_VariableSystem *pConstants = NULL,
854 const TCHAR *entryPoint = NULL);
17b1ab4a 855 bool run() { ObjectArray<NXSL_Value> args(1, 1, false); return run(&args); }
b36dc6ff 856
6b29839d 857 UINT32 getCodeSize() { return m_instructionSet->size(); }
1f564860 858
bb5365ed
VK
859 void trace(int level, const TCHAR *text);
860 void dump(FILE *pFile);
a3906178
VK
861 int getErrorCode() { return m_errorCode; }
862 int getErrorLine() { return m_errorLine; }
863 const TCHAR *getErrorText() { return CHECK_NULL_EX(m_errorText); }
bb5365ed 864 NXSL_Value *getResult() { return m_pRetValue; }
f76f2296
VK
865
866 void *getUserData() { return m_userData; }
867 void setUserData(void *data) { m_userData = data; }
b36dc6ff
VK
868};
869
55bdca5a 870/**
594b54e7
VK
871 * NXSL "TableRow" class
872 */
873class LIBNXSL_EXPORTABLE NXSL_TableRowClass : public NXSL_Class
874{
875public:
876 NXSL_TableRowClass();
877 virtual ~NXSL_TableRowClass();
878
879 virtual NXSL_Value *getAttr(NXSL_Object *pObject, const TCHAR *pszAttr);
880 virtual void onObjectDelete(NXSL_Object *object);
881};
882
883/**
967893bb
VK
884 * NXSL "TableColumn" class
885 */
886class LIBNXSL_EXPORTABLE NXSL_TableColumnClass : public NXSL_Class
887{
888public:
889 NXSL_TableColumnClass();
890 virtual ~NXSL_TableColumnClass();
891
892 virtual NXSL_Value *getAttr(NXSL_Object *pObject, const TCHAR *pszAttr);
893 virtual void onObjectDelete(NXSL_Object *object);
894};
895
896/**
55bdca5a
VK
897 * NXSL "Table" class
898 */
899class LIBNXSL_EXPORTABLE NXSL_TableClass : public NXSL_Class
900{
901public:
902 NXSL_TableClass();
903 virtual ~NXSL_TableClass();
904
905 virtual NXSL_Value *getAttr(NXSL_Object *pObject, const TCHAR *pszAttr);
906 virtual void onObjectDelete(NXSL_Object *object);
907};
2791a0c9 908
adf6f870 909/**
7de1151b
VK
910 * NXSL "StaticTable" class - table that is not deleted when ref count reaches 0
911 */
912class LIBNXSL_EXPORTABLE NXSL_StaticTableClass : public NXSL_TableClass
913{
914public:
915 NXSL_StaticTableClass();
916 virtual ~NXSL_StaticTableClass();
917
918 virtual void onObjectDelete(NXSL_Object *object);
919};
920
921/**
adf6f870
AK
922 * NXSL "Connector" class
923 */
924class LIBNXSL_EXPORTABLE NXSL_ConnectorClass : public NXSL_Class
925{
926public:
927 NXSL_ConnectorClass();
928 virtual ~NXSL_ConnectorClass();
929
930 virtual NXSL_Value *getAttr(NXSL_Object *pObject, const TCHAR *pszAttr);
931 virtual void onObjectDelete(NXSL_Object *object);
932};
933
7de1151b 934/**
bf9daa23 935 * NXSL "GeoLocation" class
63e99e56
VK
936 */
937class LIBNXSL_EXPORTABLE NXSL_GeoLocationClass : public NXSL_Class
938{
939public:
940 NXSL_GeoLocationClass();
941 virtual ~NXSL_GeoLocationClass();
942
943 virtual NXSL_Value *getAttr(NXSL_Object *pObject, const TCHAR *pszAttr);
944 virtual void onObjectDelete(NXSL_Object *object);
bf9daa23
VK
945
946 static NXSL_Value *createObject(const GeoLocation& gl);
947};
948
949/**
950 * NXSL "InetAddress" class
951 */
952class LIBNXSL_EXPORTABLE NXSL_InetAddressClass : public NXSL_Class
953{
954public:
955 NXSL_InetAddressClass();
956 virtual ~NXSL_InetAddressClass();
957
958 virtual NXSL_Value *getAttr(NXSL_Object *pObject, const TCHAR *pszAttr);
959 virtual void onObjectDelete(NXSL_Object *object);
960
961 static NXSL_Value *createObject(const InetAddress& addr);
63e99e56
VK
962};
963
964/**
7de1151b
VK
965 * Class definition instances
966 */
967extern NXSL_TableClass LIBNXSL_EXPORTABLE g_nxslTableClass;
968extern NXSL_StaticTableClass LIBNXSL_EXPORTABLE g_nxslStaticTableClass;
594b54e7 969extern NXSL_TableRowClass LIBNXSL_EXPORTABLE g_nxslTableRowClass;
967893bb 970extern NXSL_TableColumnClass LIBNXSL_EXPORTABLE g_nxslTableColumnClass;
7de1151b 971extern NXSL_ConnectorClass LIBNXSL_EXPORTABLE g_nxslConnectorClass;
63e99e56 972extern NXSL_GeoLocationClass LIBNXSL_EXPORTABLE g_nxslGeoLocationClass;
bf9daa23 973extern NXSL_InetAddressClass LIBNXSL_EXPORTABLE g_nxslInetAddressClass;
7de1151b 974
b36dc6ff 975#endif