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

📄 jsicontext.cpp

📁 sloedgy open sip stack source code
💻 CPP
📖 第 1 页 / 共 4 页
字号:
   // Copy simple variables
   runtime = rt;
   maxBranches = mb;
 
   // Base logging class initialization
   SetLog (l, diagTagBase);
 
   Diag (SBJSI_LOG_CONTEXT, L"JsiContext::Create", L"start 0x%p", this);
 
   // Create the context
   VXIjsiResult rc = runtime->NewContext (contextSize, &context);
   if ( rc != VXIjsi_RESULT_SUCCESS )
     return rc;
 
   // Lock the context for access
 #ifdef JS_THREADSAFE
   JS_BeginRequest (context);
 #else
   if ( AccessBegin( ) != true )
     rc = VXIjsi_RESULT_SYSTEM_ERROR;
 #endif
 
   // Attach this as private data to the context for use in callbacks
   if ( rc == VXIjsi_RESULT_SUCCESS )
     JS_SetContextPrivate (context, this);
 
   // Set the callback to enforce maxBranches
   if ( rc == VXIjsi_RESULT_SUCCESS )
     JS_SetBranchCallback (context, JsiContext::BranchCallback);
   
   // Set the callback for reporting errors
   if ( rc == VXIjsi_RESULT_SUCCESS )
     JS_SetErrorReporter (context, JsiContext::ErrorReporter);
 
   // Add JSOPTION_STRICT to enable strictness, which provides
   // additional warnings/errors.
   // 
   // TBD make these flags run-time configurable? Would be helpful for
   // migrating older apps to VoiceXML 2.0 April 2002 (April 2002
   // requires declaring variables prior to use, older VoiceXML does
   // not).
 #if defined(JSI_MUST_DECLARE_VARS) || defined(JSI_STRICT)
   if ( rc == VXIjsi_RESULT_SUCCESS )
     JS_SetOptions (context, 
 #if defined(JSI_MUST_DECLARE_VARS) || defined(JSI_STRICT)
 #if defined(SWI_JSOPTION_MUST_DECLARE_VARS)
        SWI_JSOPTION_MUST_DECLARE_VARS | JSOPTION_STRICT
 #else
        JSOPTION_STRICT
 #endif
 #else
 #ifdef JSI_MUST_DECLARE_VARS
 #ifdef SWI_JSOPTION_MUST_DECLARE_VARS
        SWI_JSOPTION_MUST_DECLARE_VARS
 #endif
 #endif
 #ifdef JSI_STRICT
        JSOPTION_STRICT
 #endif
 #endif
        );
 #endif
 
   // Create and intialize the global scope we require in the context,
   // the scope chain node object locks it to protect it from the
   // garbage collector
   if ( rc == VXIjsi_RESULT_SUCCESS ) {
     JSObject *globalScope = JS_NewObject (context, &SCOPE_CLASS, NULL, NULL);
     if ( ! globalScope )
       rc = VXIjsi_RESULT_OUT_OF_MEMORY;
     else {
       Diag (SBJSI_LOG_SCOPE, L"JsiContext::Create", 
       L"global scope 0x%p, context 0x%p", globalScope, context);
 
       scopeChain = new JsiScopeChainNode (context, NULL, GLOBAL_SCOPE_NAME_W);
       if ( scopeChain ) {
   rc = scopeChain->Create (globalScope);
   if ( rc == VXIjsi_RESULT_SUCCESS ) {
     if ( JS_SetPrivate (context, globalScope, scopeChain) )
       currentScope = scopeChain;
     else
       rc = VXIjsi_RESULT_FATAL_ERROR;
   }
       } else {
   rc = VXIjsi_RESULT_OUT_OF_MEMORY;
       }
     }
   }
 
   // Initialize the standard JavaScript classes, like Array, Math, String, etc.
   if (( rc == VXIjsi_RESULT_SUCCESS ) &&
       ( ! JS_InitStandardClasses (context, currentScope->GetJsobj( )) ))
     rc = VXIjsi_RESULT_OUT_OF_MEMORY;
 
   // Set version only after there is a valid global scope object
   if (( rc == VXIjsi_RESULT_SUCCESS ) &&
       ( version != JSVERSION_DEFAULT ))
     JS_SetVersion (context, version);
 
   // On failure, destroy the context here to avoid use of it
   if ( rc != VXIjsi_RESULT_SUCCESS ) {
     if ( context ) {
 #ifdef JS_THREADSAFE
       JS_EndRequest (context);
 #endif
       runtime->DestroyContext (&context);
     }
   }
 #ifdef JS_THREADSAFE
   else {
     contextRefs = JS_SuspendRequest (context);
   }
 #else
 
   if ( AccessEnd( ) != true )
     rc = VXIjsi_RESULT_SYSTEM_ERROR;
 #endif
 
   Diag (SBJSI_LOG_CONTEXT, L"JsiContext::Create", 
   L"end 0x%p, JS context 0x%p", this, context);
 
   return rc;
 }
 
 
 // Create a script variable relative to the current scope
 VXIjsiResult JsiContext::CreateVar (const VXIchar  *name, 
             const VXIchar  *expr)
 {
   if (( name == NULL ) || ( name[0] == 0 ))
     return VXIjsi_RESULT_INVALID_ARGUMENT;
 
 
   // If this is a fully qualified name, just do a SetVar( ) as that
   // handles explicitly scoped variables and this doesn't. No
   // functional effect to doing so, the only difference is that
   // CreateVar( ) masks vars of the same name from prior scopes when
   // SetVar( ) just sets the old one, having an explicit scope makes
   // that irrelevant since then JS knows exactly what to do.
   if ( wcschr (name, L'.') )
     return SetVar (name, expr);
 
   if ( AccessBegin( ) == false )
     return VXIjsi_RESULT_SYSTEM_ERROR;
   // Evaluate the expression, need to eval before setting so we can
   // deal with things like "1; 2;" which can't be handled if we just
   // make a temporary script
   VXIjsiResult rc = VXIjsi_RESULT_SUCCESS;
   JsiProtectedJsval val (context);
   
   // Check if the current scope is writeable
   rc = CheckWriteable(context, currentScope->GetJsobj(), name);
   
   if ( rc == VXIjsi_RESULT_SUCCESS && ( expr != NULL ) && ( expr[0] != 0 ))
     rc = EvaluateScript (expr, &val);
 
   // Set the variable in the current scope directly, ensures we mask
   // any var of the same name from earlier scopes
   if ( rc == VXIjsi_RESULT_SUCCESS ) {
     if( IsValidVarName(context, currentScope->GetJsobj( ), name) )
     {
       GET_JSCHAR_FROM_VXICHAR(tmpname, tmpnamelen, name);
       if (! JS_DefineUCProperty (context, currentScope->GetJsobj( ), 
         tmpname, tmpnamelen, val.Get( ), NULL, NULL,
         JSPROP_ENUMERATE) )
         rc = VXIjsi_RESULT_OUT_OF_MEMORY;
     }
     else
       rc = VXIjsi_RESULT_SYNTAX_ERROR;
   }
 
   // Must unroot before unlocking
   val.Clear( );
 
   if ( AccessEnd( ) == false )
     rc = VXIjsi_RESULT_SYSTEM_ERROR;
 
   return rc;
 }
 
 
 // Create a script variable relative to the current scope
 VXIjsiResult JsiContext::CreateVar (const VXIchar  *name, 
             const VXIValue *value)
 {
   if (( name == NULL ) || ( name[0] == 0 ))
     return VXIjsi_RESULT_INVALID_ARGUMENT;
 
   // If this is a fully qualified name, just do a SetVar( ) as that
   // handles explicitly scoped variables and this doesn't. No
   // functional effect to doing so, the only difference is that
   // CreateVar( ) masks vars of the same name from prior scopes when
   // SetVar( ) just sets the old one, having an explicit scope makes
   // that irrelevant since then JS knows exactly what to do.
   if ( wcschr (name, L'.') )
     return SetVar (name, value);
 
   if ( AccessBegin( ) == false )
     return VXIjsi_RESULT_SYSTEM_ERROR;
 
   // Convert the value to a JavaScript variable
   VXIjsiResult rc = VXIjsi_RESULT_SUCCESS;
   JsiProtectedJsval val (context);
 
   // Check if the current scope is writeable
   rc = CheckWriteable(context, currentScope->GetJsobj(), name);
   
   if ( rc == VXIjsi_RESULT_SUCCESS && value )
     rc = VXIValueToJsval (context, value, &val);
 
   // Set the variable in the current scope directly, ensures we mask
   // any var of the same name from earlier scopes
   if ( rc == VXIjsi_RESULT_SUCCESS ) {
     // check if variable name is valid
     if( IsValidVarName(context, currentScope->GetJsobj( ), name) )
     {
       GET_JSCHAR_FROM_VXICHAR(tmpname, tmpnamelen, name);
       if ( ! JS_DefineUCProperty (context, currentScope->GetJsobj( ), 
             tmpname, tmpnamelen, val.Get( ), NULL, NULL,
             JSPROP_ENUMERATE) )
         rc = VXIjsi_RESULT_OUT_OF_MEMORY;
     }
     else
       rc = VXIjsi_RESULT_SYNTAX_ERROR;
   }
 
   // Must unroot before unlocking
   val.Clear( );
 
   if ( AccessEnd( ) == false )
     rc = VXIjsi_RESULT_SYSTEM_ERROR;
 
   return rc;
 }
 
 
 // Set a script variable relative to the current scope
 VXIjsiResult JsiContext::SetVar (const VXIchar     *name, 
          const VXIchar     *expr)
 {
   if (( name == NULL ) || ( name[0] == 0 ) ||
       ( expr == NULL ) || ( expr[0] == 0 ))
     return VXIjsi_RESULT_INVALID_ARGUMENT;
 
   if ( AccessBegin( ) == false )
     return VXIjsi_RESULT_SYSTEM_ERROR;
 
   JsiProtectedJsval val (context);
   VXIjsiResult rc = VXIjsi_RESULT_SUCCESS;
 #ifdef JSI_MUST_DECLARE_VARS
   // Must declare the variable before attempt 
   rc = EvaluateScript(name, &val, false);
 #endif
   // Evaluate the expression, need to eval before setting so we can
   // deal with things like "1; 2;" which can't be handled if we just
   // make a temporary script
   if( rc == VXIjsi_RESULT_SUCCESS )
     rc = EvaluateScript (expr, &val);
 
   // Check if the current scope is writeable
   if( rc == VXIjsi_RESULT_SUCCESS )
     rc = CheckWriteable(context, currentScope->GetJsobj(), name);
 
   // What we'd like to do is lookup the variable, then set it to the
   // jsval we got above. (The lookup is complex because it could be
   // a partially or fully qualified name, with potential scope
   // chain/prototype chain lookups.) However, that isn't possible in
   // SpiderMonkey. So instead we set a temporary variable in the
   // global scope, then assign the specified object to that, then
   // destroy the temporary.
   if ( rc == VXIjsi_RESULT_SUCCESS ) {
     if ( JS_DefineProperty (context, currentScope->GetJsobj( ),
           GLOBAL_TEMP_VAR, val.Get( ), NULL, NULL, 0) ) {
       // Do the copy using a temporary script
       SBjsiString script (name);
       script += L"=";
       script += GLOBAL_TEMP_VAR_W;
       rc = EvaluateScript (script.c_str( ), NULL);
 
       // Destroy the temporary variable
       jsval ignored = JSVAL_VOID;
       if ( ! JS_DeleteProperty2 (context, currentScope->GetJsobj( ), 
          GLOBAL_TEMP_VAR, &ignored) )
         rc = VXIjsi_RESULT_FATAL_ERROR;
     } else {
       rc = VXIjsi_RESULT_OUT_OF_MEMORY;
     }
   }
 
   // Must unroot before unlocking
   val.Clear( );
 
   if ( AccessEnd( ) == false )
     rc = VXIjsi_RESULT_SYSTEM_ERROR;
 
   return rc;
 }
 
 
 // Set a script variable relative to the current scope
 VXIjsiResult JsiContext::SetVar (const VXIchar   *name, 
          const VXIValue  *value)
 {
   if (( name == NULL ) || ( name[0] == 0 ) || ( value == NULL ))
     return VXIjsi_RESULT_INVALID_ARGUMENT;
 
   if ( AccessBegin( ) == false )
     return VXIjsi_RESULT_SYSTEM_ERROR;
 
   // Convert the value to a JavaScript variable
   JsiProtectedJsval val (context);
   VXIjsiResult rc = VXIjsi_RESULT_SUCCESS;
 #ifdef JSI_MUST_DECLARE_VARS
   rc = EvaluateScript(name, &val, false);
 #endif
 
   if( rc == VXIjsi_RESULT_SUCCESS )
     rc =  VXIValueToJsval (context, value, &val);
 
   // Check if the current scope is writeable
   if( rc == VXIjsi_RESULT_SUCCESS )
     rc = CheckWriteable(context, currentScope->GetJsobj(), name);
 
   // What we'd like to do is lookup the variable, then set it to the
   // jsval we got above. (The lookup is complex because it could be
   // a partially or fully qualified name, with potential scope
   // chain/prototype chain lookups.) However, that isn't possible in
   // SpiderMonkey. So instead we set a temporary variable in the
   // global scope, then assign the specified object to that, then
   // destroy the temporary.
   if ( rc == VXIjsi_RESULT_SUCCESS ) {
     if ( JS_DefineProperty (context, currentScope->GetJsobj( ),
           GLOBAL_TEMP_VAR, val.Get( ), NULL, NULL, 0) ) {
       // Do the copy using a temporary script
       SBjsiString script (name);
       script += L"=";
       script += GLOBAL_TEMP_VAR_W;
       rc = EvaluateScript (script.c_str( ), NULL);
 
       // Destroy the temporary variable
       jsval ignored = JSVAL_VOID;
       if ( ! JS_DeleteProperty2 (context, currentScope->GetJsobj( ), 
          GLOBAL_TEMP_VAR, &ignored) )
         rc = VXIjsi_RESULT_FATAL_ERROR;
     } else {
       rc = VXIjsi_RESULT_OUT_OF_MEMORY;
     }
   }
 
   // Must unroot before unlocking
   val.Clear( );
 
   if ( AccessEnd( ) == false )
     rc = VXIjsi_RESULT_SYSTEM_ERROR;
 
   return rc;
 }
 
 
 // Set the given scope namespace to read-only attribute
 VXIjsiResult JsiContext::SetReadOnly(const VXIchar *name) const
 {
   
   if (( name == NULL ) || ( name[0] == 0 ))
     return VXIjsi_RESULT_INVALID_ARGUMENT;
 
   if ( AccessBegin( ) == false )
     return VXIjsi_RESULT_SYSTEM_ERROR;
   
   // setting the attribute of the given object's name
   // to read-only status.  By evaluating the object's name we'll
   // get to the correct scope.
   JSBool foundp; 
   JsiProtectedJsval val (context);
   VXIjsiResult rc = EvaluateScript (name, &val);
   
   // Check if this  variable is an object
   if( rc == VXIjsi_RESULT_SUCCESS && JSVAL_IS_OBJECT (val.Get()) )
   {
     // Check if it is an instance of SCOPE_CLASS object
     JSObject *robj = JSVAL_TO_OBJECT(val.Get());    
     if( JS_InstanceOf (context, robj, &SCOPE_CLASS, NULL) )
     {
       // find the parent node of the current scope because JS_SetUCPropertyAttributes
       // only works from top-down
       JsiScopeChainNode * prdata = (JsiScopeChainNode *) JS_GetPrivate(context, robj);
       if( prdata && prdata->GetParent())
       {
         // Set the property to read-only
         JSObject *pobj = prdata->GetParent()->GetJsobj(); 
         GET_JSCHAR_FROM_VXICHAR(tmpname, tmpnamelen, name);
         if( JS_SetUCPropertyAttributes(context, pobj, tmpname, tmpnamelen, 
             JSPROP_ENUMERATE | JSPROP_READONLY, &foundp) )
         {
           if( !foundp )
           {
             rc = VXIjsi_RESULT_FAILURE;         
           }
         } 
         else
           rc = VXIjsi_RESULT_FAILURE;             
       }
     }
   }

⌨️ 快捷键说明

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