From cd22c4371f647ccf77484d0e4520c8d7435e710d Mon Sep 17 00:00:00 2001 From: "brendan%mozilla.org" Date: Sat, 2 Sep 2006 20:33:42 +0000 Subject: [PATCH] Fix local function shadowing argument decompilation (351116, r=mrbkap). --- js/src/jsopcode.c | 7 +++++-- js/src/jsparse.c | 22 +++++++++++++++++----- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/js/src/jsopcode.c b/js/src/jsopcode.c index 0cc664fc1939..810856c3e126 100644 --- a/js/src/jsopcode.c +++ b/js/src/jsopcode.c @@ -3224,6 +3224,8 @@ js_DecompileFunction(JSPrinter *jp, JSFunction *fun) js_puts(jp, "("); if (FUN_INTERPRETED(fun) && fun->object) { + size_t paramsize; + /* * Print the parameters. * @@ -3237,12 +3239,13 @@ js_DecompileFunction(JSPrinter *jp, JSFunction *fun) cx = jp->sprinter.context; nargs = fun->nargs; mark = JS_ARENA_MARK(&cx->tempPool); - JS_ARENA_ALLOCATE_CAST(params, JSAtom **, &cx->tempPool, - nargs * sizeof(JSAtom *)); + paramsize = nargs * sizeof(JSAtom *); + JS_ARENA_ALLOCATE_CAST(params, JSAtom **, &cx->tempPool, paramsize); if (!params) { JS_ReportOutOfMemory(cx); return JS_FALSE; } + memset(params, 0, paramsize); scope = OBJ_SCOPE(fun->object); for (sprop = SCOPE_LAST_PROP(scope); sprop; sprop = sprop->parent) { if (sprop->getter != js_GetArgument) diff --git a/js/src/jsparse.c b/js/src/jsparse.c index 2acb5e043a82..3b52df13b365 100644 --- a/js/src/jsparse.c +++ b/js/src/jsparse.c @@ -1103,12 +1103,14 @@ FunctionDef(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc, * local variable to bind its name to its value, and not an activation * object property (it might also need the activation property, if the * outer function contains with statements, e.g., but the stack slot - * wins when jsemit.c's LookupArgOrVar can optimize a JSOP_NAME into a + * wins when jsemit.c's BindNameToSlot can optimize a JSOP_NAME into a * JSOP_GETVAR bytecode). */ if (AT_TOP_LEVEL(tc) && (tc->flags & TCF_IN_FUNCTION)) { + JSScopeProperty *sprop; + /* - * Define a property on the outer function so that LookupArgOrVar + * Define a property on the outer function so that BindNameToSlot * can properly optimize accesses. */ JS_ASSERT(OBJ_GET_CLASS(cx, varobj) == &js_FunctionClass); @@ -1119,16 +1121,26 @@ FunctionDef(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc, } if (prop) OBJ_DROP_PROPERTY(cx, pobj, prop); + sprop = NULL; if (!prop || pobj != varobj || - ((JSScopeProperty *)prop)->getter != js_GetLocalVariable) { + (sprop = (JSScopeProperty *)prop, + sprop->getter != js_GetLocalVariable)) { + uintN sflags; + + /* + * Use SPROP_IS_DUPLICATE if there is a formal argument of the + * same name, so the decompiler can find the parameter name. + */ + sflags = (sprop && sprop->getter == js_GetArgument) + ? SPROP_IS_DUPLICATE | SPROP_HAS_SHORTID + : SPROP_HAS_SHORTID; if (!js_AddHiddenProperty(cx, varobj, ATOM_TO_JSID(funAtom), js_GetLocalVariable, js_SetLocalVariable, SPROP_INVALID_SLOT, JSPROP_PERMANENT | JSPROP_SHARED, - SPROP_HAS_SHORTID, - fp->fun->u.i.nvars)) { + sflags, fp->fun->u.i.nvars)) { return NULL; } if (fp->fun->u.i.nvars == JS_BITMASK(16)) {