コード例 #1
0
JSBool
XPC_XOW_WrapObject(JSContext *cx, JSObject *parent, jsval *vp,
                   XPCWrappedNative* wn)
{
  NS_ASSERTION(XPCPerThreadData::IsMainThread(cx),
               "Can't do this off the main thread!");

  // Our argument should be a wrapped native object, but the caller may have
  // passed it in as an optimization.
  JSObject *wrappedObj;
  if (!JSVAL_IS_OBJECT(*vp) ||
      !(wrappedObj = JSVAL_TO_OBJECT(*vp)) ||
      STOBJ_GET_CLASS(wrappedObj) == &sXPC_XOW_JSClass.base) {
    return JS_TRUE;
  }

  if (!wn &&
      !(wn = XPCWrappedNative::GetAndMorphWrappedNativeOfJSObject(cx, wrappedObj))) {
    return JS_TRUE;
  }

  XPCJSRuntime *rt = nsXPConnect::GetRuntimeInstance();

  // The parent must be the inner global object for its scope.
  parent = JS_GetGlobalForObject(cx, parent);

  JSClass *clasp = STOBJ_GET_CLASS(parent);
  if (clasp->flags & JSCLASS_IS_EXTENDED) {
    JSExtendedClass *xclasp = reinterpret_cast<JSExtendedClass *>(clasp);
    if (xclasp->innerObject) {
      parent = xclasp->innerObject(cx, parent);
      if (!parent) {
        return JS_FALSE;
      }
    }
  }

  XPCWrappedNativeScope *parentScope =
    XPCWrappedNativeScope::FindInJSObjectScope(cx, parent, nsnull, rt);

#ifdef DEBUG_mrbkap_off
  printf("Wrapping object at %p (%s) [%p]\n",
         (void *)wrappedObj, STOBJ_GET_CLASS(wrappedObj)->name,
         (void *)parentScope);
#endif

  JSObject *outerObj = nsnull;
  WrappedNative2WrapperMap *map = parentScope->GetWrapperMap();

  outerObj = map->Find(wrappedObj);
  if (outerObj) {
    NS_ASSERTION(STOBJ_GET_CLASS(outerObj) == &sXPC_XOW_JSClass.base,
                              "What crazy object are we getting here?");
#ifdef DEBUG_mrbkap_off
    printf("But found a wrapper in the map %p!\n", (void *)outerObj);
#endif
    *vp = OBJECT_TO_JSVAL(outerObj);
    return JS_TRUE;
  }

  outerObj = JS_NewObjectWithGivenProto(cx, &sXPC_XOW_JSClass.base, nsnull,
                                        parent);
  if (!outerObj) {
    return JS_FALSE;
  }

  if (!JS_SetReservedSlot(cx, outerObj, XPCWrapper::sWrappedObjSlot, *vp) ||
      !JS_SetReservedSlot(cx, outerObj, XPCWrapper::sFlagsSlot,
                          JSVAL_ZERO) ||
      !JS_SetReservedSlot(cx, outerObj, XPC_XOW_ScopeSlot,
                          PRIVATE_TO_JSVAL(parentScope))) {
    return JS_FALSE;
  }

  *vp = OBJECT_TO_JSVAL(outerObj);

  map->Add(wn->GetScope()->GetWrapperMap(), wrappedObj, outerObj);

  return JS_TRUE;
}