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

📄 jsicontext.cpp

📁 Open VXI. This is a open source.
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/***************************************************************************** ***************************************************************************** * * $Id: JsiContext.cpp,v 1.34.6.4 2001/10/03 16:20:52 dmeyer Exp $ * * JsiContext, class for managing JavaScript contexts  * * The JsiContext class represents a JavaScript context, a script * execution state. All JavaScript variables are maintained in a * context, and all scripts are executed in reference to a context * (for accessing variables and maintaining script side-effects). Each * context may have one or more scopes that are used to layer the * state information so that it is possible for clients to control the * lifetime of state information within the context. * SBjsiInterface, definition of the real SBjsi resource object * ***************************************************************************** ****************************************************************************//****************License************************************************ * * Copyright 2000-2001.  SpeechWorks International, Inc.   * * Use of this software is subject to notices and obligations set forth * in the SpeechWorks Public License - Software Version 1.1 which is * included with this software. * * SpeechWorks is a registered trademark, and SpeechWorks Here,  * DialogModules and the SpeechWorks logo are trademarks of SpeechWorks  * International, Inc. in the United States and other countries.  *  ************************************************************************ */static const char *rcsid = 0 ? (char *) &rcsid :"$Id: JsiContext.cpp,v 1.34.6.4 2001/10/03 16:20:52 dmeyer Exp $";// -----1=0-------2=0-------3=0-------4=0-------5=0-------6=0-------7=0-------8#include "SBjsiInternal.h"#include <string.h>                  // For strlen( )#include <jsapi.h>                   // SpiderMonkey API#include "SBjsiLog.h"                // For logging#include "SBinetString.hpp"          // For SBinetString#include "JsiRuntime.hpp"            // For the JsiRuntime class#include "JsiContext.hpp"            // Defines this class// SpiderMonkey class that describes our scope objects which we use// as contextsstatic JSClass SCOPE_CLASS = {    "__SBjsiScope", JSCLASS_HAS_PRIVATE,    JS_PropertyStub,  JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,    JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub,      JsiContext::ScopeFinalize, JSCLASS_NO_OPTIONAL_MEMBERS};// SpiderMonkey class that describes our content objects which we use// to point at VXIContent objectsstatic JSClass CONTENT_CLASS = {    "__SBjsiContent", JSCLASS_HAS_PRIVATE,    JS_PropertyStub,  JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,    JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub,      JsiContext::ContentFinalize, JSCLASS_NO_OPTIONAL_MEMBERS};// SpiderMonkey class that describes our objects which we create from// a VXIMap, just very simple objectsstatic JSClass MAP_CLASS = {    "__SBjsiMap", 0,    JS_PropertyStub,  JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,    JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub,      JS_FinalizeStub, JSCLASS_NO_OPTIONAL_MEMBERS};// Names for JS objects we protect from garbage collection, only used// for SpiderMonkey debugging purposesstatic const char GLOBAL_SCOPE_NAME[]  = "__SBjsiGlobalScope";static const wchar_t GLOBAL_SCOPE_NAME_W[]  = L"__SBjsiGlobalScope";static const char SCRIPT_OBJECT_NAME[] = "__SBjsiScriptObject";static const char PROTECTED_JSVAL_NAME[] = "__SBjsiProtectedJsval";// Global variable we use for temporariesstatic const char GLOBAL_TEMP_VAR[] = "__SBjsiTempVar";static const wchar_t GLOBAL_TEMP_VAR_W[] = L"__SBjsiTempVar";// -----1=0-------2=0-------3=0-------4=0-------5=0-------6=0-------7=0-------8// Macros and objects used to efficiently convert between VXIchar (native// OS wchar_t, usually 16 bits but under GNU gcc 32 bits) and jschar// (SpiderMonkey 16 bit).class JsiConvertJschar { public:  JsiConvertJschar(const jschar *in) : len(0), str(NULL) {    if (in) {      while (in[len])	len++;    }    str = new VXIchar [len + 1];    str[len] = 0;    for (size_t i = 0; i < len; i++)      str[i] = in[i];  }  ~JsiConvertJschar( ) { if (str) delete [] str; }  const VXIchar *Get( ) const { return str; }  size_t GetLength( ) const { return len; } private:  size_t   len;  VXIchar *str;};class JsiConvertVXIchar { public:  JsiConvertVXIchar(const VXIchar *in) : len(0), str(NULL) {    if (in)      len = wcslen (in);    str = new jschar [len + 1];    str[len] = 0;    for (size_t i = 0; i < len; i++)      str[i] = (jschar) in[i];  }  ~JsiConvertVXIchar( ) { if (str) delete [] str; }  const jschar *Get( ) const { return str; }  size_t GetLength( ) const { return len; } private:  size_t   len;  jschar  *str;};#ifdef VXICHAR_SIZE_16_BITS#define GET_VXICHAR_FROM_JSCHAR(out, in) \  const VXIchar *out = (const VXIchar *) in#define GET_JSCHAR_FROM_VXICHAR(out, outlen, in) \  const jschar *out = (const jschar *) in; \  size_t outlen = wcslen(in)#else /* not VXICHAR_SIZE_16_BITS */#define GET_VXICHAR_FROM_JSCHAR(out, in) \  JsiConvertJschar convert_##out(in); \  const VXIchar *out = convert_##out.Get( )#define GET_JSCHAR_FROM_VXICHAR(out, outlen, in) \  JsiConvertVXIchar convert_##out(in); \  const jschar *out = convert_##out.Get( ); \  size_t outlen = convert_##out.GetLength( )#endif /* VXICHAR_SIZE_16_BITS */// -----1=0-------2=0-------3=0-------4=0-------5=0-------6=0-------7=0-------8// Wrapper class around jsval that automatically protects the held// jsval from garbage collectionclass JsiProtectedJsval { public:  // Constructor and destructor  JsiProtectedJsval (JSContext *c) : context(c), val(JSVAL_VOID) { }  ~JsiProtectedJsval( ) { Clear( ); }  // Clear the value  VXIjsiResult Clear( ) {     VXIjsiResult rc;    rc = ((( JSVAL_IS_GCTHING(val) ) && ( ! JS_RemoveRoot (context, &val) )) ?	  VXIjsi_RESULT_FATAL_ERROR : VXIjsi_RESULT_SUCCESS);    val = JSVAL_VOID;    return rc;  }    // Set the value  VXIjsiResult Set (jsval v) {    VXIjsiResult rc = Clear( );    val = v;    if (( JSVAL_IS_GCTHING(val) ) &&	( ! JS_AddNamedRoot (context, &val, PROTECTED_JSVAL_NAME) )){      rc = VXIjsi_RESULT_OUT_OF_MEMORY; // blown away by GC already!    }    return rc;  }  // Accessor  const jsval Get( ) const { return val; } private:  // Disabled copy constructor and assignment operator  JsiProtectedJsval (const JsiProtectedJsval &v);  JsiProtectedJsval &operator=(const JsiProtectedJsval &v); private:  JSContext  *context;  jsval      val;};// -----1=0-------2=0-------3=0-------4=0-------5=0-------6=0-------7=0-------8// Scope chain class, used to keep the scope chain independantly of// the actual user visible scope chain to avoid crashes from invalid// or malicious scripts (push a scope called "session", then overwrite// that variable with an integer named "session", then try to do more// work in that scope)class JsiScopeChainNode { public:  // Constructor and destructor  JsiScopeChainNode (JSContext *context, JsiScopeChainNode *p, 		     const VXIchar *n) :    name(n), parent(p), child(NULL), jsVal(context) { }  ~JsiScopeChainNode( ) { }  // Creation method  VXIjsiResult Create (JSObject *scopeObj) {     return jsVal.Set (OBJECT_TO_JSVAL(scopeObj)); }  // Accessors  const SBinetString & GetName( )   const { return name; }  jsval                GetJsval( )  { return jsVal.Get( ); }  JSObject           * GetJsobj( )  { return JSVAL_TO_OBJECT(jsVal.Get( )); }  JsiScopeChainNode  * GetParent( ) { return parent; }  JsiScopeChainNode  * GetChild( )  { return child; }  // Set the child scope  void SetChild (JsiScopeChainNode *c) { child = c; }  // Release this scope and all under it  VXIjsiResult Release( ); private:  SBinetString        name;      // Name of this scope  JsiScopeChainNode  *parent;    // Parent scope  JsiScopeChainNode  *child;     // Child scope, may be NULL  JsiProtectedJsval   jsVal;     // JS object for the scope};VXIjsiResult JsiScopeChainNode::Release( ){  JsiScopeChainNode *node = this, *next = NULL;  while (node) {    // Release the lock on the underlying object    node->jsVal.Clear( );    // Clear pointers for safety and advance to child scopes    next = node->child;    node->parent = NULL;    node->child = NULL;    node = next;    // NOTE: the deletion of this node and the child nodes is handled    // by the ScopeFinalize( ) method that is called when the JS    // object is garbage collected  }  return VXIjsi_RESULT_SUCCESS;}// -----1=0-------2=0-------3=0-------4=0-------5=0-------6=0-------7=0-------8// Constructor, only does initialization that cannot failJsiContext::JsiContext( ) : SBinetLogger (MODULE_SBJSI, NULL, 0),  version(JSVERSION_DEFAULT), runtime(NULL), context(NULL),  contextRefs(0), scopeChain(NULL), currentScope(NULL), logEnabled(true),  maxBranches(0L), numBranches(0L), exception(NULL){}// DestructorJsiContext::~JsiContext( ){  Diag (SBJSI_LOG_CONTEXT, L"JsiContext::~JsiContext", 	L"start 0x%p, JS context 0x%p", this, context);      if ( exception )    VXIValueDestroy (&exception);  if ( context ) {    // Lock the context for access#ifdef JS_THREADSAFE    JS_ResumeRequest (context, contextRefs);#else    if ( ! AccessBegin( ) )      return;#endif    // Destroy the scope chain, which automatically unroots the global    // scope to allow garbage collection of everything    if ( scopeChain )      scopeChain->Release( );    // Release the lock, must be done before destroying the context#ifdef JS_THREADSAFE    JS_EndRequest (context);#else    AccessEnd( );#endif    // Destroy the context, is set to NULL    runtime->DestroyContext (&context);  }  Diag (SBJSI_LOG_CONTEXT, L"JsiContext::~JsiContext", L"end 0x%p", this);}// Creation methodVXIjsiResult JsiContext::Create (JsiRuntime        *rt, 				 long               contextSize, 				 long               mb,				 VXIlogInterface   *l,				 VXIunsigned        diagTagBase){  if (( rt == NULL ) || ( contextSize < 1 ) || ( mb < 1 ) ||      ( l == NULL ))    return VXIjsi_RESULT_INVALID_ARGUMENT;  // Copy simple variables  runtime = rt;  maxBranches = mb;  // Base logging class initialization  SetLog (l, diagTagBase);  Diag (SBJSI_LOG_CONTEXT, L"JsiContext::Create", L"start 0x%p", this);  // Create the context  VXIjsiResult rc = runtime->NewContext (contextSize, &context);  if ( rc != VXIjsi_RESULT_SUCCESS )    return rc;  // Lock the context for access#ifdef JS_THREADSAFE  JS_BeginRequest (context);#else  if ( AccessBegin( ) != true )    rc = VXIjsi_RESULT_SYSTEM_ERROR;#endif  // Attach this as private data to the context for use in callbacks  if ( rc == VXIjsi_RESULT_SUCCESS )    JS_SetContextPrivate (context, this);  // Set the callback to enforce maxBranches  if ( rc == VXIjsi_RESULT_SUCCESS )    JS_SetBranchCallback (context, JsiContext::BranchCallback);    // Set the callback for reporting errors  if ( rc == VXIjsi_RESULT_SUCCESS )    JS_SetErrorReporter (context, JsiContext::ErrorReporter);#if 0  // Enable strictness, which provides additional warnings/errors.  // NOTE: Disabled for now, may want this configurable in the future.  if ( rc == VXIjsi_RESULT_SUCCESS )    JS_SetOptions (context, JSOPTION_STRICT);#endif  // Create and intialize the global scope we require in the context,  // the scope chain node object locks it to protect it from the  // garbage collector  if ( rc == VXIjsi_RESULT_SUCCESS ) {    JSObject *globalScope = JS_NewObject (context, &SCOPE_CLASS, NULL, NULL);    if ( ! globalScope )      rc = VXIjsi_RESULT_OUT_OF_MEMORY;    else {      Diag (SBJSI_LOG_SCOPE, L"JsiContext::Create", 	    L"global scope 0x%p, context 0x%p", globalScope, context);      scopeChain = new JsiScopeChainNode (context, NULL, GLOBAL_SCOPE_NAME_W);      if ( scopeChain ) {	rc = scopeChain->Create (globalScope);	if ( rc == VXIjsi_RESULT_SUCCESS ) {	  if ( JS_SetPrivate (context, globalScope, scopeChain) )	    currentScope = scopeChain;	  else	    rc = VXIjsi_RESULT_FATAL_ERROR;	}      } else {	rc = VXIjsi_RESULT_OUT_OF_MEMORY;      }    }  }  // Initialize the standard JavaScript classes, like Array, Math, String, etc.  if (( rc == VXIjsi_RESULT_SUCCESS ) &&      ( ! JS_InitStandardClasses (context, currentScope->GetJsobj( )) ))    rc = VXIjsi_RESULT_OUT_OF_MEMORY;  // Set version only after there is a valid global scope object  if (( rc == VXIjsi_RESULT_SUCCESS ) &&      ( version != JSVERSION_DEFAULT ))    JS_SetVersion (context, version);  // On failure, destroy the context here to avoid use of it  if ( rc != VXIjsi_RESULT_SUCCESS ) {    if ( context ) {#ifdef JS_THREADSAFE      JS_EndRequest (context);#endif      runtime->DestroyContext (&context);    }  }#ifdef JS_THREADSAFE  else {    contextRefs = JS_SuspendRequest (context);  }#else  if ( AccessEnd( ) != true )    rc = VXIjsi_RESULT_SYSTEM_ERROR;#endif  Diag (SBJSI_LOG_CONTEXT, L"JsiContext::Create", 	L"end 0x%p, JS context 0x%p", this, context);  return rc;}// Create a script variable relative to the current scope

⌨️ 快捷键说明

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