Skip to content

Instantly share code, notes, and snippets.

@jorendorff
Created May 24, 2012 22:02
Show Gist options
  • Save jorendorff/2784468 to your computer and use it in GitHub Desktop.
Save jorendorff/2784468 to your computer and use it in GitHub Desktop.
diff --git a/js/src/jsopcode.cpp b/js/src/jsopcode.cpp
--- a/js/src/jsopcode.cpp
+++ b/js/src/jsopcode.cpp
@@ -1045,72 +1045,71 @@ struct DecompiledOpcode
: text(NULL), parent(NULL), parentOffset(-1), parenthesized(false)
{}
};
struct JSPrinter
{
Sprinter sprinter; /* base class state */
LifoAlloc pool; /* string allocation pool */
- unsigned indent; /* indentation in spaces */
+ unsigned indent; /* indentation in spaces */
bool pretty; /* pretty-print: indent, use newlines */
bool grouped; /* in parenthesized expression context */
bool strict; /* in code marked strict */
JSScript *script; /* script being printed */
jsbytecode *dvgfence; /* DecompileExpression fencepost */
jsbytecode **pcstack; /* DecompileExpression modeled stack */
JSFunction *fun; /* interpreted function */
+ BindingNames initialLocalNames; /* storage for outermost localNames */
BindingNames *localNames; /* argument and variable names */
Vector<DecompiledOpcode> *decompiledOpcodes; /* optional state for decompiled ops */
+ explicit JSPrinter(JSContext *cx) : sprinter(cx), pool(1024), initialLocalNames(cx) {}
+
DecompiledOpcode &decompiled(jsbytecode *pc) {
JS_ASSERT(decompiledOpcodes);
return (*decompiledOpcodes)[pc - script->code];
}
};
JSPrinter *
js_NewPrinter(JSContext *cx, const char *name, JSFunction *fun,
unsigned indent, JSBool pretty, JSBool grouped, JSBool strict)
{
- JSPrinter *jp = (JSPrinter *) cx->malloc_(sizeof(JSPrinter));
+ JSPrinter *jp = cx->new_<JSPrinter>(cx);
if (!jp)
return NULL;
- new (&jp->sprinter) Sprinter(cx);
- if (!jp->sprinter.init())
+ if (!jp->sprinter.init()) {
+ cx->delete_(jp);
return NULL;
- new (&jp->pool) LifoAlloc(1024);
+ }
jp->indent = indent;
jp->pretty = !!pretty;
jp->grouped = !!grouped;
jp->strict = !!strict;
jp->script = NULL;
jp->dvgfence = NULL;
jp->pcstack = NULL;
jp->fun = fun;
jp->localNames = NULL;
jp->decompiledOpcodes = NULL;
if (fun && fun->isInterpreted() && fun->script()->bindings.count() > 0) {
- jp->localNames = cx->new_<BindingNames>(cx);
- if (!jp->localNames || !fun->script()->bindings.getLocalNameArray(cx, jp->localNames)) {
- js_DestroyPrinter(jp);
+ jp->localNames = &jp->initialLocalNames;
+ if (!fun->script()->bindings.getLocalNameArray(cx, jp->localNames)) {
+ cx->delete_(jp);
return NULL;
}
}
return jp;
}
void
js_DestroyPrinter(JSPrinter *jp)
{
- JSContext *cx = jp->sprinter.context;
- jp->pool.freeAll();
- Foreground::delete_(jp->localNames);
- jp->sprinter.Sprinter::~Sprinter();
- cx->free_(jp);
+ jp->sprinter.context->delete_(jp);
}
JSString *
js_GetPrinterOutput(JSPrinter *jp)
{
JSContext *cx = jp->sprinter.context;
return JS_NewStringCopyZ(cx, jp->sprinter.string());
}
@@ -4651,23 +4650,21 @@ Decompile(SprintStack *ss, jsbytecode *p
/*
* All allocation when decompiling is LIFO, using malloc or,
* more commonly, arena-allocating from cx->tempLifoAlloc
* Therefore after InitSprintStack succeeds, we must release
* to mark before returning.
*/
LifoAllocScope las(&cx->tempLifoAlloc());
+ BindingNames bn(cx);
if (fun->script()->bindings.count() > 0) {
- innerLocalNames = cx->new_<BindingNames>(cx);
- if (!innerLocalNames ||
- !fun->script()->bindings.getLocalNameArray(cx, innerLocalNames))
- {
+ innerLocalNames = &bn;
+ if (!fun->script()->bindings.getLocalNameArray(cx, innerLocalNames))
return NULL;
- }
} else {
innerLocalNames = NULL;
}
inner = fun->script();
if (!InitSprintStack(cx, &ss2, jp, StackDepth(inner)))
return NULL;
ss2.inGenExp = JS_TRUE;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment