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

📄 jsicontext.cpp

📁 Open VXI. This is a open source.
💻 CPP
📖 第 1 页 / 共 3 页
字号:
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);  if (( 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 ) {    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;  }  // Must unroot before unlocking  val.Clear( );  if ( AccessEnd( ) == false )    rc = VXIjsi_RESULT_SYSTEM_ERROR;  return rc;}// Create a script variable relative to the current scopeVXIjsiResult 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);  if ( 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 ) {    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;  }  // Must unroot before unlocking  val.Clear( );  if ( AccessEnd( ) == false )    rc = VXIjsi_RESULT_SYSTEM_ERROR;  return rc;}// Set a script variable relative to the current scopeVXIjsiResult 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;  // 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  JsiProtectedJsval val (context);  VXIjsiResult rc = EvaluateScript (expr, &val);  // 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      SBinetString 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 scopeVXIjsiResult 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 = VXIValueToJsval (context, value, &val);  // 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      SBinetString 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;}// Get the value of a variableVXIjsiResult 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_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 resultVXIjsiResult 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){  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;  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;      }    }  }  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;  Diag (SBJSI_LOG_SCOPE, L"JsiContext::PopScope", 	L"scope %s (0x%p), context 0x%p", 	currentScope->GetName( ).c_str( ), currentScope->GetJsobj( ), context);    // 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  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;}// 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 evaluationVXIjsiResult JsiContext::EvaluateScript (const VXIchar *script, 					 JsiProtectedJsval *retval,					 bool loggingEnabled) const

⌨️ 快捷键说明

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