Don't lose error condition in decompiler (bug 621988, r=brendan).
authorAndreas Gal <gal@mozilla.com>
Sat, 22 Jan 2011 23:30:30 -0800
changeset 61222 7da52f991c293c40455e78d41799f474c00dcf33
parent 61221 bbcc51fa912b89282886ee9404afed5e482536bd
child 61223 e107ac5e475217cbb6b7eb478a836fea931c1825
push id18277
push usercleary@mozilla.com
push dateTue, 25 Jan 2011 03:52:51 +0000
treeherdermozilla-central@7ee91bd90e7a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbrendan
bugs621988
milestone2.0b10pre
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Don't lose error condition in decompiler (bug 621988, r=brendan).
js/src/jsapi.cpp
js/src/jsopcode.cpp
js/src/jsopcode.h
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -4840,17 +4840,18 @@ JS_DecompileScript(JSContext *cx, JSScri
                        !(indent & JS_DONT_PRETTY_PRINT),
                        false, false);
     if (!jp)
         return NULL;
     if (js_DecompileScript(jp, script))
         str = js_GetPrinterOutput(jp);
     else
         str = NULL;
-    js_DestroyPrinter(jp);
+    if (!js_DestroyPrinter(jp))
+        return NULL;
     return str;
 }
 
 JS_PUBLIC_API(JSString *)
 JS_DecompileFunction(JSContext *cx, JSFunction *fun, uintN indent)
 {
     JS_THREADSAFE_ASSERT(cx->compartment != cx->runtime->atomsCompartment);
     CHECK_REQUEST(cx);
--- a/js/src/jsopcode.cpp
+++ b/js/src/jsopcode.cpp
@@ -800,16 +800,17 @@ js_QuoteString(JSContext *cx, JSString *
 
 struct JSPrinter {
     Sprinter        sprinter;       /* base class state */
     JSArenaPool     pool;           /* string allocation pool */
     uintN           indent;         /* indentation in spaces */
     bool            pretty;         /* pretty-print: indent, use newlines */
     bool            grouped;        /* in parenthesized expression context */
     bool            strict;         /* in code marked strict */
+    bool            error;          /* error occured */
     JSScript        *script;        /* script being printed */
     jsbytecode      *dvgfence;      /* DecompileExpression fencepost */
     jsbytecode      **pcstack;      /* DecompileExpression modeled stack */
     JSFunction      *fun;           /* interpreted function */
     jsuword         *localNames;    /* argument and variable names */
 };
 
 JSPrinter *
@@ -822,36 +823,39 @@ js_NewPrinter(JSContext *cx, const char 
     if (!jp)
         return NULL;
     INIT_SPRINTER(cx, &jp->sprinter, &jp->pool, 0);
     JS_InitArenaPool(&jp->pool, name, 256, 1, &cx->scriptStackQuota);
     jp->indent = indent;
     jp->pretty = !!pretty;
     jp->grouped = !!grouped;
     jp->strict = !!strict;
+    jp->error = false;
     jp->script = NULL;
     jp->dvgfence = NULL;
     jp->pcstack = NULL;
     jp->fun = fun;
     jp->localNames = NULL;
     if (fun && fun->isInterpreted() && fun->script()->bindings.hasLocalNames()) {
         jp->localNames = fun->script()->bindings.getLocalNameArray(cx, &jp->pool);
         if (!jp->localNames) {
             js_DestroyPrinter(jp);
             return NULL;
         }
     }
     return jp;
 }
 
-void
+bool
 js_DestroyPrinter(JSPrinter *jp)
 {
     JS_FinishArenaPool(&jp->pool);
+    bool error = jp->error;
     jp->sprinter.context->free(jp);
+    return error;
 }
 
 JSString *
 js_GetPrinterOutput(JSPrinter *jp)
 {
     JSContext *cx;
     JSString *str;
 
@@ -2324,17 +2328,17 @@ Decompile(SprintStack *ss, jsbytecode *p
                     jp2 = js_NewPrinter(cx, "nested_function", fun,
                                         jp->indent, jp->pretty, jp->grouped,
                                         jp->strict);
                     if (!jp2)
                         return NULL;
                     ok = js_DecompileFunction(jp2);
                     if (ok && jp2->sprinter.base)
                         js_puts(jp, jp2->sprinter.base);
-                    js_DestroyPrinter(jp2);
+                    ok &= !!js_DestroyPrinter(jp2);
                     if (!ok)
                         return NULL;
                     js_puts(jp, "\n\n");
                     break;
 
                   case SRC_BRACE:
                     js_printf(jp, "\t{\n");
                     jp->indent += 4;
@@ -4916,17 +4920,18 @@ js_DecompileToString(JSContext *cx, cons
 
     jp = js_NewPrinter(cx, name, fun, indent, pretty, grouped, strict);
     if (!jp)
         return NULL;
     if (decompiler(jp))
         str = js_GetPrinterOutput(jp);
     else
         str = NULL;
-    js_DestroyPrinter(jp);
+    if (!js_DestroyPrinter(jp))
+        return NULL;
     return str;
 }
 
 static const char native_code_str[] = "\t[native code]\n";
 
 JSBool
 js_DecompileFunctionBody(JSPrinter *jp)
 {
@@ -5299,17 +5304,20 @@ DecompileExpression(JSContext *cx, JSScr
                        false, false, false);
     if (jp) {
         jp->dvgfence = end;
         jp->pcstack = pcstack;
         if (DecompileCode(jp, script, begin, (uintN) len, (uintN) pcdepth)) {
             name = (jp->sprinter.base) ? jp->sprinter.base : (char *) "";
             name = JS_strdup(cx, name);
         }
-        js_DestroyPrinter(jp);
+        if (!js_DestroyPrinter(jp)) {
+            cx->free(name);
+            name = NULL;
+        }
     }
 
 out:
     cx->free(pcstack);
     return name;
 }
 
 uintN
--- a/js/src/jsopcode.h
+++ b/js/src/jsopcode.h
@@ -306,17 +306,17 @@ js_QuoteString(JSContext *cx, JSString *
  * functions need not be re-marked with a strict directive.  It should
  * be false in the outermost printer.
  */
 
 extern JSPrinter *
 js_NewPrinter(JSContext *cx, const char *name, JSFunction *fun,
               uintN indent, JSBool pretty, JSBool grouped, JSBool strict);
 
-extern void
+extern bool
 js_DestroyPrinter(JSPrinter *jp);
 
 extern JSString *
 js_GetPrinterOutput(JSPrinter *jp);
 
 extern int
 js_printf(JSPrinter *jp, const char *format, ...);