From 96f5b25ca33200708cd05a414079a2248e000ef1 Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Fri, 20 Mar 2015 21:34:18 -0400 Subject: [PATCH] Bug 1145491 part 3. Only do the fast path for JSOP_SETGNAME and JSOP_STRICTSETGNAME when the script doesn't have a polluted global. r=luke,jandem --- js/src/jit/IonBuilder.cpp | 2 ++ js/src/vm/Interpreter-inl.h | 6 ++++-- js/src/vm/Interpreter.cpp | 5 ++++- js/src/vm/Opcodes.h | 6 ++++-- 4 files changed, 14 insertions(+), 5 deletions(-) diff --git a/js/src/jit/IonBuilder.cpp b/js/src/jit/IonBuilder.cpp index 4cb8de06436e..f87fad053418 100644 --- a/js/src/jit/IonBuilder.cpp +++ b/js/src/jit/IonBuilder.cpp @@ -1827,6 +1827,8 @@ IonBuilder::inspectOpcode(JSOp op) case JSOP_STRICTSETGNAME: { PropertyName *name = info().getAtom(pc)->asPropertyName(); + if (script()->hasPollutedGlobalScope()) + return jsop_setprop(name); JSObject *obj = &script()->global(); return setStaticName(obj, name); } diff --git a/js/src/vm/Interpreter-inl.h b/js/src/vm/Interpreter-inl.h index 79131f83afc9..f60d4ad88684 100644 --- a/js/src/vm/Interpreter-inl.h +++ b/js/src/vm/Interpreter-inl.h @@ -303,8 +303,10 @@ SetNameOperation(JSContext *cx, JSScript *script, jsbytecode *pc, HandleObject s *pc == JSOP_STRICTSETNAME || *pc == JSOP_SETGNAME || *pc == JSOP_STRICTSETGNAME); - MOZ_ASSERT_IF(*pc == JSOP_SETGNAME, scope == cx->global()); - MOZ_ASSERT_IF(*pc == JSOP_STRICTSETGNAME, scope == cx->global()); + MOZ_ASSERT_IF(*pc == JSOP_SETGNAME && !script->hasPollutedGlobalScope(), + scope == cx->global()); + MOZ_ASSERT_IF(*pc == JSOP_STRICTSETGNAME && !script->hasPollutedGlobalScope(), + scope == cx->global()); bool strict = *pc == JSOP_STRICTSETNAME || *pc == JSOP_STRICTSETGNAME; RootedPropertyName name(cx, script->getName(pc)); diff --git a/js/src/vm/Interpreter.cpp b/js/src/vm/Interpreter.cpp index 3130171756fc..30cbcf064bef 100644 --- a/js/src/vm/Interpreter.cpp +++ b/js/src/vm/Interpreter.cpp @@ -2472,6 +2472,9 @@ CASE(JSOP_STRICTSETNAME) "setname and strictsetname must be the same size"); static_assert(JSOP_SETGNAME_LENGTH == JSOP_STRICTSETGNAME_LENGTH, "setganem adn strictsetgname must be the same size"); + static_assert(JSOP_SETNAME_LENGTH == JSOP_SETGNAME_LENGTH, + "We're sharing the END_CASE so the lengths better match"); + RootedObject &scope = rootObject0; scope = ®S.sp[-2].toObject(); HandleValue value = REGS.stackHandleAt(-1); @@ -2742,7 +2745,7 @@ CASE(JSOP_GETNAME) PUSH_COPY(rval); TypeScript::Monitor(cx, script, REGS.pc, rval); - static_assert(JSOP_NAME_LEGNTH == JSOP_GETGNAME_LENGTH, + static_assert(JSOP_GETNAME_LENGTH == JSOP_GETGNAME_LENGTH, "We're sharing the END_CASE so the lengths better match"); } END_CASE(JSOP_GETNAME) diff --git a/js/src/vm/Opcodes.h b/js/src/vm/Opcodes.h index 37aae4cffa0b..94e707a12922 100644 --- a/js/src/vm/Opcodes.h +++ b/js/src/vm/Opcodes.h @@ -1515,7 +1515,8 @@ * Pops the top two values on the stack as 'val' and 'scope', sets property * of 'scope' as 'val' and pushes 'val' back on the stack. * - * 'scope' should be the global scope. + * 'scope' should be the global scope unless the script has a polluted + * global scope, in which case acts like JSOP_SETNAME. * Category: Variables and Scopes * Type: Free Variables * Operands: uint32_t nameIndex @@ -1528,7 +1529,8 @@ * of 'scope' as 'val' and pushes 'val' back on the stack. Throws a * TypeError if the set fails, per strict mode semantics. * - * 'scope' should be the global scope. + * 'scope' should be the global scope unless the script has a polluted + * global scope, in which case acts like JSOP_STRICTSETNAME. * Category: Variables and Scopes * Type: Free Variables * Operands: uint32_t nameIndex