⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 scriptengine.cpp

📁 php-4.4.7学习linux时下载的源代码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
					if (info->pstrItemName) {						strcat(sname, item_name.ansi_string());						strcat(sname, "_");					}					if (info->pstrSubItemName) {						strcat(sname, sub_item_name.ansi_string());						strcat(sname, "_");					}					if (info->pstrEventName)						strcat(sname, event_name.ansi_string());				}				trace("%08x: AddScriptlet:\n state=%s\n name=%s\n code=%s\n item=%s\n subitem=%s\n event=%s\n delim=%s\n line=%d\n",						this, scriptstate_to_string(m_scriptstate),						default_name.safe_ansi_string(), code.safe_ansi_string(), item_name.safe_ansi_string(),						sub_item_name.safe_ansi_string(), event_name.safe_ansi_string(), delimiter.safe_ansi_string(),						info->ulStartingLineNumber);				code_frag *frag = compile_code_fragment(						FRAG_SCRIPTLET,						sname,						info->pstrCode,						info->ulStartingLineNumber,						info->pexcepinfo,						this						TSRMLS_CC);				if (frag) {					frag->persistent = (info->dwFlags & SCRIPTTEXT_ISPERSISTENT);					zend_hash_next_index_insert(&m_frags, &frag, sizeof(code_frag*), NULL);					/*					   ScriptProcedureDispatch *disp = new ScriptProcedureDispatch;					   disp->AddRef();					   disp->m_frag = frag;					   disp->m_procflags = info->dwFlags;					   disp->m_engine = this;					   frag->ptr = disp;					 *info->ppdisp = disp;					 */					ret = S_OK;				} else {					ret = DISP_E_EXCEPTION;				}				*info->pbstrName = TWideString::bstr_from_ansi(sname);				trace("%08x: done with scriptlet %s\n", this, sname);			}			break;		case PHPSE_GET_DISPATCH:			{				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 */					TWideString itemname(info->pstrItemName);										/* Get that item from the global namespace.					 * If it is an object, export it as a dispatchable object.					 * */					if (zend_hash_find(&EG(symbol_table), itemname.ansi_string(),								itemname.ansi_len() + 1, (void**)&tmp) == SUCCESS) {						if (Z_TYPE_PP(tmp) == IS_OBJECT) {							/* FIXME: if this causes an allocation (emalloc) and we are							 * not in the engine thread, things could get ugly!!! */							disp = php_COM_export_object(*tmp TSRMLS_CC);						}					}				} else {					/* This object represents PHP global namespace */					disp = (IDispatch*) new ScriptDispatch;				}				if (disp) {					ret = GIT_put(disp, IID_IDispatch, &info->dispatch);					disp->Release();				} else {					ret = S_FALSE;				}			}			break;		case PHPSE_ADD_NAMED_ITEM:			{				/* The Host uses this to add objects to the global namespace.				 * Some objects are intended to have their child properties				 * globally visible, so we add those to the global namespace too.				 * */				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))) 					add_to_global_namespace(disp, info->dwFlags, name.ansi_string() TSRMLS_CC);			}			break;		case PHPSE_SET_SITE:			{				if (m_pass_eng) {					m_pass_eng->Release();					m_pass_eng = NULL;				}				if (lParam)					GIT_get(lParam, IID_IActiveScriptSite, (void**)&m_pass_eng);				trace("%08x: site (engine-side) is now %08x (base=%08x)\n", this, m_pass_eng, m_pass);			}			break;		case PHPSE_EXEC_PROC:			{				ScriptProcedureDispatch *disp = (ScriptProcedureDispatch *)lParam;				execute_code_fragment(disp->m_frag, NULL, NULL TSRMLS_CC);			}			break;		case PHPSE_PARSE_PROC:			{				/* This is the IActiveScriptParseProcedure implementation.				 * IE uses this to request for an IDispatch that it will invoke in				 * response to some event, and tells us the code that it wants to				 * run.				 * We compile the code and pass it back a dispatch object.				 * The object will then serialize access to the engine thread and				 * execute the opcodes */				struct php_active_script_parse_proc_info *info = (struct php_active_script_parse_proc_info*)lParam;				TWideString					formal_params(info->pstrFormalParams),					procedure_name(info->pstrProcedureName),					item_name(info->pstrItemName),					delimiter(info->pstrDelimiter);				trace("%08x: ParseProc:\n state=%s\nparams=%s\nproc=%s\nitem=%s\n delim=%s\n line=%d\n",						this, scriptstate_to_string(m_scriptstate),						formal_params.ansi_string(), procedure_name.ansi_string(),						item_name.safe_ansi_string(), delimiter.safe_ansi_string(),						info->ulStartingLineNumber);				code_frag *frag = compile_code_fragment(						FRAG_PROCEDURE,						NULL,						info->pstrCode,						info->ulStartingLineNumber,						NULL,						this						TSRMLS_CC);				if (frag) {					frag->persistent = (info->dwFlags & SCRIPTTEXT_ISPERSISTENT);					zend_hash_next_index_insert(&m_frags, &frag, sizeof(code_frag*), NULL);					ScriptProcedureDispatch *disp = new ScriptProcedureDispatch;					disp->m_frag = frag;					disp->m_procflags = info->dwFlags;					disp->m_engine = this;					frag->ptr = disp;					info->dispcookie = disp->m_gitcookie;				} else {					ret = DISP_E_EXCEPTION;				}			}			break;		case PHPSE_PARSE_SCRIPT:			{				struct php_active_script_parse_info *info = (struct php_active_script_parse_info*)lParam;				int doexec;				TWideString					code(info->pstrCode),				item_name(info->pstrItemName),				delimiter(info->pstrDelimiter);				trace("%08x: ParseScriptText:\n state=%s\ncode=%s\n item=%s\n delim=%s\n line=%d\n",						this, scriptstate_to_string(m_scriptstate),						code.safe_ansi_string(), item_name.safe_ansi_string(), delimiter.safe_ansi_string(),						info->ulStartingLineNumber);				code_frag *frag = compile_code_fragment(						FRAG_MAIN,						info->dwFlags & SCRIPTTEXT_ISEXPRESSION ? FRAG_CREATE_FUNC : NULL,						info->pstrCode,						info->ulStartingLineNumber,						info->pexcepinfo,						this						TSRMLS_CC);				doexec = (info->dwFlags & SCRIPTTEXT_ISEXPRESSION) ||					m_scriptstate == SCRIPTSTATE_STARTED ||					m_scriptstate == SCRIPTSTATE_CONNECTED ||					m_scriptstate == SCRIPTSTATE_DISCONNECTED;				if (frag) {					frag->persistent = (info->dwFlags & SCRIPTTEXT_ISPERSISTENT);					ret = S_OK;					if (info->dwFlags & SCRIPTTEXT_ISEXPRESSION) {						if (m_scriptstate == SCRIPTSTATE_INITIALIZED) {							/* not allowed to execute code in this state */							ret = E_UNEXPECTED;							doexec = 0;						}					}					if (doexec) {						/* execute the code as an expression */						if (!execute_code_fragment(frag, info->pvarResult, info->pexcepinfo TSRMLS_CC))							ret = DISP_E_EXCEPTION;					}					zend_hash_next_index_insert(&m_frags, &frag, sizeof(code_frag*), NULL);				} else {					ret = DISP_E_EXCEPTION;				}				if (info->pvarResult) {					VariantInit(info->pvarResult);				}			}			break;		default:			trace("unhandled message type %08x\n", msg);			if (handled)				*handled = 0;	}	return ret;}/* The PHP/Zend state actually lives in this thread */void TPHPScriptingEngine::engine_thread_func(void){	TSRMLS_FETCH();	int handled;	int terminated = 0;	MSG msg;	trace("%08x: engine thread started up!\n", this);	CoInitializeEx(0, COINIT_MULTITHREADED);		m_tsrm_hack = tsrm_ls;	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)) {					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);					}				}				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)) {		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);#endif	m_enginethread = 0;	CoUninitialize();}/* Only call this in the context of the engine thread, or you'll be sorry. * * When SCRIPTITEM_GLOBALMEMBERS is set, we're only adding COM objects to the namespace. * We could add *all* properties, but I don't like this idea; what if the value changes * while the page is running?  We'd be left with stale data. * */void TPHPScriptingEngine::add_to_global_namespace(IDispatch *disp, DWORD flags, char *name TSRMLS_DC){	zval *val;	ITypeInfo *typ;	int i;	unsigned int namelen;	FUNCDESC *func;	BSTR funcname;	TYPEATTR *attr;	DISPPARAMS dispparams;	VARIANT vres;	ITypeInfo *rettyp;	TYPEATTR *retattr;trace("Add %s to global namespace\n", name);		val = php_COM_object_from_dispatch(disp, NULL TSRMLS_CC);		if (val == NULL) {		disp->Release();		return;	}	ZEND_SET_SYMBOL(&EG(symbol_table), name, val);	if (flags & SCRIPTITEM_GLOBALMEMBERS == 0) {		disp->Release();		return;	}	/* Enumerate properties and add those too */	if (FAILED(disp->GetTypeInfo(0, 0, &typ))) {		disp->Release();		return;	}	if (SUCCEEDED(typ->GetTypeAttr(&attr))) {		for (i = 0; i < attr->cFuncs; i++) {			if (FAILED(typ->GetFuncDesc(i, &func)))				continue;			/* Look at it's type */			if (func->invkind == INVOKE_PROPERTYGET					&& VT_PTR == func->elemdescFunc.tdesc.vt					&& VT_USERDEFINED == func->elemdescFunc.tdesc.lptdesc->vt					&& SUCCEEDED(typ->GetRefTypeInfo(func->elemdescFunc.tdesc.lptdesc->hreftype, &rettyp)))			{				if (SUCCEEDED(rettyp->GetTypeAttr(&retattr))) {					if (retattr->typekind == TKIND_DISPATCH) {						/* It's dispatchable */						/* get the value */						dispparams.cArgs = 0;						dispparams.cNamedArgs = 0;						VariantInit(&vres);						if (SUCCEEDED(disp->Invoke(func->memid, IID_NULL, 0, func->invkind,										&dispparams, &vres, NULL, NULL))) {							/* Get it's dispatch */							IDispatch *sub = NULL;							if (V_VT(&vres) == VT_UNKNOWN)								V_UNKNOWN(&vres)->QueryInterface(IID_IDispatch, (void**)&sub);							else if (V_VT(&vres) == VT_DISPATCH)								sub = V_DISPATCH(&vres);							if (sub) {								/* find out it's name */								typ->GetDocumentation(func->memid, &funcname, NULL, NULL, NULL);								name = php_OLECHAR_to_char(funcname, &namelen, CP_ACP TSRMLS_CC);								/* add to namespace */								zval *subval = php_COM_object_from_dispatch(sub, NULL TSRMLS_CC);								if (subval) {									ZEND_SET_SYMBOL(&EG(symbol_table), name, subval);									}								efree(name);								SysFreeString(funcname);							}							VariantClear(&vres);						}					}					rettyp->ReleaseTypeAttr(retattr);				}				rettyp->Release();			}			typ->ReleaseFuncDesc(func);		}		typ->ReleaseTypeAttr(attr);	}	disp->Release();}STDMETHODIMP_(DWORD) TPHPScriptingEngine::AddRef(void){	return InterlockedIncrement(const_cast<long*> (&m_refcount));}STDMETHODIMP_(DWORD) TPHPScriptingEngine::Release(void){	DWORD ret = InterlockedDecrement(const_cast<long*> (&m_refcount));	if (ret == 0) {		trace("%08x: Release: zero refcount, destroy the engine!\n", this);		delete this;	}	return ret;}STDMETHODIMP TPHPScriptingEngine::QueryInterface(REFIID iid, void **ppvObject){	*ppvObject = NULL;		if (IsEqualGUID(IID_IActiveScript, iid)) {		*ppvObject = (IActiveScript*)this;	} else if (IsEqualGUID(IID_IActiveScriptParse, iid)) {		*ppvObject = (IActiveScriptParse*)this;	} else if (IsEqualGUID(IID_IActiveScriptParseProcedure, iid)) {		*ppvObject = (IActiveScriptParseProcedure*)this;	} else if (IsEqualGUID(IID_IUnknown, iid)) {		*ppvObject = this;		} else {		LPOLESTR guidw;		StringFromCLSID(iid, &guidw);		{			TWideString guid(guidw);			trace("%08x: QueryInterface for unsupported %s\n", this, guid.ansi_string());		}		CoTaskMemFree(guidw);	}	if (*ppvObject) {		AddRef();		return S_OK;	}		return E_NOINTERFACE;}/* This is called by the host to set the scrite site. * It also defines the base thread. */STDMETHODIMP TPHPScriptingEngine::SetScriptSite(IActiveScriptSite *pass){	TSRMLS_FETCH();	tsrm_mutex_lock(m_mutex);	trace("%08x: -----> Base thread is %08x\n", this, tsrm_thread_id());		if (m_pass) {		m_pass->Release();		m_pass = NULL;		SEND_THREAD_MESSAGE(this, PHPSE_SET_SITE, 0, 0 TSRMLS_CC);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -