LCOV - app.info - js/ipc/ObjectWrapperChild.cpp

LCOV - code coverage report
| Current view: | directory - js/ipc - ObjectWrapperChild.cpp (source / functions) |  | Found | Hit | Coverage |
| Test: | app.info | Lines: | 272 | 0 | 0.0 %
| Date: | 2012-04-21 | Functions: | 32 | 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 "base/basictypes.h"
          42                 :
          43                 : #include "mozilla/jsipc/ContextWrapperChild.h"
          44                 : #include "mozilla/jsipc/ObjectWrapperChild.h"
          45                 : #include "mozilla/jsipc/CPOWTypes.h"
          46                 :
          47                 : #include "jsapi.h"
          48                 : #include "nsAutoPtr.h"
          49                 : #include "nsTArray.h"
          50                 : #include "nsContentUtils.h"
          51                 : #include "nsIJSContextStack.h"
          52                 : #include "nsJSUtils.h"
          53                 :
          54                 : using namespace mozilla::jsipc;
          55                 : using namespace js;
          56                 :
          57                 : namespace {
          58                 :
          59                 :     class AutoContextPusher {
          60                 :
          61                 :         nsCxPusher mStack;
          62                 :         JSAutoRequest mRequest;
          63                 :         JSContext* const mContext;
          64                 :         const uint32 mSavedOptions;
          65                 :         JS_DECL_USE_GUARD_OBJECT_NOTIFIER
          66                 :
          67                 :     public:
          68                 :
          69               0 :         AutoContextPusher(JSContext* cx
          70                 :                           JS_GUARD_OBJECT_NOTIFIER_PARAM)
          71                 :             : mRequest(cx)
          72                 :             , mContext(cx)
          73               0 :             , mSavedOptions(JS_SetOptions(cx, (JS_GetOptions(cx) |
          74               0 :                                                JSOPTION_DONT_REPORT_UNCAUGHT)))
          75                 :         {
          76               0 :             JS_GUARD_OBJECT_NOTIFIER_INIT;
          77               0 :             mStack.Push(cx, false);
          78               0 :         }
          79                 :
          80               0 :         ~AutoContextPusher() {
          81               0 :             mStack.Pop();
          82               0 :             JS_SetOptions(mContext, mSavedOptions);
          83               0 :         }
          84                 :
          85                 :     };
          86                 :
          87                 :     class StatusPtrOwner
          88                 :     {
          89                 :         OperationStatus* mStatusPtr;
          90                 :     public:
          91               0 :         StatusPtrOwner() : mStatusPtr(NULL) {}
          92               0 :         void SetStatusPtr(OperationStatus* statusPtr) {
          93               0 :             mStatusPtr = statusPtr;
          94                 :             // By default, initialize mStatusPtr to failure without an
          95                 :             // exception.  Doing so only when the union is uninitialized
          96                 :             // allows AutoCheckOperation classes to be nested on the
          97                 :             // stack, just in case AnswerConstruct, for example, calls
          98                 :             // AnswerCall (as it once did, before there were unrelated
          99                 :             // problems with that approach).
         100               0 :             if (mStatusPtr->type() == OperationStatus::T__None)
         101               0 :                 *mStatusPtr = JS_FALSE;
         102               0 :         }
         103               0 :         OperationStatus* StatusPtr() {
         104               0 :             NS_ASSERTION(mStatusPtr, "Should have called SetStatusPtr by now.");
         105               0 :             return mStatusPtr;
         106                 :         }
         107                 :     };
         108                 :
         109                 :     typedef AutoCheckOperationBase<StatusPtrOwner> ACOBase;
         110                 :
         111                 :     class AutoCheckOperation : public ACOBase
         112               0 :     {
         113                 :         JS_DECL_USE_GUARD_OBJECT_NOTIFIER
         114                 :     public:
         115               0 :         AutoCheckOperation(ObjectWrapperChild* owc,
         116                 :                            OperationStatus* statusPtr
         117                 :                            JS_GUARD_OBJECT_NOTIFIER_PARAM)
         118               0 :             : ACOBase(NULL, owc)
         119                 :         {
         120               0 :             JS_GUARD_OBJECT_NOTIFIER_INIT;
         121               0 :             SetStatusPtr(statusPtr);
         122               0 :         }
         123                 :     };
         124                 : }
         125                 :
         126                 : void
         127               0 : ObjectWrapperChild::CheckOperation(JSContext*,
         128                 :                                    OperationStatus* status)
         129                 : {
         130               0 :     NS_PRECONDITION(status->type() != OperationStatus::T__None,
         131                 :                     "Checking an uninitialized operation.");
         132                 :
         133               0 :     JSContext* cx = Manager()->GetContext();
         134                 :     jsval thrown;
         135                 :
         136               0 :     if (JS_GetPendingException(cx, &thrown)) {
         137               0 :         NS_ASSERTION(!(status->type() == OperationStatus::TJSBool &&
         138                 :                        status->get_JSBool()),
         139                 :                      "Operation succeeded but exception was thrown?");
         140               0 :         JSVariant exception;
         141               0 :         if (!jsval_to_JSVariant(cx, thrown, &exception))
         142               0 :             exception = void_t(); // XXX Useful?
         143               0 :         *status = exception;
         144               0 :         JS_ClearPendingException(cx);
         145                 :     }
         146               0 : }
         147                 :
         148               0 : ObjectWrapperChild::ObjectWrapperChild(JSContext* cx, JSObject* obj)
         149               0 :     : mObj(obj)
         150                 : {
         151               0 :     JSAutoRequest request(cx);
         152                 : #ifdef DEBUG
         153                 :     bool added =
         154                 : #endif
         155               0 :          JS_AddObjectRoot(cx, &mObj);
         156               0 :     NS_ASSERTION(added, "ObjectWrapperChild constructor failed to root JSObject*");
         157               0 : }
         158                 :
         159                 : void
         160               0 : ObjectWrapperChild::ActorDestroy(ActorDestroyReason why)
         161                 : {
         162               0 :     JSContext* cx = Manager()->GetContext();
         163               0 :     JSAutoRequest request(cx);
         164               0 :     JS_RemoveObjectRoot(cx, &mObj);
         165               0 : }
         166                 :
         167                 : bool
         168               0 : ObjectWrapperChild::JSObject_to_JSVariant(JSContext* cx, JSObject* from,
         169                 :                                           JSVariant* to)
         170                 : {
         171               0 :     *to = Manager()->GetOrCreateWrapper(from);
         172               0 :     return true;
         173                 : }
         174                 :
         175                 : bool
         176               0 : ObjectWrapperChild::jsval_to_JSVariant(JSContext* cx, jsval from, JSVariant* to)
         177                 : {
         178               0 :     switch (JS_TypeOfValue(cx, from)) {
         179                 :     case JSTYPE_VOID:
         180               0 :         *to = void_t();
         181               0 :         return true;
         182                 :     case JSTYPE_NULL:
         183               0 :         if (from != JSVAL_NULL)
         184               0 :             return false;
         185                 :         // fall through
         186                 :     case JSTYPE_FUNCTION:
         187                 :         // fall through
         188                 :     case JSTYPE_OBJECT:
         189               0 :         return JSObject_to_JSVariant(cx, JSVAL_TO_OBJECT(from), to);
         190                 :     case JSTYPE_STRING:
         191                 :         {
         192               0 :             nsDependentJSString depStr;
         193               0 :             if (!depStr.init(cx, from))
         194               0 :                 return false;
         195               0 :             *to = depStr;
         196                 :         }
         197               0 :         return true;
         198                 :     case JSTYPE_NUMBER:
         199               0 :         if (JSVAL_IS_INT(from))
         200               0 :             *to = JSVAL_TO_INT(from);
         201               0 :         else if (JSVAL_IS_DOUBLE(from))
         202               0 :             *to = JSVAL_TO_DOUBLE(from);
         203               0 :         else return false;
         204               0 :         return true;
         205                 :     case JSTYPE_BOOLEAN:
         206               0 :         *to = !!JSVAL_TO_BOOLEAN(from);
         207               0 :         return true;
         208                 :     case JSTYPE_XML:
         209                 :         // fall through
         210                 :     default:
         211               0 :         return false;
         212                 :     }
         213                 : }
         214                 :
         215                 : /*static*/ bool
         216               0 : ObjectWrapperChild::
         217                 : JSObject_from_PObjectWrapperChild(JSContext*,
         218                 :                                   const PObjectWrapperChild* from,
         219                 :                                   JSObject** to)
         220                 : {
         221                 :     const ObjectWrapperChild* owc =
         222               0 :         static_cast<const ObjectWrapperChild*>(from);
         223               0 :     *to = owc ? owc->mObj : NULL;
         224               0 :     return true;
         225                 : }
         226                 :
         227                 : /*static*/ bool
         228               0 : ObjectWrapperChild::JSObject_from_JSVariant(JSContext* cx,
         229                 :                                             const JSVariant& from,
         230                 :                                             JSObject** to)
         231                 : {
         232               0 :     if (from.type() != JSVariant::TPObjectWrapperChild)
         233               0 :         return false;
         234                 :     return JSObject_from_PObjectWrapperChild(cx,
         235               0 :                                              from.get_PObjectWrapperChild(),
         236               0 :                                              to);
         237                 : }
         238                 :
         239                 : /*static*/ bool
         240               0 : ObjectWrapperChild::jsval_from_JSVariant(JSContext* cx, const JSVariant& from,
         241                 :                                          jsval* to)
         242                 : {
         243               0 :     switch (from.type()) {
         244                 :     case JSVariant::Tvoid_t:
         245               0 :         *to = JSVAL_VOID;
         246               0 :         return true;
         247                 :     case JSVariant::TPObjectWrapperChild:
         248                 :         {
         249                 :             JSObject* obj;
         250               0 :             if (!JSObject_from_JSVariant(cx, from, &obj))
         251               0 :                 return false;
         252               0 :             *to = OBJECT_TO_JSVAL(obj);
         253               0 :             return true;
         254                 :         }
         255                 :     case JSVariant::TnsString:
         256                 :         {
         257               0 :             const nsString& str = from.get_nsString();
         258                 :             JSString* s = JS_NewUCStringCopyN(cx,
         259                 :                                               str.BeginReading(),
         260               0 :                                               str.Length());
         261               0 :             if (!s)
         262               0 :                 return false;
         263               0 :             *to = STRING_TO_JSVAL(s);
         264                 :         }
         265               0 :         return true;
         266                 :     case JSVariant::Tint:
         267               0 :         *to = INT_TO_JSVAL(from.get_int());
         268               0 :         return true;
         269                 :     case JSVariant::Tdouble:
         270               0 :         return !!JS_NewNumberValue(cx, from.get_double(), to);
         271                 :     case JSVariant::Tbool:
         272               0 :         *to = BOOLEAN_TO_JSVAL(from.get_bool());
         273               0 :         return true;
         274                 :     default:
         275               0 :         return false;
         276                 :     }
         277                 : }
         278                 :
         279                 : ContextWrapperChild*
         280               0 : ObjectWrapperChild::Manager()
         281                 : {
         282               0 :     PContextWrapperChild* pcwc = PObjectWrapperChild::Manager();
         283               0 :     return static_cast<ContextWrapperChild*>(pcwc);
         284                 : }
         285                 :
         286                 : static bool
         287               0 : jsid_to_nsString(JSContext* cx, jsid from, nsString* to)
         288                 : {
         289               0 :     if (JSID_IS_STRING(from)) {
         290                 :         size_t length;
         291               0 :         const jschar* chars = JS_GetInternedStringCharsAndLength(JSID_TO_STRING(from), &length);
         292               0 :         *to = nsDependentString(chars, length);
         293               0 :         return true;
         294                 :     }
         295               0 :     return false;
         296                 : }
         297                 :
         298                 : static bool
         299               0 : jsid_from_nsString(JSContext* cx, const nsString& from, jsid* to)
         300                 : {
         301               0 :     JSString* str = JS_NewUCStringCopyN(cx, from.BeginReading(), from.Length());
         302               0 :     if (!str)
         303               0 :         return false;
         304               0 :     return JS_ValueToId(cx, STRING_TO_JSVAL(str), to);
         305                 : }
         306                 :
         307                 : #if 0
         308                 : // The general schema for ObjectWrapperChild::Answer* methods:
         309                 : bool
         310                 : ObjectWrapperChild::AnswerSomething(/* in-parameters */
         311                 :                                     /* out-parameters */)
         312                 : {
         313                 :     // initialize out-parameters for failure
         314                 :     JSContext* cx = Manager()->GetContext();
         315                 :     AutoContextPusher acp(cx);
         316                 :     // validate in-parameters, else return false
         317                 :     // successfully perform local JS operations, else return true
         318                 :     // perform out-parameter conversions, else return false
         319                 :     return true;
         320                 : }
         321                 : // There's an important subtlety here: though a local JS operation may
         322                 : // fail, leaving out-parameters uninitialized, we must initialize all
         323                 : // out-parameters when reporting success (returning true) to the IPC
         324                 : // messaging system.  See AnswerGetProperty for illustration.
         325                 : #endif
         326                 :
         327                 : bool
         328               0 : ObjectWrapperChild::AnswerAddProperty(const nsString& id,
         329                 :                                       OperationStatus* status)
         330                 : {
         331                 :     jsid interned_id;
         332                 :
         333               0 :     JSContext* cx = Manager()->GetContext();
         334               0 :     AutoContextPusher acp(cx);
         335               0 :     AutoCheckOperation aco(this, status);
         336                 :
         337               0 :     if (!jsid_from_nsString(cx, id, &interned_id))
         338               0 :         return false;
         339                 :
         340                 :     *status = JS_DefinePropertyById(cx, mObj, interned_id, JSVAL_VOID,
         341               0 :                                     NULL, NULL, 0);
         342               0 :     return true;
         343                 : }
         344                 :
         345                 : bool
         346               0 : ObjectWrapperChild::AnswerGetProperty(const nsString& id,
         347                 :                                       OperationStatus* status, JSVariant* vp)
         348                 : {
         349                 :     jsid interned_id;
         350                 :     jsval val;
         351                 :
         352               0 :     JSContext* cx = Manager()->GetContext();
         353               0 :     AutoContextPusher acp(cx);
         354               0 :     AutoCheckOperation aco(this, status);
         355                 :
         356               0 :     if (!jsid_from_nsString(cx, id, &interned_id))
         357               0 :         return false;
         358                 :
         359               0 :     *status = JS_GetPropertyById(cx, mObj, interned_id, &val);
         360                 :
         361                 :     // Since we fully expect this call to jsval_to_JSVariant to return
         362                 :     // true, we can't just leave vp uninitialized when JS_GetPropertyById
         363                 :     // returns JS_FALSE.  This pitfall could be avoided in general if IPDL
         364                 :     // ensured that outparams were pre-initialized to some default value
         365                 :     // (XXXfixme cjones?).
         366               0 :     return jsval_to_JSVariant(cx, aco.Ok() ? val : JSVAL_VOID, vp);
         367                 : }
         368                 :
         369                 : bool
         370               0 : ObjectWrapperChild::AnswerSetProperty(const nsString& id, const JSVariant& v,
         371                 :                                       OperationStatus* status, JSVariant* vp)
         372                 : {
         373                 :     jsid interned_id;
         374                 :     jsval val;
         375                 :
         376               0 :     *vp = v;
         377                 :
         378               0 :     JSContext* cx = Manager()->GetContext();
         379               0 :     AutoContextPusher acp(cx);
         380               0 :     AutoCheckOperation aco(this, status);
         381                 :
         382               0 :     if (!jsid_from_nsString(cx, id, &interned_id) ||
         383               0 :         !jsval_from_JSVariant(cx, v, &val))
         384               0 :         return false;
         385                 :
         386               0 :     *status = JS_SetPropertyById(cx, mObj, interned_id, &val);
         387                 :
         388               0 :     return jsval_to_JSVariant(cx, aco.Ok() ? val : JSVAL_VOID, vp);
         389                 : }
         390                 :
         391                 : bool
         392               0 : ObjectWrapperChild::AnswerDelProperty(const nsString& id,
         393                 :                                       OperationStatus* status, JSVariant* vp)
         394                 : {
         395                 :     jsid interned_id;
         396                 :     jsval val;
         397                 :
         398               0 :     JSContext* cx = Manager()->GetContext();
         399               0 :     AutoContextPusher acp(cx);
         400               0 :     AutoCheckOperation aco(this, status);
         401                 :
         402               0 :     if (!jsid_from_nsString(cx, id, &interned_id))
         403               0 :         return false;
         404                 :
         405               0 :     *status = JS_DeletePropertyById2(cx, mObj, interned_id, &val);
         406                 :
         407               0 :     return jsval_to_JSVariant(cx, aco.Ok() ? val : JSVAL_VOID, vp);
         408                 : }
         409                 :
         410                 : static const PRUint32 sNextIdIndexSlot = 0;
         411                 : static const PRUint32 sNumNewEnumerateStateSlots = 1;
         412                 :
         413                 : static void
         414               0 : CPOW_NewEnumerateState_Finalize(JSContext* cx, JSObject* state)
         415                 : {
         416                 :     nsTArray<nsString>* strIds =
         417               0 :         static_cast<nsTArray<nsString>*>(JS_GetPrivate(state));
         418                 :
         419               0 :     if (strIds) {
         420               0 :         delete strIds;
         421               0 :         JS_SetPrivate(state, NULL);
         422                 :     }
         423               0 : }
         424                 :
         425                 : // Similar to IteratorClass in XPCWrapper.cpp
         426                 : static const JSClass sCPOW_NewEnumerateState_JSClass = {
         427                 :     "CPOW NewEnumerate State",
         428                 :     JSCLASS_HAS_PRIVATE |
         429                 :     JSCLASS_HAS_RESERVED_SLOTS(sNumNewEnumerateStateSlots),
         430                 :     JS_PropertyStub,  JS_PropertyStub,
         431                 :     JS_PropertyStub,  JS_StrictPropertyStub,
         432                 :     JS_EnumerateStub, JS_ResolveStub,
         433                 :     JS_ConvertStub,   CPOW_NewEnumerateState_Finalize,
         434                 :     JSCLASS_NO_OPTIONAL_MEMBERS
         435                 : };
         436                 :
         437                 : bool
         438               0 : ObjectWrapperChild::AnswerNewEnumerateInit(/* no in-parameters */
         439                 :                                            OperationStatus* status, JSVariant* statep, int* idp)
         440                 : {
         441               0 :     *idp = 0;
         442                 :
         443               0 :     JSContext* cx = Manager()->GetContext();
         444               0 :     AutoContextPusher acp(cx);
         445               0 :     AutoCheckOperation aco(this, status);
         446                 :
         447               0 :     JSClass* clasp = const_cast<JSClass*>(&sCPOW_NewEnumerateState_JSClass);
         448               0 :     JSObject* state = JS_NewObjectWithGivenProto(cx, clasp, NULL, NULL);
         449               0 :     if (!state)
         450               0 :         return false;
         451               0 :     AutoObjectRooter tvr(cx, state);
         452                 :
         453               0 :     for (JSObject* proto = mObj;
         454                 :          proto;
         455                 :          proto = JS_GetPrototype(proto))
         456                 :     {
         457               0 :         AutoIdArray ids(cx, JS_Enumerate(cx, proto));
         458               0 :         for (size_t i = 0; i < ids.length(); ++i)
         459                 :             JS_DefinePropertyById(cx, state, ids[i], JSVAL_VOID,
         460               0 :                                   NULL, NULL, JSPROP_ENUMERATE | JSPROP_SHARED);
         461                 :     }
         462                 :
         463                 :     InfallibleTArray<nsString>* strIds;
         464                 :     {
         465               0 :         AutoIdArray ids(cx, JS_Enumerate(cx, state));
         466               0 :         if (!ids)
         467               0 :             return false;
         468               0 :         strIds = new InfallibleTArray<nsString>(ids.length());
         469               0 :         for (size_t i = 0; i < ids.length(); ++i)
         470               0 :             if (!jsid_to_nsString(cx, ids[i], strIds->AppendElement())) {
         471               0 :                 delete strIds;
         472               0 :                 return false;
         473                 :             }
         474                 :     }
         475               0 :     *idp = strIds->Length();
         476                 :
         477               0 :     JS_SetPrivate(state, strIds);
         478               0 :     JS_SetReservedSlot(state, sNextIdIndexSlot, JSVAL_ZERO);
         479                 :
         480               0 :     *status = JSObject_to_JSVariant(cx, state, statep);
         481                 :
         482               0 :     return true;
         483                 : }
         484                 :
         485                 : bool
         486               0 : ObjectWrapperChild::AnswerNewEnumerateNext(const JSVariant& in_state,
         487                 :                                            OperationStatus* status, JSVariant* statep, nsString* idp)
         488                 : {
         489                 :     JSObject* state;
         490                 :
         491               0 :     *statep = in_state;
         492               0 :     idp->Truncate();
         493                 :
         494               0 :     JSContext* cx = Manager()->GetContext();
         495               0 :     AutoContextPusher acp(cx);
         496               0 :     AutoCheckOperation aco(this, status);
         497                 :
         498               0 :     if (!JSObject_from_JSVariant(cx, in_state, &state))
         499               0 :         return false;
         500                 :
         501                 :     InfallibleTArray<nsString>* strIds =
         502               0 :         static_cast<InfallibleTArray<nsString>*>(JS_GetPrivate(state));
         503                 :
         504               0 :     if (!strIds)
         505               0 :         return false;
         506                 :
         507               0 :     jsval v = JS_GetReservedSlot(state, sNextIdIndexSlot);
         508                 :
         509               0 :     int32_t i = JSVAL_TO_INT(v);
         510               0 :     NS_ASSERTION(i >= 0, "Index of next jsid negative?");
         511               0 :     NS_ASSERTION(i <= strIds->Length(), "Index of next jsid too large?");
         512                 :
         513               0 :     if (size_t(i) == strIds->Length()) {
         514               0 :         *status = JS_TRUE;
         515               0 :         return JSObject_to_JSVariant(cx, NULL, statep);
         516                 :     }
         517                 :
         518               0 :     *idp = strIds->ElementAt(i);
         519               0 :     JS_SetReservedSlot(state, sNextIdIndexSlot, INT_TO_JSVAL(i + 1));
         520               0 :     *status = JS_TRUE;
         521               0 :     return true;
         522                 : }
         523                 :
         524                 : bool
         525               0 : ObjectWrapperChild::RecvNewEnumerateDestroy(const JSVariant& in_state)
         526                 : {
         527                 :     JSObject* state;
         528                 :
         529               0 :     JSContext* cx = Manager()->GetContext();
         530               0 :     AutoContextPusher acp(cx);
         531                 :
         532               0 :     if (!JSObject_from_JSVariant(cx, in_state, &state))
         533               0 :         return false;
         534                 :
         535               0 :     CPOW_NewEnumerateState_Finalize(cx, state);
         536                 :
         537               0 :     return true;
         538                 : }
         539                 :
         540                 : bool
         541               0 : ObjectWrapperChild::AnswerNewResolve(const nsString& id, const int& flags,
         542                 :                                      OperationStatus* status, PObjectWrapperChild** obj2)
         543                 : {
         544                 :     jsid interned_id;
         545                 :
         546               0 :     *obj2 = NULL;
         547                 :
         548               0 :     JSContext* cx = Manager()->GetContext();
         549               0 :     AutoContextPusher acp(cx);
         550               0 :     AutoCheckOperation aco(this, status);
         551                 :
         552               0 :     if (!jsid_from_nsString(cx, id, &interned_id))
         553               0 :         return false;
         554                 :
         555                 :     CPOW_LOG(("new-resolving \"%s\"...",
         556                 :               NS_ConvertUTF16toUTF8(id).get()));
         557                 :
         558                 :     JSPropertyDescriptor desc;
         559               0 :     if (!JS_GetPropertyDescriptorById(cx, mObj, interned_id, flags, &desc))
         560               0 :         return true;
         561                 :
         562               0 :     *status = JS_TRUE;
         563                 :
         564               0 :     if (desc.obj)
         565               0 :         *obj2 = Manager()->GetOrCreateWrapper(desc.obj);
         566                 :
         567               0 :     return true;
         568                 : }
         569                 :
         570                 : bool
         571               0 : ObjectWrapperChild::AnswerConvert(const JSType& type,
         572                 :                                   OperationStatus* status, JSVariant* vp)
         573                 : {
         574                 :     jsval v;
         575               0 :     JSContext* cx = Manager()->GetContext();
         576               0 :     AutoContextPusher acp(cx);
         577               0 :     AutoCheckOperation aco(this, status);
         578               0 :     *status = JS_ConvertValue(cx, OBJECT_TO_JSVAL(mObj), type, &v);
         579               0 :     return jsval_to_JSVariant(cx, aco.Ok() ? v : JSVAL_VOID, vp);
         580                 : }
         581                 :
         582                 : namespace {
         583                 :     // Should be an overestimate of typical JS function arity.
         584                 :     typedef nsAutoTArray<jsval, 5> AutoJSArgs;
         585                 : }
         586                 :
         587                 : bool
         588               0 : ObjectWrapperChild::AnswerCall(PObjectWrapperChild* receiver, const InfallibleTArray<JSVariant>& argv,
         589                 :                                OperationStatus* status, JSVariant* rval)
         590                 : {
         591               0 :     JSContext* cx = Manager()->GetContext();
         592               0 :     AutoContextPusher acp(cx);
         593               0 :     AutoCheckOperation aco(this, status);
         594                 :
         595                 :     JSObject* obj;
         596               0 :     if (!JSObject_from_PObjectWrapperChild(cx, receiver, &obj))
         597               0 :         return false;
         598                 :
         599               0 :     AutoJSArgs args;
         600               0 :     PRUint32 argc = argv.Length();
         601               0 :     jsval *jsargs = args.AppendElements(argc);
         602               0 :     if (!jsargs)
         603               0 :         return false;
         604               0 :     AutoArrayRooter tvr(cx, argc, jsargs);
         605                 :
         606               0 :     for (PRUint32 i = 0; i < argc; ++i)
         607               0 :         if (!jsval_from_JSVariant(cx, argv.ElementAt(i), jsargs + i))
         608               0 :             return false;
         609                 :
         610                 :     jsval rv;
         611               0 :     *status = JS_CallFunctionValue(cx, obj, OBJECT_TO_JSVAL(mObj),
         612               0 :                                    argv.Length(), jsargs, &rv);
         613                 :
         614               0 :     return jsval_to_JSVariant(cx, aco.Ok() ? rv : JSVAL_VOID, rval);
         615                 : }
         616                 :
         617                 : bool
         618               0 : ObjectWrapperChild::AnswerConstruct(const InfallibleTArray<JSVariant>& argv,
         619                 :                                     OperationStatus* status, PObjectWrapperChild** rval)
         620                 : {
         621               0 :     JSContext* cx = Manager()->GetContext();
         622               0 :     AutoContextPusher acp(cx);
         623               0 :     AutoCheckOperation aco(this, status);
         624                 :
         625               0 :     AutoJSArgs args;
         626               0 :     PRUint32 argc = argv.Length();
         627               0 :     jsval* jsargs = args.AppendElements(argc);
         628               0 :     if (!jsargs)
         629               0 :         return false;
         630               0 :     AutoArrayRooter tvr(cx, argc, jsargs);
         631                 :
         632               0 :     for (PRUint32 i = 0; i < argc; ++i)
         633               0 :         if (!jsval_from_JSVariant(cx, argv.ElementAt(i), jsargs + i))
         634               0 :             return false;
         635                 :
         636               0 :     JSObject* obj = JS_New(cx, mObj, argc, jsargs);
         637                 :
         638               0 :     *status = !!obj;
         639               0 :     *rval = Manager()->GetOrCreateWrapper(obj);
         640                 :
         641               0 :     return true;
         642                 : }
         643                 :
         644                 : bool
         645               0 : ObjectWrapperChild::AnswerHasInstance(const JSVariant& v,
         646                 :                                       OperationStatus* status, JSBool* bp)
         647                 : {
         648                 :     jsval candidate;
         649               0 :     JSContext* cx = Manager()->GetContext();
         650               0 :     AutoContextPusher acp(cx);
         651               0 :     AutoCheckOperation aco(this, status);
         652               0 :     if (!jsval_from_JSVariant(cx, v, &candidate))
         653               0 :         return false;
         654               0 :     *status = JS_HasInstance(cx, mObj, candidate, bp);
         655               0 :     return true;
         656                 : }

Generated by: LCOV version 1.7