Back to index

lightning-sunbird  0.9+nobinonly
Classes | Typedefs | Functions | Variables
nsJSNPRuntime.cpp File Reference
#include "nsJSNPRuntime.h"
#include "ns4xPlugin.h"
#include "ns4xPluginInstance.h"
#include "nsIPluginInstancePeer2.h"
#include "nsPIPluginInstancePeer.h"
#include "nsIScriptGlobalObject.h"
#include "nsIScriptContext.h"
#include "nsIDocument.h"
#include "nsIJSRuntimeService.h"
#include "nsIJSContextStack.h"
#include "nsIXPConnect.h"
#include "nsIDOMElement.h"
#include "prmem.h"
#include "nsIContent.h"
#include "jscntxt.h"

Go to the source code of this file.

Classes

struct  NPObjectMemberPrivate
struct  AutoCXPusher
class  JSObjWrapperHashEntry
class  NPObjWrapperHashEntry

Typedefs

typedef struct
NPObjectMemberPrivate 
NPObjectMemberPrivate

Functions

 NPObjWrapper_AddProperty (JSContext *cx, JSObject *obj, jsval id, jsval *vp)
 NPObjWrapper_DelProperty (JSContext *cx, JSObject *obj, jsval id, jsval *vp)
 NPObjWrapper_SetProperty (JSContext *cx, JSObject *obj, jsval id, jsval *vp)
 NPObjWrapper_GetProperty (JSContext *cx, JSObject *obj, jsval id, jsval *vp)
 NPObjWrapper_NewResolve (JSContext *cx, JSObject *obj, jsval id, uintN flags, JSObject **objp)
 NPObjWrapper_Finalize (JSContext *cx, JSObject *obj)
 NPObjWrapper_Call (JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
static bool CreateNPObjectMember (NPP npp, JSContext *cx, JSObject *obj, NPObject *npobj, jsval id, jsval *vp)
 NPObjectMember_Convert (JSContext *cx, JSObject *obj, JSType type, jsval *vp)
 NPObjectMember_Finalize (JSContext *cx, JSObject *obj)
 NPObjectMember_Call (JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
 NPObjectMember_Mark (JSContext *cx, JSObject *obj, void *arg)
static void OnWrapperCreated ()
static void OnWrapperDestroyed ()
static JSContextGetJSContext (NPP npp)
static NPP LookupNPP (NPObject *npobj)
static jsval NPVariantToJSVal (NPP npp, JSContext *cx, const NPVariant *variant)
bool JSValToNPVariant (NPP npp, JSContext *cx, jsval val, NPVariant *variant)
static void ThrowJSException (JSContext *cx, const char *message)
static JSBool ReportExceptionIfPending (JSContext *cx)
static JSBool GetProperty (JSContext *cx, JSObject *obj, NPIdentifier identifier, jsval *rval)
static bool doInvoke (NPObject *npobj, NPIdentifier method, const NPVariant *args, uint32_t argCount, NPVariant *result)
 JSObjWrapperHash (PLDHashTable *table, const void *key)
 JSObjWrapperHashGetKey (PLDHashTable *table, PLDHashEntryHdr *entry)
 JSObjWrapperHashMatchEntry (PLDHashTable *table, const PLDHashEntryHdr *entry, const void *key)
static NPObjectGetNPObject (JSContext *cx, JSObject *obj)
 CallNPMethod (JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
 JSObjWrapperPluginDestroyedCallback (PLDHashTable *table, PLDHashEntryHdr *hdr, PRUint32 number, void *arg)
 NPObjWrapperPluginDestroyedCallback (PLDHashTable *table, PLDHashEntryHdr *hdr, PRUint32 number, void *arg)

Variables

static PLDHashTable sJSObjWrappers
static PLDHashTable sNPObjWrappers
static PRInt32 sWrapperCount
static JSRuntimesJSRuntime
static nsIJSContextStacksContextStack
static JSClass sNPObjectJSWrapperClass
static JSClass sNPObjectMemberClass

Class Documentation

struct NPObjectMemberPrivate

Definition at line 133 of file nsJSNPRuntime.cpp.

Collaboration diagram for NPObjectMemberPrivate:
Class Members
jsval fieldValue
jsval methodName
JSObject * npobjWrapper
NPP npp

Typedef Documentation


Function Documentation

CallNPMethod ( JSContext cx,
JSObject obj,
uintN  argc,
jsval argv,
jsval rval 
)

Definition at line 1066 of file nsJSNPRuntime.cpp.

{
  while (JS_GET_CLASS(cx, obj) != &sNPObjectJSWrapperClass) {
    obj = ::JS_GetPrototype(cx, obj);
  }

  if (!obj) {
    ThrowJSException(cx, "NPMethod called on non-NPObject wrapped JSObject!");

    return JS_FALSE;
  }

  NPObject *npobj = (NPObject *)::JS_GetPrivate(cx, obj);

  if (!npobj || !npobj->_class || !npobj->_class->invoke) {
    ThrowJSException(cx, "Bad NPObject as private data!");

    return JS_FALSE;
  }

  // Find out what plugin (NPP) is the owner of the object we're
  // manipulating, and make it own any JSObject wrappers created here.
  NPP npp = LookupNPP(npobj);

  if (!npp) {
    ThrowJSException(cx, "Error finding NPP for NPObject!");

    return JS_FALSE;
  }

  NPVariant npargs_buf[8];
  NPVariant *npargs = npargs_buf;

  if (argc > (sizeof(npargs_buf) / sizeof(NPVariant))) {
    // Our stack buffer isn't large enough to hold all arguments,
    // malloc a buffer.
    npargs = (NPVariant *)PR_Malloc(argc * sizeof(NPVariant));

    if (!npargs) {
      ThrowJSException(cx, "Out of memory!");

      return JS_FALSE;
    }
  }

  // Convert arguments
  PRUint32 i;
  for (i = 0; i < argc; ++i) {
    if (!JSValToNPVariant(npp, cx, argv[i], npargs + i)) {
      ThrowJSException(cx, "Error converting jsvals to NPVariants!");

      return JS_FALSE;
    }
  }

  NPVariant v;
  VOID_TO_NPVARIANT(v);

  JSObject *funobj = JSVAL_TO_OBJECT(argv[-2]);
  JSBool ok;

  if (funobj != obj) {
    // A obj.function() style call is made, get the method name from
    // the function object.

    JSFunction *fun = (JSFunction *)::JS_GetPrivate(cx, funobj);
    jsval method = STRING_TO_JSVAL(::JS_GetFunctionId(fun));

    ok = npobj->_class->invoke(npobj, (NPIdentifier)method, npargs, argc, &v);
  } else {
    // obj is a callable object that is being called, no method name
    // available then. Invoke the default method.

    ok = npobj->_class->invokeDefault(npobj, npargs, argc, &v);
  }

  // Release arguments.
  for (i = 0; i < argc; ++i) {
    _releasevariantvalue(npargs + i);
  }

  if (npargs != npargs_buf) {
    PR_Free(npargs);
  }

  if (!ok) {
    ThrowJSException(cx, "Error calling method on NPObject!");

    return JS_FALSE;
  }

  *rval = NPVariantToJSVal(npp, cx, &v);

  // *rval now owns the value, release our reference.
  _releasevariantvalue(&v);

  return ReportExceptionIfPending(cx);
}

Here is the call graph for this function:

Here is the caller graph for this function:

bool CreateNPObjectMember ( NPP  npp,
JSContext cx,
JSObject obj,
NPObject npobj,
jsval  id,
jsval vp 
) [static]

Definition at line 1562 of file nsJSNPRuntime.cpp.

{
  NS_ENSURE_TRUE(vp, false);

  if (!npobj || !npobj->_class || !npobj->_class->getProperty ||
      !npobj->_class->invoke) {
    ThrowJSException(cx, "Bad NPObject");

    return false;
  }

  NPObjectMemberPrivate *memberPrivate =
    (NPObjectMemberPrivate *)PR_Malloc(sizeof(NPObjectMemberPrivate));
  if (!memberPrivate)
    return false;

  // Make sure to clear all members in case something fails here
  // during initialization.
  memset(memberPrivate, 0, sizeof(NPObjectMemberPrivate));

  JSObject *memobj = ::JS_NewObject(cx, &sNPObjectMemberClass, nsnull, nsnull);
  if (!memobj) {
    PR_Free(memberPrivate);
    return false;
  }

  *vp = OBJECT_TO_JSVAL(memobj);
  ::JS_AddRoot(cx, vp);

  ::JS_SetPrivate(cx, memobj, (void *)memberPrivate);

  jsval fieldValue;
  NPVariant npv;
  VOID_TO_NPVARIANT(npv);
  if (!npobj->_class->getProperty(npobj, (NPIdentifier)id, &npv)) {
    ::JS_RemoveRoot(cx, vp);
    return false;
  }

  fieldValue = NPVariantToJSVal(npp, cx, &npv);

  // npobjWrapper is the JSObject through which we make sure we don't
  // outlive the underlying NPObject, so make sure it points to the
  // real JSObject wrapper for the NPObject.
  while (JS_GET_CLASS(cx, obj) != &sNPObjectJSWrapperClass) {
    obj = ::JS_GetPrototype(cx, obj);
  }

  memberPrivate->npobjWrapper = obj;

  memberPrivate->fieldValue = fieldValue;
  memberPrivate->methodName = id;
  memberPrivate->npp = npp;

  ::JS_RemoveRoot(cx, vp);

  return true;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static bool doInvoke ( NPObject npobj,
NPIdentifier  method,
const NPVariant args,
uint32_t  argCount,
NPVariant result 
) [static]

Definition at line 538 of file nsJSNPRuntime.cpp.

{
  NPP npp = NPPStack::Peek();
  JSContext *cx = GetJSContext(npp);

  if (!cx || !npobj || !result) {
    // XXX: Throw null-ptr exception

    return PR_FALSE;
  }

  // Initialize *result
  VOID_TO_NPVARIANT(*result);

  nsJSObjWrapper *npjsobj = (nsJSObjWrapper *)npobj;
  jsval fv;

  AutoCXPusher pusher(cx);

  if ((jsval)method != JSVAL_VOID) {
    if (!GetProperty(cx, npjsobj->mJSObj, method, &fv) ||
        ::JS_TypeOfValue(cx, fv) != JSTYPE_FUNCTION) {
      return PR_FALSE;
    }
  } else {
    fv = OBJECT_TO_JSVAL(npjsobj->mJSObj);
  }

  jsval jsargs_buf[8];
  jsval *jsargs = jsargs_buf;

  if (argCount > (sizeof(jsargs_buf) / sizeof(jsval))) {
    // Our stack buffer isn't large enough to hold all arguments,
    // malloc a buffer.
    jsargs = (jsval *)PR_Malloc(argCount * sizeof(jsval));

    if (!jsargs) {
      // XXX: throw an OOM exception!

      return PR_FALSE;
    }
  }

  JSTempValueRooter tvr;
  JS_PUSH_TEMP_ROOT(cx, 0, jsargs, &tvr);

  // Convert args
  for (PRUint32 i = 0; i < argCount; ++i) {
    jsargs[i] = NPVariantToJSVal(npp, cx, args + i);
    ++tvr.count;
  }

  jsval v;
  JSBool ok = ::JS_CallFunctionValue(cx, npjsobj->mJSObj, fv, argCount, jsargs,
                                     &v);

  JS_POP_TEMP_ROOT(cx, &tvr);

  if (jsargs != jsargs_buf)
    PR_Free(jsargs);

  if (ok)
    ok = JSValToNPVariant(npp, cx, v, result);

  // return ok == JS_TRUE to quiet down compiler warning, even if
  // return ok is what we really want.
  return ok == JS_TRUE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static JSContext* GetJSContext ( NPP  npp) [static]

Definition at line 253 of file nsJSNPRuntime.cpp.

Here is the call graph for this function:

Here is the caller graph for this function:

static NPObject* GetNPObject ( JSContext cx,
JSObject obj 
) [static]

Definition at line 895 of file nsJSNPRuntime.cpp.

{
  while (JS_GET_CLASS(cx, obj) != &sNPObjectJSWrapperClass) {
    obj = ::JS_GetPrototype(cx, obj);
  }

  if (!obj) {
    return nsnull;
  }

  return (NPObject *)::JS_GetPrivate(cx, obj);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static JSBool GetProperty ( JSContext cx,
JSObject obj,
NPIdentifier  identifier,
jsval rval 
) [static]

Definition at line 500 of file nsJSNPRuntime.cpp.

{
  jsval id = (jsval)identifier;

  AutoCXPusher pusher(cx);

  if (JSVAL_IS_STRING(id)) {
    JSString *str = JSVAL_TO_STRING(id);

    return ::JS_GetUCProperty(cx, obj, ::JS_GetStringChars(str),
                              ::JS_GetStringLength(str), rval);
  }

  NS_ASSERTION(JSVAL_IS_INT(id), "id must be either string or int!\n");

  return ::JS_GetElement(cx, obj, JSVAL_TO_INT(id), rval);
}

Here is the call graph for this function:

JSObjWrapperHash ( PLDHashTable table,
const void key 
)

Definition at line 757 of file nsJSNPRuntime.cpp.

{
  const nsJSObjWrapperKey *e = NS_STATIC_CAST(const nsJSObjWrapperKey *, key);

  return (PLDHashNumber)((PRWord)e->mJSObj ^ (PRWord)e->mNpp) >> 2;
}

Here is the caller graph for this function:

Definition at line 765 of file nsJSNPRuntime.cpp.

Here is the caller graph for this function:

Definition at line 774 of file nsJSNPRuntime.cpp.

{
  const nsJSObjWrapperKey *objWrapperKey =
    NS_STATIC_CAST(const nsJSObjWrapperKey *, key);
  const JSObjWrapperHashEntry *e =
    NS_STATIC_CAST(const JSObjWrapperHashEntry *, entry);

  return (e->mJSObjWrapper->mJSObj == objWrapperKey->mJSObj &&
          e->mJSObjWrapper->mNpp == objWrapperKey->mNpp);
}

Here is the caller graph for this function:

JSObjWrapperPluginDestroyedCallback ( PLDHashTable table,
PLDHashEntryHdr hdr,
PRUint32  number,
void arg 
)

Definition at line 1361 of file nsJSNPRuntime.cpp.

{
  JSObjWrapperHashEntry *entry = (JSObjWrapperHashEntry *)hdr;

  nsJSObjWrapper *npobj = entry->mJSObjWrapper;

  if (npobj->mNpp == arg) {
    // Prevent invalidate() and _releaseobject() from touching the hash
    // we're enumerating.
    const PLDHashTableOps *ops = table->ops;
    table->ops = nsnull;

    if (npobj->_class && npobj->_class->invalidate) {
      npobj->_class->invalidate(npobj);
    }

    _releaseobject(npobj);

    table->ops = ops;

    return PL_DHASH_REMOVE;
  }

  return PL_DHASH_NEXT;
}

Here is the call graph for this function:

Here is the caller graph for this function:

bool JSValToNPVariant ( NPP  npp,
JSContext cx,
jsval  val,
NPVariant variant 
)

Definition at line 348 of file nsJSNPRuntime.cpp.

{
  NS_ASSERTION(npp, "Must have an NPP to wrap a jsval!");

  if (JSVAL_IS_PRIMITIVE(val)) {
    if (val == JSVAL_VOID) {
      VOID_TO_NPVARIANT(*variant);
    } else if (JSVAL_IS_NULL(val)) {
      NULL_TO_NPVARIANT(*variant);
    } else if (JSVAL_IS_BOOLEAN(val)) {
      BOOLEAN_TO_NPVARIANT(JSVAL_TO_BOOLEAN(val), *variant);
    } else if (JSVAL_IS_INT(val)) {
      INT32_TO_NPVARIANT(JSVAL_TO_INT(val), *variant);
    } else if (JSVAL_IS_DOUBLE(val)) {
      DOUBLE_TO_NPVARIANT(*JSVAL_TO_DOUBLE(val), *variant);
    } else if (JSVAL_IS_STRING(val)) {
      JSString *jsstr = JSVAL_TO_STRING(val);
      nsDependentString str((PRUnichar *)::JS_GetStringChars(jsstr),
                            ::JS_GetStringLength(jsstr));

      PRUint32 len;
      char *p = ToNewUTF8String(str, &len);

      if (!p) {
        return false;
      }

      STRINGN_TO_NPVARIANT(p, len, *variant);
    } else {
      NS_ERROR("Unknown primitive type!");

      return false;
    }

    return true;
  }

  NPObject *npobj =
    nsJSObjWrapper::GetNewOrUsed(npp, cx, JSVAL_TO_OBJECT(val));
  if (!npobj) {
    return false;
  }

  // Pass over ownership of npobj to *variant
  OBJECT_TO_NPVARIANT(npobj, *variant);

  return true;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static NPP LookupNPP ( NPObject npobj) [static]

Definition at line 1536 of file nsJSNPRuntime.cpp.

{
  if (npobj->_class == &nsJSObjWrapper::sJSObjWrapperNPClass) {
    NS_ERROR("NPP requested for NPObject of class "
             "nsJSObjWrapper::sJSObjWrapperNPClass!\n");

    return nsnull;
  }



  NPObjWrapperHashEntry *entry =
    NS_STATIC_CAST(NPObjWrapperHashEntry *,
                   PL_DHashTableOperate(&sNPObjWrappers, npobj,
                                        PL_DHASH_ADD));

  if (PL_DHASH_ENTRY_IS_FREE(entry)) {
    return nsnull;
  }

  NS_ASSERTION(entry->mNpp, "Live NPObject entry w/o an NPP!");

  return entry->mNpp;
}

Here is the call graph for this function:

Here is the caller graph for this function:

NPObjectMember_Call ( JSContext cx,
JSObject obj,
uintN  argc,
jsval argv,
jsval rval 
)

Definition at line 1661 of file nsJSNPRuntime.cpp.

{
  JSObject *memobj = JSVAL_TO_OBJECT(argv[-2]);
  NS_ENSURE_TRUE(memobj, JS_FALSE);

  NPObjectMemberPrivate *memberPrivate =
    (NPObjectMemberPrivate *)::JS_GetInstancePrivate(cx, memobj,
                                                     &sNPObjectMemberClass,
                                                     nsnull);
  if (!memberPrivate || !memberPrivate->npobjWrapper)
    return JS_FALSE;

  NPObject *npobj = GetNPObject(cx, memberPrivate->npobjWrapper);
  if (!npobj) {
    ThrowJSException(cx, "Call on invalid member object");

    return JS_FALSE;
  }

  NPVariant npargs_buf[8];
  NPVariant *npargs = npargs_buf;

  if (argc > (sizeof(npargs_buf) / sizeof(NPVariant))) {
    // Our stack buffer isn't large enough to hold all arguments,
    // malloc a buffer.
    npargs = (NPVariant *)PR_Malloc(argc * sizeof(NPVariant));

    if (!npargs) {
      ThrowJSException(cx, "Out of memory!");

      return JS_FALSE;
    }
  }

  // Convert arguments
  PRUint32 i;
  for (i = 0; i < argc; ++i) {
    if (!JSValToNPVariant(memberPrivate->npp, cx, argv[i], npargs + i)) {
      ThrowJSException(cx, "Error converting jsvals to NPVariants!");

      if (npargs != npargs_buf) {
        PR_Free(npargs);
      }

      return JS_FALSE;
    }
  }

  NPVariant npv;
  JSBool ok;
  ok = npobj->_class->invoke(npobj, (NPIdentifier)memberPrivate->methodName,
                             npargs, argc, &npv);

  // Release arguments.
  for (i = 0; i < argc; ++i) {
    _releasevariantvalue(npargs + i);
  }

  if (npargs != npargs_buf) {
    PR_Free(npargs);
  }

  if (!ok) {
    ThrowJSException(cx, "Error calling method on NPObject!");

    return JS_FALSE;
  }

  *rval = NPVariantToJSVal(memberPrivate->npp, cx, &npv);

  // *rval now owns the value, release our reference.
  _releasevariantvalue(&npv);

  return ReportExceptionIfPending(cx);
}

Here is the call graph for this function:

NPObjectMember_Convert ( JSContext cx,
JSObject obj,
JSType  type,
jsval vp 
)

Definition at line 1623 of file nsJSNPRuntime.cpp.

{
  NPObjectMemberPrivate *memberPrivate =
    (NPObjectMemberPrivate *)::JS_GetInstancePrivate(cx, obj,
                                                     &sNPObjectMemberClass,
                                                     nsnull);
  NS_ASSERTION(memberPrivate, "no Ambiguous Member Private data!");

  switch (type) {
  case JSTYPE_VOID:
  case JSTYPE_STRING:
  case JSTYPE_NUMBER:
  case JSTYPE_BOOLEAN:
  case JSTYPE_OBJECT:
    *vp = memberPrivate->fieldValue;
    return JS_TRUE;
  case JSTYPE_FUNCTION:
    // Leave this to NPObjectMember_Call.
    return JS_TRUE;
  default:
    NS_ERROR("illegal operation on JSObject prototype object");
    return JS_FALSE;
  }
}

Here is the call graph for this function:

Definition at line 1649 of file nsJSNPRuntime.cpp.

{
  NPObjectMemberPrivate *memberPrivate;

  memberPrivate = (NPObjectMemberPrivate *)::JS_GetPrivate(cx, obj);
  if (!memberPrivate)
    return;

  PR_Free(memberPrivate);
}

Here is the call graph for this function:

NPObjectMember_Mark ( JSContext cx,
JSObject obj,
void arg 
)

Definition at line 1739 of file nsJSNPRuntime.cpp.

{
  NPObjectMemberPrivate *memberPrivate =
    (NPObjectMemberPrivate *)::JS_GetInstancePrivate(cx, obj,
                                                     &sNPObjectMemberClass,
                                                     nsnull);
  if (!memberPrivate)
    return 0;

  if (!JSVAL_IS_PRIMITIVE(memberPrivate->fieldValue)) {
    ::JS_MarkGCThing(cx, JSVAL_TO_OBJECT(memberPrivate->fieldValue),
                     "NPObject Member => fieldValue", arg);
  }

  // There's no strong reference from our private data to the
  // NPObject, so make sure to mark the NPObject wrapper to keep the
  // NPObject alive as long as this NPObjectMember is alive.
  if (memberPrivate->npobjWrapper) {
    ::JS_MarkGCThing(cx, memberPrivate->npobjWrapper,
                     "NPObject Member => npobjWrapper", arg);
  }

  return 0;
}

Here is the call graph for this function:

NPObjWrapper_AddProperty ( JSContext cx,
JSObject obj,
jsval  id,
jsval vp 
)

Definition at line 909 of file nsJSNPRuntime.cpp.

{
  NPObject *npobj = GetNPObject(cx, obj);

  if (!npobj || !npobj->_class || !npobj->_class->hasProperty ||
      !npobj->_class->hasMethod) {
    ThrowJSException(cx, "Bad NPObject as private data!");

    return JS_FALSE;
  }

  // We must permit methods here since JS_DefineUCFunction() will add
  // the function as a property
  if (!npobj->_class->hasProperty(npobj, (NPIdentifier)id) &&
      !npobj->_class->hasMethod(npobj, (NPIdentifier)id)) {
    ThrowJSException(cx, "Trying to add unsupported property on scriptable "
                     "plugin object!");

    return JS_FALSE;
  }

  return ReportExceptionIfPending(cx);
}

Here is the call graph for this function:

NPObjWrapper_Call ( JSContext cx,
JSObject obj,
uintN  argc,
jsval argv,
jsval rval 
)

Definition at line 1247 of file nsJSNPRuntime.cpp.

{
  return CallNPMethod(cx, JSVAL_TO_OBJECT(argv[-2]), argc, argv, rval);
}

Here is the call graph for this function:

NPObjWrapper_DelProperty ( JSContext cx,
JSObject obj,
jsval  id,
jsval vp 
)

Definition at line 934 of file nsJSNPRuntime.cpp.

{
  NPObject *npobj = GetNPObject(cx, obj);

  if (!npobj || !npobj->_class || !npobj->_class->hasProperty) {
    ThrowJSException(cx, "Bad NPObject as private data!");

    return JS_FALSE;
  }

  if (!npobj->_class->hasProperty(npobj, (NPIdentifier)id)) {
    ThrowJSException(cx, "Trying to remove unsupported property on scriptable "
                     "plugin object!");

    return JS_FALSE;
  }

  return ReportExceptionIfPending(cx);
}

Here is the call graph for this function:

NPObjWrapper_Finalize ( JSContext cx,
JSObject obj 
)

Definition at line 1230 of file nsJSNPRuntime.cpp.

{
  NPObject *npobj = (NPObject *)::JS_GetPrivate(cx, obj);

  if (npobj) {
    if (sNPObjWrappers.ops) {
      PL_DHashTableOperate(&sNPObjWrappers, npobj, PL_DHASH_REMOVE);
    }

    // Let go of our NPObject
    _releaseobject(npobj);
  }

  OnWrapperDestroyed();
}

Here is the call graph for this function:

NPObjWrapper_GetProperty ( JSContext cx,
JSObject obj,
jsval  id,
jsval vp 
)

Definition at line 1006 of file nsJSNPRuntime.cpp.

{
  NPObject *npobj = GetNPObject(cx, obj);

  if (!npobj || !npobj->_class || !npobj->_class->hasProperty ||
      !npobj->_class->hasMethod || !npobj->_class->getProperty) {
    ThrowJSException(cx, "Bad NPObject as private data!");

    return JS_FALSE;
  }

  PRBool hasProperty = npobj->_class->hasProperty(npobj, (NPIdentifier)id);
  PRBool hasMethod = npobj->_class->hasMethod(npobj, (NPIdentifier)id);
  NPP npp = nsnull;
  if (hasProperty) {
    // Find out what plugin (NPP) is the owner of the object we're
    // manipulating, and make it own any JSObject wrappers created
    // here.
    npp = LookupNPP(npobj);
    if (!npp) {
      ThrowJSException(cx, "No NPP found for NPObject!");

      return JS_FALSE;
    }
  }

  // To support ambiguous members, we return NPObject Member class here.
  if (hasProperty && hasMethod)
    return CreateNPObjectMember(npp, cx, obj, npobj, id, vp);

  if (hasProperty) {
    NPVariant npv;
    VOID_TO_NPVARIANT(npv);

    if (!npobj->_class->getProperty(npobj, (NPIdentifier)id, &npv)) {
      ThrowJSException(cx, "Error setting property on scriptable plugin "
                       "object!");

      return JS_FALSE;
    }

    *vp = NPVariantToJSVal(npp, cx, &npv);

    // *vp now owns the value, release our reference.
    _releasevariantvalue(&npv);

    return JS_TRUE;
  }

  if (!hasMethod) {
    ThrowJSException(cx, "Trying to get unsupported property on scriptable "
                     "plugin object!");

    return JS_FALSE;
  }

  return ReportExceptionIfPending(cx);
}

Here is the call graph for this function:

NPObjWrapper_NewResolve ( JSContext cx,
JSObject obj,
jsval  id,
uintN  flags,
JSObject **  objp 
)

Definition at line 1168 of file nsJSNPRuntime.cpp.

{
  NPObject *npobj = GetNPObject(cx, obj);

  if (!npobj || !npobj->_class || !npobj->_class->hasProperty ||
      !npobj->_class->hasMethod) {
    ThrowJSException(cx, "Bad NPObject as private data!");

    return JS_FALSE;
  }

  if (npobj->_class->hasProperty(npobj, (NPIdentifier)id)) {
    JSBool ok;

    if (JSVAL_IS_STRING(id)) {
      JSString *str = JSVAL_TO_STRING(id);

      ok = ::JS_DefineUCProperty(cx, obj, ::JS_GetStringChars(str),
                                 ::JS_GetStringLength(str), JSVAL_VOID, nsnull,
                                 nsnull, JSPROP_ENUMERATE);
    } else {
      ok = ::JS_DefineElement(cx, obj, JSVAL_TO_INT(id), JSVAL_VOID, nsnull,
                              nsnull, JSPROP_ENUMERATE);
    }

    if (!ok) {
      return JS_FALSE;
    }

    *objp = obj;
  } else if (npobj->_class->hasMethod(npobj, (NPIdentifier)id)) {
    JSString *str = nsnull;

    if (JSVAL_IS_STRING(id)) {
      str = JSVAL_TO_STRING(id);
    } else {
      NS_ASSERTION(JSVAL_IS_INT(id), "id must be either string or int!\n");

      str = ::JS_ValueToString(cx, id);

      if (!str) {
        // OOM. The JS engine throws exceptions for us in this case.

        return JS_FALSE;
      }
    }

    JSFunction *fnc =
      ::JS_DefineUCFunction(cx, obj, ::JS_GetStringChars(str),
                            ::JS_GetStringLength(str), CallNPMethod, 0,
                            JSPROP_ENUMERATE);

    *objp = obj;

    return fnc != nsnull;
  }

  return ReportExceptionIfPending(cx);
}

Here is the call graph for this function:

NPObjWrapper_SetProperty ( JSContext cx,
JSObject obj,
jsval  id,
jsval vp 
)

Definition at line 955 of file nsJSNPRuntime.cpp.

{
  NPObject *npobj = GetNPObject(cx, obj);

  if (!npobj || !npobj->_class || !npobj->_class->hasProperty ||
      !npobj->_class->setProperty) {
    ThrowJSException(cx, "Bad NPObject as private data!");

    return JS_FALSE;
  }

  if (!npobj->_class->hasProperty(npobj, (NPIdentifier)id)) {
    ThrowJSException(cx, "Trying to set unsupported property on scriptable "
                     "plugin object!");

    return JS_FALSE;
  }

  // Find out what plugin (NPP) is the owner of the object we're
  // manipulating, and make it own any JSObject wrappers created here.
  NPP npp = LookupNPP(npobj);

  if (!npp) {
    ThrowJSException(cx, "No NPP found for NPObject!");

    return JS_FALSE;
  }

  NPVariant npv;
  if (!JSValToNPVariant(npp, cx, *vp, &npv)) {
    ThrowJSException(cx, "Error converting jsval to NPVariant!");

    return JS_FALSE;
  }

  JSBool ok = npobj->_class->setProperty(npobj, (NPIdentifier)id, &npv);

  // Release the variant
  _releasevariantvalue(&npv);

  if (!ok) {
    ThrowJSException(cx, "Error setting property on scriptable plugin "
                     "object!");

    return JS_FALSE;
  }

  return ReportExceptionIfPending(cx);
}

Here is the call graph for this function:

NPObjWrapperPluginDestroyedCallback ( PLDHashTable table,
PLDHashEntryHdr hdr,
PRUint32  number,
void arg 
)

Definition at line 1389 of file nsJSNPRuntime.cpp.

{
  NPObjWrapperHashEntry *entry = (NPObjWrapperHashEntry *)hdr;

  if (entry->mNpp == arg) {
    NPObject *npobj = entry->mNPObj;

    if (npobj->_class && npobj->_class->invalidate) {
      npobj->_class->invalidate(npobj);
    }

    // Force deallocation of plugin objects since the plugin they came
    // from is being torn down.
    if (npobj->_class && npobj->_class->deallocate) {
      npobj->_class->deallocate(npobj);
    } else {
      PR_Free(npobj);
    }

    JSContext *cx = GetJSContext((NPP)arg);

    if (cx) {
      ::JS_SetPrivate(cx, entry->mJSObj, nsnull);
    } else {
      NS_ERROR("dangling entry->mJSObj JSPrivate because we can't find cx");
    }

    return PL_DHASH_REMOVE;
  }

  return PL_DHASH_NEXT;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static jsval NPVariantToJSVal ( NPP  npp,
JSContext cx,
const NPVariant variant 
) [static]

Definition at line 287 of file nsJSNPRuntime.cpp.

{
  switch (variant->type) {
  case NPVariantType_Void :
    return JSVAL_VOID;
  case NPVariantType_Null :
    return JSVAL_NULL;
  case NPVariantType_Bool :
    return BOOLEAN_TO_JSVAL(NPVARIANT_TO_BOOLEAN(*variant));
  case NPVariantType_Int32 :
    return INT_TO_JSVAL(NPVARIANT_TO_INT32(*variant));
  case NPVariantType_Double :
    {
      jsval val;
      if (::JS_NewNumberValue(cx, NPVARIANT_TO_DOUBLE(*variant), &val)) {
        return val;
      }

      break;
    }
  case NPVariantType_String :
    {
      const NPString *s = &NPVARIANT_TO_STRING(*variant);
      PRUint32 len;
      PRUnichar *p =
        UTF8ToNewUnicode(nsDependentCString(s->utf8characters, s->utf8length),
                         &len);

      JSString *str = ::JS_NewUCString(cx, (jschar *)p, len);

      if (str) {
        return STRING_TO_JSVAL(str);
      }

      break;
    }
  case NPVariantType_Object:
    {
      if (npp) {
        JSObject *obj =
          nsNPObjWrapper::GetNewOrUsed(npp, cx, NPVARIANT_TO_OBJECT(*variant));

        if (obj) {
          return OBJECT_TO_JSVAL(obj);
        }
      }

      NS_ERROR("Error wrapping NPObject!");

      break;
    }
  default:
    NS_ERROR("Unknown NPVariant type!");
  }

  NS_ERROR("Unable to convert NPVariant to jsval!");

  return JSVAL_VOID;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void OnWrapperCreated ( ) [static]

Definition at line 164 of file nsJSNPRuntime.cpp.

{
  if (sWrapperCount++ == 0) {
    static const char rtsvc_id[] = "@mozilla.org/js/xpc/RuntimeService;1";
    nsCOMPtr<nsIJSRuntimeService> rtsvc(do_GetService(rtsvc_id));
    if (!rtsvc)
      return;

    rtsvc->GetRuntime(&sJSRuntime);
    NS_ASSERTION(sJSRuntime != nsnull, "no JSRuntime?!");

    CallGetService("@mozilla.org/js/xpc/ContextStack;1", &sContextStack);
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void OnWrapperDestroyed ( ) [static]

Definition at line 180 of file nsJSNPRuntime.cpp.

{
  NS_ASSERTION(sWrapperCount, "Whaaa, unbalanced created/destroyed calls!");

  if (--sWrapperCount == 0) {
    if (sJSObjWrappers.ops) {
      NS_ASSERTION(sJSObjWrappers.entryCount == 0, "Uh, hash not empty?");

      // No more wrappers, and our hash was initalized. Finish the
      // hash to prevent leaking it.
      PL_DHashTableFinish(&sJSObjWrappers);

      sJSObjWrappers.ops = nsnull;
    }

    if (sNPObjWrappers.ops) {
      NS_ASSERTION(sNPObjWrappers.entryCount == 0, "Uh, hash not empty?");

      // No more wrappers, and our hash was initalized. Finish the
      // hash to prevent leaking it.
      PL_DHashTableFinish(&sNPObjWrappers);

      sNPObjWrappers.ops = nsnull;
    }

    // No more need for this.
    sJSRuntime = nsnull;

    NS_IF_RELEASE(sContextStack);
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static JSBool ReportExceptionIfPending ( JSContext cx) [static]

Definition at line 431 of file nsJSNPRuntime.cpp.

{
  const char *ex = PeekException();

  if (!ex) {
    return JS_TRUE;
  }

  ThrowJSException(cx, nsnull);

  return JS_FALSE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void ThrowJSException ( JSContext cx,
const char *  message 
) [static]

Definition at line 398 of file nsJSNPRuntime.cpp.

{
  const char *ex = PeekException();

  if (ex) {
    nsAutoString ucex;

    if (message) {
      AppendASCIItoUTF16(message, ucex);

      AppendASCIItoUTF16(" [plugin exception: ", ucex);
    }

    AppendUTF8toUTF16(ex, ucex);

    if (message) {
      AppendASCIItoUTF16("].", ucex);
    }

    JSString *str = ::JS_NewUCStringCopyN(cx, (jschar *)ucex.get(),
                                          ucex.Length());

    if (str) {
      ::JS_SetPendingException(cx, STRING_TO_JSVAL(str));
    }

    PopException();
  } else {
    ::JS_ReportError(cx, message);
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

Definition at line 79 of file nsJSNPRuntime.cpp.

Definition at line 63 of file nsJSNPRuntime.cpp.

JSRuntime* sJSRuntime [static]

Definition at line 75 of file nsJSNPRuntime.cpp.

Definition at line 66 of file nsJSNPRuntime.cpp.

Definition at line 71 of file nsJSNPRuntime.cpp.