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

Diff of /trunk/js/jsopcode.cpp

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

revision 460 by siliconforks, Sat Sep 26 23:15:22 2009 UTC revision 507 by siliconforks, Sun Jan 10 07:23:34 2010 UTC
# Line 1  Line 1 
1  /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-  /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2   * vim: set sw=4 ts=8 et tw=99:   * vim: set sw=4 ts=8 et tw=99:
3   *   *
4   * ***** BEGIN LICENSE BLOCK *****   * ***** BEGIN LICENSE BLOCK *****
# Line 41  Line 41 
41  /*  /*
42   * JS bytecode descriptors, disassemblers, and decompilers.   * JS bytecode descriptors, disassemblers, and decompilers.
43   */   */
 #include "jsstddef.h"  
44  #ifdef HAVE_MEMORY_H  #ifdef HAVE_MEMORY_H
45  #include <memory.h>  #include <memory.h>
46  #endif  #endif
# Line 50  Line 49 
49  #include <stdlib.h>  #include <stdlib.h>
50  #include <string.h>  #include <string.h>
51  #include "jstypes.h"  #include "jstypes.h"
52    #include "jsstdint.h"
53  #include "jsarena.h" /* Added by JSIFY */  #include "jsarena.h" /* Added by JSIFY */
54  #include "jsutil.h" /* Added by JSIFY */  #include "jsutil.h" /* Added by JSIFY */
55  #include "jsdtoa.h"  #include "jsdtoa.h"
# Line 73  Line 73 
73  #include "jsstr.h"  #include "jsstr.h"
74  #include "jsstaticcheck.h"  #include "jsstaticcheck.h"
75  #include "jstracer.h"  #include "jstracer.h"
76    #include "jsvector.h"
77    
78    #include "jsscriptinlines.h"
79    
80  #include "jsautooplen.h"  #include "jsautooplen.h"
81    
# Line 209  Line 212 
212      switch (op) {      switch (op) {
213        case JSOP_POPN:        case JSOP_POPN:
214          return GET_UINT16(pc);          return GET_UINT16(pc);
215          case JSOP_CONCATN:
216            return GET_UINT16(pc);
217        case JSOP_LEAVEBLOCK:        case JSOP_LEAVEBLOCK:
218          return GET_UINT16(pc);          return GET_UINT16(pc);
219        case JSOP_LEAVEBLOCKEXPR:        case JSOP_LEAVEBLOCKEXPR:
# Line 248  Line 253 
253          if (pc == script->main)          if (pc == script->main)
254              fputs("main:\n", fp);              fputs("main:\n", fp);
255          len = js_Disassemble1(cx, script, pc,          len = js_Disassemble1(cx, script, pc,
256                                PTRDIFF(pc, script->code, jsbytecode),                                pc - script->code,
257                                lines, fp);                                lines, fp);
258          if (!len)          if (!len)
259              return JS_FALSE;              return JS_FALSE;
# Line 257  Line 262 
262      return JS_TRUE;      return JS_TRUE;
263  }  }
264    
265    JSBool
266    js_DumpScript(JSContext *cx, JSScript *script)
267    {
268        return js_Disassemble(cx, script, true, stdout);
269    }
270    
271  const char *  const char *
272  ToDisassemblySource(JSContext *cx, jsval v)  ToDisassemblySource(JSContext *cx, jsval v)
273  {  {
# Line 356  Line 367 
367        case JOF_REGEXP:        case JOF_REGEXP:
368          index = js_GetIndexFromBytecode(cx, script, pc, 0);          index = js_GetIndexFromBytecode(cx, script, pc, 0);
369          if (type == JOF_ATOM) {          if (type == JOF_ATOM) {
370              JS_GET_SCRIPT_ATOM(script, index, atom);              JS_GET_SCRIPT_ATOM(script, pc, index, atom);
371              v = ATOM_KEY(atom);              v = ATOM_KEY(atom);
372          } else {          } else {
373              if (type == JOF_OBJECT)              if (type == JOF_OBJECT)
374                  JS_GET_SCRIPT_OBJECT(script, index, obj);                  obj = script->getObject(index);
375              else              else
376                  JS_GET_SCRIPT_REGEXP(script, index, obj);                  obj = script->getRegExp(index);
377              v = OBJECT_TO_JSVAL(obj);              v = OBJECT_TO_JSVAL(obj);
378          }          }
379          bytes = ToDisassemblySource(cx, v);          bytes = ToDisassemblySource(cx, v);
# Line 415  Line 426 
426          pc2 += UINT16_LEN;          pc2 += UINT16_LEN;
427          fprintf(fp, " offset %d npairs %u", (intN) off, (uintN) npairs);          fprintf(fp, " offset %d npairs %u", (intN) off, (uintN) npairs);
428          while (npairs) {          while (npairs) {
429              JS_GET_SCRIPT_ATOM(script, GET_INDEX(pc2), atom);              JS_GET_SCRIPT_ATOM(script, pc, GET_INDEX(pc2), atom);
430              pc2 += INDEX_LEN;              pc2 += INDEX_LEN;
431              off = GetJumpOffset(pc, pc2);              off = GetJumpOffset(pc, pc2);
432              pc2 += jmplen;              pc2 += jmplen;
# Line 443  Line 454 
454          fprintf(fp, " %u", GET_SLOTNO(pc));          fprintf(fp, " %u", GET_SLOTNO(pc));
455          index = js_GetIndexFromBytecode(cx, script, pc, SLOTNO_LEN);          index = js_GetIndexFromBytecode(cx, script, pc, SLOTNO_LEN);
456          if (type == JOF_SLOTATOM) {          if (type == JOF_SLOTATOM) {
457              JS_GET_SCRIPT_ATOM(script, index, atom);              JS_GET_SCRIPT_ATOM(script, pc, index, atom);
458              v = ATOM_KEY(atom);              v = ATOM_KEY(atom);
459          } else {          } else {
460              JS_GET_SCRIPT_OBJECT(script, index, obj);              obj = script->getObject(index);
461              v = OBJECT_TO_JSVAL(obj);              v = OBJECT_TO_JSVAL(obj);
462          }          }
463          bytes = ToDisassemblySource(cx, v);          bytes = ToDisassemblySource(cx, v);
# Line 562  Line 573 
573  static ptrdiff_t  static ptrdiff_t
574  SprintString(Sprinter *sp, JSString *str)  SprintString(Sprinter *sp, JSString *str)
575  {  {
576      jschar *chars;      const jschar *chars;
577      size_t length, size;      size_t length, size;
578      ptrdiff_t offset;      ptrdiff_t offset;
579    
580      JSSTRING_CHARS_AND_LENGTH(str, chars, length);      str->getCharsAndLength(chars, length);
581      if (length == 0)      if (length == 0)
582          return sp->offset;          return sp->offset;
583    
# Line 598  Line 609 
609          return -1;          return -1;
610      }      }
611      offset = SprintCString(sp, bp);      offset = SprintCString(sp, bp);
612      free(bp);      js_free(bp);
613      return offset;      return offset;
614  }  }
615    
# Line 635  Line 646 
646          return NULL;          return NULL;
647    
648      /* Loop control variables: z points at end of string sentinel. */      /* Loop control variables: z points at end of string sentinel. */
649      JSSTRING_CHARS_AND_END(str, s, z);      str->getCharsAndEnd(s, z);
650      for (t = s; t < z; s = ++t) {      for (t = s; t < z; s = ++t) {
651          /* Move t forward from s past un-quote-worthy characters. */          /* Move t forward from s past un-quote-worthy characters. */
652          c = *t;          c = *t;
# Line 645  Line 656 
656              if (t == z)              if (t == z)
657                  break;                  break;
658          }          }
659          len = PTRDIFF(t, s, jschar);          len = t - s;
660    
661          /* Allocate space for s, including the '\0' at the end. */          /* Allocate space for s, including the '\0' at the end. */
662          if (!SprintEnsureBuffer(sp, len))          if (!SprintEnsureBuffer(sp, len))
# Line 731  Line 742 
742  {  {
743      JSPrinter *jp;      JSPrinter *jp;
744    
745      jp = (JSPrinter *) JS_malloc(cx, sizeof(JSPrinter));      jp = (JSPrinter *) cx->malloc(sizeof(JSPrinter));
746      if (!jp)      if (!jp)
747          return NULL;          return NULL;
748      INIT_SPRINTER(cx, &jp->sprinter, &jp->pool, 0);      INIT_SPRINTER(cx, &jp->sprinter, &jp->pool, 0);
# Line 758  Line 769 
769  js_DestroyPrinter(JSPrinter *jp)  js_DestroyPrinter(JSPrinter *jp)
770  {  {
771      JS_FinishArenaPool(&jp->pool);      JS_FinishArenaPool(&jp->pool);
772      JS_free(jp->sprinter.context, jp);      jp->sprinter.context->free(jp);
773  }  }
774    
775  JSString *  JSString *
# Line 826  Line 837 
837      /* Allocate temp space, convert format, and put. */      /* Allocate temp space, convert format, and put. */
838      bp = JS_vsmprintf(format, ap);      /* XXX vsaprintf */      bp = JS_vsmprintf(format, ap);      /* XXX vsaprintf */
839      if (fp) {      if (fp) {
840          JS_free(jp->sprinter.context, fp);          jp->sprinter.context->free(fp);
841          format = NULL;          format = NULL;
842      }      }
843      if (!bp) {      if (!bp) {
# Line 837  Line 848 
848      cc = strlen(bp);      cc = strlen(bp);
849      if (SprintPut(&jp->sprinter, bp, (size_t)cc) < 0)      if (SprintPut(&jp->sprinter, bp, (size_t)cc) < 0)
850          cc = -1;          cc = -1;
851      free(bp);      js_free(bp);
852    
853      va_end(ap);      va_end(ap);
854      return cc;      return cc;
# Line 923  Line 934 
934              if (off < 0)              if (off < 0)
935                  off = 0;                  off = 0;
936              ss->offsets[i] = off;              ss->offsets[i] = off;
937              JS_free(ss->sprinter.context, bytes);              ss->sprinter.context->free(bytes);
938              return off;              return off;
939          }          }
940          if (!ss->sprinter.base && SprintPut(&ss->sprinter, "", 0) >= 0) {          if (!ss->sprinter.base && SprintPut(&ss->sprinter, "", 0) >= 0) {
# Line 1288  Line 1299 
1299      script = ss->printer->script;      script = ss->printer->script;
1300      if (script->objectsOffset == 0)      if (script->objectsOffset == 0)
1301          return GetStr(ss, i);          return GetStr(ss, i);
1302      for (j = 0, n = JS_SCRIPT_OBJECTS(script)->length; ; j++) {      for (j = 0, n = script->objects()->length; ; j++) {
1303          if (j == n)          if (j == n)
1304              return GetStr(ss, i);              return GetStr(ss, i);
1305          JS_GET_SCRIPT_OBJECT(script, j, obj);          obj = script->getObject(j);
1306          if (OBJ_GET_CLASS(cx, obj) == &js_BlockClass) {          if (OBJ_GET_CLASS(cx, obj) == &js_BlockClass) {
1307              depth = OBJ_BLOCK_DEPTH(cx, obj);              depth = OBJ_BLOCK_DEPTH(cx, obj);
1308              count = OBJ_BLOCK_COUNT(cx, obj);              count = OBJ_BLOCK_COUNT(cx, obj);
# Line 1336  Line 1347 
1347      return JS_FALSE;      return JS_FALSE;
1348  }  }
1349    
1350    #define LOAD_ATOM(PCOFF)                                                      \
1351        GET_ATOM_FROM_BYTECODE(jp->script, pc, PCOFF, atom)
1352    
1353  #if JS_HAS_DESTRUCTURING  #if JS_HAS_DESTRUCTURING
1354    
1355  #define LOCAL_ASSERT(expr)  LOCAL_ASSERT_RV(expr, NULL)  #define LOCAL_ASSERT(expr)  LOCAL_ASSERT_RV(expr, NULL)
# Line 1396  Line 1410 
1410              atom = GetArgOrVarAtom(jp, GET_SLOTNO(pc));              atom = GetArgOrVarAtom(jp, GET_SLOTNO(pc));
1411              LOCAL_ASSERT(atom);              LOCAL_ASSERT(atom);
1412          } else if (op == JSOP_SETGVAR) {          } else if (op == JSOP_SETGVAR) {
1413              GET_ATOM_FROM_BYTECODE(jp->script, pc, 0, atom);              LOAD_ATOM(0);
1414          } else if (IsVarSlot(jp, pc, &i)) {          } else if (IsVarSlot(jp, pc, &i)) {
1415              atom = GetArgOrVarAtom(jp, i);              atom = GetArgOrVarAtom(jp, i);
1416              LOCAL_ASSERT(atom);              LOCAL_ASSERT(atom);
# Line 1530  Line 1544 
1544            case JSOP_INT32:  d = i = GET_INT32(pc);  goto do_getelem;            case JSOP_INT32:  d = i = GET_INT32(pc);  goto do_getelem;
1545    
1546            case JSOP_DOUBLE:            case JSOP_DOUBLE:
1547              GET_ATOM_FROM_BYTECODE(jp->script, pc, 0, atom);              GET_DOUBLE_FROM_BYTECODE(jp->script, pc, 0, atom);
1548              d = *ATOM_TO_DOUBLE(atom);              d = *ATOM_TO_DOUBLE(atom);
1549              LOCAL_ASSERT(JSDOUBLE_IS_FINITE(d) && !JSDOUBLE_IS_NEGZERO(d));              LOCAL_ASSERT(JSDOUBLE_IS_FINITE(d) && !JSDOUBLE_IS_NEGZERO(d));
1550              i = (jsint)d;              i = (jsint)d;
# Line 1566  Line 1580 
1580    
1581            case JSOP_CALLPROP:            case JSOP_CALLPROP:
1582            case JSOP_GETPROP:            case JSOP_GETPROP:
1583              GET_ATOM_FROM_BYTECODE(jp->script, pc, 0, atom);              LOAD_ATOM(0);
1584            do_destructure_atom:            do_destructure_atom:
1585              *OFF2STR(&ss->sprinter, head) = '{';              *OFF2STR(&ss->sprinter, head) = '{';
1586              str = ATOM_TO_STRING(atom);              str = ATOM_TO_STRING(atom);
# Line 1826  Line 1840 
1840   */   */
1841  #define ATOM_IS_IDENTIFIER(atom) js_IsIdentifier(ATOM_TO_STRING(atom))  #define ATOM_IS_IDENTIFIER(atom) js_IsIdentifier(ATOM_TO_STRING(atom))
1842  #define ATOM_IS_KEYWORD(atom)                                                 \  #define ATOM_IS_KEYWORD(atom)                                                 \
1843      (js_CheckKeyword(JSSTRING_CHARS(ATOM_TO_STRING(atom)),                    \      (js_CheckKeyword(ATOM_TO_STRING(atom)->chars(),                           \
1844                       JSSTRING_LENGTH(ATOM_TO_STRING(atom))) != TOK_EOF)                       ATOM_TO_STRING(atom)->length()) != TOK_EOF)
1845    
1846  /*  /*
1847   * Given an atom already fetched from jp->script's atom map, quote/escape its   * Given an atom already fetched from jp->script's atom map, quote/escape its
# Line 1849  Line 1863 
1863              return NULL;                                                      \              return NULL;                                                      \
1864      JS_END_MACRO      JS_END_MACRO
1865    
 #define LOAD_ATOM(PCOFF)                                                      \  
     GET_ATOM_FROM_BYTECODE(jp->script, pc, PCOFF, atom)  
   
1866  #define LOAD_OBJECT(PCOFF)                                                    \  #define LOAD_OBJECT(PCOFF)                                                    \
1867      GET_OBJECT_FROM_BYTECODE(jp->script, pc, PCOFF, obj)      GET_OBJECT_FROM_BYTECODE(jp->script, pc, PCOFF, obj)
1868    
# Line 2234  Line 2245 
2245                      break;                      break;
2246    
2247                    case SRC_FUNCDEF:                    case SRC_FUNCDEF:
2248                      JS_GET_SCRIPT_FUNCTION(jp->script,                      fun = jp->script->getFunction(js_GetSrcNoteOffset(sn, 0));
                                            js_GetSrcNoteOffset(sn, 0),  
                                            fun);  
2249                    do_function:                    do_function:
2250                      js_puts(jp, "\n");                      js_puts(jp, "\n");
2251                      jp2 = JS_NEW_PRINTER(cx, "nested_function", fun,                      jp2 = JS_NEW_PRINTER(cx, "nested_function", fun,
# Line 2502  Line 2511 
2511                      len = 0;                      len = 0;
2512    
2513                      if (!Decompile(ss, done, pc - done, JSOP_POP)) {                      if (!Decompile(ss, done, pc - done, JSOP_POP)) {
2514                          JS_free(cx, (char *)lval);                          cx->free((char *)lval);
2515                          return NULL;                          return NULL;
2516                      }                      }
2517    
2518                      /* Pop Decompile result and print comma expression. */                      /* Pop Decompile result and print comma expression. */
2519                      rval = POP_STR();                      rval = POP_STR();
2520                      todo = Sprint(&ss->sprinter, "%s, %s", lval, rval);                      todo = Sprint(&ss->sprinter, "%s, %s", lval, rval);
2521                      JS_free(cx, (char *)lval);                      cx->free((char *)lval);
2522                      break;                      break;
2523    
2524                    case SRC_HIDDEN:                    case SRC_HIDDEN:
# Line 2541  Line 2550 
2550                          /* Set saveop to reflect what we will push. */                          /* Set saveop to reflect what we will push. */
2551                          saveop = JSOP_LEAVEBLOCKEXPR;                          saveop = JSOP_LEAVEBLOCKEXPR;
2552                          if (!Decompile(ss, pc, len, saveop)) {                          if (!Decompile(ss, pc, len, saveop)) {
2553                              JS_free(cx, (char *)lval);                              cx->free((char *)lval);
2554                              return NULL;                              return NULL;
2555                          }                          }
2556                          rval = PopStr(ss, JSOP_SETNAME);                          rval = PopStr(ss, JSOP_SETNAME);
# Line 2550  Line 2559 
2559                                        ? "let (%s) (%s)"                                        ? "let (%s) (%s)"
2560                                        : "let (%s) %s",                                        : "let (%s) %s",
2561                                        lval, rval);                                        lval, rval);
2562                          JS_free(cx, (char *)lval);                          cx->free((char *)lval);
2563                      }                      }
2564                      break;                      break;
2565    
# Line 2614  Line 2623 
2623                  if ((size_t)argc <= JS_ARRAY_LENGTH(smallv)) {                  if ((size_t)argc <= JS_ARRAY_LENGTH(smallv)) {
2624                      atomv = smallv;                      atomv = smallv;
2625                  } else {                  } else {
2626                      atomv = (JSAtom **) JS_malloc(cx, argc * sizeof(JSAtom *));                      atomv = (JSAtom **) cx->malloc(argc * sizeof(JSAtom *));
2627                      if (!atomv)                      if (!atomv)
2628                          return NULL;                          return NULL;
2629                  }                  }
# Line 2724  Line 2733 
2733    
2734                      len = js_GetSrcNoteOffset(sn, 0);                      len = js_GetSrcNoteOffset(sn, 0);
2735                      if (len) {                      if (len) {
2736                          len -= PTRDIFF(pc, pc2, jsbytecode);                          len -= pc - pc2;
2737                          LOCAL_ASSERT_OUT(len > 0);                          LOCAL_ASSERT_OUT(len > 0);
2738                          js_printf(jp, " if ");                          js_printf(jp, " if ");
2739                          ok = Decompile(ss, pc, len, JSOP_NOP) != NULL;                          ok = Decompile(ss, pc, len, JSOP_NOP) != NULL;
# Line 2749  Line 2758 
2758  #undef LOCAL_ASSERT_OUT  #undef LOCAL_ASSERT_OUT
2759                enterblock_out:                enterblock_out:
2760                  if (atomv != smallv)                  if (atomv != smallv)
2761                      JS_free(cx, atomv);                      cx->free(atomv);
2762                  if (!ok)                  if (!ok)
2763                      return NULL;                      return NULL;
2764                }                }
# Line 2805  Line 2814 
2814                {                {
2815                  if (!jp->fun) {                  if (!jp->fun) {
2816                      JS_ASSERT(jp->script->flags & JSSF_SAVED_CALLER_FUN);                      JS_ASSERT(jp->script->flags & JSSF_SAVED_CALLER_FUN);
2817                      JS_GET_SCRIPT_FUNCTION(jp->script, 0, jp->fun);                      jp->fun = jp->script->getFunction(0);
2818                  }                  }
2819    
2820                  if (!jp->localNames)                  if (!jp->localNames)
# Line 2837  Line 2846 
2846                          JS_ASSERT(jp->script->upvarsOffset != 0);                          JS_ASSERT(jp->script->upvarsOffset != 0);
2847                      }                      }
2848  #endif  #endif
2849                      uva = JS_SCRIPT_UPVARS(jp->script);                      uva = jp->script->upvars();
2850                      index = UPVAR_FRAME_SLOT(uva->vector[index]);                      index = UPVAR_FRAME_SLOT(uva->vector[index]);
2851                  }                  }
2852                  atom = GetArgOrVarAtom(jp, index);                  atom = GetArgOrVarAtom(jp, index);
# Line 3274  Line 3283 
3283                      DECOMPILE_CODE(pc + oplen, len - oplen);                      DECOMPILE_CODE(pc + oplen, len - oplen);
3284                      lval = JS_strdup(cx, POP_STR());                      lval = JS_strdup(cx, POP_STR());
3285                      if (!lval) {                      if (!lval) {
3286                          JS_free(cx, (void *)xval);                          cx->free((void *)xval);
3287                          return NULL;                          return NULL;
3288                      }                      }
3289                      pc += len;                      pc += len;
# Line 3285  Line 3294 
3294                      rval = POP_STR();                      rval = POP_STR();
3295                      todo = Sprint(&ss->sprinter, "%s ? %s : %s",                      todo = Sprint(&ss->sprinter, "%s ? %s : %s",
3296                                    xval, lval, rval);                                    xval, lval, rval);
3297                      JS_free(cx, (void *)xval);                      cx->free((void *)xval);
3298                      JS_free(cx, (void *)lval);                      cx->free((void *)lval);
3299                      break;                      break;
3300    
3301                    default:                    default:
# Line 3311  Line 3320 
3320                      return NULL;                      return NULL;
3321                  done = pc + GetJumpOffset(pc, pc);                  done = pc + GetJumpOffset(pc, pc);
3322                  pc += len;                  pc += len;
3323                  len = PTRDIFF(done, pc, jsbytecode);                  len = done - pc;
3324                  if (!Decompile(ss, pc, len, op)) {                  if (!Decompile(ss, pc, len, op)) {
3325                      JS_free(cx, (char *)lval);                      cx->free((char *)lval);
3326                      return NULL;                      return NULL;
3327                  }                  }
3328                  rval = POP_STR();                  rval = POP_STR();
# Line 3326  Line 3335 
3335                          todo = Sprint(&ss->sprinter, "%s %s\n", lval, xval);                          todo = Sprint(&ss->sprinter, "%s %s\n", lval, xval);
3336                          tail = Sprint(&ss->sprinter, "%*s%s",                          tail = Sprint(&ss->sprinter, "%*s%s",
3337                                        jp->indent + 4, "", rval);                                        jp->indent + 4, "", rval);
3338                          JS_free(cx, (char *)rval);                          cx->free((char *)rval);
3339                      }                      }
3340                      if (tail < 0)                      if (tail < 0)
3341                          todo = -1;                          todo = -1;
3342                  } else {                  } else {
3343                      todo = Sprint(&ss->sprinter, "%s %s %s", lval, xval, rval);                      todo = Sprint(&ss->sprinter, "%s %s %s", lval, xval, rval);
3344                  }                  }
3345                  JS_free(cx, (char *)lval);                  cx->free((char *)lval);
3346                  break;                  break;
3347    
3348                case JSOP_AND:                case JSOP_AND:
# Line 3517  Line 3526 
3526                  }                  }
3527                  break;                  break;
3528    
3529                  case JSOP_CONCATN:
3530                  {
3531                    argc = GET_UINT16(pc);
3532                    JS_ASSERT(argc > 0);
3533    
3534                    js::Vector<char *> argv(cx);
3535                    if (!argv.resize(argc))
3536                        return NULL;
3537    
3538                    MUST_FLOW_THROUGH("out");
3539                    ok = JS_FALSE;
3540    
3541                    for (i = argc - 1; i >= 0; i--) {
3542                        argv[i] = JS_strdup(cx, POP_STR());
3543                        if (!argv[i])
3544                            goto out;
3545                    }
3546    
3547                    todo = Sprint(&ss->sprinter, "%s", argv[0]);
3548                    if (todo < 0)
3549                        goto out;
3550                    for (i = 1; i < argc; i++) {
3551                        if (Sprint(&ss->sprinter, " + %s", argv[i]) < 0)
3552                            goto out;
3553                    }
3554    
3555                    ok = JS_TRUE;
3556    
3557                  out:
3558                    for (i = 0; i < argc; i++)
3559                        JS_free(cx, argv[i]);
3560                    if (!ok)
3561                        return NULL;
3562                    break;
3563                  }
3564    
3565                case JSOP_NEW:                case JSOP_NEW:
3566                case JSOP_CALL:                case JSOP_CALL:
3567                case JSOP_EVAL:                case JSOP_EVAL:
# Line 3526  Line 3571 
3571  #endif  #endif
3572                  argc = GET_ARGC(pc);                  argc = GET_ARGC(pc);
3573                  argv = (char **)                  argv = (char **)
3574                      JS_malloc(cx, (size_t)(argc + 1) * sizeof *argv);                      cx->malloc((size_t)(argc + 1) * sizeof *argv);
3575                  if (!argv)                  if (!argv)
3576                      return NULL;                      return NULL;
3577    
# Line 3584  Line 3629 
3629                      ok = JS_FALSE;                      ok = JS_FALSE;
3630    
3631                  for (i = 0; i <= argc; i++)                  for (i = 0; i <= argc; i++)
3632                      JS_free(cx, argv[i]);                      cx->free(argv[i]);
3633                  JS_free(cx, argv);                  cx->free(argv);
3634                  if (!ok)                  if (!ok)
3635                      return NULL;                      return NULL;
3636  #if JS_HAS_LVALUE_RETURN  #if JS_HAS_LVALUE_RETURN
# Line 3953  Line 3998 
3998                  break;                  break;
3999    
4000                case JSOP_DOUBLE:                case JSOP_DOUBLE:
4001                  LOAD_ATOM(0);                  GET_DOUBLE_FROM_BYTECODE(jp->script, pc, 0, atom);
4002                  val = ATOM_KEY(atom);                  val = ATOM_KEY(atom);
4003                  LOCAL_ASSERT(JSVAL_IS_DOUBLE(val));                  LOCAL_ASSERT(JSVAL_IS_DOUBLE(val));
4004                  todo = SprintDoubleValue(&ss->sprinter, val, &saveop);                  todo = SprintDoubleValue(&ss->sprinter, val, &saveop);
# Line 4089  Line 4134 
4134                      if (!rval)                      if (!rval)
4135                          return NULL;                          return NULL;
4136                      todo = SprintCString(&ss->sprinter, rval);                      todo = SprintCString(&ss->sprinter, rval);
4137                      JS_free(cx, (void *)rval);                      cx->free((void *)rval);
4138                      break;                      break;
4139                  }                  }
4140  #endif /* JS_HAS_GENERATOR_EXPRS */  #endif /* JS_HAS_GENERATOR_EXPRS */
# Line 4160  Line 4205 
4205                      ok = JS_TRUE;                      ok = JS_TRUE;
4206                  } else {                  } else {
4207                      table = (TableEntry *)                      table = (TableEntry *)
4208                              JS_malloc(cx, (size_t)n * sizeof *table);                              cx->malloc((size_t)n * sizeof *table);
4209                      if (!table)                      if (!table)
4210                          return NULL;                          return NULL;
4211                      for (i = j = 0; i < n; i++) {                      for (i = j = 0; i < n; i++) {
# Line 4180  Line 4225 
4225                          pc2 += jmplen;                          pc2 += jmplen;
4226                      }                      }
4227                      tmp = (TableEntry *)                      tmp = (TableEntry *)
4228                            JS_malloc(cx, (size_t)j * sizeof *table);                            cx->malloc((size_t)j * sizeof *table);
4229                      if (tmp) {                      if (tmp) {
4230                          VOUCH_DOES_NOT_REQUIRE_STACK();                          VOUCH_DOES_NOT_REQUIRE_STACK();
4231                          ok = js_MergeSort(table, (size_t)j, sizeof(TableEntry),                          ok = js_MergeSort(table, (size_t)j, sizeof(TableEntry),
4232                                            CompareOffsets, NULL, tmp);                                            CompareOffsets, NULL, tmp);
4233                          JS_free(cx, tmp);                          cx->free(tmp);
4234                      } else {                      } else {
4235                          ok = JS_FALSE;                          ok = JS_FALSE;
4236                      }                      }
# Line 4195  Line 4240 
4240                      ok = DecompileSwitch(ss, table, (uintN)j, pc, len, off,                      ok = DecompileSwitch(ss, table, (uintN)j, pc, len, off,
4241                                           JS_FALSE);                                           JS_FALSE);
4242                  }                  }
4243                  JS_free(cx, table);                  cx->free(table);
4244                  if (!ok)                  if (!ok)
4245                      return NULL;                      return NULL;
4246                  todo = -2;                  todo = -2;
# Line 4221  Line 4266 
4266                  pc2 += UINT16_LEN;                  pc2 += UINT16_LEN;
4267    
4268                  table = (TableEntry *)                  table = (TableEntry *)
4269                      JS_malloc(cx, (size_t)npairs * sizeof *table);                      cx->malloc((size_t)npairs * sizeof *table);
4270                  if (!table)                  if (!table)
4271                      return NULL;                      return NULL;
4272                  for (k = 0; k < npairs; k++) {                  for (k = 0; k < npairs; k++) {
# Line 4232  Line 4277 
4277                      } else {                      } else {
4278                          table[k].label = NULL;                          table[k].label = NULL;
4279                      }                      }
4280                      JS_GET_SCRIPT_ATOM(jp->script, GET_INDEX(pc2), atom);                      JS_GET_SCRIPT_ATOM(jp->script, pc, GET_INDEX(pc2), atom);
4281                      pc2 += INDEX_LEN;                      pc2 += INDEX_LEN;
4282                      off2 = GetJumpOffset(pc, pc2);                      off2 = GetJumpOffset(pc, pc2);
4283                      pc2 += jmplen;                      pc2 += jmplen;
# Line 4242  Line 4287 
4287    
4288                  ok = DecompileSwitch(ss, table, (uintN)npairs, pc, len, off,                  ok = DecompileSwitch(ss, table, (uintN)npairs, pc, len, off,
4289                                       JS_FALSE);                                       JS_FALSE);
4290                  JS_free(cx, table);                  cx->free(table);
4291                  if (!ok)                  if (!ok)
4292                      return NULL;                      return NULL;
4293                  todo = -2;                  todo = -2;
# Line 4286  Line 4331 
4331                   * and the distance to its statements in table[i].offset.                   * and the distance to its statements in table[i].offset.
4332                   */                   */
4333                  table = (TableEntry *)                  table = (TableEntry *)
4334                      JS_malloc(cx, (size_t)ncases * sizeof *table);                      cx->malloc((size_t)ncases * sizeof *table);
4335                  if (!table)                  if (!table)
4336                      return NULL;                      return NULL;
4337                  pc2 = pc;                  pc2 = pc;
# Line 4316  Line 4361 
4361    
4362                  ok = DecompileSwitch(ss, table, (uintN)ncases, pc, len, off,                  ok = DecompileSwitch(ss, table, (uintN)ncases, pc, len, off,
4363                                       JS_TRUE);                                       JS_TRUE);
4364                  JS_free(cx, table);                  cx->free(table);
4365                  if (!ok)                  if (!ok)
4366                      return NULL;                      return NULL;
4367                  todo = -2;                  todo = -2;
# Line 4364  Line 4409 
4409                      break;                      break;
4410                  }                  }
4411    
4412                  argv = (char **) JS_malloc(cx, size_t(argc) * sizeof *argv);                  argv = (char **) cx->malloc(size_t(argc) * sizeof *argv);
4413                  if (!argv)                  if (!argv)
4414                      return NULL;                      return NULL;
4415    
# Line 4388  Line 4433 
4433                  }                  }
4434    
4435                  for (i = 0; i < argc; i++)                  for (i = 0; i < argc; i++)
4436                      JS_free(cx, argv[i]);                      cx->free(argv[i]);
4437                  JS_free(cx, argv);                  cx->free(argv);
4438                  if (!ok)                  if (!ok)
4439                      return NULL;                      return NULL;
4440    
# Line 4722  Line 4767 
4767                       (*rval == '\0' ||                       (*rval == '\0' ||
4768                        (SprintPut(&ss->sprinter, " ", 1) >= 0 &&                        (SprintPut(&ss->sprinter, " ", 1) >= 0 &&
4769                         SprintCString(&ss->sprinter, rval)));                         SprintCString(&ss->sprinter, rval)));
4770                  JS_free(cx, (char *)rval);                  cx->free((char *)rval);
4771                  if (!ok)                  if (!ok)
4772                      return NULL;                      return NULL;
4773                  SprintPut(&ss->sprinter, "?>", 2);                  SprintPut(&ss->sprinter, "?>", 2);
# Line 4830  Line 4875 
4875    
4876      ok = Decompile(&ss, pc, len, JSOP_NOP) != NULL;      ok = Decompile(&ss, pc, len, JSOP_NOP) != NULL;
4877      if (code != oldcode) {      if (code != oldcode) {
4878          JS_free(cx, jp->script->code);          cx->free(jp->script->code);
4879          jp->script->code = oldcode;          jp->script->code = oldcode;
4880          jp->script->main = oldmain;          jp->script->main = oldmain;
4881      }      }
# Line 4916  Line 4961 
4961          jp->indent -= 4;          jp->indent -= 4;
4962          js_printf(jp, "\t}");          js_printf(jp, "\t}");
4963      } else {      } else {
4964  #ifdef JS_HAS_DESTRUCTURING  #if JS_HAS_DESTRUCTURING
4965          SprintStack ss;          SprintStack ss;
4966          void *mark;          void *mark;
4967  #endif  #endif
# Line 4926  Line 4971 
4971          endpc = pc + fun->u.i.script->length;          endpc = pc + fun->u.i.script->length;
4972          ok = JS_TRUE;          ok = JS_TRUE;
4973    
4974  #ifdef JS_HAS_DESTRUCTURING  #if JS_HAS_DESTRUCTURING
4975          /* Skip JSOP_GENERATOR in case of destructuring parameters. */          /* Skip trace hint if it appears here. */
4976          if (*pc == JSOP_GENERATOR)          if (js_GetOpcode(jp->sprinter.context, fun->u.i.script, pc) == JSOP_TRACE) {
4977              pc += JSOP_GENERATOR_LENGTH;              JS_STATIC_ASSERT(JSOP_TRACE_LENGTH == JSOP_NOP_LENGTH);
4978                pc += JSOP_TRACE_LENGTH;
4979            }
4980    
4981          ss.printer = NULL;          ss.printer = NULL;
4982          jp->script = fun->u.i.script;          jp->script = fun->u.i.script;
# Line 4983  Line 5030 
5030              }              }
5031          }          }
5032    
5033  #ifdef JS_HAS_DESTRUCTURING  #if JS_HAS_DESTRUCTURING
5034          jp->script = NULL;          jp->script = NULL;
5035          JS_ARENA_RELEASE(&jp->sprinter.context->tempPool, mark);          JS_ARENA_RELEASE(&jp->sprinter.context->tempPool, mark);
5036  #endif  #endif
# Line 5049  Line 5096 
5096           * populated interpreter's stack with its current content.           * populated interpreter's stack with its current content.
5097           */           */
5098          pcstack = (jsbytecode **)          pcstack = (jsbytecode **)
5099                    JS_malloc(cx, StackDepth(script) * sizeof *pcstack);                    cx->malloc(StackDepth(script) * sizeof *pcstack);
5100          if (!pcstack)          if (!pcstack)
5101              return NULL;              return NULL;
5102          pcdepth = ReconstructPCStack(cx, script, pc, pcstack);          pcdepth = ReconstructPCStack(cx, script, pc, pcstack);
# Line 5090  Line 5137 
5137          }          }
5138    
5139        release_pcstack:        release_pcstack:
5140          JS_free(cx, pcstack);          cx->free(pcstack);
5141          if (pcdepth < 0)          if (pcdepth < 0)
5142              goto do_fallback;              goto do_fallback;
5143      }      }
# Line 5126  Line 5173 
5173          if (!fallback)          if (!fallback)
5174              return NULL;              return NULL;
5175      }      }
5176      return js_DeflateString(cx, JSSTRING_CHARS(fallback),      return js_DeflateString(cx, fallback->chars(), fallback->length());
                             JSSTRING_LENGTH(fallback));  
5177  }  }
5178    
5179  static char *  static char *
# Line 5220  Line 5266 
5266          break;          break;
5267        default:;        default:;
5268      }      }
5269      len = PTRDIFF(end, begin, jsbytecode);      len = end - begin;
5270      if (len <= 0) {      if (len <= 0) {
5271          name = FAILED_EXPRESSION_DECOMPILER;          name = FAILED_EXPRESSION_DECOMPILER;
5272          goto out;          goto out;
5273      }      }
5274    
5275      pcstack = (jsbytecode **)      pcstack = (jsbytecode **)
5276                JS_malloc(cx, StackDepth(script) * sizeof *pcstack);                cx->malloc(StackDepth(script) * sizeof *pcstack);
5277      if (!pcstack) {      if (!pcstack) {
5278          name = NULL;          name = NULL;
5279          goto out;          goto out;
# Line 5254  Line 5300 
5300    
5301    out:    out:
5302      if (code != oldcode) {      if (code != oldcode) {
5303          JS_free(cx, script->code);          cx->free(script->code);
5304          script->code = oldcode;          script->code = oldcode;
5305          script->main = oldmain;          script->main = oldmain;
5306      }      }
5307    
5308      JS_free(cx, pcstack);      cx->free(pcstack);
5309      return name;      return name;
5310  }  }
5311    
# Line 5328  Line 5374 
5374  }  }
5375    
5376  #ifdef JS_TRACER  #ifdef JS_TRACER
5377    
5378    #undef LOCAL_ASSERT
5379    #define LOCAL_ASSERT(expr)      LOCAL_ASSERT_CUSTOM(expr, goto failure);
5380    
5381  static intN  static intN
5382  SimulateImacroCFG(JSContext *cx, JSScript *script,  SimulateImacroCFG(JSContext *cx, JSScript *script,
5383                    uintN pcdepth, jsbytecode *pc, jsbytecode *target,                    uintN pcdepth, jsbytecode *pc, jsbytecode *target,
5384                    jsbytecode **pcstack)                    jsbytecode **pcstack)
5385  {  {
5386      size_t nbytes = StackDepth(script) * sizeof *pcstack;      size_t nbytes = StackDepth(script) * sizeof *pcstack;
5387      jsbytecode** tmp_pcstack = (jsbytecode **) JS_malloc(cx, nbytes);      jsbytecode** tmp_pcstack = (jsbytecode **) cx->malloc(nbytes);
5388      if (!tmp_pcstack)      if (!tmp_pcstack)
5389          return -1;          return -1;
5390      memcpy(tmp_pcstack, pcstack, nbytes);      memcpy(tmp_pcstack, pcstack, nbytes);
# Line 5355  Line 5405 
5405              ptrdiff_t jmpoff = (type == JOF_JUMP) ? GET_JUMP_OFFSET(pc)              ptrdiff_t jmpoff = (type == JOF_JUMP) ? GET_JUMP_OFFSET(pc)
5406                                                    : GET_JUMPX_OFFSET(pc);                                                    : GET_JUMPX_OFFSET(pc);
5407              LOCAL_ASSERT(jmpoff >= 0);              LOCAL_ASSERT(jmpoff >= 0);
5408              uintN tmp_pcdepth = SimulateImacroCFG(cx, script, pcdepth, pc + jmpoff,              intN tmp_pcdepth = SimulateImacroCFG(cx, script, pcdepth, pc + jmpoff,
5409                                                    target, tmp_pcstack);                                                   target, tmp_pcstack);
5410              if (tmp_pcdepth >= 0) {              if (tmp_pcdepth >= 0) {
5411                  pcdepth = tmp_pcdepth;                  pcdepth = uintN(tmp_pcdepth);
5412                  goto success;                  goto success;
5413              }              }
5414    
# Line 5373  Line 5423 
5423      LOCAL_ASSERT(pc == target);      LOCAL_ASSERT(pc == target);
5424    
5425    success:    success:
     LOCAL_ASSERT(pcdepth >= 0);  
5426      memcpy(pcstack, tmp_pcstack, nbytes);      memcpy(pcstack, tmp_pcstack, nbytes);
5427      JS_free(cx, tmp_pcstack);      cx->free(tmp_pcstack);
5428      return pcdepth;      return pcdepth;
5429    
5430    failure:    failure:
5431      JS_free(cx, tmp_pcstack);      cx->free(tmp_pcstack);
5432      return -1;      return -1;
5433  }  }
5434    
5435    #undef LOCAL_ASSERT
5436    #define LOCAL_ASSERT(expr)      LOCAL_ASSERT_RV(expr, -1);
5437    
5438  static intN  static intN
5439  ReconstructPCStack(JSContext *cx, JSScript *script, jsbytecode *target,  ReconstructPCStack(JSContext *cx, JSScript *script, jsbytecode *target,
5440                     jsbytecode **pcstack);                     jsbytecode **pcstack);
# Line 5398  Line 5450 
5450       */       */
5451      JSStackFrame *fp = js_GetScriptedCaller(cx, NULL);      JSStackFrame *fp = js_GetScriptedCaller(cx, NULL);
5452      JS_ASSERT(fp->imacpc);      JS_ASSERT(fp->imacpc);
5453      uintN pcdepth = ReconstructPCStack(cx, script, fp->imacpc, pcstack);      intN pcdepth = ReconstructPCStack(cx, script, fp->imacpc, pcstack);
5454      if (pcdepth < 0)      if (pcdepth < 0)
5455          return pcdepth;          return pcdepth;
5456      return SimulateImacroCFG(cx, script, pcdepth, imacstart, target, pcstack);      return SimulateImacroCFG(cx, script, pcdepth, imacstart, target, pcstack);

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

  ViewVC Help
Powered by ViewVC 1.1.24