]> granicus.if.org Git - php/commitdiff
Improve stability.
authorWez Furlong <wez@php.net>
Tue, 4 May 2004 14:54:01 +0000 (14:54 +0000)
committerWez Furlong <wez@php.net>
Tue, 4 May 2004 14:54:01 +0000 (14:54 +0000)
Give it a new CLSID and change the engine name to ActivePHP5.
Globals registered by the scripting host are now auto-globals and don't
need to be declared global when accessed from within functions.

sapi/activescript/README
sapi/activescript/classfactory.cpp
sapi/activescript/php5activescript.c
sapi/activescript/php5as_classfactory.h
sapi/activescript/php5as_scriptengine.h
sapi/activescript/scriptengine.cpp

index 70f49821d879d3719ddb37e2a00778ce5ee0f13c..39066f578362b9de05b78898eb846a4f9984eb83 100644 (file)
@@ -26,7 +26,7 @@ Usage.
 
 o. Client-side script in Internet Explorer
 
-  <script language="ActivePHP">
+  <script language="ActivePHP5">
        $window->alert("Hello");
   </script>
 
@@ -35,22 +35,22 @@ o. Windows Script Host
   Create a .wsf file like this:
 
   <job id="test">
-    <script language="ActivePHP">
+    <script language="ActivePHP5">
          $WScript->Echo("Hello");
        </script>
   </script>
 
 o. ASP and ASP.NET
 
-  <%@language=ActivePHP %>
+  <%@language=ActivePHP5 %>
   <% $Response->Write("Hello"); %>
 
 o. Windows Script Components / Behaviours
 
-  Use language="ActivePHP" on your <script> tags
+  Use language="ActivePHP5" on your <script> tags
 
 o. MS Scriptlet control
 
-  Set the language property to "ActivePHP"
+  Set the language property to "ActivePHP5"
 
 
index ecdd6f63a3d125d0fa3463d6e118f3bcc85c39f2..698a052cd22e06520761aa55a40b347052c069f3 100644 (file)
@@ -145,10 +145,10 @@ static const struct reg_entry engine_entries[] = {
        { HKEY_CLASSES_ROOT,    "CLSID\\[CLSID]\\InprocServer32",       NULL,                           "[MODULENAME]" },
        { HKEY_CLASSES_ROOT,    "CLSID\\[CLSID]\\InprocServer32",       "ThreadingModel",       "[THREADING]" },
        { HKEY_CLASSES_ROOT,    "CLSID\\[CLSID]\\OLEScript",            NULL,                           NULL },
-       { HKEY_CLASSES_ROOT,    "CLSID\\[CLSID]\\ProgID",                       NULL,                           "ActivePHP" },
-       { HKEY_CLASSES_ROOT,    "ActivePHP",                                            NULL,                           "ActivePHP" },
-       { HKEY_CLASSES_ROOT,    "ActivePHP\\CLSID",                                     NULL,                           "[CLSID]"},
-       { HKEY_CLASSES_ROOT,    "ActivePHP\\OLEScript",                         NULL,                           NULL},
+       { HKEY_CLASSES_ROOT,    "CLSID\\[CLSID]\\ProgID",                       NULL,                           "ActivePHP5" },
+       { HKEY_CLASSES_ROOT,    "ActivePHP5",                                           NULL,                           "ActivePHP5" },
+       { HKEY_CLASSES_ROOT,    "ActivePHP5\\CLSID",                            NULL,                           "[CLSID]"},
+       { HKEY_CLASSES_ROOT,    "ActivePHP5\\OLEScript",                        NULL,                           NULL},
        
        { 0, NULL, NULL, NULL }
 };
index 6aa4b414953428dc2c1062551775c16746ca2839..93222fdbf86ddd7fb135723b815d7e739b81c3a2 100644 (file)
@@ -127,7 +127,7 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
                case DLL_PROCESS_ATTACH:
                        module_handle = hinstDLL;
 
-                       tsrm_startup(128, 1, TSRM_ERROR_LEVEL_CORE, "C:\\TSRM.log");
+                       tsrm_startup(128, 32, TSRM_ERROR_LEVEL_CORE, "C:\\TSRM.log");
 
                        sapi_startup(&activescript_sapi_module);
                        if (activescript_sapi_module.startup) {
@@ -137,12 +137,14 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
                case DLL_THREAD_ATTACH:
                        break;
                case DLL_THREAD_DETACH:
+                       //OutputDebugString("THREAD_DETACH\n");
                        ts_free_thread();
                        break;
                case DLL_PROCESS_DETACH:
                        if (activescript_sapi_module.shutdown) {
                                activescript_sapi_module.shutdown(&sapi_module);
                        }
+                       //OutputDebugString("PROCESS_DETACH\n");
                        tsrm_shutdown();
                        break;
        }
index 2f1695fa0cfc11af340296f71ab5afaef0b438a4..61823fb689d5246752627b3b063c5ee696bf024b 100644 (file)
 
 #include <unknwn.h>
 
+// {CF108A38-59A9-468a-AF45-1368D7855DAE}
+DEFINE_GUID(CLSID_PHPActiveScriptEngine,
+0xcf108a38, 0x59a9, 0x468a, 0xaf, 0x45, 0x13, 0x68, 0xd7, 0x85, 0x5d, 0xae);
+
+#if 0
+/* this was for PHP 4 */
 // {A0AD8E7A-95EC-4819-986F-78D93895F2AE}
 DEFINE_GUID(CLSID_PHPActiveScriptEngine, 
 0xa0ad8e7a, 0x95ec, 0x4819, 0x98, 0x6f, 0x78, 0xd9, 0x38, 0x95, 0xf2, 0xae);
+#endif
 
 class TPHPClassFactory:
        public IClassFactory
index fd5fd522a8a0dff569e5757f51346e572ff40803..6e9a06ff46ee4016a25a84823847b361ac2dfce4 100644 (file)
@@ -18,6 +18,7 @@
 /* $Id$ */
 
 #include <activscp.h>
+#include <objsafe.h>
 #include "zend.h"
 #include <setjmp.h>
 
@@ -106,6 +107,9 @@ class TPHPScriptingEngine:
        public IActiveScript,
        public IActiveScriptParse,
        public IActiveScriptParseProcedure
+#if ACTIVEPHP_OBJECT_SAFETY
+       , public IObjectSafety
+#endif
 {
 public:
        volatile LONG m_refcount;
@@ -227,6 +231,20 @@ public: /* IActiveScriptParseProcedure */
                /* [in] */ ULONG ulStartingLineNumber,
                /* [in] */ DWORD dwFlags,
                /* [out] */ IDispatch **ppdisp);
+
+#if ACTIVEPHP_OBJECT_SAFETY
+public: /* IObjectSafety */
+       STDMETHODIMP GetInterfaceSafetyOptions(
+               /* [in]  */ REFIID      riid,                                           // Interface that we want options for
+               /* [out] */ DWORD       *pdwSupportedOptions,           // Options meaningful on this interface
+               /* [out] */ DWORD       *pdwEnabledOptions);            // current option values on this interface
+
+       STDMETHODIMP SetInterfaceSafetyOptions(
+               /* [in]  */ REFIID              riid,                                   // Interface to set options for
+               /* [in]  */ DWORD               dwOptionSetMask,                // Options to change
+               /* [in]  */ DWORD               dwEnabledOptions);              // New option values
+#endif
+       
 public:
        TPHPScriptingEngine();
        ~TPHPScriptingEngine();
index 7853af163711428e3627e3957303002ba1150693..9906ca14901c1e69e14878fa671ebbc43ccb9951 100644 (file)
@@ -50,6 +50,9 @@ extern "C" {
 #include "php5as_scriptengine.h"
 #include "php5as_classfactory.h"
 #include <objbase.h>
+#undef php_win_err
+
+#define ACTIVEPHP_THREADING_MODE       COINIT_MULTITHREADED
 
 /* {{{ trace */
 static inline void trace(char *fmt, ...)
@@ -651,7 +654,6 @@ TPHPScriptingEngine::TPHPScriptingEngine()
        TPHPClassFactory::AddToObjectCount();
        
        m_engine_thread_handle = CreateThread(NULL, 0, begin_engine_thread, this, 0, &m_enginethread);
-       CloseHandle(m_engine_thread_handle);
 }
 
 void activescript_run_ticks(int count)
@@ -733,10 +735,14 @@ HRESULT TPHPScriptingEngine::SendThreadMessage(LONG msg, WPARAM wparam, LPARAM l
 TPHPScriptingEngine::~TPHPScriptingEngine()
 {
        trace("\n\n *** Engine Destructor Called\n\n");
-       if (m_scriptstate != SCRIPTSTATE_UNINITIALIZED && m_scriptstate != SCRIPTSTATE_CLOSED && m_enginethread)
-               Close();
 
+       if (m_scriptstate != SCRIPTSTATE_UNINITIALIZED && m_scriptstate != SCRIPTSTATE_CLOSED && m_enginethread) {
+               Close();
+       }
+               
        PostThreadMessage(m_enginethread, WM_QUIT, 0, 0);
+       WaitForSingleObject(m_engine_thread_handle, INFINITE);
+       CloseHandle(m_engine_thread_handle);
 
        TPHPClassFactory::RemoveFromObjectCount();
        tsrm_mutex_free(m_mutex);
@@ -851,6 +857,8 @@ HRESULT TPHPScriptingEngine::engine_thread_handler(LONG msg, WPARAM wparam, LPAR
                                /* Prepare PHP/ZE for use */
 
                                trace("%08x: m_frags : INIT NEW\n", this);
+
+#if 0
                                zend_hash_init(&m_frags, 0, NULL, frag_dtor, TRUE);
 
                                SG(options) |= SAPI_OPTION_NO_CHDIR;
@@ -865,8 +873,9 @@ HRESULT TPHPScriptingEngine::engine_thread_handler(LONG msg, WPARAM wparam, LPAR
 
                                php_request_startup(TSRMLS_C);
                                PG(during_request_startup) = 0;
-                               trace("\n\n     *** ticks func at %08x %08x ***\n\n\n", activescript_run_ticks, &activescript_run_ticks);
+//                             trace("\n\n     *** ticks func at %08x %08x ***\n\n\n", activescript_run_ticks, &activescript_run_ticks);
 //                             php_add_tick_function(activescript_run_ticks);
+#endif
 
                        }
                        break;
@@ -881,8 +890,10 @@ HRESULT TPHPScriptingEngine::engine_thread_handler(LONG msg, WPARAM wparam, LPAR
                                        m_pass_eng->Release();
                                        m_pass_eng = NULL;
                                }
+#if 0
                                zend_hash_destroy(&m_frags);
                                php_request_shutdown(NULL);
+#endif
 
                                break;
                        }
@@ -998,7 +1009,7 @@ HRESULT TPHPScriptingEngine::engine_thread_handler(LONG msg, WPARAM wparam, LPAR
                        {
                                struct php_active_script_get_dispatch_info *info = (struct php_active_script_get_dispatch_info *)lParam;
                                IDispatch *disp = NULL;
-
+                               
                                if (info->pstrItemName != NULL) {
                                        zval **tmp;
                                        /* use this rather than php_OLECHAR_to_char because we want to avoid emalloc here */
@@ -1025,8 +1036,10 @@ HRESULT TPHPScriptingEngine::engine_thread_handler(LONG msg, WPARAM wparam, LPAR
                                if (disp) {
                                        ret = GIT_put(disp, IID_IDispatch, &info->dispatch);
                                        disp->Release();
+                                       trace("GET_DISPATCH: we put it in the GIT\n");
                                } else {
                                        ret = S_FALSE;
+                                       trace("GET_DISPATCH: FAILED to put it in the GIT\n");
                                }
                        }
                        break;
@@ -1039,10 +1052,22 @@ HRESULT TPHPScriptingEngine::engine_thread_handler(LONG msg, WPARAM wparam, LPAR
                                struct php_active_script_add_named_item_info *info = (struct php_active_script_add_named_item_info *)lParam;
 
                                TWideString name(info->pstrName);
-                               IDispatch *disp;
-                               
-                               if (SUCCEEDED(GIT_get(info->marshal, IID_IDispatch, (void**)&disp))) 
+                               IDispatch *disp = NULL;
+                               HRESULT res;
+                       
+                               trace("ADD_NAMED_ITEM\n");
+
+#if ACTIVEPHP_THREADING_MODE == COINIT_MULTITHREADED
+                               res = info->punk->QueryInterface(IID_IDispatch, (void**)&disp);
+#else
+                               res = GIT_get(info->marshal, IID_IDispatch, (void**)&disp);
+#endif
+                               if (SUCCEEDED(res) && disp) {
                                        add_to_global_namespace(disp, info->dwFlags, name.ansi_string() TSRMLS_CC);
+                                       disp->Release();
+                               } else {
+                                       trace("Ouch: failed to get IDispatch for %s from GIT '%s'\n", name.ansi_string(), php_win_err(res));
+                               }
 
                        }
                        break;
@@ -1178,7 +1203,7 @@ HRESULT TPHPScriptingEngine::engine_thread_handler(LONG msg, WPARAM wparam, LPAR
                        }
                        break;
                default:
-                       trace("unhandled message type %08x\n", msg);
+                       trace("XXXXX: unhandled message type %08x\n", msg);
                        if (handled)
                                *handled = 0;
        }
@@ -1195,55 +1220,86 @@ void TPHPScriptingEngine::engine_thread_func(void)
 
        trace("%08x: engine thread started up!\n", this);
 
-       CoInitializeEx(0, COINIT_MULTITHREADED);
+       CoInitializeEx(0, ACTIVEPHP_THREADING_MODE);
        
-       m_tsrm_hack = tsrm_ls;
+       zend_first_try {
+               m_tsrm_hack = tsrm_ls;
+
+               SG(options) |= SAPI_OPTION_NO_CHDIR;
+               SG(headers_sent) = 1;
+               SG(request_info).no_headers = 1;
+
+               SG(server_context) = this;
+               /* override the default PHP error callback */
+               zend_error_cb = activescript_error_handler;
+
+               zend_alter_ini_entry("register_argc_argv", 19, "1", 1, PHP_INI_SYSTEM, PHP_INI_STAGE_ACTIVATE);
+               zend_alter_ini_entry("html_errors", 12, "0", 1, PHP_INI_SYSTEM, PHP_INI_STAGE_ACTIVATE);
+               zend_alter_ini_entry("implicit_flush", 15, "1", 1, PHP_INI_SYSTEM, PHP_INI_STAGE_ACTIVATE);
+               zend_alter_ini_entry("max_execution_time", 19, "0", 1, PHP_INI_SYSTEM, PHP_INI_STAGE_ACTIVATE);
+
+               if (SUCCESS == php_request_startup(TSRMLS_C)) {
+                       PG(during_request_startup) = 0;
+                       if (FAILURE == zend_hash_init(&m_frags, 0, NULL, frag_dtor, 1)) {
+                               trace("failed to init frags hash\n");
+                       }
 
-       while(!terminated) {
-               DWORD result = MsgWaitForMultipleObjects(0, NULL, FALSE, 4000, QS_ALLINPUT);
+                       while(!terminated) {
+                               DWORD result = MsgWaitForMultipleObjects(0, NULL, FALSE, 4000, QS_ALLINPUT);
 
-               switch(result) {
-                       case WAIT_OBJECT_0:
-                               while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
+                               switch(result) {
+                                       case WAIT_OBJECT_0:
+                                               while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
 
-                                       if (msg.message == WM_QUIT) {
-                                               terminated = 1;
-                                       } else if (msg.hwnd) {
-                                               TranslateMessage(&msg);
-                                               DispatchMessage(&msg);
+                                                       if (msg.message == WM_QUIT) {
+                                                               terminated = 1;
+                                                       } else if (msg.hwnd) {
+                                                               TranslateMessage(&msg);
+                                                               DispatchMessage(&msg);
 
-                                       } else {
-                                               handled = 1;
-                                               m_sync_thread_ret = engine_thread_handler(msg.message, msg.wParam, msg.lParam, &handled TSRMLS_CC);
-                                               if (handled)
-                                                       SetEvent(m_sync_thread_msg);
-                                       }
+                                                       } else {
+                                                               handled = 1;
+                                                               m_sync_thread_ret = engine_thread_handler(msg.message, msg.wParam, msg.lParam, &handled TSRMLS_CC);
+                                                               if (handled)
+                                                                       SetEvent(m_sync_thread_msg);
+                                                       }
 
+                                               }
+                                               break;
+                                       case WAIT_TIMEOUT:
+                                               trace("thread wait timed out\n");
+                                               break;
+                                       default:
+                                               trace("some strange value\n");
                                }
-                               break;
-                       case WAIT_TIMEOUT:
-                               trace("thread wait timed out\n");
-                               break;
-                       default:
-                               trace("some strange value\n");
-               }
-       }
-       
+                       }
+
 #if 0
-       while(GetMessage(&msg, NULL, 0, 0)) {
+                       while(GetMessage(&msg, NULL, 0, 0)) {
 
-               if (msg.message == WM_QUIT)
-                       break;
-               
-               handled = 1;
-               m_sync_thread_ret = engine_thread_handler(msg.message, msg.wParam, msg.lParam, &handled TSRMLS_CC);
-               if (handled)
-                       SetEvent(m_sync_thread_msg);
-       }
-       trace("%08x: engine thread exiting!!!!!\n", this);
+                               if (msg.message == WM_QUIT)
+                                       break;
+
+                               handled = 1;
+                               m_sync_thread_ret = engine_thread_handler(msg.message, msg.wParam, msg.lParam, &handled TSRMLS_CC);
+                               if (handled)
+                                       SetEvent(m_sync_thread_msg);
+                       }
 #endif
-       m_enginethread = 0;
 
+                       trace("%08x: engine thread exiting!!!!!\n", this);
+                       zend_hash_destroy(&m_frags);
+                       trace("calling request shutdown\n");
+                       php_request_shutdown(NULL);
+               } else {
+                       trace("request startup failed\n");
+               }
+
+       } zend_catch {
+               trace("ouch: bailed out\n");
+       } zend_end_try();
+       
+       m_enginethread = 0;
        CoUninitialize();
 }
 
@@ -1255,6 +1311,16 @@ void TPHPScriptingEngine::engine_thread_func(void)
  *
  * TODO: evaluate if it is appropriate to register as an auto_global
  * */
+
+static inline void make_auto_global(char *name, zval *val TSRMLS_DC)
+{
+       int namelen = strlen(name);
+
+       zend_register_auto_global(name, namelen, NULL TSRMLS_CC);
+       zend_auto_global_disable_jit(name, namelen TSRMLS_CC);
+       ZEND_SET_SYMBOL(&EG(symbol_table), name, val);
+}
+
 void TPHPScriptingEngine::add_to_global_namespace(IDispatch *disp, DWORD flags, char *name TSRMLS_DC)
 {
        zval *val;
@@ -1271,6 +1337,7 @@ void TPHPScriptingEngine::add_to_global_namespace(IDispatch *disp, DWORD flags,
 
 trace("Add %s to global namespace\n", name);
        
+       MAKE_STD_ZVAL(val);
        php_com_wrap_dispatch(val, disp, CP_ACP TSRMLS_CC);
        
        if (val == NULL) {
@@ -1278,7 +1345,7 @@ trace("Add %s to global namespace\n", name);
                return;
        }
 
-       ZEND_SET_SYMBOL(&EG(symbol_table), name, val);
+       make_auto_global(name, val TSRMLS_CC);
 
        if ((flags & SCRIPTITEM_GLOBALMEMBERS) == 0) {
                disp->Release();
@@ -1329,10 +1396,12 @@ trace("Add %s to global namespace\n", name);
 
                                                                /* add to namespace */
                                                                zval *subval;
+
+                                                               MAKE_STD_ZVAL(subval);
                                                                
                                                                php_com_wrap_dispatch(subval, sub, CP_ACP TSRMLS_CC);
                                                                if (subval) {
-                                                                       ZEND_SET_SYMBOL(&EG(symbol_table), name, subval);       
+                                                                       make_auto_global(name, subval TSRMLS_CC);
                                                                }
 
                                                                efree(name);
@@ -1377,6 +1446,10 @@ STDMETHODIMP TPHPScriptingEngine::QueryInterface(REFIID iid, void **ppvObject)
                *ppvObject = (IActiveScriptParse*)this;
        } else if (IsEqualGUID(IID_IActiveScriptParseProcedure, iid)) {
                *ppvObject = (IActiveScriptParseProcedure*)this;
+#if ACTIVEPHP_OBJECT_SAFETY
+       } else if (IsEqualGUID(IID_IObjectSafety, iid)) {
+               *ppvObject = (IObjectSafety*)this;
+#endif
        } else if (IsEqualGUID(IID_IUnknown, iid)) {
                *ppvObject = this;      
        } else {
@@ -1486,16 +1559,38 @@ STDMETHODIMP TPHPScriptingEngine::Close(void)
 STDMETHODIMP TPHPScriptingEngine::AddNamedItem(LPCOLESTR pstrName, DWORD dwFlags)
 {
        struct php_active_script_add_named_item_info info;
+       HRESULT res;
        TSRMLS_FETCH();
 
        info.pstrName = pstrName;
        info.dwFlags = dwFlags;
 
-       m_pass->GetItemInfo(pstrName, SCRIPTINFO_IUNKNOWN, &info.punk, NULL);
-       if (SUCCEEDED(GIT_put(info.punk, IID_IDispatch, &info.marshal))) {
+       res = m_pass->GetItemInfo(pstrName, SCRIPTINFO_IUNKNOWN, &info.punk, NULL);
+
+       if (SUCCEEDED(res)) {
+#if ACTIVEPHP_THREADING_MODE == COINIT_MULTITHREADED
+               /* strangely, the GIT doesn't want to give the engine thread the interface
+                * in this threading mode */
                SEND_THREAD_MESSAGE(this, PHPSE_ADD_NAMED_ITEM, 0, (LPARAM)&info TSRMLS_CC);
+#else
+               IDispatch *disp;
+               res = info.punk->QueryInterface(IID_IDispatch, (void**)&disp);
+               
+               if (SUCCEEDED(res) && disp) {
+                       if (SUCCEEDED(GIT_put(disp, IID_IDispatch, &info.marshal))) {
+                               trace("put disp=%p into git with marshal ID of %x\n", disp, info.marshal);
+                               SEND_THREAD_MESSAGE(this, PHPSE_ADD_NAMED_ITEM, 0, (LPARAM)&info TSRMLS_CC);
+                               GIT_revoke(info.marshal, disp);
+                       }
+                       disp->Release();
+               } else {
+                       trace("failed to get IDispatch from punk %s", php_win_err(res));
+               }
+               info.punk->Release();
+#endif
+       } else {
+               trace("failed to get named item, %s", php_win_err(res));
        }
-       info.punk->Release();
        
        return S_OK;
 }
@@ -1545,7 +1640,9 @@ STDMETHODIMP TPHPScriptingEngine::GetScriptDispatch(
         * This is "safe" only in this instance, since we are not modifying
         * the engine state by looking up the dispatch (I hope).
         * The scripting engine rules pretty much guarantee that this
-        * method is only called in the base thread. */
+        * method is only called in the base thread.
+        * This appears to only happen when we set the threading to
+        * apartment. */
 
        if (tsrm_thread_id() != m_enginethread) {
                tsrm_ls = m_tsrm_hack;
@@ -1748,6 +1845,31 @@ STDMETHODIMP TPHPScriptingEngine::ParseProcedureText(
        return ret;
 }
 
+#if ACTIVEPHP_OBJECT_SAFETY
+STDMETHODIMP TPHPScriptingEngine::GetInterfaceSafetyOptions(
+               /* [in]  */ REFIID      riid,                                           // Interface that we want options for
+               /* [out] */ DWORD       *pdwSupportedOptions,           // Options meaningful on this interface
+               /* [out] */ DWORD       *pdwEnabledOptions)                     // current option values on this interface
+{
+       /* PHP isn't really safe for untrusted anything */
+       *pdwSupportedOptions = 0;
+       *pdwEnabledOptions = 0;
+       return S_OK;
+}
+
+STDMETHODIMP TPHPScriptingEngine::SetInterfaceSafetyOptions(
+               /* [in]  */ REFIID              riid,                                   // Interface to set options for
+               /* [in]  */ DWORD               dwOptionSetMask,                // Options to change
+               /* [in]  */ DWORD               dwEnabledOptions)               // New option values
+{
+       /* PHP isn't really safe for untrusted anything */
+       if (dwEnabledOptions == 0) {
+               return S_OK;
+       }
+       return E_FAIL;
+}
+#endif
+       
 extern "C" 
 void activescript_error_func(int type, const char *error_msg, ...)
 {