LCOV - app.info - js/src/vm/GlobalObject.cpp

LCOV - code coverage report
| Current view: | directory - js/src/vm - GlobalObject.cpp (source / functions) |  | Found | Hit | Coverage |
| Test: | app.info | Lines: | 215 | 155 | 72.1 %
| Date: | 2012-04-07 | Functions: | 18 | 15 | 83.3 %

           1                 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
           2                 :  * vim: set ts=8 sw=4 et tw=99:
           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 SpiderMonkey global object 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) 2011
          22                 :  * the Initial Developer. All Rights Reserved.
          23                 :  *
          24                 :  * Contributor(s):
          25                 :  *   Jeff Walden <jwalden+code@mit.edu> (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 "GlobalObject.h"
          42                 :
          43                 : #include "jscntxt.h"
          44                 : #include "jsexn.h"
          45                 : #include "jsmath.h"
          46                 : #include "json.h"
          47                 : #include "jsweakmap.h"
          48                 :
          49                 : #include "builtin/MapObject.h"
          50                 : #include "builtin/RegExp.h"
          51                 : #include "frontend/BytecodeEmitter.h"
          52                 : #include "vm/GlobalObject-inl.h"
          53                 :
          54                 : #include "jsobjinlines.h"
          55                 : #include "vm/RegExpObject-inl.h"
          56                 : #include "vm/RegExpStatics-inl.h"
          57                 :
          58                 : #ifdef JS_METHODJIT
          59                 : #include "methodjit/Retcon.h"
          60                 : #endif
          61                 :
          62                 : using namespace js;
          63                 :
          64                 : JSObject *
          65           23355 : js_InitObjectClass(JSContext *cx, JSObject *obj)
          66                 : {
          67           23355 :     JS_ASSERT(obj->isNative());
          68                 :
          69           23355 :     return obj->asGlobal().getOrCreateObjectPrototype(cx);
          70                 : }
          71                 :
          72                 : JSObject *
          73              10 : js_InitFunctionClass(JSContext *cx, JSObject *obj)
          74                 : {
          75              10 :     JS_ASSERT(obj->isNative());
          76                 :
          77              10 :     return obj->asGlobal().getOrCreateFunctionPrototype(cx);
          78                 : }
          79                 :
          80                 : static JSBool
          81               0 : ThrowTypeError(JSContext *cx, unsigned argc, Value *vp)
          82                 : {
          83                 :     JS_ReportErrorFlagsAndNumber(cx, JSREPORT_ERROR, js_GetErrorMessage, NULL,
          84               0 :                                  JSMSG_THROW_TYPE_ERROR);
          85               0 :     return false;
          86                 : }
          87                 :
          88                 : namespace js {
          89                 :
          90                 : JSObject *
          91           23629 : GlobalObject::initFunctionAndObjectClasses(JSContext *cx)
          92                 : {
          93           47258 :     RootedVar<GlobalObject*> self(cx, this);
          94                 :
          95           23629 :     JS_THREADSAFE_ASSERT(cx->compartment != cx->runtime->atomsCompartment);
          96           23629 :     JS_ASSERT(isNative());
          97                 :
          98                 :     /*
          99                 :      * Calling a function from a cleared global triggers this (yeah, I know).
         100                 :      * Uncomment this once bug 470510 is fixed (if that bug doesn't remove
         101                 :      * isCleared entirely).
         102                 :      */
         103                 :     // JS_ASSERT(!isCleared());
         104                 :
         105                 :     /* If cx has no global object, make this the global object. */
         106           23629 :     if (!cx->globalObject)
         107           18666 :         JS_SetGlobalObject(cx, self);
         108                 :
         109           47258 :     RootedVarObject objectProto(cx);
         110                 :
         111                 :     /*
         112                 :      * Create |Object.prototype| first, mirroring CreateBlankProto but for the
         113                 :      * prototype of the created object.
         114                 :      */
         115           23629 :     objectProto = NewObjectWithGivenProto(cx, &ObjectClass, NULL, self);
         116           23629 :     if (!objectProto || !objectProto->setSingletonType(cx))
         117               0 :         return NULL;
         118                 :
         119                 :     /*
         120                 :      * The default 'new' type of Object.prototype is required by type inference
         121                 :      * to have unknown properties, to simplify handling of e.g. heterogenous
         122                 :      * objects in JSON and script literals.
         123                 :      */
         124           23629 :     if (!objectProto->setNewTypeUnknown(cx))
         125               0 :         return NULL;
         126                 :
         127                 :     /* Create |Function.prototype| next so we can create other functions. */
         128           47258 :     RootedVarFunction functionProto(cx);
         129                 :     {
         130           23629 :         JSObject *functionProto_ = NewObjectWithGivenProto(cx, &FunctionClass, objectProto, self);
         131           23629 :         if (!functionProto_)
         132               0 :             return NULL;
         133           23629 :         functionProto = functionProto_->toFunction();
         134                 :
         135                 :         /*
         136                 :          * Bizarrely, |Function.prototype| must be an interpreted function, so
         137                 :          * give it the guts to be one.
         138                 :          */
         139                 :         JSObject *proto = js_NewFunction(cx, functionProto,
         140           23629 :                                          NULL, 0, JSFUN_INTERPRETED, self, NULL);
         141           23629 :         if (!proto)
         142               0 :             return NULL;
         143           23629 :         JS_ASSERT(proto == functionProto);
         144           23629 :         functionProto->flags |= JSFUN_PROTOTYPE;
         145                 :
         146                 :         JSScript *script =
         147           23629 :             JSScript::NewScript(cx, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, JSVERSION_DEFAULT);
         148           23629 :         if (!script)
         149               0 :             return NULL;
         150           23629 :         script->noScriptRval = true;
         151           23629 :         script->code[0] = JSOP_STOP;
         152           23629 :         script->code[1] = SRC_NULL;
         153           23629 :         functionProto->initScript(script);
         154           23629 :         functionProto->getType(cx)->interpretedFunction = functionProto;
         155           23629 :         script->setFunction(functionProto);
         156                 :
         157           23629 :         if (!functionProto->setSingletonType(cx))
         158               0 :             return NULL;
         159                 :
         160                 :         /*
         161                 :          * The default 'new' type of Function.prototype is required by type
         162                 :          * inference to have unknown properties, to simplify handling of e.g.
         163                 :          * CloneFunctionObject.
         164                 :          */
         165           23629 :         if (!functionProto->setNewTypeUnknown(cx))
         166               0 :             return NULL;
         167                 :     }
         168                 :
         169                 :     /* Create the Object function now that we have a [[Prototype]] for it. */
         170           47258 :     RootedVarFunction objectCtor(cx);
         171                 :     {
         172           23629 :         JSObject *ctor = NewObjectWithGivenProto(cx, &FunctionClass, functionProto, self);
         173           23629 :         if (!ctor)
         174               0 :             return NULL;
         175                 :         objectCtor = js_NewFunction(cx, ctor, js_Object, 1, JSFUN_CONSTRUCTOR, self,
         176           23629 :                                     CLASS_ATOM(cx, Object));
         177           23629 :         if (!objectCtor)
         178               0 :             return NULL;
         179                 :     }
         180                 :
         181                 :     /*
         182                 :      * Install |Object| and |Object.prototype| for the benefit of subsequent
         183                 :      * code that looks for them.
         184                 :      */
         185           23629 :     self->setObjectClassDetails(objectCtor, objectProto);
         186                 :
         187                 :     /* Create |Function| so it and |Function.prototype| can be installed. */
         188           47258 :     RootedVarFunction functionCtor(cx);
         189                 :     {
         190                 :         JSObject *ctor =
         191           23629 :             NewObjectWithGivenProto(cx, &FunctionClass, functionProto, self);
         192           23629 :         if (!ctor)
         193               0 :             return NULL;
         194                 :         functionCtor = js_NewFunction(cx, ctor, Function, 1, JSFUN_CONSTRUCTOR, self,
         195           23629 :                                       CLASS_ATOM(cx, Function));
         196           23629 :         if (!functionCtor)
         197               0 :             return NULL;
         198           23629 :         JS_ASSERT(ctor == functionCtor);
         199                 :     }
         200                 :
         201                 :     /*
         202                 :      * Install |Function| and |Function.prototype| so that we can freely create
         203                 :      * functions and objects without special effort.
         204                 :      */
         205           23629 :     self->setFunctionClassDetails(functionCtor, functionProto);
         206                 :
         207                 :     /*
         208                 :      * The hard part's done: now go back and add all the properties these
         209                 :      * primordial values have.
         210                 :      */
         211          141774 :     if (!LinkConstructorAndPrototype(cx, objectCtor, objectProto) ||
         212           23629 :         !DefinePropertiesAndBrand(cx, objectProto, object_props, object_methods) ||
         213           23629 :         !DefinePropertiesAndBrand(cx, objectCtor, NULL, object_static_methods) ||
         214           23629 :         !LinkConstructorAndPrototype(cx, functionCtor, functionProto) ||
         215           23629 :         !DefinePropertiesAndBrand(cx, functionProto, NULL, function_methods) ||
         216           23629 :         !DefinePropertiesAndBrand(cx, functionCtor, NULL, NULL))
         217                 :     {
         218               0 :         return NULL;
         219                 :     }
         220                 :
         221                 :     /* Add the global Function and Object properties now. */
         222           23629 :     jsid objectId = ATOM_TO_JSID(CLASS_ATOM(cx, Object));
         223           23629 :     if (!self->addDataProperty(cx, objectId, JSProto_Object + JSProto_LIMIT * 2, 0))
         224               0 :         return NULL;
         225           23629 :     jsid functionId = ATOM_TO_JSID(CLASS_ATOM(cx, Function));
         226           23629 :     if (!self->addDataProperty(cx, functionId, JSProto_Function + JSProto_LIMIT * 2, 0))
         227               0 :         return NULL;
         228                 :
         229                 :     /* Heavy lifting done, but lingering tasks remain. */
         230                 :
         231                 :     /* ES5 15.1.2.1. */
         232           23629 :     jsid id = ATOM_TO_JSID(cx->runtime->atomState.evalAtom);
         233           23629 :     JSObject *evalobj = js_DefineFunction(cx, self, id, eval, 1, JSFUN_STUB_GSOPS);
         234           23629 :     if (!evalobj)
         235               0 :         return NULL;
         236           23629 :     self->setOriginalEval(evalobj);
         237                 :
         238                 :     /* ES5 13.2.3: Construct the unique [[ThrowTypeError]] function object. */
         239           47258 :     RootedVarFunction throwTypeError(cx);
         240           23629 :     throwTypeError = js_NewFunction(cx, NULL, ThrowTypeError, 0, 0, self, NULL);
         241           23629 :     if (!throwTypeError)
         242               0 :         return NULL;
         243           47258 :     AutoIdVector ids(cx);
         244           23629 :     if (!throwTypeError->preventExtensions(cx, &ids))
         245               0 :         return NULL;
         246           23629 :     self->setThrowTypeError(throwTypeError);
         247                 :
         248                 :     /*
         249                 :      * The global object should have |Object.prototype| as its [[Prototype]].
         250                 :      * Eventually we'd like to have standard classes be there from the start,
         251                 :      * and thus we would know we were always setting what had previously been a
         252                 :      * null [[Prototype]], but right now some code assumes it can set the
         253                 :      * [[Prototype]] before standard classes have been initialized.  For now,
         254                 :      * only set the [[Prototype]] if it hasn't already been set.
         255                 :      */
         256           23629 :     if (self->shouldSplicePrototype(cx) && !self->splicePrototype(cx, objectProto))
         257               0 :         return NULL;
         258                 :
         259                 :     /*
         260                 :      * Notify any debuggers about the creation of the script for
         261                 :      * |Function.prototype| -- after all initialization, for simplicity.
         262                 :      */
         263           23629 :     js_CallNewScriptHook(cx, functionProto->script(), functionProto);
         264           23629 :     return functionProto;
         265                 : }
         266                 :
         267                 : GlobalObject *
         268           23659 : GlobalObject::create(JSContext *cx, Class *clasp)
         269                 : {
         270           23659 :     JS_ASSERT(clasp->flags & JSCLASS_IS_GLOBAL);
         271                 :
         272           47318 :     RootedVar<GlobalObject*> obj(cx);
         273                 :
         274           23659 :     JSObject *obj_ = NewObjectWithGivenProto(cx, clasp, NULL, NULL);
         275           23659 :     if (!obj_)
         276               0 :         return NULL;
         277           23659 :     obj = &obj_->asGlobal();
         278                 :
         279           23659 :     if (!obj->setSingletonType(cx) || !obj->setVarObj(cx))
         280               0 :         return NULL;
         281                 :
         282                 :     /* Construct a regexp statics object for this global object. */
         283           23659 :     JSObject *res = RegExpStatics::create(cx, obj);
         284           23659 :     if (!res)
         285               0 :         return NULL;
         286           23659 :     obj->initSlot(REGEXP_STATICS, ObjectValue(*res));
         287           23659 :     obj->initFlags(0);
         288                 :
         289           23659 :     return obj;
         290                 : }
         291                 :
         292                 : bool
         293             264 : GlobalObject::initStandardClasses(JSContext *cx)
         294                 : {
         295             264 :     JSAtomState &state = cx->runtime->atomState;
         296                 :
         297                 :     /* Define a top-level property 'undefined' with the undefined value. */
         298             264 :     if (!defineProperty(cx, state.typeAtoms[JSTYPE_VOID], UndefinedValue(),
         299             264 :                         JS_PropertyStub, JS_StrictPropertyStub, JSPROP_PERMANENT | JSPROP_READONLY))
         300                 :     {
         301               0 :         return false;
         302                 :     }
         303                 :
         304             264 :     if (!initFunctionAndObjectClasses(cx))
         305               0 :         return false;
         306                 :
         307                 :     /* Initialize the rest of the standard objects and functions. */
         308             264 :     return js_InitArrayClass(cx, this) &&
         309             264 :            js_InitBooleanClass(cx, this) &&
         310             264 :            js_InitExceptionClasses(cx, this) &&
         311             264 :            js_InitMathClass(cx, this) &&
         312             264 :            js_InitNumberClass(cx, this) &&
         313             264 :            js_InitJSONClass(cx, this) &&
         314             264 :            js_InitRegExpClass(cx, this) &&
         315             264 :            js_InitStringClass(cx, this) &&
         316             264 :            js_InitTypedArrayClasses(cx, this) &&
         317                 : #if JS_HAS_XML_SUPPORT
         318             264 :            js_InitXMLClasses(cx, this) &&
         319                 : #endif
         320                 : #if JS_HAS_GENERATORS
         321             264 :            js_InitIteratorClasses(cx, this) &&
         322                 : #endif
         323             264 :            js_InitDateClass(cx, this) &&
         324             264 :            js_InitWeakMapClass(cx, this) &&
         325             264 :            js_InitProxyClass(cx, this) &&
         326             264 :            js_InitMapClass(cx, this) &&
         327            3960 :            js_InitSetClass(cx, this);
         328                 : }
         329                 :
         330                 : void
         331               0 : GlobalObject::clear(JSContext *cx)
         332                 : {
         333               0 :     for (int key = JSProto_Null; key < JSProto_LIMIT * 3; key++)
         334               0 :         setSlot(key, UndefinedValue());
         335                 :
         336                 :     /* Clear regexp statics. */
         337               0 :     getRegExpStatics()->clear();
         338                 :
         339                 :     /* Clear the runtime-codegen-enabled cache. */
         340               0 :     setSlot(RUNTIME_CODEGEN_ENABLED, UndefinedValue());
         341                 :
         342                 :     /*
         343                 :      * Clear the original-eval and [[ThrowTypeError]] slots, in case throwing
         344                 :      * trying to execute a script for this global must reinitialize standard
         345                 :      * classes.  See bug 470150.
         346                 :      */
         347               0 :     setSlot(EVAL, UndefinedValue());
         348               0 :     setSlot(THROWTYPEERROR, UndefinedValue());
         349                 :
         350                 :     /*
         351                 :      * Mark global as cleared. If we try to execute any compile-and-go
         352                 :      * scripts from here on, we will throw.
         353                 :      */
         354               0 :     int32_t flags = getSlot(FLAGS).toInt32();
         355               0 :     flags |= FLAGS_CLEARED;
         356               0 :     setSlot(FLAGS, Int32Value(flags));
         357                 :
         358                 :     /*
         359                 :      * Reset the new object cache in the compartment, which assumes that
         360                 :      * prototypes cached on the global object are immutable.
         361                 :      */
         362               0 :     cx->compartment->newObjectCache.reset();
         363                 :
         364                 : #ifdef JS_METHODJIT
         365                 :     /*
         366                 :      * Destroy compiled code for any scripts parented to this global. Call ICs
         367                 :      * can directly call scripts which have associated JIT code, and do so
         368                 :      * without checking whether the script's global has been cleared.
         369                 :      */
         370               0 :     for (gc::CellIter i(cx->compartment, gc::FINALIZE_SCRIPT); !i.done(); i.next()) {
         371               0 :         JSScript *script = i.get<JSScript>();
         372               0 :         if (script->compileAndGo && script->hasJITCode() && script->hasClearedGlobal()) {
         373               0 :             mjit::Recompiler::clearStackReferences(cx->runtime->defaultFreeOp(), script);
         374               0 :             mjit::ReleaseScriptCode(cx->runtime->defaultFreeOp(), script);
         375                 :         }
         376                 :     }
         377                 : #endif
         378               0 : }
         379                 :
         380                 : bool
         381          108221 : GlobalObject::isRuntimeCodeGenEnabled(JSContext *cx)
         382                 : {
         383          108221 :     HeapSlot &v = getSlotRef(RUNTIME_CODEGEN_ENABLED);
         384          108221 :     if (v.isUndefined()) {
         385                 :         /*
         386                 :          * If there are callbacks, make sure that the CSP callback is installed
         387                 :          * and that it permits runtime code generation, then cache the result.
         388                 :          */
         389            5334 :         JSCSPEvalChecker allows = cx->runtime->securityCallbacks->contentSecurityPolicyAllows;
         390            5334 :         v.set(this, RUNTIME_CODEGEN_ENABLED, BooleanValue(!allows || allows(cx)));
         391                 :     }
         392          108221 :     return !v.isFalse();
         393                 : }
         394                 :
         395                 : JSFunction *
         396           69713 : GlobalObject::createConstructor(JSContext *cx, Native ctor, JSAtom *name, unsigned length,
         397                 :                                 gc::AllocKind kind)
         398                 : {
         399          139426 :     RootedVarObject self(cx, this);
         400           69713 :     return js_NewFunction(cx, NULL, ctor, length, JSFUN_CONSTRUCTOR, self, name, kind);
         401                 : }
         402                 :
         403                 : static JSObject *
         404           71915 : CreateBlankProto(JSContext *cx, Class *clasp, JSObject &proto, GlobalObject &global)
         405                 : {
         406           71915 :     JS_ASSERT(clasp != &ObjectClass);
         407           71915 :     JS_ASSERT(clasp != &FunctionClass);
         408                 :
         409           71915 :     JSObject *blankProto = NewObjectWithGivenProto(cx, clasp, &proto, &global);
         410           71915 :     if (!blankProto || !blankProto->setSingletonType(cx))
         411               0 :         return NULL;
         412                 :
         413           71915 :     return blankProto;
         414                 : }
         415                 :
         416                 : JSObject *
         417           44811 : GlobalObject::createBlankPrototype(JSContext *cx, Class *clasp)
         418                 : {
         419           44811 :     JSObject *objectProto = getOrCreateObjectPrototype(cx);
         420           44811 :     if (!objectProto)
         421               0 :         return NULL;
         422                 :
         423           44811 :     return CreateBlankProto(cx, clasp, *objectProto, *this);
         424                 : }
         425                 :
         426                 : JSObject *
         427           27104 : GlobalObject::createBlankPrototypeInheriting(JSContext *cx, Class *clasp, JSObject &proto)
         428                 : {
         429           27104 :     return CreateBlankProto(cx, clasp, proto, *this);
         430                 : }
         431                 :
         432                 : bool
         433          322273 : LinkConstructorAndPrototype(JSContext *cx, JSObject *ctor, JSObject *proto)
         434                 : {
         435          644546 :     RootObject ctorRoot(cx, &ctor);
         436          644546 :     RootObject protoRoot(cx, &proto);
         437                 :
         438                 :     return ctor->defineProperty(cx, cx->runtime->atomState.classPrototypeAtom,
         439          322273 :                                 ObjectValue(*proto), JS_PropertyStub, JS_StrictPropertyStub,
         440          322273 :                                 JSPROP_PERMANENT | JSPROP_READONLY) &&
         441                 :            proto->defineProperty(cx, cx->runtime->atomState.constructorAtom,
         442          322273 :                                  ObjectValue(*ctor), JS_PropertyStub, JS_StrictPropertyStub, 0);
         443                 : }
         444                 :
         445                 : bool
         446          574608 : DefinePropertiesAndBrand(JSContext *cx, JSObject *obj, JSPropertySpec *ps, JSFunctionSpec *fs)
         447                 : {
         448         1149216 :     RootObject root(cx, &obj);
         449                 :
         450          574608 :     if ((ps && !JS_DefineProperties(cx, obj, ps)) || (fs && !JS_DefineFunctions(cx, obj, fs)))
         451               0 :         return false;
         452          574608 :     return true;
         453                 : }
         454                 :
         455                 : void
         456            3332 : GlobalDebuggees_finalize(FreeOp *fop, JSObject *obj)
         457                 : {
         458            3332 :     fop->delete_((GlobalObject::DebuggerVector *) obj->getPrivate());
         459            3332 : }
         460                 :
         461                 : static Class
         462                 : GlobalDebuggees_class = {
         463                 :     "GlobalDebuggee", JSCLASS_HAS_PRIVATE,
         464                 :     JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
         465                 :     JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, GlobalDebuggees_finalize
         466                 : };
         467                 :
         468                 : GlobalObject::DebuggerVector *
         469          131913 : GlobalObject::getDebuggers()
         470                 : {
         471          131913 :     Value debuggers = getReservedSlot(DEBUGGERS);
         472          131913 :     if (debuggers.isUndefined())
         473            4535 :         return NULL;
         474          127378 :     JS_ASSERT(debuggers.toObject().getClass() == &GlobalDebuggees_class);
         475          127378 :     return (DebuggerVector *) debuggers.toObject().getPrivate();
         476                 : }
         477                 :
         478                 : GlobalObject::DebuggerVector *
         479            4439 : GlobalObject::getOrCreateDebuggers(JSContext *cx)
         480                 : {
         481            4439 :     assertSameCompartment(cx, this);
         482            4439 :     DebuggerVector *debuggers = getDebuggers();
         483            4439 :     if (debuggers)
         484            1107 :         return debuggers;
         485                 :
         486            3332 :     JSObject *obj = NewObjectWithGivenProto(cx, &GlobalDebuggees_class, NULL, this);
         487            3332 :     if (!obj)
         488               0 :         return NULL;
         489            3332 :     debuggers = cx->new_<DebuggerVector>();
         490            3332 :     if (!debuggers)
         491               0 :         return NULL;
         492            3332 :     obj->setPrivate(debuggers);
         493            3332 :     setReservedSlot(DEBUGGERS, ObjectValue(*obj));
         494            3332 :     return debuggers;
         495                 : }
         496                 :
         497                 : bool
         498               0 : GlobalObject::addDebugger(JSContext *cx, Debugger *dbg)
         499                 : {
         500               0 :     DebuggerVector *debuggers = getOrCreateDebuggers(cx);
         501               0 :     if (!debuggers)
         502               0 :         return false;
         503                 : #ifdef DEBUG
         504               0 :     for (Debugger **p = debuggers->begin(); p != debuggers->end(); p++)
         505               0 :         JS_ASSERT(*p != dbg);
         506                 : #endif
         507               0 :     if (debuggers->empty() && !compartment()->addDebuggee(cx, this))
         508               0 :         return false;
         509               0 :     if (!debuggers->append(dbg)) {
         510               0 :         compartment()->removeDebuggee(cx->runtime->defaultFreeOp(), this);
         511               0 :         return false;
         512                 :     }
         513               0 :     return true;
         514                 : }
         515                 :
         516                 : } // namespace js

Generated by: LCOV version 1.7