LCOV - code coverage report
Current view: directory - js/ipc - ObjectWrapperParent.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 319 0 0.0 %
Date: 2012-06-02 Functions: 41 0 0.0 %

       1                 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
       2                 :  * vim: set ts=8 sw=4 et tw=80:
       3                 :  *
       4                 :  * ***** BEGIN LICENSE BLOCK *****
       5                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       6                 :  *
       7                 :  * The contents of this file are subject to the Mozilla Public License Version
       8                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       9                 :  * the License. You may obtain a copy of the License at
      10                 :  * http://www.mozilla.org/MPL/
      11                 :  *
      12                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      13                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      14                 :  * for the specific language governing rights and limitations under the
      15                 :  * License.
      16                 :  *
      17                 :  * The Original Code is mozilla.org code.
      18                 :  *
      19                 :  * The Initial Developer of the Original Code is
      20                 :  * The Mozilla Foundation.
      21                 :  * Portions created by the Initial Developer are Copyright (C) 2010
      22                 :  * the Initial Developer. All Rights Reserved.
      23                 :  *
      24                 :  * Contributor(s):
      25                 :  *   Ben Newman <b{enjam,newma}n@mozilla.com> (original author)
      26                 :  *
      27                 :  * Alternatively, the contents of this file may be used under the terms of
      28                 :  * either of the GNU General Public License Version 2 or later (the "GPL"),
      29                 :  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      30                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      31                 :  * of those above. If you wish to allow use of your version of this file only
      32                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      33                 :  * use your version of this file under the terms of the MPL, indicate your
      34                 :  * decision by deleting the provisions above and replace them with the notice
      35                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      36                 :  * the provisions above, a recipient may use your version of this file under
      37                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      38                 :  *
      39                 :  * ***** END LICENSE BLOCK ***** */
      40                 : 
      41                 : #include "mozilla/jsipc/ObjectWrapperParent.h"
      42                 : #include "mozilla/jsipc/ContextWrapperParent.h"
      43                 : #include "mozilla/jsipc/CPOWTypes.h"
      44                 : #include "mozilla/unused.h"
      45                 : #include "nsJSUtils.h"
      46                 : 
      47                 : #include "jsutil.h"
      48                 : #include "jsfriendapi.h"
      49                 : 
      50                 : using namespace mozilla::jsipc;
      51                 : 
      52                 : namespace {
      53                 : 
      54                 :     // Only need one reserved slot because the ObjectWrapperParent* is
      55                 :     // stored in the private slot.
      56                 :     static const unsigned sFlagsSlot = 0;
      57                 :     static const unsigned sNumSlots = 1;
      58                 :     static const unsigned CPOW_FLAG_RESOLVING = 1 << 0;
      59                 : 
      60                 :     class AutoResolveFlag
      61                 :     {
      62                 :         JSObject* mObj;
      63                 :         unsigned mOldFlags;
      64                 :         JS_DECL_USE_GUARD_OBJECT_NOTIFIER
      65                 : 
      66               0 :         static unsigned GetFlags(JSObject* obj) {
      67               0 :             jsval v = JS_GetReservedSlot(obj, sFlagsSlot);
      68               0 :             return JSVAL_TO_INT(v);
      69                 :         }
      70                 : 
      71               0 :         static unsigned SetFlags(JSObject* obj, unsigned flags) {
      72               0 :             unsigned oldFlags = GetFlags(obj);
      73               0 :             if (oldFlags != flags)
      74               0 :                 JS_SetReservedSlot(obj, sFlagsSlot, INT_TO_JSVAL(flags));
      75               0 :             return oldFlags;
      76                 :         }
      77                 : 
      78                 :     public:
      79                 : 
      80               0 :         AutoResolveFlag(JSObject* obj
      81                 :                         JS_GUARD_OBJECT_NOTIFIER_PARAM)
      82                 :             : mObj(obj)
      83               0 :             , mOldFlags(SetFlags(obj, GetFlags(obj) | CPOW_FLAG_RESOLVING))
      84                 :         {
      85               0 :             JS_GUARD_OBJECT_NOTIFIER_INIT;
      86               0 :         }
      87                 : 
      88               0 :         ~AutoResolveFlag() {
      89               0 :             SetFlags(mObj, mOldFlags);
      90               0 :         }
      91                 : 
      92               0 :         static JSBool IsSet(JSObject* obj) {
      93               0 :             return GetFlags(obj) & CPOW_FLAG_RESOLVING;
      94                 :         }
      95                 : 
      96                 :     };
      97                 : 
      98                 :     class StatusMemberOwner
      99               0 :     {
     100                 :         OperationStatus mStatus;
     101                 :     public:
     102               0 :         StatusMemberOwner() : mStatus(JS_FALSE) {}
     103               0 :         OperationStatus* StatusPtr() {
     104               0 :             return &mStatus;
     105                 :         }
     106                 :     };
     107                 : 
     108                 :     typedef AutoCheckOperationBase<StatusMemberOwner> ACOBase;
     109                 : 
     110                 :     class AutoCheckOperation : public ACOBase
     111               0 :     {
     112                 :         JS_DECL_USE_GUARD_OBJECT_NOTIFIER
     113                 :     public:
     114               0 :         AutoCheckOperation(JSContext* cx,
     115                 :                            ObjectWrapperParent* owp
     116                 :                            JS_GUARD_OBJECT_NOTIFIER_PARAM)
     117               0 :             : ACOBase(cx, owp)
     118                 :         {
     119               0 :             JS_GUARD_OBJECT_NOTIFIER_INIT;
     120               0 :         }
     121                 :     };
     122                 : 
     123                 : }
     124                 : 
     125                 : void
     126               0 : ObjectWrapperParent::CheckOperation(JSContext* cx,
     127                 :                                     OperationStatus* status)
     128                 : {
     129               0 :     NS_PRECONDITION(status->type() != OperationStatus::T__None,
     130                 :                     "Checking an uninitialized operation.");
     131                 : 
     132               0 :     switch (status->type()) {
     133                 :     case OperationStatus::TJSVariant:
     134                 :         {
     135                 :             jsval thrown;
     136               0 :             if (jsval_from_JSVariant(cx, status->get_JSVariant(), &thrown))
     137               0 :                 JS_SetPendingException(cx, thrown);
     138               0 :             *status = JS_FALSE;
     139                 :         }
     140               0 :         break;
     141                 :     case OperationStatus::TJSBool:
     142               0 :         if (!status->get_JSBool() && !JS_IsExceptionPending(cx)) {
     143               0 :             NS_WARNING("CPOW operation failed without setting an exception.");
     144                 :         }
     145               0 :         break;
     146                 :     default:
     147               0 :         NS_NOTREACHED("Invalid or uninitialized OperationStatus type.");
     148               0 :         break;
     149                 :     }
     150               0 : }
     151                 : 
     152                 : template <typename RType>
     153                 : static RType
     154               0 : with_error(JSContext* cx,
     155                 :                RType rval,
     156                 :                const char* error = NULL)
     157                 : {
     158               0 :     if (!JS_IsExceptionPending(cx))
     159               0 :         JS_ReportError(cx, error ? error : "Unspecified CPOW error");
     160               0 :     return rval;
     161                 : }
     162                 : 
     163                 : const js::Class ObjectWrapperParent::sCPOW_JSClass = {
     164                 :       "CrossProcessObjectWrapper",
     165                 :       JSCLASS_NEW_RESOLVE | JSCLASS_NEW_ENUMERATE |
     166                 :       JSCLASS_HAS_PRIVATE | JSCLASS_HAS_RESERVED_SLOTS(sNumSlots),
     167                 :       ObjectWrapperParent::CPOW_AddProperty,
     168                 :       ObjectWrapperParent::CPOW_DelProperty,
     169                 :       ObjectWrapperParent::CPOW_GetProperty,
     170                 :       ObjectWrapperParent::CPOW_SetProperty,
     171                 :       (JSEnumerateOp) ObjectWrapperParent::CPOW_NewEnumerate,
     172                 :       (JSResolveOp) ObjectWrapperParent::CPOW_NewResolve,
     173                 :       ObjectWrapperParent::CPOW_Convert,
     174                 :       ObjectWrapperParent::CPOW_Finalize,
     175                 :       nsnull, // checkAccess
     176                 :       ObjectWrapperParent::CPOW_Call,
     177                 :       ObjectWrapperParent::CPOW_Construct,
     178                 :       ObjectWrapperParent::CPOW_HasInstance,
     179                 :       nsnull, // trace
     180                 :       {
     181                 :           ObjectWrapperParent::CPOW_Equality,
     182                 :           nsnull, // outerObject
     183                 :           nsnull, // innerObject
     184                 :           nsnull, // iteratorObject
     185                 :           nsnull, // wrappedObject
     186                 :     }
     187                 : };
     188                 : 
     189                 : void
     190               0 : ObjectWrapperParent::ActorDestroy(ActorDestroyReason)
     191                 : {
     192               0 :     if (mObj) {
     193               0 :         JS_SetPrivate(mObj, NULL);
     194               0 :         mObj = NULL;
     195                 :     }
     196               0 : }
     197                 : 
     198                 : ContextWrapperParent*
     199               0 : ObjectWrapperParent::Manager()
     200                 : {
     201               0 :     PContextWrapperParent* pcwp = PObjectWrapperParent::Manager();
     202               0 :     return static_cast<ContextWrapperParent*>(pcwp);
     203                 : }
     204                 : 
     205                 : JSObject*
     206               0 : ObjectWrapperParent::GetJSObject(JSContext* cx) const
     207                 : {
     208               0 :     if (!mObj) {
     209               0 :         js::Class *clasp = const_cast<js::Class *>(&ObjectWrapperParent::sCPOW_JSClass);
     210               0 :         mObj = JS_NewObject(cx, js::Jsvalify(clasp), NULL, NULL);
     211               0 :         if (mObj) {
     212               0 :             JS_SetPrivate(mObj, (void*)this);
     213               0 :             JS_SetReservedSlot(mObj, sFlagsSlot, JSVAL_ZERO);
     214                 :         }
     215                 :     }
     216               0 :     return mObj;
     217                 : }
     218                 : 
     219                 : static ObjectWrapperParent*
     220               0 : Unwrap(JSObject* obj)
     221                 : {
     222               0 :     while (js::GetObjectClass(obj) != &ObjectWrapperParent::sCPOW_JSClass)
     223               0 :         if (!(obj = js::GetObjectProto(obj)))
     224               0 :             return NULL;
     225                 :     
     226                 :     ObjectWrapperParent* self =
     227               0 :         static_cast<ObjectWrapperParent*>(JS_GetPrivate(obj));
     228                 : 
     229               0 :     NS_ASSERTION(!self || self->GetJSObjectOrNull() == obj,
     230                 :                  "Wrapper and wrapped object disagree?");
     231                 :     
     232               0 :     return self;
     233                 : }
     234                 : 
     235                 : /*static*/ bool
     236               0 : ObjectWrapperParent::jsval_to_JSVariant(JSContext* cx, jsval from,
     237                 :                                         JSVariant* to)
     238                 : {
     239               0 :     switch (JS_TypeOfValue(cx, from)) {
     240                 :     case JSTYPE_VOID:
     241               0 :         *to = void_t();
     242               0 :         return true;
     243                 :     case JSTYPE_NULL:
     244               0 :         if (from != JSVAL_NULL)
     245               0 :             return false;
     246                 :         // fall through
     247                 :     case JSTYPE_FUNCTION:
     248                 :         // CPOWs can fool JS_TypeOfValue into returning JSTYPE_FUNCTION
     249                 :         // because they have a call hook, but CPOWs are really objects, so
     250                 :         // fall through to the JSTYPE_OBJECT case:
     251                 :     case JSTYPE_OBJECT:
     252                 :         {
     253                 :             PObjectWrapperParent* powp;
     254               0 :             if (!JSObject_to_PObjectWrapperParent(JSVAL_TO_OBJECT(from), &powp))
     255               0 :                 return with_error(cx, false, "Cannot pass parent-created object to child");
     256               0 :             *to = powp;
     257                 :         }
     258               0 :         return true;
     259                 :     case JSTYPE_STRING:
     260                 :         {
     261               0 :             nsDependentJSString depStr;
     262               0 :             if (!depStr.init(cx, from))
     263               0 :                 return false;
     264               0 :             *to = depStr;
     265                 :         }
     266               0 :         return true;
     267                 :     case JSTYPE_NUMBER:
     268               0 :         if (JSVAL_IS_INT(from))
     269               0 :             *to = JSVAL_TO_INT(from);
     270               0 :         else if (JSVAL_IS_DOUBLE(from))
     271               0 :             *to = JSVAL_TO_DOUBLE(from);
     272               0 :         else return false;
     273               0 :         return true;
     274                 :     case JSTYPE_BOOLEAN:
     275               0 :         *to = !!JSVAL_TO_BOOLEAN(from);
     276               0 :         return true;
     277                 :     case JSTYPE_XML:
     278               0 :         return with_error(cx, false, "CPOWs currently cannot handle JSTYPE_XML");
     279                 :     default:
     280               0 :         return with_error(cx, false, "Bad jsval type");
     281                 :     }
     282                 : }
     283                 : 
     284                 : /*static*/ bool
     285               0 : ObjectWrapperParent::jsval_from_JSVariant(JSContext* cx, const JSVariant& from,
     286                 :                                           jsval* to)
     287                 : {
     288               0 :     switch (from.type()) {
     289                 :     case JSVariant::Tvoid_t:
     290               0 :         *to = JSVAL_VOID;
     291               0 :         return true;
     292                 :     case JSVariant::TPObjectWrapperParent:
     293               0 :         return jsval_from_PObjectWrapperParent(cx, from.get_PObjectWrapperParent(), to);
     294                 :     case JSVariant::TnsString:
     295                 :         {
     296               0 :             JSString* str = JS_NewUCStringCopyZ(cx, from.get_nsString().BeginReading());
     297               0 :             if (!str)
     298               0 :                 return false;
     299               0 :             *to = STRING_TO_JSVAL(str);
     300               0 :             return true;
     301                 :         }
     302                 :     case JSVariant::Tint:
     303               0 :         *to = INT_TO_JSVAL(from.get_int());
     304               0 :         return true;
     305                 :     case JSVariant::Tdouble:
     306               0 :         return !!JS_NewNumberValue(cx, from.get_double(), to);
     307                 :     case JSVariant::Tbool:
     308               0 :         *to = BOOLEAN_TO_JSVAL(from.get_bool());
     309               0 :         return true;
     310                 :     default:
     311               0 :         return false;
     312                 :     }
     313                 : }
     314                 : 
     315                 : /*static*/ bool
     316               0 : ObjectWrapperParent::
     317                 : JSObject_to_PObjectWrapperParent(JSObject* from, PObjectWrapperParent** to)
     318                 : {
     319               0 :     if (!from) {
     320               0 :         *to = NULL;
     321               0 :         return true;
     322                 :     }
     323               0 :     ObjectWrapperParent* owp = Unwrap(from);
     324               0 :     if (!owp)
     325               0 :         return false;
     326               0 :     *to = owp;
     327               0 :     return true;
     328                 : }
     329                 : 
     330                 : /*static*/ bool
     331               0 : ObjectWrapperParent::
     332                 : JSObject_from_PObjectWrapperParent(JSContext* cx,
     333                 :                                    const PObjectWrapperParent* from,
     334                 :                                    JSObject** to)
     335                 : {
     336                 :     const ObjectWrapperParent* owp =
     337               0 :         static_cast<const ObjectWrapperParent*>(from);
     338                 :     *to = owp
     339                 :         ? owp->GetJSObject(cx)
     340               0 :         : JSVAL_TO_OBJECT(JSVAL_NULL);
     341               0 :     return true;
     342                 : }
     343                 : 
     344                 : /*static*/ bool
     345               0 : ObjectWrapperParent::
     346                 : jsval_from_PObjectWrapperParent(JSContext* cx,
     347                 :                                 const PObjectWrapperParent* from,
     348                 :                                 jsval* to)
     349                 : {
     350                 :     JSObject* obj;
     351               0 :     if (!JSObject_from_PObjectWrapperParent(cx, from, &obj))
     352               0 :         return false;
     353               0 :     *to = OBJECT_TO_JSVAL(obj);
     354               0 :     return true;
     355                 : }
     356                 :     
     357                 : static bool
     358               0 : jsid_from_int(JSContext* cx, int from, jsid* to)
     359                 : {
     360               0 :     jsval v = INT_TO_JSVAL(from);
     361               0 :     return JS_ValueToId(cx, v, to);
     362                 : }
     363                 : 
     364                 : static bool
     365               0 : jsid_from_nsString(JSContext* cx, const nsString& from, jsid* to)
     366                 : {
     367               0 :     JSString* str = JS_NewUCStringCopyZ(cx, from.BeginReading());
     368               0 :     if (!str)
     369               0 :         return false;
     370               0 :     return JS_ValueToId(cx, STRING_TO_JSVAL(str), to);
     371                 : }
     372                 : 
     373                 : static bool
     374               0 : jsval_to_nsString(JSContext* cx, jsid from, nsString* to)
     375                 : {
     376                 :     JSString* str;
     377                 :     const jschar* chars;
     378                 :     jsval idval;
     379               0 :     if (JS_IdToValue(cx, from, &idval) &&
     380                 :         (str = JS_ValueToString(cx, idval)) &&
     381                 :         (chars = JS_GetStringCharsZ(cx, str))) {
     382               0 :         *to = chars;
     383               0 :         return true;
     384                 :     }
     385               0 :     return false;
     386                 : }
     387                 : 
     388                 : /*static*/ JSBool
     389               0 : ObjectWrapperParent::CPOW_AddProperty(JSContext *cx, JSObject *obj, jsid id,
     390                 :                                       jsval *vp)
     391                 : {
     392                 :     CPOW_LOG(("Calling CPOW_AddProperty (%s)...",
     393                 :               JSVAL_TO_CSTR(cx, id)));
     394                 : 
     395               0 :     ObjectWrapperParent* self = Unwrap(obj);
     396               0 :     if (!self)
     397               0 :         return with_error(cx, JS_FALSE, "Unwrapping failed in CPOW_AddProperty");
     398                 : 
     399               0 :     if (AutoResolveFlag::IsSet(obj))
     400               0 :         return JS_TRUE;
     401                 : 
     402               0 :     AutoCheckOperation aco(cx, self);
     403                 : 
     404               0 :     nsString in_id;
     405                 : 
     406               0 :     if (!jsval_to_nsString(cx, id, &in_id))
     407               0 :         return JS_FALSE;
     408                 : 
     409               0 :     return (self->Manager()->RequestRunToCompletion() &&
     410                 :             self->CallAddProperty(in_id,
     411               0 :                                   aco.StatusPtr()) &&
     412               0 :             aco.Ok());
     413                 : }
     414                 : 
     415                 : /*static*/ JSBool
     416               0 : ObjectWrapperParent::CPOW_GetProperty(JSContext *cx, JSObject *obj, jsid id,
     417                 :                                       jsval *vp)
     418                 : {
     419                 :     CPOW_LOG(("Calling CPOW_GetProperty (%s)...",
     420                 :               JSVAL_TO_CSTR(cx, id)));
     421                 : 
     422               0 :     ObjectWrapperParent* self = Unwrap(obj);
     423               0 :     if (!self)
     424               0 :         return with_error(cx, JS_FALSE, "Unwrapping failed in CPOW_GetProperty");
     425                 : 
     426               0 :     AutoCheckOperation aco(cx, self);
     427                 : 
     428               0 :     nsString in_id;
     429                 : 
     430               0 :     if (!jsval_to_nsString(cx, id, &in_id))
     431               0 :         return JS_FALSE;
     432                 : 
     433               0 :     JSVariant out_v;
     434                 :     
     435               0 :     return (self->Manager()->RequestRunToCompletion() &&
     436                 :             self->CallGetProperty(in_id,
     437               0 :                                   aco.StatusPtr(), &out_v) &&
     438               0 :             aco.Ok() &&
     439               0 :             self->jsval_from_JSVariant(cx, out_v, vp));
     440                 : }
     441                 : 
     442                 : /*static*/ JSBool
     443               0 : ObjectWrapperParent::CPOW_SetProperty(JSContext *cx, JSObject *obj, jsid id, 
     444                 :                                       JSBool strict, jsval *vp)
     445                 : {
     446                 :     CPOW_LOG(("Calling CPOW_SetProperty (%s)...",
     447                 :               JSVAL_TO_CSTR(cx, id)));
     448                 : 
     449               0 :     ObjectWrapperParent* self = Unwrap(obj);
     450               0 :     if (!self)
     451               0 :         return with_error(cx, JS_FALSE, "Unwrapping failed in CPOW_SetProperty");
     452                 : 
     453               0 :     AutoCheckOperation aco(cx, self);
     454                 : 
     455               0 :     nsString in_id;
     456               0 :     JSVariant in_v;
     457                 : 
     458               0 :     if (!jsval_to_nsString(cx, id, &in_id) ||
     459               0 :         !self->jsval_to_JSVariant(cx, *vp, &in_v))
     460               0 :         return JS_FALSE;
     461                 : 
     462               0 :     JSVariant out_v;
     463                 : 
     464               0 :     return (self->Manager()->RequestRunToCompletion() &&
     465                 :             self->CallSetProperty(in_id, in_v,
     466               0 :                                   aco.StatusPtr(), &out_v) &&
     467               0 :             aco.Ok() &&
     468               0 :             self->jsval_from_JSVariant(cx, out_v, vp));
     469                 : }    
     470                 :     
     471                 : /*static*/ JSBool
     472               0 : ObjectWrapperParent::CPOW_DelProperty(JSContext *cx, JSObject *obj, jsid id,
     473                 :                                       jsval *vp)
     474                 : {
     475                 :     CPOW_LOG(("Calling CPOW_DelProperty (%s)...",
     476                 :               JSVAL_TO_CSTR(cx, id)));
     477                 : 
     478               0 :     ObjectWrapperParent* self = Unwrap(obj);
     479               0 :     if (!self)
     480               0 :         return with_error(cx, JS_FALSE, "Unwrapping failed in CPOW_DelProperty");
     481                 : 
     482               0 :     AutoCheckOperation aco(cx, self);
     483                 : 
     484               0 :     nsString in_id;
     485                 : 
     486               0 :     if (!jsval_to_nsString(cx, id, &in_id))
     487               0 :         return JS_FALSE;
     488                 : 
     489               0 :     JSVariant out_v;
     490                 :     
     491               0 :     return (self->Manager()->RequestRunToCompletion() &&
     492                 :             self->CallDelProperty(in_id,
     493               0 :                                   aco.StatusPtr(), &out_v) &&
     494               0 :             aco.Ok() &&
     495               0 :             jsval_from_JSVariant(cx, out_v, vp));
     496                 : }
     497                 : 
     498                 : JSBool
     499               0 : ObjectWrapperParent::NewEnumerateInit(JSContext* cx, jsval* statep, jsid* idp)
     500                 : {
     501               0 :     AutoCheckOperation aco(cx, this);
     502                 : 
     503               0 :     JSVariant out_state;
     504                 :     int out_id;
     505                 : 
     506               0 :     return (CallNewEnumerateInit(aco.StatusPtr(), &out_state, &out_id) &&
     507               0 :             aco.Ok() &&
     508               0 :             jsval_from_JSVariant(cx, out_state, statep) &&
     509               0 :             (!idp || jsid_from_int(cx, out_id, idp)));
     510                 : }
     511                 : 
     512                 : JSBool
     513               0 : ObjectWrapperParent::NewEnumerateNext(JSContext* cx, jsval* statep, jsid* idp)
     514                 : {
     515               0 :     AutoCheckOperation aco(cx, this);
     516                 : 
     517               0 :     JSVariant in_state;
     518                 : 
     519               0 :     if (!jsval_to_JSVariant(cx, *statep, &in_state))
     520               0 :         return JS_FALSE;
     521                 : 
     522               0 :     JSVariant out_state;
     523               0 :     nsString out_id;
     524                 : 
     525               0 :     if (CallNewEnumerateNext(in_state,
     526               0 :                              aco.StatusPtr(), &out_state, &out_id) &&
     527               0 :         aco.Ok() &&
     528               0 :         jsval_from_JSVariant(cx, out_state, statep) &&
     529               0 :         jsid_from_nsString(cx, out_id, idp))
     530                 :     {
     531               0 :         JSObject* obj = GetJSObject(cx);
     532               0 :         AutoResolveFlag arf(obj);
     533                 :         return JS_DefinePropertyById(cx, obj, *idp, JSVAL_VOID, NULL, NULL,
     534               0 :                                      JSPROP_ENUMERATE);
     535                 :     }
     536               0 :     return JS_FALSE;
     537                 : }
     538                 : 
     539                 : JSBool
     540               0 : ObjectWrapperParent::NewEnumerateDestroy(JSContext* cx, jsval state)
     541                 : {
     542               0 :     AutoCheckOperation aco(cx, this);
     543                 : 
     544               0 :     JSVariant in_state;
     545                 : 
     546               0 :     if (!jsval_to_JSVariant(cx, state, &in_state))
     547               0 :         return JS_FALSE;
     548                 : 
     549               0 :     return SendNewEnumerateDestroy(in_state);
     550                 : }
     551                 : 
     552                 : /*static*/ JSBool
     553               0 : ObjectWrapperParent::CPOW_NewEnumerate(JSContext *cx, JSObject *obj,
     554                 :                                        JSIterateOp enum_op, jsval *statep,
     555                 :                                        jsid *idp)
     556                 : {
     557                 :     CPOW_LOG(("Calling CPOW_NewEnumerate..."));
     558                 : 
     559               0 :     ObjectWrapperParent* self = Unwrap(obj);
     560               0 :     if (!self)
     561               0 :         return with_error(cx, JS_FALSE, "Unwrapping failed in CPOW_NewEnumerate");
     562                 : 
     563               0 :     switch (enum_op) {
     564                 :     case JSENUMERATE_INIT:
     565                 :     case JSENUMERATE_INIT_ALL:
     566               0 :         self->Manager()->RequestRunToCompletion();
     567               0 :         return self->NewEnumerateInit(cx, statep, idp);
     568                 :     case JSENUMERATE_NEXT:
     569               0 :         return self->NewEnumerateNext(cx, statep, idp);
     570                 :     case JSENUMERATE_DESTROY:
     571               0 :         return self->NewEnumerateDestroy(cx, *statep);
     572                 :     }
     573                 : 
     574                 :     NS_NOTREACHED("Unknown enum_op value in CPOW_NewEnumerate");
     575                 :     return JS_FALSE;
     576                 : }
     577                 : 
     578                 : /*static*/ JSBool
     579               0 : ObjectWrapperParent::CPOW_NewResolve(JSContext *cx, JSObject *obj, jsid id,
     580                 :                                      unsigned flags, JSObject **objp)
     581                 : {
     582                 :     CPOW_LOG(("Calling CPOW_NewResolve (%s)...",
     583                 :               JSVAL_TO_CSTR(cx, id)));
     584                 : 
     585               0 :     ObjectWrapperParent* self = Unwrap(obj);
     586               0 :     if (!self)
     587               0 :         return with_error(cx, JS_FALSE, "Unwrapping failed in CPOW_NewResolve");
     588                 : 
     589               0 :     AutoCheckOperation aco(cx, self);
     590                 : 
     591               0 :     nsString in_id;
     592                 : 
     593               0 :     if (!jsval_to_nsString(cx, id, &in_id))
     594               0 :         return JS_FALSE;
     595                 : 
     596                 :     PObjectWrapperParent* out_pobj;
     597                 : 
     598               0 :     if (!self->Manager()->RequestRunToCompletion() ||
     599                 :         !self->CallNewResolve(in_id, flags,
     600               0 :                               aco.StatusPtr(), &out_pobj) ||
     601               0 :         !aco.Ok() ||
     602               0 :         !JSObject_from_PObjectWrapperParent(cx, out_pobj, objp))
     603               0 :         return JS_FALSE;
     604                 : 
     605               0 :     if (*objp) {
     606               0 :         AutoResolveFlag arf(*objp);
     607                 :         JS_DefinePropertyById(cx, *objp, id, JSVAL_VOID, NULL, NULL,
     608               0 :                               JSPROP_ENUMERATE);
     609                 :     }
     610               0 :     return JS_TRUE;
     611                 : }
     612                 : 
     613                 : /*static*/ JSBool
     614               0 : ObjectWrapperParent::CPOW_Convert(JSContext *cx, JSObject *obj, JSType type,
     615                 :                                   jsval *vp)
     616                 : {
     617                 :     CPOW_LOG(("Calling CPOW_Convert (to %s)...",
     618                 :               JS_GetTypeName(cx, type)));
     619                 : 
     620               0 :     ObjectWrapperParent* self = Unwrap(obj);
     621               0 :     if (!self)
     622               0 :         return with_error(cx, JS_FALSE, "Unwrapping failed in CPOW_Convert");
     623                 : 
     624               0 :     *vp = OBJECT_TO_JSVAL(obj);
     625                 : 
     626               0 :     return JS_TRUE;
     627                 : }
     628                 : 
     629                 : /*static*/ void
     630               0 : ObjectWrapperParent::CPOW_Finalize(JSContext* cx, JSObject* obj)
     631                 : {
     632                 :     CPOW_LOG(("Calling CPOW_Finalize..."));
     633                 :     
     634               0 :     ObjectWrapperParent* self = Unwrap(obj);
     635               0 :     if (self) {
     636               0 :         self->mObj = NULL;
     637               0 :         unused << ObjectWrapperParent::Send__delete__(self);
     638                 :     }
     639               0 : }
     640                 : 
     641                 : /*static*/ JSBool
     642               0 : ObjectWrapperParent::CPOW_Call(JSContext* cx, unsigned argc, jsval* vp)
     643                 : {
     644                 :     CPOW_LOG(("Calling CPOW_Call..."));
     645                 : 
     646               0 :     JSObject* thisobj = JS_THIS_OBJECT(cx, vp);
     647               0 :     if (!thisobj)
     648               0 :         return JS_FALSE;
     649                 : 
     650                 :     ObjectWrapperParent* function =
     651               0 :         Unwrap(JSVAL_TO_OBJECT(JS_CALLEE(cx, vp)));
     652               0 :     if (!function)
     653               0 :         return with_error(cx, JS_FALSE, "Could not unwrap CPOW function");
     654                 : 
     655               0 :     AutoCheckOperation aco(cx, function);
     656                 : 
     657               0 :     ObjectWrapperParent* receiver = Unwrap(thisobj);
     658               0 :     if (!receiver) {
     659                 :         // Substitute child global for parent global object.
     660                 :         // TODO First make sure we're really replacing the global object?
     661                 :         ContextWrapperParent* manager =
     662               0 :             static_cast<ContextWrapperParent*>(function->Manager());
     663               0 :         receiver = manager->GetGlobalObjectWrapper();
     664                 :     }
     665                 : 
     666               0 :     InfallibleTArray<JSVariant> in_argv(argc);
     667               0 :     jsval* argv = JS_ARGV(cx, vp);
     668               0 :     for (unsigned i = 0; i < argc; i++)
     669               0 :         if (!jsval_to_JSVariant(cx, argv[i], in_argv.AppendElement()))
     670               0 :             return JS_FALSE;
     671                 : 
     672               0 :     JSVariant out_rval;
     673                 : 
     674               0 :     return (function->Manager()->RequestRunToCompletion() &&
     675                 :             function->CallCall(receiver, in_argv,
     676               0 :                                aco.StatusPtr(), &out_rval) &&
     677               0 :             aco.Ok() &&
     678               0 :             jsval_from_JSVariant(cx, out_rval, vp));
     679                 : }
     680                 : 
     681                 : /*static*/ JSBool
     682               0 : ObjectWrapperParent::CPOW_Construct(JSContext* cx, unsigned argc, jsval* vp)
     683                 : {
     684                 :     CPOW_LOG(("Calling CPOW_Construct..."));
     685                 :     
     686               0 :     ObjectWrapperParent* constructor = Unwrap(JSVAL_TO_OBJECT(JS_CALLEE(cx, vp)));
     687               0 :     if (!constructor)
     688               0 :         return with_error(cx, JS_FALSE, "Could not unwrap CPOW constructor function");
     689                 : 
     690               0 :     AutoCheckOperation aco(cx, constructor);
     691                 : 
     692               0 :     InfallibleTArray<JSVariant> in_argv(argc);
     693               0 :     jsval* argv = JS_ARGV(cx, vp);
     694               0 :     for (unsigned i = 0; i < argc; i++)
     695               0 :         if (!jsval_to_JSVariant(cx, argv[i], in_argv.AppendElement()))
     696               0 :             return JS_FALSE;
     697                 : 
     698                 :     PObjectWrapperParent* out_powp;
     699                 : 
     700               0 :     return (constructor->Manager()->RequestRunToCompletion() &&
     701               0 :             constructor->CallConstruct(in_argv, aco.StatusPtr(), &out_powp) &&
     702               0 :             aco.Ok() &&
     703               0 :             jsval_from_PObjectWrapperParent(cx, out_powp, vp));
     704                 : }
     705                 : 
     706                 : /*static*/ JSBool
     707               0 : ObjectWrapperParent::CPOW_HasInstance(JSContext *cx, JSObject *obj, const jsval *v,
     708                 :                                       JSBool *bp)
     709                 : {
     710                 :     CPOW_LOG(("Calling CPOW_HasInstance..."));
     711                 : 
     712               0 :     *bp = JS_FALSE;
     713                 : 
     714               0 :     ObjectWrapperParent* self = Unwrap(obj);
     715               0 :     if (!self)
     716               0 :         return with_error(cx, JS_FALSE, "Unwrapping failed in CPOW_HasInstance");
     717                 : 
     718               0 :     AutoCheckOperation aco(cx, self);
     719                 : 
     720               0 :     JSVariant in_v;
     721                 : 
     722               0 :     if (!jsval_to_JSVariant(cx, *v, &in_v))
     723               0 :         return JS_FALSE;
     724                 : 
     725               0 :     return (self->Manager()->RequestRunToCompletion() &&
     726                 :             self->CallHasInstance(in_v,
     727               0 :                                   aco.StatusPtr(), bp) &&
     728               0 :             aco.Ok());
     729                 : }
     730                 : 
     731                 : /*static*/ JSBool
     732               0 : ObjectWrapperParent::CPOW_Equality(JSContext *cx, JSObject *obj, const jsval *v,
     733                 :                                    JSBool *bp)
     734                 : {
     735                 :     CPOW_LOG(("Calling CPOW_Equality..."));
     736                 : 
     737               0 :     *bp = JS_FALSE;
     738                 :     
     739               0 :     ObjectWrapperParent* self = Unwrap(obj);
     740               0 :     if (!self)
     741               0 :         return with_error(cx, JS_FALSE, "Unwrapping failed in CPOW_Equality");
     742                 : 
     743               0 :     if (JSVAL_IS_PRIMITIVE(*v))
     744               0 :         return JS_TRUE;
     745                 : 
     746               0 :     ObjectWrapperParent* other = Unwrap(JSVAL_TO_OBJECT(*v));
     747               0 :     if (!other)
     748               0 :         return JS_TRUE;
     749                 : 
     750               0 :     *bp = (self == other);
     751                 :     
     752               0 :     return JS_TRUE;
     753                 : }

Generated by: LCOV version 1.7