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

📄 jsicontext.cpp

📁 sloedgy open sip stack source code
💻 CPP
📖 第 1 页 / 共 4 页
字号:
     
   // Must unroot before unlocking
   val.Clear( );
     
   if ( AccessEnd( ) == false )
     rc = VXIjsi_RESULT_SYSTEM_ERROR;
   
   return rc;
 }
 
 
 // Get the value of a variable
 VXIjsiResult JsiContext::GetVar (const VXIchar     *name,
          VXIValue         **value) const
 {
   if (( name == NULL ) || ( name[0] == 0 ) || ( value == NULL ))
     return VXIjsi_RESULT_INVALID_ARGUMENT;
 
   *value = NULL;
 
   if ( AccessBegin( ) == false )
     return VXIjsi_RESULT_SYSTEM_ERROR;
 
   // Get the variable, we need to evaluate instead of just calling
   // JS_GetUCProperty( ) in order to have it automatically look back
   // through the scope chain, as well as to permit explicit scope
   // references like "myscope.myvar"
   JsiProtectedJsval val (context);
   VXIjsiResult rc = EvaluateScript (name, &val);
 
   if ( rc == VXIjsi_RESULT_SUCCESS )
     rc = JsvalToVXIValue (context, val.Get( ), value);
   else if (( rc == VXIjsi_RESULT_SYNTAX_ERROR ) ||
      ( rc == VXIjsi_RESULT_SCRIPT_EXCEPTION ))
     rc = VXIjsi_RESULT_NON_FATAL_ERROR;
 
   // Must unroot before unlocking
   val.Clear( );
 
   if ( AccessEnd( ) == false )
     rc = VXIjsi_RESULT_SYSTEM_ERROR;
 
   return rc;
 }
 
 
 // Check whether a variable is defined (not void, could be NULL)
 VXIjsiResult JsiContext::CheckVar (const VXIchar   *name) const
 {
   if (( name == NULL ) || ( name[0] == 0 ))
     return VXIjsi_RESULT_INVALID_ARGUMENT;
 
   if ( AccessBegin( ) == false )
     return VXIjsi_RESULT_SYSTEM_ERROR;
 
   // Get the variable, we need to evaluate instead of just calling
   // JS_GetUCProperty( ) in order to have it automatically look back
   // through the scope chain, as well as to permit explicit scope
   // references like "myscope.myvar". We disable logging because
   // we don't want JavaScript error reports about this var being
   // undefined.
   JsiProtectedJsval val (context);
   VXIjsiResult rc = EvaluateScript (name, &val, false);
 
   if (( rc == VXIjsi_RESULT_SYNTAX_ERROR ) ||
       ( rc == VXIjsi_RESULT_SCRIPT_EXCEPTION ) ||
       ( rc == VXIjsi_RESULT_NON_FATAL_ERROR ) )
     rc = VXIjsi_RESULT_NON_FATAL_ERROR;
   else if (( rc == VXIjsi_RESULT_SUCCESS ) &&
           ( JSVAL_IS_VOID (val.Get( )) ) )   // JavaScript undefined
     rc = VXIjsi_RESULT_FAILURE;
 
   // Must unroot before unlocking
   val.Clear( );
 
   if ( AccessEnd( ) == false )
     rc = VXIjsi_RESULT_SYSTEM_ERROR;
 
   return rc;
 }
 
 
 // Execute a script, optionally returning any execution result
 VXIjsiResult JsiContext::Eval (const VXIchar       *expr,
              VXIValue           **result)
 {
   if (( expr == NULL ) || ( expr[0] == 0 ))
     return VXIjsi_RESULT_INVALID_ARGUMENT;
 
   if ( result )
     *result = NULL;
 
   // Execute the script
   if ( AccessBegin( ) == false )
     return VXIjsi_RESULT_SYSTEM_ERROR;
 
   JsiProtectedJsval val (context);
   VXIjsiResult rc = EvaluateScript (expr, &val);
  
   if (( result ) && ( rc == VXIjsi_RESULT_SUCCESS ) &&
       ( val.Get( ) != JSVAL_VOID ))
     rc = JsvalToVXIValue (context, val.Get( ), result);
 
   // Must unroot before unlocking
   val.Clear( );
 
   if ( AccessEnd( ) == false )
     rc = VXIjsi_RESULT_SYSTEM_ERROR;
 
   return rc;
 }
 
 
 // Push a new context onto the scope chain (add a nested scope)
 VXIjsiResult JsiContext::PushScope (const VXIchar *name, const VXIjsiScopeAttr attr)
 {
   if (( ! name ) || ( ! name[0] ))
     return VXIjsi_RESULT_INVALID_ARGUMENT;
 
   if ( AccessBegin( ) == false )
     return VXIjsi_RESULT_SYSTEM_ERROR;
 
   // Create an object for the scope, the current scope is its parent
   VXIjsiResult rc = VXIjsi_RESULT_SUCCESS;
   if( attr == VXIjsi_NATIVE_SCOPE )
   {
     JSObject *scope = JS_NewObject (context, &SCOPE_CLASS, NULL, 
             currentScope->GetJsobj( ));
     if ( ! scope ) {
       rc = VXIjsi_RESULT_OUT_OF_MEMORY;
     } else {
   
       Diag (SBJSI_LOG_SCOPE, L"JsiContext::PushScope", 
             L"scope %s (0x%p), context 0x%p", name, scope, context);
         
       // The scope chain node object locks it to protect this from
       // garbage collection in case someone (possibly a malicious
       // script) destroys the data member pointing at this in the global
       // scope
       JsiScopeChainNode *newScope = 
         new JsiScopeChainNode (context, currentScope, name);
       if ( newScope ) {
         rc = newScope->Create (scope);
         if (( rc == VXIjsi_RESULT_SUCCESS ) &&
             ( ! JS_SetPrivate (context, scope, newScope) ))
           rc = VXIjsi_RESULT_FATAL_ERROR;
       } else {
         rc = VXIjsi_RESULT_OUT_OF_MEMORY;
       }
   
       // Set this scope as a property of the parent scope
       if ( rc == VXIjsi_RESULT_SUCCESS ) {
         GET_JSCHAR_FROM_VXICHAR(tmpname, tmpnamelen, name);
         if ( JS_DefineUCProperty (context, currentScope->GetJsobj( ), tmpname,
             tmpnamelen, newScope->GetJsval( ), NULL, NULL, JSPROP_ENUMERATE) ) {
           // Add it to the scope chain and set it as the current scope
           currentScope->SetChild (newScope);
           currentScope = newScope;
         } else {
           rc = VXIjsi_RESULT_FATAL_ERROR;
         }
       }
     }
   }
   else if( attr == VXIjsi_ALIAS_SCOPE )
   {
     JSObject *aliasScope = JS_NewObject (context, &SCOPE_CLASS, NULL, 
             currentScope->GetJsobj( ));
     if ( ! aliasScope ) {
       rc = VXIjsi_RESULT_OUT_OF_MEMORY;
     } else {
   
       Diag (SBJSI_LOG_SCOPE, L"JsiContext::PushScope", 
             L"alias scope %s (0x%p), context 0x%p", name, aliasScope, context);
       // The scope chain node object locks it to protect this from
       // garbage collection in case someone (possibly a malicious
       // script) destroys the data member pointing at this in the global
       // scope
       JsiScopeChainNode *newAliasScope = 
         new JsiScopeChainNode (context, currentScope->GetParent(), name);
       if ( newAliasScope ) {
         rc = newAliasScope->Create (aliasScope);
         if (( rc == VXIjsi_RESULT_SUCCESS ) &&
             ( ! JS_SetPrivate (context, aliasScope, newAliasScope) ))
           rc = VXIjsi_RESULT_FATAL_ERROR;
       } else {
         rc = VXIjsi_RESULT_OUT_OF_MEMORY;
       }
   
       // Set this scope as a property of the parent scope
       if ( rc == VXIjsi_RESULT_SUCCESS ) {
         GET_JSCHAR_FROM_VXICHAR(tmpname, tmpnamelen, name);
         if ( JS_DefineUCProperty (context, currentScope->GetJsobj( ), tmpname,
             tmpnamelen, newAliasScope->GetJsval( ), NULL, NULL, JSPROP_ENUMERATE) ) {
           // set the alias scope to current scope by evaluating a javascript
           SBjsiString aliasScript(name);
           aliasScript += " = ";
           aliasScript += currentScope->GetName().c_str();
           currentScope->SetAliasScopeFlag();
           rc = EvaluateScript (aliasScript.c_str( ), NULL);
           currentScope->ResetAliasScopeFlag();
           // Add it to the scope chain and set it as the current scope
           if( rc == VXIjsi_RESULT_SUCCESS )
             rc = currentScope->PushAlias(newAliasScope);
         } else {
           rc = VXIjsi_RESULT_FATAL_ERROR;
         }
       }
     }
   }
   else
     rc = VXIjsi_RESULT_INVALID_ARGUMENT;
     
   if ( AccessEnd( ) == false )
     rc = VXIjsi_RESULT_SYSTEM_ERROR;
 
   return rc;
 }
 
 
 // Pop a context from the scope chain (remove a nested scope)
 VXIjsiResult JsiContext::PopScope( )
 {
   // Don't pop up past the global scope
   if ( currentScope == scopeChain )
     return VXIjsi_RESULT_NON_FATAL_ERROR;
 
   if ( AccessBegin( ) == false )
     return VXIjsi_RESULT_SYSTEM_ERROR;
   // make sure we retrieve correct native scope name and alias
   const VXIchar* scopeName = (currentScope->HasAlias() ? 
                               currentScope->GetAliasName().c_str() : currentScope->GetName().c_str());
   
   Diag (SBJSI_LOG_SCOPE, L"JsiContext::PopScope", 
   L"scope %s (0x%p), context 0x%p", 
   scopeName, currentScope->GetJsobj( ), context);
 
   VXIjsiResult rc = VXIjsi_RESULT_SUCCESS;
   
   // if the current scope is an alias, we pop the alias then unlock and return
   if( currentScope->HasAlias() )
   {
     JsiScopeChainNode *oldAlias = currentScope->PopAlias();
     // Release the old scope variable within the parent scope to permit
     // it to be garbage collected
     rc = (oldAlias == NULL ? VXIjsi_RESULT_FAILURE : rc);
     if( rc == VXIjsi_RESULT_SUCCESS )
     {
       jsval rval;
       GET_JSCHAR_FROM_VXICHAR(tmpname, tmpnamelen, oldAlias->GetName( ).c_str( ));
       if ( ! JS_DeleteUCProperty2 (context, currentScope->GetJsobj( ), tmpname,
              tmpnamelen, &rval) )
         rc = VXIjsi_RESULT_FATAL_ERROR;
 
       // Now finish releasing the old scope, the actual wrapper object is
       // freed by the scope finalize method when garbage collection occurs
       rc = oldAlias->Release( );
     }
     
     if ( AccessEnd( ) == false )
       return VXIjsi_RESULT_SYSTEM_ERROR;
     return rc;
   }
   
   // Revert to the parent scope
   JsiScopeChainNode *oldScope = currentScope;
   currentScope = currentScope->GetParent( );
   currentScope->SetChild (NULL);
 
   // Release the old scope variable within the parent scope to permit
   // it to be garbage collected
   jsval rval;
   GET_JSCHAR_FROM_VXICHAR(tmpname, tmpnamelen, oldScope->GetName( ).c_str( ));
   if ( ! JS_DeleteUCProperty2 (context, currentScope->GetJsobj( ), tmpname,
              tmpnamelen, &rval) )
     rc = VXIjsi_RESULT_FATAL_ERROR;
 
   // Now finish releasing the old scope, the actual wrapper object is
   // freed by the scope finalize method when garbage collection occurs
   rc = oldScope->Release( );
 
   if ( AccessEnd( ) == false )
     rc = VXIjsi_RESULT_SYSTEM_ERROR;
 
   return rc;
 }
 
 
 // Reset the scope chain to the global scope (pop all nested scopes)
 VXIjsiResult JsiContext::ClearScopes( )
 {
   // See if there is anything to do
   if ( currentScope == scopeChain )
     return VXIjsi_RESULT_SUCCESS;
 
   if ( AccessBegin( ) == false )
     return VXIjsi_RESULT_SYSTEM_ERROR;
 
   Diag (SBJSI_LOG_SCOPE, L"JsiContext::ClearScopes", L"context 0x%p", 
   context);
 
   // Revert to the global scope
   JsiScopeChainNode *oldScope = scopeChain->GetChild( );
   currentScope = scopeChain;
   currentScope->SetChild (NULL);
 
   // Release the old child scope variable within the global scope to
   // permit it and all its descendants to be garbage collected
   VXIjsiResult rc = VXIjsi_RESULT_SUCCESS;
   jsval rval;
   GET_JSCHAR_FROM_VXICHAR(tmpname, tmpnamelen, oldScope->GetName( ).c_str( ));
   if ( ! JS_DeleteUCProperty2 (context, currentScope->GetJsobj( ), tmpname,
              tmpnamelen, &rval) )
     rc = VXIjsi_RESULT_FATAL_ERROR;
   
   // Now finish releasing the old scope, the actual wrapper object is
   // freed by the scope finalize method when garbage collection occurs
   rc = oldScope->Release( );
 
   if ( AccessEnd( ) == false )
     rc = VXIjsi_RESULT_SYSTEM_ERROR;
 
   return rc;
 }
 
 
 // Script evaluation
 VXIjsiResult JsiContext::EvaluateScript (const VXIchar *script, 
            JsiProtectedJsval *retval,
            bool loggingEnabled) const
 {
   if (( script == NULL ) || ( script[0] == 0 ))
     return VXIjsi_RESULT_INVALID_ARGUMENT;
 
   // Reset our private data for evaluation callbacks
   EvaluatePrepare (loggingEnabled);
   if ( retval )
     retval->Clear( );
 
   // Compile the script
   VXIjsiResult rc = VXIjsi_RESULT_SUCCESS;
   GET_JSCHAR_FROM_VXICHAR(tmpscript, tmpscriptlen, script);
   JSScript *jsScript = JS_CompileUCScript (context, currentScope->GetJsobj( ), 
                                            tmpscript, tmpscriptlen, NULL, 1);
   if ( ! jsScript )
     rc = VXIjsi_RESULT_SYNTAX_ERROR;
   else {
     // Create a script object and root it to protect the script from
     // garbage collection, note that once this object exists it owns
     // the jsScript and thus we must not free it ourselves
     JSObject *jsScriptObj = JS_NewScriptObject (context, jsScript);
     if (( ! jsScriptObj ) ||
   ( ! JS_AddNamedRoot (context, &jsScriptObj, SCRIPT_OBJECT_NAME) )) {
       JS_DestroyScript (context, jsScript);
       rc = VXIjsi_RESULT_OUT_OF_MEMORY;
     } else {
       // Evaluate the script
       jsval val = JSVAL_VOID;
       if ( JS_ExecuteScript (context, currentScope->GetJsobj( ), jsScript, 
            &val) ) {
   if ( retval )
     rc = retval->Set (val);
       } else if ( exception ) {
   rc = VXIjsi_RESULT_SCRIPT_EXCEPTION;
       } else if ( numBranches > maxBranches ) {
   rc = VXIjsi_RESULT_SECURITY_VIOLATION;
       } else {
   rc = VXIjsi_RESULT_NON_FATAL_ERROR;
       }
       
       // Release the script object
       if ( ! JS_RemoveRoot (context, &jsScriptObj) )
   rc = VXIjsi_RESULT_FATAL_ERROR;
     }
   }
   
   return rc;
 }
 
 
 // Convert JS values to VXIValue types
 VXIjsiResult JsiContext::JsvalToVXIValue (JSContext *context,
             const jsval val,
             VXIValue **value)
 {
   if ( value == NULL )
     return VXIjsi_RESULT_INVALID_ARGUMENT;
   
   *value = NULL;
   VXIjsiResult rc = VXIjsi_RESULT_SUCCESS;
 
   if ( JSVAL_IS_STRING (val) ) {
     GET_VXICHAR_FROM_JSCHAR(tmpval, JS_GetStringChars (JSVAL_TO_STRING (val)));
     *value = (VXIValue *) VXIStringCreate(tmpval);
   
   } else if ( JSVAL_IS_INT (val) )
     *value = (VXIValue *) VXIIntegerCreate (JSVAL_TO_INT (val));
   
   else if ( JSVAL_IS_DOUBLE (val) )
     *value = (VXIValue *) VXIFloatCreate ((VXIflt32) *JSVAL_TO_DOUBLE (val));
   
   else if ( JSVAL_IS_BOOLEAN (val) )
     *value = (VXIValue *) 
       VXIBooleanCreate ((JSVAL_TO_BOOLEAN (val) ? TRUE : FALSE));

⌨️ 快捷键说明

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