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

📄 jsicontext.cpp

📁 Open VXI. This is a open source.
💻 CPP
📖 第 1 页 / 共 3 页
字号:
{  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 typesVXIjsiResult 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 *) VXIIntegerCreate (JSVAL_TO_BOOLEAN (val));    else if ( JSVAL_IS_NULL (val) )  // JavaScript null    rc = VXIjsi_RESULT_FAILURE;  else if ( JSVAL_IS_OBJECT (val) ) {    JSObject *obj = JSVAL_TO_OBJECT(val);    if ( JS_IsArrayObject (context, obj) ) {      // Array, create a VXIVector      jsuint elements = 0;      VXIVector *vec = NULL;      if ( ! JS_GetArrayLength (context, obj, &elements) ) {	rc = VXIjsi_RESULT_FATAL_ERROR;      } else if ( (vec = VXIVectorCreate( )) == NULL ) {	rc = VXIjsi_RESULT_OUT_OF_MEMORY;      } else {	// Traverse through the elements in the vector (could be empty,	// in which case we want to return an empty VXIVector)	for (jsuint i = 0; 	     (( rc == VXIjsi_RESULT_SUCCESS ) && ( i < elements )); i++) {	  // Convert the element to a VXIValue, then insert	  jsval elVal = JSVAL_VOID;	  if ( JS_GetElement (context, obj, i, &elVal) ) {	    VXIValue *elValue;	    rc = JsvalToVXIValue (context, elVal, &elValue);	    if (( rc == VXIjsi_RESULT_SUCCESS ) &&		( VXIVectorAddElement (vec, elValue) != 		  VXIvalue_RESULT_SUCCESS )) {	      rc = VXIjsi_RESULT_OUT_OF_MEMORY;	      VXIValueDestroy (&elValue);	    }	  } else {	    rc = VXIjsi_RESULT_FATAL_ERROR;	  }	}	if ( rc == VXIjsi_RESULT_SUCCESS )	  *value = (VXIValue *) vec;	else	  VXIVectorDestroy (&vec);      }    } else if ( JS_InstanceOf (context, obj, &CONTENT_CLASS, NULL) ) {      // Content object, retrieve the VXIContent      *value = (VXIValue *) JS_GetPrivate (context, obj);      if ( *value == NULL )	rc = VXIjsi_RESULT_FATAL_ERROR;      else 	*value = VXIValueClone (*value);    } else {      // Regular object, create a VXIMap      JSIdArray *props = JS_Enumerate (context, obj);      VXIMap *vmap = NULL;      if ( ! props ) {	rc = VXIjsi_RESULT_FATAL_ERROR;      } else if ( (vmap = VXIMapCreate( )) == NULL ) {	rc = VXIjsi_RESULT_OUT_OF_MEMORY;      } else {	// Traverse through the properties in the object (could be empty,	// in which case we want to return an empty VXIMap)	for (jsint i = 0;	     (( rc == VXIjsi_RESULT_SUCCESS ) && ( i < props->length )); i++) {	  // Get the property name, looks funky but this was	  // recommended by one of the SpiderMonkey contributors in a	  // newsgroup thread	  jsval prName = JSVAL_VOID, prVal = JSVAL_VOID;	  if ( JS_IdToValue (context, props->vector[i], &prName) ) {	    const jschar *name = JS_GetStringChars (JSVAL_TO_STRING (prName));	    size_t namelen = JS_GetStringLength(JSVAL_TO_STRING (prName));	    // Lookup the property, convert to a value, then add to the map	    if (( name ) &&		( JS_GetUCProperty (context, obj, name, namelen, &prVal) )) {	      VXIValue *prValue;	      GET_VXICHAR_FROM_JSCHAR(tmpname, name);	      rc = JsvalToVXIValue (context, prVal, &prValue);	      if (( rc == VXIjsi_RESULT_SUCCESS ) &&		  ( VXIMapSetProperty (vmap, tmpname, prValue) 		    != VXIvalue_RESULT_SUCCESS )) {		rc = VXIjsi_RESULT_OUT_OF_MEMORY;		VXIValueDestroy (&prValue);	      }	    } else {	      rc = VXIjsi_RESULT_FATAL_ERROR;	    }	  } else {	    rc = VXIjsi_RESULT_FATAL_ERROR;	  }	}	if ( rc == VXIjsi_RESULT_SUCCESS )	  *value = (VXIValue *) vmap;	else	  VXIMapDestroy (&vmap);      }      // Free the ID array      if ( props )	JS_DestroyIdArray (context, props);    }  }  else                             // JavaScript undefined (VOID)    rc = VXIjsi_RESULT_NON_FATAL_ERROR;  // Check for out of memory during VXIValue type create  if (( rc == VXIjsi_RESULT_SUCCESS ) && ( *value == NULL ))    rc = VXIjsi_RESULT_OUT_OF_MEMORY;  return rc;}// Convert VXIValue types to JS valuesVXIjsiResult JsiContext::VXIValueToJsval (JSContext *context,					  const VXIValue *value,					  JsiProtectedJsval *val){  VXIjsiResult rc = VXIjsi_RESULT_SUCCESS;  if (( value == NULL ) || ( val == NULL ))    return VXIjsi_RESULT_INVALID_ARGUMENT;  switch ( VXIValueGetType (value) ) {  case VALUE_INTEGER: {    VXIint32 i = VXIIntegerValue ((VXIInteger *) value);    if ( INT_FITS_IN_JSVAL(i) )      rc = val->Set (INT_TO_JSVAL(i));    else      rc = VXIjsi_RESULT_NON_FATAL_ERROR;    } break;  case VALUE_FLOAT: {    jsdouble *d = JS_NewDouble (context, 				(double) VXIFloatValue ((VXIFloat *) value));    if ( d )      rc = val->Set (DOUBLE_TO_JSVAL(d));    else      rc = VXIjsi_RESULT_OUT_OF_MEMORY;    } break;  case VALUE_STRING: {    GET_JSCHAR_FROM_VXICHAR(tmpvalue, tmpvaluelen, 			    VXIStringCStr ((const VXIString *) value));    JSString *s = JS_NewUCStringCopyZ (context, tmpvalue);    if ( s )      rc = val->Set (STRING_TO_JSVAL(s));    else      rc = VXIjsi_RESULT_OUT_OF_MEMORY;    } break;  case VALUE_PTR:    // Not supported in JavaScript    rc = VXIjsi_RESULT_NON_FATAL_ERROR;    break;  case VALUE_CONTENT: {    // Create an object for the content, attach the passed content as    // private data. We set the return value prior to setting the    // private data to avoid getting garbage collected in the    // meantime.    VXIValue *c = NULL;    JSObject *content = JS_NewObject (context, &CONTENT_CLASS, NULL, NULL);    if (( ! content ) || 	( val->Set (OBJECT_TO_JSVAL(content)) != VXIjsi_RESULT_SUCCESS ) ||	( (c = VXIValueClone (value)) == NULL )) {      val->Clear( );      rc = VXIjsi_RESULT_OUT_OF_MEMORY; // JS object gets garbage collected    } else if ( ! JS_SetPrivate (context, content, c) ) {      val->Clear( );      rc = VXIjsi_RESULT_FATAL_ERROR;    }    } break;  case VALUE_MAP: {    // Create an object for the map, temporarily root it so the data    // added underneath is not garbage collected on us    JSObject *mapObj = JS_NewObject (context, &MAP_CLASS, NULL, NULL);    if ( ! mapObj ) {      rc = VXIjsi_RESULT_OUT_OF_MEMORY;    } else if ( (rc = val->Set (OBJECT_TO_JSVAL (mapObj))) ==		VXIjsi_RESULT_SUCCESS ) {      // Walk the map and add object properties, the map may be empty      const VXIchar *prop;      const VXIValue *propValue;      VXIMapIterator *it = VXIMapGetFirstProperty ((const VXIMap *) value, 						   &prop, &propValue);      while (( it ) && ( rc == VXIjsi_RESULT_SUCCESS )) {	JsiProtectedJsval propVal (context);	rc = VXIValueToJsval (context, propValue, &propVal);	if ( rc == VXIjsi_RESULT_SUCCESS ) {	  GET_JSCHAR_FROM_VXICHAR(tmpprop, tmpproplen, prop);	  if ( ! JS_DefineUCProperty (context, mapObj, tmpprop, tmpproplen,				      propVal.Get( ), NULL, NULL, 				      JSPROP_ENUMERATE) )	    rc = VXIjsi_RESULT_OUT_OF_MEMORY;	}		if ( VXIMapGetNextProperty (it, &prop, &propValue) != 	     VXIvalue_RESULT_SUCCESS ) {	  VXIMapIteratorDestroy (&it);	  it = NULL;	}      }      if ( it )	VXIMapIteratorDestroy (&it);    }    } break;  case VALUE_VECTOR: {    // Create a vector for the map, temporarily root it so the data    // added underneath is not garbage collected on us    JSObject *vecObj = JS_NewArrayObject (context, 0, NULL);    if ( ! vecObj ) {      rc = VXIjsi_RESULT_OUT_OF_MEMORY;    } else if ( (rc = val->Set (OBJECT_TO_JSVAL (vecObj))) ==		VXIjsi_RESULT_SUCCESS ) {      // Walk the map and add object properties, the map may be empty      const VXIVector *vec = (const VXIVector *) value;      VXIunsigned i = 0;      const VXIValue *elValue;      while (( rc == VXIjsi_RESULT_SUCCESS ) &&	     ( (elValue = VXIVectorGetElement (vec, i)) != NULL )) {	JsiProtectedJsval elVal (context);	rc = VXIValueToJsval (context, elValue, &elVal);	if (( rc == VXIjsi_RESULT_SUCCESS ) &&	    ( ! JS_DefineElement (context, vecObj, i, elVal.Get( ), NULL,				  NULL, JSPROP_ENUMERATE) ))	  rc = VXIjsi_RESULT_OUT_OF_MEMORY;	i++;      }    }    } break;  default:    rc = VXIjsi_RESULT_UNSUPPORTED;  }  if ( rc != VXIjsi_RESULT_SUCCESS )    val->Clear( );  return rc;}// Static callback for finalizing scopesvoid JS_DLL_CALLBACK JsiContext::ScopeFinalize (JSContext *context, JSObject *obj){  // Get this for logging the destruction  JsiContext *pThis = (JsiContext *) JS_GetContextPrivate (context);  // Get the scope node from the private data and delete it  JsiScopeChainNode *scopeNode =     (JsiScopeChainNode *) JS_GetPrivate (context, obj);  if ( scopeNode ) {    if ( pThis )      pThis->Diag (SBJSI_LOG_SCOPE, L"JsiContext::ScopeFinalize",		   L"scope garbage collected %s (0x%p), context 0x%p", 		   scopeNode->GetName( ).c_str( ), obj, context);    delete scopeNode;  }}// Static callback for finalizing content objectsvoid JS_DLL_CALLBACK JsiContext::ContentFinalize (JSContext *cx, JSObject *obj){  // Get the scope name from the private data and delete it  VXIContent *content = (VXIContent *) JS_GetPrivate (cx, obj);  if ( content ) {    VXIValue *tmp = (VXIValue *) content;    VXIValueDestroy (&tmp);  }}// Static callback for enforcing maxBranchesJSBool JS_DLL_CALLBACK JsiContext::BranchCallback (JSContext *context, JSScript *script){  if ( ! context )    return JS_FALSE;  // Get ourself from our private data  JsiContext *pThis = (JsiContext *) JS_GetContextPrivate (context);  if ( ! pThis ) {    // Severe error    return JS_FALSE;  }  pThis->numBranches++;  JSBool rc = JS_TRUE;  if ( pThis->numBranches > pThis->maxBranches ) {    rc = JS_FALSE;    pThis->Error (JSI_WARN_MAX_BRANCHES_EXCEEDED, L"%s%ld", 		  L"maxBranches", pThis->maxBranches);  }  return rc;}// Static callback for reporting JavaScript errorsvoid JS_DLL_CALLBACK JsiContext::ErrorReporter (JSContext *context, 						const char *message,						JSErrorReport *report){  if ( ! context )    return;  // Get ourself from our private data  JsiContext *pThis = (JsiContext *) JS_GetContextPrivate (context);  if ( ! pThis )    return;  // Severe error  // Save exception information, ownership of the value is passed  jsval ex = JSVAL_VOID;  VXIValue *exception = NULL;  if (( JS_IsExceptionPending (context) ) &&      ( JS_GetPendingException (context, &ex) ) &&      ( JsvalToVXIValue (context, ex, &exception) == VXIjsi_RESULT_SUCCESS )) {    if ( pThis->exception )       VXIValueDestroy (&pThis->exception);    pThis->exception = exception;  }  if ( pThis->logEnabled ) {    // Convert the ASCII string to wide characters    wchar_t wmessage[1024];    size_t len = strlen (message);    if ( len > 1023 )      len = 1023;    for (size_t i = 0; i < len; i++)      wmessage[i] = (wchar_t) message[i];    wmessage[len] = 0;        // Determine the error number to log    unsigned int errNum;    if ( JSREPORT_IS_WARNING (report->flags) )      errNum = JSI_WARN_SM_SCRIPT_WARNING;    else if ( JSREPORT_IS_EXCEPTION (report->flags) )      errNum = JSI_ERROR_SM_SCRIPT_EXCEPTION;    else if ( JSREPORT_IS_STRICT (report->flags) )      errNum = JSI_WARN_SM_SCRIPT_STRICT;    else      errNum = JSI_ERROR_SM_SCRIPT_ERROR;        // Log the error    GET_VXICHAR_FROM_JSCHAR(tmpuclinebuf, report->uclinebuf);    GET_VXICHAR_FROM_JSCHAR(tmpuctokenptr, report->uctokenptr);    pThis->Error (errNum, L"%s%s%s%ld%s%s%s%s", L"errmsg", wmessage,		  L"line", report->lineno, L"linetxt", tmpuclinebuf,		  L"tokentxt", tmpuctokenptr);  }}

⌨️ 快捷键说明

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