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

📄 jsicontext.cpp

📁 sloedgy open sip stack source code
💻 CPP
📖 第 1 页 / 共 4 页
字号:
   
   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)
         jsint i = 0;
         for (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 = NULL;
             size_t namelen = 0;
             if ( JSVAL_IS_STRING (prName) ) {
               name = JS_GetStringChars (JSVAL_TO_STRING (prName));
               namelen = JS_GetStringLength (JSVAL_TO_STRING (prName));
             } else if ( JSVAL_IS_INT (prName) ) {
               JSString *str = JS_ValueToString (context, prName);
               name = JS_GetStringChars (str);
               namelen = JS_GetStringLength (str);
             }
       
             // Lookup the property, convert to a value, then add to the map
             if (( name ) &&
                ( JS_GetUCProperty (context, obj, name, namelen, &prVal) )) {
               VXIValue *prValue = NULL;
               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);
               }
               if( rc == VXIjsi_RESULT_NON_FATAL_ERROR )
                 rc = VXIjsi_RESULT_SUCCESS;
             } 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 values
 VXIjsiResult 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_BOOLEAN: {
     VXIbool i = VXIBooleanValue ((const VXIBoolean *) value);
     rc = val->Set (BOOLEAN_TO_JSVAL(i));
     } break;
 
   case VALUE_INTEGER: {
     VXIint32 i = VXIIntegerValue ((const 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 ((const 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));
     tmpvaluelen;
     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 scopes
 void 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 objects
 void 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 maxBranches
 JSBool 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 errors
 void 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 ? tmpuclinebuf : L""), 
       L"tokentxt", (tmpuctokenptr ? tmpuctokenptr : L""));
   }
 }
 
 // Check if the variable name is valid at declaration
 bool JsiContext::IsValidVarName(JSContext *context, JSObject *obj, const VXIchar* vname)
 {
   bool ret = true;
   SBjsiString tscript(L"var ");
   tscript += vname;
   GET_JSCHAR_FROM_VXICHAR(tmpscript, tmpscriptlen, tscript.c_str());
     // check if the variable name is valid
   JSScript *jsScript = JS_CompileUCScript (context, obj, 
                                            tmpscript, tmpscriptlen, NULL, 1);
   if( !jsScript ) 
     ret = false;
   else
     JS_DestroyScript (context, jsScript);
   return ret;
 }

#endif

⌨️ 快捷键说明

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