Subj : Help with scoping within the JSAPI To : netscape.public.mozilla.jseng From : alipman2@yahoo.com Date : Fri May 27 2005 01:44 pm I am writing an application where I need 3 levels of scoping. 1. Application Scope 2. Global Scope 3. Local Scope Currently, I have 2 levels of scoping working I use the Global Object for scope 1, and then I push a stack frame with my own varobj for scope 2. //////////////////////////////////////////////// At the beginning of execution I create my own Frame. //////////////////////////////////////////////// JSStackFrame *m_fp; JSStackFrame m_Frame; memset( (void *)&m_Frame,0 ,sizeof( m_Frame)); m_Frame.varobj = m_glob; m_Frame.fun = NULL; m_Frame.thisp = m_glob; m_Frame.argc = m_Frame.nvars = 0; m_Frame.argv = m_Frame.vars = NULL; m_Frame.annotation = NULL; m_Frame.sharpArray = NULL; m_Frame.rval = JSVAL_VOID; m_Frame.down = NULL; m_Frame.scopeChain = m_glob; m_Frame.pc = NULL; m_Frame.sp = NULL; m_Frame.spbase = NULL; m_Frame.sharpDepth = 0; m_Frame.flags = 0; m_Frame.dormantNext = NULL; m_Frame.objAtomMap = NULL; m_fp=&m_Frame; //////////////////////////////////////////////// I use the following code to execute code using this frame. //////////////////////////////////////////////// if (!js_Execute(m_cx, m_fp->scopeChain, m_ExecutingScript, m_fp, 0, &ScriptResult)) { #if JS_HAS_EXCEPTIONS js_ReportUncaughtException(m_cx); #endif ok = JS_FALSE; } else { ok = JS_TRUE; } //////////////////////////////////////////////// I use the following code to push a stack frame to go to scope 2. I adapted this code from the code that pushes on a stack frame before a function is called. m_ScopeLevel is a global variable //////////////////////////////////////////////// uintN nframeslots; void *newmark; JSInlineFrame *newifp; jsval *sp, *newsp; JSStackFrame *fp; jsval *vp; if ( m_ScopeLevel > 0 ) { m_ErrorMessage ="Push has already been executed"; return false; } fp = NULL; /* Compute the number of stack slots needed for fun. */ nframeslots = (sizeof(JSInlineFrame) + sizeof(jsval) - 1) / sizeof(jsval); /* Allocate the frame and space for vars and operands. */ newsp = js_AllocRawStack(m_cx, nframeslots , &newmark); if (!newsp) { m_ErrorMessage = "js_AllocRawStack failed"; return false; } newifp = (JSInlineFrame *) newsp; newsp += nframeslots; vp = sp - 2; JSObject *varobj; varobj = JS_NewObject(m_cx, &global_class, NULL, NULL); if (!varobj) { m_ErrorMessage="Couldn't create variables object"; return false; if ( JS_AddRoot(m_cx, varobj) ) { m_ErrorMessage="Can't root scope object"; return false; } } JS_SetGlobalObject(m_cx, varobj); if (!JS_InitStandardClasses(m_cx, varobj)) { m_ErrorMessage="Initialization Error, Can't Init Standard Classes"; return false; } /* Initialize the stack frame. */ memset(newifp, 0, sizeof(JSInlineFrame)); newifp->frame.rval = JSVAL_VOID; newifp->frame.nvars = 0; newifp->frame.vars = newsp; newifp->frame.argv = vp + 2; newifp->frame.scopeChain = varobj; newifp->mark = newmark; newifp->frame.down = m_fp; newifp->frame.argsobj=NULL; newifp->frame.varobj = varobj; /* Push void to initialize local variables. */ sp = newsp; newifp->frame.spbase = sp; SAVE_SP(&newifp->frame); m_fp = &newifp->frame; m_ScopeLevel++; return true; ///////////////////////////////////////////////// I use the following code to pop the stack frame //////////////////////////////////////////////// JSStackFrame *fp; JSInlineFrame *ifp = (JSInlineFrame *) m_fp; jsval *vp; jsval *sp; if ( m_ScopeLevel == 0 ) { m_ErrorMessage="PopScope called with no corresponding PushScope"; return false; } /* Restore cx->fp and release the inline frame's space. */ fp = m_fp; if ( !JS_RemoveRoot(m_cx, fp->varobj)){ m_ErrorMessage="Couldn't not remove scope object from root"; } sp = fp->spbase; m_cx->fp = fp = fp->down; m_fp = fp; JS_ARENA_RELEASE(&m_cx->stackPool, ifp->mark); if ( fp ) { vp = fp->argv - 2; fp->sp = vp + 1; RESTORE_SP(fp); } m_ScopeLevel--; return true; } //////////////////////////////////////////////// If I want to push another level of stack frame, what do I set in the new frame that I create? .