NXSL: added support for modules
authorVictor Kirhenshtein <victor@netxms.org>
Sat, 7 Jan 2006 13:12:50 +0000 (13:12 +0000)
committerVictor Kirhenshtein <victor@netxms.org>
Sat, 7 Jan 2006 13:12:50 +0000 (13:12 +0000)
13 files changed:
ChangeLog
include/nxsl.h
include/nxsl_classes.h
src/console/win32/nxcon.clw
src/console/win32/nxcon.rc
src/console/win32/resource.h
src/libnxsl/env.cpp
src/libnxsl/instruction.cpp
src/libnxsl/main.cpp
src/libnxsl/parser.l
src/libnxsl/parser.y
src/libnxsl/program.cpp
src/nxscript/nxscript.cpp

index b7d6a28..c69b3f8 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -5,7 +5,7 @@
 - Added built-in scripting language
 - Implemented DCI transformations
 - Added startup scripts for Gentoo Linux
-- Fixed issues: #68
+- Fixed issues: #68, #71
 
 
 *
index 6a3b3d9..716c34e 100644 (file)
@@ -60,6 +60,7 @@
 #define NXSL_ERR_TYPE_CAST                13
 #define NXSL_ERR_NOT_OBJECT               14
 #define NXSL_ERR_NO_SUCH_ATTRIBUTE        15
+#define NXSL_ERR_MODULE_NOT_FOUND         16
 
 
 //
@@ -92,6 +93,7 @@ int LIBNXSL_EXPORTABLE NXSLRun(NXSL_SCRIPT hScript);
 TCHAR LIBNXSL_EXPORTABLE *NXSLGetRuntimeError(NXSL_SCRIPT hScript);
 void LIBNXSL_EXPORTABLE NXSLDestroy(NXSL_SCRIPT hScript);
 void LIBNXSL_EXPORTABLE NXSLDump(NXSL_SCRIPT hScript, FILE *pFile);
+TCHAR LIBNXSL_EXPORTABLE *NXSLLoadFile(TCHAR *pszFileName, DWORD *pdwFileSize);
 
 #ifdef __cplusplus
 }
index ca0d1fe..3c5a2b2 100644 (file)
@@ -231,6 +231,8 @@ struct NXSL_ExtFunction
 // Environment for NXSL program
 //
 
+class NXSL_Program;
+
 class LIBNXSL_EXPORTABLE NXSL_Environment
 {
 private:
@@ -250,6 +252,8 @@ public:
 
    NXSL_ExtFunction *FindFunction(char *pszName);
    void RegisterFunctionSet(DWORD dwNumFunctions, NXSL_ExtFunction *pList);
+
+   BOOL UseModule(NXSL_Program *pMain, char *pszName);
 };
 
 
@@ -321,11 +325,26 @@ public:
    NXSL_Instruction(int nLine, int nOpCode, char *pszString, int nStackItems);
    NXSL_Instruction(int nLine, int nOpCode, DWORD dwAddr);
    NXSL_Instruction(int nLine, int nOpCode, int nStackItems);
+   NXSL_Instruction(NXSL_Instruction *pSrc);
    ~NXSL_Instruction();
 };
 
 
 //
+// Used module information
+//
+
+struct NXSL_Module
+{
+   char m_szName[MAX_PATH];
+   DWORD m_dwCodeStart;
+   DWORD m_dwCodeSize;
+   DWORD m_dwFunctionStart;
+   DWORD m_dwNumFunctions;
+};
+
+
+//
 // Class representing compiled NXSL program
 //
 
@@ -338,6 +357,9 @@ protected:
    DWORD m_dwCodeSize;
    DWORD m_dwCurrPos;
 
+   DWORD m_dwNumPreloads;
+   char **m_ppszPreloadList;
+
    DWORD m_dwSubLevel;
    NXSL_Stack *m_pDataStack;
    NXSL_Stack *m_pCodeStack;
@@ -350,17 +372,24 @@ protected:
    DWORD m_dwNumFunctions;
    NXSL_Function *m_pFunctionList;
 
+   DWORD m_dwNumModules;
+   NXSL_Module *m_pModuleList;
+
    NXSL_Value *m_pRetValue;
    int m_nErrorCode;
    TCHAR *m_pszErrorText;
 
    void Execute(void);
+   void CallFunction(int nArgCount);
    void DoUnaryOperation(int nOpCode);
    void DoBinaryOperation(int nOpCode);
    void Error(int nError);
 
    NXSL_Variable *FindOrCreateVariable(TCHAR *pszName);
 
+   DWORD GetFunctionAddress(char *pszName);
+   void RelocateCode(DWORD dwStartOffset, DWORD dwLen, DWORD dwShift);
+
 public:
    NXSL_Program(void);
    ~NXSL_Program();
@@ -369,6 +398,8 @@ public:
    void ResolveFunctions(void);
    void AddInstruction(NXSL_Instruction *pInstruction);
    void ResolveLastJump(int nOpCode);
+   void AddPreload(char *pszName);
+   void UseModule(NXSL_Program *pModule, char *pszName);
 
    int Run(NXSL_Environment *pEnv = NULL, DWORD argc = 0, NXSL_Value **argv = NULL);
 
@@ -380,4 +411,23 @@ public:
 };
 
 
+//
+// Script library
+//
+
+class NXSL_Library
+{
+private:
+   DWORD m_dwNumScripts;
+   NXSL_Program **m_ppScriptList;
+
+public:
+   NXSL_Library(void);
+   ~NXSL_Library();
+
+   BOOL AddScript(NXSL_Program *pScript);
+   
+};
+
+
 #endif
index bd984f5..a1fe2e0 100644 (file)
@@ -16,9 +16,9 @@ Class7=CEventBrowser
 Class9=CMapView
 
 ResourceCount=135
-Resource1=IDD_SET_PASSWORD (English (U.S.))
+Resource1=IDD_EDIT_RULE_SEVERITY (English (U.S.))
 Resource2=IDD_OBJECT_NODE_GENERAL
-Resource3=IDD_ACTION_PROPERTIES (English (U.S.))
+Resource3=IDD_EDIT_TRAP_ARG (English (U.S.))
 Resource4=IDD_SELECT_OBJECT
 Resource5=IDD_SELECT_ACTION
 Class2=CChildView
@@ -32,9 +32,9 @@ Resource7=IDD_NEW_USER
 Class12=CObjectBrowser
 Resource8=IDD_CREATE_CONTAINER
 Class13=CObjectPropDlg
-Resource9=IDA_DC_EDITOR (English (U.S.))
-Resource10=IDD_NEW_ACTION (English (U.S.))
-Resource11=IDA_EVENT_EDITOR (English (U.S.))
+Resource9=IDD_DCI_SCHEDULE (English (U.S.))
+Resource10=IDD_EDIT_TRAP (English (U.S.))
+Resource11=IDA_OBJECT_TOOLS_EDITOR (English (U.S.))
 Resource12=IDR_CTRLPANEL (English (U.S.))
 Resource13=IDR_EVENTS (English (U.S.))
 Resource14=IDR_MAPFRAME (English (U.S.))
@@ -42,17 +42,17 @@ Resource15=IDR_OBJECTS (English (U.S.))
 Resource16=IDD_DUMMY (English (U.S.))
 Class14=CEventEditor
 Class15=CEditEventDlg
-Resource17=IDD_OBJECT_RELATIONS (English (U.S.))
+Resource17=IDD_EDIT_IP_SUBNET (English (U.S.))
 Class16=CDebugFrame
-Resource18=IDD_SELECT_ACTION (English (U.S.))
+Resource18=IDD_REQUEST_PROCESSING (English (U.S.))
 Resource19=IDD_OBJECT_PROPERTIES (English (U.S.))
 Resource20=IDD_SELECT_EVENT
 Class17=CObjectPreview
-Resource21=IDD_MIB_BROWSER (English (U.S.))
+Resource21=IDD_ACTION_PROPERTIES (English (U.S.))
 Class18=CToolBox
 Class19=CObjectInfoBox
 Class20=CObjectSearchBox
-Resource22=IDD_DATA_QUERY (English (U.S.))
+Resource22=IDD_GROUP_PROPERTIES (English (U.S.))
 Class21=CEditBox
 Class22=COPGeneral
 Class23=CNodePropsGeneral
@@ -61,14 +61,14 @@ Class24=CObjectPropCaps
 Class25=CObjectPropSheet
 Resource24=IDA_MDI_DEFAULT
 Class26=CRequestProcessingDlg
-Resource25=IDD_NEW_OBJECT_TOOL (English (U.S.))
+Resource25=IDA_NETMAP (English (U.S.))
 Resource26=IDD_PROGRESS (English (U.S.))
 Resource27=IDD_EDIT_RULE_ALARM
-Resource28=IDA_ALARM_BROWSER (English (U.S.))
+Resource28=IDA_AGENT_CFG_EDITOR (English (U.S.))
 Class27=CObjectPropsGeneral
-Resource29=IDD_SELECT_EVENT (English (U.S.))
+Resource29=IDD_CREATE_NODE (English (U.S.))
 Class28=CObjectPropsSecurity
-Resource30=IDD_CREATE_CONTAINER (English (U.S.))
+Resource30=IDD_SELECT_AGENT_PARAM (English (U.S.))
 Resource31=IDD_SELECT_USER
 Resource32=IDD_OBJECT_SECURITY
 Class29=CUserSelectDlg
@@ -79,36 +79,36 @@ Class31=CNewUserDlg
 Resource35=IDD_THRESHOLD
 Resource36=IDA_EPP
 Class32=CUserPropDlg
-Resource37=IDD_CP_GENERAL (English (U.S.))
+Resource37=IDD_DATA_QUERY (English (U.S.))
 Resource38=IDD_ABOUTBOX
 Class33=CGroupPropDlg
 Resource39=IDD_CP_GENERAL
 Resource40=IDA_TRAP_EDITOR
 Resource41=IDM_VIEW_SPECIFIC
-Resource42=IDD_EDIT_RULE_SEVERITY (English (U.S.))
+Resource42=IDD_CREATE_TG (English (U.S.))
 Class34=CPasswordChangeDlg
 Class35=CNodeSummary
 Class36=CNetSummaryFrame
 Class37=CDataCollectionEditor
-Resource43=IDD_EDIT_TRAP (English (U.S.))
+Resource43=IDD_DESKTOP_SAVE_AS (English (U.S.))
 Class38=CDCIPropPage
-Resource44=IDD_CREATE_TEMPLATE (English (U.S.))
+Resource44=IDD_SELECT_ACTION (English (U.S.))
 Class39=CDCIDataView
-Resource45=IDD_DCI_TRANSFORM (English (U.S.))
+Resource45=IDA_GRAPH (English (U.S.))
 Class40=CGraph
 Class41=CGraphFrame
 Class42=CDCIThresholdsPage
-Resource46=IDD_EDIT_EVENT (English (U.S.))
-Resource47=IDA_MDI_DEFAULT (English (U.S.))
+Resource46=IDD_OBJECT_RELATIONS (English (U.S.))
+Resource47=IDA_PACKAGE_MGR (English (U.S.))
 Resource48=IDM_CONTEXT
 Class43=CThresholdDlg
-Resource49=IDD_ABOUTBOX (English (U.S.))
+Resource49=IDD_USER_PROPERTIES (English (U.S.))
 Resource50=IDD_EDIT_TRAP_ARG
 Class44=CMIBBrowserDlg
 Class45=CEventPolicyEditor
 Class46=CRuleList
 Class47=CRuleHeader
-Resource51=IDD_DCI_SCHEDULE (English (U.S.))
+Resource51=IDD_SELECT_OBJECT (English (U.S.))
 Resource52=IDD_CREATE_NODE
 Class48=CObjectSelDlg
 Resource53=IDD_OBJECT_CAPS
@@ -117,22 +117,22 @@ Class49=CRuleCommentDlg
 Resource55=IDD_DCI_COLLECTION
 Class50=CEventSelDlg
 Resource56=IDD_DATA_QUERY
-Resource57=IDD_SAVE_AGENT_CFG (English (U.S.))
+Resource57=IDA_MDI_DEFAULT (English (U.S.))
 Resource58=IDD_CREATE_TG
-Resource59=IDA_AGENT_CFG_EDITOR (English (U.S.))
-Resource60=IDA_PACKAGE_MGR (English (U.S.))
+Resource59=IDD_OBJECT_SECURITY (English (U.S.))
+Resource60=IDD_OBJECT_CAPS (English (U.S.))
 Class51=CObjectPropsPresentation
-Resource61=IDD_GROUP_PROPERTIES (English (U.S.))
+Resource61=IDD_OBJECT_PRESENTATION (English (U.S.))
 Resource62=IDD_EDIT_RULE_COMMENT
 Class52=CRuleSeverityDlg
 Resource63=IDD_ACTION_PROPERTIES
 Class53=CRuleAlarmDlg
 Class54=CAlarmBrowser
-Resource64=IDD_EDIT_RULE_ALARM (English (U.S.))
+Resource64=IDD_CREATE_TEMPLATE (English (U.S.))
 Resource65=IDD_DCI_TRANSFORM
-Resource66=IDD_OBJECT_PRESENTATION (English (U.S.))
-Resource67=IDA_TRAP_EDITOR (English (U.S.))
-Resource68=IDD_CREATE_NODE (English (U.S.))
+Resource66=IDD_DCI_TRANSFORM (English (U.S.))
+Resource67=IDD_EDIT_EVENT (English (U.S.))
+Resource68=IDD_INPUT_BOX (English (U.S.))
 Class55=CConsolePropsGeneral
 Class56=CActionEditor
 Resource69=IDA_ACTION_EDITOR
@@ -143,18 +143,18 @@ Class58=CEditActionDlg
 Resource72=IDA_NETMAP
 Class59=CActionSelDlg
 Resource73=IDD_MIB_BROWSER
-Resource74=IDD_SELECT_OBJECT (English (U.S.))
-Resource75=IDD_OBJECT_NODE_POLL (English (U.S.))
+Resource74=IDA_LAST_VALUES (English (U.S.))
+Resource75=IDD_SELECT_INTERNAL_ITEM (English (U.S.))
 Resource76=IDD_USER_PROPERTIES
 Class60=CCreateObjectDlg
 Class61=CCreateContainerDlg
 Resource77=IDR_MAINFRAME
 Class62=CCreateNodeDlg
-Resource78=IDD_THRESHOLD (English (U.S.))
-Resource79=IDA_OBJECT_BROWSER (English (U.S.))
-Resource80=IDD_EDIT_VARIABLE (English (U.S.))
+Resource78=IDD_NEW_ACTION (English (U.S.))
+Resource79=IDD_OBJECT_NODE_POLL (English (U.S.))
+Resource80=IDD_OBJTOOL_OPTIONS (English (U.S.))
 Class63=CDCITransformPage
-Resource81=IDD_EDIT_RULE_COMMENT (English (U.S.))
+Resource81=IDD_CREATE_CONTAINER (English (U.S.))
 Class64=CPollNodeDlg
 Resource82=IDD_POLL_NODE (English (U.S.))
 Class65=CNodePoller
@@ -171,7 +171,7 @@ Resource89=IDA_ALARM_BROWSER
 Class69=CDataQueryDlg
 Resource90=IDD_EDIT_RULE_SEVERITY
 Class70=CTrapEditDlg
-Resource91=IDD_REMOVE_TEMPLATE
+Resource91=IDA_ACTION_EDITOR (English (U.S.))
 Class71=CTrapParamDlg
 Resource92=IDD_EDIT_EVENT
 Resource93=IDD_CREATE_TEMPLATE
@@ -179,82 +179,82 @@ Class72=CGraphPropDlg
 Class73=CColorSelector
 Class74=CPackageMgr
 Resource94=IDD_GROUP_PROPERTIES
-Resource95=IDA_NETMAP (English (U.S.))
-Resource96=IDM_VIEW_SPECIFIC (English (U.S.))
-Resource97=IDA_SERVER_CFG_EDITOR (English (U.S.))
-Resource98=IDD_EDIT_IP_SUBNET (English (U.S.))
-Resource99=IDD_USER_PROPERTIES (English (U.S.))
-Resource100=IDD_DCI_DATA_EXPORT (English (U.S.))
-Resource101=IDR_MAINFRAME (English (U.S.))
-Resource102=IDD_OBJECT_NETSRV_GENERAL (English (U.S.))
-Resource103=IDD_OBJECT_VPNC_GENERAL (English (U.S.))
-Resource104=IDD_OBJECT_STATUS (English (U.S.))
-Resource105=IDD_REQUEST_PROCESSING (English (U.S.))
-Resource106=IDD_NEW_USER (English (U.S.))
-Resource107=IDD_OBJTOOL_OPTIONS (English (U.S.))
+Resource95=IDA_DC_EDITOR (English (U.S.))
+Resource96=IDM_CONTEXT (English (U.S.))
+Resource97=IDD_OBJECT_GENERAL (English (U.S.))
+Resource98=IDR_MAINFRAME (English (U.S.))
+Resource99=IDD_SELECT_EVENT (English (U.S.))
+Resource100=IDD_NEW_OBJECT_TOOL (English (U.S.))
+Resource101=IDD_CREATE_NETSRV (English (U.S.))
+Resource102=IDD_CREATE_VPNC (English (U.S.))
+Resource103=IDD_CHANGE_IP
+Resource104=IDA_EPP (English (U.S.))
+Resource105=IDD_DCI_THRESHOLDS (English (U.S.))
+Resource106=IDD_EDIT_RULE_COMMENT (English (U.S.))
+Resource107=IDA_EVENT_EDITOR (English (U.S.))
 Class75=CInternalItemSelDlg
-Resource108=IDD_SELECT_AGENT_PARAM (English (U.S.))
+Resource108=IDD_LASTVAL_PROP (English (U.S.))
 Class76=CAgentParamSelDlg
-Resource109=IDD_CHANGE_IP
+Resource109=IDA_TRAP_EDITOR (English (U.S.))
 Class77=CInputBox
-Resource110=IDD_GRAPH_PROP_DATA (English (U.S.))
+Resource110=IDD_CP_GENERAL (English (U.S.))
 Class78=CCreateNetSrvDlg
-Resource111=IDD_GRAPH_PROP_SETTINGS (English (U.S.))
+Resource111=IDD_SELECT_USER (English (U.S.))
 Class79=CNetSrvPropsGeneral
 Resource112=IDD_LOGIN (English (U.S.))
 Class80=CNodePropsPolling
 Class81=CDeploymentView
 Class82=CLastValuesView
 Class83=CValueList
-Resource113=IDD_SELECT_INTERNAL_ITEM (English (U.S.))
+Resource113=IDD_GRAPH_PROP_DATA (English (U.S.))
 Class84=CObjectPropsRelations
-Resource114=IDD_LASTVAL_PROP (English (U.S.))
+Resource114=IDD_OBJTOOL_GENERAL (English (U.S.))
 Class85=CSaveDesktopDlg
-Resource115=IDD_DESKTOP_SAVE_AS (English (U.S.))
+Resource115=IDD_SAVE_AGENT_CFG (English (U.S.))
 Class86=CGraphSettingsPage
-Resource116=IDD_CREATE_NETSRV (English (U.S.))
+Resource116=IDD_EDIT_VARIABLE (English (U.S.))
 Class87=CGraphDataPage
-Resource117=IDD_OBJECT_GENERAL (English (U.S.))
+Resource117=IDD_THRESHOLD (English (U.S.))
 Class88=CRemoveTemplateDlg
-Resource118=IDD_OBJTOOL_GENERAL (English (U.S.))
+Resource118=IDA_ALARM_BROWSER (English (U.S.))
 Class89=CAddrChangeDlg
-Resource119=IDD_OBJECT_NODE_GENERAL (English (U.S.))
+Resource119=IDD_SET_PASSWORD (English (U.S.))
 Class90=CLastValuesPropDlg
 Class91=CAgentCfgEditor
-Resource120=IDD_DCI_COLLECTION (English (U.S.))
+Resource120=IDD_EDIT_RULE_ALARM (English (U.S.))
 Class92=CDataExportDlg
 Class93=CServerCfgEditor
-Resource121=IDA_EPP (English (U.S.))
-Resource122=IDA_GRAPH (English (U.S.))
+Resource121=IDA_SERVER_CFG_EDITOR (English (U.S.))
+Resource122=IDD_OBJECT_NODE_GENERAL (English (U.S.))
 Class94=CEditVariableDlg
-Resource123=IDD_CREATE_TG (English (U.S.))
+Resource123=IDD_OBJECT_NETSRV_GENERAL (English (U.S.))
 Class95=CCreateVPNConnDlg
-Resource124=IDD_DCI_THRESHOLDS (English (U.S.))
+Resource124=IDD_OBJECT_STATUS (English (U.S.))
 Class96=CVPNCPropsGeneral
-Resource125=IDA_ACTION_EDITOR (English (U.S.))
+Resource125=IDD_ABOUTBOX (English (U.S.))
 Class97=CEditSubnetDlg
-Resource126=IDM_CONTEXT (English (U.S.))
-Resource127=IDD_SELECT_USER (English (U.S.))
+Resource126=IDM_VIEW_SPECIFIC (English (U.S.))
+Resource127=IDA_OBJECT_BROWSER (English (U.S.))
 Class98=CModifiedAgentCfgDlg
 Class99=CSimpleSplitter
 Class100=CAdvSplitter
-Resource128=IDD_OBJECT_SECURITY (English (U.S.))
+Resource128=IDD_MIB_BROWSER (English (U.S.))
 Class101=CTableView
 Class102=CWaitView
 Class103=CWebBrowser
 Class104=CSyslogBrowser
 Class105=CLPPList
-Resource129=IDA_LAST_VALUES (English (U.S.))
+Resource129=IDD_OBJECT_VPNC_GENERAL (English (U.S.))
 Class106=CDCISchedulePage
-Resource130=IDD_EDIT_TRAP_ARG (English (U.S.))
+Resource130=IDD_GRAPH_PROP_SETTINGS (English (U.S.))
 Class107=CObjectPropsStatus
 Class108=CObjectToolsEditor
-Resource131=IDD_CREATE_VPNC (English (U.S.))
-Resource132=IDD_OBJECT_CAPS (English (U.S.))
+Resource131=IDD_REMOVE_TEMPLATE
+Resource132=IDD_DCI_COLLECTION (English (U.S.))
 Class109=CObjToolPropGeneral
-Resource133=IDA_OBJECT_TOOLS_EDITOR (English (U.S.))
+Resource133=IDD_NEW_USER (English (U.S.))
 Class110=CObjToolPropColumns
-Resource134=IDD_INPUT_BOX (English (U.S.))
+Resource134=IDD_DCI_DATA_EXPORT (English (U.S.))
 Class111=CNewObjectToolDlg
 Class112=CObjToolPropOptions
 Resource135=IDD_OBJTOOL_COLUMNS
@@ -2426,8 +2426,8 @@ ControlCount=7
 Control1=IDC_STATIC,static,1342308352
 Control2=IDC_COMBO_DELTA,combobox,1344339971
 Control3=IDC_STATIC,static,1342308352
-Control4=IDC_EDIT_FORMULA,edit,1350631552
-Control5=IDC_BUTTON_CREATE,button,1342242816
+Control4=IDC_EDIT_FORMULA,edit,1353781380
+Control5=IDC_BUTTON_CHECK,button,1342242816
 Control6=IDC_STATIC_WARNING_ICON,static,1342177283
 Control7=IDC_STATIC_WARNING_TEXT,static,1342308352
 
index d8d465b..8d0c425 100644 (file)
@@ -1535,12 +1535,13 @@ BEGIN
     LTEXT           "Step 1 - Delta processing",IDC_STATIC,7,7,80,8
     COMBOBOX        IDC_COMBO_DELTA,7,17,214,120,CBS_DROPDOWNLIST | 
                     WS_VSCROLL | WS_TABSTOP
-    LTEXT           "Step 2 - Formula",IDC_STATIC,7,39,52,8
-    EDITTEXT        IDC_EDIT_FORMULA,7,50,214,14,ES_AUTOHSCROLL
-    PUSHBUTTON      "&Create...",IDC_BUTTON_CREATE,171,68,50,14
-    ICON            IDI_SEVERITY_MINOR,IDC_STATIC_WARNING_ICON,7,91,21,20
+    LTEXT           "Step 2 - Transformation Script",IDC_STATIC,7,35,94,8
+    EDITTEXT        IDC_EDIT_FORMULA,7,46,214,99,ES_MULTILINE | 
+                    ES_AUTOHSCROLL | ES_WANTRETURN | WS_VSCROLL | WS_HSCROLL
+    PUSHBUTTON      "&Check...",IDC_BUTTON_CHECK,171,150,50,14
+    ICON            IDI_SEVERITY_MINOR,IDC_STATIC_WARNING_ICON,7,166,20,20
     LTEXT           "WARNING! Delta calculation will produce incorrect results for polling interval less than 60 seconds.",
-                    IDC_STATIC_WARNING_TEXT,33,93,188,18
+                    IDC_STATIC_WARNING_TEXT,33,168,188,18
 END
 
 IDD_CREATE_TG DIALOG DISCARDABLE  0, 0, 229, 126
index a374c69..286bf55 100644 (file)
 #define IDC_COMBO_DELTA                 1163
 #define IDC_EDIT_FORMULA                1164
 #define IDC_BUTTON_CREATE               1166
+#define IDC_BUTTON_CHECK                1166
 #define IDC_EDIT_EVENT                  1167
 #define IDC_POLL_PROGRESS               1169
 #define IDC_EDIT_MSG                    1170
index f462789..6f5505e 100644 (file)
@@ -93,3 +93,31 @@ void NXSL_Environment::RegisterFunctionSet(DWORD dwNumFunctions, NXSL_ExtFunctio
    memcpy(&m_pFunctionList[m_dwNumFunctions], pList, sizeof(NXSL_ExtFunction) * dwNumFunctions);
    m_dwNumFunctions += dwNumFunctions;
 }
+
+
+//
+// Find module by name
+//
+
+BOOL NXSL_Environment::UseModule(NXSL_Program *pMain, TCHAR *pszName)
+{
+   TCHAR *pData, szBuffer[MAX_PATH];
+   DWORD dwSize;
+   NXSL_Program *pScript;
+   BOOL bRet = FALSE;
+
+   _sntprintf(szBuffer, MAX_PATH, "%s.nxsl", pszName);
+   pData = NXSLLoadFile(szBuffer, &dwSize);
+   if (pData != NULL)
+   {
+      pScript = (NXSL_Program *)NXSLCompile(pData, NULL, 0);
+      if (pScript != NULL)
+      {
+         pMain->UseModule(pScript, pszName);
+         delete pScript;
+         bRet = TRUE;
+      }
+      free(pData);
+   }
+   return bRet;
+}
index 633c572..09c85fd 100644 (file)
@@ -73,6 +73,33 @@ NXSL_Instruction::NXSL_Instruction(int nLine, int nOpCode, int nStackItems)
    m_nStackItems = nStackItems;
 }
 
+NXSL_Instruction::NXSL_Instruction(NXSL_Instruction *pSrc)
+{
+   m_nOpCode = pSrc->m_nOpCode;
+   m_nSourceLine = pSrc->m_nSourceLine;
+   m_nStackItems = pSrc->m_nStackItems;
+   switch(m_nOpCode)
+   {
+      case OPCODE_PUSH_CONSTANT:
+         m_operand.m_pConstant = new NXSL_Value(pSrc->m_operand.m_pConstant);
+         break;
+      case OPCODE_PUSH_VARIABLE:
+      case OPCODE_SET:
+      case OPCODE_CALL_EXTERNAL:
+      case OPCODE_BIND:
+      case OPCODE_INC:
+      case OPCODE_DEC:
+      case OPCODE_INCP:
+      case OPCODE_DECP:
+      case OPCODE_REFERENCE:
+         m_operand.m_pszString = strdup(pSrc->m_operand.m_pszString);
+         break;
+      default:
+         m_operand.m_dwAddr = pSrc->m_operand.m_dwAddr;
+         break;
+   }
+}
+
 
 //
 // Destructor
@@ -85,6 +112,12 @@ NXSL_Instruction::~NXSL_Instruction()
       case OPCODE_PUSH_VARIABLE:
       case OPCODE_CALL_EXTERNAL:
       case OPCODE_SET:
+      case OPCODE_BIND:
+      case OPCODE_INC:
+      case OPCODE_DEC:
+      case OPCODE_INCP:
+      case OPCODE_DECP:
+      case OPCODE_REFERENCE:
          safe_free(m_operand.m_pszString);
          break;
       case OPCODE_PUSH_CONSTANT:
index d03140d..0cac127 100644 (file)
@@ -89,6 +89,43 @@ TCHAR LIBNXSL_EXPORTABLE *NXSLGetRuntimeError(NXSL_SCRIPT hScript)
 
 
 //
+// Load file into memory
+//
+
+TCHAR LIBNXSL_EXPORTABLE *NXSLLoadFile(TCHAR *pszFileName, DWORD *pdwFileSize)
+{
+   int fd, iBufPos, iNumBytes, iBytesRead;
+   TCHAR *pBuffer = NULL;
+   struct stat fs;
+
+   fd = open(pszFileName, O_RDONLY | O_BINARY);
+   if (fd != -1)
+   {
+      if (fstat(fd, &fs) != -1)
+      {
+         pBuffer = (TCHAR *)malloc(fs.st_size + 1);
+         if (pBuffer != NULL)
+         {
+            *pdwFileSize = fs.st_size;
+            for(iBufPos = 0; iBufPos < fs.st_size; iBufPos += iBytesRead)
+            {
+               iNumBytes = min(16384, fs.st_size - iBufPos);
+               if ((iBytesRead = read(fd, &pBuffer[iBufPos], iNumBytes)) < 0)
+               {
+                  free(pBuffer);
+                  pBuffer = NULL;
+                  break;
+               }
+            }
+         }
+      }
+      close(fd);
+   }
+   return pBuffer;
+}
+
+
+//
 // DLL entry point
 //
 
index fbeba07..16a2719 100644 (file)
@@ -43,6 +43,7 @@ escape                \\[bnrt0\"]
 <INITIAL>"sub"         return T_SUB;
 <INITIAL>"uint32"      return T_TYPE_UINT32;
 <INITIAL>"uint64"      return T_TYPE_UINT64;
+<INITIAL>"use"         return T_USE;
 <INITIAL>"while"       return T_WHILE;
 
 <INITIAL>{identifier}  { m_plval->valStr = strdup(yytext); return T_IDENTIFIER; }
index 9c95c78..049aa5e 100644 (file)
@@ -51,6 +51,7 @@ int yylex(YYSTYPE *lvalp, NXSL_Lexer *pLexer);
 %token T_TYPE_STRING
 %token T_TYPE_UINT32
 %token T_TYPE_UINT64
+%token T_USE
 %token T_WHILE
 
 %token <valStr> T_IDENTIFIER
@@ -112,6 +113,14 @@ Module:
 
 ModuleComponent:
        Function
+|      UseStatement
+;
+
+UseStatement:
+       T_USE T_IDENTIFIER ';'
+{
+       pScript->AddPreload($2);
+}
 ;
 
 Function:
index e860cc2..5bd54ca 100644 (file)
@@ -28,7 +28,7 @@
 // Constants
 //
 
-#define MAX_ERROR_NUMBER         15
+#define MAX_ERROR_NUMBER         16
 #define CONTROL_STACK_LIMIT      32768
 
 
@@ -71,7 +71,8 @@ static TCHAR *m_szErrorMessage[MAX_ERROR_NUMBER] =
    _T("Invalid number of function's arguments"),
    _T("Cannot do automatic type cast"),
    _T("Left argument of -> must be a reference to object"),
-   _T("Unknown object's attribute")
+   _T("Unknown object's attribute"),
+   _T("Requested module not found or cannot be loaded")
 };
 
 
@@ -141,6 +142,10 @@ NXSL_Program::NXSL_Program(void)
    m_dwSubLevel = 0;    // Level of current subroutine
    m_pEnv = NULL;
    m_pRetValue = NULL;
+   m_dwNumModules = 0;
+   m_pModuleList = NULL;
+   m_dwNumPreloads = 0;
+   m_ppszPreloadList = NULL;
 }
 
 
@@ -167,6 +172,11 @@ NXSL_Program::~NXSL_Program(void)
    delete m_pRetValue;
 
    safe_free(m_pFunctionList);
+   safe_free(m_pModuleList);
+
+   for(i = 0; i < m_dwNumPreloads; i++)
+      safe_free(m_ppszPreloadList[i]);
+   safe_free(m_ppszPreloadList);
 
    safe_free(m_pszErrorText);
 }
@@ -230,6 +240,18 @@ BOOL NXSL_Program::AddFunction(char *pszName, DWORD dwAddr, char *pszError)
 
 
 //
+// Add preload information
+//
+
+void NXSL_Program::AddPreload(char *pszName)
+{
+   m_ppszPreloadList = (char **)realloc(m_ppszPreloadList, sizeof(char *) * (m_dwNumPreloads + 1));
+   m_ppszPreloadList[m_dwNumPreloads] = pszName;
+   m_dwNumPreloads++;
+}
+
+
+//
 // resolve local functions
 //
 
@@ -338,11 +360,15 @@ void NXSL_Program::Error(int nError)
 
 int NXSL_Program::Run(NXSL_Environment *pEnv, DWORD argc, NXSL_Value **argv)
 {
-   DWORD i;
+   DWORD i, dwOrigCodeSize, dwOrigNumFn;
    NXSL_VariableSystem *pSavedGlobals;
    NXSL_Value *pValue;
    char szBuffer[32];
 
+   // Save original code size and number of functions
+   dwOrigCodeSize = m_dwCodeSize;
+   dwOrigNumFn = m_dwNumFunctions;
+
    // Delete previous return value
    delete m_pRetValue;
    m_pRetValue = NULL;
@@ -368,21 +394,34 @@ int NXSL_Program::Run(NXSL_Environment *pEnv, DWORD argc, NXSL_Value **argv)
    // Preserve original global variables
    pSavedGlobals = new NXSL_VariableSystem(m_pGlobals);
 
-   // Locate main()
-   for(i = 0; i < m_dwNumFunctions; i++)
-      if (!strcmp(m_pFunctionList[i].m_szName, "main"))
-         break;
-   if (i < m_dwNumFunctions)
+   // Preload modules
+   for(i = 0; i < m_dwNumPreloads; i++)
    {
-      m_dwCurrPos = m_pFunctionList[i].m_dwAddr;
-      while(m_dwCurrPos < m_dwCodeSize)
-         Execute();
-      if (m_dwCurrPos != INVALID_ADDRESS)
-         m_pRetValue = (NXSL_Value *)m_pDataStack->Pop();
+      if (!pEnv->UseModule(this, m_ppszPreloadList[i]))
+      {
+         Error(NXSL_ERR_MODULE_NOT_FOUND);
+         break;
+      }
    }
-   else
+
+   // Locate main() and run
+   if (i == m_dwNumPreloads)
    {
-      Error(NXSL_ERR_NO_MAIN);
+      for(i = 0; i < m_dwNumFunctions; i++)
+         if (!strcmp(m_pFunctionList[i].m_szName, "main"))
+            break;
+      if (i < m_dwNumFunctions)
+      {
+         m_dwCurrPos = m_pFunctionList[i].m_dwAddr;
+         while(m_dwCurrPos < m_dwCodeSize)
+            Execute();
+         if (m_dwCurrPos != INVALID_ADDRESS)
+            m_pRetValue = (NXSL_Value *)m_pDataStack->Pop();
+      }
+      else
+      {
+         Error(NXSL_ERR_NO_MAIN);
+      }
    }
 
    // Restore global variables
@@ -402,6 +441,15 @@ int NXSL_Program::Run(NXSL_Environment *pEnv, DWORD argc, NXSL_Value **argv)
    delete_and_null(m_pLocals);
    delete_and_null(m_pDataStack);
    delete_and_null(m_pCodeStack);
+   safe_free(m_pModuleList);
+   m_pModuleList = NULL;
+   m_dwNumModules = 0;
+
+   // Restore original code size and number of functions
+   for(i = dwOrigCodeSize; i < m_dwCodeSize; i++)
+      delete m_ppInstructionSet[i];
+   m_dwCodeSize = dwOrigCodeSize;
+   m_dwNumFunctions = dwOrigNumFn;
 
    return (m_dwCurrPos == INVALID_ADDRESS) ? -1 : 0;
 }
@@ -511,35 +559,8 @@ void NXSL_Program::Execute(void)
          }
          break;
       case OPCODE_CALL:
-         if (m_dwSubLevel < CONTROL_STACK_LIMIT)
-         {
-            m_dwSubLevel++;
-            dwNext = cp->m_operand.m_dwAddr;
-            m_pCodeStack->Push((void *)(m_dwCurrPos + 1));
-            m_pCodeStack->Push(m_pLocals);
-            m_pLocals = new NXSL_VariableSystem;
-            m_nBindPos = 1;
-
-            // Bind arguments
-            for(i = cp->m_nStackItems; i > 0; i--)
-            {
-               pValue = (NXSL_Value *)m_pDataStack->Pop();
-               if (pValue != NULL)
-               {
-                  sprintf(szBuffer, "$%d", i);
-                  m_pLocals->Create(szBuffer, pValue);
-               }
-               else
-               {
-                  Error(NXSL_ERR_DATA_STACK_UNDERFLOW);
-                  break;
-               }
-            }
-         }
-         else
-         {
-            Error(NXSL_ERR_CONTROL_STACK_OVERFLOW);
-         }
+         dwNext = cp->m_operand.m_dwAddr;
+         CallFunction(cp->m_nStackItems);
          break;
       case OPCODE_CALL_EXTERNAL:
          pFunc = m_pEnv->FindFunction(cp->m_operand.m_pszString);
@@ -577,7 +598,18 @@ void NXSL_Program::Execute(void)
          }
          else
          {
-            Error(NXSL_ERR_NO_FUNCTION);
+            DWORD dwAddr;
+
+            dwAddr = GetFunctionAddress(cp->m_operand.m_pszString);
+            if (dwAddr != INVALID_ADDRESS)
+            {
+               dwNext = dwAddr;
+               CallFunction(cp->m_nStackItems);
+            }
+            else
+            {
+               Error(NXSL_ERR_NO_FUNCTION);
+            }
          }
          break;
       case OPCODE_RET_NULL:
@@ -1016,3 +1048,122 @@ void NXSL_Program::DoUnaryOperation(int nOpCode)
       Error(NXSL_ERR_DATA_STACK_UNDERFLOW);
    }
 }
+
+
+//
+// Relocate code block
+//
+
+void NXSL_Program::RelocateCode(DWORD dwStart, DWORD dwLen, DWORD dwShift)
+{
+   DWORD i, dwLast;
+
+   dwLast = min(dwStart + dwLen, m_dwCodeSize);
+   for(i = dwStart; i < dwLast; i++)
+      if ((m_ppInstructionSet[i]->m_nOpCode == OPCODE_JMP) ||
+          (m_ppInstructionSet[i]->m_nOpCode == OPCODE_JZ) ||
+          (m_ppInstructionSet[i]->m_nOpCode == OPCODE_JNZ) ||
+          (m_ppInstructionSet[i]->m_nOpCode == OPCODE_CALL))
+      {
+         m_ppInstructionSet[i]->m_operand.m_dwAddr += dwShift;
+      }
+}
+
+
+//
+// Use external module
+//
+
+void NXSL_Program::UseModule(NXSL_Program *pModule, char *pszName)
+{
+   DWORD i, j, dwStart;
+
+   // Check if module already loaded
+   for(i = 0; i < m_dwNumModules; i++)
+      if (!stricmp(pszName, m_pModuleList[i].m_szName))
+         return;  // Already loaded
+
+   // Add code from module
+   dwStart = m_dwCodeSize;
+   m_dwCodeSize += pModule->m_dwCodeSize;
+   m_ppInstructionSet = (NXSL_Instruction **)realloc(m_ppInstructionSet,
+         sizeof(NXSL_Instruction *) * m_dwCodeSize);
+   for(i = dwStart, j = 0; i < m_dwCodeSize; i++, j++)
+      m_ppInstructionSet[i] = new NXSL_Instruction(pModule->m_ppInstructionSet[j]);
+   RelocateCode(dwStart, pModule->m_dwCodeSize, dwStart);
+   
+   // Add function names from module
+   m_pFunctionList = (NXSL_Function *)realloc(m_pFunctionList,
+         sizeof(NXSL_Function) * (m_dwNumFunctions + pModule->m_dwNumFunctions));
+   memcpy(&m_pFunctionList[m_dwNumFunctions], pModule->m_pFunctionList,
+          sizeof(NXSL_Function) * pModule->m_dwNumFunctions);
+   for(i = m_dwNumFunctions, j = 0; j < pModule->m_dwNumFunctions; i++, j++)
+      m_pFunctionList[i].m_dwAddr += dwStart;
+
+   // Register module as loaded
+   m_pModuleList = (NXSL_Module *)malloc(sizeof(NXSL_Module) * (m_dwNumModules + 1));
+   strncpy(m_pModuleList[m_dwNumModules].m_szName, pszName, MAX_PATH);
+   m_pModuleList[m_dwNumModules].m_dwCodeStart = dwStart;
+   m_pModuleList[m_dwNumModules].m_dwCodeSize = pModule->m_dwCodeSize;
+   m_pModuleList[m_dwNumModules].m_dwFunctionStart = m_dwNumFunctions;
+   m_pModuleList[m_dwNumModules].m_dwNumFunctions = pModule->m_dwNumFunctions;
+   m_dwNumModules++;
+
+   m_dwNumFunctions += pModule->m_dwNumFunctions;
+}
+
+
+//
+// Call function at given address
+//
+
+void NXSL_Program::CallFunction(int nArgCount)
+{
+   int i;
+   NXSL_Value *pValue;
+   char szBuffer[32];
+
+   if (m_dwSubLevel < CONTROL_STACK_LIMIT)
+   {
+      m_dwSubLevel++;
+      m_pCodeStack->Push((void *)(m_dwCurrPos + 1));
+      m_pCodeStack->Push(m_pLocals);
+      m_pLocals = new NXSL_VariableSystem;
+      m_nBindPos = 1;
+
+      // Bind arguments
+      for(i = nArgCount; i > 0; i--)
+      {
+         pValue = (NXSL_Value *)m_pDataStack->Pop();
+         if (pValue != NULL)
+         {
+            sprintf(szBuffer, "$%d", i);
+            m_pLocals->Create(szBuffer, pValue);
+         }
+         else
+         {
+            Error(NXSL_ERR_DATA_STACK_UNDERFLOW);
+            break;
+         }
+      }
+   }
+   else
+   {
+      Error(NXSL_ERR_CONTROL_STACK_OVERFLOW);
+   }
+}
+
+
+//
+// Find function address by name
+//
+
+DWORD NXSL_Program::GetFunctionAddress(char *pszName)
+{
+   DWORD i;
+
+   for(i = 0; i < m_dwNumFunctions; i++)
+      if (!strcmp(m_pFunctionList[i].m_szName, pszName))
+         return m_pFunctionList[i].m_dwAddr;
+   return INVALID_ADDRESS;
+}
index 15669b0..c3edea5 100644 (file)
 static NXSL_TestClass *m_pTestClass;
 
 
-static char *LoadFile(char *pszFileName, DWORD *pdwFileSize)
-{
-   int fd, iBufPos, iNumBytes, iBytesRead;
-   char *pBuffer = NULL;
-   struct stat fs;
-
-   fd = open(pszFileName, O_RDONLY | O_BINARY);
-   if (fd != -1)
-   {
-      if (fstat(fd, &fs) != -1)
-      {
-         pBuffer = (char *)malloc(fs.st_size + 1);
-         if (pBuffer != NULL)
-         {
-            *pdwFileSize = fs.st_size;
-            for(iBufPos = 0; iBufPos < fs.st_size; iBufPos += iBytesRead)
-            {
-               iNumBytes = min(16384, fs.st_size - iBufPos);
-               if ((iBytesRead = read(fd, &pBuffer[iBufPos], iNumBytes)) < 0)
-               {
-                  free(pBuffer);
-                  pBuffer = NULL;
-                  break;
-               }
-            }
-         }
-      }
-      close(fd);
-   }
-   return pBuffer;
-}
-
-
 int F_new(int argc, NXSL_Value **argv, NXSL_Value **ppResult)
 {
    *ppResult = new NXSL_Value(new NXSL_Object(m_pTestClass, NULL));
@@ -96,7 +63,7 @@ int main(int argc, char *argv[])
       return 127;
    }
 
-   pszSource = LoadFile(argv[1], &dwSize);
+   pszSource = NXSLLoadFile(argv[1], &dwSize);
    pScript = (NXSL_Program *)NXSLCompile(pszSource, szError, 1024);
    if (pScript != NULL)
    {