/[jscoverage]/trunk/js/jsscript.cpp
ViewVC logotype

Diff of /trunk/js/jsscript.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 459 by siliconforks, Tue Dec 9 03:37:47 2008 UTC revision 460 by siliconforks, Sat Sep 26 23:15:22 2009 UTC
# Line 60  Line 60 
60  #include "jsparse.h"  #include "jsparse.h"
61  #include "jsscope.h"  #include "jsscope.h"
62  #include "jsscript.h"  #include "jsscript.h"
63    #include "jstracer.h"
64  #if JS_HAS_XDR  #if JS_HAS_XDR
65  #include "jsxdrapi.h"  #include "jsxdrapi.h"
66  #endif  #endif
# Line 230  Line 231 
231      }      }
232    
233      /* Compile using the caller's scope chain, which js_Invoke passes to fp. */      /* Compile using the caller's scope chain, which js_Invoke passes to fp. */
234      caller = JS_GetScriptedCaller(cx, cx->fp);      caller = js_GetScriptedCaller(cx, NULL);
235      JS_ASSERT(!caller || cx->fp->scopeChain == caller->scopeChain);      JS_ASSERT(!caller || cx->fp->scopeChain == caller->scopeChain);
236    
237      if (caller) {      if (caller) {
# Line 262  Line 263 
263       * jsparse.c to optimize based on identity of run- and compile-time scope.       * jsparse.c to optimize based on identity of run- and compile-time scope.
264       */       */
265      tcflags = 0;      tcflags = 0;
266      script = js_CompileScript(cx, scopeobj, NULL, principals, tcflags,      script = JSCompiler::compileScript(cx, scopeobj, NULL, principals, tcflags,
267                                JSSTRING_CHARS(str), JSSTRING_LENGTH(str),                                         JSSTRING_CHARS(str), JSSTRING_LENGTH(str),
268                                NULL, file, line);                                         NULL, file, line);
269      if (!script)      if (!script)
270          return JS_FALSE;          return JS_FALSE;
271    
# Line 310  Line 311 
311  script_exec_sub(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,  script_exec_sub(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
312                  jsval *rval)                  jsval *rval)
313  {  {
314      JSObject *scopeobj, *parent;      JSObject *scopeobj;
315      JSStackFrame *fp, *caller;      JSStackFrame *caller;
316      JSPrincipals *principals;      JSPrincipals *principals;
317      JSScript *script;      JSScript *script;
318      JSBool ok;      JSBool ok;
# Line 338  Line 339 
339       * a lightweight function, we will need to get a Call object representing       * a lightweight function, we will need to get a Call object representing
340       * its frame, to act as the var object and scope chain head.       * its frame, to act as the var object and scope chain head.
341       */       */
342      fp = cx->fp;      caller = js_GetScriptedCaller(cx, NULL);
     caller = JS_GetScriptedCaller(cx, fp);  
343      if (caller && !caller->varobj) {      if (caller && !caller->varobj) {
344          /* Called from a lightweight function. */          /* Called from a lightweight function. */
345          JS_ASSERT(caller->fun && !JSFUN_HEAVYWEIGHT_TEST(caller->fun->flags));          JS_ASSERT(caller->fun && !JSFUN_HEAVYWEIGHT_TEST(caller->fun->flags));
346    
347          /* Scope chain links from Call object to callee's parent. */          /* Scope chain links from Call object to caller's scope chain. */
348          parent = OBJ_GET_PARENT(cx, caller->callee);          if (!js_GetCallObject(cx, caller))
         if (!js_GetCallObject(cx, caller, parent))  
349              return JS_FALSE;              return JS_FALSE;
350      }      }
351    
# Line 363  Line 362 
362          } else {          } else {
363              /*              /*
364               * Called from native code, so we don't know what scope object to               * Called from native code, so we don't know what scope object to
365               * use.  We could use parent (see above), but Script.prototype.exec               * use.  We could use the caller's scope chain (see above), but Script.prototype.exec
366               * might be a shared/sealed "superglobal" method.  A more general               * might be a shared/sealed "superglobal" method.  A more general
367               * approach would use cx->globalObject, which will be the same as               * approach would use cx->globalObject, which will be the same as
368               * exec.__parent__ in the non-superglobal case.  In the superglobal               * exec.__parent__ in the non-superglobal case.  In the superglobal
# Line 458  Line 457 
457          version = (uint32)script->version | (script->nfixed << 16);          version = (uint32)script->version | (script->nfixed << 16);
458          lineno = (uint32)script->lineno;          lineno = (uint32)script->lineno;
459          nslots = (uint32)script->nslots;          nslots = (uint32)script->nslots;
460          nslots = (uint32)((script->staticDepth << 16) | script->nslots);          nslots = (uint32)((script->staticLevel << 16) | script->nslots);
461          natoms = (uint32)script->atomMap.length;          natoms = (uint32)script->atomMap.length;
462    
463          /* Count the srcnotes, keeping notes pointing at the first one. */          /* Count the srcnotes, keeping notes pointing at the first one. */
# Line 509  Line 508 
508              return JS_FALSE;              return JS_FALSE;
509    
510          script->main += prologLength;          script->main += prologLength;
511          script->version = (JSVersion) (version & 0xffff);          script->version = JSVersion(version & 0xffff);
512          script->nfixed = (uint16) (version >> 16);          script->nfixed = uint16(version >> 16);
513    
514          /* If we know nsrcnotes, we allocated space for notes in script. */          /* If we know nsrcnotes, we allocated space for notes in script. */
515          notes = SCRIPT_NOTES(script);          notes = SCRIPT_NOTES(script);
# Line 583  Line 582 
582          }          }
583          script->lineno = (uintN)lineno;          script->lineno = (uintN)lineno;
584          script->nslots = (uint16)nslots;          script->nslots = (uint16)nslots;
585          script->staticDepth = nslots >> 16;          script->staticLevel = (uint16)(nslots >> 16);
586      }      }
587    
588      for (i = 0; i != natoms; ++i) {      for (i = 0; i != natoms; ++i) {
# Line 594  Line 593 
593      /*      /*
594       * Here looping from 0-to-length to xdr objects is essential. It ensures       * Here looping from 0-to-length to xdr objects is essential. It ensures
595       * that block objects from the script->objects array will be written and       * that block objects from the script->objects array will be written and
596       * restored in the outer-to-inner order. block_xdrObject relies on this to       * restored in the outer-to-inner order. js_XDRBlockObject relies on this
597       * restore the parent chain.       * to restore the parent chain.
598       */       */
599      for (i = 0; i != nobjects; ++i) {      for (i = 0; i != nobjects; ++i) {
600          if (!js_XDRObject(xdr, &JS_SCRIPT_OBJECTS(script)->vector[i]))          JSObject **objp = &JS_SCRIPT_OBJECTS(script)->vector[i];
601            uint32 isBlock;
602            if (xdr->mode == JSXDR_ENCODE) {
603                JSClass *clasp = STOBJ_GET_CLASS(*objp);
604                JS_ASSERT(clasp == &js_FunctionClass ||
605                          clasp == &js_BlockClass);
606                isBlock = (clasp == &js_BlockClass) ? 1 : 0;
607             }
608            if (!JS_XDRUint32(xdr, &isBlock))
609              goto error;              goto error;
610            if (isBlock == 0) {
611                if (!js_XDRFunctionObject(xdr, objp))
612                    goto error;
613            } else {
614                JS_ASSERT(isBlock == 1);
615                if (!js_XDRBlockObject(xdr, objp))
616                    goto error;
617            }
618      }      }
619      for (i = 0; i != nupvars; ++i) {      for (i = 0; i != nupvars; ++i) {
620          if (!JS_XDRUint32(xdr, &JS_SCRIPT_UPVARS(script)->vector[i]))          if (!JS_XDRUint32(xdr, &JS_SCRIPT_UPVARS(script)->vector[i]))
621              goto error;              goto error;
622      }      }
623      for (i = 0; i != nregexps; ++i) {      for (i = 0; i != nregexps; ++i) {
624          if (!js_XDRObject(xdr, &JS_SCRIPT_REGEXPS(script)->vector[i]))          if (!js_XDRRegExpObject(xdr, &JS_SCRIPT_REGEXPS(script)->vector[i]))
625              goto error;              goto error;
626      }      }
627    
# Line 903  Line 918 
918  Script(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)  Script(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
919  {  {
920      /* If not constructing, replace obj with a new Script object. */      /* If not constructing, replace obj with a new Script object. */
921      if (!(cx->fp->flags & JSFRAME_CONSTRUCTING)) {      if (!JS_IsConstructing(cx)) {
922          obj = js_NewObject(cx, &js_ScriptClass, NULL, NULL, 0);          obj = js_NewObject(cx, &js_ScriptClass, NULL, NULL, 0);
923          if (!obj)          if (!obj)
924              return JS_FALSE;              return JS_FALSE;
# Line 984  Line 999 
999  }  }
1000    
1001  static void  static void
1002  js_free_table_space(void *priv, void *item)  js_free_table_space(void *priv, void *item, size_t size)
1003  {  {
1004      free(item);      free(item);
1005  }  }
# Line 1146  Line 1161 
1161          sfp->flags |= flags;          sfp->flags |= flags;
1162      }      }
1163    
1164    #ifdef JS_FUNCTION_METERING
1165        size_t len = strlen(sfe->filename);
1166        if (len >= sizeof rt->lastScriptFilename)
1167            len = sizeof rt->lastScriptFilename - 1;
1168        memcpy(rt->lastScriptFilename, sfe->filename, len);
1169        rt->lastScriptFilename[len] = '\0';
1170    #endif
1171    
1172      return sfe;      return sfe;
1173  }  }
1174    
# Line 1472  Line 1495 
1495      script->main += prologLength;      script->main += prologLength;
1496      memcpy(script->code, CG_PROLOG_BASE(cg), prologLength * sizeof(jsbytecode));      memcpy(script->code, CG_PROLOG_BASE(cg), prologLength * sizeof(jsbytecode));
1497      memcpy(script->main, CG_BASE(cg), mainLength * sizeof(jsbytecode));      memcpy(script->main, CG_BASE(cg), mainLength * sizeof(jsbytecode));
1498      nfixed = (cg->treeContext.flags & TCF_IN_FUNCTION)      nfixed = (cg->flags & TCF_IN_FUNCTION)
1499               ? cg->treeContext.u.fun->u.i.nvars               ? cg->fun->u.i.nvars
1500               : cg->treeContext.ngvars + cg->regexpList.length;               : cg->ngvars + cg->regexpList.length;
1501      JS_ASSERT(nfixed < SLOTNO_LIMIT);      JS_ASSERT(nfixed < SLOTNO_LIMIT);
1502      script->nfixed = (uint16) nfixed;      script->nfixed = (uint16) nfixed;
1503      js_InitAtomMap(cx, &script->atomMap, &cg->atomList);      js_InitAtomMap(cx, &script->atomMap, &cg->atomList);
1504    
1505      filename = cg->treeContext.parseContext->tokenStream.filename;      filename = cg->compiler->tokenStream.filename;
1506      if (filename) {      if (filename) {
1507          script->filename = js_SaveScriptFilename(cx, filename);          script->filename = js_SaveScriptFilename(cx, filename);
1508          if (!script->filename)          if (!script->filename)
# Line 1492  Line 1515 
1515          goto bad;          goto bad;
1516      }      }
1517      script->nslots = script->nfixed + cg->maxStackDepth;      script->nslots = script->nfixed + cg->maxStackDepth;
1518      script->staticDepth = cg->staticDepth;      script->staticLevel = cg->staticLevel;
1519      script->principals = cg->treeContext.parseContext->principals;      script->principals = cg->compiler->principals;
1520      if (script->principals)      if (script->principals)
1521          JSPRINCIPALS_HOLD(cx, script->principals);          JSPRINCIPALS_HOLD(cx, script->principals);
1522    
# Line 1502  Line 1525 
1525      if (cg->ntrynotes != 0)      if (cg->ntrynotes != 0)
1526          js_FinishTakingTryNotes(cg, JS_SCRIPT_TRYNOTES(script));          js_FinishTakingTryNotes(cg, JS_SCRIPT_TRYNOTES(script));
1527      if (cg->objectList.length != 0)      if (cg->objectList.length != 0)
1528          FinishParsedObjects(&cg->objectList, JS_SCRIPT_OBJECTS(script));          cg->objectList.finish(JS_SCRIPT_OBJECTS(script));
1529      if (cg->regexpList.length != 0)      if (cg->regexpList.length != 0)
1530          FinishParsedObjects(&cg->regexpList, JS_SCRIPT_REGEXPS(script));          cg->regexpList.finish(JS_SCRIPT_REGEXPS(script));
1531      if (cg->treeContext.flags & TCF_NO_SCRIPT_RVAL)      if (cg->flags & TCF_NO_SCRIPT_RVAL)
1532          script->flags |= JSSF_NO_SCRIPT_RVAL;          script->flags |= JSSF_NO_SCRIPT_RVAL;
1533    
1534      if (cg->upvarList.count != 0) {      if (cg->upvarList.count != 0) {
1535          JS_ASSERT(cg->upvarList.count <= cg->upvarMap.length);          JS_ASSERT(cg->upvarList.count <= cg->upvarMap.length);
1536          memcpy(JS_SCRIPT_UPVARS(script)->vector, cg->upvarMap.vector,          memcpy(JS_SCRIPT_UPVARS(script)->vector, cg->upvarMap.vector,
1537                 cg->upvarList.count * sizeof(uint32));                 cg->upvarList.count * sizeof(uint32));
1538          ATOM_LIST_INIT(&cg->upvarList);          cg->upvarList.clear();
1539          JS_free(cx, cg->upvarMap.vector);          JS_free(cx, cg->upvarMap.vector);
1540          cg->upvarMap.vector = NULL;          cg->upvarMap.vector = NULL;
1541      }      }
# Line 1522  Line 1545 
1545       * so that the debugger has a valid FUN_SCRIPT(fun).       * so that the debugger has a valid FUN_SCRIPT(fun).
1546       */       */
1547      fun = NULL;      fun = NULL;
1548      if (cg->treeContext.flags & TCF_IN_FUNCTION) {      if (cg->flags & TCF_IN_FUNCTION) {
1549          fun = cg->treeContext.u.fun;          fun = cg->fun;
1550          JS_ASSERT(FUN_INTERPRETED(fun) && !FUN_SCRIPT(fun));          JS_ASSERT(FUN_INTERPRETED(fun) && !FUN_SCRIPT(fun));
1551          JS_ASSERT_IF(script->upvarsOffset != 0,          JS_ASSERT_IF(script->upvarsOffset != 0,
1552                       JS_SCRIPT_UPVARS(script)->length == fun->u.i.nupvars);                       JS_SCRIPT_UPVARS(script)->length == fun->u.i.nupvars);
# Line 1533  Line 1556 
1556  #ifdef CHECK_SCRIPT_OWNER  #ifdef CHECK_SCRIPT_OWNER
1557          script->owner = NULL;          script->owner = NULL;
1558  #endif  #endif
1559          if (cg->treeContext.flags & TCF_FUN_HEAVYWEIGHT)          if (cg->flags & TCF_FUN_HEAVYWEIGHT)
1560              fun->flags |= JSFUN_HEAVYWEIGHT;              fun->flags |= JSFUN_HEAVYWEIGHT;
1561      }      }
1562    
# Line 1580  Line 1603 
1603          JSPRINCIPALS_DROP(cx, script->principals);          JSPRINCIPALS_DROP(cx, script->principals);
1604    
1605      if (JS_GSN_CACHE(cx).code == script->code)      if (JS_GSN_CACHE(cx).code == script->code)
1606          JS_CLEAR_GSN_CACHE(cx);          JS_PURGE_GSN_CACHE(cx);
1607    
1608      /*      /*
1609       * The GC flushes all property caches, so no need to purge just the       * The GC flushes all property caches, so no need to purge just the
1610       * entries for this script.       * entries for this script.
1611       *       *
1612       * JS_THREADSAFE note: js_FlushPropertyCacheForScript flushes only the       * JS_THREADSAFE note: js_PurgePropertyCacheForScript purges only the
1613       * current thread's property cache, so a script not owned by a function       * current thread's property cache, so a script not owned by a function
1614       * or object, which hands off lifetime management for that script to the       * or object, which hands off lifetime management for that script to the
1615       * GC, must be used by only one thread over its lifetime.       * GC, must be used by only one thread over its lifetime.
# Line 1601  Line 1624 
1624  #endif  #endif
1625    
1626      if (!cx->runtime->gcRunning) {      if (!cx->runtime->gcRunning) {
1627          if (!(cx->fp && (cx->fp->flags & JSFRAME_EVAL))) {          JSStackFrame *fp = js_GetTopStackFrame(cx);
1628    
1629            if (!(fp && (fp->flags & JSFRAME_EVAL))) {
1630  #ifdef CHECK_SCRIPT_OWNER  #ifdef CHECK_SCRIPT_OWNER
1631              JS_ASSERT(script->owner == cx->thread);              JS_ASSERT(script->owner == cx->thread);
1632  #endif  #endif
1633              js_FlushPropertyCacheForScript(cx, script);              js_PurgePropertyCacheForScript(cx, script);
1634    #ifdef JS_TRACER
1635                js_PurgeScriptFragments(cx, script);
1636    #endif
1637          }          }
1638      }      }
1639    
# Line 1673  Line 1701 
1701    
1702  #define GSN_CACHE_THRESHOLD     100  #define GSN_CACHE_THRESHOLD     100
1703    
1704    void
1705    js_PurgeGSNCache(JSGSNCache *cache)
1706    {
1707        cache->code = NULL;
1708        if (cache->table.ops) {
1709            JS_DHashTableFinish(&cache->table);
1710            cache->table.ops = NULL;
1711        }
1712        GSN_CACHE_METER(cache, purges);
1713    }
1714    
1715  jssrcnote *  jssrcnote *
1716  js_GetSrcNoteCached(JSContext *cx, JSScript *script, jsbytecode *pc)  js_GetSrcNoteCached(JSContext *cx, JSScript *script, jsbytecode *pc)
1717  {  {
# Line 1710  Line 1749 
1749    
1750      if (JS_GSN_CACHE(cx).code != script->code &&      if (JS_GSN_CACHE(cx).code != script->code &&
1751          script->length >= GSN_CACHE_THRESHOLD) {          script->length >= GSN_CACHE_THRESHOLD) {
1752          JS_CLEAR_GSN_CACHE(cx);          JS_PURGE_GSN_CACHE(cx);
1753          nsrcnotes = 0;          nsrcnotes = 0;
1754          for (sn = SCRIPT_NOTES(script); !SN_IS_TERMINATOR(sn);          for (sn = SCRIPT_NOTES(script); !SN_IS_TERMINATOR(sn);
1755               sn = SN_NEXT(sn)) {               sn = SN_NEXT(sn)) {
# Line 1751  Line 1790 
1790  uintN  uintN
1791  js_PCToLineNumber(JSContext *cx, JSScript *script, jsbytecode *pc)  js_PCToLineNumber(JSContext *cx, JSScript *script, jsbytecode *pc)
1792  {  {
1793        JSOp op;
1794      JSFunction *fun;      JSFunction *fun;
1795      uintN lineno;      uintN lineno;
1796      ptrdiff_t offset, target;      ptrdiff_t offset, target;
# Line 1765  Line 1805 
1805       * Special case: function definition needs no line number note because       * Special case: function definition needs no line number note because
1806       * the function's script contains its starting line number.       * the function's script contains its starting line number.
1807       */       */
1808      if (js_CodeSpec[*pc].format & JOF_INDEXBASE)      op = js_GetOpcode(cx, script, pc);
1809          pc += js_CodeSpec[*pc].length;      if (js_CodeSpec[op].format & JOF_INDEXBASE)
1810            pc += js_CodeSpec[op].length;
1811      if (*pc == JSOP_DEFFUN) {      if (*pc == JSOP_DEFFUN) {
1812          GET_FUNCTION_FROM_BYTECODE(script, pc, 0, fun);          GET_FUNCTION_FROM_BYTECODE(script, pc, 0, fun);
1813          return fun->u.i.script->lineno;          return fun->u.i.script->lineno;

Legend:
Removed from v.459  
changed lines
  Added in v.460

  ViewVC Help
Powered by ViewVC 1.1.24