void JSD_ASSERT_VALID_VALUE(JSDValue* jsdval) { JS_ASSERT(jsdval); JS_ASSERT(jsdval->nref > 0); if(!JS_CLIST_IS_EMPTY(&jsdval->props)) { JS_ASSERT(CHECK_BIT_FLAG(jsdval->flags, GOT_PROPS)); JS_ASSERT(!JSVAL_IS_PRIMITIVE(jsdval->val)); } if(jsdval->proto) { JS_ASSERT(CHECK_BIT_FLAG(jsdval->flags, GOT_PROTO)); JS_ASSERT(jsdval->proto->nref > 0); } if(jsdval->parent) { JS_ASSERT(CHECK_BIT_FLAG(jsdval->flags, GOT_PARENT)); JS_ASSERT(jsdval->parent->nref > 0); } if(jsdval->ctor) { JS_ASSERT(CHECK_BIT_FLAG(jsdval->flags, GOT_CTOR)); JS_ASSERT(jsdval->ctor->nref > 0); } }
void jsd_DestroyObjects(JSDContext* jsdc) { JSD_LOCK_OBJECTS(jsdc); while( !JS_CLIST_IS_EMPTY(&jsdc->objectsList) ) _destroyJSDObject(jsdc, (JSDObject*)JS_NEXT_LINK(&jsdc->objectsList)); JSD_UNLOCK_OBJECTS(jsdc); }
static JSBool _buildProps(JSDContext* jsdc, JSDValue* jsdval) { JSContext* cx = jsdc->dumbContext; JS::RootedObject obj(cx); JSPropertyDescArray pda; unsigned i; JSCompartment* oldCompartment = NULL; JS_ASSERT(JS_CLIST_IS_EMPTY(&jsdval->props)); JS_ASSERT(!(CHECK_BIT_FLAG(jsdval->flags, GOT_PROPS))); JS_ASSERT(!JSVAL_IS_PRIMITIVE(jsdval->val)); if(JSVAL_IS_PRIMITIVE(jsdval->val)) return JS_FALSE; obj = JSVAL_TO_OBJECT(jsdval->val); JS_BeginRequest(cx); oldCompartment = JS_EnterCompartment(jsdc->dumbContext, obj); if(!JS_GetPropertyDescArray(cx, obj, &pda)) { JS_EndRequest(cx); JS_LeaveCompartment(jsdc->dumbContext, oldCompartment); return JS_FALSE; } for(i = 0; i < pda.length; i++) { JSDProperty* prop = _newProperty(jsdc, &pda.array[i], 0); if(!prop) { _freeProps(jsdc, jsdval); break; } JS_APPEND_LINK(&prop->links, &jsdval->props); } JS_PutPropertyDescArray(cx, &pda); JS_LeaveCompartment(jsdc->dumbContext, oldCompartment); JS_EndRequest(cx); SET_BIT_FLAG(jsdval->flags, GOT_PROPS); return !JS_CLIST_IS_EMPTY(&jsdval->props); }
/* * Callback function to delete a JSThread info when the thread that owns it * is destroyed. */ void JS_DLL_CALLBACK js_ThreadDestructorCB(void *ptr) { JSThread *thread = (JSThread *)ptr; if (!thread) return; while (!JS_CLIST_IS_EMPTY(&thread->contextList)) JS_REMOVE_AND_INIT_LINK(thread->contextList.next); free(thread); }
void jsd_DropProperty(JSDContext* jsdc, JSDProperty* jsdprop) { JS_ASSERT(jsdprop->nref > 0); if(0 == --jsdprop->nref) { JS_ASSERT(JS_CLIST_IS_EMPTY(&jsdprop->links)); DROP_CLEAR_VALUE(jsdc, jsdprop->val); DROP_CLEAR_VALUE(jsdc, jsdprop->name); DROP_CLEAR_VALUE(jsdc, jsdprop->alias); free(jsdprop); } }
static void _freeProps(JSDContext* jsdc, JSDValue* jsdval) { JSDProperty* jsdprop; while(jsdprop = (JSDProperty*)jsdval->props.next, jsdprop != (JSDProperty*)&jsdval->props) { JS_REMOVE_AND_INIT_LINK(&jsdprop->links); jsd_DropProperty(jsdc, jsdprop); } JS_ASSERT(JS_CLIST_IS_EMPTY(&jsdval->props)); CLEAR_BIT_FLAG(jsdval->flags, GOT_PROPS); }
/* * Callback function to delete a JSThread info when the thread that owns it * is destroyed. */ void JS_DLL_CALLBACK js_ThreadDestructorCB(void *ptr) { JSThread *thread = (JSThread *)ptr; if (!thread) return; /* * Check that this thread properly called either JS_DestroyContext or * JS_ClearContextThread on each JSContext it created or used. */ JS_ASSERT(JS_CLIST_IS_EMPTY(&thread->contextList)); GSN_CACHE_CLEAR(&thread->gsnCache); free(thread); }
/* Remove the owning thread info of a context. */ void js_ClearContextThread(JSContext *cx) { /* * If cx is associated with a thread, this must be called only from that * thread. If not, this is a harmless no-op. */ JS_ASSERT(cx->thread == js_GetCurrentThread(cx->runtime) || !cx->thread); JS_REMOVE_AND_INIT_LINK(&cx->threadLinks); #ifdef DEBUG if (JS_CLIST_IS_EMPTY(&cx->thread->contextList)) { memset(cx->thread->gcFreeLists, JS_FREE_PATTERN, sizeof(cx->thread->gcFreeLists)); } #endif cx->thread = NULL; }
/* * Sets current thread as owning thread of a context by assigning the * thread-private info to the context. If the current thread doesn't have * private JSThread info, create one. */ JSBool js_SetContextThread(JSContext *cx) { JSThread *thread = js_GetCurrentThread(cx->runtime); if (!thread) { JS_ReportOutOfMemory(cx); return JS_FALSE; } /* * Clear gcFreeLists on each transition from 0 to 1 context active on the * current thread. See bug 351602. */ if (JS_CLIST_IS_EMPTY(&thread->contextList)) memset(thread->gcFreeLists, 0, sizeof(thread->gcFreeLists)); /* Assert that the previous cx->thread called JS_ClearContextThread(). */ JS_ASSERT(!cx->thread || cx->thread == thread); if (!cx->thread) JS_APPEND_LINK(&cx->threadLinks, &thread->contextList); cx->thread = thread; return JS_TRUE; }
void JSD_ASSERT_VALID_OBJECT(JSDObject* jsdobj) { JS_ASSERT(jsdobj); JS_ASSERT(!JS_CLIST_IS_EMPTY(&jsdobj->links)); JS_ASSERT(jsdobj->obj); }