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

📄 jsicontext.cpp

📁 OSB-PIK-OpenVXI-3.0.0源代码 “中国XML论坛 - 专业的XML技术讨论区--XML在语音技术中的应用”
💻 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) )

⌨️ 快捷键说明

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