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

📄 jsicontext.cpp

📁 OSB-PIK-OpenVXI-3.0.0源代码 “中国XML论坛 - 专业的XML技术讨论区--XML在语音技术中的应用”
💻 CPP
📖 第 1 页 / 共 4 页
字号:
 /****************License************************************************  *  * Copyright 2000-2003.  ScanSoft, Inc.      *  * Use of this software is subject to notices and obligations set forth   * in the SpeechWorks Public License - Software Version 1.2 which is   * included with this software.   *  * ScanSoft is a registered trademark of ScanSoft, Inc., and OpenSpeech,   * SpeechWorks and the SpeechWorks logo are registered trademarks or   * trademarks of SpeechWorks International, Inc. in the United States   * and other countries.  *  ***********************************************************************/  /*****************************************************************************  *****************************************************************************  *  *  * JsiContext, class for managing JavaScript contexts   *  * The JsiContext class represents a JavaScript context, a script  * execution state. All JavaScript variables are maintained in a  * context, and all scripts are executed in reference to a context  * (for accessing variables and maintaining script side-effects). Each  * context may have one or more scopes that are used to layer the  * state information so that it is possible for clients to control the  * lifetime of state information within the context.  * SBjsiInterface, definition of the real SBjsi resource object  *  *****************************************************************************  ****************************************************************************/   // -----1=0-------2=0-------3=0-------4=0-------5=0-------6=0-------7=0-------8   #include "SBjsiInternal.h"  #include "JsiRuntime.hpp"            // For the JsiRuntime class #include "JsiContext.hpp"            // Defines this class  #include <string.h>                  // For strlen( ) #include <deque>                       // for deque   #include "SBjsiLog.h"                // For logging #include "SBjsiString.hpp"          // For SBjsiString #include "JsiCharCvt.hpp"            // For jschar <-> VXIchar conversion  // SpiderMonkey class that describes our scope objects which we use // as contexts static JSClass SCOPE_CLASS = {     "__SBjsiScope", JSCLASS_HAS_PRIVATE,     JS_PropertyStub,  JS_PropertyStub, JS_PropertyStub, JsiContext::SCOPE_CLASS_SetProperty,     JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub,       JsiContext::ScopeFinalize, JSCLASS_NO_OPTIONAL_MEMBERS };  // SpiderMonkey class that describes our content objects which we use // to point at VXIContent objects static JSClass CONTENT_CLASS = {     "__SBjsiContent", JSCLASS_HAS_PRIVATE,     JS_PropertyStub,  JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,     JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub,       JsiContext::ContentFinalize, JSCLASS_NO_OPTIONAL_MEMBERS };  // SpiderMonkey class that describes our objects which we create from // a VXIMap, just very simple objects static JSClass MAP_CLASS = {     "__SBjsiMap", 0,     JS_PropertyStub,  JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,     JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub,       JS_FinalizeStub, JSCLASS_NO_OPTIONAL_MEMBERS };  // Names for JS objects we protect from garbage collection, only used // for SpiderMonkey debugging purposes static const char GLOBAL_SCOPE_NAME[]  = "__SBjsiGlobalScope"; static const wchar_t GLOBAL_SCOPE_NAME_W[]  = L"__SBjsiGlobalScope"; static const char SCRIPT_OBJECT_NAME[] = "__SBjsiScriptObject"; static const char PROTECTED_JSVAL_NAME[] = "__SBjsiProtectedJsval";  // Global variable we use for temporaries static const char GLOBAL_TEMP_VAR[] = "__SBjsiTempVar"; static const wchar_t GLOBAL_TEMP_VAR_W[] = L"__SBjsiTempVar";   // -----1=0-------2=0-------3=0-------4=0-------5=0-------6=0-------7=0-------8   #define GET_VXICHAR_FROM_JSCHAR(out, in) \   JscharToVXIchar convert_##out(in); \   const VXIchar *out = convert_##out.c_str( )  #define GET_JSCHAR_FROM_VXICHAR(out, outlen, in) \   VXIcharToJschar convert_##out(in); \   const jschar *out = convert_##out.c_str( ); \   size_t outlen = convert_##out.length( )   // -----1=0-------2=0-------3=0-------4=0-------5=0-------6=0-------7=0-------8   // Wrapper class around jsval that automatically protects the held // jsval from garbage collection class JsiProtectedJsval {  public:   // Constructor and destructor   JsiProtectedJsval (JSContext *c) : context(c), val(JSVAL_VOID) { }   ~JsiProtectedJsval( ) { Clear( ); }    // Clear the value   VXIjsiResult Clear( ) {      VXIjsiResult rc;     rc = ((( JSVAL_IS_GCTHING(val) ) && ( ! JS_RemoveRoot (context, &val) )) ?     VXIjsi_RESULT_FATAL_ERROR : VXIjsi_RESULT_SUCCESS);     val = JSVAL_VOID;     return rc;   }      // Set the value   VXIjsiResult Set (jsval v) {     VXIjsiResult rc = Clear( );     val = v;     if (( JSVAL_IS_GCTHING(val) ) &&   ( ! JS_AddNamedRoot (context, &val, PROTECTED_JSVAL_NAME) )){       rc = VXIjsi_RESULT_OUT_OF_MEMORY; // blown away by GC already!     }     return rc;   }    // Accessor   const jsval Get( ) const { return val; }   private:   // Disabled copy constructor and assignment operator   JsiProtectedJsval (const JsiProtectedJsval &v);   JsiProtectedJsval &operator=(const JsiProtectedJsval &v);   private:   JSContext  *context;   jsval      val; };   // -----1=0-------2=0-------3=0-------4=0-------5=0-------6=0-------7=0-------8   // Scope chain class, used to keep the scope chain independantly of // the actual user visible scope chain to avoid crashes from invalid // or malicious scripts (push a scope called "session", then overwrite // that variable with an integer named "session", then try to do more // work in that scope) class JsiScopeChainNode {  public:   // Constructor and destructor   JsiScopeChainNode (JSContext *context, JsiScopeChainNode *p,           const VXIchar *n) :     pushAliasFlag(false), name(n), parent(p), child(NULL), jsVal(context) { }   ~JsiScopeChainNode( ) { }    // Creation method   VXIjsiResult Create (JSObject *scopeObj) {      return jsVal.Set (OBJECT_TO_JSVAL(scopeObj)); }    // Accessors   const SBjsiString & GetName( )   const { return name; }   jsval                GetJsval( )  { return jsVal.Get( ); }   JSObject           * GetJsobj( )  { return JSVAL_TO_OBJECT(jsVal.Get( )); }   JsiScopeChainNode  * GetParent( ) { return parent; }   JsiScopeChainNode  * GetChild( )  { return child; }    // Set the child scope   void SetChild (JsiScopeChainNode *c) { child = c; }    // Release this scope and all under it   VXIjsiResult Release( );      // Alias functions   VXIjsiResult PushAlias(JsiScopeChainNode *_alias)    {      VXIjsiResult rc = VXIjsi_RESULT_SUCCESS;     if( _alias )     {       aliasList.push_front(_alias);     }     else       rc = VXIjsi_RESULT_FAILURE;     return rc;   }       JsiScopeChainNode* PopAlias(void)    {     JsiScopeChainNode *a = NULL;     if( !aliasList.empty() )     {       a = aliasList.front();       aliasList.pop_front();       }     return a;   }   bool HasAlias(void) { return !aliasList.empty(); }   const SBjsiString & GetAliasName(void) const   {     if( !aliasList.empty() )       return aliasList.front()->GetName();     return GetName();   }      void SetAliasScopeFlag(void) { pushAliasFlag = true; }   bool IsSetAliasScopeFlag(void) { return pushAliasFlag; }   void ResetAliasScopeFlag(void) { pushAliasFlag = false; }     private:   SBjsiString        name;      // Name of this scope   JsiScopeChainNode  *parent;    // Parent scope   JsiScopeChainNode  *child;     // Child scope, may be NULL   JsiProtectedJsval   jsVal;     // JS object for the scope   // alias list   std::deque<JsiScopeChainNode*> aliasList;   bool               pushAliasFlag; };   VXIjsiResult JsiScopeChainNode::Release( ) {   JsiScopeChainNode *node = this, *next = NULL, *alias = NULL;   while (node) {     // if node is an alias, just pop the alias and continue     if( node->HasAlias() )     {       alias = node->PopAlias();       if( alias ) alias->jsVal.Clear( );       continue;     }     // Release the lock on the underlying object     node->jsVal.Clear( );      // Clear pointers for safety and advance to child scopes     next = node->child;     node->parent = NULL;     node->child = NULL;     node = next;      // NOTE: the deletion of this node and the child nodes is handled     // by the ScopeFinalize( ) method that is called when the JS     // object is garbage collected   }    return VXIjsi_RESULT_SUCCESS; }   // To support VXML 2.0 SPEC, that added the read-only attribute to a namespace. // Therefore any attempt to modify, create any variable in this namespace will result // in java script semantic error.  This is the callback that will be called // every time set property function is called.  It will check for read-only flag // of the current scope to determine if it is read-only, if so return false. JSBool JsiContext::SCOPE_CLASS_SetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp) {   uintN attrp;   JSBool foundp;   JsiScopeChainNode * prdata = (JsiScopeChainNode *) JS_GetPrivate(cx, obj);   if( prdata )   {     // return true, if pushing alias scope     if (prdata->IsSetAliasScopeFlag() )       return JS_TRUE;     GET_JSCHAR_FROM_VXICHAR(tmpname, tmpnamelen, prdata->GetName().c_str());     JSObject *pobj = (prdata->GetParent() ? prdata->GetParent()->GetJsobj() : prdata->GetJsobj());     if( JS_GetUCPropertyAttributes(cx, pobj,                            tmpname, tmpnamelen,                            &attrp, &foundp) )     {       if( foundp && (attrp & JSPROP_READONLY) )       {         return JS_FALSE;       }     }   }   return JS_TRUE; }  VXIjsiResult JsiContext::CheckWriteable(JSContext *cx, JSObject *obj, const VXIchar* varname) {   VXIjsiResult rc = VXIjsi_RESULT_SUCCESS;   uintN attrp;   JSBool foundp;   JsiScopeChainNode * prdata = (JsiScopeChainNode *) JS_GetPrivate(cx, obj);   // evaluate var name to get the root, i.e a.b.c, then the root is a   // if there is no root i.e, a then we don't need to evaluate   if( wcschr (varname, L'.') )   {     VXIchar* rootvar, *state = NULL;     VXIchar _varname[1024];     wcscpy(_varname, varname); #ifdef WIN32     rootvar = wcstok(_varname, L"."); #else     rootvar = wcstok(_varname, L".", &state); #endif     if( rootvar )     {       JsiProtectedJsval val (context);       VXIjsiResult rc = EvaluateScript (rootvar, &val);       JSObject *classobj = JSVAL_TO_OBJECT(val.Get());       // if this object is scope class then get the private data,       // otherwise just ignore it       if( rc == VXIjsi_RESULT_SUCCESS && JS_InstanceOf (cx, classobj, &SCOPE_CLASS, NULL) )       {         prdata = (JsiScopeChainNode *) JS_GetPrivate(cx, classobj);       }       val.Clear( );     }   }          if( prdata )   {     // get scope from the current parent     JSObject* pscope = (prdata->GetParent() ? prdata->GetParent()->GetJsobj() : prdata->GetJsobj());      // retrieve read-only attribute      GET_JSCHAR_FROM_VXICHAR(tmpname, tmpnamelen, prdata->GetName().c_str());     if( JS_GetUCPropertyAttributes(cx, pscope,                            tmpname, tmpnamelen,                            &attrp, &foundp) )     {       if( foundp && (attrp & JSPROP_READONLY) )       {         return rc = VXIjsi_RESULT_NON_FATAL_ERROR;       }     }   }   return rc; }  // -----1=0-------2=0-------3=0-------4=0-------5=0-------6=0-------7=0-------8   // Constructor, only does initialization that cannot fail JsiContext::JsiContext( ) : SBjsiLogger (MODULE_SBJSI, NULL, 0),   version(JSVERSION_DEFAULT), runtime(NULL), context(NULL),   contextRefs(0), scopeChain(NULL), currentScope(NULL), logEnabled(true),   maxBranches(0L), numBranches(0L), exception(NULL) { }   // Destructor JsiContext::~JsiContext( ) {   Diag (SBJSI_LOG_CONTEXT, L"JsiContext::~JsiContext",    L"start 0x%p, JS context 0x%p", this, context);        if ( exception )     VXIValueDestroy (&exception);    if ( context ) {     // Lock the context for access #ifdef JS_THREADSAFE     JS_ResumeRequest (context, contextRefs); #else     if ( ! AccessBegin( ) )       return; #endif      // Destroy the scope chain, which automatically unroots the global     // scope to allow garbage collection of everything     if ( scopeChain )       scopeChain->Release( );      // Release the lock, must be done before destroying the context #ifdef JS_THREADSAFE     JS_EndRequest (context); #else     AccessEnd( ); #endif      // Destroy the context, is set to NULL     runtime->DestroyContext (&context);   }    Diag (SBJSI_LOG_CONTEXT, L"JsiContext::~JsiContext", L"end 0x%p", this); }   // Creation method VXIjsiResult JsiContext::Create (JsiRuntime        *rt,           long               contextSize,           long               mb,          VXIlogInterface   *l,          VXIunsigned        diagTagBase) {   if (( rt == NULL ) || ( contextSize < 1 ) || ( mb < 1 ) ||       ( l == NULL ))     return VXIjsi_RESULT_INVALID_ARGUMENT;    // Copy simple variables   runtime = rt;

⌨️ 快捷键说明

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